VirtualBox

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

Last change on this file since 58841 was 57162, checked in by vboxsync, 9 years ago

BIOS: Initialize ROMs before showin logo.

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

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