mirror of
https://github.com/stevenhowes/wbios.git
synced 2026-05-26 15:53:34 +01:00
d410ad0acb
Original source https://www.pcengines.ch/file/wbios111s.zip
361 lines
7.0 KiB
Plaintext
361 lines
7.0 KiB
Plaintext
;
|
|
; WRAP BIOS update
|
|
;
|
|
; pd 030807
|
|
; pd 040115 compare before erase, retry message on failure
|
|
;
|
|
org 0100
|
|
|
|
jmp start
|
|
;
|
|
; variables
|
|
;
|
|
even
|
|
|
|
rombase equ 0fffe0000
|
|
port61 equ 061
|
|
iowait equ 0eb
|
|
|
|
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
|
|
db "Reading 128KB flash image "
|
|
filename: db "wrap.rom",0 ;file name
|
|
msg_io: db " - I/O error !",13,10,0
|
|
msg_open: db 13,10,"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 update OK.",13,10,0
|
|
msg_try: db "(R)etry (Q)uit ?",13,10,0
|
|
msg_same: db 13,10,"Flash verify OK.",13,10,0
|
|
;
|
|
; main code
|
|
;
|
|
start: cld
|
|
mov sp,offset stack1
|
|
|
|
mov si,offset msg_strt
|
|
call v_msg
|
|
|
|
; set segment values
|
|
|
|
xor eax,eax ;set buffer segment
|
|
mov ax,cs
|
|
shl eax,4 ;-> physical
|
|
add eax,offset stack1
|
|
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
|
|
|
|
; open image file
|
|
|
|
mov dx,offset filename
|
|
mov ax,3d00h ;open file
|
|
int 21h
|
|
mov [file],ax ;save file handle
|
|
jb long ioerr
|
|
|
|
start3: mov bx,[file] ;file handle
|
|
xor dx,dx ;destination DS:DX
|
|
mov ds,[curseg]
|
|
mov cx,8000h ;read 32KB
|
|
mov ah,03f ;block read
|
|
int 21h
|
|
push cs ;restore DS
|
|
pop ds
|
|
jb ioerr
|
|
cmp ax,8000h ;read all ?
|
|
jnz ioerr
|
|
add word [curseg],0800 ;update segment
|
|
dec byte [count]
|
|
jnz start3 ;:another block
|
|
|
|
mov ah,03e ;close
|
|
mov bx,[file] ;file handle
|
|
int 21h
|
|
jb ioerr
|
|
|
|
start4: mov si,offset msg_open ;look for flash
|
|
call v_msg
|
|
call rom_open ;read device ID
|
|
|
|
call rom_cmp ;verify flash
|
|
mov si,offset msg_same
|
|
jnb start9 ;:same, give message and exit
|
|
|
|
mov si,offset msg_zap ;erase flash
|
|
call v_msg
|
|
call rom_zap
|
|
|
|
mov si,offset msg_set ;program flash
|
|
call v_msg
|
|
call rom_set
|
|
|
|
mov si,offset msg_cmp ;verify flash
|
|
call v_msg
|
|
call rom_cmp
|
|
mov si,offset msg_ok
|
|
jnb start9 ;:ok
|
|
|
|
mov si,offset msg_fail
|
|
barf: call getreal
|
|
call v_msg ;display error message
|
|
mov si,offset msg_try
|
|
call v_msg ;ask for retry
|
|
|
|
start5: mov ah,0 ;get key
|
|
int 16h
|
|
cmp al,"Q"
|
|
jz terminat ;Q = exit
|
|
cmp al,"q"
|
|
jz terminat
|
|
cmp al,"R"
|
|
jz start4 ;R = retry
|
|
cmp al,"r"
|
|
jz start4
|
|
jmp start5
|
|
|
|
ioerr: mov si,offset msg_io ;I/O error
|
|
start9: call v_msg ;display message
|
|
terminat: call rom_exit ;write-protect flash
|
|
mov ax,4c00h ;terminate
|
|
int 21h
|
|
;
|
|
; display string [SI] -> TTY
|
|
;
|
|
v_msg: cs: lodsb ;get character
|
|
and al,al ;0 = end
|
|
jz v_msg9
|
|
mov ah,0eh ;TTY output
|
|
mov bh,0 ;page 0
|
|
int 10h
|
|
jmp v_msg
|
|
v_msg9: ret
|
|
;
|
|
; 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,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
|
|
jz rom_open8
|
|
cmp ah,0d6 ;39VF020
|
|
jz rom_open8
|
|
cmp ah,0d7 ;39VF040
|
|
jnz rom_open9
|
|
rom_open8:
|
|
ret
|
|
rom_open9:
|
|
mov si,offset msg_fail
|
|
jmp barf
|
|
;
|
|
; 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 ;disable 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
|
|
jmp getreal
|
|
;
|
|
; 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
|
|
jmp getreal
|
|
;
|
|
; compare flash [bufpt] -> [rombase], carry set if mismatch
|
|
;
|
|
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
|
|
rom_cmp3: mov eax,[esi]
|
|
cmp [edi],eax
|
|
jnz rom_cmp4 ;:failure
|
|
lea esi,[esi+4]
|
|
lea edi,[edi+4]
|
|
dec ecx
|
|
jnz rom_cmp3
|
|
call getreal
|
|
clc
|
|
ret
|
|
|
|
rom_cmp4: call getreal ;failure exit
|
|
stc
|
|
ret
|
|
;
|
|
; Wait BX milliseconds - depends on refresh rate !!!
|
|
;
|
|
; This is used for floppy delays and INT15 function 86.
|
|
;
|
|
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
|
|
;
|
|
; stack
|
|
;
|
|
db (($+100) and 0fff0h)-$ dup 0ffh ;allocate stack
|
|
stack1: ;this is end, buffer follows...
|
|
;buffer is even 16
|