title 'Decision 1 Megabyte Ram Test' subttl 'c. Morrow Designs Inc. 1982' org 100H .z80 mapram equ 600h ;MPZ80 Address map ram base equ 048h ;Mult I/O base address group0 equ 0 ;others grp1 equ 1 ;uart1 grp2 equ 2 ;uart2 grp3 equ 3 ;uart3 grpctl equ base + 7 ;multio group select thre equ 20h ;holding register empty thr equ base ;UART holding register lsr equ base + 5 ;UART status register acr equ 0dh ;ASCII carriage return alf equ 0ah ;ASCII line feed asp equ 020h ;ASCII space bel equ 07h ;ASCII bell org 100h jp start org 1000h start: halt ;trap to task 0 halt ld sp,10h ld hl,1010H ;source ld de,10h ;destination ld bc,ecode - begin ;byte count ldir ;move code into local ram jp begin org 10h begin: xor a out (41h),a ;turn DJ off ld c,a ;segment counter ld b,a ld ix,mapram + 2 ;window into ram call initmap ;clear report ram again: ld b,054h ld iy,01ffh ;report map pointer ld a,'A' ;pass 1 = A ld (iy),a ;******************************************************** ;* * ;* Pass1 executes only once and is a quick check of * ;* ram, writing alternating ones and zeroes and comp- * ;* lement. * ;* a = test character * ;* b = saved test pattern * ;* c = current 4K segment value * ;* de = 2K boudary counter * ;* hl = memory location under test * ;* * ;******************************************************** pass1: ld hl,1000h ld (ix),c pass: ld a,55h ;alternating pattern inc iy ;map pointer ld de,0 pass1a: ld (hl),a cp (hl) jr nz,special cpl ld (hl),a cp (hl) jr nz,special inc hl inc de bit 3,d ;2K boundary?? jr z,pass1a call gmesage ;update map if true bit 5,h ;4K boudary jr z,pass ;skip if true inc c jr nz,pass1 ;do a megs worth jp prnmap ;print the results ;******************************************************** ;* * ;* Loop0 - updates the segment under test for 1 Mb * ;* of main memory (c = 0ffh). * ;* test - Checks memory 4 Kb with march pattern * ;ª first zeroes then ones * ;* Loop2 - goes back and checks again--checking for * ;* for refresh problems * ;* * ;* a = shifting pattern * ;* b = pattern to begin writing with * ;* c = segment under test * ;* de = 2K counter * ;* hl = memory address under test * ;* iy = error map pointer for current segment * ;* * ;******************************************************** nulop: pop af scf jr normal loop0: ld hl,1000h ;memory counter ld (ix),c ;segment pointer loop1: xor a ld a,b ;save the pattern push af cp 0 jr z,nulop pop af normal: ld de,0 inc iy ; Fill memory segment with a marching 1 pattern test: push af ;save carry flag ld (hl),a cp (hl) jr nz,special pop af ;get carry back rla ;shift the bit inc hl inc de bit 3,d jr z,test ;loop till 2K done bit 5,h ;was it the high 2K? jr nz,loop3 ;take jump if yes ; Check the whole array for pattern (refresh) ld hl,1000h ;check written pattern loop4: ld de,0 xor a ;clear carry ld a,b ;get original pattern push af cp 0 jr z,lloop2 pop af loop2: push af ;save carry flag cp (hl) jr nz,special pop af ;get carry back rla ;shift the bit inc hl inc de bit 3,d ;done 2K worth? jr z,loop2 call gmesage ;got this far, mark it good bit 5,h jr z,loop1 ;do the high 2K inc c ;else do next 4K segment jr z,prnmap ;print report if done jr loop0 ;next segment lloop2: pop af scf jr loop2 loop3: ld hl,1800h jr loop4 ;############################################################## ; This is a special piece of code for debugging ; c = segment under test ; hl = address within segment ; a = pattern expected special: ld b,10 pop af ;get back carry pexit: cp (hl) jr z,exit dec b jr nz,pexit exit: ld d,a ;save the pattern ld a,(hl) ;get the memory contents jp 0bf0h ;trap into the monitor ;############################################################## ; update the map gmesage: ld a,'G' message: push af ld a,(iy) ;get old segment result cp '-' ;was it bad?? jr z,mesret ;leave alone if yes cp '?' jr z,mesret pop af ld (iy),a ;update the map ret mesret: pop af ;re-align sp ret ; clear the map...executes only once initmap: ld de,0200h ;byte count ld iy,01ffh ;beginning adress initlp: inc iy ld (iy),b ;null the message ram dec de ld a,e or d jr nz,initlp ld iy,01ffh ;begin message ram ret ;******************************************************** ;* * ;* Print the map... executes everytime c = 0 * ;* only register b is preserved. * ;* * ;******************************************************** prnmap: ld iy,01ffh ;begining report buffer ld de,0200h ;byte count ld hl,0420h ;32 bytes lines/ groups of 4 call passprn pmap0: ld a,(iy) ;get the results ld c,a ;print character in c call conout ;print it inc iy ;next segment report dec h call z,space dec l call z,pmap1 ;16 bytes per line dec de ld a,d or e jr nz,pmap0 ;255 entries ; updates the pass number...until 'z' is reached newpas: ld c,0 ld iy,01ffh ld a,(iy) ;increment the pass # inc a ld (iy),a ;update the pass counter sub 05ch ;check for upper case jr z,nmarch0 ;entry to marhing 0's jr nc,npass1 xor a ;clear carry ld a,b push af ;save for npass0 cp 54h ;first time entry jr z,nuone cp 0 jr nz,npass0 pop af inc a jr npasss npass0: pop af rla ;shift the bit npasss: ld b,a ;save the pattern jp loop0 nuone: pop af ;re-align stack xor a ;start pattern with 0 first scf jr npasss ; marching 0 through field of ones npass1: ld a,(iy) cp 'z' jp z,again ;begin pattern again xor a ld a,b ;what was the last pass push af ;save for npass0 cp 0ffh ;rotation complete jr nz,march0 cp 0 ;first time entry jr nz,march0 ;do it again ; nmarch0 sets up the ffh for marching zeroe pattern nmarch0: xor a cpl ld b,a jp loop0 march0: pop af xor a cpl push af jr npass0 pmap1: ld l,20h call crlf ret space: ld c,asp call conout ld h,4 ret ; routine prints the pass number passprn: call crlf call crlf ld a,(iy) ;get the pass number inc iy ld c,a call conout ; Print a carriage return/line feed crlf: ld c,ACR call conout ld c,ALF ; Console output routine for Mult I/O or WB I/O conout: ld a,grp1 out (grpctl),a wait: in a,(lsr) and thre jr z,wait ld a,c out (thr),a ret ecode equ $ end