VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS-new/orgs.asm@ 38699

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

Converted system BIOS to Watcom C.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use