`timescale 1ns / 1ps // ============================================================================ // __ // \\__/ o\ (C) 2013-2017 Robert Finch, Waterloo // \ __ / All rights reserved. // \/_// robfinch@finitron.ca // || // // FT832.v // - 8/16/32 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 . // // Approx 10561 LUTs (16900 LC's) // 9 block rams // ============================================================================ // `define TRUE 1'b1 `define FALSE 1'b0 `define DEBUG 1'b1 // Comment out the SUPPORT_xxx definitions to remove a core feature. `define SUPPORT_TASK 1'b1 `define TASK_MEM 4096 `define TASK_MEM_ABIT 11 //`define TASK_BL 1'b1 // core uses back link register rather than stack `define SUPPORT_SEG 1'b1 `define ICACHE_4K 1'b1 //`define ICACHE_16K 1'b1 //`define ICACHE_2WAY 1'b1 `define SUPPORT_BCD 1'b1 //`define SUPPORT_CGI 1'b1 // support the control giveaway interrupt `define SUPPORT_NEW_INSN 1'b1 `define SUPPORT_INTMD 1'b1 `define BYTE_RST_VECT 32'h0000FFFC `define BYTE_NMI_VECT 32'h0000FFFA `define BYTE_IRQ_VECT 32'h0000FFFE `define BYTE_ABT_VECT 32'h0000FFF8 `define BYTE_COP_VECT 32'h0000FFF4 `define RST_VECT_816 32'h0000FFFC `define IRQ_VECT_816 32'h0000FFEE `define NMI_VECT_816 32'h0000FFEA `define ABT_VECT_816 32'h0000FFE8 `define BRK_VECT_816 32'h0000FFE6 `define COP_VECT_816 32'h0000FFE4 `define IRQ2_VECT 32'h0000FFE2 `define IRQ3_VECT 32'h0000FFE0 `define RST_VECT_832 32'h0000FFFC `define IRQ_VECT_832 32'h0000FFDE `define NMI_VECT_832 32'h0000FFDA `define ABT_VECT_832 32'h0000FFD8 `define BRK_VECT_832 32'h0000FFD6 `define COP_VECT_832 32'h0000FFD4 `define ADV_VECT_832 32'h0000FFD2 // address violation `define BRK 9'h00 `define BRK2 9'h100 `define RTI 9'h40 `define RTIC 9'h150 `define RTS 9'h60 `define PHP 9'h08 `define CLC 9'h18 `define CMC 9'h118 `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 SEI_IMM 9'h178 `define DEY 9'h88 `define DEY4 9'h188 `define TYA 9'h98 `define TAY 9'hA8 `define CLV 9'hB8 `define SEV 9'h1B8 `define INY 9'hC8 `define INY4 9'h1C8 `define CLD 9'hD8 `define INX 9'hE8 `define INX4 9'h1E8 `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 DEX4 9'h1CA `define NOP 9'hEA `define NOP2 9'h1EA `define TXY 9'h9B `define TYX 9'hBB `define TAS 9'h1B `define TSA 9'h3B `define TCD 9'h5B `define TDC 9'h7B `define STP 9'hDB `define XCE 9'hFB `define INA 9'h1A `define DEA 9'h3A `define SEP 9'hE2 `define SEP16 9'h1E2 `define REP 9'hC2 `define REP16 9'h1C2 `define PEA 9'hF4 `define PEI 9'hD4 `define PER 9'h62 `define WDM 9'h42 `define PEAxl 9'h1F4 `define CS 9'h11B `define SS 9'h16A `define SEG 9'h13B `define SEG0 9'h15B `define IOS 9'h17B `define PHDS 9'h10B `define PLDS 9'h12B `define PHCS 9'h14B `define PCHIST 9'h1F0 `define CACHE 9'h1E0 `define BYT 9'h18B `define UBT 9'h19B `define HAF 9'h1AB `define UHF 9'h1BB `define WRD 9'h19A `define INF 9'h14A `define AAX 9'h18A `define RA 9'h1F8 `define CR 9'h1D8 `define TASS 9'h15A `define TSSA 9'h17A `define SDU 9'h1BA `define LLA 9'h1FA `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 ADC_XDSPIY 9'h173 `define ADC_XIYL 9'h177 `define ADC_XIL 9'h167 `define ADC_XABS 9'h16D `define ADC_XABSX 9'h17D `define ADC_XABSY 9'h179 `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 SBC_XDSPIY 9'h1F3 `define SBC_XIYL 9'h1F7 `define SBC_XIL 9'h1E7 `define SBC_XABS 9'h1ED `define SBC_XABSX 9'h1FD `define SBC_XABSY 9'h1F9 `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 CMP_XDSPIY 9'h1D3 `define CMP_XIYL 8'h1D7 `define CMP_XIL 9'h1C7 `define CMP_XABS 9'h1CD `define CMP_XABSX 9'h1DD `define CMP_XABSY 9'h1D9 `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 AND_XDSPIY 9'h133 `define AND_XIL 9'h127 `define AND_XIYL 9'h137 `define AND_XABS 9'h12D `define AND_XABSX 9'h13D `define AND_XABSY 9'h139 `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 ORA_XDSPIY 9'h113 `define ORA_XIL 9'h107 `define ORA_XIYL 9'h117 `define ORA_XABS 9'h10D `define ORA_XABSX 9'h11D `define ORA_XABSY 9'h119 `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 EOR_XDSPIY 9'h153 `define EOR_XIL 9'h147 `define EOR_XIYL 9'h157 `define EOR_XABS 9'h14D `define EOR_XABSX 9'h15D `define EOR_XABSY 9'h159 //`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 LDA_XDSPIY 9'h1B3 `define LDA_XIL 9'h1A7 `define LDA_XIYL 9'h1B7 `define LDA_XABS 9'h1AD `define LDA_XABSX 9'h1BD `define LDA_XABSY 9'h1B9 `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 STA_XDSPIY 9'h193 `define STA_XIL 9'h187 `define STA_XIYL 9'h197 `define STA_XABS 9'h18D `define STA_XABSX 9'h19D `define STA_XABSY 9'h199 `define ASL_ACC 9'h0A `define ASR_ACC 9'h10A `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 ASL_XABS 9'h10E `define ASL_XABSX 9'h11E `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 ROL_XABS 9'h12E `define ROL_XABSX 9'h13E `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 LSR_XABS 9'h14E `define LSR_XABSX 9'h15E `define ROR_ZP 9'h66 `define ROR_ZPX 9'h76 `define ROR_ABS 9'h6E `define ROR_ABSX 9'h7E `define ROR_XABS 9'h16E `define ROR_XABSX 9'h17E `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 DEC_XABS 9'h1CE `define DEC_XABSX 9'h1DE `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 INC_XABS 9'h1EE `define INC_XABSX 9'h1FE `define INC_IMM 9'h1E9 `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 `define BIT_XABS 9'h12C `define BIT_XABSX 9'h13C // 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 BGT 9'h110 `define BLE 8'h1B0 `define JML 9'h5C `define JML_IND 9'hDC `define JML_XIND 9'h1DC `define JMF 9'h15C `define JMP 9'h4C `define JMP_IND 9'h6C `define JMP_INDX 9'h7C `define JML_XINDX 9'h17C `define JSR 9'h20 `define JSL 9'h22 `define JSL_XINDX 9'h1FC `define JSF 9'h122 `define JSR_INDX 9'hFC `define RTS 9'h60 `define RTT 9'h160 `define RTL 9'h6B `define RTF 9'h16B `define NOP 9'hEA `define NOP2 9'h1EA `define RTS_IMM 9'h1C0 `define RTL_IMM 9'h168 `define BSR 9'h128 `define BSL 9'h148 `define PLX 9'hFA `define PLY 9'h7A `define PHX 9'hDA `define PHY 9'h5A `define WAI 9'hCB `define PHB 9'h8B `define PHD 9'h0B `define PHK 9'h4B `define XBA 9'hEB `define XBAW 9'h1EB `define COP 9'h02 `define PLB 9'hAB `define PLD 9'h2B `define MUL 9'h12A `define FAR 9'h1DA `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_XABS 9'h1AE `define LDX_XABSY 9'h1BE `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 LDY_XABS 9'h1AC `define LDY_XABSX 9'h1BC `define STX_ZP 9'h86 `define STX_ZPX 9'h96 `define STX_ZPY 9'h96 `define STX_ABS 9'h8E `define STX_XABS 9'h18E `define STY_ZP 9'h84 `define STY_ZPX 9'h94 `define STY_ABS 9'h8C `define STY_XABS 9'h18C `define STZ_ZP 9'h64 `define STZ_ZPX 9'h74 `define STZ_ABS 9'h9C `define STZ_ABSX 9'h9E `define STZ_XABS 9'h19C `define STZ_XABSX 9'h19E `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 CPX_XABS 9'h1EC `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 CPY_XABS 9'h1CC `define TRB_ZP 9'h14 `define TRB_ABS 9'h1C `define TRB_XABS 9'h11C `define TSB_ZP 9'h04 `define TSB_ABS 9'h0C `define TSB_XABS 9'h10C `define BMT_XABS 9'h114 `define BMS_XABS 9'h124 `define BMC_XABS 9'h134 `define MVP 9'h44 `define MVN 9'h54 `define FILL 9'h144 `define TSK_IMM 9'h1A2 `define TSK_ACC 9'h13A `define LDT_XABSX 9'h14C `define LDT_XABS 9'h16C `define FORK_IMM 9'h1A0 `define FORK_ACC 9'h1AA `define TTA 9'h11A `define TASB 9'h19A `define TSBA 9'h1BA `define JCR 9'h120 `define JCL 9'h182 `define JCF 9'h162 `define RTC 9'h140 `define JCI 9'h180 `define TJ 9'h1CB // Page Two Opcodes `define PG2 9'h42 `define NOTHING 6'd0 `define SR_70 6'd1 `define SR_158 6'd2 `define WORD_310 6'd4 `define PC_70 6'd5 `define PC_158 6'd6 `define PC_2316 6'd7 `define LDW_SEG70 6'd8 `define LDW_SEG158 6'd9 `define WORD_311 6'd10 `define IA_310 6'd11 `define IA_70 6'd12 `define IA_158 6'd13 `define WORD_312 6'd15 `define WORD_313 6'd16 `define WORD_314 6'd17 `define IA_2316 6'd18 `define BYTE_72 6'd25 `define TRIP_2316 6'd26 `define WORD_71S 6'd27 `define LOAD_70 6'd28 `define LOAD_158 6'd29 `define LOAD_2316 6'd30 `define LOAD_3124 6'd31 `define WORD_159S 6'd36 `define WORD_2317S 6'd37 `define WORD_3125S 6'd38 `define IA_3124 6'd39 `define CS_70 6'd40 `define CS_158 6'd41 `define CS_2316 6'd42 `define CS_3124 6'd43 `define LDW_TR70 6'd44 `define LDW_TR158 6'd45 `define CPY_BUF 6'd46 `define LDW_TR70S 6'd47 `define LDW_TR158S 6'd48 `define STW_DEF 6'h1 `define STW_SR158 6'd2 `define STW_CS3124 6'd4 `define STW_CS2316 6'd5 `define STW_CS158 6'd6 `define STW_CS70 6'd7 `define STW_DS3124 6'd8 `define STW_DS2316 6'd9 `define STW_DS158 6'd10 `define STW_DS70 6'd11 `define STW_ACC3124 6'd12 `define STW_ACC2316 6'd13 `define STW_RES8 6'd14 `define STW_TR70 6'd15 `define STW_TR158 6'd16 `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_DEF3124 6'd29 `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 `define STW_X3124 6'd48 `define STW_X2316 6'd49 `define STW_Y3124 6'd50 `define STW_Y2316 6'd51 `define STW_Z3124 6'd52 `define STW_Z2316 6'd53 `define STW_IA2316 6'd54 `define STW_IA3124 6'd55 `define STW_TMP3124 6'd56 `define STW_TMP2316 6'd57 `define STW_CPY_BUF 6'd58 // Input Frequency is 32 times the 00 clock module FT832(corenum, rst, clk, clko, cyc, phi11, phi12, phi81, phi82, nmi, irq1, irq2, irq3, abort, e, mx, rdy, be, vpa, vda, mlb, vpb, rw, ad, db, err_i, rty_i); parameter STORE_SKIPPING = 1'b1; // set to 1 to skip the store operation if the value didn't change during a RMW instruction parameter EXTRA_LONG_BRANCHES = 1'b1; // set to 1 to use an illegal branch displacement ($FF) to indicate a long branch parameter IO_SEGMENT = 32'hFFD00000; // set to determine the segment value of the IOS: prefix parameter PC24 = 1'b0; // set if PC is to be true 24 bits (generates slightly more hardware). parameter POPBF = 1'b0; // set to 1 if popping the break flag from the stack is desired parameter TASK_VECTORING = 1'b0; // controls whether the core uses task vectors or regular interrupt vectors //parameter DEAD_CYCLE = 1'b1; // insert dead cycles between each memory access // There parameters are not meant to be altered. parameter RESET1 = 6'd0; parameter IFETCH = 6'd1; parameter LDT1 = 6'd2; parameter TSK1 = 6'd3; parameter TSK2 = 6'd4; parameter DECODE = 6'd5; parameter INF1 = 6'd6; parameter SSM1 = 6'd7; parameter TSK3 = 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 TSK4 = 6'd18; parameter BUS_ERROR = 6'd19; parameter LOAD_MAC1 = 6'd20; parameter LOAD_MAC2 = 6'd21; parameter LOAD_MAC3 = 6'd22; 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 SEG1 = 6'd34; parameter MVN816 = 6'd36; parameter JMF1 = 6'd37; parameter PLDS1 = 6'd38; parameter PLDS2 = 6'd39; parameter TASS1 = 6'd40; parameter ICACHE2 = 6'd43; parameter CALC = 6'd44; parameter ICACHE3 = 6'd45; parameter PBDELAY = 6'd46; parameter JCR1 = 6'd47; parameter SEGF_NONE = 6'd0; parameter SEGF_EXEC = 6'd1; parameter SEGF_WRITE = 6'd2; parameter SEGF_BOUND = 6'd3; parameter PRES_NONE = 7'h00; parameter PRES_ACC = 7'h08; parameter PRES_X = 7'h04; parameter PRES_Y = 7'h02; parameter PRES_P = 7'h01; parameter PRES_PC = 7'h10; parameter PRES_CS = 7'h40; parameter PRES_BACKLINK = 7'h20; parameter PRES_ALL = 7'h7F; localparam PRES_FAXY = PRES_ACC | PRES_X | PRES_Y | PRES_P; input [31:0] corenum; input rst; input clk; output clko; output reg [4:0] cyc; output phi11; output phi12; output phi81; output phi82; input nmi; input irq1; input irq2; input irq3; 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 [31:0] ad; inout tri [7:0] db; input err_i; input rty_i; parameter TRUE = 1'b1; parameter FALSE = 1'b0; reg [31:0] phi1r,phi2r; reg [31:0] ado1; wire cs_pgmap; wire [7:0] pgo; wire [12:0] pc_page; reg pgr, ivda; always @(posedge clk) pgr <= cs_pgmap; wire pgmap_rdy = cs_pgmap ? pgr : 1'b1; wire irdy = rdy;// & pgmap_rdy; reg rwo; reg [7:0] dbo; reg [31:0] ado; reg pg2; reg [5:0] state; // machine state number reg [5:0] retstate; // return state - allows 1 level of state subroutine call reg [7:0] cnt; // icache counter / general counter reg [7:0] maxcnt; reg [127:0] ir; // the instruction register wire [8:0] ir9 = {pg2,ir[7:0]}; // The first byte of the instruction reg [23:0] pc,opc,npc; wire [28:0] mapped_pc = {pc_page,pc[15:0]}; reg pc_cap; // pc history capture flag `ifdef SUPPORT_SEG reg [15:0] ds; // data segment reg [15:0] cs; // code segment reg [15:0] ss; // stack segment reg [31:0] cs_base, cs_limit; reg [31:0] ds_base, ds_limit; reg [31:0] ss_base, ss_limit; reg ds_wr; // data segment is writable reg ss_wr; // writability of stack segment reg cs_wr; // writability of code segment reg mem_wr; // memory is writable reg [31:0] lmt; // segment limit reg [3:0] seg_fault_val; wire [31:0] cspc = cs_base + pc; `else wire [31:0] cspc = pc; reg [3:0] seg_fault_val = 0; `endif reg [15:0] dpr; // direct page register reg [7:0] dbr; // data bank register reg [31:0] x,y,acc,sp; // programming model registers reg [23:0] stack_page = 24'd1; // The default stack page for eight bit emulation reg [15:0] stack_bank = 16'd0; // The default stack bank for sixteen bit emulation reg [1:0] stksz; // size of stack 00=256,01=4095,10=65536,11=16777216 reg [15:0] tmp; wire [15:0] acc16 = acc[15:0]; // convenience wires 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] sp16 = sp[15:0]; wire [31:0] acc_dec = acc - 32'd1; wire [31:0] acc_inc = acc + 32'd1; wire [31:0] x_dec = x - 32'd1; wire [31:0] x_inc = x + 32'd1; wire [31:0] y_dec = y - 32'd1; wire [31:0] y_inc = y + 32'd1; reg gie; // global interrupt enable (set when sp is loaded) reg hwi; // hardware interrupt indicator reg [2:0] iml,iml1; wire im = |iml; reg [2:0] irqenc; reg [15:0] ima; reg its; // interrupt task switch bit reg cf,vf,nf,zf,df,em,bf; reg m816,m832; reg x_bit,m_bit; reg m16,m32; reg xb16,xb32; reg mxb16,mxb32; reg mib; reg ssm; reg [2:0] tmsp [0:511]; integer n; initial begin for (n = 0; n < 512; n = n + 2) tmsp[n] <= 0; end wire DEAD_CYCLE = FALSE;//(vda|vpa) && ado >= 32'h10000; //wire m16 = m816 & ~m_bit; //wire xb16 = m816 & ~x_bit; always @(m816,m832,m_bit,x_bit) begin case ({~m832,~m816,m_bit,x_bit}) 4'b0000: begin m32 = `FALSE; m16 = `TRUE; xb32 = `TRUE; xb16 = `FALSE; end 4'b0001: begin m32 = `FALSE; m16 = `TRUE; xb32 = `FALSE; xb16 = `FALSE; end 4'b0010: begin m32 = `FALSE; m16 = `FALSE; xb32 = `TRUE; xb16 = `FALSE; end 4'b0011: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end 4'b0100: begin m32 = `TRUE; m16 = `FALSE; xb32 = `TRUE; xb16 = `FALSE; end 4'b0101: begin m32 = `TRUE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end 4'b0110: begin m32 = `FALSE; m16 = `FALSE; xb32 = `TRUE; xb16 = `FALSE; end 4'b0111: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end 4'b1000: begin m32 = `FALSE; m16 = `TRUE; xb32 = `FALSE; xb16 = `TRUE; end 4'b1001: begin m32 = `FALSE; m16 = `TRUE; xb32 = `FALSE; xb16 = `FALSE; end 4'b1010: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `TRUE; end 4'b1011: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end 4'b1100: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end 4'b1101: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end 4'b1110: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end 4'b1111: begin m32 = `FALSE; m16 = `FALSE; xb32 = `FALSE; xb16 = `FALSE; end endcase end wire [31:0] acc32 = m32 ? acc : m16 ? {16'h0000,acc[15:0]} : {24'h000000,acc[7:0]}; // for multiply wire [31:0] x32 = xb32 ? x : xb16 ? {16'h0000,x[15:0]} : {24'h000000,x[7:0]}; wire [31:0] y32 = xb32 ? y : xb16 ? {16'h0000,y[15:0]} : {24'h000000,y[7:0]}; wire [7:0] sr8 = (m816|m832) ? {nf,vf,m_bit,x_bit,df,im,zf,cf} : {nf,vf,1'b0,bf,df,im,zf,cf}; wire [7:0] srx = {3'b0,ssm,1'b0,mib,m832,m816}; reg nmi1,nmi_edge; reg wai; reg [31:0] a32,b32; wire [15:0] b16 = b32[15:0]; wire [7:0] b8 = b32[7:0]; reg [32:0] res32; reg [63:0] prod64; wire resc8 = res32[8]; wire resc16 = res32[16]; wire resc32 = res32[32]; wire resz8 = res32[7:0]==8'h00; wire resz16 = res32[15:0]==16'h0000; wire resz32 = res32[31:0]==32'd0; wire resn8 = res32[7]; wire resn16 = res32[15]; wire resn32 = res32[31]; reg [31:0] radr; reg [31:0] wadr; reg [31:0] wdat; wire [7:0] rdat; reg [5:0] load_what; reg [5:0] store_what; reg [15:0] temp_vec; reg s8,s16,s32,lds; reg sop; // size override prefix reg [31:0] tmp32; reg first_ifetch; reg [31:0] derr_address; reg [8:0] intno; reg isBusErr; reg isBrk,isMove,isSts; reg isMove816; reg isFar = 0; reg isRTI,isRTL,isRTS,isRTF; reg isRMW; reg isSub; reg isJmpi; reg isJsrIndx,isJsrInd,isJLInd; reg isIY,isIY24,isI24,isIY32,isI32; reg isDspiy,isStaiy; reg tj_prefix; reg lla; wire isCmp = ir9==`CPX_ZPX || ir9==`CPX_ABS || ir9==`CPX_XABS || ir9==`CPY_ZPX || ir9==`CPY_ABS || ir9==`CPY_XABS; 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==`ASL_XABS || ir9==`ROL_XABS || ir9==`LSR_XABS || ir9==`ROR_XABS || ir9==`INC_XABS || ir9==`DEC_XABS || ir9==`ASL_XABSX || ir9==`ROL_XABSX || ir9==`LSR_XABSX || ir9==`ROR_XABSX || ir9==`INC_XABSX || ir9==`DEC_XABSX || ir9==`TRB_ZP || ir9==`TRB_ABS || ir9==`TSB_ZP || ir9==`TSB_ABS || ir9==`TRB_XABS || ir9==`TSB_XABS ; wire isBranch = ir9==`BRA || ir9==`BEQ || ir9==`BNE || ir9==`BVS || ir9==`BVC || ir9==`BMI || ir9==`BPL || ir9==`BCS || ir9==`BCC || ir9==`BGT || ir9==`BLE; // This function needed to make the processor adhere to the page and bank // wrapping characteristics of the 65xx. The stack will wrap around within // page 1 for eight bit emulation, and within bank 0 for 16 bit emulation. // Direct page addressimg wraps around within bank 0 for 16 bit emulation. reg bank_wrap; reg page_wrap; function [31:0] inc_adr; input [31:0] adr; begin if (page_wrap) inc_adr = {adr[31:8],adr[7:0] + 8'd1}; else if (bank_wrap) inc_adr = {adr[31:16],adr[15:0] + 16'd1}; else inc_adr = adr + 32'd1; end endfunction // Instruction cache. // The cache is organized as 256 lines of 16 bytes each, for a total of // 4kB. The processor has access to a window of 16 bytes into the cache // from the current program counter. reg wr_icache; wire [127:0] insn; ft832_icachemem uicm1 ( .wclk(clk), .wce(rdy), .wr(vpa&wr_icache), .wa(ado[11:0]), .i(db), .rclk(~clk), .rce(1'b1), .pc(cspc[11:0]), .insn(insn) ); reg inv_icache; reg wr_itag; wire hit0,hit1; reg prc_hit0,prc_hit1; reg inv_iline; ft832_itagmem uitm1 ( .wclk(clk), .wce(1'b1), .wr(wr_itag), .wa(ado1), .invalidate(inv_icache), .invalidate_line(inv_iline), .rclk(~clk), .rce(1'b1), .pc(cspc), .hit0(hit0), .hit1(hit1) ); `ifdef SUPPORT_TASK reg [`TASK_MEM_ABIT-3:0] tr, otr, trh; reg [7:0] tsk_pres; // register value preservation flags reg tskm_we; reg tskm_wr; reg [`TASK_MEM_ABIT-3:0] tskm_wa; wire [15:0] cs_o; wire [15:0] ds_o; wire [15:0] ss_o; wire [23:0] pc_o; wire [31:0] acc_o; wire [31:0] x_o; wire [31:0] y_o; wire [31:0] sp_o; wire [7:0] sr_o; wire [7:0] srx_o; wire [7:0] dbr_o; wire [15:0] dpr_o; wire [5:0] mapno_o; wire [`TASK_MEM_ABIT-3:0] bl_o; reg [15:0] cs_i; reg [15:0] ds_i; reg [15:0] ss_i; reg [23:0] pc_i; reg [31:0] acc_i; reg [31:0] x_i; reg [31:0] y_i; reg [31:0] sp_i; reg [7:0] sr_i; reg [7:0] srx_i; reg [7:0] dbr_i; reg [15:0] dpr_i; reg [5:0] mapno_i; reg [`TASK_MEM_ABIT-3:0] bl_i; reg [`TASK_MEM_ABIT-3:0] back_link; task_mem utskm1 ( .wclk(clk), .wce(tskm_we), .wr(tskm_wr), .wa({tmsp[tskm_wa],tskm_wa}), .cs_i(cs_i), .ds_i(ds_i), .ss_i(ss_i), .pc_i(pc_i), .acc_i(acc_i), .x_i(x_i), .y_i(y_i), .sp_i(sp_i), .sr_i(sr_i), .srx_i(srx_i), .db_i(dbr_i), .dpr_i(dpr_i), .bl_i(bl_i), .mapno_i(mapno_i), .rclk(~clk), .rce(1'b1), .ra({tmsp[tr],tr}), .cs_o(cs_o), .ds_o(ds_o), .ss_o(ss_o), .pc_o(pc_o), .acc_o(acc_o), .x_o(x_o), .y_o(y_o), .sp_o(sp_o), .sr_o(sr_o), .srx_o(srx_o), .db_o(dbr_o), .dpr_o(dpr_o), .bl_o(bl_o), .mapno_o(mapno_o) ); `endif `ifdef SUPPORT_SEG reg wr_sdt; reg [11:0] sdt_wa; reg [11:0] sdt_ra; reg [7:0] acr_i; reg [3:0] size_i; reg [31:0] base_i; wire [7:0] acr_o; wire [3:0] size_o; wire [31:0] base_o; SegDescTbl usdt1 ( .wclk(clk), .wce(1'b1), .wr(wr_sdt), .wa(sdt_wa), .acr_i(acr_i), .size_i(size_i), .base_i(base_i), .rclk(~clk), .rce(1'b1), .ra(sdt_ra), .acr_o(acr_o), .size_o(size_o), .base_o(base_o) ); `endif reg [5:0] mapno; /* ProgramMappingTbl upmap1 ( .clk(clk), .wr(cs_pgmap & ~rwo), .wadr(ado[14:0]), .wdat(dbo), .rdat(pgo), .omapno(mapno), .pb(cspc[23:16]), .page(pc_page) ); */ reg [7:0] cpybuf [63:0]; // stack copy buffer // 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==DECODE) begin isRMW <= isRMW8; isRTI <= ir9==`RTI; isRTL <= ir9==`RTL || ir9==`RTL_IMM; isRTS <= ir9==`RTS || ir9==`RTS_IMM; isRTF <= ir9==`RTF; isBrk <= ir9==`BRK || ir9==`COP; isMove <= ir9==`MVP || ir9==`MVN; isJsrIndx <= ir9==`JSR_INDX; isJmpi <= ir9==`JMP_IND || ir9==`JMP_INDX; isJLInd <= ir9==`JML_IND || ir9==`JML_XIND || ir9==`JSL_XINDX || ir9==`JML_XINDX; isDspiy <= ir9[4:0]==5'h13; isStaiy <= ir9==`STA_IY || ir9==`STA_IYL || ir9==`STA_XIYL || ir9==`STA_DSPIY || ir9==`STA_XDSPIY; end assign mx = clk ? m_bit : x_bit; assign e = ~(m816|m832); 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 function carry; input op; // 0=add,1=sub input a; input b; input s; begin carry = op? (~a&b)|(s&~a)|(s&b) : (a&b)|(a&~s)|(b&~s); end endfunction wire [7:0] dati = db;//cs_pgmap ? pgo : 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; `BGT: takb <= !nf & !zf;//(nf & vf & !zf) | (!nf & !vf & !zf); //`BGE: takb <= !nf;//(nf & vf) | (!nf & !vf); `BLE: takb <= zf | nf;//zf | (nf & !vf) | (!nf & vf); //`BLT: takb <= nf;//(nf & !vf) | (!nf & vf); default: takb <= 1'b0; endcase // Address generation reg [7:0] mvndst_bank; reg [7:0] mvnsrc_bank; reg [31:0] seg; reg [31:0] ia; wire [15:0] dpr_zp = {16'h00,ir[15:8]} + dpr; wire [15:0] dpr_zpx = {{16'h00,ir[15:8]} + x32} + dpr; wire [15:0] dpr_zpy = {{16'h00,ir[15:8]} + y32} + dpr; wire [31:0] dpr_zp32 = {16'h00,ir[15:8]} + dpr; wire [31:0] dpr_zpx32 = {{16'h00,ir[15:8]} + x32} + dpr; wire [31:0] dpr_zpy32 = {{16'h00,ir[15:8]} + y32} + dpr; wire [31:0] mvnsrc_address = m832 ? x32 : {8'h00,ir[23:16],x32[15:0]}; wire [31:0] mvndst_address = m832 ? y32 : {8'h00,ir[15:8],y32[15:0]}; wire [31:0] iapy8 = ia + y32; // Don't add in abs8, already included with ia wire [31:0] zp_address = (m832 ? dpr_zp32 : dpr_zp); wire [31:0] zpx_address = (m832 ? dpr_zpx32 : dpr_zpx); wire [31:0] zpy_address = (m832 ? dpr_zpy32 : dpr_zpy); wire [31:0] abs_address = {8'h00,dbr,ir[23:8]}; wire [31:0] absx_address = m832 ? {8'h00,dbr,ir[23:8]} + x32 : {8'h00,dbr,ir[23:8] + x16} ; // simulates 64k bank wrap-around wire [31:0] absy_address = m832 ? {8'h00,dbr,ir[23:8]} + y32 : {8'h00,dbr,ir[23:8] + y16} ; wire [31:0] al_address = {8'h00,ir[31:8]}; wire [31:0] alx_address = {8'h00,ir[31:8]} + x32; wire [31:0] xal_address = ir[39:8]; wire [31:0] xalx_address = ir[39:8] + x32; wire [31:0] xaly_address = ir[39:8] + y32; wire [31:0] dsp_address = m832 ? sp + ir[15:8] : m816 ? {stack_bank,sp16 + ir[15:8]} : {stack_page,sp[7:0]+ir[15:8]}; reg [31:0] vect; assign cs_pgmap = 1'b0;//ivda && (ado[31:16]==16'h0002); assign rw = be ? rwo|cs_pgmap : 1'bz; assign ad = be ? ado : {32{1'bz}}; assign db = rwo ? {8{1'bz}} : be ? dbo : {8{1'bz}}; wire [23:0] pc_hist_o; vtdl #(.WID(24),.DEP(64)) pc_hist_buf ( .clk(clk), .ce(state==IFETCH && hit0 && hit1 && pc_cap), .a(x[5:0]), .d(pc), .q(pc_hist_o) ); /* c_shift_ram_0 pc_hist_buf ( .A(x[5:0]), // input wire [5 : 0] A .D({8'h00,pc}), // input wire [31 : 0] D .CLK(clk), // input wire CLK .CE(state==IFETCH && hit0 && hit1 && pc_cap), // input wire CE .Q(pc_hist_o) // output wire [31 : 0] Q ); */ 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 //----------------------------------------------------------------------------- // Clock control // - reset or NMI reenables the clock // - this circuit must be under the clk_i domain //----------------------------------------------------------------------------- // //wire clkx = clk; //assign clko = clkx; reg clk_en; reg cpu_clk_en; wire clkx; BUFGCE u20 (.CE(cpu_clk_en), .I(clk), .O(clkx) ); 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 isRstVect; reg abort1; reg abort_edge; reg [2:0] imcd; // interrupt mask enable count down always @* if (~irq3) irqenc <= 3'b011; else if (~irq2) irqenc <= 3'b010; else if (~irq1) irqenc <= 3'b001; else irqenc <= 3'b000; always @(posedge clkx) if (~rst) begin vpa <= `FALSE; vda <= `FALSE; ivda <= `FALSE; vpb <= `TRUE; rwo <= `TRUE; ado <= 32'h000000; 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; m832 <= 1'b0; m_bit <= 1'b1; x_bit <= 1'b1; vect <= `BYTE_RST_VECT; state <= RESET1; em <= 1'b1; pc <= 24'h00FFF0; // set high-order pc to zero `ifdef SUPPORT_SEG cs <= 16'd0; ds <= 16'd0; ss <= 16'd0; cs_base <= 32'd0; ds_base <= 32'd0; ss_base <= 32'd0; cs_limit <= 32'hFFFFFFFF; ds_limit <= 32'hFFFFFFFF; ss_limit <= 32'hFFFFFFFF; ds_wr <= TRUE; ss_wr <= TRUE; cs_wr <= FALSE; wr_sdt <= FALSE; `endif dpr <= 16'h0000; dbr <= 8'h00; acc <= 32'h0; x <= 32'h0; y <= 32'h0; sp <= 32'h1FF; stack_page <= 24'h000001; stack_bank <= 16'h0000; clk_en <= 1'b1; iml <= 3'b000; imcd <= 3'b111; ima <= 16'h0000; mib <= `FALSE; gie <= 1'b0; isIY <= 1'b0; isIY24 <= 1'b0; isI24 <= `FALSE; load_what <= `NOTHING; abort_edge <= 1'b0; abort1 <= 1'b0; inv_icache <= TRUE; inv_iline <= FALSE; pc_cap <= TRUE; tr <= 8'h00; tskm_we <= FALSE; tskm_wr <= FALSE; ssm <= FALSE; tj_prefix <= FALSE; seg_fault_val = SEGF_NONE; lla <= FALSE; isRstVect <= `TRUE; mapno <= 6'd0; 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; inv_iline <= FALSE; `ifdef SUPPORT_TASK tskm_we <= FALSE; tskm_wr <= FALSE; `endif wr_itag <= FALSE; `ifdef SUPPORT_SEG wr_sdt <= FALSE; `endif case(state) RESET1: begin radr <= `BYTE_RST_VECT; load_what <= `PC_70; `ifdef SUPPORT_SEG cs <= 16'd0; ds <= 16'd0; ss <= 16'd0; cs_base <= 32'd0; ds_base <= 32'd0; ss_base <= 32'd0; cs_limit <= 32'hFFFFFFFF; ds_limit <= 32'hFFFFFFFF; ss_limit <= 32'hFFFFFFFF; ds_wr <= TRUE; seg <= 32'd0; lmt <= 32'hFFFF; mem_wr <= TRUE; `endif first_ifetch <= TRUE; inv_icache <= FALSE; state <= LOAD_MAC1; end IFETCH: begin vda <= FALSE; if (hit0&hit1) begin vect <= m832 ? `BRK_VECT_832 : m816 ? `BRK_VECT_816 : `BYTE_IRQ_VECT; hwi <= `FALSE; isBusErr <= `FALSE; pg2 <= FALSE; isFar <= `FALSE; isIY <= `FALSE; isIY24 <= `FALSE; isIY32 <= `FALSE; isI24 <= `FALSE; isI32 <= `FALSE; lla <= `FALSE; s8 <= FALSE; s16 <= FALSE; s32 <= FALSE; lds <= FALSE; sop <= FALSE; tj_prefix <= FALSE; bank_wrap <= FALSE; page_wrap <= FALSE; `ifdef SUPPORT_SEG seg <= ds_base; lmt <= ds_limit; mem_wr <= ds_wr; seg_fault_val = SEGF_NONE; `endif store_what <= (m32 | m16) ? `STW_DEF70 : `STW_DEF; ir <= insn; opc <= pc; if (nmi_edge | ~irq1 | ~irq2 | ~irq3) wai <= 1'b0; if (abort_edge) begin pc <= opc; iml1 <= 3'd7; ir[7:0] <= `BRK; abort_edge <= 1'b0; hwi <= `TRUE; vect <= m832 ? `ABT_VECT_832 : m816 ? `ABT_VECT_816 : `BYTE_ABT_VECT; vect[23:16] <= 8'h00; seg <= 32'd0; lmt <= 32'hFFFF; mem_wr <= FALSE; next_state(DECODE); end else if (nmi_edge & gie) begin iml1 <= 3'd7; ir[7:0] <= `BRK; nmi_edge <= 1'b0; hwi <= `TRUE; vect <= m832 ? `NMI_VECT_832 : m816 ? `NMI_VECT_816 : `BYTE_NMI_VECT; vect[23:16] <= 8'h00; next_state(DECODE); end else if ((irqenc > iml) && gie) begin iml1 <= irqenc; ir[7:0] <= `BRK; hwi <= `TRUE; case(irqenc) 3'b010: vect <= `IRQ2_VECT; 3'b011: vect <= `IRQ3_VECT; default: // 001 if (m832) vect <= `IRQ_VECT_832; else if (m816) vect <= `IRQ_VECT_816; endcase next_state(DECODE); end `ifdef SUPPORT_SEG else if (pc > cs_limit) begin iml1 <= 3'd7; ir[7:0] <= `BRK; hwi <= `TRUE; if (m832) vect <= `IRQ_VECT_832; else if (m816) vect <= `IRQ_VECT_816; seg <= 32'd0; lmt <= 32'hFFFF; mem_wr <= FALSE; next_state(DECODE); seg_fault_val <= SEGF_BOUND; end `endif else if (!wai) begin `ifdef SUPPORT_INTMD if (mib) begin set_task_regs(m832 ? 24'd4 : m816 ? 24'd2 : 24'd1); case({m832,m816}) 2'd0: acc <= insn[7:0]; 2'd1: acc <= insn[15:0]; 2'd2: acc <= insn[31:0]; 2'd3: acc <= insn[31:0]; endcase x <= pc; tsk_pres <= 7'h0C; tr <= back_link; retstate <= IFETCH; next_state(TSK1); end else `endif next_state(DECODE); end else next_state(IFETCH); if (!abort_edge) begin case(ir9) // 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]; if (ir[10]) iml <= 3'd1; df <= df | ir[11]; if (m816|m832) 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[31:8] <= 24'd0; y[31:8] <= 24'd0; end end vf <= vf | ir[14]; nf <= nf | ir[15]; end `REP: begin cf <= cf & ~ir[8]; zf <= zf & ~ir[9]; if (ir[10]) iml <= 3'd0; df <= df & ~ir[11]; if (m816|m832) begin x_bit <= x_bit & ~ir[12]; m_bit <= m_bit & ~ir[13]; end vf <= vf & ~ir[14]; nf <= nf & ~ir[15]; end `ifdef SUPPORT_NEW_INSN `SEP16: begin cf <= cf | ir[8]; zf <= zf | ir[9]; if (ir[10]) iml <= 3'd1; df <= df | ir[11]; if (m816|m832) 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[31:8] <= 24'd0; y[31:8] <= 24'd0; end end vf <= vf | ir[14]; nf <= nf | ir[15]; m816 <= m816 | ir[16]; m832 <= m832 | ir[17]; mib <= mib | ir[18]; ssm <= ssm | ir[20]; end `REP16: begin cf <= cf & ~ir[8]; zf <= zf & ~ir[9]; if (ir[10]) iml <= 3'd0; df <= df & ~ir[11]; if (m816|m832) begin x_bit <= x_bit & ~ir[12]; m_bit <= m_bit & ~ir[13]; end vf <= vf & ~ir[14]; nf <= nf & ~ir[15]; m816 <= m816 & ~ir[16]; m832 <= m832 & ~ir[17]; mib <= mib & ~ir[18]; ssm <= ssm & ~ir[20]; end `INF: begin acc <= res32; nf <= resn32; zf <= resz32; end `endif `XBA: begin acc[15:0] <= res32[15:0]; nf <= resn8; zf <= resz8; end `ifdef SUPPORT_NEW_INSN `XBAW: begin acc <= res32; nf <= resn16; zf <= resz16; end `AAX: begin if (m32) begin acc <= res32; zf <= resz32; nf <= resn32; vf <= (res32[31] ^ b32[31]) & (1'b1 ^ a32[31] ^ b32[31]); cf <= carry(0,a32[31],b32[31],res32[31]); end else if (m16) begin acc[15:0] <= res32[15:0]; zf <= resz16; nf <= resn16; vf <= (res32[15] ^ b32[15]) & (1'b1 ^ a32[15] ^ b32[15]); cf <= carry(0,a32[15],b32[15],res32[15]); end else begin acc[7:0] <= res32[7:0]; zf <= resz8; nf <= resn8; vf <= (res32[7] ^ b32[7]) & (1'b1 ^ a32[7] ^ b32[7]); cf <= carry(0,a32[7],b32[7],res32[7]); end end `endif `LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX,`LDY_XABS,`LDY_XABSX, `TAY,`TXY,`DEY,`INY,`INY4,`DEY4,`PLY: begin if (xb32) begin y <= res32; nf <= resn32; zf <= resz32; end else if (xb16) begin y <= {16'h0000,res32[15:0]}; nf <= resn16; zf <= resz16; end else begin y <= {24'h000000,res32[7:0]}; nf <= resn8; zf <= resz8; end end `LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY,`LDX_XABS,`LDX_XABSY, `TAX,`TYX,`TSX,`DEX,`INX,`INX4,`DEX4,`PLX: begin if (xb32) begin x <= res32; nf <= resn32; zf <= resz32; end else if (xb16) begin x <= {16'h0000,res32[15:0]}; nf <= resn16; zf <= resz16; end else begin x <= {24'h000000,res32[7:0]}; nf <= resn8; zf <= resz8; end end `TTA: begin if (m32) begin acc <= res32; nf <= resn16; zf <= resz16; end else if (m16) begin acc[15:0] <= res32[15:0]; nf <= resn16; zf <= resz16; end else begin acc[15:0] <= res32[15:0]; nf <= resn16; zf <= resz16; end end `ifdef SUPPORT_SEG `TASS: ss <= res32[15:0]; `TSSA, `endif `TSA,`TYA,`TXA,`INA,`DEA,`PLA: begin if (m32) begin acc <= res32; nf <= resn32; zf <= resz32; end else if (m16) begin acc[15:0] <= {acc[31:16],res32[15:0]}; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= {acc[31:8],res32[7:0]}; nf <= resn8; zf <= resz8; end end `PCHIST: acc <= res32; `TAS,`TXS: begin if (m832) sp <= res32; else if (m816) sp <= {stack_bank,res32[15:0]}; else sp <= {stack_page,res32[7:0]}; gie <= `TRUE; end `TCD: begin dpr <= res32[15:0]; end `TDC: begin acc <= {16'h0000,res32[15:0]}; nf <= resn16; zf <= resz16; end `ADC_IMM: begin if (m32) begin acc <= df ? bcaio : res32; cf <= df ? bcaico : carry(0,a32[31],b32[31],res32[31]); // vf <= resv8; vf <= (res32[31] ^ b32[31]) & (1'b1 ^ a32[31] ^ b32[31]); nf <= df ? bcaio[15] : resn32; zf <= df ? bcaio==16'h0000 : resz32; end else if (m16) begin acc[15:0] <= df ? bcaio : res32[15:0]; cf <= df ? bcaico : carry(0,a32[15],b32[15],res32[15]);; // vf <= resv8; vf <= (res32[15] ^ b32[15]) & (1'b1 ^ a32[15] ^ b32[15]); nf <= df ? bcaio[15] : resn16; zf <= df ? bcaio==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcaio[7:0] : res32[7:0]; cf <= df ? bcaico8 : carry(0,a32[7],b32[7],res32[7]); // vf <= resv8; vf <= (res32[7] ^ b32[7]) & (1'b1 ^ a32[7] ^ b32[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, `ADC_XABS,`ADC_XABSX,`ADC_XABSY,`ADC_XIYL,`ADC_XIL,`ADC_XDSPIY: begin if (m32) begin acc <= df ? bcao : res32; cf <= df ? bcaco : carry(0,a32[31],b32[31],res32[31]); vf <= (res32[31] ^ b32[31]) & (1'b1 ^ a32[31] ^ b32[31]); nf <= df ? bcao[15] : resn32; zf <= df ? bcao==16'h0000 : resz32; end else if (m16) begin acc[15:0] <= df ? bcao : res32[15:0]; cf <= df ? bcaco : carry(0,a32[15],b32[15],res32[15]); vf <= (res32[15] ^ b32[15]) & (1'b1 ^ a32[15] ^ b32[15]); nf <= df ? bcao[15] : resn16; zf <= df ? bcao==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcao[7:0] : res32[7:0]; cf <= df ? bcaco8 : carry(0,a32[7],b32[7],res32[7]); vf <= (res32[7] ^ b32[7]) & (1'b1 ^ a32[7] ^ b32[7]); nf <= df ? bcao[7] : resn8; zf <= df ? bcao[7:0]==8'h00 : resz8; end end `SBC_IMM: begin if (m32) begin acc <= df ? bcsio : res32; cf <= ~(df ? bcsico : carry(1,a32[31],b32[31],res32[31])); vf <= (1'b1 ^ res32[31] ^ b32[31]) & (a32[31] ^ b32[31]); nf <= df ? bcsio[15] : resn32; zf <= df ? bcsio==16'h0000 : resz32; end else if (m16) begin acc[15:0] <= df ? bcsio : res32[15:0]; cf <= ~(df ? bcsico : carry(1,a32[15],b32[15],res32[15])); vf <= (1'b1 ^ res32[15] ^ b32[15]) & (a32[15] ^ b32[15]); nf <= df ? bcsio[15] : resn16; zf <= df ? bcsio==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcsio[7:0] : res32[7:0]; cf <= ~(df ? bcsico8 : carry(1,a32[7],b32[7],res32[7])); vf <= (1'b1 ^ res32[7] ^ b32[7]) & (a32[7] ^ b32[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, `SBC_XABS,`SBC_XABSX,`SBC_XABSY,`SBC_XIYL,`SBC_XIL,`SBC_XDSPIY: begin if (m32) begin acc <= df ? bcso : res32; vf <= (1'b1 ^ res32[31] ^ b32[31]) & (a32[31] ^ b32[31]); cf <= ~(df ? bcsco : carry(1,a32[31],b32[31],res32[31])); nf <= df ? bcso[15] : resn32; zf <= df ? bcso==16'h0000 : resz32; end else if (m16) begin acc[15:0] <= df ? bcso : res32[15:0]; vf <= (1'b1 ^ res32[15] ^ b32[15]) & (a32[15] ^ b32[15]); cf <= ~(df ? bcsco : carry(1,a32[15],b32[15],res32[15])); nf <= df ? bcso[15] : resn16; zf <= df ? bcso==16'h0000 : resz16; end else begin acc[7:0] <= df ? bcso[7:0] : res32[7:0]; vf <= (1'b1 ^ res32[7] ^ b32[7]) & (a32[7] ^ b32[7]); cf <= ~(df ? bcsco8 : carry(1,a32[7],b32[7],res32[7])); 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, `CMP_XABS,`CMP_XABSX,`CMP_XABSY,`CMP_XIYL,`CMP_XIL,`CMP_XDSPIY: if (m32) begin cf <= ~carry(1,a32[31],b32[31],res32[31]); nf <= resn32; zf <= resz32; end else if (m16) begin cf <= ~carry(1,a32[15],b32[15],res32[15]); nf <= resn16; zf <= resz16; end else begin cf <= ~carry(1,a32[7],b32[7],res32[7]); nf <= resn8; zf <= resz8; end `CPX_IMM,`CPX_ZP,`CPX_ABS,`CPX_XABS: if (xb32) begin cf <= ~carry(1,a32[31],b32[31],res32[31]); nf <= resn32; zf <= resz32; end else if (xb16) begin cf <= ~carry(1,a32[15],b32[15],res32[15]); nf <= resn16; zf <= resz16; end else begin cf <= ~carry(1,a32[7],b32[7],res32[7]); nf <= resn8; zf <= resz8; end `CPY_IMM,`CPY_ZP,`CPY_ABS,`CPY_XABS: if (xb32) begin cf <= ~carry(1,a32[31],b32[31],res32[31]); nf <= resn32; zf <= resz32; end else if (xb16) begin cf <= ~carry(1,a32[15],b32[15],res32[15]); nf <= resn16; zf <= resz16; end else begin cf <= ~carry(1,a32[7],b32[7],res32[7]); nf <= resn8; zf <= resz8; end `BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX,`BIT_XABS,`BIT_XABSX: if (m32) begin nf <= b32[31]; vf <= b32[30]; zf <= resz32; end else if (m16) begin nf <= b32[15]; vf <= b32[14]; zf <= resz16; end else begin nf <= b32[7]; vf <= b32[6]; zf <= resz8; end `TRB_ZP,`TRB_ABS,`TSB_ZP,`TSB_ABS,`TRB_XABS,`TSB_XABS: if (m32) begin zf <= resz32; end else if (m16) begin zf <= resz16; end else begin zf <= resz8; end `BMT_XABS,`BMS_XABS,`BMC_XABS: begin zf <= resz8; nf <= resn8; 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, `LDA_XABS,`LDA_XABSX,`LDA_XABSY,`LDA_XIYL,`LDA_XIL,`LDA_XDSPIY, `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, `AND_XABS,`AND_XABSX,`AND_XABSY,`AND_XIYL,`AND_XIL,`AND_XDSPIY, `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, `ORA_XABS,`ORA_XABSX,`ORA_XABSY,`ORA_XIYL,`ORA_XIL,`ORA_XDSPIY, `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, `ORA_XABS,`ORA_XABSX,`ORA_XABSY,`ORA_XIYL,`ORA_XIL,`ORA_XDSPIY: if (m32) begin acc <= res32; nf <= resn32; zf <= resz32; end else if (m16) begin acc[15:0] <= res32[15:0]; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res32[7:0]; nf <= resn8; zf <= resz8; end `ASR_ACC: if (m32) begin acc <= res32; cf <= a32[0]; nf <= resn32; zf <= resz32; end else if (m16) begin acc[15:0] <= res32[15:0]; cf <= a32[0]; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res32[7:0]; cf <= a32[0]; nf <= resn8; zf <= resz8; end `ASL_ACC, `ROL_ACC: if (m32) begin acc <= res32; cf <= res32[32]; nf <= resn32; zf <= resz32; end else if (m16) begin acc[15:0] <= res32[15:0]; cf <= res32[16]; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res32[7:0]; cf <= res32[8]; nf <= resn8; zf <= resz8; end `LSR_ACC, `ROR_ACC: if (m32) begin acc <= res32; cf <= res32[32]; nf <= resn32; zf <= resz32; end else if (m16) begin acc[15:0] <= res32[15:0]; cf <= res32[32]; nf <= resn16; zf <= resz16; end else begin acc[7:0] <= res32[7:0]; cf <= res32[32]; nf <= resn8; zf <= resz8; end `ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX,`ASL_XABS,`ASL_XABSX, `ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX,`ROL_XABS,`ROL_XABSX: if (m32) begin cf <= b32[31]; nf <= resn32; zf <= resz32; end else if (m16) begin cf <= b32[15]; nf <= resn16; zf <= resz16; end else begin cf <= b32[7]; nf <= resn8; zf <= resz8; end `LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX,`LSR_XABS,`LSR_XABSX, `ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX,`ROR_XABS,`ROR_XABSX: if (m32) begin cf <= b32[0]; nf <= resn32; zf <= resz32; end else if (m16) begin cf <= b32[0]; nf <= resn16; zf <= resz16; end else begin cf <= b32[0]; nf <= resn8; zf <= resz8; end `INC_IMM, `INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX,`INC_XABS,`INC_XABSX, `DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX,`DEC_XABS,`DEC_XABSX: if (m32) begin nf <= resn32; zf <= resz32; end else if (m16) begin nf <= resn16; zf <= resz16; end else begin nf <= resn8; zf <= resz8; end `PLB: begin dbr <= res32[7:0]; nf <= resn8; zf <= resz8; end `ifdef SUPPORT_NEW_INSN `MUL: begin acc <= prod64[31:0]; x <= prod64[63:32]; zf <= prod64==64'd0; nf <= prod64[63]; vf <= prod64[63:32]!=32'd0; end `ifdef SUPPORT_SEG `PLDS: begin ds <= res32[15:0]; nf <= resn16; zf <= resz16; end `endif `endif `PLD: begin dpr <= res32[15:0]; nf <= resn16; zf <= resz16; end endcase end // abort_edge end else begin prc_hit0 <= FALSE; prc_hit1 <= FALSE; next_state(ICACHE1); end end // Decode DECODE: begin moveto_ifetch(); inc_pc(24'd1); case(ir9) `PG2: begin pg2 <= TRUE; ir <= {8'h00,ir[127:8]}; next_state(DECODE); end `ifdef SUPPORT_NEW_INSN `LLA: begin lla <= `TRUE; ir <= {8'h00,ir[127:8]}; next_state(DECODE); end `ifdef SUPPORT_SEG `CS: begin seg <= cs_base; lmt <= cs_limit; mem_wr <= cs_wr; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `SS: begin seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `IOS: begin seg <= IO_SEGMENT; lmt <= 32'hFFFFF; mem_wr <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `SEG0: begin seg <= 32'd0; lmt <= 32'hFFFFFFFF; mem_wr <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `SEG: begin inc_pc(24'd3); sdt_ra <= ir[23:8]; ir <= {24'h00,ir[127:24]}; pg2 <= FALSE; next_state(SEG1); end `endif `TJ: begin tj_prefix <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `BYT: begin sop <= TRUE; lds <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `UBT: begin sop <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `HAF: begin sop <= TRUE; lds <= TRUE; s16 <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `UHF: begin sop <= TRUE; s16 <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `UHF: begin sop <= TRUE; s16 <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `WRD: begin sop <= TRUE; s32 <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `SEP16: inc_pc(24'd3); // see byte_ifetch `REP16: inc_pc(24'd3); `FAR: begin isFar <= TRUE; ir <= {8'h00,ir[127:8]}; pg2 <= FALSE; next_state(DECODE); end `endif `SEP: inc_pc(24'd2); // see byte_ifetch `REP: inc_pc(24'd2); `PCHIST: res32 <= pc_hist_o; // 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: res32 <= {acc[31:16],acc[7:0],acc[15:8]}; `STP: begin clk_en <= 1'b0; end // Switching the processor mode always zeros out the upper part of the index registers. // switching to native mode sets 8 bit memory/indexes `XCE: begin m816 <= ~cf; m832 <= ~vf; cf <= ~m816; vf <= ~m832; if (!cf) begin x_bit <= 1'b1; m_bit <= 1'b1; end end // `NOP: ; // may help routing `CLC: begin cf <= 1'b0; end `SEC: begin cf <= 1'b1; end `CMC: cf <= ~cf; `CLV: begin vf <= 1'b0; end `CLI: begin iml <= 3'd0; end// imcd <= 3'b110; end `SEI: begin iml <= 3'd7; end `SEI_IMM: begin iml <= ir[10:8]; end `CLD: begin df <= 1'b0; end `SED: begin df <= 1'b1; end `WAI: begin wai <= 1'b1; end `DEX: begin res32 <= x_dec; end `INX: begin res32 <= x_inc; end `DEY: begin res32 <= y_dec; end `INY: begin res32 <= y_inc; end `ifdef SUPPORT_NEW_INSN `XBAW: res32 <= {acc[15:0],acc[31:16]}; `DEX4: res32 <= x - 32'd4; `DEY4: res32 <= y - 32'd4; `INX4: res32 <= x + 32'd4; `INY4: res32 <= y + 32'd4; `AAX: begin res32 <= acc32 + x32; a32 <= acc32; b32 <= x32; end `TSSA: res32 <= ss; `TASS: begin res32 <= acc[15:0]; sdt_ra <= acc[11:0]; next_state(TASS1); end `ifdef SUPPORT_TASK `TTA: res32 <= {mapno,1'b0,tr}; `endif `endif `DEA: res32 <= acc_dec; `INA: res32 <= acc_inc; `TSX,`TSA: res32 <= sp; `TXS,`TXA,`TXY: begin res32 <= x32; end `TAX,`TAY: begin res32 <= acc; end `TAS: res32 <= acc; `TYA,`TYX: begin res32 <= y32; end `TDC: begin res32 <= dpr; end `TCD: begin res32 <= acc; end `ASL_ACC: res32 <= {acc,1'b0}; `ROL_ACC: res32 <= {acc,cf}; `LSR_ACC: if (m32) res32 <= {acc[0],1'b0,acc[31:1]}; else if (m16) res32 <= {acc[0],17'b0,acc[15:1]}; else res32 <= {acc[0],25'b0,acc[7:1]}; `ifdef SUPPORT_NEW_INSN `ASR_ACC: begin a32 <= acc; if (m32) res32 <= {acc[0],acc[31],acc[31:1]}; else if (m16) res32 <= {acc[0],16'b0,acc[15],acc[15:1]}; else res32 <= {acc[0],24'b0,acc[7],acc[7:1]}; end `MUL: prod64 <= acc32 * x32; `INF: begin otr <= tr; tr <= x32[15:4]; sdt_ra <= y[11:0]; next_state(INF1); end `endif `ROR_ACC: if (m32) res32 <= {acc[0],cf,acc[31:1]}; else if (m16) res32 <= {acc[0],16'b0,cf,acc[15:1]}; else res32 <= {acc[0],24'b0,cf,acc[7:1]}; `ifdef SUPPORT_SEG `RTF,`RTS_IMM,`RTL_IMM: begin inc_pc(24'd2); inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif load_what <= `PC_70; state <= LOAD_MAC1; end `endif `RTS,`RTL: begin inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif load_what <= `PC_70; state <= LOAD_MAC1; end `RTIC: begin iml <= ima[2:0]; its <= ima[3]; ima <= {4'b0,ima[15:4]}; do_rtx(24'h1,8'h00,PRES_NONE); end `RTI: begin iml <= ima[2:0]; its <= ima[3]; ima <= {4'b0,ima[15:4]}; if (ima[3]) begin set_task_regs(24'd1); tsk_pres <= PRES_NONE; sp_i <= fn_add_to_sp(32'd2); inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif load_what <= `LDW_TR70S; state <= LOAD_MAC1; end else begin `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif `ifdef SUPPORT_TASK if (m832) begin set_task_regs(24'd1); begin sp_i <= fn_add_to_sp(32'd2); inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif tsk_pres <= 7'd0; load_what <= `LDW_TR70S; state <= LOAD_MAC1; end end else `endif begin inc_sp(); if (bf) pc_cap <= TRUE; load_what <= `SR_70; state <= LOAD_MAC1; end end end `PHP: begin if (m832 || (sop & s16)) tsk_push(`STW_SR158,1,0); else tsk_push(`STW_SR70,0,0); end `PHA: tsk_push(`STW_ACC70,m16,m32); `PHX: tsk_push(`STW_X70,xb16,xb32); `PHY: tsk_push(`STW_Y70,xb16,xb32); // `PHCS: tsk_push(`STW_CS0,0,1); `PHK: tsk_push(`STW_PC2316,0,0); `PHB: tsk_push(`STW_DBR,0,0); `PHD: tsk_push(`STW_DPR70,1,0); `PEA: begin inc_pc(24'd3); wdat <= ir[23:8]; tsk_push(`STW_DEF70,1,0); end `ifdef SUPPORT_NEW_INSN `PEAxl: begin inc_pc(24'd5); wdat <= ir[39:8]; tsk_push(`STW_DEF70,0,1); end `endif `PER: begin inc_pc(24'd3); wdat <= pc[15:0] + ir[23:8] + 16'd3; tsk_push(`STW_DEF70,1,0); end `PLP: begin inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif load_what <= `SR_70; state <= LOAD_MAC1; end `PLA: begin inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `WORD_71S; state <= LOAD_MAC1; retstate <= ssm ? SSM1:IFETCH; end `PLX,`PLY: begin inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `WORD_71S; state <= LOAD_MAC1; retstate <= ssm ? SSM1:IFETCH; end `PLB: begin inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif load_what <= `WORD_71S; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; end `PLD: begin inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif if (!sop) s16 <= TRUE; load_what <= `WORD_71S; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; end // Handle # mode `LDA_IMM: begin if (m32) inc_pc(24'd5); else if (m16) inc_pc(24'd3); else inc_pc(24'd2); res32 <= ir[39:8]; end `LDX_IMM,`LDY_IMM: begin if (xb32) inc_pc(24'd5); else if (xb16) inc_pc(24'd3); else inc_pc(24'd2); res32 <= ir[39:8]; end // We don't care what the high order bits of the calculation // are for 8/16 bit results, so we can safely use 32 bits // from the instruction stream. The high order bits will be // invalid, but don't get stored anyway for 8/16 bit ops. // This is to save some hardware. `ADC_IMM: begin a32 <= acc; b32 <= ir[39:8]; // for overflow calc if (m32) inc_pc(24'd5); else if (m16) inc_pc(24'd3); else inc_pc(24'd2); res32 <= acc + ir[39:8] + {31'b0,cf}; end `SBC_IMM: begin a32 <= acc; b32 <= ir[39:8]; // for overflow calc if (m32) inc_pc(24'd5); else if (m16) inc_pc(24'd3); else inc_pc(24'd2); res32 <= acc - ir[39:8] - {31'b0,~cf}; end `AND_IMM,`BIT_IMM: begin if (m32) inc_pc(24'd5); else if (m16) inc_pc(24'd3); else inc_pc(24'd2); res32 <= acc & ir[39:8]; b32 <= ir[39:8]; // for bit flags end `ORA_IMM: begin if (m32) inc_pc(24'd5); else if (m16) inc_pc(24'd3); else inc_pc(24'd2); res32 <= acc | ir[39:8]; end `EOR_IMM: begin if (m32) inc_pc(24'd5); else if (m16) inc_pc(24'd3); else inc_pc(24'd2); res32 <= acc ^ ir[39:8]; end `CMP_IMM: begin a32 <= acc; b32 <= ir[39:8]; // for carry calc res32 <= {1'd0,acc} - {1'd0,ir[39:8]}; if (m32) inc_pc(24'd5); else if (m16) inc_pc(24'd3); else inc_pc(24'd2); end `CPX_IMM: begin a32 <= x32; b32 <= ir[39:8]; // for carry calc res32 <= x32 - ir[39:8]; if (xb32) inc_pc(24'd5); else if (xb16) inc_pc(24'd3); else inc_pc(24'd2); end `CPY_IMM: begin a32 <= y32; b32 <= ir[39:8]; // for carry calc res32 <= y32 - ir[39:8]; if (xb32) inc_pc(24'd5); else if (xb16) inc_pc(24'd3); else inc_pc(24'd2); end // Handle zp mode `LDA_ZP: begin inc_pc(24'd2); radr <= zp_address; if (lla) begin acc <= zp_address; next_state(IFETCH); end else next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `LDX_ZP,`LDY_ZP: begin inc_pc(24'd2); radr <= zp_address; next_state(LOAD_MAC1); mxb16 <= xb16; mxb32 <= xb32; if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; //state <= LOAD_MAC2; bank_wrap <= !m832; 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 inc_pc(24'd2); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end radr <= zp_address; wadr <= zp_address; next_state(LOAD_MAC1); load_what <= `LOAD_70; retstate <= CALC; bank_wrap <= !m832; end `INC_ZP,`DEC_ZP: begin inc_pc(24'd2); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end radr <= zp_address; wadr <= zp_address; next_state(LOAD_MAC1); load_what <= `LOAD_70; retstate <= CALC; bank_wrap <= !m832; end `INC_IMM: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end radr <= zp_address; wadr <= zp_address; load_what <= `LOAD_70; state <= LOAD_MAC1; retstate <= CALC; bank_wrap <= !m832; end `CPX_ZP,`CPY_ZP: begin inc_pc(24'd2); mxb16 <= xb16; mxb32 <= xb32; if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end radr <= zp_address; next_state(LOAD_MAC1); load_what <= `LOAD_70; retstate <= CALC; bank_wrap <= !m832; end `STA_ZP: begin inc_pc(24'd2); wadr <= zp_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; bank_wrap <= !m832; end `STX_ZP: begin inc_pc(24'd2); wadr <= zp_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_X70; bank_wrap <= !m832; end `STY_ZP: begin inc_pc(24'd2); wadr <= zp_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_Y70; bank_wrap <= !m832; end `STZ_ZP: begin inc_pc(24'd2); wadr <= zp_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_Z70; bank_wrap <= !m832; end // Handle zp,x mode `LDA_ZPX: begin inc_pc(24'd2); radr <= zpx_address; if (lla) begin acc <= zpx_address; next_state(IFETCH); end else next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `LDY_ZPX: begin inc_pc(24'd2); radr <= zpx_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; 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 inc_pc(24'd2); radr <= zpx_address; wadr <= zpx_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; bank_wrap <= !m832; end `STA_ZPX: begin inc_pc(24'd2); wadr <= zpx_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; bank_wrap <= !m832; end `STY_ZPX: begin inc_pc(24'd2); wadr <= zpx_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_Y70; bank_wrap <= !m832; end `STZ_ZPX: begin inc_pc(24'd2); wadr <= zpx_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_Z70; bank_wrap <= !m832; end // Handle zp,y `LDX_ZPY: begin inc_pc(24'd2); radr <= zpy_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `STX_ZPY: begin inc_pc(24'd2); wadr <= zpy_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_X70; bank_wrap <= !m832; end // Handle (zp,x) `LDA_IX: begin inc_pc(24'd2); radr <= zpx_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC2; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; data_read(zpx_address,1); end `ADC_IX,`SBC_IX,`AND_IX,`ORA_IX,`EOR_IX,`CMP_IX,`STA_IX: begin inc_pc(24'd2); radr <= zpx_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; bank_wrap <= !m832; end // Handle (zp),y `LDA_IY: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; isIY <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `ADC_IY,`SBC_IY,`AND_IY,`ORA_IY,`EOR_IY,`CMP_IY,`LDA_IY,`STA_IY: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; isIY <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; bank_wrap <= !m832; end // Handle d,sp `LDA_DSP: begin inc_pc(24'd2); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif radr <= dsp_address; mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; end `ADC_DSP,`SBC_DSP,`CMP_DSP,`ORA_DSP,`AND_DSP,`EOR_DSP: begin inc_pc(24'd2); radr <= dsp_address; `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; state <= LOAD_MAC1; retstate <= CALC; end `STA_DSP: begin inc_pc(24'd2); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif radr <= dsp_address; wadr <= dsp_address; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; state <= STORE1; end // Handle (d,sp),y `LDA_DSPIY: begin inc_pc(24'd2); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif radr <= dsp_address; mxb16 <= m16; mxb32 <= m32; isIY <= `TRUE; load_what <= `IA_70; retstate <= ssm ? SSM1 : IFETCH; state <= LOAD_MAC1; end `ADC_DSPIY,`SBC_DSPIY,`CMP_DSPIY,`ORA_DSPIY,`AND_DSPIY,`EOR_DSPIY,`STA_DSPIY: begin inc_pc(24'd2); radr <= dsp_address; `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif mxb16 <= m16; mxb32 <= m32; isIY <= `TRUE; load_what <= `IA_70; retstate <= CALC; state <= LOAD_MAC1; end `ifdef SUPPORT_NEW_INSN // Handle {d,sp},y `LDA_XDSPIY: begin inc_pc(24'd2); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif radr <= dsp_address; mxb16 <= m16; mxb32 <= m32; isI32 <= `TRUE; isIY32 <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; end `ADC_XDSPIY,`SBC_XDSPIY,`CMP_XDSPIY,`ORA_XDSPIY,`AND_XDSPIY,`EOR_XDSPIY,`STA_XDSPIY: begin inc_pc(24'd2); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif radr <= dsp_address; mxb16 <= m16; mxb32 <= m32; isI32 <= TRUE; isIY32 <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; end `endif // Handle [zp],y `LDA_IYL: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; isI24 <= `TRUE; isIY24 <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; end `ADC_IYL,`SBC_IYL,`AND_IYL,`ORA_IYL,`EOR_IYL,`CMP_IYL,`STA_IYL: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; isI24 <= `TRUE; isIY24 <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; end `ifdef SUPPORT_NEW_INSN // Handle {zp},y `LDA_XIYL: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; isI32 <= `TRUE; isIY32 <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; end `ADC_XIYL,`SBC_XIYL,`AND_XIYL,`ORA_XIYL,`EOR_XIYL,`CMP_XIYL,`STA_XIYL: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; isI32 <= `TRUE; isIY32 <= `TRUE; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; end `endif // Handle [zp] `LDA_IL: begin inc_pc(24'd2); isI24 <= `TRUE; radr <= zp_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `ADC_IL,`SBC_IL,`AND_IL,`ORA_IL,`EOR_IL,`CMP_IL,`STA_IL: begin inc_pc(24'd2); isI24 <= `TRUE; radr <= zp_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; bank_wrap <= !m832; end `ifdef SUPPORT_NEW_INSN // Handle {zp} `LDA_XIL: begin inc_pc(24'd2); isI32 <= `TRUE; radr <= zp_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `ADC_XIL,`SBC_XIL,`AND_XIL,`ORA_XIL,`EOR_XIL,`CMP_XIL,`STA_XIL: begin inc_pc(24'd2); isI32 <= `TRUE; radr <= zp_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; bank_wrap <= !m832; end `endif // Handle (zp) `LDA_I: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `ADC_I,`SBC_I,`AND_I,`ORA_I,`EOR_I,`CMP_I,`STA_I,`PEI: begin inc_pc(24'd2); radr <= zp_address; mxb16 <= m16; mxb32 <= m32; load_what <= `IA_70; state <= LOAD_MAC1; retstate <= CALC; bank_wrap <= !m832; end // Handle abs `LDA_ABS: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= abs_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `LDX_ABS,`LDY_ABS: begin inc_pc(24'd3); mxb16 <= xb16; mxb32 <= xb32; radr <= abs_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; 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 inc_pc(24'd3); radr <= abs_address; wadr <= abs_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `CPX_ABS,`CPY_ABS: begin inc_pc(24'd3); radr <= abs_address; next_state(LOAD_MAC1); mxb16 <= xb16; mxb32 <= xb32; if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `STA_ABS: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= abs_address; wadr <= abs_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; end `STX_ABS: begin inc_pc(24'd3); mxb16 <= xb16; mxb32 <= xb32; radr <= abs_address; wadr <= abs_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_X70; end `STY_ABS: begin inc_pc(24'd3); mxb16 <= xb16; mxb32 <= xb32; radr <= abs_address; wadr <= abs_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_Y70; end `STZ_ABS: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= abs_address; wadr <= abs_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_Z70; end `ifdef SUPPORT_NEW_INSN // Handle xlabs `LDA_XABS: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= xal_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `LDX_XABS,`LDY_XABS: begin inc_pc(24'd5); mxb16 <= xb16; mxb32 <= xb32; radr <= xal_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `ADC_XABS,`SBC_XABS,`AND_XABS,`ORA_XABS,`EOR_XABS,`CMP_XABS, `ASL_XABS,`ROL_XABS,`LSR_XABS,`ROR_XABS,`INC_XABS,`DEC_XABS,`TRB_XABS,`TSB_XABS, `BIT_XABS: begin inc_pc(24'd5); radr <= xal_address; wadr <= xal_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `CPX_XABS,`CPY_XABS: begin inc_pc(24'd5); radr <= xal_address; next_state(LOAD_MAC1); mxb16 <= xb16; mxb32 <= xb32; if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `STA_XABS: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= xal_address; wadr <= xal_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; end `STX_XABS: begin inc_pc(24'd5); mxb16 <= xb16; mxb32 <= xb32; radr <= xal_address; wadr <= xal_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_X70; end `STY_XABS: begin inc_pc(24'd5); mxb16 <= xb16; mxb32 <= xb32; radr <= xal_address; wadr <= xal_address; next_state(STORE1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end store_what <= `STW_Y70; end `STZ_XABS: begin inc_pc(24'd5); radr <= xal_address; wadr <= xal_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_Z70; end `BMT_XABS,`BMS_XABS,`BMC_XABS: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= {3'd0,acc[31:3]} + xal_address; wadr <= {3'd0,acc[31:3]} + xal_address; next_state(LOAD_MAC1); s32 <= FALSE; s16 <= FALSE; load_what <= `LOAD_70; retstate <= CALC; end `endif // Handle abs,x `LDA_ABSX: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= absx_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; 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 inc_pc(24'd3); radr <= absx_address; wadr <= absx_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `LDY_ABSX: begin inc_pc(24'd3); mxb16 <= xb16; mxb32 <= xb32; radr <= absx_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `STA_ABSX: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= absx_address; wadr <= absx_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; end `STZ_ABSX: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= absx_address; wadr <= absx_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_Z70; end `ifdef SUPPORT_NEW_INSN // Handle xlabs,x `LDA_XABSX: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= xalx_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `ADC_XABSX,`SBC_XABSX,`AND_XABSX,`ORA_XABSX,`EOR_XABSX,`CMP_XABSX, `ASL_XABSX,`ROL_XABSX,`LSR_XABSX,`ROR_XABSX,`INC_XABSX,`DEC_XABSX,`BIT_XABSX: begin inc_pc(24'd5); radr <= xalx_address; wadr <= xalx_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `LDY_XABSX: begin inc_pc(24'd5); mxb16 <= xb16; mxb32 <= xb32; radr <= xalx_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `STA_XABSX: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= xalx_address; wadr <= xalx_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; end `STZ_XABSX: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= xalx_address; wadr <= xalx_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_Z70; end `endif // Handle abs,y `LDA_ABSY: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= absy_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; bank_wrap <= !m832; end `ADC_ABSY,`SBC_ABSY,`AND_ABSY,`ORA_ABSY,`EOR_ABSY,`CMP_ABSY: begin inc_pc(24'd3); radr <= absy_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `LDX_ABSY: begin inc_pc(24'd3); mxb16 <= xb16; mxb32 <= xb32; radr <= absy_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `STA_ABSY: begin inc_pc(24'd3); mxb16 <= m16; mxb32 <= m32; radr <= absy_address; wadr <= absy_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; end `ifdef SUPPORT_NEW_INSN // Handle xlabs,y `LDA_XABSY: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= xaly_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `ADC_XABSY,`SBC_XABSY,`AND_XABSY,`ORA_XABSY,`EOR_XABSY,`CMP_XABSY: begin inc_pc(24'd5); radr <= xaly_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `LDX_XABSY: begin inc_pc(24'd5); mxb16 <= xb16; mxb32 <= xb32; radr <= xaly_address; next_state(LOAD_MAC1); if (!sop) begin if (xb32) s32 <= TRUE; else if (xb16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `STA_XABSY: begin inc_pc(24'd5); mxb16 <= m16; mxb32 <= m32; radr <= xaly_address; wadr <= xaly_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; end `endif // Handle al `LDA_AL: begin inc_pc(24'd4); mxb16 <= m16; mxb32 <= m32; radr <= al_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `ADC_AL,`SBC_AL,`AND_AL,`ORA_AL,`EOR_AL,`CMP_AL: begin inc_pc(24'd4); radr <= al_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `STA_AL: begin inc_pc(24'd4); mxb16 <= m16; mxb32 <= m32; radr <= al_address; wadr <= al_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; data_write(al_address,acc[7:0],1); state <= STORE2; end // Handle alx `LDA_ALX: begin inc_pc(24'd4); mxb16 <= m16; mxb32 <= m32; radr <= alx_address; next_state(LOAD_MAC1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= ssm ? SSM1 : IFETCH; end `ADC_ALX,`SBC_ALX,`AND_ALX,`ORA_ALX,`EOR_ALX,`CMP_ALX: begin inc_pc(24'd4); radr <= alx_address; next_state(LOAD_MAC1); mxb16 <= m16; mxb32 <= m32; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end load_what <= `LOAD_70; retstate <= CALC; end `STA_ALX: begin inc_pc(24'd4); mxb16 <= m16; mxb32 <= m32; radr <= alx_address; wadr <= alx_address; next_state(STORE1); if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; end `BRK,`BRK2: begin pc_cap <= FALSE; if (!hwi) inc_pc(24'd2); else pc <= pc; // override increment above begin iml <= iml1; ima <= {ima[11:0],1'b0,iml}; `ifdef SUPPORT_SEG seg <= 32'd0; lmt <= 32'hFFFF; mem_wr <= FALSE; `endif radr <= vect; otr <= tr; load_what <= `LDW_TR70; next_state(LOAD_MAC1); end /* else begin set_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif store_what <= m816 ? `STW_PC2316 : `STW_PC158;// `STW_PC3124; data_nack(); state <= STORE1; end */ bf <= !hwi; end // ToDo: update this to work like BRK `COP: begin iml <= 3'd7; // ToDo set to 7 ima <= {ima[11:0],1'b0,iml}; `ifdef SUPPORT_SEG seg <= 32'd0; lmt <= 32'hFFFF; mem_wr <= FALSE; `endif radr <= m832 ? `COP_VECT_832 : m816 ? `COP_VECT_816 : `BYTE_COP_VECT; otr <= tr; load_what <= `LDW_TR70; next_state(LOAD_MAC1); end /* `COP: begin iml <= 3'd7; ima <= {ima[1:0],4'd7}; inc_pc(24'd2); set_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif store_what <= `SUPPORT_SEG ? `STW_CS158 : `STW_PC2316;// `STW_PC3124; state <= STORE1; vect <= m832 ? `COP_VECT_832 : m816 ? `COP_VECT_816 : `BYTE_COP_VECT; end */ `BEQ,`BNE,`BPL,`BMI,`BCC,`BCS,`BVC,`BVS,`BRA,`BGT,`BLE: begin if (ir[15:8]==8'hFF) begin if (takb) inc_pc({{8{ir[31]}},ir[31:16]} + 24'd4); else inc_pc(24'd4); end else begin if (takb) inc_pc({{16{ir[15]}},ir[15:8]} + 24'd2); else inc_pc(24'd2); end end `JMP: begin pc[15:0] <= ir[23:8]; end `JMP_IND: begin radr <= abs_address; load_what <= `PC_70; state <= LOAD_MAC2; data_read(abs_address,0); end `JML_IND: begin radr <= abs_address; load_what <= `PC_70; state <= LOAD_MAC2; data_read(abs_address,0); end `JML_XIND: begin radr <= xal_address; load_what <= `PC_70; state <= LOAD_MAC2; data_read(xal_address,0); end `ifdef SUPPORT_NEW_INSN `JML_XINDX: begin radr <= xalx_address; load_what <= `PC_70; state <= LOAD_MAC2; data_read(xalx_address,0); end `JSL_XINDX: begin inc_pc(24'd4); // Yes this should be one less than the instruction length. set_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif store_what <= `STW_PC2316; state <= STORE1; end `endif `JMP_INDX: begin radr <= absx_address; load_what <= `PC_70; state <= LOAD_MAC2; data_read(absx_address,0); end `BSR,`JSR,`JSR_INDX: begin inc_pc(24'd2); // Yes this should be one less than the instruction length. set_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif store_what <= `STW_PC158; state <= STORE1; end `BRL: begin inc_pc({{8{ir[23]}},ir[23:8]} + 24'd3); end `JML: begin pc <= ir[31:8]; if (pc[23:16]!=ir[31:24]) next_state(PBDELAY); end `BSL,`JSL: begin inc_pc(24'd3); set_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif store_what <= `STW_PC2316; state <= STORE1; end `ifdef SUPPORT_NEW_INSN `ifdef SUPPORT_SEG `PHDS: tsk_push(`STW_DS70,1,0); `PHCS: begin set_sp(); seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; // data_write(fn_get_sp(sp),cs[31:24],0); // new to set the segment in use // mlb <= TRUE; store_what <= `STW_CS158; state <= STORE1; end `PLDS: begin inc_sp(); seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; s16 <= TRUE; load_what <= `WORD_71S; // data_read(fn_sp_inc(sp_inc),0); state <= LOAD_MAC1; retstate <= PLDS1; end `SDU: begin base_i <= acc; size_i <= x[3:0]; acr_i <= x[11:4]; sdt_wa <= y[11:0]; wr_sdt <= TRUE; end `JMF: begin pc <= ir[31:8]; // Switch modes ? if (ir[63:32]==32'hFFFFFFFF) begin m832 <= `FALSE; m816 <= `FALSE; sdt_ra <= 16'd0; cs <= 16'd0; ds <= 16'd0; mapno <= 6'd0; end else if (ir[63:32]==32'hFFFFFFFE) begin m832 <= `FALSE; m816 <= `TRUE; sdt_ra <= 16'd0; cs <= 16'd0; ds <= 16'd0; mapno <= 6'd0; x_bit <= 1'b1; m_bit <= 1'b1; end else begin sdt_ra <= ir[47:32]; cs <= ir[47:32]; mapno <= ir[37:32]; end next_state(JMF1); end `JSF: begin inc_pc(24'd5); set_sp(); seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; store_what <= `STW_CS158; state <= STORE1; end `endif `ifdef SUPPORT_TASK `TSK_IMM: begin inc_pc(24'd3); do_tsk(ir[`TASK_MEM_ABIT+8-3:8]); end `TSK_ACC: begin do_tsk(acc[`TASK_MEM_ABIT-3:0]); end `FORK_IMM: begin inc_pc(24'd3); do_fork(ir[`TASK_MEM_ABIT+8-3:8]); end `FORK_ACC: begin do_fork(acc[`TASK_MEM_ABIT-3:0]); end `RTT: begin do_rtx(24'd1,8'd0,PRES_NONE); end `LDT_XABS: begin inc_pc(24'd5); cnt <= 4'd0; radr <= ir[39:8]; next_state(LDT1); end `LDT_XABSX: begin inc_pc(24'd5); cnt <= 4'd0; radr <= ir[39:8] + (x << 5); next_state(LDT1); end `JCF: begin inc_pc(24'd9); if (tr != ir[`TASK_MEM_ABIT+48-3:48]) begin pc <= ir[31:8]; mapno <= ir[37:32]; `ifdef SUPPORT_SEG cs <= ir[47:32]; sdt_ra <= ir[47:32]; `endif back_link <= tr; set_task_regs(24'd9); otr <= tr; tr <= ir[`TASK_MEM_ABIT+48-3:48]; maxcnt <= ir[68:64]; if (ir[71]) tsk_pres <= PRES_ALL; else tsk_pres <= PRES_CS|PRES_PC|PRES_BACKLINK; if (ir[68:64] > 5'd0) begin cnt <= 8'h00; load_what <= `CPY_BUF; store_what <= `STW_CPY_BUF; inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif next_state(LOAD_MAC1); retstate <= STORE1; end else begin state <= TSK1; `ifdef TASK_BL retstate <= ssm ? SSM1 : IFETCH; `else store_what <= `STW_TR158; retstate <= tj_prefix ? PBDELAY : STORE1; `endif end end end `JCL: begin inc_pc(24'd7); if (tr != ir[`TASK_MEM_ABIT+32-3:32]) begin pc <= ir[31:8]; back_link <= tr; set_task_regs(24'd7); otr <= tr; tr <= ir[`TASK_MEM_ABIT+32-3:32]; maxcnt <= ir[52:48]; if (ir[55]) tsk_pres <= PRES_FAXY|PRES_PC|PRES_BACKLINK; else tsk_pres <= PRES_PC|PRES_BACKLINK; if (ir[52:48] > 5'd0) begin cnt <= 8'h00; load_what <= `CPY_BUF; store_what <= `STW_CPY_BUF; inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif next_state(LOAD_MAC1); retstate <= STORE1; end else begin state <= TSK1; `ifdef TASK_BL retstate <= ssm ? SSM1 : PBDELAY; `else store_what <= `STW_TR158; retstate <= tj_prefix ? PBDELAY : STORE1; `endif end end end `JCR: begin tmsp[tr] <= tmsp[tr] - 3'd1; state <= JCR1; end `JCI: begin if (tr != {8'h00,acc[31:24]}) begin pc <= acc[23:0]; back_link <= tr; set_task_regs(24'd1); otr <= tr; tr <= {8'h00,acc[31:24]}; tsk_pres <= PRES_FAXY|PRES_PC|PRES_BACKLINK; state <= TSK1; store_what <= `STW_TR158; retstate <= tj_prefix ? PBDELAY : STORE1; end end `RTC: begin // Cause a subsequent TSK instruction to return to the RTC and return // right away by backing up the PC to the start of the instruction. do_rtx(24'hFFFFFF,ir[15:8],PRES_FAXY); //inc_pc(24'hFFFFFF); //tsk_pres <= PRES_FAXY; //state <= TSK1; //retstate <= IFETCH; end `endif `FILL: begin mvndst_bank <= ir[15:8]; wadr <= mvndst_address; store_what <= `STW_X70; npc <= PC24 ? pc + 24'd2 : {pc[23:16],pc[15:0]+16'd2}; pc <= opc; // override increment above next_state(STORE1); end `endif `MVN,`MVP: begin mvndst_bank <= ir[15:8]; mvnsrc_bank <= ir[23:16]; radr <= mvnsrc_address; load_what <= `BYTE_72; npc <= PC24 ? pc + 24'd3 : {pc[23:16],pc[15:0]+16'd3}; pc <= opc; // override increment above state <= LOAD_MAC1; end `ifdef SUPPORT_NEW_INSN `CACHE: begin inc_pc(24'd2); case(ir[15:8]) 8'h00: inv_icache <= TRUE; // invalidate entire instruction cache 8'h01: begin ado1 <= {acc[31:4],4'h0}; inv_iline <= TRUE; end 8'h02: begin // LICL rwo <= TRUE; vpa <= TRUE; vda <= TRUE; ado <= {acc[31:4],4'h0}; wr_icache <= TRUE; cnt <= 4'h0; // Going to the ICACHE2 state will ensure that loading // the cache line didn't dump the cache line that is // required by the PC. next_state(ICACHE2); end default: ; endcase end `endif default: begin moveto_ifetch(); end endcase end JCR1: begin //inc_pc(24'd4); pc <= {8'h00,ir[23:8]}; set_task_regs(24'd3); // already incremented above otr <= tr; tr <= {8'h00,ir[31:24]}; tsk_pres <= PRES_FAXY|PRES_PC|PRES_BACKLINK; state <= TSK1; store_what <= `STW_TR158; retstate <= tj_prefix ? IFETCH : STORE1; //retstate <= IFETCH; end `ifdef SUPPORT_TASK TSK1: begin `ifdef SUPPORT_SEG if (!tsk_pres[6]) begin sdt_ra <= cs_o; cs <= cs_o; end `endif mapno <= mapno_o; if (!tsk_pres[4]) pc <= pc_o; if (!tsk_pres[3]) acc <= acc_o; if (!tsk_pres[2]) x <= x_o; if (!tsk_pres[1]) y <= y_o; sp <= sp_o[31:0]; if (!tsk_pres[0]) cf <= sr_o[0]; if (!tsk_pres[0]) zf <= sr_o[1]; // Force further interrupts to be masked automatically when the task is // invoked as an interrupt handler. Otherwise the task will be invoked // continuously. /* if (sr_o[2]|hwi) im <= 1'b1; else begin im <= 1'b0; //imcd <= 3'b110; end */ df <= sr_o[3]; if (srx_o[1:0]!=2'b00) begin x_bit <= sr_o[4]; m_bit <= sr_o[5]; end else begin x_bit <= 1'b1; m_bit <= 1'b1; // The following load of the break flag is different than the '02 // which never loads the flag. if (POPBF) bf <= sr_o[4]; end if (!tsk_pres[0]) vf <= sr_o[6]; if (!tsk_pres[0]) nf <= sr_o[7]; m816 <= srx_o[0]; m832 <= srx_o[1]; mib <= srx_o[2]; ssm <= srx_o[4]; iml <= srx_o[7:5]; dbr <= dbr_o; dpr <= dpr_o; if (!tsk_pres[5]) back_link <= bl_o; `ifdef SUPPORT_SEG next_state(TSK2); `else next_state(TSK4); `endif end TSK2: begin `ifdef SUPPORT_SEG ds <= ds_o; ss <= ss_o; sdt_ra <= ds_o[11:0]; if (!tsk_pres[6]) begin cs_base <= base_o; cs_limit <= fn_limit(size_o); cs_wr <= acr_o[3]; end // Fault if the code segment isn't executable if (!acr_o[4] & !tsk_pres[6]) seg_fault(SEGF_EXEC); else `endif next_state(TSK3); end TSK3: begin `ifdef SUPPORT_SEG sdt_ra <= ss_o[11:0]; ds_base <= base_o; ds_limit <= fn_limit(size_o); ds_wr <= acr_o[3]; `endif next_state(TSK4); end TSK4: begin if (ir9==`JCR) // stay in the same task tr <= otr; else if (ir9==`RTC || ir9==`RTIC) tmsp[tr] <= tmsp[tr] + 3'd1; `ifdef SUPPORT_SEG ss_base <= base_o; ss_limit <= fn_limit(size_o); ss_wr <= acr_o[3]; // Fault if the stack segment isn't writable if (acr_o[3] != TRUE) seg_fault(SEGF_WRITE); else `endif begin if (!srx_o[2]) begin if (retstate==STORE1) begin set_sp(); `ifdef SUPPORT_SEG seg <= base_o; lmt <= fn_limit(size_o); mem_wr <= acr_o[3]; `endif end next_state(retstate); end else moveto_ifetch(); end end PBDELAY: moveto_ifetch(); `ifdef SUPPORT_SEG JMF1: begin cs_base <= base_o; cs_limit <= fn_limit(size_o); cs_wr <= acr_o[3]; // Fault if the code segment isn't executable if (!acr_o[4]) seg_fault(SEGF_EXEC); else moveto_ifetch(); end TASS1: begin ss_base <= base_o; ss_limit <= fn_limit(size_o); ss_wr <= acr_o[3]; // Fault if the stack segment isn't writable if (acr_o[3] != TRUE) seg_fault(SEGF_WRITE); else moveto_ifetch(); end PLDS1: begin sdt_ra <= res32[11:0]; next_state(PLDS2); end PLDS2: begin ds_base <= base_o; ds_limit <= fn_limit(size_o); ds_wr <= acr_o[3]; moveto_ifetch(); end `endif LDT1: begin cnt <= cnt + 4'd1; s32 <= TRUE; if (cnt < 4'd8) begin data_read(radr,cnt==4'd0); if (seg_fault_val == 4'd0) begin load_what <= `LOAD_70; next_state(LOAD_MAC2); retstate <= LDT1; end end case(cnt) 4'd1: begin cs_i <= b32[15:0]; ds_i <= b32[31:16]; end 4'd2: begin ss_i <= b32[15:0]; pc_i[15:0] <= b32[31:16]; end 4'd3: begin pc_i[23:16] <= b32[7:0]; acc_i[23:0] <= b32[31:8]; end 4'd4: begin acc_i[31:24] <= b32[7:0]; x_i[23:0] <= b32[31:8]; end 4'd5: begin x_i[31:24] <= b32[7:0]; y_i[23:0] <= b32[31:8]; end 4'd6: begin y_i[31:24] <= b32[7:0]; sp_i[23:0] <= b32[31:8]; end 4'd7: begin sp_i[31:24] <= b32[7:0]; sr_i <= b32[15:8]; srx_i <= b32[23:16]; dbr_i <= b32[31:24]; end 4'd8: begin dpr_i <= b32[15:0]; mapno_i <= b32[21:16]; tskm_we <= TRUE; tskm_wr <= TRUE; tskm_wa <= x32[`TASK_MEM_ABIT-3:0]; moveto_ifetch(); end endcase end INF1: begin if (x[15:4]==12'hFFF) begin case(x[3:0]) 4'h0: res32 <= corenum; `ifdef SUPPORT_SEG 4'hC: res32 <= base_o; 4'hD: res32 <= {acr_o,size_o}; 4'hF: res32 <= seg_fault_val; `endif default: ; endcase end else begin case(x[3:0]) 4'h0: res32 <= cs_o; 4'h1: res32 <= ds_o; 4'h2: res32 <= ss_o; 4'h3: res32 <= pc_o; 4'h4: res32 <= acc_o; 4'h5: res32 <= x_o; 4'h6: res32 <= y_o; 4'h7: res32 <= sp_o; 4'h8: res32 <= {srx_o,sr_o}; 4'h9: res32 <= dbr_o; 4'hA: res32 <= dpr_o; 4'hB: res32 <= bl_o; 4'hC: res32 <= mapno_o; default: ; endcase end tr <= otr; moveto_ifetch(); end `endif SEG1: begin seg <= base_o; lmt <= fn_limit(size_o); mem_wr <= acr_o[3]; next_state(DECODE); end LOAD_MAC1: `ifdef SUPPORT_DCACHE if (unCachedData) `endif begin if (!lla) begin if (load_what==`CPY_BUF && maxcnt > 1) mlb <= 1'b1; if (isRMW) mlb <= 1'b1; if (isBrk) vpb <= `TRUE; end data_read(radr,0); if (seg_fault_val==0 && !lla) state <= LOAD_MAC2; end `ifdef SUPPORT_DCACHE else if (dhit) load_tsk(rdat,rdat8,rdat16); else begin retstate <= LOAD_MAC1; state <= DCACHE1; end `endif LOAD_MAC2: if (irdy) begin data_nack(); begin case(load_what) `CPY_BUF: begin cnt <= cnt + 8'd1; cpybuf[cnt] <= dati; if (cnt < maxcnt - 8'd1) begin inc_sp(); next_state(LOAD_MAC1); end else begin mlb <= 1'b0; cnt <= cnt; next_state(TSK1); end end `BYTE_72: begin wdat[7:0] <= dati; radr <= mvnsrc_address; wadr <= mvndst_address; store_what <= `STW_DEF70; if (m832) acc <= acc_dec; else acc[15:0] <= acc_dec[15:0]; if (ir9==`MVN) begin if (xb32) begin x <= x_inc; y <= y_inc; end else if (xb16) begin x <= {16'h0000,x_inc[15:0]}; y <= {16'h0000,y_inc[15:0]}; end else begin x <= {24'h0000,x_inc[7:0]}; y <= {24'h0000,y_inc[7:0]}; end end else begin if (xb32) begin x <= x_dec; y <= y_dec; end else if (xb16) begin x <= {16'h0000,x_dec[15:0]}; y <= {16'h0000,y_dec[15:0]}; end else begin x <= {24'h0000,x_dec[7:0]}; y <= {24'h0000,y_dec[7:0]}; end end next_state(STORE1); end `LOAD_70: begin radr <= inc_adr(radr); if (lds) begin b32 <= {{24{dati[7]}},dati}; res32 <= {{24{dati[7]}},dati}; end else begin b32 <= {24'd0,dati}; res32 <= {24'd0,dati}; end if (s16|s32) begin load_what <= `LOAD_158; next_state(LOAD_MAC1); end else state <= retstate; end `LOAD_158: begin radr <= inc_adr(radr); if (lds) begin b32[31:8] <= {{16{dati[7]}},dati}; res32[31:8] <= {{16{dati[7]}},dati}; end else begin b32[31:8] <= {24'd0,dati}; res32[31:8] <= {24'd0,dati}; end if (s32) begin load_what <= `LOAD_2316; next_state(LOAD_MAC1); end else state <= retstate; end `LOAD_2316: begin b32[23:16] <= dati; res32[23:16] <= dati; load_what <= `LOAD_3124; radr <= inc_adr(radr); next_state(LOAD_MAC1); end `LOAD_3124: begin radr <= inc_adr(radr); b32[31:24] <= dati; res32[31:24] <= dati; state <= retstate; end `WORD_71S: begin res32[7:0] <= dati; if (s16|s32) begin load_what <= `WORD_159S; inc_sp(); next_state(LOAD_MAC1); end else next_state(retstate); end `WORD_159S: begin res32[15:8] <= dati; if (s32) begin load_what <= `WORD_2317S; inc_sp(); next_state(LOAD_MAC1); end else next_state(retstate); end `WORD_2317S: begin res32[23:16] <= dati; load_what <= `WORD_3125S; inc_sp(); next_state(LOAD_MAC1); end `WORD_3125S: begin res32[31:24] <= dati; state <= retstate; end `SR_70: begin cf <= dati[0]; zf <= dati[1]; /* if (dati[2] & ~isRTI) im <= 1'b1; else begin im <= 1'b0; //imcd <= 3'b110; end */ df <= dati[3]; if (m816|m832) begin x_bit <= dati[4]; m_bit <= dati[5]; // if (dati[4]) begin // x[31:8] <= 24'd0; // y[31:8] <= 24'd0; // end end // The following load of the break flag is different than the '02 // which never loads the flag. else begin x_bit <= 1'b1; m_bit <= 1'b1; if (POPBF) bf <= dati[4]; end vf <= dati[6]; nf <= dati[7]; if (isRTI) begin load_what <= `PC_70; inc_sp(); next_state(LOAD_MAC1); end else begin // PLP if (m832) begin load_what <= `SR_158; inc_sp(); next_state(LOAD_MAC1); end else moveto_ifetch(); end end `SR_158: begin m816 <= dati[0]; m832 <= dati[1]; mib <= dati[2]; ssm <= dati[4]; moveto_ifetch(); end `ifdef SUPPORT_TASK // Vector to the task only if it's not the one currently running. `LDW_TR70: begin b32 <= dati; radr <= inc_adr(radr); load_what <= `LDW_TR158; next_state(LOAD_MAC1); end `LDW_TR158: begin radr <= inc_adr(radr); vpb <= FALSE; if (dati[7:1]==7'b0) begin ima[3] <= 1'b1; its <= 1'b1; if ({dati[`TASK_MEM_ABIT-8-3:0],b32[7:0]} != tr) begin set_task_regs(hwi ? 24'd0 : 24'd2); tr <= {dati,b32[7:0]}; back_link <= tr; tsk_pres <= PRES_BACKLINK; state <= TSK1; store_what <= `STW_TR158; retstate <= STORE1; end else begin next_state(IFETCH); end end else begin its <= 1'b0; ima[3] <= 1'b0; temp_vec <= {dati,b32[7:0]}; set_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif store_what <= `SUPPORT_SEG ? `STW_CS158 : `STW_PC2316; data_nack(); state <= STORE1; end end `LDW_TR70S: begin trh <= dati; load_what <= `LDW_TR158S; inc_sp(); next_state(LOAD_MAC1); end `LDW_TR158S: begin tr[`TASK_MEM_ABIT-3:0] <= {dati,trh[7:0]}; next_state(TSK1); retstate <= ssm ? SSM1 : IFETCH; // ??? should assign in TSK1 ? end `endif `PC_70: begin if (ir[7:0]==`BRK && hwi) iml <= iml1; pc[7:0] <= dati; load_what <= `PC_158; if (isRTI|isRTS|isRTL|isRTF) begin inc_sp(); next_state(LOAD_MAC1); end else begin // JMP (abs) radr <= inc_adr(radr); state <= LOAD_MAC1; end end `PC_158: begin pc[15:8] <= dati; if (isJmpi|isJsrIndx) moveto_ifetch(); else if (isRTI|isRTL|isRTF) begin load_what <= `PC_2316; inc_sp(); next_state(LOAD_MAC1); end else if (isRTS) begin // rts instruction `ifdef SUPPORT_SEG sdt_ra <= cs; `endif next_state(RTS1); end else if (isJLInd) begin // jmp (abs) load_what <= `PC_2316; `ifdef SUPPORT_SEG seg <= ds_base; lmt <= ds_limit; mem_wr <= ds_wr; `endif radr <= inc_adr(radr); state <= LOAD_MAC1; end else if (isRstVect) begin isRstVect <= `FALSE; next_state(IFETCH); end else begin // brk vpb <= `FALSE; pc[23:16] <= 8'h00; cs <= 16'h0000; sdt_ra <= 12'h000; next_state(JMF1); end end `PC_2316: begin pc[23:16] <= dati; if (isRTF|isRTI) begin load_what <= `CS_70; inc_sp(); next_state(LOAD_MAC1); end else if (isRTL) begin load_what <= `NOTHING; sdt_ra <= cs; next_state(RTS1); end else begin load_what <= `NOTHING; next_state((pc[23:16]!=dati)?PBDELAY:IFETCH); end end `ifdef SUPPORT_SEG `CS_70: begin load_what <= `CS_158; inc_sp(); cs[7:0] <= dati; //mapno <= dati[5:0]; next_state(LOAD_MAC1); end `CS_158: begin cs[15:8] <= dati; sdt_ra <= {dati,cs[7:0]}; if (isRTF) next_state(RTS1); else next_state(JMF1); end `endif // `PC_3124: begin // pc[31:24] <= dati; // load_what <= `NOTHING; // next_state(BYTE_IFETCH); // end `IA_70: begin radr <= inc_adr(radr); next_state(LOAD_MAC1); ia[7:0] <= dati; load_what <= `IA_158; end `IA_158: begin radr <= inc_adr(radr); ia[15:8] <= dati; ia[23:16] <= dbr; ia[31:24] <= 8'h00; if (isIY24|isI24|isIY32|isI32) begin next_state(LOAD_MAC1); load_what <= `IA_2316; end else begin `ifdef SUPPORT_SEG if (isFar) begin load_what <= `LDW_SEG70; next_state(LOAD_MAC1); end else begin sdt_ra <= ds; state <= isIY ? BYTE_IY5 : BYTE_IX5; end `else state <= isIY ? BYTE_IY5 : BYTE_IX5; `endif end end `IA_2316: begin radr <= inc_adr(radr); ia[23:16] <= dati; ia[31:24] <= 8'h00; if (isI32|isIY32) begin load_what <= `IA_3124; next_state(LOAD_MAC1); end else begin `ifdef SUPPORT_SEG if (isFar) begin load_what <= `LDW_SEG70; next_state(LOAD_MAC1); end else begin sdt_ra <= ds; state <= isIY24 ? BYTE_IY5 : BYTE_IX5; end `else state <= isIY24 ? BYTE_IY5 : BYTE_IX5; `endif end end `IA_3124: begin radr <= inc_adr(radr); ia[31:24] <= dati; `ifdef SUPPORT_SEG if (isFar) begin load_what <= `LDW_SEG70; next_state(LOAD_MAC1); end else begin sdt_ra <= ds; state <= isIY32 ? BYTE_IY5 : BYTE_IX5; end `else state <= isIY32 ? BYTE_IY5 : BYTE_IX5; `endif end `LDW_SEG70: begin load_what <= `LDW_SEG158; radr <= inc_adr(radr); sdt_ra[7:0] <= dati; next_state(LOAD_MAC1); end `LDW_SEG158: begin sdt_ra[11:8] <= dati[3:0]; state <= isIY|isIY24|isIY32 ? BYTE_IY5 : BYTE_IX5; end endcase end //endtask // load_tsk(dati,b16); end `ifdef SUPPORT_BERR else if (err_i) begin mlb <= 1'b0; data_nack(); derr_address <= ado; intno <= 9'd508; state <= BUS_ERROR; end `endif RTS1: begin if (ir9==`RTL_IMM || ir9==`RTS_IMM || ir9==`RTF) sp <= fn_add_to_sp(ir[15:8]); inc_pc(24'd1); cs_base <= base_o; cs_limit <= fn_limit(size_o); cs_wr <= acr_o[3]; moveto_ifetch(); end BYTE_IX5: begin isI24 <= `FALSE; isI32 <= `FALSE; bank_wrap <= FALSE; page_wrap <= FALSE; `ifdef SUPPORT_SEG seg <= base_o; lmt <= fn_limit(size_o); mem_wr <= acr_o[3]; `endif radr <= ia; load_what <= `LOAD_70; state <= LOAD_MAC1; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end if (ir[7:0]==`STA_IX || ir[7:0]==`STA_I || ir[7:0]==`STA_IL || ir[7:0]==`STA_XIL) begin wadr <= ia; store_what <= `STW_ACC70; state <= STORE1; end else if (ir[7:0]==`PEI) begin set_sp(); seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; store_what <= isI32 ? `STW_IA3124 : `STW_IA158; state <= STORE1; end end BYTE_IY5: begin isIY <= `FALSE; isIY24 <= `FALSE; isIY32 <= `FALSE; bank_wrap <= FALSE; page_wrap <= FALSE; `ifdef SUPPORT_SEG seg <= base_o; lmt <= fn_limit(size_o); mem_wr <= acr_o[3]; `endif radr <= iapy8; wadr <= iapy8; if (!sop) begin if (m32) s32 <= TRUE; else if (m16) s16 <= TRUE; end store_what <= `STW_ACC70; load_what <= `LOAD_70; $display("IY addr: %h", iapy8); // Testing only ir[7:0] below will take care of 'X' forms as well. if (ir[7:0]==`STA_IY || ir[7:0]==`STA_IYL || ir[7:0]==`STA_DSPIY) state <= STORE1; else state <= LOAD_MAC1; end STORE1: begin case(store_what) `ifdef SUPPORT_SEG `STW_CS158: begin data_write(wadr,cs[15:8],0); mlb <= TRUE; end `STW_CS70: data_write(wadr,cs[7:0],0); `STW_DS70: begin data_write(wadr,ds[7:0],0); mlb <= 1'b1; end `STW_DS158: data_write(wadr,ds[15:8],0); `endif `STW_PC2316: begin data_write(wadr,pc[23:16],0); mlb <= 1'b1; end `STW_PC158: data_write(wadr,pc[15:8],0); `STW_PC70: data_write(wadr,pc[7:0],0); `STW_SR70: data_write(wadr,sr8,0); `STW_SR158: begin data_write(wadr,srx,1); mlb <= TRUE; end `STW_DEF70: begin data_write(wadr,wdat,0); mlb <= s16|s32; end `STW_DEF158: data_write(wadr,wdat[15:8],0); `STW_DEF2316: data_write(wadr,wdat[23:16],0); `STW_DEF3124: data_write(wadr,wdat[31:24],0); `STW_ACC70: begin data_write(wadr,acc,0); mlb <= s16|s32; end `STW_ACC158: data_write(wadr,acc[15:8],0); `STW_ACC2316: data_write(wadr,acc[23:16],0); `STW_ACC3124: data_write(wadr,acc[31:24],0); `STW_X70: begin data_write(wadr,x,0); mlb <= s16|s32; end `STW_X158: data_write(wadr,x[15:8],0); `STW_X2316: data_write(wadr,x[23:16],0); `STW_X3124: data_write(wadr,x[31:24],0); `STW_Y70: begin data_write(wadr,y,0); mlb <= s16|s32; end `STW_Y158: data_write(wadr,y[15:8],0); `STW_Y2316: data_write(wadr,y[23:16],0); `STW_Y3124: data_write(wadr,y[31:24],0); `STW_Z70: begin data_write(wadr,8'h00,0); mlb <= s16|s32; end `STW_Z158: data_write(wadr,8'h00,0); `STW_Z2316: data_write(wadr,8'h00,0); `STW_Z3124: data_write(wadr,8'h00,0); `STW_DBR: data_write(wadr,dbr,0); `STW_DPR158: begin data_write(wadr,dpr[15:8],0); mlb<= 1'b1; end `STW_DPR70: begin data_write(wadr,dpr[7:0],0); mlb <= 1'b1; end `STW_TMP3124: begin data_write(wadr,tmp32[31:24],0); mlb <= 1'b1; end `STW_TMP2316: begin data_write(wadr,tmp32[23:16],0); mlb <= 1'b1; end `STW_TMP158: begin data_write(wadr,tmp32[15:8],0); mlb <= 1'b1; end `STW_TMP70: data_write(wadr,tmp32[7:0],0); `STW_IA3124: begin data_write(wadr,ia[31:24],0); mlb <= 1'b1; end `STW_IA2316: data_write(wadr,ia[23:16],0); `STW_IA158: begin data_write(wadr,ia[15:8],0); mlb <= 1'b1; end `STW_IA70: data_write(wadr,ia,0); `ifdef SUPPORT_TASK `STW_TR158: begin data_write(wadr,otr[`TASK_MEM_ABIT-3:8],1); mlb <= 1'b1; end `STW_TR70: data_write(wadr,otr[7:0],0); `STW_CPY_BUF: begin data_write(wadr,cpybuf[cnt],0); mlb <= maxcnt > 8'd1; end `endif default: data_write(wadr,wdat,0); endcase `ifdef SUPPORT_DCACHE radr <= wadr; // Do a cache read to test the hit `endif if (seg_fault_val==0) state <= STORE2; end // Terminal state for stores. Update the data cache if there was a cache hit. // Clear any previously set lock status STORE2: if (irdy) begin // wdat <= dat_o; mlb <= 1'b0; data_nack(); if (!em && (isMove|isSts)) begin state <= MVN816; retstate <= MVN816; end else begin if (em) begin if (isMove) begin state <= MVN816; retstate <= MVN816; end else begin moveto_ifetch(); retstate <= IFETCH; end end else begin moveto_ifetch(); retstate <= IFETCH; end end case(store_what) `STW_CPY_BUF: begin if (cnt > 0) begin mlb <= TRUE; cnt <= cnt - 8'd1; set_sp(); next_state(STORE1); end else begin `ifdef TASK_BL moveto_ifetch(); `else if (tj_prefix) moveto_ifetch(); else begin store_what <= `STW_TR158; set_sp(); next_state(STORE1); end `endif end end `STW_DEF70: begin wadr <= inc_adr(wadr); if (s16|s32) begin mlb <= TRUE; store_what <= `STW_DEF158; next_state(STORE1); end end `STW_DEF158: if (s32) begin mlb <= TRUE; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_DEF2316; end `STW_DEF2316: begin mlb <= TRUE; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_DEF3124; end `STW_ACC70: if (s16|s32) begin wadr <= inc_adr(wadr); mlb <= TRUE; store_what <= `STW_ACC158; next_state(STORE1); end `STW_ACC158: if (s32) begin wadr <= inc_adr(wadr); mlb <= TRUE; store_what <= `STW_ACC2316; next_state(STORE1); end `STW_ACC2316: begin wadr <= inc_adr(wadr); mlb <= TRUE; store_what <= `STW_ACC3124; next_state(STORE1); end `STW_X70: begin do_fill_inc(MVN816); if (s16|s32) begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_X158; end end `STW_X158: begin do_fill_inc(MVN816); if (s32) begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_X2316; end end `STW_X2316: begin do_fill_inc(MVN816); mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_X3124; end `STW_X3124: do_fill_inc(MVN816); `STW_Y70: if (s16|s32) begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_Y158; end `STW_Y158: if (s32) begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_Y2316; end `STW_Y2316: begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_Y3124; end `STW_Z70: if (s16|s32) begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_Z158; end `STW_Z158: if (s32) begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_Z2316; end `STW_Z2316: begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_Z3124; end `STW_DPR70: begin mlb <= 1'b1; wadr <= inc_adr(wadr); store_what <= `STW_DPR158; state <= STORE1; end `ifdef SUPPORT_TASK `STW_TR158: begin mlb <= `TRUE; set_sp(); next_state(STORE1); store_what <= `STW_TR70; end `STW_TR70: begin moveto_ifetch(); end `endif `ifdef SUPPORT_SEG `STW_DS70: begin mlb <= 1'b1; wadr <= inc_adr(wadr); next_state(STORE1); store_what <= `STW_DS158; end `STW_CS158: begin mlb <= TRUE; set_sp(); next_state(STORE1); store_what <= `STW_CS70; end `STW_CS70: if (ir9 != `PHCS) begin mlb <= TRUE; set_sp(); next_state(STORE1); store_what <= `STW_PC2316; end `endif `STW_TMP158: begin set_sp(); store_what <= `STW_TMP70; state <= STORE1; end `STW_IA3124: begin set_sp(); store_what <= `STW_IA2316; state <= STORE1; end `STW_IA2316: begin set_sp(); store_what <= `STW_IA158; state <= STORE1; end `STW_IA158: begin set_sp(); store_what <= `STW_IA70; state <= STORE1; end `STW_PC2316: begin if (ir9 != `PHK) begin mlb <= TRUE; set_sp(); next_state(STORE1); store_what <= `STW_PC158; end end `STW_PC158: begin mlb <= TRUE; set_sp(); next_state(STORE1); store_what <= `STW_PC70; end `STW_PC70: begin case(ir9) `BRK,`BRK2,`COP: begin mlb <= TRUE; set_sp(); next_state(STORE1); store_what <= `STW_SR70; end `JSR: begin pc[15:0] <= ir[23:8]; end `JSL: begin pc[23:0] <= ir[31:8]; next_state(PBDELAY); end `BSR: pc[15:0] <= pc[15:0] + ir[23:8] + 16'd1; `BSL: begin pc <= pc + ir[31:8] + 24'd1; next_state(PBDELAY); end `ifdef SUPPORT_SEG `JSF,`JCF: begin pc <= ir[31:8]; `ifdef SUPPORT_SEG cs <= ir[47:32]; mapno <= ir[37:32]; sdt_ra <= ir[47:32]; `endif next_state(JMF1); end `endif `JSR_INDX: begin state <= LOAD_MAC1; load_what <= `PC_70; `ifdef SUPPORT_SEG seg <= ds_base; lmt <= ds_limit; mem_wr <= ds_wr; `endif radr <= absx_address; bank_wrap <= FALSE; page_wrap <= FALSE; end `JSL_XINDX: begin state <= LOAD_MAC1; load_what <= `PC_70; `ifdef SUPPORT_SEG seg <= ds_base; lmt <= ds_limit; mem_wr <= ds_wr; `endif radr <= xalx_address; bank_wrap <= FALSE; page_wrap <= FALSE; end endcase end `STW_SR158: begin store_what <= `STW_SR70; set_sp(); next_state(STORE1); end `STW_SR70: begin if (ir[7:0]==`BRK) begin pc <= {8'h00,temp_vec};//abs8[23:16]; df <= 1'b0; bank_wrap <= FALSE; page_wrap <= FALSE; end else if (ir[7:0]==`COP) begin pc <= {8'h00,temp_vec};//abs8[23:16]; iml <= 3'd7; bank_wrap <= FALSE; page_wrap <= FALSE; end end endcase `ifdef SUPPORT_DCACHE if (!dhit && write_allocate) begin state <= DCACHE1; end `endif end `ifdef SUPPORT_BERR else if (err_i) begin mlb <= 1'b0; data_nack(); derr_address <= ado[23:0]; intno <= 9'd508; state <= BUS_ERROR; end `endif CALC: begin moveto_ifetch(); store_what <= `STW_DEF70; // The following calculations are the same regardless of the size. case(ir9) `ADC_IMM,`ADC_ZP,`ADC_ZPX,`ADC_IX,`ADC_IY,`ADC_ABS,`ADC_ABSX,`ADC_ABSY,`ADC_XABS,`ADC_XABSX,`ADC_XABSY, `ADC_IYL,`ADC_XIYL,`ADC_I,`ADC_IL,`ADC_XIL,`ADC_AL,`ADC_ALX,`ADC_DSP,`ADC_DSPIY,`ADC_XDSPIY: begin res32 <= acc + b32 + {31'b0,cf}; a32 <= acc; end `SBC_IMM,`SBC_ZP,`SBC_ZPX,`SBC_IX,`SBC_IY,`SBC_ABS,`SBC_ABSX,`SBC_ABSY,`SBC_XABS,`SBC_XABSX,`SBC_XABSY, `SBC_IYL,`SBC_XIYL,`SBC_I,`SBC_IL,`SBC_XIL,`SBC_AL,`SBC_ALX,`SBC_DSP,`SBC_DSPIY,`SBC_XDSPIY: begin res32 <= acc - b32 - {31'b0,~cf}; a32 <= acc; end `CMP_IMM,`CMP_ZP,`CMP_ZPX,`CMP_IX,`CMP_IY,`CMP_ABS,`CMP_ABSX,`CMP_ABSY,`CMP_XABS,`CMP_XABSX,`CMP_XABSY, `CMP_IYL,`CMP_XIYL,`CMP_I,`CMP_IL,`CMP_XIL,`CMP_AL,`CMP_ALX,`CMP_DSP,`CMP_DSPIY,`CMP_XDSPIY: begin res32 <= acc - b32; a32 <= acc; end `CPX_IMM,`CPX_ZP,`CPX_ABS,`CPX_XABS: begin res32 <= x - b32; a32 <= x; end `CPY_IMM,`CPY_ZP,`CPY_ABS,`CPY_XABS: begin res32 <= y - b32; a32 <= y; end `AND_IMM,`AND_ZP,`AND_ZPX,`AND_IX,`AND_IY,`AND_ABS,`AND_ABSX,`AND_ABSY,`AND_XABS,`AND_XABSX,`AND_XABSY, `AND_IYL,`AND_XIYL,`AND_I,`AND_IL,`AND_XIL,`AND_AL,`AND_ALX,`AND_DSP,`AND_DSPIY,`AND_XDSPIY: begin res32 <= acc & b32; end `ORA_IMM,`ORA_ZP,`ORA_ZPX,`ORA_IX,`ORA_IY,`ORA_ABS,`ORA_ABSX,`ORA_ABSY,`ORA_XABS,`ORA_XABSX,`ORA_XABSY, `ORA_IYL,`ORA_XIYL,`ORA_I,`ORA_IL,`ORA_XIL,`ORA_AL,`ORA_ALX,`ORA_DSP,`ORA_DSPIY,`ORA_XDSPIY: begin res32 <= acc | b32; end `EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_XABS,`EOR_XABSX,`EOR_XABSY, `EOR_IYL,`EOR_XIYL,`EOR_I,`EOR_IL,`EOR_XIL,`EOR_AL,`EOR_ALX,`EOR_DSP,`EOR_DSPIY,`EOR_XDSPIY: begin res32 <= acc ^ b32; end `LDA_IMM,`LDA_ZP,`LDA_ZPX,`LDA_IX,`LDA_IY,`LDA_ABS,`LDA_ABSX,`LDA_ABSY,`LDA_XABS,`LDA_XABSX,`LDA_XABSY, `LDA_IYL,`LDA_XIYL,`LDA_I,`LDA_IL,`LDA_XIL,`LDA_AL,`LDA_ALX,`LDA_DSP,`LDA_DSPIY,`LDA_XDSPIY: begin res32 <= b32; end `BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX,`BIT_XABS,`BIT_XABSX: begin res32 <= acc & b32; end `LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY,`LDX_XABS,`LDX_XABSY: begin res32 <= b32; end `LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX,`LDY_XABS,`LDY_XABSX: begin res32 <= b32; end `TRB_ZP,`TRB_ABS,`TRB_XABS: begin res32 <= acc & b32; wdat <= ~acc & b32; state <= STORE1; data_nack(); end `TSB_ZP,`TSB_ABS,`TSB_XABS: begin res32 <= acc & b32; wdat <= acc | b32; state <= STORE1; data_nack(); end `BMT_XABS: begin res32 <= (32'd1 << acc[2:0]) & b32; end `BMS_XABS: begin res32 <= (32'd1 << acc[2:0]) & b32; wdat <= (32'd1 << acc[2:0]) | b32; state <= STORE1; data_nack(); end `BMC_XABS: begin res32 <= (32'd1 << acc[2:0]) & b32; wdat <= ~(32'd1 << acc[2:0]) & b32; state <= STORE1; data_nack(); end `INC_ZP,`INC_ZPX,`INC_ABS,`INC_ABSX,`INC_XABS,`INC_XABSX: begin res32 <= b32 + 32'd1; wdat <= b32+32'd1; state <= STORE1; data_nack(); end `DEC_ZP,`DEC_ZPX,`DEC_ABS,`DEC_ABSX,`DEC_XABS,`DEC_XABSX: begin res32 <= b32 - 32'd1; wdat <= b32-32'd1; state <= STORE1; data_nack(); end `ASL_ZP,`ASL_ZPX,`ASL_ABS,`ASL_ABSX,`ASL_XABS,`ASL_XABSX: begin res32 <= {b32,1'b0}; wdat <= {b32[30:0],1'b0}; state <= STORE1; data_nack(); end `ROL_ZP,`ROL_ZPX,`ROL_ABS,`ROL_ABSX,`ROL_XABS,`ROL_XABSX: begin res32 <= {b32,cf}; wdat <= {b32[30:0],cf}; state <= STORE1; data_nack(); end `INC_IMM: begin res32 <= b32 + {{24{ir[23]}},ir[23:16]}; wdat <= {{24{ir[23]}},ir[23:16]}; state <= STORE1; data_nack(); end default: begin // The following calculations depend on the operand size. if ((sop && mxb16) || (!sop && s16)) begin case(ir9) `LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX,`LSR_XABS,`LSR_XABSX: begin res32 <= {b32[0],17'b0,b32[15:1]}; wdat <= {17'b0,b32[15:1]}; state <= STORE1; data_nack(); end `ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX,`ROR_XABS,`ROR_XABSX: begin res32 <= {b32[0],16'b0,cf,b32[15:1]}; wdat <= {16'h0,cf,b32[15:1]}; state <= STORE1; data_nack(); end default: res32 <= 32'hDEADDEAD; endcase end else if ((sop && mxb32) || (!sop && s32)) begin case(ir9) `LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX,`LSR_XABS,`LSR_XABSX: begin res32 <= {b32[0],1'b0,b32[31:1]}; wdat <= {1'b0,b32[31:1]}; state <= STORE1; data_nack(); end `ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX,`ROR_XABS,`ROR_XABSX: begin res32 <= {b32[0],cf,b32[31:1]}; wdat <= {cf,b32[31:1]}; state <= STORE1; data_nack(); end default: res32 <= 32'hDEADDEAD; endcase end else begin case(ir9) `LSR_ZP,`LSR_ZPX,`LSR_ABS,`LSR_ABSX,`LSR_XABS,`LSR_XABSX: begin res32 <= {b32[0],25'b0,b8[7:1]}; wdat <= {25'b0,b8[7:1]}; state <= STORE1; data_nack(); end `ROR_ZP,`ROR_ZPX,`ROR_ABS,`ROR_ABSX,`ROR_XABS,`ROR_XABSX: begin res32 <= {b32[0],24'b0,cf,b8[7:1]}; wdat <= {24'b0,cf,b8[7:1]}; state <= STORE1; data_nack(); end default: res32 <= 32'hDEADDEAD; endcase end end endcase end MVN816: begin moveto_ifetch(); if (m832) begin if (&acc) begin pc <= npc; if (pc[23:16]!= npc[23:16]) next_state(PBDELAY); end end else begin if (&acc[15:0]) begin pc <= npc; if (pc[23:16]!= npc[23:16]) next_state(PBDELAY); dbr <= mvndst_bank; end end end SSM1: begin set_task_regs(24'd0); otr <= tr; back_link <= tr; tr <= 16'd9; // single step task tsk_pres <= 7'h2C; acc <= tr; x <= pc; `ifndef TASK_BL seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; store_what <= `STW_TR158; retstate <= STORE1; // Do not switch on SSM here `else retstate <= IFETCH; `endif next_state(TSK1); end ICACHE1: begin rwo <= TRUE; inv_icache <= FALSE; inv_iline <= FALSE; if (!hit0) begin prc_hit0 <= TRUE; vpa <= TRUE; vda <= TRUE; ado <= {cspc[31:4],4'h0}; wr_icache <= TRUE; cnt <= 8'h0; next_state(ICACHE2); end else if (!hit1) begin prc_hit1 <= TRUE; vpa <= TRUE; vda <= TRUE; ado <= {cspc[31:4]+28'd1,4'h0}; wr_icache <= TRUE; cnt <= 8'h0; next_state(ICACHE2); end else next_state(IFETCH); end ICACHE2: if (rdy) begin ado1 <= ado; vda <= FALSE; if (DEAD_CYCLE) begin vpa <= FALSE; ado <= 32'd0; next_state(ICACHE3); end else ado <= {ado[31:4],cnt[3:0]+4'd1}; if (cnt[3:0] == 4'hE) wr_itag <= TRUE; if (cnt[3:0] == 4'hF) begin vpa <= FALSE; ado <= 32'd0; if ((hit1|prc_hit1)&hit0) begin next_state(IFETCH); end else next_state(ICACHE1); wr_icache <= FALSE; end cnt <= cnt + 4'd1; end ICACHE3: begin vpa <= TRUE; ado <= {ado1[31:4],cnt[3:0]}; next_state(ICACHE2); end endcase end task data_read; input [31:0] adr; input first; begin `ifdef SUPPORT_SEG if (adr > lmt) seg_fault(SEGF_BOUND); else `endif if (lla) begin acc <= seg + adr; next_state(IFETCH); end else begin vpa <= `FALSE; vda <= !cs_pgmap; ivda <= `TRUE; rwo <= `TRUE; ado <= seg + adr; end end endtask task data_write; input [31:0] adr; input [7:0] dat; input first; begin `ifdef SUPPORT_SEG if (adr > lmt) seg_fault(SEGF_BOUND); else if (mem_wr) `endif begin vpa <= `FALSE; vda <= !cs_pgmap; ivda <= `TRUE; rwo <= `FALSE; ado <= seg + adr; dbo <= dat; end `ifdef SUPPORT_SEG else seg_fault(SEGF_WRITE); `endif end endtask task data_nack; begin vpa <= `FALSE; vda <= `FALSE; ivda <= `FALSE; rwo <= `TRUE; // ado <= 32'h000000; // dbo <= 8'h00; end endtask // RTT, RTC instructions task do_rtx; input [23:0] pcinc; input [7:0] spinc; input [7:0] tp; begin inc_pc(pcinc); if (ir9!=`RTC && ir9!=`RTIC) set_task_regs(pcinc); tsk_pres <= tp; sp_i <= fn_add_to_sp(spinc+32'd2); inc_sp(); `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif load_what <= `LDW_TR70S; state <= LOAD_MAC1; end endtask task do_tsk; input [`TASK_MEM_ABIT-3:0] ntr; // new task register value begin store_what <= `STW_TR158; tsk_pres <= PRES_NONE; if (tr != ntr) begin set_task_regs(24'd3); otr <= tr; tr <= ntr; next_state(TSK1); retstate <= tj_prefix ? IFETCH : STORE1; end //retstate <= ssm ? SSM1 : IFETCH; end endtask task do_fork; input [`TASK_MEM_ABIT-3:0] ntr; // new task register value begin store_what <= `STW_TR158; if (tr != ntr) begin set_task_regs(24'd3); otr <= tr; tr <= ntr; `ifdef SUPPORT_SEG seg <= ss_base; lmt <= ss_limit; mem_wr <= ss_wr; `endif if (!tj_prefix) begin set_sp(); next_state(STORE1); end end end endtask task set_task_regs; input [23:0] amt; begin tskm_we <= TRUE; tskm_wr <= TRUE; tskm_wa <= tr; mapno_i <= mapno; `ifdef SUPPORT_SEG cs_i <= cs; ds_i <= ds; ss_i <= ss; `else cs_i <= 16'd0; ds_i <= 16'd0; ss_i <= 16'd0; `endif if (PC24) pc_i <= pc + amt; else pc_i <= {pc[23:16],pc[15:0] + amt[15:0]}; acc_i <= acc; x_i <= x; y_i <= y; sp_i <= sp; if (tr==9'd1 || tr==9'd2 || tr==9'd3) sr_i <= sr8|8'h04;//sr8&8'hFB; else sr_i <= sr8&8'hFB; srx_i <= {iml,ssm,1'b0,mib,m832,m816}; dbr_i <= dbr; dpr_i <= dpr; bl_i <= back_link; end endtask task do_fill_inc; input [5:0] ns; begin if (ir9==`FILL) begin if (m832) acc <= acc_dec; else acc[15:0] <= acc_dec[15:0]; if (xb32) y <= y_inc; else if (xb16) y <= {16'h0000,y_inc[15:0]}; else y <= {24'h0000,y_inc[7:0]}; next_state(ns); end end endtask task set_vect_seg; begin `ifdef SUPPORT_SEG seg <= 32'd0; lmt <= 32'hFFFF; mem_wr <= FALSE; `endif end endtask `include "FT832misc_task.v" task next_state; input [5:0] nxt; begin state <= nxt; end endtask task inc_pc; input [23:0] amt; begin if (PC24) pc <= pc + amt; else pc[15:0] <= pc[15:0] + amt[15:0]; end endtask function fn_inc_pc; input [23:0] amt; begin if (PC24) fn_inc_pc = pc + amt; else fn_inc_pc = {pc[23:16],pc[15:0] + amt[15:0]}; end endfunction task seg_fault; input [7:0] fault_num; begin ir[7:0] <= `BRK; hwi <= `TRUE; if (m832) vect <= `IRQ_VECT_832; else if (m816) vect <= `IRQ_VECT_816; else vect <= `BYTE_IRQ_VECT; seg <= 32'd0; next_state(DECODE); seg_fault_val = fault_num; end endtask function [127:0] fnStateName; input [5:0] state; case(state) RESET1: fnStateName = "RESET1 "; IFETCH: fnStateName = "IFETCH "; STORE1: fnStateName = "STORE1 "; STORE2: fnStateName = "STORE2 "; RTS1: fnStateName = "RTS1 "; IY3: fnStateName = "IY3 "; BYTE_IX5: fnStateName = "BYTE_IX5 "; BYTE_IY5: fnStateName = "BYTE_IY5 "; DECODE: fnStateName = "DECODE "; CALC: fnStateName = "CALC "; BUS_ERROR: fnStateName = "BUS_ERROR "; LOAD_MAC1: fnStateName = "LOAD_MAC1 "; LOAD_MAC2: fnStateName = "LOAD_MAC2 "; ICACHE1: fnStateName = "ICACHE1 "; ICACHE2: fnStateName = "ICACHE2 "; ICACHE3: fnStateName = "ICACHE3 "; MVN816: fnStateName = "MVN816 "; TSK1: fnStateName = "TSK1 "; TSK2: fnStateName = "TSK2 "; TSK3: fnStateName = "TSK3 "; TSK4: fnStateName = "TSK4 "; LDT1: fnStateName = "LDT1 "; INF1: fnStateName = "INF1 "; SSM1: fnStateName = "SSM1 "; JMF1: fnStateName = "JMF1 "; TASS1: fnStateName = "TASS1 "; PLDS1: fnStateName = "PLDS1 "; PLDS2: fnStateName = "PLDS2 "; default: fnStateName = "UNKNOWN "; endcase endfunction endmodule // ============================================================================ // Cache Memories // ============================================================================ module ft832_icachemem(wclk, wce, wr, wa, i, rclk, rce, pc, insn); input wclk; input wce; input wr; input [7:0] i; input rclk; input rce; output [127:0] insn; reg [127:0] insn; input [11:0] wa; input [11:0] pc; reg [127:0] mem [0:255]; reg [11:0] rpc,rpcp16; wire [127:0] insn0 = mem[rpc[11:4]]; wire [127:0] insn1 = mem[rpcp16[11:4]]; genvar g; generate begin : wstrobes for (g = 0; g < 16; g = g + 1) always @(posedge wclk) if (wce & wr && wa[3:0]==g) mem[wa[11:4]][g*8+7:g*8] <= i; end endgenerate always @(posedge rclk) if (rce) rpc <= pc; always @(posedge rclk) if (rce) rpcp16 <= pc + 16'd16; always @(insn0 or insn1 or rpc) case(rpc[3:0]) 4'h0: insn <= insn0; 4'h1: insn <= {insn1[7:0],insn0[127:8]}; 4'h2: insn <= {insn1[15:0],insn0[127:16]}; 4'h3: insn <= {insn1[23:0],insn0[127:24]}; 4'h4: insn <= {insn1[31:0],insn0[127:32]}; 4'h5: insn <= {insn1[39:0],insn0[127:40]}; 4'h6: insn <= {insn1[47:0],insn0[127:48]}; 4'h7: insn <= {insn1[55:0],insn0[127:56]}; 4'h8: insn <= {insn1[63:0],insn0[127:64]}; 4'h9: insn <= {insn1[71:0],insn0[127:72]}; 4'hA: insn <= {insn1[79:0],insn0[127:80]}; 4'hB: insn <= {insn1[87:0],insn0[127:88]}; 4'hC: insn <= {insn1[95:0],insn0[127:96]}; 4'hD: insn <= {insn1[103:0],insn0[127:104]}; 4'hE: insn <= {insn1[111:0],insn0[127:112]}; 4'hF: insn <= {insn1[119:0],insn0[127:120]}; endcase endmodule module ft832_itagmem(wclk, wce, wr, wa, invalidate, invalidate_line, rclk, rce, pc, hit0, hit1); input wclk; input wce; input wr; input [31:0] wa; input invalidate; input invalidate_line; input rclk; input rce; input [31:0] pc; output hit0; output hit1; wire [20:0] tag0,tag1; reg [31:12] mem [0:255]; reg [0:255] tvalid; reg [31:0] rpc,rpcp16; always @(posedge rclk) if (rce) rpc <= pc; always @(posedge rclk) if (rce) rpcp16 <= pc + 32'd16; always @(posedge wclk) if (wce & wr) mem[wa[11:4]] <= wa[31:12]; always @(posedge wclk) if (invalidate) tvalid <= 256'd0; else if (invalidate_line) tvalid[wa[11:4]] <= 1'b0; else if (wce & wr) tvalid[wa[11:4]] <= 1'b1; assign tag0 = {mem[rpc[11:4]],tvalid[rpc[11:4]]}; assign tag1 = {mem[rpcp16[11:4]],tvalid[rpcp16[11:4]]}; assign hit0 = tag0 == {rpc[31:12],1'b1}; assign hit1 = tag1 == {rpcp16[31:12],1'b1}; endmodule module task_mem(wclk, wce, wr, wa, cs_i, ds_i, ss_i, pc_i, acc_i, x_i, y_i, sp_i, sr_i, srx_i, db_i, dpr_i, bl_i, mapno_i, rclk, rce, ra, cs_o, ds_o, ss_o, pc_o, acc_o, x_o, y_o, sp_o, sr_o, srx_o, db_o, dpr_o, bl_o, mapno_o, ); input wclk; input wce; input wr; input [`TASK_MEM_ABIT:0] wa; input [15:0] cs_i; input [15:0] ds_i; input [15:0] ss_i; input [23:0] pc_i; input [31:0] acc_i; input [31:0] x_i; input [31:0] y_i; input [31:0] sp_i; input [7:0] sr_i; input [7:0] srx_i; input [7:0] db_i; input [15:0] dpr_i; input [5:0] mapno_i; input [`TASK_MEM_ABIT-3:0] bl_i; input rclk; input rce; input [`TASK_MEM_ABIT:0] ra; output [15:0] cs_o; output [15:0] ds_o; output [15:0] ss_o; output [23:0] pc_o; output [31:0] acc_o; output [31:0] x_o; output [31:0] y_o; output [31:0] sp_o; output [7:0] sr_o; output [7:0] srx_o; output [7:0] db_o; output [15:0] dpr_o; output [5:0] mapno_o; output [`TASK_MEM_ABIT-3:0] bl_o; reg [`TASK_MEM_ABIT+246-3:0] mem [`TASK_MEM-1:0]; always @(posedge wclk) if (wce & wr) mem[wa] <= {bl_i,mapno_i,cs_i,ds_i,ss_i,pc_i,acc_i,x_i,y_i,sp_i,sr_i,srx_i,db_i,dpr_i}; wire [`TASK_MEM_ABIT+246-3:0] memo; reg [`TASK_MEM_ABIT:0] rra; always @(posedge rclk) rra <= ra; assign memo = mem[rra]; assign dpr_o = memo[15:0]; assign db_o = memo[23:16]; assign srx_o = memo[31:24]; assign sr_o = memo[39:32]; assign sp_o = memo[71:40]; assign y_o = memo[103:72]; assign x_o = memo[135:104]; assign acc_o = memo[167:136]; assign pc_o = memo[191:168]; assign ss_o = memo[207:192]; assign ds_o = memo[223:208]; assign cs_o = memo[239:224]; assign mapno_o = memo[245:240]; assign bl_o = memo[`TASK_MEM_ABIT+246-3:246]; endmodule module SegDescTbl(wclk, wce, wr, wa, acr_i, size_i, base_i, rclk, rce, ra, acr_o, size_o, base_o); input wclk; input wce; input wr; input [11:0] wa; input [7:0] acr_i; input [3:0] size_i; input [31:0] base_i; input rclk; input rce; input [11:0] ra; output [7:0] acr_o; output [3:0] size_o; output [31:0] base_o; reg [43:0] mem [4095:0]; reg [11:0] rra; integer n; initial begin for (n = 0; n < 4096; n = n + 1) mem[n] = 0; end always @(posedge wclk) if (wce & wr) mem[wa] <= {acr_i,size_i,base_i}; always @(posedge rclk) rra <= ra; assign acr_o = mem[rra][43:36]; assign size_o = mem[rra][35:32]; assign base_o = mem[rra][31:0]; endmodule /* module ProgramMappingTbl(clk, wr, wadr, wdat, rdat, omapno, pb, page); input clk; input wr; input [14:0] wadr; input [7:0] wdat; output [7:0] rdat; input [5:0] omapno; input [7:0] pb; output [12:0] page; reg [12:0] mem [0:16384]; reg [13:0] rradr; reg [14:0] rradr1; always @(posedge clk) begin if (wr & ~wadr[0]) mem[wadr[14:1]][7:0] <= wdat; if (wr & wadr[0]) mem[wadr[14:1]][12:8] <= wdat[4:0]; end always @(posedge clk) rradr1 <= wadr[14:0]; always @(posedge clk) rradr <= {omapno,pb}; assign page = (omapno==6'd0) ? pb : mem [rradr]; assign rdat = rradr1[0] ? mem[rradr1[14:1]][12:8] : mem[rradr1[14:1]][7:0]; endmodule */