diff --git a/common/sram-common.h b/common/sram-common.h index 54cc45e..78e8c3a 100644 --- a/common/sram-common.h +++ b/common/sram-common.h @@ -13,11 +13,12 @@ * read. Requires these macros (with sample definitions): * * #define SRAM_MARCH_TEST_START(bank) sram_start_bank(bank) - * #define SRAM_MARCH_TEST_DATA(data) sram_write(&data, 1) + * #define SRAM_MARCH_TEST_DATA(offset, data) sram_write(&data, 1) * #define SRAM_MARCH_TEST_END() sram_flush_and_release_bank() */ bool sram_march_test(int pass) { - SRAM_MARCH_TEST_START(pass & 1); + int bank = pass & 1; + SRAM_MARCH_TEST_START(bank); switch (pass) { // Bit-sliding test. @@ -46,32 +47,54 @@ bool sram_march_test(int pass) { case 13: case 14: case 15: - for (int i = 0; i < SRAM_BANK_SIZE_BYTES; ++i) { - int bit = (i + pass / 2) % 8; + for (int offset = 0; offset < SRAM_BANK_SIZE_BYTES; ++offset) { + int bit = (offset + pass / 2) % 8; uint8_t data = 1 << bit; - SRAM_MARCH_TEST_DATA(data); + SRAM_MARCH_TEST_DATA(offset, data); } break; // Write the lowest 8 bits of the address to each byte of SRAM. case 16: case 17: - for (int i = 0; i < SRAM_BANK_SIZE_BYTES; ++i) { - uint8_t data = i & 0xff; - SRAM_MARCH_TEST_DATA(data); + for (int offset = 0; offset < SRAM_BANK_SIZE_BYTES; ++offset) { + uint8_t data = offset & 0xff; + SRAM_MARCH_TEST_DATA(offset, data); } break; // Write the lowest 8 bits of the address (inverted) to each byte of SRAM. case 18: case 19: - for (int i = 0; i < SRAM_BANK_SIZE_BYTES; ++i) { - uint8_t data = (i & 0xff) ^ 0xff; - SRAM_MARCH_TEST_DATA(data); + for (int offset = 0; offset < SRAM_BANK_SIZE_BYTES; ++offset) { + uint8_t data = (offset & 0xff) ^ 0xff; + SRAM_MARCH_TEST_DATA(offset, data); } break; + + // Write repeating sequences with prime periods, to avoid any periodic + // repeating on address bit boundaries (powers of 2). To make bank 1 + // different from bank 0, start counter at non-zero for bank 1. + case 20: + case 21: { + int primes[8] = { 251, 241, 239, 233, 229, 227, 223, 211 }; + int prime_index = 0; + int offset = 0; + int counter = bank * 199; + for (; offset < SRAM_BANK_SIZE_BYTES; ++offset, ++counter) { + if (counter == primes[prime_index] * 255) { + prime_index = (prime_index + 1) % 8; + counter = 0; + } + uint8_t data = counter % primes[prime_index]; + SRAM_MARCH_TEST_DATA(offset, data); + } + break; + } } SRAM_MARCH_TEST_END(); return true; } + +#define SRAM_MARCH_TEST_NUM_PASSES 22 diff --git a/emulator-patches/blastem-0.6.2.patch b/emulator-patches/blastem-0.6.2.patch index 7d2b130..ac5fec0 100644 --- a/emulator-patches/blastem-0.6.2.patch +++ b/emulator-patches/blastem-0.6.2.patch @@ -1,6 +1,6 @@ -commit 5126640d303a7411d7e84e8d41cfd5d92b88c1bd -Author: Joey Parrish -Date: Wed Mar 27 07:39:28 2024 -0700 +commit 3c98e2a06d7c398d7b46b032c349837ebb43aa59 +Author: Joey Parrish +Date: Mon Sep 23 21:34:59 2024 -0700 Emulate Kinetoscope hardware in BlastEm 0.6.2 @@ -21,7 +21,7 @@ index 0000000..8f39f7f +zdis +kinetoscope diff --git a/Makefile b/Makefile -index 0dddc9f..f4c96df 100644 +index 0dddc9f..f8e4562 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,13 @@ endif @@ -77,6 +77,15 @@ index 0dddc9f..f4c96df 100644 %.tiles : %.spec ./img2tiles.py -s $< $@ +@@ -382,6 +398,8 @@ m68k.c : m68k.cpu cpu_dsl.py + res.o : blastem.rc + $(WINDRES) blastem.rc res.o + ++kinetoscope/emulator-patches/kinetoscope.o: kinetoscope/emulator-patches/kinetoscope.c kinetoscope/emulator-patches/*.h kinetoscope/common/*.h ++ + arrow.tiles : arrow.png + cursor.tiles : cursor.png + font_interlace_variable.tiles : font_interlace_variable.png diff --git a/build_release b/build_release index f5faa10..880044d 100755 --- a/build_release diff --git a/emulator-patches/kinetoscope.c b/emulator-patches/kinetoscope.c index b1122b9..2471d90 100644 --- a/emulator-patches/kinetoscope.c +++ b/emulator-patches/kinetoscope.c @@ -74,8 +74,8 @@ static void write_sram(uint32_t offset, const uint8_t* data, uint32_t size); // Macros to complete sram_march_test in sram-common.h -#define SRAM_MARCH_TEST_START(bank) uint32_t offset = (pass & 1) * SRAM_BANK_SIZE_BYTES -#define SRAM_MARCH_TEST_DATA(data) write_sram(offset++, &data, 1) +#define SRAM_MARCH_TEST_START(bank) uint32_t bank_offset = bank ? SRAM_BANK_SIZE_BYTES : 0; +#define SRAM_MARCH_TEST_DATA(offset, data) write_sram(offset + bank_offset, &data, 1) #define SRAM_MARCH_TEST_END() {} // Defines sram_march_test() diff --git a/firmware/sram.cc b/firmware/sram.cc index 6a77b05..c0a2498 100644 --- a/firmware/sram.cc +++ b/firmware/sram.cc @@ -15,7 +15,7 @@ // Macros to complete sram_march_test in sram-common.h #define SRAM_MARCH_TEST_START(bank) sram_start_bank(bank) -#define SRAM_MARCH_TEST_DATA(data) sram_write(&data, 1) +#define SRAM_MARCH_TEST_DATA(offset, data) sram_write(&data, 1) #define SRAM_MARCH_TEST_END() sram_flush_and_release_bank() // Defines sram_march_test() diff --git a/software/build.sh b/software/build.sh index c17ef3a..acf728b 100755 --- a/software/build.sh +++ b/software/build.sh @@ -45,7 +45,7 @@ docker run \ -v "$repo_root":/src \ -u $(id -u):$(id -g) \ -w "/src/$relative_dir" \ - ghcr.io/stephane-d/sgdk:latest + ghcr.io/stephane-d/sgdk:working # SGDK's compiler makes the output executable, but that's not appropriate. chmod 644 $this_dir/out/rom.bin diff --git a/software/hardware-test/src/main.c b/software/hardware-test/src/main.c index 045dd5d..c75f3b2 100644 --- a/software/hardware-test/src/main.c +++ b/software/hardware-test/src/main.c @@ -36,8 +36,8 @@ // Macros to complete sram_march_test in sram-common.h #define SRAM_MARCH_TEST_START(bank) \ volatile uint8_t* sram = bank ? KINETOSCOPE_SRAM_BANK_1 : KINETOSCOPE_SRAM_BANK_0 -#define SRAM_MARCH_TEST_DATA(data) { \ - if (sram[i] != data) { \ +#define SRAM_MARCH_TEST_DATA(offset, data) { \ + if (sram[offset] != data) { \ return false; \ } \ } @@ -251,7 +251,7 @@ int main(bool hardReset) { // 13. Perform various intensive memory tests through the firmware. - // There are 20 different passes of this, with different patterns to verify. + // There are many different passes of this, with different patterns to verify. line++; // blank line int memory_test_pass_line = line; line += 2; @@ -260,9 +260,9 @@ int main(bool hardReset) { // 0 1 // 012345678901234567 VDP_drawText("SRAM test pass 00", 0, memory_test_pass_line); - VDP_drawText("....................", 1, memory_test_pass_line + 1); + VDP_drawText("......................", 1, memory_test_pass_line + 1); - for (int pass = 0; pass < 20; ++pass) { + for (int pass = 0; pass < SRAM_MARCH_TEST_NUM_PASSES; ++pass) { waitMs(1); *KINETOSCOPE_PORT_COMMAND = CMD_MARCH_TEST; *KINETOSCOPE_PORT_ARG = pass;