mirror of
https://github.com/stevenhowes/wbios.git
synced 2026-05-26 15:53:34 +01:00
Initial commit of 1.11 source as released by PC Engines
Original source https://www.pcengines.ch/file/wbios111s.zip
This commit is contained in:
@@ -0,0 +1,398 @@
|
||||
;
|
||||
; Miscellaneous interrupts
|
||||
;
|
||||
; (C)1997-2001 Pascal Dornier / PC Engines; All rights reserved.
|
||||
; This file is licensed pursuant to the COMMON PUBLIC LICENSE 0.5.
|
||||
;
|
||||
; Limitations:
|
||||
;
|
||||
; - INT15 support is very limited.
|
||||
;
|
||||
; pd 050206 add Int15 E820, change to d_exmem
|
||||
; pd 020215 add NO_RTC option
|
||||
; pd 991127 add PS/2 mouse hook
|
||||
|
||||
;
|
||||
; Dummy interrupts -> IRET
|
||||
;
|
||||
intdummy:
|
||||
int00: ;divide by zero
|
||||
int01: ;single step
|
||||
int03: ;breakpoint
|
||||
int04: ;overflow
|
||||
int06: ;invalid opcode
|
||||
int07: ;coprocessor not available
|
||||
int1b: ;keyboard break
|
||||
int1c: ;user timer tick
|
||||
|
||||
iret
|
||||
|
||||
;
|
||||
; NMI
|
||||
;
|
||||
nmi: push ax
|
||||
in al,port61 ;check type of NMI
|
||||
#if ! def NO_NMI
|
||||
shl al,1
|
||||
jb nmi1 ;$80 set: parity error
|
||||
shl al,1
|
||||
jb nmi2 ;$40 set: I/O check
|
||||
#else
|
||||
mov al,33h ;display POST code on NMI
|
||||
out post,al
|
||||
#endif
|
||||
mov al,0dh ;read CMOS register -> clear NMI
|
||||
out cm_idx,al
|
||||
out iowait,al
|
||||
in al,cm_dat
|
||||
pop ax
|
||||
iret
|
||||
|
||||
#if ! def NO_NMI
|
||||
|
||||
; display error message
|
||||
|
||||
nmi1: mov si,offset msg_parit
|
||||
jmp short nmi3
|
||||
|
||||
nmi2: mov si,offset msg_iochk
|
||||
|
||||
nmi3: mov ax,7 ;set video mode
|
||||
int 10h
|
||||
call v_msg ;display message
|
||||
mov si,offset msg_halt
|
||||
call v_msg ;"system halted"
|
||||
cli ;hang system
|
||||
hlt
|
||||
#endif
|
||||
;
|
||||
; end of interrupt, primary controller
|
||||
;
|
||||
inteoi: push ax
|
||||
mov al,eoi
|
||||
out pic0,al
|
||||
pop ax
|
||||
iret
|
||||
;
|
||||
; end of interrupt, secondary controller
|
||||
;
|
||||
inteoi2: push ax
|
||||
mov al,eoi
|
||||
out pic1,al
|
||||
out pic0,al
|
||||
pop ax
|
||||
iret
|
||||
;
|
||||
; INT 5: print screen
|
||||
;
|
||||
int05: push ax
|
||||
push ds
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov byte [m_prtsc],0ffh ;error
|
||||
pop ds
|
||||
pop ax
|
||||
iret
|
||||
;
|
||||
; INT 11 entry: equipment flag
|
||||
;
|
||||
int11: push ds
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,[m_devflg]
|
||||
pop ds
|
||||
iret
|
||||
;
|
||||
; INT12 entry: memory size
|
||||
;
|
||||
int12: push ds
|
||||
xor ax,ax
|
||||
mov ds,ax
|
||||
mov ax,[m_lomem]
|
||||
pop ds
|
||||
iret
|
||||
;
|
||||
; AH=87: block move
|
||||
;
|
||||
; This assumes that A20 gate is always open (preferably using
|
||||
; port 92), and uses "unreal mode". Interrupts are disabled during
|
||||
; block move, which can add considerably to interrupt latency.
|
||||
;
|
||||
; Note we don't close the A20 gate on return.
|
||||
;
|
||||
int1587: push ax
|
||||
push bx
|
||||
push si
|
||||
push di
|
||||
push ds
|
||||
push es
|
||||
call cs_a20on ;enable A20 gate
|
||||
cld
|
||||
and ecx,0000ffffh
|
||||
mov edi,[es:si+1ah] ;24 bit destination address
|
||||
and edi,00ffffffh ;mask high bits
|
||||
mov esi,[es:si+12h] ;24 bit destination address
|
||||
and esi,00ffffffh ;mask high bits
|
||||
|
||||
; enter unreal mode
|
||||
|
||||
cli ;disable interrupts
|
||||
lgdt [cs:gdt] ;load GDT
|
||||
mov eax,cr0
|
||||
or al,1 ;enable protected mode
|
||||
mov cr0,eax
|
||||
jmp short int15872 ;flush queue
|
||||
int15872: mov bx,8 ;selector
|
||||
mov ds,bx
|
||||
mov es,bx
|
||||
and al,0feh ;exit protected mode
|
||||
mov cr0,eax
|
||||
|
||||
shr cx,1 ;convert to 32 bit words
|
||||
a4 rep movsd ;do the block move
|
||||
jnb int15873
|
||||
a4 movsw ;move a 16 bit "orphan"
|
||||
int15873: pop es
|
||||
pop ds
|
||||
sti ;now interrupts are ok again
|
||||
pop di
|
||||
pop si
|
||||
pop bx
|
||||
pop ax
|
||||
mov ah,0 ;ok return
|
||||
clc
|
||||
retf 2
|
||||
;
|
||||
; INT15 function 86: wait
|
||||
;
|
||||
int1586: pusha
|
||||
mov bx,dx ;microseconds / 1024 -> BX
|
||||
shr bx,10
|
||||
shl cx,6
|
||||
or bx,cx
|
||||
call cs_waitbx ;do the delay
|
||||
popa
|
||||
clc ;return ok status
|
||||
retf 2
|
||||
;
|
||||
; INT15 entry: multiplex interrupt
|
||||
;
|
||||
int15: sti
|
||||
|
||||
;& push ax ;display command code
|
||||
;& mov al,ah
|
||||
;& call diaghex
|
||||
;& pop ax
|
||||
|
||||
cmp ah,87h ;block move ?
|
||||
jz int1587
|
||||
#if def PS2MOUSE
|
||||
cmp ah,0c2h ;PS/2 mouse ?
|
||||
jnz int15nc2
|
||||
jmp int15c2
|
||||
int15nc2:
|
||||
#endif
|
||||
cmp ah,88h ;memory size determine ?
|
||||
jz int1588
|
||||
cmp ah,0c0h ;configuration table ?
|
||||
jz int15c0
|
||||
cmp ah,86h ;wait ?
|
||||
jz int1586
|
||||
cmp ax,0e801h ;big memory size ?
|
||||
jz int15e8
|
||||
cmp ax,0e820h ;system memory map ?
|
||||
jz inte820
|
||||
|
||||
#if def INT15_24
|
||||
cmp ax,02400
|
||||
jz int1524
|
||||
cmp ax,02401
|
||||
jz int1524
|
||||
#endif
|
||||
|
||||
#if def CLE266
|
||||
cmp ah,05f ;VIA VGA API ?
|
||||
jnz int15ex ;:yes
|
||||
jmp int15_cle
|
||||
#endif
|
||||
|
||||
int15ex: mov ah,86h ;bad command
|
||||
stc
|
||||
retf 2 ;return
|
||||
|
||||
#if def INT15_24
|
||||
|
||||
; Function 24xx is supposed to control the A20 gate.
|
||||
; This is added to keep GRUB from using the keyboard
|
||||
; controller on legacy free systems.
|
||||
|
||||
int1524: mov ah,00 ;A20 gate "support" - we just lie
|
||||
clc ;and say we did it... tinyBIOS always
|
||||
retf 2 ;leaves A20 gate open
|
||||
#endif
|
||||
;
|
||||
; AH=88: determine extended memory size
|
||||
;
|
||||
int1588:
|
||||
#if def NO_RTC
|
||||
mov eax,dword [cs:d_exmem] ;get extended memory size
|
||||
shr eax,10 ;convert to KB
|
||||
cmp eax,63*1024 ;limit to 64MB
|
||||
jb >l1
|
||||
mov eax,63*1024
|
||||
l1:
|
||||
#else
|
||||
push bx
|
||||
mov ah,cm_exh ;read high memory size
|
||||
call rtc_read
|
||||
mov bh,al
|
||||
mov ah,cm_exl ;read low memory size
|
||||
call rtc_read
|
||||
mov ah,bh
|
||||
pop bx
|
||||
#endif
|
||||
iret
|
||||
;
|
||||
; AH=C0: configuration table
|
||||
;
|
||||
int15c0: mov bx,offset conf_tab ;ES:BX = @configuration table
|
||||
push cs
|
||||
pop es
|
||||
mov ah,0
|
||||
clc
|
||||
retf 2
|
||||
;
|
||||
; AH=E8: extended memory size
|
||||
;
|
||||
int15e8: mov eax,dword [cs:d_exmem] ;get extended memory size
|
||||
mov ebx,eax
|
||||
shr eax,10 ;convert -> 1KB blocks
|
||||
cmp eax,15*1024
|
||||
jb >l1
|
||||
mov ax,15*1024 ;AX = memory 1MB to 16MB in 1KB blocks
|
||||
l1: mov cx,ax ;configured = actual memory
|
||||
|
||||
shr ebx,16 ;convert -> 64KB blocks
|
||||
sub bx,16*16 ;subtract low 16MB
|
||||
jnb >l2 ;:ok
|
||||
xor bx,bx ;return 0 if less than 16MB
|
||||
l2: mov dx,bx ;configured = actual memory
|
||||
clc
|
||||
retf 2
|
||||
;
|
||||
; Int15 E820: get system memory map
|
||||
;
|
||||
inte820: push si
|
||||
cmp edx,0534d4150 ;check cookie
|
||||
jnz e820_err
|
||||
mov si,offset e820map ;pointer to map
|
||||
inc ebx ;point to next entry
|
||||
mov eax,ebx ;index -> eax
|
||||
e820_1: dec eax
|
||||
jz e820_2 ;:got the right si
|
||||
add si,20
|
||||
cmp si,e820mape ;end of map ?
|
||||
jb e820_1
|
||||
e820_err: mov ah,086 ;error code
|
||||
stc
|
||||
pop si
|
||||
retf 2
|
||||
|
||||
e820_2: mov cx,5 ;we always copy 20 bytes
|
||||
cld
|
||||
push di
|
||||
cs: rep movsd
|
||||
pop di
|
||||
mov cx,20 ;say 20 bytes
|
||||
mov eax,edx ;cookie to eax
|
||||
cmp si,e820mape ;end of table ?
|
||||
jnz e820_3 ;:no
|
||||
xor bx,bx ;clear BX = end of table
|
||||
e820_3: clc
|
||||
pop si
|
||||
retf 2 ;ok exit
|
||||
;
|
||||
; configuration table
|
||||
;
|
||||
conf_tab: dw 8 ;length
|
||||
db 0fch ;model byte
|
||||
db 01 ;sub model
|
||||
db 00 ;BIOS level
|
||||
db 70h ;cascaded interrupt 2, RTC, keyboard
|
||||
;scan hook 1A
|
||||
db 0,0,0,0 ;reserved
|
||||
|
||||
;
|
||||
; INT18 entry: expansion ROM
|
||||
;
|
||||
#if ! def int18 ;if not defined by user code
|
||||
int18: mov si,msg_noboot ;display message "No boot device..."
|
||||
call v_msg
|
||||
mov ah,0 ;get a keystroke
|
||||
int 16h
|
||||
iret
|
||||
#endif
|
||||
;
|
||||
; INT19 entry: boot operating system
|
||||
;
|
||||
int19: mov byte [m_fdcnt],36 ;spin down drive A: after 2 seconds
|
||||
|
||||
#if def BOOT_AC
|
||||
mov dl,0 ;drive A:
|
||||
mov cx,1 ;retry count
|
||||
call bootdrv ;try to boot
|
||||
test ah,80h ;time out ?
|
||||
jnz int19_1 ;yes: probably no disk
|
||||
mov dl,0 ;drive A:
|
||||
mov cx,2 ;retry count
|
||||
call bootdrv ;try to boot
|
||||
int19_1: mov dl,80h ;drive C:
|
||||
mov cx,3 ;retry count
|
||||
call bootdrv ;try to boot
|
||||
#else
|
||||
mov dl,80h ;drive C:
|
||||
mov cx,3 ;retry count
|
||||
call bootdrv ;try to boot
|
||||
mov dl,0 ;drive A:
|
||||
mov cx,3 ;retry count
|
||||
call bootdrv ;try to boot
|
||||
#endif
|
||||
int 18h ;display message / expansion ROM
|
||||
jmp int19
|
||||
;
|
||||
; Try to boot operating system from drive DL, CX retries
|
||||
;
|
||||
bootdrv: push cx
|
||||
xor ax,ax ;$0000:$7c00 = destination address
|
||||
mov es,ax
|
||||
mov bx,7c00h
|
||||
mov ax,0201h ;read, 1 sector
|
||||
mov cx,0001 ;cylinder 0, sector 1
|
||||
mov dh,0 ;head 0
|
||||
int 13h ;try to read boot sector
|
||||
pop cx
|
||||
jnb bootdrv2 ;:ok
|
||||
push ax
|
||||
mov ah,0 ;reset disk system
|
||||
int 13h
|
||||
pop ax ;restore status
|
||||
loop bootdrv ;try 3 times
|
||||
bootdrv9: ret ;return, didn't work
|
||||
|
||||
; check boot sector signature
|
||||
|
||||
bootdrv2: cmp word [es:7dfeh],0aa55h
|
||||
jnz bootdrv9 ;:no
|
||||
jmp far 0:7c00h ;jump to boot sector
|
||||
;
|
||||
; IRQ13: coprocessor error
|
||||
;
|
||||
irq13: push ax
|
||||
mov al,0 ;clear error
|
||||
out 0f0h,al
|
||||
mov al,eoi ;end of interrupt
|
||||
out pic1,al
|
||||
out pic0,al
|
||||
pop ax
|
||||
int 2 ;NMI -> further handling
|
||||
iret
|
||||
Reference in New Issue
Block a user