URL
https://opencores.org/ocsvn/nextz80/nextz80/trunk
Subversion Repositories nextz80
Compare Revisions
- This comparison shows the changes necessary to convert path
/nextz80/trunk
- from Rev 16 to Rev 17
- ↔ Reverse comparison
Rev 16 → Rev 17
/Next8080CPU.v
44,8 → 44,22
// Each CPU machine cycle takes (mainly) one clock T state. This makes this processor over 4 times faster than a 8080 at the same |
// clock frequency (some instructions are up to 10 times faster). |
// Only 8080 instructions available (minus DAA, which = CPL) + some extra: JR, DJNZ |
// Only IM0 supported, flags 3 and 5 always 0, opcodes DD, ED, FD, CB treated as NOP |
// Only IM0 supported, flags 3 and 5 always 0, opcodes ED, FD, CB treated as NOP |
// No H and N flags, always 0 |
|
// Indexed mode: after the new instruction INDEX i8 [0xdd, i8], the next instruction (only) will use (mem+i8) instead of (mem) |
// No interrupt is accepted after INDEX i8. i8 is a signed 8bit value. |
// Indexed mode applies to the following instructions: |
// 02h = ld (bc+i8),a |
// 12h = ld (de+i8),a |
// 22h = ld (hl+i8),a instead of ld (nn),hl. Ex: [0xdd 0xff 0x22] will execute ld (hl-1),a |
// 32h = ld (sp+i8),a instead of ld (nn),a. Ex: [0xdd 0x13 0x32] will execute ld (sp+13h),a |
// 0Ah = ld a,(bc+i8) |
// 1Ah = ld a,(de+i8) |
// 2Ah = ld a,(hl+i8),a instead of ld hl,(nn) |
// 3Ah = ld a,(sp+i8),a instead of ld a,(nn) |
// All the other instructions which uses memory at (hl): ld r,(hl+i8); ld (hl+i8),r; inc (hl+i8); dec (hl+i8); ld (hl+i8),n; op a,(hl); |
|
// ~450 LUT6 |
// See NextZ80 for more detais |
/////////////////////////////////////////////////////////////////////////////////// |
70,7 → 84,7
); |
|
// connections and registers |
reg [1:0] CPUStatus = 0; // 0=HL-HL', 1=EI |
reg [2:0] CPUStatus = 0; // 0=HL-DE, 1=EI, 2-indexed mode |
wire [7:0] ALU8FLAGS; |
wire [7:0] FLAGS; |
wire [7:0] ALU80; |
96,7 → 110,7
reg next_stage; |
reg [3:0]REG_WSEL; |
reg [3:0]REG_RSEL; |
reg [2:0]status; // 0=HL-HL', 1=EI, 2=set EI |
reg [3:0]status; // 0=HL-DE, 1=EI, 2=set EI, 3=set indexed mode |
// FETCH[5:3]: 000 NZ, 001 Z, 010 NC, 011 C, 100 PO, 101 PE, 110 P, 111 M |
wire [7:0]FlagMux = {FLAGS[7], !FLAGS[7], FLAGS[2], !FLAGS[2], FLAGS[0], !FLAGS[0], FLAGS[6], !FLAGS[6]}; |
reg tzf; |
153,12 → 167,13
if(FETCH[8:6] == 3'b110) {FETCH[8:7]} <= 2'b00; // exit RESET state |
else begin |
if(M1) FETCH <= {1'b0, DI}; |
if(!next_stage & SINT & CPUStatus[1] & !status[2]) {FETCH[8:6], FETCH[1:0]} <= {3'b100, HALT, M1}; // INT request |
if(!next_stage & SINT & CPUStatus[1] & !status[2] & !status[3]) {FETCH[8:6], FETCH[1:0]} <= {3'b100, HALT, M1}; // INT request |
end |
if(next_stage) STAGE <= STAGE + 1'b1; |
else STAGE <= 0; |
CPUStatus[0] <= CPUStatus[0] ^ status[0]; |
if(status[2]) CPUStatus[1] <= status[1]; // EI |
if(!next_stage) CPUStatus[2] <= status[3]; |
tzf <= ALU8FLAGS[6]; |
end |
|
183,7 → 198,7
WR = 0; |
HALT = 0; |
IORQ = 0; |
status = 3'b000; |
status = 4'b0000; |
|
|
case(FETCH[8:6]) |
262,10 → 277,11
4'b0010, 4'b1010: |
case(STAGE[2:0]) |
3'b000: |
if(FETCH[5] == 0) begin // LD (BC) A, LD (DE) A - stage1 |
if(FETCH[3]) DINW_SEL = 1; // DI |
else DO_SEL = 2'b00; // ALU80 |
if(!FETCH[5] | CPUStatus[2]) begin // LD (BC) A, LD (DE) A - stage1 |
DINW_SEL = 1; // DI |
DO_SEL = 2'b00; // ALU80 |
ALU160_SEL = 0; // regs |
if(CPUStatus[2]) ALU16OP = 3; // indexed mode |
WE = {4'b000x, FETCH[3], 1'bx}; // hi |
next_stage = 1; |
REG_WSEL = FETCH[3] ? 4'b011x : 4'b0110; // A |
281,7 → 297,7
M1 = 0; |
end |
3'b001: |
if(FETCH[5] == 0) begin // LD (BC), A, LD (DE), A - stage2 |
if(!FETCH[5] | CPUStatus[2]) begin // LD (BC), A, LD (DE), A - stage2 |
ALU160_SEL = 1; // pc |
WE = 6'b010x00; // PC |
end else begin // LD (nn),A - LH (nn),HL - stage 2 |
368,9 → 384,9
end else case({STAGE[1:0]}) |
2'b00: begin // (HL) - stage1 |
ALU160_SEL = 0; // regs |
if(CPUStatus[2]) ALU16OP = 3; // indexed mode |
DINW_SEL = 1; // DI |
WE = 6'b000001; // lo |
ALU16OP = 3'd0; |
next_stage = 1; |
REG_WSEL = 4'b011x; // tmpLO |
REG_RSEL = 4'b010x; // HL |
379,9 → 395,9
2'b01: begin // (HL) stage2 |
DO_SEL = 2'b11; // ALU80OUT |
ALU160_SEL = 0; // regs |
if(CPUStatus[2]) ALU16OP = 3; // indexed mode |
WE = 6'b100x0x; // flags |
ALU8OP = {3'b010, FETCH[0], 1'b0}; // inc / dec |
ALU16OP = 3'd0; |
next_stage = 1; |
REG_WSEL = 4'b0111; // tmpLO |
REG_RSEL = 4'b010x; // HL |
394,7 → 410,7
end |
endcase |
// ----------------------- ld r/(HL), n -------------------- |
4'b0110, 4'b1110: |
4'b0110, 4'b1110: |
case({STAGE[1:0], op1mem}) |
3'b00_0, 3'b00_1: begin // r, (HL) - stage1 (read n) |
ALU160_SEL = 1; // pc |
411,8 → 427,8
3'b01_1: begin // (HL) - stage2 |
DO_SEL = 2'b00; // ALU80 |
ALU160_SEL = 0; // regs |
if(CPUStatus[2]) ALU16OP = 3; // indexed mode |
WE = 6'b000x0x; // nothing |
ALU16OP = 3'd0; |
next_stage = 1; |
REG_WSEL = 4'b0111; // tmpLO |
REG_RSEL = 4'b010x; // HL |
459,7 → 475,7
endcase |
|
// ---------------------------------------------- block 01 LD8 --------------------------------------------------- |
3'b001: |
3'b001: |
case({STAGE[0], op1mem, op0mem}) |
3'b0_00, // LD r, r 1st stage |
3'b1_01: // LD r, (HL) 2nd stage |
474,9 → 490,9
3'b0_01: // LD r, (HL) 1st stage |
begin |
ALU160_SEL = 0; // regs |
if(CPUStatus[2]) ALU16OP = 3; // indexed mode |
DINW_SEL = 1; // DI |
WE = 6'b000x01; // LO |
ALU16OP = 3'd0; // ADD - NOP |
next_stage = 1; |
REG_WSEL = 4'b011x; // A - tmpLO |
REG_RSEL = 4'b010x; // HL |
486,8 → 502,8
begin |
DO_SEL = 0; // ALU80 |
ALU160_SEL = 0; // regs |
if(CPUStatus[2]) ALU16OP = 3; // indexed mode |
WE = 6'b000x00; // no write |
ALU16OP = 3'd0; // ADD - NOP |
next_stage = 1; |
REG_WSEL = {1'b0, opd[2:0]}; |
REG_RSEL = 4'b010x; // HL |
507,7 → 523,7
end |
endcase |
// ---------------------------------------------- block 10 arith8 --------------------------------------------------- |
3'b010: |
3'b010: |
case({STAGE[0], op0mem}) |
2'b0_0, // OP r,r 1st stage |
2'b1_1: // OP r, (HL) 2nd stage |
521,10 → 537,10
end |
2'b0_1: // OP r, (HL) 1st stage |
begin |
ALU160_SEL = 0; // HL |
ALU160_SEL = 0; // regs |
if(CPUStatus[2]) ALU16OP = 3; // indexed mode |
DINW_SEL = 1; // DI |
WE = 6'b000x01; // lo |
ALU16OP = 3'd0; // ADD - NOP |
next_stage = 1; |
REG_WSEL = 4'b011x; // A-tmpLO |
REG_RSEL = 4'b010x; // HL |
895,8 → 911,19
REG_RSEL = 4'b111x; // tmp7 |
end |
endcase |
2'b01, 2'b10, 2'b11: begin // DD - IX, ED, FD - IY |
2'b01: begin // DD - indexed mode |
ALU160_SEL = 1; // PC |
if(!STAGE[0]) begin |
WE = 6'b010100; // PC, tmpHI |
next_stage = 1; |
M1 = 0; |
end else begin |
WE = 6'b010000; // PC |
status[3] = 1'b1; // set indexed mode |
end |
end |
2'b10, 2'b11: begin // ED, FD - IY |
ALU160_SEL = 1; // PC |
WE = 6'b010x00; // PC |
end |
endcase |
1212,11 → 1239,8
0: RAMSEL = 3'b000; // BC |
1: RAMSEL = rstatus ? 3'b010 : 3'b001; // HL - DE |
2: RAMSEL = rstatus ? 3'b001 : 3'b010; // DE - HL |
3: RAMSEL = 3'b011; // A-TL |
4: RAMSEL = 3'b100; // I-R |
5: RAMSEL = 3'b100; // tmp SP |
6: RAMSEL = 3'b100; // zero |
7: RAMSEL = 3'b100; // temp |
3: RAMSEL = 3'b011; // A-TL |
default: RAMSEL = 3'b100; // I-R, tmp SP, zero, temp |
endcase |
end |
endmodule |