DOS 3.30 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2213 lines
67 KiB

4 years ago
  1. ; modification history
  2. ;
  3. ; 3.21 sp added pushf-popf fix around NoParms to fix bug
  4. ;;Rev 3.30 Modification -----------------------------------------------
  5. test = 0
  6. include msgroup.inc ;define code segment
  7. include dskprm.inc
  8. include msequ.inc
  9. include msmacro.inc
  10. include msextrn.inc
  11. include biostruc.inc
  12. include cmosequ.inc
  13. EXTRN OLD13:DWORD
  14. ; THE FOLLOWING LABEL DEFINES THE END OF THE AT ROM PATCH. THIS IS USED
  15. ; AT CONFIGURATION TIME.
  16. ; Warning!!! This code will be dynamically relocated by MSINIT.
  17. PUBLIC ENDATROM ;NOT REFERENCES EXTERNALLY, BUT
  18. ; JUST TO CAUSE ENTRY IN LINK MAP
  19. ENDATROM LABEL BYTE
  20. ;CMOS Clock setting support routines used by MSCLOCK.
  21. ;Warning!!! This code will be dynamically relocated by MSINIT.
  22. EXTRN base_century:byte
  23. EXTRN base_year:byte
  24. EXTRN month_tab:byte
  25. public Daycnt_to_day ;for real time clock support
  26. Daycnt_to_day proc near ;for real time clock support
  27. ;Entry: [DAYCNT] = number of days since 1-1-80
  28. ;Return: CH=centry in BCD, CL=year in BCD, DH=month in BCD, DL=day in BCD
  29. push [daycnt] ;save daycnt
  30. cmp daycnt, (365*20+(20/4)) ;# days from 1-1-1980 to 1-1-2000
  31. jae century20
  32. mov base_century, 19
  33. mov base_year, 80
  34. jmp years
  35. century20: ;20th century
  36. mov base_century, 20
  37. mov base_year, 0
  38. sub daycnt, (365*20+(20/4)) ;adjust daycnt
  39. years:
  40. xor dx, dx
  41. mov ax, daycnt
  42. mov bx, (366+365*3) ;# of days in a Leap year block
  43. div bx ;AX = # of leap block, DX=daycnt
  44. mov daycnt, dx ;save daycnt left
  45. ; or ah, ah ;ax should be less than 256
  46. ; jz OK1
  47. ; jmp Erroroccur
  48. ;OK1:
  49. mov bl,4
  50. mul bl ;AX=# of years. Less than 100
  51. add base_year, al ;So, ah = 0. Adjust year
  52. inc daycnt ;set daycnt to 1 base
  53. cmp daycnt, 366 ;daycnt=remainder of leap year bk
  54. jbe Leapyear ;within 366+355+355+355 days.
  55. inc base_year ;if daycnt <= 366, then leap year
  56. sub daycnt, 366 ;else daycnt--, base_year++;
  57. ;And next three years are normal
  58. mov cx, 3
  59. Regularyear:
  60. cmp daycnt, 365 ;for(i=1; i>3 or daycnt <=365;i++)
  61. jbe YearDone ;{if (daycnt > 365)
  62. inc base_year ; { daycnt -= 365
  63. sub daycnt, 365 ; }
  64. loop regularyear ;}
  65. ; jmp Erroroccur ;cannot come to here
  66. Leapyear:
  67. mov byte ptr month_tab+1,29 ;leap year. change month table.
  68. Yeardone:
  69. xor bx,bx
  70. xor dx,dx
  71. mov ax, daycnt
  72. mov si, offset month_tab
  73. mov cx, 12
  74. Months:
  75. inc bl ;
  76. mov dl, byte ptr ds:[si] ;cmp daycnt for each month til fit
  77. cmp ax, dx ;dh=0.
  78. jbe Month_done
  79. inc si ;next month
  80. sub ax, dx ;adjust daycnt
  81. loop Months
  82. ; jmp Erroroccur
  83. Month_done:
  84. mov byte ptr month_tab+1, 28 ;restore month table value
  85. mov dl, bl
  86. mov dh, base_year
  87. mov cl, base_century ;al=day,dl=month,dh=year,cl=cntry
  88. call word ptr BinToBCD ;To save 15 bytes, Bin_To_BCD proc
  89. ;was rel from Daycnt_to_Day proc.
  90. ; call Bin_to_bcd ;convert "day" to bcd
  91. xchg dl, al ;dl = bcd day, al = month
  92. call word ptr BinToBCD
  93. ; call Bin_to_bcd
  94. xchg dh, al ;dh = bcd month, al = year
  95. call word ptr BinToBCD
  96. ; call Bin_to_bcd
  97. xchg cl, al ;cl = bcd year, al = century
  98. call word ptr BinToBCD
  99. ; call Bin_to_bcd
  100. mov ch, al ;ch = bcd century
  101. pop [daycnt] ;restore original value
  102. ret
  103. Daycnt_to_day endp
  104. public EndDaycntToDay
  105. EndDaycntToDay label byte
  106. public Bin_to_bcd
  107. Bin_to_bcd proc near ; real time clock sup
  108. ;Convert a binary input in AL (less than 63h or 99 decimal)
  109. ;into a bcd value in AL. AH destroyed.
  110. push cx
  111. xor ah, ah
  112. mov cl, 10
  113. div cl ;al=high digit bcd, ah=low digit bcd
  114. mov cl, 4
  115. shl al, cl ;mov the high digit to high nibble
  116. or al, ah
  117. pop cx
  118. ret
  119. Bin_to_bcd endp
  120. Public EndCMOSClockset ;End of routines for CMOS clock
  121. EndCMOSClockset label byte
  122. ;
  123. EXTRN INT6C_RET_ADDR:DWORD ; RETURN ADDRESS FROM INT 6C
  124. EXTRN BIN_DATE_TIME:BYTE
  125. EXTRN MONTH_TABLE:WORD
  126. EXTRN DAYCNT2:WORD
  127. EXTRN FEB29:BYTE
  128. EXTRN TimeToTicks:Word ;indirect intra-segment call add
  129. EVENB
  130. ;
  131. ; THE K09 REQUIRES ROUTINES FOR READING THE CLOCK BECAUSE OF THE SUSPEND/
  132. ; RESUME FACILITY. THE SYSTEM CLOCK NEEDS TO BE RESET AFTER RESUME.
  133. ;
  134. ASSUME ES:NOTHING
  135. ; THE FOLLOWING ROUTINE IS EXECUTED AT RESUME TIME WHEN THE SYSTEM
  136. ; POWERED ON AFTER SUSPENSION. IT READS THE REAL TIME CLOCK AND
  137. ; RESETS THE SYSTEM TIME AND DATE, AND THEN IRETS.
  138. ; Warning!!! This code will be dynamically relocated by MSINIT.
  139. INT6C PROC FAR
  140. PUSH CS
  141. POP DS
  142. ASSUME DS:CODE
  143. POP WORD PTR INT6C_RET_ADDR ; POP OFF RETURN ADDRESS
  144. POP WORD PTR INT6C_RET_ADDR+2
  145. POPF
  146. CALL READ_REAL_DATE ; GET THE DATE FROM THE CLOCK
  147. CLI
  148. MOV DS:DAYCNT,SI ; UPDATE DOS COPY OF DATE
  149. STI
  150. CALL READ_REAL_TIME ; GET THE TIME FROM THE RTC
  151. CLI
  152. MOV AH, 01h ; COMMAND TO SET THE TIME
  153. INT 1Ah ; CALL ROM-BIOS TIME ROUTINE
  154. STI
  155. JMP INT6C_RET_ADDR ; LONG JUMP
  156. INT6C ENDP
  157. INCLUDE READCLOCK.INC
  158. INCLUDE CLOCKSUB.INC
  159. PUBLIC ENDK09 ;NOT REFERENCES EXTERNALLY, BUT
  160. ; JUST TO CAUSE ENTRY IN LINK MAP
  161. ENDK09 LABEL BYTE
  162. ASSUME DS:NOTHING,ES:NOTHING
  163. ;;End of Modification -----------------------------------------------
  164. ;------------------------------------------------------------------------
  165. ; :
  166. ; System initiailzation :
  167. ; :
  168. ; The entry conditions are established by the bootstrap :
  169. ; loader and are considered unknown. The following jobs :
  170. ; will be performed by this module: :
  171. ; :
  172. ; 1. All device initialization is performed :
  173. ; 2. A local stack is set up and DS:SI are set :
  174. ; to point to an initialization table. Then :
  175. ; an inter-segment call is made to the first :
  176. ; byte of the dos :
  177. ; 3. Once the dos returns from this call the ds :
  178. ; register has been set up to point to the start :
  179. ; of free memory. The initialization will then :
  180. ; load the command program into this area :
  181. ; beginning at 100 hex and transfer control to :
  182. ; this program. :
  183. ; :
  184. ;------------------------------------------------------------------------
  185. ; DRVFAT must be the first location of freeable space!
  186. EVENB
  187. DRVFAT DW 0000 ; Drive and FAT ID of DOS
  188. BIOS$ DW 0000 ; First sector of data
  189. DOSCNT DW 0000 ; How many sectors to read
  190. fBigFAT DB 0 ; Flags for drive
  191. FatLen DW ? ; number of sectors in FAT.
  192. FatLoc DW ? ; seg addr of fat sector
  193. ;;Rev 3.30 Modification -----------------------------------------------
  194. ; THE FOLLOWING TWO BYTES ARE USED TO SAVE INFO RETURNED BY INT 13, AH=8
  195. ; CALL TO DETERMINE DRIVE PARAMETERS.
  196. NUM_HEADS DB 2 ; NUMBER OF HEADS RETURNED BY ROM
  197. SEC_TRK DB 9 ; SEC/TRK RETURNED BY ROM
  198. NUM_CYLN DB 40 ; NUMBER OF CYLINDERS RET BY ROM
  199. public Model_Byte
  200. MODEL_BYTE DB 0FFH ; MODEL BYTE. SET UP AT INIT TIME.
  201. ; FF - PC-1, EXPANSION, OLD PC-2
  202. ; FE - NEWER PC-2 (64/256K PLANAR)
  203. ; FD -
  204. ; FC -
  205. public Secondary_Model_Byte
  206. Secondary_Model_Byte db 0
  207. ;;End of Modification -----------------------------------------------
  208. BOOTBIAS = 200H
  209. EVENB
  210. DiskTable DW 512, 0100h, 64, 0
  211. DW 2048, 0201h, 112, 0
  212. DW 8192, 0402h, 256, 0
  213. DW 32680, 0803h, 512, 0
  214. DW 65535, 1004h, 1024, 0
  215. DiskTable2 DW 32680, 0803h, 512, 0
  216. DW 65535, 0402h, 512, fBIG
  217. ;;Rev 3.30 Modification -----------------------------------------------
  218. ;*************************************************************************
  219. ;Variables for Mini disk initialization
  220. ;*************************************************************************
  221. End_Of_BDSM dw ? ;offset value of the ending add
  222. ;of BDSM table. Needed to figure
  223. ;the Final_DOS_Location.
  224. numh db 0 ;number of hard files
  225. mininum db 0 ;logical drive num for mini disk
  226. num_mini_dsk db 0 ;# of mini disk installed
  227. Rom_Minidsk_num db 80h ;physical mini disk number
  228. Mini_HDLIM dw 0
  229. Mini_SECLIM dw 0
  230. Mini_BPB_ptr dw 0 ;temporary variable used to save
  231. ;Mini Disk BPB pt add in DskDrvs.
  232. ;;End of Modification -----------------------------------------------
  233. Bios_Date DB '01/10/84',0
  234. ;
  235. ; The following are the recommended BPBs for the media that we know of so
  236. ; far.
  237. ; 48 tpi diskettes
  238. EVENB
  239. BPB48T DW 512
  240. DB 2
  241. DW 1
  242. DB 2
  243. DW 112
  244. DW 2*9*40
  245. DB 0FDH
  246. DW 2
  247. DW 9
  248. DW 2
  249. DD 0 ;hidden sectors - sp
  250. DD 0 ;big total sectors - sp
  251. DB 6 DUP(?) ;reserved
  252. ; 96tpi diskettes
  253. EVENB
  254. BPB96T DW 512
  255. DB 1
  256. DW 1
  257. DB 2
  258. DW 224
  259. DW 2*15*80
  260. DB 0f9H
  261. DW 7
  262. DW 15
  263. DW 2
  264. DD 0 ;hidden sectors - sp
  265. DD 0 ;big total sectors - sp
  266. DB 6 DUP(?) ;reserved
  267. BPBSIZ = $-BPB96T
  268. ; 3 1/2 inch diskette BPB
  269. EVENB
  270. BPB35 DW 512
  271. DB 2
  272. DW 1 ; Double sided with 9 sec/trk
  273. DB 2
  274. DW 70h
  275. DW 2*9*80
  276. DB 0f9H
  277. DW 3
  278. DW 9
  279. DW 2
  280. DD 0 ;hidden sectors - sp
  281. DD 0 ;big total sectors - sp
  282. DB 6 DUP(?) ;reserved
  283. EVENB
  284. BPBTable dw BPB48T ; 48tpi drives
  285. dw BPB96T ; 96tpi drives
  286. dw BPB35 ; 3.5" drives
  287. ;dw BPB48T ; Not used - 8" drives
  288. ;dw BPB48T ; Not Used - 8" drives
  289. ;dw BPB48T ; Not Used - hard files
  290. ;dw BPB48T ; Not Used - tape drives
  291. ;dw BPB48T ; Not Used - Other
  292. PatchTable LABEL BYTE
  293. DW 10,media_patch
  294. DW 3,getbp1_patch
  295. DW 3,SET_PATCH
  296. DW 3,DiskIO_Patch
  297. DW 3,DSKErr
  298. DW 10,Changed_Patch
  299. DW 3,INIT_PATCH
  300. DW 0
  301. ASSUME DS:NOTHING,ES:NOTHING
  302. ;
  303. ; Entry from boot sector. The register contents are:
  304. ; DL = INT 13 drive number we booted from
  305. ; CH = media byte
  306. ; BX = First data sector on disk (0-based)
  307. ;
  308. Public INIT
  309. INIT PROC NEAR
  310. MESSAGE FTESTINIT,<"MSBIO",CR,LF> ;3.30
  311. CLI
  312. XOR AX,AX
  313. MOV DS,AX
  314. ;
  315. ; Preserve original int 13 vector
  316. ; We need to save INT13 in two places in case we are running on an AT.
  317. ; On ATs we install the IBM supplied ROM_BIOS patch DISK.OBJ which hooks
  318. ; INT13 ahead of ORIG13. Since INT19 must unhook INT13 to point to the
  319. ; ROM INT13 routine, we must have that ROM address also stored away.
  320. ;
  321. MOV AX,DS:[13h*4]
  322. MOV WORD PTR Old13,AX
  323. MOV WORD PTR Orig13,AX
  324. MOV AX,DS:[13h*4+2]
  325. MOV WORD PTR Old13+2,AX
  326. MOV WORD PTR Orig13+2,AX
  327. ;
  328. ; Set up INT 13 for new action
  329. ;
  330. MOV WORD PTR DS:[13h*4],OFFSET Block13
  331. MOV DS:[13h*4+2],CS
  332. ;
  333. ; Preserve original int 19 vector
  334. ;
  335. MOV AX,DS:[19h*4]
  336. MOV WORD PTR Orig19,AX
  337. MOV AX,DS:[19h*4+2]
  338. MOV WORD PTR Orig19+2,AX
  339. ;
  340. ; Set up INT 19 for new action
  341. ;
  342. MOV WORD PTR DS:[19h*4],OFFSET int19
  343. MOV DS:[19h*4+2],CS
  344. STI
  345. int 11h ; rom-bios equipment determination
  346. ROL AL,1 ;PUT BITS 6 & 7 INTO BITS 0 & 1
  347. ROL AL,1
  348. AND AX,3 ;ONLY LOOK AT BITS 0 & 1
  349. JNZ NOTSINGLE ;ZERO MEANS SINGLE DRIVE SYSTEM
  350. INC AX ;PRETEND IT'S A TWO DRIVE SYSTEM
  351. INC CS:SINGLE ;REMEMBER THIS
  352. NOTSINGLE:
  353. INC AX ;AX HAS NUMBER OF DRIVES, 2-4
  354. ;IS ALSO 0 INDEXED BOOT DRIVE IF WE
  355. ; BOOTED OFF HARD FILE
  356. mov CL, AL ; save number of diskette drives in CL
  357. test DL, 80h ; booted from hard disk ?
  358. jnz GotHrd ; yes, jump down
  359. xor AX, AX ; no - indicate boot from drive A
  360. GotHrd:
  361. ; At this point the registers contain these values:
  362. ; AX = 0-based drive we booted from
  363. ; BX = the logical number of the first data sector on the disk
  364. ; CL = number of floppies including logical one
  365. ; CH = media byte
  366. ;
  367. Message fTestINIT,<"Init",CR,LF>
  368. ;
  369. ; set up local stack
  370. ;
  371. xor DX,DX
  372. cli ; turn interrupts off while manupulating stack
  373. mov SS,DX ; set stack segment register
  374. mov SP,700h ; set stack pointer
  375. sti ; turn interrupts on
  376. ASSUME SS:NOTHING
  377. ; preserve some of the values in registers
  378. push CX ; save number of floppies and media byte
  379. mov BIOS$,BX ; save first data sector
  380. mov AH,CH ; FAT ID to AH too
  381. push AX ; save boot drive number, and media byte
  382. ;;Rev 3.30 Modification -----------------------------------------------
  383. ; Let Model_byte, Secondary_Model_Byte be set here!!!
  384. mov ah,0c0h ; return system environment
  385. int 15h ; call ROM-Bios routine
  386. jc No_Rom_System_Conf ; just use Model_Byte
  387. cmp ah, 0 ; double check
  388. jne No_Rom_System_Conf
  389. mov al, ES:[BX.bios_SD_modelbyte] ;get the model byte
  390. mov [Model_Byte], al
  391. mov al, ES:[BX.bios_SD_scnd_modelbyte] ;secondary model byte
  392. mov [Secondary_Model_Byte], al
  393. jmp short Turn_Timer_On
  394. No_Rom_System_Conf:
  395. MOV SI,0FFFFH ;MJB001
  396. MOV ES,SI ;MJB001
  397. MOV AL,ES:[0EH] ; GET MODEL BYTE ARR 2.41
  398. MOV MODEL_BYTE,AL ; SAVE MODEL BYTE ARR 2.41
  399. ;;End of Modification -----------------------------------------------
  400. Turn_Timer_On:
  401. mov AL,EOI
  402. out AKPORT,AL ; turn on the timer
  403. Message fTestINIT,<"COM devices",CR,LF>
  404. ;;Rev 3.30 Modification -----------------------------------------------
  405. mov si,offset COM4DEV
  406. call AUX_INIT
  407. mov si,offset COM3DEV
  408. call AUX_INIT
  409. ;;End of Modification -----------------------------------------------
  410. mov SI,OFFSET COM2DEV
  411. call AUX_INIT ;INIT COM2
  412. mov SI,OFFSET COM1DEV
  413. call AUX_INIT ;INIT COM1
  414. Message fTestINIT,<"LPT devices",CR,LF>
  415. mov SI,OFFSET LPT3DEV
  416. call PRINT_INIT ;INIT LPT3
  417. mov SI,OFFSET LPT2DEV
  418. call PRINT_INIT ;INIT LPT2
  419. mov SI,OFFSET LPT1DEV
  420. call PRINT_INIT ;INIT LPT1
  421. xor DX,DX
  422. mov DS,DX ;TO INITIALIZE PRINT SCREEN VECTOR
  423. mov ES,DX
  424. xor AX,AX
  425. mov DI,INITSPOT
  426. stosw ;INIT four bytes to 0
  427. stosw
  428. mov AX,CS ;FETCH SEGMENT
  429. mov DS:WORD PTR BRKADR,OFFSET CBREAK ;BREAK ENTRY POINT
  430. mov DS:BRKADR+2,AX ;VECTOR FOR BREAK
  431. mov DS:WORD PTR CHROUT*4,OFFSET WORD PTR OUTCHR
  432. mov DS:WORD PTR CHROUT*4+2,AX
  433. Message fTestINIT,<"Interrupt vectors",CR,LF>
  434. mov DI,4
  435. mov BX,OFFSET INTRET ;WILL INITIALIZE REST OF INTERRUPTS
  436. xchg AX,BX
  437. stosw ;Location 4
  438. xchg AX,BX
  439. stosw ;INT 1 ;Location 6
  440. add DI,4
  441. xchg AX,BX
  442. stosw ;Location 12
  443. xchg AX,BX
  444. stosw ;INT 3 ;Location 14
  445. xchg AX,BX
  446. stosw ;Location 16
  447. xchg AX,BX
  448. stosw ;INT 4 ;Location 18
  449. mov DS:WORD PTR 500H,DX ;SET PRINT SCREEN & BREAK =0
  450. mov DS:WORD PTR LSTDRV,DX ;clean out last drive spec
  451. Message fTestINIT,<"Disk parameter table",CR,LF>
  452. mov SI,WORD PTR DS:DSKADR ; ARR 2.41
  453. mov DS,WORD PTR DS:DSKADR+2 ; DS:SI -> current table ARR 2.41
  454. mov DI,SEC9 ; ES:DI -> New Table ARR 2.41
  455. mov CX,SIZE DISK_PARMS ; ARR 2.41
  456. rep MOVSB ; Copy Table ARR 2.41
  457. push ES ; ARR 2.41
  458. pop DS ; DS = 0 ARR 2.41
  459. mov WORD PTR DS:DSKADR,SEC9 ; ARR 2.41
  460. mov WORD PTR DS:DSKADR+2,DS ; Point disk parm vector to new table
  461. ; ARR 2.41
  462. ;-----------------------------------------------
  463. ;
  464. ; THE FOLLOWING DEPEND ON THE TYPE OF MACHINE.
  465. ;
  466. CMP MODEL_BYTE,0FDH ; IS THIS AN OLD ROM? ARR 2.41
  467. JB NO_DIDDLE ; NO ARR 2.41
  468. MOV WORD PTR DS:(SEC9 + DISK_HEAD_STTL),0200H+NORMSETTLE
  469. ; SET HEAD SETTLE AND MOTOR START
  470. ; ON PC-1 PC-2 PC-XT HAL0 ARR 2.41
  471. MOV DS:(SEC9 + DISK_SPECIFY_1),0DFH
  472. ; SET 1ST SPECIFY BYTE
  473. ; ON PC-1 PC-2 PC-XT HAL0 ARR 2.41
  474. NO_DIDDLE: ; ARR 2.41
  475. int 12h ; call rom-bios for memory size
  476. mov CL, 6 ; get ready for shift
  477. shl AX, CL ; change from K to 16 byte blocks
  478. pop CX ; restore CX
  479. mov DRVFAT, CX
  480. push AX
  481. mov dx,ds:(7C00h + 16h) ; number of sectors/fat from boot sec
  482. xor dh,dh
  483. mov FatLen,DX
  484. ;
  485. ; Convert sector count to paragraph count:512 bytes / sec / 16 bytes / para
  486. ; = 32 para /sector
  487. ;
  488. ;;Rev 3.30 Modification -----------------------------------------------
  489. SHL DX,1
  490. SHL DX,1
  491. SHL DX,1
  492. SHL DX,1
  493. SHL DX,1
  494. ;;End of Modification -----------------------------------------------
  495. SUB AX,dx ; room for FAT
  496. MOV FatLoc,AX ; location to read fat
  497. POP AX
  498. MOV DX,SYSINITSEG
  499. MOV DS,DX
  500. ASSUME DS:SYSINITSEG
  501. MOV WORD PTR DEVICE_LIST,OFFSET CONHeader
  502. MOV WORD PTR DEVICE_LIST+2,CS
  503. ; Allocation of buffers has moved to SYSINIT - Aug 19/85 BAS
  504. ;DEF_BUFF:
  505. MOV MEMORY_SIZE,AX
  506. INC CL
  507. MOV DEFAULT_DRIVE,CL ;SAVE DEFAULT DRIVE SPEC
  508. ;DOSSEG = ((((OFFSET END$)-(OFFSET START$))+15)/16)+BIOSEG+SYSIZE
  509. ; BAS DEBUG
  510. ;MOV CURRENT_DOS_LOCATION,((((OFFSET END$)-(OFFSET START$))+15)/16)+SYSIZE
  511. MOV AX, OFFSET END$
  512. SUB AX, OFFSET START$
  513. ADD AX, 15
  514. RCR AX, 1 ; DIVIDE BY 16
  515. SHR AX, 1
  516. SHR AX, 1
  517. SHR AX, 1
  518. ADD AX, SYSIZE
  519. ADD AX, CODE
  520. MOV Current_DOS_Location, AX
  521. ; BAS DEBUG
  522. ; ADD Current_DOS_Location,CODE
  523. ;
  524. ; IMPORTANT: Some old IBM hardware generates spurious INT F's due to bogus
  525. ; printer cards. We initialize this value to point to an IRET ONLY IF
  526. ;
  527. ; 1) The original segment points to storage inside valid RAM.
  528. ;
  529. ; 2) The original segment is 0F000:xxxx
  530. ;
  531. ; Theses are capricious requests from our OEM for reasons behind them, read
  532. ; the DCR's for the IBM DOS 3.2 project.
  533. ;
  534. push ax
  535. ASSUME ES:SYSINITSEG, DS:NOTHING
  536. mov ax,SYSINITSEG
  537. mov es,ax
  538. xor ax,ax
  539. mov ds,ax
  540. mov ax,word ptr ds:(0fH*4+2) ; segment for Int 15
  541. cmp ax,es:MEMORY_SIZE ; Condition 1
  542. jna ResetIntF
  543. cmp ax, 0F000h ; Condition 2
  544. jne KeepIntF
  545. ResetIntF:
  546. mov word ptr ds:[0FH*4],offset INTRET
  547. mov word ptr ds:[0FH*4+2],cs
  548. KeepIntF:
  549. pop ax
  550. ;
  551. ; END IMPORTANT
  552. ;
  553. ;**************************************************************
  554. ; WILL INITIALIZE THE NUMBER OF DRIVES
  555. ; AFTER THE EQUIPMENT CALL (INT 11H) BITS 6&7 WILL TELL
  556. ; THE INDICATIONS ARE AS FOLLOWS:
  557. ;
  558. ; BITS 7 6 DRIVES
  559. ; 0 0 1
  560. ; 0 1 2
  561. ; 1 0 3
  562. ; 1 1 4
  563. ;**************************************************************
  564. PUSH CS
  565. POP DS
  566. PUSH CS
  567. POP ES
  568. ASSUME DS:CODE,ES:CODE
  569. call CMOS_Clock_Read ;Before doing anything if CMOS clock,
  570. ;then set the system time accordingly.
  571. ;Also, reset the cmos clock rate.
  572. Message fTestINIT,<"Disk devices",CR,LF>
  573. XOR SI,SI
  574. MOV WORD PTR [SI],OFFSET HARDDRV ;set up pointer to hdrive
  575. POP AX ;number of floppies and FAT ID
  576. XOR AH,AH ; Chuck FAT ID byte
  577. MOV HARDNUM,AL ;Remember which drive is hard disk
  578. MOV DRVMAX,AL ;And set initial number of drives
  579. SHL AX,1 ;Two bytes per address
  580. MOV DI,OFFSET DSKDRVS
  581. ADD DI,AX ;Point to hardfile location
  582. MOV SI,OFFSET HDSKTAB
  583. MOVSW ;Two addresses to move
  584. MOVSW
  585. MESSAGE FTESTINIT,<"BEFORE INT 13",CR,LF>
  586. mov DL, 80h ; tell rom bios to look at hard drives
  587. mov AH, 8h ; set command to get drive parameter
  588. int 13h ; call ROM-BIOS to get number of drives
  589. jc ENDDRV ; old, rom therefore no hard disks
  590. mov HNUM, DL ; save number of hard drives in HNUM
  591. ENDDRV:
  592. Message fTestINIT,<"Setting up BDSs",CR,LF>
  593. ;
  594. ; Scan the list of drives to determine their type. We have three flavors of
  595. ; diskette drives:
  596. ;
  597. ; 48tpi drives We do nothing special for them
  598. ; 96tpi drives Mark the fact that they have changeline support.
  599. ; 3 1/4 drives Mark changeline support and small.
  600. ;
  601. ; The following code uses registers for certain values:
  602. ; DL - Physical Drive
  603. ; DS:DI - points to current BDS
  604. ; CX - Flag bits for BDS
  605. ; DH - Form Factor for the drive (1 - 48tpi, 2 - 96tpi, 3 - 3.5" medium)
  606. ;
  607. XOR DL,DL ; start out with drive 0.
  608. push cs
  609. pop ds
  610. ASSUME DS:CODE
  611. MOV EOT,9
  612. mov di,offset Start_BDS
  613. loop_drive:
  614. cmp dl,drvmax
  615. jb got_more
  616. jmp Done_Drives
  617. got_more:
  618. xor cx,cx ; zero all flags
  619. mov di,word ptr [di].link ; get next BDS
  620. mov dh,ff48tpi ; Set Form Factor to 48 tpi
  621. MOV NUM_CYLN,40 ; 40 TRACKS PER SIDE
  622. PUSH DS
  623. PUSH DI
  624. PUSH DX
  625. PUSH CX
  626. PUSH ES
  627. MOV AH, 8h ;GET DRIVE PARAMETERS
  628. INT 13h ;CALL ROM-BIOS
  629. JNC PARMSFROMROM
  630. JMP NOPARMSFROMROM ; GOT AN OLD ROM
  631. PARMSFROMROM:
  632. ;If CMOS is bad, it gives ES,AX,BX,CX,DH,DI=0. CY=0.
  633. ;In this case, we are going to put bogus informations to BDS table.
  634. ;We are going to set CH=39,CL=9,DH=1 to avoid divide overflow when
  635. ;they are calculated at the later time. This is just for the Diagnostic
  636. ;Diskette which need IO.SYS,MSDOS to boot up before it sets CMOS.
  637. ;This should only happen with drive B.
  638. ;;Rev 3.30 Modification -----------------------------------------------
  639. CMP CH,0 ; if ch=0, then cl,dh=0 too.
  640. JNE PFR_OK
  641. MOV CH,39 ; ROM gave wrong info.
  642. MOV CL,9 ; Let's default to 360K.
  643. MOV DH,1
  644. PFR_OK:
  645. INC DH ; MAKE NUMBER OF HEADS 1-BASED
  646. INC CH ; MAKE NUMBER OF CYLINDERS 1-BASED
  647. MOV NUM_HEADS,DH ; SAVE PARMS RETURNED BY ROM
  648. AND CL,00111111B ; EXTRACT SECTORS/TRACK
  649. MOV SEC_TRK,CL
  650. MOV NUM_CYLN,CH ; ASSUME LESS THAN 256 CYLINDERS!!
  651. ; MAKE SURE THAT EOT CONTAINS THE MAX NUM OF SEC/TRK IN SYSTEM OF FLOPPIES
  652. CMP CL,EOT ; MAY SET CARRY
  653. JBE EOT_OK
  654. MOV EOT,CL
  655. EOT_OK:
  656. POP ES
  657. POP CX
  658. POP DX
  659. POP DI
  660. POP DS
  661. ;
  662. ; Check for presence of changeline
  663. ;
  664. mov AH, 15h ; set command to get DASD type
  665. int 13h ; call ROM-BIOS
  666. JC CHANGELINE_DONE
  667. CMP AH,02 ; CHECK FOR PRESENCE OF CHANGELINE
  668. JNE CHANGELINE_DONE
  669. ;;End of Modification -----------------------------------------------
  670. ;
  671. ; We have a drive with change line support.
  672. ;
  673. Message fTestINIT,<"96tpi devices",CR,LF>
  674. or CL,fChangeLine ; signal type
  675. mov fHave96,1 ; Remember that we have 96tpi disks
  676. ; ;3.30
  677. ; WE NOW TRY TO SET UP THE FORM FACTOR FOR THE TYPES OF MEDIA THAT WE KNOW;3.30
  678. ; AND CAN RECOGNISE. FOR THE REST, WE SET THE FORM FACTOR AS "OTHER". ;3.30
  679. ; ;3.30
  680. CHANGELINE_DONE: ;3.30
  681. ; 40 CYLINDERS AND 9 OR LESS SEC/TRK, TREAT AS 48 TPI MEDIUM. ;3.30
  682. CMP NUM_CYLN,40 ;3.30
  683. JNZ TRY_80 ;3.30
  684. CMP SEC_TRK,9 ;3.30
  685. JBE GOT_FF ;3.30
  686. GOTOTHER: ;3.30
  687. MOV DH,FFOTHER ; WE HAVE A "STRANGE" MEDIUM ;3.30
  688. JMP SHORT GOT_FF ;3.30
  689. ;3.30
  690. ; ;3.30
  691. ; 80 CYLINDERS AND 9 SECTORS/TRACK => 720 KB DEVICE ;3.30
  692. ; 80 CYLINDERS AND 15 SEC/TRK => 96 TPI MEDIUM ;3.30
  693. ; ;3.30
  694. TRY_80: ;3.30
  695. CMP NUM_CYLN,80 ;3.30
  696. JNZ GOTOTHER ;3.30
  697. CMP SEC_TRK,15 ;3.30
  698. JZ GOT96 ;3.30
  699. CMP SEC_TRK,9 ;3.30
  700. JNZ GOTOTHER ;3.30
  701. MOV DH,FFSMALL ;3.30
  702. JMP SHORT GOT_FF ;3.30
  703. ;3.30
  704. GOT96: ;3.30
  705. MOV DH,FF96TPI ;3.30
  706. ;3.30
  707. GOT_FF: ;3.30
  708. JMP SHORT NEXTDRIVE ;3.30
  709. ;3.30
  710. ; AN OLD ROM, SO WE EITHER HAVE A 48TPI OR 96TPI DRIVE. IF THE DRIVE ;3.30
  711. ; HAS CHANGELINE, WE ASSUME IT IS A 96TPI, OTHERWISE IT IS A 48TPI. ;3.30
  712. ;3.30
  713. NOPARMSFROMROM: ;3.30
  714. POP ES ;3.30
  715. POP CX ;3.30
  716. POP DX ;3.30
  717. POP DI ;3.30
  718. POP DS ;3.30
  719. ;3.30
  720. MOV AH, 15h ; SET COMMAND TO GET DASD TYPE ;3.30
  721. INT 13h ; CALL ROM-BIOS ;3.30
  722. JC NEXTDRIVE ;3.30
  723. CMP AH,2 ; IS THERE CHANGELINE? ;3.30
  724. JNZ NEXTDRIVE ;3.30
  725. OR CL,FCHANGELINE ;3.30
  726. MOV FHAVE96,1 ; REMEMBER WE HAVE 96TPI DRIVES ;3.30
  727. MOV NUM_CYLN,80 ;3.30
  728. MOV DH,FF96TPI ;3.30
  729. MOV AL,15 ; SET EOT IF NECESSARY ;3.30
  730. CMP AL, EOT ;3.30
  731. JBE EOT_OK2 ;3.30
  732. MOV EOT,AL ;3.30
  733. EOT_OK2: ;3.30
  734. NextDrive:
  735. or cl,fI_Own_Physical ; set this true for all drives
  736. mov bh,dl ;save Int13 drive number
  737. ;
  738. ; We need to do special things if we have a single drive system and are setting
  739. ; up a logical drive. It needs to have the same Int13 drive number as its
  740. ; counterpart, but the next drive letter. Also reset ownership flag.
  741. ; We detect the presence of this situation by examining the flag SINGLE for the
  742. ; value 2.
  743. ;
  744. cmp single,2
  745. jnz Not_Special
  746. dec bh ; Int13 drive number same for logical drive
  747. xor cl,fI_Own_Physical ; reset ownership flag for logical drive
  748. Not_Special:
  749. ; The values that we put in for RHdlim and RSeclim will only remain if the
  750. ; form factor is of type "ffOther".
  751. xor ax,ax ; fill BDS for drive
  752. mov al,num_heads
  753. mov word ptr [di].RHdlim,ax
  754. mov al,sec_trk
  755. mov word ptr [di].RSeclim,ax
  756. mov word ptr [di].flags,cx
  757. mov byte ptr [di].FormFactor,dh
  758. mov byte ptr [di].DriveLet,dl
  759. mov byte ptr [di].DriveNum,bh
  760. MOV BL,BYTE PTR NUM_CYLN ;3.30
  761. mov byte ptr [di].cCyln,bl ; only the l.s. byte is set here
  762. cmp single,1 ; Special case for single drive system
  763. jnz No_Single
  764. message fTestINIT,<"Single Drive System",CR,LF>
  765. ; Don't forget we have
  766. mov single,2 ; single drive system
  767. or cx,fI_Am_Mult ; set that this is one of
  768. ; several drives
  769. or word ptr [di].flags,cx ; save flags
  770. mov di,word ptr [di].link ; move to next BDS in list
  771. inc dl ; add a number
  772. jmp short NextDrive ; Use same info for BDS as previous
  773. No_Single:
  774. inc dl
  775. jmp loop_drive
  776. Done_Drives:
  777. mov ax,-1 ; Signify end of list by
  778. mov word ptr [di].link,ax ; setting pointer to -1
  779. ;
  780. ; Set up all the hard drives in the system
  781. ;
  782. DoHard:
  783. MNUM fTestINIT+fTestHARD,AX
  784. Message fTestINIT+fTestHARD,<" Hard disk(s) to initialize",CR,LF>
  785. Message fTestINIT+fTestHARD,<"Hard disk 1",CR,LF>
  786. CMP HNUM,0 ; IF (No_Hard_files)
  787. JLE STATIC_CONFIGURE ; THEN EXIT TO CONFIGURE ;3.30
  788. mov DL, 80h ; set first hard file number
  789. mov di,offset BDSH ; Set up first hard file.
  790. mov bl,HARDNUM
  791. call SETHARD
  792. jnc HardFile1_OK
  793. dec HNUM ; First hard file is bad.
  794. cmp HNUM,0 ; IF (Second_Hard_File)
  795. jg Second_Hard ; THEN Set up second hard file
  796. JMP SHORT STATIC_CONFIGURE ;3.30
  797. HardFile1_OK:
  798. call Install_BDS ; install BDS into linked list
  799. cmp HNUM,2 ; IF (Only_one_hardfile)
  800. jb SetIt ; THEN SetIt "in place"
  801. mov bl,HARDNUM
  802. inc BL ; next drive letter
  803. mov di,offset BDSX
  804. Second_Hard: ; SETUP Second Hard FILE
  805. Message fTestINIT+fTestHARD,<"Hard disk 2",CR,LF>
  806. mov DL, 81h ; set second hard file number
  807. call SETHARD
  808. jnc HardFile2_OK
  809. dec HNUM
  810. jmp short SetIt
  811. HardFile2_OK:
  812. Call Install_BDS
  813. SETIT:
  814. mov al,HNUM
  815. or al,al
  816. JZ STATIC_CONFIGURE ;3.30
  817. add al,HARDNUM
  818. mov DRVMAX,al
  819. ; End of physical drive initialization. ;3.30
  820. ; *** Do not change the position of the following statement.
  821. ; *** DoMini routine will use [DRVMAX] value for the start of the logical ;3.30
  822. ; *** drive number of Mini disk(s). ;3.30
  823. ;3.30
  824. call DoMini ;For setting up mini disks, if found -;3.30
  825. ; End of drive initialization.
  826. ;9/24/86 We now decide, based on the configurations available so far,;3.30
  827. ;what code or data we need to keep as a stay resident code. The following;3.30
  828. ;table shows the configurations under consideration. They are listed in ;3.30
  829. ;the order of their current position memory. ;3.30
  830. ;Configuration will be done in two ways: ;3.30
  831. ;First, we are going to set "Static configuration". Static configuration ;3.30
  832. ;will consider from basic configuration to ENDOF96TPI configuration. ;3.30
  833. ;The result of static configuration will be the address the Dynamic ;3.30
  834. ;configuration will use to start with. ;3.30
  835. ;Secondly, "Dynamic cofiguration" will be performed. Dynamic configuration;3.30
  836. ;involves possible relocation of CODE/DATA. Dynamic configuration routine ;3.30
  837. ;will take care of BDSM tables and AT ROM Fix module thru K09 suspend/res ;3.30
  838. ;code individually. After these operation, FINAL_DOS_LOCATION will be set.;3.30
  839. ;This will be the place SYSINIT routine will relocate MSDOS module. ;3.30
  840. ; ;3.30
  841. ; 1. BASIC CONFIGURATION FOR MSBIO (EndFloppy, EndSwap) ;3.30
  842. ; 2. ENDONEHARD ;3.30
  843. ; 3. ENDTWOHARD ;3.30
  844. ; 4. END96TPI ;a system that supports "Change Line Error" ;3.30
  845. ; 5. End of BDSM ;BDSM tables for mini disks. ;3.30
  846. ; 6. ENDATROM ;Some of AT ROM fix module. ;3.30
  847. ; 7. ENDCMOSCLOCKSET;Supporting program for CMOS clock write. ;3.30
  848. ; 8. ENDK09 ;K09 CMOS Clock module to handle SUSPEND/RESUME ;3.30
  849. ; ;3.30
  850. ;9/24/86. ;3.30
  851. ;3.30
  852. ; *** For mini disk configuration. 4/7/86 ;3.30
  853. ; *** END_OF_BDSM will contain the ending address(off) of BDSM table for ;3.30
  854. ; *** mini disks which is located right after the label END96TPI. ;3.30
  855. ; *** The variable NUM_MINI_DSK will indicate the existance. 4/7/86 ;3.30
  856. ;3.30
  857. ;3.30
  858. STATIC_CONFIGURE: ;3.30
  859. ;3.30
  860. ;3.30
  861. PUSH AX ;3.30
  862. mov ax, offset END96TPI ;let's start with the biggest one.;3.30
  863. cmp fHave96, 0 ;Is change line support there? ;3.30
  864. jnz Config96 ;Yes. ;3.30
  865. ;3.30
  866. mov ax, offset ENDTWOHARD ;3.30
  867. cmp HNUM, 1 ;1 hard file? ;3.30
  868. jbe No_Two_HRD ;3.30
  869. jmp ConfigTwoHard ;3.30
  870. No_Two_HRD: ;3.30
  871. mov ax, offset ENDONEHARD ;3.30
  872. jnz Basic_Floppy ;3.30
  873. jmp ConfigOneHard ;3.30
  874. Basic_Floppy: ;3.30
  875. mov ax, offset ENDFLOPPY ;3.30
  876. jmp Dynamic_Configure ;static configuration is done! ;3.30
  877. ;
  878. ; Keep the 96tpi code
  879. ;
  880. Config96:
  881. ;
  882. ; Save old INT 13 vector
  883. ;
  884. PUSH AX
  885. PUSH DS
  886. XOR AX,AX
  887. MOV DS,AX
  888. ASSUME DS:NOTHING ;3.30
  889. MOV AX,DS:[4 * 13h]
  890. MOV WORD PTR CS:Real13,AX
  891. MOV AX,DS:[4 * 13h+2]
  892. MOV WORD PTR CS:Real13+2,AX
  893. ;
  894. ; Insert new vector
  895. ;
  896. MOV WORD PTR DS:[4 * 13h],OFFSET INT13
  897. MOV DS:[4 * 13h + 2],CS
  898. POP DS
  899. ASSUME DS:CODE ;3.30
  900. POP AX
  901. ;
  902. ; Keep two hard disk BPBs
  903. ;
  904. ConfigTwoHard:
  905. ;
  906. ; Keep one hard disk BPB
  907. ;
  908. ConfigOneHard:
  909. ;
  910. ; Adjust the number of drives to include the hard disks.
  911. ;
  912. PUSH AX
  913. MOV AL,HardNum
  914. ADD AL,HNum
  915. add al, num_mini_dsk ;4/7/86 for mini disks installed ;3.30
  916. ;if not installed, then num_mini_dsk = 0. ;3.30
  917. MOV DrvMax,AL
  918. POP AX
  919. DYNAMIC_CONFIGURE: ;3.30
  920. call Get_Para_Offset ;For dynamic allocation, we are ;3.30
  921. ;going to use offset address that ;3.30
  922. ;is in paragraph boundary. ;3.30
  923. push cs ;3.30
  924. pop es ;es -> code ;3.30
  925. assume es:code ;3.30
  926. cld ;clear direction ;3.30
  927. ;3.30
  928. cmp [num_mini_dsk], 0 ;Mini disk(s) installed ? ;3.30
  929. jz CheckATROM ;No. ;3.30
  930. mov ax, End_Of_BDSM ;set the new ending address ;3.30
  931. call Get_Para_Offset ;3.30
  932. CheckATROM: ;3.30
  933. cmp Model_Byte, 0FCh ;AT ? ;3.30
  934. jnz CheckCMOSClock ;3.30
  935. cmp HNUM, 0 ;No hard file? ;3.30
  936. jz CheckCMOSClock ;3.30
  937. mov si, 0F000h ;3.30
  938. mov es, si ;ES -> BIOS segment ;3.30
  939. assume es:nothing ;3.30
  940. mov si, offset BIOS_DATE ;3.30
  941. mov di, 0FFF5H ;ROM BIOS string is at F000:FFF5 ;3.30
  942. Cmpbyte: ;Only patch ROM for bios 01/10/84 ;3.30
  943. cmpsb ;3.30
  944. jnz CheckCMOSClock ;3.30
  945. cmp byte ptr [si-1],0 ;3.30
  946. jnz Cmpbyte ;3.30
  947. ;3.30
  948. SetRomCode: ;Now we have to install ROM fix ;3.30
  949. ;AX is the address to move. ;3.30
  950. push cs ;3.30
  951. pop es ;set ES to CODE seg ;3.30
  952. assume es:code ;3.30
  953. mov word ptr ORIG13, ax ;3.30
  954. mov word ptr ORIG13+2, cs ;set new ROM bios int 13 vector ;3.30
  955. mov cx, offset ENDATROM ;3.30
  956. mov si, offset IBM_DISK_IO ;3.30
  957. sub cx, si ;size of AT ROM FIX module ;3.30
  958. mov di, ax ;destination ;3.30
  959. rep movsb ;relocate it ;3.30
  960. mov ax, di ;new ending address ;3.30
  961. call Get_Para_Offset ;in AX ;3.30
  962. ;3.30
  963. CheckCMOSClock: ;3.30
  964. push cs ;3.30
  965. pop es ;set ES to CODE seg ;3.30
  966. assume es:code ;3.30
  967. cmp HaveCMOSClock, 1 ;CMOS Clock exists? ;3.30
  968. jne CheckK09 ;3.30
  969. mov DaycntToDay, ax ;set the address for MSCLOCK ;3.30
  970. mov cx, offset EndDaycntToDay ;3.30
  971. mov si, offset Daycnt_To_Day ;3.30
  972. sub cx, si ;size of CMOS clock sup routine ;3.30
  973. mov di, ax ;3.30
  974. rep movsb ;3.30
  975. mov ax, di ;3.30
  976. call Get_Para_Offset ;3.30
  977. mov BinToBCD, ax ;set the address for MSCLOCK ;3.30
  978. mov cx, offset EndCMOSClockSet ;3.30
  979. mov si, offset Bin_To_BCD ;3.30
  980. sub cx, si ;3.30
  981. mov di, ax ;3.30
  982. rep movsb ;3.30
  983. mov ax, di ;3.30
  984. call Get_Para_Offset ;3.30
  985. ;3.30
  986. CheckK09: ;3.30
  987. push ax ;save ax ;3.30*
  988. mov ax,4100h ;Q: is it a K09 ;3.30*
  989. mov bl,0 ; ;3.30*
  990. int 15h ; ;3.30*
  991. pop ax ;3.30
  992. jc CONFIGDONE ;3.30
  993. ;3.30
  994. mov si, offset INT6C ;3.30
  995. mov cx, offset ENDK09 ;3.30
  996. sub cx, si ;size of K09 routine ;3.30
  997. mov di, ax ;3.30
  998. push di ;save destination ;3.30
  999. rep movsb ;3.30
  1000. mov ax, di ; ;3.30
  1001. call Get_Para_Offset ;AX = new ending address ;3.30
  1002. pop di ;3.30
  1003. ;3.30
  1004. push ax ;3.30
  1005. push ds ;3.30
  1006. mov fHaveK09, 1 ;remember we have a K09 type ;3.30
  1007. xor ax,ax ;3.30
  1008. mov ds, ax ;3.30
  1009. assume ds:nothing ;3.30
  1010. ;3.30
  1011. mov word ptr ds:[4 * 6Ch], di ;new INT 6Ch handler ;3.30
  1012. mov ds:[4 * 6Ch +2], cs ;3.30
  1013. ;3.30
  1014. pop ds ;3.30
  1015. assume ds:code ;3.30
  1016. pop ax ;restore the ending address ;3.30
  1017. ;
  1018. ; Set up config stuff for SYSINIT
  1019. ;
  1020. ConfigDone:
  1021. MOV DX,SYSINITSEG
  1022. MOV DS,DX
  1023. ASSUME DS:SYSINITSEG
  1024. SUB AX,OFFSET START$ ;3.30
  1025. ADD AX,15
  1026. RCR AX,1
  1027. SHR AX, 1
  1028. SHR AX, 1
  1029. SHR AX, 1
  1030. MOV FINAL_DOS_LOCATION, AX
  1031. POP AX
  1032. GOINIT:
  1033. ADD Final_DOS_Location,CODE
  1034. Message fTestINIT,<"Final DOS location is ">
  1035. MNUM fTestINIT,Final_DOS_Location
  1036. Message fTestINIT,<CR,LF>
  1037. PUSH CS
  1038. POP DS
  1039. ASSUME DS:CODE,ES:NOTHING
  1040. CMP BYTE PTR fHave96,0
  1041. JNZ ReadDos
  1042. call purge_96tpi ;mjb001 eliminate calls to 96tpi hoohah
  1043. ReadDos:
  1044. Message fTestINIT,<"Load FAT",CR,LF>
  1045. mov ax,DRVFAT ; Get drive and FAT ID
  1046. call SetDrive ; Get BDS for drive
  1047. call GetBP ; Ensure valid BPB is present
  1048. call GETFAT ; Read in the FAT sector
  1049. xor DI,DI
  1050. mov AL,ES:[DI] ; Get fat id byte
  1051. mov BYTE PTR DRVFAT+1,AL ; Save FAT byte
  1052. mov AX,DRVFAT
  1053. Message fTestINIT,<"FATID read ">
  1054. mnum ftestinit,ax
  1055. message ftestinit,<cr,lf>
  1056. call SETDRIVE ; Get Correct BDS for this drive
  1057. mov BL,[DI].FatSiz ; get size of fat on media
  1058. mov fBigFat,BL
  1059. mov CL,[DI].SecPerClus ; get sectors/cluster
  1060. mov AX,[DI].HIDSEC ; get number of hidden sectors
  1061. sub BIOS$,AX ; subtract hidden sector offset
  1062. xor CH,CH ; CX = sectors/cluster
  1063. ;
  1064. ; THE BOOT PROGRAM HAS LEFT THE DIRECTORY AT 0:500
  1065. ;
  1066. PUSH DS
  1067. XOR DI,DI
  1068. MOV DS,DI ; ES:DI POINTS TO LOAD LOCATION
  1069. MOV BX,DS:WORD PTR [53AH] ; clus=*53A;
  1070. POP DS ;
  1071. Message fTestINIT,<"Load DOS",CR,LF>
  1072. ; BAS DEBUG
  1073. ;LOADIT: MOV AX,((((OFFSET END$)-(OFFSET START$))+15)/16)+SYSIZE
  1074. LOADIT:
  1075. MOV AX, OFFSET END$ ;3.30
  1076. SUB AX, OFFSET START$ ;3.30
  1077. ADD AX, 15
  1078. RCR AX, 1 ; DIVIDE BY 16
  1079. SHR AX, 1
  1080. SHR AX, 1
  1081. SHR AX, 1
  1082. ADD AX, SYSIZE
  1083. ADD AX,CODE
  1084. MOV ES,AX ;
  1085. CALL GETCLUS ; clus = GetClus (clus);
  1086. IsEof:
  1087. TEST fBigFat,fBIG ; if (fBigFAT)
  1088. JNZ EOFBig
  1089. Message fTestINIT,<CR,LF,"Small FAT EOF check",CR,LF>
  1090. CMP BX,0FF7h ; return (clus > 0ff7h);
  1091. JMP SHORT ISEOFX ;3.30
  1092. EOFBig:
  1093. Message fTestINIT,<CR,LF,"Big FAT EOF check",CR,LF>
  1094. CMP BX,0FFF7h ; else
  1095. ISEOFX: ;3.30
  1096. JB LOADIT ; } WHILE (!ISEOF (CLUS)); ;3.30
  1097. ;3.30
  1098. CALL SETDRVPARMS ;3.30
  1099. ;3.30
  1100. MESSAGE FTESTINIT,<"SYSINIT",CR,LF> ;3.30
  1101. ZWAIT ;3.30
  1102. MESSAGE FTESTINIT,<"ON TO SYSINIT...",CR,LF> ;3.30
  1103. JMP SYSINIT ;3.30
  1104. ;3.30
  1105. INIT ENDP ;3.30
  1106. ;3.30
  1107. ;**************************** ;3.30
  1108. ;3.30
  1109. Get_Para_Offset proc near ;3.30
  1110. ;in: AX - offset value ;3.30
  1111. ;out: AX - offset value adjusted for the next paragraph boundary. ;3.30
  1112. add ax, 15 ;make a paragraph ;3.30
  1113. rcr ax, 1 ;3.30
  1114. shr ax, 1 ;3.30
  1115. shr ax, 1 ;3.30
  1116. shr ax, 1 ;3.30
  1117. shl ax, 1 ;now, make it back to offset value ;3.30
  1118. shl ax, 1 ;3.30
  1119. shl ax, 1 ;3.30
  1120. shl ax, 1 ;3.30
  1121. ret ;3.30
  1122. Get_Para_Offset endp ;3.30
  1123. ;
  1124. ; READ A FAT SECTOR INTO fat location
  1125. ;
  1126. GETFAT PROC NEAR ;3.30
  1127. XOR DI,DI ; offset
  1128. MOV DX,1 ; relative sector (1st sector of fat)
  1129. MOV CX,FatLen ; read entire fat.
  1130. MOV AX,FatLoc ;
  1131. MOV ES,AX ; location to read
  1132. MOV AX,DRVFAT ; AH FAT ID byte, AL drive
  1133. JMP DISKRD
  1134. GETFAT ENDP ;3.30
  1135. ;
  1136. ; READ A BOOT RECORD INTO 7C0:BootBias
  1137. ; GetBoot reads the boot record into 7C0:BootBias
  1138. ; On Entry:
  1139. ; DL contains ROM drive number (80 or 81)
  1140. ; On Exit:
  1141. ; if carry set error
  1142. ; if carry clear:
  1143. ; ES:BX piont to boot sector
  1144. ; AX and CX are not preserved
  1145. ; BX and ES are used to return values
  1146. ;
  1147. GETBOOT PROC NEAR
  1148. mov AX, 07C0h ; prepare to load ES
  1149. mov ES, AX ; load ES segment register
  1150. mov BX, BootBias ; load BX, ES:BX is where sector goes
  1151. mov AX, 0201h ; command to read & num sec. to 1
  1152. xor DH, DH ; head number zero
  1153. mov CX, 0001h ; cylinder zero and sector one
  1154. int 13h ; call rom bios
  1155. jc ERRET
  1156. cmp WORD PTR ES:[BootBias+1FEH],0AA55H ; DAVE LITTON MAGIC BYTE?
  1157. jz Norm_Ret
  1158. message ftesthard,<"Signature AA55 not found",cr,lf>
  1159. ERRET:
  1160. message ftesthard,<"Error in Getboot",cr,lf>
  1161. STC
  1162. Norm_Ret:
  1163. RET
  1164. GETBOOT ENDP ;3.30
  1165. ;
  1166. ; SetHard - generate BPB for a variable sized hard file. IBM has a
  1167. ; partitioned hard file; we must read physical sector 0 to determine where
  1168. ; our own logical sectors start. We also read in our boot sector to
  1169. ; determine version number
  1170. ;
  1171. ; Inputs: DL is ROM drive number (80 OR 81)
  1172. ; DS:DI points to BDS
  1173. ; Outputs: Carry clear -> BPB is filled in
  1174. ; Carry set -> BPB is left uninitialized due to error
  1175. ;
  1176. SETHARD PROC NEAR ;3.30
  1177. push di
  1178. push bx
  1179. push ds
  1180. mov byte ptr [di].DriveLet,bl
  1181. mov byte ptr [di].DriveNum,dl
  1182. xor ax,ax
  1183. or al,fNon_Removable
  1184. or word ptr [di].flags,ax
  1185. mov byte ptr [di].FormFactor,ffHardFile
  1186. MOV fBigFat,0 ; Assume 12 bit FAT
  1187. PUSH DX
  1188. mov AH, 8 ; set command to get drive parameters
  1189. int 13h ; call rom-bios disk routine
  1190. ; DH is number of heads-1
  1191. ; DL is number of hard disks attached
  1192. ; Low 6 bits of CL is sectors/track
  1193. ; High 2 bits of CL with CH are max # of cylinders
  1194. INC DH ; get number of heads
  1195. MOV BYTE PTR [DI].HDLIM,DH
  1196. POP DX
  1197. JC SETRET ; carry here means no hard disk
  1198. AND CL,3FH ; extract number of sectors/track
  1199. MOV BYTE PTR [DI].SECLIM,CL
  1200. CALL GETBOOT ; if (getBoot ())
  1201. JC SETRET ; return -1;
  1202. MOV BX,1C2H+BootBias ; p = &boot[0x1C2];
  1203. SET1:
  1204. CMP BYTE PTR ES:[BX],1 ; while (p->PartitionType != 1 &&
  1205. JZ SET2
  1206. CMP Byte Ptr ES:[BX],4 ; p->PartitionType != 4) {
  1207. JZ Set2
  1208. ADD BX,16 ; p += sizeof Partition;
  1209. CMP BX,202H+BootBias ; if (p == &boot[0x202h])
  1210. JNZ SET1 ; return -1;
  1211. SETRET:
  1212. STC ; }
  1213. jmp Ret_Hard
  1214. SET2:
  1215. PUSH DX
  1216. MOV AX,WORD PTR ES:[BX+4]
  1217. MOV DX,WORD PTR ES:[BX+6]
  1218. ;Decrement the sector count by 1 to make it zero based. Exactly 64k ;3.30
  1219. ;sectors should be allowed ;3.30
  1220. ; ;3.30
  1221. SUB AX,1 ; PTM 901 12/12/86 MT ;3.30
  1222. SBB DX,0 ; PTM 901 12/12/86 MT ;3.30
  1223. ADD AX,WORD PTR ES:[BX+8]
  1224. ADC DX,WORD PTR ES:[BX+10]
  1225. JZ OKDrive
  1226. Message fTestHard,<"Partition invalid",CR,LF>
  1227. OR fBigFat,fTOOBIG
  1228. OKDrive:
  1229. POP DX
  1230. MOV AX,WORD PTR ES:[BX+4]
  1231. MOV [DI].HIDSEC,AX ; BPB->HidSecCt = p->PartitionBegin;
  1232. MOV AX,WORD PTR ES:[BX+8]
  1233. CMP AX,64 ; if (p->PartitionLength < 64)
  1234. JB SETRET ; return -1;
  1235. MOV WORD PTR [DI].DRVLIM,AX ; BPB->MaxSec = p->PartitionLength;
  1236. PUSH AX
  1237. PUSH DX
  1238. MOV AX,[DI].HidSec ; boot sector number
  1239. XOR DX,DX
  1240. MOV BH,DH
  1241. MOV BL,byte ptr [DI].SecLim
  1242. DIV BX
  1243. MOV CL,DL ; CL is sector number
  1244. INC CL ; sectors are 1 based
  1245. CWD
  1246. MOV BL,byte ptr [DI].HdLim
  1247. DIV BX ; DL is head, AX is cylinder
  1248. ;
  1249. ; DL is head.
  1250. ; AX is cylinder
  1251. ; CL is sector number
  1252. ; TOS is drive
  1253. ;
  1254. ;*** For Mini Disks *** 4/7/86 ;3.30
  1255. cmp word ptr [di].IsMini, 1 ;check for mini disk - 4/7/86 ;3.30
  1256. jnz OKnotMini ;not mini disk. - 4/7/86 ;3.30
  1257. add ax, [di].hidden_trks ;set phy track num - 4/7/86 ;3.30
  1258. OKnotMini: ; 4/7/86 ;3.30
  1259. ;*** End of added logic for mini disk ;3.30
  1260. ROR AH,1 ; move high two bits of cyl to high
  1261. ROR AH,1 ; two bits of upper byte
  1262. AND AH,0C0h ; turn off remainder of bits
  1263. OR CL,AH ; move two bits to correct spot
  1264. MOV CH,AL ; CH is Cylinder
  1265. ;
  1266. ; CL is sector + 2 high bits of cylinder
  1267. ; CH is low 8 bits of cylinder
  1268. ; DL is head
  1269. ; TOS is drive
  1270. ;
  1271. POP AX ; AL is drive
  1272. MOV DH,DL ; DH is head
  1273. MOV DL,AL ; DL is drive
  1274. ;
  1275. ; CL is sector + 2 high bits of cylinder
  1276. ; CH is low 8 bits of cylinder
  1277. ; DH is head
  1278. ; DL is drive
  1279. ;
  1280. xor BX, BX ; clear BX -- ES:BX points to buffer
  1281. mov ax, 0201h ; set command to read one sector
  1282. int 13h ; call rom-bios to read sector
  1283. pop AX
  1284. ;
  1285. ; ES:[0] points to the boot sector. In theory, (ha ha) the BPB in this thing
  1286. ; is correct. We can, therefore, pull out all the relevant statistics on the
  1287. ; media if we recognize the version number.
  1288. ;
  1289. CMP WORD PTR ES:[3], "B" SHL 8 + "I"
  1290. JNZ Unknownj
  1291. CMP WORD PTR ES:[5], " " SHL 8 + "M"
  1292. JNZ Unknownj
  1293. CMP WORD PTR ES:[8], "." SHL 8 + "2"
  1294. JNZ Try5
  1295. CMP BYTE PTR ES:[10], "0"
  1296. JNZ Try5
  1297. Message fTestHard,<"Version 2.0 media",CR,LF>
  1298. JMP SHORT CopyBPB
  1299. unknownj:
  1300. jmp unknown
  1301. Try5:
  1302. CMP WORD PTR ES:[8],"." SHL 8 + "3"
  1303. JNZ Unknownj
  1304. cmp byte ptr es:[10],"1" ;do not trust 3.0 boot record. 4/15/86;3.30
  1305. jb unknownj ;if version >= 3.1, then O.K. 4/15/86 ;3.30
  1306. Message ftestHard,<"VERSION 3.1 OR ABOVE MEDIA",CR,LF>
  1307. CopyBPB:
  1308. ; We have a valid Boot sector. Use the BPB in it to build the
  1309. ; BPB in BIOS. It is assumed that ONLY SecPerClus, cDIR, and
  1310. ; cSecFat need to be set (all other values in already). fBigFat
  1311. ; is also set.
  1312. MOV AX,WORD PTR ES:[11+DRVLIM-BytePerSec] ; Total sectors
  1313. MNUM fTestHard,AX
  1314. Message fTestHard,<" Sec ">
  1315. DEC AX ; Subtract # reserved (always 1)
  1316. MOV DX,WORD PTR ES:[11+cSecFAT-BytePerSec] ; Sectors for 1 fat
  1317. MNUM fTestHard,DX
  1318. Message fTestHard,<" Sec/Fat ">
  1319. MOV [DI+cSecFAT],DX ; Set in BIOS BPB
  1320. SHL DX,1 ; Always 2 FATs
  1321. SUB AX,DX ; Sub # FAT sectors
  1322. MOV DX,WORD PTR ES:[11+cDIR-BytePerSec] ; # root entries
  1323. MOV [DI+cDIR],DX ; Set in BIOS BPB
  1324. MNUM fTestHard,DX
  1325. Message fTestHard,<" directory entries ">
  1326. MOV CL,4
  1327. SHR DX,CL ; Div by 16 ents/sector
  1328. SUB AX,DX ; Sub # dir sectors
  1329. ; AX now contains the # of data sectors.
  1330. MOV CL,BYTE PTR ES:[11+SecPerClus-BytePerSec] ; Sectors per cluster
  1331. MOV [DI.SecPerClus],CL ; Set in BIOS BPB
  1332. XOR DX,DX
  1333. MOV CH,DH
  1334. MNUM fTestHard,CX
  1335. Message fTestHard,<" SecPerClus",CR,LF>
  1336. DIV CX
  1337. ; AX now contains the # clusters.
  1338. CMP AX,4096-10 ; is this 16-bit fat?
  1339. JB GoodRetj ; No
  1340. OR fBigFat,fBIG ; 16 bit FAT
  1341. GoodRetj:
  1342. JMP GoodRet
  1343. Unknown:
  1344. Message fTestHard,<"Unknown hard media. Assuming 3.0.",CR,LF>
  1345. MOV SI,OFFSET DiskTable2
  1346. Scan:
  1347. CMP AX,[SI]
  1348. JBE GotParm
  1349. ADD SI,4 * 2
  1350. JMP Scan
  1351. GotParm:
  1352. MOV CL,BYTE PTR [SI+6]
  1353. OR fBigFat,CL
  1354. MOV CX,[SI+2]
  1355. MOV DX,[SI+4]
  1356. ;
  1357. ; AX = number of sectors on disk drive
  1358. ; DX = number of dir entries,
  1359. ; CH = number of sectors per cluster
  1360. ; CL = log base 2 of ch
  1361. ;
  1362. ; NOW CALCULATE SIZE OF FAT TABLE
  1363. ;
  1364. MNUM fTestHard,AX
  1365. Message fTestHard,<" sectors ">
  1366. MNUM fTestHard,DX
  1367. Message fTestHard,<" directory entries ">
  1368. MNUM fTestHard,CX
  1369. Message fTestHard,<" SecPerClus|ClusShift">
  1370. MOV WORD PTR cDir[DI],DX ;SAVE NUMBER OF DIR ENTRIES
  1371. MOV BYTE PTR SecPerClus[DI],CH ;SAVE SECTORS PER CLUSTER
  1372. TEST fBigFAT,fBIG ; if (fBigFat)
  1373. JNZ DoBig ; goto DoBig;
  1374. Message fTestHard,<" Small fat",CR,LF>
  1375. XOR BX,BX
  1376. MOV BL,CH
  1377. DEC BX
  1378. ADD BX,AX
  1379. SHR BX,CL ; BX = 1+(BPB->MaxSec+SecPerClus-1)/
  1380. INC BX ; SecPerClus
  1381. AND BL,11111110B ; BX &= ~1; (=number of clusters)
  1382. MOV SI,BX
  1383. SHR BX,1
  1384. ADD BX,SI
  1385. ADD BX,511 ; BX += 511 + BX/2
  1386. SHR BH,1 ; BH >>= 1; (=BX/512)
  1387. MOV BYTE PTR [DI].cSecFat,BH ;SAVE NUMBER OF FAT SECTORS
  1388. JMP SHORT GOODRET ;3.30
  1389. DoBig:
  1390. Message fTestHard,<" Big fat",CR,LF>
  1391. MOV CL,4 ; 16 (2^4) directory entries per sector
  1392. SHR DX,CL ; cSecDir = cDir / 16;
  1393. SUB AX,DX ; AX -= cSecDir; AX -= cSecReserved;
  1394. DEC AX ; ax = t - r - d
  1395. MOV BL,2
  1396. MOV BH,SecPerClus[DI] ; bx = 256 * secperclus + 2
  1397. XOR DX,DX
  1398. ADD AX,BX ; ax = t-r-d+256*spc+2
  1399. ADC DX,0
  1400. SUB AX,1 ; ax = t-r-d+256*spc+1
  1401. SBB DX,0
  1402. DIV BX ; cSecFat = ceil((total-dir-res)/
  1403. ; (256*secperclus+2));
  1404. MOV WORD PTR [DI].cSecFat,AX ; number of fat sectors
  1405. GoodRet:
  1406. MOV BL,fBigFat
  1407. MOV [DI].FatSiz,BL ; set size of fat on media
  1408. CLC
  1409. Ret_Hard:
  1410. pop ds
  1411. pop bx
  1412. pop di
  1413. RET
  1414. SETHARD ENDP ;3.30
  1415. ;
  1416. ; SetDrvParms sets up the recommended BPB in each BDS in the system based on
  1417. ; the form factor. It is assumed that the BPBs for the various form factors
  1418. ; are present in the BPBTable. For hard files, the Recommended BPB is the same
  1419. ; as the BPB on the drive.
  1420. ; No attempt is made to preserve registers since we are going to jump to
  1421. ; SYSINIT straight after this routine.
  1422. ;
  1423. SETDRVPARMS PROC NEAR ;3.30
  1424. message ftestinit,<"Setting Drive Parameters",cr,lf>
  1425. xor bx,bx
  1426. les di,dword ptr cs:[Start_BDS] ; get first BDS in list
  1427. Next_BDS:
  1428. cmp di,-1
  1429. jnz Do_SetP
  1430. Done_SetParms:
  1431. RET
  1432. Do_SetP:
  1433. push es
  1434. push di ; preserve pointer to BDS
  1435. mov bl,es:[di].FormFactor
  1436. cmp bl,ffHardFile
  1437. jnz NotHardFF
  1438. mov ax,es:[di].DrvLim
  1439. push ax
  1440. mov ax,word ptr es:[di].hdlim
  1441. mul word ptr es:[di].seclim
  1442. mov cx,ax ; cx has # sectors per cylinder
  1443. pop ax
  1444. xor dx,dx ; set up for div
  1445. div cx ; div #sec by sec/cyl to get # cyl
  1446. or dx,dx
  1447. jz No_Cyl_Rnd ; came out even
  1448. inc ax ; round up
  1449. No_Cyl_Rnd:
  1450. mov es:[di].cCyln,ax
  1451. message ftestinit,<"Ccyln ">
  1452. MNUM ftestinit,AX
  1453. message ftestinit,<cr,lf>
  1454. push es
  1455. pop ds
  1456. lea si,[di].BytePerSec ; ds:si -> BPB for hard file
  1457. jmp short Set_RecBPB
  1458. NotHardFF:
  1459. push cs
  1460. pop ds
  1461. cmp bl,ffOther ; Special case "other" type of medium
  1462. JNZ NOT_PROCESS_OTHER ;3.30
  1463. Process_Other:
  1464. xor dx,dx
  1465. mov ax,[di].cCyln
  1466. mov bx,[di].RHdlim
  1467. mul bx
  1468. mov bx,[di].RSeclim
  1469. mul bx
  1470. mov [di].RDrvlim,ax ; Have the total number of sectors
  1471. dec ax
  1472. ; New logic to get the sectors/fat area. ;3.30
  1473. ;Fat entry assumed to be 1.5 bytes;3.30
  1474. mov bx, 3 ;3.30
  1475. mul bx ;3.30
  1476. mov bx,2 ;3.30
  1477. div bx ;3.30
  1478. xor dx, dx ;3.30
  1479. mov bx, 512 ;3.30
  1480. div bx ;3.30
  1481. inc ax ;3.30
  1482. No_Round_Up:
  1483. mov [di].RcSecFat,ax
  1484. jmp short Go_To_Next_BDS
  1485. NOT_PROCESS_OTHER: ;3.30
  1486. shl bx,1 ; bx is word index into table of BPBs
  1487. mov si,offset BPBTable
  1488. mov si,word ptr [si+bx] ; get address of BPB
  1489. Set_RecBPB:
  1490. lea di,[di].RBytePerSec ; es:di -> RecBPB
  1491. mov cx,BPBSIZ
  1492. REP MOVSB ; MOVE BPBSIZ BYTES ;3.30
  1493. Go_To_Next_BDS:
  1494. pop di
  1495. pop es ; restore pointer to BDS
  1496. mov bx,word ptr es:[di].link+2
  1497. mov di,word ptr es:[di].link
  1498. mov es,bx
  1499. jmp Next_BDS
  1500. SETDRVPARMS ENDP ;3.30
  1501. ;
  1502. ; READ CLUSTER SPECIFIED IN BX
  1503. ; CX = SECTORS PER CLUSTER
  1504. ; DI = LOAD LOCATION
  1505. ;
  1506. GETCLUS PROC NEAR ;3.30
  1507. PUSH CX
  1508. PUSH DI
  1509. MOV DOSCNT,CX ;SAVE NUMBER OF SECTORS TO READ
  1510. MOV AX,BX
  1511. DEC AX
  1512. DEC AX
  1513. MUL CX ;CONVERT TO LOGICAL SECTOR
  1514. ADD AX,BIOS$ ;ADD IN FIRST DATA SECTOR
  1515. MOV DX,AX ;DX = FIRST SECTOR TO READ
  1516. GETCL1:
  1517. MNUM fTestINIT
  1518. Message fTestINIT,<" => ">
  1519. ;SI = BX, BX = NEXT ALLOCATION UNIT
  1520. ;
  1521. ; GET THE FAT ENTRY AT BX, WHEN FINISHED SI=ENTRY BX
  1522. ;
  1523. UNPACK:
  1524. PUSH DS
  1525. PUSH BX
  1526. MOV SI,FatLoc
  1527. TEST fBigFat,fBIG ; if (!fBigFat) {
  1528. JNZ Unpack16
  1529. MOV DS,SI
  1530. MOV SI,BX
  1531. SHR SI,1
  1532. MOV BX,[SI+BX] ; p = fat[clus+clus/2];
  1533. JNC HAVCLUS ; if (clus&1)
  1534. SHR BX,1 ; p >>= 4;
  1535. SHR BX,1
  1536. SHR BX,1
  1537. SHR BX,1
  1538. HAVCLUS:
  1539. AND BX,0FFFH ; oldclus=clus; clus = p & 0xFFF;
  1540. JMP SHORT UNPACKX ;3.30
  1541. Unpack16: ; else {
  1542. MOV DS,SI
  1543. SHL BX,1 ; oldclus = clus;
  1544. MOV BX,[BX] ; clus = fat[2*clus];
  1545. UNPACKX: ;3.30
  1546. POP SI ; return;
  1547. POP DS
  1548. ; }
  1549. MNUM fTestINIT
  1550. Message fTestINIT,<" ">
  1551. SUB SI,BX
  1552. CMP SI,-1 ;one apart?
  1553. JNZ GETCL2
  1554. ADD DOSCNT,CX
  1555. JMP GETCL1
  1556. GETCL2:
  1557. PUSH BX
  1558. MOV AX,DRVFAT ;GET DRIVE AND FAT SPEC
  1559. MOV CX,DOSCNT
  1560. CALL DISKRD ;READ THE CLUSTERS
  1561. POP BX
  1562. POP DI
  1563. MOV AX,DOSCNT ;GET NUMBER OF SECTORS READ
  1564. XCHG AH,AL ;MULTIPLY BY 256
  1565. SHL AX,1 ;TIMES 2 EQUAL 512
  1566. ADD DI,AX ;UPDATE LOAD LOCATION
  1567. POP CX ;RESTORE SECTORS/CLUSTER
  1568. RET
  1569. GETCLUS ENDP ; RETURN; ;3.30
  1570. ;
  1571. ; SI POINTS TO DEVICE HEADER
  1572. ;
  1573. ; 4/22/86 - print_init, aux_init is modified to eliminate the ;3.30
  1574. ; self-modifying code. ;3.30
  1575. ;3.30
  1576. PRINT_INIT: ;3.30
  1577. call Get_device_number ;3.30
  1578. mov ah,1 ;initalize printer port ;3.30
  1579. int 17h ;call ROM-Bios routine ;3.30
  1580. ret ;3.30
  1581. ;3.30
  1582. AUX_INIT: ;3.30
  1583. call Get_device_number ;3.30
  1584. mov al,RSINIT ;2400,N,1,8 (MSEQU.INC) ;3.30*
  1585. mov ah,0 ;initalize AUX port ;3.30*
  1586. int 14h ;call ROM-Bios routine ;3.30*
  1587. ret ;3.30
  1588. ;3.30
  1589. GET_DEVICE_NUMBER: ;3.30
  1590. ;SI -> device header ;3.30
  1591. MOV AL,CS:[SI+13] ;GET DEVICE NUMBER FROM THE NAME ;3.30
  1592. SUB AL,"1" ;3.30
  1593. CBW ;3.30
  1594. MOV DX,AX ;3.30
  1595. RET ;3.30
  1596. ;
  1597. ; purge_96tpi NOP's calls to 96tpi support.
  1598. ;
  1599. PURGE_96TPI PROC NEAR ;MJB001 ;3.30
  1600. PUSH DS
  1601. PUSH ES
  1602. push cs ;mjb001
  1603. pop es ;mjb001
  1604. push cs ;mjb001
  1605. pop ds ;mjb001
  1606. ASSUME DS:CODE,ES:CODE ;3.30
  1607. MOV SI,OFFSET PatchTable
  1608. PatchLoop:
  1609. LODSW
  1610. MOV CX,AX
  1611. JCXZ PatchDone
  1612. LODSW
  1613. MOV DI,AX
  1614. MOV AL,90h
  1615. REP STOSB
  1616. JMP PatchLoop
  1617. PatchDone:
  1618. mov di,offset TABLE_PATCH ; ARR 2.42
  1619. MOV AX,OFFSET EXIT
  1620. STOSW
  1621. STOSW
  1622. POP ES
  1623. POP DS
  1624. ret ;mjb001
  1625. PURGE_96TPI ENDP ;3.30
  1626. ;Mini disk initialization routine. Called right after DoHard - 4/7/86;3.30
  1627. ; DoMini **************************************************************** ;3.30
  1628. ; **CS=DS=ES=code ;3.30
  1629. ; **DoMini will search for every extended partition in the system, and ;3.30
  1630. ; initialize it. ;3.30
  1631. ; **BDSM stands for BDS table for Mini disk and located right after the ;3.30
  1632. ; label End96Tpi. End_Of_BDSM will have the offset value of the ending ;3.30
  1633. ; address of BDSM table. ;3.30
  1634. ; **BDSM is the same as usual BDS except that TIM_LO, TIM_HI entries are ;3.30
  1635. ; overlapped and used to id mini disk and the number of Hidden_trks. ;3.30
  1636. ; Right now, they are called as IsMini, Hidden_Trks respectively. ;3.30
  1637. ; **DoMini will use the same routine in SETHARD routine after label SET1 ;3.30
  1638. ; to save coding. ;3.30
  1639. ; **DRVMAX determined in DoHard routine will be used for the next ;3.30
  1640. ; available logical mini disk drive number. ;3.30
  1641. ; ;3.30
  1642. ; Input: DRVMAX, DSKDRVS ;3.30
  1643. ; ;3.30
  1644. ; Output: MiniDisk installed. BDSM table established and installed to BDS.;3.30
  1645. ; num_mini_dsk - number of mini disks installed in the system. ;3.30
  1646. ; End_Of_BDSM - ending offset address of BDSM. ;3.30
  1647. ; ;3.30
  1648. ; ;3.30
  1649. ; Called modules: ;3.30
  1650. ; GetBoot, WRMSG, int 13h (AH=8, Rom) ;3.30
  1651. ; FIND_MINI_PARTITION (new), Install_BDSM (new), ;3.30
  1652. ; SetMini (new, it will use SET1 routine) ;3.30
  1653. ; Variables used: End_Of_BDSM, numh, mininum, num_mini_dsk, ;3.30
  1654. ; Rom_Minidsk_num, Mini_HDLIM, Mini_SECLIM ;3.30
  1655. ; BDSMs, BDSM_type (struc), Start_BDS ;3.30
  1656. ;************************************************************************ ;3.30
  1657. ; ;3.30
  1658. ;3.30
  1659. DoMini: ;3.30
  1660. Message fTestHard,<"Start of DoMini...",cr,lf> ;3.30
  1661. ;3.30
  1662. push ax ;Do I need to do this? ;3.30
  1663. ;3.30
  1664. mov di, offset BDSMs ;from now on, DI points to BDSM ;3.30
  1665. mov dl, 80h ;look at first hard drive ;3.30*
  1666. mov ah, 8h ;get drive parameters ;3.30*
  1667. int 13h ;call ROM-Bios ;3.30*
  1668. cmp dl, 0 ;3.30
  1669. jz DoMiniRet ;no hard file? Then exit. ;3.30
  1670. mov numh, dl ;save the number of hard files. ;3.30
  1671. xor ax,ax ;3.30
  1672. mov al, drvmax ;3.30
  1673. mov mininum, al ;this will be logical drive letter;3.30
  1674. ;for mini disk to start with. ;3.30
  1675. ;3.30
  1676. shl ax, 1 ;ax=number of devices. word bndry ;3.30
  1677. push bx ;3.30
  1678. mov bx, offset DSKDRVS ;3.30
  1679. add bx, ax ;3.30
  1680. mov Mini_BPB_ptr, BX ;Mini_BPB_ptr points to first avlb;3.30
  1681. ;spot in DskDrvs for Mini disk ;3.30
  1682. ;which points to BPB area of BDSM.;3.30
  1683. pop bx ;3.30
  1684. ;3.30
  1685. mov Rom_Minidsk_num, 80h ;3.30
  1686. DoMiniBegin: ;3.30
  1687. inc dh ;Get # of heads (conv to 1 based) ;3.30
  1688. xor ax, ax ;3.30
  1689. mov al, dh ;3.30
  1690. mov Mini_HDLIM, ax ;save it. ;3.30
  1691. xor ax, ax ;3.30
  1692. and cl, 3fh ;Get # of sectors/track ;3.30
  1693. mov al, cl ;3.30
  1694. mov Mini_SECLIM, ax ;and save it. ;3.30
  1695. ;3.30
  1696. mov dl, Rom_Minidsk_num ;drive number <DL> ;3.30
  1697. call GETBOOT ;rd master boot rec 7c0:BootBias ;3.30
  1698. jc DoMiniNext ;3.30
  1699. call FIND_MINI_PARTITION ;3.30
  1700. DoMiniNext: ;3.30
  1701. dec numh ;3.30
  1702. jz DoMiniRet ;3.30
  1703. inc Rom_MiniDsk_Num ;Next hard file ;3.30
  1704. mov dl, Rom_MiniDsk_Num ;look at next hard drive ;3.30*
  1705. mov ah, 8h ;get drive parameters ;3.30*
  1706. int 13h ;call ROM-Bios ;3.30*
  1707. jmp DoMiniBegin ;3.30
  1708. ;3.30
  1709. DoMiniRet: ;3.30
  1710. pop ax ;3.30
  1711. ret ;3.30
  1712. ;3.30
  1713. ;3.30
  1714. ;Find_Mini_Partition tries to find every Extended partition on a disk. ;3.30
  1715. ;At entry: DI -> BDSM entry ;3.30
  1716. ; ES:BX -> 07c0:BootBias - Master Boot Record ;3.30
  1717. ; Rom_MiniDsk_Num - ROM drive number ;3.30
  1718. ; MiniNum - Logical drive number ;3.30
  1719. ; Mini_HDLIM, Mini_SECLIM ;3.30
  1720. ; ;3.30
  1721. ;Called routine: SETMINI which uses SET1 (in SETHARD routine) ;3.30
  1722. ;Variables & equates used from orig BIOS - flags, fNon_Removable, fBigfat ;3.30
  1723. ; ;3.30
  1724. ; ;3.30
  1725. FIND_MINI_PARTITION: ;3.30
  1726. ;3.30
  1727. add bx, 1C2h ;BX -> system id. ;3.30
  1728. ;3.30
  1729. FmpNext: ;3.30
  1730. cmp byte ptr ES:[BX], 5 ; 5 = extended partition ID. ;3.30
  1731. jz FmpGot ;3.30
  1732. add bx, 16 ; for next entry ;3.30
  1733. cmp bx, 202h+BootBias ;3.30
  1734. jnz FmpNext ;3.30
  1735. jmp FmpRet ;not found extended partition ;3.30
  1736. ;3.30
  1737. FmpGot: ;found my partition. ;3.30
  1738. Message ftestHard,<"Found my partition...",cr,lf> ;3.30
  1739. xor ax,ax ;3.30
  1740. or al, fNon_Removable ;3.30
  1741. or word ptr [DI].Flags, ax ;3.30
  1742. mov byte ptr [DI].FormFactor, ffHardFile ;3.30
  1743. mov fBigFat, 0 ;assume 12 bit Fat. ;3.30
  1744. mov ax, Mini_HDLIM ;3.30
  1745. mov [DI].HDLIM, ax ;3.30
  1746. mov ax, Mini_SECLIM ;3.30
  1747. mov [DI].SECLIM, ax ;3.30
  1748. mov al, Rom_MiniDsk_Num ;3.30
  1749. mov [DI].DriveNum, al ;set physical number ;3.30
  1750. mov al, Mininum ;3.30
  1751. mov [DI].DriveLet, al ;set logical number ;3.30
  1752. ;3.30
  1753. cmp word ptr ES:[BX+8], 64 ;**With current BPB, only lower word ;3.30
  1754. ; is meaningful. ;3.30
  1755. je FmpRet ;should be bigger than 64 sectors at least ;3.30
  1756. sub bx, 4 ;let BX point to the start of the entry ;3.30
  1757. mov dh, byte ptr ES:[BX+2] ;3.30
  1758. and dh, 11000000b ;get higher bits of cyl ;3.30
  1759. rol dh, 1 ;3.30
  1760. rol dh, 1 ;3.30
  1761. mov dl, byte ptr ES:[BX+3] ;cyl byte ;3.30
  1762. mov [DI].Hidden_Trks, dx ;set hidden trks ;3.30
  1763. ;** Now, read the volume boot record into BootBias. ;3.30
  1764. mov cx,ES:[BX+2] ;cylinder,cylinder/sector ;3.30*
  1765. mov dh,ES:[BX+1] ;head ;3.30*
  1766. mov dl,Rom_MiniDsk_Num ;drive ;3.30*
  1767. mov ax,7c0h ; ;3.30*
  1768. mov es,ax ;buffer segment ;3.30*
  1769. mov bx,BOOTBIAS ;buffer offset ;3.30*
  1770. mov ax,0201h ;read,1 sector ;3.30*
  1771. int 13h ;call ROM-Bios routine ;3.30*
  1772. jc FmpRet ;cannot continue. ;3.30
  1773. mov bx, 1c2h+BootBias ;3.30
  1774. ;3.30
  1775. call SetMini ;install a mini disk. BX value saved. ;3.30
  1776. jc FmpnextChain ;3.30
  1777. ;3.30
  1778. call Install_BDSM ;install the BDSM into the BDS table ;3.30
  1779. ; call Show_Installed_Mini ;show the installed message. 3/35/86 - Don't show messages. ;3.30
  1780. inc mininum ;increase the logical drive number for next ;3.30
  1781. inc num_mini_dsk ;increase the number of mini disk installed. ;3.30
  1782. ;3.30
  1783. push bx ;now, set the DskDrvs pointer to BPB info. ;3.30
  1784. mov bx, Mini_BPB_ptr ;3.30
  1785. lea si, [di].BytePerSec ;points to BPB of BDSM ;3.30
  1786. mov [bx], si ;3.30
  1787. inc Mini_BPB_ptr ;advance to the next address ;3.30
  1788. inc Mini_BPB_ptr ;3.30
  1789. pop bx ;3.30
  1790. ;3.30
  1791. add DI, type BDSM_type ;adjust to the next BDSM table entry. ;3.30
  1792. mov End_OF_BDSM, DI ;set the ending address of BDSM table to this. ;3.30
  1793. ; Message fTestHard,<"Mini disk installed.",cr,lf> ;3.30
  1794. FmpnextChain: jmp FmpNext ;let's find out if we have any chained partition ;3.30
  1795. FmpRet: ;3.30
  1796. ret ;3.30
  1797. ;3.30
  1798. SetMini: ;3.30
  1799. push di ;3.30
  1800. push bx ;3.30
  1801. push ds ;3.30
  1802. jmp SET1 ;will be returned to Find mini partition routine. ;3.30
  1803. ;Some logic has been added to SET1 to ;3.30
  1804. ;deal with Mini disks. ;3.30
  1805. ;3.30
  1806. ; ;3.30
  1807. ;Install BDSM installs a BDSM (pointed by DS:DI) into the end of the current ;3.30
  1808. ;linked list of BDS. ;3.30
  1809. ;Also, set the current BDSM pointer segment to DS. ;3.30
  1810. ;At entry: DS:DI -> BDSM ;3.30
  1811. ; ;3.30
  1812. Install_BDSM: ;3.30
  1813. ;3.30
  1814. push ax ;3.30
  1815. push si ;3.30
  1816. push es ;3.30
  1817. ;3.30
  1818. les si, dword ptr cs:Start_BDS ;start of the beginning of list ;3.30
  1819. I_BDSM_Next: ;3.30
  1820. cmp word ptr es:[si], -1 ;end of the list? ;3.30
  1821. jz I_BDSM_New ;3.30
  1822. mov si, word ptr es:[si].link ;3.30
  1823. mov ax, word ptr es:[si].link+2 ;next pointer ;3.30
  1824. mov es, ax ;3.30
  1825. jmp short I_BDSM_Next ;3.30
  1826. I_BDSM_New: ;3.30
  1827. mov ax, ds ;3.30
  1828. mov word ptr ds:[di].link+2, ax ;BDSM segment had not been initialized. ;3.30
  1829. mov word ptr es:[si].link+2, ax ;3.30
  1830. mov word ptr es:[si].link, di ;3.30
  1831. mov word ptr ds:[di].link, -1 ;make sure it is a null ptr. ;3.30
  1832. ;3.30
  1833. I_BDSM_ret: ;3.30
  1834. pop es ;3.30
  1835. pop si ;3.30
  1836. pop ax ;3.30
  1837. ret ;3.30
  1838. ;3.30
  1839. ;***The following code is not needed any more. Don't show any ;3.30
  1840. ;***messages to be compatible with the behavior of IO.SYS. ;3.30
  1841. ;;Show the message "Mini disk installed ..." ;3.30
  1842. ;;This routine uses WRMSG procedure which will call OUTCHR. ;3.30
  1843. ;Show_Installed_Mini: ;3.30
  1844. ; push ax ;3.30
  1845. ; push bx ;3.30
  1846. ; push ds ;3.30
  1847. ; ;3.30
  1848. ; mov al, Mininum ;logical drive number ;3.30
  1849. ; add al, Drv_Letter_Base ;='A' ;3.30
  1850. ; mov Mini_Drv_Let, al ;3.30
  1851. ; mov si, offset Installed_Mini ;3.30
  1852. ; call WRMSG ;3.30
  1853. ; ;3.30
  1854. ; pop ds ;3.30
  1855. ; pop bx ;3.30
  1856. ; pop ax ;3.30
  1857. ; ret ;3.30
  1858. ;**End of mini disk initialization** ; 4/7/86 ;3.30
  1859. ;3.30
  1860. ;3.30
  1861. CMOS_Clock_Read proc near ;3.30
  1862. ;3.30
  1863. ; IN ORDER TO DETERMINE IF THERE IS A CLOCK PRESENT IN THE SYSTEM, THE FOLLOWING ;3.30
  1864. ; NEEDS TO BE DONE. ;3.30
  1865. PUSH AX ;3.30
  1866. PUSH CX ;3.30
  1867. PUSH DX ;3.30
  1868. PUSH BP ;3.30
  1869. ;3.30
  1870. XOR BP,BP ;3.30
  1871. LOOP_CLOCK: ;3.30
  1872. XOR CX,CX ;3.30
  1873. XOR DX,DX ;3.30
  1874. MOV AH,2 ;READ REAL TIME CLOCK ;3.30
  1875. INT 1Ah ;CALL ROM-BIOS ROUTINE ;3.30
  1876. CMP CX,0 ;3.30
  1877. JNZ CLOCK_PRESENT ;3.30
  1878. ;3.30
  1879. CMP DX,0 ;3.30
  1880. JNZ CLOCK_PRESENT ;3.30
  1881. ;3.30
  1882. CMP BP,1 ; READ AGAIN AFTER A SLIGHT DELAY, IN CASE CLOCK ;3.30
  1883. JZ NO_READDATE ; WAS AT ZERO SETTING. ;3.30
  1884. ;3.30
  1885. INC BP ; ONLY PERFORM DELAY ONCE. ;3.30
  1886. MOV CX,4000H ;3.30
  1887. DELAY: ;3.30
  1888. LOOP DELAY ;3.30
  1889. JMP LOOP_CLOCK ;3.30
  1890. ;3.30
  1891. CLOCK_PRESENT: ;3.30
  1892. mov cs:HaveCMOSClock, 1 ; Set the flag for cmos clock ;3.30
  1893. ;3.30
  1894. call CMOSCK ; Reset CMOS clock rate that may be ;3.30
  1895. ;possibly destroyed by CP DOS and POST routine did not ;3.30
  1896. ;restore that. ;3.30
  1897. ;3.30
  1898. PUSH SI ;3.30
  1899. MESSAGE FTESTINIT,<"CLOCK DEVICE",CR,LF> ;3.30
  1900. CALL READ_REAL_DATE ;MJB002 READ REAL-TIME CLOCK FOR DATE ;3.30
  1901. ;3.30
  1902. CLI ;MJB002 ;3.30
  1903. MOV DAYCNT,SI ;MJB002 SET SYSTEM DATE ;3.30
  1904. STI ;MJB002 ;3.30
  1905. POP SI ;MJB002 ;3.30
  1906. NO_READDATE: ;3.30
  1907. POP BP ;3.30
  1908. POP DX ;3.30
  1909. POP CX ;3.30
  1910. POP AX ;3.30
  1911. RET ;3.30
  1912. ;3.30
  1913. CMOS_Clock_Read endp ;3.30
  1914. ; ;3.30
  1915. ; 10/28/86 ;3.30
  1916. ; THE FOLLOWING CODE IS WRITTEN BY JACK GULLEY IN ENGINEERING GROUP. ;3.30
  1917. ; CP DOS IS CHANGING CMOS CLOCK RATE FOR ITS OWN PURPOSES AND IF THE ;3.30
  1918. ; USE COLD BOOT THE SYSTEM TO USE PC DOS WHILE RUNNING CP DOS, THE CMOS ;3.30
  1919. ; CLOCK RATE ARE STILL SLOW WHICH SLOW DOWN DISK OPERATIONS OF PC DOS ;3.30
  1920. ; WHICH USES CMOS CLOCK. PC DOS IS PUT THIS CODE IN MSINIT TO FIX THIS ;3.30
  1921. ; PROBLEM AT THE REQUEST OF CP DOS. ;3.30
  1922. ; THE PROGRAM IS MODIFIED TO BE RUN ON MSINIT. Equates are defined in CMOSEQU.INC. ;3.30
  1923. ; This program will be called by CMOS_Clock_Read procedure. ;3.30
  1924. ; ;3.30
  1925. ; The following code CMOSCK is used to insure that the CMOS has not ;3.30
  1926. ; had its rate controls left in an invalid state on older AT's. ;3.30
  1927. ; ;3.30
  1928. ; It checks for an AT model byte "FC" with a submodel type of ;3.30
  1929. ; 00, 01, 02, 03 or 06 and resets the periodic interrupt rate ;3.30
  1930. ; bits incase POST has not done it. This initilization routine ;3.30
  1931. ; is only needed once when DOS loads. It should be ran as soon ;3.30
  1932. ; as possible to prevent slow diskette access. ;3.30
  1933. ; ;3.30
  1934. ; This code exposes one to DOS clearing CMOS setup done by a ;3.30
  1935. ; resident program that hides and re-boots the system. ;3.30
  1936. ; ;3.30
  1937. CMOSCK PROC NEAR ; CHECK AND RESET RTC RATE BITS ;3.30
  1938. ;3.30
  1939. ;Model byte and Submodel byte were already determined in MSINIT. ;3.30
  1940. push ax ;3.30
  1941. cmp cs:Model_byte, 0FCh ;check for PC-AT model byte ;3.30
  1942. ; EXIT IF NOT "FC" FOR A PC-AT ;3.30
  1943. JNE CMOSCK9 ; Exit if not an AT model ;3.30
  1944. ;3.30
  1945. CMP cs:Secondary_Model_Byte,06H ; Is it 06 for the industral AT ;3.30
  1946. JE CMOSCK4 ; Go reset CMOS periodic rate if 06 ;3.30
  1947. CMP cs:Secondary_Model_Byte,04H ; Is it 00, 01, 02, or 03 ;3.30
  1948. JNB CMOSCK9 ; EXIT if problem fixed by POST ;3.30
  1949. ; Also,Secondary_model_byte = 0 when AH=0c0h, int 15h failed. ;3.30
  1950. CMOSCK4: ; RESET THE CMOS PERIODIC RATE ;3.30
  1951. ; Model=FC submodel=00,01,02,03 or 06 ;3.30
  1952. mov al,CMOS_REG_A or NMI ;NMI disabled on return
  1953. mov ah,00100110b ;Set divider & rate selection
  1954. call CMOS_WRITE
  1955. mov al,CMOS_REG_B or NMI ;NMI disabled on return
  1956. call CMOS_READ
  1957. and al,00000111b ;clear SET,PIE,AIE,UIE,SQWE
  1958. mov ah,al
  1959. mov al,CMOS_REG_B ;NMI enabled on return
  1960. call CMOS_WRITE
  1961. CMOSCK9: ; EXIT ROUTINE ;3.30
  1962. pop ax ;3.30
  1963. RET ; RETurn to caller ;3.30
  1964. ; Flags modifyied ;3.30
  1965. CMOSCK ENDP ;3.30
  1966. PAGE ;3.30
  1967. ;--- CMOS_READ ----------------------------------------------------------------- ;3.30
  1968. ; READ BYTE FROM CMOS SYSTEM CLOCK CONFIGURATION TABLE : ;3.30
  1969. ; : ;3.30
  1970. ; INPUT: (AL)= CMOS TABLE ADDRESS TO BE READ : ;3.30
  1971. ; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT : ;3.30
  1972. ; BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ : ;3.30
  1973. ; : ;3.30
  1974. ; OUTPUT: (AL) VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS : ;3.30
  1975. ; ON THEN NMI LEFT DISABLED. DURING THE CMOS READ BOTH NMI AND : ;3.30
  1976. ; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. : ;3.30
  1977. ; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND : ;3.30
  1978. ; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. : ;3.30
  1979. ; ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED. : ;3.30
  1980. ;------------------------------------------------------------------------------- ;3.30
  1981. ;3.30
  1982. CMOS_READ PROC NEAR ; READ LOCATION (AL) INTO (AL) ;3.30
  1983. PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS ;3.30
  1984. cli
  1985. push bx
  1986. push ax ;save user NMI state
  1987. or al,NMI ;disable NMI for us
  1988. out CMOS_PORT,al
  1989. nop ;undocumented delay needed
  1990. in al,CMOS_DATA ;get data value
  1991. ;set NMI state to user specified
  1992. mov bx,ax ;save data value
  1993. pop ax ;get user NMI
  1994. and al,NMI
  1995. or al,CMOS_SHUT_DOWN
  1996. out CMOS_PORT,al
  1997. nop
  1998. in al,CMOS_DATA
  1999. mov ax,bx ;data value
  2000. pop bx
  2001. PUSH CS ; *PLACE CODE SEGMENT IN STACK AND ;3.30
  2002. CALL CMOS_POPF ; *HANDLE POPF FOR B- LEVEL 80286 ;3.30
  2003. RET ; RETURN WITH FLAGS RESTORED ;3.30
  2004. ;3.30
  2005. CMOS_READ ENDP ;3.30
  2006. ;3.30
  2007. CMOS_POPF PROC NEAR ; POPF FOR LEVEL B- PARTS ;3.30
  2008. IRET ; RETURN FAR AND RESTORE FLAGS ;3.30
  2009. ;3.30
  2010. CMOS_POPF ENDP ;3.30
  2011. ;3.30
  2012. ;--- CMOS_WRITE ---------------------------------------------------------------- ;3.30
  2013. ; WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE : ;3.30
  2014. ; : ;3.30
  2015. ; INPUT: (AL)= CMOS TABLE ADDRESS TO BE WRITTEN TO : ;3.30
  2016. ; BIT 7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT : ;3.30
  2017. ; BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE : ;3.30
  2018. ; (AH)= NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION : ;3.30
  2019. ; : ;3.30
  2020. ; OUTPUT: VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED : ;3.30
  2021. ; IF BIT 7 OF (AL) IS ON. DURING THE CMOS UPDATE BOTH NMI AND : ;3.30
  2022. ; NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. : ;3.30
  2023. ; THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND : ;3.30
  2024. ; THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN. : ;3.30
  2025. ; ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED. : ;3.30
  2026. ;------------------------------------------------------------------------------- ;3.30
  2027. ;3.30
  2028. CMOS_WRITE PROC NEAR ; WRITE (AH) TO LOCATION (AL) ;3.30
  2029. PUSHF ; SAVE INTERRUPT ENABLE STATUS AND FLAGS ;3.30
  2030. PUSH AX ; SAVE WORK REGISTER VALUES ;3.30
  2031. cli
  2032. push ax ;save user NMI state
  2033. or al,NMI ;disable NMI for us
  2034. out CMOS_PORT,al
  2035. nop
  2036. mov al,ah
  2037. out CMOS_DATA,al ;write data
  2038. ;set NMI state to user specified
  2039. pop ax ;get user NMI
  2040. and al,NMI
  2041. or al,CMOS_SHUT_DOWN
  2042. out CMOS_PORT,al
  2043. nop
  2044. in al,CMOS_DATA
  2045. POP AX ; RESTORE WORK REGISTERS ;3.30
  2046. PUSH CS ; *PLACE CODE SEGMENT IN STACK AND ;3.30
  2047. CALL CMOS_POPF ; *HANDLE POPF FOR B- LEVEL 80286 ;3.30
  2048. RET ;3.30
  2049. ;3.30
  2050. CMOS_WRITE ENDP ;3.30
  2051. ; ;3.30
  2052. END$:
  2053. code ends
  2054. end