home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
sampler0
/
critter.asm
< prev
next >
Wrap
Assembly Source File
|
1987-11-14
|
16KB
|
606 lines
PAGE 60,132
TITLE CRITTER - Critical error handler
; (C) Copyright 1987 Forest Hill Software, Inc.
; All rights reserved
;
; Note: This program was put together with code from a handler that
; was integrated with a larger project. Do not be supprised to
; find added references and code which do not seem pertinent.
; (it was also ported from Manx Assembler source code)
DOSSEG
.MODEL small
.STACK 100h
LINE equ 3 ;Starting line # of error window
COLUMN equ 9 ;Starting column of error window
LINES equ 4 ;# of lines in error window
COLUMNS equ 25 ;# of columns in error window
DISK_ER equ 80h ;Disk error flag bit
ALERT_D equ 10 ;Alert tone duration
ALERT_F equ 300 ;Alert tone frequency
NOCURS equ 2000h ;Scan lines setting for no cursor
; Allowed action bits - provided in ah when entering INT 24
QUI_BIT equ 08h ;Quit (fail) allowed bit
RET_BIT equ 10h ;Retry allowed bit
IGN_BIT equ 20h ;Ignore allowed bit
; Action key scan codes
SCAN_R equ 19 ;Key 'R' pressed
SCAN_I equ 23 ;Key 'I' pressed
; Actions which can be supplied back to DOS in al
IGNORE equ 0 ;Ignore the error
RETRY equ 1 ;Retry the operation
ABORT equ 2 ;Abort the program
FAIL equ 3 ;Fail the call
; Video attributes
CO_NORM equ 17h ;Color text attributes - normal = white on blue
CO_HIGH equ 1eh ; highlite = yellow on blue
CO_ERRO equ 9ch ; error = flash red on blue
BW_NORM equ 07h ;B/W text attributes - normal = low intensity
BW_HIGH equ 0fh ; highlite = high intensity
BW_ERRO equ 8fh ; error = flash high intens
MO_NORM equ 07h ;Mono text attributes - normal = normal
MO_HIGH equ 70h ; highlite = reverse
MO_ERRO equ 87h ; error = flash reverse
; Interupts
VIDEO equ 10h ;BIOS video services interupt
SETSIZE equ 01h ;Set cursor size
SETPOS equ 02h ;Set cursor position
READCUR equ 03h ;Read cursor
READCHR equ 08h ;Read character and attribute
WRITCHR equ 09h ;Write character and attribute
GETMODE equ 0fh ;Get video mode
KEYBRD equ 16h ;BIOS keyboard services interupt
READKBD equ 00h ;Read keypress
TESTKBD equ 01h ;Test if keypress waiting
DOS equ 21h ;DOS function call interrupt
DISPSTR equ 09h ;Display $ terminated string
SETVECT equ 2500h ;Set interrupt vector
KEEPPGM equ 3100h ;Keep process (TSR)
GETVECT equ 3500h ;Get interrupt vector
EXITPGM equ 4C00h ;End process
TICK equ 08h ;Clock tick interrupt
CRITIC equ 24h ;Critical error handler interrupt
.DATA
logon db 13,10,'CRITTER - Your hyperactive critical error handler'
db 13,10,' (C) Copyright 1987 by Forest Hill Software, Inc.'
db 13,10,'$'
.CODE
; Data to be kept in Code segment
EVEN
top_stk dw 0 ;Top of local stack
old_cur dw 0 ;Original cursor scan lines
old_pos dw 0 ;Original cursor position
err_sta dw 0 ;Error status information
err_num dw 0 ;Error number (code)
tic_off dw 0 ;Saved INT 8 vector
tic_seg dw 0
crt_off dw 0 ;Saved INT 24 vector
crt_seg dw 0
our_sp dw 0 ;Our local stack
our_ss dw 0
sav_sp dw 0 ;Callers stack
sav_ss dw 0
scr_sav db LINES*COLUMNS*2 dup (0) ;Storage for used screen area
scr_pag db 0 ;Current screen page
lin_sav db 0 ;Temporary line # storage
col_sav db 0 ;Temporary column # storage
line_c db 0 ;Line counter
colum_c db 0 ;Column counter
att_nor db 0 ;Video attributes - normal
att_hig db 0 ; highlite
att_err db 0 ; error
; Error window background
err_top db 213, 8 dup (205), 7 dup (' '), 8 dup (205), 184, '$'
err_mid db 179, 23 dup (' '), 179, '$'
err_bot db 212, 23 dup (205), 190, '$'
err_nam db 'ERROR$'
; Critical Error Handler Messages
; |<-- width = 23 --->| Lower byte of reg di
ERR_SIZ equ 24 ;Length of each error message inc $
errors db ' Write Protected $' ;0
db ' Unknown Device $' ;1
db ' Drive Not Ready $' ;2
db ' Unknown Command $' ;3
db ' Data Error (CRC) $' ;4
db ' Request Structure $' ;5
db ' Seek Error $' ;6
db ' Unknown Media $' ;7
db ' Sector Not Found $' ;8
db ' Out of Paper $' ;9
db ' Write Fault $' ;a
db ' Read Fault $' ;b
db ' General Failure $' ;c
db ' (reserved) $' ;d
db ' (reserved) $' ;e
db ' Invalid Disk Change $' ;f
; Actions
actions db 'Ignore Retry Abort Fail$'
ignor_c db 'I$'
retry_c db 'R$'
abort_c db 'A$'
fail_c db 'F$'
I_POS equ 1 ;Position of I in Ignore to highlite
R_POS equ 8 ;Position of R in Retry to highlite
A_POS equ 14 ;Position of A in Abort to highlite
F_POS equ 20 ;Position of F in Fail to highlite
; Install critical error handler and stay resident
start: mov ax, @DATA ;Initialize DS
mov ds, ax
mov ah, DISPSTR ;Display logon message
mov dx, offset logon
int DOS
call install ;Install handler and tick watch
mov ax, sp ;Determine paragraphs to keep
mov cs:our_sp, ax ; also save sp for the handler
;fortunately there should be no fatal errors untill this TSR's
mov cl, 4 ;starting with para's in stack
shr ax, cl
mov bx, ss ;Add that to stack segment
mov cs:our_ss, bx ; also save ss for the handler
add ax, bx
mov bx, es ;Then subtract PSP segment
sub ax, bx
inc ax ;Add 1 para for safety
mov dx, ax
mov ax, KEEPPGM ;TSR with code 0
int DOS
; Link vector check routine into timer interupt
install proc
push ds
push es
push cs
pop ds
mov ax, (GETVECT+CRITIC) ;Read existing INT 24 vector
int DOS
mov crt_off, bx
mov crt_seg, es
mov ax, (SETVECT+CRITIC) ;Set new INT 24 vector
mov dx, offset crit_handler
int DOS
mov ax, (GETVECT+TICK) ;Read existing INT 8 vector
int DOS
mov tic_off, bx
mov tic_seg, es
mov ax, (SETVECT+TICK) ;Set new INT 8 vector
mov dx, offset vect_check
int DOS
pop es
pop ds
ret
install endp
; Remove critical error handler from interrupt
remove proc
push ds
push cs
pop ds
mov dx, tic_off
mov ax, (SETVECT+TICK)
int DOS
mov dx, crt_off
mov ax, (SETVECT+CRITIC)
int DOS
pop ds
ret
remove endp
; Vector check
vect_check proc
sti
push ax
push bx
push es
xor ax, ax ;Get current INT 24 Vector
mov es, ax
mov bx, es:[CRITIC*4]
mov ax, es:[CRITIC*4+2]
cmp ax, seg crit_handler ;Does it point to our handler
jne revect
cmp bx, offset crit_handler
je chkend
revect: cmp ax, seg crit_handler ;Don't revector programs loaded after
ja chkend ; this program
mov cs:crt_off, bx ;If not, save current vector
mov cs:crt_seg, ax
cli ;then revector it to our handler
mov es:[CRITIC*4], offset crit_handler
mov es:word ptr [CRITIC*4+2], seg crit_handler
sti
chkend: pop es
pop bx
pop ax
jmp dword ptr cs:[tic_off] ;Chain to previous tick handler
vect_check endp
; Critical error interrupt handler
crit_handler proc
sti ;Enable interupts again
push ds ;Save caller's data segment
push cs ;data segment=codeseg
pop ds
mov sav_ss, ss ;Save caller's stack
mov sav_sp, sp
cli ;Set up local stack
mov ss, our_ss
mov sp, our_sp
sti
push bx ;Save required regs on local stack
push cx
push dx
push bp
push si
push di
push es
;
mov err_sta, ax ;Save error status
and di, 00ffh ;Mask out all but error number
mov err_num, di ;Save error number
call vid_mod ;Get video mode
cmp al, 3 ;If mode 0-3 it's text
jle text
mov att_nor, MO_NORM ;Only remaining text mode is mono
mov att_hig, MO_HIGH ;so set attributes just in case
mov att_err, MO_ERRO
cmp al, 7 ;If it is monochrome mode
je mode_ok ;then all set
;
call get_act ;Get action - no window in graphics
jmp done ;Return with action code
;
text: mov att_nor, BW_NORM ;Assume B/W attributes
mov att_hig, BW_HIGH
mov att_err, BW_ERRO
test al, 1 ;unless it's a color mode
je mode_ok
;
color: mov att_nor, CO_NORM ;then use color attributes
mov att_hig, CO_HIGH
mov att_err, CO_ERRO
;
mode_ok:call cur_off ;Turn cursor off
call sav_scr ;Save underlying screen
; display window background and name
mov bl, att_nor ;Use normal attribute for window
mov bp, offset err_top ;Display top line of window
mov dh, LINE ;Top line of window
mov dl, COLUMN ;Left column of window
call str_out ;Display this line
mov bp, offset err_mid ;Display middle 2 lines (less text)
inc dh ;on next line
mov dl, COLUMN ;Yes! We have to keep setting it!
call str_out
mov bp, offset err_mid ;and the one following
inc dh
mov dl, COLUMN
call str_out
mov bp, offset err_bot ;Display bottom line
inc dh
mov dl, COLUMN
call str_out
mov bl, att_err ;Use highlite attribute
mov bp, offset err_nam ;Display window name - "ERROR"
mov dl, COLUMN+10 ;In middle of top line
mov dh, LINE
call str_out
; Display appropriate error message
mov ax, err_num ;Calculate start of message
mov bl, ERR_SIZ ;Where each message is ERR_SIZ long
mul bl
add ax, offset errors ;and the table base is "errors"
mov bp, ax
mov bl, att_nor ;Use normal attributes
mov dh, LINE+1 ;Starting on seccond row
mov dl, COLUMN+1 ;and the second column
call str_out ;Display it
; Display allowed actions
mov bl, att_nor ;Normal attr for all but R & I
mov dh, LINE+2 ;Line where actions are displayed
mov dl, COLUMN+1 ;Column where actions are displ.
mov bp, offset actions ;Display actions
call str_out
mov dl, COLUMN+I_POS ;Overlay highlited "I"
mov bp, offset ignor_c
mov bl, att_hig
call str_out
mov dl, COLUMN+R_POS ;Overlay highlited "R"
mov bp, offset retry_c
mov bl, att_hig
call str_out
mov dl, COLUMN+A_POS ;Overlay highlited "A"
mov bp, offset abort_c
mov bl, att_hig
call str_out
mov dl, COLUMN+F_POS ;Overlay highlited "F"
mov bp, offset fail_c
mov bl, att_hig
call str_out
; Convert error number to DOS standard
add err_num, 19
; Get desired action from user
call get_act ;Get desired action from user
push ax ;Save action code
call res_scr ;Restore screen under window
call cur_on ;Restore original cursor
pop ax ;Restore action code
mov bx, err_sta ;Restore original error status
mov bl, al ;with new action code
mov ax, bx
;
done: pop es ;Restore registers from local stack
pop di
pop si
pop bp
pop dx
pop cx
pop bx
cli ;int's off...just in case
mov ss, sav_ss ;Restore caller's stack
mov sp, sav_sp
sti
pop ds
iret ;At this point al contains action
crit_handler endp
; Get video mode
vid_mod proc
mov ah, GETMODE ;Get video page
int VIDEO
mov scr_pag, bh
ret
vid_mod endp
; Turn cursor off
cur_off proc
mov bh, scr_pag ;Get cursor information
mov ah, READCUR
int VIDEO
cmp cx, 0067h ;Test for BIOS bug
jne cur_ok
mov cx, 0607h ;fix it if required
cur_ok: mov old_cur, cx ;Save cursor scan lines
mov old_pos, dx ;Save cursor position
mov ah, SETSIZE ;Set cursor off
mov cx, NOCURS
int VIDEO
ret
cur_off endp
; Turn cursor back on
cur_on proc
mov dx, old_pos ;Restore original cursor position
mov bh, scr_pag
mov ah, SETPOS
int VIDEO
mov cx, old_cur ;Restor original scan lines
mov ah, SETSIZE
int VIDEO
ret
cur_on endp
; Save the screen area under the window
sav_scr proc
mov al, LINE ;Starting at LINE
mov line_c, al
xor di, di ;Point to start of scr_save
mov cx, LINES ;For each line
lin_loo:push cx
mov cx, COLUMNS ;For each column
mov al, COLUMN ;Starting at COLUMN
mov colum_c, al
col_loo:mov ah, SETPOS ;Set position to read
mov bh, scr_pag
mov dh, line_c
mov dl, colum_c
int VIDEO
mov ah, READCHR ;Read character & attribute
mov bh, scr_pag
int VIDEO
mov scr_sav[di], ah ;Place attribute in scr_sav
inc di ;Bump scr_sav pointer
mov scr_sav[di], al ;Place character in scr_sav
inc di
inc colum_c ;Bump column pointer
loop col_loo ;Till line is done
inc line_c ;Bump line pointer
pop cx ;Till window done
loop lin_loo
ret
sav_scr endp
; Restore the area under the window
res_scr proc near
mov al, LINE ;Starting at LINE
mov line_c, al
xor di, di ;Point to start of scr_sav
mov cx, LINES ;For each line
lin_lo2:push cx
mov cx, COLUMNS ;For each column
mov al, COLUMN ;Point to starting column
mov colum_c, al
col_lo2:mov ah, SETPOS ;Set position to restore
mov bh, scr_pag
mov dh, line_c
mov dl, colum_c
int VIDEO
push cx
mov ah, WRITCHR ;Write character & attribute
mov bl, scr_sav[di] ;Get attribute
inc di ;Bump scr_sav pointer
mov al, scr_sav[di] ;Get character
inc di ;Bump scr_sav pointer
mov bh, scr_pag ;Ensure we have correct page
mov cx, 1 ;This character just once
int VIDEO
pop cx
inc colum_c ;Bump column pointer
loop col_lo2 ;Till line is done
inc line_c ;Bump line pointer
pop cx ;Till window done
loop lin_lo2
ret
res_scr endp
; Display string - till '$' - No Wrap Allowed!
; call with: bp = pointer to string
; bl = attribute
; dh = screen row
; dl = starting column
str_out proc
push di ;We must save di reg
push ax ;and ax reg
mov bh, scr_pag ;Position cursor
mov ah, SETPOS
int VIDEO
xor di, di ;Point to start of string
str_loo:mov al, cs:[bp][di] ;Get current character
cmp al, '$' ;Check for end of string
je str_end
mov cx, 1 ;Only 1 of each character
mov ah, WRITCHR ;Write character to screen
int VIDEO
inc dl ;Point to next column
mov ah, SETPOS ;Move cursor there
int VIDEO
inc di ;Point to next character in string
jmp str_loo ;continue
;
str_end:pop ax ;Restore ax reg
pop di ;and di reg
ret
str_out endp
; Obtain response from user - Test for valid action
; when valid is specified set return code in al reg
get_act proc
push cx
action: call alert ;Alert user
; Clear keyboard buffer
tst_kbd:mov ah, TESTKBD ;Any characters in keyboard buffer?
int KEYBRD
jz buf_clr ;If nothing in buffer then it's clr
mov ah, READKBD ;else dump this keypress
int KEYBRD
jmp tst_kbd
buf_clr:
; Get a new keypress
key_psd:mov ah, TESTKBD ;Any key pressed yet
int KEYBRD
jz key_psd ;If not then wait
mov ah, READKBD ;else get keypress
int KEYBRD
and al, 0DFh ;Convert to lower case
; Test for valid key
xor cx, cx
cmp al, 'I' ;Test if 'I' pressed
je goodkey
inc cl
cmp al, 'R' ;Test if 'R' pressed
je goodkey
inc cl
cmp al, 'A' ;Test if 'A' pressed
je goodkey
inc cl
cmp al, 'F' ;Test if 'F' pressed
je goodkey
jmp action
goodkey:mov al, cl
pop cx
ret
get_act endp
; Alert user with low beep tone
alert proc
push bx
push di
mov bx, ALERT_D ;Duration of alert tone
mov di, ALERT_F ;Frequency of alert tone
call abeep
pop di
pop bx
ret
alert endp
; Produce Beep
; BX = Duration
; DI = Frequency
abeep proc
push ax
push bx
push cx
push dx
push di
mov al, 0B6h
out 43h, al
mov dx, 14h
mov ax, 4F38h
div di
out 42h, al
mov al, ah
out 42h, al
in al, 61h
mov ah, al
or al, 3
out 61h, al
delay: mov cx, 2801
tone: loop tone
dec bx
jnz delay
mov al, ah
out 61h, al
pop di
pop dx
pop cx
pop bx
pop ax
ret
abeep endp
END start