mirror of
https://github.com/stevenhowes/wbios.git
synced 2026-05-27 00:03:32 +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:
+332
@@ -0,0 +1,332 @@
|
||||
;
|
||||
; WRAP BIOS update - for Xmodem upload
|
||||
;
|
||||
; pd 030807, 030812
|
||||
; pd 050625 add 39VF040
|
||||
;
|
||||
rombase equ 0fffe0000
|
||||
CONSOLE equ 03f8
|
||||
port61 equ 061
|
||||
iowait equ 0eb
|
||||
|
||||
org 0
|
||||
|
||||
db "TB" ;signature
|
||||
|
||||
entry: jmp start
|
||||
;
|
||||
; output AL to serial port
|
||||
;
|
||||
xm_out: push dx
|
||||
push ax
|
||||
mov dx,CONSOLE+5
|
||||
xm_out1: in al,dx ;wait for transmit ready
|
||||
out iowait,ax
|
||||
test al,40h
|
||||
jz xm_out1
|
||||
mov dl,low(CONSOLE)
|
||||
pop ax
|
||||
out dx,al
|
||||
pop dx
|
||||
ret
|
||||
;
|
||||
; display message [cs:si]
|
||||
;
|
||||
v_msg1: call xm_out
|
||||
v_msg: cs: lodsb
|
||||
cmp al,0
|
||||
jnz v_msg1
|
||||
ret
|
||||
;
|
||||
; variables
|
||||
;
|
||||
even
|
||||
|
||||
bufpt: dd 0 ;buffer pointer
|
||||
devid: dw 0 ;device ID
|
||||
file: dw 0 ;file handle
|
||||
bufseg: dw 0 ;buffer segment
|
||||
curseg: dw 0 ;current segment
|
||||
count: db 4 ;number of 32KB blocks to be read
|
||||
rom64: db 0 ;1 = 64KB flash
|
||||
|
||||
msg_strt: db "WRAP flash update",13,10,0
|
||||
msg_len: db "Invalid image length",13,10,0
|
||||
msg_open: db "Flash ID",0
|
||||
msg_fail: db " - FAIL !",13,10,0
|
||||
msg_zap: db 13,10,"Erase",0
|
||||
msg_set: db " Program",0
|
||||
msg_cmp: db " Verify",0
|
||||
msg_ok: db 13,10,"Flash updated successfully.",13,10,0
|
||||
;
|
||||
; main code
|
||||
;
|
||||
start: cld
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov si,offset msg_strt
|
||||
call v_msg
|
||||
|
||||
mov si,offset msg_len
|
||||
mov ax,es ;verify image length
|
||||
cmp ax,03000
|
||||
jnz barf ;:bad
|
||||
cmp di,buf
|
||||
jb barf
|
||||
|
||||
; set segment values
|
||||
|
||||
xor eax,eax ;set buffer segment
|
||||
mov ax,cs
|
||||
shl eax,4 ;-> physical
|
||||
add eax,offset buf
|
||||
mov [bufpt],eax
|
||||
shr eax,4 ;-> segment
|
||||
mov [bufseg],ax
|
||||
mov [curseg],ax
|
||||
|
||||
xor eax,eax ;set GDT physical address
|
||||
mov ax,cs
|
||||
shl eax,4
|
||||
add eax,offset gdt
|
||||
mov dword [gdtadr],eax
|
||||
|
||||
mov si,offset msg_open ;look for flash
|
||||
call v_msg
|
||||
call rom_open ;read device ID
|
||||
jb barf
|
||||
|
||||
mov si,offset msg_zap ;erase flash
|
||||
call v_msg
|
||||
call rom_zap
|
||||
jb barf
|
||||
|
||||
mov si,offset msg_set ;program flash
|
||||
call v_msg
|
||||
call rom_set
|
||||
jb barf
|
||||
|
||||
mov si,offset msg_cmp ;verify flash
|
||||
call v_msg
|
||||
call rom_cmp
|
||||
jb barf
|
||||
|
||||
mov si,offset msg_ok ;success message
|
||||
barf: call v_msg
|
||||
call rom_exit ;write-protect flash
|
||||
xor ax,ax ;restore DS,ES
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
retf ;return to setup
|
||||
;
|
||||
; global descriptor table (GDT) for unreal mode
|
||||
;
|
||||
db (($+15) and 0fff0h)-$ dup 0ffh ;even 16
|
||||
gdt: dw gdtend-gdt-1 ;GDT limit
|
||||
gdtadr: dw gdt,000fh ;linear address of GDT
|
||||
dw 0
|
||||
dw 0ffffh,0,9300h,008fh ;4G data segment, accessed
|
||||
gdtend:
|
||||
;
|
||||
; Enter unreal (4GB segment) mode -> change DS,ES selector
|
||||
;
|
||||
; based on code in DDJ 7/90
|
||||
;
|
||||
getunreal: cli ;disable interrupts
|
||||
cs: lgdt [gdt] ;load GDT (in data module, writeable)
|
||||
|
||||
mov eax,cr0
|
||||
or al,1 ;enable protected mode
|
||||
mov cr0,eax
|
||||
jmp short getunrl2 ;flush queue
|
||||
getunrl2: mov bx,8 ;selector
|
||||
mov ds,bx
|
||||
mov es,bx
|
||||
and al,0feh ;exit protected mode
|
||||
mov cr0,eax
|
||||
ret
|
||||
;
|
||||
; get back to normal segments
|
||||
;
|
||||
getreal: push cs
|
||||
pop ds
|
||||
sti
|
||||
ret
|
||||
;
|
||||
; open flash access
|
||||
;
|
||||
rom_open: mov eax,80009050h ;9052 enable flash writes sc172
|
||||
mov dx,0cf8
|
||||
out dx,eax
|
||||
xchg eax,ebx
|
||||
mov dl,0fe
|
||||
in al,dx
|
||||
or al,2 ;enable flash write
|
||||
xchg eax,ebx
|
||||
mov dl,0f8
|
||||
out dx,eax
|
||||
mov dl,0fe
|
||||
xchg eax,ebx
|
||||
out dx,al
|
||||
|
||||
; read device ID
|
||||
|
||||
call getunreal ;enter unreal mode
|
||||
mov ebx,rombase
|
||||
mov byte [ebx+05555],0aa ;software ID
|
||||
mov byte [ebx+02aaa],055
|
||||
mov byte [ebx+05555],090
|
||||
out iowait,al ;short delay
|
||||
mov ax,[ebx] ;read the device ID
|
||||
mov byte [ebx],0f0 ;exit ID mode
|
||||
call getreal
|
||||
mov [devid],ax
|
||||
|
||||
; check device ID
|
||||
|
||||
cmp al,0bf ;SST ?
|
||||
jnz rom_open9 ;no: fail
|
||||
cmp ah,0d6 ;39VF020
|
||||
jz rom_open8
|
||||
cmp ah,0d7 ;39VF040
|
||||
jz rom_open8
|
||||
cmp ah,0b5 ;39SF010
|
||||
jz rom_open8
|
||||
cmp ah,0d5 ;39VF010
|
||||
jz rom_open8
|
||||
inc byte [rom64] ;set flag for 64KB flash
|
||||
cmp ah,0b4 ;39SF512
|
||||
jz rom_open8
|
||||
cmp ah,0d4 ;39VF512
|
||||
jnz rom_open9
|
||||
rom_open8:
|
||||
clc
|
||||
ret
|
||||
rom_open9:
|
||||
stc
|
||||
mov si,offset msg_fail
|
||||
ret
|
||||
;
|
||||
; close flash access
|
||||
;
|
||||
rom_exit: mov eax,80009050h ;9052 disable flash writes sc172
|
||||
mov dx,0cf8
|
||||
out dx,eax
|
||||
xchg eax,ebx
|
||||
mov dl,0fe
|
||||
in al,dx
|
||||
and al,not 2 ;enable flash write
|
||||
xchg eax,ebx
|
||||
mov dl,0f8
|
||||
out dx,eax
|
||||
mov dl,0fe
|
||||
xchg eax,ebx
|
||||
out dx,al
|
||||
ret
|
||||
;
|
||||
; chip erase flash
|
||||
;
|
||||
rom_zap: call getunreal ;enter unreal mode
|
||||
mov ebx,rombase
|
||||
mov byte [ebx+05555],0aa ;erase setup
|
||||
mov byte [ebx+02aaa],055
|
||||
mov byte [ebx+05555],080
|
||||
mov byte [ebx+05555],0aa ;erase command
|
||||
mov byte [ebx+02aaa],055
|
||||
mov byte [ebx+05555],010
|
||||
|
||||
mov bx,100 ;wait for 100 ms
|
||||
call cs_waitbx
|
||||
|
||||
mov eax,0ffffffff ;check for erase
|
||||
mov ecx,08000 ;128KB
|
||||
mov edi,rombase
|
||||
a4 repz scasd
|
||||
jnz rom_open9 ;:failure
|
||||
call getreal
|
||||
clc
|
||||
ret
|
||||
;
|
||||
; program flash [bufpt] -> [rombase]
|
||||
;
|
||||
rom_set: mov esi,[bufpt]
|
||||
mov edi,rombase
|
||||
mov ecx,020000 ;128KB
|
||||
cmp byte [rom64],1 ;64KB flash ?
|
||||
jnz rom_set2
|
||||
shr ecx,1 ;yes
|
||||
add esi,ecx
|
||||
add edi,ecx
|
||||
rom_set2: call getunreal
|
||||
mov ebx,edi ;^base
|
||||
|
||||
rom_set3: mov al,[esi] ;data byte
|
||||
cmp al,0ff
|
||||
jz rom_set5 ;blank -> skip
|
||||
|
||||
mov byte [ebx+05555],0aa ;byte program command
|
||||
mov byte [ebx+02aaa],055
|
||||
mov byte [ebx+05555],0a0
|
||||
mov [edi],al
|
||||
|
||||
mov dx,1000 ;time-out
|
||||
rom_set4: cmp [edi],al ;correct data ?
|
||||
jz rom_set5 ;:yes
|
||||
dec dx
|
||||
jnz rom_set4
|
||||
jmp rom_open9 ;program failure, bail
|
||||
|
||||
rom_set5: inc esi
|
||||
inc edi
|
||||
dec ecx
|
||||
jnz rom_set3 ;:another
|
||||
call getreal
|
||||
clc
|
||||
ret
|
||||
;
|
||||
; compare flash [bufpt] -> [rombase]
|
||||
;
|
||||
rom_cmp: mov esi,[bufpt]
|
||||
mov edi,rombase
|
||||
mov ecx,020000 ;128KB
|
||||
cmp byte [rom64],1 ;64KB flash ?
|
||||
jnz rom_cmp2
|
||||
shr ecx,1 ;yes
|
||||
add esi,ecx
|
||||
add edi,ecx
|
||||
rom_cmp2: call getunreal
|
||||
shr ecx,2
|
||||
mov eax,[esi]
|
||||
cmp [edi],eax
|
||||
jnz rom_open9 ;:failure
|
||||
lea esi,[esi+4]
|
||||
lea edi,[edi+4]
|
||||
dec ecx
|
||||
jnz rom_cmp2
|
||||
call getreal
|
||||
clc
|
||||
ret
|
||||
;
|
||||
; Wait BX milliseconds - depends on refresh rate !!!
|
||||
;
|
||||
cs_waitbx: inc bx
|
||||
jmp short cs_wbx8
|
||||
|
||||
cs_wbx1: mov cx,62 ;62 refresh cycles per millisecond
|
||||
cs_wbx2: in al,port61
|
||||
and al,10h
|
||||
mov ah,al
|
||||
cs_wbx3: in al,port61 ;wait for refresh bit to change state
|
||||
and al,10h
|
||||
cmp al,ah
|
||||
jz cs_wbx3
|
||||
loop cs_wbx2 ;:another iteration
|
||||
cs_wbx8: dec bx ;another millisecond ?
|
||||
jnz cs_wbx1
|
||||
cs_wbx9: ret
|
||||
;
|
||||
; flash image is appended here
|
||||
;
|
||||
db (($+15) and 0fff0h)-$ dup 0ffh ;even 16
|
||||
buf: ;flash image follows here
|
||||
Reference in New Issue
Block a user