Line 1... |
Line 1... |
`timescale 1ns / 1ps
|
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
// Company: //
|
// Company: //
|
// Engineer: Scott Moore //
|
// Engineer: Scott Moore //
|
// //
|
// //
|
|
// Additional contributions by: //
|
|
// //
|
|
// Chris N. Strahm - Modifications for Altera Quartus build. //
|
|
// //
|
// Create Date: 11:45:32 09/04/2006 //
|
// Create Date: 11:45:32 09/04/2006 //
|
// Design Name: //
|
// Design Name: //
|
// Module Name: cpu8080 //
|
// Module Name: cpu8080 //
|
// Project Name: cpu8080 //
|
// Project Name: cpu8080 //
|
// Target Devices: xc3c200, xc3s1000 //
|
// Target Devices: xc3c200, xc3s1000 //
|
Line 65... |
Line 68... |
// Revision 0.01 - File Created //
|
// Revision 0.01 - File Created //
|
// Additional Comments: //
|
// Additional Comments: //
|
// //
|
// //
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
`timescale 1ns / 1ps
|
|
|
|
//
|
|
// Build option
|
|
//
|
|
// Uncomment this line to build without wait state ability. Many FPGA
|
|
// applications don't require wait states. This can save silicon area.
|
|
//
|
|
// Defining this option will cause the wait line to be ignored.
|
|
//
|
|
// `define NOWAIT
|
|
|
|
//
|
|
// Build option
|
|
//
|
|
// Uncomment this line to build without I/O instruction ability. An application
|
|
// may have memory mapped I/O only, and not require I/O instructions. This can
|
|
// save silicon area.
|
|
//
|
|
// Defining this option will cause I/O instructions to be treated as no-ops.
|
|
// alternately, you can modify what they do.
|
|
//
|
|
// `define NOIO
|
|
|
//
|
//
|
// CPU states
|
// CPU states
|
//
|
//
|
|
|
`define cpus_idle 6'h00 // Idle
|
`define cpus_idle 6'h00 // Idle
|
Line 260... |
Line 287... |
writemem <= 0;
|
writemem <= 0;
|
readio <= 0;
|
readio <= 0;
|
writeio <= 0;
|
writeio <= 0;
|
inta <= 0;
|
inta <= 0;
|
intcyc <= 0;
|
intcyc <= 0;
|
ei <= 1;
|
ei <= 1; // interrupts on by default
|
eienb <= 0;
|
eienb <= 0;
|
|
|
end else case (state)
|
end else case (state)
|
|
|
`cpus_fetchi: begin // start of instruction fetch
|
`cpus_fetchi: begin // start of instruction fetch
|
Line 296... |
Line 323... |
|
|
end
|
end
|
|
|
`cpus_fetchi3: begin // complete instruction memory read
|
`cpus_fetchi3: begin // complete instruction memory read
|
|
|
if (!waitr) begin // no wait selected, otherwise cycle
|
`ifndef NOWAIT
|
|
if (!waitr)
|
|
`endif
|
|
begin // no wait selected, otherwise cycle
|
|
|
opcode <= data; // latch opcode
|
opcode <= data; // latch opcode
|
readmem <= 0; // Deactivate instruction memory read
|
readmem <= 0; // Deactivate instruction memory read
|
inta <= 0; // and interrupt acknowledge
|
inta <= 0; // and interrupt acknowledge
|
state <= `cpus_fetchi4; // next state
|
state <= `cpus_fetchi4; // next state
|
Line 323... |
Line 353... |
6'b000000: begin // NOP
|
6'b000000: begin // NOP
|
|
|
// yes, do nothing
|
// yes, do nothing
|
|
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b110111: begin // STC
|
6'b110111: begin // STC
|
|
|
carry <= 1; // set carry flag
|
carry <= 1; // set carry flag
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b111111: begin // CMC
|
6'b111111: begin // CMC
|
|
|
carry <= ~carry; // complement carry flag
|
carry <= ~carry; // complement carry flag
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b101111: begin // CMA
|
6'b101111: begin // CMA
|
|
|
regfil[`reg_a] <= ~regfil[`reg_a]; // complement accumulator
|
regfil[`reg_a] <= ~regfil[`reg_a]; // complement accumulator
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b100111: begin // DAA
|
6'b100111: begin // DAA
|
|
|
// decimal adjust accumulator, or remove by carry any
|
// decimal adjust accumulator, or remove by carry any
|
// results in nybbles greater than 9
|
// results in nybbles greater than 9
|
|
|
if (regfil[`reg_a][3:0] > 9 || auxcar)
|
if (regfil[`reg_a][3:0] > 9 || auxcar)
|
{ auxcar, regfil[`reg_a] } <= regfil[`reg_a]+6;
|
{ auxcar, regfil[`reg_a] } <= regfil[`reg_a]+8'h06;
|
state <= `cpus_daa; // finish DAA
|
state <= `cpus_daa; // finish DAA
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000100, 6'b001100, 6'b010100, 6'b011100, 6'b100100,
|
6'b000100, 6'b001100, 6'b010100, 6'b011100, 6'b100100,
|
6'b101100, 6'b110100, 6'b111100, 6'b000101, 6'b001101,
|
6'b101100, 6'b110100, 6'b111100, 6'b000101, 6'b001101,
|
Line 380... |
Line 410... |
raddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
|
raddrhold <= regfil[`reg_h]<<8|regfil[`reg_l];
|
statesel <= `mac_indm; // inc/dec m
|
statesel <= `mac_indm; // inc/dec m
|
state <= `cpus_read; // read byte
|
state <= `cpus_read; // read byte
|
|
|
end else state <= `cpus_indcb; // go inr/dcr cycleback
|
end else state <= `cpus_indcb; // go inr/dcr cycleback
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000010, 6'b010010: begin // STAX
|
6'b000010, 6'b010010: begin // STAX
|
|
|
Line 393... |
Line 423... |
waddrhold <= regfil[`reg_d]<<8|regfil[`reg_e];
|
waddrhold <= regfil[`reg_d]<<8|regfil[`reg_e];
|
else // use BC pair
|
else // use BC pair
|
waddrhold <= regfil[`reg_b] << 8|regfil[`reg_c];
|
waddrhold <= regfil[`reg_b] << 8|regfil[`reg_c];
|
statesel <= `mac_writebyte; // write byte
|
statesel <= `mac_writebyte; // write byte
|
state <= `cpus_write;
|
state <= `cpus_write;
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b001010, 6'b011010: begin // LDAX
|
6'b001010, 6'b011010: begin // LDAX
|
|
|
Line 406... |
Line 436... |
raddrhold <= regfil[`reg_d]<<8|regfil[`reg_e];
|
raddrhold <= regfil[`reg_d]<<8|regfil[`reg_e];
|
else // use BC pair
|
else // use BC pair
|
raddrhold <= regfil[`reg_b]<<8|regfil[`reg_c];
|
raddrhold <= regfil[`reg_b]<<8|regfil[`reg_c];
|
statesel <= `mac_readbtoreg; // read byte to register
|
statesel <= `mac_readbtoreg; // read byte to register
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000111: begin // RLC
|
6'b000111: begin // RLC
|
|
|
// rotate left circular
|
// rotate left circular
|
{ carry, regfil[`reg_a] } <=
|
{ carry, regfil[`reg_a] } <=
|
(regfil[`reg_a] << 1)+regfil[`reg_a][7];
|
(regfil[`reg_a] << 1)+regfil[`reg_a][7];
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b010111: begin // RAL
|
6'b010111: begin // RAL
|
|
|
// rotate left through carry
|
// rotate left through carry
|
{ carry, regfil[`reg_a] } <= (regfil[`reg_a] << 1)+carry;
|
{ carry, regfil[`reg_a] } <= (regfil[`reg_a] << 1)+carry;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b001111: begin // RRC
|
6'b001111: begin // RRC
|
|
|
// rotate right circular
|
// rotate right circular
|
regfil[`reg_a] <=
|
regfil[`reg_a] <=
|
(regfil[`reg_a] >> 1)+(regfil[`reg_a][0] << 7);
|
(regfil[`reg_a] >> 1)+(regfil[`reg_a][0] << 7);
|
carry <= regfil[`reg_a][0];
|
carry <= regfil[`reg_a][0];
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b011111: begin // RAR
|
6'b011111: begin // RAR
|
|
|
// rotate right through carry
|
// rotate right through carry
|
regfil[`reg_a] <= (regfil[`reg_a] >> 1)+(carry << 7);
|
regfil[`reg_a] <= (regfil[`reg_a] >> 1)+(carry << 7);
|
carry <= regfil[`reg_a][0];
|
carry <= regfil[`reg_a][0];
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b001001: begin // DAD B
|
6'b001001: begin // DAD B
|
|
|
// add BC to HL
|
// add BC to HL
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+
|
(regfil[`reg_b] << 8)+regfil[`reg_c];
|
(regfil[`reg_b] << 8)+regfil[`reg_c];
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b011001: begin // DAD D
|
6'b011001: begin // DAD D
|
|
|
// add DE to HL
|
// add DE to HL
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+
|
(regfil[`reg_d] << 8)+regfil[`reg_e];
|
(regfil[`reg_d] << 8)+regfil[`reg_e];
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b101001: begin // DAD H
|
6'b101001: begin // DAD H
|
|
|
// add HL to HL
|
// add HL to HL
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+
|
(regfil[`reg_h] << 8)+regfil[`reg_l];
|
(regfil[`reg_h] << 8)+regfil[`reg_l];
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b111001: begin // DAD SP
|
6'b111001: begin // DAD SP
|
|
|
// add SP to HL
|
// add SP to HL
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
{ carry, regfil[`reg_h], regfil[`reg_l] } <=
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+sp;
|
(regfil[`reg_h] << 8)+regfil[`reg_l]+sp;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000011: begin // INX B
|
6'b000011: begin // INX B
|
|
|
// increment BC, no flags set
|
// increment BC, no flags set
|
regfil[`reg_b] <=
|
regfil[`reg_b] <=
|
(((regfil[`reg_b] << 8)+regfil[`reg_c])+1)>>8;
|
(((regfil[`reg_b] << 8)+regfil[`reg_c])+16'h1)>>8;
|
regfil[`reg_c] <=
|
regfil[`reg_c] <=
|
((regfil[`reg_b] << 8)+regfil[`reg_c])+1;
|
((regfil[`reg_b] << 8)+regfil[`reg_c])+16'h1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b010011: begin // INX D
|
6'b010011: begin // INX D
|
|
|
// increment DE, no flags set
|
// increment DE, no flags set
|
regfil[`reg_d] <=
|
regfil[`reg_d] <=
|
(((regfil[`reg_d] << 8)+regfil[`reg_e])+1)>>8;
|
(((regfil[`reg_d] << 8)+regfil[`reg_e])+16'h1)>>8;
|
regfil[`reg_e] <=
|
regfil[`reg_e] <=
|
((regfil[`reg_d] << 8)+regfil[`reg_e])+1;
|
((regfil[`reg_d] << 8)+regfil[`reg_e])+16'h1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b100011: begin // INX H
|
6'b100011: begin // INX H
|
|
|
// increment HL, no flags set
|
// increment HL, no flags set
|
regfil[`reg_h] <=
|
regfil[`reg_h] <=
|
(((regfil[`reg_h] << 8)+regfil[`reg_l])+1)>>8;
|
(((regfil[`reg_h] << 8)+regfil[`reg_l])+16'h1)>>8;
|
regfil[`reg_l] <=
|
regfil[`reg_l] <=
|
((regfil[`reg_h] << 8)+regfil[`reg_l])+1;
|
((regfil[`reg_h] << 8)+regfil[`reg_l])+16'h1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b110011: begin // INX SP
|
6'b110011: begin // INX SP
|
|
|
// increment SP, no flags set
|
// increment SP, no flags set
|
sp <= sp+1;
|
sp <= sp + 16'b1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b001011: begin // DCX B
|
6'b001011: begin // DCX B
|
|
|
// decrement BC, no flags set
|
// decrement BC, no flags set
|
regfil[`reg_b] <=
|
regfil[`reg_b] <=
|
(((regfil[`reg_b] << 8)+regfil[`reg_c])-1)>>8;
|
(((regfil[`reg_b] << 8)+regfil[`reg_c])-16'h1)>>8;
|
regfil[`reg_c] <=
|
regfil[`reg_c] <=
|
((regfil[`reg_b] << 8)+regfil[`reg_c])-1;
|
((regfil[`reg_b] << 8)+regfil[`reg_c])-16'h1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b011011: begin // DCX D
|
6'b011011: begin // DCX D
|
|
|
// decrement DE, no flags set
|
// decrement DE, no flags set
|
regfil[`reg_d] <=
|
regfil[`reg_d] <=
|
(((regfil[`reg_d] << 8)+regfil[`reg_e])-1)>>8;
|
(((regfil[`reg_d] << 8)+regfil[`reg_e])-16'h1)>>8;
|
regfil[`reg_e] <=
|
regfil[`reg_e] <=
|
((regfil[`reg_d] << 8)+regfil[`reg_e])-1;
|
((regfil[`reg_d] << 8)+regfil[`reg_e])-16'h1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b101011: begin // DCX H
|
6'b101011: begin // DCX H
|
|
|
// decrement HL, no flags set
|
// decrement HL, no flags set
|
regfil[`reg_h] <=
|
regfil[`reg_h] <=
|
(((regfil[`reg_h] << 8)+regfil[`reg_l])-1)>>8;
|
(((regfil[`reg_h] << 8)+regfil[`reg_l])-16'h1)>>8;
|
regfil[`reg_l] <=
|
regfil[`reg_l] <=
|
((regfil[`reg_h] << 8)+regfil[`reg_l])-1;
|
((regfil[`reg_h] << 8)+regfil[`reg_l])-16'h1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+1'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b111011: begin // DCX SP
|
6'b111011: begin // DCX SP
|
|
|
// decrement SP, no flags set
|
// decrement SP, no flags set
|
sp <= sp-1;
|
sp <= sp-16'b1;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000001: begin // LXI B
|
6'b000001: begin // LXI B
|
|
|
raddrhold <= pc+1; // pick up after instruction
|
raddrhold <= pc+16'h1; // pick up after instruction
|
statesel <= `mac_readdtobc; // read double to BC
|
statesel <= `mac_readdtobc; // read double to BC
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // skip
|
pc <= pc+16'h3; // skip
|
|
|
end
|
end
|
|
|
6'b010001: begin // LXI D
|
6'b010001: begin // LXI D
|
|
|
raddrhold <= pc+1; // pick up after instruction
|
raddrhold <= pc+16'h1; // pick up after instruction
|
statesel <= `mac_readdtode; // read double to DE
|
statesel <= `mac_readdtode; // read double to DE
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // skip
|
pc <= pc+16'h3; // skip
|
|
|
end
|
end
|
|
|
6'b100001: begin // LXI H
|
6'b100001: begin // LXI H
|
|
|
raddrhold <= pc+1; // pick up after instruction
|
raddrhold <= pc+16'h1; // pick up after instruction
|
statesel <= `mac_readdtohl; // read double to HL
|
statesel <= `mac_readdtohl; // read double to HL
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // skip
|
pc <= pc+16'h3; // skip
|
|
|
end
|
end
|
|
|
6'b110001: begin // LXI SP
|
6'b110001: begin // LXI SP
|
|
|
raddrhold <= pc+1; // pick up after instruction
|
raddrhold <= pc+16'h1; // pick up after instruction
|
pc <= pc+3; // skip
|
|
statesel <= `mac_readdtosp; // read double to SP
|
statesel <= `mac_readdtosp; // read double to SP
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // skip
|
pc <= pc+16'h3; // skip
|
|
|
end
|
end
|
|
|
6'b000110, 6'b001110, 6'b010110, 6'b011110, 6'b100110,
|
6'b000110, 6'b001110, 6'b010110, 6'b011110, 6'b100110,
|
6'b101110, 6'b110110, 6'b111110: begin // MVI
|
6'b101110, 6'b110110, 6'b111110: begin // MVI
|
|
|
// move immediate to register
|
// move immediate to register
|
regd <= opcode[5:3]; // set destination register
|
regd <= opcode[5:3]; // set destination register
|
raddrhold <= pc+1; // set pickup address
|
raddrhold <= pc+16'h1; // set pickup address
|
if (opcode[5:3] == `reg_m) begin // it's mvi m,imm
|
if (opcode[5:3] == `reg_m) begin // it's mvi m,imm
|
|
|
regd <= opcode[5:3]; // set destination register
|
regd <= opcode[5:3]; // set destination register
|
// set destination address
|
// set destination address
|
waddrhold <= { regfil[`reg_h], regfil[`reg_l] };
|
waddrhold <= { regfil[`reg_h], regfil[`reg_l] };
|
statesel <= `mac_readbmtw; // read byte and move to write
|
statesel <= `mac_readbmtw; // read byte and move to write
|
|
|
end else
|
end else
|
statesel <= `mac_readbmtr; // read byte and move to register
|
statesel <= `mac_readbmtr; // read byte and move to register
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+2; // advance over byte
|
pc <= pc+16'h2; // advance over byte
|
|
|
end
|
end
|
|
|
6'b110010: begin // STA
|
6'b110010: begin // STA
|
|
|
wdatahold <= regfil[`reg_a]; // set write data
|
wdatahold <= regfil[`reg_a]; // set write data
|
raddrhold <= pc+1; // set read address
|
raddrhold <= pc+16'h1; // set read address
|
statesel <= `mac_sta; // perform sta
|
statesel <= `mac_sta; // perform sta
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // next
|
pc <= pc + 16'h3; // next
|
|
|
end
|
end
|
|
|
6'b111010: begin // LDA
|
6'b111010: begin // LDA
|
|
|
raddrhold <= pc+1; // set read address
|
raddrhold <= pc+16'h1; // set read address
|
regd <= `reg_a; // set destination
|
regd <= `reg_a; // set destination
|
statesel <= `mac_lda; // perform lda
|
statesel <= `mac_lda; // perform lda
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // next
|
pc <= pc+16'h3; // next
|
|
|
end
|
end
|
|
|
6'b100010: begin // SHLD
|
6'b100010: begin // SHLD
|
|
|
wdatahold <= regfil[`reg_l]; // set write data
|
wdatahold <= regfil[`reg_l]; // set write data
|
wdatahold2 <= regfil[`reg_h];
|
wdatahold2 <= regfil[`reg_h];
|
raddrhold <= pc+1; // set read address
|
raddrhold <= pc+16'h1; // set read address
|
statesel <= `mac_shld; // perform SHLD
|
statesel <= `mac_shld; // perform SHLD
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // next
|
pc <= pc+16'h3; // skip
|
|
|
end
|
end
|
|
|
6'b101010: begin // LHLD
|
6'b101010: begin // LHLD
|
|
|
raddrhold <= pc+1; // set read address
|
raddrhold <= pc+16'h1; // set read address
|
statesel <= `mac_lhld; // perform LHLD
|
statesel <= `mac_lhld; // perform LHLD
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+3; // next
|
pc <= pc+16'h3; // skip
|
|
|
end
|
end
|
|
|
// the illegal opcodes behave as NOPs
|
// the illegal opcodes behave as NOPs
|
|
|
6'b001000, 6'b010000, 6'b011000, 6'b100000, 6'b101000,
|
6'b001000, 6'b010000, 6'b011000, 6'b100000, 6'b101000,
|
6'b110000, 6'b110000: begin
|
6'b110000, 6'b110000: begin
|
|
|
state <= `cpus_fetchi; // fetch next instruction
|
state <= `cpus_fetchi; // fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|
Line 731... |
Line 760... |
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
|
|
end
|
end
|
|
|
end
|
end
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
2'b10: begin // 10: Reg or mem to accumulator ops
|
2'b10: begin // 10: Reg or mem to accumulator ops
|
|
|
Line 751... |
Line 780... |
statesel <= `mac_alum; // alu from m
|
statesel <= `mac_alum; // alu from m
|
state <= `cpus_read; // read byte
|
state <= `cpus_read; // read byte
|
|
|
end else
|
end else
|
state <= `cpus_alucb; // go to alu cycleback
|
state <= `cpus_alucb; // go to alu cycleback
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
2'b11: begin // 11: jmp/call and others
|
2'b11: begin // 11: jmp/call and others
|
|
|
case (opcode[5:0]) // decode these instructions
|
case (opcode[5:0]) // decode these instructions
|
|
|
6'b000101, 6'b010101, 6'b100101, 6'b110101: begin // PUSH
|
6'b000101, 6'b010101, 6'b100101, 6'b110101: begin // PUSH
|
|
|
waddrhold <= sp-2; // write to stack
|
waddrhold <= sp-16'h2; // write to stack
|
sp <= sp-2; // pushdown stack
|
sp <= sp-16'h2; // pushdown stack
|
case (opcode[5:4]) // register set
|
case (opcode[5:4]) // register set
|
|
|
2'b00: { wdatahold2, wdatahold } <=
|
2'b00: { wdatahold2, wdatahold } <=
|
{ regfil[`reg_b], regfil[`reg_c] };
|
{ regfil[`reg_b], regfil[`reg_c] };
|
2'b01: { wdatahold2, wdatahold } <=
|
2'b01: { wdatahold2, wdatahold } <=
|
Line 778... |
Line 807... |
1'b0, parity, 1'b1, carry };
|
1'b0, parity, 1'b1, carry };
|
|
|
endcase
|
endcase
|
statesel <= `mac_writedbyte; // write double byte
|
statesel <= `mac_writedbyte; // write double byte
|
state <= `cpus_write;
|
state <= `cpus_write;
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000001, 6'b010001, 6'b100001, 6'b110001: begin // POP
|
6'b000001, 6'b010001, 6'b100001, 6'b110001: begin // POP
|
|
|
popdes <= opcode[5:4]; // set destination
|
popdes <= opcode[5:4]; // set destination
|
raddrhold <= sp; // read from stack
|
raddrhold <= sp; // read from stack
|
sp <= sp+2; // pushup stack
|
sp <= sp+16'h2; // pushup stack
|
statesel <= `mac_pop; // perform POP
|
statesel <= `mac_pop; // perform POP
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b101011: begin // XCHG
|
6'b101011: begin // XCHG
|
|
|
regfil[`reg_d] <= regfil[`reg_h];
|
regfil[`reg_d] <= regfil[`reg_h];
|
regfil[`reg_e] <= regfil[`reg_l];
|
regfil[`reg_e] <= regfil[`reg_l];
|
regfil[`reg_h] <= regfil[`reg_d];
|
regfil[`reg_h] <= regfil[`reg_d];
|
regfil[`reg_l] <= regfil[`reg_e];
|
regfil[`reg_l] <= regfil[`reg_e];
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b100011: begin // XTHL
|
6'b100011: begin // XTHL
|
|
|
Line 812... |
Line 841... |
waddrhold <= sp; // address SP for write
|
waddrhold <= sp; // address SP for write
|
wdatahold <= regfil[`reg_l]; // set data is HL
|
wdatahold <= regfil[`reg_l]; // set data is HL
|
wdatahold2 <= regfil[`reg_h];
|
wdatahold2 <= regfil[`reg_h];
|
statesel <= `mac_xthl; // perform XTHL
|
statesel <= `mac_xthl; // perform XTHL
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b111001: begin // SPHL
|
6'b111001: begin // SPHL
|
|
|
sp <= { regfil[`reg_h], regfil[`reg_l] };
|
sp <= { regfil[`reg_h], regfil[`reg_l] };
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000110, 6'b001110, 6'b010110, 6'b011110, 6'b100110,
|
6'b000110, 6'b001110, 6'b010110, 6'b011110, 6'b100110,
|
6'b101110, 6'b110110,
|
6'b101110, 6'b110110,
|
6'b111110: begin // immediate arithmetic to accumulator
|
6'b111110: begin // immediate arithmetic to accumulator
|
|
|
aluopra <= regfil[`reg_a]; // load as alu a
|
aluopra <= regfil[`reg_a]; // load as alu a
|
alusel <= opcode[5:3]; // set alu operation from instruction
|
alusel <= opcode[5:3]; // set alu operation from instruction
|
alucin <= carry; // input carry
|
alucin <= carry; // input carry
|
raddrhold <= pc+1; // read at PC
|
raddrhold <= pc+16'h1; // read at PC
|
statesel <= `mac_accimm; // finish accumulator immediate
|
statesel <= `mac_accimm; // finish accumulator immediate
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+2; // skip immediate byte
|
pc <= pc+16'h2; // skip immediate byte
|
|
|
end
|
end
|
|
|
6'b101001: begin // PCHL
|
6'b101001: begin // PCHL
|
|
|
Line 847... |
Line 876... |
|
|
end
|
end
|
|
|
6'b000011: begin // JMP
|
6'b000011: begin // JMP
|
|
|
raddrhold <= pc+1; // pick up jump address
|
raddrhold <= pc+16'h1; // pick up jump address
|
statesel <= `mac_jmp; // finish JMP
|
statesel <= `mac_jmp; // finish JMP
|
state <= `cpus_read;
|
state <= `cpus_read;
|
|
|
end
|
end
|
|
|
6'b000010, 6'b001010, 6'b010010, 6'b011010, 6'b100010,
|
6'b000010, 6'b001010, 6'b010010, 6'b011010, 6'b100010,
|
6'b101010, 6'b110010, 6'b111010: begin // Jcc
|
6'b101010, 6'b110010, 6'b111010: begin // Jcc
|
|
|
raddrhold <= pc+1; // pick up jump address
|
raddrhold <= pc+16'h1; // pick up jump address
|
statesel <= `mac_jmp; // finish JMP
|
statesel <= `mac_jmp; // finish JMP
|
// choose continue or read according to condition
|
// choose continue or read according to condition
|
case (opcode[5:3]) // decode flag cases
|
case (opcode[5:3]) // decode flag cases
|
|
|
3'b000: if (zero) state <= `cpus_fetchi;
|
3'b000: if (zero) state <= `cpus_fetchi;
|
Line 879... |
Line 908... |
else state <= `cpus_read;
|
else state <= `cpus_read;
|
3'b111: if (!sign) state <= `cpus_fetchi;
|
3'b111: if (!sign) state <= `cpus_fetchi;
|
else state <= `cpus_read;
|
else state <= `cpus_read;
|
|
|
endcase
|
endcase
|
pc <= pc+3; // advance after jump for false
|
pc <= pc+16'h3; // advance after jump for false
|
|
|
end
|
end
|
|
|
6'b001101: begin // CALL
|
6'b001101: begin // CALL
|
|
|
raddrhold <= pc+1; // pick up call address
|
raddrhold <= pc+16'h1; // pick up call address
|
waddrhold <= sp-2; // place address on stack
|
waddrhold <= sp-16'h2; // place address on stack
|
// if interrupt cycle, use current pc, else use address
|
// if interrupt cycle, use current pc, else use address
|
// after call
|
// after call
|
if (intcyc) { wdatahold2, wdatahold } <= pc;
|
if (intcyc) { wdatahold2, wdatahold } <= pc;
|
else { wdatahold2, wdatahold } <= pc+3;
|
else { wdatahold2, wdatahold } <= pc+16'h3;
|
statesel <= `mac_call; // finish CALL
|
statesel <= `mac_call; // finish CALL
|
state <= `cpus_read;
|
state <= `cpus_read;
|
|
|
end
|
end
|
|
|
6'b000100, 6'b001100, 6'b010100, 6'b011100, 6'b100100,
|
6'b000100, 6'b001100, 6'b010100, 6'b011100, 6'b100100,
|
6'b101100, 6'b110100, 6'b111100: begin // Ccc
|
6'b101100, 6'b110100, 6'b111100: begin // Ccc
|
|
|
raddrhold <= pc+1; // pick up call address
|
raddrhold <= pc+16'h1; // pick up call address
|
waddrhold <= sp-2; // place address on stack
|
waddrhold <= sp-16'h2; // place address on stack
|
{ wdatahold2, wdatahold } <= pc+3; // of address after call
|
// of address after call
|
|
{ wdatahold2, wdatahold } <= pc + 16'h3;
|
statesel <= `mac_call; // finish CALL
|
statesel <= `mac_call; // finish CALL
|
// choose continue or read according to condition
|
// choose continue or read according to condition
|
case (opcode[5:3]) // decode flag cases
|
case (opcode[5:3]) // decode flag cases
|
|
|
3'b000: if (zero) state <= `cpus_fetchi;
|
3'b000: if (zero) state <= `cpus_fetchi;
|
Line 924... |
Line 954... |
else state <= `cpus_read;
|
else state <= `cpus_read;
|
3'b111: if (!sign) state <= `cpus_fetchi;
|
3'b111: if (!sign) state <= `cpus_fetchi;
|
else state <= `cpus_read;
|
else state <= `cpus_read;
|
|
|
endcase
|
endcase
|
pc <= pc+3; // advance after jump for false
|
pc <= pc+16'h3; // advance after jump for false
|
|
|
end
|
end
|
|
|
6'b001001: begin // RET
|
6'b001001: begin // RET
|
|
|
Line 962... |
Line 992... |
else state <= `cpus_read;
|
else state <= `cpus_read;
|
3'b111: if (!sign) state <= `cpus_fetchi;
|
3'b111: if (!sign) state <= `cpus_fetchi;
|
else state <= `cpus_read;
|
else state <= `cpus_read;
|
|
|
endcase
|
endcase
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b000111, 6'b001111, 6'b010111, 6'b011111, 6'b100111,
|
6'b000111, 6'b001111, 6'b010111, 6'b011111, 6'b100111,
|
6'b101111, 6'b110111, 6'b111111: begin // RST
|
6'b101111, 6'b110111, 6'b111111: begin // RST
|
|
|
pc <= opcode & 8'b00111000; // place restart value in PC
|
pc <= opcode & 8'b00111000; // place restart value in PC
|
waddrhold <= sp-2; // place address on stack
|
waddrhold <= sp-16'h2; // place address on stack
|
// if interrupt cycle, use current pc, else use address
|
// if interrupt cycle, use current pc, else use address
|
// after call
|
// after call
|
if (intcyc) { wdatahold2, wdatahold } <= pc;
|
if (intcyc) { wdatahold2, wdatahold } <= pc;
|
else { wdatahold2, wdatahold } <= pc+3;
|
else { wdatahold2, wdatahold } <= pc+16'h3;
|
{ wdatahold2, wdatahold } <= pc+1; // of address after call
|
{ wdatahold2, wdatahold } <= pc+16'h1; // of address after call
|
sp <= sp-2; // pushdown stack
|
sp <= sp-16'h2; // pushdown stack CNS
|
statesel <= `mac_writedbyte; // finish RST
|
statesel <= `mac_writedbyte; // finish RST
|
state <= `cpus_write; // write to stack
|
state <= `cpus_write; // write to stack
|
|
|
end
|
end
|
|
|
6'b111011: begin // EI
|
6'b111011: begin // EI
|
|
|
eienb <= 1'b1; // set delayed interrupt enable
|
eienb <= 1'b1; // set delayed interrupt enable
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b110011: begin // DI
|
6'b110011: begin // DI
|
|
|
ei <= 1'b0;
|
ei <= 1'b0;
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
pc <= pc+1; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
6'b011011: begin // IN p
|
6'b011011: begin // IN p
|
|
|
|
`ifndef NOIO
|
|
// perform input
|
raddrhold <= pc+1; // pick up byte I/O address
|
raddrhold <= pc+1; // pick up byte I/O address
|
pc <= pc+2; // next
|
|
statesel <= `mac_in; // finish IN
|
statesel <= `mac_in; // finish IN
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+2; // Next instruction byte
|
pc <= pc+16'h2; // advance over byte
|
|
`else
|
|
// ignore instruction
|
|
state <= `cpus_fetchi; // fetch next instruction
|
|
pc <= pc+16'h1; // Next instruction byte
|
|
`endif
|
|
|
end
|
end
|
|
|
6'b010011: begin // OUT p
|
6'b010011: begin // OUT p
|
|
|
|
`ifndef NOIO
|
|
// perform output
|
raddrhold <= pc+1; // pick up byte I/O address
|
raddrhold <= pc+1; // pick up byte I/O address
|
pc <= pc+2; // next
|
|
statesel <= `mac_out; // finish OUT
|
statesel <= `mac_out; // finish OUT
|
state <= `cpus_read;
|
state <= `cpus_read;
|
pc <= pc+2; // Next instruction byte
|
pc <= pc+16'h2; // advance over byte
|
|
`else
|
|
// ignore instruction
|
|
state <= `cpus_fetchi; // fetch next instruction
|
|
pc <= pc+16'h1; // Next instruction byte
|
|
`endif
|
|
|
end
|
end
|
|
|
// the illegal opcodes behave as NOPs
|
// the illegal opcodes behave as NOPs
|
|
|
6'b001011, 6'b011001, 6'b011101, 6'b101101,
|
6'b001011, 6'b011001, 6'b011101, 6'b101101,
|
6'b111101: begin
|
6'b111101: begin
|
|
|
state <= `cpus_fetchi; // fetch next instruction
|
state <= `cpus_fetchi; // fetch next instruction
|
pc <= pc+2; // Next instruction byte
|
pc <= pc+16'h1; // Next instruction byte
|
|
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|
Line 1046... |
Line 1088... |
//
|
//
|
|
|
`cpus_write: begin
|
`cpus_write: begin
|
|
|
addr <= waddrhold; // place address on output
|
addr <= waddrhold; // place address on output
|
waddrhold <= waddrhold+1; // next address
|
waddrhold <= waddrhold + 1'b1; // next address
|
datao <= wdatahold; // set data to output
|
datao <= wdatahold; // set data to output
|
wdatahold <= wdatahold2; // next data
|
wdatahold <= wdatahold2; // next data
|
dataeno <= 1; // enable output data
|
dataeno <= 1; // enable output data
|
state <= `cpus_write2; // next state
|
state <= `cpus_write2; // next state
|
|
|
Line 1063... |
Line 1105... |
|
|
end
|
end
|
|
|
`cpus_write3: begin // continue write #3
|
`cpus_write3: begin // continue write #3
|
|
|
if (!waitr) begin // no wait selected, otherwise cycle
|
`ifndef NOWAIT
|
|
if (!waitr)
|
|
`endif
|
|
begin // no wait selected, otherwise cycle
|
|
|
writemem <= 0; // disable write memory data
|
writemem <= 0; // disable write memory data
|
state <= `cpus_write4; // idle hold time
|
state <= `cpus_write4; // idle hold time
|
|
|
end
|
end
|
Line 1076... |
Line 1121... |
|
|
`cpus_write4: begin // continue write #4
|
`cpus_write4: begin // continue write #4
|
|
|
dataeno <= 0; // disable output data
|
dataeno <= 0; // disable output data
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
//
|
//
|
// single byte read, reads rdatahold from the raddrhold address
|
// single byte read, reads rdatahold from the raddrhold address
|
//
|
//
|
|
|
`cpus_read: begin
|
`cpus_read: begin
|
|
|
addr <= raddrhold; // place address on output
|
addr <= raddrhold; // place address on output
|
raddrhold <= raddrhold+1; // next address
|
raddrhold <= raddrhold + 16'h1; // next address
|
if (intcyc) inta <= 1; // activate interrupt acknowledge
|
if (intcyc) inta <= 1; // activate interrupt acknowledge
|
else readmem <= 1; // activate memory read
|
else readmem <= 1; // activate memory read
|
state <= `cpus_read2; // next state
|
state <= `cpus_read2; // next state
|
|
|
end
|
end
|
Line 1103... |
Line 1148... |
|
|
end
|
end
|
|
|
`cpus_read3: begin // continue read #3
|
`cpus_read3: begin // continue read #3
|
|
|
if (!waitr) begin // no wait selected, otherwise cycle
|
`ifndef NOWAIT
|
|
if (!waitr)
|
|
`endif
|
|
begin // no wait selected, otherwise cycle
|
|
|
rdatahold2 <= rdatahold; // shift data
|
rdatahold2 <= rdatahold; // shift data
|
rdatahold <= data; // read new data
|
rdatahold <= data; // read new data
|
readmem <= 0; // deactivate instruction memory read
|
readmem <= 0; // deactivate instruction memory read
|
inta <= 0; // deactivate interrupt acknowledge
|
inta <= 0; // deactivate interrupt acknowledge
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
end
|
end
|
|
|
Line 1129... |
Line 1177... |
2'b10: { regfil[`reg_h], regfil[`reg_l] } <=
|
2'b10: { regfil[`reg_h], regfil[`reg_l] } <=
|
{ rdatahold, rdatahold2 };
|
{ rdatahold, rdatahold2 };
|
2'b11: begin
|
2'b11: begin
|
|
|
regfil[`reg_a] <= rdatahold;
|
regfil[`reg_a] <= rdatahold;
|
sign <= rdatahold2 >> 7&1;
|
sign <= ((rdatahold2 >> 7)& 1'b1) ? 1'b1:1'b0;
|
zero <= rdatahold2 >> 6&1;
|
zero <= ((rdatahold2 >> 6)& 1'b1) ? 1'b1:1'b0;
|
auxcar <= rdatahold2 >> 4&1;
|
auxcar <= ((rdatahold2 >> 4)& 1'b1) ? 1'b1:1'b0;
|
parity <= rdatahold2 >> 2&1;
|
parity <= ((rdatahold2 >> 2)& 1'b1) ? 1'b1:1'b0;
|
carry <= rdatahold2 >> 0&1;
|
carry <= ((rdatahold2 >> 0)& 1'b1) ? 1'b1:1'b0;
|
|
|
end
|
end
|
|
|
endcase
|
endcase
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
Line 1151... |
Line 1199... |
|
|
end
|
end
|
|
|
`cpus_call: begin // call address
|
`cpus_call: begin // call address
|
|
|
sp <= sp-2; // pushdown stack
|
sp <= sp-16'h2; // pushdown stack
|
state <= `cpus_fetchi; // and return to instruction fetch
|
state <= `cpus_fetchi; // and return to instruction fetch
|
pc <= { rdatahold, rdatahold2 };
|
pc <= { rdatahold, rdatahold2 };
|
|
|
end
|
end
|
|
|
`cpus_ret: begin // return from call
|
`cpus_ret: begin // return from call
|
|
|
sp <= sp+2; // pushup stack
|
sp <= sp+16'h2; // pushup stack
|
state <= `cpus_fetchi; // and return to instruction fetch
|
state <= `cpus_fetchi; // and return to instruction fetch
|
pc <= { rdatahold, rdatahold2 };
|
pc <= { rdatahold, rdatahold2 };
|
|
|
end
|
end
|
|
|
|
`ifndef NOIO // if I/O instructions are to be included
|
`cpus_in: begin // input single byte to A
|
`cpus_in: begin // input single byte to A
|
|
|
addr <= rdatahold; // place I/O address on address lines
|
addr <= rdatahold; // place I/O address on address lines
|
readio <= 1; // set read I/O
|
readio <= 1; // set read I/O
|
state <= `cpus_in2; // continue
|
state <= `cpus_in2; // continue
|
Line 1182... |
Line 1231... |
|
|
end
|
end
|
|
|
`cpus_in3: begin // input single byte to A #3
|
`cpus_in3: begin // input single byte to A #3
|
|
|
if (!waitr) begin // no wait selected, otherwise cycle
|
`ifndef NOWAIT
|
|
if (!waitr)
|
|
`endif
|
|
begin // no wait selected, otherwise cycle
|
|
|
regfil[`reg_a] <= data; // place input data
|
regfil[`reg_a] <= data; // place input data
|
readio <= 0; // clear read I/O
|
readio <= 0; // clear read I/O
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
|
|
Line 1210... |
Line 1262... |
|
|
end
|
end
|
|
|
`cpus_out3: begin // continue out #3
|
`cpus_out3: begin // continue out #3
|
|
|
if (!waitr) begin // no wait selected, otherwise cycle
|
`ifndef NOWAIT
|
|
if (!waitr)
|
|
`endif
|
|
begin // no wait selected, otherwise cycle
|
|
|
writeio <= 0; // disable write I/O data
|
writeio <= 0; // disable write I/O data
|
state <= `cpus_out4; // idle hold time
|
state <= `cpus_out4; // idle hold time
|
|
|
end
|
end
|
Line 1225... |
Line 1280... |
|
|
dataeno <= 0; // disable output data
|
dataeno <= 0; // disable output data
|
state <= `cpus_fetchi; // Fetch next instruction
|
state <= `cpus_fetchi; // Fetch next instruction
|
|
|
end
|
end
|
|
`endif
|
|
|
`cpus_halt: begin // Halt waiting for interrupt
|
`cpus_halt: begin // Halt waiting for interrupt
|
|
|
// If there is an interrupt request and interrupts are enabled, then we
|
// If there is an interrupt request and interrupts are enabled, then we
|
// can leave halt. Otherwise we stay here.
|
// can leave halt. Otherwise we stay here.
|
Line 1239... |
Line 1295... |
|
|
`cpus_movtr: begin // move to register
|
`cpus_movtr: begin // move to register
|
|
|
regfil[regd] <= rdatahold; // place data
|
regfil[regd] <= rdatahold; // place data
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
`cpus_movtalua: begin // move to alu a
|
`cpus_movtalua: begin // move to alu a
|
|
|
aluopra <= rdatahold; // place data
|
aluopra <= rdatahold; // place data
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
`cpus_movtalub: begin // move to alu b
|
`cpus_movtalub: begin // move to alu b
|
|
|
aluoprb <= rdatahold; // place data
|
aluoprb <= rdatahold; // place data
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
`cpus_alucb: begin // alu cycleback
|
`cpus_alucb: begin // alu cycleback
|
|
|
Line 1291... |
Line 1347... |
sign <= alures[7]; // place sign
|
sign <= alures[7]; // place sign
|
zero <= aluzout; // place zero
|
zero <= aluzout; // place zero
|
parity <= alupar; // place parity
|
parity <= alupar; // place parity
|
auxcar <= aluaxc; // place auxiliary carry
|
auxcar <= aluaxc; // place auxiliary carry
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
`cpus_movmtbc: begin // finish LXI B
|
`cpus_movmtbc: begin // finish LXI B
|
|
|
Line 1330... |
Line 1386... |
|
|
`cpus_movrtw: begin // move read to write
|
`cpus_movrtw: begin // move read to write
|
|
|
wdatahold <= rdatahold; // move read to write data
|
wdatahold <= rdatahold; // move read to write data
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
`cpus_movrtwa: begin // move read data to write address
|
`cpus_movrtwa: begin // move read data to write address
|
|
|
waddrhold <= { rdatahold, rdatahold2 };
|
waddrhold <= { rdatahold, rdatahold2 };
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
`cpus_movrtra: begin // move read data to read address
|
`cpus_movrtra: begin // move read data to read address
|
|
|
raddrhold <= { rdatahold, rdatahold2 };
|
raddrhold <= { rdatahold, rdatahold2 };
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro
|
|
|
end
|
end
|
|
|
`cpus_lhld: begin // load HL from read data
|
`cpus_lhld: begin // load HL from read data
|
|
|
regfil[`reg_l] <= rdatahold2; // low
|
regfil[`reg_l] <= rdatahold2; // low
|
regfil[`reg_h] <= rdatahold; // high
|
regfil[`reg_h] <= rdatahold; // high
|
state <= nextstate; // get next macro state
|
state <= nextstate; // get next macro state
|
statesel <= statesel+1; // and index next in macro
|
statesel <= statesel+6'b1; // and index next in macro CNS
|
|
|
end
|
end
|
|
|
`cpus_accimm: begin
|
`cpus_accimm: begin
|
|
|
Line 1567... |
Line 1623... |
case (sel)
|
case (sel)
|
|
|
`aluop_add: begin // add
|
`aluop_add: begin // add
|
|
|
{ cout, resi } = opra+oprb; // find result and carry
|
{ cout, resi } = opra+oprb; // find result and carry
|
auxcar = (opra[3:0]+oprb[3:0]) >> 4 & 1; // find auxiliary carry
|
// find auxiliary carry
|
|
auxcar = (((opra[3:0]+oprb[3:0]) >> 4) & 8'b1) ? 1'b1 : 1'b0;
|
|
|
end
|
end
|
`aluop_adc: begin // adc
|
`aluop_adc: begin // adc
|
|
|
{ cout, resi } = opra+oprb+cin; // find result and carry
|
{ cout, resi } = opra+oprb+cin; // find result and carry
|
auxcar = (opra[3:0]+oprb[3:0]+cin) >> 4 & 1; // find auxiliary carry
|
// find auxiliary carry
|
|
auxcar = (((opra[3:0]+oprb[3:0]+cin) >> 4) & 8'b1) ? 1'b1 : 1'b0;
|
|
|
end
|
end
|
`aluop_sub, `aluop_cmp: begin // sub/cmp
|
`aluop_sub, `aluop_cmp: begin // sub/cmp
|
|
|
{ cout, resi } = opra-oprb; // find result and carry
|
{ cout, resi } = opra-oprb; // find result and carry
|
auxcar = (opra[3:0]-oprb[3:0]) >> 4 & 1; // find auxiliary borrow
|
// find auxiliary borrow
|
|
auxcar = (((opra[3:0]-oprb[3:0]) >> 4) & 8'b1) ? 1'b1 : 1'b0;
|
|
|
end
|
end
|
`aluop_sbb: begin // sbb
|
`aluop_sbb: begin // sbb
|
|
|
{ cout, resi } = opra-oprb-cin; // find result and carry
|
{ cout, resi } = opra-oprb-cin; // find result and carry
|
auxcar = (opra[3:0]-oprb[3:0]-cin >> 4) & 1; // find auxiliary borrow
|
// find auxiliary borrow
|
|
auxcar = (((opra[3:0]-oprb[3:0]-cin >> 4)) & 8'b1) ? 1'b1 : 1'b0;
|
|
|
end
|
end
|
`aluop_and: begin // ana
|
`aluop_and: begin // ana
|
|
|
{ cout, resi } = {1'b0, opra&oprb}; // find result and carry
|
{ cout, resi } = {1'b0, opra&oprb}; // find result and carry
|
auxcar = 0; // clear auxillary carry
|
auxcar = 1'b0; // clear auxillary carry
|
|
|
end
|
end
|
`aluop_xor: begin // xra
|
`aluop_xor: begin // xra
|
|
|
{ cout, resi } = {1'b0, opra^oprb}; // find result and carry
|
{ cout, resi } = {1'b0, opra^oprb}; // find result and carry
|
auxcar = 0; // clear auxillary carry
|
auxcar = 1'b0; // clear auxillary carry
|
|
|
end
|
end
|
`aluop_or: begin // ora
|
`aluop_or: begin // ora
|
|
|
{ cout, resi } = {1'b0, opra|oprb}; // find result and carry
|
{ cout, resi } = {1'b0, opra|oprb}; // find result and carry
|
auxcar = 0; // clear auxillary carry
|
auxcar = 1'b0; // clear auxillary carry
|
|
|
end
|
end
|
|
|
endcase
|
endcase
|
|
|