]>
wirehaze git hosting - MS-DOS.git/blob - v4.0/src/BIOS/MSINIT.ASM
3 ;=======================================================
5 ;AN000; - NEW Version 4.00. J.K.
6 ;AC000; - Modified Line 4.00. J.K.
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 ;==============================================================================
27 INCLUDE MSGROUP
.INC ;DEFINE CODE SEGMENT
36 ; THE FOLLOWING LABEL DEFINES THE END OF THE AT ROM PATCH. THIS IS USED AT
38 ;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT.
40 PUBLIC ENDATROM
;NOT REFERENCES EXTERNALLY, BUT
41 ; JUST TO CAUSE ENTRY IN LINK MAP
44 ;CMOS Clock setting support routines used by MSCLOCK.
45 ;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT.
47 EXTRN base_century
:byte
51 public Daycnt_to_day
;J.K. 4/30/86 for real time clock support
52 Daycnt_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
56 push [daycnt
] ;save daycnt
57 cmp daycnt
, (365*20+(20/4)) ;# of days from 1-1-1980 to 1-1-2000
62 century20: ;20th century
65 sub daycnt
, (365*20+(20/4)) ;adjust 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
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.
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
92 ; jmp Erroroccur ;cannot come to here
94 mov byte ptr month_tab
+1,29 ;leap year. change the month table.
99 mov si, offset month_tab
103 mov dl, byte ptr ds:[si] ;compare daycnt for each month until fits
107 sub ax, dx ;adjust daycnt
111 mov byte ptr month_tab
+1, 28 ;restore month table value
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
121 xchg dh, al ;dh = bcd month, al = year
122 call word ptr BinToBCD
124 xchg cl, al ;cl = bcd year, al = century
125 call word ptr BinToBCD
127 mov ch, al ;ch = bcd century
128 pop [daycnt
] ;restore original value
132 public EndDaycntToDay
133 EndDaycntToDay
label byte
136 Bin_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.
142 div cl ;al - high digit for bcd, ah - low digit for bcd
144 shl al, cl ;mov the high digit to high nibble
150 Public EndCMOSClockset
;End of supporting routines for CMOS clock setting.
151 EndCMOSClockset
label byte
154 EXTRN INT6C_RET_ADDR
:DWORD ; RETURN ADDRESS FROM INT 6C
155 EXTRN BIN_DATE_TIME
:BYTE
156 EXTRN MONTH_TABLE
:WORD
159 EXTRN TimeToTicks
:Word ;indirect intra-segment call address
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.
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.
172 ;J.K. 10/2/86 Waring!!! This code will be dynamically relocated by MSINIT.
180 POP WORD PTR INT6C_RET_ADDR
; POP OFF RETURN ADDRESS
181 POP WORD PTR INT6C_RET_ADDR
+2
183 CALL READ_REAL_DATE
; GET THE DATE FROM THE CLOCK
185 MOV DS:DAYCNT
,SI ; UPDATE DOS COPY OF DATE
187 CALL READ_REAL_TIME
; GET THE TIME FROM THE RTC
189 ;SB33019***************************************************************
190 MOV AH, 01h ; COMMAND TO SET THE TIME ;SB;3.30
191 INT 1
Ah ; CALL ROM-BIOS TIME ROUTINE ;SB;3.30
192 ;SB33019***************************************************************
194 JMP INT6C_RET_ADDR
; LONG JUMP
202 PUBLIC ENDK09
;NOT REFERENCES EXTERNALLY, BUT
203 ; JUST TO CAUSE ENTRY IN LINK MAP
205 ASSUME
DS:NOTHING
,ES:NOTHING
207 ;*********************************************************
208 ; SYSTEM INITIALIZATION
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:
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
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
226 ;********************************************************
228 ;SYSIZE=200H ;NUMBER OF PARAGRAPHS IN SYSINIT MODULE
231 ; DRVFAT MUST BE THE FIRST LOCATION OF FREEABLE SPACE!
233 DRVFAT
DW 0000 ;DRIVE AND FAT ID OF DOS
234 BIOS$_L
DW 0000 ;FIRST SECTOR OF DATA (Low word)
235 bios$_H
dw 0000 ;First sector of data (High word)
236 DOSCNT
DW 0000 ;HOW MANY SECTORS TO READ
237 FBIGFAT
DB 0 ; FLAGS FOR DRIVE
239 ;FATLEN DW ? ; NUMBER OF SECTORS IN FAT.
240 FATLOC
DW ?
; SEG ADDR OF FAT SECTOR
241 Init_BootSeg dw ?
;AN015; seg addr of buffer for reading boot record
242 ROM_drv_num db 80h
;AN000; rom drv number
243 ;Boot_Sec_Per_Fat dw 0 ;AN000; Boot media sectors/FAT
244 Md_SectorSize dw 512 ;AN004; Used by Get_Fat_Sector proc.
245 Temp_Cluster dw 0 ;AN004; Used by Get_Fat_Sector proc.
246 Last_Fat_SecNum dw -1 ;AN004; Used by Get_Fat_Sector proc.
248 ; THE FOLLOWING TWO BYTES ARE USED TO SAVE THE INFO RETURNED BY INT 13, AH = 8
249 ; CALL TO DETERMINE DRIVE PARAMETERS.
250 NUM_HEADS
DB 2 ; NUMBER OF HEADS RETURNED BY ROM
251 SEC_TRK
DB 9 ; SEC/TRK RETURNED BY ROM
252 NUM_CYLN
DB 40 ; NUMBER OF CYLINDERS RETURNED BY ROM
254 FakeFloppyDrv db 0 ;AN002; If 1, then No diskette drives in the system.
258 EXT_BOOT_SIG_OFF
= 11+size BPB_TYPE
;AN000; 3 byte jmp+8 byte OEM +extended bpb
262 DISKTABLE
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
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
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
280 ;AN004 Default DiskTable under the assumption of Total FAT size <= 128 KB, and
281 ; the maxium size of FAT entry = 16 Bit.
282 DiskTable2 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...
290 ;******************************************************************************
291 ;Variables for Mini disk initialization - J.K. 4/7/86
292 ;******************************************************************************
293 End_Of_BDSM dw ?
;offset value of the ending address
294 ;of BDSM table. Needed to figure out
295 ;the Final_DOS_Location.
296 numh db 0 ;number of hard files
297 mininum db 0 ;logical drive number for mini disk(s)
298 num_mini_dsk db 0 ;# of mini disk installed
299 Rom_Minidsk_num db 80h
;physical mini disk number
302 Mini_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 **********************************
307 BIOS_DATE
DB '01/10/84',0 ;This is used for checking AT ROM BIOS date.
309 ; THE FOLLOWING ARE THE RECOMMENDED BPBS FOR THE MEDIA THAT WE KNOW OF SO
325 dw 0 ;AN000; hidden sector High
326 dd 0 ;AN000; extended total sectors
341 dw 0 ;AN000; hidden sector High
342 dd 0 ;AN000; extended total sectors
346 ; 3 1/2 INCH DISKETTE BPB
351 DW 1 ; DOUBLE SIDED WITH 9 SEC/TRK
360 dw 0 ;AN000; hidden sector High
361 dd 0 ;AN000; extended total sectors
364 BPBTABLE
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
373 PATCHTABLE
LABEL BYTE
383 ASSUME
DS:NOTHING
,ES:NOTHING
386 ; ENTRY FROM BOOT SECTOR. THE REGISTER CONTENTS ARE:
387 ; DL = INT 13 DRIVE NUMBER WE BOOTED FROM
389 ; BX = FIRST DATA SECTOR ON DISK.
391 ; AX = first data sector (High)
392 ; DI = Sectors/FAT for the boot media.
396 MESSAGE FTESTINIT
,<"IBMBIO",CR
,LF
>
402 ;J.K. MSLOAD will check the extended boot record and set AX, BX accordingly.
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.
412 ;SB34INIT000*************************************************************
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;
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.
429 MOV WORD PTR OLD13
,AX
430 MOV WORD PTR ORIG13
,AX
432 MOV WORD PTR OLD13
+2,AX
433 MOV WORD PTR ORIG13
+2,AX
435 ; SET UP INT 13 FOR NEW ACTION
437 MOV WORD PTR DS:[13H
*4],OFFSET BLOCK13
440 ; PRESERVE ORIGINAL INT 19 VECTOR
443 MOV WORD PTR ORIG19
,AX
445 MOV WORD PTR ORIG19
+2,AX
447 ; SET UP INT 19 FOR NEW ACTION
449 MOV WORD PTR DS:[19H
*4],OFFSET INT19
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.!!!***
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
480 mov cs:FakeFloppyDrv
,1 ; fake floppy
481 mov ax,1 ; set to indicate 2 floppies
486 ;SB34INIT001**************************************************************
488 ; Determine if there are one or two diskette drives in system
490 ROL AL,1 ;PUT BITS 6 & 7 INTO BITS 0 & 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
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 ?
503 XOR AX,AX ;INDICATE BOOT FROM DRIVE A
506 ; AX = 0-BASED DRIVE WE BOOTED FROM
507 ; BIOS$_L, BIOS$_H set.
508 ; CL = NUMBER OF FLOPPIES INCLUDING FAKE ONE
511 MESSAGE FTESTINIT
,<"INIT",CR
,LF
>
515 MOV SP,700H
;LOCAL STACK
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
532 mov al, ES:[BX.bios_SD_scnd_modelbyte
] ;secondary model byte
533 mov [Secondary_Model_Byte
], al
534 jmp short Turn_Timer_On
536 MOV SI,0FFFFH ;MJB001
538 MOV AL,ES:[0EH] ; GET MODEL BYTE ARR 2.41
539 MOV MODEL_BYTE
,AL ; SAVE MODEL BYTE ARR 2.41
542 OUT AKPORT
,AL ;TURN ON THE TIMER
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
553 pop es ;AN003;ES -> CS
554 mov di, offset DoubleWordMov
;AN003;
555 mov cx, 3 ;AN003; 3 bytes to NOP
559 Skip_Patch_DoubleWordMov: ;AN003;
560 MESSAGE FTESTINIT
,<"COM DEVICES",CR
,LF
>
561 ;SB33IN1*********************************************************
563 mov si,offset COM4DEV
565 mov si,offset COM3DEV
567 ;SB33IN1*********************************************************
568 MOV SI,OFFSET COM2DEV
569 CALL AUX_INIT
;INIT COM2
570 MOV SI,OFFSET COM1DEV
571 CALL AUX_INIT
;INIT COM1
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
582 MOV DS,DX ;TO INITIALIZE PRINT SCREEN VECTOR
587 STOSW ;INIT FOUR BYTES TO 0
590 MOV AX,CS ;FETCH SEGMENT
592 MOV DS:WORD PTR BRKADR
,OFFSET CBREAK
;BREAK ENTRY POINT
593 MOV DS:BRKADR
+2,AX ;VECTOR FOR BREAK
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
601 ;*********************************************** ARR 2.15
604 MOV DS:WORD PTR CHROUT
*4,OFFSET
WORD PTR OUTCHR
605 MOV DS:WORD PTR CHROUT
*4+2,AX
607 MESSAGE FTESTINIT
,<"INTERRUPT VECTORS",CR
,LF
>
609 MOV BX,OFFSET INTRET
;WILL INITIALIZE REST OF INTERRUPTS
613 STOSW ;INT 1 ;LOCATION 6
618 STOSW ;INT 3 ;LOCATION 14
622 STOSW ;INT 4 ;LOCATION 18
624 MOV DS:WORD PTR 500H
,DX ;SET PRINT SCREEN & BREAK =0
625 MOV DS:WORD PTR LSTDRV
,DX ;CLEAN OUT LAST DRIVE SPEC
627 MESSAGE FTESTINIT
,<"DISK PARAMETER TABLE",CR
,LF
>
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
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
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
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
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
657 NO_DIDDLE: ; ARR 2.41
658 INT 12H
;GET MEMORY SIZE--1K BLOCKS IN AX
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
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
668 ; mov dx, cs:Boot_Sec_Per_FAT ;AC000;Do not use the bpb info from Boot record any more.
672 ; CONVERT SECTOR COUNT TO PARAGRAPH COUNT:512 BYTES / SEC / 16 BYTES / PARA
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;
693 MOV WORD PTR DEVICE_LIST
,OFFSET CONHEADER
694 MOV WORD PTR DEVICE_LIST
+2,CS
698 MOV DEFAULT_DRIVE
,CL ;SAVE DEFAULT DRIVE SPEC
700 ;DOSSEG = (((END$ - START$)+15)/16)+BIOSEG+SYSIZE
703 ;MOV CURRENT_DOS_LOCATION,(((END$ - START$)+15)/16)+SYSIZE
705 SUB AX, OFFSET START$
707 RCR AX, 1 ; DIVIDE BY 16
713 MOV CURRENT_DOS_LOCATION
, AX
715 ; ADD CURRENT_DOS_LOCATION,CODE
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
720 ; 1) THE ORIGINAL SEGMENT POINTS TO STORAGE INSIDE VALID RAM.
722 ; 2) THE ORIGINAL SEGMENT IS 0F000:XXXX
724 ; THESES ARE CAPRICIOUS REQUESTS FROM OUR OEM FOR REASONS BEHIND THEM, READ
725 ; THE DCR'S FOR THE IBM DOS 3.2 PROJECT.
729 ASSUME
ES:SYSINITSEG
, DS:NOTHING
734 XOR AX,AX ; AX := SEGMENT FOR INT 15
736 MOV AX,WORD PTR DS:(0FH*4+2)
738 CMP AX,ES:MEMORY_SIZE
; CONDITION 1
741 CMP AX,0F000H ; CONDITION 2
745 MOV WORD PTR DS:[0FH*4],OFFSET INTRET
746 MOV WORD PTR DS:[0FH*4+2],CS
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
761 mov cl,ds:0496h ; get keyboard flag
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
768 ;SB34INIT003****************************************************************
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:
780 ;**************************************************************
786 ASSUME
DS:CODE,ES:CODE
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.
792 MESSAGE FTESTINIT
,<"DISK DEVICES",CR
,LF
>
795 MOV WORD PTR [SI],OFFSET HARDDRV
;SET UP POINTER TO HDRIVE
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
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
816 MESSAGE FTESTINIT
,<"SETTING UP BDSS",CR
,LF
>
819 ; SCAN THE LIST OF DRIVES TO DETERMINE THEIR TYPE. WE HAVE THREE FLAVORS OF
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.
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)
832 XOR DL,DL ; START OUT WITH DRIVE 0.
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
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.
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*********************************************************
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
879 ;SB33022********************************************************************
880 MOV AH, 8h
;GET DRIVE PARAMETERS ;SB;3.30
881 INT 13h
;CALL ROM-BIOS ;SB;3.30
882 ;SB33022********************************************************************
884 JMP NOPARMSFROMROM
; GOT AN OLD ROM
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.
893 CMP CH,0 ; if ch=0, then cl,dh=0 too.
895 MOV CH,39 ; ROM gave wrong info.
896 MOV CL,9 ; Let's default to 360K.
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
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
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********************************************************************
922 CMP AH,02 ; CHECK FOR PRESENCE OF CHANGELINE
925 ; WE HAVE A DRIVE WITH CHANGE LINE SUPPORT.
927 MESSAGE FTESTINIT
,<"96TPI DEVICES",CR
,LF
>
929 OR CL,FCHANGELINE
; SIGNAL TYPE
930 MOV FHAVE96
,1 ; REMEMBER THAT WE HAVE 96TPI DISKS
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".
936 ; 40 CYLINDERS AND 9 OR LESS SEC/TRK, TREAT AS 48 TPI MEDIUM.
942 MOV DH,FFOTHER
; WE HAVE A "STRANGE" MEDIUM
946 ; 80 CYLINDERS AND 9 SECTORS/TRACK => 720 KB DEVICE
947 ; 80 CYLINDERS AND 15 SEC/TRK => 96 TPI MEDIUM
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.
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****************************************************************
980 CMP AH,2 ; IS THERE CHANGELINE?
983 MOV FHAVE96
,1 ; REMEMBER THAT WE HAVE 96TPI DRIVES
986 MOV AL,15 ; SET EOT IF NECESSARY
993 OR CL,FI_OWN_PHYSICAL
; SET THIS TRUE FOR ALL DRIVES
994 MOV BH,DL ;SAVE INT13 DRIVE NUMBER
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
1004 DEC BH ; INT13 DRIVE NUMBER SAME FOR LOGICAL DRIVE
1005 XOR CL,FI_OWN_PHYSICAL
; RESET OWNERSHIP FLAG FOR LOGICAL DRIVE
1007 ; THE VALUES THAT WE PUT IN FOR RHDLIM AND RSECLIM WILL ONLY REMAIN IF THE
1008 ; FORM FACTOR IS OF TYPE "FFOTHER".
1011 MOV WORD PTR [DI].RHDLIM
,AX
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
1022 MESSAGE FTESTINIT
,<"SINGLE DRIVE SYSTEM",CR
,LF
>
1023 MOV SINGLE
,2 ; DON'T LOSE INFO THAT WE HAVE SINGLE SYSTEM
1025 OR WORD PTR [DI].FLAGS
,CX
1026 MOV DI,WORD PTR [DI].LINK
; MOVE TO NEXT BDS IN LIST
1028 JMP SHORT NEXTDRIVE
; USE SAME INFO FOR BDS A PREVIOUS
1034 MOV AX,-1 ; SET LINK TO NULL
1035 MOV WORD PTR [DI].LINK
,AX
1037 ; SET UP ALL THE HARD DRIVES IN THE SYSTEM
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
>
1044 CMP HNUM
,0 ; IF (NO_HARD_FILES)
1045 JLE STATIC_CONFIGURE
; THEN EXIT TO CONFIGURE
1048 MOV DI,OFFSET BDSH
; SET UP FIRST HARD FILE.
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
1060 CALL INSTALL_BDS
; INSTALL BDS INTO LINKED LIST
1061 CMP HNUM
,2 ; IF (ONLY_ONE_HARDFILE)
1062 JB SETIT
; THEN SETIT "IN PLACE"
1065 INC BL ; NEXT DRIVE LETTER
1068 SECOND_HARD: ; SETUP SECOND HARD FILE
1070 MESSAGE FTESTINIT
+FTESTHARD
,<"HARD DISK 2",CR
,LF
>
1071 MOV DL,81H
; NEXT HARD FILE
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).
1093 call DoMini
;For setting up mini disks, if found -J.K.
1096 ; END OF DRIVE INITIALIZATION.
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
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.
1113 ; 1. BASIC CONFIGURATION FOR IBMBIO (EndFloppy, EndSwap)
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.
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
1134 mov ax, offset END96TPI
;let's start with the biggest one.
1135 cmp fHave96
, 0 ;Is change line support there?
1138 mov ax, offset ENDTWOHARD
1139 cmp HNUM
, 1 ;1 hard file?
1143 mov ax, offset ENDONEHARD
1147 mov ax, offset ENDFLOPPY
1148 jmp Dynamic_Configure
;static configuration is done!
1151 ; KEEP THE 96TPI CODE
1155 ; SAVE OLD INT 13 VECTOR
1164 MOV WORD PTR CS:REAL13
,AX
1165 MOV AX,DS:[4 * 13H
+2]
1166 MOV WORD PTR CS:REAL13
+2,AX
1170 MOV WORD PTR DS:[4 * 13H
],OFFSET INT13
1171 MOV DS:[4 * 13H
+ 2],CS
1178 ; KEEP TWO HARD DISK BPBS
1182 ; KEEP ONE HARD DISK BPB
1186 ; ADJUST THE NUMBER OF DRIVES TO INCLUDE THE HARD DISKS.
1192 add al, num_mini_dsk
;J.K. 4/7/86 for mini disks installed
1193 ;if not installed, then num_mini_dsk = 0.
1195 POP AX ;now, static config is done.
1199 call Get_Para_Offset
;For dynamic allocation, we are
1200 ;going to use offset address that
1201 ;is in paragraph boundary.
1205 cld ;clear direction
1207 cmp [num_mini_dsk
], 0 ;Mini disk(s) installed ?
1209 mov ax, End_Of_BDSM
;set the new ending address
1210 call Get_Para_Offset
1212 cmp Model_Byte
, 0FCh ;AT ?
1214 cmp HNUM
, 0 ;No hard file?
1218 mov es, si ;ES -> BIOS segment
1220 mov si, offset BIOS_DATE
;
1221 mov di, 0FFF5H ;ROM BIOS string is at F000:FFF5
1222 Cmpbyte: ;Only patch ROM for bios dated 01/10/84
1224 jnz CheckCMOSClock
;
1225 cmp byte ptr [si-1],0 ;
1227 SetRomCode: ;Now we have to install ROM fix
1228 ;AX is the address to move.
1230 pop es ;set ES to CODE seg
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
1245 pop es ;set ES to CODE seg
1247 cmp HaveCMOSClock
, 1 ;CMOS Clock exists?
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
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
1264 call Get_Para_Offset
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****************************************************************
1276 mov si, offset INT6C
1277 mov cx, offset ENDK09
1278 sub cx, si ;size of K09 routine
1280 push di ;save destination
1283 call Get_Para_Offset
;AX = new ending address
1288 mov fHaveK09
, 1 ;remember we have a K09 type
1293 mov word ptr ds:[4 * 6
Ch], di ;new INT 6Ch handler
1294 mov ds:[4 * 6
Ch +2], cs
1298 pop ax ;restore the ending address
1300 ; SET UP CONFIG STUFF FOR SYSINIT
1302 CONFIGDONE: ;AX is final ending address of MSBIO.
1305 ASSUME
DS:SYSINITSEG
1307 SUB AX,OFFSET START$
1313 MOV FINAL_DOS_LOCATION
, AX
1317 ADD FINAL_DOS_LOCATION
,CODE
1318 MESSAGE FTESTINIT
,<"FINAL DOS LOCATION IS ">
1319 MNUM FTESTINIT
,FINAL_DOS_LOCATION
1320 MESSAGE FTESTINIT
,<CR
,LF
>
1324 ASSUME
DS:CODE,ES:NOTHING
1326 CMP BYTE PTR FHAVE96
,0
1328 CALL PURGE_96TPI
;MJB001 ELIMINATE CALLS TO 96TPI HOOHAH
1331 MESSAGE FTESTINIT
,<"LOAD FAT",CR
,LF
>
1332 MOV AX,DRVFAT
; GET DRIVE AND FAT ID
1333 CALL SETDRIVE
; GET BDS FOR DRIVE
1335 CALL GETBP
; ENSURE VALID BPB IS PRESENT
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
1341 MOV AL,ES:[DI] ;GET FAT ID BYTE
1342 MOV BYTE PTR DRVFAT
+1,AL ;SAVE FAT BYTE
1344 MESSAGE FTESTINIT
,<"FATID READ ">
1346 MESSAGE FTESTINIT
,<CR
,LF
>
1347 CALL SETDRIVE
;GET CORRECT BDS FOR THIS DRIVE
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
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
1363 mov ax,[di].HIDSEC_H
;subtract upper 16 bits of sector num
1365 ;SB34INIT005******************************************************************
1366 XOR CH,CH ;CX = SECTORS/CLUSTER
1368 ; THE BOOT PROGRAM HAS LEFT THE DIRECTORY AT 0:500
1372 MOV DS,DI ; ES:DI POINTS TO LOAD LOCATION
1373 MOV BX,DS:WORD PTR [53
AH] ; CLUS=*53A;
1375 MESSAGE FTESTINIT
,<"LOAD DOS",CR
,LF
>
1377 ;LOADIT: MOV AX,(((END$ - START$)+15)/16)+SYSIZE
1381 SUB AX, OFFSET START$
1383 RCR AX, 1 ; DIVIDE BY 16
1392 CALL GETCLUS
; CLUS = GETCLUS (CLUS);
1395 TEST FBIGFAT
,FBIG
; IF (FBIGFAT)
1397 MESSAGE FTESTINIT
,<CR
,LF
,"SMALL FAT EOF CHECK",CR
,LF
>
1398 CMP BX,0FF7H ; RETURN (CLUS > 0FF7H);
1401 MESSAGE FTESTINIT
,<CR
,LF
,"BIG FAT EOF CHECK",CR
,LF
>
1402 CMP BX,0FFF7H ; ELSE
1404 JB LOADIT
; } WHILE (!ISEOF (CLUS));
1408 MESSAGE FTESTINIT
,<"SYSINIT",CR
,LF
>
1410 MESSAGE FTESTINIT
,<"ON TO SYSINIT...",CR
,LF
>
1415 ;****************************
1417 Get_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
1425 shl ax, 1 ;now, make it back to offset value
1430 Get_Para_Offset endp
1432 ;AN004; Don't need this procedure. Get_FAT_Sector replace this.
1433 ; READ A FAT SECTOR INTO FAT LOCATION
1435 ; XOR DI,DI ; OFFSET
1436 ; MOV DX,1 ; RELATIVE SECTOR (1ST SECTOR OF FAT)
1437 ; MOV CX,FATLEN ; READ ENTIRE FAT.
1439 ; MOV ES,AX ; LOCATION TO READ
1440 ; MOV AX,DRVFAT ; AH FAT ID BYTE, AL DRIVE
1444 ; READ A BOOT RECORD INTO 7C0:BOOTBIAS
1445 ;AN015; Read a boot record into Init_BootSeg:BOOTBIAS
1448 ;SB33026****************************************************************
1449 mov AX, cs:Init_BootSeg
; prepare to load ES
1450 mov ES, AX ;SB ; load ES segment register
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****************************************************************
1460 CMP WORD PTR ES:[BOOTBIAS
+1FEH
],0AA55H ; DAVE L**** MAGIC BYTE?
1462 MESSAGE FTESTHARD
,<"SIGNATURE AA55 NOT FOUND",CR
,LF
>
1464 MESSAGE FTESTHARD
,<"ERROR IN GETBOOT",CR
,LF
>
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
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
1481 assume
ds:code,es:nothing
1485 MOV BYTE PTR [DI].DRIVELET
,BL
1486 MOV BYTE PTR [DI].DRIVENUM
,DL
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
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
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 ())
1509 JC SETRET
; RETURN -1;
1510 MOV BX,1C2H
+BOOTBIAS
; P = &BOOT[0X1C2];
1512 CMP BYTE PTR ES:[BX],1 ; WHILE (P->PARTITIONTYPE != 1 &&
1515 CMP BYTE PTR ES:[BX],4 ; P->PARTITIONTYPE != 4 &&
1518 ;SB34INIT006******************************************************************
1519 ;SB we have a new partition type 6 now. add code to support this too.
1521 cmp byte ptr es:[bx],6 ; P->PARTITIONTYPE !=6
1523 ;SB34INIT006******************************************************************
1525 ADD BX,16 ; P += SIZEOF PARTITION;
1526 CMP BX,202H
+BOOTBIAS
; IF (P == &BOOT[0X202H])
1527 JNZ SET1
; RETURN -1;}
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.
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
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
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.
1549 mov cs:ROM_drv_num
, dl ;AN000; save the ROM BIOS drive number we are handling now.
1551 MOV AX,WORD PTR ES:[BX+4] ;Hidden sectors
1552 MOV DX,WORD PTR ES:[BX+6]
1555 ;Decrement the sector count by 1 to make it zero based. Exactly 64k
1556 ;sectors should be allowed
1558 SUB AX,1 ; PTM 901 12/12/86 MT
1559 SBB DX,0 ; PTM 901 12/12/86 MT
1561 ADD AX,WORD PTR ES:[BX+8] ;Sectors in Partition
1562 ADC DX,WORD PTR ES:[BX+10]
1565 MESSAGE FTESTHARD
,<"PARTITION INVALID",CR
,LF
>
1569 MOV AX,WORD PTR ES:[BX+4]
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;
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;
1580 ja OKDrive_Cont
;AN000;
1581 CMP AX,64 ; IF (P->PARTITIONLENGTH < 64)
1582 JB SETRET
; RETURN -1;
1584 OKDrive_Cont: ;AN000;
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.
1591 MOV BL,BYTE PTR [DI].SECLIM
1596 mov cs:[Temp_H
],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
1604 MOV BL,BYTE PTR [DI].HDLIM
1607 mov ax, cs:[Temp_H
] ;AN000;
1609 mov cs:[Temp_H
],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
1619 ; CL IS SECTOR NUMBER (assume less than 2**6 = 64 for INT 13h)
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
1625 OKnotMini: ;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
1633 ; CL IS SECTOR + 2 HIGH BITS OF CYLINDER
1634 ; CH IS LOW 8 BITS OF CYLINDER
1636 ; ROM_drv_num IS DRIVE
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
1643 ; CL IS SECTOR + 2 HIGH BITS OF CYLINDER
1644 ; CH IS LOW 8 BITS OF CYLINDER
1647 ;J.K. For convenience, we are going to read the logical boot sector
1648 ;into cs:DiskSector area.
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.
1657 mov bx,offset DiskSector
1658 mov ax,0201h ; read, one sector
1661 ;SB34INIT009*************************************************************
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"
1670 cmp word ptr cs:[bx+5], "O" shl 8 + "D"
1672 cmp byte ptr cs:[bx+7], "S"
1674 ; ...or perhaps pcdos...
1676 CMP WORD PTR cs:[bx+3], "B" SHL 8 + "I"
1678 CMP WORD PTR cs:[bx+5], " " SHL 8 + "M"
1680 ;----------------------------------------------------------------------
1681 ; check for Microsoft OS/2 signature also. 7/29/88. HKN
1683 CMP WORD PTR cs:[bx+3], "S" SHL 8 + "O"
1685 CMP WORD PTR cs:[bx+5], " " SHL 8 + "2"
1687 ;-----------------------------------------------------------------------
1689 sigfound: ; signature was found, now check version
1690 CMP WORD PTR cs:[bx+8], "." SHL 8 + "2"
1692 CMP BYTE PTR cs:[bx+10], "0"
1694 MESSAGE FTESTHARD
,<"VERSION 2.0 MEDIA",CR
,LF
>
1701 JMP UNKNOWN
;Unformatted or illegal media.
1702 UNKNOWN3_0_J: ;AN012;Legally formatted media,
1703 jmp Unknown3_0
;AN012; although, content might be bad.
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
>
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
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
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.
1735 pop es ;AN000; now es:di -> bds
1737 pop ds ;AN000; ds = cs
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;
1744 pop ds ;AN000; Restore Reg.
1746 call Mov_Media_IDs
;AN000; Set Volume id, SystemId, Serial.
1749 COPYBPB_FAT: ;AN000; Fat system
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;
1758 Fat_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)
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
1768 mov bx, cs:[si.DIRNUM
] ;AN000; # root entries
1769 mov [di.cDIR
],bx ;AN000; Set in BDS BPB
1772 shr bx,cl ;AN000; Div by 16 ents/sector
1773 sub ax,bx ;AN000; sub # dir sectors
1775 ;AN000; DX;AX now contains the # of data sectors
1777 MOV CL, cs:[si.SECALL
] ; SECTORS PER CLUSTER
1778 MOV [DI.SECPERCLUS
],CL ; SET IN BIOS BPB
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
1789 div cx ;AN000; cx = sectors per cluster
1790 mov cs:[Temp_H
],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
1800 call Mov_Media_IDs
;AN000; Copy Filesys_ID, Volume label,
1801 ;and Volume serial to BDS table, if extended
1803 JMP Massage_bpb
;AN000; Now final check for BPB info. and return.
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
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.
1815 ;AN008; For the time being, allow it.
1816 ;AN009; Now implemented again
1817 Unknown3_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
1827 cmp dx, word ptr cs:[si] ;AN000;
1829 ja Scan_Next
;AN000;
1830 cmp ax, word ptr cs:[si+2] ;AN000;
1833 add si, 5 * 2 ;AN000;
1834 JMP SCAN
;AN000; Covers upto 512 MB media
1836 ; MOV CL,BYTE PTR [SI+6]
1837 mov cl,byte ptr [si+8] ;AN000; Fat size for FBIGFAT flag
1841 mov cx, word ptr cs:[SI+4] ;AN000;
1842 mov dx, word ptr cs:[SI+6] ;AN000;
1844 ; DX = NUMBER OF DIR ENTRIES,
1845 ; CH = NUMBER OF SECTORS PER CLUSTER
1846 ; CL = LOG BASE 2 OF CH
1848 ; NOW CALCULATE SIZE OF FAT TABLE
1851 MESSAGE FTESTHARD
,<" SECTORS ">
1853 MESSAGE FTESTHARD
,<" DIRECTORY ENTRIES ">
1855 MESSAGE FTESTHARD
,<" SECPERCLUS|CLUSSHIFT">
1857 MOV WORD PTR CDIR
[DI],DX ;SAVE NUMBER OF DIR ENTRIES
1859 ;Now, CX = SecPerClus|Clusshift
1860 ; [DI.CDIR] = number of directory entries.
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 !!!.
1876 ADD BX,AX ;AN000; DX=0
1877 SHR BX,CL ; BX = 1+(BPB->MAXSEC+SECPERCLUS-1)/
1879 AND BL,11111110B ; BX &= ~1; (=NUMBER OF CLUSTERS)
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
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;
1897 ; DEC AX ; AX = T - R - D
1898 SUB ax,1 ;AN000; DX;AX = T - R - D
1901 MOV BH,SECPERCLUS
[DI] ; BX = 256 * SECPERCLUS + 2
1903 ;J.K. I don't understand why to add BX here!!!
1904 ADD AX,BX ; AX = T-R-D+256*SPC+2
1906 SUB AX,1 ; AX = T-R-D+256*SPC+1
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
1914 MOV [DI].FATSIZ
,BL ; SET SIZE OF FAT ON MEDIA
1915 call Clear_IDs
;AN000;
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.
1924 Massage_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;
1937 cmp [di].DRVLIM_H
, 0 ;AN014; Big media?
1938 jbe Not_BigMedia
;AN014; No.
1941 mov ax, SYSINITSEG
;AN014;
1943 mov es:Big_Media_Flag
, 1 ;AN014; Set the flag in SYSINITSEG.
1946 Not_BigMedia: ;AN014;
1948 MOV [DI].FATSIZ
,BL ; SET SIZE OF FAT ON MEDIA
1958 Cover_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.
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;
1973 CFB_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;
1989 Cover_FDISK_Bug endp
;AN010;
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.
1997 ; NO ATTEMPT IS MADE TO PRESERVE REGISTERS SINCE WE ARE GOING TO JUMP TO
1998 ; SYSINIT STRAIGHT AFTER THIS ROUTINE.
2000 SETDRVPARMS PROC
NEAR
2001 MESSAGE FTESTINIT
,<"SETTING DRIVE PARAMETERS",CR
,LF
>
2003 LES DI,DWORD PTR CS:[START_BDS
] ; GET FIRST BDS IN LIST
2012 PUSH DI ; PRESERVE POINTER TO BDS
2013 MOV BL,ES:[DI].FORMFACTOR
2018 MOV AX,ES:[DI].DRVLIM
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;
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
2030 pop dx ;AN000; Restore drvlim.
2035 mov cs:[Temp_H
],ax ;AN000; AX be 0 here.
2037 DIV CX ; DIV #SEC BY SEC/CYL TO GET # CYL.
2039 JZ NO_CYL_RND
; CAME OUT EVEN
2042 MOV ES:[DI].CCYLN
,AX
2043 MESSAGE FTESTINIT
,<"CCYLN ">
2045 MESSAGE FTESTINIT
,<CR
,LF
>
2048 LEA SI,[DI].BYTEPERSEC
; DS:SI -> BPB FOR HARD FILE
2049 JMP SHORT SET_RECBPB
2052 ;J.K. We don't use the extended BPB for a floppy.
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.
2062 cmp cs:FakeFloppyDrv
,1
2064 ;SB34INIT007******************************************************************
2066 CMP BL,FFOTHER
; SPECIAL CASE "OTHER" TYPE OF MEDIUM
2067 JNZ NOT_PROCESS_OTHER
2075 MOV [DI].RDRVLIM
,AX ; HAVE THE TOTAL NUMBER OF SECTORS
2078 ;J.K. Old logic was...
2083 ; INC AX ; ROUND UP NUMBER OF FAT SECTORS
2085 ;J.K. New logic to get the sectors/fat area.
2086 ;Fat entry is assumed to be 1.5 bytes!!!
2097 MOV [DI].RCSECFAT
,AX
2098 JMP SHORT GO_TO_NEXT_BDS
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
2104 LEA DI,[DI].RBYTEPERSEC
; ES:DI -> RECBPB
2106 REP MOVSB ; MOVE BPBSIZ BYTES
2109 POP ES ; RESTORE POINTER TO BDS
2110 MOV BX,WORD PTR ES:[DI].LINK
+2
2111 MOV DI,WORD PTR ES:[DI].LINK
2117 ; READ CLUSTER SPECIFIED IN BX
2118 ; CX = SECTORS PER CLUSTER
2119 ; DI = LOAD LOCATION
2124 MOV DOSCNT
,CX ;SAVE NUMBER OF SECTORS TO READ
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
2136 ;SB34INIT008*************************************************************
2137 ;J.K. Now DX;AX = first logical sector to read
2138 ; MOV DX,AX ;DX = FIRST SECTOR TO READ
2141 MESSAGE FTESTINIT
,<" => ">
2142 ; ;SI = BX, BX = NEXT ALLOCATION UNIT
2144 ; GET THE FAT ENTRY AT BX
2148 push ax ;AN004;Save First logical sector (Low)
2151 MOV DS,SI ;DS -> FATLOC segment
2153 TEST cs:FBIGFAT
,FBIG
;16 bit fat?
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;
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;
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.
2178 mov bx, ax ;AN004; Now BX = New FAT entry.
2179 AND BX,0FFFH ;AN004; keep low 12 bits.
2181 UNPACK16: ;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.
2186 POP SI ;Retore Old BX value into SI
2187 pop ax ;AN004;Restore logical sector (low)
2191 MESSAGE FTESTINIT
,<" ">
2193 CMP SI,-1 ;ONE APART?
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
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
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
2217 GETCLUS ENDP
; RETURN;
2219 Get_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
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.)
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;
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;
2260 GFS_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
2272 Get_FAT_Sector endp
;AN004;
2275 ; SI POINTS TO DEVICE HEADER
2276 ; J.K. 4/22/86 - print_init, aux_init is modified to eliminate the self-modifying
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*****************************************************************
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*****************************************************************
2297 ;SI -> device header
2298 MOV AL,CS:[SI+13] ;GET DEVICE NUMBER FROM THE NAME
2305 ; PURGE_96TPI NOP'S CALLS TO 96TPI SUPPORT.
2307 PURGE_96TPI PROC
NEAR ;MJB001
2315 ASSUME
DS:CODE,ES:CODE
2317 MOV SI,OFFSET PATCHTABLE
2329 ;**************NOT NEEDED ANY MORE***********************
2330 ; MOV DI,OFFSET FORMAT_PATCH ; ARR 2.42
2331 ; MOV AL,CS:INST_FAR_RET
2333 ;********************************************************
2334 MOV DI,OFFSET TABLE_PATCH
; ARR 2.42
2344 ;Mini disk initialization routine. Called right after DoHard - J.K. 4/7/86
2345 ; DoMini **********************************************************************
2347 ; **DoMini will search for every extended partition in the system, and
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
2357 ; **DRVMAX determined in DoHard routine will be used for the next
2358 ; available logical mini disk drive number.
2360 ; Input: DRVMAX, DSKDRVS
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.
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 ;******************************************************************************
2382 assume
ds:code,es:code
2383 Message fTestHard
,<"Start of DoMini...",cr
,lf
>
2385 push ax ;Do I need to do this?
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********************************************************************
2394 jz DoMiniRet
;no hard file? Then exit.
2395 mov numh
, dl ;save the number of hard files.
2398 mov mininum
, al ;this will be the logical drive letter
2399 ;for mini disk to start with.
2401 shl ax, 1 ;ax=number of devices. make it to word boundary
2403 mov bx, offset DSKDRVS
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.
2410 mov Rom_Minidsk_num
, 80h
2412 inc dh ;Get # of heads (convert it to 1 based)
2415 mov Mini_HDLIM
, ax ;save it.
2417 and cl, 3fh
;Get # of sectors/track
2419 mov Mini_SECLIM
, ax ;and save it.
2421 mov dl, Rom_Minidsk_num
;drive number <DL>
2422 call GETBOOT
;read master boot record into 7c0:BootBias
2425 call FIND_MINI_PARTITION
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********************************************************************
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
2449 ;Called routine: SETMINI which uses SET1 (in SETHARD routine)
2450 ;Variables & equates used from original BIOS - flags, fNon_Removable, fBigfat
2453 FIND_MINI_PARTITION:
2455 add bx, 1C2h
;BX -> system id.
2458 cmp byte ptr ES:[BX], 5 ; 5 = extended partition ID.
2460 add bx, 16 ; for next entry
2461 cmp bx, 202h
+BootBias
2463 jmp FmpRet
;not found extended partition
2465 FmpGot: ;found my partition.
2466 Message ftestHard
,<"Found my partition...",cr
,lf
>
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.
2476 mov al, Rom_MiniDsk_Num
2477 mov [DI].DRIVENUM
, al ;set physical number
2479 mov [DI].DRIVELET
, al ;set logical number
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
2485 jb FmpRet
;should be bigger than 64 sectors at least
2486 FmpGot_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
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
2506 push es ;;DCL/KWC 8/2/87 addressability to
2509 call SetMini
;install a mini disk. BX value saved.
2511 pop es ;;DCL/KWC 8/2/87
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.
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
2524 inc Mini_BPB_ptr
;advance to the next address
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>
2531 FmpnextChain: jmp FmpNext
;let's find out if we have any chained partition
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.
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
2550 assume
ds:code,es:nothing
2555 les si, dword ptr cs:Start_BDS
;start of the beginning of list
2557 cmp word ptr es:[si], -1 ;end of the list?
2559 mov si, word ptr es:[si].LINK
2560 mov ax, word ptr es:[si].LINK
+2 ;next pointer
2562 jmp short I_BDSM_Next
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.
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:
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
2595 ;**End of mini disk initialization** ;J.K. 4/7/86
2598 CMOS_Clock_Read proc
near
2600 assume
ds:code,es:code
2601 ; IN ORDER TO DETERMINE IF THERE IS A CLOCK PRESENT IN THE SYSTEM, THE FOLLOWING
2612 ;SB33030********************************************************************
2613 MOV AH,2 ;READ REAL TIME CLOCK ;SB ;3.30
2614 INT 1
Ah ;CALL ROM-BIOS ROUTINE ;SB ;3.30
2615 ;SB33030********************************************************************
2622 CMP BP,1 ; READ AGAIN AFTER A SLIGHT DELAY, IN CASE CLOCK
2623 JZ NO_READDATE
; WAS AT ZERO SETTING.
2625 INC BP ; ONLY PERFORM DELAY ONCE.
2632 mov cs:HaveCMOSClock
, 1 ;J.K. Set the flag for cmos clock
2634 call CMOSCK
;J.K. Reset CMOS clock rate that may be
2635 ;possibly destroyed by CP DOS and POST routine did not
2639 MESSAGE FTESTINIT
,<"CLOCK DEVICE",CR
,LF
>
2640 CALL READ_REAL_DATE
;MJB002 READ REAL-TIME CLOCK FOR DATE
2643 MOV DAYCNT
,SI ;MJB002 SET SYSTEM DATE
2653 CMOS_Clock_Read endp
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.
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.
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.
2674 ; This code exposes one to DOS clearing CMOS setup done by a
2675 ; resident program that hides and re-boots the system.
2677 CMOSCK PROC
NEAR ; CHECK AND RESET RTC RATE BITS
2678 assume
ds:nothing
,es:nothing
2680 ;Model byte and Submodel byte were already determined in MSINIT.
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
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.
2691 CMOSCK4: ; RESET THE CMOS PERIODIC RATE
2692 ; Model=FC submodel=00,01,02,03 or 06
2693 ;SB33IN2***********************************************************************
2695 mov al,CMOS_REG_A
or NMI
;NMI disabled on return
2696 mov ah,00100110b ;Set divider & rate selection
2699 ;SB33IN2***********************************************************************
2701 ; CLEAR SET,PIE,AIE,UIE AND SQWE
2702 mov al,CMOS_REG_B
or NMI
;NMI disabled on return
2704 and al,00000111b ;clear SET,PIE,AIE,UIE,SQWE
2706 mov al,CMOS_REG_B
;NMI enabled on return
2709 ;SB33IN3***********************************************************************
2711 CMOSCK9: ; EXIT ROUTINE
2713 RET ; RETurn to caller
2717 ;--- CMOS_READ -----------------------------------------------------------------
2718 ; READ BYTE FROM CMOS SYSTEM CLOCK CONFIGURATION TABLE :
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 :
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 ;-------------------------------------------------------------------------------
2732 CMOS_READ PROC
NEAR ; READ LOCATION (AL) INTO (AL)
2733 assume
es:nothing
,ds:nothing
2734 PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS
2735 ;SB33IN4********************************************************************
2739 push ax ;save user NMI state
2740 or al,NMI
;disable NMI for us
2742 nop ;undocumented delay needed
2743 in al,CMOS_DATA
;get data value
2745 ;set NMI state to user specified
2746 mov bx,ax ;save data value
2747 pop ax ;get user NMI
2749 or al,CMOS_SHUT_DOWN
2754 mov ax,bx ;data value
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
2764 CMOS_POPF PROC
NEAR ; POPF FOR LEVEL B- PARTS
2765 IRET ; RETURN FAR AND RESTORE FLAGS
2769 ;--- CMOS_WRITE ----------------------------------------------------------------
2770 ; WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE :
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 :
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 ;-------------------------------------------------------------------------------
2785 CMOS_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
2791 push ax ;save user NMI state
2792 or al,NMI
;disable NMI for us
2796 out CMOS_DATA
,al ;write data
2798 ;set NMI state to user specified
2799 pop ax ;get user NMI
2801 or al,CMOS_SHUT_DOWN
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