VirtualBox

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

Last change on this file since 42127 was 42127, checked in by vboxsync, 13 years ago

BIOS: Updating PCI BIOS service.

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

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