home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
MEMTEST
/
WORM21.AQM
/
WORM21.ASM
Wrap
Assembly Source File
|
2000-06-30
|
7KB
|
259 lines
; WORM.ASM ver 2.1 (revised 10/9/81)
;
;Jim Eccleston July 19 1980 - program originally written
;
;Keith Petersen, W8SDZ, October 9, 1981 - fixed bug which
; caused program to print one trap error at start.
; Added REPORT conditional assembly so addresses
; won't be reported unless there is an error.
; Added equates for console ports.
;
;Allen Mar August 8, 1980 - added 'label + offset'
; so COM file can be generated without DDT.COM
; Thanks to Bill Precht and Ward Christensen
; who used it in his 'PMMIBYE2' remote CP/M
; program...
;
;************************************************************************
;* *
;* W O R M T E S T *
;* *
;* A serious flaw exists in most memory test routines when *
;* applied to Z-80 systems. A board can be tested for hours *
;* and never drop a bit, then when it's loaded with a program *
;* fail instantly. The problem is that access timing on a *
;* Z-80 instruction fetch (the M-1 cycle) is significantly *
;* more critical than on a simple read cycle. No matter how *
;* fancy a normal memory test gets, it never makes demands *
;* on memory speed that an actual program does. The only way *
;* to check this memory for full speed operation is to *
;* actually run a program in it. Wormtest does just that. *
;* vide The M-1 Worm. P.C. July 73 *
;* *
;************************************************************************
;
;The first few lines relocate the program down to low memory
;There are two parts to the test program. The larger portion
;consists of service routines, but the Worm itself consists of
;a short 12 byte routine that upon initialization breaks away
;from the main body and crawls up through memory space giving a
;running travelogue as he goes. If he stops talking, you know
;something bad happened, and where. The Worm acts as the main
;program loop. It manipulates two test bytes and calls two sub-
;routines. One of the subroutines reports the location of the
;worm and detects and reports any errors in the test bytes. The
;other subroutine shifts the Worm up in memory one location and
;adjusts the return to begin execution for another loop. There
;are seven instruction fetches per loop, with the data manipulation
;instructions in complementary pairs to ensure full speed testing
;on both ones and zeroes. The instruction RST 7 is embedded in
;the Worm in non-executable locations as traps in case a memory
;error causes the program counter to get out of sync. The Worm
;leaves behind a slime-trail of FF's as it travels. Any execution
;of a trap is reported and the trap subroutine attempts to return
;execution back to the worm. The error reports indicate which data
;byte was bad and what the erroneous value was. A "D" indicates
;that bits were dropped, while a "P" indicates that bits were
;picked. A trap error is flagged by a "T" followed by the address.
;Upon execution the Worm will immediately start reporting its
;location (by address). Bad memory will trash the program or
;else trigger the error reports. No memory looks like a string
;of FF's and a sequential string of traps will be reported.
;When ROM is hit, execution of the ROM program will begin,
;so if you have the Morrows Disk Controller you will know
;your memory is ok when the system re-boots.
;
stport equ 20h ;console status port
txrdy equ 04h ;console putput mask
daport equ 21h ;console data port
;
report equ 0 ;<--make non-zero for address reporting
;
org 0100h
;
; Move routine relocates WORM program down to 08H
;
start lxi d,dest ;Destination address
lxi h,source ;Source address
mvi b,pend-source+1 ;Number of bytes to move
;
loop mov a,m ;Get byte
stax d ;Put byte
inx h ;Bump up source adr.
inx d ;Bump up destination adr.
dcr b ;Decrease byte count
jnz loop ;Do again if not zero count
lxi sp,stack ;Set up stack pointer
lxi b,data ;Set up data pointer
jmp worm+1
;
dest equ 08h ;destination
;
source equ $
offset equ dest-source ;reloc amount
;
stwrm equ $+offset ;Start of relocated code (08h)
dw 0ffffh
dw 0ffffh
dw 0ffffh
dw 0ffffh ;Rst 7s
;
movwrm equ $+offset
pop h ;Get address of worm + 1
mov d,h ;Duplicate address in d
mov e,l ;and e regs.
dcx d ;Set DE to last address of worm
mvi b,0ch ;Set length of worm
;
getwrm equ $+offset
ldax d ;;Get byte of worm
mov m,a ;Move it up one location
dcx d ;Adjust pointers
dcx h
dcr b
mov a,b
cpi 00
jnz getwrm
lxi b,data ;Restore data pointer
inx h ;HL to start of worm
inx h
pchl ;Return to worm
rst 7 ;RST 7
;
rptadr equ $+offset
cpi 0ffh ;Check for dropped bit error
jnz errdrp
mov a,b
cpi 00h ;Check for picked bit error
jnz errpik
jmp rptad2 ;Show the address
rst 7
rst 7 ;Trap
;
trap equ $+offset
mvi a,54h ;Print a "T"
call output
mvi a,20h ;Print a " "
call output
pop h ;Recover address
dcx h ;Adjust address
call adout ;Print the address
inx h ;Adjust address
pchl ;Return
;
rptad2 equ $+offset
pop h ;Recover address
;
if report
call adout ;Print address
endif
;
if not report
nop ! nop ! nop ;Don't print address
endif
;
inx h ;Adjust return address
inx h
inx h
pchl ;Return
;
errdrp equ $+offset
mvi b,44h ;Show it's dropped bit(s)
jmp errprt ;Print error message
;
errpik equ $+offset
mvi b,50h ;Show it's picked bit(s)
;
errprt equ $+offset
mov c,a ;Save error data
mvi a,2ah ;Print "*"
call output
mvi a,20h ;Print " "
call output
mov a,b ;Print type of error
call output
mvi a,20h ;Print " "
call output
mov a,c ;Get error data
call bowcl ;Print and end line
jmp rptad2 ;Now try for address and return
;
adout equ $+offset
push h ;Save address
mov a,h
call bytout ;Its nybble time
mov a,l
call bowcl ;Same with cr/lf
pop h ;Restore address
ret
;
bytout equ $+offset
push psw ;Save A
rrc ;Shift nybble
rrc
rrc
rrc
call nybout ;Nybble out 1
pop psw ;Restore A
call nybout ;Nybble out 2
ret
;
bowcl equ $+offset
call bytout
mvi a,0Dh ;C/R time
call output
mvi a,0Ah ;LF time
call output
ret
;
nybout equ $+offset
ani 0fh ;Strip high nibble
cpi 0ah ;Divide alpha v numeric
jm isnum ;If numeric
adi 07h ;Add alpha offset
isnum equ $+offset
adi 30h ;Add numeric offset
call output
ret
;
;************************************************
;* Insert Your DIRECT Console Output Call Here *
;* unless you want to use cp/m calls till crash *
;************************************************
;
output equ $+offset
push b ;save bc
push psw ;save character
;
lp equ $+offset
in stport ;get console status
ani txrdy ;ready for character?
jz lp ;no, loop and wait
pop psw ;get character
out daport ;output to console
pop b ;restore bc
ret
;
data equ $+offset
db 00
;
ds 20
stack equ $+offset-1
;
worm equ $+offset
rst 7 ;Trap
ldax b ;Move data to A; start of worm
push psw ;Push test data onto stack
mvi a,0ffh ;Move second test byte to A
pop b ;Pop first test byte into B
rst 5 ;call "rptadr"
rst 7 ;Trap
rst 7
rst 7
nop ;"rptadr" return location
rst 2 ;call "movwrm"
;
pend equ $ ;program end
;
end 0100h