summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/BIOS')
-rw-r--r--v4.0/src/BIOS/BIOSTRUC.INC103
-rw-r--r--v4.0/src/BIOS/CLOCKSUB.INC78
-rw-r--r--v4.0/src/BIOS/CMOSEQU.INC50
-rw-r--r--v4.0/src/BIOS/DEFEMS.INC33
-rw-r--r--v4.0/src/BIOS/DEVMARK.INC23
-rw-r--r--v4.0/src/BIOS/JUMPMAC.INC31
-rw-r--r--v4.0/src/BIOS/LOCSCR1
-rw-r--r--v4.0/src/BIOS/MAKEFILE167
-rw-r--r--v4.0/src/BIOS/MS96TPI.INC536
-rw-r--r--v4.0/src/BIOS/MSAUX.ASM281
-rw-r--r--v4.0/src/BIOS/MSBDATA.INC722
-rw-r--r--v4.0/src/BIOS/MSBIO.LNK14
-rw-r--r--v4.0/src/BIOS/MSBIO.SKL139
-rw-r--r--v4.0/src/BIOS/MSBIO1.ASM645
-rw-r--r--v4.0/src/BIOS/MSBIO2.ASM572
-rw-r--r--v4.0/src/BIOS/MSCLOCK.ASM296
-rw-r--r--v4.0/src/BIOS/MSCON.ASM328
-rw-r--r--v4.0/src/BIOS/MSDISK.ASM2443
-rw-r--r--v4.0/src/BIOS/MSDSKPR.INC22
-rw-r--r--v4.0/src/BIOS/MSEQU.INC76
-rw-r--r--v4.0/src/BIOS/MSEXTRN.INC97
-rw-r--r--v4.0/src/BIOS/MSGROUP.INC46
-rw-r--r--v4.0/src/BIOS/MSHARD.ASM427
-rw-r--r--v4.0/src/BIOS/MSINIT.ASM2819
-rw-r--r--v4.0/src/BIOS/MSIOCTL.INC1362
-rw-r--r--v4.0/src/BIOS/MSLOAD.ASM1090
-rw-r--r--v4.0/src/BIOS/MSLOAD.INC7
-rw-r--r--v4.0/src/BIOS/MSLPT.ASM270
-rw-r--r--v4.0/src/BIOS/MSMACRO.INC192
-rw-r--r--v4.0/src/BIOS/MSSTACK.INC306
-rw-r--r--v4.0/src/BIOS/MSVOLID.INC297
-rw-r--r--v4.0/src/BIOS/PSOPTION.INC63
-rw-r--r--v4.0/src/BIOS/PUSHPOP.INC20
-rw-r--r--v4.0/src/BIOS/READCLOC.INC165
-rw-r--r--v4.0/src/BIOS/STKINIT.INC271
-rw-r--r--v4.0/src/BIOS/SYSCONF.ASM3392
-rw-r--r--v4.0/src/BIOS/SYSIMES.ASM38
-rw-r--r--v4.0/src/BIOS/SYSINIT1.ASM2668
-rw-r--r--v4.0/src/BIOS/SYSINIT2.ASM1624
39 files changed, 21714 insertions, 0 deletions
diff --git a/v4.0/src/BIOS/BIOSTRUC.INC b/v4.0/src/BIOS/BIOSTRUC.INC
new file mode 100644
index 0000000..f131e11
--- /dev/null
+++ b/v4.0/src/BIOS/BIOSTRUC.INC
@@ -0,0 +1,103 @@
1%OUT BIOSTRUC.INC...
2; SCCSID = @(#)BIOSTRUC.INC 1.0 86/09/30
3; ROM BIOS CALL PACKET STRUCTURES
4
5;*******************************
6;System Service call ( Int 15h )
7;*******************************
8;Function AH = 0C0h, Return system configuration
9;For PC and PCJR on return:
10; (AH) = 80h
11; (CY) = 1
12;For PCXT, PC PORTABLE and PCAT on return:
13; (AH) = 86h
14; (CY) = 1
15;For all others:
16; (AH) = 0
17; (CY) = 0
18; (ES:BX) = pointer to system descriptor vector in ROS
19; System descriptor :
20; DW xxxx length of descriptor in bytes,
21; minimum length = 8
22; DB xx model byte
23; 0FFh = PC
24; 0FEh = PC/XT, Portable
25; 0FDh = PC/JR
26; 0FCh = PC/AT, 6Mhz PC/AT,
27; 6Mhz PC/AT running coprocessor(?),
28; PS/2 Model 50, 50 z
29; 0FAh = PS/2 Model 25, 30
30; 0F9h = PC Convertible
31; 0F8h = PS/2 Model 80
32; 0F7h = Nova
33; 0E0 thru 0EFh = reserved
34;
35; DB xx secondary model byte
36; 000h = PC1
37; 000h = PC/XT, Portable
38; 000h = PC/JR
39; 000h = PC/AT
40; 001h = 6Mhz PC/AT
41; 003h = 6Mhz PC/AT running coprocessor(?)
42; 004h = PS/2 Model 50, 50z
43; 001h = PS/2 Model 25
44; 000h = PC Convertible
45; 000h = PS/2 Model 80
46; 000h = Nova
47;
48; DB xx bios revision level
49; 00 for first release, subsequent release
50; of code with same model byte and
51; secondary model byte require revison level
52; to increase by one.
53;
54; DB xx feature information byte 1
55; X0000000 = 1, bios use DMA channel 3
56; = 0, DMA channel 3 not used
57;
58; 0X000000 = 1, 2nd Interrupt chip present
59; = 0, 2nd Interrupt chip not present
60;
61; 00X00000 = 1, Real Time Clock present
62; = 0, Real Time Clock not present
63;
64; 000X0000 = 1, Keyboard escape sequence(INT15h)
65; called in keyboard interrupt
66; (Int 09h).
67; = 0, Keyboard escape sequence not
68; called.
69; 0000XXXX reserved
70;
71; DB xx feature information byte 2 - reserved
72;
73; DB xx feature information byte 2 - reserved
74;
75; DB xx feature information byte 2 - reserved
76;
77; DB xx feature information byte 2 - reserved
78;
79
80BIOS_SYSTEM_DESCRIPTOR struc
81bios_SD_leng dw ?
82bios_SD_modelbyte db ?
83bios_SD_scnd_modelbyte db ?
84 db ?
85bios_SD_featurebyte1 db ?
86 db 4 dup (?)
87BIOS_SYSTEM_DESCRIPTOR ends
88
89;FeatureByte1 bit map equates
90DMAchannel3 equ 10000000b
91ScndIntController equ 01000000b
92RealTimeClock equ 00100000b
93KeyEscapeSeq equ 00010000b
94;
95;Model Byte
96MDL_PC1 EQU 0FFH
97MDL_XT EQU 0FEH
98MDL_JR EQU 0FDH
99MDL_AT EQU 0FCH
100MDL_CONVERT EQU 0F9H
101
102mdl_ps2_30 equ 0fah
103mdl_ps2_80 equ 0f8h
diff --git a/v4.0/src/BIOS/CLOCKSUB.INC b/v4.0/src/BIOS/CLOCKSUB.INC
new file mode 100644
index 0000000..65b6698
--- /dev/null
+++ b/v4.0/src/BIOS/CLOCKSUB.INC
@@ -0,0 +1,78 @@
1;
2; date_verify loosely checks bcd date values to be in range in bin_date_time
3;
4date_verify: ;
5assume ds:code,es:nothing
6 cmp byte ptr bin_date_time+0,20h ; century check
7 ja date_error ; jmp error
8 jz century_20 ; jmp in 20th century
9 cmp byte ptr bin_date_time+0,19h ; century check
10 jb date_error ; jmp error
11 cmp byte ptr bin_date_time+1,80h ; year check
12 jb date_error ; jmp error
13century_20: ;
14 cmp byte ptr bin_date_time+1,99h ; year check
15 ja date_error ; jmp error
16 cmp byte ptr bin_date_time+2,12h ; month check
17 ja date_error ; jmp error
18 cmp byte ptr bin_date_time+2,00h ; month check
19 jbe date_error ; jmp error
20 cmp byte ptr bin_date_time+3,31h ; day check
21 ja date_error ; jmp error
22 cmp byte ptr bin_date_time+3,00h ; day check
23 jbe date_error ; jmp error
24 clc ; set success flag
25 ret ;
26date_error: ;
27 stc ; set error flag
28 ret ;
29
30;
31; time_verify very loosely checks bcd date values to be in range in bin_date_time
32;
33time_verify:
34assume ds:code,es:nothing
35 cmp byte ptr bin_date_time+0,24H
36 ja time_error
37 cmp byte ptr bin_date_time+1,59H
38 ja time_error
39 cmp byte ptr bin_date_time+2,59H
40 ja time_error
41 clc
42 ret
43time_error:
44 stc
45 ret
46
47;
48; bcd_verify checks values in bin_date_time to be valid
49; bcd numerals. carry set if any nibble out of range
50;
51bcd_verify: ;
52assume ds:code,es:nothing
53 mov cx,4 ; 4 bytes to check
54 mov bx,offset bin_date_time ;
55bv_loop: ;
56 mov al,[bx] ; get a bcd number (0..99)
57 mov ah,al ;
58 and ax,0f00fh ; 10's place in high ah, 1's in al
59 cmp al,10 ; is 1's place in range?
60 ja bv_error ; jmp out of range
61 shr ah,1 ; swap nibbles
62 shr ah,1 ; ...
63 shr ah,1 ; ...
64 shr ah,1 ; ...
65 and ah,0fh ; get rid of any erroneous bits
66 cmp ah,10 ; is 10's place in range
67 ja bv_error ; jmp out of range
68 inc bx ; next byte
69 dec cx ;
70 jnz bv_loop ;
71 clc ; set success flag
72 ret ;
73bv_error: ;
74 stc ; set error flag
75 ret ;
76;
77; Dos 3.30 - The real time clock structures were moved to msbio2.asm
78;
diff --git a/v4.0/src/BIOS/CMOSEQU.INC b/v4.0/src/BIOS/CMOSEQU.INC
new file mode 100644
index 0000000..b52b259
--- /dev/null
+++ b/v4.0/src/BIOS/CMOSEQU.INC
@@ -0,0 +1,50 @@
1 ;;Rev 3.30 Modification
2;Equates for CMOS.
3
4;----------------------------------------
5; CMOS EQUATES FOR THIS SYSTEM :
6;-------------------------------------------------------------------------------
7CMOS_PORT EQU 070H ; I/O ADDRESS OF CMOS ADDRESS PORT
8CMOS_DATA EQU 071H ; I/O ADDRESS OF CMOS DATA PORT
9NMI EQU 10000000B ; DISABLE NMI INTERRUPTS MASK -
10 ; HIGH BIT OF CMOS LOCATION ADDRESS
11
12;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
13CMOS_SECONDS EQU 000H ; SECONDS
14CMOS_SEC_ALARM EQU 001H ; SECONDS ALARM ## NOTE: ALL LOCATIONS
15CMOS_MINUTES EQU 002H ; MINUTES | IN THE CMOS AREA
16CMOS_MIN_ALARM EQU 003H ; MINUTES ALARM | ARE IBM USE ONLY
17CMOS_HOURS EQU 004H ; HOURS | AND SUBJECT TO
18CMOS_HR_ALARM EQU 005H ; HOURS ALARM | CHANGE. ONLY THE
19CMOS_DAY_WEEK EQU 006H ; DAY OF THE WEEK | POST & BIOS CODE
20CMOS_DAY_MONTH EQU 007H ; DAY OF THE MONTH | SHOULD DIRECTLY
21CMOS_MONTH EQU 008H ; MONTH | ACCESS LOCATIONS
22CMOS_YEAR EQU 009H ; YEAR (TWO DIGITS) | IN CMOS STORAGE.
23CMOS_REG_A EQU 00AH ; STATUS REGISTER A '-----------------
24CMOS_REG_B EQU 00BH ; STATUS REGISTER B ALARM
25CMOS_REG_C EQU 00CH ; STATUS REGISTER C FLAGS
26CMOS_REG_D EQU 00DH ; STATUS REGISTER D BATTERY
27CMOS_DIAG EQU 00EH ; POST DIAGNOSTIC STATUS RESULTS BYTE
28CMOS_SHUT_DOWN EQU 00FH ; SHUTDOWN STATUS COMMAND BYTE
29CMOS_DISKETTE EQU 010H ; DISKETTE DRIVE TYPE BYTE ;
30; EQU 011H ; - RESERVED ;C
31CMOS_DISK EQU 012H ; FIXED DISK TYPE BYTE ;H
32; EQU 013H ; - RESERVED ;E
33CMOS_EQUIP EQU 014H ; EQUIPMENT WORD LOW BYTE ;C
34CMOS_B_M_S_LO EQU 015H ; BASE MEMORY SIZE - LOW BYTE (X1024) ;K
35CMOS_B_M_S_HI EQU 016H ; BASE MEMORY SIZE - HIGH BYTE ;S
36CMOS_E_M_S_LO EQU 017H ; EXPANSION MEMORY SIZE - LOW BYTE ;U
37CMOS_E_M_S_HI EQU 018H ; EXPANSION MEMORY SIZE - HIGH BYTE ;M
38CMOS_DISK_1 EQU 019H ; FIXED DISK TYPE - DRIVE C EXTENSION ;E
39CMOS_DISK_2 EQU 01AH ; FIXED DISK TYPE - DRIVE D EXTENSION ;D
40; EQU 01BH ; - 1BH THROUGH 2DH - RESERVED ;
41CMOS_CKSUM_HI EQU 02EH ; CMOS CHECKSUM - HIGH BYTE ;*
42CMOS_CKSUM_LO EQU 02FH ; CMOS CHECKSUM - LOW BYTE ;*
43CMOS_U_M_S_LO EQU 030H ; USABLE MEMORY ABOVE 1 MEG - LOW BYTE
44CMOS_U_M_S_HI EQU 031H ; USABLE MEMORY ABOVE 1 MEG - HIGH BYTE
45CMOS_CENTURY EQU 032H ; DATE CENTURY BYTE (BCD)
46CMOS_INFO128 EQU 033H ; 128KB INFORMATION STATUS FLAG BYTE
47; EQU 034H ; - 34H THROUGH 3FH - RESERVED
48;
49 ;;End of Modification
50 \ No newline at end of file
diff --git a/v4.0/src/BIOS/DEFEMS.INC b/v4.0/src/BIOS/DEFEMS.INC
new file mode 100644
index 0000000..a1786d0
--- /dev/null
+++ b/v4.0/src/BIOS/DEFEMS.INC
@@ -0,0 +1,33 @@
1;J.K. This is a temporary version of EMS function definitions needed for
2;IBMBIO SYSINIT.
3
4EMS_INT equ 67h ;interrupt vector designated for EMS.
5
6EMS_STATUS equ 40h ;status of memery manager
7EQ_PAGES equ 42h ;get number of unallocated & total pages
8E_GET_HANDLE equ 43h ;allocate pages
9EMAP_L_TO_P equ 44h ;Map logical to physical page
10EMAP_STATE equ 4Fh ;Mapping status
11 GET_MAP_STATE equ 00h
12 GET_MAP_SIZE equ 02h
13 SET_MAP_STATE equ 01h
14EDE_ALLOCATE equ 45h ;deallocate pages
15EMS_VERSION equ 46h ;Get EMM version number
16GET_PAGE_FRAME equ 58h ;Get page frame address
17 GET_PAGEFRAME_TAB equ 00H
18 GET_NUM_PAGEFRAME equ 01H
19EMS_HANDLE_NAME equ 53h
20 SET_HANDLE_NAME equ 01h
21
22IBM_PAGE_ID equ 255 ;Physical page id that will be used by
23 ;IBMBIO and IBMDOS for buffer manipulation.
24
25;MAX_NUM_PAGEFRAME equ 12 ;maximum number of page frames IBMBIO can
26 ;handle
27
28MAX_NUM_PAGEFRAME equ 64 ;maximum number of page frames MSBIO can
29 ;handle
30
31EMSVERSION equ 40h ;4.0
32
33 \ No newline at end of file
diff --git a/v4.0/src/BIOS/DEVMARK.INC b/v4.0/src/BIOS/DEVMARK.INC
new file mode 100644
index 0000000..1b919f7
--- /dev/null
+++ b/v4.0/src/BIOS/DEVMARK.INC
@@ -0,0 +1,23 @@
1;Structure, Equtes for DEVMARK for MEM command.
2
3DEVMARK struc
4DEVMARK_ID db 0
5DEVMARK_SEG dw 0
6DEVMARK_SIZE dw 0
7DEVMARK_DUM db 3 dup (?)
8DEVMARK_FILENAME db 8 dup (' ')
9DEVMARK ends
10
11DEVMARK_STK equ 'S'
12DEVMARK_DEVICE equ 'D'
13DEVMARK_IFS equ 'I'
14DEVMARK_BUF equ 'B'
15DEVMARK_CDS equ 'L' ;lastdrive
16DEVMARK_FILES equ 'F'
17DEVMARK_FCBS equ 'X'
18DEVMARK_INST equ 'T' ;used for SYSINIT BASE for INSTALL= command.
19DEVMARK_EMS_STUB equ 'E'
20
21SETBRKDONE equ 00000001b
22FOR_DEVMARK equ 00000010b
23NOT_FOR_DEVMARK equ 11111101b
diff --git a/v4.0/src/BIOS/JUMPMAC.INC b/v4.0/src/BIOS/JUMPMAC.INC
new file mode 100644
index 0000000..e631e2e
--- /dev/null
+++ b/v4.0/src/BIOS/JUMPMAC.INC
@@ -0,0 +1,31 @@
1 ;;Rev 3.30 Modification
2;
3; given a label <lbl> either 2 byte jump to another label <lbl>_J
4; if it is near enough or 3 byte jump to <lbl>
5;
6
7jump macro lbl
8 local a
9.xcref
10
11 ifndef lbl&_j ;; is this the first invocation
12a:
13 JMP lbl
14 ELSE
15 IF (lbl&_J GE $) OR ($-lbl&_J GT 126)
16a:
17 JMP lbl ;; is the jump too far away?
18 ELSE
19a:
20 JMP lbl&_J ;; do the short one...
21 ENDIF
22 ENDIF
23lbl&_j = a
24.cref
25 endm
26.xcref jump
27;REDEFINE THE ABOVE MACRO TO ALWAYS TRY A 3 BYTE NEAR JUMP
28JUMP MACRO LBL
29 JMP LBL
30 ENDM ;;End of Modification
31 \ No newline at end of file
diff --git a/v4.0/src/BIOS/LOCSCR b/v4.0/src/BIOS/LOCSCR
new file mode 100644
index 0000000..2bbd69c
--- /dev/null
+++ b/v4.0/src/BIOS/LOCSCR
@@ -0,0 +1 @@
70
diff --git a/v4.0/src/BIOS/MAKEFILE b/v4.0/src/BIOS/MAKEFILE
new file mode 100644
index 0000000..66a281f
--- /dev/null
+++ b/v4.0/src/BIOS/MAKEFILE
@@ -0,0 +1,167 @@
1#************************** makefile for bios ***************************
2
3dest =io
4msg =..\messages
5dos =..\dos
6inc =..\inc
7hinc =..\h
8
9#
10####################### dependencies begin here. #########################
11#
12
13all: $(dest).sys
14
15msbio.cl1: msbio.skl \
16 $(msg)\$(COUNTRY).msg
17
18msload.obj: msload.asm \
19 makefile \
20 msbio.cl1 \
21 $(inc)\bootform.inc \
22 $(inc)\versiona.inc \
23 msload.inc
24
25msload.com: msload.obj
26 link msload.obj,msload,,;
27 exe2bin msload.exe msload.com
28
29msbio1.obj: msbio1.asm \
30 makefile \
31 msbdata.inc \
32 msgroup.inc \
33 jumpmac.inc \
34 pushpop.inc \
35 $(inc)\devsym.inc \
36 msdskpr.inc \
37 msmacro.inc
38
39mscon.obj: mscon.asm \
40 makefile \
41 msgroup.inc \
42 jumpmac.inc \
43 msmacro.inc
44
45msaux.obj: msaux.asm \
46 makefile \
47 msgroup.inc \
48 jumpmac.inc \
49 msmacro.inc
50
51mslpt.obj: mslpt.asm \
52 makefile \
53 msgroup.inc \
54 msequ.inc \
55 $(inc)\msbds.inc \
56 msmacro.inc \
57 $(inc)\devsym.inc \
58 $(inc)\ioctl.inc $(inc)\bpb.inc
59
60msclock.obj: msclock.asm \
61 makefile \
62 msgroup.inc \
63 msmacro.inc
64
65msdisk.obj: msdisk.asm \
66 makefile \
67 msgroup.inc \
68 msequ.inc \
69 $(inc)\msbds.inc \
70 pushpop.inc \
71 msmacro.inc \
72 $(inc)\devsym.inc \
73 msdskpr.inc \
74 msioctl.inc $(inc)\ioctl.inc $(inc)\bpb.inc
75
76msinit.obj: msinit.asm \
77 makefile \
78 msgroup.inc \
79 msdskpr.inc \
80 msequ.inc $(inc)\msbds.inc \
81 $(inc)\cputype.inc \
82 msmacro.inc \
83 readcloc.inc \
84 clocksub.inc \
85 msextrn.inc
86
87
88sysinit1.obj: sysinit1.asm \
89 makefile \
90 msstack.inc \
91 msbio.cl4 \
92 msbio.cl5 \
93 stkinit.inc \
94 devmark.inc \
95 $(inc)\smifssym.inc \
96 $(inc)\devsym.inc \
97 $(inc)\ioctl.inc \
98 $(inc)\cputype.inc \
99 $(inc)\smdossym.inc $(inc)\dosmac.inc $(inc)\bpb.inc $(inc)\buffer.inc \
100 $(inc)\sysvar.inc $(inc)\vector.inc $(inc)\dirent.inc \
101 $(inc)\dpb.inc $(inc)\curdir.inc \
102 $(inc)\pdb.inc $(inc)\exe.inc $(inc)\sf.inc $(inc)\arena.inc \
103 $(inc)\intnat.inc $(inc)\mi.inc \
104 $(inc)\syscall.inc
105
106
107sysconf.obj: sysconf.asm \
108 makefile \
109 psoption.inc \
110 devmark.inc \
111 $(inc)\psdata.inc \
112 $(inc)\parse.asm \
113 $(inc)\smifssym.inc \
114 $(inc)\devsym.inc \
115 $(inc)\ioctl.inc \
116 $(inc)\smdossym.inc $(inc)\dosmac.inc $(inc)\bpb.inc $(inc)\buffer.inc \
117 $(inc)\sysvar.inc $(inc)\vector.inc $(inc)\dirent.inc \
118 $(inc)\dpb.inc $(inc)\curdir.inc \
119 $(inc)\pdb.inc $(inc)\exe.inc $(inc)\sf.inc $(inc)\arena.inc \
120 $(inc)\intnat.inc $(inc)\mi.inc \
121 $(inc)\syscall.inc
122
123sysinit2.obj: sysinit2.asm \
124 makefile \
125 devmark.inc \
126 $(inc)\copyrigh.inc \
127 $(inc)\smifssym.inc \
128 $(inc)\devsym.inc \
129 $(inc)\ioctl.inc \
130 $(inc)\smdossym.inc $(inc)\dosmac.inc $(inc)\bpb.inc $(inc)\buffer.inc \
131 $(inc)\sysvar.inc $(inc)\vector.inc $(inc)\dirent.inc \
132 $(inc)\dpb.inc $(inc)\curdir.inc \
133 $(inc)\pdb.inc $(inc)\exe.inc $(inc)\sf.inc $(inc)\arena.inc \
134 $(inc)\intnat.inc $(inc)\mi.inc \
135 $(inc)\syscall.inc
136
137sysimes.obj: sysimes.asm \
138 makefile \
139 msmacro.inc \
140 msbio.cl3 \
141 msequ.inc $(inc)\msbds.inc
142
143msbio2.obj: msbio2.asm \
144 makefile \
145 msgroup.inc \
146 msequ.inc \
147 $(inc)\msbds.inc \
148 $(inc)\devsym.inc \
149 pushpop.inc \
150 msmacro.inc \
151 msbio.cl2 \
152 ms96tpi.inc msvolid.inc
153
154mshard.obj: mshard.asm $(inc)\postequ.inc $(inc)\dseg.inc
155
156$(dest).sys: msbio.cl1 msbio1.obj mscon.obj msaux.obj \
157 mslpt.obj msclock.obj msdisk.obj msbio2.obj \
158 msinit.obj mshard.obj sysinit1.obj sysconf.obj \
159 sysinit2.obj sysimes.obj \
160 msload.com \
161 makefile
162 link @msbio.lnk
163 exe2bin msbio.exe msbio.bin <locscr
164 copy /b msload.com+msbio.bin $(dest).sys
165 del msbio.bin
166 del msbio.exe
167
diff --git a/v4.0/src/BIOS/MS96TPI.INC b/v4.0/src/BIOS/MS96TPI.INC
new file mode 100644
index 0000000..2760b00
--- /dev/null
+++ b/v4.0/src/BIOS/MS96TPI.INC
@@ -0,0 +1,536 @@
1%OUT MS96TPI.INC...
2;==============================================================================
3;REVISION HISTORY:
4;AN000 - New for DOS Version 4.00 - J.K.
5;AC000 - Changed for DOS Version 4.00 - J.K.
6;AN00x - PTM number for DOS Version 4.00 - J.K.
7;==============================================================================
8;AN001 - p2781 Changeline error behavior incompatibile with DOS 3.3 1/06/88 J.K.
9;==============================================================================
10;
11; DISK OPEN/CLOSE ROUTINES ARR 2.41
12;
13
14DSK$OPEN: ;ARR 2.41
15 PUBLIC DSK$OPEN
16
17 MESSAGE FTESTDISK,<"DISK OPEN ">
18 MNUM FTESTDISK,AX
19 MESSAGE FTESTDISK,<CR,LF>
20; AL IS LOGICAL DRIVE
21 CALL SETDRIVE ;GET BDS FOR DRIVE
22 INC WORD PTR DS:[DI].OPCNT
23 JMP EXIT ;ARR 2.41
24
25DSK$CLOSE: ;ARR 2.41
26 PUBLIC DSK$CLOSE
27
28 MESSAGE FTESTDISK,<"DISK CLOSE ">
29 MNUM FTESTDISK,AX
30 MESSAGE FTESTDISK,<CR,LF>
31; AL IS LOGICAL DRIVE
32 CALL SETDRIVE ;GET BDS FOR DRIVE
33 CMP WORD PTR DS:[DI].OPCNT,0
34 JZ EXITJX ; WATCH OUT FOR WRAP ARR 2.41
35 DEC WORD PTR DS:[DI].OPCNT
36EXITJX:
37 JMP EXIT
38
39; INPUT : DS:DI POINTS TO CURRENT BDS FOR DRIVE.
40; RETURN : ZERO SET IF NO OPEN FILES
41; ZERO RESET IF OPEN FILES
42CHKOPCNT:
43 MESSAGE FTEST96,<"CHECK OPEN COUNT ">
44 MNUM FTEST96,AX
45 MESSAGE FTEST96,<CR,LF>
46 CMP WORD PTR DS:[DI].OPCNT,0
47 RET
48
49;
50; AT MEDIA CHECK TIME, WE NEED TO REALLY GET DOWN AND CHECK WHAT THE CHANGE IS.
51; THIS IS GUARANTEED TO BE EXPENSIVE.
52;
53 PUBLIC MEDIACHECK
54MEDIACHECK:
55 CALL CHECKSINGLE ; MAKE SURE CORRECT DISK IS IN PLACE
56 XOR SI,SI
57 CALL HASCHANGE
58 JZ MEDIARET
59 CALL CHECKROMCHANGE
60 JNZ MEDIADOVOLID
61 PUSH AX
62 PUSH DX
63;SB33001****************************************************************
64 mov DL, DS:[DI.drivenum] ;SB ; set logical drive number ;3.30*
65 mov AH, 16h ;SB ; get changeline status ;3.30*
66 int 13h ;SB ; call rom diskette routine ;3.30*
67;SB33001****************************************************************
68 POP DX
69 POP AX
70 JC MEDIADOVOLID
71 MOV SI,1 ; SIGNAL NO CHANGE
72; THERE ARE SOME DRIVES WITH CHANGELINE THAT "LOSE" THE CHANGELINE INDICATION
73; IF A DIFFERENT DRIVE IS ACCESSED AFTER THE CURRENT ONE. IN ORDER TO AVOID
74; MISSING A MEDIA CHANGE, WE RETURN AN "I DON'T KNOW" TO DOS IF THE CHANGELINE
75; IS NOT ACTIVE AND WE ARE ACCESSING A DIFFERENT DRIVE FROM THE LAST ONE.
76; IF WE ARE ACCESSING THE SAME DRIVE, THEN WE CAN SAFELY RELY ON THE CHANGELINE
77; STATUS.
78 PUBLIC LOSECHNG
79LOSECHNG:
80 MOV BL,CS:[TIM_DRV] ; GET LAST DRIVE ACCESSED
81 CMP BYTE PTR [DI].DRIVENUM,BL
82 JZ MEDIARET
83; DO THE 2 SECOND TWIDDLE. IF TIME >= 2 SECONDS, DO A VOLID CHECK.
84; OTHERWISE RETURN "I DON'T KNOW" (STRICTLY SPEAKING, WE SHOULD RETURN A
85; "NOT CHANGED" HERE SINCE THE 2 SECOND TEST SAID NO CHANGE.) - RS.
86 SAVEREG <AX,CX,DX>
87 CALL CHECK_TIME_OF_ACCESS
88 RESTOREREG <DX,CX,AX>
89 OR SI,SI
90 JZ MEDIADOVOLID ; CHECK_TIME SAYS ">= 2 SECS PASSED"
91 XOR SI,SI ; RETURN "I DON'T KNOW"
92 PUBLIC MEDIARET
93MEDIARET:
94 RET
95;
96; SOMEHOW THE MEDIA WAS CHANGED. LOOK AT VID TO SEE. WE DO NOT LOOK AT FAT
97; BECAUSE THIS MAY BE DIFFERENT SINCE WE ONLY SET MEDBYT WHEN DOING A READ
98; OR WRITE.
99;
100MEDIADOVOLID:
101 CALL GETBP ; BUILD A NEW BPB IN CURRENT BDS
102 JC MEDIARET
103 CALL CHECK_VID
104 JNC MEDIARET
105 CALL MAPERROR ; FIX UP AL FOR RETURN TO DOS
106 RET
107;
108; SIMPLE, QUICK CHECK OF LATCHED CHANGE. IF NO INDICATION, THEN RETURN
109; OTHERWISE DO EXPENSIVE CHECK. IF THE EXPENSIVE TEST FAILS, POP OFF THE
110; RETURN AND SET AL = 15 (FOR INVALID MEDIA CHANGE) WHICH WILL BE RETURNED TO
111; DOS.
112;J.K. 9/16/86 For DOS 3.3, this will work only for the drive that has
113;J.K. 9/16/86 changeline.
114 PUBLIC CHECKLATCHIO
115CHECKLATCHIO:
116; IF RETURNING FAKE BPB THEN ASSUME THE DISK HAS NOT CHANGED
117; TEST WORD PTR DS:[DI].FLAGS, RETURN_FAKE_BPB
118; JNZ CHECKRET
119;J.K. 9/16/86
120; call HasChange ;change line supported?
121; jz CheckRet ;No. Just return
122 CALL CHKOPCNT
123 JNZ CHECKROM
124CHECKRET:
125 RET
126;
127; CHECK FOR PAST ROM INDICATIONS. IF NO ROM CHANGE INDICATED, THEN RETURN OK.
128;
129 PUBLIC CHECKROM
130CHECKROM:
131 CALL CHECKROMCHANGE
132 JZ CHECKRET ; NO CHANGE
133;
134; WE NOW SEE THAT A CHANGE LINE HAS BEEN SEEN IN THE PAST. LET'S DO THE
135; EXPENSIVE VERIFICATION.
136;
137 MESSAGE FTEST96,<"CHECKROMCHANGE SAYS YES...",CR,LF>
138 CALL GETBP ; BUILD BPB IN CURRENT BDS
139 JC RET_NO_ERROR_MAP ; GETBP HAS ALREADY CALLED MAPERROR
140 CALL CHECK_VID
141 JC CHECKLATCHRET ; DISK ERROR TRYING TO READ IN.
142 OR SI,SI ; IS CHANGED FOR SURE?
143 JNS CHECKRET
144 CALL RETURNVID
145CHECKLATCHRET:
146 CALL MAPERROR ; FIX UP AL FOR RETURN TO DOS
147RET_NO_ERROR_MAP:
148 STC
149 POP SI ; POP OFF RETURN ADDRESS
150 RET
151
152;
153; CHECK THE FAT AND THE VID. RETURN IN DI -1 OR 0. RETURN WITH CARRY SET
154; ONLY IF THERE WAS A DISK ERROR. RETURN THAT ERROR CODE IN AX.
155;
156 PUBLIC CHECKFATVID
157CHECKFATVID:
158 MESSAGE FTEST96,<"CHECK FAT",CR,LF>
159 CALL FAT_CHECK
160 OR SI,SI
161 JS CHANGED_DRV
162;
163; THE FAT WAS THE SAME. HOW ABOUT THE VOLUME ID?
164;
165CHECK_VID:
166;J.K. Now with the extended BOOT record, the logic should be enhanced.
167;If it is the extended BOOT record, then we check the volume serial
168;number instead of volume id. If it is different, then set SI to -1.
169;If it is same, then SI= 1 (No change).
170;If it is not the extended BOOT record, then just follows the old
171;logic. DOS 4.00 will check if the # of FAT in the boot record BPB
172;is not 0. If it is 0 then it must be Non_FAT based system and
173;should have already covered by extended boot structure checking.
174;So, we will return "I don't know" by setting SI to 0.
175;This routine assume the newest valid boot record is in CS:[DISKSECTOR].
176;(This will be gauranteed by a successful GETBP call right before this
177;routine.)
178 MESSAGE FTEST96,<"CHECK VID",CR,LF>
179;SB34MS96TPI001*********************************************************
180;SB check the EXT_Boot_Sig variable for the Extended boot signature
181;SB if it is set then go to do the extended ID check otherwise continue
182;SB with code below
183;SB 2 LOCS
184
185 cmp cs:[Ext_Boot_Sig],Ext_Boot_Signature
186 jz Do_Ext_Check_Id
187;SB34MS96TPI001*********************************************************
188 call HasChange ;AN000;
189 jz CheckRet ;AN000;
190
191 xor si,si ;AN000; assume I don't know.
192 cmp byte ptr cs:[SECPERCLUSINSECTOR]+3,0 ;AN000; Don't read vol id from
193 je CHECKFATRET ;AN000; the directory if not FAT system
194 CALL READ_VOLUME_ID
195 JC CHECKFATRET
196 CALL CHECK_VOLUME_ID
197 OR SI,SI
198 JNZ CHANGED_DRV
199 MESSAGE FTEST96,<"VID NOT CHANGED",CR,LF>
200
201VID_NO_Changed:
202 CALL RESETCHANGED
203 clc ;AN000;
204CHECKFATRET:
205 RET
206CHANGED_DRV:
207 MOV CS:[TIM_DRV],-1 ; ENSURE THAT WE ASK ROM FOR MEDIA
208 RET ; CHECK NEXT TIME ROUND
209 ;
210 ; extended ID check
211 ;
212Do_Ext_Check_ID: ;AN000;
213 push ax ;AN000;
214;SB34MS96TPI002**************************************************************
215;SB The code to check extended ID is basically a check to see if the
216;Sb volume serial number is still the same. The volume serial number
217;SB previously read is in cs:[Boot_Serial_H] and cs:[Boot_Serial_L]
218;SB high and low words respectively. DS:DI points to the BDS of the
219;SB drive under consideration. The BDS has fields containing the
220;SB high and low words of the volume serial number of the media in the
221;SB drive. Compare these fields to the fields mentioned above. If these
222;SB fields do not match the media has changed and so we should jump
223;SB to the code starting at Ext_Changed else return "I don't know" status
224;SB in the register used for the changeline status and continue executing
225;SB the code given below. For temporary storage use the register which
226;SB has been saved and restored around this block.
227;SB 7 LOCS
228;SB BDS fields in inc\msbds.inc
229
230 mov ax,cs:[Boot_Serial_L]
231 cmp ax,word ptr ds:[di+VOL_SERIAL]
232 jnz Ext_Changed
233 mov ax,cs:[Boot_Serial_H]
234 cmp ax,word ptr ds:[di+VOL_SERIAL+2]
235 jnz Ext_Changed
236 xor si,si ; don't know
237
238;SB34MS96TPI002**************************************************************
239 pop ax ;AN000;
240; jmp CheckFatRet ;AN000;
241 jmp VID_NO_Changed ;AN001;Reset the flag
242Ext_Changed: ;AN000; Serial number is different!
243 pop ax ;AN000;
244 mov si, -1 ;AN000; disk changed!
245 clc ;AN000; clear carry. Only SI is meaningful here.
246 jmp Changed_Drv ;AN000;
247
248;
249; AT I/O TIME, WE DETECTED THE ERROR. NOW WE NEED TO DETERMINE WHETHER THE
250; MEDIA WAS TRULY CHANGED OR NOT. WE RETURN NORMALLY IF MEDIA CHANGE UNKNOWN.
251; AND WE POP OFF THE CALL AND JMP TO HARDERR IF WE SEE AN ERROR.
252;
253 PUBLIC CHECKIO
254CHECKIO:
255 CMP AH,06
256 JNZ CHECKFATRET
257 CALL CHKOPCNT
258 JZ CHECKFATRET ; NO OPEN FILES
259; IF RETURNING FAKE BPB THEN IGNORE DISK CHANGES
260; TEST WORD PTR DS:[DI].FLAGS, RETURN_FAKE_BPB
261; JNZ IGNORECHANGE
262 CALL GETBP ; BUILD UP A NEW BPB IN CURRENT BDS
263 JC NO_ERROR_MAP ; GETBP HAS ALREADY CALLED MAPERROR
264 CALL CHECKFATVID
265 JC CHECKIORET ; DISK ERROR TRYING TO READ IN.
266 OR SI,SI ; IS CHANGED FOR SURE?
267 JS CHECKIOERR ; YES CHANGED
268IGNORECHANGE:
269 INC BP ; ALLOW A RETRY
270 RET
271CHECKIOERR:
272 CALL RETURNVID
273CHECKIORET:
274; POP SI ; POP OFF RETURN
275 STC ; MAKE SURE CARRY GETS PASSED THROUGH
276 JMP HARDERR
277
278NO_ERROR_MAP:
279 JMP HARDERR2
280;
281; RETURN VID SETS UP THE VID FOR A RETURN TO DOS.
282;
283 PUBLIC RETURNVID
284RETURNVID:
285 MESSAGE FTEST96,<"RETURN VID",CR,LF>
286 PUSH DS ; SAVE POINTER TO CURRENT BDS
287 PUSH DI
288 PUSH CX
289 CALL INIT_VID_LOOP ; SETS ES:DI -> VID
290 LDS BX,CS:[PTRSAV]
291 MOV [BX.EXTRA],DI
292 MOV [BX.EXTRA+2],ES
293 POP CX
294 POP DI ; RESTORE CURRENT BDS
295 POP DS
296 MOV AH,6 ; INVALID MEDIA CHANGE
297 STC
298 RET
299
300;
301; MUNGE THE TIME OF LAST SUCCESSFUL ACCESS FOR TWEEKED DRIVES
302;
303; DON'T NEED ANY MORE
304; TWEEKCHECK:
305; PUSH AX
306; MOV AX,WORD PTR DS:[DI].FLAGS
307; TEST AL,FCHANGED_BY_FORMAT
308; JZ TWEEKDONE
309; MOV CS:[TIM_DRV],-1
310; TWEEKDONE:
311; POP AX
312; RET
313
314;
315; DRIVE IS THE LOGICAL DRIVE TO USE
316;
317; FORMAT_MEDIA_CHECK: ;ARR 2.42
318; PUSH AX
319; MOV AX,WORD PTR DS:[DI].FLAGS
320; TEST AL,FCHANGED_BY_FORMAT
321; JZ RETF1 ; MEDIA NOT CHANGED VIA FORMAT
322; AND AL,NOT FCHANGED_BY_FORMAT
323; MOV WORD PTR [DI].FLAGS,AX ; RESET CHANGED_BY_FORMAT BIT
324; MOV SI,-1 ; MEDIA CHANGED VIA FORMAT
325; RETF1:
326; POP AX
327; RET
328
329;
330; MOVES THE POINTER TO THE VOLID FOR THE DRIVE INTO THE ORIGINAL REQUEST PACKET
331; ON ENTRY, DS:BX POINTS TO THE ORIGINAL PACKET.
332; NO ATTEMPT IS MADE TO PRESERVE REGISTERS.
333;
334MEDIA_SET_VID: ; ARR 2.42
335 PUBLIC MEDIA_SET_VID
336
337 CALL INIT_VID_LOOP ; SETS ES:DI -> VID
338 LDS BX,CS:[PTRSAV] ; GET POINTER TO PACKET
339 MOV WORD PTR [BX.TRANS+1],DI
340 MOV WORD PTR [BX.TRANS+3],ES
341 RET
342
343
344;
345; HIDENSITY - EXAMINE A DRIVE/MEDIA DESCRIPTOR TO SET THE MEDIA TYPE. IF
346; THE MEDIA DESCRIPTOR IS NOT F9 (NOT 96TPI OR 3 1/2), WE RETURN AND LET THE
347; CALLER DO THE REST. OTHERWISE, WE POP OFF THE RETURN AND JUMP TO THE TAIL
348; OF GETBP. FOR 3.5" MEDIA, WE JUST RETURN.
349;
350; INPUTS: DS:DI POINT TO CORRECT BDS FOR THIS DRIVE
351; AH HAS MEDIA BYTE
352;
353; OUTPUTS: CARRY CLEAR
354; NO REGISTERS MODIFIED
355; CARRY SET
356; AL = SECTORS/FAT
357; BH = NUMBER OF ROOT DIRECTORY ENTRIES
358; BL = SECTORS PER TRACK
359; CX = NUMBER OF SECTORS
360; DH = SECTORS PER ALLOCATION UNIT
361; DL = NUMBER OF HEADS
362;
363HIDENSITY:
364 PUBLIC HIDENSITY
365;
366; CHECK FOR CORRECT DRIVE
367;
368 TEST WORD PTR DS:[DI].FLAGS,FCHANGELINE ; IS IT SPECIAL?
369 JZ DOFLOPPY ; NO, DO NORMAL FLOPPY TEST
370;
371; WE HAVE A MEDIA BYTE THAT IS PRETTY COMPLEX. EXAMINE DRIVE INFORMATION
372; TABLE TO SEE WHAT KIND IT IS.
373;
374 CMP BYTE PTR DS:[DI].FORMFACTOR,FFSMALL; IS IT SINGLE-MEDIA?
375 JZ DOFLOPPY ; YES, USE FATID...
376;
377; 96 TPI DRIVE
378;
379 CMP AH,0F9H
380 JNZ DOFLOPPY
381 MOV AL,7 ; SEVEN SECTORS / FAT
382 MOV BX,224*256+0FH ; 224 ROOT DIR ENTRIES & 0F SECTOR MAX
383 MOV CX,80*15*2 ; 80 TRACKS, 15 SECTORS/TRACK, 2 SIDES
384 MOV DX,01*256+2 ; SECTORS/ALLOCATION UNIT & HEAD MAX
385POPR:
386 ADD SP,2 ; POP OFF RETURN ADDRESS
387 JMP HAS1 ; RETURN TO TAIL OF GETBP
388
389DOFLOPPY:
390 RET
391
392 PATHSTART 001,TPI96
393
394;
395; CERTAIN BOGUS PROGRAMS AVOID DOS ALTOGETHER AND USE INT 13 DIRECTLY. THESE
396; PROGRAMS EVEN RETRY OPERATIONS AND, THUS, WILL IGNORE THE DISK CHANGE LOGIC.
397;
398; WE HOOK INT 13 AND NOTE ALL ERRORS.
399;
400 ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
401 PUBLIC REAL13
402REAL13 DD ?
403OLDINT DD ?
404DMY DW ?
405
406 PATHEND 001,TPI96
407
408 PUBLIC INT13
409INT13 PROC FAR
410 POP WORD PTR OLDINT
411 POP WORD PTR OLDINT+2
412 POP DMY
413 MESSAGE FTEST13,<"*">
414 PUSHF
415 CALL REAL13 ; SIMULATE ANOTHER INT 13
416 JC ERR13 ; DID AN ERROR OCCUR?
417 JMP OLDINT ; NO, RETURN AND POP OFF FLAGS
418ERR13:
419 MESSAGE FTEST13,<"INT 13 ERROR ">
420 MNUM FTEST13,AX
421 MESSAGE FTEST13,<CR,LF>
422 PUSHF ; SAVE STATE
423 CMP AH,06H ; DID I SEE A CHANGE EVENT?
424 JZ GOTERR ; YES
425B: POPF ; NO, SOME OTHER ERROR, IGNORE IT
426 JMP OLDINT ; RETURN AND POP OFF FLAGS
427GOTERR: OR DL,DL ; IS THIS FOR THE HARD DISK?
428 JS B ; YES, IGNORE
429 MOV WORD PTR CS:[FLAGBITS],FCHANGED
430 CALL SET_CHANGED_DL
431 JMP B
432INT13 ENDP
433
434;
435; SET_CHANGED_DL - SETS FLAG BITS ACCORDING TO BITS SET IN [FLAGBITS].
436; ESSENTIALLY USED TO INDICATE CHANGELINE, OR FORMAT.
437;
438; INPUTS: DL CONTAINS PHYSICAL DRIVE NUMBER
439; [FLAGBITS] CONTAINS BITS TO SET IN THE FLAG FIELD IN THE BDSS
440; OUTPUTS: NONE
441; REGISTERS MODIFIED: FLAGS
442;
443SET_CHANGED_DL:
444 PUBLIC SET_CHANGED_DL
445
446 MESSAGE FTEST96,<"SET CHANGED",CR,LF>
447 PUSH BX
448 PUSH DX
449 MOV BL,DL
450ALL_SET:
451 MOV DX,CS:[FLAGBITS] ; GET BITS TO SET IN FLAG FIELD
452 XOR BH,BH
453;
454; IN THE VIRTUAL DRIVE SYSTEM WE *MUST* FLAG THE OTHER DRIVES AS BEING CHANGED
455;
456; ASSUME FIRST BDS IS IN THIS SEGMENT
457 PUSH AX
458 PUSH DS ; SAVE CURRENT BDS
459 PUSH DI
460 LDS DI,DWORD PTR CS:[START_BDS]
461SCAN_BDS:
462 CMP DI,-1
463 JZ SKIPSET
464 CMP BYTE PTR [DI].DRIVENUM,BL
465 JNZ GET_NEXT_BDS
466;
467; SOMEONE MAY COMPLAIN, BUT THIS *ALWAYS* MUST BE DONE WHEN A DISK CHANGE IS
468; NOTED. THERE ARE *NO* OTHER COMPROMISING CIRCUMSTANCES.
469;
470SETCHANGED:
471 OR WORD PTR DS:[DI].FLAGS,DX ; SIGNAL CHANGE ON OTHER DRIVE
472GET_NEXT_BDS:
473 MOV AX,WORD PTR [DI].LINK+2 ; GO TO NEXT BDS
474 MOV DI,WORD PTR [DI].LINK
475 MOV DS,AX
476 JMP SHORT SCAN_BDS
477SKIPSET:
478 POP DI ; RESTORE CURRENT BDS
479 POP DS
480 POP AX
481 POP DX
482 POP BX
483 RET
484
485;
486; CHECKROMCHANGE - SEE IF EXTERNAL PROGRAM HAS DIDDLED ROM CHANGE LINE.
487;
488; INPUTS: DS:DI POINTS TO CURRENT BDS.
489; OUTPUTS: ZERO SET - NO CHANGE
490; ZERO RESET - CHANGE
491; REGISTERS MODIFIED: NONE
492
493CHECKROMCHANGE:
494 MESSAGE FTEST13,<"CHECKROM ">
495 MNUM FTEST13
496 MESSAGE FTEST13,<CR,LF>
497 TEST WORD PTR [DI].FLAGS,FCHANGED
498 RET
499
500;
501; RESETCHANGED - RESTORE VALUE OF CHANGE LINE
502;
503; INPUTS: DS:DI POINTS TO CURRENT BDS
504; OUTPUTS: NONE
505; REGISTERS MODIFIED: NONE
506
507 public ResetChanged
508RESETCHANGED:
509 MESSAGE FTEST13,<"RESETCHANGED ">
510 MNUM FTEST13
511 MESSAGE FTEST13,<CR,LF>
512 AND WORD PTR DS:[DI].FLAGS,NOT FCHANGED
513 RET
514
515;
516; HASCHANGE - SEE IF DRIVE CAN SUPPLY CHANGE LINE
517;
518; INPUTS: DS:DI POINTS TO CURRENT BDS
519; OUTPUTS: ZERO SET - NO CHANGE LINE AVAILABLE
520; ZERO RESET - CHANGE LINE AVAILABLE
521; REGISTERS MODIFIED: NONE
522
523 PUBLIC HASCHANGE
524HASCHANGE:
525 MESSAGE FTEST13,<"HASCHANGE ">
526 MNUM FTEST13
527 MESSAGE FTEST13,<CR,LF>
528 TEST WORD PTR [DI].FLAGS,FCHANGELINE
529 RET
530
531 ASSUME DS:CODE
532
533 INCLUDE MSVOLID.INC
534
535 PUBLIC END96TPI
536END96TPI LABEL BYTE
diff --git a/v4.0/src/BIOS/MSAUX.ASM b/v4.0/src/BIOS/MSAUX.ASM
new file mode 100644
index 0000000..4d5a95e
--- /dev/null
+++ b/v4.0/src/BIOS/MSAUX.ASM
@@ -0,0 +1,281 @@
1 TITLE MSAUX - DOS 3.3
2;----------------------------------------------------------------
3; :
4; A U X - AUXILARY DEVICE DRIVER :
5; :
6; :
7; This file contains the Auxilary Device Driver. The :
8; auxilary driver handles calls to and from the RS-232 port. :
9; Three devices uses this code: AUX, COM1, and COM2. AUX and :
10; COM1 talk to the zero RS-232 card and COM2 talks to the :
11; 'one' RS-232 card. The beginning of the interrupt entry :
12; point for these devices sets the variable AUXNUM in the :
13; msbio.asm module. If the value is 0 the routines in this :
14; file will talk to the the 'zero' card. If the value in :
15; AUXNUM is 1 the routines will talk to the 'one' card. :
16; The procedure GETDX is called to put the value 0 or 1 in :
17; the DX register depending on the value in AUXBUF. :
18; :
19; The routines in this files are: :
20; :
21; routine function :
22; ------- -------- :
23; AUX$READ Read characters from the :
24; specified device. :
25; AUX$RDND Non-desrucrtive read with :
26; no waiting. :
27; AUX$FLSH Flush specified device input :
28; buffer. :
29; AUX$WRIT Write characters to the :
30; specified device. :
31; AUX$WRST Get status of specified :
32; device :
33; :
34; These routines are not called directly. Call are made via :
35; the strategy and interrupt entry point (see Device Header). :
36; :
37; Data structure: :
38; The Aux Device has a two byte buffer called AUXBUF. The :
39; first byte is for the zero card, the second byte is for the :
40; one card. A zero value in the byte indicates the buffer is :
41; empty. The routines use GETBX to get the address of the :
42; buffer. :
43; :
44;----------------------------------------------------------------
45
46;;Ver 3.30 modification ---------------------------
47 itest=0
48 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
49 INCLUDE JUMPMAC.INC
50 INCLUDE MSMACRO.INC
51
52 EXTRN ERR$CNT:NEAR ;MSBIO1
53 EXTRN GETDX:NEAR ;MSBIO1
54 EXTRN RDEXIT:NEAR ;MSCON
55 EXTRN EXIT:NEAR ;MSBIO1
56 EXTRN BUS$EXIT:NEAR ;MSBIO1
57 ;DATA
58 EXTRN AUXBUF:BYTE ;MSDATA
59
60; VALUES IN AH, REQUESTING FUNCTION OF INT 14H IN ROM BIOS
61AUXFUNC_SEND EQU 1 ;TRANSMIT
62AUXFUNC_RECEIVE EQU 2 ;READ
63AUXFUNC_STATUS EQU 3 ;REQUEST STATUS
64
65; ERROR FLAGS, REPORTED BY INT 14H
66
67; THESE FLAGS REPORTED IN AH:
68FLAG_DATA_READY EQU 01H ;DATA READY
69FLAG_OVERRUN EQU 02H ;OVERRUN ERROR
70FLAG_PARITY EQU 04H ;PARITY ERROR
71FLAG_FRAME EQU 08H ;FRAMING ERROR
72FLAG_BREAK EQU 10H ;BREAK DETECT
73FLAG_TRANHOL_EMP EQU 20H ;TRANSMIT HOLDING REGISTER EMPTY
74FLAG_TRANSHF_EMP EQU 40H ;TRANSMIT SHIFT REGISTER EMPTY
75FLAG_TIMEOUT EQU 80H ;TIMEOUT
76
77; THESE FLAGS REPORTED IN AL:
78FLAG_DELTA_CTS EQU 01H ;DELTA CLEAR TO SEND
79FLAG_DELTA_DSR EQU 02H ;DELTA DATA SET READY
80FLAG_TRAIL_RING EQU 04H ;TRAILING EDGE RING INDICATOR
81FLAG_DELTA_SIG EQU 08H ;DELTA RECEIVE LINE SIGNAL DETECT
82FLAG_CTS EQU 10H ;CLEAR TO SEND
83FLAG_DSR EQU 20H ;DATA SET READY
84FLAG_RING EQU 40H ;RING INDICATOR
85FLAG_REC_SIG EQU 80H ;RECEIVE LINE SIGNAL DETECT
86;;End of modification ------------------
87
88
89;----------------------------------------------------------------
90; :
91; Read zero or more characters from Auxilary Device :
92; :
93; input:es:[di] points to area to receive aux data :
94; cx has number of bytes to be read :
95; "auxnum" first byte has number of aux device (rel 0):
96; :
97;----------------------------------------------------------------
98 PUBLIC AUX$READ
99AUX$READ PROC NEAR
100 ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE
101 jcxz EXVEC2 ; if no characters, get out
102 call GETBX ; put address of AUXBUF in BX
103 xor AX,AX ; clear AX register
104 xchg AL,[BX] ; Get character , if any, from
105 ; buffer and clear buffer
106 or AL,AL ; if AL is nonzero there was a
107 ; character in the buffer
108 jnz AUX2 ; if so skip AUXIN call
109AUX1: ;
110 call AUXIN ; get character from port
111AUX2: ;
112 stosb ; store character
113 loop AUX1 ; if more character, go around again
114EXVEC2: ;
115 Jump EXIT ; all done, successful exit
116AUX$READ ENDP
117
118;
119; AUXIN: make a call on ROM BIOS to read character from
120; the auxilary device, then do some error checking.
121; If an error occurs then AUXIN jumps to ERR$CNT and
122; does NOT return to where it was called from.
123;
124
125AUXIN PROC NEAR
126
127 mov ah,AUXFUNC_RECEIVE
128 call AUXOP
129 ;check for Frame, Parity, or Overrun errors
130 ;WARNING: these error bits are unpredictable
131 ; if timeout (bit 7) is set
132 test ah,FLAG_FRAME or FLAG_PARITY or FLAG_OVERRUN
133 jz AROK ;No error if all bits are clear
134
135 ;Error getting character
136 add sp,+2 ;Remove rtn address (near call)
137 xor al,al
138 or al,FLAG_REC_SIG or FLAG_DSR or FLAG_CTS
139
140 JUMP ERR$CNT
141AROK:
142 RET ;CHAR JUST READ IS IN AL, STATUS IS IN AH
143AUXIN ENDP
144
145;----------------------------------------------------------------
146; :
147; Aux non-destructive read with no waiting :
148; :
149; input: es:[di] points to area to receive aux data :
150; :
151;----------------------------------------------------------------
152;
153 PUBLIC AUX$RDND
154AUX$RDND PROC NEAR
155 ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE
156 call GETBX ; have BX point to AUXBUF
157 mov AL,[BX] ; copy contents of buffer to AL
158 or AL,AL ; if AL is non-zero (char in buffer)
159 jnz AUXRDX ; then return character
160 call AUXSTAT ; if not, get status of AUX device
161 TEST AH,FLAG_DATA_READY ;TEST DATA READY
162 jz AUXBUS ; then device is busy (not ready)
163
164 TEST AL,FLAG_DSR ;TEST DATA SET READY
165 jz AUXBUS ; then device is busy (not ready)
166 call AUXIN ; else aux is ready, get character
167 call GETBX ; have bx point to AUXBUF
168 mov [BX],AL ; save character in buffer
169AUXRDX: ;
170 Jump RDEXIT ; return character
171
172AUXBUS: ;
173 Jump BUS$EXIT ; jump to device busy exit
174AUX$RDND ENDP
175
176;----------------------------------------------------------------
177; :
178; Aux Output Status :
179; :
180;----------------------------------------------------------------
181 PUBLIC AUX$WRST
182AUX$WRST PROC NEAR
183 ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE
184 call AUXSTAT ; get status of AUX in AX
185 ; now test to see if device is busy
186 ; if this bit is not set,
187;;Ver 3.30 modification -----------------------
188 TEST AL,FLAG_DSR ;TEST DATA SET READY
189 jz AUXBUS ; then device is busy (not ready)
190 TEST AH,FLAG_TRANHOL_EMP ;TEST TRANSMIT HOLD REG EMPTY
191;;End of modification -------------------------
192 jz AUXBUS ; then device is busy (not ready)
193 Jump Exit
194
195AUX$WRST ENDP
196
197;
198; AUXSTAT makes a call on the ROM-BIOS to determine the status
199; of the auxilary device
200; Outputs:
201; AX is filled with status of port.
202; DX is changes to specify which card - either 0, 1 (, 2, 3) ;ba
203; NO other registers are modified
204;
205
206AUXSTAT proc near
207 mov ah,AUXFUNC_STATUS
208 call AUXOP
209 ret
210AUXSTAT endp
211
212AUXOP PROC NEAR
213 ;AH=FUNCTION CODE
214 ;0=INIT, 1=SEND, 2=RECEIVE, 3=STATUS
215 call GETDX ; have DX point to proper card
216 int 14h ; call rom-bios for status
217 ret
218AUXOP ENDP
219
220;----------------------------------------------------------------
221; :
222; Flush AUX Input buffer - set contents of AUXBUF to zero :
223; :
224;----------------------------------------------------------------
225 PUBLIC AUX$FLSH
226AUX$FLSH PROC NEAR
227 ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE
228 call GETBX ; get BX to point to AUXBUF
229 mov BYTE PTR [BX],0 ; zero out buffer
230 Jump Exit ; all done, successful return
231AUX$FLSH ENDP
232
233
234
235;----------------------------------------------------------------
236; :
237; Write to Auxilary Device :
238; :
239;----------------------------------------------------------------
240 PUBLIC AUX$WRIT
241AUX$WRIT PROC NEAR
242 ASSUME DS:CODE ; SET BY AUX DEVICE DRIVER ENTRY ROUTINE
243 jcxz EXVEC2 ; if CX is zero, no characters
244 ; to be written, jump to exit
245AUX$LOOP:
246 mov AL,ES:[DI] ; get character to be written
247 inc DI ; move DI pointer to next character
248;;Ver 3.30 modification ---------------------------
249 MOV AH,AUXFUNC_SEND ;VALUE=1, INDICATES A WRITE
250 CALL AUXOP ;SEND CHARACTER OVER AUX PORT
251
252 TEST AH,FLAG_TIMEOUT ;CHECK FOR ERROR
253;;End of modification ---------------------------
254 jz AWOK ; then no error
255 mov AL,10 ; else indicate write fault
256 Jump ERR$CNT ; call error routines
257
258 ; if CX is non-zero, still more
259AWOK:
260 loop AUX$LOOP ; more characrter to print
261 Jump Exit ; all done, successful return
262AUX$WRIT ENDP
263
264
265;
266; GETBX puts the address of AUXBUF (the Auxilary Device buffer)
267; in BX. After calling GETBX, a routine can get to AUXBUF
268; with [BX].
269;
270; NOTE: The getdx routine is in msbio1 and looks like:
271; mov dx,word ptr cs:[auxnum]
272;
273GETBX PROC NEAR
274 call GETDX
275 mov BX,DX
276 add BX,OFFSET AUXBUF
277 ret
278GETBX ENDP
279
280CODE ENDS
281 END
diff --git a/v4.0/src/BIOS/MSBDATA.INC b/v4.0/src/BIOS/MSBDATA.INC
new file mode 100644
index 0000000..d0be320
--- /dev/null
+++ b/v4.0/src/BIOS/MSBDATA.INC
@@ -0,0 +1,722 @@
1;==============================================================================
2;REVISION HISTORY:
3;AN000 - New for DOS Version 3.4 - J.K.
4;AC000 - Changed for DOS Version 3.4 - J.K.
5;ANxxx - PTR, DCRs
6;==============================================================================
7;AN001 - d9 Double word MOV instruction for 80386 based machine. 7/1/87 J.K.
8;AN002 - d25 Change DASD ERP to that recommended by Storage Systems. 7/29/87 J.K.
9;AN003; d304 Boot record structure change for OS2 11/9/87 J.K.
10;==============================================================================
11 EXTRN INIT:NEAR
12
13 PUBLIC START$
14START$:
15 JMP INIT ;START$ PATCH BY INIT TO POINT TO
16 ;HDRIVE BPB
17; PUBLIC FORMAT_PATCH
18;FORMAT_PATCH: ;ARR 2.42
19; JMP FMTSET ;MJB001 DISPATCH FOR CALL FROM FORMAT UTILITY
20
21
22 PATHSTART 001,BIO
23
24; DB 20 DUP (0) ;IBM WANTS SOME ZEROED AREA (DELETED)
25
26
27;HEADER DB "Ver 2.45"
28;--------------------------------------------------------------
29;
30; COMMAND JUMP TABLES
31;
32; BEWARE - THESE TABLES OVERLAP SOMEWHAT! -C.P.
33;
34 ODD
35DSKTBL LABEL BYTE
36 DB 24 ; THIS IS THE SIZE OF THE TABLE YUK!!!!
37 DW DSK$INIT
38 DW MEDIA$CHK
39 DW GET$BPB
40 DW CMDERR ;RS
41 DW DSK$READ
42 DW BUS$EXIT
43 DW EXIT
44 DW EXIT
45 DW DSK$WRIT
46 DW DSK$WRITV
47 DW EXIT ;ARR 2.41
48 DW EXIT ;ARR 2.41
49 DW CMDERR ;RS
50
51 PUBLIC TABLE_PATCH
52TABLE_PATCH LABEL WORD ;ARR 2.42
53 DW DSK$OPEN ;ARR 2.41
54 DW DSK$CLOSE ;ARR 2.41
55 DW DSK$REM ;ARR 2.41
56 DW EXIT
57 DW EXIT
58 DW EXIT
59 DW GENERIC$IOCTL ; KGS 3.20
60 DW EXIT
61 DW EXIT
62 DW EXIT
63 DW IOCTL$GETOWN ; RS 3.20
64 DW IOCTL$SETOWN ; RE 3.20
65
66 ODD
67CONTBL LABEL BYTE
68 DB 10
69 DW EXIT
70 DW EXIT
71 DW EXIT
72 DW CMDERR
73 DW CON$READ
74 DW CON$RDND
75 DW EXIT
76 DW CON$FLSH
77 DW CON$WRIT
78 DW CON$WRIT
79 DW EXIT ;ARR 2.41
80
81; DW CMDERR ;J.K. 4/29/86 for CON$GENIOCTL support
82; DW CMDERR ;J.K. 4/29/86
83; DW CMDERR ;J.K. 4/29/86
84; DW CMDERR ;J.K. 4/29/86
85; DW CMDERR ;J.K. 4/29/86
86; DW CMDERR ;J.K. 4/29/86
87; DW CMDERR ;J.K. 4/29/86
88; DW CMDERR ;J.K. 4/29/86
89; DW CON$GENIOCTL ;J.K. 4/29/86
90
91 ODD
92AUXTBL LABEL BYTE
93 DB 10
94 DW EXIT
95 DW EXIT
96 DW EXIT
97 DW CMDERR
98 DW AUX$READ
99 DW AUX$RDND
100 DW EXIT
101 DW AUX$FLSH
102 DW AUX$WRIT
103 DW AUX$WRIT
104 DW AUX$WRST
105
106 ODD
107TIMTBL LABEL BYTE
108 DB 9
109 DW EXIT
110 DW EXIT
111 DW EXIT
112 DW CMDERR
113 DW TIM$READ
114 DW BUS$EXIT
115 DW EXIT
116 DW EXIT
117 DW TIM$WRIT
118 DW TIM$WRIT
119
120 ODD
121PRNTBL LABEL BYTE
122 DB 24
123 DW EXIT ;INIT
124 DW EXIT
125 DW EXIT
126 DW CMDERR
127 DW EXIT$ZER ;INDICATE ZERO CHARS READ
128 DW BUS$EXIT
129 DW EXIT
130 DW EXIT
131 DW PRN$WRIT
132 DW PRN$WRIT
133 DW PRN$STAT
134 DW EXIT
135 DW EXIT ;ARR 2.41
136 DW EXIT ;ARR 2.41
137 DW EXIT ;ARR 2.41
138 DW EXIT ;ARR 2.41
139 DW PRN$TILBUSY
140 DW EXIT ;RS 3.20
141 DW EXIT ;RS 3.20
142 DW PRN$GENIOCTL ;RS 3.20
143 DW EXIT ;RS 3.20
144 DW EXIT ;RS 3.20
145 DW EXIT ;RS 3.20
146 DW CMDERR ;RS 3.20
147 DW CMDERR ;RS 3.20
148
149 EVENB
150 PUBLIC OLD13 ;(MOVED HERE FROM IBMBIO2)
151OLD13 label DWORD
152 db '5986' ;J.K. 11/7/86 Secrete Code for DOS 3.30 IBMBIO.
153 PUBLIC ORIG13
154ORIG13 label DWORD
155 db '21',0,0 ;J.K. 11/8/86 This is my employee serial # !!!
156
157 EVENB
158 PUBLIC PTRSAV
159PTRSAV DD 0
160 PUBLIC AUXBUF
161AUXBUF DB 0,0,0,0 ;SET OF 1 BYTE BUFFERS FOR COM 1,2,3, AND 4
162
163 EVENB
164 PUBLIC PREVOPER,NUMBER_OF_SEC
165PREVOPER DW ? ; HOLDS INT 13 REQUEST (I.E. REGISTER AX).
166NUMBER_OF_SEC DB ? ; HOLDS NUMBER OF SECTORS TO READ ON AN ECC ERROR
167
168 IF ($-CODE) GT 100H
169 %OUT VDISK BUFFER NOT CORRECTLY LOCATED
170 ELSE
171 ORG 100H
172 ENDIF
173 PUBLIC VDISK_AREA
174VDISK_AREA DB 108 DUP(0) ;FOR USE BY VDISK
175
176 EVENB
177; WARNING!!! THESE ARE ADDRESSED TOGETHER IN GETDX
178AUXNUM DB 0 ;WHICH AUX DEVICE WAS REQUESTED
179 DB 0
180
181 EVENB
182 PUBLIC CONHEADER
183CONHEADER LABEL WORD ;HEADER FOR DEVICE "CON"
184 DD AUXDEV2
185 DW 1000000000010011B ;CON IN AND CON OUT + SPECIAL
186 DW STRATEGY
187 DW CON$IN
188 DB 'CON '
189
190 EVENB
191 PUBLIC AUXDEV2
192AUXDEV2 LABEL WORD ;HEADER FOR DEVICE "AUX"
193 DD PRNDEV2
194 DW 1000000000000000B
195 DW STRATEGY
196 DW AUX0$IN
197 DB 'AUX '
198
199 EVENB
200 PUBLIC PRNDEV2
201PRNDEV2 LABEL WORD ;HEADER FOR DEVICE "PRN"
202 DD TIMDEV
203 DW CHARDEV + OUTTILBUSY + DEV320
204 DW STRATEGY
205 DW PRN0$IN
206 DB 'PRN '
207
208 EVENB
209 PUBLIC TIMDEV
210TIMDEV LABEL WORD
211 DD DSKDEV
212 DW 1000000000001000B
213 DW STRATEGY
214 DW TIM$IN
215 DB 'CLOCK$ '
216
217 EVENB
218 PUBLIC DSKDEV
219DSKDEV LABEL WORD
220 DD COM1DEV
221 DW 0000100001000010B ;J.K.I1. 32 bit sector calculation
222 DW STRATEGY
223 DW DSK$IN
224DRVMAX DB 4
225 PUBLIC DRVMAX
226
227 PUBLIC STEP_DRV
228STEP_DRV DB -2 ; ARR 2.20 LAST DRIVE ACCESSED
229
230 PUBLIC PHYS_DRV
231PHYS_DRV DB 0 ; USED BY SETDRIVE FOR GETTING BDS FOR
232 ; LOGICAL DRIVE, OR PHYSICAL DRIVE.
233 PUBLIC FHAVE96
234FHAVE96 DB 0 ; FLAG TO INDICATE PRESENCE OF
235 ; 96TPI SUPPORT
236 PUBLIC SINGLE
237SINGLE DB 0 ; USED TO DETECT SINGLE DRIVE SYSTEMS
238
239 PUBLIC FHAVEK09
240FHAVEK09 DB 0 ;INDICATES IF THIS IS A K09 OR NOT
241 ; USED BY CONSOLE DRIVER.
242 PUBLIC NEW_ROM
243NEW_ROM DB 0 ;SET TO 1 IF WE HAVE A ROM THAT CAN
244 ; HANDLE STRANGE MEDIA LAYOUTS.
245
246 PUBLIC FSETOWNER
247FSETOWNER DB ? ;=1 IF WE ARE SETTING THE OWNER OF A
248 ;DRIVE. (EXAMINED BY CHECKSINGLE).
249 public Secrete_Code
250Secrete_Code dw 'jk' ;J.K. 11/7/86 Secrete code for DOS 3.30 IBMBIO.
251
252 EVENB
253 PUBLIC COM1DEV
254COM1DEV LABEL WORD
255 DD LPT1DEV
256 DW 1000000000000000B
257 DW STRATEGY
258 DW AUX0$IN
259 DB 'COM1 '
260
261 EVENB
262 PUBLIC LPT1DEV
263LPT1DEV LABEL WORD
264 DD LPT2DEV
265 DW CHARDEV + OUTTILBUSY + DEV320
266 DW STRATEGY
267 DW PRN1$IN
268 DB 'LPT1 '
269
270 EVENB
271 PUBLIC LPT2DEV
272LPT2DEV LABEL WORD
273 DD LPT3DEV
274 DW CHARDEV + OUTTILBUSY + DEV320
275 DW STRATEGY
276 DW PRN2$IN
277 DB 'LPT2 '
278
279 EVENB
280 PUBLIC LPT3DEV
281LPT3DEV LABEL WORD
282 DD COM2DEV
283 DW CHARDEV + OUTTILBUSY + DEV320
284 DW STRATEGY
285 DW PRN3$IN
286 DB 'LPT3 '
287
288 EVENB
289 PUBLIC COM2DEV
290COM2DEV LABEL WORD
291 DD COM3DEV
292 DW 1000000000000000B
293 DW STRATEGY
294 DW AUX1$IN
295 DB 'COM2 '
296
297 EVENB
298 PUBLIC COM3DEV
299COM3DEV LABEL WORD ;EDK
300 DD COM4DEV
301 DW 1000000000000000B
302 DW STRATEGY
303 DW AUX2$IN
304 DB 'COM3 '
305
306 EVENB
307 PUBLIC COM4DEV
308COM4DEV LABEL WORD ;EDK
309 DW -1,CODE
310 DW 1000000000000000B
311 DW STRATEGY
312 DW AUX3$IN
313 DB 'COM4 '
314
315; HARD-WIRE THE LINK TO THE NEXT INT2F HANDLER.
316 EVENB
317 PUBLIC NEXT2F_13
318NEXT2F_13 LABEL WORD
319 EXTRN INT2F_DISK:FAR ;IBMBIO2
320 DD INT2F_DISK
321
322 EVENB
323 PUBLIC START_BDS
324START_BDS LABEL WORD
325 DD BDS1 ;START OF BDS LINKED LIST.
326 PUBLIC ACCESSCOUNT
327ACCESSCOUNT DB 0 ; NUMBER OF TIMES MEDIA CHECK CALLED
328 PUBLIC TIM_DRV
329TIM_DRV DB -1 ; TIME WHEN LAST DISK I/O PERFORMED
330 PUBLIC FLAGBITS
331FLAGBITS DW 0 ; BITS TO SET IN FLAG FIELD WHEN DOING
332 ; A SET_CHANGED_DL
333 PUBLIC MEDBYT
334MEDBYT DB ?
335
336 EVENB
337 PUBLIC WRTVERIFY
338WRTVERIFY LABEL WORD
339 PUBLIC RFLAG
340RFLAG DB ROMREAD ;2 FOR READ, 3 FOR WRITE
341VERIFY DB 0 ;1 IF VERIFY AFTER WRITE
342 PUBLIC SECCNT
343SECCNT DW 0
344 PUBLIC HARDNUM
345HARDNUM DB 99 ;LOGICAL DRIVE NUMBER OF FIRST HARDFILE
346 PUBLIC MOTORSTARTUP,SETTLECURRENT,SETTLESLOW
347MOTORSTARTUP DB ? ; VALUE FROM TABLE
348SETTLECURRENT DB ? ; VALUE FROM TABLE
349SETTLESLOW DB ? ; SLOW SETTLE VALUE
350
351NEXTSPEED DB ? ; VALUE OF SPEED TO BE USED
352 public save_head_sttl
353Save_head_sttl db ? ;used by READ_SECTOR routine
354
355 PUBLIC EOT
356EOT DB 9
357
358 EVENB
359 PUBLIC DPT
360DPT DD ?
361
362;KEEP THE NEXT TWO ITEMS CONTIGUOUS - SEE IOCTL_BLOCK FOR REASON
363 PUBLIC CURSEC,CURHD,CURTRK,SPSAV
364CURSEC DB 0 ;CURRENT SECTOR
365CURHD DB 0 ;CURRENT HEAD
366CURTRK DW 0 ;CURRENT TRACK
367SPSAV DW 0 ;SAVE THE STACK POINTER
368
369; THE FOLLOWING ARE USED FOR IOCTL FUNCTION CALLS
370 PUBLIC FORMT_EOT,HDNUM,TRKNUM,GAP_PATCH
371FORMT_EOT DB 8 ; EOT USED FOR FORMAT
372HDNUM DB 0 ; HEAD NUMBER
373TRKNUM DW 0 ; TRACK BEING MANIPULATED
374GAP_PATCH DB 50H ; FORMAT GAP PATCHED INTO DPT
375
376;DISK ERRORS RETURNED FROM THE IBM ROM
377 PUBLIC ERRIN
378ERRIN LABEL BYTE
379 db 0cch ;AN002; Write Fault error
380 DB 80H ;NO RESPONSE
381 DB 40H ;SEEK FAILURE
382 DB 10H ;BAD CRC
383 DB 8 ;DMA OVERRUN
384 DB 6 ; MEDIA CHANGE
385 DB 4 ;SECTOR NOT FOUND
386 DB 3 ;WRITE ATTEMPT TO WRITE-PROTECT DISK
387 PUBLIC LSTERR
388LSTERR DB 0 ;ALL OTHER ERRORS
389
390;RETURNED ERROR CODES CORRESPONDING TO ABOVE
391 PUBLIC ERROUT
392ERROUT LABEL BYTE
393 db 10 ;AN002; Write Fault error
394 DB 2 ;NO RESPONSE
395 DB 6 ;SEEK FAILURE
396 DB 4 ;BAD CRC
397 DB 4 ;DMA OVERRUN
398 DB 15 ; INVALID MEDIA CHANGE
399 DB 8 ;SECTOR NOT FOUND
400 DB 0 ;WRITE ATTEMPT ON WRITE-PROTECT DISK
401 DB 12 ;GENERAL ERROR
402 PUBLIC NUMERR
403NUMERR = ERROUT-ERRIN
404
405;-------------------------------------------------------------
406
407; READ IN BOOT SECTOR HERE, READ DONE IN READBOOT.
408; ALSO READ SECTOR FOR DMA CHECK FOR HARD DISK.
409
410;J.K. The buffer for a disk sector is going to be at a double word boundary
411; for 80386 machine.
412
413 IF ($-CODE) Mod 4 ;AN001;
414 Org ($-CODE)+4-(($-CODE) Mod 4) ;AN001;
415 ENDIF ;AN001;
416
417 PUBLIC DISKSECTOR
418DiskSector DB 11 DUP(?) ; TAKE CARE OF 3 JUMP BYTES PLUS OEM NAME.
419 PUBLIC BPB_IN_SECTOR
420Bpb_In_Sector DW ?
421 PUBLIC SECPERCLUSINSECTOR
422SecPerClusInSector DB ?
423 DW ?
424 public NumberOfFats
425NumberOfFats DB ?
426 DW ?
427 DW ?
428 PUBLIC MEDIABYTE
429MediaByte DB ?
430 DW ?
431 DW ?
432 DW ?
433 DW ?
434 DW ? ;AN000; Extended Hidden sector (high)
435 DW ? ;AN000; Extended Total sector (low)
436 DW ? ;AN000; Extended Total sector (high)
437 db ? ;AN003; PHYDRV in boot record.
438 db ? ;AN003; CURRENT HEAD in boot record.
439 public Ext_Boot_Sig
440Ext_Boot_Sig DB ? ;AN000; Extended Boot record sig. (=90h)
441 public Boot_Serial_L
442Boot_Serial_L DW ? ;AN000; Boot volume serial number (Low)
443 public Boot_Serial_H
444Boot_Serial_H DW ? ;AN000; Boot volume serial number (High)
445 public Boot_Volume_Label
446Boot_Volume_Label DB 11 dup (' ') ;AN000; Volume label
447 public Boot_System_ID
448Boot_System_ID DB 8 dup (' ') ;AN000; File system Id.
449 DB 512-($-DISKSECTOR) DUP (?)
450
451;*********************************************************************
452; "BDS" CONTAINS INFORMATION FOR EACH DRIVE IN THE SYSTEM.
453; VARIOUS VALUES ARE PATCHED WHENEVER ACTIONS ARE PERFORMED.
454; SECTORS/ALLOC. UNIT IN BPB INITIALLY SET TO -1 TO SIGNIFY THAT
455; THE BPB HAS NOT BEEN FILLED. LINK ALSO SET TO -1 TO SIGNIFY END
456; OF LIST. # OF CYLINDERS IN MAXPARMS INITIALIZED TO -1 TO INDICATE
457; THAT THE PARAMETERS HAVE NOT BEEN SET.
458;
459 EVENB
460BDS1 LABEL WORD
461 DD BDS2 ;LINK TO NEXT STRUCTURE
462 DB 0 ;INT 13 DRIVE NUMBER
463 DB 0 ;LOGICAL DRIVE LETTER
464 PUBLIC FDRIVE1
465FDRIVE1 DW 512 ;PHYSICAL SECTOR SIZE IN BYTES
466 DB -1 ;SECTORS/ALLOCATION UNIT
467 DW 1 ;RESERVED SECTORS FOR DOS
468 DB 2 ;NO. ALLOCATION TABLES
469 DW 64 ;NUMBER DIRECTORY ENTRIES
470 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
471 DB 00000000B ;MEDIA DESCRIPTOR, INITIALLY 00H.
472 DW 2 ;NUMBER OF FAT SECTORS
473 DW 9 ;SECTOR LIMIT
474 DW 1 ;HEAD LIMIT
475 DW 0 ;HIDDEN SECTOR COUNT (low word)
476 dw 0 ;J.K. Hidden sector (high)
477 dw 0 ;J.K. Number sectors (low)
478 dw 0 ;J.K. Number sectors (high)
479 DB 0 ; TRUE => LARGE FATS
480OPCNT1 DW 0 ;OPEN REF. COUNT
481
482 DB 3 ;FORM FACTOR
483FLAGS1 DW 0020H ;VARIOUS FLAGS
484; DB 9 DUP (0) ;RESERVED FOR FUTURE USE
485 DW 40 ; NUMBER OF CYLINDERS
486; RECOMMENDED BPB FOR DRIVE.
487RECBPB1 DW 512 ;BYTES PER SECTOR
488 DB 1 ;SECTORS/ALLOCATION UNIT
489 DW 1 ;RESERVED SECTORS FOR DOS
490 DB 2 ;NO. ALLOCATION TABLES
491 DW 0E0H ;NUMBER DIRECTORY ENTRIES
492 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
493 DB 0F0H ;MEDIA DESCRIPTOR, INITIALLY F0H.
494 DW 2 ;NUMBER OF FAT SECTORS
495 DW 9 ;SECTOR LIMIT
496 DW 2 ;HEAD LIMIT
497 DW 0 ;HIDDEN SECTOR COUNT(low)
498 dw 0 ;J.K. Hidden sector count (high)
499 dw 0 ;J.K. Number sectors (low)
500 dw 0 ;J.K. Number sectors (high)
501 DB 6 DUP (?)
502TRACK1 DB -1 ;LAST TRACK ACCESSED ON THIS DRIVE
503TIM_LO1 DW -1 ;KEEP THESE TWO CONTIGUOUS (?)
504TIM_HI1 DW -1
505VOLID1 DB "NO NAME ",0 ;VOLUME ID FOR THIS DISK
506VOLSER1 dd 0 ;Current volume serial number from Boot record
507SYSID1 db "FAT12 ",0 ;Current file system id from Boot record
508
509 EVENB
510BDS2 LABEL WORD
511 DD BDS3 ;LINK TO NEXT STRUCTURE
512 DB 0 ;INT 13 DRIVE NUMBER
513 DB 0 ;LOGICAL DRIVE LETTER
514 PUBLIC FDRIVE2
515FDRIVE2 DW 512 ;PHYSICAL SECTOR SIZE IN BYTES
516 DB -1 ;SECTORS/ALLOCATION UNIT
517 DW 1 ;RESERVED SECTORS FOR DOS
518 DB 2 ;NO. ALLOCATION TABLES
519 DW 64 ;NUMBER DIRECTORY ENTRIES
520 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
521 DB 00000000B ;MEDIA DESCRIPTOR, INITIALLY 00H.
522 DW 2 ;NUMBER OF FAT SECTORS
523 DW 9 ;SECTOR LIMIT
524 DW 1 ;HEAD LIMIT
525 DW 0 ;HIDDEN SECTOR COUNT (low word)
526 dw 0 ;J.K. Hidden sector (high)
527 dw 0 ;J.K. Number sectors (low)
528 dw 0 ;J.K. Number sectors (high)
529 DB 0 ; TRUE => LARGE FATS
530OPCNT2 DW 0 ;OPEN REF. COUNT
531 DB 3 ;FORM FACTOR
532FLAGS2 DW 0020H ;VARIOUS FLAGS
533; DB 9 DUP (0) ;RESERVED FOR FUTURE USE
534 DW 40 ; NUMBER OF CYLINDERS
535; RECOMMENDED BPB FOR DRIVE.
536RECBPB2 DW 512 ;BYTES PER SECTOR
537 DB 1 ;SECTORS/ALLOCATION UNIT
538 DW 1 ;RESERVED SECTORS FOR DOS
539 DB 2 ;NO. ALLOCATION TABLES
540 DW 0E0H ;NUMBER DIRECTORY ENTRIES
541 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
542 DB 0F0H ;MEDIA DESCRIPTOR, INITIALLY F0H.
543 DW 2 ;NUMBER OF FAT SECTORS
544 DW 9 ;SECTOR LIMIT
545 DW 2 ;HEAD LIMIT
546 DW 0 ;HIDDEN SECTOR COUNT(low)
547 dw 0 ;J.K. Hidden sector count (high)
548 dw 0 ;J.K. Number sectors (low)
549 dw 0 ;J.K. Number sectors (high)
550 DB 6 DUP (?)
551TRACK2 DB -1 ;LAST TRACK ACCESSED ON THIS DRIVE
552TIM_LO2 DW -1 ;KEEP THESE TWO CONTIGUOUS (?)
553TIM_HI2 DW -1
554VOLID2 DB "NO NAME ",0 ;VOLUME ID FOR THIS DISK
555VOLSER2 dd 0 ;Current volume serial number from Boot record
556SYSID2 db "FAT12 ",0 ;Current file system id from Boot record
557
558 EVENB
559BDS3 LABEL WORD
560 DD BDS4 ;LINK TO NEXT STRUCTURE
561 DB 0 ;INT 13 DRIVE NUMBER
562 DB 0 ;LOGICAL DRIVE LETTER
563 PUBLIC FDRIVE3
564FDRIVE3 DW 512 ;PHYSICAL SECTOR SIZE IN BYTES
565 DB -1 ;SECTORS/ALLOCATION UNIT
566 DW 1 ;RESERVED SECTORS FOR DOS
567 DB 2 ;NO. ALLOCATION TABLES
568 DW 64 ;NUMBER DIRECTORY ENTRIES
569 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
570 DB 00000000B ;MEDIA DESCRIPTOR, INITIALLY 00H.
571 DW 2 ;NUMBER OF FAT SECTORS
572 DW 9 ;SECTOR LIMIT
573 DW 1 ;HEAD LIMIT
574 DW 0 ;HIDDEN SECTOR COUNT (low word)
575 dw 0 ;J.K. Hidden sector (high)
576 dw 0 ;J.K. Number sectors (low)
577 dw 0 ;J.K. Number sectors (high)
578 DB 0 ; TRUE => LARGE FATS
579OPCNT3 DW 0 ;OPEN REF. COUNT
580 DB 3 ;FORM FACTOR
581FLAGS3 DW 0020H ;VARIOUS FLAGS
582; DB 9 DUP (0) ;RESERVED FOR FUTURE USE
583 DW 40 ; NUMBER OF CYLINDERS
584; RECOMMENDED BPB FOR DRIVE.
585RECBPB3 DW 512 ;BYTES PER SECTOR
586 DB 1 ;SECTORS/ALLOCATION UNIT
587 DW 1 ;RESERVED SECTORS FOR DOS
588 DB 2 ;NO. ALLOCATION TABLES
589 DW 0E0H ;NUMBER DIRECTORY ENTRIES
590 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
591 DB 0F0H ;MEDIA DESCRIPTOR, INITIALLY F0H.
592 DW 2 ;NUMBER OF FAT SECTORS
593 DW 9 ;SECTOR LIMIT
594 DW 2 ;HEAD LIMIT
595 DW 0 ;HIDDEN SECTOR COUNT(low)
596 dw 0 ;J.K. Hidden sector count (high)
597 dw 0 ;J.K. Number sectors (low)
598 dw 0 ;J.K. Number sectors (high)
599 DB 6 DUP (?)
600TRACK3 DB -1 ;LAST TRACK ACCESSED ON THIS DRIVE
601TIM_LO3 DW -1 ;KEEP THESE TWO CONTIGUOUS (?)
602TIM_HI3 DW -1
603VOLID3 DB "NO NAME ",0 ;VOLUME ID FOR THIS DISK
604VOLSER3 dd 0 ;Current volume serial number from Boot record
605SYSID3 db "FAT12 ",0 ;Current file system id from Boot record
606
607 EVENB
608BDS4 LABEL WORD
609 DW -1 ;LINK TO NEXT STRUCTURE
610 DW CODE
611 DB 0 ;INT 13 DRIVE NUMBER
612 DB 0 ;LOGICAL DRIVE LETTER
613 PUBLIC FDRIVE4
614FDRIVE4 DW 512 ;PHYSICAL SECTOR SIZE IN BYTES
615 DB -1 ;SECTORS/ALLOCATION UNIT
616 DW 1 ;RESERVED SECTORS FOR DOS
617 DB 2 ;NO. ALLOCATION TABLES
618 DW 64 ;NUMBER DIRECTORY ENTRIES
619 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
620 DB 00000000B ;MEDIA DESCRIPTOR, INITIALLY 00H.
621 DW 2 ;NUMBER OF FAT SECTORS
622 DW 9 ;SECTOR LIMIT
623 DW 1 ;HEAD LIMIT
624 DW 0 ;HIDDEN SECTOR COUNT (low word)
625 dw 0 ;J.K. Hidden sector (high)
626 dw 0 ;J.K. Number sectors (low)
627 dw 0 ;J.K. Number sectors (high)
628 DB 0 ; TRUE => LARGE FATS
629OPCNT4 DW 0 ;OPEN REF. COUNT
630 DB 3 ;FORM FACTOR
631FLAGS4 DW 0020H ;VARIOUS FLAGS
632; DB 9 DUP (0) ;RESERVED FOR FUTURE USE
633 DW 40 ; NUMBER OF CYLINDERS
634; RECOMMENDED BPB FOR DRIVE.
635RECBPB4 DW 512 ;BYTES PER SECTOR
636 DB 1 ;SECTORS/ALLOCATION UNIT
637 DW 1 ;RESERVED SECTORS FOR DOS
638 DB 2 ;NO. ALLOCATION TABLES
639 DW 0E0H ;NUMBER DIRECTORY ENTRIES
640 DW 9*40 ;NUMBER SECTORS (AT 512 BYTES EA.)
641 DB 0F0H ;MEDIA DESCRIPTOR, INITIALLY F0H.
642 DW 2 ;NUMBER OF FAT SECTORS
643 DW 9 ;SECTOR LIMIT
644 DW 2 ;HEAD LIMIT
645 DW 0 ;HIDDEN SECTOR COUNT(low)
646 dw 0 ;J.K. Hidden sector count (high)
647 dw 0 ;J.K. Number sectors (low)
648 dw 0 ;J.K. Number sectors (high)
649 DB 6 DUP (?)
650TRACK4 DB -1 ;LAST TRACK ACCESSED ON THIS DRIVE
651TIM_LO4 DW -1 ;KEEP THESE TWO CONTIGUOUS (?)
652TIM_HI4 DW -1
653VOLID4 DB "NO NAME ",0 ;VOLUME ID FOR THIS DISK
654VOLSER4 dd 0 ;Current volume serial number from Boot record
655SYSID4 db "FAT12 ",0 ;Current file system id from Boot record
656
657BPBTYPE STRUC
658SPF DB ?
659SPT DB ?
660CDIRE DB ?
661CSEC DW ?
662SPA DB ?
663CHEAD DB ?
664BPBTYPE ENDS
665 PUBLIC SM92
666SM92 BPBTYPE <3,9,70H,2*9*80,2,2>
667
668;-----------------------------------------------
669;
670; C O N - CONSOLE DEVICE DRIVER
671;
672 PUBLIC ALTAH
673ALTAH DB 0 ;SPECIAL KEY HANDLING
674 public KEYRD_Func
675KEYRD_Func DB 0 ;AN000; Default is conventional keyboard read
676 public KEYSTS_Func
677KEYSTS_Func DB 1 ;AN000; Defualt if conventional keyboard status check.
678
679; PUBLIC SAV_SC_INFO ;J.K. 4/29/86 FOR CON$GENIOCTL
680; PUBLIC SAV_SC_MODE
681; PUBLIC SAV_SC_COLORS
682; PUBLIC SAV_SC_WIDTH
683; PUBLIC SAV_SC_LENGTH
684;SAV_SC_INFO LABEL BYTE
685;SAV_SC_MODE DB 0
686;SAV_SC_COLORS DW 0
687;SAV_SC_WIDTH DW 0
688;SAV_SC_LENGTH DW 0 ;J.K. 4/29/86 FOR CON$GENIOCTL
689
690;-------------------------------------------------------------
691;
692; P R N - PRINTER DEVICE
693;
694 PUBLIC PRINTDEV
695PRINTDEV DB 0 ; INDEX INTO ABOVE ARRAY
696
697; THE FOLLOWING VARIABLE CAN BE MODIFIED VIA IOCTL SUB-FUNCTION 16. IN THIS
698; WAY, THE WAIT CAN BE SET TO SUIT THE SPEED OF THE PARTICULAR PRINTER BEING
699; USED. ONE FOR EACH PRINTER DEVICE.
700
701 EVENB
702 PUBLIC WAIT_COUNT
703WAIT_COUNT DW 4 DUP (50H) ; ARRAY OF RETRY COUNTS FOR PRINTER
704
705 EVENB
706 PUBLIC DAYCNT
707DAYCNT DW 0
708
709
710 IF iTEST ;Testing Mode for IBMBIO.
711 PUBLIC NUMBUF
712NUMBUF DB 5 DUP (?)
713 PUBLIC DIGITS
714DIGITS DB "0123456789ABCDEF"
715 PUBLIC FTESTBITS
716;FTESTBITS DW FTESTDISK+FTESTINIT
717FTESTBITS DW fTestDISK
718;ftestbits dw ftestclock
719 ENDIF
720
721 PATHEND 001,BIO
722 \ No newline at end of file
diff --git a/v4.0/src/BIOS/MSBIO.LNK b/v4.0/src/BIOS/MSBIO.LNK
new file mode 100644
index 0000000..d1a15bd
--- /dev/null
+++ b/v4.0/src/BIOS/MSBIO.LNK
@@ -0,0 +1,14 @@
1msbio1+
2msCON+
3msAUX+
4msLPT+
5msCLOCK+
6msDISK+
7msBIO2+
8mshard+
9msinit+
10sysinit1+
11sysconf+
12sysinit2+
13sysimes,msbio,msBIO/M;
14 \ No newline at end of file
diff --git a/v4.0/src/BIOS/MSBIO.SKL b/v4.0/src/BIOS/MSBIO.SKL
new file mode 100644
index 0000000..9c890df
--- /dev/null
+++ b/v4.0/src/BIOS/MSBIO.SKL
@@ -0,0 +1,139 @@
1;==============================================================================
2;REVISION HISTORY:
3;AN000 - New for DOS Version 4.0 - J.K.
4;AC000 - Changed for DOS Version 4.0 - J.K.
5;AN00x - PTM number for DOS Version 4.0 - J.K.
6;==============================================================================
7;==============================================================================
8;AN001 D246, P976 Show "Bad command or parameters - ..." msg 9/22/87 J.K.
9;AN002 D274 Take "file" out from "Incorrect order..." msg 10/07/87 J.K.
10;AN003 D486 Share installation for large media 02/24/88 J.K.
11;==============================================================================
12;===================
13:class 1
14;===================
15; MESSAGES FOR THE IBM BOOT SECTOR. NUL Terminated.
16; This is used by IBMBOOT and IBMLOAD program and it stays in IBMBOOT directory.
17
18;For IBMLOAD program
19;SYSMSG DB 13,10,"Non-System disk or disk error",13,10
20; DB "Replace and strike any key when ready",13,10,0
21:use 001 BOOT SYSMSG
22
23;===================
24:class 2
25;===================
26; SCCSID = @(#)biomes.asm 1.2 85/07/25
27; SINGLE DRIVE MESSAGE FOR IBMBIO.COM. NUL TERMINATED.
28;IFNDEF PATHSTART
29;PATHSTART MACRO INDEX,ABBR
30; IFDEF PATHGEN
31; PUBLIC ABBR&INDEX&S,ABBR&INDEX&E
32; ABBR&INDEX&S LABEL BYTE
33; ENDIF
34; ENDM
35;ENDIF
36;
37;IFNDEF PATHEND
38;PATHEND MACRO INDEX,ABBR
39; IFDEF PATHGEN
40; ABBR&INDEX&E LABEL BYTE
41; ENDIF
42; ENDM
43;ENDIF
44; PATHSTART 001,BIOMS
45
46
47:def 20 SNGMSG DB 13,10,"Insert diskette for drive "
48:def 21 DRVLET DB "A: and strike",13,10,"any key when ready",13,10,10,0
49
50; PATHEND 001,BIOMS
51
52;==================
53:class 3
54;==================
55
56; PRINTED when there is a bad command in CONFIG.SYS. '$' TERMINATED, note
57; that this message includes crlfm!
58;PATHSTART 001,SYSMES
59
60:def 03 BADOPM DB 13,10,"Unrecognized command in CONFIG.SYS"
61
62;BADSIZ_POST LABEL BYTE
63;BADLD_POST LABEL BYTE
64
65:def 04 CRLFM DB 13,10,'$'
66
67:def 22 BadParm db 13,10,"Bad command or parameters - $" ;AN001;
68
69;PRINTED when installed device specifies too large a sector size.'$' terminated.
70; FORM: <BADSIZ_PRE>device name<BADSIZ_POST>
71:def 05 BADSIZ_PRE DB 13,10,"Sector size too large in file $"
72
73;PRINTED when installed device cannot be found. '$' terminated.
74; FORM: <BADLD_PRE>device name<BADLD_POST>
75:def 06 BADLD_PRE DB 13,10,"Bad or missing $"
76
77;PRINTED when command interpreter is not found. NUL terminated.
78; FORM: <BADLD_PRE><BADCOM><BADLD_POST>
79:def 07 BADCOM DB "Command Interpreter",0
80
81;PRINTED when country code, code page combination was not found in country.sys file. '$' terminated.
82; FORM: <BADCOUNTRY>
83:def 08 BADCOUNTRY DB 13,10,"Invalid country code or code page",13,10,"$"
84
85;PRINTED when code page id is missing or wrong syntax. - J.K.
86; FORM: <BADCOUNTRYCOM>
87:def 09 BADCOUNTRYCOM DB 13,10,"Error in COUNTRY command",13,10,"$"
88
89;PRINTED when the memory left is not sufficient to handle COUTRY.SYS file
90; FORM: <INSUFMEMORY>
91:def 10 INSUFMEMORY DB 13,10, "Insufficient memory for COUNTRY.SYS file",13,10,"$"
92
93; PRINTED when there is insufficient memory. '$' TERMINATED, note
94; that this message includes crlfm!
95:def 11 BADMEM DB 13,10,"Configuration too large for memory",13,10,"$"
96
97; PRINTED when the attempt is made to install a block device which would
98; have a drive letter > 'Z'
99:def 12 BADBLOCK DB 13,10,"Too many Block Devices",13,10,"$"
100
101; PRINTED when the attempt is made to install a stack with invalid
102; combinations of # of stacks, stack size. - J.K. 5/23/86
103:def 13 BADSTACK DB 13,10,"Invalid STACK parameters",13,10,"$"
104
105;AN000; - PRINTED when encountering a command that is not "install=" after
106; we had a "Install=" command. - J.K.I1.
107; Translation::: Please leave the last blank space at the end of the line
108; as it is.
109:def 14 BADORDER DB 13,10,"Incorrect order in CONFIG.SYS line ","$"
110
111;AN000; - PRINTED when the command failed.
112; Translation::: Please leave the last blank space at the end of the line
113; as it is.
114:def 15 ERRORCMD DB "Error in CONFIG.SYS line ","$"
115
116;AN003; - PRINTED when SHARE.EXE is not loaded and has a large media > 32 MB.
117:def 23 SHAREWARNMSG db "WARNING! SHARE should be loaded for large media",13,10,"$"
118
119;==================
120:class 4
121;==================
122;IBMBIO SYSINIT
123;Message for SYSINIT_BASE program.
124:def 16 Mem_alloc_err db 13,10,"Memory allocation error","$"
125
126
127;==================
128:class 5
129;==================
130; %OUT STKMES.INC...
131; SCCSID = @(#)stkmes.inc 1.0 86/10/21
132
133; PUBLIC FATAL_MSG
134:def 17 FATAL_MSG DB 0DH,0AH,7,0DH,0AH
135 DB "Internal stack overflow",0DH,0AH
136 DB "System halted",0DH,0AH,"$"
137;
138:END
139
diff --git a/v4.0/src/BIOS/MSBIO1.ASM b/v4.0/src/BIOS/MSBIO1.ASM
new file mode 100644
index 0000000..36dac91
--- /dev/null
+++ b/v4.0/src/BIOS/MSBIO1.ASM
@@ -0,0 +1,645 @@
1
2 PAGE ,132 ;
3 TITLE MSBIO1.asm - BIOS
4;==============================================================================
5;REVISION HISTORY:
6;AN000 - New for DOS Version 4.00 - J.K.
7;AC000 - Changed for DOS Version 4.00 - J.K.
8;AN00x - PTM number for DOS Version 4.00 - J.K.
9;==============================================================================
10COMMENT *
11THE LINK STEP IS PERFORMED BY USING THE FOLLOWING "NEW.ARF" FILE:
12msbio1+
13msSTACK+
14MsCON+
15msAUX+
16msLPT+
17msCLOCK+
18msdISK+
19msBIO2+
20C:\BIO2\OLDOBJ\disk+
21C:\BIO2\OLDOBJ\msinit+
22C:\BIO2\OLDOBJ\sysinit1+
23C:\BIO2\OLDOBJ\sysinit2+
24C:\BIO2\OLDOBJ\sysimes,msbio,/M;
25
26THE FOLLOWING IS A BATCH FILE THAT CAN BE USED TO CREATE THE IBMBIO.COM
27WHERE "LOCSCR" IS A FILE THAT JUST HAS THE NUMBER, 70:
28
29link @NEW.ARF
30exe2bin ibmbio ibmbio.com <C:\BIO2\Locscr
31del ibmbio.exe
32(END OF COMMENT)*
33
34;***For testing purposes, set the TEST flag to 1. Otherwise reset it.
35
36iTEST=0
37
38PATHGEN = 1
39
40.SALL
41 %OUT ...MSBIO1.ASM
42
43; THIS IS A DOSMAC MACRO WHICH IS USED IN DEVSYM WHICH IS INCLUDED LATER
44BREAK MACRO SUBTITLE
45 SUBTTL SUBTITLE
46 PAGE
47 ENDM
48
49POPFF MACRO
50 JMP $+3
51 IRET
52 PUSH CS
53 CALL $-2
54 ENDM
55
56 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
57
58SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
59SYSINITSEG ENDS
60
61
62 INCLUDE JUMPMAC.INC
63PATHSTART MACRO INDEX,ABBR
64 IFDEF PATHGEN
65 PUBLIC ABBR&INDEX&S,ABBR&INDEX&E
66 ABBR&INDEX&S LABEL BYTE
67 ENDIF
68 ENDM
69
70PATHEND MACRO INDEX,ABBR
71 IFDEF PATHGEN
72 ABBR&INDEX&E LABEL BYTE
73 ENDIF
74 ENDM
75
76 INCLUDE PUSHPOP.INC
77 INCLUDE DEVSYM.INC ;MJB001
78
79; REV 2.1 5/1/83 ARR ADDED TIMER INT HANDLER AND CHANGED ORDER OF AUX
80; PRN INIT FOR HAL0
81;
82; REV 2.15 7/13/83 ARR BECAUSE IBM IS FUNDAMENTALY BRAIN DAMAGED, AND
83; BASCOM IS RUDE ABOUT THE 1CH TIMER INTERRUPT, THE TIMER
84; HANDLER HAS TO GO BACK OUT!!!!! IBM SEEMS UNWILLING TO
85; BELIEVE THE PROBLEM IS WITH THE BASCOM RUNTIME, NOT THE
86; DOS. THEY HAVE EVEN BEEN GIVEN A PATCH FOR BASCOM!!!!!
87; THE CORRECT CODE IS COMMENTED OUT AND HAS AN ARR 2.15
88; ANNOTATION. THIS MEANS THE BIOS WILL GO BACK TO THE
89; MULTIPLE ROLL OVER BUG.
90; REV 2.20 8/5/83 ARR IBM MAKES HARDWARE CHANGE. NOW WANTS TO USE HALF
91; HIGHT DRIVES FOR HAL0, AND BACK FIT FOR PC/PC XT. PROBLEM
92; WITH HEAD SETTLE TIME. PREVIOUS DRIVES GOT BY ON A 0
93; SETTLE TIME, 1/2 HIGHT DRIVES NEED 15 HEAD SETTLE WHEN
94; DOING WRITES (0 OK ON READ) IF THE HEAD IS BEING STEPPED.
95; THIS REQUIRES A LAST TRACK VALUE TO BE KEPT SO THAT BIOS
96; KNOWS WHEN HEAD IS BEING MOVED. TO HELP OUT STUPID
97; PROGRAMS THAT ISSUE INT 13H DIRECTLY, THE HEAD SETTLE WILL
98; NORMALLY BE SET TO 15. IT WILL BE CHANGED TO 0 ON READS,
99; OR ON WRITES WHICH DO NOT REQUIRE HEAD STEP.
100; REV 2.21 8/11/83 MZ IBM WANTS WRITE WITH VERIFY TO USE HEAD SETTLE 0.
101; USE SAME TRICK AS ABOVE.
102; REV 2.25 6/20/83 MJB001 ADDED SUPPORT FOR 96TPI AND SALMON
103; REV 2.30 6/27/83 MJB002 ADDED REAL-TIME CLOCK
104; REV 2.40 7/8/83 MJB003 ADDED VOLUME-ID CHECKING AND INT 2F MACRO
105; DEFINITIONS PUSH* AND POP*
106; REV 2.41 7/12/83 ARR MORE 2.X ENHANCEMENTS. OPEN/CLOSE MEDIA CHANGE
107; REV 2.42 11/3/83 ARR MORE 2.X ENHANCEMENTS. DISK OPEN/CLOSE, FORMAT
108; CODE AND OTHER MISC HOOKED OUT TO SHRINK BIOS. CODE FOR
109; DISK OPEN/CLOSE, FORMAT INCLUDED ONLY WITH 96TPI DISKS.
110; REV 2.43 12/6/83 MZ EXAMINE BOOT SECTORS ON HARD DISKS FOR 16-BIT FAT
111; CHECK. EXAMINE LARGE FAT BIT IN BPB FOR WALK OF MEDIA FOR
112; DOS
113; REV 2.44 12/9/83 ARR CHANGE TO ERROR REPORTING ON INT 17H
114; REV 2.45 12/22/83 MZ MAKE HEAD SETTLE CHANGE ONLY WHEN DISK PARM IS 0.
115
116;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
117;
118; IBM ADDRESSES FOR I/O
119;
120;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
121
122 INCLUDE MSDSKPR.INC
123
124LF = 10 ;LINE FEED
125CR = 13 ;CARRIAGE RETURN
126BACKSP = 8 ;BACKSPACE
127BRKADR = 1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS
128TIMADR = 1CH * 4 ;0070 1CH TIMER INTERRUPT
129DSKADR = 1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS
130SEC9 = 522H ;ADDRESS OF DISK PARAMETERS
131HEADSETTLE = SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME
132NORMSETTLE = 15 ; ARR 2.20 NORMAL HEAD SETTLE
133SPEEDSETTLE = 0 ; ARR 2.20 SPEED UP SETTLE TIME
134INITSPOT = 534H ; ARR IBM WANTS 4 ZEROS HERE
135AKPORT = 20H
136EOI = 20H
137
138 ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
139
140 EXTRN MEDIA$CHK:NEAR
141 EXTRN GET$BPB:NEAR
142 EXTRN DSK$INIT:NEAR
143 EXTRN DSK$READ:NEAR
144 EXTRN DSK$WRIT:NEAR
145 EXTRN DSK$WRITV:NEAR
146 EXTRN DSK$OPEN:NEAR
147 EXTRN DSK$CLOSE:NEAR
148 EXTRN DSK$REM:NEAR
149 EXTRN GENERIC$IOCTL:NEAR
150 EXTRN IOCTL$GETOWN:NEAR
151 EXTRN IOCTL$SETOWN:NEAR
152 EXTRN CON$READ:NEAR
153 EXTRN CON$RDND:NEAR
154 EXTRN CON$FLSH:NEAR
155 EXTRN CON$WRIT:NEAR
156; EXTRN CON$GENIOCTL:NEAR ;J.K. 4/29/86
157 EXTRN AUX$READ:NEAR
158 EXTRN AUX$WRIT:NEAR
159 EXTRN AUX$FLSH:NEAR
160 EXTRN AUX$RDND:NEAR
161 EXTRN AUX$WRST:NEAR
162 EXTRN TIM$READ:NEAR
163 EXTRN TIM$WRIT:NEAR
164 EXTRN PRN$WRIT:NEAR
165 EXTRN PRN$STAT:NEAR
166 EXTRN PRN$TILBUSY:NEAR
167 EXTRN PRN$GENIOCTL:NEAR
168 EXTRN WRMSG:NEAR
169
170;DATA AREAS
171 extrn Start_Sec_H:word ;AN000; Starting sector high word for
172 ;disk I/O request. IBMDISK.ASM
173
174 INCLUDE MSBDATA.INC
175
176 IF iTEST
177 PUBLIC MSGNUM
178MSGNUM:
179 PUSHF
180 TEST FTESTBITS,AX
181 JZ MRET
182 PUSH SI
183 PUSH BX
184 PUSH CX
185 PUSH ES
186 PUSH DI
187 MOV DI,OFFSET NUMBUF
188 PUSH CS
189 POP ES
190 MOV CX,4
191NUMLOOP:
192 PUSH CX
193 MOV CL,4
194 ROL BX,CL
195 POP CX
196 PUSH BX
197 AND BX,0FH
198 MOV AL,DIGITS[BX]
199 STOSB
200 POP BX
201 LOOP NUMLOOP
202 POP DI
203 POP ES
204 POP CX
205 POP BX
206 MOV SI,OFFSET NUMBUF
207 CALL MSGOUT
208 POP SI
209 POPF
210 RET
211
212 PUBLIC MSGOUT
213MSGOUT:
214 PUSHF
215 TEST FTESTBITS,AX
216 JZ MRET
217 PUSH DS
218 PUSH AX
219 PUSH BX
220 PUSH CS
221 POP DS
222 CALL WRMSG
223 POP BX
224 POP AX
225 POP DS
226MRET:
227 POPF
228 RET
229
230 PUBLIC DUMPBYTES ;J.K. 4/9/86
231;Dumpbytes will dump the bytes in memory in hex. Space will be put in between
232;the bytes and CR, LF will be put at the end. - J.K.
233;Input: DS:SI -> buffer to dump in Hex.
234; CX -> # of bytes (Length of the buffer)
235;
236DUMPBYTES proc near
237 pushf
238 push ax
239dumploops:
240 lodsb
241 mov ah, al
242 shr ah, 1
243 shr ah, 1
244 shr ah, 1
245 shr ah, 1
246 call hex_to_ascii
247 push ax
248 mov al, ah
249 call outchar
250 pop ax
251 call outchar
252 mov al, ' '
253 call outchar
254 loop dumploops
255
256 mov al, 0dh
257 call outchar
258 mov al, 0ah
259 call outchar
260
261 pop ax
262 popf
263 ret
264DUMPBYTES endp
265
266 PUBLIC Hex_to_ascii
267Hex_to_ascii proc near ;J.K. - 4/9/86
268 and ax, 0f0fh
269 add ah, 30h
270 cmp ah, 3ah
271 jb hta_$1
272 add ah, 7
273hta_$1:
274 add al, 30h
275 cmp al, 3ah
276 jb hta_$2
277 add al, 7
278hta_$2:
279 ret
280Hex_to_ascii endp
281
282 PUBLIC outchar
283Outchar proc near
284 PUSH AX
285 PUSH SI
286 PUSH DI
287 PUSH BP
288 PUSH BX
289;SB33002*******************************************************
290 MOV AH, 0Eh ;SET COMMAND TO WRITE A CHAR ;SB;3.30*
291 MOV BX, 7 ;SET FOREGROUND COLOR ;SB;3.30*
292 INT 10h ;CALL ROM-BIOS ;SB;3.30*
293;SB33002*******************************************************
294 POP BX
295 POP BP
296 POP DI
297 POP SI
298 POP AX
299 RET
300Outchar endp
301
302 ENDIF
303 INCLUDE MSMACRO.INC
304
305;---------------------------------------------------
306;
307; DEVICE ENTRY POINT
308;
309CMDLEN = 0 ;LENGTH OF THIS COMMAND
310UNIT = 1 ;SUB UNIT SPECIFIER
311CMD = 2 ;COMMAND CODE
312STATUS = 3 ;STATUS
313MEDIA = 13 ;MEDIA DESCRIPTOR
314TRANS = 14 ;TRANSFER ADDRESS
315COUNT = 18 ;COUNT OF BLOCKS OR CHARACTERS
316START = 20 ;FIRST BLOCK TO TRANSFER
317EXTRA = 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15
318START_L = 26 ;AN000; Extended start sector (Low)
319START_H = 28 ;AN000; Extended start sector (High)
320
321 PUBLIC STRATEGY
322STRATEGY PROC FAR
323 MOV WORD PTR CS:[PTRSAV],BX
324 MOV WORD PTR CS:[PTRSAV+2],ES
325 RET
326STRATEGY ENDP
327
328 PUBLIC CON$IN
329CON$IN PROC FAR
330 PUSH SI
331 MOV SI,OFFSET CONTBL
332 JMP SHORT ENTRY
333CON$IN ENDP
334
335 PUBLIC AUX0$IN
336AUX0$IN PROC FAR
337 PUSH SI
338 PUSH AX
339 XOR AL,AL
340 JMP SHORT AUXENT
341AUX0$IN ENDP
342
343 PUBLIC AUX1$IN
344AUX1$IN PROC FAR
345 PUSH SI
346 PUSH AX
347 MOV AL,1
348 JMP short AUXENT ;J.K. 4/15/86
349AUX1$IN ENDP
350
351;SB33102****************************************************************
352;SB Add code to handle two more COM Ports
353;boban
354
355 PUBLIC AUX2$IN
356AUX2$IN proc far
357 push si
358 push ax
359 mov al,2
360 jmp short AUXENT
361AUX2$IN endp
362
363 PUBLIC AUX3$IN
364AUX3$IN proc far
365 push si
366 push ax
367 mov al,3
368 jmp short AUXENT
369
370;SB33102****************************************************************
371
372AUXENT:
373 MOV SI,OFFSET AUXTBL
374 JMP SHORT ENTRY1
375AUX3$IN ENDP
376
377PRN0$IN PROC FAR
378 PUBLIC PRN0$IN
379
380 PUSH SI
381 PUSH AX
382 XOR AX,AX
383 JMP SHORT PRNENT
384PRN0$IN ENDP
385
386 PUBLIC PRN1$IN
387PRN1$IN PROC FAR
388 PUSH SI
389 PUSH AX
390 XOR AL,AL
391 MOV AH,1
392 JMP SHORT PRNENT
393PRN1$IN ENDP
394
395 PUBLIC PRN2$IN
396PRN2$IN PROC FAR
397 PUSH SI
398 PUSH AX
399 MOV AL,1
400 MOV AH,2
401 JMP SHORT PRNENT
402PRN2$IN ENDP
403
404 PUBLIC PRN3$IN
405PRN3$IN PROC FAR
406 PUSH SI
407 PUSH AX
408 MOV AL,2
409 MOV AH,3
410PRNENT:
411 MOV SI,OFFSET PRNTBL
412 MOV CS:[PRINTDEV],AH ;SAVE INDEX INTO ARRAY OF RETRY COUNTS
413 JMP SHORT ENTRY1
414PRN3$IN ENDP
415
416 PUBLIC TIM$IN
417TIM$IN PROC FAR
418 PUSH SI
419 MOV SI,OFFSET TIMTBL
420 JMP SHORT ENTRY
421TIM$IN ENDP
422
423 PUBLIC DSK$IN
424DSK$IN PROC FAR
425 PUSH SI
426 MOV SI,OFFSET DSKTBL
427
428ENTRY:
429 PUSH AX
430ENTRY1:
431 PUSH CX
432 PUSH DX
433 PUSH DI
434 PUSH BP
435 PUSH DS
436 PUSH ES
437 PUSH BX
438
439 MOV CS:[AUXNUM],AL ;SAVE CHOICE OF AUX/PRN DEVICE
440
441 LDS BX,CS:[PTRSAV] ;GET POINTER TO I/O PACKET
442 ASSUME DS:NOTHING
443
444 MOV AL,BYTE PTR DS:[BX].UNIT ;AL = UNIT CODE
445 MOV AH,BYTE PTR DS:[BX].MEDIA ;AH = MEDIA DESCRIP
446 MOV CX,WORD PTR DS:[BX].COUNT ;CX = COUNT
447 MOV DX,WORD PTR DS:[BX].START ;DX = START SECTOR
448
449;SB34MSB100*********************************************************************
450;SB
451;SB The disk device driver can now handle 32 bit start sector number.
452;SB So we should check to see if a 32 bit sector number has been specified
453;SB and if so get it. Whether a 32 bit sector has been specified or not
454;SB the disk driver expects a 32 bit sector number with the high word
455;SB in cs:Start_Sec_H and the low word in dx.
456;SB
457;SB Algorithm:
458;SB 1. Check to see if the request is for the disk driver by
459;SB checking to see if SI points to DSKTBL.
460;SB
461;SB 2. If request not for the disk nothing special needs to be done.
462;SB
463;SB 3. If request for the disk then check to see if a 32 bit
464;SB sector number has been specified by seeing whether the
465;SB the conventional sector number specified is -1. If so
466;SB we need to pick the 32 bit sector number from the new
467;SB fields in the request packet. See the request header
468;SB struc for the fields you need. If the conventional
469;SB sector field is not -1 then a 16 bit sector number
470;SB has been specified and we just need to initalise the
471;SB high word in cs:Start_Sec_H to 0
472;SB
473;SB NOTE: START_L and START_H are the offsets withing the IO_REQUEST packet
474;SB which contain the low and hi words of the 32 bit start sector if
475;SB it has been used.
476;SB
477;SB NOTE:Remember not to destroy the registers which have been set up before
478
479 CMP SI,OFFSET DSKTBL
480 JNZ DSK_REQ_CONT ; Not Disk Req
481 CMP DX,-1
482 JNZ DSK_REQ_16
483 MOV DX,DS:[BX].START_H ; 32 bits DSK REQ
484 MOV CS:START_SEC_H,DX ; CS:Start_sec_H = Packet.Start_H
485 MOV DX,DS:[BX].START_L ; DX = Packet.Start_L
486 JMP SHORT DSK_REQ_CONT
487DSK_REQ_16:
488 MOV CS:START_SEC_H,0
489DSK_REQ_CONT:
490
491;SB34MSB100*********************************************************************
492
493 XCHG DI,AX
494 MOV AL,BYTE PTR DS:[BX].CMD
495 CMP AL,CS:[SI] ;ARR 2.41
496 JA CMDERR
497
498 CBW ; NOTE THAT AL <= 15 MEANS OK
499 SHL AX,1
500
501 ADD SI,AX
502 XCHG AX,DI
503
504 LES DI,DWORD PTR DS:[BX].TRANS
505
506 PUSH CS
507 POP DS
508
509 ASSUME DS:CODE
510
511 CLD
512 JMP WORD PTR [SI+1] ;GO DO COMMAND
513DSK$IN ENDP
514 PAGE
515;=====================================================
516;=
517;= SUBROUTINES SHARED BY MULTIPLE DEVICES
518;=
519;=====================================================
520;----------------------------------------------------------
521;
522; EXIT - ALL ROUTINES RETURN THROUGH THIS PATH
523;
524 PUBLIC BUS$EXIT
525BUS$EXIT PROC FAR
526 ASSUME DS:NOTHING
527 MOV AH,00000011B
528 JMP SHORT ERR1
529
530 PUBLIC CMDERR
531CMDERR:
532 MOV AL,3 ;UNKNOWN COMMAND ERROR
533
534 PUBLIC ERR$CNT
535ERR$CNT:
536 LDS BX,CS:[PTRSAV]
537 ASSUME DS:NOTHING
538 SUB WORD PTR [BX].COUNT,CX ;# OF SUCCESSFUL I/O'S
539
540 PUBLIC ERR$EXIT
541ERR$EXIT:
542 MOV AH,10000001B ;MARK ERROR RETURN
543 JMP SHORT ERR1
544BUS$EXIT ENDP
545
546EXITP PROC FAR
547 ASSUME DS:CODE ; WE ARE NOT SURE THIS IS CORRECT 3/18/86
548EXIT$ZER:
549 LDS BX,[PTRSAV]
550 ASSUME DS:NOTHING
551 XOR AX,AX
552 MOV WORD PTR [BX].COUNT,AX ;INDICATE NO CHARS READ
553
554 PUBLIC EXIT
555EXIT:
556 ASSUME DS:NOTHING
557 MOV AH,00000001B
558ERR1:
559 ASSUME DS:NOTHING
560 LDS BX,CS:[PTRSAV]
561 MOV WORD PTR [BX].STATUS,AX ;MARK OPERATION COMPLETE
562
563 POP BX
564 POP ES
565 POP DS
566 POP BP
567 POP DI
568 POP DX
569 POP CX
570 POP AX
571 POP SI
572 RET ;RESTORE REGS AND RETURN
573EXITP ENDP
574
575;-------------------------------------------------------------
576;
577; CHROUT - WRITE OUT CHAR IN AL USING CURRENT ATTRIBUTE
578;
579; CALLED VIA INT 29H
580;
581 PUBLIC CHROUT
582CHROUT = 29H
583
584 PUBLIC OUTCHR
585OUTCHR PROC FAR
586 PUSH AX
587 PUSH SI
588 PUSH DI
589 PUSH BP
590;SB33002a*******************************************************
591 push bx ; ;SB ;3.30
592 mov AH, 0Eh ; set command to write a character;SB;3.30
593 mov BX, 7 ; set foreground color ;SB ;3.30
594 int 10h ; call rom-bios ;SB ;3.30
595 pop bx ; ;SB ;3.30
596;SB33002a*******************************************************
597 POP BP
598 POP DI
599 POP SI
600 POP AX
601 IRET
602OUTCHR ENDP
603;----------------------------------------------
604;
605; SET DX TO AUXNUM
606;
607 PUBLIC GETDX
608GETDX PROC NEAR
609 MOV DX,WORD PTR CS:[AUXNUM]
610 RET
611GETDX ENDP
612 PAGE
613;************************************************** ARR 2.15
614
615;-----------------------------------------------
616;
617; TIMER INTERRUPT HANDLER
618;
619;TIMER_LOW DW 0
620;TIMER_HIGH DW 0
621;
622;TIMER:
623; STI
624; PUSH AX
625; PUSH CX
626; PUSH DX
627; PUSH DS
628; PUSH CS
629; POP DS
630; XOR AX,AX
631; INT 1AH ; GET ROM TIME AND ZAP ROLL OVER
632; MOV [TIMER_HIGH],CX
633; MOV [TIMER_LOW],DX
634; OR AL,AL
635; JZ T5
636; INC WORD PTR [DAYCNT] ; ONE DAY GONE BY
637;T5:
638; POP DS
639; POP DX
640; POP CX
641; POP AX
642; IRET
643;************************************************** ARR 2.15
644CODE ENDS
645 END
diff --git a/v4.0/src/BIOS/MSBIO2.ASM b/v4.0/src/BIOS/MSBIO2.ASM
new file mode 100644
index 0000000..50b25bc
--- /dev/null
+++ b/v4.0/src/BIOS/MSBIO2.ASM
@@ -0,0 +1,572 @@
1 PAGE ,132 ;
2 TITLE MSBIO2 - BIOS
3
4 %OUT ...MSBIO2.ASM
5
6;==============================================================================
7;REVISION HISTORY:
8;AN000 - New for DOS Version 4.00 - J.K.
9;AC000 - Changed for DOS Version 4.00 - J.K.
10;AN00x - PTM number for DOS Version 4.00 - J.K.
11;==============================================================================
12;AN001; - P1820 New Message SKL file 10/20/87 J.K.
13;AN002; - P5045 New INT 2fh for Get BDS table vector for EMS 06/06/88 J.K.
14;==============================================================================
15
16ROMSEGMENT EQU 0F000H
17MODELBYTE EQU DS:BYTE PTR [0FFFEH]
18MODELPCJR EQU 0FDH
19
20 itest=0
21
22 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
23 INCLUDE MSEQU.INC
24 INCLUDE DEVSYM.INC
25 INCLUDE PUSHPOP.INC
26 INCLUDE MSMACRO.INC
27
28 ASSUME DS:NOTHING,ES:NOTHING
29
30 EXTRN DSK$IN:NEAR
31 EXTRN SETPTRSAV:NEAR
32 EXTRN OUTCHR:NEAR
33 EXTRN SETDRIVE:NEAR
34 EXTRN FLUSH:NEAR
35 EXTRN HARDERR:NEAR
36 EXTRN HARDERR2:NEAR
37 EXTRN MAPERROR:NEAR
38 EXTRN GETBP:NEAR
39 EXTRN CHECKSINGLE:NEAR
40 EXTRN CHECK_TIME_OF_ACCESS:NEAR
41 EXTRN EXIT:NEAR
42 EXTRN HAS1:NEAR
43 EXTRN READ_SECTOR:NEAR
44 EXTRN INT_2F_13:FAR
45
46 EXTRN OLD13:DWORD
47
48;DATA
49 EXTRN PTRSAV:DWORD ;IBMBIO1
50 EXTRN START_BDS:WORD
51 EXTRN FDRIVE1:WORD
52 EXTRN FDRIVE2:WORD
53 EXTRN FDRIVE3:WORD
54 EXTRN FDRIVE4:WORD
55 EXTRN FLAGBITS:WORD
56 EXTRN TIM_DRV:BYTE
57 EXTRN MEDBYT:BYTE
58 EXTRN DRVMAX:BYTE
59 extrn Ext_Boot_Sig:byte ;AN000; ibmbdata
60 extrn SecPerClusInSector:byte ;AN000; ibmbdata
61 extrn Boot_Serial_L:word ;AN000; ibmbdata
62 extrn Boot_Serial_H:word ;AN000; ibmbdata
63
64 PATHSTART 005,DISK
65 EVENB
66 public Model_Byte
67MODEL_BYTE DB 0FFH ; MODEL BYTE. SET UP AT INIT TIME.
68 ; FF - PC1
69 ; FE - XT (64/256K PLANAR)
70 ; FD - PC-JR
71 ; FC - PC/AT
72 public Secondary_Model_Byte
73Secondary_Model_Byte db 0
74
75 PUBLIC ORIG19
76ORIG19 DD ?
77
78 PUBLIC INT19SEM
79INT19SEM DB 0 ; INDICATE THAT ALL INT 19
80 ; INITIALIZATION IS COMPLETE
81
82 IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77>
83 public Int19OLD&AA
84Int19OLD&AA dd -1 ;Orignal hardware int. vectors for INT 19h.
85 ENDM
86
87 EVENB
88 PUBLIC DSKDRVS
89DSKDRVS DW FDRIVE1
90 DW FDRIVE2
91 DW FDRIVE3
92 DW FDRIVE4
93 PUBLIC HDSKTAB
94HDSKTAB DW HDRIVE
95 DW DRIVEX
96;* Next area is reseved for mini disk BPB pointers *** J.K. 4/7/86
97;* Don't change this position. Should be addressible from DskDrvs *** J.K. 4/7/86
98MINI_DISK_BPB_PTRS DB 40 dup (?) ;J.K. 4/7/86 - memory reserved for Mini disk.
99
100 EVENB
101 PUBLIC INT_2F_NEXT
102INT_2F_NEXT DD ?
103
104RET_ADDR DD ?
105
106 PATHEND 005,DISK
107; = = = = = = = = = = = = = = = = = = = =
108
109; INT19
110;
111; WE "HOOK" THE INT 19 VECTOR, BECAUSE CONTRARY TO IBM DOCUMENTATION,
112; IT DOES NOT "BOOTSTRAP" THE MACHINE. IT LEAVES MEMORY ALMOST UNTOUCHED.
113; SINCE THE BIOS_INIT CODE ASSUMES THAT CERTAIN INTERRUPT VECTORS POINT TO
114; THE ROM_BIOS WE MUST "UNHOOK" THEM BEFORE ISSUING THE ACTUAL INT_19.
115; CURRENTLY THE ONLY VECTORS THAT NEED TO BE UNHOOKED ARE INT_19, INT_13,
116; AND THE HARDWARE INTERRUPTS.
117;
118 PUBLIC INT19
119INT19 PROC FAR
120 XOR AX,AX
121 MOV DS,AX
122 assume ds:nothing
123 assume es:nothing
124
125 LES DI,OLD13
126 MOV DS:[13H*4],DI
127 MOV DS:[13H*4+2],ES
128
129 CMP BYTE PTR INT19SEM, 0
130 JNZ INT19VECS
131 JMP DOINT19
132
133; ON THE PCJR, DON'T REPLACE ANY VECTORS
134; MODEL BYTE DEFINITIONS FROM IBMSTACK.ASM
135 MOV AX,ROMSEGMENT
136 MOV DS,AX
137 MOV AL,MODELPCJR
138
139 CMP AL,MODELBYTE
140 JNE INT19VECS
141 JMP DOINT19
142
143;Stacks code has changed these hardware interrupt vectors
144;STKINIT in SYSINIT1 will initialzie Int19hOLDxx values.
145INT19VECS:
146 XOR AX,AX
147 MOV DS,AX
148
149 IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77>
150
151 LES DI,Int19OLD&AA
152;SB33103******************************************************************
153
154 mov ax,es ;
155 cmp ax,-1 ;OPT 0ffffh is unlikely segment
156 je skip_int&AA ;OPT no need to check selector too
157 cmp di,-1 ;OPT 0ffffh is unlikely offset
158 je skip_int&AA
159
160;SB33103******************************************************************
161 MOV DS:[AA&H*4],DI
162 MOV DS:[AA&H*4+2],ES
163skip_int&AA:
164 ENDM
165
166DOINT19:
167 LES DI,ORIG19
168 MOV DS:[19H*4],DI
169 MOV DS:[19H*4+2],ES
170
171 INT 19H
172INT19 ENDP
173
174 ASSUME DS:CODE
175 PUBLIC DSK$INIT
176DSK$INIT PROC NEAR
177 PUSH CS
178 POP DS
179 MOV AH,BYTE PTR DRVMAX
180 MOV DI,OFFSET DSKDRVS
181 JMP SETPTRSAV
182DSK$INIT ENDP
183
184;
185; INT 2F HANDLER FOR EXTERNAL BLOCK DRIVERS TO COMMUNICATE WITH THE INTERNAL
186; BLOCK DRIVER IN IBMDISK. THE MULTIPLEX NUMBER CHOSEN IS 8. THE HANDLER
187; SETS UP THE POINTER TO THE REQUEST PACKET IN [PTRSAV] AND THEN JUMPS TO
188; DSK$IN, THE ENTRY POINT FOR ALL DISK REQUESTS.
189; ON EXIT FROM THIS DRIVER (AT EXIT), WE WILL RETURN TO THE EXTERNAL DRIVER
190; THAT ISSUED THIS INT 2F, AND CAN THEN REMOVE THE FLAGS FROM THE STACK.
191; THIS SCHEME ALLOWS US TO HAVE A SMALL EXTERNAL DEVICE DRIVER, AND MAKES
192; THE MAINTAINANCE OF THE VARIOUS DRIVERS (DRIVER AND IBMBIO) MUCH EASIER,
193; SINCE WE ONLY NEED TO MAKE CHANGES IN ONE PLACE (MOST OF THE TIME).
194;
195; 06/03/88 J.K. When AL=3, return DS:DI -> Start of BDS table.
196; (EMS device driver hooks INT 13h to handle 16KB DMA overrun
197; problem. BDS table is going to be used to get head/sector
198; informations without calling Generic IOCTL Get Device Parm call.)
199;
200; AL CONTAINS THE INT2F FUNCTION:
201; 0 - CHECK FOR INSTALLED HANDLER - RESERVED
202; 1 - INSTALL THE BDS INTO THE LINKED LIST
203; 2 - DOS REQUEST
204; 3 - Get BDS vector ;06/03/88 J.K.
205; Return BDS table starting pointer in DS:DI
206
207MYNUM EQU 8
208
209 PUBLIC INT2F_DISK
210INT2F_DISK PROC FAR
211 CMP AH,MYNUM
212 JE MINE
213 JMP CS:[INT_2F_NEXT] ; CHAIN TO NEXT INT 2F HANDLER
214MINE:
215 CMP AL,0F8H ; IRET ON RESERVED FUNCTIONS
216 JB DO_FUNC
217 IRET
218DO_FUNC:
219 OR AL,AL ; A GET INSTALLED STATE REQUEST?
220 JNE DISP_FUNC
221 MOV AL,0FFH
222 IRET
223DISP_FUNC:
224 MESSAGE FTESTINIT,<"INT2F_DISK",CR,LF>
225 CMP AL,1 ; REQUEST FOR INSTALLING BDS?
226 JNE DO_DOS_REQ
227 CALL INSTALL_BDS
228 IRET
229
230DO_DOS_REQ:
231; SET UP POINTER TO REQUEST PACKET
232 cmp al, 3 ;AN002; Get BDS vector?
233 je DO_Get_BDS_Vector ;AN002;
234 MOV WORD PTR CS:[PTRSAV],BX ;othrwise DOS function.
235 MOV WORD PTR CS:[PTRSAV+2],ES
236 JMP DSK$IN
237
238DO_Get_BDS_Vector: ;AN002; AL=3
239 push cs ;AN002;
240 pop ds ;AN002;
241 mov di, Start_BDS ;AN002;
242 IRET ;AN002;
243
244INT2F_DISK ENDP
245
246;
247; INSTALL_BDS INSTALLS A BDS A LOCATION DS:DI INTO THE CURRENT LINKED LIST OF
248; BDS MAINTAINED BY THIS DEVICE DRIVER. IT PLACES THE BDS AT THE END OF THE
249; LIST.
250 PUBLIC INSTALL_BDS
251INSTALL_BDS PROC NEAR
252 MESSAGE FTESTINIT,<"INSTALL BDS",CR,LF>
253; DS:DI POINT TO BDS TO BE INSTALLED
254 LES SI,DWORD PTR CS:[START_BDS] ; START AT BEGINNING OF LIST
255 PUSH ES ; SAVE POINTER TO CURRENT BDS
256 PUSH SI
257; ES:SI NOW POINT TO BDS IN LINKED LIST
258LOOP_NEXT_BDS:
259 CMP SI,-1 ; GOT TO END OF LINKED LIST?
260 JZ INSTALL_RET
261; IF WE HAVE SEVERAL LOGICAL DRIVES USING THE SAME PHYSICAL DRIVE, WE MUST
262; SET THE I_AM_MULT FLAG IN EACH OF THE APPROPRIATE BDSS.
263 MOV AL,BYTE PTR DS:[DI].DRIVENUM
264 CMP BYTE PTR ES:[SI].DRIVENUM,AL
265 JNZ NEXT_BDS
266 MESSAGE FTESTINIT,<"LOGICAL DRIVES",CR,LF>
267 XOR BX,BX
268 MOV BL,FI_AM_MULT
269 OR WORD PTR DS:[DI].FLAGS,BX ; SET FLAGS IN BOTH BDSS CONCERNED
270 OR WORD PTR ES:[SI].FLAGS,BX
271 MOV BL,FI_OWN_PHYSICAL
272 XOR BX,-1
273 AND WORD PTR DS:[DI].FLAGS,BX ; RESET THAT FLAG FOR 'NEW' BDS
274; WE MUST ALSO SET THE FCHANGELINE BIT CORRECTLY.
275 MOV BX,WORD PTR ES:[SI].FLAGS ; DETERMINE IF CHANGELINE AVAILABLE
276 AND BL,FCHANGELINE
277 XOR BH,BH
278 OR WORD PTR DS:[DI].FLAGS,BX
279
280NEXT_BDS:
281; BEFORE MOVING TO NEXT BDS, PRESERVE POINTER TO CURRENT ONE. THIS IS NEEDED AT
282; THE END WHEN THE NEW BDS IS LINKED INTO THE LIST.
283 POP BX ; DISCARD PREVIOUS POINTER TO BDS
284 POP BX
285 PUSH ES
286 PUSH SI
287 MOV BX,WORD PTR ES:[SI].LINK + 2
288 MOV SI,WORD PTR ES:[SI].LINK
289 MOV ES,BX
290 JMP SHORT LOOP_NEXT_BDS
291
292INSTALL_RET:
293 POP SI ; RETRIEVE POINTER TO LAST BDS
294 POP ES ; IN LINKED LIST.
295 MOV AX,DS
296 MOV WORD PTR ES:[SI].LINK+2,AX ; INSTALL BDS
297 MOV WORD PTR ES:[SI].LINK,DI
298 MOV WORD PTR DS:[DI].LINK,-1 ; SET NEXT POINTER TO NULL
299 RET
300INSTALL_BDS ENDP
301
302;
303; RE_INIT INSTALLS THE INT 2F VECTOR THAT WILL HANDLE COMMUNICATION BETWEEN
304; EXTERNAL BLOCK DRIVERS AND THE INTERNAL DRIVER. IT ALSO INSTALLS THE
305; RESET_INT_13 INTERFACE. IT IS CALLED BY SYSYINIT
306;
307 PUBLIC RE_INIT
308RE_INIT PROC FAR
309 MESSAGE FTESTINIT,<"REINIT",CR,LF>
310 PUSH AX
311 PUSH DS
312 PUSH DI
313 XOR DI,DI
314 MOV DS,DI
315 MOV DI,2FH*4 ; POINT IT TO INT 2F VECTOR
316 MOV AX,WORD PTR DS:[DI]
317 MOV WORD PTR CS:[INT_2F_NEXT],AX
318 MOV AX,WORD PTR DS:[DI+2] ; PRESERVE OLD INT 2F VECTOR
319 MOV WORD PTR CS:[INT_2F_NEXT+2],AX
320
321; INSTALL THE RESET_INT_13
322; INTERFACE
323
324;
325; THE FOLLOWING TWO LINES ARE NOT NEEDED ANYMORE BECAUSE THE LINK HAS BEEN
326; HARD-WIRED INTO THE CODE AT NEXT2F_13. - RAJEN.
327;------------------------------------------------------------------------------
328; MOV WORD PTR CS:[NEXT2F_13],OFFSET INT2F_DISK ; PRESERVE INT2F_DISK POINTER
329; MOV WORD PTR CS:[NEXT2F_13+2],CS
330;------------------------------------------------------------------------------
331
332 CLI
333 MOV WORD PTR DS:[DI],OFFSET INT_2F_13 ; INSTALL NEW VECTORS
334 MOV WORD PTR DS:[DI+2],CS
335 STI
336 POP DI
337 POP DS
338 POP AX
339
340 RET
341
342RE_INIT ENDP
343
344;-------------------------------------------------
345;
346; ASK TO SWAP THE DISK IN DRIVE A:
347;
348 PUBLIC SWPDSK
349SWPDSK PROC NEAR
350 MOV AL,BYTE PTR DS:[DI].DRIVELET ; GET THE DRIVE LETTER
351;USING A DIFFERENT DRIVE IN A ONE DRIVE SYSTEM SO REQUEST THE USER CHANGE DISKS
352 ADD AL,"A"
353 MOV CS:DRVLET,AL
354 PUSH DS ; PRESERVE SEGMENT REGISTER
355 PUSH CS
356 POP DS
357 MOV SI,OFFSET SNGMSG ; DS:SI -> MESSAGE
358 PUSH BX
359 CALL WRMSG ;PRINT DISK CHANGE MESSAGE
360 CALL FLUSH
361;SB33003***************************************************************
362 xor AH, AH ; set command to read character;SB
363 int 16h ; call rom-bios ;SB
364;SB33003***************************************************************
365 POP BX
366 POP DS ; RESTORE SEGMENT REGISTER
367WRMRET:
368 RET
369SWPDSK ENDP
370
371;----------------------------------------------
372;
373; WRITE OUT MESSAGE POINTED TO BY [SI]
374;
375 PUBLIC WRMSG
376WRMSG PROC NEAR
377 LODSB ;GET THE NEXT CHARACTER OF THE MESSAGE
378 OR AL,AL ;SEE IF END OF MESSAGE
379 JZ WRMRET
380; INT CHROUT
381 PUSHF
382 PUSH CS
383 CALL OUTCHR
384 JMP SHORT WRMSG
385WRMSG ENDP
386
387; INCLUDE BIOMES.INC
388 include MSBIO.CL2
389
390;
391; END OF SUPPORT FOR MULTIPLE FLOPPIES WITH NO LOGICAL DRIVES
392; THIS IS NOT 'SPECIAL' ANY MORE BECAUSE WE NOW HAVE THE CAPABILITY OF
393; DEFINING LOGICAL DRIVES IN CONFIG.SYS. WE THEREFORE KEEP THE CODE FOR
394; SWAPPING RESIDENT ALL THE TIME.
395;
396
397;J.K. 10/1/86 *******************************************************
398;Variables for Dynamic Relocatable modules
399;These should be stay resident.
400
401 public INT6C_RET_ADDR
402INT6C_RET_ADDR DD ? ; return address from INT 6C for P12 machine
403
404 PATHSTART 001,CLK
405;
406; DATA STRUCTURES FOR REAL-TIME DATE AND TIME
407;
408 public BIN_DATE_TIME
409 public MONTH_TABLE
410 public DAYCNT2
411 public FEB29
412BIN_DATE_TIME:
413 DB 0 ; CENTURY (19 OR 20) OR HOURS (0-23)
414 DB 0 ; YEAR IN CENTURY (0...99) OR MINUTES (0-59)
415 DB 0 ; MONTH IN YEAR (1...12) OR SECONDS (0-59)
416 DB 0 ; DAY IN MONTH (1...31)
417MONTH_TABLE: ;
418 DW 0 ;MJB002 JANUARY
419 DW 31 ;MJB002 FEBRUARY
420 DW 59 ;MJB002
421 DW 90 ;MJB002
422 DW 120 ;MJB002
423 DW 151 ;MJB002
424 DW 181 ;MJB002
425 DW 212 ;MJB002
426 DW 243 ;MJB002
427 DW 273 ;MJB002
428 DW 304 ;MJB002
429 DW 334 ;MJB002 DECEMBER
430DAYCNT2 DW 0000 ;MJB002 TEMP FOR COUNT OF DAYS SINCE 1-1-80
431FEB29 DB 0 ;MJB002 FEBRUARY 29 IN A LEAP YEAR FLAG
432 PATHEND 001,CLK
433
434;********************************************************************
435;
436
437 PUBLIC ENDFLOPPY
438ENDFLOPPY LABEL BYTE
439;
440; END OF CODE FOR VIRTUAL FLOPPY DRIVES
441;
442 PUBLIC ENDSWAP
443ENDSWAP LABEL BYTE
444
445 PATHSTART 004,BIO
446
447 PUBLIC HNUM
448HNUM DB 0 ;NUMBER OF HARDFILES
449 PUBLIC HARDDRV
450HARDDRV DB 80H ;PHYSICAL DRIVE NUMBER OF FIRST HARDFILE
451;**********************************************************************
452; "HDRIVE" IS A HARD DISK WITH 512 BYTE SECTORS
453;*********************************************************************
454 EVENB
455 PUBLIC BDSH
456BDSH DW -1 ;LINK TO NEXT STRUCTURE
457 DW CODE
458 DB 80 ;INT 13 DRIVE NUMBER
459 DB "C" ;LOGICAL DRIVE LETTER
460 PUBLIC HDRIVE
461HDRIVE:
462 DW 512
463 DB 1 ;SECTORS/ALLOCATION UNIT
464 DW 1 ;RESERVED SECTORS FOR DOS
465 DB 2 ;NO. OF ALLOCATION TABLES
466 DW 16 ;NUMBER OF DIRECTORY ENTRIES
467 DW 0000 ;NUMBER OF SECTORS (AT 512 BYTES EACH)
468 DB 11111000B ;MEDIA DESCRIPTOR
469 DW 1 ;NUMBER OF FAT SECTORS
470 DW 00 ;SECTOR LIMIT
471 DW 00 ;HEAD LIMIT
472 DW 00 ;HIDDEN SECTOR COUNT(low)
473 dw 00 ;AN000; Hidden Sector (high)
474 dw 00 ;AN000; Number of Sectors (low)
475 dw 00 ;AN000; Number of Sectors (high)
476 DB 0 ; TRUE => BIGFAT
477OPCNTH DW 0 ;OPEN REF. COUNT
478 DB 3 ;FORM FACTOR
479FLAGSH DW 0020H ;VARIOUS FLAGS
480; DB 9 DUP (0) ;RESERVED FOR FUTURE USE
481 DW 40 ; NUMBER OF CYLINDERS
482RECBPBH DB 31 DUP (?) ; RECOMMENDED BPB FOR DRIVE
483TRACKH DB -1 ;LAST TRACK ACCESSED ON THIS DRIVE
484TIM_LOH DW -1 ;KEEP THESE TWO CONTIGUOUS (?)
485TIM_HIH DW -1
486VOLIDH DB "NO NAME ",0 ;AN000; VOLUME ID FOR THIS DISK
487VolSerH dd 0 ;AN000; Current volume serial number from Boot record
488SysIDH db "FAT12 " ,0 ;AN000; Current file system id from Boot record
489
490;
491; END OF SINGLE HARD DISK SECTION
492;
493 PUBLIC ENDONEHARD
494ENDONEHARD LABEL BYTE
495;**********************************************************************
496; "DRIVEX " IS AN EXTRA TYPE OF DRIVE USUALLY RESERVED FOR AN
497; ADDITIONAL HARD FILE
498;*********************************************************************
499 EVENB
500 PUBLIC BDSX
501BDSX DW -1 ;LINK TO NEXT STRUCTURE
502 DW CODE
503 DB 81 ;INT 13 DRIVE NUMBER
504 DB "D" ;LOGICAL DRIVE LETTER
505 PUBLIC DRIVEX
506DRIVEX:
507 DW 512
508 DB 00 ;SECTORS/ALLOCATION UNIT
509 DW 1 ;RESERVED SECTORS FOR DOS
510 DB 2 ;NO. OF ALLOCATION TABLES
511 DW 0000 ;NUMBER OF DIRECTORY ENTRIES
512 DW 0000 ;NUMBER OF SECTORS (AT 512 BYTES EACH)
513 DB 11111000B ;MEDIA DESCRIPTOR
514 DW 0000 ;NUMBER OF FAT SECTORS
515 DW 00 ;SECTOR LIMIT
516 DW 00 ;HEAD LIMIT
517 DW 00 ;HIDDEN SECTOR COUNT (low)
518 dw 00 ;AN000; Hidden Sector (high)
519 dw 00 ;AN000; Number of Sectors (low)
520 dw 00 ;AN000; Number of Sectors (high)
521 DB 0 ; TRUE => BIGFAT
522OPCNTD DW 0 ;OPEN REF. COUNT
523 DB 3 ;FORM FACTOR
524FLAGSD DW 0020H ;VARIOUS FLAGS
525; DB 9 DUP (0) ;RESERVED FOR FUTURE USE
526 DW 40 ; NUMBER OF CYLINDERS
527RECBPBD DB 31 DUP (?) ; RECOMMENDED BPB FOR DRIVE
528TRACKD DB -1 ;LAST TRACK ACCESSED ON THIS DRIVE
529TIM_LOD DW -1 ;KEEP THESE TWO CONTIGUOUS (?)
530TIM_HID DW -1
531VOLIDD DB "NO NAME ",0 ;AN000; VOLUME ID FOR THIS DISK
532VolSerD dd 0 ;AN000; Current volume serial number from Boot record
533SysIDD db "FAT12 " ,0 ;AN000; Current file system id from Boot record
534
535;
536; END OF SECTION FOR TWO HARD DISKS
537 PUBLIC ENDTWOHARD
538ENDTWOHARD LABEL BYTE
539
540 PATHEND 004,BIO
541
542 PUBLIC TWOHARD
543TWOHARD LABEL BYTE
544 PAGE
545 INCLUDE MS96TPI.INC
546
547;*********************************************************************
548;Memory allocation for BDSM table. - J.K. 2/21/86
549;*********************************************************************
550 PUBLIC BDSMs
551BDSMs BDSM_type Max_mini_dsk_num dup (<>) ;currently max. 23
552
553;** End_of_BDSM defined in IBMINIT.ASM will be used to set the appropriate
554;** ending address of BDSM table.
555
556;
557;;3.3 BUG FIX -SP ------------------------------
558;;Migrated into 4.00 -MRW
559;Paragraph buffer between the BDSMs and MSHARD
560;
561;The relocation code for MSHARD needs this. this cannot be used for
562;anything. nothing can come before this or after this.....IMPORTANT!!!!
563;don't get too smart and using this buffer for anything!!!!!!
564;
565 db 16 dup(0)
566;
567;end of bug fix buffer
568;;
569;;3.3 BUG FIX -SP------------------------------
570
571CODE ENDS
572 END
diff --git a/v4.0/src/BIOS/MSCLOCK.ASM b/v4.0/src/BIOS/MSCLOCK.ASM
new file mode 100644
index 0000000..5d66d03
--- /dev/null
+++ b/v4.0/src/BIOS/MSCLOCK.ASM
@@ -0,0 +1,296 @@
1 TITLE MSCLOCK - DOS 3.3
2;----------------------------------------------------------------
3; :
4; CLOCK DEVICE DRIVER :
5; :
6; :
7; This file contains the Clock Device Driver. :
8; :
9; The routines in this files are: :
10; :
11; routine function :
12; ------- -------- :
13; TIM$WRIT Set the current time :
14; TIM$READ Read the current time :
15; Time_To_Ticks Convert time to corresponding :
16; number of clock ticks :
17; :
18; The clock ticks at the rate of: :
19; :
20; 1193180/65536 ticks/second (about 18.2 ticks per second):
21; See each routine for information on the use. :
22; :
23;----------------------------------------------------------------
24
25
26 itest=0
27 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
28 INCLUDE MSMACRO.INC
29
30 EXTRN EXIT:NEAR
31;
32; DAYCNT is the number of days since 1-1-80.
33; Each time the clock is read it is necessary to check if another day has
34; passed. The ROM only returns the day rollover once so if it is missed
35; the time will be off by a day.
36;
37 EXTRN DAYCNT:WORD ;MSDATA
38
39;;Rev 3.30 Modification ------------------------------------------------
40; variables for real time clock setting
41 public HaveCMOSClock
42HaveCMOSClock db 0 ;set by MSINIT.
43 public base_century
44base_century db 19
45 public base_year
46base_year db 80
47 public month_tab
48month_tab db 31,28,31,30,31,30,31,31,30,31,30,31
49
50; The following are indirect intra-segment call addresses. The
51;procedures are defined in MSINIT for relocation. MSINIT will set these
52;address when the relocation is done.
53 public BinToBCD
54BinToBCD dw 0 ;should point to Bin_To_BCD proc in MSINIT
55 public DaycntToDay
56DaycntToDay dw 0 ;should point to Daycnt_to_day in MSINIT
57
58;********************************************************************
59; Indirect call address of TIME_TO_TICKS procedure.
60;This will be used by the relocatable portable suspend/resume code.
61
62 public TimeToTicks
63TimeToTicks dw Time_To_Ticks
64
65;;End of Modification ------------------------------------------------
66
67;--------------------------------------------------------------------
68;
69; Settime sets the current time
70;
71; On entry ES:[DI] has the current time:
72;
73; number of days since 1-1-80 (WORD)
74; minutes (0-59) (BYTE)
75; hours (0-23) (BYTE)
76; hundredths of seconds (0-99) (BYTE)
77; seconds (0-59) (BYTE)
78;
79; Each number has been checked for the correct range.
80;
81 PUBLIC TIM$WRIT
82TIM$WRIT PROC NEAR
83 ASSUME DS:CODE
84 mov AX,WORD PTR ES:[DI]
85 push AX ;DAYCNT. We need to set this at the very
86 ; end to avoid tick windows.
87;;Rev 3.30 Modification
88 cmp HaveCMOSClock, 0
89 je No_CMOS_1
90 mov al,es:[di+3] ;get binary hours
91 call BinToBCD ;convert to BCD
92 mov ch,al ;CH = BCD hours
93 mov al,es:[di+2] ;get binary minutes
94 call BinToBCD ;convert to BCD
95 mov cl,al ;CL = BCD minutes
96 mov al,es:[di+5] ;get binary seconds
97 call BinToBCD ;convert to BCD
98 mov dh,al ;DH = BCD seconds
99 mov dl,0 ;DL = 0 (ST) or 1 (DST)
100 cli ;turn off timer
101 mov ah,03h ;set RTC time
102 int 1Ah ;call rom bios clock routine
103 sti
104
105;;End of Modification
106No_CMOS_1:
107 mov CX,WORD PTR ES:[DI+2]
108 mov DX,WORD PTR ES:[DI+4]
109;;Rev 3.30 Modification
110 call time_to_ticks ; convert time to ticks
111 ;CX:DX now has time in ticks
112 cli ; Turn off timer
113 mov AH, 1 ; command is set time in clock
114 int 1Ah ; call rom-bios clock routines
115 pop [DAYCNT]
116 sti
117;CMOS clock -------------------------------------
118 cmp HaveCMOSClock, 0
119 je No_CMOS_2
120 call DaycntToDay ; convert to BCD format
121 cli ; Turn off timer
122 mov AH,05h ; set RTC date
123 int 1Ah ; call rom-bios clock routines
124 sti
125;------------------------------------------------
126
127No_CMOS_2:
128 jmp EXIT
129TIM$WRIT ENDP
130;;End of Modification
131
132
133
134;
135; convert time to ticks
136; input : time in CX and DX
137; ticks returned in CX:DX
138;
139public time_to_ticks
140TIME_TO_TICKS PROC NEAR
141
142 ; first convert from Hour,min,sec,hund. to
143 ; total number of 100th of seconds
144 mov AL,60
145 mul CH ;Hours to minutes
146 mov CH,0
147 add AX,CX ;Total minutes
148 mov CX,6000 ;60*100
149 mov BX,DX ;Get out of the way of the multiply
150 mul CX ;Convert to 1/100 sec
151 mov CX,AX
152 mov AL,100
153 mul BH ;Convert seconds to 1/100 sec
154 add CX,AX ;Combine seconds with hours and min.
155 adc DX,0 ;Ripple carry
156 mov BH,0
157 add CX,BX ;Combine 1/100 sec
158 adc DX,0
159
160;;Rev 3.30 Modification
161;DX:CX IS TIME IN 1/100 SEC
162 XCHG AX,DX
163 XCHG AX,CX ;NOW TIME IS IN CX:AX
164 MOV BX,59659
165 MUL BX ;MULTIPLY LOW HALF
166 XCHG DX,CX
167 XCHG AX,DX ;CX->AX, AX->DX, DX->CX
168 MUL BX ;MULTIPLY HIGH HALF
169 ADD AX,CX ;COMBINE OVERLAPPING PRODUCTS
170 ADC DX,0
171 XCHG AX,DX ;AX:DX=TIME*59659
172 MOV BX,5
173 DIV BL ;DIVIDE HIGH HALF BY 5
174 MOV CL,AL
175 MOV CH,0
176 MOV AL,AH ;REMAINDER OF DIVIDE-BY-5
177 CBW
178 XCHG AX,DX ;USE IT TO EXTEND LOW HALF
179 DIV BX ;DIVDE LOW HALF BY 5
180 MOV DX,AX
181 ; CX:DX is now number of ticks in time
182 ret
183TIME_TO_TICKS ENDP
184;;End of Modification
185
186
187;
188; Gettime reads date and time
189; and returns the following information:
190;
191; ES:[DI] =count of days since 1-1-80
192; ES:[DI+2]=hours
193; ES:[DI+3]=minutes
194; ES:[DI+4]=seconds
195; ES:[DI+5]=hundredths of seconds
196;
197 PUBLIC TIM$READ
198TIM$READ PROC NEAR
199 ; read the clock
200 xor AH, AH ; set command to read clock
201 int 1Ah ; call rom-bios to get time
202
203 or al,al ; check for a new day
204 jz noroll1 ; if al=0 then don't reset day count
205 INC [DAYCNT] ; CATCH ROLLOVE
206noroll1:
207 MOV SI,[DAYCNT]
208
209;
210; we now need to convert the time in tick to the time in 100th of
211; seconds. The relation between tick and seconds is:
212;
213; 65536 seconds
214; ----------------
215; 1,193,180 tick
216;
217; To get to 100th of second we need to multiply by 100. The equation is:
218;
219; Ticks from clock * 65536 * 100
220; --------------------------------- = time in 100th of seconds
221; 1,193,180
222;
223; Fortunately this fromula simplifies to:
224;
225; Ticks from clock * 5 * 65,536
226; --------------------------------- = time in 100th of seconds
227; 59,659
228;
229; The calculation is done by first multipling tick by 5. Next we divide by
230; 59,659. In this division we multiply by 65,536 by shifting the dividend
231; my 16 bits to the left.
232;
233; start with ticks in CX:DX
234; multiply by 5
235 MOV AX,CX
236 MOV BX,DX
237 SHL DX,1
238 RCL CX,1 ;TIMES 2
239 SHL DX,1
240 RCL CX,1 ;TIMES 4
241 ADD DX,BX
242 ADC AX,CX ;TIMES 5
243 XCHG AX,DX
244
245
246; now have ticks * 5 in DX:AX
247; we now need to multiply by 65,536 and divide by 59659 d.
248
249 mov CX,59659 ; get divisor
250 div CX
251 ; DX now has remainder
252 ; AX has high word of final quotient
253 mov BX,AX ; put high work if safe place
254 xor AX,AX ; this is the multiply by 65536
255 div CX ; BX:AX now has time in 100th of seconds
256
257;
258;Rounding based on the remainder may be added here
259;The result in BX:AX is time in 1/100 second.
260 mov DX,BX
261 mov CX,200 ;Extract 1/100's
262;Division by 200 is necessary to ensure no overflow--max result
263;is number of seconds in a day/2 = 43200.
264 div CX
265 cmp DL,100 ;Remainder over 100?
266 jb NOADJ
267 sub DL,100 ;Keep 1/100's less than 100
268NOADJ:
269 cmc ;If we subtracted 100, carry is now set
270 mov BL,DL ;Save 1/100's
271;To compensate for dividing by 200 instead of 100, we now multiply
272;by two, shifting a one in if the remainder had exceeded 100.
273 rcl AX,1
274 mov DL,0
275 rcl DX,1
276 mov CX,60 ;Divide out seconds
277 div CX
278 mov BH,DL ;Save the seconds
279 div CL ;Break into hours and minutes
280 xchg AL,AH
281
282;Time is now in AX:BX (hours, minutes, seconds, 1/100 sec)
283
284 push AX
285 MOV AX,SI ; DAYCNT
286 stosw
287 pop AX
288 stosw
289 mov AX,BX
290 stosw
291 jmp EXIT
292
293TIM$READ ENDP
294CODE ENDS
295 END
296 \ No newline at end of file
diff --git a/v4.0/src/BIOS/MSCON.ASM b/v4.0/src/BIOS/MSCON.ASM
new file mode 100644
index 0000000..68fcfff
--- /dev/null
+++ b/v4.0/src/BIOS/MSCON.ASM
@@ -0,0 +1,328 @@
1 PAGE ,132 ;
2 TITLE MSCON - BIOS
3 %OUT ...MSCON.ASM
4;==============================================================================
5;REVISION HISTORY:
6;AN000 - New for DOS Version 4.00 - J.K.
7;AC000 - Changed for DOS Version 4.00 - J.K.
8;AN00x - PTM number for DOS Version 4.00 - J.K.
9;==============================================================================
10
11 itest=0
12 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
13 INCLUDE JUMPMAC.INC
14 INCLUDE MSEQU.INC
15 INCLUDE MSMACRO.INC
16
17;*** DOS 3.3 will not support more than 25 rows
18; INCLUDE DEVSYM.INC ;J.K. 4/29/86 for CON$GENIOCTL support
19; INCLUDE IOCTL.INC ;J.K. 4/29/86 for CON$GENIOCTL support
20
21 EXTRN EXIT:NEAR ;MSBIO1
22 EXTRN BUS$EXIT:NEAR ;MSBIO1
23
24; EXTRN CMDERR:NEAR ;MSBIO1 J.K. 4/29/86
25
26;DATA
27 EXTRN PTRSAV:DWORD ;MSBIO1
28 EXTRN FHAVEK09:BYTE ;MSDISK
29 EXTRN ALTAH:BYTE ;MSBDATA
30 EXTRN KEYRD_Func:Byte ;MSBDATA
31 EXTRN KEYSTS_Func:Byte ;MSBDATA
32
33; EXTRN SAV_SC_INFO:BYTE ;MSBDATA J.K. 4/29/86
34; EXTRN SAV_SC_MODE:BYTE ;MSBDATA J.K. 4/29/86
35;------------------------------------------------------
36;
37; CONSOLE READ ROUTINE
38;
39 ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY POINT
40 PUBLIC CON$READ
41CON$READ PROC NEAR
42 JCXZ CON$EXIT
43CON$LOOP:
44 CALL CHRIN ;GET CHAR IN AL
45 STOSB ;STORE CHAR AT ES:DI
46 LOOP CON$LOOP
47CON$EXIT:
48 JUMP EXIT
49CON$READ ENDP
50;---------------------------------------------------------
51;
52; INPUT SINGLE CHAR INTO AL
53;
54;J.K.5/12/87 We are going to issue extended keyboard function, if supported.
55;The returning value of the extended key stroke of the extended key board
56;function uses 0E0h in AL instead of 00 as in the conventional key board
57;function. This creates a conflict when the user entered real Greek Alpha
58;charater (= 0E0h) to distinguish the extended key stroke and the Greek Alpha.
59;This case will be handled in the following manner;
60; AH = 16h
61; INT 16h
62; If AL == 0, then extended code (in AH)
63; else If AL == 0E0h, then
64; IF AH <> 0, then extended code (in AH)
65; else Greek_Alpha character.
66;Also, for compatibility reason, if an extended code is detected, then we
67;are going to change the value in AL from 0E0h to 00h.
68
69
70CHRIN PROC NEAR
71;AN000;
72; XOR AX,AX
73 mov ah,KEYRD_Func ;AN000; Set by MSINIT. 0 or 10h
74 xor al,al ;AN000;
75 XCHG AL,ALTAH ;GET CHARACTER & ZERO ALTAH
76
77 OR AL,AL
78 JNZ KEYRET
79;SB34CON000**************************************************************
80;SB Keyboard I/O interrupt
81;SB AH already contains the keyboard read function number
82;SB 1 LOC
83
84 int 16h
85;SB34CON000**************************************************************
86ALT10:
87 OR AX,AX ;CHECK FOR NON-KEY AFTER BREAK
88 JZ CHRIN
89 CMP AX,7200H ;CHECK FOR CTRL-PRTSC
90 JNZ ALT_Ext_Chk ;AN000;
91 MOV AL,16
92 jmp KeyRet ;AN000;
93ALT_Ext_Chk:
94;SB34CON001**************************************************************
95;SB IF operation was extended function (i.e. KEYRD_Func != 0) THEN
96;SB IF character read was 0E0h THEN
97;SB IF extended byte was zero (i.e. AH == 0) THEN
98;SB goto keyret
99;SB ELSE
100;SB set AL to zero
101;SB goto ALT_SAVE
102;SB ENDIF
103;SB ENDIF
104;SB ENDIF
105;SB 9 LOCS
106
107 cmp BYTE PTR KEYRD_Func,0
108 jz NOT_EXT
109 cmp al,0E0h
110 jnz NOT_EXT
111 or ah,ah
112 jz KEYRET
113 xor al,al
114 jmp short ALT_SAVE
115NOT_EXT:
116
117;SB34CON001**************************************************************
118 OR AL,AL ;SPECIAL CASE?
119 JNZ KEYRET
120ALT_SAVE:
121 MOV ALTAH,AH ;STORE SPECIAL KEY
122KEYRET:
123 RET
124CHRIN ENDP
125
126;--------------------------------------------------------------
127;
128; KEYBOARD NON DESTRUCTIVE READ, NO WAIT
129;
130; PC-CONVERTIBLE-TYPE MACHINE: IF BIT 10 IS SET BY THE DOS IN THE STATUS WORD
131; OF THE REQUEST PACKET, AND THERE IS NO CHARACTER IN THE INPUT BUFFER, THE
132; DRIVER ISSUES A SYSTEM WAIT REQUEST TO THE ROM. ON RETURN FROM THE ROM, IT
133; RETURNS A 'CHAR-NOT-FOUND' TO THE DOS.
134;
135CONBUSJ:
136 ASSUME DS:NOTHING
137 JMP CONBUS
138
139 ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY POINT
140 PUBLIC CON$RDND
141CON$RDND:
142 MOV AL,[ALTAH]
143 OR AL,AL
144 JZ RD1
145 JMP RDEXIT
146
147RD1:
148;SB34CON002**************************************************************
149;SB Keyboard I/O interrupt
150;SB Get keystroke status (KEYSTS_Func)
151;SB 2 LOCS
152
153 mov ah,KEYSTS_Func
154 int 16h
155;SB34CON002**************************************************************
156 JZ NOCHR
157 JMP GOTCHR
158NOCHR:
159 CMP FHAVEK09,0
160 JZ CONBUSJ
161 LDS BX,[PTRSAV]
162 ASSUME DS:NOTHING
163 TEST [BX].STATUS,0400H ; SYSTEM WAIT ENABLED?
164 JZ CONBUSJ
165
166;********************************
167; NEED TO WAIT FOR IBM RESPONSE TO REQUEST FOR CODE ON HOW TO USE THE SYSTEM
168; WAIT CALL.
169;********************************
170 MESSAGE FTESTCON,<"SYSTEM WAIT STAGE",CR,LF>
171 MOV AX,4100H ; WAIT ON AN EXTERNAL EVENT
172; MOV BX,0300H ; NO TIMEOUT
173; MOV DX,60H ; LOOK AT I/O PORT 60H
174 INT 15H ; CALL ROM FOR SYSTEM WAIT
175 MESSAGE FTESTCON,<"OUT OF WAIT. AX IS ">
176 MNUM FTESTCON,AX
177 MESSAGE FTESTCON,<CR,LF>
178 JMP CONBUS
179
180 ASSUME DS:CODE
181GOTCHR:
182 OR AX,AX
183 JNZ NOTBRK ;CHECK FOR NULL AFTER BREAK
184;SB34CON004**************************************************************
185;SB Keyboard I/O interrupt
186;SB Keyboard read function (KEYRD_Func)
187;SB 2 LOCS
188
189 mov ah,KEYRD_Func
190 int 16h
191;SB34CON004**************************************************************
192 JUMP CON$RDND ;AND GET A REAL STATUS
193NOTBRK:
194 CMP AX,7200H ;CHECK FOR CTRL-PRTSC
195 JNZ RD_Ext_Chk ;AN000;
196 MOV AL,16
197 jmp RDEXIT ;AN000;
198RD_Ext_Chk: ;AN000;
199 cmp KEYRD_Func, 0 ;AN000; Extended Keyboard function?
200 jz RDEXIT ;AN000; No. Normal exit.
201 cmp al,0E0h ;AN000; Extended key value or Greek Alpha?
202 jne RDEXIT ;AN000;
203 cmp ah, 0 ;AN000; Scan code exist?
204 jz RDEXIT ;AN000; Yes. Greek Alpha char.
205 mov al, 0 ;AN000; No. Extended key stroke. Change it for compatibility
206 PUBLIC RDEXIT
207RDEXIT:
208 LDS BX,[PTRSAV]
209 ASSUME DS:NOTHING
210 MOV [BX].MEDIA,AL
211EXVEC:
212 JUMP EXIT
213
214CONBUS:
215 ASSUME DS:NOTHING
216 JUMP BUS$EXIT
217;--------------------------------------------------------------
218;
219; KEYBOARD FLUSH ROUTINE
220;
221 ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY POINT
222 PUBLIC CON$FLSH
223CON$FLSH:
224 CALL FLUSH
225 JUMP EXIT
226
227 PUBLIC FLUSH
228FLUSH:
229 MOV [ALTAH],0 ;CLEAR OUT HOLDING BUFFER
230
231FLLOOP:
232;SB33012****************************************************************
233 ;SB ; Is there a char there?
234 mov AH, 1 ;SB ; command code for check status
235 int 16h ;SB ; call rom-bios keyboard routine
236;SB33012****************************************************************
237 JZ FLDONE
238;SB33013****************************************************************
239 xor AH, AH ;SB ; if zf is nof set, get character
240 int 16h ;SB ; call rom-bios to get character
241;SB33013****************************************************************
242 JMP FLLOOP
243FLDONE:
244
245 RET
246;----------------------------------------------------------
247;
248; CONSOLE WRITE ROUTINE
249;
250 ASSUME DS:CODE ; THIS WAS SET BY THE CON DD ENTRY POINT
251 PUBLIC CON$WRIT
252CON$WRIT:
253 JCXZ EXVEC
254CON$LP:
255 MOV AL,ES:[DI] ;GET CHAR
256 INC DI
257 INT CHROUT ;OUTPUT CHAR
258 LOOP CON$LP ;REPEAT UNTIL ALL THROUGH
259 JUMP EXIT
260;-----------------------------------------------
261;
262; BREAK KEY HANDLING
263;
264 PUBLIC CBREAK
265CBREAK:
266 MOV CS:ALTAH,3 ;INDICATE BREAK KEY SET
267
268 PUBLIC INTRET
269INTRET:
270 IRET
271
272;------------------------------------------------------------------------------
273;J.K. 4/29/86 - CONSOLE GENERIC IOCTL SUPPORT FOR DOS 3.3.
274;CON$GENIOCTL supports Get mode information, Set mode information functions.
275;It will only save the value from "Set mode information" and will return
276;the value through "Get mode information". It is supposed to be set by
277;the MODE.COM and other application program can retrieve information
278;through "Get mode information" call.
279;Initially, there is no valuable informaton until set by MODE command, so
280;any attemp to "Get mode information" at that points will fail. (unknown
281;command with carry set.)
282;At entry: CS = DS = code
283; CS:[PTRSAV] has seg, address of the Request Header saved in
284; in Strategy routine.
285;
286; PUBLIC CON$GENIOCTL
287; ASSUME DS:CODE
288;CON$GENIOCTL:
289; les di, CS:[PTRSAV] ;get the request header
290; cmp es:[di].MajorFunction, IOC_SC
291; je Major_SC_OK
292;SC_CMDERR:
293; stc
294; jmp cmderr ;carry is set, exit to cmderr
295;Major_SC_OK:
296; mov al, es:[di].MinorFunction ;save minor function
297; les di, es:[di].GenericIOCTL_Packet ;pointer of SC_MODE_INFO structure
298; mov cx, es:[di].SC_INFO_LENGTH ;save length
299; inc di
300; inc di ;ES:DI -> SC_MODE in Info. Packet
301; cmp cx, SC_INFO_PACKET_LENGTH ;currently 9.
302; jne SC_CMDERR ;cannot accept the different packet
303; cmp al, GET_SC_MODE ;minor function = 60h ?
304; jne SC_SET_MODE_FUNC ;no, check if it is "Set mode function"
305; cmp SAV_SC_MODE, 0 ;information set before?
306; je SC_CMDERR ;no, cannot get the info.
307;;SC_GET_MODE_FUNC: ;es:di -> SC_MODE in info. packet
308; ;cx - length
309; mov si, offset SAV_SC_INFO
310; rep movsb ;ds:si -> sav_sc_info, es:di -> sc_mode
311; jmp exit
312;
313;SC_SET_MODE_FUNC: ;es:di -> SC_MODE
314; cmp al, SET_SC_MODE ;minor function = 40h ?
315; jne SC_CMDERR
316; mov si, offset SAV_SC_INFO
317; xchg di, si
318; push es
319; push ds
320; pop es
321; pop ds
322; rep movsb ;ds:si -> sc_mode, es:di -> sav_sc_info
323; jmp exit
324;
325;J.K. 4/29/86 - End of CONSOLE GENERIC IOCTL SUPPORT FOR DOS 3.3.
326
327CODE ENDS
328 END
diff --git a/v4.0/src/BIOS/MSDISK.ASM b/v4.0/src/BIOS/MSDISK.ASM
new file mode 100644
index 0000000..f132e7f
--- /dev/null
+++ b/v4.0/src/BIOS/MSDISK.ASM
@@ -0,0 +1,2443 @@
1 PAGE ,132 ;
2 TITLE MSDISK - BIOS
3 %OUT ...MSDISK.ASM
4
5;==============================================================================
6;REVISION HISTORY:
7;AN000 - New for DOS Version 4.00 - J.K.
8;AC000 - Changed for DOS Version 4.00 - J.K.
9;AN00x - PTM number for DOS Version 4.00 - J.K.
10;==============================================================================
11;AN001; d24 Multi Track enable/disable command in CONFIG.SYS 6/27/87 J.K.
12;AN002; d9 Double word MOV instruction 7/1/87 J.K.
13;AN003: d25 Change DASD ERP to that recommended by Storage systems 7/28/87 J.K.
14;AN004; D113 Disable I/O access to unformatted media 9/03/87 J.K.
15;AN005; P985 Allow I/O access to unformatted media 9/14/87 J.K.
16;AN006; P1535 Disallow I/O access to unformatted media. 10/15/87 J.K.
17; (Give the user to control this - Generic IOCTL subfunction 64h/44h
18;AN007; p2828 Do not retry for multi-track format request 12/08/87 J.K.
19;AC008; p3197 Should reset change line after BPB set in BDS table 01/21/88 J.K.
20;AN009; p3349 Should retry at hard file timeout error 02/03/88 J.K.
21;AN010; p4696 ECC error handler should cover PC ATs for CMC disks 05/04/88 J.K.
22;AN011; p5034 Possible virgin hard file problem with direct INT 13 06/03/88 J.K.
23;AN012; P5049 Attempt to write at DISK BASE table in ROM BIOS 06/06/88 J.K.
24;AN013; P5055 Diskcopy fails (Regression of P5049) 06/09/88 J.K.
25;==============================================================================
26
27;for testing, set itest to 1. So as MSBIO1.ASM.
28 itest=0
29 EXTRN NUMERR:ABS ;MSDATA
30
31 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
32 INCLUDE MSEQU.INC
33 INCLUDE PUSHPOP.INC
34 INCLUDE MSMACRO.INC
35 INCLUDE DEVSYM.INC
36 INCLUDE MSDSKPR.INC
37 include biostruc.inc
38
39 EXTRN INT2F_DISK:FAR ;MSBIO2
40 EXTRN MEDIACHECK:NEAR ;96TPI
41 EXTRN HASCHANGE:NEAR ;96TPI
42 EXTRN MEDIA_SET_VID:NEAR ;96TPI
43 EXTRN HIDENSITY:NEAR ;96TPI
44 EXTRN CHECKLATCHIO:NEAR ;96TPI
45 EXTRN CHECKIO:NEAR ;96TPI
46 EXTRN SET_CHANGED_DL:NEAR ;96TPI
47 EXTRN SET_VOLUME_ID:NEAR ;MSVOLID
48 EXTRN SWPDSK:NEAR ;MSBIO2
49 EXTRN CMDERR:NEAR ;MSBIO1
50 EXTRN STRATEGY:NEAR ;MSBIO1
51 EXTRN ERR$CNT:NEAR ;MSBIO1
52 EXTRN DSK$IN:NEAR ;MSBIO1
53 EXTRN EXIT:NEAR ;MSBIO1
54 EXTRN BUS$EXIT:NEAR ;MSBIO1
55 EXTRN ERR$EXIT:NEAR ;MSBIO1
56 extrn ResetChanged:near ;AN000; MS96TPI
57
58;DATA
59 EXTRN OLD13:DWORD ;MSBIO2
60 EXTRN PTRSAV:DWORD ;MSBIO1
61 EXTRN COM1DEV:WORD ;MSAUX
62 EXTRN DAYCNT:WORD ;MSCLOCK
63 EXTRN TIM_DRV:BYTE ;MSDATA
64 EXTRN ACCESSCOUNT:BYTE ;MSDATA
65 EXTRN SM92:BYTE ;MSDATA
66 EXTRN DISKSECTOR:BYTE ;MSDATA
67 EXTRN MEDIABYTE:BYTE ;MSDATA
68 EXTRN SECPERCLUSINSECTOR:BYTE ;MSDATA
69 EXTRN BPB_IN_SECTOR:WORD ;MSDATA
70 EXTRN DISKSECTOR:BYTE ;MSDATA
71 EXTRN STEP_DRV:BYTE ;MSDATA
72 EXTRN START_BDS:WORD ;MSDATA
73 EXTRN PHYS_DRV:BYTE ;MSDATA
74 EXTRN WRTVERIFY:WORD ;MSDATA
75 EXTRN FSETOWNER:BYTE ;MSDATA
76 EXTRN SINGLE:BYTE ;MSDATA
77 EXTRN RFLAG:BYTE ;MSDATA
78 EXTRN MEDBYT:BYTE ;MSDATA
79 EXTRN SPSAV:WORD ;MSDATA
80 EXTRN SECCNT:WORD ;MSDATA
81 EXTRN DPT:DWORD ;MSDATA
82 EXTRN CURSEC:BYTE,CURHD:BYTE ;MSDATA
83 EXTRN CURTRK:WORD ;MSDATA
84 EXTRN EOT:BYTE ;MSDATA
85 EXTRN MOTORSTARTUP:BYTE,SETTLECURRENT:BYTE,SETTLESLOW:BYTE ;MSDATA
86 EXTRN CURHD:BYTE ;MSDATA
87 EXTRN LSTERR:BYTE ;MSDATA
88 EXTRN ERRIN:BYTE,ERROUT:BYTE ;MSDATA
89 EXTRN PREVOPER:WORD ;MSDATA
90 EXTRN ORIG13:DWORD ;MSDATA
91 EXTRN FLAGBITS:WORD ;MSDATA
92 EXTRN NUMBER_OF_SEC:BYTE ;MSDATA
93 EXTRN FHAVE96:BYTE ;MSDATA
94 EXTRN NEW_ROM:BYTE ;MSDATA
95 EXTRN FORMT_EOT:BYTE,HDNUM:BYTE,TRKNUM:WORD,GAP_PATCH:BYTE ;MSDATA
96 EXTRN NEXT2F_13:WORD ;MSDATA
97 extrn Save_head_sttl:byte ;msbdata
98 extrn Secrete_Code:word ;msbdata J.K. 11/7/86 Secrete code for DOS 3.3 MSBIO
99 extrn Ext_Boot_Sig:byte ;AN000; msbdata
100 extrn Boot_Serial_L:word ;AN000; msbdata
101 extrn Boot_Serial_H:word ;AN000; msbdata
102 extrn Boot_Volume_Label:byte ;AN000; msbdata
103 extrn Boot_System_ID:byte ;AN000; msbdata
104 extrn Model_Byte:Byte ;MSBIO2
105 extrn Secondary_Model_Byte:Byte ;MSBIO2
106
107;-----------------------------------------------------------------
108;
109; DISK INTERFACE ROUTINES
110;
111; DEVICE ATTRIBUTE BITS:
112; BIT 6 - GET/SET MAP FOR LOGICAL DRIVES AND GENERIC IOCTL.
113;
114
115MAXERR = 5
116LSTDRV = 504H
117
118; SOME FLOPPIES DO NOT HAVE CHANGELINE. AS A RESULT, MEDIA-CHECK WOULD
119; NORMALLY RETURN I-DON'T-KNOW, THE DOS WOULD CONTINUALLY REREAD THE FAT, AND
120; DISCARD CACHED DATA. WE OPTIMIZE THIS BY IMPLEMENTING A LOGICAL DOOR-
121; LATCH: IT IS PHYSICALLY IMPOSSIBLE TO CHANGE A DISK IN UNDER 2 SECONDS. WE
122; RETAIN THE TIME OF THE LAST SUCCESSFUL DISK OPERATION AND COMPARE IT WITH
123; THE CURRENT TIME DURING MEDIA-CHECK. IF < 2 SECONDS AND AT LEAST 1 TIMER
124; TICK HAS PASSED, THE WE SAY NO CHANGE. IF > 2 SECONDS THEN WE SAY I-
125; DON'T-KNOW. FINALLY, SINCE WE CANNOT TRUST THE TIMER TO BE ALWAYS
126; AVAILABLE, WE RECORD THE NUMBER OF MEDIA CHECKS THAT HAVE OCCURRED WHEN NO
127; APPARENT TIME HAS ELAPSED. WHILE THIS NUMBER IS < A GIVEN THRESHOLD, WE SAY
128; NO CHANGE. WHEN IT EXCEEDS THAT THRESHOLD, WE SAY I-DON'T-KNOW AND RESET
129; THE COUNTER TO 0. WHEN WE STORE THE TIME OF LAST SUCCESSFUL ACCESS, IF WE
130; SEE THAT TIME HAS PASSED TOO, WE RESET THE COUNTER.
131;
132ACCESSMAX = 5
133;
134; DUE TO VARIOUS BOGOSITIES, WE NEED TO CONTINUALLY ADJUST WHAT THE HEAD
135; SETTLE TIME IS. THE FOLLOWING ALGORITHM IS USED:
136;
137; GET THE CURRENT HEAD SETTLE VALUE.
138; IF IT IS 0, THEN
139; SET SLOW = 15
140; ELSE
141; SET SLOW = VALUE
142; ...
143;*********************************************
144;************ OLD ALGORITHM ******************
145;* IF WE ARE SEEKING AND WRITING THEN
146;* USE SLOW
147;* ELSE
148;* USE FAST
149;*********************************************
150;*********** IBM'S REQUESTED LOGIC ***********
151; IF WE ARE SEEKING AND WRITING AND NOT ON AN AT THEN
152; USE SLOW
153; ELSE
154; USE FAST
155; ...
156; RESTORE CURRENT HEAD SETTLE VALUE
157;
158
159Set_ID_Flag db 0 ;AN000; If 1, GETBP routine will set the
160 ;Vol_Serial and FileSys_ID in BDS table
161 ;from the media Boot record, if it is > DOS 4.00
162 ;formatted one. Then Set_ID_flag will be set to 2
163 ;to signal that volume_label is set from the extended
164 ;boot record and do not set it from the root
165 ;directory as done in SET_VOLUME_ID routine.
166 ;For the old version, Vol_Serial
167 ;will be set to -1, and FileSys_ID will be set
168 ;to "FAT12 " if it is a floppy.
169
170 public Fat_12_ID
171Fat_12_ID DB "FAT12 ",0 ;AN000; Default System ID for floppy.
172 public Fat_16_ID
173Fat_16_ID DB "FAT16 ",0 ;AN000;
174 public Vol_No_Name
175Vol_No_Name db "NO NAME ",0 ;AN000;
176 public Temp_H
177Temp_H dw 0 ;AN000; Temporary for 32 bit calculation.
178
179 public Start_Sec_H
180Start_Sec_H dw 0 ;AN000; Starting sector number high word.
181 ;Used as an input to DISKIO subroutine.
182Saved_Word dw 0 ;AN000; Tempory saving place for a word.
183
184;---------------------------------------
185;J.K. 6/29/87 For Multi-track
186MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns
187 ; it on after handling CONFIG.SYS file as a
188 ; default value, if MulTrk_flag = MULTRK_OFF1.
189MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered.
190MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off.
191 public MulTrk_Flag
192MulTrk_Flag dw 0 ;AN001;
193;J.K. 6/29/87 End of Multi-track definition.
194;---------------------------------------------------------------------
195 public EC35_Flag
196EC35_Flag db 0 ; flags for electrically compatible 3.5 inch disk drives (mrw 4/88)
197;---------------------------------------------------------------------
198VRetry_Cnt dw 0 ;AN003;
199Soft_ECC_Cnt dw 0 ;AN003;
200;---------------------------------------------------------------------
201MultiTrk_Format_Flag db 0 ;AN007;Testing. If 1, then Multi track format request
202;---------------------------------------------------------------------
203;
204; IF ID IS F9, HAVE A 96TPI DISK ELSE
205; IF BIT 2 IS 0 THEN MEDIA IS NOT REMOVABLE AND COULD NOT HAVE CHANGED
206; OTHERWISE IF WITHIN 2 SECS OF LAST DISK OPERATION MEDIA COULD NOT
207; HAVE CHANGED, OTHERWISE DONT KNOW IF MEDIA HAS CHANGED
208;
209 PUBLIC MEDIA$CHK
210MEDIA$CHK PROC NEAR
211 MESSAGE FTESTDISK,<"DISK MEDIA CHECK ">
212 MNUM FTESTDISK,AX
213 MESSAGE FTESTDISK,<CR,LF>
214 CALL SETDRIVE
215
216 cmp cs:Secrete_Code, 'jk' ;J.K.11/7/86 Secrete code for DOS 3.3 IBMBIO.
217 jne media$done ;J.K.11/7/86
218
219; FOR NON-REMOVABLE DISKS ONLY RETURN CHANGED IF CHANGED BY FORMAT, OTHERWISE
220; RETURN 'NOT CHANGED'.
221 MOV SI,1 ; ASSUME NO CHANGE
222 TEST WORD PTR [DI].FLAGS,FCHANGED_BY_FORMAT
223 JZ WEARENOTFAKINGIT
224 AND WORD PTR [DI].FLAGS,NOT FCHANGED_BY_FORMAT ; RESET FLAG
225; IF MEDIA HAS BEEN CHANGED BY FORMAT, WE MUST ASK THE ROM. CANNOT RELY ON THE
226; 2 SECOND TIME CHECK.
227 MOV CS:[TIM_DRV],-1 ; ENSURE THAT WE ASK THE ROM IF MEDIA
228 ; HAS CHANGED
229 TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE
230 JZ WEHAVEAFLOPPY
231 MOV SI,-1 ; INDICATE MEDIA CHANGED
232 JMP SHORT MEDIA$DONE
233;
234; WE NEED TO RETURN 'NOT CHANGED' IF WE HAVE A HARD FILE.
235;
236WEARENOTFAKINGIT:
237 TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE
238 JNZ MEDIA$DONE
239WEHAVEAFLOPPY:
240 XOR SI,SI ; PRESUME "I DON'T KNOW"
241;
242; IF WE HAVE A FLOPPY WITH CHANGELINE SUPPORT, WE ASK THE ROM TO DETERMINE IF
243; MEDIA HAS CHANGED. WE DO NOT PERFORM THE 2 SECOND CHECK FOR THESE DRIVES.
244;----------------------------------------|
245; WARNING: DO NOT CHANGE THE FOLLOWING. ;|
246; IT GETS PATCHED IN MSINIT ;|
247 PUBLIC MEDIA_PATCH ;|
248MEDIA_PATCH: ;|
249 CALL MEDIACHECK ;|
250 JC ERR$EXITJ ;|
251 CALL HASCHANGE ;|
252 JNZ MEDIA$DONE ;|
253;----------------------------------------|
254; IF WE COME HERE, WE HAVE A FLOPPY WITH NO CHANGELINE SUPPORT
255 MOV SI,1 ; PRESUME NO CHANGE
256 MOV AL,CS:[TIM_DRV] ; LAST DRIVE ACCESSED
257 CMP AL,BYTE PTR [DI].DRIVENUM ;IS DRIVE OF LAST ACCESS THE SAME?
258 JNZ MEDIA$UNK ; NO, THEN "I DON'T KNOW"
259;
260; CHECK TO SEE IF THIS DRIVE HAS BEEN ACCESSED IN THE LAST 2 SECONDS.
261 CALL CHECK_TIME_OF_ACCESS ; SETS SI CORRECTLY
262 JMP SHORT MEDIA$DONE
263
264MEDIA$UNK:
265 DEC SI ; RETURN "I DON'T KNOW"
266;
267; SI NOW CONTAINS THE CORRECT VALUE FOR MEDIA CHANGE. CLEAN UP THE LEFT OVERS
268;
269MEDIA$DONE:
270 LES BX,CS:[PTRSAV] ; GET ORIGINAL PACKET
271 MOV WORD PTR ES:[BX].TRANS,SI
272 OR SI,SI
273 JS INIT_PATCH
274 JMP EXIT
275MEDIA$CHK ENDP
276;----------------------------------------|
277; WARNING: DO NOT CHANGE THE FOLLOWING. ;|
278; IT GETS PATCHED IN MSINIT ;|
279 PUBLIC INIT_PATCH ;|
280INIT_PATCH PROC NEAR ;|
281 CALL MEDIA_SET_VID ;|
282;----------------------------------------|
283 MOV CS:[TIM_DRV],-1 ; MAKE SURE WE ASK ROM FOR MEDIA CHECK
284VOLIDOK:
285 JMP EXIT
286INIT_PATCH ENDP
287
288ERR$EXITJ PROC NEAR
289
290 MESSAGE FTESTCOM,<"ERR$EXITJ: ">
291 MNUM FTESTCOM,AX
292 MESSAGE FTESTCOM,<" == ">
293 CALL MAPERROR
294 MNUM FTESTCOM,AX
295 MESSAGE FTESTCOM,<CR,LF>
296 JMP ERR$EXIT
297ERR$EXITJ ENDP
298
299;
300; PERFORM A CHECK ON THE TIME PASSED SINCE THE LAST ACCESS FOR THIS PHYSICEL
301; DRIVE.
302; WE ARE ACCESSING THE SAME DRIVE. IF THE TIME OF LAST SUCCESSFUL ACCESS WAS
303; LESS THAN 2 SECONDS AGO, THEN WE MAY PRESUME THAT THE DISK WAS NOT CHANGED.
304; RETURNS IN SI:
305; 0 - IF TIME OF LAST ACCESS WAS >= 2 SECONDS
306; 1 - IF TIME WAS < 2 SECONDS (I.E NO MEDIA CHANGE ASSUMED)
307; REGISTERS AFFECTED AX,CX,DX, FLAGS.
308;
309CHECK_TIME_OF_ACCESS PROC NEAR
310 PUBLIC CHECK_TIME_OF_ACCESS
311
312 MOV SI,1 ; PRESUME NO CHANGE.
313;SB33014*************************************************************
314 xor AH,AH ; set command to read time
315 int 1Ah ; call rom-bios clock routine
316;SB33014*************************************************************
317;
318; NOW THAT WE ARE READING THE TIME, WE MUST MAKE SURE THAT WE DO NOT LOSE A
319; DATE WRAP. THE ROM WILL RETURN THE VALUE ONLY ONCE, SO WE NEED TO NOTE THIS
320; FACT.
321;
322 SHR AL,1
323 ADC CS:[DAYCNT],0 ; ADD IT IN TO OUR REMEMBERED DAY COUNT
324;
325; COMPUTE ELAPSED TIME
326;
327 MOV AX,WORD PTR DS:[DI].TIM_LO ; GET STORED TIME
328 SUB DX,AX
329 MOV AX,WORD PTR DS:[DI].TIM_HI
330 SBB CX,AX
331;
332; CX:DX IS THE ELAPSED TIME
333;
334 JNZ TIMECHECK_UNK ; CX <> 0 => > 1 HOUR
335 OR DX,DX ; TIME MUST PASS
336 JNZ TIMEPASSED ; YES, EXAMINE MAX VALUE
337;
338; NO NOTICEABLE TIME HAS PASSED. WE CANNOT TRUST THE COUNTER TO BE ALWAYS
339; AVAILABLE AS THERE ARE BOGUS PROGRAMS THAT GO AND REPROGRAM THE THING. WE
340; KEEP A COUNT OF THE NUMBER OF MEDIA CHECKS THAT WE'VE SEEN THAT DO NOT HAVE
341; ANY TIME PASSING. IF WE EXCEED A GIVE THRESHOLD, WE GIVE UP ON THE TIMER.
342;
343 INC BYTE PTR CS:ACCESSCOUNT
344 CMP BYTE PTR CS:ACCESSCOUNT,ACCESSMAX
345 JB TIMECHECK_RET ; IF COUNT IS LESS THAN THRESHOLD, OK
346 DEC BYTE PTR CS:ACCESSCOUNT ; DON'T LET THE COUNT WRAP
347 JMP SHORT TIMECHECK_UNK ; "I DON'T KNOW" IF MEDIA CHANGED
348;
349; 18.2 TICS PER SECOND.
350;
351TIMEPASSED:
352 CMP DX,18 * 2 ; MIN ELAPSED TIME?
353 JBE TIMECHECK_RET ; YES, PRESUME NO CHANGE
354;
355; EVERYTHING INDICATES THAT WE DO NOT KNOW WHAT HAS HAPPENED.
356;
357TIMECHECK_UNK:
358 DEC SI ; PRESUME I DON'T KNOW
359TIMECHECK_RET:
360 RET
361CHECK_TIME_OF_ACCESS ENDP
362
363ERR$EXITJ2: JMP ERR$EXITJ
364;
365; BUILD A VALID BPB FOR THE DISK IN THE DRIVE.
366;
367 PUBLIC GET$BPB
368GET$BPB PROC NEAR
369 MESSAGE FTESTDISK,<"DISK BUILD BPB ">
370 MNUM FTESTDISK,AX
371 MESSAGE FTESTDISK,<CR,LF>
372 MOV AH,BYTE PTR ES:[DI] ;GET FAT ID BYTE READ BY DOS
373 CALL SETDRIVE ; GET THE CORRECT BDS FOR THE DRIVE
374 TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE
375 JNZ ALREADY_GOTBPB ; NO NEED TO BUILD FOR FIXED DISKS
376;J.K. Let's set the default value for VOLID,Vol_Serial,FileSys_ID in BDS table
377 call Clear_IDs ;AN000;
378 mov cs:[Set_ID_Flag],1 ;AN000; Indicate to set system id in BDS
379 CALL GETBP ;BUILD A BPB IF NECESSARY.
380 JC ERR$EXITJ2 ;AN000; If error, Set_ID_flag is set to 0 already.
381 cmp cs:[Set_ID_Flag],2 ;AN000; Already, volume_Label set from Boot record
382 mov cs:[Set_ID_Flag],0 ;AN000; to BDS table?
383 je Already_GotBPB ;AN000; Then do not set it again from Root directory.
384 ;AN000; Otherwise, conventional Boot record.
385GET$BPB ENDP
386;----------------------------------------|
387; WARNING: DO NOT CHANGE THE FOLLOWING. ;|
388; IT GETS PATCHED IN MSINIT ;|
389 PUBLIC SET_PATCH ;|
390SET_PATCH PROC NEAR ;|
391 CALL SET_VOLUME_ID ;|
392;----------------------------------------|
393 MESSAGE FTESTDISK,<"SET VOLUME ID">
394 MNUM FTESTDISK,DI
395 MESSAGE FTESTDISK,<" ">
396 MNUM FTESTDISK,DS
397 MESSAGE FTESTDISK,<CR,LF>
398
399ALREADY_GOTBPB:
400 ADD DI,BYTEPERSEC ; RETURN THE BPB THAT IS IN THE CURRENT BDS
401
402 PUBLIC SETPTRSAV
403SETPTRSAV: ; RETURN POINT FOR DSK$INIT
404 LES BX,CS:[PTRSAV]
405 MOV ES:[BX].MEDIA,AH
406 MOV ES:[BX].COUNT,DI
407 MOV ES:[BX].COUNT+2,DS
408 JMP EXIT
409SET_PATCH ENDP
410
411;J.K. Clear IDs in BDS table. Only applied for Floppies.
412;Input: DS:DI -> BDS table
413;Output: VOLID set to "NO NAME "
414; VOL_SERIAL set to 0.
415; FileSys_ID set to "FAT12 " or "FAT16 "
416; depending on the flag FATSIZE in BDS.
417;All registers saved.
418 public Clear_IDs
419Clear_IDs proc near ;AN000;
420 push ds ;AN000;
421 push di ;AN000;
422 push es ;AN000;
423 push si ;AN000;
424 push cx ;AN000;
425
426 push ds ;AN000;
427 pop es ;AN000; es -> bds
428 push cs ;AN000;
429 pop ds ;AN000; ds = cs
430
431 mov cx, 0 ;AN000; no serial number
432 mov word ptr es:[di.VOL_SERIAL],cx ;AN000;
433 mov word ptr es:[di.VOL_SERIAL]+2,cx ;AN000;
434
435 mov cx, BOOT_VOLUME_LABEL_SIZE ;AN000; =11
436 mov si, offset VOL_NO_NAME ;AN000;
437 push di ;AN000; save BDS pointer
438 add di, VOLID ;AN000; points to VOLID field
439 rep movsb ;AN000;
440 pop di ;AN000; restore BDS pointer
441 test es:[di.FATSIZ], FBIG ;AN000;
442 jnz CI_BigFat ;AN000; small fat
443 mov si, offset FAT_12_ID ;AN000;
444 jmp CI_Filesys ;AN000;
445CI_BigFat: ;AN000;
446 mov si, offset FAT_16_ID ;AN000; big fat
447CI_Filesys: ;AN000;
448 mov cx, BOOT_SYSTEM_ID_SIZE ;AN000; =8
449 add di, FILESYS_ID ;AN000; points to FILESYS_ID field
450 rep movsb ;AN000;
451
452 pop cx ;AN000;
453 pop si ;AN000;
454 pop es ;AN000;
455 pop di ;AN000;
456 pop ds ;AN000;
457 ret ;AN000;
458Clear_IDs endp ;AN000;
459
460
461; GETBP - RETURN BPB FROM THE DRIVE SPECIFIED BY THE BDS.
462; IF THE RETURN_FAKE_BPB FLAG IS SET, THEN IT DOES NOTHING.
463; NOTE THAT WE NEVER COME HERE FOR FIXED DISKS.
464; FOR ALL OTHER CASES,
465; - IT READS BOOT SECTOR TO PULL OUT THE BPB
466; - IF NO VALID BPB IS FOUND, IT THEN READS THE FAT SECTOR,
467; TO GET THE FAT ID BYTE TO BUILD THE BPB FROM THERE.
468;
469; INPUTS: DS:DI POINT TO CORRECT BDS.
470;
471; OUTPUTS: FILLS IN BPB IN CURRENT BDS IF VALID BPB OR FAT ID ON DISK.
472; CARRY SET, AND AL=7 IF INVALID DISK.
473; CARRY SET AND ERROR CODE IN AL IF OTHER ERROR.
474; If failed to recognize the Boot Record, then will set the
475; Set_ID_Flag to 0.
476; J.K. This routine will only work for a floppy diskette.
477; For a fixed disk, it will just return.
478
479 PUBLIC GETBP
480GETBP PROC NEAR
481; IF RETURNING FAKE BPB THEN RETURN BPB AS IS.
482 TEST WORD PTR [DI].FLAGS,RETURN_FAKE_BPB OR FNON_REMOVABLE
483 JZ GETBP1
484 JMP GETRET_EXIT
485
486GETBP1:
487 MESSAGE FTESTDISK,<"BUILDING BPB FROM SCRATCH",CR,LF>
488 SAVEREG <CX,DX,ES,BX>
489;
490; ATTEMPT TO READ IN BOOT SECTOR AND DETERMINE BPB.
491; WE ASSUME THAT THE 2.X AND GREATER DOS DISKS ALL HAVE A VALID BOOT SECTOR.
492;
493RDBOOT:
494 CALL READBOOTSEC
495 JC GETBP_ERR_RET_brdg ; CARRY SET IF THERE WAS ERROR.
496 CMP BX,0 ; BX IS 0 IF BOOT SECTOR IS VALID.
497 JNZ DOFATBPB
498
499 CALL MOVBPB ; MOVE BPB INTO REGISTERS.
500 JMP HAS1
501
502Getbp_err_ret_brdg: jmp Getbp_err_ret
503;
504; WE HAVE A 1.X DISKETTE.
505; IN THIS CASE READ IN THE FAT ID BYTE AND FILL IN BPB FROM THERE.
506;
507DOFATBPB:
508 CALL READFAT ; PUTS MEDIA DESCRIPTOR BYTE IN AH
509 JC GETBP_ERR_RET_Brdg
510;----------------------------------------|
511; WARNING: DO NOT CHANGE THE FOLLOWING. ;|
512; IT GETS PATCHED IN MSINIT ;|
513 PUBLIC GETBP1_PATCH ;|
514GETBP1_PATCH: ;|
515 CALL HIDENSITY ;|
516;----------------------------------------|
517;TEST FOR A VALID 3.5" MEDIUM
518 CMP [DI].FORMFACTOR,FFSMALL
519 JNZ IS_FLOPPY
520 CMP AH,0F9H ; IS IT A VALID FAT ID BYTE FOR 3.5" ?
521 JNZ GOT_UNKNOWN_MEDIUM
522 MOV BX,OFFSET SM92 ; POINTER TO CORRECT BPB
523 PUSH CS
524 POP ES
525
526 ASSUME ES:CODE
527;J.K. DS points to segment of BDS. The following should be modified
528;J.K. to get spf,csec,spa,spt correctly. It had been wrong if DRIVER.SYS
529;J.K. is loaded since the BDS is inside the driver.sys.
530 MOV AL,es:[BX.SPF]
531 MOV CX,es:[BX.CSEC]
532 MOV DX,WORD PTR es:[BX.SPA]
533 MOV BX,WORD PTR es:[BX.SPT]
534 JMP SHORT HAS1
535; MUST BE A 5.25" FLOPPY IF WE COME HERE
536IS_FLOPPY:
537 MOV CL,AH ;SAVE MEDIA
538 AND CL,0F8H ;NORMALIZE
539 CMP CL,0F8H ;COMPARE WITH GOOD MEDIA BYTE
540 JNZ GOT_UNKNOWN_MEDIUM
541
542GOODID:
543 MOV AL,1 ;SET NUMBER OF FAT SECTORS
544 MOV BX,64*256+8 ;SET DIR ENTRIES AND SECTOR MAX
545 MOV CX,40*8 ;SET SIZE OF DRIVE
546 MOV DX,01*256+1 ;SET HEAD LIMIT AND SEC/ALL UNIT
547 TEST AH,00000010B ;TEST FOR 8 OR 9 SECTOR
548 JNZ HAS8 ;NZ = HAS 8 SECTORS
549 INC AL ;INC NUMBER OF FAT SECTORS
550 INC BL ;INC SECTOR MAX
551 ADD CX,40 ;INCREASE SIZE
552HAS8:
553 TEST AH,00000001B ;TEST FOR 1 OR 2 HEADS
554 JZ HAS1 ;Z = 1 HEAD
555 ADD CX,CX ;DOUBLE SIZE OF DISK
556 MOV BH,112 ;INCREASE NUMBER OF DIRECTORY ENTRIES
557 INC DH ;INC SEC/ALL UNIT
558 INC DL ;INC HEAD LIMIT
559
560HAS1:
561 PUBLIC HAS1
562
563 MOV BYTE PTR DS:[DI].SECPERCLUS,DH
564 MOV BYTE PTR DS:[DI].CDIR,BH
565 MOV WORD PTR DS:[DI].DRVLIM,CX
566 MOV BYTE PTR DS:[DI].MEDIAD,AH
567 MOV BYTE PTR DS:[DI].CSECFAT,AL
568 MOV BYTE PTR DS:[DI].SECLIM,BL
569 MOV BYTE PTR DS:[DI].HDLIM,DL
570;SB34DISK001*******************************************************************
571;SB the HIDSEC_H field and DRVLIM_L field and the
572;SB DRVLIM_H fields need to be set to 0 since this code here is for floppies
573;SB 3 LOCS
574
575 mov word ptr ds:[di].HIDSEC_H,0
576 mov word ptr ds:[di].HIDSEC_L,0
577 mov word ptr ds:[di].DRVLIM_H,0
578
579;SB34DISK001*******************************************************************
580GETRET:
581 POP BX
582 RESTOREREG <ES,DX,CX>
583
584 ASSUME ES:NOTHING
585
586GETRET_EXIT:
587 RET
588
589GETBP_ERR_RET:
590;J.K. Before doing anything else, set Set_ID_Flag to 0.
591 mov cs:Set_ID_Flag, 0 ;AN000;
592 CALL MAPERROR
593 JMP SHORT GETRET
594;
595; WE HAVE A 3.5" DISKETTE FOR WHICH WE CANNOT BUILD A BPB. WE DO NOT ASSUME ANY
596; TYPE OF BPB FOR THIS MEDIUM.
597;
598GOT_UNKNOWN_MEDIUM:
599 mov cs:Set_ID_Flag, 0 ;AN000;
600 MOV AL,ERROR_UNKNOWN_MEDIA
601 STC
602 JMP SHORT GETRET
603GETBP ENDP
604
605BPBTYPE STRUC
606SPF DB ?
607SPT DB ?
608CDIRE DB ?
609CSEC DW ?
610SPA DB ?
611CHEAD DB ?
612BPBTYPE ENDS
613
614;
615; READ IN THE BOOT SECTOR. SET CARRY IF ERROR IN READING SECTOR.
616; BX IS SET TO 1 IF THE BOOT SECTOR IS INVALID, OTHERWISE IT IS 0.
617;
618READBOOTSEC PROC NEAR
619 MOV DH,0 ;HEAD 0
620 MOV CX,0001 ;CYLINDER 0, SECTOR 1
621 CALL READ_SECTOR
622 JC ERR_RET
623 XOR BX,BX ; ASSUME VALID BOOT SECTOR.
624
625;*******************************************************************************
626; PUT A SANITY CHECK FOR THE BOOT SECTOR IN HERE TO DETECT BOOT SECTORS THAT
627; DO NOT HAVE VALID BPBS.
628; WE EXAMINE THE FIRST TWO BYTES - THEY MUST CONTAIN A LONG JUMP (69H) OR A
629; SHORT JUMP (EBH) FOLLOWED BY A NOP (90H), OR A SHORT JUMP (E9H).
630; IF THIS TEST IS PASSED, WE FURTHER CHECK BY EXAMINING THE SIGNATURE AT
631; THE END OF THE BOOT SECTOR FOR THE WORD AA55H.
632; IF THE SIGNATURE IS NOT PRESENT, WE EXAMINE THE MEDIA DESCRIPTOR BYTE TO
633; SEE IF IT IS VALID.
634;J.K. 10/15/86 DCR00012. For DOS 3.3, this logic is modified a little bit.
635; We are not going to check Signature. Instead we are going to sanity
636; check the media byte in BPB regardless of the validity of signature.
637; This is to save the already developed commercial products that have
638; good jump instruction and signature but with the false BPB informations
639; that will crash the diskette drive operation. (For example, Symphony diskette).
640;******************************************************************************
641 CMP BYTE PTR CS:[DISKSECTOR],069H ; IS IT A DIRECT JUMP?
642 JE Check_bpb_MediaByte ; DON'T NEED TO FIND A NOP
643 CMP BYTE PTR CS:[DISKSECTOR],0E9H ; DOS 2.0 JUMP?
644 JE Check_bpb_MediaByte ; NO NEED FOR NOP
645 CMP BYTE PTR CS:[DISKSECTOR],0EBH ; HOW ABOUT A SHORT JUMP.
646 JNE INVALIDBOOTSEC
647 CMP BYTE PTR CS:[DISKSECTOR]+2,090H ; IS NEXT ONE A NOP?
648 JNE INVALIDBOOTSEC
649
650
651;J.K. 10/15/86 Don't have to perform the following signature check since
652; we need to check the media byte even with the good signatured diskette.
653;CHECK_SIGNATURE:
654; CMP WORD PTR CS:[DISKSECTOR+1FEH],0AA55H ; SEE IF NON-IBM DISK OR 1.X
655; ; MEDIA.
656; JZ CHECKSINGLESIDED ; GO SEE IF SINGLE SIDED MEDIUM. MAY
657; ; NEED SOME SPECIAL HANDLING
658;
659; CHECK FOR NON-IBM DISKS WHICH DO NOT HAVE THE SIGNATURE AA55 AT THE
660; END OF THE BOOT SECTOR, BUT STILL HAVE A VALID BOOT SECTOR. THIS IS DONE
661; BY EXAMINING THE MEDIA DESCRIPTOR IN THE BOOT SECTOR.
662;
663
664Check_bpb_MediaByte:
665
666 MOV AL,BYTE PTR CS:MEDIABYTE
667 AND AL,0F0H
668 CMP AL,0F0H ; ALLOW FOR STRANGE MEDIA
669 JNZ INVALIDBOOTSEC
670;
671; THERE WERE SOME (APPARENTLY A LOT OF THEM) DISKETTES THAT HAD BEEN FORMATTED
672; UNDER DOS 3.1 AND EARLIER VERSIONS WHICH HAVE INVALID BPBS IN THEIR BOOT
673; SECTORS. THESE ARE SPECIFICALLY DISKETTES THAT WERE FORMATTED IN DRIVES
674; WITH ONE HEAD, OR WHOSE SIDE 0 WAS BAD. THESE CONTAIN BPBS IN THE BOOT
675; SECTOR THAT HAVE THE SEC/CLUS FIELD SET TO 2 INSTEAD OF 1, AS IS STANDARD
676; IN DOS. IN ORDER TO SUPPORT THEM, WE HAVE TO INTRODUCE A "HACK" THAT WILL
677; HELP OUR BUILD BPB ROUTINE TO RECOGNISE THESE SPECIFIC CASES, AND TO
678; SET UP OUT COPY OF THE BPB ACCORDINGLY.
679; WE DO THIS BY CHECKING TO SEE IF THE BOOT SECTOR IS OFF A DISKETTE THAT
680; IS SINGLE-SIDED AND IS A PRE-DOS 3.20 DISKETTE. IF IT IS, WE SET THE
681; SEC/CLUS FIELD TO 1. IF NOT, WE CARRY ON AS NORMAL.
682CHECKSINGLESIDED:
683 MOV AL,BYTE PTR CS:MEDIABYTE
684 TEST AL,0001H ; IS LOW BIT SET? - INDICATES DOUBLE SIDED
685 JNZ GOODDSK
686 CMP WORD PTR CS:[DISKSECTOR+8],"." SHL 8 + "3"
687 JNZ MUSTBEEARLIER
688 CMP BYTE PTR CS:[DISKSECTOR+10],"2"
689 JAE GOODDSK
690
691; WE MUST HAVE A PRE-3.20 DISKETTE. SET THE SEC/CLUS FIELD TO 1
692MUSTBEEARLIER:
693 MOV BYTE PTR CS:[SECPERCLUSINSECTOR],1
694 JMP SHORT GOODDSK
695;******************************************************************************
696
697INVALIDBOOTSEC:
698 INC BX ; INDICATE THAT BOOT SECTOR INVALID
699GOODDSK: ; CARRY ALREADY RESET
700 CLC
701 RET
702
703ERR_RET: ; CARRY IS ALREADY SET ON ENTRY HERE
704 MESSAGE FTESTDISK,<"ERROR IN READBOOT",CR,LF>
705 RET
706READBOOTSEC ENDP
707
708; MOVES THE BPB READ FROM THE BOOT SECTOR INTO REGISTERS FOR USE BY
709; GETBP ROUTINE AT HAS1
710;J.K.-
711; If the Set_ID_Flag is 1, and if an extended Boot Record, then set Volume
712; Serial Number, Volume Label, File System ID in BDS according to
713; the BOOT reocrd. After that, this routine will set the Set_ID_Flag to 2
714; to signal that VOLUME Label is set already from the Extended BOOT record
715; (so, don't set it again by calling "SET_VOLUME_ID" routine which uses
716; the volume label in the root directory.
717
718MOVBPB PROC NEAR
719 SAVEREG <DS,DI>
720 PUSH CS
721 POP DS
722 MOV DI,OFFSET BPB_IN_SECTOR
723 MOV DH,BYTE PTR [DI].SECALL ;SECTORS PER UNIT
724 MOV BH,BYTE PTR [DI].DIRNUM ;NUMBER OF DIRECTORY ENTRIES
725 MOV CX,WORD PTR [DI].SECNUM ;SIZE OF DRIVE
726 MOV AH,BYTE PTR [DI].FATID ;MEDIA DESCRIPTOR
727 MOV AL,BYTE PTR [DI].FATSIZE ;NUMBER OF FAT SECTORS
728 MOV BL,BYTE PTR [DI].SLIM ;SECTORS PER TRACK
729 MOV DL,BYTE PTR [DI].HLIM ;NUMBER OF HEADS
730 RESTOREREG <DI,DS>
731 cmp cs:[Set_ID_Flag], 1 ;AC008 called by GET$BPB?
732 jne MovBPB_Ret ;AC008
733 call Mov_Media_IDs ;AC008
734 jc MovBPB_Conv ;AC008 Conventional boot record?
735 mov cs:[Set_ID_Flag],2 ;AC008 signals that Volume ID is set.
736MovBPB_Conv: ;AC008
737 cmp cs:fHave96, 1 ;AC008
738 jne MovBPB_Ret ;AC008
739 call ResetChanged ;AC008 Reset Flags in BDS to NOT fCHANGED.
740MovBPB_Ret: ;AC008
741 clc ;AC008
742 ret ;AC008
743MOVBPB ENDP ;AC008
744
745
746;
747 public Mov_Media_IDs
748Mov_Media_IDs Proc near ;AN000;
749;copy the boot_serial number, Volume id, and Filesystem id from the
750;***Extended Boot record*** in cs:DiskSector to the BDS table pointed
751;by DS:DI.
752;In.) DS:DI -> BDS
753; CS:DiskSector = Valid extended boot record.
754;Out.) Vol_Serial, Volid and System_Id in BDS are set according to
755; the boot record information.
756; Carry flag set if not an extended BPB.
757; All registers saved except the flag.
758
759 cmp cs:[Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN000; = 41
760 jne MMI_Not_Ext ;AN000;
761 push cx ;AN000;
762 mov cx, cs:[Boot_Serial_L] ;AN000;
763 mov word ptr ds:[di.VOL_SERIAL],cx ;AN000;
764 mov cx, cs:[Boot_Serial_H] ;AN000;
765 mov word ptr ds:[di.VOL_SERIAL+2],cx ;AN000;
766 push ds ;AN000; Save regs.
767 push di ;AN000;
768 push es ;AN000;
769 push si ;AN000;
770
771 push ds ;AN000; ds-> cs, es-> bds
772 pop es ;AN000;
773 push cs ;AN000;
774 pop ds ;AN000;
775
776 mov cx, BOOT_VOLUME_LABEL_SIZE ;AN000;
777 mov si, offset Boot_Volume_Label;AN000;
778 push di
779 add di, VOLID ;AN000;
780 rep movsb ;AN000;
781 pop di
782 mov cx, BOOT_SYSTEM_ID_SIZE ;AN000; =8
783 mov si, offset Boot_System_ID ;AN000;
784 add di, FILESYS_ID ;AN000;
785 rep movsb ;AN000;
786
787 pop si ;AN000;
788 pop es ;AN000;
789 pop di ;AN000;
790 pop ds ;AN000;
791 pop cx ;AN000;
792 clc ;AN000;
793MMI_Ret: ;AN000;
794 ret ;AN000;
795MMI_Not_Ext: ;AN000;
796 stc ;AN000;
797 ret ;AN000;
798Mov_Media_IDs endp ;AN000;
799
800
801; READ IN THE FAT SECTOR AND GET THE MEDIA BYTE FROM IT.
802; INPUT : AL CONTAINS LOGICAL DRIVE.
803; OUTPUT:
804; CARRY SET IF AN ERROR OCCURS, AX CONTAINS ERROR CODE.
805; OTHERWISE, AH CONTAINS MEDIA BYTE ON EXIT. AL IS PRESERVED.
806
807READFAT PROC NEAR
808 PUSH AX ; PRESERVE LOGICAL DRIVE IN AL
809 MOV DH,0 ; HEAD 0
810 MOV CX,0002 ; CYLINDER 0, SECTOR 2
811 CALL READ_SECTOR ; CS:BX POINTS TO FAT SECTOR
812 JC BAD_FAT_RET
813 POP AX ; RESET LOGICAL DRIVE
814 MOV AH,BYTE PTR CS:[BX] ; MEDIA BYTE
815 RET
816
817BAD_FAT_RET: ; CARRY SET ON ENTRY
818 MESSAGE FTESTDISK,<"ERROR IN FAT READ",CR,LF>
819 POP CX ; CLEAR STACK
820 RET
821READFAT ENDP
822
823; READ A SINGLE SECTOR INTO THE TEMP BUFFER.
824; PERFORM THREE RETRIES IN CASE OF ERROR.
825; INPUTS: DRIVE HAS PHYSICAL DRIVE TO USE
826; CX HAS SECTOR AND CYLINDER
827; DH HAS HEAD
828; OUTPUTS: CARRY CLEAR
829; CS:BX POINT TO SECTOR
830; CARRY SET
831; AX HAS ROM ERROR CODE
832; REGISTERS ES AND BP ARE PRESERVED.
833
834READ_SECTOR PROC NEAR
835 PUBLIC READ_SECTOR
836
837 PUSH BP
838 MOV BP,3 ; MAKE 3 ATTEMPTS
839 PUSH ES
840;SB33015*****************************************************************
841 mov DL, byte ptr ds:[di].DriveNum ;SB;3.30*
842 mov BX, offset DiskSector ; Get ES:BX to point to buffer ;SB;3.30*
843 push CS ; get the segment right ;SB;3.30*
844 pop ES ; now ES:BX is correct ;SB;3.30*
845;SB33015*****************************************************************
846RD_RET:
847;SB33016*****************************************************************
848 mov AX, 0201h ; number of sectors to 1 (AL=1);SB;3.30*
849 int 13h ; call rom-bios disk routines ;SB;3.30*
850
851;SB33016*****************************************************************
852 JNC OKRET2
853Rd_rty:
854 CALL AGAIN ; RESET DISK, DECREMENT BP, PRESERVE AX
855 jz Err_RD_RET
856 test word ptr ds:[di].flags,fNon_Removable
857 JNZ RD_RET
858 cmp cs:[Media_Set_For_Format], 0 ;AN012;
859 jne Rd_Skip1_DPT ;AN012;
860 push ds ;J.K. 11/7/86 For retry, set the head settle time
861 push ax ;to 0Fh. PTM845.
862 lds si,cs:DPT
863 mov al, ds:[si].disk_head_sttl
864 mov cs:[save_head_sttl],al
865 mov byte ptr ds:[si].disk_head_sttl, NormSettle
866 pop ax
867 pop ds
868Rd_Skip1_DPT: ;AN012;
869;SB33017*****************************************************************
870 ; SET CMD TO READ (AH=2) AND ;SB ;3.30
871 MOV AX, 0201h ; NUM OF SECTORS TO 1 (AL=1) ;SB ;3.30
872 INT 13h ; CALL ROM-BIOS DISK ROUTINES ;SB ;3.30
873;SB33017*****************************************************************
874 pushf ;AN012;
875 cmp cs:[Media_Set_For_Format], 0 ;AN012;
876 jne Rd_Skip2_DPT ;AN012;
877 push ds
878 push ax
879 lds si,cs:DPT
880 mov al, cs:[save_head_sttl]
881 mov byte ptr ds:[si].disk_head_sttl, al
882 pop ax
883 pop ds
884Rd_Skip2_DPT: ;AN012;
885 popf ;AN012;
886 jnc OKRET2
887 jmp Rd_rty
888ERR_RD_RET:
889 MOV DL,-1 ; MAKE SURE WE ASK ROM IF MEDIA HAS CHANGED
890 STC ; RETURN ERROR
891; UPDATE INFORMATION PERTAINING TO LAST DRIVE ACCESSED, TIME OF ACCESS, LAST
892; TRACK ACCESSED IN THAT DRIVE.
893OKRET2:
894 MOV CS:[STEP_DRV],DL ; SET UP FOR HEAD SETTLE LOGIC IN DISK.
895 MOV CS:[TIM_DRV],DL ;SAVE DRIVE LAST ACCESSED
896 MOV BYTE PTR [DI].TRACK,CH ; SAVE LAST TRACK ACCESSED ON THIS DRIVE
897 PUSHF ; PRESERVE FLAGS IN CASE ERROR OCCURRED
898 CALL SET_TIM
899 POPF ; RESTORE FLAGS
900 POP ES
901 POP BP
902 RET
903READ_SECTOR ENDP
904
905;-----------------------------------------------------------
906;
907; DISK REMOVABLE ROUTINE ARR 2.41
908;
909
910DSK$REM PROC NEAR ;ARR 2.41
911 PUBLIC DSK$REM
912
913 MESSAGE FTESTDISK,<"DISK REMOVABLE ">
914 MNUM FTESTDISK,AX
915 MESSAGE FTESTDISK,<CR,LF>
916; AL IS UNIT #
917 CALL SETDRIVE ; GET BDS FOR THIS DRIVE
918 TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE
919 JNZ NON_REM
920 JMP EXIT
921
922NON_REM:
923 JMP BUS$EXIT ;ARR 2.41
924DSK$REM ENDP
925
926; SETDRIVE SCANS THROUGH THE DATA STRUCTURE OF BDSS, AND RETURNS A POINTER TO
927; THE ONE THAT BELONGS TO THE DRIVE SPECIFIED. CARRY IS SET IF NONE EXISTS FOR
928; THE DRIVE.
929; IF THE BYTE [PHYS_DRV] IS 0 THEN
930; ON ENTRY, AL CONTAINS THE LOGICAL DRIVE NUMBER.
931; ON EXIT, DS:DI POINTS TO CORRECT BDS FOR THE DRIVE IF CARRY CLEAR.
932
933; ELSE IF THE BYTE [PHYS_DRV] IS 1 THEN (ONLY USED FOR FIXED DISKS WHEN AN ECC
934; ERROR OCCURS)
935; ON ENTRY, DL CONTAINS THE PYHSICAL DRIVE NUMBER.
936; ON EXIT, DS:DI POINTS TO CORRECT BDS FOR THE DRIVE IF CARRY CLEAR.
937
938 PUBLIC SETDRIVE
939SETDRIVE PROC NEAR
940 MESSAGE FTESTDISK,<"SETDRIVE",CR,LF>
941 PUSH BX
942 PUSH CS
943 POP DS
944 ASSUME DS:CODE
945
946; ASSUME FIRST BDS IS IN THIS SEGMENT
947 MOV DI,WORD PTR START_BDS
948SCAN_LOOP:
949 CMP BYTE PTR CS:[PHYS_DRV],1 ; DOES AL HAVE PHYSICAL DRIVE?
950 JB USE_LOGICAL_DRV
951 CMP BYTE PTR [DI].DRIVENUM,AL
952 JE SETDRV
953 JMP SHORT GET_NXT_BDS
954USE_LOGICAL_DRV:
955 CMP BYTE PTR [DI].DRIVELET,AL
956 JE SETDRV
957GET_NXT_BDS:
958 MOV BX,WORD PTR [DI].LINK+2 ; GO TO NEXT BDS
959 MOV DI,WORD PTR [DI].LINK
960 MOV DS,BX
961 ASSUME DS:NOTHING
962
963 CMP DI,-1
964 JNZ SCAN_LOOP
965 STC
966SETDRV:
967 POP BX
968 RET
969SETDRIVE ENDP
970
971;-----------------------------------------------------------
972;
973; DISK I/O ROUTINES
974;
975
976DSK$WRITV PROC NEAR
977 PUBLIC DSK$WRITV
978
979 MESSAGE FTESTDISK,<"DISK WRITE WITH VERIFY ">
980 MNUM FTESTDISK,AX
981 MESSAGE FTESTDISK,<" ">
982 MNUM FTESTDISK,DX
983 MESSAGE FTESTDISK,<" FOR ">
984 MNUM FTESTDISK,CX
985 MESSAGE FTESTDISK,<CR,LF>
986 MOV CS:[WRTVERIFY],103H
987 JMP SHORT DSK$CL
988
989DSK$WRIT:
990 PUBLIC DSK$WRIT
991 MESSAGE FTESTDISK,<"DISK WRITE ">
992 MNUM FTESTDISK,AX
993 MESSAGE FTESTDISK,<" ">
994 MNUM FTESTDISK,DX
995 MESSAGE FTESTDISK,<" FOR ">
996 MNUM FTESTDISK,CX
997 MESSAGE FTESTDISK,<CR,LF>
998 MOV CS:[WRTVERIFY],ROMWRITE
999
1000DSK$CL:
1001 CALL DISKIO
1002DSK$IO:
1003 JC DSKBAD
1004 JMP EXIT
1005DSKBAD:
1006 JMP ERR$CNT
1007DSK$WRITV ENDP
1008
1009DSK$READ PROC NEAR
1010 PUBLIC DSK$READ
1011 MESSAGE FTESTDISK,<"DISK READ ">
1012 MNUM FTESTDISK,AX
1013 MESSAGE FTESTDISK,<" ">
1014 MNUM FTESTDISK,DX
1015 MESSAGE FTESTDISK,<" FOR ">
1016 MNUM FTESTDISK,CX
1017 MESSAGE FTESTDISK,<CR,LF>
1018 CALL DISKRD
1019 JMP DSK$IO
1020DSK$READ ENDP
1021
1022; MISCELLANEOUS ODD JUMP ROUTINES. MOVED OUT OF MAINLINE FOR SPEED.
1023
1024
1025; IF WE HAVE A SYSTEM WHERE WE HAVE VIRTUAL DRIVES, WE NEED TO PROMPT THE
1026; USER TO PLACE THE CORRECT DISK IN THE DRIVE.
1027
1028CHECKSINGLE PROC NEAR
1029 PUBLIC CHECKSINGLE
1030
1031 PUSH AX
1032 PUSH BX
1033 MOV BX,WORD PTR DS:[DI].FLAGS
1034 ; IF HARD DRIVE, CANNOT CHANGE DISK.
1035 ; IF CURRENT OWNER OF PHYSICAL DRIVE, NO NEED TO CHANGE DISKETTE.
1036 TEST BL,FNON_REMOVABLE OR FI_OWN_PHYSICAL
1037 JNZ SINGLERET
1038 TEST BL,FI_AM_MULT ; IS THERE A DRIVE SHARING THIS
1039 ; PHYSICAL DRIVE?
1040 JZ SINGLERET
1041; LOOK FOR THE PREVIOUS OWNER OF THIS PHYSICAL DRIVE AND RESET ITS OWNERSHIP
1042; FLAG.
1043 MOV AL,DS:[DI].DRIVENUM ; GET PHYSICAL DRIVE NUMBER
1044 PUSH DS ; PRESERVE POINTER TO CURRENT BDS
1045 PUSH DI
1046 PUSH CS
1047 POP DS
1048 ASSUME DS:CODE
1049
1050 MOV DI,OFFSET START_BDS
1051SCAN_LIST:
1052 MOV BX,WORD PTR [DI].LINK+2 ; GO TO NEXT BDS
1053 MOV DI,WORD PTR [DI].LINK
1054 MOV DS,BX
1055 ASSUME DS:NOTHING
1056
1057 CMP DI,-1 ; END OF LIST?
1058 JZ SINGLE_ERR_RET ; MUST BE ERROR
1059 CMP BYTE PTR [DI].DRIVENUM,AL
1060 JNZ SCAN_LIST
1061
1062CHECK_OWN:
1063 MOV BX,WORD PTR [DI].FLAGS
1064 TEST BL,FI_OWN_PHYSICAL
1065 JZ SCAN_LIST
1066 XOR BL,FI_OWN_PHYSICAL ; RESET OWNERSHIP FLAG
1067 MOV WORD PTR DS:[DI].FLAGS,BX
1068 POP DI ; RESTORE POINTER TO CURRENT BDS
1069 POP DS
1070 XOR BX,BX
1071 OR BL,FI_OWN_PHYSICAL ; ESTABLISH CURRENT BDS AS OWNER
1072 OR WORD PTR [DI].FLAGS,BX
1073
1074;
1075; WE EXAMINE THE FSETOWNER FLAG. IF IT IS SET, THEN WE ARE USING THE CODE IN
1076; CHECKSINGLE TO JUST SET THE OWNER OF A DRIVE. WE MUST NOT ISSUE THE PROMPT
1077; IN THIS CASE.
1078;
1079 CMP BYTE PTR CS:[FSETOWNER],1
1080 JZ SINGLERET
1081; TO SUPPORT "BACKWARD" COMPATIBILITY WITH IBM'S "SINGLE DRIVE STATUS BYTE"
1082; WE NOW CHECK TO SEE IF WE ARE IN A SINGLE DRIVE SYSTEM AND THE APPLICATION
1083; HAS "CLEVERLY" DIDDLED THE SDSB
1084 CMP CS:[SINGLE],2 ; IF (SINGLE_DRIVE_SYSTEM)
1085 JNE SHORT IGNORE_SDSB
1086
1087 SAVEREG <DS,DI,AX> ; THEN
1088 MOV AL,DS:[DI].DRIVELET ; IF (CURR_DRV == REQ_DRV)
1089 MOV AH,AL
1090 XOR DI,DI
1091 MOV DS,DI
1092 XCHG AL,DS:BYTE PTR LSTDRV ; THEN SWAP(CURR_DRV,REQ_DRV)
1093 CMP AH,AL ; ELSE
1094 RESTOREREG <AX,DI,DS> ; SWAP(CURR_DRV,REQ_DRV)
1095 JE SINGLERET ; ISSUE SWAP_DSK_MSG
1096
1097IGNORE_SDSB:
1098 CALL SWPDSK ; ASK USER FOR CORRECT DISK
1099SINGLERET:
1100 POP BX
1101 POP AX
1102 RET
1103
1104SINGLE_ERR_RET:
1105 STC
1106 POP DI ; RESTORE CURRENT BDS
1107 POP DS
1108 JMP SHORT SINGLERET
1109
1110BADDRIVE:
1111 MOV AL,8 ;Sector not found
1112 jmp short BadDrive_Ret ;AN004;AN005;AN006;
1113UnformattedDrive: ;AN004;AN005;AN006;
1114 mov al,7 ;AN004;Unknown media;AN005;AN006;
1115BadDrive_Ret:
1116 STC
1117IORET: RET
1118
1119BOGUSSETTLE:
1120 MOV AL,NORMSETTLE ; SOMEONE HAS DIDDLED THE SETTLE
1121 JMP GOTSLOWSETTLE
1122CHECKSINGLE ENDP
1123;------------------------------------------------------------
1124;
1125; DISK I/O HANDLER
1126;
1127; AL = DRIVE NUMBER (0-6)
1128; AH = MEDIA DESCRIPTOR
1129; CX = SECTOR COUNT
1130; DX = FIRST SECTOR (low)
1131; [Start_Sec_H] = FIRST SECTOR (high) ;J.K. 32 bit calculation.
1132; DS = CS
1133; ES:DI = TRANSFER ADDRESS
1134; [RFLAG]=OPERATION (2=READ, 3=WRITE)
1135; [VERIFY]=1 FOR VERIFY AFTER WRITE
1136;
1137; IF SUCCESSFUL CARRY FLAG = 0
1138; ELSE CF=1 AND AL CONTAINS ERROR CODE
1139;
1140 PUBLIC DISKRD
1141DISKRD PROC NEAR
1142 MOV CS:[RFLAG],ROMREAD
1143
1144DISKIO:
1145 MOV BX,DI ; ES:BX = TRANSFER ADDRESS
1146 CALL SETDRIVE ; MAP LOGICAL AND PHYSICAL
1147 MOV AL,BYTE PTR DS:[DI].MEDIAD
1148 MOV CS:MEDBYT,AL ; PRESERVE MEDIA BYTE FOR DRIVE FOR USE
1149 ; IN DETERMINING MEDIA CHANGE.
1150 JCXZ IORET
1151;SB34DISK006******************************************************************
1152;SB See if the Media is formatted or not by checking the flags field in
1153;SB in the BDS. If it is unformatted we cannot allow I/O, so we should
1154;SB go to the error exit at label UnformattedDrive. 2LOCS
1155
1156 test word ptr ds:[di].FLAGS, UNFORMATTED_MEDIA
1157 jnz UnformattedDrive
1158;SB34DISK006******************************************************************
1159 mov cs:[SECCNT],CX ;save sector count
1160 MOV CS:[SPSAV],SP ; SAVE SP
1161
1162; ENSURE THAT WE ARE TRYING TO ACCESS VALID SECTORS ON THE DRIVE
1163;
1164
1165 mov ax,dx ;AN000; save DX to AX
1166 xor si,si ;AN000;
1167 add dx,cx ;AN000;
1168 adc si,0 ;AN000;
1169 cmp [di].DrvLim, 0 ;AN000; Is this drive > 32 bit sector ?
1170 je Sanity32 ;AN000;
1171 cmp si,0 ;AN000;
1172 jne BADDRIVE ;AN000;
1173 cmp dx, [di].DrvLim ;AN000;
1174 ja BADDRIVE ;AN000;
1175 jmp short SanityOK ;AN000;
1176Sanity32: ;AN000;
1177 add si, cs:[Start_Sec_H] ;AN000;
1178 cmp si, [di].DrvLim_H ;AN000;
1179 jb SanityOK ;AN000;
1180 ja BADDRIVE ;AN000;
1181 cmp dx, [di].DrvLim_L ;AN000;
1182 ja BADDRIVE ;AN000;
1183SanityOK: ;AN000;
1184 mov dx,cs:[Start_Sec_H] ;AN000;
1185 add ax,word ptr [di].HIDSEC_L ;AN000;
1186 adc dx,word ptr [di].Hidsec_H ;AN000;
1187;J.K. Now DX;AX have the physical first sector.
1188;Since the following procedures is going to destroy AX, let's
1189;save it temporarily to SAVED_WORD.
1190 mov cs:[Saved_Word], ax ;AN000; Save the sector number (low)
1191
1192; MOV SI,DX
1193; ADD SI,CX
1194; ADD DX,WORD PTR [DI].HIDSEC ; ADD IN THE HIDDEN SECTORS
1195; CMP SI,WORD PTR [DI].DRVLIM ; COMPARE AGAINST DRIVE MAX
1196; JA BADDRIVE
1197
1198; SET UP POINTER TO DISK BASE TABLE IN [DPT]. WE CANNOT ASSUME THAT IOSETUP
1199; WILL DO IT BECAUSE WE WILL SKIP THE SET UP STUFF WITH HARD DISKS.
1200 PUSH DS
1201 XOR AX,AX
1202 MOV DS,AX
1203 LDS SI,DWORD PTR DS:[DSKADR]; CURRENT DISK PARM TABLE
1204 MOV WORD PTR CS:DPT,SI
1205 MOV WORD PTR CS:DPT+2,DS
1206 POP DS
1207 TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE
1208 JNZ SKIP_SETUP
1209 CALL CHECKSINGLE
1210;
1211; CHECK TO SEE IF WE HAVE PREVIOUSLY NOTED A CHANGE LINE. THE ROUTINE
1212; RETURNS IF EVERYTHING IS OK. OTHERWISE, IT POPS OFF THE STACK AND RETURNS
1213; THE PROPER ERROR CODE.
1214;
1215;----------------------------------------|
1216; WARNING: DO NOT CHANGE THE FOLLOWING. ;|
1217; IT GETS PATCHED IN MSINIT ;|
1218 PUBLIC DISKIO_PATCH ;|
1219DISKIO_PATCH: ;|
1220 CALL CHECKLATCHIO ;|
1221;----------------------------------------|
1222;
1223; SET UP TABLES AND VARIABLES FOR I/O
1224 CALL IOSETUP
1225;
1226; NOW THE SETTLE VALUES ARE CORRECT FOR THE FOLLOWING CODE
1227;
1228SKIP_SETUP:
1229;J.K. 32 bit sector calculation.
1230; DX;[Saved_Word] = starting sector number.
1231 mov ax,dx ;AN000;
1232 xor dx,dx ;AN000;
1233 DIV WORD PTR [DI].SECLIM ;DIVIDE BY SEC PER TRACK
1234 mov cs:[Temp_H],ax ;AN000;
1235 mov ax, cs:[Saved_Word] ;AN000; Restore the lower word
1236 div word ptr [di].SecLim ;AN000;
1237;Now, [Temp_H],AX = track #, DX = sector
1238 INC DL ;Sector number is 1 based.
1239 MOV CS:[CURSEC],DL ;SAVE CURRENT SECTOR
1240 MOV CX,WORD PTR [DI].HDLIM ;GET NUMBER OF HEADS
1241
1242 push ax ;AN000;
1243 XOR DX,DX ;DIVIDE TRACKS BY HEADS PER CYLINDER
1244 mov ax, cs:[Temp_H] ;AN000;
1245 DIV CX
1246 mov cs:[Temp_H],ax ;AN000;
1247 pop ax ;AN000;
1248 div cx ;AN000;
1249;Now, [Temp_H],AX = cyliner #, DX = head
1250 cmp cs:[Temp_H],0 ;AN000;
1251 ja BADDRIVE_brdg ;AN000;
1252 cmp AX, 1024 ;AN000; 2**10 currently maxium for track #.
1253 ja BADDRIVE_brdg ;AN000;
1254 MOV CS:[CURHD],DL ;SAVE CURRENT HEAD
1255 MOV CS:[CURTRK],AX ;SAVE CURRENT TRACK
1256
1257;
1258; WE ARE NOW SET UP FOR THE I/O. NORMALLY, WE CONSIDER THE DMA BOUNDARY
1259; VIOLATIONS HERE. NOT TRUE. WE PERFORM THE OPERATION AS IF EVERYTHING IS
1260; SYMMETRIC; LET THE INT 13 HANDLER WORRY ABOUT THE DMA VIOLATIONS.
1261;
1262 MOV AX, CS:[SECCNT]
1263 CALL BLOCK
1264 CALL DONE
1265 RET
1266DISKRD ENDP
1267
1268;
1269BADDRIVE_Brdg:jmp Baddrive
1270;
1271
1272; SET THE DRIVE-LAST-ACCESSED FLAG FOR DISKETTE ONLY. WE KNOW THAT THE HARD
1273; DISK WILL NOT BE REMOVED.
1274; DS:DI -> CURRENT BDS.
1275; AX,CX,SI ARE DESTROYED.
1276;
1277 PUBLIC IOSETUP
1278IOSETUP PROC NEAR
1279 MOV AL,[DI].DRIVENUM
1280 MOV CS:[TIM_DRV],AL ; SAVE DRIVE LETTER
1281;
1282; DETERMINE PROPER HEAD SETTLE VALUES
1283;
1284 cmp cs:[Media_Set_For_Format], 0 ;AN012;
1285 jne Skip_DPT_Setting ;AN012;
1286 MOV CX,DS
1287 LDS SI,DWORD PTR CS:[DPT] ; GET POINTER TO DISK BASE TABLE
1288 MOV AL,CS:[EOT]
1289 MOV [SI].DISK_EOT,AL ; BUMP FOR US
1290 MOV AL,[SI].DISK_MOTOR_STRT ; PRESERVE OLD MOTOR START TIME
1291 MOV CS:MOTORSTARTUP,AL
1292;
1293; FOR 3.5" DRIVES, BOTH EXTERNAL AS WELL AS ON THE K09, WE NEED TO SET THE
1294; MOTOR START TIME TO 4. THIS CHECKING FOR EVERY I/O IS GOING TO AFFECT
1295; PERFORMANCE ACROSS THE BOARD, BUT IS NECESSARY!! - RS
1296;
1297 PUSH ES
1298 MOV ES,CX ; ES:DI -> TO CURRENT BDS
1299 CMP BYTE PTR ES:[DI].FORMFACTOR,FFSMALL
1300 JNZ MOTOR_START_OK
1301 MOV AL,4
1302 XCHG AL,[SI].DISK_MOTOR_STRT
1303MOTOR_START_OK:
1304 POP ES
1305;
1306; DS:SI NOW POINTS TO DISK PARAMETER TABLE. GET CURRENT SETTLE AND SET FAST
1307; SETTLE
1308;
1309 XOR AL,AL
1310 INC AL ; IBM WANTS FAST SETTLE TO BE 1 - RS.
1311 XCHG AL,[SI].DISK_HEAD_STTL ; GET SETTLE AND SET UP FOR FAST
1312 MOV CS:SETTLECURRENT,AL
1313 MOV AL,NORMSETTLE ; SOMEONE HAS DIDDLED THE SETTLE
1314GOTSLOWSETTLE:
1315 MOV DS,CX
1316 MOV CS:SETTLESLOW,AL
1317Skip_DPT_Setting: ;AN012;
1318 RET
1319;
1320; SET TIME OF LAST ACCESS, AND RESET DEFAULT VALUES IN THE DPT.
1321;
1322DONE:
1323 TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE
1324 JNZ RETZ ; DO NOT SET FOR NON-REMOVABLE MEDIA
1325 CALL SET_TIM ; SET TIME OF LAST ACCESS FOR DRIVE
1326;
1327; RESTORE HEAD SETTLE AND EOT VALUES
1328;
1329DIDDLEBACK:
1330 pushf ;AN013;Save flag
1331 cmp cs:[Media_Set_For_Format], 0 ;AN012;
1332 jne NoDiddleBack ;AN012;
1333 PUSH AX
1334 MOV DX,DS
1335 MOV AL,CS:SETTLECURRENT
1336 MOV AH,CS:MOTORSTARTUP
1337 LDS SI,CS:DPT
1338; MOV [SI].DISK_EOT,9 ;J.K. 4/25/86. Should not change the EOT value
1339 ;of diskbase to 9. This cause a problem
1340 ;with 1.44M diskette in Polaris when the user
1341 ;issue INT 13 with the default system
1342 ;diskbase.
1343 mov [si].DISK_EOT,9 ;J.K. 11/5/86. For compatibility reason, return
1344 ;back to set it to 9 ( PTM826 ).
1345 MOV [SI].DISK_HEAD_STTL,AL
1346 MOV [SI].DISK_SECTOR_SIZ,2
1347 MOV [SI].DISK_MOTOR_STRT,AH
1348 MOV DS,DX
1349 POP AX
1350NoDiddleBack: ;AN013;
1351 popf ;AN013;Restore flag
1352RETZ:
1353 RET
1354
1355;READ THE NUMBER OF SECTORS SPECIFIED IN AX, HANDLING TRACK BOUNDARIES
1356;DS:DI -> BDS FOR THIS DRIVE
1357BLOCK:
1358 OR AX,AX ;SEE IF ANY SECTORS TO READ
1359 JZ RETZ
1360;Fixed disk will not be restricted to the track-by-track basis. -J.K.4/10/86
1361 test word ptr [di].Flags, fNon_Removable ;J.K. Fixed disk?
1362 jz BLOCK_FLOPPY ;J.K.
1363;SB34DISK002*****************************************************************
1364;SB Check to see if multi track operation is allowed. If not
1365;SB we have to go to the block_floppy below to break up the operation.
1366;SB 2 LOCS
1367 test word ptr CS:MulTrk_Flag, MulTrk_ON
1368 jz BLOCK_FLOPPY
1369;SB34DISK002*****************************************************************
1370 call DISK ;J.K.
1371 xor ax,ax
1372 RET ;J.K.
1373BLOCK_FLOPPY: ;J.K.4/10/86
1374;
1375; READ AT MOST 1 TRACK WORTH. PERFORM MINIMIZATION AT SECTOR / TRACK
1376;
1377 MOV CL,BYTE PTR [DI].SECLIM
1378 INC CL
1379 SUB CL,CS:CURSEC ; LEEAC 3.20 ADD SEGMENT OVERRIDE
1380 XOR CH,CH
1381 CMP AX,CX
1382 JAE GOTMIN
1383 MOV CX,AX
1384GOTMIN:
1385;
1386; AX IS THE REQUESTED NUMBER OF SECTORS TO READ
1387; CX IS THE NUMBER THAT WE CAN DO ON THIS TRACK
1388;
1389 PUSH AX
1390 PUSH CX
1391 MOV AX,CX ; AL IS NUMBER OF SECTORS TO READ
1392 CALL DISK
1393 POP CX
1394 POP AX
1395;
1396; CX IS THE NUMBER OF SECTORS JUST TRANSFERRED
1397;
1398 SUB AX,CX ; REDUCE SECTORS-REMAINING BY LAST I/O
1399 SHL CL,1
1400 ADD BH,CL ; ADJUST TRANSFER ADDRESS
1401 JMP BLOCK
1402IOSETUP ENDP
1403
1404DskErr_Brdg: jmp DskErr ;AN003;
1405
1406;
1407;PERFORM DISK I/O WITH RETRIES
1408; AL = NUMBER OF SECTORS (1-8, ALL ON ONE TRACK)
1409; DI POINT TO DRIVE PARAMETERS
1410; ES:BX = TRANSFER ADDRESS (MUST NOT CROSS A 64K PHYSICAL BOUNDARY)
1411; [RFLAG] = 2 IF READ, 3 IF WRITE
1412; [VERIFY] = 0 FOR NORMAL, 1 FOR VERIFY AFTER WRITE
1413
1414 PUBLIC DISK
1415DISK PROC NEAR
1416 MOV BP,MAXERR ; SET UP RETRY COUNT
1417 mov cs:VRetry_Cnt, BP ;AN003;Verify op. retry cnt for Write-Verify.
1418 mov cs:Soft_ECC_Cnt, BP ;AN003;Soft ECC error retry count.
1419 MOV AH,CS:RFLAG ;GET READ/WRITE INDICATOR
1420
1421RETRY:
1422 PUSH AX
1423
1424 MOV DX,CS:[CURTRK] ;LOAD CURRENT CYLINDER
1425
1426 test word ptr [di].FLAGS, fNon_Removable ;Fixed disk? - J.K. 4/7/86
1427 jz DISK_NOT_MINI ;no, skip this. - J.K. 4/7/86
1428 cmp [di].IsMini, 1 ;Is this a mini disk? - J.K. 4/7/86
1429 jnz DISK_NOT_MINI ;No. continue to next.- J.K. 4/7/86
1430 add dx, [di].Hidden_Trks ;else add hidden trks.- J.K. 4/7/86
1431DISK_NOT_MINI: ;J.K. 4/7/86
1432 ROR DH,1
1433 ROR DH,1
1434
1435 OR DH,CS:[CURSEC]
1436 MOV CX,DX
1437 XCHG CH,CL ; CL = SECTOR, CH = CYLINDER
1438 MOV DH,BYTE PTR CS:[CURHD] ; LOAD CURRENT HEAD NUMBER AND
1439 MOV DL,BYTE PTR [DI].DRIVENUM ; PHYSICAL DRIVE NUMBER
1440 CMP BYTE PTR [DI].FORMFACTOR,FFHARDFILE
1441 JZ DO_FAST ; HARD FILES USE FAST SPEED
1442; IF WE HAVE [STEP_DRV] SET TO -1, WE USE THE SLOW SETTLE TIME.
1443; THIS HELPS WHEN WE HAVE JUST DONE A RESED DISK OPERATION AND THE HEAD HAS
1444; BEEN MOVED TO ANOTHER CYLINDER - THE PROBLEM CROPS UP WITH 3.5" DRIVES.
1445 CMP CS:[STEP_DRV],-1
1446 JZ DO_WRITEJ
1447 CMP AH,ROMREAD ; ARR 2.20
1448 JE DO_FAST
1449 CMP AH, ROMVERIFY
1450 JE DO_FAST
1451DO_WRITEJ:
1452; READS ALWAYS FAST, UNLESS WE HAVE JUST DONE A DISK RESET OPERATION
1453 JMP DO_WRITE ; ARR 2.20 READS ALWAYS FAST
1454DO_FAST: ; ARR 2.20
1455 CALL FASTSPEED ; MZ 2.21 CHANGE SETTLE MODE
1456TESTERR: ; MZ 2.21
1457 JC DSKERR_brdg
1458; SET DRIVE AND TRACK OF LAST ACCESS
1459 MOV CS:[STEP_DRV],DL ; ARR 2.20 SET DRIVE
1460 MOV BYTE PTR [DI].TRACK,CH ; ARR 2.20 SAVE TRACK
1461NO_SET:
1462 CMP CS:WRTVERIFY,103H ; CHECK FOR WRITE AND VERIFY
1463 JZ DOVERIFY
1464NOVERIFY:
1465 POP AX
1466
1467;SB34DISK003*****************************************************************
1468;SB Check the flags word in the BDS to see if the drive is non removable
1469;SB If not we needn't do anything special
1470;SB If it is a hard disk then check to see if multi-track operation
1471;SB is specified. If specified we don't have to calculate for the next
1472;SB track since we are already done. So we can go to the exit of this
1473;SB routine. 5 LOCS
1474
1475 test word ptr [di].FLAGS, fNON_REMOVABLE
1476 jz ITS_REMOVABLE
1477 test CS:MulTrk_Flag, MulTrk_ON
1478 jnz DISK_RET
1479ITS_REMOVABLE:
1480;SB34DISK003*****************************************************************
1481 AND CL,03FH ; ELIMINATE CYLINDER BITS FROM SECTOR
1482 XOR AH,AH
1483 SUB CS:[SECCNT],AX ; REDUCE COUNT OF SECTORS TO GO
1484 ADD CL,AL ; NEXT SECTOR
1485 MOV CS:[CURSEC],CL
1486 CMP CL,BYTE PTR [DI].SECLIM ; SEE IF SECTOR/TRACK LIMIT REACHED
1487 JBE DISK_RET
1488NEXTTRACK:
1489 MOV CS:[CURSEC],1 ; START WITH FIRST SECTOR OF NEXT TRACK
1490 MOV DH,CS:[CURHD]
1491 INC DH
1492 CMP DH,BYTE PTR [DI].HDLIM
1493 JB NOXOR
1494 XOR DH,DH
1495 INC CS:[CURTRK] ;NEXT TRACK
1496NOXOR:
1497 MOV CS:[CURHD],DH
1498DISK_RET:
1499 CLC ; LEEAC
1500 RET
1501DISK ENDP
1502
1503
1504; THE REQUEST IS FOR WRITE. DETERMINE IF WE ARE TALKING ABOUT THE SAME
1505; TRACK AND DRIVE. IF SO, USE THE FAST SPEED.
1506
1507DO_WRITE PROC NEAR
1508 CMP DL,CS:[STEP_DRV] ; ARR 2.20
1509 JNZ DO_NORM ; WE HAVE CHANGED DRIVES
1510
1511 CMP CH,BYTE PTR [DI].TRACK ; ARR 2.20
1512 JZ DO_FAST ; WE ARE STILL ON THE SAME TRACK
1513
1514DO_NORM:
1515 CALL NORMSPEED
1516 JMP SHORT TESTERR ; MZ 2.21 TEST FOR ERROR
1517DO_WRITE ENDP
1518;
1519; WE HAVE A VERIFY REQUEST ALSO. GET STATE INFO AND GO VERIFY
1520;
1521
1522DOVERIFY PROC NEAR
1523 POP AX ; RESTORE SECTOR COUNT
1524 PUSH AX
1525 MOV AH,ROMVERIFY ; REQUEST VERIFY
1526 CALL FASTSPEED ; MZ 2.21 CHANGE SETTLE MODE
1527 JNC NOVERIFY
1528
1529;SB34DISK004**************************************************************
1530;SB check the error returned in AH to see if it is a SOFT ECC error.
1531;SB If it is not we needn't do anything special. If it is a SOFT
1532;SB ECC error then decrement the SOFT_ECC_CNT error retry count. If
1533;SB this retry count becomes 0 then we just ignore the error and go to
1534;SB No_verify but if we can still try then we call the routine to reset
1535;SB the disk and go to DSKerr1 to retry the operation. 6 LOCS
1536
1537 cmp ah,11h ;SOFT ECC error ?
1538 jnz Not_SoftECC_Err
1539 dec SOFT_ECC_CNT
1540 jz NoVerify ;no more retry
1541 call ResetDisk ;reset disk
1542 jmp DskErr1 ;retry
1543
1544;SB34DISK004**************************************************************
1545
1546Not_SoftECC_Err: ;AN003;Other error.
1547 call ResetDisk ;AN003;
1548 dec VRetry_Cnt ;AN003;
1549 jmp DskErr0 ;AN003;
1550DOVERIFY ENDP
1551;
1552; NEED TO SPECIAL CASE THE CHANGE-LINE ERROR AH=06H. IF WE GET THIS, WE
1553; NEED TO RETURN IT.
1554;
1555;----------------------------------------|
1556; WARNING: DO NOT CHANGE THE FOLLOWING. ;|
1557; IT GETS PATCHED IN MSINIT ;|
1558 PUBLIC DSKERR ;|
1559DSKERR PROC NEAR ;|
1560 CALL CHECKIO ;|
1561;---------------------------------------;|
1562
1563 cmp cs:MultiTrk_Format_Flag, 1 ;AN007;Multi trk format request?
1564 jne DoChkAgain ;AN007;
1565 mov bp, 1 ;AN007;No more retry.
1566 mov cs:MultiTrk_Format_Flag, 0 ;AN007;Clear the flag.
1567DoChkAgain: ;AN007;
1568 CALL AGAIN
1569DskErr0: ;AN003;
1570 JZ HARDERR
1571 test word ptr [di].FLAGS, fNon_Removable ;AN009;
1572 jnz Skip_TimeOut_Chk ;AN009;
1573 CMP AH,80H ;TIMEOUT?
1574 JZ HARDERR ;***
1575Skip_TimeOut_Chk: ;AN009;
1576 cmp ah, 0cch ;AN003;Write Fault error?
1577 jz Write_Fault_Err ;AN003; Then, don't retry.
1578 mov cs:Soft_ECC_Cnt, MAXERR ;AN003;Set Soft_ECC_Cnt back to MAXERR
1579DSKERR1:
1580 POP AX ;RESTORE SECTOR COUNT
1581 JMP RETRY
1582
1583Write_Fault_Err: ;AN003;
1584 mov bp, 1 ;AN003;Just retry only once for Write Fault error.
1585 jmp DskErr1 ;AN003;
1586
1587HARDERR:
1588 PUBLIC HARDERR
1589
1590 CALL MAPERROR
1591
1592HARDERR2: ; FOR ROUTINES THAT CALL MAPERROR THEMSELVES
1593 PUBLIC HARDERR2
1594
1595 MOV CS:[TIM_DRV],-1 ;FORCE A MEDIA CHECK THROUGH ROM
1596 MOV CX,CS:SECCNT ;GET COUNT OF SECTORS TO GO
1597 MOV SP,CS:[SPSAV] ;RECOVER ENTRY STACK POINTER
1598;
1599; SINCE WE ARE PERFORMING A NON-LOCAL GOTO, RESTORE THE DISK PARAMETERS
1600;
1601MEDBYT_OK:
1602 CALL DIDDLEBACK
1603 RET ;AND RETURN
1604DSKERR ENDP
1605
1606;
1607; CHANGE SETTLE VALUE FROM SETTLECURRENT TO WHATEVER IS APPROPRIATE
1608; NOTE THAT THIS ROUTINE IS NEVER CALLED FOR A FIXED DISK.
1609;
1610NORMSPEED PROC NEAR
1611 cmp cs:[Media_Set_For_Format], 0 ;AN012;
1612 jne FASTSPEED ;AN012;
1613 PUSH DS
1614 PUSH AX
1615 MOV AL,CS:SETTLESLOW
1616 LDS SI,CS:DPT ; CURRENT DISK PARM TABLE
1617 MOV [SI].DISK_HEAD_STTL,AL
1618 POP AX
1619 POP DS
1620 CALL FASTSPEED
1621 PUSH DS
1622 LDS SI,CS:DPT
1623 MOV [SI].DISK_HEAD_STTL,1 ; 1 IS FAST SETTLE VALUE
1624 POP DS
1625 RET
1626NORMSPEED ENDP
1627
1628FASTSPEED PROC NEAR
1629;
1630; IF THE DRIVE HAS BEEN MARKED AS TOO BIG (I.E. STARTING SECTOR OF THE
1631; PARTITION IS > 16 BITS, THEN ALWAYS RETURN DRIVE NOT READY.
1632;
1633 TEST BYTE PTR [DI].FATSIZ,FTOOBIG
1634 IF iTEST
1635 JZ READY
1636 JMP NOTREADY
1637READY:
1638 ELSE
1639 JNZ NOTREADY
1640 ENDIF
1641
1642 MESSAGE FTESTINIT,<"<">
1643 MNUM FTESTINIT,AX
1644 MESSAGE FTESTINIT,<",">
1645 MNUM FTESTINIT,ES
1646 MESSAGE FTESTINIT,<":">
1647 MNUM FTESTINIT
1648 MESSAGE FTESTINIT,<",">
1649 MNUM FTESTINIT,CX
1650 MESSAGE FTESTINIT,<",">
1651 MNUM FTESTINIT,DX
1652 MESSAGE FTESTINIT,<">">
1653 INT 13H
1654DEATH:
1655 RET
1656NOTREADY:
1657 STC
1658 MOV AH,80H
1659 JMP DEATH
1660FASTSPEED ENDP
1661
1662; MAP ERROR RETURNED BY ROM IN AH INTO CORRESPONDING CODE TO BE RETURNED TO
1663; DOS IN AL.
1664;
1665MAPERROR PROC NEAR
1666 PUBLIC MAPERROR
1667
1668 PUSH CX ; SAVE CX
1669 PUSH CS
1670 POP ES ;MAKE ES THE LOCAL SEGMENT
1671 MOV AL,AH ;PUT ERROR CODE IN AL
1672 MOV CS:[LSTERR],AL ;TERMINATE LIST WITH ERROR CODE
1673 MOV CX,NUMERR ;NUMBER OF POSSIBLE ERROR CONDITIONS
1674 MOV DI,OFFSET ERRIN ;POINT TO ERROR CONDITIONS
1675 REPNE SCASB
1676 MOV AL,CS:[DI + NUMERR - 1] ;GET TRANSLATION
1677 POP CX ; RESTORE CX
1678 STC ;FLAG ERROR CONDITION
1679 RET
1680MAPERROR ENDP
1681
1682; SET THE TIME OF LAST ACCESS FOR THIS DRIVE. THIS IS DONE ONLY FOR REMOVABLE
1683; MEDIA.
1684
1685 PUBLIC SET_TIM
1686SET_TIM PROC NEAR
1687 PUSH AX
1688;SB33018******************************************************************
1689 xor AH, AH ; set command to get time ;SB;3.30*
1690 int 1Ah ; call rom-bios timer function ;SB;3.30*
1691;SB33018******************************************************************
1692 OR AL,AL
1693 JZ NOROLL3
1694 INC CS:[DAYCNT] ; CATCH ROLLOVER
1695NOROLL3:
1696; WE HAVE THE NEW TIME. IF WE SEE THAT THE TIME HAS PASSED, THEN WE RESET
1697; THE THRESHOLD COUNTER...
1698 CMP DX,WORD PTR [DI].TIM_LO
1699 JNZ SETACCESS
1700 CMP CX,WORD PTR [DI].TIM_HI
1701 JZ DONE_SET
1702SETACCESS:
1703 MOV BYTE PTR CS:[ACCESSCOUNT],0
1704 MOV WORD PTR [DI].TIM_LO,DX ;SAVE IT
1705 MOV WORD PTR [DI].TIM_HI,CX
1706DONE_SET:
1707 CLC
1708 POP AX
1709 RET
1710SET_TIM ENDP
1711
1712 ASSUME CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING
1713
1714;
1715; THIS IS THE TRUE INT 13 HANDLER. WE PARSE THE REQUEST TO SEE IF THERE IS
1716; A DMA VIOLATION. IF SO, DEPENDING ON THE FUNCTION, WE:
1717; READ/WRITE BREAK THE REQUEST INTO THREE PIECES AND MOVE THE MIDDLE ONE
1718; INTO OUR INTERNAL BUFFER.
1719; FORMAT COPY THE FORMAT TABLE INTO THE BUFFER
1720; VERIFY POINT THE TRANSFER ADDRESS INTO THE BUFFER
1721;
1722; THIS IS THE BIGGEST BOGOSITY OF ALL. THE IBM CONTROLLER DOES NOT HANDLE
1723; OPERATIONS THAT CROSS PHYSICAL 64K BOUNDARIES. IN THESE CASES, WE COPY
1724; THE OFFENDING SECTOR INTO THE BUFFER BELOW AND DO THE I/O FROM THERE.
1725;
1726INT13FRAME STRUC
1727OLDBP DW ?
1728OLDAX DW ?
1729OLDBX DW ?
1730OLDCX DW ?
1731OLDDX DW ?
1732OLDDD DD ?
1733OLDF DW ?
1734INT13FRAME ENDS
1735
1736;J.K. 1/30/87 To handle the ps2_30 machine INT 13h, AH = 8 Problem.
1737;Save Registers here.
1738Save_AX DW ?
1739Save_BX DW ?
1740Save_CX DW ?
1741Save_DX DW ?
1742Save_DI DW ?
1743Save_SI DW ?
1744Save_BP DW ?
1745Save_DS DW ?
1746Save_ES DW ?
1747Prev_DX DW ?
1748Save_Flag DW ?
1749
1750
1751; ENTRY CONDITIONS:
1752; AH = FUNCTION
1753; AL = NUMBER OF SECTORS
1754; ES:BX = DMA ADDRESS
1755; CX = PACKED TRACK AND SECTOR
1756; DX = HEAD AND DRIVE
1757; OUTPUT CONDITIONS:
1758; NO DMA VIOLATION.
1759;
1760 PUBLIC BLOCK13
1761BLOCK13 PROC FAR
1762;
1763; LET THE OPPERATION PROCEED. IF THERE IS A DMA VIOLATION, THEN WE DO THINGS.
1764;
1765 MOV CS:PREVOPER,AX ; SAVE REQUEST
1766 PUSHF
1767 CMP AH,ROMFORMAT
1768 JNZ NOT_FORMAT
1769; SET CHANGED BY FORMAT BIT FOR ALL LOGICAL DRIVES USING THIS PHYSICAL DRIVE
1770;---------------------------------------------------------|
1771; WARNING: DO NOT CHANGE THE FOLLOWING.
1772; IT GETS PATCHED IN AT INIT TIME |
1773 PUBLIC CHANGED_PATCH
1774CHANGED_PATCH:
1775 MOV WORD PTR CS:[FLAGBITS],FCHANGED_BY_FORMAT+FCHANGED
1776 CALL SET_CHANGED_DL ; INDICATE THAT MEDIA CHANGED BY FORMAT
1777; |
1778;---------------------------------------------------------|
1779NOT_FORMAT:
1780 test dl, 80h ; floppy or hard disk?
1781 jnz not_floppy ; if hard, skip this nonsense
1782 cmp cs:EC35_Flag, 0 ; any electrically compat. drives?
1783 jz not_floppy ; no; proceed unhindered
1784 SAVEREG <ax, bx, cx>
1785 mov cl, dl ; turn drive number into bit map:
1786 mov al, 1 ; assume drive 0
1787 shl al, cl ; shift over correct number of times
1788 test al, cs:EC35_Flag ; is THIS drive an electrically compatible 3.5 incher?
1789 jz not_EC35 ; no; don't change anything
1790 mov bl, dl ; which drive was it?
1791 xor bh, bh ; need only one byte of index
1792 push es ; need a segment register
1793 mov ax, 40h ; the machine state byte is in the...
1794 mov es, ax ; ...segment at 40h
1795 mov byte ptr es:[90h+bx], 93H ; establish drive type as: (360k disk in 360k drive, no double-stepping, 250 kbs transfer rate)
1796 pop es ; fix up register again
1797not_EC35:
1798 RESTOREREG <cx, bx, ax>
1799not_floppy:
1800 cmp cs:[model_byte], mdl_ps2_30 ; is this a ps2/30?
1801 jne not_ps2_30 ; if not, just do normal call
1802 cmp ah, 8 ;J.K. 1/30/87 Read Driver Parm ?
1803 je ps2_30_Problem ;J.K. 1/30/87
1804 cmp ah, 15h
1805 je ps2_30_Problem
1806not_ps2_30:
1807 CALL ORIG13 ; SIMULATE INT 13
1808 JC GOTERR13_br ; ERROR?
1809 RET 2 ; NO, RETURN AND CLEAR FLAGS
1810
1811GOTERR13_br: jmp Goterr13
1812
1813;J.K.1/30/87 ps2_30 machine has some problem with AH=8h(Read Drive Parm), Int 13h.
1814;This function does not reset the common buses after the execution.
1815;To solve this problem, when we detect AH=8h, then we will save the result and
1816;will issue AH=1 (Read Status) call to reset the buses.
1817
1818ps2_30_Problem: ;J.K. 1/30/87; ps2_30 = PS2 Model 30.
1819 mov cs:Prev_DX, DX ;save orignal drive number
1820 call Orig13 ;Do "Read drive parm"
1821
1822 mov cs:Save_AX, AX ;Save registers,flag
1823 mov cs:Save_BX, BX
1824 mov cs:Save_CX, CX
1825 mov cs:Save_DX, DX
1826 mov cs:Save_DI, DI
1827 mov cs:Save_SI, SI
1828 mov cs:Save_BP, BP
1829 mov cs:Save_DS, DS
1830 mov cs:Save_ES, ES
1831 pushf
1832 pop cs:Save_Flag
1833
1834 mov dx, cs:Prev_DX ;restore orignal drive
1835 pushf
1836 mov ah, 1 ;Read Status.
1837 call Orig13 ;Reset the bus as a side effect of this call.
1838
1839 mov AX, cs:Save_AX ;restore registers,flag
1840 mov BX, cs:Save_BX
1841 mov CX, cs:Save_CX
1842 mov DX, cs:Save_DX
1843 mov DI, cs:Save_DI
1844 mov SI, cs:Save_SI
1845 mov BP, cs:Save_BP
1846 mov DS, cs:Save_DS
1847 mov ES, cs:Save_ES
1848 push cs:Save_Flag
1849 popf
1850 jc GotErr13 ;AH=8 had been an error?
1851 ret 2
1852
1853;
1854; SOME KIND OF ERROR OCCURRED. SEE IF IT IS DMA VIOLATION
1855;
1856GOTERR13:
1857 PUSHF
1858 cmp ah, 09h ;AN011; DMA error?
1859 je Chk_ValidMedia_ERR13 ;AN011;
1860 cmp ah, 11h ;AN011; ECC error?
1861 je Chk_ValidMedia_ERR13 ;AN011;
1862 jmp Skip_Ecc_Check ;AN011; Other error. Just return back.
1863
1864Chk_ValidMedia_ERR13: ;AN011;If SetDrive fails, then just
1865 push ds ;AN011; return back to INT 13h caller,
1866 push di ;AN011; without performing ECC, DMA
1867 push ax ;AN011; error handling.
1868 mov byte ptr cs:[Phys_Drv], 1 ;AN011;
1869 mov al, dl ;AN011;
1870 call SetDrive ;AN011;
1871 mov byte ptr cs:[Phys_Drv], 0 ;AN011;
1872 pop ax ;AN011;
1873 pop di ;AN011;
1874 pop ds ;AN011;
1875 jc Skip_Ecc_Check ;AN011;
1876
1877; TEST OF BIT PATTERN 08H LET OTHER ERRORS BE PASSED AS DMA ERRORS - PTR 32D0519
1878; TEST AH,08H ; DMA BIT
1879 CMP AH, 09H ; DMA ERROR CODE
1880 JNZ CHECK_ECC
1881 JMP GOTDMAERR
1882CHECK_ECC:
1883;J.K. AN003; Soft ECC bug is only applied to PC1 and PC-XT. So, we will enforce
1884;this ECC error handler for them. Also, since CMC hardfiles in PC AT also
1885;generate a lot of unnecessary ECC errors, we will still cover PC ATs as
1886;it is done in the earlier version of MSBIO.
1887;During Format/Verify operation, we are going to consider any Soft Ecc as a
1888;hard error.
1889
1890;SB34DISK005*****************************************************************
1891;SB See if the machine we are operating on is a PC, XT or AT by checking
1892;SB the model byte. The soft ECC bug is only on these machines and if
1893;SB the machine we are operating on is not one of these three then we
1894;SB needn't do anything special. If we are operating one these however
1895;SB we check to see if the error occured during format by checking
1896;SB media_set_for_format. If it did occur during format we cannot do
1897;SB anything but if not during format then check to see if the error
1898;SB returned in AH is the SOFT_ECC error and if so go to OK11 since
1899;SB the error can be ignored. 6 LOCS
1900
1901 cmp cs:[Media_Set_For_Format], 1 ; formatting?
1902 je Skip_Ecc_Check
1903 cmp cs:[Model_Byte], 0FEh ; PC or XT?
1904 jae Go_Chk_Ecc
1905 cmp cs:[Model_Byte], 0FBh ; XT?
1906 je Go_Chk_Ecc
1907 cmp cs:[Model_Byte], 0FCh
1908 jne Skip_Ecc_Check
1909 cmp cs:[Secondary_Model_Byte], 2 ; AT?
1910 ja Skip_Ecc_Check
1911Go_Chk_Ecc: ; for PC, XT, AT
1912 CMP AH,11H
1913 JZ OK11
1914Skip_Ecc_Check: ;AN003; Just return back to INT 13h caller.
1915
1916;SB34DISK005*****************************************************************
1917
1918 POPF
1919 RET 2
1920;
1921; WE HAVE AN ERROR STATUS 11H. THIS INDICATES AN ECC-CORRECTED ERROR. NOTE
1922; THAT THIS INDICATES THAT THE DATA IS PROBABLY CORRECT BUT NOT CERTAINLY
1923; CORRECT. THE ROMS ON PC-1S AND PC_XTS HAVE A 'BUG' IN THAT IF AN ECC ERROR
1924; OCCURS FOR A MULTI-SECTOR READ, ONLY THE SECTORS UP TO THE ONE WHERE THE
1925; ERROR OCCURRED ARE READ IN. WE HAVE NO WAY OF KNOWING HOW MANY WERE READ IN
1926; THIS CASE, SO WE REDO THE OPERATION, READING ONE SECTOR AT A TIME. IF WE
1927; GET AN ECC ERROR ON READING ONE SECTOR, WE IGNORE THE ERROR BECAUSE THE
1928; SECTOR HAS BEEN READ IN.
1929;
1930 PUBLIC OK11
1931OK11:
1932; POPF
1933;J.K. 8/29/86 Here, it is better reset the system. So, we are going to
1934;call Orig13 again
1935
1936 xor ah, ah
1937 call Orig13 ;reset. Don't care about the result
1938
1939 MOV AX,CS:[PREVOPER] ; RETRIEVE REQUEST
1940;
1941; THIS WILL PROVIDE A TERMINATION POINT.
1942;
1943 CMP AL,1 ; IF REQUEST FOR ONE SECTOR, ASSUME OK
1944 JNZ ECC_ERR_HANDLE
1945 XOR AH,AH ; CLEAR CARRY TOO!
1946 RET 2
1947
1948 PUBLIC ECC_ERR_HANDLE
1949ECC_ERR_HANDLE:
1950 SAVEREG <BX,CX,DX>
1951 MOV CS:[NUMBER_OF_SEC],AL
1952LOOP_ECC:
1953 MOV AX,CS:[PREVOPER]
1954 MOV AL,1 ; REQUEST FOR ONE SECTOR ONLY
1955;
1956; WE DO READS ONE SECTOR AT A TIME. THIS ENSURES THAT WE WILL EVENTUALLY
1957; FINISH THE REQUEST SINCE ECC ERRORS ON ONE SECTOR DO READ IN THAT SECTOR.
1958;
1959; WE NEED TO PUT IN SOME "INTELLIGENCE" INTO THE ECC HANDLER TO HANDLE READS
1960; THAT ATTEMPT TO READ MORE SECTORS THAN ARE AVAILABLE ON A PARTICULAR
1961; TRACK.
1962; WE CALL CHECK_WRAP TO SET UP THE SECTOR #, HEAD # AND CYLINDER # FOR
1963; THIS REQUEST.
1964; AT THIS POINT, ALL REGISTERS ARE SET UP FOR THE CALL TO ORIG13, EXCEPT
1965; THAT THERE MAY BE A STARTING SECTOR NUMBER THAT IS BIGGER THAN THE NUMBER
1966; OF SECTORS ON A TRACK.
1967;
1968 CALL CHECK_WRAP ; GET CORRECT PARAMETERS FOR INT 13
1969 PUSHF
1970 CALL ORIG13
1971 JNC OK11_OP
1972 CMP AH,11H ; ONLY ALLOW ECC ERRORS
1973 JNZ OK11_EXIT_err ;J.K. 8/26/86 Other error?
1974 mov ah, 0 ;J.K. ECC error. Reset the system again.
1975 pushf
1976 call Orig13
1977 xor ax, ax ; clear the error code so that if this
1978 ; was the last sector, no error code
1979 ; will be returned for the corrected
1980 ; read. (clear carry too.)
1981OK11_OP:
1982 DEC CS:[NUMBER_OF_SEC]
1983 JZ OK11_EXIT ; ALL DONE?
1984 INC CL ; ADVANCE SECTOR NUMBER
1985 INC BH ; ADD 200H TO ADDRESS
1986 INC BH
1987 JMP SHORT LOOP_ECC
1988OK11_EXIT_err:
1989 stc ;J.K. 8/28/86 Set carry bit again.
1990OK11_EXIT:
1991 RESTOREREG <DX,CX,BX>
1992 RET 2
1993;
1994; WE TRULY HAVE A DMA VIOLATION. RESTORE REGISTER AX AND RETRY THE
1995; OPERATION AS BEST WE CAN.
1996;
1997GOTDMAERR:
1998 POP AX ; CLEAN UP STACK
1999 MOV AX,CS:PREVOPER
2000 STI
2001 CMP AH,ROMREAD ; SAVE USER FLAGS
2002 JB INTDONE
2003 CMP AH,ROMVERIFY
2004 JZ INTVERIFY
2005 CMP AH,ROMFORMAT
2006 JZ INTFORMAT
2007 JA INTDONE
2008;
2009; WE ARE DOING A READ/WRITE CALL. CHECK FOR DMA PROBLEMS
2010;
2011 SAVEREG <DX,CX,BX,AX>
2012 PUSH BP
2013 MOV BP,SP
2014 MOV DX,ES ; CHECK FOR 64K BOUNDARY ERROR
2015
2016 SHL DX,1
2017 SHL DX,1
2018 SHL DX,1
2019 SHL DX,1 ; SEGMENT CONVERTED TO ABSOLUTE ADDRESS
2020
2021 ADD DX,BX ; COMBINE WITH OFFSET
2022 ADD DX,511 ; SIMULATE A TRANSFER
2023;
2024; IF CARRY IS SET, THEN WE ARE WITHIN 512 BYTES OF THE END OF THE SEGMENT.
2025; WE SKIP THE FIRST TRANSFER AND PERFORM THE REMAINING BUFFERING AND TRANSFER
2026;
2027 JNC NO_SKIP_FIRST
2028 MOV DH,BYTE PTR [BP.OLDDX+1] ; SET UP HEAD NUMBER
2029 JMP BUFFER ;J.K. 4/10/86
2030; JMP SHORT BUFFER
2031;
2032; DX IS THE PHYSICAL 16 BITS OF START OF TRANSFER. COMPUTE REMAINING
2033; SECTORS IN SEGMENT.
2034;
2035NO_SKIP_FIRST:
2036 SHR DH,1 ; DH = NUMBER OF SECTORS BEFORE ADDRESS
2037 MOV AH,128 ; AH = MAX NUMBER OF SECTORS IN SEGMENT
2038 SUB AH,DH
2039;
2040; AH IS NOW THE NUMBER OF SECTORS THAT WE CAN SUCCESSFULLY WRITE IN THIS
2041; SEGMENT. IF THIS NUMBER IS ABOVE OR EQUAL TO THE REQUESTED NUMBER, THEN WE
2042; CONTINUE THE OPERATION AS NORMAL. OTHERWISE, WE BREAK IT INTO PIECES.
2043;
2044 CMP AH,AL ; CAN WE FIT IT IN?
2045 JB DOBLOCK ; NO, PERFORM BLOCKING.
2046;
2047; YES, THE REQUEST FITS. LET IT HAPPEN
2048;
2049 MOV DH,BYTE PTR [BP.OLDDX+1] ; SET UP HEAD NUMBER
2050 CALL DOINT
2051 JMP BAD13
2052;
2053; VERIFY THE GIVEN SECTORS. PLACE THE BUFFER POINTER INTO OUR SPACE.
2054;
2055INTVERIFY:
2056 SAVEREG <ES,BX>
2057 PUSH CS
2058 POP ES
2059DOSIMPLE:
2060 MOV BX,OFFSET DISKSECTOR
2061 PUSHF
2062 CALL ORIG13
2063 RESTOREREG <BX,ES>
2064 RET 2
2065
2066;
2067; FORMAT OPERATION. COPY THE PARAMETER TABLE INTO MEMORY
2068;
2069INTFORMAT:
2070 SAVEREG <ES,BX>
2071 SAVEREG <SI,DI,DS>
2072 PUSH ES
2073 PUSH CS
2074 POP ES
2075 POP DS
2076 MOV SI,BX
2077 MOV DI,OFFSET DISKSECTOR
2078 CALL MOVE
2079 RESTOREREG <DS,DI,SI>
2080 JMP DOSIMPLE
2081;
2082; INLINE CONTINUATION OF OPERATION
2083;
2084INTDONE:
2085 JMP ORIG13
2086
2087;
2088; We can't fit the request into the entire block. Perform the operation on
2089; the first block.
2090;
2091; DoBlock is modified to correctly handle multi-sector disk I/O. -J.K. 4/10/86
2092; Old DoBlock had added the number of sectors I/Oed (Ah in Old DoBlock) after
2093; the DoInt call to CL. Observing only the lower 6 bits of CL(=max. 64) can
2094; represent a starting sector, if AH was big, then CL would be clobbered.
2095; By the way, we still are going to use CL for this purpose since Checkwrap
2096; routine will use it as an input. To prevent CL from being clobbered, a
2097; safe number of sectors should be calculated like "63 - # of sectors/track".
2098; DoBlock will handle the first block of requested sectors within the
2099; boundary of this safe value. - J.K. 2/28/86
2100
2101DoBlock:
2102;Try to get the # of sectors/track from BDS via Rom drive number.
2103;For any mini disks installed, here we have to pray that they have the
2104;same # of sector/track as the main DOS partition disk drive.
2105
2106 Message ftestDisk,<"!!!DMA DoBlock!!!">
2107
2108 mov dx, word ptr [bp.olddx] ;set head #
2109 push di
2110 push ds
2111 push ax ;AH - # of sectors before DMA boundary
2112 ;AL - User requeseted # of sectors for I/O.
2113 mov byte ptr CS:[phys_drv],1
2114 mov al, dl
2115 call SetDrive ;get BDS pointer for this DISK.
2116 pop ax
2117 mov byte ptr CS:[phys_drv],0
2118 test word ptr [DI].Flags, fNon_Removable ;don't have to worry
2119 jnz DoBlockHard ;about floppies. They are track by track operation.
2120 mov al, ah ;set al = ah for floppies
2121 jmp short DoBlockCont
2122DoBlockHard:
2123 push cx
2124 xor cx, cx
2125 mov cx, [DI].SecLim ;# of sectors/track
2126 mov ch, 63
2127 sub ch, cl
2128 mov al, ch
2129 xchg ah, al ;now ah - safe # of sectors
2130 ;al - # of sectors before DMA boundary
2131 pop cx
2132DoBlockCont:
2133 pop ds
2134 pop di
2135DoBlockContinue:
2136 Message ftestDisk,<"%%DMA DoBlock Loop%%">
2137 cmp ah, al ;if safe_# >= #_of_sectors_to_go_before DMA,
2138 jae DoBlocklast ;then #_of_sectors_to_go as it is for DoInt.
2139 push ax ;save AH, AL
2140 mov al, ah ;Otherwise, set al to ah to operate.
2141 jmp short DoBlockDoInt ;DoInt will set AH to a proper function in [BP.Oldax]
2142DoBlocklast:
2143 mov ah, al
2144 push ax ;save AH
2145DoBlockDoInt: ;let AH = AL = # of sectors for this shot
2146 CALL DoInt
2147 JC BAD13 ;something happened, bye!
2148 pop ax
2149 SUB BYTE PTR [BP.oldax], AH ;decrement by the successful operation
2150 ADD CL,AH ;advance sector number. Safety gauranteed.
2151 ADD BH,AH ;advance DMA address
2152 ADD BH,AH ;twice for 512 byte sectors.
2153 cmp ah, al ;check the previous value
2154 je Buffer ;if #_of_sectors_to_go < safe_#, then we are done already.
2155 sub al, ah ;otherwise, #_sector_to_go = #_of_sector_to_go - safe_#
2156 call Check_Wrap ;get new CX, DH for the next operation.
2157 jmp short DoBlockContinue ;handles next sectors left.
2158;End of modificaion of DoBlock - J.K. 2/28/86
2159;The following is the original one.
2160; PUSH AX
2161; MOV AL,AH ; get max to operate on
2162; MOV AH,BYTE PTR [BP.oldax+1]; get function
2163; mov dh,byte ptr [BP.olddx+1] ; set up head number
2164; CALL DoInt
2165; JC Bad13 ; something happened, bye!
2166; POP AX
2167; SUB BYTE PTR [BP.oldax],AH ; decrement by the successful operation
2168; ADD CL,AH ; advance sector number
2169; ADD BH,AH ; advance DMA address
2170; ADD BH,AH ; twice for 512 byte sectors.
2171
2172;
2173; THE NEXT REQUEST WILL WRAP THE 64K BOUNDARY. IF WE ARE WRITING, THEN COPY
2174; THE OFFENDING SECTOR INTO OUR SPACE.
2175;
2176; ES:BX POINTS TO THE SECTOR
2177; CX,DX CONTAIN THE CORRECT TRACK/SECTOR/HEAD/DRIVE INFO
2178; [BP.OLDAX] HAS CORRECT FUNCTION CODE
2179;
2180BUFFER:
2181 PUSH BX
2182 MOV AH,BYTE PTR [BP.OLDAX+1]
2183 CMP AH,ROMWRITE
2184 JNZ DOREAD
2185;
2186; COPY THE OFFENDING SECTOR INTO LOCAL BUFFER
2187;
2188 SAVEREG <DS,ES,SI,DI>
2189 PUSH CS ; EXCHANGE SEGMENT REGISTERS
2190 PUSH ES
2191 POP DS
2192 POP ES
2193 MOV DI,OFFSET DISKSECTOR ; WHERE TO MOVE
2194 PUSH DI ; SAVE IT
2195 MOV SI,BX ; SOURCE
2196 CALL MOVE
2197 POP BX ; NEW TRANSFER ADDRESS
2198 RESTOREREG <DI,SI>
2199 MOV AL,1
2200; SEE IF WE ARE WRAPPING AROUND A TRACK OR HEAD
2201 MOV DL,BYTE PTR [BP.OLDDX] ; GET DRIVE NUMBER
2202 CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND
2203;
2204; AH IS FUNCTION
2205; AL IS 1 FOR SINGLE SECTOR TRANSFER
2206; ES:BX IS LOCAL TRANSFER ADDRES
2207; CX IS TRACK/SECTOR NUMBER
2208; DX IS HEAD/DRIVE NUMBER
2209; SI,DI UNCHANGED
2210;
2211 CALL DOINT
2212 RESTOREREG <ES,DS>
2213 JC BAD13 ; GO CLEAN UP
2214 JMP SHORT DOTAIL
2215;
2216; READING A SECTOR. DO INT FIRST, THEN MOVE THINGS AROUND
2217;
2218DOREAD:
2219 SAVEREG <ES,BX>
2220 PUSH CS
2221 POP ES
2222 MOV BX,OFFSET DISKSECTOR
2223 MOV AL,1
2224; SEE IF OUR REQUEST WILL WRAP A TRACK OR HEAD BOUNDARY
2225 MOV DL,BYTE PTR [BP.OLDDX] ; GET DRIVE NUMBER
2226 CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND
2227;
2228; AH = FUNCTION
2229; AL = 1 FOR SINGLE SECTOR
2230; ES:BX POINTS TO LOCAL BUFFER
2231; CX, DX ARE TRACK/SECTOR, HEAD/DRIVE
2232;
2233 CALL DOINT
2234 RESTOREREG <BX,ES>
2235 JC BAD13 ; ERROR => CLEAN UP
2236 SAVEREG <DS,SI,DI>
2237 PUSH CS
2238 POP DS
2239 MOV DI,BX
2240 MOV SI,OFFSET DISKSECTOR
2241 CALL MOVE
2242 RESTOREREG <DI,SI,DS>
2243;
2244; NOTE THE FACT THAT WE'VE DONE 1 MORE SECTOR
2245;
2246DOTAIL:
2247 POP BX ; RETRIEVE NEW DMA AREA
2248 ADD BH,2 ; ADVANCE OVER SECTOR
2249 INC CX
2250 MOV AL,BYTE PTR [BP.OLDAX]
2251 CLC
2252 DEC AL
2253 JZ BAD13 ; NO MORE I/O
2254; SEE IF WE WRAP AROUND A TRACK OR HEAD BOUNDARY WITH STARTING SECTOR
2255; WE ALREADY HAVE THE CORRECT HEAD NUMBER TO PASS TO CHECK_WRAP
2256 MOV DL,BYTE PTR [BP.OLDDX] ; GET DRIVE NUMBER
2257 CALL CHECK_WRAP ; SETS UP REGISTERS IF WRAP-AROUND
2258 CALL DOINT
2259;
2260; WE ARE DONE. AX HAS THE FINAL CODE; WE THROW AWAY WHAT WE GOT BEFORE
2261;
2262BAD13:
2263 MOV SP,BP
2264 RESTOREREG <BP,BX,BX,CX,DX>
2265 RET 2
2266BLOCK13 ENDP
2267 PAGE
2268 INCLUDE MSIOCTL.INC
2269 PAGE
2270; CHECK_WRAP IS A ROUTINE THAT ADJUSTS THE STARTING SECTOR, STARTING HEAD
2271; AND STARTING CYLINDER FOR AN INT 13 REQUEST THAT REQUESTS I/O OF A LOT
2272; OF SECTORS. IT ONLY DOES THIS FOR FIXED DISKS. IT IS USED IN THE SECTIONS
2273; OF CODE THAT HANDLE ECC ERRORS AND DMA ERRORS. IT IS NECESSARY, BECAUSE
2274; ORDINARILY THE ROM WOULD TAKE CARE OF WRAPS AROUND HEADS AND CYLINDERS,
2275; BUT WE BREAK DOWN A REQUEST WHEN WE GET AN ECC OR DMA ERROR INTO SEVERAL
2276; I/O OF ONE OR MORE SECTORS. IN THIS CASE, WE MAY ALREADY BE BEYOND THE
2277; NUMBER OF SECTORS ON A TRACK ON THE MEDIUM, AND THE REQUEST WOULD FAIL.
2278;
2279; INPUT CONDITIONS:
2280; ALL REGISTERS SET UP FOR AN INT 13 REQUEST.
2281;
2282; OUTPUT:
2283; DH - CONTAINS STARTING HEAD NUMBER FOR REQUEST
2284; CX - CONTAINS STARTING SECTOR AND CYLINDER NUMBERS
2285; (THE ABOVE MAY OR MAY NOT HAVE BEEN CHANGED, AND ARE 0-BASED)
2286; ALL OTHER REGISTERS PRESERVED.
2287;
2288 PUBLIC CHECK_WRAP
2289CHECK_WRAP:
2290 Message ftestDisk,<"Entering Check_Wrap...",cr,lf>
2291 SAVEREG <AX,BX,DS,DI>
2292 MOV BYTE PTR CS:[PHYS_DRV],1; USE PHYSICAL DRIVE IN AL TO GET BDS
2293 MOV AL,DL ; AL HAS PHYSICAL DRIVE NUMBER
2294 CALL SETDRIVE ; GET POINTER TO BDS FOR DRIVE
2295 MOV BYTE PTR CS:[PHYS_DRV],0; RESTORE FLAG TO USE LOGICAL DRIVE
2296 JC NO_WRAP ; DO NOTHING IF WRONG PHYSICAL DRIVE
2297 TEST WORD PTR [DI].FLAGS,FNON_REMOVABLE
2298 JZ NO_WRAP ; NO WRAPPING FOR REMOVABLE MEDIA
2299 MOV BX,[DI].SECLIM
2300 MOV AX,CX
2301 AND AX,003FH ; EXTRACT SECTOR NUMBER
2302 CMP AX,BX ; ARE WE GOING TO WRAP?
2303 JBE NO_WRAP
2304 DIV BL ; AH=NEW SECTOR #, AL=# OF HEAD WRAPS
2305; WE NEED TO BE CAREFUL HERE. IF THE NEW SECTOR # IS 0, THEN WE ARE ON THE
2306; LAST SECTOR ON THAT TRACK.
2307 OR AH,AH
2308 JNZ NOT_ON_BOUND
2309 MOV AH,BL ; SET SECTOR=SECLIM IF ON BOUNDARY
2310 DEC AL ; ALSO DECREMENT # OF HEAD WRAPS
2311NOT_ON_BOUND:
2312 AND CL,0C0H ; ZERO OUT SECTOR #
2313 OR CL,AH ; OR IN NEW SECTOR #
2314 XOR AH,AH ; AX = # OF HEAD WRAPS
2315 INC AX
2316 ADD AL,DH ; ADD IN STARTING HEAD #
2317 ADC AH,0 ; CATCH ANY CARRY
2318 CMP AX,[DI].HDLIM ; ARE WE GOING TO WRAP AROUND A HEAD?
2319 JBE NO_WRAP_HEAD ; DO NOT LOSE NEW HEAD NUMBER!!
2320 PUSH DX ; PRESERVE DRIVE NUMBER AND HEAD NUMBER
2321 XOR DX,DX
2322 MOV BX,[DI].HDLIM
2323 DIV BX ; DX=NEW HEAD #, AX=# OF CYLINDER WRAPS
2324; CAREFUL HERE! IF NEW HEAD # IS 0, THEN WE ARE ON THE LAST HEAD.
2325 OR DX,DX
2326 JNZ NO_HEAD_BOUND
2327 MOV DX,BX ; ON BOUNDARY. SET TO HDLIM
2328; IF WE HAD SOME CYLINDER WRAPS, WE NEED TO REDUCE THEM BY ONE!!
2329 OR AX,AX
2330 JZ NO_HEAD_BOUND
2331 DEC AX ; REDUCE NUMBER OF CYLINDER WRAPS
2332NO_HEAD_BOUND:
2333 MOV BH,DL ; BH HAS NEW HEAD NUMBER
2334 POP DX ; RESTORE DRIVE NUMBER AND HEAD NUMBER
2335 DEC BH ; GET IT 0-BASED
2336 MOV DH,BH ; SET UP NEW HEAD NUMBER IN DH
2337 MOV BH,CL
2338 AND BH,3FH ; PRESERVE SECTOR NUMBER
2339 MOV BL,6
2340 XCHG CL,BL
2341 SHR BL,CL ; GET MS CYLINDER BITS TO LS END
2342 ADD CH,AL ; ADD IN CYLINDER WRAP
2343 ADC BL,AH ; ADD IN HIGH BYTE
2344 SHL BL,CL ; MOVE UP TO MS END
2345 XCHG BL,CL ; RESTORE CYLINDER BITS INTO CL
2346 OR CL,BH ; OR IN SECTOR NUMBER
2347
2348NO_WRAP:
2349 CLC ; RESET CARRY
2350 RESTOREREG <DI,DS,BX,AX>
2351 RET
2352
2353NO_WRAP_HEAD:
2354 MOV DH,AL ; DO NOT LOSE NEW HEAD NUMBER
2355 DEC DH ; GET IT 0-BASED
2356 JMP SHORT NO_WRAP
2357
2358;
2359; INT_2F_13:
2360; THIS CODE IS CHAINED INTO THE INT_2F INTERRUPT DURING BIOS
2361; INITIALIZATION. IT ALLOWS THE USER TO CHANGE THE ORIG13 INT_13 VECTOR
2362; AFTER BOOTING. THIS ALLOWS TESTING AND IMPLEMENTATION OF CUSTOM INT_13
2363; HANDLERS, WITHOUT GIVING UP MS-DOS ERROR RECOVERY
2364;
2365; ENTRY CONDITIONS
2366; AH == RESET_INT_13 (13H)
2367; DS:DX == ADDRESS OF NEW INT_13 HANDLER
2368; ES:BX == ADDRESS OF NEW INT_13 VECTOR USED BY WARM BOOT
2369; (INT 19)
2370;
2371; EXIT CONDITIONS
2372; ORIG13 == ADDRESS OF NEW INT_13 HANDLER
2373; DS:DX == OLD ORIG13 VALUE
2374; ES:BX == OLD OLD13 VALUE
2375
2376 ASSUME CS:CODE,DS:NOTHING,ES:NOTHING,SS:NOTHING
2377
2378 PUBLIC INT_2F_13
2379INT_2F_13 PROC FAR
2380
2381 CMP AH,13H ; IF (INTERRUPT_VALUE != RESET_INT_13)
2382 JE CHG_ORIG13
2383 JMP CS:[NEXT2F_13] ; THEN CONTINUE ON INT_2F CHAIN
2384
2385CHG_ORIG13: ; ELSE
2386 PUSH WORD PTR CS:[ORIG13] ; SAVE OLD VALUE OF OLD13 AND
2387 PUSH WORD PTR CS:[ORIG13 + 2]; ORIG13 SO THAT WE CAN
2388
2389 PUSH WORD PTR CS:[OLD13] ; RETURN THEM TO CALLER
2390 PUSH WORD PTR CS:[OLD13 + 2]
2391
2392 MOV WORD PTR CS:[ORIG13],DX ; ORIG13 := ADDR. OF NEW INT_13
2393 ; VECTOR
2394 MOV WORD PTR CS:[ORIG13+2],DS
2395
2396 MOV WORD PTR CS:[OLD13],BX ; OLD13 := ADDR. OF NEW
2397 ; BOOT_13 VECTOR
2398 MOV WORD PTR CS:[OLD13+2],ES
2399
2400 POP ES ; ES:BX := OLD OLD13 VECTOR
2401 POP BX
2402
2403 POP DS ; DS:DX := OLD ORIG13 VECTOR
2404 POP DX
2405
2406 IRET ; END ELSE
2407
2408INT_2F_13 ENDP
2409
2410MOVE PROC NEAR
2411 CLD
2412 PUSH CX
2413 MOV CX,512/2
2414;J.K. Warning!!! Do not change the position of this label.
2415; The following three bytes will be NOPed out by MSINIT if the system
2416; does not support the DOUBLE WORD MOV instruction, i.e., (if
2417; not 386 base machine.)
2418;----------------------------------------------------------------------------
2419 public DoubleWordMov
2420DoubleWordMov: ;AN002;
2421 shr cx, 1 ;AN002;Make it a double word.
2422 db 66h ;AN002;Machine code for double word mov
2423;----------------------------------------------------------------------------
2424 REP MOVSW
2425 POP CX
2426 RET
2427MOVE ENDP
2428
2429DOINT PROC NEAR
2430 MOV DL,BYTE PTR [BP.OLDDX] ; GET PHYSICAL DRIVE NUMBER
2431 XOR AH,AH
2432 OR AL,AL
2433 JZ DOINTDONE
2434 MOV AH,BYTE PTR [BP.OLDAX+1] ; GET REQUEST CODE
2435 PUSH [BP.OLDF]
2436 CALL ORIG13
2437 PUSHF
2438 POP [BP.OLDF]
2439DOINTDONE:
2440 RET
2441DOINT ENDP
2442CODE ENDS
2443 END
diff --git a/v4.0/src/BIOS/MSDSKPR.INC b/v4.0/src/BIOS/MSDSKPR.INC
new file mode 100644
index 0000000..6b24bff
--- /dev/null
+++ b/v4.0/src/BIOS/MSDSKPR.INC
@@ -0,0 +1,22 @@
1; The following structure defines the disk parameter table
2; pointed to by Interrupt vector 1EH (location 0:78H)
3
4DISK_PARMS STRUC
5DISK_SPECIFY_1 DB ?
6DISK_SPECIFY_2 DB ?
7DISK_MOTOR_WAIT DB ? ; Wait till motor off
8DISK_SECTOR_SIZ DB ? ; Bytes/Sector (2 = 512)
9DISK_EOT DB ? ; Sectors per track (MAX)
10DISK_RW_GAP DB ? ; Read Write Gap
11DISK_DTL DB ?
12DISK_FORMT_GAP DB ? ; Format Gap Length
13DISK_FILL DB ? ; Format Fill Byte
14DISK_HEAD_STTL DB ? ; Head Settle Time (MSec)
15DISK_MOTOR_STRT DB ? ; Motor start delay
16DISK_PARMS ENDS
17
18ROMStatus equ 1
19ROMRead equ 2
20ROMWrite equ 3
21ROMVerify equ 4
22ROMFormat equ 5
diff --git a/v4.0/src/BIOS/MSEQU.INC b/v4.0/src/BIOS/MSEQU.INC
new file mode 100644
index 0000000..d45577b
--- /dev/null
+++ b/v4.0/src/BIOS/MSEQU.INC
@@ -0,0 +1,76 @@
1%OUT MSEQU.INC...
2;==============================================================================
3
4FTOOBIG EQU 80H
5FBIG EQU 40H
6ROMSTATUS EQU 1
7ROMREAD EQU 2
8ROMWRITE EQU 3
9ROMVERIFY EQU 4
10ROMFORMAT EQU 5
11VID_SIZE EQU 12
12
13INCLUDE MSBDS.INC ; VARIOUS EQUATES FOR BDS
14
15;AN000; Extended BPB structure.
16BPB_TYPE STRUC
17SECSIZE DW ?
18SECALL DB ?
19RESNUM DW ?
20FATNUM DB ?
21DIRNUM DW ?
22SECNUM DW ?
23FATID DB ?
24FATSIZE DW ?
25SLIM DW ?
26HLIM DW ?
27HIDDEN_L DW ?
28HIDDEN_H dw 0 ;J.K.
29SECNUM_L dw 0 ;J.K.
30SECNUM_H dw 0 ;J.K.
31BPB_TYPE ENDS
32
33;;;;;;;;;;;
34BOOT_SERIAL_SIZE equ 4 ;J.K.
35BOOT_VOLUME_LABEL_SIZE equ 11 ;J.K.
36BOOT_SYSTEM_ID_SIZE equ 8 ;J.K.
37EXT_BOOT_SIGNATURE equ 41 ;J.K.
38RSINIT=0A3H ;RS232 INITIALIZATION
39 ;9600 BAUD:NO PARITY:1 STOP:8 BIT WORD
40LF=10 ;LINE FEED
41CR=13 ;CARRIAGE RETURN
42BACKSP=8 ;BACKSPACE
43BRKADR=1BH * 4 ;006C 1BH BREAK VECTOR ADDRESS
44TIMADR=1CH * 4 ;0070 1CH TIMER INTERRUPT
45DSKADR=1EH * 4 ;ADDRESS OF PTR TO DISK PARAMETERS
46SEC9=522H ;ADDRESS OF DISK PARAMETERS
47HEADSETTLE=SEC9+9 ; ARR 2.20 ADDRESS OF HEAD SETTLE TIME
48NORMSETTLE=15 ; ARR 2.20 NORMAL HEAD SETTLE
49SPEEDSETTLE=0 ; ARR 2.20 SPEED UP SETTLE TIME
50INITSPOT=534H ; ARR IBM WANTS 4 ZEROS HERE
51AKPORT=20H
52EOI=20H
53CMDLEN = 0 ;LENGTH OF THIS COMMAND
54UNIT = 1 ;SUB UNIT SPECIFIER
55CMD = 2 ;COMMAND CODE
56STATUS = 3 ;STATUS
57MEDIA = 13 ;MEDIA DESCRIPTOR
58TRANS = 14 ;TRANSFER ADDRESS
59COUNT = 18 ;COUNT OF BLOCKS OR CHARACTERS
60START = 20 ;FIRST BLOCK TO TRANSFER
61EXTRA = 22 ;USUALLY A POINTER TO VOL ID FOR ERROR 15
62CHROUT = 29H
63MAXERR = 5
64LSTDRV = 504H
65
66BOOTBIAS = 200H
67NOTBUSYSTATUS = 10000000B ; NOT BUSY
68ACKSTATUS = 01000000B ; ACKNOWLEDGE (FOR WHAT?)
69NOPAPERSTATUS = 00100000B ; NO MORE PAPER
70SELECTEDSTATUS = 00010000B ; THE PRINTER SAID IT WAS SELECTED
71IOERRSTATUS = 00001000B ; SOME KINDA ERROR
72RESERVED = 00000110B ; NOPS
73TIMEOUTSTATUS = 00000001B ; TIME OUT.
74ERROR_UNKNOWN_MEDIA = 7 ; FOR USE IN BUILD BPB CALL
75
76PATHGEN = 1
diff --git a/v4.0/src/BIOS/MSEXTRN.INC b/v4.0/src/BIOS/MSEXTRN.INC
new file mode 100644
index 0000000..b72d879
--- /dev/null
+++ b/v4.0/src/BIOS/MSEXTRN.INC
@@ -0,0 +1,97 @@
1; SCCSID = @(#)IBMEXTRN.ASM 1.11 85/11/18
2;This is for IBMINIT module.
3;=======================================================
4;REVISION HISTORY:
5;AN000; - NEW Version 4.00. J.K.
6;AC000; - Modified Line 4.00. J.K.
7;ANxxx; - PTMyyy
8;==============================================================================
9;AN001; D486 SHARE installation for large media 2/23/88 J.K.
10;==============================================================================
11
12 EXTRN ORIG13:DWORD,ORIG19:DWORD
13 EXTRN COM2DEV:WORD,COM1DEV:WORD
14 EXTRN COM4DEV:WORD,COM3DEV:WORD
15 EXTRN LPT3DEV:WORD,LPT2DEV:WORD,LPT1DEV:WORD
16 EXTRN HARDDRV:BYTE,HARDNUM:BYTE,DRVMAX:BYTE,HDSKTAB:WORD
17 EXTRN DSKDRVS:WORD,HNUM:BYTE,EOT:BYTE,FHAVE96:BYTE
18 EXTRN REAL13:DWORD,DAYCNT:WORD,CONHEADER:WORD
19 EXTRN TWOHARD:BYTE,INT_2F_NEXT:DWORD
20 EXTRN BDSH:WORD,BDSX:WORD,START_BDS:DWORD
21 EXTRN FHAVEK09:BYTE, NEW_ROM:BYTE
22 EXTRN SINGLE:BYTE
23 EXTRN BDSMs:BYTE ;for Mini Disk -J.K. 4/7/86
24 EXTRN HaveCMOSClock:byte ;set by IBMINIT. Used by IBMCLOCK.ASM
25 EXTRN BinToBCD:word ;set by IBMINIT. Used by IBMCLOCK.ASM
26 EXTRN DaycntToDay:word ;set by IBMINIT. Used by IBMCLOCK.ASM
27 EXTRN OLD13:DWORD
28 extrn Temp_H:word ;J.K. For 32 bit calculation. IBMDISK
29 extrn Start_Sec_H:word ;J.K. IBMDISK.
30 extrn KEYRD_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA.
31 extrn KEYSTS_Func:byte ;J.K. For IBMCON. Defined in IBMBDATA.
32 extrn DiskSector:byte ;J.K. IBMBDATA
33 extrn Bpb_In_Sector:word ;J.K. IBMBDATA
34 extrn SecPerCLusInSector:Byte ;J.K. IBMBDATA
35 extrn NumberOfFats:byte ;J.K. IBMBDATA
36 extrn MediaByte:byte ;J.K. IBMBDATA
37 extrn Ext_Boot_Sig:Byte ;J.K. IBMBDATA
38 extrn Boot_Serial_L:Word ;J.K. IBMBDATA
39 extrn Boot_Serial_H:Word ;J.K. IBMBDATA
40 extrn Boot_Volume_Label:Byte ;J.K. IBMBDATA
41 extrn Boot_System_ID:Byte ;J.K. IBMBDATA
42 extrn Fat_12_ID:Byte ;J.K. IBMDISK
43 extrn Fat_16_ID:Byte ;J.K. IBMDISK
44 extrn Vol_No_Name:Byte ;J.K. IBMDISK
45 extrn MotorStartup:Byte ;J.K. IBMBDATA
46 extrn DoubleWordMov:Byte ;J.K. IBMDISK
47 extrn Model_Byte:Byte ;J.K. IBMBIO2
48 extrn Secondary_Model_Byte:Byte ;J.K. IBMBIO2
49
50 IF iTEST
51 IFNDEF NUMBUF
52 EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD
53 ENDIF
54 ENDIF
55
56 EXTRN START$:NEAR,ERROUT:NEAR,BLOCK13:FAR,INT19:FAR
57 EXTRN INTRET:NEAR,HDRIVE:NEAR,DRIVEX:NEAR,INT13:FAR,CBREAK:NEAR,OUTCHR:NEAR
58 EXTRN DISKRD:NEAR,MEDIA_PATCH:NEAR,GETBP1_PATCH:NEAR
59 EXTRN SET_PATCH:NEAR,DISKIO_PATCH:NEAR,DSKERR:NEAR,INIT_PATCH:NEAR
60 EXTRN TABLE_PATCH:NEAR,EXIT:NEAR,CHANGED_PATCH:NEAR
61 EXTRN ERRIN:NEAR,GETBP:NEAR,SWPDSK:NEAR
62 EXTRN OUTCHR:NEAR,WRMSG:NEAR,TIME_TO_TICKS:NEAR
63 EXTRN INT2F_DISK:NEAR,INSTALL_BDS:NEAR,SETDRIVE:NEAR
64 extrn Mov_Media_IDs:Near ;J.K.
65 extrn Clear_IDs:Near ;J.K.
66 IF iTEST
67 IFNDEF NUMBUF
68 EXTRN MSGNUM:NEAR,MSGOUT:NEAR,dumpbytes:near,hex_to_ascii:near
69 EXTRN outchar:near
70 ENDIF
71 ENDIF
72
73SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
74 ASSUME CS:SYSINITSEG
75 EXTRN CURRENT_DOS_LOCATION:WORD
76 EXTRN FINAL_DOS_LOCATION:WORD
77 EXTRN DEVICE_LIST:DWORD
78 EXTRN MEMORY_SIZE:WORD
79 EXTRN DEFAULT_DRIVE:BYTE
80 EXTRN BUFFERS:WORD
81 EXTRN SYSINIT:FAR
82 extrn Big_Media_Flag:Byte ;AN001;
83SYSINITSEG ENDS
84
85 ASSUME CS:CODE
86
87; END OF DISK MODULES FOR CONFIGURATION
88
89 EXTRN END96TPI:BYTE
90 EXTRN ENDTWOHARD:BYTE
91 EXTRN ENDONEHARD:BYTE
92 EXTRN ENDSWAP:BYTE
93 EXTRN ENDFLOPPY:BYTE
94
95; IBM FIXED UP AT ROM
96
97 EXTRN IBM_DISK_IO:FAR
diff --git a/v4.0/src/BIOS/MSGROUP.INC b/v4.0/src/BIOS/MSGROUP.INC
new file mode 100644
index 0000000..ac6202d
--- /dev/null
+++ b/v4.0/src/BIOS/MSGROUP.INC
@@ -0,0 +1,46 @@
1EVBOUND = 1 ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1 ;3.30
2 ; ALIGNS TO EVEN ;3.30
3; : : : : : : : : : : : : : : ;3.30
4 IF EVBOUND ;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED, ;3.30
5; : : : : : : : : : : : : : : ;3.30
6EVENB MACRO ;3.30
7 EVEN ;;ADJUST TO EVEN BOUNDARY ;3.30
8 ENDM ;3.30
9 ;3.30
10ODD MACRO ;3.30
11;;GENERATE BOUNDARY PADDING TO FORCE ODD OFFSET ;3.30
12 IF (($-CODE) MOD 2) EQ 0 ;3.30
13 DB ? ;3.30
14 ENDIF ;3.30
15 ENDM ;3.30
16 ;3.30
17CODE_SEGMENT MACRO ;3.30
18;;ALLIGN THE SEGMENT ON WORD BOUNDARY TO ALLOW FOR EVEN ALLIGNMENT OF DATA;3.30
19CODE SEGMENT WORD PUBLIC 'CODE' ;3.30 ;3.30
20 ENDM ;3.30
21 ;3.30
22; : : : : : : : : : : : : : : ;3.30
23 ELSE ;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT
24; : : : : : : : : : : : : : : ;3.30
25 ;3.30
26EVENB MACRO ;3.30
27;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING ;3.30
28 ENDM ;3.30
29 ;3.30
30ODD MACRO ;3.30
31;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING ;3.30
32 ENDM ;3.30
33 ;3.30
34CODE_SEGMENT MACRO ;3.30
35;;SEGMENT IS ALLIGNED ON BYTE BOUNDARY FOR MINIMUM SIZE OF GENERATION ;3.30
36CODE SEGMENT BYTE PUBLIC 'CODE' ;3.30
37 ENDM ;3.30
38 ;3.30
39; : : : : : : : : : : : : : : ;3.30
40 ENDIF ;3.30
41; : : : : : : : : : : : : : : ;3.30
42 ;3.30
43 CODE_SEGMENT ;3.30
44 ASSUME CS:CODE ;3.30
45 ;3.30
46 \ No newline at end of file
diff --git a/v4.0/src/BIOS/MSHARD.ASM b/v4.0/src/BIOS/MSHARD.ASM
new file mode 100644
index 0000000..51c0dc8
--- /dev/null
+++ b/v4.0/src/BIOS/MSHARD.ASM
@@ -0,0 +1,427 @@
1;***
2; Title: Disk
3; C: (C) Copyright 1988 by Microsoft corp.
4; Date: 1/11/85
5;
6; There is a bug in some versions of IBM's AT ROM BIOS.
7; Interrupts are not disabled during read operations.
8;
9; Use: This program should be chained in line with the disk
10; interupt 13h, it intercepts read calls to the hard disk
11; and handles them appropriately. For other functions it
12; passes controll to OLD13, which should contain the
13; address of the AT ROM disk routine. The entry point for
14; this program is IBM_DISK_IO.
15;
16
17
18 .286c ;Use 80286 non-protected mode
19
20BIOSEG = 040h ;Segment for ROM BIOS Data
21ROMSEG = 0F000h ;Segment of ROM
22
23
24BAD_DISK = 01
25
26HF_PORT = 01F0h
27HF_REG_PORT = 03F6h
28
29;* Offsets into Fixed disk parameter table
30FDP_PRECOMP = 5
31FDP_CONTROL = 8
32
33DATA SEGMENT AT BIOSEG ;ROM BIOS data segment
34
35 ORG 42h
36CMD_BLOCK DB 6 DUP (?)
37
38;* Offsets into CMD_BLOCK for registers
39PRE_COMP = 0 ;Write Pre-compensation
40SEC_CNT = 1 ;Sector count
41SEC_NUM = 2 ;Sector number
42CYL_LOW = 3 ;Cylinder number, low part
43CYL_HIGH = 4 ;Cylinder number, high part
44DRV_HEAD = 5 ;Drive/Head (Bit 7 = ECC mode, Bit 5 = 512 byte sectors,
45 ; Bit 4 = drive number, Bits 3-0 have head number)
46CMD_REG = 6 ;Command register
47
48
49 ORG 074h
50
51DISK_STATUS1 DB ?
52HF_NUM DB ?
53CONTROL_BYTE DB ?
54
55DATA ENDS
56
57
58
59;*** Define where the ROM routines are actually located
60ROM SEGMENT AT ROMSEG
61
62 ORG 02E1Eh
63ROMCOMMAND PROC FAR
64ROMCOMMAND ENDP
65
66 ORG 02E7Fh
67ROMWAIT PROC FAR
68ROMWAIT ENDP
69
70 ORG 02EE2h
71ROMWAIT_DRQ PROC FAR
72ROMWAIT_DRQ ENDP
73
74 ORG 02EF8h
75ROMCHECK_STATUS PROC FAR
76ROMCHECK_STATUS ENDP
77
78 ORG 02F69h
79ROMCHECK_DMA PROC FAR
80ROMCHECK_DMA ENDP
81
82 ORG 02F8Eh
83ROMGET_VEC PROC FAR
84ROMGET_VEC ENDP
85
86 ORG 0FF65h
87ROMFRET PROC FAR ;Far return at F000:FF65 in AT ROM.
88ROMFRET ENDP
89
90ROM ENDS
91
92
93CODE SEGMENT BYTE PUBLIC 'code'
94
95EXTRN OLD13:DWORD ;Link to AT bios int 13h
96
97PUBLIC IBM_DISK_IO
98
99
100 ASSUME CS:CODE
101 ASSUME DS:DATA
102
103
104;*** IBM_DISK_IO - main routine, fixes AT ROM bug
105;
106; ENTRY: (AH) = function, 02 or 0A for read.
107; (DL) = drive number (80h or 81h).
108; (DH) = head number.
109; (CH) = cylinder number.
110; (CL) = Sector number (high 2 bits has cylinder number).
111; (AL) = number of sectors.
112; (ES:BX) = address of read buffer.
113; For more on register contents see ROM BIOS listing.
114; Stack set up for return by an IRET.
115;
116; EXIT: (AH) = status of current operation.
117; (CY) = 1 IF failed, 0 if successful.
118; For other register contents see ROM BIOS listing.
119;
120; USES:
121;
122;
123; WARNING: Uses OLD13 vector for non-read calls.
124; Does direct calls to the AT ROM.
125; Does segment arithmatic.
126;
127; EFFECTS: Performs DISK I/O operation.
128;
129IBM_DISK_IO PROC FAR
130 CMP DL, 80h
131 JB ATD1 ;Pass through floppy disk calls.
132 CMP AH, 02
133 JE ATD2 ;Intercept call 02 (read sectors).
134 CMP AH, 0Ah
135 JE ATD2 ;and call 0Ah (read long).
136ATD1:
137 JMP OLD13 ;Use ROM INT 13h handler.
138ATD2:
139 PUSH BX
140 PUSH CX
141 PUSH DX
142 PUSH DI
143 PUSH DS
144 PUSH ES
145 PUSH AX
146 MOV AX,BIOSEG ;Establish BIOS segment addressing.
147 MOV DS,AX
148 MOV DISK_STATUS1, 0 ;Initially no error code.
149 AND DL, 07fh ;Mask to hard disk number
150 CMP DL, HF_NUM
151 JB ATD3 ;Disk number in range
152 MOV DISK_STATUS1, BAD_DISK
153 JMP SHORT ATD4 ;Disk number out of range error, return
154
155ATD3:
156 PUSH BX
157 MOV AX, ES ;Make ES:BX to Seg:000x form.
158 SHR BX, 4
159 ADD AX, BX
160 MOV ES, AX
161 POP BX
162 AND BX,000Fh
163 PUSH CS
164 CALL CHECK_DMA
165 JC ATD4 ;Abort if DMA across segment boundary
166
167 POP AX ;Restore AX register for SETCMD
168 PUSH AX
169 CALL SETCMD ;Set up command block for disk op
170 MOV DX, HF_REG_PORT
171 OUT DX, AL ;Write out command modifier
172 CALL DOCMD ;Carry out command
173ATD4:
174;; Old code - Carry cleared after set by logical or opearation
175;; POP AX
176;; MOV AH,DISK_STATUS1 ;On return AH has error code
177;; STC
178;; OR AH,AH
179;; JNZ ATD5 ;Carry set if error
180;; CLC
181;;---------------------------------------------------
182;; New Code - Let Logical or clear carry and then set carry if ah!=0
183;; And save a couple bytes while were at it.
184 POP AX
185 MOV AH,DISK_STATUS1 ;On return AH has error code
186 OR AH,AH
187 JZ ATD5 ;Carry set if error
188 STC
189
190ATD5:
191 POP ES
192 POP DS
193 POP DI
194 POP DX
195 POP CX
196 POP BX
197 RET 2 ;Far return, dropping flags
198IBM_DISK_IO ENDP
199
200
201
202;*** SETCMD - Set up CMD_BLOCK for the disk operation
203;
204; ENTRY: (DS) = BIOS Data segment.
205; (ES:BX) in seg:000x form.
206; Other registers as in INT 13h call
207;
208; EXIT: CMD_BLOCK set up for disk read call.
209; CONTROL_BYTE set up for disk operation.
210; (AL) = Control byte modifier
211;
212;
213; Sets the fields of CMD_BLOCK using the register contents
214; and the contents of the disk parameter block for the given drive.
215;
216; WARNING: (AX) destroyed.
217; Does direct calls to the AT ROM.
218;
219SETCMD PROC NEAR
220 MOV CMD_BLOCK[SEC_CNT], AL
221 MOV CMD_BLOCK[CMD_REG], 020h ;Assume function 02
222 CMP AH, 2
223 JE SETC1 ;CMD_REG = 20h if function 02 (read)
224 MOV CMD_BLOCK[CMD_REG], 022h ;CMD_REG = 22h if function 0A (" long)
225SETC1: ;No longer need value in AX
226 MOV AL, CL
227 AND AL, 03fh ;Mask to sector number
228 MOV CMD_BLOCK[SEC_NUM], AL
229 MOV CMD_BLOCK[CYL_LOW], CH
230 MOV AL, CL
231 SHR AL, 6 ;Get two high bits of cylender number
232 MOV CMD_BLOCK[CYL_HIGH], AL
233 MOV AX, DX
234 SHL AL, 4 ;Drive number
235 AND AH, 0Fh
236 OR AL, AH ;Head number
237 OR AL, 0A0h ;Set ECC and 512 bytes per sector
238 MOV CMD_BLOCK[DRV_HEAD], AL
239 PUSH ES ;GET_VEC destroys ES:BX
240 PUSH BX
241 PUSH CS
242 CALL GET_VEC
243 MOV AX, ES:FDP_PRECOMP[BX] ;Write pre-comp from disk parameters
244 SHR AX, 2
245 MOV CMD_BLOCK[PRE_COMP],AL ;Only use low part
246 MOV AL, ES:FDP_CONTROL[BX] ;Control byte modifier
247 POP BX
248 POP ES
249 MOV AH, CONTROL_BYTE
250 AND AH, 0C0h ;Keep disable retry bits
251 OR AH, AL
252 MOV CONTROL_BYTE, AH
253 RET
254SETCMD ENDP
255
256
257
258;*** DOCMD - Carry out READ operation to AT hard disk
259;
260; ENTRY: (ES:BX) = address for read in data.
261; CMD_BLOCK set up for disk read.
262;
263; EXIT: Buffer at (ES:BX) contains data read.
264; DISK_STATUS1 set to error code (0 if success).
265;
266;
267;
268; WARNING: (AX), (BL), (CX), (DX), (DI) destroyed.
269; No check is made for DMA boundary overrun.
270;
271; EFFECTS: Programs disk controller.
272; Performs disk input.
273;
274DOCMD PROC NEAR
275 MOV DI, BX ;(ES:DI) = data buffer addr.
276 PUSH CS
277 CALL COMMAND
278 JNZ DOC3
279DOC1:
280 PUSH CS
281 CALL WAITT ;Wait for controller to complete read
282 JNZ DOC3
283 MOV CX, 100h ;256 words per sector
284 MOV DX, HF_PORT
285 CLD ;String op goes up
286 CLI ;Disable interrupts (BUG WAS FORGETTING THIS)
287 REPZ INSW ;Read in sector
288 STI
289 TEST CMD_BLOCK[CMD_REG], 02
290 JZ DOC2 ;No ECC bytes to read.
291 PUSH CS
292 CALL WAIT_DRQ
293 JC DOC3
294 MOV CX, 4 ;4 bytes of ECC
295 MOV DX, HF_PORT
296 CLI
297 REPZ INSB ;Read in ECC
298 STI
299DOC2:
300 PUSH CS
301 CALL CHECK_STATUS
302 JNZ DOC3 ;Operation failed
303 DEC CMD_BLOCK[SEC_CNT]
304 JNZ DOC1 ;Loop while more sectors to read
305DOC3:
306 RET
307DOCMD ENDP
308
309
310
311;*** GET_VEC - Get pointer to hard disk parameters.
312;
313; ENTRY: (DL) = Low bit has hard disk number (0 or 1).
314;
315; EXIT: (ES:BX) = address of disk parameters table.
316;
317; USES: AX for segment computation.
318;
319; Loads ES:BX from interrupt table in low memory, vector 46h (disk 0)
320; or 70h (disk 1).
321;
322; WARNING: (AX) destroyed.
323; This does a direct call to the AT ROM.
324;
325GET_VEC PROC NEAR
326 PUSH OFFSET ROMFRET
327 JMP ROMGET_VEC
328GET_VEC ENDP
329
330
331
332;*** COMMAND - Send contents of CMD_BLOCK to disk controller.
333;
334; ENTRY: Control_byte
335; CMD_BLOCK - set up with values for hard disk controller.
336;
337; EXIT: DISK_STATUS1 = Error code.
338; NZ if error, ZR for no error.
339;
340;
341; WARNING: (AX), (CX), (DX) destroyed.
342; Does a direct call to the AT ROM.
343;
344; EFFECTS: Programs disk controller.
345;
346COMMAND PROC NEAR
347 PUSH OFFSET ROMFRET
348 JMP ROMCOMMAND
349COMMAND ENDP
350
351
352
353;*** WAITT - Wait for disk interrupt
354;
355; ENTRY: Nothing.
356;
357; EXIT: DISK_STATUS1 = Error code.
358; NZ if error, ZR if no error.
359;
360;
361; WARNING: (AX), (BL), (CX) destroyed.
362; Does a direct call to the AT ROM.
363;
364; EFFECTS: Calls int 15h, function 9000h.
365;
366WAITT PROC NEAR
367 PUSH OFFSET ROMFRET
368 JMP ROMWAIT
369WAITT ENDP
370
371
372
373;*** WAIT_DRQ - Wait for data request.
374;
375; ENTRY: Nothing.
376;
377; EXIT: DISK_STATUS1 = Error code.
378; CY if error, NC if no error.
379;
380;
381; WARNING: (AL), (CX), (DX) destroyed.
382; Does a direct call to the AT ROM.
383;
384WAIT_DRQ PROC NEAR
385 PUSH OFFSET ROMFRET
386 JMP ROMWAIT_DRQ
387WAIT_DRQ ENDP
388
389
390
391;*** CHECK_STATUS - Check hard disk status.
392;
393; ENTRY: Nothing.
394;
395; EXIT: DISK_STATUS1 = Error code.
396; NZ if error, ZR if no error.
397;
398;
399; WARNING: (AX), (CX), (DX) destroyed.
400; Does a direct call to the AT ROM.
401;
402CHECK_STATUS PROC NEAR
403 PUSH OFFSET ROMFRET
404 JMP ROMCHECK_STATUS
405CHECK_STATUS ENDP
406
407
408
409;*** CHECK_DMA - check for DMA overrun 64k segment.
410;
411; ENTRY: (ES:BX) = addr. of memory buffer in seg:000x form.
412; CMD_BLOCK set up for operation.
413;
414; EXIT: DISK_STATUS1 - Error code.
415; CY if error, NC if no error.
416;
417;
418; WARNING: Does a direct call to the AT ROM.
419;
420CHECK_DMA PROC NEAR
421 PUSH OFFSET ROMFRET
422 JMP ROMCHECK_DMA
423CHECK_DMA ENDP
424
425
426CODE ENDS
427 END
diff --git a/v4.0/src/BIOS/MSINIT.ASM b/v4.0/src/BIOS/MSINIT.ASM
new file mode 100644
index 0000000..d00c8af
--- /dev/null
+++ b/v4.0/src/BIOS/MSINIT.ASM
@@ -0,0 +1,2819 @@
1 PAGE ,132 ;
2 %OUT ...MSINIT.ASM
3;=======================================================
4;REVISION HISTORY:
5;AN000; - NEW Version 4.00. J.K.
6;AC000; - Modified Line 4.00. J.K.
7;ANxxx; - PTMyyy
8;==============================================================================
9;AN001; P87 Set the value of MOTOR START TIME Variable 6/25/87 J.K.
10;AN002; P40 Boot from the system with no floppy diskette drives 6/26/87 J.K.
11;AN003; D9 Double Word MOV instruction for 386 based machine 7/1/87 J.K.
12;AN004; D64 Extend DOS 3.3 FAT tables to 64 K entries. 7/8/87 J.K.
13;AN005; D113 Disable I/O access to unformatted media 9/03/87 J.K.
14;AN006; p941 D113 does not implemented properly. 9/11/87 J.K.
15;AN007; p969 Should Honor OS2 boot record. 9/11/87 J.K.
16;AN008; p985 Allow I/O access to unformtted media 9/14/87 J.K.
17;AN009; p1535 Disallow I/O access to unformtted media 10/15/87 J.K.
18;AN010; p2349 Cover DOS 3.3 and below FDISK bug 11/10/87 J.K.
19;AN011; P2431 OS2 boot record version number is at offset 7 (not 8)11/12/87 J.K.
20;AN012; P2900 DOS 4.0 does not recognize 3.0 formatted media 12/18/87 J.K.
21;AN013; P3409 Extended keyboard not recognized 02/05/88 J.K.
22;AN014; D486 Share installation for big media 02/23/88 J.K.
23;AN015; P3929 Boot record buffer overlaps MSBIO code 03/18/88 J.K.
24;==============================================================================
25
26 itest = 0
27 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
28 INCLUDE MSDSKPR.INC
29 INCLUDE MSEQU.INC
30 INCLUDE MSMACRO.INC
31 INCLUDE MSEXTRN.INC
32 INCLUDE BIOSTRUC.INC
33 INCLUDE CMOSEQU.INC
34 include cputype.inc
35
36; THE FOLLOWING LABEL DEFINES THE END OF THE AT ROM PATCH. THIS IS USED AT
37; CONFIGURATION TIME.
38;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT.
39
40 PUBLIC ENDATROM ;NOT REFERENCES EXTERNALLY, BUT
41 ; JUST TO CAUSE ENTRY IN LINK MAP
42ENDATROM LABEL BYTE
43
44;CMOS Clock setting support routines used by MSCLOCK.
45;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT.
46
47 EXTRN base_century:byte
48 EXTRN base_year:byte
49 EXTRN month_tab:byte
50
51 public Daycnt_to_day ;J.K. 4/30/86 for real time clock support
52Daycnt_to_day proc near ;J.K. 4/30/86 for real time clock support
53;Entry: [DAYCNT] = number of days since 1-1-80
54;Return: CH - centry in BCD, CL - year in BCD, DH - month in BCD, DL - day in BCD
55
56 push [daycnt] ;save daycnt
57 cmp daycnt, (365*20+(20/4)) ;# of days from 1-1-1980 to 1-1-2000
58 jae century20
59 mov base_century, 19
60 mov base_year, 80
61 jmp years
62century20: ;20th century
63 mov base_century, 20
64 mov base_year, 0
65 sub daycnt, (365*20+(20/4)) ;adjust daycnt
66years:
67 xor dx, dx
68 mov ax, daycnt
69 mov bx, (366+365*3) ;# of days in a Leap year block
70 div bx ;AX = # of leap block, DX = daycnt
71 mov daycnt, dx ;save daycnt left
72; or ah, ah ;ax should be less than 256
73; jz OK1
74; jmp Erroroccur
75;OK1:
76 mov bl,4
77 mul bl ;AX = # of years. Less than 100 years!
78 add base_year, al ;So, ah = 0. Adjust year accordingly.
79 inc daycnt ;set daycnt to 1 base
80 cmp daycnt, 366 ;the daycnt here is the remainder of the leap year block.
81 jbe Leapyear ;So, it should within 366+355+355+355 days.
82 inc base_year ;First if daycnt <= 366, then leap year
83 sub daycnt, 366 ;else daycnt--, base_year++;
84 ;And the next three years are regular years.
85 mov cx, 3
86Regularyear:
87 cmp daycnt, 365 ;for(i=1; i>3 or daycnt <=365;i++)
88 jbe YearDone ;{if (daycnt > 365)
89 inc base_year ; { daycnt -= 365
90 sub daycnt, 365 ; }
91 loop regularyear ;}
92; jmp Erroroccur ;cannot come to here
93Leapyear:
94 mov byte ptr month_tab+1,29 ;leap year. change the month table.
95Yeardone:
96 xor bx,bx
97 xor dx,dx
98 mov ax, daycnt
99 mov si, offset month_tab
100 mov cx, 12
101Months:
102 inc bl ;
103 mov dl, byte ptr ds:[si] ;compare daycnt for each month until fits
104 cmp ax, dx ;dh=0.
105 jbe Month_done
106 inc si ;next month
107 sub ax, dx ;adjust daycnt
108 loop Months
109; jmp Erroroccur
110Month_done:
111 mov byte ptr month_tab+1, 28 ;restore month table value
112 mov dl, bl
113 mov dh, base_year
114 mov cl, base_century ;now, al=day, dl=month,dh=year,cl=century
115 call word ptr BinToBCD ;Oh my!!! To save 15 bytes, Bin_To_BCD proc
116 ;was relocated seperately from Daycnt_to_Day proc.
117; call Bin_to_bcd ;convert "day" to bcd
118 xchg dl, al ;dl = bcd day, al = month
119 call word ptr BinToBCD
120; call Bin_to_bcd
121 xchg dh, al ;dh = bcd month, al = year
122 call word ptr BinToBCD
123; call Bin_to_bcd
124 xchg cl, al ;cl = bcd year, al = century
125 call word ptr BinToBCD
126; call Bin_to_bcd
127 mov ch, al ;ch = bcd century
128 pop [daycnt] ;restore original value
129 ret
130Daycnt_to_day endp
131
132 public EndDaycntToDay
133EndDaycntToDay label byte
134
135 public Bin_to_bcd
136Bin_to_bcd proc near ;J.K. 4/30/86 for real time clock support
137;Convert a binary input in AL (less than 63h or 99 decimal)
138;into a bcd value in AL. AH destroyed.
139 push cx
140 xor ah, ah
141 mov cl, 10
142 div cl ;al - high digit for bcd, ah - low digit for bcd
143 mov cl, 4
144 shl al, cl ;mov the high digit to high nibble
145 or al, ah
146 pop cx
147 ret
148Bin_to_bcd endp
149
150 Public EndCMOSClockset ;End of supporting routines for CMOS clock setting.
151EndCMOSClockset label byte
152;
153
154 EXTRN INT6C_RET_ADDR:DWORD ; RETURN ADDRESS FROM INT 6C
155 EXTRN BIN_DATE_TIME:BYTE
156 EXTRN MONTH_TABLE:WORD
157 EXTRN DAYCNT2:WORD
158 EXTRN FEB29:BYTE
159 EXTRN TimeToTicks:Word ;indirect intra-segment call address
160
161 EVENB
162;
163; THE K09 REQUIRES THE ROUTINES FOR READING THE CLOCK BECAUSE OF THE SUSPEND/
164; RESUME FACILITY. THE SYSTEM CLOCK NEEDS TO BE RESET AFTER RESUME.
165;
166 ASSUME ES:NOTHING
167
168; THE FOLLOWING ROUTINE IS EXECUTED AT RESUME TIME WHEN THE SYSTEM
169; POWERED ON AFTER SUSPENSION. IT READS THE REAL TIME CLOCK AND
170; RESETS THE SYSTEM TIME AND DATE, AND THEN IRETS.
171
172;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT.
173
174INT6C PROC FAR
175 PUSH CS
176 POP DS
177
178 ASSUME DS:CODE
179
180 POP WORD PTR INT6C_RET_ADDR ; POP OFF RETURN ADDRESS
181 POP WORD PTR INT6C_RET_ADDR+2
182 POPF
183 CALL READ_REAL_DATE ; GET THE DATE FROM THE CLOCK
184 CLI
185 MOV DS:DAYCNT,SI ; UPDATE DOS COPY OF DATE
186 STI
187 CALL READ_REAL_TIME ; GET THE TIME FROM THE RTC
188 CLI
189;SB33019***************************************************************
190 MOV AH, 01h ; COMMAND TO SET THE TIME ;SB;3.30
191 INT 1Ah ; CALL ROM-BIOS TIME ROUTINE ;SB;3.30
192;SB33019***************************************************************
193 STI
194 JMP INT6C_RET_ADDR ; LONG JUMP
195
196INT6C ENDP
197
198
199 INCLUDE READCLOC.INC
200 INCLUDE CLOCKSUB.INC
201
202 PUBLIC ENDK09 ;NOT REFERENCES EXTERNALLY, BUT
203 ; JUST TO CAUSE ENTRY IN LINK MAP
204ENDK09 LABEL BYTE
205 ASSUME DS:NOTHING,ES:NOTHING
206
207;*********************************************************
208; SYSTEM INITIALIZATION
209;
210; THE ENTRY CONDITIONS ARE ESTABLISHED BY THE BOOTSTRAP
211; LOADER AND ARE CONSIDERED UNKNOWN. THE FOLLOWING JOBS
212; WILL BE PERFORMED BY THIS MODULE:
213;
214; 1. ALL DEVICE INITIALIZATION IS PERFORMED
215; 2. A LOCAL STACK IS SET UP AND DS:SI ARE SET
216; TO POINT TO AN INITIALIZATION TABLE. THEN
217; AN INTER-SEGMENT CALL IS MADE TO THE FIRST
218; BYTE OF THE DOS
219; 3. ONCE THE DOS RETURNS FROM THIS CALL THE DS
220; REGISTER HAS BEEN SET UP TO POINT TO THE START
221; OF FREE MEMORY. THE INITIALIZATION WILL THEN
222; LOAD THE COMMAND PROGRAM INTO THIS AREA
223; BEGINNING AT 100 HEX AND TRANSFER CONTROL TO
224; THIS PROGRAM.
225;
226;********************************************************
227
228;SYSIZE=200H ;NUMBER OF PARAGRAPHS IN SYSINIT MODULE
229sysize=500h ;AC000;
230
231; DRVFAT MUST BE THE FIRST LOCATION OF FREEABLE SPACE!
232 EVENB
233DRVFAT DW 0000 ;DRIVE AND FAT ID OF DOS
234BIOS$_L DW 0000 ;FIRST SECTOR OF DATA (Low word)
235bios$_H dw 0000 ;First sector of data (High word)
236DOSCNT DW 0000 ;HOW MANY SECTORS TO READ
237FBIGFAT DB 0 ; FLAGS FOR DRIVE
238;an004
239;FATLEN DW ? ; NUMBER OF SECTORS IN FAT.
240FATLOC DW ? ; SEG ADDR OF FAT SECTOR
241Init_BootSeg dw ? ;AN015; seg addr of buffer for reading boot record
242ROM_drv_num db 80h ;AN000; rom drv number
243;Boot_Sec_Per_Fat dw 0 ;AN000; Boot media sectors/FAT
244Md_SectorSize dw 512 ;AN004; Used by Get_Fat_Sector proc.
245Temp_Cluster dw 0 ;AN004; Used by Get_Fat_Sector proc.
246Last_Fat_SecNum dw -1 ;AN004; Used by Get_Fat_Sector proc.
247
248; THE FOLLOWING TWO BYTES ARE USED TO SAVE THE INFO RETURNED BY INT 13, AH = 8
249; CALL TO DETERMINE DRIVE PARAMETERS.
250NUM_HEADS DB 2 ; NUMBER OF HEADS RETURNED BY ROM
251SEC_TRK DB 9 ; SEC/TRK RETURNED BY ROM
252NUM_CYLN DB 40 ; NUMBER OF CYLINDERS RETURNED BY ROM
253
254FakeFloppyDrv db 0 ;AN002; If 1, then No diskette drives in the system.
255
256BOOTBIAS = 200H
257BOOT_ADDR = 7C00H
258EXT_BOOT_SIG_OFF = 11+size BPB_TYPE ;AN000; 3 byte jmp+8 byte OEM +extended bpb
259
260
261 EVENB
262DISKTABLE DW 512, 0100H, 64, 0
263 DW 2048, 0201H, 112, 0
264 DW 8192, 0402H, 256, 0
265 DW 32680, 0803H, 512, 0 ;Warning !!! Old values
266; DW 20740, 0803H, 512, 0 ;PTM P892 J.K. 12/3/86 DOS 3.3 will use this.
267 ;J.K.3/16/87 P54 Return back to old value for compatibility.!!!
268 DW 65535, 1004H, 1024, 0
269
270;DISKTABLE2 DW 32680, 0803H, 512, 0 ;Warning !!! Old values ;J.K.3/16/87 P54 Return to old value!!!
271;DISKTABLE2 DW 20740, 0803H, 512, 0 ;PTM p892 J.K. 12/3/86 DOS 3.3 will use this.
272; DW 65535, 0402H, 512, FBIG
273;AN000;
274;DISKTABLE2 dw 0, 32680, 0803h, 512, 0 ;table with the assumption of the
275; dw 2h, 0000h, 0402h, 512, FBIG ;total fat size <= 64KB.
276; dw 4h, 0000h, 0803h, 512, FBIG ;-This will cover upto 134 MB
277; dw 8h, 0000h, 1004h, 512, FBIG ;-This will cover upto 268 MB
278; dw 10h, 0000h, 2005h, 512, FBIG ;-This will cover upto 536 MB
279
280;AN004 Default DiskTable under the assumption of Total FAT size <= 128 KB, and
281; the maxium size of FAT entry = 16 Bit.
282DiskTable2 dw 0, 32680, 0803h, 512, 0 ;For compatibility.
283 dw 4h, 0000h, 0402h, 512, FBIG ;Covers upto 134 MB media.
284 dw 8h, 0000h, 0803h, 512, FBIG ; upto 268 MB
285 dw 10h, 0000h, 1004h, 512, FBIG ; upto 536 MB
286 dw 20h, 0000h, 2005h, 512, FBIG ; upto 1072 MB
287 dw 40h, 0000h, 4006h, 512, FBIG ; upto 2144 MB
288 dw 80h, 0000h, 8007h, 512, FBIG ; upto 4288 MB...
289
290;******************************************************************************
291;Variables for Mini disk initialization - J.K. 4/7/86
292;******************************************************************************
293End_Of_BDSM dw ? ;offset value of the ending address
294 ;of BDSM table. Needed to figure out
295 ;the Final_DOS_Location.
296numh db 0 ;number of hard files
297mininum db 0 ;logical drive number for mini disk(s)
298num_mini_dsk db 0 ;# of mini disk installed
299Rom_Minidsk_num db 80h ;physical mini disk number
300Mini_HDLIM dw 0
301Mini_SECLIM dw 0
302Mini_BPB_ptr dw 0 ;temporary variable used to save the
303 ;Mini Disk BPB pointer address in DskDrvs.
304;J.K. 4/7/86 End of Mini Disk Init Variables **********************************
305
306
307BIOS_DATE DB '01/10/84',0 ;This is used for checking AT ROM BIOS date.
308
309; THE FOLLOWING ARE THE RECOMMENDED BPBS FOR THE MEDIA THAT WE KNOW OF SO
310; FAR.
311
312; 48 TPI DISKETTES
313 EVENB
314BPB48T DW 512
315 DB 2
316 DW 1
317 DB 2
318 DW 112
319 DW 2*9*40
320 DB 0FDH
321 DW 2
322 DW 9
323 DW 2
324 DW 0
325 dw 0 ;AN000; hidden sector High
326 dd 0 ;AN000; extended total sectors
327
328; 96TPI DISKETTES
329 EVENB
330BPB96T DW 512
331 DB 1
332 DW 1
333 DB 2
334 DW 224
335 DW 2*15*80
336 DB 0F9H
337 DW 7
338 DW 15
339 DW 2
340 DW 0
341 dw 0 ;AN000; hidden sector High
342 dd 0 ;AN000; extended total sectors
343
344BPBSIZ = $-BPB96T
345
346; 3 1/2 INCH DISKETTE BPB
347
348 EVENB
349BPB35 DW 512
350 DB 2
351 DW 1 ; DOUBLE SIDED WITH 9 SEC/TRK
352 DB 2
353 DW 70h
354 DW 2*9*80
355 DB 0F9H
356 DW 3
357 DW 9
358 DW 2
359 DW 0
360 dw 0 ;AN000; hidden sector High
361 dd 0 ;AN000; extended total sectors
362
363 EVENB
364BPBTABLE DW BPB48T ; 48TPI DRIVES
365 DW BPB96T ; 96TPI DRIVES
366 DW BPB35 ; 3.5" DRIVES
367 ;DW BPB48T ; NOT USED - 8" DRIVES
368 ;DW BPB48T ; NOT USED - 8" DRIVES
369 ;DW BPB48T ; NOT USED - HARD FILES
370 ;DW BPB48T ; NOT USED - TAPE DRIVES
371 ;DW BPB48T ; NOT USED - OTHER
372
373PATCHTABLE LABEL BYTE
374 DW 10,MEDIA_PATCH
375 DW 3,GETBP1_PATCH
376 DW 3,SET_PATCH
377 DW 3,DISKIO_PATCH
378 DW 3,DSKERR
379 DW 10,CHANGED_PATCH
380 DW 3,INIT_PATCH
381 DW 0
382
383 ASSUME DS:NOTHING,ES:NOTHING
384
385;
386; ENTRY FROM BOOT SECTOR. THE REGISTER CONTENTS ARE:
387; DL = INT 13 DRIVE NUMBER WE BOOTED FROM
388; CH = MEDIA BYTE
389; BX = FIRST DATA SECTOR ON DISK.
390;J.K.
391; AX = first data sector (High)
392; DI = Sectors/FAT for the boot media.
393;
394 PUBLIC INIT
395INIT PROC NEAR
396 MESSAGE FTESTINIT,<"IBMBIO",CR,LF>
397 CLI
398 push ax
399 XOR AX,AX
400 MOV DS,AX
401 pop ax
402;J.K. MSLOAD will check the extended boot record and set AX, BX accordingly.
403
404;SB34INIT000*************************************************************
405;SB MSLOAD passes a 32 bit sector number hi word in ax and low in bx
406;SB Save this in cs:BIOS$_H and cs:BIOS$_L. This is for the start of
407;SB data sector of the BIOS.
408
409 mov cs:BIOS$_H,ax
410 mov cs:BIOS$_L,bx
411
412;SB34INIT000*************************************************************
413
414;J.K. With the following information from MSLOAD, we don't need the
415; Boot sector any more.-> This will solve the problem of 29 KB size
416; limitation of MSBIO.COM file.
417;J.K. AN004 - Don't need this information any more, since we are not going to
418; read the whole FAT into memory.
419; mov cs:Boot_Sec_Per_FAT, di ;sectors/FAT for boot media. ;AN000;
420
421;
422; PRESERVE ORIGINAL INT 13 VECTOR
423; WE NEED TO SAVE INT13 IN TWO PLACES IN CASE WE ARE RUNNING ON AN AT.
424; ON ATS WE INSTALL THE IBM SUPPLIED ROM_BIOS PATCH DISK.OBJ WHICH HOOKS
425; INT13 AHEAD OF ORIG13. SINCE INT19 MUST UNHOOK INT13 TO POINT TO THE
426; ROM INT13 ROUTINE, WE MUST HAVE THAT ROM ADDRESS ALSO STORED AWAY.
427;
428 MOV AX,DS:[13H*4]
429 MOV WORD PTR OLD13,AX
430 MOV WORD PTR ORIG13,AX
431 MOV AX,DS:[13H*4+2]
432 MOV WORD PTR OLD13+2,AX
433 MOV WORD PTR ORIG13+2,AX
434;
435; SET UP INT 13 FOR NEW ACTION
436;
437 MOV WORD PTR DS:[13H*4],OFFSET BLOCK13
438 MOV DS:[13H*4+2],CS
439;
440; PRESERVE ORIGINAL INT 19 VECTOR
441;
442 MOV AX,DS:[19H*4]
443 MOV WORD PTR ORIG19,AX
444 MOV AX,DS:[19H*4+2]
445 MOV WORD PTR ORIG19+2,AX
446;
447; SET UP INT 19 FOR NEW ACTION
448;
449 MOV WORD PTR DS:[19H*4],OFFSET INT19
450 MOV DS:[19H*4+2],CS
451 STI
452 INT 11H ;GET EQUIPMENT STATUS
453;J.K.6/24/87 We have to support a system that does not have any diskette
454;drives but only hardfiles. This system will IPL from the hardfile.
455;If the equipment flag bit 0 is 1, then the system has diskette drive(s).
456;Otherwise, the system only have hardfiles.
457;Important thing is that still, for compatibility reason, the drive letter
458;for the hardfile start from "C". So, we still need to allocate dummy BDS
459;drive A and driver B. In SYSINIT time, we are going to set CDS table entry
460;of DPB pointer for these drives to 0, so any user attempt to access this
461;drives will get "Invalid drive letter ..." message. We are going to
462;establish "FAKEFLOPPYDRV" flag. ***SYSINIT module should call INT 11h to check
463;if there are any diskette drivers in the system or not.!!!***
464
465;SB34INIT001**************************************************************
466;SB check the register returned by the equipment determination interrupt
467;SB we have to handle the case of no diskettes in the system by faking
468;SB two dummy drives.
469;SB if the register indicates that we do have floppy drives we don't need
470;SB to do anything special.
471;SB if the register indicates that we don't have any floppy drives then
472;SB what we need to do is set the FakeFloppyDrv variable, change the
473;SB register to say that we do have floppy drives and then go to execute
474;SB the code which starts at NOTSINGLE. This is because we can skip the
475;SB code given below which tries to find if there are one or two drives
476;SB since we already know about this. 6 LOCS
477
478 test ax,1
479 jnz DO_FLOPPY
480 mov cs:FakeFloppyDrv,1 ; fake floppy
481 mov ax,1 ; set to indicate 2 floppies
482 jmp short NOTSINGLE
483
484DO_FLOPPY:
485
486;SB34INIT001**************************************************************
487 ;
488 ; Determine if there are one or two diskette drives in system
489 ;
490 ROL AL,1 ;PUT BITS 6 & 7 INTO BITS 0 & 1
491 ROL AL,1
492 AND AX,3 ;ONLY LOOK AT BITS 0 & 1
493 JNZ NOTSINGLE ;ZERO MEANS SINGLE DRIVE SYSTEM
494 INC AX ;PRETEND IT'S A TWO DRIVE SYSTEM
495 INC CS:SINGLE ;REMEMBER THIS
496NOTSINGLE:
497 INC AX ;AX HAS NUMBER OF DRIVES, 2-4
498 ;IS ALSO 0 INDEXED BOOT DRIVE IF WE
499 ; BOOTED OFF HARD FILE
500 MOV CL,AL ;CH IS FAT ID, CL # FLOPPIES
501 TEST DL,80H ;BOOT FROM FLOPPY ?
502 JNZ GOTHRD ;NO.
503 XOR AX,AX ;INDICATE BOOT FROM DRIVE A
504GOTHRD:
505;
506; AX = 0-BASED DRIVE WE BOOTED FROM
507; BIOS$_L, BIOS$_H set.
508; CL = NUMBER OF FLOPPIES INCLUDING FAKE ONE
509; CH = MEDIA BYTE
510;
511 MESSAGE FTESTINIT,<"INIT",CR,LF>
512 XOR DX,DX
513 CLI
514 MOV SS,DX
515 MOV SP,700H ;LOCAL STACK
516 STI
517 ASSUME SS:NOTHING
518
519 PUSH CX ;SAVE NUMBER OF FLOPPIES AND MEDIA BYTE
520 MOV AH,CH ;SAVE FAT ID TO AH
521 PUSH AX ;SAVE BOOT DRIVE NUMBER, AND MEDIA BYTE
522;J.K. Let Model_byte, Secondary_Model_Byte be set here!!!
523;SB33020******************************************************************
524 mov ah,0c0h ; return system environment ;SB;3.30
525 int 15h ; call ROM-Bios routine ;SB;3.30
526;SB33020******************************************************************
527 jc No_Rom_System_Conf ; just use Model_Byte
528 cmp ah, 0 ; double check
529 jne No_Rom_System_Conf
530 mov al, ES:[BX.bios_SD_modelbyte] ;get the model byte
531 mov [Model_Byte], al
532 mov al, ES:[BX.bios_SD_scnd_modelbyte] ;secondary model byte
533 mov [Secondary_Model_Byte], al
534 jmp short Turn_Timer_On
535No_Rom_System_Conf:
536 MOV SI,0FFFFH ;MJB001
537 MOV ES,SI ;MJB001
538 MOV AL,ES:[0EH] ; GET MODEL BYTE ARR 2.41
539 MOV MODEL_BYTE,AL ; SAVE MODEL BYTE ARR 2.41
540Turn_Timer_On:
541 MOV AL,EOI
542 OUT AKPORT,AL ;TURN ON THE TIMER
543
544; NOP out the double word MOV instruction in MSDISK, if
545; this is not a 386 machine...
546 Get_CPU_Type ; macro to determine cpu type
547 cmp ax, 2 ; is it a 386?
548 je Skip_Patch_DoubleWordMov; yes: skip the patch
549
550Patch_DoubleWordMov:
551 push es ;AN003;
552 push cs ;AN003;
553 pop es ;AN003;ES -> CS
554 mov di, offset DoubleWordMov ;AN003;
555 mov cx, 3 ;AN003; 3 bytes to NOP
556 mov al, 90h ;AN003;
557 rep stosb ;AN003;
558 pop es ;AN003;
559Skip_Patch_DoubleWordMov: ;AN003;
560 MESSAGE FTESTINIT,<"COM DEVICES",CR,LF>
561;SB33IN1*********************************************************
562
563 mov si,offset COM4DEV
564 call AUX_INIT
565 mov si,offset COM3DEV
566 call AUX_INIT
567;SB33IN1*********************************************************
568 MOV SI,OFFSET COM2DEV
569 CALL AUX_INIT ;INIT COM2
570 MOV SI,OFFSET COM1DEV
571 CALL AUX_INIT ;INIT COM1
572
573 MESSAGE FTESTINIT,<"LPT DEVICES",CR,LF>
574 MOV SI,OFFSET LPT3DEV
575 CALL PRINT_INIT ;INIT LPT3
576 MOV SI,OFFSET LPT2DEV
577 CALL PRINT_INIT ;INIT LPT2
578 MOV SI,OFFSET LPT1DEV
579 CALL PRINT_INIT ;INIT LPT1
580
581 XOR DX,DX
582 MOV DS,DX ;TO INITIALIZE PRINT SCREEN VECTOR
583 MOV ES,DX
584
585 XOR AX,AX
586 MOV DI,INITSPOT
587 STOSW ;INIT FOUR BYTES TO 0
588 STOSW
589
590 MOV AX,CS ;FETCH SEGMENT
591
592 MOV DS:WORD PTR BRKADR,OFFSET CBREAK ;BREAK ENTRY POINT
593 MOV DS:BRKADR+2,AX ;VECTOR FOR BREAK
594
595;*********************************************** ARR 2.15
596; SINCE WE'RE FIRST IN SYSTEM, NO NEED TO CHAIN THIS.
597; CLI ; ARR 2.15 DON'T GET BLOWN
598; MOV DS:WORD PTR TIMADR,OFFSET TIMER ; ARR 2.15 TIMER ENTRY POINT
599; MOV DS:TIMADR+2,AX ; ARR 2.15 VECTOR FOR TIMER
600; STI
601;*********************************************** ARR 2.15
602
603; BAS DEBUG
604 MOV DS:WORD PTR CHROUT*4,OFFSET WORD PTR OUTCHR
605 MOV DS:WORD PTR CHROUT*4+2,AX
606
607 MESSAGE FTESTINIT,<"INTERRUPT VECTORS",CR,LF>
608 MOV DI,4
609 MOV BX,OFFSET INTRET ;WILL INITIALIZE REST OF INTERRUPTS
610 XCHG AX,BX
611 STOSW ;LOCATION 4
612 XCHG AX,BX
613 STOSW ;INT 1 ;LOCATION 6
614 ADD DI,4
615 XCHG AX,BX
616 STOSW ;LOCATION 12
617 XCHG AX,BX
618 STOSW ;INT 3 ;LOCATION 14
619 XCHG AX,BX
620 STOSW ;LOCATION 16
621 XCHG AX,BX
622 STOSW ;INT 4 ;LOCATION 18
623
624 MOV DS:WORD PTR 500H,DX ;SET PRINT SCREEN & BREAK =0
625 MOV DS:WORD PTR LSTDRV,DX ;CLEAN OUT LAST DRIVE SPEC
626
627 MESSAGE FTESTINIT,<"DISK PARAMETER TABLE",CR,LF>
628
629;;** MOV SI,WORD PTR DS:DSKADR ; ARR 2.41
630;;** MOV DS,WORD PTR DS:DSKADR+2 ; DS:SI -> CURRENT TABLE ARR 2.41
631;;**
632;;** MOV DI,SEC9 ; ES:DI -> NEW TABLE ARR 2.41
633;;** MOV CX,SIZE DISK_PARMS ; ARR 2.41
634;;** REP MOVSB ; COPY TABLE ARR 2.41
635;;** PUSH ES ; ARR 2.41
636;;** POP DS ; DS = 0 ARR 2.41
637
638;;** MOV WORD PTR DS:DSKADR,SEC9 ; ARR 2.41
639;;** MOV WORD PTR DS:DSKADR+2,DS ; POINT DISK PARM VECTOR TO NEW TABLE
640 ; ARR 2.41
641;SB34INIT002******************************************************************
642;SB We need to initalise the cs:MotorStartup variable from the disk
643;SB parameter table at SEC9. The offsets in this table are defined in
644;SB the DISK_PARMS struc in MSDSKPRM.INC. 2 LOCS
645
646 mov al,ds:SEC9 + DISK_MOTOR_STRT
647 mov cs:MotorStartup,al
648;SB34INIT002******************************************************************
649 CMP MODEL_BYTE,0FDH ; IS THIS AN OLD ROM? ARR 2.41
650 JB NO_DIDDLE ; NO ARR 2.41
651 MOV WORD PTR DS:(SEC9 + DISK_HEAD_STTL),0200H+NORMSETTLE
652 ; SET HEAD SETTLE AND MOTOR START
653 ; ON PC-1 PC-2 PC-XT HAL0 ARR 2.41
654 MOV DS:(SEC9 + DISK_SPECIFY_1),0DFH
655 ; SET 1ST SPECIFY BYTE
656 ; ON PC-1 PC-2 PC-XT HAL0 ARR 2.41
657NO_DIDDLE: ; ARR 2.41
658 INT 12H ;GET MEMORY SIZE--1K BLOCKS IN AX
659 MOV CL,6
660 SHL AX,CL ;CONVERT TO 16-BYTE BLOCKS(SEGMENT NO.)
661 POP CX ; RETREIVE BOOT DRIVE NUMBER, AND FAT ID
662 MOV DRVFAT,CX ;SAVE DRIVE TO LOAD DOS, AND FAT ID
663
664 PUSH AX
665;J.K. Don't have to look at the boot addr.
666; MOV DX,DS:(7C00H + 16H) ; NUMBER OF SECTORS/FAT FROM BOOT SEC
667;an004
668; mov dx, cs:Boot_Sec_Per_FAT ;AC000;Do not use the bpb info from Boot record any more.
669; XOR DH,DH
670; MOV FATLEN,DX
671;
672; CONVERT SECTOR COUNT TO PARAGRAPH COUNT:512 BYTES / SEC / 16 BYTES / PARA
673; = 32 PARA /SECTOR
674;
675
676; SHL DX,1
677; SHL DX,1
678; SHL DX,1
679; SHL DX,1
680; SHL DX,1
681; SUB AX,DX ; ROOM FOR FAT
682 sub ax, 64 ;AN004; Room for FATLOC segment. (1 KB buffer)
683 MOV FATLOC,AX ; LOCATION TO READ FAT
684 sub ax, 64 ;Room for Boot Record buffer segment (1 KB)
685 mov Init_BootSeg, ax ;AN015;
686 POP AX
687
688 MOV DX,SYSINITSEG
689 MOV DS,DX
690
691 ASSUME DS:SYSINITSEG
692
693 MOV WORD PTR DEVICE_LIST,OFFSET CONHEADER
694 MOV WORD PTR DEVICE_LIST+2,CS
695
696 MOV MEMORY_SIZE,AX
697 INC CL
698 MOV DEFAULT_DRIVE,CL ;SAVE DEFAULT DRIVE SPEC
699
700;DOSSEG = (((END$ - START$)+15)/16)+BIOSEG+SYSIZE
701
702; BAS DEBUG
703;MOV CURRENT_DOS_LOCATION,(((END$ - START$)+15)/16)+SYSIZE
704 MOV AX, OFFSET END$
705 SUB AX, OFFSET START$
706 ADD AX, 15
707 RCR AX, 1 ; DIVIDE BY 16
708 SHR AX, 1
709 SHR AX, 1
710 SHR AX, 1
711 ADD AX, SYSIZE
712 ADD AX, CODE
713 MOV CURRENT_DOS_LOCATION, AX
714; BAS DEBUG
715; ADD CURRENT_DOS_LOCATION,CODE
716
717; IMPORTANT: SOME OLD IBM HARDWARE GENERATES SPURIOUS INT F'S DUE TO BOGUS
718; PRINTER CARDS. WE INITIALIZE THIS VALUE TO POINT TO AN IRET ONLY IF
719
720; 1) THE ORIGINAL SEGMENT POINTS TO STORAGE INSIDE VALID RAM.
721
722; 2) THE ORIGINAL SEGMENT IS 0F000:XXXX
723
724; THESES ARE CAPRICIOUS REQUESTS FROM OUR OEM FOR REASONS BEHIND THEM, READ
725; THE DCR'S FOR THE IBM DOS 3.2 PROJECT.
726
727 PUSH AX
728
729 ASSUME ES:SYSINITSEG, DS:NOTHING
730
731 MOV AX,SYSINITSEG
732 MOV ES,AX
733
734 XOR AX,AX ; AX := SEGMENT FOR INT 15
735 MOV DS,AX
736 MOV AX,WORD PTR DS:(0FH*4+2)
737
738 CMP AX,ES:MEMORY_SIZE ; CONDITION 1
739 JNA RESETINTF
740
741 CMP AX,0F000H ; CONDITION 2
742 JNE KEEPINTF
743
744RESETINTF:
745 MOV WORD PTR DS:[0FH*4],OFFSET INTRET
746 MOV WORD PTR DS:[0FH*4+2],CS
747KEEPINTF:
748 POP AX
749
750; END IMPORTANT
751
752;SB34INIT003****************************************************************
753;SB We will check if the system has IBM extended key board by
754;SB looking at a byte at 40:96. If bit 4 is set, then extended key board
755;SB is installed, and we are going to set KEYRD_Func to 10h, KEYSTS_Func to 11h
756;SB for the extended keyboard function. Use cx as the temporary register. 8 LOCS
757
758 xor cx,cx
759 mov ds,cx
760 assume ds:nothing
761 mov cl,ds:0496h ; get keyboard flag
762 test cl,00010000b
763 jz ORG_KEY ; orginal keyboard
764 mov byte ptr KEYRD_func,10h ; extended keyboard
765 mov byte ptr KEYSTS_func,11h ; change for extended keyboard functions
766ORG_KEY:
767
768;SB34INIT003****************************************************************
769
770;**************************************************************
771; WILL INITIALIZE THE NUMBER OF DRIVES
772; AFTER THE EQUIPMENT CALL (INT 11H) BITS 6&7 WILL TELL
773; THE INDICATIONS ARE AS FOLLOWS:
774;
775; BITS 7 6 DRIVES
776; 0 0 1
777; 0 1 2
778; 1 0 3
779; 1 1 4
780;**************************************************************
781 PUSH CS
782 POP DS
783 PUSH CS
784 POP ES
785
786 ASSUME DS:CODE,ES:CODE
787
788 call CMOS_Clock_Read ;Before doing anythig else if CMOS clock exists,
789 ;then set the system time according to that.
790 ;Also, reset the cmos clock rate.
791
792 MESSAGE FTESTINIT,<"DISK DEVICES",CR,LF>
793
794 XOR SI,SI
795 MOV WORD PTR [SI],OFFSET HARDDRV ;SET UP POINTER TO HDRIVE
796
797 POP AX ;NUMBER OF FLOPPIES AND FAT ID
798 XOR AH,AH ; CHUCK FAT ID BYTE
799 MOV HARDNUM,AL ;REMEMBER WHICH DRIVE IS HARD DISK
800 MOV DRVMAX,AL ;AND SET INITIAL NUMBER OF DRIVES
801 SHL AX,1 ;TWO BYTES PER ADDRESS
802 MOV DI,OFFSET DSKDRVS
803 ADD DI,AX ;POINT TO HARDFILE LOCATION
804 MOV SI,OFFSET HDSKTAB
805 MOVSW ;TWO ADDRESSES TO MOVE
806 MOVSW
807 MESSAGE FTESTINIT,<"BEFORE INT 13",CR,LF>
808;SB33021********************************************************************
809 mov DL, 80h ;SB ; tell rom bios to look at hard drives
810 mov AH, 8h ;SB ; set command to get drive parameter
811 int 13h ;SB ; call ROM-BIOS to get number of drives
812;SB33021********************************************************************
813 JC ENDDRV ;CARRY INDICATES OLD ROM, SO NO HARDFILE
814 MOV HNUM,DL
815ENDDRV:
816 MESSAGE FTESTINIT,<"SETTING UP BDSS",CR,LF>
817
818;
819; SCAN THE LIST OF DRIVES TO DETERMINE THEIR TYPE. WE HAVE THREE FLAVORS OF
820; DISKETTE DRIVES:
821;
822; 48TPI DRIVES WE DO NOTHING SPECIAL FOR THEM
823; 96TPI DRIVES MARK THE FACT THAT THEY HAVE CHANGELINE SUPPORT.
824; 3 1/4 DRIVES MARK CHANGELINE SUPPORT AND SMALL.
825;
826; THE FOLLOWING CODE USES REGISTERS FOR CERTAIN VALUES:
827; DL - PHYSICAL DRIVE
828; DS:DI - POINTS TO CURRENT BDS
829; CX - FLAG BITS FOR BDS
830; DH - FORM FACTOR FOR THE DRIVE (1 - 48TPI, 2 - 96TPI, 3 - 3.5" MEDIUM)
831;
832 XOR DL,DL ; START OUT WITH DRIVE 0.
833 PUSH CS
834 POP DS
835 ASSUME DS:CODE
836
837 MOV EOT,9
838 MOV DI,OFFSET START_BDS
839;J.K.6/24/87 Check if the system has no physical diskette drives.
840;J.K. If it is, then we don't have to set BDS tables. But since we
841;J.K. pretend that we have 2 floppies, we are going to reserve two
842;J.K. BDS tables for the fake drive A, and B. and set the end of link
843;J.K. pointer.
844
845;SB34INIT004*********************************************************
846;SB Check to see if we are faking floppy drives. If not we don't
847;SB do anything special. If we are faking floppy drives we need
848;SB to set aside two BDSs for the two fake floppy drives. We
849;SB don't need to initalise any fields though. So starting at START_BDS
850;SB use the link field in the BDS structure to go to the second BDS
851;SB in the list and initalise it's link field to -1 to set the end of
852;SB the list. Then jump to the routine at DoHard to allocate/initialise
853;SB the BDS for HardDrives.
854
855 cmp cs:FakeFloppyDrv,1
856 jnz LOOP_DRIVE ; system has floppy
857 mov di,word ptr [di].link ; di <- first BDS link
858 mov di,word ptr [di].link ; di <- second BDS link
859 mov word ptr [di].link,-1 ; set end of link
860 jmp DoHard ; allocate/initialise BDS for HardDrives
861;SB34INIT004*********************************************************
862
863LOOP_DRIVE:
864 CMP DL,DRVMAX
865 JB GOT_MORE
866 JMP DONE_DRIVES
867GOT_MORE:
868 XOR CX,CX ; ZERO ALL FLAGS
869 MOV DI,WORD PTR [DI].LINK ; GET NEXT BDS
870 MOV DH,FF48TPI ; SET FORM FACTOR TO 48 TPI
871 MOV NUM_CYLN,40 ; 40 TRACKS PER SIDE
872
873 PUSH DS
874 PUSH DI
875 PUSH DX
876 PUSH CX
877 PUSH ES
878
879;SB33022********************************************************************
880 MOV AH, 8h ;GET DRIVE PARAMETERS ;SB;3.30
881 INT 13h ;CALL ROM-BIOS ;SB;3.30
882;SB33022********************************************************************
883 JNC PARMSFROMROM
884 JMP NOPARMSFROMROM ; GOT AN OLD ROM
885PARMSFROMROM:
886;J.K. 10/9/86 If CMOS is bad, it gives ES,AX,BX,CX,DH,DI=0. CY=0.
887;In this case, we are going to put bogus informations to BDS table.
888;We are going to set CH=39,CL=9,DH=1 to avoid divide overflow when
889;they are calculated at the later time. This is just for the Diagnostic
890;Diskette which need MSBIO,MSDOS to boot up before it sets CMOS.
891;This should only happen with drive B.
892
893 CMP CH,0 ; if ch=0, then cl,dh=0 too.
894 JNE PFR_OK
895 MOV CH,39 ; ROM gave wrong info.
896 MOV CL,9 ; Let's default to 360K.
897 MOV DH,1
898PFR_OK:
899 INC DH ; MAKE NUMBER OF HEADS 1-BASED
900 INC CH ; MAKE NUMBER OF CYLINDERS 1-BASED
901 MOV NUM_HEADS,DH ; SAVE PARMS RETURNED BY ROM
902 AND CL,00111111B ; EXTRACT SECTORS/TRACK
903 MOV SEC_TRK,CL
904 MOV NUM_CYLN,CH ; ASSUME LESS THAN 256 CYLINDERS!!
905; MAKE SURE THAT EOT CONTAINS THE MAX NUMBER OF SEC/TRK IN SYSTEM OF FLOPPIES
906 CMP CL,EOT ; MAY SET CARRY
907 JBE EOT_OK
908 MOV EOT,CL
909EOT_OK:
910 POP ES
911 POP CX
912 POP DX
913 POP DI
914 POP DS
915
916; CHECK FOR CHANGELINE SUPPORT ON DRIVE
917;SB33023********************************************************************
918 mov AH, 15h ;SB ; set command to get DASD type
919 int 13h ;SB ; call ROM-BIOS
920;SB33023********************************************************************
921 JC CHANGELINE_DONE
922 CMP AH,02 ; CHECK FOR PRESENCE OF CHANGELINE
923 JNE CHANGELINE_DONE
924;
925; WE HAVE A DRIVE WITH CHANGE LINE SUPPORT.
926;
927 MESSAGE FTESTINIT,<"96TPI DEVICES",CR,LF>
928
929 OR CL,FCHANGELINE ; SIGNAL TYPE
930 MOV FHAVE96,1 ; REMEMBER THAT WE HAVE 96TPI DISKS
931;
932; WE NOW TRY TO SET UP THE FORM FACTOR FOR THE TYPES OF MEDIA THAT WE KNOW
933; AND CAN RECOGNISE. FOR THE REST, WE SET THE FORM FACTOR AS "OTHER".
934;
935CHANGELINE_DONE:
936; 40 CYLINDERS AND 9 OR LESS SEC/TRK, TREAT AS 48 TPI MEDIUM.
937 CMP NUM_CYLN,40
938 JNZ TRY_80
939 CMP SEC_TRK,9
940 JBE GOT_FF
941GOTOTHER:
942 MOV DH,FFOTHER ; WE HAVE A "STRANGE" MEDIUM
943 JMP SHORT GOT_FF
944
945;
946; 80 CYLINDERS AND 9 SECTORS/TRACK => 720 KB DEVICE
947; 80 CYLINDERS AND 15 SEC/TRK => 96 TPI MEDIUM
948;
949TRY_80:
950 CMP NUM_CYLN,80
951 JNZ GOTOTHER
952 CMP SEC_TRK,15
953 JZ GOT96
954 CMP SEC_TRK,9
955 JNZ GOTOTHER
956 MOV DH,FFSMALL
957 JMP SHORT GOT_FF
958
959GOT96:
960 MOV DH,FF96TPI
961
962GOT_FF:
963 JMP SHORT NEXTDRIVE
964
965; WE HAVE AN OLD ROM, SO WE EITHER HAVE A 48TPI OR 96TPI DRIVE. IF THE DRIVE
966; HAS CHANGELINE, WE ASSUEM IT IS A 96TPI, OTHERWISE WE TREAT IT AS A 48TPI.
967
968NOPARMSFROMROM:
969 POP ES
970 POP CX
971 POP DX
972 POP DI
973 POP DS
974
975;SB33024****************************************************************
976 MOV AH, 15h ; SET COMMAND TO GET DASD TYPE ;SB;3.30
977 INT 13h ; CALL ROM-BIOS ;SB;3.30
978;SB33024****************************************************************
979 JC NEXTDRIVE
980 CMP AH,2 ; IS THERE CHANGELINE?
981 JNZ NEXTDRIVE
982 OR CL,FCHANGELINE
983 MOV FHAVE96,1 ; REMEMBER THAT WE HAVE 96TPI DRIVES
984 MOV NUM_CYLN,80
985 MOV DH,FF96TPI
986 MOV AL,15 ; SET EOT IF NECESSARY
987 CMP AL, EOT
988 JBE EOT_OK2
989 MOV EOT,AL
990EOT_OK2:
991
992NEXTDRIVE:
993 OR CL,FI_OWN_PHYSICAL ; SET THIS TRUE FOR ALL DRIVES
994 MOV BH,DL ;SAVE INT13 DRIVE NUMBER
995
996; WE NEED TO DO SPECIAL THINGS IF WE HAVE A SINGLE DRIVE SYSTEM AND ARE SETTING
997; UP A LOGICAL DRIVE. IT NEEDS TO HAVE THE SAME INT13 DRIVE NUMBER AS ITS
998; COUNTERPART, BUT THE NEXT DRIVE LETTER. ALSO RESET OWNERSHIP FLAG.
999; WE DETECT THE PRESENCE OF THIS SITUATION BY EXAMINING THE FLAG SINGLE FOR THE
1000; VALUE 2.
1001
1002 CMP SINGLE,2
1003 JNZ NOT_SPECIAL
1004 DEC BH ; INT13 DRIVE NUMBER SAME FOR LOGICAL DRIVE
1005 XOR CL,FI_OWN_PHYSICAL ; RESET OWNERSHIP FLAG FOR LOGICAL DRIVE
1006NOT_SPECIAL:
1007; THE VALUES THAT WE PUT IN FOR RHDLIM AND RSECLIM WILL ONLY REMAIN IF THE
1008; FORM FACTOR IS OF TYPE "FFOTHER".
1009 XOR AX,AX
1010 MOV AL,NUM_HEADS
1011 MOV WORD PTR [DI].RHDLIM,AX
1012 MOV AL,SEC_TRK
1013 MOV WORD PTR [DI].RSECLIM,AX
1014 MOV WORD PTR [DI].FLAGS,CX
1015 MOV BYTE PTR [DI].FORMFACTOR,DH
1016 MOV BYTE PTR [DI].DRIVELET,DL
1017 MOV BYTE PTR [DI].DRIVENUM,BH
1018 MOV BL,BYTE PTR NUM_CYLN
1019 MOV BYTE PTR [DI].CCYLN,BL ; ONLY THE L.S. BYTE IS SET HERE
1020 CMP SINGLE,1 ; SPECIAL CASE FOR SINGLE DRIVE SYSTEM
1021 JNZ NO_SINGLE
1022 MESSAGE FTESTINIT,<"SINGLE DRIVE SYSTEM",CR,LF>
1023 MOV SINGLE,2 ; DON'T LOSE INFO THAT WE HAVE SINGLE SYSTEM
1024 OR CX,FI_AM_MULT
1025 OR WORD PTR [DI].FLAGS,CX
1026 MOV DI,WORD PTR [DI].LINK ; MOVE TO NEXT BDS IN LIST
1027 INC DL
1028 JMP SHORT NEXTDRIVE ; USE SAME INFO FOR BDS A PREVIOUS
1029NO_SINGLE:
1030 INC DL
1031 JMP LOOP_DRIVE
1032
1033DONE_DRIVES:
1034 MOV AX,-1 ; SET LINK TO NULL
1035 MOV WORD PTR [DI].LINK,AX
1036
1037; SET UP ALL THE HARD DRIVES IN THE SYSTEM
1038
1039DOHARD:
1040 MNUM FTESTINIT+FTESTHARD,AX
1041 MESSAGE FTESTINIT+FTESTHARD,<" HARD DISK(S) TO INITIALIZE",CR,LF>
1042 MESSAGE FTESTINIT+FTESTHARD,<"HARD DISK 1",CR,LF>
1043
1044 CMP HNUM,0 ; IF (NO_HARD_FILES)
1045 JLE STATIC_CONFIGURE ; THEN EXIT TO CONFIGURE
1046
1047 MOV DL,80H
1048 MOV DI,OFFSET BDSH ; SET UP FIRST HARD FILE.
1049 MOV BL,HARDNUM
1050 CALL SETHARD
1051 assume es:nothing
1052 JNC HARDFILE1_OK
1053
1054 DEC HNUM ; FIRST HARD FILE IS BAD.
1055 CMP HNUM,0 ; IF (SECOND_HARD_FILE)
1056 JG SECOND_HARD ; THEN SET UP SECOND HARD FILE
1057 JMP SHORT STATIC_CONFIGURE
1058
1059HARDFILE1_OK:
1060 CALL INSTALL_BDS ; INSTALL BDS INTO LINKED LIST
1061 CMP HNUM,2 ; IF (ONLY_ONE_HARDFILE)
1062 JB SETIT ; THEN SETIT "IN PLACE"
1063
1064 MOV BL,HARDNUM
1065 INC BL ; NEXT DRIVE LETTER
1066 MOV DI,OFFSET BDSX
1067
1068SECOND_HARD: ; SETUP SECOND HARD FILE
1069
1070 MESSAGE FTESTINIT+FTESTHARD,<"HARD DISK 2",CR,LF>
1071 MOV DL,81H ; NEXT HARD FILE
1072 CALL SETHARD
1073 assume es:nothing
1074 JNC HARDFILE2_OK
1075 DEC HNUM
1076 JMP SHORT SETIT
1077
1078HARDFILE2_OK:
1079 CALL INSTALL_BDS
1080
1081SETIT:
1082 MOV AL,HNUM
1083 OR AL,AL
1084 JZ STATIC_CONFIGURE
1085 ADD AL,HARDNUM
1086 MOV DRVMAX,AL
1087
1088; End of physical drive initialization.
1089; *** Do not change the position of the following statement.-J.K.4/7/86
1090; *** DoMini routine will use [DRVMAX] value for the start of the logical
1091; *** drive number of Mini disk(s).
1092
1093 call DoMini ;For setting up mini disks, if found -J.K.
1094
1095 assume es:nothing
1096; END OF DRIVE INITIALIZATION.
1097
1098;J.K. 9/24/86 We now decide, based on the configurations available so far, what
1099;code or data we need to keep as a stay resident code. The following table
1100;shows the configurations under consideration. They are listed in the order
1101;of their current position memory.
1102;Configuration will be done in two ways:
1103;First, we are going to set "Static configuration". Static configuration will
1104;consider from basic configuration to ENDOF96TPI configuration. The result
1105;of static configuration will be the address the Dynamic configuration will
1106;use to start with.
1107;Secondly, "Dynamic cofiguration" will be performed. Dynamic configuration
1108;involves possible relocation of CODE or DATA. Dynamic configuration routine
1109;will take care of BDSM tables and AT ROM Fix module thru K09 suspend/resume
1110;code individually. After these operation, FINAL_DOS_LOCATION will be set.
1111;This will be the place SYSINIT routine will relocate MSDOS module for good.
1112;
1113; 1. BASIC CONFIGURATION FOR IBMBIO (EndFloppy, EndSwap)
1114; 2. ENDONEHARD
1115; 3. ENDTWOHARD
1116; 4. END96TPI ;a system that supports "Change Line Error"
1117; 5. End of BDSM ;BDSM tables for mini disks.
1118; 6. ENDATROM ;Some of AT ROM fix module.
1119; 7. ENDCMOSCLOCKSET;Supporting program for CMOS clock write.
1120; 8. ENDK09 ;K09 CMOS Clock module to handle SUSPEND/RESUME operation.
1121;
1122;J.K. 9/24/86.
1123
1124; *** For mini disk configuration. -J.K. 4/7/86
1125; *** END_OF_BDSM will contains the ending address(offset) of BDSM table for
1126; *** mini disks which is located right after the label END96TPI.
1127; *** The variable NUM_MINI_DSK will indicate the existance of the mini disk.-J.K. 4/7/86
1128
1129
1130STATIC_CONFIGURE:
1131
1132
1133 PUSH AX
1134 mov ax, offset END96TPI ;let's start with the biggest one.
1135 cmp fHave96, 0 ;Is change line support there?
1136 jnz Config96 ;Yes.
1137
1138 mov ax, offset ENDTWOHARD
1139 cmp HNUM, 1 ;1 hard file?
1140 jbe No_Two_HRD
1141 jmp ConfigTwoHard
1142No_Two_HRD:
1143 mov ax, offset ENDONEHARD
1144 jnz Basic_Floppy
1145 jmp ConfigOneHard
1146Basic_Floppy:
1147 mov ax, offset ENDFLOPPY
1148 jmp Dynamic_Configure ;static configuration is done!
1149
1150;
1151; KEEP THE 96TPI CODE
1152;
1153CONFIG96:
1154;
1155; SAVE OLD INT 13 VECTOR
1156;
1157 PUSH AX
1158 PUSH DS
1159 XOR AX,AX
1160 MOV DS,AX
1161 ASSUME DS:NOTHING
1162
1163 MOV AX,DS:[4 * 13H]
1164 MOV WORD PTR CS:REAL13,AX
1165 MOV AX,DS:[4 * 13H+2]
1166 MOV WORD PTR CS:REAL13+2,AX
1167;
1168; INSERT NEW VECTOR
1169;
1170 MOV WORD PTR DS:[4 * 13H],OFFSET INT13
1171 MOV DS:[4 * 13H + 2],CS
1172
1173 POP DS
1174 ASSUME DS:CODE
1175
1176 POP AX
1177
1178; KEEP TWO HARD DISK BPBS
1179
1180CONFIGTWOHARD:
1181
1182; KEEP ONE HARD DISK BPB
1183
1184CONFIGONEHARD:
1185
1186; ADJUST THE NUMBER OF DRIVES TO INCLUDE THE HARD DISKS.
1187
1188 PUSH AX
1189
1190 MOV AL,HARDNUM
1191 ADD AL,HNUM
1192 add al, num_mini_dsk ;J.K. 4/7/86 for mini disks installed
1193 ;if not installed, then num_mini_dsk = 0.
1194 MOV DRVMAX,AL
1195 POP AX ;now, static config is done.
1196
1197
1198DYNAMIC_CONFIGURE:
1199 call Get_Para_Offset ;For dynamic allocation, we are
1200 ;going to use offset address that
1201 ;is in paragraph boundary.
1202 push cs
1203 pop es ;es -> code
1204 assume es:code
1205 cld ;clear direction
1206
1207 cmp [num_mini_dsk], 0 ;Mini disk(s) installed ?
1208 jz CheckATROM ;No.
1209 mov ax, End_Of_BDSM ;set the new ending address
1210 call Get_Para_Offset
1211CheckATROM:
1212 cmp Model_Byte, 0FCh ;AT ?
1213 jnz CheckCMOSClock
1214 cmp HNUM, 0 ;No hard file?
1215 jz CheckCMOSClock
1216
1217 mov si, 0F000h
1218 mov es, si ;ES -> BIOS segment
1219 assume es:nothing ;
1220 mov si, offset BIOS_DATE ;
1221 mov di, 0FFF5H ;ROM BIOS string is at F000:FFF5
1222Cmpbyte: ;Only patch ROM for bios dated 01/10/84
1223 cmpsb ;
1224 jnz CheckCMOSClock ;
1225 cmp byte ptr [si-1],0 ;
1226 jnz Cmpbyte ;
1227SetRomCode: ;Now we have to install ROM fix
1228 ;AX is the address to move.
1229 push cs ;
1230 pop es ;set ES to CODE seg
1231 assume es:code
1232
1233 mov word ptr ORIG13, ax
1234 mov word ptr ORIG13+2, cs ;set new ROM bios int 13 vector
1235 mov cx, offset ENDATROM
1236 mov si, offset IBM_DISK_IO
1237 sub cx, si ;size of AT ROM FIX module
1238 mov di, ax ;destination
1239 rep movsb ;relocate it
1240 mov ax, di ;new ending address
1241 call Get_Para_Offset ;in AX
1242
1243CheckCMOSClock:
1244 push cs
1245 pop es ;set ES to CODE seg
1246 assume es:code
1247 cmp HaveCMOSClock, 1 ;CMOS Clock exists?
1248 jne CheckK09
1249 mov DaycntToDay, ax ;set the address for MSCLOCK
1250 mov cx, offset EndDaycntToDay
1251 mov si, offset Daycnt_To_Day
1252 sub cx, si ;size of CMOS clock supporting routine
1253 mov di, ax
1254 rep movsb
1255 mov ax, di
1256 call Get_Para_Offset
1257 mov BinToBCD, ax ;set the address for MSCLOCK
1258 mov cx, offset EndCMOSClockSet
1259 mov si, offset Bin_To_BCD
1260 sub cx, si
1261 mov di, ax
1262 rep movsb
1263 mov ax, di
1264 call Get_Para_Offset
1265
1266CheckK09:
1267;SB33025****************************************************************
1268 push ax ;save ax ;SB ;3.30*
1269 mov ax,4100h ;Q: is it a K09 ;SB ;3.30*
1270 mov bl,0 ; ;SB ;3.30*
1271 int 15h ; ;SB ;3.30*
1272;SB33025****************************************************************
1273 pop ax
1274 jc CONFIGDONE
1275
1276 mov si, offset INT6C
1277 mov cx, offset ENDK09
1278 sub cx, si ;size of K09 routine
1279 mov di, ax
1280 push di ;save destination
1281 rep movsb
1282 mov ax, di ;
1283 call Get_Para_Offset ;AX = new ending address
1284 pop di
1285
1286 push ax
1287 push ds
1288 mov fHaveK09, 1 ;remember we have a K09 type
1289 xor ax,ax
1290 mov ds, ax
1291 assume ds:nothing
1292
1293 mov word ptr ds:[4 * 6Ch], di ;new INT 6Ch handler
1294 mov ds:[4 * 6Ch +2], cs
1295
1296 pop ds
1297 assume ds:code
1298 pop ax ;restore the ending address
1299
1300; SET UP CONFIG STUFF FOR SYSINIT
1301
1302CONFIGDONE: ;AX is final ending address of MSBIO.
1303 MOV DX,SYSINITSEG
1304 MOV DS,DX
1305 ASSUME DS:SYSINITSEG
1306
1307 SUB AX,OFFSET START$
1308 ADD AX,15
1309 RCR AX,1
1310 SHR AX, 1
1311 SHR AX, 1
1312 SHR AX, 1
1313 MOV FINAL_DOS_LOCATION, AX
1314 POP AX
1315
1316GOINIT:
1317 ADD FINAL_DOS_LOCATION,CODE
1318 MESSAGE FTESTINIT,<"FINAL DOS LOCATION IS ">
1319 MNUM FTESTINIT,FINAL_DOS_LOCATION
1320 MESSAGE FTESTINIT,<CR,LF>
1321 PUSH CS
1322 POP DS
1323
1324 ASSUME DS:CODE,ES:NOTHING
1325
1326 CMP BYTE PTR FHAVE96,0
1327 JNZ READDOS
1328 CALL PURGE_96TPI ;MJB001 ELIMINATE CALLS TO 96TPI HOOHAH
1329
1330READDOS:
1331 MESSAGE FTESTINIT,<"LOAD FAT",CR,LF>
1332 MOV AX,DRVFAT ; GET DRIVE AND FAT ID
1333 CALL SETDRIVE ; GET BDS FOR DRIVE
1334
1335 CALL GETBP ; ENSURE VALID BPB IS PRESENT
1336
1337;AN004; J.K. Don't need this. We are not read the whole FAT at once.
1338; CALL GETFAT ;READ IN THE FAT SECTOR
1339
1340 XOR DI,DI
1341 MOV AL,ES:[DI] ;GET FAT ID BYTE
1342 MOV BYTE PTR DRVFAT+1,AL ;SAVE FAT BYTE
1343 MOV AX,DRVFAT
1344 MESSAGE FTESTINIT,<"FATID READ ">
1345 MNUM FTESTINIT,AX
1346 MESSAGE FTESTINIT,<CR,LF>
1347 CALL SETDRIVE ;GET CORRECT BDS FOR THIS DRIVE
1348
1349 mov bx, [di].BYTEPERSEC
1350 mov cs:Md_SectorSize, bx ;AN004;Used by Get_Fat_Sector proc.
1351 MOV BL,[DI].FATSIZ ; GET SIZE OF FAT ON MEDIA
1352 MOV FBIGFAT,BL
1353 MOV CL,[DI].SECPERCLUS ;GET SECTORS/CLUSTER
1354;J.K.32 bit calculation
1355 MOV AX,[DI].HIDSEC_L ;GET NUMBER OF HIDDEN SECTORS (low)
1356 SUB BIOS$_L,AX ;SUBTRACT HIDDEN SECTORS since we
1357 ;need a logical sector number that will
1358 ;be used by GETCLUS(diskrd procedure)
1359;SB34INIT005******************************************************************
1360;SB We have 32 bit sector number now though. SO the high word also needs
1361;SB to be adjusted. Update BIOS$_H too. 2 LOCS
1362
1363 mov ax,[di].HIDSEC_H ;subtract upper 16 bits of sector num
1364 sbb BIOS$_H,ax
1365;SB34INIT005******************************************************************
1366 XOR CH,CH ;CX = SECTORS/CLUSTER
1367
1368; THE BOOT PROGRAM HAS LEFT THE DIRECTORY AT 0:500
1369
1370 PUSH DS
1371 XOR DI,DI
1372 MOV DS,DI ; ES:DI POINTS TO LOAD LOCATION
1373 MOV BX,DS:WORD PTR [53AH] ; CLUS=*53A;
1374 POP DS ;
1375 MESSAGE FTESTINIT,<"LOAD DOS",CR,LF>
1376; BAS DEBUG
1377;LOADIT: MOV AX,(((END$ - START$)+15)/16)+SYSIZE
1378
1379LOADIT:
1380 MOV AX, OFFSET END$
1381 SUB AX, OFFSET START$
1382 ADD AX, 15
1383 RCR AX, 1 ; DIVIDE BY 16
1384 SHR AX, 1
1385 SHR AX, 1
1386 SHR AX, 1
1387 ADD AX, SYSIZE
1388
1389 ADD AX,CODE
1390
1391 MOV ES,AX ;
1392 CALL GETCLUS ; CLUS = GETCLUS (CLUS);
1393
1394ISEOF:
1395 TEST FBIGFAT,FBIG ; IF (FBIGFAT)
1396 JNZ EOFBIG
1397 MESSAGE FTESTINIT,<CR,LF,"SMALL FAT EOF CHECK",CR,LF>
1398 CMP BX,0FF7H ; RETURN (CLUS > 0FF7H);
1399 JMP SHORT ISEOFX
1400EOFBIG:
1401 MESSAGE FTESTINIT,<CR,LF,"BIG FAT EOF CHECK",CR,LF>
1402 CMP BX,0FFF7H ; ELSE
1403ISEOFX:
1404 JB LOADIT ; } WHILE (!ISEOF (CLUS));
1405
1406 CALL SETDRVPARMS
1407
1408 MESSAGE FTESTINIT,<"SYSINIT",CR,LF>
1409 ZWAIT
1410 MESSAGE FTESTINIT,<"ON TO SYSINIT...",CR,LF>
1411 JMP SYSINIT
1412
1413INIT ENDP
1414
1415;****************************
1416
1417Get_Para_Offset proc near
1418;in: AX - offset value
1419;out: AX - offset value adjusted for the next paragraph boundary.
1420 add ax, 15 ;make a paragraph
1421 rcr ax, 1
1422 shr ax, 1
1423 shr ax, 1
1424 shr ax, 1
1425 shl ax, 1 ;now, make it back to offset value
1426 shl ax, 1
1427 shl ax, 1
1428 shl ax, 1
1429 ret
1430Get_Para_Offset endp
1431
1432;AN004; Don't need this procedure. Get_FAT_Sector replace this.
1433; READ A FAT SECTOR INTO FAT LOCATION
1434;GETFAT PROC NEAR
1435; XOR DI,DI ; OFFSET
1436; MOV DX,1 ; RELATIVE SECTOR (1ST SECTOR OF FAT)
1437; MOV CX,FATLEN ; READ ENTIRE FAT.
1438; MOV AX,FATLOC ;
1439; MOV ES,AX ; LOCATION TO READ
1440; MOV AX,DRVFAT ; AH FAT ID BYTE, AL DRIVE
1441; JMP DISKRD
1442;GETFAT ENDP
1443
1444; READ A BOOT RECORD INTO 7C0:BOOTBIAS
1445;AN015; Read a boot record into Init_BootSeg:BOOTBIAS
1446
1447GETBOOT PROC NEAR
1448;SB33026****************************************************************
1449 mov AX, cs:Init_BootSeg ; prepare to load ES
1450 mov ES, AX ;SB ; load ES segment register
1451 assume es:nothing
1452 mov BX, BootBias ;SB ; load BX, ES:BX is where sector goes
1453 mov AX, 0201h ;SB ; command to read & num sec. to 1
1454 xor DH, DH ;SB ; head number zero
1455 mov CX, 0001h ;SB ; cylinder zero and sector one
1456 int 13h ;SB ; call rom bios
1457;SB33026****************************************************************
1458 JC ERRET
1459
1460 CMP WORD PTR ES:[BOOTBIAS+1FEH],0AA55H ; DAVE L**** MAGIC BYTE?
1461 JZ NORM_RET
1462 MESSAGE FTESTHARD,<"SIGNATURE AA55 NOT FOUND",CR,LF>
1463ERRET:
1464 MESSAGE FTESTHARD,<"ERROR IN GETBOOT",CR,LF>
1465 STC
1466NORM_RET:
1467 RET
1468GETBOOT ENDP
1469
1470; SETHARD - GENERATE BPB FOR A VARIABLE SIZED HARD FILE. IBM HAS A
1471; PARTITIONED HARD FILE; WE MUST READ PHYSICAL SECTOR 0 TO DETERMINE WHERE
1472; OUR OWN LOGICAL SECTORS START. WE ALSO READ IN OUR BOOT SECTOR TO
1473; DETERMINE VERSION NUMBER
1474
1475; INPUTS: DL IS ROM DRIVE NUMBER (80 OR 81)
1476; DS:DI POINTS TO BDS
1477; OUTPUTS: CARRY CLEAR -> BPB IS FILLED IN
1478; CARRY SET -> BPB IS LEFT UNINITIALIZED DUE TO ERROR
1479
1480SETHARD PROC NEAR
1481 assume ds:code,es:nothing
1482 PUSH DI
1483 PUSH BX
1484 PUSH DS
1485 MOV BYTE PTR [DI].DRIVELET,BL
1486 MOV BYTE PTR [DI].DRIVENUM,DL
1487 XOR AX,AX
1488 OR AL,FNON_REMOVABLE
1489 OR WORD PTR [DI].FLAGS,AX
1490 MOV BYTE PTR [DI].FORMFACTOR,FFHARDFILE
1491 MOV FBIGFAT,0 ; ASSUME 12 BIT FAT
1492 PUSH DX
1493;SB33027***************************************************************
1494 mov AH, 8 ;SB ; set command to get drive parameters
1495 int 13h ;SB ; call rom-bios disk routine
1496;SB33027***************************************************************
1497; DH IS NUMBER OF HEADS-1
1498; DL IS NUMBER OF HARD DISKS ATTACHED
1499; LOW 6 BITS OF CL IS SECTORS/TRACK
1500; HIGH 2 BITS OF CL WITH CH ARE MAX # OF CYLINDERS
1501 INC DH ; GET NUMBER OF HEADS
1502 MOV BYTE PTR [DI].HDLIM,DH
1503 POP DX
1504 JC SETRET ; CARRY HERE MEANS NO HARD DISK
1505 AND CL,3FH ; EXTRACT NUMBER OF SECTORS/TRACK
1506 MOV BYTE PTR [DI].SECLIM,CL
1507 CALL GETBOOT ; IF (GETBOOT ())
1508 assume es:nothing
1509 JC SETRET ; RETURN -1;
1510 MOV BX,1C2H+BOOTBIAS ; P = &BOOT[0X1C2];
1511SET1:
1512 CMP BYTE PTR ES:[BX],1 ; WHILE (P->PARTITIONTYPE != 1 &&
1513 JZ SET2
1514
1515 CMP BYTE PTR ES:[BX],4 ; P->PARTITIONTYPE != 4 &&
1516 JZ SET2
1517
1518;SB34INIT006******************************************************************
1519;SB we have a new partition type 6 now. add code to support this too.
1520
1521 cmp byte ptr es:[bx],6 ; P->PARTITIONTYPE !=6
1522 jz set2
1523;SB34INIT006******************************************************************
1524
1525 ADD BX,16 ; P += SIZEOF PARTITION;
1526 CMP BX,202H+BOOTBIAS ; IF (P == &BOOT[0X202H])
1527 JNZ SET1 ; RETURN -1;}
1528
1529SETRET:
1530 STC ;AN000; Note: Partitiontype 6 means either
1531 JMP RET_HARD ;1).the partition has not been formatted yet, or
1532 ;2).(# of sectors before the partition +
1533 ; # of sectors in this partition) > word boundary
1534 ; i.e., needs 32 bit sector calculation, or
1535 ;3).the partition is not a FAT file system.
1536
1537;J.K. Until we get the real logical boot record and get the bpb,
1538;DRVLIM_H,DRVLIM_L will be used instead of DRVLIM for the convenience of
1539;the computation.
1540;At the end of this procedure, if a BPB information is gotten from
1541;the valid boot record, then we are going to use those BPB information
1542;without change.
1543;Otherwise, if (hidden sectors + total sectors) <= a word, then
1544;we will move DRVLIM_L to DRVLIM and zero out DRVLIM_L entry to make
1545;it a conventional BPB format.
1546
1547SET2:
1548; PUSH DX ;AN000;
1549 mov cs:ROM_drv_num, dl ;AN000; save the ROM BIOS drive number we are handling now.
1550
1551 MOV AX,WORD PTR ES:[BX+4] ;Hidden sectors
1552 MOV DX,WORD PTR ES:[BX+6]
1553
1554
1555 ;Decrement the sector count by 1 to make it zero based. Exactly 64k
1556 ;sectors should be allowed
1557 ;
1558 SUB AX,1 ; PTM 901 12/12/86 MT
1559 SBB DX,0 ; PTM 901 12/12/86 MT
1560
1561 ADD AX,WORD PTR ES:[BX+8] ;Sectors in Partition
1562 ADC DX,WORD PTR ES:[BX+10]
1563; JZ OKDRIVE
1564 jnc Okdrive ;AC000;
1565 MESSAGE FTESTHARD,<"PARTITION INVALID",CR,LF>
1566 OR FBIGFAT,FTOOBIG
1567OKDRIVE:
1568; POP DX
1569 MOV AX,WORD PTR ES:[BX+4]
1570
1571 MOV [DI].HIDSEC_L,AX ; BPB->HIDSECCT = P->PARTITIONBEGIN;
1572 mov ax,word ptr es:[bx+6] ;AN000;
1573 mov [di].HIDSEC_H,ax ;AN000;
1574
1575 mov dx,word ptr es:[bx+10] ;AN000; # of sectors (High)
1576 MOV AX,WORD PTR ES:[BX+8] ;# of sectors (Low)
1577 mov word ptr [di].DRVLIM_H,dx ;AN000;
1578 MOV WORD PTR [DI].DRVLIM_L,AX ; BPB->MAXSEC = P->PARTITIONLENGTH;
1579 cmp dx,0 ;AN000;
1580 ja OKDrive_Cont ;AN000;
1581 CMP AX,64 ; IF (P->PARTITIONLENGTH < 64)
1582 JB SETRET ; RETURN -1;
1583
1584OKDrive_Cont: ;AN000;
1585 ; PUSH DX ;AC000;
1586 mov dx,[di].HIDSEC_H ;AN000;
1587 MOV AX,[DI].HIDSEC_L ; BOOT SECTOR NUMBER - For mini disk,;J.K.
1588; XOR DX,DX ; this will be logical and equal to ;AC000;
1589 xor bx,bx ;usUally equal to the # of sec/trk. ;J.K.
1590; MOV BH,DH ;AC000;
1591 MOV BL,BYTE PTR [DI].SECLIM
1592 push ax ;AN000;
1593 mov ax,dx ;AN000;
1594 xor dx,dx ;AN000;
1595 div bx ;AN000;
1596 mov cs:[Temp_H],ax ;AN000;
1597 pop ax ;AN000;
1598 DIV BX ;(Sectors)DX;AX / (Seclim)BX =(Track) Temp_H;AX + (Sector)DX
1599 MOV CL,DL ; CL IS SECTOR NUMBER;J.K.Assume sector number < 255.
1600 INC CL ; SECTORS ARE 1 BASED
1601; CWD ;AC000;
1602
1603 xor bx,bx ;AN000;
1604 MOV BL,BYTE PTR [DI].HDLIM
1605 push ax ;AN000;
1606 xor dx,dx ;AN000;
1607 mov ax, cs:[Temp_H] ;AN000;
1608 div bx ;AN000;
1609 mov cs:[Temp_H],ax ;AN000;
1610 pop ax ;AN000;
1611 DIV BX ; DL IS HEAD, AX IS CYLINDER
1612 cmp cs:[Temp_H],0 ;AN000;
1613 ja SetRet_brdg ;AN000; Exceeds the limit of Int 13h
1614 cmp ax, 1024 ;AN000;
1615 ja SetRet_brdg ;AN000; Exceeds the limit of Int 13h
1616
1617; DL IS HEAD.
1618; AX IS CYLINDER
1619; CL IS SECTOR NUMBER (assume less than 2**6 = 64 for INT 13h)
1620
1621;*** For Mini Disks *** J.K. 4/7/86
1622 cmp word ptr [di].ISMINI, 1 ;check for mini disk -J.K. 4/7/86
1623 jnz OKnotMini ;not mini disk. -J.K. 4/7/86
1624 add ax, [di].HIDDEN_TRKS ;set the physical track number -J.K. 4/7/86
1625OKnotMini: ;J.K. 4/7/86
1626;*** End of added logic for mini disk
1627 ROR AH,1 ; MOVE HIGH TWO BITS OF CYL TO HIGH
1628 ROR AH,1 ; TWO BITS OF UPPER BYTE
1629 AND AH,0C0H ; TURN OFF REMAINDER OF BITS
1630 OR CL,AH ; MOVE TWO BITS TO CORRECT SPOT
1631 MOV CH,AL ; CH IS CYLINDER
1632
1633; CL IS SECTOR + 2 HIGH BITS OF CYLINDER
1634; CH IS LOW 8 BITS OF CYLINDER
1635; DL IS HEAD
1636; ROM_drv_num IS DRIVE
1637
1638; POP AX ;AC000; AL IS DRIVE
1639 MOV DH,DL ; DH IS HEAD
1640; MOV DL,AL ;AC000; DL IS DRIVE
1641 mov dl, cs:ROM_drv_num ;AN000; Set the drive number
1642
1643; CL IS SECTOR + 2 HIGH BITS OF CYLINDER
1644; CH IS LOW 8 BITS OF CYLINDER
1645; DH IS HEAD
1646; DL IS DRIVE
1647;J.K. For convenience, we are going to read the logical boot sector
1648;into cs:DiskSector area.
1649
1650;SB34INIT009*************************************************************
1651;SB Read in boot sector using BIOS disk interrupt. The buffer where it
1652;SB is to be read in is cs:Disksector.
1653;SB 5 LOCS
1654
1655 push cs
1656 pop es
1657 mov bx,offset DiskSector
1658 mov ax,0201h ; read, one sector
1659 int 13h
1660
1661;SB34INIT009*************************************************************
1662
1663; cs:Disksec contains THE BOOT SECTOR. IN THEORY, (HA HA) THE BPB IN THIS THING
1664; IS CORRECT. WE CAN, THEREFORE, SUCK OUT ALL THE RELEVANT STATISTICS ON THE
1665; MEDIA IF WE RECOGNIZE THE VERSION NUMBER.
1666 mov bx, offset DiskSector ;AN000;
1667; look for a signature for msdos...
1668 cmp word ptr cs:[bx+3], "S" shl 8 + "M"
1669 jnz notmssig
1670 cmp word ptr cs:[bx+5], "O" shl 8 + "D"
1671 jnz notmssig
1672 cmp byte ptr cs:[bx+7], "S"
1673 je sigfound
1674; ...or perhaps pcdos...
1675notmssig:
1676 CMP WORD PTR cs:[bx+3], "B" SHL 8 + "I"
1677 jnz notibmsig
1678 CMP WORD PTR cs:[bx+5], " " SHL 8 + "M"
1679 je sigfound
1680;----------------------------------------------------------------------
1681; check for Microsoft OS/2 signature also. 7/29/88. HKN
1682notibmsig:
1683 CMP WORD PTR cs:[bx+3], "S" SHL 8 + "O"
1684 JNZ UNKNOWNJ
1685 CMP WORD PTR cs:[bx+5], " " SHL 8 + "2"
1686 JNZ UNKNOWNJ
1687;-----------------------------------------------------------------------
1688
1689sigfound: ; signature was found, now check version
1690 CMP WORD PTR cs:[bx+8], "." SHL 8 + "2"
1691 JNZ TRY5
1692 CMP BYTE PTR cs:[bx+10], "0"
1693 JNZ TRY5
1694 MESSAGE FTESTHARD,<"VERSION 2.0 MEDIA",CR,LF>
1695 JMP SHORT COPYBPB
1696
1697SetRet_Brdg:
1698 jmp SETRET
1699
1700UNKNOWNJ:
1701 JMP UNKNOWN ;Unformatted or illegal media.
1702UNKNOWN3_0_J: ;AN012;Legally formatted media,
1703 jmp Unknown3_0 ;AN012; although, content might be bad.
1704
1705TRY5:
1706 call Cover_Fdisk_Bug ;AN010;
1707 CMP WORD PTR cs:[bx+8],"." SHL 8 + "3"
1708 jb Unknown3_0_J ;AN012; Must be 2.1 boot record. Do not trust it, but still legal.
1709 JNZ COPYBPB ;AN007; Honor OS2 boot record, or DOS 4.0 version
1710 cmp byte ptr cs:[bx+10],"1" ;do not trust 3.0 boot record. But still legal J.K. 4/15/86
1711 jb UnKnown3_0_J ;AN012; if version >= 3.1, then O.K.
1712 Message ftestHard,<"VERSION 3.1 OR ABOVE MEDIA",CR,LF>
1713
1714COPYBPB:
1715; WE HAVE A VALID BOOT SECTOR. USE THE BPB IN IT TO BUILD THE
1716; BPB IN BIOS. IT IS ASSUMED THAT ONLY SECPERCLUS, CDIR, AND
1717; CSECFAT NEED TO BE SET (ALL OTHER VALUES IN ALREADY). FBIGFAT
1718; IS ALSO SET.
1719
1720;If it is non FAT based system, then just copy the BPB from the BOOT sector
1721;into the BPB in BDS table, and also set the Boot serial number, Volume id,
1722;and System ID according to the Boot record.
1723;For the non_FAT system, don't need to set the other value. So just
1724;do GOODRET.- J.K.
1725
1726 cmp cs:[Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN000;
1727 jne COPYBPB_FAT ;AN000; Conventional Fat system
1728 cmp cs:[NumberOfFats], 0 ;AN000; If (# of FAT <> 0) then
1729 jne COPYBPB_FAT ;AN000; a Fat system.
1730;J.K. Non Fat based media.
1731 push di ;AN000; Sav Reg.
1732 push ds ;AN000;
1733
1734 push ds ;AN000;
1735 pop es ;AN000; now es:di -> bds
1736 push cs ;AN000;
1737 pop ds ;AN000; ds = cs
1738
1739 mov si, offset Bpb_In_Sector ;AN000; ds:si -> BPB in Boot
1740 add di, BYTEPERSEC ;AN000; es:di -> BPB in BDS
1741 mov cx, size BPB_TYPE ;AN000;
1742 rep movsb ;AN000;
1743
1744 pop ds ;AN000; Restore Reg.
1745 pop di ;AN000;
1746 call Mov_Media_IDs ;AN000; Set Volume id, SystemId, Serial.
1747 jmp GoodRet
1748
1749COPYBPB_FAT: ;AN000; Fat system
1750 xor dx,dx ;AN000;
1751 mov si, offset Bpb_In_Sector ;AN000; cs:bx -> bpb in boot
1752 mov ax, cs:[si.SECNUM] ;AN000; total sectors
1753 cmp ax,0 ;AN000; double word sector number?
1754 jnz Fat_Big_Small ;AN000; No. Conventional BPB.
1755 mov ax, word ptr cs:[si.SECNUM_L] ;AN000; Use double word
1756 mov dx, word ptr es:[si.SECNUM_H] ;AN000;
1757
1758Fat_Big_Small: ;AN000; Determine Fat entry size.
1759;At this moment DX;AX = Total sector number
1760; DEC AX ; SUBTRACT # RESERVED (ALWAYS 1)
1761 sub ax,1 ;AN000; Subtrack # reserved (always 1)
1762 sbb dx,0 ;AN000;
1763 mov bx, cs:[si.FATSIZE] ;AN000; BX = Sectors/Fat
1764 mov [di.CSECFAT],bx ;AN000; Set in BDS BPB
1765 shl bx,1 ;AN000; Always 2 FATS
1766 sub ax,bx ;AN000; Sub # fat sectors
1767 sbb dx,0 ;AN000;
1768 mov bx, cs:[si.DIRNUM] ;AN000; # root entries
1769 mov [di.cDIR],bx ;AN000; Set in BDS BPB
1770
1771 MOV CL,4
1772 shr bx,cl ;AN000; Div by 16 ents/sector
1773 sub ax,bx ;AN000; sub # dir sectors
1774 sbb dx,0 ;AN000;
1775 ;AN000; DX;AX now contains the # of data sectors
1776 xor cx,cx ;AN000;
1777 MOV CL, cs:[si.SECALL] ; SECTORS PER CLUSTER
1778 MOV [DI.SECPERCLUS],CL ; SET IN BIOS BPB
1779; XOR DX,DX
1780; MOV CH,DH
1781 MNUM FTESTHARD,CX
1782 MESSAGE FTESTHARD,<" SECPERCLUS",CR,LF>
1783;J.K. 3/16/87 P54 Returning back to old logic for compatibility reason.
1784;So, use the old logic again that once had been commented out!!!!!!!!!!!!
1785;Old logic to determine FAT Entry Size J.K. 12/3/86
1786 push ax ;AN000;
1787 mov ax,dx ;AN000;
1788 xor dx,dx ;AN000;
1789 div cx ;AN000; cx = sectors per cluster
1790 mov cs:[Temp_H],ax ;AN000;
1791 pop ax ;AN000;
1792 DIV CX ;AN000; [Temp_H];AX NOW CONTAINS THE # CLUSTERS.
1793 cmp cs:[Temp_H],0 ;AN000;
1794 ja TooBig_Ret ;AN000; Too big cluster number
1795 CMP AX,4096-10 ; IS THIS 16-BIT FAT?
1796 JB CopyMediaID ; NO, small FAT
1797 OR FBIGFAT,FBIG ; 16 BIT FAT
1798;End of Old logic
1799CopyMediaID:
1800 call Mov_Media_IDs ;AN000; Copy Filesys_ID, Volume label,
1801 ;and Volume serial to BDS table, if extended
1802 ;boot record.
1803 JMP Massage_bpb ;AN000; Now final check for BPB info. and return.
1804
1805TooBig_Ret: ;AN000;
1806 OR cs:FBIGFAT,FTOOBIG
1807 JMP GOODRET ;AN000; Still drive letter is assigned
1808 ;AN000; But useless. To big for
1809 ;AN000; current PC DOS FAT file system
1810UNKNOWN:
1811; or [di].FLAGS, UNFORMATTED_MEDIA ;AN005; Set unformatted media flag.
1812 ; preceeding line commented out 10/88 by MRW-- The boot signature
1813 ; may not be recognizable, but we should TRY and read it anyway.
1814 ;AN006;
1815 ;AN008; For the time being, allow it.
1816 ;AN009; Now implemented again
1817Unknown3_0: ;AN012;Skip setting UNFORMATTED_MEDIA bit
1818 MESSAGE FTESTHARD,<"UNKNOWN HARD MEDIA. ASSUMING 3.0.",CR,LF>
1819 mov dx, [di.DRVLIM_H] ;AN000;
1820 mov ax, [di.DRVLIM_L] ;AN000;
1821 MOV SI,OFFSET DISKTABLE2
1822SCAN:
1823; CMP AX,[SI]
1824; JBE GOTPARM
1825; ADD SI,4 * 2
1826
1827 cmp dx, word ptr cs:[si] ;AN000;
1828 jb GotParm ;AN000;
1829 ja Scan_Next ;AN000;
1830 cmp ax, word ptr cs:[si+2] ;AN000;
1831 jbe GotParm ;AN000;
1832Scan_Next: ;AN000;
1833 add si, 5 * 2 ;AN000;
1834 JMP SCAN ;AN000; Covers upto 512 MB media
1835GOTPARM:
1836; MOV CL,BYTE PTR [SI+6]
1837 mov cl,byte ptr [si+8] ;AN000; Fat size for FBIGFAT flag
1838 OR FBIGFAT,CL
1839; MOV CX,[SI+2]
1840; MOV DX,[SI+4]
1841 mov cx, word ptr cs:[SI+4] ;AN000;
1842 mov dx, word ptr cs:[SI+6] ;AN000;
1843
1844; DX = NUMBER OF DIR ENTRIES,
1845; CH = NUMBER OF SECTORS PER CLUSTER
1846; CL = LOG BASE 2 OF CH
1847
1848; NOW CALCULATE SIZE OF FAT TABLE
1849
1850 MNUM FTESTHARD,AX
1851 MESSAGE FTESTHARD,<" SECTORS ">
1852 MNUM FTESTHARD,DX
1853 MESSAGE FTESTHARD,<" DIRECTORY ENTRIES ">
1854 MNUM FTESTHARD,CX
1855 MESSAGE FTESTHARD,<" SECPERCLUS|CLUSSHIFT">
1856
1857 MOV WORD PTR CDIR[DI],DX ;SAVE NUMBER OF DIR ENTRIES
1858
1859;Now, CX = SecPerClus|Clusshift
1860; [DI.CDIR] = number of directory entries.
1861
1862 mov dx, [di.DRVLIM_H] ;AN000;
1863 mov ax, [di.DRVLIM_L] ;AN000;
1864 MOV BYTE PTR SECPERCLUS[DI],CH ;SAVE SECTORS PER CLUSTER
1865 TEST FBIGFAT,FBIG ; IF (FBIGFAT)
1866 JNZ DOBIG ; GOTO DOBIG;
1867 MESSAGE FTESTHARD,<" SMALL FAT",CR,LF>
1868;J.K. We don't need to change "small fat" logic since it is gauranteed
1869;that double word total sector will not use 12 bit fat (unless
1870;it's sectors/cluster >= 16 which will never be in this case.)
1871;So in this case we assume DX = 0 !!!.
1872
1873 XOR BX,BX
1874 MOV BL,CH
1875 DEC BX
1876 ADD BX,AX ;AN000; DX=0
1877 SHR BX,CL ; BX = 1+(BPB->MAXSEC+SECPERCLUS-1)/
1878 INC BX ; SECPERCLUS
1879 AND BL,11111110B ; BX &= ~1; (=NUMBER OF CLUSTERS)
1880 MOV SI,BX
1881 SHR BX,1
1882 ADD BX,SI
1883 ADD BX,511 ; BX += 511 + BX/2
1884 SHR BH,1 ; BH >>= 1; (=BX/512)
1885 MOV BYTE PTR [DI].CSECFAT,BH ;SAVE NUMBER OF FAT SECTORS
1886 JMP SHORT Massage_BPB
1887DOBIG:
1888;J.K. For BIGFAT we do need to extend this logic to 32 bit sector calculation.
1889 MESSAGE FTESTHARD,<" BIG FAT",CR,LF>
1890 MOV CL,4 ; 16 (2^4) DIRECTORY ENTRIES PER SECTOR
1891 push dx ;AN000; Save total sectors (high)
1892 mov dx, CDIR[DI] ;AN000;
1893 SHR DX,CL ; CSECDIR = CDIR / 16;
1894 SUB AX,DX ; DX;AX -= CSECDIR; DX;AX -= CSECRESERVED;
1895 pop dx ;AN000;
1896 SBB dx,0 ;AN000;
1897; DEC AX ; AX = T - R - D
1898 SUB ax,1 ;AN000; DX;AX = T - R - D
1899 SBB dx,0 ;AN000;
1900 MOV BL,2
1901 MOV BH,SECPERCLUS[DI] ; BX = 256 * SECPERCLUS + 2
1902; XOR DX,DX
1903;J.K. I don't understand why to add BX here!!!
1904 ADD AX,BX ; AX = T-R-D+256*SPC+2
1905 ADC DX,0
1906 SUB AX,1 ; AX = T-R-D+256*SPC+1
1907 SBB DX,0
1908;J.K. Assuming DX in the table will never be bigger than BX.
1909 DIV BX ; CSECFAT = CEIL((TOTAL-DIR-RES)/
1910 ; (256*SECPERCLUS+2));
1911 MOV WORD PTR [DI].CSECFAT,AX ; NUMBER OF FAT SECTORS
1912;J.K. Now, set the default FileSys_ID, Volume label, Serial number
1913 MOV BL,FBIGFAT
1914 MOV [DI].FATSIZ,BL ; SET SIZE OF FAT ON MEDIA
1915 call Clear_IDs ;AN000;
1916
1917;J.K. At this point, in BPB of BDS table, DRVLIM_H,DRVLIM_L which were
1918;set according to the partition information. We are going to
1919;see if (hidden sectors + total sectors) > a word. If it is true,
1920;then no change. Otherwise, DRVLIM_L will be moved to DRVLIM
1921;and DRVLIM_L will be set to 0.
1922;We don't do this for the bpb information from the boot record. We
1923;are not going to change the BPB information from the boot record.
1924Massage_bpb: ;AN000;
1925 mov dx, [di.DRVLIM_H] ;AN000;
1926 mov ax, [di.DRVLIM_L] ;AN000;
1927 cmp dx,0 ;AN000; Double word total sector?
1928 ja GOODRET ;AN000; don't have to change it.
1929 cmp [di.HIDSEC_H], 0 ;AN000;
1930 ja GOODRET ;AN000; don't have to change it.
1931 add ax, [di.HIDSEC_L] ;AN000;
1932 jc GOODRET ;AN000; bigger than a word boundary
1933 mov ax, [di.DRVLIM_L] ;AN000;
1934 mov [di.DRVLIM], ax ;AN000;
1935 mov [di.DRVLIM_L], 0 ;AN000;
1936GOODRET:
1937 cmp [di].DRVLIM_H, 0 ;AN014; Big media?
1938 jbe Not_BigMedia ;AN014; No.
1939 push es ;AN014;
1940 push ax ;AN014;
1941 mov ax, SYSINITSEG ;AN014;
1942 mov es, ax ;AN014;
1943 mov es:Big_Media_Flag, 1 ;AN014; Set the flag in SYSINITSEG.
1944 pop ax ;AN014;
1945 pop es ;AN014;
1946Not_BigMedia: ;AN014;
1947 MOV BL,FBIGFAT
1948 MOV [DI].FATSIZ,BL ; SET SIZE OF FAT ON MEDIA
1949 CLC
1950RET_HARD:
1951 POP DS
1952 POP BX
1953 POP DI
1954 RET
1955
1956SETHARD ENDP
1957
1958Cover_FDISK_Bug proc ;AN010;
1959;FDISK of PC DOS 3.3 and below, OS2 1.0 has a bug. The maximum number of
1960;sector that can be handled by PC DOS 3.3 ibmbio should be 0FFFFh.
1961;Instead, sometimes FDISK use 10000h to calculate the maximum number.
1962;So, we are going to check that if SECNUM + Hidden sector = 10000h
1963;then subtrack 1 from SECNUM.
1964 push ax ;AN010;
1965 push dx ;AN010;
1966 push si ;AN010;
1967 cmp cs:[Ext_Boot_Sig], EXT_BOOT_SIGNATURE ;AN010;
1968 je CFB_Retit ;AN010;if extended BPB, then >= PC DOS 4.00
1969 cmp word ptr cs:[bx+7], "0" shl 8 + "1" ;AN011; OS2 1.0 ? = IBM 10.0
1970 jne CFB_Chk_SECNUM ;AN010;
1971 cmp byte ptr cs:[bx+10], "0" ;AN010;
1972 jne CFB_Retit ;AN010;
1973CFB_Chk_SECNUM: ;AN010;
1974 mov si, offset BPB_In_Sector ;AN010;
1975 cmp cs:[si.SECNUM], 0 ;AN010;Just to make sure.
1976 je CFB_Retit ;AN010;
1977 mov ax, cs:[si.SECNUM] ;AN010;
1978 add ax, cs:[si.HIDDEN_L] ;AN010;
1979 jnc CFB_Retit ;AN010;
1980 xor ax, ax ;AN010;if carry set and AX=0?
1981 jnz CFB_Retit ;AN010;
1982 dec cs:[si.SECNUM] ;AN010; then decrease SECNUM by 1.
1983 dec [di].DRVLIM_L ;AN010;
1984CFB_Retit: ;AN010;
1985 pop si ;AN010;
1986 pop dx ;AN010;
1987 pop ax ;AN010;
1988 ret ;AN010;
1989Cover_FDISK_Bug endp ;AN010;
1990
1991
1992; SETDRVPARMS SETS UP THE RECOMMENDED BPB IN EACH BDS IN THE SYSTEM BASED ON
1993; THE FORM FACTOR. IT IS ASSUMED THAT THE BPBS FOR THE VARIOUS FORM FACTORS
1994; ARE PRESENT IN THE BPBTABLE. FOR HARD FILES, THE RECOMMENDED BPB IS THE SAME
1995; AS THE BPB ON THE DRIVE.
1996
1997; NO ATTEMPT IS MADE TO PRESERVE REGISTERS SINCE WE ARE GOING TO JUMP TO
1998; SYSINIT STRAIGHT AFTER THIS ROUTINE.
1999
2000SETDRVPARMS PROC NEAR
2001 MESSAGE FTESTINIT,<"SETTING DRIVE PARAMETERS",CR,LF>
2002 XOR BX,BX
2003 LES DI,DWORD PTR CS:[START_BDS] ; GET FIRST BDS IN LIST
2004NEXT_BDS:
2005 CMP DI,-1
2006 JNZ DO_SETP
2007DONE_SETPARMS:
2008 RET
2009
2010DO_SETP:
2011 PUSH ES
2012 PUSH DI ; PRESERVE POINTER TO BDS
2013 MOV BL,ES:[DI].FORMFACTOR
2014 CMP BL,FFHARDFILE
2015 JNZ NOTHARDFF
2016
2017 xor dx,dx ;AN000;
2018 MOV AX,ES:[DI].DRVLIM
2019 cmp ax,0 ;AN000;
2020 jne GET_cCYL ;AN000;
2021 mov dx,es:[di].DRVLIM_H ;AN000; Use Double word sector number
2022 MOV AX,ES:[DI].DRVLIM_L ;AN000;
2023GET_cCYL:
2024 push dx ;AN000;
2025 PUSH AX
2026 MOV AX,WORD PTR ES:[DI].HDLIM
2027 MUL WORD PTR ES:[DI].SECLIM ;Assume Sectorsp per cyl. < 64K.
2028 MOV CX,AX ; CX HAS # SECTORS PER CYLINDER
2029 POP AX ;
2030 pop dx ;AN000; Restore drvlim.
2031 push ax ;AN000;
2032 mov ax,dx ;AN000;
2033 xor dx,dx ;AN000;
2034 div cx ;AN000;
2035 mov cs:[Temp_H],ax ;AN000; AX be 0 here.
2036 pop ax ;AN000;
2037 DIV CX ; DIV #SEC BY SEC/CYL TO GET # CYL.
2038 OR DX,DX
2039 JZ NO_CYL_RND ; CAME OUT EVEN
2040 INC AX ; ROUND UP
2041NO_CYL_RND:
2042 MOV ES:[DI].CCYLN,AX
2043 MESSAGE FTESTINIT,<"CCYLN ">
2044 MNUM FTESTINIT,AX
2045 MESSAGE FTESTINIT,<CR,LF>
2046 PUSH ES
2047 POP DS
2048 LEA SI,[DI].BYTEPERSEC ; DS:SI -> BPB FOR HARD FILE
2049 JMP SHORT SET_RECBPB
2050
2051NOTHARDFF:
2052;J.K. We don't use the extended BPB for a floppy.
2053 PUSH CS
2054 POP DS
2055 assume ds:code
2056;J.K.6/24/87
2057
2058;SB34INIT007******************************************************************
2059;SB If Fake floppy drive variable is set then we don't have to handle this
2060;SB BDS. We can just go and deal with the next BDS at label Go_To_Next_BDS.
2061
2062 cmp cs:FakeFloppyDrv,1
2063 jz Go_To_Next_BDS
2064;SB34INIT007******************************************************************
2065
2066 CMP BL,FFOTHER ; SPECIAL CASE "OTHER" TYPE OF MEDIUM
2067 JNZ NOT_PROCESS_OTHER
2068PROCESS_OTHER:
2069 XOR DX,DX
2070 MOV AX,[DI].CCYLN
2071 MOV BX,[DI].RHDLIM
2072 MUL BX
2073 MOV BX,[DI].RSECLIM
2074 MUL BX
2075 MOV [DI].RDRVLIM,AX ; HAVE THE TOTAL NUMBER OF SECTORS
2076 DEC AX
2077
2078;J.K. Old logic was...
2079; MOV BX,515
2080; DIV BX
2081; OR DX,DX
2082; JZ NO_ROUND_UP
2083; INC AX ; ROUND UP NUMBER OF FAT SECTORS
2084
2085;J.K. New logic to get the sectors/fat area.
2086 ;Fat entry is assumed to be 1.5 bytes!!!
2087 mov bx, 3
2088 mul bx
2089 mov bx,2
2090 div bx
2091 xor dx, dx
2092 mov bx, 512
2093 div bx
2094 inc ax
2095
2096NO_ROUND_UP:
2097 MOV [DI].RCSECFAT,AX
2098 JMP SHORT GO_TO_NEXT_BDS
2099NOT_PROCESS_OTHER:
2100 SHL BX,1 ; BX IS WORD INDEX INTO TABLE OF BPBS
2101 MOV SI,OFFSET BPBTABLE
2102 MOV SI,WORD PTR [SI+BX] ; GET ADDRESS OF BPB
2103SET_RECBPB:
2104 LEA DI,[DI].RBYTEPERSEC ; ES:DI -> RECBPB
2105 MOV CX,BPBSIZ
2106 REP MOVSB ; MOVE BPBSIZ BYTES
2107GO_TO_NEXT_BDS:
2108 POP DI
2109 POP ES ; RESTORE POINTER TO BDS
2110 MOV BX,WORD PTR ES:[DI].LINK+2
2111 MOV DI,WORD PTR ES:[DI].LINK
2112 MOV ES,BX
2113 JMP NEXT_BDS
2114
2115SETDRVPARMS ENDP
2116
2117; READ CLUSTER SPECIFIED IN BX
2118; CX = SECTORS PER CLUSTER
2119; DI = LOAD LOCATION
2120;
2121GETCLUS PROC NEAR
2122 PUSH CX
2123 PUSH DI
2124 MOV DOSCNT,CX ;SAVE NUMBER OF SECTORS TO READ
2125 MOV AX,BX
2126 DEC AX
2127 DEC AX
2128 MUL CX ;CONVERT TO LOGICAL SECTOR
2129;J.K. Now DX;AX = matching logical sector number starting from the data sector.
2130;SB34INIT008*************************************************************
2131;SB Add the BIOS start sector to the sector number in DX:AX. The BIOS
2132;SB start sector number is in BIOS$_H:BIOS$_L
2133
2134 add ax,cs:BIOS$_L
2135 adc dx,cs:BIOS$_H
2136;SB34INIT008*************************************************************
2137;J.K. Now DX;AX = first logical sector to read
2138; MOV DX,AX ;DX = FIRST SECTOR TO READ
2139GETCL1:
2140 MNUM FTESTINIT
2141 MESSAGE FTESTINIT,<" => ">
2142; ;SI = BX, BX = NEXT ALLOCATION UNIT
2143
2144; GET THE FAT ENTRY AT BX
2145
2146UNPACK:
2147 PUSH DS
2148 push ax ;AN004;Save First logical sector (Low)
2149 PUSH BX
2150 MOV SI,FATLOC
2151 MOV DS,SI ;DS -> FATLOC segment
2152 mov si, bx ;AN004;
2153 TEST cs:FBIGFAT,FBIG ;16 bit fat?
2154 JNZ UNPACK16
2155; MOV SI,BX
2156 SHR SI,1 ;12 bit fat. si=si/2
2157 add si, bx ;AN004; si = clus + clus/2
2158 call Get_Fat_Sector ;AN004; offset of FAT entry in BX
2159 mov ax, [bx] ;AN004;Save it into AX
2160 jne Even_Odd ;AN004;IF not a splitted FAT, check even-odd.
2161 mov al, byte ptr [bx] ;AN004;Splitted FAT.
2162 mov byte ptr cs:Temp_Cluster, al ;AN004;
2163 inc si ;AN004;
2164 call Get_Fat_Sector ;AN004;
2165 mov al, byte ptr ds:[0] ;AN004;
2166 mov byte ptr cs:Temp_Cluster+1, al ;AN004;
2167 mov ax, cs:Temp_Cluster ;AN004;
2168Even_Odd: ;AN004;
2169 pop bx ;AN004;Restore old Fat entry value
2170 push bx ;AN004;Save it right away.
2171 shr bx, 1 ;AN004;Was it even or odd?
2172 jnc HAVCLUS ;It was even.
2173 SHR ax,1 ;Odd. Massage FAT value and keep
2174 SHR ax,1 ;the highest 12 bits.
2175 SHR ax,1
2176 SHR ax,1
2177HAVCLUS:
2178 mov bx, ax ;AN004; Now BX = New FAT entry.
2179 AND BX,0FFFH ;AN004; keep low 12 bits.
2180 JMP SHORT UNPACKX
2181UNPACK16: ;16 bit fat.
2182 shl si, 1 ;Get the offset value.
2183 call Get_Fat_Sector ;AN004;
2184 mov bx, [bx] ;AN004; Now BX = New FAT entry.
2185UNPACKX:
2186 POP SI ;Retore Old BX value into SI
2187 pop ax ;AN004;Restore logical sector (low)
2188 POP DS
2189
2190 MNUM FTESTINIT
2191 MESSAGE FTESTINIT,<" ">
2192 SUB SI,BX
2193 CMP SI,-1 ;ONE APART?
2194 JNZ GETCL2
2195 ADD DOSCNT,CX
2196 JMP GETCL1
2197
2198GETCL2:
2199 PUSH BX
2200 push dx ;AN000; Sector to read (High)
2201 push ax ;AN000; Sector to read (low)
2202 MOV AX,DRVFAT ;GET DRIVE AND FAT SPEC
2203 MOV CX,DOSCNT
2204 pop dx ;AN000; Sector to read for DISKRD (Low)
2205 pop cs:[Start_Sec_H] ;AN000; Sector to read for DISKRD (High)
2206 CALL DISKRD ;READ THE CLUSTERS
2207
2208 POP BX
2209 POP DI
2210 MOV AX,DOSCNT ;GET NUMBER OF SECTORS READ
2211 XCHG AH,AL ;MULTIPLY BY 256
2212 SHL AX,1 ;TIMES 2 EQUAL 512
2213 ADD DI,AX ;UPDATE LOAD LOCATION
2214 POP CX ;RESTORE SECTORS/CLUSTER
2215 RET
2216
2217GETCLUS ENDP ; RETURN;
2218
2219Get_FAT_Sector proc near ;AN004;
2220;Function: FInd and read the corresponding FAT sector into DS:0
2221;In). SI - offset value (starting from FAT entry 0) of FAT entry to find.
2222; DS - FATLOC segment
2223; cs:DRVFAT - Logical drive number, FAT id
2224; cs:Md_SectorSize
2225; cs:Last_Fat_SecNum - Last FAT sector number read in.
2226;Out). Corresponding FAT sector read in.
2227; BX = offset value from FATLOG segment.
2228; Other registera saved.
2229; Zero flag set if the FAT entry is splitted, i.e., wehn 12 bit FAT entry
2230; starts at the last byte of the FAT sector. In this case, the caller
2231; should save this byte, and read the next FAT sector to get the rest
2232; of the FAT entry value. (This will only happen with the 12 bit fat.)
2233
2234 push ax ;AN004;
2235 push cx ;AN004;
2236 push dx ;AN004;
2237 push di ;AN004;
2238 push si ;AN004;
2239 push es ;AN004;
2240 push ds ;AN004;
2241 xor dx, dx ;AN004;
2242 mov ax, si ;AN004;
2243 mov cx, cs:Md_SectorSize ;AN004; =512 bytes
2244 div cx ;AN004; AX=sector number, dx = offset
2245 inc ax ;AN004; Make AX to relative logical sector number
2246 cmp ax, cs:Last_Fat_SecNum ;AN004; by adding Reserved sector number.
2247 je GFS_Split_Chk ;AN004; Don't need to read it again.
2248 mov cs:Last_Fat_SecNum, ax ;AN004; Update Last_Fat_SecNum
2249 push dx ;AN004; save offset value.
2250 mov cs:[Start_Sec_H],0 ;AN004; Prepare to read the FAT sector
2251 mov dx, ax ;AN004; Start_Sec_H is always 0 for FAT sector.
2252 mov cx, 1 ;AN004; 1 sector to read
2253 mov ax, cs:DrvFAT ;AN004;
2254 push ds ;AN004;
2255 pop es ;AN004;
2256 xor di, di ;AN004; es:di -> FatLoc segment:0
2257 call DiskRD ;AN004; cross your finger.
2258 pop dx ;AN004; restore offset value.
2259 mov cx, cs:Md_SectorSize ;AN004;
2260GFS_Split_Chk: ;AN004;
2261 dec cx ;AN004;if offset points to the
2262 cmp dx, cx ;AN004;last byte of this sector, then splitted entry.
2263 mov bx, dx ;AN004;Set BX to DX
2264 pop ds ;AN004;
2265 pop es ;AN004;
2266 pop si ;AN004;
2267 pop di ;AN004;
2268 pop dx ;AN004;
2269 pop cx ;AN004;
2270 pop ax ;AN004;
2271 ret ;AN004;
2272Get_FAT_Sector endp ;AN004;
2273
2274;
2275; SI POINTS TO DEVICE HEADER
2276; J.K. 4/22/86 - print_init, aux_init is modified to eliminate the self-modifying
2277; J.K. code.
2278
2279PRINT_INIT:
2280 call Get_device_number
2281;SB33028*****************************************************************
2282 mov ah,1 ;initalize printer port ;SB;3.30
2283 int 17h ;call ROM-Bios routine ;SB;3.30
2284;SB33028*****************************************************************
2285 ret
2286
2287AUX_INIT:
2288 call Get_device_number
2289;SB33028*****************************************************************
2290 mov al,RSINIT ;2400,N,1,8 (MSEQU.INC) ;SB ;3.30*
2291 mov ah,0 ;initalize AUX port ;SB ;3.30*
2292 int 14h ;call ROM-Bios routine ;SB ;3.30*
2293;SB33028*****************************************************************
2294 ret
2295
2296GET_DEVICE_NUMBER:
2297;SI -> device header
2298 MOV AL,CS:[SI+13] ;GET DEVICE NUMBER FROM THE NAME
2299 SUB AL,"1"
2300 CBW
2301 MOV DX,AX
2302 RET
2303
2304;
2305; PURGE_96TPI NOP'S CALLS TO 96TPI SUPPORT.
2306;
2307PURGE_96TPI PROC NEAR ;MJB001
2308 PUSH DS
2309 PUSH ES
2310
2311 PUSH CS ;MJB001
2312 POP ES ;MJB001
2313 PUSH CS ;MJB001
2314 POP DS ;MJB001
2315 ASSUME DS:CODE,ES:CODE
2316
2317 MOV SI,OFFSET PATCHTABLE
2318PATCHLOOP:
2319 LODSW
2320 MOV CX,AX
2321 JCXZ PATCHDONE
2322 LODSW
2323 MOV DI,AX
2324 MOV AL,90H
2325 REP STOSB
2326 JMP PATCHLOOP
2327
2328PATCHDONE:
2329;**************NOT NEEDED ANY MORE***********************
2330; MOV DI,OFFSET FORMAT_PATCH ; ARR 2.42
2331; MOV AL,CS:INST_FAR_RET
2332; STOSB
2333;********************************************************
2334 MOV DI,OFFSET TABLE_PATCH ; ARR 2.42
2335 MOV AX,OFFSET EXIT
2336 STOSW
2337 STOSW
2338
2339 POP ES
2340 POP DS
2341 RET ;MJB001
2342PURGE_96TPI ENDP
2343
2344;Mini disk initialization routine. Called right after DoHard - J.K. 4/7/86
2345; DoMini **********************************************************************
2346; **CS=DS=ES=code
2347; **DoMini will search for every extended partition in the system, and
2348; initialize it.
2349; **BDSM stands for BDS table for Mini disk and located right after the label
2350; End96Tpi. End_Of_BDSM will have the offset value of the ending
2351; address of BDSM table.
2352; **BDSM is the same as usual BDS structure except that TIM_LO, TIM_HI entries
2353; are overlapped and used to identify mini disk and the number of Hidden_trks.
2354; Right now, they are called as IsMini, Hidden_Trks respectively.
2355; **DoMini will use the same routine in SETHARD routine after label SET1 to
2356; save coding.
2357; **DRVMAX determined in DoHard routine will be used for the next
2358; available logical mini disk drive number.
2359;
2360; Input: DRVMAX, DSKDRVS
2361;
2362; Output: MiniDisk installed. BDSM table established and installed to BDS.
2363; num_mini_dsk - the number of mini disks installed in the system.
2364; End_Of_BDSM - ending offset address of BDSM.
2365;
2366;
2367; Called modules:
2368; GetBoot, WRMSG, int 13h (AH=8, Rom)
2369; FIND_MINI_PARTITION (new), Install_BDSM (new),
2370; SetMini (new, it will use SET1 routine)
2371; Variables used: End_Of_BDSM, numh, mininum, num_mini_dsk,
2372; Rom_Minidsk_num, Mini_HDLIM, Mini_SECLIM
2373; BDSMs, BDSM_type (struc), Start_BDS
2374;******************************************************************************
2375;
2376
2377DoMini:
2378 push cs
2379 pop es
2380 push cs
2381 pop ds
2382 assume ds:code,es:code
2383 Message fTestHard,<"Start of DoMini...",cr,lf>
2384
2385 push ax ;Do I need to do this?
2386
2387 mov di, offset BDSMs ;from now on, DI points to BDSM
2388;SB33028********************************************************************
2389 mov dl, 80h ;look at first hard drive ;SB ;3.30*
2390 mov ah, 8h ;get drive parameters ;SB ;3.30*
2391 int 13h ;call ROM-Bios ;SB ;3.30*
2392;SB33028********************************************************************
2393 cmp dl, 0
2394 jz DoMiniRet ;no hard file? Then exit.
2395 mov numh, dl ;save the number of hard files.
2396 xor ax,ax
2397 mov al, drvmax
2398 mov mininum, al ;this will be the logical drive letter
2399 ;for mini disk to start with.
2400
2401 shl ax, 1 ;ax=number of devices. make it to word boundary
2402 push bx
2403 mov bx, offset DSKDRVS
2404 add bx, ax
2405 mov Mini_BPB_ptr, BX ;Mini_BPB_ptr points to the first available
2406 ;spot in DskDrvs for Mini disk which
2407 ;points to BPB area of BDSM.
2408 pop bx
2409
2410 mov Rom_Minidsk_num, 80h
2411DoMiniBegin:
2412 inc dh ;Get # of heads (convert it to 1 based)
2413 xor ax, ax
2414 mov al, dh
2415 mov Mini_HDLIM, ax ;save it.
2416 xor ax, ax
2417 and cl, 3fh ;Get # of sectors/track
2418 mov al, cl
2419 mov Mini_SECLIM, ax ;and save it.
2420
2421 mov dl, Rom_Minidsk_num ;drive number <DL>
2422 call GETBOOT ;read master boot record into 7c0:BootBias
2423 assume es:nothing
2424 jc DoMiniNext
2425 call FIND_MINI_PARTITION
2426DoMiniNext:
2427 dec numh
2428 jz DoMiniRet
2429 inc Rom_MiniDsk_Num ;Next hard file
2430;SB33028********************************************************************
2431 mov dl, Rom_MiniDsk_Num ;look at next hard drive ;SB ;3.30*
2432 mov ah, 8h ;get drive parameters ;SB ;3.30*
2433 int 13h ;call ROM-Bios ;SB ;3.30*
2434;SB33028********************************************************************
2435 jmp DoMiniBegin
2436
2437DoMiniRet:
2438 pop ax
2439 ret
2440
2441
2442;Find_Mini_Partition tries to find every Extended partition on a disk.
2443;At entry: DI -> BDSM entry
2444; ES:BX -> 07c0:BootBias - Master Boot Record
2445; Rom_MiniDsk_Num - ROM drive number
2446; MiniNum - Logical drive number
2447; Mini_HDLIM, Mini_SECLIM
2448;
2449;Called routine: SETMINI which uses SET1 (in SETHARD routine)
2450;Variables & equates used from original BIOS - flags, fNon_Removable, fBigfat
2451;
2452;
2453FIND_MINI_PARTITION:
2454
2455 add bx, 1C2h ;BX -> system id.
2456
2457FmpNext:
2458 cmp byte ptr ES:[BX], 5 ; 5 = extended partition ID.
2459 jz FmpGot
2460 add bx, 16 ; for next entry
2461 cmp bx, 202h+BootBias
2462 jnz FmpNext
2463 jmp FmpRet ;not found extended partition
2464
2465FmpGot: ;found my partition.
2466 Message ftestHard,<"Found my partition...",cr,lf>
2467 xor ax,ax
2468 or al, fNon_Removable
2469 or word ptr [DI].Flags, ax
2470 mov byte ptr [DI].FormFactor, ffHardFile
2471 mov fBigFat, 0 ;assume 12 bit Fat.
2472 mov ax, Mini_HDLIM
2473 mov [DI].HDLIM, ax
2474 mov ax, Mini_SECLIM
2475 mov [DI].SECLIM, ax
2476 mov al, Rom_MiniDsk_Num
2477 mov [DI].DRIVENUM, al ;set physical number
2478 mov al, Mininum
2479 mov [DI].DRIVELET, al ;set logical number
2480
2481 cmp word ptr es:[bx+10], 0 ;AN000;
2482 ja FmpGot_Cont ;AN000;
2483 cmp word ptr ES:[BX+8], 64 ;**With current BPB, only lower word
2484 ; is meaningful.
2485 jb FmpRet ;should be bigger than 64 sectors at least
2486FmpGot_Cont: ;AN000;
2487 sub bx, 4 ;let BX point to the start of the entry
2488 mov dh, byte ptr ES:[BX+2]
2489 and dh, 11000000b ;get higher bits of cyl
2490 rol dh, 1
2491 rol dh, 1
2492 mov dl, byte ptr ES:[BX+3] ;cyl byte
2493 mov [DI].HIDDEN_TRKS, dx ;set hidden trks
2494;** Now, read the volume boot record into BootBias.
2495;SB33029******************************************************************
2496 mov cx,ES:[BX+2] ;cylinder,cylinder/sector ;SB ;3.30*
2497 mov dh,ES:[BX+1] ;head ;SB ;3.30*
2498 mov dl,Rom_MiniDsk_Num ;drive ;SB ;3.30*
2499 mov bx,BOOTBIAS ;buffer offset ;SB ;3.30*
2500 mov ax,0201h ;read,1 sector ;SB ;3.30*
2501 int 13h ;call ROM-Bios routine ;SB ;3.30*
2502;SB33029******************************************************************
2503 jc FmpRet ;cannot continue.
2504 mov bx, 1c2h+BOOTBIAS
2505
2506 push es ;;DCL/KWC 8/2/87 addressability to
2507 ;; next minidisk
2508
2509 call SetMini ;install a mini disk. BX value saved.
2510
2511 pop es ;;DCL/KWC 8/2/87
2512
2513 jc FmpnextChain
2514
2515 call Install_BDSM ;install the BDSM into the BDS table
2516; call Show_Installed_Mini ;show the installed message. 3/35/86 - Don't show messages. J.K.
2517 inc mininum ;increase the logical drive number for next
2518 inc num_mini_dsk ;increase the number of mini disk installed.
2519
2520 push bx ;now, set the DskDrvs pointer to BPB info.
2521 mov bx, Mini_BPB_ptr
2522 lea si, [di].BYTEPERSEC ;points to BPB of BDSM
2523 mov [bx], si
2524 inc Mini_BPB_ptr ;advance to the next address
2525 inc Mini_BPB_ptr
2526 pop bx
2527
2528 add DI, type BDSM_type ;adjust to the next BDSM table entry.
2529 mov End_OF_BDSM, DI ;set the ending address of BDSM table to this.
2530; Message fTestHard,<"Mini disk installed.",cr,lf>
2531FmpnextChain: jmp FmpNext ;let's find out if we have any chained partition
2532FmpRet:
2533 ret
2534
2535SetMini:
2536 push di
2537 push bx
2538 push ds
2539 jmp SET1 ;will be returned to Find mini partition routine.
2540 ;Some logic has been added to SET1 to
2541 ;deal with Mini disks.
2542
2543;
2544;Install BDSM installs a BDSM (pointed by DS:DI) into the end of the current
2545;linked list of BDS.
2546;Also, set the current BDSM pointer segment to DS.
2547;At entry: DS:DI -> BDSM
2548;
2549Install_BDSM:
2550assume ds:code,es:nothing
2551 push ax
2552 push si
2553 push es
2554
2555 les si, dword ptr cs:Start_BDS ;start of the beginning of list
2556I_BDSM_Next:
2557 cmp word ptr es:[si], -1 ;end of the list?
2558 jz I_BDSM_New
2559 mov si, word ptr es:[si].LINK
2560 mov ax, word ptr es:[si].LINK+2 ;next pointer
2561 mov es, ax
2562 jmp short I_BDSM_Next
2563I_BDSM_New:
2564 mov ax, ds
2565 mov word ptr ds:[di].LINK+2, ax ;BDSM segment had not been initialized.
2566 mov word ptr es:[si].LINK+2, ax
2567 mov word ptr es:[si].LINK, di
2568 mov word ptr ds:[di].LINK, -1 ;make sure it is a null ptr.
2569
2570I_BDSM_ret:
2571 pop es
2572 pop si
2573 pop ax
2574 ret
2575
2576;***The following code is not needed any more. Don't show any
2577;***messages to be compatible with the behavior of IBMBIO.COM.
2578;;Show the message "Mini disk installed ..."
2579;;This routine uses WRMSG procedure which will call OUTCHR.
2580;Show_Installed_Mini:
2581; push ax
2582; push bx
2583; push ds
2584;
2585; mov al, Mininum ;logical drive number
2586; add al, Drv_Letter_Base ;='A'
2587; mov Mini_Drv_Let, al
2588; mov si, offset Installed_Mini
2589; call WRMSG
2590;
2591; pop ds
2592; pop bx
2593; pop ax
2594; ret
2595;**End of mini disk initialization** ;J.K. 4/7/86
2596
2597
2598CMOS_Clock_Read proc near
2599
2600 assume ds:code,es:code
2601; IN ORDER TO DETERMINE IF THERE IS A CLOCK PRESENT IN THE SYSTEM, THE FOLLOWING
2602; NEEDS TO BE DONE.
2603 PUSH AX
2604 PUSH CX
2605 PUSH DX
2606 PUSH BP
2607
2608 XOR BP,BP
2609LOOP_CLOCK:
2610 XOR CX,CX
2611 XOR DX,DX
2612;SB33030********************************************************************
2613 MOV AH,2 ;READ REAL TIME CLOCK ;SB ;3.30
2614 INT 1Ah ;CALL ROM-BIOS ROUTINE ;SB ;3.30
2615;SB33030********************************************************************
2616 CMP CX,0
2617 JNZ CLOCK_PRESENT
2618
2619 CMP DX,0
2620 JNZ CLOCK_PRESENT
2621
2622 CMP BP,1 ; READ AGAIN AFTER A SLIGHT DELAY, IN CASE CLOCK
2623 JZ NO_READDATE ; WAS AT ZERO SETTING.
2624
2625 INC BP ; ONLY PERFORM DELAY ONCE.
2626 MOV CX,4000H
2627DELAY:
2628 LOOP DELAY
2629 JMP LOOP_CLOCK
2630
2631CLOCK_PRESENT:
2632 mov cs:HaveCMOSClock, 1 ;J.K. Set the flag for cmos clock
2633
2634 call CMOSCK ;J.K. Reset CMOS clock rate that may be
2635 ;possibly destroyed by CP DOS and POST routine did not
2636 ;restore that.
2637
2638 PUSH SI
2639 MESSAGE FTESTINIT,<"CLOCK DEVICE",CR,LF>
2640 CALL READ_REAL_DATE ;MJB002 READ REAL-TIME CLOCK FOR DATE
2641
2642 CLI ;MJB002
2643 MOV DAYCNT,SI ;MJB002 SET SYSTEM DATE
2644 STI ;MJB002
2645 POP SI ;MJB002
2646NO_READDATE:
2647 POP BP
2648 POP DX
2649 POP CX
2650 POP AX
2651 RET
2652
2653CMOS_Clock_Read endp
2654;
2655;J.K. 10/28/86
2656;J.K. THE FOLLOWING CODE IS WRITTEN BY JACK GULLEY IN ENGINEERING GROUP.
2657;J.K. CP DOS IS CHANGING CMOS CLOCK RATE FOR ITS OWN PURPOSES AND IF THE
2658;J.K. USE COLD BOOT THE SYSTEM TO USE PC DOS WHILE RUNNING CP DOS, THE CMOS
2659;J.K. CLOCK RATE ARE STILL SLOW WHICH SLOW DOWN DISK OPERATIONS OF PC DOS
2660;J.K. WHICH USES CMOS CLOCK. PC DOS IS PUT THIS CODE IN MSINIT TO FIX THIS
2661;J.K. PROBLEM AT THE REQUEST OF CP DOS.
2662;J.K. THE PROGRAM IS MODIFIED TO BE RUN ON MSINIT. Equates are defined in CMOSEQU.INC.
2663;J.K. This program will be called by CMOS_Clock_Read procedure.
2664;
2665; The following code CMOSCK is used to insure that the CMOS has not
2666; had its rate controls left in an invalid state on older AT's.
2667;
2668; It checks for an AT model byte "FC" with a submodel type of
2669; 00, 01, 02, 03 or 06 and resets the periodic interrupt rate
2670; bits incase POST has not done it. This initilization routine
2671; is only needed once when DOS loads. It should be ran as soon
2672; as possible to prevent slow diskette access.
2673;
2674; This code exposes one to DOS clearing CMOS setup done by a
2675; resident program that hides and re-boots the system.
2676;
2677CMOSCK PROC NEAR ; CHECK AND RESET RTC RATE BITS
2678 assume ds:nothing,es:nothing
2679
2680;Model byte and Submodel byte were already determined in MSINIT.
2681 push ax
2682 cmp cs:Model_byte, 0FCh ;check for PC-AT model byte
2683 ; EXIT IF NOT "FC" FOR A PC-AT
2684 JNE CMOSCK9 ; Exit if not an AT model
2685
2686 CMP cs:Secondary_Model_Byte,06H ; Is it 06 for the industral AT
2687 JE CMOSCK4 ; Go reset CMOS periodic rate if 06
2688 CMP cs:Secondary_Model_Byte,04H ; Is it 00, 01, 02, or 03
2689 JNB CMOSCK9 ; EXIT if problem fixed by POST
2690 ;J.K. Also,Secondary_model_byte = 0 when AH=0c0h, int 15h failed.
2691CMOSCK4: ; RESET THE CMOS PERIODIC RATE
2692 ; Model=FC submodel=00,01,02,03 or 06
2693;SB33IN2***********************************************************************
2694
2695 mov al,CMOS_REG_A or NMI ;NMI disabled on return
2696 mov ah,00100110b ;Set divider & rate selection
2697 call CMOS_WRITE
2698
2699;SB33IN2***********************************************************************
2700
2701 ; CLEAR SET,PIE,AIE,UIE AND SQWE
2702 mov al,CMOS_REG_B or NMI ;NMI disabled on return
2703 call CMOS_READ
2704 and al,00000111b ;clear SET,PIE,AIE,UIE,SQWE
2705 mov ah,al
2706 mov al,CMOS_REG_B ;NMI enabled on return
2707 call CMOS_WRITE
2708
2709;SB33IN3***********************************************************************
2710
2711CMOSCK9: ; EXIT ROUTINE
2712 pop ax
2713 RET ; RETurn to caller
2714 ; Flags modifyied
2715CMOSCK ENDP
2716PAGE
2717;--- CMOS_READ -----------------------------------------------------------------
2718; READ BYTE FROM CMOS SYSTEM CLOCK CONFIGURATION TABLE :
2719; :
2720; INPUT: (AL)= CMOS TABLE ADDRESS TO BE READ :
2721; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT :
2722; BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ :
2723; :
2724; OUTPUT: (AL) VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS :
2725; ON THEN NMI LEFT DISABLED. DURING THE CMOS READ BOTH NMI AND :
2726; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
2727; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND :
2728; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. :
2729; ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED. :
2730;-------------------------------------------------------------------------------
2731
2732CMOS_READ PROC NEAR ; READ LOCATION (AL) INTO (AL)
2733 assume es:nothing,ds:nothing
2734 PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS
2735;SB33IN4********************************************************************
2736
2737 cli
2738 push bx
2739 push ax ;save user NMI state
2740 or al,NMI ;disable NMI for us
2741 out CMOS_PORT,al
2742 nop ;undocumented delay needed
2743 in al,CMOS_DATA ;get data value
2744
2745 ;set NMI state to user specified
2746 mov bx,ax ;save data value
2747 pop ax ;get user NMI
2748 and al,NMI
2749 or al,CMOS_SHUT_DOWN
2750 out CMOS_PORT,al
2751 nop
2752 in al,CMOS_DATA
2753
2754 mov ax,bx ;data value
2755 pop bx
2756
2757;SB33IN4********************************************************************
2758 PUSH CS ; *PLACE CODE SEGMENT IN STACK AND
2759 CALL CMOS_POPF ; *HANDLE POPF FOR B- LEVEL 80286
2760 RET ; RETURN WITH FLAGS RESTORED
2761
2762CMOS_READ ENDP
2763
2764CMOS_POPF PROC NEAR ; POPF FOR LEVEL B- PARTS
2765 IRET ; RETURN FAR AND RESTORE FLAGS
2766
2767CMOS_POPF ENDP
2768
2769;--- CMOS_WRITE ----------------------------------------------------------------
2770; WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE :
2771; :
2772; INPUT: (AL)= CMOS TABLE ADDRESS TO BE WRITTEN TO :
2773; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT :
2774; BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE :
2775; (AH)= NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION :
2776; :
2777; OUTPUT: VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED :
2778; IF BIT 7 OF (AL) IS ON. DURING THE CMOS UPDATE BOTH NMI AND :
2779; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
2780; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND :
2781; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. :
2782; ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED. :
2783;-------------------------------------------------------------------------------
2784
2785CMOS_WRITE PROC NEAR ; WRITE (AH) TO LOCATION (AL)
2786 assume es:nothing,ds:nothing
2787 PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS
2788 PUSH AX ; SAVE WORK REGISTER VALUES
2789
2790 cli
2791 push ax ;save user NMI state
2792 or al,NMI ;disable NMI for us
2793 out CMOS_PORT,al
2794 nop
2795 mov al,ah
2796 out CMOS_DATA,al ;write data
2797
2798 ;set NMI state to user specified
2799 pop ax ;get user NMI
2800 and al,NMI
2801 or al,CMOS_SHUT_DOWN
2802 out CMOS_PORT,al
2803 nop
2804 in al,CMOS_DATA
2805
2806;SB33IN5********************************************************************
2807 POP AX ; RESTORE WORK REGISTERS
2808 PUSH CS ; *PLACE CODE SEGMENT IN STACK AND
2809 CALL CMOS_POPF ; *HANDLE POPF FOR B- LEVEL 80286
2810 RET
2811
2812CMOS_WRITE ENDP
2813;
2814
2815
2816END$:
2817CODE ENDS
2818 END
2819 \ No newline at end of file
diff --git a/v4.0/src/BIOS/MSIOCTL.INC b/v4.0/src/BIOS/MSIOCTL.INC
new file mode 100644
index 0000000..9967605
--- /dev/null
+++ b/v4.0/src/BIOS/MSIOCTL.INC
@@ -0,0 +1,1362 @@
1 %OUT MSIOCTL.SIL...
2 INCLUDE IOCTL.INC
3; $SALUT $ioctl$
4
5;==============================================================================
6;REVISION HISTORY:
7;AN000 - New for DOS Version 4.00 - J.K.
8;AC000 - Changed for DOS Version 4.00 - J.K.
9;AN00x - PTM number for DOS Version 4.00 - J.K.
10;==============================================================================
11;AN001 - P58 Diskcopy format fails when error occurs during format op.6/26/87 J.K.
12;AN002; - d24 MultiTrack= command added. 6/29/87 J.K.
13;AN003; - p155 Format intermittant failre due to haed settle time 8/18/87 J.K.
14;AN004; D113 Disable I/O access to unformatted media 9/03/87 J.K.
15;AN005; P985 Allow I/O access to unformtted media 9/14/87 J.K.
16;AN006; D241 Provide support of Multi-track Format/Verify 9/23/87 J.K.
17;AN007; P1535 Unformatted hard file problem 10/15/87 J.K.
18;AN008; P2590 Change the recommended BPB info. after AFS format 11/20/87 J.K.
19;AN009; P2828 Do not retry for multi-track format request 12/08/87 J.K.
20;AN010; P2781 Changeline error behavior incompatibile with DOS 3.3. 1/06/88 J.K.
21;AN011; P3178 Set Media ID should update media info in BDS table. 1/21/88 J.K.
22;AN012; D490 IOCTL subfunction 63h,43h,64h,44h conflicts with OS2 2/26/88 J.K.
23;==============================================================================
24
25;J.K. 10/15/87
26;NOTE: GetAccessFlag/SetAccessFlag is unpublished function.
27; This function is intended to give the user to control the
28; BDS table FLAGS of UNFORMATTED_MEDIA bit.
29; GetAccessFlag will show the status -
30; A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 DISK I/O not allowed
31; 1 DISK I/O allowed
32; SetAccessFlag will Set/Reset the UNFORMATTED_MEDIA bit in FLAGS -
33; A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 Allow disk I/O
34; 1 Disallow disk I/O
35;------------------------------------------------------------------------------
36
37; GENERIC IOCTL DISPATCH TABLES
38;
39IOREADJUMPTABLE DB 7 ;AN012;maximum number (0 based)
40 DW OFFSET GETDEVICEPARAMETERS ;60h
41 DW OFFSET READTRACK ;61h
42 DW OFFSET VERIFYTRACK ;62h
43 dw Cmd_Err_Proc ;AN012;Overlapped with OS2 subfunction
44 dw Cmd_Err_Proc ;AN012;
45 dw Cmd_Err_Proc ;AN012;
46 dw GetMediaID ;AN000;AN012;66h
47 dw GetAccessFlag ;AN007;AN012;67h Unpublished function
48
49IOWRITEJUMPTABLE DB 7 ;AN012;
50 DW OFFSET SETDEVICEPARAMETERS ;40h
51 DW OFFSET WRITETRACK ;41h
52 DW OFFSET FORMATTRACK ;42h
53 dw Cmd_Err_Proc ;AN012;
54 dw Cmd_Err_Proc ;AN012;
55 dw Cmd_Err_Proc ;AN012;
56 dw SetMediaID ;AN000;AN012;46h
57 dw SetAccessFlag ;AN007;AN012;47h Unpublished function
58;
59; TRACKTABLE CONTAINS A 4-TUPLES (C,H,R,N) FOR EACH SECTOR IN A TRACK
60; C = CYLINDER NUMBER, H = HEAD NUMBER, R = SECTOR ID, N = BYTES PER SECTOR
61; N BYTES PER SECTOR
62; --- ----------------
63; 0 128
64; 1 256
65; 2 512
66; 3 1024
67;
68MAX_SECTORS_CURR_SUP EQU 63 ; CURRENT MAXIMUM SEC/TRK THAT
69 ; WE SUPPORT (Was 40 in DOS 3.2)
70SECTORSPERTRACK DW 36
71TRACKTABLE DB 0,0,1,2
72 DB 0,0,2,2
73 DB 0,0,3,2
74 DB 0,0,4,2
75 DB 0,0,5,2
76 DB 0,0,6,2
77 DB 0,0,7,2
78 DB 0,0,8,2
79 DB 0,0,9,2
80 DB 0,0,10,2
81 DB 0,0,11,2
82 DB 0,0,12,2
83 DB 0,0,13,2
84 DB 0,0,14,2
85 DB 0,0,15,2
86 db 0,0,16,2
87 db 0,0,17,2
88 db 0,0,18,2
89 db 0,0,19,2
90 db 0,0,20,2
91 db 0,0,21,2
92 db 0,0,22,2
93 db 0,0,23,2
94 db 0,0,24,2
95 db 0,0,25,2
96 db 0,0,26,2
97 db 0,0,27,2
98 db 0,0,28,2
99 db 0,0,29,2
100 db 0,0,30,2
101 db 0,0,31,2
102 db 0,0,32,2
103 db 0,0,33,2
104 db 0,0,34,2
105 db 0,0,35,2
106 db 0,0,36,2
107 DB 4*MAX_SECTORS_CURR_SUP - ($ - TRACKTABLE) DUP (0)
108
109; THIS IS A REAL UGLY PLACE TO PUT THIS
110; IT SHOULD REALLY GO IN THE BDS
111MEDIATYPE DB 0
112
113MEDIA_SET_FOR_FORMAT DB 0 ; 1 IF WE HAVE DONE AN INT 13 SET MEDIA
114 ; TYPE FOR FORMAT CALL
115Had_Format_Error db 0 ; 1 if the previous format operation
116 ; failed. - J.K. 7/8/86
117Dsk_time_out_Err equ 80h ; Time out error (No media present).
118Dsk_change_line_Err equ 6h ; Change line error
119Dsk_illegal_combination equ 0Ch ; Return code of ah=18h function.
120
121; TEMP DISK BASE TABLE. IT HOLDS THE THE CURRENT DPT WHICH IS THEN REPLACED BY
122; THE ONE PASSED BY "NEW ROMS" BEFORE WE PERFORM A FORMAT OPERATION. THE OLD
123; DPT IS RESTORED IN RESTOREOLDDPT. THE FIRST ENTRY (DISK_SPECIFY_1) IS -1 IF
124; THIS TABLE DOES NOT CONTAIN THE PREVIOUSLY SAVED DPT.
125TEMPDPT DD -1
126
127;
128; GENERIC$IOCTL:
129; PERFORM GENERIC IOCTL REQUEST
130; INPUT:
131; AL - UNIT NUMBER
132; OUTPUT:
133; IF CARRY SET THEN AL CONTAINS ERROR CODE
134;
135 PUBLIC GENERIC$IOCTL
136GENERIC$IOCTL:
137 MESSAGE FTESTDISK,<"GENERIC IOCTL",CR,LF>
138 LES BX,CS:[PTRSAV] ; ES:BX POINTS TO REQUEST HEADER.
139 CALL SETDRIVE ; DS:DI POINTS TO BDS FOR DRIVE.
140;
141; AT THIS POINT:
142; ES:BX - POINTS TO THE REQUEST HEADER
143; DS:DI POINTS TO THE BDS FOR THE DRIVE
144;
145 CMP ES:[BX].MAJORFUNCTION, RAWIO
146 JNE IOCTL_FUNC_ERR
147 MOV AL, ES:[BX].MINORFUNCTION
148 MOV SI, OFFSET IOREADJUMPTABLE
149 TEST AL, GEN_IOCTL_FN_TST ; TEST OF REQ. FUNCTION
150 JNZ NOTGENERICIOCTLWRITE ; FUNCTION IS A READ.
151 MOV SI, OFFSET IOWRITEJUMPTABLE
152NOTGENERICIOCTLWRITE:
153; AND AL, 0FH
154 and al, 9fH ;AN000; Try to check other than 6x, 4x.
155 CMP AL, CS:[SI]
156 JA IOCTL_FUNC_ERR
157 CBW
158 SHL AX, 1
159 INC SI
160 ADD SI,AX
161 LES BX, ES:[BX].GENERICIOCTL_PACKET
162 CALL CS:[SI]
163 JC FAILGENERIC$IOCTL
164 JMP EXIT
165
166FAILGENERIC$IOCTL:
167 JMP ERR$EXIT
168
169IOCTL_FUNC_ERR:
170 JMP CMDERR
171Cmd_Err_Proc: ;AN012;
172 pop dx ;AN012;clear up stack
173 pop dx ;AN012;clear up stack
174 jmp IOCTL_FUNC_ERR ;AN012;Cmd error
175;
176; GETDEVICEPARAMETERS:
177;
178; INPUT: DS:DI POINTS TO BDS FOR DRIVE
179; ES:BX POINTS TO DEVICE PARAMETER PACKET
180;
181 PUBLIC GETDEVICEPARAMETERS
182GETDEVICEPARAMETERS PROC NEAR
183; COPY INFO FROM BDS TO THE DEVICE PARAMETERS PACKET
184 MOV AL, BYTE PTR DS:[DI].FORMFACTOR
185 MOV BYTE PTR ES:[BX].DP_DEVICETYPE, AL
186 MOV AX, WORD PTR DS:[DI].FLAGS
187 AND AX,FNON_REMOVABLE+FCHANGELINE ; MASK OFF OTHER BITS
188 MOV WORD PTR ES:[BX].DP_DEVICEATTRIBUTES, AX
189 MOV AX, WORD PTR DS:[DI].CCYLN
190 MOV WORD PTR ES:[BX].DP_CYLINDERS, AX
191
192; SET MEDIA TYPE TO DEFAULT
193 XOR AL, AL
194 MOV BYTE PTR ES:[BX].DP_MEDIATYPE, AL
195
196; COPY RECOMMENDED BPB
197 LEA SI, BYTE PTR [DI].RBYTEPERSEC
198 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, BUILD_DEVICE_BPB
199 JZ USE_BPB_PRESENT
200; GET THE CORRECT DISK IN THE DRIVE
201 CALL CHECKSINGLE
202; BUILD THE BPB FROM SCRATCH
203 CALL GETBP
204 JC GET_PARM_RET
205 LEA SI,BYTE PTR [DI].BYTEPERSEC
206USE_BPB_PRESENT:
207 LEA DI, BYTE PTR [BX].DP_BPB
208 MOV CX, SIZE BPB_TYPE ; FOR NOW USE 'SMALL' BPB
209 REP MOVSB
210 CLC
211GET_PARM_RET:
212 RET
213GETDEVICEPARAMETERS ENDP
214
215;
216; SETDEVICEPARAMETERS:
217;
218; INPUT: DS:DI POINTS TO BDS FOR DRIVE
219; ES:BX POINTS TO DEVICE PARAMETER PACKET
220;
221 PUBLIC SETDEVICEPARAMETERS
222SETDEVICEPARAMETERS PROC NEAR
223; MAKE SURE THE FCHANGED_BY_FORMAT FLAG GETS SET TO KICK DOS INTO LOOKING AT
224; THE BPB
225 OR WORD PTR DS:[DI].FLAGS, FCHANGED_BY_FORMAT OR FCHANGED
226 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, ONLY_SET_TRACKLAYOUT
227 JZ SHORT SETDEVPARM_1
228 JMP SETTRACKTABLE ; ORIGINALLY TRACKLAYOUT
229
230SETDEVPARM_1:
231; COPY INFO FROM THE DEVICE PARAMETERS PACKET TO BDS
232 MOV AL, BYTE PTR ES:[BX].DP_DEVICETYPE
233 MOV BYTE PTR DS:[DI].FORMFACTOR, AL
234
235 MOV AX, WORD PTR ES:[BX].DP_CYLINDERS
236 MOV WORD PTR DS:[DI].CCYLN, AX
237
238; IF CHANGE LINE IS NOT LOADED THEN IGNORE CHANGELING FLAG
239 MOV AX, WORD PTR ES:[BX].DP_DEVICEATTRIBUTES
240 CMP CS:[FHAVE96],0
241 JNZ HAVE_CHANGE
242 AND AX,NOT FCHANGELINE
243HAVE_CHANGE:
244; IGNORE ALL BITS EXCEPT NON_REMOVABLE AND CHANGELINE
245 AND AX,FNON_REMOVABLE OR FCHANGELINE
246 MOV CX, WORD PTR DS:[DI].FLAGS
247; AND CX, NOT (FNON_REMOVABLE OR FCHANGELINE OR GOOD_TRACKLAYOUT)
248 AND CX, NOT (FNON_REMOVABLE OR FCHANGELINE OR GOOD_TRACKLAYOUT or UNFORMATTED_MEDIA) ;AN004;AN005;AN007;
249 OR AX, CX
250 MOV WORD PTR DS:[DI].FLAGS, AX
251
252; SET MEDIA TYPE
253 MOV AL, BYTE PTR ES:[BX].DP_MEDIATYPE
254 MOV CS:MEDIATYPE, AL
255; THE MEDIA CHANGED (MAYBE) SO WE WILL HAVE TO DO A SETDASD THE NEXT TIME
256; WE FORMAT A TRACK
257 OR WORD PTR DS:[DI].FLAGS, SET_DASD_TRUE
258
259 SAVEREG <DS,DI,ES,BX>
260; FIGURE OUT WHAT WE ARE SUPPOSED TO DO WITH THE BPB
261
262; WERE WE ASKED TO INSTALL A FAKE BPB?
263 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, INSTALL_FAKE_BPB
264 JNZ SHORT INSTALLFAKEBPB
265
266; WERE WE RETURNING A FAKE BPB WHEN ASKED TO BUILD A BPB?
267 TEST WORD PTR DS:[DI].FLAGS, RETURN_FAKE_BPB
268 JZ SHORT INSTALLRECOMMENDEDBPB
269
270; WE WERE RETURNING A FAKE BPB BUT WE CAN STOP NOW
271 AND WORD PTR DS:[DI].FLAGS, NOT RETURN_FAKE_BPB
272; JMP DONEWITHBPBSTUFF ;AN008; Comment out this instruction.
273
274INSTALLRECOMMENDEDBPB:
275 MOV CX, SIZE A_BPB
276 LEA DI, BYTE PTR [DI].RBYTEPERSEC
277 JMP SHORT COPYTHEBPB
278
279INSTALLFAKEBPB:
280 or word ptr ds:[di].flags, return_fake_bpb ;AN000; Problem
281 ;reported by WHS.
282 MOV CX, SIZE BPB_TYPE ; MOVE 'SMALLER' BPB
283 LEA DI, BYTE PTR [DI].BYTEPERSEC
284COPYTHEBPB:
285 LEA SI, BYTE PTR [BX].DP_BPB
286; EXCHANGE ES AND DS
287 PUSH ES
288 PUSH DS
289 POP ES
290 POP DS
291
292 REP MOVSB
293
294DONEWITHBPBSTUFF:
295 CALL RESTOREOLDDPT ; RESTORE THE OLD DPT FROM TEMPDPT
296 RESTOREREG <BX,ES,DI,DS>
297
298; SET UP TRACK TABLE (IF NECCESSARY)
299SETTRACKTABLE:
300 MOV CX, WORD PTR ES:[BX].DP_TRACKTABLEENTRIES
301 MOV CS:SECTORSPERTRACK, CX
302 AND WORD PTR DS:[DI].FLAGS, NOT GOOD_TRACKLAYOUT
303 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS, TRACKLAYOUT_IS_GOOD
304 JZ UGLYTRACKLAYOUT
305 OR WORD PTR DS:[DI].FLAGS, GOOD_TRACKLAYOUT
306
307UGLYTRACKLAYOUT:
308 CMP CX, MAX_SECTORS_IN_TRACK
309 JA TOOMANYSECTORSPERTRACK
310 JCXZ SECTORINFOSAVED
311 MOV DI, OFFSET TRACKTABLE
312 LEA SI, ES:[BX].DP_SECTORTABLE
313 PUSH ES
314 POP DS
315 PUSH CS
316 POP ES
317STORESECTORINFO:
318 INC DI ; SKIP OVER CYLINDER
319 INC DI ; SKIP OVER HEAD
320 LODSW ; GET SECTOR ID
321 PUSH AX ; SAVE IT
322 LODSW ; GET SECTOR SIZE
323 CALL SECTORSIZETOSECTORINDEX
324 POP DX ; GET SECTOR ID BACK
325 MOV AL, DL ; AH = SECTOR SIZE INDEX
326 ; AL = SECTOR ID
327 STOSW
328 LOOP STORESECTORINFO
329
330SECTORINFOSAVED:
331 CLC
332 RET
333
334TOOMANYSECTORSPERTRACK:
335 MOV AL, 0CH
336 STC
337 RET
338
339SETDEVICEPARAMETERS ENDP
340
341;
342; SET MEDIA TYPE FOR FORMAT
343; PERFORMS THE INT 13 WITH AH = 18H TO SEE IF THE MEDIUM DESCRIBED IN THE
344; BPB AREA IN THE BDS CAN BE HANDLED BY THE ROM.
345; ON INPUT, DS:DI -> CURRENT BDS.
346; THE STATUS OF THE OPERATION IS RETURNED IN AL
347; - 0 - IF THE SUPPORT IS AVAILABLE, AND THE COMBINATION IS VALID.
348; - 1 - NO ROM SUPPORT
349; - 2 - ILLEGAL COMBINATION
350; - 3 - No media present (ROM support exists but cannot determine now)
351; FLAGS ALSO MAY BE ALTERED. ALL OTHER REGISTERS PRESERVED.
352; IF THE CALL TO ROM RETURNS NO ERROR, THEN THE CURRENT DPT IS "REPLACED" BY
353; THE ONE RETURNED BY THE ROM. THIS IS DONE BY CHANGING THE POINTER IN [DPT]
354; TO THE ONE RETURNED. THE ORIGINAL POINTER TO THE DISK BASE TABLE IS STORED
355; IN TEMPDPT, UNTIL IT IS RESTORED.
356;
357 PUBLIC SET_MEDIA_FOR_FORMAT
358SET_MEDIA_FOR_FORMAT PROC NEAR
359 SAVEREG <CX,DX>
360 XOR AX,AX
361 cmp cs:[Had_Format_Error],1 ;Did we have a format error before?
362 jne No_Form_Err ;AN001;
363 call ResetDisk
364No_Form_Err: ;AN001;
365 CMP BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],1
366 jnz Do_Set_Media_for_Format
367 jmp SET_MED_RET ; MEDIA ALREADY SET
368Do_Set_Media_for_Format:
369 SAVEREG <DS,SI>
370 MOV DS,AX
371 LDS SI,DWORD PTR DS:[DSKADR] ; GET POINTER TO DISK BASE TABLE
372 MOV WORD PTR CS:[DPT],SI
373 MOV WORD PTR CS:[DPT+2],DS ; SAVE POINTER TO TABLE
374;SB34IOCTL000******************************************************************
375;SB Initialise the head settle time to 0fh. See the offsets given in
376;SB DSKPRM.INC. 1 LOC.
377
378 mov ds:[si].DISK_HEAD_STTL, 0Fh
379;SB34IOCTL000******************************************************************
380 RESTOREREG <SI,DS>
381 mov cs:[New_Rom], 1 ;assume a new ROM.
382 XOR AL,AL
383;SB33031****************************************************************
384 mov cx,ds:[di.ccyln] ;get number of cylinders ;SB ;3.30*
385 dec cx ;cylinder must be zero based ;SB ;3.30*
386 and ch,03h ; blank out unnecessary bits
387 ror ch,1 ;put in int form ;SB ;3.30*
388 ror ch,1 ; ;SB ;3.30*
389 xchg ch,cl ; ;SB ;3.30*
390 or cl,byte ptr ds:[di.seclim] ;get number of sectors ;SB ;3.30*
391 mov dl,ds:[di.drivenum] ;get drive number ;SB ;3.30*
392 mov ah,18h ;set media for format ;SB ;3.30*
393 SAVEREG <ES,DS,SI,DI>
394 int 13h ;call rom bios ;SB ;3.30*
395;SB33031****************************************************************
396 JC FORMAT_STAT_ERR
397; ES:DI POINTS TO A DISK BASE TABLE FOR THIS COMBINATION FOR THIS DRIVE.
398 XOR CX,CX
399 MOV DS,CX ; HAVE DS -> SEGMENT 0
400 LDS SI,DWORD PTR DS:[DSKADR] ; GET CURRENT DISK BASE TABLE
401 MOV WORD PTR CS:[TEMPDPT],SI
402 MOV WORD PTR CS:[TEMPDPT+2],DS ; SAVE IT
403 MOV WORD PTR DS:[DSKADR],DI
404 MOV WORD PTR DS:[DSKADR+2],ES ; REPLACE WITH ONE RETURNED BY ROM
405 MOV BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],1
406Skip_Disk_Base_setting:
407 XOR AL,AL ; LEGAL COMBINATION + ROM SUPPORT CODE
408 mov cs:[Had_Format_Error],al ;reset the flag
409 JMP SHORT POP_STAT_RET
410
411FORMAT_STAT_ERR:
412 cmp ah, Dsk_illegal_combination ;J.K. illegal combination = 0ch
413 je Format_stat_illegal_comb
414 cmp ah, Dsk_Time_Out_Err ;J.K. = 80h
415 je Format_stat_Time_out
416 mov al, 1 ;Function not supported.
417 mov cs:[New_Rom], 0 ;So, it is an old rom.
418 jmp short Pop_stat_ret
419Format_stat_illegal_comb: ;J.K. Function supported, but
420 MOV AL,2 ;J.K. illegal sect/trk, trk combination.
421 jmp short Pop_stat_ret
422Format_stat_Time_out: ;J.K. Function supported, but
423 mov al, 3 ;J.K. media not present.
424POP_STAT_RET:
425 RESTOREREG <DI,SI,DS,ES>
426SET_MED_RET:
427 RESTOREREG <DX,CX>
428 RET
429
430SET_MEDIA_FOR_FORMAT ENDP
431
432;
433; FORMATTRACK:
434; IF SPECIALFUNCTION BYTE IS 1, THEN THIS IS A STATUS CALL TO SEE IF THERE IS
435; ROM SUPPORT FOR THE COMBINATION OF SEC/TRK AND # OF CYLN, AND IF THE
436; COMBINATION IS LEGAL. IF SPECIALFUNCTION BYTE IS 0, THEN FORMAT THE TRACK.
437;
438; INPUT: DS:DI POINTS TO BDS FOR DRIVE
439; ES:BX POINTS TO FORMAT PACKET
440;
441; OUTPUT:
442; FOR STATUS CALL:
443; SPECIALFUNCTION BYTE SET TO:
444; 0 - ROM SUPPORT + LEGAL COMBINATION
445; 1 - NO ROM SUPPORT
446; 2 - ILLEGAL COMBINATION
447; 3 - no media present ;J.K. 7/8/86
448; CARRY CLEARED.
449;
450; FOR FORMAT TRACK:
451; CARRY SET IF ERROR
452;
453 PUBLIC FORMATTRACK
454FORMATTRACK PROC NEAR
455 TEST BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS,STATUS_FOR_FORMAT
456 JZ DO_FORMAT_TRACK
457 CALL SET_MEDIA_FOR_FORMAT ; ALSO MOVES CURRENT DPT TO TEMPDPT
458STAT_RET:
459 MOV BYTE PTR ES:[BX].DP_SPECIALFUNCTIONS,AL
460 CLC
461 RET
462
463DO_FORMAT_TRACK:
464 CMP BYTE PTR DS:[DI].FORMFACTOR, DEV_HARDDISK
465 jne Do_Format_Diskette
466 jmp DoVerifyTrack
467Do_Format_Diskette:
468 SAVEREG <DS,DI,ES,BX>
469;SB34IOCTL001*************************************************************
470;SB check the special functions word to see if DO_FAST_FORMAT has been
471;SB specified. If so it is an error and we need to finish this operation
472;SB by indicating the error value 1 in register ah and going to the
473;SB the code at DO_MAP_IT to map the error. This is because we cannot
474;SB allow multitrack format on floppies - 5 LOCS
475
476 test byte ptr es:[bx].FP_SPECIALFUNCTIONS,DO_FAST_FORMAT
477 jz NO_FAST_FORMAT
478 mov ah, 1
479 jmp DO_MAP_IT
480NO_FAST_FORMAT:
481;SB34IOCTL001*************************************************************
482 CALL SET_MEDIA_FOR_FORMAT ; ALSO MOVES CURRENT DPT TO TEMPDPT
483 CMP AL,1 ; DO WE HAVE ROM SUPPORT FOR sector/trk, # trks combination?
484 JZ Need_Set_DASD ;Old ROM.
485 cmp al,3 ;time out error?
486 jnz No_Set_DASD ;No, fine.(At this point, don't care about the illegal combination.)
487 jmp Format_Failed
488Need_Set_DASD:
489 CALL SETDASD ;AH=17h, INT 13h
490;
491; STORE CYLINDER,HEAD IN TRACK TABLE
492; ***** ASSUMPTION *******
493; SINCE FORMAT REQUESTS ON FIXED MEDIA ARE CONVERTED TO VERIFIES, WE
494; ASSUME THAT WE ARE FORMATTING A FLOPPY AND HENCE HAVE 255 OR LESS
495; TRACKS AND HEADS. WE THEREFORE MUST CHANGE THE CYLINDER, HEAD DATA
496; FROM THE REQUEST PACKET SIZE TO THAT OF THE TRACKTABLE (SEE INT 13
497; INTERFACE IN IBM'S TECH REF.).
498
499NO_SET_DASD:
500; CHECK TO ENSURE CORRECT DISK IS IN DRIVE
501 CALL CHECKSINGLE
502
503 MOV AX, WORD PTR ES:[BX].FP_CYLINDER
504 MOV WORD PTR CS:[TRKNUM],AX
505 MOV CX, WORD PTR ES:[BX].FP_HEAD
506 MOV BYTE PTR CS:[HDNUM],CL
507 MOV AH,CL
508
509 PUSH DI ; SAVE PTR TO BDS
510 MOV DI, OFFSET TRACKTABLE
511 PUSH CS
512 POP ES
513 MOV CX, CS:SECTORSPERTRACK
514STORECYLINDERHEAD:
515 STOSW
516 INC DI ; SKIP SECTOR ID
517 INC DI ; SKIP SECTOR SIZE
518 LOOP STORECYLINDERHEAD
519 POP DI ; RESTORE PTR TO BDS
520
521 MOV CX, MAXERR ; SET UP RETRY COUNT
522FORMATRETRY:
523 PUSH CX
524 MOV BX, OFFSET TRACKTABLE
525 PUSH CS
526 POP ES
527 MOV AX, CS:SECTORSPERTRACK
528 MOV AH, ROMFORMAT
529 CALL TO_ROM
530 POP CX
531 JNC FORMATOK
532 call resetdisk
533 mov cs:[Had_Format_Error],1
534 push ax
535 push cx
536 push dx
537 call Set_Media_For_Format
538 cmp al, 1
539 jnz While_Err
540 call SetDASD
541While_Err:
542 pop dx
543 pop cx
544 pop ax
545 LOOP FORMATRETRY
546;SB33106*******************************************************************
547Format_Failed:
548 mov cs:[Had_Format_Error], 1 ;set the format error flag.
549 cmp ah, Dsk_Change_Line_Err ;=06h. Convert change line
550 jne Do_Map_it ;error to Time Out error.
551 mov ah, Dsk_Time_Out_Err ;=80h
552;SB33106*******************************************************************
553Do_Map_it:
554 CALL MAPERROR
555 RESTOREREG <BX,ES,DI,DS>
556 RET
557
558FORMATOK:
559 mov cs:[Had_Format_Error],0 ;reset the format error flag.
560 RESTOREREG <BX,ES,DI,DS>
561
562DOVERIFYTRACK:
563 CALL VERIFYTRACK
564 RET
565
566FORMATTRACK ENDP
567
568VerifyTrack_Err: ;AN006;
569 mov ah, 1 ;AN006;
570 call MapError ;AN006;
571 ret ;AN006;
572
573;
574; VERIFYTRACK:
575;
576; INPUT: DS:DI POINTS TO BDS FOR DRIVE
577; ES:BX POINTS TO VERIFY PACKET
578;
579 PUBLIC VERIFYTRACK
580VERIFYTRACK PROC NEAR
581 MOV CS:RFLAG, ROMVERIFY
582 MOV AX, WORD PTR ES:[BX].VP_CYLINDER
583 MOV CS:CURTRK, AX
584 MOV AX, WORD PTR ES:[BX].VP_HEAD
585
586; ****** ASSUMPTION ******
587; WE ASSUME THAT WE HAVE LESS THAN 256 HEADS, AND THAT THE REQUEST
588; HEADER DATA STRUCTURE IS UNNECCESSARILY BIG
589 MOV CS:CURHD, AL
590 MOV CX, CS:SECTORSPERTRACK ;CL = sectors/track
591;SB34IOCTL005*************************************************************
592;SB
593;SB Check SPECIALFUNCTIONS to see if DO_FAST_FORMAT has been specified
594;SB If not we should go to the normal track verification routine. If
595;SB fast format has been specified we should get the number of tracks
596;SB to be verified and check it to see if it is > 255. If it is then
597;SB it is an error and we should go to VerifyTrack_Err. If not multiply
598;SB the number of tracks by the sectors per track to get the total
599;SB number of sectors to be verified. This should also be less than
600;SB equal to 255 otherwise we go to same error exit. If everything
601;SB is okay we initalise cx to the total sectors. use ax as a temporary
602;SB register. 9 LOCS
603
604 test byte ptr es:[bx].FP_SPECIALFUNCTIONS,DO_FAST_FORMAT
605 jz Norm_VerifyTrack
606 mov ax,es:[bx].FP_TRACKCOUNT ;ax <- tracks to be verify
607 cmp ax,0FFh
608 ja VerifyTrack_Err ;#tracks > 255
609 mul cl
610 cmp ax,0FFh ;#sectors > 255
611 ja VerifyTrack_Err
612 mov cx,ax ;#sectors to verify
613;SB34IOCTL005*************************************************************
614
615;Set the multi track request flag
616 test word ptr [di].Flags, fNON_REMOVABLE ;AN009;hard disk?
617 jz Norm_VerifyTrack ;AN009;
618 test cs:Multrk_Flag, MULTRK_ON ;AN009;MultiTrack operation = on?
619 jz Norm_VerifyTrack ;AN009;
620 mov cs:Multitrk_Format_Flag, 1 ;AN009; then set the flag
621Norm_VerifyTrack: ;AN006;
622 XOR AX, AX ;1st sector
623; USE 0:0 AS THE TRANSFER ADDRESS FOR VERIFY
624 XOR BX, BX
625 MOV ES, BX
626 CALL TRACKIO
627 mov cs:Multitrk_Format_Flag, 0 ;AN009;Reset the flag.
628 RET
629VERIFYTRACK ENDP
630
631;
632; READTRACK:
633;
634; INPUT: DS:DI POINTS TO BDS FOR DRIVE
635; ES:BX POINTS TO READ PACKET
636;
637 PUBLIC READTRACK
638READTRACK:
639 MOV CS:RFLAG, ROMREAD
640 JMP READWRITETRACK
641
642;
643; WRITETRACK:
644;
645; INPUT: DS:DI POINTS TO BDS FOR DRIVE
646; ES:BX POINTS TO WRITE PACKET
647;
648 PUBLIC WRITETRACK
649WRITETRACK:
650 MOV CS:RFLAG, ROMWRITE
651 JMP READWRITETRACK
652;
653; READWRITETRACK:
654;
655; INPUT:
656; DS:DI POINTS TO BDS FOR DRIVE
657; ES:BX POINTS TO WRITE PACKET
658; RFLAG - 2 FOR READ, 3 FOR WRITE
659;
660 PUBLIC READWRITETRACK
661READWRITETRACK PROC NEAR
662 MOV AX, WORD PTR ES:[BX].TRWP_CYLINDER
663 MOV CS:CURTRK, AX
664 MOV AX, WORD PTR ES:[BX].TRWP_HEAD
665
666; ****** ASSUMPTION ******
667; WE ASSUME THAT WE HAVE LESS THAN 256 HEADS, AND THAT THE REQUEST
668; HEADER DATA STRUCTURE IS UNNECCESSARILY BIG
669 MOV CS:CURHD, AL
670 MOV AX, WORD PTR ES:[BX].TRWP_FIRSTSECTOR
671 MOV CX, WORD PTR ES:[BX].TRWP_SECTORSTOREADWRITE
672 LES BX, ES:[BX].TRWP_TRANSFERADDRESS
673 CALL TRACKIO
674 RET
675READWRITETRACK ENDP
676
677
678;
679; TRACKIO:
680; PERFORMS TRACK READ/WRITE/VERIFY
681;
682; INPUT:
683; RFLAG - 2 = READ
684; 3 = WRITE
685; 4 = VERIFY
686; AX - INDEX INTO TRACK TABLE OF FIRST SECTOR TO IO
687; CX - NUMBER OF SECTORS TO IO
688; ES:BX - TRANSFER ADDRESS
689; DS:DI - POINTER TO BDS
690; CURTRK - CURRENT CYLINDER
691; CURHD - CURRENT HEAD
692;
693 PUBLIC TRACKIO
694TRACKIO PROC NEAR
695; PROCEDURE `DISK' WILL POP STACK TO SPSAV AND RETURN IF ERROR
696 MOV CS:SPSAV, SP
697; ENSURE CORRECT DISK IS IN DRIVE
698 CALL CHECKSINGLE
699; SEE IF WE HAVE ALREADY SET THE DISK BASE TABLE
700 CMP BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],1
701 JZ DPTALREADYSET
702;
703; SET UP TABLES AND VARIABLES FOR I/O
704;
705 SAVEREG <AX,CX>
706 CALL IOSETUP
707 RESTOREREG <CX,AX>
708;
709; POINT SI AT THE TABLE ENTRY OF THE FIRST SECTOR TO BE IO'D
710;
711DPTALREADYSET:
712 MOV SI, OFFSET TRACKTABLE
713 SHL AX, 1
714 SHL AX, 1
715 ADD SI, AX
716;
717; WE WANT:
718; CX TO BE THE NUMBER OF TIMES WE HAVE TO LOOP
719; DX TO BE THE NUMBER OF SECTORS WE READ ON EACH ITERATION
720 MOV DX, 1
721 TEST WORD PTR DS:[DI].FLAGS, GOOD_TRACKLAYOUT
722 JZ IONEXTSECTOR
723
724; HEY! WE CAN READ ALL THE SECTORS IN ONE BLOW
725 XCHG DX, CX
726
727IONEXTSECTOR:
728 PUSH CX
729 PUSH DX
730; SKIP OVER THE CYLINDER AND HEAD IN THE TRACK TABLE
731 INC SI
732 INC SI
733; GET SECTOR ID FROM TRACK TABLE
734 LODS BYTE PTR CS:[SI]
735 MOV CS:CURSEC, AL
736;*** For a Fixed disk multi-track disk I/O - J.K. 4/14/86
737;Assumptions: 1). In the input CX (# of sectors to go) to TRACKIO, only CL is
738;valid. 2). Sector size should be set to 512 bytes. 3). GOODTRACKLAYOUT.
739;
740 test word ptr [di].Flags, fNon_Removable ;Fixed disk? - J.K.
741 jz IOREMOVABLE ;no -J.K.
742 test cs:MulTrk_Flag, MULTRK_ON ;AN002; Allow multi-track operation?
743 jz IORemovable ;AN002; No, don't do that.
744 mov cs:[seccnt], dx ;# of sectors to I/O -J.K.
745 mov ax, dx ;J.K.
746 call disk ;J.K.
747 pop dx ;J.K.
748 pop cx ;J.K.
749 clc ;J.K.
750 ret ;J.K.
751IOREMOVABLE: ;J.K.
752; GET SECTOR SIZE INDEX FROM TRACK TABLE AND SAVE IT
753 LODS BYTE PTR CS:[SI]
754 PUSH AX
755; PATCH SECTOR SIZE IN DPT
756 PUSH SI
757 PUSH DS
758 LDS SI, CS:DPT
759 MOV BYTE PTR DS:[SI].DISK_SECTOR_SIZ,AL
760 MOV AL,CS:[EOT]
761 MOV [SI].DISK_EOT,AL ; SET UP THE MAX NUMBER OF SEC/TRACK
762 POP DS
763 MOV AL, DL
764DOTHEIO:
765 MOV CS:[SECCNT],AX ; SET UP THE COUNT OF SECTORS TO I/O
766 CALL DISK
767; ADVANCE BUFFER POINTER BY ADDING SECTOR SIZE
768 POP SI
769 POP AX
770 CALL SECTORSIZEINDEXTOSECTORSIZE
771 ADD BX, AX
772 POP DX
773 POP CX
774 LOOP IONEXTSECTOR
775 cmp byte ptr cs:[Media_Set_For_Format], 1 ;AN001;
776 je No_Need_Done ;AN001;
777 CALL DONE ; SET TIME OF LAST ACCESS, AND RESET
778No_Need_Done: ;AN001;
779 CLC ; ENTRIES IN DPT.
780 RET
781
782TRACKIO ENDP
783;
784; THE SECTOR SIZE IN BYTES NEEDS TO BE CONVERTED TO AN INDEX VALUE FOR THE IBM
785; ROM. (0=>128, 1=>256,2=>512,3=>1024). IT IS ASSUMED THAT ONLY THESE VALUES
786; ARE PERMISSIBLE.
787; ON INPUT AX CONTAINS SECTOR SIZE IN BYTES
788; ON OUTPUT AL CONTAINS INDEX
789;
790 PUBLIC SECTORSIZETOSECTORINDEX
791SECTORSIZETOSECTORINDEX PROC NEAR
792 CMP AH,2 ; EXAMINE UPPER BYTE ONLY
793 JA ONEK
794 MOV AL,AH ; VALUE IN AH IS THE INDEX!
795 RET
796ONEK:
797 MOV AL,3
798 RET
799SECTORSIZETOSECTORINDEX ENDP
800
801SECTORSIZEINDEXTOSECTORSIZE PROC NEAR
802 MOV CL, AL
803 MOV AX,128
804 SHL AX, CL
805 RET
806SECTORSIZEINDEXTOSECTORSIZE ENDP
807
808;
809; SET UP THE ROM FOR FORMATTING.
810; WE HAVE TO TELL THE ROM BIOS WHAT TYPE OF DISK IS IN THE DRIVE.
811; ON INPUT - DS:DI - POINTS TO BDS
812;
813 PUBLIC SETDASD
814SETDASD:
815; SEE IF WE HAVE PREVIOUSLY SET DASD TYPE
816;SB33114******************************************************************
817 cmp cs:[Had_Format_Error],1
818 je DoSetDasd
819;SB33114******************************************************************
820 TEST WORD PTR DS:[DI].FLAGS, SET_DASD_TRUE
821 JZ DASDHASBEENSET
822 AND WORD PTR DS:[DI].FLAGS, NOT SET_DASD_TRUE
823;SB33115******************************************************************
824DoSetDasd:
825 mov cs:[Had_Format_Error],0 ;reset it
826;SB33115******************************************************************
827 MOV CS:[GAP_PATCH],50H ; FORMAT GAP FOR 48TPI DISKS
828 MOV AL,4
829 CMP BYTE PTR DS:[DI].FORMFACTOR,DEV_3INCH720KB
830 JZ DO_SET
831 CMP BYTE PTR DS:[DI].FORMFACTOR, DEV_5INCH96TPI
832 JZ GOT_BIG
833 MOV AL,1 ; 160/320K IN A 160/320K DRIVE
834 JMP SHORT DO_SET
835GOT_BIG:
836 MOV AL,2 ; 160/320K IN A 1.2 MEG DRIVE
837 CMP CS:MEDIATYPE, 0
838 JNE DO_SET
839 MOV AL,3 ; 1.2MEG IN A 1.2MEG DRIVE
840 MOV CS:[GAP_PATCH],54H
841DO_SET:
842 push ds ;AN003;
843 push si ;AN003;
844;SB34IOCTL002****************************************************************
845;SB Get the disk parameter table address (dword address) from the location
846;SB 0:[DSKADR] and fix the head settle time in this to be 0fh. 4 LOCS
847
848 xor si, si
849 mov ds, si
850 lds si, dword ptr ds:[DSKADR]
851 mov ds:[si].DISK_HEAD_STTL, 0Fh
852;SB34IOCTL002****************************************************************
853 pop si ;AN003;
854 pop ds ;AN003;
855;SB33032******************************************************************
856 mov AH, 17h ; set command to Set DASD type;SB ;3.30*
857 mov DL, [di].DriveNum ; set drive number ;SB ;3.30*
858 int 13h ; call rom-bios ;SB ;3.30*
859;SB33032******************************************************************
860DASDHASBEENSET:
861 MOV AH,BYTE PTR [DI].SECLIM
862 MOV CS:[FORMT_EOT],AH
863 RET
864
865;
866; THIS ROUTINE IS CALLED IF AN ERROR OCCURS WHILE FORMATTING OR VERIFYING.
867; IT RESETS THE DRIVE, AND DECREMENTS THE RETRY COUNT.
868; ON ENTRY - DS:DI - POINTS TO BDS FOR THE DRIVE
869; BP - CONTAINS RETRY COUNT
870; ON EXIT FLAGS INDICATE RESULT OF DECREMENTING RETRY COUNT
871;
872AGAIN:
873 CALL RESETDISK
874
875;(deleted section here, as requested by D.L.)
876
877 DEC BP ; DECREMENT RETRY COUNT
878 RET
879
880
881; RESET THE DRIVE.
882; WE ALSO SET [STEP_DRV] TO -1 TO FORCE THE MAIN DISK ROUTINE TO USE THE
883; SLOW HEAD SETTLE TIME FOR THE NEXT OPERATION. THIS IS BECAUSE THE RESET
884; OPERATION MOVES THE HEAD TO CYLINDER 0, SO WE NEED TO DO A SEEK THE NEXT
885; TIME AROUND - THERE IS A PROBLEM WITH 3.5" DRIVES IN THAT THE HEAD DOES
886; NOT SETTLE DOWN IN TIME, EVEN FOR READ OPERATIONS!!
887;
888 PUBLIC RESETDISK
889RESETDISK:
890 SAVEREG <AX>
891;SB33033******************************************************************
892 xor AH, AH ; set command to reset disk ;SB ;3.30*
893 int 13h ; call the rom-bios ;SB ;3.30*
894;SB33033******************************************************************
895 MOV CS:[STEP_DRV],-1 ; ZAP UP THE SPEED
896 RESTOREREG <AX>
897 RET
898
899;
900; THIS ROUTINE SETS UP THE DRIVE PARAMETER TABLE WITH THE VALUES NEEDED FOR
901; FORMAT, DOES AN INT 13. VALUES IN DPT ARE RESTORED AFTER A VERIFY IS DONE.
902;
903; ON ENTRY - DS:DI - POINTS TO BDS FOR THE DRIVE
904; ES:BX - POINTS TO TRKBUF
905; AL - NUMBER OF SECTORS
906; AH - INT 13 FUNCTION CODE
907; CL - SECTOR NUMBER FOR VERIFY
908; ON EXIT - DS,DI,ES,BX REMAIN UNCHANGED.
909; AX AND FLAGS ARE THE RESULTS OF THE INT 13
910;
911 PUBLIC TO_ROM
912TO_ROM:
913 SAVEREG <DS,DI,ES,BX,SI>
914 TEST BYTE PTR CS:[NEW_ROM],1
915 JNZ GOT_VALID_DPT
916 PUSH AX
917 MOV DX,DS ; SAVE DS:DI-> BDS
918 XOR AX,AX
919 MOV DS,AX
920 LDS SI,DWORD PTR DS:[DSKADR] ; GET POINTER TO DISK BASE TABLE
921 MOV WORD PTR CS:[DPT],SI
922 MOV WORD PTR CS:[DPT+2],DS ; SAVE POINTER TO TABLE
923 MOV AL,CS:[FORMT_EOT]
924 MOV [SI].DISK_EOT,AL
925 MOV AL,CS:[GAP_PATCH]
926 MOV [SI].DISK_FORMT_GAP,AL ; IMPORTANT FOR FORMAT
927 MOV [SI].DISK_HEAD_STTL,15 ; ASSUME WE ARE DOING A SEEK OPERATION
928; SET UP MOTOR START CORRECTLY FOR 3.5" DRIVES.
929 PUSH ES
930 MOV ES,DX
931 CMP BYTE PTR ES:[DI].FORMFACTOR,FFSMALL ; IS IT A 3.5" DRIVE?
932 JNZ MOTORSTRTOK
933 MOV AL,4
934 XCHG AL,[SI].DISK_MOTOR_STRT
935MOTORSTRTOK:
936 POP ES
937;----------------------------------------------------------------------------
938; THE FOLLOWING TWO LINES ARE NO LONGER NECESSARY SINCE THEY ARE ONLY USEFUL
939; FOR A VERIFY OPERATION.
940; MOV AL,CS:[SECTOR_SIZ_IND]
941; MOV [SI].DISK_SECTOR_SIZ,AL ; IMPORTANT FOR VERIFY
942;----------------------------------------------------------------------------
943 MOV DS,DX ; RESTORE DS:DI-> BDS
944 POP AX
945GOT_VALID_DPT:
946;SB33034*******************************************************************
947 mov dx, cs:[trknum] ; set track number ;SB ;3.30*
948 mov ch,dl ; set low 8 bits in ch ;SB ;3.30*
949 mov DL, ds:[di].DriveNum ; set drive number ;SB ;3.30*
950 mov DH, CS:[HDNUM] ; set head number ;SB ;3.30*
951 int 13h ; call the rom-bios routines ;SB ;3.30*
952;SB33034*******************************************************************
953 RESTOREREG <SI,BX,ES,DI,DS>
954 RET
955
956;
957; GET THE OWNER OF THE PHYSICAL DRIVE REPRESENTED BY THE LOGICAL DRIVE IN BL.
958; THE ASSUMPTION IS THAT WE **ALWAYS** KEEP TRACK OF THE OWNER OF A DRIVE!!
959; IF THIS IS NOT THE CASE, THE SYSTEM MAY HANG, JUST FOLLOWING THE LINKED LIST.
960;
961 PUBLIC IOCTL$GETOWN
962IOCTL$GETOWN:
963 CALL SETDRIVE
964 MOV AL,BYTE PTR [DI].DRIVENUM ; GET PHYSICAL DRIVE NUMBER
965 PUSH CS
966 POP DS
967 MOV DI,WORD PTR START_BDS
968OWN_LOOP:
969 CMP BYTE PTR [DI].DRIVENUM,AL
970 JNE GETNEXTBDS
971 TEST WORD PTR [DI].FLAGS,FI_OWN_PHYSICAL
972 JNZ DONE_GETOWN
973GETNEXTBDS:
974 MOV BX,WORD PTR [DI].LINK+2
975 MOV DI,WORD PTR [DI].LINK
976 MOV DS,BX
977 JMP SHORT OWN_LOOP
978DONE_GETOWN:
979 JMP SHORT EXIT_OWN
980
981;
982; SET THE OWNERSHIP OF THE PHYSICAL DRIVE REPRESENTED BY THE LOGICAL DRIVE IN
983; BL TO BL.
984;
985 PUBLIC IOCTL$SETOWN
986IOCTL$SETOWN:
987 CALL SETDRIVE
988 MOV BYTE PTR CS:[FSETOWNER],1 ; SET FLAG FOR CHECKSINGLE TO
989 ; LOOK AT.
990 CALL CHECKSINGLE ; SET OWNERSHIP OF DRIVE
991 MOV BYTE PTR CS:[FSETOWNER],0 ; RESET FLAG
992 XOR BX,BX
993 MOV ES,BX
994 MOV CL,-1
995 MOV BYTE PTR ES:[LSTDRV],CL ; SET UP SDSB AS WELL
996
997EXIT_OWN:
998; IF THERE IS ONLY ONE LOGICAL DRIVE ASSIGNED TO THIS PHYSICAL DRIVE, RETURN
999; 0 TO USER TO INDICATE THIS.
1000 XOR CL,CL
1001 TEST WORD PTR [DI].FLAGS,FI_AM_MULT
1002 JZ EXIT_NO_MULT
1003 MOV CL,BYTE PTR [DI].DRIVELET ; GET LOGICAL DRIVE NUMBER
1004 INC CL ; GET IT 1-BASED
1005EXIT_NO_MULT:
1006 LDS BX,CS:[PTRSAV]
1007 MOV BYTE PTR [BX].UNIT,CL
1008 JMP EXIT
1009
1010
1011;
1012; MOVES THE OLD DPT THAT HAD BEEN SAVED IN TEMPDPT BACK TO DPT. THIS IS DONE
1013; ONLY IF THE FIRST BYTE OF TEMPDPT IS NOT -1.
1014; ALL REGISTERS (INCLUDING FLAGS) ARE PRESERVED.
1015;
1016 PUBLIC RESTOREOLDDPT
1017RESTOREOLDDPT:
1018; IF WE HAVE ALREADY RESTORED THE DISK BASE TABLE EARLIER, DO NOT DO IT
1019; AGAIN.
1020 PUSH AX
1021 XOR AL,AL
1022; RESET FLAG AND GET CURRENT FLAG SETTING
1023 mov cs:[Had_Format_Error],al
1024 XCHG BYTE PTR CS:[MEDIA_SET_FOR_FORMAT],AL
1025 OR AL,AL
1026 JZ DONTRESTORE
1027 SAVEREG <SI,DS,ES>
1028 LDS SI,CS:[TEMPDPT]
1029 XOR AX,AX
1030 MOV ES,AX ; HAVE ES -> SEGMENT 0
1031 MOV WORD PTR ES:[DSKADR],SI
1032 MOV WORD PTR ES:[DSKADR+2],DS
1033GOTCURRENTDPT:
1034 RESTOREREG <ES,DS,SI>
1035DONTRESTORE:
1036 POP AX
1037 CLC ; CLEAR CARRY
1038 RET
1039
1040;******************************************************************************
1041;AN000; Get Media ID
1042;*******************************************************************************
1043; *
1044; Function: Get the volume label, the system id and the serial number from *
1045; the media that has the extended boot record. *
1046; For the conventional media, this routine will return "Unknown *
1047; media type" error to DOS. *
1048; *
1049; Input : DS:DI -> BDS table for this drive. *
1050; ES:BX -> Request packet (= A_Media_ID_INFO structure) *
1051; *
1052; Output: The request packet filled with the information, if not carry. *
1053; If carry set, then AL contains the device driver error number *
1054; that will be returned to DOS. *
1055; Register DS,DX,AX,CX,DI,SI destroyed. *
1056; Subroutines to be called: *
1057; BOOT_IO:NEAR *
1058; *
1059; Logic: *
1060; /*To recognize the extended boot record, this logic will actually */ *
1061; /*access the boot sector even if it is a hard disk. */ *
1062; /*NOTE:the valid extended bpb is recognized by looking at the mediabyte*
1063; /*field of BPB and the extended Boot Signature. *
1064; *
1065; { *
1066; Get logical drive number from BDS table; *
1067; RFLAG = Read operation; *
1068; BOOT_IO; /*Get the media boot record into the buffer*/ *
1069; IF (no error) THEN *
1070; IF (extended boot record) THEN *
1071; { set Volume Label, Volume Serial number and System id *
1072; of the Request packet to those of the boot record; *
1073; }; *
1074; ELSE /*Not an extended BPB */ *
1075; { set Register AL to "Unknown media.." error code; *
1076; set Carry bit; *
1077; }; *
1078; ELSE *
1079; Exit; /*Already error code is set in the register AL*
1080; *
1081; Expected LOC: 40 (New) *
1082;*******************************************************************************
1083
1084GetMediaID proc near ;AN000;
1085 call Changeline_Chk ;AN010;
1086 mov al, DS:[DI].DRIVELET ;AN000; logical drive number
1087 mov cs:RFlag, ROMREAD ;AN000; read operation
1088 call Boot_IO ;AN000; read boot sector into cs:DiskSector
1089; $IF NC ;AN000;
1090 JC $IOCTL$IF1
1091 mov cl, cs:MediaByte ;AN000; Mediabyte in BPB
1092 and cl, 0F0h ;AN000;
1093 cmp cl, 0F0h ;AN000; Is it a valid BPB?
1094; $IF E,AND ;AN000;
1095 JNE $IOCTL$IF2
1096 cmp cs:Ext_Boot_Sig, EXT_BOOT_SIGNATURE ;AN000; =90h
1097; $IF E ;AN000; Extended Boot Record
1098 JNE $IOCTL$IF2
1099 push cs ;AN000;
1100 pop ds ;AN000;
1101 mov si, offset Boot_Serial_L ;AN000;
1102 mov di, bx ;AN000;
1103 add di, MI_SERIAL ;AN000;
1104 mov cx, BOOT_SERIAL_SIZE+BOOT_VOLUME_LABEL_SIZE+BOOT_SYSTEM_ID_SIZE
1105 rep movsb ;AN000;
1106; $ELSE ;AN000;
1107 JMP SHORT $IOCTL$EN2
1108$IOCTL$IF2:
1109 mov al, ERROR_UNKNOWN_MEDIA ;AN000; =7
1110 stc ;AN000;
1111; $ENDIF ;End Extended Boot Record check.
1112$IOCTL$EN2:
1113; $ENDIF ;Read boot sector failed. Hard error.
1114$IOCTL$IF1:
1115 ret ;AN000;
1116GetMediaID endp
1117
1118;******************************************************************************
1119;AN000; Set Media ID
1120;*******************************************************************************
1121; *
1122; Function: Set the volume label, the system id and the serial number of *
1123; the media that has the extended boot record. *
1124; For the conventional media, this routine will return "Unknown *
1125; media.." error to DOS. *
1126; This routine will also set the corresponding informations in *
1127; the BDS table. *
1128; *
1129; Input : DS:DI -> BDS table for this drive. *
1130; ES:BX -> Request packet (= A_Media_ID_INFO structure) *
1131; *
1132; Output: The extended boot record in the media will be set according to *
1133; the Request packet. *
1134; If carry set, then AL contains the device driver error number *
1135; that will be returned to DOS. *
1136; *
1137; Subroutines to be called: *
1138; BOOT_IO:NEAR *
1139; *
1140; Logic: *
1141; *
1142; *
1143; { *
1144; Get Drive_Number from BDS; *
1145; RFLAG = "Read operation"; *
1146; BOOT_IO; *
1147; IF (no error) THEN *
1148; IF (extended boot record) THEN *
1149; { set Volume Label, Volume Serial number and System id *
1150; of the boot record to those of the Request packet; *
1151; RFLAG = "Write operation"; *
1152; Get Drive Number from BDS; *
1153; BOOT_IO; /*Write it back*/ *
1154; }; *
1155; ELSE /*Not an extended BPB */ *
1156; { set Register AL to "Unknown media.." error code; *
1157; set Carry bit; *
1158; Exit; /*Return back to caller */ *
1159; }; *
1160; ELSE *
1161; Exit; /*Already error code is set */ *
1162; *
1163; Expected LOC: 45 (New) *
1164;*******************************************************************************
1165
1166SetMediaID proc near
1167 call Changeline_Chk ;AN010;
1168 mov al, DS:[DI].DRIVELET ;AN000; logical drive number
1169 mov dl, al ;AN000; save it for the time being.
1170 mov cs:RFlag, ROMREAD ;AN000; read operation
1171 push dx ;AN000; save drive number
1172 call Boot_IO ;AN000; read boot sector into cs:DiskSector
1173 pop dx ;AN000; restore drive number
1174; $IF NC ;AN000;
1175 JC $IOCTL$IF6
1176 mov cl, cs:MediaByte ;AN000; Mediabyte in BPB
1177 and cl, 0F0h ;AN000;
1178 cmp cl, 0F0h ;AN000; Is it a valid BPB?
1179; $IF E,AND ;AN000;
1180 JNE $IOCTL$IF7
1181 cmp cs:Ext_Boot_Sig, EXT_BOOT_SIGNATURE ;AN000; =41 (=29h)
1182; $IF E ;AN000; Extended Boot Record
1183 JNE $IOCTL$IF7
1184 push ds ;AN011; save BDS pointer
1185 push di ;AN011;
1186 push es ;AN000;
1187 pop ds ;AN000;Now DS-> Request packet
1188 push cs ;AN000;
1189 pop es ;AN000;Now ES -> Boot Record
1190 mov di, offset Boot_Serial_L ;AN000;
1191 mov si, bx ;AN000;
1192 add si, MI_Serial ;AN000;
1193 mov cx, BOOT_SERIAL_SIZE+BOOT_VOLUME_LABEL_SIZE+BOOT_SYSTEM_ID_SIZE
1194 rep movsb ;AN000;
1195 pop di ;AN011;Restore BDS pointer
1196 pop ds ;AN011;
1197 call Mov_Media_IDs ;AN011; Update the BDS media ID info.
1198 mov al, dl ;AN000; set drive number for Boot_IO
1199 mov cs:RFlag, ROMWRITE ;AN000;
1200 call Boot_IO ;AN000; write it back.
1201 mov cs:[TIM_DRV], -1 ;AN011; Make sure chk$media check the driver
1202; $ELSE ;AN000;
1203 JMP SHORT $IOCTL$EN7
1204$IOCTL$IF7:
1205 mov al, ERROR_UNKNOWN_MEDIA ;AN000; =7
1206 stc ;AN000;
1207; $ENDIF ;End Extended Boot Record check.
1208$IOCTL$EN7:
1209; $ENDIF ;Read boot sector failed. Hard error.
1210$IOCTL$IF6:
1211 ret ;AN000;
1212SetMediaID endp
1213
1214;******************************************************************************
1215;AN000; Boot_IO
1216;*******************************************************************************
1217; *
1218; Function: Read/Write the boot record into Boot sector. *
1219; *
1220; Input : *
1221; AL=logical drive number *
1222; RFLAG = operation (read/write) *
1223; *
1224; Output: For read operation, the boot record of the drive specified in BDS *
1225; be read into the DISKSECTOR buffer. *
1226; For write operation, the DISKSECTOR buffer image will be written *
1227; to the drive specified in BDS. *
1228; If carry set, then AL contains the device driver error number *
1229; that will be returned to DOS. *
1230; AX,CX,DX register destroyed. *
1231; If carry set, then AL will contain the error code from DISKIO. *
1232; *
1233; Subroutines to be called: *
1234; DISKIO:NEAR *
1235; *
1236; Logic: *
1237; *
1238; { *
1239; First_Sector = 0; /*logical sector 0 is the boot sector */ *
1240; SectorCount = 1; /*read 1 sector only */ *
1241; Buffer = DISKSECTOR; /*read it into the disksector buffer */ *
1242; Call DISKIO (RFLAG, Drive_Number,First_Sector,SectorCount,Buffer); *
1243; } *
1244; Expected LOC: 6 (New) *
1245;*******************************************************************************
1246Boot_IO proc near ;AN000;
1247 push ds ;AN000;
1248 push es ;AN000;
1249 push di ;AN000;
1250 push bx ;AN000;
1251;SB34IOCTL003**************************************************************
1252;SB Call DISKIO to read/write the boot sector. The parameters which
1253;SB need to be initialised for this subroutine out here are
1254;SB - transfer address to cs:DiskSector
1255;SB - low sector needs to be initalised to 0. This is a reg. param
1256;SB - hi sector in cs:[Start_Sec_H] needs to be initialised to 0.
1257;SB - number of sectors <-- 1
1258;SB 7 LOCS
1259
1260 mov di, cs
1261 mov ds, di
1262 mov es, di
1263 mov di, offset DiskSector ;es:di -> transfer address
1264 xor dx, dx ;first sector (H) -> 0
1265 mov [Start_Sec_H], dx ;start sector (H) -> 0
1266 mov cx, 01 ;one sector
1267 call DISKIO
1268;SB34IOCTL003**************************************************************
1269 pop bx ;AN000;
1270 pop di ;AN000;
1271 pop es ;AN000;
1272 pop ds ;AN000;
1273 ret ;AN000;
1274Boot_IO endp ;AN000;
1275
1276;*******************************************************************************
1277;AN010; Changeline_Chk
1278;*******************************************************************************
1279;When the user calls Get/Set media ID call before DOS establishes the media *
1280;by calling "Media$Chk", the change line activity of the drive is going to be *
1281;lost. This routine will check the change line activity and will save the *
1282;history in the flags. *
1283; *
1284; Function: Check the change line error activity *
1285; *
1286; Input : DS:DI -> BDS table. *
1287; *
1288; Output: FLAG in BDS table will be updated if change line occurs. *
1289; *
1290; Subroutines to be called: *
1291; SET_CHANGED_DL *
1292; *
1293;*******************************************************************************
1294Changeline_Chk proc near ;AN010;
1295 mov dl, byte ptr ds:[di].DRIVENUM ;AN010;
1296 or dl, dl ;AN010;Fixed disk?
1297 js Chln_Chk_Ret ;AN010;Yes, skip it.
1298 cmp cs:[fHave96], 1 ;AN011;This ROM support change line?
1299 jne Chln_Chk_Ret ;AN011;
1300 call HasChange ;AN011;This drive support change line?
1301 jz Chln_Chk_Ret ;AN011;do nothing
1302;SB34IOCTL004*****************************************************************
1303;SB Execute the ROM disk interrupt to check changeline activity. 2 LOCS
1304
1305 mov ah, 16h
1306 int 13h
1307;SB34IOCTL004*****************************************************************
1308 jnc Chln_Chk_Ret ;AN010;no change line activity?
1309 mov word ptr cs:[FLAGBITS], FCHANGED ;AN010;
1310 call SET_CHANGED_DL ;AN010;Update FLAG in BDS for this physical drive
1311Chln_Chk_Ret: ;AN010;
1312 ret ;AN010;
1313Changeline_Chk endp ;AN010;
1314
1315;******************************************************************************
1316;AN007; GetAccessFlag
1317;*******************************************************************************
1318; *
1319; Function: Get the status of UNFORMATTED_MEDIA bit of FLAGS in BDS table *
1320; *
1321; Input : *
1322; es:bx -> A_DISKACCESS_CONTROL structure *
1323; ds:di -> BDS table *
1324; *
1325; Output: A_DISKACCESS_CONTROL.DAC_ACCESS_FLAG = 0 if disk I/O not allowed. *
1326; = 1 if disk I/O allowed. *
1327;*******************************************************************************
1328GetAccessFlag proc ;AN007;
1329 test word ptr ds:[di].FLAGS, UNFORMATTED_MEDIA ;AN007;Is it unformtted media?
1330 jz GAF_Allowed ;AN007;No, formatted media
1331 mov es:[bx].DAC_ACCESS_FLAG, 0 ;AN007;
1332 jmp short GAF_Done ;AN007;
1333GAF_Allowed: ;AN007;
1334 mov es:[bx].DAC_ACCESS_FLAG, 1 ;AN007;
1335GAF_Done: ;AN007;
1336 ret ;AN007;
1337GetAccessFlag endp ;AN007;
1338
1339;******************************************************************************
1340;AN007; SetAccessFlag
1341;*******************************************************************************
1342; *
1343; Function: Set/Reset the UNFORMATTED_MEDIA bit of FLAGS in BDS table *
1344; *
1345; Input : *
1346; es:bx -> A_DISKACCESS_CONTROL structure *
1347; ds:di -> BDS table *
1348; *
1349; Output: UNFORMTTED_MEDIA bit modified according to the user request *
1350;*******************************************************************************
1351SetAccessFlag proc ;AN007;
1352 cmp es:[bx].DAC_ACCESS_FLAG, 0 ;AN007;
1353 jne SAF_Allow_Access ;AN007;
1354 or word ptr ds:[di].FLAGS, UNFORMATTED_MEDIA ;AN007;
1355 jmp short SAF_Done ;AN007;
1356SAF_Allow_Access: ;AN007;
1357 and word ptr ds:[di].FLAGS, not UNFORMATTED_MEDIA ;AN007;
1358SAF_Done: ;AN007;
1359 ret ;AN007;
1360SetAccessFlag endp ;AN007;
1361
1362 \ No newline at end of file
diff --git a/v4.0/src/BIOS/MSLOAD.ASM b/v4.0/src/BIOS/MSLOAD.ASM
new file mode 100644
index 0000000..859a318
--- /dev/null
+++ b/v4.0/src/BIOS/MSLOAD.ASM
@@ -0,0 +1,1090 @@
1
2page ,132;
3title Non-Contiguous IBMBIO Loader (MSLOAD)
4;==============================================================================
5;REVISION HISTORY:
6;AN000 - New for DOS Version 4.00 - J.K.
7;AC000 - Changed for DOS Version 4.00 - J.K.
8;AN00x - PTMs for DOS Version 4.00 - J.K.
9;==============================================================================
10;AN001; - P1820 New Message SKL file 10/20/87 J.K.
11;AN002; - D381 For SYS.COM, put the version number 01/06/88 J.K.
12;==============================================================================
13;JK, 1987 -
14; For DOS 4.00, MSLOAD program has been changed to allow:
15; 1. 32 bit calculation,
16; 2. Reading a FAT sector when needed, instead of reading the whole FAT
17; sectors at once. This will make the Boot time faster, and eliminate
18; the memory size limitation problem,
19; 3. Solving the limitation of the file size (29 KB) of IBMBIO.COM,
20; 4. Adding the boot error message. Show the same boot error message
21; and do the same behavior when the read operation of IBMBIO.COM
22; failes as the MSBOOT program, since MSLOAD program is the
23; extention of MSBOOT program.
24;
25
26IF1
27 %OUT ASSEMBLING: Non-Contiguous IBMBIO Loader (MSLOAD)
28 %OUT
29
30ENDIF
31
32
33DSKADR = 1Eh * 4 ;ROM bios diskette table vector position
34
35bootseg segment at 0h
36
37
38 org 7C00h
39Boot_Sector label byte
40bootseg ends
41
42
43dosloadseg segment at 70h
44 org 00h
45IBMBIO_Address label byte
46
47dosloadseg ends
48
49
50cseg segment public para 'code'
51 assume cs:cseg,ds:nothing,es:nothing,ss:nothing
52
53include MSload.inc
54include Bootform.inc ;AN000; Extended bpb, boot record defintion.
55include versiona.inc ;AN001; Version number for SYS.COM
56
57sec9 equ 522h ;;** 8/3/87 DCL
58
59BIOOFF equ 700h
60;
61org 0h
62
63start:
64 jmp Save_Input_Values
65SYS_Version dw EXPECTED_VERSION ;AN001; From VERSIONA.INC file
66Mystacks dw 64 dup (0) ;AN000; local stack
67MyStack_ptr label word
68
69;local data
70Number_Of_Heads dw 0
71Size_Cluster dw 0
72Start_Sector_L dw 0
73Start_Sector_H dw 0 ;J.K.
74Temp_H dw 0 ;J.K. For 32 bit calculation
75Temp_Cluster dw 0 ;J.K. Temporary place for cluster number
76Last_Fat_SecNum dw -1 ;Fat sector number starting from the first fat entry.
77Sector_Count dw 0
78Number_Of_FAT_Sectors dw 0
79Hidden_Sectors_L dw 0
80Hidden_Sectors_H dw 0 ;J.K.
81Sector_Size dw 0
82Reserved_Sectors dw 0
83Last_Found_Cluster dw 0
84Next_BIO_Location dw 0
85First_Sector_L dw 0
86First_Sector_H dw 0 ;J.K.
87Drive_Lim_L dw 0 ;J.K. Max. number of sectors
88Drive_Lim_H dw 0 ;J.K.
89Sectors_Per_Track dw 0
90Drive_Number db 0
91FAT_Size db 0
92Media_Byte db 0
93EOF db 0
94Org_Rom_Disktable dd 0
95FAT_Segment dw 0
96Sectors_Per_Cluster db 0
97
98subttl Save Input Values
99page
100;***********************************************************************
101; Save_Input_Values
102;***********************************************************************
103;
104; Input: none
105;
106; DL = INT 13 drive number we booted from
107; CH = media byte
108; BX = First data sector (low) on disk (0-based)
109; DS:SI = Original ROM BIOS DISKETTE Parameter table.
110;J.K. 6/2/87 If an extended Boot Record, then AX will be the First data sector
111;J.K. high word. Save AX and set First_Sector_H according to AX if it is an
112;J.K. extended boot record.
113; AX = First data sector (High) on disk ;
114; Output:
115;
116; BX = first data sector on disk
117;
118; Media_Byte = input CH
119; Drive_Number = input DL
120; First_Sector_L = input BX
121; First_Sector_H = input AX, if an extended Boot record.;J.K.
122; Drive_Lim_L = maximum sector number in this media ;J.K.
123; Drive_Lim_H = high word of the above
124; Hidden_Sectors_L = hidden secotrs
125; Hidden_Sectors_H
126; Reserved_Sectors = reserved sectors
127; Sectors_Per_Track = Sectors/track
128; Number_Of_Heads = heads/cylinder
129;
130; DS = 0
131; AX,DX,SI destroyed
132;
133; Calls: none
134;-----------------------------------------------------------------------
135;Function:
136; Save input information and BPB informations from the boot record.
137;
138;----------------------------------------------------------------------
139Save_Input_Values:
140
141
142 mov First_Sector_L,bx ;AC000;
143 mov media_Byte,ch
144 mov Drive_Number,dl
145 mov word ptr Org_Rom_Disktable, si
146 push ds
147 pop word ptr Org_Rom_Disktable+2
148 xor cx,cx ;Segment 0
149 mov ds,cx
150 assume ds:Bootseg
151
152 push es ;;** DCL 8/3/87
153 mov es,cx ;;** DCL 8/3/87
154 assume es:Bootseg ;;** DCL 8/3/87
155
156 MOV SI,WORD PTR DS:DSKADR ; ARR 2.41
157 MOV DS,WORD PTR DS:DSKADR+2 ; DS:SI -> CURRENT TABLE ARR 2.41
158
159 MOV DI,SEC9 ; ES:DI -> NEW TABLE ARR 2.41
160 MOV CX,11 ; taken from ibmboot.asm ARR 2.41
161 CLD ;
162 REP MOVSB ; COPY TABLE ARR 2.41
163 PUSH ES ; ARR 2.41
164 POP DS ; DS = 0 ARR 2.41
165
166 MOV WORD PTR DS:DSKADR,SEC9 ; ARR 2.41
167 MOV WORD PTR DS:DSKADR+2,DS ; POINT DISK PARM VECTOR TO NEW TABLE
168 pop es ;;** DCL 8/3/87
169 assume es:nothing
170
171 mov cx,Boot_Sector.EXT_BOOT_BPB.EBPB_BYTESPERSECTOR ;AN000;
172 mov cs:Sector_Size, cx ;AN000;
173 mov cl,Boot_Sector.EXT_BOOT_BPB.EBPB_SECTORSPERCLUSTER ;AN000;
174 mov cs:Sectors_Per_Cluster, cl ;AN000;
175 mov cx,Boot_Sector.EXT_BOOT_BPB.EBPB_SECTORSPERTRACK ;Get Sectors per track
176 mov cs:Sectors_Per_Track,cx
177 mov cx,Boot_Sector.EXT_BOOT_BPB.EBPB_HEADS ;Get BPB heads per cylinder
178 mov cs:Number_Of_Heads,cx
179 mov cx,Boot_Sector.EXT_BOOT_BPB.EBPB_SECTORSPERFAT ;Get sectors per FAT
180 mov cs:Number_Of_FAT_Sectors,cx
181 mov cx,Boot_Sector.EXT_BOOT_BPB.EBPB_RESERVEDSECTORS ;Get Reserved Sectors
182 mov cs:Reserved_Sectors,cx
183 mov cx,word ptr Boot_Sector.EXT_BOOT_BPB.EBPB_HIDDENSECTOR ;Get hidden sectors
184 mov cs:Hidden_Sectors_L,cx
185 mov cx, Boot_Sector.EXT_BOOT_BPB.EBPB_TOTALSECTORS ;AN000;
186 mov cs:Drive_Lim_L, cx ;AN000;
187
188;J.K. First of all, check if it the boot record is an extended one.
189;J.K. This is just a safe guard in case some user just "copy" the 4.00 IBMBIO.COM
190;J.K. to a media with a conventional boot record.
191
192 cmp Boot_Sector.EXT_BOOT_SIG, EXT_BOOT_SIGNATURE ;AN000;
193 jne Relocate ;AN000;
194 mov cs:First_Sector_H, AX ;AN000; start data sector (high)
195 mov ax,word ptr Boot_Sector.EXT_BOOT_BPB.EBPB_HIDDENSECTOR+2 ;AN000;
196 mov cs:Hidden_Sectors_H,ax ;AN000;
197 cmp cx, 0 ;AN000; CX set already before (=Totalsectors)
198 jne Relocate ;AN000;
199 mov ax, word ptr Boot_Sector.EXT_BOOT_BPB.EBPB_BIGTOTALSECTORS ;AN000;
200 mov cs:Drive_Lim_L, ax ;AN000;
201 mov ax, word ptr Boot_Sector.EXT_BOOT_BPB.EBPB_BIGTOTALSECTORS+2 ;AN000;
202 mov cs:Drive_Lim_H, ax ;AN000;
203subttl Relocate
204page
205;
206;***********************************************************************
207; RELOCATE
208;***********************************************************************
209;
210; Notes:
211;
212; Relocate the loader code to top-of-memory.
213;
214; Input: none
215;
216; Output: Code and data relocated.
217; ax,cx,si,di destroyed
218;
219; Calls: none
220;-----------------------------------------------------------------------
221; Copy code from Start to Top of memory.
222;
223; The length to copy is Total_length
224;
225; Jump to relocated code
226;-----------------------------------------------------------------------
227;
228Relocate:
229 assume ds:nothing
230 cld ;AN000;
231 xor si,si ;AN000;
232 mov di,si ;AN000;
233;SB34LOAD000****************************************************************
234;SB Determine the number of paragraphs (16 byte blocks) of memory.
235;SB This involves invoking the memory size determination interrupt,
236;SB which returns the number of 1K blocks of memory, and then
237;SB converting this to the number of paragraphs.
238;SB Leave the number of paragraphs of memory in AX.
239
240 int 12h ;get system memory size in Kbytes
241 mov cl,6 ;
242 shl ax,cl ;memory size in paragraphs
243;SB34LOAD000****************************************************************
244 mov cl,4 ;AN000;
245 mov dx, cs:Sector_Size ;AN000;
246 shr dx,cl ;AN000;
247 inc dx ;AN000;
248 sub ax, dx ;AN000;
249 mov cs:Fat_Segment, ax ;AN000;This will be used for FAT sector
250 mov dx, offset total_length ;AN000;
251 shr dx, cl ;AN000;
252 inc dx ;AN000;
253 sub ax, dx ;AN000;
254 mov es, ax ;AN000;es:di -> place be relocated.
255 push cs ;AN000;
256 pop ds ;AN000;ds:si -> source
257 mov cx, offset total_length ;AN000;
258 rep movsb ;AN000;
259
260 push es ;AN000;
261 mov ax, offset Setup_stack ;AN000;
262 push ax ;AN000;massage stack for destination of cs:ip
263Dumbbb proc far ;AN000;
264 ret ;AN000;
265Dumbbb endp ;AN000;
266
267
268; push cs ;Set up ds segreg
269; pop ds
270; xor ax,ax ;Set up ES segreg
271; mov es,ax
272;
273; assume es:bootseg,ds:cseg
274;
275; mov si,offset Start ;Source
276; mov di,offset Relocate_Start ;Target
277; mov cx,Relocate_Length ;Length
278; rep movsb ;Go do it
279; jmp far ptr Relocate_Start
280
281
282
283subttl Setup Stack
284page
285;***********************************************************************
286; Setup_Stack
287;***********************************************************************
288;
289; Input: none
290;
291; Output:
292;
293; SS:SP set
294; AX destroyed
295;-----------------------------------------------------------------------
296; First thing is to reset the stack to a better and more known place.
297;
298; Move the stack to just under the boot record and relocation area (0:7C00h)
299;
300; Preserve all other registers
301;----------------------------------------------------------------------
302
303Setup_Stack:
304 assume ds:nothing, es:nothing, ss:nothing
305; CLI ;Stop interrupts till stack ok
306 mov ax,cs
307 MOV SS,AX ;Set up the stack to the known area.
308 mov sp, offset MyStack_Ptr
309; MOV SP,7C00h - 50 ;Leave room for stack frame
310; MOV BP,7C00h - 50 ;Point BP as stack index pointer
311; STI
312
313subttl Find_Cluster_Size
314page
315;***********************************************************************
316; Find_Cluster_Size
317;***********************************************************************
318;
319; Input: BPB information in loaded boot record at 0:7C00h
320;
321; Output:
322;
323; DS = 0
324; AX = Bytes/Cluster
325; BX = Sectors/Cluster
326; SI destroyed
327; Calls: none
328;-----------------------------------------------------------------------
329;
330; Get Bytes/sector from BPB
331;
332; Get sectors/cluster from BPB
333;
334; Bytes/cluster = Bytes/sector * sector/cluster
335;----------------------------------------------------------------------
336Find_Cluster_Size:
337
338;For the time being just assume the boot record is valid and the BPB
339;is there.
340
341 xor ax,ax ;Segment 0
342 mov ds,ax
343
344 assume ds:bootseg
345
346 mov ax,Boot_Sector.EXT_BOOT_BPB.EBPB_BYTESPERSECTOR ;AC000;Get BPB bytes/sector
347 xor bx,bx
348 mov bl,Boot_Sector.EXT_BOOT_BPB.EBPB_SECTORSPERCLUSTER ;AC000;Get sectors/cluster
349 mul bx ;Bytes/cluster
350 mov cs:Size_Cluster,ax ;Save it
351
352
353subttl Determine FAT size
354page
355;***********************************************************************
356; Determine_FAT_Size
357;***********************************************************************
358;
359; Notes:
360;
361; Determine if FAT is 12 or 16 bit FAT. 12 bit FAT if floppy, read MBR
362; to find out what system id byte is.
363;
364; Input:
365;
366; Output:
367;
368; cs:Fat_Size = FAT12_bit or FAT16_bit
369; All other registers destroyed
370;
371;----------------------------------------------------------------------
372Determine_FAT_Size:
373 mov cs:FAT_Size,FAT12_bit ;AN000;Assume 12 bit fat
374 mov dx, cs:Drive_Lim_H ;AN000;
375 mov ax, cs:Drive_Lim_L ;AN000;
376 sub ax, cs:Reserved_Sectors ;AN000;
377 sbb dx, 0 ;AN000;now, dx;ax = available total sectors
378 mov bx, cs:Number_Of_FAT_Sectors ;AN000;
379 shl bx, 1 ;AN000;2 FATs
380 sub ax, bx ;AN000;
381 sbb dx, 0 ;AN000;now, dx;ax = tatal sectors - fat sectors
382 mov bx, Boot_Sector.EXT_BOOT_BPB.EBPB_ROOTENTRIES ;AN000;
383 mov cl, 4 ;AN000;
384 shr bx, cl ;AN000;Sectors for dir entries = dir entries / Num_DIR_Sector
385 sub ax, bx ;AN000;
386 sbb dx, 0 ;AN000;
387 xor cx, cx ;AN000;
388 mov cl, Boot_Sector.EXT_BOOT_BPB.EBPB_SECTORSPERCLUSTER ;AN000;
389 push ax ;AN000;
390 mov ax, dx ;AN000;
391 xor dx, dx ;AN000;
392 div cx ;AN000;
393 mov cs:Temp_H, ax ;AN000;
394 pop ax ;AN000;
395;J.K. We assume that cx > dx.
396 div cx ;AN000;
397 cmp ax, 4096-10 ;AN000;
398; jb Determine_First_Cluster ;AN000;
399 jb Read_In_FirstClusters
400 mov cs:FAT_Size, FAT16_Bit ;AN000;16 bit fat
401
402; cmp cs:Media_Byte,0F8h ;Is it floppy
403; jne FAT_Size_Found ;Yep, all set
404; mov cs:Logical_Sector,0 ;Got hardfile, go get MBR
405; xor ax,ax
406; mov es,ax
407; mov di,offset Relocate_Start
408; mov cs:Sector_Count,1
409; call Disk_Read
410; mov si,offset Relocate_Start+1C2h
411; mov cx,4
412; xor ax,ax
413; mov ds,ax
414;Find_Sys_Id:
415; mov cs:FAT_Size,FAT12_bit ;Assume 12 bit fat
416; cmp byte ptr [si],1
417; je FAT_Size_Found
418; mov cs:FAT_Size,FAT16_bit ;Assume 12 bit fat
419; cmp byte ptr [si],4
420; je Fat_Size_Found
421; add si,16
422; loop Find_Sys_Id
423; ;xxxxxxxxxxxxxxxxxxxxxxxxxx error
424;FAT_Size_Found:
425
426
427subttl Read_In_FirstClusters
428page
429;***********************************************************************
430; Read_In_FirstClusters
431;***********************************************************************
432;
433; Notes: Read the start of the clusters that covers at least IBMLOADSIZE
434; fully. For example, if sector/cluster = 2, and IBMLOADSIZE=3
435; then we are going to re-read the second cluster to fully cover
436; MSLOAD program in the cluster boundary.
437;
438; Input:
439; IBMLOADSIZE - Make sure this value is the same as the one in
440; MSBOOT program when you build the new version!!!!!
441;
442; Sectors_Per_Cluster
443; Size_Cluster
444; First_Sector_L
445; First_Sector_H
446;
447; Output: MSLOAD program is fully covered in a cluster boundary.
448; AX = # of clusters we read in so far.
449;
450; Calls: Disk_Read
451; Logic:
452; AX; DX = IBMLOADSIZE / # of sector in a cluster.
453; if DX = 0 then Ok. (MSLOAD is in a cluster boundary.)
454; else (Has to read (AX+1)th cluster to cover MSLOAD)
455; read (AX+1)th cluster into the address after the clusters we
456; read in so far.
457;-----------------------------------------------------------------------
458
459Read_In_FirstClusters:
460 mov ax, IBMLOADSIZE ;AN000;
461 div cs:Sectors_Per_Cluster ;AN000;
462 cmp ah, 0 ;AN000;
463 je Set_Next_Cluster_Number ;AN000;
464 xor ah, ah ;AN000;
465 push ax ;AN000;
466 mov cx, cs:First_Sector_L ;AN000;
467 mov cs:Start_Sector_L, cx ;AN000;
468 mov cx, cs:First_Sector_H ;AN000;
469 mov cs:Start_Sector_H, cx ;AN000;
470 mul cs:Sectors_Per_Cluster ;AN000; Now, AX=# of sectors
471 add cs:Start_Sector_L, ax ;AN000;
472 adc cs:Start_Sector_H, 0 ;AN000;
473 pop ax ;AN000;
474 push ax ;AN000;
475 mov di, BIOOFF ;AN000;
476 mul cs:Size_Cluster ;AN000;AX = # of bytes read in before this cluster
477 add di, ax ;AN000;
478 xor ax, ax ;AN000;
479 mov es, ax ;AN000;
480 mov al, cs:Sectors_Per_Cluster ;AN000;
481 mov cs:Sector_Count, ax ;AN000;
482 call Disk_Read ;AN000;
483 pop ax ;AN000;
484 inc ax ;AN000;# of clusters read in so far.
485
486subttl Set_Next_Cluster_Number
487page
488;***********************************************************************
489; Set_Next_Cluster_Number
490;***********************************************************************
491;
492; Notes: Set LAST_Found_Cluster for the next use.
493; Last_Found_Cluster is the cluster number we are in now.
494; Since cluster number is 0 based and there are 2 clusters int
495; the beginning of FAT table used by the system, we just add
496; 1 to set Last_Found_Cluster.
497;
498; Input:
499; AX = # of clusters read in so far.
500;
501; Output:
502;
503; cs:Last_Found_Cluster
504;
505; Calls: none
506;------------------------------------------------------------------
507Set_Next_Cluster_Number:
508 inc ax ;AN000; For Last_Found_Cluster
509 mov cs:Last_Found_Cluster,ax ;2 is the first data cluster number(0 based)
510
511subttl Read In FAT
512page
513;***********************************************************************
514; Read_In_FAT
515;***********************************************************************
516;
517; Notes:
518;
519; Reads in the entire FAT at 800:0. This gives the relocated portion
520; of this loader a maximum size of 768 bytes (8000 - 7D00).
521; With 64 KB memory system, this can support maximum size of FAT to
522; be 32 KB. We assumes that the system memory size be 128 KB, if
523; the system has a big media with the total fat size bigger than
524; 32 KB.
525;
526; Input: none
527;
528; Output:
529;
530; ES = 0
531; All sectors destroyed
532;
533; Calls: READ DISK
534;-----------------------------------------------------------------------
535; Get number of sectors in FAT
536;
537; Set ES:DI to 800:0
538;
539; Read in the sectors
540;
541;----------------------------------------------------------------------
542;Read_In_FAT:
543; mov ax,cs:Number_Of_FAT_Sectors ;Get sectors/FAT
544; mov cs:Sector_Count,ax ;Number of sectors to read
545; mov ax,cs:Hidden_Sectors_L ;Hidden+Reserved = start of FAT sector
546; mov dx,cs:Hidden_Sectors_H ;AN000;
547; add ax,cs:Reserved_Sectors
548; adc dx, 0
549; mov cs:Start_Sector_L,ax ;AC000;Save it, setup for disk read
550; mov cs:Start_Sector_H,dx ;AN000;
551; mov di, 800h ;AC000;
552; mov es, di ;AC000;
553; xor di, di ;AC000;
554; assume es:nothing
555; call Disk_Read
556;
557subttl Keep Loaded BIO
558page
559;***********************************************************************
560; KEEP LOADED BIO
561;***********************************************************************
562;
563; Notes:
564;
565; Determine how much of IBMBIO was loaded in when the loader was loaded
566; by the boot record (only the portion that is guaranteed to be contiguous)
567;
568; Input:
569;
570; cs:Last_Found_Cluster = number of clusters used for loader+2
571;
572; Output:
573; ES=70h
574; DI = Next offset to load IBMBIO code
575; AX,BX,CX,DX,SI destroyed
576;
577; cs:Next_BIO_Location = DI on output
578; cs:Last_Cluster = last cluster loaded
579;
580; Calls: none
581;-----------------------------------------------------------------------
582;Number of clusters loaded+2 is in cs:Last_Found_Cluster
583;
584;Multiply cluster * cluster size in bytes to get total loaded for MSLOAD
585;
586;Subtract TOTAL_LOADED - LOADBIO_SIZE to get loaded IBMBIO in last cluster
587;
588;Relocate this piece of IBMBIO down to 70:0
589;
590;----------------------------------------------------------------------
591Keep_Loaded_BIO:
592 push ds
593 mov ax,cs:Last_Found_Cluster ;Point to last cluster loaded
594 sub ax,1 ;Get number of clusters loaded
595 mul cs:Size_Cluster ;Get total bytes loaded by
596 ;This is always < 64k, so
597 ;lower 16 bits ok
598 sub ax,LoadBio_Size ;Get portion of IBMBIO loaded
599 mov cx,ax ;Save length to move
600 mov ax,70h ;Segment at 70h
601 mov ds,ax
602 mov es,ax
603 mov si,offset Total_Length ;Point at IBMBIO
604 mov di,0 ;Point at 70:0
605 rep movsb ;Relocate this code
606 mov cs:Next_Bio_Location,di ;Save where to load next
607 pop ds
608
609subttl Get Contiguous Clusters
610page
611;***********************************************************************
612; Get_Contiguous_Clusters
613;***********************************************************************
614;
615; Notes: Go find clusters as long as they are contiguous
616;
617;
618; Input:
619;
620; cs:Next_BIO_Location
621; cs:
622;
623;
624; Output:
625;
626;
627; Calls: Get_Next_FAT_Entry
628;-----------------------------------------------------------------------
629;
630;Set cs:Sector_Count to Sectors per cluster
631;
632;Call Get_Next_FAT_Entry to get next cluster in file
633;
634;Call Check_for_EOF
635;
636;IF (NC returned)
637;
638; {Call Get_Next_FAT_Entry
639;
640; IF (New cluster is contig to old cluster)
641; {Add sectors per cluster to cs:Sector_Count
642;
643; Call Check_For_EOF
644;
645; IF (NC returned)
646;
647;
648;----------------------------------------------------------------------
649Get_Contiguous_Cluster:
650 xor ah,ah
651 mov al,cs:Sectors_Per_Cluster ;Assume we will get one cluster
652 mov cs:Sector_Count,ax
653 push cs:Sector_Count
654 call Get_Next_Fat_Entry ;Go get it in AX
655 pop cs:Sector_Count
656 mov cs:Last_Found_Cluster,ax ;Update the last one found
657 cmp cs:EOF,END_OF_FILE
658 je GO_IBMBIO
659
660; je GOTO_IBMBIO
661;Got_Contig_Clusters:
662
663 xor dx,dx ;AN000;
664 sub ax,2 ;Zero base the cluster
665 xor ch,ch
666 mov cl,cs:Sectors_Per_Cluster ;Get sectors per cluster
667 mul cx ;Get how many
668 add ax,cs:First_Sector_L ;AC000;See where the data sector starts
669 adc dx,cs:First_Sector_H ;AN000;
670 mov cs:Start_Sector_L,ax ;AC000;Save it
671 mov cs:Start_Sector_H,dx ;AN000;
672 mov di,cs:Next_Bio_Location ;Get where to put code
673 push cs:Sector_Count ;Save how many sectors
674 mov ax,dosloadseg ;Get area to load code
675 mov es,ax
676 call Disk_Read
677 pop ax ;Get back total sectors read in
678; jc ##########
679 mul cs:Sector_Size ;AC000;Get number of bytes we loaded
680; mul Boot_Sector.ByteSec
681 add cs:Next_Bio_Location,ax ;Point to where to load next
682 jmp Get_Contiguous_Cluster
683
684subttl GOTO IBMBIO
685page
686;***********************************************************************
687; GOTO_IBMBIO
688;***********************************************************************
689;
690; Notes:
691;
692; Set up required registers for IBMBIO, then jump to it (70:0)
693;
694; Input: none
695;
696; cs:Media_Byte = media byte
697; cs:Drive_Number = INT 13 drive number we booted from
698; cs:First_Sector_L = First data sector on disk (Low) (0-based)
699; cs:First_Sector_H = First data sector on disk (High)
700;
701; Output:
702;
703; Required by MSINIT
704; DL = INT 13 drive number we booted from
705; CH = media byte
706; BX = First data sector on disk (0-based)
707; AX = First data sector on disk (High)
708; DI = Sectors/FAT for the boot media.
709;
710; Calls: none
711;-----------------------------------------------------------------------
712;
713; Set up registers for MSINIT then do Far Jmp
714;
715;----------------------------------------------------------------------
716GO_IBMBIO:
717 mov ch,cs:Media_Byte ;Restore regs required for MSINT
718 mov dl,cs:Drive_Number ;Physical Drive number we booted from.
719 mov bx,cs:First_Sector_L ;AC000;
720 mov ax,cs:First_Sector_H ;AN000; AX will be the First data sector (High)
721;J.K. Don't need this information any more.
722; mov di,cs:Number_Of_FAT_Sectors ;AN000
723 jmp far ptr IBMBIO_Address
724
725
726subttl Disk Read
727page
728;***********************************************************************
729; Disk_Read
730;***********************************************************************
731;
732; Notes:
733;
734; Read in the cs:Sector_Count number of sectors at ES:DI
735;
736;
737; Input: none
738;
739; DI = Offset of start of read
740; ES = Segment of read
741; cs:Sector_Count = number of sectors to read
742; cs:Start_sector_L = starting sector (Low)
743; cs:Start_sector_H = starting sector (High)
744; Following is BPB info that must be setup prior to call
745; cs:Number_Of_Heads
746; cs:Number_Of_Sectors
747; cs:Drive_Number
748; cs:Sectors_Per_Track
749;
750; Output:
751;
752; AX,BX,CX,DX,SI,DI destroyed
753;-----------------------------------------------------------------------
754; Divide start sector by sectors per track
755; The remainder is the actual sector number, 0 based
756;
757; Increment actual sector number to get 1 based
758;
759; The quotient is the number of tracks - divide by heads to get the cyl
760;
761; The remainder is actual head, the quotient is cylinder
762;
763; Figure the number of sectors in that track, set AL to this
764;
765; Do the read
766;
767; If Error, Do RESET, then redo the INT 13h
768;
769; If successful read, Subtract # sectors read from Sector_Count, Add to Logical
770; Sector, add #sectors read * Sector_Size to BX;
771;
772; If Sector_Count <> 0 Do next read
773;----------------------------------------------------------------------
774Disk_Read:
775
776;
777; convert a logical sector into Track/sector/head. AX has the logical
778; sector number
779;
780DODIV:
781 MOV cx,5 ;5 retries
782
783Try_Read:
784 PUSH cx ;Save it
785 MOV AX,cs:Start_Sector_L ;AC000; Get starting sector
786 mov dx, cs:Start_Sector_H ;AN000;
787; XOR DX,DX
788 push ax ;AN000;
789 mov ax, dx ;AN000;
790 xor dx, dx ;AN000;
791 DIV word ptr cs:Sectors_Per_Track
792 mov cs:Temp_H, ax ;AN000;
793 pop ax ;AN000;
794 div word ptr cs:Sectors_Per_Track ;AN000;[temp_h];AX = track, DX = sector number
795 MOV bx,cs:Sectors_Per_Track ;Get number of sectors we can read in
796 sub bx,dx ;this track
797 mov si,bx
798 cmp cs:Sector_Count,si ;Is possible sectors in track more
799 jae Got_Length ;than what we need to read?
800 mov si,cs:Sector_Count ;Yes, only read what we need to
801Got_Length:
802 INC DL ; sector numbers are 1-based
803 MOV bl,dl ;Start sector in DL
804 mov dx, cs:Temp_H ;AN000;now, dx;ax = track
805; XOR DX, DX
806 push ax ;AN000;
807 mov ax, dx ;AN000;
808 xor dx, dx ;AN000;
809 DIV word ptr cs:Number_Of_Heads ;Start cyl in ax,head in DL
810 mov cs:Temp_h, ax ;AN000;
811 pop ax ;AN000;
812 div word ptr cs:Number_of_Heads ;AN000;now [temp_h];AX = cyliner, dx = head
813;J.K. At this moment, we assume that Temp_h = 0, AX <= 1024, DX <= 255
814 MOV DH,DL
815;
816; Issue one read request. ES:BX have the transfer address, AL is the number
817; of sectors.
818;
819 MOV CL,6
820 SHL AH,CL ;Shift cyl high bits up
821 OR AH,BL ;Mix in with sector bits
822 MOV CH,AL ;Setup Cyl low
823 MOV CL,AH ;Setup Cyl/high - Sector
824 mov bx,di ;Get back offset
825 MOV DL,cs:Drive_Number ;Get drive
826 mov ax,si ;Get number of sectors to read (AL)
827
828 MOV AH,2 ;Read
829 push ax ;Save length of read
830 push di
831; Issue one read request. ES:BX have the transfer address, AL is the number
832; of sectors.
833 INT 13H
834 pop di
835 pop ax
836 pop cx ;Get retry count back
837 jnc Read_OK
838 mov bx,di ;Get offset
839 xor ah,ah
840 push cx
841 mov dl,cs:Drive_Number
842 push di
843 int 13h
844 pop di
845 pop cx
846; loop Try_Read ;AC000;
847 ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx error
848 dec cx ;AN000;
849 jz Read_Error ;AN000;
850 jmp Try_Read ;AN000;
851Read_Error: ;AN000;
852 jmp ErrorOut ;AN000;
853
854Read_OK:
855 xor ah,ah ;Mask out read command, just get # read
856 sub cs:Sector_Count,ax ;Bump number down
857 jz Read_Finished
858 add cs:Start_Sector_L,ax ;AC000;Where to start next time
859 adc cs:Start_Sector_H, 0 ;AN000;
860 xor bx,bx ;Get number sectors read
861 mov bl,al
862 mov ax,cs:Sector_Size ;Bytes per sector
863 mul bx ;Get total bytes read
864 add di,ax ;Add it to offset
865 jmp DODIV
866Read_Finished:
867 RET
868
869subttl GET NEXT FAT ENTRY
870page
871;***********************************************************************
872; GET_NEXT_FAT_ENTRY
873;***********************************************************************
874;
875; Notes:
876;
877; Given the last cluster found, this will return the next cluster of
878; IBMBIO. If the last cluster is (F)FF8 - (F)FFF, then the final cluster
879; of IBMBIO has been loaded, and control is passed to GOTO_IBMBIO
880; MSLOAD can handle maximum FAT area size of 64 KB.
881;
882; Input:
883;
884; cs:Last_Found_Cluster
885; cs:Fat_Size
886;
887; Output:
888;
889; cs:Last_Found_Cluster (updated)
890;
891; Calls: Get_Fat_Sector
892;-----------------------------------------------------------------------
893; Get Last_Found_Cluster
894;
895; IF (16 bit FAT)
896; {IF (Last_Found_Cluster = FFF8 - FFFF)
897; {JMP GOTO_IBMBIO}
898; ELSE
899; {Get offset by multiply cluster by 2}
900;
901; ELSE
902; {IF (Last_Found_Cluster = FF8 - FFF)
903; {JMP GOTO_IBMBIO}
904; ELSE
905; {Get offset by - multiply cluster by 3
906;
907; Rotate right to divide by 2
908;
909; IF (CY set - means odd number)
910; {SHR 4 times to keep high twelve bits}
911;
912; ELSE
913; {AND with 0FFFh to keep low 12 bits}
914; }
915; }
916;
917;
918;----------------------------------------------------------------------
919Get_Next_FAT_Entry:
920
921 push es ;AN000;
922 mov ax, cs:FAT_Segment ;AN000;
923 mov es, ax ;AN000; es-> Fat area segment
924 assume es:nothing
925
926 mov cs:EOF,End_Of_File ;Assume last cluster
927 mov ax,cs:Last_Found_Cluster ;Get last cluster
928 cmp cs:Fat_Size,FAT12_bit
929 jne Got_16_Bit
930 mov si, ax ;AN000;
931 shr ax, 1 ;AN000;
932 add si, ax ;AN000; si = ax*1.5 = ax+ax/2
933 call Get_Fat_Sector ;AN000;
934 jne Ok_cluster ;AN000;
935 mov al, byte ptr es:[bx] ;AN000;
936 mov byte ptr cs:Temp_cluster, al ;AN000;
937 inc si ;AN000;
938 call Get_Fat_Sector ;AN000;read next FAT sector
939 mov al, byte ptr es:[0] ;AN000;
940 mov byte ptr cs:Temp_cluster+1, al ;AN000;
941 mov ax, cs:Temp_cluster ;AN000;
942 jmp short Even_Odd ;AN000;
943Ok_cluster: ;AN000;
944 mov ax, es:[bx] ;AN000;
945Even_Odd: ;AN000;
946
947; xor bx,bx
948; mov bl,3 ;Mult by 3
949; mul bx
950; shr ax,1 ;Div by 2 to get 1.5
951; mov si,ax ;Get the final buffer offset
952; mov ax,[si]+8000h ;Get new cluster
953
954 test cs:Last_Found_Cluster,1 ;Was last cluster odd?
955 jnz Odd_Result ;If Carry set it was odd
956 and ax,0FFFh ;Keep low 12 bits
957 jmp short Test_EOF ;
958
959Odd_Result:
960 mov cl,4 ;AN000;Keep high 12 bits for odd
961 shr ax,cl
962Test_EOF:
963 cmp ax,0FF8h ;Is it last cluster?
964 jae Got_Cluster_Done ;Yep, all done here
965 jmp short Not_Last_CLuster
966
967Got_16_Bit:
968 shl ax,1 ;Multiply cluster by 2
969 mov si,ax ;Get the final buffer offset
970 call Get_Fat_Sector ;AN000;
971 mov ax, es:[bx] ;AN000;
972; mov ax,[si]+8000h ;Get new cluster
973 cmp ax,0FFF8h
974 jae Got_Cluster_Done
975
976Not_Last_Cluster:
977 mov cs:EOF,not END_OF_FILE ;Assume last cluster
978
979Got_Cluster_Done:
980 pop es
981 ret
982
983
984Get_Fat_Sector proc near
985;Function: Find and read the corresponding FAT sector into ES:0
986;In). SI = offset value (starting from FAT entry 0) of FAT entry to find.
987; ES = FAT sector segment
988; cs:Sector_Size
989;Out). Corresponding FAT sector read in.
990; BX = offset value of the corresponding FAT entry in the FAT sector.
991; CX destroyed.
992; Zero flag set if the FAT entry is splitted, i.e. when 12 bit FAT entry
993; starts at the last byte of the FAT sector. In this case, the caller
994; should save this byte, and read the next FAT sector to get the rest
995; of the FAT entry value. (This will only happen with the 12 bit fat).
996
997 push ax ;AN000;
998 push si ;AN000;
999 push di ;AN000;
1000 push dx ;AN000;
1001 xor dx, dx ;AN000;
1002 mov ax, si ;AN000;
1003 mov cx, cs:Sector_Size ;AN000;
1004 div cx ;AN000;ax = sector number, dx = offset
1005 cmp ax, cs:Last_Fat_SecNum ;AN000;the same fat sector?
1006 je GFS_Split_Chk ;AN000;don't need to read it again.
1007 mov cs:Last_Fat_SecNum, ax ;AN000;
1008 push dx ;AN000;
1009 xor dx, dx ;AN000;
1010 add ax, cs:Hidden_Sectors_L ;AN000;
1011 adc dx, cs:Hidden_Sectors_H ;AN000;
1012 add ax, cs:Reserved_Sectors ;AN000;
1013 adc dx, 0 ;AN000;
1014 mov cs:Start_Sector_L, ax ;AN000;
1015 mov cs:Start_Sector_H, dx ;AN000;set up for Disk_Read
1016 mov cs:Sector_Count, 1 ;AN000;1 sector
1017 xor di, di ;AN000;
1018 call Disk_Read ;AN000;
1019 pop dx ;AN000;
1020 mov cx, cs:Sector_Size ;AN000;
1021GFS_Split_Chk: ;AN000;
1022 dec cx ;AN000;now, cx= sector size - 1
1023 cmp dx, cx ;AN000;if the last byte of the sector, then splitted entry.
1024 mov bx, dx ;AN000;Set BX to DX
1025 pop dx ;AN000;
1026 pop di ;AN000;
1027 pop si ;AN000;
1028 pop ax ;AN000;
1029 ret ;AN000;
1030Get_Fat_Sector endp ;AN000;
1031
1032
1033Errorout: ;AN000;
1034 push cs ;AN000;
1035 pop ds ;AN000;
1036 mov si, offset Sysmsg ;AN000;
1037 call write ;AN000;
1038;SB34LOAD001****************************************************************
1039;SB Wait for a keypress on the keyboard. Use the BIOS keyboard interrupt.
1040;SB 2 LOCS
1041
1042 xor ah,ah
1043 int 16h ;read keyboard
1044;SB34LOAD001****************************************************************
1045
1046;SB34LOAD002****************************************************************
1047;SB We have to restore the address of the original rom Disk parameter table
1048;SB to the location at [0:DSKADR]. The address of this original table has been
1049;SB saved previously in 0:Org_Rom_DiskTable and 0:Org_Rom_Disktable+2.
1050;SB After this table address has been restored we can reboot by
1051;SB invoking the bootstrap loader BIOS interrupt.
1052
1053 xor bx, bx
1054 mov ds, bx
1055 les bx, dword ptr ds:Org_Rom_DiskTable
1056 mov si, DSKADR
1057 mov word ptr ds:[si], bx ;restore offset
1058 mov word ptr ds:[si+2], es ;restore segment
1059 int 19h ;reboot
1060;SB34LOAD002****************************************************************
1061
1062Write proc near ;show error messages
1063;In) DS:SI -> ASCIIZ string.
1064
1065 lodsb ;AN000;
1066 or al, al ;AN000;
1067 jz Endwr ;AN000;
1068;SB34LOAD003****************************************************************
1069;SB Write the character in al to the screen.
1070;SB Use Video service 'Write teletype to active page' (ROM_TELETYPE)
1071;SB Use normal character attribute
1072 mov ah, ROM_TELETYPE
1073 mov bl, 7 ;"normal" attribute ?
1074 int 10h ;video write
1075;SB34LOAD003****************************************************************
1076 jmp Write ;AN000;
1077Endwr: ;AN000;
1078 ret ;AN000;
1079Write endp
1080;
1081
1082;include MSbtmes.inc ;AN000;
1083include MSbio.cl1 ;AN001;
1084
1085Relocate_Length equ $ - start
1086Total_Length label byte
1087LoadBIO_Size equ $ - Start
1088
1089cseg ends
1090 end start
diff --git a/v4.0/src/BIOS/MSLOAD.INC b/v4.0/src/BIOS/MSLOAD.INC
new file mode 100644
index 0000000..1f8d73c
--- /dev/null
+++ b/v4.0/src/BIOS/MSLOAD.INC
@@ -0,0 +1,7 @@
1;MSLOAD.INC
2End_Of_File equ 0FFh
3FAT12_Bit equ 01h
4FAT16_Bit equ 04h
5ROM_TELETYPE equ 14 ;INT 10h, Teletype function
6
7NUM_DIR_PER_SECTOR equ 16 ; number of directory entries per sector
diff --git a/v4.0/src/BIOS/MSLPT.ASM b/v4.0/src/BIOS/MSLPT.ASM
new file mode 100644
index 0000000..ad858a0
--- /dev/null
+++ b/v4.0/src/BIOS/MSLPT.ASM
@@ -0,0 +1,270 @@
1 PAGE ,132 ;
2 TITLE MSLPT - BIOS
3 %OUT ...MSLPT.ASM
4
5;==============================================================================
6;REVISION HISTORY:
7;AN000 - New for DOS Version 4.00 - J.K.
8;AC000 - Changed for DOS Version 4.00 - J.K.
9;AN00x - PTM number for DOS Version 4.00 - J.K.
10;==============================================================================
11;AN001 - P156 KBMLPT device driver's retry logic. 8/18/87 J.K.
12;==============================================================================
13 itest=0
14 INCLUDE MSGROUP.INC ;DEFINE CODE SEGMENT
15 INCLUDE MSEQU.INC
16 INCLUDE MSMACRO.INC
17 INCLUDE DEVSYM.INC
18 INCLUDE IOCTL.INC
19
20 EXTRN BUS$EXIT:NEAR ;MSBIO1
21 EXTRN ERR$CNT:NEAR ;MSBIO1
22 EXTRN CMDERR:NEAR ;MSBIO1
23 EXTRN GETDX:NEAR ;MSBIO1
24 EXTRN EXIT:NEAR ;MSBIO1
25 EXTRN ERR$EXIT:NEAR ;MSBIO1
26;DATA
27 EXTRN PTRSAV:DWORD ;MSBIO1
28 EXTRN TIMDEV:WORD ;MSCLOCK
29 EXTRN LPT2DEV:WORD ;MSBIO2
30 EXTRN WAIT_COUNT:WORD ;MSDATA
31 EXTRN PRINTDEV:BYTE ;MSDATA
32; IBM ROM STATUS BITS (I DON'T TRUST THEM, NEITHER SHOULD YOU)
33
34NOTBUSYSTATUS = 10000000B ; NOT BUSY
35ACKSTATUS = 01000000B ; ACKNOWLEDGE (FOR WHAT?)
36NOPAPERSTATUS = 00100000B ; NO MORE PAPER
37SELECTEDSTATUS = 00010000B ; THE PRINTER SAID IT WAS SELECTED
38IOERRSTATUS = 00001000B ; SOME KINDA ERROR
39RESERVED = 00000110B ; NOPS
40TIMEOUTSTATUS = 00000001B ; TIME OUT.
41
42
43; WARNING!!! THE IBM ROM DOES NOT RETURN JUST ONE BIT. IT RETURNS A
44; WHOLE SLEW OF BITS, ONLY ONE OF WHICH IS CORRECT.
45
46;----------------------------------------------------------
47;J.K. AN001; PRN$WRIT will retry only if error code is TIMEOUT.
48
49; WRITE TO PRINTER DEVICE
50
51; CX HAS COUNT OF BYTES
52; ES:DI POINT TO DESTINATION
53; AUXNUM HAS PRINTER NUMBER
54
55 PUBLIC PRN$WRIT
56PRN$WRIT PROC NEAR
57 ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY
58
59 jcxz Prn$Done ;No char to output
60Prn$Loop:
61 mov bx, 2 ;Initialize retry count
62Prn$Out:
63;SB34LPT000****************************************************************
64;SB Print the character at ES:[DI]
65;SB Call the function PrnOP to do this
66;SB The character to be printed goes in AL and the function code
67;SB for 'Output character' goes in AH
68;SB Check for error in printing.
69;SB If there is no error go to print the next character.
70;SB If there is an error indicated see if it is due to TIMEOUT. If the
71;SB error is not TIMEOUT then we can do nothing about it. Just go to
72;SB print the next character. If it is due to timeout we can execute
73;SB the code to retry the print which follows this piece of code
74;SB LOCS: 6
75
76 mov al,es:[di] ; assume AX disposible since enter
77 xor ah,ah ; via int 21h
78 call PrnOp ; print to printer
79 jz Prn$Con ; no error - continue
80 test ah,TIMEOUTSTATUS
81 jz Prn$Con ; NOT time out - continue
82
83;SB34LPT000****************************************************************
84 dec bx ;Retry until count is exhausted.
85 jnz Prn$Out ;Retry it.
86 jmp short Pmessg ;Return with error.
87 ;
88 ; next character
89 ;
90Prn$Con:
91 inc di ;point to next char and continue
92 loop Prn$Loop
93Prn$Done:
94 jmp Exit
95Pmessg:
96 jmp Err$Cnt
97PRN$WRIT endp
98
99; JCXZ EXVEC3 ; NO CHARS TO OUTPUT..
100;PRN$LOOP:
101; MOV BX,2 ; INITIALIZE RETRY FLAG
102;PRN$OUT:
103; MOV AL,ES:[DI] ; GET CHAR INTO AL
104; INC DI ; POINT TO NEXT CHAR
105; XOR AH,AH ; AH=0 => OUTPUT CHAR IN DL
106; CALL PRNOP ; TO INDICATE PRINT CHAR IN AL
107; JNZ PRRETRY
108; LOOP PRN$LOOP
109;EXVEC3:
110; JMP EXIT
111;PRRETRY:
112; DEC DI ; UNDO THE INC ABOVE...
113; DEC BX
114; JNZ PRN$OUT
115;PMESSG:
116; JMP ERR$CNT ;RETURN WITH THE ERROR
117;PRN$WRIT ENDP
118
119;--------------------------------------------------------
120
121; PRINTER STATUS ROUTINE
122
123 PUBLIC PRN$STAT
124PRN$STAT PROC NEAR
125 ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY
126
127 CALL PRNSTAT ;DEVICE IN DX
128 JNZ PMESSG ; OTHER ERRORS WERE FOUND
129;J.K. The next three lines are commented out, since it is a dead code.
130; MOV AL,9 ; AGAIN, ASSUME OUT OF PAPER...
131; TEST AH,NOPAPERSTATUS
132; JNZ PMESSG
133 TEST AH,NOTBUSYSTATUS
134 jnz Prn$Done ;No error. Exit
135 JMP BUS$EXIT
136PRN$STAT ENDP
137
138; TAKE THE APPROPRIATE PRINTER AND DO THE OPERATION. TRIAGE THE STATUS
139; RETURNED IN AH INTO SOME MEANINGFUL ERROR.
140
141PRNSTAT PROC NEAR
142;SB33037**********************************************************************
143 mov AH, 2 ; set command for get status ;SB ;3.30*
144PRNOP: ;SB ;3.30*
145 call GETDX ; determine which printer ;SB ;3.30*
146 int 17h ; call ROM-BIOS printer routine ;SB;3.30*
147
148;SB33037**********************************************************************
149
150; EXAMINE THE STATUS BITS TO SEE IF AN ERROR OCCURRED. UNFORTUNATELY, SEVERAL
151; OF THE BITS ARE SET SO WE HAVE TO PICK AND CHOOSE. WE MUST BE EXTREMELY
152; CAREFUL ABOUT BREAKING BASIC.
153
154 TEST AH,IOERRSTATUS ; I/O ERROR?
155 JZ CHECKNOTREADY ; NO, TRY NOT READY
156
157; AT THIS POINT, WE KNOW WE HAVE AN ERROR. THE CONVERSE IS NOT TRUE.
158
159 MOV AL,9 ; FIRST, ASSUME OUT OF PAPER
160 TEST AH,NOPAPERSTATUS ; OUT OF PAPER SET?
161 JNZ RET1 ; YES, ERROR IS SET
162 INC AL ; INDICATE I/O ERROR
163RET1:
164
165; WE HAVE TRIAGED NOW FOR OUT OF PAPER AND IO ERR (IGNORING TIME-OUT)
166
167 RET ; RETURN WITH ERROR
168
169; THE BITS SAID NO ERROR. UNFORTUNATELY, THERE MAY BE OTHER THINGS AT WORK
170; HERE.
171
172CHECKNOTREADY:
173 MOV AL,2 ; ASSUME NOT-READY
174 TEST AH,TIMEOUTSTATUS ; IS TIME-OUT SET?
175 ; IF NZ THEN ERROR, ELSE OK???
176PRNOP2:
177 RET
178PRNSTAT ENDP
179
180; OUTPUT UNTIL BUSY. THIS ENTRY POINT IS USED EXCLUSIVELY BY THE PRINT
181; SPOOLERS. UNDER NO CURCUMSTANCES SHOULD THE DEVICE DRIVER BLOCK WAITING FOR
182; THE DEVICE TO BECOME READY.
183
184; INPUTS: CX HAS COUNT OF BYTES TO OUTPUT.
185; ES:DI POINTS TO SOURCE BUFFER
186; OUTPUTS: SET THE NUMBER OF BYTES TRANSFERRED APPROPRIATELY
187 PUBLIC PRN$TILBUSY
188PRN$TILBUSY PROC NEAR
189 ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY
190
191 PUSH DS
192 PUSH ES
193 POP DS ; NOW ES AND DS BOTH POINT TO SOURCE BUFFER
194 ASSUME DS:NOTHING
195
196 MOV SI,DI ; EVERYTHING IS SET FOR LODSB
197PRN$TILBLOOP:
198 PUSH CX
199 PUSH BX
200 XOR BX,BX
201 MOV BL,CS:[PRINTDEV]
202 SHL BX,1
203 MOV CX,CS:WAIT_COUNT[BX] ; WAIT COUNT TIMES TO COME READY
204 POP BX
205PRN$GETSTAT:
206 CALL PRNSTAT ; GET STATUS
207 JNZ PRN$BPERR ; ERROR
208 TEST AH,10000000B ; READY YET?
209 LOOPZ PRN$GETSTAT ; NO, GO FOR MORE
210 POP CX ; GET ORIGINAL COUNT
211 JZ PRN$BERR ; STILL NOT READY => DONE
212 LODSB
213 XOR AH,AH
214 CALL PRNOP
215 JNZ PRN$BERR ; ERROR
216 LOOP PRN$TILBLOOP ; GO FOR MORE
217PRN$B:
218 POP DS
219 LDS BX,CS:[PTRSAV]
220 ASSUME DS:NOTHING
221 SUB WORD PTR [BX].COUNT,CX ;# OF SUCCESSFUL I/O'S
222 JMP EXIT
223PRN$TILBUSY ENDP
224
225PRN$BPERR PROC NEAR
226 ASSUME DS:CODE
227 POP CX
228PRN$BERR:
229 POP DS
230 LDS BX,CS:[PTRSAV]
231 ASSUME DS:NOTHING
232
233 SUB WORD PTR [BX].COUNT,CX ;# OF SUCCESSFUL I/O'S
234 JMP ERR$EXIT
235PRN$BPERR ENDP
236;
237; MANIPULATES THE VALUE IN WAIT_COUNT DEPENDING ON THE VALUE PASSED IN THE
238; GENERIC IOCTL PACKET.
239; IT EITHER SETS OR RETURNS THE CURRENT VALUE FOR THE RETRY COUNT FOR THE
240; DEVICE.
241;
242 PUBLIC PRN$GENIOCTL
243PRN$GENIOCTL PROC NEAR
244 ASSUME DS:CODE ; SET BY PRINTER DEVICE DRIVER ENTRY
245
246 LES DI,[PTRSAV]
247 CMP ES:[DI].MAJORFUNCTION,IOC_PC
248 JE PRNFUNC_OK
249PRNFUNCERR:
250 JMP CMDERR
251
252PRNFUNC_OK:
253 MOV AL,ES:[DI].MINORFUNCTION
254 LES DI,ES:[DI].GENERICIOCTL_PACKET
255 XOR BX,BX
256 MOV BL,[PRINTDEV] ; GET INDEX INTO RETRY COUNTS
257 SHL BX,1
258 MOV CX,WAIT_COUNT[BX] ; PULL OUT RETRY COUNT FOR DEVICE
259 CMP AL,GET_RETRY_COUNT
260 JZ PRNGETCOUNT
261 CMP AL,SET_RETRY_COUNT
262 JNZ PRNFUNCERR
263 MOV CX,ES:[DI].RC_COUNT
264PRNGETCOUNT:
265 MOV WAIT_COUNT[BX],CX ; PLACE "NEW" RETRY COUNT
266 MOV ES:[DI].RC_COUNT,CX ; RETURN CURRENT RETRY COUNT
267 JMP EXIT
268PRN$GENIOCTL ENDP
269CODE ENDS
270 END
diff --git a/v4.0/src/BIOS/MSMACRO.INC b/v4.0/src/BIOS/MSMACRO.INC
new file mode 100644
index 0000000..efc034c
--- /dev/null
+++ b/v4.0/src/BIOS/MSMACRO.INC
@@ -0,0 +1,192 @@
1;
2; This file contains three macros used in debugging the system. If the
3; variable "itest" (in msbio.asm) is nonzero code is included in the
4; modules to print debugging messages. The level of debugging is controlled
5; by the value of the variable fTestBits in msbio.asm. Specific bits in
6; the variable determine which messages to print. The equ's below tell
7; which bits control which funcitons. For example the fifth bit
8; cooresponds to disk activity (see fTestDisk equ below).
9;
10; The macros in the file are:
11;
12; message Prints an ascii string on the screen.
13; Example usage:
14;
15; message fTestDisk, <"Start Disk Write", CR, LF>
16; message fTestINIT, <"Begin BDS initialization">
17;
18;
19; MNUM Print the value in a register or memory location on
20; the screen. Value is displayed in hex.
21; Usage:
22; MNUM bitpattern, valueLocation
23;
24; valueLocation is typically a regester:
25;
26; mnum fTestCom, AX
27; mnum fTestDisk, DX
28;
29; ValueLocation can also be a memory location:
30;
31; mnum fTestINIT, Final_Dos_Location
32;
33; If no valueLocation is given the macro defaults to
34; the BX register.
35;
36; ZWAIT Stops the program until any key is pressed.
37;
38;
39; The three macros preserve all register values. If "test" is zero
40; defined during assembly then the marco produce no code.
41;
42
43 IF iTEST ;3.30
44 IFNDEF MSGOUT ;3.30
45 EXTRN MSGOUT:NEAR,MSGNUM:NEAR ;3.30
46 ENDIF ;3.30
47 IFNDEF NUMBUF ;3.30
48 EXTRN NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD ;3.30
49 ENDIF ;3.30
50 IFNDEF DUMPBYTES ;3.30
51 EXTRN DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR ;3.30
52 ENDIF ;3.30
53
54
55
56fTestALL equ 1111111111111111b ; watch everything
57fTestHARD equ 0000000000000001b ; watch hard disk initialization
58fTest96 equ 0000000000000010b ; watch 96 tpi activity
59FTEST13 EQU 0000000000000100B ; WATCH INT 13 ACTIVITY ;3.30
60FTESTCOM EQU 0000000000001000B ; WATCH PACKET ACTIVITY ;3.30
61FTESTINIT EQU 0000000000010000B ; WATCH INITIALIZATION MESSAGES ;3.30
62FTESTDISK EQU 0000000000100000B ; WATCH DISK DEVICE DRIVER CALLS ;3.30
63FTESTCON EQU 0000000001000000B ; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE
64FtestClock equ 0000000010000000b ; wathc clock device 5/2/86 ;3.30
65
66
67;
68; message macro -- see above for description
69;
70
71MESSAGE MACRO Bits,msg
72 LOCAL A,B ;3.30
73 jmp SHORT b
74a: db msg,0
75b: push SI
76 push AX
77 mov AX,Bits
78 mov SI,OFFSET a
79 call MSGOUT
80 pop AX
81 pop SI
82endm
83
84
85;
86; mnum macro -- see above for description
87;
88
89MNum MACRO Bits,num
90 push AX
91ifb <num>
92 mov AX,Bits
93 call MSGNUM
94else
95 push BX
96 mov BX,num
97 mov AX,Bits
98 call MSGNUM
99 pop BX
100endif
101 pop AX
102endm
103
104
105;
106; zwait macro -- see above for description
107;
108
109ZWAIT MACRO
110 Message fTestALL,<"? ">
111 CALL ZWAITrtn
112ENDM
113
114ZWAITrtn:
115 pushf ; save the flags
116 push AX ; preserve AX
117 xor AH, AH ; set command to get character ;3.30*
118 int 16h ; call rom keyboard routine ;3.30*
119 pop AX ; restore AX
120 popf ; restore the flags
121 ret
122
123;Dump_byte dumps the memory contents in hex. ;3.30
124;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG. ;3.30
125DUMP_BYTE MACRO DUMPSEG, DUMPOFFLABEL, BYTELENGTH ;3.30
126 push es ;3.30
127 PUSH DS ;3.30
128 PUSH SI ;3.30
129 PUSH CX ;3.30
130 ;3.30
131 MOV CX, DUMPSEG ;3.30
132 MOV DS, CX ;3.30
133 MOV SI, OFFSET DUMPOFFLABEL ;3.30
134 MOV CX, BYTELENGTH ;3.30
135 call dumpbytes ;3.30
136 ;3.30
137 POP CX ;3.30
138 POP SI ;3.30
139 POP DS ;3.30
140 pop es ;3.30
141 ENDM ;3.30
142 ;3.30
143;Dump_Byte_Reg dumps the memory contents in hex. - 4/9/86 ;3.30
144;DUMPOFFREG should be a register contains the offset value in DUMPSEG. ;3.30
145DUMP_BYTE_REG MACRO DUMPSEG, DUMPOFFREG, BYTELENGTH ;3.30
146 push es ;3.30
147 PUSH DS ;3.30
148 PUSH SI ;3.30
149 PUSH CX ;3.30
150 ;3.30
151 MOV CX, DUMPSEG ;3.30
152 MOV DS, CX ;3.30
153 MOV SI, DUMPOFFREG ;3.30
154 MOV CX, BYTELENGTH ;3.30
155 call dumpbytes ;3.30
156 ;3.30
157 POP CX ;3.30
158 POP SI ;3.30
159 POP DS ;3.30
160 pop es ;3.30
161 ENDM ;3.30
162
163else
164 ; if test is not defined then make macro into null statements
165Message macro
166ENDM
167
168MNUM macro
169ENDM
170
171ZWAIT macro
172ENDM
173
174DUMP_BYTE MACRO ;3.30
175 ENDM ;3.30
176DUMP_BYTE_REG MACRO ;3.30
177 ENDM ;3.30
178 ENDIF ;3.30
179 ;3.30
180PATHSTART MACRO INDEX,ABBR ;3.30
181 IFDEF PATHGEN ;3.30
182 PUBLIC ABBR&INDEX&S,ABBR&INDEX&E ;3.30
183 ABBR&INDEX&S LABEL BYTE ;3.30
184 ENDIF ;3.30
185 ENDM ;3.30
186 ;3.30
187PATHEND MACRO INDEX,ABBR ;3.30
188 IFDEF PATHGEN ;3.30
189 ABBR&INDEX&E LABEL BYTE ;3.30
190 ENDIF ;3.30
191 ENDM ;3.30
192
diff --git a/v4.0/src/BIOS/MSSTACK.INC b/v4.0/src/BIOS/MSSTACK.INC
new file mode 100644
index 0000000..21a2095
--- /dev/null
+++ b/v4.0/src/BIOS/MSSTACK.INC
@@ -0,0 +1,306 @@
1; MSStack.inc
2;
3; Interrupt level 2, 3, 4, 5, 6, 7,(10, 11, 12, 14, 15 - AT level)
4; should follow the standard Interrupt Sharing Scheme which has
5; a standard header structure.
6; Fyi, the following shows the relations between
7; the interrupt vector and interrupt level.
8; VEC(Hex) 2 8 9 A B C D E 70 72 73 74 76 77
9; LVL(Deci) 9 0 1 2 3 4 5 6 8 10 11 12 14 15
10; MSSTACK module modifies the following interrupt vectors
11; to meet the standard Interrupt Sharing standard;
12; A, B, C, D, E, 72, 73, 74, 76, 77.
13; Also, for interrupt level 7 and 15, the FirstFlag in a standard header
14; should be initialized to indicat whether this interrupt handler is
15; the first (= 80h) or not. The FirstFlag entry of INT77h's
16; program header is initialized in STKINIT.INC module.
17; FirstFlag is only meaningful for interrupt level 7 and 15.
18;
19
20; User specifies the number of stack elements - default = 9
21; minimum = 8
22; maximum = 64
23;
24; Intercepts Asynchronous Hardware Interrupts only
25;
26; Picks a stack from pool of stacks and switches to it
27;
28; Calls the previously saved interrupt vector after pushing flags
29;
30; On return, returns the stack to the stack pool
31;
32
33
34; This is a modification of STACKS:
35; 1. To fix a bug which was causing the program to take up too much space.
36; 2. To dispense stack space from hi-mem first rather than low-mem first.
37; . Clobbers the stack that got too big instead of innocent stack
38; . Allows system to work if the only stack that got too big was the most
39; deeply nested one
40; 3. Disables NMI interrupts while setting the NMI vector.
41; 4. Does not intercept any interupts on a PCjr.
42; 5. Double checks that a nested interrupt didn't get the same stack.
43; 6. Intercepts Ints 70, 72-77 for PC-ATs and other future products
44
45;The following variables are for MSSTACK.inc
46 EVEN
47 dw 0 ; SPARE FIELD BUT LEAVE THESE IN ORDER
48StackCount dw 0
49StackAt dw 0
50StackSize dw 0
51Stacks dw 0
52 dw 0
53
54FirstEntry dw Stacks
55LastEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
56NextEntry dw Stacks+(DefaultCount*EntrySize)-EntrySize
57
58;End of variables defined for MSSTACK.
59
60;*******************************************************************
61;Macro Interrupt handler for the ordinary interrupt vectors and
62;the shared interrupt vectors.
63;*****************************
64Stack_Main MACRO AA
65 ASSUME DS:NOTHING
66 ASSUME ES:NOTHING
67 ASSUME SS:NOTHING
68PUBLIC Int&AA
69PUBLIC Old&AA
70;-----------------------------
71 ife IntSharingFlag ;if not IntSharingFlag
72;-----------------------------
73 Old&AA DD 0
74Int&AA PROC FAR
75;-----------------------------
76 else ;for shared interrupt. A Header exists.
77
78PUBLIC FirstFlag&AA
79Int&AA PROC FAR
80 jmp short Entry_Int&AA&_Stk
81 Old&AA dd 0 ;Forward pointer
82 dw 424Bh ;compatible signature for Int. Sharing
83 FirstFlag&AA db 0 ;the firstly hooked.
84 jmp short Intret_&AA ;Reset routine. We don't care this.
85 db 7 dup (0) ;Reserved for future.
86Entry_Int&AA&_Stk:
87;-----------------------------
88 endif
89;-----------------------------
90
91;
92; Keyboard interrupt must have a three byte jump, a NOP and a zero byte
93; as its first instruction for compatibility reasons
94 ifidn <&aa>,<09>
95 jmp Keyboard_lbl
96 nop
97 db 0
98Keyboard_lbl label near
99 endif
100
101; This patches INTERRUPT 75h to be "unhooked". We do this Wierdness,
102; rather than never hooking INT 75h, to maintain maximum compat. with IBMs
103; post production patch.
104 push ax
105
106 ifidn <&aa>,<02>
107
108; *********************************************************************
109;
110; This is special support for the PC Convertible / NMI handler
111;
112; On the PC Convertible, there is a situation where an NMI can be
113; caused by using the "OUT" instructions to certain ports. When this
114; occurs, the PC Convertible hardware *GUARANTEES* that **NOTHING**
115; can stop the NMI or interfere with getting to the NMI handler. This
116; includes other type of interrupts (hardware and software), and
117; also includes other type of NMI's. When any NMI has occured,
118; no other interrtupt (hardware, software or NMI) can occur until
119; the software takes specific steps to allow further interrupting.
120;
121; For PC Convertible, the situation where the NMI is generated by the
122; "OUT" to a control port requires "fixing-up" and re-attempting. In
123; otherwords, it is actually a "restartable exception". In this
124; case, the software handler must be able to get to the stack in
125; order to figure out what instruction caused the problem, where
126; it was "OUT"ing to and what value it was "OUT"ing. Therefore,
127; we will not switch stacks in this situation. This situation is
128; detected by interrogating port 62h, and checking for a bit value
129; of 80h. If set, *****DO NOT SWITCH STACKS*****.
130;
131; *********************************************************************
132
133 push es
134 mov ax,0f000h
135 mov es,ax
136 cmp byte ptr es:[0fffeh],mdl_convert ;check if convertible
137 pop es
138 jne Normal&aa
139
140 in al,62h
141 test al,80h
142 jz Normal&aa
143
144Special&aa:
145 pop ax
146 jmp dword ptr Old&aa
147
148Normal&aa:
149
150; *********************************************************************
151
152 endif
153
154 push bp
155 push es
156 mov es, cs:[STACKS+2] ; Get segment of stacks
157
158 mov bp,NextEntry ; get most likely candidate
159 mov al,Allocated
160 xchg AllocByte,al ; grab the entry
161 cmp al,Free ; still avail?
162 jne NotFree&aa
163
164 sub NextEntry,EntrySize ; set for next interrupt
165
166Found&aa:
167 mov SavedSP,sp ; save sp value
168 mov SavedSS,ss ; save ss also
169; mov IntLevel,aa&h ; save the int level
170
171 mov ax,bp ; temp save of table offset
172
173 mov bp,NewSP ; get new SP value
174 cmp es:[bp],ax ; check for offset into table
175 jne FoundBad&aa
176
177 mov ax,es ; point ss,sp to the new stack
178 mov ss,ax
179 mov sp,bp
180
181 pushf ; go execute the real interrupt handler
182 call dword ptr old&aa ; which will iret back to here
183
184 mov bp,sp ; retrieve the table offset for us
185 mov bp,es:[bp] ; but leave it on the stack
186 mov ss,SavedSS ; get old stack back
187 mov sp,SavedSP
188
189; cmp AllocByte,Allocated ; If an error occured,
190; jne NewError&aa ; do not free us
191
192 mov AllocByte,Free ; free the entry
193 mov NextEntry,bp ; setup to use next time
194
195NewError&aa:
196 pop es
197 pop bp ; saved on entry
198 pop ax ; saved on entry
199
200INTRET_&AA: ;3.30
201 iret ; done with this interrupt
202
203NotFree&aa:
204 cmp al,Allocated ; error flag
205 je findnext&aa ; no, continue
206 xchg AllocByte,al ; yes, restore error value
207
208FindNext&aa:
209 call LongPath
210 jmp Found&aa
211
212FoundBad&aa:
213 cmp bp,FirstEntry
214 jc findnext&aa
215 mov bp,ax ; flag this entry
216 mov AllocByte,Clobbered
217; add bp,EntrySize ; and previous entry
218; mov AllocByte,Overflowed
219; sub bp,EntrySize
220 jmp findnext&aa ; keep looking
221
222int&aa endp
223
224
225 endm
226
227;***************************** ;3.30
228;End of Macro definition ;3.30
229;******************************************************************** ;3.30
230; THESE ARE THE INDIVIDUAL INTERRUPT HANDLERS ;3.30
231 ;3.30
232 IRP A,<02,08,09,70> ;3.30
233 IntSharingFlag=0 ;3.30
234 Stack_Main &A ;3.30
235 ENDM ;3.30
236 ;3.30
237 IRP A,<0A,0B,0C,0D,0E,72,73,74,76,77> ;3.30
238 IntSharingFlag=1 ;3.30
239 Stack_Main &A ;3.30
240 ENDM ;3.30
241 ;3.30
242;******************************************************************** ;3.30
243;Common routines ;3.30
244
245longpath:
246 mov bp,LastEntry ; start with last entry in table
247
248LPLOOPP: ;3.30
249 cmp AllocByte,Free ; is entry free?
250 jne inuse ; no, try next one
251
252 mov al,Allocated
253 xchg AllocByte,al ; allocate entry
254 cmp al,Free ; is it still free?
255 je found ; yes, go use it
256
257 cmp al,Allocated ; is it other than Allocated or Free?
258 je inuse ; no, check the next one
259
260 mov AllocByte,al ; yes, put back the error state
261
262inuse:
263 cmp bp,FirstEntry
264 je Fatal
265 sub bp,EntrySize
266 JMP LPLOOPP ;3.30
267
268found:
269 ret
270
271 page
272
273fatal proc near
274 push ds ;3.30
275 mov ax, 0f000h ;loook at the model byte ;3.30
276 mov ds, ax ;3.30
277 cmp ds:byte ptr [0fffeh], mdl_convert ;convertible? ;3.30
278 pop ds ;3.30
279 jne Skip_NMIS ;3.30
280 ;3.30
281 mov al,07h ; disable PC Convertible NMIs
282 out 72h,al
283
284Skip_NMIS: ;3.30
285 cli ; disable and mask
286 mov al,0ffh ; all other ints
287 out 021h,al
288 out 0a1h,al
289
290 mov si,cs
291 mov ds,si
292 mov si,offset fatal_msg
293
294fatal_loop:
295 lodsb
296 cmp al,'$'
297 je fatal_done
298
299 mov bl,7 ;3.30*
300 mov ah,14 ;3.30*
301 int 010h ; whoops, this enables ints ;3.30*
302 jmp fatal_loop
303
304fatal_done:
305 jmp fatal_done
306fatal endp
diff --git a/v4.0/src/BIOS/MSVOLID.INC b/v4.0/src/BIOS/MSVOLID.INC
new file mode 100644
index 0000000..d1a9588
--- /dev/null
+++ b/v4.0/src/BIOS/MSVOLID.INC
@@ -0,0 +1,297 @@
1;-------------------------------------------------------------------------
2;
3; File: msvolid.asm
4; This file contains the volume_id subroutines and data structures.
5;
6; Routines in this file are:
7; Set_Volume_ID - main routine, calls other routines.
8; read_volume_id - read the volume ID and tells if it has
9; been changed.
10; Transfer_volume_id - copy the volume ID from TMP to special
11; drive.
12; Check_Volume_ID - compare volume ID in TMP area with one
13; expected for drive.
14; Fat_Check - see of the fatID has changed in the
15; specified drive.
16; Init_Vid_loop - set up for VID scan or move
17;
18;
19;-------------------------------------------------------------------------
20
21;
22; length of the volume id
23;
24
25vid_size equ 12
26
27 PATHSTART 001,VOLID ;3.30
28
29;
30; null volume id
31;
32
33nul_vid db "NO NAME ",0
34
35;
36; data scratch area used to hold volume ids
37;
38
39tmp_vid db "NO NAME ",0
40
41 PATHEND 001,VOLID ;3.30
42
43;
44; Set_Volume_ID
45; If drive has changeline support, read in and set the volume_ID
46; and the last FAT_ID byte. If no change line support then do nothing.
47;
48; On entry:
49; DS:DI points to the BDS for this disk.
50; AH contains media byte
51;
52; On Exit:
53; Carry clear:
54; Successful call
55; Carry set
56; Error and AX has error code
57;
58
59Set_Volume_ID:
60 PUBLIC SET_VOLUME_ID ;3.30
61 push dx ; save registers
62 push ax
63 CALL HasChange ; does drive have changeline support?
64 jz setvret ; no, get out
65 push di
66 call read_volume_ID ; read the volume ID
67 pop di
68 jc SetErr ; if error go to error routine
69 call transfer_volume_ID ; copy the volume id to special drive
70 call ResetChanged ; restore value of change line
71
72setvret: ; SET Volume RETurn
73 clc ; no error, clear carry flag
74 pop ax ; restore registers
75 pop dx
76 ret
77SetErr:
78 pop dx ; pop stack but don't overwrite AX
79 pop dx ; restore DX
80 ret
81
82
83
84root_sec DW ? ;Root sector #
85
86
87
88
89;
90; read_volume_id read the volume ID and tells if it has been changed.
91;
92; On entry:
93; DS:DI points to current BDS for drive.
94; On Exit:
95; Carry Clear
96; SI = 1 No change
97; SI = 0 ?
98; SI = -1 Change
99;
100; Carry Set:
101; Error and AX has error code.
102;
103
104read_volume_id:
105 push ES ; preserve registers
106 push DX
107 push CX
108 push BX
109 push AX
110 push DS ; Preserve Current BDS
111 push DI
112 push cs ; get ES segment correct
113 pop es
114 push cs ; get DS segment correct
115 pop ds
116 mov di,offset tmp_vid
117 mov si,offset nul_vid
118 mov cx,vid_size
119 rep movsb ; initialize tmp_vid to null vi_id
120
121 pop DI ; Restore Current BDS
122 pop DS
123 mov al,byte ptr ds:[di].cFAT ; # of fats
124 mov cx,word ptr ds:[di].csecfat ; sectors / fat
125 mul cl ; size taken by fats
126 add ax,word ptr ds:[di].ressec ; add on reserved sectors
127 ; AX is now sector # (0 based)
128 mov cs:[root_sec],ax ; set initial value
129 mov ax,[di].cDir ; # root dir entries
130 mov cl,4 ; 16 entries/sector
131 shr ax,cl ; divide by 16
132 mov cx,ax ; cx is # of sectors to scan
133next_sec:
134 push cx ; save outer loop counter
135 mov ax,cs:[root_sec] ; get sector #
136 mov cx,word ptr ds:[di].seclim ; sectors / track
137 xor DX,DX
138 div cx
139 ; set up registers for call to read_sector
140 inc DX ; dx= sectors into track, ax= track count from 0
141 mov cl,dl ; sector to read
142 xor DX,DX
143 div word ptr ds:[di].hdlim ; # heads on this disc
144 mov dh,dl ; Head number
145 mov ch,al ; Track #
146 call read_sector ; get first sector of the root directory,
147 ; ES:BX -> BOOT
148 jc ReadVIDErr ; error on read
149 mov cx,16 ; # of dir entries in a block of root
150 mov al,08h ; volume label bit
151fvid_loop:
152 cmp byte ptr es:[bx],0 ; End of dir?
153 jz no_vid ; yes, no vol id
154 cmp byte ptr es:[bx],0E5h ; empty entry?
155 jz ent_loop ; yes, skip
156 test es:[bx+11],al ; is volume label bit set in fcb?
157 jnz found_vid ; jmp yes
158ent_loop:
159 ADD BX,32 ;MJB003 ADD LENGTH OF DIRECTORY ENTRY ;3.30
160 loop fvid_loop
161 pop cx ; outer loop
162 inc cs:[root_sec] ; next sector
163 loop next_sec ; continue
164NotFound:
165 XOR SI,SI
166 jmp short fvid_ret
167
168found_vid:
169 pop cx ; clean stack of outer loop counter
170 mov si,bx ; point to volume_id
171 push ds ; preserve currnet BDS
172 push di
173 push es ; es:si points to volume id.
174 pop ds ; source segment
175 push cs
176 pop es ; destination segment
177 mov di,offset tmp_vid ; dest of volume_id
178 mov cx,vid_size -1 ; length of string minus NUL
179 rep movsb ; mov volume label to tmp_vid
180 xor al,al
181 stosb ; Null terminate
182 XOR SI,SI
183 pop DI ; restore current BDS
184 pop DS
185fvid_ret:
186 pop ax
187 clc
188RVIDRet:
189 pop BX ; restore register
190 pop CX
191 pop DX
192 pop ES
193 ret
194no_vid:
195 pop cx ; clean stack of outer loop counter
196 jmp NotFound ; not found
197ReadVIDErr:
198 pop SI
199 pop SI
200 jmp RVIDRet
201
202
203
204;
205; Transfer_volume_id - copy the volume ID from TMP to special drive
206;
207; Inputs: DS:DI nas current BDS
208; Outputs: BDS for drive has volume ID from TMP
209;
210
211transfer_volume_ID:
212 push DS ; preserve current BDS
213 push DI
214 push ES
215 push SI
216 push CX
217 call init_vid_loop
218 cld
219 rep MOVSB ; transfer
220 pop CX
221 pop SI
222 pop ES
223 pop DI ; restore current BDS
224 pop DS
225 ret
226
227
228;
229; Check_Volume_ID - compare volume ID in TMP area with one expected for
230; drive
231;
232; Inputs: DS:DI has current BDS for drive
233; Outputs: SI = 0 if compare succeeds
234; SI = -1 if compare fails.
235
236check_volume_id:
237 push DS ; preserve current BDS for drive
238 push DI
239 push ES
240 push CX
241 call init_vid_loop
242 cld
243 repz cmpsb ; are the 2 volume_ids the same?
244 mov si,0 ; assume unknown
245 jz check_vid_ret ; carry clear if jump taken
246 mov si,-1 ; failure
247check_vid_ret:
248 pop CX
249 pop ES
250 pop DI ; restore current BDS
251 pop DS
252 ret
253
254;
255; Fat_Check - see of the fatID has changed in the specified drive.
256; - uses the FAT ID obtained from the boot sector.
257;
258; Inputs: MedByt is expected FAT ID
259; DS:DI points to current BDS
260; Output: Carry Clear
261; SI = -1 if fat ID different,
262; SI = 0 otherwise
263; No other registers changed.
264
265FAT_CHECK:
266 push AX
267 xor SI, SI ; say FAT ID's are same.
268 mov AL, cs:MedByt
269 cmp AL, byte ptr [DI].Mediad ; compare it with the BDS medbyte
270 jz OKRET1 ; carry clear
271 dec SI
272OkRet1: clc
273 pop AX
274 ret
275
276
277;
278; Init_Vid_loop - set up for VID scan or move
279;
280; Inputs: DS:DI pionts to BDS for the drive
281; Outputs: DS:SI points to tmp_vid
282; ES:DI points to vid for drive
283; CX has size for VID compare
284;
285
286init_vid_loop:
287 push ax
288 push ds
289 pop es
290 push cs
291 pop ds
292 mov si,offset tmp_vid ; source
293 add di,volid
294 mov cx,vid_size
295 pop ax
296 ret
297
diff --git a/v4.0/src/BIOS/PSOPTION.INC b/v4.0/src/BIOS/PSOPTION.INC
new file mode 100644
index 0000000..d7f56d4
--- /dev/null
+++ b/v4.0/src/BIOS/PSOPTION.INC
@@ -0,0 +1,63 @@
1;*******************************************************************
2; Parser Options set for IBMBIO SYSCONF module
3;*******************************************************************
4;
5;**** Default assemble swiches definition **************************
6
7IFNDEF FarSW
8FarSW equ 0 ; Near call expected
9ENDIF
10
11IFNDEF DateSW
12DateSW equ 0 ; Check date format
13ENDIF
14
15IFNDEF TimeSW
16TimeSW equ 0 ; Check time format
17ENDIF
18
19IFNDEF FileSW
20FileSW equ 1 ; Check file specification
21ENDIF
22
23IFNDEF CAPSW
24CAPSW equ 0 ; Perform CAPS if specified
25ENDIF
26
27IFNDEF CmpxSW
28CmpxSW equ 0 ; Check complex list
29ENDIF
30
31IFNDEF NumSW
32NumSW equ 1 ; Check numeric value
33ENDIF
34
35IFNDEF KeySW
36KeySW equ 0 ; Support keywords
37ENDIF
38
39IFNDEF SwSW
40SwSW equ 1 ; Support switches
41ENDIF
42
43IFNDEF Val1SW
44Val1SW equ 1 ; Support value definition 1
45ENDIF
46
47IFNDEF Val2SW
48Val2SW equ 0 ; Support value definition 2
49ENDIF
50
51IFNDEF Val3SW
52Val3SW equ 1 ; Support value definition 3
53ENDIF
54
55IFNDEF DrvSW
56DrvSW equ 1 ; Support drive only format
57ENDIF
58
59IFNDEF QusSW
60QusSW equ 0 ; Support quoted string format
61ENDIF
62
63 \ No newline at end of file
diff --git a/v4.0/src/BIOS/PUSHPOP.INC b/v4.0/src/BIOS/PUSHPOP.INC
new file mode 100644
index 0000000..aaa76eb
--- /dev/null
+++ b/v4.0/src/BIOS/PUSHPOP.INC
@@ -0,0 +1,20 @@
1 IF1 ;3.30
2
3SaveReg MACRO reglist ;; push those registers
4IRP reg,<reglist>
5 ?stackdepth = ?stackdepth + 1
6 PUSH reg
7ENDM
8ENDM
9.xcref SaveReg
10
11
12RestoreReg MACRO reglist ;; pop those registers
13IRP reg,<reglist>
14 ?stackdepth = ?stackdepth - 1
15 POP reg
16ENDM
17ENDM
18.xcref RestoreReg
19
20 ENDIF ;3.30
diff --git a/v4.0/src/BIOS/READCLOC.INC b/v4.0/src/BIOS/READCLOC.INC
new file mode 100644
index 0000000..700f0aa
--- /dev/null
+++ b/v4.0/src/BIOS/READCLOC.INC
@@ -0,0 +1,165 @@
1; SCCSID = @(#)readclock.asm 1.2 85/07/25
2;************************************************************************
3;
4; read_real_date reads real-time clock for date and returns the number
5; of days elapsed since 1-1-80 in si
6;
7read_real_date: ;mjb002
8 assume ds:code,es:nothing
9 PUSH AX
10 PUSH CX
11 PUSH DX
12 XOR AH,AH ; throw away clock roll over ;3.30*
13 INT 1AH ;3.30*
14 POP DX
15 POP CX
16 POP AX
17
18 PUSH AX
19 PUSH BX
20 PUSH CX
21 PUSH DX
22 MOV CS:DAYCNT2,1 ;MJB002 REAL TIME CLOCK ERROR FLAG (+1 DA;3.30Y)
23 mov ah,4 ;mjb002 read date function code ;3.30*
24 int 1ah ;mjb002 read real-time clock ;3.30*
25 jnc read_ok ;mjb002 jmp success
26 jmp r_d_ret ;mjb002 jmp error
27read_ok: ;mjb002 ******* get bcd values in binary *****
28 mov byte ptr bin_date_time+0,ch ;mjb002 store as hex value
29 mov byte ptr bin_date_time+1,cl ;mjb002 ...
30 mov byte ptr bin_date_time+2,dh ;mjb002 ...
31 mov byte ptr bin_date_time+3,dl ;mjb002 ...
32 MOV CS:DAYCNT2,2 ;MJB002 READ OF R-T CLOCK SUCCESSFUL ;3.30
33 call bcd_verify ;mjb002 verify bcd values in range
34 jc r_d_ret ;mjb002 jmp some value out of range
35 MOV CS:DAYCNT2,3 ;MJB002 READ OF R-T CLOCK SUCCESSFUL ;3.30
36 call date_verify ;mjb002 verify date values in range
37 jc r_d_ret ;mjb002 jmp some value out of range
38 MOV CS:DAYCNT2,0 ;MJB002 VERIFY SUCCESSFUL ;3.30;3.30
39 call in_bin ;mjb002 convert date to binary
40 ;mjb002 ******* years since 1-1-80 *********
41 mov al,byte ptr bin_date_time+1 ;mjb002 get years into century
42 cbw ;mjb002
43 cmp byte ptr bin_date_time+0,20 ;mjb002 20th century?
44 jnz century_19 ;mjb002 jmp no
45 add ax,100 ;mjb002 add in a century
46century_19: ;mjb002
47 sub ax,80 ;mjb002 subtract off 1-1-80
48 mov cl,4 ;mjb002 leap year every 4
49 div cl ;mjb002 al= # leap year blocks, ah= remainder
50 mov bl,ah ;mjb002 save odd years
51 cbw ;mjb002 zero ah
52 mov cx,366+3*365 ;mjb002 # of days in leap year blocks
53 mul cx ;mjb002 dx:ax is result
54 MOV CS:DAYCNT2,AX ;MJB002 SAVE COUNT OF DAYS ;3.30
55 mov al,bl ;mjb002 get odd years count
56 cbw ;mjb002
57 or ax,ax ;mjb002 is ax= 0?
58 jz leap_year ;mjb002 jmp if none
59 mov cx,365 ;mjb002 days in year
60 mul cx ;mjb002 dx:ax is result
61 ADD CS:DAYCNT2,AX ;MJB002 ADD ON DAYS IN ODD YEARS ;3.30
62 jmp short leap_adjustment ;mjb002 account for leap year
63leap_year: ;mjb002 possibly account for a leap day
64 cmp byte ptr bin_date_time+2,2 ;mjb002 is month february
65 jbe no_leap_adjustment ;mjb002 jan or feb. no leap day yet.
66leap_adjustment: ;mjb002 account for leap day
67 INC CS:DAYCNT2 ;MJB002 ... ;3.30
68no_leap_adjustment: ;mjb002 ******* get days of month *******
69 mov cl,byte ptr bin_date_time+3 ;mjb002 ...
70 xor ch,ch ;mjb002
71 dec cx ;mjb002 because of offset from day 1, not day 0
72 ADD CS:DAYCNT2,CX ;MJB002 ******* GET DAYS IN MONTHS PRECEE;3.30DING *****
73 mov cl,byte ptr bin_date_time+2 ;mjb002 get month
74 xor ch,ch ;mjb002
75 dec cx ;mjb002 january starts at offset 0
76 shl cx,1 ;mjb002 word offset
77 mov si,offset month_table ;mjb002 beginning of month_table
78 add si,cx ;mjb002 point into month table
79 mov ax,word ptr [si];mjb002 get # days in previous months
80 ADD CS:DAYCNT2,AX ;MJB002 ... ;3.30
81r_d_ret: ;mjb002
82 MOV SI,CS:DAYCNT2 ;MJB002 RESULT IN SI ;3.30
83 POP DX
84 POP CX
85 POP BX
86 POP AX
87 ret ;mjb002
88
89r_t_retj:
90 xor cx,cx
91 xor dx,dx
92 jmp r_t_ret
93;
94; Read_Real_Time reads the time from the RTC. on exit, it has the number of
95; ticks (at 18.2 ticks per sec.) in CX:DX.
96;
97Read_Real_Time:
98 mov ah,2 ;3.30*
99 int 1AH ;3.30*
100 jc r_t_retj
101oktime:
102 mov byte ptr bin_date_time,ch ; hours
103 mov byte ptr bin_date_time+1,cl ; minutes
104 mov byte ptr bin_date_time+2,dh ; seconds
105 mov byte ptr bin_date_time+3,0 ; unused for time
106 call bcd_verify
107 jc r_t_retj
108 call time_verify
109 jc r_t_retj
110 call in_bin
111 MOV ch,byte ptr bin_date_time
112 MOV cl,byte ptr bin_date_time+1
113 MOV dh,byte PTR bin_date_time+2
114 MOV dl,byte PTR bin_date_time+3
115 message ftestinit,<"Read Time ">
116 mnum ftestinit,cx
117 message ftestinit,<" ">
118 mnum ftestinit,dx
119 message ftestinit,<cr,lf>
120; get time in ticks in CX:DX
121 CALL word ptr cs:TimeToTicks ;3.30
122 message ftestinit,<"Conv Time ">
123 mnum ftestinit,cx
124 message ftestinit,<" ">
125 mnum ftestinit,dx
126 message ftestinit,<cr,lf>
127r_t_ret:
128 ret
129
130;
131; in_bin converts bin_date_time values from bcd to bin
132;
133in_bin: ;mjb002
134 assume ds:code,es:nothing
135 mov al,byte ptr bin_date_time+0 ; century or hours
136 call bcd_to_bin ; ...
137 mov byte ptr bin_date_time+0,al ;
138 mov al,byte ptr bin_date_time+1 ; years or minutes
139 call bcd_to_bin ; ...
140 mov byte ptr bin_date_time+1,al ;
141 mov al,byte ptr bin_date_time+2 ; months or seconds
142 call bcd_to_bin ; ...
143 mov byte ptr bin_date_time+2,al ;
144 mov al,byte ptr bin_date_time+3 ; days (not used for time)
145 call bcd_to_bin ; ...
146 mov byte ptr bin_date_time+3,al ;
147 ret ;
148;
149; bcd_to_bin converts two bcd nibbles in al (value <= 99.) to
150; a binary representation in al
151; ah is destroyed
152;
153bcd_to_bin: ;mjb002
154 assume ds:nothing,es:nothing
155 mov ah,al ;mjb002 copy bcd number to ah
156 and ax,0f00fh ;mjb002 clear unwanted nibbles
157 mov bl,al ;mjb002 save units place
158 xchg ah,al ;mjb002 10's place to al
159 xor ah,ah ;mjb002 ah not wanted
160 mov cl,4 ;mjb002 shift count
161 shr ax,cl ;mjb004 swap nibbles
162 mov cl,10 ;mjb002 convert al to ...
163 mul cl ;mjb002 ... its binary value
164 add al,bl ;mjb002 add in units
165 ret ;mjb002
diff --git a/v4.0/src/BIOS/STKINIT.INC b/v4.0/src/BIOS/STKINIT.INC
new file mode 100644
index 0000000..8298fb8
--- /dev/null
+++ b/v4.0/src/BIOS/STKINIT.INC
@@ -0,0 +1,271 @@
1;
2; To follow the standard interrupt sharing scheme, MSSTACK.ASM ;3.30
3; has been modified. This initialization routine also has to ;3.30
4; be modified because for the interrupt level 7 and 15, FirstFlag ;3.30
5; should be set to signal that this interrupt handler is the ;3.30
6; first handler hooked to this interrupt vector. ;3.30
7; We determine this by looking at the instruction pointed by ;3.30
8; this vector. If it is IRET, then this handler should be the ;3.30
9; first one. In our case, only the interrupt vector 77h is the ;3.30
10; interrupt level 15. (We don't hook interrupt level 7.) ;3.30
11; 9/10/1986 ;3.30
12; The followings are mainly due to M.R.T; PTM fix of P886 12/3/86;3.30
13; Some design changes are needed to the above interrupt sharing ;3.30
14; method. The above sharing scheme assumes that 1). Interrupt ;3.30
15; sharing is NEVER done on levels that have BIOS support. 2). "Phantom" ;3.30
16; interrupts would only be generated on levels 7 and 15. ;3.30
17; These assumptions are not true any more. We have to use the FirstFlag ;3.30
18; for EVERY level of interrupt. We will set the firstFlag on the following;3.30
19; conditions: ;3.30
20; a. if the CS portion of the vector is 0000, then "first" ;3.30
21; b. else if CS:IP points to valid shared header, then NOT "first" ;3.30
22; c. else if CS:IP points to an IRET, then "first" ;3.30
23; d. else if CS:IP points to DUMMY, then "first" ;3.30
24; where DUMMY is - the CS portion must be F000, and the IP portion must ;3.30
25; be equal to the value at F000:FF01. This location is the initial value ;3.30
26; from VECTOR_TABLE for interrupt 7, one of the preserved addresses in all;3.30
27; the BIOSes for all of the machines. ;3.30
28; ;3.30
29; System design group requests BIOS to handle the phantom interrupts. ;3.30
30; ;3.30
31; The "Phantom" interrupt is an illegal interrupt such as an interrupt ;3.30
32; produced by the bogus adapter card even without interrupt request is ;3.30
33; set. More specifically, 1). The 8259 has a feature when running in ;3.30
34; edge triggered mode to latch a pulse and present the interrupt when ;3.30
35; the processor indicates interrupt acknowledge (INTA). The interrupt ;3.30
36; pulse was exist at the time of INTA to get a "phantom" interrupt. ;3.30
37; 2). or, this is caused by adapter cards placing a glitch on the ;3.30
38; interrupt line. ;3.30
39; ;3.30
40; To handle those "phantom" interrupts, the main stack code will check ;3.30
41; the own FirstFlag, and if it is not "first" (which means the forward ;3.30
42; pointer points to the legal shared interrupt handler), then pass the ;3.30
43; control. If it is the first, then the following action should be ;3.30
44; taken. We don't have to implement skack logic in this case. ;3.30
45; ;3.30
46; To implement this logic, we rather choose a simple method. ;3.30
47; If ont of the above "FirstFlag" conditions is met, we are not ;3.30
48; going to hook this interrupt vector. The reason is if the original ;3.30
49; vector points to "IRET" and do nothing, we don't need ;3.30
50; to implement the stack logic for it. This will simplify implementation;3.30
51; while maintaining compatibility with the old version of DOS. ;3.30
52; This implies that in the main stack code, there might be a stack code ;3.30
53; that will never be used, a dead code. ;3.30
54; ;3.30
55; 12/3/86 ;3.30
56 ;3.30
57;In - CS, DS -> sysinitseg, ES -> relocated stack code & data. ;3.30
58 ;3.30
59 PAGE ;3.30
60 assume ds:sysinitseg ; sunilp SB340
61StackInit proc near ;3.30
62 ;3.30
63 PUSH AX ;SAVE ALL ;3.30
64 PUSH DS ;3.30
65 PUSH ES ;3.30
66 PUSH BX ;3.30
67 PUSH CX ;3.30
68 PUSH DX ;3.30
69 PUSH DI ;3.30
70 PUSH SI ;3.30
71 PUSH BP ;3.30
72 ;3.30
73;Currently ES -> stack code area ;3.30
74 MOV AX, cs:[STACK_COUNT] ;defined in CS ;3.30
75 MOV es:[STACKCOUNT], AX ;defined in STACK CODE AREA ;3.30
76 MOV AX, [STACK_SIZE] ;in CS ;3.30
77 MOV es:[STACKSIZE], AX ; ;3.30
78 MOV AX, WORD PTR cs:[STACK_ADDR] ; OFFSET ;3.30
79 MOV WORD PTR es:[STACKS], AX ;3.30
80 MOV AX, WORD PTR cs:[STACK_ADDR+WORD] ; SEGMENT ;3.30
81 MOV WORD PTR es:[STACKS+WORD], AX ;3.30
82 ;3.30
83; INITIALIZE THE DATA FIELDS WITH THE PARAMETERS ;3.30
84 ;3.30
85; "FIRSTENTRY" WILL ALWAYS BE AT STACKS ;3.30
86 ;3.30
87 MOV BP, word ptr es:STACKS ; GET OFFSET OF STACK ;3.30
88 MOV es:FIRSTENTRY,BP ;3.30
89 ;3.30
90; THE STACKS WILL ALWAYS IMMEDIATELY FOLLOW THE TABLE ENTRIES ;3.30
91 ;3.30
92 MOV AX,ENTRYSIZE ;3.30
93 MOV CX,es:STACKCOUNT ;3.30
94 MUL CX ;3.30
95 ADD AX,BP ;3.30
96 MOV es:STACKAT,AX ;3.30
97 MOV BX,AX ;3.30
98 SUB BX,2 ;3.30
99 ;3.30
100; ZERO THE ENTIRE STACK AREA TO START WITH ;3.30
101 ;3.30
102 MOV DI,es:STACKAT ;3.30
103 MOV AX,es:STACKSIZE ;3.30
104 MUL CX ;3.30
105 MOV CX,AX ;3.30
106 xor ax,ax ;3.30
107 push es ;3.30
108 pop ds ;ds = Relocated stack code seg.;3.30
109 assume ds:nothing ;3.30
110;Now, DS -> stack code area ;3.30
111 MOV ES, word ptr ds:[STACKS+2] ; GET SEGMENT OF STACK AREA.;3.30
112 CLD ;3.30
113 REP STOSB ;3.30
114 ;3.30
115 MOV CX, ds:STACKCOUNT ;3.30
116 ;3.30
117; LOOP FOR "COUNT" TIMES, BUILDING A TABLE ENTRY ;3.30
118; cs = sysinitseg, ds = Relocated stack code seg , es = segment of stack space;3.30
119; CX = NUMBER OF ENTRIES ;3.30
120; ES:BP => BASE OF STACKS - 2 ;3.30
121; ES:BX => FIRST TABLE ENTRY ;3.30
122 ;3.30
123BUILDLOOP: ;3.30
124 MOV ALLOCBYTE,FREE ;3.30
125 MOV INTLEVEL,AL ;AX = 0 ;3.30
126 MOV SAVEDSP,AX ;3.30
127 MOV SAVEDSS,AX ;3.30
128 ADD BX,ds:STACKSIZE ;3.30
129 MOV NEWSP,BX ;3.30
130 MOV ES:[BX],BP ;3.30
131 ADD BP,ENTRYSIZE ;3.30
132 ;3.30
133 LOOP BUILDLOOP ;3.30
134 ;3.30
135 SUB BP,ENTRYSIZE ;3.30
136 MOV ds:LASTENTRY,BP ;3.30
137 MOV ds:NEXTENTRY,BP ;3.30
138 ;3.30
139 push ds ;3.30
140 mov ax, 0f000h ;loook at the model byte ;3.30
141 mov ds, ax ;3.30
142 cmp ds:byte ptr [0fffeh], mdl_convert ;convertible? ;3.30
143 pop ds ;3.30
144 jne Skip_disableNMIS ;3.30
145 ;3.30
146 MOV AL,07H ; DISABLE Convertible NMIS ;3.30
147 OUT 72H,AL ;3.30
148 ;3.30
149Skip_disableNMIS: ;3.30
150 XOR AX,AX ;3.30
151 MOV es,AX ;es - SEGID OF VECTOR TABLE AT 0;3.30
152 ASSUME es:NOTHING ;ds - Relocated Stack code segment;3.30
153 ;3.30
154 CLI ;3.30
155 ;3.30
156 IRP AA,<02,08,09,70> ;3.30
157 ;3.30
158 MOV SI,AA&H*4 ;PASS WHERE VECTOR IS TO BE ADJUSTED ;3.30
159 mov di, offset Int19OLD&AA ;we have to set OLD&AA for Int19 handler too.;3.30
160 MOV BX,OFFSET OLD&AA ;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30
161 MOV DX,OFFSET INT&AA ;PASS WHERE NEW HANDLER IS ;3.30
162 CALL NEW_INIT_LOOP ;ADJUST THE VECTOR TO NEW HANDLER, ;3.30
163 ; SAVING POINTER TO ORIGINAL OWNER ;3.30
164 ENDM ;3.30
165 ;3.30
166 IRP AA,<0A,0B,0C,0D,0E,72,73,74,76,77> ;shared interrupts ;3.30
167 ;3.30
168 MOV SI,AA&H*4 ;PASS WHERE VECTOR IS TO BE ADJUSTED ;3.30
169 push ds ;save relocated stack code segment ;3.30
170 lds bx, es:[si] ;ds:bx -> original interrupt handler ;3.30
171 push ds ;3.30
172 pop dx ;dx = segment value ;3.30
173
174 cmp dx,0
175 jz int&AA&_first
176
177 cmp byte ptr ds:[bx],0cfh ;Does vector point to an IRET?
178 jz int&AA&_first
179
180 cmp word ptr ds:[bx.6],424Bh ;Magic offset (see INT&AA, msstack.inc)
181 jz int&AA&_Not_first
182
183 cmp dx,0f000h ;ROM BIOS segment
184 jnz int&AA&_Not_first
185
186 push es
187 push dx
188 mov dx,0f000h
189 mov es,dx
190 cmp bx,word ptr es:0ff01h
191 pop dx
192 pop es
193 jz int&AA&_first
194
195int&AA&_Not_first: ;Not the first. We are going to hook vector.;3.30
196 pop ds ;3.30
197 mov di, offset Int19OLD&AA ;we have to set OLD&AA for Int19 handler too.;3.30
198 mov BX, OFFSET OLD&AA ;PASS WHERE TO SAVE ORIGINAL OWNER POINTER;3.30
199 MOV DX, OFFSET INT&AA ;PASS WHERE NEW HANDLER IS ;3.30
200 CALL NEW_INIT_LOOP ;ADJUST THE VECTOR TO NEW HANDLER, SAVING;3.30
201 ;POINTER TO ORIGINAL OWNER. ;3.30
202 jmp short int&AA&_end ;3.30
203int&AA&_first: ;the first. Don't have to hook stack code.;3.30
204 pop ds ;3.30
205int&AA&_end: ;3.30
206 ;3.30
207 ENDM ;3.30
208 ;3.30
209 push ds ;3.30
210 mov ax, 0f000h ;loook at the model byte ;3.30
211 mov ds, ax ;3.30
212 cmp ds:byte ptr [0fffeh], mdl_convert ;PC convertible? ;3.30
213 pop ds ;3.30
214 jne Skip_EnableNMIS ;3.30
215 ;3.30
216 MOV AL,27H ; ENABLE Convertible NMIS ;3.30
217 OUT 72H,AL ;3.30
218 ;3.30
219Skip_EnableNMIS: ;3.30
220 STI ;3.30
221 MOV AX,code ;3.30
222 MOV DS,AX ;3.30
223 ASSUME DS:CODE ;3.30
224 ;3.30
225; MOV SI,OFFSET STKMSG1 ;3.30
226; CALL WRMSG ;3.30
227 ;3.30
228 mov [INT19SEM],1 ; INDICATE THAT INT 19 ;3.30
229 ; INITIALIZATION IS COMPLETE ;3.30
230 ;3.30
231 POP BP ; RESTORE ALL ;3.30
232 POP SI ;3.30
233 POP DI ;3.30
234 POP DX ;3.30
235 POP CX ;3.30
236 POP BX ;3.30
237 ;3.30
238 POP ES ;3.30
239 POP DS ;3.30
240 assume ds:sysinitseg ;3.30
241 POP AX ;3.30
242 RET ;3.30
243STACKINIT ENDP ;3.30
244; ;3.30
245 ;3.30
246NEW_INIT_LOOP PROC NEAR ;3.30
247;INPUT: SI=OFSET INTO VECTOR TABLE OF THE PARTICULAR INT VECTOR BEING ADJUSTED ;3.30
248; BX=ds:OFFSET OF OLDxx, WHERE WILL BE SAVED THE POINTER TO ORIGINAL OWNER;3.30
249; DX=ds:OFFSET OF INTxx, THE NEW INTERRUPT HANDLER ;3.30
250; di=offset value of Int19OLD&AA variable in BIOS. ;3.30
251; es=ZERO, SEGID OF VECTOR TABLE ;3.30
252; ds=Relocated Stack code segment ;3.30
253 ;3.30
254 MOV AX,es:[SI+0] ;REMEMBER OFFSET IN VECTOR ;3.30
255 MOV WORD PTR ds:[BX],AX ; TO ORIGINAL OWNER in DS ;3.30
256 MOV AX,es:[SI+2] ;REMEMBER SEGID IN VECTOR ;3.30
257 MOV WORD PTR ds:[BX]+2,AX ; TO ORIGINAL OWNER in DS ;3.30
258 push ds ;3.30
259 mov ax, code ;3.30
260 mov ds, ax ;Set Int19OLDxx value in BIOS for ;3.30
261 mov ax,es:[si+0] ;Int 19 handler ;3.30
262 mov word ptr ds:[di],ax ;3.30
263 mov ax,es:[si+2] ;3.30
264 mov word ptr ds:[di]+2,ax ;3.30
265 pop ds ;3.30
266 ;3.30
267 MOV WORD PTR es:[SI+0],DX ;SET VECTOR TO POINT TO NEW INT HANDLER ;3.30
268 MOV es:[SI+2],ds ;3.30
269 RET ;3.30
270NEW_INIT_LOOP ENDP ;3.30
271 ;3.30
diff --git a/v4.0/src/BIOS/SYSCONF.ASM b/v4.0/src/BIOS/SYSCONF.ASM
new file mode 100644
index 0000000..7de3d30
--- /dev/null
+++ b/v4.0/src/BIOS/SYSCONF.ASM
@@ -0,0 +1,3392 @@
1 PAGE ,132 ;
2; SCCSID = @(#)sysconf.asm 0.0 86/10/20
3TITLE BIOS SYSTEM INITIALIZATION
4%OUT ...SYSCONF
5
6;==============================================================================
7;REVISION HISTORY:
8;AN000 - New for DOS Version 4.00 - J.K.
9;AC000 - Changed for DOS Version 4.00 - J.K.
10;AN00x - PTM number for DOS Version 4.00 - J.K.
11;==============================================================================
12;AN001; P132 Multiple character device installation problem. 06/27/87 J.K.
13;AN002; D24 MultiTrack= command added. 06/29/87 J.K.
14;AN003; D41 REM command in CONFIG.SYS. 07/6/87 J.K.
15;AN004; D184 Set DEVMARK for MEM command 08/25/87 J.K.
16;AN005; P568 CONFIG.SYS parsing error with FCBS=10,15 08/31/87 J.K.
17;AN006; P887 STACKS=0 does not show "ERROR in CONFIG.SYS..." 09/09/87 J.K.
18;AN007; D246, P976 Show "Bad command or parameters - ..." msg 09/22/87 J.K.
19;AN008; P1299 Set the second entry of DEVMARK for MEM command 09/25/87 J.K.
20;AN009; P1326 New Extended attribute 09/28/87 J.K.
21;AN010; P1820 New message SKL file 10/20/87 J.K.
22;AN011; P1970 AUTOTEST FCBS= command error msg inconsistent 10/23/87 J.K.
23;AN012; P2211 Setting the EA=7 for ANSI.SYS hangs the system 11/02/87 J.K.
24;AN013; P2342 REM not allowed after INSTALL command 11/09/87 J.K.
25;AN014; P2546 DEVICE= command still allowed after IFS= 11/17/87 J.K.
26;AN015; D358 New device driver INIT function package 12/03/87 J.K.
27;AN016; D285 Undo the extended error handling 12/17/87 J.K.
28;AN017; P3170 Do not call block device driver when drive # > 26 01/20/88 J.K.
29;AN018; P3111 Take out the order dependency of the INSTALL= 01/25/88 J.K.
30;AN019; D479 New option to disable extended INT 16h function call 02/12/88 J.K.
31;AN020; P3607 MEM does not give correct filename 02/24/88 J.K.
32;AN021; D493 Undo D358 & do not show error message for device driv 02/24/88 J.K.
33;AN022; P3807 Single buffer unprotected - System hangs 03/10/88 J.K.
34;AN023; P3797 An INSTALL cmd right after Bad cmd is not executed 03/10/88 J.K.
35;AN024; D503 Version change to 4.0 - IBMCACHE.SYS is an exception 03/15/88 J.K.
36;AN025; D474 Change BUFFERS= /E option to /X for expanded memory 03/16/88 J.K.
37;AN026; D506 Take out the order dependency of the IFS= 03/28/88 J.K.
38;AN027; P3957 Undo D503 - IBMCACHE.SYS version check problem 03/30/88 J.K.
39;AN028; P4086 Memory allocation error when loading share.exe 03/31/88 J.K.
40;AN029; D528 Install XMAEM.SYS first before everything else 04/29/88 J.K.
41;AN030; P4759 INT2f, INT 67h handlers for XMA 05/11/88 J.K.
42;AN031; P4889 Should check the validity of INT 67h call 05/17/88 G.A.
43;AN032; P4934 P4759 INT 2fh number should be changed to 1Bh 05/20/88 J.K.
44;AN033; P5002 EMS w/single page allocated now works 05/20/88 G.A.
45;AN034; P5128 EMS INT 2FH HANDLER BUG 06/24/88
46;==============================================================================
47
48TRUE EQU 0FFFFh
49FALSE EQU 0
50LF equ 10
51CR equ 13
52TAB equ 9
53SEMICOLON equ ';'
54
55IBMVER EQU TRUE
56IBM EQU IBMVER
57STACKSW EQU TRUE ;Include Switchable Hardware Stacks
58IBMJAPVER EQU FALSE ;If TRUE set KANJI true also
59MSVER EQU FALSE
60ALTVECT EQU FALSE ;Switch to build ALTVECT version
61KANJI EQU FALSE
62
63HAVE_INSTALL_CMD equ 00000001b ;AN018; CONFIG.SYS has INSTALL= commands
64HAS_INSTALLED equ 00000010b ;AN018; SYSINIT_BASE installed.
65
66IS_IFS equ 00000001b ;IFS command?
67NOT_IFS equ 11111110b
68;
69;AN016; Undo the extended attribute handling
70;;Extended attribute value
71;EA_UNSPECIFIED equ 0 ;AN009;
72;EA_DEVICE_DRIVER equ 6 ;AN009;
73;EA_IFS_DRIVER equ 7 ;AN009;
74
75DEFAULT_FILENUM = 8
76;
77 IF IBMJAPVER
78NOEXEC EQU TRUE
79 ELSE
80NOEXEC EQU FALSE
81 ENDIF
82
83DOSSIZE EQU 0A000H
84;dossize equ 0C000H ;J.K. for the debugging version of IBMDOS.
85
86.xlist
87; INCLUDE dossym.INC
88 include smdossym.inc ;J.K. Reduced version of DOSSYM.INC
89 INCLUDE devsym.INC
90 include ioctl.INC
91 include BIOSTRUC.INC
92 include smifssym.inc ;AN000; Reduced version of IFSSYM.INC.
93 include DEVMARK.inc ;AN004;
94 include version.inc
95.list
96
97 IF NOT IBMJAPVER
98 EXTRN RE_INIT:FAR
99 ENDIF
100
101;
102
103;J.K. 6/29/87 External variable defined in IBMBIO module for Multi-track
104MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns
105 ; it on after handling CONFIG.SYS file as a
106 ; default value, if MulTrk_flag = MULTRK_OFF1.
107MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered.
108MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off.
109
110CODE segment public 'code'
111 EXTRN MulTrk_flag:word ;AN002;
112 extrn KEYRD_Func:byte ;AN019;
113 extrn KEYSTS_Func:byte ;AN019;
114CODE ends
115;J.K. 6/29/87 End of Multi-track definition.
116
117SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
118
119ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
120
121 EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE,BADMEM:BYTE,BADBLOCK:BYTE
122 EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE
123; EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE
124 EXTRN BADSTACK:BYTE,BADCOUNTRYCOM:BYTE
125 EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE,INSUFMEMORY:BYTE
126 EXTRN CONDEV:BYTE,AUXDEV:BYTE,PRNDEV:BYTE,COMMND:BYTE,CONFIG:BYTE
127 EXTRN Cntry_Drv:BYTE,Cntry_Root:BYTE,Cntry_Path:BYTE
128 EXTRN DeviceParameters:byte
129 EXTRN MEMORY_SIZE:word
130 EXTRN BUFFERS:word
131 EXTRN FILES:byte,NUM_CDS:byte
132 EXTRN DOSINFO:dword,ENTRY_POINT:dword
133 EXTRN FCBS:byte,KEEP:byte
134 EXTRN CONFBOT:word,ALLOCLIM:word,COMMAND_LINE:byte
135 EXTRN ZERO:byte,SEPCHR:byte
136 EXTRN COUNT:word,CHRPTR:word,CNTRYFILEHANDLE:word
137 EXTRN MEMLO:word,MEMHI:word,PRMBLK:word,LDOFF:word
138 EXTRN PACKET:byte,UNITCOUNT:byte,BREAK_ADDR:dword
139 EXTRN BPB_ADDR:dword,DRIVENUMBER:byte,SYSI_COUNTRY:dword
140 extrn Config_Size:word ;AN000;
141 extrn Install_Flag:word ;AN000;
142 extrn BadOrder:byte ;AN000;
143 extrn Errorcmd:byte ;AN000;
144 extrn LineCount:word ;AN000;
145 extrn ShowCount:byte ;AN000;
146 extrn Buffer_LineNum:word ;AN000;
147 extrn IFS_Flag:word ;AN000;
148 extrn IFS_RH:byte ;AN000;
149 extrn H_Buffers:word ;AN000;
150 extrn Buffer_Slash_X:byte ;AN000;AN025;
151 extrn Badparm:byte ;AN007;
152 extrn ConfigMsgFlag:Word ;AN015;
153 extrn Org_Count:Word ;AN018;
154 extrn Multi_Pass_Id:byte ;AN026;
155
156 EXTRN MEM_ERR:NEAR,SetDOSCountryInfo:NEAR
157 EXTRN PARAROUND:NEAR,TEMPCDS:NEAR
158 EXTRN Set_Country_Path:NEAR,Move_ASCIIZ:NEAR,DELIM:NEAR
159 EXTRN BADFIL:NEAR,ROUND:NEAR
160 extrn Do_Install_Exec:NEAR ;AN018;
161 extrn SetDevMark:NEAR ;AN030;
162
163;AN016; Undo the extended attribute handling
164; extrn Get_Ext_Attribute:near ;AN009;
165
166 IF STACKSW
167
168; Internal Stack Parameters
169 EntrySize equ 8
170
171 MinCount equ 8
172 DefaultCount equ 9
173 MaxCount equ 64
174
175 MinSize equ 32
176 DefaultSize equ 128
177 MaxSize equ 512
178
179 extrn stack_count:word
180 extrn stack_size:word
181 extrn stack_addr:dword
182
183 ENDIF
184
185 PUBLIC DOCONF
186 PUBLIC GETCHR
187 public Multi_Pass ;AN018;AN026;
188
189 public MultDeviceFlag
190MultDeviceFlag db 0 ;AN001;
191 public DevMark_Addr
192DevMark_Addr dw ? ;AN004;Segment address for DEVMARK.
193 public SetDevMarkFlag
194SetDevMarkFlag db 0 ;AN004;Flag used for DEVMARK
195
196EMS_Stub_Installed db 0 ;AN030;
197
198Badparm_Ptr label dword
199Badparm_Off dw 0 ;AN007;
200Badparm_Seg dw 0 ;AN007;
201
202XMAEM_file db 'XMAEM.SYS',0 ;AN029;
203
204;IBMCACHE_file db 'IBMCACHE.SYS',0;AN024;AN026;To cope with the IBMCACHE.SYS
205 ; problem of DOS version checking.
206
207;******************************************************************************
208;Take care of Config.sys file.
209;SYSTEM parser data and code.
210;******************************************************************************
211.xlist
212 include PSOPTION.INC ;Parsing options for SYSCONF.
213 include PARSE.ASM ;together with PSDATA.INC
214.list
215;Control block definitions for PARSER.
216;---------------------------------------------------
217; BUFFER = [n | n,m] {/E}
218
219Buf_Parms label byte ;AN000;
220 dw Buf_Parmsx ;AN000;
221 db 1 ;AN000; An extra delimeter list
222 db 1 ;AN000; length is 1
223 db SEMICOLON ;AN000;
224
225Buf_Parmsx label byte ;AN000;
226 db 1,2 ;AN000; Min 1, Max 2 positional
227 dw Buf_Pos1 ;AN000;
228 dw Buf_Pos2 ;AN000;
229 db 1 ;AN000; 1 switch
230 dw SW_X_Ctrl ;AN000;AN025; /X control
231 db 0 ;AN000; no keywords
232
233Buf_Pos1 label word ;AN000;
234 dw 8000h ;AN000; Numeric value
235 dw 0 ;AN000; no function
236 dw Result_Val ;AN000; Result value buffer
237 dw Buf_Range_1 ;AN000; value list
238 db 0 ;AN000; no switches/keywords
239
240Buf_Range_1 label byte ;AN000; value definition
241 db 1 ;AN000; range definition
242 db 1 ;AN000; 1 definition of range
243 db 1 ;AN000; item tag for this range
244 dd 1,10000 ;AN000; from 1 to 10000
245
246Buf_Pos2 label word ;AN000;
247 dw 8001h ;AN000; Numeric value, Optional
248 dw 0 ;AN000; no function
249 dw Result_Val ;AN000; Result value buffer
250 dw Buf_Range_2 ;AN000; value list
251 db 0 ;AN000; no switches/keywords
252
253Buf_Range_2 label byte ;AN000; value definition
254 db 1 ;AN000; range definition
255 db 1 ;AN000; 1 definition of range
256 db 1 ;AN000; item tag for this range
257 dd 0,8 ;AN000; from 0 to 8.
258
259SW_X_Ctrl label word ;AN000;AN025;
260 dw 0 ;AN000; no matching flag
261 dw 0 ;AN000; no function
262 dw Result_Val ;AN000; return value
263 dw NoVal ;AN000; no value definition
264 db 1 ;AN000; # of switches
265Switch_X label byte ;AN000;AN025;
266 db '/X',0 ;AN000;AN025;
267;local variables
268P_Buffers dw 0 ;AN000;
269P_H_Buffers dw 0 ;AN000;
270P_Buffer_Slash_X db 0 ;AN000;AN025;
271Buffer_Pre_Scan db 0 ;AN030;
272
273;Common definitions -------------
274NoVal db 0 ;AN000;
275
276Result_Val label byte ;AN000;
277 db ? ;AN000; type returned
278 db ? ;AN000; item tag returned
279 dw ? ;AN000; ES:offset of the switch defined
280RV_Byte label byte ;AN000;
281RV_Dword label dword ;AN000;
282 dd ? ;AN000; value if number, or seg:offset to string.
283;--------------------------------
284
285; BREAK = [ ON | OFF ]
286
287Brk_Parms label byte ;AN000;
288 dw Brk_Parmsx ;AN000;
289 db 1 ;AN000; An extra delimeter list
290 db 1 ;AN000; length is 1
291 db SEMICOLON ;AN000;
292
293Brk_Parmsx label byte ;AN000;
294 db 1,1 ;AN000; Min 1, Max 1 positional
295 dw Brk_Pos ;AN000;
296 db 0 ;AN000; no switches
297 db 0 ;AN000; no keywords
298
299Brk_Pos label word ;AN000;
300 dw 2000h ;AN000; Simple string
301 dw 0 ;AN000; No functions
302 dw Result_Val ;AN000;
303 dw On_Off_String ;AN000; ON,OFF string descriptions
304 db 0 ;AN000; no keyword/switch synonyms
305
306On_Off_String label byte ;AN000;
307 db 3 ;AN000; signals that there is a string choice
308 db 0 ;AN000; no range definition
309 db 0 ;AN000; no numeric values choice
310 db 2 ;AN000; 2 strings for choice
311 db 1 ;AN000; the 1st string tag
312 dw On_String ;AN000;
313 db 2 ;AN000; the 2nd string tag
314 dw Off_String ;AN000;
315
316On_String db "ON",0 ;AN000;
317Off_String db "OFF",0 ;AN000;
318;local variable
319P_Ctrl_Break db 0 ;AN000; local variable
320
321;--------------------------------
322
323; COUNTRY = n {m {path}}
324; or
325; COUNTRY = n,,path
326
327Cntry_Parms label byte ;AN000;
328 dw Cntry_Parmsx ;AN000;
329 db 1 ;AN000; An extra delimeter list
330 db 1 ;AN000; length is 1
331 db SEMICOLON ;AN000;
332
333Cntry_Parmsx label byte ;AN000;
334 db 1,3 ;AN000; Min 1, Max 3 positional
335 dw Cntry_Pos1 ;AN000;
336 dw Cntry_Pos2 ;AN000;
337 dw Cntry_Pos3 ;AN000;
338 db 0 ;AN000; no switches
339 db 0 ;AN000; no keywords
340
341Cntry_Pos1 label word ;AN000; control definition for positional 1
342 dw 8000h ;AN000; Numeric value
343 dw 0 ;AN000; no functions
344 dw Result_Val ;AN000;
345 dw Cntry_Codepage_Range ;AN000; country id code range description
346 db 0 ;AN000; no switch/keyword synonyms
347
348Cntry_Codepage_Range label byte ;AN000;
349 db 1 ;AN000; # of value definitions
350 db 1 ;AN000; # of ranges
351 db 1 ;AN000; Tag for this range
352 dd 1,999 ;AN000;
353
354Cntry_Pos2 label word ;AN000; control definition for positional 2
355 dw 8001h ;AN000; Numeric value, optional
356 dw 0 ;AN000; no functions
357 dw Result_Val ;AN000;
358 dw Cntry_Codepage_Range ;AN000; code page range descriptions.
359 db 0 ;AN000; no switch/keyword synonyms
360
361Cntry_Pos3 label word ;AN000; control definition for positional 3
362 dw 0201h ;AN000; File spec, optional
363 dw 0 ;AN000; No functions. Don't need to CAP.
364 dw Result_Val ;AN000;
365 dw NoVal ;AN000; no value list
366 db 0 ;AN000; no switch/keyword synonyms
367
368;Local variables
369P_Cntry_Code dw 0 ;AN000;
370P_Code_Page dw 0 ;AN000;
371
372;--------------------------------
373
374; FILES = n
375
376Files_Parms label byte ;AN000;
377 dw Files_Parmsx ;AN000;
378 db 1 ;AN000; An extra delimeter list
379 db 1 ;AN000; length is 1
380 db SEMICOLON ;AN000;
381
382Files_Parmsx label byte ;AN000;
383 db 1,1 ;AN000; Min 1, Max 1 positional
384 dw Files_Pos ;AN000;
385 db 0 ;AN000; no switches
386 db 0 ;AN000; no keywords
387
388Files_Pos label byte ;AN000;
389 dw 8000h ;AN000; Numeric value
390 dw 0 ;AN000; no functions
391 dw Result_Val ;AN000;
392 dw Files_Range ;AN000; Files range description
393 db 0 ;AN000; no switch/keyword synonyms
394
395Files_Range label byte ;AN000;
396 db 1 ;AN000; # of value definitions
397 db 1 ;AN000; # of ranges
398 db 1 ;AN000; Tag for this range
399 dd 8,255 ;AN000;
400;local variable
401P_Files db 0 ;AN000;
402
403;--------------------------------
404
405; FCBS = n,m
406
407FCBS_Parms label byte ;AN000;
408 dw FCBS_Parmsx ;AN000;
409 db 1 ;AN000; An extra delimeter list
410 db 1 ;AN000; length is 1
411 db SEMICOLON ;AN000;
412
413FCBS_Parmsx label byte ;AN000;
414 db 2,2 ;AN000; Min 2, Max 2 positional
415 dw FCBS_Pos_1 ;AN000;
416 dw FCBS_Pos_2 ;AN000;
417 db 0 ;AN000; no switches
418 db 0 ;AN000; no keywords
419
420FCBS_Pos_1 label byte ;AN000;
421 dw 8000h ;AN000; Numeric value
422 dw 0 ;AN000; no functions
423 dw Result_Val ;AN000;
424 dw FCBS_Range ;AN000; FCBS range descriptions
425 db 0 ;AN000; no switch/keyword synonyms
426
427FCBS_Range label byte ;AN000;
428 db 1 ;AN000; # of value definitions
429 db 1 ;AN000; # of ranges
430 db 1 ;AN000; Tag for this range
431 dd 1,255 ;AN000;
432
433FCBS_Pos_2 label byte ;AN000;
434 dw 8000h ;AN000; Numeric value
435 dw 0 ;AN000; no functions
436 dw Result_Val ;AN000;
437 dw FCBS_Keep_Range ;AN000; FCBS KEEP range descriptions
438 db 0 ;AN000; no switch/keyword synonyms
439
440FCBS_Keep_Range label byte ;AN000;
441 db 1 ;AN000; # of value definitions
442 db 1 ;AN000; # of ranges
443 db 1 ;AN000; Tag for this range
444 dd 0,255 ;AN000;
445
446;local variable
447P_Fcbs db 0 ;AN000;
448P_Keep db 0 ;AN000;
449;--------------------------------
450
451; LASTDRIVE = x
452
453LDRV_Parms label byte ;AN000;
454 dw LDRV_Parmsx ;AN000;
455 db 1 ;AN000; An extra delimeter list
456 db 1 ;AN000; length is 1
457 db SEMICOLON ;AN000;
458
459LDRV_Parmsx label byte ;AN000;
460 db 1,1 ;AN000; Min 1, Max 1 positional
461 dw LDRV_Pos ;AN000;
462 db 0 ;AN000; no switches
463 db 0 ;AN000; no keywords
464
465LDRV_Pos label byte ;AN000;
466 dw 0110h ;AN000; Drive only, Ignore colon.
467 dw 0010h ;AN000; Remove colon at end
468 dw Result_Val ;AN000;
469 dw NoVal ;AN000; No value list
470 db 0 ;AN000; no switch/keyword synonyms
471
472;local variable
473P_Ldrv db 0 ;AN000;
474;--------------------------------
475
476; STACKS = n,m
477
478STKS_Parms label byte ;AN000;
479 dw STKS_Parmsx ;AN000;
480 db 1 ;AN000; An extra delimeter list
481 db 1 ;AN000; length is 1
482 db SEMICOLON ;AN000;
483
484STKS_Parmsx label byte ;AN000;
485 db 2,2 ;AN000; Min 2, Max 2 positional
486 dw STKS_Pos_1 ;AN000;
487 dw STKS_Pos_2 ;AN000;
488 db 0 ;AN000; no switches
489 db 0 ;AN000; no keywords
490
491STKS_Pos_1 label byte ;AN000;
492 dw 8000h ;AN000; Numeric value
493 dw 0 ;AN000; no functions
494 dw Result_Val ;AN000;
495 dw STKS_Range ;AN000; number of stack range descriptions
496 db 0 ;AN000; no switch/keyword synonyms
497
498STKS_Range label byte ;AN000;
499 db 1 ;AN000; # of value definitions
500 db 1 ;AN000; # of ranges
501 db 1 ;AN000; Tag for this range
502 dd 0,64 ;AN000;
503
504STKS_Pos_2 label byte ;AN000;
505 dw 8000h ;AN000; Numeric value
506 dw 0 ;AN000; no functions
507 dw Result_Val ;AN000;
508 dw STK_SIZE_Range ;AN000; stack size range descriptions
509 db 0 ;AN000; no switch/keyword synonyms
510
511STK_SIZE_Range label byte ;AN000;
512 db 1 ;AN000; # of value definitions
513 db 1 ;AN000; # of ranges
514 db 1 ;AN000; Tag for this range
515 dd 0,512 ;AN000;
516;local variables
517P_Stack_Count dw 0 ;AN000;
518P_Stack_Size dw 0 ;AN000;
519
520;--------------------------------
521
522; MULTITRACK = [ ON | OFF ]
523
524MTrk_Parms label byte ;AN002;
525 dw MTrk_Parmsx ;AN002;
526 db 1 ;AN002; An extra delimeter list
527 db 1 ;AN002; length is 1
528 db SEMICOLON ;AN002;
529
530MTrk_Parmsx label byte ;AN002;
531 db 1,1 ;AN002; Min 1, Max 1 positional
532 dw MTrk_Pos ;AN002;
533 db 0 ;AN002; no switches
534 db 0 ;AN002; no keywords
535
536MTrk_Pos label word ;AN002;
537 dw 2000h ;AN002; Simple string
538 dw 0 ;AN002; No functions
539 dw Result_Val ;AN002;
540 dw On_Off_String ;AN002; ON,OFF string descriptions
541 db 0 ;AN002; no keyword/switch synonyms
542
543;local variables
544P_Mtrk db 0 ;AN002;
545;--------------------------------
546
547; CPSW = [ ON | OFF ]
548
549CPSW_Parms label byte ;AN002;
550 dw CPSW_Parmsx ;AN002;
551 db 1 ;AN002; An extra delimeter list
552 db 1 ;AN002; length is 1
553 db SEMICOLON ;AN002;
554
555CPSW_Parmsx label byte ;AN002;
556 db 1,1 ;AN002; Min 1, Max 1 positional
557 dw CPSW_Pos ;AN002;
558 db 0 ;AN002; no switches
559 db 0 ;AN002; no keywords
560
561CPSW_Pos label word ;AN002;
562 dw 2000h ;AN002; Simple string
563 dw 0 ;AN002; No functions
564 dw Result_Val ;AN002;
565 dw On_Off_String ;AN002; ON,OFF string descriptions
566 db 0 ;AN002; no keyword/switch synonyms
567
568;local variables
569P_CPSW db 0 ;AN002;
570
571;--------------------------------
572; SWITCHES=/K
573
574Swit_Parms label byte ;AN019;
575 dw Swit_Parmsx ;AN019;
576 db 1 ;AN019; An extra delimeter list
577 db 1 ;AN019; length is 1
578 db SEMICOLON ;AN019;
579
580Swit_Parmsx label byte ;AN019;
581 db 0,0 ;AN019; No positionals
582 db 1 ;AN019; 1 switch for now.
583 dw Swit_K_Ctrl ;AN019; /K control
584 db 0 ;AN019; no keywords
585
586Swit_K_Ctrl label word ;AN019;
587 dw 0 ;AN019; no matching flag
588 dw 0 ;AN019; no function
589 dw Result_Val ;AN019; return value
590 dw NoVal ;AN019; no value definition
591 db 1 ;AN019; # of switches
592Swit_K label byte ;AN019;
593 db '/K',0 ;AN019;
594;local variables
595P_Swit_K db 0 ;AN019;
596
597;******************************************************************************
598
599DOCONF:
600 PUSH CS
601 POP DS
602 ASSUME DS:SYSINITSEG
603
604 MOV AX,(CHAR_OPER SHL 8) ;GET SWITCH CHARACTER
605 INT 21H
606 MOV [COMMAND_LINE+1],DL ; Set in default command line
607
608 MOV DX,OFFSET CONFIG ;NOW POINTING TO FILE DESCRIPTION
609 MOV AX,OPEN SHL 8 ;OPEN FILE "CONFIG.SYS"
610 STC ;IN CASE OF INT 24
611 INT 21H ;FUNCTION REQUEST
612; JC ENDCONF ;Wasn't there, or couldn't open (sickness)
613 jc No_Config_sys ;AN028;
614 JMP NOPROB ;PROBLEM WITH OPEN
615No_Config_sys: ;AN028;
616 mov Multi_Pass_Id, 11 ;AN028; set it to unreasonable number
617ENDCONF:
618 return
619
620
621BADOP: MOV DX,OFFSET BADOPM ;WANT TO PRINT COMMAND ERROR "Unrecognized command..."
622 invoke PRINT
623 call Error_Line ;show "Error in CONFIG.SYS ..." .
624 JMP COFF
625
626Badop_p proc near ;AN000;
627;Same thing as BADOP, but will make sure to set DS register back to SYSINITSEG
628;and return back to the calller.
629 push cs
630 pop ds ;set ds to CONFIGSYS seg.
631 mov dx, offset badopm
632 invoke PRINT
633 call Error_Line
634 ret
635Badop_p endp
636
637Badparm_p proc near ;AN007;
638;Show "Bad command or parameters - xxxxxx"
639;In Badparm_seg, Badparm_off -> xxxxx
640;
641 cmp cs:Buffer_Pre_Scan, 1 ;AN030; Pre scanning Buffers ... /X?
642 je BadParmp_Ret ;AN030; then do not show any message.
643 push ds ;AN007;
644 push dx ;AN007;
645 push si ;AN007;
646
647 push cs ;AN007;
648 pop ds ;AN007;
649 mov dx, offset Badparm ;AN007;
650 invoke PRINT ;AN007;"Bad command or parameters - "
651 lds si, Badparm_ptr ;AN007;
652Badparm_Prt: ;AN007;print "xxxx" until CR.
653 mov dl, byte ptr [si] ;AN007;
654 mov ah,STD_CON_OUTPUT ;AN007;
655 int 21h ;AN007;
656 inc si ;AN007;
657 cmp dl, CR ;AN007;
658 jne Badparm_Prt ;AN007;
659 push cs ;AN007;
660 pop ds ;AN007;
661 mov dx, offset CRLFM ;AN007;
662 invoke PRINT ;AN007;
663 call Error_Line ;AN007;
664 pop si ;AN007;
665 pop dx ;AN007;
666 pop ds ;AN007;
667BadParmp_Ret: ;AN030;
668 ret ;AN007;
669Badparm_p endp
670
671NOPROB: ;GET FILE SIZE (NOTE < 64K!!)
672 MOV BX,AX
673 XOR CX,CX
674 XOR DX,DX
675 MOV AX,(LSEEK SHL 8) OR 2
676 INT 21H
677 MOV [COUNT],AX
678 XOR DX,DX
679 MOV AX,LSEEK SHL 8 ;Reset pointer to beginning of file
680 INT 21H
681; MOV DX,CS
682 mov dx, [ConfBot] ;AN022;Use current CONFBOT value
683 MOV AX,[COUNT]
684 mov [config_size], ax ;save the size of config.sys file.
685 call ParaRound
686 SUB DX,AX
687 SUB DX,11H ;ROOM FOR HEADER
688 MOV [CONFBOT],DX ; Config starts here. New CONBOT value.
689 CALL TEMPCDS ; Finally get CDS to "safe" location
690ASSUME DS:NOTHING,ES:NOTHING
691
692 MOV DX,[CONFBOT]
693 MOV DS,DX
694 MOV ES,DX
695 XOR DX,DX
696 MOV CX,[COUNT]
697 MOV AH,READ
698 STC ;IN CASE OF INT 24
699 INT 21H ;Function request
700 PUSHF
701;
702; Find the EOF mark in the file. If present, then trim length.
703
704 SaveReg <AX,DI,CX>
705 MOV AL,1Ah ; eof mark
706 MOV DI,DX ; point ro buffer
707 JCXZ PutEOL ; no chars
708 REPNZ SCASB ; find end
709 JNZ PutEOL ; none found and count exahusted
710;
711; We found a 1A. Back up
712;
713 DEC DI ; backup past 1A
714;
715; Just for the halibut, stick in an extra EOL
716;
717PutEOL:
718 MOV AL,CR
719 STOSB ; CR
720 MOV AL,LF
721 STOSB ; LF
722 SUB DI,DX ; difference moved
723 MOV Count,DI ; new count
724;
725; Restore registers
726;
727 RestoreReg <CX,DI,AX>
728
729 PUSH CS
730 POP DS
731ASSUME DS:SYSINITSEG
732 PUSH AX
733 MOV AH,CLOSE
734 INT 21H
735 POP AX
736 POPF
737 JC CONFERR ;IF NOT WE'VE GOT A PROBLEM
738 CMP CX,AX
739 JZ GETCOM ;COULDN'T READ THE FILE
740CONFERR:
741 MOV DX,OFFSET CONFIG ;WANT TO PRINT CONFIG ERROR
742 CALL BADFIL
743ENDCONV:JMP ENDCONF
744
745Multi_Pass: ;AN018;AN026; called to execute IFS=, INSTALL= commands
746 push cs ;AN018;
747 pop ds ;AN018;
748 cmp Multi_Pass_id, 10 ;J.K.
749 jae Endconv ;J.K. Do nothing. Just return.
750 push Confbot ;AN018;
751 pop es ;AN018; ES -> Confbot
752 mov si, Org_Count ;AN018;
753 mov Count, si ;AN018; set Count
754 xor si,si ;AN018;
755 mov Chrptr, si ;AN018; reset Chrptr, LineCount
756 mov LineCount, si ;AN018;
757 call GetChr ;AN018;
758 jmp Conflp ;AN018;
759GETCOM:
760 invoke ORGANIZE ;ORGANIZE THE FILE
761 CALL GETCHR
762
763CONFLP: JC ENDCONV
764 call Reset_DOS_Version ;AN024;AN026; Still need to reset version even IBMDOS handles this through
765 ; function 4Bh call, since IBMDOS does not know when Load/Overlay call finishes.
766
767IF NOT BUFFERFLAG
768 call EMS_Stub_handler ;AN030;
769ENDIF
770
771 inc LineCount ;AN000; Increase LineCount.
772 mov Buffer_Pre_Scan, 0 ;AN030; Reset Buffer_Pre_Scan.
773 mov MultDeviceFlag,0 ;AN001; Reset MultDeviceFlag.
774 mov SetDevMarkFlag,0 ;AN004; Reset SetDevMarkFlag.
775 cmp al, LF ;AN000; LineFeed?
776 je Blank_Line ;AN000; then ignore this line.
777 MOV AH,AL
778 CALL GETCHR
779 jnc TryI ;AN000;
780 cmp Multi_Pass_ID, 2 ;AN026;
781 jae Endconv ;AN026;Do not show Badop again for multi_pass.
782 JMP BADOP
783
784COFF: PUSH CS
785 POP DS
786 invoke NEWLINE
787 JMP CONFLP
788Blank_Line: ;AN000;
789 call Getchr ;AN000;
790 jmp CONFLP ;AN000;
791
792COFF_P:
793 push cs
794 pop ds
795
796
797;J.K. 1/27/88 ;;;;;;;;;;;;;;;;;;
798;To handle INSTALL= commands, we are going to use multi-pass.
799;The first pass handles the other commands and only set Install_Flag when
800;it finds any INSTALL command. The second pass will only handle the
801;INSTALL= command.
802
803;------------------------------------------------------------------------------
804;INSTALL command
805;------------------------------------------------------------------------------
806TRYI:
807 cmp Multi_Pass_Id, 0 ;AN029; the initial pass for XMAEM.SYS
808 je Multi_Try_XMAEM ;AN029; and BUFFERS= ... /X pre scan.
809 cmp Multi_Pass_Id, 2 ;AN026; the second pass for IFS= ?
810 je Multi_Try_J ;AN026;
811 cmp Multi_Pass_Id, 3 ;AN026; the third pass for INSTALL= ?
812 je Multi_Try_I ;AN026;
813 cmp ah, 'I' ;AN018; INSTALL= command?
814 jne TryB ;AN018; the first pass is for normal operation.
815 or Install_Flag, HAVE_INSTALL_CMD ;AN018; Set the flag
816 jmp coff ;AN018; and handles the next command
817
818Multi_Try_XMAEM: ;AN029;
819 cmp ah, 'D' ;AN029; device= command?
820 jne Multi_Try_Buff ;AN029; no skip it.
821 call Chk_XMAEM ;AN029; is it for XMAEM.SYS?
822 jnz Multi_Pass_FIlter ;AN029; no skip it.
823 mov byte ptr es:[si-1], 0FFh ;AN029; mark this command as a Null command for the next pass.
824 jmp TryDJ ;AN029; execute this command.
825Multi_Try_Buff: ;AN030;
826 cmp ah, 'B' ;AN030; Buffers= command?
827 jne Multi_Pass_Filter ;AN030;
828 mov Buffer_Pre_Scan, 1 ;AN030; Set Buffer_Pre_Scan
829 jmp TryB ;AN030; TryB will set P_Buffer_Slash_X to non-zero value.
830
831Multi_Try_J: ;AN026;
832 cmp ah, 'J' ;AN026; IFS= command?
833 jne Multi_Pass_Filter ;AN026; No. Ignore this.
834 jmp GotJ ;AN026; Handles IFS= command.
835
836Multi_Try_I: ;AN026;
837 cmp ah, 'I' ;AN026; INSTALL= command?
838 jne Multi_Pass_Filter ;AN026; No. Ignore this.
839 call Do_Install_Exec ;Install it.
840 jmp Coff ;to handle next Install= command.
841
842Multi_Pass_Filter: ;AN023;AN026;
843 cmp ah, 'Y' ;AN023; Comment?
844 je Multi_Pass_Adjust ;AN023;
845 cmp ah, 'Z' ;AN023; Bad command?
846 je Multi_Pass_Adjust ;AN023;
847 cmp ah, '0' ;AN023; REM?
848 jne Multi_Pass_Coff ;AN023; ignore the rest of the commands.
849Multi_Pass_Adjust: ;AN023; These commands need to
850 dec Chrptr ;AN023; adjust chrptr, count
851 inc Count ;AN023; for NEWLINE proc.
852Multi_Pass_Coff: ;AN023;
853 jmp Coff ;AN018; To handle next INSTALL= commands.
854
855;------------------------------------------------------------------------------
856
857Sysinit_Parse proc
858;Set up registers for SysParse
859;In) ES:SI -> command line in CONFBOT
860; DI -> offset of the parse control defintion.
861;
862;Out) Calls SYSPARSE.
863; Carry will set if Parse error.
864; *** The caller should check the EOL condition by looking at AX
865; *** after each call.
866; *** If no parameters are found, then AX will contain a error code.
867; *** If the caller needs to look at the SYNOMYM@ of the result,
868; *** the caller should use CS:@ instead of ES:@.
869; CX register should be set to 0 at the first time the caller calls this
870; procedure.
871; AX - exit code
872; BL - TErminated delimeter code
873; CX - new positional ordinal
874; SI - set to pase scanned operand
875; DX - selected result buffer
876
877 push es ;save es,ds
878 push ds
879
880 push es
881 pop ds ;now DS:SI -> command line
882 push cs
883 pop es ;now ES:DI -> control definition
884
885 mov cs:Badparm_Seg,ds ;AN007;Save the pointer to the parm
886 mov cs:Badparm_Off,si ;AN007; we are about to parse for Badparm msg.
887 mov dx, 0
888 call SysParse
889 cmp ax, $P_NO_ERROR ;no error
890; $IF E,OR
891 JE $$LL1
892 cmp ax, $P_RC_EOL ;or the end of line?
893; $IF E
894 JNE $$IF1
895$$LL1:
896 clc
897; $ELSE
898 JMP SHORT $$EN1
899$$IF1:
900 stc
901; $ENDIF
902$$EN1:
903 pop ds
904 pop es ;restore es,ds
905 ret
906Sysinit_Parse endp
907
908;------------------------------------------------------------------------------
909; Buffer command
910;------------------------------------------------------------------------------
911;*******************************************************************************
912; *
913; Function: Parse the parameters of buffers= command. *
914; *
915; Input : *
916; ES:SI -> parameters in command line. *
917; Output: *
918; Buffers set *
919; Buffer_Slash_X flag set if /X option chosen. *
920; H_Buffers set if secondary buffer cache specified. *
921; *
922; Subroutines to be called: *
923; Sysinit_Parse *
924; Logic: *
925; { *
926; Set DI points to Buf_Parms; /*Parse control definition*/ *
927; Set DX,CX to 0; *
928; Reset Buffer_Slash_X; *
929; While (End of command line) *
930; { Sysinit_parse; *
931; if (no error) then *
932; if (Result_Val.$P_SYNONYM_ptr == Slash_E) then /*Not a switch *
933; Buffer_Slash_X = 1 *
934; else if (CX == 1) then /* first positional */ *
935; Buffers = Result_Val.$P_Picked_Val; *
936; else H_Buffers = Result_Val.$P_Picked_Val; *
937; else {Show Error message;Error Exit} *
938; }; *
939; If (Buffer_Slash_X is off & Buffers > 99) then Show_Error; *
940; }; *
941; *
942;*******************************************************************************
943;TryB: CMP AH,'B' ;BUFFER COMMAND?
944; JNZ TRYC
945; invoke GETNUM
946; JZ TryBBad ; Gotta have at least one
947; CMP AX,100 ; check for max number
948; JB SaveBuf
949;TryBBad:JMP BadOp
950;SaveBuf:
951; MOV [BUFFERS],AX
952;CoffJ1: JMP COFF
953
954TryB:
955 CMP AH,'B'
956 JNZ TryC
957 mov P_Buffer_Slash_X, 0 ;AN000;AN025;
958 mov di, offset Buf_Parms ;AN000;
959 xor cx, cx ;AN000;
960 mov dx, cx ;AN000;
961
962; $SEARCH ;AN000;
963$$DO4:
964 call Sysinit_Parse ;AN000;
965; $EXITIF C ;AN000; Parse Error,
966 JNC $$IF4
967 call Badparm_p ;AN007; and Show messages and end the search loop.
968; $ORELSE ;AN000;
969 JMP SHORT $$SR4
970$$IF4:
971 cmp ax, $P_RC_EOL ;AN000; End of Line?
972; $LEAVE E ;AN000; then jmp to $Endloop for semantic check.
973 JE $$EN4
974 cmp Result_Val.$P_SYNONYM_PTR, offset Switch_X ;AN000;AN025;
975; $IF E ;AN000;
976 JNE $$IF8
977 mov P_Buffer_Slash_X, 1 ;AN000;AN025; set the flag
978; $ELSE ;AN000;
979 JMP SHORT $$EN8
980$$IF8:
981 mov ax, word ptr Result_Val.$P_PICKED_VAL ;AN000;
982 cmp cx, 1 ;AN000;
983; $IF E ;AN000;
984 JNE $$IF10
985 mov P_Buffers, ax ;AN000;
986; $ELSE ;AN000;
987 JMP SHORT $$EN10
988$$IF10:
989 mov P_H_Buffers, ax ;AN000;
990; $ENDIF ;AN000;
991$$EN10:
992; $ENDIF ;AN000;
993$$EN8:
994; $ENDLOOP ;AN000;
995 JMP SHORT $$DO4
996$$EN4:
997 cmp P_Buffers, 99 ;AN000;
998; $IF A,AND ;AN000;
999 JNA $$IF15
1000 cmp P_Buffer_Slash_X, 0 ;AN000;AN025;
1001; $IF E ;AN000;
1002 JNE $$IF15
1003 call Badparm_p ;AN000;
1004 mov P_H_Buffers, 0 ;AN000;
1005; $ELSE ;AN000;
1006 JMP SHORT $$EN15
1007$$IF15:
1008 mov ax, P_Buffers ;AN000; We don't have any problem.
1009 mov Buffers, ax ;AN000; Now, let's set it really.
1010 mov ax, P_H_Buffers ;AN000;
1011 mov H_Buffers, ax ;AN000;
1012 mov al, P_Buffer_Slash_X ;AN000;AN025;
1013 mov Buffer_Slash_X, al ;AN000;AN025;
1014 mov ax, LineCount ;AN000;
1015 mov Buffer_LineNum, ax ;AN000; Save the line number for the future use.
1016; $ENDIF ;AN000;
1017$$EN15:
1018; $ENDSRCH ;AN000;
1019$$SR4:
1020 jmp Coff
1021
1022;------------------------------------------------------------------------------
1023; Break command
1024;------------------------------------------------------------------------------
1025;*******************************************************************************
1026; *
1027; Function: Parse the parameters of Break = command. *
1028; *
1029; Input : *
1030; ES:SI -> parameters in command line. *
1031; Output: *
1032; Turn the Control-C check on or off. *
1033; *
1034; Subroutines to be called: *
1035; Sysinit_Parse *
1036; Logic: *
1037; { *
1038; Set DI to Brk_Parms; *
1039; Set DX,CX to 0; *
1040; While (End of command line) *
1041; { Sysinit_Parse; *
1042; if (no error) then *
1043; if (Result_Val.$P_Item_Tag == 1) then /*ON */ *
1044; Set P_Ctrl_Break, on; *
1045; else /*OFF */ *
1046; Set P_Ctrl_Break, off; *
1047; else {Show message;Error_Exit}; *
1048; }; *
1049; If (no error) then *
1050; DOS function call to set Ctrl_Break check according to *
1051; }; *
1052; *
1053;********************************************************************************
1054;TryC: CMP AH,'C'
1055; JZ GOTC
1056; JMP TRYDJ
1057;GOTC:
1058; CMP AL,'O' ;FIRST LETTER OF "ON" or "OFF"
1059; JNZ TryCBad
1060; CALL GETCHR
1061; JC TryCBad
1062; CMP AL,'N' ;SECOND LETTER OF "ON"
1063; JNZ TryCoff
1064; MOV AH,SET_CTRL_C_TRAPPING ;TURN ON CONTROL-C CHECK
1065; MOV AL,1
1066; MOV DL,AL
1067; INT 21H
1068;CoffJ2: JMP Coff
1069;TryCOff:CMP AL,'F'
1070; JNZ TryCBad ; Check for "OFF"
1071; CALL GetChr
1072; JC TryCBad
1073; CMP AL,'F'
1074; JZ COffJ2
1075;TryCBad:JMP BadOp
1076;
1077TryC:
1078 CMP AH,'C'
1079 JNZ TRYM
1080 mov di, offset Brk_Parms ;AN000;
1081 xor cx,cx ;AN000;
1082 mov dx,cx ;AN000;
1083; $SEARCH ;AN000;
1084$$DO19:
1085 call Sysinit_Parse ;AN000;
1086; $EXITIF C ;AN000; Parse error
1087 JNC $$IF19
1088 call Badparm_p ;AN007; Show message and end the serach loop.
1089; $ORELSE ;AN000;
1090 JMP SHORT $$SR19
1091$$IF19:
1092 cmp ax, $P_RC_EOL ;AN000; End of Line?
1093; $LEAVE E ;AN000; then end the $ENDLOOP
1094 JE $$EN19
1095 cmp Result_Val.$P_ITEM_TAG, 1 ;AN000;
1096; $IF E ;AN000;
1097 JNE $$IF23
1098 mov P_Ctrl_Break, 1 ;AN000; Turn it on
1099; $ELSE ;AN000;
1100 JMP SHORT $$EN23
1101$$IF23:
1102 mov P_Ctrl_Break, 0 ;AN000; Turn it off
1103; $ENDIF ;AN000;
1104$$EN23:
1105; $ENDLOOP ;AN000; we actually set the ctrl break
1106 JMP SHORT $$DO19
1107$$EN19:
1108 mov ah, SET_CTRL_C_TRAPPING ;AN000; if we don't have any parse error.
1109 mov al, 1 ;AN000;
1110 mov dl, P_Ctrl_Break ;AN000;
1111 Int 21h ;AN000;
1112; $ENDSRCH ;AN000;
1113$$SR19:
1114 jmp Coff
1115
1116;------------------------------------------------------------------------------
1117; MultiTrack command
1118;------------------------------------------------------------------------------
1119;*******************************************************************************
1120; *
1121; Function: Parse the parameters of MultiTrack= command. *
1122; *
1123; Input : *
1124; ES:SI -> parameters in command line. *
1125; Output: *
1126; Turn MulTrk_Flag on or off. *
1127; *
1128; Subroutines to be called: *
1129; Sysinit_Parse *
1130; Logic: *
1131; { *
1132; Set DI to Brk_Parms; *
1133; Set DX,CX to 0; *
1134; While (End of command line) *
1135; { Sysinit_Parse; *
1136; if (no error) then *
1137; if (Result_Val.$P_Item_Tag == 1) then /*ON */ *
1138; Set P_Mtrk, on; *
1139; else /*OFF */ *
1140; Set P_Mtrk, off; *
1141; else {Show message;Error_Exit}; *
1142; }; *
1143; If (no error) then *
1144; DOS function call to set MulTrk_Flag according to P_Mtrk. *
1145; *
1146; }; *
1147; *
1148;********************************************************************************
1149TryM: ;AN002;
1150 CMP AH,'M' ;AN002;
1151 JNZ TRYW ;AN002;
1152 mov di, offset Mtrk_Parms ;AN002;
1153 xor cx,cx ;AN002;
1154 mov dx,cx ;AN002;
1155; $SEARCH ;AN002;
1156$$DO28:
1157 call Sysinit_Parse ;AN002;
1158; $EXITIF C ;AN002; Parse error
1159 JNC $$IF28
1160 call Badparm_p ;AN007; Show message and end the serach loop.
1161; $ORELSE ;AN002;
1162 JMP SHORT $$SR28
1163$$IF28:
1164 cmp ax, $P_RC_EOL ;AN002; End of Line?
1165; $LEAVE E ;AN002; then end the $ENDLOOP
1166 JE $$EN28
1167 cmp Result_Val.$P_ITEM_TAG, 1 ;AN002;
1168; $IF E ;AN002;
1169 JNE $$IF32
1170 mov P_Mtrk, 1 ;AN002; Turn it on temporarily.
1171; $ELSE ;AN002;
1172 JMP SHORT $$EN32
1173$$IF32:
1174 mov P_Mtrk, 0 ;AN002; Turn it off temporarily.
1175; $ENDIF ;AN002;
1176$$EN32:
1177; $ENDLOOP ;AN002; we actually set the MulTrk_Flag here.
1178 JMP SHORT $$DO28
1179$$EN28:
1180 push ds ;AN002;
1181 mov ax, Code ;AN002;
1182 mov ds, ax ;AN002;
1183 assume ds:Code
1184 cmp P_Mtrk, 0 ;AN002;
1185; $IF E ;AN002;
1186 JNE $$IF36
1187 mov MulTrk_Flag, MULTRK_OFF2 ;AN002; 0001h
1188; $ELSE ;AN002;
1189 JMP SHORT $$EN36
1190$$IF36:
1191 mov MulTrk_Flag, MULTRK_ON ;AN002; 8000h
1192; $ENDIF ;AN002;
1193$$EN36:
1194 pop ds ;AN002;
1195 assume ds:SYSINITSEG
1196; $ENDSRCH ;AN002;
1197$$SR28:
1198 jmp Coff ;AN002;
1199
1200;------------------------------------------------------------------------------
1201; CPSW command
1202;------------------------------------------------------------------------------
1203;*******************************************************************************
1204; *
1205; Function: Parse the parameters of CPSW= command. *
1206; *
1207; Input : *
1208; ES:SI -> parameters in command line. *
1209; Output: *
1210; Turn CPSW on or off. *
1211; *
1212; Subroutines to be called: *
1213; Sysinit_Parse *
1214; Logic: *
1215; { *
1216; Set DI to CPSW_Parms; *
1217; Set DX,CX to 0; *
1218; While (End of command line) *
1219; { Sysinit_Parse; *
1220; if (no error) then *
1221; if (Result_Val.$P_Item_Tag == 1) then /*ON */ *
1222; Set P_CPSW, on; *
1223; else /*OFF */ *
1224; Set P_CPSW, off; *
1225; else {Show message;Error_Exit}; *
1226; }; *
1227; If (no error) then *
1228; DOS function call to set CPSW according to P_CPSW. *
1229; }; *
1230; *
1231;********************************************************************************
1232TryW: ;AN002;
1233 CMP AH,'W' ;AN002;
1234 JNZ TRYDJ ;AN002;
1235 mov di, offset CPSW_Parms ;AN002;
1236 xor cx,cx ;AN002;
1237 mov dx,cx ;AN002;
1238; $SEARCH ;AN002;
1239$$DO40:
1240 call Sysinit_Parse ;AN002;
1241; $EXITIF C ;AN002; Parse error
1242 JNC $$IF40
1243 call Badparm_p ;AN007; Show message and end the serach loop.
1244; $ORELSE ;AN002;
1245 JMP SHORT $$SR40
1246$$IF40:
1247 cmp ax, $P_RC_EOL ;AN002; End of Line?
1248; $LEAVE E ;AN002; then end the $ENDLOOP
1249 JE $$EN40
1250 cmp Result_Val.$P_ITEM_TAG, 1 ;AN002;
1251; $IF E ;AN002;
1252 JNE $$IF44
1253 mov P_CPSW, 1 ;AN002; Turn it on temporarily.
1254; $ELSE ;AN002;
1255 JMP SHORT $$EN44
1256$$IF44:
1257 mov P_CPSW, 0 ;AN002; Turn it off temporarily.
1258; $ENDIF ;AN002;
1259$$EN44:
1260; $ENDLOOP ;AN002; we actually set the MulTrk_Flag here.
1261 JMP SHORT $$DO40
1262$$EN40:
1263 mov ah, SET_CTRL_C_TRAPPING ;AN000; The same function number as Ctrl_Break
1264 mov al, 4 ;AN000; Set CPSW state function
1265 mov dl, P_CPSW ;AN000; 0=off, 1=on
1266 Int 21h ;AN000;
1267; $ENDSRCH ;AN002;
1268$$SR40:
1269 jmp Coff ;AN002;
1270
1271;------------------------------------------------------------------------------
1272; Device command
1273;------------------------------------------------------------------------------
1274TRYDJ:
1275 and cs:IFS_Flag, NOT_IFS ;AN000; Reset the flag
1276 CMP AH,'D'
1277 JZ GOTDJ
1278 CMP AH,'J'
1279 jz GOTJ
1280 JMP TRYQ
1281GOTJ: ;AN000; IFS= command.
1282 or cs:[IFS_Flag], IS_IFS ;AN000; set the flag.
1283 cmp Multi_Pass_Id, 2 ;second pass?
1284 je GOTDJ ;then proceed
1285 jmp Coff ;else ignore this until the second pass.
1286
1287; jmp GOTDJ_Cont
1288;GOTD:
1289; test cs:[IFS_Flag], HAD_IFS ;AN000; Cannot have DEVICE= command after IFS= command.
1290; jz GOTDJ_Cont ;AN000;
1291; call Incorrect_Order ;AN000; Display "Incorrect order ..." msg.
1292; jmp COFF ;AN000;
1293
1294GOTDJ:
1295 MOV BX,CS ;DEVICE= or IFS= command.
1296 MOV DS,BX
1297
1298 MOV WORD PTR [BPB_ADDR],SI
1299 MOV WORD PTR [BPB_ADDR+2],ES
1300
1301;J.K. In case it is for IFS=, then set the parameter pointer.
1302 mov word ptr [ifs_rh.IFSR_PARMS@], SI ;AN000; for IFS
1303 mov word ptr [ifs_rh.IFSR_PARMS@+2], ES ;AN000;
1304
1305 CALL ROUND
1306;J.K. Set up the DEVMARK entries here for MEM command.
1307;J.K. Only the DEVMARK_ID and DEVMARK_FILENAME will be set.
1308;J.K. DEVMARK_SIZE should be set after a successful process of this file.
1309 call Set_DevMark ;AN004;
1310 inc [MEMHI] ;AN004;Size of DEVMARK is a paragraph!!
1311 ;Don't forget decrease MEMHI
1312 ; with an unsuccessful process of this file!!.
1313 XOR AX,AX
1314 MOV WORD PTR [ENTRY_POINT],AX
1315 MOV AX,[MEMHI]
1316 MOV WORD PTR [ENTRY_POINT+2],AX ;SET ENTRY POINT
1317
1318 IF NOT NOEXEC
1319 MOV [LDOFF],AX ;SET LOAD OFFSET
1320 ENDIF
1321
1322 PUSH ES
1323 POP DS
1324ASSUME DS:NOTHING
1325 MOV DX,SI ;DS:DX POINTS TO FILE NAME
1326
1327 IF NOEXEC
1328 LES BX,DWORD PTR CS:[MEMLO]
1329 CALL LDFIL ;LOAD IN THE DEVICE DRIVER
1330 ELSE
1331; We are going to open the cdevice driver and size it as is done
1332; in LDFIL. The reason we must do this is that EXEC does NO checking
1333; for us. We must make sure there is room to load the device without
1334; trashing SYSINIT. This code is not
1335; perfect (for instance .EXE device drivers are possible) because
1336; it does its sizing based on the assumption that the file being loaded
1337; is a .COM file. It is close enough to correctness to be usable.
1338 MOV ES,AX ;ES:0 is LOAD addr
1339 MOV AX,OPEN SHL 8 ;OPEN THE FILE
1340 STC ;IN CASE OF INT 24
1341 INT 21H
1342 JC BADLDRESET
1343 MOV BX,AX ;Handle in BX
1344;AN016; UNDO THE EXTENDED ATTRIBUTE HANDLING
1345; call Get_Ext_Attribute ;AN009;
1346; jc BadLdReset ;AN009;
1347; test cs:[IFS_Flag], IS_IFS ;AN009;
1348; jnz Chk_Ext_Attr_IFS ;AN009;
1349; cmp al, EA_UNSPECIFIED ;AN009;Check the extended attr. for device driver
1350; je Ext_Attr_Ok ;AN009; Allow 0 and EA_DEVICE_DRIVER
1351; cmp al, EA_DEVICE_DRIVER ;AN009;
1352; je Ext_Attr_Ok ;AN009;
1353; stc ;AN012;BadLdReset depends on the carry bit.
1354; jmp BadLdReset ;AN009;
1355;Chk_Ext_Attr_IFS: ;AN009;
1356; cmp al, EA_IFS_DRIVER ;AN009;
1357; je Ext_Attr_Ok ;AN012;
1358; stc ;AN012;
1359; jmp BadLdReset ;AN012;
1360;Ext_Attr_Ok: ;AN009;
1361 PUSH DX ; Save pointer to name
1362 XOR CX,CX
1363 XOR DX,DX
1364 MOV AX,(LSEEK SHL 8) OR 2
1365 STC ;IN CASE OF INT 24
1366 INT 21H ; Get file size in DX:AX
1367 JNC GO_AHEAD_LOAD
1368 MOV AH,CLOSE ; Close file
1369 INT 21H
1370 POP DX ; Clean stack
1371 STC ; Close may clear carry
1372 JMP SHORT BADLDRESET
1373
1374GO_AHEAD_LOAD:
1375 ; Convert size in DX:AX to para in AX
1376 ADD AX,15 ; Round up size for conversion to para
1377 ADC DX,0
1378 MOV CL,4
1379 SHR AX,CL
1380 MOV CL,12
1381 SHL DX,CL ; Low nibble of DX to high nibble
1382 OR AX,DX ; AX is now # of para for file
1383
1384 MOV CX,ES ; CX:0 is xaddr
1385 ADD CX,AX ; New device will take up to here
1386 JC MEM_ERRJY ; WOW!!!!
1387 CMP CX,CS:[ALLOCLIM]
1388 JB OKLDX
1389MEM_ERRJY:
1390 JMP MEM_ERR
1391
1392OKLDX:
1393 POP DX ; Recover name pointer
1394 MOV AH,CLOSE ; Close file
1395 INT 21H
1396 MOV BX,CS
1397 MOV ES,BX
1398 MOV BX,OFFSET PRMBLK ;ES:BX POINTS TO PARAMETERS
1399 MOV AL,3
1400 MOV AH,EXEC
1401 STC ;IN CASE OF INT 24
1402 INT 21H ;LOAD IN THE DEVICE DRIVER
1403 ENDIF
1404
1405BADLDRESET:
1406 PUSH DS
1407 POP ES ;ES:SI BACK TO CONFIG.SYS
1408 PUSH CS
1409 POP DS ;DS BACK TO SYSINIT
1410ASSUME DS:SYSINITSEG
1411 JNC GOODLD
1412BADBRK:
1413 test cs:[SetDevMarkFlag],SETBRKDONE ;AN004;If already Set_Break is done,
1414 jnz Skip0_ResetMEMHI ;AN004; then do not
1415 dec cs:[MEMHI] ;AN004;Adjust MEMHI by a paragrah of DEVMARK.
1416Skip0_ResetMEMHI:
1417 cmp byte ptr es:[si], CR ;file name is CR? (Somebody entered "device=" without filename)
1418 jne BADBRK_1
1419 jmp BADOP ;show "Unrecognized command in CONFIG.SYS"
1420BADBRK_1:
1421 invoke BADLOAD
1422 JMP COFF
1423
1424GOODLD:
1425;J.K. If it is IFS=, then we should set IFS_DOSCALL@ field in IFSHEADER.
1426 test cs:[IFS_Flag], IS_IFS ;AN000;
1427 jz Skip_IFSHEADER_Set ;AN000;
1428 push es ;AN000;
1429 push di ;AN000;
1430 push ds ;AN000;
1431 mov bx, word ptr cs:[ENTRY_POINT+2] ;AN000;
1432 mov ds, bx ;AN000; DS:0 will be the header
1433 les di, cs:[DosInfo] ;AN000;
1434 mov bx, word ptr es:[di.SYSI_IFS_DOSCALL@] ;AN000;
1435 mov word ptr ds:[IFS_DOSCALL@], bx ;AN000;
1436 mov bx, word ptr es:[di.SYSI_IFS_DOSCALL@]+2 ;AN000;
1437 mov word ptr ds:[IFS_DOSCALL@]+2, bx ;AN000;
1438 pop ds ;AN000;
1439 pop di ;AN000;
1440 pop es ;AN000;
1441Skip_IFSHEADER_Set: ;AN000;
1442 SaveReg <ES,SI> ;INITIALIZE THE DEVICE
1443; call Chk_IBMCACHE ;AN024 IBMCACHE.SYS problem.;AN026;IBMDOS will handles this thru 4Bh call.
1444Restore:MOV BL,ES:[SI] ; while ((c=*p) != 0)
1445 OR BL,BL
1446 JZ Got
1447 INC SI ; p++;
1448 JMP Restore
1449Got: MOV BYTE PTR ES:[SI],' ' ; *p = ' ';
1450 SaveReg <ES,SI>
1451 PUSH CS
1452 POP ES
1453
1454 test cs:[IFS_Flag], IS_IFS ;AN000;
1455 jz Got_Device_Com ;AN000;
1456 mov bx, IFS_CALL@ ;AN000; offset from the start of IFSHEADER
1457 call CallIFS ;AN000;
1458 jmp short End_Init_Call
1459Got_Device_Com:
1460 push ds ;AN017;
1461 push si ;AN017;
1462 lds si, cs:[ENTRY_POINT] ;AN017; Peeks the header attribute
1463 test word ptr ds:[si.SDEVATT], DEVTYP ;AN017;Block device driver?
1464 jnz Got_Device_Com_Cont ;AN017;No.
1465 lds si, cs:[DOSINFO] ;AN017; DS:SI -> SYS_VAR
1466 cmp ds:[si.SYSI_NUMIO], 26 ;AN017; No more than 26 drive number
1467 jb Got_Device_Com_Cont ;AN017;
1468 pop si ;AN017;
1469 pop ds ;AN017;
1470 pop si ;AN017;clear the stack
1471 pop es ;AN017;
1472 jmp BadNumBlock ;AN017;
1473Got_Device_Com_Cont: ;AN017;
1474 pop si ;AN017;
1475 pop ds ;AN017;
1476 MOV BX,SDEVSTRAT
1477 invoke CALLDEV ; CallDev (SDevStrat);
1478 MOV BX,SDEVINT
1479 invoke CALLDEV ; CallDev (SDevInt);
1480End_Init_Call:
1481 RestoreReg <SI,DS>
1482 MOV BYTE PTR [SI],0 ; *p = 0;
1483
1484 PUSH CS
1485 POP DS
1486
1487 test [IFS_Flag], IS_IFS ;AN000;
1488 jz Was_Device_Com ;AN000;
1489 cmp [ifs_rh.IFSR_RETCODE], 0 ;AN000; Was a success ?
1490 jne Erase_Dev_do ;AN000;
1491 pop si ;AN000; restore es:si to clean up the
1492 pop es ;AN000; stack for Set_Break call.
1493 mov ax, word ptr [Entry_Point+2] ;AN000; Get the loaded segment
1494 add ax, word ptr [ifs_rh.IFSR_RESSIZE] ;AN000;
1495 mov word ptr [Break_addr], 0 ;AN000;
1496 mov word ptr [Break_addr+2], ax ;AN000;
1497 or cs:[SetDevMarkFlag], FOR_DEVMARK ;AN004;
1498 invoke Set_Break ;AN000; Will also check the memory size too.
1499 push es ;AN000; Save it again, in case, for Erase_Dev_Do.
1500 push si ;AN000;
1501 jc Erase_Dev_do ;AN000;
1502Link_IFS: ;AN000;
1503 les di, cs:[dosinfo] ;AN000;
1504 mov cx, word ptr es:[di.SYSI_IFS] ;AN000; save old pointer
1505 mov dx, word ptr es:[di.SYSI_IFS+2] ;AN000;
1506 lds si, cs:[Entry_Point] ;AN000;
1507 mov word ptr es:[di.SYSI_IFS],si ;AN000;
1508 mov word ptr es:[di.SYSI_IFS+2], ds ;AN000;
1509 mov word ptr ds:[si], cx ;AN000; We don't permit multiple IFSs.
1510 mov word ptr ds:[si+2], dx ;AN000;
1511 pop si ;AN000; Restore es:si for the next command.
1512 pop es ;AN000;
1513; mov cs:[IFS_Flag], HAD_IFS ;AN014; Set the flag.
1514 jmp COFF ;AN000;
1515
1516ERASE_DEV_do: ;AC000;; Modified to show message "Error in CONFIG.SYS..."
1517 pop si
1518 pop es
1519 push cs
1520 pop ds
1521 test [SetDevMarkFlag],SETBRKDONE ;AN004;If already Set_Break is done,
1522 jnz Skip1_ResetMEMHI ;AN004; then do not
1523 dec [MEMHI] ;AN004;Adjust MEMHI by a paragrah of DEVMARK.
1524Skip1_ResetMEMHI:
1525 cmp ConfigMsgFlag, 0 ;AN015;
1526 je No_Error_Line_Msg ;AN015;
1527 call Error_Line ;AN021; No "Error in CONFIG.SYS" msg for device driver. DCR D493
1528 mov ConfigMsgFlag, 0 ;AN015;AN021;Set the default value again.
1529No_Error_Line_Msg: ;AN015;
1530 JMP Coff
1531
1532Was_Device_Com: ;AN000;
1533 MOV AX,WORD PTR [BREAK_ADDR+2]
1534 CMP AX,[MEMORY_SIZE]
1535 JB BREAKOK
1536 POP SI
1537 POP ES
1538 JMP BADBRK
1539
1540BREAKOK:
1541 LDS DX,[ENTRY_POINT] ;SET DS:DX TO HEADER
1542 MOV SI,DX
1543 ADD SI,SDEVATT ;DS:SI POINTS TO ATTRIBUTES
1544 LES DI,CS:[DOSINFO] ;ES:DI POINT TO DOS INFO
1545 MOV AX,DS:[SI] ;GET ATTRIBUTES
1546 TEST AX,DEVTYP ;TEST IF BLOCK DEV
1547 JZ ISBLOCK
1548 or cs:[SetDevMarkFlag],FOR_DEVMARK ;AN004;
1549 invoke Set_Break ; Go ahead and alloc mem for device
1550 jc Erase_Dev_do ;device driver's Init routien failed.
1551 TEST AX,ISCIN ;IS IT A CONSOLE IN?
1552 JZ TRYCLK
1553 MOV WORD PTR ES:[DI.SYSI_CON],DX
1554 MOV WORD PTR ES:[DI.SYSI_CON+2],DS
1555
1556TRYCLK: TEST AX,ISCLOCK ;IS IT A CLOCK DEVICE?
1557 JZ GOLINK
1558 MOV WORD PTR ES:[DI+SYSI_CLOCK],DX
1559 MOV WORD PTR ES:[DI+SYSI_CLOCK+2],DS
1560GOLINK: JMP LINKIT
1561
1562ISBLOCK:
1563 MOV AL,CS:[UNITCOUNT] ;IF NO UNITS FOUND, erase the device
1564 OR AL,AL
1565 jz Erase_Dev_do
1566; JNZ PERDRV
1567; MOV AX, -1
1568; JMP ENDDEV
1569
1570PERDRV:
1571 CBW ; WARNING NO DEVICE > 127 UNITS
1572 MOV CX,AX
1573 MOV DH,AH
1574 MOV DL,ES:[DI.SYSI_NUMIO] ;GET NUMBER OF DEVICES
1575 MOV AH,DL
1576 ADD AH,AL ; Check for too many devices
1577 CMP AH,26 ; 'A' - 'Z' is 26 devices
1578 JBE OK_BLOCK
1579BadNumBlock: ;AN017;
1580 PUSH CS
1581 POP DS
1582 MOV DX,OFFSET BADBLOCK
1583 invoke PRINT
1584 JMP ERASE_DEV_do
1585
1586OK_BLOCK:
1587 or cs:[SetDevMarkFlag],FOR_DEVMARK ;AN004;
1588 invoke SET_BREAK ; Alloc the device
1589 ADD ES:[DI.SYSI_NUMIO],AL ;UPDATE THE AMOUNT
1590 ADD CS:DriveNumber,AL ; remember amount for next device
1591 LDS BX,CS:[BPB_ADDR] ;POINT TO BPB ARRAY
1592PERUNIT:
1593 LES BP,CS:[DOSINFO]
1594 LES BP,DWORD PTR ES:[BP.SYSI_DPB] ;GET FIRST DPB
1595
1596SCANDPB:CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1
1597 JZ FOUNDPB
1598 LES BP,ES:[BP.DPB_NEXT_DPB]
1599 JMP SCANDPB
1600FOUNDPB:
1601 MOV AX,CS:[MEMLO]
1602 MOV WORD PTR ES:[BP.DPB_NEXT_DPB],AX
1603 MOV AX,CS:[MEMHI]
1604 MOV WORD PTR ES:[BP.DPB_NEXT_DPB+2],AX
1605 LES BP,DWORD PTR CS:[MEMLO]
1606 ADD WORD PTR CS:[MEMLO],DPBSIZ
1607 or cs:[SetDevMarkFlag], FOR_DEVMARK ;AN004;Add DPB area for this unit
1608 CALL ROUND ;Check for alloc error
1609 MOV WORD PTR ES:[BP.DPB_NEXT_DPB],-1
1610 MOV ES:[BP.DPB_FIRST_ACCESS],-1
1611
1612 MOV SI,[BX] ;DS:SI POINTS TO BPB
1613 INC BX
1614 INC BX ;POINT TO NEXT GUY
1615 MOV WORD PTR ES:[BP.DPB_DRIVE],DX
1616 MOV AH,SETDPB ;HIDDEN SYSTEM CALL
1617 INT 21H
1618 MOV AX,ES:[BP.DPB_SECTOR_SIZE]
1619 PUSH ES
1620 LES DI,CS:[DOSINFO] ;ES:DI POINT TO DOS INFO
1621 CMP AX,ES:[DI.SYSI_MAXSEC]
1622 POP ES
1623 ja Bad_BPB_Size_Sector
1624 PUSH DS
1625 PUSH DX
1626 LDS DX,CS:[ENTRY_POINT]
1627 MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR],DX
1628 MOV WORD PTR ES:[BP.DPB_DRIVER_ADDR+2],DS
1629 POP DX
1630 POP DS
1631 INC DX
1632 INC DH
1633 LOOP PERUNIT
1634 PUSH CS
1635 POP DS
1636 CALL TEMPCDS ; Set CDS for new drives
1637
1638LINKIT:
1639 LES DI,CS:[DOSINFO] ;ES:DI = DOS TABLE
1640 MOV CX,WORD PTR ES:[DI.SYSI_DEV] ;DX:CX = HEAD OF LIST
1641 MOV DX,WORD PTR ES:[DI.SYSI_DEV+2]
1642
1643 LDS SI,CS:[ENTRY_POINT] ;DS:SI = DEVICE LOCATION
1644 MOV WORD PTR ES:[DI.SYSI_DEV],SI ;SET HEAD OF LIST IN DOS
1645 MOV WORD PTR ES:[DI.SYSI_DEV+2],DS
1646 MOV AX,DS:[SI] ;GET POINTER TO NEXT DEVICE
1647 MOV WORD PTR CS:[ENTRY_POINT],AX ;AND SAVE IT
1648
1649 MOV WORD PTR DS:[SI],CX ;LINK IN THE DRIVER
1650 MOV WORD PTR DS:[SI+2],DX
1651ENDDEV:
1652 POP SI
1653 POP ES
1654 INC AX ;AX = FFFF (no more devs if YES)?
1655 JZ COFFJ3
1656 inc cs:MultDeviceFlag ;AN001; Possibly multiple device driver.
1657 JMP GOODLD ;OTHERWISE PRETEND WE LOADED IT IN
1658COFFJ3: mov cs:MultDeviceFlag, 0 ;AN001; Reset the flag
1659 JMP COFF
1660
1661Bad_BPB_Size_Sector:
1662 POP SI
1663 POP ES
1664 MOV DX,OFFSET BADSIZ_PRE
1665; MOV BX,OFFSET BADSIZ_POST
1666 mov bx, offset CRLFM ;AN???;
1667 invoke PRNERR
1668 test [SetDevMarkFlag],SETBRKDONE ;AN004;If already Set_Break is done,
1669 jnz Skip2_ResetMEMHI ;AN004; then do not
1670 dec [MEMHI] ;AN004;Adjust MEMHI by a paragrah of DEVMARK.
1671Skip2_ResetMEMHI:
1672 JMP COFF
1673
1674
1675;------------------------------------------------------------------------------
1676; Country command
1677; J.K. The syntax is:
1678; COUNTRY=country id {,codepage {,path}}
1679; COUNTRY=country id {,,path} :Default CODEPAGE ID in DOS
1680;------------------------------------------------------------------------------
1681TRYQ:
1682 CMP AH,'Q'
1683 JZ TRYQ_CONT
1684 JMP TRYF
1685TRYQ_CONT:
1686
1687; invoke GETNUM
1688; JZ TryQBad ; 0 is never a valid code, or number is
1689; ; bad
1690; MOV BX,AX ; Country code in BX
1691;
1692; ;J.K. 5/26/86
1693; MOV DX,0 ; assume no code page id
1694;
1695; invoke skip_delim ;skip the delimeters after the first num
1696; jc TryQ_Def_File ;no more characters left? then use default file
1697; cmp al, CR ;
1698; je TryQ_Def_File
1699; cmp al, LF
1700; jne TRYQ_YES_EXTENDED
1701; inc [COUNT] ;This is for NEWLINE routine in COFF.
1702; dec [CHRPTR]
1703;COFFJ41:
1704; JMP TryQ_Def_File ;O.K. no code page, no path specified. Use default path.
1705;
1706;TRYQ_YES_EXTENDED:
1707; cmp al, ',' ;was the second comma?
1708; jne TryQ_GETNUM
1709; invoke skip_delim ;Yes, skip ',' and other possible delim
1710; jmp short TRYQ_PATH ;and No code page id entered.
1711;TRYQ_GETNUM:
1712; invoke GETNUM
1713; jc TryQBadCOM ;"Country=xxx,path" will not be accepted.
1714;; jc TRYQ_PATH ;Codepage is not specified. No code page.
1715;; ;At this point, AL already contain the
1716;; ;first char of the PATH.
1717; jz TryQBad ;codepage=0 entered. Error
1718; mov DX, AX ;save code page in DX
1719; invoke skip_delim ;move CHRPTR to the path string
1720; jc TryQ_Def_File ;no more char? then use default filename
1721; cmp al, CR
1722; je TryQ_Def_File
1723; cmp al, LF
1724; jne TryQ_PATH ;path entered.
1725; inc [COUNT]
1726; dec [CHRPTR]
1727;TryQ_Def_File:
1728; push dx ;save code page
1729; mov cs:CNTRY_DRV, 0 ;flag that the default path has been used!!!
1730; mov dx, offset CNTRY_ROOT ;the default path
1731; jmp TRYQ_OPEN
1732;
1733;TryQBad: ;"Invalid country code or code page"
1734; STC
1735; MOV DX,OFFSET BADCOUNTRY
1736; jmp TryQChkErr
1737;
1738;TryQBadCOM: ;Error in COUNTRY command
1739; STC
1740; MOV DX,OFFSET BADCOUNTRYCOM
1741; jmp TryQChkErr
1742;
1743;TRYQ_PATH: ;DS - sysinitseg, ES - CONFBOT,
1744; mov CX, [COUNT] ;AL - the first char of path
1745; inc CX ;BX - country id, DX - codepage id, 0 = No code page
1746; mov DI, SI
1747;TRYQ_PATH_LOOP: ;find the end of path to put 0 after that.
1748; mov AL, byte ptr ES:[DI]
1749; call delim
1750; jz TRYQ_PATH_END
1751; cmp al, 13
1752; jz TRYQ_PATH_END
1753; inc DI
1754; jmp short TRYQ_PATH_LOOP
1755;TryQBad_Brg:jmp short TryQBad
1756;TRYQ_PATH_END:
1757; mov es:byte ptr [di], 0 ;make it a ASCIIZ string. (Organize did not handle this string)
1758; push ds ;switch ds,es
1759; push es
1760; pop ds
1761; pop es
1762;
1763; mov di, offset CNTRY_DRV ;move the user specified path to CNTRY_DRV
1764; call Move_ASCIIZ
1765;
1766; push ds ;restore ds,es
1767; push es
1768; pop ds
1769; pop es
1770;
1771;; call Set_Country_Path ;set CNTRY_DRV
1772;
1773; push dx ;save DX
1774; mov dx, offset CNTRY_DRV ;Now DS:DX -> CNTRY_DRV
1775
1776 mov Cntry_Drv, 0 ;AN000; Reset the drive,path to default value.
1777 mov P_Code_Page,0 ;AN000;
1778 mov di, offset Cntry_Parms ;AN000;
1779 xor cx,cx ;AN000;
1780 mov dx,cx ;AN000;
1781; $SEARCH ;AN000;
1782$$DO49:
1783 call Sysinit_Parse ;AN000;
1784; $EXITIF C ;AN000; Parse error, check the error code and
1785 JNC $$IF49
1786 call Cntry_Error ;AN000; Show message and end the serach loop.
1787 mov P_Cntry_Code, -1 ;AN000; Signals that parse error.
1788; $ORELSE ;AN000;
1789 JMP SHORT $$SR49
1790$$IF49:
1791 cmp ax, $P_RC_EOL ;AN000; End of Line?
1792; $LEAVE E ;AN000; then end the $SEARCH LOOP
1793 JE $$EN49
1794 cmp Result_Val.$P_TYPE, $P_NUMBER ;AN000; Numeric?
1795; $IF E ;AN000;
1796 JNE $$IF53
1797 mov ax, word ptr Result_Val.$P_PICKED_VAL ;AN000;
1798 cmp cx, 1 ;AN000;
1799; $IF E ;AN000;
1800 JNE $$IF54
1801 mov P_Cntry_Code, ax ;AN000;
1802; $ELSE ;AN000;
1803 JMP SHORT $$EN54
1804$$IF54:
1805 mov P_Code_Page, ax ;AN000;
1806; $ENDIF ;AN000;
1807$$EN54:
1808; $ELSE ;AN000; Path entered.
1809 JMP SHORT $$EN53
1810$$IF53:
1811 push ds ;AN000;
1812 push es ;AN000;
1813 push si ;AN000;
1814 push di ;AN000;
1815 push cs ;AN000;
1816 pop es ;AN000;
1817 lds si, RV_Dword ;AN000; Move the path to known place.
1818 mov di, offset CNTRY_Drv ;AN000;
1819 call Move_ASCIIZ ;AN000;
1820 pop di ;AN000;
1821 pop si ;AN000;
1822 pop es ;AN000;
1823 pop ds ;AN000;
1824; $ENDIF ;AN000;
1825$$EN53:
1826; $ENDLOOP
1827 JMP SHORT $$DO49
1828$$EN49:
1829; $ENDSRCH ;AN000;
1830$$SR49:
1831 cmp P_Cntry_Code, -1 ;AN000; Had a parse error?
1832 jne TRYQ_OPEN ;AN000;
1833 jmp Coff ;AN000;
1834
1835TryQBad: ;"Invalid country code or code page"
1836 STC
1837 MOV DX,OFFSET BADCOUNTRY
1838 jmp TryQChkErr
1839
1840TRYQ_OPEN:
1841 cmp CNTRY_Drv, 0 ;AC000;
1842 je TRYQ_Def ;AC000;
1843 mov dx, offset CNTRY_Drv ;AC000;
1844 jmp TryQ_Openit ;AC000;
1845TRYQ_Def: ;AC000;
1846 mov dx, offset CNTRY_Root ;AC000;
1847TryQ_Openit:
1848 mov ax, 3d00h ;open a file
1849 stc
1850 int 21h
1851 jc TryQFileBad ;open failure
1852
1853 mov cs:CntryFileHandle, ax ;save file handle
1854 mov bx, ax
1855 mov ax, cs:P_Cntry_Code ;AN000;
1856 mov dx, cs:P_Code_Page ;AN000; Now, AX=country id, bx=filehandle
1857; xchg ax, bx ;now, AX = country id, BX = file handle
1858 mov cx, cs:[MEMHI]
1859 add cx, 128 ;I need 2K buffer to handle COUNTRY.SYS
1860 cmp cx, cs:[ALLOCLIM]
1861 ja TryQMemory ;cannot allocate the buffer for country.sys
1862
1863 mov si, offset CNTRY_DRV ;DS:SI -> CNTRY_DRV
1864 cmp byte ptr [si],0 ;default path?
1865 jne TRYQ_Set_for_DOS
1866 inc si
1867 inc si ;DS:SI -> CNTRY_ROOT
1868TRYQ_Set_for_DOS:
1869 les di, cs:SYSI_Country ;ES:DI -> country info tab in DOS
1870 push di ;save di
1871 add di, ccPath_CountrySys
1872 call MOVE_ASCIIZ ;Set the path to COUNTRY.SYS in DOS.
1873 pop di ;ES:DI -> country info tab again.
1874 mov cx, cs:[MEMHI]
1875 mov ds, cx
1876 xor si, si ;DS:SI -> 2K buffer to be used.
1877 call SetDOSCountryInfo ;now do the job!!!
1878 jnc TryQchkERR ;read error or could not find country,code page combination
1879 cmp cx, -1 ;Could not find matching country_id,code page?
1880 je TryQBad ;then "Invalid country code or code page"
1881TryQFileBad:
1882 push cs ;AN000;
1883 pop es ;AN000;
1884 cmp cs:CNTRY_DRV,0 ;Is the default file used?
1885 je TryQDefBad
1886; mov si, cs:[CONFBOT]
1887; mov es, si
1888; mov si, cs:[CHRPTR]
1889; dec si ;ES:SI -> path in CONFBOT
1890 mov si, offset CNTRY_Drv
1891 jmp short TryQBADLOAD
1892TryQDefBad: ;Default file has been used.
1893; push cs
1894; pop es
1895 mov si, offset CNTRY_ROOT ;ES:SI -> \COUNTRY.SYS in SYSINIT_SEG
1896TryQBADLOAD:
1897 call BADLOAD ;DS will be restored to SYSINIT_SEG
1898 mov cx, cs:[CONFBOT]
1899 mov es, cx ;Restore ES -> CONFBOT.
1900 jmp short CoffJ4
1901TryQMemory:
1902 MOV DX,OFFSET INSUFMEMORY
1903TryQChkErr:
1904 mov cx, cs:[CONFBOT]
1905 mov es, cx ;restore ES -> CONFBOT seg
1906 push cs
1907 pop ds ;retore DS to SYSINIT_SEG
1908 jnc CoffJ4 ;if no error, then exit
1909 invoke PRINT ;else show error message
1910 call Error_Line ;AN000;
1911CoffJ4:
1912 mov bx, CntryFileHandle
1913 mov ah, 3eh
1914 int 21h ;close a file. Don't care even if it fails.
1915 JMP COFF
1916
1917Cntry_Error proc near
1918;Function: Show "Invalid country code or code page" messages, or
1919; "Error in COUNTRY command" depending on the error code
1920; in AX returned by SYSPARSE;
1921;In: AX - error code
1922; DS - Sysinitseg
1923; ES - CONFBOT
1924;Out: Show message. DX destroyed.
1925
1926 cmp ax, $P_OUT_OF_RANGE
1927; $IF E
1928 JNE $$IF61
1929 mov dx, offset BadCountry ;"Invalid country code or code page"
1930; $ELSE
1931 JMP SHORT $$EN61
1932$$IF61:
1933 mov dx, offset BadCountryCom ;"Error in CONTRY command"
1934; $ENDIF
1935$$EN61:
1936 invoke Print
1937 call Error_Line
1938 ret
1939Cntry_Error endp
1940
1941;------------------------------------------------------------------------------
1942; Files command
1943;------------------------------------------------------------------------------
1944;*******************************************************************************
1945; Function: Parse the parameters of FILES= command. *
1946; *
1947; Input : *
1948; ES:SI -> parameters in command line. *
1949; Output: *
1950; Variable FILES set. *
1951; *
1952; Subroutines to be called: *
1953; Sysinit_Parse *
1954; Logic: *
1955; { *
1956; Set DI points to FILES_Parms; *
1957; Set DX,CX to 0; *
1958; While (End of command line) *
1959; { Sysinit_parse; *
1960; if (no error) then *
1961; Files = Result_Val.$P_Picked_Val *
1962; else *
1963; Error Exit; *
1964; }; *
1965; }; *
1966; *
1967;*******************************************************************************
1968TRYF:
1969 CMP AH,'F'
1970 JNZ TRYL
1971
1972; invoke GETNUM
1973; CMP AX,5 ;j.k. change it to 8!!!!!!!!
1974; JB TryFBad ; Gotta have at least 5
1975; CMP AX,256
1976; JAE TryFBad ; Has to be a byte
1977; MOV [FILES],AL
1978;CoffJ5: JMP COFF
1979;TryFBad:JMP BadOp
1980
1981 mov di, offset Files_Parms ;AN000;
1982 xor cx, cx ;AN000;
1983 mov dx, cx ;AN000;
1984
1985; $SEARCH ;AN000;
1986$$DO64:
1987 call Sysinit_Parse ;AN000;
1988; $EXITIF C ;AN000; Parse Error,
1989 JNC $$IF64
1990 call Badparm_p ;AN007; and Show messages and end the search loop.
1991; $ORELSE ;AN000;
1992 JMP SHORT $$SR64
1993$$IF64:
1994 cmp ax, $P_RC_EOL ;AN000; End of Line?
1995; $LEAVE E ;AN000; then end the $ENDLOOP
1996 JE $$EN64
1997 mov al, byte ptr Result_Val.$P_PICKED_VAL ;AN000;
1998 mov P_Files, al ;AN000; Save it temporarily
1999; $ENDLOOP ;AN000;
2000 JMP SHORT $$DO64
2001$$EN64:
2002 mov al, P_Files ;AN000;
2003 mov Files, al ;AN000; No error. Really set the value now.
2004; $ENDSRCH ;AN000;
2005$$SR64:
2006 jmp Coff
2007
2008;------------------------------------------------------------------------------
2009; LastDrive command
2010;------------------------------------------------------------------------------
2011;*******************************************************************************
2012; Function: Parse the parameters of LASTDRIVE= command. *
2013; *
2014; Input : *
2015; ES:SI -> parameters in command line. *
2016; Output: *
2017; Set the variable NUM_CDS. *
2018; *
2019; Subroutines to be called: *
2020; Sysinit_Parse *
2021; Logic: *
2022; { *
2023; Set DI points to LDRV_Parms; *
2024; Set DX,CX to 0; *
2025; While (End of command line) *
2026; { Sysinit_Parse; *
2027; if (no error) then *
2028; Set NUM_CDS to the returned value; *
2029; else /*Error exit*/ *
2030; Error Exit; *
2031; }; *
2032; }; *
2033; *
2034;*******************************************************************************
2035TRYL:
2036 CMP AH,'L'
2037 JNZ TRYP
2038
2039; OR AL,020h
2040; SUB AL,'a'
2041; JB TryLBad
2042; INC AL
2043; CMP AL,26 ; a-z are allowed
2044; JA TryLBad
2045; MOV [NUM_CDS],AL
2046;CoffJ6: JMP COFF
2047;TryLBad:JMP BadOp
2048
2049 mov di, offset LDRV_Parms ;AN000;
2050 xor cx, cx ;AN000;
2051 mov dx, cx ;AN000;
2052
2053; $SEARCH ;AN000;
2054$$DO70:
2055 call Sysinit_Parse ;AN000;
2056; $EXITIF C ;AN000; Parse Error,
2057 JNC $$IF70
2058 call Badparm_p ;AN007; and Show messages and end the search loop.
2059; $ORELSE ;AN000;
2060 JMP SHORT $$SR70
2061$$IF70:
2062 cmp ax, $P_RC_EOL ;AN000; End of Line?
2063; $LEAVE E ;AN000; then end the $ENDLOOP
2064 JE $$EN70
2065 mov al, RV_Byte ;AN000; Pick up the drive number
2066 mov P_Ldrv, al ;AN000; Save it temporarily
2067; $ENDLOOP ;AN000;
2068 JMP SHORT $$DO70
2069$$EN70:
2070 mov al, P_Ldrv ;AN000;
2071; sub al, 'A' ;AN000; Convert it to drive number
2072; inc al ;AN000; make it to be a number of drives.
2073 mov Num_CDS, al ;AN000; No error. Really set the value now.
2074; $ENDSRCH ;AN000;
2075$$SR70:
2076 jmp Coff
2077
2078
2079;-------------------------------------------------------------------------------
2080; Setting Drive Parameters
2081;-------------------------------------------------------------------------------
2082TRYP:
2083 CMP AH,'P'
2084 JNZ TRYK
2085 invoke PARSELINE
2086 JC TryPBad
2087 invoke SETPARMS
2088 INVOKE DIDDLEBACK
2089 jc TryPBad
2090 JMP COFF
2091TryPBad:jmp Badop
2092;-------------------------------------------------------------------------------
2093; Setting Internal Stack Parameters
2094; STACKS=M,N where
2095; M is the number of stacks (range 8 to 64, default 9)
2096; N is the stack size (range 32 to 512 bytes, default 128)
2097; J.K. 5/5/86: STACKS=0,0 implies no stack installation.
2098; Any combinations that are not within the specified limits will
2099; result in "Unrecognized command" error.
2100;-------------------------------------------------------------------------------
2101;*******************************************************************************
2102; *
2103; Function: Parse the parameters of STACKS= command. *
2104; The minimum value for "number of stacks" and "stack size" is *
2105; 8 and 32 each. In the definition of SYSPARSE value list, they *
2106; are set to 0. This is for accepting the exceptional case of *
2107; STACKS=0,0 case (,which means do not install the stack.) *
2108; So, after SYSPARSE is done, we have to check if the entered *
2109; values (STACK_COUNT, STACK_SIZE) are within the actual range, *
2110; (or if "0,0" pair has been entered.) *
2111; Input : *
2112; ES:SI -> parameters in command line. *
2113; Output: *
2114; Set the variables STACK_COUNT, STACK_SIZE. *
2115; *
2116; Subroutines to be called: *
2117; Sysinit_Parse *
2118; Logic: *
2119; { *
2120; Set DI points to STKS_Parms; *
2121; Set DX,CX to 0; *
2122; While (End of command line) *
2123; { Sysinit_Parse; *
2124; if (no error) then *
2125; { if (CX == 1) then /* first positional = stack count */ *
2126; P_Stack_Count = Result_Val.$P_Picked_Val; *
2127; if (CX == 2) then /* second positional = stack size */ *
2128; P_Stack_Size = Result_Val.$P_Picked_Val; *
2129; } *
2130; else /*Error exit*/ *
2131; Error Exit; *
2132; }; *
2133; Here check P_STACK_COUNT,P_STACK_SIZE if it meets the condition; *
2134; If O.K., then set Stack_Count, Stack_Size; *
2135; else Error_Exit; *
2136; }; *
2137;*******************************************************************************
2138TRYK:
2139 CMP AH,'K'
2140 JE Do_TryK
2141 jmp TRYS
2142
2143 IF STACKSW
2144
2145; MOV SepChr,','
2146; INVOKE GetNum ; Get number of stacks
2147; MOV SepChr,0
2148; cmp ax, 0 ;J.K. 5/5/86
2149; je TRYK_0 ;J.K. Let's accept 0.
2150; CMP AX, MinCount ; 8 <= Number of Stacks <= 64
2151; JB TryKBad
2152; CMP AX, MaxCount
2153; JA TryKBad
2154;TRYK_0:
2155; MOV [STACK_COUNT], AX
2156;
2157; Skip delimiters after the first number.
2158;
2159; invoke Skip_delim ;J.K.
2160; JC TryKBad
2161;
2162; INVOKE GetNum ; Get size of individual stack
2163; JC TryKBad ; Number bad
2164;
2165; cmp ax, 0 ;J.K. 5/5/86
2166; je TRYK_SIZE0 ;J.K. 5/5/86. Accept 0
2167;
2168; CMP AX, MinSize ; 32 <= Stack Size <= 512
2169; JB TryKBad
2170; CMP AX, MaxSize
2171; JA TryKBad
2172;TRYK_SIZE0:
2173; MOV [STACK_SIZE], AX
2174; cmp ax,0
2175; je TRYK_BOTH0
2176;TRYK_OK:
2177; mov word ptr [stack_addr], -1 ;set the flag that the user entered stacks= command.
2178; JMP COFF
2179;TRYK_BOTH0:
2180; cmp [STACK_COUNT],0 ;stack_size = 0. Stack_Count = 0 too?
2181; je TRYK_OK ;yes. accepted.
2182;TryKBad:
2183; MOV DX, OFFSET BADSTACK ;J.K. 5/26/86 "Invalid stack parameter"
2184; invoke PRINT
2185; JMP COFF
2186
2187Do_TryK:
2188 mov di, offset STKS_Parms ;AN000;
2189 xor cx, cx ;AN000;
2190 mov dx, cx ;AN000;
2191
2192; $SEARCH ;AN000;
2193$$DO76:
2194 call Sysinit_Parse ;AN000;
2195; $EXITIF C ;AN000; Parse Error,
2196 JNC $$IF76
2197 mov dx, offset BadStack ;AN000; "Invalid stack parameter"
2198 call Print ;AN000; and Show messages and end the search loop.
2199 call Error_Line ;AN006;
2200; $ORELSE ;AN000;
2201 JMP SHORT $$SR76
2202$$IF76:
2203 cmp ax, $P_RC_EOL ;AN000; End of Line?
2204; $LEAVE E ;AN000; then end the $ENDLOOP
2205 JE $$EN76
2206 mov ax, word ptr Result_Val.$P_PICKED_VAL ;AN000;
2207 cmp cx, 1 ;AN000;
2208; $IF E ;AN000;
2209 JNE $$IF80
2210 mov P_Stack_Count, ax ;AN000;
2211; $ELSE ;AN000;
2212 JMP SHORT $$EN80
2213$$IF80:
2214 mov P_Stack_Size, ax ;AN000;
2215; $ENDIF ;AN000;
2216$$EN80:
2217; $ENDLOOP ;AN000;
2218 JMP SHORT $$DO76
2219$$EN76:
2220 cmp P_Stack_Count, 0 ;AN000;
2221; $IF NE ;AN000;
2222 JE $$IF84
2223 cmp P_Stack_Count, MINCOUNT ;AN000;
2224; $IF B,OR ;AN000;
2225 JB $$LL85
2226 cmp P_Stack_Size, MINSIZE ;AN000;
2227; $IF B ;AN000;
2228 JNB $$IF85
2229$$LL85:
2230 mov P_Stack_Count, -1 ;AN000; Invalid
2231; $ENDIF ;AN000;
2232$$IF85:
2233; $ELSE ;AN000;
2234 JMP SHORT $$EN84
2235$$IF84:
2236 cmp P_Stack_Size, 0 ;AN000;
2237; $IF NE ;AN000;
2238 JE $$IF88
2239 mov P_Stack_Count, -1 ;AN000; Invalid
2240; $ENDIF ;AN000;
2241$$IF88:
2242; $ENDIF ;AN000;
2243$$EN84:
2244 cmp P_Stack_Count, -1 ;AN000; Invalid?
2245; $IF E ;AN000;
2246 JNE $$IF91
2247 mov Stack_Count, DEFAULTCOUNT ;AN000;Reset to default value.
2248 mov Stack_Size, DEFAULTSIZE ;AN000;
2249 mov word ptr STACK_ADDR, 0 ;AN000;
2250 mov dx, offset BadStack ;AN000;
2251 call Print ;AN000;
2252 call Error_Line ;AN006;
2253; $ELSE ;AN000;
2254 JMP SHORT $$EN91
2255$$IF91:
2256 mov ax, P_Stack_Count ;AN000;
2257 mov Stack_Count, ax ;AN000;
2258 mov ax, P_Stack_Size ;AN000;
2259 mov Stack_Size, ax ;AN000;
2260 mov word ptr Stack_Addr, -1 ;AN000;STACKS= been accepted.
2261; $ENDIF ;AN000;
2262$$EN91:
2263; $ENDSRCH ;AN000;
2264$$SR76:
2265 jmp Coff
2266 ENDIF
2267;------------------------------------------------------------------------------
2268; Switch command ;No longer supported.
2269;------------------------------------------------------------------------------
2270;TRYW:
2271; CMP AH,'W'
2272; JNZ TRYA
2273; JMP BadOp ; no longer implemented
2274; MOV DL,AL
2275; MOV AX,(CHAR_OPER SHL 8) OR 1 ;SET SWITCH CHARACTER
2276; MOV [COMMAND_LINE+1],DL
2277; INT 21H
2278; JMP COFF
2279;------------------------------------------------------------------------------
2280; Availdev command ;No longer supported.
2281;------------------------------------------------------------------------------
2282;TRYA:
2283; CMP AH,'A'
2284; JNZ TRYS
2285; JMP BadOp ; NO LONGER IMPLEMENTED
2286; CMP AL,'F' ;FIRST LETTER OF "FALSE"
2287; JNZ COFFJ7
2288; MOV AX,(CHAR_OPER SHL 8) OR 3 ;TURN ON "/DEV" PREFIX
2289; XOR DL,DL
2290; INT 21H
2291;COFFJ7: JMP COFF
2292
2293;------------------------------------------------------------------------------
2294; shell command
2295;------------------------------------------------------------------------------
2296TRYS:
2297 CMP AH,'S'
2298 JNZ TRYX
2299 MOV [COMMAND_LINE+1],0
2300 MOV DI,OFFSET COMMND + 1
2301 MOV [DI-1],AL
2302STORESHELL:
2303 CALL GETCHR
2304 OR AL,AL
2305 JZ GETSHPARMS
2306 CMP AL," "
2307 JB ENDSH
2308 MOV [DI],AL
2309 INC DI
2310 JMP STORESHELL
2311
2312ENDSH:
2313 MOV BYTE PTR [DI],0
2314 CALL GETCHR
2315 CMP AL,LF
2316 JNZ CONV
2317 CALL GETCHR
2318CONV: JMP CONFLP
2319
2320GETSHPARMS:
2321 MOV BYTE PTR [DI],0
2322 MOV DI,OFFSET COMMAND_LINE+1
2323PARMLOOP:
2324 CALL GETCHR
2325 CMP AL," "
2326 JB ENDSH
2327 MOV [DI],AL
2328 INC DI
2329 JMP PARMLOOP
2330
2331;------------------------------------------------------------------------------
2332; FCBS Command
2333;------------------------------------------------------------------------------
2334;*******************************************************************************
2335; Function: Parse the parameters of FCBS= command. *
2336; *
2337; Input : *
2338; ES:SI -> parameters in command line. *
2339; Output: *
2340; Set the variables FCBS, KEEP. *
2341; *
2342; Subroutines to be called: *
2343; Sysinit_Parse *
2344; Logic: *
2345; { *
2346; Set DI points to FCBS_Parms; *
2347; Set DX,CX to 0; *
2348; While (End of command line) *
2349; { SYSPARSE; *
2350; if (no error) then *
2351; { if (CX == 1) then /* first positional = FCBS */ *
2352; FCBS = Result_Val.$P_Picked_Val; *
2353; if (CX == 2) then /* second positional = KEEP */ *
2354; KEEP = Result_Val.$P_Picked_Val; *
2355; } *
2356; else /*Error exit*/ *
2357; Error Exit; *
2358; }; *
2359; }; *
2360;*******************************************************************************
2361TRYX:
2362 CMP AH,'X'
2363 JNZ TRYY
2364; invoke GETNUM
2365; JZ TryXBad ; gotta have at least one
2366; CMP AX,256
2367; JAE TryXBad ; Can't be more than 8 bits worth
2368; MOV [FCBS],AL
2369;
2370; Skip delimiters after the first number including ","
2371;
2372; invoke Skip_delim ;J.K.
2373; jc tryxbad
2374; invoke GetNum
2375; JC TryXBad ; Number bad (Zero is OK here)
2376; CMP AX,256
2377; JAE TryXBad
2378; CMP AL,FCBS
2379; JA TryXBad
2380; MOV Keep,AL
2381; JMP COFF
2382;TryXBad:JMP BadOp
2383
2384 mov di, offset FCBS_Parms ;AN000;
2385 xor cx, cx ;AN000;
2386 mov dx, cx ;AN000;
2387
2388; $SEARCH ;AN000;
2389$$DO95:
2390 call Sysinit_Parse ;AN000;
2391; $EXITIF C ;AN000; Parse Error,
2392 JNC $$IF95
2393 call Badparm_p ;AN007; and Show messages and end the search loop.
2394; $ORELSE ;AN000;
2395 JMP SHORT $$SR95
2396$$IF95:
2397 cmp ax, $P_RC_EOL ;AN000; End of Line?
2398; $LEAVE E ;AN000; then end the $ENDLOOP
2399 JE $$EN95
2400 mov al, byte ptr Result_Val.$P_PICKED_VAL ;AN000;
2401 cmp cx, 1 ;AN000; The first positional?
2402; $IF E ;AN000;
2403 JNE $$IF99
2404 mov P_Fcbs, al ;AN000;
2405; $ELSE ;AN000;
2406 JMP SHORT $$EN99
2407$$IF99:
2408 mov P_Keep, al ;AN000;
2409; $ENDIF ;AN000;
2410$$EN99:
2411; $ENDLOOP ;AN000;
2412 JMP SHORT $$DO95
2413$$EN95:
2414 mov al, P_Fcbs ;AN005;make sure P_Fcbs >= P_Keep
2415 cmp al, P_Keep ;AN005;
2416; $IF B ;AN005;
2417 JNB $$IF103
2418; call Badop_p ;AN005;
2419 call Badparm_p ;AN011;show "Bad parameter -" msg.
2420 mov P_Keep, 0 ;AN005;
2421; $ELSE ;AN005;
2422 JMP SHORT $$EN103
2423$$IF103:
2424 mov Fcbs, al ;AN000; No error. Really set the value now.
2425 mov al, P_Keep ;AN000;
2426 mov Keep, al ;AN000;
2427; $ENDIF ;AN005;
2428$$EN103:
2429; $ENDSRCH ;AN000;
2430$$SR95:
2431 jmp Coff
2432
2433;------------------------------------------------------------------------------
2434; Comment= Do nothing. Just decrese CHRPTR, and increase COUNT for correct
2435; line number
2436;------------------------------------------------------------------------------
2437TRYY: ;AN000;
2438 cmp ah, 'Y' ;AN000;
2439 jne Try0 ;AN000;
2440DoNothing:
2441 dec CHRPTR ;AN000;
2442 inc COUNT ;AN000;
2443 jmp COFF ;AN000;
2444
2445;------------------------------------------------------------------------------
2446; REM command
2447;------------------------------------------------------------------------------
2448Try0: ;AN003;do nothing with this line.
2449 cmp ah, '0' ;AN003;
2450 je DoNothing ;AN003;
2451
2452;------------------------------------------------------------------------------
2453; SWITCHES command
2454;------------------------------------------------------------------------------
2455;*******************************************************************************
2456; *
2457; Function: Parse the option switches specified. *
2458; Note - This command is intended for the future use also. When we need to *
2459; to set system data flag, use this command. *
2460; *
2461; Input : *
2462; ES:SI -> parameters in command line. *
2463; Output: *
2464; P_Swit_K set if /K option chosen. *
2465; *
2466; Subroutines to be called: *
2467; Sysinit_Parse *
2468; Logic: *
2469; { *
2470; Set DI points to Swit_Parms; /*Parse control definition*/ *
2471; Set DX,CX to 0; *
2472; While (End of command line) *
2473; { Sysinit_parse; *
2474; if (no error) then *
2475; if (Result_Val.$P_SYNONYM_ptr == Swit_K) then *
2476; P_Swit_K = 1 *
2477; endif *
2478; else {Show Error message;Error Exit} *
2479; }; *
2480; }; *
2481; *
2482;*******************************************************************************
2483
2484 cmp ah, '1' ;AN019;Switches= command entered?
2485 jne Tryz ;AN019;
2486
2487 mov di, offset Swit_Parms ;AN019;
2488 xor cx, cx ;AN019;
2489 mov dx, cx ;AN019;
2490
2491; $SEARCH ;AN019;
2492$$DO107:
2493 call Sysinit_Parse ;AN019;
2494; $EXITIF C ;AN019; Parse Error,
2495 JNC $$IF107
2496 call Badparm_p ;AN019; and Show messages and end the search loop.
2497; $ORELSE ;AN019;
2498 JMP SHORT $$SR107
2499$$IF107:
2500 cmp ax, $P_RC_EOL ;AN019; End of Line?
2501; $LEAVE E ;AN019; then jmp to $Endloop for semantic check.
2502 JE $$EN107
2503 cmp Result_Val.$P_SYNONYM_PTR, offset Swit_K ;AN019;
2504; $IF E ;AN019;
2505 JNE $$IF111
2506 mov P_Swit_K, 1 ;AN019; set the flag
2507; $ENDIF ;AN019;
2508$$IF111:
2509; $ENDLOOP ;AN019;
2510 JMP SHORT $$DO107
2511$$EN107:
2512 cmp P_Swit_K, 1 ;AN019;If /K entered,
2513 push ds ;AN019;
2514 mov ax, Code ;AN019;
2515 mov ds, ax ;AN019;
2516 assume ds:Code ;AN019;
2517; $IF E ;AN019;
2518 JNE $$IF114
2519 mov KEYRD_Func, 0 ;AN019;Use the conventional keyboard functions
2520 mov KEYSTS_Func, 1 ;AN019;
2521; $ENDIF ;AN019;
2522$$IF114:
2523 pop ds ;AN019;
2524 assume ds:SYSINITSEG ;AN019;
2525; $ENDSRCH ;AN019;
2526$$SR107:
2527 jmp Coff ;AN019;
2528
2529;------------------------------------------------------------------------------
2530; Bogus command
2531;------------------------------------------------------------------------------
2532TRYZ:
2533 cmp ah, 0FFh ;AN029;
2534 je TryFF ;AN029;
2535 dec CHRPTR
2536 inc COUNT
2537 JMP BADOP
2538
2539;------------------------------------------------------------------------------
2540; Null command
2541;------------------------------------------------------------------------------
2542TryFF: ;AN029;Skip this command.
2543 jmp DoNothing ;AN029;
2544
2545GETCHR:
2546 PUSH CX
2547 MOV CX,COUNT
2548 JCXZ NOCHAR
2549 MOV SI,CHRPTR
2550 MOV AL,ES:[SI]
2551 DEC COUNT
2552 INC CHRPTR
2553 CLC
2554GET_RET:
2555 POP CX
2556 return
2557NOCHAR: STC
2558 JMP SHORT GET_RET
2559
2560Incorrect_Order proc near ;AN000;
2561;Show "Incorrect order in CONFIG.SYS ..." message.
2562 mov dx, offset BADORDER ;AN000;
2563 call print ;AN000;
2564 call ShowLineNum ;AN000;
2565 ret ;AN000;
2566Incorrect_Order endp ;AN000;
2567;
2568 public Error_Line
2569Error_Line proc near ;AN000;
2570;Show "Error in CONFIG.SYS ..." message.
2571 push cs ;AN000;
2572 pop ds ;AN000;
2573 mov dx, offset ErrorCmd ;AN000;
2574 call print ;AN000;
2575 call ShowLineNum ;AN000;
2576 ret ;AN000;
2577Error_Line endp ;AN000;
2578;
2579ShowLineNum proc near ;AN000;
2580;J.K. Convert the binary LineCount to Decimal ASCII string in ShowCount
2581;and Display Showcount at the current curser position.
2582;In.) LineCount
2583;
2584;Out) the number is printed.
2585 push es ;AN000;
2586 push ds ;AN000;
2587 push di ;AN000;
2588
2589 push cs ;AN000;
2590 pop es ;AN000; es=cs
2591 push cs ;AN000;
2592 pop ds ;AN000;
2593
2594; mov ax, ' '
2595; mov di, offset ShowCount ;clean it up.
2596; stosw
2597; stosw
2598; stosb ;lenght of ShowCount is 5.
2599; dec di ;let DI points to the least significant ASCII field.
2600
2601 mov di, offset ShowCount+4 ;AN000; DI -> the least significant decimal field.
2602 mov cx, 10 ;AN000; decimal devide factor
2603 mov ax, cs:LineCount ;AN000;
2604SLN_Loop: ;AN000;
2605 cmp ax, 10 ;AN000; < 10?
2606 jb SLN_Last ;AN000;
2607 xor dx,dx ;AN000;
2608 div cx ;AN000;
2609 or dl, 30h ;AN000; add "0" (= 30h) to make it an ascii.
2610 mov [di],dl ;AN000;
2611 dec di ;AN000;
2612 jmp SLN_Loop ;AN000;
2613SLN_Last: ;AN000;
2614 or al, 30h ;AN000;
2615 mov [di],al ;AN000;
2616 mov dx, di ;AN000;
2617 call print ;AN000; show it.
2618 pop di ;AN000;
2619 pop ds ;AN000;
2620 pop es ;AN000;
2621 ret ;AN000;
2622ShowLineNum endp ;AN000;
2623
2624
2625CallIFS proc near ;AN000;
2626;*******************************************************************************
2627; Function: Interface to IFS call. This procedure will call IFS_CALL@ *
2628; *
2629; Input : *
2630; Entry_Point - Segment:Offset of loaded IFS. *
2631; BX = IFS_CALL@ (offset of IFS_CALL@ from the IFS header) *
2632; ES = Segment of IFS request header *
2633; IFS_Packet - IFS Request packet *
2634; *
2635; Output: Nothing *
2636;*******************************************************************************
2637 push ax ;AN000;
2638 mov ds, word ptr cs:[Entry_Point+2] ;AN000;
2639 add bx, word ptr cs:[Entry_Point] ;AN000; DS:[BX] = Real IFS_CALL@ addr.
2640 mov ax, ds:[bx] ;AN000; save it
2641 push word ptr cs:[Entry_Point] ;AN000; save Entry point offset
2642 mov word ptr cs:[Entry_Point], ax ;AN000; set for the call
2643 mov bx, offset IFS_RH ;AN000; Now, ES:BX -> Request packet
2644 call cs:[Entry_Point] ;AN000; Far call
2645 pop word ptr cs:[Entry_Point] ;AN000; Restore Entry point offset
2646 pop ax ;AN000;
2647 ret ;AN000;
2648CallIFS endp ;AN000;
2649
2650
2651Set_DevMark proc near ;AN004;
2652;*******************************************************************************
2653; Function: Set a paragraph of informations infront of a Device file or *
2654; an IFS file to be loaded for MEM command. *
2655; The structure is: *
2656; DEVMARK_ID byte "D" for device, "I" for IFS *
2657; DEVMARK_SIZE size in para for the device loaded *
2658; DEVMARK_FILENAME 11 bytes. Filename *
2659; *
2660; Input : *
2661; [MEMHI] = address to set up DEVMARK. *
2662; [MEMLO] = 0 *
2663; ES:SI -> pointer to [drive][path]filename,0 *
2664; [IFS_Flag] = IS_IFS bit set if IFS= command. *
2665; *
2666; Output: DEVMARK_ID, DEVMARK_FILENAME set *
2667; cs:[DevMark_addr] set. *
2668; AX, CX register destroyed. *
2669;*******************************************************************************
2670 push ds ;AN004;
2671 push si ;AN004;
2672 push es ;AN004;
2673 push di ;AN004;
2674
2675 mov di, cs:[MEMHI] ;AN004;
2676 mov ds, di ;AN004;
2677 assume ds:nothing ;AN004;
2678 mov [DevMark_Addr], di ;AN004; save the DEVMARK address for the future.
2679 test [IFS_Flag], IS_IFS ;AN004;
2680 jnz SDVMK_IFS ;AN004;
2681 mov al, DEVMARK_DEVICE ;AN004; ='D'
2682 jmp short SDVMK_ID ;AN004;
2683SDVMK_IFS:
2684 mov al, DEVMARK_IFS ;AN004; ='I'
2685SDVMK_ID: ;AN004;
2686 mov ds:[DEVMARK_ID], al ;AN004;
2687 inc di ;AN008;
2688 mov ds:[DEVMARK_SEG], di ;AN008;
2689 xor al,al ;AN004;
2690 push si ;AN004;
2691 pop di ;AN004; now es:si = es:di = [path]filename,0
2692 mov cx, 128 ;AN004; Maximum 128 char
2693 repnz scasb ;AN004; find 0
2694 dec di ;AN020; Now es:di-> 0
2695SDVMK_Backward: ;AN004; find the pointer to the start of the filename.
2696 mov al, byte ptr es:[di] ;AN004;;AN020;We do this by check es:di backward until
2697 cmp al, '\' ;AN004;;AN020; DI = SI or DI -> '\' or DI -> ':'.
2698 je SDVMK_GotFile ;AN004;;AN020;
2699 cmp al, ':' ;AN004;
2700 je SDVMK_GotFile ;AN004;
2701 cmp di, si ;AN004;
2702 je SDVMK_FilePtr ;AN004;
2703 dec di ;AN004;
2704 jmp SDVMK_BackWard ;AN004;
2705SDVMK_GotFile: ;AN004;
2706 inc di ;AN004;
2707SDVMK_FilePtr: ;AN004; now es:di -> start of file name
2708 push di ;AN004;
2709 pop si ;AN004; save di to si.
2710 push ds ;AN004; switch es, ds
2711 push es ;AN004;
2712 pop ds ;AN004;
2713 pop es ;AN004; now, ds:si -> start of filename
2714 mov di, DEVMARK_FILENAME ;AN004;
2715 push di ;AN004;
2716 mov al, ' ' ;AN004;
2717 mov cx, 8 ;AN004;
2718 rep stosb ;AN004; Clean up Memory.
2719 pop di ;AN004;
2720 mov cx, 8 ;AN004; Max 8 char. only
2721SDVMK_Loop: ;AN004;
2722 lodsb ;AN004;
2723 cmp al, '.' ;AN004;
2724 je SDVMK_Done ;AN004;
2725 cmp al, 0 ;AN004;
2726 je SDVMK_Done ;AN004;
2727 stosb ;AN004;
2728 loop SDVMK_Loop ;AN004;
2729SDVMK_Done: ;AN004;
2730 pop di ;AN004;
2731 pop es ;AN004;
2732 pop si ;AN004;
2733 pop ds ;AN004;
2734 ret ;AN004;
2735Set_DevMark endp ;AN004;
2736
2737Chk_XMAEM proc near ;AN029;
2738;Function: Check XMAEM.SYS file name.
2739;In: ES:SI -> path, filename, 0
2740;out: if XMAEM.SYS, then zero flag set.
2741
2742 push es ;AN029;
2743 push si ;AN029;
2744 push ds ;AN029;
2745 push di ;AN029;
2746 push cx ;AN029;
2747 mov di, si ;AN029;save current starting pointer
2748CX_Cmp: ;AN029;
2749 cmp byte ptr es:[si], 0 ;AN029;
2750 je CX_Endfile ;AN029;
2751 inc si ;AN029;
2752 jmp CX_Cmp ;AN029;
2753CX_Endfile: ;AN029;
2754 dec si ;AN029;
2755 cmp byte ptr es:[si], '\' ;AN029;
2756 je CX_Got_Tail ;AN029;
2757 cmp byte ptr es:[si], ':' ;AN029;
2758 je CX_Got_Tail ;AN029;
2759 cmp di, si ;AN029;
2760 je CX_Got_Tail0 ;AN029;
2761 jmp CX_Endfile ;AN029;
2762CX_Got_Tail: ;AN029;
2763 inc si ;AN029;
2764CX_Got_Tail0: ;AN029;
2765 push cs ;AN029;
2766 pop ds ;AN029;
2767 push si ;AN029;
2768 pop di ;AN029;now es:di -> filename,0
2769 mov cx, 9 ;AN029;
2770 mov si, offset XMAEM_File ;AN029;ds:si -> XMAEM.SYS,0
2771 repe cmpsb ;AN029;
2772CX_Ret: ;AN029;
2773 pop cx ;AN029;
2774 pop di ;AN029;
2775 pop ds ;AN029;
2776 pop si ;AN029;
2777 pop es ;AN029;
2778 ret ;AN029;
2779Chk_XMAEM endp
2780
2781;Chk_IBMCACHE proc near ;AN024;AN026; Don't need this any more.
2782 ; IBMDOS is going to handle this through 4Bh call.
2783;Function: IBMCACHE.SYS does not handle a DOS version 4.0 or above.
2784; So, this procedure will check if the device driver is IBMCACHE.SYS.
2785; If it is, through new INT 2fh interface "Set/Restore DOS version"
2786; AX=122Fh
2787; DX= 0 ; reset
2788; otherwise ; DH = minor version, DL = major version
2789; INT 2fh
2790;In: ES:SI -> path, filename, 0
2791;out: if IBMCACHE.SYS, then DOS version changed to 4.00 temporarily.
2792; Reset_Dos_Version proc will later reset it back to current DOS version 4.0.
2793
2794; push es ;AN024;
2795; push si ;AN024;
2796; push ds ;AN024;
2797; push di ;AN024;
2798; push cx ;AN024;
2799; mov di, si ;AN024;save current starting pointer
2800;CIC_Cmp: ;AN024;
2801; cmp byte ptr es:[si], 0 ;AN024;
2802; je CIC_Endfile ;AN024;
2803; inc si ;AN024;
2804; jmp CIC_Cmp ;AN024;
2805;CIC_Endfile: ;AN024;
2806; dec si ;AN024;
2807; cmp byte ptr es:[si], '\' ;AN024;
2808; je CIC_Got_Tail ;AN024;
2809; cmp byte ptr es:[si], ':' ;AN024;
2810; je CIC_Got_Tail ;AN024;
2811; cmp di, si ;AN024;
2812; je CIC_Got_Tail0 ;AN024;
2813; jmp CIC_Endfile ;AN024;
2814;CIC_Got_Tail: ;AN024;
2815; inc si ;AN024;
2816;CIC_Got_Tail0: ;AN024;
2817; push cs ;AN024;
2818; pop ds ;AN024;
2819; push si ;AN024;
2820; pop di ;AN024;now es:di -> filename,0
2821; mov cx, 12 ;AN024;
2822; mov si, offset IBMCACHE_File ;AN024;ds:si -> IBMCACHE.SYS,0
2823; repe cmpsb ;AN024;
2824; jnz CIC_ret ;AN024;
2825; mov ax, 122Fh ;AN024;Change DOS version to
2826; mov dx, 2803h ;AN024; DOS 3.4 temporarily.
2827; int 2fh ;AN024;
2828;CIC_Ret: ;AN024;
2829; pop cx ;AN024;
2830; pop di ;AN024;
2831; pop ds ;AN024;
2832; pop si ;AN024;
2833; pop es ;AN024;
2834; ret ;AN024;
2835;Chk_IBMCACHE endp
2836;
2837
2838Reset_DOS_Version proc near ;AN024;
2839;Function: issue AX=122Fh, DX=0, INT 2fh to restore the DOS version.
2840 push ax ;AN024;
2841 push dx ;AN024;
2842 mov ax, 122Fh ;AN024;
2843 mov dx, 0 ;AN024;
2844 int 2fh ;AN024;
2845 pop dx ;AN024;
2846 pop ax ;AN024;
2847 ret ;AN024;
2848Reset_DOS_Version endp
2849
2850
2851;Int 2F EMS handler + Int 67h handler for EMS
2852;=========================================================================
2853; Int_2F_EMS - This routine provides support for VDISK,
2854; FASTOPEN, and BUFFERS to determine the physical
2855; EMS pages available for their usage.
2856;
2857; Inputs : AH - Function code (18h) to return available phys. page
2858; DI - FEh (Signals to return useable page for VDISK & FASTOPEN)
2859; FFh (Signals to return useable page for BUFFERS)
2860;
2861; AL = 0 is for installation check. - J.K.
2862;
2863; Outputs : ES - Segment value for physical page
2864; DI - Physical Page number
2865; AH - Non-zero (physical page not available)
2866; Zero (valid physical page data returned)
2867;
2868; For installation check, AL = 0FFh for being present. - J.K.
2869; For the other functions, AX = 0 for successful op.
2870; AX = -1 for an error.
2871;
2872; Date : 5/5/88
2873; Release : DOS 4.0
2874;=========================================================================
2875
2876;Int_2F_Handler proc ;traps Int_2f and checks for EMS ;an000; dms;
2877
2878EMS_STUB_START label byte ;AN030;J.K.
2879;Dummy DEVICE HEADER for other dummy ;AN031; Symphony assumes int 67h handler seg as a device driver!
2880 DD -1 ;AN031;becomes pointer to next device header
2881 DW 0C040H ;AN031;attribute (character device)
2882 DW 0000 ;AN031;pointer to harzard area. System will hang.
2883 DW 0000 ;AN031;pointer to harzard area. System will hang.
2884 DB 'EMMXXXX0' ;AN031;device name
2885
2886INTV2F equ $-EMS_STUB_START ;AN030;J.K.pointer to old 2Fh handler ;an000; dms;
2887IntV2FO DW ? ;AN030;;offset ;an000; dms;
2888IntV2FS DW ? ;AN030;;segment ;an000; dms;
2889
2890OLDINT67_VECTOR equ $-EMS_STUB_START ;AN030;J.K.
2891OldInt67 dd ? ;AN030;; save pointer to old INT 67 handler here
2892
2893IF BUFFERFLAG
2894
2895LOCKFLAG equ $-EMS_STUB_START
2896LOCK_FLAG db ?
2897
2898ELSE
2899
2900EMSPAGE_CNT equ $-EMS_STUB_START ;AN030;J.K.
2901EMSPageCount dw ? ;AN030;; save count of EMS mappable pages here
2902
2903EMSReservedArray_X label word ;AN030;;J.K. For initialization routine
2904EMSRESERVEDARRAY equ $-EMS_STUB_START ;AN030;;J.K.
2905 dw 0ffffh,0ffffh ;AN030;; array of reserved pages
2906 dw 0ffffh,0ffffh ;AN030;; phys_page_segment, phys_page_number * 2 entries
2907MappableArray_X label word ;AN030;;J.K. for initialization routine
2908MAPPABLEARRAY equ $-EMS_STUB_START ;AN030;;J.K.
2909 dw 64 dup (0,0) ;AN030;; table to get addresses from old INT 67 handler
2910
2911ENDIF
2912 ; 64 entries * 2 words
2913NEWEMS2F_OFF equ $-EMS_STUB_START;AN030;
2914Int_2F_EMS: ;AN030;;J.K. Name changed.
2915 cmp ah,1Bh ;AN030;;AN032;2Fh trap for Mappable Phys. Add. Array ;an000; dms;
2916 je Int_2F_EMS_MINE ;AN030;;This one we want ;an000; dms;
2917
2918 jmp dword ptr cs:IntV2F ;AN030;;go to old interrupt handler ;an000; dms;
2919
2920Int_2F_EMS_MINE: ;AN030;
2921 or al, al ;AN030;;J.K. Installation check?
2922 jnz Int_2F_5800_Func ;AN030;;J.K.
2923 mov al, 0FFh ;AN030;;J.K. Yes, I am here!
2924 iret ;AN030;;J.K.
2925
2926Int_2F_5800_Func: ;AN030;
2927
2928IF BUFFERFLAG
2929; int 3
2930 cmp di, 80h
2931 jne st_flag
2932 mov byte ptr cs:LOCKFLAG, 0
2933 jmp Int_2f_5800_Good_Exit
2934st_flag:
2935 cmp di, 81h
2936 jne Int_2f_5800_Err_Exit
2937 mov byte ptr cs:LOCKFLAG, 1
2938 jmp Int_2f_5800_Good_Exit
2939ELSE
2940
2941 push si ;AN030;; ;an000; dms;
2942
2943; mov si,offset EMSReservedArray ;point to array containing pages ;an000; dms;
2944 mov si, EMSRESERVEDARRAY ;AN030;;J.K.
2945
2946 cmp di,0feh ;AN030;;VDISK or FASTOPEN request? ;an000; dms;
2947 jne Int_2F_5800_Buff_Ck ;AN030;;no - check for buffers ;an000; dms;
2948
2949 cmp word ptr cs:[si],0ffffh ;AN030;;valid entry? ;an000; dms;
2950 je Int_2F_5800_Err_Exit ;AN030;;no - exit ;an000; dms;
2951
2952 mov es,word ptr cs:[si] ;AN030;;get segment value ;an000; dms;
2953 mov di,word ptr cs:[si+2] ;AN030;;get physical page value ;an000; dms;
2954 jmp Int_2F_5800_Good_Exit ;AN030;;exit routine ;an000; dms;
2955
2956Int_2F_5800_Buff_Ck: ;AN030;
2957
2958 cmp di,0ffh ;AN030;;BUFFERS request? ;an000; dms;
2959 jne Int_2F_5800_Err_Exit ;AN030;;no - exit with error ;an000; dms;
2960
2961 add si,4 ;AN030;;point to second element in array ;an000; dms;
2962
2963 cmp word ptr cs:[si],0ffffh ;AN034;;valid entry? ;an000; dms;
2964 je Int_2F_5800_Err_Exit ;AN034;;no - exit ;an000; dms;
2965
2966 mov es,word ptr cs:[si] ;AN030;;get segment value ;an000; dms;
2967 mov di,word ptr cs:[si+2] ;AN030;;get physical page value ;an000; dms;
2968
2969ENDIF
2970
2971Int_2F_5800_Good_Exit: ;AN030;
2972
2973 xor ax,ax ;AN030;;signal good return ;an000; dms;
2974 jmp Int_2F_Exit ;AN030;;exit routine ;an000; dms;
2975
2976Int_2F_5800_Err_Exit: ;AN030;
2977
2978 mov ax,0ffffh ;AN030;;signal error ;an000; dms;
2979
2980Int_2F_Exit: ;AN030;
2981
2982
2983IF NOT BUFFERFLAG
2984 pop si ;AN030;;restore regs ;an000; dms;
2985ENDIF
2986 iret ;AN030;;return to caller ;an000; dms;
2987
2988
2989
2990;-------------------------------------------------------------------
2991;
2992; INT 67h Filter
2993;
2994; This routine filters INT 67's looking for AH=58h. When initialized,
2995; the original INT 67 handler is called and the mappable address array
2996; is changed to "reserve" two pages for DOS use. This new array is
2997; then returned to the calling program when INT 67 AH=58h is found.
2998;
2999; Information about the two pages "reserved" for DOS is returned
3000; via an unpublished INT 2Fh interface.
3001;
3002; 5/10/88 for DOS 4.0.
3003;-------------------------------------------------------------------
3004
3005IF NOT BUFFERFLAG
3006
3007GetMappableArray equ 58h ; INT 67 function code for Get Mappable Array
3008GetPageFrame equ 41h ; function code for getting the page frame address
3009null equ 0 ; zero value
3010I67Error8F equ 8fh ;AN031;; invalid sub-function error
3011
3012ENDIF
3013
3014;-------------------------------------------------------------------
3015NEW67_OFFSET equ $-EMS_STUB_START ;J.K.
3016Int67Filter: ;AN030;
3017
3018IF BUFFERFLAG
3019; int 3
3020 cmp byte ptr cs:LOCKFLAG, 1
3021 jne PassThru
3022 mov ah, 80h
3023 stc
3024 iret
3025ELSE
3026 cmp ah,GETMAPPABLEARRAY ;AN030;; is this the INT 67 call we are interested in?
3027 jne PassThru ;AN030;; no, pass it to old INT 67 handler
3028 ;AN030;; yes ...
3029 cmp al,0 ;AN031;; AL=0 return count and table
3030 je I67Fcn0
3031
3032 cmp al,1 ;AN031;; AL=1 return count only
3033 jne I67Error ;AN031;; otherwise, error
3034
3035
3036; return count of mappable pages
3037
3038 sti ;AN031;; turn interrupts on
3039
3040 mov cx,word ptr cs:EMSPAGE_CNT ;AN031;J.K. get number of mappable pages in fake table
3041 xor ah,ah ;AN031;; good return code
3042 iret
3043
3044; return invalid sub-function code
3045
3046I67Error:
3047 sti ;AN031;; turn interrupts on
3048 mov ah,I67Error8F ;AN031;; invalid sub-function error
3049 iret
3050
3051
3052I67Fcn0: ;AN031
3053
3054; copy the fake table to user's buffer
3055
3056 sti ;AN030;; turn interrupts on
3057
3058 push ds ;AN030; save some regs
3059 push di ;AN030;
3060 push si ;AN030;
3061
3062 mov cx,word ptr cs:EMSPAGE_CNT ;AN030;J.K. get number of mappable pages in fake table
3063 shl cx,1 ;AN030;; count * 2 = number of words to copy
3064
3065 push cs ;AN030;; point DS:SI to fake table
3066 pop ds ;AN030;
3067; lea si,MappableArray
3068 mov si, MAPPABLEARRAY ;AN030;;J.K.
3069
3070 rep movsw ;AN030;; copy CX words from DS:SI to ES:DI
3071
3072 xor ah,ah ;AN030;; good return code
3073 mov cx,word ptr cs:EMSPAGE_CNT ;AN030;; page count returned to user in CX
3074
3075
3076 pop si ;AN030;; restore some regs
3077 pop di ;AN030;
3078 pop ds ;AN030;
3079
3080 iret ;AN030;; end of INT 67 filter routine
3081
3082ENDIF
3083
3084;-------------------------------------------------------------------
3085;
3086; PassThru - send request to old INT 67 handler
3087;
3088;-------------------------------------------------------------------
3089
3090PassThru:
3091 jmp dword ptr cs:OldINT67_VECTOR ;AN030;;J.K. jump to old INT 67 handler
3092 ; (IRET will return to calling program)
3093
3094
3095EMS_STUB_END label byte ;AN030;
3096;-------------------------------------------------------------------
3097
3098IF NOT BUFFERFLAG
3099;-------------------------------------------------------------------
3100;
3101; Int67FilterInit - This routine is called to initialize the INT 67
3102; filter. It should be called as soon as possible after installation.
3103;
3104;-------------------------------------------------------------------
3105
3106Int67FilterInit: ;AN030;
3107 push es ;AN030;; save caller's ES:DI
3108 push di ;AN030;
3109
3110 push cs ;AN030;; make ES:DI point to our array
3111 pop es ;AN030;
3112 mov di,offset MappableArray_X ;AN030;
3113
3114; call dword ptr cs:OldInt67 ; get mappable array from EMS DD
3115
3116 mov ah, GetMappableArray ;AN030;
3117 xor al,al ;AN030;
3118 int 67h ;AN030;;J.K.
3119
3120
3121;------------------------
3122; scan table looking for highest phys_page_number
3123
3124 xor ax,ax ;AN030;;
3125
3126 cmp cx,0 ;AN033;; are the any pages left?
3127 je NoMoreEMSPages ;AN033;; no, don't bother looking any more
3128
3129 call GetHighestPage ;AN030;; get highest entry from table
3130
3131 mov EMSReservedArray_X+4,bx ;AN030;; phys_page_segment
3132 mov EMSReservedArray_X+6,ax ;AN030;; phys_page_number
3133
3134 cmp cx,0 ;AN033;; are the any pages left?
3135 je NoMoreEMSPages ;AN033;; no, don't bother looking any more
3136
3137 call GetHighestPage ;AN030;; get next highest entry from table
3138
3139 mov EMSReservedArray_X+0,bx ;AN030;; phys_page_segment
3140 mov EMSReservedArray_X+2,ax ;AN030;; phys_page_number
3141
3142NoMoreEMSPages: ;AN033;;
3143 mov EMSPageCount,cx ;AN030;; save new page count for INT 67 filter
3144
3145 pop di
3146 pop es
3147 ret ;AN030;; return to calling program
3148
3149
3150 page
3151;-------------------------------------------------------------------
3152;
3153; GetHighestPage - returns highest physical page number in AX
3154; and segment for it in BX. A -1 means no valid page found.
3155;
3156;-------------------------------------------------------------------
3157GetHighestPage:
3158
3159 xor ax,ax ;AN030;; zero candidate register
3160 mov bx,ax ;AN030;; zero pointer to candidate page
3161
3162 push cx ;AN030;; save count
3163 push dx ;AN030;
3164 push di ;AN030;; save pointer
3165
3166PageScanLoop: ;AN030;
3167 cmp ax,ES:[di+2] ;AN030;; get phys_page_number
3168 ja LookAtNextPage ;AN030;; this one is lower than the one we are holding
3169
3170 cmp es:[di], 0a000h ; Only reserve pages in memory above 640K..
3171 jb LookAtNextPage ; fix for ps2emm and m20emm with motherboard
3172 ; disabled. 7/25/88. HKN.
3173
3174 mov ax,ES:[di+2] ;AN030;; this one is higher, make it new candidate
3175 mov bx,di ;AN030;; pointer to new candidate page, used to zero
3176 ; it later so we don't get the same one again
3177 mov dx,cx ;AN030;; save count where we found candidate
3178
3179LookAtNextPage: ;AN030;
3180 add di,4 ;AN030;; point to next entry in mappable table
3181
3182 loop PageScanLoop ;AN030;; look at next entry
3183
3184 cmp bx,null ;AN030;; did we find any pages?
3185 jne FoundOne ;AN030;; yes, exit
3186
3187 jmp ReturnError ;AN030;
3188
3189;------------------------
3190FoundOne: ;AN030;
3191 cmp ax,3 ;AN030;; could the one we found be part of a page frame
3192 ja NotFrame ;AN030;; no, carry on
3193
3194; yes, find out if it is part of frame
3195
3196 push ax ;AN030;; save physical page number
3197 push bx ;an030;; dms; bx destroyed by call
3198 mov ah,GetPageFrame ;AN030;; function code to get page frame ...
3199; call dword ptr cs:OldInt67 ; ... from the EMS DD
3200 int 67h ;AN030;;J.K.
3201 or ah,ah ;an030;;dms; error?
3202 pop bx ;an030;;dms; restore bx
3203 pop ax ;AN030;; restore phys page number
3204 jnz NotFrame ;AN030;; no frame available, carry on
3205
3206; there is a frame, this page is part of frame, so return -1's
3207
3208ReturnError: ;AN030;
3209 mov ax,0ffffh ;AN030;; indicate failure
3210 mov bx,ax ;AN030;; ax and bx = -1
3211
3212 pop di ;AN030;; restore pointer
3213 pop dx
3214 pop cx ;AN030;; restore count
3215
3216 jmp GHPExit ;AN030;
3217
3218
3219
3220
3221;------------------------
3222; Found a page, and it is not part of a page frame, so re-pack table
3223; and return info. The entry we "reserve" for DOS must be removed
3224; from the table and the other entries moved up to repack the table.
3225; The count must be reduced by 1 to reflect this change.
3226
3227Notframe: ;AN030;
3228
3229 mov di,bx ;AN030;; make ES:DI point to highest page table entry
3230
3231 mov bx,ES:[di] ;AN030;; get segment address of page
3232
3233 mov cx,dx ;AN030;; get count from candidate page
3234
3235 push ax ;AN030;
3236PackLoop: ;AN030;
3237 mov ax, es:[di+4] ;AN030;
3238 mov es:[di+0], ax ;AN030;
3239 mov ax, es:[di+6] ;AN030;
3240 mov es:[di+2], ax ;AN030;
3241 add di, 4 ;AN030;
3242 loop PackLoop ;AN030;; do it until done
3243 pop ax ;AN030;
3244
3245 pop di ;AN030;; restore pointer
3246 pop dx ;AN030;
3247 pop cx ;AN030;; restore count
3248
3249 sub cx,1 ;AN030;; reduce count by one, one less page in table now
3250
3251GHPExit: ;AN030;
3252
3253 ret ;AN030;; return to caller
3254
3255ENDIF
3256
3257;=========================================================================
3258; EMS_Install_Check : THIS MODULE DETERMINES WHETHER OR NOT EMS IS
3259; INSTALLED FOR THIS SESSION.
3260;
3261; INPUTS : NONE
3262;
3263; OUTPUTS : ES:BX - FRAME ARRAY
3264; CY - EMS NOT AVAILABLE
3265; NC - EMS AVAILABLE
3266;
3267; Date : 5/6/88
3268;=========================================================================
3269
3270EMS_Install_Check proc near ;AN030;; check if EMS is installed ;an000; dms;
3271
3272 push ax ;AN030;; save regs ;an000; dms;
3273
3274 push ds ;AN030;; save ds ;an000; dms;
3275 xor ax,ax ;AN030;; set ax to 0 ;an000; dms;
3276 mov ds,ax ;AN030;; set ds to 0 ;an000; dms;
3277 cmp ds:word ptr[067h*4+0],0 ;AN030;; see if int 67h is there ;an000; dms;
3278 pop ds ;AN030;; restore ds ;an000; dms;
3279 je EMS_Install_Ck_Err_Exit ;AN030;; exit routine - EMS not loaded ;an000; dms;
3280
3281 mov ah,40h ;AN030;; Get Status function ;an000; dms;
3282 xor al,al ;AN030;; clear al ;an000; dms;
3283 int 67h ;AN030;; ;an000; dms;
3284 or ah,ah ;AN030;; EMS installed? ;an000; dms;
3285 jnz EMS_Install_Ck_Err_Exit ;AN030;; exit routine - EMS not loaded ;an000; dms;
3286
3287 mov ah,46h ;AN030;; Get Version number ;an000; dms;
3288 xor al,al ;AN030;; clear al ;an000; dms;
3289 int 67h ;AN030;; ;an000; dms;
3290 cmp al,40h ;AN030;; Version 4.0? ;an000; dms;
3291 jb EMS_Install_Ck_Err_Exit ;AN030;; exit routine - wrong EMS loaded ;an000; dms;
3292
3293 clc ;AN030;; signal EMS loaded ;an000; dms;
3294 jmp EMS_Install_Ck_Exit ;AN030;; exit routine ;an000; dms;
3295
3296EMS_Install_Ck_Err_Exit: ;AN030;
3297
3298 stc ;AN030;; signal EMS not loaded ;an000; dms;
3299
3300EMS_Install_Ck_Exit: ;AN030;
3301
3302 pop ax ;AN030;; restore regs ;an000; dms;
3303
3304 ret ;AN030;; return to caller ;an000; dms;
3305
3306EMS_Install_Check endp ; ;an000; dms;
3307
3308EMS_Stub_Handler proc near ;AN030;
3309;At the request of Architecture Group, this logic is implemented.
3310;Function: If (Buffer_Slash_X <> 0 and EMS_Stub_Installed == 0),
3311; then { call Chk_EMS;
3312; if EMS is there, then install EMS_Stub dynamically
3313; and initialize it.}
3314; Note: EMS_Stub consists of INT 2fh EMS handler and INT 67h handler.
3315; When EMS_Stub is installed, EMS_Stub_Installed will be set to 1.
3316
3317 push es ;AN030;
3318 push si ;AN030;
3319 push ds ;AN030;
3320 push di ;AN030;
3321 push ax ;AN030;
3322 push cx ;AN030;
3323 cmp EMS_Stub_Installed, 0 ;AN030;
3324 je EMS_Stub_X ;AN030;
3325 jmp EMS_SH_Ret ;AN030;
3326EMS_Stub_X: ;AN030;
3327 cmp Buffer_Slash_X, 0 ;AN030;
3328 je EMS_SH_Ret ;AN030;
3329 call EMS_Install_Check ;AN030;
3330 jc EMS_SH_Ret ;AN030;
3331;Install EMS_Stub. ;AN030;
3332EMS_Stub_Do:
3333 push es ;AN030;
3334 xor ax,ax ;AN030;save current Int 2fh, 67h vectors.
3335 mov es, ax ;AN030;
3336 mov ax, word ptr es:[2fh*4] ;AN030;
3337 mov IntV2FO, ax ;AN030;
3338 mov ax, word ptr es:[2fh*4+2] ;AN030;
3339 mov IntV2FS, ax ;AN030;
3340 mov ax, word ptr es:[67h*4] ;AN030;
3341 mov word ptr cs:[OldInt67], ax ;AN030;
3342 mov ax, word ptr es:[67h*4+2] ;AN030;
3343 mov word ptr cs:[OldInt67+2], ax ;AN030;
3344 pop es ;AN030;
3345
3346IF NOT BUFFERFLAG
3347;initalize tables in INT 67h handler
3348 call Int67FilterInit ;AN030;
3349 cmp ax, 0ffffh ; if the page found was part of a lim 4.0 page frame
3350 je EMS_SH_ret ; do not install stub. 7/24/88. HKN
3351ENDIF
3352 call Round ;AN030;
3353 mov ax, DEVMARK_EMS_STUB ;AN030;
3354 call SetDevMark ;AN030;
3355 mov ax, [memhi] ;AN030;
3356 mov es, ax ;AN030;
3357 assume es:nothing ;AN030;
3358 xor di, di ;AN030;
3359 push cs ;AN030;
3360 pop ds ;AN030;
3361 mov cx, offset EMS_STUB_END ;AN030;
3362 mov si, offset EMS_STUB_START ;AN030;
3363 sub cx, si ;AN030;cx = size in byte
3364 mov [memlo], cx ;AN030;
3365 rep movsb ;AN030;
3366 or [SetDevMarkFlag], FOR_DEVMARK ;AN030;set the devmark_size for MEM command.
3367 call Round ;AN030;and get the next [memhi] avaiable.
3368 mov EMS_Stub_Installed, 1 ;AN030;
3369
3370 xor ax, ax ;AN030;
3371 mov ds, ax ;AN030;
3372 cli ;AN030;
3373 mov word ptr ds:[2Fh*4],NEWEMS2F_OFF;AN030;set the new int 2fh, 67h vectors.
3374 mov word ptr ds:[2Fh*4+2], es ;AN030;
3375 mov word ptr ds:[67h*4],NEW67_OFFSET;AN030;
3376 mov word ptr ds:[67h*4+2], es ;AN030;
3377 sti ;AN030;
3378EMS_SH_Ret: ;AN030;
3379 pop cx ;AN030;
3380 pop ax ;AN030;
3381 pop di ;AN030;
3382 pop ds ;AN030;
3383 pop si ;AN030;
3384 pop es ;AN030;
3385 ret ;AN030;
3386
3387EMS_Stub_Handler endp ;AN030;
3388
3389
3390SYSINITSEG ENDS
3391 END
3392 \ No newline at end of file
diff --git a/v4.0/src/BIOS/SYSIMES.ASM b/v4.0/src/BIOS/SYSIMES.ASM
new file mode 100644
index 0000000..0640282
--- /dev/null
+++ b/v4.0/src/BIOS/SYSIMES.ASM
@@ -0,0 +1,38 @@
1 ;SCCSID = @(#)sysimes.asm 1.2 85/07/25
2%OUT ...SYSIMES
3
4;==============================================================================
5;REVISION HISTORY:
6;AN000 - New for DOS Version 4.00 - J.K.
7;AC000 - Changed for DOS Version 4.00 - J.K.
8;AN00x - PTM number for DOS Version 4.00 - J.K.
9;==============================================================================
10;AN001 D246, P976 Show "Bad command or parameters - ..." msg 9/22/87 J.K.
11;AN002 P1820 New Message SKL file 10/20/87 J.K.
12;AN003 D486 Share installation for large media 02/24/88 J.K.
13;==============================================================================
14
15iTEST = 0
16include MSequ.INC
17include MSmacro.INC
18
19SYSINITSEG SEGMENT PUBLIC BYTE 'SYSTEM_INIT'
20
21 PUBLIC BADOPM,CRLFM,BADSIZ_PRE,BADLD_PRE,BADCOM,SYSSIZE,BADCOUNTRY
22; PUBLIC BADLD_POST,BADSIZ_POST,BADMEM,BADBLOCK,BADSTACK
23 PUBLIC BADMEM,BADBLOCK,BADSTACK
24 PUBLIC INSUFMEMORY,BADCOUNTRYCOM
25 public BadOrder,Errorcmd ;AN000;
26 public BadParm ;AN001;
27 public SHAREWARNMSG ;AN003;
28
29
30;include sysimes.inc
31include MSbio.cl3 ;AN002;
32
33SYSSIZE LABEL BYTE
34
35PATHEND 001,SYSMES
36
37SYSINITSEG ENDS
38 END
diff --git a/v4.0/src/BIOS/SYSINIT1.ASM b/v4.0/src/BIOS/SYSINIT1.ASM
new file mode 100644
index 0000000..7869b76
--- /dev/null
+++ b/v4.0/src/BIOS/SYSINIT1.ASM
@@ -0,0 +1,2668 @@
1 PAGE ,132 ;
2; SCCSID = @(#)sysinit1.asm 1.7 85/10/24
3TITLE BIOS SYSTEM INITIALIZATION
4%OUT ...SYSINIT1
5;==============================================================================
6;REVISION HISTORY:
7;AN000 - New for DOS Version 4.00 - J.K.
8;AC000 - Changed for DOS Version 4.00 - J.K.
9;AN00x - PTM number for DOS Version 4.00 - J.K.
10;==============================================================================
11;AN001; p40 Boot from the system with no floppy diskette drives 6/26/87 J.K.
12;AN002; d24 MultiTrack= command added. 6/29/87 J.K.
13;AN003; d9 Double word mov for 386 machine 7/15/87 J.K.
14;AN004; p447 BUFFERS = 50 /E without EMS installed hangs 8/25/87 J.K.
15;AN005; d184 Set DEVMARK for MEM command 8/25/87 J.K.
16;AN006; p851 Installable files not recognized corretly. 9/08/87 J.K.
17;AN007; p1299 Set the second entry of DEVMARK for MEM command 9/25/87 J.K.
18;AN008; p1361 New Extended Attribute 9/28/87 J.K.
19;AN009; p1326 Buffers = 50 /e hangs 9/28/87 J.K.
20;AN010; New EMS Interface
21;AN011; New Message SKL file 10/20/87 J.K.
22;AN012; P2211 Setting EA=7 for ANSI.SYS hangs the system 11/02/87 J.K.
23;AN013; p2343 Set the name for SYSINIT_BASE for MEM command 11/11/87 J.K.
24;AN014; D358 New device driver INIT function package 12/03/87 J.K.
25;AN015; For Installed module with no parameter 12/11/87 J.K.
26;AN016; D285 Undo the Extended Attribute handling 12/17/87 J.K.
27;AN017; P2806 Show "Error in CONFIG.SYS ..." for INSTALL= command 12/17/87 J.K.
28;AN018; P2914 Add Extended Memory Size in SYSVAR 01/05/88 J.K.
29;AN019; P3111 Take out the order dependency of the INSTALL= 01/25/88 J.K.
30;AN020; P3497 Performace fix for new buffer scheme 02/15/88 J.K.
31;AN021; D486 SHARE installation for big media 02/23/88 J.K.
32;AN022; D493 Undo D358 & do not show error message for device driv02/24/88 J.K.
33;AN023; D474 Change BUFFERS= /E option to /X for expanded memory 03/16/88 J.K.
34;AN024; D506 Take out the order dependency of the IFS= 03/28/88 J.K.
35;AN025; P4086 Memory allocation error when loading SHARE.EXE 03/31/88 J.K.
36;AN026; D517 New Balanced Real memory buffer set up scheme 04/18/88 J.K.
37;AN027; D528 Install XMAEM.SYS first before everything else 04/29/88 J.K.
38;AN028; P4669 SHARE /NC causes an error 05/03/88 J.K.
39;AN029; P4759 Install EMS INT2fh, INT 67h handler 05/12/88 J.K.
40;AN030; P4934 P4759 INT 2Fh handler number be changed to 1Bh 05/20/88 J.K.
41;==============================================================================
42
43TRUE EQU 0FFFFh
44FALSE EQU 0
45CR equ 13
46LF equ 10
47TAB equ 9
48
49IBMVER EQU TRUE
50IBM EQU IBMVER
51STACKSW EQU TRUE ;Include Switchable Hardware Stacks
52IBMJAPVER EQU FALSE ;If TRUE set KANJI true also
53MSVER EQU FALSE
54ALTVECT EQU FALSE ;Switch to build ALTVECT version
55KANJI EQU FALSE
56MYCDS_SIZE equ 88 ;J.K. Size of Curdir_List. If it is not
57 ;the same, then will generate compile error.
58
59;
60 IF IBMJAPVER
61NOEXEC EQU TRUE
62 ELSE
63NOEXEC EQU FALSE
64 ENDIF
65
66DOSSIZE EQU 0A000H
67;dossize equ 0C000H ;J.K. for the debugging version of IBMDOS.
68
69.xlist
70; INCLUDE dossym.INC
71 include smdossym.inc ;J.K. Reduced version of DOSSYM.INC
72 INCLUDE devsym.INC
73 include ioctl.INC
74 include BIOSTRUC.INC
75 include smifssym.inc ;AN000;
76 include defems.inc ;AN010;
77 include DEVMARK.inc ;AN005;
78 include cputype.inc
79
80 include version.inc
81
82.list
83
84;AN000 J.K. If MYCDS_SIZE <> CURDIRLEN, then force a compilatiaon error.
85 if MYCDS_SIZE NE CURDIRLEN
86 %OUT  !!! SYSINIT1 COMPILATION FAILED. DIFFERENT CDS SIZE !!!
87 .ERRE MYCDS_SIZE EQ CURDIRLEN
88 endif
89
90 IF NOT IBMJAPVER
91 EXTRN RE_INIT:FAR
92 ENDIF
93
94;---------------------------------------
95;Equates for Main stack and stack Initialization program
96 IF STACKSW
97
98EntrySize equ 8
99
100MinCount equ 8
101DefaultCount equ 9
102MaxCount equ 64
103
104MinSize equ 32
105DefaultSize equ 128
106MaxSize equ 512
107
108AllocByte equ es:byte ptr [bp+0]
109IntLevel equ es:byte ptr [bp+1]
110SavedSP equ es:word ptr [bp+2]
111SavedSS equ es:word ptr [bp+4]
112NewSP equ es:word ptr [bp+6]
113Free equ 0
114allocated equ 1
115overflowed equ 2
116clobbered equ 3
117
118
119;External variables in IBMBIO for INT19h handling rouitne. J.K. 10/23/86
120CODE segment public 'code'
121 EXTRN Int19sem:byte
122
123 IRP AA,<02,08,09,0A,0B,0C,0D,0E,70,72,73,74,76,77>
124 EXTRN Int19OLD&AA:dword
125 ENDM
126CODE ends
127 ENDIF
128;---------------------------------------
129;J.K. 6/29/87 External variable defined in IBMBIO module for Multi-track
130MULTRK_ON EQU 10000000B ;User spcified Mutitrack=on, or System turns
131 ; it on after handling CONFIG.SYS file as a
132 ; default value, if MulTrk_flag = MULTRK_OFF1.
133MULTRK_OFF1 EQU 00000000B ;initial value. No "Multitrack=" command entered.
134MULTRK_OFF2 EQU 00000001B ;User specified Multitrack=off.
135
136CODE segment public 'code'
137 EXTRN MulTrk_flag:word ;AN002;
138CODE ends
139;J.K. 6/29/87 End of Multi-track definition.
140
141SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT'
142
143ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
144
145 EXTRN BADCOM:BYTE
146 EXTRN SYSSIZE:BYTE
147 EXTRN CONDEV:BYTE,AUXDEV:BYTE,PRNDEV:BYTE,COMMND:BYTE
148 extrn DeviceParameters:byte
149 extrn DevMark_Addr:word
150 extrn SetDevMarkFlag:byte
151 extrn PathString:byte ;AN021;
152 extrn LShare:byte ;AN021;
153 extrn ShareWarnMsg:byte ;AN021;
154
155 EXTRN INT24:NEAR,MEM_ERR:NEAR
156 EXTRN DOCONF:NEAR
157 extrn Multi_Pass:NEAR ;AN024;
158 extrn BadLoad:near
159 extrn Error_Line:near
160
161 PUBLIC CURRENT_DOS_LOCATION
162 PUBLIC FINAL_DOS_LOCATION
163 PUBLIC DEVICE_LIST
164 PUBLIC SYSI_COUNTRY
165 PUBLIC MEMORY_SIZE
166 PUBLIC DEFAULT_DRIVE
167 PUBLIC BUFFERS
168 PUBLIC FILES
169 PUBLIC NUM_CDS
170 PUBLIC SYSINIT
171 PUBLIC CNTRYFILEHANDLE
172 PUBLIC COMMAND_LINE
173 public Big_Media_Flag ;AN021;Set by IBMINIT
174
175 IF STACKSW
176 ;Internal Stack Information
177 PUBLIC STACK_COUNT
178 PUBLIC STACK_SIZE
179 PUBLIC STACK_ADDR
180 ENDIF
181
182 PUBLIC dosinfo,entry_point
183 PUBLIC fcbs,keep
184 PUBLIC confbot,alloclim
185 PUBLIC zero,sepchr,STALL
186 PUBLIC count,chrptr,org_count
187 PUBLIC bufptr,memlo,prmblk,memhi
188 PUBLIC ldoff,area,PACKET,UNITCOUNT
189 PUBLIC BREAK_ADDR,BPB_ADDR,drivenumber
190 public Config_Size
191 public Install_Flag
192 public COM_Level
193 public CMMT
194 public CMMT1
195 public CMMT2
196 public Cmd_Indicator
197 public LineCount
198 public ShowCount
199 public Buffer_LineNum
200 public DoNotShowNum
201 public IFS_Flag
202 public IFS_RH
203 public H_Buffers
204 public Buffer_Slash_X ;AN023;
205 public ConfigMsgFlag ;AN014;
206 public Do_Install_Exec ;AN019;
207 public Multi_Pass_Id ;AN024;
208
209
210;
211SYSINIT$:
212 IF STACKSW
213.SALL
214 include MSSTACK.INC ;Main stack program and data definitions
215; include STKMES.INC ;Fatal stack error message
216 include MSBIO.CL5 ;Fatal stack error message
217.XALL
218 public Endstackcode
219Endstackcode label byte
220 ENDIF
221
222;
223SYSINIT:
224 JMP GOINIT
225DOSINFO LABEL DWORD
226 DW 0000
227CURRENT_DOS_LOCATION DW 0000
228
229MSDOS LABEL DWORD
230ENTRY_POINT LABEL DWORD
231 DW 0000
232FINAL_DOS_LOCATION DW 0000
233DEVICE_LIST DD 00000000
234
235SYSI_Country LABEL DWORD ;J.K. 5/29/86 Pointer to
236 DW 0000 ;country table in DOS
237 DW 0000
238
239Fake_Floppy_Drv db 0 ;AN001;Set to 1 if this machine
240 ;does not have any floppies!!!
241Big_Media_Flag db 0 ;AN021;Set by IBMINIT if > 32 MB fixed media exist.
242;
243;Variables for Stack Initialization Program.
244 IF STACKSW
245STACK_COUNT DW DefaultCount
246STACK_SIZE DW DefaultSize
247STACK_ADDR DD 00000000
248 ENDIF
249; various default values
250
251MEMORY_SIZE DW 0001
252DEFAULT_DRIVE DB 00 ;initialized by IBMINIT.
253BUFFERS DW -1 ; initialized during buffer allocation
254H_Buffers dw 0 ;AN000; # of the Heuristic buffers. Initially 0.
255Buffer_Pages dw 0 ;AN000; # of extended memory pages for the buffer.
256BufferBuckets dw 0 ;AN000;
257Buffer_odds dw 0 ;AN000;
258SingleBufferSize dw ? ;AN000; Maximum sector size + buffer header
259MaxNumBuf1 db 15 ;AN026;Num of buffers in a bucket group 1.
260MaxNumBuf2 db 15 ;AN026;Num of buffers in a possible bucket group 2.
261NthBuck db 0 ;AN026; 1st bucket group = 1st bucket through Nth Bucket. The rest = second group
262
263IF BUFFERFLAG
264
265FIRST_PAGE DW 0, 0
266LAST_PAGE DW 0, 0
267NPA640 DW 0
268EMS_SAVE_BUF DB 0,0,0,0,0,0,0,0,0,0,0,0
269
270ENDIF
271
272FILES DB 8 ; enough files for pipe
273FCBS DB 4 ; performance for recycling
274Keep DB 0 ; keep original set
275NUM_CDS DB 5 ; 5 net drives
276CONFBOT DW ?
277ALLOCLIM DW ?
278FOOSTRNG DB "A:\",0
279COMMAND_LINE DB 2,0,"P" ;Default Command.com Args
280 DB 29 DUP (0)
281ZERO DB 0
282SepChr DB 0
283LineCount dw 0 ;AN000; Line count in config.sys
284ShowCount db ' ',CR,LF,'$' ;AN000; Used to convert Linecount to ASCII.
285Buffer_LineNum dw 0 ;AN000; Line count for "BUFFERS=" command if entered.
286
287Sys_Model_Byte db 0FFh ;model byte used in SYSINIT
288Sys_Scnd_Model_Byte db 0 ;secondary model byte used in SYSINIT
289;
290Buffer_Slash_X db 0 ;AN000;AN023; BUFFERS= ... /X option entered.
291Real_IBM_Page_Id dw 0 ;AN029;
292IBM_Frame_Seg dw 0 ;AN000; segment value for physical IBM page frame.
293Frame_Info_Buffer dw (MAX_NUM_PAGEFRAME * 4) dup (0) ;AN010; For EMS. as per spec. 2 words per entry
294EMSHandleName db 'BUFFERS ' ;AN010; 8 char. EMS handle name
295EMS_Ctrl_Tab dd 0 ;AN010;
296EMS_State_Buf dd 0 ;AN010;
297BUF_PREV_OFF dw 0 ;AN020;
298EMS_Buf_First dw 0 ;AN020;
299
300 IF NOT NOEXEC
301COMEXE EXEC0 <0,COMMAND_LINE,DEFAULT_DRIVE,ZERO>
302 ENDIF
303
304;------------------------------------------------------------------
305;J.K. 2/23/87 ;variables for INSTALL= command.
306
307Multi_Pass_Id db 0 ;AN024;AN027;
308Install_Flag dw 0 ;AN000;
309 HAVE_INSTALL_CMD equ 00000001b ;AN019; CONFIG.SYS has INSTALL= commands
310 HAS_INSTALLED equ 00000010b ;AN019; SYSINIT_BASE installed.
311 SHARE_INSTALL equ 00000100b ;AN021; Used to install SHARE.EXE
312
313Config_Size dw 0 ;AN000; size of config.sys file. Set by SYSCONF.ASM
314Sysinit_Base_Ptr dd 0 ;AN000; pointer to SYSINIT_BASE
315Sysinit_Ptr dd 0 ;AN000; returning addr. from SYSINIT_BASE
316CheckSum dw 0 ;AN000; Used by Sum_up
317
318Ldexec_FCB db 20 dup (' ') ;AN000;big enough
319Ldexec_Line db 0 ;AN000;# of parm characters
320Ldexec_start db ' ' ;AN000;
321Ldexec_parm db 80 dup (0) ;AN000;
322
323INSTEXE EXEC0 <0,Ldexec_Line,Ldexec_FCB,Ldexec_FCB> ;AN000;
324
325;AN016; Undo the extended attribute handling
326;EA_QueryList label byte
327; dw 1 ;AN008; I need just one EA info.
328; db 02h ;AN008; Type is BINARY
329; dw 8000h ;AN008; Flag is SYSTEM DEFINED.
330; db 8 ;AN008; Length of name is 8 bytes
331; db 'FILETYPE' ;AN008; Name is FILETYPE
332;Ext_Attr_List dw 1 ;AN008; Just 1 Extended attribute List
333; db 2 ;AN008;EA_TYPE
334; dw 8000h ;AN008;FLAG
335; db 0 ;AN008;Failure reason
336; db 8 ;AN008;Length of NAME
337; dw 1 ;AN008;Length of VALUE
338; db 'FILETYPE' ;AN008;Name
339;Ext_Attr_Value db 0 ;AN008;Value
340;SIZE_EXT_ATTR_LIST equ $-Ext_Attr_List ;AN008;
341;
342;;Extended attribute value
343;EA_INSTALLABLE equ 4 ;AN008;Value for Installable file
344
345;------------------------------------------------------------------
346;J.K. 5/15/87 ;Request header, variables for IFS= command.
347
348IFS_Flag dw 0 ;AN000; Set to 1 if it is an IFS.
349 IS_IFS equ 00000001b ;IFS command?
350 NOT_IFS equ 11111110b
351
352IFS_RH IFSRH <LENGTH_INIT, IFSINIT,,,,> ;AN000; IFS initialization request packet
353
354;------------------------------------------------------------------
355;Variables for Comment=
356COM_Level db 0 ;AN000;level of " " in command line
357CMMT db 0 ;AN000;length of COMMENT string token
358CMMT1 db 0 ;AN000;token
359CMMT2 db 0 ;AN000;token
360Cmd_Indicator db ? ;AN000;
361DoNotShowNum db 0 ;AN000;
362
363;------------------------------------------------------------------
364COUNT DW 0000
365Org_Count dw 0000 ;AN019;
366CHRPTR DW 0000
367CntryFilehandle DW 0000
368Old_Area dw 0 ;AN013;
369Impossible_Owner_Size dw 0 ;AN013; Paragraph
370;------------------------------------------------------------------
371BucketPTR LABEL dword ;AN000;
372BUFPTR LABEL DWORD ;LEAVE THIS STUFF IN ORDER!
373MEMLO DW 0
374PRMBLK LABEL WORD
375MEMHI DW 0
376LDOFF DW 0
377AREA DW 0
378
379PACKET DB 24 ;AN014; Was 22
380 DB 0
381 DB 0 ;INITIALIZE CODE
382 DW 0
383 DB 8 DUP (?)
384UNITCOUNT DB 0
385BREAK_ADDR DD 0
386BPB_ADDR DD 0
387DriveNumber DB 0
388ConfigMsgFlag dw 0 ;AN014;AN022; Used to control "Error in CONFIG.SYS line #" message
389
390TempStack DB 80h DUP (?)
391
392GOINIT:
393;J.K. before doing anything else, let's set the model byte
394;SB33043*****************************************************************
395 mov ah,0c0h ;get system configuration ;SB ;3.30*
396 int 15h ; * ;SB ;3.30*
397;SB33043*****************************************************************
398 jc No_ROM_Config
399 cmp ah, 0 ; double check
400 jne No_ROM_Config
401 mov al, ES:[BX.bios_SD_modelbyte]
402 mov cs:[Sys_Model_Byte], al
403 mov al, ES:[BX.bios_SD_scnd_modelbyte]
404 mov cs:[Sys_Scnd_Model_Byte], al
405 jmp short Move_Myself
406No_ROM_Config: ; Old ROM
407 mov ax, 0f000h
408 mov ds, ax
409 mov al, byte ptr ds:[0fffeh]
410 mov cs:[Sys_Model_Byte], al ;set the model byte.
411;J.K.6/24/87 Set Fake_Floppy_Drv if there is no diskette drives in this machine.
412;SB34SYSINIT1001********************************************************
413;SB execute the equipment determination interrupt and then
414;SB check the returned value to see if we have any floppy drives
415;SB if we have no floppy drive we set cs:Fake_Floppy_Drv to 1
416;SB See the AT Tech Ref BIOS listings for help on the equipment
417;SB flag interrupt (11h)
418
419 int 11h
420 test ax,1 ; has floppy ?
421 jnz Move_Myself
422 mov cs:Fake_Floppy_Drv,1 ; no floppy, fake.
423
424;SB34SYSINIT1001********************************************************
425Move_Myself:
426 CLD ; Set up move
427 XOR SI,SI
428 MOV DI,SI
429
430 IF MSVER
431 MOV CX,cs:[MEMORY_SIZE]
432 CMP CX,1 ; 1 means do scan
433 JNZ NOSCAN
434 MOV CX,2048 ;START SCANNING AT 32K BOUNDARY
435 XOR BX,BX
436
437MEMSCAN:INC CX
438 JZ SETEND
439 MOV DS,CX
440 MOV AL,[BX]
441 NOT AL
442 MOV [BX],AL
443 CMP AL,[BX]
444 NOT AL
445 MOV [BX],AL
446 JZ MEMSCAN
447SETEND:
448 MOV cs:[MEMORY_SIZE],CX
449 ENDIF
450
451 IF IBMVER OR IBMJAPVER
452 MOV CX,cs:[MEMORY_SIZE]
453 ENDIF
454
455NOSCAN: ; CX is mem size in para
456 MOV AX,CS
457 MOV DS,AX
458ASSUME DS:SYSINITSEG
459
460 MOV AX,OFFSET SYSSIZE
461 Call ParaRound
462 SUB CX,AX ;Compute new sysinit location
463 MOV ES,CX
464 MOV CX,OFFSET SYSSIZE + 1
465 SHR CX,1 ;Divide by 2 to get words
466 REP MOVSW ;RELOCATE SYSINIT
467
468 ASSUME ES:SYSINITSEG
469
470 PUSH ES
471 MOV AX,OFFSET SYSIN
472 PUSH AX
473
474AAA_DUMMY PROC FAR
475 RET
476AAA_DUMMY ENDP
477;
478; MOVE THE DOS TO ITS PROPER LOCATION
479;
480SYSIN:
481
482 ASSUME DS:NOTHING,ES:SYSINITSEG,SS:NOTHING
483
484 MOV AX,[CURRENT_DOS_LOCATION] ; Where it is (set by BIOS)
485 MOV DS,AX
486 MOV AX,[FINAL_DOS_LOCATION] ; Where it is going (set by BIOS)
487 MOV ES,AX
488
489 ASSUME ES:NOTHING
490
491 XOR SI,SI
492 MOV DI,SI
493
494 MOV CX,DOSSIZE/2
495 REP MOVSW
496
497 LDS SI,[DEVICE_LIST] ; Set for call to DOSINIT
498 MOV DX,[MEMORY_SIZE] ; Set for call to DOSINIT
499
500 CLI
501 MOV AX,CS
502 MOV SS,AX
503 MOV SP,OFFSET LOCSTACK ; Set stack
504
505 ASSUME SS:SYSINITSEG
506
507 IF NOT ALTVECT
508 STI ; Leave INTs disabled for ALTVECT
509 ENDIF
510LOCSTACK LABEL BYTE
511
512 CALL MSDOS ; Call DOSINIT
513 ;ES:DI -> SysInitVars_Ext
514 mov ax, word ptr es:[di.SYSI_InitVars] ;J.K. 5/29/86
515 mov word ptr [dosinfo], ax
516 mov ax, word ptr es:[di.SYSI_InitVars+2]
517 mov word ptr [dosinfo+2],ax ;set the sysvar pointer
518
519 mov ax, word ptr es:[di.SYSI_Country_Tab]
520 mov word ptr [SYSI_Country],ax
521 mov ax, word ptr es:[di.SYSI_Country_Tab+2]
522 mov word ptr [SYSI_Country+2],ax ;set the SYSI_Country pointer J.K.
523
524 les di, dosinfo ;es:di -> dosinfo
525
526 clc ;AN018;Get the extended memory size
527;SB34SYSINIT1002**************************************************************
528;SB execute the get extended memory size subfunction in the BIOS INT 15h
529;SB if the function reports an error do nothing else store the extended
530;SB memory size reported at the appropriate location in the dosinfo buffer
531;SB currently pointed to by es:di. Use the offsets specified in the
532;SB definition of the sysinitvars struct in inc\sysvar.inc
533;SB 5 LOCS
534
535 mov ah,88h
536 int 15h ;check extended memory size
537 jc No_Ext_Memory
538 mov es:[di].SYSI_EXT_MEM,ax ;save extended memory size
539No_Ext_Memory:
540
541;SB34SYSINIT1002**************************************************************
542 mov word ptr es:[di.SYSI_IFS], -1 ;AN000; Initialize SYSI_IFS chain.
543 mov word ptr es:[di.SYSI_IFS+2], -1 ;AN000;
544
545 mov ax, es:[di.SYSI_MAXSEC] ;AN020; Get the sector size
546 add ax, BUFINSIZ ;AN020; size of buffer header
547 mov [SingleBufferSize], ax ;AN020; total size for a buffer
548
549 mov al, Default_Drive ;AN000;Get the 1 based boot drive number set by IBMINIT
550 mov es:[di.SYSI_BOOT_DRIVE], al ;AN000; set SYSI_BOOT_DRIVE
551
552; Determine if 386 system...
553 Get_CPU_Type ; macro to determine cpu type
554 cmp ax, 2 ; is it a 386?
555 jne Not_386_System ; no: don't mess with flag
556 mov es:[di.SYSI_DWMOVE], 1 ;AN003;
557Not_386_System: ;AN003;
558 MOV AL,ES:[DI.SYSI_NUMIO]
559 MOV DriveNumber,AL ; Save start of installable block drvs
560
561 MOV AX,CS
562 SUB AX,11H ; room for header we will copy shortly
563 mov cx, [SingleBufferSize] ;AN020;Temporary Single buffer area
564 shr cx, 1 ;AN020;
565 shr cx, 1 ;AN020;
566 shr cx, 1 ;AN020;
567 shr cx, 1 ;AN020; Paragraphs
568 inc cx ;AN020;
569 sub ax, cx ;AN020;
570 MOV [CONFBOT],AX ; Temp "unsafe" location
571
572 push es ;AN020;
573 push di ;AN020;
574 les di, es:[di.SYSI_BUF] ;AN020;get the buffer hash entry pointer
575 les di, es:[di.HASH_PTR] ;AN020;
576 mov word ptr es:[di.BUFFER_BUCKET],0 ;AN020;
577 mov word ptr es:[di.BUFFER_BUCKET+2], ax ;AN020;
578 mov es, ax ;AN020;
579 xor ax, ax ;AN020;
580 mov di, ax ;AN020;es:di -> Single buffer
581 mov es:[di.BUF_NEXT], ax ;AN020;points to itself
582 mov es:[di.BUF_PREV], ax ;AN020;points to itself
583 mov word ptr es:[di.BUF_ID],00FFh ;AN020;free buffer, clear flag
584 mov word ptr es:[di.BUF_SECTOR], 0 ;AN020;
585 mov word ptr es:[di.BUF_SECTOR+2], 0 ;AN020;
586 pop di ;AN020;
587 pop es ;AN020;
588
589 PUSH DS ; Save as input to RE_INIT
590 PUSH CS
591 POP DS
592ASSUME DS:SYSINITSEG
593 CALL TEMPCDS ; Set up CDSs so RE_INIT and SYSINIT
594 ; can make DISK system calls
595
596 POP DS ; Recover DS input to RE_INIT
597ASSUME DS:NOTHING
598
599 IF NOT IBMJAPVER
600 CALL RE_INIT ; Re-call the BIOS
601 ENDIF
602
603 STI ; INTs OK
604 CLD ; MAKE SURE
605; DOSINIT has set up a default "process" (PHP) at DS:0. We will move it out
606; of the way by putting it just below SYSINIT at end of memory.
607 MOV BX,CS
608 SUB BX,10H
609 MOV ES,BX
610 XOR SI,SI
611 MOV DI,SI
612 MOV CX,80H
613 REP MOVSW
614 MOV WORD PTR ES:[PDB_JFN_Pointer + 2],ES ; Relocate
615 MOV AH,SET_CURRENT_PDB
616 INT 21H ; Tell DOS we moved it
617 PUSH DS
618 PUSH CS
619 POP DS
620ASSUME DS:SYSINITSEG
621 MOV DX,OFFSET INT24 ;SET UP INT 24 HANDLER
622 MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
623 INT 21H
624
625 MOV BX,0FFFFH
626 MOV AH,ALLOC
627 INT 21H ;FIRST TIME FAILS
628 MOV AH,ALLOC
629 INT 21H ;SECOND TIME GETS IT
630 MOV [AREA],AX
631 MOV [MEMHI],AX ; MEMHI:MEMLO now points to
632 ; start of free memory
633 IF ALTVECT
634 MOV DX,OFFSET BOOTMES
635 invoke PRINT ;Print message DOSINIT couldn't
636 ENDIF
637
638 POP DS
639ASSUME DS:NOTHING
640
641 MOV DL,[DEFAULT_DRIVE]
642 OR DL,DL
643 JZ NODRVSET ; BIOS didn't say
644 DEC DL ;A = 0
645 MOV AH,SET_DEFAULT_DRIVE
646 INT 21H ;SELECT THE DISK
647;J.K. 2/23/87 Modified to handle INSTALL= command.
648NODRVSET:
649 CALL DOCONF ;DO THE CONFIG STUFF
650 inc cs:Multi_Pass_Id ;AN027;
651 call Multi_Pass ;AN027;
652 inc cs:Multi_Pass_Id ;AN024;
653 call Multi_Pass ;AN024;
654 call EndFile
655 test Install_Flag, HAVE_INSTALL_CMD ;AN019;
656 jz DoLast ;AN019;
657 inc cs:Multi_Pass_Id ;AN024;
658 call Multi_Pass ;AN019;AN024; Execute INSTALL= commands
659
660;J.K. [AREA] has the segment address for the allocated memory of SYSINIT,CONFBOT.
661;Free the CONFBOT area used for CONFIG.SYS and SYSINIT itself.
662DoLast:
663 call LoadShare ;AN021; Try to load share.exe, if needed.
664 mov cs:[DoNotShowNum], 1 ;AN000; Done with CONFIG.SYS. Do not show line number message.
665 mov cx, [area] ;AN000;
666 mov es, cx ;AN000;
667 mov ah, 49h ;AN000; Free allocated memory for command.com
668 int 21h ;AN000;
669
670 test cs:[Install_flag], HAS_INSTALLED ;AN013; SYSINIT_BASE installed?
671 jz Skip_Free_SYSINITBASE ;AN013; No.
672;Set Block from the Old_Area with Impossible_Owner_size.
673;This will free the unnecessary SYSINIT_BASE that had been put in memory to
674;handle INSTALL= command.
675 push es ;AN013;
676 push bx ;AN013;
677 mov ax, cs:[Old_Area] ;AN013;
678 mov es, ax ;AN013;
679 mov bx, cs:[Impossible_Owner_Size] ;AN013;
680 mov ah, SETBLOCK ;AN013;
681 int 21h ;AN013;
682 MOV AX,ES ;AN013;
683 DEC AX ;AN013;
684 MOV ES,AX ;Point to arena
685 MOV ES:[arena_owner],8 ;Set impossible owner
686 pop bx ;AN013;
687 pop es ;AN013;
688Skip_Free_SYSINITBASE: ;AN013;
689 IF NOEXEC
690 MOV BP,DS ;SAVE COMMAND.COM SEGMENT
691 PUSH DS
692 POP ES
693 MOV BX,CS
694 SUB BX,10H ; Point to current PHP
695 MOV DS,BX
696 XOR SI,SI
697 MOV DI,SI
698 MOV CX,80H
699 REP MOVSW ; Copy it to new location for shell
700 MOV WORD PTR ES:[PDB_JFN_Pointer + 2],ES ; Relocate
701 MOV BX,ES
702 MOV AH,SET_CURRENT_PDB
703 INT 21H ; Tell DOS we moved it
704 MOV ES:[PDB_PARENT_PID],ES ;WE ARE THE ROOT
705 ENDIF
706
707 PUSH CS
708 POP DS
709ASSUME DS:SYSINITSEG
710;
711; SET UP THE PARAMETERS FOR COMMAND
712;
713
714 MOV SI,OFFSET COMMAND_LINE+1
715
716 IF NOEXEC
717 MOV DI,81H
718 ELSE
719 PUSH DS
720 POP ES
721 MOV DI,SI
722 ENDIF
723
724 MOV CL,-1
725COMTRANLP: ;FIND LENGTH OF COMMAND LINE
726 INC CL
727 LODSB
728 STOSB ;COPY COMMAND LINE IN
729 OR AL,AL
730 JNZ COMTRANLP
731 DEC DI
732 MOV AL,CR ; CR terminate
733 STOSB
734
735 IF NOEXEC
736 MOV ES:[80H],CL ; Set up header
737 MOV AL,[DEFAULT_DRIVE]
738 MOV ES:[5CH],AL
739 ELSE
740 MOV [COMMAND_LINE],CL ;Count
741 ENDIF
742
743 MOV DX,OFFSET COMMND ;NOW POINTING TO FILE DESCRIPTION
744
745 IF NOEXEC
746 MOV ES,BP ;SET LOAD ADDRESS
747 MOV BX,100H
748 CALL LDFIL ;READ IN COMMAND
749 JC COMERR
750 MOV DS,BP
751 MOV DX,80H
752 MOV AH,SET_DMA ;SET DISK TRANFER ADDRESS
753 INT 21H
754 CLI
755 MOV SS,BP
756 MOV SP,DX
757 STI
758 XOR AX,AX ;PUSH A WORD OF ZEROS
759 PUSH AX
760 PUSH BP ;SET HIGH PART OF JUMP ADDRESS
761 MOV AX,100H
762 PUSH AX ;SET LOW PART OF JUMP ADDRESS
763CCC PROC FAR
764 RET ;CRANK UP COMMAND!
765CCC ENDP
766
767 ELSE
768; We are going to open the command interpreter and size it as is done in
769; LDFIL. The reason we must do this is that SYSINIT is in free memory. If
770; there is not enough room for the command interpreter, EXEC will probably
771; overlay our stack and code so when it returns with an error SYSINIT won't be
772; here to catch it. This code is not perfect (for instance .EXE command
773; interpreters are possible) because it does its sizing based on the
774; assumption that the file being loaded is a .COM file. It is close enough to
775; correctness to be usable.
776
777 PUSH DX ; Save pointer to name
778
779; First, find out where the command interpreter is going to go.
780 MOV BX,0FFFFH
781 MOV AH,ALLOC
782 INT 21H ;Get biggest piece
783 MOV AH,ALLOC
784 INT 21H ;SECOND TIME GETS IT
785 JC MEMERRJX ; Oooops
786 MOV ES,AX
787 MOV AH,DEALLOC
788 INT 21H ; Give it right back
789 MOV BP,BX
790; ES:0 points to Block, and BP is the size of the block
791; in para.
792
793; We will now adjust the size in BP DOWN by the size of SYSINIT. We
794; need to do this because EXEC might get upset if some of the EXEC
795; data in SYSINIT is overlayed during the EXEC.
796 MOV BX,[MEMORY_SIZE]
797 MOV AX,CS
798 SUB BX,AX ; BX is size of SYSINIT in Para
799 ADD BX,11H ; Add the SYSINIT PHP
800 SUB BP,BX ; BAIS down
801 JC MEMERRJX ; No Way.
802
803 MOV AX,(OPEN SHL 8) ;OPEN THE FILE being EXECED
804 STC ;IN CASE OF INT 24
805 INT 21H
806 JC COMERR ; Ooops
807 MOV BX,AX ;Handle in BX
808 XOR CX,CX
809 XOR DX,DX
810 MOV AX,(LSEEK SHL 8) OR 2
811 STC ;IN CASE OF INT 24
812 INT 21H ; Get file size in DX:AX
813 JC COMERR
814 ; Convert size in DX:AX to para in AX
815 ADD AX,15 ; Round up size for conversion to para
816 ADC DX,0
817 MOV CL,4
818 SHR AX,CL
819 MOV CL,12
820 SHL DX,CL ; Low nibble of DX to high nibble
821 OR AX,DX ; AX is now # of para for file
822 ADD AX,10H ; 100H byte PHP
823 CMP AX,BP ; Will it fit?
824 JB OKLD ; Jump if yes.
825MEMERRJX:
826 JMP MEM_ERR
827
828OKLD:
829 MOV AH,CLOSE
830 INT 21H ; Close file
831 POP DX ; Recover pointer to name
832 PUSH CS
833 POP ES
834 ASSUME ES:SYSINITSEG
835 MOV BX,OFFSET COMEXE ; Point to EXEC block
836 MOV WORD PTR [BX.EXEC0_COM_LINE+2],CS ; Set segments
837 MOV WORD PTR [BX.EXEC0_5C_FCB+2],CS
838 MOV WORD PTR [BX.EXEC0_6C_FCB+2],CS
839 XOR AX,AX ;Load and go
840 MOV AH,EXEC
841 STC ;IN CASE OF INT 24
842 INT 21H ;GO START UP COMMAND
843 ENDIF
844; NOTE FALL THROUGH IF EXEC RETURNS (an error)
845
846COMERR:
847 MOV DX,OFFSET BADCOM ;WANT TO PRINT COMMAND ERROR
848 INVOKE BADFIL
849STALL: JMP STALL
850
851 PUBLIC TEMPCDS
852TEMPCDS:
853ASSUME DS:SYSINITSEG
854 LES DI,[DOSINFO]
855
856 MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO]
857 XOR CH,CH
858 MOV ES:[DI.SYSI_NCDS],CL
859 MOV AL,CL
860 MOV AH,SIZE curdir_list
861 MUL AH
862 call ParaRound
863 MOV SI,[CONFBOT]
864 SUB SI,AX
865 MOV [ALLOCLIM],SI ; Can't alloc past here!
866 MOV WORD PTR ES:[DI.SYSI_CDS + 2],SI
867 MOV AX,SI
868 MOV WORD PTR ES:[DI.SYSI_CDS],0
869 LDS SI,ES:[DI.SYSI_DPB]
870ASSUME DS:NOTHING
871 MOV ES,AX
872 XOR DI,DI
873
874FOOSET: ; Init CDSs
875 MOV AX,WORD PTR [FOOSTRNG]
876 STOSW
877 MOV AX,WORD PTR [FOOSTRNG + 2]
878 STOSW
879 INC BYTE PTR [FOOSTRNG]
880 XOR AX,AX
881 PUSH CX
882 MOV CX,curdir_flags - 4
883 REP STOSB
884 CMP SI,-1
885; JNZ NORMCDS
886;J.K. 6/24/87 Should handle the system that does not have any floppies.
887;J.K. In this case, we are going to pretended there are two dummy floppies
888;J.K. in the system. Still they have DPB and CDS, but we are going to
889;J.K. 0 out Curdir_Flags, Curdir_devptr of CDS so IBMDOS can issue
890;J.K. "Invalid drive specification" message when the user try to
891;J.K. access them.
892 je Fooset_Zero ;AN001;Don't have any physical drive.
893;SB34SYSINIT1003*************************************************************
894;SB Check to see if we are faking floppy drives. If not go to NORMCDS.
895;SB If we are faking floppy drives then see if this CDS being initialised
896;SB is for drive a: or b: by checking the appropriate field in the DPB
897;SB pointed to by ds:si. If not for a: or b: then go to NORMCDS. If
898;Sb for a: or b: then execute the code given below starting at Fooset_Zero.
899;SB For dpb offsets look at inc\dpb.inc.
900;SB 5 LOCS
901
902 cmp cs:Fake_Floppy_Drv,1 ;fake drive ?
903 jnz NORMCDS
904 cmp ds:[si].dpb_drive,02 ;check for a: or b:
905 jae NORMCDS
906
907;SB34SYSINIT1003*************************************************************
908Fooset_Zero: ;AN001;
909 XOR AX,AX
910 MOV CL,3
911 REP STOSW
912 POP CX
913 JMP SHORT FINCDS
914NORMCDS:
915 POP CX
916;J.K. If a non-fat based media is detected (by DPB.NumberOfFat == 0), then
917; set curdir_flags to 0. This is for signaling IBMDOS and IFSfunc that
918; this media is a non-fat based one.
919 cmp [SI.dpb_FAT_count], 0 ;AN000; Non fat system?
920 je SetNormCDS ;AN000; Yes. Set curdir_Flags to 0. AX = 0 now.
921 MOV AX,CURDIR_INUSE ;AN000; else, FAT system. set the flag to CURDIR_INUSE.
922SetNormCDS: ;AN000;
923 STOSW ; curdir_flags
924 MOV AX,SI
925 STOSW ; curdir_devptr
926 MOV AX,DS
927 STOSW
928 LDS SI,[SI.dpb_next_dpb]
929FINCDS:
930 MOV AX,-1
931 STOSW ; curdir_ID
932 STOSW ; curdir_ID
933 STOSW ; curdir_user_word
934 mov ax,2
935 stosw ; curdir_end
936 mov ax, 0 ;AN000;Clear out 7 bytes (curdir_type,
937 stosw ;AN000; curdir_ifs_hdr, curdir_fsda)
938 stosw ;AN000;
939 stosw ;AN000;
940 stosb ;AN000;
941 LOOP FOOSET
942 MOV BYTE PTR [FOOSTRNG],"A"
943 return
944
945;------------------------------------------------------------------------------
946; Allocate FILEs
947;------------------------------------------------------------------------------
948ENDFILE:
949; WE ARE NOW SETTING UP FINAL CDSs, BUFFERS, FILES, FCSs STRINGs etc. We no
950; longer need the space taken by The TEMP stuff below CONFBOT, so set ALLOCLIM
951; to CONFBOT.
952
953;J.K. 2/23/87 If this procedure has been called to take care of INSTALL= command,
954;then we have to save ES,SI registers.
955
956; test [Install_Flag],IS_INSTALL ;AN000; Called to handle INSTALL=?
957; jz ENDFILE_Cont ;AN000;
958; push es ;AN000; Save es,si for CONFIG.SYS
959; push si ;AN000;
960; test [Install_Flag],HAS_INSTALLED ;AN000; Sysinit_base already installed?
961; jz ENDFILE_Cont ;AN000; No. Install it.
962; jmp DO_Install_EXEC ;AN000; Just handle "INSTALL=" cmd only.
963;ENDFILE_Cont: ;AN000;
964
965 push ds ;AN002;
966 mov ax, Code ;AN002;
967 mov ds, ax ;AN002;
968 assume ds:Code
969 cmp MulTrk_flag, MULTRK_OFF1 ;AN002;=0, MULTRACK= command entered?
970 jne MulTrk_Flag_Done ;AN002;
971 or MulTrk_flag, MULTRK_ON ;AN002; Default will be ON.
972MulTrk_Flag_Done: ;AN002;
973 pop ds ;AN002;
974 assume ds:nothing
975
976 MOV AX,[CONFBOT]
977 MOV [ALLOCLIM],AX
978
979 PUSH CS
980 POP DS
981 INVOKE ROUND
982 MOV AL,[FILES]
983 SUB AL,5
984 JBE DOFCBS
985 push ax ;AN005;
986 mov al, DEVMARK_FILES ;AN005;
987 call SetDevMark ;AN005; Set DEVMARK for SFTS (FILES)
988 pop ax ;AN005;
989 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
990 ; IT DOES SIGN EXTEND.
991 MOV BX,[MEMLO]
992 MOV DX,[MEMHI]
993 LDS DI,[DOSINFO] ;GET POINTER TO DOS DATA
994 LDS DI,[DI+SYSI_SFT] ;DS:BP POINTS TO SFT
995 MOV WORD PTR [DI+SFLINK],BX
996 MOV WORD PTR [DI+SFLINK+2],DX ;SET POINTER TO NEW SFT
997 PUSH CS
998 POP DS
999 LES DI,DWORD PTR [MEMLO] ;POINT TO NEW SFT
1000 MOV WORD PTR ES:[DI+SFLINK],-1
1001 MOV ES:[DI+SFCOUNT],AX
1002 MOV BL,SIZE SF_ENTRY
1003 MUL BL ;AX = NUMBER OF BYTES TO CLEAR
1004 MOV CX,AX
1005 ADD [MEMLO],AX ;ALLOCATE MEMORY
1006 MOV AX,6
1007 ADD [MEMLO],AX ;REMEMBER THE HEADER TOO
1008 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1009 INVOKE ROUND ; Check for mem error before the STOSB
1010 ADD DI,AX
1011 XOR AX,AX
1012 REP STOSB ;CLEAN OUT THE STUFF
1013
1014;------------------------------------------------------------------------------
1015; Allocate FCBs
1016;------------------------------------------------------------------------------
1017DOFCBS:
1018 PUSH CS
1019 POP DS
1020 INVOKE ROUND
1021 mov al, DEVMARK_FCBS ;AN005;='X'
1022 call SetDevMark ;AN005;
1023 MOV AL,[FCBS]
1024 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
1025 ; IT DOES SIGN EXTEND.
1026 MOV BX,[MEMLO]
1027 MOV DX,[MEMHI]
1028 LDS DI,[DOSINFO] ;GET POINTER TO DOS DATA
1029 ASSUME DS:NOTHING
1030 MOV WORD PTR [DI+SYSI_FCB],BX
1031 MOV WORD PTR [DI+SYSI_FCB+2],DX ;SET POINTER TO NEW Table
1032 MOV BL,CS:Keep
1033 XOR BH,BH
1034 MOV [DI+SYSI_keep],BX
1035 PUSH CS
1036 POP DS
1037 ASSUME DS:SYSINITSEG
1038 LES DI,DWORD PTR [MEMLO] ;POINT TO NEW Table
1039 MOV WORD PTR ES:[DI+SFLINK],-1
1040 MOV ES:[DI+SFCOUNT],AX
1041 MOV BL,SIZE SF_ENTRY
1042 MOV CX,AX
1043 MUL BL ;AX = NUMBER OF BYTES TO CLEAR
1044 ADD [MEMLO],AX ;ALLOCATE MEMORY
1045 MOV AX,size sf-2
1046 ADD [MEMLO],AX ;REMEMBER THE HEADER TOO
1047 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1048 INVOKE ROUND ; Check for mem error before the STOSB
1049 ADD DI,AX ;Skip over header
1050 MOV AL,"A"
1051FillLoop:
1052 PUSH CX ; save count
1053 MOV CX,SIZE sf_entry ; number of bytes to fill
1054 cld
1055 REP STOSB ; filled
1056 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_ref_count],0
1057 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_position],0
1058 MOV WORD PTR ES:[DI-(SIZE sf_entry)+sf_position+2],0
1059 POP CX
1060 LOOP FillLoop
1061
1062;------------------------------------------------------------------------------
1063; Allocate Buffers
1064;------------------------------------------------------------------------------
1065
1066; Search through the list of media supported and allocate 3 buffers if the
1067; capacity of the drive is > 360KB
1068
1069 CMP [BUFFERS], -1 ; Has buffers been already set?
1070 je DoDefaultBuff
1071 cmp Buffer_Slash_X, 1 ;AN000;
1072 jne DO_Buffer ;AN000;
1073 call DoEMS ;AN000; Carry set if (enough) EMS is not available
1074 jc DoDefaultBuff ;AN000; Error. Just use default buffer.
1075DO_Buffer:
1076 jmp DOBUFF ; the user entered the buffers=.
1077
1078DoDefaultBuff:
1079 mov [H_Buffers], 0 ;AN000; Default is no heuristic buffers.
1080 MOV [BUFFERS], 2 ; Default to 2 buffers
1081 PUSH AX
1082 PUSH DS
1083 LES BP,CS:[DOSINFO] ; Search through the DPB's
1084 LES BP,DWORD PTR ES:[BP.SYSI_DPB] ; Get first DPB
1085
1086ASSUME DS:SYSINITSEG
1087 PUSH CS
1088 POP DS
1089
1090NEXTDPB:
1091 ; Test if the drive supports removeable media
1092 MOV BL, BYTE PTR ES:[BP.DPB_DRIVE]
1093 INC BL
1094 MOV AX, (IOCTL SHL 8) OR 8
1095 INT 21H
1096
1097; Ignore fixed disks
1098 OR AX, AX ; AX is nonzero if disk is nonremoveable
1099 JNZ NOSETBUF
1100
1101; Get parameters of drive
1102 XOR BX, BX
1103 MOV BL, BYTE PTR ES:[BP.DPB_DRIVE]
1104 INC BL
1105 MOV DX, OFFSET DeviceParameters
1106 MOV AX, (IOCTL SHL 8) OR GENERIC_IOCTL
1107 MOV CX, (RAWIO SHL 8) OR GET_DEVICE_PARAMETERS
1108 INT 21H
1109 JC NOSETBUF ; Get next DPB if driver doesn't support
1110 ; Generic IOCTL
1111
1112; Determine capacity of drive
1113; Media Capacity = #Sectors * Bytes/Sector
1114 MOV BX, WORD PTR DeviceParameters.DP_BPB.BPB_TotalSectors
1115
1116; To keep the magnitude of the media capacity within a word,
1117; scale the sector size
1118; (ie. 1 -> 512 bytes, 2 -> 1024 bytes, ...)
1119 MOV AX, WORD PTR DeviceParameters.DP_BPB.BPB_BytesPerSector
1120 XOR DX, DX
1121 MOV CX, 512
1122 DIV CX ; Scale sector size in factor of
1123 ; 512 bytes
1124
1125 MUL BX ; AX = #sectors * size factor
1126 OR DX, DX ; Just in case of LARGE floppies
1127 JNZ SETBUF
1128 CMP AX, 720 ; 720 Sectors * size factor of 1
1129 JBE NOSETBUF
1130SETBUF:
1131 MOV [BUFFERS], 3
1132 jmp Chk_Memsize_for_Buffers ; Now check the memory size for default buffer count
1133; JMP BUFSET ; Jump out of search loop
1134NOSETBUF:
1135 CMP WORD PTR ES:[BP.DPB_NEXT_DPB],-1
1136 jz Chk_Memsize_for_Buffers
1137; JZ BUFSET
1138 LES BP,ES:[BP.DPB_NEXT_DPB]
1139 JMP NEXTDPB
1140
1141;J.K. 10/15/86 DCR00014.
1142;From DOS 3.3, the default number of buffers will be changed according to the
1143;memory size too.
1144; Default buffers = 2
1145; If diskette Media > 360 kb, then default buffers = 3
1146; If memory size > 128 kb (2000H para), then default buffers = 5
1147; If memory size > 256 kb (4000H para), then default buffers = 10
1148; If memory size > 512 kb (8000H para), then default buffers = 15.
1149
1150Chk_Memsize_for_Buffers:
1151 cmp [memory_size], 2000h
1152 jbe BufSet
1153 mov [buffers], 5
1154 cmp [memory_size], 4000h
1155 jbe BufSet
1156 mov [buffers], 10
1157 cmp [memory_size], 8000h
1158 jbe BufSet
1159 mov [buffers], 15
1160
1161BUFSET:
1162ASSUME DS:NOTHING
1163 POP DS
1164 POP AX
1165
1166;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1167;J.K. Here we should put extended stuff and new allocation scheme!!!
1168;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1169;*******************************************************************************
1170; *
1171; Function: Actually allocate BUFFERS into the (extended) memory and initialize*
1172; it. *
1173; If it is installed in real memory, the number of buffers in each *
1174; bucket will be balanced out as far as possible for perfermance. *
1175; Also, if the user specified the secondary buffer cache, it will *
1176; be installed in the real memory. *
1177; *
1178; Input : *
1179; BuffINFO.EMS_MODE - 0=IBM mode, -1 = do not use extended memory. *
1180; BuffINFO.Frame_Page - Page frame 0 segment address *
1181; MEMHI:MEMLO - Start of the next available memory *
1182; Buffer_Pages = Number of extended memory pages for buffer *
1183; BUFFERS = Number of buffers *
1184; H_Buffers = Number of secondary buffers *
1185; *
1186; Output: *
1187; BuffINFO.Cache_Count - # of caches to be installed. *
1188; Hash table set. *
1189; BuffINFO set. *
1190; BufferBuckets set. *
1191; MaxNumBuf1, MaxNumBuf2, and NthBuck set. *
1192; *
1193; Subroutines to be called: *
1194; *
1195; Logic: *
1196; { *
1197; IF (BuffINFO.EMS_MODE == -1) THEN *
1198; { *
1199; IF BUFFERS < 30 THEN *
1200; {# of Bucket = 1; MaxNumBuf1 = BUFFERS; NthBuck = 1} *
1201; ELSE { *
1202; # of Bucket = BUFFERS/15; *
1203; r = BUFFERS mod 15; *
1204; IF r == 0 THEN NthBuck = # of Bucket *
1205; ELSE *
1206; { *
1207; AddBuff = r / # of Bucket; *
1208; NthBuck = r mod # of Bucket; *
1209; MaxNumBuf1 = 15 + AddBuff; /* 1st Bucket - Nth Bucket*
1210; MaxNumBuf2 = 15 + AddBuff +1;/*(N+1)th Bucket to last*
1211; } *
1212; } *
1213; } *
1214; ELSE *
1215; { *
1216; # of Bucket = Buffer_Pages * 2; /* 2 buckets per page *
1217; }; *
1218; *
1219; /*Now allocate memory for Hash table */ *
1220; Hash Table Size = (size Buffer_Hash_Entry) * # of Bucket; *
1221; Set BuffINFO.Hash_ptr to MEMHI:MEMLO; *
1222; Adjust MEMHI:MEMLO according to Hash table size; *
1223; *
1224; /*Set buffers*/ *
1225; IF (EMS_MODE <> -1) THEN *
1226; Set_EMS_Buffer *
1227; ELSE /*Do not use the extended memory */ *
1228; Set_Buffer; *
1229;/*Now set the caches if specified.*/ *
1230; IF (BuffINFO.Cache_count > 0) THEN *
1231; {Set BuffINFO.Cache_ptr to MEMHI:MEMLO; *
1232; MEMHI:MEMLO = MEMHI:MEMLO + 512 * BuffINFO.Cache_count; *
1233; }; *
1234; }; *
1235; *
1236;*******************************************************************************
1237DOBUFF: ;AN000;
1238 lds bx, cs:[DosInfo] ;AN000; ds:bx -> SYSINITVAR
1239
1240 mov ax, [Buffers] ;AN000;Set SYSI_BUFFERS
1241 mov word ptr ds:[bx.SYSI_BUFFERS], ax ;AN000;
1242 mov ax, [H_Buffers] ;AN000;
1243 mov word ptr ds:[bx.SYSI_BUFFERS+2], ax ;AN000;
1244
1245 lds bx, ds:[bx.SYSI_BUF] ;AN000; now, ds:bx -> BuffInfo
1246 cmp ds:[bx.EMS_MODE], -1 ;AN000;
1247; $IF E, LONG ;AN000;
1248 JE $$XL1
1249 JMP $$IF1
1250$$XL1:
1251 xor dx, dx ;AN000;
1252 mov ax, [Buffers] ;AN000; < 99
1253 cmp al, 30 ;AN026; if less than 30,
1254; $IF B ;AN026;
1255 JNB $$IF2
1256 mov [BufferBuckets], 1 ;AN026; then put every buffer
1257 mov ds:[bx.HASH_COUNT], 1 ;AN026; into one bucket
1258 mov [MaxNumBuf1], al ;AN026;
1259 mov [NthBuck], 1 ;AN026;
1260; $ELSE ;AN026; else...
1261 JMP SHORT $$EN2
1262$$IF2:
1263 mov cl, 15 ;AN026; Magic number 15.
1264 div cl ;AN026; al=# of buckets, ah=remainders
1265 push ax ;AN026; save the result
1266 xor ah, ah ;AN026;
1267 mov [BufferBuckets], ax ;AN026;
1268 mov ds:[bx.HASH_COUNT], ax ;AN026;
1269 pop ax ;AN026;
1270 or ah, ah ;AN026;
1271; $IF Z ;AN026;if no remainders
1272 JNZ $$IF4
1273 mov [NthBuck], al ;AN026;then set NthBuck=# of bucket for Set_Buffer proc.
1274; $ELSE ;AN026;else
1275 JMP SHORT $$EN4
1276$$IF4:
1277 mov cl, al ;AN026;
1278 mov al, ah ;AN026;remainder/# of buckets
1279 xor ah, ah ;AN026; =
1280 div cl ;AN026;al=additional num of buffers
1281 or ah, ah ;AN026;ah=Nth bucket
1282; $IF Z ;AN026;
1283 JNZ $$IF6
1284 add [MaxNumBuf1], al ;AN026;
1285 mov ax, [BufferBuckets] ;AN026;
1286 mov [NthBuck], al ;AN026;
1287; $ELSE ;AN026;
1288 JMP SHORT $$EN6
1289$$IF6:
1290 mov [NthBuck], ah ;AN026;
1291 add [MaxNumBuf1], al ;AN026;MaxNumNuf are initially set to 15.
1292 add [MaxNumBuf2], al ;AN026;
1293 inc [MaxNumBuf1] ;AN026;Additional 1 more buffer for group 1 buckets.
1294; $ENDIF ;AN026;
1295$$EN6:
1296; $ENDIF ;AN026;
1297$$EN4:
1298; $ENDIF ;AN026;
1299$$EN2:
1300; $ELSE ;AN000; Use the extended memory.
1301 JMP SHORT $$EN1
1302$$IF1:
1303 mov ax, [Buffer_Pages] ;AN000;
1304 mov cx, MAXBUCKETINPAGE ;AN000;
1305 mul cx ;AN000; gauranteed to be word boundary.
1306 mov [BufferBuckets], ax ;AN000;
1307 mov ds:[bx.HASH_COUNT], ax ;AN000;
1308; $ENDIF ;AN000;
1309$$EN1:
1310 invoke Round ;AN000; get [MEMHI]:[MEMLO]
1311 mov al, DEVMARK_BUF ;AN005; ='B'
1312 call SetDevMark ;AN005;
1313;Now, allocate Hash table at [memhi]:[memlo]. AX = Hash_Count.
1314 mov ax, [BufferBuckets] ;AN026; # of buckets==Hash_Count
1315 mov cx, size BUFFER_HASH_ENTRY ;AN000;
1316 mul cx ;AN000; now AX = Size of hash table.
1317 les di, ds:[bx.HASH_PTR] ;AN000; save Single buffer address.
1318 mov cx, [MemLo] ;AN000;
1319 mov word ptr ds:[bx.HASH_PTR], cx ;AN000; set BuffINFO.HASH_PTR
1320 mov cx, [MemHi] ;AN000;
1321 mov word ptr ds:[bx.HASH_PTR+2], cx ;AN000;
1322 mov [Memlo], ax ;AN000;
1323 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1324 call Round ;AN000; get new [memhi]:[memlo]
1325;Allocate buffers
1326 push ds ;AN000; Save Buffer info. ptr.
1327 push bx ;AN000;
1328 cmp ds:[bx.EMS_MODE], -1 ;AN000;
1329; $IF NE ;AN000;
1330 JE $$IF13
1331 call Set_EMS_Buffer ;AN000;
1332; $ELSE ;AN000;
1333 JMP SHORT $$EN13
1334$$IF13:
1335 call Set_Buffer ;AN000;
1336; $ENDIF ;AN000;
1337$$EN13:
1338 pop bx ;AN000;
1339 pop ds ;AN000;
1340;Now set the secondary buffer if specified.
1341 cmp [H_Buffers], 0 ;AN000;
1342; $IF NE ;AN000;
1343 JE $$IF16
1344 call Round ;AN000;
1345 mov cx, [MemLo] ;AN000;
1346 mov word ptr ds:[bx.CACHE_PTR], cx ;AN000;
1347 mov cx, [MemHi] ;AN000;
1348 mov word ptr ds:[bx.CACHE_PTR+2], cx ;AN000;
1349 mov cx, [H_Buffers] ;AN000;
1350 mov ds:[bx.CACHE_COUNT], cx ;AN000;
1351 mov ax, 512 ;AN000; 512 byte
1352 mul cx ;AN000;
1353 mov [Memlo], ax ;AN000;
1354 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1355 call Round ;AN000;
1356; $ENDIF ;AN000;
1357$$IF16:
1358;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1359;J.K. END OF NEW BUFFER SCHEME.
1360;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1361;DOBUFF:
1362; INVOKE ROUND
1363; DEC [BUFFERS] ; FIRST DEC acounts for buffer already
1364; ; in system.
1365; JZ BUF1 ; All done
1366; PUSH DS
1367; LES DI,BUFPTR
1368; LDS BX,DOSINFO
1369; MOV AX,WORD PTR [BX.SYSI_BUF] ; Link in new buffer
1370; MOV WORD PTR ES:[DI.buf_link],AX
1371; MOV AX,WORD PTR [BX.SYSI_BUF+2]
1372; MOV WORD PTR ES:[DI.buf_link+2],AX
1373; MOV WORD PTR [BX.SYSI_BUF],DI
1374; MOV WORD PTR [BX.SYSI_BUF+2],ES
1375; MOV WORD PTR ES:[DI.buf_ID],00FFH ;NEW BUFFER FREE
1376; mov word ptr es:[di.buf_Sector],0 ;AN000;
1377; mov word ptr es:[di.buf_Sector+2],0 ;AN000;
1378; MOV BX,[BX.SYSI_MAXSEC]
1379; POP DS
1380; ADD BX,BUFINSIZ
1381; ADD [MEMLO],BX
1382; JMP DOBUFF
1383
1384;------------------------------------------------------------------------------
1385; Allocate CDSs
1386;------------------------------------------------------------------------------
1387BUF1:
1388 INVOKE ROUND
1389 push ax ;AN005;
1390 mov ax, DEVMARK_CDS ;AN005;='L'
1391 call SetDevMark ;AN005;
1392 pop ax ;AN005;
1393 LES DI,[DOSINFO]
1394 MOV CL,BYTE PTR ES:[DI.SYSI_NUMIO]
1395 CMP CL,[NUM_CDS]
1396 JAE GOTNCDS ; User setting must be at least NUMIO
1397 MOV CL,[NUM_CDS]
1398GOTNCDS:
1399 XOR CH,CH
1400 MOV ES:[DI.SYSI_NCDS],CL
1401 MOV AX,[MEMHI]
1402 MOV WORD PTR ES:[DI.SYSI_CDS + 2],AX
1403 MOV AX,[MEMLO]
1404 MOV WORD PTR ES:[DI.SYSI_CDS],AX
1405 MOV AL,CL
1406 MOV AH,SIZE curdir_list
1407 MUL AH
1408 call ParaRound
1409 ADD [MEMHI],AX
1410 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;
1411 INVOKE ROUND ; Check for mem error before initializing
1412 LDS SI,ES:[DI.SYSI_DPB]
1413ASSUME DS:NOTHING
1414 LES DI,ES:[DI.SYSI_CDS]
1415 CALL FOOSET
1416
1417;------------------------------------------------------------------------------
1418; Allocate Space for Internal Stack
1419;------------------------------------------------------------------------------
1420
1421 IF STACKSW
1422
1423 PUSH CS
1424 POP DS
1425 ASSUME DS:SYSINITSEG
1426
1427 IF IBM
1428;Don't install the system stack on the PCjr. Ignore STACKS=command too.
1429 CMP [Sys_Model_Byte], 0FDh ; PCjr = 0FDh
1430 JE SkipStack_brdg
1431 ENDIF
1432
1433;J.K. 10/15/86 DCR00013
1434;If the use does not entered STACKS= command, as a default, do not install
1435;sytem stacks for PC1, PC XT, PC Portable cases.
1436;Otherwise, install it to the user specified value or to the default
1437;value of 9, 128 for the rest of the system.
1438
1439 cmp word ptr [stack_addr], -1 ;Has the user entered "stacks=" command?
1440 je DoInstallStack ;Then install as specified by the user
1441 cmp [Sys_Scnd_Model_Byte], 0 ;PC1, XT has the secondary model byte = 0
1442 jne DoInstallStack ;Other model should have default stack of 9, 128
1443 cmp [Sys_Model_Byte], 0FFh ;PC1 ?
1444 je SkipStack_brdg
1445 cmp [Sys_Model_Byte], 0FEh ;PC/XT or PC Portable ?
1446 jne DoInstallStack
1447SkipStack_Brdg:
1448 jmp SkipStack
1449DoInstallStack:
1450 mov ax, [stack_count] ;J.K. Stack_count = 0?
1451 cmp ax, 0 ;then, stack size must be 0 too.
1452 jz SkipStack_brdg ;Don't install stack.
1453;J.K. 10/21/86 Dynamic Relocation of Stack code.
1454 call Round ;[memhi] = Seg. for stack code
1455 ;[memlo] = 0
1456;J.K. Set DEVMARK block into memory for MEM command
1457;J.K. DEVMARK_ID = 'S' for stack
1458 mov al, DEVMARK_STK ;AN005;='S'
1459 call SetDevMark
1460
1461 mov ax, [memhi]
1462 mov es, ax ;ES -> Seg. the stack code is going to move.
1463 assume es:nothing
1464 push cs
1465 pop ds
1466 xor si,si ;!!We know that Stack code is at the beginning of SYSINIT.
1467 xor di,di
1468 mov cx, offset Endstackcode
1469 mov [memlo],cx
1470 call Round ;Have enough space for relocation?
1471 rep movsb
1472
1473 mov ax, [memlo]
1474 mov word ptr [stack_addr],ax ;set for stack area initialization
1475 mov ax, [memhi] ;This will be used by Stack_Init routine.
1476 mov word ptr [stack_addr+2],ax
1477
1478; Space for Internal Stack area = STACK_COUNT(ENTRYSIZE + STACK_SIZE)
1479 MOV AX, EntrySize
1480 ADD AX, [STACK_SIZE]
1481 MOV CX, [STACK_COUNT]
1482 MUL CX
1483 call ParaRound ; Convert size to pargraphs
1484 ADD [MEMHI], AX
1485 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;To set the DEVMARK_SIZE for Stack by ROUND routine.
1486 INVOKE ROUND ; Check for memory error before
1487 ; continuing
1488 CALL StackInit ; Initialize hardware stack. CS=DS=sysinitseg, ES=Relocated stack code & data
1489
1490SkipStack:
1491 ENDIF
1492
1493 PUSH CS
1494 POP DS
1495 ASSUME DS:SYSINITSEG
1496
1497 MOV AL,[FILES]
1498 XOR AH,AH ; DO NOT USE CBW INSTRUCTION!!!!!
1499 ; IT DOES SIGN EXTEND.
1500 MOV CX,AX
1501 XOR BX,BX ;Close standard input
1502 MOV AH,CLOSE
1503 INT 21H
1504 MOV BX,2
1505RCCLLOOP: ;Close everybody but standard output
1506 MOV AH,CLOSE ; Need output so we can print message
1507 INT 21H ; in case we can't get new one open.
1508 INC BX
1509 LOOP RCCLLOOP
1510
1511 MOV DX,OFFSET CONDEV
1512 MOV AL,2
1513 MOV AH,OPEN ;OPEN CON FOR READ/WRITE
1514 STC ; Set for possible INT 24
1515 INT 21H
1516 JNC GOAUX
1517 INVOKE BADFIL
1518 JMP SHORT GOAUX2
1519
1520GOAUX: PUSH AX
1521 MOV BX,1 ;close standard output
1522 MOV AH,CLOSE
1523 INT 21H
1524 POP AX
1525
1526 MOV BX,AX ;New device handle
1527 MOV AH,XDUP
1528 INT 21H ;Dup to 1, STDOUT
1529 MOV AH,XDUP
1530 INT 21H ;Dup to 2, STDERR
1531
1532GOAUX2: MOV DX,OFFSET AUXDEV
1533 MOV AL,2 ;READ/WRITE ACCESS
1534 INVOKE OPEN_DEV
1535
1536 MOV DX,OFFSET PRNDEV
1537 MOV AL,1 ;WRITE ONLY
1538 INVOKE OPEN_DEV
1539
1540;J.K.9/29/86 *******************
1541;Global Rearm command for Shared Interrupt devices attached in the system;
1542;Shared interrupt attachment has some problem when it issues interrupt
1543;during a warm reboot. Once the interrupt is presented by the attachment,
1544;no further interrupts on that level will be presented until a global rearm
1545;is issued. By the request of the system architecture group, IBMBIO will
1546;issue a global rearm after every device driver is loaded.
1547;To issue a global rearm: ;For PC1, XT, Palace
1548; OUT 02F2h, XX ; Interrupt level 2
1549; OUT 02F3h, XX ; Interrupt level 3
1550; OUT 02F4h, XX ; Interrupt level 4
1551; OUT 02F5h, XX ; Interrupt level 5
1552; OUT 02F6h, XX ; Interrupt level 6
1553; OUT 02F7h, XX ; Interrupt level 7
1554;
1555; ;For PC AT, in addition to the above commands,
1556; ;need to handle the secondary interrupt handler
1557; OUT 06F2h, XX ; Interrupt level 10
1558; OUT 06F3h, XX ; Interrupt level 11
1559; OUT 06F4h, XX ; Interrupt level 12
1560; OUT 06F6h, XX ; Interrupt level 14
1561; OUT 06F7h, XX ; Interrupt level 15
1562;
1563; ;For Round-Up machine
1564; None.
1565; where XX stands for any value.
1566; For your information, after Naples level machine, the system service bios
1567; call (INT 15h), function AH=0C0h returns the system configuration parameters
1568;
1569
1570 cmp [sys_model_byte], 0FDh ;PCjr?
1571; je GoCheckInstall
1572 je Set_Sysinit_Base
1573;SB33045*******************************************************************
1574 push ax ;Save Regs ;SB ;3.30*
1575 push bx ; * ;SB ;3.30*
1576 push dx ; * ;SB ;3.30*
1577 push es ; * ;SB ;3.30*
1578 mov al,0ffh ;Reset h/w by writing to port ;SB ;3.30*
1579 mov dx,2f2h ;Get starting address ;SB ;3.30*
1580 out dx,al ; out 02f2h,0ffh
1581 inc dx
1582 out dx,al ; out 02f3h,0ffh
1583 inc dx
1584 out dx,al ; out 02f4h,0ffh
1585 inc dx
1586 out dx,al ; out 02f5h,0ffh
1587 inc dx
1588 out dx,al ; out 02f6h,0ffh
1589 inc dx
1590 out dx,al ; out 02f7h,0ffh
1591;SB33045*******************************************************************
1592
1593;SB33046*******************************************************************
1594;SB Secondary global rearm ;3.30
1595 mov ax,0f000h ;Get machine type ;SB ;3.30*
1596 mov es,ax ; * ;SB ;3.30*
1597 cmp byte ptr es:[0fffeh],0fch ;Q:Is it a AT type machine ;SB ;3.30*
1598 je startrearm ; *if AT no need to check
1599 mov ah,0c0h ;Get system configuration ;SB ;3.30*
1600 int 15h ; * ;SB ;3.30*
1601 jc finishrearm ; *jmp if old rom ;SB ;3.30*
1602; ;SB ;3.30*
1603; Test feature byte for secondary interrupt controller ;SB ;3.30*
1604; ;SB ;3.30*
1605 test es:[bx.bios_SD_featurebyte1],ScndIntController ; ;SB ;3.30*
1606 je finishrearm ;Jmp if it is there ;SB ;3.30*
1607startrearm:
1608 mov al,0ffh ;Write any pattern to port ;SB ;3.30*
1609 mov dx,6f2h ;Get starting address ;SB ;3.30*
1610 out dx,al ;out 06f2h,0ffh
1611 inc dx ;Bump address ;SB ;3.30*
1612 out dx,al ;out 06f3h,0ffh
1613 inc dx ;Bump address ;SB ;3.30*
1614 out dx,al ;out 06f4h,0ffh
1615 inc dx ;Bump address ;SB ;3.30*
1616 inc dx ;Bump address ;SB ;3.30*
1617 out dx,al ;out 06f6h,0ffh
1618 inc dx ;Bump address ;SB ;3.30*
1619 out dx,al ;out 06f7h,0ffh
1620finishrearm: ; ;SB ;3.30*
1621 pop es ;Restore regs ;SB ;3.30*
1622 pop dx ; * ;SB ;3.30*
1623 pop bx ; * ;SB ;3.30*
1624 pop ax ; * ;SB ;3.30*
1625;SB33046*******************************************************************
1626
1627;J.K. 9/29/86 Global Rearm end *******************
1628
1629;------------------------------------------------------------------------------
1630; Allocate SYSINIT_BASE for INSTALL= command
1631;------------------------------------------------------------------------------
1632;J.K. SYSINIT_BASE allocation.
1633;Check if ENDFILE has been called to handle INSTALL= command.
1634
1635Set_Sysinit_Base:
1636;GoCheckInstall:
1637; test [Install_Flag], HAVE_INSTALL_CMD ;AN019;;AN021;install sysinit base all the time.
1638; jz Skip_SYSINIT_BASE ;AN019;
1639
1640;J.K.--------------------------------------------------------------------------
1641;SYSINIT_BASE will be established in the secure area of
1642;lower memory when it handles the first INSTALL= command.
1643;SYSINIT_BASE is the place where the actual EXEC function will be called and
1644;will check SYSINIT module in high memory if it is damaged by the application
1645;program. If SYSINIT module has been broken, then "Memory error..." message
1646;is displayed by SYSINIT_BASE.
1647;------------------------------------------------------------------------------
1648 push ax ;AN013; Set DEVMARK for MEM command
1649 mov ax, [memhi] ;AN013;
1650 sub ax, [area] ;AN013;
1651 mov [Impossible_owner_size], ax ;AN013;Remember the size in case.
1652 mov al, DEVMARK_INST ;AN013;
1653 call SetDevMark ;AN013;
1654 pop ax ;AN013;
1655
1656 mov di, [memhi] ;AN000;
1657 mov es, di ;AN000;
1658 assume es:nothing ;AN000;
1659 mov word ptr [sysinit_base_ptr+2],di ;AN000; save this entry for the next use.
1660 xor di, di ;AN000;
1661 mov word ptr [sysinit_base_ptr], di ;AN000; es:di -> destination.
1662 mov si, offset SYSINIT_BASE ;AN000; ds:si -> source code to be relocated.
1663 mov cx, Size_SYSINIT_BASE ;AN000;
1664 add [memlo],cx ;AN000;
1665 or cs:[SetDevMarkFlag], FOR_DEVMARK ;AN013;
1666 call round ;AN000; check mem error. Also, readjust MEMHI for the next use.
1667 rep movsb ;AN000; reallocate it.
1668
1669 mov word ptr [Sysinit_Ptr], offset SYSINITPTR ;AN000; Returing address from
1670 mov word ptr [Sysinit_Ptr+2], cs ;AN000; SYSINIT_BASE back to SYSINIT.
1671 or [Install_Flag],HAS_INSTALLED ;AN000; Set the flag.
1672
1673;------------------------------------------------------------------------------
1674; Free the rest of the memory from MEMHI to CONFBOT. Still from CONFBOT to
1675; the top of the memory will be allocated for SYSINIT and CONFIG.SYS if
1676; HAVE_INSTALL_CMD.
1677;------------------------------------------------------------------------------
1678;Skip_SYSINIT_BASE: ;AN021;
1679
1680 INVOKE ROUND
1681 MOV BX,[MEMHI]
1682 MOV AX,[AREA]
1683 mov [Old_Area], ax ;AN013; Save [AREA]
1684 MOV ES,AX ;CALC WHAT WE NEEDED
1685 SUB BX,AX
1686 MOV AH,SETBLOCK
1687 INT 21H ;GIVE THE REST BACK
1688 PUSH ES
1689 MOV AX,ES
1690 DEC AX
1691 MOV ES,AX ;Point to arena
1692 MOV ES:[arena_owner],8 ;Set impossible owner
1693 POP ES
1694
1695 mov bx,0ffffh ;AN000;
1696 mov ah,Alloc ;AN000;
1697 int 21h ;AN000;
1698 mov ah,Alloc ;AN000;
1699 int 21h ;AN000; Allocate the rest of the memory
1700
1701 mov [memhi],ax ;AN000; Start of the allocated memory
1702 mov [memlo],0 ;AN000; to be used next.
1703
1704 ;;;; At this moment, memory from [MEMHI]:0 to Top-of-the memory is
1705 ;;;; allocated.
1706 ;;;; To protect sysinit, confbot module (From CONFBOT (or =ALLOCLIM at
1707 ;;;; this time) to the Top-of-the memory), here we are going to
1708 ;;;; 1). "SETBLOCK" from MEMHI to CONFBOT.
1709 ;;;; 2). "ALLOC" from CONFBOT to the top of the memory.
1710 ;;;; 3). "Free Alloc Memory" from MEMHI to CONFBOT.
1711;Memory allocation for SYSINIT, CONFBOT module.
1712 mov es, ax ;AN000;
1713 mov bx, [confbot] ;AN000;
1714 sub bx, ax ;AN000; CONFBOT - MEMHI
1715 dec bx ;AN000; Make a room for the memory block id.
1716 dec bx ;AN000; make sure!!!.
1717 mov ah, SETBLOCK ;AN000;
1718 int 21h ;AN000; this will free (CONFBOT to top of memory)
1719 mov bx, 0ffffh ;AN000;
1720 mov ah, ALLOC ;AN000;
1721 int 21h ;AN000;
1722 mov ah, ALLOC ;AN000;
1723 int 21h ;AN000; allocate (CONFBOT to top of memory)
1724 mov [area],ax ;AN000; Save Allocated memory segment.
1725 ;AN000; Need this to free this area for COMMAND.COM.
1726 mov es, [memhi] ;AN000;
1727 mov ah, 49h ;AN000; Free Allocated Memory.
1728 int 21h ;AN000; Free (Memhi to CONFBOT(=AREA))
1729
1730; IF NOEXEC
1731; MOV BX,0FFFFH ;ALLOCATE THE REST OF MEM FOR COMMAND
1732; MOV AH,ALLOC
1733; INT 21H
1734; MOV AH,ALLOC
1735; INT 21H
1736; MOV DS,AX
1737; ENDIF
1738
1739; test cs:[Install_Flag],IS_INSTALL ;AN000;
1740; jnz DO_Install_Exec ;AN000;
1741
1742ENDFILE_Ret:
1743 return
1744
1745
1746Do_Install_Exec proc near ;AN000; Now, handles INSTALL= command.
1747
1748 push si ;AN000; save SI for config.sys again.
1749
1750 ;;;; We are going to call LOAD/EXEC function.
1751 ;;;;;Set ES:BX to the parameter block here;;;;;;;
1752 ;;;;;Set DS:DX to the ASCIIZ string. Remember that we already has 0
1753 ;;;;;after the filename. So parameter starts after that. If next
1754 ;;;;;character is a line feed (i.e. 10), then assume that the 0
1755 ;;;;;we already encountered used to be a carrage return. In this
1756 ;;;;;case, let's set the length to 0 which will be followed by
1757 ;;;;;carridge return.
1758;J.K. ES:SI -> command line in CONFIG.SYS. Points to the first non blank
1759;character after =.
1760 push es ;AN000;
1761 push ds ;AN000;
1762 pop es ;AN000;
1763 pop ds ;AN000; es->sysinitseg, ds->confbot seg
1764 assume ds:nothing ;AN000;
1765 mov dx, si ;AN000; ds:dx->file name,0 in CONFIG.SYS image.
1766;AN016; UNDO THE EXTENDED ATTRIBUTES HANDLING
1767; mov ax, OPEN SHL 8 ;AN008;
1768; int 21h ;AN008;
1769; jc SysInitPtr ;AN008;
1770; mov bx, ax ;AN008;handle
1771; call Get_Ext_Attribute ;AN008;Get the extended attribute.
1772; cmp al, EA_INSTALLABLE ;AN008;
1773; je EA_Installable_OK ;AN012;
1774; stc ;AN012;
1775; jmp SysInitPtr ;AN012;
1776;EA_Installable_OK: ;AN012;
1777 xor cx,cx ;AN000;
1778 cld ;AN000;
1779 mov cs:Ldexec_start, ' ' ;AN015; Clear out the parm area
1780 mov di, offset Ldexec_parm ;AN000;
1781InstallFilename: ;AN000; skip the file name
1782 lodsb ;AN000; al = ds:si; si++
1783 cmp al, 0 ;AN000;
1784 je Got_InstallParm ;AN000;
1785 jmp InstallFilename ;AN000;
1786Got_InstallParm: ;AN000; copy the parameters to Ldexec_parm
1787 lodsb ;AN000;
1788 mov es:[di], al ;AN000;
1789 cmp al, LF ;AN000;AN028; line feed?
1790 je Done_InstallParm ;AN000;AN028;
1791 inc cl ;AN000; # of char. in the parm.
1792 inc di ;AN000;
1793 jmp Got_Installparm ;AN000;
1794Done_Installparm: ;AN000;
1795 mov byte ptr cs:[Ldexec_line], cl ;AN000; length of the parm.
1796 cmp cl, 0 ;AN015;If no parm, then
1797 jne Install_Seg_Set ;AN015; let the parm area
1798 mov byte ptr cs:[Ldexec_Start],CR ;AN015; starts with CR.
1799Install_Seg_Set: ;AN015;
1800 mov word ptr cs:0, 0 ;AN000; Make a null environment segment
1801 mov ax, cs ;AN000; by overlap JMP instruction of SYSINITSEG.
1802 mov cs:[INSTEXE.EXEC0_ENVIRON],ax ;AN000; Set the environment seg.
1803 mov word ptr cs:[INSTEXE.EXEC0_COM_LINE+2],ax ;AN000; Set the seg.
1804 mov word ptr cs:[INSTEXE.EXEC0_5C_FCB+2],ax ;AN000;
1805 mov word ptr cs:[INSTEXE.EXEC0_6C_FCB+2],ax ;AN000;
1806 call Sum_up ;AN000;
1807 mov es:CheckSum, ax ;AN000; save the value of the sum
1808 xor ax,ax ;AN000;
1809 mov ah, EXEC ;AN000; Load/Exec
1810 mov bx, offset INSTEXE ;AN000; ES:BX -> parm block.
1811 push es ;AN000; Save es,ds for Load/Exec
1812 push ds ;AN000; these registers will be restored in SYSINIT_BASE.
1813 jmp cs:dword ptr SYSINIT_BASE_PTR ;AN000; jmp to SYSINIT_BASE to execute
1814 ; LOAD/EXEC function and check sum.
1815
1816;J.K. This is the returning address from SYSINIT_BASE.
1817SYSINITPTR: ;AN000; returning far address from SYSINIT_BASE
1818 pop si ;AN000; restore SI for CONFIG.SYS file.
1819 push es ;AN000;
1820 push ds ;AN000;
1821 pop es ;AN000;
1822 pop ds ;AN000; now ds - sysinitseg, es - confbot
1823 jnc Exec_Exit_Code
1824 test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc?
1825 jnz Install_Error_Exit ;AN021; Just exit with carry set.
1826 push si ;AN000; Error in loading the file for INSTALL=.
1827 call BadLoad ;AN000; ES:SI-> path,filename,0.
1828 pop si ;AN000;
1829 jmp Install_Exit_Ret
1830Exec_Exit_Code:
1831 test cs:Install_Flag, SHARE_INSTALL ;AN021; Called by LoadShare proc?
1832 jnz Install_Exit_Ret ;AN021; Just exit.
1833 mov ah, 4dh ;AN017;
1834 int 21h ;AN017;
1835 cmp ah, 3 ;AN017;Only accept "Stay Resident" prog.
1836 je Install_Exit_Ret ;AN017;
1837 call Error_Line ;AN017;Inform the user
1838Install_Error_Exit: ;AN021;
1839 stc ;AN021;
1840Install_Exit_Ret:
1841 ret
1842Do_Install_Exec endp
1843
1844Public ParaRound
1845ParaRound:
1846 ADD AX,15
1847 RCR AX,1
1848 SHR AX,1
1849 SHR AX,1
1850 SHR AX,1
1851 return
1852
1853;------------------------------------------------------------------------------
1854;J.K. SYSINIT_BASE module.
1855;In: After relocation,
1856; AX = 4B00h - Load and execute the program DOS function.
1857; DS = CONFBOT. Segment of CONFIG.SYS file image
1858; ES = Sysinitseg. Segment of SYSINIT module itself.
1859; DS:DX = pointer to ASCIIZ string of the path,filename to be executed.
1860; ES:BX = pointer to a parameter block for load.
1861; SYSSIZE (Byte) - offset vaule of End of SYSINIT module label
1862; BIGSIZE (word) - # of word from CONFBOT to SYSSIZE.
1863; CHKSUM (word) - Sum of every byte from CONFBOT to SYSSIZE in a
1864; word boundary moduler form.
1865; SYSINIT_PTR (dword ptr) - Return address to SYSINIT module.
1866;Note: SYSINIT should save necessary registers and when the control is back
1867
1868
1869 public Sysinit_Base
1870Sysinit_Base: ;AN000;
1871 mov word ptr cs:SYSINIT_BASE_SS, SS ;AN000; save stack
1872 mov word ptr cs:SYSINIT_BASE_SP, SP ;AN000;
1873 int 21h ;AN000; LOAD/EXEC DOS call.
1874 mov SS, word ptr cs:SYSINIT_BASE_SS ;AN000; restore stack
1875 mov SP, word ptr cs:SYSINIT_BASE_SP ;AN000;
1876 pop ds ;AN000; restore CONFBOT seg
1877 pop es ;AN000; restore SYSINITSEG
1878 jc SysInit_Base_End ;AN000; LOAD/EXEC function failed.
1879 ;At this time, I don't have to worry about
1880 ;that SYSINIT module has been broken or not.
1881 call Sum_up ;AN000; Otherwise, check if it is good.
1882 cmp es:CheckSum, AX ;AN000;
1883 je SysInit_Base_End ;AN000;
1884;Memory broken. Show "Memory allocation error" message and stall.
1885 mov ah, 09h ;AN000;
1886 push cs ;AN000;
1887 pop ds ;AN000;
1888 mov dx, Mem_alloc_err_msg ;AN000;
1889 int 21h ;AN000;
1890Stall_now: jmp Stall_now ;AN000;
1891
1892SysInit_Base_End: jmp es:Sysinit_Ptr ;AN000; return back to sysinit module
1893
1894Sum_up: ;AN000;
1895;In:
1896; ES - SYSINITSEG.
1897;OUT: AX - Result
1898;Remark: Since this routine will only check starting from "LocStack" to the end of
1899; Sysinit segment, the data area, and the current stack area are not
1900; coverd. In this sense, this check sum routine only gives a minimal
1901; gaurantee to be safe.
1902;First sum up CONFBOT seg.
1903 push ds ;AN021;
1904 mov ax,es:ConfBot ;AN021;
1905 mov ds,ax ;AN021;
1906 xor si,si ;AN000;
1907 xor ax,ax ;AN000;
1908 mov cx,es:Config_Size ;AN000; If CONFIG_SIZE has been broken, then this
1909 ;whole test better fail.
1910 shr cx, 1 ;AN000; make it a word count
1911 jz Sum_Sys_Code ;AN025; When CONFIG.SYS file not exist.
1912Sum1: ;AN000;
1913 add ax, ds:word ptr [si] ;AN000;
1914 inc si ;AN000;
1915 inc si ;AN000;
1916 loop Sum1 ;AN000;
1917;Now, sum up SYSINIT module.
1918Sum_Sys_Code: ;AN025;
1919 mov si, offset LocStack ;AN000; Starting after the stack.
1920 ;AN000; This does not cover the possible STACK code!!!
1921 mov cx, offset SYSSIZE ;AN000; SYSSIZE is the label at the end of SYSINIT
1922 sub cx, si ;AN000; From After_Checksum to SYSSIZE
1923 shr cx, 1 ;AN000;
1924Sum2: ;AN000;
1925 add ax, es:word ptr [si] ;AN000;
1926 inc si ;AN000;
1927 inc si ;AN000;
1928 loop Sum2 ;AN000;
1929 pop ds ;AN021;
1930 ret ;AN000;
1931
1932Sysinit_Base_SS equ $-Sysinit_Base ;AN000;
1933 dw ? ;AN000;
1934Sysinit_Base_SP equ $-Sysinit_Base ;AN000;
1935 dw ? ;AN000;
1936Mem_Alloc_Err_msg equ $-Sysinit_Base ;AN000;
1937;include BASEMES.INC ;AN000; Memory allocation error message
1938include MSBIO.CL4 ;AN011; Memory allocation error message
1939End_Sysinit_Base label byte ;AN000;
1940SIZE_SYSINIT_BASE equ $-Sysinit_Base ;AN000;
1941
1942;
1943;AN016; Undo the extended attribute handling
1944; public Get_Ext_Attribute
1945;Get_Ext_Attribute proc near ;AN008;
1946;;In: BX - file handle
1947;;Out: AL = The extended attribute got from the handle.
1948;; AX destroyed.
1949;; Carry set when DOS function call fails.
1950;
1951; push ds ;AN008;
1952; push si ;AN008;
1953; push es ;AN008;
1954; push di ;AN008;
1955; push cx ;AN008;
1956;
1957; push cs ;AN008;
1958; pop ds ;AN008;
1959; push cs ;AN008;
1960; pop es ;AN008;
1961;
1962; mov Ext_Attr_Value, 0ffh ;AN008; Initialize to unrealistic value
1963; mov ax, 5702h ;AN008;Get extended attribute by handle thru LIST
1964; mov si, offset EA_QueryList ;AN008;
1965; mov di, offset Ext_Attr_List ;AN008;
1966; mov cx, SIZE_EXT_ATTR_LIST ;AN008;
1967; int 21h ;AN008;
1968; mov al, Ext_Attr_Value ;AN008;
1969; pop cx ;AN008;
1970; pop di ;AN008;
1971; pop es ;AN008;
1972; pop si ;AN008;
1973; pop ds ;AN008;
1974; ret ;AN008;
1975;Get_Ext_Attribute endp ;AN008;
1976
1977
1978;------------------------------------------------------------------------------
1979
1980DoEMS proc near
1981;*******************************************************************************
1982; Function: Called prior to DOBUFF subroutine. Only called when /E option *
1983; for the buffers= command has been specified. *
1984; This routine will check if the extended memory is avaiable, *
1985; and determine what is the page number. We only use physical page *
1986; 254. if it is there, then this routine will calculate the number *
1987; of pages needed for buffers and will allocate logical pages in the *
1988; extended memory and get the page handle of them. *
1989; *
1990; Input : *
1991; Buffers - Number of buffers *
1992; Buffer_LineNum - Saved line number to be used in case of Error case *
1993; *
1994; Output: *
1995; BuffINFO.EMS_Handle *
1996; Buffer_Pages = Number of pages for buffer in the extended memory. *
1997; BuffINFO.EMS_MODE = -1 No extended memory or Non-IBM compatible mode. *
1998; Buffers = the number will be changed to be a multiple of 30. *
1999; Carry set if no extended memory exist or if it is not big enough. *
2000; AX, BX, CX, DX destroyed. *
2001; *
2002; Logic: *
2003; { *
2004; Get EMS Version (AH=46h); *
2005; If (EMS not installed or it is not IBM compatible or *
2006; (Available_pages * 30 < Buffers) then *
2007; {Show error message "Error in CONFIG.SYS line #"; *
2008; Set carry; Exit }; *
2009; else *
2010; Buffer_Pages = Roundup(BUFFERS/30); /* Round up 30 buffers per page*/ *
2011; Buffers = Buffer_Pages * 30; /* Set the new number of Buffers*/*
2012; Allocate Buffer_Pages (AH=43h) and set EMS_Handle; *
2013; }; *
2014; *
2015;*******************************************************************************
2016
2017 push es ;AN000;
2018 push di ;AN000; save es, di
2019 push si ;AN010;
2020 push bx ;AN010;
2021 xor di,di ;AN004; if vector pointer of
2022 mov es, di ;AN004; EMS (INT 67h) is 0,0
2023 mov di, word ptr es:[EMS_INT * 4] ;AN004; then error.
2024 mov ax, word ptr es:[EMS_INT * 4 +2] ;AN009;
2025 or ax,di ;AN009;
2026; $IF NZ,AND,LONG ;AN004;
2027 JNZ $$XL2
2028 JMP $$IF18
2029$$XL2:
2030 les di, cs:[DosInfo] ;AN000; es:di -> SYSINITVAR
2031 les di, es:[di.SYSI_BUF] ;AN000; now, es:di -> BuffInfo
2032
2033 mov ah, EMS_STATUS ;AN000; get the status of EMS = 40h
2034 int EMS_INT ;AN000;
2035 or ah, ah ;AN000; EMS installed?
2036; $IF Z,AND,LONG ;AN000;
2037 JZ $$XL3
2038 JMP $$IF18
2039$$XL3:
2040 mov ah, EMS_VERSION ;AN010;=46h
2041 int EMS_INT ;AN010;
2042 cmp AL, EMSVERSION ;AN010;40h = 4.0
2043; $IF AE,AND,LONG ;AN010;
2044 JAE $$XL4
2045 JMP $$IF18
2046$$XL4:
2047 call Check_IBM_PageID ;AN000; IBM (compatible) mode?
2048
2049IF BUFFERFLAG
2050 mov ax, cs:[LAST_PAGE]
2051 mov es:[di.EMS_LAST_PAGE], ax
2052 mov ax, cs:[LAST_PAGE+2]
2053 mov es:[di.EMS_LAST_PAGE+2], ax
2054 mov ax, cs:[FIRST_PAGE]
2055 mov es:[di.EMS_FIRST_PAGE], ax
2056 mov ax, cs:[FIRST_PAGE+2]
2057 mov es:[di.EMS_FIRST_PAGE+2], ax
2058 mov ax, cs:[NPA640]
2059 mov es:[di.EMS_NPA640], ax
2060 mov es:[di.EMS_SAFE_FLAG], 1
2061ENDIF
2062
2063; $IF NC,AND,LONG ;AN000;
2064 JNC $$XL5
2065 JMP $$IF18
2066$$XL5:
2067 mov ah, EMAP_STATE ;AN010; Check if the size of
2068 mov al, GET_MAP_SIZE ;AN010; the MAP state table
2069 mov bx, 1 ;AN010; # of pages
2070 int EMS_INT ;AN010; is acceptable.
2071 or ah, ah ;AN010;
2072; $IF Z,AND ;AN010;
2073 JNZ $$IF18
2074 cmp al, EMS_MAP_BUFF_SIZE ;AN010; Curretly=12 bytes
2075; $IF BE,AND ;AN010;
2076 JNBE $$IF18
2077 mov ah, EQ_PAGES ;AN000; Get number of unallocated & total pages = 42h
2078 int EMS_INT ;AN000; result in BX
2079 xor dx, dx ;AN000;
2080 mov ax, cs:[Buffers] ;AN000;
2081 mov cx, MAXBUFFINBUCKET*MAXBUCKETINPAGE ;AN000;
2082 call Roundup ;AN000; find out how many pages are needed.
2083 cmp bx, ax ;AN000; AX is the number of pages for [buffers]
2084; $IF AE,AND ;AN000;
2085 JNAE $$IF18
2086 mov cs:[Buffer_Pages], ax ;AN000;
2087 mov bx, ax ;AN000; prepare for Get handle call.
2088 mul cx ;AN000;
2089 mov cs:[Buffers], ax ;AN000; set new [Buffers] for the extended memory.
2090 mov ah, E_GET_HANDLE ;AN000; allocate pages = 43h
2091 int EMS_INT ;AN000; page handle in DX.
2092 or ah, ah ;AN000;
2093; $IF Z ;AN000; pages allocated.
2094 JNZ $$IF18
2095 mov ah, EMS_HANDLE_NAME ;AN010;
2096 mov al, SET_HANDLE_NAME ;AN010;
2097 push es ;AN010;
2098 push di ;AN010;
2099 push ds ;AN010;
2100 push cs ;AN010;
2101 pop ds ;AN010;
2102 mov si, offset EMSHandleName ;AN010;
2103 int EMS_INT ;AN010; Set the handle name
2104 pop ds ;AN010;
2105 pop di ;AN010;
2106 pop es ;AN010;
2107 xor ah,ah ;AN010;
2108 mov es:[di.EMS_MODE], ah ;AN000; put 0 in EMS_mode.
2109 mov es:[di.EMS_HANDLE], dx ;AN000; save EMS handle
2110 mov ax, cs:[IBM_Frame_Seg] ;AN010;
2111 mov es:[di.EMS_PAGE_FRAME],ax ;AN010;
2112 mov ax, cs:[Real_IBM_Page_Id] ;AN029;
2113 mov es:[di.EMS_PAGEFRAME_NUMBER], ax;AN029;
2114 mov ax, es ;AN010;
2115 mov word ptr cs:[EMS_Ctrl_tab+2],ax ;AN010;
2116 mov word ptr cs:[EMS_state_buf+2],ax;AN010;
2117 push di ;AN010;save di-> Buffinfo
2118 add di, EMS_SEG_CNT ;AN010;
2119 mov word ptr cs:[EMS_Ctrl_tab], di ;AN010;
2120 pop di ;AN010;
2121 add di, EMS_MAP_BUFF ;AN010;
2122 mov word ptr cs:[EMS_state_Buf],di ;AN010;
2123 clc ;AN000;
2124; $ELSE ;AN000;
2125 JMP SHORT $$EN18
2126$$IF18:
2127 mov ax, cs:[Buffer_LineNum] ;AN000; Show error message.
2128 push cs:[LineCount] ;AN017; Save current line count
2129 mov cs:[LineCount], ax ;AN000; Now, we can change Linecount
2130 call Error_Line ;AN000; since we are through with CONFIG.SYS file.
2131 pop cs:[LineCount] ;AN017; Restore line count
2132 stc ;AN000;
2133; $ENDIF
2134$$EN18:
2135 pop bx ;AN010;
2136 pop si ;AN010;
2137 pop di ;AN000;
2138 pop es ;AN000;
2139 ret ;AN000;
2140DoEMS endp
2141
2142;
2143Set_Buffer proc near
2144;*******************************************************************************
2145;Function: Set buffers in the real memory. *
2146; For each hash table entry, set the pointer to the *
2147; corresponding hash bucket. *
2148; Lastly set the memhi, memlo for the next available free address. *
2149; ** At the request of IBMDOS, each hash bucket will start at the *
2150; ** new segment. *
2151; *
2152;Input: ds:bx -> BuffInfo. *
2153; [Memhi]:[MemLo = 0] = available space for the hash bucket. *
2154; BufferInfo.Hash_Ptr -> Hash table. *
2155; BufferBuckets = # of buckets to install. *
2156; SingleBufferSize = Buffer header size + Sector size *
2157; MaxNumBuff1 = Number of buffers in the first group of buckets *
2158; MaxNumBuff2 = Number of buffers in the second group of buckets *
2159; NthBuck = 1st thru Nth bucket are the first group *
2160; *
2161;Output: Buffers, hash buckets and Hash table entries established. *
2162; [Memhi]:[Memlo] = address of the next available free space. *
2163; *
2164; { For (every bucket) *
2165; { Set Hash table entry; *
2166; Next buffer ptr = buffer size; *
2167; For (every buffer in the bucket) *
2168; { Calll Set_Buffer_Info; /*Set link, id... */ *
2169; IF (last buffer in a bucket) THEN *
2170; {last buffer's next_ptr -> first buffer; *
2171; first buffer's prev_ptr -> last buffer; *
2172; }; *
2173; Next buffer ptr += buffer size; *
2174; }; *
2175; }; *
2176; MEMHI:MEMLO = Current Buffer_Bucket add + (# of odd * buffer size)*
2177; }; *
2178;*******************************************************************************
2179
2180 assume ds:nothing ;AN000;to make sure.
2181 lds bx, ds:[bx.HASH_PTR] ;AN000;now, ds:bx -> hash table
2182 xor dx, dx ;AN026;To be used to count buckets
2183; $DO ;AN000;For each bucket
2184$$DO21:
2185 inc dl ;AN026; Current bucket number
2186 mov word ptr ds:[bx.BUFFER_BUCKET],0 ;AN000;Memlo is 0 after ROUND.
2187 mov di, [MemHi] ;AN000;
2188 mov word ptr ds:[bx.BUFFER_BUCKET+2], di ;AN000;Hash entry set.
2189 mov word ptr ds:[bx.DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0.
2190 mov es, di ;AN000;
2191 xor di, di ;AN000;es:di -> hash bucket
2192 xor cx, cx ;AN000
2193 xor ax, ax ;AN000
2194; $DO ;AN000;For each buffer in the bucket
2195$$DO22:
2196 call Set_Buffer_Info ;AN000;Set buf_link, buf_id...
2197 inc cx ;AN000;buffer number
2198 cmp dl, [NthBuck] ;AN026;Current bucket number > NthBuck?
2199; $IF BE ;AN026;
2200 JNBE $$IF23
2201 cmp cl, [MaxNumBuf1] ;AN026; last buffer of the 1st group?
2202; $ELSE ;AN026;
2203 JMP SHORT $$EN23
2204$$IF23:
2205 cmp cl, [MaxNumBuf2] ;AN026; last buffer of the 2nd group?
2206; $ENDIF ;AN026;
2207$$EN23:
2208
2209; $IF E ;AN020;Yes, last buffer
2210 JNE $$IF26
2211 mov word ptr es:[di.BUF_NEXT], 0 ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain)
2212 mov word ptr es:[BUF_PREV], di ;AN020;the first buffer's prev -> the last buffer
2213; $ENDIF ;AN020;
2214$$IF26:
2215 mov di, ax ;AN000;adjust next buffer position
2216; $ENDDO E ;AN000;flag set already for testing last buffer.
2217 JNE $$DO22
2218 add [Memlo], ax ;AN000;AX is the size of this bucket.
2219 or [SetDevMarkFlag], FOR_DEVMARK ;AN005;Update DEVMARK_SIZE
2220 call Round ;AN000;memhi:memlo adjusted for the next bucket.
2221 add bx, size BUFFER_HASH_ENTRY ;AN000;ds:bx -> next hash entry.
2222 dec [BufferBuckets] ;AN000;
2223; $ENDDO Z ;AN000;
2224 JNZ $$DO21
2225 ret ;AN000;
2226Set_Buffer endp
2227
2228;
2229Set_EMS_Buffer proc near
2230;*******************************************************************************
2231;Function: Set buffers in the extended memory. *
2232; For each hash table entry, set the pointer to the corresponding *
2233; hash bucket. *
2234; *
2235;Input: ds:bx -> BuffInfo. *
2236; BuffINFO.Hash_Ptr -> Hash table. *
2237; BuffINFO.EMS_Handle = EMS handle *
2238; Buffers = tatal # of buffers to install. *
2239; Multiple of MAXBUFFINBUCKET*MAXBUCKETINPAGE. *
2240; Buffer_Pages = # of extended memory pages for buffers. *
2241; BufferBuckets = # of buckets to install. *
2242; SingleBufferSize = Buffer header size + Sector size. *
2243; *
2244;Output: Buffers, hash buckets and Hash table entries established. *
2245; *
2246; { For (each page) *
2247; { Map the page; /*Map the page into Page frame *
2248; For (each bucket) /*Each page has two buckets */ *
2249; { *
2250; Set EMS_Page; *
2251; Set Buffer_Bucket; *
2252; Next buffer ptr = buffer size; *
2253; For (every buffer) /*A bucket has 15 buffers */ *
2254; { Set Buf_link to Next buffer ptr; *
2255; Set Buffer_ID to free; *
2256; If (last buffer in this bucket) THEN *
2257; {Buf_link = -1; *
2258; Next buffer ptr = 0; *
2259; }; *
2260; Next buffer ptr += buffer size; *
2261; }; *
2262; }; *
2263; }; *
2264; }; *
2265;*******************************************************************************
2266
2267 assume ds:nothing ;AN000;to make sure.
2268
2269IF BUFFERFLAG
2270
2271 push ax
2272 mov ax, offset ems_save_buf
2273 mov word ptr cs:[ems_state_buf], ax
2274 push cs
2275 pop word ptr cs:[ems_state_buf+2]
2276 pop ax
2277
2278ENDIF
2279
2280 call Save_MAP_State ;AN010;
2281 mov dx, es:[bx.EMS_Handle] ;AN000;save EMS_Handle
2282 lds si, ds:[bx.HASH_PTR] ;AN000;now ds:si -> Hash table
2283 xor bx, bx ;AN000;starting logical page number.
2284; $DO ;AN000;For each page,
2285$$DO30:
2286 call Map_Page ;AN000;map it to IBM physical page 254.
2287 mov di, cs:IBM_Frame_Seg ;AN000;
2288 mov es, di ;AN000
2289 xor di, di ;AN000;es:di -> bucket
2290 xor ax, ax ;AN000
2291 xor cx, cx ;AN000
2292; $DO ;AN000;For each bucket,
2293$$DO31:
2294 mov ds:[si.EMS_PAGE_NUM], bx ;AN000;set the logical page number in Hash table.
2295 mov word ptr ds:[si.BUFFER_BUCKET], di ;AN000;set the offset in hash table for this bucket.
2296 mov word ptr ds:[si.BUFFER_BUCKET+2], es ;AN000;set the segment value in hash table.
2297 mov word ptr ds:[si.DIRTY_COUNT], 0 ;AN020;set DIRTY_COUNT, BUFFER_RESERVED to 0.
2298 push cx ;AN000;save bucket number
2299 xor cx, cx ;AN000;
2300; $DO ;AN000;For each buffer in a bucket,
2301$$DO32:
2302 call Set_Buffer_Info ;AN000;AX adjusted for the next buffer.
2303 inc cx ;AN000;inc number of buffers in this bucket.
2304 cmp cx, 1 ;AN020;The first buffer in the bucket?
2305; $IF E ;AN020;
2306 JNE $$IF33
2307 mov cs:[EMS_Buf_First], di ;AN020;then save the offset value
2308; $ENDIF ;AN020;
2309$$IF33:
2310 cmp cx, MAXBUFFINBUCKET ;AN000;
2311; $IF E ;AN000
2312 JNE $$IF35
2313 push word ptr cs:[EMS_Buf_First] ;AN020;
2314 pop word ptr es:[di.BUF_NEXT] ;AN020;the last buffer's next -> the first buffer in bucket (Circular chain)
2315 push di ;AN020;save di
2316 push di ;AN020;di-> last buffer
2317 mov di, cs:[EMS_Buf_First] ;AN020;es:di-> first buffer
2318 pop word ptr es:[di.BUF_PREV] ;AN020;the first buffer's prev -> the last buffer
2319 pop di ;AN020;restore di
2320; $ENDIF ;AN000;
2321$$IF35:
2322 mov di, ax ;AN000;advance di to the next buffer position.
2323; $ENDDO E ;AN000;
2324 JNE $$DO32
2325 add si, size BUFFER_HASH_ENTRY ;AN000;ds:si -> next hash table entry
2326 pop cx ;AN000;restore bucket number
2327 inc cx ;AN000;next bucket
2328 cmp cx, MAXBUCKETINPAGE ;AN000;2 buckets per page
2329; $ENDDO E ;AN000;
2330 JNE $$DO31
2331 inc bx ;AN000;increse logical page number
2332 cmp bx, cs:[Buffer_Pages] ;AN000;reached the maximum page number?
2333; $ENDDO E ;AN000;
2334 JNE $$DO30
2335 call Restore_MAP_State ;AN010;
2336 ret ;AN000;
2337Set_EMS_Buffer endp
2338
2339
2340Set_Buffer_Info proc
2341;Function: Set buf_link, buf_id, Buf_Sector
2342;In: ES:DI -> Buffer header to be set.
2343; AX = DI
2344;Out:
2345; Above entries set.
2346
2347
2348 push [Buf_Prev_Off] ;AN020;
2349 pop es:[di.BUF_PREV] ;AN020;
2350 mov Buf_Prev_Off, ax ;AN020;
2351 add ax, [SingleBufferSize] ;AN000;adjust ax
2352 mov word ptr es:[di.BUF_NEXT], ax ;AN020;
2353 mov word ptr es:[di.BUF_ID], 00FFh ;AN000;new buffer free
2354 mov word ptr es:[di.BUF_SECTOR], 0 ;AN000;To compensate the MASM 3 bug
2355 mov word ptr es:[di.BUF_SECTOR+2],0 ;AN000;To compensate the MASM 3 bug
2356 ret ;AN000;
2357Set_Buffer_Info endp
2358
2359Check_IBM_PageID proc near
2360;Function: check if the physical page 255 exists. (Physical page 255 is only
2361; one we are intereseted in, and this will be used for BUFFER
2362; manipulation by IBMBIO, IBMDOS)
2363;In: nothing
2364;Out: Carry clear and IBM_Frame_Seg set if it exist. All registers saved.
2365 push es ;AN000;
2366 push ax ;AN000;
2367 push bx ;AN000;
2368 push cx ;AN000;
2369 push dx ;AN000;
2370 push di ;AN010;
2371
2372IF NOT BUFFERFLAG
2373
2374 mov ax, 1B00h ;AN029;AN030;AN0 Check EMS int 2fh installed.
2375 int 2fh ;AN029;
2376 cmp al, 0ffh ;AN029;
2377 jne Cp_IBM_Err ;AN029;If not installed, then no IBM page.
2378 mov ax, 1B01h ;AN029;AN030;Then ask if IBM page exists.
2379 mov di, IBM_PAGE_ID ;AN029;=255
2380 int 2fh ;AN029;
2381 or ah, ah ;AN029;
2382 jnz Cp_IBM_Err ;AN029;;No IBM Page
2383 mov cs:IBM_Frame_Seg, es ;AN029;;Save Physical IBM page frame addr.
2384 mov cs:Real_IBM_Page_Id, di ;AN029;;Real page number for it.
2385 clc ;AN029;
2386 jmp short Cp_ID_Ret ;AN029;
2387
2388ELSE
2389 push cs ;AN000;
2390 pop es ;AN000;
2391 mov ah, GET_PAGE_FRAME ;AN010;=58h
2392 mov al, GET_NUM_PAGEFRAME ;AN010;=01h How many page frames?
2393 int EMS_INT ;AN010;
2394 or ah, ah ;AN010;
2395 jnz hkn_err ;AN010;
2396 cmp cx, MAX_NUM_PAGEFRAME ;AN010;
2397 ja hkn_err ;AN010; cannot handle this big number
2398 push cx ;AN010;
2399 mov ah, GET_PAGE_FRAME ;AN010;
2400 mov al, GET_PAGEFRAME_TAB ;AN010;
2401 mov di, offset Frame_info_Buffer ;AN010;
2402 int EMS_INT ;AN010;
2403 pop cx ;AN010;
2404 or ah, ah ;AN010;
2405 jnz cp_IBM_Err ;AN010;
2406Cp_IBM_ID: ;AN010;
2407
2408; mov dx, es:[di]
2409; mov cs:[FIRST_PAGE], dx
2410; mov dx, es:[di+2]
2411; mov cs:[FIRST_PAGE+2], dx
2412
2413 xor dx, dx
2414
2415; int 3
2416find_page:
2417 cmp es:[di], 0a000h ; is current page above 640K
2418 jb next ; NO - goto check_last
2419
2420 inc dx ; count the no. of pages above 640K
2421
2422 cmp dx, 1
2423 jne first_ok
2424
2425 mov ax, es:[di]
2426 mov cs:[FIRST_PAGE], ax
2427 mov ax, es:[di+2]
2428 mov cs:[FIRST_PAGE+2], ax
2429
2430first_ok:
2431 mov ax, cs:[FIRST_PAGE]
2432 cmp ax, es:[di] ; is this page less than the one we have in
2433 ; FIRST_PAGE
2434 jbe check_last ; NO - goto check_last
2435 mov ax, es:[di] ; update FIRST_PAGE with this page segment
2436 mov cs:[FIRST_PAGE], ax
2437 mov ax, es:[di+2]
2438 mov cs:[FIRST_PAGE+2], ax
2439 jmp next
2440
2441hkn_err: jmp cp_ibm_err
2442
2443check_last:
2444 mov ax, cs:[LAST_PAGE] ;
2445 cmp ax, es:[di] ; is this page greater than the one we have in
2446 ; LAST_PAGE?
2447 ja next ; NO - goto next
2448 mov ax, es:[di] ; update LAST_PAGE with this value.
2449 mov cs:[LAST_PAGE], ax
2450 mov ax, es:[di+2]
2451 mov cs:[LAST_PAGE+2], ax
2452
2453next:
2454 add di, 4
2455 loop find_page
2456
2457 cmp dx, 3 ; there should be at least 3 pages
2458 ; above 640K for the buffers to be
2459 ; installed.
2460 jb Cp_IBM_Err
2461
2462 mov ax, cs:[LAST_PAGE]
2463 mov cs:IBM_Frame_Seg, ax
2464 mov ax, cs:[LAST_PAGE+2]
2465 mov cs:Real_IBM_Page_Id, ax
2466 mov cs:[NPA640], dx
2467 clc
2468 jmp short Cp_Id_Ret
2469
2470ENDIF
2471
2472
2473; cmp word ptr es:[di+2], IBM_PAGE_ID ;AN010; the second word is the id
2474; je Got_IBM_ID ;AN010;
2475; add di, 4 ;AN010; advance to the next row (4 bytes)
2476; loop Cp_IBM_ID ;AN010;
2477
2478Cp_IBM_Err: ;AN010;;AN029;
2479 stc ;AN000;;AN029;
2480 jmp short Cp_ID_Ret ;AN000;;AN029;
2481
2482;Got_IBM_ID: ;AN000;
2483; mov ax, word ptr es:[di] ;AN010;Physical seg. addr.
2484; mov cs:IBM_Frame_Seg, ax ;AN000;
2485; clc ;AN000;
2486Cp_ID_Ret: ;AN000;
2487 pop di ;AN010;
2488 pop dx ;AN000;
2489 pop cx ;AN000;
2490 pop bx ;AN000;
2491 pop ax ;AN000;
2492 pop es ;AN000;
2493 ret ;AN000;
2494Check_IBM_PageID endp
2495
2496;
2497Save_Map_State proc ;AN010;
2498;Function: Save the map state.
2499;In)
2500; EMS_Ctrl_Tab = double word pointer to EMS_state control table address
2501; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address
2502;Out) Map state saved
2503 push ax ;AN010;
2504 push ds ;AN010;
2505 push si ;AN010;
2506 push es ;AN010;
2507 push di ;AN010;
2508 lds si, cs:EMS_Ctrl_Tab ;AN010;
2509 les di, cs:EMS_state_Buf ;AN010;
2510 mov ah, EMAP_STATE ;AN010; =4Fh
2511 mov al, GET_MAP_STATE ;AN010; =00h
2512 int EMS_INT ;AN010;
2513 pop di ;AN010;
2514 pop es ;AN010;
2515 pop si ;AN010;
2516 pop ds ;AN010;
2517 pop ax ;AN010;
2518 ret ;AN010;
2519Save_Map_State endp
2520;
2521Restore_Map_State proc ;AN010;
2522 push ax ;AN010;
2523 push ds ;AN010;
2524 push si ;AN010;
2525 lds si, cs:EMS_state_Buf ;AN010;
2526 mov ah, EMAP_STATE ;AN010;
2527 mov al, SET_MAP_STATE ;AN010;
2528 int EMS_INT ;AN010;
2529 pop si ;AN010;
2530 pop ds ;AN010;
2531 pop ax ;AN010;
2532 ret ;AN010;
2533Restore_Map_State endp
2534;
2535Map_Page proc near ;AN000;
2536;Function: Map the logical page in BX of handle in DX to the physical page 255
2537;In)
2538; BX = logical page number
2539; DX = EMS handle
2540; EMS_Ctrl_Tab = double word pointer to EMS_state control table address
2541; EMS_state_Buf = double word pointer to EMS_MAP_BUFF address
2542;Out) Logical page mapped into first phsical page frame.
2543; AX saved.
2544
2545 push ax ;AN000;
2546 mov ah, EMAP_L_TO_P ;AN000;
2547 mov al, byte ptr cs:Real_IBM_PAGE_ID ;AN029;= 255
2548 int EMS_INT ;AN000;
2549 pop ax ;AN000;
2550 ret ;AN000;
2551Map_Page endp ;AN000;
2552;
2553
2554Roundup proc
2555;In: DX;AX - operand
2556; CX - divisor
2557; Important: DX should be less than CX.
2558;out: AX - Quotient (Rounded up)
2559
2560 div cx ;AN000;
2561 or dx, dx ;AN000;
2562 jz RU_ret ;AN000;
2563 inc AX ;AN000;
2564RU_ret: ;AN000;
2565 ret ;AN000;
2566Roundup endp
2567;------------------------------------------------------------------------------
2568;J.K. 5/6/86. IBMSTACK initialization routine.
2569 IF STACKSW
2570.SALL
2571
2572INCLUDE STKINIT.INC
2573
2574.XALL
2575 ENDIF
2576;------------------------------------------------------------------------------
2577 public SetDevMark
2578SetDevMark proc
2579;Set the DEVMARK for MEM command.
2580;In: [MEMHI] - the address to place DEVMARK
2581; [MEMLO] = 0
2582; AL = ID for DEVMARK_ID
2583;OUT: DEVMARK established.
2584; the address saved in cs:[DevMark_Addr]
2585; [MEMHI] increase by 1.
2586
2587 push es ;AN005;
2588 push cx ;AN005;
2589
2590 mov cx, cs:[memhi] ;AN005;
2591 mov cs:[DevMark_Addr],cx ;AN005;
2592 mov es, cx ;AN005;
2593 mov es:[DEVMARK_ID], al ;AN005;
2594 inc cx ;AN007;
2595 mov es:[DEVMARK_SEG], cx ;AN007;
2596
2597 pop cx ;AN005;
2598 pop es ;AN005;
2599 inc cs:[memhi] ;AN005;
2600 ret ;AN005;
2601SetDevMark endp
2602
2603;*******************************************************************************
2604;Function: Load SHARE.EXE, if Big_Media_Flag = 1 and SHARE.EXE has not been *
2605; loaded yet. *
2606; This routine will use the same path for SHELL= command. *
2607; If SHELL= command has not been entered, then default to the root *
2608; directory. *
2609; If load fails, then issue message "Warning: SHARE.EXE not loaded" *
2610; *
2611;Input: Big_Media_Flag, COMMND *
2612;Output: Share.exe loaded if necessary. *
2613; *
2614;*******************************************************************************
2615LoadShare proc near ;AN021;
2616 cmp Big_Media_Flag, 1 ;AN021;
2617 jne LShare_Ret ;AN021;
2618;Check if SHARE is already loaded.
2619 mov ax, 1000h ;AN021;multShare installation check
2620 int 2fh ;AN021;
2621 cmp al, 0ffh ;AN021;
2622 jz LShare_Ret ;AN021;Share already loaded!
2623;SHARE not loaded.
2624 push cs ;AN021;
2625 pop ds ;AN021;
2626 push cs ;AN021;
2627 pop es ;AN021;
2628 mov si, offset COMMND ;AN021;
2629 mov di, offset PathString ;AN021;
2630LShare_String: ;AN021;
2631 movsb ;AN021;
2632 cmp byte ptr [di-1], 0 ;AN021;reached to the end?
2633 jne LShare_string ;AN021;
2634 mov si, offset PathString ;AN021;SI= start of PathString
2635LShare_Tail: ;AN021;
2636 dec di ;AN021;
2637 cmp byte ptr [di], "\" ;AN021;
2638 je LShare_Got_Tail ;AN021;
2639 cmp byte ptr [di], ":" ;AN021;
2640 je LShare_Got_Tail ;AN021;
2641 cmp di, si ;AN021;No path case (e.g. SHELL=command.com)
2642 je LShare_Got_Tail_0 ;AN021;
2643 jmp LShare_Tail ;AN021;
2644LShare_Got_Tail: ;AN021;di -> "\" or ":"
2645 inc di ;AN021;
2646LShare_Got_Tail_0: ;AN021;
2647 mov si, offset LShare ;AN021;
2648LShare_Set_Filename: ;AN021;
2649 movsb ;AN021;Tag "SHARE.EXE",0,0Ah to the path.
2650 cmp byte ptr [di-1], 0Ah ;AN021;Line feed?
2651 jne LShare_Set_Filename ;AN021;
2652;Now, we got a path,filename with no parameters for SHARE.EXE
2653 mov si, offset PathString ;AN021;
2654 or Install_Flag, SHARE_INSTALL ;AN021;Signals Do_Install_Exec that this is for SHARE.EXE.
2655 call Do_Install_Exec ;AN021;execute it.
2656 jnc LShare_Ret ;AN021;No problem
2657;Load/Exec failed. Show "Warning: SHARE should be loaded for large media"
2658 push cs ;AN021;
2659 pop ds ;AN021;
2660 mov dx, offset ShareWarnMsg ;AN021;WARNING! SHARE should be loaded...
2661 invoke Print ;AN021;
2662LShare_Ret: ;AN021;
2663 ret ;AN021;
2664LoadShare endp ;AN021;
2665
2666SYSINITSEG ENDS
2667 END
2668 \ No newline at end of file
diff --git a/v4.0/src/BIOS/SYSINIT2.ASM b/v4.0/src/BIOS/SYSINIT2.ASM
new file mode 100644
index 0000000..ff8b8ae
--- /dev/null
+++ b/v4.0/src/BIOS/SYSINIT2.ASM
@@ -0,0 +1,1624 @@
1 PAGE ,132 ;
2; SCCSID = @(#)sysinit2.asm 1.13 85/10/15
3TITLE BIOS SYSTEM INITIALIZATION
4%OUT ...SYSINIT2
5
6;==============================================================================
7;REVISION HISTORY:
8;AN000 - New for DOS Version 4.00 - J.K.
9;AC000 - Changed for DOS Version 4.00 - J.K.
10;AN00x - PTM number for DOS Version 4.00 - J.K.
11;==============================================================================
12;AN001; p132 Multiple character device installation problem. 6/27/87 J.K.
13;AN002; d24 MultiTrack= command added. 6/29/87 J.K.
14;AN003; p29 Extra space character in parameters passed.
15; (Modification on ORGANIZE routine for COMMENT= fixed this
16; problem too) 6/29/87 J.K.
17;AN004; d41 REM command in CONFIG.SYS 7/7/87 J.K.
18;AN005; d184 Set DEVMARK for MEM command 8/25/87 J.K.
19;AN006; p1820 New Message SKL file 10/20/87 J.K.
20;AN007; p1821 Include the COPYRIGH.INC file 10/22/87 J.K.
21;AN008; p2210 IBMDOS returns incorrect DBCS vector table length 11/02/87 J.K.
22;AN009; p2667 ccMono_Ptr problem 11/30/87 J.K.
23;AN010; p2792 Device?driver.sys /d:2 command should not work 12/09/87 J.K.
24;AN011; p3120 REM followed by CR, LF causes problem 01/13/88 J.K.
25;AN012; p3111 Take out the order dependency of the INSTALL= 01/25/88 J.K.
26;AN013; d479 New option to disable extended INT 16h function call 02/12/88 J.K.
27;AN014; D486 SHARE installation for big media 02/23/88 J.K.
28;AN015; D526 Add /NC parameter when installing SHARE.EXE 04/28/88 J.K.
29;==============================================================================
30
31TRUE EQU 0FFFFh
32FALSE EQU 0
33LF equ 10
34CR equ 13
35TAB equ 9
36
37IBMVER EQU TRUE
38IBM EQU IBMVER
39STACKSW EQU TRUE ;Include Switchable Hardware Stacks
40IBMJAPVER EQU FALSE ;If TRUE set KANJI true also
41MSVER EQU FALSE
42ALTVECT EQU FALSE ;Switch to build ALTVECT version
43KANJI EQU FALSE
44
45 IF IBMJAPVER
46NOEXEC EQU TRUE
47 ELSE
48NOEXEC EQU FALSE
49 ENDIF
50
51DOSSIZE EQU 0A000H
52
53.xlist
54; INCLUDE dossym.INC
55 include smdossym.inc ;J.K. Reduced version of DOSSYM.INC
56 INCLUDE devsym.INC
57 include ioctl.INC
58 include DEVMARK.inc
59.list
60
61 IF NOT IBM
62 IF NOT IBMJAPVER
63 EXTRN RE_INIT:FAR
64 ENDIF
65 ENDIF
66
67code segment public 'code'
68 extrn EC35_Flag: byte
69code ends
70
71SYSINITSEG SEGMENT PUBLIC 'SYSTEM_INIT' BYTE
72
73ASSUME CS:SYSINITSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
74
75 EXTRN BADOPM:BYTE,CRLFM:BYTE,BADCOM:BYTE,BADMEM:BYTE,BADBLOCK:BYTE
76 EXTRN BADSIZ_PRE:BYTE,BADLD_PRE:BYTE
77; EXTRN BADSIZ_POST:BYTE,BADLD_POST:BYTE
78 EXTRN SYSSIZE:BYTE,BADCOUNTRY:BYTE
79
80 EXTRN dosinfo:dword,entry_point:dword,
81 EXTRN MEMORY_SIZE:WORD,fcbs:byte,keep:byte
82 EXTRN DEFAULT_DRIVE:BYTE,confbot:word,alloclim:word
83 EXTRN BUFFERS:WORD,zero:byte,sepchr:byte
84 EXTRN FILES:BYTE
85 EXTRN count:word,chrptr:word
86 EXTRN bufptr:byte,memlo:word,prmblk:byte,memhi:word
87 EXTRN ldoff:word,area:word,PACKET:BYTE,UNITCOUNT:BYTE,
88 EXTRN BREAK_ADDR:DWORD,BPB_ADDR:DWORD,drivenumber:byte
89 extrn COM_Level:byte, CMMT:byte, CMMT1:byte, CMMT2:byte
90 extrn Cmd_Indicator:byte
91 extrn DoNotShowNum:byte
92 extrn MultDeviceFlag:byte
93 extrn DevMark_Addr:word ;AN005;
94 extrn SetDevMarkFlag:byte ;AN005;
95 extrn Org_Count:word ;AN012;
96
97 EXTRN Stall:near
98 EXTRN Error_Line:near
99
100 PUBLIC Int24,Open_Dev,Organize,Mem_Err,Newline,CallDev,Badload
101 PUBLIC PrnDev,AuxDev,Config,Commnd,Condev,GetNum,BadFil,PrnErr
102 PUBLIC Round,Delim,Print,Set_Break
103 PUBLIC SetParms, ParseLine, DiddleBack
104 PUBLIC Skip_delim,SetDOSCountryInfo,Set_Country_Path,Move_Asciiz
105 PUBLIC Cntry_Drv,Cntry_Root,Cntry_Path
106 PUBLIC Delim
107 public PathString ;AN014;
108 public LShare ;AN014;
109
110;
111; The following set of routines is used to parse the DRIVPARM = command in
112; the CONFIG.SYS file to change the default drive parameters.
113;
114SetParms:
115 push ds
116 push ax
117 push bx
118 push cx
119 push dx
120 push cs
121 pop ds
122 ASSUME DS:SYSINITSEG
123 xor bx,bx
124 mov bl,byte ptr drive
125 inc bl ; get it correct for IOCTL call (1=A,2=B...)
126 mov dx,offset DeviceParameters
127 mov ah, IOCTL
128 mov al, GENERIC_IOCTL
129 mov ch, RAWIO
130 mov cl, SET_DEVICE_PARAMETERS
131 int 21H
132 test word ptr Switches, flagec35
133 jz Not_EC35
134
135 mov cl, byte ptr drive ; which drive was this for?
136 mov ax, Code ; get Code segment
137 mov ds, ax ; set code segment
138 assume ds:code
139 mov al, 1 ; assume drive 0
140 shl al, cl ; set proper bit depending on drive
141 or ds:EC35_Flag, al ; set the bit in the permanent flags
142
143Not_EC35:
144 pop dx ; fix up all the registers
145 pop cx
146 pop bx
147 pop ax
148 pop ds
149 assume ds:nothing
150 ret
151
152;
153; Replace default values for further DRIVPARM commands
154;
155DiddleBack:
156 push ds
157 push cs
158 pop ds
159 assume ds:sysinitseg
160 mov word ptr DeviceParameters.DP_Cylinders,80
161 mov byte ptr DeviceParameters.DP_DeviceType, DEV_3INCH720KB
162 mov word ptr DeviceParameters.DP_DeviceAttributes,0
163 mov word ptr switches,0 ; zero all switches
164 pop ds
165 assume ds:nothing
166 ret
167
168;
169; Entry point is ParseLine. AL contains the first character in command line.
170;
171ParseLine: ; don't get character first time
172 push ds
173 push cs
174 pop ds
175 ASSUME DS:SYSINITSEG
176NextSwtch:
177 cmp al,CR ; carriage return?
178 jz done_line
179 cmp al,LF ; linefeed?
180 jz put_back ; put it back and done
181; Anything less or equal to a space is ignored.
182 cmp al,' ' ; space?
183 jbe get_next ; skip over space
184 cmp al,'/'
185 jz getparm
186 stc ; mark error invalid-character-in-input
187 jmp short exitpl
188
189getparm:
190 call Check_Switch
191 mov word ptr Switches,BX ; save switches read so far
192 jc swterr
193get_next:
194 invoke getchr
195 jc done_line
196 jmp NextSwtch
197swterr:
198 jmp exitpl ; exit if error
199
200done_line:
201 test word ptr Switches,flagdrive ; see if drive specified
202 jnz okay
203 stc ; mark error no-drive-specified
204 jmp short exitpl
205
206okay:
207 mov ax,word ptr switches
208 and ax,0003H ; get flag bits for changeline and non-rem
209 mov word ptr DeviceParameters.DP_DeviceAttributes,ax
210 mov word ptr DeviceParameters.DP_TrackTableEntries, 0
211 clc ; everything is fine
212 call SetDeviceParameters
213exitpl:
214 pop ds
215 ret
216
217put_back:
218 inc count ; one more char to scan
219 dec chrptr ; back up over linefeed
220 jmp short done_line
221;
222; Processes a switch in the input. It ensures that the switch is valid, and
223; gets the number, if any required, following the switch. The switch and the
224; number *must* be separated by a colon. Carry is set if there is any kind of
225; error.
226;
227Check_Switch:
228 invoke getchr
229 jc err_check
230 and al,0DFH ; convert it to upper case
231 cmp al,'A'
232 jb err_check
233 cmp al,'Z'
234 ja err_check
235 push es
236 push cs
237 pop es
238 mov cl,byte ptr switchlist ; get number of valid switches
239 mov ch,0
240 mov di,1+offset switchlist ; point to string of valid switches
241 repne scasb
242 pop es
243 jnz err_check
244 mov ax,1
245 shl ax,cl ; set bit to indicate switch
246 mov bx,word ptr switches ; get switches so far
247 or bx,ax ; save this with other switches
248 mov cx,ax
249 test ax, switchnum ; test against switches that require number to follow
250 jz done_swtch
251 invoke getchr
252 jc err_Swtch
253 cmp al,':'
254 jnz err_swtch
255 invoke getchr
256 push bx ; preserve switches
257 mov byte ptr cs:sepchr,' ' ; allow space separators
258 call GetNum
259 mov byte ptr cs:sepchr,0
260 pop bx ; restore switches
261; Because GetNum does not consider carriage-return or line-feed as OK, we do
262; not check for carry set here. If there is an error, it will be detected
263; further on (hopefully).
264 call Process_Num
265
266done_swtch:
267 clc
268 ret
269
270err_swtch:
271 xor bx,cx ; remove this switch from the records
272err_check:
273 stc
274 ret
275
276;
277; This routine takes the switch just input, and the number following (if any),
278; and sets the value in the appropriate variable. If the number input is zero
279; then it does nothing - it assumes the default value that is present in the
280; variable at the beginning. Zero is OK for form factor and drive, however.
281;
282Process_Num:
283 test word ptr Switches,cx ; if this switch has been done before,
284 jnz done_ret ; ignore this one.
285 test cx,flagdrive
286 jz try_f
287 mov byte ptr drive,al
288 jmp short done_ret
289
290try_f:
291 test cx,flagff
292 jz try_t
293; Ensure that we do not get bogus form factors that are not supported
294 ;cmp al,Max_Dev_Type
295 ;ja done_ret
296 mov byte ptr DeviceParameters.DP_DeviceType,al
297 jmp short done_ret
298
299try_t:
300 or ax,ax
301 jz done_ret ; if number entered was 0, assume default value
302 test cx,flagcyln
303 jz try_s
304 mov word ptr DeviceParameters.DP_Cylinders,ax
305 jmp short done_ret
306
307try_s:
308 test cx,flagseclim
309 jz try_h
310 mov word ptr slim,ax
311 jmp short done_ret
312;
313; Must be for number of heads
314try_h:
315 mov word ptr hlim,ax
316
317done_ret:
318 clc
319 ret
320
321;
322; SetDeviceParameters sets up the recommended BPB in each BDS in the
323; system based on the form factor. It is assumed that the BPBs for the
324; various form factors are present in the BPBTable. For hard files,
325; the Recommended BPB is the same as the BPB on the drive.
326; No attempt is made to preserve registers since we are going to jump to
327; SYSINIT straight after this routine.
328;
329SetDeviceParameters:
330 push es
331 push cs
332 pop es
333ASSUME ES:SYSINITSEG
334 xor bx,bx
335 mov bl,byte ptr DeviceParameters.DP_DeviceType
336 cmp bl,DEV_5INCH
337 jnz Got_80
338 mov cx,40 ; 48tpi has 40 cylinders
339 mov word ptr DeviceParameters.DP_Cylinders,cx
340Got_80:
341 shl bx,1 ; get index into BPB table
342 mov si,offset BPBTable
343 mov si,word ptr [si+bx] ; get address of BPB
344Set_RecBPB:
345 mov di,offset DeviceParameters.DP_BPB ; es:di -> BPB
346 mov cx,size a_BPB
347 cld
348 repe movsb
349 pop es
350ASSUME ES:NOTHING
351 test word ptr switches,flagseclim
352 jz see_heads
353 mov ax,word ptr slim
354 mov word ptr DeviceParameters.DP_BPB.BPB_SectorsPerTrack,ax
355see_heads:
356 test word ptr switches,flagheads
357 jz Set_All_Done
358 mov ax,word ptr hlim
359 mov word ptr DeviceParameters.DP_BPB.BPB_Heads,ax
360;
361; We need to set the media byte and the total number of sectors to reflect the
362; number of heads. We do this by multiplying the number of heads by the number
363; of 'sectors per head'. This is not a fool-proof scheme!!
364;
365 mov cx,ax ; cx has number of heads
366 dec cl ; get it 0-based
367 mov ax,DeviceParameters.DP_BPB.BPB_TotalSectors ; this is OK for two heads
368 sar ax,1 ; ax contains # of sectors/head
369 sal ax,cl
370 jc Set_All_Done ; We have too many sectors - overflow!!
371 mov DeviceParameters.DP_BPB.BPB_TotalSectors,ax
372; Set up correct Media Descriptor Byte
373 cmp cl,1
374 mov bl,0F0H
375 mov al,2 ; AL contains sectors/cluster
376 ja Got_Correct_Mediad
377 mov bl,byte ptr DeviceParameters.DP_BPB.BPB_MediaDescriptor
378 je Got_Correct_Mediad
379; We have one head - OK for 48tpi medium
380 mov al,1 ; AL contains sectors/cluster
381 mov ch,DeviceParameters.DP_DeviceType
382 cmp ch,DEV_5INCH
383 jz Dec_Mediad
384 mov bl,0F0H
385 jmp short Got_Correct_Mediad
386Dec_Mediad:
387 dec bl ; adjust for one head
388Got_Correct_Mediad:
389 mov byte ptr DeviceParameters.DP_BPB.BPB_MediaDescriptor,bl
390 mov byte ptr DeviceParameters.DP_BPB.BPB_SectorsPerCluster,al
391 clc
392Set_All_Done:
393 RET
394
395ASSUME DS:NOTHING, ES:NOTHING
396
397NOCHAR1: STC
398 return
399
400ORGANIZE:
401 MOV CX,[COUNT]
402 JCXZ NOCHAR1
403 CALL MAPCASE
404 XOR SI,SI
405 MOV DI,SI
406 xor ax,ax
407 mov COM_Level, 0
408
409;ORG1: CALL GET ;SKIP LEADING CONTROL CHARACTERS
410; CMP AL,' '
411; JB ORG1
412Org1:
413 call Skip_Comment ;AN000;
414 jz End_Commd_Line ;AN000; found a comment string and skipped.
415 call Get2 ;AN000; Not a comment string. Then get a char.
416 cmp al, LF ;AN000;
417 je End_Commd_Line ;AN000; starts with a blank line.
418 cmp al, ' ' ;AN000;
419 jbe Org1 ;AN000; skip leading control characters
420 jmp Findit ;AN000;
421End_Commd_Line: ;AN000;
422 stosb ;AN000; store line feed char in buffer for the LineCount.
423 mov COM_Level, 0 ;AN000; reset the command level.
424 jmp Org1 ;AN000;
425Findit: ;AN000;
426 PUSH CX
427 PUSH SI
428 PUSH DI
429 MOV BP,SI
430 DEC BP
431 MOV SI,OFFSET COMTAB ;Prepare to search command table
432 MOV CH,0
433FINDCOM:
434 MOV DI,BP
435 MOV CL,[SI]
436 INC SI
437 JCXZ NOCOM
438 REPE CMPSB
439 LAHF
440 ADD SI,CX ;Bump to next position without affecting flags
441 SAHF
442 LODSB ;Get indicator letter
443 JNZ FINDCOM
444 cmp byte ptr es:[di], CR ;AN011;The next char might be CR,LF
445 je GotCom0 ;AN011; such as in "REM",CR,LF case.
446 cmp byte ptr es:[di], LF ;AN011;
447 je GotCom0 ;AN011;
448 push ax ;AN010;
449 mov al, byte ptr es:[di] ;AN010;Now the next char. should be a delim.
450 call delim ;AN010;
451 pop ax ;AN010;
452 jnz findcom ;AN010;
453GotCom0:
454 POP DI
455 POP SI
456 POP CX
457 JMP SHORT GOTCOM
458
459NOCOM:
460 POP DI
461 POP SI
462 POP CX
463 MOV AL,'Z'
464 stosb ;AN000; save indicator char.
465Skip_Line: ;AN000;
466 call Get2 ;AN000;
467 cmp al, LF ;AN000; skip this bad command line
468 jne Skip_Line ;AN000;
469 jmp End_Commd_Line ;AN000; handle next command line
470
471GOTCOM: STOSB ;SAVE INDICATOR CHAR IN BUFFER
472 mov Cmd_Indicator, al ;AN000; save it for the future use.
473
474ORG2: CALL GET2 ;SKIP the commad name UNTIL DELIMITER
475 cmp al, LF ;AN011;
476 je Org21 ;AN011;
477 cmp al, CR ;AN011;
478 je Org21 ;AN011;
479 CALL DELIM ;
480 JNZ ORG2
481 jmp short Org3 ;AN011;
482Org21: ;AN011;if CR or LF then
483 dec si ;AN011; undo SI, CX register
484 inc cx ;AN011; and continue
485
486;ORG4: CALL GET2
487; call Delim ;J.K. 5/30/86. To permit "device=filename/p..." stuff.
488; jz ORG_EXT ;J.K. 5/30/86
489;Org4_Cont:
490; STOSB
491; CMP AL,' '
492; JA ORG4
493; CMP AL,10
494; JZ ORG1
495;
496; MOV BYTE PTR ES:[DI-1],0
497
498Org3:
499 cmp Cmd_Indicator, 'Y' ;AN000; Comment= command?
500 je Get_Cmt_Token ;AN000;
501 cmp Cmd_Indicator, 'I' ;AN000; Install= command?
502 je Org_file ;AN000;
503 cmp Cmd_Indicator, 'D' ;AN000; Device= command?
504 je Org_file ;AN000;
505 cmp Cmd_Indicator, 'J' ;AN000; IFS= command?
506 je Org_file ;AN000;
507 cmp Cmd_Indicator, 'S' ;AN000; Shell= is a special one!!!
508 je Org_file ;AN000;
509 cmp Cmd_Indicator, '1' ;AN013; SWITCHES= command?
510 je Org_Switch ;AN013;
511 jmp Org4 ;AN000;
512Org_Switch:
513 call Skip_Comment ;AN013;
514 jz End_Commd_Line_Brdg ;AN013;
515 call Get2 ;AN013;
516 call Org_Delim ;AN013;
517 jz Org_Switch ;AN013;
518 stosb ;AN013;
519 jmp Org5 ;AN013;
520Org_file: ;AN000; Get the filename and put 0 at end,
521 call Skip_Comment ;AN000;
522 jz Org_Put_Zero ;AN000;
523 call Get2 ;AN000; Not a comment
524 call Delim ;AN000;
525 jz Org_file ;AN000; Skip the possible delimeters
526 stosb ;AN000; copy the first non delim char found in buffer
527Org_Copy_File: ;AN000;
528 call Skip_Comment ;AN000; comment char in the filename?
529 jz Org_Put_Zero ;AN000; then stop copying filename at that point
530 call Get2 ;AN000;
531 cmp al, '/' ;AN000; a switch char? (device=filename/xxx)
532 je End_File_slash ;AN000; this will be the special case.
533 stosb ;AN000; save the char. in buffer
534 call Delim ;AN000;
535 jz End_Copy_File ;AN000;
536 cmp al, ' ' ;AN000;
537 ja Org_Copy_File ;AN000; keep copying
538 jmp End_Copy_File ;AN000; otherwise, assume end of the filename.
539Get_Cmt_token: ;AN000; get the token. Just max. 2 char.
540 call Get2 ;AN000;
541 cmp al, ' ' ;AN000; skip white spaces or "=" char.
542 je Get_Cmt_Token ;AN000; (we are allowing the other special
543 cmp al, TAB ;AN000; charaters can used for comment id.
544 je Get_Cmt_Token ;AN000; character.)
545 cmp al, '=' ;AN000; = is special in this case.
546 je Get_Cmt_Token ;AN000;
547 cmp al, CR ;AN000;
548 je Get_Cmt_End ;AN000; cannot accept the carridge return
549 cmp al, LF ;AN000;
550 je Get_Cmt_End ;AN000;
551 mov CMMT1, al ;AN000; store it
552 mov CMMT, 1 ;AN000; 1 char. so far.
553 call Get2 ;AN000;
554 cmp al, ' ' ;AN000;
555 je Get_Cmt_End ;AN000;
556 cmp al, TAB ;AN000;
557 je Get_Cmt_End ;AN000;
558 cmp al, CR ;AN000;
559 je Get_Cmt_End ;AN000;
560 cmp al, LF ;AN000;
561 je End_Commd_Line_Brdg ;AN000;
562 mov CMMT2, al ;AN000;
563 inc CMMT ;AN000;
564Get_Cmt_End: ;AN000;
565 call Get2 ;AN000;
566 cmp al, LF ;AN000;
567 jne Get_Cmt_End ;AN000; skip it.
568End_Commd_Line_Brdg: jmp End_Commd_Line ;AN000; else jmp to End_Commd_Line
569
570Org_Put_Zero: ;AN000; Make the filename in front of
571 mov byte ptr es:[di], 0 ;AN000; the comment string to be an asciiz.
572 inc di ;AN000;
573 jmp End_Commd_Line ;AN000; (Maybe null if device=/*)
574End_file_slash: ;AN000; AL = "/" option char.
575 mov byte ptr es:[di],0 ;AN000; make a filename an asciiz
576 inc di ;AN000; and
577 stosb ;AN000; store "/" after that.
578 jmp Org5 ;AN000; continue with the rest of the line
579
580End_Copy_File: ;AN000;
581 mov byte ptr es:[di-1], 0 ;AN000; make it an asciiz and handle the next char.
582 cmp al, LF ;AN000;
583 je End_Commd_Line_brdg ;AN000;
584 jmp Org5 ;AN000;
585
586Org4: ;AN000; Org4 skips all delimiters after the command name except for '/'
587 call Skip_Comment ;AN000;
588 jz End_Commd_Line_brdg ;AN000;
589 call Get2 ;AN000;
590 call Org_Delim ;AN000; skip delimiters EXCEPT '/' (mrw 4/88)
591 jz Org4 ;AN000;
592 jmp Org51 ;AN000;
593Org5: ;AN000; rest of the line
594 call Skip_Comment ;AN000; Comment?
595 jz End_Commd_Line_brdg ;AN000;
596 call Get2 ;AN000; Not a comment.
597Org51: ;AN000;
598 stosb ;AN000; copy the character
599 cmp al, '"' ;AN000; a quote ?
600 je At_Quote ;AN000;
601 cmp al, ' ' ;AN000;
602 ja Org5 ;AN000;
603 cmp al, LF ;AN000; line feed?
604 je Org1_brdg ;AN000; handles the next command line.
605 jmp Org5 ;AN000; handles next char in this line.
606Org1_brdg: jmp Org1 ;AN000;
607At_Quote: ;AN000;
608 cmp COM_Level, 0 ;AN000;
609 je Up_Level ;AN000;
610 mov COM_Level, 0 ;AN000; reset it.
611 jmp Org5 ;AN000;
612Up_Level: ;AN000;
613 inc COM_level ;AN000; set it.
614 jmp Org5 ;AN000;
615
616
617;ORG5: CALL GET2
618; STOSB
619; CMP AL,10
620; JNZ ORG5
621; JMP ORG1
622;
623;ORG_EXT:
624; cmp al,' ' ;space?
625; je Org4_Cont ;then do not make an exception. Go back.
626; cmp al,9 ;Tab?
627; je Org4_Cont
628; mov byte ptr es:[di], 0 ;put 0 at the current DI to make it an ASCIIZ
629; inc DI ;
630; stosb ;and copy the delimeter char.
631; jmp short ORG5 ;and continue as usual.
632
633
634GET2:
635 JCXZ NOGET
636 MOV AL,ES:[SI]
637 INC SI
638 DEC CX
639 return
640
641;GET: JCXZ NOGET
642; MOV AL,ES:[SI]
643; INC SI
644; DEC CX
645; CALL Org_DELIM
646; JZ GET
647; return
648
649Skip_Comment:
650;J.K.Skip the commented string until LF, if current es:si-> a comment string.
651;J.K.In) ES:SI-> sting
652;J.K. CX -> length.
653;J.K.Out) Zero flag not set if not found a comment string.
654;J.K. Zero flag set if found a comment string and skipped it. AL will contain
655;J.K. the line feed charater at this moment when return.
656;J.K. AX register destroyed.
657;J.K. If found, SI, CX register adjusted accordingly.
658
659 jcxz NoGet ;AN000; Get out of the Organize routine.
660 cmp COM_Level, 0 ;AN000; only check it if parameter level is 0.
661 jne No_Commt ;AN000; (Not inside quotations)
662
663 cmp CMMT, 1 ;AN000;
664 jb No_Commt ;AN000;
665 mov al, es:[si] ;AN000;
666 cmp CMMT1, al ;AN000;
667 jne No_Commt ;AN000;
668 cmp CMMT, 2 ;AN000;
669 jne Skip_Cmmt ;AN000;
670 mov al, es:[si+1] ;AN000;
671 cmp CMMT2, al ;AN000;
672 jne No_Commt ;AN000;
673Skip_Cmmt: ;AN000;
674 jcxz NoGet ;AN000; get out of Organize routine.
675 mov al, es:[si] ;AN000;
676 inc si ;AN000;
677 dec cx ;AN000;
678 cmp al, LF ;AN000; line feed?
679 jne Skip_Cmmt ;AN000;
680No_Commt: ;AN000;
681 ret ;AN000;
682
683
684DELIM:
685 CMP AL,'/' ;J.K. 5/30/86. IBM will assume "/" as an delimeter.
686 retz
687 cmp al, 0 ;J.K. 5/23/86 Special case for sysinit!!!
688 retz
689Org_Delim: ;AN000; Used by Organize routine except for getting
690 CMP AL,' ' ;the filename.
691 retz
692 CMP AL,9
693 retz
694 CMP AL,'='
695 retz
696 CMP AL,','
697 retz
698 CMP AL,';'
699 return
700
701
702NOGET: POP CX
703 MOV COUNT,DI
704 mov Org_Count, DI ;AN012;
705 XOR SI,SI
706 MOV CHRPTR,SI
707 return
708
709;Get3: jcxz NOGET ;J.K.do not consider '/',',' as a delim.
710; mov al, es:[si]
711; inc si
712; dec cx
713; call DELIM
714; jnz Get3_ret
715; cmp al,'/'
716; je Get3_ret
717; cmp al,','
718; jne Get3
719;Get3_ret:
720; ret
721
722
723
724;
725; NEWLINE RETURNS WITH FIRST CHARACTER OF NEXT LINE
726;
727NEWLINE:invoke GETCHR ;SKIP NON-CONTROL CHARACTERS
728 retc
729 CMP AL,LF ;LOOK FOR LINE FEED
730 JNZ NEWLINE
731 invoke GETCHR
732 return
733
734MAPCASE:
735 PUSH CX
736 PUSH SI
737 PUSH DS
738 PUSH ES
739 POP DS
740 XOR SI,SI
741CONVLOOP:
742 LODSB
743
744 IF KANJI
745 CALL TESTKANJ
746 JZ NORMCONV
747 INC SI ;Skip next char
748 DEC CX
749 JCXZ CONVDONE ;Just ignore 1/2 kanji error
750;Fall through, know AL is not in 'a'-'z' range
751NORMCONV:
752 ENDIF
753
754 CMP AL,'a'
755 JB NOCONV
756 CMP AL,'z'
757 JA NOCONV
758 SUB AL,20H
759 MOV [SI-1],AL
760NOCONV:
761 LOOP CONVLOOP
762CONVDONE:
763 POP DS
764 POP SI
765 POP CX
766 return
767
768 IF KANJI
769TESTKANJ:
770 CMP AL,81H
771 JB NOTLEAD
772 CMP AL,9FH
773 JBE ISLEAD
774 CMP AL,0E0H
775 JB NOTLEAD
776 CMP AL,0FCH
777 JBE ISLEAD
778NOTLEAD:
779 PUSH AX
780 XOR AX,AX ;Set zero
781 POP AX
782 return
783
784ISLEAD:
785 PUSH AX
786 XOR AX,AX ;Set zero
787 INC AX ;Reset zero
788 POP AX
789 return
790 ENDIF
791
792ASSUME DS:NOTHING
793
794Yes_Break_Failed: ;device driver Init failed and aborted.
795 stc
796 pop ax
797 return
798
799SET_BREAK:
800;J.K. 8/14/86 For DOS 3.3, this routine is modified to take care of the
801;Device driver's initialization error and abort.
802;If [break_addr+2] == [memhi] && [break_addr] = 0 then assume
803;that the device driver's initialization has an error and wanted to
804;abort the device driver. In this case, this routine will set carry
805;and return to the caller.
806;J.K. 6/26/87 If MultDeviceFlag <> 0, then do not perform the check.
807;This is to allow the multiple character device driver which uses
808;the same ending address segment with the offset value 0 for each
809;of the drives.
810
811 PUSH AX
812 MOV AX,WORD PTR [BREAK_ADDR+2] ;REMOVE THE INIT CODE
813 cmp MultDeviceFlag, 0 ;AN001;
814 jne Set_Break_Continue ;AN001;Do not check it.
815 cmp ax, [MEMHI]
816 jne Set_Break_Continue ;if not same, then O.K.
817
818 cmp word ptr [BREAK_ADDR],0
819 je Yes_Break_failed ;[Break_addr+2]=[MEMHI] & [Break_addr]=0
820
821Set_Break_Continue:
822 MOV [MEMHI],AX
823 MOV AX,WORD PTR [BREAK_ADDR]
824 MOV [MEMLO],AX
825 POP AX ; NOTE FALL THROUGH
826 or [SetDevMarkFlag], SETBRKDONE ;AN005; Signal the successful Set_break
827
828;
829; Round the values in MEMLO and MEMHI to paragraph boundary.
830; Perform bounds check.
831;
832ROUND:
833 PUSH AX
834 MOV AX,[MEMLO]
835
836 invoke ParaRound ; para round up
837
838 ADD [MEMHI],AX
839 MOV [MEMLO],0
840 mov ax,memhi ; ax = new memhi
841 CMP AX,[ALLOCLIM] ; if new memhi >= alloclim, error
842 JAE MEM_ERR
843 test cs:[SetDevMarkFlag], FOR_DEVMARK ;AN005;
844 jz Skip_Set_DEVMARKSIZE ;AN005;
845 push es ;AN005;
846 push si ;AN005;
847 mov si, cs:[DevMark_Addr] ;AN005;
848 mov es, si ;AN005;
849 sub ax, si ;AN005;
850 dec ax ;AN005;
851 mov es:[DEVMARK_SIZE], ax ;AN005; Paragraph
852 and cs:[SetDevMarkFlag], NOT_FOR_DEVMARK ;AN005;
853 pop si ;AN005;
854 pop es ;AN005;
855Skip_Set_DEVMARKSIZE: ;AN005;
856 POP AX
857 clc ;clear carry
858 return
859
860MEM_ERR:
861 MOV DX,OFFSET BADMEM
862 PUSH CS
863 POP DS
864 CALL PRINT
865 JMP STALL
866
867CALLDEV:MOV DS,WORD PTR CS:[ENTRY_POINT+2]
868 ADD BX,WORD PTR CS:[ENTRY_POINT] ;Do a little relocation
869 MOV AX,DS:[BX]
870 PUSH WORD PTR CS:[ENTRY_POINT]
871 MOV WORD PTR CS:[ENTRY_POINT],AX
872 MOV BX,OFFSET PACKET
873 CALL [ENTRY_POINT]
874 POP WORD PTR CS:[ENTRY_POINT]
875 return
876
877BADNUM:
878 MOV sepchr,0
879 XOR AX,AX ; Set Zero flag, and AX = 0
880 pop bx ; J.K.
881 stc ; AND carry set
882 return
883
884ToDigit:
885 SUB AL,'0'
886 JB NotDig
887 CMP AL,9
888 JA NotDig
889 CLC
890 return
891NotDig: STC
892 return
893
894; GetNum parses a decimal number.
895; Returns it in AX, sets zero flag if AX = 0 (MAY BE considered an
896; error), if number is BAD carry is set, zero is set, AX=0.
897GETNUM: push bx ; J.K.
898 XOR BX,BX ; running count is zero
899B2: CALL ToDigit ; do we have a digit
900 JC BadNum ; no, bomb
901 XCHG AX,BX ; put total in AX
902 PUSH BX ; save digit
903 MOV BX,10 ; base of arithmetic
904 MUL BX ; shift by one decimal di...
905 POP BX ; get back digit
906 ADD AL,BL ; get total
907 ADC AH,0 ; make that 16 bits
908 JC BADNUM ; too big a number
909 XCHG AX,BX ; stash total
910
911 invoke GETCHR ;GET NEXT DIGIT
912 JC B1 ; no more characters
913 cmp al, ' ' ;J.K. 5/23/86 space?
914 jz B15 ;J.K. 5/23/86 then end of digits
915 cmp al, ',' ;J.K. 5/23/86 ',' is a seperator!!!
916 jz B15 ;J.K. 5/23/86 then end of digits.
917 cmp al, TAB ;J.K. 5/23/86 TAB
918 jz B15 ;J.K.
919 CMP AL,SepChr ; allow 0 or special separators
920 JZ b15
921 cmp al,SWTCHR ; See if another switch follows
922 JZ b15
923 cmp al,LF ; Line-feed?
924 jz b15
925 cmp al,CR ; Carriage return?
926 jz b15
927 OR AL,AL ; end of line separator?
928 JNZ B2 ; no, try as a valid char...
929b15: INC COUNT ; one more character to s...
930 DEC CHRPTR ; back up over separator
931B1: MOV AX,BX ; get proper count
932 OR AX,AX ; Clears carry, sets Zero accordingly
933 pop bx
934 return
935
936SKIP_DELIM proc near ;J.K.
937;Skip the delimeters pointed by CHRPTR. AL will contain the first non delimeter
938;character encountered and CHRPTR will point to the next character.
939;This rouitne will assume the second "," found as a non delimiter character. So
940;in case if the string is " , , ", this routine will stop at the second ",". At
941;this time, Zero flag is set.
942;If COUNT is exhausted, then carry will be set.
943Skip_delim_char:
944 call getchr
945 jc Skip_delim_exit
946 cmp al, ',' ;the first comma?
947 je Skip_delim_next
948 call delim ;check the charater in AL.
949 jz Skip_delim_char
950 jmp short Skip_delim_exit ;found a non delim char
951Skip_delim_next:
952 call getchr
953 jc Skip_delim_exit
954 cmp al, ',' ;the second comma?
955 je Skip_delim_exit ;done
956 call delim
957 jz Skip_delim_next
958Skip_delim_exit:
959 return
960SKIP_DELIM endp
961
962;J.K. 5/26/86 *****************************************************************
963SetDOSCountryInfo proc near
964;Input: ES:DI -> pointer to DOS_COUNTRY_CDPG_INFO
965; DS:0 -> buffer.
966; SI = 0
967; AX = country id
968; DX = code page id. (If 0, then use ccSysCodePage as a default.)
969; BX = file handle
970; This routine can handle maxium 72 COUNTRY_DATA entries.
971;Output: DOS_country_cdpg_info set.
972; Carry set if any file read failure or wrong information in the file.
973; Carry set and CX = -1 if cannot find the matching COUNTRY_id, CODEPAGE
974; _id in the file.
975
976 push di
977 push ax
978 push dx
979
980 xor cx,cx
981 xor dx,dx
982 mov ax, 512 ;read 512 bytes
983 call ReadInControlBuffer ;Read the file header
984 jc SetDOSData_fail
985 push es
986 push si
987 push cs
988 pop es
989 mov di, offset COUNTRY_FILE_SIGNATURE
990 mov cx, 8 ;length of the signature
991 repz cmpsb
992 pop si
993 pop es
994 jnz SetDOSData_fail ;signature mismatch
995
996 add si, 18 ;SI -> county info type
997 cmp byte ptr ds:[si], 1 ;Only accept type 1 (Currently only 1 header type)
998 jne SetDOSData_fail ;cannot proceed. error return
999 inc si ;SI -> file offset
1000 mov dx, word ptr ds:[si] ;Get the INFO file offset.
1001 mov cx, word ptr ds:[si+2]
1002 mov ax, 1024 ;read 1024 bytes.
1003 call ReadInControlBuffer ;Read INFO
1004 jc SetDOSData_fail
1005 mov cx, word ptr ds:[si] ;get the # of country, codepage combination entries
1006 cmp cx, 72 ;cannot handle more than 72 entries.
1007 ja SetDOSData_fail
1008 inc si
1009 inc si ;SI -> entry information packet
1010 pop dx ;restore code page id
1011 pop ax ;restore country id
1012 pop di
1013
1014SetDOSCntry_find: ;Search for desired country_id,codepage_id.
1015 cmp ax, word ptr ds:[si+2] ;compare country_id
1016 jne SetDOSCntry_next
1017 cmp dx, 0 ;No user specified code page ?
1018 je SetDOSCntry_any_codepage;then no need to match code page id.
1019 cmp dx, word ptr ds:[si+4] ;compare code page id
1020 je SetDOSCntry_got_it
1021SetDOSCntry_next:
1022 add si, word ptr ds:[si] ;next entry
1023 inc si
1024 inc si ;take a word for size of entry itself
1025 loop SetDOSCntry_find
1026 mov cx, -1 ;signals that bad country id entered.
1027SetDOSCntry_fail:
1028 stc
1029 ret
1030
1031SetDOSData_fail:
1032 pop si
1033 pop cx
1034 pop di
1035 jmp short SetDOSCntry_fail
1036
1037SetDOSCntry_any_CodePage: ;use the code_page_id of the country_id found.
1038 mov dx, word ptr ds:[si+4]
1039SetDOSCntry_got_it: ;found the matching entry
1040 mov cs:CntryCodePage_Id, dx ;save code page ID for this country.
1041 mov dx, word ptr ds:[si+10] ;get the file offset of country data
1042 mov cx, word ptr ds:[si+12]
1043 mov ax, 512 ;read 512 bytes
1044 call ReadInControlBuffer
1045 jc SetDOSCntry_fail
1046 mov cx, word ptr ds:[si] ;get the number of entries to handle.
1047 inc si
1048 inc si ;SI -> first entry
1049
1050SetDOSCntry_data:
1051 push di ;ES:DI -> DOS_COUNTRY_CDPG_INFO
1052 push cx ;save # of entry left
1053 push si ;si -> current entry in Control buffer
1054
1055 mov al, byte ptr ds:[si+2] ;get data entry id
1056 call GetCountryDestination ;get the address of destination in ES:DI
1057 jc SetDOSCntry_data_next ;No matching data entry id in DOS
1058
1059
1060 mov dx, word ptr ds:[si+4] ;get offset of data
1061 mov cx, word ptr ds:[si+6]
1062 mov ax, 4200h
1063 stc
1064 int 21h ;move pointer
1065 jc SetDOSData_fail
1066 mov dx, 512 ;start of data buffer
1067; mov cx, word ptr es:[di] ;length of the corresponding data in DOS.
1068; add cx, 10 ;Signature + A word for the length itself
1069 mov cx, 20 ;read 20 bytes only. We only need to
1070 mov ah, 3fh ;look at the length of the data in the file.
1071 stc
1072 int 21h ;read the country.sys data
1073 jc SetDOSData_fail ;read failure
1074 cmp ax, cx
1075 jne SetDOSData_fail
1076
1077 mov dx, word ptr ds:[si+4] ;AN008;get offset of data again.
1078 mov cx, word ptr ds:[si+6] ;AN008;
1079 mov ax, 4200h ;AN008;
1080 stc ;AN008;
1081 int 21h ;AN008;move pointer back again
1082 jc SetDOSData_fail ;AN008;
1083
1084 push si ;AN008;
1085 mov si, (512+8) ;AN008;get length of the data from the file
1086 mov cx, word ptr ds:[si] ;AN008;
1087 pop si ;AN008;
1088 mov dx, 512 ;AN008;start of data buffer
1089 add cx, 10 ;AN008;Signature + A word for the length itself
1090 mov ah, 3fh ;AN008;Read the data from the file.
1091 stc ;AN008;
1092 int 21h ;AN008;
1093 jc SetDOSData_fail ;AN008;
1094 cmp ax, cx ;AN008;
1095 jne SetDOSData_fail ;AN008;
1096
1097 mov al, byte ptr ds:[si+2] ;save Data id for future use.
1098 mov si, (512+8) ;SI-> data buffer + id tag field
1099 mov cx, word ptr ds:[si] ;get the length of the file
1100 inc cx ;Take care of a word for lenght of tab
1101 inc cx ;itself.
1102 cmp cx, (2048 - 512 - 8) ;Fit into the buffer?
1103 ja SetDOSData_fail
1104 cmp al, SetCountryInfo ;is the data for SetCountryInfo table?
1105 jne SetDOSCntry_Mov ;no, don't worry
1106 push word ptr es:[di+ccMono_Ptr-ccCountryInfoLen] ;AN009;Cannot destroy ccMono_ptr address. Save them.
1107 push word ptr es:[di+ccMono_Ptr-ccCountryInfoLen+2] ;AN009;At this time DI -> ccCountryInfoLen
1108 push di ;save DI
1109
1110 push ax
1111 mov ax,cs:CntryCodePage_Id ;Do not use the Code Page info in Country_Info
1112 mov ds:[si+4], ax ;Use the saved one for this !!!!
1113 pop ax
1114
1115SetDOSCntry_Mov:
1116 rep movsb ;copy the table into DOS
1117 cmp al, SetCountryInfo ;was the ccMono_ptr saved?
1118 jne SetDOSCntry_data_next
1119 pop di ;restore DI
1120 pop word ptr es:[di+ccMono_Ptr-ccCountryInfoLen+2] ;AN009;restore
1121 pop word ptr es:[di+ccMono_Ptr-ccCountryInfoLen] ;AN009;
1122
1123SetDOSCntry_data_next:
1124 pop si ;restore control buffer pointer
1125 pop cx ;restore # of entries left
1126 pop di ;restore pointer to DSO_COUNTRY_CDPG
1127 add si, word ptr ds:[si] ;try to get the next entry
1128 inc si
1129 inc si ;take a word of entry length itself
1130; loop SetDOSCntry_data
1131 dec cx ;AN008;
1132 cmp cx,0 ;AN008;
1133 je SetDOSCntry_OK ;AN008;
1134 jmp SetDOSCntry_data ;AN008;
1135SetDOSCntry_OK: ;AN008;
1136 ret
1137SetDOSCountryInfo endp
1138;
1139
1140GetCountryDestination proc near
1141;Get the destination address in the DOS country info table.
1142;Input: AL - Data ID
1143; ES:DI -> DOS_COUNTRY_CDPG_INFO
1144;On return:
1145; ES:DI -> Destination address of the matching data id
1146; carry set if no matching data id found in DOS.
1147
1148 push cx
1149 add di, ccNumber_of_entries ;skip the reserved area, syscodepage etc.
1150 mov cx, word ptr es:[di] ;get the number of entries
1151 inc di
1152 inc di ;SI -> the first start entry id
1153GetCntryDest:
1154 cmp byte ptr es:[di], al
1155 je GetCntryDest_OK
1156 cmp byte ptr es:[di], SetCountryInfo ;was it SetCountryInfo entry?
1157 je GetCntryDest_1
1158 add di, 5 ;next data id
1159 jmp short GetCntryDest_loop
1160GetCntryDest_1:
1161 add di, NEW_COUNTRY_SIZE + 3 ;next data id
1162GetCntryDest_loop:
1163 loop GetCntryDest
1164 stc
1165 jmp short GetCntryDest_exit
1166GetCntryDest_OK:
1167 cmp al, SetCountryInfo ;select country info?
1168 jne GetCntryDest_OK1
1169 inc di ;now DI -> ccCountryInfoLen
1170 jmp short GetCntryDest_exit
1171GetCntryDest_OK1:
1172 les di, dword ptr es:[di+1] ;get the destination in ES:DI
1173GetCntryDest_Exit:
1174 pop cx
1175 ret
1176GetCountryDestination endp
1177
1178;
1179ReadInControlBuffer proc near
1180;Move file pointer to CX:DX
1181;Read AX bytes into the control buffer. (Should be less than 2 Kb)
1182;SI will be set to 0 hence DS:SI points to the control buffer.
1183;Entry: CX,DX offset from the start of the file where the read/write pointer
1184; be moved.
1185; AX - # of bytes to read
1186; BX - file handle
1187; DS - buffer seg.
1188;Return: The control data information is read into DS:0 - DS:0200.
1189; CX,DX value destroyed.
1190; Carry set if error in Reading file.
1191;
1192 push ax ;# of bytes to read
1193 mov ax, 4200h
1194 stc
1195 int 21h ;move pointer
1196 pop cx ;# of bytes to read
1197 jc RICB_exit
1198 xor dx,dx ;ds:dx -> control buffer
1199 xor si,si
1200 mov ah,3fh ;read into the buffer
1201 stc
1202 int 21h ;should be less than 1024 bytes.
1203RICB_exit:
1204 ret
1205ReadInControlBuffer endp
1206
1207;
1208SET_COUNTRY_PATH proc near
1209;In: DS - SYSINITSEG, ES - CONFBOT, SI -> start of the asciiz path string
1210; DOSINFO_EXT, CNTRY_DRV, CNTRY_ROOT, CNTRY_PATH
1211; Assumes current directory is the ROOT directory.
1212;Out: DS:DI -> full path (CNTRY_DRV).
1213; Set the CNTRY_DRV string from the COUNTRY=,,path command.
1214; DS, ES, SI value saved.
1215
1216 push si
1217 push ds ;switch ds, es
1218 push es
1219 pop ds
1220 pop es ;now DS -> CONFBOT, ES -> SYSINITSEG
1221
1222 call chk_drive_letter ;current DS:[SI] is a drive letter?
1223 jc SCP_Default_drv ;no, use current default drive.
1224 mov al, byte ptr DS:[SI]
1225 inc si
1226 inc si ;SI -> next char after ":"
1227 jmp short SCP_SetDrv
1228SCP_Default_drv:
1229 mov ah, 19h
1230 int 21h
1231 add al, "A" ;convert it to a character.
1232SCP_SetDrv:
1233 mov cs:CNTRY_DRV, al ;set the drive letter.
1234 mov di, offset CNTRY_PATH
1235 mov al, byte ptr DS:[SI]
1236 cmp al, "\"
1237 je SCP_Root_Dir
1238 cmp al, cs:SWTCHR ;let's accept "/" as an directory delim
1239 je SCP_Root_Dir
1240 jmp short SCP_Path
1241SCP_Root_Dir:
1242 dec di ;DI -> CNTRY_ROOT
1243SCP_Path:
1244 call MOVE_ASCIIZ ;copy it
1245 mov di, offset CNTRY_DRV
1246SCPath_Exit:
1247 push ds ;switch ds, es
1248 push es
1249 pop ds
1250 pop es ;DS, ES value restored
1251 pop si
1252 RET
1253SET_COUNTRY_PATH endp
1254
1255;
1256CHK_DRIVE_LETTER proc near
1257;Check if DS:[SI] is a drive letter followed by ":".
1258;Assume that every alpha charater is already converted to UPPER CASE.
1259;Carry set if not.
1260;
1261 push ax
1262 cmp byte ptr ds:[si], "A"
1263 jb CDLetter_NO
1264 cmp byte ptr ds:[si], "Z"
1265 ja CDLetter_NO
1266 cmp byte ptr ds:[si+1], ":"
1267 jne CDLetter_NO
1268 jmp short CDLetter_exit
1269CDLetter_NO:
1270 stc
1271CDLetter_exit:
1272 pop ax
1273 ret
1274CHK_DRIVE_LETTER endp
1275
1276;
1277MOVE_ASCIIZ proc near
1278;In: DS:SI -> source ES:DI -> target
1279;Out: copy the string until 0.
1280;Assumes there exists a 0.
1281MASCIIZ_loop:
1282 movsb
1283 cmp byte ptr DS:[SI-1], 0 ;Was it 0?
1284 jne MASCIIZ_loop
1285 ret
1286MOVE_ASCIIZ endp
1287
1288;
1289; DS:DX POINTS TO STRING TO OUTPUT (ASCIZ)
1290;
1291; PRINTS <BADLD_PRE> <STRING> <BADLD_POST>
1292;
1293;
1294;
1295BADFIL:
1296 PUSH CS
1297 POP ES
1298 MOV SI,DX
1299BADLOAD:
1300 MOV DX,OFFSET BADLD_PRE ;WANT TO PRINT CONFIG ERROR
1301; MOV BX,OFFSET BADLD_POST
1302 mov bx, offset CRLFM ;AN006;
1303PRNERR:
1304 PUSH CS
1305 POP DS
1306 call Print
1307PRN1: MOV DL,ES:[SI]
1308 OR DL,DL
1309 JZ PRN2
1310 MOV AH,STD_CON_OUTPUT
1311 INT 21H
1312 INC SI
1313 JMP PRN1
1314PRN2: MOV DX,BX
1315 call Print
1316 cmp DoNotShowNum, 1 ;AN000; suppress line number when handling COMMAND.COM
1317 je Prnexit
1318 call Error_Line
1319PRNEXIT:
1320 return
1321
1322PRINT: MOV AH,STD_CON_STRING_OUTPUT
1323 INT 21H
1324 return
1325
1326
1327 IF NOEXEC
1328;
1329; LOAD NON EXE FILE CALLED [DS:DX] AT MEMORY LOCATION ES:BX
1330;
1331LDFIL:
1332 PUSH AX
1333 PUSH BX
1334 PUSH CX
1335 PUSH DX
1336 PUSH SI
1337 PUSH DS
1338 PUSH BX
1339 XOR AX,AX ;OPEN THE FILE
1340 MOV AH,OPEN
1341 STC ;IN CASE OF INT 24
1342 INT 21H
1343 POP DX ;Clean stack in case jump
1344 JC LDRET
1345 PUSH DX
1346 MOV BX,AX ;Handle in BX
1347 XOR CX,CX
1348 XOR DX,DX
1349 MOV AX,(LSEEK SHL 8) OR 2
1350 STC ;IN CASE OF INT 24
1351 INT 21H ; Get file size in DX:AX
1352 JC LDCLSP
1353 OR DX,DX
1354 JNZ LDERRP ; File >64K
1355 POP DX
1356 PUSH DX
1357 MOV CX,ES ; CX:DX is xaddr
1358 ADD DX,AX ; Add file size to Xaddr
1359 JNC DOSIZE
1360 ADD CX,1000H ; ripple carry
1361DOSIZE:
1362 mov ax,dx
1363 call ParaRound
1364 mov dx,ax
1365
1366 ADD CX,DX
1367 CMP CX,[ALLOCLIM]
1368 JB OKLD
1369 JMP MEM_ERR
1370
1371OKLD:
1372 XOR CX,CX
1373 XOR DX,DX
1374 MOV AX,LSEEK SHL 8 ;Reset pointer to beginning of file
1375 STC ;IN CASE OF INT 24
1376 INT 21H
1377 JC LDCLSP
1378 POP DX
1379 PUSH ES ;READ THE FILE IN
1380 POP DS ;Trans addr is DS:DX
1381 MOV CX,0FF00H ; .COM files arn't any bigger than
1382 ; 64k-100H
1383 MOV AH,READ
1384 STC ;IN CASE OF INT 24
1385 INT 21H
1386 JC LDCLS
1387 MOV SI,DX ;CHECK FOR EXE FILE
1388 CMP WORD PTR [SI],"ZM"
1389 CLC ; Assume OK
1390 JNZ LDCLS ; Only know how to do .COM files
1391 STC
1392 JMP SHORT LDCLS
1393
1394LDERRP:
1395 STC
1396LDCLSP:
1397 POP DX ;Clean stack
1398LDCLS:
1399 PUSHF
1400 MOV AH,CLOSE ;CLOSE THE FILE
1401 STC
1402 INT 21H
1403 POPF
1404
1405LDRET: POP DS
1406 POP SI
1407 POP DX
1408 POP CX
1409 POP BX
1410 POP AX
1411 return
1412 ENDIF
1413
1414;
1415; OPEN DEVICE POINTED TO BY DX, AL HAS ACCESS CODE
1416; IF UNABLE TO OPEN DO A DEVICE OPEN NULL DEVICE INSTEAD
1417;
1418OPEN_DEV:
1419 CALL OPEN_FILE
1420 JNC OPEN_DEV3
1421OPEN_DEV1:
1422 MOV DX,OFFSET NULDEV
1423 CALL OPEN_FILE
1424 return
1425
1426OPEN_DEV3:
1427 MOV BX,AX ; Handle from open to BX
1428 XOR AX,AX ; GET DEVICE INFO
1429 MOV AH,IOCTL
1430 INT 21H
1431 TEST DL,10000000B
1432 retnz
1433 MOV AH,CLOSE
1434 INT 21H
1435 JMP OPEN_DEV1
1436
1437OPEN_FILE:
1438 MOV AH,OPEN
1439 STC
1440 INT 21H
1441 return
1442
1443;J.K. TEST INT24. Return back to DOS with the fake user response of "FAIL"
1444INT24:
1445 mov al, 3 ;AN000; Fail the system call
1446 iret ;AN000; Return back to DOS.
1447
1448
1449;INT24: ADD SP,6 ;RESTORE MACHINE STATE
1450; POP AX
1451; POP BX
1452; POP CX
1453; POP DX
1454; POP SI
1455; POP DI
1456; POP BP
1457; POP DS
1458; POP ES
1459; PUSH AX
1460; MOV AH,GET_DEFAULT_DRIVE ;INITIALIZE DOS
1461; INT 21H
1462; POP AX
1463; IRET ;BACK TO USER
1464
1465 IF ALTVECT
1466BOOTMES DB 13,10,"MS-DOS version "
1467 DB MAJOR_VERSION + "0"
1468 DB "."
1469 DB (MINOR_VERSION / 10) + "0"
1470 DB (MINOR_VERSION MOD 10) + "0"
1471 DB 13,10
1472 DB "Copyright 1981,88 Microsoft Corp.",13,10,"$"
1473 ENDIF
1474
1475include copyrigh.inc ;P1821; Copyright statement
1476
1477NULDEV DB "NUL",0
1478CONDEV DB "CON",0
1479AUXDEV DB "AUX",0
1480PRNDEV DB "PRN",0
1481
1482CONFIG DB "\CONFIG.SYS",0
1483
1484CNTRY_DRV DB "A:"
1485CNTRY_ROOT DB "\"
1486CNTRY_PATH DB "COUNTRY.SYS",0
1487 DB 52 DUP (0)
1488
1489COUNTRY_FILE_SIGNATURE db 0FFh,'COUNTRY'
1490
1491CntryCodePage_Id DW ?
1492
1493COMMND DB "\COMMAND.COM",0
1494 DB 51 dup (0)
1495
1496PathString db 64 dup (0) ;AN014;
1497LShare db "SHARE.EXE",0,"/NC",0Dh,0Ah ;AN014;AN015;To be used by Load/exec.
1498 ;/NC parm will disable file sharing check.
1499
1500COMTAB LABEL BYTE
1501;;;; DB 8,"AVAILDEV",'A' ; NO LONGER SUPPORTED
1502 DB 7,"BUFFERS", 'B'
1503 DB 5,"BREAK", 'C'
1504 DB 6,"DEVICE", 'D'
1505 DB 5,"FILES", 'F'
1506 DB 4,"FCBS", 'X'
1507 DB 9,"LASTDRIVE",'L'
1508 db 10,"MULTITRACK", 'M' ;AN002;
1509 DB 8,"DRIVPARM", 'P' ; RS for DOS 3.2
1510 IF STACKSW
1511 DB 6,"STACKS", 'K' ; BAS for DOS 3.2
1512 ENDIF
1513 DB 7,"COUNTRY", 'Q'
1514 DB 5,"SHELL", 'S'
1515 db 7,"INSTALL", 'I' ;AN000;
1516 db 3,"IFS", 'J' ;AN000;
1517 db 4,"CPSW", 'W' ;AN000;
1518;;;; DB 8,"SWITCHAR",'W' ; NO LONGER SUPPORTED
1519 db 7,"COMMENT", 'Y' ;AN000;
1520 db 3,"REM", '0' ;AN004;
1521 db 8,"SWITCHES", '1' ;AN013;
1522 DB 0
1523
1524public DeviceParameters
1525DeviceParameters a_DeviceParameters <0,DEV_3INCH720KB,0,80>
1526
1527hlim dw 2
1528slim dw 9
1529
1530public drive
1531drive db ?
1532
1533public switches
1534Switches dw 0
1535
1536;
1537; The following are the recommended BPBs for the media that we know of so
1538; far.
1539
1540; 48 tpi diskettes
1541
1542BPB48T DW 512
1543 DB 2
1544 DW 1
1545 DB 2
1546 DW 112
1547 DW 2*9*40
1548 DB 0FDH
1549 DW 2
1550 DW 9
1551 DW 2
1552 DD 0
1553 DD 0
1554
1555; 96tpi diskettes
1556
1557BPB96T DW 512
1558 DB 1
1559 DW 1
1560 DB 2
1561 DW 224
1562 DW 2*15*80
1563 DB 0F9H
1564 DW 7
1565 DW 15
1566 DW 2
1567 DD 0
1568 DD 0
1569
1570; 3 1/2 inch diskette BPB
1571
1572BPB35 DW 512
1573 DB 2
1574 DW 1
1575 DB 2
1576 DW 70h
1577 DW 2*9*80
1578 DB 0F9H
1579 DW 3
1580 DW 9
1581 DW 2
1582 DD 0
1583 DD 0
1584
1585BPB35H DW 0200H
1586 DB 01H
1587 DW 0001H
1588 DB 02H
1589 DW 0E0h
1590 DW 0B40H
1591 DB 0F0H
1592 DW 0009H
1593 DW 0012H
1594 DW 0002H
1595 DD 0
1596 DD 0
1597
1598BPBTable dw BPB48T ; 48tpi drives
1599 dw BPB96T ; 96tpi drives
1600 dw BPB35 ; 3.5" drives
1601; The following are not supported, so default to 3.5" media layout
1602 dw BPB35 ; Not used - 8" drives
1603 dw BPB35 ; Not Used - 8" drives
1604 dw BPB35 ; Not Used - hard files
1605 dw BPB35 ; Not Used - tape drives
1606 dw BPB35H ; 3-1/2" 1.44MB drive
1607
1608switchlist db 8,"FHSTDICN" ; Preserve the positions of N and C.
1609
1610; The following depend on the positions of the various letters in SwitchList
1611
1612switchnum equ 11111000B ; which switches require number
1613
1614flagec35 equ 00000100B ; electrically compatible 3.5 inch disk drive
1615flagdrive equ 00001000B
1616flagcyln equ 00010000B
1617flagseclim equ 00100000B
1618flagheads equ 01000000B
1619flagff equ 10000000B
1620
1621SWTCHR EQU "/" ; switch follows this character
1622
1623SYSINITSEG ENDS
1624 END