// // // File Name : MCL65_PETDoctor.ino // Used on : // Author : Ted Fried, MicroCore Labs // Creation : 12/16/2025 // // Description: // ============ // // Commodore PET motherboard tester // //------------------------------------------------------------------------ // // Modification History: // ===================== // // Revision 1 12/62/2025 // Initial revision // // //------------------------------------------------------------------------ // // Copyright (c) 2025 Ted Fried // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // //------------------------------------------------------------------------ #include // Teensy 4.1 pin assignments // #define PIN_CLK0 24 #define PIN_RESET 40 #define PIN_READY_n 26 #define PIN_IRQ 25 #define PIN_NMI 41 #define PIN_RDWR_n 12 #define PIN_SYNC 39 #define PIN_ADDR0 27 #define PIN_ADDR1 38 #define PIN_ADDR2 28 #define PIN_ADDR3 37 #define PIN_ADDR4 29 #define PIN_ADDR5 36 #define PIN_ADDR6 30 #define PIN_ADDR7 35 #define PIN_ADDR8 31 #define PIN_ADDR9 34 #define PIN_ADDR10 32 #define PIN_ADDR11 33 #define PIN_ADDR12 1 #define PIN_ADDR13 0 #define PIN_ADDR14 2 #define PIN_ADDR15 23 #define PIN_DATAIN0 14 #define PIN_DATAIN1 15 #define PIN_DATAIN2 16 #define PIN_DATAIN3 17 #define PIN_DATAIN4 18 #define PIN_DATAIN5 19 #define PIN_DATAIN6 20 #define PIN_DATAIN7 21 #define PIN_DATAOUT0 11 #define PIN_DATAOUT1 10 #define PIN_DATAOUT2 9 #define PIN_DATAOUT3 8 #define PIN_DATAOUT4 7 #define PIN_DATAOUT5 6 #define PIN_DATAOUT6 5 #define PIN_DATAOUT7 4 #define PIN_DATAOUT_OE_n 3 uint8_t direct_datain=0; uint8_t direct_reset=0; uint8_t direct_ready_n=0; uint8_t direct_irq=0; uint8_t direct_nmi=0; uint8_t global_temp=0; uint8_t sid_sound_on=0; int incomingByte; uint32_t failcount=0; uint32_t failbits=0; uint8_t DRAM_Pattern_Array[0x8000]; uint32_t Dataout_Array7[256] = { 0x0, 0x4, 0x1, 0x5, 0x800, 0x804, 0x801, 0x805, 0x10000, 0x10004, 0x10001, 0x10005, 0x10800, 0x10804, 0x10801, 0x10805, 0x20000, 0x20004, 0x20001, 0x20005, 0x20800, 0x20804, 0x20801, 0x20805, 0x30000, 0x30004, 0x30001, 0x30005, 0x30800, 0x30804, 0x30801, 0x30805, 0x400, 0x404, 0x401, 0x405, 0xc00, 0xc04, 0xc01, 0xc05, 0x10400, 0x10404, 0x10401, 0x10405, 0x10c00, 0x10c04, 0x10c01, 0x10c05, 0x20400, 0x20404, 0x20401, 0x20405, 0x20c00, 0x20c04, 0x20c01, 0x20c05, 0x30400, 0x30404, 0x30401, 0x30405, 0x30c00, 0x30c04, 0x30c01, 0x30c05, 0x0, 0x4, 0x1, 0x5, 0x800, 0x804, 0x801, 0x805, 0x10000, 0x10004, 0x10001, 0x10005, 0x10800, 0x10804, 0x10801, 0x10805, 0x20000, 0x20004, 0x20001, 0x20005, 0x20800, 0x20804, 0x20801, 0x20805, 0x30000, 0x30004, 0x30001, 0x30005, 0x30800, 0x30804, 0x30801, 0x30805, 0x400, 0x404, 0x401, 0x405, 0xc00, 0xc04, 0xc01, 0xc05, 0x10400, 0x10404, 0x10401, 0x10405, 0x10c00, 0x10c04, 0x10c01, 0x10c05, 0x20400, 0x20404, 0x20401, 0x20405, 0x20c00, 0x20c04, 0x20c01, 0x20c05, 0x30400, 0x30404, 0x30401, 0x30405, 0x30c00, 0x30c04, 0x30c01, 0x30c05, 0x0, 0x4, 0x1, 0x5, 0x800, 0x804, 0x801, 0x805, 0x10000, 0x10004, 0x10001, 0x10005, 0x10800, 0x10804, 0x10801, 0x10805, 0x20000, 0x20004, 0x20001, 0x20005, 0x20800, 0x20804, 0x20801, 0x20805, 0x30000, 0x30004, 0x30001, 0x30005, 0x30800, 0x30804, 0x30801, 0x30805, 0x400, 0x404, 0x401, 0x405, 0xc00, 0xc04, 0xc01, 0xc05, 0x10400, 0x10404, 0x10401, 0x10405, 0x10c00, 0x10c04, 0x10c01, 0x10c05, 0x20400, 0x20404, 0x20401, 0x20405, 0x20c00, 0x20c04, 0x20c01, 0x20c05, 0x30400, 0x30404, 0x30401, 0x30405, 0x30c00, 0x30c04, 0x30c01, 0x30c05, 0x0, 0x4, 0x1, 0x5, 0x800, 0x804, 0x801, 0x805, 0x10000, 0x10004, 0x10001, 0x10005, 0x10800, 0x10804, 0x10801, 0x10805, 0x20000, 0x20004, 0x20001, 0x20005, 0x20800, 0x20804, 0x20801, 0x20805, 0x30000, 0x30004, 0x30001, 0x30005, 0x30800, 0x30804, 0x30801, 0x30805, 0x400, 0x404, 0x401, 0x405, 0xc00, 0xc04, 0xc01, 0xc05, 0x10400, 0x10404, 0x10401, 0x10405, 0x10c00, 0x10c04, 0x10c01, 0x10c05, 0x20400, 0x20404, 0x20401, 0x20405, 0x20c00, 0x20c04, 0x20c01, 0x20c05, 0x30400, 0x30404, 0x30401, 0x30405, 0x30c00, 0x30c04, 0x30c01, 0x30c05 }; uint32_t Dataout_Array9[256] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140, 0x140 }; uint32_t gpio6_addr_array_l[256] = {0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000, 0x0, 0x80000000, 0x10000000, 0x90000000 }; uint32_t gpio6_addr_array_h[256] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0xc, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000000, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000004, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x2000008, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c, 0x200000c}; uint32_t gpio7_addr_array_l[256] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x80000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0x40000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0xc0000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10080000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x10040000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000, 0x100c0000}; uint32_t gpio7_addr_array_h[256] = {0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000, 0x0, 0x0, 0x20000000, 0x20000000, 0x1000, 0x1000, 0x20001000, 0x20001000}; uint32_t gpio8_addr_array_l[256] = {0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x0, 0x0, 0x0, 0x0, 0x40000, 0x40000, 0x40000, 0x40000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000, 0x800000, 0x800000, 0x800000, 0x800000, 0x840000, 0x840000, 0x840000, 0x840000}; uint32_t gpio8_addr_array_h[256] = {0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000, 0x0, 0x400000}; uint32_t gpio9_addr_array_l[256] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000}; uint32_t gpio9_addr_array_h[256] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; // ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------ // Setup Teensy 4.1 IO's // void setup() { pinMode(PIN_CLK0, INPUT); pinMode(PIN_RESET, INPUT); pinMode(PIN_READY_n, INPUT); pinMode(PIN_IRQ, INPUT); pinMode(PIN_NMI, INPUT); pinMode(PIN_RDWR_n, OUTPUT); pinMode(PIN_SYNC, OUTPUT); pinMode(PIN_ADDR0, OUTPUT); pinMode(PIN_ADDR1, OUTPUT); pinMode(PIN_ADDR2, OUTPUT); pinMode(PIN_ADDR3, OUTPUT); pinMode(PIN_ADDR4, OUTPUT); pinMode(PIN_ADDR5, OUTPUT); pinMode(PIN_ADDR6, OUTPUT); pinMode(PIN_ADDR7, OUTPUT); pinMode(PIN_ADDR8, OUTPUT); pinMode(PIN_ADDR9, OUTPUT); pinMode(PIN_ADDR10, OUTPUT); pinMode(PIN_ADDR11, OUTPUT); pinMode(PIN_ADDR12, OUTPUT); pinMode(PIN_ADDR13, OUTPUT); pinMode(PIN_ADDR14, OUTPUT); pinMode(PIN_ADDR15, OUTPUT); pinMode(PIN_DATAIN0, INPUT); pinMode(PIN_DATAIN1, INPUT); pinMode(PIN_DATAIN2, INPUT); pinMode(PIN_DATAIN3, INPUT); pinMode(PIN_DATAIN4, INPUT); pinMode(PIN_DATAIN5, INPUT); pinMode(PIN_DATAIN6, INPUT); pinMode(PIN_DATAIN7, INPUT); pinMode(PIN_DATAOUT0, OUTPUT); pinMode(PIN_DATAOUT1, OUTPUT); pinMode(PIN_DATAOUT2, OUTPUT); pinMode(PIN_DATAOUT3, OUTPUT); pinMode(PIN_DATAOUT4, OUTPUT); pinMode(PIN_DATAOUT5, OUTPUT); pinMode(PIN_DATAOUT6, OUTPUT); pinMode(PIN_DATAOUT7, OUTPUT); pinMode(PIN_DATAOUT_OE_n, OUTPUT); digitalWriteFast(PIN_RDWR_n, 0x1); Serial.begin(9600); } // -------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------- // // Begin 6502 Bus Interface Unit // // -------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------- // ------------------------------------------------- // Wait for the CLK1 rising edge and sample signals // ------------------------------------------------- inline void wait_for_CLK_rising_edge() { uint32_t GPIO6_data=0; uint32_t GPIO6_data_d1=0; uint32_t d10, d2, d3, d4, d5, d76; while (((GPIO6_DR >> 12) & 0x1)!=0) {} // Teensy 4.1 Pin-24 GPIO6_DR[12] CLK //while (((GPIO6_DR >> 12) & 0x1)==0) {GPIO6_data=GPIO6_DR;} // This method is ok for VIC-20 and Apple-II+ non-DRAM ranges do { GPIO6_data_d1=GPIO6_DR; } while (((GPIO6_data_d1 >> 12) & 0x1)==0); // This method needed to support Apple-II+ DRAM read data setup time GPIO6_data=GPIO6_data_d1; d10 = (GPIO6_data&0x000C0000) >> 18; // Teensy 4.1 Pin-14 GPIO6_DR[19:18] D1:D0 d2 = (GPIO6_data&0x00800000) >> 21; // Teensy 4.1 Pin-16 GPIO6_DR[23] D2 d3 = (GPIO6_data&0x00400000) >> 19; // Teensy 4.1 Pin-17 GPIO6_DR[22] D3 d4 = (GPIO6_data&0x00020000) >> 13; // Teensy 4.1 Pin-18 GPIO6_DR[17] D4 d5 = (GPIO6_data&0x00010000) >> 11; // Teensy 4.1 Pin-19 GPIO6_DR[16] D5 d76 = (GPIO6_data&0x0C000000) >> 20; // Teensy 4.1 Pin-20 GPIO6_DR[27:26] D7:D6 direct_irq = (GPIO6_data&0x00002000) >> 13; // Teensy 4.1 Pin-25 GPIO6_DR[13] IRQ direct_ready_n = (GPIO6_data&0x40000000) >> 30; // Teensy 4.1 Pin-26 GPIO6_DR[30] READY direct_reset = (GPIO6_data&0x00100000) >> 20; // Teensy 4.1 Pin-40 GPIO6_DR[20] RESET direct_nmi = (GPIO6_data&0x00200000) >> 21; // Teensy 4.1 Pin-41 GPIO6_DR[21] NMI direct_datain = d76 | d5 | d4 | d3 | d2 | d10; return; } // ------------------------------------------------- // Wait for the CLK1 falling edge // ------------------------------------------------- inline void wait_for_CLK_falling_edge() { while (((GPIO6_DR >> 12) & 0x1)==0) {} // Teensy 4.1 Pin-24 GPIO6_DR[12] CLK while (((GPIO6_DR >> 12) & 0x1)!=0) {} return; } // ------------------------------------------------- // Drive the 6502 Address pins // ------------------------------------------------- inline void send_address(uint16_t local_address) { uint32_t writeback_data; writeback_data = (0x6DFFFFF3 & GPIO6_DR); // Read in current GPIOx register value and clear the bits we intend to update GPIO6_DR = writeback_data | (gpio6_addr_array_h[local_address>>8] | gpio6_addr_array_l[local_address&0x00FF]); writeback_data = (0xCFF3EFFF & GPIO7_DR); // Read in current GPIOx register value and clear the bits we intend to update GPIO7_DR = writeback_data | (gpio7_addr_array_h[local_address>>8] | gpio7_addr_array_l[local_address&0x00FF]); writeback_data = (0xFF3BFFFF & GPIO8_DR); // Read in current GPIOx register value and clear the bits we intend to update GPIO8_DR = writeback_data | (gpio8_addr_array_h[local_address>>8] | gpio8_addr_array_l[local_address&0x00FF]); writeback_data = (0x7FFFFF6F & GPIO9_DR); // Read in current GPIOx register value and clear the bits we intend to update GPIO9_DR = writeback_data | (gpio9_addr_array_h[local_address>>8] | gpio9_addr_array_l[local_address&0x00FF]); return; } // ------------------------------------------------- // Send the address for a read cyle // ------------------------------------------------- inline void start_read(uint32_t local_address) { uint32_t gpio7_int; gpio7_int = GPIO7_DR; GPIO7_DR = gpio7_int | 0x00000002; // digitalWriteFast(PIN_RDWR_n, 0x1); send_address(local_address); return; } // ------------------------------------------------- // On the rising CLK edge, read in the data // ------------------------------------------------- inline uint8_t finish_read_byte() { do { wait_for_CLK_rising_edge(); } while (direct_ready_n == 0x1); // Delay a clock cycle until ready is active return direct_datain; } // ------------------------------------------------- // Full read cycle with address and data read in // ------------------------------------------------- inline uint8_t read_byte(uint16_t local_address) { start_read(local_address); do { wait_for_CLK_rising_edge(); } while (direct_ready_n == 0x1); // Delay a clock cycle until ready is active return direct_datain; } // ------------------------------------------------- // Full write cycle with address and data written // ------------------------------------------------- inline void write_byte(uint16_t local_address , uint8_t local_write_data) { uint32_t gpio7_int; uint32_t gpio9_int; gpio7_int = GPIO7_DR; GPIO7_DR = gpio7_int & 0xFFFFFFFD; // digitalWriteFast(PIN_RDWR_n, 0x0); send_address(local_address); // Drive the data bus pins from the Teensy to the bus driver which is inactive // gpio7_int = GPIO7_DR & 0xFFFCF3FA; // Clear destination bits gpio9_int = GPIO9_DR & 0xFFFFFEBF; GPIO7_DR = gpio7_int | Dataout_Array7[local_write_data]; GPIO9_DR = gpio9_int | Dataout_Array9[local_write_data]; // During the second CLK phase, enable the data bus output drivers // wait_for_CLK_falling_edge(); gpio9_int = GPIO9_DR; GPIO9_DR = gpio9_int & 0xFFFFFFDF; // digitalWriteFast(PIN_DATAOUT_OE_n, 0x0 ); wait_for_CLK_rising_edge(); GPIO9_DR = gpio9_int | 0x00000020; // digitalWriteFast(PIN_DATAOUT_OE_n, 0x1 ); GPIO7_DR = gpio7_int | 0x00000002; // digitalWriteFast(PIN_RDWR_n, 0x1); } return; } // -------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------- // // End 6502 Bus Interface Unit // // -------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------- void print_binary(uint8_t num) { // Determine the number of bits in an unsigned int (commonly 32) int i; for (i = 8 - 1; i >= 0; i--) { // Right shift the number by i positions, then mask with 1 // to check the value of the rightmost bit (0 or 1) if ((num >> i) & 1) { printf("1"); } else { printf("0"); } // Optional: add a space every 4 or 8 bits for readability // if (i % 8 == 0) printf(" "); } printf("\n"); } void Data_Check(uint16_t local_address, uint8_t expected_data) { uint8_t data_in; data_in = read_byte(local_address); if (data_in != expected_data) { printf("FAIL: Address: 0x%x expected: 0x%x read: 0x%x\n",local_address,expected_data,data_in); failcount++; failbits = failbits | (data_in ^ expected_data); } return; } void Report_FailBits() { if (failcount != 0) printf("Number of Failures: 0x%lu Failing Bits: 0x%lu \n",failcount,failbits); failcount=0; failbits=0; return; } void test_1() { uint8_t byte_in=0; uint8_t last_byte=0; uint32_t addr=0; uint8_t x=0; uint8_t pattern=0; uint16_t toggle_bit0=0; uint16_t toggle_bit1=0; uint16_t toggle_bit2=0; uint16_t toggle_bit3=0; uint16_t toggle_bit4=0; uint16_t toggle_bit5=0; uint16_t toggle_bit6=0; uint16_t toggle_bit7=0; failcount=0; failbits=0; // DRAM Tests // --------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------- printf("Scan for stuck bits in the RAM space.........."); for (addr=0x0; addr<=0x7FFF; addr++) { write_byte(addr , (random(0x00, 0xFF)) ); } for (addr=0x0; addr<=0x7FFF; addr++) { last_byte = byte_in; byte_in = read_byte(addr); if ( ((last_byte^byte_in)&0x01) == 0x01) toggle_bit0++; if ( ((last_byte^byte_in)&0x02) == 0x02) toggle_bit1++; if ( ((last_byte^byte_in)&0x04) == 0x04) toggle_bit2++; if ( ((last_byte^byte_in)&0x08) == 0x08) toggle_bit3++; if ( ((last_byte^byte_in)&0x10) == 0x10) toggle_bit4++; if ( ((last_byte^byte_in)&0x20) == 0x20) toggle_bit5++; if ( ((last_byte^byte_in)&0x40) == 0x40) toggle_bit6++; if ( ((last_byte^byte_in)&0x80) == 0x80) toggle_bit7++; } if ((toggle_bit0<11) | (toggle_bit1<11) | (toggle_bit2<11) | (toggle_bit3<11) | (toggle_bit4<11) | (toggle_bit5<11) | (toggle_bit6<11) | (toggle_bit7<11) ) { printf("Possible stuck bits. Actual bit transitions: B7:%x B5:%x B5:%x B4:%x B3:%x B2:%x B1:%x B0:%x \n",toggle_bit7,toggle_bit6,toggle_bit5,toggle_bit4,toggle_bit3,toggle_bit2,toggle_bit1,toggle_bit0); } else printf("No stuck bits.\n"); printf("Pattern #1: Address as data...\n"); pattern = addr; for (addr=0x0; addr<=0x7FFF; addr++) { write_byte(addr , pattern); DRAM_Pattern_Array[addr]=pattern; } for (addr=0x0; addr<=0x7FFF; addr++) { Data_Check(addr, DRAM_Pattern_Array[addr]); } //Report_FailBits(); printf("Pattern #2: All 0x00..........\n"); pattern = 0x00; for (addr=0x0; addr<=0x7FFF; addr++) { write_byte(addr , pattern); DRAM_Pattern_Array[addr]=pattern; } for (addr=0x0; addr<=0x7FFF; addr++) { Data_Check(addr, DRAM_Pattern_Array[addr]); } //Report_FailBits(); printf("Pattern #3: All 0xFF..........\n"); pattern = 0x00; for (addr=0x0; addr<=0x7FFF; addr++) { write_byte(addr , pattern); DRAM_Pattern_Array[addr]=pattern; } for (addr=0x0; addr<=0x7FFF; addr++) { Data_Check(addr, DRAM_Pattern_Array[addr]); } //Report_FailBits(); printf("Pattern #4: Walking 1's.......\n"); pattern = 0x01; for (x=0; x<8; x++) { //printf("Pattern: "); print_binary(pattern); for (addr=0x0; addr<=0x7FFF; addr++) { write_byte(addr , pattern); DRAM_Pattern_Array[addr]=pattern; } for (addr=0x0; addr<=0x7FFF; addr++) { Data_Check(addr, DRAM_Pattern_Array[addr]); } pattern=pattern<<1; } //Report_FailBits(); printf("Pattern #5: Walking 0's.......\n"); pattern = 0xFE; for (x=0; x<8; x++) { //printf("Pattern: "); print_binary(pattern); for (addr=0x0; addr<=0x7FFF; addr++) { write_byte(addr , pattern); DRAM_Pattern_Array[addr]=pattern; } for (addr=0x0; addr<=0x7FFF; addr++) { Data_Check(addr, DRAM_Pattern_Array[addr]); } pattern=pattern<<1; } printf("Pattern #6: Random data.......\n"); for (addr=0x0; addr<=0x7FFF; addr++) { pattern = (random(0x00, 0xFF)); write_byte(addr , pattern ); DRAM_Pattern_Array[addr]=pattern; } for (addr=0x0; addr<=0x7FFF; addr++) { Data_Check(addr, DRAM_Pattern_Array[addr]); } Report_FailBits(); return; } void test_2() { uint8_t byte_in=0; uint8_t last_byte=0; uint32_t addr=0; uint16_t checksum=0; uint16_t toggle_bit0=0; uint16_t toggle_bit1=0; uint16_t toggle_bit2=0; uint16_t toggle_bit3=0; uint16_t toggle_bit4=0; uint16_t toggle_bit5=0; uint16_t toggle_bit6=0; uint16_t toggle_bit7=0; // ROM Tests // --------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------- printf("Generating 16-bit Checksums for ROMs..........\n"); checksum=0; for (addr=0xB000; addr<=0xBFFF; addr++) { checksum=checksum+read_byte(addr); } printf("0xB000 Checksum: %x\n",checksum); checksum=0; for (addr=0xC000; addr<=0xCFFF; addr++) { checksum=checksum+read_byte(addr); } printf("0xC000 Checksum: %x\n",checksum); checksum=0; for (addr=0xD000; addr<=0xDFFF; addr++) { checksum=checksum+read_byte(addr); } printf("0xD000 Checksum: %x\n",checksum); checksum=0; for (addr=0xF000; addr<=0xFFFF; addr++) { checksum=checksum+read_byte(addr); } printf("0xF000 Checksum: %x\n",checksum); printf("\n\n"); printf("Scan for stuck bits in the ROM space.........."); for (addr=0xB000; addr<=0xFFFF; addr++) { last_byte = byte_in; byte_in = read_byte(addr); if ( ((last_byte^byte_in)&0x01) == 0x01) toggle_bit0++; if ( ((last_byte^byte_in)&0x02) == 0x02) toggle_bit1++; if ( ((last_byte^byte_in)&0x04) == 0x04) toggle_bit2++; if ( ((last_byte^byte_in)&0x08) == 0x08) toggle_bit3++; if ( ((last_byte^byte_in)&0x10) == 0x10) toggle_bit4++; if ( ((last_byte^byte_in)&0x20) == 0x20) toggle_bit5++; if ( ((last_byte^byte_in)&0x40) == 0x40) toggle_bit6++; if ( ((last_byte^byte_in)&0x80) == 0x80) toggle_bit7++; } if ((toggle_bit0<11) | (toggle_bit1<11) | (toggle_bit2<11) | (toggle_bit3<11) | (toggle_bit4<11) | (toggle_bit5<11) | (toggle_bit6<11) | (toggle_bit7<11) ) { printf("Possible stuck bits. Actual bit transitions: B7:%x B5:%x B5:%x B4:%x B3:%x B2:%x B1:%x B0:%x \n",toggle_bit7,toggle_bit6,toggle_bit5,toggle_bit4,toggle_bit3,toggle_bit2,toggle_bit1,toggle_bit0); } else printf("No stuck bits.\n"); return; } void test_3() { uint32_t addr=0; printf("Dumping the ROMs..........\n\n"); printf("0xB000: \n"); for (addr=0xB000; addr<=0xBFFF; addr++) { printf("0x%x,",read_byte(addr)); } printf("\n\n"); printf("0xC000: \n"); for (addr=0xc000; addr<=0xCFFF; addr++) { printf("0x%x,",read_byte(addr)); } printf("\n\n"); printf("0xD000: \n"); for (addr=0xd000; addr<=0xDFFF; addr++) { printf("0x%x,",read_byte(addr)); } printf("\n\n"); printf("0xF000: \n"); for (addr=0xf000; addr<=0xEFFF; addr++) { printf("0x%x,",read_byte(addr)); } printf("\n\n"); return; } void test_4() { printf("Toggling all 6502 output signals. POWER CYCLE TO RESET\n"); while(1) { digitalWriteFast(PIN_RDWR_n, 0x1); digitalWriteFast(PIN_SYNC, 0x1); digitalWriteFast(PIN_ADDR0, 0x1); digitalWriteFast(PIN_ADDR1, 0x1); digitalWriteFast(PIN_ADDR2, 0x1); digitalWriteFast(PIN_ADDR3, 0x1); digitalWriteFast(PIN_ADDR4, 0x1); digitalWriteFast(PIN_ADDR5, 0x1); digitalWriteFast(PIN_ADDR6, 0x1); digitalWriteFast(PIN_ADDR7, 0x1); digitalWriteFast(PIN_ADDR8, 0x1); digitalWriteFast(PIN_ADDR9, 0x1); digitalWriteFast(PIN_ADDR10, 0x1); digitalWriteFast(PIN_ADDR11, 0x1); digitalWriteFast(PIN_ADDR12, 0x1); digitalWriteFast(PIN_ADDR13, 0x1); digitalWriteFast(PIN_ADDR14, 0x1); digitalWriteFast(PIN_ADDR15, 0x1); digitalWriteFast(PIN_DATAOUT0, 0x1); digitalWriteFast(PIN_DATAOUT1, 0x1); digitalWriteFast(PIN_DATAOUT2, 0x1); digitalWriteFast(PIN_DATAOUT3, 0x1); digitalWriteFast(PIN_DATAOUT4, 0x1); digitalWriteFast(PIN_DATAOUT5, 0x1); digitalWriteFast(PIN_DATAOUT6, 0x1); digitalWriteFast(PIN_DATAOUT7, 0x1); digitalWriteFast(PIN_DATAOUT_OE_n, 0x1); delay (100); digitalWriteFast(PIN_RDWR_n, 0x0); digitalWriteFast(PIN_SYNC, 0x0); digitalWriteFast(PIN_ADDR0, 0x0); digitalWriteFast(PIN_ADDR1, 0x0); digitalWriteFast(PIN_ADDR2, 0x0); digitalWriteFast(PIN_ADDR3, 0x0); digitalWriteFast(PIN_ADDR4, 0x0); digitalWriteFast(PIN_ADDR5, 0x0); digitalWriteFast(PIN_ADDR6, 0x0); digitalWriteFast(PIN_ADDR7, 0x0); digitalWriteFast(PIN_ADDR8, 0x0); digitalWriteFast(PIN_ADDR9, 0x0); digitalWriteFast(PIN_ADDR10, 0x0); digitalWriteFast(PIN_ADDR11, 0x0); digitalWriteFast(PIN_ADDR12, 0x0); digitalWriteFast(PIN_ADDR13, 0x0); digitalWriteFast(PIN_ADDR14, 0x0); digitalWriteFast(PIN_ADDR15, 0x0); digitalWriteFast(PIN_DATAOUT0, 0x0); digitalWriteFast(PIN_DATAOUT1, 0x0); digitalWriteFast(PIN_DATAOUT2, 0x0); digitalWriteFast(PIN_DATAOUT3, 0x0); digitalWriteFast(PIN_DATAOUT4, 0x0); digitalWriteFast(PIN_DATAOUT5, 0x0); digitalWriteFast(PIN_DATAOUT6, 0x0); digitalWriteFast(PIN_DATAOUT7, 0x0); digitalWriteFast(PIN_DATAOUT_OE_n, 0x0); delay (100); } return; } void test_5() { uint16_t address_to_peek=0x0123; printf("PEEK from address: 0x%x DATA=0x%x \n",address_to_peek, read_byte(address_to_peek)); return; } void test_6() { uint16_t address_to_poke=0x0123; uint8_t data_to_poke=0x5A; printf("POKEing DATA=0x%x to Address: 0x%x \n",data_to_poke, address_to_poke); write_byte(address_to_poke, data_to_poke); return; } void test_7() { uint8_t signal_in=0; uint8_t signal_in_d=0; uint16_t signal_toggle=0; printf("6502 receiving a CLK........"); for (uint16_t x=0; x<=0x3FFF; x++) { signal_in_d = signal_in; signal_in = digitalReadFast(PIN_CLK0); if (signal_in != signal_in_d) signal_toggle++; } if (signal_toggle > 100) printf ("YES\n"); else printf ("NO\n"); printf("6502 RESET level ..........."); if (digitalRead(PIN_RESET) != 0) printf ("LOW\n"); else printf ("HIGH\n"); printf("6502 IRQ_n level............"); if (digitalRead(PIN_IRQ) != 0) printf ("LOW\n"); else printf ("HIGH\n"); printf("6502 NMI_n level............"); if (digitalRead(PIN_NMI) != 0) printf ("LOW\n"); else printf ("HIGH\n"); return; } void test_8() { uint32_t addr=0; printf("Filling PET screen with random letters..........\n"); for (addr=0x8000; addr<=0x8FFF; addr++) { write_byte(addr , (random(0x41,0x5A))); } delay(1000); for (addr=0x8000; addr<=0x8FFF; addr++) { write_byte(addr , (random(0x41,0x5A))); } delay(1000); for (addr=0x8000; addr<=0x8FFF; addr++) { write_byte(addr , (random(0x41,0x5A))); } delay(1000); return; } void test_9() { write_byte(0xE811 , 0xAA); // PIA-1 Control-A Register write_byte(0xE813 , 0x55); // PIA-1 Control-B Register if ( read_byte(0xE811) == 0xAA) printf("PIA-1 Control-A Register PASS\n"); else printf("PIA-1 Control-A Register FAIL %x\n",read_byte(0xE811)); if ( read_byte(0xE813) == 0x55) printf("PIA-1 Control-B Register PASS\n"); else printf("PIA-1 Control-B Register FAIL %x\n",read_byte(0xE813)); write_byte(0xE821 , 0x99); // PIA-1 Control-A Register write_byte(0xE823 , 0x66); // PIA-1 Control-B Register if ( read_byte(0xE821) == 0x99) printf("PIA-1 Control-A Register PASS\n"); else printf("PIA-1 Control-A Register FAIL %x\n",read_byte(0xE821)); if ( read_byte(0xE823) == 0x66) printf("PIA-1 Control-B Register PASS\n"); else printf("PIA-1 Control-B Register FAIL %x\n",read_byte(0xE823)); write_byte(0xE840 , 0x5A); // VIA Port-B Control Register if ( read_byte(0xE840) == 0x5A) printf("VIA Port-B Control RegisterPASS\n"); else printf("VIA Port-B Control Register FAIL %x\n",read_byte(0xE840)); return; } // ------------------------------------------------- // // Main loop // // ------------------------------------------------- void loop() { // Give Teensy 4.1 a moment delay (2000); wait_for_CLK_rising_edge(); wait_for_CLK_rising_edge(); wait_for_CLK_rising_edge(); while (1) { printf("\n"); printf("\n"); printf("MicroCore Labs\n"); printf("MCL65_PETDoctor\n"); printf("Commodore PET Board Tester\n"); printf("----------------------------------------------\n"); printf("\n"); printf("Tests Menu\n"); printf("----------\n"); printf("1) Test DRAM\n"); printf("2) Test ROMs\n"); printf("3) Dump ROMs\n"); printf("4) Toggle all 6502 output signals\n"); printf("5) PEEK\n"); printf("6) POKE\n"); printf("7) 6502 Clock, Reset, and Interrupts\n"); printf("8) Video\n"); printf("9) PIA and VIA Registers\n"); printf("\n"); while (Serial.available()==0 ) { } incomingByte = Serial.read(); switch (incomingByte){ case 49: test_1(); break; case 50: test_2(); break; case 51: test_3(); break; case 52: test_4(); break; case 53: test_5(); break; case 54: test_6(); break; case 55: test_7(); break; case 56: test_8(); break; case 57: test_9(); break; } // Remove extra characters incomingByte = Serial.read(); incomingByte = Serial.read(); delay(100); } }