`timescale 1ns / 1ps // ============================================================================ // __ // \\__/ o\ (C) 2013, 2014 Robert Finch, Stratford // \ __ / All rights reserved. // \/_// robfinch@finitron.ca // || // // FT816.v // - 16 bit CPU // // This source file is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser 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 . // // ============================================================================ // `define TRUE 1'b1 `define FALSE 1'b0 `define DEBUG 1'b1 `define SUPPORT_ICACHE 1'b1 `define ICACHE_4K 1'b1 //`define ICACHE_16K 1'b1 //`define ICACHE_2WAY 1'b1 //`define SUPPORT_DCACHE 1'b1 `define SUPPORT_BCD 1'b1 `define SUPPORT_DIVMOD 1'b1 `define SUPPORT_EM8 1'b1 `define SUPPORT_816 1'b1 //`define SUPPORT_EXEC 1'b1 `define SUPPORT_BERR 1'b1 `define SUPPORT_STRING 1'b1 `define SUPPORT_SHIFT 1'b1 //`define SUPPORT_CGI 1'b1 // support the control giveaway interrupt `define BRK_VECTNO 9'd0 `define SLP_VECTNO 9'd1 `define BYTE_RST_VECT 24'h00FFFC `define BYTE_NMI_VECT 24'h00FFFA `define BYTE_IRQ_VECT 24'h00FFFE `define BYTE_ABT_VECT 24'h00FFF8 `define BYTE_COP_VECT 24'h00FFF4 `define RST_VECT_816 24'h00FFFC `define IRQ_VECT_816 24'h00FFEE `define NMI_VECT_816 24'h00FFEA `define ABT_VECT_816 24'h00FFE8 `define BRK_VECT_816 24'h00FFE6 `define COP_VECT_816 24'h00FFE4 `define BRK 9'h00 `define RTI 9'h40 `define RTS 9'h60 `define PHP 9'h08 `define CLC 9'h18 `define PLP 9'h28 `define SEC 9'h38 `define PHA 9'h48 `define CLI 9'h58 `define PLA 9'h68 `define SEI 9'h78 `define DEY 9'h88 `define TYA 9'h98 `define TAY 9'hA8 `define CLV 9'hB8 `define INY 9'hC8 `define CLD 9'hD8 `define INX 9'hE8 `define SED 9'hF8 `define ROR_ACC 9'h6A `define TXA 9'h8A `define TXS 9'h9A `define TAX 9'hAA `define TSX 9'hBA `define DEX 9'hCA `define NOP 9'hEA `define TXY 9'h9B `define TYX 9'hBB `define TAS 9'h1B `define TSA 9'h3B `define TRS 9'h8B `define TSR 9'hAB `define TCD 9'h5B `define TDC 9'h7B `define STP 9'hDB `define NAT 9'hFB `define EMM 9'hFB `define XCE 9'hFB `define INA 9'h1A `define DEA 9'h3A `define SEP 9'hE2 `define REP 9'hC2 `define PEA 9'hF4 `define PEI 9'hD4 `define PER 9'h62 `define WDM 9'h42 // CMP = SUB r0,.... `define ADC_IMM 9'h69 `define ADC_ZP 9'h65 `define ADC_ZPX 9'h75 `define ADC_IX 9'h61 `define ADC_IY 9'h71 `define ADC_IYL 9'h77 `define ADC_ABS 9'h6D `define ADC_ABSX 9'h7D `define ADC_ABSY 9'h79 `define ADC_I 9'h72 `define ADC_IL 9'h67 `define ADC_AL 9'h6F `define ADC_ALX 9'h7F `define ADC_DSP 9'h63 `define ADC_DSPIY 9'h73 `define SBC_IMM 9'hE9 `define SBC_ZP 9'hE5 `define SBC_ZPX 9'hF5 `define SBC_IX 9'hE1 `define SBC_IY 9'hF1 `define SBC_IYL 9'hF7 `define SBC_ABS 9'hED `define SBC_ABSX 9'hFD `define SBC_ABSY 9'hF9 `define SBC_I 9'hF2 `define SBC_IL 9'hE7 `define SBC_AL 9'hEF `define SBC_ALX 9'hFF `define SBC_DSP 9'hE3 `define SBC_DSPIY 9'hF3 `define CMP_IMM 9'hC9 `define CMP_ZP 9'hC5 `define CMP_ZPX 9'hD5 `define CMP_IX 9'hC1 `define CMP_IY 9'hD1 `define CMP_IYL 8'hD7 `define CMP_ABS 9'hCD `define CMP_ABSX 9'hDD `define CMP_ABSY 9'hD9 `define CMP_I 9'hD2 `define CMP_IL 9'hC7 `define CMP_AL 9'hCF `define CMP_ALX 9'hDF `define CMP_DSP 9'hC3 `define CMP_DSPIY 9'hD3 `define LDA_IMM8 9'hA5 `define LDA_IMM16 9'hB9 `define LDA_IMM32 9'hA9 `define AND_IMM 9'h29 `define AND_ZP 9'h25 `define AND_ZPX 9'h35 `define AND_IX 9'h21 `define AND_IY 9'h31 `define AND_IYL 9'h37 `define AND_ABS 9'h2D `define AND_ABSX 9'h3D `define AND_ABSY 9'h39 `define AND_RIND 9'h32 `define AND_I 9'h32 `define AND_IL 9'h27 `define AND_DSP 9'h23 `define AND_DSPIY 9'h33 `define AND_AL 9'h2F `define AND_ALX 9'h3F `define ORA_IMM 9'h09 `define ORA_ZP 9'h05 `define ORA_ZPX 9'h15 `define ORA_IX 9'h01 `define ORA_IY 9'h11 `define ORA_IYL 9'h17 `define ORA_ABS 9'h0D `define ORA_ABSX 9'h1D `define ORA_ABSY 9'h19 `define ORA_I 9'h12 `define ORA_IL 9'h07 `define ORA_AL 9'h0F `define ORA_ALX 9'h1F `define ORA_DSP 9'h03 `define ORA_DSPIY 9'h13 `define EOR_IMM 9'h49 `define EOR_ZP 9'h45 `define EOR_ZPX 9'h55 `define EOR_IX 9'h41 `define EOR_IY 9'h51 `define EOR_IYL 9'h57 `define EOR_ABS 9'h4D `define EOR_ABSX 9'h5D `define EOR_ABSY 9'h59 `define EOR_RIND 9'h52 `define EOR_I 9'h52 `define EOR_IL 9'h47 `define EOR_DSP 9'h43 `define EOR_DSPIY 9'h53 `define EOR_AL 9'h4F `define EOR_ALX 9'h5F //`define LDB_RIND 9'hB2 // Conflict with LDX #imm16 `define LDA_IMM 9'hA9 `define LDA_ZP 9'hA5 `define LDA_ZPX 9'hB5 `define LDA_IX 9'hA1 `define LDA_IY 9'hB1 `define LDA_IYL 9'hB7 `define LDA_ABS 9'hAD `define LDA_ABSX 9'hBD `define LDA_ABSY 9'hB9 `define LDA_I 9'hB2 `define LDA_IL 9'hA7 `define LDA_AL 9'hAF `define LDA_ALX 9'hBF `define LDA_DSP 9'hA3 `define LDA_DSPIY 9'hB3 `define STA_ZP 9'h85 `define STA_ZPX 9'h95 `define STA_IX 9'h81 `define STA_IY 9'h91 `define STA_IYL 9'h97 `define STA_ABS 9'h8D `define STA_ABSX 9'h9D `define STA_ABSY 9'h99 `define STA_I 9'h92 `define STA_IL 9'h87 `define STA_AL 9'h8F `define STA_ALX 9'h9F `define STA_DSP 9'h83 `define STA_DSPIY 9'h93 `define ASL_ACC 9'h0A `define ASL_ZP 9'h06 `define ASL_RR 9'h06 `define ASL_ZPX 9'h16 `define ASL_ABS 9'h0E `define ASL_ABSX 9'h1E `define ROL_ACC 9'h2A `define ROL_ZP 9'h26 `define ROL_RR 9'h26 `define ROL_ZPX 9'h36 `define ROL_ABS 9'h2E `define ROL_ABSX 9'h3E `define LSR_ACC 9'h4A `define LSR_ZP 9'h46 `define LSR_RR 9'h46 `define LSR_ZPX 9'h56 `define LSR_ABS 9'h4E `define LSR_ABSX 9'h5E `define ROR_RR 9'h66 `define ROR_ZP 9'h66 `define ROR_ZPX 9'h76 `define ROR_ABS 9'h6E `define ROR_ABSX 9'h7E `define DEC_RR 9'hC6 `define DEC_ZP 9'hC6 `define DEC_ZPX 9'hD6 `define DEC_ABS 9'hCE `define DEC_ABSX 9'hDE `define INC_RR 9'hE6 `define INC_ZP 9'hE6 `define INC_ZPX 9'hF6 `define INC_ABS 9'hEE `define INC_ABSX 9'hFE `define BIT_IMM 9'h89 `define BIT_ZP 9'h24 `define BIT_ZPX 9'h34 `define BIT_ABS 9'h2C `define BIT_ABSX 9'h3C // CMP = SUB r0,... // BIT = AND r0,... `define BPL 9'h10 `define BVC 9'h50 `define BCC 9'h90 `define BNE 9'hD0 `define BMI 9'h30 `define BVS 9'h70 `define BCS 9'hB0 `define BEQ 9'hF0 `define BRL 9'h82 `define BRA 9'h80 `define JML 9'h5C `define JMP 9'h4C `define JMP_IND 9'h6C `define JMP_INDX 9'h7C `define JMP_RIND 9'hD2 `define JSR 9'h20 `define JSL 9'h22 `define JSR_IND 9'h2C `define JSR_INDX 9'hFC `define JSR_RIND 9'hC2 `define RTS 9'h60 `define RTL 9'h6B `define BSR 9'h62 `define NOP 9'hEA `define BRK 9'h00 `define PLX 9'hFA `define PLY 9'h7A `define PHX 9'hDA `define PHY 9'h5A `define WAI 9'hCB `define PUSH 9'h0B `define POP 9'h2B `define PHB 9'h8B `define PHD 9'h0B `define PHK 9'h4B `define XBA 9'hEB `define COP 9'h02 `define PLB 9'hAB `define PLD 9'h2B `define PSHR4 9'h0F `define POPR4 9'h2F `define LDX_IMM 9'hA2 `define LDX_ZP 9'hA6 `define LDX_ZPX 9'hB6 `define LDX_ZPY 9'hB6 `define LDX_ABS 9'hAE `define LDX_ABSY 9'hBE `define LDX_IMM32 9'hA2 `define LDX_IMM16 9'hB2 `define LDX_IMM8 9'hA6 `define LDY_IMM 9'hA0 `define LDY_ZP 9'hA4 `define LDY_ZPX 9'hB4 `define LDY_IMM32 9'hA0 `define LDY_IMM8 9'hA1 `define LDY_ABS 9'hAC `define LDY_ABSX 9'hBC `define STX_ZP 9'h86 `define STX_ZPX 9'h96 `define STX_ZPY 9'h96 `define STX_ABS 9'h8E `define STY_ZP 9'h84 `define STY_ZPX 9'h94 `define STY_ABS 9'h8C `define STZ_ZP 9'h64 `define STZ_ZPX 9'h74 `define STZ_ABS 9'h9C `define STZ_ABSX 9'h9E `define CPX_IMM 9'hE0 `define CPX_IMM32 9'hE0 `define CPX_IMM8 9'hE2 `define CPX_ZP 9'hE4 `define CPX_ZPX 9'hE4 `define CPX_ABS 9'hEC `define CPY_IMM 9'hC0 `define CPY_IMM32 9'hC0 `define CPY_IMM8 9'hC1 `define CPY_ZP 9'hC4 `define CPY_ZPX 9'hC4 `define CPY_ABS 9'hCC `define TRB_ZP 9'h14 `define TRB_ZPX 9'h14 `define TRB_ABS 9'h1C `define TSB_ZP 9'h04 `define TSB_ZPX 9'h04 `define TSB_ABS 9'h0C `define MVP 9'h44 `define MVN 9'h54 `define STS 9'h64 // Page Two Opcodes `define PG2 9'h42 `define ICOFF 9'h108 `define ICON 9'h128 `define TOFF 9'h118 `define TON 9'h138 `define MUL_IMM8 9'h105 `define MUL_IMM16 9'h119 `define MUL_IMM32 9'h109 `define MULS_IMM8 9'h125 `define MULS_IMM16 9'h139 `define MULS_IMM32 9'h129 `define DIV_IMM8 9'h145 `define DIV_IMM16 9'h159 `define DIV_IMM32 9'h149 `define DIVS_IMM8 9'h165 `define DIVS_IMM16 9'h179 `define DIVS_IMM32 9'h169 `define MOD_IMM8 9'h185 `define MOD_IMM16 9'h199 `define MOD_IMM32 9'h189 `define MODS_IMM8 9'h1A5 `define MODS_IMM16 9'h1B9 `define MODS_IMM32 9'h1A9 `define PUSHA 9'h10B `define POPA 9'h12B `define BMS_ZPX 9'h106 `define BMS_ABS 9'h10E `define BMS_ABSX 9'h11E `define BMC_ZPX 9'h126 `define BMC_ABS 9'h12E `define BMC_ABSX 9'h13E `define BMF_ZPX 9'h146 `define BMF_ABS 9'h14E `define BMF_ABSX 9'h15E `define BMT_ZPX 9'h166 `define BMT_ABS 9'h16E `define BMT_ABSX 9'h17E `define HOFF 9'h158 `define CMPS 9'h144 `define SPL_ABS 9'h18E `define SPL_ABSX 9'h19E `define LEA_ZPX 9'h1D5 `define LEA_IX 9'h1C1 `define LEA_IY 9'h1D1 `define LEA_ABS 9'h1CD `define LEA_ABSX 9'h1DD `define LEA_RIND 9'h1D2 `define LEA_I 9'h1D2 `define LEA_DSP 9'h1C3 `define NOTHING 5'd0 `define SR_70 5'd1 `define SR_310 5'd2 `define BYTE_70 5'd3 `define WORD_310 5'd4 `define PC_70 5'd5 `define PC_158 5'd6 `define PC_2316 5'd7 `define PC_3124 5'd8 `define PC_310 5'd9 `define WORD_311 5'd10 `define IA_310 5'd11 `define IA_70 5'd12 `define IA_158 5'd13 `define BYTE_71 5'd14 `define WORD_312 5'd15 `define WORD_313 5'd16 `define WORD_314 5'd17 `define IA_2316 5'd18 `define HALF_70 5'd19 `define HALF_158 5'd20 `define HALF_71 5'd21 `define HALF_159 5'd22 `define HALF_71S 5'd23 `define HALF_159S 5'd24 `define BYTE_72 5'd25 `define TRIP_2316 5'd26 `define STW_DEF 6'h0 `define STW_RES8 6'd14 `define STW_R4 6'd15 `define STW_ACC8 6'd16 `define STW_X8 6'd17 `define STW_Y8 6'd18 `define STW_PC3124 6'd19 `define STW_PC2316 6'd20 `define STW_PC158 6'd21 `define STW_PC70 6'd22 `define STW_SR70 6'd23 `define STW_Z8 6'd24 `define STW_DEF8 6'd25 `define STW_DEF70 6'd26 `define STW_DEF158 6'd27 `define STW_DEF2316 6'd28 `define STW_ACC70 6'd32 `define STW_ACC158 6'd33 `define STW_X70 6'd34 `define STW_X158 6'd35 `define STW_Y70 6'd36 `define STW_Y158 6'd37 `define STW_Z70 6'd38 `define STW_Z158 6'd39 `define STW_DBR 6'd40 `define STW_DPR158 6'd41 `define STW_DPR70 6'd42 `define STW_TMP158 6'd43 `define STW_TMP70 6'd44 `define STW_IA158 6'd45 `define STW_IA70 6'd46 `define STW_BRA 6'd47 // Input Frequency is 32 times the 00 clock module FT816(rst, clk, clko, cyc, phi11, phi12, phi81, phi82, nmi, irq, abort, e, mx, rdy, be, vpa, vda, mlb, vpb, rw, ad, db, dw, err_i, rty_i); parameter SUPPORT_TRIBYTES = 1'b0; parameter STORE_SKIPPING = 1'b1; parameter EXTRA_LONG_BRANCHES = 1'b1; parameter RESET1 = 6'd0; parameter IFETCH1 = 6'd1; parameter IFETCH2 = 6'd2; parameter IFETCH3 = 6'd3; parameter IFETCH4 = 6'd4; parameter DECODE1 = 6'd5; parameter DECODE2 = 6'd6; parameter DECODE3 = 6'd7; parameter DECODE4 = 6'd8; parameter STORE1 = 6'd9; parameter STORE2 = 6'd10; parameter JSR161 = 6'd11; parameter RTS1 = 6'd12; parameter IY3 = 6'd13; parameter BSR1 = 6'd14; parameter BYTE_IX5 = 6'd15; parameter BYTE_IY5 = 6'd16; parameter WAIT_DHIT = 6'd17; parameter BYTE_CALC = 6'd18; parameter BUS_ERROR = 6'd19; parameter LOAD_MAC1 = 6'd20; parameter LOAD_MAC2 = 6'd21; parameter LOAD_MAC3 = 6'd22; parameter MVN3 = 6'd23; parameter IFETCH0 = 6'd24; parameter LOAD_DCACHE = 6'd26; parameter LOAD_ICACHE = 6'd27; parameter LOAD_IBUF1 = 6'd28; parameter LOAD_IBUF2 = 6'd29; parameter LOAD_IBUF3 = 6'd30; parameter ICACHE1 = 6'd31; parameter IBUF1 = 6'd32; parameter DCACHE1 = 6'd33; parameter HALF_CALC = 6'd35; parameter MVN816 = 6'd36; input rst; input clk; output clko; output reg [4:0] cyc; output phi11; output phi12; output phi81; output phi82; input nmi; input irq; input abort; output e; output mx; input rdy; input be; output reg vpa; output reg vda; output reg mlb; output reg vpb; output tri rw; output tri [23:0] ad; input [7:0] db; output[7:0] dw; input err_i; input rty_i; parameter TRUE = 1'b1; parameter FALSE = 1'b0; reg [31:0] phi1r,phi2r; reg rwo; reg [23:0] ado; reg [7:0] dbo; reg [7:0] dbi; reg pg2; reg [5:0] state; reg [5:0] retstate; reg [31:0] ir; wire [8:0] ir9 = {pg2,ir[7:0]}; reg [23:0] pc,opc; reg [15:0] dpr; // direct page register reg [7:0] dbr; // data bank register reg [15:0] x,y,acc,sp; reg [15:0] tmp; wire [15:0] acc16 = acc; wire [7:0] acc8=acc[7:0]; wire [7:0] x8=x[7:0]; wire [7:0] y8=y[7:0]; wire [15:0] x16 = x[15:0]; wire [15:0] y16 = y[15:0]; wire [15:0] acc_dec = acc - 16'd1; wire [15:0] acc_inc = acc + 16'd1; wire [15:0] x_dec = x - 16'd1; wire [15:0] x_inc = x + 16'd1; wire [15:0] y_dec = y - 16'd1; wire [15:0] y_inc = y + 16'd1; wire [15:0] sp_dec = sp - 16'd1; wire [15:0] sp_inc = sp + 16'd1; wire [15:0] sp_dec2 = sp - 16'd2; reg gie; // global interrupt enable (set when sp is loaded) reg hwi; // hardware interrupt indicator reg im; reg cf,vf,nf,zf,df,em,bf; reg m816; reg x_bit,m_bit; wire m16 = m816 & ~m_bit; wire xb16 = m816 & ~x_bit; wire [7:0] sr8 = m816 ? {nf,vf,m_bit,x_bit,df,im,zf,cf} : {nf,vf,1'b0,bf,df,im,zf,cf}; reg nmi1,nmi_edge; reg wai; reg [7:0] b8; reg [15:0] b16; reg [7:0] b24; reg [8:0] res8; reg [16:0] res16; wire resc8 = res8[8]; wire resc16 = res16[16]; wire resz8 = ~|res8[7:0]; wire resz16 = ~|res16[15:0]; wire resn8 = res8[7]; wire resn16 = res16[15]; reg [23:0] radr; reg [23:0] wadr; reg [23:0] wdat; wire [7:0] rdat; reg [4:0] load_what; reg [5:0] store_what; reg [15:0] tmp16; reg first_ifetch; reg [23:0] derr_address; reg [8:0] intno; reg isBusErr; reg isBrk,isMove,isSts; reg isMove816; reg isRTI,isRTL,isRTS; reg isRMW; reg isSub; reg isJsrIndx,isJsrInd; reg isIY,isIY24,isI24; reg isTribyte; wire isCmp = ir9==`CPX_ZPX || ir9==`CPX_ABS || ir9==`CPY_ZPX || ir9==`CPY_ABS; wire isRMW8 = ir9==`ASL_ZP || ir9==`ROL_ZP || ir9==`LSR_ZP || ir9==`ROR_ZP || ir9==`INC_ZP || ir9==`DEC_ZP || ir9==`ASL_ZPX || ir9==`ROL_ZPX || ir9==`LSR_ZPX || ir9==`ROR_ZPX || ir9==`INC_ZPX || ir9==`DEC_ZPX || ir9==`ASL_ABS || ir9==`ROL_ABS || ir9==`LSR_ABS || ir9==`ROR_ABS || ir9==`INC_ABS || ir9==`DEC_ABS || ir9==`ASL_ABSX || ir9==`ROL_ABSX || ir9==`LSR_ABSX || ir9==`ROR_ABSX || ir9==`INC_ABSX || ir9==`DEC_ABSX || ir9==`TRB_ZP || ir9==`TRB_ZPX || ir9==`TRB_ABS || ir9==`TSB_ZP || ir9==`TSB_ZPX || ir9==`TSB_ABS; wire isBranch = ir9==`BRA || ir9==`BEQ || ir9==`BNE || ir9==`BVS || ir9==`BVC || ir9==`BMI || ir9==`BPL || ir9==`BCS || ir9==`BCC; // Registerable decodes // The following decodes can be registered because they aren't needed until at least the cycle after // the DECODE stage. always @(posedge clk) if (state==RESET1) isBrk <= `TRUE; else if (state==DECODE1||state==DECODE2||state==DECODE3||state==DECODE4) begin isRMW <= isRMW8; isRTI <= ir9==`RTI; isRTL <= ir9==`RTL; isRTS <= ir9==`RTS; isBrk <= ir9==`BRK || ir9==`COP; isMove <= ir9==`MVP || ir9==`MVN; isJsrIndx <= ir9==`JSR_INDX; isJsrInd <= ir9==`JSR_IND; end assign mx = clk ? m_bit : x_bit; assign e = ~m816; wire [15:0] bcaio; wire [15:0] bcao; wire [15:0] bcsio; wire [15:0] bcso; wire bcaico,bcaco,bcsico,bcsco; wire bcaico8,bcaco8,bcsico8,bcsco8; `ifdef SUPPORT_BCD BCDAdd4 ubcdai1 (.ci(cf),.a(acc16),.b(ir[23:8]),.o(bcaio),.c(bcaico),.c8(bcaico8)); BCDAdd4 ubcda2 (.ci(cf),.a(acc16),.b(b8),.o(bcao),.c(bcaco),.c8(bcaco8)); BCDSub4 ubcdsi1 (.ci(cf),.a(acc16),.b(ir[23:8]),.o(bcsio),.c(bcsico),.c8(bcsico8)); BCDSub4 ubcds2 (.ci(cf),.a(acc16),.b(b8),.o(bcso),.c(bcsco),.c8(bcsco8)); `endif wire [7:0] dati = db; // Evaluate branches // reg takb; always @(ir9 or cf or vf or nf or zf) case(ir9) `BEQ: takb <= zf; `BNE: takb <= !zf; `BPL: takb <= !nf; `BMI: takb <= nf; `BCS: takb <= cf; `BCC: takb <= !cf; `BVS: takb <= vf; `BVC: takb <= !vf; `BRA: takb <= 1'b1; `BRL: takb <= 1'b1; default: takb <= 1'b0; endcase reg [23:0] ia; wire [23:0] mvnsrc_address = {ir[23:16],x16}; wire [23:0] mvndst_address = {ir[15: 8],y16}; wire [23:0] iapy8 = ia + y16; // Don't add in abs8, already included with ia wire [23:0] zp_address = {8'h00,ir[15:8]} + dpr; wire [23:0] zpx_address = {{16'h00,ir[15:8]} + x16} + dpr; wire [23:0] zpy_address = {{16'h00,ir[15:8]} + y16} + dpr; wire [23:0] abs_address = {dbr,ir[23:8]}; wire [23:0] absx_address = {dbr,ir[23:8] + x16}; // simulates 64k bank wrap-around wire [23:0] absy_address = {dbr,ir[23:8] + y16}; wire [23:0] al_address = {ir[31:8]}; wire [23:0] alx_address = {ir[31:8] + x16}; wire [23:0] dsp_address = m816 ? {8'h00,sp + ir[15:8]} : {16'h0001,sp[7:0]+ir[15:8]}; reg [23:0] vect; assign rw = be ? rwo : 1'bz; assign ad = be ? ado : {24{1'bz}}; assign dw = rwo ? {8{1'bz}} : be ? dbo : {8{1'bz}}; reg [31:0] phi11r,phi12r,phi81r,phi82r; assign phi11 = phi11r[31]; assign phi12 = phi12r[31]; assign phi81 = phi81r[31]; assign phi82 = phi82r[31]; always @(posedge clk) if (~rst) begin cyc <= 5'd0; phi11r <= 32'b01111111111111100000000000000000; phi12r <= 32'b00000000000000000111111111111110; phi81r <= 32'b01110000011100000111000001110000; phi82r <= 32'b00000111000001110000011100000111; end else begin cyc <= cyc + 5'd1; phi11r <= {phi11r[30:0],phi11r[31]}; phi12r <= {phi12r[30:0],phi12r[31]}; phi81r <= {phi81r[30:0],phi81r[31]}; phi82r <= {phi82r[30:0],phi82r[31]}; end // Detect a single byte opcode function isOneByte; input [7:0] ir; casex(ir) 8'hx8: isOneByte = TRUE; 8'hxA: isOneByte = TRUE; 8'hxB: isOneByte = TRUE; `RTI,`RTS: isOneByte = TRUE; default: isOneByte = FALSE; endcase endfunction // Detect double byte opcode function isTwoBytes; input [7:0] ir; input m16; input xb16; casex(ir) `BRK,`COP: isTwoBytes = TRUE; 8'hx1: isTwoBytes = TRUE; 8'hx3: isTwoBytes = TRUE; 8'hx5: isTwoBytes = TRUE; 8'hx6: isTwoBytes = TRUE; 8'hx7: isTwoBytes = TRUE; `BPL,`BMI,`BVS,`BVC,`BCS,`BCC,`BEQ,`BNE,`BRA: isTwoBytes = TRUE; `LDY_IMM,`CPY_IMM,`CPX_IMM,`LDX_IMM: isTwoBytes = !xb16; `ORA_I,`AND_I,`EOR_I,`LDA_I,`CMP_I,`STA_I,`ADC_I,`SBC_I,`PEI: isTwoBytes = TRUE; `REP,`SEP: isTwoBytes = TRUE; `TSB_ZPX,`TRB_ZPX,`BIT_ZP,`BIT_ZPX,`STZ_ZP,`STZ_ZPX,`STY_ZP,`STY_ZPX, `LDY_ZP,`LDY_ZPX,`CPY_ZP,`CPX_ZP: isTwoBytes = TRUE; `ORA_IMM,`AND_IMM,`EOR_IMM,`ADC_IMM,`SBC_IMM,`CMP_IMM,`LDA_IMM,`BIT_IMM: isTwoBytes = !m16; default: isTwoBytes = FALSE; endcase endfunction function isThreeBytes; input [7:0] ir; input m16; input xb16; casex(ir) `JSR: isThreeBytes = TRUE; `PER,`BRL: isThreeBytes = TRUE; `MVP,`MVN,`PEA: isThreeBytes = TRUE; `LDY_IMM,`CPY_IMM,`CPX_IMM,`LDX_IMM: isThreeBytes = xb16; `ORA_IMM,`AND_IMM,`EOR_IMM,`ADC_IMM,`SBC_IMM,`CMP_IMM,`LDA_IMM,`BIT_IMM: isThreeBytes = m16; 8'bxxx11001: isThreeBytes = TRUE; `TSB_ABS,`TRB_ABS,`BIT_ABS,`BIT_ABSX, `JMP,`JMP_IND,`JMP_INDX,`STY_ABS,`STZ_ABS,`LDY_ABS,`LDY_ABSX,`CPY_ABS, `CPX_ABS,`JSR_INDX: isThreeBytes = TRUE; 8'hxD,8'hxE: isThreeBytes = TRUE; default: isThreeBytes = FALSE; endcase endfunction //----------------------------------------------------------------------------- // Clock control // - reset or NMI reenables the clock // - this circuit must be under the clk_i domain //----------------------------------------------------------------------------- // reg cpu_clk_en; reg clk_en; wire clkx; //BUFGCE u20 (.CE(cpu_clk_en), .I(clk), .O(clkx) ); assign clkx = clk; assign clko = clkx; //assign clkx = clk; always @(posedge clk) if (~rst) begin cpu_clk_en <= 1'b1; nmi1 <= 1'b0; end else begin nmi1 <= nmi; if (nmi) cpu_clk_en <= 1'b1; else cpu_clk_en <= clk_en; end reg abort1; reg abort_edge; reg [2:0] imcd; // interrupt mask enable count down always @(posedge clkx) if (~rst) begin vpa <= `FALSE; vda <= `FALSE; vpb <= `TRUE; rwo <= `TRUE; ado <= 24'h000000; sp <= 16'h0001ff; // TODO dbo <= 8'h00; nmi_edge <= 1'b0; wai <= 1'b0; pg2 <= 1'b0; ir <= 8'hEA; cf <= 1'b0; df <= 1'b0; m816 <= 1'b0; m_bit <= 1'b1; x_bit <= 1'b1; pc <= 24'h00FFF0; // set high-order pc to zero vect <= `BYTE_RST_VECT; state <= RESET1; em <= 1'b1; dbr <= 8'h00; dpr <= 16'h0000; clk_en <= 1'b1; im <= `TRUE; gie <= 1'b0; isIY <= 1'b0; isIY24 <= 1'b0; isI24 <= `FALSE; load_what <= `NOTHING; abort_edge <= 1'b0; abort1 <= 1'b0; imcd <= 3'b111; end else begin abort1 <= abort; if (~abort & abort1) abort_edge <= 1'b1; if (~nmi & nmi1) nmi_edge <= 1'b1; if (~nmi|~nmi1) clk_en <= 1'b1; case(state) RESET1: begin radr <= `BYTE_RST_VECT; load_what <= `PC_70; state <= LOAD_MAC1; end IFETCH0: moveto_ifetch(); IFETCH1: if (rdy) begin if (imcd != 3'b111) imcd <= {imcd[1:0],1'b0}; if (imcd == 3'b000) begin imcd <= 3'b111; im <= 1'b0; end vect <= m816 ? `BRK_VECT_816 : `BYTE_IRQ_VECT; hwi <= `FALSE; isBusErr <= `FALSE; pg2 <= `FALSE; isIY <= `FALSE; isIY24 <= `FALSE; isTribyte <= `FALSE; store_what <= m16 ? `STW_DEF70 : `STW_DEF; ir[7:0] <= db; opc <= pc; if (nmi_edge | ~irq) wai <= 1'b0; if (abort_edge) begin pc <= opc; ir[7:0] <= `BRK; abort_edge <= 1'b0; hwi <= `TRUE; vect <= m816 ? `ABT_VECT_816 : `BYTE_ABT_VECT; vect[23:16] <= 8'h00; next_state(DECODE2); end else if (nmi_edge & gie) begin ir[7:0] <= `BRK; nmi_edge <= 1'b0; hwi <= `TRUE; vect <= m816 ? `NMI_VECT_816 : `BYTE_NMI_VECT; vect[23:16] <= 8'h00; next_state(DECODE2); end else if (~irq & gie & ~im) begin ir[7:0] <= `BRK; hwi <= `TRUE; if (m816) vect <= `IRQ_VECT_816; next_state(DECODE2); end else if (!wai) begin ado <= pc + 24'd1; pc <= pc + 24'd1; // Is it more than one byte ? if (!isOneByte(db)) begin vpa <= TRUE; next_state(IFETCH2); end else begin vpa <= FALSE; next_state(DECODE1); end vda <= FALSE; end else next_state(IFETCH1); if (!abort_edge) begin case(ir[7:0]) // Note the break flag is not affected by SEP/REP // Setting the index registers to eight bit zeros out the upper part of the register. `SEP: begin cf <= cf | ir[8]; zf <= zf | ir[9]; im <= im | ir[10]; df <= df | ir[11]; if (m816) begin x_bit <= x_bit | ir[12]; m_bit <= m_bit | ir[13]; //if (ir[13]) acc[31:8] <= 24'd0; if (ir[12]) begin x[15:8] <= 8'd0; y[15:8] <= 8'd0; end end vf <= vf | ir[14]; nf <= nf | ir[15]; end `REP: begin cf <= cf & ~ir[8]; zf <= zf & ~ir[9]; im <= im & ~ir[10]; df <= df & ~ir[11]; if (m816) begin x_bit <= x_bit & ~ir[12]; m_bit <= m_bit & ~ir[13]; end vf <= vf & ~ir[14]; nf <= nf & ~ir[15]; end `XBA: begin acc[15:0] <= res16[15:0]; nf <= resn8; zf <= resz8; end `TAY,`TXY,`DEY,`INY: if (xb16) begin y[15:0] <= res16[15:0]; nf <= resn16; zf <= resz16; end else begin y[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end `TAX,`TYX,`TSX,`DEX,`INX: if (xb16) begin x[15:0] <= res16[15:0]; nf <= resn16; zf <= resz16; end else begin x[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end `TSA,`TYA,`TXA,`INA,`DEA: if (m16) begin acc[15:0] <= res16[15:0]; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end `TAS,`TXS: begin if (m816) sp <= res16[15:0]; else sp <= {8'h01,res8[7:0]}; gie <= `TRUE; end `TCD: begin dpr <= res16[15:0]; end `TDC: begin acc[15:0] <= res16[15:0]; nf <= resn16; zf <= resz16; end `ADC_IMM: begin if (m16) begin acc[15:0] <= df ? bcaio : res16[15:0]; cf <= df ? bcaico : resc16; // vf <= resv8; vf <= (res16[15] ^ b16[15]) & (1'b1 ^ acc[15] ^ b16[15]); nf <= df ? bcaio[15] : resn16; zf <= df ? bcaio==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcaio[7:0] : res8[7:0]; cf <= df ? bcaico8 : resc8; // vf <= resv8; vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); nf <= df ? bcaio[7] : resn8; zf <= df ? bcaio[7:0]==8'h00 : resz8; end end `ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_IYL,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_I,`ADC_IL,`ADC_AL,`ADC_ALX,`ADC_DSP,`ADC_DSPIY: begin if (m16) begin acc[15:0] <= df ? bcao : res16[15:0]; cf <= df ? bcaco : resc16; vf <= (res16[15] ^ b16[15]) & (1'b1 ^ acc[15] ^ b16[15]); nf <= df ? bcao[15] : resn16; zf <= df ? bcao==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcao[7:0] : res8[7:0]; cf <= df ? bcaco8 : resc8; vf <= (res8[7] ^ b8[7]) & (1'b1 ^ acc[7] ^ b8[7]); nf <= df ? bcao[7] : resn8; zf <= df ? bcao[7:0]==8'h00 : resz8; end end `SBC_IMM: begin if (m16) begin acc[15:0] <= df ? bcsio : res16[15:0]; cf <= ~(df ? bcsico : resc16); vf <= (1'b1 ^ res16[15] ^ b16[15]) & (acc[15] ^ b16[15]); nf <= df ? bcsio[15] : resn16; zf <= df ? bcsio==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcsio[7:0] : res8[7:0]; cf <= ~(df ? bcsico8 : resc8); vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); nf <= df ? bcsio[7] : resn8; zf <= df ? bcsio[7:0]==8'h00 : resz8; end end `SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_IYL,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_I,`SBC_IL,`SBC_AL,`SBC_ALX,`SBC_DSP,`SBC_DSPIY: begin if (m16) begin acc[15:0] <= df ? bcso : res16[15:0]; vf <= (1'b1 ^ res16[15] ^ b16[15]) & (acc[15] ^ b16[15]); cf <= ~(df ? bcsco : resc16); nf <= df ? bcso[15] : resn16; zf <= df ? bcso==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcso[7:0] : res8[7:0]; vf <= (1'b1 ^ res8[7] ^ b8[7]) & (acc[7] ^ b8[7]); cf <= ~(df ? bcsco8 : resc8); nf <= df ? bcso[7] : resn8; zf <= df ? bcso[7:0]==8'h00 : resz8; end end `CMP_IMM,`CMP_ZP,`CMP_ZPX,`CMP_IX,`CMP_IY,`CMP_IYL,`CMP_ABS,`CMP_ABSX,`CMP_ABSY,`CMP_I,`CMP_IL,`CMP_AL,`CMP_ALX,`CMP_DSP,`CMP_DSPIY: if (m16) begin cf <= ~resc16; nf <= resn16; zf <= resz16; end else begin cf <= ~resc8; nf <= resn8; zf <= resz8; end `CPX_IMM,`CPX_ZP,`CPX_ABS, `CPY_IMM,`CPY_ZP,`CPY_ABS: if (xb16) begin cf <= ~resc16; nf <= resn16; zf <= resz16; end else begin cf <= ~resc8; nf <= resn8; zf <= resz8; end `BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX: if (m16) begin nf <= b16[15]; vf <= b16[14]; zf <= resz16; end else begin nf <= b8[7]; vf <= b8[6]; zf <= resz8; end `TRB_ZP,`TRB_ABS,`TSB_ZP,`TSB_ABS: if (m16) begin zf <= resz16; end else begin zf <= resz8; end `LDA_IMM,`LDA_ZP,`LDA_ZPX,`LDA_IX,`LDA_IY,`LDA_IYL,`LDA_ABS,`LDA_ABSX,`LDA_ABSY,`LDA_I,`LDA_IL,`LDA_AL,`LDA_ALX,`LDA_DSP,`LDA_DSPIY, `AND_IMM,`AND_ZP,`AND_ZPX,`AND_IX,`AND_IY,`AND_IYL,`AND_ABS,`AND_ABSX,`AND_ABSY,`AND_I,`AND_IL,`AND_AL,`AND_ALX,`AND_DSP,`AND_DSPIY, `ORA_IMM,`ORA_ZP,`ORA_ZPX,`ORA_IX,`ORA_IY,`ORA_IYL,`ORA_ABS,`ORA_ABSX,`ORA_ABSY,`ORA_I,`ORA_IL,`ORA_AL,`ORA_ALX,`ORA_DSP,`ORA_DSPIY, `EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_IYL,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_I,`EOR_IL,`EOR_AL,`EOR_ALX,`EOR_DSP,`EOR_DSPIY: if (m16) begin acc[15:0] <= res16[15:0]; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end `ASL_ACC: if (m16) begin acc[15:0] <= res16[15:0]; cf <= resc16; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end `ROL_ACC: if (m16) begin acc[15:0] <= res16[15:0]; cf <= resc16; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end `LSR_ACC: if (m16) begin acc[15:0] <= res16[15:0]; cf <= resc16; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end `ROR_ACC: if (m16) begin acc[15:0] <= res16[15:0]; cf <= resc16; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res8[7:0]; cf <= resc8; nf <= resn8; zf <= resz8; end `ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX: if (m16) begin cf <= resc16; nf <= resn16; zf <= resz16; end else begin cf <= resc8; nf <= resn8; zf <= resz8; end `ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX: if (m16) begin cf <= resc16; nf <= resn16; zf <= resz16; end else begin cf <= resc8; nf <= resn8; zf <= resz8; end `LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX: if (m16) begin cf <= resc16; nf <= resn16; zf <= resz16; end else begin cf <= resc8; nf <= resn8; zf <= resz8; end `ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX: if (m16) begin cf <= resc16; nf <= resn16; zf <= resz16; end else begin cf <= resc8; nf <= resn8; zf <= resz8; end `INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX: if (m16) begin nf <= resn16; zf <= resz16; end else begin nf <= resn8; zf <= resz8; end `DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX: if (m16) begin nf <= resn16; zf <= resz16; end else begin nf <= resn8; zf <= resz8; end `PLA: if (m16) begin acc[15:0] <= res16[15:0]; zf <= resz16; nf <= resn16; end else begin acc[7:0] <= res8[7:0]; zf <= resz8; nf <= resn8; end `PLX: if (xb16) begin x[15:0] <= res16[15:0]; zf <= resz16; nf <= resn16; end else begin x[7:0] <= res8[7:0]; zf <= resz8; nf <= resn8; end `PLY: if (xb16) begin y[15:0] <= res16[15:0]; zf <= resz16; nf <= resn16; end else begin y[7:0] <= res8[7:0]; zf <= resz8; nf <= resn8; end `PLB: begin dbr <= res8[7:0]; nf <= resn8; zf <= resz8; end `PLD: begin dpr <= res16[15:0]; nf <= resn16; zf <= resz16; end `LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: if (xb16) begin x[15:0] <= res16[15:0]; nf <= resn16; zf <= resz16; end else begin x[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end `LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: if (xb16) begin y[15:0] <= res16[15:0]; nf <= resn16; zf <= resz16; end else begin y[7:0] <= res8[7:0]; nf <= resn8; zf <= resz8; end endcase end // abort_edge end IFETCH2: if (rdy) begin ir[15:8] <= db; ado <= pc + 24'd1; pc <= pc + 24'd1; if ((isBranch && db==8'hFF && EXTRA_LONG_BRANCHES) || (!isTwoBytes(ir,m16,xb16))) begin vpa <= TRUE; next_state(IFETCH3); end else begin vpa <= FALSE; next_state(DECODE2); end vda <= FALSE; end IFETCH3: if (rdy) begin ir[23:16] <= db; ado <= pc + 24'd1; pc <= pc + 24'd1; if (!isThreeBytes(ir,m16,xb16)) begin vpa <= TRUE; next_state(IFETCH4); end else begin vpa <= FALSE; next_state(DECODE3); end vda <= FALSE; end IFETCH4: if (rdy) begin ir[31:24] <= db; ado <= pc + 24'd1; pc <= pc + 24'd1; next_state(DECODE4); vpa <= FALSE; vda <= FALSE; end // Decode single byte opcodes DECODE1: if (rdy) begin next_state(IFETCH1); opcode_read(); case(ir[7:0]) `SEP: ; // see byte_ifetch `REP: ; // XBA cannot be done in the ifetch stage because it'd repeat when there // was a cache miss, causing the instruction to be done twice. `XBA: begin res16 <= {acc[7:0],acc[15:8]}; res8 <= acc[15:8]; // for flag settings end `STP: begin clk_en <= 1'b0; end // Switching the processor mode always zeros out the upper part of the index registers. // switching to emulation mode sets 8 bit memory/indexes `XCE: begin m816 <= ~cf; cf <= ~m816; if (cf) begin m_bit <= 1'b1; x_bit <= 1'b1; sp[15:8] <= 8'h01; end x[15:8] <= 8'd0; y[15:8] <= 8'd0; end // `NOP: ; // may help routing `CLC: begin cf <= 1'b0; end `SEC: begin cf <= 1'b1; end `CLV: begin vf <= 1'b0; end `CLI: begin imcd <= 3'b110; end `SEI: begin im <= 1'b1; end `CLD: begin df <= 1'b0; end `SED: begin df <= 1'b1; end `WAI: begin wai <= 1'b1; end `DEX: begin res8 <= x_dec[7:0]; res16 <= x_dec[15:0]; end `INX: begin res8 <= x_inc[7:0]; res16 <= x_inc[15:0]; end `DEY: begin res8 <= y_dec[7:0]; res16 <= y_dec[15:0]; end `INY: begin res8 <= y_inc[7:0]; res16 <= y_inc[15:0]; end `DEA: begin res8 <= acc_dec[7:0]; res16 <= acc_dec[15:0]; end `INA: begin res8 <= acc_inc[7:0]; res16 <= acc_inc[15:0]; end `TSX,`TSA: begin res8 <= sp[7:0]; res16 <= sp[15:0]; end `TXS,`TXA,`TXY: begin res8 <= x[7:0]; res16 <= xb16 ? x[15:0] : {8'h00,x8}; end `TAX,`TAY: begin res8 <= acc[7:0]; res16 <= m16 ? acc[15:0] : {8'h00,acc8}; end `TAS: begin res8 <= acc[7:0]; res16 <= acc[15:0]; end `TYA,`TYX: begin res8 <= y[7:0]; res16 <= xb16 ? y[15:0] : {8'h00,y8}; end `TDC: begin res16 <= dpr; end `TCD: begin res16 <= acc[15:0]; end `ASL_ACC: begin res8 <= {acc8,1'b0}; res16 <= {acc16,1'b0}; end `ROL_ACC: begin res8 <= {acc8,cf}; res16 <= {acc16,cf}; end `LSR_ACC: begin res8 <= {acc8[0],1'b0,acc8[7:1]}; res16 <= {acc16[0],1'b0,acc16[15:1]}; end `ROR_ACC: begin res8 <= {acc8[0],cf,acc8[7:1]}; res16 <= {acc16[0],cf,acc16[15:1]}; end `RTS,`RTL: begin begin if (m816) begin radr <= {8'h00,sp_inc[15:0]}; sp <= sp_inc; end else begin radr <= {16'h0001,sp_inc[7:0]}; sp <= {8'h1,sp_inc[7:0]}; end end data_nack(); load_what <= `PC_70; state <= LOAD_MAC1; end `RTI: begin begin if (m816) begin radr <= {8'h00,sp_inc[15:0]}; sp <= sp_inc; end else begin radr <= {16'h0001,sp_inc[7:0]}; sp <= {8'h1,sp_inc[7:0]}; end end data_nack(); load_what <= `SR_70; state <= LOAD_MAC1; end `PHP: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end data_nack(); store_what <= `STW_SR70; state <= STORE1; end `PHA: begin if (m816) begin if (m16) begin radr <= {8'h00,sp_dec[15:0]}; wadr <= {8'h00,sp_dec[15:0]}; store_what <= `STW_ACC70; sp <= sp_dec2; end else begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; store_what <= `STW_ACC8; sp <= sp_dec; end end else begin radr <= {16'h01,sp[7:0]}; wadr <= {16'h01,sp[7:0]}; store_what <= `STW_ACC8; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end state <= STORE1; end // tsk_push(`STW_ACC8,`STW_ACC70,m16); `PHX: tsk_push(`STW_X8,`STW_X70,xb16); `PHY: tsk_push(`STW_Y8,`STW_Y70,xb16); `PLP: begin begin if (m816) begin radr <= {8'h00,sp_inc[15:0]}; sp <= sp_inc; end else begin radr <= {16'h0001,sp_inc[7:0]}; sp <= {8'h1,sp_inc[7:0]}; end end load_what <= `SR_70; data_nack(); state <= LOAD_MAC1; end `PLA: begin begin if (m816) begin radr <= {8'h00,sp_inc[15:0]}; sp <= sp_inc; end else begin radr <= {16'h0001,sp_inc[7:0]}; sp <= {8'h1,sp_inc[7:0]}; end end load_what <= m16 ? `HALF_71S : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `PLX,`PLY: begin begin if (m816) begin radr <= {8'h00,sp_inc[15:0]}; sp <= sp_inc; end else begin radr <= {16'h0001,sp_inc[7:0]}; sp <= {8'h1,sp_inc[7:0]}; end end load_what <= xb16 ? `HALF_71S : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `PHB: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end store_what <= `STW_DBR; data_nack(); state <= STORE1; end `PHD: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end store_what <= `STW_DPR158; data_nack(); state <= STORE1; end `PHK: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end store_what <= `STW_PC2316; data_nack(); state <= STORE1; end `PLB: begin begin if (m816) begin radr <= {8'h00,sp_inc[15:0]}; sp <= sp_inc; end else begin radr <= {16'h0001,sp_inc[7:0]}; sp <= {8'h1,sp_inc[7:0]}; end end load_what <= `BYTE_71; data_nack(); state <= LOAD_MAC1; end `PLD: begin begin if (m816) begin radr <= {8'h00,sp_inc[15:0]}; sp <= sp_inc; end else begin radr <= {16'h0001,sp_inc[7:0]}; sp <= {8'h1,sp_inc[7:0]}; end end load_what <= `HALF_71S; data_nack(); state <= LOAD_MAC1; end default: begin opcode_read(); next_state(IFETCH1); end endcase end // Decode 2-byte opcodes DECODE2: if (rdy) begin case(ir[7:0]) // Handle # mode `LDA_IMM: begin res8 <= ir[15:8]; opcode_read(); next_state(IFETCH1); end `LDX_IMM,`LDY_IMM: begin res8 <= ir[15:8]; opcode_read(); next_state(IFETCH1); end `ADC_IMM: begin res8 <= acc8 + ir[15:8] + {7'b0,cf}; b8 <= ir[15:8]; // for overflow calc opcode_read(); next_state(IFETCH1); end `SBC_IMM: begin res8 <= acc8 - ir[15:8] - {7'b0,~cf}; $display("sbc: %h= %h-%h-%h", acc8 - ir[15:8] - {7'b0,~cf},acc8,ir[15:8],~cf); b8 <= ir[15:8]; // for overflow calc opcode_read(); next_state(IFETCH1); end `AND_IMM,`BIT_IMM: begin res8 <= acc8 & ir[15:8]; b8 <= ir[15:8]; // for bit flags opcode_read(); next_state(IFETCH1); end `ORA_IMM: begin res8 <= acc8 | ir[15:8]; opcode_read(); next_state(IFETCH1); end `EOR_IMM: begin res8 <= acc8 ^ ir[15:8]; opcode_read(); next_state(IFETCH1); end `CMP_IMM: begin res8 <= acc8 - ir[15:8]; opcode_read(); next_state(IFETCH1); end `CPX_IMM: begin res8 <= x8 - ir[15:8]; opcode_read(); next_state(IFETCH1); end `CPY_IMM: begin res8 <= y8 - ir[15:8]; opcode_read(); next_state(IFETCH1); end // Handle zp mode `LDA_ZP: begin data_nack(); radr <= zp_address; load_what <= m16 ? `HALF_71 : `BYTE_71; state <= LOAD_MAC1; end `LDX_ZP,`LDY_ZP: begin radr <= zp_address; load_what <= xb16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `ADC_ZP,`SBC_ZP,`AND_ZP,`ORA_ZP,`EOR_ZP,`CMP_ZP, `BIT_ZP, `ASL_ZP,`ROL_ZP,`LSR_ZP,`ROR_ZP,`TRB_ZP,`TSB_ZP: begin radr <= zp_address; wadr <= zp_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `INC_ZP,`DEC_ZP: begin radr <= zp_address; wadr <= zp_address; isTribyte <= zp_address[23:4]==16'h2 && SUPPORT_TRIBYTES; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `CPX_ZP,`CPY_ZP: begin radr <= zp_address; load_what <= xb16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `STA_ZP: begin wadr <= zp_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end `STX_ZP: begin wadr <= zp_address; store_what <= xb16 ? `STW_X70 : `STW_X8; data_nack(); state <= STORE1; end `STY_ZP: begin wadr <= zp_address; store_what <= xb16 ? `STW_Y70 : `STW_Y8; data_nack(); state <= STORE1; end `STZ_ZP: begin wadr <= zp_address; store_what <= m16 ? `STW_Z70 : `STW_Z8; data_nack(); state <= STORE1; end // Handle zp,x mode `LDA_ZPX: begin radr <= zpx_address; load_what <= m16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `LDY_ZPX: begin radr <= zpx_address; load_what <= xb16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `ADC_ZPX,`SBC_ZPX,`AND_ZPX,`ORA_ZPX,`EOR_ZPX,`CMP_ZPX, `BIT_ZPX, `ASL_ZPX,`ROL_ZPX,`LSR_ZPX,`ROR_ZPX,`INC_ZPX,`DEC_ZPX: begin radr <= zpx_address; wadr <= zpx_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `STA_ZPX: begin wadr <= zpx_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end `STY_ZPX: begin wadr <= zpx_address; store_what <= xb16 ? `STW_Y70 : `STW_Y8; data_nack(); state <= STORE1; end `STZ_ZPX: begin wadr <= zpx_address; store_what <= m16 ? `STW_Z70 : `STW_Z8; data_nack(); state <= STORE1; end // Handle zp,y `LDX_ZPY: begin radr <= zpy_address; load_what <= xb16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `STX_ZPY: begin wadr <= zpy_address; store_what <= xb16 ? `STW_X70 : `STW_X8; data_nack(); state <= STORE1; end // Handle (zp,x) `ADC_IX,`SBC_IX,`AND_IX,`ORA_IX,`EOR_IX,`CMP_IX,`LDA_IX,`STA_IX: begin radr <= zpx_address; load_what <= `IA_70; data_nack(); state <= LOAD_MAC1; end // Handle (zp),y `ADC_IY,`SBC_IY,`AND_IY,`ORA_IY,`EOR_IY,`CMP_IY,`LDA_IY,`STA_IY: begin radr <= zp_address; isIY <= `TRUE; load_what <= `IA_70; data_nack(); state <= LOAD_MAC1; end // Handle d,sp `LDA_DSP: begin radr <= dsp_address; load_what <= m16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `ADC_DSP,`SBC_DSP,`CMP_DSP,`ORA_DSP,`AND_DSP,`EOR_DSP: begin radr <= dsp_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `STA_DSP: begin wadr <= dsp_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end // Handle (d,sp),y `ADC_DSPIY,`SBC_DSPIY,`CMP_DSPIY,`ORA_DSPIY,`AND_DSPIY,`EOR_DSPIY,`LDA_DSPIY,`STA_DSPIY: begin radr <= dsp_address; isIY <= `TRUE; load_what <= `IA_70; data_nack(); state <= LOAD_MAC1; end // Handle [zp],y `ADC_IYL,`SBC_IYL,`AND_IYL,`ORA_IYL,`EOR_IYL,`CMP_IYL,`LDA_IYL,`STA_IYL: begin radr <= zp_address; isIY24 <= `TRUE; load_what <= `IA_70; data_nack(); state <= LOAD_MAC1; end // Handle [zp] `ADC_IL,`SBC_IL,`AND_IL,`ORA_IL,`EOR_IL,`CMP_IL,`LDA_IL,`STA_IL: begin isI24 <= `TRUE; radr <= zp_address; load_what <= `IA_70; data_nack(); state <= LOAD_MAC1; end // Handle (zp) `ADC_I,`SBC_I,`AND_I,`ORA_I,`EOR_I,`CMP_I,`LDA_I,`STA_I,`PEI: begin radr <= zp_address; load_what <= `IA_70; data_nack(); state <= LOAD_MAC1; end `BRK: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end store_what <= m816 ? `STW_PC2316 : `STW_PC158;// `STW_PC3124; data_nack(); state <= STORE1; bf <= !hwi; end `COP: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end store_what <= m816 ? `STW_PC2316 : `STW_PC158;// `STW_PC3124; state <= STORE1; vect <= m816 ? `COP_VECT_816 : `BYTE_COP_VECT; data_nack(); end `BEQ,`BNE,`BPL,`BMI,`BCC,`BCS,`BVC,`BVS,`BRA: begin vpa <= `TRUE; vda <= `TRUE; if (takb) begin pc <= pc + {{16{ir[15]}},ir[15:8]}; ado <= pc + {{16{ir[15]}},ir[15:8]}; end next_state(IFETCH1); end //end default: begin opcode_read(); next_state(IFETCH1); end endcase end DECODE3: if (rdy) begin case(ir[7:0]) // Handle # mode `LDA_IMM: begin res16 <= ir[23:8]; opcode_read(); next_state(IFETCH1); end `LDX_IMM,`LDY_IMM: begin res16 <= ir[23:8]; opcode_read(); next_state(IFETCH1); end `ADC_IMM: begin res16 <= acc16 + ir[23:8] + {15'b0,cf}; b16 <= ir[23:8]; // for overflow calc opcode_read(); next_state(IFETCH1); end `SBC_IMM: begin res16 <= acc16 - ir[23:8] - {15'b0,~cf}; b16 <= ir[23:8]; // for overflow calc opcode_read(); next_state(IFETCH1); end `AND_IMM,`BIT_IMM: begin res16 <= acc16 & ir[23:8]; b16 <= ir[23:8]; // for bit flags opcode_read(); next_state(IFETCH1); end `ORA_IMM: begin res16 <= acc16 | ir[23:8]; opcode_read(); next_state(IFETCH1); end `EOR_IMM: begin res16 <= acc16 ^ ir[23:8]; opcode_read(); next_state(IFETCH1); end `CMP_IMM: begin res16 <= acc16 - ir[23:8]; opcode_read(); next_state(IFETCH1); end `CPX_IMM: begin res16 <= x16 - ir[23:8]; opcode_read(); next_state(IFETCH1); end `CPY_IMM: begin res16 <= y16 - ir[23:8]; opcode_read(); next_state(IFETCH1); end // Handle abs `LDA_ABS: begin radr <= abs_address; load_what <= m16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `LDX_ABS,`LDY_ABS: begin radr <= abs_address; load_what <= xb16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `ADC_ABS,`SBC_ABS,`AND_ABS,`ORA_ABS,`EOR_ABS,`CMP_ABS, `ASL_ABS,`ROL_ABS,`LSR_ABS,`ROR_ABS,`INC_ABS,`DEC_ABS,`TRB_ABS,`TSB_ABS, `BIT_ABS: begin radr <= abs_address; wadr <= abs_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `CPX_ABS,`CPY_ABS: begin radr <= abs_address; load_what <= xb16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `STA_ABS: begin wadr <= abs_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end `STX_ABS: begin wadr <= abs_address; store_what <= xb16 ? `STW_X70 : `STW_X8; data_nack(); state <= STORE1; end `STY_ABS: begin wadr <= abs_address; store_what <= xb16 ? `STW_Y70 : `STW_Y8; data_nack(); state <= STORE1; end `STZ_ABS: begin wadr <= abs_address; store_what <= m16 ? `STW_Z70 : `STW_Z8; data_nack(); state <= STORE1; end // Handle abs,x `LDA_ABSX: begin radr <= absx_address; load_what <= m16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `ADC_ABSX,`SBC_ABSX,`AND_ABSX,`ORA_ABSX,`EOR_ABSX,`CMP_ABSX, `ASL_ABSX,`ROL_ABSX,`LSR_ABSX,`ROR_ABSX,`INC_ABSX,`DEC_ABSX,`BIT_ABSX: begin radr <= absx_address; wadr <= absx_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `LDY_ABSX: begin radr <= absx_address; load_what <= xb16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `STA_ABSX: begin wadr <= absx_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end `STZ_ABSX: begin wadr <= absx_address; store_what <= m16 ? `STW_Z70 : `STW_Z8; data_nack(); state <= STORE1; end // Handle abs,y `LDA_ABSY: begin radr <= absy_address; load_what <= m16 ? `HALF_71 : `BYTE_71; state <= LOAD_MAC1; data_nack(); end `ADC_ABSY,`SBC_ABSY,`AND_ABSY,`ORA_ABSY,`EOR_ABSY,`CMP_ABSY: begin radr <= absy_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `LDX_ABSY: begin radr <= absy_address; load_what <= xb16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `STA_ABSY: begin wadr <= absy_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end `JMP: begin vpa <= `TRUE; vda <= `TRUE; pc[15:0] <= ir[23:8]; ado[15:0] <= ir[23:8]; next_state(IFETCH1); end `JMP_IND: begin radr <= abs_address; load_what <= `PC_70; data_nack(); state <= LOAD_MAC1; end `JMP_INDX: begin radr <= absx_address; load_what <= `PC_70; data_nack(); state <= LOAD_MAC1; end `JSR,`JSR_INDX: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end pc <= pc - 24'd1; store_what <= `STW_PC158; data_nack(); state <= STORE1; end `BRL: begin vpa <= `TRUE; vda <= `TRUE; pc <= pc + {{8{ir[23]}},ir[23:8]}; ado <= pc + {{8{ir[23]}},ir[23:8]}; next_state(IFETCH1); end `PEA: begin tmp16 <= ir[23:8]; begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end store_what <= `STW_TMP158; data_nack(); state <= STORE1; end `PER: begin tmp16 <= pc[15:0] + ir[23:8] + 16'd3; begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end store_what <= `STW_TMP158; data_nack(); state <= STORE1; end `MVN,`MVP: begin radr <= mvnsrc_address; load_what <= `BYTE_72; pc <= pc - 24'd3; // override increment above data_nack(); state <= LOAD_MAC1; end default: begin opcode_read(); next_state(IFETCH1); end endcase end DECODE4: if (rdy) begin first_ifetch <= `TRUE; next_state(IFETCH1); case(ir[7:0]) `WDM: if (ir[15:8]==`XCE) begin em <= 1'b0; next_state(IFETCH1); pc <= pc + 32'd2; end // Handle al `LDA_AL: begin radr <= al_address; load_what <= m16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `ADC_AL,`SBC_AL,`AND_AL,`ORA_AL,`EOR_AL,`CMP_AL: begin radr <= al_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `STA_AL: begin wadr <= al_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end // Handle alx `LDA_ALX: begin radr <= alx_address; load_what <= m16 ? `HALF_71 : `BYTE_71; data_nack(); state <= LOAD_MAC1; end `ADC_ALX,`SBC_ALX,`AND_ALX,`ORA_ALX,`EOR_ALX,`CMP_ALX: begin radr <= alx_address; load_what <= m16 ? `HALF_70 : `BYTE_70; data_nack(); state <= LOAD_MAC1; end `STA_ALX: begin wadr <= alx_address; store_what <= m16 ? `STW_ACC70 : `STW_ACC8; data_nack(); state <= STORE1; end `JML: begin vpa <= `TRUE; vda <= `TRUE; pc[23:0] <= ir[31:8]; ado[23:0] <= ir[31:8]; next_state(IFETCH1); end `JSL: begin begin if (m816) begin radr <= {8'h00,sp[15:0]}; wadr <= {8'h00,sp[15:0]}; sp <= sp_dec; end else begin radr <= {16'h0001,sp[7:0]}; wadr <= {16'h0001,sp[7:0]}; sp[7:0] <= sp[7:0] - 8'd1; sp[15:8] <= 8'h1; end end pc <= pc - 24'd1; store_what <= `STW_PC2316; data_nack(); state <= STORE1; end `BEQ,`BNE,`BPL,`BMI,`BCC,`BCS,`BVC,`BVS,`BRA: begin vpa <= `TRUE; vda <= `TRUE; if (takb) begin pc <= pc + {{8{ir[31]}},ir[31:16]}; ado <= pc + {{8{ir[31]}},ir[31:16]}; end next_state(IFETCH1); end default: begin opcode_read(); next_state(IFETCH1); end endcase end `include "load_mac.v" `include "store.v" //`include "half_calc.v" `include "byte_calc.v" HALF_CALC: begin moveto_ifetch(); store_what <= `STW_DEF70; case(ir[7:0]) `ADC_IMM,`ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_IYL,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_AL,`ADC_ALX,`ADC_I,`ADC_IL,`ADC_DSP,`ADC_DSPIY: begin res16 <= acc16 + b16 + {15'd0,cf}; end `SBC_IMM,`SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_IYL,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_AL,`SBC_ALX,`SBC_I,`SBC_IL,`SBC_DSP,`SBC_DSPIY: begin res16 <= acc16 - b16 - {15'd0,~cf}; end `CMP_IMM,`CMP_ZP,`CMP_ZPX,`CMP_IX,`CMP_IY,`CMP_IYL,`CMP_ABS,`CMP_ABSX,`CMP_ABSY,`CMP_AL,`CMP_ALX,`CMP_I,`CMP_IL,`CMP_DSP,`CMP_DSPIY: begin res16 <= acc16 - b16; end `AND_IMM,`AND_ZP,`AND_ZPX,`AND_IX,`AND_IY,`AND_IYL,`AND_ABS,`AND_ABSX,`AND_ABSY,`AND_AL,`AND_ALX,`AND_I,`AND_IL,`AND_DSP,`AND_DSPIY: begin res16 <= acc16 & b16; end `ORA_IMM,`ORA_ZP,`ORA_ZPX,`ORA_IX,`ORA_IY,`ORA_IYL,`ORA_ABS,`ORA_ABSX,`ORA_ABSY,`ORA_AL,`ORA_ALX,`ORA_I,`ORA_IL,`ORA_DSP,`ORA_DSPIY: begin res16 <= acc16 | b16; end `EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_IYL,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_AL,`EOR_ALX,`EOR_I,`EOR_IL,`EOR_DSP,`EOR_DSPIY: begin res16 <= acc16 ^ b16; end `LDA_IMM,`LDA_ZP,`LDA_ZPX,`LDA_IX,`LDA_IY,`LDA_IYL,`LDA_ABS,`LDA_ABSX,`LDA_ABSY,`LDA_AL,`LDA_ALX,`LDA_I,`LDA_IL,`LDA_DSP,`LDA_DSPIY: begin res16 <= b16; end `BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX: begin res16 <= acc16 & b16; end `TRB_ZP,`TRB_ABS: begin res16 <= acc16 & b16; wdat <= ~acc16 & b16; state <= STORE1; data_nack(); end `TSB_ZP,`TSB_ABS: begin res16 <= acc16 & b16; wdat <= acc16 | b16; state <= STORE1; data_nack(); end `LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: begin res16 <= b16; end `LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: begin res16 <= b16; end `CPX_IMM,`CPX_ZP,`CPX_ABS: begin res16 <= x16 - b16; end `CPY_IMM,`CPY_ZP,`CPY_ABS: begin res16 <= y16 - b16; end `ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX: begin res16 <= {b16,1'b0}; wdat <= {b16[14:0],1'b0}; state <= STORE1; data_nack(); end `ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX: begin res16 <= {b16,cf}; wdat <= {b16[14:0],cf}; state <= STORE1; data_nack(); end `LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX: begin res16 <= {b16[0],1'b0,b16[15:1]}; wdat <= {1'b0,b16[15:1]}; state <= STORE1; data_nack(); end `ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX: begin res16 <= {b16[0],cf,b16[15:1]}; wdat <= {cf,b16[15:1]}; state <= STORE1; data_nack(); end `INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX: begin res16 <= {b24,b16} + 24'd1; wdat <= {{b24,b16}+24'd1}; state <= STORE1; data_nack(); end `DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX: begin res16 <= {b24,b16} - 24'd1; wdat <= {{b24,b16}-24'd1}; state <= STORE1; data_nack(); end endcase end MVN816: begin moveto_ifetch(); if (&acc[15:0]) begin pc <= pc + 24'd3; ado <= pc + 24'd3; dbr <= ir[15:8]; end end endcase end `include "bus_task.v" `include "misc_task.v" task next_state; input [5:0] nxt; begin state <= nxt; end endtask function [127:0] fnStateName; input [5:0] state; case(state) RESET1: fnStateName = "RESET1 "; IFETCH1: fnStateName = "IFETCH1 "; IFETCH2: fnStateName = "IFETCH2 "; IFETCH3: fnStateName = "IFETCH3 "; IFETCH4: fnStateName = "IFETCH4 "; STORE1: fnStateName = "STORE1 "; STORE2: fnStateName = "STORE2 "; RTS1: fnStateName = "RTS1 "; IY3: fnStateName = "IY3 "; BYTE_IX5: fnStateName = "BYTE_IX5 "; BYTE_IY5: fnStateName = "BYTE_IY5 "; DECODE1: fnStateName = "DECODE1 "; DECODE2: fnStateName = "DECODE2 "; DECODE3: fnStateName = "DECODE3 "; DECODE4: fnStateName = "DECODE4 "; BYTE_CALC: fnStateName = "BYTE_CALC "; BUS_ERROR: fnStateName = "BUS_ERROR "; LOAD_MAC1: fnStateName = "LOAD_MAC1 "; LOAD_MAC2: fnStateName = "LOAD_MAC2 "; LOAD_MAC3: fnStateName = "LOAD_MAC3 "; MVN3: fnStateName = "MVN3 "; LOAD_DCACHE: fnStateName = "LOAD_DCACHE"; LOAD_ICACHE: fnStateName = "LOAD_ICACHE"; LOAD_IBUF1: fnStateName = "LOAD_IBUF1 "; LOAD_IBUF2: fnStateName = "LOAD_IBUF2 "; LOAD_IBUF3: fnStateName = "LOAD_IBUF3 "; ICACHE1: fnStateName = "ICACHE1 "; IBUF1: fnStateName = "IBUF1 "; DCACHE1: fnStateName = "DCACHE1 "; HALF_CALC: fnStateName = "HALF_CALC "; MVN816: fnStateName = "MVN816 "; default: fnStateName = "UNKNOWN "; endcase endfunction endmodule