Project

General

Profile

« Previous | Next » 

Revision 685

Added by markw over 7 years ago

Latest 65816 changes from Robs github

View differences:

ultimate_cart/veronica/FT816.v
reg cpu_clk_en;
reg clk_en;
wire clkx;
//FIXME TODO XXX BUFGCE u20 (.CE(cpu_clk_en), .I(clk), .O(clkx) );
//BUFGCE u20 (.CE(cpu_clk_en), .I(clk), .O(clkx) );
assign clkx = clk;
assign clko = clkx;
//assign clkx = clk;
......
`EOR_IMM,`EOR_ZP,`EOR_ZPX,`EOR_IX,`EOR_IY,`EOR_IYL,`EOR_ABS,`EOR_ABSX,`EOR_ABSY,`EOR_AL,`EOR_ALX,`EOR_I,`EOR_IL,`EOR_DSP,`EOR_DSPIY: begin res16 <= acc16 ^ b16; end
`LDA_IMM,`LDA_ZP,`LDA_ZPX,`LDA_IX,`LDA_IY,`LDA_IYL,`LDA_ABS,`LDA_ABSX,`LDA_ABSY,`LDA_AL,`LDA_ALX,`LDA_I,`LDA_IL,`LDA_DSP,`LDA_DSPIY: begin res16 <= b16; end
`BIT_IMM,`BIT_ZP,`BIT_ZPX,`BIT_ABS,`BIT_ABSX: begin res16 <= acc16 & b16; end
`TRB_ZP,`TRB_ABS: begin res16 <= ~acc16 & b16; wdat <= ~acc16 & b16; state <= STORE1; data_nack(); end
`TSB_ZP,`TSB_ABS: begin res16 <= acc16 | b16; wdat <= acc16 | b16; state <= STORE1; data_nack(); end
`TRB_ZP,`TRB_ABS: begin res16 <= acc16 & b16; wdat <= ~acc16 & b16; state <= STORE1; data_nack(); end
`TSB_ZP,`TSB_ABS: begin res16 <= acc16 & b16; wdat <= acc16 | b16; state <= STORE1; data_nack(); end
`LDX_IMM,`LDX_ZP,`LDX_ZPY,`LDX_ABS,`LDX_ABSY: begin res16 <= b16; end
`LDY_IMM,`LDY_ZP,`LDY_ZPX,`LDY_ABS,`LDY_ABSX: begin res16 <= b16; end
`CPX_IMM,`CPX_ZP,`CPX_ABS: begin res16 <= x16 - b16; end
......
`include "bus_task.v"
`include "misc_task.v"
`include "load_tsk.v"
task next_state;
input [5:0] nxt;
ultimate_cart/veronica/FT832.v
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2013-2015 Robert Finch, Stratford
// \\__/ o\ (C) 2013-2017 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
......
// Comment out the SUPPORT_xxx definitions to remove a core feature.
`define SUPPORT_TASK 1'b1
`define TASK_MEM 512
`define TASK_MEM_ABIT 8
`define TASK_BL 1'b1 // core uses back link register rather than stack
`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 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 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 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 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 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 BRL 9'h82
`define BRA 9'h80
`define BGT 9'h110
`define BLT 9'h130
`define BGE 9'h190
`define BLE 8'h1B0
`define JML 9'h5C
......
`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 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 PC_70 6'd5
`define PC_158 6'd6
`define PC_2316 6'd7
`define PC_3124 6'd8
`define PC_310 6'd9
`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
......
// Input Frequency is 32 times the 00 clock
module FT832(corenum, rst, clk, clko, cyc, phi11, phi12, phi81, phi82, nmi, irq, abort, e, mx, rdy, be, vpa, vda, mlb, vpb,
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'b1; // set if PC is to be true 24 bits (generates slightly more hardware).
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'b1; // controls whether the core uses task vectors or regular interrupt vectors
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 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 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 phi81;
output phi82;
input nmi;
input irq;
input irq1;
input irq2;
input irq3;
input abort;
output e;
output mx;
......
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 [7:0] dbi;
reg pg2;
reg [5:0] state; // machine state number
reg [5:0] retstate; // return state - allows 1 level of state subroutine call
......
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
......
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
......
wire [31:0] y_inc = y + 32'd1;
reg gie; // global interrupt enable (set when sp is loaded)
reg hwi; // hardware interrupt indicator
reg im;
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 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 [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 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;
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;
......
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==`BGE || ir9==`BLT || ir9==`BLE;
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
......
);
`ifdef SUPPORT_TASK
reg [`TASK_MEM_ABIT:0] tr, otr;
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:0] tskm_wa;
reg [`TASK_MEM_ABIT-3:0] tskm_wa;
wire [15:0] cs_o;
wire [15:0] ds_o;
......
wire [7:0] srx_o;
wire [7:0] dbr_o;
wire [15:0] dpr_o;
wire [`TASK_MEM_ABIT:0] bl_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 [7:0] srx_i;
reg [7:0] dbr_i;
reg [15:0] dpr_i;
reg [`TASK_MEM_ABIT:0] bl_i;
reg [`TASK_MEM_ABIT:0] back_link;
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(tskm_wa),
.wa({tmsp[tskm_wa],tskm_wa}),
.cs_i(cs_i),
.ds_i(ds_i),
.ss_i(ss_i),
......
.db_i(dbr_i),
.dpr_i(dpr_i),
.bl_i(bl_i),
.mapno_i(mapno_i),
.rclk(~clk),
.rce(1'b1),
.ra(tr),
.ra({tmsp[tr],tr}),
.cs_o(cs_o),
.ds_o(ds_o),
.ss_o(ss_o),
......
.srx_o(srx_o),
.db_o(dbr_o),
.dpr_o(dpr_o),
.bl_o(bl_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;
......
.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
......
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;
......
wire [7:0] dati = db;
wire [7:0] dati = db;//cs_pgmap ? pgo : db;
// Evaluate branches
//
......
m816 ? {stack_bank,sp16 + ir[15:8]} : {stack_page,sp[7:0]+ir[15:8]};
reg [31:0] vect;
assign rw = be ? rwo : 1'bz;
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}};
......
// - this circuit must be under the clk_i domain
//-----------------------------------------------------------------------------
//
//wire clkx = clk;
//assign clko = clkx;
reg clk_en;
reg cpu_clk_en;
reg clk_en;
wire clkx;
BUFGCE u20 (.CE(cpu_clk_en), .I(clk), .O(clkx) );
assign clko = clkx;
......
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;
......
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;
......
ds_wr <= TRUE;
ss_wr <= TRUE;
cs_wr <= FALSE;
stksz <= 2'b00; // 256 bytes
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;
im <= `TRUE;
iml <= 3'b000;
imcd <= 3'b111;
ima <= 16'h0000;
mib <= `FALSE;
gie <= 1'b0;
isIY <= 1'b0;
......
load_what <= `NOTHING;
abort_edge <= 1'b0;
abort1 <= 1'b0;
imcd <= 3'b111;
inv_icache <= TRUE;
inv_iline <= FALSE;
pc_cap <= TRUE;
tr <= 8'h00;
tskm_we <= FALSE;
tskm_wr <= FALSE;
wr_sdt <= FALSE;
ssm <= FALSE;
tj_prefix <= FALSE;
seg_fault_val = SEGF_NONE;
lla <= FALSE;
isRstVect <= `TRUE;
mapno <= 6'd0;
end
else begin
abort1 <= abort;
......
tskm_wr <= FALSE;
`endif
wr_itag <= FALSE;
`ifdef SUPPORT_SEG
wr_sdt <= FALSE;
`endif
case(state)
RESET1:
begin
......
ds_limit <= 32'hFFFFFFFF;
ss_limit <= 32'hFFFFFFFF;
ds_wr <= TRUE;
seg <= 32'd0;
lmt <= 32'hFFFF;
mem_wr <= TRUE;
`endif
first_ifetch <= TRUE;
seg <= 32'd0;
lmt <= 32'hFFFF;
mem_wr <= TRUE;
inv_icache <= FALSE;
state <= LOAD_MAC1;
end
......
begin
vda <= FALSE;
if (hit0&hit1) begin
if (imcd != 3'b111)
imcd <= {imcd[1:0],1'b0};
if (imcd == 3'b000) begin
imcd <= 3'b111;
im <= 1'b0;
end
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;
......
store_what <= (m32 | m16) ? `STW_DEF70 : `STW_DEF;
ir <= insn;
opc <= pc;
if (nmi_edge | ~irq)
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;
......
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;
seg <= 32'd0;
lmt <= 32'hFFFF;
mem_wr <= FALSE;
next_state(DECODE);
end
else if (~irq & gie & ~im) begin
else if ((irqenc > iml) && gie) begin
iml1 <= irqenc;
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;
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
else if (pc > cs_limit && m832) begin
`ifdef SUPPORT_SEG
else if (pc > cs_limit) begin
iml1 <= 3'd7;
ir[7:0] <= `BRK;
hwi <= `TRUE;
if (m832)
......
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})
......
next_state(TSK1);
end
else
`endif
next_state(DECODE);
end
else
next_state(IFETCH);
if (!abort_edge & first_ifetch) begin
first_ifetch <= FALSE;
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.
......
begin
cf <= cf | ir[8];
zf <= zf | ir[9];
im <= im | ir[10];
if (ir[10])
iml <= 3'd1;
df <= df | ir[11];
if (m816|m832) begin
x_bit <= x_bit | ir[12];
......
begin
cf <= cf & ~ir[8];
zf <= zf & ~ir[9];
im <= im & ~ir[10];
if (ir[10])
iml <= 3'd0;
df <= df & ~ir[11];
if (m816|m832) begin
x_bit <= x_bit & ~ir[12];
......
begin
cf <= cf | ir[8];
zf <= zf | ir[9];
im <= im | ir[10];
if (ir[10])
iml <= 3'd1;
df <= df | ir[11];
if (m816|m832) begin
x_bit <= x_bit | ir[12];
......
begin
cf <= cf & ~ir[8];
zf <= zf & ~ir[9];
im <= im & ~ir[10];
if (ir[10])
iml <= 3'd0;
df <= df & ~ir[11];
if (m816|m832) begin
x_bit <= x_bit & ~ir[12];
......
zf <= resz16;
end
end
`ifdef SUPPORT_SEG
`TASS: ss <= res32[15:0];
`TSA,`TYA,`TXA,`INA,`DEA,`PLA,`TSSA:
`TSSA,
`endif
`TSA,`TYA,`TXA,`INA,`DEA,`PLA:
begin
if (m32) begin
acc <= res32;
......
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] : resn16;
zf <= df ? bcsio==16'h0000 : resz16;
nf <= df ? bcsio[15] : resn32;
zf <= df ? bcsio==16'h0000 : resz32;
end
else if (m16) begin
acc[15:0] <= df ? bcsio : res32[15:0];
......
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] : resn16;
zf <= df ? bcso==16'h0000 : resz16;
nf <= df ? bcso[15] : resn32;
zf <= df ? bcso==16'h0000 : resz32;
end
else if (m16) begin
acc[15:0] <= df ? bcso : res32[15:0];
......
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,
......
// Decode
DECODE:
begin
first_ifetch <= TRUE;
moveto_ifetch();
inc_pc(24'd1);
case(ir9)
......
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;
......
next_state(DECODE);
end
`SEG: begin
inc_pc(24'd5);
seg <= ir[39:8];
ir <= {40'h00,ir[127:40]};
inc_pc(24'd3);
sdt_ra <= ir[23:8];
ir <= {24'h00,ir[127:24]};
pg2 <= FALSE;
next_state(DECODE);
next_state(SEG1);
end
`endif
`TJ: begin tj_prefix <= 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);
......
`SEC: begin cf <= 1'b1; end
`CMC: cf <= ~cf;
`CLV: begin vf <= 1'b0; end
`CLI: begin imcd <= 3'b110; end
`SEI: begin im <= 1'b1; 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
......
next_state(TASS1);
end
`ifdef SUPPORT_TASK
`TTA: res32 <= tr;
`TTA: res32 <= {mapno,1'b0,tr};
`endif
`endif
`DEA: res32 <= acc_dec;
......
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
......
`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);
`ifdef TASK_BL
begin
tr <= back_link;
tsk_pres <= 7'h0;
retstate <= IFETCH;
next_state(TSK1);
end
`else
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
`endif
end
else
`endif
......
state <= LOAD_MAC1;
end
end
end
`PHP: begin
if (m832)
if (m832 || (sop & s16))
tsk_push(`STW_SR158,1,0);
else
tsk_push(`STW_SR70,0,0);
......
`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;
if (m32) s32 <= TRUE;
else if (m16) s16 <= TRUE;
`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;
......
`PLX,`PLY:
begin
inc_sp();
`ifdef SUPPORT_SEG
seg <= ss_base;
lmt <= ss_limit;
mem_wr <= ss_wr;
if (xb32) s32 <= TRUE;
else if (xb16) s16 <= TRUE;
`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;
......
`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;
......
`PLD:
begin
inc_sp();
`ifdef SUPPORT_SEG
seg <= ss_base;
lmt <= ss_limit;
mem_wr <= ss_wr;
s16 <= TRUE;
`endif
if (!sop)
s16 <= TRUE;
load_what <= `WORD_71S;
state <= LOAD_MAC1;
retstate <= ssm ? SSM1 : IFETCH;
......
begin
inc_pc(24'd2);
radr <= zp_address;
data_read(zp_address,1);
if (lla) begin
acc <= zp_address;
next_state(IFETCH);
end
else
next_state(LOAD_MAC1);
mxb16 <= m16;
mxb32 <= m32;
if (!sop) begin
......
else if (m16) s16 <= TRUE;
end
load_what <= `LOAD_70;
state <= LOAD_MAC2;
retstate <= ssm ? SSM1 : IFETCH;
bank_wrap <= !m832;
end
......
begin
inc_pc(24'd2);
radr <= zp_address;
data_read(zp_address,1);
next_state(LOAD_MAC1);
mxb16 <= xb16;
mxb32 <= xb32;
if (!sop) begin
......
end
load_what <= `LOAD_70;
retstate <= ssm ? SSM1 : IFETCH;
state <= LOAD_MAC2;
//state <= LOAD_MAC2;
bank_wrap <= !m832;
end
`ADC_ZP,`SBC_ZP,`AND_ZP,`ORA_ZP,`EOR_ZP,`CMP_ZP,
......
end
radr <= zp_address;
wadr <= zp_address;
data_read(zp_address,1);
next_state(LOAD_MAC1);
load_what <= `LOAD_70;
state <= LOAD_MAC2;
retstate <= CALC;
bank_wrap <= !m832;
end
......
end
radr <= zp_address;
wadr <= zp_address;
data_read(zp_address,1);
next_state(LOAD_MAC1);
load_what <= `LOAD_70;
state <= LOAD_MAC2;
retstate <= CALC;
bank_wrap <= !m832;
end
......
end
radr <= zp_address;
wadr <= zp_address;
data_read(zp_address,1);
load_what <= `LOAD_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= CALC;
bank_wrap <= !m832;
end
......
else if (xb16) s16 <= TRUE;
end
radr <= zp_address;
data_read(zp_address,1);
next_state(LOAD_MAC1);
load_what <= `LOAD_70;
state <= LOAD_MAC2;
retstate <= CALC;
bank_wrap <= !m832;
end
......
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;
state <= STORE1;
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;
state <= STORE1;
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;
state <= STORE1;
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;
state <= STORE1;
bank_wrap <= !m832;
end
// Handle zp,x mode
......
begin
inc_pc(24'd2);
radr <= zpx_address;
data_read(zpx_address,1);
if (lla) begin
acc <= zpx_address;
next_state(IFETCH);
end
else
next_state(LOAD_MAC1);
mxb16 <= m16;
mxb32 <= m32;
if (!sop) begin
......
else if (m16) s16 <= TRUE;
end
load_what <= `LOAD_70;
state <= LOAD_MAC2;
retstate <= ssm ? SSM1 : IFETCH;
bank_wrap <= !m832;
end
......
begin
inc_pc(24'd2);
radr <= zpx_address;
data_read(zpx_address,1);
next_state(LOAD_MAC1);
if (!sop) begin
if (xb32) s32 <= TRUE;
else if (xb16) s16 <= TRUE;
end
load_what <= `LOAD_70;
state <= LOAD_MAC2;
retstate <= ssm ? SSM1 : IFETCH;
bank_wrap <= !m832;
end
......
inc_pc(24'd2);
radr <= zpx_address;
wadr <= zpx_address;
data_read(zpx_address,1);
next_state(LOAD_MAC1);
mxb16 <= m16;
mxb32 <= m32;
if (!sop) begin
......
end
load_what <= `LOAD_70;
retstate <= CALC;
state <= LOAD_MAC2;
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;
state <= STORE1;
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;
state <= STORE1;
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;
state <= STORE1;
bank_wrap <= !m832;
end
// Handle zp,y
......
begin
inc_pc(24'd2);
radr <= zpy_address;
data_read(zpy_address,1);
next_state(LOAD_MAC1);
if (!sop) begin
if (xb32) s32 <= TRUE;
else if (xb16) s16 <= TRUE;
end
load_what <= `LOAD_70;
state <= LOAD_MAC2;
retstate <= ssm ? SSM1 : IFETCH;
bank_wrap <= !m832;
end
......
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;
state <= STORE1;
bank_wrap <= !m832;
end
// Handle (zp,x)
......
begin
inc_pc(24'd2);
radr <= zpx_address;
data_read(zpx_address,1);
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;
data_read(zpx_address,1);
mxb16 <= m16;
mxb32 <= m32;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= CALC;
bank_wrap <= !m832;
end
......
begin
inc_pc(24'd2);
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
isIY <= `TRUE;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= ssm ? SSM1 : IFETCH;
bank_wrap <= !m832;
end
......
begin
inc_pc(24'd2);
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
isIY <= `TRUE;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= CALC;
bank_wrap <= !m832;
end
......
`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;
......
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
......
`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
......
`LDA_DSPIY:
begin
inc_pc(24'd2);
`ifdef SUPPORT_SEG
seg <= ss_base;
lmt <= ss_limit;
mem_wr <= ss_wr;
`endif
radr <= dsp_address;
mem_wr <= ss_wr;
mxb16 <= m16;
mxb32 <= m32;
isIY <= `TRUE;
......
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;
......
`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;
......
`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;
......
begin
inc_pc(24'd2);
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
isI24 <= `TRUE;
isIY24 <= `TRUE;
load_what <= `IA_70;
state <= LOAD_MAC2;
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;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
isI24 <= `TRUE;
isIY24 <= `TRUE;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= CALC;
end
`ifdef SUPPORT_NEW_INSN
......
begin
inc_pc(24'd2);
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
isI32 <= `TRUE;
isIY32 <= `TRUE;
load_what <= `IA_70;
state <= LOAD_MAC2;
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;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
isI32 <= `TRUE;
isIY32 <= `TRUE;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= CALC;
end
`endif
......
inc_pc(24'd2);
isI24 <= `TRUE;
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= ssm ? SSM1 : IFETCH;
bank_wrap <= !m832;
end
......
inc_pc(24'd2);
isI24 <= `TRUE;
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= CALC;
bank_wrap <= !m832;
end
......
inc_pc(24'd2);
isI32 <= `TRUE;
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= ssm ? SSM1 : IFETCH;
bank_wrap <= !m832;
end
......
inc_pc(24'd2);
isI32 <= `TRUE;
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
load_what <= `IA_70;
state <= LOAD_MAC2;
state <= LOAD_MAC1;
retstate <= CALC;
bank_wrap <= !m832;
end
......
begin
inc_pc(24'd2);
radr <= zp_address;
data_read(zp_address,1);
mxb16 <= m16;
mxb32 <= m32;
load_what <= `IA_70;
state <= LOAD_MAC2;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff