;; Emacs Mode Selection Info: -*-mode: ASM; coding: iso-latin-1-dos;-*- * ;; ******************************************************************************************** ;; File Name: BIT.inc ;; Auther: John L. Weinrich ;; Date: 01/31/03 ;; Useage 4004 TIC-TAC-TOE Game ;; Description: ;; ;; This routine tests RAM by performing three tests: ;; 1. Sequences through each RAM CHAR, RAM REG, RAM, and RAM bank, writes a 0xA, checks for ;; 0xA, writes a 0x5, and checks for 0x5. ;; ;; 2. Walks a 1 from bit 0 (LSB) through bit 3 (MSB) and checks for valid data. ;; ;; 3. Writes a sequential number sequentially into the entire RAM and then sequentially reads ;; and checks each RAM location for correct data. Data number sequence is offet at CHAR, ;; REG/RAM CHIP, and RAM bank to prevent mimicking. ;; ;; If an error is detected, ACC returns a MEM_BAD, else ACC = MEM_GOOD. ;; ;; Memory locations are altered. ;; ;; The display is also tested by writing and reading to the display RAM and verifying the data ;; is correct. ;; ;; Status RAM is pattern checked with the RAM. ;; ;; Assumptions: All possible RAM is available for testing: ;; 8 RAM Banks ;; 4 RAM/Bank ;; 4 RAM REGs ;; 16 CHAR/REG ;; = 4096-4 bit memory locations ;; ;; The display is connected ;; ;; Status registers: ;; 4 RAM Banks ;; 4 RAM/Bank ;; 4 RAM REGs ;; 4 CHAR/REG ;; = 256-4 bit status memory locations ;; ;; ;; Registers used: SRC_P, SCRATCH_0_P, SCRATCH_1_P, UTILITY_0_L, & ACC ;; Memory used: All, destructive ;; Entrance parameters: None ;; Exit parameters: SCRATCH_0_H: if memory bad: RAM bank pointer, else RAM bank pointer+1 ;; SCRATCH_1_L: Last saved RAM CHAR ;; UTILITY_0_L Status of BIT, LSB = display, bit 1 = memory, 1 = fail ;; SRC_L: if memory bad: RAM CHAR pointer, else RAM CHAR pointer+1 ;; SRC_H: if memory bad: RAM REG/CHIP pointer, else RAM REG/CHIP pointer+1 ;; ACC: if memory bad: MEM_BAD, else MEM_GOOD ;; Labels used: BIT (call label) ;; MemTestLoop1 ;; MemTestLoop2 ;; MemTestLoop3 ;; TestChar0 ;; TestChar1 ;; TestWalk1 ;; WalkOneLoop ;; NextBit ;; MemOK1 ;; MemOK2 ;; PatternTest ;; DisLowNibGood ;; DisGood ;; ******************************************************************************************** ;; Test display BIT fim UTILITY_0_P,0 ; Initilize status register ;; First, get the display ready for command data fim SRC_P,MISC_PORT ; Select MISC port src SRC_P ; Tell MISC port it is selected ldm DISPLAY_COMMAND_MODE ; Set accumulator for display command mode wrr ; Write MISC port, set display to command mode ;; Send CG RAM address fim SRC_P,DISPLAY_HIGH_PORT ; Get upper nibble display port address src SRC_P ; Send out upper display port address ldm DISPLAY_CG_ADDRESS_H ; Get upper nibble data wrr ; Write upper nibble to display port fim SRC_P,DISPLAY_LOW_PORT ; Get lower nibble display port address src SRC_P ; Send out lower display port address ldm DISPLAY_CG_ADDRESS_L ; Get lower nibble data wrr ; Write lower nibble to display port ;; Set display to data mode fim SRC_P,MISC_PORT ; Select MISC port src SRC_P ; Tell MISC port it is selected ldm DISPLAY_DATA_MODE ; Set accumulator for display command mode wrr ; Write MISC port, set display to command mode ;; Write upper nibble to display fim SRC_P,DISPLAY_HIGH_PORT ; Select display upper nibble port src SRC_P ; Send out display upper nibble port selection ldm TEST_CHAR0 ; Get test char wrr ; Write the upper nibble to display ;; Write lower nibble to display fim SRC_P,DISPLAY_LOW_PORT ; Select display lower nibble port src SRC_P ; Send out display lower nibble port selection ldm TEST_CHAR1 ; Get test char wrr ; Write the loer nibble to display ;; Set display to command mode fim SRC_P,MISC_PORT ; Select MISC port src SRC_P ; Tell MISC port it is selected ldm DISPLAY_COMMAND_MODE ; Set accumulator for display command mode wrr ; Write MISC port, set display to command mode ;; Send CG RAM address fim SRC_P,DISPLAY_HIGH_PORT ; Get upper nibble display port address src SRC_P ; Send out upper display port address ldm DISPLAY_CG_ADDRESS_H ; Get upper nibble data wrr ; Write upper nibble to display port fim SRC_P,DISPLAY_LOW_PORT ; Get lower nibble display port address src SRC_P ; Send out lower display port address ldm DISPLAY_CG_ADDRESS_L ; Get lower nibble data wrr ; Write lower nibble to display port ;; Set display to data mode fim SRC_P,MISC_PORT ; Select MISC port src SRC_P ; Tell MISC port it is selected ldm DISPLAY_DATA_MODE ; Set accumulator for display command mode wrr ; Write MISC port, set display to command mode ;; Read lower nibble from display and check if matched the test data fim SRC_P,DISPLAY_LOW_PORT ; Select display lower nibble port src SRC_P ; Send out display lower nibble port selection clb ; Clear the accumulator rdr ; Read the lower test nibble fim SCRATCH_0_P,TEST_CHAR1 ; Get the test data sub SCRATCH_0_L ; Subtract the lower nibble of display jcn Z,DisLowNibGood ; Check if written data is valid jun DisBad ; Set display bad display bit and return ;; Read upper nibble from display and check if matched the test data DisLowNibGood fim SRC_P,DISPLAY_HIGH_PORT ; Select display upper nibble port src SRC_P ; Send out display upper nibble port selection clb ; Clear the accumulator rdr ; Read the upper test nibble fim SCRATCH_0_P,TEST_CHAR0 ; Get the test data sub SCRATCH_0_L ; Subtract the upper nibble of display jcn Z,MemTest ; Check if written data is valid DisBad xch UTILITY_0_L ; Get status data rar ; Select display bit stc ; Set display bit to indicate FAIL ral ; deselect display bit xch UTILITY_0_L ; Put back status data ;; Test RAM ;; Initialize loop pointers used to point to RAM MemTest fim SRC_P,RAM_0_REG_0_CHAR_0 ; Initialize pointer to RAM 0, RAM REG 0, & RAM CHAR 0 fim SCRATCH_0_P,RAM_BANK_0 + 080H ; Initialize pointer to RAM bank 0, set MSB for loop counter ;; Start of loop, sequencing through RAM bank, RAM, RAM REG, & RAM CHAR MemTestLoop1 ld SCRATCH_0_H ; Move RAM bank pointer to ACC dcl ; Select RAM bank src SRC_P ; Select RAM, RAM REG, & RAM CHAR ;; Test with TEST_CHAR0 clc ; Clear carry so flag test works TestChar0 ldm TEST_CHAR0 ; Select TEST_CHAR0 to write to RAM CHAR wrm ; Write RAM CHAR sbm ; Read and subtract RAM CHAR from ACC jcn Z,TestChar1 ; Check if written data is valid jun MemBad ; Set memory bad bit and return ;; Test with TEST_CHAR1 TestChar1 clc ; Clear carry so flag test works ldm TEST_CHAR1 ; Select TEST_CHAR1 to write to RAM CHAR wrm ; Write RAM CHAR sbm ; Read and subtract RAM CHAR from ACC jcn Z,TestWalkOne ; Check if written data is valid jun MemBad ; Set memory bad bit and return ;; Test walking "1" TestWalkOne clc ; Clear carry so flag test works ldm 0001B ; Preload ACC with LSB set WalkOneLoop wrm ; Write test CHAR out to RAM CHAR location sbm ; Read and subtract RAM CHAR from ACC jcn Z,NextBit ; Check if written data is valid jun MemBad ; Set memory bad bit and return NextBit clc ; Clear carry so flag test works rdm ; Data valid, read RAM CHAR ral ; Rotate test bit left one jcn Z,MemOK1 ; Check if all four bit are tested jun WalkOneLoop ; Not tested, loop and test next bit ;; Increment loop pointers and check if done MemOK1 isz SRC_L,MemTestLoop1 ; Increment RAM CHAR pointer & check for rollover isz SRC_H,MemTestLoop1 ; Increment RAM REG/RAM CHIP pointer & check for rollover isz SCRATCH_0_H,MemTestLoop1 ; Increment RAM bank pointer & check for rollover ;; Start of pattern test. save sequential data into RAM, read back and verify correct. ;; Offset data at each RAM CHAR and RAM REG/RAM CHIP to make sure that there is indeed ;; more than one set of RAM locations. PatternTest fim SRC_P,RAM_0_REG_0_CHAR_0 ; Initialize pointer to RAM 0, RAM REG 0, & RAM CHAR 0 fim SCRATCH_0_P,RAM_BANK_0 + 080H ; Initialize pointer to RAM bank 0, set MSB for loop counter fim SCRATCH_1_P,0 ; Initialize Accumulator storage ;; Start of loop, sequencing through RAM bank, RAM, RAM REG, & RAM CHAR MemTestLoop2 ld SCRATCH_0_H ; Move RAM bank pointer to ACC dcl ; Select RAM bank src SRC_P ; Select RAM, RAM REG, & RAM CHAR clb ; Make sure accumulator is cleared ld SCRATCH_1_L ; Get test data wrm ; Write test data to RAM CHAR inc SCRATCH_1_L ; Increment test data isz SRC_L,MemTestLoop2 ; Increment RAM CHAR pointer & check for rollover inc SCRATCH_1_L ; Increment test data isz SRC_H,MemTestLoop2 ; Increment RAM REG/RAM CHIP pointer & check for rollover inc SCRATCH_1_L ; Increment test data isz SCRATCH_0_H,MemTestLoop2 ; Increment RAM bank pointer & check for rollover fim SRC_P,RAM_0_REG_0_CHAR_0 ; Initialize pointer to RAM 0, RAM REG 0, & RAM CHAR 0 fim SCRATCH_0_P,RAM_BANK_0 + 0B0H ; Initialize pointer to RAM bank 0, set MSB for loop counter ;; Start of loop, sequencing through RAM bank, RAM, RAM REG, & status CHAR fim SCRATCH_1_P,0 ; Initialize Accumulator storage StatusTestLoop2 ld SCRATCH_0_H ; Move RAM bank pointer to ACC dcl ; Select RAM bank src SRC_P ; Select RAM, RAM REG, & RAM CHAR ld SCRATCH_1_L ; Get test data wr0 ; Write test data to Status register inc SCRATCH_1_L ; Increment test CHAR ld SCRATCH_1_L ; Get test data wr1 ; Write test data to Status register inc SCRATCH_1_L ; Increment test CHAR inc SCRATCH_1_L ; Increment test CHAR ld SCRATCH_1_L ; Get test data wr2 ; Write test data to Status register inc SCRATCH_1_L ; Increment test CHAR ld SCRATCH_1_L ; Get test data wr3 ; Write test data to Status register isz SRC_H,StatusTestLoop2 ; Increment RAM REG/RAM CHIP pointer & check for rollover isz SCRATCH_0_H,StatusTestLoop2 ; Increment RAM bank pointer & check for rollover ;; Start of pattern checking fim SRC_P,RAM_0_REG_0_CHAR_0 ; Initialize pointer to RAM 0, RAM REG 0, & RAM CHAR 0 fim SCRATCH_0_P,RAM_BANK_0 + 080H ; Initialize pointer to RAM bank 0, set MSB for loop counter fim SCRATCH_1_P,0 ; Initialize Accumulator storage MemTestLoop3 ld SCRATCH_0_H ; Move RAM bank pointer to ACC dcl ; Select RAM bank src SRC_P ; Select RAM, RAM REG, & RAM CHAR clb ; make sure accumulator is cleared ld SCRATCH_1_L ; Get test data sbm ; Subtract RAM from accumulator jcn Z,MemOK2 ; If accumulator matches RAM CHAR, them RAM CHAR is OK MemBad xch UTILITY_0_L ; Get status data rar ; Select memory bit rar ; " " stc ; Set memory bit to indicate FAIL ral ; deselect memory bit ral ; " " xch UTILITY_0_L ; Put back status data bbl MEM_BAD ; Else RAM CHAR is bad MemOK2 inc SCRATCH_1_L ; Increment test data isz SRC_L,MemTestLoop3 ; Increment RAM CHAR pointer & check for rollover inc SCRATCH_1_L ; Increment test data isz SRC_H,MemTestLoop3 ; Increment RAM REG/RAM CHIP pointer & check for rollover inc SCRATCH_1_L ; Increment test data isz SCRATCH_0_H,MemTestLoop3 ; Increment RAM bank pointer & check for rollover fim SRC_P,RAM_0_REG_0_CHAR_0 ; Initialize pointer to RAM 0, RAM REG 0, & RAM CHAR 0 fim SCRATCH_0_P,RAM_BANK_0 + 0B0H ; Initialize pointer to RAM bank 0, set MSB for loop counter ;; Start of loop, sequencing through RAM bank, RAM, RAM REG, & status CHAR fim SCRATCH_1_P,0 ; Initialize Accumulator storage StatusTestLoop3 ld SCRATCH_0_H ; Move RAM bank pointer to ACC dcl ; Select RAM bank src SRC_P ; Select RAM, RAM REG, & RAM CHAR clb ; Make sure accumulator is cleared rd0 ; Read Status register 0 sub SCRATCH_1_L ; Compare status CHAR data jcn NZ,MemBad ; If accumulator matches Status CHAR, then Status CHAR is OK clb ; Make sure accumulator is cleared rd1 ; Read Status register 1 inc SCRATCH_1_L ; Increment test CHAR sub SCRATCH_1_L ; Compare status CHAR data jcn NZ,MemBad ; If accumulator matches Status CHAR, then Status CHAR is OK clb ; Make sure accumulator is cleared rd2 ; Read Status register 2 inc SCRATCH_1_L ; Increment test CHAR inc SCRATCH_1_L ; Increment test CHAR sub SCRATCH_1_L ; Compare status CHAR data jcn NZ,MemBad ; If accumulator matches Status CHAR, then Status CHAR is OK clb ; Make sure accumulator is cleared rd3 ; Read Status register 3 inc SCRATCH_1_L ; Increment test CHAR sub SCRATCH_1_L ; Compare status CHAR data jcn NZ,MemBad ; If accumulator matches RAM CHAR, them RAM CHAR is OK MemOK3 isz SRC_H,StatusTestLoop3 ; Increment RAM REG/RAM CHIP pointer & check for rollover isz SCRATCH_0_H,StatusTestLoop3 ; Increment RAM bank pointer & check for rollover jun CheckRNG ; Jump to check random number generator ;; Check Random Number Generator. org BIT_LOCATION + 0100H ; ORG here cause' jcn jump too large CheckRNG fim SCRATCH_1_P,000H ; Load RN checking register fim SCRATCH_0_P,000H ; Load RN checking register LookAgain ldm RAM_BANK_0 ; Select RAM bank 0 dcl ; Send out RAM bank selection fim SRC_P,RAND_NUM_GEN_PORT ; Select RNG port src SRC_P ; Send out RNG port selection clb ; Make sure that the accumulator is clear rdr ; Get RNG sub SCRATCH_0_L ; Check if the RN is found isz SCRATCH_0_H,NoTimeOut ; Increment loop timer 1 isz SCRATCH_1_L,NoTimeOut ; Increment loop timer 2 isz SCRATCH_1_H,NoTimeOut ; Increment loop timer 2 RNGBad xch UTILITY_0_L ; Get status data rar ; Select memory bit rar ; " " rar ; " " stc ; Set RNG bit to indicate FAIL ral ; deselect memory bit ral ; " " ral ; " " xch UTILITY_0_L ; Put back status data jun MemBad ; Jump to memory bad NoTimeOut jcn NZ,LookAgain ; If not, look again isz SCRATCH_0_L,LookAgain ; Check all values (0-F) bbl MEM_GOOD ; Data valid, return MEM_GOOD