mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-04-19 08:29:56 +00:00
1180 lines
28 KiB
Verilog
1180 lines
28 KiB
Verilog
`timescale 1 ns / 1 ns
|
||
`define BASE_SYS_ROM
|
||
`define BASE_DOS_ROM
|
||
`define BOOT_ROM_6000
|
||
`define BASE_RAM_78//2k
|
||
`define BASE_RAM_16K
|
||
//`define RAM_16K_EXPANSION
|
||
`define VRAM_2K
|
||
//`define VRAM_8K
|
||
`define SHRG
|
||
//`ifdef CASS_EMU
|
||
//`ifdef CASS_EMU_16K
|
||
//`ifdef CASS_EMU_8K
|
||
//`ifdef CASS_EMU_4K
|
||
//`ifdef CASS_EMU_2K
|
||
|
||
//Switches
|
||
// 9 Latch BANK_4000
|
||
// 8 Latch BANK_4000
|
||
// 7 Latch BANK_4000
|
||
// 6 Latch BANK_0000
|
||
// 5 Latch BANK_0000
|
||
// 4 Latch BANK_0000
|
||
// 3
|
||
// 2 SHRG_EN
|
||
// 1 Dosrom Enable
|
||
// 0 Turbo
|
||
|
||
|
||
module LASER310_TOP(
|
||
input CLK50MHZ,
|
||
input CLK25MHZ,
|
||
input CLK10MHZ,
|
||
input RESET,//Active Low
|
||
output [7:0] VGA_RED,
|
||
output [7:0] VGA_GREEN,
|
||
output [7:0] VGA_BLUE,
|
||
output VGA_HS,
|
||
output VGA_VS,
|
||
output blank,
|
||
input VIDEO_MODE,
|
||
output [1:0] AUD_ADCDAT,
|
||
output [7:0] audio_s,
|
||
input key_strobe,
|
||
input key_pressed,
|
||
input [7:0] key_code,
|
||
input [9:0] SWITCH,
|
||
input UART_RXD,
|
||
output UART_TXD
|
||
|
||
|
||
reg [3:0] CLK;
|
||
|
||
reg MEM_OP_WR;
|
||
//reg MEM_RD;
|
||
(*keep*)reg GPIO_CPU_CLK;
|
||
// Processor
|
||
(*keep*)reg CPU_CLK;
|
||
(*keep*)wire[15:0] CPU_A;
|
||
(*keep*)wire [7:0] CPU_DI;
|
||
(*keep*)wire [7:0] CPU_DO;
|
||
(*keep*)wire CPU_RESET;
|
||
(*keep*)wire CPU_HALT;
|
||
(*keep*)wire CPU_MREQ;
|
||
(*keep*)wire CPU_RD;
|
||
(*keep*)wire CPU_WR;
|
||
(*keep*)wire CPU_IORQ;
|
||
(*keep*)reg CPU_INT;
|
||
(*keep*)wire CPU_M1;
|
||
wire CPU_BUSRQ;
|
||
wire CPU_BUSAK;
|
||
wire CPU_RFSH;
|
||
(*keep*)wire CPU_RESET_N;
|
||
(*keep*)wire CPU_HALT_N;
|
||
(*keep*)wire CPU_MREQ_N;
|
||
(*keep*)wire CPU_RD_N;
|
||
(*keep*)wire CPU_WR_N;
|
||
(*keep*)wire CPU_IORQ_N;
|
||
(*keep*)wire CPU_INT_N;
|
||
(*keep*)wire CPU_M1_N;
|
||
wire CPU_BUSRQ_N;
|
||
wire CPU_BUSAK_N;
|
||
wire CPU_RFSH_N;
|
||
// VRAM
|
||
(*keep*)wire[12:0] VRAM_ADDRESS;
|
||
(*keep*)wire VRAM_WR;
|
||
(*keep*)wire [7:0] VRAM_DATA_OUT;
|
||
(*keep*)wire VDG_RD;
|
||
(*keep*)wire[12:0] VDG_ADDRESS;
|
||
(*keep*)wire [7:0] VDG_DATA;
|
||
// ROM IO RAM
|
||
reg LATCHED_DOSROM_EN;
|
||
reg LATCHED_BOOTROM_EN;
|
||
reg LATCHED_AUTOSTARTROM_EN;
|
||
wire [7:0] SYS_ROM_DATA;
|
||
wire [7:0] DOS_ROM_DATA;
|
||
wire [7:0] AUTOSTART_ROM_DATA;
|
||
wire [7:0] BOOT_ROM_6000_DATA;
|
||
reg BOOTROM_EN;
|
||
reg [7:0] BOOTROM_BANK;
|
||
reg AUTOSTARTROM_EN;
|
||
reg [7:0] AUTOSTARTROM_BANK;
|
||
//wire [7:0] IO_DATA;
|
||
//wire [7:0] IO_WR;
|
||
wire RAM_16K_WR;
|
||
wire [7:0] RAM_16K_DATA_OUT;
|
||
wire RAM_78_WR;
|
||
wire [7:0] RAM_78_DATA;
|
||
wire RAM_16K_EXP_WR;
|
||
wire [7:0] RAM_16K_EXP_DATA_OUT;
|
||
wire RAM_89AB_WR;
|
||
wire [7:0] RAM_89AB_DATA;
|
||
wire RAM_CDEF_WR;
|
||
wire [7:0] RAM_CDEF_DATA;
|
||
wire [7:0] MEM_CDEF_DATA_OUT;
|
||
wire [7:0] RAM_89AB_DATA_OUT;
|
||
wire [7:0] RAM_CDEF_DATA_OUT;
|
||
wire ADDRESS_ROM;
|
||
wire ADDRESS_DOSROM;
|
||
wire ADDRESS_IO;
|
||
wire ADDRESS_VRAM;
|
||
wire ADDRESS_BOOTROM_6000;
|
||
wire ADDRESS_AUTOSTARTROM;
|
||
wire ADDRESS_89AB;
|
||
wire ADDRESS_CDEF;
|
||
wire ADDRESS_RAM_78;
|
||
wire ADDRESS_RAM_16K;
|
||
wire ADDRESS_RAM_16K_EXP;
|
||
wire ADDRESS_IO_SHRG;
|
||
wire ADDRESS_IO_BANK;
|
||
wire ADDRESS_RAM_CHIP;
|
||
reg [7:0] LATCHED_IO_DATA_WR;
|
||
//reg [7:0] LATCHED_IO_DATA_RD;
|
||
reg [7:0] LATCHED_BANK_0000;
|
||
reg [7:0] LATCHED_BANK_4000;
|
||
reg [7:0] LATCHED_BANK_C000;
|
||
reg [7:0] LATCHED_BANK_4DEF;
|
||
`ifdef SHRG
|
||
reg LATCHED_SHRG_EN;
|
||
reg [7:0] LATCHED_IO_SHRG;
|
||
`endif
|
||
|
||
// keyboard
|
||
reg [4:0] KB_CLK;
|
||
|
||
wire [7:0] SCAN;
|
||
wire PRESS;
|
||
wire PRESS_N;
|
||
wire EXTENDED;
|
||
|
||
reg [63:0] KEY;
|
||
reg [9:0] KEY_EX;
|
||
reg [11:0] KEY_Fxx;
|
||
wire [7:0] KEY_DATA;
|
||
//reg [63:0] LAST_KEY;
|
||
//reg CAPS_CLK;
|
||
//reg CAPS;
|
||
wire A_KEY_PRESSED;
|
||
|
||
reg [7:0] LATCHED_KEY_DATA;
|
||
|
||
// emu keyboard
|
||
wire [63:0] EMU_KEY;
|
||
wire [9:0] EMU_KEY_EX;
|
||
wire EMU_KEY_EN;
|
||
// cassette
|
||
|
||
(*keep*)wire [1:0] CASS_OUT;
|
||
(*keep*)wire CASS_IN;
|
||
(*keep*)wire CASS_IN_L;
|
||
(*keep*)wire CASS_IN_R;
|
||
|
||
|
||
// 用于外部磁带仿真计数
|
||
//(*keep*)reg EMU_CASS_CLK;
|
||
|
||
(*keep*)wire EMU_CASS_EN;
|
||
(*keep*)wire [1:0] EMU_CASS_DAT;
|
||
|
||
|
||
reg [16:0] RESET_KEY_COUNT;
|
||
wire RESET_KEY_N, RESET_N;
|
||
|
||
wire TURBO_SPEED = SWITCH[0];
|
||
|
||
|
||
RESET_DE RESET_DE(
|
||
.CLK(CLK50MHZ),
|
||
.SYS_RESET_N(RESET),
|
||
.RESET_N(RESET_N)
|
||
);
|
||
|
||
|
||
// 键盘 ctrl + f12 系统复位
|
||
assign RESET_KEY_N = RESET_KEY_COUNT[16];
|
||
|
||
reg [17:0] INT_CNT;
|
||
|
||
always @ (negedge CLK10MHZ)
|
||
case(INT_CNT[17:0])
|
||
18'd0:
|
||
begin
|
||
CPU_INT <= 1'b1;
|
||
INT_CNT <= 18'd1;
|
||
end
|
||
18'd640:
|
||
begin
|
||
CPU_INT <= 1'b0;
|
||
INT_CNT <= 18'd641;
|
||
end
|
||
18'd199999:
|
||
begin
|
||
INT_CNT <= 18'd0;
|
||
end
|
||
default:
|
||
begin
|
||
INT_CNT <= INT_CNT + 1;
|
||
end
|
||
endcase
|
||
|
||
always @(posedge CLK50MHZ or negedge RESET_N)
|
||
if(~RESET_N)
|
||
begin
|
||
CPU_CLK <= 1'b0;
|
||
GPIO_CPU_CLK <= 1'b0;
|
||
// 复位期间设置,避免拨动开关引起错误
|
||
LATCHED_DOSROM_EN <= SWITCH[1];
|
||
LATCHED_BANK_0000 <= {5'b0,SWITCH[6:4]};
|
||
LATCHED_BANK_4000 <= {5'b0,SWITCH[9:7]};
|
||
LATCHED_BOOTROM_EN <= BOOTROM_EN;
|
||
LATCHED_AUTOSTARTROM_EN <= AUTOSTARTROM_EN;
|
||
//LATCHED_BOOTROM_EN <= 1'b0;
|
||
`ifdef SHRG
|
||
LATCHED_IO_SHRG <= 8'b00001000;
|
||
// 复位期间设置,避免拨动开关引起错误
|
||
LATCHED_SHRG_EN <= SWITCH[2];
|
||
`endif
|
||
`ifdef IO_BANK
|
||
if(BOOTROM_EN)
|
||
LATCHED_BANK_C000 <= BOOTROM_BANK;
|
||
else
|
||
LATCHED_BANK_C000 <= 8'b0;
|
||
if(AUTOSTARTROM_EN)
|
||
LATCHED_BANK_4DEF <= AUTOSTARTROM_BANK;
|
||
else
|
||
LATCHED_BANK_4DEF <= 8'b0;
|
||
`endif
|
||
|
||
|
||
MEM_OP_WR <= 1'b0;
|
||
|
||
LATCHED_KEY_DATA <= 8'b0;
|
||
LATCHED_IO_DATA_WR <= 8'b0;
|
||
//EMU_CASS_CLK <= 1'b0;
|
||
CLK <= 4'd0;
|
||
end
|
||
else
|
||
begin
|
||
case (CLK[3:0])
|
||
4'd0:
|
||
begin
|
||
// 同步内存,等待读写信号建立
|
||
CPU_CLK <= 1'b1;
|
||
GPIO_CPU_CLK <= 1'b1;
|
||
MEM_OP_WR <= 1'b1;
|
||
//EMU_CASS_CLK <= ~EMU_CASS_CLK;
|
||
CLK <= 4'd1;
|
||
end
|
||
|
||
4'd1:
|
||
begin
|
||
// 同步内存,锁存读写信号和地址
|
||
CPU_CLK <= 1'b0;
|
||
MEM_OP_WR <= 1'b0;
|
||
LATCHED_KEY_DATA <= KEY_DATA;
|
||
if({CPU_MREQ,CPU_RD,CPU_WR,ADDRESS_IO}==4'b1011)
|
||
LATCHED_IO_DATA_WR <= CPU_DO;
|
||
`ifdef SHRG
|
||
if(LATCHED_SHRG_EN)
|
||
if({CPU_IORQ,CPU_RD,CPU_WR,ADDRESS_IO_SHRG}==4'b1011)
|
||
LATCHED_IO_SHRG <= CPU_DO;
|
||
`endif
|
||
`ifdef IO_BANK
|
||
if({CPU_IORQ,CPU_RD,CPU_WR,ADDRESS_IO_BANK}==4'b1011)
|
||
LATCHED_BANK_C000 <= CPU_DO;
|
||
`endif
|
||
CLK <= 4'd2;
|
||
end
|
||
|
||
4'd2:
|
||
begin
|
||
// 完成读写操作,开始输出
|
||
CPU_CLK <= 1'b0;
|
||
GPIO_CPU_CLK <= ~TURBO_SPEED;
|
||
|
||
MEM_OP_WR <= 1'b0;
|
||
CLK <= 4'd3;
|
||
end
|
||
4'd3:
|
||
begin
|
||
if(TURBO_SPEED)
|
||
CLK <= 4'd0;
|
||
else
|
||
CLK <= 4'd4;
|
||
end
|
||
4'd7:
|
||
begin
|
||
CPU_CLK <= 1'b0;
|
||
GPIO_CPU_CLK <= 1'b0;
|
||
MEM_OP_WR <= 1'b0;
|
||
CLK <= 4'd8;
|
||
end
|
||
4'd13:// 正常速度
|
||
begin
|
||
CPU_CLK <= 1'b0;
|
||
MEM_OP_WR <= 1'b0;
|
||
CLK <= 4'd0;
|
||
end
|
||
default:
|
||
begin
|
||
CPU_CLK <= 1'b0;
|
||
MEM_OP_WR <= 1'b0;
|
||
CLK <= CLK + 1'b1;
|
||
end
|
||
endcase
|
||
end
|
||
|
||
// CPU
|
||
assign CPU_RESET = ~RESET_N;
|
||
assign CPU_M1 = ~CPU_M1_N;
|
||
assign CPU_MREQ = ~CPU_MREQ_N;
|
||
assign CPU_IORQ = ~CPU_IORQ_N;
|
||
assign CPU_RD = ~CPU_RD_N;
|
||
assign CPU_WR = ~CPU_WR_N;
|
||
assign CPU_RFSH = ~CPU_RFSH_N;
|
||
assign CPU_HALT= ~CPU_HALT_N;
|
||
assign CPU_BUSAK = ~CPU_BUSAK_N;
|
||
assign CPU_RESET_N = ~CPU_RESET;
|
||
assign CPU_INT_N = VIDEO_MODE ? ~CPU_INT : ~VGA_VS;
|
||
assign CPU_BUSRQ_N = ~CPU_BUSRQ;
|
||
|
||
tv80s Z80CPU (
|
||
.m1_n(CPU_M1_N),
|
||
.mreq_n(CPU_MREQ_N),
|
||
.iorq_n(CPU_IORQ_N),
|
||
.rd_n(CPU_RD_N),
|
||
.wr_n(CPU_WR_N),
|
||
.rfsh_n(CPU_RFSH_N),
|
||
.halt_n(CPU_HALT_N),
|
||
.busak_n(CPU_BUSAK_N),
|
||
.A(CPU_A),
|
||
.dout(CPU_DO),
|
||
.reset_n(CPU_RESET_N),
|
||
.clk(CPU_CLK),
|
||
.wait_n(1'b1),
|
||
.int_n(CPU_INT_N),
|
||
.nmi_n(1'b1),
|
||
.busrq_n(CPU_BUSRQ_N),
|
||
.di(CPU_DI)
|
||
);
|
||
|
||
|
||
// 0000 -- 3FFF ROM 16KB
|
||
// 4000 -- 5FFF DOS
|
||
// 6000 -- 67FF BOOT ROM
|
||
// 6800 -- 6FFF I/O
|
||
// 7000 -- 77FF VRAM 2KB (SRAM 6116)
|
||
// 7800 -- 7FFF RAM 2KB
|
||
// 8000 -- B7FF RAM 14KB
|
||
// B800 -- BFFF RAM ext 2KB
|
||
// C000 -- F7FF RAM ext 14KB
|
||
|
||
assign ADDRESS_ROM = (CPU_A[15:14] == 2'b00)?1'b1:1'b0;
|
||
assign ADDRESS_DOSROM = (CPU_A[15:13] == 3'b010)?LATCHED_DOSROM_EN:1'b0;
|
||
assign ADDRESS_BOOTROM_6000 = (CPU_A[15:11] == 5'b01100)?LATCHED_BOOTROM_EN:1'b0;
|
||
assign ADDRESS_AUTOSTARTROM = (CPU_A[15:12] == 4'h4||CPU_A[15:12] == 4'hD||CPU_A[15:12] == 4'hE||CPU_A[15:12] == 4'hF)?LATCHED_AUTOSTARTROM_EN:1'b0;
|
||
assign ADDRESS_IO = (CPU_A[15:11] == 5'b01101)?1'b1:1'b0;
|
||
assign ADDRESS_VRAM = (CPU_A[15:11] == 5'b01110)?1'b1:1'b0;
|
||
assign ADDRESS_89AB = (CPU_A[15:14] == 2'b10)?1'b1:1'b0;
|
||
assign ADDRESS_CDEF = (CPU_A[15:14] == 2'b11)?1'b1:1'b0;
|
||
// 7800 -- 7FFF RAM 2KB
|
||
assign ADDRESS_RAM_78 = (CPU_A[15:11] == 5'b01111)?1'b1:1'b0;
|
||
// 7800 -- 7FFF RAM 2KB
|
||
// 8000 -- B7FF RAM 14KB
|
||
|
||
assign ADDRESS_RAM_16K = (CPU_A[15:12] == 4'h8)?1'b1:
|
||
(CPU_A[15:12] == 4'h9)?1'b1:
|
||
(CPU_A[15:12] == 4'hA)?1'b1:
|
||
(CPU_A[15:11] == 5'b01111)?1'b1:
|
||
(CPU_A[15:11] == 5'b10110)?1'b1:
|
||
1'b0;
|
||
|
||
// B800 -- BFFF RAM ext 2KB
|
||
// C000 -- F7FF RAM ext 14KB
|
||
|
||
assign ADDRESS_RAM_16K_EXP = (CPU_A[15:12] == 4'hC)?1'b1:
|
||
(CPU_A[15:12] == 4'hD)?1'b1:
|
||
(CPU_A[15:12] == 4'hE)?1'b1:
|
||
(CPU_A[15:11] == 5'b10111)?1'b1:
|
||
(CPU_A[15:11] == 5'b11110)?1'b1:
|
||
1'b0;
|
||
|
||
assign ADDRESS_IO_SHRG = (CPU_A[7:0] == 8'd32)?1'b1:1'b0;
|
||
|
||
// 64K RAM expansion cartridge vz300_review.pdf 中的端口号是 IO 7FH 127
|
||
// 128K SIDEWAYS RAM SHRG2 HVVZUG23 (Mar-Apr 1989).PDF 中的端口号是 IO 112
|
||
|
||
assign ADDRESS_IO_BANK = (CPU_A[7:0] == 8'd127 || CPU_A[7:0] == 8'd112)?1'b1:1'b0;
|
||
|
||
|
||
|
||
|
||
`ifdef RAM_16K_EXPANSION
|
||
assign ADDRESS_RAM_CHIP = ADDRESS_RAM_16K|ADDRESS_RAM_16K_EXP;
|
||
`else
|
||
assign ADDRESS_RAM_CHIP = ADDRESS_RAM_16K;
|
||
`endif
|
||
|
||
|
||
|
||
assign VRAM_WR = ({ADDRESS_VRAM,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
assign RAM_78_WR = ({ADDRESS_RAM_78,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
assign RAM_16K_WR = ({ADDRESS_RAM_16K,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
assign RAM_16K_EXP_WR = ({ADDRESS_RAM_16K_EXP,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
|
||
|
||
assign RAM_89AB_WR = ({ADDRESS_89AB,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
assign RAM_CDEF_WR = ({ADDRESS_CDEF,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
|
||
assign RAM_89AB_WR = ({ADDRESS_89AB,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
assign RAM_CDEF_WR = ({ADDRESS_CDEF,MEM_OP_WR,CPU_WR,CPU_IORQ} == 4'b1110)?1'b1:1'b0;
|
||
|
||
|
||
assign CPU_DI = ADDRESS_ROM ? SYS_ROM_DATA :
|
||
ADDRESS_AUTOSTARTROM ? AUTOSTART_ROM_DATA :
|
||
ADDRESS_DOSROM ? DOS_ROM_DATA :
|
||
`ifdef BOOT_ROM_6000
|
||
ADDRESS_BOOTROM_6000 ? BOOT_ROM_6000_DATA :
|
||
`endif
|
||
ADDRESS_IO ? LATCHED_KEY_DATA :
|
||
ADDRESS_VRAM ? VRAM_DATA_OUT :
|
||
`ifdef BASE_RAM_16K
|
||
ADDRESS_RAM_16K ? RAM_16K_DATA_OUT :
|
||
`endif
|
||
`ifdef RAM_16K_EXPANSION
|
||
ADDRESS_RAM_16K_EXP ? RAM_16K_EXP_DATA_OUT :
|
||
`endif
|
||
8'hzz;
|
||
|
||
|
||
|
||
|
||
`ifdef BASE_SYS_ROM
|
||
sprom #(
|
||
.init_file("./roms/sysrom.mif"),
|
||
.widthad_a(14),
|
||
.width_a(8))
|
||
sys_rom(
|
||
.address(CPU_A[13:0]),
|
||
.clock(CLK50MHZ),
|
||
.q(SYS_ROM_DATA)
|
||
);
|
||
`endif
|
||
|
||
`ifdef BASE_DOS_ROM
|
||
sprom #(
|
||
.init_file("./roms/dosrom.mif"),
|
||
.widthad_a(13),
|
||
.width_a(8))
|
||
DOS_ROM(
|
||
.address(CPU_A[12:0]),
|
||
.clock(CLK50MHZ),
|
||
.q(DOS_ROM_DATA)
|
||
);
|
||
`endif
|
||
|
||
`ifdef BOOT_ROM_6000
|
||
sprom #(
|
||
.init_file("./roms/boot_rom_6000.mif"),
|
||
.widthad_a(9),
|
||
.width_a(8))
|
||
BOOT_ROM(
|
||
.address(CPU_A[8:0]),
|
||
.clock(CLK50MHZ),
|
||
.q(BOOT_ROM_6000_DATA)
|
||
);
|
||
`endif
|
||
|
||
`ifdef BASE_RAM_78
|
||
spram #(
|
||
. addr_width_g(11),
|
||
.data_width_g(8))
|
||
BASE_RAM78(
|
||
.address(CPU_A[10:0]),
|
||
.clken(1),
|
||
.clock(CLK50MHZ),
|
||
.data(CPU_DO),
|
||
.wren(CPU_MREQ & RAM_78_WR),
|
||
.q(RAM_78_DATA)
|
||
);
|
||
`endif
|
||
|
||
`ifdef BASE_RAM_16K
|
||
spram #(
|
||
. addr_width_g(14),
|
||
.data_width_g(8))
|
||
BASE_RAM16k(
|
||
.address(CPU_A[13:0]),
|
||
.clken(1),
|
||
.clock(CLK50MHZ),
|
||
.data(CPU_DO),
|
||
.wren(CPU_MREQ & RAM_16K_WR),
|
||
.q(RAM_16K_DATA_OUT)
|
||
);
|
||
`else
|
||
assign RAM_16K_DATA_OUT = 8'bz;
|
||
`endif
|
||
|
||
`ifdef RAM_16K_EXPANSION
|
||
spram #(
|
||
. addr_width_g(14),
|
||
.data_width_g(8))
|
||
BASE_RAM16kex(
|
||
.address(CPU_A[13:0]),
|
||
.clken(1),
|
||
.clock(CLK50MHZ),
|
||
.data(CPU_DO),
|
||
.wren(CPU_MREQ & RAM_16K_EXP_WR),
|
||
.q(RAM_16K_EXP_DATA_OUT)
|
||
);
|
||
`else
|
||
assign RAM_16K_EXP_DATA_OUT = 8'bz;
|
||
`endif
|
||
|
||
|
||
`ifdef VRAM_2K
|
||
dpram #(
|
||
.addr_width_g(11),
|
||
.data_width_g(8))
|
||
vram_2k(
|
||
.clk_a_i(CLK50MHZ),
|
||
.en_a_i(1),
|
||
.we_i(CPU_MREQ & VRAM_WR),
|
||
.addr_a_i(CPU_A[10:0]),
|
||
.data_a_i(CPU_DO),
|
||
.data_a_o(VRAM_DATA_OUT),
|
||
.clk_b_i(VDG_RD),
|
||
.addr_b_i(VDG_ADDRESS[10:0]),
|
||
.data_b_o(VDG_DATA)
|
||
);
|
||
`endif
|
||
|
||
|
||
`ifdef VRAM_8K
|
||
dpram #(
|
||
.addr_width_g(13),
|
||
.data_width_g(8))
|
||
vram_8k(
|
||
.clk_a_i(CLK50MHZ),
|
||
.en_a_i(1),
|
||
.we_i(CPU_MREQ & VRAM_WR),
|
||
.addr_a_i({LATCHED_IO_SHRG[1:0],CPU_A[10:0]}),
|
||
.data_a_i(CPU_DO),
|
||
.data_a_o(VRAM_DATA_OUT),
|
||
.clk_b_i(VDG_RD),
|
||
.addr_b_i(VDG_ADDRESS[12:0]),
|
||
.data_b_o(VDG_DATA)
|
||
);
|
||
`endif
|
||
|
||
MC6847_VGA MC6847_VGA(
|
||
.PIX_CLK(CLK25MHZ),
|
||
.RESET_N(RESET_N),
|
||
.RD(VDG_RD),
|
||
.DD(VDG_DATA),
|
||
.DA(VDG_ADDRESS),
|
||
.AG(LATCHED_IO_DATA_WR[3]),
|
||
.AS(1'b0),
|
||
.EXT(1'b0),
|
||
.INV(1'b0),
|
||
`ifdef SHRG
|
||
.GM(LATCHED_IO_SHRG[4:2]),
|
||
`else
|
||
.GM(3'b010),
|
||
`endif
|
||
.CSS(LATCHED_IO_DATA_WR[4]),
|
||
// vga
|
||
.blank(blank),
|
||
.VGA_OUT_HSYNC(VGA_HS),
|
||
.VGA_OUT_VSYNC(VGA_VS),
|
||
.VGA_OUT_RED(VGA_RED),
|
||
.VGA_OUT_GREEN(VGA_GREEN),
|
||
.VGA_OUT_BLUE(VGA_BLUE)
|
||
);
|
||
|
||
|
||
// keyboard
|
||
|
||
/*****************************************************************************
|
||
* Convert PS/2 keyboard to ASCII keyboard
|
||
******************************************************************************/
|
||
|
||
/*
|
||
KD5 KD4 KD3 KD2 KD1 KD0 扫描用地址
|
||
A0 R Q E W T 68FEH 0
|
||
A1 F A D CTRL S G 68FDH 8
|
||
A2 V Z C SHFT X B 68FBH 16
|
||
A3 4 1 3 2 5 68F7H 24
|
||
A4 M 空格 , . N 68EFH 32
|
||
A5 7 0 8 - 9 6 68DFH 40
|
||
A6 U P I RETN O Y 68BFH 48
|
||
A7 J ; K : L H 687FH 56
|
||
*/
|
||
|
||
// 7: 0
|
||
// 15: 8
|
||
// 23:16
|
||
// 31:24
|
||
// 39:32
|
||
// 47:40
|
||
// 55:48
|
||
// 63:56
|
||
|
||
|
||
|
||
// 键盘检测的方法,就是循环地问每一行线发送低电平信号,也就是用该地址线为“0”的地址去读取数据。
|
||
// 例如,检测第一行时,使A0为0,其余为1;加上选通IC4的高五位地址01101,成为01101***11111110B(A8~A10不起作用,
|
||
// 可为任意值,故68FEH,69FEH,6AFEH,6BFEH,6CFEH,6DFEH,6EFEH,6FFEH均可)。
|
||
// 读 6800H 判断是否有按键按下。
|
||
|
||
// The method of keyboard detection is to cyclically ask each line to send a low level signal,
|
||
// that is, to read the data with the address line "0".
|
||
// For example, when detecting the first line, make A0 0 and the rest 1; plus the high five-bit address 01101 of the strobe IC4,
|
||
// become 01101***11111110B (A8~A10 does not work,
|
||
// It can be any value, so 68FEH, 69FEH, 6AFEH, 6BFEH, 6CFEH, 6DFEH, 6EFEH, 6FFEH can be).
|
||
// Read 6800H to determine if there is a button press.
|
||
|
||
// 键盘选通,整个竖列有一个选通的位置被按下,对应值为0。
|
||
// The keyboard is strobed, and a strobe position is pressed in the entire vertical column, and the corresponding value is 0.
|
||
|
||
// 键盘扩展
|
||
// 加入方向键盘
|
||
// Keyboard extension
|
||
|
||
// left: ctrl M 37 KEY_EX[5]
|
||
// right: ctrl , 35 KEY_EX[6]
|
||
// up: ctrl . 33 KEY_EX[4]
|
||
// down: ctrl space 36 KEY_EX[7]
|
||
// esc: ctrl - 42 KEY_EX[3]
|
||
// backspace: ctrl M 37 KEY_EX[8]
|
||
|
||
// R-Shift
|
||
|
||
|
||
wire [63:0] KEY_C = EMU_KEY_EN?EMU_KEY:KEY;
|
||
wire [9:0] KEY_EX_C = EMU_KEY_EN?EMU_KEY_EX:KEY_EX;
|
||
|
||
//wire KEY_CTRL_ULRD = (KEY_EX[7:4]==4'b1111);
|
||
wire KEY_CTRL_ULRD_BRK = (KEY_EX[8:3]==6'b111111);
|
||
|
||
wire KEY_DATA_BIT5 = (CPU_A[7:0]|{KEY_C[61], KEY_C[53], KEY_C[45], KEY_C[37]&KEY_EX_C[5]&KEY_EX_C[8], KEY_C[29], KEY_C[21], KEY_C[13], KEY_C[ 5]})==8'hff;
|
||
wire KEY_DATA_BIT4 = (CPU_A[7:0]|{KEY_C[60], KEY_C[52], KEY_C[44], KEY_C[36]&KEY_EX_C[7], KEY_C[28], KEY_C[20], KEY_C[12], KEY_C[ 4]})==8'hff;
|
||
wire KEY_DATA_BIT3 = (CPU_A[7:0]|{KEY_C[59], KEY_C[51], KEY_C[43], KEY_C[35]&KEY_EX_C[6], KEY_C[27], KEY_C[19], KEY_C[11], KEY_C[ 3]})==8'hff;
|
||
wire KEY_DATA_BIT2 = (CPU_A[7:0]|{KEY_C[58], KEY_C[50], KEY_C[42]&KEY_EX_C[3], KEY_C[34], KEY_C[26], KEY_C[18]&KEY_EX_C[0], KEY_C[10]&KEY_CTRL_ULRD_BRK, KEY_C[ 2]})==8'hff;
|
||
wire KEY_DATA_BIT1 = (CPU_A[7:0]|{KEY_C[57], KEY_C[49], KEY_C[41], KEY_C[33]&KEY_EX_C[4], KEY_C[25], KEY_C[17], KEY_C[ 9], KEY_C[ 1]})==8'hff;
|
||
wire KEY_DATA_BIT0 = (CPU_A[7:0]|{KEY_C[56], KEY_C[48], KEY_C[40], KEY_C[32], KEY_C[24], KEY_C[16], KEY_C[ 8], KEY_C[ 0]})==8'hff;
|
||
|
||
/*
|
||
wire KEY_DATA_BIT5 = (CPU_A[7:0]|{KEY[61], KEY[53], KEY[45], KEY[37], KEY[29], KEY[21], KEY[13], KEY[ 5]})==8'hff;
|
||
wire KEY_DATA_BIT4 = (CPU_A[7:0]|{KEY[60], KEY[52], KEY[44], KEY[36], KEY[28], KEY[20], KEY[12], KEY[ 4]})==8'hff;
|
||
wire KEY_DATA_BIT3 = (CPU_A[7:0]|{KEY[59], KEY[51], KEY[43], KEY[35], KEY[27], KEY[19], KEY[11], KEY[ 3]})==8'hff;
|
||
wire KEY_DATA_BIT2 = (CPU_A[7:0]|{KEY[58], KEY[50], KEY[42], KEY[34], KEY[26], KEY[18], KEY[10], KEY[ 2]})==8'hff;
|
||
wire KEY_DATA_BIT1 = (CPU_A[7:0]|{KEY[57], KEY[49], KEY[41], KEY[33], KEY[25], KEY[17], KEY[ 9], KEY[ 1]})==8'hff;
|
||
wire KEY_DATA_BIT0 = (CPU_A[7:0]|{KEY[56], KEY[48], KEY[40], KEY[32], KEY[24], KEY[16], KEY[ 8], KEY[ 0]})==8'hff;
|
||
*/
|
||
|
||
wire KEY_DATA_BIT7 = 1'b1; // 没有空置,具体用途没有理解
|
||
//wire KEY_DATA_BIT6 = CASS_IN;
|
||
wire KEY_DATA_BIT6 = ~CASS_IN;
|
||
|
||
assign KEY_DATA = { KEY_DATA_BIT7, KEY_DATA_BIT6, KEY_DATA_BIT5, KEY_DATA_BIT4, KEY_DATA_BIT3, KEY_DATA_BIT2, KEY_DATA_BIT1, KEY_DATA_BIT0 };
|
||
|
||
/*
|
||
assign KEY_DATA = (CPU_A[0]==1'b0) ? KEY[ 7: 0] :
|
||
(CPU_A[1]==1'b0) ? KEY[15: 8] :
|
||
(CPU_A[2]==1'b0) ? KEY[23:16] :
|
||
(CPU_A[3]==1'b0) ? KEY[31:24] :
|
||
(CPU_A[4]==1'b0) ? KEY[39:32] :
|
||
(CPU_A[5]==1'b0) ? KEY[47:40] :
|
||
(CPU_A[6]==1'b0) ? KEY[55:48] :
|
||
(CPU_A[7]==1'b0) ? KEY[63:56] :
|
||
8'hff;
|
||
|
||
assign KEY_DATA =
|
||
(CPU_A[7]==1'b0) ? KEY[63:56] :
|
||
(CPU_A[6]==1'b0) ? KEY[55:48] :
|
||
(CPU_A[5]==1'b0) ? KEY[47:40] :
|
||
(CPU_A[4]==1'b0) ? KEY[39:32] :
|
||
(CPU_A[3]==1'b0) ? KEY[31:24] :
|
||
(CPU_A[2]==1'b0) ? KEY[23:16] :
|
||
(CPU_A[1]==1'b0) ? KEY[15: 8] :
|
||
(CPU_A[0]==1'b0) ? KEY[ 7: 0] :
|
||
8'hff;
|
||
*/
|
||
|
||
|
||
assign A_KEY_PRESSED = (KEY[63:0] == 64'hFFFFFFFFFFFFFFFF) ? 1'b0:1'b1;
|
||
|
||
always @(posedge KB_CLK[3] or negedge RESET)
|
||
begin
|
||
if(~RESET)
|
||
begin
|
||
KEY <= 64'hFFFFFFFFFFFFFFFF;
|
||
KEY_EX <= 10'h3FF;
|
||
KEY_Fxx <= 12'h000;
|
||
// CAPS_CLK <= 1'b0;
|
||
RESET_KEY_COUNT <= 17'h1FFFF;
|
||
|
||
BOOTROM_BANK <= 0;
|
||
BOOTROM_EN <= 1'b0;
|
||
|
||
AUTOSTARTROM_BANK <= 0;
|
||
AUTOSTARTROM_EN <= 1'b0;
|
||
end
|
||
else
|
||
begin
|
||
//KEY[?] <= CAPS;
|
||
if(RESET_KEY_COUNT[16]==1'b0)
|
||
RESET_KEY_COUNT <= RESET_KEY_COUNT+1;
|
||
|
||
case(key_code)
|
||
8'h07:
|
||
begin
|
||
KEY_Fxx[11] <= PRESS; // F12 RESET
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b0;
|
||
BOOTROM_BANK <= 0;
|
||
AUTOSTARTROM_EN <= 1'b0;
|
||
AUTOSTARTROM_BANK <= 0;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h78: KEY_Fxx[10] <= PRESS; // F11
|
||
8'h09: KEY_Fxx[ 9] <= PRESS; // F10 CASS STOP
|
||
8'h01: KEY_Fxx[ 8] <= PRESS; // F9 CASS PLAY
|
||
8'h0A:
|
||
begin
|
||
KEY_Fxx[ 7] <= PRESS; // F8 Ctrl or L-Shift BOOT 8
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 39;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 23;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h83:
|
||
begin
|
||
KEY_Fxx[ 6] <= PRESS; // F7 Ctrl or L-Shift BOOT 7
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 38;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 22;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h0B:
|
||
begin
|
||
KEY_Fxx[ 5] <= PRESS; // F6 Ctrl or L-Shift BOOT 6
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 37;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 21;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h03:
|
||
begin
|
||
KEY_Fxx[ 4] <= PRESS; // F5 Ctrl or L-Shift BOOT 5
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 36;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 20;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h0C:
|
||
begin
|
||
KEY_Fxx[ 3] <= PRESS; // F4 Ctrl or L-Shift BOOT 4
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 35;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 19;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h04:
|
||
begin
|
||
KEY_Fxx[ 2] <= PRESS; // F3 Ctrl or L-Shift BOOT 3
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 34;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 18;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h06:
|
||
begin
|
||
KEY_Fxx[ 1] <= PRESS; // F2 Ctrl or L-Shift BOOT 2
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 33;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 17;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
8'h05:
|
||
begin
|
||
KEY_Fxx[ 0] <= PRESS; // F1 Ctrl or L-Shift BOOT 1
|
||
if(PRESS && (KEY[18]==PRESS_N))
|
||
begin
|
||
BOOTROM_EN <= 1'b1;
|
||
BOOTROM_BANK <= 32;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
else
|
||
if(PRESS && (KEY[10]==PRESS_N))
|
||
begin
|
||
AUTOSTARTROM_EN <= 1'b1;
|
||
AUTOSTARTROM_BANK <= 16;
|
||
RESET_KEY_COUNT <= 17'h0;
|
||
end
|
||
end
|
||
|
||
8'h16: KEY[28] <= PRESS_N; // 1 !
|
||
8'h1E: KEY[25] <= PRESS_N; // 2 @
|
||
8'h26: KEY[27] <= PRESS_N; // 3 #
|
||
8'h25: KEY[29] <= PRESS_N; // 4 $
|
||
8'h2E: KEY[24] <= PRESS_N; // 5 %
|
||
8'h36: KEY[40] <= PRESS_N; // 6 ^
|
||
8'h3D: KEY[45] <= PRESS_N; // 7 &
|
||
// 8'h0D: KEY[?] <= PRESS_N; // TAB
|
||
8'h3E: KEY[43] <= PRESS_N; // 8 *
|
||
8'h46: KEY[41] <= PRESS_N; // 9 (
|
||
8'h45: KEY[44] <= PRESS_N; // 0 )
|
||
8'h4E: KEY[42] <= PRESS_N; // - _
|
||
// 8'h55: KEY[?] <= PRESS_N; // = +
|
||
8'h66: KEY_EX[8] <= PRESS_N; // backspace
|
||
// 8'h0E: KEY[?] <= PRESS_N; // ` ~
|
||
// 8'h5D: KEY[?] <= PRESS_N; // \ |
|
||
8'h49: KEY[33] <= PRESS_N; // . >
|
||
8'h4b: KEY[57] <= PRESS_N; // L
|
||
8'h44: KEY[49] <= PRESS_N; // O
|
||
// 8'h11 KEY[?] <= PRESS_N; // line feed (really right ALT (Extended) see below
|
||
8'h5A: KEY[50] <= PRESS_N; // CR
|
||
// 8'h54: KEY[?] <= PRESS_N; // [ {
|
||
// 8'h5B: KEY[?] <= PRESS_N; // ] }
|
||
8'h52: KEY[58] <= PRESS_N; // ' "
|
||
8'h1D: KEY[ 1] <= PRESS_N; // W
|
||
8'h24: KEY[ 3] <= PRESS_N; // E
|
||
8'h2D: KEY[ 5] <= PRESS_N; // R
|
||
8'h2C: KEY[ 0] <= PRESS_N; // T
|
||
8'h35: KEY[48] <= PRESS_N; // Y
|
||
8'h3C: KEY[53] <= PRESS_N; // U
|
||
8'h43: KEY[51] <= PRESS_N; // I
|
||
8'h1B: KEY[ 9] <= PRESS_N; // S
|
||
8'h23: KEY[11] <= PRESS_N; // D
|
||
8'h2B: KEY[13] <= PRESS_N; // F
|
||
8'h34: KEY[ 8] <= PRESS_N; // G
|
||
8'h33: KEY[56] <= PRESS_N; // H
|
||
8'h3B: KEY[61] <= PRESS_N; // J
|
||
8'h42: KEY[59] <= PRESS_N; // K
|
||
8'h22: KEY[17] <= PRESS_N; // X
|
||
8'h21: KEY[19] <= PRESS_N; // C
|
||
8'h2a: KEY[21] <= PRESS_N; // V
|
||
8'h32: KEY[16] <= PRESS_N; // B
|
||
8'h31: KEY[32] <= PRESS_N; // N
|
||
8'h3a: KEY[37] <= PRESS_N; // M
|
||
8'h41: KEY[35] <= PRESS_N; // , <
|
||
8'h15: KEY[ 4] <= PRESS_N; // Q
|
||
8'h1C: KEY[12] <= PRESS_N; // A
|
||
8'h1A: KEY[20] <= PRESS_N; // Z
|
||
8'h29: KEY[36] <= PRESS_N; // Space
|
||
// 8'h4A: KEY[?] <= PRESS_N; // / ?
|
||
8'h4C: KEY[60] <= PRESS_N; // ; :
|
||
8'h4D: KEY[52] <= PRESS_N; // P
|
||
8'h14: KEY[10] <= PRESS_N; // Ctrl either left or right
|
||
8'h12: KEY[18] <= PRESS_N; // L-Shift
|
||
8'h59: KEY_EX[0] <= PRESS_N; // R-Shift
|
||
8'h11:
|
||
begin
|
||
if(~EXTENDED)
|
||
KEY_EX[1] <= PRESS_N; // Repeat really left ALT
|
||
else
|
||
KEY_EX[2] <= PRESS_N; // LF really right ALT
|
||
end
|
||
8'h76: KEY_EX[3] <= PRESS_N; // Esc
|
||
8'h75: KEY_EX[4] <= PRESS_N; // up
|
||
8'h6B: KEY_EX[5] <= PRESS_N; // left
|
||
8'h74: KEY_EX[6] <= PRESS_N; // right
|
||
8'h72: KEY_EX[7] <= PRESS_N; // down
|
||
endcase
|
||
end
|
||
end
|
||
|
||
|
||
|
||
|
||
always @ (posedge CLK50MHZ) // 50MHz
|
||
KB_CLK <= KB_CLK + 1'b1; // 50/32 = 1.5625 MHz
|
||
|
||
assign PRESS_N = ~key_pressed;
|
||
|
||
|
||
`ifdef CASS_EMU
|
||
|
||
wire CASS_BUF_RD;
|
||
wire [15:0] CASS_BUF_A;
|
||
wire CASS_BUF_WR;
|
||
wire [7:0] CASS_BUF_DAT;
|
||
wire [7:0] CASS_BUF_Q;
|
||
|
||
// F9 CASS PLAY
|
||
// F10 CASS STOP
|
||
|
||
EMU_CASS_KEY EMU_CASS_KEY(
|
||
KEY_Fxx[8],
|
||
KEY_Fxx[9],
|
||
// cass emu
|
||
CASS_BUF_RD,
|
||
//
|
||
CASS_BUF_A,
|
||
CASS_BUF_WR,
|
||
CASS_BUF_DAT,
|
||
CASS_BUF_Q,
|
||
// Control Signals
|
||
EMU_CASS_EN,
|
||
EMU_CASS_DAT,
|
||
|
||
// key emu
|
||
EMU_KEY,
|
||
EMU_KEY_EX,
|
||
EMU_KEY_EN,
|
||
/*
|
||
* UART: 115200 bps, 8N1
|
||
*/
|
||
UART_RXD,
|
||
UART_TXD,
|
||
|
||
// System
|
||
TURBO_SPEED,
|
||
// Clock: 10MHz
|
||
CLK10MHZ,
|
||
RESET_N
|
||
);
|
||
|
||
|
||
`ifdef CASS_EMU_16K
|
||
|
||
cass_ram_16k_altera cass_buf(
|
||
.address(CASS_BUF_A[13:0]),
|
||
.clock(CLK10MHZ),
|
||
.data(CASS_BUF_DI),
|
||
.wren(CASS_BUF_WR),
|
||
.q(CASS_BUF_Q)
|
||
);
|
||
|
||
`endif
|
||
|
||
|
||
`ifdef CASS_EMU_8K
|
||
|
||
cass_ram_8k_altera cass_buf(
|
||
.address(CASS_BUF_A[12:0]),
|
||
.clock(CLK10MHZ),
|
||
.data(CASS_BUF_DI),
|
||
.wren(CASS_BUF_WR),
|
||
.q(CASS_BUF_Q)
|
||
);
|
||
|
||
`endif
|
||
|
||
|
||
`ifdef CASS_EMU_4K
|
||
|
||
cass_ram_4k_altera cass_buf(
|
||
.address(CASS_BUF_A[11:0]),
|
||
.clock(CLK10MHZ),
|
||
.data(CASS_BUF_DAT),
|
||
.wren(CASS_BUF_WR),
|
||
.q(CASS_BUF_Q)
|
||
);
|
||
|
||
`endif
|
||
|
||
|
||
`ifdef CASS_EMU_2K
|
||
|
||
cass_ram_2k_altera cass_buf(
|
||
.address(CASS_BUF_A[10:0]),
|
||
.clock(CLK10MHZ),
|
||
.data(CASS_BUF_DAT),
|
||
.wren(CASS_BUF_WR),
|
||
.q(CASS_BUF_Q)
|
||
);
|
||
|
||
`endif
|
||
|
||
`endif
|
||
|
||
sn76489_top #(
|
||
.clock_div_16_g(1))
|
||
sn76489(
|
||
.clock_i(CLK25MHZ),
|
||
.clock_en_i(CPU_CLK),
|
||
.res_n_i(RESET),
|
||
.ce_n_i(),//todo
|
||
.we_n_i(),//todo
|
||
.ready_o(),
|
||
.d_i(CPU_DO),
|
||
.aout_o(audio_s)
|
||
);
|
||
|
||
assign CASS_OUT = EMU_CASS_EN ? EMU_CASS_DAT : {LATCHED_IO_DATA_WR[2], 1'b0};
|
||
|
||
(*keep*)wire trap = (CPU_RD|CPU_WR) && (CPU_A[15:12] == 4'h0);
|
||
|
||
assign AUD_ADCDAT = {LATCHED_IO_DATA_WR[0],LATCHED_IO_DATA_WR[5]};
|
||
|
||
|
||
// floppy
|
||
wire ADDRESS_IO_FDC;
|
||
wire ADDRESS_IO_FDC_CT;
|
||
wire ADDRESS_IO_FDC_DATA;
|
||
wire ADDRESS_IO_FDC_POLL;
|
||
wire ADDRESS_IO_FDC_WP;
|
||
reg [7:0] LATCHED_IO_FDC;
|
||
reg [7:0] LATCHED_IO_FDC_CT;
|
||
reg [7:0] LATCHED_RAM_DATA_FDC;
|
||
|
||
// floppy
|
||
(*keep*)wire FDC_RAM_R;
|
||
(*keep*)wire FDC_RAM_W;
|
||
(*keep*)wire [17:0] FDC_RAM_ADDR_R;
|
||
(*keep*)wire [17:0] FDC_RAM_ADDR_W;
|
||
reg [7:0] LAST_WRITE_DATA;
|
||
(*keep*)wire [7:0] FDC_RAM_DATA_W;
|
||
|
||
(*keep*)wire [7:0] FLOPPY_RD_DATA;
|
||
(*keep*)wire [7:0] FLOPPY_DATA;
|
||
|
||
// FDC
|
||
// if({CPU_IORQ,CPU_RD,CPU_WR,ADDRESS_IO_FDC_CT}==4'b1011)
|
||
// LATCHED_IO_FDC_CT <= CPU_DO;
|
||
|
||
// if({CPU_IORQ,CPU_RD,CPU_WR}==3'b110)
|
||
// LATCHED_IO_FDC <= ADDRESS_IO_FDC_POLL ? {FDC_POLL, 7'h7F} :
|
||
// ADDRESS_IO_FDC_DATA ? FDC_DATA :
|
||
// ADDRESS_IO_FDC_WP ? {FDC_WP, 7'h7F} :
|
||
// 8'hFF;
|
||
wire FLOPPY_WP_READ = 1'b0;
|
||
wire RAM_ADDRESS_FD_R = FDC_RAM_ADDR_R;
|
||
wire RAM_ADDRESS_FD_W = FDC_RAM_ADDR_W;
|
||
|
||
assign ADDRESS_IO_FDC = (CPU_A[7:2] == 6'b000100)?1'b1:1'b0;
|
||
|
||
assign ADDRESS_IO_FDC_CT = (CPU_A[7:0] == 8'h10)?1'b1:1'b0;
|
||
assign ADDRESS_IO_FDC_DATA = (CPU_A[7:0] == 8'h11)?1'b1:1'b0;
|
||
assign ADDRESS_IO_FDC_POLL = (CPU_A[7:0] == 8'h12)?1'b1:1'b0;
|
||
assign ADDRESS_IO_FDC_WP = (CPU_A[7:0] == 8'h13)?1'b1:1'b0;
|
||
|
||
|
||
wire [7:0] FDC_DATA;
|
||
wire FDC_POLL;
|
||
wire FDC_WP;
|
||
|
||
wire [7:0] SECTOR_BYTE;
|
||
wire [7:0] TRACK1_NO;
|
||
wire [7:0] TRACK2_NO;
|
||
wire DRIVE1;
|
||
wire DRIVE2;
|
||
wire MOTOR;
|
||
|
||
wire FDC_IO_R;
|
||
wire FDC_IO_W;
|
||
|
||
wire FDC_SIG;
|
||
wire FDC_SIG_CLK;
|
||
|
||
wire FDC_IO = (CPU_IORQ&ADDRESS_IO_FDC);
|
||
wire FDC_IO_POLL = (CPU_IORQ&ADDRESS_IO_FDC_POLL);
|
||
wire FDC_IO_DATA = (CPU_IORQ&ADDRESS_IO_FDC_DATA);
|
||
wire FDC_IO_CT = (CPU_IORQ&ADDRESS_IO_FDC_CT);
|
||
|
||
FDC_IF FDC_U (
|
||
.FDC_CLK(CPU_CLK),
|
||
.RESET_N(RESET_N),
|
||
.SW(SWITCH[3:2]),
|
||
.DBG(SWITCH[9:6]),
|
||
|
||
.FDC_RAM_R(FDC_RAM_R),
|
||
.FDC_RAM_W(FDC_RAM_W),
|
||
.FDC_RAM_ADDR_R(FDC_RAM_ADDR_R),
|
||
.FDC_RAM_ADDR_W(FDC_RAM_ADDR_W),
|
||
.FDC_RAM_DATA_R(LATCHED_RAM_DATA_FDC),
|
||
.FDC_RAM_DATA_W(FDC_RAM_DATA_W),
|
||
|
||
.FDC_IO(FDC_IO),
|
||
.FDC_IO_POLL(FDC_IO_POLL),
|
||
.FDC_IO_DATA(FDC_IO_DATA),
|
||
.FDC_IO_CT(FDC_IO_CT),
|
||
|
||
.FDC_SIG(FDC_SIG),
|
||
.FDC_SIG_CLK(FDC_SIG_CLK),
|
||
|
||
.FDC_CT(LATCHED_IO_FDC_CT),
|
||
.FDC_DATA(FDC_DATA),
|
||
.FDC_POLL(FDC_POLL),
|
||
.FDC_WP(FDC_WP),
|
||
|
||
.FLOPPY_SECTOR_BYTE(SECTOR_BYTE),
|
||
.TRACK1_NO(TRACK1_NO),
|
||
.TRACK2_NO(TRACK2_NO),
|
||
.DRIVE1(DRIVE1),
|
||
.DRIVE2(DRIVE2),
|
||
.MOTOR(MOTOR)
|
||
);
|
||
|
||
|
||
endmodule
|