diff --git a/MCL65+_PET/MCL65_PETDoctor.ino b/MCL65+_PET/MCL65_PETDoctor.ino new file mode 100644 index 0000000..d5d1460 --- /dev/null +++ b/MCL65+_PET/MCL65_PETDoctor.ino @@ -0,0 +1,761 @@ +// +// +// 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); + + } + } +