From 08c155dd7bccce2fa2ae993bf18e63785d80a62f Mon Sep 17 00:00:00 2001 From: ccmcbrien Date: Tue, 21 Mar 2023 18:15:23 -0600 Subject: [PATCH 1/2] Add ramtest feature --- bootloader.asm | 9 +- ram_test.asm | 342 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 ram_test.asm diff --git a/bootloader.asm b/bootloader.asm index cf3d99f..1615edc 100644 --- a/bootloader.asm +++ b/bootloader.asm @@ -42,6 +42,7 @@ PROGRAM_LOCATION = $0200 ; memory location for user progr .org $8000 + .include "ram_test.asm" ;================================================================================ ; @@ -199,8 +200,10 @@ MENU_main: cmp #4 beq .clear_ram cmp #5 - beq .about + beq .test_ram cmp #6 + beq .about + cmp #7 beq .credits jmp .end ; should we have an invalid option, restart @@ -222,6 +225,9 @@ MENU_main: .clear_ram: ; start the clear ram routine jsr BOOTLOADER__clear_ram jmp .start +.test_ram: + jsr RAM_TEST__main + jmp .start .about: ; start the about routine lda #about @@ -1073,6 +1079,7 @@ menu_items: .text " Run " .text " Monitor " .text " Clear RAM " + .text " RAM Test " .text " About " .text " Credits " about: diff --git a/ram_test.asm b/ram_test.asm new file mode 100644 index 0000000..1c4720e --- /dev/null +++ b/ram_test.asm @@ -0,0 +1,342 @@ +;================================================================================ +; +; "Ram Test" +; _________ +; +; v0.1 +; +; Ram Test - Simple module to test the RAM in a 6502 system +; +; Written by Chris McBrien for Sixty/5o2 by Jan Roesner +; +; Credits: +; - Ben Eater (Project 6502) +; - Steven Wozniak (bin2hex routine) +; - Anke L. (love, patience & support) +; - Jan Roesner (Sixty/5o2) +; +;================================================================================ +; Constants +RAM_TEST__STATUS_RUNNING = $0 +RAM_TEST__STATUS_FAIL = $1 +RAM_TEST__STATUS_PASS = $2 +RAM_TEST__LAST_BYTE = $3fd7 ; 2 bytes - Last address in RAM which can be tested +RAM_TEST__FIRST_BYTE = $0006 ; 2 bytes - First address in RAM which can be tested +RAM_TEST__NUM_PATTERNS = $04 ; 1 byte - Number of patterns +; Variables +RAM_TEST_TARGET = $04 ; 2 bytes - Zero-page vector for RAM location to test +RAM_TEST__STATUS = $3fd9 ; 1 byte - Indicates the test current status +RAM_TEST__CURRENT_PATTERN_OFFSET = $3fd8 ; 1 byte - The bit pattern read/written to RAM + +;================================================================================ +; +; RAM_TEST__main - main entry point for the ram test function +; +; Writes various bit patterns to all accessible RAM locaitons and verifies +; that the same value is read back. +; The stack page is skipped. +; Some reserved bytes in the zero-page and at the end of RAM are not tested. +; When complete the test result is displaed on the LCD. If the test failed, +; then the memory location which caused the failure is also shown. +; Pressing the 'exit' (left-key) will return to the Sixty/5o2 bootloader menu. +; ———————————————————————————————————— +; Preparatory Ops: none +; +; Returned Values: none +; +; Destroys: .A, .X, .Y +; +; ———————————————————————————————————— +; +;================================================================================ +RAM_TEST__main: + jsr .display_start_msg + lda #RAM_TEST__STATUS_RUNNING + sta RAM_TEST__STATUS ; set the status to running + ldx #RAM_TEST__NUM_PATTERNS + stx RAM_TEST__CURRENT_PATTERN_OFFSET ; initialize with the first test bit-pattern +.main_loop + jsr .test_pattern ; run a test with the current bit-pattern + ldy RAM_TEST__STATUS + bne .main_done ; exit if no longer running + dec RAM_TEST__CURRENT_PATTERN_OFFSET ; set to the next test bit-pattern + beq .main_done ; exit if all of the patterns have been run + jmp .main_loop +.main_done + cpy #RAM_TEST__STATUS_FAIL + beq .main_fail ; test failed? + lda #RAM_TEST__STATUS_PASS + sta RAM_TEST__STATUS + jsr .display_pass ; show that test passed + jmp .main_exit +.main_fail + jsr .display_fail +.main_exit: + rts + + +;================================================================================ +; +; .display_start_msg - displays message indicating the RAM test is about to start` +; +; ———————————————————————————————————— +; Preparatory Ops: none +; Returned Values: none +; +; Destroys: .A, .X, .Y +; ———————————————————————————————————— +; +;================================================================================ +.display_start_msg: + jsr LCD__clear_video_ram + lda #RAM_TEST__START_MSG + jsr LCD__print + jsr .long_wait + rts + + +;================================================================================ +; +; .display_fail - displays a message on the LCD indicating that the test failed +; +; Shows the memory location that failed +; and waits for the 'exit' (left) key to be pressed +; +; ———————————————————————————————————— +; Preparatory Ops: RAM_TEST_TARGET - contains the last address to be tested +; Returned Values: none +; +; Destroys: .A, .X, .Y +; ———————————————————————————————————— +; +;================================================================================ +.display_fail: + jsr LCD__clear_video_ram + lda #RAM_TEST__FAIL_MSG + jsr LCD__print ; show fail message + lda RAM_TEST_TARGET + 1 + ldx #12 + jsr .print_hex_num ; show high-byte of failed memory location + lda RAM_TEST_TARGET + ldx #14 + jsr .print_hex_num ; show low-byte of failed memory location + jsr LCD__render + jsr LCD__print_text.wait_for_input ; wait for the exit key to be pressed + rts + + +;================================================================================ +; +; .display_pass - displays a test passed message on the LCD +; +; Shows the message and waits for the 'exit' (left) key to be pressed +; +; ———————————————————————————————————— +; Preparatory Ops: none +; +; Returned Values: none +; +; Destroys: .A, .X, .Y +; ———————————————————————————————————— +; +;================================================================================ +.display_pass: + lda #RAM_TEST__PASS_MSG + ldx #1 + jsr LCD__print_text + rts + + +;================================================================================ +; +; .test_pattern - Tests all available RAM using a pattern of bits +; +; ———————————————————————————————————— +; Preparatory Ops: RAM_TEST__FIRST_BYTE - contains first testable byte +; RAM_TEST__LAST_BYTE - contains last testable byte +; RAM_TEST__CURRENT_PATTERN_OFFSET - contains offset into pattern array +; +; Returned Values: RAM_TEST__STATUS - Indicates that the test passed or failed +; +; Destroys: .A, .X, .Y +; +; ———————————————————————————————————— +; +;================================================================================ +.test_pattern: + lda #RAM_TEST__FIRST_BYTE + sta RAM_TEST_TARGET + 1 ; put first testable byte in zero-page vector + ldx RAM_TEST__CURRENT_PATTERN_OFFSET + lda RAM_TEST__PATTERNS, x ; put the test bit-pattern in .A + jsr .display_page +.pattern_loop: + sta (RAM_TEST_TARGET) ; write a test pattern to RAM + cmp (RAM_TEST_TARGET) ; read the pattern back + bne .pattern_fail ; stop if they don't match + inc RAM_TEST_TARGET ; move to next location in RAM + bne .continue_same_page + inc RAM_TEST_TARGET + 1 ; move to next page + jsr .display_page ; show the current page under test on the LCD + ldx #$1 + cpx RAM_TEST_TARGET + 1 ; check for stack-page + bne .pattern_continue + inc RAM_TEST_TARGET + 1 ; skip stack-page + jsr .display_page +.continue_same_page: + ldx #>RAM_TEST__LAST_BYTE ; if on the last testable page.... + cpx RAM_TEST_TARGET + 1 + bne .pattern_continue + ldx #RAM_TEST__PAGE_MSG + ldx #3 + jsr LCD__print_with_offset ; append 'PAGE=' + jsr .display_page_num ; append the memory page number + jsr LCD__render + pla + rts + + +;================================================================================ +; +; .display_page_num - Shows on the LCD the current memory page under test +; +; +; ———————————————————————————————————— +; Preparatory Ops: RAM_TEST_TARGET + 1 - contains the memory being being tested +; +; Returned Values: none +; +; Destroys: .A +; +; ———————————————————————————————————— +; +;================================================================================ +.display_page_num: + lda RAM_TEST_TARGET + 1 ; the current page in RAM of the test + and #$f0 ; get high digit + clc + ror + ror + ror + ror + ldx #8 + jsr .print_numeral + lda RAM_TEST_TARGET + 1 + and #$0f ; get low digit + ldx #9 + jsr .print_numeral + rts + +;================================================================================ +; +; .print_hex_num - Prints a hex number +; +; Displays a 2-digit hex value on the LCD by directly appending to video RAM +; +; ———————————————————————————————————— +; Preparatory Ops: .A - contains the value to print +; .X - contains the current offset into video RAM +; +; Returned Values: none +; +; Destroys: .A, .X, .Y +; +; ———————————————————————————————————— +; +;================================================================================ +.print_hex_num: + stx Z3 ; save offset into video RAM + + jsr LIB__bin_to_hex ; get the ASCII representation + stx Z2 ; save the low-digit + + ldx Z3 ; restore video RAM location + sta VIDEO_RAM, x ; put high-digit in video RAM + inx ; move to next character position + lda Z2 ; restore low-digit + sta VIDEO_RAM, x ; put low-digit in video RAM + + rts + + +;================================================================================ +; +; .long_wait - Provides a long wait +; +; Gives a timeout to allow the user to read messages before they disappear +; +; ———————————————————————————————————— +; Preparatory Ops: none +; +; Returned Values: none +; +; Destroys: .X, .Y +; +; ———————————————————————————————————— +; +;================================================================================ +.long_wait: + ldx #0 + ldy #0 ; count down from 256 * 256 +.wait_loop: + nop + dex + bne .wait_loop + dey + bne .wait_loop + rts + +RAM_TEST__PAGE_MSG: + string "PAGE=" +RAM_TEST__PASS_MSG: + string "PASS" +RAM_TEST__START_MSG: + string "Starting RAM test..." +RAM_TEST__FAIL_MSG: + string "FAILURE AT $" +RAM_TEST__PATTERNS: + byte $00, $ff, $aa, $55 \ No newline at end of file From 2b2c5bb7a97f1cd025a2deeebb5dfaa3a860a050 Mon Sep 17 00:00:00 2001 From: ccmcbrien Date: Tue, 21 Mar 2023 19:53:21 -0600 Subject: [PATCH 2/2] Fix last menu item. Use LIB routine for hex numbers. Use all the patterns. --- bootloader.asm | 4 ++-- ram_test.asm | 41 +++++++---------------------------------- 2 files changed, 9 insertions(+), 36 deletions(-) diff --git a/bootloader.asm b/bootloader.asm index 1615edc..e8d79a2 100644 --- a/bootloader.asm +++ b/bootloader.asm @@ -102,9 +102,9 @@ MENU_main: jmp .start .MAX_SCREEN_POS: ; define some constants in ROM - .byte $05 ; its always number of items - 2, here its 6 windows ($00-$05) in 7 items + .byte $06 ; its always number of items - 2, here its 6 windows ($00-$05) in 7 items .OFFSETS: - .byte $00, $10, $20, $30, $40, $50 ; content offsets for all 6 screen windows + .byte $00, $10, $20, $30, $40, $50, $60 ; content offsets for all 6 screen windows .start: ; and off we go jsr LCD__clear_video_ram ldx POSITION_MENU diff --git a/ram_test.asm b/ram_test.asm index 1c4720e..c07bf31 100644 --- a/ram_test.asm +++ b/ram_test.asm @@ -53,13 +53,15 @@ RAM_TEST__main: jsr .display_start_msg lda #RAM_TEST__STATUS_RUNNING sta RAM_TEST__STATUS ; set the status to running - ldx #RAM_TEST__NUM_PATTERNS + ldx #RAM_TEST__NUM_PATTERNS - 1 stx RAM_TEST__CURRENT_PATTERN_OFFSET ; initialize with the first test bit-pattern .main_loop jsr .test_pattern ; run a test with the current bit-pattern ldy RAM_TEST__STATUS bne .main_done ; exit if no longer running - dec RAM_TEST__CURRENT_PATTERN_OFFSET ; set to the next test bit-pattern + dec RAM_TEST__CURRENT_PATTERN_OFFSET ; set to the next test bit-pattern + ldy #255 ; done with all patterns? + cpy RAM_TEST__CURRENT_PATTERN_OFFSET beq .main_done ; exit if all of the patterns have been run jmp .main_loop .main_done @@ -234,43 +236,14 @@ RAM_TEST__main: ldy #>RAM_TEST__PAGE_MSG ldx #3 jsr LCD__print_with_offset ; append 'PAGE=' - jsr .display_page_num ; append the memory page number + lda RAM_TEST_TARGET + 1 ; the current page in RAM of the test + ldx #8 + jsr .print_hex_num jsr LCD__render pla rts -;================================================================================ -; -; .display_page_num - Shows on the LCD the current memory page under test -; -; -; ———————————————————————————————————— -; Preparatory Ops: RAM_TEST_TARGET + 1 - contains the memory being being tested -; -; Returned Values: none -; -; Destroys: .A -; -; ———————————————————————————————————— -; -;================================================================================ -.display_page_num: - lda RAM_TEST_TARGET + 1 ; the current page in RAM of the test - and #$f0 ; get high digit - clc - ror - ror - ror - ror - ldx #8 - jsr .print_numeral - lda RAM_TEST_TARGET + 1 - and #$0f ; get low digit - ldx #9 - jsr .print_numeral - rts - ;================================================================================ ; ; .print_hex_num - Prints a hex number