diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/DigDug_MiST.qsf b/Arcade_MiST/Galaga Hardware/DigDug_MiST/DigDug_MiST.qsf index 093a04b1..b3735a8e 100644 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/DigDug_MiST.qsf +++ b/Arcade_MiST/Galaga Hardware/DigDug_MiST/DigDug_MiST.qsf @@ -45,36 +45,6 @@ set_global_assignment -name PROJECT_CREATION_TIME_DATE "01:53:30 APRIL 20, 2017 set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" -set_global_assignment -name SYSTEMVERILOG_FILE rtl/DigDug.sv -set_global_assignment -name VERILOG_FILE rtl/FPGA_DIGDUG.v -set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CORES.v -set_global_assignment -name VERILOG_FILE rtl/cpucore.v -set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CUSIO.v -set_global_assignment -name VERILOG_FILE rtl/DIGDUG_IODEV.v -set_global_assignment -name VERILOG_FILE rtl/DIGDUG_SPRITE.v -set_global_assignment -name VERILOG_FILE rtl/DIGDUG_VIDEO.v -set_global_assignment -name VERILOG_FILE rtl/hvgen.v -set_global_assignment -name VERILOG_FILE rtl/dprams.v -set_global_assignment -name VERILOG_FILE rtl/wsg.v -set_global_assignment -name VERILOG_FILE rtl/LINEBUF.v -set_global_assignment -name VERILOG_FILE rtl/pll.v -set_global_assignment -name VERILOG_FILE rtl/TV80/tv80s.v -set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_reg.v -set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_mcode.v -set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_core.v -set_global_assignment -name VERILOG_FILE rtl/TV80/tv80_alu.v -set_global_assignment -name VHDL_FILE rtl/roms/wave_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/spclut_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/spchip_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/palette_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/fgchip_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/cpu2_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/cpu1_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/bgscrn_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/bgclut_rom.vhd -set_global_assignment -name VHDL_FILE rtl/roms/bgchip_rom.vhd -set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip -set_global_assignment -name SYSTEMVERILOG_FILE ../../../common/mist/sdram.sv # Pin & Location Assignments # ========================== @@ -228,4 +198,30 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - # end ENTITY(DigDug) # ------------------ +set_global_assignment -name SYSTEMVERILOG_FILE rtl/DigDug.sv +set_global_assignment -name VERILOG_FILE rtl/FPGA_DIGDUG.v +set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CORES.v +set_global_assignment -name VERILOG_FILE rtl/cpucore.v +set_global_assignment -name VERILOG_FILE rtl/DIGDUG_CUSIO.v +set_global_assignment -name VERILOG_FILE rtl/DIGDUG_IODEV.v +set_global_assignment -name VERILOG_FILE rtl/DIGDUG_SPRITE.v +set_global_assignment -name VERILOG_FILE rtl/DIGDUG_VIDEO.v +set_global_assignment -name VHDL_FILE rtl/roms/wave_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/spclut_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/spchip_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/palette_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/fgchip_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/cpu2_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/cpu1_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/bgscrn_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/bgclut_rom.vhd +set_global_assignment -name VHDL_FILE rtl/roms/bgchip_rom.vhd +set_global_assignment -name VERILOG_FILE rtl/hvgen.v +set_global_assignment -name VERILOG_FILE rtl/dprams.v +set_global_assignment -name VERILOG_FILE rtl/wsg.v +set_global_assignment -name VERILOG_FILE rtl/LINEBUF.v +set_global_assignment -name VERILOG_FILE rtl/pll.v +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip +set_global_assignment -name QIP_FILE ../../../common/CPU/tv80/TV80.qip set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_alu.v b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_alu.v deleted file mode 100644 index 2f015e21..00000000 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_alu.v +++ /dev/null @@ -1,442 +0,0 @@ -// -// TV80 8-Bit Microprocessor Core -// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) -// -// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -module tv80_alu (/*AUTOARG*/ - // Outputs - Q, F_Out, - // Inputs - Arith16, Z16, ALU_Op, IR, ISet, BusA, BusB, F_In - ); - - parameter Mode = 0; - parameter Flag_C = 0; - parameter Flag_N = 1; - parameter Flag_P = 2; - parameter Flag_X = 3; - parameter Flag_H = 4; - parameter Flag_Y = 5; - parameter Flag_Z = 6; - parameter Flag_S = 7; - - input Arith16; - input Z16; - input [3:0] ALU_Op ; - input [5:0] IR; - input [1:0] ISet; - input [7:0] BusA; - input [7:0] BusB; - input [7:0] F_In; - output [7:0] Q; - output [7:0] F_Out; - reg [7:0] Q; - reg [7:0] F_Out; - - function [4:0] AddSub4; - input [3:0] A; - input [3:0] B; - input Sub; - input Carry_In; - begin - AddSub4 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In; - end - endfunction // AddSub4 - - function [3:0] AddSub3; - input [2:0] A; - input [2:0] B; - input Sub; - input Carry_In; - begin - AddSub3 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In; - end - endfunction // AddSub4 - - function [1:0] AddSub1; - input A; - input B; - input Sub; - input Carry_In; - begin - AddSub1 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + Carry_In; - end - endfunction // AddSub4 - - // AddSub variables (temporary signals) - reg UseCarry; - reg Carry7_v; - reg OverFlow_v; - reg HalfCarry_v; - reg Carry_v; - reg [7:0] Q_v; - - reg [7:0] BitMask; - - - always @(/*AUTOSENSE*/ALU_Op or BusA or BusB or F_In or IR) - begin - case (IR[5:3]) - 3'b000 : BitMask = 8'b00000001; - 3'b001 : BitMask = 8'b00000010; - 3'b010 : BitMask = 8'b00000100; - 3'b011 : BitMask = 8'b00001000; - 3'b100 : BitMask = 8'b00010000; - 3'b101 : BitMask = 8'b00100000; - 3'b110 : BitMask = 8'b01000000; - default: BitMask = 8'b10000000; - endcase // case(IR[5:3]) - - UseCarry = ~ ALU_Op[2] && ALU_Op[0]; - { HalfCarry_v, Q_v[3:0] } = AddSub4(BusA[3:0], BusB[3:0], ALU_Op[1], ALU_Op[1] ^ (UseCarry && F_In[Flag_C]) ); - { Carry7_v, Q_v[6:4] } = AddSub3(BusA[6:4], BusB[6:4], ALU_Op[1], HalfCarry_v); - { Carry_v, Q_v[7] } = AddSub1(BusA[7], BusB[7], ALU_Op[1], Carry7_v); - OverFlow_v = Carry_v ^ Carry7_v; - end // always @ * - - reg [7:0] Q_t; - reg [8:0] DAA_Q; - - always @ (/*AUTOSENSE*/ALU_Op or Arith16 or BitMask or BusA or BusB - or Carry_v or F_In or HalfCarry_v or IR or ISet - or OverFlow_v or Q_v or Z16) - begin - Q_t = 8'hxx; - DAA_Q = {9{1'bx}}; - - F_Out = F_In; - case (ALU_Op) - 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 : - begin - F_Out[Flag_N] = 1'b0; - F_Out[Flag_C] = 1'b0; - - case (ALU_Op[2:0]) - - 3'b000, 3'b001 : // ADD, ADC - begin - Q_t = Q_v; - F_Out[Flag_C] = Carry_v; - F_Out[Flag_H] = HalfCarry_v; - F_Out[Flag_P] = OverFlow_v; - end - - 3'b010, 3'b011, 3'b111 : // SUB, SBC, CP - begin - Q_t = Q_v; - F_Out[Flag_N] = 1'b1; - F_Out[Flag_C] = ~ Carry_v; - F_Out[Flag_H] = ~ HalfCarry_v; - F_Out[Flag_P] = OverFlow_v; - end - - 3'b100 : // AND - begin - Q_t[7:0] = BusA & BusB; - F_Out[Flag_H] = 1'b1; - end - - 3'b101 : // XOR - begin - Q_t[7:0] = BusA ^ BusB; - F_Out[Flag_H] = 1'b0; - end - - default : // OR 3'b110 - begin - Q_t[7:0] = BusA | BusB; - F_Out[Flag_H] = 1'b0; - end - - endcase // case(ALU_OP[2:0]) - - if (ALU_Op[2:0] == 3'b111 ) - begin // CP - F_Out[Flag_X] = BusB[3]; - F_Out[Flag_Y] = BusB[5]; - end - else - begin - F_Out[Flag_X] = Q_t[3]; - F_Out[Flag_Y] = Q_t[5]; - end - - if (Q_t[7:0] == 8'b00000000 ) - begin - F_Out[Flag_Z] = 1'b1; - if (Z16 == 1'b1 ) - begin - F_Out[Flag_Z] = F_In[Flag_Z]; // 16 bit ADC,SBC - end - end - else - begin - F_Out[Flag_Z] = 1'b0; - end // else: !if(Q_t[7:0] == 8'b00000000 ) - - F_Out[Flag_S] = Q_t[7]; - case (ALU_Op[2:0]) - 3'b000, 3'b001, 3'b010, 3'b011, 3'b111 : // ADD, ADC, SUB, SBC, CP - ; - - default : - F_Out[Flag_P] = ~(^Q_t); - endcase // case(ALU_Op[2:0]) - - if (Arith16 == 1'b1 ) - begin - F_Out[Flag_S] = F_In[Flag_S]; - F_Out[Flag_Z] = F_In[Flag_Z]; - F_Out[Flag_P] = F_In[Flag_P]; - end - end // case: 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 - - 4'b1100 : - begin - // DAA - F_Out[Flag_H] = F_In[Flag_H]; - F_Out[Flag_C] = F_In[Flag_C]; - DAA_Q[7:0] = BusA; - DAA_Q[8] = 1'b0; - if (F_In[Flag_N] == 1'b0 ) - begin - // After addition - // Alow > 9 || H == 1 - if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 ) - begin - if ((DAA_Q[3:0] > 9) ) - begin - F_Out[Flag_H] = 1'b1; - end - else - begin - F_Out[Flag_H] = 1'b0; - end - DAA_Q = DAA_Q + 6; - end // if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 ) - - // new Ahigh > 9 || C == 1 - if (DAA_Q[8:4] > 9 || F_In[Flag_C] == 1'b1 ) - begin - DAA_Q = DAA_Q + 96; // 0x60 - end - end - else - begin - // After subtraction - if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 ) - begin - if (DAA_Q[3:0] > 5 ) - begin - F_Out[Flag_H] = 1'b0; - end - DAA_Q[7:0] = DAA_Q[7:0] - 6; - end - if (BusA > 153 || F_In[Flag_C] == 1'b1 ) - begin - DAA_Q = DAA_Q - 352; // 0x160 - end - end // else: !if(F_In[Flag_N] == 1'b0 ) - - F_Out[Flag_X] = DAA_Q[3]; - F_Out[Flag_Y] = DAA_Q[5]; - F_Out[Flag_C] = F_In[Flag_C] || DAA_Q[8]; - Q_t = DAA_Q[7:0]; - - if (DAA_Q[7:0] == 8'b00000000 ) - begin - F_Out[Flag_Z] = 1'b1; - end - else - begin - F_Out[Flag_Z] = 1'b0; - end - - F_Out[Flag_S] = DAA_Q[7]; - F_Out[Flag_P] = ~ (^DAA_Q); - end // case: 4'b1100 - - 4'b1101, 4'b1110 : - begin - // RLD, RRD - Q_t[7:4] = BusA[7:4]; - if (ALU_Op[0] == 1'b1 ) - begin - Q_t[3:0] = BusB[7:4]; - end - else - begin - Q_t[3:0] = BusB[3:0]; - end - F_Out[Flag_H] = 1'b0; - F_Out[Flag_N] = 1'b0; - F_Out[Flag_X] = Q_t[3]; - F_Out[Flag_Y] = Q_t[5]; - if (Q_t[7:0] == 8'b00000000 ) - begin - F_Out[Flag_Z] = 1'b1; - end - else - begin - F_Out[Flag_Z] = 1'b0; - end - F_Out[Flag_S] = Q_t[7]; - F_Out[Flag_P] = ~(^Q_t); - end // case: when 4'b1101, 4'b1110 - - 4'b1001 : - begin - // BIT - Q_t[7:0] = BusB & BitMask; - F_Out[Flag_S] = Q_t[7]; - if (Q_t[7:0] == 8'b00000000 ) - begin - F_Out[Flag_Z] = 1'b1; - F_Out[Flag_P] = 1'b1; - end - else - begin - F_Out[Flag_Z] = 1'b0; - F_Out[Flag_P] = 1'b0; - end - F_Out[Flag_H] = 1'b1; - F_Out[Flag_N] = 1'b0; - F_Out[Flag_X] = 1'b0; - F_Out[Flag_Y] = 1'b0; - if (IR[2:0] != 3'b110 ) - begin - F_Out[Flag_X] = BusB[3]; - F_Out[Flag_Y] = BusB[5]; - end - end // case: when 4'b1001 - - 4'b1010 : - // SET - Q_t[7:0] = BusB | BitMask; - - 4'b1011 : - // RES - Q_t[7:0] = BusB & ~ BitMask; - - 4'b1000 : - begin - // ROT - case (IR[5:3]) - 3'b000 : // RLC - begin - Q_t[7:1] = BusA[6:0]; - Q_t[0] = BusA[7]; - F_Out[Flag_C] = BusA[7]; - end - - 3'b010 : // RL - begin - Q_t[7:1] = BusA[6:0]; - Q_t[0] = F_In[Flag_C]; - F_Out[Flag_C] = BusA[7]; - end - - 3'b001 : // RRC - begin - Q_t[6:0] = BusA[7:1]; - Q_t[7] = BusA[0]; - F_Out[Flag_C] = BusA[0]; - end - - 3'b011 : // RR - begin - Q_t[6:0] = BusA[7:1]; - Q_t[7] = F_In[Flag_C]; - F_Out[Flag_C] = BusA[0]; - end - - 3'b100 : // SLA - begin - Q_t[7:1] = BusA[6:0]; - Q_t[0] = 1'b0; - F_Out[Flag_C] = BusA[7]; - end - - 3'b110 : // SLL (Undocumented) / SWAP - begin - if (Mode == 3 ) - begin - Q_t[7:4] = BusA[3:0]; - Q_t[3:0] = BusA[7:4]; - F_Out[Flag_C] = 1'b0; - end - else - begin - Q_t[7:1] = BusA[6:0]; - Q_t[0] = 1'b1; - F_Out[Flag_C] = BusA[7]; - end // else: !if(Mode == 3 ) - end // case: 3'b110 - - 3'b101 : // SRA - begin - Q_t[6:0] = BusA[7:1]; - Q_t[7] = BusA[7]; - F_Out[Flag_C] = BusA[0]; - end - - default : // SRL - begin - Q_t[6:0] = BusA[7:1]; - Q_t[7] = 1'b0; - F_Out[Flag_C] = BusA[0]; - end - endcase // case(IR[5:3]) - - F_Out[Flag_H] = 1'b0; - F_Out[Flag_N] = 1'b0; - F_Out[Flag_X] = Q_t[3]; - F_Out[Flag_Y] = Q_t[5]; - F_Out[Flag_S] = Q_t[7]; - if (Q_t[7:0] == 8'b00000000 ) - begin - F_Out[Flag_Z] = 1'b1; - end - else - begin - F_Out[Flag_Z] = 1'b0; - end - F_Out[Flag_P] = ~(^Q_t); - - if (ISet == 2'b00 ) - begin - F_Out[Flag_P] = F_In[Flag_P]; - F_Out[Flag_S] = F_In[Flag_S]; - F_Out[Flag_Z] = F_In[Flag_Z]; - end - end // case: 4'b1000 - - - default : - ; - - endcase // case(ALU_Op) - - Q = Q_t; - end // always @ (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) - -endmodule // T80_ALU diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_core.v b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_core.v deleted file mode 100644 index b9f7193a..00000000 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_core.v +++ /dev/null @@ -1,1356 +0,0 @@ -// -// TV80 8-Bit Microprocessor Core -// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) -// -// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -//`define TV80_REFRESH - -module tv80_core (/*AUTOARG*/ - // Outputs - m1_n, iorq, no_read, write, rfsh_n, halt_n, busak_n, A, do, mc, ts, - intcycle_n, IntE, stop, - // Inputs - reset_n, clk, cen, wait_n, int_n, nmi_n, busrq_n, dinst, di - ); - // Beginning of automatic inputs (from unused autoinst inputs) - // End of automatics - - parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle - parameter Flag_C = 0; - parameter Flag_N = 1; - parameter Flag_P = 2; - parameter Flag_X = 3; - parameter Flag_H = 4; - parameter Flag_Y = 5; - parameter Flag_Z = 6; - parameter Flag_S = 7; - - input reset_n; - input clk; - input cen; - input wait_n; - input int_n; - input nmi_n; - input busrq_n; - output m1_n; - output iorq; - output no_read; - output write; - output rfsh_n; - output halt_n; - output busak_n; - output [15:0] A; - input [7:0] dinst; - input [7:0] di; - output [7:0] do; - output [6:0] mc; - output [6:0] ts; - output intcycle_n; - output IntE; - output stop; - - reg m1_n; - reg iorq; - reg rfsh_n; - reg halt_n; - reg busak_n; - reg [15:0] A; - reg [7:0] do; - reg [6:0] mc; - reg [6:0] ts; - reg intcycle_n; - reg IntE; - reg stop; - - parameter aNone = 3'b111; - parameter aBC = 3'b000; - parameter aDE = 3'b001; - parameter aXY = 3'b010; - parameter aIOA = 3'b100; - parameter aSP = 3'b101; - parameter aZI = 3'b110; - - // Registers - reg [7:0] ACC, F; - reg [7:0] Ap, Fp; - reg [7:0] I; - reg [7:0] R; - reg [15:0] SP, PC; - reg [7:0] RegDIH; - reg [7:0] RegDIL; - wire [15:0] RegBusA; - wire [15:0] RegBusB; - wire [15:0] RegBusC; - reg [2:0] RegAddrA_r; - reg [2:0] RegAddrA; - reg [2:0] RegAddrB_r; - reg [2:0] RegAddrB; - reg [2:0] RegAddrC; - reg RegWEH; - reg RegWEL; - reg Alternate; - - // Help Registers - reg [15:0] TmpAddr; // Temporary address register - reg [7:0] IR; // Instruction register - reg [1:0] ISet; // Instruction set selector - reg [15:0] RegBusA_r; - - reg [15:0] ID16; - reg [7:0] Save_Mux; - - reg [6:0] tstate; - reg [6:0] mcycle; - reg last_mcycle, last_tstate; - reg IntE_FF1; - reg IntE_FF2; - reg Halt_FF; - reg BusReq_s; - reg BusAck; - reg ClkEn; - reg NMI_s; - reg INT_s; - reg [1:0] IStatus; - - reg [7:0] DI_Reg; - reg T_Res; - reg [1:0] XY_State; - reg [2:0] Pre_XY_F_M; - reg NextIs_XY_Fetch; - reg XY_Ind; - reg No_BTR; - reg BTR_r; - reg Auto_Wait; - reg Auto_Wait_t1; - reg Auto_Wait_t2; - reg IncDecZ; - - // ALU signals - reg [7:0] BusB; - reg [7:0] BusA; - wire [7:0] ALU_Q; - wire [7:0] F_Out; - - // Registered micro code outputs - reg [4:0] Read_To_Reg_r; - reg Arith16_r; - reg Z16_r; - reg [3:0] ALU_Op_r; - reg Save_ALU_r; - reg PreserveC_r; - reg [2:0] mcycles; - - // Micro code outputs - wire [2:0] mcycles_d; - wire [2:0] tstates; - reg IntCycle; - reg NMICycle; - wire Inc_PC; - wire Inc_WZ; - wire [3:0] IncDec_16; - wire [1:0] Prefix; - wire Read_To_Acc; - wire Read_To_Reg; - wire [3:0] Set_BusB_To; - wire [3:0] Set_BusA_To; - wire [3:0] ALU_Op; - wire Save_ALU; - wire PreserveC; - wire Arith16; - wire [2:0] Set_Addr_To; - wire Jump; - wire JumpE; - wire JumpXY; - wire Call; - wire RstP; - wire LDZ; - wire LDW; - wire LDSPHL; - wire iorq_i; - wire [2:0] Special_LD; - wire ExchangeDH; - wire ExchangeRp; - wire ExchangeAF; - wire ExchangeRS; - wire I_DJNZ; - wire I_CPL; - wire I_CCF; - wire I_SCF; - wire I_RETN; - wire I_BT; - wire I_BC; - wire I_BTR; - wire I_RLD; - wire I_RRD; - wire I_INRC; - wire SetDI; - wire SetEI; - wire [1:0] IMode; - wire Halt; - - reg [15:0] PC16; - reg [15:0] PC16_B; - reg [15:0] SP16, SP16_A, SP16_B; - reg [15:0] ID16_B; - reg Oldnmi_n; - - tv80_mcode #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_mcode - ( - .IR (IR), - .ISet (ISet), - .MCycle (mcycle), - .F (F), - .NMICycle (NMICycle), - .IntCycle (IntCycle), - .MCycles (mcycles_d), - .TStates (tstates), - .Prefix (Prefix), - .Inc_PC (Inc_PC), - .Inc_WZ (Inc_WZ), - .IncDec_16 (IncDec_16), - .Read_To_Acc (Read_To_Acc), - .Read_To_Reg (Read_To_Reg), - .Set_BusB_To (Set_BusB_To), - .Set_BusA_To (Set_BusA_To), - .ALU_Op (ALU_Op), - .Save_ALU (Save_ALU), - .PreserveC (PreserveC), - .Arith16 (Arith16), - .Set_Addr_To (Set_Addr_To), - .IORQ (iorq_i), - .Jump (Jump), - .JumpE (JumpE), - .JumpXY (JumpXY), - .Call (Call), - .RstP (RstP), - .LDZ (LDZ), - .LDW (LDW), - .LDSPHL (LDSPHL), - .Special_LD (Special_LD), - .ExchangeDH (ExchangeDH), - .ExchangeRp (ExchangeRp), - .ExchangeAF (ExchangeAF), - .ExchangeRS (ExchangeRS), - .I_DJNZ (I_DJNZ), - .I_CPL (I_CPL), - .I_CCF (I_CCF), - .I_SCF (I_SCF), - .I_RETN (I_RETN), - .I_BT (I_BT), - .I_BC (I_BC), - .I_BTR (I_BTR), - .I_RLD (I_RLD), - .I_RRD (I_RRD), - .I_INRC (I_INRC), - .SetDI (SetDI), - .SetEI (SetEI), - .IMode (IMode), - .Halt (Halt), - .NoRead (no_read), - .Write (write) - ); - - tv80_alu #(Mode, Flag_C, Flag_N, Flag_P, Flag_X, Flag_H, Flag_Y, Flag_Z, Flag_S) i_alu - ( - .Arith16 (Arith16_r), - .Z16 (Z16_r), - .ALU_Op (ALU_Op_r), - .IR (IR[5:0]), - .ISet (ISet), - .BusA (BusA), - .BusB (BusB), - .F_In (F), - .Q (ALU_Q), - .F_Out (F_Out) - ); - - function [6:0] number_to_bitvec; - input [2:0] num; - begin - case (num) - 1 : number_to_bitvec = 7'b0000001; - 2 : number_to_bitvec = 7'b0000010; - 3 : number_to_bitvec = 7'b0000100; - 4 : number_to_bitvec = 7'b0001000; - 5 : number_to_bitvec = 7'b0010000; - 6 : number_to_bitvec = 7'b0100000; - 7 : number_to_bitvec = 7'b1000000; - default : number_to_bitvec = 7'bx; - endcase // case(num) - end - endfunction // number_to_bitvec - - always @(/*AUTOSENSE*/mcycle or mcycles or tstate or tstates) - begin - case (mcycles) - 1 : last_mcycle = mcycle[0]; - 2 : last_mcycle = mcycle[1]; - 3 : last_mcycle = mcycle[2]; - 4 : last_mcycle = mcycle[3]; - 5 : last_mcycle = mcycle[4]; - 6 : last_mcycle = mcycle[5]; - 7 : last_mcycle = mcycle[6]; - default : last_mcycle = 1'bx; - endcase // case(mcycles) - - case (tstates) - 0 : last_tstate = tstate[0]; - 1 : last_tstate = tstate[1]; - 2 : last_tstate = tstate[2]; - 3 : last_tstate = tstate[3]; - 4 : last_tstate = tstate[4]; - 5 : last_tstate = tstate[5]; - 6 : last_tstate = tstate[6]; - default : last_tstate = 1'bx; - endcase - end // always @ (... - - - always @(/*AUTOSENSE*/ALU_Q or BusAck or BusB or DI_Reg - or ExchangeRp or IR or Save_ALU_r or Set_Addr_To or XY_Ind - or XY_State or cen or last_tstate or mcycle) - begin - ClkEn = cen && ~ BusAck; - - if (last_tstate) - T_Res = 1'b1; - else T_Res = 1'b0; - - if (XY_State != 2'b00 && XY_Ind == 1'b0 && - ((Set_Addr_To == aXY) || - (mcycle[0] && IR == 8'b11001011) || - (mcycle[0] && IR == 8'b00110110))) - NextIs_XY_Fetch = 1'b1; - else - NextIs_XY_Fetch = 1'b0; - - if (ExchangeRp) - Save_Mux = BusB; - else if (!Save_ALU_r) - Save_Mux = DI_Reg; - else - Save_Mux = ALU_Q; - end // always @ * - - always @ (posedge clk) - begin - if (reset_n == 1'b0 ) - begin - PC <= #1 0; // Program Counter - A <= #1 0; - TmpAddr <= #1 0; - IR <= #1 8'b00000000; - ISet <= #1 2'b00; - XY_State <= #1 2'b00; - IStatus <= #1 2'b00; - mcycles <= #1 3'b000; - do <= #1 8'b00000000; - - ACC <= #1 8'hFF; - F <= #1 8'hFF; - Ap <= #1 8'hFF; - Fp <= #1 8'hFF; - I <= #1 0; - `ifdef TV80_REFRESH - R <= #1 0; - `endif - SP <= #1 16'hFFFF; - Alternate <= #1 1'b0; - - Read_To_Reg_r <= #1 5'b00000; - Arith16_r <= #1 1'b0; - BTR_r <= #1 1'b0; - Z16_r <= #1 1'b0; - ALU_Op_r <= #1 4'b0000; - Save_ALU_r <= #1 1'b0; - PreserveC_r <= #1 1'b0; - XY_Ind <= #1 1'b0; - end - else - begin - - if (ClkEn == 1'b1 ) - begin - - ALU_Op_r <= #1 4'b0000; - Save_ALU_r <= #1 1'b0; - Read_To_Reg_r <= #1 5'b00000; - - mcycles <= #1 mcycles_d; - - if (IMode != 2'b11 ) - begin - IStatus <= #1 IMode; - end - - Arith16_r <= #1 Arith16; - PreserveC_r <= #1 PreserveC; - if (ISet == 2'b10 && ALU_Op[2] == 1'b0 && ALU_Op[0] == 1'b1 && mcycle[2] ) - begin - Z16_r <= #1 1'b1; - end - else - begin - Z16_r <= #1 1'b0; - end - - if (mcycle[0] && (tstate[1] | tstate[2] | tstate[3] )) - begin - // mcycle == 1 && tstate == 1, 2, || 3 - if (tstate[2] && wait_n == 1'b1 ) - begin - `ifdef TV80_REFRESH - if (Mode < 2 ) - begin - A[7:0] <= #1 R; - A[15:8] <= #1 I; - R[6:0] <= #1 R[6:0] + 1; - end - `endif - if (Jump == 1'b0 && Call == 1'b0 && NMICycle == 1'b0 && IntCycle == 1'b0 && ~ (Halt_FF == 1'b1 || Halt == 1'b1) ) - begin - PC <= #1 PC16; - end - - if (IntCycle == 1'b1 && IStatus == 2'b01 ) - begin - IR <= #1 8'b11111111; - end - else if (Halt_FF == 1'b1 || (IntCycle == 1'b1 && IStatus == 2'b10) || NMICycle == 1'b1 ) - begin - IR <= #1 8'b00000000; - end - else - begin - IR <= #1 dinst; - end - - ISet <= #1 2'b00; - if (Prefix != 2'b00 ) - begin - if (Prefix == 2'b11 ) - begin - if (IR[5] == 1'b1 ) - begin - XY_State <= #1 2'b10; - end - else - begin - XY_State <= #1 2'b01; - end - end - else - begin - if (Prefix == 2'b10 ) - begin - XY_State <= #1 2'b00; - XY_Ind <= #1 1'b0; - end - ISet <= #1 Prefix; - end - end - else - begin - XY_State <= #1 2'b00; - XY_Ind <= #1 1'b0; - end - end // if (tstate == 2 && wait_n == 1'b1 ) - - - end - else - begin - // either (mcycle > 1) OR (mcycle == 1 AND tstate > 3) - - if (mcycle[5] ) - begin - XY_Ind <= #1 1'b1; - if (Prefix == 2'b01 ) - begin - ISet <= #1 2'b01; - end - end - - if (T_Res == 1'b1 ) - begin - BTR_r <= #1 (I_BT || I_BC || I_BTR) && ~ No_BTR; - if (Jump == 1'b1 ) - begin - A[15:8] <= #1 DI_Reg; - A[7:0] <= #1 TmpAddr[7:0]; - PC[15:8] <= #1 DI_Reg; - PC[7:0] <= #1 TmpAddr[7:0]; - end - else if (JumpXY == 1'b1 ) - begin - A <= #1 RegBusC; - PC <= #1 RegBusC; - end else if (Call == 1'b1 || RstP == 1'b1 ) - begin - A <= #1 TmpAddr; - PC <= #1 TmpAddr; - end - else if (last_mcycle && NMICycle == 1'b1 ) - begin - A <= #1 16'b0000000001100110; - PC <= #1 16'b0000000001100110; - end - else if (mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 ) - begin - A[15:8] <= #1 I; - A[7:0] <= #1 TmpAddr[7:0]; - PC[15:8] <= #1 I; - PC[7:0] <= #1 TmpAddr[7:0]; - end - else - begin - case (Set_Addr_To) - aXY : - begin - if (XY_State == 2'b00 ) - begin - A <= #1 RegBusC; - end - else - begin - if (NextIs_XY_Fetch == 1'b1 ) - begin - A <= #1 PC; - end - else - begin - A <= #1 TmpAddr; - end - end // else: !if(XY_State == 2'b00 ) - end // case: aXY - - aIOA : - begin - if (Mode == 3 ) - begin - // Memory map I/O on GBZ80 - A[15:8] <= #1 8'hFF; - end - else if (Mode == 2 ) - begin - // Duplicate I/O address on 8080 - A[15:8] <= #1 DI_Reg; - end - else - begin - A[15:8] <= #1 ACC; - end - A[7:0] <= #1 DI_Reg; - end // case: aIOA - - - aSP : - begin - A <= #1 SP; - end - - aBC : - begin - if (Mode == 3 && iorq_i == 1'b1 ) - begin - // Memory map I/O on GBZ80 - A[15:8] <= #1 8'hFF; - A[7:0] <= #1 RegBusC[7:0]; - end - else - begin - A <= #1 RegBusC; - end - end // case: aBC - - aDE : - begin - A <= #1 RegBusC; - end - - aZI : - begin - if (Inc_WZ == 1'b1 ) - begin - A <= #1 TmpAddr + 1; - end - else - begin - A[15:8] <= #1 DI_Reg; - A[7:0] <= #1 TmpAddr[7:0]; - end - end // case: aZI - - default : - begin - A <= #1 PC; - end - endcase // case(Set_Addr_To) - - end // else: !if(mcycle[2] && IntCycle == 1'b1 && IStatus == 2'b10 ) - - - Save_ALU_r <= #1 Save_ALU; - ALU_Op_r <= #1 ALU_Op; - - if (I_CPL == 1'b1 ) - begin - // CPL - ACC <= #1 ~ ACC; - F[Flag_Y] <= #1 ~ ACC[5]; - F[Flag_H] <= #1 1'b1; - F[Flag_X] <= #1 ~ ACC[3]; - F[Flag_N] <= #1 1'b1; - end - if (I_CCF == 1'b1 ) - begin - // CCF - F[Flag_C] <= #1 ~ F[Flag_C]; - F[Flag_Y] <= #1 ACC[5]; - F[Flag_H] <= #1 F[Flag_C]; - F[Flag_X] <= #1 ACC[3]; - F[Flag_N] <= #1 1'b0; - end - if (I_SCF == 1'b1 ) - begin - // SCF - F[Flag_C] <= #1 1'b1; - F[Flag_Y] <= #1 ACC[5]; - F[Flag_H] <= #1 1'b0; - F[Flag_X] <= #1 ACC[3]; - F[Flag_N] <= #1 1'b0; - end - end // if (T_Res == 1'b1 ) - - - if (tstate[2] && wait_n == 1'b1 ) - begin - if (ISet == 2'b01 && mcycle[6] ) - begin - IR <= #1 dinst; - end - if (JumpE == 1'b1 ) - begin - PC <= #1 PC16; - end - else if (Inc_PC == 1'b1 ) - begin - //PC <= #1 PC + 1; - PC <= #1 PC16; - end - if (BTR_r == 1'b1 ) - begin - //PC <= #1 PC - 2; - PC <= #1 PC16; - end - if (RstP == 1'b1 ) - begin - TmpAddr <= #1 { 10'h0, IR[5:3], 3'h0 }; - //TmpAddr <= #1 (others =>1'b0); - //TmpAddr[5:3] <= #1 IR[5:3]; - end - end - if (tstate[3] && mcycle[5] ) - begin - TmpAddr <= #1 SP16; - end - - if ((tstate[2] && wait_n == 1'b1) || (tstate[4] && mcycle[0]) ) - begin - if (IncDec_16[2:0] == 3'b111 ) - begin - SP <= #1 SP16; - end - end - - if (LDSPHL == 1'b1 ) - begin - SP <= #1 RegBusC; - end - if (ExchangeAF == 1'b1 ) - begin - Ap <= #1 ACC; - ACC <= #1 Ap; - Fp <= #1 F; - F <= #1 Fp; - end - if (ExchangeRS == 1'b1 ) - begin - Alternate <= #1 ~ Alternate; - end - end // else: !if(mcycle == 3'b001 && tstate(2) == 1'b0 ) - - - if (tstate[3] ) - begin - if (LDZ == 1'b1 ) - begin - TmpAddr[7:0] <= #1 DI_Reg; - end - if (LDW == 1'b1 ) - begin - TmpAddr[15:8] <= #1 DI_Reg; - end - - if (Special_LD[2] == 1'b1 ) - begin - case (Special_LD[1:0]) - 2'b00 : - begin - ACC <= #1 I; - F[Flag_P] <= #1 IntE_FF2; - end - - 2'b01 : - begin - ACC <= #1 R; - F[Flag_P] <= #1 IntE_FF2; - end - - 2'b10 : - I <= #1 ACC; - - `ifdef TV80_REFRESH - default : - R <= #1 ACC; - `else - default : ; - `endif - endcase - end - end // if (tstate == 3 ) - - - if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 ) - begin - if (Mode == 3 ) - begin - F[6] <= #1 F_Out[6]; - F[5] <= #1 F_Out[5]; - F[7] <= #1 F_Out[7]; - if (PreserveC_r == 1'b0 ) - begin - F[4] <= #1 F_Out[4]; - end - end - else - begin - F[7:1] <= #1 F_Out[7:1]; - if (PreserveC_r == 1'b0 ) - begin - F[Flag_C] <= #1 F_Out[0]; - end - end - end // if ((I_DJNZ == 1'b0 && Save_ALU_r == 1'b1) || ALU_Op_r == 4'b1001 ) - - if (T_Res == 1'b1 && I_INRC == 1'b1 ) - begin - F[Flag_H] <= #1 1'b0; - F[Flag_N] <= #1 1'b0; - if (DI_Reg[7:0] == 8'b00000000 ) - begin - F[Flag_Z] <= #1 1'b1; - end - else - begin - F[Flag_Z] <= #1 1'b0; - end - F[Flag_S] <= #1 DI_Reg[7]; - F[Flag_P] <= #1 ~ (^DI_Reg[7:0]); - end // if (T_Res == 1'b1 && I_INRC == 1'b1 ) - - - if (tstate[1] && Auto_Wait_t1 == 1'b0 ) - begin - do <= #1 BusB; - if (I_RLD == 1'b1 ) - begin - do[3:0] <= #1 BusA[3:0]; - do[7:4] <= #1 BusB[3:0]; - end - if (I_RRD == 1'b1 ) - begin - do[3:0] <= #1 BusB[7:4]; - do[7:4] <= #1 BusA[3:0]; - end - end - - if (T_Res == 1'b1 ) - begin - Read_To_Reg_r[3:0] <= #1 Set_BusA_To; - Read_To_Reg_r[4] <= #1 Read_To_Reg; - if (Read_To_Acc == 1'b1 ) - begin - Read_To_Reg_r[3:0] <= #1 4'b0111; - Read_To_Reg_r[4] <= #1 1'b1; - end - end - - if (tstate[1] && I_BT == 1'b1 ) - begin - F[Flag_X] <= #1 ALU_Q[3]; - F[Flag_Y] <= #1 ALU_Q[1]; - F[Flag_H] <= #1 1'b0; - F[Flag_N] <= #1 1'b0; - end - if (I_BC == 1'b1 || I_BT == 1'b1 ) - begin - F[Flag_P] <= #1 IncDecZ; - end - - if ((tstate[1] && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) || - (Save_ALU_r == 1'b1 && ALU_Op_r != 4'b0111) ) - begin - case (Read_To_Reg_r) - 5'b10111 : - ACC <= #1 Save_Mux; - 5'b10110 : - do <= #1 Save_Mux; - 5'b11000 : - SP[7:0] <= #1 Save_Mux; - 5'b11001 : - SP[15:8] <= #1 Save_Mux; - 5'b11011 : - F <= #1 Save_Mux; - endcase - end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||... - end // if (ClkEn == 1'b1 ) - end // else: !if(reset_n == 1'b0 ) - end - - - //------------------------------------------------------------------------- - // - // BC('), DE('), HL('), IX && IY - // - //------------------------------------------------------------------------- - always @ (posedge clk) - begin - if (ClkEn == 1'b1 ) - begin - // Bus A / Write - RegAddrA_r <= #1 { Alternate, Set_BusA_To[2:1] }; - if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusA_To[2:1] == 2'b10 ) - begin - RegAddrA_r <= #1 { XY_State[1], 2'b11 }; - end - - // Bus B - RegAddrB_r <= #1 { Alternate, Set_BusB_To[2:1] }; - if (XY_Ind == 1'b0 && XY_State != 2'b00 && Set_BusB_To[2:1] == 2'b10 ) - begin - RegAddrB_r <= #1 { XY_State[1], 2'b11 }; - end - - // Address from register - RegAddrC <= #1 { Alternate, Set_Addr_To[1:0] }; - // Jump (HL), LD SP,HL - if ((JumpXY == 1'b1 || LDSPHL == 1'b1) ) - begin - RegAddrC <= #1 { Alternate, 2'b10 }; - end - if (((JumpXY == 1'b1 || LDSPHL == 1'b1) && XY_State != 2'b00) || (mcycle[5]) ) - begin - RegAddrC <= #1 { XY_State[1], 2'b11 }; - end - - if (I_DJNZ == 1'b1 && Save_ALU_r == 1'b1 && Mode < 2 ) - begin - IncDecZ <= #1 F_Out[Flag_Z]; - end - if ((tstate[2] || (tstate[3] && mcycle[0])) && IncDec_16[2:0] == 3'b100 ) - begin - if (ID16 == 0 ) - begin - IncDecZ <= #1 1'b0; - end - else - begin - IncDecZ <= #1 1'b1; - end - end - - RegBusA_r <= #1 RegBusA; - end - - end // always @ (posedge clk) - - - always @(/*AUTOSENSE*/Alternate or ExchangeDH or IncDec_16 - or RegAddrA_r or RegAddrB_r or XY_State or mcycle or tstate) - begin - if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && XY_State == 2'b00) - RegAddrA = { Alternate, IncDec_16[1:0] }; - else if ((tstate[2] || (tstate[3] && mcycle[0] && IncDec_16[2] == 1'b1)) && IncDec_16[1:0] == 2'b10) - RegAddrA = { XY_State[1], 2'b11 }; - else if (ExchangeDH == 1'b1 && tstate[3]) - RegAddrA = { Alternate, 2'b10 }; - else if (ExchangeDH == 1'b1 && tstate[4]) - RegAddrA = { Alternate, 2'b01 }; - else - RegAddrA = RegAddrA_r; - - if (ExchangeDH == 1'b1 && tstate[3]) - RegAddrB = { Alternate, 2'b01 }; - else - RegAddrB = RegAddrB_r; - end // always @ * - - - always @(/*AUTOSENSE*/ALU_Op_r or Auto_Wait_t1 or ExchangeDH - or IncDec_16 or Read_To_Reg_r or Save_ALU_r or mcycle - or tstate or wait_n) - begin - RegWEH = 1'b0; - RegWEL = 1'b0; - if ((tstate[1] && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) || - (Save_ALU_r == 1'b1 && ALU_Op_r != 4'b0111) ) - begin - case (Read_To_Reg_r) - 5'b10000 , 5'b10001 , 5'b10010 , 5'b10011 , 5'b10100 , 5'b10101 : - begin - RegWEH = ~ Read_To_Reg_r[0]; - RegWEL = Read_To_Reg_r[0]; - end - endcase // case(Read_To_Reg_r) - - end // if ((tstate == 1 && Save_ALU_r == 1'b0 && Auto_Wait_t1 == 1'b0) ||... - - - if (ExchangeDH == 1'b1 && (tstate[3] || tstate[4]) ) - begin - RegWEH = 1'b1; - RegWEL = 1'b1; - end - - if (IncDec_16[2] == 1'b1 && ((tstate[2] && wait_n == 1'b1 && mcycle != 3'b001) || (tstate[3] && mcycle[0])) ) - begin - case (IncDec_16[1:0]) - 2'b00 , 2'b01 , 2'b10 : - begin - RegWEH = 1'b1; - RegWEL = 1'b1; - end - endcase - end - end // always @ * - - - always @(/*AUTOSENSE*/ExchangeDH or ID16 or IncDec_16 or RegBusA_r - or RegBusB or Save_Mux or mcycle or tstate) - begin - RegDIH = Save_Mux; - RegDIL = Save_Mux; - - if (ExchangeDH == 1'b1 && tstate[3] ) - begin - RegDIH = RegBusB[15:8]; - RegDIL = RegBusB[7:0]; - end - else if (ExchangeDH == 1'b1 && tstate[4] ) - begin - RegDIH = RegBusA_r[15:8]; - RegDIL = RegBusA_r[7:0]; - end - else if (IncDec_16[2] == 1'b1 && ((tstate[2] && mcycle != 3'b001) || (tstate[3] && mcycle[0])) ) - begin - RegDIH = ID16[15:8]; - RegDIL = ID16[7:0]; - end - end - - tv80_reg i_reg - ( - .clk (clk), - .CEN (ClkEn), - .WEH (RegWEH), - .WEL (RegWEL), - .AddrA (RegAddrA), - .AddrB (RegAddrB), - .AddrC (RegAddrC), - .DIH (RegDIH), - .DIL (RegDIL), - .DOAH (RegBusA[15:8]), - .DOAL (RegBusA[7:0]), - .DOBH (RegBusB[15:8]), - .DOBL (RegBusB[7:0]), - .DOCH (RegBusC[15:8]), - .DOCL (RegBusC[7:0]) - ); - - //------------------------------------------------------------------------- - // - // Buses - // - //------------------------------------------------------------------------- - - always @ (posedge clk) - begin - if (ClkEn == 1'b1 ) - begin - case (Set_BusB_To) - 4'b0111 : - BusB <= #1 ACC; - 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 : - begin - if (Set_BusB_To[0] == 1'b1 ) - begin - BusB <= #1 RegBusB[7:0]; - end - else - begin - BusB <= #1 RegBusB[15:8]; - end - end - 4'b0110 : - BusB <= #1 DI_Reg; - 4'b1000 : - BusB <= #1 SP[7:0]; - 4'b1001 : - BusB <= #1 SP[15:8]; - 4'b1010 : - BusB <= #1 8'b00000001; - 4'b1011 : - BusB <= #1 F; - 4'b1100 : - BusB <= #1 PC[7:0]; - 4'b1101 : - BusB <= #1 PC[15:8]; - 4'b1110 : - BusB <= #1 8'b00000000; - default : - BusB <= #1 8'hxx; - endcase - - case (Set_BusA_To) - 4'b0111 : - BusA <= #1 ACC; - 4'b0000 , 4'b0001 , 4'b0010 , 4'b0011 , 4'b0100 , 4'b0101 : - begin - if (Set_BusA_To[0] == 1'b1 ) - begin - BusA <= #1 RegBusA[7:0]; - end - else - begin - BusA <= #1 RegBusA[15:8]; - end - end - 4'b0110 : - BusA <= #1 DI_Reg; - 4'b1000 : - BusA <= #1 SP[7:0]; - 4'b1001 : - BusA <= #1 SP[15:8]; - 4'b1010 : - BusA <= #1 8'b00000000; - default : - BusB <= #1 8'hxx; - endcase - end - end - - //------------------------------------------------------------------------- - // - // Generate external control signals - // - //------------------------------------------------------------------------- -`ifdef TV80_REFRESH - always @ (posedge clk) - begin - if (reset_n == 1'b0 ) - begin - rfsh_n <= #1 1'b1; - end - else - begin - if (cen == 1'b1 ) - begin - if (mcycle[0] && ((tstate[2] && wait_n == 1'b1) || tstate[3]) ) - begin - rfsh_n <= #1 1'b0; - end - else - begin - rfsh_n <= #1 1'b1; - end - end - end - end -`endif - - always @(/*AUTOSENSE*/BusAck or Halt_FF or I_DJNZ or IntCycle - or IntE_FF1 or di or iorq_i or mcycle or tstate) - begin - mc = mcycle; - ts = tstate; - DI_Reg = di; - halt_n = ~ Halt_FF; - busak_n = ~ BusAck; - intcycle_n = ~ IntCycle; - IntE = IntE_FF1; - iorq = iorq_i; - stop = I_DJNZ; - end - - //----------------------------------------------------------------------- - // - // Syncronise inputs - // - //----------------------------------------------------------------------- - - always @ (posedge clk) - begin : sync_inputs - - if (reset_n == 1'b0 ) - begin - BusReq_s <= #1 1'b0; - INT_s <= #1 1'b0; - NMI_s <= #1 1'b0; - Oldnmi_n <= #1 1'b0; - end - else - begin - if (cen == 1'b1 ) - begin - BusReq_s <= #1 ~ busrq_n; - INT_s <= #1 ~ int_n; - if (NMICycle == 1'b1 ) - begin - NMI_s <= #1 1'b0; - end - else if (nmi_n == 1'b0 && Oldnmi_n == 1'b1 ) - begin - NMI_s <= #1 1'b1; - end - Oldnmi_n <= #1 nmi_n; - end - end - end - - //----------------------------------------------------------------------- - // - // Main state machine - // - //----------------------------------------------------------------------- - - always @ (posedge clk) - begin - if (reset_n == 1'b0 ) - begin - mcycle <= #1 7'b0000001; - tstate <= #1 7'b0000001; - Pre_XY_F_M <= #1 3'b000; - Halt_FF <= #1 1'b0; - BusAck <= #1 1'b0; - NMICycle <= #1 1'b0; - IntCycle <= #1 1'b0; - IntE_FF1 <= #1 1'b0; - IntE_FF2 <= #1 1'b0; - No_BTR <= #1 1'b0; - Auto_Wait_t1 <= #1 1'b0; - Auto_Wait_t2 <= #1 1'b0; - m1_n <= #1 1'b1; - end - else - begin - if (cen == 1'b1 ) - begin - if (T_Res == 1'b1 ) - begin - Auto_Wait_t1 <= #1 1'b0; - end - else - begin - Auto_Wait_t1 <= #1 Auto_Wait || iorq_i; - end - Auto_Wait_t2 <= #1 Auto_Wait_t1; - No_BTR <= #1 (I_BT && (~ IR[4] || ~ F[Flag_P])) || - (I_BC && (~ IR[4] || F[Flag_Z] || ~ F[Flag_P])) || - (I_BTR && (~ IR[4] || F[Flag_Z])); - if (tstate[2] ) - begin - if (SetEI == 1'b1 ) - begin - IntE_FF1 <= #1 1'b1; - IntE_FF2 <= #1 1'b1; - end - if (I_RETN == 1'b1 ) - begin - IntE_FF1 <= #1 IntE_FF2; - end - end - if (tstate[3] ) - begin - if (SetDI == 1'b1 ) - begin - IntE_FF1 <= #1 1'b0; - IntE_FF2 <= #1 1'b0; - end - end - if (IntCycle == 1'b1 || NMICycle == 1'b1 ) - begin - Halt_FF <= #1 1'b0; - end - if (mcycle[0] && tstate[2] && wait_n == 1'b1 ) - begin - m1_n <= #1 1'b1; - end - if (BusReq_s == 1'b1 && BusAck == 1'b1 ) - begin - end - else - begin - BusAck <= #1 1'b0; - if (tstate[2] && wait_n == 1'b0 ) - begin - end - else if (T_Res == 1'b1 ) - begin - if (Halt == 1'b1 ) - begin - Halt_FF <= #1 1'b1; - end - if (BusReq_s == 1'b1 ) - begin - BusAck <= #1 1'b1; - end - else - begin - tstate <= #1 7'b0000010; - if (NextIs_XY_Fetch == 1'b1 ) - begin - mcycle <= #1 7'b0100000; - Pre_XY_F_M <= #1 mcycle; - if (IR == 8'b00110110 && Mode == 0 ) - begin - Pre_XY_F_M <= #1 3'b010; - end - end - else if ((mcycle[6]) || (mcycle[5] && Mode == 1 && ISet != 2'b01) ) - begin - mcycle <= #1 number_to_bitvec(Pre_XY_F_M + 1); - end - else if ((last_mcycle) || - No_BTR == 1'b1 || - (mcycle[1] && I_DJNZ == 1'b1 && IncDecZ == 1'b1) ) - begin - m1_n <= #1 1'b0; - mcycle <= #1 7'b0000001; - IntCycle <= #1 1'b0; - NMICycle <= #1 1'b0; - if (NMI_s == 1'b1 && Prefix == 2'b00 ) - begin - NMICycle <= #1 1'b1; - IntE_FF1 <= #1 1'b0; - end - else if ((IntE_FF1 == 1'b1 && INT_s == 1'b1) && Prefix == 2'b00 && SetEI == 1'b0 ) - begin - IntCycle <= #1 1'b1; - IntE_FF1 <= #1 1'b0; - IntE_FF2 <= #1 1'b0; - end - end - else - begin - mcycle <= #1 { mcycle[5:0], mcycle[6] }; - end - end - end - else - begin // verilog has no "nor" operator - if ( ~(Auto_Wait == 1'b1 && Auto_Wait_t2 == 1'b0) && - ~(IOWait == 1 && iorq_i == 1'b1 && Auto_Wait_t1 == 1'b0) ) - begin - tstate <= #1 { tstate[5:0], tstate[6] }; - end - end - end - if (tstate[0]) - begin - m1_n <= #1 1'b0; - end - end - end - end - - always @(/*AUTOSENSE*/BTR_r or DI_Reg or IncDec_16 or JumpE or PC - or RegBusA or RegBusC or SP or tstate) - begin - if (JumpE == 1'b1 ) - begin - PC16_B = { {8{DI_Reg[7]}}, DI_Reg }; - end - else if (BTR_r == 1'b1 ) - begin - PC16_B = -2; - end - else - begin - PC16_B = 1; - end - - if (tstate[3]) - begin - SP16_A = RegBusC; - SP16_B = { {8{DI_Reg[7]}}, DI_Reg }; - end - else - begin - // suspect that ID16 and SP16 could be shared - SP16_A = SP; - - if (IncDec_16[3] == 1'b1) - SP16_B = -1; - else - SP16_B = 1; - end - - if (IncDec_16[3]) - ID16_B = -1; - else - ID16_B = 1; - - ID16 = RegBusA + ID16_B; - PC16 = PC + PC16_B; - SP16 = SP16_A + SP16_B; - end // always @ * - - - always @(/*AUTOSENSE*/IntCycle or NMICycle or mcycle) - begin - Auto_Wait = 1'b0; - if (IntCycle == 1'b1 || NMICycle == 1'b1 ) - begin - if (mcycle[0] ) - begin - Auto_Wait = 1'b1; - end - end - end // always @ * - -// synopsys dc_script_begin -// set_attribute current_design "revision" "$Id: tv80_core.v,v 1.5 2005/01/26 18:55:47 ghutchis Exp $" -type string -quiet -// synopsys dc_script_end -endmodule // T80 - diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_mcode.v b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_mcode.v deleted file mode 100644 index 325e5a8c..00000000 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_mcode.v +++ /dev/null @@ -1,2653 +0,0 @@ -// -// TV80 8-Bit Microprocessor Core -// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) -// -// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -module tv80_mcode - (/*AUTOARG*/ - // Outputs - MCycles, TStates, Prefix, Inc_PC, Inc_WZ, IncDec_16, Read_To_Reg, - Read_To_Acc, Set_BusA_To, Set_BusB_To, ALU_Op, Save_ALU, PreserveC, - Arith16, Set_Addr_To, IORQ, Jump, JumpE, JumpXY, Call, RstP, LDZ, - LDW, LDSPHL, Special_LD, ExchangeDH, ExchangeRp, ExchangeAF, - ExchangeRS, I_DJNZ, I_CPL, I_CCF, I_SCF, I_RETN, I_BT, I_BC, I_BTR, - I_RLD, I_RRD, I_INRC, SetDI, SetEI, IMode, Halt, NoRead, Write, - // Inputs - IR, ISet, MCycle, F, NMICycle, IntCycle - ); - - parameter Mode = 0; - parameter Flag_C = 0; - parameter Flag_N = 1; - parameter Flag_P = 2; - parameter Flag_X = 3; - parameter Flag_H = 4; - parameter Flag_Y = 5; - parameter Flag_Z = 6; - parameter Flag_S = 7; - - input [7:0] IR; - input [1:0] ISet ; - input [6:0] MCycle ; - input [7:0] F ; - input NMICycle ; - input IntCycle ; - output [2:0] MCycles ; - output [2:0] TStates ; - output [1:0] Prefix ; // None,BC,ED,DD/FD - output Inc_PC ; - output Inc_WZ ; - output [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc - output Read_To_Reg ; - output Read_To_Acc ; - output [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - output [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - output [3:0] ALU_Op ; - output Save_ALU ; - output PreserveC ; - output Arith16 ; - output [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI - output IORQ ; - output Jump ; - output JumpE ; - output JumpXY ; - output Call ; - output RstP ; - output LDZ ; - output LDW ; - output LDSPHL ; - output [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None - output ExchangeDH ; - output ExchangeRp ; - output ExchangeAF ; - output ExchangeRS ; - output I_DJNZ ; - output I_CPL ; - output I_CCF ; - output I_SCF ; - output I_RETN ; - output I_BT ; - output I_BC ; - output I_BTR ; - output I_RLD ; - output I_RRD ; - output I_INRC ; - output SetDI ; - output SetEI ; - output [1:0] IMode ; - output Halt ; - output NoRead ; - output Write ; - - // regs - reg [2:0] MCycles ; - reg [2:0] TStates ; - reg [1:0] Prefix ; // None,BC,ED,DD/FD - reg Inc_PC ; - reg Inc_WZ ; - reg [3:0] IncDec_16 ; // BC,DE,HL,SP 0 is inc - reg Read_To_Reg ; - reg Read_To_Acc ; - reg [3:0] Set_BusA_To ; // B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - reg [3:0] Set_BusB_To ; // B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - reg [3:0] ALU_Op ; - reg Save_ALU ; - reg PreserveC ; - reg Arith16 ; - reg [2:0] Set_Addr_To ; // aNone,aXY,aIOA,aSP,aBC,aDE,aZI - reg IORQ ; - reg Jump ; - reg JumpE ; - reg JumpXY ; - reg Call ; - reg RstP ; - reg LDZ ; - reg LDW ; - reg LDSPHL ; - reg [2:0] Special_LD ; // A,I;A,R;I,A;R,A;None - reg ExchangeDH ; - reg ExchangeRp ; - reg ExchangeAF ; - reg ExchangeRS ; - reg I_DJNZ ; - reg I_CPL ; - reg I_CCF ; - reg I_SCF ; - reg I_RETN ; - reg I_BT ; - reg I_BC ; - reg I_BTR ; - reg I_RLD ; - reg I_RRD ; - reg I_INRC ; - reg SetDI ; - reg SetEI ; - reg [1:0] IMode ; - reg Halt ; - reg NoRead ; - reg Write ; - - parameter aNone = 3'b111; - parameter aBC = 3'b000; - parameter aDE = 3'b001; - parameter aXY = 3'b010; - parameter aIOA = 3'b100; - parameter aSP = 3'b101; - parameter aZI = 3'b110; - // constant aNone : std_logic_vector[2:0] = 3'b000; - // constant aXY : std_logic_vector[2:0] = 3'b001; - // constant aIOA : std_logic_vector[2:0] = 3'b010; - // constant aSP : std_logic_vector[2:0] = 3'b011; - // constant aBC : std_logic_vector[2:0] = 3'b100; - // constant aDE : std_logic_vector[2:0] = 3'b101; - // constant aZI : std_logic_vector[2:0] = 3'b110; - - function is_cc_true; - input [7:0] F; - input [2:0] cc; - begin - if (Mode == 3 ) - begin - case (cc) - 3'b000 : is_cc_true = F[7] == 1'b0; // NZ - 3'b001 : is_cc_true = F[7] == 1'b1; // Z - 3'b010 : is_cc_true = F[4] == 1'b0; // NC - 3'b011 : is_cc_true = F[4] == 1'b1; // C - 3'b100 : is_cc_true = 0; - 3'b101 : is_cc_true = 0; - 3'b110 : is_cc_true = 0; - 3'b111 : is_cc_true = 0; - endcase - end - else - begin - case (cc) - 3'b000 : is_cc_true = F[6] == 1'b0; // NZ - 3'b001 : is_cc_true = F[6] == 1'b1; // Z - 3'b010 : is_cc_true = F[0] == 1'b0; // NC - 3'b011 : is_cc_true = F[0] == 1'b1; // C - 3'b100 : is_cc_true = F[2] == 1'b0; // PO - 3'b101 : is_cc_true = F[2] == 1'b1; // PE - 3'b110 : is_cc_true = F[7] == 1'b0; // P - 3'b111 : is_cc_true = F[7] == 1'b1; // M - endcase - end - end - endfunction // is_cc_true - - - reg [2:0] DDD; - reg [2:0] SSS; - reg [1:0] DPAIR; - - always @ (/*AUTOSENSE*/F or IR or ISet or IntCycle or MCycle - or NMICycle) - begin - DDD = IR[5:3]; - SSS = IR[2:0]; - DPAIR = IR[5:4]; - - MCycles = 3'b001; - if (MCycle[0] ) - begin - TStates = 3'b100; - end - else - begin - TStates = 3'b011; - end - Prefix = 2'b00; - Inc_PC = 1'b0; - Inc_WZ = 1'b0; - IncDec_16 = 4'b0000; - Read_To_Acc = 1'b0; - Read_To_Reg = 1'b0; - Set_BusB_To = 4'b0000; - Set_BusA_To = 4'b0000; - ALU_Op = { 1'b0, IR[5:3] }; - Save_ALU = 1'b0; - PreserveC = 1'b0; - Arith16 = 1'b0; - IORQ = 1'b0; - Set_Addr_To = aNone; - Jump = 1'b0; - JumpE = 1'b0; - JumpXY = 1'b0; - Call = 1'b0; - RstP = 1'b0; - LDZ = 1'b0; - LDW = 1'b0; - LDSPHL = 1'b0; - Special_LD = 3'b000; - ExchangeDH = 1'b0; - ExchangeRp = 1'b0; - ExchangeAF = 1'b0; - ExchangeRS = 1'b0; - I_DJNZ = 1'b0; - I_CPL = 1'b0; - I_CCF = 1'b0; - I_SCF = 1'b0; - I_RETN = 1'b0; - I_BT = 1'b0; - I_BC = 1'b0; - I_BTR = 1'b0; - I_RLD = 1'b0; - I_RRD = 1'b0; - I_INRC = 1'b0; - SetDI = 1'b0; - SetEI = 1'b0; - IMode = 2'b11; - Halt = 1'b0; - NoRead = 1'b0; - Write = 1'b0; - - case (ISet) - 2'b00 : - begin - - //---------------------------------------------------------------------------- - // - // Unprefixed instructions - // - //---------------------------------------------------------------------------- - - casex (IR) - // 8 BIT LOAD GROUP - 8'b01xxxxxx : - begin - if (IR[5:0] == 6'b110110) - Halt = 1'b1; - else if (IR[2:0] == 3'b110) - begin - // LD r,(HL) - MCycles = 3'b010; - if (MCycle[0]) - Set_Addr_To = aXY; - if (MCycle[1]) - begin - Set_BusA_To[2:0] = DDD; - Read_To_Reg = 1'b1; - end - end // if (IR[2:0] == 3'b110) - else if (IR[5:3] == 3'b110) - begin - // LD (HL),r - MCycles = 3'b010; - if (MCycle[0]) - begin - Set_Addr_To = aXY; - Set_BusB_To[2:0] = SSS; - Set_BusB_To[3] = 1'b0; - end - if (MCycle[1]) - Write = 1'b1; - end // if (IR[5:3] == 3'b110) - else - begin - Set_BusB_To[2:0] = SSS; - ExchangeRp = 1'b1; - Set_BusA_To[2:0] = DDD; - Read_To_Reg = 1'b1; - end // else: !if(IR[5:3] == 3'b110) - end // case: 8'b01xxxxxx - - 8'b00xxx110 : - begin - if (IR[5:3] == 3'b110) - begin - // LD (HL),n - MCycles = 3'b011; - if (MCycle[1]) - begin - Inc_PC = 1'b1; - Set_Addr_To = aXY; - Set_BusB_To[2:0] = SSS; - Set_BusB_To[3] = 1'b0; - end - if (MCycle[2]) - Write = 1'b1; - end // if (IR[5:3] == 3'b110) - else - begin - // LD r,n - MCycles = 3'b010; - if (MCycle[1]) - begin - Inc_PC = 1'b1; - Set_BusA_To[2:0] = DDD; - Read_To_Reg = 1'b1; - end - end - end - - 8'b00001010 : - begin - // LD A,(BC) - MCycles = 3'b010; - if (MCycle[0]) - Set_Addr_To = aBC; - if (MCycle[1]) - Read_To_Acc = 1'b1; - end // case: 8'b00001010 - - 8'b00011010 : - begin - // LD A,(DE) - MCycles = 3'b010; - if (MCycle[0]) - Set_Addr_To = aDE; - if (MCycle[1]) - Read_To_Acc = 1'b1; - end // case: 8'b00011010 - - 8'b00111010 : - begin - if (Mode == 3 ) - begin - // LDD A,(HL) - MCycles = 3'b010; - if (MCycle[0]) - Set_Addr_To = aXY; - if (MCycle[1]) - begin - Read_To_Acc = 1'b1; - IncDec_16 = 4'b1110; - end - end - else - begin - // LD A,(nn) - MCycles = 3'b100; - if (MCycle[1]) - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - if (MCycle[2]) - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - end - if (MCycle[3]) - begin - Read_To_Acc = 1'b1; - end - end // else: !if(Mode == 3 ) - end // case: 8'b00111010 - - 8'b00000010 : - begin - // LD (BC),A - MCycles = 3'b010; - if (MCycle[0]) - begin - Set_Addr_To = aBC; - Set_BusB_To = 4'b0111; - end - if (MCycle[1]) - begin - Write = 1'b1; - end - end // case: 8'b00000010 - - 8'b00010010 : - begin - // LD (DE),A - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aDE; - Set_BusB_To = 4'b0111; - end - MCycle[1] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: 8'b00010010 - - 8'b00110010 : - begin - if (Mode == 3 ) - begin - // LDD (HL),A - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aXY; - Set_BusB_To = 4'b0111; - end - MCycle[1] : - begin - Write = 1'b1; - IncDec_16 = 4'b1110; - end - default :; - endcase // case(MCycle) - - end - else - begin - // LD (nn),A - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - Set_BusB_To = 4'b0111; - end - MCycle[3] : - begin - Write = 1'b1; - end - default :; - endcase - end // else: !if(Mode == 3 ) - end // case: 8'b00110010 - - - // 16 BIT LOAD GROUP - 8'b00000001,8'b00010001,8'b00100001,8'b00110001 : - begin - // LD dd,nn - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - Read_To_Reg = 1'b1; - if (DPAIR == 2'b11 ) - begin - Set_BusA_To[3:0] = 4'b1000; - end - else - begin - Set_BusA_To[2:1] = DPAIR; - Set_BusA_To[0] = 1'b1; - end - end // case: 2 - - MCycle[2] : - begin - Inc_PC = 1'b1; - Read_To_Reg = 1'b1; - if (DPAIR == 2'b11 ) - begin - Set_BusA_To[3:0] = 4'b1001; - end - else - begin - Set_BusA_To[2:1] = DPAIR; - Set_BusA_To[0] = 1'b0; - end - end // case: 3 - - default :; - endcase // case(MCycle) - end // case: 8'b00000001,8'b00010001,8'b00100001,8'b00110001 - - 8'b00101010 : - begin - if (Mode == 3 ) - begin - // LDI A,(HL) - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aXY; - MCycle[1] : - begin - Read_To_Acc = 1'b1; - IncDec_16 = 4'b0110; - end - - default :; - endcase - end - else - begin - // LD HL,(nn) - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - LDW = 1'b1; - end - MCycle[3] : - begin - Set_BusA_To[2:0] = 3'b101; // L - Read_To_Reg = 1'b1; - Inc_WZ = 1'b1; - Set_Addr_To = aZI; - end - MCycle[4] : - begin - Set_BusA_To[2:0] = 3'b100; // H - Read_To_Reg = 1'b1; - end - default :; - endcase - end // else: !if(Mode == 3 ) - end // case: 8'b00101010 - - 8'b00100010 : - begin - if (Mode == 3 ) - begin - // LDI (HL),A - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aXY; - Set_BusB_To = 4'b0111; - end - MCycle[1] : - begin - Write = 1'b1; - IncDec_16 = 4'b0110; - end - default :; - endcase - end - else - begin - // LD (nn),HL - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - LDW = 1'b1; - Set_BusB_To = 4'b0101; // L - end - - MCycle[3] : - begin - Inc_WZ = 1'b1; - Set_Addr_To = aZI; - Write = 1'b1; - Set_BusB_To = 4'b0100; // H - end - MCycle[4] : - Write = 1'b1; - default :; - endcase - end // else: !if(Mode == 3 ) - end // case: 8'b00100010 - - 8'b11111001 : - begin - // LD SP,HL - TStates = 3'b110; - LDSPHL = 1'b1; - end - - 8'b11xx0101 : - begin - // PUSH qq - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - begin - TStates = 3'b101; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - if (DPAIR == 2'b11 ) - begin - Set_BusB_To = 4'b0111; - end - else - begin - Set_BusB_To[2:1] = DPAIR; - Set_BusB_To[0] = 1'b0; - Set_BusB_To[3] = 1'b0; - end - end // case: 1 - - MCycle[1] : - begin - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - if (DPAIR == 2'b11 ) - begin - Set_BusB_To = 4'b1011; - end - else - begin - Set_BusB_To[2:1] = DPAIR; - Set_BusB_To[0] = 1'b1; - Set_BusB_To[3] = 1'b0; - end - Write = 1'b1; - end // case: 2 - - MCycle[2] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: 8'b11000101,8'b11010101,8'b11100101,8'b11110101 - - 8'b11xx0001 : - begin - // POP qq - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aSP; - MCycle[1] : - begin - IncDec_16 = 4'b0111; - Set_Addr_To = aSP; - Read_To_Reg = 1'b1; - if (DPAIR == 2'b11 ) - begin - Set_BusA_To[3:0] = 4'b1011; - end - else - begin - Set_BusA_To[2:1] = DPAIR; - Set_BusA_To[0] = 1'b1; - end - end // case: 2 - - MCycle[2] : - begin - IncDec_16 = 4'b0111; - Read_To_Reg = 1'b1; - if (DPAIR == 2'b11 ) - begin - Set_BusA_To[3:0] = 4'b0111; - end - else - begin - Set_BusA_To[2:1] = DPAIR; - Set_BusA_To[0] = 1'b0; - end - end // case: 3 - - default :; - endcase // case(MCycle) - end // case: 8'b11000001,8'b11010001,8'b11100001,8'b11110001 - - - // EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP - 8'b11101011 : - begin - if (Mode != 3 ) - begin - // EX DE,HL - ExchangeDH = 1'b1; - end - end - - 8'b00001000 : - begin - if (Mode == 3 ) - begin - // LD (nn),SP - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - LDW = 1'b1; - Set_BusB_To = 4'b1000; - end - - MCycle[3] : - begin - Inc_WZ = 1'b1; - Set_Addr_To = aZI; - Write = 1'b1; - Set_BusB_To = 4'b1001; - end - - MCycle[4] : - Write = 1'b1; - default :; - endcase - end - else if (Mode < 2 ) - begin - // EX AF,AF' - ExchangeAF = 1'b1; - end - end // case: 8'b00001000 - - 8'b11011001 : - begin - if (Mode == 3 ) - begin - // RETI - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aSP; - MCycle[1] : - begin - IncDec_16 = 4'b0111; - Set_Addr_To = aSP; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Jump = 1'b1; - IncDec_16 = 4'b0111; - I_RETN = 1'b1; - SetEI = 1'b1; - end - default :; - endcase - end - else if (Mode < 2 ) - begin - // EXX - ExchangeRS = 1'b1; - end - end // case: 8'b11011001 - - 8'b11100011 : - begin - if (Mode != 3 ) - begin - // EX (SP),HL - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aSP; - MCycle[1] : - begin - Read_To_Reg = 1'b1; - Set_BusA_To = 4'b0101; - Set_BusB_To = 4'b0101; - Set_Addr_To = aSP; - end - MCycle[2] : - begin - IncDec_16 = 4'b0111; - Set_Addr_To = aSP; - TStates = 3'b100; - Write = 1'b1; - end - MCycle[3] : - begin - Read_To_Reg = 1'b1; - Set_BusA_To = 4'b0100; - Set_BusB_To = 4'b0100; - Set_Addr_To = aSP; - end - MCycle[4] : - begin - IncDec_16 = 4'b1111; - TStates = 3'b101; - Write = 1'b1; - end - - default :; - endcase - end // if (Mode != 3 ) - end // case: 8'b11100011 - - - // 8 BIT ARITHMETIC AND LOGICAL GROUP - 8'b10xxxxxx : - begin - if (IR[2:0] == 3'b110) - begin - // ADD A,(HL) - // ADC A,(HL) - // SUB A,(HL) - // SBC A,(HL) - // AND A,(HL) - // OR A,(HL) - // XOR A,(HL) - // CP A,(HL) - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aXY; - MCycle[1] : - begin - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_BusB_To[2:0] = SSS; - Set_BusA_To[2:0] = 3'b111; - end - - default :; - endcase // case(MCycle) - end // if (IR[2:0] == 3'b110) - else - begin - // ADD A,r - // ADC A,r - // SUB A,r - // SBC A,r - // AND A,r - // OR A,r - // XOR A,r - // CP A,r - Set_BusB_To[2:0] = SSS; - Set_BusA_To[2:0] = 3'b111; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - end // else: !if(IR[2:0] == 3'b110) - end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,... - - 8'b11xxx110 : - begin - // ADD A,n - // ADC A,n - // SUB A,n - // SBC A,n - // AND A,n - // OR A,n - // XOR A,n - // CP A,n - MCycles = 3'b010; - if (MCycle[1] ) - begin - Inc_PC = 1'b1; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_BusB_To[2:0] = SSS; - Set_BusA_To[2:0] = 3'b111; - end - end - - 8'b00xxx100 : - begin - if (IR[5:3] == 3'b110) - begin - // INC (HL) - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aXY; - MCycle[1] : - begin - TStates = 3'b100; - Set_Addr_To = aXY; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - PreserveC = 1'b1; - ALU_Op = 4'b0000; - Set_BusB_To = 4'b1010; - Set_BusA_To[2:0] = DDD; - end // case: 2 - - MCycle[2] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: 8'b00110100 - else - begin - // INC r - Set_BusB_To = 4'b1010; - Set_BusA_To[2:0] = DDD; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - PreserveC = 1'b1; - ALU_Op = 4'b0000; - end - end - - 8'b00xxx101 : - begin - if (IR[5:3] == 3'b110) - begin - // DEC (HL) - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aXY; - MCycle[1] : - begin - TStates = 3'b100; - Set_Addr_To = aXY; - ALU_Op = 4'b0010; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - PreserveC = 1'b1; - Set_BusB_To = 4'b1010; - Set_BusA_To[2:0] = DDD; - end // case: 2 - - MCycle[2] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end - else - begin - // DEC r - Set_BusB_To = 4'b1010; - Set_BusA_To[2:0] = DDD; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - PreserveC = 1'b1; - ALU_Op = 4'b0010; - end - end - - // GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS - 8'b00100111 : - begin - // DAA - Set_BusA_To[2:0] = 3'b111; - Read_To_Reg = 1'b1; - ALU_Op = 4'b1100; - Save_ALU = 1'b1; - end - - 8'b00101111 : - // CPL - I_CPL = 1'b1; - - 8'b00111111 : - // CCF - I_CCF = 1'b1; - - 8'b00110111 : - // SCF - I_SCF = 1'b1; - - 8'b00000000 : - begin - if (NMICycle == 1'b1 ) - begin - // NMI - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - begin - TStates = 3'b101; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1101; - end - - MCycle[1] : - begin - TStates = 3'b100; - Write = 1'b1; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1100; - end - - MCycle[2] : - begin - TStates = 3'b100; - Write = 1'b1; - end - - default :; - endcase // case(MCycle) - - end - else if (IntCycle == 1'b1 ) - begin - // INT (IM 2) - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[0] : - begin - LDZ = 1'b1; - TStates = 3'b101; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1101; - end - - MCycle[1] : - begin - TStates = 3'b100; - Write = 1'b1; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1100; - end - - MCycle[2] : - begin - TStates = 3'b100; - Write = 1'b1; - end - - MCycle[3] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - MCycle[4] : - Jump = 1'b1; - default :; - endcase - end - end // case: 8'b00000000 - - 8'b11110011 : - // DI - SetDI = 1'b1; - - 8'b11111011 : - // EI - SetEI = 1'b1; - - // 16 BIT ARITHMETIC GROUP - 8'b00001001,8'b00011001,8'b00101001,8'b00111001 : - begin - // ADD HL,ss - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - NoRead = 1'b1; - ALU_Op = 4'b0000; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_BusA_To[2:0] = 3'b101; - case (IR[5:4]) - 0,1,2 : - begin - Set_BusB_To[2:1] = IR[5:4]; - Set_BusB_To[0] = 1'b1; - end - - default : - Set_BusB_To = 4'b1000; - endcase // case(IR[5:4]) - - TStates = 3'b100; - Arith16 = 1'b1; - end // case: 2 - - MCycle[2] : - begin - NoRead = 1'b1; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - ALU_Op = 4'b0001; - Set_BusA_To[2:0] = 3'b100; - case (IR[5:4]) - 0,1,2 : - Set_BusB_To[2:1] = IR[5:4]; - default : - Set_BusB_To = 4'b1001; - endcase - Arith16 = 1'b1; - end // case: 3 - - default :; - endcase // case(MCycle) - end // case: 8'b00001001,8'b00011001,8'b00101001,8'b00111001 - - 8'b00000011,8'b00010011,8'b00100011,8'b00110011 : - begin - // INC ss - TStates = 3'b110; - IncDec_16[3:2] = 2'b01; - IncDec_16[1:0] = DPAIR; - end - - 8'b00001011,8'b00011011,8'b00101011,8'b00111011 : - begin - // DEC ss - TStates = 3'b110; - IncDec_16[3:2] = 2'b11; - IncDec_16[1:0] = DPAIR; - end - - // ROTATE AND SHIFT GROUP - 8'b00000111, - // RLCA - 8'b00010111, - // RLA - 8'b00001111, - // RRCA - 8'b00011111 : - // RRA - begin - Set_BusA_To[2:0] = 3'b111; - ALU_Op = 4'b1000; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - end // case: 8'b00000111,... - - - // JUMP GROUP - 8'b11000011 : - begin - // JP nn - MCycles = 3'b011; - if (MCycle[1]) - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - if (MCycle[2]) - begin - Inc_PC = 1'b1; - Jump = 1'b1; - end - - end // case: 8'b11000011 - - 8'b11xxx010 : - begin - if (IR[5] == 1'b1 && Mode == 3 ) - begin - case (IR[4:3]) - 2'b00 : - begin - // LD ($FF00+C),A - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aBC; - Set_BusB_To = 4'b0111; - end - MCycle[1] : - begin - Write = 1'b1; - IORQ = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 2'b00 - - 2'b01 : - begin - // LD (nn),A - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - Set_BusB_To = 4'b0111; - end - - MCycle[3] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: default :... - - 2'b10 : - begin - // LD A,($FF00+C) - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aBC; - MCycle[1] : - begin - Read_To_Acc = 1'b1; - IORQ = 1'b1; - end - default :; - endcase // case(MCycle) - end // case: 2'b10 - - 2'b11 : - begin - // LD A,(nn) - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - end - MCycle[3] : - Read_To_Acc = 1'b1; - default :; - endcase // case(MCycle) - end - endcase - end - else - begin - // JP cc,nn - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - MCycle[2] : - begin - Inc_PC = 1'b1; - if (is_cc_true(F, IR[5:3]) ) - begin - Jump = 1'b1; - end - end - - default :; - endcase - end // else: !if(DPAIR == 2'b11 ) - end // case: 8'b11000010,8'b11001010,8'b11010010,8'b11011010,8'b11100010,8'b11101010,8'b11110010,8'b11111010 - - 8'b00011000 : - begin - if (Mode != 2 ) - begin - // JR e - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - Inc_PC = 1'b1; - MCycle[2] : - begin - NoRead = 1'b1; - JumpE = 1'b1; - TStates = 3'b101; - end - default :; - endcase - end // if (Mode != 2 ) - end // case: 8'b00011000 - - // Conditional relative jumps (JR [C/NC/Z/NZ], e) - 8'b001xx000 : - begin - if (Mode != 2 ) - begin - MCycles = 3'd3; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - - case (IR[4:3]) - 0 : MCycles = (F[Flag_Z]) ? 3'd2 : 3'd3; - 1 : MCycles = (!F[Flag_Z]) ? 3'd2 : 3'd3; - 2 : MCycles = (F[Flag_C]) ? 3'd2 : 3'd3; - 3 : MCycles = (!F[Flag_C]) ? 3'd2 : 3'd3; - endcase - end - - MCycle[2] : - begin - NoRead = 1'b1; - JumpE = 1'b1; - TStates = 3'd5; - end - default :; - endcase - end // if (Mode != 2 ) - end // case: 8'b00111000 - - 8'b11101001 : - // JP (HL) - JumpXY = 1'b1; - - 8'b00010000 : - begin - if (Mode == 3 ) - begin - I_DJNZ = 1'b1; - end - else if (Mode < 2 ) - begin - // DJNZ,e - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - begin - TStates = 3'b101; - I_DJNZ = 1'b1; - Set_BusB_To = 4'b1010; - Set_BusA_To[2:0] = 3'b000; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - ALU_Op = 4'b0010; - end - MCycle[1] : - begin - I_DJNZ = 1'b1; - Inc_PC = 1'b1; - end - MCycle[2] : - begin - NoRead = 1'b1; - JumpE = 1'b1; - TStates = 3'b101; - end - default :; - endcase - end // if (Mode < 2 ) - end // case: 8'b00010000 - - - // CALL AND RETURN GROUP - 8'b11001101 : - begin - // CALL nn - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - MCycle[2] : - begin - IncDec_16 = 4'b1111; - Inc_PC = 1'b1; - TStates = 3'b100; - Set_Addr_To = aSP; - LDW = 1'b1; - Set_BusB_To = 4'b1101; - end - MCycle[3] : - begin - Write = 1'b1; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1100; - end - MCycle[4] : - begin - Write = 1'b1; - Call = 1'b1; - end - default :; - endcase // case(MCycle) - end // case: 8'b11001101 - - 8'b11000100,8'b11001100,8'b11010100,8'b11011100,8'b11100100,8'b11101100,8'b11110100,8'b11111100 : - begin - if (IR[5] == 1'b0 || Mode != 3 ) - begin - // CALL cc,nn - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - MCycle[2] : - begin - Inc_PC = 1'b1; - LDW = 1'b1; - if (is_cc_true(F, IR[5:3]) ) - begin - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - TStates = 3'b100; - Set_BusB_To = 4'b1101; - end - else - begin - MCycles = 3'b011; - end // else: !if(is_cc_true(F, IR[5:3]) ) - end // case: 3 - - MCycle[3] : - begin - Write = 1'b1; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1100; - end - - MCycle[4] : - begin - Write = 1'b1; - Call = 1'b1; - end - - default :; - endcase - end // if (IR[5] == 1'b0 || Mode != 3 ) - end // case: 8'b11000100,8'b11001100,8'b11010100,8'b11011100,8'b11100100,8'b11101100,8'b11110100,8'b11111100 - - 8'b11001001 : - begin - // RET - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - begin - TStates = 3'b101; - Set_Addr_To = aSP; - end - - MCycle[1] : - begin - IncDec_16 = 4'b0111; - Set_Addr_To = aSP; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Jump = 1'b1; - IncDec_16 = 4'b0111; - end - - default :; - endcase // case(MCycle) - end // case: 8'b11001001 - - 8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000 : - begin - if (IR[5] == 1'b1 && Mode == 3 ) - begin - case (IR[4:3]) - 2'b00 : - begin - // LD ($FF00+nn),A - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - Set_Addr_To = aIOA; - Set_BusB_To = 4'b0111; - end - - MCycle[2] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: 2'b00 - - 2'b01 : - begin - // ADD SP,n - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - ALU_Op = 4'b0000; - Inc_PC = 1'b1; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_BusA_To = 4'b1000; - Set_BusB_To = 4'b0110; - end - - MCycle[2] : - begin - NoRead = 1'b1; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - ALU_Op = 4'b0001; - Set_BusA_To = 4'b1001; - Set_BusB_To = 4'b1110; // Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! - end - - default :; - endcase // case(MCycle) - end // case: 2'b01 - - 2'b10 : - begin - // LD A,($FF00+nn) - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - Set_Addr_To = aIOA; - end - - MCycle[2] : - Read_To_Acc = 1'b1; - default :; - endcase // case(MCycle) - end // case: 2'b10 - - 2'b11 : - begin - // LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - LDW = 1'b1; - end - - MCycle[3] : - begin - Set_BusA_To[2:0] = 3'b101; // L - Read_To_Reg = 1'b1; - Inc_WZ = 1'b1; - Set_Addr_To = aZI; - end - - MCycle[4] : - begin - Set_BusA_To[2:0] = 3'b100; // H - Read_To_Reg = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 2'b11 - - endcase // case(IR[4:3]) - - end - else - begin - // RET cc - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - begin - if (is_cc_true(F, IR[5:3]) ) - begin - Set_Addr_To = aSP; - end - else - begin - MCycles = 3'b001; - end - TStates = 3'b101; - end // case: 1 - - MCycle[1] : - begin - IncDec_16 = 4'b0111; - Set_Addr_To = aSP; - LDZ = 1'b1; - end - MCycle[2] : - begin - Jump = 1'b1; - IncDec_16 = 4'b0111; - end - default :; - endcase - end // else: !if(IR[5] == 1'b1 && Mode == 3 ) - end // case: 8'b11000000,8'b11001000,8'b11010000,8'b11011000,8'b11100000,8'b11101000,8'b11110000,8'b11111000 - - 8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111 : - begin - // RST p - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - begin - TStates = 3'b101; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1101; - end - - MCycle[1] : - begin - Write = 1'b1; - IncDec_16 = 4'b1111; - Set_Addr_To = aSP; - Set_BusB_To = 4'b1100; - end - - MCycle[2] : - begin - Write = 1'b1; - RstP = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 8'b11000111,8'b11001111,8'b11010111,8'b11011111,8'b11100111,8'b11101111,8'b11110111,8'b11111111 - - // INPUT AND OUTPUT GROUP - 8'b11011011 : - begin - if (Mode != 3 ) - begin - // IN A,(n) - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - Set_Addr_To = aIOA; - end - - MCycle[2] : - begin - Read_To_Acc = 1'b1; - IORQ = 1'b1; - end - - default :; - endcase - end // if (Mode != 3 ) - end // case: 8'b11011011 - - 8'b11010011 : - begin - if (Mode != 3 ) - begin - // OUT (n),A - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - Set_Addr_To = aIOA; - Set_BusB_To = 4'b0111; - end - - MCycle[2] : - begin - Write = 1'b1; - IORQ = 1'b1; - end - - default :; - endcase - end // if (Mode != 3 ) - end // case: 8'b11010011 - - - //---------------------------------------------------------------------------- - //---------------------------------------------------------------------------- - // MULTIBYTE INSTRUCTIONS - //---------------------------------------------------------------------------- - //---------------------------------------------------------------------------- - - 8'b11001011 : - begin - if (Mode != 2 ) - begin - Prefix = 2'b01; - end - end - - 8'b11101101 : - begin - if (Mode < 2 ) - begin - Prefix = 2'b10; - end - end - - 8'b11011101,8'b11111101 : - begin - if (Mode < 2 ) - begin - Prefix = 2'b11; - end - end - - endcase // case(IR) - end // case: 2'b00 - - - 2'b01 : - begin - - - //---------------------------------------------------------------------------- - // - // CB prefixed instructions - // - //---------------------------------------------------------------------------- - - Set_BusA_To[2:0] = IR[2:0]; - Set_BusB_To[2:0] = IR[2:0]; - - case (IR) - 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111, - 8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010111, - 8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001111, - 8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011111, - 8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100111, - 8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101111, - 8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110111, - 8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111111 : - begin - // RLC r - // RL r - // RRC r - // RR r - // SLA r - // SRA r - // SRL r - // SLL r (Undocumented) / SWAP r - if (MCycle[0] ) begin - ALU_Op = 4'b1000; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - end - end // case: 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000111,... - - 8'b00000110, 8'b00001110, 8'b00010110, 8'b00011110, - 8'b00100110, 8'b00101110, 8'b00110110, 8'b00111110 : - begin - // RLC (HL) - // RL (HL) - // RRC (HL) - // RR (HL) - // SRA (HL) - // SRL (HL) - // SLA (HL) - // SLL (HL) (Undocumented) / SWAP (HL) - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0], MCycle[6] : - Set_Addr_To = aXY; - MCycle[1] : - begin - ALU_Op = 4'b1000; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_Addr_To = aXY; - TStates = 3'b100; - end - - MCycle[2] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: 8'b00000110,8'b00010110,8'b00001110,8'b00011110,8'b00101110,8'b00111110,8'b00100110,8'b00110110 - - 8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111, - 8'b01001000,8'b01001001,8'b01001010,8'b01001011,8'b01001100,8'b01001101,8'b01001111, - 8'b01010000,8'b01010001,8'b01010010,8'b01010011,8'b01010100,8'b01010101,8'b01010111, - 8'b01011000,8'b01011001,8'b01011010,8'b01011011,8'b01011100,8'b01011101,8'b01011111, - 8'b01100000,8'b01100001,8'b01100010,8'b01100011,8'b01100100,8'b01100101,8'b01100111, - 8'b01101000,8'b01101001,8'b01101010,8'b01101011,8'b01101100,8'b01101101,8'b01101111, - 8'b01110000,8'b01110001,8'b01110010,8'b01110011,8'b01110100,8'b01110101,8'b01110111, - 8'b01111000,8'b01111001,8'b01111010,8'b01111011,8'b01111100,8'b01111101,8'b01111111 : - begin - // BIT b,r - if (MCycle[0] ) - begin - Set_BusB_To[2:0] = IR[2:0]; - ALU_Op = 4'b1001; - end - end // case: 8'b01000000,8'b01000001,8'b01000010,8'b01000011,8'b01000100,8'b01000101,8'b01000111,... - - 8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110 : - begin - // BIT b,(HL) - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0], MCycle[6] : - Set_Addr_To = aXY; - MCycle[1] : - begin - ALU_Op = 4'b1001; - TStates = 3'b100; - end - - default :; - endcase // case(MCycle) - end // case: 8'b01000110,8'b01001110,8'b01010110,8'b01011110,8'b01100110,8'b01101110,8'b01110110,8'b01111110 - - 8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111, - 8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001111, - 8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010111, - 8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011111, - 8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100111, - 8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101111, - 8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110111, - 8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111111 : - begin - // SET b,r - if (MCycle[0] ) - begin - ALU_Op = 4'b1010; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - end - end // case: 8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000111,... - - 8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110 : - begin - // SET b,(HL) - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0], MCycle[6] : - Set_Addr_To = aXY; - MCycle[1] : - begin - ALU_Op = 4'b1010; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_Addr_To = aXY; - TStates = 3'b100; - end - MCycle[2] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: 8'b11000110,8'b11001110,8'b11010110,8'b11011110,8'b11100110,8'b11101110,8'b11110110,8'b11111110 - - 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111, - 8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001111, - 8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010111, - 8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011111, - 8'b10100000,8'b10100001,8'b10100010,8'b10100011,8'b10100100,8'b10100101,8'b10100111, - 8'b10101000,8'b10101001,8'b10101010,8'b10101011,8'b10101100,8'b10101101,8'b10101111, - 8'b10110000,8'b10110001,8'b10110010,8'b10110011,8'b10110100,8'b10110101,8'b10110111, - 8'b10111000,8'b10111001,8'b10111010,8'b10111011,8'b10111100,8'b10111101,8'b10111111 : - begin - // RES b,r - if (MCycle[0] ) - begin - ALU_Op = 4'b1011; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - end - end // case: 8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000111,... - - 8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110 : - begin - // RES b,(HL) - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0], MCycle[6] : - Set_Addr_To = aXY; - MCycle[1] : - begin - ALU_Op = 4'b1011; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_Addr_To = aXY; - TStates = 3'b100; - end - - MCycle[2] : - Write = 1'b1; - default :; - endcase // case(MCycle) - end // case: 8'b10000110,8'b10001110,8'b10010110,8'b10011110,8'b10100110,8'b10101110,8'b10110110,8'b10111110 - - endcase // case(IR) - end // case: 2'b01 - - - default : - begin : default_ed_block - - //---------------------------------------------------------------------------- - // - // ED prefixed instructions - // - //---------------------------------------------------------------------------- - - case (IR) - /* - * Undocumented NOP instructions commented out to reduce size of mcode - * - 8'b00000000,8'b00000001,8'b00000010,8'b00000011,8'b00000100,8'b00000101,8'b00000110,8'b00000111 - ,8'b00001000,8'b00001001,8'b00001010,8'b00001011,8'b00001100,8'b00001101,8'b00001110,8'b00001111 - ,8'b00010000,8'b00010001,8'b00010010,8'b00010011,8'b00010100,8'b00010101,8'b00010110,8'b00010111 - ,8'b00011000,8'b00011001,8'b00011010,8'b00011011,8'b00011100,8'b00011101,8'b00011110,8'b00011111 - ,8'b00100000,8'b00100001,8'b00100010,8'b00100011,8'b00100100,8'b00100101,8'b00100110,8'b00100111 - ,8'b00101000,8'b00101001,8'b00101010,8'b00101011,8'b00101100,8'b00101101,8'b00101110,8'b00101111 - ,8'b00110000,8'b00110001,8'b00110010,8'b00110011,8'b00110100,8'b00110101,8'b00110110,8'b00110111 - ,8'b00111000,8'b00111001,8'b00111010,8'b00111011,8'b00111100,8'b00111101,8'b00111110,8'b00111111 - - - ,8'b10000000,8'b10000001,8'b10000010,8'b10000011,8'b10000100,8'b10000101,8'b10000110,8'b10000111 - ,8'b10001000,8'b10001001,8'b10001010,8'b10001011,8'b10001100,8'b10001101,8'b10001110,8'b10001111 - ,8'b10010000,8'b10010001,8'b10010010,8'b10010011,8'b10010100,8'b10010101,8'b10010110,8'b10010111 - ,8'b10011000,8'b10011001,8'b10011010,8'b10011011,8'b10011100,8'b10011101,8'b10011110,8'b10011111 - , 8'b10100100,8'b10100101,8'b10100110,8'b10100111 - , 8'b10101100,8'b10101101,8'b10101110,8'b10101111 - , 8'b10110100,8'b10110101,8'b10110110,8'b10110111 - , 8'b10111100,8'b10111101,8'b10111110,8'b10111111 - ,8'b11000000,8'b11000001,8'b11000010,8'b11000011,8'b11000100,8'b11000101,8'b11000110,8'b11000111 - ,8'b11001000,8'b11001001,8'b11001010,8'b11001011,8'b11001100,8'b11001101,8'b11001110,8'b11001111 - ,8'b11010000,8'b11010001,8'b11010010,8'b11010011,8'b11010100,8'b11010101,8'b11010110,8'b11010111 - ,8'b11011000,8'b11011001,8'b11011010,8'b11011011,8'b11011100,8'b11011101,8'b11011110,8'b11011111 - ,8'b11100000,8'b11100001,8'b11100010,8'b11100011,8'b11100100,8'b11100101,8'b11100110,8'b11100111 - ,8'b11101000,8'b11101001,8'b11101010,8'b11101011,8'b11101100,8'b11101101,8'b11101110,8'b11101111 - ,8'b11110000,8'b11110001,8'b11110010,8'b11110011,8'b11110100,8'b11110101,8'b11110110,8'b11110111 - ,8'b11111000,8'b11111001,8'b11111010,8'b11111011,8'b11111100,8'b11111101,8'b11111110,8'b11111111 : - ; // NOP, undocumented - - 8'b01111110,8'b01111111 : - // NOP, undocumented - ; - */ - - // 8 BIT LOAD GROUP - 8'b01010111 : - begin - // LD A,I - Special_LD = 3'b100; - TStates = 3'b101; - end - - 8'b01011111 : - begin - // LD A,R - Special_LD = 3'b101; - TStates = 3'b101; - end - - 8'b01000111 : - begin - // LD I,A - Special_LD = 3'b110; - TStates = 3'b101; - end - - 8'b01001111 : - begin - // LD R,A - Special_LD = 3'b111; - TStates = 3'b101; - end - - // 16 BIT LOAD GROUP - 8'b01001011,8'b01011011,8'b01101011,8'b01111011 : - begin - // LD dd,(nn) - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - LDW = 1'b1; - end - - MCycle[3] : - begin - Read_To_Reg = 1'b1; - if (IR[5:4] == 2'b11 ) - begin - Set_BusA_To = 4'b1000; - end - else - begin - Set_BusA_To[2:1] = IR[5:4]; - Set_BusA_To[0] = 1'b1; - end - Inc_WZ = 1'b1; - Set_Addr_To = aZI; - end // case: 4 - - MCycle[4] : - begin - Read_To_Reg = 1'b1; - if (IR[5:4] == 2'b11 ) - begin - Set_BusA_To = 4'b1001; - end - else - begin - Set_BusA_To[2:1] = IR[5:4]; - Set_BusA_To[0] = 1'b0; - end - end // case: 5 - - default :; - endcase // case(MCycle) - end // case: 8'b01001011,8'b01011011,8'b01101011,8'b01111011 - - - 8'b01000011,8'b01010011,8'b01100011,8'b01110011 : - begin - // LD (nn),dd - MCycles = 3'b101; - case (1'b1) // MCycle - MCycle[1] : - begin - Inc_PC = 1'b1; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Set_Addr_To = aZI; - Inc_PC = 1'b1; - LDW = 1'b1; - if (IR[5:4] == 2'b11 ) - begin - Set_BusB_To = 4'b1000; - end - else - begin - Set_BusB_To[2:1] = IR[5:4]; - Set_BusB_To[0] = 1'b1; - Set_BusB_To[3] = 1'b0; - end - end // case: 3 - - MCycle[3] : - begin - Inc_WZ = 1'b1; - Set_Addr_To = aZI; - Write = 1'b1; - if (IR[5:4] == 2'b11 ) - begin - Set_BusB_To = 4'b1001; - end - else - begin - Set_BusB_To[2:1] = IR[5:4]; - Set_BusB_To[0] = 1'b0; - Set_BusB_To[3] = 1'b0; - end - end // case: 4 - - MCycle[4] : - begin - Write = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 8'b01000011,8'b01010011,8'b01100011,8'b01110011 - - 8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000 : - begin - // LDI, LDD, LDIR, LDDR - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aXY; - IncDec_16 = 4'b1100; // BC - end - - MCycle[1] : - begin - Set_BusB_To = 4'b0110; - Set_BusA_To[2:0] = 3'b111; - ALU_Op = 4'b0000; - Set_Addr_To = aDE; - if (IR[3] == 1'b0 ) - begin - IncDec_16 = 4'b0110; // IX - end - else - begin - IncDec_16 = 4'b1110; - end - end // case: 2 - - MCycle[2] : - begin - I_BT = 1'b1; - TStates = 3'b101; - Write = 1'b1; - if (IR[3] == 1'b0 ) - begin - IncDec_16 = 4'b0101; // DE - end - else - begin - IncDec_16 = 4'b1101; - end - end // case: 3 - - MCycle[3] : - begin - NoRead = 1'b1; - TStates = 3'b101; - end - - default :; - endcase // case(MCycle) - end // case: 8'b10100000 , 8'b10101000 , 8'b10110000 , 8'b10111000 - - 8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001 : - begin - // CPI, CPD, CPIR, CPDR - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aXY; - IncDec_16 = 4'b1100; // BC - end - - MCycle[1] : - begin - Set_BusB_To = 4'b0110; - Set_BusA_To[2:0] = 3'b111; - ALU_Op = 4'b0111; - Save_ALU = 1'b1; - PreserveC = 1'b1; - if (IR[3] == 1'b0 ) - begin - IncDec_16 = 4'b0110; - end - else - begin - IncDec_16 = 4'b1110; - end - end // case: 2 - - MCycle[2] : - begin - NoRead = 1'b1; - I_BC = 1'b1; - TStates = 3'b101; - end - - MCycle[3] : - begin - NoRead = 1'b1; - TStates = 3'b101; - end - - default :; - endcase // case(MCycle) - end // case: 8'b10100001 , 8'b10101001 , 8'b10110001 , 8'b10111001 - - 8'b01000100,8'b01001100,8'b01010100,8'b01011100,8'b01100100,8'b01101100,8'b01110100,8'b01111100 : - begin - // NEG - ALU_Op = 4'b0010; - Set_BusB_To = 4'b0111; - Set_BusA_To = 4'b1010; - Read_To_Acc = 1'b1; - Save_ALU = 1'b1; - end - - 8'b01000110,8'b01001110,8'b01100110,8'b01101110 : - begin - // IM 0 - IMode = 2'b00; - end - - 8'b01010110,8'b01110110 : - // IM 1 - IMode = 2'b01; - - 8'b01011110,8'b01110111 : - // IM 2 - IMode = 2'b10; - - // 16 bit arithmetic - 8'b01001010,8'b01011010,8'b01101010,8'b01111010 : - begin - // ADC HL,ss - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - NoRead = 1'b1; - ALU_Op = 4'b0001; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_BusA_To[2:0] = 3'b101; - case (IR[5:4]) - 0,1,2 : - begin - Set_BusB_To[2:1] = IR[5:4]; - Set_BusB_To[0] = 1'b1; - end - default : - Set_BusB_To = 4'b1000; - endcase - TStates = 3'b100; - end // case: 2 - - MCycle[2] : - begin - NoRead = 1'b1; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - ALU_Op = 4'b0001; - Set_BusA_To[2:0] = 3'b100; - case (IR[5:4]) - 0,1,2 : - begin - Set_BusB_To[2:1] = IR[5:4]; - Set_BusB_To[0] = 1'b0; - end - default : - Set_BusB_To = 4'b1001; - endcase // case(IR[5:4]) - end // case: 3 - - default :; - endcase // case(MCycle) - end // case: 8'b01001010,8'b01011010,8'b01101010,8'b01111010 - - 8'b01000010,8'b01010010,8'b01100010,8'b01110010 : - begin - // SBC HL,ss - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[1] : - begin - NoRead = 1'b1; - ALU_Op = 4'b0011; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_BusA_To[2:0] = 3'b101; - case (IR[5:4]) - 0,1,2 : - begin - Set_BusB_To[2:1] = IR[5:4]; - Set_BusB_To[0] = 1'b1; - end - default : - Set_BusB_To = 4'b1000; - endcase - TStates = 3'b100; - end // case: 2 - - MCycle[2] : - begin - NoRead = 1'b1; - ALU_Op = 4'b0011; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - Set_BusA_To[2:0] = 3'b100; - case (IR[5:4]) - 0,1,2 : - Set_BusB_To[2:1] = IR[5:4]; - default : - Set_BusB_To = 4'b1001; - endcase - end // case: 3 - - default :; - - endcase // case(MCycle) - end // case: 8'b01000010,8'b01010010,8'b01100010,8'b01110010 - - 8'b01101111 : - begin - // RLD - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[1] : - begin - NoRead = 1'b1; - Set_Addr_To = aXY; - end - - MCycle[2] : - begin - Read_To_Reg = 1'b1; - Set_BusB_To[2:0] = 3'b110; - Set_BusA_To[2:0] = 3'b111; - ALU_Op = 4'b1101; - TStates = 3'b100; - Set_Addr_To = aXY; - Save_ALU = 1'b1; - end - - MCycle[3] : - begin - I_RLD = 1'b1; - Write = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 8'b01101111 - - 8'b01100111 : - begin - // RRD - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[1] : - Set_Addr_To = aXY; - MCycle[2] : - begin - Read_To_Reg = 1'b1; - Set_BusB_To[2:0] = 3'b110; - Set_BusA_To[2:0] = 3'b111; - ALU_Op = 4'b1110; - TStates = 3'b100; - Set_Addr_To = aXY; - Save_ALU = 1'b1; - end - - MCycle[3] : - begin - I_RRD = 1'b1; - Write = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 8'b01100111 - - 8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101 : - begin - // RETI, RETN - MCycles = 3'b011; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aSP; - - MCycle[1] : - begin - IncDec_16 = 4'b0111; - Set_Addr_To = aSP; - LDZ = 1'b1; - end - - MCycle[2] : - begin - Jump = 1'b1; - IncDec_16 = 4'b0111; - I_RETN = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 8'b01000101,8'b01001101,8'b01010101,8'b01011101,8'b01100101,8'b01101101,8'b01110101,8'b01111101 - - 8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000 : - begin - // IN r,(C) - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - Set_Addr_To = aBC; - - MCycle[1] : - begin - IORQ = 1'b1; - if (IR[5:3] != 3'b110 ) - begin - Read_To_Reg = 1'b1; - Set_BusA_To[2:0] = IR[5:3]; - end - I_INRC = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 8'b01000000,8'b01001000,8'b01010000,8'b01011000,8'b01100000,8'b01101000,8'b01110000,8'b01111000 - - 8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001 : - begin - // OUT (C),r - // OUT (C),0 - MCycles = 3'b010; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aBC; - Set_BusB_To[2:0] = IR[5:3]; - if (IR[5:3] == 3'b110 ) - begin - Set_BusB_To[3] = 1'b1; - end - end - - MCycle[1] : - begin - Write = 1'b1; - IORQ = 1'b1; - end - - default :; - endcase // case(MCycle) - end // case: 8'b01000001,8'b01001001,8'b01010001,8'b01011001,8'b01100001,8'b01101001,8'b01110001,8'b01111001 - - 8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010 : - begin - // INI, IND, INIR, INDR - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[0] : - begin - Set_Addr_To = aBC; - Set_BusB_To = 4'b1010; - Set_BusA_To = 4'b0000; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - ALU_Op = 4'b0010; - end - - MCycle[1] : - begin - IORQ = 1'b1; - Set_BusB_To = 4'b0110; - Set_Addr_To = aXY; - end - - MCycle[2] : - begin - if (IR[3] == 1'b0 ) - begin - IncDec_16 = 4'b0110; - end - else - begin - IncDec_16 = 4'b1110; - end - TStates = 3'b100; - Write = 1'b1; - I_BTR = 1'b1; - end // case: 3 - - MCycle[3] : - begin - NoRead = 1'b1; - TStates = 3'b101; - end - - default :; - endcase // case(MCycle) - end // case: 8'b10100010 , 8'b10101010 , 8'b10110010 , 8'b10111010 - - 8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011 : - begin - // OUTI, OUTD, OTIR, OTDR - MCycles = 3'b100; - case (1'b1) // MCycle - MCycle[0] : - begin - TStates = 3'b101; - Set_Addr_To = aXY; - Set_BusB_To = 4'b1010; - Set_BusA_To = 4'b0000; - Read_To_Reg = 1'b1; - Save_ALU = 1'b1; - ALU_Op = 4'b0010; - end - - MCycle[1] : - begin - Set_BusB_To = 4'b0110; - Set_Addr_To = aBC; - if (IR[3] == 1'b0 ) - begin - IncDec_16 = 4'b0110; - end - else - begin - IncDec_16 = 4'b1110; - end - end - - MCycle[2] : - begin - if (IR[3] == 1'b0 ) - begin - IncDec_16 = 4'b0010; - end - else - begin - IncDec_16 = 4'b1010; - end - IORQ = 1'b1; - Write = 1'b1; - I_BTR = 1'b1; - end // case: 3 - - MCycle[3] : - begin - NoRead = 1'b1; - TStates = 3'b101; - end - - default :; - endcase // case(MCycle) - end // case: 8'b10100011 , 8'b10101011 , 8'b10110011 , 8'b10111011 - - endcase // case(IR) - end // block: default_ed_block - endcase // case(ISet) - - if (Mode == 1 ) - begin - if (MCycle[0] ) - begin - //TStates = 3'b100; - end - else - begin - TStates = 3'b011; - end - end - - if (Mode == 3 ) - begin - if (MCycle[0] ) - begin - //TStates = 3'b100; - end - else - begin - TStates = 3'b100; - end - end - - if (Mode < 2 ) - begin - if (MCycle[5] ) - begin - Inc_PC = 1'b1; - if (Mode == 1 ) - begin - Set_Addr_To = aXY; - TStates = 3'b100; - Set_BusB_To[2:0] = SSS; - Set_BusB_To[3] = 1'b0; - end - if (IR == 8'b00110110 || IR == 8'b11001011 ) - begin - Set_Addr_To = aNone; - end - end - if (MCycle[6] ) - begin - if (Mode == 0 ) - begin - TStates = 3'b101; - end - if (ISet != 2'b01 ) - begin - Set_Addr_To = aXY; - end - Set_BusB_To[2:0] = SSS; - Set_BusB_To[3] = 1'b0; - if (IR == 8'b00110110 || ISet == 2'b01 ) - begin - // LD (HL),n - Inc_PC = 1'b1; - end - else - begin - NoRead = 1'b1; - end - end - end // if (Mode < 2 ) - - end // always @ (IR, ISet, MCycle, F, NMICycle, IntCycle) - - // synopsys dc_script_begin - // set_attribute current_design "revision" "$Id: tv80_mcode.v,v 1.6 2005/12/13 19:17:09 ghutchis Exp $" -type string -quiet - // synopsys dc_script_end -endmodule // T80_MCode diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_reg.v b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_reg.v deleted file mode 100644 index 8218407b..00000000 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80_reg.v +++ /dev/null @@ -1,71 +0,0 @@ -// -// TV80 8-Bit Microprocessor Core -// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) -// -// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -module tv80_reg (/*AUTOARG*/ - // Outputs - DOBH, DOAL, DOCL, DOBL, DOCH, DOAH, - // Inputs - AddrC, AddrA, AddrB, DIH, DIL, clk, CEN, WEH, WEL - ); - input [2:0] AddrC; - output [7:0] DOBH; - input [2:0] AddrA; - input [2:0] AddrB; - input [7:0] DIH; - output [7:0] DOAL; - output [7:0] DOCL; - input [7:0] DIL; - output [7:0] DOBL; - output [7:0] DOCH; - output [7:0] DOAH; - input clk, CEN, WEH, WEL; - - reg [7:0] RegsH [0:7]; - reg [7:0] RegsL [0:7]; - - always @(posedge clk) - begin - if (CEN) - begin - if (WEH) RegsH[AddrA] <= DIH; - if (WEL) RegsL[AddrA] <= DIL; - end - end - - assign DOAH = RegsH[AddrA]; - assign DOAL = RegsL[AddrA]; - assign DOBH = RegsH[AddrB]; - assign DOBL = RegsL[AddrB]; - assign DOCH = RegsH[AddrC]; - assign DOCL = RegsL[AddrC]; - - // break out ram bits for waveform debug - wire [7:0] H = RegsH[2]; - wire [7:0] L = RegsL[2]; - -// synopsys dc_script_begin -// set_attribute current_design "revision" "$Id: tv80_reg.v,v 1.1 2004/05/16 17:39:57 ghutchis Exp $" -type string -quiet -// synopsys dc_script_end -endmodule - diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80s.v b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80s.v deleted file mode 100644 index 34269bc7..00000000 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/TV80/tv80s.v +++ /dev/null @@ -1,164 +0,0 @@ -// -// TV80 8-Bit Microprocessor Core -// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org) -// -// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org) -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -//`define TV80_REFRESH - -module tv80s (/*AUTOARG*/ - // Outputs - m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, do, - // Inputs - reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di - ); - - parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - parameter T2Write = 1; // 0 => wr_n active in T3, /=0 => wr_n active in T2 - parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle - - - input reset_n; - input clk; - input wait_n; - input int_n; - input nmi_n; - input busrq_n; - output m1_n; - output mreq_n; - output iorq_n; - output rd_n; - output wr_n; - output rfsh_n; - output halt_n; - output busak_n; - output [15:0] A; - input [7:0] di; - output [7:0] do; - - reg mreq_n; - reg iorq_n; - reg rd_n; - reg wr_n; - - wire cen; - wire intcycle_n; - wire no_read; - wire write; - wire iorq; - reg [7:0] di_reg; - wire [6:0] mcycle; - wire [6:0] tstate; - - assign cen = 1; - - tv80_core #(Mode, IOWait) i_tv80_core - ( - .cen (cen), - .m1_n (m1_n), - .iorq (iorq), - .no_read (no_read), - .write (write), - .rfsh_n (rfsh_n), - .halt_n (halt_n), - .wait_n (wait_n), - .int_n (int_n), - .nmi_n (nmi_n), - .reset_n (reset_n), - .busrq_n (busrq_n), - .busak_n (busak_n), - .clk (clk), - .IntE (), - .stop (), - .A (A), - .dinst (di), - .di (di_reg), - .do (do), - .mc (mcycle), - .ts (tstate), - .intcycle_n (intcycle_n) - ); - - always @(posedge clk) - begin - if (!reset_n) - begin - rd_n <= #1 1'b1; - wr_n <= #1 1'b1; - iorq_n <= #1 1'b1; - mreq_n <= #1 1'b1; - di_reg <= #1 0; - end - else - begin - rd_n <= #1 1'b1; - wr_n <= #1 1'b1; - iorq_n <= #1 1'b1; - mreq_n <= #1 1'b1; - if (mcycle[0]) - begin - if (tstate[1] || (tstate[2] && wait_n == 1'b0)) - begin - rd_n <= #1 ~ intcycle_n; - mreq_n <= #1 ~ intcycle_n; - iorq_n <= #1 intcycle_n; - end - `ifdef TV80_REFRESH - if (tstate[3]) - mreq_n <= #1 1'b0; - `endif - end // if (mcycle[0]) - else - begin - if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && no_read == 1'b0 && write == 1'b0) - begin - rd_n <= #1 1'b0; - iorq_n <= #1 ~ iorq; - mreq_n <= #1 iorq; - end - if (T2Write == 0) - begin - if (tstate[2] && write == 1'b1) - begin - wr_n <= #1 1'b0; - iorq_n <= #1 ~ iorq; - mreq_n <= #1 iorq; - end - end - else - begin - if ((tstate[1] || (tstate[2] && wait_n == 1'b0)) && write == 1'b1) - begin - wr_n <= #1 1'b0; - iorq_n <= #1 ~ iorq; - mreq_n <= #1 iorq; - end - end // else: !if(T2write == 0) - - end // else: !if(mcycle[0]) - - if (tstate[2] && wait_n == 1'b1) - di_reg <= #1 di; - end // else: !if(!reset_n) - end // always @ (posedge clk or negedge reset_n) - -endmodule // t80s - diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/cpucore.v b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/cpucore.v index 0fe9d063..2a2afc5e 100644 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/cpucore.v +++ b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/cpucore.v @@ -28,14 +28,13 @@ wire [7:0] m_di = cs_mrom ? IR : DV ? DI : 8'hFF; assign m_irq = ~IRQ; assign m_nmi = ~NMI; - tv80s core( .mreq_n(m_me), .iorq_n(m_ie), .rd_n(m_rd), .wr_n(m_wr), .A(m_ad), - .do(m_do), + .dout(m_do), .reset_n(~RESET), .clk(CLK), diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/dpram.vhd b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/dpram.vhd deleted file mode 100644 index 665f5ab7..00000000 --- a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/dpram.vhd +++ /dev/null @@ -1,119 +0,0 @@ -LIBRARY ieee; -USE ieee.std_logic_1164.all; - -LIBRARY altera_mf; -USE altera_mf.all; - -ENTITY dpram IS - GENERIC - ( - widthad_a : natural; - width_a : natural := 8 - ); - PORT - ( - address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); - address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); - clock_a : IN STD_LOGIC ; - clock_b : IN STD_LOGIC ; - data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - wren_a : IN STD_LOGIC := '1'; - wren_b : IN STD_LOGIC := '1'; - q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) - ); -END dpram; - - -ARCHITECTURE SYN OF dpram IS - - SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - SIGNAL sub_wire1 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - - COMPONENT altsyncram - GENERIC ( - address_reg_b : STRING; - clock_enable_input_a : STRING; - clock_enable_input_b : STRING; - clock_enable_output_a : STRING; - clock_enable_output_b : STRING; - indata_reg_b : STRING; - init_file : STRING; - intended_device_family : STRING; - lpm_type : STRING; - numwords_a : NATURAL; - numwords_b : NATURAL; - operation_mode : STRING; - outdata_aclr_a : STRING; - outdata_aclr_b : STRING; - outdata_reg_a : STRING; - outdata_reg_b : STRING; - power_up_uninitialized : STRING; - widthad_a : NATURAL; - widthad_b : NATURAL; - width_a : NATURAL; - width_b : NATURAL; - width_byteena_a : NATURAL; - width_byteena_b : NATURAL; - wrcontrol_wraddress_reg_b : STRING - ); - PORT ( - wren_a : IN STD_LOGIC ; - clock0 : IN STD_LOGIC ; - wren_b : IN STD_LOGIC ; - clock1 : IN STD_LOGIC ; - address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); - address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0); - q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0); - data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) - ); - END COMPONENT; - -BEGIN - q_a <= sub_wire0(width_a-1 DOWNTO 0); - q_b <= sub_wire1(width_a-1 DOWNTO 0); - - altsyncram_component : altsyncram - GENERIC MAP ( - address_reg_b => "CLOCK1", - clock_enable_input_a => "BYPASS", - clock_enable_input_b => "BYPASS", - clock_enable_output_a => "BYPASS", - clock_enable_output_b => "BYPASS", - indata_reg_b => "CLOCK1", - init_file => "", - intended_device_family => "Cyclone III", - lpm_type => "altsyncram", - numwords_a => 2**widthad_a, - numwords_b => 2**widthad_a, - operation_mode => "BIDIR_DUAL_PORT", - outdata_aclr_a => "NONE", - outdata_aclr_b => "NONE", - outdata_reg_a => "UNREGISTERED", - outdata_reg_b => "UNREGISTERED", - power_up_uninitialized => "FALSE", - widthad_a => widthad_a, - widthad_b => widthad_a, - width_a => width_a, - width_b => width_a, - width_byteena_a => 1, - width_byteena_b => 1, - wrcontrol_wraddress_reg_b => "CLOCK1" - ) - PORT MAP ( - wren_a => wren_a, - clock0 => clock_a, - wren_b => wren_b, - clock1 => clock_b, - address_a => address_a, - address_b => address_b, - data_a => data_a, - data_b => data_b, - q_a => sub_wire0, - q_b => sub_wire1 - ); - -END SYN; diff --git a/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/sdram.sv b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/sdram.sv new file mode 100644 index 00000000..8f927d05 --- /dev/null +++ b/Arcade_MiST/Galaga Hardware/DigDug_MiST/rtl/sdram.sv @@ -0,0 +1,254 @@ +// +// sdram.v +// +// Static RAM controller implementation using SDRAM MT48LC16M16A2 +// +// Copyright (c) 2015,2016 Sorgelig +// +// Some parts of SDRAM code used from project: +// http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ------------------------------------------ +// +// v2.1 - Add universal 8/16 bit mode. +// + +module sdram +( + input init, // reset to initialize RAM + input clk, // clock ~100MHz + // + // SDRAM_* - signals to the MT48LC16M16 chip + inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus + output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus + output reg SDRAM_DQML, // two byte masks + output reg SDRAM_DQMH, // + output reg [1:0] SDRAM_BA, // two banks + output SDRAM_nCS, // a single chip select + output SDRAM_nWE, // write enable + output SDRAM_nRAS, // row address select + output SDRAM_nCAS, // columns address select + output SDRAM_CKE, // clock enable + // + input [1:0] wtbt, // 16bit mode: bit1 - write high byte, bit0 - write low byte, + // 8bit mode: 2'b00 - use addr[0] to decide which byte to write + // Ignored while reading. + // + input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations. + output [15:0] dout, // data output to cpu + input [15:0] din, // data input from cpu + input we, // cpu requests write + input rd, // cpu requests read + output reg ready // dout is valid. Ready to accept new read/write. +); + +assign SDRAM_nCS = command[3]; +assign SDRAM_nRAS = command[2]; +assign SDRAM_nCAS = command[1]; +assign SDRAM_nWE = command[0]; +assign SDRAM_CKE = cke; + +// no burst configured +localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8 +localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved +localparam CAS_LATENCY = 3'd2; // 2 for < 100MHz, 3 for >100MHz +localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed +localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write +localparam MODE = {3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; + +localparam sdram_startup_cycles= 14'd12100;// 100us, plus a little more, @ 100MHz +localparam cycles_per_refresh = 14'd186; // (64000*36)/8192-1 Calc'd as (64ms @ 36MHz)/8192 rose +localparam startup_refresh_max = 14'b11111111111111; + +// SDRAM commands +localparam CMD_INHIBIT = 4'b1111; +localparam CMD_NOP = 4'b0111; +localparam CMD_ACTIVE = 4'b0011; +localparam CMD_READ = 4'b0101; +localparam CMD_WRITE = 4'b0100; +localparam CMD_BURST_TERMINATE = 4'b0110; +localparam CMD_PRECHARGE = 4'b0010; +localparam CMD_AUTO_REFRESH = 4'b0001; +localparam CMD_LOAD_MODE = 4'b0000; + +reg [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles; +reg [3:0] command = CMD_INHIBIT; +reg cke = 0; +reg [24:0] save_addr; +reg [15:0] data; + +assign dout = save_addr[0] ? {data[7:0], data[15:8]} : {data[15:8], data[7:0]}; +typedef enum +{ + STATE_STARTUP, + STATE_OPEN_1, + STATE_WRITE, + STATE_READ, + STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3, + STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7 +} state_t; + +state_t state = STATE_STARTUP; + +always @(posedge clk) begin + reg old_we, old_rd; + reg [CAS_LATENCY:0] data_ready_delay; + + reg [15:0] new_data; + reg [1:0] new_wtbt; + reg new_we; + reg new_rd; + reg save_we = 1; + + + command <= CMD_NOP; + refresh_count <= refresh_count+1'b1; + + data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]}; + + if(data_ready_delay[0]) data <= SDRAM_DQ; + + case(state) + STATE_STARTUP: begin + //------------------------------------------------------------------------ + //-- This is the initial startup state, where we wait for at least 100us + //-- before starting the start sequence + //-- + //-- The initialisation is sequence is + //-- * de-assert SDRAM_CKE + //-- * 100us wait, + //-- * assert SDRAM_CKE + //-- * wait at least one cycle, + //-- * PRECHARGE + //-- * wait 2 cycles + //-- * REFRESH, + //-- * tREF wait + //-- * REFRESH, + //-- * tREF wait + //-- * LOAD_MODE_REG + //-- * 2 cycles wait + //------------------------------------------------------------------------ + cke <= 1; + SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; + SDRAM_DQML <= 1; + SDRAM_DQMH <= 1; + SDRAM_A <= 0; + SDRAM_BA <= 0; + + // All the commands during the startup are NOPS, except these + if(refresh_count == startup_refresh_max-31) begin + // ensure all rows are closed + command <= CMD_PRECHARGE; + SDRAM_A[10] <= 1; // all banks + SDRAM_BA <= 2'b00; + end else if (refresh_count == startup_refresh_max-23) begin + // these refreshes need to be at least tREF (66ns) apart + command <= CMD_AUTO_REFRESH; + end else if (refresh_count == startup_refresh_max-15) + command <= CMD_AUTO_REFRESH; + else if (refresh_count == startup_refresh_max-7) begin + // Now load the mode register + command <= CMD_LOAD_MODE; + SDRAM_A <= MODE; + end + + //------------------------------------------------------ + //-- if startup is complete then go into idle mode, + //-- get prepared to accept a new command, and schedule + //-- the first refresh cycle + //------------------------------------------------------ + if(!refresh_count) begin + state <= STATE_IDLE; + ready <= 1; + refresh_count <= 0; + end + end + + STATE_IDLE_7: state <= STATE_IDLE_6; + STATE_IDLE_6: state <= STATE_IDLE_5; + STATE_IDLE_5: state <= STATE_IDLE_4; + STATE_IDLE_4: state <= STATE_IDLE_3; + STATE_IDLE_3: state <= STATE_IDLE_2; + STATE_IDLE_2: state <= STATE_IDLE_1; + STATE_IDLE_1: begin + SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; + state <= STATE_IDLE; + // mask possible refresh to reduce colliding. + if(refresh_count > cycles_per_refresh) begin + //------------------------------------------------------------------------ + //-- Start the refresh cycle. + //-- This tasks tRFC (66ns), so 2 idle cycles are needed @ 36MHz + //------------------------------------------------------------------------ + state <= STATE_IDLE_2; + command <= CMD_AUTO_REFRESH; + refresh_count <= refresh_count - cycles_per_refresh + 1'd1; + end + end + + STATE_IDLE: begin + // Priority is to issue a refresh if one is outstanding + if(refresh_count > (cycles_per_refresh<<1)) state <= STATE_IDLE_1; + else if(new_rd | new_we) begin + new_we <= 0; + new_rd <= 0; + save_addr<= addr; + save_we <= new_we; + state <= STATE_OPEN_1; + command <= CMD_ACTIVE; + SDRAM_A <= addr[13:1]; + SDRAM_BA <= addr[24:23]; + end + end + + // ACTIVE-to-READ or WRITE delay >20ns (1 cycle @ 36 MHz)(-75) + STATE_OPEN_1: begin + SDRAM_A <= {4'b0010, save_addr[22:14]}; + SDRAM_DQML <= save_we & (new_wtbt ? ~new_wtbt[0] : save_addr[0]); + SDRAM_DQMH <= save_we & (new_wtbt ? ~new_wtbt[1] : ~save_addr[0]); + state <= save_we ? STATE_WRITE : STATE_READ; + end + + STATE_READ: begin + state <= STATE_IDLE_5; + command <= CMD_READ; + SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; + + // Schedule reading the data values off the bus + data_ready_delay[CAS_LATENCY] <= 1; + end + + STATE_WRITE: begin + state <= STATE_IDLE_5; + command <= CMD_WRITE; + SDRAM_DQ <= new_wtbt ? new_data : {new_data[7:0], new_data[7:0]}; + ready <= 1; + end + endcase + + if(init) begin + state <= STATE_STARTUP; + refresh_count <= startup_refresh_max - sdram_startup_cycles; + end + + old_we <= we; + old_rd <= rd; + if(we & ~old_we) {ready, new_we, new_data, new_wtbt} <= {1'b0, 1'b1, din, wtbt}; + else + if((rd & ~old_rd) || (rd & old_rd & (save_addr != addr))) {ready, new_rd} <= {1'b0, 1'b1}; + +end + +endmodule diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/Galaga_MiST.qsf b/Arcade_MiST/Galaga Hardware/Galaga_MiST/Galaga_MiST.qsf index c9d80a1b..15c896f9 100644 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/Galaga_MiST.qsf +++ b/Arcade_MiST/Galaga Hardware/Galaga_MiST/Galaga_MiST.qsf @@ -198,7 +198,6 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top # end ENTITY(galaga_mist) # ----------------------- set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top set_global_assignment -name SYSTEMVERILOG_FILE rtl/galaga_mist.sv set_global_assignment -name VHDL_FILE rtl/galaga.vhd set_global_assignment -name VHDL_FILE rtl/gen_video.vhd @@ -219,11 +218,7 @@ set_global_assignment -name VHDL_FILE rtl/roms/galaga_cpu1.vhd set_global_assignment -name VHDL_FILE rtl/roms/bg_palette.vhd set_global_assignment -name VHDL_FILE rtl/roms/bg_graphx.vhd set_global_assignment -name VHDL_FILE rtl/roms/cs54xx_prog.vhd -set_global_assignment -name VHDL_FILE rtl/T80/T80se.vhd -set_global_assignment -name VHDL_FILE rtl/T80/T80_Reg.vhd -set_global_assignment -name VHDL_FILE rtl/T80/T80_Pack.vhd -set_global_assignment -name VHDL_FILE rtl/T80/T80_MCode.vhd -set_global_assignment -name VHDL_FILE rtl/T80/T80_ALU.vhd -set_global_assignment -name VHDL_FILE rtl/T80/T80.vhd set_global_assignment -name VERILOG_FILE rtl/pll.v -set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip \ No newline at end of file +set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip +set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80.vhd b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80.vhd deleted file mode 100644 index 398fa0df..00000000 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80.vhd +++ /dev/null @@ -1,1073 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0247 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- 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 --- 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/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0210 : Fixed wait and halt --- --- 0211 : Fixed Refresh addition and IM 1 --- --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- --- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson --- --- 0235 : Added clock enable and IM 2 fix by Mike Johnson --- --- 0237 : Changed 8080 I/O address output, added IntE output --- --- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag --- --- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode --- --- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM --- --- 0247 : Fixed bus req/ack cycle --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80 is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - IORQ : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DInst : in std_logic_vector(7 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - MC : out std_logic_vector(2 downto 0); - TS : out std_logic_vector(2 downto 0); - IntCycle_n : out std_logic; - IntE : out std_logic; - Stop : out std_logic - ); -end T80; - -architecture rtl of T80 is - - constant aNone : std_logic_vector(2 downto 0) := "111"; - constant aBC : std_logic_vector(2 downto 0) := "000"; - constant aDE : std_logic_vector(2 downto 0) := "001"; - constant aXY : std_logic_vector(2 downto 0) := "010"; - constant aIOA : std_logic_vector(2 downto 0) := "100"; - constant aSP : std_logic_vector(2 downto 0) := "101"; - constant aZI : std_logic_vector(2 downto 0) := "110"; - - -- Registers - signal ACC, F : std_logic_vector(7 downto 0); - signal Ap, Fp : std_logic_vector(7 downto 0); - signal I : std_logic_vector(7 downto 0); - signal R : unsigned(7 downto 0); - signal SP, PC : unsigned(15 downto 0); - signal RegDIH : std_logic_vector(7 downto 0); - signal RegDIL : std_logic_vector(7 downto 0); - signal RegBusA : std_logic_vector(15 downto 0); - signal RegBusB : std_logic_vector(15 downto 0); - signal RegBusC : std_logic_vector(15 downto 0); - signal RegAddrA_r : std_logic_vector(2 downto 0); - signal RegAddrA : std_logic_vector(2 downto 0); - signal RegAddrB_r : std_logic_vector(2 downto 0); - signal RegAddrB : std_logic_vector(2 downto 0); - signal RegAddrC : std_logic_vector(2 downto 0); - signal RegWEH : std_logic; - signal RegWEL : std_logic; - signal Alternate : std_logic; - - -- Help Registers - signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register - signal IR : std_logic_vector(7 downto 0); -- Instruction register - signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector - signal RegBusA_r : std_logic_vector(15 downto 0); - - signal ID16 : signed(15 downto 0); - signal Save_Mux : std_logic_vector(7 downto 0); - - signal TState : unsigned(2 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal IntE_FF1 : std_logic; - signal IntE_FF2 : std_logic; - signal Halt_FF : std_logic; - signal BusReq_s : std_logic; - signal BusAck : std_logic; - signal ClkEn : std_logic; - signal NMI_s : std_logic; - signal INT_s : std_logic; - signal IStatus : std_logic_vector(1 downto 0); - - signal DI_Reg : std_logic_vector(7 downto 0); - signal T_Res : std_logic; - signal XY_State : std_logic_vector(1 downto 0); - signal Pre_XY_F_M : std_logic_vector(2 downto 0); - signal NextIs_XY_Fetch : std_logic; - signal XY_Ind : std_logic; - signal No_BTR : std_logic; - signal BTR_r : std_logic; - signal Auto_Wait : std_logic; - signal Auto_Wait_t1 : std_logic; - signal Auto_Wait_t2 : std_logic; - signal IncDecZ : std_logic; - - -- ALU signals - signal BusB : std_logic_vector(7 downto 0); - signal BusA : std_logic_vector(7 downto 0); - signal ALU_Q : std_logic_vector(7 downto 0); - signal F_Out : std_logic_vector(7 downto 0); - - -- Registered micro code outputs - signal Read_To_Reg_r : std_logic_vector(4 downto 0); - signal Arith16_r : std_logic; - signal Z16_r : std_logic; - signal ALU_Op_r : std_logic_vector(3 downto 0); - signal Save_ALU_r : std_logic; - signal PreserveC_r : std_logic; - signal MCycles : std_logic_vector(2 downto 0); - - -- Micro code outputs - signal MCycles_d : std_logic_vector(2 downto 0); - signal TStates : std_logic_vector(2 downto 0); - signal IntCycle : std_logic; - signal NMICycle : std_logic; - signal Inc_PC : std_logic; - signal Inc_WZ : std_logic; - signal IncDec_16 : std_logic_vector(3 downto 0); - signal Prefix : std_logic_vector(1 downto 0); - signal Read_To_Acc : std_logic; - signal Read_To_Reg : std_logic; - signal Set_BusB_To : std_logic_vector(3 downto 0); - signal Set_BusA_To : std_logic_vector(3 downto 0); - signal ALU_Op : std_logic_vector(3 downto 0); - signal Save_ALU : std_logic; - signal PreserveC : std_logic; - signal Arith16 : std_logic; - signal Set_Addr_To : std_logic_vector(2 downto 0); - signal Jump : std_logic; - signal JumpE : std_logic; - signal JumpXY : std_logic; - signal Call : std_logic; - signal RstP : std_logic; - signal LDZ : std_logic; - signal LDW : std_logic; - signal LDSPHL : std_logic; - signal IORQ_i : std_logic; - signal Special_LD : std_logic_vector(2 downto 0); - signal ExchangeDH : std_logic; - signal ExchangeRp : std_logic; - signal ExchangeAF : std_logic; - signal ExchangeRS : std_logic; - signal I_DJNZ : std_logic; - signal I_CPL : std_logic; - signal I_CCF : std_logic; - signal I_SCF : std_logic; - signal I_RETN : std_logic; - signal I_BT : std_logic; - signal I_BC : std_logic; - signal I_BTR : std_logic; - signal I_RLD : std_logic; - signal I_RRD : std_logic; - signal I_INRC : std_logic; - signal SetDI : std_logic; - signal SetEI : std_logic; - signal IMode : std_logic_vector(1 downto 0); - signal Halt : std_logic; - -begin - - mcode : T80_MCode - generic map( - Mode => Mode, - Flag_C => Flag_C, - Flag_N => Flag_N, - Flag_P => Flag_P, - Flag_X => Flag_X, - Flag_H => Flag_H, - Flag_Y => Flag_Y, - Flag_Z => Flag_Z, - Flag_S => Flag_S) - port map( - IR => IR, - ISet => ISet, - MCycle => MCycle, - F => F, - NMICycle => NMICycle, - IntCycle => IntCycle, - MCycles => MCycles_d, - TStates => TStates, - Prefix => Prefix, - Inc_PC => Inc_PC, - Inc_WZ => Inc_WZ, - IncDec_16 => IncDec_16, - Read_To_Acc => Read_To_Acc, - Read_To_Reg => Read_To_Reg, - Set_BusB_To => Set_BusB_To, - Set_BusA_To => Set_BusA_To, - ALU_Op => ALU_Op, - Save_ALU => Save_ALU, - PreserveC => PreserveC, - Arith16 => Arith16, - Set_Addr_To => Set_Addr_To, - IORQ => IORQ_i, - Jump => Jump, - JumpE => JumpE, - JumpXY => JumpXY, - Call => Call, - RstP => RstP, - LDZ => LDZ, - LDW => LDW, - LDSPHL => LDSPHL, - Special_LD => Special_LD, - ExchangeDH => ExchangeDH, - ExchangeRp => ExchangeRp, - ExchangeAF => ExchangeAF, - ExchangeRS => ExchangeRS, - I_DJNZ => I_DJNZ, - I_CPL => I_CPL, - I_CCF => I_CCF, - I_SCF => I_SCF, - I_RETN => I_RETN, - I_BT => I_BT, - I_BC => I_BC, - I_BTR => I_BTR, - I_RLD => I_RLD, - I_RRD => I_RRD, - I_INRC => I_INRC, - SetDI => SetDI, - SetEI => SetEI, - IMode => IMode, - Halt => Halt, - NoRead => NoRead, - Write => Write); - - alu : T80_ALU - generic map( - Mode => Mode, - Flag_C => Flag_C, - Flag_N => Flag_N, - Flag_P => Flag_P, - Flag_X => Flag_X, - Flag_H => Flag_H, - Flag_Y => Flag_Y, - Flag_Z => Flag_Z, - Flag_S => Flag_S) - port map( - Arith16 => Arith16_r, - Z16 => Z16_r, - ALU_Op => ALU_Op_r, - IR => IR(5 downto 0), - ISet => ISet, - BusA => BusA, - BusB => BusB, - F_In => F, - Q => ALU_Q, - F_Out => F_Out); - - ClkEn <= CEN and not BusAck; - - T_Res <= '1' when TState = unsigned(TStates) else '0'; - - NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and - ((Set_Addr_To = aXY) or - (MCycle = "001" and IR = "11001011") or - (MCycle = "001" and IR = "00110110")) else '0'; - - Save_Mux <= BusB when ExchangeRp = '1' else - DI_Reg when Save_ALU_r = '0' else - ALU_Q; - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - PC <= (others => '0'); -- Program Counter - A <= (others => '0'); - TmpAddr <= (others => '0'); - IR <= "00000000"; - ISet <= "00"; - XY_State <= "00"; - IStatus <= "00"; - MCycles <= "000"; - DO <= "00000000"; - - ACC <= (others => '1'); - F <= (others => '1'); - Ap <= (others => '1'); - Fp <= (others => '1'); - I <= (others => '0'); - R <= (others => '0'); - SP <= (others => '1'); - Alternate <= '0'; - - Read_To_Reg_r <= "00000"; - F <= (others => '1'); - Arith16_r <= '0'; - BTR_r <= '0'; - Z16_r <= '0'; - ALU_Op_r <= "0000"; - Save_ALU_r <= '0'; - PreserveC_r <= '0'; - XY_Ind <= '0'; - - elsif CLK_n'event and CLK_n = '1' then - - if ClkEn = '1' then - - ALU_Op_r <= "0000"; - Save_ALU_r <= '0'; - Read_To_Reg_r <= "00000"; - - MCycles <= MCycles_d; - - if IMode /= "11" then - IStatus <= IMode; - end if; - - Arith16_r <= Arith16; - PreserveC_r <= PreserveC; - if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then - Z16_r <= '1'; - else - Z16_r <= '0'; - end if; - - if MCycle = "001" and TState(2) = '0' then - -- MCycle = 1 and TState = 1, 2, or 3 - - if TState = 2 and Wait_n = '1' then - if Mode < 2 then - A(7 downto 0) <= std_logic_vector(R); - A(15 downto 8) <= I; - R(6 downto 0) <= R(6 downto 0) + 1; - end if; - - if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then - PC <= PC + 1; - end if; - - if IntCycle = '1' and IStatus = "01" then - IR <= "11111111"; - elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then - IR <= "00000000"; - else - IR <= DInst; - end if; - - ISet <= "00"; - if Prefix /= "00" then - if Prefix = "11" then - if IR(5) = '1' then - XY_State <= "10"; - else - XY_State <= "01"; - end if; - else - if Prefix = "10" then - XY_State <= "00"; - XY_Ind <= '0'; - end if; - ISet <= Prefix; - end if; - else - XY_State <= "00"; - XY_Ind <= '0'; - end if; - end if; - - else - -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) - - if MCycle = "110" then - XY_Ind <= '1'; - if Prefix = "01" then - ISet <= "01"; - end if; - end if; - - if T_Res = '1' then - BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; - if Jump = '1' then - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= TmpAddr(7 downto 0); - PC(15 downto 8) <= unsigned(DI_Reg); - PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); - elsif JumpXY = '1' then - A <= RegBusC; - PC <= unsigned(RegBusC); - elsif Call = '1' or RstP = '1' then - A <= TmpAddr; - PC <= unsigned(TmpAddr); - elsif MCycle = MCycles and NMICycle = '1' then - A <= "0000000001100110"; - PC <= "0000000001100110"; - elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then - A(15 downto 8) <= I; - A(7 downto 0) <= TmpAddr(7 downto 0); - PC(15 downto 8) <= unsigned(I); - PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); - else - case Set_Addr_To is - when aXY => - if XY_State = "00" then - A <= RegBusC; - else - if NextIs_XY_Fetch = '1' then - A <= std_logic_vector(PC); - else - A <= TmpAddr; - end if; - end if; - when aIOA => - if Mode = 3 then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - elsif Mode = 2 then - -- Duplicate I/O address on 8080 - A(15 downto 8) <= DI_Reg; - else - A(15 downto 8) <= ACC; - end if; - A(7 downto 0) <= DI_Reg; - when aSP => - A <= std_logic_vector(SP); - when aBC => - if Mode = 3 and IORQ_i = '1' then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - A(7 downto 0) <= RegBusC(7 downto 0); - else - A <= RegBusC; - end if; - when aDE => - A <= RegBusC; - when aZI => - if Inc_WZ = '1' then - A <= std_logic_vector(unsigned(TmpAddr) + 1); - else - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= TmpAddr(7 downto 0); - end if; - when others => - A <= std_logic_vector(PC); - end case; - end if; - - Save_ALU_r <= Save_ALU; - ALU_Op_r <= ALU_Op; - - if I_CPL = '1' then - -- CPL - ACC <= not ACC; - F(Flag_Y) <= not ACC(5); - F(Flag_H) <= '1'; - F(Flag_X) <= not ACC(3); - F(Flag_N) <= '1'; - end if; - if I_CCF = '1' then - -- CCF - F(Flag_C) <= not F(Flag_C); - F(Flag_Y) <= ACC(5); - F(Flag_H) <= F(Flag_C); - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - if I_SCF = '1' then - -- SCF - F(Flag_C) <= '1'; - F(Flag_Y) <= ACC(5); - F(Flag_H) <= '0'; - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - end if; - - if TState = 2 and Wait_n = '1' then - if ISet = "01" and MCycle = "111" then - IR <= DInst; - end if; - if JumpE = '1' then - PC <= unsigned(signed(PC) + signed(DI_Reg)); - elsif Inc_PC = '1' then - PC <= PC + 1; - end if; - if BTR_r = '1' then - PC <= PC - 2; - end if; - if RstP = '1' then - TmpAddr <= (others =>'0'); - TmpAddr(5 downto 3) <= IR(5 downto 3); - end if; - end if; - if TState = 3 and MCycle = "110" then - TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); - end if; - - if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then - if IncDec_16(2 downto 0) = "111" then - if IncDec_16(3) = '1' then - SP <= SP - 1; - else - SP <= SP + 1; - end if; - end if; - end if; - - if LDSPHL = '1' then - SP <= unsigned(RegBusC); - end if; - if ExchangeAF = '1' then - Ap <= ACC; - ACC <= Ap; - Fp <= F; - F <= Fp; - end if; - if ExchangeRS = '1' then - Alternate <= not Alternate; - end if; - end if; - - if TState = 3 then - if LDZ = '1' then - TmpAddr(7 downto 0) <= DI_Reg; - end if; - if LDW = '1' then - TmpAddr(15 downto 8) <= DI_Reg; - end if; - - if Special_LD(2) = '1' then - case Special_LD(1 downto 0) is - when "00" => - ACC <= I; - F(Flag_P) <= IntE_FF2; - when "01" => - ACC <= std_logic_vector(R); - F(Flag_P) <= IntE_FF2; - when "10" => - I <= ACC; - when others => - R <= unsigned(ACC); - end case; - end if; - end if; - - if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then - if Mode = 3 then - F(6) <= F_Out(6); - F(5) <= F_Out(5); - F(7) <= F_Out(7); - if PreserveC_r = '0' then - F(4) <= F_Out(4); - end if; - else - F(7 downto 1) <= F_Out(7 downto 1); - if PreserveC_r = '0' then - F(Flag_C) <= F_Out(0); - end if; - end if; - end if; - if T_Res = '1' and I_INRC = '1' then - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - if DI_Reg(7 downto 0) = "00000000" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; - end if; - F(Flag_S) <= DI_Reg(7); - F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor - DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); - end if; - - if TState = 1 and Auto_Wait_t1 = '0' then - DO <= BusB; - if I_RLD = '1' then - DO(3 downto 0) <= BusA(3 downto 0); - DO(7 downto 4) <= BusB(3 downto 0); - end if; - if I_RRD = '1' then - DO(3 downto 0) <= BusB(7 downto 4); - DO(7 downto 4) <= BusA(3 downto 0); - end if; - end if; - - if T_Res = '1' then - Read_To_Reg_r(3 downto 0) <= Set_BusA_To; - Read_To_Reg_r(4) <= Read_To_Reg; - if Read_To_Acc = '1' then - Read_To_Reg_r(3 downto 0) <= "0111"; - Read_To_Reg_r(4) <= '1'; - end if; - end if; - - if TState = 1 and I_BT = '1' then - F(Flag_X) <= ALU_Q(3); - F(Flag_Y) <= ALU_Q(1); - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - end if; - if I_BC = '1' or I_BT = '1' then - F(Flag_P) <= IncDecZ; - end if; - - if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or - (Save_ALU_r = '1' and ALU_OP_r /= "0111") then - case Read_To_Reg_r is - when "10111" => - ACC <= Save_Mux; - when "10110" => - DO <= Save_Mux; - when "11000" => - SP(7 downto 0) <= unsigned(Save_Mux); - when "11001" => - SP(15 downto 8) <= unsigned(Save_Mux); - when "11011" => - F <= Save_Mux; - when others => - end case; - end if; - - end if; - - end if; - - end process; - ---------------------------------------------------------------------------- --- --- BC('), DE('), HL('), IX and IY --- ---------------------------------------------------------------------------- - process (CLK_n) - begin - if CLK_n'event and CLK_n = '1' then - if ClkEn = '1' then - -- Bus A / Write - RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); - if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then - RegAddrA_r <= XY_State(1) & "11"; - end if; - - -- Bus B - RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); - if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then - RegAddrB_r <= XY_State(1) & "11"; - end if; - - -- Address from register - RegAddrC <= Alternate & Set_Addr_To(1 downto 0); - -- Jump (HL), LD SP,HL - if (JumpXY = '1' or LDSPHL = '1') then - RegAddrC <= Alternate & "10"; - end if; - if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then - RegAddrC <= XY_State(1) & "11"; - end if; - - if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then - IncDecZ <= F_Out(Flag_Z); - end if; - if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then - if ID16 = 0 then - IncDecZ <= '0'; - else - IncDecZ <= '1'; - end if; - end if; - - RegBusA_r <= RegBusA; - end if; - end if; - end process; - - RegAddrA <= - -- 16 bit increment/decrement - Alternate & IncDec_16(1 downto 0) when (TState = 2 or - (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else - XY_State(1) & "11" when (TState = 2 or - (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else - -- EX HL,DL - Alternate & "10" when ExchangeDH = '1' and TState = 3 else - Alternate & "01" when ExchangeDH = '1' and TState = 4 else - -- Bus A / Write - RegAddrA_r; - - RegAddrB <= - -- EX HL,DL - Alternate & "01" when ExchangeDH = '1' and TState = 3 else - -- Bus B - RegAddrB_r; - - ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else - signed(RegBusA) + 1; - - process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) - begin - RegWEH <= '0'; - RegWEL <= '0'; - if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or - (Save_ALU_r = '1' and ALU_OP_r /= "0111") then - case Read_To_Reg_r is - when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => - RegWEH <= not Read_To_Reg_r(0); - RegWEL <= Read_To_Reg_r(0); - when others => - end case; - end if; - - if ExchangeDH = '1' and (TState = 3 or TState = 4) then - RegWEH <= '1'; - RegWEL <= '1'; - end if; - - if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then - case IncDec_16(1 downto 0) is - when "00" | "01" | "10" => - RegWEH <= '1'; - RegWEL <= '1'; - when others => - end case; - end if; - end process; - - process (Save_Mux, RegBusB, RegBusA_r, ID16, - ExchangeDH, IncDec_16, MCycle, TState, Wait_n) - begin - RegDIH <= Save_Mux; - RegDIL <= Save_Mux; - - if ExchangeDH = '1' and TState = 3 then - RegDIH <= RegBusB(15 downto 8); - RegDIL <= RegBusB(7 downto 0); - end if; - if ExchangeDH = '1' and TState = 4 then - RegDIH <= RegBusA_r(15 downto 8); - RegDIL <= RegBusA_r(7 downto 0); - end if; - - if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then - RegDIH <= std_logic_vector(ID16(15 downto 8)); - RegDIL <= std_logic_vector(ID16(7 downto 0)); - end if; - end process; - - Regs : T80_Reg - port map( - Clk => CLK_n, - CEN => ClkEn, - WEH => RegWEH, - WEL => RegWEL, - AddrA => RegAddrA, - AddrB => RegAddrB, - AddrC => RegAddrC, - DIH => RegDIH, - DIL => RegDIL, - DOAH => RegBusA(15 downto 8), - DOAL => RegBusA(7 downto 0), - DOBH => RegBusB(15 downto 8), - DOBL => RegBusB(7 downto 0), - DOCH => RegBusC(15 downto 8), - DOCL => RegBusC(7 downto 0)); - ---------------------------------------------------------------------------- --- --- Buses --- ---------------------------------------------------------------------------- - process (CLK_n) - begin - if CLK_n'event and CLK_n = '1' then - if ClkEn = '1' then - case Set_BusB_To is - when "0111" => - BusB <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusB_To(0) = '1' then - BusB <= RegBusB(7 downto 0); - else - BusB <= RegBusB(15 downto 8); - end if; - when "0110" => - BusB <= DI_Reg; - when "1000" => - BusB <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusB <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusB <= "00000001"; - when "1011" => - BusB <= F; - when "1100" => - BusB <= std_logic_vector(PC(7 downto 0)); - when "1101" => - BusB <= std_logic_vector(PC(15 downto 8)); - when "1110" => - BusB <= "00000000"; - when others => - BusB <= "--------"; - end case; - - case Set_BusA_To is - when "0111" => - BusA <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusA_To(0) = '1' then - BusA <= RegBusA(7 downto 0); - else - BusA <= RegBusA(15 downto 8); - end if; - when "0110" => - BusA <= DI_Reg; - when "1000" => - BusA <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusA <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusA <= "00000000"; - when others => - BusB <= "--------"; - end case; - end if; - end if; - end process; - ---------------------------------------------------------------------------- --- --- Generate external control signals --- ---------------------------------------------------------------------------- - process (RESET_n,CLK_n) - begin - if RESET_n = '0' then - RFSH_n <= '1'; - elsif CLK_n'event and CLK_n = '1' then - if CEN = '1' then - if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then - RFSH_n <= '0'; - else - RFSH_n <= '1'; - end if; - end if; - end if; - end process; - - MC <= std_logic_vector(MCycle); - TS <= std_logic_vector(TState); - DI_Reg <= DI; - HALT_n <= not Halt_FF; - BUSAK_n <= not BusAck; - IntCycle_n <= not IntCycle; - IntE <= IntE_FF1; - IORQ <= IORQ_i; - Stop <= I_DJNZ; - -------------------------------------------------------------------------- --- --- Syncronise inputs --- -------------------------------------------------------------------------- - process (RESET_n, CLK_n) - variable OldNMI_n : std_logic; - begin - if RESET_n = '0' then - BusReq_s <= '0'; - INT_s <= '0'; - NMI_s <= '0'; - OldNMI_n := '0'; - elsif CLK_n'event and CLK_n = '1' then - if CEN = '1' then - BusReq_s <= not BUSRQ_n; - INT_s <= not INT_n; - if NMICycle = '1' then - NMI_s <= '0'; - elsif NMI_n = '0' and OldNMI_n = '1' then - NMI_s <= '1'; - end if; - OldNMI_n := NMI_n; - end if; - end if; - end process; - -------------------------------------------------------------------------- --- --- Main state machine --- -------------------------------------------------------------------------- - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - MCycle <= "001"; - TState <= "000"; - Pre_XY_F_M <= "000"; - Halt_FF <= '0'; - BusAck <= '0'; - NMICycle <= '0'; - IntCycle <= '0'; - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - No_BTR <= '0'; - Auto_Wait_t1 <= '0'; - Auto_Wait_t2 <= '0'; - M1_n <= '1'; - elsif CLK_n'event and CLK_n = '1' then - if CEN = '1' then - if T_Res = '1' then - Auto_Wait_t1 <= '0'; - else - Auto_Wait_t1 <= Auto_Wait or IORQ_i; - end if; - Auto_Wait_t2 <= Auto_Wait_t1; - No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or - (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or - (I_BTR and (not IR(4) or F(Flag_Z))); - if TState = 2 then - if SetEI = '1' then - IntE_FF1 <= '1'; - IntE_FF2 <= '1'; - end if; - if I_RETN = '1' then - IntE_FF1 <= IntE_FF2; - end if; - end if; - if TState = 3 then - if SetDI = '1' then - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - end if; - end if; - if IntCycle = '1' or NMICycle = '1' then - Halt_FF <= '0'; - end if; - if MCycle = "001" and TState = 2 and Wait_n = '1' then - M1_n <= '1'; - end if; - if BusReq_s = '1' and BusAck = '1' then - else - BusAck <= '0'; - if TState = 2 and Wait_n = '0' then - elsif T_Res = '1' then - if Halt = '1' then - Halt_FF <= '1'; - end if; - if BusReq_s = '1' then - BusAck <= '1'; - else - TState <= "001"; - if NextIs_XY_Fetch = '1' then - MCycle <= "110"; - Pre_XY_F_M <= MCycle; - if IR = "00110110" and Mode = 0 then - Pre_XY_F_M <= "010"; - end if; - elsif (MCycle = "111") or - (MCycle = "110" and Mode = 1 and ISet /= "01") then - MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); - elsif (MCycle = MCycles) or - No_BTR = '1' or - (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then - M1_n <= '0'; - MCycle <= "001"; - IntCycle <= '0'; - NMICycle <= '0'; - if NMI_s = '1' and Prefix = "00" then - NMICycle <= '1'; - IntE_FF1 <= '0'; - elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then - IntCycle <= '1'; - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - end if; - else - MCycle <= std_logic_vector(unsigned(MCycle) + 1); - end if; - end if; - else - if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor - (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then - TState <= TState + 1; - end if; - end if; - end if; - if TState = 0 then - M1_n <= '0'; - end if; - end if; - end if; - end process; - - process (IntCycle, NMICycle, MCycle) - begin - Auto_Wait <= '0'; - if IntCycle = '1' or NMICycle = '1' then - if MCycle = "001" then - Auto_Wait <= '1'; - end if; - end if; - end process; - -end; diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_ALU.vhd b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_ALU.vhd deleted file mode 100644 index 86fddce7..00000000 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_ALU.vhd +++ /dev/null @@ -1,351 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0247 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- 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 --- 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/t80/ --- --- Limitations : --- --- File history : --- --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- --- 0238 : Fixed zero flag for 16 bit SBC and ADC --- --- 0240 : Added GB operations --- --- 0242 : Cleanup --- --- 0247 : Cleanup --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_ALU is - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - Arith16 : in std_logic; - Z16 : in std_logic; - ALU_Op : in std_logic_vector(3 downto 0); - IR : in std_logic_vector(5 downto 0); - ISet : in std_logic_vector(1 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - F_In : in std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0); - F_Out : out std_logic_vector(7 downto 0) - ); -end T80_ALU; - -architecture rtl of T80_ALU is - - procedure AddSub(A : std_logic_vector; - B : std_logic_vector; - Sub : std_logic; - Carry_In : std_logic; - signal Res : out std_logic_vector; - signal Carry : out std_logic) is - variable B_i : unsigned(A'length - 1 downto 0); - variable Res_i : unsigned(A'length + 1 downto 0); - begin - if Sub = '1' then - B_i := not unsigned(B); - else - B_i := unsigned(B); - end if; - Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); - Carry <= Res_i(A'length + 1); - Res <= std_logic_vector(Res_i(A'length downto 1)); - end; - - -- AddSub variables (temporary signals) - signal UseCarry : std_logic; - signal Carry7_v : std_logic; - signal Overflow_v : std_logic; - signal HalfCarry_v : std_logic; - signal Carry_v : std_logic; - signal Q_v : std_logic_vector(7 downto 0); - - signal BitMask : std_logic_vector(7 downto 0); - -begin - - with IR(5 downto 3) select BitMask <= "00000001" when "000", - "00000010" when "001", - "00000100" when "010", - "00001000" when "011", - "00010000" when "100", - "00100000" when "101", - "01000000" when "110", - "10000000" when others; - - UseCarry <= not ALU_Op(2) and ALU_Op(0); - AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); - AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); - AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); - OverFlow_v <= Carry_v xor Carry7_v; - - process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) - variable Q_t : std_logic_vector(7 downto 0); - variable DAA_Q : unsigned(8 downto 0); - begin - Q_t := "--------"; - F_Out <= F_In; - DAA_Q := "---------"; - case ALU_Op is - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => - F_Out(Flag_N) <= '0'; - F_Out(Flag_C) <= '0'; - case ALU_OP(2 downto 0) is - when "000" | "001" => -- ADD, ADC - Q_t := Q_v; - F_Out(Flag_C) <= Carry_v; - F_Out(Flag_H) <= HalfCarry_v; - F_Out(Flag_P) <= OverFlow_v; - when "010" | "011" | "111" => -- SUB, SBC, CP - Q_t := Q_v; - F_Out(Flag_N) <= '1'; - F_Out(Flag_C) <= not Carry_v; - F_Out(Flag_H) <= not HalfCarry_v; - F_Out(Flag_P) <= OverFlow_v; - when "100" => -- AND - Q_t(7 downto 0) := BusA and BusB; - F_Out(Flag_H) <= '1'; - when "101" => -- XOR - Q_t(7 downto 0) := BusA xor BusB; - F_Out(Flag_H) <= '0'; - when others => -- OR "110" - Q_t(7 downto 0) := BusA or BusB; - F_Out(Flag_H) <= '0'; - end case; - if ALU_Op(2 downto 0) = "111" then -- CP - F_Out(Flag_X) <= BusB(3); - F_Out(Flag_Y) <= BusB(5); - else - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - end if; - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - if Z16 = '1' then - F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC - end if; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= Q_t(7); - case ALU_Op(2 downto 0) is - when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP - when others => - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - end case; - if Arith16 = '1' then - F_Out(Flag_S) <= F_In(Flag_S); - F_Out(Flag_Z) <= F_In(Flag_Z); - F_Out(Flag_P) <= F_In(Flag_P); - end if; - when "1100" => - -- DAA - F_Out(Flag_H) <= F_In(Flag_H); - F_Out(Flag_C) <= F_In(Flag_C); - DAA_Q(7 downto 0) := unsigned(BusA); - DAA_Q(8) := '0'; - if F_In(Flag_N) = '0' then - -- After addition - -- Alow > 9 or H = 1 - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if (DAA_Q(3 downto 0) > 9) then - F_Out(Flag_H) <= '1'; - else - F_Out(Flag_H) <= '0'; - end if; - DAA_Q := DAA_Q + 6; - end if; - -- new Ahigh > 9 or C = 1 - if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q + 96; -- 0x60 - end if; - else - -- After subtraction - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if DAA_Q(3 downto 0) > 5 then - F_Out(Flag_H) <= '0'; - end if; - DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; - end if; - if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q - 352; -- 0x160 - end if; - end if; - F_Out(Flag_X) <= DAA_Q(3); - F_Out(Flag_Y) <= DAA_Q(5); - F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); - Q_t := std_logic_vector(DAA_Q(7 downto 0)); - if DAA_Q(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= DAA_Q(7); - F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor - DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); - when "1101" | "1110" => - -- RLD, RRD - Q_t(7 downto 4) := BusA(7 downto 4); - if ALU_Op(0) = '1' then - Q_t(3 downto 0) := BusB(7 downto 4); - else - Q_t(3 downto 0) := BusB(3 downto 0); - end if; - F_Out(Flag_H) <= '0'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= Q_t(7); - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - when "1001" => - -- BIT - Q_t(7 downto 0) := BusB and BitMask; - F_Out(Flag_S) <= Q_t(7); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - F_Out(Flag_P) <= '1'; - else - F_Out(Flag_Z) <= '0'; - F_Out(Flag_P) <= '0'; - end if; - F_Out(Flag_H) <= '1'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= '0'; - F_Out(Flag_Y) <= '0'; - if IR(2 downto 0) /= "110" then - F_Out(Flag_X) <= BusB(3); - F_Out(Flag_Y) <= BusB(5); - end if; - when "1010" => - -- SET - Q_t(7 downto 0) := BusB or BitMask; - when "1011" => - -- RES - Q_t(7 downto 0) := BusB and not BitMask; - when "1000" => - -- ROT - case IR(5 downto 3) is - when "000" => -- RLC - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := BusA(7); - F_Out(Flag_C) <= BusA(7); - when "010" => -- RL - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := F_In(Flag_C); - F_Out(Flag_C) <= BusA(7); - when "001" => -- RRC - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := BusA(0); - F_Out(Flag_C) <= BusA(0); - when "011" => -- RR - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := F_In(Flag_C); - F_Out(Flag_C) <= BusA(0); - when "100" => -- SLA - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := '0'; - F_Out(Flag_C) <= BusA(7); - when "110" => -- SLL (Undocumented) / SWAP - if Mode = 3 then - Q_t(7 downto 4) := BusA(3 downto 0); - Q_t(3 downto 0) := BusA(7 downto 4); - F_Out(Flag_C) <= '0'; - else - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := '1'; - F_Out(Flag_C) <= BusA(7); - end if; - when "101" => -- SRA - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := BusA(7); - F_Out(Flag_C) <= BusA(0); - when others => -- SRL - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := '0'; - F_Out(Flag_C) <= BusA(0); - end case; - F_Out(Flag_H) <= '0'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - F_Out(Flag_S) <= Q_t(7); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - if ISet = "00" then - F_Out(Flag_P) <= F_In(Flag_P); - F_Out(Flag_S) <= F_In(Flag_S); - F_Out(Flag_Z) <= F_In(Flag_Z); - end if; - when others => - null; - end case; - Q <= Q_t; - end process; - -end; diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_MCode.vhd b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_MCode.vhd deleted file mode 100644 index 4cc30f35..00000000 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_MCode.vhd +++ /dev/null @@ -1,1934 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- 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 --- 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/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0211 : Fixed IM 1 --- --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- --- 0235 : Added IM 2 fix by Mike Johnson --- --- 0238 : Added NoRead signal --- --- 0238b: Fixed instruction timing for POP and DJNZ --- --- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes --- --- 0242 : Fixed I/O instruction timing, cleanup --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_MCode is - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - IR : in std_logic_vector(7 downto 0); - ISet : in std_logic_vector(1 downto 0); - MCycle : in std_logic_vector(2 downto 0); - F : in std_logic_vector(7 downto 0); - NMICycle : in std_logic; - IntCycle : in std_logic; - MCycles : out std_logic_vector(2 downto 0); - TStates : out std_logic_vector(2 downto 0); - Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD - Inc_PC : out std_logic; - Inc_WZ : out std_logic; - IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc - Read_To_Reg : out std_logic; - Read_To_Acc : out std_logic; - Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - ALU_Op : out std_logic_vector(3 downto 0); - -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None - Save_ALU : out std_logic; - PreserveC : out std_logic; - Arith16 : out std_logic; - Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI - IORQ : out std_logic; - Jump : out std_logic; - JumpE : out std_logic; - JumpXY : out std_logic; - Call : out std_logic; - RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; - LDSPHL : out std_logic; - Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None - ExchangeDH : out std_logic; - ExchangeRp : out std_logic; - ExchangeAF : out std_logic; - ExchangeRS : out std_logic; - I_DJNZ : out std_logic; - I_CPL : out std_logic; - I_CCF : out std_logic; - I_SCF : out std_logic; - I_RETN : out std_logic; - I_BT : out std_logic; - I_BC : out std_logic; - I_BTR : out std_logic; - I_RLD : out std_logic; - I_RRD : out std_logic; - I_INRC : out std_logic; - SetDI : out std_logic; - SetEI : out std_logic; - IMode : out std_logic_vector(1 downto 0); - Halt : out std_logic; - NoRead : out std_logic; - Write : out std_logic - ); -end T80_MCode; - -architecture rtl of T80_MCode is - - constant aNone : std_logic_vector(2 downto 0) := "111"; - constant aBC : std_logic_vector(2 downto 0) := "000"; - constant aDE : std_logic_vector(2 downto 0) := "001"; - constant aXY : std_logic_vector(2 downto 0) := "010"; - constant aIOA : std_logic_vector(2 downto 0) := "100"; - constant aSP : std_logic_vector(2 downto 0) := "101"; - constant aZI : std_logic_vector(2 downto 0) := "110"; --- constant aNone : std_logic_vector(2 downto 0) := "000"; --- constant aXY : std_logic_vector(2 downto 0) := "001"; --- constant aIOA : std_logic_vector(2 downto 0) := "010"; --- constant aSP : std_logic_vector(2 downto 0) := "011"; --- constant aBC : std_logic_vector(2 downto 0) := "100"; --- constant aDE : std_logic_vector(2 downto 0) := "101"; --- constant aZI : std_logic_vector(2 downto 0) := "110"; - - function is_cc_true( - F : std_logic_vector(7 downto 0); - cc : bit_vector(2 downto 0) - ) return boolean is - begin - if Mode = 3 then - case cc is - when "000" => return F(7) = '0'; -- NZ - when "001" => return F(7) = '1'; -- Z - when "010" => return F(4) = '0'; -- NC - when "011" => return F(4) = '1'; -- C - when "100" => return false; - when "101" => return false; - when "110" => return false; - when "111" => return false; - end case; - else - case cc is - when "000" => return F(6) = '0'; -- NZ - when "001" => return F(6) = '1'; -- Z - when "010" => return F(0) = '0'; -- NC - when "011" => return F(0) = '1'; -- C - when "100" => return F(2) = '0'; -- PO - when "101" => return F(2) = '1'; -- PE - when "110" => return F(7) = '0'; -- P - when "111" => return F(7) = '1'; -- M - end case; - end if; - end; - -begin - - process (IR, ISet, MCycle, F, NMICycle, IntCycle) - variable DDD : std_logic_vector(2 downto 0); - variable SSS : std_logic_vector(2 downto 0); - variable DPair : std_logic_vector(1 downto 0); - variable IRB : bit_vector(7 downto 0); - begin - DDD := IR(5 downto 3); - SSS := IR(2 downto 0); - DPair := IR(5 downto 4); - IRB := to_bitvector(IR); - - MCycles <= "001"; - if MCycle = "001" then - TStates <= "100"; - else - TStates <= "011"; - end if; - Prefix <= "00"; - Inc_PC <= '0'; - Inc_WZ <= '0'; - IncDec_16 <= "0000"; - Read_To_Acc <= '0'; - Read_To_Reg <= '0'; - Set_BusB_To <= "0000"; - Set_BusA_To <= "0000"; - ALU_Op <= "0" & IR(5 downto 3); - Save_ALU <= '0'; - PreserveC <= '0'; - Arith16 <= '0'; - IORQ <= '0'; - Set_Addr_To <= aNone; - Jump <= '0'; - JumpE <= '0'; - JumpXY <= '0'; - Call <= '0'; - RstP <= '0'; - LDZ <= '0'; - LDW <= '0'; - LDSPHL <= '0'; - Special_LD <= "000"; - ExchangeDH <= '0'; - ExchangeRp <= '0'; - ExchangeAF <= '0'; - ExchangeRS <= '0'; - I_DJNZ <= '0'; - I_CPL <= '0'; - I_CCF <= '0'; - I_SCF <= '0'; - I_RETN <= '0'; - I_BT <= '0'; - I_BC <= '0'; - I_BTR <= '0'; - I_RLD <= '0'; - I_RRD <= '0'; - I_INRC <= '0'; - SetDI <= '0'; - SetEI <= '0'; - IMode <= "11"; - Halt <= '0'; - NoRead <= '0'; - Write <= '0'; - - case ISet is - when "00" => - ------------------------------------------------------------------------------- --- --- Unprefixed instructions --- ------------------------------------------------------------------------------- - - case IRB is --- 8 BIT LOAD GROUP - when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" - |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" - |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" - |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" - |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" - |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" - |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => - -- LD r,r' - Set_BusB_To(2 downto 0) <= SSS; - ExchangeRp <= '1'; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => - -- LD r,n - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when others => null; - end case; - when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => - -- LD r,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when others => null; - end case; - when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => - -- LD (HL),r - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00110110" => - -- LD (HL),n - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aXY; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - when 3 => - Write <= '1'; - when others => null; - end case; - when "00001010" => - -- LD A,(BC) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - when 2 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "00011010" => - -- LD A,(DE) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aDE; - when 2 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "00111010" => - if Mode = 3 then - -- LDD A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Acc <= '1'; - IncDec_16 <= "1110"; - when others => null; - end case; - else - -- LD A,(nn) - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - when 4 => - Read_To_Acc <= '1'; - when others => null; - end case; - end if; - when "00000010" => - -- LD (BC),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00010010" => - -- LD (DE),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aDE; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00110010" => - if Mode = 3 then - -- LDD (HL),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IncDec_16 <= "1110"; - when others => null; - end case; - else - -- LD (nn),A - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - Set_BusB_To <= "0111"; - when 4 => - Write <= '1'; - when others => null; - end case; - end if; - --- 16 BIT LOAD GROUP - when "00000001"|"00010001"|"00100001"|"00110001" => - -- LD dd,nn - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1000"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '1'; - end if; - when 3 => - Inc_PC <= '1'; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1001"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - when "00101010" => - if Mode = 3 then - -- LDI A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Acc <= '1'; - IncDec_16 <= "0110"; - when others => null; - end case; - else - -- LD HL,(nn) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Set_BusA_To(2 downto 0) <= "101"; -- L - Read_To_Reg <= '1'; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Set_BusA_To(2 downto 0) <= "100"; -- H - Read_To_Reg <= '1'; - when others => null; - end case; - end if; - when "00100010" => - if Mode = 3 then - -- LDI (HL),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IncDec_16 <= "0110"; - when others => null; - end case; - else - -- LD (nn),HL - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - Set_BusB_To <= "0101"; -- L - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - Set_BusB_To <= "0100"; -- H - when 5 => - Write <= '1'; - when others => null; - end case; - end if; - when "11111001" => - -- LD SP,HL - TStates <= "110"; - LDSPHL <= '1'; - when "11000101"|"11010101"|"11100101"|"11110101" => - -- PUSH qq - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "0111"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 2 => - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "1011"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - Write <= '1'; - when 3 => - Write <= '1'; - when others => null; - end case; - when "11000001"|"11010001"|"11100001"|"11110001" => - -- POP qq - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1011"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '1'; - end if; - when 3 => - IncDec_16 <= "0111"; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "0111"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - --- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP - when "11101011" => - if Mode /= 3 then - -- EX DE,HL - ExchangeDH <= '1'; - end if; - when "00001000" => - if Mode = 3 then - -- LD (nn),SP - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - Set_BusB_To <= "1000"; - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - Set_BusB_To <= "1001"; - when 5 => - Write <= '1'; - when others => null; - end case; - elsif Mode < 2 then - -- EX AF,AF' - ExchangeAF <= '1'; - end if; - when "11011001" => - if Mode = 3 then - -- RETI - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - I_RETN <= '1'; - SetEI <= '1'; - when others => null; - end case; - elsif Mode < 2 then - -- EXX - ExchangeRS <= '1'; - end if; - when "11100011" => - if Mode /= 3 then - -- EX (SP),HL - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aSP; - when 2 => - Read_To_Reg <= '1'; - Set_BusA_To <= "0101"; - Set_BusB_To <= "0101"; - Set_Addr_To <= aSP; - when 3 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - TStates <= "100"; - Write <= '1'; - when 4 => - Read_To_Reg <= '1'; - Set_BusA_To <= "0100"; - Set_BusB_To <= "0100"; - Set_Addr_To <= aSP; - when 5 => - IncDec_16 <= "1111"; - TStates <= "101"; - Write <= '1'; - when others => null; - end case; - end if; - --- 8 BIT ARITHMETIC AND LOGICAL GROUP - when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" - |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" - |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" - |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" - |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => - -- ADD A,r - -- ADC A,r - -- SUB A,r - -- SBC A,r - -- AND A,r - -- OR A,r - -- XOR A,r - -- CP A,r - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => - -- ADD A,(HL) - -- ADC A,(HL) - -- SUB A,(HL) - -- SBC A,(HL) - -- AND A,(HL) - -- OR A,(HL) - -- XOR A,(HL) - -- CP A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - when others => null; - end case; - when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => - -- ADD A,n - -- ADC A,n - -- SUB A,n - -- SBC A,n - -- AND A,n - -- OR A,n - -- XOR A,n - -- CP A,n - MCycles <= "010"; - if MCycle = "010" then - Inc_PC <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - end if; - when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => - -- INC r - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0000"; - when "00110100" => - -- INC (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - TStates <= "100"; - Set_Addr_To <= aXY; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0000"; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - when 3 => - Write <= '1'; - when others => null; - end case; - when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => - -- DEC r - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0010"; - when "00110101" => - -- DEC (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - TStates <= "100"; - Set_Addr_To <= aXY; - ALU_Op <= "0010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - when 3 => - Write <= '1'; - when others => null; - end case; - --- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS - when "00100111" => - -- DAA - Set_BusA_To(2 downto 0) <= "111"; - Read_To_Reg <= '1'; - ALU_Op <= "1100"; - Save_ALU <= '1'; - when "00101111" => - -- CPL - I_CPL <= '1'; - when "00111111" => - -- CCF - I_CCF <= '1'; - when "00110111" => - -- SCF - I_SCF <= '1'; - when "00000000" => - if NMICycle = '1' then - -- NMI - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - TStates <= "100"; - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - TStates <= "100"; - Write <= '1'; - when others => null; - end case; - elsif IntCycle = '1' then - -- INT (IM 2) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - LDZ <= '1'; - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - TStates <= "100"; - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - TStates <= "100"; - Write <= '1'; - when 4 => - Inc_PC <= '1'; - LDZ <= '1'; - when 5 => - Jump <= '1'; - when others => null; - end case; - else - -- NOP - end if; - when "01110110" => - -- HALT - Halt <= '1'; - when "11110011" => - -- DI - SetDI <= '1'; - when "11111011" => - -- EI - SetEI <= '1'; - --- 16 BIT ARITHMETIC GROUP - when "00001001"|"00011001"|"00101001"|"00111001" => - -- ADD HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - Arith16 <= '1'; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - when others => - Set_BusB_To <= "1001"; - end case; - Arith16 <= '1'; - when others => - end case; - when "00000011"|"00010011"|"00100011"|"00110011" => - -- INC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "01"; - IncDec_16(1 downto 0) <= DPair; - when "00001011"|"00011011"|"00101011"|"00111011" => - -- DEC ss - TStates <= "110"; - IncDec_16(3 downto 2) <= "11"; - IncDec_16(1 downto 0) <= DPair; - --- ROTATE AND SHIFT GROUP - when "00000111" - -- RLCA - |"00010111" - -- RLA - |"00001111" - -- RRCA - |"00011111" => - -- RRA - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - --- JUMP GROUP - when "11000011" => - -- JP nn - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - Jump <= '1'; - when others => null; - end case; - when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => - if IR(5) = '1' and Mode = 3 then - case IRB(4 downto 3) is - when "00" => - -- LD ($FF00+C),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IORQ <= '1'; - when others => - end case; - when "01" => - -- LD (nn),A - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - Set_BusB_To <= "0111"; - when 4 => - Write <= '1'; - when others => null; - end case; - when "10" => - -- LD A,($FF00+C) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - when 2 => - Read_To_Acc <= '1'; - IORQ <= '1'; - when others => - end case; - when "11" => - -- LD A,(nn) - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - when 4 => - Read_To_Acc <= '1'; - when others => null; - end case; - end case; - else - -- JP cc,nn - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Jump <= '1'; - end if; - when others => null; - end case; - end if; - when "00011000" => - if Mode /= 2 then - -- JR e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00111000" => - if Mode /= 2 then - -- JR C,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_C) = '0' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00110000" => - if Mode /= 2 then - -- JR NC,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_C) = '1' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00101000" => - if Mode /= 2 then - -- JR Z,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_Z) = '0' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00100000" => - if Mode /= 2 then - -- JR NZ,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_Z) = '1' then - MCycles <= "010"; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "11101001" => - -- JP (HL) - JumpXY <= '1'; - when "00010000" => - if Mode = 3 then - I_DJNZ <= '1'; - elsif Mode < 2 then - -- DJNZ,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - I_DJNZ <= '1'; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= "000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - I_DJNZ <= '1'; - Inc_PC <= '1'; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - --- CALL AND RETURN GROUP - when "11001101" => - -- CALL nn - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - IncDec_16 <= "1111"; - Inc_PC <= '1'; - TStates <= "100"; - Set_Addr_To <= aSP; - LDW <= '1'; - Set_BusB_To <= "1101"; - when 4 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 5 => - Write <= '1'; - Call <= '1'; - when others => null; - end case; - when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => - if IR(5) = '0' or Mode /= 3 then - -- CALL cc,nn - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - LDW <= '1'; - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - TStates <= "100"; - Set_BusB_To <= "1101"; - else - MCycles <= "011"; - end if; - when 4 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 5 => - Write <= '1'; - Call <= '1'; - when others => null; - end case; - end if; - when "11001001" => - -- RET - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => - if IR(5) = '1' and Mode = 3 then - case IRB(4 downto 3) is - when "00" => - -- LD ($FF00+nn),A - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; - when 3 => - Write <= '1'; - when others => null; - end case; - when "01" => - -- ADD SP,n - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - ALU_Op <= "0000"; - Inc_PC <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To <= "1000"; - Set_BusB_To <= "0110"; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To <= "1001"; - Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! - when others => - end case; - when "10" => - -- LD A,($FF00+nn) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - when 3 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "11" => - -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Set_BusA_To(2 downto 0) <= "101"; -- L - Read_To_Reg <= '1'; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Set_BusA_To(2 downto 0) <= "100"; -- H - Read_To_Reg <= '1'; - when others => null; - end case; - end case; - else - -- RET cc - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Set_Addr_TO <= aSP; - else - MCycles <= "001"; - end if; - TStates <= "101"; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - end if; - when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => - -- RST p - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - Write <= '1'; - RstP <= '1'; - when others => null; - end case; - --- INPUT AND OUTPUT GROUP - when "11011011" => - if Mode /= 3 then - -- IN A,(n) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - when 3 => - Read_To_Acc <= '1'; - IORQ <= '1'; - when others => null; - end case; - end if; - when "11010011" => - if Mode /= 3 then - -- OUT (n),A - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; - when 3 => - Write <= '1'; - IORQ <= '1'; - when others => null; - end case; - end if; - ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- --- MULTIBYTE INSTRUCTIONS ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- - - when "11001011" => - if Mode /= 2 then - Prefix <= "01"; - end if; - - when "11101101" => - if Mode < 2 then - Prefix <= "10"; - end if; - - when "11011101"|"11111101" => - if Mode < 2 then - Prefix <= "11"; - end if; - - end case; - - when "01" => - ------------------------------------------------------------------------------- --- --- CB prefixed instructions --- ------------------------------------------------------------------------------- - - Set_BusA_To(2 downto 0) <= IR(2 downto 0); - Set_BusB_To(2 downto 0) <= IR(2 downto 0); - - case IRB is - when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" - |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" - |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" - |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" - |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" - |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" - |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" - |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => - -- RLC r - -- RL r - -- RRC r - -- RR r - -- SLA r - -- SRA r - -- SRL r - -- SLL r (Undocumented) / SWAP r - if MCycle = "001" then - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => - -- RLC (HL) - -- RL (HL) - -- RRC (HL) - -- RR (HL) - -- SRA (HL) - -- SRL (HL) - -- SLA (HL) - -- SLL (HL) (Undocumented) / SWAP (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => - end case; - when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" - |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" - |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" - |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" - |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" - |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" - |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" - |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => - -- BIT b,r - if MCycle = "001" then - Set_BusB_To(2 downto 0) <= IR(2 downto 0); - ALU_Op <= "1001"; - end if; - when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => - -- BIT b,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1001"; - TStates <= "100"; - when others => - end case; - when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" - |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" - |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" - |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" - |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" - |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" - |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" - |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => - -- SET b,r - if MCycle = "001" then - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => - -- SET b,(HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => - end case; - when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" - |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" - |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" - |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" - |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => - -- RES b,r - if MCycle = "001" then - ALU_Op <= "1011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => - -- RES b,(HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => - end case; - end case; - - when others => - ------------------------------------------------------------------------------- --- --- ED prefixed instructions --- ------------------------------------------------------------------------------- - - case IRB is - when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" - |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" - |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" - |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" - |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" - |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" - |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" - |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" - - - |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" - | "10100100"|"10100101"|"10100110"|"10100111" - | "10101100"|"10101101"|"10101110"|"10101111" - | "10110100"|"10110101"|"10110110"|"10110111" - | "10111100"|"10111101"|"10111110"|"10111111" - |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" - |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" - |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" - |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" - |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" - |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" - |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" - |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => - null; -- NOP, undocumented - when "01111110"|"01111111" => - -- NOP, undocumented - null; --- 8 BIT LOAD GROUP - when "01010111" => - -- LD A,I - Special_LD <= "100"; - TStates <= "101"; - when "01011111" => - -- LD A,R - Special_LD <= "101"; - TStates <= "101"; - when "01000111" => - -- LD I,A - Special_LD <= "110"; - TStates <= "101"; - when "01001111" => - -- LD R,A - Special_LD <= "111"; - TStates <= "101"; --- 16 BIT LOAD GROUP - when "01001011"|"01011011"|"01101011"|"01111011" => - -- LD dd,(nn) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Read_To_Reg <= '1'; - if IR(5 downto 4) = "11" then - Set_BusA_To <= "1000"; - else - Set_BusA_To(2 downto 1) <= IR(5 downto 4); - Set_BusA_To(0) <= '1'; - end if; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Read_To_Reg <= '1'; - if IR(5 downto 4) = "11" then - Set_BusA_To <= "1001"; - else - Set_BusA_To(2 downto 1) <= IR(5 downto 4); - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - when "01000011"|"01010011"|"01100011"|"01110011" => - -- LD (nn),dd - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - if IR(5 downto 4) = "11" then - Set_BusB_To <= "1000"; - else - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - if IR(5 downto 4) = "11" then - Set_BusB_To <= "1001"; - else - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 5 => - Write <= '1'; - when others => null; - end case; - when "10100000" | "10101000" | "10110000" | "10111000" => - -- LDI, LDD, LDIR, LDDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - IncDec_16 <= "1100"; -- BC - when 2 => - Set_BusB_To <= "0110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "0000"; - Set_Addr_To <= aDE; - if IR(3) = '0' then - IncDec_16 <= "0110"; -- IX - else - IncDec_16 <= "1110"; - end if; - when 3 => - I_BT <= '1'; - TStates <= "101"; - Write <= '1'; - if IR(3) = '0' then - IncDec_16 <= "0101"; -- DE - else - IncDec_16 <= "1101"; - end if; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "10100001" | "10101001" | "10110001" | "10111001" => - -- CPI, CPD, CPIR, CPDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - IncDec_16 <= "1100"; -- BC - when 2 => - Set_BusB_To <= "0110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "0111"; - Save_ALU <= '1'; - PreserveC <= '1'; - if IR(3) = '0' then - IncDec_16 <= "0110"; - else - IncDec_16 <= "1110"; - end if; - when 3 => - NoRead <= '1'; - I_BC <= '1'; - TStates <= "101"; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => - -- NEG - Alu_OP <= "0010"; - Set_BusB_To <= "0111"; - Set_BusA_To <= "1010"; - Read_To_Acc <= '1'; - Save_ALU <= '1'; - when "01000110"|"01001110"|"01100110"|"01101110" => - -- IM 0 - IMode <= "00"; - when "01010110"|"01110110" => - -- IM 1 - IMode <= "01"; - when "01011110"|"01110111" => - -- IM 2 - IMode <= "10"; --- 16 bit arithmetic - when "01001010"|"01011010"|"01101010"|"01111010" => - -- ADC HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0001"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '0'; - when others => - Set_BusB_To <= "1001"; - end case; - when others => - end case; - when "01000010"|"01010010"|"01100010"|"01110010" => - -- SBC HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - ALU_Op <= "0011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - when 3 => - NoRead <= '1'; - ALU_Op <= "0011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - when others => - Set_BusB_To <= "1001"; - end case; - when others => - end case; - when "01101111" => - -- RLD - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - NoRead <= '1'; - Set_Addr_To <= aXY; - when 3 => - Read_To_Reg <= '1'; - Set_BusB_To(2 downto 0) <= "110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1101"; - TStates <= "100"; - Set_Addr_To <= aXY; - Save_ALU <= '1'; - when 4 => - I_RLD <= '1'; - Write <= '1'; - when others => - end case; - when "01100111" => - -- RRD - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Set_Addr_To <= aXY; - when 3 => - Read_To_Reg <= '1'; - Set_BusB_To(2 downto 0) <= "110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1110"; - TStates <= "100"; - Set_Addr_To <= aXY; - Save_ALU <= '1'; - when 4 => - I_RRD <= '1'; - Write <= '1'; - when others => - end case; - when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => - -- RETI, RETN - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - I_RETN <= '1'; - when others => null; - end case; - when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => - -- IN r,(C) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - when 2 => - IORQ <= '1'; - if IR(5 downto 3) /= "110" then - Read_To_Reg <= '1'; - Set_BusA_To(2 downto 0) <= IR(5 downto 3); - end if; - I_INRC <= '1'; - when others => - end case; - when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => - -- OUT (C),r - -- OUT (C),0 - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To(2 downto 0) <= IR(5 downto 3); - if IR(5 downto 3) = "110" then - Set_BusB_To(3) <= '1'; - end if; - when 2 => - Write <= '1'; - IORQ <= '1'; - when others => - end case; - when "10100010" | "10101010" | "10110010" | "10111010" => - -- INI, IND, INIR, INDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "1010"; - Set_BusA_To <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - IORQ <= '1'; - Set_BusB_To <= "0110"; - Set_Addr_To <= aXY; - when 3 => - if IR(3) = '0' then - IncDec_16 <= "0010"; - else - IncDec_16 <= "1010"; - end if; - TStates <= "100"; - Write <= '1'; - I_BTR <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "10100011" | "10101011" | "10110011" | "10111011" => - -- OUTI, OUTD, OTIR, OTDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - Set_Addr_To <= aXY; - Set_BusB_To <= "1010"; - Set_BusA_To <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - Set_BusB_To <= "0110"; - Set_Addr_To <= aBC; - when 3 => - if IR(3) = '0' then - IncDec_16 <= "0010"; - else - IncDec_16 <= "1010"; - end if; - IORQ <= '1'; - Write <= '1'; - I_BTR <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - end case; - - end case; - - if Mode = 1 then - if MCycle = "001" then --- TStates <= "100"; - else - TStates <= "011"; - end if; - end if; - - if Mode = 3 then - if MCycle = "001" then --- TStates <= "100"; - else - TStates <= "100"; - end if; - end if; - - if Mode < 2 then - if MCycle = "110" then - Inc_PC <= '1'; - if Mode = 1 then - Set_Addr_To <= aXY; - TStates <= "100"; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - end if; - if IRB = "00110110" or IRB = "11001011" then - Set_Addr_To <= aNone; - end if; - end if; - if MCycle = "111" then - if Mode = 0 then - TStates <= "101"; - end if; - if ISet /= "01" then - Set_Addr_To <= aXY; - end if; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - if IRB = "00110110" or ISet = "01" then - -- LD (HL),n - Inc_PC <= '1'; - else - NoRead <= '1'; - end if; - end if; - end if; - - end process; - -end; diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_Pack.vhd b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_Pack.vhd deleted file mode 100644 index ac7d34da..00000000 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_Pack.vhd +++ /dev/null @@ -1,208 +0,0 @@ --- --- Z80 compatible microprocessor core --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- 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 --- 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/t80/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; - -package T80_Pack is - - component T80 - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - IORQ : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DInst : in std_logic_vector(7 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - MC : out std_logic_vector(2 downto 0); - TS : out std_logic_vector(2 downto 0); - IntCycle_n : out std_logic; - IntE : out std_logic; - Stop : out std_logic - ); - end component; - - component T80_Reg - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0) - ); - end component; - - component T80_MCode - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - IR : in std_logic_vector(7 downto 0); - ISet : in std_logic_vector(1 downto 0); - MCycle : in std_logic_vector(2 downto 0); - F : in std_logic_vector(7 downto 0); - NMICycle : in std_logic; - IntCycle : in std_logic; - MCycles : out std_logic_vector(2 downto 0); - TStates : out std_logic_vector(2 downto 0); - Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD - Inc_PC : out std_logic; - Inc_WZ : out std_logic; - IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc - Read_To_Reg : out std_logic; - Read_To_Acc : out std_logic; - Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - ALU_Op : out std_logic_vector(3 downto 0); - -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None - Save_ALU : out std_logic; - PreserveC : out std_logic; - Arith16 : out std_logic; - Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI - IORQ : out std_logic; - Jump : out std_logic; - JumpE : out std_logic; - JumpXY : out std_logic; - Call : out std_logic; - RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; - LDSPHL : out std_logic; - Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None - ExchangeDH : out std_logic; - ExchangeRp : out std_logic; - ExchangeAF : out std_logic; - ExchangeRS : out std_logic; - I_DJNZ : out std_logic; - I_CPL : out std_logic; - I_CCF : out std_logic; - I_SCF : out std_logic; - I_RETN : out std_logic; - I_BT : out std_logic; - I_BC : out std_logic; - I_BTR : out std_logic; - I_RLD : out std_logic; - I_RRD : out std_logic; - I_INRC : out std_logic; - SetDI : out std_logic; - SetEI : out std_logic; - IMode : out std_logic_vector(1 downto 0); - Halt : out std_logic; - NoRead : out std_logic; - Write : out std_logic - ); - end component; - - component T80_ALU - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - Arith16 : in std_logic; - Z16 : in std_logic; - ALU_Op : in std_logic_vector(3 downto 0); - IR : in std_logic_vector(5 downto 0); - ISet : in std_logic_vector(1 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - F_In : in std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0); - F_Out : out std_logic_vector(7 downto 0) - ); - end component; - -end; diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_Reg.vhd b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_Reg.vhd deleted file mode 100644 index 828485fb..00000000 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80_Reg.vhd +++ /dev/null @@ -1,105 +0,0 @@ --- --- T80 Registers, technology independent --- --- Version : 0244 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- 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 --- 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/t51/ --- --- Limitations : --- --- File history : --- --- 0242 : Initial release --- --- 0244 : Changed to single register file --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_Reg is - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0) - ); -end T80_Reg; - -architecture rtl of T80_Reg is - - type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); - signal RegsH : Register_Image(0 to 7); - signal RegsL : Register_Image(0 to 7); - -begin - - process (Clk) - begin - if Clk'event and Clk = '1' then - if CEN = '1' then - if WEH = '1' then - RegsH(to_integer(unsigned(AddrA))) <= DIH; - end if; - if WEL = '1' then - RegsL(to_integer(unsigned(AddrA))) <= DIL; - end if; - end if; - end if; - end process; - - DOAH <= RegsH(to_integer(unsigned(AddrA))); - DOAL <= RegsL(to_integer(unsigned(AddrA))); - DOBH <= RegsH(to_integer(unsigned(AddrB))); - DOBL <= RegsL(to_integer(unsigned(AddrB))); - DOCH <= RegsH(to_integer(unsigned(AddrC))); - DOCL <= RegsL(to_integer(unsigned(AddrC))); - -end; diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80se.vhd b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80se.vhd deleted file mode 100644 index ac8886a8..00000000 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/T80/T80se.vhd +++ /dev/null @@ -1,184 +0,0 @@ --- --- Z80 compatible microprocessor core, synchronous top level with clock enable --- Different timing than the original z80 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- 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 --- 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/t80/ --- --- Limitations : --- --- File history : --- --- 0235 : First release --- --- 0236 : Added T2Write generic --- --- 0237 : Fixed T2Write with wait state --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80se is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CLKEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T80se; - -architecture rtl of T80se is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - u0 : T80 - generic map( - Mode => Mode, - IOWait => IOWait) - port map( - CEN => CLKEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - WAIT_n => Wait_n, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n, - CLK_n => CLK_n, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK_n'event and CLK_n = '1' then - if CLKEN = '1' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and Wait_n = '0') then - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - IORQ_n <= IntCycle_n; - end if; - if TState = "011" then - MREQ_n <= '0'; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then - RD_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - if T2Write = 0 then - if TState = "010" and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - end if; - end if; - if TState = "010" and Wait_n = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; - -end; diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/galaga_mist.sv b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/galaga_mist.sv index 2f8eabe2..8a1bd536 100644 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/galaga_mist.sv +++ b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/galaga_mist.sv @@ -23,9 +23,9 @@ localparam CONF_STR = { "Galaga;;", "O2,Rotate Controls,Off,On;", "O34,Scanlines,Off,25%,50%,75%;", -// "O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;", + "O5,Blend,Off,On;", "T6,Reset;", - "V,v1.20.",`BUILD_DATE + "V,v1.21.",`BUILD_DATE }; assign LED = 1; @@ -37,7 +37,6 @@ pll pll( .c0(clk_18) ); - wire [31:0] status; wire [1:0] buttons; wire [1:0] switches; @@ -83,7 +82,7 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video( .SPI_DI(SPI_DI), .R(blankn ? r : 0), .G(blankn ? g : 0), - .B(blankn ? {b, b[1]} : 0), + .B(blankn ? {b[0], b} : 0), .HSync(hs), .VSync(vs), .VGA_R(VGA_R), @@ -92,6 +91,7 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video( .VGA_VS(VGA_VS), .VGA_HS(VGA_HS), .ce_divider(1'b1), + .blend(status[5]), .rotate({1'b1,status[2]}), .scanlines(scandoublerD ? 2'b00 : status[4:3]), .scandoubler_disable(scandoublerD), diff --git a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/pll.qip b/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/pll.qip deleted file mode 100644 index afd958be..00000000 --- a/Arcade_MiST/Galaga Hardware/Galaga_MiST/rtl/pll.qip +++ /dev/null @@ -1,4 +0,0 @@ -set_global_assignment -name IP_TOOL_NAME "ALTPLL" -set_global_assignment -name IP_TOOL_VERSION "13.1" -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"] -set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] diff --git a/Arcade_MiST/Nintendo Radar Scope Hardware/Donkey Kong/DKong.qsf b/Arcade_MiST/Nintendo Radar Scope Hardware/Donkey Kong/DKong.qsf index 6939351e..f28b4b7c 100644 --- a/Arcade_MiST/Nintendo Radar Scope Hardware/Donkey Kong/DKong.qsf +++ b/Arcade_MiST/Nintendo Radar Scope Hardware/Donkey Kong/DKong.qsf @@ -144,16 +144,15 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - # Incremental Compilation Assignments # =================================== - set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top - set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top - set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top # end DESIGN_PARTITION(Top) # ------------------------- # end ENTITY(dkong_MiST) # ---------------------- -set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip set_global_assignment -name SYSTEMVERILOG_FILE rtl/dkong_MiST.sv set_global_assignment -name VERILOG_FILE rtl/dkong_top.v set_global_assignment -name VERILOG_FILE rtl/i8035ip.v @@ -211,4 +210,5 @@ set_global_assignment -name VHDL_FILE "rtl/t48_ip/alu_pack-p.vhd" set_global_assignment -name VHDL_FILE rtl/t48_ip/alu.vhd set_global_assignment -name VERILOG_FILE rtl/pll.v set_global_assignment -name SYSTEMVERILOG_FILE rtl/dkong_soundboard.sv +set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Phoenix Hardware/Survival_MIST/Survival_-_1982_-_Rocket_Company.pdf b/Arcade_MiST/Phoenix Hardware/Survival_MIST/Survival_-_1982_-_Rocket_Company.pdf deleted file mode 100644 index 7a97786b..00000000 Binary files a/Arcade_MiST/Phoenix Hardware/Survival_MIST/Survival_-_1982_-_Rocket_Company.pdf and /dev/null differ diff --git a/Arcade_MiST/Phoenix Hardware/Survival_MIST/Survival_MiST.qsf b/Arcade_MiST/Phoenix Hardware/Survival_MIST/Survival_MiST.qsf index 55a4778a..9a598efd 100644 --- a/Arcade_MiST/Phoenix Hardware/Survival_MIST/Survival_MiST.qsf +++ b/Arcade_MiST/Phoenix Hardware/Survival_MIST/Survival_MiST.qsf @@ -404,7 +404,6 @@ set_global_assignment -name VHDL_FILE rtl/phoenix_effect3.vhd set_global_assignment -name VHDL_FILE rtl/phoenix_effect2.vhd set_global_assignment -name VHDL_FILE rtl/phoenix_effect1.vhd set_global_assignment -name VHDL_FILE rtl/phoenix_video.vhd -set_global_assignment -name SYSTEMVERILOG_FILE rtl/ym2149.sv set_global_assignment -name VHDL_FILE rtl/ROM/survival_prog.vhd set_global_assignment -name VHDL_FILE rtl/ROM/prom_palette_ic41.vhd set_global_assignment -name VHDL_FILE rtl/ROM/prom_palette_ic40.vhd @@ -416,4 +415,5 @@ set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd set_global_assignment -name VHDL_FILE rtl/pll.vhd set_global_assignment -name QIP_FILE ../../../common/CPU/T80/T80.qip set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip +set_global_assignment -name VHDL_FILE rtl/YM2149_linmix_sep.vhd set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/Survival_MiST.sv b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/Survival_MiST.sv index d1203d64..c7a94478 100644 --- a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/Survival_MiST.sv +++ b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/Survival_MiST.sv @@ -41,14 +41,14 @@ localparam CONF_STR = { assign LED = 1; assign AUDIO_R = AUDIO_L; -wire clk_sys, clk_28, clk_1p79; +wire clk_sys, clk_28, clk_ay; wire pll_locked; pll pll( .inclk0(CLOCK_27), .areset(0), .c0(clk_sys),//11 .c1(clk_28),//28 - .c2(clk_1p79)//1.79 + .c2(clk_ay)//2.75 ); wire [31:0] status; @@ -69,7 +69,7 @@ wire [1:0] r,g,b; phoenix phoenix( .clk(clk_sys), .clk_28(clk_28), - .clk_1p79(clk_1p79), + .clk_ay(clk_ay), .reset(status[0] | status[6] | buttons[1]), .dip_switch(8'b00001111), .btn_coin(btn_coin), diff --git a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/YM2149_linmix_sep.vhd b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/YM2149_linmix_sep.vhd new file mode 100644 index 00000000..27f26749 --- /dev/null +++ b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/YM2149_linmix_sep.vhd @@ -0,0 +1,553 @@ +-- changes for seperate audio outputs and enable now enables cpu access as well +-- +-- A simulation model of YM2149 (AY-3-8910 with bells on) + +-- Copyright (c) MikeJ - Jan 2005 +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email support@fpgaarcade.com +-- +-- Revision list +-- +-- version 001 initial release +-- +-- Clues from MAME sound driver and Kazuhiro TSUJIKAWA +-- +-- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V) +-- vol 15 .. 0 +-- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132 +-- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order +-- to produced all the required values. +-- (The first part of the curve is a bit steeper and the last bit is more linear than expected) +-- +-- NOTE, this component uses LINEAR mixing of the three analogue channels, and is only +-- accurate for designs where the outputs are buffered and not simply wired together. +-- The ouput level is more complex in that case and requires a larger table. + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + +entity YM2149 is + port ( + -- data bus + I_DA : in std_logic_vector(7 downto 0); + O_DA : out std_logic_vector(7 downto 0); + O_DA_OE_L : out std_logic; + -- control + I_A9_L : in std_logic; + I_A8 : in std_logic; + I_BDIR : in std_logic; + I_BC2 : in std_logic; + I_BC1 : in std_logic; + I_SEL_L : in std_logic; + + O_AUDIO : out std_logic_vector(7 downto 0); + O_CHAN : out std_logic_vector(1 downto 0); + -- port a + I_IOA : in std_logic_vector(7 downto 0); + O_IOA : out std_logic_vector(7 downto 0); + O_IOA_OE_L : out std_logic; + -- port b + I_IOB : in std_logic_vector(7 downto 0); + O_IOB : out std_logic_vector(7 downto 0); + O_IOB_OE_L : out std_logic; + + ENA : in std_logic; -- clock enable for higher speed operation + RESET_L : in std_logic; + CLK : in std_logic -- note 6 Mhz + ); +end; + +architecture RTL of YM2149 is + type array_16x8 is array (0 to 15) of std_logic_vector( 7 downto 0); + type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0); + + signal cnt_div : std_logic_vector(3 downto 0) := (others => '0'); + signal cnt_div_t1 : std_logic_vector(3 downto 0); + signal noise_div : std_logic := '0'; + signal ena_div : std_logic; + signal ena_div_noise : std_logic; + signal poly17 : std_logic_vector(16 downto 0) := (others => '0'); + + -- registers + signal addr : std_logic_vector(7 downto 0); + signal busctrl_addr : std_logic; + signal busctrl_we : std_logic; + signal busctrl_re : std_logic; + + signal reg : array_16x8; + signal env_reset : std_logic; + signal ioa_inreg : std_logic_vector(7 downto 0); + signal iob_inreg : std_logic_vector(7 downto 0); + + signal noise_gen_cnt : std_logic_vector(4 downto 0); + signal noise_gen_op : std_logic; + signal tone_gen_cnt : array_3x12 := (others => (others => '0')); + signal tone_gen_op : std_logic_vector(3 downto 1) := "000"; + + signal env_gen_cnt : std_logic_vector(15 downto 0); + signal env_ena : std_logic; + signal env_hold : std_logic; + signal env_inc : std_logic; + signal env_vol : std_logic_vector(4 downto 0); + + signal tone_ena_l : std_logic; + signal tone_src : std_logic; + signal noise_ena_l : std_logic; + signal chan_vol : std_logic_vector(4 downto 0); + + signal dac_amp : std_logic_vector(7 downto 0); +begin + -- cpu i/f + p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8) + variable cs : std_logic; + variable sel : std_logic_vector(2 downto 0); + begin + -- BDIR BC2 BC1 MODE + -- 0 0 0 inactive + -- 0 0 1 address + -- 0 1 0 inactive + -- 0 1 1 read + -- 1 0 0 address + -- 1 0 1 inactive + -- 1 1 0 write + -- 1 1 1 read + busctrl_addr <= '0'; + busctrl_we <= '0'; + busctrl_re <= '0'; + + cs := '0'; + if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then + cs := '1'; + end if; + + sel := (I_BDIR & I_BC2 & I_BC1); + case sel is + when "000" => null; + when "001" => busctrl_addr <= '1'; + when "010" => null; + when "011" => busctrl_re <= cs; + when "100" => busctrl_addr <= '1'; + when "101" => null; + when "110" => busctrl_we <= cs; + when "111" => busctrl_addr <= '1'; + when others => null; + end case; + end process; + + p_oe : process(busctrl_re) + begin + -- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns + O_DA_OE_L <= not (busctrl_re); + end process; + + -- + -- CLOCKED + -- + p_waddr : process(RESET_L, CLK) + begin + -- looks like registers are latches in real chip, but the address is caught at the end of the address state. + if (RESET_L = '0') then + addr <= (others => '0'); + elsif rising_edge(CLK) then + if (ENA = '1') then + if (busctrl_addr = '1') then + addr <= I_DA; + end if; + end if; + end if; + end process; + + p_wdata : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + reg <= (others => (others => '0')); + env_reset <= '1'; + elsif rising_edge(CLK) then + if (ENA = '1') then + env_reset <= '0'; + if (busctrl_we = '1') then + case addr(3 downto 0) is + when x"0" => reg(0) <= I_DA; + when x"1" => reg(1) <= I_DA; + when x"2" => reg(2) <= I_DA; + when x"3" => reg(3) <= I_DA; + when x"4" => reg(4) <= I_DA; + when x"5" => reg(5) <= I_DA; + when x"6" => reg(6) <= I_DA; + when x"7" => reg(7) <= I_DA; + when x"8" => reg(8) <= I_DA; + when x"9" => reg(9) <= I_DA; + when x"A" => reg(10) <= I_DA; + when x"B" => reg(11) <= I_DA; + when x"C" => reg(12) <= I_DA; + when x"D" => reg(13) <= I_DA; env_reset <= '1'; + when x"E" => reg(14) <= I_DA; + when x"F" => reg(15) <= I_DA; + when others => null; + end case; + end if; + end if; + end if; + end process; + + p_rdata : process(busctrl_re, addr, reg, ioa_inreg, iob_inreg) + begin + O_DA <= (others => '0'); -- 'X' + if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator + case addr(3 downto 0) is + when x"0" => O_DA <= reg(0) ; + when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ; + when x"2" => O_DA <= reg(2) ; + when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ; + when x"4" => O_DA <= reg(4) ; + when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ; + when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ; + when x"7" => O_DA <= reg(7) ; + when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ; + when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ; + when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ; + when x"B" => O_DA <= reg(11); + when x"C" => O_DA <= reg(12); + when x"D" => O_DA <= "0000" & reg(13)(3 downto 0); + when x"E" => if (reg(7)(6) = '0') then -- input + O_DA <= ioa_inreg; + else + O_DA <= reg(14); -- read output reg + end if; + when x"F" => if (Reg(7)(7) = '0') then + O_DA <= iob_inreg; + else + O_DA <= reg(15); + end if; + when others => null; + end case; + end if; + end process; + -- + p_divider : process + begin + wait until rising_edge(CLK); + -- / 8 when SEL is high and /16 when SEL is low + if (ENA = '1') then + ena_div <= '0'; + ena_div_noise <= '0'; + if (cnt_div = "0000") then + cnt_div <= (not I_SEL_L) & "111"; + ena_div <= '1'; + + noise_div <= not noise_div; + if (noise_div = '1') then + ena_div_noise <= '1'; + end if; + else + cnt_div <= cnt_div - "1"; + end if; + end if; + end process; + + p_noise_gen : process + variable noise_gen_comp : std_logic_vector(4 downto 0); + variable poly17_zero : std_logic; + begin + wait until rising_edge(CLK); + if (reg(6)(4 downto 0) = "00000") then + noise_gen_comp := "00000"; + else + noise_gen_comp := (reg(6)(4 downto 0) - "1"); + end if; + + poly17_zero := '0'; + if (poly17 = "00000000000000000") then poly17_zero := '1'; end if; + + if (ENA = '1') then + if (ena_div_noise = '1') then -- divider ena + + if (noise_gen_cnt >= noise_gen_comp) then + noise_gen_cnt <= "00000"; + poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1); + else + noise_gen_cnt <= (noise_gen_cnt + "1"); + end if; + end if; + end if; + end process; + noise_gen_op <= poly17(0); + + p_tone_gens : process + variable tone_gen_freq : array_3x12; + variable tone_gen_comp : array_3x12; + begin + wait until rising_edge(CLK); + -- looks like real chips count up - we need to get the Exact behaviour .. + tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0); + tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2); + tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4); + -- period 0 = period 1 + for i in 1 to 3 loop + if (tone_gen_freq(i) = x"000") then + tone_gen_comp(i) := x"000"; + else + tone_gen_comp(i) := (tone_gen_freq(i) - "1"); + end if; + end loop; + + if (ENA = '1') then + for i in 1 to 3 loop + if (ena_div = '1') then -- divider ena + + if (tone_gen_cnt(i) >= tone_gen_comp(i)) then + tone_gen_cnt(i) <= x"000"; + tone_gen_op(i) <= not tone_gen_op(i); + else + tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1"); + end if; + end if; + end loop; + end if; + end process; + + p_envelope_freq : process + variable env_gen_freq : std_logic_vector(15 downto 0); + variable env_gen_comp : std_logic_vector(15 downto 0); + begin + wait until rising_edge(CLK); + env_gen_freq := reg(12) & reg(11); + -- envelope freqs 1 and 0 are the same. + if (env_gen_freq = x"0000") then + env_gen_comp := x"0000"; + else + env_gen_comp := (env_gen_freq - "1"); + end if; + + if (ENA = '1') then + env_ena <= '0'; + if (ena_div = '1') then -- divider ena + if (env_gen_cnt >= env_gen_comp) then + env_gen_cnt <= x"0000"; + env_ena <= '1'; + else + env_gen_cnt <= (env_gen_cnt + "1"); + end if; + end if; + end if; + end process; + + p_envelope_shape : process(env_reset, reg, CLK) + variable is_bot : boolean; + variable is_bot_p1 : boolean; + variable is_top_m1 : boolean; + variable is_top : boolean; + begin + if (env_reset = '1') then + -- load initial state + if (reg(13)(2) = '0') then -- attack + env_vol <= "11111"; + env_inc <= '0'; -- -1 + else + env_vol <= "00000"; + env_inc <= '1'; -- +1 + end if; + env_hold <= '0'; + + elsif rising_edge(CLK) then + is_bot := (env_vol = "00000"); + is_bot_p1 := (env_vol = "00001"); + is_top_m1 := (env_vol = "11110"); + is_top := (env_vol = "11111"); + + if (ENA = '1') then + if (env_ena = '1') then + if (env_hold = '0') then + if (env_inc = '1') then + env_vol <= (env_vol + "00001"); + else + env_vol <= (env_vol + "11111"); + end if; + end if; + + -- envelope shape control. + if (reg(13)(3) = '0') then + if (env_inc = '0') then -- down + if is_bot_p1 then env_hold <= '1'; end if; + else + if is_top then env_hold <= '1'; end if; + end if; + else + if (reg(13)(0) = '1') then -- hold = 1 + if (env_inc = '0') then -- down + if (reg(13)(1) = '1') then -- alt + if is_bot then env_hold <= '1'; end if; + else + if is_bot_p1 then env_hold <= '1'; end if; + end if; + else + if (reg(13)(1) = '1') then -- alt + if is_top then env_hold <= '1'; end if; + else + if is_top_m1 then env_hold <= '1'; end if; + end if; + end if; + + elsif (reg(13)(1) = '1') then -- alternate + if (env_inc = '0') then -- down + if is_bot_p1 then env_hold <= '1'; end if; + if is_bot then env_hold <= '0'; env_inc <= '1'; end if; + else + if is_top_m1 then env_hold <= '1'; end if; + if is_top then env_hold <= '0'; env_inc <= '0'; end if; + end if; + end if; + + end if; + end if; + end if; + end if; + end process; + + p_chan_mixer : process(cnt_div, reg, tone_gen_op) + begin + tone_ena_l <= '1'; tone_src <= '1'; + noise_ena_l <= '1'; chan_vol <= "00000"; + case cnt_div(1 downto 0) is + when "00" => + tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0); + noise_ena_l <= reg(7)(3); + when "01" => + tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0); + noise_ena_l <= reg(7)(4); + when "10" => + tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0); + noise_ena_l <= reg(7)(5); + when "11" => null; -- tone gen outputs become valid on this clock + when others => null; + end case; + end process; + + p_op_mixer : process + variable chan_mixed : std_logic; + variable chan_amp : std_logic_vector(4 downto 0); + begin + wait until rising_edge(CLK); + if (ENA = '1') then + + chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op); + + chan_amp := (others => '0'); + if (chan_mixed = '1') then + if (chan_vol(4) = '0') then + if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet + chan_amp := "00000"; + else + chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone) + end if; + else + chan_amp := env_vol(4 downto 0); + end if; + end if; + + dac_amp <= x"00"; + case chan_amp is + when "11111" => dac_amp <= x"FF"; + when "11110" => dac_amp <= x"D9"; + when "11101" => dac_amp <= x"BA"; + when "11100" => dac_amp <= x"9F"; + when "11011" => dac_amp <= x"88"; + when "11010" => dac_amp <= x"74"; + when "11001" => dac_amp <= x"63"; + when "11000" => dac_amp <= x"54"; + when "10111" => dac_amp <= x"48"; + when "10110" => dac_amp <= x"3D"; + when "10101" => dac_amp <= x"34"; + when "10100" => dac_amp <= x"2C"; + when "10011" => dac_amp <= x"25"; + when "10010" => dac_amp <= x"1F"; + when "10001" => dac_amp <= x"1A"; + when "10000" => dac_amp <= x"16"; + when "01111" => dac_amp <= x"13"; + when "01110" => dac_amp <= x"10"; + when "01101" => dac_amp <= x"0D"; + when "01100" => dac_amp <= x"0B"; + when "01011" => dac_amp <= x"09"; + when "01010" => dac_amp <= x"08"; + when "01001" => dac_amp <= x"07"; + when "01000" => dac_amp <= x"06"; + when "00111" => dac_amp <= x"05"; + when "00110" => dac_amp <= x"04"; + when "00101" => dac_amp <= x"03"; + when "00100" => dac_amp <= x"03"; + when "00011" => dac_amp <= x"02"; + when "00010" => dac_amp <= x"02"; + when "00001" => dac_amp <= x"01"; + when "00000" => dac_amp <= x"00"; + when others => null; + end case; + + cnt_div_t1 <= cnt_div; + end if; + end process; + + p_audio_output : process(RESET_L, CLK) + begin + if (RESET_L = '0') then + O_AUDIO <= (others => '0'); + O_CHAN <= (others => '0'); + elsif rising_edge(CLK) then + + if (ENA = '1') then + O_AUDIO <= dac_amp(7 downto 0); + O_CHAN <= cnt_div_t1(1 downto 0); + end if; + end if; + end process; + + p_io_ports : process(reg) + begin + O_IOA <= reg(14); + O_IOA_OE_L <= not reg(7)(6); + O_IOB <= reg(15); + O_IOB_OE_L <= not reg(7)(7); + end process; + + p_io_ports_inreg : process + begin + wait until rising_edge(CLK); + if (ENA = '1') then -- resync + ioa_inreg <= I_IOA; + iob_inreg <= I_IOB; + end if; + end process; +end architecture RTL; diff --git a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/phoenix.vhd b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/phoenix.vhd index c976ba63..77e024e0 100644 --- a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/phoenix.vhd +++ b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/phoenix.vhd @@ -20,10 +20,9 @@ generic ( port( clk : in std_logic; -- 11 MHz for TV, 25 MHz for VGA clk_28 : in std_logic; - clk_1p79 : in std_logic; + clk_ay : in std_logic; reset : in std_logic; ce_pix : out std_logic; - dip_switch : in std_logic_vector(7 downto 0); -- game controls, normal logic '1':pressed, '0':released @@ -125,33 +124,14 @@ architecture struct of phoenix is signal player_start : std_logic_vector(1 downto 0); signal buttons : std_logic_vector(3 downto 0); signal R_autofire : std_logic_vector(21 downto 0); - signal ay_do : std_logic_vector( 7 downto 0) := (others =>'0'); - signal protection : std_logic_vector( 7 downto 0) := (others =>'0'); - signal chanA : std_logic_vector( 7 downto 0) := (others =>'0'); - signal chanB : std_logic_vector( 7 downto 0) := (others =>'0'); - signal chanC : std_logic_vector( 7 downto 0) := (others =>'0'); -COMPONENT ym2149 - PORT - ( - CLK : IN STD_LOGIC; - CE : IN STD_LOGIC; - RESET : IN STD_LOGIC; - BDIR : IN STD_LOGIC; - BC : IN STD_LOGIC; - DI : IN STD_LOGIC_VECTOR(7 DOWNTO 0); - DO : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); - CHANNEL_A : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); - CHANNEL_B : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); - CHANNEL_C : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); - SEL : IN STD_LOGIC; - MODE : IN STD_LOGIC; - IOA_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0); - IOA_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); - IOB_in : IN STD_LOGIC_VECTOR(7 DOWNTO 0); - IOB_out : OUT STD_LOGIC_VECTOR(7 DOWNTO 0) - ); -END COMPONENT; + signal psg_cs : std_logic; + signal ay_ena : std_logic; + signal ay_do : std_logic_vector( 7 downto 0) := (others =>'0'); + signal ay_iob_do : std_logic_vector(7 downto 0); + signal ay_ioa_di : std_logic_vector(7 downto 0); + signal ay_bdir : std_logic; + signal ay_bc1 : std_logic; begin @@ -401,28 +381,43 @@ port map( q => bkgnd_ram_do ); +-- bdir bc1 (bc2 = 1) +-- 0 0 : Inactive +-- 0 1 : Read +-- 1 0 : Write +-- 1 1 : Address +--ay_ioa_di <= not sw2(to_integer(unsigned(ay_iob_do(3 downto 1)))) & "000" & not sw1; -music: YM2149 -port map( - -- data bus - DI => cpu_do, - DO => open,--? - BDIR => cpu_wr_n,--? - BC => cpu_adr(0),--? - SEL => '0',--? - MODE => '1',--AY8910 - CHANNEL_A => chanA, - CHANNEL_B => chanB, - CHANNEL_C => chanC, - IOA_in => (others => '0'), - IOA_out => open, - IOB_in => (others => '0'), - IOB_out => ay_do,--protection - CE => clk_1p79,--2.75 - RESET => not reset_n, - CLK => clk - ); +ay_bdir <= '1' when cpu_wr_n = '0' else '0'; +ay_bc1 <= '1' when ((cpu_wr_n = '1' and cpu_adr(0) = '0')) else '0'; +psg_cs <= '1' when cpu_adr(15 downto 10) = "110100" else '0';--110100000000000 +ym2149 : entity work.ym2149 --110100100000000 +port map ( +-- data bus + I_DA => cpu_do, --: in std_logic_vector(7 downto 0); + O_DA => ay_do, --: out std_logic_vector(7 downto 0); + O_DA_OE_L => open, --: out std_logic; +-- control + I_A9_L => '1', --: in std_logic; + I_A8 => '1', --: in std_logic; + I_BDIR => ay_bdir, --: in std_logic; + I_BC2 => '1', --: in std_logic; + I_BC1 => ay_bc1, --: in std_logic; + I_SEL_L => '1', --: in std_logic; +-- audio + O_AUDIO => audio, --: out std_logic_vector(7 downto 0); +-- port a + I_IOA => ay_ioa_di, --: in std_logic_vector(7 downto 0); + O_IOA => open, --: out std_logic_vector(7 downto 0); + O_IOA_OE_L => open, --: out std_logic; +-- port b + I_IOB => "11111111", --: in std_logic_vector(7 downto 0); + O_IOB => ay_iob_do, --: out std_logic_vector(7 downto 0); + O_IOB_OE_L => open, --: out std_logic; -audio <= chanA + chanB + chanC; + ENA => '1', --: in std_logic; -- clock enable for higher speed operation + RESET_L => '1', --: in std_logic; + CLK => clk_ay +); end struct; diff --git a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/pll.vhd b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/pll.vhd index f2cf9b90..e39588dc 100644 --- a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/pll.vhd +++ b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/pll.vhd @@ -167,7 +167,7 @@ BEGIN clk1_duty_cycle => 50, clk1_multiply_by => 57, clk1_phase_shift => "0", - clk2_divide_by => 860, + clk2_divide_by => 560, clk2_duty_cycle => 50, clk2_multiply_by => 57, clk2_phase_shift => "0", @@ -256,7 +256,7 @@ END SYN; -- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" -- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "140" -- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "55" --- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "860" +-- Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "560" -- Retrieval info: PRIVATE: DIV_FACTOR3 NUMERIC "35" -- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" -- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" @@ -264,7 +264,7 @@ END SYN; -- Retrieval info: PRIVATE: DUTY_CYCLE3 STRING "50.00000000" -- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "10.992857" -- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "27.981817" --- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "1.789535" +-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "2.748214" -- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE3 STRING "43.971428" -- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" -- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" @@ -301,7 +301,7 @@ END SYN; -- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" -- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "11.00000000" -- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "28.00000000" --- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "1.79000000" +-- Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "2.75000000" -- Retrieval info: PRIVATE: OUTPUT_FREQ3 STRING "44.00000000" -- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" -- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0" @@ -370,7 +370,7 @@ END SYN; -- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" -- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "57" -- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" --- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "860" +-- Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "560" -- Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50" -- Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "57" -- Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0" diff --git a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/ym2149.sv b/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/ym2149.sv deleted file mode 100644 index 76d6e31d..00000000 --- a/Arcade_MiST/Phoenix Hardware/Survival_MIST/rtl/ym2149.sv +++ /dev/null @@ -1,293 +0,0 @@ -module ym2149 -( - input CLK, // Global clock - input CE, // PSG Clock enable - input RESET, // Chip RESET (set all Registers to '0', active hi) - input BDIR, // Bus Direction (0 - read , 1 - write) - input BC, // Bus control - input [7:0] DI, // Data In - output [7:0] DO, // Data Out - output [7:0] CHANNEL_A, // PSG Output channel A - output [7:0] CHANNEL_B, // PSG Output channel B - output [7:0] CHANNEL_C, // PSG Output channel C - - input SEL, - input MODE, - - input [7:0] IOA_in, - output [7:0] IOA_out, - - input [7:0] IOB_in, - output [7:0] IOB_out -); - -assign IOA_out = ymreg[14]; -assign IOB_out = ymreg[15]; - -reg ena_div; -reg ena_div_noise; -reg [3:0] addr; -reg [7:0] ymreg[16]; -reg env_ena; -reg [4:0] env_vol; - -wire [7:0] volTableAy[16] = - '{8'h00, 8'h03, 8'h04, 8'h06, - 8'h0a, 8'h0f, 8'h15, 8'h22, - 8'h28, 8'h41, 8'h5b, 8'h72, - 8'h90, 8'hb5, 8'hd7, 8'hff - }; - -wire [7:0] volTableYm[32] = - '{8'h00, 8'h01, 8'h01, 8'h02, - 8'h02, 8'h03, 8'h03, 8'h04, - 8'h06, 8'h07, 8'h09, 8'h0a, - 8'h0c, 8'h0e, 8'h11, 8'h13, - 8'h17, 8'h1b, 8'h20, 8'h25, - 8'h2c, 8'h35, 8'h3e, 8'h47, - 8'h54, 8'h66, 8'h77, 8'h88, - 8'ha1, 8'hc0, 8'he0, 8'hff - }; - -// Read from AY -assign DO = dout; -reg [7:0] dout; -always_comb begin - case(addr) - 0: dout = ymreg[0]; - 1: dout = {4'b0000, ymreg[1][3:0]}; - 2: dout = ymreg[2]; - 3: dout = {4'b0000, ymreg[3][3:0]}; - 4: dout = ymreg[4]; - 5: dout = {4'b0000, ymreg[5][3:0]}; - 6: dout = {3'b000, ymreg[6][4:0]}; - 7: dout = ymreg[7]; - 8: dout = {3'b000, ymreg[8][4:0]}; - 9: dout = {3'b000, ymreg[9][4:0]}; - 10: dout = {3'b000, ymreg[10][4:0]}; - 11: dout = ymreg[11]; - 12: dout = ymreg[12]; - 13: dout = {4'b0000, ymreg[13][3:0]}; - 14: dout = (ymreg[7][6] ? ymreg[14] : IOA_in); - 15: dout = (ymreg[7][7] ? ymreg[15] : IOB_in); - endcase -end - -// p_divider -always @(posedge CLK) begin - reg [3:0] cnt_div; - reg noise_div; - - if(CE) begin - ena_div <= 0; - ena_div_noise <= 0; - if(!cnt_div) begin - cnt_div <= {SEL, 3'b111}; - ena_div <= 1; - - noise_div <= (~noise_div); - if (noise_div) ena_div_noise <= 1; - end else begin - cnt_div <= cnt_div - 1'b1; - end - end -end - - -reg [16:0] poly17; -wire [4:0] noise_gen_comp = ymreg[6][4:0] ? ymreg[6][4:0] - 1'd1 : 5'd0; - -// p_noise_gen -always @(posedge CLK) begin - reg [4:0] noise_gen_cnt; - - if(CE) begin - if (ena_div_noise) begin - if (noise_gen_cnt >= noise_gen_comp) begin - noise_gen_cnt <= 0; - poly17 <= {(poly17[0] ^ poly17[2] ^ !poly17), poly17[16:1]}; - end else begin - noise_gen_cnt <= noise_gen_cnt + 1'd1; - end - end - end -end - -wire [11:0] tone_gen_freq[1:3]; -assign tone_gen_freq[1] = {ymreg[1][3:0], ymreg[0]}; -assign tone_gen_freq[2] = {ymreg[3][3:0], ymreg[2]}; -assign tone_gen_freq[3] = {ymreg[5][3:0], ymreg[4]}; - -wire [11:0] tone_gen_comp[1:3]; -assign tone_gen_comp[1] = tone_gen_freq[1] ? tone_gen_freq[1] - 1'd1 : 12'd0; -assign tone_gen_comp[2] = tone_gen_freq[2] ? tone_gen_freq[2] - 1'd1 : 12'd0; -assign tone_gen_comp[3] = tone_gen_freq[3] ? tone_gen_freq[3] - 1'd1 : 12'd0; - -reg [3:1] tone_gen_op; - -//p_tone_gens -always @(posedge CLK) begin - integer i; - reg [11:0] tone_gen_cnt[1:3]; - - if(CE) begin - // looks like real chips count up - we need to get the Exact behaviour .. - - for (i = 1; i <= 3; i = i + 1) begin - if(ena_div) begin - if (tone_gen_cnt[i] >= tone_gen_comp[i]) begin - tone_gen_cnt[i] <= 0; - tone_gen_op[i] <= (~tone_gen_op[i]); - end else begin - tone_gen_cnt[i] <= tone_gen_cnt[i] + 1'd1; - end - end - end - end -end - -wire [15:0] env_gen_comp = {ymreg[12], ymreg[11]} ? {ymreg[12], ymreg[11]} - 1'd1 : 16'd0; - -//p_envelope_freq -always @(posedge CLK) begin - reg [15:0] env_gen_cnt; - - if(CE) begin - env_ena <= 0; - if(ena_div) begin - if (env_gen_cnt >= env_gen_comp) begin - env_gen_cnt <= 0; - env_ena <= 1; - end else begin - env_gen_cnt <= (env_gen_cnt + 1'd1); - end - end - end -end - -wire is_bot = (env_vol == 5'b00000); -wire is_bot_p1 = (env_vol == 5'b00001); -wire is_top_m1 = (env_vol == 5'b11110); -wire is_top = (env_vol == 5'b11111); - -always @(posedge CLK) begin - reg old_BDIR; - reg env_reset; - reg env_hold; - reg env_inc; - - // envelope shapes - // C AtAlH - // 0 0 x x \___ - // - // 0 1 x x /___ - // - // 1 0 0 0 \\\\ - // - // 1 0 0 1 \___ - // - // 1 0 1 0 \/\/ - // ___ - // 1 0 1 1 \ - // - // 1 1 0 0 //// - // ___ - // 1 1 0 1 / - // - // 1 1 1 0 /\/\ - // - // 1 1 1 1 /___ - - if(RESET) begin - ymreg[0] <= 0; - ymreg[1] <= 0; - ymreg[2] <= 0; - ymreg[3] <= 0; - ymreg[4] <= 0; - ymreg[5] <= 0; - ymreg[6] <= 0; - ymreg[7] <= 255; - ymreg[8] <= 0; - ymreg[9] <= 0; - ymreg[10] <= 0; - ymreg[11] <= 0; - ymreg[12] <= 0; - ymreg[13] <= 0; - ymreg[14] <= 0; - ymreg[15] <= 0; - addr <= 0; - env_vol <= 0; - end else begin - old_BDIR <= BDIR; - if(~old_BDIR & BDIR) begin - if(BC) addr <= DI[3:0]; - else begin - ymreg[addr] <= DI; - env_reset <= (addr == 13); - end - end - end - - if(CE) begin - if(env_reset) begin - env_reset <= 0; - // load initial state - if(!ymreg[13][2]) begin // attack - env_vol <= 5'b11111; - env_inc <= 0; // -1 - end else begin - env_vol <= 5'b00000; - env_inc <= 1; // +1 - end - env_hold <= 0; - end else begin - - if (env_ena) begin - if (!env_hold) begin - if (env_inc) env_vol <= (env_vol + 5'b00001); - else env_vol <= (env_vol + 5'b11111); - end - - // envelope shape control. - if(!ymreg[13][3]) begin - if(!env_inc) begin // down - if(is_bot_p1) env_hold <= 1; - end else if (is_top) env_hold <= 1; - end else if(ymreg[13][0]) begin // hold = 1 - if(!env_inc) begin // down - if(ymreg[13][1]) begin // alt - if(is_bot) env_hold <= 1; - end else if(is_bot_p1) env_hold <= 1; - end else if(ymreg[13][1]) begin // alt - if(is_top) env_hold <= 1; - end else if(is_top_m1) env_hold <= 1; - end else if(ymreg[13][1]) begin // alternate - if(env_inc == 1'b0) begin // down - if(is_bot_p1) env_hold <= 1; - if(is_bot) begin - env_hold <= 0; - env_inc <= 1; - end - end else begin - if(is_top_m1) env_hold <= 1; - if(is_top) begin - env_hold <= 0; - env_inc <= 0; - end - end - end - end - end - end -end - -wire [4:0] A = ~((ymreg[7][0] | tone_gen_op[1]) & (ymreg[7][3] | poly17[0])) ? 5'd0 : ymreg[8][4] ? env_vol[4:0] : { ymreg[8][3:0], ymreg[8][3]}; -wire [4:0] B = ~((ymreg[7][1] | tone_gen_op[2]) & (ymreg[7][4] | poly17[0])) ? 5'd0 : ymreg[9][4] ? env_vol[4:0] : { ymreg[9][3:0], ymreg[9][3]}; -wire [4:0] C = ~((ymreg[7][2] | tone_gen_op[3]) & (ymreg[7][5] | poly17[0])) ? 5'd0 : ymreg[10][4] ? env_vol[4:0] : {ymreg[10][3:0], ymreg[10][3]}; - -assign CHANNEL_A = MODE ? volTableAy[A[4:1]] : volTableYm[A]; -assign CHANNEL_B = MODE ? volTableAy[B[4:1]] : volTableYm[B]; -assign CHANNEL_C = MODE ? volTableAy[C[4:1]] : volTableYm[C]; - - -endmodule diff --git a/common/CPU/T80/T80.qip b/common/CPU/T80/T80.qip index 4d071284..efe676ed 100644 --- a/common/CPU/T80/T80.qip +++ b/common/CPU/T80/T80.qip @@ -7,4 +7,4 @@ set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Reg.vh set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_MCode.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_ALU.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80.vhd ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Pack.vhd ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80_Pack.vhd ] \ No newline at end of file diff --git a/common/CPU/tv80/TV80.qip b/common/CPU/tv80/TV80.qip new file mode 100644 index 00000000..10942d15 --- /dev/null +++ b/common/CPU/tv80/TV80.qip @@ -0,0 +1,6 @@ +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_core.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_alu.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_mcode.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80_reg.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80n.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "tv80s.v"] \ No newline at end of file