·汇编源码--BRK
·汇编源码--CLOCK
·汇编源码--BURNOUT
·汇编源码--DOSSYM
·汇编源码--circle
·汇编源码--DEV
·汇编源码--getspace
·汇编源码--CLEAR
·汇编源码--col
·汇编源码--gameport
; By Steve Holzner (from June 11, 1985 issue of PC Magazine)
interruptssegment at 0h; This is where the disk interrupt
org13h*4; holds the address of its service routine
disk_intlabeldword
interruptsends
screensegment at 0B000h; A dummy segment to use as the Extra
screenends; Segment so we can write to the display
code_segsegment
assumecs:code_seg
org0100h; ORG = 100h to make this a .COM file
first:jmpload_watch; First time through jump to initialize routine
msg_part_1db'Disk error: '; Here are the error messages
msg_part_2db'No response Failed Seek NEC Error '
db'Bad CRC SeenDMA Overrun Impos Sector'
db'No Addr MarkW. ProtectedErr Unknown '
first_positiondw?; Position of 1st char on screen
flagsdw?
screen_seg_offset dw0; 0 for mono, 8000h for graphics
old_disk_intdd?; Location of old disk interrupt
ret_addrlabel dword; Used in fooling around with
ret_addr_worddw 2 dup(?); the stack
disk_watchprocfar; The disk interrupt will now come here
assumecs:code_seg
pushf; First, call old disk interrupt
callold_disk_int
pushf; Save the flags in memory location "FLAGS"
popflags; (cunning name)
jcerror; If there was an error, carry flag will have
jmpfin; been set by Disk Interrupt
error:pushax; AH has the status of the error
pushcx; Push all used registers for politeness
pushdx
pushdi
pushsi
pushes
leasi,msg_part_1; Always print "Disk Error: " part.
assumees:screen; Use screen as extra segment
movdx,screen
moves,dx
movdi,screen_seg_offset; DI will be pointer to screen position
adddi,first_position; Add to point to desired area on screen
callwrite_to_screen; This writes 12 chars from [SI] to [DI]
movdx,80h; Initialize for later comparisons
movcx,7; Loop seven times
e_loop:cmpah,dh; Are error code and DH the same?
jee_found; If yes, Error has been found
addsi,12; Point to next error message
shrdh,1; Divide DH by 2
loope_loop; Keep going until matched DH = 0
cmpah,3; Error code no even number; 3 perhaps?
jee_found; If yes, have found the error
addsi,12; Err unknown; unknown error returned
e_found:callwrite_to_screen; Write the error message to the screen
popes; Restore the registers
popsi
popdi
popdx
popcx
popax
fin:popret_addr_word; Fooling with the stack. We want to
popret_addr_word[2]; preserve the flags but the old flags
addsp,2; are still on the stack. First remove
pushflags; return address, then flags. Fill flags
popf; from "FLAGS", return to correct addr.
jmpret_addr
disk_watchendp
write_to_screenprocnear; Puts 12 characters on screen
movcx,12; Loop 12 times
w_loop:movses:byte ptr[di],cs:[si] ; Move to the screen
moval,7; Move screen attribute into screen buffer
moves:[di],al
incdi; Point to next byte in screen buffer
loopw_loop; Keep going until done
ret
write_to_screenendp
load_watchprocnear; This procedure initializes everything
assumeds:interrupts; The data segment will be the interrupt area
movax,interrupts
movds,ax
movax,disk_int; Get the old interrupt service routine
movold_disk_int,ax; address and put it into our location
movax,disk_int[2]; OLD_DISK_INT so we can call it.
movold_disk_int[2],ax
movdisk_int,offset disk_watch ; Now load the address of DskWatch
movdisk_int[2],cs; routine into the disk interrupt
movah,15; Ask for service 15 of INT 10h
int10h; This tells us how display is set up
subah,25; Move to twenty five places before edge
shlah,1; Mult. by two (char & attribute bytes)
movbyte ptr first_position,ah; Set screen cursor
testal,4; Is it a monochrome display?
jnzexit; Yes - jump out
movscreen_seg_offset,8000h; No, set up for graphics display
exit:movdx,offset load_watch; Set up everything but this program to
int27h; stay and attach itself to DOS
load_watchendp
code_segends
endfirst; END "FIRST" so 8088 will go to FIRST first.
进入讨论组讨论。