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.

2228 lines
68 KiB

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