mirror of https://github.com/zxdos/zxuno.git
Actualizo zxpp03
This commit is contained in:
parent
ba5db596ff
commit
adc419fe22
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -26,18 +26,21 @@ CONFIG PROHIBIT=P144;
|
|||
CONFIG PROHIBIT=P69;
|
||||
CONFIG PROHIBIT=P60;
|
||||
|
||||
NET netCLK LOC="P94" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLK
|
||||
NET netHS LOC="P117" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C3
|
||||
NET netVS LOC="P116" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C2
|
||||
NET netR(0) LOC="P118" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C4
|
||||
NET netR(1) LOC="P119" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C5
|
||||
NET netR(2) LOC="P120" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C6
|
||||
NET netR(3) LOC="P121" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C7
|
||||
NET netG(0) LOC="P84" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B4
|
||||
NET netG(1) LOC="P82" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B5
|
||||
NET netG(2) LOC="P80" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B6
|
||||
NET netG(3) LOC="P78" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B7
|
||||
NET netB(0) LOC="P99" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B0
|
||||
NET netB(1) LOC="P97" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B1
|
||||
NET netB(2) LOC="P92" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B2
|
||||
NET netB(3) LOC="P87" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B3
|
||||
NET netRST LOC="P85" | IOSTANDARD=LVTTL | PULLDOWN; # A11
|
||||
NET netNMI LOC="P59" | IOSTANDARD=LVTTL | PULLDOWN; # B11
|
||||
NET netCLK LOC="P94" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLK
|
||||
|
||||
NET videoV LOC="P116" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C2
|
||||
NET videoH LOC="P117" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C3
|
||||
NET videoR(0) LOC="P118" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C4
|
||||
NET videoR(1) LOC="P119" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C5
|
||||
NET videoR(2) LOC="P120" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C6
|
||||
NET videoR(3) LOC="P121" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # C7
|
||||
NET videoG(0) LOC="P84" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B4
|
||||
NET videoG(1) LOC="P82" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B5
|
||||
NET videoG(2) LOC="P80" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B6
|
||||
NET videoG(3) LOC="P78" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B7
|
||||
NET videoB(0) LOC="P99" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B0
|
||||
NET videoB(1) LOC="P97" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B1
|
||||
NET videoB(2) LOC="P92" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B2
|
||||
NET videoB(3) LOC="P87" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST; # B3
|
||||
|
|
|
|||
|
|
@ -0,0 +1,442 @@
|
|||
//
|
||||
// TV80 8-Bit Microprocessor Core
|
||||
// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
|
||||
//
|
||||
// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
module tv80_alu (/*AUTOARG*/
|
||||
// Outputs
|
||||
Q, F_Out,
|
||||
// Inputs
|
||||
Arith16, Z16, ALU_Op, IR, ISet, BusA, BusB, F_In
|
||||
);
|
||||
|
||||
parameter Mode = 0;
|
||||
parameter Flag_C = 0;
|
||||
parameter Flag_N = 1;
|
||||
parameter Flag_P = 2;
|
||||
parameter Flag_X = 3;
|
||||
parameter Flag_H = 4;
|
||||
parameter Flag_Y = 5;
|
||||
parameter Flag_Z = 6;
|
||||
parameter Flag_S = 7;
|
||||
|
||||
input Arith16;
|
||||
input Z16;
|
||||
input [3:0] ALU_Op ;
|
||||
input [5:0] IR;
|
||||
input [1:0] ISet;
|
||||
input [7:0] BusA;
|
||||
input [7:0] BusB;
|
||||
input [7:0] F_In;
|
||||
output [7:0] Q;
|
||||
output [7:0] F_Out;
|
||||
reg [7:0] Q;
|
||||
reg [7:0] F_Out;
|
||||
|
||||
function [4:0] AddSub4;
|
||||
input [3:0] A;
|
||||
input [3:0] B;
|
||||
input Sub;
|
||||
input Carry_In;
|
||||
begin
|
||||
AddSub4 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + {4'h0,Carry_In};
|
||||
end
|
||||
endfunction // AddSub4
|
||||
|
||||
function [3:0] AddSub3;
|
||||
input [2:0] A;
|
||||
input [2:0] B;
|
||||
input Sub;
|
||||
input Carry_In;
|
||||
begin
|
||||
AddSub3 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + {3'h0,Carry_In};
|
||||
end
|
||||
endfunction // AddSub4
|
||||
|
||||
function [1:0] AddSub1;
|
||||
input A;
|
||||
input B;
|
||||
input Sub;
|
||||
input Carry_In;
|
||||
begin
|
||||
AddSub1 = { 1'b0, A } + { 1'b0, (Sub)?~B:B } + {1'h0,Carry_In};
|
||||
end
|
||||
endfunction // AddSub4
|
||||
|
||||
// AddSub variables (temporary signals)
|
||||
reg UseCarry;
|
||||
reg Carry7_v;
|
||||
reg OverFlow_v;
|
||||
reg HalfCarry_v;
|
||||
reg Carry_v;
|
||||
reg [7:0] Q_v;
|
||||
|
||||
reg [7:0] BitMask;
|
||||
|
||||
|
||||
always @(/*AUTOSENSE*/ALU_Op or BusA or BusB or F_In or IR)
|
||||
begin
|
||||
case (IR[5:3])
|
||||
3'b000 : BitMask = 8'b00000001;
|
||||
3'b001 : BitMask = 8'b00000010;
|
||||
3'b010 : BitMask = 8'b00000100;
|
||||
3'b011 : BitMask = 8'b00001000;
|
||||
3'b100 : BitMask = 8'b00010000;
|
||||
3'b101 : BitMask = 8'b00100000;
|
||||
3'b110 : BitMask = 8'b01000000;
|
||||
default: BitMask = 8'b10000000;
|
||||
endcase // case(IR[5:3])
|
||||
|
||||
UseCarry = ~ ALU_Op[2] && ALU_Op[0];
|
||||
{ HalfCarry_v, Q_v[3:0] } = AddSub4(BusA[3:0], BusB[3:0], ALU_Op[1], ALU_Op[1] ^ (UseCarry && F_In[Flag_C]) );
|
||||
{ Carry7_v, Q_v[6:4] } = AddSub3(BusA[6:4], BusB[6:4], ALU_Op[1], HalfCarry_v);
|
||||
{ Carry_v, Q_v[7] } = AddSub1(BusA[7], BusB[7], ALU_Op[1], Carry7_v);
|
||||
OverFlow_v = Carry_v ^ Carry7_v;
|
||||
end // always @ *
|
||||
|
||||
reg [7:0] Q_t;
|
||||
reg [8:0] DAA_Q;
|
||||
|
||||
always @ (/*AUTOSENSE*/ALU_Op or Arith16 or BitMask or BusA or BusB
|
||||
or Carry_v or F_In or HalfCarry_v or IR or ISet
|
||||
or OverFlow_v or Q_v or Z16)
|
||||
begin
|
||||
Q_t = 8'hxx;
|
||||
DAA_Q = {9{1'bx}};
|
||||
|
||||
F_Out = F_In;
|
||||
case (ALU_Op)
|
||||
4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111 :
|
||||
begin
|
||||
F_Out[Flag_N] = 1'b0;
|
||||
F_Out[Flag_C] = 1'b0;
|
||||
|
||||
case (ALU_Op[2:0])
|
||||
|
||||
3'b000, 3'b001 : // ADD, ADC
|
||||
begin
|
||||
Q_t = Q_v;
|
||||
F_Out[Flag_C] = Carry_v;
|
||||
F_Out[Flag_H] = HalfCarry_v;
|
||||
F_Out[Flag_P] = OverFlow_v;
|
||||
end
|
||||
|
||||
3'b010, 3'b011, 3'b111 : // SUB, SBC, CP
|
||||
begin
|
||||
Q_t = Q_v;
|
||||
F_Out[Flag_N] = 1'b1;
|
||||
F_Out[Flag_C] = ~ Carry_v;
|
||||
F_Out[Flag_H] = ~ HalfCarry_v;
|
||||
F_Out[Flag_P] = OverFlow_v;
|
||||
end
|
||||
|
||||
3'b100 : // AND
|
||||
begin
|
||||
Q_t[7:0] = BusA & BusB;
|
||||
F_Out[Flag_H] = 1'b1;
|
||||
end
|
||||
|
||||
3'b101 : // XOR
|
||||
begin
|
||||
Q_t[7:0] = BusA ^ BusB;
|
||||
F_Out[Flag_H] = 1'b0;
|
||||
end
|
||||
|
||||
default : // OR 3'b110
|
||||
begin
|
||||
Q_t[7:0] = BusA | BusB;
|
||||
F_Out[Flag_H] = 1'b0;
|
||||
end
|
||||
|
||||
endcase // case(ALU_OP[2:0])
|
||||
|
||||
if (ALU_Op[2:0] == 3'b111 )
|
||||
begin // CP
|
||||
F_Out[Flag_X] = BusB[3];
|
||||
F_Out[Flag_Y] = BusB[5];
|
||||
end
|
||||
else
|
||||
begin
|
||||
F_Out[Flag_X] = Q_t[3];
|
||||
F_Out[Flag_Y] = Q_t[5];
|
||||
end
|
||||
|
||||
if (Q_t[7:0] == 8'b00000000 )
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b1;
|
||||
if (Z16 == 1'b1 )
|
||||
begin
|
||||
F_Out[Flag_Z] = F_In[Flag_Z]; // 16 bit ADC,SBC
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b0;
|
||||
end // else: !if(Q_t[7:0] == 8'b00000000 )
|
||||
|
||||
F_Out[Flag_S] = Q_t[7];
|
||||
case (ALU_Op[2:0])
|
||||
3'b000, 3'b001, 3'b010, 3'b011, 3'b111 : // ADD, ADC, SUB, SBC, CP
|
||||
;
|
||||
|
||||
default :
|
||||
F_Out[Flag_P] = ~(^Q_t);
|
||||
endcase // case(ALU_Op[2:0])
|
||||
|
||||
if (Arith16 == 1'b1 )
|
||||
begin
|
||||
F_Out[Flag_S] = F_In[Flag_S];
|
||||
F_Out[Flag_Z] = F_In[Flag_Z];
|
||||
F_Out[Flag_P] = F_In[Flag_P];
|
||||
end
|
||||
end // case: 4'b0000, 4'b0001, 4'b0010, 4'b0011, 4'b0100, 4'b0101, 4'b0110, 4'b0111
|
||||
|
||||
4'b1100 :
|
||||
begin
|
||||
// DAA
|
||||
F_Out[Flag_H] = F_In[Flag_H];
|
||||
F_Out[Flag_C] = F_In[Flag_C];
|
||||
DAA_Q[7:0] = BusA;
|
||||
DAA_Q[8] = 1'b0;
|
||||
if (F_In[Flag_N] == 1'b0 )
|
||||
begin
|
||||
// After addition
|
||||
// Alow > 9 || H == 1
|
||||
if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
|
||||
begin
|
||||
if ((DAA_Q[3:0] > 9) )
|
||||
begin
|
||||
F_Out[Flag_H] = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
F_Out[Flag_H] = 1'b0;
|
||||
end
|
||||
DAA_Q = DAA_Q + 6;
|
||||
end // if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
|
||||
|
||||
// new Ahigh > 9 || C == 1
|
||||
if (DAA_Q[8:4] > 9 || F_In[Flag_C] == 1'b1 )
|
||||
begin
|
||||
DAA_Q = DAA_Q + 9'd96; // 0x60 ***kyp*** DAA_Q = DAA_Q + 96;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
// After subtraction
|
||||
if (DAA_Q[3:0] > 9 || F_In[Flag_H] == 1'b1 )
|
||||
begin
|
||||
if (DAA_Q[3:0] > 5 )
|
||||
begin
|
||||
F_Out[Flag_H] = 1'b0;
|
||||
end
|
||||
DAA_Q[7:0] = DAA_Q[7:0] - 8'd6; // ***kyp*** DAA_Q[7:0] = DAA_Q[7:0] - 6;
|
||||
end
|
||||
if (BusA > 153 || F_In[Flag_C] == 1'b1 )
|
||||
begin
|
||||
DAA_Q = DAA_Q - 9'd352; // 0x160 ***kyp*** DAA_Q = DAA_Q - 352;
|
||||
end
|
||||
end // else: !if(F_In[Flag_N] == 1'b0 )
|
||||
|
||||
F_Out[Flag_X] = DAA_Q[3];
|
||||
F_Out[Flag_Y] = DAA_Q[5];
|
||||
F_Out[Flag_C] = F_In[Flag_C] || DAA_Q[8];
|
||||
Q_t = DAA_Q[7:0];
|
||||
|
||||
if (DAA_Q[7:0] == 8'b00000000 )
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b0;
|
||||
end
|
||||
|
||||
F_Out[Flag_S] = DAA_Q[7];
|
||||
F_Out[Flag_P] = ~ (^DAA_Q);
|
||||
end // case: 4'b1100
|
||||
|
||||
4'b1101, 4'b1110 :
|
||||
begin
|
||||
// RLD, RRD
|
||||
Q_t[7:4] = BusA[7:4];
|
||||
if (ALU_Op[0] == 1'b1 )
|
||||
begin
|
||||
Q_t[3:0] = BusB[7:4];
|
||||
end
|
||||
else
|
||||
begin
|
||||
Q_t[3:0] = BusB[3:0];
|
||||
end
|
||||
F_Out[Flag_H] = 1'b0;
|
||||
F_Out[Flag_N] = 1'b0;
|
||||
F_Out[Flag_X] = Q_t[3];
|
||||
F_Out[Flag_Y] = Q_t[5];
|
||||
if (Q_t[7:0] == 8'b00000000 )
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b0;
|
||||
end
|
||||
F_Out[Flag_S] = Q_t[7];
|
||||
F_Out[Flag_P] = ~(^Q_t);
|
||||
end // case: when 4'b1101, 4'b1110
|
||||
|
||||
4'b1001 :
|
||||
begin
|
||||
// BIT
|
||||
Q_t[7:0] = BusB & BitMask;
|
||||
F_Out[Flag_S] = Q_t[7];
|
||||
if (Q_t[7:0] == 8'b00000000 )
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b1;
|
||||
F_Out[Flag_P] = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b0;
|
||||
F_Out[Flag_P] = 1'b0;
|
||||
end
|
||||
F_Out[Flag_H] = 1'b1;
|
||||
F_Out[Flag_N] = 1'b0;
|
||||
F_Out[Flag_X] = 1'b0;
|
||||
F_Out[Flag_Y] = 1'b0;
|
||||
if (IR[2:0] != 3'b110 )
|
||||
begin
|
||||
F_Out[Flag_X] = BusB[3];
|
||||
F_Out[Flag_Y] = BusB[5];
|
||||
end
|
||||
end // case: when 4'b1001
|
||||
|
||||
4'b1010 :
|
||||
// SET
|
||||
Q_t[7:0] = BusB | BitMask;
|
||||
|
||||
4'b1011 :
|
||||
// RES
|
||||
Q_t[7:0] = BusB & ~ BitMask;
|
||||
|
||||
4'b1000 :
|
||||
begin
|
||||
// ROT
|
||||
case (IR[5:3])
|
||||
3'b000 : // RLC
|
||||
begin
|
||||
Q_t[7:1] = BusA[6:0];
|
||||
Q_t[0] = BusA[7];
|
||||
F_Out[Flag_C] = BusA[7];
|
||||
end
|
||||
|
||||
3'b010 : // RL
|
||||
begin
|
||||
Q_t[7:1] = BusA[6:0];
|
||||
Q_t[0] = F_In[Flag_C];
|
||||
F_Out[Flag_C] = BusA[7];
|
||||
end
|
||||
|
||||
3'b001 : // RRC
|
||||
begin
|
||||
Q_t[6:0] = BusA[7:1];
|
||||
Q_t[7] = BusA[0];
|
||||
F_Out[Flag_C] = BusA[0];
|
||||
end
|
||||
|
||||
3'b011 : // RR
|
||||
begin
|
||||
Q_t[6:0] = BusA[7:1];
|
||||
Q_t[7] = F_In[Flag_C];
|
||||
F_Out[Flag_C] = BusA[0];
|
||||
end
|
||||
|
||||
3'b100 : // SLA
|
||||
begin
|
||||
Q_t[7:1] = BusA[6:0];
|
||||
Q_t[0] = 1'b0;
|
||||
F_Out[Flag_C] = BusA[7];
|
||||
end
|
||||
|
||||
3'b110 : // SLL (Undocumented) / SWAP
|
||||
begin
|
||||
if (Mode == 3 )
|
||||
begin
|
||||
Q_t[7:4] = BusA[3:0];
|
||||
Q_t[3:0] = BusA[7:4];
|
||||
F_Out[Flag_C] = 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Q_t[7:1] = BusA[6:0];
|
||||
Q_t[0] = 1'b1;
|
||||
F_Out[Flag_C] = BusA[7];
|
||||
end // else: !if(Mode == 3 )
|
||||
end // case: 3'b110
|
||||
|
||||
3'b101 : // SRA
|
||||
begin
|
||||
Q_t[6:0] = BusA[7:1];
|
||||
Q_t[7] = BusA[7];
|
||||
F_Out[Flag_C] = BusA[0];
|
||||
end
|
||||
|
||||
default : // SRL
|
||||
begin
|
||||
Q_t[6:0] = BusA[7:1];
|
||||
Q_t[7] = 1'b0;
|
||||
F_Out[Flag_C] = BusA[0];
|
||||
end
|
||||
endcase // case(IR[5:3])
|
||||
|
||||
F_Out[Flag_H] = 1'b0;
|
||||
F_Out[Flag_N] = 1'b0;
|
||||
F_Out[Flag_X] = Q_t[3];
|
||||
F_Out[Flag_Y] = Q_t[5];
|
||||
F_Out[Flag_S] = Q_t[7];
|
||||
if (Q_t[7:0] == 8'b00000000 )
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
F_Out[Flag_Z] = 1'b0;
|
||||
end
|
||||
F_Out[Flag_P] = ~(^Q_t);
|
||||
|
||||
if (ISet == 2'b00 )
|
||||
begin
|
||||
F_Out[Flag_P] = F_In[Flag_P];
|
||||
F_Out[Flag_S] = F_In[Flag_S];
|
||||
F_Out[Flag_Z] = F_In[Flag_Z];
|
||||
end
|
||||
end // case: 4'b1000
|
||||
|
||||
|
||||
default :
|
||||
;
|
||||
|
||||
endcase // case(ALU_Op)
|
||||
|
||||
Q = Q_t;
|
||||
end // always @ (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16)
|
||||
|
||||
endmodule // T80_ALU
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// TV80 8-Bit Microprocessor Core
|
||||
// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
|
||||
//
|
||||
// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
module tv80_reg (/*AUTOARG*/
|
||||
// Outputs
|
||||
DOBH, DOAL, DOCL, DOBL, DOCH, DOAH,
|
||||
// Inputs
|
||||
AddrC, AddrA, AddrB, DIH, DIL, clk, CEN, WEH, WEL
|
||||
);
|
||||
input [2:0] AddrC;
|
||||
output [7:0] DOBH;
|
||||
input [2:0] AddrA;
|
||||
input [2:0] AddrB;
|
||||
input [7:0] DIH;
|
||||
output [7:0] DOAL;
|
||||
output [7:0] DOCL;
|
||||
input [7:0] DIL;
|
||||
output [7:0] DOBL;
|
||||
output [7:0] DOCH;
|
||||
output [7:0] DOAH;
|
||||
input clk, CEN, WEH, WEL;
|
||||
|
||||
reg [7:0] RegsH [0:7];
|
||||
reg [7:0] RegsL [0:7];
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (CEN)
|
||||
begin
|
||||
if (WEH) RegsH[AddrA] <= DIH;
|
||||
if (WEL) RegsL[AddrA] <= DIL;
|
||||
end
|
||||
end
|
||||
|
||||
assign DOAH = RegsH[AddrA];
|
||||
assign DOAL = RegsL[AddrA];
|
||||
assign DOBH = RegsH[AddrB];
|
||||
assign DOBL = RegsL[AddrB];
|
||||
assign DOCH = RegsH[AddrC];
|
||||
assign DOCL = RegsL[AddrC];
|
||||
|
||||
// break out ram bits for waveform debug
|
||||
// synopsys translate_off
|
||||
wire [7:0] B = RegsH[0];
|
||||
wire [7:0] C = RegsL[0];
|
||||
wire [7:0] D = RegsH[1];
|
||||
wire [7:0] E = RegsL[1];
|
||||
wire [7:0] H = RegsH[2];
|
||||
wire [7:0] L = RegsL[2];
|
||||
|
||||
wire [15:0] IX = { RegsH[3], RegsL[3] };
|
||||
wire [15:0] IY = { RegsH[7], RegsL[7] };
|
||||
// synopsys translate_on
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
//
|
||||
// TV80 8-Bit Microprocessor Core
|
||||
// Based on the VHDL T80 core by Daniel Wallner (jesus@opencores.org)
|
||||
//
|
||||
// Copyright (c) 2004 Guy Hutchison (ghutchis@opencores.org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
// Negative-edge based wrapper allows memory wait_n signal to work
|
||||
// correctly without resorting to asynchronous logic.
|
||||
|
||||
module tv80n (/*AUTOARG*/
|
||||
// Outputs
|
||||
m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n, A, dout,
|
||||
// Inputs
|
||||
reset_n, clk, wait_n, int_n, nmi_n, busrq_n, di
|
||||
);
|
||||
|
||||
parameter Mode = 0; // 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB
|
||||
parameter T2Write = 0; // 0 => wr_n active in T3, /=0 => wr_n active in T2
|
||||
parameter IOWait = 1; // 0 => Single cycle I/O, 1 => Std I/O cycle
|
||||
|
||||
|
||||
input reset_n;
|
||||
input clk;
|
||||
input wait_n;
|
||||
input int_n;
|
||||
input nmi_n;
|
||||
input busrq_n;
|
||||
output m1_n;
|
||||
output mreq_n;
|
||||
output iorq_n;
|
||||
output rd_n;
|
||||
output wr_n;
|
||||
output rfsh_n;
|
||||
output halt_n;
|
||||
output busak_n;
|
||||
output [15:0] A;
|
||||
input [7:0] di;
|
||||
output [7:0] dout;
|
||||
|
||||
reg mreq_n;
|
||||
reg iorq_n;
|
||||
reg rd_n;
|
||||
reg wr_n;
|
||||
reg nxt_mreq_n;
|
||||
reg nxt_iorq_n;
|
||||
reg nxt_rd_n;
|
||||
reg nxt_wr_n;
|
||||
|
||||
wire cen;
|
||||
wire intcycle_n;
|
||||
wire no_read;
|
||||
wire write;
|
||||
wire iorq;
|
||||
reg [7:0] di_reg;
|
||||
wire [6:0] mcycle;
|
||||
wire [6:0] tstate;
|
||||
|
||||
assign cen = 1;
|
||||
|
||||
tv80_core #(Mode, IOWait) i_tv80_core
|
||||
(
|
||||
.cen (cen),
|
||||
.m1_n (m1_n),
|
||||
.iorq (iorq),
|
||||
.no_read (no_read),
|
||||
.write (write),
|
||||
.rfsh_n (rfsh_n),
|
||||
.halt_n (halt_n),
|
||||
.wait_n (wait_n),
|
||||
.int_n (int_n),
|
||||
.nmi_n (nmi_n),
|
||||
.reset_n (reset_n),
|
||||
.busrq_n (busrq_n),
|
||||
.busak_n (busak_n),
|
||||
.clk (clk),
|
||||
.IntE (),
|
||||
.stop (),
|
||||
.A (A),
|
||||
.dinst (di),
|
||||
.di (di_reg),
|
||||
.dout (dout),
|
||||
.mc (mcycle),
|
||||
.ts (tstate),
|
||||
.intcycle_n (intcycle_n)
|
||||
);
|
||||
|
||||
always @*
|
||||
begin
|
||||
nxt_mreq_n = 1;
|
||||
nxt_rd_n = 1;
|
||||
nxt_iorq_n = 1;
|
||||
nxt_wr_n = 1;
|
||||
|
||||
if (mcycle[0])
|
||||
begin
|
||||
if (tstate[1] || tstate[2])
|
||||
begin
|
||||
nxt_rd_n = ~ intcycle_n;
|
||||
nxt_mreq_n = ~ intcycle_n;
|
||||
nxt_iorq_n = intcycle_n;
|
||||
end
|
||||
end // if (mcycle[0])
|
||||
else
|
||||
begin
|
||||
if ((tstate[1] || tstate[2]) && !no_read && !write)
|
||||
begin
|
||||
nxt_rd_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
if (T2Write == 0)
|
||||
begin
|
||||
if (tstate[2] && write)
|
||||
begin
|
||||
nxt_wr_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
if ((tstate[1] || (tstate[2] && !wait_n)) && write)
|
||||
begin
|
||||
nxt_wr_n = 1'b0;
|
||||
nxt_iorq_n = ~ iorq;
|
||||
nxt_mreq_n = iorq;
|
||||
end
|
||||
end // else: !if(T2write == 0)
|
||||
end // else: !if(mcycle[0])
|
||||
end // always @ *
|
||||
|
||||
always @(negedge clk)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
rd_n <= #1 1'b1;
|
||||
wr_n <= #1 1'b1;
|
||||
iorq_n <= #1 1'b1;
|
||||
mreq_n <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
rd_n <= #1 nxt_rd_n;
|
||||
wr_n <= #1 nxt_wr_n;
|
||||
iorq_n <= #1 nxt_iorq_n;
|
||||
mreq_n <= #1 nxt_mreq_n;
|
||||
end // else: !if(!reset_n)
|
||||
end // always @ (posedge clk or negedge reset_n)
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (!reset_n)
|
||||
begin
|
||||
di_reg <= #1 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (tstate[2] && wait_n == 1'b1)
|
||||
di_reg <= #1 di;
|
||||
end // else: !if(!reset_n)
|
||||
end // always @ (posedge clk)
|
||||
|
||||
endmodule // t80n
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity ula is
|
||||
port
|
||||
(
|
||||
clock25 : in std_logic;
|
||||
clock14 : in std_logic;
|
||||
clock4 : out std_logic;
|
||||
iorq : in std_logic;
|
||||
rd : in std_logic;
|
||||
wr : in std_logic;
|
||||
a0 : in std_logic;
|
||||
di : in std_logic_vector( 7 downto 0);
|
||||
do : out std_logic_vector( 7 downto 0);
|
||||
int : out std_logic;
|
||||
va : out std_logic_vector(12 downto 0);
|
||||
vd : in std_logic_vector( 7 downto 0);
|
||||
hs : out std_logic;
|
||||
vs : out std_logic;
|
||||
rgb : out std_logic_vector(11 downto 0)
|
||||
);
|
||||
end;
|
||||
|
||||
architecture behavioral of ula is
|
||||
|
||||
signal clock : std_logic;
|
||||
signal portFF : std_logic_vector(2 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
Uvga: entity work.vga port map
|
||||
(
|
||||
clock25 => clock25,
|
||||
border => portFF(2 downto 0),
|
||||
va => va,
|
||||
vd => vd,
|
||||
hs => hs,
|
||||
vs => vs,
|
||||
rgb => rgb
|
||||
);
|
||||
Uvideo: entity work.video port map
|
||||
(
|
||||
clock14 => clock14,
|
||||
clock4 => clock,
|
||||
int => int
|
||||
);
|
||||
|
||||
clock4 <= clock;
|
||||
portFF <= di(2 downto 0) when rising_edge(clock) and iorq = '0' and wr = '0' and a0 = '0';
|
||||
|
||||
end;
|
||||
|
|
@ -15,6 +15,7 @@ entity vga is
|
|||
port
|
||||
(
|
||||
clock25 : in std_logic;
|
||||
border : in std_logic_vector( 2 downto 0);
|
||||
va : out std_logic_vector(12 downto 0);
|
||||
vd : in std_logic_vector( 7 downto 0);
|
||||
hs : out std_logic;
|
||||
|
|
@ -25,12 +26,12 @@ end;
|
|||
|
||||
architecture behavioral of vga is
|
||||
|
||||
signal x : std_logic_vector( 9 downto 0);
|
||||
signal y : std_logic_vector( 9 downto 0);
|
||||
signal f : std_logic_vector( 5 downto 0);
|
||||
signal xy : std_logic_vector(17 downto 0);
|
||||
signal bmap : std_logic_vector( 7 downto 0);
|
||||
signal attr : std_logic_vector( 7 downto 0);
|
||||
signal xy : std_logic_vector(17 downto 0);
|
||||
signal x : std_logic_vector( 9 downto 0) := std_logic_vector(to_unsigned(512-20, 10));
|
||||
signal y : std_logic_vector( 9 downto 0) := std_logic_vector(to_unsigned(383, 10));
|
||||
signal f : std_logic_vector( 5 downto 0);
|
||||
signal bmap : std_logic_vector( 7 downto 0);
|
||||
signal attr : std_logic_vector( 7 downto 0);
|
||||
|
||||
type tpalette is array (0 to 15) of std_logic_vector(11 downto 0);
|
||||
constant palette : tpalette := ( x"000", x"007", x"700", x"707", x"070", x"077", x"770", x"777", x"000", x"00f", x"f00", x"f0f", x"0f0", x"0ff", x"ff0", x"fff" );
|
||||
|
|
@ -83,7 +84,7 @@ begin
|
|||
if attr(6) = '1' then c := c+8; end if;
|
||||
rgb <= palette(c);
|
||||
elsif x < 640 and y < 480 then
|
||||
rgb <= x"700";
|
||||
rgb <= palette(to_integer(unsigned(border)));
|
||||
else
|
||||
rgb <= x"000";
|
||||
end if;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
library ieee;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
|
||||
entity video is
|
||||
port
|
||||
(
|
||||
clock14 : in std_logic;
|
||||
clock4 : out std_logic;
|
||||
int : out std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture behavioral of video is
|
||||
|
||||
signal count4 : std_logic_vector(1 downto 0) := "00";
|
||||
|
||||
begin
|
||||
|
||||
clock4 <= count4(1);
|
||||
count4 <= count4+1 when rising_edge(clock14);
|
||||
|
||||
process(count4(1))
|
||||
variable c : std_logic_vector(17 downto 0) := (others => '0');
|
||||
begin
|
||||
if rising_edge(count4(1)) then
|
||||
if c < 69887 then c := c+1; else c := (others => '0'); end if;
|
||||
if c >= 16 and c < 48 then int <= '0'; else int <= '1'; end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end;
|
||||
|
|
@ -1,3 +1,12 @@
|
|||
vhdl work "ipcore_dir/rom.vhd"
|
||||
vhdl work "ipcore_dir/loram.vhd"
|
||||
verilog work "tv80_reg.v"
|
||||
verilog work "tv80_mcode.v"
|
||||
verilog work "tv80_alu.v"
|
||||
vhdl work "video.vhd"
|
||||
vhdl work "vga.vhd"
|
||||
verilog work "tv80_core.v"
|
||||
vhdl work "ula.vhd"
|
||||
verilog work "tv80n.v"
|
||||
vhdl work "clock.vhd"
|
||||
vhdl work "zxpp.vhd"
|
||||
|
|
|
|||
|
|
@ -4,74 +4,102 @@ library ieee;
|
|||
entity zxpp is
|
||||
port
|
||||
(
|
||||
netCLK : in std_logic;
|
||||
netVS : out std_logic;
|
||||
netHS : out std_logic;
|
||||
netR : out std_logic_vector(3 downto 0);
|
||||
netG : out std_logic_vector(3 downto 0);
|
||||
netB : out std_logic_vector(3 downto 0)
|
||||
netRST : in std_logic;
|
||||
netNMI : in std_logic;
|
||||
netCLK : in std_logic;
|
||||
--
|
||||
videoV : out std_logic;
|
||||
videoH : out std_logic;
|
||||
videoR : out std_logic_vector(3 downto 0);
|
||||
videoG : out std_logic_vector(3 downto 0);
|
||||
videoB : out std_logic_vector(3 downto 0)
|
||||
);
|
||||
end;
|
||||
|
||||
architecture structural of zxpp is
|
||||
|
||||
component clock is
|
||||
port
|
||||
(
|
||||
clock32 : in std_logic;
|
||||
clock25 : out std_logic;
|
||||
clock14 : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component loram
|
||||
port
|
||||
(
|
||||
clka : in std_logic;
|
||||
wea : in std_logic_vector( 0 downto 0);
|
||||
addra : in std_logic_vector(13 downto 0);
|
||||
dina : in std_logic_vector( 7 downto 0);
|
||||
douta : out std_logic_vector( 7 downto 0);
|
||||
clkb : in std_logic;
|
||||
web : in std_logic_vector( 0 downto 0);
|
||||
addrb : in std_logic_vector(13 downto 0);
|
||||
dinb : in std_logic_vector( 7 downto 0);
|
||||
doutb : out std_logic_vector( 7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component vga is
|
||||
port
|
||||
(
|
||||
clock25 : in std_logic;
|
||||
va : out std_logic_vector(12 downto 0);
|
||||
vd : in std_logic_vector( 7 downto 0);
|
||||
hs : out std_logic;
|
||||
vs : out std_logic;
|
||||
rgb : out std_logic_vector(11 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal clock25 : std_logic;
|
||||
signal clock14 : std_logic;
|
||||
signal va : std_logic_vector(12 downto 0);
|
||||
signal vd : std_logic_vector( 7 downto 0);
|
||||
signal clock25 : std_logic;
|
||||
signal clock14 : std_logic;
|
||||
signal clock4 : std_logic;
|
||||
signal reset : std_logic;
|
||||
signal nmi : std_logic;
|
||||
signal int : std_logic;
|
||||
signal mreq : std_logic;
|
||||
signal iorq : std_logic;
|
||||
signal m1 : std_logic;
|
||||
signal rd : std_logic;
|
||||
signal wr : std_logic;
|
||||
signal a : std_logic_vector(15 downto 0);
|
||||
signal d : std_logic_vector( 7 downto 0);
|
||||
signal va : std_logic_vector(12 downto 0);
|
||||
signal vd : std_logic_vector( 7 downto 0);
|
||||
signal dula : std_logic_vector( 7 downto 0);
|
||||
signal dcpu : std_logic_vector( 7 downto 0);
|
||||
signal drom : std_logic_vector( 7 downto 0);
|
||||
signal dloram : std_logic_vector( 7 downto 0);
|
||||
signal wloram : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
Uclock: clock port map
|
||||
Uclock: entity work.clock port map
|
||||
(
|
||||
clock32 => netCLK,
|
||||
clock25 => clock25,
|
||||
clock14 => clock14
|
||||
clock32 => netCLK,
|
||||
clock25 => clock25,
|
||||
clock14 => clock14
|
||||
);
|
||||
Uloram: loram port map
|
||||
Uula: entity work.ula port map
|
||||
(
|
||||
clka => '0',
|
||||
wea(0) => '0',
|
||||
addra => (others => '0'),
|
||||
dina => (others => '0'),
|
||||
douta => open,
|
||||
clock25 => clock25,
|
||||
clock14 => clock14,
|
||||
clock4 => clock4,
|
||||
iorq => iorq,
|
||||
rd => rd,
|
||||
wr => wr,
|
||||
a0 => a(0),
|
||||
di => dcpu,
|
||||
do => dula,
|
||||
int => int,
|
||||
va => va,
|
||||
vd => vd,
|
||||
hs => videoH,
|
||||
vs => videoV,
|
||||
rgb(11 downto 8) => videoR,
|
||||
rgb( 7 downto 4) => videoG,
|
||||
rgb( 3 downto 0) => videoB
|
||||
);
|
||||
Ucpu: entity work.tv80n port map
|
||||
(
|
||||
clk => clock4,
|
||||
reset_n => reset,
|
||||
nmi_n => nmi,
|
||||
int_n => int,
|
||||
wait_n => '1',
|
||||
busrq_n => '1',
|
||||
mreq_n => mreq,
|
||||
iorq_n => iorq,
|
||||
rd_n => rd,
|
||||
wr_n => wr,
|
||||
m1_n => m1,
|
||||
rfsh_n => open,
|
||||
halt_n => open,
|
||||
busak_n => open,
|
||||
a => a,
|
||||
di => d,
|
||||
dout => dcpu
|
||||
);
|
||||
Urom: entity work.rom port map
|
||||
(
|
||||
clka => clock4,
|
||||
addra => a(13 downto 0),
|
||||
douta => drom
|
||||
);
|
||||
Uloram: entity work.loram port map
|
||||
(
|
||||
clka => clock4,
|
||||
wea(0) => wloram,
|
||||
addra => a(13 downto 0),
|
||||
dina => dcpu,
|
||||
douta => dloram,
|
||||
clkb => clock25,
|
||||
web(0) => '0',
|
||||
addrb(13) => '0',
|
||||
|
|
@ -79,16 +107,15 @@ begin
|
|||
dinb => (others => '0'),
|
||||
doutb => vd
|
||||
);
|
||||
Uvga: vga port map
|
||||
(
|
||||
clock25 => clock25,
|
||||
va => va,
|
||||
vd => vd,
|
||||
hs => netHS,
|
||||
vs => netVS,
|
||||
rgb(11 downto 8) => netR,
|
||||
rgb( 7 downto 4) => netG,
|
||||
rgb( 3 downto 0) => netB
|
||||
);
|
||||
|
||||
reset <= not netRST;
|
||||
nmi <= not netNMI;
|
||||
|
||||
wloram <= '1' when mreq = '0' and wr = '0' and a(15 downto 14) = "01" else '0';
|
||||
|
||||
d <= dula when iorq = '0' and rd = '0' and a(0) = '0'
|
||||
else drom when mreq = '0' and rd = '0' and a(15 downto 14) = "00"
|
||||
else dloram when mreq = '0' and rd = '0' and a(15 downto 14) = "01"
|
||||
else (others => '1');
|
||||
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ run
|
|||
-rtlview Yes
|
||||
-glob_opt AllClockNets
|
||||
-read_cores YES
|
||||
-sd {"ipcore_dir" }
|
||||
-write_timing_constraints NO
|
||||
-cross_clock_analysis NO
|
||||
-hierarchy_separator /
|
||||
|
|
|
|||
Loading…
Reference in New Issue