Changeset 67065 in vbox for trunk/src/VBox
- Timestamp:
- May 24, 2017 1:04:01 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/BIOS/orgs.asm
r66959 r67065 1 1 ;; 2 ;; Copyright (C) 2006-201 6Oracle Corporation2 ;; Copyright (C) 2006-2017 Oracle Corporation 3 3 ;; 4 4 ;; This file is part of VirtualBox Open Source Edition (OSE), as … … 49 49 include commondefs.inc 50 50 51 EBDA_SEG equ 09FC0h; starts at 639K52 EBDA_SIZE equ 1; 1K53 BASE_MEM_IN_K equ(640 - EBDA_SIZE)54 55 CMOS_ADDR equ070h56 CMOS_DATA equ071h57 58 59 PIC_CMD_EOI equ020h60 PIC_MASTER equ020h61 PIC_SLAVE equ0A0h62 63 BIOS_FIX_BASE equ0E000h51 EBDA_SEG equ 09FC0h ; starts at 639K 52 EBDA_SIZE equ 1 ; 1K 53 BASE_MEM_IN_K equ (640 - EBDA_SIZE) 54 55 CMOS_ADDR equ 070h 56 CMOS_DATA equ 071h 57 58 59 PIC_CMD_EOI equ 020h 60 PIC_MASTER equ 020h 61 PIC_SLAVE equ 0A0h 62 63 BIOS_FIX_BASE equ 0E000h 64 64 65 65 if VBOX_BIOS_CPU ge 80286 66 SYS_MODEL_ID equ 0FCh; PC/AT66 SYS_MODEL_ID equ 0FCh ; PC/AT 67 67 else 68 SYS_MODEL_ID equ 0FBh; PC/XT69 endif 70 SYS_SUBMODEL_ID equ071 BIOS_REVISION equ172 73 BIOS_BUILD_DATE equ'06/23/99'74 BIOS_COPYRIGHT equ'Oracle VM VirtualBox BIOS'75 76 BX_ROMBIOS32 equ077 BX_CALL_INT15_4F equ168 SYS_MODEL_ID equ 0FBh ; PC/XT 69 endif 70 SYS_SUBMODEL_ID equ 0 71 BIOS_REVISION equ 1 72 73 BIOS_BUILD_DATE equ '06/23/99' 74 BIOS_COPYRIGHT equ 'Oracle VM VirtualBox BIOS' 75 76 BX_ROMBIOS32 equ 0 77 BX_CALL_INT15_4F equ 1 78 78 79 79 ;; Set a fixed BIOS location, with a marker for verification 80 BIOSORG macroaddr, addr_minus_two80 BIOSORG macro addr, addr_minus_two 81 81 .errnz (addr - 2 - addr_minus_two) ;; Couldn't convince wasm to accept $ here. Would've save us a lot of bother and ugly SED. 82 83 orgaddr - BIOS_FIX_BASE - 284 db'XM'85 86 82 BIOSORG_CHECK_BEFORE addr_minus_two 83 org addr - BIOS_FIX_BASE - 2 84 db 'XM' 85 BIOSORG_CHECK addr 86 endm 87 87 88 88 ;; Set an interrupt vector (not very efficient if multiple vectors are 89 89 ;; programmed in one go) 90 SET_INT_VECTOR macrovec, segm, offs91 movax, offs92 movds:[vec*4], ax93 movax, segm94 movds:[vec*4+2], ax90 SET_INT_VECTOR macro vec, segm, offs 91 mov ax, offs 92 mov ds:[vec*4], ax 93 mov ax, segm 94 mov ds:[vec*4+2], ax 95 95 endm 96 96 97 97 ; Set up an environment C code expects. DS must point to the BIOS segment 98 98 ; and the direction flag must be cleared(!) 99 C_SETUP 100 pushcs101 popds102 99 C_SETUP macro 100 push cs 101 pop ds 102 cld 103 103 endm 104 104 105 105 106 106 ;; External function in separate modules 107 extrn 108 extrn 109 extrn 110 extrn 111 extrn 112 extrn 113 extrn 114 extrn 115 extrn 116 extrn 117 extrn 118 extrn 119 extrn 120 extrn 121 extrn 122 extrn 123 extrn 124 extrn 125 extrn 126 extrn 127 extrn 128 extrn 129 extrn 130 extrn 131 extrn 132 extrn 133 extrn 134 extrn 135 extrn 136 extrn 137 extrn 138 extrn 139 extrn 107 extrn _dummy_isr_function:near 108 extrn _log_bios_start:near 109 extrn _nmi_handler_msg:near 110 extrn _int18_panic_msg:near 111 extrn _int09_function:near 112 extrn _int13_diskette_function:near 113 extrn _int13_eltorito:near 114 extrn _int13_cdemu:near 115 extrn _int13_cdrom:near 116 extrn _cdemu_isactive:near 117 extrn _cdemu_emulated_drive:near 118 extrn _int13_harddisk:near 119 extrn _int13_harddisk_ext:near 120 extrn _int14_function:near 121 extrn _int15_function:near 122 extrn _int15_function_mouse:near 123 extrn _int15_function32:near 124 extrn _int16_function:near 125 extrn _int17_function:near 126 extrn _int19_function:near 127 extrn _int1a_function:near 128 extrn _pci16_function:near 129 extrn _int70_function:near 130 extrn _int74_function:near 131 extrn _apm_function:near 132 extrn _ata_init:near 133 extrn _scsi_init:near 134 extrn _ata_detect:near 135 extrn _cdemu_init:near 136 extrn _keyboard_init:near 137 extrn _print_bios_banner:near 138 extrn _inv_op_handler:near 139 extrn rom_scan_:near 140 140 ifdef VBOX_WITH_AHCI 141 extrn 141 extrn _ahci_init:near 142 142 endif 143 143 if VBOX_BIOS_CPU ge 80286 144 extrn 144 extrn _int15_blkmove:near 145 145 endif 146 146 if VBOX_BIOS_CPU ge 80386 147 extrn 147 extrn _apic_setup:near 148 148 endif 149 149 150 150 151 151 ;; Symbols referenced from C code 152 public 153 public 154 public 155 public 156 public 157 public 152 public _diskette_param_table 153 public _pmode_IDT 154 public _rmode_IDT 155 public post 156 public eoi_both_pics 157 public rtc_post 158 158 159 159 ;; Additional publics for easier disassembly and debugging 160 160 ifndef DEBUG 161 DEBUG equ1162 endif 163 ifdef 164 165 public 166 public 167 public 168 public 169 public 170 public 161 DEBUG equ 1 162 endif 163 ifdef DEBUG 164 165 public int08_handler 166 public int0e_handler 167 public int11_handler 168 public int12_handler 169 public int13_handler 170 public int13_relocated 171 171 if VBOX_BIOS_CPU eq 8086 172 public 173 endif 174 public 175 public 176 public 177 public 178 public 179 public 180 public 181 public 182 public 183 public 184 public 185 public 186 public 187 public 188 public 189 public 190 public 191 public 192 public 193 public 194 public 195 public 196 public 197 public 198 public 199 public 200 public 201 public 202 public 203 public 204 public 205 public 206 public 207 public 208 public 172 public jmp_call_ret_int13_out 173 endif 174 public int15_handler 175 public int17_handler 176 public int19_handler 177 public int19_relocated 178 public dummy_iret 179 public nmi 180 public rom_fdpt 181 public cpu_reset 182 public normal_post 183 public eoi_jmp_post 184 public no_eoi_jmp_post 185 public eoi_master_pic 186 public ebda_post 187 public seg_40_value 188 public hard_drive_post 189 public int13_legacy 190 public int70_handler 191 public int75_handler 192 public int15_handler32 193 public int15_handler_mouse 194 public iret_modify_cf 195 public init_pic 196 public floppy_post 197 public int13_out 198 public int13_disk 199 public int13_notfloppy 200 public int13_legacy 201 public int13_noeltorito 202 public int1c_handler 203 public int10_handler 204 public int74_handler 205 public int76_handler 206 public detect_parport 207 public detect_serial 208 public font8x8 209 209 210 210 endif … … 217 217 SET_DEFAULT_CPU_286 218 218 219 BIOSSEG segment'CODE'220 assumecs:BIOSSEG219 BIOSSEG segment 'CODE' 220 assume cs:BIOSSEG 221 221 222 222 ;; 223 223 ;; Start of fixed code - eoi_jmp_post is kept near here to allow short jumps. 224 224 ;; 225 BIOSORG0E030h, 0E02Eh225 BIOSORG 0E030h, 0E02Eh 226 226 eoi_both_pics: 227 moval, PIC_CMD_EOI228 outPIC_SLAVE, al227 mov al, PIC_CMD_EOI 228 out PIC_SLAVE, al 229 229 eoi_master_pic: 230 moval, PIC_CMD_EOI231 outPIC_MASTER, al232 233 234 235 236 237 set_int_vects procnear238 239 mov[bx], ax240 mov[bx+2], dx241 addbx, 4242 loopset_int_vects243 244 245 set_int_vects 230 mov al, PIC_CMD_EOI 231 out PIC_MASTER, al 232 ret 233 234 ;; routine to write the pointer in DX:AX to memory starting 235 ;; at DS:BX (repeat CX times) 236 ;; - modifies BX, CX 237 set_int_vects proc near 238 239 mov [bx], ax 240 mov [bx+2], dx 241 add bx, 4 242 loop set_int_vects 243 ret 244 245 set_int_vects endp 246 246 247 247 eoi_jmp_post: 248 calleoi_both_pics248 call eoi_both_pics 249 249 no_eoi_jmp_post: 250 xorax, ax251 movds, ax252 jmpdword ptr ds:[0467h]253 254 seg_40_value: 250 xor ax, ax 251 mov ds, ax 252 jmp dword ptr ds:[0467h] 253 254 seg_40_value: dw 40h ;; Replaces a push 40; pop ds. 255 255 256 256 ;; -------------------------------------------------------- 257 257 ;; POST entry point 258 258 ;; -------------------------------------------------------- 259 BIOSORG0E05Bh, 0E059h259 BIOSORG 0E05Bh, 0E059h 260 260 post: 261 261 cli 262 262 263 263 if VBOX_BIOS_CPU ge 80286 264 265 264 ;; Check if in protected (V86) mode. If so, the CPU needs 265 ;; to be reset. 266 266 .286p 267 smswax268 testax, 1269 jzin_real_mode270 267 smsw ax 268 test ax, 1 269 jz in_real_mode 270 SET_DEFAULT_CPU_286 271 271 else 272 jmpin_real_mode273 endif 274 275 276 272 jmp in_real_mode 273 endif 274 275 ;; Reset processor to get out of protected mode. Use system 276 ;; port instead of KBC. 277 277 reset_sys: 278 moval, 1279 out92h, al280 jmp $; not strictly necessary in a VM281 282 278 mov al, 1 279 out 92h, al 280 jmp $ ; not strictly necessary in a VM 281 282 283 283 in_real_mode: 284 285 moval, 0Fh286 outCMOS_ADDR, al287 inal, CMOS_DATA288 289 290 xchgah, al291 292 293 294 inal, 64h295 test al, 4; clear flag indicates cold boot296 jzcont_post297 298 299 moval, ah300 oral, al301 jnzcont_post302 303 304 305 306 284 ;; read the CMOS shutdown status 285 mov al, 0Fh 286 out CMOS_ADDR, al 287 in al, CMOS_DATA 288 289 ;; save status 290 xchg ah, al 291 292 ;; Check KBC self-test/shutdown flag. If it is set, we need 293 ;; to check for a reboot attempt. 294 in al, 64h 295 test al, 4 ; clear flag indicates cold boot 296 jz cont_post 297 298 ;; Warm boot, check the shutdown byte. 299 mov al, ah 300 or al, al 301 jnz cont_post 302 303 ;; Warm boot but shutdown byte is zero. This is either a warm 304 ;; boot request or an attempt to reset the system via triple 305 ;; faulting the CPU or similar. Check reboot flag. 306 ;; NB: At this point, registers need not be preserved. 307 307 mov ds, cs:[seg_40_value] 308 cmpword ptr ds:[72h], 1234h309 jnz reset_sys; trigger system reset308 cmp word ptr ds:[72h], 1234h 309 jnz reset_sys ; trigger system reset 310 310 311 311 cont_post: 312 313 moval, 0Fh314 outCMOS_ADDR, al315 moval, 0316 outCMOS_DATA, al317 318 319 320 moval, ah321 cmpal, 09h322 jzcheck_shutdown323 cmpal, 0Ah324 jzcheck_shutdown325 326 xoral, al327 328 329 out00Dh, al330 out0DAh, al331 332 333 moval, 0C0h334 out 0D6h, al; enable channel 4 cascade335 moval, 0336 out 0D4h, al; unmask channel 4312 ;; reset the shutdown status in CMOS 313 mov al, 0Fh 314 out CMOS_ADDR, al 315 mov al, 0 316 out CMOS_DATA, al 317 318 ;; pre-check the shutdown status - shutdown codes 9/A leave 319 ;; the hardware alone 320 mov al, ah 321 cmp al, 09h 322 jz check_shutdown 323 cmp al, 0Ah 324 jz check_shutdown 325 326 xor al, al 327 328 ;; reset the DMA controllers 329 out 00Dh, al 330 out 0DAh, al 331 332 ;; then initialize the DMA controllers 333 mov al, 0C0h 334 out 0D6h, al ; enable channel 4 cascade 335 mov al, 0 336 out 0D4h, al ; unmask channel 4 337 337 338 338 check_shutdown: 339 340 moval, ah341 cmpal, 0342 jznormal_post343 344 cmpal, 0Dh345 jaenormal_post346 cmpal, 9347 jnecheck_next_std348 jmpreturn_blkmove349 check_next_std: 350 351 352 cmpal, 5353 jeeoi_jmp_post354 355 cmpal, 0ah356 jeno_eoi_jmp_post357 358 359 360 jmpnormal_post339 ;; examine the shutdown status code 340 mov al, ah 341 cmp al, 0 342 jz normal_post 343 344 cmp al, 0Dh 345 jae normal_post 346 cmp al, 9 347 jne check_next_std 348 jmp return_blkmove 349 check_next_std: 350 351 ;; 05h = EOI + jump through 40:67 352 cmp al, 5 353 je eoi_jmp_post 354 ;; 0ah = jump through 40:67 (no EOI) ;ba x 1 %fe05b ; ba x 1 %18b81 355 cmp al, 0ah 356 je no_eoi_jmp_post 357 358 ;; any other shutdown status values are ignored 359 ;; OpenSolaris sets the status to 0Ah in some cases? 360 jmp normal_post 361 361 362 362 normal_post: 363 364 365 366 367 368 369 movax, 7800h370 movsp, ax371 xorax, ax372 movds, ax373 movss, ax374 375 376 377 moves, ax378 xordi, di379 380 movcx, 0472h / 2381 repstosw382 incdi383 incdi384 movcx, (1000h - 0472h - 2) / 2385 repstosw386 387 388 389 xorbx, bx363 ;; shutdown code 0: normal startup 364 365 ;; Set up the stack top at 0:7800h. The stack should not be 366 ;; located above 0:7C00h; that conflicts with PXE, which 367 ;; considers anything above that address to be fair game. 368 ;; The traditional locations are 30:100 (PC) or 0:400 (PC/AT). 369 mov ax, 7800h 370 mov sp, ax 371 xor ax, ax 372 mov ds, ax 373 mov ss, ax 374 375 ;; clear the bottom of memory except for the word at 40:72 376 ;; TODO: Why not clear all of it? What's the point? 377 mov es, ax 378 xor di, di 379 cld 380 mov cx, 0472h / 2 381 rep stosw 382 inc di 383 inc di 384 mov cx, (1000h - 0472h - 2) / 2 385 rep stosw 386 387 ;; clear the remaining base memory except for the top 388 ;; of the EBDA (the MP table is planted there) 389 xor bx, bx 390 390 memory_zero_loop: 391 addbx, 1000h392 cmpbx, 9000h393 jaememory_cleared394 moves, bx395 xordi, di396 mov cx, 8000h; 32K words397 repstosw398 jmpmemory_zero_loop391 add bx, 1000h 392 cmp bx, 9000h 393 jae memory_cleared 394 mov es, bx 395 xor di, di 396 mov cx, 8000h ; 32K words 397 rep stosw 398 jmp memory_zero_loop 399 399 memory_cleared: 400 moves, bx401 xordi, di402 mov cx, 7FF8h; all but the last 16 bytes403 repstosw404 xorbx, bx405 406 407 408 call_log_bios_start400 mov es, bx 401 xor di, di 402 mov cx, 7FF8h ; all but the last 16 bytes 403 rep stosw 404 xor bx, bx 405 406 407 C_SETUP 408 call _log_bios_start 409 409 410 410 if VBOX_BIOS_CPU ge 80386 411 callpmode_setup412 endif 413 414 415 xorbx, bx416 movds, bx417 mov cx, 60h; leave the rest as zeros418 movax, dummy_iret419 movdx, BIOSSEG420 callset_int_vects421 422 423 424 425 movbx, 68h * 4426 movcx, 10h427 callset_int_vects428 429 430 movax, BASE_MEM_IN_K431 movds:[413h], ax432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 callebda_post448 449 411 call pmode_setup 412 endif 413 414 ;; set all interrupts in 00h-5Fh range to default handler 415 xor bx, bx 416 mov ds, bx 417 mov cx, 60h ; leave the rest as zeros 418 mov ax, dummy_iret 419 mov dx, BIOSSEG 420 call set_int_vects 421 422 ;; also set 68h-77h to default handler; note that the 423 ;; 60h-67h range must contain zeros for certain programs 424 ;; to function correctly 425 mov bx, 68h * 4 426 mov cx, 10h 427 call set_int_vects 428 429 ;; base memory in K to 40:13 430 mov ax, BASE_MEM_IN_K 431 mov ds:[413h], ax 432 433 ;; manufacturing test at 40:12 434 ;; zeroed out above 435 436 ;; set up various service vectors 437 ;; TODO: This should use the table at FEF3h instead 438 SET_INT_VECTOR 06h, BIOSSEG, int06_handler 439 SET_INT_VECTOR 11h, BIOSSEG, int11_handler 440 SET_INT_VECTOR 12h, BIOSSEG, int12_handler 441 SET_INT_VECTOR 15h, BIOSSEG, int15_handler 442 SET_INT_VECTOR 17h, BIOSSEG, int17_handler 443 SET_INT_VECTOR 18h, BIOSSEG, int18_handler 444 SET_INT_VECTOR 19h, BIOSSEG, int19_handler 445 SET_INT_VECTOR 1Ch, BIOSSEG, int1c_handler 446 447 call ebda_post 448 449 ;; Initialize PCI devices. This can and should be done early. 450 450 if VBOX_BIOS_CPU ge 80386 ; (Impossible to do on 16-bit CPUs.) 451 callpcibios_init_iomem_bases452 callpcibios_init_irqs453 endif 454 455 456 457 458 mov al, 34h; timer 0, binary, 16-bit, mode 2459 out43h, al460 mov al, 0; max count -> ~18.2 Hz461 out40h, al462 out40h, al463 464 465 466 467 468 469 470 471 xorax, ax472 movds, ax473 474 mov ds:[417h], al; keyboard shift flags, set 1475 mov ds:[418h], al; keyboard shift flags, set 2476 mov ds:[419h], al; keyboard Alt-numpad work area477 mov ds:[471h], al; keyboard Ctrl-Break flag478 mov ds:[497h], al; keyboard status flags 4479 moval, 10h480 mov ds:[496h], al; keyboard status flags 3481 482 movbx, 1Eh483 mov ds:[41Ah], bx; keyboard buffer head484 mov ds:[41Ch], bx; keyboard buffer tail485 mov ds:[480h], bx; keyboard buffer start486 movbx, 3Eh487 mov ds:[482h], bx; keyboard buffer end488 489 490 moval, 14h491 outCMOS_ADDR, al492 inal, CMOS_DATA493 movds:[410h], al494 495 pushds496 497 498 499 500 movax, 0C000h501 movdx, 0C800h502 callrom_scan_503 504 505 call_keyboard_init506 popds507 508 509 510 xorax, ax511 movds, ax512 xorbx, bx513 mov cl, 14h; timeout value514 mov dx, 378h; parallel port 1515 calldetect_parport516 mov dx, 278h; parallel port 2517 calldetect_parport518 DO_shlbx, 0Eh519 mov ax, ds:[410h]; equipment word520 andax, 3FFFh521 or ax, bx; set number of parallel ports522 mov ds:[410h], ax; store in BDA523 524 525 526 527 528 xorbx, bx529 mov cl, 0Ah; timeout value530 mov dx, 3F8h; first serial address531 calldetect_serial532 mov dx, 2F8h; second serial address533 calldetect_serial534 mov dx, 3E8h; third serial address535 calldetect_serial536 mov dx, 2E8h; fourth serial address537 calldetect_serial538 DO_shlbx, 9539 mov ax, ds:[410h]; equipment word540 and ax, 0F1FFh; bits 9-11 determine serial ports541 orax, bx542 movds:[410h], ax543 544 545 SET_INT_VECTOR 4Ah, BIOSSEG, dummy_iret; TODO: redundant?546 547 548 callrtc_post549 550 jmpnorm_post_cont451 call pcibios_init_iomem_bases 452 call pcibios_init_irqs 453 endif 454 SET_INT_VECTOR 1Ah, BIOSSEG, int1a_handler 455 456 ;; PIT setup 457 SET_INT_VECTOR 08h, BIOSSEG, int08_handler 458 mov al, 34h ; timer 0, binary, 16-bit, mode 2 459 out 43h, al 460 mov al, 0 ; max count -> ~18.2 Hz 461 out 40h, al 462 out 40h, al 463 464 ;; video setup - must be done before POSTing VGA ROM 465 SET_INT_VECTOR 10h, BIOSSEG, int10_handler 466 467 ;; keyboard setup 468 SET_INT_VECTOR 09h, BIOSSEG, int09_handler 469 SET_INT_VECTOR 16h, BIOSSEG, int16_handler 470 471 xor ax, ax 472 mov ds, ax 473 ;; TODO: What's the point? The BDA is zeroed already?! 474 mov ds:[417h], al ; keyboard shift flags, set 1 475 mov ds:[418h], al ; keyboard shift flags, set 2 476 mov ds:[419h], al ; keyboard Alt-numpad work area 477 mov ds:[471h], al ; keyboard Ctrl-Break flag 478 mov ds:[497h], al ; keyboard status flags 4 479 mov al, 10h 480 mov ds:[496h], al ; keyboard status flags 3 481 482 mov bx, 1Eh 483 mov ds:[41Ah], bx ; keyboard buffer head 484 mov ds:[41Ch], bx ; keyboard buffer tail 485 mov ds:[480h], bx ; keyboard buffer start 486 mov bx, 3Eh 487 mov ds:[482h], bx ; keyboard buffer end 488 489 ;; store CMOS equipment byte in BDA 490 mov al, 14h 491 out CMOS_ADDR, al 492 in al, CMOS_DATA 493 mov ds:[410h], al 494 495 push ds 496 C_SETUP 497 498 ;; Scan for video ROMs in the C000-C800 range. This is done 499 ;; early so that errors are displayed on the screen. 500 mov ax, 0C000h 501 mov dx, 0C800h 502 call rom_scan_ 503 504 ;; Initialize the keyboard 505 call _keyboard_init 506 pop ds 507 508 ;; parallel setup 509 SET_INT_VECTOR 0Fh, BIOSSEG, dummy_iret 510 xor ax, ax 511 mov ds, ax 512 xor bx, bx 513 mov cl, 14h ; timeout value 514 mov dx, 378h ; parallel port 1 515 call detect_parport 516 mov dx, 278h ; parallel port 2 517 call detect_parport 518 DO_shl bx, 0Eh 519 mov ax, ds:[410h] ; equipment word 520 and ax, 3FFFh 521 or ax, bx ; set number of parallel ports 522 mov ds:[410h], ax ; store in BDA 523 524 ;; Serial setup 525 SET_INT_VECTOR 0Bh, BIOSSEG, dummy_isr 526 SET_INT_VECTOR 0Ch, BIOSSEG, dummy_isr 527 SET_INT_VECTOR 14h, BIOSSEG, int14_handler 528 xor bx, bx 529 mov cl, 0Ah ; timeout value 530 mov dx, 3F8h ; first serial address 531 call detect_serial 532 mov dx, 2F8h ; second serial address 533 call detect_serial 534 mov dx, 3E8h ; third serial address 535 call detect_serial 536 mov dx, 2E8h ; fourth serial address 537 call detect_serial 538 DO_shl bx, 9 539 mov ax, ds:[410h] ; equipment word 540 and ax, 0F1FFh ; bits 9-11 determine serial ports 541 or ax, bx 542 mov ds:[410h], ax 543 544 ;; CMOS RTC 545 SET_INT_VECTOR 4Ah, BIOSSEG, dummy_iret ; TODO: redundant? 546 SET_INT_VECTOR 70h, BIOSSEG, int70_handler 547 ;; BIOS DATA AREA 4CEh ??? 548 call rtc_post 549 550 jmp norm_post_cont 551 551 552 552 … … 554 554 ;; NMI handler 555 555 ;; -------------------------------------------------------- 556 BIOSORG0E2C3h, 0E2C1h556 BIOSORG 0E2C3h, 0E2C1h 557 557 nmi: 558 559 call_nmi_handler_msg560 558 C_SETUP 559 call _nmi_handler_msg 560 iret 561 561 562 562 int75_handler: 563 out 0F0h, al; clear IRQ13564 calleoi_both_pics565 int 2; emulate legacy NMI566 567 568 569 hard_drive_post procnear570 571 xorax, ax572 movds, ax573 574 mov ds:[474h], al; last HD operation status575 mov ds:[477h], al; HD port offset (XT only???)576 mov ds:[48Ch], al; HD status register577 mov ds:[48Dh], al; HD error register578 mov ds:[48Eh], al; HD task complete flag579 moval, 0C0h580 mov ds:[476h], al; HD control byte581 582 583 584 585 586 587 588 589 590 591 hard_drive_post 563 out 0F0h, al ; clear IRQ13 564 call eoi_both_pics 565 int 2 ; emulate legacy NMI 566 iret 567 568 569 hard_drive_post proc near 570 571 xor ax, ax 572 mov ds, ax 573 ;; TODO: Didn't we just clear the entire EBDA? 574 mov ds:[474h], al ; last HD operation status 575 mov ds:[477h], al ; HD port offset (XT only???) 576 mov ds:[48Ch], al ; HD status register 577 mov ds:[48Dh], al ; HD error register 578 mov ds:[48Eh], al ; HD task complete flag 579 mov al, 0C0h 580 mov ds:[476h], al ; HD control byte 581 ;; set up hard disk interrupt vectors 582 SET_INT_VECTOR 13h, BIOSSEG, int13_handler 583 SET_INT_VECTOR 76h, BIOSSEG, int76_handler 584 ;; INT 41h/46h: hard disk 0/1 dpt 585 ; TODO: This should be done from the code which 586 ; builds the DPTs? 587 SET_INT_VECTOR 41h, EBDA_SEG, 3Dh 588 SET_INT_VECTOR 46h, EBDA_SEG, 4Dh 589 ret 590 591 hard_drive_post endp 592 592 593 593 594 594 norm_post_cont: 595 596 597 598 599 600 601 callinit_pic602 603 595 ;; PS/2 mouse setup 596 SET_INT_VECTOR 74h, BIOSSEG, int74_handler 597 598 ;; IRQ 13h (FPU exception) setup 599 SET_INT_VECTOR 75h, BIOSSEG, int75_handler 600 601 call init_pic 602 603 C_SETUP 604 604 605 605 if VBOX_BIOS_CPU ge 80386 606 607 608 609 call_apic_setup610 611 612 endif 613 614 615 call_ata_init616 call_ata_detect606 ;; Set up local APIC 607 .386 608 pushad 609 call _apic_setup 610 popad 611 SET_DEFAULT_CPU_286 612 endif 613 614 ;; ATA/ATAPI driver setup 615 call _ata_init 616 call _ata_detect 617 617 618 618 ifdef VBOX_WITH_AHCI 619 620 call_ahci_init619 ; AHCI driver setup 620 call _ahci_init 621 621 endif 622 622 623 623 ifdef VBOX_WITH_SCSI 624 625 call_scsi_init626 endif 627 628 629 callfloppy_post630 631 632 callhard_drive_post633 634 C_SETUP; in case assembly code changed things635 636 movax, 0C800h637 movdx, 0F000h638 callrom_scan_639 640 call_print_bios_banner641 642 643 call_cdemu_init644 645 646 sti; enable interrupts647 int19h648 649 624 ; SCSI driver setup 625 call _scsi_init 626 endif 627 628 ;; floppy setup 629 call floppy_post 630 631 ;; hard drive setup 632 call hard_drive_post 633 634 C_SETUP ; in case assembly code changed things 635 ;; Scan for additional ROMs in the C800-EFFF range 636 mov ax, 0C800h 637 mov dx, 0F000h 638 call rom_scan_ 639 640 call _print_bios_banner 641 642 ;; El Torito floppy/hard disk emulation 643 call _cdemu_init 644 645 ; TODO: what's the point of enabling interrupts here?? 646 sti ; enable interrupts 647 int 19h 648 ;; does not return here 649 sti 650 650 wait_forever: 651 652 jmpwait_forever653 654 655 651 hlt 652 jmp wait_forever 653 cli 654 hlt 655 656 656 657 657 ;; … … 660 660 ;; 661 661 return_blkmove: 662 663 movax, 40h664 movds, ax665 666 movss, ds:[69h]667 movsp, ds:[67h]668 669 inal, 92h670 andal, 0FDh671 out92h, al672 673 lidtfword ptr cs:_rmode_IDT674 675 popds676 popes677 678 movbp, sp679 680 inal, 80h681 mov[bp+15], al682 683 cmp ah,al; AH is zero here!684 685 686 687 retf2688 662 .286p 663 mov ax, 40h 664 mov ds, ax 665 ;; restore user stack 666 mov ss, ds:[69h] 667 mov sp, ds:[67h] 668 ;; reset A20 gate 669 in al, 92h 670 and al, 0FDh 671 out 92h, al 672 ;; ensure proper real mode IDT 673 lidt fword ptr cs:_rmode_IDT 674 ;; restore user segments 675 pop ds 676 pop es 677 ;; set up BP 678 mov bp, sp 679 ;; restore status code 680 in al, 80h 681 mov [bp+15], al 682 ;; set ZF/CF 683 cmp ah,al ; AH is zero here! 684 ;; restore registers and return 685 popa 686 sti 687 retf 2 688 SET_DEFAULT_CPU_286 689 689 690 690 … … 692 692 ;; INT 13h handler - Disk services 693 693 ;; -------------------------------------------------------- 694 BIOSORG0E3FEh, 0E3FCh694 BIOSORG 0E3FEh, 0E3FCh 695 695 696 696 int13_handler: 697 jmpint13_relocated697 jmp int13_relocated 698 698 699 699 … … 701 701 ;; Fixed Disk Parameter Table 702 702 ;; -------------------------------------------------------- 703 BIOSORG_CHECK 0E401h; fixed wrt preceding703 BIOSORG_CHECK 0E401h ; fixed wrt preceding 704 704 705 705 rom_fdpt: … … 708 708 ;; INT 19h handler - Boot load service 709 709 ;; -------------------------------------------------------- 710 BIOSORG0E6F2h, 0E6F0h710 BIOSORG 0E6F2h, 0E6F0h 711 711 712 712 int19_handler: 713 jmpint19_relocated713 jmp int19_relocated 714 714 715 715 … … 718 718 ;; System BIOS Configuration Table 719 719 ;; -------------------------------------------------------- 720 BIOSORG_CHECK 0E6F5h; fixed wrt preceding720 BIOSORG_CHECK 0E6F5h ; fixed wrt preceding 721 721 ; must match BIOS_CONFIG_TABLE 722 722 bios_cfg_table: 723 dw 9; table size in bytes724 dbSYS_MODEL_ID725 dbSYS_SUBMODEL_ID726 dbBIOS_REVISION727 728 729 730 731 732 733 734 735 723 dw 9 ; table size in bytes 724 db SYS_MODEL_ID 725 db SYS_SUBMODEL_ID 726 db BIOS_REVISION 727 ; Feature byte 1 728 ; b7: 1=DMA channel 3 used by hard disk 729 ; b6: 1=2 interrupt controllers present 730 ; b5: 1=RTC present 731 ; b4: 1=BIOS calls int 15h/4Fh for every key 732 ; b3: 1=wait for extern event supported (Int 15h/41h) 733 ; b2: 1=extended BIOS data area used 734 ; b1: 0=AT or ESDI bus, 1=MicroChannel 735 ; b0: 1=Dual bus (MicroChannel + ISA) 736 736 ifdef BX_CALL_INT15_4F 737 db74h; or USE_EBDA737 db 74h; or USE_EBDA 738 738 else 739 db64h; or USE_EBDA740 endif 741 742 743 744 745 746 747 748 749 750 db40h751 752 753 754 755 756 757 758 759 760 db0761 762 763 764 765 766 767 768 db0769 770 771 772 db0739 db 64h; or USE_EBDA 740 endif 741 ; Feature byte 2 742 ; b7: 1=32-bit DMA supported 743 ; b6: 1=int16h, function 9 supported 744 ; b5: 1=int15h/C6h (get POS data) supported 745 ; b4: 1=int15h/C7h (get mem map info) supported 746 ; b3: 1=int15h/C8h (en/dis CPU) supported 747 ; b2: 1=non-8042 kb controller 748 ; b1: 1=data streaming supported 749 ; b0: reserved 750 db 40h 751 ; Feature byte 3 752 ; b7: not used 753 ; b6: reserved 754 ; b5: reserved 755 ; b4: POST supports ROM-to-RAM enable/disable 756 ; b3: SCSI on system board 757 ; b2: info panel installed 758 ; b1: Initial Machine Load (IML) system - BIOS on disk 759 ; b0: SCSI supported in IML 760 db 0 761 ; Feature byte 4 762 ; b7: IBM private 763 ; b6: EEPROM present 764 ; b5-3: ABIOS presence (011 = not supported) 765 ; b2: private 766 ; b1: memory split above 16Mb supported 767 ; b0: POSTEXT directly supported by POST 768 db 0 769 ; Feature byte 5 (IBM) 770 ; b1: enhanced mouse 771 ; b0: flash EPROM 772 db 0 773 773 774 774 … … 776 776 ;; Baud Rate Generator Table 777 777 ;; -------------------------------------------------------- 778 BIOSORG0E729h, 0E727h778 BIOSORG 0E729h, 0E727h 779 779 780 780 … … 782 782 ;; INT 14h handler - Serial Communication Service 783 783 ;; -------------------------------------------------------- 784 BIOSORG0E739h, 0E737h784 BIOSORG 0E739h, 0E737h 785 785 int14_handler: 786 pushds787 pushes788 789 790 call_int14_function791 792 popes793 popds794 786 push ds 787 push es 788 DO_pusha 789 C_SETUP 790 call _int14_function 791 DO_popa 792 pop es 793 pop ds 794 iret 795 795 796 796 … … 800 800 ;; 801 801 dummy_isr: 802 pushds803 pushes804 805 806 call_dummy_isr_function807 808 popes809 popds810 811 812 813 init_pic procnear814 815 mov al, 11h; send init commands816 outPIC_MASTER, al817 outPIC_SLAVE, al818 mov al, 08h; base 08h819 outPIC_MASTER+1, al820 mov al, 70h; base 70h821 outPIC_SLAVE+1, al822 mov al, 04h; master PIC823 outPIC_MASTER+1, al824 mov al, 02h; slave PIC825 outPIC_SLAVE+1, al826 moval, 01h827 outPIC_MASTER+1, al828 outPIC_SLAVE+1, al829 mov al, 0B8h; unmask IRQs 0/1/2/6830 outPIC_MASTER+1, al831 moval, 08Fh832 out PIC_SLAVE+1, al; unmask IRQs 12/13/14833 834 835 init_pic 836 837 ebda_post procnear838 839 SET_INT_VECTOR 0Dh, BIOSSEG, dummy_isr; IRQ 5840 SET_INT_VECTOR 0Fh, BIOSSEG, dummy_isr; IRQ 7841 SET_INT_VECTOR 72h, BIOSSEG, dummy_isr; IRQ 11842 SET_INT_VECTOR 77h, BIOSSEG, dummy_isr; IRQ 15843 844 movax, EBDA_SEG845 movds, ax846 movbyte ptr ds:[0], EBDA_SIZE847 848 xorax, ax849 movds, ax850 movword ptr ds:[40Eh], EBDA_SEG851 852 853 ebda_post 802 push ds 803 push es 804 DO_pusha 805 C_SETUP 806 call _dummy_isr_function 807 DO_popa 808 pop es 809 pop ds 810 iret 811 812 813 init_pic proc near 814 815 mov al, 11h ; send init commands 816 out PIC_MASTER, al 817 out PIC_SLAVE, al 818 mov al, 08h ; base 08h 819 out PIC_MASTER+1, al 820 mov al, 70h ; base 70h 821 out PIC_SLAVE+1, al 822 mov al, 04h ; master PIC 823 out PIC_MASTER+1, al 824 mov al, 02h ; slave PIC 825 out PIC_SLAVE+1, al 826 mov al, 01h 827 out PIC_MASTER+1, al 828 out PIC_SLAVE+1, al 829 mov al, 0B8h ; unmask IRQs 0/1/2/6 830 out PIC_MASTER+1, al 831 mov al, 08Fh 832 out PIC_SLAVE+1, al ; unmask IRQs 12/13/14 833 ret 834 835 init_pic endp 836 837 ebda_post proc near 838 839 SET_INT_VECTOR 0Dh, BIOSSEG, dummy_isr ; IRQ 5 840 SET_INT_VECTOR 0Fh, BIOSSEG, dummy_isr ; IRQ 7 841 SET_INT_VECTOR 72h, BIOSSEG, dummy_isr ; IRQ 11 842 SET_INT_VECTOR 77h, BIOSSEG, dummy_isr ; IRQ 15 843 844 mov ax, EBDA_SEG 845 mov ds, ax 846 mov byte ptr ds:[0], EBDA_SIZE 847 ;; store EBDA seg in 40:0E 848 xor ax, ax 849 mov ds, ax 850 mov word ptr ds:[40Eh], EBDA_SEG 851 ret 852 853 ebda_post endp 854 854 855 855 … … 858 858 ;; INT 16h handler - Keyboard service 859 859 ;; -------------------------------------------------------- 860 BIOSORG0E82Eh, 0E82Ch860 BIOSORG 0E82Eh, 0E82Ch 861 861 int16_handler: 862 863 pushes864 pushds865 866 867 cmpah, 0868 jeint16_F00869 870 cmpah, 10h871 jeint16_F00872 873 874 call_int16_function875 876 popds877 popes878 862 sti 863 push es 864 push ds 865 DO_pusha 866 867 cmp ah, 0 868 je int16_F00 869 870 cmp ah, 10h 871 je int16_F00 872 873 C_SETUP 874 call _int16_function 875 DO_popa 876 pop ds 877 pop es 878 iret 879 879 880 880 int16_F00: 881 mov bx, 40h; TODO: why 40h here and 0 elsewhere?882 movds, bx881 mov bx, 40h ; TODO: why 40h here and 0 elsewhere? 882 mov ds, bx 883 883 int16_wait_for_key: 884 885 movbx, ds:[1Ah]886 cmpbx, ds:[1Ch]887 jneint16_key_found888 889 884 cli 885 mov bx, ds:[1Ah] 886 cmp bx, ds:[1Ch] 887 jne int16_key_found 888 sti 889 nop 890 890 ; TODO: review/enable? 891 891 if 0 892 pushax893 movax, 9002h894 int15h895 popax896 endif 897 jmpint16_wait_for_key892 push ax 893 mov ax, 9002h 894 int 15h 895 pop ax 896 endif 897 jmp int16_wait_for_key 898 898 899 899 int16_key_found: 900 901 call_int16_function902 903 popds904 popes900 C_SETUP 901 call _int16_function 902 DO_popa 903 pop ds 904 pop es 905 905 ; TODO: review/enable? If so, flags should be restored here? 906 906 if 0 907 pushax908 movax, 9202h909 int15h910 popax911 endif 912 907 push ax 908 mov ax, 9202h 909 int 15h 910 pop ax 911 endif 912 iret 913 913 914 914 … … 922 922 923 923 924 KBDC_DISABLE EQU0ADh925 KBDC_ENABLE EQU0AEh926 KBC_CMD EQU64h927 KBC_DATA EQU60h924 KBDC_DISABLE EQU 0ADh 925 KBDC_ENABLE EQU 0AEh 926 KBC_CMD EQU 64h 927 KBC_DATA EQU 60h 928 928 929 929 ;; -------------------------------------------------------- 930 930 ;; INT 09h handler - Keyboard ISR (IRQ 1) 931 931 ;; -------------------------------------------------------- 932 BIOSORG0E987h, 0E985h932 BIOSORG 0E987h, 0E985h 933 933 int09_handler: 934 cli; TODO: why? they're off already!935 pushax936 moval, KBDC_DISABLE937 outKBC_CMD, al938 939 inal, KBC_DATA940 pushds941 942 cld; Before INT 15h (and any C code)934 cli ; TODO: why? they're off already! 935 push ax 936 mov al, KBDC_DISABLE 937 out KBC_CMD, al 938 939 in al, KBC_DATA 940 push ds 941 DO_pusha 942 cld ; Before INT 15h (and any C code) 943 943 ifdef BX_CALL_INT15_4F 944 movah, 4Fh945 946 int 15h; keyboard intercept947 jncint09_done948 endif 949 sti; Only after calling INT 15h950 951 952 cmpal, 0E0h953 jneint09_check_pause954 xorax, ax955 movds, ax956 or byte ptr ds:[496h], 2; mf2_state |= 0x02957 jmpint09_done944 mov ah, 4Fh 945 stc 946 int 15h ; keyboard intercept 947 jnc int09_done 948 endif 949 sti ; Only after calling INT 15h 950 951 ;; check for extended key 952 cmp al, 0E0h 953 jne int09_check_pause 954 xor ax, ax 955 mov ds, ax 956 or byte ptr ds:[496h], 2 ; mf2_state |= 0x02 957 jmp int09_done 958 958 959 959 int09_check_pause: 960 cmp al, 0E1h; pause key?961 jneint09_process_key962 xorax, ax963 movds, ax964 or byte ptr ds:[496h], 1; mf2_state | 0x01965 jmpint09_done960 cmp al, 0E1h ; pause key? 961 jne int09_process_key 962 xor ax, ax 963 mov ds, ax 964 or byte ptr ds:[496h], 1 ; mf2_state | 0x01 965 jmp int09_done 966 966 967 967 int09_process_key: 968 pushes969 970 call_int09_function971 popes968 push es 969 C_SETUP 970 call _int09_function 971 pop es 972 972 973 973 int09_done: 974 975 popds976 977 calleoi_master_pic978 979 moval, KBDC_ENABLE980 outKBC_CMD, al981 popax982 974 DO_popa 975 pop ds 976 cli 977 call eoi_master_pic 978 979 mov al, KBDC_ENABLE 980 out KBC_CMD, al 981 pop ax 982 iret 983 983 984 984 … … 988 988 989 989 int06_handler: 990 991 pushes992 pushds993 994 call_inv_op_handler995 popds996 popes997 998 990 DO_pusha 991 push es 992 push ds 993 C_SETUP 994 call _inv_op_handler 995 pop ds 996 pop es 997 DO_popa 998 iret 999 999 1000 1000 ;; -------------------------------------------------------- 1001 1001 ;; INT 13h handler - Diskette service 1002 1002 ;; -------------------------------------------------------- 1003 BIOSORG0EC59h, 0EC57h1003 BIOSORG 0EC59h, 0EC57h 1004 1004 int13_diskette: 1005 jmpint13_noeltorito1005 jmp int13_noeltorito 1006 1006 1007 1007 … … 1011 1011 ;; -------------------------------------------------------- 1012 1012 int13_relocated: 1013 1014 cmpah, 4Ah1015 jbint13_not_eltorito1016 1017 cmpah, 4Dh1018 jaint13_not_eltorito1019 1020 1021 pushes1022 pushds1023 C_SETUP; TODO: setup C envrionment only once?1024 1013 ;; check for an El-Torito function 1014 cmp ah, 4Ah 1015 jb int13_not_eltorito 1016 1017 cmp ah, 4Dh 1018 ja int13_not_eltorito 1019 1020 DO_pusha 1021 push es 1022 push ds 1023 C_SETUP ; TODO: setup C envrionment only once? 1024 DO_JMP_CALL_EX _int13_eltorito, int13_out, jmp_call_ret_int13_out ; ELDX not used 1025 1025 if VBOX_BIOS_CPU eq 8086 1026 1026 jmp_call_ret_int13_out: dw offset int13_out … … 1028 1028 1029 1029 int13_not_eltorito: 1030 pushes1031 push ax; TODO: better register save/restore1032 pushbx1033 pushcx1034 pushdx1035 1036 1037 call_cdemu_isactive1038 cmpal, 01039 jeint13_cdemu_inactive1040 1041 1042 call_cdemu_emulated_drive1043 pop dx; recover dx (destroyed by C code)1044 pushdx1045 cmp al, dl; INT 13h on emulated drive1046 jneint13_nocdemu1047 1048 popdx1049 popcx1050 popbx1051 popax1052 popes1053 1054 1055 pushes1056 pushds1057 C_SETUP; TODO: setup environment only once?1058 1059 1030 push es 1031 push ax ; TODO: better register save/restore 1032 push bx 1033 push cx 1034 push dx 1035 1036 ;; check if emulation is active 1037 call _cdemu_isactive 1038 cmp al, 0 1039 je int13_cdemu_inactive 1040 1041 ;; check if access to the emulated drive 1042 call _cdemu_emulated_drive 1043 pop dx ; recover dx (destroyed by C code) 1044 push dx 1045 cmp al, dl ; INT 13h on emulated drive 1046 jne int13_nocdemu 1047 1048 pop dx 1049 pop cx 1050 pop bx 1051 pop ax 1052 pop es 1053 1054 DO_pusha 1055 push es 1056 push ds 1057 C_SETUP ; TODO: setup environment only once? 1058 1059 DO_JMP_CALL_EX _int13_cdemu, int13_out, jmp_call_ret_int13_out ; ELDX not used 1060 1060 1061 1061 int13_nocdemu: 1062 and dl, 0E0h; mask to get device class1063 cmpal, dl1064 jneint13_cdemu_inactive1065 1066 popdx1067 popcx1068 popbx1069 popax1070 popes1071 1072 pushax1073 pushcx1074 pushdx1075 pushbx1076 1077 dec dl; real drive is dl - 11078 jmpint13_legacy1062 and dl, 0E0h ; mask to get device class 1063 cmp al, dl 1064 jne int13_cdemu_inactive 1065 1066 pop dx 1067 pop cx 1068 pop bx 1069 pop ax 1070 pop es 1071 1072 push ax 1073 push cx 1074 push dx 1075 push bx 1076 1077 dec dl ; real drive is dl - 1 1078 jmp int13_legacy 1079 1079 1080 1080 int13_cdemu_inactive: 1081 popdx1082 popcx1083 popbx1084 popax1085 popes1081 pop dx 1082 pop cx 1083 pop bx 1084 pop ax 1085 pop es 1086 1086 1087 1087 int13_noeltorito: 1088 pushax1089 pushcx1090 pushdx1091 pushbx1088 push ax 1089 push cx 1090 push dx 1091 push bx 1092 1092 int13_legacy: 1093 push dx; push eltorito dx in place of sp1094 pushbp1095 pushsi1096 pushdi1097 pushes1098 pushds1099 C_SETUP; TODO: setup environment only once?1100 1101 1102 1103 test dl, 80h; non-removable?1104 jnzint13_notfloppy1105 1106 1093 push dx ; push eltorito dx in place of sp 1094 push bp 1095 push si 1096 push di 1097 push es 1098 push ds 1099 C_SETUP ; TODO: setup environment only once? 1100 1101 ;; now the registers can be restored with 1102 ;; pop ds; pop es; DO_popa; iret 1103 test dl, 80h ; non-removable? 1104 jnz int13_notfloppy 1105 1106 DO_JMP_CALL_EX _int13_diskette_function, int13_out, jmp_call_ret_int13_out 1107 1107 1108 1108 int13_notfloppy: 1109 cmpdl, 0E0h1110 jbint13_notcdrom1111 1112 1113 1114 ;; @todo figure if 80286/8086 variant is applicable.1115 1116 shrebx, 161117 pushbx1118 call_int13_cdrom1119 popbx1120 shlebx, 161121 1122 jmpint13_out1109 cmp dl, 0E0h 1110 jb int13_notcdrom 1111 1112 ;; ebx may be modified, save here 1113 ;; TODO: check/review 32-bit register use 1114 ;; @todo figure if 80286/8086 variant is applicable. 1115 .386 1116 shr ebx, 16 1117 push bx 1118 call _int13_cdrom 1119 pop bx 1120 shl ebx, 16 1121 SET_DEFAULT_CPU_286 1122 jmp int13_out 1123 1123 1124 1124 int13_notcdrom: 1125 1125 int13_disk: 1126 cmpah,40h1127 jaint13x1128 call_int13_harddisk1129 jmpint13_out1126 cmp ah,40h 1127 ja int13x 1128 call _int13_harddisk 1129 jmp int13_out 1130 1130 1131 1131 int13x: 1132 call_int13_harddisk_ext1132 call _int13_harddisk_ext 1133 1133 1134 1134 int13_out: 1135 popds1136 popes1137 1138 1135 pop ds 1136 pop es 1137 DO_popa 1138 iret 1139 1139 1140 1140 1141 1141 1142 1142 ; parallel port detection: port in dx, index in bx, timeout in cl 1143 detect_parport procnear1144 1145 pushdx1146 incdx1147 incdx1148 inal, dx1149 and al, 0DFh; clear input mode1150 outdx, al1151 popdx1152 moval, 0AAh1153 outdx, al1154 inal, dx1155 cmpal, 0AAh1156 jneno_parport1157 1158 pushbx1159 shlbx, 11160 mov [bx+408h], dx; parallel I/O address1161 popbx1162 mov [bx+478h], cl; parallel printer timeout1163 incbx1143 detect_parport proc near 1144 1145 push dx 1146 inc dx 1147 inc dx 1148 in al, dx 1149 and al, 0DFh ; clear input mode 1150 out dx, al 1151 pop dx 1152 mov al, 0AAh 1153 out dx, al 1154 in al, dx 1155 cmp al, 0AAh 1156 jne no_parport 1157 1158 push bx 1159 shl bx, 1 1160 mov [bx+408h], dx ; parallel I/O address 1161 pop bx 1162 mov [bx+478h], cl ; parallel printer timeout 1163 inc bx 1164 1164 no_parport: 1165 1166 1167 detect_parport 1165 ret 1166 1167 detect_parport endp 1168 1168 1169 1169 ; setial port detection: port in dx, index in bx, timeout in cl 1170 detect_serial procnear1171 1172 pushdx1173 incdx1174 moval, 21175 outdx, al1176 inal, dx1177 cmpal, 21178 jneno_serial1179 1180 incdx1181 inal, dx1182 cmpal, 21183 jneno_serial1184 1185 decdx1186 xoral, al1187 popdx1188 pushbx1189 shlbx, 11190 mov [bx+400h], dx; serial I/O address1191 popbx1192 mov [bx+47Ch], cl; serial timeout1193 incbx1194 1170 detect_serial proc near 1171 1172 push dx 1173 inc dx 1174 mov al, 2 1175 out dx, al 1176 in al, dx 1177 cmp al, 2 1178 jne no_serial 1179 1180 inc dx 1181 in al, dx 1182 cmp al, 2 1183 jne no_serial 1184 1185 dec dx 1186 xor al, al 1187 pop dx 1188 push bx 1189 shl bx, 1 1190 mov [bx+400h], dx ; serial I/O address 1191 pop bx 1192 mov [bx+47Ch], cl ; serial timeout 1193 inc bx 1194 ret 1195 1195 1196 1196 no_serial: 1197 popdx1198 1199 1200 detect_serial 1197 pop dx 1198 ret 1199 1200 detect_serial endp 1201 1201 1202 1202 … … 1204 1204 ;; POST: Floppy drive 1205 1205 ;; 1206 floppy_post procnear1207 1208 xorax, ax1209 movds, ax1210 1211 1212 1213 moval, 01214 mov ds:[43Eh], al; drive 0/1 uncalibrated, no IRQ1215 mov ds:[43Fh], al; motor status1216 mov ds:[440h], al; motor timeout counter1217 mov ds:[441h], al; controller status return code1218 mov ds:[442h], al; hd/floppy ctlr status register1219 mov ds:[443h], al; controller status register 11220 mov ds:[444h], al; controller status register 21221 mov ds:[445h], al; cylinder number1222 mov ds:[446h], al; head number1223 mov ds:[447h], al; sector number1224 mov ds:[448h], al; bytes written1225 1226 mov ds:[48Bh], al; configuration data1227 1228 mov al, 10h; floppy drive type1229 outCMOS_ADDR, al1230 inal, CMOS_DATA1231 mov ah, al; save drive type byte1206 floppy_post proc near 1207 1208 xor ax, ax 1209 mov ds, ax 1210 1211 ;; TODO: This code is really stupid. Zeroing the BDA byte 1212 ;; by byte is dumb, and it's been already zeroed elsewhere! 1213 mov al, 0 1214 mov ds:[43Eh], al ; drive 0/1 uncalibrated, no IRQ 1215 mov ds:[43Fh], al ; motor status 1216 mov ds:[440h], al ; motor timeout counter 1217 mov ds:[441h], al ; controller status return code 1218 mov ds:[442h], al ; hd/floppy ctlr status register 1219 mov ds:[443h], al ; controller status register 1 1220 mov ds:[444h], al ; controller status register 2 1221 mov ds:[445h], al ; cylinder number 1222 mov ds:[446h], al ; head number 1223 mov ds:[447h], al ; sector number 1224 mov ds:[448h], al ; bytes written 1225 1226 mov ds:[48Bh], al ; configuration data 1227 1228 mov al, 10h ; floppy drive type 1229 out CMOS_ADDR, al 1230 in al, CMOS_DATA 1231 mov ah, al ; save drive type byte 1232 1232 1233 1233 look_drive0: 1234 1235 DO_shr al, 4; drive 0 in high nibble1236 jz f0_missing; jump if no drive1237 mov bl, 7; drv0 determined, multi-rate, chgline1238 jmplook_drive11234 ; TODO: pre-init bl to reduce jumps 1235 DO_shr al, 4 ; drive 0 in high nibble 1236 jz f0_missing ; jump if no drive 1237 mov bl, 7 ; drv0 determined, multi-rate, chgline 1238 jmp look_drive1 1239 1239 1240 1240 f0_missing: 1241 mov bl, 0; no drive 01241 mov bl, 0 ; no drive 0 1242 1242 1243 1243 look_drive1: 1244 mov al, ah; restore CMOS data1245 and al, 0Fh; drive 1 in low nibble1246 jzf1_missing1247 or bl, 70h; drv1 determined, multi-rate, chgline1244 mov al, ah ; restore CMOS data 1245 and al, 0Fh ; drive 1 in low nibble 1246 jz f1_missing 1247 or bl, 70h ; drv1 determined, multi-rate, chgline 1248 1248 f1_missing: 1249 mov ds:[48Fh], bl; store in BDA1250 1251 1252 moval, 01253 mov ds:[490h], al; drv0 media state1254 mov ds:[491h], al; drv1 media state1255 mov ds:[492h], al; drv0 operational state1256 mov ds:[493h], al; drv1 operational state1257 mov ds:[494h], al; drv0 current cylinder1258 mov ds:[495h], al; drv1 current cylinder1259 1260 moval, 21261 out 0Ah, al; unmask DMA channel 21262 1263 1264 1265 SET_INT_VECTOR 0Eh, BIOSSEG, int0e_handler; IRQ 61266 1267 1268 1269 floppy_post 1270 1271 1272 bcd_to_bin procnear1273 1274 1275 1249 mov ds:[48Fh], bl ; store in BDA 1250 1251 ;; TODO: See above. Dumb *and* redundant! 1252 mov al, 0 1253 mov ds:[490h], al ; drv0 media state 1254 mov ds:[491h], al ; drv1 media state 1255 mov ds:[492h], al ; drv0 operational state 1256 mov ds:[493h], al ; drv1 operational state 1257 mov ds:[494h], al ; drv0 current cylinder 1258 mov ds:[495h], al ; drv1 current cylinder 1259 1260 mov al, 2 1261 out 0Ah, al ; unmask DMA channel 2 1262 1263 SET_INT_VECTOR 1Eh, BIOSSEG, _diskette_param_table 1264 SET_INT_VECTOR 40h, BIOSSEG, int13_diskette 1265 SET_INT_VECTOR 0Eh, BIOSSEG, int0e_handler ; IRQ 6 1266 1267 ret 1268 1269 floppy_post endp 1270 1271 1272 bcd_to_bin proc near 1273 1274 ;; in : AL in packed BCD format 1275 ;; out: AL in binary, AH always 0 1276 1276 if VBOX_BIOS_CPU ge 80186 1277 shlax, 41278 shral, 41277 shl ax, 4 1278 shr al, 4 1279 1279 else 1280 pushcx1281 movcl, 41282 shlax, cl1283 shral, cl1284 popcx1285 endif 1286 1287 1288 1289 bcd_to_bin 1290 1291 rtc_post procnear1280 push cx 1281 mov cl, 4 1282 shl ax, cl 1283 shr al, cl 1284 pop cx 1285 endif 1286 aad 1287 ret 1288 1289 bcd_to_bin endp 1290 1291 rtc_post proc near 1292 1292 1293 1293 if VBOX_BIOS_CPU lt 80386 ;; @todo fix loopy code below 1294 1295 moval, 01296 outCMOS_ADDR, al1297 in al, CMOS_DATA; RTC seconds, in BCD1298 call bcd_to_bin; ax now has seconds in binary1299 testal, al1300 xorah, ah1301 movdx, 0x1234 ; 18206507*0x100/1000000 = 0x1234 (4660.865792)1302 mul dx1303 mov cx, ax; tick count in dx:cx1304 1305 1306 moval, 21307 outCMOS_ADDR, al1308 in al, CMOS_DATA; RTC minutes, in BCD1309 call bcd_to_bin; eax now has minutes in binary1310 test al, al1311 jz rtc_post_hours1312 rtc_pos_min_loop: 1313 addcx, 0x44631314 1315 decal1316 jnzrtc_pos_min_loop1317 1318 1294 ;; get RTC seconds 1295 mov al, 0 1296 out CMOS_ADDR, al 1297 in al, CMOS_DATA ; RTC seconds, in BCD 1298 call bcd_to_bin ; ax now has seconds in binary 1299 test al, al 1300 xor ah, ah 1301 mov dx, 0x1234 ; 18206507*0x100/1000000 = 0x1234 (4660.865792) 1302 mul dx 1303 mov cx, ax ; tick count in dx:cx 1304 1305 ;; get RTC minutes 1306 mov al, 2 1307 out CMOS_ADDR, al 1308 in al, CMOS_DATA ; RTC minutes, in BCD 1309 call bcd_to_bin ; eax now has minutes in binary 1310 test al, al 1311 jz rtc_post_hours 1312 rtc_pos_min_loop: ; 18206507*60*0x100/1000000 = 0x44463 (279651.94752) 1313 add cx, 0x4463 1314 adc dx, 0x0004 1315 dec al 1316 jnz rtc_pos_min_loop 1317 1318 ;; get RTC hours 1319 1319 rtc_post_hours: 1320 moval, 41321 outCMOS_ADDR, al1322 in al, CMOS_DATA; RTC hours, in BCD1323 call bcd_to_bin; eax now has hours in binary1324 testal, al1325 jzrtc_pos_shift1326 rtc_pos_hour_loop: 1327 addcx, 0x076C1328 1329 decal1330 jnzrtc_pos_hour_loop1320 mov al, 4 1321 out CMOS_ADDR, al 1322 in al, CMOS_DATA ; RTC hours, in BCD 1323 call bcd_to_bin ; eax now has hours in binary 1324 test al, al 1325 jz rtc_pos_shift 1326 rtc_pos_hour_loop: ; 18206507*3600*0x100/1000000 = 0x100076C (16779116.8512) 1327 add cx, 0x076C 1328 adc dx, 0x0100 1329 dec al 1330 jnz rtc_pos_hour_loop 1331 1331 1332 1332 rtc_pos_shift: 1333 movcl, ch1334 movch, dl1335 movdl, dh1336 xordh, dh1337 mov ds:[46Ch], cx; timer tick count1338 mov ds:[46Ch+2], dx; timer tick count1339 mov ds:[470h], dh; rollover flag1333 mov cl, ch 1334 mov ch, dl 1335 mov dl, dh 1336 xor dh, dh 1337 mov ds:[46Ch], cx ; timer tick count 1338 mov ds:[46Ch+2], dx ; timer tick count 1339 mov ds:[470h], dh ; rollover flag 1340 1340 1341 1341 else 1342 1343 1344 xoreax, eax1345 moval, 01346 outCMOS_ADDR, al1347 in al, CMOS_DATA; RTC seconds, in BCD1348 call bcd_to_bin; eax now has seconds in binary1349 movedx, 182065071350 muledx1351 movebx, 10000001352 xoredx, edx1353 divebx1354 mov ecx, eax; total ticks in ecx1355 1356 1357 xoreax, eax1358 moval, 21359 outCMOS_ADDR, al1360 in al, CMOS_DATA; RTC minutes, in BCD1361 call bcd_to_bin; eax now has minutes in binary1362 movedx, 109239041363 muledx1364 movebx, 100001365 xoredx, edx1366 divebx1367 add ecx, eax; add to total ticks1368 1369 1370 xoreax, eax1371 moval, 41372 outCMOS_ADDR, al1373 in al, CMOS_DATA; RTC hours, in BCD1374 call bcd_to_bin; eax now has hours in binary1375 movedx, 655434271376 muledx1377 movebx, 10001378 xoredx, edx1379 divebx1380 add ecx, eax; add to total ticks1381 1382 mov ds:[46Ch], ecx; timer tick count1383 xor al, al; TODO: redundant?1384 mov ds:[470h], al; rollover flag1385 1386 endif 1387 1388 1389 rtc_post 1342 .386 1343 ;; get RTC seconds 1344 xor eax, eax 1345 mov al, 0 1346 out CMOS_ADDR, al 1347 in al, CMOS_DATA ; RTC seconds, in BCD 1348 call bcd_to_bin ; eax now has seconds in binary 1349 mov edx, 18206507 1350 mul edx 1351 mov ebx, 1000000 1352 xor edx, edx 1353 div ebx 1354 mov ecx, eax ; total ticks in ecx 1355 1356 ;; get RTC minutes 1357 xor eax, eax 1358 mov al, 2 1359 out CMOS_ADDR, al 1360 in al, CMOS_DATA ; RTC minutes, in BCD 1361 call bcd_to_bin ; eax now has minutes in binary 1362 mov edx, 10923904 1363 mul edx 1364 mov ebx, 10000 1365 xor edx, edx 1366 div ebx 1367 add ecx, eax ; add to total ticks 1368 1369 ;; get RTC hours 1370 xor eax, eax 1371 mov al, 4 1372 out CMOS_ADDR, al 1373 in al, CMOS_DATA ; RTC hours, in BCD 1374 call bcd_to_bin ; eax now has hours in binary 1375 mov edx, 65543427 1376 mul edx 1377 mov ebx, 1000 1378 xor edx, edx 1379 div ebx 1380 add ecx, eax ; add to total ticks 1381 1382 mov ds:[46Ch], ecx ; timer tick count 1383 xor al, al ; TODO: redundant? 1384 mov ds:[470h], al ; rollover flag 1385 .286 1386 endif 1387 ret 1388 1389 rtc_post endp 1390 1390 1391 1391 … … 1394 1394 ;; INT 0Eh handler - Diskette IRQ 6 ISR 1395 1395 ;; -------------------------------------------------------- 1396 BIOSORG0EF57h, 0EF55h1396 BIOSORG 0EF57h, 0EF55h 1397 1397 int0e_handler: 1398 pushax1399 pushdx1400 movdx, 3F4h1401 inal, dx1402 andal, 0C0h1403 cmpal, 0C0h1404 jeint0e_normal1405 movdx, 3F5h1406 mov al, 08h; sense interrupt1407 outdx, al1398 push ax 1399 push dx 1400 mov dx, 3F4h 1401 in al, dx 1402 and al, 0C0h 1403 cmp al, 0C0h 1404 je int0e_normal 1405 mov dx, 3F5h 1406 mov al, 08h ; sense interrupt 1407 out dx, al 1408 1408 int0e_loop1: 1409 mov dx, 3F4h; TODO: move out of the loop?1410 inal, dx1411 andal, 0C0h1412 cmpal, 0C0h1413 jneint0e_loop11409 mov dx, 3F4h ; TODO: move out of the loop? 1410 in al, dx 1411 and al, 0C0h 1412 cmp al, 0C0h 1413 jne int0e_loop1 1414 1414 1415 1415 int0e_loop2: 1416 mov dx, 3F5h; TODO: inc/dec dx instead1417 inal, dx1418 movdx, 3F4h1419 inal, dx1420 andal, 0C0h1421 cmpal, 0C0h1422 jeint0e_loop21416 mov dx, 3F5h ; TODO: inc/dec dx instead 1417 in al, dx 1418 mov dx, 3F4h 1419 in al, dx 1420 and al, 0C0h 1421 cmp al, 0C0h 1422 je int0e_loop2 1423 1423 1424 1424 int0e_normal: 1425 pushds1426 xorax, ax1427 movds, ax1428 calleoi_master_pic1429 1430 orbyte ptr ds:[43Eh], 80h1431 popds1432 popdx1433 popax1434 1425 push ds 1426 xor ax, ax 1427 mov ds, ax 1428 call eoi_master_pic 1429 ; indicate that an interrupt occurred 1430 or byte ptr ds:[43Eh], 80h 1431 pop ds 1432 pop dx 1433 pop ax 1434 iret 1435 1435 1436 1436 … … 1438 1438 ;; Diskette Parameter Table 1439 1439 ;; -------------------------------------------------------- 1440 BIOSORG0EFC7h, 0EFC5h1440 BIOSORG 0EFC7h, 0EFC5h 1441 1441 _diskette_param_table: 1442 db0AFh1443 db 2; HLT=1, DMA mode1444 db025h1445 db21446 db 18; SPT (good for 1.44MB media)1447 db01Bh1448 db0FFh1449 db06Ch1450 db 0F6h; format filler1451 db151452 db81442 db 0AFh 1443 db 2 ; HLT=1, DMA mode 1444 db 025h 1445 db 2 1446 db 18 ; SPT (good for 1.44MB media) 1447 db 01Bh 1448 db 0FFh 1449 db 06Ch 1450 db 0F6h ; format filler 1451 db 15 1452 db 8 1453 1453 1454 1454 … … 1457 1457 ;; INT 17h handler - Printer service 1458 1458 ;; -------------------------------------------------------- 1459 BIOSORG_CHECK 0EFD2h; fixed WRT preceding code1460 1461 jmp int17_handler; NT floppy boot workaround1462 1459 BIOSORG_CHECK 0EFD2h ; fixed WRT preceding code 1460 1461 jmp int17_handler ; NT floppy boot workaround 1462 ; see @bugref{6481} 1463 1463 int17_handler: 1464 pushds1465 pushes1466 1467 1468 call_int17_function1469 1470 popes1471 popds1472 1464 push ds 1465 push es 1466 DO_pusha 1467 C_SETUP 1468 call _int17_function 1469 DO_popa 1470 pop es 1471 pop ds 1472 iret 1473 1473 1474 1474 … … 1483 1483 1484 1484 _pmode_IDT: 1485 dw 0; limit 15:01486 dw 0; base 15:01487 dw 0Fh; base 23:161485 dw 0 ; limit 15:0 1486 dw 0 ; base 15:0 1487 dw 0Fh ; base 23:16 1488 1488 1489 1489 … … 1495 1495 1496 1496 _rmode_IDT: 1497 dw 3FFh; limit 15:001498 dw 0; base 15:001499 dw 0; base 23:161497 dw 3FFh ; limit 15:00 1498 dw 0 ; base 15:00 1499 dw 0 ; base 23:16 1500 1500 1501 1501 … … 1504 1504 ;; 1505 1505 ;; TODO: Why does this need a special handler? 1506 int1c_handler: 1507 1506 int1c_handler: ;; user timer tick 1507 iret 1508 1508 1509 1509 … … 1512 1512 ;; INT 10h functions 0-Fh entry point 1513 1513 ;; -------------------------------------------------------- 1514 1514 BIOSORG 0F045h, 0F043h 1515 1515 i10f0f_entry: 1516 1516 iret 1517 1517 1518 1518 … … 1520 1520 ;; INT 10h handler - MDA/CGA video 1521 1521 ;; -------------------------------------------------------- 1522 1522 BIOSORG 0F065h, 0F063h 1523 1523 int10_handler: 1524 1525 1524 ;; do nothing - assumes VGA 1525 iret 1526 1526 1527 1527 … … 1529 1529 ;; MDA/CGA Video Parameter Table (INT 1Dh) 1530 1530 ;; -------------------------------------------------------- 1531 1531 BIOSORG 0F0A4h, 0F0A2h 1532 1532 mdacga_vpt: 1533 1533 … … 1537 1537 ;; 1538 1538 int18_handler: 1539 1540 call_int18_panic_msg1541 1542 1543 1539 C_SETUP 1540 call _int18_panic_msg 1541 ;; TODO: handle failure better? 1542 hlt 1543 iret 1544 1544 1545 1545 ;; … … 1552 1552 ; The approach used is faking a warm reboot (which just skips showing the 1553 1553 ; logo), which is a bit more than what we need, but hey, it's fast. 1554 movbp, sp1555 mov ax, [bp+2]; TODO: redundant? address via sp?1556 cmp ax, BIOSSEG; check caller's segment1557 jzbios_initiated_boot1558 1559 xorax, ax1560 movds, ax1561 movax, 1234h1562 movds:[472], ax1563 jmppost1554 mov bp, sp 1555 mov ax, [bp+2] ; TODO: redundant? address via sp? 1556 cmp ax, BIOSSEG ; check caller's segment 1557 jz bios_initiated_boot 1558 1559 xor ax, ax 1560 mov ds, ax 1561 mov ax, 1234h 1562 mov ds:[472], ax 1563 jmp post 1564 1564 1565 1565 bios_initiated_boot: 1566 1567 1568 1569 C_SETUP; TODO: Here? Now?1570 pushbp1571 movbp, sp1572 1573 1574 movax, 11575 pushax1576 call_int19_function1577 incsp1578 incsp1579 test ax, ax; if 0, try next device1580 jnzboot_setup1581 1582 1583 movax, 21584 pushax1585 call_int19_function1586 incsp1587 incsp1588 test ax, ax; if 0, try next device1589 jnzboot_setup1590 1591 1592 movax, 31593 pushax1594 call_int19_function1595 incsp1596 incsp1597 test ax, ax; if 0, try next device1598 jnzboot_setup1599 1600 1601 movax, 41602 pushax1603 call_int19_function1604 incsp1605 incsp1606 test ax, ax; if 0, invoke INT 18h1607 jzint18_handler1566 ;; The C worker function returns the boot drive in bl and 1567 ;; the boot segment in ax. In case of failure, the boot 1568 ;; segment will be zero. 1569 C_SETUP ; TODO: Here? Now? 1570 push bp 1571 mov bp, sp 1572 1573 ;; 1st boot device 1574 mov ax, 1 1575 push ax 1576 call _int19_function 1577 inc sp 1578 inc sp 1579 test ax, ax ; if 0, try next device 1580 jnz boot_setup 1581 1582 ;; 2nd boot device 1583 mov ax, 2 1584 push ax 1585 call _int19_function 1586 inc sp 1587 inc sp 1588 test ax, ax ; if 0, try next device 1589 jnz boot_setup 1590 1591 ; 3rd boot device 1592 mov ax, 3 1593 push ax 1594 call _int19_function 1595 inc sp 1596 inc sp 1597 test ax, ax ; if 0, try next device 1598 jnz boot_setup 1599 1600 ; 4th boot device 1601 mov ax, 4 1602 push ax 1603 call _int19_function 1604 inc sp 1605 inc sp 1606 test ax, ax ; if 0, invoke INT 18h 1607 jz int18_handler 1608 1608 1609 1609 boot_setup: 1610 1610 ; TODO: the drive should be in dl already?? 1611 ;; mov dl, bl; tell guest OS what boot drive is1611 ;; mov dl, bl ; tell guest OS what boot drive is 1612 1612 if VBOX_BIOS_CPU lt 80386 1613 mov[bp], ax1614 DO_shlax, 41615 mov [bp+2], ax; set ip1616 movax, [bp]1613 mov [bp], ax 1614 DO_shl ax, 4 1615 mov [bp+2], ax ; set ip 1616 mov ax, [bp] 1617 1617 else 1618 .386; NB: We're getting garbage into high eax bits1619 shl eax, 4; convert seg to ip1620 mov [bp+2], ax; set ip1621 1622 shr eax, 4; get cs back1623 1624 endif 1625 and ax, BIOSSEG; remove what went in ip1626 mov [bp+4], ax; set cs1627 xorax, ax1628 movds, ax1629 moves, ax1630 mov [bp], ax; TODO: what's this?!1631 mov ax, 0AA55h; set ok flag ; TODO: and this?1632 1633 pop bp; TODO: why'd we just zero it??1634 iret; beam me up scotty1618 .386 ; NB: We're getting garbage into high eax bits 1619 shl eax, 4 ; convert seg to ip 1620 mov [bp+2], ax ; set ip 1621 1622 shr eax, 4 ; get cs back 1623 .286 1624 endif 1625 and ax, BIOSSEG ; remove what went in ip 1626 mov [bp+4], ax ; set cs 1627 xor ax, ax 1628 mov ds, ax 1629 mov es, ax 1630 mov [bp], ax ; TODO: what's this?! 1631 mov ax, 0AA55h ; set ok flag ; TODO: and this? 1632 1633 pop bp ; TODO: why'd we just zero it?? 1634 iret ; beam me up scotty 1635 1635 1636 1636 ;; PCI BIOS … … 1643 1643 ;; INT 12h handler - Memory size 1644 1644 ;; -------------------------------------------------------- 1645 BIOSORG0F841h, 0F83Fh1645 BIOSORG 0F841h, 0F83Fh 1646 1646 int12_handler: 1647 1648 1649 pushds1650 movax, 40h1651 movds, ax1652 movax, ds:[13h]1653 popds1654 1647 ;; Don't touch - fixed size! 1648 sti 1649 push ds 1650 mov ax, 40h 1651 mov ds, ax 1652 mov ax, ds:[13h] 1653 pop ds 1654 iret 1655 1655 1656 1656 … … 1658 1658 ;; INT 11h handler - Equipment list service 1659 1659 ;; -------------------------------------------------------- 1660 BIOSORG_CHECK 0F84Dh; fixed wrt preceding code1660 BIOSORG_CHECK 0F84Dh ; fixed wrt preceding code 1661 1661 int11_handler: 1662 1663 1664 pushds1665 movax, 40h1666 movds, ax1667 movax, ds:[10h]1668 popds1669 1662 ;; Don't touch - fixed size! 1663 sti 1664 push ds 1665 mov ax, 40h 1666 mov ds, ax 1667 mov ax, ds:[10h] 1668 pop ds 1669 iret 1670 1670 1671 1671 … … 1673 1673 ;; INT 15h handler - System services 1674 1674 ;; -------------------------------------------------------- 1675 BIOSORG_CHECK 0F859h; fixed wrt preceding code1675 BIOSORG_CHECK 0F859h ; fixed wrt preceding code 1676 1676 int15_handler: 1677 1677 1678 1678 if VBOX_BIOS_CPU ge 80286 1679 cmpah, 87h1680 jnenot_blkmove1681 1682 1683 1684 1685 1686 pushes1687 pushds1688 1689 call_int15_blkmove1690 popds1691 popes1692 1693 1679 cmp ah, 87h 1680 jne not_blkmove 1681 1682 ;; INT 15h/87h has semi-public interface because software 1683 ;; may use CMOS shutdown status code 9 for its own purposes. 1684 ;; The stack layout has to match. 1685 pusha 1686 push es 1687 push ds 1688 C_SETUP 1689 call _int15_blkmove 1690 pop ds 1691 pop es 1692 popa 1693 iret 1694 1694 not_blkmove: 1695 1695 1696 1696 endif 1697 1697 1698 1699 pushds1700 pushes1701 1702 cmpah, 86h1703 jeint15_handler321704 cmpah, 0E8h1705 jeint15_handler321706 cmpah, 0d0h1707 jeint15_handler321708 1709 cmp ah, 53h; APM function?1710 jeapm_call1711 cmp ah, 0C2h; PS/2 mouse function?1712 jeint15_handler_mouse1713 1714 call_int15_function1698 pushf 1699 push ds 1700 push es 1701 C_SETUP 1702 cmp ah, 86h 1703 je int15_handler32 1704 cmp ah, 0E8h 1705 je int15_handler32 1706 cmp ah, 0d0h 1707 je int15_handler32 1708 DO_pusha 1709 cmp ah, 53h ; APM function? 1710 je apm_call 1711 cmp ah, 0C2h ; PS/2 mouse function? 1712 je int15_handler_mouse 1713 1714 call _int15_function 1715 1715 int15_handler_popa_ret: 1716 1716 DO_popa 1717 1717 int15_handler32_ret: 1718 popes1719 popds1720 1721 jmpiret_modify_cf1718 pop es 1719 pop ds 1720 popf 1721 jmp iret_modify_cf 1722 1722 1723 1723 apm_call: 1724 call_apm_function1725 jmpint15_handler_popa_ret1724 call _apm_function 1725 jmp int15_handler_popa_ret 1726 1726 1727 1727 int15_handler_mouse: 1728 call_int15_function_mouse1729 jmpint15_handler_popa_ret1728 call _int15_function_mouse 1729 jmp int15_handler_popa_ret 1730 1730 1731 1731 int15_handler32: 1732 1732 if VBOX_BIOS_CPU ge 80386 1733 1734 1735 1736 call_int15_function321737 1738 1733 ;; need to save/restore 32-bit registers 1734 .386 1735 pushad 1736 call _int15_function32 1737 popad 1738 .286 1739 1739 else 1740 1741 call_int15_function321742 1743 endif 1744 jmpint15_handler32_ret1740 DO_pusha 1741 call _int15_function32 1742 DO_popa 1743 endif 1744 jmp int15_handler32_ret 1745 1745 1746 1746 ;; … … 1748 1748 ;; 1749 1749 iret_modify_cf: 1750 jccarry_set1751 pushbp1752 movbp, sp1753 andbyte ptr [bp + 6], 0FEh1754 popbp1755 1750 jc carry_set 1751 push bp 1752 mov bp, sp 1753 and byte ptr [bp + 6], 0FEh 1754 pop bp 1755 iret 1756 1756 carry_set: 1757 pushbp1758 movbp, sp1759 orbyte ptr [bp + 6], 11760 popbp1761 1757 push bp 1758 mov bp, sp 1759 or byte ptr [bp + 6], 1 1760 pop bp 1761 iret 1762 1762 1763 1763 ;; 1764 1764 ;; INT 74h handler - PS/2 mouse (IRQ 12) 1765 1765 ;; 1766 int74_handler 1767 1768 1769 1770 pushes1771 pushds1772 xorax, ax1773 push ax; placeholder for status1774 push ax; placeholder for X1775 push ax; placeholder for Y1776 push ax; placeholder for Z1777 push ax; placeholder for make_far_call bool1778 1779 call_int74_function1780 pop cx; pop make_far_call flag1781 jcxzint74_done1782 1783 1766 int74_handler proc 1767 1768 sti 1769 DO_pusha 1770 push es 1771 push ds 1772 xor ax, ax 1773 push ax ; placeholder for status 1774 push ax ; placeholder for X 1775 push ax ; placeholder for Y 1776 push ax ; placeholder for Z 1777 push ax ; placeholder for make_far_call bool 1778 C_SETUP 1779 call _int74_function 1780 pop cx ; pop make_far_call flag 1781 jcxz int74_done 1782 1783 ;; make far call to EBDA:0022 1784 1784 if VBOX_BIOS_CPU ge 80186 1785 push01785 push 0 1786 1786 else 1787 xorax, ax1788 pushax1789 endif 1790 popds1791 pushds:[40Eh]1792 popds1793 callfar ptr ds:[22h]1787 xor ax, ax 1788 push ax 1789 endif 1790 pop ds 1791 push ds:[40Eh] 1792 pop ds 1793 call far ptr ds:[22h] 1794 1794 int74_done: 1795 1796 calleoi_both_pics1797 add sp, 8; remove status, X, Y, Z1798 popds1799 popes1800 1801 1802 1803 int74_handler 1804 1805 int76_handler 1806 1807 1808 pushax1809 pushds1810 movax, 40h1811 movds, ax1812 movbyte ptr ds:[8Eh], 0FFh1813 calleoi_both_pics1814 popds1815 popax1816 1817 1818 int76_handler 1795 cli 1796 call eoi_both_pics 1797 add sp, 8 ; remove status, X, Y, Z 1798 pop ds 1799 pop es 1800 DO_popa 1801 iret 1802 1803 int74_handler endp 1804 1805 int76_handler proc 1806 1807 ;; record completion in BIOS task complete flag 1808 push ax 1809 push ds 1810 mov ax, 40h 1811 mov ds, ax 1812 mov byte ptr ds:[8Eh], 0FFh 1813 call eoi_both_pics 1814 pop ds 1815 pop ax 1816 iret 1817 1818 int76_handler endp 1819 1819 1820 1820 … … 1823 1823 ;; 1824 1824 int70_handler: 1825 pushes1826 pushds1827 1828 1829 call_int70_function1830 1831 popds1832 popes1833 1825 push es 1826 push ds 1827 DO_pusha 1828 C_SETUP 1829 call _int70_function 1830 DO_popa 1831 pop ds 1832 pop es 1833 iret 1834 1834 1835 1835 … … 1841 1841 ; 1842 1842 int08_maybe_rollover: 1843 jaint08_rollover1844 cmpax, 00B0h1845 jbint08_rollover_store1846 1843 ja int08_rollover 1844 cmp ax, 00B0h 1845 jb int08_rollover_store 1846 ;; there has been a midnight rollover 1847 1847 int08_rollover: 1848 xordx, dx1849 xorax, ax1850 1851 inc byte ptr ds:[70h]; increment rollover flag1848 xor dx, dx 1849 xor ax, ax 1850 1851 inc byte ptr ds:[70h] ; increment rollover flag 1852 1852 int08_rollover_store: 1853 jmpint08_store_ticks1853 jmp int08_store_ticks 1854 1854 endif 1855 1855 … … 1858 1858 ;; 8x8 font (first 128 characters) 1859 1859 ;; -------------------------------------------------------- 1860 BIOSORG0FA6Eh, 0FA6Ch1860 BIOSORG 0FA6Eh, 0FA6Ch 1861 1861 include font8x8.inc 1862 1862 … … 1865 1865 ;; INT 1Ah handler - Time of the day + PCI BIOS 1866 1866 ;; -------------------------------------------------------- 1867 BIOSORG_CHECK 0FE6Eh; fixed wrt preceding table1867 BIOSORG_CHECK 0FE6Eh ; fixed wrt preceding table 1868 1868 int1a_handler: 1869 1869 if VBOX_BIOS_CPU ge 80386 1870 cmpah, 0B1h1871 jneint1a_normal1872 1873 pushes1874 pushds1875 1876 1877 1878 call_pci16_function1879 1880 1881 popds1882 popes1883 1870 cmp ah, 0B1h 1871 jne int1a_normal 1872 1873 push es 1874 push ds 1875 C_SETUP 1876 .386 1877 pushad 1878 call _pci16_function 1879 popad 1880 .286 1881 pop ds 1882 pop es 1883 iret 1884 1884 endif 1885 1885 1886 1886 int1a_normal: 1887 pushes1888 pushds1889 1890 1887 push es 1888 push ds 1889 DO_pusha 1890 C_SETUP 1891 1891 int1a_callfunction: 1892 call_int1a_function1893 1894 popds1895 popes1896 1892 call _int1a_function 1893 DO_popa 1894 pop ds 1895 pop es 1896 iret 1897 1897 1898 1898 … … 1900 1900 ;; Timer tick - IRQ 0 handler 1901 1901 ;; -------------------------------------------------------- 1902 BIOSORG0FEA5h, 0FEA3h1902 BIOSORG 0FEA5h, 0FEA3h 1903 1903 int08_handler: 1904 1904 if VBOX_BIOS_CPU ge 80386 1905 1906 1907 pusheax1905 .386 1906 sti 1907 push eax 1908 1908 else 1909 1910 pushax1911 endif 1912 pushds1913 pushdx1914 movax, 40h1915 movds, ax1909 sti 1910 push ax 1911 endif 1912 push ds 1913 push dx 1914 mov ax, 40h 1915 mov ds, ax 1916 1916 1917 1917 if VBOX_BIOS_CPU ge 80386 1918 mov eax, ds:[6Ch]; get ticks dword1919 inceax1918 mov eax, ds:[6Ch] ; get ticks dword 1919 inc eax 1920 1920 else 1921 mov ax, ds:[6Ch]; get ticks dword1922 mov dx, ds:[6Ch+2]1923 inc ax; inc+jz+inc saves two bytes over add+adc.1924 jnzint08_compare1925 incdx1921 mov ax, ds:[6Ch] ; get ticks dword 1922 mov dx, ds:[6Ch+2] 1923 inc ax ; inc+jz+inc saves two bytes over add+adc. 1924 jnz int08_compare 1925 inc dx 1926 1926 int08_compare: 1927 1927 endif 1928 1928 1929 1929 ;; compare eax to one day's worth of ticks (at 18.2 Hz) 1930 1930 if VBOX_BIOS_CPU ge 80386 1931 cmpeax, 1800B0h1932 jbint08_store_ticks1931 cmp eax, 1800B0h 1932 jb int08_store_ticks 1933 1933 else 1934 cmpdx, 18h1935 jbint08_store_ticks1936 jmpint08_maybe_rollover1934 cmp dx, 18h 1935 jb int08_store_ticks 1936 jmp int08_maybe_rollover 1937 1937 endif 1938 1938 1939 1939 if VBOX_BIOS_CPU ge 80386 1940 1941 xoreax, eax1942 inc byte ptr ds:[70h]; increment rollover flag1940 ;; there has been a midnight rollover 1941 xor eax, eax 1942 inc byte ptr ds:[70h] ; increment rollover flag 1943 1943 1944 1944 int08_store_ticks: 1945 movds:[6Ch], eax1945 mov ds:[6Ch], eax 1946 1946 else 1947 1947 int08_store_ticks: 1948 movds:[6Ch], ax1949 movds:[6Ch+2], dx1950 endif 1951 1952 1953 moval, ds:[40h]1954 oral, al1955 jzint08_floppy_off1956 decal1957 movds:[40h], al1958 jnzint08_floppy_off1959 1960 movdx, 03F2h1961 inal, dx1962 andal, 0CFh1963 outdx, al1948 mov ds:[6Ch], ax 1949 mov ds:[6Ch+2], dx 1950 endif 1951 1952 ;; time to turn off floppy drive motor(s)? 1953 mov al, ds:[40h] 1954 or al, al 1955 jz int08_floppy_off 1956 dec al 1957 mov ds:[40h], al 1958 jnz int08_floppy_off 1959 ;; turn motor(s) off 1960 mov dx, 03F2h 1961 in al, dx 1962 and al, 0CFh 1963 out dx, al 1964 1964 int08_floppy_off: 1965 1965 1966 int 1Ch; call the user timer handler1967 1968 1969 calleoi_master_pic1970 popdx1971 popds1966 int 1Ch ; call the user timer handler 1967 1968 cli 1969 call eoi_master_pic 1970 pop dx 1971 pop ds 1972 1972 if VBOX_BIOS_CPU ge 80386 1973 popeax1974 1973 pop eax 1974 .286 1975 1975 else 1976 1977 endif 1978 1976 pop ax 1977 endif 1978 iret 1979 1979 1980 1980 … … 1982 1982 ;; Initial interrupt vector offsets for POST 1983 1983 ;; -------------------------------------------------------- 1984 BIOSORG0FEF3h, 0FEF1h1984 BIOSORG 0FEF3h, 0FEF1h 1985 1985 vector_table: 1986 1986 … … 1990 1990 ;; BIOS copyright string 1991 1991 ;; -------------------------------------------------------- 1992 BIOSORG0FF00h, 0FEFEh1992 BIOSORG 0FF00h, 0FEFEh 1993 1993 bios_string: 1994 dbBIOS_COPYRIGHT1994 db BIOS_COPYRIGHT 1995 1995 1996 1996 … … 1998 1998 ;; IRET - default interrupt handler 1999 1999 ;; -------------------------------------------------------- 2000 BIOSORG0FF53h, 0FF51h2000 BIOSORG 0FF53h, 0FF51h 2001 2001 2002 2002 dummy_iret: 2003 2003 iret 2004 2004 2005 2005 … … 2007 2007 ;; INT 05h - Print Screen service 2008 2008 ;; -------------------------------------------------------- 2009 BIOSORG_CHECK 0FF54h; fixed wrt preceding2009 BIOSORG_CHECK 0FF54h ; fixed wrt preceding 2010 2010 int05_handler: 2011 2012 2011 ;; Not implemented 2012 iret 2013 2013 2014 2014 include smidmi.inc … … 2017 2017 ;; Processor reset entry point 2018 2018 ;; -------------------------------------------------------- 2019 BIOSORG0FFF0h, 0FFEEh2019 BIOSORG 0FFF0h, 0FFEEh 2020 2020 cpu_reset: 2021 2022 jmpfar ptr post2023 2024 2025 dbBIOS_BUILD_DATE2026 db 0; padding2027 2028 dbSYS_MODEL_ID2029 2030 db0FFh2031 2032 2033 BIOSSEG 2034 2035 2036 2021 ;; This is where the CPU starts executing after a reset 2022 jmp far ptr post 2023 2024 ;; BIOS build date 2025 db BIOS_BUILD_DATE 2026 db 0 ; padding 2027 ;; System model ID 2028 db SYS_MODEL_ID 2029 ;; Checksum byte 2030 db 0FFh 2031 2032 2033 BIOSSEG ends 2034 2035 end 2036
Note:
See TracChangeset
for help on using the changeset viewer.