VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/orgs.asm@ 43804

最後變更 在這個檔案從43804是 43759,由 vboxsync 提交於 12 年 前

BIOS: Windows 2000 floppy boot workaround.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 36.3 KB
 
1;;
2;; Copyright (C) 2006-2011 Oracle Corporation
3;;
4;; This file is part of VirtualBox Open Source Edition (OSE), as
5;; available from http://www.alldomusa.eu.org. This file is free software;
6;; you can redistribute it and/or modify it under the terms of the GNU
7;; General Public License (GPL) as published by the Free Software
8;; Foundation, in version 2 as it comes in the "COPYING" file of the
9;; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
10;; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
11;; --------------------------------------------------------------------
12;;
13;; This code is based on:
14;;
15;; ROM BIOS for use with Bochs/Plex86/QEMU emulation environment
16;;
17;; Copyright (C) 2002 MandrakeSoft S.A.
18;;
19;; MandrakeSoft S.A.
20;; 43, rue d'Aboukir
21;; 75002 Paris - France
22;; http://www.linux-mandrake.com/
23;; http://www.mandrakesoft.com/
24;;
25;; This library is free software; you can redistribute it and/or
26;; modify it under the terms of the GNU Lesser General Public
27;; License as published by the Free Software Foundation; either
28;; version 2 of the License, or (at your option) any later version.
29;;
30;; This library is distributed in the hope that it will be useful,
31;; but WITHOUT ANY WARRANTY; without even the implied warranty of
32;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33;; Lesser General Public License for more details.
34;;
35;; You should have received a copy of the GNU Lesser General Public
36;; License along with this library; if not, write to the Free Software
37;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
38;;
39;;
40
41
42; Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
43; other than GPL or LGPL is available it will apply instead, Oracle elects to use only
44; the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
45; a choice of LGPL license versions is made available with the language indicating
46; that LGPLv2 or any later version may be used, or where a choice of which version
47; of the LGPL is applied is otherwise unspecified.
48
49EBDA_SEG equ 09FC0h ; starts at 639K
50EBDA_SIZE equ 1 ; 1K
51BASE_MEM_IN_K equ (640 - EBDA_SIZE)
52
53CMOS_ADDR equ 070h
54CMOS_DATA equ 071h
55
56
57PIC_CMD_EOI equ 020h
58PIC_MASTER equ 020h
59PIC_SLAVE equ 0A0h
60
61BIOS_FIX_BASE equ 0E000h
62
63SYS_MODEL_ID equ 0FCh ; PC/AT
64SYS_SUBMODEL_ID equ 0
65BIOS_REVISION equ 1
66
67BIOS_BUILD_DATE equ '06/23/99'
68BIOS_COPYRIGHT equ 'Oracle VM VirtualBox BIOS'
69
70BX_ROMBIOS32 equ 0
71BX_CALL_INT15_4F equ 1
72
73;; Set a fixed BIOS location, with a marker for verification
74BIOSORG macro addr
75 org addr - BIOS_FIX_BASE - 2
76 db 'XM'
77 endm
78
79;; Set an interrupt vector (not very efficient if multiple vectors are
80;; programmed in one go)
81SET_INT_VECTOR macro vec, segm, offs
82 mov ax, offs
83 mov ds:[vec*4], ax
84 mov ax, segm
85 mov ds:[vec*4+2], ax
86endm
87
88; Set up an environment C code expects. DS must point to the BIOS segment
89; and the direction flag must be cleared(!)
90C_SETUP macro
91 push cs
92 pop ds
93 cld
94endm
95
96;; External function in separate modules
97extrn _dummy_isr_function:near
98extrn _log_bios_start:near
99extrn _nmi_handler_msg:near
100extrn _int18_panic_msg:near
101extrn _int09_function:near
102extrn _int13_diskette_function:near
103extrn _int13_eltorito:near
104extrn _int13_cdemu:near
105extrn _int13_cdrom:near
106extrn _cdemu_isactive:near
107extrn _cdemu_emulated_drive:near
108extrn _int13_harddisk:near
109extrn _int13_harddisk_ext:near
110extrn _int14_function:near
111extrn _int15_function:near
112extrn _int15_function_mouse:near
113extrn _int15_function32:near
114extrn _int16_function:near
115extrn _int17_function:near
116extrn _int19_function:near
117extrn _int1a_function:near
118extrn _pci16_function:near
119extrn _int70_function:near
120extrn _int74_function:near
121extrn _apm_function:near
122extrn _ata_init:near
123extrn _ahci_init:near
124extrn _scsi_init:near
125extrn _ata_detect:near
126extrn _cdemu_init:near
127extrn _keyboard_init:near
128extrn _print_bios_banner:near
129
130
131;; Symbols referenced from C code
132public _diskette_param_table
133public _pmode_IDT
134public _rmode_IDT
135public post
136public eoi_both_pics
137public rtc_post
138
139;; Additional publics for easier disassembly and debugging
140ifndef DEBUG
141 DEBUG equ 1
142endif
143ifdef DEBUG
144
145public int08_handler
146public int0e_handler
147public int11_handler
148public int12_handler
149public int13_handler
150public int13_relocated
151public int15_handler
152public int17_handler
153public int19_handler
154public int19_relocated
155public dummy_iret
156public nmi
157public rom_fdpt
158public cpu_reset
159public normal_post
160public eoi_jmp_post
161public eoi_master_pic
162public ebda_post
163public hard_drive_post
164public int13_legacy
165public int70_handler
166public int75_handler
167public int15_handler32
168public int15_handler_mouse
169public iret_modify_cf
170public rom_scan
171public rom_checksum
172public init_pic
173public floppy_post
174public int13_out
175public int13_disk
176public int13_notfloppy
177public int13_legacy
178public int13_noeltorito
179public int1c_handler
180public int10_handler
181public int74_handler
182public int76_handler
183public detect_parport
184public detect_serial
185public font8x8
186
187endif
188
189;; NOTE: The last 8K of the ROM BIOS are peppered with fixed locations which
190;; must be retained for compatibility. As a consequence, some of the space is
191;; going to be wasted, but the gaps should be filled with miscellaneous code
192;; and data when possible.
193
194.286p
195
196BIOSSEG segment 'CODE'
197 assume cs:BIOSSEG
198
199;;
200;; Start of fixed code - eoi_jmp_post is kept here to allow short jumps.
201;;
202 BIOSORG 0E030h
203eoi_jmp_post:
204 call eoi_both_pics
205 xor ax, ax
206 mov ds, ax
207 jmp dword ptr ds:[0467h]
208
209eoi_both_pics:
210 mov al, PIC_CMD_EOI
211 out PIC_SLAVE, al
212eoi_master_pic:
213 mov al, PIC_CMD_EOI
214 out PIC_MASTER, al
215 ret
216
217;; --------------------------------------------------------
218;; POST entry point
219;; --------------------------------------------------------
220 BIOSORG 0E05Bh
221post:
222 xor ax, ax
223
224 ;; reset the DMA controllers
225 out 00Dh, al
226 out 0DAh, al
227
228 ;; then initialize the DMA controllers
229 mov al, 0C0h
230 out 0D6h, al ; enable channel 4 cascade
231 mov al, 0
232 out 0D4h, al ; unmask channel 4
233
234 ;; read the CMOS shutdown status
235 mov al, 0Fh
236 out CMOS_ADDR, al
237 in al, CMOS_DATA
238
239 ;; save status
240 mov bl, al
241
242 ;; reset the shutdown status in CMOS
243 mov al, 0Fh
244 out CMOS_ADDR, al
245 mov al, 0
246 out CMOS_DATA, al
247
248 ;; examine the shutdown status code
249 mov al, bl
250 cmp al, 0
251 jz normal_post
252 cmp al, 0Dh
253 jae normal_post
254 cmp al, 9
255 je normal_post ;; TODO: really?!
256
257 ;; 05h = EOI + jump through 40:67
258 cmp al, 5
259 je eoi_jmp_post
260
261 ;; any other shutdown status values are ignored
262 ;; OpenSolaris sets the status to 0Ah in some cases?
263 jmp normal_post
264
265
266 ;; routine to write the pointer in DX:AX to memory starting
267 ;; at DS:BX (repeat CX times)
268 ;; - modifies BX, CX
269set_int_vects proc near
270
271 mov [bx], ax
272 mov [bx+2], dx
273 add bx, 4
274 loop set_int_vects
275 ret
276
277set_int_vects endp
278
279normal_post:
280 ;; shutdown code 0: normal startup
281 cli
282 ;; Set up the stack top at 0:7800h. The stack should not be
283 ;; located above 0:7C00h; that conflicts with PXE, which
284 ;; considers anything above that address to be fair game.
285 ;; The traditional locations are 30:100 (PC) or 0:400 (PC/AT).
286 mov ax, 7800h
287 mov sp, ax
288 xor ax, ax
289 mov ds, ax
290 mov ss, ax
291
292 ;; clear the bottom of memory except for the word at 40:72
293 ;; TODO: Why not clear all of it? What's the point?
294 mov es, ax
295 xor di, di
296 cld
297 mov cx, 0472h / 2
298 rep stosw
299 inc di
300 inc di
301 mov cx, (1000h - 0472h - 2) / 2
302 rep stosw
303
304 ;; clear the remaining base memory except for the top
305 ;; of the EBDA (the MP table is planted there)
306 xor bx, bx
307memory_zero_loop:
308 add bx, 1000h
309 cmp bx, 9000h
310 jae memory_cleared
311 mov es, bx
312 xor di, di
313 mov cx, 8000h ; 32K words
314 rep stosw
315 jmp memory_zero_loop
316memory_cleared:
317 mov es, bx
318 xor di, di
319 mov cx, 7FF8h ; all but the last 16 bytes
320 rep stosw
321 xor bx, bx
322
323
324 C_SETUP
325 call _log_bios_start
326
327 call pmode_setup
328
329 ;; set all interrupts in 00h-5Fh range to default handler
330 xor bx, bx
331 mov ds, bx
332 mov cx, 60h ; leave the rest as zeros
333 mov ax, dummy_iret
334 mov dx, BIOSSEG
335 call set_int_vects
336
337 ;; also set 68h-77h to default handler; note that the
338 ;; 60h-67h range must contain zeros for certain programs
339 ;; to function correctly
340 mov bx, 68h * 4
341 mov cx, 10h
342 call set_int_vects
343
344 ;; base memory in K to 40:13
345 mov ax, BASE_MEM_IN_K
346 mov ds:[413h], ax
347
348 ;; manufacturing test at 40:12
349 ;; zeroed out above
350
351 ;; set up various service vectors
352 ;; TODO: This should use the table at FEF3h instead
353 SET_INT_VECTOR 11h, BIOSSEG, int11_handler
354 SET_INT_VECTOR 12h, BIOSSEG, int12_handler
355 SET_INT_VECTOR 15h, BIOSSEG, int15_handler
356 SET_INT_VECTOR 17h, BIOSSEG, int17_handler
357 SET_INT_VECTOR 18h, BIOSSEG, int18_handler
358 SET_INT_VECTOR 19h, BIOSSEG, int19_handler
359 SET_INT_VECTOR 1Ch, BIOSSEG, int1c_handler
360
361 call ebda_post
362
363 ;; PIT setup
364 SET_INT_VECTOR 08h, BIOSSEG, int08_handler
365 mov al, 34h ; timer 0, binary, 16-bit, mode 2
366 out 43h, al
367 mov al, 0 ; max count -> ~18.2 Hz
368 out 40h, al
369 out 40h, al
370
371 ;; keyboard setup
372 SET_INT_VECTOR 09h, BIOSSEG, int09_handler
373 SET_INT_VECTOR 16h, BIOSSEG, int16_handler
374
375 xor ax, ax
376 mov ds, ax
377 ;; TODO: What's the point? The BDA is zeroed already?!
378 mov ds:[417h], al ; keyboard shift flags, set 1
379 mov ds:[418h], al ; keyboard shift flags, set 2
380 mov ds:[419h], al ; keyboard Alt-numpad work area
381 mov ds:[471h], al ; keyboard Ctrl-Break flag
382 mov ds:[497h], al ; keyboard status flags 4
383 mov al, 10h
384 mov ds:[496h], al ; keyboard status flags 3
385
386 mov bx, 1Eh
387 mov ds:[41Ah], bx ; keyboard buffer head
388 mov ds:[41Ch], bx ; keyboard buffer tail
389 mov ds:[480h], bx ; keyboard buffer start
390 mov bx, 3Eh
391 mov ds:[482h], bx ; keyboard buffer end
392
393 push ds
394 C_SETUP
395 call _keyboard_init
396 pop ds
397
398
399 ;; store CMOS equipment byte in BDA
400 mov al, 14h
401 out CMOS_ADDR, al
402 in al, CMOS_DATA
403 mov ds:[410h], al
404
405 ;; parallel setup
406 SET_INT_VECTOR 0Fh, BIOSSEG, dummy_iret
407 xor ax, ax
408 mov ds, ax
409 xor bx, bx
410 mov cl, 14h ; timeout value
411 mov dx, 378h ; parallel port 1
412 call detect_parport
413 mov dx, 278h ; parallel port 2
414 call detect_parport
415 shl bx, 0Eh
416 mov ax, ds:[410h] ; equipment word
417 and ax, 3FFFh
418 or ax, bx ; set number of parallel ports
419 mov ds:[410h], ax ; store in BDA
420
421 ;; Serial setup
422 SET_INT_VECTOR 0Bh, BIOSSEG, dummy_isr
423 SET_INT_VECTOR 0Ch, BIOSSEG, dummy_isr
424 SET_INT_VECTOR 14h, BIOSSEG, int14_handler
425 xor bx, bx
426 mov cl, 0Ah ; timeout value
427 mov dx, 3F8h ; first serial address
428 call detect_serial
429 mov dx, 2F8h ; second serial address
430 call detect_serial
431 mov dx, 3E8h ; third serial address
432 call detect_serial
433 mov dx, 2E8h ; fourth serial address
434 call detect_serial
435 shl bx, 9
436 mov ax, ds:[410h] ; equipment word
437 and ax, 0F1FFh ; bits 9-11 determine serial ports
438 or ax, bx
439 mov ds:[410h], ax
440
441 ;; CMOS RTC
442 SET_INT_VECTOR 1Ah, BIOSSEG, int1a_handler
443 SET_INT_VECTOR 4Ah, BIOSSEG, dummy_iret ; TODO: redundant?
444 SET_INT_VECTOR 70h, BIOSSEG, int70_handler
445 ;; BIOS DATA AREA 4CEh ???
446 call rtc_post
447
448 ;; PS/2 mouse setup
449 SET_INT_VECTOR 74h, BIOSSEG, int74_handler
450
451 ;; IRQ 13h (FPU exception) setup
452 SET_INT_VECTOR 75h, BIOSSEG, int75_handler
453
454 ;; Video setup
455 SET_INT_VECTOR 10h, BIOSSEG, int10_handler
456
457 call init_pic
458
459 call pcibios_init_iomem_bases
460 call pcibios_init_irqs
461
462 call rom_scan
463
464 C_SETUP
465 ;; ATA/ATAPI driver setup
466 call _ata_init
467 call _ata_detect
468
469ifdef VBOX_WITH_AHCI
470 ; AHCI driver setup
471 call _ahci_init
472endif
473
474ifdef VBOX_WITH_SCSI
475 ; SCSI driver setup
476 call _scsi_init
477endif
478
479 ;; floppy setup
480 call floppy_post
481
482 ;; hard drive setup
483 call hard_drive_post
484
485 C_SETUP ; in case assembly code changed things
486 call _print_bios_banner
487
488 ;; El Torito floppy/hard disk emulation
489 call _cdemu_init
490
491 ; TODO: what's the point of enabling interrupts here??
492 sti ; enable interrupts
493 int 19h
494 ;; does not return here
495 sti
496wait_forever:
497 hlt
498 jmp wait_forever
499 cli
500 hlt
501
502
503;; --------------------------------------------------------
504;; NMI handler
505;; --------------------------------------------------------
506 BIOSORG 0E2C3h
507nmi:
508 C_SETUP
509 call _nmi_handler_msg
510 iret
511
512int75_handler:
513 out 0F0h, al ; clear IRQ13
514 call eoi_both_pics
515 int 2 ; emulate legacy NMI
516 iret
517
518
519hard_drive_post proc near
520
521 ;; TODO Why? And what about secondary controllers?
522 mov al, 0Ah ; disable IRQ 14
523 mov dx, 03F6h
524 out dx, al
525
526 xor ax, ax
527 mov ds, ax
528 ;; TODO: Didn't we just clear the entire EBDA?
529 mov ds:[474h], al ; last HD operation status
530 mov ds:[477h], al ; HD port offset (XT only???)
531 mov ds:[48Ch], al ; HD status register
532 mov ds:[48Dh], al ; HD error register
533 mov ds:[48Eh], al ; HD task complete flag
534 mov al, 0C0h
535 mov ds:[476h], al ; HD control byte
536 ;; set up hard disk interrupt vectors
537 SET_INT_VECTOR 13h, BIOSSEG, int13_handler
538 SET_INT_VECTOR 76h, BIOSSEG, int76_handler
539 ;; INT 41h/46h: hard disk 0/1 dpt
540 ; TODO: This should be done from the code which
541 ; builds the DPTs?
542 SET_INT_VECTOR 41h, EBDA_SEG, 3Dh
543 SET_INT_VECTOR 46h, EBDA_SEG, 4Dh
544 ret
545
546hard_drive_post endp
547
548
549;; --------------------------------------------------------
550;; INT 13h handler - Disk services
551;; --------------------------------------------------------
552 BIOSORG 0E3FEh
553
554int13_handler:
555 jmp int13_relocated
556
557
558;; --------------------------------------------------------
559;; Fixed Disk Parameter Table
560;; --------------------------------------------------------
561;; BIOSORG 0E401h - fixed wrt preceding
562
563rom_fdpt:
564
565;; --------------------------------------------------------
566;; INT 19h handler - Boot load service
567;; --------------------------------------------------------
568 BIOSORG 0E6F2h
569
570int19_handler:
571 jmp int19_relocated
572
573
574
575;; --------------------------------------------------------
576;; System BIOS Configuration Table
577;; --------------------------------------------------------
578;; BIOSORG 0E6F5h - fixed wrt preceding
579; must match BIOS_CONFIG_TABLE
580bios_cfg_table:
581 dw 9 ; table size in bytes
582 db SYS_MODEL_ID
583 db SYS_SUBMODEL_ID
584 db BIOS_REVISION
585 ; Feature byte 1
586 ; b7: 1=DMA channel 3 used by hard disk
587 ; b6: 1=2 interrupt controllers present
588 ; b5: 1=RTC present
589 ; b4: 1=BIOS calls int 15h/4Fh for every key
590 ; b3: 1=wait for extern event supported (Int 15h/41h)
591 ; b2: 1=extended BIOS data area used
592 ; b1: 0=AT or ESDI bus, 1=MicroChannel
593 ; b0: 1=Dual bus (MicroChannel + ISA)
594ifdef BX_CALL_INT15_4F
595 db 74h; or USE_EBDA
596else
597 db 64h; or USE_EBDA
598endif
599 ; Feature byte 2
600 ; b7: 1=32-bit DMA supported
601 ; b6: 1=int16h, function 9 supported
602 ; b5: 1=int15h/C6h (get POS data) supported
603 ; b4: 1=int15h/C7h (get mem map info) supported
604 ; b3: 1=int15h/C8h (en/dis CPU) supported
605 ; b2: 1=non-8042 kb controller
606 ; b1: 1=data streaming supported
607 ; b0: reserved
608 db 40h
609 ; Feature byte 3
610 ; b7: not used
611 ; b6: reserved
612 ; b5: reserved
613 ; b4: POST supports ROM-to-RAM enable/disable
614 ; b3: SCSI on system board
615 ; b2: info panel installed
616 ; b1: Initial Machine Load (IML) system - BIOS on disk
617 ; b0: SCSI supported in IML
618 db 0
619 ; Feature byte 4
620 ; b7: IBM private
621 ; b6: EEPROM present
622 ; b5-3: ABIOS presence (011 = not supported)
623 ; b2: private
624 ; b1: memory split above 16Mb supported
625 ; b0: POSTEXT directly supported by POST
626 db 0
627 ; Feature byte 5 (IBM)
628 ; b1: enhanced mouse
629 ; b0: flash EPROM
630 db 0
631
632
633;; --------------------------------------------------------
634;; Baud Rate Generator Table
635;; --------------------------------------------------------
636 BIOSORG 0E729h
637
638
639;; --------------------------------------------------------
640;; INT 14h handler - Serial Communication Service
641;; --------------------------------------------------------
642 BIOSORG 0E739h
643int14_handler:
644 push ds
645 push es
646 pusha
647 C_SETUP
648 call _int14_function
649 popa
650 pop es
651 pop ds
652 iret
653
654
655
656;;
657;; Handler for unexpected hardware interrupts
658;;
659dummy_isr:
660 push ds
661 push es
662 pusha
663 C_SETUP
664 call _dummy_isr_function
665 popa
666 pop es
667 pop ds
668 iret
669
670
671rom_checksum proc near
672 push ax
673ifdef CHECKSUM_ROMS
674 push bx
675 push cx
676 xor ax, ax
677 xor bx, bx
678 xor cx, cx
679 mov ch, ds:[2]
680 shl cx, 1
681checksum_loop:
682 add al, [bx]
683 inc bx
684 loop checksum_loop
685 and al, 0FFh ; set flags
686 pop cx
687 pop bx
688else
689 xor al, al
690endif
691 pop ax
692 ret
693rom_checksum endp
694
695
696;;
697;; ROM scan - scan for valid ROMs and initialize them
698;;
699rom_scan:
700 mov cx, 0C000h ; start at C000
701rom_scan_loop:
702 mov ds, cx
703 mov ax, 4 ; scan in 2K increments
704 cmp word ptr ds:[0], 0AA55h ; look for signature
705 jne rom_scan_increment
706
707 call rom_checksum
708 jnz rom_scan_increment
709
710 mov al, ds:[2] ; set increment to ROM length
711 test al, 3
712 jz block_count_rounded
713
714 and al, 0FCh ; round up
715 add al, 4 ; to nearest 2K
716block_count_rounded:
717 xor bx, bx
718 mov ds, bx
719 push ax
720 push cx ; push segment...
721 push 3 ; ...and offset of ROM entry
722 mov bp, sp
723 call dword ptr [bp] ; call ROM init routine
724 cli ; in case ROM enabled interrupts
725 add sp, 2 ; get rid of offset
726 pop cx ; restore registers
727 pop ax
728rom_scan_increment:
729 shl ax, 5 ; convert to 16-byte increments
730 add cx, ax
731 cmp cx, 0E800h ; must encompass VBOX_LANBOOT_SEG!
732 jbe rom_scan_loop
733
734 xor ax, ax ; DS back to zero
735 mov ds, ax
736 ret
737
738init_pic proc near
739
740 mov al, 11h ; send init commands
741 out PIC_MASTER, al
742 out PIC_SLAVE, al
743 mov al, 08h ; base 08h
744 out PIC_MASTER+1, al
745 mov al, 70h ; base 70h
746 out PIC_SLAVE+1, al
747 mov al, 04h ; master PIC
748 out PIC_MASTER+1, al
749 mov al, 02h ; slave PIC
750 out PIC_SLAVE+1, al
751 mov al, 01h
752 out PIC_MASTER+1, al
753 out PIC_SLAVE+1, al
754 mov al, 0B8h ; unmask IRQs 0/1/2/6
755 out PIC_MASTER+1, al
756 mov al, 08Fh
757 out PIC_SLAVE+1, al ; unmask IRQs 12/13/14
758 ret
759
760init_pic endp
761
762ebda_post proc near
763
764 SET_INT_VECTOR 0Dh, BIOSSEG, dummy_isr ; IRQ 5
765 SET_INT_VECTOR 0Fh, BIOSSEG, dummy_isr ; IRQ 7
766 SET_INT_VECTOR 72h, BIOSSEG, dummy_isr ; IRQ 11
767 SET_INT_VECTOR 77h, BIOSSEG, dummy_isr ; IRQ 15
768
769 mov ax, EBDA_SEG
770 mov ds, ax
771 mov byte ptr ds:[0], EBDA_SIZE
772 ;; store EBDA seg in 40:0E
773 xor ax, ax
774 mov ds, ax
775 mov word ptr ds:[40Eh], EBDA_SEG
776 ret
777
778ebda_post endp
779
780
781
782;; --------------------------------------------------------
783;; INT 16h handler - Keyboard service
784;; --------------------------------------------------------
785 BIOSORG 0E82Eh
786int16_handler:
787 sti
788 push es
789 push ds
790 pusha
791
792 cmp ah, 0
793 je int16_F00
794
795 cmp ah, 10h
796 je int16_F00
797
798 C_SETUP
799 call _int16_function
800 popa
801 pop ds
802 pop es
803 iret
804
805int16_F00:
806 mov bx, 40h ; TODO: why 40h here and 0 elsewhere?
807 mov ds, bx
808int16_wait_for_key:
809 cli
810 mov bx, ds:[1Ah]
811 cmp bx, ds:[1Ch]
812 jne int16_key_found
813 sti
814 nop
815; TODO: review/enable?
816if 0
817 push ax
818 mov ax, 9002h
819 int 15h
820 pop ax
821endif
822 jmp int16_wait_for_key
823
824int16_key_found:
825 C_SETUP
826 call _int16_function
827 popa
828 pop ds
829 pop es
830; TODO: review/enable? If so, flags should be restored here?
831if 0
832 push ax
833 mov ax, 9202h
834 int 15h
835 pop ax
836endif
837 iret
838
839
840;; Quick and dirty protected mode entry/exit routines
841include pmode.inc
842
843;; Initialization code which needs to run in protected mode (LAPIC etc.)
844include pmsetup.inc
845
846
847KBDC_DISABLE EQU 0ADh
848KBDC_ENABLE EQU 0AEh
849KBC_CMD EQU 64h
850KBC_DATA EQU 60h
851
852;; --------------------------------------------------------
853;; INT 09h handler - Keyboard ISR (IRQ 1)
854;; --------------------------------------------------------
855 BIOSORG 0E987h
856int09_handler:
857 cli ; TODO: why? they're off already!
858 push ax
859 mov al, KBDC_DISABLE
860 out KBC_CMD, al
861
862 mov al, 0Bh
863 out PIC_MASTER, al
864 in al, PIC_MASTER
865 and al, 2
866 jz int09_finish
867
868 in al, KBC_DATA
869 push ds
870 pusha
871 cld ; Before INT 15h (and any C code)
872ifdef BX_CALL_INT15_4F
873 mov ah, 4Fh
874 stc
875 int 15h ; keyboard intercept
876 jnc int09_done
877endif
878 sti ; Only after calling INT 15h
879
880 ;; check for extended key
881 cmp al, 0E0h
882 jne int09_check_pause
883 xor ax, ax
884 mov ds, ax
885 mov al, ds:[496h] ; mf2_state |= 0x02
886 or al, 2 ; TODO: why not RMW?
887 mov ds:[496h], al
888 jmp int09_done
889
890int09_check_pause:
891 cmp al, 0E1h ; pause key?
892 jne int09_process_key
893 xor ax, ax
894 mov ds, ax ; TODO: haven't we just done that??
895 mov al, ds:[496h]
896 or al, 1
897 mov ds:[496h], al ; TODO: why not RMW?
898 jmp int09_done
899
900int09_process_key:
901 push es
902 C_SETUP
903 call _int09_function
904 pop es
905
906int09_done:
907 popa
908 pop ds
909 cli
910 call eoi_master_pic
911
912int09_finish:
913 mov al, KBDC_ENABLE
914 out KBC_CMD, al
915 pop ax
916 iret
917
918
919;; --------------------------------------------------------
920;; INT 13h handler - Diskette service
921;; --------------------------------------------------------
922 BIOSORG 0EC59h
923int13_diskette:
924 jmp int13_noeltorito
925
926
927
928;; --------------------------------------------------------
929;; INT 13h handler - Disk service
930;; --------------------------------------------------------
931int13_relocated:
932 ;; check for an El-Torito function
933 cmp ah, 4Ah
934 jb int13_not_eltorito
935
936 cmp ah, 4Dh
937 ja int13_not_eltorito
938
939 pusha
940 push es
941 push ds
942 C_SETUP ; TODO: setup C envrionment only once?
943 push int13_out ; simulate a call
944 jmp _int13_eltorito ; ELDX not used
945
946int13_not_eltorito:
947 push es
948 push ax ; TODO: better register save/restore
949 push bx
950 push cx
951 push dx
952
953 ;; check if emulation is active
954 call _cdemu_isactive
955 cmp al, 0
956 je int13_cdemu_inactive
957
958 ;; check if access to the emulated drive
959 call _cdemu_emulated_drive
960 pop dx ; recover dx (destroyed by C code)
961 push dx
962 cmp al, dl ; INT 13h on emulated drive
963 jne int13_nocdemu
964
965 pop dx
966 pop cx
967 pop bx
968 pop ax
969 pop es
970
971 pusha
972 push es
973 push ds
974 C_SETUP ; TODO: setup environment only once?
975
976 push int13_out ; simulate a call
977 jmp _int13_cdemu ; ELDX not used
978
979int13_nocdemu:
980 and dl, 0E0h ; mask to get device class
981 cmp al, dl
982 jne int13_cdemu_inactive
983
984 pop dx
985 pop cx
986 pop bx
987 pop ax
988 pop es
989
990 push ax
991 push cx
992 push dx
993 push bx
994
995 dec dl ; real drive is dl - 1
996 jmp int13_legacy
997
998int13_cdemu_inactive:
999 pop dx
1000 pop cx
1001 pop bx
1002 pop ax
1003 pop es
1004
1005int13_noeltorito:
1006 push ax
1007 push cx
1008 push dx
1009 push bx
1010int13_legacy:
1011 push dx ; push eltorito dx in place of sp
1012 push bp
1013 push si
1014 push di
1015 push es
1016 push ds
1017 C_SETUP ; TODO: setup environment only once?
1018
1019 ;; now the registers can be restored with
1020 ;; pop ds; pop es; popa; iret
1021 test dl, 80h ; non-removable?
1022 jnz int13_notfloppy
1023
1024 push int13_out ; simulate a near call
1025 jmp _int13_diskette_function
1026
1027int13_notfloppy:
1028 cmp dl, 0E0h
1029 jb int13_notcdrom
1030
1031 ;; ebx may be modified, save here
1032 ;; TODO: check/review 32-bit register use
1033 .386
1034 shr ebx, 16
1035 push bx
1036 call _int13_cdrom
1037 pop bx
1038 shl ebx, 16
1039 .286
1040
1041 jmp int13_out
1042
1043int13_notcdrom:
1044int13_disk:
1045 cmp ah,40h
1046 ja int13x
1047 call _int13_harddisk
1048 jmp int13_out
1049
1050int13x:
1051 call _int13_harddisk_ext
1052
1053int13_out:
1054 pop ds
1055 pop es
1056 popa
1057 iret
1058
1059
1060
1061; parallel port detection: port in dx, index in bx, timeout in cl
1062detect_parport proc near
1063
1064 push dx
1065 inc dx
1066 inc dx
1067 in al, dx
1068 and al, 0DFh ; clear input mode
1069 out dx, al
1070 pop dx
1071 mov al, 0AAh
1072 out dx, al
1073 in al, dx
1074 cmp al, 0AAh
1075 jne no_parport
1076
1077 push bx
1078 shl bx, 1
1079 mov [bx+408h], dx ; parallel I/O address
1080 pop bx
1081 mov [bx+478h], cl ; parallel printer timeout
1082 inc bx
1083no_parport:
1084 ret
1085
1086detect_parport endp
1087
1088; setial port detection: port in dx, index in bx, timeout in cl
1089detect_serial proc near
1090
1091 push dx
1092 inc dx
1093 mov al, 2
1094 out dx, al
1095 in al, dx
1096 cmp al, 2
1097 jne no_serial
1098
1099 inc dx
1100 in al, dx
1101 cmp al, 2
1102 jne no_serial
1103
1104 dec dx
1105 xor al, al
1106 pop dx
1107 push bx
1108 shl bx, 1
1109 mov [bx+400h], dx ; serial I/O address
1110 pop bx
1111 mov [bx+47Ch], cl ; serial timeout
1112 inc bx
1113 ret
1114
1115no_serial:
1116 pop dx
1117 ret
1118
1119detect_serial endp
1120
1121
1122;;
1123;; POST: Floppy drive
1124;;
1125floppy_post proc near
1126
1127 xor ax, ax
1128 mov ds, ax
1129
1130 ;; TODO: This code is really stupid. Zeroing the BDA byte
1131 ;; by byte is dumb, and it's been already zeroed elsewhere!
1132 mov al, 0
1133 mov ds:[43Eh], al ; drive 0/1 uncalibrated, no IRQ
1134 mov ds:[43Fh], al ; motor status
1135 mov ds:[440h], al ; motor timeout counter
1136 mov ds:[441h], al ; controller status return code
1137 mov ds:[442h], al ; hd/floppy ctlr status register
1138 mov ds:[443h], al ; controller status register 1
1139 mov ds:[444h], al ; controller status register 2
1140 mov ds:[445h], al ; cylinder number
1141 mov ds:[446h], al ; head number
1142 mov ds:[447h], al ; sector number
1143 mov ds:[448h], al ; bytes written
1144
1145 mov ds:[48Bh], al ; configuration data
1146
1147 mov al, 10h ; floppy drive type
1148 out CMOS_ADDR, al
1149 in al, CMOS_DATA
1150 mov ah, al ; save drive type byte
1151
1152look_drive0:
1153 ; TODO: pre-init bl to reduce jumps
1154 shr al, 4 ; drive 0 in high nibble
1155 jz f0_missing ; jump if no drive
1156 mov bl, 7 ; drv0 determined, multi-rate, chgline
1157 jmp look_drive1
1158
1159f0_missing:
1160 mov bl, 0 ; no drive 0
1161
1162look_drive1:
1163 mov al, ah ; restore CMOS data
1164 and al, 0Fh ; drive 1 in low nibble
1165 jz f1_missing
1166 or bl, 70h ; drv1 determined, multi-rate, chgline
1167f1_missing:
1168 mov ds:[48Fh], bl ; store in BDA
1169
1170 ;; TODO: See above. Dumb *and* redundant!
1171 mov al, 0
1172 mov ds:[490h], al ; drv0 media state
1173 mov ds:[491h], al ; drv1 media state
1174 mov ds:[492h], al ; drv0 operational state
1175 mov ds:[493h], al ; drv1 operational state
1176 mov ds:[494h], al ; drv0 current cylinder
1177 mov ds:[495h], al ; drv1 current cylinder
1178
1179 mov al, 2
1180 out 0Ah, al ; unmask DMA channel 2
1181
1182 SET_INT_VECTOR 1Eh, BIOSSEG, _diskette_param_table
1183 SET_INT_VECTOR 40h, BIOSSEG, int13_diskette
1184 SET_INT_VECTOR 0Eh, BIOSSEG, int0e_handler ; IRQ 6
1185
1186 ret
1187
1188floppy_post endp
1189
1190
1191bcd_to_bin proc near
1192
1193 ;; in : AL in packed BCD format
1194 ;; out: AL in binary, AH always 0
1195 shl ax, 4
1196 shr al, 4
1197 aad
1198 ret
1199
1200bcd_to_bin endp
1201
1202rtc_post proc near
1203
1204 .386
1205 ;; get RTC seconds
1206 xor eax, eax
1207 mov al, 0
1208 out CMOS_ADDR, al
1209 in al, CMOS_DATA ; RTC seconds, in BCD
1210 call bcd_to_bin ; eax now has seconds in binary
1211 mov edx, 18206507
1212 mul edx
1213 mov ebx, 1000000
1214 xor edx, edx
1215 div ebx
1216 mov ecx, eax ; total ticks in ecx
1217
1218 ;; get RTC minutes
1219 xor eax, eax
1220 mov al, 2
1221 out CMOS_ADDR, al
1222 in al, CMOS_DATA ; RTC minutes, in BCD
1223 call bcd_to_bin ; eax now has minutes in binary
1224 mov edx, 10923904
1225 mul edx
1226 mov ebx, 10000
1227 xor edx, edx
1228 div ebx
1229 add ecx, eax ; add to total ticks
1230
1231 ;; get RTC hours
1232 xor eax, eax
1233 mov al, 4
1234 out CMOS_ADDR, al
1235 in al, CMOS_DATA ; RTC hours, in BCD
1236 call bcd_to_bin ; eax now has hours in binary
1237 mov edx, 65543427
1238 mul edx
1239 mov ebx, 1000
1240 xor edx, edx
1241 div ebx
1242 add ecx, eax ; add to total ticks
1243
1244 mov ds:[46Ch], ecx ; timer tick count
1245 xor al, al ; TODO: redundant?
1246 mov ds:[470h], al ; rollover flag
1247 .286
1248 ret
1249
1250rtc_post endp
1251
1252
1253
1254;; --------------------------------------------------------
1255;; INT 0Eh handler - Diskette IRQ 6 ISR
1256;; --------------------------------------------------------
1257 BIOSORG 0EF57h
1258int0e_handler:
1259 push ax
1260 push dx
1261 mov dx, 3F4h
1262 in al, dx
1263 and al, 0C0h
1264 cmp al, 0C0h
1265 je int0e_normal
1266 mov dx, 3F5h
1267 mov al, 08h ; sense interrupt
1268 out dx, al
1269int0e_loop1:
1270 mov dx, 3F4h ; TODO: move out of the loop?
1271 in al, dx
1272 and al, 0C0h
1273 cmp al, 0C0h
1274 jne int0e_loop1
1275
1276int0e_loop2:
1277 mov dx, 3F5h ; TODO: inc/dec dx instead
1278 in al, dx
1279 mov dx, 3F4h
1280 in al, dx
1281 and al, 0C0h
1282 cmp al, 0C0h
1283 je int0e_loop2
1284
1285int0e_normal:
1286 push ds
1287 xor ax, ax
1288 mov ds, ax
1289 call eoi_master_pic
1290 ; indicate that an interrupt occurred
1291 or byte ptr ds:[43Eh], 80h
1292 pop ds
1293 pop dx
1294 pop ax
1295 iret
1296
1297
1298;; --------------------------------------------------------
1299;; Diskette Parameter Table
1300;; --------------------------------------------------------
1301 BIOSORG 0EFC7h
1302_diskette_param_table:
1303 db 0AFh
1304 db 2 ; HLT=1, DMA mode
1305 db 025h
1306 db 2
1307 db 18 ; SPT (good for 1.44MB media)
1308 db 01Bh
1309 db 0FFh
1310 db 06Ch
1311 db 0F6h ; format filler
1312 db 15
1313 db 8
1314
1315
1316
1317;; --------------------------------------------------------
1318;; INT 17h handler - Printer service
1319;; --------------------------------------------------------
1320;; BIOSORG 0EFD2h - fixed WRT preceding code
1321
1322 jmp int17_handler ; NT floppy boot workaround
1323 ; see @bugref{6481}
1324int17_handler:
1325 push ds
1326 push es
1327 pusha
1328 C_SETUP
1329 call _int17_function
1330 popa
1331 pop es
1332 pop ds
1333 iret
1334
1335
1336
1337;; Protected mode IDT descriptor
1338;;
1339;; The limit is 0 to cause a shutdown if an exception occurs
1340;; in protected mode. TODO: Is that what we really want?
1341;;
1342;; Set base to F0000 to correspond to beginning of BIOS,
1343;; in case an IDT is defined later.
1344
1345_pmode_IDT:
1346 dw 0 ; limit 15:0
1347 dw 0 ; base 15:0
1348 dw 0Fh ; base 23:16
1349
1350
1351;; Real mode IDT descriptor
1352;;
1353;; Set to typical real-mode values.
1354;; base = 000000
1355;; limit = 03ff
1356
1357_rmode_IDT:
1358 dw 3FFh ; limit 15:00
1359 dw 0 ; base 15:00
1360 dw 0 ; base 23:16
1361
1362
1363;;
1364;; INT 1Ch
1365;;
1366;; TODO: Why does this need a special handler?
1367int1c_handler: ;; user timer tick
1368 iret
1369
1370
1371
1372;; --------------------------------------------------------
1373;; INT 10h functions 0-Fh entry point
1374;; --------------------------------------------------------
1375 BIOSORG 0F045h
1376i10f0f_entry:
1377 iret
1378
1379
1380;; --------------------------------------------------------
1381;; INT 10h handler - MDA/CGA video
1382;; --------------------------------------------------------
1383 BIOSORG 0F065h
1384int10_handler:
1385 ;; do nothing - assumes VGA
1386 iret
1387
1388
1389;; --------------------------------------------------------
1390;; MDA/CGA Video Parameter Table (INT 1Dh)
1391;; --------------------------------------------------------
1392 BIOSORG 0F0A4h
1393mdacga_vpt:
1394
1395
1396;;
1397;; INT 18h - boot failure
1398;;
1399int18_handler:
1400 C_SETUP
1401 call _int18_panic_msg
1402 ;; TODO: handle failure better?
1403 hlt
1404 iret
1405
1406;;
1407;; INT 19h - boot service - relocated
1408;;
1409int19_relocated:
1410; If an already booted OS calls int 0x19 to reboot, it is not sufficient
1411; just to try booting from the configured drives. All BIOS variables and
1412; interrupt vectors need to be reset, otherwise strange things may happen.
1413; The approach used is faking a warm reboot (which just skips showing the
1414; logo), which is a bit more than what we need, but hey, it's fast.
1415 mov bp, sp
1416 mov ax, [bp+2] ; TODO: redundant? address via sp?
1417 cmp ax, BIOSSEG ; check caller's segment
1418 jz bios_initiated_boot
1419
1420 xor ax, ax
1421 mov ds, ax
1422 mov ax, 1234h
1423 mov ds:[472], ax
1424 jmp post
1425
1426bios_initiated_boot:
1427 ;; The C worker function returns the boot drive in bl and
1428 ;; the boot segment in ax. In case of failure, the boot
1429 ;; segment will be zero.
1430 C_SETUP ; TODO: Here? Now?
1431 push bp
1432 mov bp, sp
1433
1434 ;; 1st boot device
1435 mov ax, 1
1436 push ax
1437 call _int19_function
1438 inc sp
1439 inc sp
1440 test ax, ax ; if 0, try next device
1441 jnz boot_setup
1442
1443 ;; 2nd boot device
1444 mov ax, 2
1445 push ax
1446 call _int19_function
1447 inc sp
1448 inc sp
1449 test ax, ax ; if 0, try next device
1450 jnz boot_setup
1451
1452 ; 3rd boot device
1453 mov ax, 3
1454 push 3
1455 call _int19_function
1456 inc sp
1457 inc sp
1458 test ax, ax ; if 0, try next device
1459 jnz boot_setup
1460
1461 ; 4th boot device
1462 mov ax, 4
1463 push ax
1464 call _int19_function
1465 inc sp
1466 inc sp
1467 test ax, ax ; if 0, invoke INT 18h
1468 jz int18_handler
1469
1470boot_setup:
1471; TODO: the drive should be in dl already??
1472;; mov dl, bl ; tell guest OS what boot drive is
1473 .386 ; NB: We're getting garbage into high eax bits
1474 shl eax, 4 ; convert seg to ip
1475 mov [bp+2], ax ; set ip
1476
1477 shr eax, 4 ; get cs back
1478 .286
1479 and ax, BIOSSEG ; remove what went in ip
1480 mov [bp+4], ax ; set cs
1481 xor ax, ax
1482 mov ds, ax
1483 mov es, ax
1484 mov [bp], ax ; TODO: what's this?!
1485 mov ax, 0AA55h ; set ok flag ; TODO: and this?
1486
1487 pop bp ; TODO: why'd we just zero it??
1488 iret ; beam me up scotty
1489
1490;; PCI BIOS
1491
1492include pcibios.inc
1493include pirq.inc
1494
1495
1496;; --------------------------------------------------------
1497;; INT 12h handler - Memory size
1498;; --------------------------------------------------------
1499 BIOSORG 0F841h
1500int12_handler:
1501 ;; Don't touch - fixed size!
1502 sti
1503 push ds
1504 mov ax, 40h
1505 mov ds, ax
1506 mov ax, ds:[13h]
1507 pop ds
1508 iret
1509
1510
1511;; --------------------------------------------------------
1512;; INT 11h handler - Equipment list service
1513;; --------------------------------------------------------
1514;; BIOSORG 0F84Dh - fixed wrt preceding code
1515int11_handler:
1516 ;; Don't touch - fixed size!
1517 sti
1518 push ds
1519 mov ax, 40h
1520 mov ds, ax
1521 mov ax, ds:[10h]
1522 pop ds
1523 iret
1524
1525
1526;; --------------------------------------------------------
1527;; INT 15h handler - System services
1528;; --------------------------------------------------------
1529;; BIOSORG 0F859h - fixed wrt preceding code
1530int15_handler:
1531 pushf
1532 push ds
1533 push es
1534 C_SETUP
1535 cmp ah, 86h
1536 je int15_handler32
1537 cmp ah, 0E8h
1538 je int15_handler32
1539 pusha
1540 cmp ah, 53h ; APM function?
1541 je apm_call
1542 cmp ah, 0C2h ; PS/2 mouse function?
1543 je int15_handler_mouse
1544
1545 call _int15_function
1546int15_handler_popa_ret:
1547 popa
1548int15_handler32_ret:
1549 pop es
1550 pop ds
1551 popf
1552 jmp iret_modify_cf
1553
1554apm_call:
1555 call _apm_function
1556 jmp int15_handler_popa_ret
1557
1558int15_handler_mouse:
1559 call _int15_function_mouse
1560 jmp int15_handler_popa_ret
1561
1562int15_handler32:
1563 ;; need to save/restore 32-bit registers
1564 .386
1565 pushad
1566 call _int15_function32
1567 popad
1568 .286
1569 jmp int15_handler32_ret
1570
1571;;
1572;; Perform an IRET but retain the current carry flag value
1573;;
1574iret_modify_cf:
1575 jc carry_set
1576 push bp
1577 mov bp, sp
1578 and byte ptr [bp + 6], 0FEh
1579 pop bp
1580 iret
1581carry_set:
1582 push bp
1583 mov bp, sp
1584 or byte ptr [bp + 6], 1
1585 pop bp
1586 iret
1587
1588;;
1589;; INT 74h handler - PS/2 mouse (IRQ 12)
1590;;
1591int74_handler proc
1592
1593 sti
1594 pusha
1595 push es
1596 push ds
1597 push 0 ; placeholder for status
1598 push 0 ; placeholder for X
1599 push 0 ; placeholder for Y
1600 push 0 ; placeholder for Z
1601 push 0 ; placeholder for make_far_call bool
1602 C_SETUP
1603 call _int74_function
1604 pop cx ; pop make_far_call flag
1605 jcxz int74_done
1606
1607 ;; make far call to EBDA:0022
1608 push 0
1609 pop ds
1610 push ds:[40Eh]
1611 pop ds
1612 call far ptr ds:[22h]
1613int74_done:
1614 cli
1615 call eoi_both_pics
1616 add sp, 8 ; remove status, X, Y, Z
1617 pop ds
1618 pop es
1619 popa
1620 iret
1621
1622int74_handler endp
1623
1624int76_handler proc
1625
1626 ;; record completion in BIOS task complete flag
1627 push ax
1628 push ds
1629 mov ax, 40h
1630 mov ds, ax
1631 mov byte ptr ds:[8Eh], 0FFh
1632 call eoi_both_pics
1633 pop ds
1634 pop ax
1635 iret
1636
1637int76_handler endp
1638
1639;; --------------------------------------------------------
1640;; 8x8 font (first 128 characters)
1641;; --------------------------------------------------------
1642 BIOSORG 0FA6Eh
1643include font8x8.inc
1644
1645
1646;; --------------------------------------------------------
1647;; INT 1Ah handler - Time of the day + PCI BIOS
1648;; --------------------------------------------------------
1649;; BIOSORG 0FE6Eh - fixed wrt preceding table
1650int1a_handler:
1651 cmp ah, 0B1h
1652 jne int1a_normal
1653
1654 push es
1655 push ds
1656 C_SETUP
1657 .386
1658 pushad
1659 call _pci16_function
1660 popad
1661 .286
1662 pop ds
1663 pop es
1664 iret
1665
1666int1a_normal:
1667 push es
1668 push ds
1669 pusha
1670 C_SETUP
1671int1a_callfunction:
1672 call _int1a_function
1673 popa
1674 pop ds
1675 pop es
1676 iret
1677
1678
1679;;
1680;; IRQ 8 handler (RTC)
1681;;
1682int70_handler:
1683 push es
1684 push ds
1685 pusha
1686 C_SETUP
1687 call _int70_function
1688 popa
1689 pop ds
1690 pop es
1691 iret
1692
1693
1694;; --------------------------------------------------------
1695;; Timer tick - IRQ 0 handler
1696;; --------------------------------------------------------
1697 BIOSORG 0FEA5h
1698int08_handler:
1699 .386
1700 sti
1701 push eax
1702 push ds
1703 xor ax, ax
1704 mov ds, ax
1705
1706 ;; time to turn off floppy driv motor(s)?
1707 mov al, ds:[440h]
1708 or al, al
1709 jz int08_floppy_off
1710 ;; turn motor(s) off
1711 push dx
1712 mov dx, 03F2h
1713 in al, dx
1714 and al, 0CFh
1715 out dx, al
1716 pop dx
1717
1718int08_floppy_off:
1719 mov eax, ds:[46Ch] ; get ticks dword
1720 inc eax
1721
1722 ;; compare eax to one day's worth of ticks (at 18.2 Hz)
1723 cmp eax, 1800B0h
1724 jb int08_store_ticks
1725 ;; there has been a midnight rollover
1726 xor eax, eax
1727 inc byte ptr ds:[470h] ; increment rollover flag
1728
1729int08_store_ticks:
1730 mov ds:[46Ch], eax
1731 int 1Ch ; call the user timer handler
1732 cli
1733 call eoi_master_pic
1734 pop ds
1735 pop eax
1736 .286
1737 iret
1738
1739
1740;; --------------------------------------------------------
1741;; Initial interrupt vector offsets for POST
1742;; --------------------------------------------------------
1743 BIOSORG 0FEF3h
1744vector_table:
1745
1746
1747
1748;; --------------------------------------------------------
1749;; BIOS copyright string
1750;; --------------------------------------------------------
1751 BIOSORG 0FF00h
1752bios_string:
1753 db BIOS_COPYRIGHT
1754
1755
1756;; --------------------------------------------------------
1757;; IRET - default interrupt handler
1758;; --------------------------------------------------------
1759 BIOSORG 0FF53h
1760
1761dummy_iret:
1762 iret
1763
1764
1765;; --------------------------------------------------------
1766;; INT 05h - Print Screen service
1767;; --------------------------------------------------------
1768;; BIOSORG 0FF54h - fixed wrt preceding
1769int05_handler:
1770 ;; Not implemented
1771 iret
1772
1773include smidmi.inc
1774
1775;; --------------------------------------------------------
1776;; Processor reset entry point
1777;; --------------------------------------------------------
1778 BIOSORG 0FFF0h
1779cpu_reset:
1780 ;; This is where the CPU starts executing after a reset
1781 jmp far ptr post
1782
1783 ;; BIOS build date
1784 db BIOS_BUILD_DATE
1785 db 0 ; padding
1786 ;; System model ID
1787 db SYS_MODEL_ID
1788 ;; Checksum byte
1789 db 0FFh
1790
1791
1792BIOSSEG ends
1793
1794 end
1795
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette