From 87dbbbc14e6bc9ecc4b15cd6265a8e1d1a39cb45 Mon Sep 17 00:00:00 2001 From: antoniovillena Date: Sun, 2 Oct 2016 12:18:55 +0200 Subject: [PATCH] Actualizo core Spectrum --- cores/AcornElectron/working/ElectronFpga.ut | 5 +- cores/AcornElectron/working/ElectronFpga.xst | 2 +- cores/Atari2600/zxuno/A2601_zxuno_Ap.ucf | 4 +- cores/Atari2600/zxuno/A2601_zxuno_v2.ucf | 8 +- cores/Atari2600/zxuno/A2601_zxuno_v3.ucf | 8 +- cores/Atari2600/zxuno/A2601_zxuno_v4.ucf | 4 +- cores/BBCMicro/working/make.bat | 3 +- cores/Spectrum/bootloader_hex.txt | 1529 ++++++------ cores/Spectrum/coreid.v | 8 +- cores/Spectrum/cuatro_relojes.v | 61 +- cores/Spectrum/new_memory.v | 16 +- cores/Spectrum/pal_sync_generator.v | 174 +- cores/Spectrum/pll_drp.v | 134 +- cores/Spectrum/pll_top.v | 14 +- cores/Spectrum/scancode_to_speccy.v | 2 +- cores/Spectrum/scandoubler_ctrl.v | 6 +- cores/Spectrum/tld_zxuno.v | 4 +- cores/Spectrum/ula_radas.v | 93 +- cores/Spectrum/vga_scandoubler.v | 3 +- cores/Spectrum/zxuno.v | 12 +- cores/VIC20/ise/VIC20.prj | 10 +- cores/VIC20/ise/VIC20.ut | 3 +- cores/VIC20/ise/VIC20.xst | 1 + cores/VIC20/readme.txt | 7 +- cores/VIC20/source/T65.vhd | 990 ++++---- cores/VIC20/source/T65_ALU.vhd | 395 +-- cores/VIC20/source/T65_MCode.vhd | 2127 +++++++++-------- cores/VIC20/source/T65_Pack.vhd | 195 +- cores/VIC20/source/m6522.vhd | 146 +- cores/VIC20/source/roms/kernal.bin | Bin 8192 -> 8192 bytes cores/VIC20/source/roms/vic20_kernal.vhd | 30 +- cores/VIC20/source/vic20.vhd | 403 ++-- cores/VIC20/source/vic20_dblscan.vhd | 6 +- cores/VIC20/source/vic20_ps2_if.vhd | 62 +- cores/VIC20/source/vic20_vic.vhd | 126 +- cores/VIC20/source/vic20_zxuno_Ap.ucf | 17 +- cores/VIC20/source/vic20_zxuno_v2_v3.ucf | 17 +- cores/VIC20/source/vic20_zxuno_v4.ucf | 17 +- cores/curso/cap1/colenc.vhd | 18 +- cores/curso/cap1/main.vhd | 7 +- firmware/generaflash.bat | 4 + ...eramcs_multi.bat => generaflash_multi.bat} | 90 +- firmware/generamcs.bat | 4 - 43 files changed, 3726 insertions(+), 3039 deletions(-) create mode 100644 firmware/generaflash.bat rename firmware/{generamcs_multi.bat => generaflash_multi.bat} (53%) delete mode 100644 firmware/generamcs.bat diff --git a/cores/AcornElectron/working/ElectronFpga.ut b/cores/AcornElectron/working/ElectronFpga.ut index fb52ea8..d1824d0 100644 --- a/cores/AcornElectron/working/ElectronFpga.ut +++ b/cores/AcornElectron/working/ElectronFpga.ut @@ -1,6 +1,6 @@ -w +-g DebugBitstream:No -g Binary:no --g Compress -g CRC:Enable -g Reset_on_err:No -g ConfigRate:2 @@ -11,8 +11,7 @@ -g TmsPin:PullUp -g UnusedPin:PullDown -g UserID:0xFFFFFFFF --g ExtMasterCclk_en:Yes --g ExtMasterCclk_divide:50 +-g ExtMasterCclk_en:No -g SPI_buswidth:1 -g TIMER_CFG:0xFFFF -g multipin_wakeup:No diff --git a/cores/AcornElectron/working/ElectronFpga.xst b/cores/AcornElectron/working/ElectronFpga.xst index 0f65ef0..364b805 100644 --- a/cores/AcornElectron/working/ElectronFpga.xst +++ b/cores/AcornElectron/working/ElectronFpga.xst @@ -1,4 +1,4 @@ -set -tmpdir "projnav.tmp" +set -tmpdir "xst/projnav.tmp" set -xsthdpdir "xst" run -ifn ElectronFpga.prj diff --git a/cores/Atari2600/zxuno/A2601_zxuno_Ap.ucf b/cores/Atari2600/zxuno/A2601_zxuno_Ap.ucf index 8cc2583..b1dc715 100644 --- a/cores/Atari2600/zxuno/A2601_zxuno_Ap.ucf +++ b/cores/Atari2600/zxuno/A2601_zxuno_Ap.ucf @@ -81,8 +81,8 @@ NET "P_U" LOC="P74" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_D" LOC="P67" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_L" LOC="P59" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_R" LOC="P58" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_tr" LOC="P75" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_A" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_A" LOC="P75" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_tr" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire3" LOC="P39" | IOSTANDARD = LVCMOS33 | PULLUP; diff --git a/cores/Atari2600/zxuno/A2601_zxuno_v2.ucf b/cores/Atari2600/zxuno/A2601_zxuno_v2.ucf index bfd1d27..e7befe0 100644 --- a/cores/Atari2600/zxuno/A2601_zxuno_v2.ucf +++ b/cores/Atari2600/zxuno/A2601_zxuno_v2.ucf @@ -14,8 +14,8 @@ NET "VGA_B[1]" LOC="P80" | IOSTANDARD = LVCMOS33; NET "VGA_B[0]" LOC="P79" | IOSTANDARD = LVCMOS33; NET "VGA_HS" LOC="P87" | IOSTANDARD = LVCMOS33; NET "VGA_VS" LOC="P85" | IOSTANDARD = LVCMOS33; -NET "NTSC" LOC="P67" | IOSTANDARD = LVCMOS33; -NET "PAL" LOC="P66" | IOSTANDARD = LVCMOS33; +NET "NTSC" LOC="P66" | IOSTANDARD = LVCMOS33; +NET "PAL" LOC="P67" | IOSTANDARD = LVCMOS33; # Sound input/output NET "AUDIO_L" LOC="P8" | IOSTANDARD = LVCMOS33; @@ -81,8 +81,8 @@ NET "P_U" LOC="P142" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_D" LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_L" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_R" LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_tr" LOC="P143" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_A" LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_A" LOC="P143" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_tr" LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire3" LOC="P7" | IOSTANDARD = LVCMOS33 | PULLUP; diff --git a/cores/Atari2600/zxuno/A2601_zxuno_v3.ucf b/cores/Atari2600/zxuno/A2601_zxuno_v3.ucf index 9c9a0b0..7ff3456 100644 --- a/cores/Atari2600/zxuno/A2601_zxuno_v3.ucf +++ b/cores/Atari2600/zxuno/A2601_zxuno_v3.ucf @@ -14,8 +14,8 @@ NET "VGA_B[1]" LOC="P80" | IOSTANDARD = LVCMOS33; NET "VGA_B[0]" LOC="P79" | IOSTANDARD = LVCMOS33; NET "VGA_HS" LOC="P87" | IOSTANDARD = LVCMOS33; NET "VGA_VS" LOC="P85" | IOSTANDARD = LVCMOS33; -NET "NTSC" LOC="P67" | IOSTANDARD = LVCMOS33; -NET "PAL" LOC="P66" | IOSTANDARD = LVCMOS33; +NET "NTSC" LOC="P66" | IOSTANDARD = LVCMOS33; +NET "PAL" LOC="P67" | IOSTANDARD = LVCMOS33; # Sound input/output NET "AUDIO_L" LOC="P8" | IOSTANDARD = LVCMOS33; @@ -81,8 +81,8 @@ NET "P_U" LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_D" LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_L" LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_R" LOC="P7" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_tr" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_A" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_A" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_tr" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire3" LOC="P39" | IOSTANDARD = LVCMOS33 | PULLUP; diff --git a/cores/Atari2600/zxuno/A2601_zxuno_v4.ucf b/cores/Atari2600/zxuno/A2601_zxuno_v4.ucf index 2de562c..90bc059 100644 --- a/cores/Atari2600/zxuno/A2601_zxuno_v4.ucf +++ b/cores/Atari2600/zxuno/A2601_zxuno_v4.ucf @@ -81,8 +81,8 @@ NET "P_U" LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_D" LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_L" LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; NET "P_R" LOC="P7" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_tr" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; -NET "P_A" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_A" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; +NET "P_tr" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire3" LOC="P39" | IOSTANDARD = LVCMOS33 | PULLUP; diff --git a/cores/BBCMicro/working/make.bat b/cores/BBCMicro/working/make.bat index 92640a3..289ba64 100644 --- a/cores/BBCMicro/working/make.bat +++ b/cores/BBCMicro/working/make.bat @@ -3,6 +3,7 @@ SET speed=2 SET ruta_ucf=..\src\bbc_micro SET ruta_bat=..\..\ call %ruta_bat%genxst.bat -rem call %ruta_bat%generar.bat v2_v3 +rem call %ruta_bat%generar.bat v2 +rem call %ruta_bat%generar.bat v3 call %ruta_bat%generar.bat v4 rem call %ruta_bat%generar.bat Ap diff --git a/cores/Spectrum/bootloader_hex.txt b/cores/Spectrum/bootloader_hex.txt index b5895fd..fb4672c 100644 --- a/cores/Spectrum/bootloader_hex.txt +++ b/cores/Spectrum/bootloader_hex.txt @@ -261,7 +261,7 @@ C9 84 B6 21 -CC +BD 1F 01 00 @@ -333,1841 +333,1842 @@ E4 2B 8F C9 -80 -55 +AC +AA 45 -55 1D 57 65 -03 +1A A2 +78 CC -4F 02 7F -3E +F2 D7 15 +E1 6B 20 -3C 2D +79 AE -CF 62 +46 B4 -28 4A 0B +F9 45 12 -5F 64 76 61 +92 53 79 -32 36 -5B +D9 81 6A -69 +4A E5 08 +F3 72 -5E 7F +1A 8C -E3 0D -69 +4F AB 21 61 -0F +7B B9 +70 D0 -AE +65 B3 -8C +2C F1 -C5 +FE EF -3F 6C +A9 D2 -55 36 33 -82 +12 8C +3C EB -47 -EC -D2 -95 -09 -F0 -B2 -4A -69 -0A -68 -62 92 -C5 +EC +95 +86 +09 +57 +B2 +69 +42 +0A +62 +2B +92 B9 +86 37 30 -30 68 -CB +59 9A 74 -9B +DE 11 -8B +5C 49 62 +64 FC -CC 1D -6E +76 E5 -8D +6B 8F -61 +0C AB -A5 +2B 1D 77 -09 +4D DA +98 6F -D3 E6 30 +7E 39 1E -4F -98 +C2 D3 -8B +5C 86 -8B +5C 53 72 3F 50 -20 +04 EC -09 +49 F8 79 26 +D8 66 -5B 2F 1C 4C -2F +7A D1 62 -36 +B1 B9 -0B +59 E7 3A 74 +78 68 0F -CF C2 -12 +96 +30 30 12 -E6 D6 -9B +DF 67 -09 +4C BF 49 6E +78 68 0D -CF 34 +C6 77 -38 E5 +C1 70 61 -F8 08 +BF 64 79 52 -17 43 4D 16 -0C +60 0E +30 7F -A6 A1 +DD 52 -5B CA +8A 7B 11 -B1 +A5 F7 -D4 -35 +AE 9D 37 -5F +F9 FA 7D 27 -B7 +BA 6E +75 AC 69 -6E D8 +C3 15 -F8 6B +57 8B -8A 6F +6C 8F -CD 14 1C +DE 75 -BB D4 -49 +4D C1 -DD +EA B1 -D8 +C6 E4 -0C +66 06 +38 B9 -87 53 47 -3F +FC 3F 5F 7D -DF +F9 AF -33 +9E FF +B9 41 0B -D7 B1 -91 +8E 27 41 +4C 75 -09 ED -3C +E0 93 -99 +C9 84 +1C 42 43 -23 48 09 -92 +91 ED 63 1C +BC 70 73 -37 0B 03 +C9 3E 6B -39 47 -59 +C9 A3 0F +7A 65 4E -AF +9D EE -73 6C 66 33 +CB 74 -39 42 +29 DD -45 1C -DE +F2 FB 10 -1B +DE 12 -8E +70 DD -8B +5C B8 5C +5C 0A -6B 0C +7B D8 -EF +27 84 -E4 38 +BF 7C -17 95 -A6 +30 91 -86 +35 1B +9C 82 -D3 7E 70 +06 81 -C0 1D 6E -BE +F6 E7 -B4 +A5 F3 +BD 16 -77 68 60 -CA +53 A6 +D6 79 -1A AF -E4 +20 94 -BC +E7 B3 -09 +4D D1 +F8 84 -7F +43 43 6B -48 B7 2E +EA 72 32 -BD 6D 6D +2D 11 -65 64 08 -85 +2B 24 74 27 -BF +FC 5F +7D DB -4F +32 C0 -C6 C4 -71 +8E EE -24 +23 F4 -AC +61 B1 -1E +F5 BF -39 +C8 F7 6C 63 +D9 70 08 -DB 64 +A6 D9 -74 39 39 17 -09 +4B +E0 F8 -9C 61 -34 +A4 AD 69 6D -8F +79 CE +34 B5 -86 35 0C -5F +FC +2A C9 5E -65 45 19 -AF +7B 43 +95 A0 -72 +4B 88 -E9 D4 +D7 79 -5A 74 7D +F2 DB -FE 15 -4C +67 D1 -DA +D2 96 -58 +C6 +8A A3 -71 09 -FD +EB CF +9F 77 16 -F3 0E -47 +3F F5 -DC +E2 A5 -5A +D6 F7 +32 8F -E6 +E7 B3 -DC +6E C9 -AD 0B +ED 6F 04 -DD 73 4B +A6 A4 -F4 E4 -B6 +B7 D9 -B2 +95 C8 -24 +25 CD 0F -3C -A8 +E1 +41 A2 +3D D2 -47 +72 72 64 75 -2E F1 -B6 +B1 9B +C5 7B 5C -38 A4 -30 +81 9B +79 18 -EF D4 -94 +A7 0E 65 +5C 63 02 -CB EE -F2 +96 A4 +77 73 09 -AE -31 +8D CF +F1 BB -9E 08 +3C 9F -87 15 +3C B3 -C7 14 -5D +EE +3A 86 -E7 DC -7A +D7 B3 +33 93 -86 48 36 38 +3C 0D -27 6D +69 F8 -CD +96 80 -D2 08 -98 +C6 9A -30 +84 BE +21 6F 0C -A4 2D -1D +ED AD -52 +90 C2 1B +F2 45 -5E 72 77 06 6D -3C +E2 9F 18 -BC +E1 EB +35 7D -66 45 73 -D2 +93 AA +5E 8D -6B 0C -B8 +C3 94 +B5 09 -76 22 36 +73 34 65 -4E +12 DF -C2 04 66 +9E AD -93 +0C C3 0B -E1 +8F 0F -71 F2 +CB 1B -D9 -3D 3D +EE 89 +31 82 -86 3F -15 +AC B9 -2B +58 B0 +21 6C 1E -A4 -71 +8D F7 -32 +93 CE +B1 D8 -B6 6D 42 +A5 13 -F4 0D 7C -4B +5F E7 +F2 CC -BE +DD E3 -FB 86 +5F 64 -CB +AE 9E -95 +64 8E -CC +E6 B8 -9C +6C B3 -CD 7F 7A 7B +CE 09 -39 +D9 8F -7B +2B 87 -65 9C +5B 66 -4B 6C +62 C7 -EC DD +DF 0F -7B +A3 A5 -B4 73 -05 +2D B7 +38 9B -C7 11 -8B +5E 9B -98 +C4 1D -26 +34 44 +41 7D 65 -C8 A1 -B2 +96 07 17 -2F 7D -AE +7D +71 4E 78 67 -DE +F5 D6 -59 +CE 97 -78 +C2 C1 +33 B6 -A6 +AD A7 -B5 +A5 08 46 -74 7B 64 +5B EE -CB +86 67 1C -D0 50 +3E D9 -C7 12 55 +5E 69 0D -CB 63 +D6 B8 -9A +24 C2 -C4 +8E 06 -31 +39 87 -67 0C +9B 61 7A 70 -13 89 -BA +D0 92 +95 18 -F2 6C 6F +77 76 -CE D6 -0E +76 D5 +F8 B3 -FF 19 09 -AF +7F FB -8F +7D 84 64 -99 +CC C1 -BC +E4 B5 04 +E5 3B -FC D4 -30 -83 -D2 -2A -E0 -0F -66 -9C -8E -E3 -B2 -98 -7A -48 -8F -8A -2A -C2 87 +91 +83 +06 +2A +0F +37 +9C +73 +E3 +94 +D5 +98 +48 +53 +8F +2A +3C +C2 47 6C +8C 8E -B1 0D +65 48 -4C A1 -9C +E2 E4 -96 +B4 89 -9D +EC ED -B7 +BC 68 79 7C 64 -9C +E5 B8 -99 +CC 69 33 +B4 67 5A -D6 81 -F2 +96 CC +7F 49 -2F A0 +C9 6B -59 CA +22 1A -E4 F8 -9C +E7 A8 -13 +9C 49 4D 44 +10 3F 09 -C2 EE +96 0E 72 -72 +13 90 -C2 +E6 D0 -9C 3B 53 -97 +BC C5 11 +CC 49 76 -39 85 -73 +99 A9 -84 +23 A7 +CC 74 78 -39 C0 -95 +A9 09 3B -F9 +CC BB -24 +27 EA 14 -9E +F1 67 48 +34 E3 -A6 +0D 9C -61 47 +2B B9 -45 +52 B9 -CA FC -BC +E6 08 07 -0F +7D E7 +D8 AD -DB 6A 6D 67 -E2 +16 9E -33 +9F E3 +11 4D -42 56 04 +92 53 4A 0E -92 -95 +AC 8E +B4 1E 75 -76 0F -2B +5B B4 +61 69 7E -AC 28 -03 +1D +A8 9E -75 69 27 19 -9D +EB +F4 C3 -DE 6B -4E +76 94 +0A 6C -21 C7 +D1 6B -DA C2 +3E 13 -E7 -E0 +07 A1 -0E +77 E0 6F -A7 +38 A6 -25 +2D AB 61 +61 4C -AC +1D D6 -E3 C0 -48 +47 35 -6B -D3 9A -DC +6B +9A +E6 C5 73 05 +DE 43 -DB 0D +BE 66 66 -97 D2 -D9 +CC A3 +66 74 -4C 08 +5A 4D 17 -AB 73 7F +2D 49 -25 +09 8B -61 84 -19 +CB B7 -12 +90 C6 -F2 +90 8B +97 6A -12 A2 -EC +60 FD +67 6F 0B -AC +85 65 -50 96 -AC +62 E9 +2D 14 -E5 -0A +57 BA +78 AE -CF D2 +DE 5B -FB 35 9F -53 +9F 13 -AE +72 4D 03 +75 D8 -AE +A5 FD -94 +AC 0C 5B -F5 69 20 +CF C7 -B9 73 26 -95 +AD 13 +74 44 -EE +57 C7 -6A +13 9C -C2 43 -23 +1E A3 -A4 +21 A5 -93 +9D 7A +14 CA 1B -E2 -D0 +87 A6 +D6 5C -5A 61 +42 8A -68 CC +63 75 -CC 5C 14 -0F +7E 7C 20 +88 F3 -91 +A4 43 -94 A2 -A5 +2C D1 +35 0D -66 4D +53 7B 72 -0A 84 -1C +E0 0E +98 65 -13 DF -2E +70 CF -AC +61 D4 -5B +DD DF 73 +4A 3C -69 -D1 -ED +6B +BC +AF 4C 3F -95 96 +44 6D -48 CA 92 12 +5C 43 -AB F5 +DD 2D 7B -FB +0F 91 -61 C3 +5B 10 -CB +A6 46 -14 F4 +28 54 28 -A5 +0D D2 -21 1B -53 +99 DF -08 +42 46 +88 A8 -51 +12 58 -A2 C0 +CD 4C 0D -D9 40 +C6 6A -F8 DE -9A +D7 61 07 -C6 +34 E4 +C6 0B -78 7A -1C +E3 93 5B +F0 0D -7E +1B CD -23 +99 CA -73 59 -BC -D5 -0F -E3 -E6 -0C -C9 -0B -9C AB -D7 +BC +0F +1E +E6 +67 +C9 +58 +9C +B8 +AB 0D -81 +0E 27 65 +9C 98 -93 0D -97 +BC C3 +F4 FC -9E -98 -E4 +24 +83 +E7 80 -DC 4A 75 -45 +2E 92 7C +F2 04 -3E +09 89 0B -E1 6C 16 -95 +AF 61 +A4 81 -74 0B +BB 58 36 -77 37 3E 4E 4C 0D -90 +83 DD +84 04 -F0 -A2 -9C +8D +E7 54 64 09 +FC 4B 67 -3F CB -BA +D1 98 +65 06 -EC +37 C9 -C6 45 -1B +DE A5 +38 AF -C7 91 +8E 1C -F1 13 +5F C5 -CB 1E +9E E9 -D3 E2 -B4 +A6 11 -19 +CD 89 66 -7F +F8 A2 22 +CB 77 44 -B9 56 5A +25 1C -24 41 6C -A5 +29 B5 -C6 -C9 +35 +B4 +EE 0F -7D BD -4B +5B E9 -4B +5A AE +C2 09 12 -F8 +A7 06 -74 DD +D3 17 -DA +0E E1 6B -61 18 +5B 49 3F -2B FC +81 6D -F0 3B 27 -F9 +CF E8 +27 6E -A4 90 +CD 79 0A -D9 -28 -99 -0A -E9 -AE -F8 -DA -E5 -D1 -09 -EC -ED -0A -70 -F0 46 +99 +49 +0A +AE +C7 +DA +2F +D1 +67 +09 +ED +87 +0A +33 +F0 4C 75 63 -62 +12 A4 +93 61 62 -92 E9 -DB +DC F3 +4E 7D -49 05 +1A EB -43 6A 0D -0A +52 48 18 +A0 52 -F4 61 0D -8F +7F AF -90 +84 F2 -B8 +C4 14 -83 +1D 4E 2C 0B +F4 6A -9E -8E +F9 +32 65 0D -A6 1E +BD 6E 6B -57 27 +72 44 -EE 20 +07 BA -60 B7 -FB +DB B1 +37 AD -A6 29 +9D 61 -93 D2 -5D +EC B6 08 -87 +3A 63 +14 85 57 -62 0E 61 -09 +4B B9 24 +F0 62 61 -7E 3C 5F -8F +7B FD -8B +5C 6D 2D -CE -AE -78 -EB -E1 74 +CE +78 +0D +EB +74 +57 FC -AA +25 BA -84 16 +6C 0C -CD 68 -05 +2E E2 +F8 85 -5F 36 +72 63 5A -AE 73 6E 6B 0D -11 +8D 5B +40 6E 67 07 -88 10 -03 +1C 47 3F 2F +C8 72 -59 BF -7C +E2 D4 69 -6B -F1 -21 -F2 -FC -49 -87 -6D 5B +F1 +93 +21 +FC +4F +87 +DA +6D A7 -B4 +A2 A2 30 +6D 31 05 -CD 6D 60 68 06 -96 +B6 55 4F 0D -BF +FC E6 -B0 +85 C1 1A +E5 73 1E -BC 21 -57 +BD C4 +32 B2 -86 4E 65 +2C 77 73 45 -85 2B -33 -B6 -E7 -96 -F2 -25 -14 -7D -F3 -CB -7C -78 -4E -82 -C5 9C -B0 +B6 +B1 +E7 +2C +F2 +14 +99 +7D +CB +C7 +7C +4E +2B +82 +9C +86 3E 4B -F6 -5C +3F +0D +C5 6E 75 05 -72 +1C 8E -24 +09 CA 69 -7C +1F C4 4F -24 +C9 91 08 6D -7B 5F +DE 10 -AF 42 72 +2B DC -C0 +B0 84 -C6 44 19 +B1 48 -56 +55 87 -91 7B +24 CA -E0 +78 8F -09 47 +42 D8 -CD 17 +F3 3A 5D 73 -27 +49 9E 48 -71 +9C 75 69 7A 0A -22 +08 16 -5C A7 +97 75 16 -B6 +2D EF -90 75 +A4 88 33 -66 0C +D9 63 1A 4D -6B 2F +DA 21 2E -BF +6F F8 -71 +1C F2 -AC +2B FE 70 0D -FC +BF 90 -CA +72 EA -B1 +AC 13 -AE +2B F1 -90 +A4 4A DA -82 +20 1C 50 -4C 1C +D3 20 27 53 -0B +82 CB 13 6C -7A +1E E2 6D 7C -B4 27 +6D 20 45 64 -61 E2 +98 64 73 0D -92 +24 54 4B -3C +4F 81 16 -E5 +79 92 0E -E1 70 +78 DD -49 +92 D9 -CE 6D +33 BD 61 -60 68 1E +98 DC -AE +6B 0A -C1 +30 59 -74 +1D 88 0C -78 66 +5E 61 CF -A1 69 +68 1D 33 08 -FD +BF 4F 2A 7E -FE +BF D8 -CE 6C +F3 A0 -D3 7A +74 2B -B9 +AE 32 -2E BA +CB 2F 1E -9F +A7 50 AF -92 66 -13 +E4 A2 -56 +84 8E +95 3E 46 6C -86 +21 CC -8C -C2 +AD +E3 44 4E -3B F1 +8E 14 -4E +53 E3 42 -E5 +F9 A0 -27 +C9 86 -63 +18 AB -78 CA +9E 0B -32 +4C 57 75 6B 73 -35 0A +4D 16 72 -B9 +6E 9F -19 81 +86 06 -72 43 -A1 -D5 +5C +8C 0A -09 +75 ED -49 -EF +42 +6F +A3 +9A 1E 07 -79 +0F 63 66 67 17 -88 +B1 46 -75 65 6C -EF -A1 +2E +DA +F4 BA -27 4F 72 +24 4A 75 12 -D9 +5B B4 -B2 72 6A +56 48 3A -D2 6A 71 +7A 6A -0B 52 +21 DC -C1 7C 54 +D8 47 75 31 7C -66 1D 59 +EC 08 -BF 64 31 39 +17 34 32 1C -60 6C 76 +2C C4 -99 +73 F4 -23 50 1E +A4 75 67 06 -CD 72 0F +D9 4D -5E ED +4B 51 -32 10 +66 4A 1B -F3 +7E 9C 1F -E3 +BC 6D 42 -35 4B -2E +C6 A4 +25 23 -19 1A -73 -6E -90 -A1 -96 C3 -84 +73 +90 +CD +A1 +92 +C3 +B0 3B -5D 85 +CB 72 7D 67 75 17 -86 44 +70 09 62 -73 51 06 +EE 15 -1F +03 4C 7E 54 -C8 17 43 +79 B2 -93 +92 05 65 -3C -6B -B1 -9F -DC -27 +1A +68 +FF +67 +C7 +26 53 E6 C5 @@ -2185,7 +2186,7 @@ E7 61 16 93 -E5 +D0 6B 75 B3 @@ -2296,7 +2297,7 @@ E5 31 62 4C -D3 +BE 54 52 C0 @@ -2310,7 +2311,7 @@ AE 64 56 6B -B0 +9B 04 FB 55 @@ -2349,13 +2350,13 @@ BA B1 0E 1D -FC +E7 69 75 -8F +FA 6E 25 -B5 +B4 63 05 B6 @@ -2390,7 +2391,7 @@ B9 EB 0E E1 -B8 +A3 63 B5 18 @@ -2404,8 +2405,8 @@ CE 5F 38 62 -8E -C4 +F9 +C0 48 77 65 @@ -2424,191 +2425,175 @@ C4 7D 5C FE -D4 +20 +57 6F -61 62 53 -0F -CB -06 +F1 +6E +98 +20 59 -0F 87 +C1 62 3F 13 -F6 6F 6C 74 +1E 7B 6E -20 -FC +E7 +E4 5F 73 7A 5F 72 -07 6D 7C -AE -C0 +6E +00 +79 69 04 5A 22 1D -F6 +EC 19 54 68 0B 5A +67 58 -33 3E 55 4E 4F 00 -B8 -54 -0F -98 -AB -C3 +A3 +6F +08 +20 +36 +96 61 6D 20 +18 2F 5C 43 -78 08 53 +6F 40 76 66 -7B 6F 00 1F -0C -B0 +8F +9B +61 76 -23 -B1 -08 +04 +9C +81 63 4C 65 -04 -96 +81 +80 06 -3C -C4 -A4 +AF +87 48 61 72 +14 6B 30 21 1D -E0 57 06 +BC 68 20 25 -CD -72 +5D +39 69 -4C +6B 29 -E9 20 73 +3D 75 70 70 -4B -C1 +6F +72 74 20 66 +00 72 6F 6D -00 -A1 +8C +C0 09 44 69 -3E 0B 57 +67 61 76 65 09 -C3 52 61 64 -3F +18 +2A 1B -C8 08 +F9 6A -57 -D3 +BE 61 +6A 6C 7A -5C -63 +47 65 6A +2C 69 -2B +16 33 -3A -B1 +25 +96 63 68 -26 -4A -E4 -6E +11 35 +6E +20 +BC 7A 62 -44 -4D -33 -79 -33 -02 -EE -57 -65 -20 -46 -6F -72 -67 -01 -6F -74 -00 -3F -17 +2F 13 -EC +C9 45 61 49 @@ -7299,7 +7284,7 @@ CD DD 21 18 -6D +82 5E 42 21 diff --git a/cores/Spectrum/coreid.v b/cores/Spectrum/coreid.v index 1bc2c43..659c9cb 100644 --- a/cores/Spectrum/coreid.v +++ b/cores/Spectrum/coreid.v @@ -37,12 +37,12 @@ module coreid ( text[i] = 8'h00; text[ 0] = "T"; text[ 1] = "2"; - text[ 2] = "2"; + text[ 2] = "3"; text[ 3] = "-"; - text[ 4] = "0"; - text[ 5] = "1"; + text[ 4] = "1"; + text[ 5] = "6"; text[ 6] = "0"; - text[ 7] = "8"; + text[ 7] = "9"; text[ 8] = "2"; text[ 9] = "0"; text[10] = "1"; diff --git a/cores/Spectrum/cuatro_relojes.v b/cores/Spectrum/cuatro_relojes.v index ffc76cc..6defe1d 100644 --- a/cores/Spectrum/cuatro_relojes.v +++ b/cores/Spectrum/cuatro_relojes.v @@ -56,19 +56,19 @@ module clock_generator // These are the clock outputs from the PLL_ADV. .CLK0OUT(CLK_OUT1), - .CLK1OUT(CLK_OUT2), - .CLK2OUT(CLK_OUT3), - .CLK3OUT(CLK_OUT4) + .CLK1OUT(/*CLK_OUT2*/), + .CLK2OUT(/*CLK_OUT3*/), + .CLK3OUT(/*CLK_OUT4*/) ); wire cpuclk_selected, cpuclk_3_2, cpuclk_1_0; -// BUFGMUX speed_3_and_2 ( // 28MHz and 14MHz for CPU -// .O(cpuclk_3_2), -// .I0(CLK_OUT2), -// .I1(CLK_OUT1), -// .S(turbo_enable[0]) -// ); +//// BUFGMUX speed_3_and_2 ( // 28MHz and 14MHz for CPU +//// .O(cpuclk_3_2), +//// .I0(CLK_OUT2), +//// .I1(CLK_OUT1), +//// .S(turbo_enable[0]) +//// ); // // BUFGMUX speed_1_and_0 ( // 7MHz and 3.5MHz for CPU // .O(cpuclk_1_0), @@ -94,34 +94,49 @@ module clock_generator reg [2:0] clkdivider = 3'b000; always @(posedge CLK_OUT1) clkdivider <= clkdivider + 3'd1; + + BUFG bclkout2 ( + .O(CLK_OUT2), + .I(clkdivider[0]) + ); - BUFGMUX speed_3_and_2 ( // 28MHz and 14MHz for CPU - .O(cpuclk_3_2), - .I0(clkdivider[0]), - .I1(CLK_OUT1), - .S(turbo_enable[0]) - ); + BUFG bclkout3 ( + .O(CLK_OUT3), + .I(clkdivider[1]) + ); + + BUFG bclkout4 ( + .O(CLK_OUT4), + .I(clkdivider[2]) + ); + +// BUFGMUX speed_3_and_2 ( // 28MHz and 14MHz for CPU +// .O(cpuclk_3_2), +// .I0(CLK_OUT2), +// .I1(CLK_OUT1), +// .S(turbo_enable[0]) +// ); BUFGMUX speed_1_and_0 ( // 7MHz and 3.5MHz for CPU .O(cpuclk_1_0), - .I0(clkdivider[2]), - .I1(clkdivider[1]), + .I0(CLK_OUT4), + .I1(CLK_OUT3), .S(turbo_enable[0]) ); BUFGMUX cpuclk_selector ( .O(cpuclk_selected), .I0(cpuclk_1_0), - .I1(/*cpuclk_3_2*/clkdivider[0]), + .I1(/*cpuclk_3_2*/CLK_OUT2), .S(turbo_enable[1]) ); BUFGMUX aplicar_contienda ( - .O(cpuclk), - .I0(cpuclk_selected), // when no contention, clock is this one - .I1(1'b1), // during contention, clock is pulled up - .S(CPUContention) // contention signal - ); + .O(cpuclk), + .I0(cpuclk_selected), // when no contention, clock is this one + .I1(1'b1), // during contention, clock is pulled up + .S(CPUContention) // contention signal + ); assign cpuclkplain = cpuclk_selected; endmodule diff --git a/cores/Spectrum/new_memory.v b/cores/Spectrum/new_memory.v index 6673fac..55db8a5 100644 --- a/cores/Spectrum/new_memory.v +++ b/cores/Spectrum/new_memory.v @@ -50,6 +50,7 @@ module new_memory ( output reg [1:0] timing_mode, output wire disable_contention, output reg access_to_screen, + output reg ioreqbank, // Interface con el bus externo input wire inhibit_rom, @@ -165,9 +166,9 @@ module new_memory ( end end -`define ADDR_7FFD_PLUS2A (a[0] && !a[1] && a[15:14]==2'b01) -`define ADDR_7FFD_SP128 (a[0] && !a[1] && !a[15]) -`define ADDR_1FFD (a[0] && !a[1] && a[15:12]==4'b0001) +`define ADDR_7FFD_PLUS2A (!a[1] && a[15:14]==2'b01) +`define ADDR_7FFD_SP128 (!a[1] && !a[15]) +`define ADDR_1FFD (!a[1] && a[15:12]==4'b0001) `define ADDR_TIMEX_MMU (a[7:0] == 8'hF4) `define PAGE0 3'b000 @@ -209,6 +210,13 @@ module new_memory ( timex_mmu <= din; end end + + always @* begin + if (!disable_7ffd && disable_1ffd && !iorq_n && (!wr_n || !rd_n) && `ADDR_7FFD_SP128) + ioreqbank = 1'b1; + else + ioreqbank = 1'b0; + end reg [18:0] addr_port2; reg oe_memory_n; @@ -383,7 +391,7 @@ module new_memory ( a[15:13]==2'b111 && timex_mmu[7]==1'b1) access_to_screen = 1'b0; else if (!amstrad_allram_page_mode) begin - if (a[15:14]==2'b01 || (a[15:14]==2'b11 && (banco_ram==3'd5 || banco_ram==3'd7))) begin + if (a[15:14]==2'b01 || (a[15:14]==2'b11 && (/*banco_ram==3'd1 || banco_ram== 3'd3 || */banco_ram==3'd5 || banco_ram==3'd7))) begin access_to_screen = 1'b1; end end diff --git a/cores/Spectrum/pal_sync_generator.v b/cores/Spectrum/pal_sync_generator.v index cfe7a88..18e661c 100644 --- a/cores/Spectrum/pal_sync_generator.v +++ b/cores/Spectrum/pal_sync_generator.v @@ -29,6 +29,14 @@ module pal_sync_generator ( input wire vretraceint_disable, input wire [8:0] raster_line, output wire raster_int_in_progress, + input wire csync_option, + + input wire [8:0] hinit48k, + input wire [8:0] vinit48k, + input wire [8:0] hinit128k, + input wire [8:0] vinit128k, + input wire [8:0] hinitpen, + input wire [8:0] vinitpen, input wire [2:0] ri, input wire [2:0] gi, @@ -40,12 +48,16 @@ module pal_sync_generator ( output reg [2:0] bo, output reg hsync, output reg vsync, + output reg csync, output wire int_n ); reg [8:0] hc = 9'h000; reg [8:0] vc = 9'h000; + reg [8:0] hc_sync = 9'd104; + reg [8:0] vc_sync = 9'd0; + reg [8:0] end_count_h = 9'd447; reg [8:0] end_count_v = 9'd311; reg [8:0] begin_hblank = 9'd320; @@ -61,76 +73,92 @@ module pal_sync_generator ( reg [8:0] begin_hcint = 9'd2; reg [8:0] end_hcint = 9'd65; - reg [1:0] old_mode = 2'b11; + //reg [1:0] old_mode = 2'b11; assign hcnt = hc; assign vcnt = vc; always @(posedge clk) begin + if (hc_sync == end_count_h) begin + hc_sync <= 9'd0; + if (vc_sync == end_count_v) begin + vc_sync <= 9'd0; + end + else begin + vc_sync <= vc_sync + 9'd1; + end + end + else begin + hc_sync <= hc_sync + 9'd1; + end + if (hc == end_count_h) begin - hc <= 0; + hc <= 9'd0; if (vc == end_count_v) begin - vc <= 0; - if (mode != old_mode) begin - old_mode <= mode; - case (mode) - 2'b00: begin // timings for Sinclair 48K - end_count_h <= 9'd447; - end_count_v <= 9'd311; - begin_hblank <= 9'd320; - end_hblank <= 9'd415; - begin_hsync <= 9'd344; - end_hsync <= 9'd375; - begin_vblank <= 9'd248; - end_vblank <= 9'd255; - begin_vsync <= 9'd248; - end_vsync <= 9'd251; - begin_vcint <= 9'd248; - end_vcint <= 9'd248; - begin_hcint <= 9'd2; - end_hcint <= 9'd65; - end - 2'b01: begin // timings for Sinclair 128K/+2 grey - end_count_h <= 9'd455; - end_count_v <= 9'd310; - begin_hblank <= 9'd320; - end_hblank <= 9'd415; - begin_hsync <= 9'd344; - end_hsync <= 9'd375; - begin_vblank <= 9'd248; - end_vblank <= 9'd255; - begin_vsync <= 9'd248; - end_vsync <= 9'd251; - begin_vcint <= 9'd248; - end_vcint <= 9'd248; - begin_hcint <= 9'd2; - end_hcint <= 9'd65; - end - 2'b10, - 2'b11: begin // timings for Pentagon 128 - end_count_h <= 9'd447; - end_count_v <= 9'd319; - begin_hblank <= 9'd336; // 9'd328; - end_hblank <= 9'd399; // 9'd391; - begin_hsync <= 9'd336; // 9'd328; - end_hsync <= 9'd367; // 9'd359; - begin_vblank <= 9'd240; - end_vblank <= 9'd271; // 9'd255; - begin_vsync <= 9'd240; - end_vsync <= 9'd255; // 9'd243; - begin_vcint <= 9'd239; - end_vcint <= 9'd239; - begin_hcint <= 9'd323; // 9'd320; - end_hcint <= 9'd391; //9'd391; - end - endcase - end + vc <= 9'd0; + case (mode) + 2'b00: begin // timings for Sinclair 48K + end_count_h <= 9'd447; + end_count_v <= 9'd311; + hc_sync <= hinit48k; + vc_sync <= vinit48k; + begin_hblank <= 9'd320; + end_hblank <= 9'd415; + begin_hsync <= 9'd344; + end_hsync <= 9'd375; + begin_vblank <= 9'd248; + end_vblank <= 9'd255; + begin_vsync <= 9'd248; + end_vsync <= 9'd251; + begin_vcint <= 9'd248; + end_vcint <= 9'd248; + begin_hcint <= 9'd2; + end_hcint <= 9'd65; + end + 2'b01: begin // timings for Sinclair 128K/+2 grey + end_count_h <= 9'd455; + end_count_v <= 9'd310; + hc_sync <= hinit128k; + vc_sync <= vinit128k; + begin_hblank <= 9'd320; + end_hblank <= 9'd415; + begin_hsync <= 9'd344; + end_hsync <= 9'd375; + begin_vblank <= 9'd248; + end_vblank <= 9'd255; + begin_vsync <= 9'd248; + end_vsync <= 9'd251; + begin_vcint <= 9'd248; + end_vcint <= 9'd248; + begin_hcint <= 9'd4; + end_hcint <= 9'd67; + end + 2'b10, + 2'b11: begin // timings for Pentagon 128 + end_count_h <= 9'd447; + end_count_v <= 9'd319; + hc_sync <= hinitpen; + vc_sync <= vinitpen; + begin_hblank <= 9'd336; // 9'd328; + end_hblank <= 9'd399; // 9'd391; + begin_hsync <= 9'd336; // 9'd328; + end_hsync <= 9'd367; // 9'd359; + begin_vblank <= 9'd240; + end_vblank <= 9'd271; // 9'd255; + begin_vsync <= 9'd240; + end_vsync <= 9'd255; // 9'd243; + begin_vcint <= 9'd239; + end_vcint <= 9'd239; + begin_hcint <= 9'd323; // 9'd323; + end_hcint <= 9'd386; //9'd386; + end + endcase end else - vc <= vc + 1; + vc <= vc + 9'd1; end else - hc <= hc + 1; + hc <= hc + 9'd1; end // INT generation @@ -166,5 +194,31 @@ module pal_sync_generator ( if (vc >= begin_vsync && vc <= end_vsync) vsync = 1'b0; end - end + end + + always @* begin + csync = 1'b1; + if (csync_option == 1'b1) begin + if (vc_sync < 9'd248 || vc_sync > 9'd255) begin + if (hc_sync >= 9'd0 && hc_sync <= 9'd27) + csync = 1'b0; + end + else if (vc_sync == 9'd248 || vc_sync == 9'd249 || vc_sync == 9'd250 || vc_sync == 9'd254 || vc_sync == 9'd255) begin + if ((hc_sync >= 9'd0 && hc_sync <= 9'd13) || (hc_sync >= 9'd224 && hc_sync <= 9'd237)) + csync = 1'b0; + end + else if (vc_sync == 9'd251 || vc_sync == 9'd252) begin + if ((hc_sync >= 9'd0 && hc_sync <= 9'd210) || (hc_sync >= 9'd224 && hc_sync <= 9'd433)) + csync = 1'b0; + end + else begin // linea 253 + if ((hc_sync >= 9'd0 && hc_sync <= 9'd210) || (hc_sync >= 9'd224 && hc_sync <= 9'd237)) + csync = 1'b0; + end + end + else begin + if ((hc_sync >= 9'd0 && hc_sync <= 9'd27) || (vc_sync >= 9'd248 && vc_sync <= 9'd251)) + csync = 1'b0; + end + end endmodule diff --git a/cores/Spectrum/pll_drp.v b/cores/Spectrum/pll_drp.v index 41be9f7..9a25304 100644 --- a/cores/Spectrum/pll_drp.v +++ b/cores/Spectrum/pll_drp.v @@ -43,7 +43,7 @@ module pll_drp #( //*********************************************************************** // State 1 Parameters - These are for the first reconfiguration state. - // 50 Hz, Salida RGB/VGA + // 50 Hz, Salida RGB/VGA, timings originales de 48K //*********************************************************************** // These parameters have an effect on the feedback path. A change on @@ -56,7 +56,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S1_CLKFBOUT_MULT = 9, + parameter S1_CLKFBOUT_MULT = 14, parameter S1_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -80,33 +80,33 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S1_CLKOUT0_DIVIDE = 16, + parameter S1_CLKOUT0_DIVIDE = 25, parameter S1_CLKOUT0_PHASE = 0, parameter S1_CLKOUT0_DUTY = 50000, - parameter S1_CLKOUT1_DIVIDE = 32, + parameter S1_CLKOUT1_DIVIDE = 25, parameter S1_CLKOUT1_PHASE = 0, parameter S1_CLKOUT1_DUTY = 50000, - parameter S1_CLKOUT2_DIVIDE = 64, + parameter S1_CLKOUT2_DIVIDE = 25, parameter S1_CLKOUT2_PHASE = 0, parameter S1_CLKOUT2_DUTY = 50000, - parameter S1_CLKOUT3_DIVIDE = 128, + parameter S1_CLKOUT3_DIVIDE = 25, parameter S1_CLKOUT3_PHASE = 0, parameter S1_CLKOUT3_DUTY = 50000, - parameter S1_CLKOUT4_DIVIDE = 128, + parameter S1_CLKOUT4_DIVIDE = 25, parameter S1_CLKOUT4_PHASE = 0, parameter S1_CLKOUT4_DUTY = 50000, - parameter S1_CLKOUT5_DIVIDE = 128, + parameter S1_CLKOUT5_DIVIDE = 25, parameter S1_CLKOUT5_PHASE = 0, parameter S1_CLKOUT5_DUTY = 50000, //*********************************************************************** // State 2 Parameters - These are for the second reconfiguration state. - // 51 Hz, Salida VGA + // 50 Hz, salida RGB/VGA, timings originales de 128K //*********************************************************************** // These parameters have an effect on the feedback path. A change on // these parameters will effect all of the clock outputs. @@ -118,7 +118,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S2_CLKFBOUT_MULT = 8, + parameter S2_CLKFBOUT_MULT = 33, parameter S2_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -128,7 +128,7 @@ module pll_drp // The divclk parameter allows th einput clock to be divided before it // reaches the phase and frequency comparitor. This can be set between // 1 and 128. - parameter S2_DIVCLK_DIVIDE = 1, + parameter S2_DIVCLK_DIVIDE = 2, // The following parameters describe the configuration that each clock // output should have once the reconfiguration for state one has @@ -142,33 +142,33 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S2_CLKOUT0_DIVIDE = 14, + parameter S2_CLKOUT0_DIVIDE = 29, parameter S2_CLKOUT0_PHASE = 0, parameter S2_CLKOUT0_DUTY = 50000, - parameter S2_CLKOUT1_DIVIDE = 28, + parameter S2_CLKOUT1_DIVIDE = 29, parameter S2_CLKOUT1_PHASE = 0, parameter S2_CLKOUT1_DUTY = 50000, - parameter S2_CLKOUT2_DIVIDE = 56, + parameter S2_CLKOUT2_DIVIDE = 29, parameter S2_CLKOUT2_PHASE = 0, parameter S2_CLKOUT2_DUTY = 50000, - parameter S2_CLKOUT3_DIVIDE = 112, + parameter S2_CLKOUT3_DIVIDE = 29, parameter S2_CLKOUT3_PHASE = 0, parameter S2_CLKOUT3_DUTY = 50000, - parameter S2_CLKOUT4_DIVIDE = 112, + parameter S2_CLKOUT4_DIVIDE = 29, parameter S2_CLKOUT4_PHASE = 0, parameter S2_CLKOUT4_DUTY = 50000, - parameter S2_CLKOUT5_DIVIDE = 112, + parameter S2_CLKOUT5_DIVIDE = 29, parameter S2_CLKOUT5_PHASE = 0, parameter S2_CLKOUT5_DUTY = 50000, //*********************************************************************** // State 3 Parameters - These are for the second reconfiguration state. - // 53.50 Hz, Salida VGA + // 52 Hz, Salida VGA //*********************************************************************** // These parameters have an effect on the feedback path. A change on // these parameters will effect all of the clock outputs. @@ -180,7 +180,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S3_CLKFBOUT_MULT = 9, + parameter S3_CLKFBOUT_MULT = 18, parameter S3_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -204,33 +204,33 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S3_CLKOUT0_DIVIDE = 15, + parameter S3_CLKOUT0_DIVIDE = 31, parameter S3_CLKOUT0_PHASE = 0, parameter S3_CLKOUT0_DUTY = 50000, - parameter S3_CLKOUT1_DIVIDE = 30, + parameter S3_CLKOUT1_DIVIDE = 31, parameter S3_CLKOUT1_PHASE = 0, parameter S3_CLKOUT1_DUTY = 50000, - parameter S3_CLKOUT2_DIVIDE = 60, + parameter S3_CLKOUT2_DIVIDE = 31, parameter S3_CLKOUT2_PHASE = 0, parameter S3_CLKOUT2_DUTY = 50000, - parameter S3_CLKOUT3_DIVIDE = 120, + parameter S3_CLKOUT3_DIVIDE = 31, parameter S3_CLKOUT3_PHASE = 0, parameter S3_CLKOUT3_DUTY = 50000, - parameter S3_CLKOUT4_DIVIDE = 120, + parameter S3_CLKOUT4_DIVIDE = 31, parameter S3_CLKOUT4_PHASE = 0, parameter S3_CLKOUT4_DUTY = 50000, - parameter S3_CLKOUT5_DIVIDE = 120, + parameter S3_CLKOUT5_DIVIDE = 31, parameter S3_CLKOUT5_PHASE = 0, parameter S3_CLKOUT5_DUTY = 50000, //*********************************************************************** // State 4 Parameters - These are for the second reconfiguration state. - // 55.80 Hz, Salida VGA + // 53 Hz, Salida VGA //*********************************************************************** // These parameters have an effect on the feedback path. A change on // these parameters will effect all of the clock outputs. @@ -242,7 +242,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S4_CLKFBOUT_MULT = 10, + parameter S4_CLKFBOUT_MULT = 16, parameter S4_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -266,33 +266,33 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S4_CLKOUT0_DIVIDE = 16, + parameter S4_CLKOUT0_DIVIDE = 27, parameter S4_CLKOUT0_PHASE = 0, parameter S4_CLKOUT0_DUTY = 50000, - parameter S4_CLKOUT1_DIVIDE = 32, + parameter S4_CLKOUT1_DIVIDE = 27, parameter S4_CLKOUT1_PHASE = 0, parameter S4_CLKOUT1_DUTY = 50000, - parameter S4_CLKOUT2_DIVIDE = 64, + parameter S4_CLKOUT2_DIVIDE = 27, parameter S4_CLKOUT2_PHASE = 0, parameter S4_CLKOUT2_DUTY = 50000, - parameter S4_CLKOUT3_DIVIDE = 128, + parameter S4_CLKOUT3_DIVIDE = 27, parameter S4_CLKOUT3_PHASE = 0, parameter S4_CLKOUT3_DUTY = 50000, - parameter S4_CLKOUT4_DIVIDE = 128, + parameter S4_CLKOUT4_DIVIDE = 27, parameter S4_CLKOUT4_PHASE = 0, parameter S4_CLKOUT4_DUTY = 50000, - parameter S4_CLKOUT5_DIVIDE = 128, + parameter S4_CLKOUT5_DIVIDE = 27, parameter S4_CLKOUT5_PHASE = 0, parameter S4_CLKOUT5_DUTY = 50000, //*********************************************************************** // State 5 Parameters - These are for the second reconfiguration state. - // 57.39 Hz, Salida VGA + // 55 Hz, Salida VGA //*********************************************************************** // These parameters have an effect on the feedback path. A change on // these parameters will effect all of the clock outputs. @@ -304,7 +304,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S5_CLKFBOUT_MULT = 9, + parameter S5_CLKFBOUT_MULT = 27, parameter S5_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -314,7 +314,7 @@ module pll_drp // The divclk parameter allows th einput clock to be divided before it // reaches the phase and frequency comparitor. This can be set between // 1 and 128. - parameter S5_DIVCLK_DIVIDE = 1, + parameter S5_DIVCLK_DIVIDE = 2, // The following parameters describe the configuration that each clock // output should have once the reconfiguration for state one has @@ -328,33 +328,33 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S5_CLKOUT0_DIVIDE = 14, + parameter S5_CLKOUT0_DIVIDE = 22, parameter S5_CLKOUT0_PHASE = 0, parameter S5_CLKOUT0_DUTY = 50000, - parameter S5_CLKOUT1_DIVIDE = 28, + parameter S5_CLKOUT1_DIVIDE = 22, parameter S5_CLKOUT1_PHASE = 0, parameter S5_CLKOUT1_DUTY = 50000, - parameter S5_CLKOUT2_DIVIDE = 56, + parameter S5_CLKOUT2_DIVIDE = 22, parameter S5_CLKOUT2_PHASE = 0, parameter S5_CLKOUT2_DUTY = 50000, - parameter S5_CLKOUT3_DIVIDE = 112, + parameter S5_CLKOUT3_DIVIDE = 22, parameter S5_CLKOUT3_PHASE = 0, parameter S5_CLKOUT3_DUTY = 50000, - parameter S5_CLKOUT4_DIVIDE = 112, + parameter S5_CLKOUT4_DIVIDE = 22, parameter S5_CLKOUT4_PHASE = 0, parameter S5_CLKOUT4_DUTY = 50000, - parameter S5_CLKOUT5_DIVIDE = 112, + parameter S5_CLKOUT5_DIVIDE = 22, parameter S5_CLKOUT5_PHASE = 0, parameter S5_CLKOUT5_DUTY = 50000, //*********************************************************************** // State 6 Parameters - These are for the second reconfiguration state. - // 59.52 Hz, Salida VGA + // 57 Hz, Salida VGA //*********************************************************************** // These parameters have an effect on the feedback path. A change on // these parameters will effect all of the clock outputs. @@ -366,7 +366,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S6_CLKFBOUT_MULT = 8, + parameter S6_CLKFBOUT_MULT = 14, parameter S6_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -390,33 +390,33 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S6_CLKOUT0_DIVIDE = 12, + parameter S6_CLKOUT0_DIVIDE = 22, parameter S6_CLKOUT0_PHASE = 0, parameter S6_CLKOUT0_DUTY = 50000, - parameter S6_CLKOUT1_DIVIDE = 24, + parameter S6_CLKOUT1_DIVIDE = 22, parameter S6_CLKOUT1_PHASE = 0, parameter S6_CLKOUT1_DUTY = 50000, - parameter S6_CLKOUT2_DIVIDE = 48, + parameter S6_CLKOUT2_DIVIDE = 22, parameter S6_CLKOUT2_PHASE = 0, parameter S6_CLKOUT2_DUTY = 50000, - parameter S6_CLKOUT3_DIVIDE = 96, + parameter S6_CLKOUT3_DIVIDE = 22, parameter S6_CLKOUT3_PHASE = 0, parameter S6_CLKOUT3_DUTY = 50000, - parameter S6_CLKOUT4_DIVIDE = 96, + parameter S6_CLKOUT4_DIVIDE = 22, parameter S6_CLKOUT4_PHASE = 0, parameter S6_CLKOUT4_DUTY = 50000, - parameter S6_CLKOUT5_DIVIDE = 96, + parameter S6_CLKOUT5_DIVIDE = 22, parameter S6_CLKOUT5_PHASE = 0, parameter S6_CLKOUT5_DUTY = 50000, //*********************************************************************** // State 7 Parameters - These are for the second reconfiguration state. - // 61.8 Hz, Salida VGA + // 59 Hz, Salida VGA //*********************************************************************** // These parameters have an effect on the feedback path. A change on // these parameters will effect all of the clock outputs. @@ -428,7 +428,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S7_CLKFBOUT_MULT = 9, + parameter S7_CLKFBOUT_MULT = 29, parameter S7_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -438,7 +438,7 @@ module pll_drp // The divclk parameter allows th einput clock to be divided before it // reaches the phase and frequency comparitor. This can be set between // 1 and 128. - parameter S7_DIVCLK_DIVIDE = 1, + parameter S7_DIVCLK_DIVIDE = 2, // The following parameters describe the configuration that each clock // output should have once the reconfiguration for state one has @@ -452,33 +452,33 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S7_CLKOUT0_DIVIDE = 13, + parameter S7_CLKOUT0_DIVIDE = 22, parameter S7_CLKOUT0_PHASE = 0, parameter S7_CLKOUT0_DUTY = 50000, - parameter S7_CLKOUT1_DIVIDE = 26, + parameter S7_CLKOUT1_DIVIDE = 22, parameter S7_CLKOUT1_PHASE = 0, parameter S7_CLKOUT1_DUTY = 50000, - parameter S7_CLKOUT2_DIVIDE = 52, + parameter S7_CLKOUT2_DIVIDE = 22, parameter S7_CLKOUT2_PHASE = 0, parameter S7_CLKOUT2_DUTY = 50000, - parameter S7_CLKOUT3_DIVIDE = 104, + parameter S7_CLKOUT3_DIVIDE = 22, parameter S7_CLKOUT3_PHASE = 0, parameter S7_CLKOUT3_DUTY = 50000, - parameter S7_CLKOUT4_DIVIDE = 104, + parameter S7_CLKOUT4_DIVIDE = 22, parameter S7_CLKOUT4_PHASE = 0, parameter S7_CLKOUT4_DUTY = 50000, - parameter S7_CLKOUT5_DIVIDE = 104, + parameter S7_CLKOUT5_DIVIDE = 22, parameter S7_CLKOUT5_PHASE = 0, parameter S7_CLKOUT5_DUTY = 50000, //*********************************************************************** // State 8 Parameters - These are for the second reconfiguration state. - // 63.77 Hz, Salida VGA + // 60 Hz, Salida VGA //*********************************************************************** // These parameters have an effect on the feedback path. A change on // these parameters will effect all of the clock outputs. @@ -490,7 +490,7 @@ module pll_drp // _PHASE: This is the phase multiplied by 1000. For example if // a phase of 24.567 deg was desired the input value would be // 24567. The range for the phase is from -360000 to 360000. - parameter S8_CLKFBOUT_MULT = 10, + parameter S8_CLKFBOUT_MULT = 8, parameter S8_CLKFBOUT_PHASE = 0, // The bandwidth parameter effects the phase error and the jitter filter @@ -514,27 +514,27 @@ module pll_drp // _DUTY: This is the duty cycle multiplied by 100,000. For example if // a duty cycle of .24567 was desired the input would be // 24567. - parameter S8_CLKOUT0_DIVIDE = 14, + parameter S8_CLKOUT0_DIVIDE = 12, parameter S8_CLKOUT0_PHASE = 0, parameter S8_CLKOUT0_DUTY = 50000, - parameter S8_CLKOUT1_DIVIDE = 28, + parameter S8_CLKOUT1_DIVIDE = 12, parameter S8_CLKOUT1_PHASE = 0, parameter S8_CLKOUT1_DUTY = 50000, - parameter S8_CLKOUT2_DIVIDE = 56, + parameter S8_CLKOUT2_DIVIDE = 12, parameter S8_CLKOUT2_PHASE = 0, parameter S8_CLKOUT2_DUTY = 50000, - parameter S8_CLKOUT3_DIVIDE = 112, + parameter S8_CLKOUT3_DIVIDE = 12, parameter S8_CLKOUT3_PHASE = 0, parameter S8_CLKOUT3_DUTY = 50000, - parameter S8_CLKOUT4_DIVIDE = 112, + parameter S8_CLKOUT4_DIVIDE = 12, parameter S8_CLKOUT4_PHASE = 0, parameter S8_CLKOUT4_DUTY = 50000, - parameter S8_CLKOUT5_DIVIDE = 112, + parameter S8_CLKOUT5_DIVIDE = 12, parameter S8_CLKOUT5_PHASE = 0, parameter S8_CLKOUT5_DUTY = 50000 diff --git a/cores/Spectrum/pll_top.v b/cores/Spectrum/pll_top.v index 40faa1b..d418252 100644 --- a/cores/Spectrum/pll_top.v +++ b/cores/Spectrum/pll_top.v @@ -237,7 +237,7 @@ module pll_top .BANDWIDTH("LOW"), // "HIGH", "LOW" or "OPTIMIZED" // CLKFBOUT stuff - .CLKFBOUT_MULT(9), + .CLKFBOUT_MULT(14), .CLKFBOUT_PHASE(0.0), // Set the clock period (ns) of input clocks and reference jitter @@ -249,27 +249,27 @@ module pll_top // DIVIDE: (1 to 128) // DUTY_CYCLE: (0.01 to 0.99) - This is dependent on the divide value. // PHASE: (0.0 to 360.0) - This is dependent on the divide value. - .CLKOUT0_DIVIDE(16), + .CLKOUT0_DIVIDE(25), .CLKOUT0_DUTY_CYCLE(0.5), .CLKOUT0_PHASE(0.0), - .CLKOUT1_DIVIDE(32), + .CLKOUT1_DIVIDE(25), .CLKOUT1_DUTY_CYCLE(0.5), .CLKOUT1_PHASE(0.0), - .CLKOUT2_DIVIDE(64), + .CLKOUT2_DIVIDE(25), .CLKOUT2_DUTY_CYCLE(0.5), .CLKOUT2_PHASE(0.0), - .CLKOUT3_DIVIDE(128), + .CLKOUT3_DIVIDE(25), .CLKOUT3_DUTY_CYCLE(0.5), .CLKOUT3_PHASE(0.0), - .CLKOUT4_DIVIDE(128), + .CLKOUT4_DIVIDE(25), .CLKOUT4_DUTY_CYCLE(0.5), .CLKOUT4_PHASE(0.0), - .CLKOUT5_DIVIDE(128), + .CLKOUT5_DIVIDE(25), .CLKOUT5_DUTY_CYCLE(0.5), .CLKOUT5_PHASE(0.0), diff --git a/cores/Spectrum/scancode_to_speccy.v b/cores/Spectrum/scancode_to_speccy.v index 22f0555..19dcbee 100644 --- a/cores/Spectrum/scancode_to_speccy.v +++ b/cores/Spectrum/scancode_to_speccy.v @@ -65,7 +65,7 @@ module scancode_to_speccy ( reg [13:0] addr = 14'h0000; reg [13:0] cpuaddr = 14'h0000; // Dirección E/S desde la CPU. Se autoincrementa en cada acceso initial begin - $readmemh ("keyb_es_hex.txt", keymap); + $readmemh ("../keymaps/keyb_es_hex.txt", keymap); end reg [2:0] keyrow1 = 3'h0; diff --git a/cores/Spectrum/scandoubler_ctrl.v b/cores/Spectrum/scandoubler_ctrl.v index 738466c..edb9b5c 100644 --- a/cores/Spectrum/scandoubler_ctrl.v +++ b/cores/Spectrum/scandoubler_ctrl.v @@ -35,7 +35,8 @@ module scandoubler_ctrl ( output wire vga_enable, output wire scanlines_enable, output wire [2:0] freq_option, - output wire [1:0] turbo_enable + output wire [1:0] turbo_enable, + output wire csync_option ); parameter SCANDBLCTRL = 8'h0B; @@ -47,6 +48,7 @@ module scandoubler_ctrl ( assign scanlines_enable = scandblctrl[1]; assign freq_option = scandblctrl[4:2]; assign turbo_enable = scandblctrl[7:6]; + assign csync_option = scandblctrl[5]; reg [7:0] scandblctrl = 8'h00; // initial value reg [1:0] kbd_change_video_edge_detect = 2'b00; @@ -58,7 +60,7 @@ module scandoubler_ctrl ( else if (iorq_n == 1'b0 && wr_n == 1'b0 && a == PRISMSPEEDCTRL) scandblctrl <= {din[1:0], scandblctrl[5:0]}; else if (kbd_change_video_edge_detect == 2'b01) begin - scandblctrl <= {scandblctrl[7:5], ((scandblctrl[0] == 1'b0)? 3'b101 : 3'b000), scandblctrl[1], ~scandblctrl[0]}; + scandblctrl <= {scandblctrl[7:5], ((scandblctrl[0] == 1'b0)? 3'b111 : 3'b000), scandblctrl[1], ~scandblctrl[0]}; end dout <= scandblctrl; end diff --git a/cores/Spectrum/tld_zxuno.v b/cores/Spectrum/tld_zxuno.v index ba55a9b..21ccfcd 100644 --- a/cores/Spectrum/tld_zxuno.v +++ b/cores/Spectrum/tld_zxuno.v @@ -96,7 +96,7 @@ module tld_zxuno ( assign audio_out_right = audio_out; wire [2:0] ri, gi, bi; - wire hsync_pal, vsync_pal; + wire hsync_pal, vsync_pal, csync_pal; wire vga_enable, scanlines_enable; @@ -114,6 +114,7 @@ module tld_zxuno ( .b(bi), .hsync(hsync_pal), .vsync(vsync_pal), + .csync(csync_pal), .clkps2(clkps2), .dataps2(dataps2), .ear(~ear), // negada porque el hardware tiene un transistor inversor @@ -158,6 +159,7 @@ module tld_zxuno ( .bi(bi), .hsync_ext_n(hsync_pal), .vsync_ext_n(vsync_pal), + .csync_ext_n(csync_pal), .ro(r), .go(g), .bo(b), diff --git a/cores/Spectrum/ula_radas.v b/cores/Spectrum/ula_radas.v index 31cb76b..9fb9fdd 100644 --- a/cores/Spectrum/ula_radas.v +++ b/cores/Spectrum/ula_radas.v @@ -61,6 +61,7 @@ module ula_radas ( output reg spk, input wire issue2_keyboard, input wire [1:0] mode, + input wire ioreqbank, input wire disable_contention, input wire access_to_contmem, output wire doc_ext_option, @@ -68,6 +69,7 @@ module ula_radas ( input wire disable_timexscr, input wire disable_ulaplus, input wire disable_radas, + input wire csync_option, // Video output wire [2:0] r, @@ -75,6 +77,7 @@ module ula_radas ( output wire [2:0] b, output wire hsync, output wire vsync, + output wire csync, output wire y_n ); @@ -99,6 +102,14 @@ module ula_radas ( // Counters from sync module wire [8:0] hc; wire [8:0] vc; + + // Initial values for synch, syncv for all supported timings + reg [8:0] hinit48k = 9'd112; + reg [8:0] vinit48k = 9'd2; + reg [8:0] hinit128k = 9'd116; + reg [8:0] vinit128k = 9'd2; + reg [8:0] hinitpen = 9'd110; + reg [8:0] vinitpen = 9'd0; // Signal when the vertical counter is in the line that we use to make the INT signal wire in_int_line; @@ -114,6 +125,15 @@ module ula_radas ( .vretraceint_disable(vretraceint_disable), .raster_line(raster_line), .raster_int_in_progress(raster_int_in_progress), + .csync_option(csync_option), + + .hinit48k(hinit48k), + .vinit48k(vinit48k), + .hinit128k(hinit128k), + .vinit128k(vinit128k), + .hinitpen(hinitpen), + .vinitpen(vinitpen), + .ri(ri), .gi(gi), .bi(bi), @@ -124,6 +144,7 @@ module ula_radas ( .bo(b), .hsync(hsync), .vsync(vsync), + .csync(csync), .int_n(int_n) ); @@ -218,12 +239,16 @@ module ula_radas ( // AttrOutput register reg [7:0] AttrOutput = 8'h00; + reg [7:0] BorderColorDelayed; // used to delay 0.5T the assignment from border to AttrOutput while in Pentagon mode wire [2:0] StdPaperColour = AttrOutput[5:3]; wire [2:0] StdInkColour = AttrOutput[2:0]; wire Bright = AttrOutput[6]; wire Flash = AttrOutput[7]; always @(posedge clk7) begin - if (AttrOutputLoad) + BorderColorDelayed <= {2'b00,Border,3'b000}; // update always BorderColorDelayed + if (mode == PENTAGON && (hc<(BHPIXEL+8) || hc>(EHPIXEL+12) || vcEVPIXEL)) + AttrOutput <= BorderColorDelayed; // and in next pixel clock, update AttrOutput if in border and Pentagon mode is on + else if (AttrOutputLoad) AttrOutput <= InputToAttrOutput; end @@ -429,15 +454,8 @@ module ula_radas ( SerializerLoad = 1'b1; // updated every 8 pixel clocks, if we are in paper area end end - if (mode == PENTAGON) begin - if (hc<(BHPIXEL+8) || hc>(EHPIXEL+12) || vcEVPIXEL) - AttrOutputLoad = 1'b1; // updated every clock for Pentagon border - else if (hc[2:0] == 3'd4) // hc=4,12,20,28,etc - AttrOutputLoad = 1'b1; // updated every 8 pixel clocks for Pentagon paper - end - else begin - if (hc[2:0] == 3'd4) // hc=4,12,20,28,etc - AttrOutputLoad = 1'b1; // updated every 8 pixel clocks + if (hc[2:0] == 3'd4) begin // hc=4,12,20,28,etc + AttrOutputLoad = 1'b1; // updated every 8 pixel clocks end if (hc[2:0]==3'd3) begin CALoad = 1'b1; @@ -484,6 +502,14 @@ module ula_radas ( ULAPLUSADDR = 16'hBF3B, ULAPLUSDATA = 16'hFF3B, RADASCTRL = 8'h40; + + parameter + HOFFS48K = 8'h80, + VOFFS48K = 8'h81, + HOFFS128K = 8'h82, + VOFFS128K = 8'h83, + HOFFSPEN = 8'h84, + VOFFSPEN = 8'h85; // Z80 writes values into registers // Port 0xFE @@ -515,6 +541,20 @@ module ula_radas ( end end end + + // Sync adjustment + always @(posedge clkregs) begin + if (zxuno_regwr == 1'b1) begin + case (zxuno_addr) + HOFFS48K: hinit48k <= {din,1'b0}; + VOFFS48K: vinit48k <= {din,1'b0}; + HOFFS128K: hinit128k <= {din,1'b0}; + VOFFS128K: vinit128k <= {din,1'b0}; + HOFFSPEN: hinitpen <= {din,1'b0}; + VOFFSPEN: vinitpen <= {din,1'b0}; + endcase + end + end reg post_processed_ear; // EAR signal after being altered by the keyboard current issue always @* begin @@ -540,6 +580,18 @@ module ula_radas ( dout = {7'b0000000,ConfigReg}; else if (a[7:0]==TIMEXPORT && enable_timexmmu && !disable_timexscr) dout = TimexConfigReg; + else if (zxuno_addr == HOFFS48K && zxuno_regrd == 1'b1) + dout = hinit48k[8:1]; + else if (zxuno_addr == VOFFS48K && zxuno_regrd == 1'b1) + dout = vinit48k[8:1]; + else if (zxuno_addr == HOFFS128K && zxuno_regrd == 1'b1) + dout = hinit128k[8:1]; + else if (zxuno_addr == VOFFS128K && zxuno_regrd == 1'b1) + dout = vinit128k[8:1]; + else if (zxuno_addr == HOFFSPEN && zxuno_regrd == 1'b1) + dout = hinitpen[8:1]; + else if (zxuno_addr == VOFFSPEN && zxuno_regrd == 1'b1) + dout = vinitpen[8:1]; else begin if (BitmapAddr || AttrAddr) dout = vramdata; @@ -554,7 +606,7 @@ module ula_radas ( /////////////////////////////////// wire iorequla = !iorq_n && (a[0]==0); wire iorequlaplus = !iorq_n && (a==ULAPLUSADDR || a==ULAPLUSDATA); - wire ioreqall_n = !(iorequlaplus || iorequla); + wire ioreqall_n = !(iorequlaplus || iorequla || ioreqbank); /////////////////////////////////// // CPU CLOCK GENERATION (Altwasser method) @@ -568,13 +620,12 @@ module ula_radas ( // wire N4 = ~Border_n | ~ioreqtw3 | ~mreqt23 | ~cpuclk; // wire N5 = ~(N1y2 | N3 | N4); // wire N6 = ~(hc[3:0]>=4'd4 | ~Border_n | ~cpuclk | ioreqall_n | ~ioreqtw3); -// assign cpuclk = (hc[0] | N5 | N6); // // always @(posedge cpuclk) begin // ioreqtw3 <= ioreqall_n; // mreqt23 <= mreq_n; // end - +// // wire Nor1 = (~access_to_contmem & ioreqall_n) | (hc[3:0]<4'd12) | // (~Border_n | ~ioreqtw3 | ~cpuclk | ~mreqt23); // wire Nor2 = (hc[3:0]<4'd4) | ~Border_n | ~cpuclk | ioreqall_n | ~ioreqtw3; @@ -587,26 +638,14 @@ module ula_radas ( // end // end // -// assign cpuclk = (!CLKContention || RadasEnabled || disable_contention)? hc[0] : 1'b1; -// -// reg CPUInternalClock = 0; -// always @(posedge `MASTERCPUCLK) begin -// if (!CLKContention || RadasEnabled || disable_contention) -// CPUInternalClock <= ~CPUInternalClock; -// else -// CPUInternalClock <= 1'b1; -// end -// -// assign cpuclk = CPUInternalClock; - - +// assign CPUContention = ~(!CLKContention || RadasEnabled || disable_contention); /////////////////////////////////// // CPU CLOCK GENERATION (CSmith method) /////////////////////////////////// reg MayContend_n; - always @* begin // esto era negedge clk7 en el esquemático + always @(negedge clk7) begin // esto era negedge clk7 en el esquemático if (hc[3:0]>4'd3 && Border_n==1'b1) MayContend_n <= 1'b0; else diff --git a/cores/Spectrum/vga_scandoubler.v b/cores/Spectrum/vga_scandoubler.v index 02ab602..e40ec09 100644 --- a/cores/Spectrum/vga_scandoubler.v +++ b/cores/Spectrum/vga_scandoubler.v @@ -30,6 +30,7 @@ module vga_scandoubler ( input wire [2:0] bi, input wire hsync_ext_n, input wire vsync_ext_n, + input wire csync_ext_n, output reg [2:0] ro, output reg [2:0] go, output reg [2:0] bo, @@ -151,7 +152,7 @@ module vga_scandoubler ( ro = ri; go = gi; bo = bi; - hsync = hsync_ext_n & vsync_ext_n; + hsync = csync_ext_n; vsync = 1'b1; end else begin // VGA output diff --git a/cores/Spectrum/zxuno.v b/cores/Spectrum/zxuno.v index 99347c8..c95e534 100644 --- a/cores/Spectrum/zxuno.v +++ b/cores/Spectrum/zxuno.v @@ -37,6 +37,7 @@ module zxuno ( output wire [2:0] b, output wire hsync, output wire vsync, + output wire csync, inout wire clkps2, inout wire dataps2, input wire ear, @@ -142,6 +143,7 @@ module zxuno ( wire disable_contention; wire access_to_screen; wire doc_ext_option; // bit 7 del puerto $FF del Timex + wire ioreqbank; // CoreID wire oe_n_coreid; @@ -152,6 +154,7 @@ module zxuno ( wire [7:0] scratch_dout; // Scandoubler control + wire csync_option; wire [7:0] scndblctrl_dout; wire oe_n_scndblctrl; @@ -277,19 +280,22 @@ module zxuno ( .kbd(kbdcol_to_ula), .issue2_keyboard(issue2_keyboard), .mode(timing_mode), + .ioreqbank(ioreqbank), .disable_contention(disable_contention), .doc_ext_option(doc_ext_option), .enable_timexmmu(enable_timexmmu), .disable_timexscr(disable_timexscr), .disable_ulaplus(disable_ulaplus), .disable_radas(disable_radas), + .csync_option(csync_option), // Video .r(r), .g(g), .b(b), .hsync(hsync), - .vsync(vsync) + .vsync(vsync), + .csync(csync) ); zxunoregs addr_reg_zxuno ( @@ -363,6 +369,7 @@ module zxuno ( .timing_mode(timing_mode), .disable_contention(disable_contention), .access_to_screen(access_to_screen), + .ioreqbank(ioreqbank), // Interface con el bus externo (TO-DO) .inhibit_rom(1'b0), @@ -492,7 +499,8 @@ module zxuno ( .vga_enable(vga_enable), .scanlines_enable(scanlines_enable), .freq_option(freq_option), - .turbo_enable(turbo_enable) + .turbo_enable(turbo_enable), + .csync_option(csync_option) ); rasterint_ctrl control_rasterint ( diff --git a/cores/VIC20/ise/VIC20.prj b/cores/VIC20/ise/VIC20.prj index d637632..0a85641 100644 --- a/cores/VIC20/ise/VIC20.prj +++ b/cores/VIC20/ise/VIC20.prj @@ -3,15 +3,19 @@ vhdl work "../source/T65_MCode.vhd" vhdl work "../source/T65_ALU.vhd" vhdl work "../source/ps2kbd.vhd" vhdl work "../source/vic20_vic.vhd" -vhdl work "../source/vic20_rams.vhd" -vhdl work "../source/vic20_ram.vhd" +vhdl work "../source/vic20_ram8.vhd" vhdl work "../source/vic20_ps2_if.vhd" vhdl work "../source/vic20_dblscan.vhd" -vhdl work "../source/vic20_clocks_xilinx.vhd" vhdl work "../source/T65.vhd" vhdl work "../source/roms/vic20_kernal.vhd" vhdl work "../source/roms/vic20_chars.vhd" +vhdl work "../source/roms/vic20_cartridge3.vhd" +vhdl work "../source/roms/vic20_cartridge2.vhd" +vhdl work "../source/roms/vic20_cartridge.vhd" vhdl work "../source/roms/vic20_basic.vhd" +vhdl work "../source/relojes.vhd" +verilog work "../source/multiboot_v4.v" vhdl work "../source/m6522.vhd" +vhdl work "../source/DistRam.vhd" vhdl work "../source/dac.vhd" vhdl work "../source/vic20.vhd" diff --git a/cores/VIC20/ise/VIC20.ut b/cores/VIC20/ise/VIC20.ut index fb52ea8..dfd4060 100644 --- a/cores/VIC20/ise/VIC20.ut +++ b/cores/VIC20/ise/VIC20.ut @@ -11,8 +11,7 @@ -g TmsPin:PullUp -g UnusedPin:PullDown -g UserID:0xFFFFFFFF --g ExtMasterCclk_en:Yes --g ExtMasterCclk_divide:50 +-g ExtMasterCclk_en:No -g SPI_buswidth:1 -g TIMER_CFG:0xFFFF -g multipin_wakeup:No diff --git a/cores/VIC20/ise/VIC20.xst b/cores/VIC20/ise/VIC20.xst index f170ef0..2092859 100644 --- a/cores/VIC20/ise/VIC20.xst +++ b/cores/VIC20/ise/VIC20.xst @@ -2,6 +2,7 @@ set -tmpdir "projnav.tmp" set -xsthdpdir "xst" run -ifn VIC20.prj +-infer_ramb8 Yes -ofn VIC20 -ofmt NGC -p xc6slx9-3-tqg144 diff --git a/cores/VIC20/readme.txt b/cores/VIC20/readme.txt index beeff2e..d2f6b30 100644 --- a/cores/VIC20/readme.txt +++ b/cores/VIC20/readme.txt @@ -1,7 +1,10 @@ ---- VIC-20 port for ZX-UNO by Quest +--- VIC-20 port for ZX-UNO and modifications by Quest 2016 +--- Added 16K expansion (selectable by keyboard), 3 embeded cartridges, cassete load via audio, +--- vga switch by keyboard, PAl Kernal and timings. +--- +--- --- Original core by MikeJ --- ---- No se puede usar cassete ni cartuchos, por lo que sólo sirve para cacharrear un poco con el BASIC. README ORIGINAL: diff --git a/cores/VIC20/source/T65.vhd b/cores/VIC20/source/T65.vhd index 915c3c0..906a1b6 100644 --- a/cores/VIC20/source/T65.vhd +++ b/cores/VIC20/source/T65.vhd @@ -1,19 +1,65 @@ -- **** -- T65(b) core. In an effort to merge and maintain bug fixes .... -- +-- Ver 313 WoS January 2015 +-- Fixed issue that NMI has to be first if issued the same time as a BRK instruction is latched in +-- Now all Lorenz CPU tests on FPGAARCADE C64 core (sources used: SVN version 1021) are OK! :D :D :D +-- This is just a starting point to go for optimizations and detailed fixes (the Lorenz test can't find) +-- +-- Ver 312 WoS January 2015 +-- Undoc opcode timing fixes for $B3 (LAX iy) and $BB (LAS ay) +-- Added comments in MCode section to find handling of individual opcodes more easily +-- All "basic" Lorenz instruction test (individual functional checks, CPUTIMING check) work now with +-- actual FPGAARCADE C64 core (sources used: SVN version 1021). +-- +-- Ver 305, 306, 307, 308, 309, 310, 311 WoS January 2015 +-- Undoc opcode fixes (now all Lorenz test on instruction functionality working, except timing issues on $B3 and $BB): +-- SAX opcode +-- SHA opcode +-- SHX opcode +-- SHY opcode +-- SHS opcode +-- LAS opcode +-- alternate SBC opcode +-- fixed NOP with immediate param (caused Lorenz trap test to fail) +-- IRQ and NMI timing fixes (in conjuction with branches) +-- +-- Ver 304 WoS December 2014 +-- Undoc opcode fixes: +-- ARR opcode +-- ANE/XAA opcode +-- Corrected issue with NMI/IRQ prio (when asserted the same time) +-- +-- Ver 303 ost(ML) July 2014 +-- (Sorry for some scratchpad comments that may make little sense) +-- Mods and some 6502 undocumented instructions. +-- Not correct opcodes acc. to Lorenz tests (incomplete list): +-- NOPN (nop) +-- NOPZX (nop + byte 172) +-- NOPAX (nop + word da ... da: byte 0) +-- ASOZ (byte $07 + byte 172) +-- +-- Ver 303,302 WoS April 2014 +-- Bugfixes for NMI from foft +-- Bugfix for BRK command (and its special flag) +-- +-- Ver 300,301 WoS January 2014 +-- More merging +-- Bugfixes by ehenciak added, started tidyup *bust* -- --- Ver 301 more merging --- Ver 300 Bugfixes by ehenciak added, started tidyup *bust* -- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- +-- Latest version from www.fpgaarcade.com (original www.opencores.org) -- **** -- -- 65xx compatible microprocessor core -- --- Version : 0246 +-- FPGAARCADE SVN: $Id: T65.vhd 1347 2015-05-27 20:07:34Z wolfgang.scherr $ -- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- Copyright (c) 2002...2015 +-- Daniel Wallner (jesus opencores org) +-- Mike Johnson (mikej fpgaarcade com) +-- Wolfgang Scherr (WoS pin4 at> +-- Morten Leikvoll () -- -- All rights reserved -- @@ -43,22 +89,37 @@ -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- --- Please report bugs to the author, but before you do so, please +-- Please report bugs to the author(s), but before you do so, please -- make sure that this is not a derivative work and that -- you have the latest version of this file. -- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t65/ +-- ----- IMPORTANT NOTES ----- -- --- Limitations : +-- Limitations: +-- 65C02 and 65C816 modes are incomplete (and definitely untested after all 6502 undoc fixes) +-- 65C02 supported : inc, dec, phx, plx, phy, ply +-- 65D02 missing : bra, ora, lda, cmp, sbc, tsb*2, trb*2, stz*2, bit*2, wai, stp, jmp, bbr*8, bbs*8 +-- Some interface signals behave incorrect +-- NMI interrupt handling not nice, needs further rework (to cycle-based encoding). -- --- 65C02 and 65C816 modes are incomplete --- Undocumented instructions are not supported --- Some interface signals behaves incorrect +-- Usage: +-- The enable signal allows clock gating / throttling without using the ready signal. +-- Set it to constant '1' when using the Clk input as the CPU clock directly. -- --- File history : +-- TAKE CARE you route the DO signal back to the DI signal while R_W_n='0', +-- otherwise some undocumented opcodes won't work correctly. +-- EXAMPLE: +-- CPU : entity work.T65 +-- port map ( +-- R_W_n => cpu_rwn_s, +-- [....all other ports....] +-- DI => cpu_din_s, +-- DO => cpu_dout_s +-- ); +-- cpu_din_s <= cpu_dout_s when cpu_rwn_s='0' else +-- [....other sources from peripherals and memories...] -- --- 0246 : First release +-- ----- IMPORTANT NOTES ----- -- library IEEE; @@ -66,336 +127,363 @@ library IEEE; use IEEE.numeric_std.all; use work.T65_Pack.all; --- ehenciak 2-23-2005 : Added the enable signal so that one doesn't have to use --- the ready signal to limit the CPU. entity T65 is - port( - Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816 - Res_n : in std_logic; - Enable : in std_logic; - Clk : in std_logic; - Rdy : in std_logic; - Abort_n : in std_logic; - IRQ_n : in std_logic; - NMI_n : in std_logic; - SO_n : in std_logic; - R_W_n : out std_logic; - Sync : out std_logic; - EF : out std_logic; - MF : out std_logic; - XF : out std_logic; - ML_n : out std_logic; - VP_n : out std_logic; - VDA : out std_logic; - VPA : out std_logic; - A : out std_logic_vector(23 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816 + Res_n : in std_logic; + Enable : in std_logic; + Clk : in std_logic; + Rdy : in std_logic; + Abort_n : in std_logic; + IRQ_n : in std_logic; + NMI_n : in std_logic; + SO_n : in std_logic; + R_W_n : out std_logic; + Sync : out std_logic; + EF : out std_logic; + MF : out std_logic; + XF : out std_logic; + ML_n : out std_logic; + VP_n : out std_logic; + VDA : out std_logic; + VPA : out std_logic; + A : out std_logic_vector(23 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + DEBUG : out T_t65_dbg + ); end T65; architecture rtl of T65 is - -- Registers - signal ABC, X, Y : std_logic_vector(7 downto 0); - signal P, AD, DL : std_logic_vector(7 downto 0) := x"00"; - signal BAH : std_logic_vector(7 downto 0); - signal BAL : std_logic_vector(8 downto 0); - signal PBR : std_logic_vector(7 downto 0); - signal DBR : std_logic_vector(7 downto 0); - signal PC : unsigned(15 downto 0); - signal S : unsigned(15 downto 0); - signal EF_i : std_logic; - signal MF_i : std_logic; - signal XF_i : std_logic; + -- Registers + signal ABC, X, Y, D : std_logic_vector(15 downto 0); + signal P, AD, DL : std_logic_vector(7 downto 0) := x"00"; + signal PwithB : std_logic_vector(7 downto 0);--ML:New way to push P with correct B state to stack + signal BAH : std_logic_vector(7 downto 0); + signal BAL : std_logic_vector(8 downto 0); + signal PBR : std_logic_vector(7 downto 0); + signal DBR : std_logic_vector(7 downto 0); + signal PC : unsigned(15 downto 0); + signal S : unsigned(15 downto 0); + signal EF_i : std_logic; + signal MF_i : std_logic; + signal XF_i : std_logic; - signal IR : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); + signal IR : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); - signal Mode_r : std_logic_vector(1 downto 0); - signal ALU_Op_r : std_logic_vector(3 downto 0); - signal Write_Data_r : std_logic_vector(2 downto 0); - signal Set_Addr_To_r : std_logic_vector(1 downto 0); - signal PCAdder : unsigned(8 downto 0); + signal Mode_r : std_logic_vector(1 downto 0); + signal ALU_Op_r : T_ALU_Op; + signal Write_Data_r : T_Write_Data; + signal Set_Addr_To_r : T_Set_Addr_To; + signal PCAdder : unsigned(8 downto 0); - signal RstCycle : std_logic; - signal IRQCycle : std_logic; - signal NMICycle : std_logic; + signal RstCycle : std_logic; + signal IRQCycle : std_logic; + signal NMICycle : std_logic; - signal B_o : std_logic; - signal SO_n_o : std_logic; - signal IRQ_n_o : std_logic; - signal NMI_n_o : std_logic; - signal NMIAct : std_logic; + signal SO_n_o : std_logic; + signal IRQ_n_o : std_logic; + signal NMI_n_o : std_logic; + signal NMIAct : std_logic; - signal Break : std_logic; + signal Break : std_logic; - -- ALU signals - signal BusA : std_logic_vector(7 downto 0); - signal BusA_r : std_logic_vector(7 downto 0); - signal BusB : std_logic_vector(7 downto 0); - signal ALU_Q : std_logic_vector(7 downto 0); - signal P_Out : std_logic_vector(7 downto 0); + -- ALU signals + signal BusA : std_logic_vector(7 downto 0); + signal BusA_r : std_logic_vector(7 downto 0); + signal BusB : std_logic_vector(7 downto 0); + signal BusB_r : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal P_Out : std_logic_vector(7 downto 0); - -- Micro code outputs - signal LCycle : std_logic_vector(2 downto 0); - signal ALU_Op : std_logic_vector(3 downto 0); - signal Set_BusA_To : std_logic_vector(2 downto 0); - signal Set_Addr_To : std_logic_vector(1 downto 0); - signal Write_Data : std_logic_vector(2 downto 0); - signal Jump : std_logic_vector(1 downto 0); - signal BAAdd : std_logic_vector(1 downto 0); - signal BreakAtNA : std_logic; - signal ADAdd : std_logic; - signal AddY : std_logic; - signal PCAdd : std_logic; - signal Inc_S : std_logic; - signal Dec_S : std_logic; - signal LDA : std_logic; - signal LDP : std_logic; - signal LDX : std_logic; - signal LDY : std_logic; - signal LDS : std_logic; - signal LDDI : std_logic; - signal LDALU : std_logic; - signal LDAD : std_logic; - signal LDBAL : std_logic; - signal LDBAH : std_logic; - signal SaveP : std_logic; - signal Write : std_logic; + -- Micro code outputs + signal LCycle : std_logic_vector(2 downto 0); + signal ALU_Op : T_ALU_Op; + signal Set_BusA_To : T_Set_BusA_To; + signal Set_Addr_To : T_Set_Addr_To; + signal Write_Data : T_Write_Data; + signal Jump : std_logic_vector(1 downto 0); + signal BAAdd : std_logic_vector(1 downto 0); + signal BreakAtNA : std_logic; + signal ADAdd : std_logic; + signal AddY : std_logic; + signal PCAdd : std_logic; + signal Inc_S : std_logic; + signal Dec_S : std_logic; + signal LDA : std_logic; + signal LDP : std_logic; + signal LDX : std_logic; + signal LDY : std_logic; + signal LDS : std_logic; + signal LDDI : std_logic; + signal LDALU : std_logic; + signal LDAD : std_logic; + signal LDBAL : std_logic; + signal LDBAH : std_logic; + signal SaveP : std_logic; + signal Write : std_logic; - signal really_rdy : std_logic; - signal R_W_n_i : std_logic; + signal Res_n_i : std_logic; + signal Res_n_d : std_logic; + + signal really_rdy : std_logic; + signal WRn_i : std_logic; + + signal NMI_entered : std_logic; begin + -- gate Rdy with read/write to make an "OK, it's really OK to stop the processor + really_rdy <= Rdy or not(WRn_i); + Sync <= '1' when MCycle = "000" else '0'; + EF <= EF_i; + MF <= MF_i; + XF <= XF_i; + R_W_n <= WRn_i; + ML_n <= '0' when IR(7 downto 6) /= "10" and IR(2 downto 1) = "11" and MCycle(2 downto 1) /= "00" else '1'; + VP_n <= '0' when IRQCycle = '1' and (MCycle = "101" or MCycle = "110") else '1'; + VDA <= '1' when Set_Addr_To_r /= Set_Addr_To_PBR else '0'; + VPA <= '1' when Jump(1) = '0' else '0'; - -- ehenciak : gate Rdy with read/write to make an "OK, it's - -- really OK to stop the processor now if Rdy is - -- deasserted" signal - really_rdy <= Rdy or not(R_W_n_i); + -- debugging signals + DEBUG.I <= IR; + DEBUG.A <= ABC(7 downto 0); + DEBUG.X <= X(7 downto 0); + DEBUG.Y <= Y(7 downto 0); + DEBUG.S <= std_logic_vector(S(7 downto 0)); + DEBUG.P <= P; - -- ehenciak : Drive R_W_n_i off chip. - R_W_n <= R_W_n_i; + mcode : entity work.T65_MCode + port map( +--inputs + Mode => Mode_r, + IR => IR, + MCycle => MCycle, + P => P, +--outputs + LCycle => LCycle, + ALU_Op => ALU_Op, + Set_BusA_To => Set_BusA_To, + Set_Addr_To => Set_Addr_To, + Write_Data => Write_Data, + Jump => Jump, + BAAdd => BAAdd, + BreakAtNA => BreakAtNA, + ADAdd => ADAdd, + AddY => AddY, + PCAdd => PCAdd, + Inc_S => Inc_S, + Dec_S => Dec_S, + LDA => LDA, + LDP => LDP, + LDX => LDX, + LDY => LDY, + LDS => LDS, + LDDI => LDDI, + LDALU => LDALU, + LDAD => LDAD, + LDBAL => LDBAL, + LDBAH => LDBAH, + SaveP => SaveP, + Write => Write + ); - Sync <= '1' when MCycle = "000" else '0'; - EF <= EF_i; - MF <= MF_i; - XF <= XF_i; - ML_n <= '0' when IR(7 downto 6) /= "10" and IR(2 downto 1) = "11" and MCycle(2 downto 1) /= "00" else '1'; - VP_n <= '0' when IRQCycle = '1' and (MCycle = "101" or MCycle = "110") else '1'; - VDA <= '1' when Set_Addr_To_r /= "000" else '0'; -- Incorrect !!!!!!!!!!!! - VPA <= '1' when Jump(1) = '0' else '0'; -- Incorrect !!!!!!!!!!!! + alu : entity work.T65_ALU + port map( + Mode => Mode_r, + Op => ALU_Op_r, + BusA => BusA_r, + BusB => BusB, + P_In => P, + P_Out => P_Out, + Q => ALU_Q + ); - mcode : T65_MCode - port map( - Mode => Mode_r, - IR => IR, - MCycle => MCycle, - P => P, - LCycle => LCycle, - ALU_Op => ALU_Op, - Set_BusA_To => Set_BusA_To, - Set_Addr_To => Set_Addr_To, - Write_Data => Write_Data, - Jump => Jump, - BAAdd => BAAdd, - BreakAtNA => BreakAtNA, - ADAdd => ADAdd, - AddY => AddY, - PCAdd => PCAdd, - Inc_S => Inc_S, - Dec_S => Dec_S, - LDA => LDA, - LDP => LDP, - LDX => LDX, - LDY => LDY, - LDS => LDS, - LDDI => LDDI, - LDALU => LDALU, - LDAD => LDAD, - LDBAL => LDBAL, - LDBAH => LDBAH, - SaveP => SaveP, - Write => Write - ); + -- the 65xx design requires at least two clock cycles before + -- starting its reset sequence (according to datasheet) + process (Res_n_i, Clk) + begin + if Res_n = '0' then + Res_n_i <= '0'; + Res_n_d <= '0'; + elsif Clk'event and Clk = '1' then + Res_n_i <= Res_n_d; + Res_n_d <= '1'; + end if; + end process; - alu : T65_ALU - port map( - Mode => Mode_r, - Op => ALU_Op_r, - BusA => BusA_r, - BusB => BusB, - P_In => P, - P_Out => P_Out, - Q => ALU_Q - ); + process (Res_n_i, Clk) + begin + if Res_n_i = '0' then + PC <= (others => '0'); -- Program Counter + IR <= "00000000"; + S <= (others => '0'); -- Dummy + D <= (others => '0'); + PBR <= (others => '0'); + DBR <= (others => '0'); - process (Res_n, Clk) - begin - if Res_n = '0' then - PC <= (others => '0'); -- Program Counter - IR <= "00000000"; - S <= (others => '0'); -- Dummy !!!!!!!!!!!!!!!!!!!!! - --D <= (others => '0'); - PBR <= (others => '0'); - DBR <= (others => '0'); + Mode_r <= (others => '0'); + ALU_Op_r <= ALU_OP_BIT; + Write_Data_r <= Write_Data_DL; + Set_Addr_To_r <= Set_Addr_To_PBR; - Mode_r <= (others => '0'); - ALU_Op_r <= "1100"; - Write_Data_r <= "000"; - Set_Addr_To_r <= "00"; + WRn_i <= '1'; + EF_i <= '1'; + MF_i <= '1'; + XF_i <= '1'; - R_W_n_i <= '1'; - EF_i <= '1'; - MF_i <= '1'; - XF_i <= '1'; + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + WRn_i <= not Write or RstCycle; - elsif Clk'event and Clk = '1' then - if (Enable = '1') then - if (really_rdy = '1') then - R_W_n_i <= not Write or RstCycle; + D <= (others => '1'); -- Dummy + PBR <= (others => '1'); -- Dummy + DBR <= (others => '1'); -- Dummy + EF_i <= '0'; -- Dummy + MF_i <= '0'; -- Dummy + XF_i <= '0'; -- Dummy - --D <= (others => '1'); -- Dummy - PBR <= (others => '1'); -- Dummy - DBR <= (others => '1'); -- Dummy - EF_i <= '0'; -- Dummy - MF_i <= '0'; -- Dummy - XF_i <= '0'; -- Dummy + if MCycle = "000" then + Mode_r <= Mode; - if MCycle = "000" then - Mode_r <= Mode; + if IRQCycle = '0' and NMICycle = '0' then + PC <= PC + 1; + end if; - if IRQCycle = '0' and NMICycle = '0' then - PC <= PC + 1; - end if; + if IRQCycle = '1' or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DI; + end if; - if IRQCycle = '1' or NMICycle = '1' then - IR <= "00000000"; - else - IR <= DI; - end if; - end if; + if LDS = '1' then -- LAS won't work properly if not limited to machine cycle 0 + S(7 downto 0) <= unsigned(ALU_Q); + end if; + end if; - ALU_Op_r <= ALU_Op; - Write_Data_r <= Write_Data; - if Break = '1' then - Set_Addr_To_r <= "00"; - else - Set_Addr_To_r <= Set_Addr_To; - end if; + ALU_Op_r <= ALU_Op; + Write_Data_r <= Write_Data; + if Break = '1' then + Set_Addr_To_r <= Set_Addr_To_PBR; + else + Set_Addr_To_r <= Set_Addr_To; + end if; - if Inc_S = '1' then - S <= S + 1; - end if; - if Dec_S = '1' and RstCycle = '0' then - S <= S - 1; - end if; - if LDS = '1' then - S(7 downto 0) <= unsigned(ALU_Q); - end if; + if Inc_S = '1' then + S <= S + 1; + end if; + if Dec_S = '1' and RstCycle = '0' then + S <= S - 1; + end if; - if IR = "00000000" and MCycle = "001" and IRQCycle = '0' and NMICycle = '0' then - PC <= PC + 1; - end if; - -- - -- jump control logic - -- - case Jump is - when "01" => - PC <= PC + 1; + if IR = "00000000" and MCycle = "001" and IRQCycle = '0' and NMICycle = '0' then + PC <= PC + 1; + end if; + -- + -- jump control logic + -- + case Jump is + when "01" => + PC <= PC + 1; + when "10" => + PC <= unsigned(DI & DL); + when "11" => + if PCAdder(8) = '1' then + if DL(7) = '0' then + PC(15 downto 8) <= PC(15 downto 8) + 1; + else + PC(15 downto 8) <= PC(15 downto 8) - 1; + end if; + end if; + PC(7 downto 0) <= PCAdder(7 downto 0); + when others => null; + end case; + end if; + end if; + end if; + end process; - when "10" => - PC <= unsigned(DI & DL); + PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1' + else "0" & PC(7 downto 0); - when "11" => - if PCAdder(8) = '1' then - if DL(7) = '0' then - PC(15 downto 8) <= PC(15 downto 8) + 1; - else - PC(15 downto 8) <= PC(15 downto 8) - 1; - end if; - end if; - PC(7 downto 0) <= PCAdder(7 downto 0); + process (Res_n_i, Clk) + variable tmpP:std_logic_vector(7 downto 0);--Lets try to handle loading P at mcycle=0 and set/clk flags at same cycle + begin + if Res_n_i = '0' then + P <= x"00"; -- ensure we have nothing set on reset + elsif Clk'event and Clk = '1' then + tmpP:=P; + if (Enable = '1') then + if (really_rdy = '1') then + if MCycle = "000" then + if LDA = '1' then + ABC(7 downto 0) <= ALU_Q; + end if; + if LDX = '1' then + X(7 downto 0) <= ALU_Q; + end if; + if LDY = '1' then + Y(7 downto 0) <= ALU_Q; + end if; + if (LDA or LDX or LDY) = '1' then + tmpP:=P_Out; + end if; + end if; + if SaveP = '1' then + tmpP:=P_Out; + end if; + if LDP = '1' then + tmpP:=ALU_Q; + end if; + if IR(4 downto 0) = "11000" then + case IR(7 downto 5) is + when "000" =>--0x18(clc) + tmpP(Flag_C) := '0'; + when "001" =>--0x38(sec) + tmpP(Flag_C) := '1'; + when "010" =>--0x58(cli) + tmpP(Flag_I) := '0'; + when "011" =>--0x78(sei) + tmpP(Flag_I) := '1'; + when "101" =>--0xb8(clv) + tmpP(Flag_V) := '0'; + when "110" =>--0xd8(cld) + tmpP(Flag_D) := '0'; + when "111" =>--0xf8(sed) + tmpP(Flag_D) := '1'; + when others => + end case; + end if; + tmpP(Flag_B) := '1'; + if IR = "00000000" and MCycle = "100" and RstCycle = '0' then + --This should happen after P has been pushed to stack + tmpP(Flag_I) := '1'; + end if; + if SO_n_o = '1' and SO_n = '0' then + tmpP(Flag_V) := '1'; + end if; + if RstCycle = '1' then + tmpP(Flag_I) := '0'; + tmpP(Flag_D) := '0'; + end if; + tmpP(Flag_1) := '1'; - when others => null; - end case; - end if; - end if; - end if; - end process; + P<=tmpP;--new way - PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1' - else "0" & PC(7 downto 0); - - process (Clk) - begin - if Clk'event and Clk = '1' then - if (Enable = '1') then - if (really_rdy = '1') then - if MCycle = "000" then - if LDA = '1' then - ABC(7 downto 0) <= ALU_Q; - end if; - if LDX = '1' then - X(7 downto 0) <= ALU_Q; - end if; - if LDY = '1' then - Y(7 downto 0) <= ALU_Q; - end if; - if (LDA or LDX or LDY) = '1' then - P <= P_Out; - end if; - end if; - if SaveP = '1' then - P <= P_Out; - end if; - if LDP = '1' then - P <= ALU_Q; - end if; - if IR(4 downto 0) = "11000" then - case IR(7 downto 5) is - when "000" => - P(Flag_C) <= '0'; - when "001" => - P(Flag_C) <= '1'; - when "010" => - P(Flag_I) <= '0'; - when "011" => - P(Flag_I) <= '1'; - when "101" => - P(Flag_V) <= '0'; - when "110" => - P(Flag_D) <= '0'; - when "111" => - P(Flag_D) <= '1'; - when others => - end case; - end if; - if IR = "00000000" and MCycle = "011" and RstCycle = '0' and NMICycle = '0' and IRQCycle = '0' then - P(Flag_B) <= '1'; - end if; - if IR = "00000000" and MCycle = "100" and RstCycle = '0' and (NMICycle = '1' or IRQCycle = '1') then - P(Flag_I) <= '1'; - P(Flag_B) <= B_o; - end if; - if SO_n_o = '1' and SO_n = '0' then - P(Flag_V) <= '1'; - end if; - if RstCycle = '1' and Mode_r /= "00" then - P(Flag_1) <= '1'; - P(Flag_D) <= '0'; - P(Flag_I) <= '1'; - end if; - P(Flag_1) <= '1'; - - B_o <= P(Flag_B); - SO_n_o <= SO_n; - IRQ_n_o <= IRQ_n; - NMI_n_o <= NMI_n; - end if; - end if; - end if; - end process; + SO_n_o <= SO_n; + if IR(4 downto 0)/="10000" or Jump/="01" then -- delay interrupts during branches (checked with Lorenz test and real 6510), not best way yet, though - but works... + IRQ_n_o <= IRQ_n; + end if; + end if; + -- detect nmi even if not rdy + if IR(4 downto 0)/="10000" or Jump/="01" then -- delay interrupts during branches (checked with Lorenz test and real 6510) not best way yet, though - but works... + NMI_n_o <= NMI_n; + end if; + end if; + end if; + end process; --------------------------------------------------------------------------- -- @@ -403,109 +491,133 @@ begin -- --------------------------------------------------------------------------- - process (Res_n, Clk) - begin - if Res_n = '0' then - BusA_r <= (others => '0'); - BusB <= (others => '0'); - AD <= (others => '0'); - BAL <= (others => '0'); - BAH <= (others => '0'); - DL <= (others => '0'); - elsif Clk'event and Clk = '1' then - if (Enable = '1') then - if (Rdy = '1') then - BusA_r <= BusA; - BusB <= DI; + process (Res_n_i, Clk) + begin + if Res_n_i = '0' then + BusA_r <= (others => '0'); + BusB <= (others => '0'); + BusB_r <= (others => '0'); + AD <= (others => '0'); + BAL <= (others => '0'); + BAH <= (others => '0'); + DL <= (others => '0'); + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + NMI_entered <= '0'; + if (really_rdy = '1') then + BusA_r <= BusA; + BusB <= DI; - case BAAdd is - when "01" => - -- BA Inc - AD <= std_logic_vector(unsigned(AD) + 1); - BAL <= std_logic_vector(unsigned(BAL) + 1); - when "10" => - -- BA Add - BAL <= std_logic_vector(resize(unsigned(BAL(7 downto 0)),9) + resize(unsigned(BusA),9)); - when "11" => - -- BA Adj - if BAL(8) = '1' then - BAH <= std_logic_vector(unsigned(BAH) + 1); - end if; - when others => - end case; + -- not really nice, but no better way found yet ! + if Set_Addr_To_r = Set_Addr_To_PBR or Set_Addr_To_r = Set_Addr_To_ZPG then + BusB_r <= std_logic_vector(unsigned(DI(7 downto 0)) + 1); -- required for SHA + end if; - -- ehenciak : modified to use Y register as well (bugfix) - if ADAdd = '1' then - if (AddY = '1') then - AD <= std_logic_vector(unsigned(AD) + unsigned(Y(7 downto 0))); - else - AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0))); - end if; - end if; + case BAAdd is + when "01" => + -- BA Inc + AD <= std_logic_vector(unsigned(AD) + 1); + BAL <= std_logic_vector(unsigned(BAL) + 1); + when "10" => + -- BA Add + BAL <= std_logic_vector(resize(unsigned(BAL(7 downto 0)),9) + resize(unsigned(BusA),9)); + when "11" => + -- BA Adj + if BAL(8) = '1' then + BAH <= std_logic_vector(unsigned(BAH) + 1); + end if; + when others => + end case; - if IR = "00000000" then - BAL <= (others => '1'); - BAH <= (others => '1'); - if RstCycle = '1' then - BAL(2 downto 0) <= "100"; - elsif NMICycle = '1' then - BAL(2 downto 0) <= "010"; - else - BAL(2 downto 0) <= "110"; - end if; - if Set_addr_To_r = "11" then - BAL(0) <= '1'; - end if; - end if; + -- modified to use Y register as well + if ADAdd = '1' then + if (AddY = '1') then + AD <= std_logic_vector(unsigned(AD) + unsigned(Y(7 downto 0))); + else + AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0))); + end if; + end if; + if IR = "00000000" then + BAL <= (others => '1'); + BAH <= (others => '1'); + if RstCycle = '1' then + BAL(2 downto 0) <= "100"; + elsif NMICycle = '1' or (NMIAct = '1' and MCycle="100") or NMI_entered='1' then + BAL(2 downto 0) <= "010"; + if MCycle="100" then + NMI_entered <= '1'; + end if; + else + BAL(2 downto 0) <= "110"; + end if; + if Set_addr_To_r = Set_Addr_To_BA then + BAL(0) <= '1'; + end if; + end if; - if LDDI = '1' then - DL <= DI; - end if; - if LDALU = '1' then - DL <= ALU_Q; - end if; - if LDAD = '1' then - AD <= DI; - end if; - if LDBAL = '1' then - BAL(7 downto 0) <= DI; - end if; - if LDBAH = '1' then - BAH <= DI; - end if; - end if; - end if; - end if; - end process; + if LDDI = '1' then + DL <= DI; + end if; + if LDALU = '1' then + DL <= ALU_Q; + end if; + if LDAD = '1' then + AD <= DI; + end if; + if LDBAL = '1' then + BAL(7 downto 0) <= DI; + end if; + if LDBAH = '1' then + BAH <= DI; + end if; + end if; + end if; + end if; + end process; - Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8)); + Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8)); + with Set_BusA_To select + BusA <= + DI when Set_BusA_To_DI, + ABC(7 downto 0) when Set_BusA_To_ABC, + X(7 downto 0) when Set_BusA_To_X, + Y(7 downto 0) when Set_BusA_To_Y, + std_logic_vector(S(7 downto 0)) when Set_BusA_To_S, + P when Set_BusA_To_P, + ABC(7 downto 0) and DI when Set_BusA_To_DA, + (ABC(7 downto 0) or x"ee") and DI when Set_BusA_To_DAO,--ee for OAL instruction. constant may be different on other platforms.TODO:Move to generics + (ABC(7 downto 0) or x"ee") and DI and X(7 downto 0) when Set_BusA_To_DAX,--XAA, ee for OAL instruction. constant may be different on other platforms.TODO:Move to generics + ABC(7 downto 0) and X(7 downto 0) when Set_BusA_To_AAX,--SAX, SHA + (others => '-') when Set_BusA_To_DONTCARE;--Can probably remove this - with Set_BusA_To select - BusA <= DI when "000", - ABC(7 downto 0) when "001", - X(7 downto 0) when "010", - Y(7 downto 0) when "011", - std_logic_vector(S(7 downto 0)) when "100", - P when "101", - (others => '-') when others; + with Set_Addr_To_r select + A <= + "0000000000000001" & std_logic_vector(S(7 downto 0)) when Set_Addr_To_SP, + DBR & "00000000" & AD when Set_Addr_To_ZPG, + "00000000" & BAH & BAL(7 downto 0) when Set_Addr_To_BA, + PBR & std_logic_vector(PC(15 downto 8)) & std_logic_vector(PCAdder(7 downto 0)) when Set_Addr_To_PBR; - with Set_Addr_To_r select - A <= "0000000000000001" & std_logic_vector(S(7 downto 0)) when "01", - DBR & "00000000" & AD when "10", - "00000000" & BAH & BAL(7 downto 0) when "11", - PBR & std_logic_vector(PC(15 downto 8)) & std_logic_vector(PCAdder(7 downto 0)) when others; + -- This is the P that gets pushed on stack with correct B flag. I'm not sure if NMI also clears B, but I guess it does. + PwithB<=(P and x"ef") when (IRQCycle='1' or NMICycle='1') else P; + + with Write_Data_r select + DO <= + DL when Write_Data_DL, + ABC(7 downto 0) when Write_Data_ABC, + X(7 downto 0) when Write_Data_X, + Y(7 downto 0) when Write_Data_Y, + std_logic_vector(S(7 downto 0)) when Write_Data_S, + PwithB when Write_Data_P, + std_logic_vector(PC(7 downto 0)) when Write_Data_PCL, + std_logic_vector(PC(15 downto 8)) when Write_Data_PCH, + ABC(7 downto 0) and X(7 downto 0) when Write_Data_AX, + ABC(7 downto 0) and X(7 downto 0) and BusB_r(7 downto 0) when Write_Data_AXB, -- no better way found yet... + X(7 downto 0) and BusB_r(7 downto 0) when Write_Data_XB, -- no better way found yet... + Y(7 downto 0) and BusB_r(7 downto 0) when Write_Data_YB, -- no better way found yet... + (others=>'-') when Write_Data_DONTCARE;--Can probably remove this - with Write_Data_r select - DO <= DL when "000", - ABC(7 downto 0) when "001", - X(7 downto 0) when "010", - Y(7 downto 0) when "011", - std_logic_vector(S(7 downto 0)) when "100", - P when "101", - std_logic_vector(PC(7 downto 0)) when "110", - std_logic_vector(PC(15 downto 8)) when others; ------------------------------------------------------------------------- -- @@ -513,40 +625,42 @@ begin -- ------------------------------------------------------------------------- - process (Res_n, Clk) - begin - if Res_n = '0' then - MCycle <= "001"; - RstCycle <= '1'; - IRQCycle <= '0'; - NMICycle <= '0'; - NMIAct <= '0'; - elsif Clk'event and Clk = '1' then - if (Enable = '1') then - if (really_rdy = '1') then - if MCycle = LCycle or Break = '1' then - MCycle <= "000"; - RstCycle <= '0'; - IRQCycle <= '0'; - NMICycle <= '0'; - if NMIAct = '1' then - NMICycle <= '1'; - elsif IRQ_n_o = '0' and P(Flag_I) = '0' then - IRQCycle <= '1'; - end if; - else - MCycle <= std_logic_vector(unsigned(MCycle) + 1); - end if; - - if NMICycle = '1' then - NMIAct <= '0'; - end if; - if NMI_n_o = '1' and NMI_n = '0' then - NMIAct <= '1'; - end if; - end if; - end if; - end if; - end process; + process (Res_n_i, Clk) + begin + if Res_n_i = '0' then + MCycle <= "001"; + RstCycle <= '1'; + IRQCycle <= '0'; + NMICycle <= '0'; + NMIAct <= '0'; + elsif Clk'event and Clk = '1' then + if (Enable = '1') then + if (really_rdy = '1') then + if MCycle = LCycle or Break = '1' then + MCycle <= "000"; + RstCycle <= '0'; + IRQCycle <= '0'; + NMICycle <= '0'; + if NMIAct = '1' and IR/=x"00" then -- delay NMI further if we just executed a BRK + NMICycle <= '1'; + NMIAct <= '0'; -- reset NMI edge detector if we start processing the NMI + elsif IRQ_n_o = '0' and P(Flag_I) = '0' then + IRQCycle <= '1'; + end if; + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + end if; + --detect NMI even if not rdy + if NMI_n_o = '1' and (NMI_n = '0' and (IR(4 downto 0)/="10000" or Jump/="01")) then -- branches have influence on NMI start (not best way yet, though - but works...) + NMIAct <= '1'; + end if; + -- we entered NMI during BRK instruction + if NMI_entered='1' then + NMIAct <= '0'; + end if; + end if; + end if; + end process; end; diff --git a/cores/VIC20/source/T65_ALU.vhd b/cores/VIC20/source/T65_ALU.vhd index b1f6d63..b3e083b 100644 --- a/cores/VIC20/source/T65_ALU.vhd +++ b/cores/VIC20/source/T65_ALU.vhd @@ -1,18 +1,18 @@ -- **** -- T65(b) core. In an effort to merge and maintain bug fixes .... -- --- --- Ver 300 Bugfixes by ehenciak added --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- See list of changes in T65 top file (T65.vhd)... -- -- **** +-- 65xx compatible microprocessor core -- --- 6502 compatible microprocessor core +-- FPGAARCADE SVN: $Id: T65_ALU.vhd 1234 2015-02-28 20:14:50Z wolfgang.scherr $ -- --- Version : 0245 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- Copyright (c) 2002...2015 +-- Daniel Wallner (jesus opencores org) +-- Mike Johnson (mikej fpgaarcade com) +-- Wolfgang Scherr (WoS pin4 at> +-- Morten Leikvoll () -- -- All rights reserved -- @@ -42,19 +42,12 @@ -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- --- Please report bugs to the author, but before you do so, please +-- Please report bugs to the author(s), but before you do so, please -- make sure that this is not a derivative work and that -- you have the latest version of this file. -- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t65/ --- -- Limitations : --- --- File history : --- --- 0245 : First version --- +-- See in T65 top file (T65.vhd)... library IEEE; use IEEE.std_logic_1164.all; @@ -62,199 +55,237 @@ use IEEE.numeric_std.all; use work.T65_Pack.all; entity T65_ALU is - port( - Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 - Op : in std_logic_vector(3 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - P_In : in std_logic_vector(7 downto 0); - P_Out : out std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0) - ); + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + Op : in T_ALU_OP; + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + P_In : in std_logic_vector(7 downto 0); + P_Out : out std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0) + ); end T65_ALU; architecture rtl of T65_ALU is - -- AddSub variables (temporary signals) - signal ADC_Z : std_logic; - signal ADC_C : std_logic; - signal ADC_V : std_logic; - signal ADC_N : std_logic; - signal ADC_Q : std_logic_vector(7 downto 0); - signal SBC_Z : std_logic; - signal SBC_C : std_logic; - signal SBC_V : std_logic; - signal SBC_N : std_logic; - signal SBC_Q : std_logic_vector(7 downto 0); + -- AddSub variables (temporary signals) + signal ADC_Z : std_logic; + signal ADC_C : std_logic; + signal ADC_V : std_logic; + signal ADC_N : std_logic; + signal ADC_Q : std_logic_vector(7 downto 0); + signal SBC_Z : std_logic; + signal SBC_C : std_logic; + signal SBC_V : std_logic; + signal SBC_N : std_logic; + signal SBC_Q : std_logic_vector(7 downto 0); + signal SBX_Q : std_logic_vector(7 downto 0); begin - process (P_In, BusA, BusB) - variable AL : unsigned(6 downto 0); - variable AH : unsigned(6 downto 0); - variable C : std_logic; - begin - AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7); - AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); + process (P_In, BusA, BusB) + variable AL : unsigned(6 downto 0); + variable AH : unsigned(6 downto 0); + variable C : std_logic; + begin + AL := resize(unsigned(BusA(3 downto 0) & P_In(Flag_C)), 7) + resize(unsigned(BusB(3 downto 0) & "1"), 7); + AH := resize(unsigned(BusA(7 downto 4) & AL(5)), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); -- pragma translate_off - if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; - if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; + if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; + if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; -- pragma translate_on - if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then - ADC_Z <= '1'; - else - ADC_Z <= '0'; - end if; + if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then + ADC_Z <= '1'; + else + ADC_Z <= '0'; + end if; - if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then - AL(6 downto 1) := AL(6 downto 1) + 6; - end if; + if AL(5 downto 1) > 9 and P_In(Flag_D) = '1' then + AL(6 downto 1) := AL(6 downto 1) + 6; + end if; - C := AL(6) or AL(5); - AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); + C := AL(6) or AL(5); + AH := resize(unsigned(BusA(7 downto 4) & C), 7) + resize(unsigned(BusB(7 downto 4) & "1"), 7); - ADC_N <= AH(4); - ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7)); + ADC_N <= AH(4); + ADC_V <= (AH(4) xor BusA(7)) and not (BusA(7) xor BusB(7)); -- pragma translate_off - if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; + if is_x(std_logic_vector(AH)) then AH := "0000000"; end if; -- pragma translate_on - if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then - AH(6 downto 1) := AH(6 downto 1) + 6; - end if; + if AH(5 downto 1) > 9 and P_In(Flag_D) = '1' then + AH(6 downto 1) := AH(6 downto 1) + 6; + end if; - ADC_C <= AH(6) or AH(5); + ADC_C <= AH(6) or AH(5); - ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); - end process; + ADC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); + end process; - process (Op, P_In, BusA, BusB) - variable AL : unsigned(6 downto 0); - variable AH : unsigned(5 downto 0); - variable C : std_logic; - begin - C := P_In(Flag_C) or not Op(0); - AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6); - AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6); + process (Op, P_In, BusA, BusB) + variable AL : unsigned(6 downto 0); + variable AH : unsigned(5 downto 0); + variable C : std_logic; + variable CT : std_logic; + begin + CT:='0'; + if( Op=ALU_OP_AND or --"0001" These OpCodes used to have LSB set + Op=ALU_OP_ADC or --"0011" + Op=ALU_OP_EQ2 or --"0101" + Op=ALU_OP_SBC or --"0111" + Op=ALU_OP_ROL or --"1001" + Op=ALU_OP_ROR or --"1011" +-- Op=ALU_OP_EQ3 or --"1101" + Op=ALU_OP_INC --"1111" + ) then + CT:='1'; + end if; --- pragma translate_off - if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; - if is_x(std_logic_vector(AH)) then AH := "000000"; end if; --- pragma translate_on + C := P_In(Flag_C) or not CT;--was: or not Op(0); + AL := resize(unsigned(BusA(3 downto 0) & C), 7) - resize(unsigned(BusB(3 downto 0) & "1"), 6); + AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(5)), 6); - if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then - SBC_Z <= '1'; - else - SBC_Z <= '0'; - end if; + -- pragma translate_off + if is_x(std_logic_vector(AL)) then AL := "0000000"; end if; + if is_x(std_logic_vector(AH)) then AH := "000000"; end if; + -- pragma translate_on - SBC_C <= not AH(5); - SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7)); - SBC_N <= AH(4); + if AL(4 downto 1) = 0 and AH(4 downto 1) = 0 then + SBC_Z <= '1'; + else + SBC_Z <= '0'; + end if; - if P_In(Flag_D) = '1' then - if AL(5) = '1' then - AL(5 downto 1) := AL(5 downto 1) - 6; - end if; - AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6); - if AH(5) = '1' then - AH(5 downto 1) := AH(5 downto 1) - 6; - end if; - end if; + SBC_C <= not AH(5); + SBC_V <= (AH(4) xor BusA(7)) and (BusA(7) xor BusB(7)); + SBC_N <= AH(4); - SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); - end process; + SBX_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); - process (Op, P_In, BusA, BusB, - ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q, - SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q) - variable Q_t : std_logic_vector(7 downto 0); - begin - -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC - -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC - P_Out <= P_In; - Q_t := BusA; - case Op(3 downto 0) is - when "0000" => - -- ORA - Q_t := BusA or BusB; - when "0001" => - -- AND - Q_t := BusA and BusB; - when "0010" => - -- EOR - Q_t := BusA xor BusB; - when "0011" => - -- ADC - P_Out(Flag_V) <= ADC_V; - P_Out(Flag_C) <= ADC_C; - Q_t := ADC_Q; - when "0101" | "1101" => - -- LDA - when "0110" => - -- CMP - P_Out(Flag_C) <= SBC_C; - when "0111" => - -- SBC - P_Out(Flag_V) <= SBC_V; - P_Out(Flag_C) <= SBC_C; - Q_t := SBC_Q; - when "1000" => - -- ASL - Q_t := BusA(6 downto 0) & "0"; - P_Out(Flag_C) <= BusA(7); - when "1001" => - -- ROL - Q_t := BusA(6 downto 0) & P_In(Flag_C); - P_Out(Flag_C) <= BusA(7); - when "1010" => - -- LSR - Q_t := "0" & BusA(7 downto 1); - P_Out(Flag_C) <= BusA(0); - when "1011" => - -- ROR - Q_t := P_In(Flag_C) & BusA(7 downto 1); - P_Out(Flag_C) <= BusA(0); - when "1100" => - -- BIT - P_Out(Flag_V) <= BusB(6); - when "1110" => - -- DEC - Q_t := std_logic_vector(unsigned(BusA) - 1); - when "1111" => - -- INC - Q_t := std_logic_vector(unsigned(BusA) + 1); - when others => - end case; + if P_In(Flag_D) = '1' then + if AL(5) = '1' then + AL(5 downto 1) := AL(5 downto 1) - 6; + end if; + AH := resize(unsigned(BusA(7 downto 4) & "0"), 6) - resize(unsigned(BusB(7 downto 4) & AL(6)), 6); + if AH(5) = '1' then + AH(5 downto 1) := AH(5 downto 1) - 6; + end if; + end if; - case Op(3 downto 0) is - when "0011" => - P_Out(Flag_N) <= ADC_N; - P_Out(Flag_Z) <= ADC_Z; - when "0110" | "0111" => - P_Out(Flag_N) <= SBC_N; - P_Out(Flag_Z) <= SBC_Z; - when "0100" => - when "1100" => - P_Out(Flag_N) <= BusB(7); - if (BusA and BusB) = "00000000" then - P_Out(Flag_Z) <= '1'; - else - P_Out(Flag_Z) <= '0'; - end if; - when others => - P_Out(Flag_N) <= Q_t(7); - if Q_t = "00000000" then - P_Out(Flag_Z) <= '1'; - else - P_Out(Flag_Z) <= '0'; - end if; - end case; + SBC_Q <= std_logic_vector(AH(4 downto 1) & AL(4 downto 1)); + end process; - Q <= Q_t; - end process; + process (Op, P_In, BusA, BusB, + ADC_Z, ADC_C, ADC_V, ADC_N, ADC_Q, + SBC_Z, SBC_C, SBC_V, SBC_N, SBC_Q) + variable Q_t : std_logic_vector(7 downto 0); + variable Q2_t : std_logic_vector(7 downto 0); + begin + -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC + -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC + P_Out <= P_In; + Q_t := BusA; + case Op is + when ALU_OP_OR=> + Q_t := BusA or BusB; + when ALU_OP_AND=> + Q_t := BusA and BusB; + when ALU_OP_EOR=> + Q_t := BusA xor BusB; + when ALU_OP_ADC=> + P_Out(Flag_V) <= ADC_V; + P_Out(Flag_C) <= ADC_C; + Q_t := ADC_Q; + when ALU_OP_CMP=> + P_Out(Flag_C) <= SBC_C; + when ALU_OP_SAX=> + P_Out(Flag_C) <= SBC_C; + Q_t := SBX_Q; -- undoc: subtract (A & X) - (immediate) + when ALU_OP_SBC=> + P_Out(Flag_V) <= SBC_V; + P_Out(Flag_C) <= SBC_C; + Q_t := SBC_Q; -- undoc: subtract (A & X) - (immediate), then decimal correction + when ALU_OP_ASL=> + Q_t := BusA(6 downto 0) & "0"; + P_Out(Flag_C) <= BusA(7); + when ALU_OP_ROL=> + Q_t := BusA(6 downto 0) & P_In(Flag_C); + P_Out(Flag_C) <= BusA(7); + when ALU_OP_LSR=> + Q_t := "0" & BusA(7 downto 1); + P_Out(Flag_C) <= BusA(0); + when ALU_OP_ROR=> + Q_t := P_In(Flag_C) & BusA(7 downto 1); + P_Out(Flag_C) <= BusA(0); + when ALU_OP_ARR=> + Q_t := P_In(Flag_C) & (BusA(7 downto 1) and BusB(7 downto 1)); + P_Out(Flag_V) <= Q_t(5) xor Q_t(6); + Q2_t := Q_t; + if P_In(Flag_D)='1' then + if (BusA(3 downto 0) and BusB(3 downto 0)) > "0100" then + Q2_t(3 downto 0) := std_logic_vector(unsigned(Q_t(3 downto 0)) + x"6"); + end if; + if (BusA(7 downto 4) and BusB(7 downto 4)) > "0100" then + Q2_t(7 downto 4) := std_logic_vector(unsigned(Q_t(7 downto 4)) + x"6"); + P_Out(Flag_C) <= '1'; + else + P_Out(Flag_C) <= '0'; + end if; + else + P_Out(Flag_C) <= Q_t(6); + end if; + when ALU_OP_BIT=> + P_Out(Flag_V) <= BusB(6); + when ALU_OP_DEC=> + Q_t := std_logic_vector(unsigned(BusA) - 1); + when ALU_OP_INC=> + Q_t := std_logic_vector(unsigned(BusA) + 1); + when others => + null; + --EQ1,EQ2,EQ3 passes BusA to Q_t and P_in to P_out + end case; + + case Op is + when ALU_OP_ADC=> + P_Out(Flag_N) <= ADC_N; + P_Out(Flag_Z) <= ADC_Z; + when ALU_OP_CMP|ALU_OP_SBC|ALU_OP_SAX=> + P_Out(Flag_N) <= SBC_N; + P_Out(Flag_Z) <= SBC_Z; + when ALU_OP_EQ1=>--dont touch P + when ALU_OP_BIT=> + P_Out(Flag_N) <= BusB(7); + if (BusA and BusB) = "00000000" then + P_Out(Flag_Z) <= '1'; + else + P_Out(Flag_Z) <= '0'; + end if; + when ALU_OP_ANC=> + P_Out(Flag_N) <= Q_t(7); + P_Out(Flag_C) <= Q_t(7); + if Q_t = "00000000" then + P_Out(Flag_Z) <= '1'; + else + P_Out(Flag_Z) <= '0'; + end if; + when others => + P_Out(Flag_N) <= Q_t(7); + if Q_t = "00000000" then + P_Out(Flag_Z) <= '1'; + else + P_Out(Flag_Z) <= '0'; + end if; + end case; + + if Op=ALU_OP_ARR then + -- handled above in ARR code + Q <= Q2_t; + else + Q <= Q_t; + end if; + end process; end; diff --git a/cores/VIC20/source/T65_MCode.vhd b/cores/VIC20/source/T65_MCode.vhd index 6c6c864..7af12a3 100644 --- a/cores/VIC20/source/T65_MCode.vhd +++ b/cores/VIC20/source/T65_MCode.vhd @@ -1,20 +1,18 @@ -- **** -- T65(b) core. In an effort to merge and maintain bug fixes .... -- --- --- Ver 302 minor timing fixes --- Ver 301 Jump timing fixed --- Ver 300 Bugfixes by ehenciak added --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- See list of changes in T65 top file (T65.vhd)... -- -- **** --- -- 65xx compatible microprocessor core -- --- Version : 0246 + fix +-- FPGAARCADE SVN: $Id: T65_MCode.vhd 1234 2015-02-28 20:14:50Z wolfgang.scherr $ -- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- Copyright (c) 2002...2015 +-- Daniel Wallner (jesus opencores org) +-- Mike Johnson (mikej fpgaarcade com) +-- Wolfgang Scherr (WoS pin4 at> +-- Morten Leikvoll () -- -- All rights reserved -- @@ -44,1009 +42,1198 @@ -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- --- Please report bugs to the author, but before you do so, please +-- Please report bugs to the author(s), but before you do so, please -- make sure that this is not a derivative work and that -- you have the latest version of this file. -- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t65/ --- -- Limitations : --- --- 65C02 --- supported : inc, dec, phx, plx, phy, ply --- missing : bra, ora, lda, cmp, sbc, tsb*2, trb*2, stz*2, bit*2, wai, stp, jmp, bbr*8, bbs*8 --- --- File history : --- --- 0246 : First release --- +-- See in T65 top file (T65.vhd)... library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; +use ieee.std_logic_unsigned.all; use work.T65_Pack.all; entity T65_MCode is - port( - Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 - IR : in std_logic_vector(7 downto 0); - MCycle : in std_logic_vector(2 downto 0); - P : in std_logic_vector(7 downto 0); - LCycle : out std_logic_vector(2 downto 0); - ALU_Op : out std_logic_vector(3 downto 0); - Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P - Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA - Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH - Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel - BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj - BreakAtNA : out std_logic; - ADAdd : out std_logic; - AddY : out std_logic; - PCAdd : out std_logic; - Inc_S : out std_logic; - Dec_S : out std_logic; - LDA : out std_logic; - LDP : out std_logic; - LDX : out std_logic; - LDY : out std_logic; - LDS : out std_logic; - LDDI : out std_logic; - LDALU : out std_logic; - LDAD : out std_logic; - LDBAL : out std_logic; - LDBAH : out std_logic; - SaveP : out std_logic; - Write : out std_logic - ); + port( + Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 + IR : in std_logic_vector(7 downto 0); + MCycle : in T_Lcycle; + P : in std_logic_vector(7 downto 0); + LCycle : out T_Lcycle; + ALU_Op : out T_ALU_Op; + Set_BusA_To : out T_Set_BusA_To; -- DI,A,X,Y,S,P,DA,DAO,DAX,AAX + Set_Addr_To : out T_Set_Addr_To; -- PC Adder,S,AD,BA + Write_Data : out T_Write_Data; -- DL,A,X,Y,S,P,PCL,PCH,AX,AXB,XB,YB + Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel + BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj + BreakAtNA : out std_logic; + ADAdd : out std_logic; + AddY : out std_logic; + PCAdd : out std_logic; + Inc_S : out std_logic; + Dec_S : out std_logic; + LDA : out std_logic; + LDP : out std_logic; + LDX : out std_logic; + LDY : out std_logic; + LDS : out std_logic; + LDDI : out std_logic; + LDALU : out std_logic; + LDAD : out std_logic; + LDBAL : out std_logic; + LDBAH : out std_logic; + SaveP : out std_logic; + Write : out std_logic + ); end T65_MCode; architecture rtl of T65_MCode is - signal Branch : std_logic; + signal Branch : std_logic; + signal ALUmore:std_logic; begin - with IR(7 downto 5) select - Branch <= not P(Flag_N) when "000", - P(Flag_N) when "001", - not P(Flag_V) when "010", - P(Flag_V) when "011", - not P(Flag_C) when "100", - P(Flag_C) when "101", - not P(Flag_Z) when "110", - P(Flag_Z) when others; + with IR(7 downto 5) select + Branch <= not P(Flag_N) when "000", + P(Flag_N) when "001", + not P(Flag_V) when "010", + P(Flag_V) when "011", + not P(Flag_C) when "100", + P(Flag_C) when "101", + not P(Flag_Z) when "110", + P(Flag_Z) when others; - process (IR, MCycle, P, Branch, Mode) - begin - LCycle <= "001"; - Set_BusA_To <= "001"; -- A - Set_Addr_To <= (others => '0'); - Write_Data <= (others => '0'); - Jump <= (others => '0'); - BAAdd <= "00"; - BreakAtNA <= '0'; - ADAdd <= '0'; - PCAdd <= '0'; - Inc_S <= '0'; - Dec_S <= '0'; - LDA <= '0'; - LDP <= '0'; - LDX <= '0'; - LDY <= '0'; - LDS <= '0'; - LDDI <= '0'; - LDALU <= '0'; - LDAD <= '0'; - LDBAL <= '0'; - LDBAH <= '0'; - SaveP <= '0'; - Write <= '0'; - AddY <= '0'; + process (IR, MCycle, P, Branch, Mode) + begin + lCycle <= Cycle_1; + Set_BusA_To <= Set_BusA_To_ABC; + Set_Addr_To <= Set_Addr_To_PBR; + Write_Data <= Write_Data_DL; + Jump <= (others => '0'); + BAAdd <= "00"; + BreakAtNA <= '0'; + ADAdd <= '0'; + PCAdd <= '0'; + Inc_S <= '0'; + Dec_S <= '0'; + LDA <= '0'; + LDP <= '0'; + LDX <= '0'; + LDY <= '0'; + LDS <= '0'; + LDDI <= '0'; + LDALU <= '0'; + LDAD <= '0'; + LDBAL <= '0'; + LDBAH <= '0'; + SaveP <= '0'; + Write <= '0'; + AddY <= '0'; + ALUmore <= '0'; - case IR(7 downto 5) is - when "100" => - --{{{ - case IR(1 downto 0) is - when "00" => - Set_BusA_To <= "011"; -- Y - Write_Data <= "011"; -- Y - when "10" => - Set_BusA_To <= "010"; -- X - Write_Data <= "010"; -- X - when others => - Write_Data <= "001"; -- A - end case; - --}}} - when "101" => - --{{{ - case IR(1 downto 0) is - when "00" => - if IR(4) /= '1' or IR(2) /= '0' then - LDY <= '1'; - end if; - when "10" => - LDX <= '1'; - when others => - LDA <= '1'; - end case; - Set_BusA_To <= "000"; -- DI - --}}} - when "110" => - --{{{ - case IR(1 downto 0) is - when "00" => - if IR(4) = '0' then - LDY <= '1'; - end if; - Set_BusA_To <= "011"; -- Y - when others => - Set_BusA_To <= "001"; -- A - end case; - --}}} - when "111" => - --{{{ - case IR(1 downto 0) is - when "00" => - if IR(4) = '0' then - LDX <= '1'; - end if; - Set_BusA_To <= "010"; -- X - when others => - Set_BusA_To <= "001"; -- A - end case; - --}}} - when others => - end case; + case IR(7 downto 5) is + when "100" => -- covers $8x,$9x + case IR(1 downto 0) is + when "00" => -- IR: $80,$84,$88,$8C,$90,$94,$98,$9C + Set_BusA_To <= Set_BusA_To_Y; + if IR(4 downto 2)="111" then -- SYA ($9C) + Write_Data <= Write_Data_YB; + else + Write_Data <= Write_Data_Y; + end if; + when "10" => -- IR: $82,$86,$8A,$8E,$92,$96,$9A,$9E + Set_BusA_To <= Set_BusA_To_X; + if IR(4 downto 2)="111" then -- SXA ($9E) + Write_Data <= Write_Data_XB; + else + Write_Data <= Write_Data_X; + end if; + when "11" => -- IR: $83,$87,$8B,$8F,$93,$97,$9B,$9F + if IR(4 downto 2)="110" then -- SHS ($9B) + Set_BusA_To <= Set_BusA_To_AAX; + LDS <= '1'; + else + Set_BusA_To <= Set_BusA_To_ABC; + end if; + if IR(4 downto 2)="111" or IR(4 downto 2)="110" or IR(4 downto 2)="100" then -- SHA ($9F, $93), SHS ($9B) + Write_Data <= Write_Data_AXB; + else + Write_Data <= Write_Data_AX; + end if; + when others => -- IR: $81,$85,$89,$8D,$91,$95,$99,$9D + Write_Data <= Write_Data_ABC; + end case; + when "101" => -- covers $Ax,$Bx + Set_BusA_To <= Set_BusA_To_DI; + case IR(1 downto 0) is + when "00" => -- IR: $A0,$A4,$A8,$AC,$B0,$B4,$B8,$BC + if IR(4) /= '1' or IR(2) /= '0' then--only for $A0,$A4,$A8,$AC or $B4,$BC + LDY <= '1'; + end if; + when "01" => -- IR: $A1,$A5,$A9,$AD,$B1,$B5,$B9,$BD + LDA <= '1'; + when "10" => -- IR: $A2,$A6,$AA,$AE,$B2,$B6,$BA,$BE + LDX <= '1'; + when others => -- IR: $A3,$A7,$AB,$AF,$B3,$B7,$BB,$BF (undoc) + LDX <= '1'; + LDA <= '1'; + if IR(4 downto 2)="110" then -- LAS (BB) + Set_BusA_To <= Set_BusA_To_S; + LDS <= '1'; + end if; + end case; + when "110" => -- covers $Cx,$Dx + case IR(1 downto 0) is + when "00" => -- IR: $C0,$C4,$C8,$CC,$D0,$D4,$D8,$DC + if IR(4) = '0' then--only for $Cx + LDY <= '1'; + end if; + Set_BusA_To <= Set_BusA_To_Y; + when others => -- IR: $C1,$C5,$C9,$CD,$D1,$D5,$D9,$DD, $C2,$C6,$CA,$CE,$D2,$D6,$DA,$DE, $C3,$C7,$CB,$CF,$D3,$D7,$DB,$DF + Set_BusA_To <= Set_BusA_To_ABC; + end case; + when "111" => -- covers $Ex,$Fx + case IR(1 downto 0) is + when "00" => -- IR: $E0,$E4,$E8,$EC,$F0,$F4,$F8,$FC + if IR(4) = '0' then -- only $Ex + LDX <= '1'; + end if; + Set_BusA_To <= Set_BusA_To_X; + when others => -- IR: $E1,$E5,$E9,$ED,$F1,$F5,$F9,$FD, $E2,$E6,$EA,$EE,$F2,$F6,$FA,$FE, $E3,$E7,$EB,$EF,$F3,$F7,$FB,$FF + Set_BusA_To <= Set_BusA_To_ABC; + end case; + when others => + end case; - if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then - Set_BusA_To <= "000"; -- DI - end if; + if IR(7 downto 6) /= "10" and IR(1) = '1' and (mode="00" or IR(0)='0') then--covers $0x-$7x, $Cx-$Fx x=2,3,6,7,A,B,E,F, for 6502 undocs + if IR=x"eb" then + Set_BusA_To <= Set_BusA_To_ABC; -- alternate SBC ($EB) + else + Set_BusA_To <= Set_BusA_To_DI; + end if; + end if; - case IR(4 downto 0) is - when "00000" | "01000" | "01010" | "11000" | "11010" => - --{{{ - -- Implied - case IR is - when "00000000" => - -- BRK - LCycle <= "110"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= "01"; -- S - Write_Data <= "111"; -- PCH - Write <= '1'; - when 2 => - Dec_S <= '1'; - Set_Addr_To <= "01"; -- S - Write_Data <= "110"; -- PCL - Write <= '1'; - when 3 => - Dec_S <= '1'; - Set_Addr_To <= "01"; -- S - Write_Data <= "101"; -- P - Write <= '1'; - when 4 => - Dec_S <= '1'; - Set_Addr_To <= "11"; -- BA - when 5 => - LDDI <= '1'; - Set_Addr_To <= "11"; -- BA - when 6 => - Jump <= "10"; -- DIDL - when others => - end case; - when "00100000" => - -- JSR - LCycle <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Jump <= "01"; - LDDI <= '1'; - Set_Addr_To <= "01"; -- S - when 2 => - Set_Addr_To <= "01"; -- S - Write_Data <= "111"; -- PCH - Write <= '1'; - when 3 => - Dec_S <= '1'; - Set_Addr_To <= "01"; -- S - Write_Data <= "110"; -- PCL - Write <= '1'; - when 4 => - Dec_S <= '1'; - when 5 => - Jump <= "10"; -- DIDL - when others => - end case; - when "01000000" => - -- RTI - LCycle <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= "01"; -- S - when 2 => - Inc_S <= '1'; - Set_Addr_To <= "01"; -- S - when 3 => - Inc_S <= '1'; - Set_Addr_To <= "01"; -- S - Set_BusA_To <= "000"; -- DI - when 4 => - LDP <= '1'; - Inc_S <= '1'; - LDDI <= '1'; - Set_Addr_To <= "01"; -- S - when 5 => - Jump <= "10"; -- DIDL - when others => - end case; - when "01100000" => - -- RTS - LCycle <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= "01"; -- S - when 2 => - Inc_S <= '1'; - Set_Addr_To <= "01"; -- S - when 3 => - Inc_S <= '1'; - LDDI <= '1'; - Set_Addr_To <= "01"; -- S - when 4 => - Jump <= "10"; -- DIDL - when 5 => - Jump <= "01"; - when others => - end case; - when "00001000" | "01001000" | "01011010" | "11011010" => - -- PHP, PHA, PHY*, PHX* - LCycle <= "010"; - if Mode = "00" and IR(1) = '1' then - LCycle <= "001"; - end if; - case to_integer(unsigned(MCycle)) is - when 1 => - case IR(7 downto 4) is - when "0000" => - Write_Data <= "101"; -- P - when "0100" => - Write_Data <= "001"; -- A - when "0101" => - Write_Data <= "011"; -- Y - when "1101" => - Write_Data <= "010"; -- X - when others => - end case; - Write <= '1'; - Set_Addr_To <= "01"; -- S - when 2 => - Dec_S <= '1'; - when others => - end case; - when "00101000" | "01101000" | "01111010" | "11111010" => - -- PLP, PLA, PLY*, PLX* - LCycle <= "011"; - if Mode = "00" and IR(1) = '1' then - LCycle <= "001"; - end if; - case IR(7 downto 4) is - when "0010" => - LDP <= '1'; - when "0110" => - LDA <= '1'; - when "0111" => - if Mode /= "00" then - LDY <= '1'; - end if; - when "1111" => - if Mode /= "00" then - LDX <= '1'; - end if; - when others => - end case; - case to_integer(unsigned(MCycle)) is - when 0 => - SaveP <= '1'; - when 1 => - Set_Addr_To <= "01"; -- S - when 2 => - Inc_S <= '1'; - Set_Addr_To <= "01"; -- S - when 3 => - Set_BusA_To <= "000"; -- DI - when others => - end case; - when "10100000" | "11000000" | "11100000" => - -- LDY, CPY, CPX - -- Immediate - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - when others => - end case; - when "10001000" => - -- DEY - LDY <= '1'; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Set_BusA_To <= "011"; -- Y - when others => - end case; - when "11001010" => - -- DEX - LDX <= '1'; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Set_BusA_To <= "010"; -- X - when others => - end case; - when "00011010" | "00111010" => - -- INC*, DEC* - if Mode /= "00" then - LDA <= '1'; -- A - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Set_BusA_To <= "100"; -- S - when others => - end case; - when "00001010" | "00101010" | "01001010" | "01101010" => - -- ASL, ROL, LSR, ROR - LDA <= '1'; -- A - Set_BusA_To <= "001"; -- A - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - when others => - end case; - when "10001010" | "10011000" => - -- TYA, TXA - LDA <= '1'; -- A - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - when others => - end case; - when "10101010" | "10101000" => - -- TAX, TAY - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Set_BusA_To <= "001"; -- A - when others => - end case; - when "10011010" => - -- TXS - case to_integer(unsigned(MCycle)) is - when 0 => - LDS <= '1'; - when 1 => - when others => - end case; - when "10111010" => - -- TSX - LDX <= '1'; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Set_BusA_To <= "100"; -- S - when others => - end case; + case IR(4 downto 0) is + -- IR: $00,$20,$40,$60,$80,$A0,$C0,$E0 + -- $08,$28,$48,$68,$88,$A8,$C8,$E8 + -- $0A,$2A,$4A,$6A,$8A,$AA,$CA,$EA + -- $18,$38,$58,$78,$98,$B8,$D8,$F8 + -- $1A,$3A,$5A,$7A,$9A,$BA,$DA,$FA + when "00000" | "01000" | "01010" | "11000" | "11010" => + -- Implied + case IR is + when x"00" => + -- BRK ($00) + lCycle <= Cycle_6; + case MCycle is + when Cycle_1 => + Set_Addr_To <= Set_Addr_To_SP; + Write_Data <= Write_Data_PCH; + Write <= '1'; + when Cycle_2 => + Dec_S <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + Write_Data <= Write_Data_PCL; + Write <= '1'; + when Cycle_3 => + Dec_S <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + Write_Data <= Write_Data_P; + Write <= '1'; + when Cycle_4 => + Dec_S <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_5 => + LDDI <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_6 => + Jump <= "10"; + when others => + end case; + when x"20" => -- JSR ($20) + lCycle <= Cycle_5; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDDI <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + when Cycle_2 => + Set_Addr_To <= Set_Addr_To_SP; + Write_Data <= Write_Data_PCH; + Write <= '1'; + when Cycle_3 => + Dec_S <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + Write_Data <= Write_Data_PCL; + Write <= '1'; + when Cycle_4 => + Dec_S <= '1'; + when Cycle_5 => + Jump <= "10"; + when others => + end case; + when x"40" => -- RTI ($40) + lCycle <= Cycle_5; + case MCycle is + when Cycle_1 => + Set_Addr_To <= Set_Addr_To_SP; + when Cycle_2 => + Inc_S <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + when Cycle_3 => + Inc_S <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + Set_BusA_To <= Set_BusA_To_DI; + when Cycle_4 => + LDP <= '1'; + Inc_S <= '1'; + LDDI <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + when Cycle_5 => + Jump <= "10"; + when others => + end case; + when x"60" => -- RTS ($60) + lCycle <= Cycle_5; + case MCycle is + when Cycle_1 => + Set_Addr_To <= Set_Addr_To_SP; + when Cycle_2 => + Inc_S <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + when Cycle_3 => + Inc_S <= '1'; + LDDI <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + when Cycle_4 => + Jump <= "10"; + when Cycle_5 => + Jump <= "01"; + when others => + end case; + when x"08" | x"48" | x"5a" | x"da" => -- PHP, PHA, PHY*, PHX* ($08,$48,$5A,$DA) + lCycle <= Cycle_2; + if Mode = "00" and IR(1) = '1' then--2 cycle nop + lCycle <= Cycle_1; + end if; + case MCycle is + when Cycle_1 => + if mode/="00" or IR(1)='0' then --wrong on 6502 + Write <= '1'; + case IR(7 downto 4) is + when "0000" => + Write_Data <= Write_Data_P; + when "0100" => + Write_Data <= Write_Data_ABC; + when "0101" => + if Mode /= "00" then + Write_Data <= Write_Data_Y; + else + Write <= '0'; + end if; + when "1101" => + if Mode /= "00" then + Write_Data <= Write_Data_X; + else + Write <= '0'; + end if; + when others => + end case; + Set_Addr_To <= Set_Addr_To_SP; + end if; + when Cycle_2 => + Dec_S <= '1'; + when others => + end case; + when x"28" | x"68" | x"7a" | x"fa" => -- PLP, PLA, PLY*, PLX* ($28,$68,$7A,$FA) + lCycle <= Cycle_3; + if Mode = "00" and IR(1) = '1' then--2 cycle nop + lCycle <= Cycle_1; + end if; + case IR(7 downto 4) is + when "0010" =>--plp + LDP <= '1'; + when "0110" =>--pla + LDA <= '1'; + when "0111" =>--ply not for 6502 + if Mode /= "00" then + LDY <= '1'; + end if; + when "1111" =>--plx not for 6502 + if Mode /= "00" then + LDX <= '1'; + end if; + when others => + end case; + case MCycle is + when Cycle_sync => + if Mode /= "00" or IR(1) = '0' then--wrong on 6502 + SaveP <= '1'; + end if; + when Cycle_1 => + if Mode /= "00" or IR(1) = '0' then--wrong on 6502 + Set_Addr_To <= Set_Addr_To_SP; + LDP <= '0'; + end if; + when Cycle_2 => + Inc_S <= '1'; + Set_Addr_To <= Set_Addr_To_SP; + LDP <= '0'; + when Cycle_3 => + Set_BusA_To <= Set_BusA_To_DI; + when others => + end case; + when x"a0" | x"c0" | x"e0" => -- LDY, CPY, CPX ($A0,$C0,$E0) + -- Immediate + case MCycle is + when Cycle_sync => + when Cycle_1 => + Jump <= "01"; + when others => + end case; + when x"88" => -- DEY ($88) + LDY <= '1'; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Set_BusA_To <= Set_BusA_To_Y; + when others => + end case; + when x"ca" => -- DEX ($CA) + LDX <= '1'; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Set_BusA_To <= Set_BusA_To_X; + when others => + end case; + when x"1a" | x"3a" => -- INC*, DEC* ($1A,$3A) + if Mode /= "00" then + LDA <= '1'; -- A + else + lCycle <= Cycle_1;--undoc 2 cycle nop + end if; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Set_BusA_To <= Set_BusA_To_S; + when others => + end case; + when x"0a" | x"2a" | x"4a" | x"6a" => -- ASL, ROL, LSR, ROR ($0A,$2A,$4A,$6A) + LDA <= '1'; -- A + Set_BusA_To <= Set_BusA_To_ABC; + case MCycle is + when Cycle_sync => + when Cycle_1 => + when others => + end case; + when x"8a" | x"98" => -- TYA, TXA ($8A,$98) + LDA <= '1'; + case MCycle is + when Cycle_sync => + when Cycle_1 => + when others => + end case; + when x"aa" | x"a8" => -- TAX, TAY ($AA,$A8) + case MCycle is + when Cycle_sync => + when Cycle_1 => + Set_BusA_To <= Set_BusA_To_ABC; + when others => + end case; + when x"9a" => -- TXS ($9A) + LDS <= '1'; -- will be set only in Cycle_sync + when x"ba" => -- TSX ($BA) + LDX <= '1'; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Set_BusA_To <= Set_BusA_To_S; + when others => + end case; + when x"80" => -- undoc: NOP imm2 ($80) + case MCycle is + when Cycle_sync => + when Cycle_1 => + Jump <= "01"; + when others => + end case; + when others => -- others ($0A,$EA, $18,$38,$58,$78,$B8,$C8,$D8,$E8,$F8) + case MCycle is + when Cycle_sync => + when others => + end case; + end case; - -- when "00011000" | "00111000" | "01011000" | "01111000" | "10111000" | "11011000" | "11111000" | "11001000" | "11101000" => - -- -- CLC, SEC, CLI, SEI, CLV, CLD, SED, INY, INX - -- case to_integer(unsigned(MCycle)) is - -- when 1 => - -- when others => - -- end case; - when others => - case to_integer(unsigned(MCycle)) is - when 0 => - when others => - end case; - end case; - --}}} + -- IR: $01,$21,$41,$61,$81,$A1,$C1,$E1 + -- $03,$23,$43,$63,$83,$A3,$C3,$E3 + when "00001" | "00011" => + -- Zero Page Indexed Indirect (d,x) + lCycle <= Cycle_5; + if IR(7 downto 6) /= "10" then -- ($01,$21,$41,$61,$C1,$E1,$03,$23,$43,$63,$C3,$E3) + LDA <= '1'; + if Mode="00" and IR(1)='1' then + lCycle <= Cycle_7; + end if; + end if; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_2 => + ADAdd <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_3 => + BAAdd <= "01"; + LDBAL <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_4 => + LDBAH <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_5=> + if Mode="00" and IR(1)='1' and IR(7 downto 6)/="10" then + Set_Addr_To <= Set_Addr_To_BA; + Write <= '1'; + LDDI<='1'; + end if; + when Cycle_6=> + Write <= '1'; + LDALU<='1'; + SaveP<='1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_7 => + ALUmore <= '1'; + Set_BusA_To <= Set_BusA_To_ABC; + when others => + end case; - when "00001" | "00011" => - --{{{ - -- Zero Page Indexed Indirect (d,x) - LCycle <= "101"; - if IR(7 downto 6) /= "10" then - LDA <= '1'; - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - LDAD <= '1'; - Set_Addr_To <= "10"; -- AD - when 2 => - ADAdd <= '1'; - Set_Addr_To <= "10"; -- AD - when 3 => - BAAdd <= "01"; -- DB Inc - LDBAL <= '1'; - Set_Addr_To <= "10"; -- AD - when 4 => - LDBAH <= '1'; - if IR(7 downto 5) = "100" then - Write <= '1'; - end if; - Set_Addr_To <= "11"; -- BA - when 5 => - when others => - end case; - --}}} + -- IR: $09,$29,$49,$69,$89,$A9,$C9,$E9 + when "01001" => + -- Immediate + if IR(7 downto 5)/="100" then -- all except undoc. NOP imm2 (not $89) + LDA <= '1'; + end if; + case MCycle is + when Cycle_1 => + Jump <= "01"; + when others => + end case; - when "01001" | "01011" => - --{{{ - -- Immediate - LDA <= '1'; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - when others => - end case; + -- IR: $0B,$2B,$4B,$6B,$8B,$AB,$CB,$EB + when "01011" => + if Mode="00" then + -- Immediate undoc for 6500 + case IR(7 downto 5) is + when "010"|"011"|"000"|"001" =>--ALR,ARR + Set_BusA_To<=Set_BusA_To_DA; + LDA <= '1'; + when "100" =>--XAA + Set_BusA_To<=Set_BusA_To_DAX; + LDA <= '1'; + when "110" =>--SAX (SBX) + Set_BusA_To<=Set_BusA_To_AAX; + LDX <= '1'; + when "101" =>--OAL + Set_BusA_To<=Set_BusA_To_DAO; + LDA <= '1'; + when others=> + LDA <= '1'; + end case; + case MCycle is + when Cycle_1 => + Jump <= "01"; + when others => + end case; + end if; - --}}} + -- IR: $02,$22,$42,$62,$82,$A2,$C2,$E2 + -- $12,$32,$52,$72,$92,$B2,$D2,$F2 + when "00010" | "10010" => + -- Immediate, SKB, KIL + case MCycle is + when Cycle_sync => + when Cycle_1 => + if IR = "10100010" then + -- LDX ($A2) + Jump <= "01"; + LDX <= '1'; -- Moved, Lorenz test showed X changing on SKB (NOPx) + elsif IR(7 downto 4)="1000" or IR(7 downto 4)="1100" or IR(7 downto 4)="1110" then + -- undoc: NOP imm2 + Jump <= "01"; + else + -- KIL !!! + end if; + when others => + end case; - when "00010" | "10010" => - --{{{ - -- Immediate, KIL - LDX <= '1'; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - if IR = "10100010" then - -- LDX - Jump <= "01"; - else - -- KIL !!!!!!!!!!!!!!!!!!!!!!!!!!!!! - end if; - when others => - end case; - --}}} + -- IR: $04,$24,$44,$64,$84,$A4,$C4,$E4 + when "00100" => + -- Zero Page + lCycle <= Cycle_2; + case MCycle is + when Cycle_sync => + if IR(7 downto 5) = "001" then--24=BIT zpg + SaveP <= '1'; + end if; + when Cycle_1 => + Jump <= "01"; + LDAD <= '1'; + if IR(7 downto 5) = "100" then--84=sty zpg (the only write in this group) + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_2 => + when others => + end case; - when "00100" => - --{{{ - -- Zero Page - LCycle <= "010"; - case to_integer(unsigned(MCycle)) is - when 0 => - if IR(7 downto 5) = "001" then - SaveP <= '1'; - end if; - when 1 => - Jump <= "01"; - LDAD <= '1'; - if IR(7 downto 5) = "100" then - Write <= '1'; - end if; - Set_Addr_To <= "10"; -- AD - when 2 => - when others => - end case; - --}}} + -- IR: $05,$25,$45,$65,$85,$A5,$C5,$E5 + -- $06,$26,$46,$66,$86,$A6,$C6,$E6 + -- $07,$27,$47,$67,$87,$A7,$C7,$E7 + when "00101" | "00110" | "00111" => + -- Zero Page + if IR(7 downto 6) /= "10" and IR(1) = '1' and (mode="00" or IR(0)='0') then--covers 0x-7x,cx-fx x=2,3,6,7,a,b,e,f, for 6502 undocs + -- Read-Modify-Write + lCycle <= Cycle_4; + if Mode="00" and IR(0)='1' then + LDA<='1'; + end if; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_2 => + LDDI <= '1'; + if Mode="00" then--The old 6500 writes back what is just read, before changing. The 65c does another read + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_3 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_4 => + if Mode="00" and IR(0)='1' then + Set_BusA_To<=Set_BusA_To_ABC; + ALUmore <= '1'; -- For undoc DCP/DCM support + LDDI <= '1'; -- requires DIN to reflect DOUT! + end if; + when others => + end case; + else + lCycle <= Cycle_2; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + end if; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Jump <= "01"; + LDAD <= '1'; + if IR(7 downto 5) = "100" then + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_2 => + when others => + end case; + end if; - when "00101" | "00110" | "00111" => - --{{{ - -- Zero Page - if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then - -- Read-Modify-Write - LCycle <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Jump <= "01"; - LDAD <= '1'; - Set_Addr_To <= "10"; -- AD - when 2 => - LDDI <= '1'; - Write <= '1'; - Set_Addr_To <= "10"; -- AD - when 3 => - LDALU <= '1'; - SaveP <= '1'; - Write <= '1'; - Set_Addr_To <= "10"; -- AD - when 4 => - when others => - end case; - else - LCycle <= "010"; - if IR(7 downto 6) /= "10" then - LDA <= '1'; - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - LDAD <= '1'; - if IR(7 downto 5) = "100" then - Write <= '1'; - end if; - Set_Addr_To <= "10"; -- AD - when 2 => - when others => - end case; - end if; - --}}} + -- IR: $0C,$2C,$4C,$6C,$8C,$AC,$CC,$EC + when "01100" => + -- Absolute + if IR(7 downto 6) = "01" and IR(4 downto 0) = "01100" then -- JMP ($4C,$6C) + if IR(5) = '0' then + lCycle <= Cycle_2; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDDI <= '1'; + when Cycle_2 => + Jump <= "10"; + when others => + end case; + else + lCycle <= Cycle_4; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDDI <= '1'; + LDBAL <= '1'; + when Cycle_2 => + LDBAH <= '1'; + if Mode /= "00" then + Jump <= "10"; + end if; + if Mode = "00" then + Set_Addr_To <= Set_Addr_To_BA; + end if; + when Cycle_3 => + LDDI <= '1'; + if Mode = "00" then + Set_Addr_To <= Set_Addr_To_BA; + BAAdd <= "01"; -- DB Inc + else + Jump <= "01"; + end if; + when Cycle_4 => + Jump <= "10"; + when others => + end case; + end if; + else + lCycle <= Cycle_3; + case MCycle is + when Cycle_sync => + if IR(7 downto 5) = "001" then--2c-BIT + SaveP <= '1'; + end if; + when Cycle_1 => + Jump <= "01"; + LDBAL <= '1'; + when Cycle_2 => + Jump <= "01"; + LDBAH <= '1'; + if IR(7 downto 5) = "100" then--80, sty, the only write in this group + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_3 => + when others => + end case; + end if; - when "01100" => - --{{{ - -- Absolute - if IR(7 downto 6) = "01" and IR(4 downto 0) = "01100" then - -- JMP - if IR(5) = '0' then - --LCycle <= "011"; - LCycle <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Jump <= "01"; - LDDI <= '1'; - when 2 => - Jump <= "10"; -- DIDL - when others => - end case; - else - --LCycle <= "101"; - LCycle <= "100"; -- mikej - case to_integer(unsigned(MCycle)) is - when 1 => - Jump <= "01"; - LDDI <= '1'; - LDBAL <= '1'; - when 2 => - LDBAH <= '1'; - if Mode /= "00" then - Jump <= "10"; -- DIDL - end if; - if Mode = "00" then - Set_Addr_To <= "11"; -- BA - end if; - when 3 => - LDDI <= '1'; - if Mode = "00" then - Set_Addr_To <= "11"; -- BA - BAAdd <= "01"; -- DB Inc - else - Jump <= "01"; - end if; - when 4 => - Jump <= "10"; -- DIDL - when others => - end case; - end if; - else - LCycle <= "011"; - case to_integer(unsigned(MCycle)) is - when 0 => - if IR(7 downto 5) = "001" then - SaveP <= '1'; - end if; - when 1 => - Jump <= "01"; - LDBAL <= '1'; - when 2 => - Jump <= "01"; - LDBAH <= '1'; - if IR(7 downto 5) = "100" then - Write <= '1'; - end if; - Set_Addr_To <= "11"; -- BA - when 3 => - when others => - end case; - end if; - --}}} + -- IR: $0D,$2D,$4D,$6D,$8D,$AD,$CD,$ED + -- $0E,$2E,$4E,$6E,$8E,$AE,$CE,$EE + -- $0F,$2F,$4F,$6F,$8F,$AF,$CF,$EF + when "01101" | "01110" | "01111" => + -- Absolute + if IR(7 downto 6) /= "10" and IR(1) = '1' and (mode="00" or IR(0)='0') then -- ($0E,$2E,$4E,$6E,$CE,$EE, $0F,$2F,$4F,$6F,$CF,$EF) + -- Read-Modify-Write + lCycle <= Cycle_5; + if Mode="00" and IR(0) = '1' then + LDA <= '1'; + end if; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDBAL <= '1'; + when Cycle_2 => + Jump <= "01"; + LDBAH <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_3 => + LDDI <= '1'; + if Mode="00" then--The old 6500 writes back what is just read, before changing. The 65c does another read + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_4 => + Write <= '1'; + LDALU <= '1'; + SaveP <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_5 => + if Mode="00" and IR(0)='1' then + ALUmore <= '1'; -- For undoc DCP/DCM support + Set_BusA_To<=Set_BusA_To_ABC; + end if; + when others => + end case; + else + lCycle <= Cycle_3; + if IR(7 downto 6) /= "10" then -- all but $8D, $8E, $8F, $AD, $AE, $AF ($AD does set LDA in an earlier case statement) + LDA <= '1'; + end if; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Jump <= "01"; + LDBAL <= '1'; + when Cycle_2 => + Jump <= "01"; + LDBAH <= '1'; + if IR(7 downto 5) = "100" then--8d + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_3 => + when others => + end case; + end if; - when "01101" | "01110" | "01111" => - --{{{ - -- Absolute - if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then - -- Read-Modify-Write - LCycle <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Jump <= "01"; - LDBAL <= '1'; - when 2 => - Jump <= "01"; - LDBAH <= '1'; - Set_Addr_To <= "11"; -- BA - when 3 => - LDDI <= '1'; - Write <= '1'; - Set_Addr_To <= "11"; -- BA - when 4 => - Write <= '1'; - LDALU <= '1'; - SaveP <= '1'; - Set_Addr_To <= "11"; -- BA - when 5 => - SaveP <= '0'; -- MIKEJ was 1 - when others => - end case; - else - LCycle <= "011"; - if IR(7 downto 6) /= "10" then - LDA <= '1'; - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - LDBAL <= '1'; - when 2 => - Jump <= "01"; - LDBAH <= '1'; - if IR(7 downto 5) = "100" then - Write <= '1'; - end if; - Set_Addr_To <= "11"; -- BA - when 3 => - when others => - end case; - end if; - --}}} + -- IR: $10,$30,$50,$70,$90,$B0,$D0,$F0 + when "10000" => + -- Relative + -- This circuit dictates when the last + -- microcycle occurs for the branch depending on + -- whether or not the branch is taken and if a page + -- is crossed... + if (Branch = '1') then + lCycle <= Cycle_3; -- We're done @ T3 if branching...upper + -- level logic will stop at T2 if no page cross + -- (See the Break signal) + else + lCycle <= Cycle_1; + end if; + -- This decodes the current microcycle and takes the + -- proper course of action... + case MCycle is + -- On the T1 microcycle, increment the program counter + -- and instruct the upper level logic to fetch the offset + -- from the Din bus and store it in the data latches. This + -- will be the last microcycle if the branch isn't taken. + when Cycle_1 => + Jump <= "01"; -- Increments the PC by one (PC will now be PC+2) + -- from microcycle T0. + LDDI <= '1'; -- Tells logic in top level (T65.vhd) to route + -- the Din bus to the memory data latch (DL) + -- so that the branch offset is fetched. + -- In microcycle T2, tell the logic in the top level to + -- add the offset. If the most significant byte of the + -- program counter (i.e. the current "page") does not need + -- updating, we are done here...the Break signal at the + -- T65.vhd level takes care of that... + when Cycle_2 => + Jump <= "11"; -- Tell the PC Jump logic to use relative mode. + PCAdd <= '1'; -- This tells the PC adder to update itself with + -- the current offset recently fetched from + -- memory. + -- The following is microcycle T3 : + -- The program counter should be completely updated + -- on this cycle after the page cross is detected. + -- We don't need to do anything here... + when Cycle_3 => + when others => null; -- Do nothing. + end case; - when "10000" => - --{{{ - -- Relative + -- IR: $11,$31,$51,$71,$91,$B1,$D1,$F1 + -- $13,$33,$53,$73,$93,$B3,$D3,$F3 + when "10001" | "10011" => + lCycle <= Cycle_5; + if IR(7 downto 6) /= "10" then -- ($11,$31,$51,$71,$D1,$F1,$13,$33,$53,$73,$D3,$F3) + LDA <= '1'; + if Mode="00" and IR(1)='1' then + lCycle <= Cycle_7; + end if; + end if; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_2 => + LDBAL <= '1'; + BAAdd <= "01"; -- DB Inc + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_3 => + Set_BusA_To <= Set_BusA_To_Y; + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_4 => + BAAdd <= "11"; -- BA Adj + if IR(7 downto 5) = "100" then + Write <= '1'; + elsif IR(1)='0' or IR=x"B3" then -- Dont do this on $x3, except undoc LAXiy $B3 (says real CPU and Lorenz tests) + BreakAtNA <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_5 => + if Mode="00" and IR(1)='1' and IR(7 downto 6)/="10" then + Set_Addr_To <= Set_Addr_To_BA; + LDDI<='1'; + Write <= '1'; + end if; + when Cycle_6 => + LDALU<='1'; + SaveP<='1'; + Write <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_7 => + ALUmore <= '1'; + Set_BusA_To<=Set_BusA_To_ABC; + when others => + end case; - -- This circuit dictates when the last - -- microcycle occurs for the branch depending on - -- whether or not the branch is taken and if a page - -- is crossed... - if (Branch = '1') then + -- IR: $14,$34,$54,$74,$94,$B4,$D4,$F4 + -- $15,$35,$55,$75,$95,$B5,$D5,$F5 + -- $16,$36,$56,$76,$96,$B6,$D6,$F6 + -- $17,$37,$57,$77,$97,$B7,$D7,$F7 + when "10100" | "10101" | "10110" | "10111" => + -- Zero Page, X + if IR(7 downto 6) /= "10" and IR(1) = '1' and (Mode="00" or IR(0)='0') then -- ($16,$36,$56,$76,$D6,$F6, $17,$37,$57,$77,$D7,$F7) + -- Read-Modify-Write + if Mode="00" and IR(0)='1' then + LDA<='1'; + end if; + lCycle <= Cycle_5; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_2 => + ADAdd <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_3 => + LDDI <= '1'; + if Mode="00" then -- The old 6500 writes back what is just read, before changing. The 65c does another read + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_4 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + if Mode="00" and IR(0)='1' then + LDDI<='1'; + end if; + when Cycle_5 => + if Mode="00" and IR(0)='1' then + ALUmore <= '1'; -- For undoc DCP/DCM support + Set_BusA_To<=Set_BusA_To_ABC; + end if; + when others => + end case; + else + lCycle <= Cycle_3; + if IR(7 downto 6) /= "10" and IR(0)='1' then -- dont LDA on undoc skip + LDA <= '1'; + end if; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Jump <= "01"; + LDAD <= '1'; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_2 => + ADAdd <= '1'; + -- Added this check for Y reg. use, added undocs + if (IR(3 downto 1) = "011") then -- ($16,$36,$56,$76,$96,$B6,$D6,$F6,$17,$37,$57,$77,$97,$B7,$D7,$F7) + AddY <= '1'; + end if; + if IR(7 downto 5) = "100" then -- ($14,$34,$15,$35,$16,$36,$17,$37) the only write instruction + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_ZPG; + when Cycle_3 => null; + when others => + end case; + end if; - LCycle <= "011"; -- We're done @ T3 if branching...upper - -- level logic will stop at T2 if no page cross - -- (See the Break signal) - else + -- IR: $19,$39,$59,$79,$99,$B9,$D9,$F9 + -- $1B,$3B,$5B,$7B,$9B,$BB,$DB,$FB + when "11001" | "11011" => + -- Absolute Y + lCycle <= Cycle_4; + if IR(7 downto 6) /= "10" then + LDA <= '1'; + if Mode="00" and IR(1)='1' then + lCycle <= Cycle_6; + end if; + end if; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDBAL <= '1'; + when Cycle_2 => + Jump <= "01"; + Set_BusA_To <= Set_BusA_To_Y; + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_3 => + BAAdd <= "11"; -- BA adj + if IR(7 downto 5) = "100" then--99/9b + Write <= '1'; + elsif IR(1)='0' or IR=x"BB" then -- Dont do this on $xB, except undoc $BB (says real CPU and Lorenz tests) + BreakAtNA <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_4 => -- just for undoc + if Mode="00" and IR(1)='1' and IR(7 downto 6)/="10" then + Set_Addr_To <= Set_Addr_To_BA; + LDDI<='1'; + Write <= '1'; + end if; + when Cycle_5 => + Write <= '1'; + LDALU<='1'; + Set_Addr_To <= Set_Addr_To_BA; + SaveP<='1'; + when Cycle_6 => + ALUmore <= '1'; + Set_BusA_To <= Set_BusA_To_ABC; + when others => + end case; - LCycle <= "001"; + -- IR: $1C,$3C,$5C,$7C,$9C,$BC,$DC,$FC + -- $1D,$3D,$5D,$7D,$9D,$BD,$DD,$FD + -- $1E,$3E,$5E,$7E,$9E,$BE,$DE,$FE + -- $1F,$3F,$5F,$7F,$9F,$BF,$DF,$FF + when "11100" | "11101" | "11110" | "11111" => + -- Absolute X + if IR(7 downto 6) /= "10" and IR(1) = '1' and (Mode="00" or IR(0)='0') then -- ($1E,$3E,$5E,$7E,$DE,$FE, $1F,$3F,$5F,$7F,$DF,$FF) + -- Read-Modify-Write + lCycle <= Cycle_6; + if Mode="00" and IR(0)='1' then + LDA <= '1'; + end if; + case MCycle is + when Cycle_1 => + Jump <= "01"; + LDBAL <= '1'; + when Cycle_2 => + Jump <= "01"; + Set_BusA_To <= Set_BusA_To_X; + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_3 => + BAAdd <= "11"; -- BA adj + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_4 => + LDDI <= '1'; + if Mode="00" then--The old 6500 writes back what is just read, before changing. The 65c does another read + Write <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_5 => + LDALU <= '1'; + SaveP <= '1'; + Write <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_6 => + if Mode="00" and IR(0)='1' then + ALUmore <= '1'; + Set_BusA_To <= Set_BusA_To_ABC; + end if; + when others => + end case; + else -- ($1C,$3C,$5C,$7C,$9C,$BC,$DC,$FC, $1D,$3D,$5D,$7D,$9D,$BD,$DD,$FD, $9E,$BE,$9F,$BF) + lCycle <= Cycle_4;--Or 3 if not page crossing + if IR(7 downto 6) /= "10" then + if Mode/="00" or IR(4)='0' or IR(1 downto 0)/="00" then + LDA <= '1'; + end if; + end if; + case MCycle is + when Cycle_sync => + when Cycle_1 => + Jump <= "01"; + LDBAL <= '1'; + when Cycle_2 => + Jump <= "01"; + -- special case $BE which uses Y reg as index!! + if(IR(7 downto 6)="10" and IR(4 downto 1)="1111") then + Set_BusA_To <= Set_BusA_To_Y; + else + Set_BusA_To <= Set_BusA_To_X; + end if; + BAAdd <= "10"; -- BA Add + LDBAH <= '1'; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_3 => + BAAdd <= "11"; -- BA adj + if IR(7 downto 5) = "100" then -- ($9E,$9F) + Write <= '1'; + else + BreakAtNA <= '1'; + end if; + Set_Addr_To <= Set_Addr_To_BA; + when Cycle_4 => + when others => + end case; + end if; + when others => + end case; + end process; - end if; + process (IR, MCycle, Mode,ALUmore) + begin + -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC + -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC + case IR(1 downto 0) is + when "00" => + case IR(4 downto 2) is + -- IR: $00,$20,$40,$60,$80,$A0,$C0,$E0 + -- $04,$24,$44,$64,$84,$A4,$C4,$E4 + -- $0C,$2C,$4C,$6C,$8C,$AC,$CC,$EC + when "000" | "001" | "011" => + case IR(7 downto 5) is + when "110" | "111" => -- CP ($C0,$C4,$CC,$E0,$E4,$EC) + ALU_Op <= ALU_OP_CMP; + when "101" => -- LD ($A0,$A4,$AC) + ALU_Op <= ALU_OP_EQ2; + when "001" => -- BIT ($20,$24,$2C - $20 is ignored, as its a jmp) + ALU_Op <= ALU_OP_BIT; + when others => -- other, NOP/ST ($x0,$x4,$xC) + ALU_Op <= ALU_OP_EQ1; + end case; - -- This decodes the current microcycle and takes the - -- proper course of action... - case to_integer(unsigned(MCycle)) is + -- IR: $08,$28,$48,$68,$88,$A8,$C8,$E8 + when "010" => + case IR(7 downto 5) is + when "111" | "110" => -- IN ($C8,$E8) + ALU_Op <= ALU_OP_INC; + when "100" => -- DEY ($88) + ALU_Op <= ALU_OP_DEC; + when others => -- LD + ALU_Op <= ALU_OP_EQ2; + end case; - -- On the T1 microcycle, increment the program counter - -- and instruct the upper level logic to fetch the offset - -- from the Din bus and store it in the data latches. This - -- will be the last microcycle if the branch isn't taken. - when 1 => + -- IR: $18,$38,$58,$78,$98,$B8,$D8,$F8 + when "110" => + case IR(7 downto 5) is + when "100" => -- TYA ($98) + ALU_Op <= ALU_OP_EQ2; + when others => + ALU_Op <= ALU_OP_EQ1; + end case; - Jump <= "01"; -- Increments the PC by one (PC will now be PC+2) - -- from microcycle T0. + -- IR: $10,$30,$50,$70,$90,$B0,$D0,$F0 + -- $14,$34,$54,$74,$94,$B4,$D4,$F4 + -- $1C,$3C,$5C,$7C,$9C,$BC,$DC,$FC + when others => + case IR(7 downto 5) is + when "101" => -- LD ($B0,$B4,$BC) + ALU_Op <= ALU_OP_EQ2; + when others => + ALU_Op <= ALU_OP_EQ1; + end case; + end case; - LDDI <= '1'; -- Tells logic in top level (T65.vhd) to route - -- the Din bus to the memory data latch (DL) - -- so that the branch offset is fetched. + when "01" => -- OR + case(to_integer(unsigned(IR(7 downto 5)))) is + when 0=> -- IR: $01,$05,$09,$0D,$11,$15,$19,$1D + ALU_Op<=ALU_OP_OR; + when 1=> -- IR: $21,$25,$29,$2D,$31,$35,$39,$3D + ALU_Op<=ALU_OP_AND; + when 2=> -- IR: $41,$45,$49,$4D,$51,$55,$59,$5D + ALU_Op<=ALU_OP_EOR; + when 3=> -- IR: $61,$65,$69,$6D,$71,$75,$79,$7D + ALU_Op<=ALU_OP_ADC; + when 4=>-- IR: $81,$85,$89,$8D,$91,$95,$99,$9D + ALU_Op<=ALU_OP_EQ1; -- STA + when 5=> -- IR: $A1,$A5,$A9,$AD,$B1,$B5,$B9,$BD + ALU_Op<=ALU_OP_EQ2; -- LDA + when 6=> -- IR: $C1,$C5,$C9,$CD,$D1,$D5,$D9,$DD + ALU_Op<=ALU_OP_CMP; + when others=> -- IR: $E1,$E5,$E9,$ED,$F1,$F5,$F9,$FD + ALU_Op<=ALU_OP_SBC; + end case; - -- In microcycle T2, tell the logic in the top level to - -- add the offset. If the most significant byte of the - -- program counter (i.e. the current "page") does not need - -- updating, we are done here...the Break signal at the - -- T65.vhd level takes care of that... - when 2 => + when "10" => + case(to_integer(unsigned(IR(7 downto 5)))) is + when 0=> -- IR: $02,$06,$0A,$0E,$12,$16,$1A,$1E + ALU_Op<=ALU_OP_ASL; + if IR(4 downto 2) = "110" and Mode/="00" then -- 00011010,$1A -> INC acc, not on 6502 + ALU_Op <= ALU_OP_INC; + end if; + when 1=> -- IR: $22,$26,$2A,$2E,$32,$36,$3A,$3E + ALU_Op<=ALU_OP_ROL; + if IR(4 downto 2) = "110" and Mode/="00" then -- 00111010,$3A -> DEC acc, not on 6502 + ALU_Op <= ALU_OP_DEC; + end if; + when 2=> -- IR: $42,$46,$4A,$4E,$52,$56,$5A,$5E + ALU_Op<=ALU_OP_LSR; + when 3=> -- IR: $62,$66,$6A,$6E,$72,$76,$7A,$7E + ALU_Op<=ALU_OP_ROR; + when 4=> -- IR: $82,$86,$8A,$8E,$92,$96,$9A,$9E + ALU_Op<=ALU_OP_BIT; + if IR(4 downto 2) = "010" then -- 10001010, $8A -> TXA + ALU_Op <= ALU_OP_EQ2; + else -- 100xxx10, $82,$86,$8E,$92,$96,$9A,$9E + ALU_Op <= ALU_OP_EQ1; + end if; + when 5=> -- IR: $A2,$A6,$AA,$AE,$B2,$B6,$BA,$BE + ALU_Op<=ALU_OP_EQ2; -- LDX + when 6=> -- IR: $C2,$C6,$CA,$CE,$D2,$D6,$DA,$DE + ALU_Op<=ALU_OP_DEC; + when others=> -- IR: $E2,$E6,$EA,$EE,$F2,$F6,$FA,$FE + ALU_Op<=ALU_OP_INC; + end case; - Jump <= "11"; -- Tell the PC Jump logic to use relative mode. + when others => -- "11" undoc double alu ops + case(to_integer(unsigned(IR(7 downto 5)))) is + -- IR: $A3,$A7,$AB,$AF,$B3,$B7,$BB,$BF + when 5 => + if IR=x"bb" then--LAS + ALU_Op <= ALU_OP_AND; + else + ALU_Op <= ALU_OP_EQ2; + end if; - PCAdd <= '1'; -- This tells the PC adder to update itself with - -- the current offset recently fetched from - -- memory. - - -- The following is microcycle T3 : - -- The program counter should be completely updated - -- on this cycle after the page cross is detected. - -- We don't need to do anything here... - when 3 => - - - when others => null; -- Do nothing. - - end case; - --}}} - - when "10001" | "10011" => - --{{{ - -- Zero Page Indirect Indexed (d),y - LCycle <= "101"; - if IR(7 downto 6) /= "10" then - LDA <= '1'; - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - LDAD <= '1'; - Set_Addr_To <= "10"; -- AD - when 2 => - LDBAL <= '1'; - BAAdd <= "01"; -- DB Inc - Set_Addr_To <= "10"; -- AD - when 3 => - Set_BusA_To <= "011"; -- Y - BAAdd <= "10"; -- BA Add - LDBAH <= '1'; - Set_Addr_To <= "11"; -- BA - when 4 => - BAAdd <= "11"; -- BA Adj - if IR(7 downto 5) = "100" then - Write <= '1'; - else - BreakAtNA <= '1'; - end if; - Set_Addr_To <= "11"; -- BA - when 5 => - when others => - end case; - --}}} - - when "10100" | "10101" | "10110" | "10111" => - --{{{ - -- Zero Page, X - if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then - -- Read-Modify-Write - LCycle <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Jump <= "01"; - LDAD <= '1'; - Set_Addr_To <= "10"; -- AD - when 2 => - ADAdd <= '1'; - Set_Addr_To <= "10"; -- AD - when 3 => - LDDI <= '1'; - Write <= '1'; - Set_Addr_To <= "10"; -- AD - when 4 => - LDALU <= '1'; - SaveP <= '1'; - Write <= '1'; - Set_Addr_To <= "10"; -- AD - when 5 => - when others => - end case; - else - LCycle <= "011"; - if IR(7 downto 6) /= "10" then - LDA <= '1'; - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - LDAD <= '1'; - Set_Addr_To <= "10"; -- AD - when 2 => - ADAdd <= '1'; - -- Added this check for Y reg. use... - if (IR(3 downto 0) = "0110") then - AddY <= '1'; - end if; - - if IR(7 downto 5) = "100" then - Write <= '1'; - end if; - Set_Addr_To <= "10"; -- AD - when 3 => null; - when others => - end case; - end if; - --}}} - - when "11001" | "11011" => - --{{{ - -- Absolute Y - LCycle <= "100"; - if IR(7 downto 6) /= "10" then - LDA <= '1'; - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - LDBAL <= '1'; - when 2 => - Jump <= "01"; - Set_BusA_To <= "011"; -- Y - BAAdd <= "10"; -- BA Add - LDBAH <= '1'; - Set_Addr_To <= "11"; -- BA - when 3 => - BAAdd <= "11"; -- BA adj - if IR(7 downto 5) = "100" then - Write <= '1'; - else - BreakAtNA <= '1'; - end if; - Set_Addr_To <= "11"; -- BA - when 4 => - when others => - end case; - --}}} - - when "11100" | "11101" | "11110" | "11111" => - --{{{ - -- Absolute X - - if IR(7 downto 6) /= "10" and IR(1 downto 0) = "10" then - -- Read-Modify-Write - LCycle <= "110"; - case to_integer(unsigned(MCycle)) is - when 1 => - Jump <= "01"; - LDBAL <= '1'; - when 2 => - Jump <= "01"; - Set_BusA_To <= "010"; -- X - BAAdd <= "10"; -- BA Add - LDBAH <= '1'; - Set_Addr_To <= "11"; -- BA - when 3 => - BAAdd <= "11"; -- BA adj - Set_Addr_To <= "11"; -- BA - when 4 => - LDDI <= '1'; - Write <= '1'; - Set_Addr_To <= "11"; -- BA - when 5 => - LDALU <= '1'; - SaveP <= '1'; - Write <= '1'; - Set_Addr_To <= "11"; -- BA - when 6 => - when others => - end case; - else - LCycle <= "100"; - if IR(7 downto 6) /= "10" then - LDA <= '1'; - end if; - case to_integer(unsigned(MCycle)) is - when 0 => - when 1 => - Jump <= "01"; - LDBAL <= '1'; - when 2 => - Jump <= "01"; - -- mikej - -- special case 0xBE which uses Y reg as index!! - if (IR = "10111110") then - Set_BusA_To <= "011"; -- Y - else - Set_BusA_To <= "010"; -- X - end if; - BAAdd <= "10"; -- BA Add - LDBAH <= '1'; - Set_Addr_To <= "11"; -- BA - when 3 => - BAAdd <= "11"; -- BA adj - if IR(7 downto 5) = "100" then - Write <= '1'; - else - BreakAtNA <= '1'; - end if; - Set_Addr_To <= "11"; -- BA - when 4 => - when others => - end case; - end if; - --}}} - when others => - end case; - end process; - - process (IR, MCycle) - begin - -- ORA, AND, EOR, ADC, NOP, LD, CMP, SBC - -- ASL, ROL, LSR, ROR, BIT, LD, DEC, INC - case IR(1 downto 0) is - when "00" => - --{{{ - case IR(4 downto 2) is - when "000" | "001" | "011" => - case IR(7 downto 5) is - when "110" | "111" => - -- CP - ALU_Op <= "0110"; - when "101" => - -- LD - ALU_Op <= "0101"; - when "001" => - -- BIT - ALU_Op <= "1100"; - when others => - -- NOP/ST - ALU_Op <= "0100"; - end case; - when "010" => - case IR(7 downto 5) is - when "111" | "110" => - -- IN - ALU_Op <= "1111"; - when "100" => - -- DEY - ALU_Op <= "1110"; - when others => - -- LD - ALU_Op <= "1101"; - end case; - when "110" => - case IR(7 downto 5) is - when "100" => - -- TYA - ALU_Op <= "1101"; - when others => - ALU_Op <= "----"; - end case; - when others => - case IR(7 downto 5) is - when "101" => - -- LD - ALU_Op <= "1101"; - when others => - ALU_Op <= "0100"; - end case; - end case; - --}}} - when "01" => -- OR - --{{{ - ALU_Op(3) <= '0'; - ALU_Op(2 downto 0) <= IR(7 downto 5); - --}}} - when "10" => - --{{{ - ALU_Op(3) <= '1'; - ALU_Op(2 downto 0) <= IR(7 downto 5); - case IR(7 downto 5) is - when "000" => - if IR(4 downto 2) = "110" then - -- INC - ALU_Op <= "1111"; - end if; - when "001" => - if IR(4 downto 2) = "110" then - -- DEC - ALU_Op <= "1110"; - end if; - when "100" => - if IR(4 downto 2) = "010" then - -- TXA - ALU_Op <= "0101"; - else - ALU_Op <= "0100"; - end if; - when others => - end case; - --}}} - when others => - --{{{ - case IR(7 downto 5) is - when "100" => - ALU_Op <= "0100"; - when others => - if MCycle = "000" then - ALU_Op(3) <= '0'; - ALU_Op(2 downto 0) <= IR(7 downto 5); - else - ALU_Op(3) <= '1'; - ALU_Op(2 downto 0) <= IR(7 downto 5); - end if; - end case; - --}}} - end case; - end process; + -- IR: $03,$07,$0B,$0F,$13,$17,$1B,$1F + -- $23,$27,$2B,$2F,$33,$37,$3B,$3F + -- $43,$47,$4B,$4F,$53,$57,$5B,$5F + -- $63,$67,$6B,$6F,$73,$77,$7B,$7F + -- $83,$87,$8B,$8F,$93,$97,$9B,$9F + -- $C3,$C7,$CB,$CF,$D3,$D7,$DB,$DF + -- $E3,$E7,$EB,$EF,$F3,$F7,$FB,$FF + when others => + if IR=x"6b" then -- ARR + ALU_Op<=ALU_OP_ARR; + elsif IR=x"8b" then -- ARR + ALU_Op<=ALU_OP_XAA; -- we can't use the bit operation as we don't set all flags... + elsif IR=x"0b" or IR=x"2b" then -- ANC + ALU_Op<=ALU_OP_ANC; + elsif IR=x"eb" then -- alternate SBC + ALU_Op<=ALU_OP_SBC; + elsif ALUmore='1' then + case(to_integer(unsigned(IR(7 downto 5)))) is + when 0=> + ALU_Op<=ALU_OP_OR; + when 1=> + ALU_Op<=ALU_OP_AND; + when 2=> + ALU_Op<=ALU_OP_EOR; + when 3=> + ALU_Op<=ALU_OP_ADC; + when 4=> + ALU_Op<=ALU_OP_EQ1; -- STA + when 5=> + ALU_Op<=ALU_OP_EQ2; -- LDA + when 6=> + ALU_Op<=ALU_OP_CMP; + when others=> + ALU_Op<=ALU_OP_SBC; + end case; + else + case(to_integer(unsigned(IR(7 downto 5)))) is + when 0=> + ALU_Op<=ALU_OP_ASL; + when 1=> + ALU_Op<=ALU_OP_ROL; + when 2=> + ALU_Op<=ALU_OP_LSR; + when 3=> + ALU_Op<=ALU_OP_ROR; + when 4=> + ALU_Op<=ALU_OP_BIT; + when 5=> + ALU_Op<=ALU_OP_EQ2; -- LDX + when 6=> + ALU_Op<=ALU_OP_DEC; + if IR(4 downto 2)="010" then -- $6B + ALU_Op<=ALU_OP_SAX; -- special SAX (SBX) case + end if; + when others=> + ALU_Op<=ALU_OP_INC; + end case; + end if; + end case; + end case; + end process; end; diff --git a/cores/VIC20/source/T65_Pack.vhd b/cores/VIC20/source/T65_Pack.vhd index e025e1b..c397739 100644 --- a/cores/VIC20/source/T65_Pack.vhd +++ b/cores/VIC20/source/T65_Pack.vhd @@ -1,18 +1,18 @@ -- **** -- T65(b) core. In an effort to merge and maintain bug fixes .... -- --- --- Ver 300 Bugfixes by ehenciak added --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- See list of changes in T65 top file (T65.vhd)... -- -- **** --- -- 65xx compatible microprocessor core -- --- Version : 0246 +-- FPGAARCADE SVN: $Id: T65_Pack.vhd 1234 2015-02-28 20:14:50Z wolfgang.scherr $ -- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- Copyright (c) 2002...2015 +-- Daniel Wallner (jesus opencores org) +-- Mike Johnson (mikej fpgaarcade com) +-- Wolfgang Scherr (WoS pin4 at> +-- Morten Leikvoll () -- -- All rights reserved -- @@ -42,76 +42,139 @@ -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- --- Please report bugs to the author, but before you do so, please +-- Please report bugs to the author(s), but before you do so, please -- make sure that this is not a derivative work and that -- you have the latest version of this file. -- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t65/ --- -- Limitations : --- --- File history : --- +-- See in T65 top file (T65.vhd)... library IEEE; use IEEE.std_logic_1164.all; package T65_Pack is - constant Flag_C : integer := 0; - constant Flag_Z : integer := 1; - constant Flag_I : integer := 2; - constant Flag_D : integer := 3; - constant Flag_B : integer := 4; - constant Flag_1 : integer := 5; - constant Flag_V : integer := 6; - constant Flag_N : integer := 7; + constant Flag_C : integer := 0; + constant Flag_Z : integer := 1; + constant Flag_I : integer := 2; + constant Flag_D : integer := 3; + constant Flag_B : integer := 4; + constant Flag_1 : integer := 5; + constant Flag_V : integer := 6; + constant Flag_N : integer := 7; - component T65_MCode - port( - Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65816 - IR : in std_logic_vector(7 downto 0); - MCycle : in std_logic_vector(2 downto 0); - P : in std_logic_vector(7 downto 0); - LCycle : out std_logic_vector(2 downto 0); - ALU_Op : out std_logic_vector(3 downto 0); - Set_BusA_To : out std_logic_vector(2 downto 0); -- DI,A,X,Y,S,P - Set_Addr_To : out std_logic_vector(1 downto 0); -- PC Adder,S,AD,BA - Write_Data : out std_logic_vector(2 downto 0); -- DL,A,X,Y,S,P,PCL,PCH - Jump : out std_logic_vector(1 downto 0); -- PC,++,DIDL,Rel - BAAdd : out std_logic_vector(1 downto 0); -- None,DB Inc,BA Add,BA Adj - BreakAtNA : out std_logic; - ADAdd : out std_logic; - AddY : out std_logic; - PCAdd : out std_logic; - Inc_S : out std_logic; - Dec_S : out std_logic; - LDA : out std_logic; - LDP : out std_logic; - LDX : out std_logic; - LDY : out std_logic; - LDS : out std_logic; - LDDI : out std_logic; - LDALU : out std_logic; - LDAD : out std_logic; - LDBAL : out std_logic; - LDBAH : out std_logic; - SaveP : out std_logic; - Write : out std_logic - ); - end component; + subtype T_Lcycle is std_logic_vector(2 downto 0); + constant Cycle_sync :T_Lcycle:="000"; + constant Cycle_1 :T_Lcycle:="001"; + constant Cycle_2 :T_Lcycle:="010"; + constant Cycle_3 :T_Lcycle:="011"; + constant Cycle_4 :T_Lcycle:="100"; + constant Cycle_5 :T_Lcycle:="101"; + constant Cycle_6 :T_Lcycle:="110"; + constant Cycle_7 :T_Lcycle:="111"; - component T65_ALU - port( - Mode : in std_logic_vector(1 downto 0); -- "00" => 6502, "01" => 65C02, "10" => 65C816 - Op : in std_logic_vector(3 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - P_In : in std_logic_vector(7 downto 0); - P_Out : out std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0) - ); - end component; + function CycleNext(c:T_Lcycle) return T_Lcycle; + + type T_Set_BusA_To is + ( + Set_BusA_To_DI, + Set_BusA_To_ABC, + Set_BusA_To_X, + Set_BusA_To_Y, + Set_BusA_To_S, + Set_BusA_To_P, + Set_BusA_To_DA, + Set_BusA_To_DAO, + Set_BusA_To_DAX, + Set_BusA_To_AAX, + Set_BusA_To_DONTCARE + ); + + type T_Set_Addr_To is + ( + Set_Addr_To_SP, + Set_Addr_To_ZPG, + Set_Addr_To_PBR, + Set_Addr_To_BA + ); + + type T_Write_Data is + ( + Write_Data_DL, + Write_Data_ABC, + Write_Data_X, + Write_Data_Y, + Write_Data_S, + Write_Data_P, + Write_Data_PCL, + Write_Data_PCH, + Write_Data_AX, + Write_Data_AXB, + Write_Data_XB, + Write_Data_YB, + Write_Data_DONTCARE + ); + + type T_ALU_OP is + ( + ALU_OP_OR, --"0000" + ALU_OP_AND, --"0001" + ALU_OP_EOR, --"0010" + ALU_OP_ADC, --"0011" + ALU_OP_EQ1, --"0100" EQ1 does not change N,Z flags, EQ2/3 does. + ALU_OP_EQ2, --"0101" Not sure yet whats the difference between EQ2&3. They seem to do the same ALU op + ALU_OP_CMP, --"0110" + ALU_OP_SBC, --"0111" + ALU_OP_ASL, --"1000" + ALU_OP_ROL, --"1001" + ALU_OP_LSR, --"1010" + ALU_OP_ROR, --"1011" + ALU_OP_BIT, --"1100" +-- ALU_OP_EQ3, --"1101" + ALU_OP_DEC, --"1110" + ALU_OP_INC, --"1111" + ALU_OP_ARR, + ALU_OP_ANC, + ALU_OP_SAX, + ALU_OP_XAA +-- ALU_OP_UNDEF--"----"--may be replaced with any? + ); + + type T_t65_dbg is record + I : std_logic_vector(7 downto 0); -- instruction + A : std_logic_vector(7 downto 0); -- A reg + X : std_logic_vector(7 downto 0); -- X reg + Y : std_logic_vector(7 downto 0); -- Y reg + S : std_logic_vector(7 downto 0); -- stack pointer + P : std_logic_vector(7 downto 0); -- processor flags + end record; end; + +package body T65_Pack is + + function CycleNext(c:T_Lcycle) return T_Lcycle is + begin + case(c) is + when Cycle_sync=> + return Cycle_1; + when Cycle_1=> + return Cycle_2; + when Cycle_2=> + return Cycle_3; + when Cycle_3=> + return Cycle_4; + when Cycle_4=> + return Cycle_5; + when Cycle_5=> + return Cycle_6; + when Cycle_6=> + return Cycle_7; + when Cycle_7=> + return Cycle_sync; + when others=> + return Cycle_sync; + end case; + end CycleNext; + +end T65_Pack; \ No newline at end of file diff --git a/cores/VIC20/source/m6522.vhd b/cores/VIC20/source/m6522.vhd index ca28f21..7a1691d 100644 --- a/cores/VIC20/source/m6522.vhd +++ b/cores/VIC20/source/m6522.vhd @@ -39,6 +39,7 @@ -- -- Revision list -- +-- version 003 Clearing PB7 when T1C-H is written by hoglet -- version 002 fix from Mark McDougall, untested -- version 001 initial release -- not very sure about the shift register, documentation is a bit light. @@ -48,8 +49,8 @@ library ieee ; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; -library UNISIM; - use UNISIM.Vcomponents.all; +--library UNISIM; +-- use UNISIM.Vcomponents.all; entity M6522 is port ( @@ -191,7 +192,6 @@ architecture RTL of M6522 is signal final_irq : std_logic; begin - p_phase : process begin -- internal clock phase @@ -275,8 +275,12 @@ begin end case; end if; - if (r_acr(7) = '1') and (t1_toggle = '1') then - r_orb(7) <= not r_orb(7); -- toggle + if (r_acr(7) = '1') then + if t1_load_counter then + r_orb(7) <= '0'; -- writing T1C-H resets bit 7 + elsif (t1_toggle = '1') then + r_orb(7) <= not r_orb(7); -- toggle + end if; end if; end if; end if; @@ -329,38 +333,41 @@ begin end if; end process; - p_read : process(cs, I_RW_L, I_RS, r_irb, r_ira, r_ddrb, r_ddra, t1c, r_t1l_l, - r_t1l_h, t2c, r_sr, r_acr, r_pcr, r_ifr, r_ier, r_orb) + p_read : process begin - t1_r_reset_int <= false; - t2_r_reset_int <= false; - sr_read_ena <= false; - r_irb_hs <= '0'; - r_ira_hs <= '0'; - O_DATA <= x"00"; -- default - if (cs = '1') and (I_RW_L = '1') then - case I_RS is - --when x"0" => O_DATA <= r_irb; r_irb_hs <= '1'; - -- fix from Mark McDougall, untested - when x"0" => O_DATA <= (r_irb and not r_ddrb) or (r_orb and r_ddrb); r_irb_hs <= '1'; - when x"1" => O_DATA <= r_ira; r_ira_hs <= '1'; - when x"2" => O_DATA <= r_ddrb; - when x"3" => O_DATA <= r_ddra; - when x"4" => O_DATA <= t1c( 7 downto 0); t1_r_reset_int <= true; - when x"5" => O_DATA <= t1c(15 downto 8); - when x"6" => O_DATA <= r_t1l_l; - when x"7" => O_DATA <= r_t1l_h; - when x"8" => O_DATA <= t2c( 7 downto 0); t2_r_reset_int <= true; - when x"9" => O_DATA <= t2c(15 downto 8); - when x"A" => O_DATA <= r_sr; sr_read_ena <= true; - when x"B" => O_DATA <= r_acr; - when x"C" => O_DATA <= r_pcr; - when x"D" => O_DATA <= r_ifr; - when x"E" => O_DATA <= ('0' & r_ier); - when x"F" => O_DATA <= r_ira; - when others => null; - end case; - end if; + wait until rising_edge(CLK); + + if ENA_4 = '1' then + t1_r_reset_int <= false; + t2_r_reset_int <= false; + sr_read_ena <= false; + r_irb_hs <= '0'; + r_ira_hs <= '0'; + + if (cs = '1') and (I_RW_L = '1') then + case I_RS is + --when x"0" => O_DATA <= r_irb; r_irb_hs <= '1'; + -- fix from Mark McDougall, untested + when x"0" => O_DATA <= (r_irb and not r_ddrb) or (r_orb and r_ddrb); r_irb_hs <= '1'; + when x"1" => O_DATA <= r_ira; r_ira_hs <= '1'; + when x"2" => O_DATA <= r_ddrb; + when x"3" => O_DATA <= r_ddra; + when x"4" => O_DATA <= t1c( 7 downto 0); t1_r_reset_int <= true; + when x"5" => O_DATA <= t1c(15 downto 8); + when x"6" => O_DATA <= r_t1l_l; + when x"7" => O_DATA <= r_t1l_h; + when x"8" => O_DATA <= t2c( 7 downto 0); t2_r_reset_int <= true; + when x"9" => O_DATA <= t2c(15 downto 8); + when x"A" => O_DATA <= r_sr; sr_read_ena <= true; + when x"B" => O_DATA <= r_acr; + when x"C" => O_DATA <= r_pcr; + when x"D" => O_DATA <= r_ifr; + when x"E" => O_DATA <= ('0' & r_ier); + when x"F" => O_DATA <= r_ira; + when others => null; + end case; + end if; + end if; end process; -- @@ -595,17 +602,14 @@ begin -- -- Timer 1 -- - p_timer1_done : process + p_timer1_done : process(t1c,phase,r_acr) variable done : boolean; begin - wait until rising_edge(CLK); - if (ENA_4 = '1') then done := (t1c = x"0000"); t1c_done <= done and (phase = "11"); - if (phase = "11") then + --if (phase = "11") then t1_reload_counter <= done and (r_acr(6) = '1'); - end if; - end if; + --end if; end process; p_timer1 : process @@ -624,12 +628,15 @@ begin elsif t1c_done then t1c_active <= false; end if; + if RESET_L = '0' then + t1c_active <= false; + end if; t1_toggle <= '0'; if t1c_active and t1c_done then t1_toggle <= '1'; t1_irq <= '1'; - elsif t1_w_reset_int or t1_r_reset_int or (clear_irq(6) = '1') then + elsif RESET_L = '0' or t1_w_reset_int or t1_r_reset_int or (clear_irq(6) = '1') then t1_irq <= '0'; end if; end if; @@ -648,17 +655,14 @@ begin end if; end process; - p_timer2_done : process + p_timer2_done : process(t2c,phase) variable done : boolean; begin - wait until rising_edge(CLK); - if (ENA_4 = '1') then done := (t2c = x"0000"); t2c_done <= done and (phase = "11"); - if (phase = "11") then + --if (phase = "11") then t2_reload_counter <= done; - end if; - end if; + --end if; end process; p_timer2 : process @@ -691,11 +695,13 @@ begin elsif t2c_done then t2c_active <= false; end if; - + if RESET_L = '0' then + t2c_active <= false; + end if; if t2c_active and t2c_done then t2_irq <= '1'; - elsif t2_w_reset_int or t2_r_reset_int or (clear_irq(5) = '1') then + elsif RESET_L = '0' or t2_w_reset_int or t2_r_reset_int or (clear_irq(5) = '1') then t2_irq <= '0'; end if; end if; @@ -732,7 +738,7 @@ begin free_run := '0'; case r_acr(4 downto 2) is - when "000" => ena := '0'; + when "000" => ena := '0'; cb1_ip := '1'; when "001" => ena := '1'; cb1_op := '1'; use_t2 := '1'; when "010" => ena := '1'; cb1_op := '1'; when "011" => ena := '1'; cb1_ip := '1'; @@ -744,28 +750,26 @@ begin end case; -- clock select - if (ena = '0') then - sr_strobe <= '1'; - else - if (cb1_ip = '1') then - sr_strobe <= I_CB1; - else - if (sr_cnt(3) = '0') and (free_run = '0') then - sr_strobe <= '1'; - else - if ((use_t2 = '1') and t2_sr_ena) or - ((use_t2 = '0') and (phase = "00")) then - sr_strobe <= not sr_strobe; - end if; - end if; - end if; - end if; + -- SR still runs even in disabled mode (on rising edge of CB1). It + -- just doesn't generate any interrupts. + -- Ref BBC micro advanced user guide p409 + if (cb1_ip = '1') then + sr_strobe <= I_CB1; + else + if (sr_cnt(3) = '0') and (free_run = '0') then + sr_strobe <= '1'; + else + if ((use_t2 = '1') and t2_sr_ena) or + ((use_t2 = '0') and (phase = "00")) then + sr_strobe <= not sr_strobe; + end if; + end if; + end if; -- latch on rising edge, shift on falling edge if sr_write_ena then r_sr <= load_data; - elsif (ena = '1') then -- use shift reg - + else if (dir_out = '0') then -- input if (sr_cnt(3) = '1') or (cb1_ip = '1') then @@ -792,7 +796,7 @@ begin sr_count_ena := sr_strobe_rising; - if sr_write_ena or sr_read_ena then + if ena = '1' and (sr_write_ena or sr_read_ena) then -- some documentation says sr bit in IFR must be set as well ? sr_cnt <= "1000"; elsif sr_count_ena and (sr_cnt(3) = '1') then diff --git a/cores/VIC20/source/roms/kernal.bin b/cores/VIC20/source/roms/kernal.bin index b7c0fc090f1805094c931d27837943c19ec8afc8..afcf5170061daa8029fa57438e6c3dcac6f29bb9 100644 GIT binary patch delta 70 zcmV-M0J;BwK!8B7bp!|KATz~GcgB;k4J5Om1Vjk}3?{SY4OtKdCXFPKsYtU$9v1-> c<|=p`NfWUT3J%i-I0I?{&;Ww~Hj{B5k6 ck|#hK#u0Q5?hHi+@d8ExxBzhgDwA;^k4BXi$^ZZW diff --git a/cores/VIC20/source/roms/vic20_kernal.vhd b/cores/VIC20/source/roms/vic20_kernal.vhd index a1391b2..06e47d7 100644 --- a/cores/VIC20/source/roms/vic20_kernal.vhd +++ b/cores/VIC20/source/roms/vic20_kernal.vhd @@ -209,7 +209,7 @@ begin attribute INIT_05 of inst : label is "DF51CF2DA100EB7AD683C099264780D302A091E0081C30323709D94911090234"; attribute INIT_06 of inst : label is "0C0C007ABD0A4A8366D005F8BC00F6277ECC300217140337C41C5170C26B7359"; attribute INIT_07 of inst : label is "3B400E0ED00EC0A649661D11DD0B7D20D4985C585811112F0104C18987A280B8"; - attribute INIT_08 of inst : label is "FFB1C4028D1C0CB137AB390C86A8A3761B2AB15A34620E015411B4DE02400D0A"; + attribute INIT_08 of inst : label is "FFB1C0028D1C0CB137AB390C86A8A3761B2AB15A34620E015411B4DE02400D0A"; attribute INIT_09 of inst : label is "FFFFFFFFFFFFFFFFFFFE04C328D19D0AC62075D111444751FFFFFFFFFFFFFFFF"; attribute INIT_0A of inst : label is "29297700124484184546D1A6619661DB476512491098451A585C329CCAC32842"; attribute INIT_0B of inst : label is "302E90D32919E002920B612B0CBD74946754705824841555987542D90136A302"; @@ -228,7 +228,7 @@ begin attribute INIT_18 of inst : label is "8728772C4616F0DDD755575327032C24D526AAAAAAAAAAAAAAAAA9018CAA1645"; attribute INIT_19 of inst : label is "729759407EEF09DDCD08BAD167CB966E1CA1D4B1105BC77773422E3459B2E59B"; attribute INIT_1A of inst : label is "FF76FFCFFFFF41651512597717259460601455C9805167273022E1379D3A5BC4"; - attribute INIT_1B of inst : label is "21991CC00000A5FFAB7FFFFFFFFFFFFFFFFFFFFFFBBFB0334E2C3FF97FE5BFC7"; + attribute INIT_1B of inst : label is "21991CC00000A8FFAB7FFFFFFFFFFFFFFFFFFFFFFBBFB0334E2C3FF97FE5BFC7"; attribute INIT_1C of inst : label is "8281D754748888888880CC1220038034745DC3340538A4E20040412222222222"; attribute INIT_1D of inst : label is "D17740524108400C2309042051DD760540A3410C88C15551C646751AAC00C111"; attribute INIT_1E of inst : label is "70C113192075D292075D5146A07012494500230555540C2305100C24BA920D35"; @@ -261,9 +261,9 @@ begin attribute INIT_39 of inst : label is "1570C0C6DD52191D14759D40119B809E0CA0EF33B3C18302D1432B855DC73754"; attribute INIT_3A of inst : label is "ABF6F8A6AC431DD8C7038466C44B0D458010518500C708E1A08D591046513567"; attribute INIT_3B of inst : label is "9675ACC1C7017699C484699B20804406848D92A1A4497572B090C6118656BD72"; - attribute INIT_3C of inst : label is "0BA0BA09411152D1B72644A103B45651564746670789E2789AE68919465D1745"; + attribute INIT_3C of inst : label is "0BA0BA09411152D1B72644A103B45451964746670789E2789AE68919465D1745"; attribute INIT_3D of inst : label is "3C64451590199D0592105184D30508C7326641502300585156055594A26A2682"; - attribute INIT_3E of inst : label is "30518082106992868E0802899D11157D479A0DB506E08645695519651D54506E"; + attribute INIT_3E of inst : label is "30518082306CBADD0A0802899D11157D479A0DB506E08645695519651D54506E"; attribute INIT_3F of inst : label is "E69FF418530C38C30F24638C38C38C38920B20B30A20D2CE28B28828718FFF0E"; begin inst : RAMB16_S2 @@ -354,7 +354,7 @@ begin attribute INIT_05 of inst : label is "D12A699B9500CB82E0BAF0E2054A0060030812A030ED02901B41E185A325801A"; attribute INIT_06 of inst : label is "4118000AB4FE93E0E27C5C8F9FC32578C18DC280390A002AC8E42874094B89D4"; attribute INIT_07 of inst : label is "26205195E2D9F2583CF09192128847C510A5502110A15E87028AC28A8E4257A1"; - attribute INIT_08 of inst : label is "FF5D0179812F04837E3559D18EA81080302A835105817B12BCD9A65B1198D934"; + attribute INIT_08 of inst : label is "FF5D0979812F04837E3559D18EA81080302A835105817B12BCD9A65B1198D934"; attribute INIT_09 of inst : label is "FFFFFFFFFFFFFFFFFFF3CA081BD5D18979283CF0F23C3F8FFFFFFFFFFFFFFFFF"; attribute INIT_0A of inst : label is "2B12782281A98A22F778B61D8F2E83A3FB4320C32822C72AE2D8055415411000"; attribute INIT_0B of inst : label is "3407DCD903D540A95161CB01C4BFCC24A49360549A49987F12CA5216A2455442"; @@ -373,7 +373,7 @@ begin attribute INIT_18 of inst : label is "83F60EE51E2877A50CEECCEFFCCFF9D775DEAAAAAAAAAAAAAAAAA64AB3AA1C87"; attribute INIT_19 of inst : label is "3EF0F571FC436650F3252ED52EA423C20FD83F9470A1DA9438C9473547A904F0"; attribute INIT_1A of inst : label is "FF0CFFDFFFFD7969298030FA2B030CA29F1C7E8E7C71CA3BCC94B682B86C8DFC"; - attribute INIT_1B of inst : label is "D3D34F800000D9FF3F7FFFFFFFFFFFFFFFFFFFFFF37F3F3CCD483FFB3FC8FFC3"; + attribute INIT_1B of inst : label is "D3D34F800000D7FF3F7FFFFFFFFFFFFFFFFFFFFFF37F3F3CCD483FFB3FC8FFC3"; attribute INIT_1C of inst : label is "62A0F3D6BC890890890C1D02410B443C3C8FD0390585781A1600B278D278D278"; attribute INIT_1D of inst : label is "F23FC25B89164528434D18B050FE3F058AE0B22090823CB6053CB8FAAD100611"; attribute INIT_1E of inst : label is "7C016015283CF59283CF5A45E0BC63B245844108F2C9084345293D2CA2D3CEF8"; @@ -406,9 +406,9 @@ begin attribute INIT_39 of inst : label is "7ED3C21CF1E03E0B20D8FEE2916200D9B8889A31420A8E2852E0377D298E1577"; attribute INIT_3A of inst : label is "8C0849BF2C0860001B146CCC004803FD0398E30F030F2AC3434DDDD83F8F07EC"; attribute INIT_3B of inst : label is "F3FAEFBBB4109431C02C832ECBC804011005C04045A0D44443120C31895B0C50"; - attribute INIT_3C of inst : label is "70C70D01C111D0721E0A499936541C87A3CBC3CB43C0300C03C0C0FE3F8B22C8"; + attribute INIT_3C of inst : label is "70C70D01C111D0721E0A499936541E8763CBC3CB43C0300C03C0C0FE3F8B22C8"; attribute INIT_3D of inst : label is "F03E1CF5E428FE88F0D8E30CC140C30F30A3E0FAA8B80A80028006800C30C340"; - attribute INIT_3E of inst : label is "C087AAA202105FD1842AA92CFE2832FB2FBA0E0D0ADC43E2CB2CB2D8B520D0AD"; + attribute INIT_3E of inst : label is "C087AAA100224EC2E92AA92CFE2832FB2FBA0E0D0ADC43E2CB2CB2D8B520D0AD"; attribute INIT_3F of inst : label is "CCEFF4DB5D73CB2D35D74C71C30CF3CBEF3DF7DF7DF7EFFBF3CFFCF7DF3FFC71"; begin inst : RAMB16_S2 @@ -499,7 +499,7 @@ begin attribute INIT_05 of inst : label is "78093C866000E409024102299A09A26B88AA424A0AA7866AA9E4C63A484A5AA9"; attribute INIT_06 of inst : label is "2AA6001AB10F47CEF6F39C1724DF3EDDCF27065A98428AB926E1029E12A40A62"; attribute INIT_07 of inst : label is "6A52CCCCDB88DB4630C2448242D3636006A006600620425026FBB83CAB878C7A"; - attribute INIT_08 of inst : label is "FF30E0C4E42CAD018C8084C0C2AAD81080AA9004914801AA92AEABE1AB82AAA8"; + attribute INIT_08 of inst : label is "FF30E8C4E42CAD018C8084C0C2AAD81080AA9004914801AA92AEABE1AB82AAA8"; attribute INIT_09 of inst : label is "FFFFFFFFFFFFFFFFFFFD0A1EB88282130E8D5169886A619AFFFFFFFFFFFFFFFF"; attribute INIT_0A of inst : label is "48997B5A05958A0080080200800084A01804241023209000E0AE99A244399A66"; attribute INIT_0B of inst : label is "8082232FC4028A5434A34F23AD0DAD9090A0BA4D9937992F4009F4464DD9910B"; @@ -518,7 +518,7 @@ begin attribute INIT_18 of inst : label is "66850700024555BFFAAAAAA99AA99B323C8EAAAAAAAAAAAAAAAAA21020AA4012"; attribute INIT_19 of inst : label is "7EF05FAC1AFD6AAAC5EA87144D0103019F141400011559AAB1BFF10513C04080"; attribute INIT_1A of inst : label is "FF06FFCFFFFE458507A441BA42C4108424412E109104084317AA1BEE36F80EFA"; - attribute INIT_1B of inst : label is "90140040000094FF553FFFFFFFFFFFFFFFFFFFFFF73F5571BFF2FFF3BFC0BFE7"; + attribute INIT_1B of inst : label is "90140040000098FF553FFFFFFFFFFFFFFFFFFFFFF73F5571BFF2FFF3BFC0BFE7"; attribute INIT_1C of inst : label is "B43545A0A2D2EF2ED2E1A8ACBAAE6AA250168872A4A122AC58EA208E38D34D24"; attribute INIT_1D of inst : label is "405A294A205B369FBA28AAE2494E5A2415E8A29F2E1A6982586019AAA8AA1A8D"; attribute INIT_1E of inst : label is "A236AA63CD516A34D516825AE8A2AAC23A5FB869A60AADBA282E88AD088A6E99"; @@ -551,9 +551,9 @@ begin attribute INIT_39 of inst : label is "4EDF2A10610CAF9826398ECB060B6FEA7E258D9627EE9FB286C8734C06DD9132"; attribute INIT_3A of inst : label is "F3F3333B6ED051331D801EA032D061CC8266FB6CA21F97EA86AAAAAE501684EC"; attribute INIT_3B of inst : label is "853B2F3B888510021D01806F006389822FB6D88480A010330BB604118B337BFF"; - attribute INIT_3C of inst : label is "00020860244648421843ACCCB3326098260A250A2509426098E5098653942609"; + attribute INIT_3C of inst : label is "00020860244648421843ACCCB3326098A60A250A2509426098E5098653942609"; attribute INIT_3D of inst : label is "2A52594C27214E0160A6FB69EBE5A21F9CA58561006E11844611168E00008218"; - attribute INIT_3E of inst : label is "8D83C40233030234492AA8194A8965375378121AD8D3E525065941996825AE8D"; + attribute INIT_3E of inst : label is "8D83C403012310347A2AA8194A8965375378121AD8D3E525065941996825AE8D"; attribute INIT_3F of inst : label is "FEEFF82083C28A2B8E3CC0A28A286186C34D24920B28938930F20838D34FFC61"; begin inst : RAMB16_S2 @@ -644,7 +644,7 @@ begin attribute INIT_05 of inst : label is "C226BC2038006C6B1B97126F098B826F09B422F35EEE01D3BB82D206D016D3BB"; attribute INIT_06 of inst : label is "0E34008A9ED49961579547DDD04B9EC7A91E41D3B8ADD38B0EA2B5B805AC636B"; attribute INIT_07 of inst : label is "CCA22222E022E02238E2226262CDBA222EA22EA22E62665D9F0CF323D9CDF5BB"; - attribute INIT_08 of inst : label is "FFD70757422F1CC2D8BBF37B000011551500205515535C38BC328C2C38B0224C"; + attribute INIT_08 of inst : label is "FFD70F57422F1CC2D8BBF37B000011551500205515535C38BC328C2C38B0224C"; attribute INIT_09 of inst : label is "FFFFFFFFFFFFFFFFFFFE492F35AEAE3B5A5F8E2620898B22FFFFFFFFFFFFFFFF"; attribute INIT_0A of inst : label is "3E0BBBCFC84E8A82BB88A2288A288AE2BB8A28A0A302A280C2B87BB8EE2489A2"; attribute INIT_0B of inst : label is "388AE3E7CAEED11BFFF186219FEEF8A8A8B9E1ECC40ECBBEE203B3E103BBBB8B"; @@ -696,9 +696,9 @@ begin attribute INIT_39 of inst : label is "2FAFC408A08CAC2268BA26C12E8BC3AB7C2CBF3EFFC6FF12A6C0EF5A1ABC3B6A"; attribute INIT_3A of inst : label is "73F3F73BF9C82EE208BB8E6FC5FCE3D8B170F34E213C39E6CEDBABA1882242F8"; attribute INIT_3B of inst : label is "289BBB3BDF38E8AEEF288A2D4A22323EEE3AE3CFF8A2ABAA88BF08228BB7FFF7"; - attribute INIT_3C of inst : label is "A28A28929A8AA4A228CE9AAA6AA989A2A8BB88AB888A2A88A2E88A2E8BA2689A"; + attribute INIT_3C of inst : label is "A28A28929A8AA4A228CE9AAA6AA989A228BB88AB888A2A88A2E88A2E8BA2689A"; attribute INIT_3D of inst : label is "78898A28E34A26622C70F343F308213C0C2812266415E88FF93FE6B928A28A24"; - attribute INIT_3E of inst : label is "4C0299901213131312599A2A2C0628B68B683028C2D70898898A224E2A088C2D"; + attribute INIT_3E of inst : label is "4C0299902310302113599A2A2C0628B68B683028C2D70898898A224E2A088C2D"; attribute INIT_3F of inst : label is "DCEFFC71C71041075D75D41041041041D75D71C71F7DC75C79D7DF75D75FFC10"; begin inst : RAMB16_S2 diff --git a/cores/VIC20/source/vic20.vhd b/cores/VIC20/source/vic20.vhd index 955b003..78050cc 100644 --- a/cores/VIC20/source/vic20.vhd +++ b/cores/VIC20/source/vic20.vhd @@ -1,4 +1,4 @@ --- +-- Port to ZX-UNO and modifications by Quest 2016 -- A simulation model of VIC20 hardware -- Copyright (c) MikeJ - March 2003 -- @@ -52,12 +52,6 @@ library UNISIM; entity VIC20 is port ( --- O_STRATAFLASH_ADDR : out std_logic_vector(23 downto 0); --- B_STRATAFLASH_DATA : inout std_logic_vector(7 downto 0); --- O_STRATAFLASH_CE_L : out std_logic; --- O_STRATAFLASH_OE_L : out std_logic; --- O_STRATAFLASH_WE_L : out std_logic; --- O_STRATAFLASH_BYTE : out std_logic; -- I_PS2_CLK : in std_logic; I_PS2_DATA : in std_logic; @@ -72,13 +66,13 @@ entity VIC20 is O_AUDIO_L : out std_logic; O_AUDIO_R : out std_logic; - O_NTSC : out std_logic; - O_PAL : out std_logic; + O_NTSC : out std_logic; + O_PAL : out std_logic; -- --- I_SW : in std_logic_vector(3 downto 0); --- O_LED : out std_logic_vector(3 downto 0); + I_SW : in std_logic_vector(4 downto 0); + LED : out std_logic; + EAR : in std_logic; -- - I_RESET : in std_logic; I_CLK_REF : in std_logic ); @@ -86,9 +80,11 @@ end; architecture RTL of VIC20 is -- default - constant K_OFFSET : std_logic_vector (4 downto 0) := "11100"; -- h position of screen to centre on your telly + constant K_OFFSET : std_logic_vector (4 downto 0) := "10000"; -- h position of screen to centre on your telly -- lunar lander is WAY off to the left - --constant K_OFFSET : std_logic_vector (4 downto 0) := "11100"; -- h position of screen to centre on your telly + + -- 1 = enable cartridge + constant Cartridge : std_logic := '1'; signal I_RESET_L : std_logic; signal clk_8 : std_logic; @@ -97,9 +93,14 @@ architecture RTL of VIC20 is signal reset_l_sampled : std_logic; -- cpu signal c_ena : std_logic; - signal c_addr : std_logic_vector(23 downto 0); signal c_din : std_logic_vector(7 downto 0); - signal c_dout : std_logic_vector(7 downto 0); + + signal c_addr : unsigned(15 downto 0); + signal c_dout : unsigned(7 downto 0); + + signal c_addrT : std_logic_vector(23 downto 0); --T65 + signal c_doutT : std_logic_vector(7 downto 0); -- T65 + signal c_rw_l : std_logic; signal c_irq_l : std_logic; signal c_nmi_l : std_logic; @@ -144,6 +145,10 @@ architecture RTL of VIC20 is signal expansion_nmi_l : std_logic; signal expansion_irq_l : std_logic; + signal blk1_dout: std_logic_vector(7 downto 0); + signal blk2_dout: std_logic_vector(7 downto 0); + signal blk3_dout: std_logic_vector(7 downto 0); + -- VIAs signal via1_nmi_l : std_logic; signal via1_pa_in : std_logic_vector(7 downto 0); @@ -155,6 +160,7 @@ architecture RTL of VIC20 is signal cass_read : std_logic; signal cass_motor : std_logic; signal cass_sw : std_logic; + signal cass_n : std_logic; signal keybd_col_out : std_logic_vector(7 downto 0); signal keybd_col_in : std_logic_vector(7 downto 0); @@ -184,7 +190,9 @@ architecture RTL of VIC20 is signal user_port_oe_l : std_logic_vector(7 downto 0); -- misc signal sw_reg : std_logic_vector(3 downto 0); --- signal cart_data : std_logic_vector(7 downto 0); + signal cart_data : std_logic_vector(7 downto 0); + signal cart2_data : std_logic_vector(7 downto 0); + signal cart3_data : std_logic_vector(7 downto 0); signal video_r : std_logic_vector(3 downto 0); signal video_g : std_logic_vector(3 downto 0); @@ -200,24 +208,39 @@ architecture RTL of VIC20 is signal blanking : std_logic; signal blanking_x2 : std_logic; + signal scanSW : std_logic_vector(6 downto 0); --q + + SIGNAL inff : STD_LOGIC_VECTOR(1 DOWNTO 0); -- input flip flops + CONSTANT cnt_max : INTEGER := (33000000/50)-1 ; -- 33MHz and 1/20ms=50Hz + SIGNAL count : INTEGER range 0 to cnt_max := 0; + constant prueb : integer := 30; + + signal clk_4 : std_logic; + signal ena_4b : std_logic; + + signal we0 : std_logic; + signal we1 : std_logic; + signal we2 : std_logic; + signal we3 : std_logic; + signal we4 : std_logic; + signal we5 : std_logic; + + signal EXP8K : std_logic; + + signal P_RESET: std_logic; + begin + + EXP8K <= not scanSW(5); O_NTSC <= '0'; O_PAL <= '1'; - -- - -- - -- IO connect these to the outside world if you wish ... - -- - - -- expansion port - -- <= c_addr; --- p_expansion : process(blk_sel_l, cart_data) --- begin - expansion_din <= x"FF"; --- if (blk_sel_l(5) = '0') then --- expansion_din <= cart_data; --- end if; --- end process; + + expansion_din <= cart_data when (scanSW(1) = '1' and blk_sel_l(5) = '0') + else cart2_data when (scanSW(2) = '1' and blk_sel_l(5) = '0') + else cart3_data when (scanSW(3) = '1' and blk_sel_l(5) = '0') else x"FF"; + + -- <= c_rw_l; -- <= v_rw_l; expansion_nmi_l <= '1'; @@ -225,7 +248,6 @@ begin -- <= ram_sel_l; -- <= io_sel_l; -- <= reset_l_sampled; - -- user port user_port_cb1_in <= '0'; user_port_cb2_in <= '0'; @@ -234,10 +256,9 @@ begin -- <= user_port_out_oe_l -- tape - cass_read <= '0'; - --<= cass_write; - --<= cass_motor - cass_sw <= '1'; -- motor off + cass_n <= EAR; + cass_read <= not cass_n; + cass_sw <= '0'; -- motor off -- serial serial_srq_in <= '0'; @@ -248,14 +269,19 @@ begin -- <= serial_data_out_l -- joy - joy <= "1111"; -- 0 up, 1 down, 2 left, 3 right - light_pen <= '1'; -- also used for fire button + -- joy <= "1111"; -- 0 up, 1 down, 2 left, 3 right + -- light_pen <= '1'; -- also used for fire button + joy <= I_SW(3 downto 0); -- "1111"; -- 0 up, 1 down, 2 left, 3 right + light_pen <= I_SW(4); -- was '1'; -- also used for fire button -- -- -- - I_RESET_L <= not I_RESET; + I_RESET_L <= '1'; + + reset_l_sampled <= P_RESET and not scanSW(4); --manual reset (F12) -- - u_clocks : entity work.VIC20_CLOCKS + + u_clocks : entity work.relojes port map ( I_CLK_REF => I_CLK_REF, I_RESET_L => I_RESET_L, @@ -264,17 +290,29 @@ begin -- O_ENA => ena_4, O_CLK => clk_8, - O_RESET_L => reset_l_sampled + + O_RESET_L => P_RESET ); c_ena <= ena_1mhz and ena_4; -- clk ena + + clkdiv2: process(clk_8) + begin + if clk_8'event AND clk_8 = '1' then + ena_4b <= not ena_4b; + clk_4 <= not clk_4; + end if; + end process; + + c_addr <= unsigned(c_addrT(15 downto 0)); --T65 + c_dout <= unsigned(c_doutT); --T65 cpu : entity work.T65 port map ( Mode => "00", Res_n => reset_l_sampled, - Enable => c_ena, - Clk => clk_8, + Enable => ena_1mhz, --c_ena, + Clk => clk_4, --clk_8, Rdy => '1', Abort_n => '1', IRQ_n => c_irq_l, @@ -289,11 +327,27 @@ begin VP_n => open, VDA => open, VPA => open, - A => c_addr, + A => c_addrT, DI => c_din, - DO => c_dout + DO => c_doutT ); +-- cpu : entity work.R65C02 --R65V02 +-- port map ( +-- Reset => reset_l_sampled, +-- Clk => clk_4, --clk_8, +-- Enable => ena_1mhz, --c_ena, +-- NMI_n => c_nmi_l, +-- IRQ_n => c_irq_l, +-- DI => unsigned(c_din), +-- DO => c_dout, +-- ADDR => c_addr, +-- nwe => c_rw_l, +-- Sync => open, +-- sync_irq => open +-- ); + + vic : entity work.VIC20_VIC generic map ( K_OFFSET => K_OFFSET @@ -317,7 +371,7 @@ begin O_HSYNC => hsync, O_VSYNC => vsync, O_COMP_SYNC_L => csync, - O_BLANK => blanking, +-- O_BLANK => blanking, -- -- I_LIGHT_PEN => light_pen, @@ -332,7 +386,7 @@ begin via1 : entity work.M6522 port map ( - I_RS => c_addr(3 downto 0), + I_RS => std_logic_vector(c_addr(3 downto 0)), I_DATA => v_data(7 downto 0), O_DATA => via1_dout, O_DATA_OE_L => open, @@ -383,7 +437,7 @@ begin via2 : entity work.M6522 port map ( - I_RS => c_addr(3 downto 0), + I_RS => std_logic_vector(c_addr(3 downto 0)), I_DATA => v_data(7 downto 0), O_DATA => via2_dout, O_DATA_OE_L => open, @@ -448,9 +502,10 @@ begin I_ENA_1MHZ => ena_1mhz, I_P2_H => p2_h, - RESET_L => reset_l_sampled, + RESET_L => '1', ENA_4 => ena_4, CLK => clk_8 + ,scanSW => scanSW --q ); p_irq_resolve : process(expansion_irq_l, expansion_nmi_l, @@ -515,8 +570,8 @@ begin v_rw_l <= '1'; col_ram_sel_l <= '1'; -- colour ram has dedicated mux for vic, so disable else -- cpu - v_addr(13 downto 0) <= blk_sel_l(4) & c_addr(12 downto 0); - v_data <= c_dout; + v_addr(13 downto 0) <= blk_sel_l(4) & std_logic_vector(c_addr(12 downto 0)); + v_data <= std_logic_vector(c_dout); v_rw_l <= c_rw_l; col_ram_sel_l <= io_sel_l(1); end if; @@ -553,7 +608,7 @@ begin vic_din(7 downto 0) <= v_data(7 downto 0); end process; - p_v_read_mux : process(col_ram_sel_l, ram_sel_l, vic_oe_l, v_addr, + p_v_read_mux : process(col_ram_sel_l, ram_sel_l, blk_sel_l, vic_oe_l, v_addr, col_ram_dout, ram0_dout, ram45_dout, ram67_dout, vic_dout, char_rom_dout, v_data_read_muxr) @@ -597,15 +652,15 @@ begin p_v_bus_hold : process begin - wait until rising_edge(clk_8); - if (ena_4 = '1') then - v_data_read_muxr <= v_data_read_mux; - end if; + wait until rising_edge(clk_4); + v_data_read_muxr <= v_data_read_mux; end process; - + -- + p_cpu_read_mux : process(p2_h, c_addr, io_sel_l, ram_sel_l, blk_sel_l, v_data_read_mux, via1_dout, via2_dout, v_data_oe_l, - basic_rom_dout, kernal_rom_dout, expansion_din) + basic_rom_dout, kernal_rom_dout, expansion_din, + blk1_dout, blk2_dout, blk3_dout) begin if (p2_h = '0') then -- vic is on the bus @@ -615,6 +670,10 @@ begin c_din <= via1_dout; elsif (io_sel_l(0) = '0') and (c_addr(5) = '1') then -- blk4 c_din <= via2_dout; + elsif (blk_sel_l(1) = '0' and EXP8K = '1') then + c_din <= blk1_dout; + elsif (blk_sel_l(2) = '0' and EXP8K = '1') then + c_din <= blk2_dout; elsif (blk_sel_l(5) = '0') then c_din <= expansion_din; elsif (blk_sel_l(6) = '0') then @@ -630,53 +689,99 @@ begin -- -- main memory -- - rams0 : entity work.VIC20_RAMS + + we0 <= (not ram_sel_l(0)) and (not v_rw_l ); + + rams0 : entity work.DistRAM + generic map ( + addr_width_g => 10, + data_width_g => 8 + ) port map ( - V_ADDR => v_addr(9 downto 0), - DIN => v_data, - DOUT => ram0_dout, - V_RW_L => v_rw_l, - CS1_L => ram_sel_l(0), - CS2_L => '1', - ENA => ena_4, - CLK => clk_8 + clk_i => clk_8, + ena => ena_4, + a_i => v_addr(9 downto 0), + we_i => we0, + d_i => v_data, + d_o => ram0_dout ); - rams45 : entity work.VIC20_RAMS + we1 <= ((not ram_sel_l(4)) or (not ram_sel_l(5))) and (not v_rw_l ); + + rams45 : entity work.DistRAM + generic map ( + addr_width_g => 11, + data_width_g => 8 + ) port map ( - V_ADDR => v_addr(9 downto 0), - DIN => v_data, - DOUT => ram45_dout, - V_RW_L => v_rw_l, - CS1_L => ram_sel_l(4), - CS2_L => ram_sel_l(5), - ENA => ena_4, - CLK => clk_8 + clk_i => clk_8, + ena => ena_4, + a_i => v_addr(10 downto 0), + we_i => we1, + d_i => v_data, + d_o => ram45_dout ); - rams67 : entity work.VIC20_RAMS + we2 <= ((not ram_sel_l(6)) or (not ram_sel_l(7))) and (not v_rw_l ); + + rams67 : entity work.DistRAM + generic map ( + addr_width_g => 11, + data_width_g => 8 + ) port map ( - V_ADDR => v_addr(9 downto 0), - DIN => v_data, - DOUT => ram67_dout, - V_RW_L => v_rw_l, - CS1_L => ram_sel_l(6), - CS2_L => ram_sel_l(7), - ENA => ena_4, - CLK => clk_8 + clk_i => clk_8, + ena => ena_4, + a_i => v_addr(10 downto 0), + we_i => we2, + d_i => v_data, + d_o => ram67_dout ); - - col_ram : entity work.VIC20_RAM + we3 <= (not col_ram_sel_l) and (not v_rw_l ); + + col_ram : entity work.DistRAM + generic map ( + addr_width_g => 10, + data_width_g => 8 + ) port map ( - V_ADDR => v_addr(9 downto 0), - DIN => v_data, - DOUT => col_ram_dout, - V_RW_L => v_rw_l, - CS_L => col_ram_sel_l, - ENA => ena_4, - CLK => clk_8 + clk_i => clk_8, + ena => ena_4, + a_i => v_addr(9 downto 0), + we_i => we3, + d_i => v_data(7 downto 0), + d_o => col_ram_dout(7 downto 0) ); + +------------------------------------------------------------------------- + +--8k 1 + blk1_inst : entity work.VIC20_RAM8 + port map + ( + V_ADDR => std_logic_vector(c_addr(12 downto 0)), + DIN => v_data, + DOUT => blk1_dout, + V_RW_L => v_rw_l, + CS_L => blk_sel_l(1), + ENA => ena_4, + CLK => clk_8 + ); + +--8k 2 + blk2_inst : entity work.VIC20_RAM8 + port map + ( + V_ADDR => std_logic_vector(c_addr(12 downto 0)), + DIN => v_data, + DOUT => blk2_dout, + V_RW_L => v_rw_l, + CS_L => blk_sel_l(2), + ENA => ena_4, + CLK => clk_8 + ); + -- -- roms -- @@ -692,7 +797,7 @@ begin port map ( CLK => clk_8, ENA => ena_4, - ADDR => c_addr(12 downto 0), + ADDR => std_logic_vector(c_addr(12 downto 0)), DATA => basic_rom_dout ); @@ -700,9 +805,41 @@ begin port map ( CLK => clk_8, ENA => ena_4, - ADDR => c_addr(12 downto 0), + ADDR => std_logic_vector(c_addr(12 downto 0)), DATA => kernal_rom_dout ); + + -- + -- cart slots 0xA000-0xBFFF (8K) + -- + + --1st cartridge + cartridge_rom : entity work.VIC20_CARTRIDGE + port map ( + CLK => clk_8, + ENA => ena_4, + ADDR => std_logic_vector(c_addr(12 downto 0)), + DATA => cart_data + ); + + --2nd cartridge, for swap + cartridge2_rom : entity work.VIC20_CARTRIDGE2 + port map ( + CLK => clk_8, + ENA => ena_4, + ADDR => std_logic_vector(c_addr(12 downto 0)), + DATA => cart2_data + ); + + --3rd cartridge, for swap + cartridge3_rom : entity work.VIC20_CARTRIDGE3 + port map ( + CLK => clk_8, + ENA => ena_4, + ADDR => std_logic_vector(c_addr(12 downto 0)), + DATA => cart3_data + ); + -- -- scan doubler -- @@ -727,29 +864,27 @@ begin ); -- - -- Scandoubler. Descomentar para activar VGA - p_video_ouput : process + p_video_ouput : process begin wait until rising_edge(clk_8); - O_VIDEO_R <= video_r_x2(3 downto 1); - O_VIDEO_G <= video_g_x2(3 downto 1); - O_VIDEO_B <= video_b_x2(3 downto 1); - O_HSYNC <= hSync_X2; - O_VSYNC <= vSync_X2; + if (scanSW(0) = '1') then -- was sw_reg(0) + O_VIDEO_R <= video_r_x2(3 downto 1); + O_VIDEO_G <= video_g_x2(3 downto 1); + O_VIDEO_B <= video_b_x2(3 downto 1); + O_HSYNC <= hSync_X2; + O_VSYNC <= vSync_X2; + else + --O_LED(0) <= '0'; + O_VIDEO_R <= video_r(3 downto 1); + O_VIDEO_G <= video_g(3 downto 1); + O_VIDEO_B <= video_b(3 downto 1); + --O_HSYNC <= hSync; + --O_VSYNC <= vSync; + O_HSYNC <= cSync; + O_VSYNC <= '1'; + end if; end process; - - -- Sin Scandoubler. Descomentar para activar RGB/Vcomp (de momento se ve mal) --- p_video_ouput : process --- begin --- wait until rising_edge(clk_8); --- O_VIDEO_R <= video_r(3 downto 1); --- O_VIDEO_G <= video_g(3 downto 1); --- O_VIDEO_B <= video_b(3 downto 1); --- O_HSYNC <= hSync; --- O_VSYNC <= vSync; --- end process; - -- -- Audio -- @@ -767,33 +902,15 @@ begin O_AUDIO_L <= audio_pwm; O_AUDIO_R <= audio_pwm; - -- - -- cart slot 0xA000-0xBFFF (8K) - -- --- p_flash : process --- begin --- wait until rising_edge(clk_8); --- O_LED(3 downto 1) <= sw_reg(3 downto 1); --- --- O_STRATAFLASH_CE_L <= '1'; --- if (sw_reg(1) = '1') then -- enable cart --- O_STRATAFLASH_CE_L <= blk_sel_l(5); --- end if; --- O_STRATAFLASH_OE_L <= '0'; --- O_STRATAFLASH_WE_L <= '1'; --- O_STRATAFLASH_BYTE <= '0'; --- --- O_STRATAFLASH_ADDR(23 downto 15) <= (others => '0'); --- O_STRATAFLASH_ADDR(14 downto 13) <= sw_reg(3 downto 2); --- O_STRATAFLASH_ADDR(12 downto 0) <= c_addr(12 downto 0); -- 8K --- --- B_STRATAFLASH_DATA <= (others => 'Z'); --- -- should really sample and latch this at the correct point, but it seems to work --- if (sw_reg(1) = '1') then -- enable cart --- cart_data <= B_STRATAFLASH_DATA; --- else --- cart_data <= (others => '1'); --- end if; --- end process; + LED <= EXP8K; --on = +16k expanded VIC20, off = not expanded + +------------multiboot--------------- + multiboot: entity work.multiboot + port map( + clk_icap => clk_8, + REBOOT => scanSW(6) --mreset key combo + ); + + end RTL; diff --git a/cores/VIC20/source/vic20_dblscan.vhd b/cores/VIC20/source/vic20_dblscan.vhd index 8356e80..fe7e886 100644 --- a/cores/VIC20/source/vic20_dblscan.vhd +++ b/cores/VIC20/source/vic20_dblscan.vhd @@ -94,7 +94,7 @@ architecture RTL of VIC20_DBLSCAN is -- signal vs_cnt : std_logic_vector(2 downto 0); signal rgb_out : std_logic_vector(15 downto 0); - + begin p_input_timing : process @@ -194,8 +194,9 @@ begin if (hpos_o < 32) then -- may need tweaking ! O_HSYNC <= '1'; end if; + + O_BLANK <= rgb_out(12); - O_BLANK <= rgb_out(12); O_B <= rgb_out(11 downto 8); O_G <= rgb_out(7 downto 4); O_R <= rgb_out(3 downto 0); @@ -205,4 +206,3 @@ begin end process; end architecture RTL; - diff --git a/cores/VIC20/source/vic20_ps2_if.vhd b/cores/VIC20/source/vic20_ps2_if.vhd index 09c0adc..47d9fcd 100644 --- a/cores/VIC20/source/vic20_ps2_if.vhd +++ b/cores/VIC20/source/vic20_ps2_if.vhd @@ -1,4 +1,4 @@ --- +-- Mod by Quest 2016 -- A simulation model of VIC20 hardware -- Copyright (c) MikeJ - March 2003 -- @@ -70,7 +70,8 @@ entity VIC20_PS2_IF is I_P2_H : in std_logic; -- high for phase 2 clock ____----__ RESET_L : in std_logic; ENA_4 : in std_logic; -- 4x system clock (4HZ) _-_-_-_-_- - CLK : in std_logic + CLK : in std_logic; + scanSW : out std_logic_vector(6 downto 0) ); end; @@ -116,6 +117,12 @@ architecture RTL of VIC20_PS2_IF is signal reset_cnt : std_logic_vector(4 downto 0); signal tag : std_logic_vector(7 downto 0); + + signal VIDEO: std_logic := '0'; +-- signal SCANL: std_logic := '0'; + signal CTRL : std_logic; + signal ALT : std_logic; + signal EXP8K : std_logic; -- non-xilinx ram --type slv_array8 is array (natural range <>) of std_logic_vector(7 downto 0); --shared variable ram : slv_array8(7 downto 0) := (others => (others => '0')); @@ -231,7 +238,8 @@ begin when x"05" => rowcol <= x"74";-- f1 f1 when x"04" => rowcol <= x"75";-- f3 f3 when x"03" => rowcol <= x"76";-- f5 f5 - when x"83" => rowcol <= x"77";-- f7 f7 + when x"83" => rowcol <= x"77";-- f7 f7 + when others => rowcol <= x"FF"; end case; else @@ -244,6 +252,7 @@ begin when x"72" => rowcol <= x"73";-- down down_cursor when x"6B" => rowcol <= x"72";-- cbm right left_cursor when x"75" => rowcol <= x"73";-- cbm down up_cursor + when others => rowcol <= x"FF"; end case; end if; @@ -276,7 +285,51 @@ begin if (kbd_scancode = x"75") then -- up_cursor up_cursor <= kbd_press; - end if; + end if; + else --q E0 + + if (kbd_scancode = x"01") then -- F9, rom/game cart1 active + scanSW(4 downto 1) <= kbd_press & "001"; --enable cart1, disable others reset + end if; + + if (kbd_scancode = x"09") then -- F10, rom/game cart2 active + scanSW(4 downto 1) <= kbd_press & "010"; --enable cart2, disable others reset + end if; + + if (kbd_scancode = x"78") then -- F11, rom/game cart3 active + scanSW(4 downto 1) <= kbd_press & "100"; --enable cart3, disable others and reset + end if; + + if (kbd_scancode = x"07") then -- F12 cold reset + scanSW(5 downto 1) <= '0' & kbd_press & "000"; --disable carts and reset to basic (EXPANDED 16k) + end if; + + if (kbd_scancode = x"77") then -- bloq num cold reset + scanSW(5 downto 1) <= '1' & kbd_press & "000"; --disable carts and reset to unexpanded VIC20 + end if; + + if (kbd_scancode = x"7E") then -- Sroll Lock VGA/RGB + if (VIDEO = '0' and kbd_press = '0') then + scanSW(0) <= '1'; + VIDEO <= '1'; + elsif (VIDEO = '1' and kbd_press = '0') then + scanSW(0) <= '0'; + VIDEO <= '0'; + end if; + end if; + + if (kbd_scancode = x"11") then --ALT + ALT <= kbd_press; + end if; + + if (kbd_scancode = x"14") then --CTRL + CTRL <= kbd_press; + end if; + + if (kbd_scancode = x"66" and ALT = '1' and CTRL = '1') then --Master reset + scanSW(6) <= kbd_press; + end if; + end if; end if; end if; @@ -448,4 +501,3 @@ begin end process; end architecture RTL; - diff --git a/cores/VIC20/source/vic20_vic.vhd b/cores/VIC20/source/vic20_vic.vhd index bc2598e..ba75d1d 100644 --- a/cores/VIC20/source/vic20_vic.vhd +++ b/cores/VIC20/source/vic20_vic.vhd @@ -59,15 +59,15 @@ library ieee ; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all; -library UNISIM; - use UNISIM.Vcomponents.all; +--library UNISIM; + --use UNISIM.Vcomponents.all; -- 6561 PAL Video Interface Chip model entity VIC20_VIC is generic ( K_OFFSET : in std_logic_vector(4 downto 0) := "10000" - ); + ); port ( I_RW_L : in std_logic; @@ -87,7 +87,6 @@ entity VIC20_VIC is O_HSYNC : out std_logic; O_VSYNC : out std_logic; O_COMP_SYNC_L : out std_logic; - O_BLANK : out std_logic; -- -- I_LIGHT_PEN : in std_logic; @@ -103,16 +102,15 @@ end; architecture RTL of VIC20_VIC is - constant HSYNC_END : std_logic_vector(8 downto 0) := "000100000"; -- 33 - constant LINE_BEGIN : std_logic_vector(8 downto 0) := "000101011"; -- 44 - constant LINE_END : std_logic_vector(8 downto 0) := "100001000"; -- 265 - constant HORIZ_LEN : std_logic_vector(8 downto 0) := "100001111"; -- 271 + -- clocks per line must be divisable by 4 + constant CLOCKS_PER_LINE_M1 : std_logic_vector(8 downto 0) := "100011011"; -- 284 -1 + constant TOTAL_LINES_M1 : std_logic_vector(8 downto 0) := "100110111"; -- 312 -1 + constant H_START_M1 : std_logic_vector(8 downto 0) := "000101011"; -- 44 -1 +-- constant H_START_M1 : std_logic_vector(8 downto 0) := "000101001"; -- 42 -1 + constant H_END_M1 : std_logic_vector(8 downto 0) := "100001111"; -- 272 -1 + constant V_START : std_logic_vector(8 downto 0) := "000011100"; -- 28 + -- video size 228 pixels by 284 lines - constant VSYNC_END : std_logic_vector(8 downto 0) := "000000001"; -- 2 - constant FRAME_BEGIN : std_logic_vector(8 downto 0) := "000001111"; -- 16 - constant FRAME_END : std_logic_vector(8 downto 0) := "100000011"; -- 260 - constant VERT_LEN : std_logic_vector(8 downto 0) := "100000101"; -- 262 - -- close to original RGB constant col0 : std_logic_vector(11 downto 0) := x"000"; -- 0 - 0000 Black constant col1 : std_logic_vector(11 downto 0) := x"FFF"; -- 1 - 0001 White @@ -173,13 +171,14 @@ architecture RTL of VIC20_VIC is signal r_backgnd_colour : std_logic_vector(3 downto 0) := "0001"; -- timing - signal hcnt : std_logic_vector(8 downto 0) := "000000000"; -- pixel counter - signal vcnt : std_logic_vector(8 downto 0) := "000000000"; -- line counter + signal hcnt : std_logic_vector(8 downto 0) := "000000000"; + signal vcnt : std_logic_vector(8 downto 0) := "000000000"; - signal hblank : std_logic := '0'; - signal vblank : std_logic := '0'; - signal hsync : std_logic := '0'; - signal vsync : std_logic := '0'; + signal do_hsync : boolean; + signal hblank : std_logic; + signal vblank : std_logic := '1'; + signal hsync : std_logic; + signal vsync : std_logic; signal start_h : boolean; signal h_char_cnt : std_logic_vector(9 downto 0); @@ -251,7 +250,6 @@ begin p2_h_int <= not hcnt(1); end process; - O_ENA_1MHZ <= ena_1mhz_int; O_P2_H <= p2_h_int; -- vic access when P2_H = '0' @@ -357,47 +355,72 @@ begin -- -- video timing -- - p_sync_timing : process + -- 312 lines per frame + -- + -- hsync blank picture blank + -- 20 24 228 12 total 284 clock + p_hvcnt : process + variable hcarry,vcarry : boolean; begin wait until rising_edge(CLK); if (ENA_4 = '1') then - if (hcnt = HORIZ_LEN) then + if (hcnt = CLOCKS_PER_LINE_M1) then hcnt <= "000000000"; - vcnt <= vcnt + "1"; - hsync <= '1'; else - hcnt <= hcnt + "1"; + hcnt <= hcnt +"1"; end if; - if (vcnt = VERT_LEN) then - vcnt <= "000000000"; - vsync <= '1'; + if do_hsync then + if (vcnt = TOTAL_LINES_M1) then + vcnt <= "000000000"; + else + vcnt <= vcnt +"1"; + end if; end if; - if (hcnt = HSYNC_END) then - hsync <= '0'; - end if; - if (vcnt = VSYNC_END) then - vsync <= '0'; - end if; - if (hcnt = LINE_BEGIN) then - hblank <= '0'; - end if; - if (vcnt = FRAME_BEGIN) then - vblank <= '0'; - end if; - if (hcnt = LINE_END) then - hblank <= '1'; - end if; - if (vcnt = FRAME_END) then - vblank <= '1'; - end if; end if; end process; - p_sync_op : process(hsync, vsync) + p_sync_comb : process(hcnt, vcnt) + begin + vsync <= '0'; + if (vcnt(8 downto 2) = "0000000") then + vsync <= '1'; + end if; + + do_hsync <= (hcnt = CLOCKS_PER_LINE_M1); + end process; + + p_sync : process + begin + wait until rising_edge(CLK); + if (ENA_4 = '1') then + if (hcnt = H_END_M1) then + hblank <= '1'; + elsif (hcnt = H_START_M1) then + hblank <= '0'; + end if; + + if do_hsync then + hsync <= '1'; + elsif (hcnt = "0000010011") then -- 20 -1 + hsync <= '0'; + end if; + + if do_hsync then + if (vcnt = TOTAL_LINES_M1) then + vblank <= '1'; + elsif (vcnt = V_START) then + vblank <= '0'; + end if; + end if; + end if; + end process; + + p_comp_sync : process(hsync, vsync) begin O_HSYNC <= hsync; O_VSYNC <= vsync; + O_COMP_SYNC_L <= (not vsync) and (not hsync); end process; -- @@ -483,7 +506,7 @@ begin elsif (h_char_cnt(9) = '1') then -- active --if h_end then --or (hblank = '1') then -- hblank removed to ensure we still get a picture with daft offset values - if h_end then + if h_end or do_hsync then h_char_cnt <= (others => '0'); h_char_last <= '1'; else @@ -640,19 +663,14 @@ begin wait until rising_edge(CLK); if (ENA_4 = '1') then if (hblank = '1') or (vblank = '1') then - O_BLANK <= '1'; + -- blanking O_VIDEO_R <= "000"; O_VIDEO_G <= "000"; O_VIDEO_B <= "000"; else - O_BLANK <= '0'; --- O_VIDEO_R <= col_rgb(11 downto 8); --- O_VIDEO_G <= col_rgb( 7 downto 4); --- O_VIDEO_B <= col_rgb( 3 downto 0); O_VIDEO_R <= col_rgb(11 downto 9); O_VIDEO_G <= col_rgb( 7 downto 5); O_VIDEO_B <= col_rgb( 3 downto 1); - end if; end if; end process; diff --git a/cores/VIC20/source/vic20_zxuno_Ap.ucf b/cores/VIC20/source/vic20_zxuno_Ap.ucf index 41a92b5..75e4a4d 100644 --- a/cores/VIC20/source/vic20_zxuno_Ap.ucf +++ b/cores/VIC20/source/vic20_zxuno_Ap.ucf @@ -1,6 +1,6 @@ # Clocks & debug -NET I_CLK_REF LOC="P55" | IOSTANDARD = LVCMOS33 | PERIOD=20.0ns; -#NET "testled" LOC="P2" | IOSTANDARD = LVCMOS33; +NET I_CLK_REF LOC="P55" | IOSTANDARD = LVCMOS33; +NET LED LOC="P2" | IOSTANDARD = LVCMOS33; # Video output NET O_VIDEO_R(2) LOC="P97" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; @@ -20,7 +20,7 @@ NET O_PAL LOC="P50" | IOSTANDARD = LVCMOS33; # Sound input/output NET O_AUDIO_L LOC="P98" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8; NET O_AUDIO_R LOC="P99" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8; -#NET "ear" LOC="P1" | IOSTANDARD = LVCMOS33; +NET EAR LOC="P1" | IOSTANDARD = LVCMOS33; # Keyboard and mouse NET I_PS2_CLK LOC="P143" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW; @@ -77,16 +77,15 @@ NET I_PS2_DATA LOC="P142" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SL #NET "sd_miso" LOC="P81" | IOSTANDARD = LVCMOS33; # JOYSTICK -#NET "joyup" LOC="P74" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joydown" LOC="P67" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyleft" LOC="P59" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyright" LOC="P58" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyfire" LOC="P75" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(0) LOC="P74" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(1) LOC="P67" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(2) LOC="P59" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(3) LOC="P58" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(4) LOC="P75" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire2" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire3" LOC="P39" | IOSTANDARD = LVCMOS33 | PULLUP; # Otros -NET I_RESET LOC="P44" | IOSTANDARD = LVCMOS33; NET I_CLK_REF TNM_NET = clk_ref_grp; TIMESPEC TS01 = PERIOD : clk_ref_grp : 20.00 : PRIORITY 1; # 50.00 MHz diff --git a/cores/VIC20/source/vic20_zxuno_v2_v3.ucf b/cores/VIC20/source/vic20_zxuno_v2_v3.ucf index 21ff0a2..7187e2f 100644 --- a/cores/VIC20/source/vic20_zxuno_v2_v3.ucf +++ b/cores/VIC20/source/vic20_zxuno_v2_v3.ucf @@ -1,6 +1,6 @@ # Clocks & debug -NET I_CLK_REF LOC="P55" | IOSTANDARD = LVCMOS33 | PERIOD=20.0ns; -#NET "testled" LOC="P10" | IOSTANDARD = LVCMOS33; +NET I_CLK_REF LOC="P55" | IOSTANDARD = LVCMOS33; +NET LED LOC="P10" | IOSTANDARD = LVCMOS33; # Video output NET O_VIDEO_R(2) LOC="P93" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; @@ -20,7 +20,7 @@ NET O_PAL LOC="P66" | IOSTANDARD = LVCMOS33; # Sound input/output NET O_AUDIO_L LOC="P8" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8; NET O_AUDIO_R LOC="P9" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8; -#NET "ear" LOC="P105" | IOSTANDARD = LVCMOS33; +NET EAR LOC="P105" | IOSTANDARD = LVCMOS33; # Keyboard and mouse NET I_PS2_CLK LOC="P98" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; @@ -77,16 +77,15 @@ NET I_PS2_DATA LOC="P97" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SL #NET "sd_miso" LOC="P78" | IOSTANDARD = LVCMOS33; # JOYSTICK -#NET "joyup" LOC="P142" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joydown" LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyleft" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyright" LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyfire" LOC="P143" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(0) LOC="P142" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(1) LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(2) LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(3) LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(4) LOC="P143" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire2" LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire3" LOC="P7" | IOSTANDARD = LVCMOS33 | PULLUP; # Otros -NET I_RESET LOC="P51" | IOSTANDARD = LVCMOS33; NET I_CLK_REF TNM_NET = clk_ref_grp; TIMESPEC TS01 = PERIOD : clk_ref_grp : 20.00 : PRIORITY 1; # 50.00 MHz diff --git a/cores/VIC20/source/vic20_zxuno_v4.ucf b/cores/VIC20/source/vic20_zxuno_v4.ucf index cd34f8c..bab70a4 100644 --- a/cores/VIC20/source/vic20_zxuno_v4.ucf +++ b/cores/VIC20/source/vic20_zxuno_v4.ucf @@ -1,6 +1,6 @@ # Clocks & debug -NET I_CLK_REF LOC="P55" | IOSTANDARD = LVCMOS33 | PERIOD=20.0ns; -#NET "testled" LOC="P10" | IOSTANDARD = LVCMOS33; +NET I_CLK_REF LOC="P55" | IOSTANDARD = LVCMOS33; +NET LED LOC="P11" | IOSTANDARD = LVCMOS33; # Video output NET O_VIDEO_R(2) LOC="P81" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; @@ -20,7 +20,7 @@ NET O_PAL LOC="P67" | IOSTANDARD = LVCMOS33; # Sound input/output NET O_AUDIO_L LOC="P10" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8; NET O_AUDIO_R LOC="P9" | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 8; -#NET "ear" LOC="P94" | IOSTANDARD = LVCMOS33; +NET EAR LOC="P94" | IOSTANDARD = LVCMOS33; # Keyboard and mouse NET I_PS2_CLK LOC="P99" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ; @@ -77,16 +77,15 @@ NET I_PS2_DATA LOC="P98" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SL #NET "sd_miso" LOC="P78" | IOSTANDARD = LVCMOS33; # JOYSTICK -#NET "joyup" LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joydown" LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyleft" LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyright" LOC="P7" | IOSTANDARD = LVCMOS33 | PULLUP; -#NET "joyfire" LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(0) LOC="P1" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(1) LOC="P5" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(2) LOC="P6" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(3) LOC="P7" | IOSTANDARD = LVCMOS33 | PULLUP; +NET I_SW(4) LOC="P2" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire2" LOC="P8" | IOSTANDARD = LVCMOS33 | PULLUP; #NET "joyfire3" LOC="P39" | IOSTANDARD = LVCMOS33 | PULLUP; # Otros -NET I_RESET LOC="P51" | IOSTANDARD = LVCMOS33; NET I_CLK_REF TNM_NET = clk_ref_grp; TIMESPEC TS01 = PERIOD : clk_ref_grp : 20.00 : PRIORITY 1; # 50.00 MHz diff --git a/cores/curso/cap1/colenc.vhd b/cores/curso/cap1/colenc.vhd index 95cb570..4e483af 100644 --- a/cores/curso/cap1/colenc.vhd +++ b/cores/curso/cap1/colenc.vhd @@ -14,15 +14,15 @@ begin process (clk_in) begin if rising_edge( clk_in ) then - r_out<= "000" when col_in(1)='0' else - "101" when col_in(3)='0' else - "111"; - g_out<= "000" when col_in(2)='0' else - "101" when col_in(3)='0' else - "111"; - b_out<= "000" when col_in(0)='0' else - "101" when col_in(3)='0' else - "111"; + if( col_in(3)='0' ) then + g_out<= col_in(2) & '0' & col_in(2); + r_out<= col_in(1) & '0' & col_in(1); + b_out<= col_in(0) & '0' & col_in(0); + else + g_out<= col_in(2) & col_in(2) & col_in(2); + r_out<= col_in(1) & col_in(1) & col_in(1); + b_out<= col_in(0) & col_in(0) & col_in(0); + end if; end if; end process; end behavioral; diff --git a/cores/curso/cap1/main.vhd b/cores/curso/cap1/main.vhd index 8b82628..07fb1eb 100644 --- a/cores/curso/cap1/main.vhd +++ b/cores/curso/cap1/main.vhd @@ -32,6 +32,7 @@ begin process (clk7) begin + sync <= '0'; color <= "0000"; if rising_edge( clk7 ) then if hcount=447 then @@ -44,10 +45,8 @@ begin else hcount <= hcount + 1; end if; - if ( vcount>=248 and vcount<252 ) or - ( hcount>=344-8 and hcount<376-8) then - sync <= '0'; - else + if ( vcount<248 or vcount>=252 ) and + ( hcount<344-8 or hcount>=376-8) then sync <= '1'; if hcount<256 and vcount<192 then color <= std_logic_vector(hcount(7 downto 4)); diff --git a/firmware/generaflash.bat b/firmware/generaflash.bat new file mode 100644 index 0000000..152f503 --- /dev/null +++ b/firmware/generaflash.bat @@ -0,0 +1,4 @@ +rem call generaflash_multi 1 Ap ZXA +rem call generaflash_multi 2 v2 ZZ2 +rem call generaflash_multi 3 v3 ZZ3 +call generaflash_multi 4 v4 ZX1 diff --git a/firmware/generamcs_multi.bat b/firmware/generaflash_multi.bat similarity index 53% rename from firmware/generamcs_multi.bat rename to firmware/generaflash_multi.bat index 5db89d3..e627170 100644 --- a/firmware/generamcs_multi.bat +++ b/firmware/generaflash_multi.bat @@ -6,48 +6,48 @@ fpad 400000 00 FLASH.ZX1 fpoke FLASH.ZX1 00000 file:header.bin ^ 04000 file:rom_binaries\esxdos.rom ^ 07000 40xFF ^ - 07044 g0203020202 ^ + 07044 g020302020202 ^ 08000 file:firmware.rom ^ 58000 file:tmp.bin fcut tmp.bin 0 53f00 "%output%sd_binaries\SPECTRUM.%3" GenRom sm12a Machine tmp.bin "%output%core_taps\SPECTRUM.TAP" rem CgLeches "%output%core_taps\SPECTRUM.TAP" "%output%core_wavs\SPECTRUM.WAV" 3 -call :CreateMachine set1 CORE2 "Sam Coupe" SamCoupe\tld_sam.%2.bit 0 %3 -call :CreateMachine set1 CORE3 "Jupiter ACE" JupiterAce\jupiter_ace.%2.bit JupiterAce\jupiter_ace.v2_v3.bit %3 -call :CreateMachine set1 CORE4 "Master System" MasterSystem\sms.%2.bit 0 %3 -call :CreateMachine set1 CORE5 "BBC Micro" BBCMicro\working\bbc_micro.%2.bit BBCMicro\working\bbc_micro.v2_v3.bit %3 -call :CreateMachine set1 CORE6 "Acorn Electron" AcornElectron\working\ElectronFpga.%2.bit AcornElectron\working\ElectronFpga.v2_v3.bit %3 -call :CreateMachine set1 CORE7 "Oric Atmos" Oric\build\oric.%2.bit Oric\build\oric.v2_v3.bit %3 -call :CreateMachine set1 CORE8 "Apple 2 (VGA)" curso\cap1\main.bit 0 %3 -call :CreateMachine set1 CORE9 "NES (VGA)" NES\xilinx\NES_ZXUNO.%2.bit 0 %3 +call :CreateMachine set1 CORE2 "Sam Coupe" ..\zxuno\stable\binaries\SamCoupe\COREX.ZX1 %3 +call :CreateMachine set1 CORE3 "Jupiter ACE" ..\zxuno\stable\binaries\JupiterAce\COREX.ZX1 %3 +call :CreateMachine set1 CORE4 "Master System" ..\zxuno\stable\binaries\SMS\COREX.ZX1 %3 +call :CreateMachine set1 CORE5 "BBC Micro" ..\zxuno\stable\binaries\BBCMicro\COREX.ZX1 %3 +call :CreateMachine set1 CORE6 "Atari 800 XL" ..\zxuno\stable\binaries\Atari800XL\COREX.ZX1 %3 +call :CreateMachine set1 CORE7 "VIC-20" ..\zxuno\stable\binaries\VIC20\COREX.ZX1 %3 +call :CreateMachine set1 CORE8 "Apple 2 (VGA)" ..\zxuno\stable\binaries\AppleII\COREX.ZX1 %3 +call :CreateMachine set1 CORE9 "NES (VGA)" ..\zxuno\stable\binaries\NES\COREX.ZX1 %3 copy /y rom_binaries\esxdos.rom "%output%sd_binaries\ESXDOS.%3" copy /y firmware.rom "%output%sd_binaries\FIRMWARE.%3" GenRom sm12 BIOS firmware.rom "%output%core_taps\FIRMWARE.TAP" rem CgLeches "%output%core_taps\FIRMWARE.TAP" "%output%core_wavs\FIRMWARE.WAV" 3 GenRom 0 ESXDOS rom_binaries\esxdos.rom "%output%core_taps\ESXDOS.TAP" -call :CreateRom 0 "ZX Spectrum 48K" 48 dnlh17 -call :CreateRom 1 "ZX +2A 4.1" plus3en41 t -call :CreateRom 5 "SE Basic IV 4.0 Anya" se dh1 -call :CreateRom 7 "ZX Spectrum 48K Cargando Leches" leches dlh -AddItem ROM 8 rom_taps\rooted.tap -call :CreateRom 9 "Inves Spectrum+" inves lh17 -call :CreateRom 10 "Zx Spectrum +2" plus2en th1 -call :CreateRom 12 "Pentagon 128" pentagon pch1 -call :CreateRom 14 "Jet Pac (1983)" JetPac lh17 -call :CreateRom 15 "Pssst (1983)" Pssst lh17 -call :CreateRom 16 "Cookie (1983)" Cookie lh17 -call :CreateRom 17 "Tranz Am (1983)" TranzAm lh17 -call :CreateRom 18 "Master Chess (1983)" MasterChess lh17 -call :CreateRom 19 "Backgammon (1983)" Backgammon lh17 -call :CreateRom 20 "Hungry Horace (1983)" HungryHorace lh17 -call :CreateRom 21 "Horace & the Spiders (1983)" HoraceSpiders lh17 -call :CreateRom 22 "Planetoids (1983)" Planetoids lh17 -call :CreateRom 23 "Space Raiders (1983)" SpaceRaiders lh17 -call :CreateRom 24 "Deathchase (1983)" Deathchase lh17 -call :CreateRom 25 "Manic Miner (1983)" ManicMiner lh17 -call :CreateRom 26 "Misco Jones (2013)" MiscoJones lh17 -call :CreateRom 27 "Jet Set Willy (1984)" JetSetWilly lh17 -call :CreateRom 28 "Lala Prologue (2010)" LalaPrologue lh17 +call :CreateRom 0 "ZX Spectrum 48K" 48 xdnlh17 +call :CreateRom 1 "ZX +2A 4.1" plus3en41 xt +call :CreateRom 5 "SE Basic IV 4.0 Anya" se xdh1 +call :CreateRom 7 "ZX Spectrum 48K Cargando Leches" leches xdlh +AddItem ROM 8 "%output%..\rom_taps\rooted.tap" +call :CreateRom 9 "Inves Spectrum+" inves xlh17 +call :CreateRom 10 "ZX Spectrum +2" plus2en xth1 +call :CreateRom 12 "Pentagon 128" pentagon xpch1 +call :CreateRom 14 "Jet Pac (1983)" JetPac xlh17 +call :CreateRom 15 "Pssst (1983)" Pssst xlh17 +call :CreateRom 16 "Cookie (1983)" Cookie xlh17 +call :CreateRom 17 "Tranz Am (1983)" TranzAm xlh17 +call :CreateRom 18 "Master Chess (1983)" MasterChess xlh17 +call :CreateRom 19 "Backgammon (1983)" Backgammon xlh17 +call :CreateRom 20 "Hungry Horace (1983)" HungryHorace xlh17 +call :CreateRom 21 "Horace & the Spiders (1983)" HoraceSpiders xlh17 +call :CreateRom 22 "Planetoids (1983)" Planetoids xlh17 +call :CreateRom 23 "Space Raiders (1983)" SpaceRaiders xlh17 +call :CreateRom 24 "Deathchase (1983)" Deathchase xlh17 +call :CreateRom 25 "Manic Miner (1983)" ManicMiner xlh17 +call :CreateRom 26 "Misco Jones (2013)" MiscoJones xlh17 +call :CreateRom 27 "Jet Set Willy (1984)" JetSetWilly xlh17 +call :CreateRom 28 "Lala Prologue (2010)" LalaPrologue xlh17 fcut FLASH.ZX1 006000 001041 tmp.bin fcut FLASH.ZX1 00c000 04c000 tmp1.bin fcut FLASH.ZX1 34c000 0b4000 tmp2.bin @@ -56,33 +56,17 @@ rem cambiar el 400000 siguiente línea por 100000 si 25Q80 fcut FLASH.ZX1 0 400000 tmp.bin del tmp1.bin tmp2.bin copy /y tmp.bin "%output%sd_binaries\set1\FLASH.%3" -call :CreateMachine set2 CORE2 "Sam Coupe" SamCoupe\tld_sam.%2.bit 0 %3 -call :CreateMachine set2 CORE3 "Jupiter ACE" JupiterAce\jupiter_ace.%2.bit JupiterAce\jupiter_ace.v2_v3.bit %3 -call :CreateMachine set2 CORE4 "Master System" MasterSystem\sms.%2.bit 0 %3 -call :CreateMachine set2 CORE5 "NES (VGA)" NES\xilinx\NES_ZXUNO.%2.bit 0 %3 -call :CreateMachine set2 CORE6 "Atari 2600 (VGA)" Atari2600\zxuno\zxuno_a2601.%2.bit 0 %3 -call :CreateMachine set2 CORE7 "Acorn Atom (VGA)" AcornAtom\working\Atomic_top_zxuno.%2.bit 0 %3 -call :CreateMachine set2 CORE8 "Apple 2 (VGA)" Apple2\build\apple2_top.%2.bit 0 %3 -call :CreateMachine set2 CORE9 "VIC-20 (VGA)" VIC20\ise\VIC20.%2.bit VIC20\ise\VIC20.v2_v3.bit %3 -fpoke FLASH.ZX1 07044 g020302020200000002 -rem cambiar el 400000 siguiente línea por 100000 si 25Q80 -fcut FLASH.ZX1 0 400000 tmp.bin -copy /y tmp.bin "%output%sd_binaries\set2\FLASH.%3" goto :eof :CreateMachine -IF EXIST ..\cores\%4 ( - Bit2Bin ..\cores\%4 "%output%sd_binaries\%1\%2.%6" -) ELSE ( - Bit2Bin ..\cores\%5 "%output%sd_binaries\%1\%2.%6" -) -GenRom 0 %3 "%output%sd_binaries\%1\%2.%6" "%output%core_taps\%1\%2.TAP" +copy /y ..\%4 "%output%sd_binaries\%1\%2.%5" +GenRom 0 %3 "%output%sd_binaries\%1\%2.%5" "%output%core_taps\%1\%2.tap" AddItem %2 "%output%core_taps\%1\%2.tap" rem CgLeches "%output%core_taps\%2.TAP" "%output%core_wavs\%2.WAV" 3 goto :eof :CreateRom -GenRom %4 %2 rom_binaries\%3.rom rom_taps\%3.tap -AddItem ROM %1 rom_taps\%3.tap -rem CgLeches rom_taps\%3.TAP rom_wavs\%3.WAV 3 +GenRom %4 %2 rom_binaries\%3.rom "%output%..\rom_taps\%3.tap" +AddItem ROM %1 "%output%..\rom_taps\%3.tap" +rem CgLeches "%output%..\rom_taps\%3.TAP" rom_wavs\%3.WAV 3 :eof diff --git a/firmware/generamcs.bat b/firmware/generamcs.bat deleted file mode 100644 index 6a4e1eb..0000000 --- a/firmware/generamcs.bat +++ /dev/null @@ -1,4 +0,0 @@ -rem call generamcs_multi 1 Ap ZXA -rem call generamcs_multi 2 v2 ZZ2 -rem call generamcs_multi 3 v3 ZZ3 -call generamcs_multi 4 v4 ZX1