VirtualBox

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

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

Really stupid typo fixed.

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