VirtualBox

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

Last change on this file since 44058 was 44058, checked in by vboxsync, 12 years ago

BIOS: Removed broken code.

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

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