summaryrefslogtreecommitdiff
path: root/v4.0/src/BIOS/MSINIT.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/BIOS/MSINIT.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/BIOS/MSINIT.ASM')
-rw-r--r--v4.0/src/BIOS/MSINIT.ASM2819
1 files changed, 2819 insertions, 0 deletions
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