From 174c2644a07a2c2209e598de9fee3847a2df5185 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Wed, 12 Feb 2020 20:52:04 +0100 Subject: [PATCH] Mappy HW: single RBF + MRA + common CPU --- .../Namco Mappy Hardware/Mappy_Hardware.qsf | 6 +- Arcade_MiST/Namco Mappy Hardware/README.txt | 18 +- .../Namco Mappy Hardware/meta/digdug2.mra | 28 + .../Namco Mappy Hardware/meta/druaga.mra | 25 + .../Namco Mappy Hardware/meta/mappy.mra | 34 + .../Namco Mappy Hardware/meta/motos.mra | 29 + .../rtl/TheTowerofDruaga_mist.sv | 244 +- .../Namco Mappy Hardware/rtl/ioctrl_0.v | 50 +- .../Namco Mappy Hardware/rtl/ioctrl_1.v | 23 +- .../Namco Mappy Hardware/rtl/mc6809/mc6809.v | 80 - .../Namco Mappy Hardware/rtl/mc6809/mc6809i.v | 4156 ----------------- Arcade_MiST/Namco Mappy Hardware/rtl/mems.v | 102 - Arcade_MiST/Namco Mappy Hardware/rtl/regs.v | 110 - 13 files changed, 317 insertions(+), 4588 deletions(-) create mode 100644 Arcade_MiST/Namco Mappy Hardware/meta/digdug2.mra create mode 100644 Arcade_MiST/Namco Mappy Hardware/meta/druaga.mra create mode 100644 Arcade_MiST/Namco Mappy Hardware/meta/mappy.mra create mode 100644 Arcade_MiST/Namco Mappy Hardware/meta/motos.mra delete mode 100644 Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809.v delete mode 100644 Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809i.v delete mode 100644 Arcade_MiST/Namco Mappy Hardware/rtl/mems.v delete mode 100644 Arcade_MiST/Namco Mappy Hardware/rtl/regs.v diff --git a/Arcade_MiST/Namco Mappy Hardware/Mappy_Hardware.qsf b/Arcade_MiST/Namco Mappy Hardware/Mappy_Hardware.qsf index 818a5dfd..968d74b8 100644 --- a/Arcade_MiST/Namco Mappy Hardware/Mappy_Hardware.qsf +++ b/Arcade_MiST/Namco Mappy Hardware/Mappy_Hardware.qsf @@ -40,7 +40,7 @@ # Project-Wide Assignments # ======================== set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.0.2 -set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name LAST_QUARTUS_VERSION "13.1 SP4.26" set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:48:06 MAY 24,2017" set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files @@ -228,9 +228,9 @@ set_global_assignment -name VERILOG_FILE rtl/wsg.v set_global_assignment -name VERILOG_FILE rtl/ioctrl.v set_global_assignment -name VERILOG_FILE rtl/hvgen.v set_global_assignment -name VHDL_FILE rtl/dpram.vhd -set_global_assignment -name VERILOG_FILE rtl/mc6809/mc6809i.v -set_global_assignment -name VERILOG_FILE rtl/mc6809/mc6809.v set_global_assignment -name VERILOG_FILE rtl/pll.v set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name VERILOG_FILE ../../common/CPU/MC6809/mc6809i.v +set_global_assignment -name VERILOG_FILE ../../common/CPU/MC6809/mc6809.v set_global_assignment -name QIP_FILE ../../common/mist/mist.qip set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Namco Mappy Hardware/README.txt b/Arcade_MiST/Namco Mappy Hardware/README.txt index 165be9a0..e92d6333 100644 --- a/Arcade_MiST/Namco Mappy Hardware/README.txt +++ b/Arcade_MiST/Namco Mappy Hardware/README.txt @@ -1,13 +1,15 @@ The Tower of Druaga/Mappy/Motos/DigDug II to Mist FPGA by Slingshot -Appropriate ROMs are required at the root of the SD Card: -DRUAGA.ROM -MAPPY.ROM -MOTOS.ROM -DIGDUG2.ROM - - - +-- Usage: +-- - Create ROM and ARC files from the MRA files in the meta directory +-- using the MRA utility. +-- Example: mra -A -z /path/to/mame/roms motos.mra +-- - Copy the ROM files to the root of the SD Card +-- - Copy the RBF and ARC files to the same folder on the SD Card +-- +-- MRA utility: https://github.com/sebdel/mra-tools-c/ +-- +-- --------------------------------------------------------------------------------- -- -- Arcade: The Tower of Druaga port to MiSTer by MiSTer-X diff --git a/Arcade_MiST/Namco Mappy Hardware/meta/digdug2.mra b/Arcade_MiST/Namco Mappy Hardware/meta/digdug2.mra new file mode 100644 index 00000000..f8cd8ec4 --- /dev/null +++ b/Arcade_MiST/Namco Mappy Hardware/meta/digdug2.mra @@ -0,0 +1,28 @@ + + Dig Dug 2 + digdug2 + Druaga + + + + + + + 03 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Namco Mappy Hardware/meta/druaga.mra b/Arcade_MiST/Namco Mappy Hardware/meta/druaga.mra new file mode 100644 index 00000000..7ba9842b --- /dev/null +++ b/Arcade_MiST/Namco Mappy Hardware/meta/druaga.mra @@ -0,0 +1,25 @@ + + The Tower of Druaga + druaga + Druaga + + + + + 01 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Namco Mappy Hardware/meta/mappy.mra b/Arcade_MiST/Namco Mappy Hardware/meta/mappy.mra new file mode 100644 index 00000000..ad479a11 --- /dev/null +++ b/Arcade_MiST/Namco Mappy Hardware/meta/mappy.mra @@ -0,0 +1,34 @@ + + Mappy + mappy + + + + + + + + Druaga + + 02 + + + + + + + + + + + + + + + + + + + + + diff --git a/Arcade_MiST/Namco Mappy Hardware/meta/motos.mra b/Arcade_MiST/Namco Mappy Hardware/meta/motos.mra new file mode 100644 index 00000000..47ac6e24 --- /dev/null +++ b/Arcade_MiST/Namco Mappy Hardware/meta/motos.mra @@ -0,0 +1,29 @@ + + Motos + motos + Druaga + + + + + + + + 04 + + + + + + + + + + + + + + + + + diff --git a/Arcade_MiST/Namco Mappy Hardware/rtl/TheTowerofDruaga_mist.sv b/Arcade_MiST/Namco Mappy Hardware/rtl/TheTowerofDruaga_mist.sv index 3bf378fb..fcc56eee 100644 --- a/Arcade_MiST/Namco Mappy Hardware/rtl/TheTowerofDruaga_mist.sv +++ b/Arcade_MiST/Namco Mappy Hardware/rtl/TheTowerofDruaga_mist.sv @@ -28,28 +28,99 @@ module TheTowerofDruaga_mist ( ); -// Uncomment one of these to load the default ROM: - -`define CORE_NAME "DRUAGA" -//`define CORE_NAME "MAPPY" -//`define CORE_NAME "MOTOS" -//`define CORE_NAME "DIGDUG2" - -//`define CORE_NAME "GROBDA" -//`define CORE_NAME "PHOZON" - - `include "rtl\build_id.v" +`define CORE_NAME "DRUAGA" +wire [6:0] core_mod; + localparam CONF_STR = { - `CORE_NAME,";ROM;", + `CORE_NAME, ";ROM;", "O2,Rotate Controls,Off,On;", "O34,Scanlines,Off,25%,50%,75%;", "O5,Blend,Off,On;", + "DIP;", + "OU,Service Mode,Off,On;", + "OT,Freeze,Off,On;", "T0,Reset;", "V,v1.00.",`BUILD_DATE }; +wire rotate = status[2]; +wire [1:0] scanlines = status[4:3]; +wire blend = status[5]; + +wire dcFreeze = status[29]; +wire dcService = status[30]; +wire dcCabinet = 1'b0; // (upright only) + +// The Tower of Druaga [t] +wire [1:0] dtLives = status[9:8]; + +// Mappy [m] +wire dmRoundP = status[6]; +wire [2:0] dmRank = status[12:10]; +wire dmDemoSnd = status[13]; +wire [2:0] dmExtend = status[16:14]; +wire [1:0] dmLives = status[18:17]; + +// DigDug2 [d] +wire ddLives = status[19]; +wire [1:0] ddExtend = status[21:20]; +wire ddLevelSel = status[22]; + +// Motos [o] +wire doLives = status[23]; +wire doRank = status[24]; +wire [1:0] doExtend = status[26:25]; +wire doDemoSnd = status[27]; + +reg [7:0] DSW0; +reg [7:0] DSW1; +reg [7:0] DSW2; + +reg [5:0] INP0; +reg [5:0] INP1; +reg [2:0] INP2; + +always @(*) begin + INP0 = { m_fireB, m_fireA, m_left, m_down, m_right, m_up}; + INP1 = { m_fire2B, m_fire2A, m_left2, m_down2, m_right2, m_up2 }; + INP2 = { m_coin1 | m_coin2, m_two_players, m_one_player }; + DSW0 = 0; + DSW1 = 0; + DSW2 = 0; + + case (core_mod) + 7'h0, 7'h1: // DRUAGA + begin + DSW0 = {2'd0,dtLives,4'd0}; + DSW1 = {dcCabinet,6'd0,dcFreeze}; + DSW2 = {DSW1[3:0],dcService,3'd0}; + end + 7'h2: // MAPPY + begin + DSW0 = {dcFreeze,dmRoundP,dmDemoSnd,2'd0,dmRank}; + DSW1 = {dmLives,dmExtend,3'd0}; + DSW2 = {{2{dcService,dcCabinet,2'd0}}}; + end + 7'h3: // DIGDUG2 + begin + DSW0 = {2'd0,ddLives,5'd0}; + DSW1 = {dcCabinet,3'd0,dcFreeze,ddLevelSel,ddExtend}; + DSW2 = {DSW1[3:0],dcService,3'd0}; + end + 7'h4: // MOTOS + begin + DSW0 = {doDemoSnd,doExtend,doRank,doLives,3'd0}; + DSW1 = {dcService,dcCabinet,6'd0}; + DSW2 = {8'd0}; + end + 7'h5: ;// GROBDA + 7'h6: ;// PHOZON + default: ; + endcase +end + assign LED = ~ioctl_downl; assign AUDIO_R = AUDIO_L; assign SDRAM_CLK = clock_48; @@ -70,24 +141,50 @@ wire [7:0] joystick_0; wire [7:0] joystick_1; wire scandoublerD; wire ypbpr; -wire [7:0] audio; -wire hs, vs; -wire hb, vb; -wire blankn = ~(hb | vb); -wire [2:0] r, g; -wire [1:0] b; -wire [14:0] rom_addr; -wire [15:0] rom_do; -wire [12:0] snd_addr; -wire [15:0] snd_do; +wire no_csync; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; + +user_io #(.STRLEN($size(CONF_STR)>>3))user_io( + .clk_sys (clock_48 ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + wire ioctl_downl; wire [7:0] ioctl_index; wire ioctl_wr; wire [24:0] ioctl_addr; wire [7:0] ioctl_dout; -wire key_strobe; -wire key_pressed; -wire [7:0] key_code; + +/* +ROM map +00000-07FFF cpu0 32k 3.1d+1.1b (+2.1c in Mappy) +08000-0BFFF spchip0 16k 6.3m +0C000-0FFFF spchip1 16k 7.3m +10000-11FFF cpu1 8k 4.1k +12000-12FFF bgchip 4k 5.3b +13000-133FF spclut 1k 7.5k +13400-134FF bgclut 256b 6.4c +13500-135FF wave 256b 3.3m +13600-1361F palet 32b 5.5b +*/ data_io data_io( .clk_sys ( clock_48 ), @@ -102,6 +199,11 @@ data_io data_io( ); reg port1_req, port2_req; +wire [14:0] rom_addr; +wire [15:0] rom_do; +wire [12:0] snd_addr; +wire [15:0] snd_do; + sdram sdram( .*, .init_n ( pll_locked ), @@ -154,17 +256,16 @@ always @(posedge clock_48) begin reset <= status[0] | buttons[1] | ioctl_downl | ~rom_loaded; end -wire [7:0] DSW0 = 0;//{2'h0,status[7:6],4'h0}; -wire [7:0] DSW1 = 0; -wire [7:0] DSW2 = 0;//{4'h0,status[8],3'h0}; - -wire [5:0] INP0 = { m_bomb, m_fire, m_left, m_down, m_right, m_up}; -wire [5:0] INP1 = { m_bomb, m_fire, m_left, m_down, m_right, m_up}; -wire [2:0] INP2 = { btn_coin, btn_two_players, btn_one_player }; - wire PCLK, PCLK_EN; wire [8:0] HPOS,VPOS; +wire [7:0] audio; +wire hs, vs; +wire hb, vb; +wire blankn = ~(hb | vb); +wire [2:0] r, g; +wire [1:0] b; + fpga_druaga fpga_druaga( .MCLK(clock_48), .CLKCPUx2(clock_6), @@ -218,32 +319,13 @@ mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video( .VGA_B ( VGA_B ), .VGA_VS ( VGA_VS ), .VGA_HS ( VGA_HS ), - .rotate ( {1'b1,status[2]} ), + .rotate ( { 1'b1, rotate } ), .scandoubler_disable( scandoublerD ), - .scanlines ( status[4:3] ), - .blend ( status[5] ), + .scanlines ( scanlines ), + .blend ( blend ), .ypbpr ( ypbpr ) ); -user_io #(.STRLEN(($size(CONF_STR)>>3)))user_io( - .clk_sys (clock_48 ), - .conf_str (CONF_STR ), - .SPI_CLK (SPI_SCK ), - .SPI_SS_IO (CONF_DATA0 ), - .SPI_MISO (SPI_DO ), - .SPI_MOSI (SPI_DI ), - .buttons (buttons ), - .switches (switches ), - .scandoubler_disable (scandoublerD ), - .ypbpr (ypbpr ), - .key_strobe (key_strobe ), - .key_pressed (key_pressed ), - .key_code (key_code ), - .joystick_0 (joystick_0 ), - .joystick_1 (joystick_1 ), - .status (status ) - ); - dac #(.C_bits(16))dac( .clk_i(clock_48), .res_n_i(1), @@ -251,40 +333,24 @@ dac #(.C_bits(16))dac( .dac_o(AUDIO_L) ); -// Rotated Normal -wire m_up = ~status[2] ? btn_left | joystick_0[1] | joystick_1[1] : btn_up | joystick_0[3] | joystick_1[3]; -wire m_down = ~status[2] ? btn_right | joystick_0[0] | joystick_1[0] : btn_down | joystick_0[2] | joystick_1[2]; -wire m_left = ~status[2] ? btn_down | joystick_0[2] | joystick_1[2] : btn_left | joystick_0[1] | joystick_1[1]; -wire m_right = ~status[2] ? btn_up | joystick_0[3] | joystick_1[3] : btn_right | joystick_0[0] | joystick_1[0]; -wire m_fire = btn_fire1 | joystick_0[4] | joystick_1[4]; -wire m_bomb = btn_fire2 | joystick_0[5] | joystick_1[5]; +wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF; +wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; -reg btn_one_player = 0; -reg btn_two_players = 0; -reg btn_left = 0; -reg btn_right = 0; -reg btn_down = 0; -reg btn_up = 0; -reg btn_fire1 = 0; -reg btn_fire2 = 0; -//reg btn_fire3 = 0; -reg btn_coin = 0; - -always @(posedge clock_48) begin - if(key_strobe) begin - case(key_code) - 'h75: btn_up <= key_pressed; // up - 'h72: btn_down <= key_pressed; // down - 'h6B: btn_left <= key_pressed; // left - 'h74: btn_right <= key_pressed; // right - 'h76: btn_coin <= key_pressed; // ESC - 'h05: btn_one_player <= key_pressed; // F1 - 'h06: btn_two_players <= key_pressed; // F2 -// 'h14: btn_fire3 <= key_pressed; // ctrl - 'h11: btn_fire2 <= key_pressed; // alt - 'h29: btn_fire1 <= key_pressed; // Space - endcase - end -end +arcade_inputs inputs ( + .clk ( clock_48 ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( 2'b11 ), + .joyswap ( 1'b0 ), + .oneplayer ( 1'b1 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), + .player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ) +); endmodule diff --git a/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_0.v b/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_0.v index 9bed2f27..f86ec387 100644 --- a/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_0.v +++ b/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_0.v @@ -1,40 +1,32 @@ //------------------------------------------ // I/O Chip for "Mappy/Druaga/DigDug2" // -// Copyright (c) 2007 MiSTer-X +// Copyright (c) 2007,19 MiSTer-X //------------------------------------------ -// TODO: DSW2 = DIPSW[23:16] case ( mema[4'h8] ) - 4'h1: begin - mema[4'h0] <= 0; - mema[4'h1] <= 0; - mema[4'h2] <= 0; - mema[4'h3] <= 0; - end - - 4'h3: begin + 4'h1,4'h3: begin credit_add = 0; credit_sub = 0; if ( iCSTART12[2] & ( credits < 99 ) ) begin credit_add = 8'h01; - credits = credits + 1'd1; + credits = credits + 1; end if ( mema[4'h9] == 0 ) begin if ( ( credits >= 2 ) & iCSTART12[1] ) begin credit_sub = 8'h02; - credits = credits - 2'd1; + credits = credits - 2; end else if ( ( credits >= 1 ) & iCSTART12[0] ) begin credit_sub = 8'h01; - credits = credits - 1'd1; + credits = credits - 1; end end mema[4'h0] <= credit_add; - mema[4'h1] <= credit_sub; + mema[4'h1] <= credit_sub | {7'd0,CSTART12[0]}; mema[4'h2] <= CREDIT_TENS; mema[4'h3] <= CREDIT_ONES; mema[4'h4] <= STKTRG12[3:0]; @@ -65,21 +57,14 @@ mema[4'h7] <= 4'hD; end - default: begin end + default:; endcase case ( memb[4'h8] ) - 4'h1: begin - memb[4'h0] <= 0; - memb[4'h1] <= 0; - memb[4'h2] <= 0; - memb[4'h3] <= 0; - end - - 4'h3: begin + 4'h1,4'h3: begin memb[4'h0] <= 0; memb[4'h1] <= 0; memb[4'h2] <= 0; @@ -91,15 +76,18 @@ end 4'h4: begin - memb[4'h0] <= DIPSW[11:8]; - memb[4'h1] <= DIPSW[3:0]; - memb[4'h2] <= DIPSW[7:4]; - memb[4'h4] <= DIPSW[15:12]; - memb[4'h6] <= DIPSW[7:4]; + memb[4'h0] <= DIPSW[11: 8]; // (P0) DSW1 Mappy + memb[4'h1] <= DIPSW[15:12]; + + memb[4'h2] <= DIPSW[ 3: 0]; // (P1) DSW0 + memb[4'h4] <= DIPSW[ 7: 4]; + + memb[4'h5] <={DIPSW[15:14],STKTRG12[ 5],iSTKTRG12[ 5]}; // (P2) DSW1 Druaga/DigDug2 + memb[4'h6] <= DIPSW[23:20]; // IsMappy ? DIPSW[19:16] : DIPSW[11:8] + + memb[4'h7] <={DIPSW[19:18],STKTRG12[11],iSTKTRG12[11]}; // (P3) DSW2 memb[4'h3] <= 0; - memb[4'h5] <= { DIPSW[3:2], STKTRG12[ 5], iSTKTRG12[ 5] }; - memb[4'h7] <= { 2'b00, STKTRG12[11], iSTKTRG12[11] }; end 4'h5: begin @@ -113,7 +101,7 @@ memb[4'h7] <= 4'hD; end - default: begin end + default:; endcase diff --git a/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_1.v b/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_1.v index cab08e36..9e12d024 100644 --- a/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_1.v +++ b/Arcade_MiST/Namco Mappy Hardware/rtl/ioctrl_1.v @@ -1,17 +1,21 @@ //------------------------------------------ // I/O Chip for "Motos" // -// Copyright (c) 2007 MiSTer-X +// Copyright (c) 2007,19 MiSTer-X //------------------------------------------ -// TODO: DSW2 = DIPSW[23:16] case ( mema[4'h8] ) 4'h1: begin - mema[4'h0] <= { 3'b00, CSTART12[2] }; + mema[4'h0] <= { 3'd0, CSTART12[2] }; mema[4'h1] <= STKTRG12[3:0]; mema[4'h2] <= STKTRG12[9:6]; mema[4'h3] <= { CSTART12[1], CSTART12[0], STKTRG12[10], STKTRG12[4] }; + mema[4'h4] <= STKTRG12[9:6]; + mema[4'h5] <= STKTRG12[9:6]; + mema[4'h6] <= STKTRG12[9:6]; + mema[4'h7] <= STKTRG12[9:6]; + mema[4'h9] <= 0; end 4'h8: begin @@ -19,8 +23,8 @@ mema[4'h1] <= 4'h9; end - default: begin end - + default:; + endcase @@ -32,17 +36,18 @@ end 4'h9: begin + memb[4'h2] <= DIPSW[3:0]; + memb[4'h4] <= DIPSW[7:4]; + memb[4'h6] <= DIPSW[15:12]; + memb[4'h0] <= 0; memb[4'h1] <= 0; - memb[4'h2] <= 0; memb[4'h3] <= 0; - memb[4'h4] <= 0; memb[4'h5] <= 0; - memb[4'h6] <= 0; memb[4'h7] <= 0; end - default: begin end + default:; endcase diff --git a/Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809.v b/Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809.v deleted file mode 100644 index b19d1552..00000000 --- a/Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809.v +++ /dev/null @@ -1,80 +0,0 @@ -`timescale 1ns / 1ps -////////////////////////////////////////////////////////////////////////////////// -// Company: -// Engineer: -// -// Create Date: 08:11:34 09/23/2016 -// Design Name: -// Module Name: mc6809e -// Project Name: -// Target Devices: -// Tool versions: -// Description: -// -// Dependencies: -// -// Revision: -// Revision 0.01 - File Created -// Additional Comments: -// -////////////////////////////////////////////////////////////////////////////////// -module mc6809( - input [7:0] D, - output [7:0] DOut, - output [15:0] ADDR, - output RnW, - output E, - output Q, - output BS, - output BA, - input nIRQ, - input nFIRQ, - input nNMI, - input EXTAL, - input XTAL, - input nHALT, - input nRESET, - input MRDY, - input nDMABREQ - - , output [111:0] RegData - - ); - -reg [1:0] clk_phase=2'b00; - -wire CLK; -assign CLK=EXTAL; - -wire LIC; -wire BUSY; -wire AVMA; -reg rE; -reg rQ; -assign E = rE; -assign Q = rQ; - -mc6809i cpucore(.D(D), .DOut(DOut), .ADDR(ADDR), .RnW(RnW), .E(E), .Q(Q), .BS(BS), .BA(BA), .nIRQ(nIRQ), .nFIRQ(nFIRQ), - .nNMI(nNMI), .AVMA(AVMA), .BUSY(BUSY), .LIC(LIC), .nHALT(nHALT), .nRESET(nRESET), .nDMABREQ(nDMABREQ) - ,.RegData(RegData) - ); - -always @(negedge CLK) -begin - case (clk_phase) - 2'b00: - rE <= 0; - 2'b01: - rQ <= 1; - 2'b10: - rE <= 1; - 2'b11: - rQ <= 0; - endcase - - if (MRDY == 1'b1) - clk_phase <= clk_phase + 2'b01; -end - - -endmodule diff --git a/Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809i.v b/Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809i.v deleted file mode 100644 index 5725aab4..00000000 --- a/Arcade_MiST/Namco Mappy Hardware/rtl/mc6809/mc6809i.v +++ /dev/null @@ -1,4156 +0,0 @@ -`timescale 1ns / 1ns -////////////////////////////////////////////////////////////////////////////////// -// Company: -// Engineer: Greg Miller -// Copyright (c) 2016, Greg Miller -// -// Create Date: 14:26:59 08/13/2016 -// Design Name: -// Module Name: mc6809 -// Project Name: Cycle-Accurate 6809 Core -// Target Devices: -// Tool versions: -// Description: -// -// Dependencies: Intended to be standalone Vanilla Verilog. -// -// Revision: -// Revision 1.0 - Initial Release -// Additional Comments: -// -////////////////////////////////////////////////////////////////////////////////// - - -// -// The 6809 has incomplete instruction decoding. A collection of instructions, if met, end up actually behaving like -// a binary-adjacent neighbor. -// -// The soft core permits three different behaviors for this situation, controlled by the instantiation parameter -// ILLEGAL_INSTRUCTIONS -// -// "GHOST" - Mimic the 6809's incomplete decoding. This is as similar to a hard 6809 as is practical. [DEFAULT] -// -// "STOP" - Cause the soft core to cease execution, placing $DEAD on the address bus and R/W to 'read'. Interrupts, -// bus control (/HALT, /DMABREQ), etc. are ignored. The core intentionally seizes in this instance. -// (Frankly, this is useful when making changes to the core and you have a logic analyzer connected.) -// -// "IGNORE"- Cause the soft core to merely ignore illegal instructions. It will consider them 1-byte instructions and -// attempt to fetch and run an exception 1 byte later. -// - -module mc6809i -#( - parameter ILLEGAL_INSTRUCTIONS="GHOST" -) -( - - input [7:0] D, - output [7:0] DOut, - output [15:0] ADDR, - output RnW, - input E, - input Q, - output BS, - output BA, - input nIRQ, - input nFIRQ, - input nNMI, - output AVMA, - output BUSY, - output LIC, - input nHALT, - input nRESET, - input nDMABREQ, - output [111:0] RegData -); - -reg [7:0] DOutput; - -assign DOut = DOutput; - -reg RnWOut; // Combinatorial - -reg rLIC; -assign LIC = rLIC; - -reg rAVMA; -assign AVMA = rAVMA; - -reg rBUSY; -assign BUSY = rBUSY; - -// Bus control -// BS BA -// 0 0 normal (CPU running, CPU is master) -// 0 1 Interrupt Ack -// 1 0 Sync Ack -// 1 1 CPU has gone high-Z on A, D, R/W -// - -assign RnW = RnWOut; - - -///////////////////////////////////////////////// -// Vectors -`define RESET_VECTOR 16'HFFFE -`define NMI_VECTOR 16'HFFFC -`define SWI_VECTOR 16'HFFFA -`define IRQ_VECTOR 16'HFFF8 -`define FIRQ_VECTOR 16'HFFF6 -`define SWI2_VECTOR 16'HFFF4 -`define SWI3_VECTOR 16'HFFF2 -`define Reserved_VECTOR 16'HFFF0 - -////////////////////////////////////////////////////// -// Latched registers -// - -// The last-latched copy. -reg [7:0] a; -reg [7:0] b; -reg [15:0] x; -reg [15:0] y; -reg [15:0] u; -reg [15:0] s; -reg [15:0] pc; -reg [7:0] dp; -reg [7:0] cc; -reg [15:0] tmp; -reg [15:0] addr; -reg [15:0] ea; - - -// Debug ability to export register contents -assign RegData[7:0] = a; -assign RegData[15:8] = b; -assign RegData[31:16] = x; -assign RegData[47:32] = y; -assign RegData[63:48] = s; -assign RegData[79:64] = u; -assign RegData[87:80] = cc; -assign RegData[95:88] = dp; -assign RegData[111:96] = pc; - - - -// The values as being calculated -reg [7:0] a_nxt; -reg [7:0] b_nxt; -reg [15:0] x_nxt; -reg [15:0] y_nxt; -reg [15:0] u_nxt; -reg [15:0] s_nxt; -reg [15:0] pc_nxt; -reg [7:0] dp_nxt; -reg [7:0] cc_nxt; -reg [15:0] addr_nxt; -reg [15:0] ea_nxt; -reg [15:0] tmp_nxt; - -reg BS_nxt; -reg BA_nxt; - -// for ADDR, BS/BA, assign them to the flops -assign BS = BS_nxt; -assign BA = BA_nxt; -assign ADDR=addr_nxt; - -localparam CC_E= 8'H80; -localparam CC_F= 8'H40; -localparam CC_H= 8'H20; -localparam CC_I= 8'H10; -localparam CC_N= 8'H08; -localparam CC_Z= 8'H04; -localparam CC_V= 8'H02; -localparam CC_C= 8'H01; - -localparam CC_E_BIT= 3'd7; -localparam CC_F_BIT= 3'd6; -localparam CC_H_BIT= 3'd5; -localparam CC_I_BIT= 3'd4; -localparam CC_N_BIT= 3'd3; -localparam CC_Z_BIT= 3'd2; -localparam CC_V_BIT= 3'd1; -localparam CC_C_BIT= 3'd0; - -// Convenience calculations -reg [15:0] pc_p1; -reg [15:0] pc_p2; -reg [15:0] pc_p3; -reg [15:0] s_p1; -reg [15:0] s_m1; -reg [15:0] u_p1; -reg [15:0] u_m1; -reg [15:0] addr_p1; -reg [15:0] ea_p1; - -////////////////////////////////////////////////////// -// NMI Mask -// -// NMI is supposed to be masked - despite the name - until the 6809 loads a value into S. -// Frankly, I'm cheating slightly. If someone does a LDS #$0, it won't disable the mask. Pretty much anything else -// that changes the value of S from the default (which is currently $0) will clear the mask. A reset will set the mask again. -reg NMIMask; - -reg NMILatched; -reg NMISample; -reg NMISample2; -reg NMIClear; -reg NMIClear_nxt; -wire wNMIClear = NMIClear; - -reg IRQLatched; - -reg IRQSample; -reg IRQSample2; -reg FIRQLatched; -reg FIRQSample; -reg FIRQSample2; -reg HALTLatched; -reg HALTSample; -reg HALTSample2; -reg DMABREQLatched; -reg DMABREQSample; -reg DMABREQSample2; - -// Interrupt types -localparam INTTYPE_NMI = 3'H0 ; -localparam INTTYPE_IRQ = 3'H1 ; -localparam INTTYPE_FIRQ = 3'H2 ; -localparam INTTYPE_SWI = 3'H3 ; -localparam INTTYPE_SWI2 = 3'H4 ; -localparam INTTYPE_SWI3 = 3'H5 ; - -reg [2:0] IntType; -reg [2:0] IntType_nxt; - -////////////////////////////////////////////////////// -// Instruction Fetch Details -// -reg InstPage2; -reg InstPage3; -reg InstPage2_nxt; -reg InstPage3_nxt; - -reg [7:0] Inst1; -reg [7:0] Inst2; -reg [7:0] Inst3; -reg [7:0] Inst1_nxt; -reg [7:0] Inst2_nxt; -reg [7:0] Inst3_nxt; - - -localparam CPUSTATE_RESET = 7'd0; -localparam CPUSTATE_RESET0 = 7'd1; - -localparam CPUSTATE_RESET2 = 7'd3; -localparam CPUSTATE_FETCH_I1 = 7'd4; -localparam CPUSTATE_FETCH_I1V2 = 7'd5; -localparam CPUSTATE_FETCH_I2 = 7'd8; - -localparam CPUSTATE_LBRA_OFFSETLOW = 7'd17; -localparam CPUSTATE_LBRA_DONTCARE = 7'd18; -localparam CPUSTATE_LBRA_DONTCARE2 = 7'd19; - - - -localparam CPUSTATE_BRA_DONTCARE = 7'd20; - -localparam CPUSTATE_BSR_DONTCARE1 = 7'd21; -localparam CPUSTATE_BSR_DONTCARE2 = 7'd22; -localparam CPUSTATE_BSR_RETURNLOW = 7'd23; -localparam CPUSTATE_BSR_RETURNHIGH = 7'd24; - -localparam CPUSTATE_TFR_DONTCARE1 = 7'd26; -localparam CPUSTATE_TFR_DONTCARE2 = 7'd27; -localparam CPUSTATE_TFR_DONTCARE3 = 7'd28; -localparam CPUSTATE_TFR_DONTCARE4 = 7'd29; - -localparam CPUSTATE_EXG_DONTCARE1 = 7'd30; -localparam CPUSTATE_EXG_DONTCARE2 = 7'd31; -localparam CPUSTATE_EXG_DONTCARE3 = 7'd32; -localparam CPUSTATE_EXG_DONTCARE4 = 7'd33; -localparam CPUSTATE_EXG_DONTCARE5 = 7'd34; -localparam CPUSTATE_EXG_DONTCARE6 = 7'd35; - -localparam CPUSTATE_ABX_DONTCARE = 7'd36; - -localparam CPUSTATE_RTS_HI = 7'd38; -localparam CPUSTATE_RTS_LO = 7'd39; -localparam CPUSTATE_RTS_DONTCARE2 = 7'd40; - -localparam CPUSTATE_16IMM_LO = 7'd41; -localparam CPUSTATE_ALU16_DONTCARE = 7'd42; -localparam CPUSTATE_DIRECT_DONTCARE = 7'd43; - -localparam CPUSTATE_ALU_EA = 7'd44; - -localparam CPUSTATE_ALU_DONTCARE = 7'd46; -localparam CPUSTATE_ALU_WRITEBACK = 7'd47; - -localparam CPUSTATE_LD16_LO = 7'd48; - -localparam CPUSTATE_ST16_LO = 7'd49; -localparam CPUSTATE_ALU16_LO = 7'd50; - - - - -localparam CPUSTATE_JSR_DONTCARE = 7'd53; -localparam CPUSTATE_JSR_RETLO = 7'd54; -localparam CPUSTATE_JSR_RETHI = 7'd55; -localparam CPUSTATE_EXTENDED_ADDRLO = 7'd56; -localparam CPUSTATE_EXTENDED_DONTCARE = 7'd57; -localparam CPUSTATE_INDEXED_BASE = 7'd58; - - -localparam CPUSTATE_IDX_DONTCARE3 = 7'd60; - -localparam CPUSTATE_IDX_OFFSET_LO = 7'd61; -localparam CPUSTATE_IDX_16OFFSET_LO = 7'd62; - -localparam CPUSTATE_IDX_16OFF_DONTCARE0= 7'd63; -localparam CPUSTATE_IDX_16OFF_DONTCARE1= 7'd64; -localparam CPUSTATE_IDX_16OFF_DONTCARE2= 7'd65; -localparam CPUSTATE_IDX_16OFF_DONTCARE3= 7'd66; - -localparam CPUSTATE_IDX_DOFF_DONTCARE1 = 7'd68; -localparam CPUSTATE_IDX_DOFF_DONTCARE2 = 7'd69; -localparam CPUSTATE_IDX_DOFF_DONTCARE3 = 7'd70; -localparam CPUSTATE_IDX_PC16OFF_DONTCARE = 7'd71; - -localparam CPUSTATE_IDX_EXTIND_LO = 7'd72; -localparam CPUSTATE_IDX_EXTIND_DONTCARE = 7'd73; - -localparam CPUSTATE_INDIRECT_HI = 7'd74; -localparam CPUSTATE_INDIRECT_LO = 7'd75; -localparam CPUSTATE_INDIRECT_DONTCARE = 7'd76; -localparam CPUSTATE_MUL_ACTION = 7'd77; - -localparam CPUSTATE_PSH_DONTCARE1 = 7'd80; -localparam CPUSTATE_PSH_DONTCARE2 = 7'd81; -localparam CPUSTATE_PSH_DONTCARE3 = 7'd82; -localparam CPUSTATE_PSH_ACTION = 7'd83; - -localparam CPUSTATE_PUL_DONTCARE1 = 7'd84; -localparam CPUSTATE_PUL_DONTCARE2 = 7'd85; -localparam CPUSTATE_PUL_ACTION = 7'd86; - -localparam CPUSTATE_NMI_START = 7'd87; -localparam CPUSTATE_IRQ_DONTCARE = 7'd88; -localparam CPUSTATE_IRQ_START = 7'd89; -localparam CPUSTATE_IRQ_DONTCARE2 = 7'd90; -localparam CPUSTATE_IRQ_VECTOR_HI = 7'd91; -localparam CPUSTATE_IRQ_VECTOR_LO = 7'd92; -localparam CPUSTATE_FIRQ_START = 7'd93; -localparam CPUSTATE_CC_DONTCARE = 7'd94; -localparam CPUSTATE_SWI_START = 7'd95; - -localparam CPUSTATE_TST_DONTCARE1 = 7'd96; -localparam CPUSTATE_TST_DONTCARE2 = 7'd97; - -localparam CPUSTATE_DEBUG = 7'd98; - -localparam CPUSTATE_16IMM_DONTCARE = 7'd99; - -localparam CPUSTATE_HALTED = 7'd100; - -localparam CPUSTATE_HALT_EXIT2 = 7'd102; -localparam CPUSTATE_STOP = 7'd105; -localparam CPUSTATE_STOP2 = 7'd106; -localparam CPUSTATE_STOP3 = 7'd107; - - -localparam CPUSTATE_CWAI = 7'd108; -localparam CPUSTATE_CWAI_DONTCARE1 = 7'd109; -localparam CPUSTATE_CWAI_POST = 7'd110; - -localparam CPUSTATE_DMABREQ = 7'd111; -localparam CPUSTATE_DMABREQ_EXIT = 7'd112; -localparam CPUSTATE_SYNC = 7'd113; -localparam CPUSTATE_SYNC_EXIT = 7'd114; - -localparam CPUSTATE_INT_DONTCARE = 7'd115; - - -reg [6:0] CpuState = CPUSTATE_RESET; -reg [6:0] CpuState_nxt = CPUSTATE_RESET; - -reg [6:0] NextState = CPUSTATE_RESET; -reg [6:0] NextState_nxt = CPUSTATE_RESET; - -wire [6:0] PostIllegalState; - -// If we encounter something like an illegal addressing mode (an index mode that's illegal for instance) -// What state should we go to? -generate -if (ILLEGAL_INSTRUCTIONS=="STOP") -begin : postillegal - assign PostIllegalState = CPUSTATE_STOP; -end -else -begin - assign PostIllegalState = CPUSTATE_FETCH_I1; -end -endgenerate - - - -/////////////////////////////////////////////////////////////////////// - -// -// MapInstruction - Considering how the core was instantiated, this -// will either directly return D[7:0] *or* remap values from D[7:0] -// that relate to undefined instructions in the 6809 to the instructions -// that the 6809 actually executed when these were encountered, due to -// incomplete decoding. -// -// NEG, COM, LSR, DEC - these four instructions, in Direct, Inherent (A or B) -// Indexed, or Extended addressing do not actually decode bit 0 on the instruction. -// Thus, for instance, a $51 encountered will be executed as a $50, which is a NEGB. -// - -// Specifically, the input is an instruction; if it matches an unknown instruction that the -// 6809 is known to ghost to another instruction, the output of the function -// is the the instruction that actually gets executed. Otherwise, the output is the -// input. - -function [7:0] MapInstruction(input [7:0] i); -reg [3:0] topnyb; -reg [3:0] btmnyb; -reg [7:0] newinst; -begin - newinst = i; - - topnyb = i[7:4]; - btmnyb = i[3:0]; - - if ( (topnyb == 4'H0) || - (topnyb == 4'H4) || - (topnyb == 4'H5) || - (topnyb == 4'H6) || - (topnyb == 4'H7) - ) - begin - if (btmnyb == 4'H1) - newinst = {topnyb, 4'H0}; - if (btmnyb == 4'H2) - newinst = {topnyb, 4'H3}; - if (btmnyb == 4'H5) - newinst = {topnyb, 4'H4}; - if (btmnyb == 4'HB) - newinst = {topnyb, 4'HA}; - end - MapInstruction = newinst; -end -endfunction - - -wire [7:0] MappedInstruction; -generate -if (ILLEGAL_INSTRUCTIONS=="GHOST") -begin : ghost - assign MappedInstruction = MapInstruction(D); -end -else -begin - assign MappedInstruction = D; -end -endgenerate - - - -/////////////////////////////////////////////////////////////////////// - -function IllegalInstruction(input [7:0] i); -reg [3:0] hi; -reg [3:0] lo; -reg illegal; -begin - illegal = 1'b0; - hi = i[7:4]; - lo = i[3:0]; - if ( (hi == 4'H0) || (hi == 4'H4) || (hi == 4'H5) || (hi == 4'H6) || (hi == 4'H7) ) - begin - if ( (lo == 4'H1) || (lo == 4'H2) || (lo == 4'H5) || (lo == 4'HB) ) - illegal = 1'b1; - if (lo == 4'HE) - if ( (hi == 4'H4) || (hi == 4'H5) ) - illegal = 1'b1; - end - if (hi == 4'H3) - begin - if ( (lo == 4'H8) || (lo == 4'HE) ) - illegal = 1'b1; - end - if (hi == 4'H1) - begin - if ( (lo == 4'H4) || (lo == 4'H5) || (lo == 4'H8) || (lo == 4'HB) ) - illegal = 1'b1; - end - if ( (hi == 4'H8) || (hi == 4'HC) ) - begin - if ( (lo == 4'H7) || (lo == 4'HF) ) - illegal = 1'b1; - if ( lo == 4'HD ) - if (hi == 4'HC) - illegal = 1'b1; - end - IllegalInstruction = illegal; -end -endfunction - -wire IsIllegalInstruction; - -generate -if (ILLEGAL_INSTRUCTIONS=="GHOST") -begin : never_illegal - assign IsIllegalInstruction = 1'b0; -end -else -begin - assign IsIllegalInstruction = IllegalInstruction(Inst1); -end -endgenerate - -wire [6:0] IllegalInstructionState; -generate -if (ILLEGAL_INSTRUCTIONS=="IGNORE") -begin : illegal_state - assign IllegalInstructionState = CPUSTATE_FETCH_I1; -end -else if (ILLEGAL_INSTRUCTIONS=="STOP") -begin - assign IllegalInstructionState = CPUSTATE_STOP; -end -else -begin - assign IllegalInstructionState = 7'd0; -end -endgenerate - - -/////////////////////////////////////////////////////////////////////// - - -always @(negedge NMISample2 or posedge wNMIClear) -begin - if (wNMIClear == 1) - NMILatched <= 1; - else if (NMIMask == 0) - NMILatched <= 0; - else - NMILatched <= 1; -end - -// -// The 6809 specs say that the CPU control signals are sampled on the falling edge of Q. -// It also says that the interrupts require 1 cycle of synchronization time. -// That's vague, as it doesn't say where "1 cycle" starts or ends. Starting from the -// falling edge of Q, the next cycle notices an assertion. From checking a hard 6809 on -// an analyzer, what they really mean is that it's sampled on the falling edge of Q, -// but there's a one cycle delay from the falling edge of E (0.25 clocks from the falling edge of Q -// where the signals were sampled) before it can be noticed. -// So, SIGNALSample is the latched value at the falling edge of Q -// SIGNALSample2 is the latched value at the falling edge of E (0.25 clocks after the line above) -// SIGNALLatched is the latched value at the falling edge of E (1 cycle after the line above) -// -// /HALT and /DMABREQ are delayed one cycle less than interrupts. The 6809 specs infer these details, -// but don't list the point-of-reference they're written from (for instance, they say that an interrupt requires -// a cycle for synchronization; however, it isn't clear whether that's from the falling Q to the next falling Q, -// a complete intermediate cycle, the falling E to the next falling E, etc.) - which, in the end, required an -// analyzer on the 6809 to determine how many cycles before a new instruction an interrupt (or /HALT & /DMABREQ) -// had to be asserted to be noted instead of the next instruction running start to finish. -// -always @(negedge Q) -begin - NMISample <= nNMI; - - IRQSample <= nIRQ; - - FIRQSample <= nFIRQ; - - HALTSample <= nHALT; - - DMABREQSample <= nDMABREQ; - - -end - - -reg rnRESET=0; // The latched version of /RESET, useful 1 clock after it's latched -always @(negedge E) -begin - rnRESET <= nRESET; - - NMISample2 <= NMISample; - - IRQSample2 <= IRQSample; - IRQLatched <= IRQSample2; - - FIRQSample2 <= FIRQSample; - FIRQLatched <= FIRQSample2; - - HALTSample2 <= HALTSample; - HALTLatched <= HALTSample2; - - DMABREQSample2 <= DMABREQSample; - DMABREQLatched <= DMABREQSample2; - - - if (rnRESET == 1) - begin - CpuState <= CpuState_nxt; - - // Don't interpret this next item as "The Next State"; it's a special case 'after this - // generic state, go to this programmable state', so that a single state - // can be shared for many tasks. [Specifically, the stack push/pull code, which is used - // for PSH, PUL, Interrupts, RTI, etc. - NextState <= NextState_nxt; - - // CPU registers latch from the combinatorial circuit - a <= a_nxt; - b <= b_nxt; - x <= x_nxt; - y <= y_nxt; - s <= s_nxt; - u <= u_nxt; - cc <= cc_nxt; - dp <= dp_nxt; - pc <= pc_nxt; - tmp <= tmp_nxt; - addr <= addr_nxt; - ea <= ea_nxt; - - InstPage2 <= InstPage2_nxt; - InstPage3 <= InstPage3_nxt; - Inst1 <= Inst1_nxt; - Inst2 <= Inst2_nxt; - Inst3 <= Inst3_nxt; - NMIClear <= NMIClear_nxt; - - IntType <= IntType_nxt; - - if (s != s_nxt) // Once S changes at all (default is '0'), release the NMI Mask. - NMIMask <= 1'b0; - end - else - begin - CpuState <= CPUSTATE_RESET; - NMIMask <= 1'b1; // Mask NMI until S is loaded. - NMIClear <= 1'b0; // Mark us as not having serviced NMI - end -end - - -///////////////////////////////////////////////////////////////// -// Decode the Index byte - -localparam IDX_REG_X = 3'd0; -localparam IDX_REG_Y = 3'd1; -localparam IDX_REG_U = 3'd2; -localparam IDX_REG_S = 3'd3; -localparam IDX_REG_PC = 3'd4; - -localparam IDX_MODE_POSTINC1 = 4'd0; -localparam IDX_MODE_POSTINC2 = 4'd1; -localparam IDX_MODE_PREDEC1 = 4'd2; -localparam IDX_MODE_PREDEC2 = 4'd3; -localparam IDX_MODE_NOOFFSET = 4'd4; -localparam IDX_MODE_B_OFFSET = 4'd5; -localparam IDX_MODE_A_OFFSET = 4'd6; -localparam IDX_MODE_5BIT_OFFSET= 4'd7; // Special case, not bit pattern 7; the offset sits in the bit pattern -localparam IDX_MODE_8BIT_OFFSET= 4'd8; -localparam IDX_MODE_16BIT_OFFSET = 4'd9; -localparam IDX_MODE_D_OFFSET = 4'd11; -localparam IDX_MODE_8BIT_OFFSET_PC = 4'd12; -localparam IDX_MODE_16BIT_OFFSET_PC= 4'd13; -localparam IDX_MODE_EXTENDED_INDIRECT = 4'd15; - -// Return: -// Register base [3 bits] -// Indirect [1 bit] -// Mode [4 bits] - -function [7:0] IndexDecode(input [7:0] postbyte); -reg [2:0] regnum; -reg indirect; -reg [3:0] mode; -begin - indirect = 0; - mode = 0; - - if (postbyte[7] == 0) // 5-bit - begin - mode = IDX_MODE_5BIT_OFFSET; - end - else - begin - mode = postbyte[3:0]; - indirect = postbyte[4]; - end - if ((mode != IDX_MODE_8BIT_OFFSET_PC) && (mode != IDX_MODE_16BIT_OFFSET_PC)) - regnum[2:0] = postbyte[6:5]; - else - regnum[2:0] = IDX_REG_PC; - - IndexDecode = {indirect, mode, regnum}; -end -endfunction - -wire [3:0] IndexedMode; -wire IndexedIndirect; -wire [2:0] IndexedRegister; - -assign {IndexedIndirect, IndexedMode, IndexedRegister} = IndexDecode(Inst2); - -///////////////////////////////////////////////////////////////// -// Is this a JMP instruction? (irrespective of addressing mode) -function IsJMP(input [7:0] inst); -reg [3:0] hi; -reg [3:0] lo; -begin - hi = inst[7:4]; - lo = inst[3:0]; - - IsJMP = 0; - if ((hi == 4'H0) || (hi == 4'H6) || (hi == 4'H7)) - if (lo == 4'HE) - IsJMP = 1; -end -endfunction - -/////////////////////////////////////////////////////////////////// -// Is this an 8-bit Store? - -localparam ST8_REG_A = 1'b0; -localparam ST8_REG_B = 1'b1; - -function [1:0] IsST8(input [7:0] inst); -reg regnum; -reg IsStore; -begin - - IsStore = 1'b0; - regnum = 1'b1; - - if ( (Inst1 == 8'H97) || (Inst1 == 8'HA7) || (Inst1 == 8'HB7) ) - begin - IsStore = 1'b1; - regnum = 1'b0; - end - else if ( (Inst1 == 8'HD7) || (Inst1 == 8'HE7) || (Inst1 == 8'HF7) ) - begin - IsStore = 1'b1; - regnum = 1'b1; - end - IsST8 = {IsStore, regnum}; -end -endfunction - -wire IsStore8; -wire Store8RegisterNum; - -assign {IsStore8, Store8RegisterNum} = IsST8(Inst1); - - -///////////////////////////////////////////////////////////////// -// Is this a 16-bit Store? - -localparam ST16_REG_X = 3'd0; -localparam ST16_REG_Y = 3'd1; -localparam ST16_REG_U = 3'd2; -localparam ST16_REG_S = 3'd3; -localparam ST16_REG_D = 3'd4; - - -function [3:0] IsST16(input [7:0] inst); -reg [3:0] hi; -reg [3:0] lo; -reg [2:0] regnum; -reg IsStore; -begin - hi = inst[7:4]; - lo = inst[3:0]; - IsStore = 1'b0; - regnum = 3'b111; - - if ((inst == 8'H9F) || (inst == 8'HAF) || (inst == 8'HBF)) - begin - IsStore = 1; - if (~InstPage2) - regnum = ST16_REG_X; - else - regnum = ST16_REG_Y; - end - else if ((inst == 8'HDF) || (inst == 8'HEF) || (inst == 8'HFF)) - begin - IsStore = 1; - if (~InstPage2) - regnum = ST16_REG_U; - else - regnum = ST16_REG_S; - end - else if ((inst == 8'HDD) || (inst == 8'HED) || (inst == 8'HFD)) - begin - IsStore = 1; - regnum = ST16_REG_D; - end - - IsST16 = {IsStore, regnum}; -end -endfunction - -wire IsStore16; -wire [2:0] StoreRegisterNum; - -assign {IsStore16, StoreRegisterNum} = IsST16(Inst1); - -///////////////////////////////////////////////////////////////// -// Is this a special Immediate mode instruction, ala -// PSH, PUL, EXG, TFR, ANDCC, ORCC -function IsSpecialImm(input [7:0] inst); -reg is; -reg [3:0] hi; -reg [3:0] lo; -begin - hi = inst[7:4]; - lo = inst[3:0]; - is = 0; - - if (hi == 4'H1) - begin - if ( (lo == 4'HA) || (lo == 4'HC) || (lo == 4'HE) || (lo == 4'HF) ) // ORCC, ANDCC, EXG, TFR - is = 1; - end - else if (hi == 4'H3) - begin - if ( (lo >= 4'H3) && (lo <= 4'H7) ) // PSHS, PULS, PSHU, PULU - is = 1; - end - else - is = 0; - - IsSpecialImm = is; -end -endfunction -wire IsSpecialImmediate = IsSpecialImm(Inst1); - -///////////////////////////////////////////////////////////////// -// Is this a one-byte instruction? [The 6809 reads 2 bytes for every instruction, minimum (it can read more). On a one-byte, we have to ensure that we haven't skipped the PC ahead. -function IsOneByteInstruction(input [7:0] inst); -reg is; -reg [3:0] hi; -reg [3:0] lo; -begin - hi = inst[7:4]; - lo = inst[3:0]; - is = 1'b0; - - if ( (hi == 4'H4) || (hi == 4'H5) ) - is = 1'b1; - else if ( hi == 4'H1) - begin - if ( (lo == 4'H2) || (lo == 4'H3) || (lo == 4'H9) || (lo == 4'HD) ) - is = 1'b1; - end - else if (hi == 4'H3) - begin - if ( (lo >= 4'H9) && (lo != 4'HC) ) - is = 1'b1; - end - else - is = 1'b0; - - IsOneByteInstruction = is; -end -endfunction - -///////////////////////////////////////////////////////////////// -// ALU16 - Simpler than the 8 bit ALU - -localparam ALU16_REG_X = 3'd0; -localparam ALU16_REG_Y = 3'd1; -localparam ALU16_REG_U = 3'd2; -localparam ALU16_REG_S = 3'd3; -localparam ALU16_REG_D = 3'd4; - -function [2:0] ALU16RegFromInst(input Page2, input Page3, input [7:0] inst); -reg [2:0] srcreg; -begin - srcreg = 3'b111; // default - casex ({Page2, Page3, inst}) // Note pattern for the matching below - 10'b1010xx0011: // 1083, 1093, 10A3, 10B3 CMPD - srcreg = ALU16_REG_D; - 10'b1010xx1100: // 108C, 109C, 10AC, 10BC CMPY - srcreg = ALU16_REG_Y; - 10'b0110xx0011: // 1183, 1193, 11A3, 11B3 CMPU - srcreg = ALU16_REG_U; - 10'b0110xx1100: // 118C, 119C, 11AC, 11BC CMPS - srcreg = ALU16_REG_S; - 10'b0010xx1100: // 8C,9C,AC,BC CMPX - srcreg = ALU16_REG_X; - - 10'b0011xx0011: // C3, D3, E3, F3 ADDD - srcreg = ALU16_REG_D; - - 10'b0011xx1100: // CC, DC, EC, FC LDD - srcreg = ALU16_REG_D; - 10'b0010xx1110: // 8E LDX, 9E LDX, AE LDX, BE LDX - srcreg = ALU16_REG_X; - 10'b0011xx1110: // CE LDU, DE LDU, EE LDU, FE LDU - srcreg = ALU16_REG_U; - 10'b1010xx1110: // 108E LDY, 109E LDY, 10AE LDY, 10BE LDY - srcreg = ALU16_REG_Y; - 10'b1011xx1110: // 10CE LDS, 10DE LDS, 10EE LDS, 10FE LDS - srcreg = ALU16_REG_S; - 10'b0010xx0011: // 83, 93, A3, B3 SUBD - srcreg = ALU16_REG_D; - - 10'H03A: // 3A ABX - srcreg = ALU16_REG_X; - 10'H030: // 30 LEAX - srcreg = ALU16_REG_X; - 10'H031: // 31 LEAY - srcreg = ALU16_REG_Y; - 10'H032: // 32 LEAS - srcreg = ALU16_REG_S; - 10'H033: // 32 LEAU - srcreg = ALU16_REG_U; - default: - srcreg = 3'b111; - endcase - ALU16RegFromInst = srcreg; -end -endfunction - -wire [2:0] ALU16Reg = ALU16RegFromInst(InstPage2, InstPage3, Inst1); - -localparam ALUOP16_SUB = 3'H0; -localparam ALUOP16_ADD = 3'H1; -localparam ALUOP16_LD = 3'H2; -localparam ALUOP16_CMP = 3'H3; -localparam ALUOP16_LEA = 3'H4; -localparam ALUOP16_INVALID = 3'H7; - -function [3:0] ALU16OpFromInst(input Page2, input Page3, input [7:0] inst); -reg [2:0] aluop; -reg writeback; -begin - aluop = 3'b111; - writeback = 1'b1; - casex ({Page2, Page3, inst}) - 10'b1010xx0011: // 1083, 1093, 10A3, 10B3 CMPD - begin - aluop = ALUOP16_CMP; - writeback = 1'b0; - end - 10'b1010xx1100: // 108C, 109C, 10AC, 10BC CMPY - begin - aluop = ALUOP16_CMP; - writeback = 1'b0; - end - 10'b0110xx0011: // 1183, 1193, 11A3, 11B3 CMPU - begin - aluop = ALUOP16_CMP; - writeback = 1'b0; - end - 10'b0110xx1100: // 118C, 119C, 11AC, 11BC CMPS - begin - aluop = ALUOP16_CMP; - writeback = 1'b0; - end - 10'b0010xx1100: // 8C,9C,AC,BC CMPX - begin - aluop = ALUOP16_CMP; - writeback = 1'b0; - end - - 10'b0011xx0011: // C3, D3, E3, F3 ADDD - aluop = ALUOP16_ADD; - - 10'b0011xx1100: // CC, DC, EC, FC LDD - aluop = ALUOP16_LD; - 10'b001xxx1110: // 8E LDX, 9E LDX, AE LDX, BE LDX, CE LDU, DE LDU, EE LDU, FE LDU - aluop = ALUOP16_LD; - 10'b101xxx1110: // 108E LDY, 109E LDY, 10AE LDY, 10BE LDY, 10CE LDS, 10DE LDS, 10EE LDS, 10FE LDS - aluop = ALUOP16_LD; - - 10'b0010xx0011: // 83, 93, A3, B3 SUBD - aluop = ALUOP16_SUB; - - 10'H03A: // 3A ABX - aluop = ALUOP16_ADD; - - 10'b00001100xx: // $30-$33, LEAX, LEAY, LEAS, LEAU - aluop = ALUOP16_LEA; - - default: - aluop = ALUOP16_INVALID; - endcase - ALU16OpFromInst = {writeback, aluop}; -end -endfunction - -wire ALU16OpWriteback; -wire [2:0] ALU16Opcode; - -assign {ALU16OpWriteback, ALU16Opcode} = ALU16OpFromInst(InstPage2, InstPage3, Inst1); - -wire IsALU16Opcode = (ALU16Opcode != 3'b111); - -function [23:0] ALU16Inst(input [2:0] operation16, input [15:0] a_arg, input [15:0] b_arg, input [7:0] cc_arg); -reg [7:0] cc_out; -reg [15:0] ALUFn; -reg carry; -reg borrow; -begin - cc_out = cc_arg; - case (operation16) - ALUOP16_ADD: - begin - {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} + b_arg; - cc_out[CC_V_BIT] = (a_arg[15] & b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & ~b_arg[15] & ALUFn[15]); - end - - ALUOP16_SUB: - begin - {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg}; - cc_out[CC_V_BIT] = (a_arg[15] & ~b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & b_arg[15] & ALUFn[15]); - end - - ALUOP16_LD: - begin - ALUFn = b_arg; - cc_out[CC_V_BIT] = 1'b0; - end - - ALUOP16_CMP: - begin - {cc_out[CC_C_BIT], ALUFn} = {1'b0, a_arg} - {1'b0, b_arg}; - cc_out[CC_V_BIT] = (a_arg[15] & ~b_arg[15] & ~ALUFn[15]) | (~a_arg[15] & b_arg[15] & ALUFn[15]); - end - - ALUOP16_LEA: - begin - ALUFn = a_arg; - end - - default: - ALUFn = 16'H0000; - - endcase - cc_out[CC_Z_BIT] = (ALUFn[15:0] == 16'H0000); - if (operation16 != ALUOP16_LEA) - cc_out[CC_N_BIT] = ALUFn[15]; - ALU16Inst = {cc_out, ALUFn}; -end -endfunction - -reg [2:0] ALU16_OP; -reg [15:0] ALU16_A; -reg [15:0] ALU16_B; -reg [7:0] ALU16_CC; - -// Top 8 bits == CC, bottom 8 bits = output value -wire [23:0] ALU16 = ALU16Inst(ALU16_OP, ALU16_A, ALU16_B, ALU16_CC); - - -///////////////////////////////////////////////////////////////// -// ALU - -// The ops are organized from the 4 low-order bits of the instructions for the first set of ops, then 16-31 are the second set - even though bit 4 isn't representative. -localparam ALUOP_NEG = 5'd0; -localparam ALUOP_COM = 5'd3; -localparam ALUOP_LSR = 5'd4; -localparam ALUOP_ROR = 5'd6; -localparam ALUOP_ASR = 5'd7; -localparam ALUOP_ASL = 5'd8; -localparam ALUOP_LSL = 5'd8; -localparam ALUOP_ROL = 5'd9; -localparam ALUOP_DEC = 5'd10; -localparam ALUOP_INC = 5'd12; -localparam ALUOP_TST = 5'd13; -localparam ALUOP_CLR = 5'd15; - -localparam ALUOP_SUB = 5'd16; -localparam ALUOP_CMP = 5'd17; -localparam ALUOP_SBC = 5'd18; -localparam ALUOP_AND = 5'd20; -localparam ALUOP_BIT = 5'd21; -localparam ALUOP_LD = 5'd22; -localparam ALUOP_EOR = 5'd24; -localparam ALUOP_ADC = 5'd25; -localparam ALUOP_OR = 5'd26; -localparam ALUOP_ADD = 5'd27; - -function [5:0] ALUOpFromInst(input [7:0] inst); -reg [4:0] op; -reg writeback; -begin - // Okay, this turned out to be simpler than I expected ... - op = {inst[7], inst[3:0]}; - case (op) - ALUOP_CMP: - writeback = 0; - ALUOP_TST: - writeback = 0; - ALUOP_BIT: - writeback = 0; - default: - writeback = 1; - endcase - ALUOpFromInst = {writeback, op}; -end -endfunction - -wire [4:0] ALU8Op; -wire ALU8Writeback; - -assign {ALU8Writeback, ALU8Op} = ALUOpFromInst(Inst1); - -reg [7:0] ALU_A; -reg [7:0] ALU_B; -reg [7:0] ALU_CC; -reg [4:0] ALU_OP; - - -function [15:0] ALUInst(input [4:0] operation, input [7:0] a_arg, input [7:0] b_arg, input [7:0] cc_arg); -reg [7:0] cc_out; -reg [7:0] ALUFn; -reg carry; -reg borrow; -begin - cc_out = cc_arg; - case (operation) - ALUOP_NEG: - begin - ALUFn[7:0] = ~a_arg + 1'b1; - cc_out[CC_C_BIT] = (ALUFn[7:0] != 8'H00); - cc_out[CC_V_BIT] = (a_arg == 8'H80); - end - - ALUOP_LSL: - begin - {cc_out[CC_C_BIT], ALUFn} = {a_arg, 1'b0}; - cc_out[CC_V_BIT] = a_arg[7] ^ a_arg[6]; - end - - ALUOP_LSR: - begin - {ALUFn, cc_out[CC_C_BIT]} = {1'b0, a_arg}; - end - - ALUOP_ASR: - begin - {ALUFn, cc_out[CC_C_BIT]} = {a_arg[7], a_arg}; - end - - ALUOP_ROL: - begin - {cc_out[CC_C_BIT], ALUFn} = {a_arg, cc_arg[CC_C_BIT]}; - cc_out[CC_V_BIT] = a_arg[7] ^ a_arg[6]; - end - - ALUOP_ROR: - begin - {ALUFn, cc_out[CC_C_BIT]} = {cc_arg[CC_C_BIT], a_arg}; - end - - ALUOP_OR: - begin - ALUFn[7:0] = (a_arg | b_arg); - cc_out[CC_V_BIT] = 1'b0; - end - - ALUOP_ADD: - begin - {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} + {1'b0, b_arg}; - cc_out[CC_V_BIT] = (a_arg[7] & b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & ~b_arg[7] & ALUFn[7]); - cc_out[CC_H_BIT] = a_arg[4] ^ b_arg[4] ^ ALUFn[4]; - end - - ALUOP_SUB: - begin - {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} - {1'b0, b_arg}; - cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]); - end - - ALUOP_AND: - begin - ALUFn[7:0] = (a_arg & b_arg); - cc_out[CC_V_BIT] = 1'b0; - end - - ALUOP_BIT: - begin - ALUFn[7:0] = (a_arg & b_arg); - cc_out[CC_V_BIT] = 1'b0; - end - - ALUOP_EOR: - begin - ALUFn[7:0] = (a_arg ^ b_arg); - cc_out[CC_V_BIT] = 1'b0; - end - - ALUOP_CMP: - begin - {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} - {1'b0, b_arg}; - cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]); - end - - ALUOP_COM: - begin - ALUFn[7:0] = ~a_arg; - cc_out[CC_V_BIT] = 1'b0; - cc_out[CC_C_BIT] = 1'b1; - end - - ALUOP_ADC: - begin - {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} + {1'b0, b_arg} + cc_arg[CC_C_BIT]; - cc_out[CC_V_BIT] = (a_arg[7] & b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & ~b_arg[7] & ALUFn[7]); - cc_out[CC_H_BIT] = a_arg[4] ^ b_arg[4] ^ ALUFn[4]; - end - - ALUOP_LD: - begin - ALUFn[7:0] = b_arg; - cc_out[CC_V_BIT] = 1'b0; - end - - ALUOP_INC: - begin - {carry, ALUFn} = {1'b0, a_arg} + 1'b1; - cc_out[CC_V_BIT] = (~a_arg[7] & ALUFn[7]); - end - - ALUOP_DEC: - begin - {carry, ALUFn[7:0]} = {1'b0, a_arg} - 1'b1; - cc_out[CC_V_BIT] = (a_arg[7] & ~ALUFn[7]); - end - - ALUOP_CLR: - begin - ALUFn[7:0] = 8'H00; - cc_out[CC_V_BIT] = 1'b0; - cc_out[CC_C_BIT] = 1'b0; - end - - ALUOP_TST: - begin - ALUFn[7:0] = a_arg; - cc_out[CC_V_BIT] = 1'b0; - end - - ALUOP_SBC: - begin - {cc_out[CC_C_BIT], ALUFn[7:0]} = {1'b0, a_arg} - {1'b0, b_arg} - cc_arg[CC_C_BIT]; - cc_out[CC_V_BIT] = (a_arg[7] & ~b_arg[7] & ~ALUFn[7]) | (~a_arg[7] & b_arg[7] & ALUFn[7]); - end - - default: - ALUFn = 8'H00; - - endcase - - cc_out[CC_N_BIT] = ALUFn[7]; - cc_out[CC_Z_BIT] = (ALUFn == 8'H00); - ALUInst = {cc_out[7:0], ALUFn[7:0]}; -end -endfunction - - -// Top 8 bits == CC, bottom 8 bits = output value -wire [15:0] ALU = ALUInst(ALU_OP, ALU_A, ALU_B, ALU_CC); - -//////////////////////////////////////////////////////////// - -localparam TYPE_INHERENT = 3'd0; -localparam TYPE_IMMEDIATE = 3'd1; -localparam TYPE_DIRECT = 3'd2; -localparam TYPE_RELATIVE = 3'd3; -localparam TYPE_INDEXED = 3'd4; -localparam TYPE_EXTENDED = 3'd5; - -localparam TYPE_INVALID = 3'd7; - -// Function to decode the addressing mode the instruction uses -function [2:0] addressing_mode_type(input [7:0] inst); -begin - casex (inst) - 8'b0000???? : addressing_mode_type = TYPE_DIRECT; - 8'b0001???? : - begin - casex (inst[3:0]) - 4'b0010: - addressing_mode_type = TYPE_INHERENT; - - 4'b0011: - addressing_mode_type = TYPE_INHERENT; - - 4'b1001: - addressing_mode_type = TYPE_INHERENT; - - 4'b1101: - addressing_mode_type = TYPE_INHERENT; - - 4'b0110: - addressing_mode_type = TYPE_RELATIVE; - - 4'b0111: - addressing_mode_type = TYPE_RELATIVE; - - 4'b1010: - addressing_mode_type = TYPE_IMMEDIATE; - - 4'b1100: - addressing_mode_type = TYPE_IMMEDIATE; - - 4'b1110: - addressing_mode_type = TYPE_IMMEDIATE; - - 4'b1111: - addressing_mode_type = TYPE_IMMEDIATE; - - default: - addressing_mode_type = TYPE_INVALID; - endcase - end - - 8'b0010????: addressing_mode_type = TYPE_RELATIVE; - 8'b0011????: - begin - casex(inst[3:0]) - 4'b00??: - addressing_mode_type = TYPE_INDEXED; - - 4'b01??: - addressing_mode_type = TYPE_IMMEDIATE; - - 4'b1001: - addressing_mode_type = TYPE_INHERENT; - - 4'b101?: - addressing_mode_type = TYPE_INHERENT; - - 4'b1100: - addressing_mode_type = TYPE_INHERENT; - - 4'b1101: - addressing_mode_type = TYPE_INHERENT; - - 4'b1111: - addressing_mode_type = TYPE_INHERENT; - - default: - addressing_mode_type = TYPE_INVALID; - endcase - end - - 8'b010?????: addressing_mode_type = TYPE_INHERENT; - - 8'b0110????: addressing_mode_type = TYPE_INDEXED; - - 8'b0111????: addressing_mode_type = TYPE_EXTENDED; - - 8'b1000????: - begin - casex (inst[3:0]) - 4'b0111: addressing_mode_type = TYPE_INVALID; - 4'b1111: addressing_mode_type = TYPE_INVALID; - 4'b1101: addressing_mode_type = TYPE_RELATIVE; - default: addressing_mode_type = TYPE_IMMEDIATE; - endcase - end - - 8'b1001????: addressing_mode_type = TYPE_DIRECT; - 8'b1010????: addressing_mode_type = TYPE_INDEXED; - 8'b1011????: addressing_mode_type = TYPE_EXTENDED; - 8'b1100????: addressing_mode_type = TYPE_IMMEDIATE; - 8'b1101????: addressing_mode_type = TYPE_DIRECT; - 8'b1110????: addressing_mode_type = TYPE_INDEXED; - 8'b1111????: addressing_mode_type = TYPE_EXTENDED; - - endcase -end -endfunction - -wire [2:0] AddrModeType = addressing_mode_type(Inst1); - -////////////////////////////////////////////////// - -// Individual opcodes that are the top of a column of states. - -localparam OPCODE_INH_ABX = 8'H3A; -localparam OPCODE_INH_RTS = 8'H39; -localparam OPCODE_INH_RTI = 8'H3B; -localparam OPCODE_INH_CWAI = 8'H3C; -localparam OPCODE_INH_MUL = 8'H3D; -localparam OPCODE_INH_SWI = 8'H3F; -localparam OPCODE_INH_SEX = 8'H1D; -localparam OPCODE_INH_NOP = 8'H12; -localparam OPCODE_INH_SYNC = 8'H13; -localparam OPCODE_INH_DAA = 8'H19; - -localparam OPCODE_IMM_ORCC = 8'H1A; -localparam OPCODE_IMM_ANDCC = 8'H1C; -localparam OPCODE_IMM_EXG = 8'H1E; -localparam OPCODE_IMM_TFR = 8'H1F; -localparam OPCODE_IMM_PSHS = 8'H34; -localparam OPCODE_IMM_PULS = 8'H35; -localparam OPCODE_IMM_PSHU = 8'H36; -localparam OPCODE_IMM_PULU = 8'H37; - -localparam OPCODE_IMM_SUBD = 8'H83; -localparam OPCODE_IMM_CMPX = 8'H8C; -localparam OPCODE_IMM_LDX = 8'H8E; -localparam OPCODE_IMM_ADDD = 8'HC3; -localparam OPCODE_IMM_LDD = 8'HCC; -localparam OPCODE_IMM_LDU = 8'HCE; -localparam OPCODE_IMM_CMPD = 8'H83; // Page2 -localparam OPCODE_IMM_CMPY = 8'H8C; // Page2 -localparam OPCODE_IMM_LDY = 8'H8E; // Page2 -localparam OPCODE_IMM_LDS = 8'HCE; // Page2 -localparam OPCODE_IMM_CMPU = 8'H83; // Page3 -localparam OPCODE_IMM_CMPS = 8'H8C; // Page3 - -localparam EXGTFR_REG_D = 4'H0; -localparam EXGTFR_REG_X = 4'H1; -localparam EXGTFR_REG_Y = 4'H2; -localparam EXGTFR_REG_U = 4'H3; -localparam EXGTFR_REG_S = 4'H4; -localparam EXGTFR_REG_PC = 4'H5; -localparam EXGTFR_REG_A = 4'H8; -localparam EXGTFR_REG_B = 4'H9; -localparam EXGTFR_REG_CC = 4'HA; -localparam EXGTFR_REG_DP = 4'HB; - -function IsALU8Set0(input [7:0] instr); -reg result; -reg [3:0] hi; -reg [3:0] lo; -begin - hi = instr[7:4]; - lo = instr[3:0]; - if ( (hi == 4'H0) || (hi == 4'H4) || (hi == 4'H5) || (hi == 4'H6) || (hi == 4'H7) ) - begin - if ( (lo != 4'H1) && (lo != 4'H2) && (lo != 4'H5) && (lo != 4'HB) && (lo != 4'HE) ) // permit NEG, COM, LSR, ROR, ASR, ASL/LSL, ROL, DEC, INC, TST, CLR - result = 1; - else - result = 0; - end - else - result = 0; - IsALU8Set0 = result; -end -endfunction - -function IsALU8Set1(input [7:0] instr); -reg result; -reg [3:0] hi; -reg [3:0] lo; -begin - hi = instr[7:4]; - lo = instr[3:0]; - if ( (hi >= 4'H8) ) - begin - if ( (lo <= 4'HB) && (lo != 4'H3) && (lo != 4'H7) ) // 8-bit SUB, CMP, SBC, AND, BIT, LD, EOR, ADC, OR, ADD - result = 1; - else - result = 0; - end - else - result = 0; - IsALU8Set1 = result; -end -endfunction - -// Determine if the instruction is performing an 8-bit op (ALU only) -function ALU8BitOp(input [7:0] instr); -begin - ALU8BitOp = IsALU8Set0(instr) | IsALU8Set1(instr); -end -endfunction - -wire Is8BitInst = ALU8BitOp(Inst1); - -function IsRegA(input [7:0] instr); -reg result; -reg [3:0] hi; -begin - hi = instr[7:4]; - if ((hi == 4'H4) || (hi == 4'H8) || (hi == 4'H9) || (hi == 4'HA) || (hi == 4'HB) ) - result = 1; - else - result = 0; - IsRegA = result; -end -endfunction - -wire IsTargetRegA = IsRegA(Inst1); - -// -// -// Decode -// 00-0F = DIRECT -// 10-1F = INHERENT, RELATIVE, IMMEDIATE -// 20-2F = RELATIVE -// 30-3F = INDEXED, IMMEDIATE (pus, pul), INHERENT -// 40-4F = INHERENT -// 50-5F = INHERENT -// 60-6F = INDEXED -// 70-7F = EXTENDED -// 80-8F = IMMEDIATE, RELATIVE (BSR) -// 90-9F = DIRECT -// A0-AF = INDEXED -// B0-BF = EXTENDED -// C0-CF = IMMEDIATE -// D0-DF = DIRECT -// E0-EF = INDEXED -// F0-FF = EXTENDED - -// DIRECT; 00-0F, 90-9F, D0-DF -// INHERENT; 10-1F (12, 13, 19, 1D), 30-3F (39-3F), 40-4F, 50-5F, -// RELATIVE: 10-1F (16, 17), 20-2F, 80-8F (8D) -// IMMEDIATE: 10-1F (1A, 1C, 1E, 1F), 30-3F (34-37), 80-8F (80-8C, 8E), C0-CF -// INDEXED: 60-6F, A0-AF, E0-EF -// EXTENDED: 70-7F, B0-Bf, F0-FF - -localparam INST_LBRA = 8'H16; // always -- shitty numbering, damnit -localparam INST_LBSR = 8'H17; // - -localparam INST_BRA = 8'H20; // always -localparam INST_BRN = 8'H21; // never -localparam INST_BHI = 8'H22; // CC.Z = 0 && CC.C = 0 -localparam INST_BLS = 8'H23; // CC.Z != 0 && CC.C != 0 -localparam INST_BCC = 8'H24; // CC.C = 0 -localparam INST_BHS = 8'H24; // same as BCC -localparam INST_BCS = 8'H25; // CC.C = 1 -localparam INST_BLO = 8'H25; // same as BCS -localparam INST_BNE = 8'H26; // CC.Z = 0 -localparam INST_BEQ = 8'H27; // CC.Z = 1 -localparam INST_BVC = 8'H28; // V = 1 -localparam INST_BVS = 8'H29; // V = 0 -localparam INST_BPL = 8'H2A; // CC.N = 0 -localparam INST_BMI = 8'H2B; // CC.N = 1 -localparam INST_BGE = 8'H2C; // CC.N = CC.V -localparam INST_BLT = 8'H2D; // CC.N != CC.V -localparam INST_BGT = 8'H2E; // CC.N = CC.V && CC.Z = 0 -localparam INST_BLE = 8'H2F; // CC.N != CC.V && CC.Z = 1 -localparam INST_BSR = 8'H8D; // always - -localparam NYB_BRA = 4'H0; // always -localparam NYB_BRN = 4'H1; // never -localparam NYB_BHI = 4'H2; // CC.Z = 0 && CC.C = 0 -localparam NYB_BLS = 4'H3; // CC.Z != 0 && CC.C != 0 -localparam NYB_BCC = 4'H4; // CC.C = 0 -localparam NYB_BHS = 4'H4; // same as BCC -localparam NYB_BCS = 4'H5; // CC.C = 1 -localparam NYB_BLO = 4'H5; // same as BCS -localparam NYB_BNE = 4'H6; // CC.Z = 0 -localparam NYB_BEQ = 4'H7; // CC.Z = 1 -localparam NYB_BVC = 4'H8; // V = 0 -localparam NYB_BVS = 4'H9; // V = 1 -localparam NYB_BPL = 4'HA; // CC.N = 0 -localparam NYB_BMI = 4'HB; // CC.N = 1 -localparam NYB_BGE = 4'HC; // CC.N = CC.V -localparam NYB_BLT = 4'HD; // CC.N != CC.V -localparam NYB_BGT = 4'HE; // CC.N = CC.V && CC.Z = 0 -localparam NYB_BLE = 4'HF; // CC.N != CC.V && CC.Z = 1 - - - -function take_branch(input [7:0] Inst1, input [7:0] cc); -begin - take_branch = 0; //default - if ( (Inst1 == INST_BSR) || (Inst1 == INST_LBSR) || (Inst1 == INST_LBRA) ) - take_branch = 1; - else - case (Inst1[3:0]) - NYB_BRA: - take_branch = 1; - NYB_BRN: - take_branch = 0; - NYB_BHI: - if ( ( cc[CC_Z_BIT] | cc[CC_C_BIT] ) == 0) - take_branch = 1; - NYB_BLS: - if ( cc[CC_Z_BIT] | cc[CC_C_BIT] ) - take_branch = 1; - NYB_BCC: - if ( cc[CC_C_BIT] == 0 ) - take_branch = 1; - NYB_BCS: - if ( cc[CC_C_BIT] == 1 ) - take_branch = 1; - NYB_BNE: - if ( cc[CC_Z_BIT] == 0 ) - take_branch = 1; - NYB_BEQ: - if ( cc[CC_Z_BIT] == 1 ) - take_branch = 1; - NYB_BVC: - if ( cc[CC_V_BIT] == 0) - take_branch = 1; - NYB_BVS: - if ( cc[CC_V_BIT] == 1) - take_branch = 1; - NYB_BPL: - if ( cc[CC_N_BIT] == 0 ) - take_branch = 1; - NYB_BMI: - if (cc[CC_N_BIT] == 1) - take_branch = 1; - NYB_BGE: - if ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 0) - take_branch = 1; - NYB_BLT: - if ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 1) - take_branch = 1; - NYB_BGT: - if ( ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 0) & (cc[CC_Z_BIT] == 0) ) - take_branch = 1; - NYB_BLE: - if ( ((cc[CC_N_BIT] ^ cc[CC_V_BIT]) == 1) | (cc[CC_Z_BIT] == 1) ) - take_branch = 1; - endcase -end -endfunction - -wire TakeBranch = take_branch(Inst1, cc); - -///////////////////////////////////////////////////////////////////// -// Convenience function for knowing the contents for TFR, EXG -function [15:0] EXGTFRRegister(input [3:0] regid); -begin - case (regid) - EXGTFR_REG_D: - EXGTFRRegister = {a, b}; - EXGTFR_REG_X: - EXGTFRRegister = x; - EXGTFR_REG_Y: - EXGTFRRegister = y; - EXGTFR_REG_U: - EXGTFRRegister = u; - EXGTFR_REG_S: - EXGTFRRegister = s; - EXGTFR_REG_PC: - EXGTFRRegister = pc_p1; // For both EXG and TFR, this is used on the 2nd byte in the instruction's cycle. The PC intended to transfer is actually the next byte. - EXGTFR_REG_DP: - EXGTFRRegister = {8'HFF, dp}; - EXGTFR_REG_A: - EXGTFRRegister = {8'HFF, a}; - EXGTFR_REG_B: - EXGTFRRegister = {8'HFF, b}; - EXGTFR_REG_CC: - EXGTFRRegister = {8'HFF, cc}; - default: - EXGTFRRegister = 16'H0; - endcase -end -endfunction -wire [15:0] EXGTFRRegA = EXGTFRRegister(D[7:4]); -wire [15:0] EXGTFRRegB = EXGTFRRegister(D[3:0]); - -// CPU state machine -always @(*) -begin - rLIC = 1'b0; - rAVMA = 1'b1; - rBUSY = 1'b0; - - addr_nxt = 16'HFFFF; - pc_p1 = (pc+16'H1); - pc_p2 = (pc+16'H2); - pc_p3 = (pc+16'H3); - s_p1 = (s+16'H1); - s_m1 = (s-16'H1); - u_p1 = (u+16'H1); - u_m1 = (u-16'H1); - addr_p1 = (addr+16'H1); - ea_p1 = (ea+16'H1); - BS_nxt = 1'b0; - BA_nxt = 1'b0; - - // These may be overridden below, but the "next" version by default should be - // the last latched version. - IntType_nxt = IntType; - NMIClear_nxt = NMIClear; - NextState_nxt = NextState; - a_nxt = a; - b_nxt = b; - x_nxt = x; - y_nxt = y; - s_nxt = s; - u_nxt = u; - cc_nxt = cc; - dp_nxt = dp; - pc_nxt = pc; - tmp_nxt = tmp; - ea_nxt = ea; - - ALU_A = 8'H00; - ALU_B = 8'H00; - ALU_CC = 8'H00; - ALU_OP = 5'H00; - - ALU16_OP = 3'H0; - ALU16_A = 16'H0000; - ALU16_B = 16'H0000; - ALU16_CC = 8'H00; - - DOutput = 8'H00; - RnWOut = 1'b1; // read - - Inst1_nxt = Inst1; - Inst2_nxt = Inst2; - Inst3_nxt = Inst3; - InstPage2_nxt = InstPage2; - InstPage3_nxt = InstPage3; - - CpuState_nxt = CpuState; - - case (CpuState) - CPUSTATE_RESET: - begin - addr_nxt = 16'HFFFF; - a_nxt = 0; - b_nxt = 0; - x_nxt = 0; - y_nxt = 0; - s_nxt = 16'HFFFD; // Take care about removing the reset of S. There's logic depending on the delta between s and s_nxt to clear NMIMask. - u_nxt = 0; - cc_nxt = CC_F | CC_I; // reset disables interrupts - dp_nxt = 0; - ea_nxt = 16'HFFFF; - - RnWOut = 1; // read - rLIC = 1'b0; // Instruction incomplete - NMIClear_nxt= 1'b0; - IntType_nxt = 3'b111; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_RESET0; - end - - CPUSTATE_RESET0: - begin - addr_nxt = `RESET_VECTOR; - rBUSY = 1'b1; - pc_nxt[15:8] = D[7:0]; - BS_nxt = 1'b1; // ACK RESET - rAVMA = 1'b1; - rLIC = 1'b1; - CpuState_nxt = CPUSTATE_RESET2; - end - - CPUSTATE_RESET2: - begin - addr_nxt = addr_p1; - BS_nxt = 1'b1; // ACK RESET - pc_nxt[7:0] = D[7:0]; - rAVMA = 1'b1; - rLIC = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_FETCH_I1: - begin - if (~DMABREQLatched) - begin - addr_nxt = pc; - RnWOut = 1'b1; - rAVMA = 1'b0; - tmp_nxt = {tmp[15:4], 4'b1111}; - BS_nxt = 1'b1; - BA_nxt = 1'b1; - rLIC = 1'b1; - CpuState_nxt = CPUSTATE_DMABREQ; - end - else if (~HALTLatched) - begin - addr_nxt = pc; - RnWOut = 1'b1; - rAVMA = 1'b0; - BS_nxt = 1'b1; - BA_nxt = 1'b1; - rLIC = 1'b1; - CpuState_nxt = CPUSTATE_HALTED; - end - else // not halting, run the inst byte fetch - begin - addr_nxt = pc; // Set the address bus for the next instruction, first byte - pc_nxt = pc_p1; - RnWOut = 1; // Set for a READ - Inst1_nxt = MappedInstruction; - InstPage2_nxt = 0; - InstPage3_nxt = 0; - - // New instruction fetch; service interrupts pending - if (NMILatched == 0) - begin - pc_nxt = pc; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_NMI_START; - end - else if ((FIRQLatched == 0) && (cc[CC_F_BIT] == 0)) - begin - pc_nxt = pc; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FIRQ_START; - end - else if ((IRQLatched == 0) && (cc[CC_I_BIT] == 0)) - begin - pc_nxt = pc; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IRQ_START; - end - - // The actual 1st byte checks - else if (Inst1_nxt == 8'H10) // Page 2 Note, like the 6809, $10 $10 $10 $10 has the same effect as a single $10. - begin - InstPage2_nxt = 1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1V2; - end - else if (Inst1_nxt == 8'H11) // Page 3 - begin - InstPage3_nxt = 1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1V2; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I2; - end - end // if not halting - end - - CPUSTATE_FETCH_I1V2: - begin - addr_nxt = pc; // Set the address bus for the next instruction, first byte - pc_nxt = pc_p1; - RnWOut = 1; // Set for a READ - Inst1_nxt = MappedInstruction; - - if (Inst1_nxt == 8'H10) // Page 2 Note, like the 6809, $10 $10 $10 $10 has the same effect as a single $10. - begin - if (InstPage3 == 0) // $11 $11 $11 $11 ... $11 $10 still = Page 3 - InstPage2_nxt = 1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1V2; - end - else if (Inst1_nxt == 8'H11) // Page 3 - begin - if (InstPage2 == 0) // $10 $10 ... $10 $11 still = Page 2 - InstPage3_nxt = 1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1V2; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I2; - end - end - - - CPUSTATE_FETCH_I2: // We've fetched the first byte. If a $10 or $11 (page select), mark those flags and fetch the next byte as instruction byte 1. - begin - addr_nxt = addr_p1; // Address bus++ - pc_nxt = pc_p1; - Inst2_nxt = D[7:0]; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - - if (IsIllegalInstruction) // Skip illegal instructions - begin - - rAVMA = 1'b1; - CpuState_nxt = IllegalInstructionState; - rLIC = 1'b1; - end - else - begin - // First byte Decode for this stage - case (AddrModeType) - TYPE_INDEXED: - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_INDEXED_BASE; - end - - - TYPE_EXTENDED: - begin - ea_nxt[15:8] = Inst2_nxt; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_EXTENDED_ADDRLO; - end - TYPE_DIRECT: - begin - ea_nxt = {dp, Inst2_nxt}; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_DIRECT_DONTCARE; - end - - TYPE_INHERENT: - begin - if (Inst1 == OPCODE_INH_NOP) - begin - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else if (Inst1 == OPCODE_INH_DAA) // Bcd lunacy - begin - if ( ((cc[CC_C_BIT]) || (a[7:4] > 4'H9)) || - ((a[7:4] > 4'H8) && (a[3:0] > 4'H9)) ) - tmp_nxt[7:4] = 4'H6; - else - tmp_nxt[7:4] = 4'H0; - - if ((cc[CC_H_BIT]) || (a[3:0] > 4'H9)) - tmp_nxt[3:0] = 4'H6; - else - tmp_nxt[3:0] = 4'H0; - - // DAA handles carry in the weirdest way. - // If it's already set, it remains set, even if carry-out is 0. - // If it wasn't set, but the output of the operation is set, carry-out gets set. - {tmp_nxt[8], a_nxt} = {1'b0, a} + tmp_nxt[7:0]; - - cc_nxt[CC_C_BIT] = cc_nxt[CC_C_BIT] | tmp_nxt[8]; - - cc_nxt[CC_N_BIT] = a_nxt[7]; - cc_nxt[CC_Z_BIT] = (a_nxt == 8'H00); - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else if (Inst1 == OPCODE_INH_SYNC) - begin - CpuState_nxt = CPUSTATE_SYNC; - rLIC = 1'b1; - rAVMA = 1'b0; - end - else if (Inst1 == OPCODE_INH_MUL) - begin - tmp_nxt = 16'H0000; - ea_nxt[15:8] = 8'H00; - ea_nxt[7:0] = a; - a_nxt = 8; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_MUL_ACTION; - end - else if (Inst1 == OPCODE_INH_RTS) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_RTS_HI; - end - else if (Inst1 == OPCODE_INH_RTI) - begin - rAVMA = 1'b1; - tmp_nxt = 16'H1001; // Set tmp[12] to indicate an RTI being processed, and at least pull CC. - CpuState_nxt = CPUSTATE_PUL_ACTION; - NextState_nxt = CPUSTATE_FETCH_I1; - end - else if (Inst1 == OPCODE_INH_SWI) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_SWI_START; - end - else if (Inst1 == OPCODE_INH_CWAI) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_CWAI; - end - else if (Inst1 == OPCODE_INH_SEX) - begin - a_nxt = {8{b[7]}}; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else if (Inst1 == OPCODE_INH_ABX) - begin - x_nxt = x + b; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_ABX_DONTCARE; - end - else - begin - ALU_OP = ALU8Op; - if (IsTargetRegA) - ALU_A = a; - else - ALU_A = b; - - ALU_B = 0; - ALU_CC = cc; - cc_nxt = ALU[15:8]; - - if (ALU8Writeback) - begin - if (IsTargetRegA) - a_nxt = ALU[7:0]; - else - b_nxt = ALU[7:0]; - end - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - if (IsOneByteInstruction(Inst1)) // This check is probably superfluous. Every inherent instruction is 1 byte on the 6809. - pc_nxt = pc; // The 6809 auto-reads 2 bytes for every instruction. :( Adjust by not incrementing PC on the 2nd byte read. - end - - TYPE_IMMEDIATE: - begin - if (IsSpecialImmediate) - begin - if (Inst1 == OPCODE_IMM_ANDCC) - begin - pc_nxt = pc_p1; - cc_nxt = cc & D; //cc_nxt & Inst2_nxt; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_CC_DONTCARE; - end - else if (Inst1 == OPCODE_IMM_ORCC) - begin - pc_nxt = pc_p1; - cc_nxt = cc | D; //cc_nxt | Inst2_nxt; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_CC_DONTCARE; - end - else if ( (Inst1 == OPCODE_IMM_PSHS) | (Inst1 == OPCODE_IMM_PSHU) ) - begin - pc_nxt = pc_p1; - tmp_nxt[15] = 1'b0; - tmp_nxt[14] = Inst1[1]; // Mark whether to save to U or S. - tmp_nxt[13] = 1'b0; // Not pushing due to an interrupt. - tmp_nxt[13:8] = 6'H00; - tmp_nxt[7:0] = Inst2_nxt; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_PSH_DONTCARE1; - NextState_nxt = CPUSTATE_FETCH_I1; - end - else if ( (Inst1 == OPCODE_IMM_PULS) | (Inst1 == OPCODE_IMM_PULU) ) - begin - pc_nxt = pc_p1; - tmp_nxt[15] = 1'b0; - tmp_nxt[14] = Inst1[1]; // S (0) or U (1) stack in use. - tmp_nxt[13:8] = 6'H00; - tmp_nxt[7:0] = Inst2_nxt; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_PUL_DONTCARE1; - NextState_nxt = CPUSTATE_FETCH_I1; - end - else if (Inst1 == OPCODE_IMM_TFR) - begin - // The second byte lists the registers; Top nybble is reg #1, bottom is reg #2. - - case (Inst2_nxt[3:0]) - EXGTFR_REG_D: - {a_nxt,b_nxt} = EXGTFRRegA; - EXGTFR_REG_X: - x_nxt = EXGTFRRegA; - EXGTFR_REG_Y: - y_nxt = EXGTFRRegA; - EXGTFR_REG_U: - u_nxt = EXGTFRRegA; - EXGTFR_REG_S: - s_nxt = EXGTFRRegA; - EXGTFR_REG_PC: - pc_nxt = EXGTFRRegA; - EXGTFR_REG_DP: - dp_nxt = EXGTFRRegA[7:0]; - EXGTFR_REG_A: - a_nxt = EXGTFRRegA[7:0]; - EXGTFR_REG_B: - b_nxt = EXGTFRRegA[7:0]; - EXGTFR_REG_CC: - cc_nxt = EXGTFRRegA[7:0]; - default: - begin - end - endcase - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_TFR_DONTCARE1; - - end - else if (Inst1 == OPCODE_IMM_EXG) - begin - // The second byte lists the registers; Top nybble is reg #1, bottom is reg #2. - - case (Inst2_nxt[7:4]) - EXGTFR_REG_D: - {a_nxt,b_nxt} = EXGTFRRegB; - EXGTFR_REG_X: - x_nxt = EXGTFRRegB; - EXGTFR_REG_Y: - y_nxt = EXGTFRRegB; - EXGTFR_REG_U: - u_nxt = EXGTFRRegB; - EXGTFR_REG_S: - s_nxt = EXGTFRRegB; - EXGTFR_REG_PC: - pc_nxt = EXGTFRRegB; - EXGTFR_REG_DP: - dp_nxt = EXGTFRRegB[7:0]; - EXGTFR_REG_A: - a_nxt = EXGTFRRegB[7:0]; - EXGTFR_REG_B: - b_nxt = EXGTFRRegB[7:0]; - EXGTFR_REG_CC: - cc_nxt = EXGTFRRegB[7:0]; - default: - begin - end - endcase - case (Inst2_nxt[3:0]) - EXGTFR_REG_D: - {a_nxt,b_nxt} = EXGTFRRegA; - EXGTFR_REG_X: - x_nxt = EXGTFRRegA; - EXGTFR_REG_Y: - y_nxt = EXGTFRRegA; - EXGTFR_REG_U: - u_nxt = EXGTFRRegA; - EXGTFR_REG_S: - s_nxt = EXGTFRRegA; - EXGTFR_REG_PC: - pc_nxt = EXGTFRRegA; - EXGTFR_REG_DP: - dp_nxt = EXGTFRRegA[7:0]; - EXGTFR_REG_A: - a_nxt = EXGTFRRegA[7:0]; - EXGTFR_REG_B: - b_nxt = EXGTFRRegA[7:0]; - EXGTFR_REG_CC: - cc_nxt = EXGTFRRegA[7:0]; - default: - begin - end - endcase - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_EXG_DONTCARE1; - end - end - // Determine if this is an 8-bit ALU operation. - else if (Is8BitInst) - begin - ALU_OP = ALU8Op; - if (IsTargetRegA) - ALU_A = a; - else - ALU_A = b; - - ALU_B = Inst2_nxt; - ALU_CC = cc; - cc_nxt = ALU[15:8]; - - if (ALU8Writeback) - begin - if (IsTargetRegA) - a_nxt = ALU[7:0]; - else - b_nxt = ALU[7:0]; - end - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else // Then it must be a 16 bit instruction - begin - // 83 SUBD - // 8C CMPX - // 8E LDX - // C3 ADDD - // CC LDD - // CE LDU - // 108E CMPD - // 108C CMPY - // 108E LDY - // 10CE LDS - // 1183 CMPU - // 118C CMPS - // Wow, they were just stuffing them in willy-nilly ... - - // LD* 16 bit immediate - if (IsALU16Opcode) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_16IMM_LO; - end - // there's a dead zone here; I need an else to take us back to CPUSTATE_FETCHI1 if we want to ignore illegal instructions, to CPUSTATE_DEAD if we want to catch them. - - end - - end - - TYPE_RELATIVE: - begin - // Is this a LB** or a B**? - // If InstPage2 is set, it's a long branch; if clear, a normal branch. - if ( (InstPage2) || (Inst1 == INST_LBRA) || (Inst1 == INST_LBSR) ) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_LBRA_OFFSETLOW; - end - else - begin - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_BRA_DONTCARE; - end - - end - default: - begin - CpuState_nxt = CPUSTATE_FETCH_I1; - end - endcase - end - end - - - CPUSTATE_LBRA_OFFSETLOW: - begin - addr_nxt = pc; - pc_nxt = pc_p1; - Inst3_nxt = D[7:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_LBRA_DONTCARE; - end - - CPUSTATE_LBRA_DONTCARE: - begin - addr_nxt = 16'HFFFF; - if ( TakeBranch ) - begin - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_LBRA_DONTCARE2; - end - else - begin - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - end - - CPUSTATE_BRA_DONTCARE: - begin - addr_nxt = 16'HFFFF; - tmp_nxt = pc; - if (TakeBranch) - begin - pc_nxt = pc + { {8{Inst2[7]}}, Inst2[7:0]}; // Sign-extend the 8 bit offset to 16. - - if (Inst1 == INST_BSR) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_BSR_DONTCARE1; - end - else - begin - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - end - else - begin - rLIC = 1'b1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - end - - CPUSTATE_LBRA_DONTCARE2: - begin - tmp_nxt= pc; - addr_nxt = 16'HFFFF; - - // Take branch - pc_nxt = pc + {Inst2[7:0], Inst3[7:0]}; - if (Inst1 == INST_LBSR) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_BSR_DONTCARE1; - end - else - begin - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - end - - CPUSTATE_BSR_DONTCARE1: - begin - addr_nxt = pc; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_BSR_DONTCARE2; - end - - CPUSTATE_BSR_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_BSR_RETURNLOW; - end - - CPUSTATE_BSR_RETURNLOW: - begin - addr_nxt = s_m1; - s_nxt = s_m1; - DOutput[7:0] = tmp[7:0]; - RnWOut = 0; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_BSR_RETURNHIGH; - end - - CPUSTATE_BSR_RETURNHIGH: - begin - addr_nxt = s_m1; - s_nxt = s_m1; - DOutput[7:0] = tmp[15:8]; - RnWOut = 0; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; // after this, RnWOut must go to 1, and the bus needs the PC placed on it. - end - - CPUSTATE_TFR_DONTCARE1: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_TFR_DONTCARE2; - end - - CPUSTATE_TFR_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_TFR_DONTCARE3; - end - - CPUSTATE_TFR_DONTCARE3: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_TFR_DONTCARE4; - end - - CPUSTATE_TFR_DONTCARE4: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - rLIC = 1'b1; // Instruction done! - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_EXG_DONTCARE1: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_EXG_DONTCARE2; - end - - CPUSTATE_EXG_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_EXG_DONTCARE3; - end - - CPUSTATE_EXG_DONTCARE3: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_EXG_DONTCARE4; - end - - CPUSTATE_EXG_DONTCARE4: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_EXG_DONTCARE5; - end - - CPUSTATE_EXG_DONTCARE5: - begin - rAVMA = 1'b0; - addr_nxt = 16'HFFFF; - CpuState_nxt = CPUSTATE_EXG_DONTCARE6; - end - - CPUSTATE_EXG_DONTCARE6: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - rLIC = 1'b1; // Instruction done! - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_ABX_DONTCARE: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - rLIC = 1'b1; // Instruction done! - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_RTS_HI: - begin - addr_nxt = s; - s_nxt = s_p1; - pc_nxt[15:8] = D[7:0]; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_RTS_LO; - end - - CPUSTATE_RTS_LO: - begin - addr_nxt = s; - s_nxt = s_p1; - pc_nxt[7:0] = D[7:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_RTS_DONTCARE2; - end - - CPUSTATE_RTS_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_16IMM_LO: - begin - addr_nxt = pc; - pc_nxt = pc_p1; - - ALU16_OP = ALU16Opcode; - ALU16_CC = cc; - ALU16_B = {Inst2, D[7:0]}; - - case (ALU16Reg) - ALU16_REG_X: - ALU16_A = x; - ALU16_REG_D: - ALU16_A = {a, b}; - ALU16_REG_Y: - ALU16_A = y; - ALU16_REG_U: - ALU16_A = u; - ALU16_REG_S: - ALU16_A = s; - default: - ALU16_A = 16'H0; - endcase - - if (ALU16OpWriteback) - begin - case (ALU16Reg) - ALU16_REG_X: - {cc_nxt, x_nxt} = ALU16; - ALU16_REG_D: - {cc_nxt, a_nxt, b_nxt} = ALU16; - ALU16_REG_Y: - {cc_nxt, y_nxt} = ALU16; - ALU16_REG_U: - {cc_nxt, u_nxt} = ALU16; - ALU16_REG_S: - {cc_nxt, s_nxt} = ALU16; - default: - begin - end - endcase - end - else - cc_nxt = ALU16[23:16]; - - if (ALU16_OP == ALUOP16_LD) - begin - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_16IMM_DONTCARE; - end - end - - CPUSTATE_DIRECT_DONTCARE: - begin - addr_nxt = 16'HFFFF; - - if (IsJMP(Inst1)) - begin - pc_nxt = ea; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_ALU_EA; - end - end - - CPUSTATE_ALU_EA: - begin - - // Is Figure 18/5 Column 2? JMP (not Immediate Mode) - // This actually isn't done here. All checks passing in to ALU_EA should check for a JMP; FIXME EVERYWHERE - - // Is Figure 18/5 Column 8? TST (not immediate mode) - // THIS IS BURIED IN THE COLUMN 3 section with comparisons to ALUOP_TST. - - // Is Figure 18/5 Column 3? - if (IsALU8Set1(Inst1)) - begin - addr_nxt = ea; - - ALU_OP = ALU8Op; - ALU_B = D[7:0]; - ALU_CC = cc; - - if (IsTargetRegA) - ALU_A = a; - else - ALU_A = b; - - cc_nxt = ALU[15:8]; - - if ( (ALU8Writeback) ) - begin - if (IsTargetRegA) - a_nxt = ALU[7:0]; - else - b_nxt = ALU[7:0]; - end - - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - // Is Figure 18/5 Column 4? (Store, 8 bits) - else if (IsStore8) - begin - addr_nxt = ea; - RnWOut = 0; // write - - ALU_OP = ALUOP_LD; // load has the same CC characteristics as store - ALU_A = 8'H00; - ALU_CC = cc; - - case (Store8RegisterNum) - ST8_REG_A: - begin - DOutput = a; - ALU_B = a; - end - ST8_REG_B: - begin - DOutput = b; - ALU_B = b; - end - - - endcase - - cc_nxt = ALU[15:8]; - - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - // Is Figure 18/5 Column 5? (Load, 16 bits) - else if (IsALU16Opcode & (ALU16Opcode == ALUOP16_LD)) - begin - addr_nxt = ea; - ea_nxt = ea_p1; - - case (ALU16Reg) - ALU16_REG_X: - x_nxt[15:8] = D[7:0]; - ALU16_REG_D: - a_nxt = D[7:0]; - ALU16_REG_Y: - y_nxt[15:8] = D[7:0]; - ALU16_REG_S: - s_nxt[15:8] = D[7:0]; - ALU16_REG_U: - u_nxt[15:8] = D[7:0]; - default: - begin - end - endcase - rAVMA = 1'b1; - rBUSY = 1'b1; - CpuState_nxt = CPUSTATE_LD16_LO; - - end - - // Is Figure 18/5 Column 6? (Store, 16 bits) - else if (IsStore16) - begin - addr_nxt = ea; - ea_nxt = ea_p1; - - ALU16_OP = ALUOP16_LD; // LD and ST have the same CC characteristics - ALU16_CC = cc; - ALU16_A = 8'H00; - - case (StoreRegisterNum) - ST16_REG_X: - begin - DOutput[7:0] = x[15:8]; - ALU16_B = x; - end - ST16_REG_Y: - begin - DOutput[7:0] = y[15:8]; - ALU16_B = y; - end - ST16_REG_U: - begin - DOutput[7:0] = u[15:8]; - ALU16_B = u; - end - ST16_REG_S: - begin - DOutput[7:0] = s[15:8]; - ALU16_B = s; - end - ST16_REG_D: - begin - DOutput[7:0] = a[7:0]; - ALU16_B = {a,b}; - end - default: - begin - end - endcase - - cc_nxt = ALU16[23:16]; - - RnWOut = 0; // Write - rAVMA = 1'b1; - rBUSY = 1'b1; - CpuState_nxt = CPUSTATE_ST16_LO; - end - - // Is Figure 18/5 Column 7? - else if (IsALU8Set0(Inst1)) - begin - // These are registerless instructions, ala - // ASL, ASR, CLR, COM, DEC, INC, (LSL), LSR, NEG, ROL, ROR - // and TST (special!) - // They require READ, Modify (the operation above), WRITE. Between the Read and the Write cycles, there's actually a /VMA - // cycle where the 6809 likely did the operation. We'll include a /VMA cycle for accuracy, but we'll do the work primarily in the first cycle. - addr_nxt = ea; - - ALU_OP = ALU8Op; - ALU_A = D[7:0]; - ALU_CC = cc; - tmp_nxt[15:8] = cc; // for debug only - tmp_nxt[7:0] = ALU[7:0]; - cc_nxt = ALU[15:8]; - if (ALU8Op == ALUOP_TST) - begin - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_TST_DONTCARE1; - end - else - begin - rAVMA = 1'b0; - rBUSY = 1'b1; - CpuState_nxt = CPUSTATE_ALU_DONTCARE; - end - - end - - // Is Figure 18/5 Column 8? TST - // NOTE: - // THIS IS BURIED IN THE COLUMN 3 section with comparisons to ALUOP_TST. [Directly above.] - - - // Is Figure 18/5 Column 9? (16-bit ALU ops, non-load) - else if (IsALU16Opcode && (ALU16Opcode != ALUOP16_LD) && ((Inst1 < 8'H30) || (Inst1 > 8'H33)) ) // 30-33 = LEAX, LEAY, LEAS, LEAU; don't include them here. - begin - addr_nxt = ea; - ea_nxt = ea_p1; - - tmp_nxt[15:8] = D[7:0]; - rAVMA = 1'b1; - rBUSY = 1'b1; - CpuState_nxt = CPUSTATE_ALU16_LO; - - end - - // Is Figure 18/5 Column 10? JSR (not Immediate Mode) - else if ((Inst1 == 8'H9D) || (Inst1 == 8'HAD) || (Inst1 == 8'HBD)) // JSR - begin - pc_nxt = ea; - addr_nxt = ea; - tmp_nxt = pc; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_JSR_DONTCARE; - end - // Is Figure 18/5 Column 11? LEA(X,Y,S,U) - else if ((Inst1 >= 8'H30) && (Inst1<= 8'H33)) - begin - addr_nxt = 16'HFFFF; // Ack, actually a valid cycle, this isn't a dontcare (/VMA) cycle! - - ALU16_OP = ALU16Opcode; - ALU16_CC = cc; - ALU16_A = ea; - - case (ALU16Reg) - ALU16_REG_X: - {cc_nxt, x_nxt} = ALU16; - ALU16_REG_Y: - {cc_nxt, y_nxt} = ALU16; - ALU16_REG_U: - u_nxt = ALU16[15:0]; - ALU16_REG_S: - s_nxt = ALU16[15:0]; - default: - begin - end - endcase - - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - - end - - end - - - CPUSTATE_ALU_DONTCARE: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - rBUSY = 1'b1; // We do nothing here, but on the real 6809, they did the modify phase here. :| - CpuState_nxt = CPUSTATE_ALU_WRITEBACK; - end - - CPUSTATE_ALU_WRITEBACK: - begin - addr_nxt = ea; - RnWOut = 0; // Write - DOutput = tmp[7:0]; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_LD16_LO: - begin - addr_nxt = ea; - - case (ALU16Reg) - ALU16_REG_X: - begin - x_nxt[7:0] = D[7:0]; - ALU16_B[15:8] = x[15:8]; - end - ALU16_REG_D: - begin - b_nxt = D[7:0]; - ALU16_B[15:8] = a; - end - ALU16_REG_Y: - begin - y_nxt[7:0] = D[7:0]; - ALU16_B[15:8] = y[15:8]; - end - ALU16_REG_S: - begin - s_nxt[7:0] = D[7:0]; - ALU16_B[15:8] = s[15:8]; - end - ALU16_REG_U: - begin - u_nxt[7:0] = D[7:0]; - ALU16_B[15:8] = u[15:8]; - end - default: - begin - end - - endcase - - ALU16_OP = ALU16Opcode; - ALU16_CC = cc; - ALU16_A = 8'H00; - ALU16_B[7:0] = D[7:0]; - cc_nxt = ALU16[23:16]; - - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_ST16_LO: - begin - addr_nxt = ea; - ea_nxt = ea_p1; - case (StoreRegisterNum) - ST16_REG_X: - DOutput[7:0] = x[7:0]; - ST16_REG_Y: - DOutput[7:0] = y[7:0]; - ST16_REG_U: - DOutput[7:0] = u[7:0]; - ST16_REG_S: - DOutput[7:0] = s[7:0]; - ST16_REG_D: - DOutput[7:0] = b[7:0]; - default: - begin - end - endcase - RnWOut = 0; // write - - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_ALU16_LO: - begin - addr_nxt = ea; - - ALU16_OP = ALU16Opcode; - ALU16_CC = cc; - - ALU16_B = {tmp[15:8], D[7:0]}; - - case (ALU16Reg) - ALU16_REG_X: - ALU16_A = x; - ALU16_REG_D: - ALU16_A = {a, b}; - ALU16_REG_Y: - ALU16_A = y; - ALU16_REG_S: - ALU16_A = s; - ALU16_REG_U: - ALU16_A = u; - default: - ALU16_A = 16'H0; - - endcase - - if (ALU16OpWriteback) - begin - case (ALU16Reg) - ALU16_REG_X: - {cc_nxt, x_nxt} = ALU16; - ALU16_REG_D: - {cc_nxt, a_nxt, b_nxt} = ALU16; - ALU16_REG_Y: - {cc_nxt, y_nxt} = ALU16; - ALU16_REG_U: - {cc_nxt, u_nxt} = ALU16; - ALU16_REG_S: - {cc_nxt, s_nxt} = ALU16; - default: - begin - end - endcase - end - else - cc_nxt = ALU16[23:16]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_ALU16_DONTCARE; - end - - CPUSTATE_ALU16_DONTCARE: - begin - addr_nxt = 16'HFFFF; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - - CPUSTATE_JSR_DONTCARE: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_JSR_RETLO; - end - - CPUSTATE_JSR_RETLO: - begin - addr_nxt = s_m1; - s_nxt = s_m1; - RnWOut = 0; - DOutput = tmp[7:0]; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_JSR_RETHI; - end - - CPUSTATE_JSR_RETHI: - begin - addr_nxt = s_m1; - s_nxt = s_m1; - RnWOut = 0; - DOutput = tmp[15:8]; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_EXTENDED_ADDRLO: - begin - addr_nxt = pc; - pc_nxt = pc_p1; - ea_nxt[7:0] = D[7:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_EXTENDED_DONTCARE; - end - - CPUSTATE_EXTENDED_DONTCARE: - begin - addr_nxt = 16'HFFFF; - if (IsJMP(Inst1)) - begin - pc_nxt = ea; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_ALU_EA; - end - end - - CPUSTATE_INDEXED_BASE: - begin - addr_nxt = pc; - - Inst3_nxt = D[7:0]; - - case (IndexedRegister) - IDX_REG_X: - ALU16_A = x; - IDX_REG_Y: - ALU16_A = y; - IDX_REG_U: - ALU16_A = u; - IDX_REG_S: - ALU16_A = s; - IDX_REG_PC: - ALU16_A = pc_p1; - default: - ALU16_A = 16'H0; - endcase - ALU16_OP = ALUOP16_ADD; - - case (IndexedMode) - IDX_MODE_NOOFFSET: - begin - case (IndexedRegister) - IDX_REG_X: - ea_nxt = x; - IDX_REG_Y: - ea_nxt = y; - IDX_REG_U: - ea_nxt = u; - IDX_REG_S: - ea_nxt = s; - default: - ea_nxt = 16'H0; - endcase - - if (IndexedIndirect) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_INDIRECT_HI; - end - else - begin - if (IsJMP(Inst1)) - begin - pc_nxt = ea_nxt; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_ALU_EA; - end - end - end - - IDX_MODE_5BIT_OFFSET: - begin - // The offset is the bottom 5 bits of the Index Postbyte, which is Inst2 here. - // We'll sign-extend it to 16 bits. - ALU16_B = { {11{Inst2[4]}}, Inst2[4:0] }; - ea_nxt = ALU16[15:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_DONTCARE3; - end - - - IDX_MODE_8BIT_OFFSET_PC: - begin - ALU16_B = { {8{D[7]}}, D[7:0] }; - pc_nxt = pc_p1; - ea_nxt = ALU16[15:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_DONTCARE3; - end - - IDX_MODE_8BIT_OFFSET: - begin - ALU16_B = { {8{D[7]}}, D[7:0] }; - pc_nxt = pc_p1; - ea_nxt = ALU16[15:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_DONTCARE3; - end - - IDX_MODE_A_OFFSET: - begin - ALU16_B = { {8{a[7]}}, a[7:0] }; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_DONTCARE3; - ea_nxt = ALU16[15:0]; - end - - IDX_MODE_B_OFFSET: - begin - ALU16_B = { {8{b[7]}}, b[7:0] }; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_DONTCARE3; - ea_nxt = ALU16[15:0]; - end - - IDX_MODE_D_OFFSET: - begin - ALU16_B = {a, b}; - - ea_nxt = ALU16[15:0]; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE1; - end - - IDX_MODE_POSTINC1: - begin - ALU16_B = 16'H1; - ea_nxt = ALU16_A; - case (IndexedRegister) - IDX_REG_X: - x_nxt = ALU16[15:0]; - IDX_REG_Y: - y_nxt = ALU16[15:0]; - IDX_REG_U: - u_nxt = ALU16[15:0]; - IDX_REG_S: - s_nxt = ALU16[15:0]; - default: - begin - end - endcase - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; - end - - IDX_MODE_POSTINC2: - begin - ALU16_B = 16'H2; - ea_nxt = ALU16_A; - case (IndexedRegister) - IDX_REG_X: - x_nxt = ALU16[15:0]; - IDX_REG_Y: - y_nxt = ALU16[15:0]; - IDX_REG_U: - u_nxt = ALU16[15:0]; - IDX_REG_S: - s_nxt = ALU16[15:0]; - default: - begin - end - endcase - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE0; - end - - IDX_MODE_PREDEC1: - begin - ALU16_B = 16'HFFFF; // -1 - case (IndexedRegister) - IDX_REG_X: - x_nxt = ALU16[15:0]; - IDX_REG_Y: - y_nxt = ALU16[15:0]; - IDX_REG_U: - u_nxt = ALU16[15:0]; - IDX_REG_S: - s_nxt = ALU16[15:0]; - default: - begin - end - endcase - ea_nxt = ALU16[15:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; - end - - IDX_MODE_PREDEC2: - begin - ALU16_B = 16'HFFFE; // -2 - case (IndexedRegister) - IDX_REG_X: - x_nxt = ALU16[15:0]; - IDX_REG_Y: - y_nxt = ALU16[15:0]; - IDX_REG_U: - u_nxt = ALU16[15:0]; - IDX_REG_S: - s_nxt = ALU16[15:0]; - default: - begin - end - endcase - ea_nxt = ALU16[15:0]; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE0; - end - - IDX_MODE_16BIT_OFFSET_PC: - begin - tmp_nxt[15:8] = D[7:0]; - pc_nxt = pc_p1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_16OFFSET_LO; - end - - IDX_MODE_16BIT_OFFSET: - begin - tmp_nxt[15:8] = D[7:0]; - pc_nxt = pc_p1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_16OFFSET_LO; - end - - IDX_MODE_EXTENDED_INDIRECT: - begin - ea_nxt[15:8] = D[7:0]; - pc_nxt = pc_p1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_EXTIND_LO; - end - - default: - begin - rLIC = 1'b1; - CpuState_nxt = PostIllegalState; - end - - endcase - end - - CPUSTATE_IDX_OFFSET_LO: - begin - tmp_nxt[7:0] = D[7:0]; - addr_nxt = pc; - pc_nxt = pc_p1; - ALU16_B = tmp_nxt; - - case (IndexedRegister) - IDX_REG_X: - ALU16_A = x; - IDX_REG_Y: - ALU16_A = y; - IDX_REG_U: - ALU16_A = u; - IDX_REG_S: - ALU16_A = s; - IDX_REG_PC: - ALU16_A = pc; - default: - ALU16_A = 16'H0; - endcase - ALU16_OP = ALUOP16_ADD; - - ea_nxt = ALU16[15:0]; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE1; - end - - - CPUSTATE_IDX_DONTCARE3: - begin - addr_nxt = 16'HFFFF; - if (IndexedIndirect) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_INDIRECT_HI; - end - else - begin - if (IsJMP(Inst1)) - begin - pc_nxt = ea; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_ALU_EA; - end - end - - end - - CPUSTATE_IDX_16OFFSET_LO: - begin - addr_nxt = pc; - pc_nxt = pc_p1; - - case (IndexedRegister) - IDX_REG_X: - ALU16_A = x; - IDX_REG_Y: - ALU16_A = y; - IDX_REG_U: - ALU16_A = u; - IDX_REG_S: - ALU16_A = s; - IDX_REG_PC: - ALU16_A = pc_nxt; // Whups; tricky; not part of the actual pattern - default: - ALU16_A = x; // Default to something - endcase - - ALU16_OP = ALUOP16_ADD; - - ALU16_B = {tmp[15:8], D[7:0]}; - - ea_nxt = ALU16[15:0]; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE1; - end - - CPUSTATE_IDX_16OFF_DONTCARE1: - begin - addr_nxt = pc; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; - end - - CPUSTATE_IDX_16OFF_DONTCARE0: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; - end - - CPUSTATE_IDX_16OFF_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - if (IndexedRegister == IDX_REG_PC) - begin - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_PC16OFF_DONTCARE; - end - else - begin - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE3; - end - end - - CPUSTATE_IDX_PC16OFF_DONTCARE: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE3; - end - - - CPUSTATE_IDX_16OFF_DONTCARE3: - begin - addr_nxt = 16'HFFFF; - if (IndexedIndirect) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_INDIRECT_HI; - end - else - begin - if (IsJMP(Inst1)) - begin - pc_nxt = ea; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_ALU_EA; - end - end - end - - CPUSTATE_IDX_DOFF_DONTCARE1: - begin - addr_nxt = pc_p1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE2; - end - - CPUSTATE_IDX_DOFF_DONTCARE2: - begin - addr_nxt = pc_p2; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IDX_16OFF_DONTCARE2; - end - - CPUSTATE_IDX_DOFF_DONTCARE3: - begin - addr_nxt = pc_p3; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_DOFF_DONTCARE2; - end - - CPUSTATE_IDX_EXTIND_LO: - begin - ea_nxt[7:0] = D[7:0]; - addr_nxt = pc; - pc_nxt = pc_p1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IDX_EXTIND_DONTCARE; - end - - CPUSTATE_IDX_EXTIND_DONTCARE: - begin - addr_nxt = pc; - if (IndexedIndirect) - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_INDIRECT_HI; - end - else - begin - if (IsJMP(Inst1)) - begin - pc_nxt = ea; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_ALU_EA; - end - end - end - - CPUSTATE_INDIRECT_HI: - begin - addr_nxt = ea; - tmp_nxt[15:8] = D[7:0]; - rAVMA = 1'b1; - rBUSY = 1'b1; - CpuState_nxt = CPUSTATE_INDIRECT_LO; - end - - CPUSTATE_INDIRECT_LO: - begin - addr_nxt = ea_p1; - ea_nxt[15:8] = tmp_nxt[15:8]; - ea_nxt[7:0] = D[7:0]; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_INDIRECT_DONTCARE; - end - - CPUSTATE_INDIRECT_DONTCARE: - begin - addr_nxt = 16'HFFFF; - if (IsJMP(Inst1)) - begin - pc_nxt = ea; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - else - begin - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_ALU_EA; - end - end - - CPUSTATE_MUL_ACTION: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - // tmp = result - // ea = additor (the shifted multiplicand) - // a = counter - // b is the multiplier (which gets shifted right) - if (a != 8'H00) - begin - if (b[0]) - begin - tmp_nxt = tmp + ea; - end - ea_nxt = {ea[14:0], 1'b0}; - b_nxt = {1'b0, b[7:1]}; - a_nxt = a - 8'H1; - end - else - begin - {a_nxt, b_nxt} = tmp; - - cc_nxt[CC_Z_BIT] = (tmp == 0); - cc_nxt[CC_C_BIT] = tmp[7]; - rLIC = 1'b1; // Instruction done! - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - end - - CPUSTATE_PSH_DONTCARE1: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_PSH_DONTCARE2; - end - - CPUSTATE_PSH_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_PSH_DONTCARE3; - end - - CPUSTATE_PSH_DONTCARE3: - begin - addr_nxt = (Inst1[1]) ? u : s; - - CpuState_nxt = CPUSTATE_PSH_ACTION; - end - - CPUSTATE_PSH_ACTION: - begin - rAVMA = 1'b1; - if (tmp[7] & ~(tmp[15])) // PC_LO - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = pc[7:0]; - RnWOut = 1'b0; // write - tmp_nxt[15] = 1'b1; - end - else if (tmp[7] & (tmp[15])) // PC_HI - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = pc[15:8]; - RnWOut = 1'b0; // write - tmp_nxt[7] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else if (tmp[6] & ~(tmp[15])) // U/S_LO - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = (tmp[14]) ? s[7:0] : u[7:0]; - RnWOut = 1'b0; // write - tmp_nxt[15] = 1'b1; - end - else if (tmp[6] & (tmp[15])) // U/S_HI - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = (tmp[14]) ? s[15:8] : u[15:8]; - RnWOut = 1'b0; // write - tmp_nxt[6] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else if (tmp[5] & ~(tmp[15])) // Y_LO - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = y[7:0]; - RnWOut = 1'b0; // write - tmp_nxt[15] = 1'b1; - end - else if (tmp[5] & (tmp[15])) // Y_HI - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = y[15:8]; - RnWOut = 1'b0; // write - tmp_nxt[5] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else if (tmp[4] & ~(tmp[15])) // X_LO - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = x[7:0]; - RnWOut = 1'b0; // write - tmp_nxt[15] = 1'b1; - end - else if (tmp[4] & (tmp[15])) // X_HI - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = x[15:8]; - RnWOut = 1'b0; // write - tmp_nxt[4] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else if (tmp[3]) // DP - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = dp; - RnWOut = 1'b0; // write - tmp_nxt[3] = 1'b0; - end - else if (tmp[2]) // B - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = b; - RnWOut = 1'b0; // write - tmp_nxt[2] = 1'b0; - end - else if (tmp[1]) // A - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = a; - RnWOut = 1'b0; // write - tmp_nxt[1] = 1'b0; - end - else if (tmp[0]) // CC - begin - addr_nxt = (tmp[14]) ? u_m1 : s_m1; - if (tmp[14]) - u_nxt = u_m1; - else - s_nxt = s_m1; - DOutput = cc; - RnWOut = 1'b0; // write - tmp_nxt[0] = 1'b0; - end - if (tmp[13]) // Then we're pushing for an IRQ, and LIC is supposed to be set. - rLIC = 1'b1; - if (tmp_nxt[7:0] == 8'H00) - begin - if (NextState == CPUSTATE_FETCH_I1) - begin - rAVMA = 1'b1; - rLIC = 1'b1; - end - else - rAVMA = 1'b0; - CpuState_nxt = NextState; - end - end - - CPUSTATE_PUL_DONTCARE1: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_PUL_DONTCARE2; - end - - CPUSTATE_PUL_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_PUL_ACTION; - end - - CPUSTATE_PUL_ACTION: - begin - rAVMA = 1'b1; - if (tmp[0]) // CC - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - cc_nxt = D[7:0]; - if (tmp[12] == 1'b1) // This pull is from an RTI, the E flag comes from the retrieved CC, and set the tmp_nxt accordingly, indicating what other registers to retrieve - begin - if (D[CC_E_BIT]) - tmp_nxt[7:0] = 8'HFE; // Retrieve all registers (ENTIRE) [CC is already retrieved] - else - tmp_nxt[7:0] = 8'H80; // Retrieve PC and CC [CC is already retrieved] - end - else - tmp_nxt[0] = 1'b0; - end - else if (tmp[1]) // A - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - a_nxt = D[7:0]; - tmp_nxt[1] = 1'b0; - end - else if (tmp[2]) // B - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - b_nxt = D[7:0]; - tmp_nxt[2] = 1'b0; - end - else if (tmp[3]) // DP - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - dp_nxt = D[7:0]; - tmp_nxt[3] = 1'b0; - end - else if (tmp[4] & (~tmp[15])) // X_HI - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - x_nxt[15:8] = D[7:0]; - tmp_nxt[15] = 1'b1; - end - else if (tmp[4] & tmp[15]) // X_LO - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - x_nxt[7:0] = D[7:0]; - tmp_nxt[4] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else if (tmp[5] & (~tmp[15])) // Y_HI - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - y_nxt[15:8] = D[7:0]; - tmp_nxt[15] = 1'b1; - end - else if (tmp[5] & tmp[15]) // Y_LO - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - y_nxt[7:0] = D[7:0]; - tmp_nxt[5] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else if (tmp[6] & (~tmp[15])) // U/S_HI - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - if (tmp[14]) - s_nxt[15:8] = D[7:0]; - else - u_nxt[15:8] = D[7:0]; - tmp_nxt[15] = 1'b1; - end - else if (tmp[6] & tmp[15]) // U/S_LO - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - if (tmp[14]) - s_nxt[7:0] = D[7:0]; - else - u_nxt[7:0] = D[7:0]; - tmp_nxt[6] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else if (tmp[7] & (~tmp[15])) // PC_HI - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - pc_nxt[15:8] = D[7:0]; - tmp_nxt[15] = 1'b1; - end - else if (tmp[7] & tmp[15]) // PC_LO - begin - addr_nxt = (tmp[14]) ? u : s; - if (tmp[14]) - u_nxt = u_p1; - else - s_nxt = s_p1; - pc_nxt[7:0] = D[7:0]; - tmp_nxt[7] = 1'b0; - tmp_nxt[15] = 1'b0; - end - else - begin - addr_nxt = (tmp[14]) ? u : s; - if (NextState == CPUSTATE_FETCH_I1) - begin - rAVMA = 1'b1; - rLIC = 1'b1; - end - else - rAVMA = 1'b0; - CpuState_nxt = NextState; - end - end - - CPUSTATE_NMI_START: - begin - NMIClear_nxt = 1'b1; - addr_nxt = pc; - // tmp stands as the bits to push to the stack - tmp_nxt = 16'H20FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC; set LIC on every push - NextState_nxt = CPUSTATE_IRQ_DONTCARE2; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_IRQ_DONTCARE; - IntType_nxt = INTTYPE_NMI; - cc_nxt[CC_E_BIT] = 1'b1; - end - - CPUSTATE_IRQ_START: - begin - addr_nxt = pc; - tmp_nxt = 16'H20FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC; set LIC on every push - NextState_nxt = CPUSTATE_IRQ_DONTCARE2; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IRQ_DONTCARE; - IntType_nxt = INTTYPE_IRQ; - cc_nxt[CC_E_BIT] = 1'b1; - end - - CPUSTATE_FIRQ_START: - begin - addr_nxt = pc; - tmp_nxt = 16'H2081; // Save to the S stack, PC, CC; set LIC on every push - NextState_nxt = CPUSTATE_IRQ_DONTCARE2; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IRQ_DONTCARE; - IntType_nxt = INTTYPE_FIRQ; - cc_nxt[CC_E_BIT] = 1'b0; - end - - CPUSTATE_SWI_START: - begin - addr_nxt = pc; - tmp_nxt = 16'H00FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC - - NextState_nxt = CPUSTATE_IRQ_DONTCARE2; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IRQ_DONTCARE; - if (InstPage3) - IntType_nxt = INTTYPE_SWI3; - if (InstPage2) - IntType_nxt = INTTYPE_SWI2; - else - IntType_nxt = INTTYPE_SWI; - - cc_nxt[CC_E_BIT] = 1'b1; - end - - CPUSTATE_IRQ_DONTCARE: - begin - NMIClear_nxt = 1'b0; - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_PSH_ACTION; - end - - - CPUSTATE_IRQ_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; - rLIC = 1'b1; - end - - CPUSTATE_IRQ_VECTOR_HI: - begin - case (IntType) - INTTYPE_NMI: - begin - addr_nxt = `NMI_VECTOR; - BS_nxt = 1'b1; // ACK Interrupt - end - INTTYPE_IRQ: - begin - addr_nxt = `IRQ_VECTOR; - BS_nxt = 1'b1; // ACK Interrupt - end - INTTYPE_SWI: - begin - addr_nxt = `SWI_VECTOR; - end - INTTYPE_FIRQ: - begin - addr_nxt = `FIRQ_VECTOR; - BS_nxt = 1'b1; // ACK Interrupt - end - INTTYPE_SWI2: - begin - addr_nxt = `SWI2_VECTOR; - end - INTTYPE_SWI3: - begin - addr_nxt = `SWI3_VECTOR; - end - default: // make the default an IRQ, even though it really should never happen - begin - addr_nxt = `IRQ_VECTOR; - BS_nxt = 1'b1; // ACK Interrupt - end - endcase - - pc_nxt[15:8] = D[7:0]; - rAVMA = 1'b1; - rBUSY = 1'b1; - rLIC = 1'b1; - CpuState_nxt = CPUSTATE_IRQ_VECTOR_LO; - - - end - - CPUSTATE_IRQ_VECTOR_LO: - begin - case (IntType) - INTTYPE_NMI: - begin - addr_nxt = `NMI_VECTOR+16'H1; - cc_nxt[CC_I_BIT] = 1'b1; - cc_nxt[CC_F_BIT] = 1'b1; - BS_nxt = 1'b1; // ACK Interrupt - end - INTTYPE_IRQ: - begin - addr_nxt = `IRQ_VECTOR+16'H1; - cc_nxt[CC_I_BIT] = 1'b1; - BS_nxt = 1'b1; // ACK Interrupt - end - INTTYPE_SWI: - begin - addr_nxt = `SWI_VECTOR+16'H1; - cc_nxt[CC_F_BIT] = 1'b1; - cc_nxt[CC_I_BIT] = 1'b1; - rLIC = 1'b1; - end - INTTYPE_FIRQ: - begin - addr_nxt = `FIRQ_VECTOR+16'H1; - cc_nxt[CC_F_BIT] = 1'b1; - cc_nxt[CC_I_BIT] = 1'b1; - BS_nxt = 1'b1; // ACK Interrupt - end - INTTYPE_SWI2: - begin - addr_nxt = `SWI2_VECTOR+16'H1; - rLIC = 1'b1; - end - INTTYPE_SWI3: - begin - addr_nxt = `SWI3_VECTOR+16'H1; - rLIC = 1'b1; - end - default: - begin - end - endcase - - pc_nxt[7:0] = D[7:0]; - rAVMA = 1'b1; - rLIC = 1'b1; - CpuState_nxt = CPUSTATE_INT_DONTCARE; - end - - CPUSTATE_INT_DONTCARE: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - rLIC = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_CC_DONTCARE: - begin - addr_nxt = pc; - rLIC = 1'b1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_TST_DONTCARE1: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_TST_DONTCARE2; - end - - CPUSTATE_TST_DONTCARE2: - begin - addr_nxt = 16'HFFFF; - rLIC = 1'b1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_DEBUG: - begin - addr_nxt = tmp; - rLIC = 1'b1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_16IMM_DONTCARE: - begin - addr_nxt = 16'HFFFF; - rLIC = 1'b1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_SYNC: - begin - addr_nxt = 16'HFFFF; - BA_nxt = 1'b1; - rLIC = 1'b1; - rAVMA = 1'b0; - - if (~(NMILatched & FIRQLatched & IRQLatched)) - begin - CpuState_nxt = CPUSTATE_SYNC_EXIT; - end - end - - CPUSTATE_SYNC_EXIT: - begin - addr_nxt = 16'HFFFF; - BA_nxt = 1'b1; - rLIC = 1'b1; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - - CPUSTATE_DMABREQ: - begin - rAVMA = 1'b0; - addr_nxt = 16'HFFFF; - BS_nxt = 1'b1; - BA_nxt = 1'b1; - rLIC = 1'b1; - tmp_nxt[3:0] = tmp[3:0] - 1'b1; - if ( (tmp[3:0] == 4'H0) | (DMABREQSample2) ) - begin - CpuState_nxt = CPUSTATE_DMABREQ_EXIT; - end - end - - CPUSTATE_DMABREQ_EXIT: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_HALTED: - begin - rAVMA = 1'b0; - addr_nxt = 16'HFFFF; - BS_nxt = 1'b1; - BA_nxt = 1'b1; - rLIC = 1'b1; - if (HALTSample2) - begin - CpuState_nxt = CPUSTATE_HALT_EXIT2; - end - end - - - CPUSTATE_HALT_EXIT2: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_FETCH_I1; - end - - CPUSTATE_STOP: - begin - addr_nxt = 16'HDEAD; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_STOP2; - end - - CPUSTATE_STOP2: - begin - addr_nxt = pc; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_STOP3; - end - - CPUSTATE_STOP3: - begin - addr_nxt = 16'H0000; //{Inst1, Inst2}; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_STOP; - end - - // The otherwise critically useful Figure 18 in the 6809 datasheet contains an error; - // it lists that CWAI has a tri-stated bus while it waits for an interrupt. - // That is not true. SYNC tristates the bus, as do things like /HALT and /DMABREQ. - // CWAI does not. It waits with /VMA cycles on the bus until an interrupt occurs. - // The implementation here fits with the 6809 Programming Manual and other Motorola - // sources, not with that typo in Figure 18. - CPUSTATE_CWAI: - begin - addr_nxt = pc; - cc_nxt = {1'b1, (cc[6:0] & Inst2[6:0])}; // Set E flag, AND CC with CWAI argument - tmp_nxt = 16'H00FF; // Save to the S stack, PC, U, Y, X, DP, B, A, CC - - NextState_nxt = CPUSTATE_CWAI_POST; - rAVMA = 1'b0; - CpuState_nxt = CPUSTATE_CWAI_DONTCARE1; - end - - CPUSTATE_CWAI_DONTCARE1: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b1; - CpuState_nxt = CPUSTATE_PSH_ACTION; - end - - CPUSTATE_CWAI_POST: - begin - addr_nxt = 16'HFFFF; - rAVMA = 1'b0; - - CpuState_nxt = CPUSTATE_CWAI_POST; - - // Wait for an interrupt - if (NMILatched == 0) - begin - rAVMA = 1'b1; - IntType_nxt = INTTYPE_NMI; - cc_nxt[CC_F_BIT] = 1'b1; - cc_nxt[CC_I_BIT] = 1'b1; - CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; - end - else if ((FIRQLatched == 0) && (cc[CC_F_BIT] == 0)) - begin - rAVMA = 1'b1; - cc_nxt[CC_F_BIT] = 1'b1; - cc_nxt[CC_I_BIT] = 1'b1; - IntType_nxt = INTTYPE_FIRQ; - CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; - end - else if ((IRQLatched == 0) && (cc[CC_I_BIT] == 0)) - begin - rAVMA = 1'b1; - cc_nxt[CC_I_BIT] = 1'b1; - IntType_nxt = INTTYPE_IRQ; - CpuState_nxt = CPUSTATE_IRQ_VECTOR_HI; - end - end - - default: // Picky darned Verilog. - begin - CpuState_nxt = PostIllegalState; - end - - endcase -end - -endmodule - diff --git a/Arcade_MiST/Namco Mappy Hardware/rtl/mems.v b/Arcade_MiST/Namco Mappy Hardware/rtl/mems.v deleted file mode 100644 index ccde3726..00000000 --- a/Arcade_MiST/Namco Mappy Hardware/rtl/mems.v +++ /dev/null @@ -1,102 +0,0 @@ -module mems -( - input CPUCLKx2, - output [14:0] rom_addr, - input [7:0] rom_data, - input [15:0] MCPU_ADRS, - input MCPU_VMA, - input MCPU_WE, - input [7:0] MCPU_DO, - output [7:0] MCPU_DI, - output IO_CS, - input [7:0] IO_O, - - input [15:0] SCPU_ADRS, - input SCPU_VMA, - input SCPU_WE, - input [7:0] SCPU_DO, - output [7:0] SCPU_DI, - output SCPU_WSG_WE, - - input VCLKx4, - input [10:0] vram_a, - output [15:0] vram_d, - input [6:0] spra_a, - output [23:0] spra_d, - - - input ROMCL, // Downloaded ROM image - input [16:0] ROMAD, - input [7:0] ROMDT, - input ROMEN -); - -//wire [7:0] mrom_d; -wire [7:0] srom_d; -assign rom_addr = MCPU_ADRS[14:0]; -//assign mrom_d = rom_data; - -scpui_rom scpui_rom( - .clk(CPUCLKx2), - .addr(SCPU_ADRS[12:0]), - .data(srom_d) -); - - -wire mram_cs0 = ( MCPU_ADRS[15:11] == 5'b00000 ) & MCPU_VMA; // $0000-$07FF -wire mram_cs1 = ( MCPU_ADRS[15:11] == 5'b00001 ) & MCPU_VMA; // $0800-$0FFF -wire mram_cs2 = ( MCPU_ADRS[15:11] == 5'b00010 ) & MCPU_VMA; // $1000-$17FF -wire mram_cs3 = ( MCPU_ADRS[15:11] == 5'b00011 ) & MCPU_VMA; // $1800-$1FFF -wire mram_cs4 = ( MCPU_ADRS[15:11] == 5'b00100 ) & MCPU_VMA; // $2000-$27FF -wire mram_cs5 = ( MCPU_ADRS[15:10] == 6'b010000 ) & MCPU_VMA; // $4000-$43FF -assign IO_CS = ( MCPU_ADRS[15:11] == 5'b01001 ) & MCPU_VMA; // $4800-$4FFF -wire mrom_cs = ( MCPU_ADRS[15] ) & MCPU_VMA; // $8000-$FFFF - -wire mram_w0 = ( mram_cs0 & MCPU_WE ); -wire mram_w1 = ( mram_cs1 & MCPU_WE ); -wire mram_w2 = ( mram_cs2 & MCPU_WE ); -wire mram_w3 = ( mram_cs3 & MCPU_WE ); -wire mram_w4 = ( mram_cs4 & MCPU_WE ); -wire mram_w5 = ( mram_cs5 & MCPU_WE ); - -wire [7:0] mram_o0, mram_o1, mram_o2, mram_o3, mram_o4, mram_o5; - -assign MCPU_DI = mram_cs0 ? mram_o0 : - mram_cs1 ? mram_o1 : - mram_cs2 ? mram_o2 : - mram_cs3 ? mram_o3 : - mram_cs4 ? mram_o4 : - mram_cs5 ? mram_o5 : - mrom_cs ? rom_data ://mrom_d : - IO_CS ? IO_O : - 8'h0; - -wire [10:0] mram_ad = MCPU_ADRS[10:0]; - -DPRAM_2048V main_ram0( CPUCLKx2, mram_ad, MCPU_DO, mram_o0, mram_w0, VCLKx4, vram_a, vram_d[7:0] ); -DPRAM_2048V main_ram1( CPUCLKx2, mram_ad, MCPU_DO, mram_o1, mram_w1, VCLKx4, vram_a, vram_d[15:8] ); - -DPRAM_2048V main_ram2( CPUCLKx2, mram_ad, MCPU_DO, mram_o2, mram_w2, VCLKx4, { 4'b1111, spra_a }, spra_d[7:0] ); -DPRAM_2048V main_ram3( CPUCLKx2, mram_ad, MCPU_DO, mram_o3, mram_w3, VCLKx4, { 4'b1111, spra_a }, spra_d[15:8] ); -DPRAM_2048V main_ram4( CPUCLKx2, mram_ad, MCPU_DO, mram_o4, mram_w4, VCLKx4, { 4'b1111, spra_a }, spra_d[23:16] ); - - - // (SCPU ADRS) -wire SCPU_CS_SREG = ( ( SCPU_ADRS[15:13] == 3'b000 ) & ( SCPU_ADRS[9:6] == 4'b0000 ) ) & SCPU_VMA; -wire srom_cs = ( SCPU_ADRS[15:13] == 3'b111 ) & SCPU_VMA; // $E000-$FFFF -wire sram_cs0 = (~SCPU_CS_SREG) & (~srom_cs) & SCPU_VMA; // $0000-$03FF -wire [7:0] sram_o0; - -assign SCPU_DI = sram_cs0 ? sram_o0 : - srom_cs ? srom_d : - 8'h0; - -assign SCPU_WSG_WE = SCPU_CS_SREG & SCPU_WE; - -DPRAM_2048 share_ram -( - CPUCLKx2, mram_ad, MCPU_DO, mram_o5, mram_w5, - CPUCLKx2, { 1'b0, SCPU_ADRS[9:0] }, SCPU_DO, sram_o0, sram_cs0 & SCPU_WE -); - -endmodule \ No newline at end of file diff --git a/Arcade_MiST/Namco Mappy Hardware/rtl/regs.v b/Arcade_MiST/Namco Mappy Hardware/rtl/regs.v deleted file mode 100644 index b7e11f62..00000000 --- a/Arcade_MiST/Namco Mappy Hardware/rtl/regs.v +++ /dev/null @@ -1,110 +0,0 @@ -module regs -( - input MCPU_CLK, - input RESET, - input VBLANK, - - input [15:0] MCPU_ADRS, - input MCPU_VMA, - input MCPU_WE, - - input [15:0] SCPU_ADRS, - input SCPU_VMA, - input SCPU_WE, - - output reg [7:0] SCROLL, - output MCPU_IRQ, - output reg MCPU_IRQEN, - output SCPU_IRQ, - output reg SCPU_IRQEN, - output SCPU_RESET, - output IO_RESET, - output reg PSG_ENABLE -); - -// BG Scroll Register -wire MCPU_SCRWE = ( ( MCPU_ADRS[15:11] == 5'b00111 ) & MCPU_VMA & MCPU_WE ); -always @ ( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) SCROLL <= 8'h0; - else if ( MCPU_SCRWE ) SCROLL <= MCPU_ADRS[10:3]; -end - -// MainCPU IRQ Generator -wire MCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000001 ) & MCPU_VMA & MCPU_WE ); -//wire MCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000001 ) & SCPU_VMA & SCPU_WE ); -assign MCPU_IRQ = MCPU_IRQEN & VBLANK; - -always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - MCPU_IRQEN <= 1'b0; - end - else begin - if ( MCPU_IRQWE ) MCPU_IRQEN <= MCPU_ADRS[0]; -// if ( MCPU_IRQWES ) MCPU_IRQEN <= SCPU_ADRS[0]; - end -end - - -// SubCPU IRQ Generator -wire SCPU_IRQWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000000 ) & MCPU_VMA & MCPU_WE ); -wire SCPU_IRQWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000000 ) & SCPU_VMA & SCPU_WE ); -assign SCPU_IRQ = SCPU_IRQEN & VBLANK; - -always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - SCPU_IRQEN <= 1'b0; - end - else begin - if ( SCPU_IRQWE ) SCPU_IRQEN <= MCPU_ADRS[0]; - if ( SCPU_IRQWES ) SCPU_IRQEN <= SCPU_ADRS[0]; - end -end - - -// SubCPU RESET Control -reg SCPU_RSTf = 1'b0; -wire SCPU_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000101 ) & MCPU_VMA & MCPU_WE ); -wire SCPU_RSTWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000101 ) & SCPU_VMA & SCPU_WE ); -assign SCPU_RESET = ~SCPU_RSTf; - -always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - SCPU_RSTf <= 1'b0; - end - else begin - if ( SCPU_RSTWE ) SCPU_RSTf <= MCPU_ADRS[0]; - if ( SCPU_RSTWES ) SCPU_RSTf <= SCPU_ADRS[0]; - end -end - - -// I/O CHIP RESET Control -reg IOCHIP_RSTf = 1'b0; -wire IOCHIP_RSTWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000100 ) & MCPU_VMA & MCPU_WE ); -assign IO_RESET = ~IOCHIP_RSTf; - -always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - IOCHIP_RSTf <= 1'b0; - end - else begin - if ( IOCHIP_RSTWE ) IOCHIP_RSTf <= MCPU_ADRS[0]; - end -end - - -// Sound Enable Control -wire PSG_ENAWE = ( ( MCPU_ADRS[15:1] == 15'b010100000000011 ) & MCPU_VMA & MCPU_WE ); -wire PSG_ENAWES = ( ( SCPU_ADRS[15:1] == 15'b001000000000011 ) & SCPU_VMA & SCPU_WE ); - -always @( negedge MCPU_CLK or posedge RESET ) begin - if ( RESET ) begin - PSG_ENABLE <= 1'b0; - end - else begin - if ( PSG_ENAWE ) PSG_ENABLE <= MCPU_ADRS[0]; - if ( PSG_ENAWES ) PSG_ENABLE <= SCPU_ADRS[0]; - end -end - -endmodule \ No newline at end of file