VirtualBox

Changeset 67065 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 24, 2017 1:04:01 PM (8 years ago)
Author:
vboxsync
Message:

Whitespace.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/orgs.asm

    r66959 r67065  
    11;;
    2 ;; Copyright (C) 2006-2016 Oracle Corporation
     2;; Copyright (C) 2006-2017 Oracle Corporation
    33;;
    44;; This file is part of VirtualBox Open Source Edition (OSE), as
     
    4949include commondefs.inc
    5050
    51 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
     51EBDA_SEG        equ     09FC0h          ; starts at 639K
     52EBDA_SIZE       equ     1               ; 1K
     53BASE_MEM_IN_K   equ     (640 - EBDA_SIZE)
     54
     55CMOS_ADDR       equ     070h
     56CMOS_DATA       equ     071h
     57
     58
     59PIC_CMD_EOI     equ     020h
     60PIC_MASTER      equ     020h
     61PIC_SLAVE       equ     0A0h
     62
     63BIOS_FIX_BASE   equ     0E000h
    6464
    6565if VBOX_BIOS_CPU ge 80286
    66 SYS_MODEL_ID    equ     0FCh            ; PC/AT
     66SYS_MODEL_ID    equ     0FCh            ; PC/AT
    6767else
    68 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
     68SYS_MODEL_ID    equ     0FBh            ; PC/XT
     69endif
     70SYS_SUBMODEL_ID equ     0
     71BIOS_REVISION   equ     1
     72
     73BIOS_BUILD_DATE equ     '06/23/99'
     74BIOS_COPYRIGHT  equ     'Oracle VM VirtualBox BIOS'
     75
     76BX_ROMBIOS32            equ     0
     77BX_CALL_INT15_4F        equ     1
    7878
    7979;; Set a fixed BIOS location, with a marker for verification
    80 BIOSORG         macro   addr, addr_minus_two
     80BIOSORG         macro   addr, addr_minus_two
    8181.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                 BIOSORG_CHECK_BEFORE addr_minus_two
    83                 org     addr - BIOS_FIX_BASE - 2
    84                 db      'XM'
    85                 BIOSORG_CHECK addr
    86                 endm
     82                BIOSORG_CHECK_BEFORE addr_minus_two
     83                org     addr - BIOS_FIX_BASE - 2
     84                db      'XM'
     85                BIOSORG_CHECK addr
     86                endm
    8787
    8888;; Set an interrupt vector (not very efficient if multiple vectors are
    8989;; programmed in one go)
    90 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
     90SET_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
    9595endm
    9696
    9797; Set up an environment C code expects. DS must point to the BIOS segment
    9898; and the direction flag must be cleared(!)
    99 C_SETUP         macro
    100                 push    cs
    101                 pop     ds
    102                 cld
     99C_SETUP         macro
     100                push    cs
     101                pop     ds
     102                cld
    103103endm
    104104
    105105
    106106;; External function in separate modules
    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
     107extrn           _dummy_isr_function:near
     108extrn           _log_bios_start:near
     109extrn           _nmi_handler_msg:near
     110extrn           _int18_panic_msg:near
     111extrn           _int09_function:near
     112extrn           _int13_diskette_function:near
     113extrn           _int13_eltorito:near
     114extrn           _int13_cdemu:near
     115extrn           _int13_cdrom:near
     116extrn           _cdemu_isactive:near
     117extrn           _cdemu_emulated_drive:near
     118extrn           _int13_harddisk:near
     119extrn           _int13_harddisk_ext:near
     120extrn           _int14_function:near
     121extrn           _int15_function:near
     122extrn           _int15_function_mouse:near
     123extrn           _int15_function32:near
     124extrn           _int16_function:near
     125extrn           _int17_function:near
     126extrn           _int19_function:near
     127extrn           _int1a_function:near
     128extrn           _pci16_function:near
     129extrn           _int70_function:near
     130extrn           _int74_function:near
     131extrn           _apm_function:near
     132extrn           _ata_init:near
     133extrn           _scsi_init:near
     134extrn           _ata_detect:near
     135extrn           _cdemu_init:near
     136extrn           _keyboard_init:near
     137extrn           _print_bios_banner:near
     138extrn           _inv_op_handler:near
     139extrn           rom_scan_:near
    140140ifdef VBOX_WITH_AHCI
    141 extrn           _ahci_init:near
     141extrn           _ahci_init:near
    142142endif
    143143if VBOX_BIOS_CPU ge 80286
    144 extrn           _int15_blkmove:near
     144extrn           _int15_blkmove:near
    145145endif
    146146if VBOX_BIOS_CPU ge 80386
    147 extrn           _apic_setup:near
     147extrn           _apic_setup:near
    148148endif
    149149
    150150
    151151;; Symbols referenced from C code
    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
     152public          _diskette_param_table
     153public          _pmode_IDT
     154public          _rmode_IDT
     155public          post
     156public          eoi_both_pics
     157public          rtc_post
    158158
    159159;; Additional publics for easier disassembly and debugging
    160160ifndef DEBUG
    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
     161 DEBUG  equ     1
     162endif
     163ifdef           DEBUG
     164
     165public          int08_handler
     166public          int0e_handler
     167public          int11_handler
     168public          int12_handler
     169public          int13_handler
     170public          int13_relocated
    171171if VBOX_BIOS_CPU eq 8086
    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
     172public  jmp_call_ret_int13_out
     173endif
     174public          int15_handler
     175public          int17_handler
     176public          int19_handler
     177public          int19_relocated
     178public          dummy_iret
     179public          nmi
     180public          rom_fdpt
     181public          cpu_reset
     182public          normal_post
     183public          eoi_jmp_post
     184public          no_eoi_jmp_post
     185public          eoi_master_pic
     186public          ebda_post
     187public          seg_40_value
     188public          hard_drive_post
     189public          int13_legacy
     190public          int70_handler
     191public          int75_handler
     192public          int15_handler32
     193public          int15_handler_mouse
     194public          iret_modify_cf
     195public          init_pic
     196public          floppy_post
     197public          int13_out
     198public          int13_disk
     199public          int13_notfloppy
     200public          int13_legacy
     201public          int13_noeltorito
     202public          int1c_handler
     203public          int10_handler
     204public          int74_handler
     205public          int76_handler
     206public          detect_parport
     207public          detect_serial
     208public          font8x8
    209209
    210210endif
     
    217217SET_DEFAULT_CPU_286
    218218
    219 BIOSSEG         segment 'CODE'
    220                 assume  cs:BIOSSEG
     219BIOSSEG         segment 'CODE'
     220                assume  cs:BIOSSEG
    221221
    222222;;
    223223;; Start of fixed code - eoi_jmp_post is kept near here to allow short jumps.
    224224;;
    225                 BIOSORG 0E030h, 0E02Eh
     225                BIOSORG 0E030h, 0E02Eh
    226226eoi_both_pics:
    227                 mov     al, PIC_CMD_EOI
    228                 out     PIC_SLAVE, al
     227                mov     al, PIC_CMD_EOI
     228                out     PIC_SLAVE, al
    229229eoi_master_pic:
    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
     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
     237set_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
     245set_int_vects   endp
    246246
    247247eoi_jmp_post:
    248                 call    eoi_both_pics
     248                call    eoi_both_pics
    249249no_eoi_jmp_post:
    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.
     250                xor     ax, ax
     251                mov     ds, ax
     252                jmp     dword ptr ds:[0467h]
     253
     254seg_40_value:   dw 40h ;; Replaces a push 40; pop ds.
    255255
    256256;; --------------------------------------------------------
    257257;; POST entry point
    258258;; --------------------------------------------------------
    259                 BIOSORG 0E05Bh, 0E059h
     259                BIOSORG 0E05Bh, 0E059h
    260260post:
    261                 cli
     261                cli
    262262
    263263if VBOX_BIOS_CPU ge 80286
    264                 ;; Check if in protected (V86) mode. If so, the CPU needs
    265                 ;; to be reset.
     264                ;; Check if in protected (V86) mode. If so, the CPU needs
     265                ;; to be reset.
    266266               .286p
    267                 smsw    ax
    268                 test    ax, 1
    269                 jz      in_real_mode
    270                 SET_DEFAULT_CPU_286
     267                smsw    ax
     268                test    ax, 1
     269                jz      in_real_mode
     270                SET_DEFAULT_CPU_286
    271271else
    272                 jmp     in_real_mode
    273 endif
    274 
    275                 ;; Reset processor to get out of protected mode. Use system
    276                 ;; port instead of KBC.
     272                jmp     in_real_mode
     273endif
     274
     275                ;; Reset processor to get out of protected mode. Use system
     276                ;; port instead of KBC.
    277277reset_sys:
    278                 mov     al, 1
    279                 out     92h, al
    280                 jmp     $               ; not strictly necessary in a VM
    281                
    282                
     278                mov     al, 1
     279                out     92h, al
     280                jmp     $               ; not strictly necessary in a VM
     281               
     282               
    283283in_real_mode:
    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.
     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.
    307307               mov     ds, cs:[seg_40_value]
    308                 cmp     word ptr ds:[72h], 1234h
    309                 jnz     reset_sys       ; trigger system reset
     308                cmp     word ptr ds:[72h], 1234h
     309                jnz     reset_sys       ; trigger system reset
    310310
    311311cont_post:
    312                 ;; 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
     312                ;; 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
    337337
    338338check_shutdown:
    339                 ;; 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
     339                ;; 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
     349check_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
    361361
    362362normal_post:
    363                 ;; 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
     363                ;; 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
    390390memory_zero_loop:
    391                 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
     391                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
    399399memory_cleared:
    400                 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
     400                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
    409409
    410410if VBOX_BIOS_CPU ge 80386
    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.
     411                call    pmode_setup
     412endif
     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.
    450450if VBOX_BIOS_CPU ge 80386 ; (Impossible to do on 16-bit CPUs.)
    451                 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
     451                call    pcibios_init_iomem_bases
     452                call    pcibios_init_irqs
     453endif
     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
    551551
    552552
     
    554554;; NMI handler
    555555;; --------------------------------------------------------
    556                 BIOSORG 0E2C3h, 0E2C1h
     556                BIOSORG 0E2C3h, 0E2C1h
    557557nmi:
    558                 C_SETUP
    559                 call    _nmi_handler_msg
    560                 iret
     558                C_SETUP
     559                call    _nmi_handler_msg
     560                iret
    561561
    562562int75_handler:
    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
     563                out     0F0h, al        ; clear IRQ13
     564                call    eoi_both_pics
     565                int     2               ; emulate legacy NMI
     566                iret
     567
     568
     569hard_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
     591hard_drive_post endp
    592592
    593593
    594594norm_post_cont:
    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
     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
    604604
    605605if VBOX_BIOS_CPU ge 80386
    606                 ;; 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
     606                ;; Set up local APIC
     607                .386
     608                pushad
     609                call    _apic_setup
     610                popad
     611                SET_DEFAULT_CPU_286
     612endif
     613
     614                ;; ATA/ATAPI driver setup
     615                call    _ata_init
     616                call    _ata_detect
    617617
    618618ifdef VBOX_WITH_AHCI
    619                 ; AHCI driver setup
    620                 call    _ahci_init
     619                ; AHCI driver setup
     620                call    _ahci_init
    621621endif
    622622
    623623ifdef VBOX_WITH_SCSI
    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
     624                ; SCSI driver setup
     625                call    _scsi_init
     626endif
     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
    650650wait_forever:
    651                 hlt
    652                 jmp     wait_forever
    653                 cli
    654                 hlt
    655                
     651                hlt
     652                jmp     wait_forever
     653                cli
     654                hlt
     655               
    656656
    657657;;
     
    660660;;
    661661return_blkmove:
    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
     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
    689689
    690690
     
    692692;; INT 13h handler - Disk services
    693693;; --------------------------------------------------------
    694                 BIOSORG 0E3FEh, 0E3FCh
     694                BIOSORG 0E3FEh, 0E3FCh
    695695
    696696int13_handler:
    697                 jmp     int13_relocated
     697                jmp     int13_relocated
    698698
    699699
     
    701701;; Fixed Disk Parameter Table
    702702;; --------------------------------------------------------
    703                 BIOSORG_CHECK   0E401h  ; fixed wrt preceding
     703                BIOSORG_CHECK   0E401h  ; fixed wrt preceding
    704704
    705705rom_fdpt:
     
    708708;; INT 19h handler - Boot load service
    709709;; --------------------------------------------------------
    710                 BIOSORG 0E6F2h, 0E6F0h
     710                BIOSORG 0E6F2h, 0E6F0h
    711711
    712712int19_handler:
    713                 jmp     int19_relocated
     713                jmp     int19_relocated
    714714
    715715
     
    718718;; System BIOS Configuration Table
    719719;; --------------------------------------------------------
    720                 BIOSORG_CHECK   0E6F5h  ; fixed wrt preceding
     720                BIOSORG_CHECK   0E6F5h  ; fixed wrt preceding
    721721; must match BIOS_CONFIG_TABLE
    722722bios_cfg_table:
    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)
     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)
    736736ifdef BX_CALL_INT15_4F
    737                 db      74h; or USE_EBDA
     737                db      74h; or USE_EBDA
    738738else
    739                 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
     739                db      64h; or USE_EBDA
     740endif
     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
    773773
    774774
     
    776776;; Baud Rate Generator Table
    777777;; --------------------------------------------------------
    778                 BIOSORG 0E729h, 0E727h
     778                BIOSORG 0E729h, 0E727h
    779779
    780780
     
    782782;; INT 14h handler -  Serial Communication Service
    783783;; --------------------------------------------------------
    784                 BIOSORG 0E739h, 0E737h
     784                BIOSORG 0E739h, 0E737h
    785785int14_handler:
    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
     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
    795795
    796796
     
    800800;;
    801801dummy_isr:
    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
     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
     813init_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
     835init_pic        endp
     836
     837ebda_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
     853ebda_post       endp
    854854
    855855
     
    858858;; INT 16h handler - Keyboard service
    859859;; --------------------------------------------------------
    860                 BIOSORG 0E82Eh, 0E82Ch
     860                BIOSORG 0E82Eh, 0E82Ch
    861861int16_handler:
    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
     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
    879879
    880880int16_F00:
    881                 mov     bx, 40h         ; TODO: why 40h here and 0 elsewhere?
    882                 mov     ds, bx
     881                mov     bx, 40h         ; TODO: why 40h here and 0 elsewhere?
     882                mov     ds, bx
    883883int16_wait_for_key:
    884                 cli
    885                 mov     bx, ds:[1Ah]
    886                 cmp     bx, ds:[1Ch]
    887                 jne     int16_key_found
    888                 sti
    889                 nop
     884                cli
     885                mov     bx, ds:[1Ah]
     886                cmp     bx, ds:[1Ch]
     887                jne     int16_key_found
     888                sti
     889                nop
    890890; TODO: review/enable?
    891891if 0
    892                 push    ax
    893                 mov     ax, 9002h
    894                 int     15h
    895                 pop     ax
    896 endif
    897                 jmp     int16_wait_for_key
     892                push    ax
     893                mov     ax, 9002h
     894                int     15h
     895                pop     ax
     896endif
     897                jmp     int16_wait_for_key
    898898
    899899int16_key_found:
    900                 C_SETUP
    901                 call    _int16_function
    902                 DO_popa
    903                 pop     ds
    904                 pop     es
     900                C_SETUP
     901                call    _int16_function
     902                DO_popa
     903                pop     ds
     904                pop     es
    905905; TODO: review/enable? If so, flags should be restored here?
    906906if 0
    907                 push    ax
    908                 mov     ax, 9202h
    909                 int     15h
    910                 pop     ax
    911 endif
    912                 iret
     907                push    ax
     908                mov     ax, 9202h
     909                int     15h
     910                pop     ax
     911endif
     912                iret
    913913
    914914
     
    922922
    923923
    924 KBDC_DISABLE    EQU     0ADh
    925 KBDC_ENABLE     EQU     0AEh
    926 KBC_CMD         EQU     64h
    927 KBC_DATA        EQU     60h
     924KBDC_DISABLE    EQU     0ADh
     925KBDC_ENABLE     EQU     0AEh
     926KBC_CMD         EQU     64h
     927KBC_DATA        EQU     60h
    928928
    929929;; --------------------------------------------------------
    930930;; INT 09h handler - Keyboard ISR (IRQ 1)
    931931;; --------------------------------------------------------
    932                 BIOSORG 0E987h, 0E985h
     932                BIOSORG 0E987h, 0E985h
    933933int09_handler:
    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)
     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)
    943943ifdef BX_CALL_INT15_4F
    944                 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
     944                mov     ah, 4Fh
     945                stc
     946                int     15h             ; keyboard intercept
     947                jnc     int09_done
     948endif
     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
    958958
    959959int09_check_pause:
    960                 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
     960                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
    966966
    967967int09_process_key:
    968                 push    es
    969                 C_SETUP
    970                 call    _int09_function
    971                 pop     es
     968                push    es
     969                C_SETUP
     970                call    _int09_function
     971                pop     es
    972972
    973973int09_done:
    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
     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
    983983
    984984
     
    988988
    989989int06_handler:
    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
     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
    999999
    10001000;; --------------------------------------------------------
    10011001;; INT 13h handler - Diskette service
    10021002;; --------------------------------------------------------
    1003                 BIOSORG 0EC59h, 0EC57h
     1003                BIOSORG 0EC59h, 0EC57h
    10041004int13_diskette:
    1005                 jmp     int13_noeltorito
     1005                jmp     int13_noeltorito
    10061006
    10071007
     
    10111011;; --------------------------------------------------------
    10121012int13_relocated:
    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
     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
    10251025if VBOX_BIOS_CPU eq 8086
    10261026jmp_call_ret_int13_out: dw offset int13_out
     
    10281028
    10291029int13_not_eltorito:
    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
     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
    10601060
    10611061int13_nocdemu:
    1062                 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
     1062                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
    10791079
    10801080int13_cdemu_inactive:
    1081                 pop     dx
    1082                 pop     cx
    1083                 pop     bx
    1084                 pop     ax
    1085                 pop     es
     1081                pop     dx
     1082                pop     cx
     1083                pop     bx
     1084                pop     ax
     1085                pop     es
    10861086
    10871087int13_noeltorito:
    1088                 push    ax
    1089                 push    cx
    1090                 push    dx
    1091                 push    bx
     1088                push    ax
     1089                push    cx
     1090                push    dx
     1091                push    bx
    10921092int13_legacy:
    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
     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
    11071107
    11081108int13_notfloppy:
    1109                 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
     1109                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
    11231123
    11241124int13_notcdrom:
    11251125int13_disk:
    1126                 cmp     ah,40h
    1127                 ja      int13x
    1128                 call    _int13_harddisk
    1129                 jmp     int13_out
     1126                cmp     ah,40h
     1127                ja      int13x
     1128                call    _int13_harddisk
     1129                jmp     int13_out
    11301130
    11311131int13x:
    1132                 call    _int13_harddisk_ext
     1132                call    _int13_harddisk_ext
    11331133
    11341134int13_out:
    1135                 pop     ds
    1136                 pop     es
    1137                 DO_popa
    1138                 iret
     1135                pop     ds
     1136                pop     es
     1137                DO_popa
     1138                iret
    11391139
    11401140
    11411141
    11421142; parallel port detection: port in dx, index in bx, timeout in cl
    1143 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
     1143detect_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
    11641164no_parport:
    1165                 ret
    1166 
    1167 detect_parport  endp
     1165                ret
     1166
     1167detect_parport  endp
    11681168
    11691169; setial port detection: port in dx, index in bx, timeout in cl
    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
     1170detect_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
    11951195
    11961196no_serial:
    1197                 pop     dx
    1198                 ret
    1199 
    1200 detect_serial   endp
     1197                pop     dx
     1198                ret
     1199
     1200detect_serial   endp
    12011201
    12021202
     
    12041204;; POST: Floppy drive
    12051205;;
    1206 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
     1206floppy_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
    12321232
    12331233look_drive0:
    1234                 ; 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
     1234                ; 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
    12391239
    12401240f0_missing:
    1241                 mov     bl, 0           ; no drive 0
     1241                mov     bl, 0           ; no drive 0
    12421242
    12431243look_drive1:
    1244                 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
     1244                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
    12481248f1_missing:
    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
     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
     1269floppy_post     endp
     1270
     1271
     1272bcd_to_bin      proc    near
     1273
     1274                ;; in : AL in packed BCD format
     1275                ;; out: AL in binary, AH always 0
    12761276if VBOX_BIOS_CPU ge 80186
    1277                 shl     ax, 4
    1278                 shr     al, 4
     1277                shl     ax, 4
     1278                shr     al, 4
    12791279else
    1280                 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
     1280                push    cx
     1281                mov     cl, 4
     1282                shl     ax, cl
     1283                shr     al, cl
     1284                pop     cx
     1285endif
     1286                aad
     1287                ret
     1288
     1289bcd_to_bin      endp
     1290
     1291rtc_post        proc    near
    12921292
    12931293if VBOX_BIOS_CPU lt 80386 ;; @todo fix loopy code below
    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
     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
     1312rtc_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
    13191319rtc_post_hours:
    1320                 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
     1320                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
     1326rtc_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
    13311331
    13321332rtc_pos_shift:
    1333                 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
     1333                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
    13401340
    13411341else
    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
     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
     1386endif
     1387                ret
     1388
     1389rtc_post        endp
    13901390
    13911391
     
    13941394;; INT 0Eh handler - Diskette IRQ 6 ISR
    13951395;; --------------------------------------------------------
    1396                 BIOSORG 0EF57h, 0EF55h
     1396                BIOSORG 0EF57h, 0EF55h
    13971397int0e_handler:
    1398                 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
     1398                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
    14081408int0e_loop1:
    1409                 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
     1409                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
    14141414
    14151415int0e_loop2:
    1416                 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
     1416                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
    14231423
    14241424int0e_normal:
    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
     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
    14351435
    14361436
     
    14381438;; Diskette Parameter Table
    14391439;; --------------------------------------------------------
    1440                 BIOSORG 0EFC7h, 0EFC5h
     1440                BIOSORG 0EFC7h, 0EFC5h
    14411441_diskette_param_table:
    1442                 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
     1442                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
    14531453
    14541454
     
    14571457;; INT 17h handler - Printer service
    14581458;; --------------------------------------------------------
    1459                 BIOSORG_CHECK   0EFD2h  ; fixed WRT preceding code
    1460 
    1461                 jmp     int17_handler   ; NT floppy boot workaround
    1462                                         ; see @bugref{6481}
     1459                BIOSORG_CHECK   0EFD2h  ; fixed WRT preceding code
     1460
     1461                jmp     int17_handler   ; NT floppy boot workaround
     1462                                        ; see @bugref{6481}
    14631463int17_handler:
    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
     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
    14731473
    14741474
     
    14831483
    14841484_pmode_IDT:
    1485                 dw      0               ; limit 15:0
    1486                 dw      0               ; base  15:0
    1487                 dw      0Fh             ; base  23:16
     1485                dw      0               ; limit 15:0
     1486                dw      0               ; base  15:0
     1487                dw      0Fh             ; base  23:16
    14881488
    14891489
     
    14951495
    14961496_rmode_IDT:
    1497                 dw      3FFh            ; limit 15:00
    1498                 dw      0               ; base  15:00
    1499                 dw      0               ; base  23:16
     1497                dw      3FFh            ; limit 15:00
     1498                dw      0               ; base  15:00
     1499                dw      0               ; base  23:16
    15001500
    15011501
     
    15041504;;
    15051505;; TODO: Why does this need a special handler?
    1506 int1c_handler:  ;; user timer tick
    1507                 iret
     1506int1c_handler:  ;; user timer tick
     1507                iret
    15081508
    15091509
     
    15121512;; INT 10h functions 0-Fh entry point
    15131513;; --------------------------------------------------------
    1514                 BIOSORG 0F045h, 0F043h
     1514                BIOSORG 0F045h, 0F043h
    15151515i10f0f_entry:
    1516                 iret
     1516                iret
    15171517
    15181518
     
    15201520;; INT 10h handler - MDA/CGA video
    15211521;; --------------------------------------------------------
    1522                 BIOSORG 0F065h, 0F063h
     1522                BIOSORG 0F065h, 0F063h
    15231523int10_handler:
    1524                 ;; do nothing - assumes VGA
    1525                 iret
     1524                ;; do nothing - assumes VGA
     1525                iret
    15261526
    15271527
     
    15291529;; MDA/CGA Video Parameter Table (INT 1Dh)
    15301530;; --------------------------------------------------------
    1531                 BIOSORG 0F0A4h, 0F0A2h
     1531                BIOSORG 0F0A4h, 0F0A2h
    15321532mdacga_vpt:
    15331533
     
    15371537;;
    15381538int18_handler:
    1539                 C_SETUP
    1540                 call    _int18_panic_msg
    1541                 ;; TODO: handle failure better?
    1542                 hlt
    1543                 iret
     1539                C_SETUP
     1540                call    _int18_panic_msg
     1541                ;; TODO: handle failure better?
     1542                hlt
     1543                iret
    15441544
    15451545;;
     
    15521552; The approach used is faking a warm reboot (which just skips showing the
    15531553; logo), which is a bit more than what we need, but hey, it's fast.
    1554                 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
     1554                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
    15641564
    15651565bios_initiated_boot:
    1566                 ;; 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
     1566                ;; 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
    16081608
    16091609boot_setup:
    16101610; TODO: the drive should be in dl already??
    1611 ;;              mov     dl, bl          ; tell guest OS what boot drive is
     1611;;              mov     dl, bl          ; tell guest OS what boot drive is
    16121612if VBOX_BIOS_CPU lt 80386
    1613                 mov     [bp], ax
    1614                DO_shl   ax, 4
    1615                 mov     [bp+2], ax      ; set ip
    1616                 mov     ax, [bp]
     1613                mov     [bp], ax
     1614                DO_shl  ax, 4
     1615                mov     [bp+2], ax      ; set ip
     1616                mov     ax, [bp]
    16171617else
    1618                 .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
     1618                .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
     1624endif
     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
    16351635
    16361636;; PCI BIOS
     
    16431643;; INT 12h handler - Memory size
    16441644;; --------------------------------------------------------
    1645                 BIOSORG 0F841h, 0F83Fh
     1645                BIOSORG 0F841h, 0F83Fh
    16461646int12_handler:
    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
     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
    16551655
    16561656
     
    16581658;; INT 11h handler - Equipment list service
    16591659;; --------------------------------------------------------
    1660                 BIOSORG_CHECK   0F84Dh  ; fixed wrt preceding code
     1660                BIOSORG_CHECK   0F84Dh  ; fixed wrt preceding code
    16611661int11_handler:
    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
     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
    16701670
    16711671
     
    16731673;; INT 15h handler - System services
    16741674;; --------------------------------------------------------
    1675                 BIOSORG_CHECK   0F859h  ; fixed wrt preceding code
     1675                BIOSORG_CHECK   0F859h  ; fixed wrt preceding code
    16761676int15_handler:
    16771677
    16781678if VBOX_BIOS_CPU ge 80286
    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
     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
    16941694not_blkmove:
    16951695
    16961696endif
    16971697
    1698                 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
     1698                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
    17151715int15_handler_popa_ret:
    1716                 DO_popa
     1716                DO_popa
    17171717int15_handler32_ret:
    1718                 pop     es
    1719                 pop     ds
    1720                 popf
    1721                 jmp     iret_modify_cf
     1718                pop     es
     1719                pop     ds
     1720                popf
     1721                jmp     iret_modify_cf
    17221722
    17231723apm_call:
    1724                 call    _apm_function
    1725                 jmp     int15_handler_popa_ret
     1724                call    _apm_function
     1725                jmp     int15_handler_popa_ret
    17261726
    17271727int15_handler_mouse:
    1728                 call    _int15_function_mouse
    1729                 jmp     int15_handler_popa_ret
     1728                call    _int15_function_mouse
     1729                jmp     int15_handler_popa_ret
    17301730
    17311731int15_handler32:
    17321732if VBOX_BIOS_CPU ge 80386
    1733                 ;; need to save/restore 32-bit registers
    1734                 .386
    1735                 pushad
    1736                 call    _int15_function32
    1737                 popad
    1738                 .286
     1733                ;; need to save/restore 32-bit registers
     1734                .386
     1735                pushad
     1736                call    _int15_function32
     1737                popad
     1738                .286
    17391739else
    1740                 DO_pusha
    1741                 call    _int15_function32
    1742                 DO_popa
    1743 endif
    1744                 jmp     int15_handler32_ret
     1740                DO_pusha
     1741                call    _int15_function32
     1742                DO_popa
     1743endif
     1744                jmp     int15_handler32_ret
    17451745
    17461746;;
     
    17481748;;
    17491749iret_modify_cf:
    1750                 jc      carry_set
    1751                 push    bp
    1752                 mov     bp, sp
    1753                 and     byte ptr [bp + 6], 0FEh
    1754                 pop     bp
    1755                 iret
     1750                jc      carry_set
     1751                push    bp
     1752                mov     bp, sp
     1753                and     byte ptr [bp + 6], 0FEh
     1754                pop     bp
     1755                iret
    17561756carry_set:
    1757                 push    bp
    1758                 mov     bp, sp
    1759                 or      byte ptr [bp + 6], 1
    1760                 pop     bp
    1761                 iret
     1757                push    bp
     1758                mov     bp, sp
     1759                or      byte ptr [bp + 6], 1
     1760                pop     bp
     1761                iret
    17621762
    17631763;;
    17641764;; INT 74h handler - PS/2 mouse (IRQ 12)
    17651765;;
    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
     1766int74_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
    17841784if VBOX_BIOS_CPU ge 80186
    1785                 push    0
     1785                push    0
    17861786else
    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]
     1787                xor     ax, ax
     1788                push    ax
     1789endif
     1790                pop     ds
     1791                push    ds:[40Eh]
     1792                pop     ds
     1793                call    far ptr ds:[22h]
    17941794int74_done:
    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
     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
     1803int74_handler   endp
     1804
     1805int76_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
     1818int76_handler   endp
    18191819
    18201820
     
    18231823;;
    18241824int70_handler:
    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
     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
    18341834
    18351835
     
    18411841;
    18421842int08_maybe_rollover:
    1843                ja       int08_rollover
    1844                 cmp     ax, 00B0h
    1845                jb       int08_rollover_store
    1846                 ;; there has been a midnight rollover
     1843                ja      int08_rollover
     1844                cmp     ax, 00B0h
     1845                jb      int08_rollover_store
     1846                ;; there has been a midnight rollover
    18471847int08_rollover:
    1848                 xor     dx, dx
    1849                 xor     ax, ax
    1850 
    1851                 inc     byte ptr ds:[70h]       ; increment rollover flag
     1848                xor     dx, dx
     1849                xor     ax, ax
     1850
     1851                inc     byte ptr ds:[70h]       ; increment rollover flag
    18521852int08_rollover_store:
    1853                 jmp     int08_store_ticks
     1853                jmp     int08_store_ticks
    18541854endif
    18551855
     
    18581858;; 8x8 font (first 128 characters)
    18591859;; --------------------------------------------------------
    1860                 BIOSORG 0FA6Eh, 0FA6Ch
     1860                BIOSORG 0FA6Eh, 0FA6Ch
    18611861include font8x8.inc
    18621862
     
    18651865;; INT 1Ah handler - Time of the day + PCI BIOS
    18661866;; --------------------------------------------------------
    1867                 BIOSORG_CHECK   0FE6Eh  ; fixed wrt preceding table
     1867                BIOSORG_CHECK   0FE6Eh  ; fixed wrt preceding table
    18681868int1a_handler:
    18691869if VBOX_BIOS_CPU ge 80386
    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
     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
    18841884endif
    18851885
    18861886int1a_normal:
    1887                 push    es
    1888                 push    ds
    1889                 DO_pusha
    1890                 C_SETUP
     1887                push    es
     1888                push    ds
     1889                DO_pusha
     1890                C_SETUP
    18911891int1a_callfunction:
    1892                 call    _int1a_function
    1893                 DO_popa
    1894                 pop     ds
    1895                 pop     es
    1896                 iret
     1892                call    _int1a_function
     1893                DO_popa
     1894                pop     ds
     1895                pop     es
     1896                iret
    18971897
    18981898
     
    19001900;; Timer tick - IRQ 0 handler
    19011901;; --------------------------------------------------------
    1902                 BIOSORG 0FEA5h, 0FEA3h
     1902                BIOSORG 0FEA5h, 0FEA3h
    19031903int08_handler:
    19041904if VBOX_BIOS_CPU ge 80386
    1905                 .386
    1906                 sti
    1907                 push    eax
     1905                .386
     1906                sti
     1907                push    eax
    19081908else
    1909                 sti
    1910                 push    ax
    1911 endif
    1912                 push    ds
    1913                 push    dx
    1914                 mov     ax, 40h
    1915                 mov     ds, ax
     1909                sti
     1910                push    ax
     1911endif
     1912                push    ds
     1913                push    dx
     1914                mov     ax, 40h
     1915                mov     ds, ax
    19161916
    19171917if VBOX_BIOS_CPU ge 80386
    1918                 mov     eax, ds:[6Ch]   ; get ticks dword
    1919                 inc     eax
     1918                mov     eax, ds:[6Ch]   ; get ticks dword
     1919                inc     eax
    19201920else
    1921                 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
     1921                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
    19261926int08_compare:
    19271927endif
    19281928
    1929                 ;; compare eax to one day's worth of ticks (at 18.2 Hz)
     1929                ;; compare eax to one day's worth of ticks (at 18.2 Hz)
    19301930if VBOX_BIOS_CPU ge 80386
    1931                 cmp     eax, 1800B0h
    1932                jb       int08_store_ticks
     1931                cmp     eax, 1800B0h
     1932                jb      int08_store_ticks
    19331933else
    1934                 cmp     dx, 18h
    1935                jb       int08_store_ticks
    1936                jmp      int08_maybe_rollover
     1934                cmp     dx, 18h
     1935                jb      int08_store_ticks
     1936                jmp     int08_maybe_rollover
    19371937endif
    19381938
    19391939if VBOX_BIOS_CPU ge 80386
    1940                 ;; there has been a midnight rollover
    1941                 xor     eax, eax
    1942                 inc     byte ptr ds:[70h]       ; increment rollover flag
     1940                ;; there has been a midnight rollover
     1941                xor     eax, eax
     1942                inc     byte ptr ds:[70h]       ; increment rollover flag
    19431943
    19441944int08_store_ticks:
    1945                 mov     ds:[6Ch], eax
     1945                mov     ds:[6Ch], eax
    19461946else
    19471947int08_store_ticks:
    1948                 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
     1948                mov     ds:[6Ch], ax
     1949                mov     ds:[6Ch+2], dx
     1950endif
     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
    19641964int08_floppy_off:
    19651965
    1966                 int     1Ch             ; call the user timer handler
    1967 
    1968                 cli
    1969                 call    eoi_master_pic
    1970                 pop     dx
    1971                 pop     ds
     1966                int     1Ch             ; call the user timer handler
     1967
     1968                cli
     1969                call    eoi_master_pic
     1970                pop     dx
     1971                pop     ds
    19721972if VBOX_BIOS_CPU ge 80386
    1973                 pop     eax
    1974                 .286
     1973                pop     eax
     1974                .286
    19751975else
    1976                 pop     ax
    1977 endif
    1978                 iret
     1976                pop     ax
     1977endif
     1978                iret
    19791979
    19801980
     
    19821982;; Initial interrupt vector offsets for POST
    19831983;; --------------------------------------------------------
    1984                 BIOSORG 0FEF3h, 0FEF1h
     1984                BIOSORG 0FEF3h, 0FEF1h
    19851985vector_table:
    19861986
     
    19901990;; BIOS copyright string
    19911991;; --------------------------------------------------------
    1992                 BIOSORG 0FF00h, 0FEFEh
     1992                BIOSORG 0FF00h, 0FEFEh
    19931993bios_string:
    1994                 db      BIOS_COPYRIGHT
     1994                db      BIOS_COPYRIGHT
    19951995
    19961996
     
    19981998;; IRET - default interrupt handler
    19991999;; --------------------------------------------------------
    2000                 BIOSORG 0FF53h, 0FF51h
     2000                BIOSORG 0FF53h, 0FF51h
    20012001
    20022002dummy_iret:
    2003                 iret
     2003                iret
    20042004
    20052005
     
    20072007;; INT 05h - Print Screen service
    20082008;; --------------------------------------------------------
    2009                 BIOSORG_CHECK   0FF54h  ; fixed wrt preceding
     2009                BIOSORG_CHECK   0FF54h  ; fixed wrt preceding
    20102010int05_handler:
    2011                 ;; Not implemented
    2012                 iret
     2011                ;; Not implemented
     2012                iret
    20132013
    20142014include smidmi.inc
     
    20172017;; Processor reset entry point
    20182018;; --------------------------------------------------------
    2019                 BIOSORG 0FFF0h, 0FFEEh
     2019                BIOSORG 0FFF0h, 0FFEEh
    20202020cpu_reset:
    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 
     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
     2033BIOSSEG         ends
     2034
     2035                end
     2036
Note: See TracChangeset for help on using the changeset viewer.

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