VirtualBox

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

Last change on this file since 47631 was 47006, checked in by vboxsync, 11 years ago

BIOS: Properly turn off floppy motor to save electricity.

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