Leaked source code of windows server 2003
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.

955 lines
22 KiB

  1. page ,160
  2. title msbio1.asm - Bios_Data definition and device driver entry/exit
  3. ;
  4. ;----------------------------------------------------------------------------
  5. ;
  6. ; Modification history
  7. ;
  8. ; 26-Feb-1991 sudeepb Ported for NT DOSEm
  9. ;
  10. ;----------------------------------------------------------------------------
  11. ;
  12. include version.inc ; set build flags
  13. include biosseg.inc ; define BIOS segments
  14. include devsym.inc
  15. include msequ.inc
  16. include vint.inc
  17. ; Assembly conditional for stack switching
  18. ;
  19. STACKSW equ 1
  20. Bios_Data segment
  21. assume cs:Bios_Data
  22. public BData_start
  23. BData_start:
  24. assume ds:nothing,es:nothing
  25. public hdrv_pat
  26. hdrv_pat label word ; patched by msinit
  27. assume cs:Bios_Data
  28. extrn init:near ; this is in msinit
  29. jmp init ; go to initialization code
  30. ; define some stuff that is also used by msdos.sys from an include file
  31. In_Bios = 0ffffh ; define flag for msbdata.inc
  32. include msbdata.inc
  33. public inHMA,xms
  34. inHMA db 0 ; flag indicates we're running from HMA
  35. xms dd 0 ; entry point to xms if above is true
  36. align 4
  37. public ntvdmstate
  38. ntvdmstate dd 0
  39. IF 2
  40. .errnz ntvdmstate-BData_start-FIXED_NTVDMSTATE_OFFSET
  41. ENDIF
  42. public ptrsav
  43. ptrsav dd 0
  44. public auxbuf
  45. auxbuf db 0,0,0,0 ;set of 1 byte buffers for com 1,2,3, and 4
  46. public zeroseg
  47. zeroseg dw 0 ; easy way to load segment registers with zero
  48. public auxnum
  49. auxnum dw 0 ;which aux device was requested
  50. public res_dev_list
  51. res_dev_list label byte
  52. p_attr = chardev+outtilbusy+dev320+IOQUERY+DEVOPCL
  53. ; ** p_attr = chardev+outtilbusy+dev320
  54. sysdev <auxdev2,8013h,strategy,con_entry,'CON '>
  55. auxdev2 sysdev <prndev2,8000h,strategy,aux0_entry,'AUX '>
  56. prndev2 sysdev <timdev,p_attr,strategy,prn0_entry,'PRN '>
  57. timdev sysdev <com1dev,8008h,strategy,tim_entry,'CLOCK$ '>
  58. com1dev sysdev <lpt1dev,8000h,strategy,aux0_entry,'COM1 '>
  59. lpt1dev sysdev <lpt2dev,p_attr,strategy,prn1_entry,"LPT1 ">
  60. lpt2dev sysdev <lpt3dev,p_attr,strategy,prn2_entry,"LPT2 ">
  61. lpt3dev sysdev <com2dev,p_attr,strategy,prn3_entry,"LPT3 ">
  62. com2dev sysdev <com3dev,8000h,strategy,aux1_entry,"COM2 ">
  63. com3dev sysdev <com4dev,8000h,strategy,aux2_entry,"COM3 ">
  64. com4dev dw -1,Bios_Data,8000h,strategy,aux3_entry
  65. db "COM4 "
  66. public RomVectors
  67. RomVectors label byte
  68. public Old10, Old15, Old19, Old1B
  69. db 10h ; M028
  70. Old10 dd (?) ; M028
  71. db 15h
  72. Old15 dd (?)
  73. db 19h
  74. Old19 dd (?)
  75. db 1bh
  76. Old1B dd (?)
  77. EndRomVectors equ $
  78. public NUMROMVECTORS
  79. NUMROMVECTORS equ ((EndRomVectors - RomVectors)/5)
  80. public spc_mse_int10
  81. spc_mse_int10 dd (?)
  82. public int29Perf
  83. int29Perf dd (?)
  84. public keyrd_func
  85. public keysts_func
  86. ; moved altah to inc\msbdata.inc so it could go in instance table in DOS
  87. keyrd_func db 0 ; default is conventional keyboard read
  88. keysts_func db 1 ; default is conventional keyboard status check.
  89. public printdev
  90. printdev db 0 ; index into above array
  91. public multrk_flag
  92. multrk_flag dw 0
  93. ; the following variable can be modified via ioctl sub-function 16. in this
  94. ; way, the wait can be set to suit the speed of the particular printer being
  95. ; used. one for each printer device.
  96. public wait_count
  97. wait_count dw 4 dup (50h) ; array of retry counts for printer
  98. public int19sem
  99. int19sem db 0 ; indicate that all int 19
  100. ; initialization is complete
  101. ; we assume the following remain contiguous and their order doesn't change
  102. i19_lst:
  103. irp aa,<02,08,09,0a,0b,0c,0d,0e,70,72,73,74,76,77>
  104. public int19old&aa
  105. db aa&h ; store the number as a byte
  106. int19old&aa dd -1 ;orignal hardware int. vectors for int 19h.
  107. endm
  108. num_i19 = ((offset $) - (offset i19_lst))/5
  109. ;variables for dynamic relocatable modules
  110. ;these should be stay resident.
  111. public int6c_ret_addr
  112. int6c_ret_addr dd ? ; return address from int 6c for p12 machine
  113. ;
  114. ; data structures for real-time date and time
  115. ;
  116. public bin_date_time
  117. public month_table
  118. public daycnt2
  119. public feb29
  120. bin_date_time:
  121. db 0 ; century (19 or 20) or hours (0-23)
  122. db 0 ; year in century (0...99) or minutes (0-59)
  123. db 0 ; month in year (1...12) or seconds (0-59)
  124. db 0 ; day in month (1...31)
  125. month_table:
  126. dw 0 ; january
  127. dw 31 ; february
  128. dw 59
  129. dw 90
  130. dw 120
  131. dw 151
  132. dw 181
  133. dw 212
  134. dw 243
  135. dw 273
  136. dw 304
  137. dw 334 ; december
  138. daycnt2 dw 0000 ; temp for count of days since 1-1-80
  139. feb29 db 0 ; february 29 in a leap year flag
  140. ;************************************************************************
  141. ;* *
  142. ;* entry points into Bios_Code routines. The segment values *
  143. ;* are plugged in by seg_reinit. *
  144. ;* *
  145. ;************************************************************************
  146. public cdev
  147. cdev dd chardev_entry
  148. bcode_i2f dd i2f_handler
  149. end_BC_entries:
  150. ;************************************************************************
  151. ;* *
  152. ;* cbreak - break key handling - simply set altah=3 and iret *
  153. ;* *
  154. ;************************************************************************
  155. public cbreak
  156. cbreak proc near
  157. assume ds:nothing,es:nothing
  158. mov altah,3 ;indicate break key set
  159. public intret ; general purpose iret in the Bios_Data seg
  160. intret:
  161. FIRET
  162. cbreak endp
  163. ;************************************************************************
  164. ;* *
  165. ;* strategy - store es:bx (device driver request packet) *
  166. ;* away at [ptrsav] for next driver function call *
  167. ;* *
  168. ;************************************************************************
  169. public strategy
  170. strategy proc far
  171. assume ds:nothing,es:nothing
  172. mov word ptr cs:[ptrsav],bx
  173. mov word ptr cs:[ptrsav+2],es
  174. ret
  175. strategy endp
  176. ;************************************************************************
  177. ;* *
  178. ;* device driver entry points. these are the initial *
  179. ;* 'interrupt' hooks out of the device driver chain. *
  180. ;* in the case of our resident drivers, they'll just *
  181. ;* stick a fake return address on the stack which *
  182. ;* points to dispatch tables and possibly some unit *
  183. ;* numbers, and then call through a common entry point *
  184. ;* which can take care of a20 switching *
  185. ;* *
  186. ;************************************************************************
  187. con_entry proc near
  188. assume ds:nothing,es:nothing
  189. call cdev_entry ; call into code segment handler
  190. dw con_table
  191. con_entry endp
  192. ;--------------------------------------------------------------------
  193. prn0_entry proc near
  194. assume ds:nothing,es:nothing
  195. call cdev_entry
  196. dw prn_table
  197. db 0,0 ; device numbers
  198. prn0_entry endp
  199. ;--------------------------------------------------------------------
  200. prn1_entry proc near
  201. assume ds:nothing,es:nothing
  202. call cdev_entry
  203. dw prn_table
  204. db 0,1
  205. prn1_entry endp
  206. ;--------------------------------------------------------------------
  207. prn2_entry proc near
  208. assume ds:nothing,es:nothing
  209. call cdev_entry
  210. dw prn_table
  211. db 1,2
  212. prn2_entry endp
  213. ;--------------------------------------------------------------------
  214. prn3_entry proc near
  215. assume ds:nothing,es:nothing
  216. call cdev_entry
  217. dw prn_table
  218. db 2,3
  219. prn3_entry endp
  220. ;--------------------------------------------------------------------
  221. aux0_entry proc near
  222. assume ds:nothing,es:nothing
  223. call cdev_entry
  224. dw aux_table
  225. db 0
  226. aux0_entry endp
  227. ;--------------------------------------------------------------------
  228. aux1_entry proc near
  229. assume ds:nothing,es:nothing
  230. call cdev_entry
  231. dw aux_table
  232. db 1
  233. aux1_entry endp
  234. ;--------------------------------------------------------------------
  235. aux2_entry proc near
  236. assume ds:nothing,es:nothing
  237. call cdev_entry
  238. dw aux_table
  239. db 2
  240. aux2_entry endp
  241. ;--------------------------------------------------------------------
  242. aux3_entry proc near
  243. assume ds:nothing,es:nothing
  244. call cdev_entry
  245. dw aux_table
  246. db 3
  247. aux3_entry endp
  248. ;--------------------------------------------------------------------
  249. tim_entry proc near
  250. assume ds:nothing,es:nothing
  251. call cdev_entry
  252. dw tim_table
  253. tim_entry endp
  254. ;--------------------------------------------------------------------
  255. ;************************************************************************
  256. ;* *
  257. ;* Ensure A20 is enabled before jumping into code in HMA. *
  258. ;* This code assumes that if Segment of Device request packet is *
  259. ;* DOS DATA segment then the Device request came from DOS & that *
  260. ;* A20 is already on. *
  261. ;* *
  262. ;************************************************************************
  263. cdev_entry proc near
  264. assume ds:nothing,es:nothing
  265. ;
  266. ; M064 - BEGIN
  267. ;
  268. cmp inHMA, 0
  269. je ce_enter_codeseg; optimized for DOS in HMA
  270. push ax
  271. mov ax, DosDataSg
  272. cmp word ptr [ptrsav+2], ax
  273. pop ax
  274. jne not_from_dos ; jump is coded this way to fall thru
  275. ; in 99.99% of the cases
  276. ce_enter_codeseg:
  277. jmp cdev
  278. not_from_dos:
  279. call EnsureA20On
  280. ;
  281. ; M064 - END
  282. ;
  283. jmp short ce_enter_codeseg
  284. cdev_entry endp
  285. ;************************************************************************
  286. ;* *
  287. ;* outchr - this is our int 29h handler. it writes the *
  288. ;* character in al on the display using int 10h ttywrite *
  289. ;* *
  290. ;************************************************************************
  291. public outchr
  292. outchr proc far
  293. assume ds:nothing,es:nothing
  294. push ax
  295. push si
  296. push di
  297. push bp
  298. push bx
  299. mov ah,0eh ; set command to write a character
  300. mov bx,7 ; set foreground color
  301. int 10h ; call rom-bios
  302. pop bx
  303. pop bp
  304. pop di
  305. pop si
  306. pop ax
  307. jmp intret
  308. outchr endp
  309. ; M001 - BEGIN
  310. ;************************************************************************
  311. ;* *
  312. ;* EnsureA20On - ensure that a20 is enabled if we're running *
  313. ;* in the HMA before interrupt entry points into Bios_Code *
  314. ;* *
  315. ;************************************************************************
  316. HiMem label dword
  317. dw 90h
  318. dw 0ffffh
  319. LoMem label dword
  320. dw 80h
  321. dw 0h
  322. EnsureA20On proc near
  323. assume ds:nothing,es:nothing
  324. call IsA20Off
  325. jz ea_enable
  326. ret
  327. EnableA20 proc near ; M041
  328. ea_enable:
  329. push ax
  330. push bx
  331. mov ah,5 ; localenablea20
  332. call xms
  333. pop bx
  334. pop ax
  335. bie_done:
  336. ret
  337. EnableA20 endp ; M041
  338. EnsureA20On endp
  339. ;
  340. ; M001 - END
  341. ; M041 : BEGIN
  342. ;
  343. ;----------------------------------------------------------------------------
  344. ;
  345. ; procedure : IsA20Off
  346. ;
  347. ;----------------------------------------------------------------------------
  348. ;
  349. IsA20Off proc near
  350. push ds
  351. push es
  352. push cx
  353. push si
  354. push di
  355. lds si, HiMem
  356. les di, LoMem
  357. mov cx, 8
  358. rep cmpsw
  359. pop di
  360. pop si
  361. pop cx
  362. pop es
  363. pop ds
  364. ret
  365. IsA20Off endp
  366. ;
  367. ;----------------------------------------------------------------------------
  368. ;
  369. ; procedure : DisableA20
  370. ;
  371. ;----------------------------------------------------------------------------
  372. ;
  373. DisableA20 proc near
  374. push ax
  375. push bx
  376. mov ah,6 ; localdisable a20
  377. call xms
  378. pop bx
  379. pop ax
  380. ret
  381. DisableA20 endp
  382. ; M041 : END
  383. ;************************************************************************
  384. ;* *
  385. ;* int19 - bootstrap interrupt -- we must restore a bunch of the *
  386. ;* interrupt vectors before resuming the original int19 code *
  387. ;* *
  388. ;************************************************************************
  389. public int19
  390. int19 proc far
  391. assume ds:nothing,es:nothing
  392. push cs
  393. pop ds
  394. assume ds:Bios_Data
  395. mov es,zeroseg
  396. mov cx, NUMROMVECTORS ; no. of rom vectors to be restored
  397. mov si, offset RomVectors ; point to list of saved vectors
  398. next_int:
  399. lodsb ; get int number
  400. cbw ; assume < 128
  401. shl ax, 1
  402. shl ax, 1 ; int * 4
  403. mov di, ax
  404. lodsw
  405. stosw
  406. lodsw
  407. stosw ; install the saved vector
  408. loop next_int
  409. cmp byte ptr int19sem,0 ; don't do the others unless we
  410. jz doint19 ; set our initialization complete flag
  411. ; stacks code has changed these hardware interrupt vectors
  412. ; stkinit in sysinit1 will initialize int19holdxx values.
  413. mov si,offset i19_lst
  414. mov cx,num_i19
  415. i19_restore_loop:
  416. lodsb ; get interrupt number
  417. cbw ; assume < 128
  418. mov di,ax ; save interrupt number
  419. lodsw ; get original vector offset
  420. mov bx,ax ; save it
  421. lodsw ; get original vector segment
  422. cmp bx,-1 ; check for 0ffffh (unlikely segment)
  423. jz i19_restor_1 ;opt no need to check selector too
  424. cmp ax,-1 ;opt 0ffffh is unlikely offset
  425. jz i19_restor_1
  426. add di,di
  427. add di,di
  428. xchg ax,bx
  429. stosw
  430. xchg ax,bx
  431. stosw ; put the vector back
  432. i19_restor_1:
  433. loop i19_restore_loop
  434. doint19:
  435. int 19h
  436. int19 endp
  437. ;
  438. ; M036 - BEGIN
  439. ;
  440. ;
  441. ;----------------------------------------------------------------------------
  442. ;
  443. ; procedure : int15
  444. ;
  445. ; Int15 handler for recognizing ctrl-alt-del seq.
  446. ;
  447. ;----------------------------------------------------------------------------
  448. ;
  449. DELKEY equ 53h
  450. public Int15
  451. Int15 proc far
  452. assume ds:nothing
  453. cmp ax, (4fh shl 8) + DELKEY ; del keystroke ?
  454. je @f
  455. jmp dword ptr Old15
  456. @@:
  457. stc
  458. jmp dword ptr Old15
  459. Int15 endp
  460. ;
  461. ;
  462. ;************************************************************************
  463. ;* *
  464. ;* the int2f handler chains up to Bios_Code through here. *
  465. ;* it returns through one of the three functions that follow. *
  466. ;* notice that we'll assume we're being entered from DOS, so *
  467. ;* that we're guaranteed to be A20 enabled if needed *
  468. ;* *
  469. ;************************************************************************
  470. int_2f proc far
  471. assume ds:nothing,es:nothing
  472. jmp bcode_i2f
  473. int_2f endp
  474. ;************************************************************************
  475. ;* *
  476. ;* re_init - called back by sysinit after a bunch of stuff *
  477. ;* is done. presently does nothing. affects no *
  478. ;* registers! *
  479. ;* *
  480. ;************************************************************************
  481. public re_init
  482. re_init proc far
  483. assume ds:nothing,es:nothing
  484. ret
  485. re_init endp
  486. ;SR; WIN386 support
  487. ; WIN386 instance data structure
  488. ;
  489. ;
  490. ; Here is a Win386 startup info structure which we set up and to which
  491. ; we return a pointer when Win386 initializes.
  492. ;
  493. public Win386_SI, SI_Version, SI_Next
  494. Win386_SI label byte ; Startup Info for Win386
  495. SI_Version db 3, 0 ; for Win386 3.0
  496. SI_Next dd ? ; pointer to next info structure
  497. dd 0 ; a field we don't need
  498. dd 0 ; another field we don't need
  499. SI_Instance dw Instance_Table, Bios_Data ; far pointer to instance table
  500. ;
  501. ; This table gives Win386 the instance data in the BIOS and ROM-BIOS data
  502. ; areas. Note that the address and size of the hardware stacks must
  503. ; be calculated and inserted at boot time.
  504. ;
  505. Instance_Table label dword
  506. dw 00H, 50H ; print screen status...
  507. dw 02 ; ...2 bytes
  508. dw 0Eh, 50H ; ROM Basic data...
  509. dw 14H ; ...14H bytes
  510. dw ALTAH, Bios_Data ; a con device buffer...
  511. dw 01 ; ... 1 byte
  512. IF STACKSW
  513. public NextStack
  514. NextStack label dword
  515. ; NOTE: If stacks are disabled by STACKS=0,0, the following
  516. ; instance items WILL NOT be filled in by SYSINIT.
  517. ; That's just fine as long as these are the last items
  518. ; in the instance list since the first item is initialized
  519. ; to 0000 at load time.
  520. dw 0, 0 ; pointer to next stack to be used...
  521. dw 02 ; ...2 bytes
  522. ; The next item in the instance table must be filled in at sysinit time
  523. public IT_StackLoc, IT_StackSize
  524. IT_StackLoc dd ? ; location of hardware stacks
  525. IT_StackSize dw ? ; size of hardware stacks
  526. ENDIF
  527. dd 0 ; terminate the instance table
  528. ;SR;
  529. ; Flag to indicate whether Win386 is running or not
  530. ;
  531. public IsWin386
  532. IsWin386 db 0
  533. ;
  534. ;This routine was originally in BIOS_CODE but this causes a lot of problems
  535. ;when we call it including checking of A20. The code being only about
  536. ;30 bytes, we might as well put it in BIOS_DATA
  537. ;
  538. PUBLIC V86_Crit_SetFocus
  539. V86_Crit_SetFocus PROC FAR
  540. push di
  541. push es
  542. push bx
  543. push ax
  544. xor di,di
  545. mov es,di
  546. mov bx,0015h ;Device ID of DOSMGR device
  547. mov ax,1684h ;Get API entry point
  548. int 2fh
  549. mov ax,es
  550. or ax,di
  551. jz Skip
  552. ;
  553. ;Here, es:di is address of API routine. Set up stack frame to simulate a call
  554. ;
  555. push cs ;push return segment
  556. mov ax,OFFSET Skip
  557. push ax ;push return offset
  558. push es
  559. push di ;API far call address
  560. mov ax,1 ;SetFocus function number
  561. retf ;do the call
  562. Skip:
  563. pop ax
  564. pop bx
  565. pop es
  566. pop di
  567. ret
  568. V86_Crit_SetFocus ENDP
  569. ;
  570. ;End WIN386 support
  571. ;
  572. public FreeHMAPtr
  573. public MoveDOSIntoHMA
  574. FreeHMAPtr dw -1
  575. MoveDOSIntoHMA dd sysinitseg:FTryToMovDOSHi
  576. ;SR;
  577. ; A communication block has been setup between the DOS and the BIOS. All
  578. ;the data starting from SysinitPresent will be part of the data block.
  579. ;Right now, this is the only data being communicated. It can be expanded
  580. ;later to add more stuff
  581. ;
  582. public SysinitPresent
  583. public DemInfoFlag
  584. SysinitPresent db 0
  585. DemInfoFlag db 0
  586. ; this will be the end of the BIOS data if no hard disks are in system
  587. public endBIOSData
  588. endBIOSData label byte
  589. Bios_Data ends
  590. ;
  591. ; okay. so much for Bios_Data. Now let's put our device driver
  592. ; entry stuff up into Bios_Code.
  593. Bios_Code segment
  594. assume cs:Bios_Code
  595. ; ORG a bit past zero to leave room for running in HMA...
  596. org 30h
  597. public BCode_start
  598. BCode_start:
  599. ; device driver entry point tables
  600. extrn con_table:near
  601. extrn tim_table:near
  602. extrn prn_table:near
  603. extrn aux_table:near
  604. extrn i2f_handler:far
  605. public Bios_Data_Word
  606. Bios_Data_Word dw Bios_Data
  607. ;************************************************************************
  608. ;* *
  609. ;* seg_reinit is called with ax = our new code segment value, *
  610. ;* trashes di, cx, es *
  611. ;* *
  612. ;* cas -- should be made disposable! *
  613. ;* *
  614. ;************************************************************************
  615. public seg_reinit
  616. seg_reinit proc far
  617. assume ds:nothing,es:nothing
  618. mov es,Bios_Data_Word
  619. assume es:Bios_Data
  620. mov di,2+offset cdev
  621. mov cx,((offset end_BC_entries) - (offset cdev))/4
  622. seg_reinit_1:
  623. stosw ; modify Bios_Code entry points
  624. inc di
  625. inc di
  626. loop seg_reinit_1
  627. ret
  628. seg_reinit endp
  629. ;************************************************************************
  630. ;* *
  631. ;* chardev_entry - main device driver dispatch routine *
  632. ;* called with a dummy parameter block on the stack *
  633. ;* dw dispatch_table, dw prn/aux numbers (optional) *
  634. ;* *
  635. ;* will eventually take care of doing the transitions in *
  636. ;* out of Bios_Code *
  637. ;* *
  638. ;************************************************************************
  639. chardev_entry proc far
  640. assume ds:nothing,es:nothing
  641. push si
  642. push ax
  643. push cx
  644. push dx
  645. push di
  646. push bp
  647. push ds
  648. push es
  649. push bx
  650. mov bp,sp ; point to stack frame
  651. mov si,18[bp] ; get return address (dispatch table)
  652. mov ds,Bios_Data_Word ; load ds: -> Bios_Data
  653. assume ds:Bios_Data
  654. mov ax,word ptr 2[si] ; get the device number if present
  655. mov byte ptr [auxnum],al
  656. mov byte ptr [printdev],ah
  657. mov si,word ptr [si] ; point to the device dispatch table
  658. les bx,[ptrsav] ;get pointer to i/o packet
  659. mov al,byte ptr es:[bx].unit ;al = unit code
  660. mov ah,byte ptr es:[bx].media ;ah = media descrip
  661. mov cx,word ptr es:[bx].count ;cx = count
  662. mov dx,word ptr es:[bx].start ;dx = start sector
  663. xchg di,ax
  664. mov al,byte ptr es:[bx].cmd
  665. cmp al,cs:[si]
  666. jae command_error
  667. cbw ; note that al <= 15 means ok
  668. shl ax,1
  669. add si,ax
  670. xchg ax,di
  671. les di,dword ptr es:[bx].trans
  672. cld ; ***** always clear direction
  673. call cs:word ptr [si+1] ;go do command
  674. assume ds:nothing
  675. jc already_got_ah_status ; if function returned status, don't
  676. mov ah,1 ; load with normal completion
  677. already_got_ah_status:
  678. mov ds,Bios_Data_Word ; cas///// note: shouldn't be needed!
  679. assume ds:Bios_Data
  680. lds bx,[ptrsav]
  681. assume ds:nothing
  682. mov word ptr [bx].status,ax ;mark operation complete
  683. pop bx
  684. pop es
  685. pop ds
  686. pop bp
  687. pop di
  688. pop dx
  689. pop cx
  690. pop ax
  691. pop si
  692. add sp,2 ; get rid of fake return address
  693. chardev_entry endp ; fall through into bc_retf
  694. public bc_retf
  695. bc_retf proc far
  696. assume ds:nothing,es:nothing
  697. ret
  698. bc_retf endp
  699. command_error:
  700. call bc_cmderr
  701. jmp short already_got_ah_status
  702. ;
  703. ;----------------------------------------------------------------------------
  704. ; The following piece of hack is for supporting CP/M compatibility
  705. ; Basically at offset 5 we have a far call into 0:c0. But this does not call
  706. ; 0:c0 directly instead it call f01d:fef0, because it needs to support 'lhld 6'
  707. ; The following hack has to reside at ffff:d0 (= f01d:fef0) if BIOS is loaded
  708. ; high.
  709. ;----------------------------------------------------------------------------
  710. ; BUGBUG sudeepb 21-May-1991 ; We can save these 30 bytes by moving
  711. ; off_d0 to right place.
  712. db 1fh dup (?) ; pad to bring offset to 0d0h
  713. if2
  714. if ( offset off_d0 - 0d0h )
  715. %out CP/M compatibilty broken!!!
  716. %out Please re-pos hack to ffff:d0
  717. endif
  718. endif
  719. public off_d0
  720. off_d0 db 5 dup (?) ; 5 bytes from 0:c0 will be copied onto here
  721. ; which is the CP/M call 5 entry point
  722. .errnz (offset off_d0 - 0d0h)
  723. ;----------------------------------------------------------
  724. ;
  725. ; exit - all routines return through this path
  726. ;
  727. public bc_cmderr
  728. bc_cmderr:
  729. mov al,3 ;unknown command error
  730. ; now zero the count field by subtracting its current value,
  731. ; which is still in cx, from itself.
  732. ; subtract the number of i/o's NOT YET COMPLETED from total
  733. ; in order to return the number actually complete
  734. public bc_err_cnt
  735. bc_err_cnt:
  736. assume ds:Bios_Data
  737. les bx,[ptrsav]
  738. assume es:nothing
  739. sub es:word ptr [bx].count,cx;# of successful i/o's
  740. mov ah,81h ;mark error return
  741. stc ; indicate abnormal end
  742. ret
  743. Bios_Code ends
  744. ; the last real segment is sysinitseg
  745. sysinitseg segment
  746. assume cs:sysinitseg
  747. extrn FTryToMovDOSHi:far
  748. public SI_start
  749. SI_start:
  750. sysinitseg ends
  751. end