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.

2056 lines
44 KiB

  1. ;++
  2. ;
  3. ; Module name
  4. ;
  5. ; exp.asm
  6. ;
  7. ; Author
  8. ;
  9. ; Thomas Parslow (tomp) Feb-26-91
  10. ;
  11. ; Description
  12. ;
  13. ; Entry points exported to OS loader by SU module. Exported
  14. ; routines provide basic machine dependent i/o funtions needed
  15. ; by the OS loader. Providing these routines decouples the
  16. ; OS loader from the h/w. Note that the OS loader will
  17. ; refer to these exported routines as the "external services".
  18. ;
  19. ;
  20. ; Exported Procedures
  21. ;
  22. ; RebootProcessor - Reboots the machine
  23. ; GetSector - Read one or more sectors from the boot device.
  24. ; PutChar - Puts a character on the video display.
  25. ; GetKey - Gets a key from the keyboard
  26. ; GetKeyEx - Gets an extended key from the keyboard or the comport (headless)
  27. ; GetCounter - Reads the Tick Counter
  28. ; Reboot - Transfers control to a loaded boot sector.
  29. ; HardwareCursor - set position of hardware cursor
  30. ; GetDateTime - gets date and time
  31. ; ComPort - int14 functions
  32. ; GetStallCount - calculates processor stall count
  33. ;
  34. ;
  35. ; Notes
  36. ;
  37. ; When adding a new exported routine note that you must manually add the
  38. ; entry's name to the BootRecord in "sudata.asm".
  39. ;
  40. ;--
  41. include su.inc
  42. include macro.inc
  43. DISK_TABLE_VECTOR equ 01Eh * 4
  44. _TEXT segment para use16 public 'CODE'
  45. ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP
  46. .386p
  47. extrn _DiskBaseTable:near
  48. extrn _RomDiskBasePointer:near
  49. extrn _EddsAddressPacket:near
  50. extrn _NetPcRomEntry:near
  51. extrn _EnableA20:near
  52. ;++
  53. ;
  54. ; Exported Name:
  55. ;
  56. ; RebootProcessor
  57. ;
  58. ; Arguments:
  59. ;
  60. ; None
  61. ;
  62. ; Description:
  63. ;
  64. ; Reboot the processor using INT 19h
  65. ;
  66. ;
  67. ;
  68. ;--
  69. ;
  70. ; ExportEntry takes us from a 32bit cs to a 16bit cs, inits 16bit stack
  71. ; and ds segments and saves the callers esp and ebp.
  72. ;
  73. ;--
  74. EXPORT_ENTRY_MACRO RebootProcessor
  75. ;
  76. ; Switch to real mode so we can take interrupts
  77. ;
  78. ENTER_REALMODE_MACRO
  79. ;
  80. ; int 19h doesn't do what you would expect on BIOS Boot Specification machines.
  81. ; It either goes on to the next boot device or goes back to the first boot
  82. ; device. In both cases, it does not properly reset the machine. So we write
  83. ; to the keyboard port instead (as does HalpReboot).
  84. ;
  85. mov ax, 040h
  86. mov ds, ax
  87. mov word ptr ds:[72h], 1234h ; set location 472 to 1234 to indicate warm reboot
  88. mov al, 0feh
  89. out 64h, al ; write to keyboard port to cause reboot
  90. ;
  91. ; Loop forever and wait to ctrl-alt-del (should never get here)
  92. ;
  93. WAIT_FOREVER_MACRO
  94. ;EXPORT_EXIT_MACRO
  95. ;++
  96. ;
  97. ; Name:
  98. ;
  99. ; GetSector
  100. ;
  101. ; Description:
  102. ;
  103. ; Reads the requested number of sectors from the specified drive into
  104. ; the specified buffer.
  105. ;
  106. ; Arguments:
  107. ;
  108. ; ULONG Virtual address into which to read data
  109. ; ULONG Number of sectors to read
  110. ; ULONG Physical sector number
  111. ; ULONG Drive Number
  112. ; ULONG Function Number
  113. ; TOS -> ULONG Flat return address (must be used with KeCodeSelector)
  114. ;
  115. ;--
  116. EXPORT_ENTRY_MACRO GetSector
  117. ;
  118. ; Move the arguments from the caller's 32bit stack to the SU module's
  119. ; 16bit stack.
  120. ;
  121. MAKE_STACK_FRAME_MACRO <GetSectorFrame>, ebx
  122. ;
  123. ; Go into real mode. We still have the same stack and sp
  124. ; but we'll be executing in realmode.
  125. ;
  126. ENTER_REALMODE_MACRO
  127. ;
  128. ; Get the requested sectors. Arguments on realmode stack
  129. ; Make (bp) point to the bottom of the argument frame.
  130. ;
  131. push bp
  132. mov bp,sp
  133. add bp,2
  134. ;
  135. ; Put the buffer pointer into es:bx. Note that and buffer
  136. ; addresses passed to this routine MUST be in the lower one
  137. ; megabyte of memory to be addressable in real mode.
  138. ;
  139. mov eax,[bp].BufferPointer
  140. mov bx,ax
  141. and bx,0fh
  142. shr eax,4
  143. mov es,ax
  144. ;
  145. ; Place the upper 2 bits of the 10bit track/cylinder number
  146. ; into the uppper 2 bits of the SectorNumber as reguired by
  147. ; the bios.
  148. ;
  149. mov cx,word ptr [bp].TrackNumber
  150. xchg ch,cl
  151. shl cl,6
  152. add cl,byte ptr [bp].SectorNumber
  153. ;
  154. ; Get the rest of the arguments
  155. ;
  156. mov ah,byte ptr [bp].FunctionNumber
  157. mov al,byte ptr [bp].NumberOfSectors
  158. mov dh,byte ptr [bp].HeadNumber
  159. mov dl,byte ptr [bp].DriveNumber
  160. ;
  161. ; Check to see if we are trying to reset/read/write/verify off the second
  162. ; floppy drive. If so, we need to go change the disk-base vector.
  163. ;
  164. cmp dl,1
  165. jne gs3
  166. cmp ah,4
  167. jg gs3
  168. cmp ah,0
  169. je gs1
  170. cmp ah,2
  171. jl gs3
  172. gs1:
  173. ;
  174. ; We need to point the BIOS disk-table vector to our own table for this
  175. ; drive.
  176. ;
  177. push es
  178. push bx
  179. push di
  180. push 0
  181. pop es
  182. mov di, offset DGROUP:_RomDiskBasePointer
  183. mov bx,es:[DISK_TABLE_VECTOR]
  184. mov [di],bx
  185. mov bx,es:[DISK_TABLE_VECTOR+2]
  186. mov [di+2],bx
  187. mov bx,offset DGROUP:_DiskBaseTable
  188. mov es:[DISK_TABLE_VECTOR],bx
  189. mov bx,ds
  190. mov es:[DISK_TABLE_VECTOR+2],bx
  191. pop di
  192. pop bx
  193. pop es
  194. int BIOS_DISK_INTERRUPT
  195. push es
  196. push bx
  197. push di
  198. push 0
  199. pop es
  200. mov di, offset DGROUP:_RomDiskBasePointer
  201. mov bx, [di]
  202. mov es:[DISK_TABLE_VECTOR],bx
  203. mov bx, [di+2]
  204. mov es:[DISK_TABLE_VECTOR+2],bx
  205. pop di
  206. pop bx
  207. pop es
  208. jc gs5
  209. xor eax,eax
  210. jmp short gs5
  211. gs3:
  212. ;
  213. ; Call the bios to read the sector now
  214. ;
  215. if 0
  216. push ax
  217. push dx
  218. push cx
  219. push bx
  220. push es
  221. extrn _DisplayArgs:near
  222. call _DisplayArgs
  223. pop es
  224. pop bx
  225. pop cx
  226. pop dx
  227. pop ax
  228. endif
  229. int BIOS_DISK_INTERRUPT
  230. jc gs5
  231. ;
  232. ; Carry wasn't set so we have no error and need to "clean" eax of
  233. ; any garbage that may have been left in it.
  234. ;
  235. xor eax,eax
  236. gs5:
  237. if 0
  238. push ax
  239. push dx
  240. push cx
  241. push bx
  242. push es
  243. extrn _DisplayArgs:near
  244. call _DisplayArgs
  245. pop es
  246. pop bx
  247. pop cx
  248. pop dx
  249. pop ax
  250. endif
  251. ;
  252. ; Mask-off any garbage that my have been left in the upper
  253. ; 16bits of eax.
  254. ;
  255. and eax,0000ffffh
  256. ;
  257. ; Restore bp and remove stack-frame from stack
  258. ;
  259. pop bp
  260. REMOVE_STACK_FRAME_MACRO <GetSectorFrame>
  261. ;
  262. ; Save return code on 16bit stack
  263. ; Re-enable protect-mode and paging.
  264. ;
  265. ; move cx into high 16-bits of ecx, and dx into cx. This is so the loader
  266. ; can get at interesting values in dx, even though edx gets munged by the
  267. ; random real-mode macros.
  268. shl ecx, 16
  269. mov cx,dx
  270. push eax
  271. RE_ENABLE_PAGING_MACRO
  272. pop eax
  273. ;
  274. ; Return to caller and the 32bit universe.
  275. ;
  276. EXPORT_EXIT_MACRO
  277. ;++
  278. ;
  279. ; Name:
  280. ;
  281. ; GetEddsSector
  282. ;
  283. ; Description:
  284. ;
  285. ; Reads the requested number of sectors from the specified drive into
  286. ; the specified buffer based on the Phoenix Enhanced Disk Drive Spec.
  287. ;
  288. ; Arguments:
  289. ;
  290. ; ULONG xint13 function number (42 = read, 43 = write)
  291. ; ULONG Virtual address into which to read data
  292. ; ULONG Number of logical blocks to read (word)
  293. ; ULONG Logical block number (High dword)
  294. ; ULONG Logical block number (Low dword)
  295. ; ULONG Drive Number (byte)
  296. ; TOS -> ULONG Flat return address (must be used with KeCodeSelector)
  297. ;
  298. ;--
  299. EXPORT_ENTRY_MACRO GetEddsSector
  300. ;
  301. ; Move the arguments from the caller's 32bit stack to the SU module's
  302. ; 16bit stack.
  303. ;
  304. MAKE_STACK_FRAME_MACRO <GetEddsSectorFrame>, ebx
  305. ;
  306. ; Go into real mode. We still have the same stack and sp
  307. ; but we'll be executing in realmode.
  308. ;
  309. ENTER_REALMODE_MACRO
  310. ;
  311. ; Get the requested sectors. Arguments on realmode stack
  312. ; Make (bp) point to the bottom of the argument frame.
  313. ;
  314. push bp
  315. mov bp,sp
  316. add bp,2
  317. push ds
  318. push si
  319. push bx
  320. ;
  321. ; Set up DS:SI -> Disk Address Packet
  322. ;
  323. push 0
  324. pop ds
  325. mov si, offset DGROUP:_EddsAddressPacket
  326. mov ds:[si],word ptr 10h ; Packet size = 10h, plus reserved byte
  327. mov ax,word ptr [bp].NumberOfBlocks
  328. mov ds:[si][2],ax ; Num blocks to transfer
  329. mov eax,[bp].BufPointer
  330. mov bx,ax
  331. and bx,0fh
  332. mov ds:[si][4],bx ; Transfer buffer address (low word=offset)
  333. shr eax,4
  334. mov ds:[si][6],ax ; Transfer buffer address (high word=segment)
  335. mov eax,[bp].LBNLow
  336. mov ds:[si][8],eax ; Starting logical block number (low dword)
  337. mov eax,[bp].LBNHigh
  338. mov ds:[si][12],eax ; Starting logical block number (high dword)
  339. ;
  340. ; Call the bios to read the sector now (DS:SI -> Disk address packet)
  341. ;
  342. mov ah,byte ptr [bp].FunctionNum ; function
  343. xor al,al ; force verify on write off
  344. mov dl,byte ptr [bp].DriveNum ; DL = drive number
  345. int BIOS_DISK_INTERRUPT
  346. jc geserror1
  347. ;
  348. ; Carry wasn't set so we have no error and need to "clean" eax of
  349. ; any garbage that may have been left in it.
  350. ;
  351. xor eax,eax
  352. geserror1:
  353. ;
  354. ; Mask-off any garbage that my have been left in the upper
  355. ; 16bits of eax.
  356. ;
  357. and eax,0000ffffh
  358. pop bx
  359. pop si
  360. pop ds
  361. ;
  362. ; Restore bp and remove stack-frame from stack
  363. ;
  364. pop bp
  365. REMOVE_STACK_FRAME_MACRO <GetEddsSectorFrame>
  366. ;
  367. ; Save return code on 16bit stack
  368. ; Re-enable protect-mode and paging.
  369. ;
  370. ; move cx into high 16-bits of ecx, and dx into cx. This is so the loader
  371. ; can get at interesting values in dx, even though edx gets munged by the
  372. ; random real-mode macros.
  373. shl ecx, 16
  374. mov cx,dx
  375. push eax
  376. RE_ENABLE_PAGING_MACRO
  377. pop eax
  378. ;
  379. ; Return to caller and the 32bit universe.
  380. ;
  381. EXPORT_EXIT_MACRO
  382. ;++
  383. ;
  384. ; Routine Name:
  385. ;
  386. ; GetKey
  387. ;
  388. ; Description:
  389. ;
  390. ; Checks the keyboard to see if a key is available.
  391. ;
  392. ; Arguments:
  393. ;
  394. ; None.
  395. ;
  396. ; Returns:
  397. ;
  398. ; If no key is available, returns 0
  399. ;
  400. ; If ASCII character is available, LSB 0 is ASCII code
  401. ; LSB 1 is keyboard scan code
  402. ; If extended character is available, LSB 0 is extended ASCII code
  403. ; LSB 1 is keyboard scan code
  404. ;
  405. ;--
  406. EXPORT_ENTRY_MACRO GetKey
  407. ;
  408. ; Go into real mode. We still have the same stack and sp
  409. ; but we'll be executing in real mode.
  410. ;
  411. ENTER_REALMODE_MACRO
  412. ;
  413. ; Set up registers to call BIOS and check to see if a key is available
  414. ;
  415. mov ax,0100h
  416. int BIOS_KEYBOARD_INTERRUPT
  417. jnz GkKeyAvail
  418. mov eax, 0
  419. jmp GkDone
  420. GkKeyAvail:
  421. ;
  422. ; Now we call BIOS again, this time to get the key from the keyboard buffer
  423. ;
  424. mov ax,0h
  425. int BIOS_KEYBOARD_INTERRUPT
  426. and eax,0000ffffh
  427. ;
  428. ; Save return code on 16bit stack
  429. ; Re-enable protect mode and paging
  430. ;
  431. GkDone:
  432. push eax
  433. RE_ENABLE_PAGING_MACRO
  434. pop eax
  435. ;
  436. ; Return to caller and the 32-bit universe
  437. ;
  438. EXPORT_EXIT_MACRO
  439. ;++
  440. ;
  441. ; Routine Name:
  442. ;
  443. ; GetKeyEx
  444. ;
  445. ; Description:
  446. ;
  447. ; Checks the keyboard to see if a (possibly extended) key is available.
  448. ;
  449. ; Arguments:
  450. ;
  451. ; None.
  452. ;
  453. ; Returns:
  454. ;
  455. ; If no key is available, returns 0
  456. ;
  457. ; If ASCII character is available, LSB 0 is ASCII code
  458. ; LSB 1 is keyboard scan code
  459. ; If extended character is available, LSB 0 is extended ASCII code
  460. ; LSB 1 is keyboard scan code
  461. ;
  462. ;--
  463. public GetKeyEx
  464. GetKeyEx proc near
  465. IFDEF HEADLESS_SRV
  466. ;
  467. ; Give priority to Com I/O
  468. ;
  469. push edi
  470. call GetCounterReal ; get starting RTC value
  471. mov edi,eax ; calculate RTC value for now + 2 secs.
  472. add edi,37 ; (RTC clicks 18.2 times per second)
  473. TopComPortRead:
  474. mov ah, 03h ; Query status
  475. mov al, 0
  476. mov dx, HEADLESS_COMPORT ; Com port
  477. int 14h
  478. mov bh, ah ; There seems to be a problem where the transmitter shift
  479. and ah, 40h ; register status bit gets stuck on. When this is
  480. jz XmitterOk1 ; the case, it blocks all other status bits. To resolve it
  481. ; we write out a NULL character
  482. mov ah, 01h ; Write character
  483. mov al, 0 ; NULL character
  484. mov dx, HEADLESS_COMPORT ; Com port
  485. int 14h
  486. call GetCounterReal ; get current RTC value
  487. cmp eax, edi ; is it higher than end value?
  488. jb TopComPortRead ; loop if current < end
  489. jmp NoComPortKey
  490. XmitterOk1:
  491. mov ah, bh
  492. and ah, 1 ; Data ready
  493. jz NoComPortKey
  494. mov ah, 02h ; Read character
  495. mov al, 0
  496. mov dx, HEADLESS_COMPORT ; Com port
  497. int 14h
  498. cmp al, 1bh ; If this is the ESC character, process Function key (if any)
  499. jne ExitComPortRead
  500. call GetCounterReal ; get starting RTC value
  501. mov edi,eax ; calculate RTC value for now + 2 secs.
  502. add edi,37 ; (RTC clicks 18.2 times per second)
  503. EscLoop:
  504. mov ah, 03h ; Query status
  505. mov al, 0
  506. mov dx, HEADLESS_COMPORT ; Com port
  507. int 14h
  508. mov bh, ah ; There seems to be a problem where the transmitter shift
  509. and ah, 40h ; register status bit gets stuck on. When this is
  510. jz XmitterOk2 ; the case, it blocks all other status bits. To resolve it
  511. ; we write out a NULL character
  512. mov ah, 01h ; Write character
  513. mov al, 0 ; NULL character
  514. mov dx, HEADLESS_COMPORT ; Com port
  515. int 14h
  516. jmp EscLoop
  517. XMitterOk2:
  518. mov ah, bh
  519. and ah, 1 ; Data ready
  520. jnz NextKeyPressed
  521. call GetCounterReal ; get current RTC value
  522. cmp eax, edi ; is it higher than end value?
  523. jb EscLoop ; loop if current < end
  524. jmp ComPortEscapeKey
  525. NextKeyPressed:
  526. mov ah, 02h ; Read character
  527. mov al, 0
  528. mov dx, HEADLESS_COMPORT ; Com port
  529. int 14h
  530. cmp al, 40h ; '@' key
  531. jne CheckMinusSign
  532. mov eax, 0DA00h ; F12 key
  533. jmp GkxDone
  534. CheckMinusSign:
  535. cmp al, 21h ; '!' key
  536. jne CheckNumbers
  537. mov eax, 0D900h ; F11 key
  538. jmp GkxDone
  539. CheckNumbers:
  540. cmp al, 30h
  541. jl ComPortEscapeKey
  542. cmp al, 39h
  543. jg ComPortEscapeKey
  544. add al, 10
  545. mov ah, 0
  546. shl eax, 8
  547. cmp eax, 3a00h ; Check for miscomputation on F10 key (aka Esc-0)
  548. jne GkxDone
  549. mov eax, 4400h
  550. jmp GkxDone
  551. ComPortEscapeKey:
  552. mov eax, 011bh ; ESCAPE key
  553. jmp GkxDone
  554. ExitComPortRead:
  555. movzx edx, al
  556. mov eax, edx
  557. jmp GkxDone
  558. NoComPortKey:
  559. endif
  560. ;
  561. ; Set up registers to call BIOS and check to see if a key is available
  562. ;
  563. mov ax,01100h
  564. int BIOS_KEYBOARD_INTERRUPT
  565. jnz GkxKeyAvail
  566. mov eax, 0
  567. jmp GkxDone
  568. GkxKeyAvail:
  569. ;
  570. ; Now we call BIOS again, this time to get the key from the keyboard buffer
  571. ;
  572. mov ax,01000h
  573. int BIOS_KEYBOARD_INTERRUPT
  574. and eax,0000ffffh
  575. GkxDone:
  576. IFDEF HEADLESS_SRV
  577. pop edi
  578. endif
  579. ret
  580. GetKeyEx endp
  581. ;++
  582. ;
  583. ; Routine Name:
  584. ;
  585. ; GetCounter
  586. ;
  587. ; Description:
  588. ;
  589. ; Reads the tick counter (incremented 18.2 times per second)
  590. ;
  591. ; Arguments:
  592. ;
  593. ; None
  594. ;
  595. ; Returns:
  596. ;
  597. ; The current value of the tick counter
  598. ;
  599. ;--
  600. EXPORT_ENTRY_MACRO GetCounter
  601. ;
  602. ; Go into real mode.
  603. ;
  604. ENTER_REALMODE_MACRO
  605. call GetCounterReal
  606. push eax
  607. RE_ENABLE_PAGING_MACRO
  608. pop eax
  609. EXPORT_EXIT_MACRO
  610. public GetCounterReal
  611. GetCounterReal proc near
  612. mov ah,0
  613. int 01ah
  614. mov ax,cx ; high word of count
  615. shl eax,16
  616. mov ax,dx ; low word of count
  617. ret
  618. GetCounterReal endp
  619. ;++
  620. ;
  621. ; Routine Name:
  622. ;
  623. ; Reboot
  624. ;
  625. ; Description:
  626. ;
  627. ; Switches to real-mode and transfers control to a loaded boot sector
  628. ;
  629. ; Arguments:
  630. ;
  631. ; unsigned BootType
  632. ; 0 = FAT. Just jump to 0:7c00.
  633. ; 1 = HPFS. Assumes boot code and super+spare areas (20 sectors)
  634. ; are already loaded at 0xd000; jumps to d00:200.
  635. ; 2 = NTFS. Assumes boot code is loaded (16 sectors) at 0xd000.
  636. ; Jumps to d00:256.
  637. ; 3 = SDI. Boot from downloaded SDI image. Assumes boot code
  638. ; (startrom.com) has been copied from the SDI image to
  639. ; 0x7c00. Changes low byte of argument from 0x03 to 0x41
  640. ; to tell startrom that this is an SDI boot. The upper 3
  641. ; bytes of the argument are the upper 3 bytes of the
  642. ; page-aligned address at which the SDI image was loaded.
  643. ;
  644. ; Returns:
  645. ; Does not return
  646. ;
  647. ; Environment:
  648. ;
  649. ; Boot sector has been loaded at 7C00
  650. ;--
  651. EXPORT_ENTRY_MACRO Reboot
  652. ;
  653. ; Move the arguments from the caller's 32bit stack to the SU module's
  654. ; 16bit stack.
  655. ;
  656. MAKE_STACK_FRAME_MACRO <RebootFrame>, ebx
  657. ;
  658. ; Go into real mode.
  659. ;
  660. ENTER_REALMODE_MACRO
  661. ;
  662. ; Get the BootType argument. Arguments on realmode stack
  663. ; Make (bp) point to the bottom of the argument frame.
  664. ;
  665. push bp
  666. mov bp,sp
  667. add bp,2
  668. mov edx, [bp].BootType
  669. ;
  670. ; Zero out the firmware heaps, 3000:0000 - 4000:ffff.
  671. ;
  672. xor eax,eax ; prepare for stosd
  673. mov bx,3000h
  674. mov es,bx
  675. mov di,ax ; es:di = physical address 30000
  676. mov cx,4000h ; cx = rep count, # dwords in 64K
  677. cld
  678. rep stosd
  679. mov cx,4000h ; rep count
  680. mov es,cx ; es:di = physical address 40000
  681. rep stosd
  682. ;
  683. ; Disable the A20 line. Some things (like EMM386 and OS/2 on PS/2 machines)
  684. ; hiccup or die if we don't do this.
  685. ;
  686. extrn _DisableA20:near
  687. call _DisableA20
  688. ;
  689. ; Put the video adapter back in 80x25 mode
  690. ;
  691. push edx
  692. mov ax, 0003h
  693. int 010h
  694. pop edx
  695. ;
  696. ; Reset all the segment registers and setup the original stack
  697. ;
  698. mov ax,0
  699. mov ds,ax
  700. mov es,ax
  701. mov fs,ax
  702. mov gs,ax
  703. mov ax,30
  704. mov ss,ax
  705. mov esp,0100h
  706. mov ebp,0
  707. mov esi,0
  708. mov edi,0
  709. ;
  710. ; Check for FAT boot or SDI boot and jump as appropriate.
  711. ;
  712. test dx,-1
  713. jz FatBoot
  714. cmp dl,3
  715. je SdiBoot
  716. ;
  717. ; Setup the registers the way the second sector of the OS/2 HPFS boot code
  718. ; expects them. We skip the first sector entirely, as that just loads in
  719. ; the rest of the sectors. Since the rest of the sectors are ours and not
  720. ; OS/2's, this would cause great distress.
  721. ;
  722. mov ax,07c0h
  723. mov ds, ax
  724. mov ax, 0d00h
  725. mov es, ax
  726. cli
  727. xor ax,ax
  728. mov ss,ax
  729. mov sp, 07c00h
  730. sti
  731. push 0d00h
  732. push 0256h
  733. jmp RebootDoit
  734. ;
  735. ; SDI boot. Set up to jump to startrom at 0:7c00. Change the 0x03 in DL
  736. ; to 0x41 to indicate SDI boot. Leave the upper three bytes of EDX as is.
  737. ;
  738. SdiBoot:
  739. push 0
  740. push 07c00h
  741. mov dl,041h
  742. jmp RebootDoit
  743. ;
  744. ; FAT boot. Set up to jump to startup at 0:7c00. Put 0x80 in DX to indicate
  745. ; the boot drive.
  746. ;
  747. FatBoot:
  748. push 0 ; set up for branch to boot sector
  749. push 07c00h
  750. mov dx,080h
  751. ;
  752. ; And away we go!
  753. ;
  754. RebootDoit:
  755. retf
  756. RE_ENABLE_PAGING_MACRO
  757. REMOVE_STACK_FRAME_MACRO <RebootFrame>
  758. EXPORT_EXIT_MACRO
  759. ;++
  760. ;
  761. ; Name:
  762. ;
  763. ; HardwareCursor
  764. ;
  765. ; Description:
  766. ;
  767. ; Positions the hardware cursor and performs other display stuff.
  768. ;
  769. ; Arguments:
  770. ;
  771. ; ULONG Y coord (0 based)
  772. ; ULONG X coord (0 based)
  773. ; TOS -> ULONG Flat return address (must be used with KeCodeSelector)
  774. ;
  775. ; If X = 0x80000000, then Y contains values that get placed into
  776. ; ax (low word of Y) and bx (hi word of y).
  777. ; Otherwise X,Y = coors for cursor
  778. ;
  779. ;
  780. ;--
  781. EXPORT_ENTRY_MACRO HardwareCursor
  782. ;
  783. ; Move the arguments from the caller's 32bit stack to the SU module's
  784. ; 16bit stack.
  785. ;
  786. MAKE_STACK_FRAME_MACRO <HardwareCursorFrame>, ebx
  787. ;
  788. ; Go into real mode. We still have the same stack and sp
  789. ; but we'll be executing in realmode.
  790. ;
  791. ENTER_REALMODE_MACRO
  792. ;
  793. ; Get the requested sectors. Arguments on realmode stack
  794. ; Make (bp) point to the bottom of the argument frame.
  795. ;
  796. push bp
  797. mov bp,sp
  798. add bp,2
  799. ;
  800. ; Put the row (y coord) in dh and the column (x coord) in dl.
  801. ;
  802. mov eax,[bp].YCoord
  803. mov edx,[bp].XCoord
  804. cmp edx,80000000h
  805. jne gotxy
  806. mov ebx,eax
  807. shr ebx,16
  808. jmp doint10
  809. gotxy:
  810. mov dh,al
  811. mov ah,2
  812. mov bh,0
  813. doint10:
  814. int 10h
  815. ;
  816. ; Restore bp and remove stack-frame from stack
  817. ;
  818. pop bp
  819. REMOVE_STACK_FRAME_MACRO <HardwareCursorFrame>
  820. ;
  821. ; Re-enable protect-mode and paging.
  822. ;
  823. RE_ENABLE_PAGING_MACRO
  824. ;
  825. ; Return to caller and the 32bit universe.
  826. ;
  827. EXPORT_EXIT_MACRO
  828. ;++
  829. ;
  830. ; Name:
  831. ;
  832. ; GetDateTime
  833. ;
  834. ; Description:
  835. ;
  836. ; Gets date and time
  837. ;
  838. ; Arguments:
  839. ;
  840. ; ULONG Virtual address of a dword in which to place time.
  841. ; ULONG Virtual address of a dword in which to place date.
  842. ; TOS -> ULONG Flat return address (must be used with KeCodeSelector)
  843. ;
  844. ;--
  845. BCD_TO_BIN macro
  846. xor ah,ah
  847. rol ax,4
  848. ror al,4
  849. aad
  850. endm
  851. EXPORT_ENTRY_MACRO GetDateTime
  852. ;
  853. ; Move the arguments from the caller's 32bit stack to the SU module's
  854. ; 16bit stack.
  855. ;
  856. MAKE_STACK_FRAME_MACRO <GetDateTimeFrame>, ebx
  857. ;
  858. ; Go into real mode. We still have the same stack and sp
  859. ; but we'll be executing in realmode.
  860. ;
  861. ENTER_REALMODE_MACRO
  862. ;
  863. ; Make (bp) point to the bottom of the argument frame.
  864. ;
  865. push bp
  866. mov bp,sp
  867. add bp,2
  868. ;
  869. ; Get the time
  870. ;
  871. mov ah,2
  872. int 1ah
  873. ;
  874. ; Convert BIOS time format into our format and place in caller's dword
  875. ; bits 0-5 are the second
  876. ; bits 6-11 are the minute
  877. ; bits 12-16 are the hour
  878. ;
  879. xor eax,eax
  880. mov al,dh ; BCD seconds
  881. BCD_TO_BIN
  882. movzx edx,ax
  883. mov al,cl ; BCD minutes
  884. BCD_TO_BIN
  885. shl ax,6
  886. or dx,ax
  887. mov al,ch ; BCD hours
  888. BCD_TO_BIN
  889. shl eax,12
  890. or edx,eax
  891. mov eax,[bp].TimeDword
  892. mov bx,ax
  893. and bx,0fh
  894. shr eax,4
  895. mov es,ax
  896. mov es:[bx],edx
  897. ;
  898. ; Get the date
  899. ;
  900. mov ah,4
  901. int 1ah
  902. ;
  903. ; Convert BIOS date format into our format and place in caller's dword
  904. ; bits 0-4 are the day
  905. ; bits 5-8 are the month
  906. ; bits 9-31 are the year
  907. ;
  908. xor eax,eax
  909. mov al,dl ; BCD day
  910. BCD_TO_BIN
  911. mov bl,dh
  912. movzx edx,ax
  913. mov al,bl ; BCD month
  914. BCD_TO_BIN
  915. shl ax,5
  916. or dx,ax
  917. mov al,cl ; BCD year
  918. BCD_TO_BIN
  919. mov cl,al
  920. mov al,ch ; BCD century
  921. BCD_TO_BIN
  922. mov ah,100
  923. mul ah
  924. xor ch,ch
  925. add ax,cx
  926. shl eax,9
  927. or edx,eax
  928. mov eax,[bp].DateDword
  929. mov bx,ax
  930. and bx,0fh
  931. shr eax,4
  932. mov es,ax
  933. mov es:[bx],edx
  934. ;
  935. ; Restore bp and remove stack-frame from stack
  936. ;
  937. pop bp
  938. REMOVE_STACK_FRAME_MACRO <GetDateTimeFrame>
  939. ;
  940. ; Re-enable protect-mode and paging.
  941. ;
  942. RE_ENABLE_PAGING_MACRO
  943. ;
  944. ; Return to caller and the 32bit universe.
  945. ;
  946. EXPORT_EXIT_MACRO
  947. ;++
  948. ;
  949. ; VOID
  950. ; DetectHardware (
  951. ; IN PDETECTION_RECORD DetectionRecord
  952. ; )
  953. ;
  954. ; Routine Description:
  955. ;
  956. ; This routine invokes x86 16 bit real mode detection code from
  957. ; osloader 32 bit flat mode.
  958. ;
  959. ; Arguments:
  960. ;
  961. ; DetectionRecord - Supplies a pointer to a detection record structure.
  962. ;
  963. ; Return Value:
  964. ;
  965. ; None.
  966. ;
  967. ;--
  968. EXPORT_ENTRY_MACRO DetectHardware
  969. ;
  970. ; Move the arguments from the caller's 32bit stack to the SU module's
  971. ; 16bit stack.
  972. ;
  973. MAKE_STACK_FRAME_MACRO <DetectionFrame>, ebx
  974. ;
  975. ; Go into real mode. We still have the same stack and sp
  976. ; but we'll be executing in realmode.
  977. ;
  978. ENTER_REALMODE_MACRO
  979. ;
  980. ; Call the Hardware Detection code
  981. ;
  982. push cs
  983. push offset _TEXT:DetectionDone ; push far return addr
  984. push DETECTION_ADDRESS_SEG
  985. push DETECTION_ADDRESS_OFFSET
  986. retf
  987. DetectionDone:
  988. ;
  989. ; Restore bp and remove stack-frame from stack
  990. ;
  991. REMOVE_STACK_FRAME_MACRO <DetectionFrame>
  992. ;
  993. ; No return code, so we don't save return code around page enabling code
  994. ; Re-enable protect-mode and paging.
  995. ;
  996. RE_ENABLE_PAGING_MACRO
  997. ;
  998. ; Return to caller and the 32bit universe.
  999. ;
  1000. EXPORT_EXIT_MACRO
  1001. ;++
  1002. ;
  1003. ; VOID
  1004. ; ComPort (
  1005. ; IN LONG Port,
  1006. ; IN ULONG Function,
  1007. ; IN UCHAR Arg
  1008. ; )
  1009. ;
  1010. ; Routine Description:
  1011. ;
  1012. ; Invoke int14 on com1.
  1013. ;
  1014. ; Arguments:
  1015. ;
  1016. ; Port - port # (0 = com1, etc).
  1017. ;
  1018. ; Function - int 14 function (for ah)
  1019. ;
  1020. ; Arg - arg for function (for al)
  1021. ;
  1022. ; Return Value:
  1023. ;
  1024. ; None.
  1025. ;
  1026. ;--
  1027. EXPORT_ENTRY_MACRO ComPort
  1028. ;
  1029. ; Move the arguments from the caller's 32bit stack to the SU module's
  1030. ; 16bit stack.
  1031. ;
  1032. MAKE_STACK_FRAME_MACRO <ComPortFrame>, ebx
  1033. ;
  1034. ; Go into real mode. We still have the same stack and sp
  1035. ; but we'll be executing in realmode.
  1036. ;
  1037. ENTER_REALMODE_MACRO
  1038. ;
  1039. ; Make (bp) point to the bottom of the argument frame.
  1040. ;
  1041. push bp
  1042. mov bp,sp
  1043. add bp,2
  1044. ;
  1045. ; Get args and call int14
  1046. ;
  1047. mov ah,byte ptr [bp].ComPortFunction
  1048. mov al,byte ptr [bp].ComPortArg
  1049. mov dx,word ptr [bp].ComPortPort
  1050. int 14h
  1051. ;
  1052. ; Restore bp and remove stack-frame from stack
  1053. ;
  1054. pop bp
  1055. REMOVE_STACK_FRAME_MACRO <ComPortFrame>
  1056. ;
  1057. ; No return code, so we don't save return code around page enabling code
  1058. ; Re-enable protect-mode and paging.
  1059. ;
  1060. RE_ENABLE_PAGING_MACRO
  1061. ;
  1062. ; Return to caller and the 32bit universe.
  1063. ;
  1064. EXPORT_EXIT_MACRO
  1065. ;++
  1066. ;
  1067. ; ULONG
  1068. ; GetStallCount (
  1069. ; VOID
  1070. ; )
  1071. ;
  1072. ; Routine Description:
  1073. ;
  1074. ; Calculates how many increments are required to stall for one microsecond
  1075. ;
  1076. ; The way this routine works is to set up an ISR on the BIOS vector 1C.
  1077. ; This routine will get called 18.2 times a second. The location where
  1078. ; IP will be stored when the interrupt occurs is computed and stashed in
  1079. ; the code segment. When the ISR fires, the IP on the stack is changed
  1080. ; to point to the next chunk of code to execute. So we can spin in a
  1081. ; very tight loop and automatically get blown out of the loop when the
  1082. ; interrupt occurs.
  1083. ;
  1084. ; This is all pretty sleazy, but it allows us to calibrate accurately
  1085. ; without relying on the 8259 or 8254 (just BIOS). It also does not
  1086. ; depend on whether the ISR can affect the CPU registers or not. (some
  1087. ; BIOSes, notably Olivetti, will preserve the registers for you)
  1088. ;
  1089. ; Arguments:
  1090. ;
  1091. ; None.
  1092. ;
  1093. ; Return Value:
  1094. ;
  1095. ; Number of increments required to stall for one microsecond
  1096. ;
  1097. ;--
  1098. EXPORT_ENTRY_MACRO GetStallCount
  1099. ;
  1100. ; Go into real mode.
  1101. ;
  1102. ENTER_REALMODE_MACRO
  1103. cli
  1104. push di
  1105. push si
  1106. push ds
  1107. mov ax,0
  1108. mov ds,ax
  1109. ;
  1110. ; save previous vector
  1111. ;
  1112. mov di, 01ch*4
  1113. mov cx, [di]
  1114. mov dx, [di+2]
  1115. ;
  1116. ; insert our vector
  1117. ;
  1118. mov ax, offset GscISR
  1119. mov [di], ax
  1120. push cs
  1121. pop ax
  1122. mov [di+2], ax
  1123. mov eax,0
  1124. mov ebx,0
  1125. mov si,sp
  1126. sub si,6
  1127. mov cs:savesp,si
  1128. mov cs:newip,offset GscLoop2
  1129. sti
  1130. ;
  1131. ; wait for first tick.
  1132. ;
  1133. GscLoop1:
  1134. cmp ebx,0
  1135. je GscLoop1
  1136. ;
  1137. ; start counting
  1138. ;
  1139. ;
  1140. ; We spin in this loop until the ISR fires. The ISR will munge the return
  1141. ; address on the stack to blow us out of the loop and into GscLoop3
  1142. ;
  1143. GscLoop2:
  1144. mov cs:newip,offset GscLoop4
  1145. GscLoop3:
  1146. add eax,1
  1147. jnz short GscLoop3
  1148. ;
  1149. GscLoop4:
  1150. ;
  1151. ; stop counting
  1152. ;
  1153. ;
  1154. ; replace old vector
  1155. ;
  1156. cli
  1157. mov [di],cx
  1158. mov [di+2],dx
  1159. sti
  1160. pop ds
  1161. pop si
  1162. pop di
  1163. jmp GscDone
  1164. newip dw ?
  1165. savesp dw ?
  1166. GscISR:
  1167. ;
  1168. ; blow out of loop
  1169. ;
  1170. push bp
  1171. push ax
  1172. mov bp,cs:savesp
  1173. mov ax,cs:newip
  1174. mov ss:[bp],ax
  1175. pop ax
  1176. pop bp
  1177. GscISRdone:
  1178. iret
  1179. GscDone:
  1180. mov edx, eax
  1181. mov ecx,16
  1182. shr edx,cl ; (dx:ax) = dividend
  1183. mov cx,0D6A6h ; (cx) = divisor
  1184. div cx
  1185. and eax,0ffffh
  1186. inc eax ; round loopcount up (prevent 0)
  1187. ;
  1188. ; Re-enable protect-mode and paging.
  1189. ;
  1190. push eax
  1191. RE_ENABLE_PAGING_MACRO
  1192. pop eax
  1193. ;
  1194. ; Return to caller and the 32bit universe.
  1195. ;
  1196. EXPORT_EXIT_MACRO
  1197. ;++
  1198. ;
  1199. ; Routine Name:
  1200. ;
  1201. ; InitializeDisplayForNt
  1202. ;
  1203. ; Description:
  1204. ;
  1205. ; Puts the display into 50 line mode
  1206. ;
  1207. ; Arguments:
  1208. ;
  1209. ; None
  1210. ;
  1211. ; Returns:
  1212. ;
  1213. ; None
  1214. ;
  1215. ;--
  1216. EXPORT_ENTRY_MACRO InitializeDisplayForNt
  1217. ;
  1218. ; Go into real mode.
  1219. ;
  1220. ENTER_REALMODE_MACRO
  1221. mov ax, 1112h ; Load 8x8 font
  1222. mov bx, 0
  1223. int 10h
  1224. RE_ENABLE_PAGING_MACRO
  1225. EXPORT_EXIT_MACRO
  1226. ;++
  1227. ;
  1228. ; Routine Name:
  1229. ;
  1230. ; GetMemoryDescriptor
  1231. ;
  1232. ; Description:
  1233. ;
  1234. ; Returns a memory descriptor
  1235. ;
  1236. ; Arguments:
  1237. ;
  1238. ; pointer to MemoryDescriptorFrame
  1239. ;
  1240. ; Returns:
  1241. ;
  1242. ; None
  1243. ;
  1244. ;--
  1245. EXPORT_ENTRY_MACRO GetMemoryDescriptor
  1246. ;
  1247. ; Move the arguments from the caller's 32bit stack to the SU module's
  1248. ; 16bit stack.
  1249. ;
  1250. MAKE_STACK_FRAME_MACRO <MemoryDescriptorFramePointer>, ebx
  1251. ;
  1252. ; Go into real mode. We still have the same stack and sp
  1253. ; but we'll be executing in realmode.
  1254. ;
  1255. ENTER_REALMODE_MACRO
  1256. ;
  1257. ; Make (bp) point to the bottom of the argument frame.
  1258. ;
  1259. push bp
  1260. mov bp,sp
  1261. add bp,2
  1262. mov eax,[bp].E820FramePointer
  1263. mov bp,ax
  1264. and bp,0fh
  1265. shr eax,4
  1266. mov es,ax ; (es:bp) = E820 Frame
  1267. mov ebx, es:[bp].Key
  1268. mov ecx, es:[bp].DescSize
  1269. lea di, [bp].BaseAddrLow
  1270. mov eax, 0E820h
  1271. mov edx, 'SMAP' ; (edx) = signature
  1272. INT 15h
  1273. mov es:[bp].Key, ebx ; update callers ebx
  1274. mov es:[bp].DescSize, ecx ; update callers size
  1275. sbb ecx, ecx ; ecx = -1 if carry, else 0
  1276. sub eax, 'SMAP' ; eax = 0 if signature matched
  1277. or ecx, eax
  1278. mov es:[bp].ErrorFlag, ecx ; return 0 or non-zero
  1279. ;
  1280. ; Restore bp and remove stack-frame from stack
  1281. ;
  1282. pop bp
  1283. REMOVE_STACK_FRAME_MACRO <MemoryDescriptorFramePointer>
  1284. RE_ENABLE_PAGING_MACRO
  1285. EXPORT_EXIT_MACRO
  1286. ;++
  1287. ;
  1288. ; Routine Name:
  1289. ;
  1290. ; GetElToritoStatus
  1291. ;
  1292. ; Description:
  1293. ;
  1294. ; Get El Torito Disk Emulation Status
  1295. ;
  1296. ; Arguments:
  1297. ;
  1298. ; None
  1299. ;
  1300. ; Returns:
  1301. ;
  1302. ; None
  1303. ;
  1304. ;--
  1305. EXPORT_ENTRY_MACRO GetElToritoStatus
  1306. ;
  1307. ; Move the arguments from the caller's 32bit stack to the SU module's
  1308. ; 16bit stack.
  1309. ;
  1310. MAKE_STACK_FRAME_MACRO <GetElToritoStatusFrame>, ebx
  1311. ;
  1312. ; Go into real mode. We still have the same stack and sp
  1313. ; but we'll be executing in realmode.
  1314. ;
  1315. ENTER_REALMODE_MACRO
  1316. ;
  1317. ; Make (bp) point to the bottom of the argument frame.
  1318. ;
  1319. push bp
  1320. mov bp,sp
  1321. add bp,2
  1322. push dx
  1323. push bx
  1324. push ds
  1325. push si
  1326. ;
  1327. ; Put the Specification Packet pointer into DS:SI, and the Drive
  1328. ; Number on DL. Note that and buffer
  1329. ; addresses passed to this routine MUST be in the lower one
  1330. ; megabyte of memory to be addressable in real mode.
  1331. ;
  1332. mov eax,[bp].SpecPacketPointer
  1333. mov bx,ax
  1334. and bx,0fh
  1335. mov si,bx
  1336. shr eax,4
  1337. mov ds,ax
  1338. mov dl,byte ptr [bp].ETDriveNum
  1339. mov ax,04B01h ; Function = Return Disk Emulation status
  1340. int BIOS_DISK_INTERRUPT
  1341. jc etstatuserr
  1342. ;
  1343. ; Carry wasn't set so we have no error and need to "clean" eax of
  1344. ; any garbage that may have been left in it.
  1345. ;
  1346. xor eax,eax
  1347. etstatuserr:
  1348. ;
  1349. ; Mask-off any garbage that my have been left in the upper
  1350. ; 16bits of eax.
  1351. ;
  1352. and eax,0000ffffh
  1353. pop si
  1354. pop ds
  1355. pop bx
  1356. pop dx
  1357. ;
  1358. ; Restore bp and remove stack-frame from stack
  1359. ;
  1360. pop bp
  1361. REMOVE_STACK_FRAME_MACRO <GetElToritoStatusFrame>
  1362. ;
  1363. ; Save return code on 16bit stack
  1364. ; Re-enable protect-mode and paging.
  1365. ;
  1366. push eax
  1367. RE_ENABLE_PAGING_MACRO
  1368. pop eax
  1369. ;
  1370. ; Return to caller and the 32bit universe.
  1371. ;
  1372. EXPORT_EXIT_MACRO
  1373. ;++
  1374. ;
  1375. ; Routine Name:
  1376. ;
  1377. ; GetExtendedInt13Params
  1378. ;
  1379. ; Description:
  1380. ;
  1381. ; Determine if extended int13 services are available for a drive
  1382. ; and if so retrieve extended disk parameters.
  1383. ;
  1384. ; Arguments:
  1385. ;
  1386. ; - 32-bit flat pointer to 26-byte param packet filled by this routine
  1387. ;
  1388. ; - int 13 unit number
  1389. ;
  1390. ; Returns:
  1391. ;
  1392. ; ax = 0 means extended int13 not supported on the given drive
  1393. ; ax = 1 means extended int13 supported and param packet filled in
  1394. ;
  1395. ;--
  1396. EXPORT_ENTRY_MACRO GetExtendedInt13Params
  1397. ;
  1398. ; Move the arguments from the caller's 32bit stack to the SU module's
  1399. ; 16bit stack.
  1400. ;
  1401. MAKE_STACK_FRAME_MACRO <GetExtendedInt13ParamsFrame>, ebx
  1402. ;
  1403. ; Go into real mode. We still have the same stack and sp
  1404. ; but we'll be executing in realmode.
  1405. ;
  1406. ENTER_REALMODE_MACRO
  1407. ;
  1408. ; Make (bp) point to the bottom of the argument frame.
  1409. ;
  1410. push bp
  1411. mov bp,sp
  1412. add bp,2
  1413. push dx
  1414. push bx
  1415. push ds
  1416. push si
  1417. ;
  1418. ; Check for support for this drive.
  1419. ;
  1420. mov ah,41h
  1421. mov bx,55aah
  1422. mov dl,byte ptr [bp].Int13UnitNumber
  1423. int BIOS_DISK_INTERRUPT
  1424. jc noxint13 ; carry set means no xint13
  1425. cmp bx,0aa55h ; check signature
  1426. jnz noxint13 ; not present, no xint13
  1427. test cl,1 ; bit 0 clear means no xint13
  1428. jz noxint13
  1429. ;
  1430. ; If we get here it looks like we have xint13 support.
  1431. ; Some BIOSes are broken though so we do some validation while we're
  1432. ; asking for the extended int13 drive parameters for the drive.
  1433. ; Note that and buffer addresses passed to this routine
  1434. ; MUST be in the lower one megabyte of memory to be addressable in real mode.
  1435. ;
  1436. mov eax,[bp].ParamPacketPointer
  1437. mov bx,ax
  1438. and bx,0fh
  1439. mov si,bx
  1440. shr eax,4
  1441. mov ds,ax ; DS:SI -> param packet
  1442. mov word ptr [si],26 ; initialize packet with size
  1443. ; some bioses helpfully zero out
  1444. ; the whole buffer according to
  1445. ; this size, so make SURE the
  1446. ; entire word is initialized and
  1447. ; there's no junk in the high byte.
  1448. mov dl,byte ptr [bp].Int13UnitNumber
  1449. mov ah,48h
  1450. int BIOS_DISK_INTERRUPT
  1451. jc noxint13
  1452. ;
  1453. ; If we get here then everything's cool and we have xint13 parameters.
  1454. ; We also know carry isn't set.
  1455. ;
  1456. mov al,1
  1457. jnc xint13done
  1458. noxint13:
  1459. xor al,al
  1460. xint13done:
  1461. movzx eax,al
  1462. pop si
  1463. pop ds
  1464. pop bx
  1465. pop dx
  1466. ;
  1467. ; Restore bp and remove stack-frame from stack
  1468. ;
  1469. pop bp
  1470. REMOVE_STACK_FRAME_MACRO <GetExtendedInt13ParamsFrame>
  1471. ;
  1472. ; Save return code on 16bit stack
  1473. ; Re-enable protect-mode and paging.
  1474. ;
  1475. push eax
  1476. RE_ENABLE_PAGING_MACRO
  1477. pop eax
  1478. ;
  1479. ; Return to caller and the 32bit universe.
  1480. ;
  1481. EXPORT_EXIT_MACRO
  1482. ;++
  1483. ;
  1484. ; ULONG
  1485. ; NetPcRomServices (
  1486. ; ULONG FunctionNumber
  1487. ; PVOID CommandPacket
  1488. ; )
  1489. ;
  1490. ; Routine Name:
  1491. ;
  1492. ; NetPcRomServices
  1493. ;
  1494. ; Description:
  1495. ;
  1496. ; Invoke a NetPC ROM service
  1497. ;
  1498. ; Arguments:
  1499. ;
  1500. ; FunctionNumber - NetPC ROM function number
  1501. ; CommandPacket - 32-bit flat pointer to command packet (must be in
  1502. ; low megabyte of physical memory)
  1503. ;
  1504. ; Returns:
  1505. ;
  1506. ; NetPC ROM status code
  1507. ;
  1508. ;--
  1509. EXPORT_ENTRY_MACRO NetPcRomServices
  1510. ;
  1511. ; Move the arguments from the caller's 32bit stack to the SU module's
  1512. ; 16bit stack.
  1513. ;
  1514. MAKE_STACK_FRAME_MACRO <NetPcRomServicesFrame>, ebx
  1515. ;
  1516. ; Go into real mode. We still have the same stack and sp
  1517. ; but we'll be executing in realmode.
  1518. ;
  1519. ENTER_REALMODE_MACRO
  1520. ;
  1521. ; Make (bp) point to the bottom of the argument frame.
  1522. ;
  1523. push bp
  1524. mov bp,sp
  1525. add bp,2
  1526. ;
  1527. ; Put the CommandPacket pointer into ES:DI, and the Function Number into BX.
  1528. ;
  1529. mov eax,dword ptr [bp].NetPcRomCommandPacketPointer
  1530. mov bx,ax
  1531. and bx,0fh
  1532. mov di,bx
  1533. shr eax,4
  1534. mov es,ax
  1535. mov bx,word ptr [bp].NetPcRomFunctionNumber
  1536. push ds
  1537. lds si,dword ptr _NetPcRomEntry
  1538. mov ax,ds
  1539. shl eax,16
  1540. mov ax,si
  1541. push cs
  1542. push offset _TEXT:RomServiceDone
  1543. push ds
  1544. push si
  1545. if 0
  1546. push ds
  1547. push si
  1548. push 0b800h
  1549. pop ds
  1550. mov si, 20*(80*2)+(2*40)
  1551. mov byte ptr ds:[si],02bh
  1552. pop si
  1553. pop ds
  1554. endif
  1555. retf
  1556. RomServiceDone:
  1557. if 0
  1558. push ds
  1559. push si
  1560. push 0b800h
  1561. pop ds
  1562. mov si, 20*(80*2)+(2*40)
  1563. mov byte ptr ds:[si],02dh
  1564. pop si
  1565. pop ds
  1566. endif
  1567. pop ds
  1568. ;
  1569. ; Restore bp and remove stack-frame from stack
  1570. ;
  1571. pop bp
  1572. REMOVE_STACK_FRAME_MACRO <NetPcRomServicesFrame>
  1573. ;
  1574. ; Save return code on 16bit stack. Turn the A20 gate back on,
  1575. ; in case the BIOS turned it off in int 15h, op 87h.
  1576. ; Re-enable protect-mode and paging.
  1577. ;
  1578. push eax
  1579. cli
  1580. call _EnableA20
  1581. sti
  1582. RE_ENABLE_PAGING_MACRO
  1583. pop eax
  1584. ;
  1585. ; Return to caller and the 32bit universe.
  1586. ;
  1587. EXPORT_EXIT_MACRO
  1588. ;++
  1589. ;
  1590. ; ULONG
  1591. ; BiosRedirectService (
  1592. ; ULONG Command
  1593. ; )
  1594. ;
  1595. ; Routine Name:
  1596. ;
  1597. ; BiosRedirectService
  1598. ;
  1599. ; Description:
  1600. ;
  1601. ; Get parameters of bios redirection.
  1602. ;
  1603. ; Arguments:
  1604. ;
  1605. ; Command - 1: Get Com Port Number
  1606. ; 2: Get Baud Rate
  1607. ; 3: Get Parity
  1608. ; 4: Get Stop Bits
  1609. ;
  1610. ; Returns:
  1611. ;
  1612. ; Value, or -1 if an error.
  1613. ;
  1614. ;--
  1615. EXPORT_ENTRY_MACRO BiosRedirectService
  1616. ;
  1617. ; Move the arguments from the caller's 32bit stack to the SU module's
  1618. ; 16bit stack.
  1619. ;
  1620. MAKE_STACK_FRAME_MACRO <BiosRedirectServiceFrame>, ebx
  1621. ;
  1622. ; Go into real mode. We still have the same stack and sp
  1623. ; but we'll be executing in realmode.
  1624. ;
  1625. ENTER_REALMODE_MACRO
  1626. ;
  1627. ; Make (bp) point to the bottom of the argument frame.
  1628. ;
  1629. push bp
  1630. mov bp,sp
  1631. add bp,2
  1632. ;
  1633. ; Get the Command and do it.
  1634. ;
  1635. mov eax,dword ptr [bp].Command
  1636. cmp eax, 1
  1637. je GetComPort
  1638. cmp eax, 2
  1639. je GetBaudRate
  1640. cmp eax, 3
  1641. je GetParity
  1642. cmp eax, 4
  1643. je GetStopBits
  1644. mov eax, -1
  1645. jmp Done
  1646. GetStopBits:
  1647. mov eax, 1
  1648. jmp Done
  1649. GetParity:
  1650. mov eax, 0
  1651. jmp Done
  1652. GetBaudRate:
  1653. IFDEF HDLS_HISPEED
  1654. mov eax, 115200
  1655. else
  1656. mov eax, 9600
  1657. endif
  1658. jmp Done
  1659. GetComPort:
  1660. IFDEF HEADLESS_SRV
  1661. mov eax, HEADLESS_COMPORT
  1662. add eax, 1
  1663. else
  1664. mov eax, -1
  1665. endif
  1666. Done:
  1667. ;
  1668. ; Restore bp and remove stack-frame from stack
  1669. ;
  1670. pop bp
  1671. REMOVE_STACK_FRAME_MACRO <BiosRedirectServiceFrame>
  1672. ;
  1673. ; Save return code on 16bit stack. Turn the A20 gate back on,
  1674. ; in case the BIOS turned it off in int 15h, op 87h.
  1675. ; Re-enable protect-mode and paging.
  1676. ;
  1677. push eax
  1678. cli
  1679. call _EnableA20
  1680. sti
  1681. RE_ENABLE_PAGING_MACRO
  1682. pop eax
  1683. ;
  1684. ; Return to caller and the 32bit universe.
  1685. ;
  1686. EXPORT_EXIT_MACRO
  1687. _TEXT ends
  1688. end