forked from FDOS/kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkernel.asm
More file actions
1340 lines (1147 loc) · 46.7 KB
/
kernel.asm
File metadata and controls
1340 lines (1147 loc) · 46.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;
; File:
; kernel.asm
; Description:
; kernel start-up code
;
; Copyright (c) 1995, 1996
; Pasquale J. Villani
; All Rights Reserved
;
; This file is part of DOS-C.
;
; DOS-C is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; either version
; 2, or (at your option) any later version.
;
; DOS-C is distributed in the hope that it will be useful, but
; WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
; the GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public
; License along with DOS-C; see the file COPYING. If not,
; write to the Free Software Foundation, 675 Mass Ave,
; Cambridge, MA 02139, USA.
;
; $Id: kernel.asm 1705 2012-02-07 08:10:33Z perditionc $
;
%include "segs.inc"
%include "stacks.inc"
%include "ludivmul.inc"
segment PSP
extern _ReqPktPtr
STACK_SIZE equ 384/2 ; stack allocated in words
;************************************************************
; KERNEL BEGINS HERE, i.e. this is byte 0 of KERNEL.SYS
;************************************************************
%ifidn __OUTPUT_FORMAT__, obj
..start:
%endif
bootloadunit: ; (byte of short jump re-used)
entry:
jmp short realentry
;************************************************************
; KERNEL CONFIGURATION AREA
; this is copied up on the very beginning
; it's a good idea to keep this in sync with KConfig.h
;************************************************************
global _LowKernelConfig
_LowKernelConfig:
config_signature:
db 'CONFIG' ; constant
dw configend-configstart; size of config area
; to be checked !!!
configstart:
DLASortByDriveNo db 0 ; sort disks by drive order
InitDiskShowDriveAssignment db 1 ;
SkipConfigSeconds db 2 ;
ForceLBA db 0 ;
GlobalEnableLBAsupport db 1 ;
BootHarddiskSeconds db 0 ;
; The following VERSION resource must be keep in sync with VERSION.H
Version_OemID db 0xFD ; OEM_ID
Version_Major db 2
Version_Revision dw 43 ; REVISION_SEQ
Version_Release dw 1 ; 0=release build, >0=svn#
CheckDebugger: db 0 ; 0 = no check, 1 = check, 2 = assume present
Verbose db 0 ; -1 = quiet, 0 = normal, 1 = verbose
PartitionMode db 0x1f ; bits 0-1: 01=GPT if found, 00=MBR if found, 11=Hybrid, GPT first then MBR, 10=Hybrid, MBR first then GPT
; in hybrid mode, EE partitions ignored, drives assigned by GPT or MBR first based on hybrid type
; bits 2-4: 001=mount ESP (usually FAT32) partition, 010=mount MS Basic partitions, 100=mount unknown partitions
; 111=attempt to mount all paritions, 110=attempt to mount all but ESP partitions
; bits 5-7: reserved, 0 else undefined behavior
configend:
kernel_config_size: equ configend - config_signature
; must be below-or-equal the size of struct _KernelConfig
; in the file kconfig.h !
times (32 - 4) - ($ - $$) db 0
bootloadstack: dd 0
;************************************************************
; KERNEL CONFIGURATION AREA END
;************************************************************
;************************************************************
; KERNEL real entry (at ~60:20)
;
; moves the INIT part of kernel.sys to high memory (~9000:0)
; then jumps there
; to aid debugging, some '123' messages are output
; this area is discardable and used as temporary PSP for the
; init sequence
;************************************************************
cpu 8086 ; (keep initial entry compatible)
global realentry
realentry: ; execution continues here
push cs
pop ds
xor di, di
mov byte [di + bootloadunit - $$], bl
push bp
mov word [di + bootloadstack - $$], sp
mov word [di + bootloadstack + 2 - $$], ss
jmp entry_common
times 0C0h - ($ - $$) nop ; magic offset (used by exeflat)
entry_common:
%ifndef QUIET
push ax
push bx
pushf
mov ax, 0e31h ; '1' Tracecode - kernel entered
mov bx, 00f0h
int 010h
popf
pop bx
pop ax
%endif
push cs
pop ds
jmp IGROUP:kernel_start
beyond_entry: times 256-(beyond_entry-entry) db 0
; scratch area for data (DOS_PSP)
_master_env equ $ - 128
global _master_env
segment INIT_TEXT
%ifdef TEST_FILL_INIT_TEXT
%macro step 0
%if _LFSR & 1
%assign _LFSR (_LFSR >> 1) ^ 0x80200003
%else
%assign _LFSR (_LFSR >> 1)
%endif
%endmacro
align 16
%assign _LFSR 1
%rep 1024 * 8
dd _LFSR
step
%endrep
%endif
extern _FreeDOSmain
extern _query_cpu
;
; kernel start-up
;
kernel_start:
cld
%ifndef QUIET
push bx
pushf
mov ax, 0e32h ; '2' Tracecode - kernel entered
mov bx, 00f0h
int 010h
popf
pop bx
%endif
extern _kernel_command_line
; INP: ds => entry section, with CONFIG block
; and compressed entry help data
; (actually always used now)
initialise_command_line_buffer:
mov dx, I_GROUP
mov es, dx
mov bl, [bootloadunit]
lds si, [bootloadstack] ; -> original ss:sp - 2
lea ax, [si + 2] ; ax = original sp
mov si, word [si] ; si = original bp
; Note that the kernel command line buffer in
; the init data segment is pre-initialised to
; hold 0x00 0xFF in the first two bytes. This
; is used to indicate no command line present,
; as opposed to an empty command line which
; will hold 0x00 0x00.
; If any of the branches to .none are taken then
; the buffer is not modified so it retains the
; 0x00 0xFF contents.
cmp si, 114h ; buffer fits below ss:bp ?
jb .none ; no -->
cmp word [si - 14h], "CL" ; signature passed to us ?
jne .none ; no -->
lea si, [si - 114h] ; -> command line buffer
cmp ax, si ; stack top starts below-or-equal buffer ?
ja .none ; no -->
mov di, _kernel_command_line ; our buffer
mov cx, 255
xor ax, ax
push di
rep movsb ; copy up to 255 bytes
stosb ; truncate
pop di
mov ch, 1 ; cx = 256
repne scasb ; scan for terminator
rep stosb ; clear remainder of buffer
; (make sure we do not have 0x00 0xFF
; even if the command line given is
; actually the empty string)
.none:
cli
mov ss, dx
mov sp, init_tos
int 12h ; move init text+data to higher memory
mov cl,6
shl ax,cl ; convert kb to para
mov dx,15 + INITSIZE
mov cl,4
shr dx,cl
sub ax,dx
mov es,ax
mov dx,INITTEXTSIZE ; para aligned
shr dx,cl
add ax,dx
mov ss,ax ; set SS to init data segment
sti ; now enable them
mov ax,cs
mov dx,__HMATextEnd ; para aligned
shr dx,cl
%ifdef WATCOM
add ax,dx
%endif
mov ds,ax
mov si,-2 + INITSIZE; word aligned
lea cx,[si+2]
mov di,si
shr cx,1
std ; if there's overlap only std is safe
rep movsw
; move HMA_TEXT to higher memory
sub ax,dx
mov ds,ax ; ds = HMA_TEXT
mov ax,es
sub ax,dx
mov es,ax ; es = new HMA_TEXT
mov si,-2 + __HMATextEnd
lea cx,[si+2]
mov di,si
shr cx,1
rep movsw
cld
%ifndef WATCOM ; for WATCOM: CS equal for HMA and INIT
add ax,dx
mov es,ax ; otherwise CS -> init_text
%endif
push es
mov ax,cont
push ax
retf
cont: ; Now set up call frame
mov ds,[cs:_INIT_DGROUP]
mov bp,sp ; and set up stack frame for c
%ifndef QUIET
push bx
pushf
mov ax, 0e33h ; '3' Tracecode - kernel entered
mov bx, 00f0h
int 010h
popf
pop bx
%endif
mov byte [_BootDrive],bl ; tell where we came from
;!! int 11h
;!! mov cl,6
;!! shr al,cl
;!! inc al
;!! mov byte [_NumFloppies],al ; and how many
call _query_cpu
%if XCPU != 86
%if XCPU < 186 || (XCPU % 100) != 86 || (XCPU / 100) > 9
%fatal Unknown CPU level defined
%endif
cmp al, (XCPU / 100)
jb cpu_abort ; if CPU not supported -->
cpu XCPU
%endif
mov [_CPULevel], al
initialise_kernel_config:
extern _InitKernelConfig
mov ax, ss ; => init data segment
mov si, 60h
mov ds, si ; => entry section
mov si, _LowKernelConfig ; -> our CONFIG block
mov es, ax ; => init data segment
mov di, _InitKernelConfig ; -> init's CONFIG block buffer
mov cx, kernel_config_size / 2 ; size that we support
rep movsw ; copy it over
%if kernel_config_size & 1
movsb ; allow odd size
%endif
mov ds, ax ; => init data segment
check_debugger_present:
extern _debugger_present
mov al, 1 ; assume debugger present
cmp byte [di - kernel_config_size + (CheckDebugger - config_signature)], 1
ja .skip_ints_00_06 ; 2 means assume present
jb .absent ; 0 means assume absent
clc ; 1 means check
int3 ; break to debugger
jc .skip_ints_00_06
; The debugger should set CY here to indicate its
; presence. The flag set is checked later to skip
; overwriting the interrupt vectors 00h, 01h, 03h,
; and 06h. This logic is taken from lDOS init.
.absent:
xor ax, ax ; no debugger present
.skip_ints_00_06:
mov byte [_debugger_present], al
jmp _FreeDOSmain
%if XCPU != 86
cpu 8086
cpu_abort:
mov ah, 0Fh
int 10h ; get video mode, bh = active page
call .first ; print string that follows (address pushed by call)
%define LOADNAME "FreeDOS"
db 13,10 ; (to emit a blank line after the tracecodes)
db 13,10
db LOADNAME, " load error: An 80", '0'+(XCPU / 100)
db "86 processor or higher is required by this build.",13,10
db "To use ", LOADNAME, " on this processor please"
db " obtain a compatible build.",13,10
db 13,10
db "Press any key to reboot.",13,10
db 0
.display:
mov ah, 0Eh
mov bl, 07h ; page in bh, bl = colour for some modes
int 10h ; write character (may change bp!)
db 0A8h ; [test al,imm8] skip "pop si" [=imm8] after the first iteration
.first:
pop si ; (first iteration only) get message address from stack
cs lodsb ; get character
test al, al ; zero ?
jnz .display ; no, display and get next character -->
xor ax, ax
xor dx, dx
int 13h ; reset floppy disks
xor ax, ax
mov dl, 80h
int 13h ; reset hard disks
; this "test ax, imm16" opcode is used to
db 0A9h ; skip "sti" \ "hlt" [=imm16] during first iteration
.wait:
sti
hlt ; idle while waiting for keystroke
mov ah, 01h
int 16h ; get keystroke
jz .wait ; none available, loop -->
mov ah, 00h
int 16h ; remove keystroke from buffer
int 19h ; reboot
jmp short $ ; (in case it returns, which it shouldn't)
cpu XCPU
%endif ; XCPU != 86
segment INIT_TEXT_END
;************************************************************
; KERNEL CODE AREA END
; the NUL device
;************************************************************
segment CONST
;
; NUL device strategy
;
global _nul_strtgy
extern GenStrategy
_nul_strtgy:
jmp LGROUP:GenStrategy
;
; NUL device interrupt
;
global _nul_intr
_nul_intr:
push es
push bx
mov bx,LGROUP
mov es,bx
les bx,[es:_ReqPktPtr] ;es:bx--> rqheadr
cmp byte [es:bx+2],4 ;if read, set 0 read
jne no_nul_read
mov word [es:bx+12h],0
no_nul_read:
or word [es:bx+3],100h ;set "done" flag
pop bx
pop es
retf
segment _LOWTEXT
; low interrupt vectors 10h,13h,15h,19h,1Bh
; these need to be at 0070:0100 (see RBIL memory.lst)
global _intvec_table
_intvec_table: db 10h
dd 0
; used by int13 handler and get/set via int 2f/13h
global _BIOSInt13 ; BIOS provided disk handler
global _UserInt13 ; actual disk handler used by kernel
db 13h
_BIOSInt13: dd 0
db 15h
dd 0
; used for cleanup on reboot
global _BIOSInt19
db 19h
_BIOSInt19: dd 0
db 1Bh
dd 0
; default to using BIOS provided disk handler
db 13h
_UserInt13: dd 0
; floppy parameter table
global _int1e_table
_int1e_table: times 0eh db 0
;************************************************************
; KERNEL FIXED DATA AREA
;************************************************************
segment _FIXED_DATA
; Because of the following bytes of data, THIS MODULE MUST BE THE FIRST
; IN THE LINK SEQUENCE. THE BYTE AT DS:0004 determines the SDA format in
; use. A 0 indicates MS-DOS 3.X style, a 1 indicates MS-DOS 4.0-6.X style.
global DATASTART
DATASTART:
global _DATASTART
_DATASTART:
dos_data db 0
dw kernel_start
db 0 ; padding
dw 1 ; Hardcoded MS-DOS 4.0+ style
times (0eh - ($ - DATASTART)) db 0
global _NetBios
_NetBios dw 0 ; NetBios Number
times (26h - 0ch - ($ - DATASTART)) db 0
; Globally referenced variables - WARNING: DO NOT CHANGE ORDER
; BECAUSE THEY ARE DOCUMENTED AS UNDOCUMENTED (?) AND HAVE
; MANY MULTIPLEX PROGRAMS AND TSRs ACCESSING THEM
global _NetRetry
_NetRetry dw 3 ;-000c network retry count
global _NetDelay
_NetDelay dw 1 ;-000a network delay count
global _DskBuffer
_DskBuffer dd -1 ;-0008 current dos disk buffer
global _inputptr
_inputptr dw 0 ;-0004 Unread con input
global _first_mcb
_first_mcb dw 0 ;-0002 Start of user memory
global _DPBp
global MARK0026H
; A reference seems to indicate that this should start at offset 26h.
MARK0026H equ $
_DPBp dd -1 ; 0000 First drive Parameter Block
global _sfthead
_sfthead dd 0 ; 0004 System File Table head
global _clock
_clock dd 0 ; 0008 CLOCK$ device
global _syscon
_syscon dw _con_dev,LGROUP ; 000c console device
global _maxsecsize
_maxsecsize dw 512 ; 0010 maximum bytes/sector of any block device
dd 0 ; 0012 pointer to buffers info structure
global _CDSp
_CDSp dd 0 ; 0016 Current Directory Structure
global _FCBp
_FCBp dd 0 ; 001a FCB table pointer
global _nprotfcb
_nprotfcb dw 0 ; 001e number of protected fcbs
global _nblkdev
_nblkdev db 0 ; 0020 number of block devices
global _lastdrive
_lastdrive db 0 ; 0021 value of last drive
global _nul_dev
_nul_dev: ; 0022 device chain root
extern _con_dev
dw _con_dev, LGROUP
; next is con_dev at init time.
dw 8004h ; attributes = char device, NUL bit set
dw _nul_strtgy
dw _nul_intr
db 'NUL '
global _njoined
_njoined db 0 ; 0034 number of joined devices
dw 0 ; 0035 DOS 4 near pointer to special names (always zero in DOS 5) [setver precursor]
global _setverPtr
_setverPtr dw 0,0 ; 0037 setver list (far pointer, set by setver driver)
dw 0 ; 003B cs offset for fix a20
dw 0 ; 003D psp of last umb exec
global _LoL_nbuffers
_LoL_nbuffers dw 1 ; 003F number of buffers
dw 1 ; 0041 size of pre-read buffer
global _BootDrive
_BootDrive db 1 ; 0043 drive we booted from
global _CPULevel
_CPULevel db 0 ; 0044 cpu type (MSDOS >0 indicates dword moves ok, ie 386+)
; unless compatibility issues arise FD uses
; 0=808x, 1=18x, 2=286, 3=386+
; see cpu.asm, use >= as may add checks for 486 ...
dw 0 ; 0045 Extended memory in KBytes
buf_info:
global _firstbuf
_firstbuf dd 0 ; 0047 disk buffer chain
dw 0 ; 004B Number of dirty buffers
dd 0 ; 004D pre-read buffer
dw 0 ; 0051 number of look-ahead buffers
global _bufloc
_bufloc db 0 ; 0053 00=conv 01=HMA
global _deblock_buf
_deblock_buf dd 0 ; 0054 deblock buffer
times 3 db 0 ; 0058 unknown
dw 0 ; 005B unknown
db 0, 0FFh, 0 ; 005D unknown
global _VgaSet
_VgaSet db 0 ; 0060 unknown
dw 0 ; 0061 unknown
global _uppermem_link
_uppermem_link db 0 ; 0063 upper memory link flag
_min_pars dw 0 ; 0064 minimum paragraphs of memory
; required by program being EXECed
global _uppermem_root
_uppermem_root dw 0ffffh ; 0066 dmd_upper_root (usually 9fff)
_last_para dw 0 ; 0068 para of last mem search
SysVarEnd:
;; FreeDOS specific entries
;; all variables below this point are subject to relocation.
;; programs should not rely on any values below this point!!!
global _os_setver_minor
_os_setver_minor db 0
global _os_setver_major
_os_setver_major db 5
global _os_minor
_os_minor db 0
global _os_major
_os_major db 5
_rev_number db 0
global _version_flags
_version_flags db 0
global os_release
extern _os_release
os_release dw _os_release
%IFDEF WIN31SUPPORT
global _winStartupInfo, _winInstanced
_winInstanced dw 0 ; set to 1 on WinInit broadcast, 0 on WinExit broadcast
_winStartupInfo:
dw 0 ; structure version (same as windows version)
dd 0 ; next startup info structure, 0:0h marks end
dd 0 ; far pointer to name virtual device file or 0:0h
dd 0 ; far pointer, reference data for virtual device driver
%ifnidni __OUTPUT_FORMAT__, elf
dw instance_table,seg instance_table ; array of instance data
%else
dw instance_table ; array of instance data
global _winseg1
_winseg1: dw 0
%endif
instance_table: ; should include stacks, Win may auto determine SDA region
; we simply include whole DOS data segment
%ifnidni __OUTPUT_FORMAT__, elf
dw seg _DATASTART, 0 ; [SEG:OFF] address of region's base
dw _markEndInstanceData wrt seg _DATASTART ; size in bytes
%else
global _winseg2
_winseg2: dw 0
dw 0 ; [SEG:OFF] address of region's base
global _winseg3
_winseg3: dw 0 ; size in bytes
%endif
dd 0 ; 0 marks end of table
dw 0 ; and 0 length for end of instance_table entry
global _winPatchTable
_winPatchTable: ; returns offsets to various internal variables
dw 0x0006 ; DOS version, major# in low byte, eg. 6.00
dw save_DS ; where DS stored during int21h dispatch
dw save_BX ; where BX stored during int21h dispatch
dw _InDOS ; offset of InDOS flag
dw _MachineId ; offset to variable containing MachineID
dw _CritPatch ; offset of to array of offsets to patch
; NOTE: this points to a null terminated
; array of offsets of critical section bytes
; to patch, for now we can just point this
; to an empty table
; ie we just point to a 0 word to mark end
dw _uppermem_root ; seg of last arena header in conv memory
; this matches MS DOS's location, but
; do we have the same meaning?
%ENDIF ; WIN31SUPPORT
;; The first 5 sft entries appear to have to be at DS:00cc
times (0cch - ($ - DATASTART)) db 0
global _firstsftt
_firstsftt:
dd -1 ; link to next
dw 5 ; count
times 5*59 db 0 ; reserve space for the 5 sft entries
db 0 ; pad byte so next value on even boundary
; Some references seem to indicate that this data should start at 01fbh in
; order to maintain 100% MS-DOS compatibility.
times (01fbh - ($ - DATASTART)) db 0
global MARK01FBH
MARK01FBH equ $
global _local_buffer ; local_buffer is 256 bytes long
; so it overflows into kb_buf!!
; only when kb_buf is used, local_buffer is limited to 128 bytes.
_local_buffer: times 128 db 0
global _kb_buf
_kb_buf db 128,0 ; initialise buffer to empty
times 128+1 db 0 ; room for 128 byte readline + LF
;
; Variables that follow are documented as part of the DOS 4.0-6.X swappable
; data area in Ralf Browns Interrupt List #56
;
; this byte is used for ^P support
global _PrinterEcho
_PrinterEcho db 0 ;-34 - 0 = no printer echo, ~0 echo
global _verify_ena
_verify_ena db 0 ; ~0, write with verify
; this byte is used for TABs (shared by all char device writes??)
global _scr_pos
_scr_pos db 0 ; Current Cursor Column
global _switchar
_switchar db '/' ;-31 - switch char
global _mem_access_mode
_mem_access_mode db 0 ;-30 - memory allocation strategy
global sharing_flag
sharing_flag db 0 ; 00 = sharing module not loaded
; 01 = sharing module loaded, but
; open/close for block devices
; disabled
; FF = sharing module loaded,
; open/close for block devices
; enabled (not implemented)
global _net_set_count
_net_set_count db 1 ;-28 - count the name below was set
global _net_name
_net_name db ' ' ;-27 - 15 Character Network Name
db 00 ; Terminating 0 byte
;
; Variables contained the the "STATE_DATA" segment contain
; information about the STATE of the current DOS Process. These
; variables must be preserved regardless of the state of the INDOS
; flag.
;
; All variables that appear in "STATE_DATA" **MUST** be declared
; in this file as the offsets from the INTERNAL_DATA variable are
; critical to the DOS applications that modify this data area.
;
;
global _ErrorMode, _InDOS
global _CritErrLocus, _CritErrCode
global _CritErrAction, _CritErrClass
global _CritErrDev, _CritErrDrive
global _dta
global _cu_psp, _default_drive
global _break_ena
global _return_code
global _internal_data
; ensure offset of critical patch table remains fixed, some programs hard code offset
times (0315h - ($ - DATASTART)) db 0
global _CritPatch
_CritPatch dw 0 ;-11 zero list of patched critical
dw 0 ; section variables
dw 0 ; DOS puts 0d0ch here but some
dw 0 ; progs really write to that addr.
dw 0 ;-03 - critical patch list terminator
db 90h ;-01 - unused, NOP pad byte
_internal_data: ; <-- Address returned by INT21/5D06
_ErrorMode db 0 ; 00 - Critical Error Flag
_InDOS db 0 ; 01 - Indos Flag
_CritErrDrive db 0 ; 02 - Drive on write protect error
_CritErrLocus db 0 ; 03 - Error Locus
_CritErrCode dw 0 ; 04 - DOS format error Code
_CritErrAction db 0 ; 06 - Error Action Code
_CritErrClass db 0 ; 07 - Error Class
_CritErrDev dd 0 ; 08 - Failing Device Address
_dta dd 0 ; 0C - current DTA
_cu_psp dw 0 ; 10 - Current PSP
break_sp dw 0 ; 12 - used in int 23
_return_code dw 0 ; 14 - return code from process
_default_drive db 0 ; 16 - Current Drive
_break_ena db 1 ; 17 - Break Flag (default TRUE)
db 0 ; 18 - flag, code page switching
db 0 ; 19 - flag, copy of 18 on int 24h abort
global _swap_always, _swap_indos
_swap_always:
global _Int21AX
_Int21AX dw 0 ; 1A - AX from last Int 21
global owning_psp, _MachineId
owning_psp dw 0 ; 1C - owning psp
_MachineId dw 0 ; 1E - remote machine ID
dw 0 ; 20 - First usable mcb
dw 0 ; 22 - Best usable mcb
dw 0 ; 24 - Last usable mcb
dw 0 ; 26 - memory size in paragraphs
dw 0 ; 28 - unknown
db 0 ; 2A - unknown
db 0 ; 2B - unknown
db 0 ; 2C - unknown
global _break_flg
_break_flg db 0 ; 2D - Program aborted by ^C
db 0 ; 2E - unknown
db 0 ; 2F - not referenced
global _DayOfMonth
_DayOfMonth db 1 ; 30 - day of month
global _Month
_Month db 1 ; 31 - month
global _YearsSince1980
_YearsSince1980 dw 0 ; 32 - year since 1980
daysSince1980 dw 0FFFFh ; 34 - number of days since epoch
; force rebuild on first clock read
global _DayOfWeek
_DayOfWeek db 2 ; 36 - day of week
_console_swap db 0 ; 37 console swapped during read from dev
global _dosidle_flag
_dosidle_flag db 1 ; 38 - safe to call int28 if nonzero
global _abort_progress
_abort_progress db 0 ; 39 - abort in progress
global _CharReqHdr
_CharReqHdr:
global _ClkReqHdr
_ClkReqHdr times 30 db 0 ; 3A - Device driver request header
dd 0 ; 58 - pointer to driver entry
global _MediaReqHdr
_MediaReqHdr times 22 db 0 ; 5C - Device driver request header
global _IoReqHdr
_IoReqHdr times 30 db 0 ; 72 - Device driver request header
times 6 db 0 ; 90 - unknown
global _ClkRecord
_ClkRecord times 6 db 0 ; 96 - CLOCK$ transfer record
dw 0 ; 9C - unknown
global __PriPathBuffer
__PriPathBuffer times 80h db 0 ; 9E - buffer for file name
global __SecPathBuffer
__SecPathBuffer times 80h db 0 ;11E - buffer for file name
global _sda_tmp_dm
_sda_tmp_dm times 21 db 0 ;19E - 21 byte srch state
global _SearchDir
_SearchDir times 32 db 0 ;1B3 - 32 byte dir entry
global _TempCDS
_TempCDS times 88 db 0 ;1D3 - TemporaryCDS buffer
global _DirEntBuffer
_DirEntBuffer times 32 db 0 ;22B - space enough for 1 dir entry
global _wAttr
_wAttr dw 0 ;24B - extended FCB file attribute
global _SAttr
_SAttr db 0 ;24D - Attribute Mask for Dir Search
global _OpenMode
_OpenMode db 0 ;24E - File Open Attribute
times 3 db 0
global _Server_Call
_Server_Call db 0 ;252 - Server call Func 5D sub 0
db 0
; Pad to 05CCh
times (25ch - ($ - _internal_data)) db 0
global _term_type ; used by break and critical error
_term_type db 0 ;25C - handlers during termination
; ecm: 00h = normal terminate,
; 01h = control-c terminate,
; 02h = critical error abort,
; 03h = TSR terminate
db 0 ;25D - padding
global term_psp
term_psp dw 0 ;25E - 0??
global int24_esbp
int24_esbp times 2 dw 0 ;260 - pointer to criticalerr DPB
global _user_r, int21regs_off, int21regs_seg
_user_r:
int21regs_off dw 0 ;264 - pointer to int21h stack frame
int21regs_seg dw 0 ; i.e. points stack frame (SS:SP) with user registers when int21h called
global critical_sp
critical_sp dw 0 ;268 - critical error internal stack, store SP during int24h
global current_ddsc
current_ddsc times 2 dw 0 ;26A - pointer to DPB for ???
diskbuf_seg dw 0 ;26E - segment of disk buffer
dd 0 ;270 - saving partial cluster number??? - see https://faydoc.tripod.com/structures/16/1690.htm
dw 0
dw 0 ;276 - temp word
db 0 ;278 - media id returned by AH=1Bh,1Ch
db 0 ;279 - unused
; Pad to 059ah
times (27ah - ($ - _internal_data)) db 0
global current_device
current_device times 2 dw 0 ;27A - point to device header if filename is character device
global _lpCurSft
_lpCurSft times 2 dw 0 ;27e - Current SFT
global _current_ldt
_current_ldt times 2 dw 0 ;282 - Current CDS
global _sda_lpFcb
_sda_lpFcb times 2 dw 0 ;286 - pointer to callers FCB
global _current_sft_idx
_current_sft_idx dw 0 ;28A - SFT index for next open
; used by MS NET
dw 0 ;28C - temp file handler
dd 0 ;28E - pointer to JFT entry (for file being opened) in process handle table
; Pad to 05b2h
times (292h - ($ - _internal_data)) db 0
dw __PriPathBuffer ; 292 - "sda_WFP_START" offset in DOS DS of first filename argument
dw __SecPathBuffer ; 294 - "sda_REN_WFP" offset in DOS DS of second filename argument
dw 0ffffh ; 296 - 0xffff or offset of last component in filename
; Pad to 05ceh
times (2aeh - ($ - _internal_data)) db 0
global _current_filepos
_current_filepos times 2 dw 0 ;2AE - current offset in file
; Pad to 05eah
times (2cah - ($ - _internal_data)) db 0
;global _save_BX
;global _save_DS
save_BX dw 0 ;2CA - unused by FreeDOS, for Win3.x
save_DS dw 0 ; compatibility, match MS's positions
dw 0 ; store DS,BX on entry to int21h (ie caller's values)
global _prev_user_r
global prev_int21regs_off
global prev_int21regs_seg
_prev_user_r:
prev_int21regs_off dw 0 ;2D0 - pointer to prev int 21 frame (see offset 264h)
prev_int21regs_seg dw 0
; Pad to 05fdh, 2D4 through 2E4 used for int21h/ax=6C00h
times (2ddh - ($ - _internal_data)) db 0
global _ext_open_action
global _ext_open_attrib
global _ext_open_mode
_ext_open_action dw 0 ;2DD - extended open action
_ext_open_attrib dw 0 ;2DF - extended open attrib
_ext_open_mode dw 0 ;2E1 - extended open mode
open_filename dd 0 ;2E3 pointer to filename to open (see ax=6C00h)
; Pad to 0620h
times (300h - ($ - _internal_data)) db 0
global apistk_bottom
apistk_bottom:
; use bottom of error stack as scratch buffer
; - only used during int 21 call
global _sda_tmp_dm_ren
_sda_tmp_dm_ren:times 21 db 0x90 ;300 - 21 byte srch state for rename
global _SearchDir_ren
_SearchDir_ren: times 32 db 0x90 ;315 - 32 byte dir entry for rename
; stacks are made to initialize to no-ops so that high-water
; testing can be performed
times STACK_SIZE*2-($-apistk_bottom) db 0x90
; critical error stack 331 bytes?, disk stack 384 bytes, character i/o 384 bytes
;300 - Error Processing Stack
global _error_tos
_error_tos:
times STACK_SIZE dw 0x9090 ;480 - Disk Function Stack
global _disk_api_tos
_disk_api_tos:
times STACK_SIZE dw 0x9090 ;600 - Char Function Stack
global _char_api_tos
_char_api_tos:
apistk_top:
db 0 ;780 device driver look-ahead (printer), see ah=64h
_VolChange db 0 ;781 - volume change
_VirtOpen db 0 ;782 - virtual open flag
; 783h to 788h are fastseek drive, 1st cluster, logical cluster, returned logical cluster
; 78Ah dw ? temp location of SYSINIT
; controlled variables end at offset 78Ch so pad to end
times (78ch - ($ - _internal_data)) db 0
; MSDOS 7.1+ with FAT32 SDA extended
;78Ch - 47 bytes of ???
times (7bbh - ($ - _internal_data)) db 0
absrdwrflg db 0 ;7bbh - 0=int 25h/26h absolute read/write, 1=int 21h/ax=7305h
times 12 dw 0 ;7bch to 7d2h, high word of 32bit values, see offsets 0x 2a2, 29c, 2bc, 29a, 276, 244, & registers ebx,edx,edi,ecx
times 3 dw 0 ; ???
;
; end of controlled variables
;
segment _BSS
;!! global _NumFloppies
;!!_NumFloppies resw 1
;!!intr_dos_stk resw 1
;!!intr_dos_seg resw 1
; mark front and end of bss area to clear
segment IB_B
global __ib_start
__ib_start:
segment IB_E
global __ib_end
__ib_end:
;; do not clear the other init BSS variables + STACK: too late.
; kernel startup stack
global init_tos
resw 512
init_tos:
; the last paragraph of conventional memory might become an MCB
resb 16
global __init_end
__init_end:
init_end:
segment _DATA
; blockdev private stack
global blk_stk_top
times 256 dw 0
blk_stk_top:
; clockdev private stack
global clk_stk_top