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,655 @@
|
||||
;
|
||||
; POST (power on self test) routines
|
||||
;
|
||||
; (C)1997-2001 Pascal Dornier / PC Engines; All rights reserved.
|
||||
; This file is licensed pursuant to the COMMON PUBLIC LICENSE 0.5.
|
||||
;
|
||||
; Limitations:
|
||||
;
|
||||
; - Ctrl-Alt-Del does not get any special treatment by POST, goes
|
||||
; through full memory test etc.
|
||||
;
|
||||
; pd050206 change from d_extop to d_exmem
|
||||
; pd030516 changed memory test display increment to 16MB
|
||||
; (faster when using serial console !)
|
||||
; pd011107 add MTEST_1PASS option
|
||||
; pd000424 add QUICKMEM option
|
||||
; pd991127 add PS/2 mouse vector
|
||||
|
||||
;
|
||||
; handle error: hang if C=1, return otherwise
|
||||
;
|
||||
post_err: jb post_err1 ;:error
|
||||
ret
|
||||
|
||||
post_err1: cli
|
||||
hlt ;hang
|
||||
;
|
||||
; verify BIOS checksum, return C=1 if error
|
||||
;
|
||||
post_sum: mov si,offset startofs ;start offset, must be multiple of 256
|
||||
xor bx,bx ;clear sum
|
||||
post_sum1: cs: lodsw
|
||||
add bl,al
|
||||
add bl,ah
|
||||
cs: lodsw
|
||||
add bl,al
|
||||
add bl,ah
|
||||
and si,si
|
||||
jnz post_sum1 ;:more to test
|
||||
and bl,bl ;sum = 0 ?
|
||||
jnz post_stc1 ;no: error
|
||||
post_clc1: clc
|
||||
ret
|
||||
;
|
||||
; Test memory refresh (and indirectly, 8254 timer)
|
||||
;
|
||||
#if def NO_ISAREF
|
||||
post_ref: clc ;skip test
|
||||
ret
|
||||
post_stc1: stc
|
||||
ret
|
||||
#else
|
||||
post_ref: mov cx,256
|
||||
post_ref1: in al,port61 ;wait for refresh bit = 0
|
||||
and al,10h
|
||||
jz post_ref2
|
||||
loop post_ref1
|
||||
post_stc1: stc ;timeout
|
||||
ret
|
||||
|
||||
post_ref2: in al,port61 ;wait for refresh bit = 1
|
||||
and al,10h
|
||||
jnz post_clc1 ;yes: return clc
|
||||
loop post_ref2
|
||||
stc ;timeout
|
||||
ret
|
||||
#endif
|
||||
;
|
||||
; Test DMA registers
|
||||
;
|
||||
post_dma: mov dx,dma1 ;I/O port
|
||||
mov si,2 ;port increment
|
||||
post_dma1: mov di,dx ;save I/O port
|
||||
mov bx,8000h ;starting pattern
|
||||
post_dma2: call post_dma3 ;test
|
||||
jb post_stc1 ;:error
|
||||
mov dx,di ;restore I/O port
|
||||
ror bx,1 ;next pattern
|
||||
jnb post_dma2 ;:another bit
|
||||
mov dl,dma0
|
||||
shr si,1 ;do dma0 ?
|
||||
jnb post_dma1 ;:yes
|
||||
clc ;passed test
|
||||
ret
|
||||
|
||||
post_dma3: mov cx,8 ;8 address and count registers
|
||||
post_dma4: mov al,bl ;write test pattern (16 bit = 2 writes)
|
||||
out dx,al
|
||||
out iowait,al
|
||||
mov al,bh
|
||||
out dx,al
|
||||
out iowait,al
|
||||
in al,dx ;read back and compare
|
||||
cmp al,bl
|
||||
jnz post_stc1
|
||||
out iowait,al
|
||||
in al,dx
|
||||
cmp al,bh
|
||||
jnz post_stc1
|
||||
out iowait,al
|
||||
add dx,si ;next port
|
||||
loop post_dma4
|
||||
clc ;ok return
|
||||
ret
|
||||
;
|
||||
; Test IRQ mask registers
|
||||
;
|
||||
post_irq: mov dx,pic0+1
|
||||
call post_reg
|
||||
jb post_irq2
|
||||
mov dl,pic1+1
|
||||
call post_reg
|
||||
post_irq2: mov al,0ffh ;mask off all interrupts
|
||||
out pic0+1,al
|
||||
out pic1+1,al
|
||||
ret
|
||||
;
|
||||
; test register [DX]
|
||||
;
|
||||
post_reg: mov bl,80h ;starting pattern
|
||||
post_reg2: mov al,bl ;write pattern
|
||||
out dx,al
|
||||
not al ;write inverted pattern to prevent
|
||||
out iowait,al ;capacitive hold
|
||||
in al,dx ;read back
|
||||
cmp al,bl
|
||||
jnz post_stc1 ;:error
|
||||
out iowait,al
|
||||
ror bl,1 ;try next bit
|
||||
jnb post_reg2
|
||||
clc ;return ok status
|
||||
post_reg9: ret
|
||||
;
|
||||
; Test DMA page registers
|
||||
;
|
||||
post_page: mov dx,fd_page
|
||||
mov cx,15 ;81..8F
|
||||
post_pag2: call post_reg
|
||||
jb post_reg9 ;:error
|
||||
inc dx
|
||||
loop post_pag2
|
||||
ret
|
||||
;
|
||||
; Test timer 2 registers
|
||||
;
|
||||
post_tim: mov al,0b0h ;timer 2
|
||||
out timer+3,al
|
||||
out iowait,ax ;this is needed, at least on M6117 !
|
||||
out iowait,ax
|
||||
#if def MEDIAGX
|
||||
out timer+2,al ;dummy write, read
|
||||
out timer+2,al
|
||||
in al,timer+2
|
||||
in al,timer+2
|
||||
#endif
|
||||
mov bx,1
|
||||
post_tim1: mov al,bl ;LSB
|
||||
out timer+2,al
|
||||
out iowait,ax
|
||||
mov al,bh ;MSB
|
||||
out timer+2,al
|
||||
out iowait,ax
|
||||
in al,timer+2 ;check LSB
|
||||
cmp al,bl
|
||||
jnz post_stc2
|
||||
out iowait,ax
|
||||
in al,timer+2 ;check MSB
|
||||
out iowait,ax
|
||||
cmp al,bh
|
||||
jnz post_stc2
|
||||
shl bx,1
|
||||
jnb post_tim1
|
||||
clc
|
||||
ret
|
||||
post_stc2: stc
|
||||
ret
|
||||
;
|
||||
; Clear registers, disable DMA, interrupts
|
||||
;
|
||||
post_clr: mov si,offset clrtab
|
||||
jmp short post_tdm0
|
||||
;
|
||||
; Initialize timers, DMA
|
||||
;
|
||||
post_tdma: mov si,tdmatab
|
||||
post_tdm0: mov dh,0
|
||||
post_tdm1: cs: lodsw
|
||||
cmp ah,0ffh ;end of table ?
|
||||
jz post_tdm9
|
||||
mov dl,ah ;port address
|
||||
out dx,al ;write data
|
||||
out iowait,al ;I/O wait
|
||||
jmp post_tdm1
|
||||
post_tdm9: 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
|
||||
#if def GX_GDT
|
||||
dw 0ffffh,0,9300h,408fh ;GX_BASE segment -> GS:
|
||||
#endif
|
||||
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
|
||||
;
|
||||
; display high memory size EBP (destroyed)
|
||||
;
|
||||
post_dsph: push ebp ;save EBP
|
||||
#if def GX_VID
|
||||
mov ax,0e0bh ;display clear to beginning of line
|
||||
#else
|
||||
mov ax,0e0dh ;display CR
|
||||
#endif
|
||||
mov bl,0
|
||||
int 10h
|
||||
pop eax ;EBP -> EAX
|
||||
shr eax,10 ;display high memory size
|
||||
;div 1024 -> KB
|
||||
sub eax,1024 ;sub eax,#1024
|
||||
;fall through
|
||||
;
|
||||
; display number EAX
|
||||
;
|
||||
; divide / stack based algorithm
|
||||
;
|
||||
post_itoa: xor dx,dx ;mark first digit on stack
|
||||
push dx
|
||||
mov ecx,10
|
||||
post_ito2: xor edx,edx
|
||||
div ecx
|
||||
or dl,"0" ;remainder -> ASCII digit
|
||||
push dx ;push digit
|
||||
and eax,eax ;done ?
|
||||
jnz post_ito2
|
||||
|
||||
post_ito3: pop ax ;get digit
|
||||
and al,al
|
||||
jz post_ito9
|
||||
mov ah,0eh ;TTY output
|
||||
mov bh,0 ;page 0
|
||||
int 10h
|
||||
jmp post_ito3
|
||||
|
||||
post_ito9: ret
|
||||
;
|
||||
; size low memory -> EBX = top address; 64KB granularity
|
||||
; (run in unreal mode)
|
||||
;
|
||||
post_szlo: mov ebx,0a0000h ;top limit
|
||||
xor ecx,ecx ;bottom limit
|
||||
post_szl0: mov edx,ebx ;save top
|
||||
mov edi,10000h ;64KB increment
|
||||
|
||||
; first, write address to memory, counting down
|
||||
|
||||
post_szl1: sub ebx,edi
|
||||
mov [ebx],ebx
|
||||
cmp ebx,ecx
|
||||
jnz post_szl1
|
||||
|
||||
; now, verify going up
|
||||
|
||||
post_szl2: add ebx,edi
|
||||
cmp [ebx],ebx
|
||||
jnz post_szl3 ;error: done
|
||||
cmp ebx,edx
|
||||
jnz post_szl2
|
||||
post_szl3: ret ;ebx = top address
|
||||
;
|
||||
; size high memory
|
||||
; (run in unreal mode)
|
||||
;
|
||||
|
||||
; first, we do binary rough size
|
||||
|
||||
post_szhi: xor esi,esi ;start seed
|
||||
mov [esi],esi
|
||||
mov ebx,00100000h ;1MB start
|
||||
mov ecx,ebx ;start for szlo
|
||||
post_szh1: mov [ebx],ebx
|
||||
cmp [esi],esi ;wrote over previous ?
|
||||
jnz post_szh2 ;:yes - reached top
|
||||
cmp [ebx],ebx ;this location ok ?
|
||||
jnz post_szh2 ;:no - reached top
|
||||
mov esi,ebx ;new seed location
|
||||
shl ebx,1
|
||||
test ebx,TOP_MEM shl 16 ;reached top ?
|
||||
jz post_szh1 ;:not yet
|
||||
post_szh2: jmp post_szl0 ;ebx is top limit - use low size
|
||||
;algorithm now for 64KB resolution
|
||||
;
|
||||
; Test 64 KB memory block [EBP]
|
||||
; (run in unreal mode)
|
||||
;
|
||||
; preserve EDX !
|
||||
;
|
||||
post_t64k: mov edi,ebp ;starting address (must be at 64K
|
||||
;multiple)
|
||||
|
||||
; first, do a 64 bit sliding bit test over first 64 x 64 bits
|
||||
|
||||
mov eax,1 ;test pattern
|
||||
xor ebx,ebx
|
||||
post_tk1: mov [edi],eax
|
||||
mov [edi+4],ebx
|
||||
add di,8
|
||||
shl eax,1
|
||||
rcl ebx,1
|
||||
jnb post_tk1 ;:another bit
|
||||
|
||||
xor di,di ;return to start
|
||||
mov eax,1 ;test pattern
|
||||
xor ebx,ebx
|
||||
post_tk2: cmp [edi],eax
|
||||
jnz post_tk9 ;:error
|
||||
cmp [edi+4],ebx
|
||||
jnz post_tk9 ;:error
|
||||
add di,8
|
||||
shl eax,1
|
||||
rcl ebx,1
|
||||
jnb post_tk2
|
||||
|
||||
; now, write initial test pattern seed
|
||||
; 72 bytes long -> always get distance between
|
||||
; current cache line and destination
|
||||
|
||||
mov eax,00100100100100100100100100100100xb ;test pattern
|
||||
post_tk3: mov edi,ebp ;start location
|
||||
mov di,16 ;skip first 16 bytes
|
||||
mov esi,edi
|
||||
|
||||
mov cx,18
|
||||
post_tk4: a4 stosd
|
||||
test al,4 ;"round" rotate
|
||||
jz post_tk41 ;implicit CLC
|
||||
stc
|
||||
post_tk41: rcr eax,1
|
||||
dec cx
|
||||
jnz post_tk4 ;:another
|
||||
|
||||
; do block move -> copies pattern all over memory
|
||||
|
||||
mov ecx,16362 ;word count
|
||||
a4 rep movsd
|
||||
|
||||
; now verify final pattern
|
||||
|
||||
post_tk5: cmp eax,[esi]
|
||||
jnz post_tk9 ;:error
|
||||
test al,4 ;"round" rotate
|
||||
jz post_tk51 ;implicit CLC
|
||||
stc
|
||||
post_tk51: rcr eax,1
|
||||
add si,4
|
||||
jnz post_tk5
|
||||
|
||||
test al,4 ;"round" rotate
|
||||
jz post_tk52 ;implicit CLC
|
||||
stc
|
||||
post_tk52:
|
||||
|
||||
#if !def MTEST_1PASS
|
||||
rcr eax,1 ;try next pattern
|
||||
jnb post_tk3 ;:again, total of three passes
|
||||
#endif
|
||||
|
||||
mov edi,ebp
|
||||
xor eax,eax
|
||||
mov cx,16384
|
||||
a4 rep stosd ;clear memory
|
||||
|
||||
mov ebp,edi ;new top
|
||||
clc
|
||||
ret
|
||||
|
||||
post_tk9: stc ;error return
|
||||
ret
|
||||
|
||||
#IF DEF QUICKMEM
|
||||
;
|
||||
; Clear 64 KB memory block [EBP]
|
||||
; (run in unreal mode)
|
||||
;
|
||||
; preserve EDX !
|
||||
;
|
||||
post_c64k: mov edi,ebp ;starting address (must be at 64K
|
||||
;multiple)
|
||||
xor eax,eax ;zero fill
|
||||
mov ecx,4000h
|
||||
a4 rep stosd ;fill
|
||||
mov ebp,edi ;mov ebp,edi - new top
|
||||
clc
|
||||
ret
|
||||
#ENDIF
|
||||
;
|
||||
; base memory test
|
||||
;
|
||||
post_base: call getunreal ;enter unreal mode
|
||||
call post_szlo ;size low memory
|
||||
mov [tmp_losz],ebx
|
||||
|
||||
mov word [m_lomem],64 ;we have at least 64KB DRAM
|
||||
mov ebp,10000h ;start address
|
||||
|
||||
post_bas0:
|
||||
#IF DEF QUICKMEM
|
||||
call post_c64k ;clear 64K of DRAM
|
||||
#ELSE
|
||||
call post_t64k ;test 64K of DRAM
|
||||
#ENDIF
|
||||
jb post_bas1 ;:error
|
||||
add word [m_lomem],64 ;we got another 64KB
|
||||
cmp ebp,[tmp_losz]
|
||||
jnz post_bas0 ;:another block
|
||||
|
||||
post_bas1: xor ax,ax ;access BIOS segment
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
|
||||
#if def CM_LEGACY
|
||||
mov ah,cm_meml ;write base memory size to CMOS
|
||||
mov al,[m_lomem]
|
||||
call rtc_write
|
||||
mov al,[m_lomem+1]
|
||||
mov ah,cm_memh ;write low memory size
|
||||
call rtc_write
|
||||
#endif
|
||||
ret
|
||||
;
|
||||
; init interrupt vectors
|
||||
;
|
||||
post_vec: mov si,offset inttab ;init interrupt vectors
|
||||
xor di,di ;vec00
|
||||
mov ax,cs ;BIOS segment -> eax bit 31..16
|
||||
shl eax,16
|
||||
mov cx,1fh
|
||||
post_vec1: cs: lodsw ;copy vectors 00.1e
|
||||
stosd ;vector + segment
|
||||
loop post_vec1
|
||||
add di,4 ;skip vector 1F
|
||||
|
||||
mov cl,60h-20h
|
||||
mov ax,offset intdummy ;dummy vectors 20..5F
|
||||
rep stosd
|
||||
add di,8*4 ;skip 60..67
|
||||
mov cl,8
|
||||
rep stosd ;fill 68..6F
|
||||
|
||||
mov cl,8 ;copy 8 more vectors
|
||||
post_vec2: cs: lodsw ;copy vectors 70..77
|
||||
stosd
|
||||
loop post_vec2
|
||||
ret
|
||||
;
|
||||
; Extended memory test
|
||||
;
|
||||
post_ext: call getunreal ;enter unreal mode again (& cli)
|
||||
|
||||
push dword [0] ;save lowest memory - zapped by
|
||||
;post_szhi
|
||||
call post_szhi ;size high memory
|
||||
pop dword [0]
|
||||
|
||||
mov [tmp_hisz],ebx
|
||||
|
||||
mov ebp,100000h ;start address
|
||||
|
||||
post_ext0:
|
||||
#IF ! DEF QUICKMEM
|
||||
test ebp,0ffffffh ;reached 16MB boundary ?
|
||||
jnz post_ext1
|
||||
pushad ;save all registers
|
||||
call post_dsph ;display current count
|
||||
call getunreal ;get back to unreal mode
|
||||
popad ;restore all registers
|
||||
#ENDIF
|
||||
post_ext1:
|
||||
#IF DEF QUICKMEM
|
||||
call post_c64k ;clear 64K of DRAM
|
||||
#ELSE
|
||||
call post_t64k ;test 64K of DRAM
|
||||
#ENDIF
|
||||
jb post_ext2 ;:error
|
||||
cmp ebp,[tmp_hisz]
|
||||
jnz post_ext0 ;:another block
|
||||
|
||||
post_ext2: push ebp ;save actual top of memory
|
||||
call post_dsph ;display current count
|
||||
mov si,msg_ext ;display " KB Extended Memory"
|
||||
call v_msg
|
||||
|
||||
xor ax,ax ;access BIOS segment
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
|
||||
call cs_shadrw ;shadow read/write
|
||||
pop eax
|
||||
push eax
|
||||
sub eax,0100000 ;subtract base memory
|
||||
mov dword [cs:d_exmem],eax ;store top address in data area
|
||||
movzx eax,word [m_lomem]
|
||||
shl eax,10 ;convert KB into actual size
|
||||
mov dword [cs:d_basmem],eax
|
||||
|
||||
call cs_shadro
|
||||
|
||||
pop ebx ;store extended memory size in CMOS
|
||||
shr ebx,10 ;convert to KB
|
||||
cmp ebx,10000h ;limit to 64MB
|
||||
jb >l1
|
||||
xor bx,bx
|
||||
l1: sub bx,1024 ;minus base memory
|
||||
|
||||
mov ah,cm_exh ;write high memory size
|
||||
mov al,bh
|
||||
call rtc_write
|
||||
mov al,bl
|
||||
mov ah,cm_exl ;write low memory size
|
||||
#if def CM_LEGACY
|
||||
call rtc_write
|
||||
mov ah,cm_exh2 ;write high memory size
|
||||
mov al,bh
|
||||
call rtc_write
|
||||
mov al,bl
|
||||
mov ah,cm_exl2 ;write low memory size
|
||||
#endif
|
||||
jmp rtc_write
|
||||
;
|
||||
; scan for option ROMs
|
||||
;
|
||||
post_scan: mov ds,bx
|
||||
cmp word [0],0aa55h ;start signature
|
||||
jnz post_scn8 ;:no
|
||||
mov cl,[2] ;get length
|
||||
shl cx,9 ;* 512
|
||||
xor si,si ;start offset
|
||||
xor al,al ;clear sum
|
||||
post_scn1: add al,[si] ;calculate checksum
|
||||
inc si
|
||||
loop post_scn1
|
||||
mov word [es:m_ioofs],3 ;offset - call vector
|
||||
mov [es:m_ioseg],ds ;segment
|
||||
shr si,4
|
||||
add bx,si ;update segment
|
||||
cmp al,0
|
||||
jnz post_scn9 ;:bad checksum
|
||||
|
||||
push bx ;save segment
|
||||
push dx ;save limit
|
||||
call far [es:m_ioofs] ;call ROM
|
||||
cld ;just in case they set it...
|
||||
pop dx ;restore limit
|
||||
pop bx ;restore segment
|
||||
jmp short post_scn9
|
||||
|
||||
post_scn8: add bx,0080h
|
||||
post_scn9: cmp bx,dx ;top limit ?
|
||||
jb post_scan ;:no
|
||||
xor ax,ax ;restore segments
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
ret
|
||||
;
|
||||
; Interrupt vector table
|
||||
;
|
||||
inttab: dw int00 ;divide by zero
|
||||
dw int01 ;single step
|
||||
dw nmi ;NMI
|
||||
dw int03 ;breakpoint
|
||||
dw int04 ;overflow
|
||||
dw int05 ;print screen
|
||||
dw int06 ;invalid opcode
|
||||
dw int07 ;coprocessor not available
|
||||
dw irq0 ;IRQ0 system timer
|
||||
dw irq1 ;IRQ1 keyboard
|
||||
dw inteoi ;reserved - cascade
|
||||
dw inteoi ;IRQ3 reserved
|
||||
dw inteoi ;IRQ4 reserved
|
||||
dw inteoi ;IRQ5 reserved
|
||||
dw irq6 ;IRQ6 floppy
|
||||
dw inteoi ;IRQ7 reserved
|
||||
dw int10 ;video
|
||||
dw int11 ;equipment determination
|
||||
dw int12 ;memory size
|
||||
dw int13 ;disk
|
||||
dw int14 ;serial
|
||||
dw int15 ;system services
|
||||
dw int16 ;keyboard
|
||||
dw int17 ;printer
|
||||
dw int18 ;expansion ROM
|
||||
dw int19 ;bootstrap
|
||||
dw int1a ;timer / RTC
|
||||
dw int1b ;keyboard break
|
||||
dw int1c ;user timer tick
|
||||
dw v_parm ;video parameters
|
||||
dw fd_ptab ;diskette parameters
|
||||
|
||||
dw irq8 ;IRQ8: RTC
|
||||
dw inteoi2 ;IRQ9: cascade
|
||||
dw inteoi2 ;IRQ10: spare
|
||||
dw inteoi2 ;IRQ11: spare
|
||||
#if def PS2MOUSE
|
||||
dw irq12
|
||||
#else
|
||||
dw inteoi2 ;IRQ12: spare
|
||||
#endif
|
||||
dw irq13 ;IRQ13: spare
|
||||
dw irq14 ;IRQ14: hard disk
|
||||
#if def HD_4DRV
|
||||
dw irq15 ;IRQ15: hard disk
|
||||
#else
|
||||
dw inteoi2 ;IRQ15: spare
|
||||
#endif
|
||||
;
|
||||
; Display POST code AL
|
||||
;
|
||||
; This routine is called very early, without a stack.
|
||||
; If you decide to display POST codes to a serial or parallel
|
||||
; port, you will have to initialize the super I/O first.
|
||||
;
|
||||
#if ! def postcode ;can be overridden by user routine
|
||||
postcode: out post,al
|
||||
ret
|
||||
#endif
|
||||
;
|
||||
; Display fatal error code AL
|
||||
;
|
||||
; This routine is called on fatal errors, e.g. bad memory.
|
||||
; We just write the POST code, then hang.
|
||||
;
|
||||
#if ! def fatal ;can be overridden by user routine
|
||||
fatal: out post,al
|
||||
fatal1: hlt
|
||||
jmp fatal1
|
||||
#endif
|
||||
Reference in New Issue
Block a user