source: xtideuniversalbios/trunk/XTIDE_Universal_BIOS/Src/Handlers/Int19h.asm

Last change on this file was 605, checked in by krille_n_, 3 years ago

Changes:

  • The "Remove other hard drives" option in the Boot settings menu in XTIDECFG is now exposed in all BIOS builds. This is needed because the system BIOS in at least two Zenith computer models (Z-161 and Z-171) does not clear the BDA HD count which causes it to increment on warm boot. Running "Auto Configure" in XTIDECFG now also tries to identify these machines by doing a CRC check on the system BIOS and sets the option to YES if a match is found.
  • WORD_ALIGN is now 2 for XT builds. This should benefit XT class machines with 8086 and NEC V30 CPU:s and the cost is negligible (1 byte for the XT BIOS builds and 12 bytes for XTIDECFG.COM).
  • Other minor optimizations.
File size: 8.5 KB
RevLine 
[243]1; Project name  :   XTIDE Universal BIOS
2; Description   :   Int 19h Handler (Boot Loader).
3
[376]4;
[505]5; XTIDE Universal BIOS and Associated Tools
[526]6; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2013 by XTIDE Universal BIOS Team.
[376]7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2 of the License, or
11; (at your option) any later version.
[505]12;
[376]13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
[505]16; GNU General Public License for more details.
[376]17; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
[505]18;
[376]19
[243]20; Section containing code
21SECTION .text
22
23;--------------------------------------------------------------------
24; Int19h_BootLoaderHandler
25;   Parameters:
26;       Nothing
27;   Returns:
28;       Never returns (loads operating system)
29;--------------------------------------------------------------------
30Int19h_BootLoaderHandler:
[553]31    sti                                         ; Enable interrupts
[592]32%ifdef CLD_NEEDED
[553]33    cld                                         ; String instructions to increment pointers
[592]34%endif
[567]35%ifdef MODULE_VERY_LATE_INIT
[561]36    LOAD_BDA_SEGMENT_TO ds, ax                  ; Load BDA segment (zero) to DS
37    les     ax, [TEMPORARY_VECTOR_FOR_SYSTEM_INT13h*4]
38    mov     [BIOS_DISK_INTERRUPT_13h*4], ax
39    mov     [BIOS_DISK_INTERRUPT_13h*4+2], es
40    push    ds                                  ; BDA segment (zero)...
41    pop     es                                  ; ...to ES
42%else
[560]43    LOAD_BDA_SEGMENT_TO es, ax                  ; Load BDA segment (zero) to ES
[556]44%endif
[392]45    ; Fall to .PrepareBootLoaderStack
[243]46
[392]47
[243]48;--------------------------------------------------------------------
[392]49; Drive detection and boot menu use lots of stack so it is
50; wise to relocate stack. Otherwise something important from
51; interrupt vectors are likely corrupted, likely our own DPTs if
52; they are located to 30:0h.
53;
54; .PrepareBootLoaderStack
[243]55;   Parameters:
56;       ES:     BDA and interrupt vector segment (zero)
57;   Returns:
58;       Never returns (loads operating system)
59;--------------------------------------------------------------------
[392]60.PrepareBootLoaderStack:
[243]61    STORE_POST_STACK_POINTER
62    SWITCH_TO_BOOT_MENU_STACK
63    ; Fall to .InitializeDisplay
64
[392]65
[243]66;--------------------------------------------------------------------
67; .InitializeDisplay
68;   Parameters:
[392]69;       ES:     BDA and interrupt vector segment (zero)
[243]70;   Returns:
71;       Never returns (loads operating system)
72;--------------------------------------------------------------------
73.InitializeDisplay:
74    ; Change display mode if necessary
75    mov     ax, [cs:ROMVARS.wDisplayMode]   ; AH 00h = Set Video Mode
76    cmp     al, DEFAULT_TEXT_MODE
77    je      SHORT .InitializeDisplayLibrary
78    int     BIOS_VIDEO_INTERRUPT_10h
79.InitializeDisplayLibrary:
[392]80    call    DetectPrint_InitializeDisplayContext
81    ; Fall to .InitializeBiosAndDetectDrives
[243]82
[392]83
[243]84;--------------------------------------------------------------------
[392]85; .InitializeBiosAndDetectDrives
[243]86;   Parameters:
[392]87;       ES:     BDA and interrupt vector segment (zero)
[243]88;   Returns:
[392]89;       DS:     RAMVARS segment
[243]90;--------------------------------------------------------------------
[555]91.InitializeBiosAndDetectDrives:
[413]92    call    Initialize_AndDetectDrives
93
94%ifdef MODULE_HOTKEYS
[547]95    ; Last hard drive might have scrolled Hotkey Bar out of screen.
96    ; We want to display it during wait.
[599]97    ;call   HotkeyBar_UpdateDuringDriveDetection
[547]98
[605]99    push    ds
100    push    es
101    pop     ds
102
[413]103.WaitUntilTimeToCloseHotkeyBar:
[605]104    mov     ax, [BDA.dwTimerTicks]
105    sub     ax, [BOOTVARS.hotkeyVars+HOTKEYVARS.wTimeWhenDisplayed]
[524]106    cmp     ax, MIN_TIME_TO_DISPLAY_HOTKEY_BAR
[413]107    jb      SHORT .WaitUntilTimeToCloseHotkeyBar
[599]108
109    ; Restore system timer tick handler since hotkeys are no longer needed
110    cli
[605]111    mov     ax, [BOOTVARS.hotkeyVars+HOTKEYVARS.fpPrevTimerHandler]
112    mov     [BIOS_SYSTEM_TIMER_TICK_INTERRUPT_08h*4], ax
113    mov     ax, [BOOTVARS.hotkeyVars+HOTKEYVARS.fpPrevTimerHandler+2]
114    mov     [BIOS_SYSTEM_TIMER_TICK_INTERRUPT_08h*4+2], ax
[599]115    sti
[605]116
117    pop     ds
[413]118%endif
[555]119    ; Fall to .ResetAllDrives
120
121
122;--------------------------------------------------------------------
123; .ResetAllDrives
124;   Parameters:
125;       DS:     RAMVARS segment
126;       ES:     BDA and interrupt vector segment (zero)
127;   Returns:
128;       Nothing
129;--------------------------------------------------------------------
130.ResetAllDrives:
131    ; Reset all drives in the system, not just our drives.
132    xor     ax, ax      ; Disk Controller Reset
133    mov     dl, 80h     ; Reset all hard drives and floppy drives
134    int     BIOS_DISK_INTERRUPT_13h
[392]135    ; Fall to SelectDriveToBootFrom
[243]136
[392]137
[243]138;--------------------------------------------------------------------
[392]139; SelectDriveToBootFrom
[243]140;   Parameters:
141;       DS:     RAMVARS segment
[392]142;       ES:     BDA and interrupt vector segment (zero)
[243]143;   Returns:
144;       Never returns (loads operating system)
145;--------------------------------------------------------------------
[492]146; The following macro could be easily inlined below.  Why a macro?  Depending on the combination
147; of MODULE_HOTKEYS or MODULE_BOOT_MENU, this code needs to either come before or after the
[505]148; call to the boot menu.
[492]149;
150%macro TRY_TO_BOOT_DL_AND_DH_DRIVES 0
151    push    dx                                  ; it's OK if this is left on the stack, if we are
[505]152                                                ; successful, the following call does not return
[528]153    call    BootSector_TryToLoadFromDriveDL_AndBoot
[492]154    pop     dx
155    mov     dl, dh
[528]156    call    BootSector_TryToLoadFromDriveDL_AndBoot
[492]157%endmacro
[505]158
[528]159
160SelectDriveToBootFrom:      ; Function starts here
[395]161%ifdef MODULE_HOTKEYS
[528]162    mov     al, [es:BOOTVARS.hotkeyVars+HOTKEYVARS.bScancode]
[492]163    cmp     al, ROM_BOOT_HOTKEY_SCANCODE
[528]164    je      SHORT .RomBoot                      ; CF clear so ROM boot
[392]165%ifdef MODULE_BOOT_MENU
[492]166    cmp     al, BOOT_MENU_HOTKEY_SCANCODE
[528]167    je      SHORT .BootMenu
168%endif ; MODULE_BOOT_MENU
169
170.TryUsingHotKeysCode:
[492]171    call    HotkeyBar_GetBootDriveNumbersToDX
[528]172    call    DriveXlate_SetDriveToSwap           ; Enable primary boot device translation
173    xchg    dl, dh
174    call    DriveXlate_SetDriveToSwap           ; Enable secondary boot device translation
175    xchg    dl, dh
[529]176    call    DriveXlate_ToOrBack                 ; Translate now so boot device will appear as 00h or 80h to OS
[492]177    TRY_TO_BOOT_DL_AND_DH_DRIVES
178    ;; falls through to boot menu, if it is present.  If not present, falls through to rom boot.
[505]179%endif ; MODULE_HOTKEYS
[392]180
[528]181
[492]182%ifdef MODULE_BOOT_MENU
[505]183.BootMenu:
[492]184    call    BootMenu_DisplayAndReturnDriveInDLRomBootClearCF
[528]185    jnc     SHORT .RomBoot                      ; CF clear so ROM boot
[392]186
[528]187    call    DriveXlate_Reset
188%ifdef MODULE_HOTKEYS
189    jmp     SHORT .TryUsingHotKeysCode          ; Selected drive stored as hotkey
190%else ; Boot menu without hotkeys, secondary boot drive is always 00h or 80h
[492]191    mov     dh, dl                              ; Setup for secondary drive
[505]192    not     dh                                  ; Floppy goes to HD, or vice versa
193    and     dh, 80h                             ; Go to first drive of the floppy or HD set
[528]194    call    DriveXlate_SetDriveToSwap
195    call    DriveXlate_ToOrBack
196    TRY_TO_BOOT_DL_AND_DH_DRIVES
197    jmp     SHORT .BootMenu                     ; Show boot menu again
198%endif ; MODULE_HOTKEYS
[398]199
[505]200%endif ; MODULE_BOOT_MENU
[392]201
[528]202; No hotkeys and no boot menu means fixed "A then C" boot order
[505]203%ifndef MODULE_HOTKEYS OR MODULE_BOOT_MENU
[529]204    xor     dl, dl                              ; Try to boot from Floppy Drive A
[528]205    call    BootSector_TryToLoadFromDriveDL_AndBoot
[529]206    mov     dl, 80h                             ; Try to boot from Hard Drive C
[528]207    call    BootSector_TryToLoadFromDriveDL_AndBoot
[386]208%endif
[243]209
[493]210.RomBoot:
211%ifdef MODULE_DRIVEXLATE
212    call    DriveXlate_Reset                    ; Clean up any drive mappings before Rom Boot
213%endif
[597]214    stc
215    ;; fall through to Int19h_JumpToBootSectorInESBXOrRomBoot
[392]216
[243]217;--------------------------------------------------------------------
[597]218; Int19h_JumpToBootSectorInESBXOrRomBoot
[243]219;
220; Switches back to the POST stack, clears the DS and ES registers,
221; and either jumps to the MBR (Master Boot Record) that was just read,
[601]222; or calls the ROM's boot routine on interrupt 18h.
[243]223;
224;   Parameters:
225;       DL:     Drive to boot from (translated, 00h or 80h)
[597]226;       CF:     Clear for Boot Sector Boot
227;               Set for ROM Boot
228;       ES:BX:  (if CF clear) Ptr to boot sector (ES = zero)
[243]229;
230;   Returns:
231;       Never returns
232;--------------------------------------------------------------------
[597]233Int19h_JumpToBootSectorInESBXOrRomBoot:
234    mov     ax, es      ; Clear AX. NOTE: can't use XOR (LOAD_BDA_SEGMENT_TO) as it impacts CF
[243]235    SWITCH_BACK_TO_POST_STACK
236
237; clear segment registers before boot sector or rom call
[597]238Int19h_JumpToBootSectorInESBXOrRomBootWithoutStackChange:
239    mov     ax, es      ; Clear AX and preserve CF
[505]240    mov     ds, ax
[243]241%ifdef USE_386
242    mov     fs, ax
243    mov     gs, ax
244%endif
[597]245    jc      SHORT .RomBoot
[243]246
247; jump to boot sector
[597]248    push    es          ; sgment address for MBR
[243]249    push    bx          ; offset address for MBR
250    retf                ; NOTE: DL is set to the drive number
251
252; Boot by calling INT 18h (ROM Basic of ROM DOS)
[596]253.RomBoot:
[505]254    int     BIOS_BOOT_FAILURE_INTERRUPT_18h ; Never returns
Note: See TracBrowser for help on using the repository browser.