mirror of
https://github.com/MiSTer-devel/MacPlus_MiSTer.git
synced 2024-06-13 01:29:28 +00:00
Compare commits
4 Commits
ea9c50291c
...
e879af35a1
Author | SHA1 | Date | |
---|---|---|---|
|
e879af35a1 | ||
|
f24b0fd44b | ||
|
0c094b4d59 | ||
|
e4ca3f4533 |
50
MacPlus.sv
50
MacPlus.sv
|
@ -208,11 +208,12 @@ localparam CONF_STR = {
|
|||
"F2,DSK,Mount Sec Floppy;",
|
||||
"-;",
|
||||
"SC0,IMGVHD,Mount SCSI-6;",
|
||||
"SC1,IMGVHD,Mount SCSI-2;",
|
||||
"SC1,IMGVHD,Mount SCSI-5;",
|
||||
"-;",
|
||||
"O78,Aspect ratio,Original,Full Screen,[ARC1],[ARC2];",
|
||||
"OBC,Scale,Normal,V-Integer,Narrower HV-Integer,Wider HV-Integer;",
|
||||
"-;",
|
||||
"O9,Model,Plus,SE;",
|
||||
"O5,Speed,8MHz,16MHz;",
|
||||
"ODE,CPU,68000,68010,68020;",
|
||||
"O4,Memory,1MB,4MB;",
|
||||
|
@ -240,6 +241,7 @@ pll pll
|
|||
|
||||
reg status_mem;
|
||||
reg [1:0] status_cpu;
|
||||
reg status_mod;
|
||||
reg n_reset = 0;
|
||||
always @(posedge clk_sys) begin
|
||||
reg [15:0] rst_cnt;
|
||||
|
@ -254,6 +256,7 @@ always @(posedge clk_sys) begin
|
|||
rst_cnt <= rst_cnt - 1'd1;
|
||||
status_mem <= status[4];
|
||||
status_cpu <= status[14:13];
|
||||
status_mod <= status[9];
|
||||
end
|
||||
else begin
|
||||
n_reset <= 1;
|
||||
|
@ -263,19 +266,21 @@ end
|
|||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
localparam SCSI_DEVS = 2;
|
||||
|
||||
// the status register is controlled by the on screen display (OSD)
|
||||
wire [31:0] status;
|
||||
wire [1:0] buttons;
|
||||
wire [31:0] sd_lba[2];
|
||||
wire [1:0] sd_rd;
|
||||
wire [1:0] sd_wr;
|
||||
wire [1:0] sd_ack;
|
||||
wire [7:0] sd_buff_addr;
|
||||
wire [15:0] sd_buff_dout;
|
||||
wire [15:0] sd_buff_din[2];
|
||||
wire sd_buff_wr;
|
||||
wire [1:0] img_mounted;
|
||||
wire [31:0] img_size;
|
||||
wire [31:0] sd_lba[SCSI_DEVS];
|
||||
wire [SCSI_DEVS-1:0] sd_rd;
|
||||
wire [SCSI_DEVS-1:0] sd_wr;
|
||||
wire [SCSI_DEVS-1:0] sd_ack;
|
||||
wire [7:0] sd_buff_addr;
|
||||
wire [15:0] sd_buff_dout;
|
||||
wire [15:0] sd_buff_din[SCSI_DEVS];
|
||||
wire sd_buff_wr;
|
||||
wire [SCSI_DEVS-1:0] img_mounted;
|
||||
wire [63:0] img_size;
|
||||
|
||||
wire ioctl_write;
|
||||
reg ioctl_wait = 0;
|
||||
|
@ -289,7 +294,7 @@ wire [15:0] ioctl_data;
|
|||
|
||||
wire [32:0] TIMESTAMP;
|
||||
|
||||
hps_io #(.CONF_STR(CONF_STR), .VDNUM(2), .WIDE(1)) hps_io
|
||||
hps_io #(.CONF_STR(CONF_STR), .VDNUM(SCSI_DEVS), .WIDE(1)) hps_io
|
||||
(
|
||||
.clk_sys(clk_sys),
|
||||
.HPS_BUS(HPS_BUS),
|
||||
|
@ -422,7 +427,7 @@ wire memoryLatch;
|
|||
|
||||
// peripherals
|
||||
wire vid_alt, loadPixels, pixelOut, _hblank, _vblank, hsync, vsync;
|
||||
wire memoryOverlayOn, selectSCSI, selectSCC, selectIWM, selectVIA, selectRAM, selectROM;
|
||||
wire memoryOverlayOn, selectSCSI, selectSCC, selectIWM, selectVIA, selectRAM, selectROM, selectSEOverlay;
|
||||
wire [15:0] dataControllerDataOut;
|
||||
|
||||
// audio
|
||||
|
@ -580,7 +585,7 @@ addrController_top ac0
|
|||
._cpuRW(_cpuRW),
|
||||
._cpuAS(_cpuAS),
|
||||
.turbo(status_turbo),
|
||||
.configROMSize(configROMSize),
|
||||
.configROMSize({status_mod,~status_mod}),
|
||||
.configRAMSize(configRAMSize),
|
||||
.memoryAddr(memoryAddr),
|
||||
.memoryLatch(memoryLatch),
|
||||
|
@ -598,6 +603,7 @@ addrController_top ac0
|
|||
.selectVIA(selectVIA),
|
||||
.selectRAM(selectRAM),
|
||||
.selectROM(selectROM),
|
||||
.selectSEOverlay(selectSEOverlay),
|
||||
.hsync(hsync),
|
||||
.vsync(vsync),
|
||||
._hblank(_hblank),
|
||||
|
@ -618,13 +624,14 @@ addrController_top ac0
|
|||
wire [1:0] diskEject;
|
||||
wire [1:0] diskMotor, diskAct;
|
||||
|
||||
dataController_top dc0
|
||||
dataController_top #(SCSI_DEVS) dc0
|
||||
(
|
||||
.clk32(clk_sys),
|
||||
.clk8_en_p(clk8_en_p),
|
||||
.clk8_en_n(clk8_en_n),
|
||||
.E_rising(E_rising),
|
||||
.E_falling(E_falling),
|
||||
.machineType(status_mod),
|
||||
._systemReset(n_reset),
|
||||
._cpuReset(_cpuReset),
|
||||
._cpuIPL(_cpuIPL),
|
||||
|
@ -641,6 +648,7 @@ dataController_top dc0
|
|||
.selectSCC(selectSCC),
|
||||
.selectIWM(selectIWM),
|
||||
.selectVIA(selectVIA),
|
||||
.selectSEOverlay(selectSEOverlay),
|
||||
.cpuBusControl(cpuBusControl),
|
||||
.videoBusControl(videoBusControl),
|
||||
.memoryDataOut(memoryDataOut),
|
||||
|
@ -686,17 +694,15 @@ dataController_top dc0
|
|||
|
||||
// block device interface for scsi disk
|
||||
.img_mounted(img_mounted),
|
||||
.img_size(img_size),
|
||||
.io_lba0(sd_lba[0]),
|
||||
.io_lba1(sd_lba[1]),
|
||||
.img_size(img_size[40:9]),
|
||||
.io_lba(sd_lba),
|
||||
.io_rd(sd_rd),
|
||||
.io_wr(sd_wr),
|
||||
.io_ack(sd_ack),
|
||||
|
||||
.sd_buff_addr(sd_buff_addr),
|
||||
.sd_buff_dout(sd_buff_dout),
|
||||
.sd_buff_din0(sd_buff_din[0]),
|
||||
.sd_buff_din1(sd_buff_din[1]),
|
||||
.sd_buff_din(sd_buff_din),
|
||||
.sd_buff_wr(sd_buff_wr)
|
||||
);
|
||||
|
||||
|
@ -771,7 +777,7 @@ always @(posedge clk_sys) begin
|
|||
|
||||
if(ioctl_write) begin
|
||||
dio_data <= {ioctl_data[7:0], ioctl_data[15:8]};
|
||||
dio_a <= {dio_index[1:0], dio_addr[18:0]};
|
||||
dio_a <= dio_index[1:0] ? {dio_index[1:0], dio_addr[18:0]} : {dio_index[6], dio_addr[17:0]};
|
||||
ioctl_wait <= 1;
|
||||
end
|
||||
|
||||
|
@ -786,7 +792,7 @@ wire download_cycle = dio_download && dioBusControl;
|
|||
|
||||
////////////////////////// SDRAM /////////////////////////////////
|
||||
|
||||
wire [24:0] sdram_addr = download_cycle ? { 4'b0001, dio_a[20:0] } : { 3'b000, ~_romOE, memoryAddr[21:1] };
|
||||
wire [24:0] sdram_addr = download_cycle ? { 4'b0001, dio_a[20:0] } : { 3'b000, ~_romOE, _romOE ? memoryAddr[21:19] : {2'b00,status_mod}, memoryAddr[18:1] };
|
||||
wire [15:0] sdram_din = download_cycle ? dio_data : memoryDataOut;
|
||||
wire [1:0] sdram_ds = download_cycle ? 2'b11 : { !_memoryUDS, !_memoryLDS };
|
||||
wire sdram_we = download_cycle ? dio_write : !_ramWE;
|
||||
|
|
|
@ -2,10 +2,11 @@ set_global_assignment -name QIP_FILE rtl/tg68k/TG68K.qip
|
|||
set_global_assignment -name QIP_FILE rtl/fx68k/fx68k.qip
|
||||
set_global_assignment -name VERILOG_FILE rtl/sdram.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/scsi.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/ncr5380.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/ncr5380.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/floppy_track_encoder.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/floppy.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/ps2_kbd.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/adb.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/ps2_mouse.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/scc.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/uart/txuart.v
|
||||
|
@ -14,7 +15,7 @@ set_global_assignment -name VERILOG_FILE rtl/iwm.v
|
|||
set_global_assignment -name VHDL_FILE rtl/via6522.vhd
|
||||
set_global_assignment -name VERILOG_FILE rtl/addrDecoder.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/addrController_top.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/dataController_top.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/dataController_top.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/videoTimer.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/videoShifter.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/rtc.v
|
||||
|
|
BIN
releases/MacPlus_20220309.rbf
Normal file
BIN
releases/MacPlus_20220309.rbf
Normal file
Binary file not shown.
BIN
releases/boot1.rom
Normal file
BIN
releases/boot1.rom
Normal file
Binary file not shown.
875
rtl/adb.sv
Normal file
875
rtl/adb.sv
Normal file
|
@ -0,0 +1,875 @@
|
|||
/* ADB implementation for plus_too */
|
||||
|
||||
module adb(
|
||||
input clk,
|
||||
input clk_en,
|
||||
input reset,
|
||||
input [1:0] st,
|
||||
output _int,
|
||||
input viaBusy,
|
||||
output reg listen,
|
||||
input [7:0] adb_din,
|
||||
input adb_din_strobe,
|
||||
output reg [7:0] adb_dout,
|
||||
output reg adb_dout_strobe,
|
||||
|
||||
output reg capslock,
|
||||
|
||||
input [24:0] ps2_mouse,
|
||||
input [10:0] ps2_key
|
||||
);
|
||||
|
||||
localparam TALKINTERVAL = 17'd8000*4'd11; // 11 ms
|
||||
|
||||
reg [3:0] cmd_r;
|
||||
reg [1:0] st_r;
|
||||
wire [1:0] r_r = cmd_r[1:0];
|
||||
reg [3:0] addr_r;
|
||||
reg [3:0] respCnt;
|
||||
reg [16:0] talkTimer;
|
||||
reg idleActive;
|
||||
|
||||
wire [3:0] cmd = adb_din[3:0];
|
||||
wire [3:0] addr = adb_din[7:4];
|
||||
|
||||
reg sendResponse;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset) begin
|
||||
respCnt <= 0;
|
||||
idleActive <= 0;
|
||||
cmd_r <= 0;
|
||||
listen <= 0;
|
||||
sendResponse <= 0;
|
||||
end else if (clk_en) begin
|
||||
st_r <= st;
|
||||
adb_dout_strobe <= 0;
|
||||
sendResponse <= 0;
|
||||
|
||||
case (st)
|
||||
2'b00: // new command
|
||||
begin
|
||||
if (st_r != 2'b00)
|
||||
listen <= 1;
|
||||
|
||||
respCnt <= 0;
|
||||
if (adb_din_strobe) begin
|
||||
idleActive <= 1;
|
||||
cmd_r <= cmd;
|
||||
addr_r <= addr;
|
||||
listen <= 0;
|
||||
|
||||
if (addr_r != addr || cmd_r != cmd)
|
||||
talkTimer <= 0;
|
||||
else
|
||||
talkTimer <= TALKINTERVAL;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
2'b01, 2'b10: // even byte, odd byte
|
||||
begin
|
||||
// Reset, flush, talk
|
||||
if (!viaBusy && (cmd_r[3:1] == 0 || cmd_r[3:2] == 2'b11) && respCnt[0] == st[1]) begin
|
||||
sendResponse <= 1;
|
||||
respCnt <= respCnt + 1'd1;
|
||||
end
|
||||
if (sendResponse) begin
|
||||
adb_dout <= adbReg;
|
||||
adb_dout_strobe <= 1;
|
||||
end
|
||||
// Listen
|
||||
if (st_r != st) listen <= cmd_r[3:2] == 2'b10;
|
||||
if (cmd_r[3:2] == 2'b10 && respCnt[0] == st[1]) begin
|
||||
if (adb_din_strobe) begin
|
||||
listen <= 0;
|
||||
respCnt <= respCnt + 1'd1;
|
||||
// Listen : it's handled in the device specific part
|
||||
// The Listen command is to write to registers, some use cases:
|
||||
// - device ID and device handler writes
|
||||
// - LED status for the keyboard
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
2'b11: // idle
|
||||
begin
|
||||
if (cmd_r[3:2] == 2'b11 && idleActive) begin
|
||||
if (talkTimer != 0)
|
||||
talkTimer <= talkTimer - 1'd1;
|
||||
else begin
|
||||
adb_dout <= 8'hFF;
|
||||
adb_dout_strobe <= 1;
|
||||
talkTimer <= TALKINTERVAL;
|
||||
idleActive <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// Device handlers
|
||||
wire [3:0] addrKeyboard = kbdReg3[11:8];
|
||||
wire [3:0] addrMouse = mouseReg3[11:8];
|
||||
|
||||
wire mouseInt = (addr_r != addrMouse && mouseValid == 2'b01);
|
||||
wire keyboardInt = (addr_r != addrKeyboard && (keyboardValid == 1 || keyboardValid == 2));
|
||||
wire irq = mouseInt | keyboardInt | !adbValid;
|
||||
wire int_inhibit = respCnt < 3 &&
|
||||
((addr_r == addrMouse && mouseValid == 2'b01) ||
|
||||
(addr_r == addrKeyboard && (keyboardValid == 1 || keyboardValid == 2)));
|
||||
assign _int = ~(irq && (st == 2'b01 || st == 2'b10)) | int_inhibit;
|
||||
|
||||
// Mouse handler
|
||||
reg [15:0] mouseReg3;
|
||||
reg [6:0] X,Y;
|
||||
reg [1:0] mouseValid;
|
||||
|
||||
reg mstb;
|
||||
always @(posedge clk) if (clk_en) mstb <= ps2_mouse[24];
|
||||
|
||||
wire mouseStrobe = mstb ^ ps2_mouse[24];
|
||||
wire [8:0] mouseX = {ps2_mouse[4], ps2_mouse[15:8]};
|
||||
wire [8:0] mouseY = {ps2_mouse[5], ps2_mouse[23:16]};
|
||||
wire button = ps2_mouse[0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset || cmd_r == 0) begin
|
||||
mouseReg3 <= 16'h6301; // device id: 3 device handler id: 1
|
||||
X <= 0;
|
||||
Y <= 0;
|
||||
mouseValid <= 0;
|
||||
end else if (clk_en) begin
|
||||
|
||||
if (mouseStrobe) begin
|
||||
if (~mouseX[8] & |mouseX[7:6]) X <= 7'h3F;
|
||||
else if (mouseX[8] & ~mouseX[6]) X <= 7'h40;
|
||||
else X <= mouseX[6:0];
|
||||
|
||||
if (~mouseY[8] & |mouseY[7:6]) Y <= 7'h40;
|
||||
else if (mouseY[8] & ~mouseY[6]) Y <= 7'h3F;
|
||||
else Y <= -mouseY[6:0];
|
||||
|
||||
mouseValid <= 2'b01;
|
||||
end
|
||||
|
||||
if (addr_r == addrMouse) begin
|
||||
|
||||
if (mouseValid == 2'b01 && respCnt == 3)
|
||||
// mouse data sent
|
||||
mouseValid <= 2'b10;
|
||||
|
||||
if ((mouseValid == 2'b10 && st == 2'b00) || cmd_r == 4'b0001) begin
|
||||
// Flush mouse data after read or flush command
|
||||
mouseValid <= 0;
|
||||
X <= 0;
|
||||
Y <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// Keyboard handler
|
||||
reg [1:0] keyboardValid;
|
||||
reg [15:0] kbdReg0;
|
||||
reg [15:0] kbdReg2;
|
||||
reg [15:0] kbdReg3;
|
||||
reg [7:0] kbdFifo[8];
|
||||
reg [2:0] kbdFifoRd, kbdFifoWr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset || cmd_r == 0) begin
|
||||
kbdReg0 <= 16'hFFFF;
|
||||
kbdReg2 <= 16'hFFFF;
|
||||
kbdReg3 <= 16'h6202; // device id: 2 device handler id: 2
|
||||
keyboardValid <= 0;
|
||||
kbdFifoRd <= 0;
|
||||
kbdFifoWr <= 0;
|
||||
end else if (clk_en) begin
|
||||
|
||||
if (keyStrobe && keyData[6:0] != 7'h7F) begin
|
||||
// Store the keypress in the FIFO
|
||||
kbdFifo[kbdFifoWr] <= keyData;
|
||||
kbdFifoWr <= kbdFifoWr + 1'd1;
|
||||
end
|
||||
|
||||
if (kbdFifoWr != kbdFifoRd && st == 2'b11 && keyboardValid < 2) begin
|
||||
// Read the FIFO when no other key processing in progress
|
||||
if (kbdReg0[6:0] == kbdFifo[kbdFifoRd][6:0])
|
||||
kbdReg0[7:0] <= kbdFifo[kbdFifoRd];
|
||||
else if (kbdReg0[14:8] == kbdFifo[kbdFifoRd][6:0])
|
||||
kbdReg0[15:8] <= kbdFifo[kbdFifoRd];
|
||||
else if (kbdReg0[7:0] == 8'hFF)
|
||||
kbdReg0[7:0] <= kbdFifo[kbdFifoRd];
|
||||
else
|
||||
kbdReg0[15:8] <= kbdFifo[kbdFifoRd];
|
||||
|
||||
// kbdReg0 has a valid key
|
||||
keyboardValid <= keyboardValid + 1'd1;
|
||||
kbdFifoRd <= kbdFifoRd + 1'd1;
|
||||
end
|
||||
|
||||
if (addr_r == addrKeyboard) begin
|
||||
if (cmd_r == 4'b1010 && adb_din_strobe && st[1]^st[0]) begin
|
||||
// write into reg2 (keyboard LEDs)
|
||||
if (respCnt == 1) kbdReg2[2:0] <= adb_din[2:0];
|
||||
end
|
||||
|
||||
if (keyboardValid != 0 && respCnt == 2)
|
||||
// Beginning of keyboard data read
|
||||
keyboardValid <= 2'd3;
|
||||
|
||||
if ((keyboardValid == 3 && st == 2'b00) || cmd_r == 4'b0001) begin
|
||||
// Flush keyboard data after read or flush command
|
||||
keyboardValid <= 0;
|
||||
kbdReg0 <= 16'hFFFF;
|
||||
if (cmd_r == 4'b0001) begin
|
||||
// Flush
|
||||
kbdFifoRd <= 0;
|
||||
kbdFifoWr <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
// Register 0 in the Apple Standard Mouse
|
||||
// Bit Meaning
|
||||
// 15 Button status; 0 = down
|
||||
// 14-8 Y move counts'
|
||||
// 7 Not used (always 1)
|
||||
// 6-0 X move counts
|
||||
|
||||
// Register 0 in the Apple Standard Keyboard
|
||||
// Bit Meaning
|
||||
// 15 Key status for first key; 0 = down
|
||||
// 14-8 Key code for first key; a 7-bit ASCII value
|
||||
// 7 Key status for second key; 0 = down
|
||||
// 6-0 Key code for second key; a 7-bit ASCII value
|
||||
|
||||
// Register 2 in the Apple Extended Keyboard
|
||||
// Bit Key
|
||||
// 15 None (reserved)
|
||||
// 14 Delete
|
||||
// 13 Caps Lock
|
||||
// 12 Reset
|
||||
// 11 Control
|
||||
// 10 Shift
|
||||
// 9 Option
|
||||
// 8 Command
|
||||
// 7 Num Lock/Clear
|
||||
// 6 Scroll Lock
|
||||
// 5-3 None (reserved)
|
||||
// 2 LED 3 (Scroll Lock) *
|
||||
// 1 LED 2 (Caps Lock) *
|
||||
// 0 LED 1 (Num Lock) *
|
||||
//
|
||||
// *Changeable via Listen Register 2
|
||||
|
||||
// Register 3 (common for all devices):
|
||||
// Bit Description
|
||||
// 15 Reserved; must be 0
|
||||
// 14 Exceptional event, device specific; always 1 if not used
|
||||
// 13 Service Request enable; 1 = enabled
|
||||
// 12 Reserved; must be 0
|
||||
// 11-8 Device address
|
||||
// 7-0 Device Handler ID
|
||||
|
||||
reg [7:0] adbReg;
|
||||
reg adbValid;
|
||||
reg [15:0] talkReg;
|
||||
|
||||
always @(*) begin
|
||||
adbReg = 8'hFF;
|
||||
adbValid = 0;
|
||||
talkReg = 0;
|
||||
if (addr_r == addrKeyboard) begin
|
||||
if (cmd_r[3:1] == 0) begin
|
||||
// reset
|
||||
if (respCnt == 0) adbValid = 1;
|
||||
end else begin
|
||||
// talk
|
||||
case (r_r)
|
||||
2'b00: talkReg = kbdReg0;
|
||||
2'b10: talkReg = kbdReg2;
|
||||
2'b11: talkReg = kbdReg3;
|
||||
default: ;
|
||||
endcase
|
||||
|
||||
if (respCnt == 1) begin
|
||||
adbReg = talkReg[15:8];
|
||||
adbValid = 1;
|
||||
end
|
||||
if (respCnt == 2) begin
|
||||
adbReg = talkReg[7:0];
|
||||
adbValid = 1;
|
||||
end
|
||||
end
|
||||
end else if (addr_r == addrMouse) begin
|
||||
if (cmd_r[3:1] == 0) begin
|
||||
// reset
|
||||
if (respCnt == 0) adbValid = 1;
|
||||
end else begin
|
||||
// talk
|
||||
case (r_r)
|
||||
2'b00: talkReg = { ~button, Y, 1'b1, X };
|
||||
2'b11: talkReg = mouseReg3;
|
||||
default: ;
|
||||
endcase
|
||||
if (respCnt == 1) begin
|
||||
adbReg = talkReg[15:8];
|
||||
adbValid = 1;
|
||||
end
|
||||
if (respCnt == 2) begin
|
||||
adbReg = talkReg[7:0];
|
||||
adbValid = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg keyStrobe;
|
||||
reg [7:0] keyData;
|
||||
wire press = ps2_key[9];
|
||||
wire capslock_key = (ps2_key[8:0] == 'h58);
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg kstb;
|
||||
|
||||
if (clk_en) begin
|
||||
kstb <= ps2_key[10];
|
||||
if (kstb ^ ps2_key[10]) begin
|
||||
case(ps2_key[8:0]) // Scan Code Set 2
|
||||
9'h000: keyData[6:0] <= 7'h7F;
|
||||
9'h001: keyData[6:0] <= 7'h65; //F9
|
||||
9'h002: keyData[6:0] <= 7'h7F;
|
||||
9'h003: keyData[6:0] <= 7'h60; //F5
|
||||
9'h004: keyData[6:0] <= 7'h63; //F3
|
||||
9'h005: keyData[6:0] <= 7'h7A; //F1
|
||||
9'h006: keyData[6:0] <= 7'h78; //F2
|
||||
9'h007: keyData[6:0] <= 7'h7F;//7'h6F; //F12 <OSD>
|
||||
9'h008: keyData[6:0] <= 7'h7F;
|
||||
9'h009: keyData[6:0] <= 7'h6D; //F10
|
||||
9'h00a: keyData[6:0] <= 7'h64; //F8
|
||||
9'h00b: keyData[6:0] <= 7'h61; //F6
|
||||
9'h00c: keyData[6:0] <= 7'h76; //F4
|
||||
9'h00d: keyData[6:0] <= 7'h30; //TAB
|
||||
9'h00e: keyData[6:0] <= 7'h32; //~ (`)
|
||||
9'h00f: keyData[6:0] <= 7'h7F;
|
||||
9'h010: keyData[6:0] <= 7'h7F;
|
||||
9'h011: keyData[6:0] <= 7'h37; //LEFT ALT (command)
|
||||
9'h012: keyData[6:0] <= 7'h38; //LEFT SHIFT
|
||||
9'h013: keyData[6:0] <= 7'h7F;
|
||||
9'h014: keyData[6:0] <= 7'h36; //CTRL
|
||||
9'h015: keyData[6:0] <= 7'h0C; //q
|
||||
9'h016: keyData[6:0] <= 7'h12; //1
|
||||
9'h017: keyData[6:0] <= 7'h7F;
|
||||
9'h018: keyData[6:0] <= 7'h7F;
|
||||
9'h019: keyData[6:0] <= 7'h7F;
|
||||
9'h01a: keyData[6:0] <= 7'h06; //z
|
||||
9'h01b: keyData[6:0] <= 7'h01; //s
|
||||
9'h01c: keyData[6:0] <= 7'h00; //a
|
||||
9'h01d: keyData[6:0] <= 7'h0D; //w
|
||||
9'h01e: keyData[6:0] <= 7'h13; //2
|
||||
9'h01f: keyData[6:0] <= 7'h7F;
|
||||
9'h020: keyData[6:0] <= 7'h7F;
|
||||
9'h021: keyData[6:0] <= 7'h08; //c
|
||||
9'h022: keyData[6:0] <= 7'h07; //x
|
||||
9'h023: keyData[6:0] <= 7'h02; //d
|
||||
9'h024: keyData[6:0] <= 7'h0E; //e
|
||||
9'h025: keyData[6:0] <= 7'h15; //4
|
||||
9'h026: keyData[6:0] <= 7'h14; //3
|
||||
9'h027: keyData[6:0] <= 7'h7F;
|
||||
9'h028: keyData[6:0] <= 7'h7F;
|
||||
9'h029: keyData[6:0] <= 7'h31; //SPACE
|
||||
9'h02a: keyData[6:0] <= 7'h09; //v
|
||||
9'h02b: keyData[6:0] <= 7'h03; //f
|
||||
9'h02c: keyData[6:0] <= 7'h11; //t
|
||||
9'h02d: keyData[6:0] <= 7'h0F; //r
|
||||
9'h02e: keyData[6:0] <= 7'h17; //5
|
||||
9'h02f: keyData[6:0] <= 7'h7F;
|
||||
9'h030: keyData[6:0] <= 7'h7F;
|
||||
9'h031: keyData[6:0] <= 7'h2D; //n
|
||||
9'h032: keyData[6:0] <= 7'h0B; //b
|
||||
9'h033: keyData[6:0] <= 7'h04; //h
|
||||
9'h034: keyData[6:0] <= 7'h05; //g
|
||||
9'h035: keyData[6:0] <= 7'h10; //y
|
||||
9'h036: keyData[6:0] <= 7'h16; //6
|
||||
9'h037: keyData[6:0] <= 7'h7F;
|
||||
9'h038: keyData[6:0] <= 7'h7F;
|
||||
9'h039: keyData[6:0] <= 7'h7F;
|
||||
9'h03a: keyData[6:0] <= 7'h2E; //m
|
||||
9'h03b: keyData[6:0] <= 7'h26; //j
|
||||
9'h03c: keyData[6:0] <= 7'h20; //u
|
||||
9'h03d: keyData[6:0] <= 7'h1A; //7
|
||||
9'h03e: keyData[6:0] <= 7'h1C; //8
|
||||
9'h03f: keyData[6:0] <= 7'h7F;
|
||||
9'h040: keyData[6:0] <= 7'h7F;
|
||||
9'h041: keyData[6:0] <= 7'h2B; //<,
|
||||
9'h042: keyData[6:0] <= 7'h28; //k
|
||||
9'h043: keyData[6:0] <= 7'h22; //i
|
||||
9'h044: keyData[6:0] <= 7'h1F; //o
|
||||
9'h045: keyData[6:0] <= 7'h1D; //0
|
||||
9'h046: keyData[6:0] <= 7'h19; //9
|
||||
9'h047: keyData[6:0] <= 7'h7F;
|
||||
9'h048: keyData[6:0] <= 7'h7F;
|
||||
9'h049: keyData[6:0] <= 7'h2F; //>.
|
||||
9'h04a: keyData[6:0] <= 7'h2C; //FORWARD SLASH
|
||||
9'h04b: keyData[6:0] <= 7'h25; //l
|
||||
9'h04c: keyData[6:0] <= 7'h29; //;
|
||||
9'h04d: keyData[6:0] <= 7'h23; //p
|
||||
9'h04e: keyData[6:0] <= 7'h1B; //-
|
||||
9'h04f: keyData[6:0] <= 7'h7F;
|
||||
9'h050: keyData[6:0] <= 7'h7F;
|
||||
9'h051: keyData[6:0] <= 7'h7F;
|
||||
9'h052: keyData[6:0] <= 7'h27; //'"
|
||||
9'h053: keyData[6:0] <= 7'h7F;
|
||||
9'h054: keyData[6:0] <= 7'h21; //[
|
||||
9'h055: keyData[6:0] <= 7'h18; // =
|
||||
9'h056: keyData[6:0] <= 7'h7F;
|
||||
9'h057: keyData[6:0] <= 7'h7F;
|
||||
9'h058: keyData[6:0] <= 7'h39; //CAPSLOCK
|
||||
9'h059: keyData[6:0] <= 7'h7B; //RIGHT SHIFT
|
||||
9'h05a: keyData[6:0] <= 7'h24; //ENTER
|
||||
9'h05b: keyData[6:0] <= 7'h1E; //]
|
||||
9'h05c: keyData[6:0] <= 7'h7F;
|
||||
9'h05d: keyData[6:0] <= 7'h2A; //BACKSLASH
|
||||
9'h05e: keyData[6:0] <= 7'h7F;
|
||||
9'h05f: keyData[6:0] <= 7'h7F;
|
||||
9'h060: keyData[6:0] <= 7'h7F;
|
||||
9'h061: keyData[6:0] <= 7'h7F; //international left shift cut out (German '<>' key), 0x56 Set#1 code
|
||||
9'h062: keyData[6:0] <= 7'h7F;
|
||||
9'h063: keyData[6:0] <= 7'h7F;
|
||||
9'h064: keyData[6:0] <= 7'h7F;
|
||||
9'h065: keyData[6:0] <= 7'h7F;
|
||||
9'h066: keyData[6:0] <= 7'h33; //BACKSPACE
|
||||
9'h067: keyData[6:0] <= 7'h7F;
|
||||
9'h068: keyData[6:0] <= 7'h7F;
|
||||
9'h069: keyData[6:0] <= 7'h53; //KP 1
|
||||
9'h06a: keyData[6:0] <= 7'h7F;
|
||||
9'h06b: keyData[6:0] <= 7'h56; //KP 4
|
||||
9'h06c: keyData[6:0] <= 7'h59; //KP 7
|
||||
9'h06d: keyData[6:0] <= 7'h7F;
|
||||
9'h06e: keyData[6:0] <= 7'h7F;
|
||||
9'h06f: keyData[6:0] <= 7'h7F;
|
||||
9'h070: keyData[6:0] <= 7'h52; //KP 0
|
||||
9'h071: keyData[6:0] <= 7'h41; //KP .
|
||||
9'h072: keyData[6:0] <= 7'h54; //KP 2
|
||||
9'h073: keyData[6:0] <= 7'h57; //KP 5
|
||||
9'h074: keyData[6:0] <= 7'h58; //KP 6
|
||||
9'h075: keyData[6:0] <= 7'h5B; //KP 8
|
||||
9'h076: keyData[6:0] <= 7'h35; //ESCAPE
|
||||
9'h077: keyData[6:0] <= 7'h47; //NUMLOCK (Mac keypad clear?)
|
||||
9'h078: keyData[6:0] <= 7'h67; //F11 <OSD>
|
||||
9'h079: keyData[6:0] <= 7'h45; //KP +
|
||||
9'h07a: keyData[6:0] <= 7'h55; //KP 3
|
||||
9'h07b: keyData[6:0] <= 7'h4E; //KP -
|
||||
9'h07c: keyData[6:0] <= 7'h43; //KP *
|
||||
9'h07d: keyData[6:0] <= 7'h5C; //KP 9
|
||||
9'h07e: keyData[6:0] <= 7'h7F; //SCROLL LOCK / KP )
|
||||
9'h07f: keyData[6:0] <= 7'h7F;
|
||||
9'h080: keyData[6:0] <= 7'h7F;
|
||||
9'h081: keyData[6:0] <= 7'h7F;
|
||||
9'h082: keyData[6:0] <= 7'h7F;
|
||||
9'h083: keyData[6:0] <= 7'h62; //F7
|
||||
9'h084: keyData[6:0] <= 7'h7F;
|
||||
9'h085: keyData[6:0] <= 7'h7F;
|
||||
9'h086: keyData[6:0] <= 7'h7F;
|
||||
9'h087: keyData[6:0] <= 7'h7F;
|
||||
9'h088: keyData[6:0] <= 7'h7F;
|
||||
9'h089: keyData[6:0] <= 7'h7F;
|
||||
9'h08a: keyData[6:0] <= 7'h7F;
|
||||
9'h08b: keyData[6:0] <= 7'h7F;
|
||||
9'h08c: keyData[6:0] <= 7'h7F;
|
||||
9'h08d: keyData[6:0] <= 7'h7F;
|
||||
9'h08e: keyData[6:0] <= 7'h7F;
|
||||
9'h08f: keyData[6:0] <= 7'h7F;
|
||||
9'h090: keyData[6:0] <= 7'h7F;
|
||||
9'h091: keyData[6:0] <= 7'h7F;
|
||||
9'h092: keyData[6:0] <= 7'h7F;
|
||||
9'h093: keyData[6:0] <= 7'h7F;
|
||||
9'h094: keyData[6:0] <= 7'h7F;
|
||||
9'h095: keyData[6:0] <= 7'h7F;
|
||||
9'h096: keyData[6:0] <= 7'h7F;
|
||||
9'h097: keyData[6:0] <= 7'h7F;
|
||||
9'h098: keyData[6:0] <= 7'h7F;
|
||||
9'h099: keyData[6:0] <= 7'h7F;
|
||||
9'h09a: keyData[6:0] <= 7'h7F;
|
||||
9'h09b: keyData[6:0] <= 7'h7F;
|
||||
9'h09c: keyData[6:0] <= 7'h7F;
|
||||
9'h09d: keyData[6:0] <= 7'h7F;
|
||||
9'h09e: keyData[6:0] <= 7'h7F;
|
||||
9'h09f: keyData[6:0] <= 7'h7F;
|
||||
9'h0a0: keyData[6:0] <= 7'h7F;
|
||||
9'h0a1: keyData[6:0] <= 7'h7F;
|
||||
9'h0a2: keyData[6:0] <= 7'h7F;
|
||||
9'h0a3: keyData[6:0] <= 7'h7F;
|
||||
9'h0a4: keyData[6:0] <= 7'h7F;
|
||||
9'h0a5: keyData[6:0] <= 7'h7F;
|
||||
9'h0a6: keyData[6:0] <= 7'h7F;
|
||||
9'h0a7: keyData[6:0] <= 7'h7F;
|
||||
9'h0a8: keyData[6:0] <= 7'h7F;
|
||||
9'h0a9: keyData[6:0] <= 7'h7F;
|
||||
9'h0aa: keyData[6:0] <= 7'h7F;
|
||||
9'h0ab: keyData[6:0] <= 7'h7F;
|
||||
9'h0ac: keyData[6:0] <= 7'h7F;
|
||||
9'h0ad: keyData[6:0] <= 7'h7F;
|
||||
9'h0ae: keyData[6:0] <= 7'h7F;
|
||||
9'h0af: keyData[6:0] <= 7'h7F;
|
||||
9'h0b0: keyData[6:0] <= 7'h7F;
|
||||
9'h0b1: keyData[6:0] <= 7'h7F;
|
||||
9'h0b2: keyData[6:0] <= 7'h7F;
|
||||
9'h0b3: keyData[6:0] <= 7'h7F;
|
||||
9'h0b4: keyData[6:0] <= 7'h7F;
|
||||
9'h0b5: keyData[6:0] <= 7'h7F;
|
||||
9'h0b6: keyData[6:0] <= 7'h7F;
|
||||
9'h0b7: keyData[6:0] <= 7'h7F;
|
||||
9'h0b8: keyData[6:0] <= 7'h7F;
|
||||
9'h0b9: keyData[6:0] <= 7'h7F;
|
||||
9'h0ba: keyData[6:0] <= 7'h7F;
|
||||
9'h0bb: keyData[6:0] <= 7'h7F;
|
||||
9'h0bc: keyData[6:0] <= 7'h7F;
|
||||
9'h0bd: keyData[6:0] <= 7'h7F;
|
||||
9'h0be: keyData[6:0] <= 7'h7F;
|
||||
9'h0bf: keyData[6:0] <= 7'h7F;
|
||||
9'h0c0: keyData[6:0] <= 7'h7F;
|
||||
9'h0c1: keyData[6:0] <= 7'h7F;
|
||||
9'h0c2: keyData[6:0] <= 7'h7F;
|
||||
9'h0c3: keyData[6:0] <= 7'h7F;
|
||||
9'h0c4: keyData[6:0] <= 7'h7F;
|
||||
9'h0c5: keyData[6:0] <= 7'h7F;
|
||||
9'h0c6: keyData[6:0] <= 7'h7F;
|
||||
9'h0c7: keyData[6:0] <= 7'h7F;
|
||||
9'h0c8: keyData[6:0] <= 7'h7F;
|
||||
9'h0c9: keyData[6:0] <= 7'h7F;
|
||||
9'h0ca: keyData[6:0] <= 7'h7F;
|
||||
9'h0cb: keyData[6:0] <= 7'h7F;
|
||||
9'h0cc: keyData[6:0] <= 7'h7F;
|
||||
9'h0cd: keyData[6:0] <= 7'h7F;
|
||||
9'h0ce: keyData[6:0] <= 7'h7F;
|
||||
9'h0cf: keyData[6:0] <= 7'h7F;
|
||||
9'h0d0: keyData[6:0] <= 7'h7F;
|
||||
9'h0d1: keyData[6:0] <= 7'h7F;
|
||||
9'h0d2: keyData[6:0] <= 7'h7F;
|
||||
9'h0d3: keyData[6:0] <= 7'h7F;
|
||||
9'h0d4: keyData[6:0] <= 7'h7F;
|
||||
9'h0d5: keyData[6:0] <= 7'h7F;
|
||||
9'h0d6: keyData[6:0] <= 7'h7F;
|
||||
9'h0d7: keyData[6:0] <= 7'h7F;
|
||||
9'h0d8: keyData[6:0] <= 7'h7F;
|
||||
9'h0d9: keyData[6:0] <= 7'h7F;
|
||||
9'h0da: keyData[6:0] <= 7'h7F;
|
||||
9'h0db: keyData[6:0] <= 7'h7F;
|
||||
9'h0dc: keyData[6:0] <= 7'h7F;
|
||||
9'h0dd: keyData[6:0] <= 7'h7F;
|
||||
9'h0de: keyData[6:0] <= 7'h7F;
|
||||
9'h0df: keyData[6:0] <= 7'h7F;
|
||||
9'h0e0: keyData[6:0] <= 7'h7F; //ps2 extended key
|
||||
9'h0e1: keyData[6:0] <= 7'h7F;
|
||||
9'h0e2: keyData[6:0] <= 7'h7F;
|
||||
9'h0e3: keyData[6:0] <= 7'h7F;
|
||||
9'h0e4: keyData[6:0] <= 7'h7F;
|
||||
9'h0e5: keyData[6:0] <= 7'h7F;
|
||||
9'h0e6: keyData[6:0] <= 7'h7F;
|
||||
9'h0e7: keyData[6:0] <= 7'h7F;
|
||||
9'h0e8: keyData[6:0] <= 7'h7F;
|
||||
9'h0e9: keyData[6:0] <= 7'h7F;
|
||||
9'h0ea: keyData[6:0] <= 7'h7F;
|
||||
9'h0eb: keyData[6:0] <= 7'h7F;
|
||||
9'h0ec: keyData[6:0] <= 7'h7F;
|
||||
9'h0ed: keyData[6:0] <= 7'h7F;
|
||||
9'h0ee: keyData[6:0] <= 7'h7F;
|
||||
9'h0ef: keyData[6:0] <= 7'h7F;
|
||||
9'h0f0: keyData[6:0] <= 7'h7F; //ps2 release code
|
||||
9'h0f1: keyData[6:0] <= 7'h7F;
|
||||
9'h0f2: keyData[6:0] <= 7'h7F;
|
||||
9'h0f3: keyData[6:0] <= 7'h7F;
|
||||
9'h0f4: keyData[6:0] <= 7'h7F;
|
||||
9'h0f5: keyData[6:0] <= 7'h7F;
|
||||
9'h0f6: keyData[6:0] <= 7'h7F;
|
||||
9'h0f7: keyData[6:0] <= 7'h7F;
|
||||
9'h0f8: keyData[6:0] <= 7'h7F;
|
||||
9'h0f9: keyData[6:0] <= 7'h7F;
|
||||
9'h0fa: keyData[6:0] <= 7'h7F; //ps2 ack code
|
||||
9'h0fb: keyData[6:0] <= 7'h7F;
|
||||
9'h0fc: keyData[6:0] <= 7'h7F;
|
||||
9'h0fd: keyData[6:0] <= 7'h7F;
|
||||
9'h0fe: keyData[6:0] <= 7'h7F;
|
||||
9'h0ff: keyData[6:0] <= 7'h7F;
|
||||
9'h100: keyData[6:0] <= 7'h7F;
|
||||
9'h101: keyData[6:0] <= 7'h7F;
|
||||
9'h102: keyData[6:0] <= 7'h7F;
|
||||
9'h103: keyData[6:0] <= 7'h7F;
|
||||
9'h104: keyData[6:0] <= 7'h7F;
|
||||
9'h105: keyData[6:0] <= 7'h7F;
|
||||
9'h106: keyData[6:0] <= 7'h7F;
|
||||
9'h107: keyData[6:0] <= 7'h7F;
|
||||
9'h108: keyData[6:0] <= 7'h7F;
|
||||
9'h109: keyData[6:0] <= 7'h7F;
|
||||
9'h10a: keyData[6:0] <= 7'h7F;
|
||||
9'h10b: keyData[6:0] <= 7'h7F;
|
||||
9'h10c: keyData[6:0] <= 7'h7F;
|
||||
9'h10d: keyData[6:0] <= 7'h7F;
|
||||
9'h10e: keyData[6:0] <= 7'h7F;
|
||||
9'h10f: keyData[6:0] <= 7'h7F;
|
||||
9'h110: keyData[6:0] <= 7'h7F;
|
||||
9'h111: keyData[6:0] <= 7'h37; //RIGHT ALT (command)
|
||||
9'h112: keyData[6:0] <= 7'h7F;
|
||||
9'h113: keyData[6:0] <= 7'h7F;
|
||||
9'h114: keyData[6:0] <= 7'h7F;
|
||||
9'h115: keyData[6:0] <= 7'h7F;
|
||||
9'h116: keyData[6:0] <= 7'h7F;
|
||||
9'h117: keyData[6:0] <= 7'h7F;
|
||||
9'h118: keyData[6:0] <= 7'h7F;
|
||||
9'h119: keyData[6:0] <= 7'h7F;
|
||||
9'h11a: keyData[6:0] <= 7'h7F;
|
||||
9'h11b: keyData[6:0] <= 7'h7F;
|
||||
9'h11c: keyData[6:0] <= 7'h7F;
|
||||
9'h11d: keyData[6:0] <= 7'h7F;
|
||||
9'h11e: keyData[6:0] <= 7'h7F;
|
||||
9'h11f: keyData[6:0] <= 7'h3A; //WINDOWS OR APPLICATION KEY (option)
|
||||
9'h120: keyData[6:0] <= 7'h7F;
|
||||
9'h121: keyData[6:0] <= 7'h7F;
|
||||
9'h122: keyData[6:0] <= 7'h7F;
|
||||
9'h123: keyData[6:0] <= 7'h7F;
|
||||
9'h124: keyData[6:0] <= 7'h7F;
|
||||
9'h125: keyData[6:0] <= 7'h7F;
|
||||
9'h126: keyData[6:0] <= 7'h7F;
|
||||
9'h127: keyData[6:0] <= 7'h7F;
|
||||
9'h128: keyData[6:0] <= 7'h7F;
|
||||
9'h129: keyData[6:0] <= 7'h7F;
|
||||
9'h12a: keyData[6:0] <= 7'h7F;
|
||||
9'h12b: keyData[6:0] <= 7'h7F;
|
||||
9'h12c: keyData[6:0] <= 7'h7F;
|
||||
9'h12d: keyData[6:0] <= 7'h7F;
|
||||
9'h12e: keyData[6:0] <= 7'h7F;
|
||||
9'h12f: keyData[6:0] <= 7'h7F;
|
||||
9'h130: keyData[6:0] <= 7'h7F;
|
||||
9'h131: keyData[6:0] <= 7'h7F;
|
||||
9'h132: keyData[6:0] <= 7'h7F;
|
||||
9'h133: keyData[6:0] <= 7'h7F;
|
||||
9'h134: keyData[6:0] <= 7'h7F;
|
||||
9'h135: keyData[6:0] <= 7'h7F;
|
||||
9'h136: keyData[6:0] <= 7'h7F;
|
||||
9'h137: keyData[6:0] <= 7'h7F;
|
||||
9'h138: keyData[6:0] <= 7'h7F;
|
||||
9'h139: keyData[6:0] <= 7'h7F;
|
||||
9'h13a: keyData[6:0] <= 7'h7F;
|
||||
9'h13b: keyData[6:0] <= 7'h7F;
|
||||
9'h13c: keyData[6:0] <= 7'h7F;
|
||||
9'h13d: keyData[6:0] <= 7'h7F;
|
||||
9'h13e: keyData[6:0] <= 7'h7F;
|
||||
9'h13f: keyData[6:0] <= 7'h7F;
|
||||
9'h140: keyData[6:0] <= 7'h7F;
|
||||
9'h141: keyData[6:0] <= 7'h7F;
|
||||
9'h142: keyData[6:0] <= 7'h7F;
|
||||
9'h143: keyData[6:0] <= 7'h7F;
|
||||
9'h144: keyData[6:0] <= 7'h7F;
|
||||
9'h145: keyData[6:0] <= 7'h7F;
|
||||
9'h146: keyData[6:0] <= 7'h7F;
|
||||
9'h147: keyData[6:0] <= 7'h7F;
|
||||
9'h148: keyData[6:0] <= 7'h7F;
|
||||
9'h149: keyData[6:0] <= 7'h7F;
|
||||
9'h14a: keyData[6:0] <= 7'h4B; //KP /
|
||||
9'h14b: keyData[6:0] <= 7'h7F;
|
||||
9'h14c: keyData[6:0] <= 7'h7F;
|
||||
9'h14d: keyData[6:0] <= 7'h7F;
|
||||
9'h14e: keyData[6:0] <= 7'h7F;
|
||||
9'h14f: keyData[6:0] <= 7'h7F;
|
||||
9'h150: keyData[6:0] <= 7'h7F;
|
||||
9'h151: keyData[6:0] <= 7'h7F;
|
||||
9'h152: keyData[6:0] <= 7'h7F;
|
||||
9'h153: keyData[6:0] <= 7'h7F;
|
||||
9'h154: keyData[6:0] <= 7'h7F;
|
||||
9'h155: keyData[6:0] <= 7'h7F;
|
||||
9'h156: keyData[6:0] <= 7'h7F;
|
||||
9'h157: keyData[6:0] <= 7'h7F;
|
||||
9'h158: keyData[6:0] <= 7'h7F;
|
||||
9'h159: keyData[6:0] <= 7'h7F;
|
||||
9'h15a: keyData[6:0] <= 7'h4C; //KP ENTER
|
||||
9'h15b: keyData[6:0] <= 7'h7F;
|
||||
9'h15c: keyData[6:0] <= 7'h7F;
|
||||
9'h15d: keyData[6:0] <= 7'h7F;
|
||||
9'h15e: keyData[6:0] <= 7'h7F;
|
||||
9'h15f: keyData[6:0] <= 7'h7F;
|
||||
9'h160: keyData[6:0] <= 7'h7F;
|
||||
9'h161: keyData[6:0] <= 7'h7F;
|
||||
9'h162: keyData[6:0] <= 7'h7F;
|
||||
9'h163: keyData[6:0] <= 7'h7F;
|
||||
9'h164: keyData[6:0] <= 7'h7F;
|
||||
9'h165: keyData[6:0] <= 7'h7F;
|
||||
9'h166: keyData[6:0] <= 7'h7F;
|
||||
9'h167: keyData[6:0] <= 7'h7F;
|
||||
9'h168: keyData[6:0] <= 7'h7F;
|
||||
9'h169: keyData[6:0] <= 7'h77; //END
|
||||
9'h16a: keyData[6:0] <= 7'h7F;
|
||||
9'h16b: keyData[6:0] <= 7'h3B; //ARROW LEFT
|
||||
9'h16c: keyData[6:0] <= 7'h73; //HOME
|
||||
9'h16d: keyData[6:0] <= 7'h7F;
|
||||
9'h16e: keyData[6:0] <= 7'h7F;
|
||||
9'h16f: keyData[6:0] <= 7'h7F;
|
||||
9'h170: keyData[6:0] <= 7'h72; //INSERT = HELP
|
||||
9'h171: keyData[6:0] <= 7'h75; //DELETE (KP clear?)
|
||||
9'h172: keyData[6:0] <= 7'h3D; //ARROW DOWN
|
||||
9'h173: keyData[6:0] <= 7'h7F;
|
||||
9'h174: keyData[6:0] <= 7'h3C; //ARROW RIGHT
|
||||
9'h175: keyData[6:0] <= 7'h3E; //ARROW UP
|
||||
9'h176: keyData[6:0] <= 7'h7F;
|
||||
9'h177: keyData[6:0] <= 7'h7F;
|
||||
9'h178: keyData[6:0] <= 7'h7F;
|
||||
9'h179: keyData[6:0] <= 7'h7F;
|
||||
9'h17a: keyData[6:0] <= 7'h79; //PGDN <OSD>
|
||||
9'h17b: keyData[6:0] <= 7'h7F;
|
||||
9'h17c: keyData[6:0] <= 7'h69; //PRTSCR (F13)
|
||||
9'h17d: keyData[6:0] <= 7'h74; //PGUP <OSD>
|
||||
9'h17e: keyData[6:0] <= 7'h71; //ctrl+break (F15)
|
||||
9'h17f: keyData[6:0] <= 7'h7F;
|
||||
9'h180: keyData[6:0] <= 7'h7F;
|
||||
9'h181: keyData[6:0] <= 7'h7F;
|
||||
9'h182: keyData[6:0] <= 7'h7F;
|
||||
9'h183: keyData[6:0] <= 7'h7F;
|
||||
9'h184: keyData[6:0] <= 7'h7F;
|
||||
9'h185: keyData[6:0] <= 7'h7F;
|
||||
9'h186: keyData[6:0] <= 7'h7F;
|
||||
9'h187: keyData[6:0] <= 7'h7F;
|
||||
9'h188: keyData[6:0] <= 7'h7F;
|
||||
9'h189: keyData[6:0] <= 7'h7F;
|
||||
9'h18a: keyData[6:0] <= 7'h7F;
|
||||
9'h18b: keyData[6:0] <= 7'h7F;
|
||||
9'h18c: keyData[6:0] <= 7'h7F;
|
||||
9'h18d: keyData[6:0] <= 7'h7F;
|
||||
9'h18e: keyData[6:0] <= 7'h7F;
|
||||
9'h18f: keyData[6:0] <= 7'h7F;
|
||||
9'h190: keyData[6:0] <= 7'h7F;
|
||||
9'h191: keyData[6:0] <= 7'h7F;
|
||||
9'h192: keyData[6:0] <= 7'h7F;
|
||||
9'h193: keyData[6:0] <= 7'h7F;
|
||||
9'h194: keyData[6:0] <= 7'h7F;
|
||||
9'h195: keyData[6:0] <= 7'h7F;
|
||||
9'h196: keyData[6:0] <= 7'h7F;
|
||||
9'h197: keyData[6:0] <= 7'h7F;
|
||||
9'h198: keyData[6:0] <= 7'h7F;
|
||||
9'h199: keyData[6:0] <= 7'h7F;
|
||||
9'h19a: keyData[6:0] <= 7'h7F;
|
||||
9'h19b: keyData[6:0] <= 7'h7F;
|
||||
9'h19c: keyData[6:0] <= 7'h7F;
|
||||
9'h19d: keyData[6:0] <= 7'h7F;
|
||||
9'h19e: keyData[6:0] <= 7'h7F;
|
||||
9'h19f: keyData[6:0] <= 7'h7F;
|
||||
9'h1a0: keyData[6:0] <= 7'h7F;
|
||||
9'h1a1: keyData[6:0] <= 7'h7F;
|
||||
9'h1a2: keyData[6:0] <= 7'h7F;
|
||||
9'h1a3: keyData[6:0] <= 7'h7F;
|
||||
9'h1a4: keyData[6:0] <= 7'h7F;
|
||||
9'h1a5: keyData[6:0] <= 7'h7F;
|
||||
9'h1a6: keyData[6:0] <= 7'h7F;
|
||||
9'h1a7: keyData[6:0] <= 7'h7F;
|
||||
9'h1a8: keyData[6:0] <= 7'h7F;
|
||||
9'h1a9: keyData[6:0] <= 7'h7F;
|
||||
9'h1aa: keyData[6:0] <= 7'h7F;
|
||||
9'h1ab: keyData[6:0] <= 7'h7F;
|
||||
9'h1ac: keyData[6:0] <= 7'h7F;
|
||||
9'h1ad: keyData[6:0] <= 7'h7F;
|
||||
9'h1ae: keyData[6:0] <= 7'h7F;
|
||||
9'h1af: keyData[6:0] <= 7'h7F;
|
||||
9'h1b0: keyData[6:0] <= 7'h7F;
|
||||
9'h1b1: keyData[6:0] <= 7'h7F;
|
||||
9'h1b2: keyData[6:0] <= 7'h7F;
|
||||
9'h1b3: keyData[6:0] <= 7'h7F;
|
||||
9'h1b4: keyData[6:0] <= 7'h7F;
|
||||
9'h1b5: keyData[6:0] <= 7'h7F;
|
||||
9'h1b6: keyData[6:0] <= 7'h7F;
|
||||
9'h1b7: keyData[6:0] <= 7'h7F;
|
||||
9'h1b8: keyData[6:0] <= 7'h7F;
|
||||
9'h1b9: keyData[6:0] <= 7'h7F;
|
||||
9'h1ba: keyData[6:0] <= 7'h7F;
|
||||
9'h1bb: keyData[6:0] <= 7'h7F;
|
||||
9'h1bc: keyData[6:0] <= 7'h7F;
|
||||
9'h1bd: keyData[6:0] <= 7'h7F;
|
||||
9'h1be: keyData[6:0] <= 7'h7F;
|
||||
9'h1bf: keyData[6:0] <= 7'h7F;
|
||||
9'h1c0: keyData[6:0] <= 7'h7F;
|
||||
9'h1c1: keyData[6:0] <= 7'h7F;
|
||||
9'h1c2: keyData[6:0] <= 7'h7F;
|
||||
9'h1c3: keyData[6:0] <= 7'h7F;
|
||||
9'h1c4: keyData[6:0] <= 7'h7F;
|
||||
9'h1c5: keyData[6:0] <= 7'h7F;
|
||||
9'h1c6: keyData[6:0] <= 7'h7F;
|
||||
9'h1c7: keyData[6:0] <= 7'h7F;
|
||||
9'h1c8: keyData[6:0] <= 7'h7F;
|
||||
9'h1c9: keyData[6:0] <= 7'h7F;
|
||||
9'h1ca: keyData[6:0] <= 7'h7F;
|
||||
9'h1cb: keyData[6:0] <= 7'h7F;
|
||||
9'h1cc: keyData[6:0] <= 7'h7F;
|
||||
9'h1cd: keyData[6:0] <= 7'h7F;
|
||||
9'h1ce: keyData[6:0] <= 7'h7F;
|
||||
9'h1cf: keyData[6:0] <= 7'h7F;
|
||||
9'h1d0: keyData[6:0] <= 7'h7F;
|
||||
9'h1d1: keyData[6:0] <= 7'h7F;
|
||||
9'h1d2: keyData[6:0] <= 7'h7F;
|
||||
9'h1d3: keyData[6:0] <= 7'h7F;
|
||||
9'h1d4: keyData[6:0] <= 7'h7F;
|
||||
9'h1d5: keyData[6:0] <= 7'h7F;
|
||||
9'h1d6: keyData[6:0] <= 7'h7F;
|
||||
9'h1d7: keyData[6:0] <= 7'h7F;
|
||||
9'h1d8: keyData[6:0] <= 7'h7F;
|
||||
9'h1d9: keyData[6:0] <= 7'h7F;
|
||||
9'h1da: keyData[6:0] <= 7'h7F;
|
||||
9'h1db: keyData[6:0] <= 7'h7F;
|
||||
9'h1dc: keyData[6:0] <= 7'h7F;
|
||||
9'h1dd: keyData[6:0] <= 7'h7F;
|
||||
9'h1de: keyData[6:0] <= 7'h7F;
|
||||
9'h1df: keyData[6:0] <= 7'h7F;
|
||||
9'h1e0: keyData[6:0] <= 7'h7F; //ps2 extended key(duplicate, see $e0)
|
||||
9'h1e1: keyData[6:0] <= 7'h7F;
|
||||
9'h1e2: keyData[6:0] <= 7'h7F;
|
||||
9'h1e3: keyData[6:0] <= 7'h7F;
|
||||
9'h1e4: keyData[6:0] <= 7'h7F;
|
||||
9'h1e5: keyData[6:0] <= 7'h7F;
|
||||
9'h1e6: keyData[6:0] <= 7'h7F;
|
||||
9'h1e7: keyData[6:0] <= 7'h7F;
|
||||
9'h1e8: keyData[6:0] <= 7'h7F;
|
||||
9'h1e9: keyData[6:0] <= 7'h7F;
|
||||
9'h1ea: keyData[6:0] <= 7'h7F;
|
||||
9'h1eb: keyData[6:0] <= 7'h7F;
|
||||
9'h1ec: keyData[6:0] <= 7'h7F;
|
||||
9'h1ed: keyData[6:0] <= 7'h7F;
|
||||
9'h1ee: keyData[6:0] <= 7'h7F;
|
||||
9'h1ef: keyData[6:0] <= 7'h7F;
|
||||
9'h1f0: keyData[6:0] <= 7'h7F; //ps2 release code(duplicate, see $f0)
|
||||
9'h1f1: keyData[6:0] <= 7'h7F;
|
||||
9'h1f2: keyData[6:0] <= 7'h7F;
|
||||
9'h1f3: keyData[6:0] <= 7'h7F;
|
||||
9'h1f4: keyData[6:0] <= 7'h7F;
|
||||
9'h1f5: keyData[6:0] <= 7'h7F;
|
||||
9'h1f6: keyData[6:0] <= 7'h7F;
|
||||
9'h1f7: keyData[6:0] <= 7'h7F;
|
||||
9'h1f8: keyData[6:0] <= 7'h7F;
|
||||
9'h1f9: keyData[6:0] <= 7'h7F;
|
||||
9'h1fa: keyData[6:0] <= 7'h7F; //ps2 ack code(duplicate see $fa)
|
||||
9'h1fb: keyData[6:0] <= 7'h7F;
|
||||
9'h1fc: keyData[6:0] <= 7'h7F;
|
||||
9'h1fd: keyData[6:0] <= 7'h7F;
|
||||
9'h1fe: keyData[6:0] <= 7'h7F;
|
||||
9'h1ff: keyData[6:0] <= 7'h7F;
|
||||
endcase
|
||||
if(capslock_key && press) capslock <= ~capslock;
|
||||
if(!(capslock_key && capslock)) begin
|
||||
keyData[7] <= ~press;
|
||||
keyStrobe <= 1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
keyStrobe <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
if (reset) capslock <= 0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -9,7 +9,7 @@ module addrController_top(
|
|||
|
||||
// system config:
|
||||
input turbo, // 0 = normal, 1 = faster
|
||||
input configROMSize, // 0 = 64K ROM, 1 = 128K ROM
|
||||
input [1:0] configROMSize, // 0 = 64K ROM, 1 = 128K ROM, 2 = 256K ROM
|
||||
input [1:0] configRAMSize, // 0 = 128K, 1 = 512K, 2 = 1MB, 3 = 4MB RAM
|
||||
|
||||
// 68000 CPU memory interface:
|
||||
|
@ -38,6 +38,7 @@ module addrController_top(
|
|||
output selectVIA,
|
||||
output selectRAM,
|
||||
output selectROM,
|
||||
output selectSEOverlay,
|
||||
|
||||
// video:
|
||||
output hsync,
|
||||
|
@ -155,14 +156,14 @@ module addrController_top(
|
|||
wire rom_access = (cpuBusControl && selectROM);
|
||||
|
||||
// simulate smaller RAM/ROM sizes
|
||||
assign macAddr[16] = rom_access && configROMSize == 1'b0 ? 1'b0 : // force A16 to 0 for 64K ROM access
|
||||
assign macAddr[16] = rom_access && configROMSize == 2'b00 ? 1'b0 : // force A16 to 0 for 64K ROM access
|
||||
addrMux[16];
|
||||
assign macAddr[17] = ram_access && configRAMSize == 2'b00 ? 1'b0 : // force A17 to 0 for 128K RAM access
|
||||
rom_access && configROMSize == 1'b1 ? 1'b0 : // force A17 to 0 for 128K ROM access
|
||||
rom_access && configROMSize == 1'b0 ? 1'b1 : // force A17 to 1 for 64K ROM access (64K ROM image is at $20000)
|
||||
rom_access && configROMSize == 2'b01 ? 1'b0 : // force A17 to 0 for 128K ROM access
|
||||
rom_access && configROMSize == 2'b00 ? 1'b1 : // force A17 to 1 for 64K ROM access (64K ROM image is at $20000)
|
||||
addrMux[17];
|
||||
assign macAddr[18] = ram_access && configRAMSize == 2'b00 ? 1'b0 : // force A18 to 0 for 128K RAM access
|
||||
rom_access ? 1'b0 : // force A18 to 0 for ROM access
|
||||
rom_access && configROMSize != 2'b11 ? 1'b0 : // force A18 to 0 for 64K/128K/256K ROM access
|
||||
addrMux[18];
|
||||
assign macAddr[19] = ram_access && configRAMSize[1] == 1'b0 ? 1'b0 : // force A19 to 0 for 128K or 512K RAM access
|
||||
rom_access ? 1'b0 : // force A19 to 0 for ROM access
|
||||
|
@ -188,6 +189,7 @@ module addrController_top(
|
|||
|
||||
// address decoding
|
||||
addrDecoder ad(
|
||||
.configROMSize(configROMSize),
|
||||
.address(cpuAddr),
|
||||
._cpuAS(_cpuAS),
|
||||
.memoryOverlayOn(memoryOverlayOn),
|
||||
|
@ -196,7 +198,8 @@ module addrController_top(
|
|||
.selectSCSI(selectSCSI),
|
||||
.selectSCC(selectSCC),
|
||||
.selectIWM(selectIWM),
|
||||
.selectVIA(selectVIA));
|
||||
.selectVIA(selectVIA),
|
||||
.selectSEOverlay(selectSEOverlay));
|
||||
|
||||
// video
|
||||
videoTimer vt(
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
*/
|
||||
|
||||
module addrDecoder(
|
||||
input [1:0] configROMSize,
|
||||
input [23:0] address,
|
||||
input _cpuAS,
|
||||
input memoryOverlayOn,
|
||||
|
@ -88,7 +89,8 @@ module addrDecoder(
|
|||
output reg selectSCSI,
|
||||
output reg selectSCC,
|
||||
output reg selectIWM,
|
||||
output reg selectVIA
|
||||
output reg selectVIA,
|
||||
output reg selectSEOverlay
|
||||
);
|
||||
|
||||
always @(*) begin
|
||||
|
@ -98,34 +100,44 @@ module addrDecoder(
|
|||
selectSCC = 0;
|
||||
selectIWM = 0;
|
||||
selectVIA = 0;
|
||||
selectSEOverlay = 0;
|
||||
|
||||
casez (address[23:20])
|
||||
4'b00??: begin
|
||||
4'b00??: begin //00 0000 - 3F FFFF
|
||||
if (memoryOverlayOn == 0)
|
||||
selectRAM = !_cpuAS;
|
||||
else begin
|
||||
if (address[23:20] == 0) begin
|
||||
// Mac Plus: repeated images of overlay ROM only extend to $0F0000
|
||||
// Mac 512K: more repeated ROM images at $020000-$02FFFF
|
||||
// Mac SE: overlay ROM at $00 0000 - $0F FFFF
|
||||
selectROM = !_cpuAS;
|
||||
end
|
||||
end
|
||||
end
|
||||
4'b0100:
|
||||
if( address[17] == 1'b0) // <- this detects SCSI!!!
|
||||
4'b0100: begin //40 0000 - 4F FFFF
|
||||
if(configROMSize[1] || address[17] == 1'b0) // <- this detects SCSI (on Plus)!!!
|
||||
selectROM = !_cpuAS;
|
||||
4'b0101:
|
||||
if (address[19:12] == 8'h80)
|
||||
selectSEOverlay = !_cpuAS;
|
||||
end
|
||||
4'b0101: begin //50 000 - 5F FFFF
|
||||
if (address[19]) // 58 000 - 5F FFFF
|
||||
selectSCSI = !_cpuAS;
|
||||
selectSEOverlay = !_cpuAS;
|
||||
end
|
||||
4'b0110:
|
||||
if (memoryOverlayOn)
|
||||
selectRAM = !_cpuAS;
|
||||
4'b10?1:
|
||||
selectSCC = !_cpuAS;
|
||||
4'b1100: // C0 000 - CF FFF
|
||||
if (!configROMSize[1])
|
||||
selectIWM = !_cpuAS;
|
||||
4'b1101:
|
||||
selectIWM = !_cpuAS;
|
||||
4'b1110:
|
||||
selectVIA = !_cpuAS;
|
||||
if (address[19]) // E8 000 - EF FFF
|
||||
selectVIA = !_cpuAS;
|
||||
default:
|
||||
; // select nothing
|
||||
endcase
|
||||
|
|
|
@ -7,6 +7,7 @@ module dataController_top(
|
|||
input E_falling,
|
||||
|
||||
// system control:
|
||||
input machineType, // 0 - Mac Plus, 1 - Mac SE
|
||||
input _systemReset,
|
||||
|
||||
// 68000 CPU control:
|
||||
|
@ -28,6 +29,7 @@ module dataController_top(
|
|||
input selectSCC,
|
||||
input selectIWM,
|
||||
input selectVIA,
|
||||
input selectSEOverlay,
|
||||
input _cpuVMA,
|
||||
|
||||
// RAM/ROM:
|
||||
|
@ -79,20 +81,20 @@ module dataController_top(
|
|||
input dskReadAckExt,
|
||||
|
||||
// connections to io controller
|
||||
input [1:0] img_mounted,
|
||||
input [31:0] img_size,
|
||||
output [31:0] io_lba0,
|
||||
output [31:0] io_lba1,
|
||||
output [1:0] io_rd,
|
||||
output [1:0] io_wr,
|
||||
input [1:0] io_ack,
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output [15:0] sd_buff_din0,
|
||||
output [15:0] sd_buff_din1,
|
||||
input sd_buff_wr
|
||||
input [SCSI_DEVS-1:0] img_mounted,
|
||||
input [31:0] img_size,
|
||||
output [31:0] io_lba[SCSI_DEVS],
|
||||
output [SCSI_DEVS-1:0] io_rd,
|
||||
output [SCSI_DEVS-1:0] io_wr,
|
||||
input [SCSI_DEVS-1:0] io_ack,
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output [15:0] sd_buff_din[SCSI_DEVS],
|
||||
input sd_buff_wr
|
||||
);
|
||||
|
||||
parameter SCSI_DEVS = 2;
|
||||
|
||||
// add binary volume levels according to volume setting
|
||||
assign audioOut =
|
||||
(snd_vol[0]?audio_x1:11'd0) +
|
||||
|
@ -167,13 +169,13 @@ module dataController_top(
|
|||
assign memoryDataOut = cpuDataIn;
|
||||
|
||||
// SCSI
|
||||
ncr5380 scsi(
|
||||
ncr5380 #(SCSI_DEVS) scsi(
|
||||
.clk(clk32),
|
||||
.ce(clk8_en_p),
|
||||
.reset(!_cpuReset),
|
||||
.bus_cs(selectSCSI),
|
||||
.bus_we(!_cpuRW),
|
||||
.bus_rs(cpuAddrRegMid),
|
||||
.ior(!_cpuUDS),
|
||||
.iow(!_cpuLDS),
|
||||
.dack(cpuAddrRegHi[0]), // A9
|
||||
.wdata(cpuDataIn[15:8]),
|
||||
.rdata(scsiDataOut),
|
||||
|
@ -181,16 +183,14 @@ module dataController_top(
|
|||
// connections to io controller
|
||||
.img_mounted( img_mounted ),
|
||||
.img_size( img_size ),
|
||||
.io_lba0 ( io_lba0 ),
|
||||
.io_lba1 ( io_lba1 ),
|
||||
.io_lba ( io_lba ),
|
||||
.io_rd ( io_rd ),
|
||||
.io_wr ( io_wr ),
|
||||
.io_ack ( io_ack ),
|
||||
|
||||
.sd_buff_addr(sd_buff_addr),
|
||||
.sd_buff_dout(sd_buff_dout),
|
||||
.sd_buff_din0(sd_buff_din0),
|
||||
.sd_buff_din1(sd_buff_din1),
|
||||
.sd_buff_din(sd_buff_din),
|
||||
.sd_buff_wr(sd_buff_wr)
|
||||
);
|
||||
|
||||
|
@ -212,9 +212,19 @@ module dataController_top(
|
|||
end
|
||||
wire onesec = vblankCount == 59;
|
||||
|
||||
// Mac SE ROM overlay switch
|
||||
reg SEOverlay;
|
||||
always @(posedge clk32) begin
|
||||
if (!_cpuReset)
|
||||
SEOverlay <= 1;
|
||||
else if (selectSEOverlay)
|
||||
SEOverlay <= 0;
|
||||
end
|
||||
|
||||
// VIA
|
||||
wire [2:0] snd_vol;
|
||||
wire snd_ena;
|
||||
wire driveSel; // internal drive select, 0 - upper, 1 - lower
|
||||
|
||||
wire [7:0] via_pa_i, via_pa_o, via_pa_oe;
|
||||
wire [7:0] via_pb_i, via_pb_o, via_pb_oe;
|
||||
|
@ -225,13 +235,14 @@ module dataController_top(
|
|||
//port A
|
||||
assign via_pa_i = {sccWReq, ~via_pa_oe[6:0] | via_pa_o[6:0]};
|
||||
assign snd_vol = ~via_pa_oe[2:0] | via_pa_o[2:0];
|
||||
assign snd_alt = ~(~via_pa_oe[3] | via_pa_o[3]);
|
||||
assign memoryOverlayOn = ~via_pa_oe[4] | via_pa_o[4];
|
||||
assign snd_alt = machineType ? 1'b0 : ~(~via_pa_oe[3] | via_pa_o[3]);
|
||||
assign driveSel = machineType ? ~via_pa_oe[4] | via_pa_o[4] : 1'b1;
|
||||
assign memoryOverlayOn = machineType ? SEOverlay : ~via_pa_oe[4] | via_pa_o[4];
|
||||
assign SEL = ~via_pa_oe[5] | via_pa_o[5];
|
||||
assign vid_alt = ~via_pa_oe[6] | via_pa_o[6];
|
||||
|
||||
//port B
|
||||
assign via_pb_i = {1'b1, _hblank, mouseY2, mouseX2, mouseButton, 2'b11, rtcdat_o};
|
||||
assign via_pb_i = {1'b1, {3{machineType}} | {_hblank, mouseY2, mouseX2}, machineType ? _ADBint : mouseButton, 2'b11, rtcdat_o};
|
||||
assign snd_ena = ~via_pb_oe[7] | via_pb_o[7];
|
||||
|
||||
assign viaDataOut[7:0] = 8'hEF;
|
||||
|
@ -286,6 +297,11 @@ module dataController_top(
|
|||
.dat_o (rtcdat_o)
|
||||
);
|
||||
|
||||
wire _ADBint;
|
||||
wire ADBST0 = ~via_pb_oe[4] | via_pb_o[4];
|
||||
wire ADBST1 = ~via_pb_oe[5] | via_pb_o[5];
|
||||
wire ADBListen;
|
||||
|
||||
reg kbdclk;
|
||||
reg [10:0] kbdclk_count;
|
||||
reg kbd_transmitting, kbd_wait_receiving, kbd_receiving;
|
||||
|
@ -303,7 +319,7 @@ module dataController_top(
|
|||
if (clk8_en_p) begin
|
||||
if ((kbd_transmitting && !kbd_wait_receiving) || kbd_receiving) begin
|
||||
kbdclk_count <= kbdclk_count + 1'd1;
|
||||
if (kbdclk_count == 12'd1300) begin // ~165usec
|
||||
if (kbdclk_count == (machineType ? 8'd80 : 12'd1300)) begin // ~165usec - Mac Plus / faster - ADB
|
||||
kbdclk <= ~kbdclk;
|
||||
kbdclk_count <= 0;
|
||||
if (kbdclk) begin
|
||||
|
@ -322,28 +338,46 @@ module dataController_top(
|
|||
// Keyboard control
|
||||
always @(posedge clk32) begin
|
||||
reg kbdclk_d;
|
||||
reg ADBListenD;
|
||||
if (!_cpuReset) begin
|
||||
kbd_bitcnt <= 0;
|
||||
kbd_transmitting <= 0;
|
||||
kbd_wait_receiving <= 0;
|
||||
kbd_data_valid <= 0;
|
||||
ADBListenD <= 0;
|
||||
end else if (clk8_en_p) begin
|
||||
if (kbd_in_strobe) begin
|
||||
if (kbd_in_strobe && !machineType) begin
|
||||
kbd_to_mac <= kbd_in_data;
|
||||
kbd_data_valid <= 1;
|
||||
end
|
||||
|
||||
if (adb_dout_strobe && machineType) begin
|
||||
kbd_to_mac <= adb_dout;
|
||||
kbd_receiving <= 1;
|
||||
end
|
||||
|
||||
kbd_out_strobe <= 0;
|
||||
adb_din_strobe <= 0;
|
||||
kbdclk_d <= kbdclk;
|
||||
|
||||
// Only the Macintosh can initiate communication over the keyboard lines. On
|
||||
// power-up of either the Macintosh or the keyboard, the Macintosh is in
|
||||
// charge, and the external device is passive. The Macintosh signals that it's
|
||||
// ready to begin communication by pulling the keyboard data line low.
|
||||
if (!kbd_transmitting && !kbd_receiving && !kbddat_i) begin
|
||||
if (!machineType && !kbd_transmitting && !kbd_receiving && !kbddat_i) begin
|
||||
kbd_transmitting <= 1;
|
||||
kbd_bitcnt <= 0;
|
||||
end
|
||||
|
||||
// ADB transmission start
|
||||
if (machineType && !kbd_transmitting && !kbd_receiving) begin
|
||||
ADBListenD <= ADBListen;
|
||||
if (!ADBListenD && ADBListen) begin
|
||||
kbd_transmitting <= 1;
|
||||
kbd_bitcnt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// The last bit of the command leaves the keyboard data line low; the
|
||||
// Macintosh then indicates it's ready to receive the keyboard's response by
|
||||
// setting the data line high.
|
||||
|
@ -359,8 +393,14 @@ module dataController_top(
|
|||
|
||||
if (kbd_bitcnt == 3'd7) begin
|
||||
if (kbd_transmitting) begin
|
||||
kbd_out_strobe <= 1;
|
||||
kbd_wait_receiving <= 1;
|
||||
if (!machineType) begin
|
||||
kbd_out_strobe <= 1;
|
||||
kbd_wait_receiving <= 1;
|
||||
end else begin
|
||||
adb_din_strobe <= 1;
|
||||
adb_din <= kbd_out_data;
|
||||
kbd_transmitting <= 0;
|
||||
end
|
||||
end
|
||||
if (kbd_receiving) begin
|
||||
kbd_receiving <= 0;
|
||||
|
@ -383,6 +423,7 @@ module dataController_top(
|
|||
.dataIn(cpuDataIn),
|
||||
.cpuAddrRegHi(cpuAddrRegHi),
|
||||
.SEL(SEL),
|
||||
.driveSel(driveSel),
|
||||
.dataOut(iwmDataOut),
|
||||
.insertDisk(insertDisk),
|
||||
.diskSides(diskSides),
|
||||
|
@ -458,4 +499,26 @@ module dataController_top(
|
|||
.capslock(capslock)
|
||||
);
|
||||
|
||||
reg [7:0] adb_din;
|
||||
reg adb_din_strobe;
|
||||
wire [7:0] adb_dout;
|
||||
wire adb_dout_strobe;
|
||||
|
||||
adb adb(
|
||||
.clk(clk32),
|
||||
.clk_en(clk8_en_p),
|
||||
.reset(~_cpuReset),
|
||||
.st({ADBST1, ADBST0}),
|
||||
._int(_ADBint),
|
||||
.viaBusy(kbd_transmitting || kbd_receiving),
|
||||
.listen(ADBListen),
|
||||
.adb_din(adb_din),
|
||||
.adb_din_strobe(adb_din_strobe),
|
||||
.adb_dout(adb_dout),
|
||||
.adb_dout_strobe(adb_dout_strobe),
|
||||
|
||||
.ps2_mouse(ps2_mouse),
|
||||
.ps2_key(ps2_key)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -215,7 +215,8 @@ module floppy
|
|||
|
||||
wire lstrbEdge = lstrb == 1'b0 && lstrbPrev == 1'b1;
|
||||
|
||||
assign readData = (driveReadAddr == `DRIVE_REG_RDDATA0 || driveReadAddr == `DRIVE_REG_RDDATA1) ? diskDataIn :
|
||||
assign readData = _enable ? 8'hFF :
|
||||
(driveReadAddr == `DRIVE_REG_RDDATA0 || driveReadAddr == `DRIVE_REG_RDDATA1) ? diskDataIn :
|
||||
{ driveRegsAsRead[driveReadAddr], 7'h00 };
|
||||
|
||||
// write drive registers
|
||||
|
|
|
@ -42,6 +42,7 @@ module iwm
|
|||
input [15:0] dataIn,
|
||||
input [3:0] cpuAddrRegHi,
|
||||
input SEL, // from VIA
|
||||
input driveSel, // internal drive select, 0 - upper, 1 - lower
|
||||
output [15:0] dataOut,
|
||||
input [1:0] insertDisk,
|
||||
output [1:0] diskEject,
|
||||
|
@ -94,7 +95,7 @@ module iwm
|
|||
.ca2(ca2),
|
||||
.SEL(SEL),
|
||||
.lstrb(lstrb),
|
||||
._enable(~diskEnableInt),
|
||||
._enable(~(diskEnableInt & driveSel)),
|
||||
.writeData(writeData),
|
||||
.readData(readDataInt),
|
||||
.advanceDriveHead(advanceDriveHead),
|
||||
|
|
|
@ -45,38 +45,38 @@
|
|||
module ncr5380
|
||||
(
|
||||
input clk,
|
||||
input ce,
|
||||
|
||||
input reset,
|
||||
|
||||
/* Bus interface. 3-bit address, to be wired
|
||||
* appropriately upstream (to A4..A6) plus one
|
||||
* more bit (A9) wired as dack.
|
||||
*/
|
||||
input bus_cs,
|
||||
input bus_we,
|
||||
input bus_cs,
|
||||
input [2:0] bus_rs,
|
||||
input dack,
|
||||
input ior,
|
||||
input iow,
|
||||
input dack,
|
||||
output dreq,
|
||||
input [7:0] wdata,
|
||||
output [7:0] rdata,
|
||||
|
||||
|
||||
// connections to io controller
|
||||
input [1:0] img_mounted,
|
||||
input [31:0] img_size,
|
||||
input [DEVS-1:0] img_mounted,
|
||||
input [31:0] img_size,
|
||||
|
||||
output [31:0] io_lba0,
|
||||
output [31:0] io_lba1,
|
||||
output [1:0] io_rd,
|
||||
output [1:0] io_wr,
|
||||
input [1:0] io_ack,
|
||||
output reg [31:0] io_lba[DEVS],
|
||||
output [DEVS-1:0] io_rd,
|
||||
output [DEVS-1:0] io_wr,
|
||||
input [DEVS-1:0] io_ack,
|
||||
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output [15:0] sd_buff_din0,
|
||||
output [15:0] sd_buff_din1,
|
||||
input sd_buff_wr
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output [15:0] sd_buff_din[DEVS],
|
||||
input sd_buff_wr
|
||||
);
|
||||
parameter DEVS = 2;
|
||||
|
||||
assign dreq = scsi_req & dma_en;
|
||||
|
||||
reg [7:0] mr; /* Mode Register */
|
||||
reg [7:0] icr; /* Initiator Command Register */
|
||||
|
@ -86,21 +86,20 @@ module ncr5380
|
|||
/* Data in and out latches and associated
|
||||
* control logic for DMA
|
||||
*/
|
||||
wire [7:0] din;
|
||||
reg [7:0] din;
|
||||
reg [7:0] dout;
|
||||
reg dphase;
|
||||
reg dma_en;
|
||||
|
||||
/* --- Main host-side interface --- */
|
||||
|
||||
/* Register & DMA accesses decodes */
|
||||
reg dma_rd;
|
||||
reg dma_wr;
|
||||
reg reg_wr;
|
||||
reg dma_ack;
|
||||
|
||||
wire i_dma_rd = bus_cs & dack & ~bus_we;
|
||||
wire i_dma_wr = bus_cs & dack & bus_we;
|
||||
wire i_reg_wr = bus_cs & ~dack & bus_we;
|
||||
wire i_dma_rd = bus_cs & dack & ior;
|
||||
wire i_dma_wr = bus_cs & dack & iow;
|
||||
wire i_reg_wr = bus_cs & ~dack & iow;
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg old_dma_rd, old_dma_wr, old_reg_wr;
|
||||
|
@ -109,13 +108,13 @@ module ncr5380
|
|||
old_dma_wr <= i_dma_wr;
|
||||
old_reg_wr <= i_reg_wr;
|
||||
|
||||
dma_rd <= 0;
|
||||
dma_wr <= 0;
|
||||
dma_ack <= 0;
|
||||
reg_wr <= 0;
|
||||
|
||||
if(~old_dma_wr & i_dma_wr) dma_wr <= 1;
|
||||
else if(~old_dma_rd & i_dma_rd) dma_rd <= 1;
|
||||
else if(~old_reg_wr & i_reg_wr) reg_wr <= 1;
|
||||
if(~old_reg_wr & i_reg_wr) reg_wr <= 1;
|
||||
if((old_dma_wr & ~i_dma_wr) | (old_dma_rd & ~i_dma_rd)) dma_ack <= dma_en;
|
||||
end
|
||||
|
||||
/* System bus reads */
|
||||
|
@ -130,31 +129,6 @@ module ncr5380
|
|||
bus_rs == `RREG_RST ? 8'hff :
|
||||
8'hff;
|
||||
|
||||
/* DMA handhsaking logic. Two phase logic, in phase 0
|
||||
* DRQ follows SCSI _REQ until we see DACK. In phase 1
|
||||
* we just wait for SCSI _REQ to go down and go back to
|
||||
* phase 0. We assert SCSI _ACK in phase 1.
|
||||
*/
|
||||
always@(posedge clk or posedge reset) begin
|
||||
if (reset) begin
|
||||
dphase <= 0;
|
||||
end else begin
|
||||
if (!dma_en) begin
|
||||
dphase <= 0;
|
||||
end else if (dphase == 0) begin
|
||||
/* Be careful to do that in bus phase 1,
|
||||
* not phase 0, or we would incorrectly
|
||||
* assert bus_hold and lock up the system
|
||||
*/
|
||||
if ((dma_rd || dma_wr) && scsi_req) begin
|
||||
dphase <= 1;
|
||||
end
|
||||
end else if (!scsi_req) begin
|
||||
dphase <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/* Data out latch (in DMA mode, this is one cycle after we've
|
||||
* asserted ACK)
|
||||
*/
|
||||
|
@ -241,119 +215,88 @@ module ncr5380
|
|||
/* BSY logic (simplified arbitration, see notes) */
|
||||
wire scsi_bsy =
|
||||
icr[`ICR_A_BSY] |
|
||||
scsi2_bsy |
|
||||
scsi6_bsy |
|
||||
|target_bsy |
|
||||
//scsi2_bsy |
|
||||
//scsi6_bsy |
|
||||
mr[`MR_ARB];
|
||||
|
||||
/* Remains of simplified arbitration logic */
|
||||
wire icr_aip = mr[`MR_ARB];
|
||||
wire icr_la = 0;
|
||||
|
||||
reg dma_ack;
|
||||
always @(posedge clk) if(ce) dma_ack <= dphase;
|
||||
|
||||
/* Other ORed SCSI signals */
|
||||
wire scsi_sel = icr[`ICR_A_SEL];
|
||||
wire scsi_rst = icr[`ICR_A_RST];
|
||||
wire scsi_ack = icr[`ICR_A_ACK] | dma_ack;
|
||||
wire scsi_atn = icr[`ICR_A_ATN];
|
||||
/*
|
||||
wire scsi_cd = scsi2_cd;
|
||||
wire scsi_io = scsi2_io;
|
||||
wire scsi_msg = scsi2_msg;
|
||||
wire scsi_req = scsi2_req;
|
||||
|
||||
assign din = scsi2_dout;
|
||||
/* Mux target signals */
|
||||
reg scsi_cd, scsi_io, scsi_msg, scsi_req;
|
||||
|
||||
assign io_lba = io_lba_2;
|
||||
assign sd_buff_din = sd_buff_din_2;
|
||||
*/
|
||||
/* Other trivial lines set by target */
|
||||
always begin
|
||||
integer i;
|
||||
scsi_cd = 0;
|
||||
scsi_io = 0;
|
||||
scsi_msg = 0;
|
||||
scsi_req = 0;
|
||||
din = 8'h55;
|
||||
|
||||
wire scsi_cd = (scsi2_bsy) ? scsi2_cd : scsi6_cd;
|
||||
wire scsi_io = (scsi2_bsy) ? scsi2_io : scsi6_io;
|
||||
wire scsi_msg = (scsi2_bsy) ? scsi2_msg : scsi6_msg;
|
||||
wire scsi_req = (scsi2_bsy) ? scsi2_req : scsi6_req;
|
||||
for (i = 0; i < DEVS; i = i + 1) begin
|
||||
if (target_bsy[i]) begin
|
||||
scsi_cd = target_cd[i];
|
||||
scsi_io = target_io[i];
|
||||
scsi_msg = target_msg[i];
|
||||
scsi_req = target_req[i];
|
||||
din = target_dout[i];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign din = scsi2_bsy ? scsi2_dout :
|
||||
scsi6_bsy ? scsi6_dout :
|
||||
8'h55;
|
||||
// input signals from targets
|
||||
wire [DEVS-1:0] target_bsy;
|
||||
wire [DEVS-1:0] target_msg;
|
||||
wire [DEVS-1:0] target_io;
|
||||
wire [DEVS-1:0] target_cd;
|
||||
wire [DEVS-1:0] target_req;
|
||||
wire [7:0] target_dout[DEVS];
|
||||
|
||||
// input signals from target 2
|
||||
wire scsi2_bsy, scsi2_msg, scsi2_io, scsi2_cd, scsi2_req;
|
||||
wire [7:0] scsi2_dout;
|
||||
generate
|
||||
genvar i;
|
||||
for (i = 0; i < DEVS; i = i + 1) begin : target
|
||||
// connect a target
|
||||
scsi #(.ID(3'd6 - i[2:0])) target
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst ( scsi_rst ),
|
||||
.sel ( scsi_sel ),
|
||||
.atn ( scsi_atn ),
|
||||
|
||||
// connect a target
|
||||
scsi #(.ID(2)) scsi2
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst ( scsi_rst ),
|
||||
.sel ( scsi_sel ),
|
||||
.atn ( scsi_atn ),
|
||||
.ack ( scsi_ack ),
|
||||
|
||||
.ack ( scsi_ack ),
|
||||
.bsy ( target_bsy[i] ),
|
||||
.msg ( target_msg[i] ),
|
||||
.cd ( target_cd[i] ),
|
||||
.io ( target_io[i] ),
|
||||
.req ( target_req[i] ),
|
||||
.dout ( target_dout[i] ),
|
||||
|
||||
.bsy ( scsi2_bsy ),
|
||||
.msg ( scsi2_msg ),
|
||||
.cd ( scsi2_cd ),
|
||||
.io ( scsi2_io ),
|
||||
.req ( scsi2_req ),
|
||||
.dout ( scsi2_dout ),
|
||||
.din ( dout ),
|
||||
|
||||
.din ( dout ),
|
||||
|
||||
// connection to io controller to read and write sectors
|
||||
// to sd card
|
||||
.img_mounted(img_mounted[1]),
|
||||
.img_blocks(img_size[31:9]),
|
||||
.io_lba ( io_lba1 ),
|
||||
.io_rd ( io_rd[1] ),
|
||||
.io_wr ( io_wr[1] ),
|
||||
.io_ack ( io_ack[1] ),
|
||||
|
||||
.sd_buff_addr( sd_buff_addr ),
|
||||
.sd_buff_dout( sd_buff_dout ),
|
||||
.sd_buff_din( sd_buff_din1 ),
|
||||
.sd_buff_wr( sd_buff_wr )
|
||||
);
|
||||
|
||||
|
||||
// input signals from target 6
|
||||
wire scsi6_bsy, scsi6_msg, scsi6_io, scsi6_cd, scsi6_req;
|
||||
wire [7:0] scsi6_dout;
|
||||
|
||||
scsi #(.ID(6)) scsi6
|
||||
(
|
||||
.clk ( clk ) , // input clk
|
||||
.rst ( scsi_rst ) , // input rst
|
||||
.sel ( scsi_sel ) , // input sel
|
||||
.atn ( scsi_atn ) , // input atn
|
||||
|
||||
.ack ( scsi_ack ) , // input ack
|
||||
|
||||
.bsy ( scsi6_bsy ) , // output bsy
|
||||
.msg ( scsi6_msg ) , // output msg
|
||||
.cd ( scsi6_cd ) , // output cd
|
||||
.io ( scsi6_io ) , // output io
|
||||
.req ( scsi6_req ) , // output req
|
||||
.dout ( scsi6_dout ) , // output [7:0] dout
|
||||
|
||||
.din ( dout ) , // input [7:0] din
|
||||
|
||||
// connection to io controller to read and write sectors
|
||||
// to sd card
|
||||
.img_mounted( img_mounted[0] ),
|
||||
.img_blocks( img_size[31:9] ),
|
||||
.io_lba ( io_lba0 ) , // output [31:0] io_lba
|
||||
.io_rd ( io_rd[0] ) , // output io_rd
|
||||
.io_wr ( io_wr[0] ) , // output io_wr
|
||||
.io_ack ( io_ack[0] ) , // input io_ack
|
||||
|
||||
.sd_buff_addr( sd_buff_addr ) , // input [8:0] sd_buff_addr
|
||||
.sd_buff_dout( sd_buff_dout ) , // input [7:0] sd_buff_dout
|
||||
.sd_buff_din( sd_buff_din0 ) , // output [7:0] sd_buff_din
|
||||
.sd_buff_wr( sd_buff_wr ) // input sd_buff_wr
|
||||
);
|
||||
// connection to io controller to read and write sectors
|
||||
// to sd card
|
||||
.img_mounted(img_mounted[i]),
|
||||
.img_blocks(img_size),
|
||||
.io_lba ( io_lba[i] ),
|
||||
.io_rd ( io_rd[i] ),
|
||||
.io_wr ( io_wr[i] ),
|
||||
.io_ack ( io_ack[i] & target_bsy[i] ),
|
||||
|
||||
.sd_buff_addr( sd_buff_addr ),
|
||||
.sd_buff_dout( sd_buff_dout ),
|
||||
.sd_buff_din( sd_buff_din[i] ),
|
||||
.sd_buff_wr( sd_buff_wr & target_bsy[i] )
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
262
rtl/scsi.v
262
rtl/scsi.v
|
@ -1,5 +1,4 @@
|
|||
/* verilator lint_off UNUSED */
|
||||
/* verilator lint_off SYNCASYNCNET */
|
||||
|
||||
// scsi.v
|
||||
// implements a target only scsi device
|
||||
|
@ -26,45 +25,73 @@ module scsi
|
|||
|
||||
// interface to io controller
|
||||
input img_mounted,
|
||||
input [23:0] img_blocks,
|
||||
input [31:0] img_blocks,
|
||||
output [31:0] io_lba,
|
||||
output reg io_rd,
|
||||
output reg io_wr,
|
||||
input io_ack,
|
||||
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output reg [15:0] sd_buff_din,
|
||||
input sd_buff_wr
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output [15:0] sd_buff_din,
|
||||
input sd_buff_wr
|
||||
);
|
||||
|
||||
|
||||
// SCSI device id
|
||||
parameter [7:0] ID = 0;
|
||||
parameter [2:0] ID = 0;
|
||||
|
||||
`define PHASE_IDLE 3'd0
|
||||
`define PHASE_CMD_IN 3'd1
|
||||
`define PHASE_DATA_OUT 3'd2
|
||||
`define PHASE_DATA_IN 3'd3
|
||||
`define PHASE_STATUS_OUT 3'd4
|
||||
`define PHASE_MESSAGE_OUT 3'd5
|
||||
localparam PHASE_IDLE = 3'd0;
|
||||
localparam PHASE_CMD_IN = 3'd1;
|
||||
localparam PHASE_DATA_OUT = 3'd2;
|
||||
localparam PHASE_DATA_IN = 3'd3;
|
||||
localparam PHASE_STATUS_OUT = 3'd4;
|
||||
localparam PHASE_MESSAGE_OUT = 3'd5;
|
||||
reg [2:0] phase;
|
||||
|
||||
// ---------------- buffer read engine -----------------------
|
||||
// the buffer itself. Can hold one sector
|
||||
reg [7:0] buffer_out0 [256];
|
||||
always @(posedge clk) sd_buff_din[7:0] <= buffer_out0[sd_buff_addr];
|
||||
// ------------ sector buffer IO controller read/write -----------------------
|
||||
// the buffer itself. Can hold two sectors
|
||||
reg sd_buff_sel;
|
||||
|
||||
reg [7:0] buffer_out1 [256];
|
||||
always @(posedge clk) sd_buff_din[15:8] <= buffer_out1[sd_buff_addr];
|
||||
wire [7:0] buffer0_dout;
|
||||
scsi_dpram buffer0
|
||||
(
|
||||
.clock(clk),
|
||||
|
||||
// ---------------- buffer write engine ----------------------
|
||||
// the buffer itself. Can hold one sector
|
||||
reg [7:0] buffer_in0 [256];
|
||||
always @(posedge clk) if(sd_buff_wr & io_ack) buffer_in0[sd_buff_addr] <= sd_buff_dout[7:0];
|
||||
.address_a({sd_buff_sel, sd_buff_addr}),
|
||||
.data_a(sd_buff_dout[7:0]),
|
||||
.wren_a(sd_buff_wr),
|
||||
.q_a(sd_buff_din[7:0]),
|
||||
|
||||
reg [7:0] buffer_in1 [256];
|
||||
always @(posedge clk) if(sd_buff_wr & io_ack) buffer_in1[sd_buff_addr] <= sd_buff_dout[15:8];
|
||||
.address_b(data_cnt[9:1]),
|
||||
.data_b(din),
|
||||
.wren_b(buffer0_wr),
|
||||
.q_b(buffer0_dout)
|
||||
);
|
||||
|
||||
wire [7:0] buffer1_dout;
|
||||
scsi_dpram buffer1
|
||||
(
|
||||
.clock(clk),
|
||||
|
||||
.address_a({sd_buff_sel, sd_buff_addr}),
|
||||
.data_a(sd_buff_dout[15:8]),
|
||||
.wren_a(sd_buff_wr),
|
||||
.q_a(sd_buff_din[15:8]),
|
||||
|
||||
.address_b(data_cnt[9:1]),
|
||||
.data_b(din),
|
||||
.wren_b(buffer1_wr),
|
||||
.q_b(buffer1_dout)
|
||||
);
|
||||
|
||||
reg old_io_ack;
|
||||
always @(posedge clk) begin
|
||||
old_io_ack <= io_ack;
|
||||
if (phase == PHASE_IDLE)
|
||||
sd_buff_sel <= 0;
|
||||
else
|
||||
if (old_io_ack & ~io_ack) sd_buff_sel <= !sd_buff_sel;
|
||||
end
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
|
@ -77,20 +104,25 @@ reg [7:0] status;
|
|||
`define MSG_CMD_COMPLETE 8'h00
|
||||
|
||||
// drive scsi signals according to phase
|
||||
assign msg = (phase == `PHASE_MESSAGE_OUT);
|
||||
assign cd = (phase == `PHASE_CMD_IN) || (phase == `PHASE_STATUS_OUT) || (phase == `PHASE_MESSAGE_OUT);
|
||||
assign io = (phase == `PHASE_DATA_OUT) || (phase == `PHASE_STATUS_OUT) || (phase == `PHASE_MESSAGE_OUT);
|
||||
assign req = (phase != `PHASE_IDLE) && !ack && !io_rd && !io_wr && !io_ack;
|
||||
assign bsy = (phase != `PHASE_IDLE);
|
||||
assign msg = (phase == PHASE_MESSAGE_OUT);
|
||||
assign cd = (phase == PHASE_CMD_IN) || (phase == PHASE_STATUS_OUT) || (phase == PHASE_MESSAGE_OUT);
|
||||
assign io = (phase == PHASE_DATA_OUT) || (phase == PHASE_STATUS_OUT) || (phase == PHASE_MESSAGE_OUT);
|
||||
|
||||
assign dout = (phase == `PHASE_STATUS_OUT)?status:
|
||||
(phase == `PHASE_MESSAGE_OUT)?`MSG_CMD_COMPLETE:
|
||||
(phase == `PHASE_DATA_OUT)?cmd_dout:
|
||||
wire io_busy = (phase == PHASE_DATA_OUT && (io_rd | io_ack) && data_cnt[9] == sd_buff_sel) ||
|
||||
(phase == PHASE_DATA_IN && (io_wr | io_ack) && data_cnt[9] == sd_buff_sel) ||
|
||||
(phase != PHASE_DATA_OUT && phase != PHASE_DATA_IN && (io_rd | io_wr | io_ack));
|
||||
assign req = (phase != PHASE_IDLE) && !ack && !io_busy;
|
||||
|
||||
assign bsy = (phase != PHASE_IDLE);
|
||||
|
||||
assign dout = (phase == PHASE_STATUS_OUT)?status:
|
||||
(phase == PHASE_MESSAGE_OUT)?`MSG_CMD_COMPLETE:
|
||||
(phase == PHASE_DATA_OUT)?cmd_dout:
|
||||
8'h00;
|
||||
|
||||
// de-multiplex different data sources
|
||||
wire [7:0] cmd_dout =
|
||||
cmd_read?buffer_dout:
|
||||
cmd_read?(data_cnt[0] ? buffer1_dout : buffer0_dout):
|
||||
cmd_inquiry?inquiry_dout:
|
||||
cmd_read_capacity?read_capacity_dout:
|
||||
cmd_mode_sense?mode_sense_dout:
|
||||
|
@ -112,23 +144,30 @@ wire [7:0] inquiry_dout =
|
|||
|
||||
(data_cnt == 32'd26)?"S":(data_cnt == 32'd27)?"T":
|
||||
(data_cnt == 32'd28)?"2":(data_cnt == 32'd29)?"2":
|
||||
(data_cnt == 32'd30)?"5":(data_cnt == 32'd31)?"N" + ID: // TESTING. ElectronAsh.
|
||||
(data_cnt == 32'd30)?"5":(data_cnt == 32'd31)?"N" + {5'd0, ID}: // TESTING. ElectronAsh.
|
||||
8'h00;
|
||||
|
||||
// output of read capacity command
|
||||
//wire [31:0] capacity = 32'd41056; // 40960 + 96 blocks = 20MB
|
||||
//wire [31:0] capacity = 32'd1024096; // 1024000 + 96 blocks = 500MB
|
||||
reg [31:0] capacity;
|
||||
reg mounted = 0;
|
||||
always @(posedge clk) begin
|
||||
if (img_mounted) capacity <= img_blocks + 8'd96;
|
||||
if (img_mounted) begin
|
||||
if (|img_blocks) begin
|
||||
capacity <= img_blocks;
|
||||
$display("Image mounted on target %d, size: %d", ID, img_blocks);
|
||||
mounted <= 1;
|
||||
end else
|
||||
mounted <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
wire [31:0] capacity_m1 = capacity - 32'd1;
|
||||
wire [7:0] read_capacity_dout =
|
||||
(data_cnt == 32'd0 )?capacity_m1[31:24]:
|
||||
(data_cnt == 32'd1 )?capacity_m1[23:16]:
|
||||
(data_cnt == 32'd2 )?capacity_m1[15:8]:
|
||||
(data_cnt == 32'd3 )?capacity_m1[7:0]:
|
||||
(data_cnt == 32'd0 )?capacity[31:24]:
|
||||
(data_cnt == 32'd1 )?capacity[23:16]:
|
||||
(data_cnt == 32'd2 )?capacity[15:8]:
|
||||
(data_cnt == 32'd3 )?capacity[7:0]:
|
||||
(data_cnt == 32'd6 )?8'd2: // 512 bytes per sector
|
||||
8'h00;
|
||||
|
||||
|
@ -140,40 +179,44 @@ wire [7:0] mode_sense_dout =
|
|||
(data_cnt == 32'd10 )?8'd2:
|
||||
8'h00;
|
||||
|
||||
// clock data out of buffer to allow for embedded ram
|
||||
reg [7:0] buffer_dout;
|
||||
always @(posedge clk) buffer_dout <= data_cnt[0] ? buffer_in1[data_cnt[8:1]] : buffer_in0[data_cnt[8:1]];
|
||||
|
||||
// buffer to store incoming commands
|
||||
reg [3:0] cmd_cnt;
|
||||
reg [7:0] cmd [9:0];
|
||||
|
||||
/* ----------------------- request data from/to io controller ----------------------- */
|
||||
|
||||
// base address of current block. Subtract one when writing since the writing happens
|
||||
// after a block has been transferred and data_cnt has thus already been increased by 512
|
||||
assign io_lba = lba + { 9'd0, data_cnt[31:9] } -
|
||||
(cmd_write ? 32'd1 : 32'd0);
|
||||
assign io_lba = lba;
|
||||
|
||||
// generate an io_rd signal whenever the first byte of a 512 byte block is required
|
||||
// start fetching the next sector when the 20th byte is read, and it's not the last sector
|
||||
wire req_rd = ((phase == PHASE_DATA_OUT) && cmd_read && (data_cnt == 0 || (data_cnt[8:0] == 9'd20 && data_cnt[31:9] != ({7'd0, tlen} - 1'd1))) && !data_complete);
|
||||
|
||||
// generate an io_wr signal whenever a 512 byte block has been received or when the status
|
||||
// phase of a write command has been reached
|
||||
wire req_wr = ((((phase == PHASE_DATA_IN) && (data_cnt[8:0] == 0) && (data_cnt != 0)) || (phase == PHASE_STATUS_OUT)) && cmd_write);
|
||||
|
||||
wire req_rd = ((phase == `PHASE_DATA_OUT) && cmd_read && (data_cnt[8:0] == 0) && !data_complete);
|
||||
wire req_wr = ((((phase == `PHASE_DATA_IN) && (data_cnt[8:0] == 0) && (data_cnt != 0)) || (phase == `PHASE_STATUS_OUT)) && cmd_write);
|
||||
always @(posedge clk) begin
|
||||
reg old_rd, old_wr;
|
||||
reg wr_pending, rd_pending;
|
||||
|
||||
old_rd <= req_rd;
|
||||
old_wr <= req_wr;
|
||||
if(~old_rd & req_rd) rd_pending <= 1;
|
||||
if(~old_wr & req_wr) wr_pending <= 1;
|
||||
|
||||
if(io_ack) begin
|
||||
io_rd <= 1'b0;
|
||||
io_wr <= 1'b0;
|
||||
end else begin
|
||||
// generate an io_rd signal whenever the first byte of a 512 byte block is required and io_wr whenever
|
||||
// the last byte of a 512 byte block has been revceived
|
||||
if(~old_rd & req_rd) io_rd <= 1;
|
||||
if (rd_pending && !io_rd) begin
|
||||
io_rd <= 1;
|
||||
rd_pending <= 0;
|
||||
end
|
||||
|
||||
// generate an io_wr signal whenever a 512 byte block has been received or when the status
|
||||
// phase of a write command has been reached
|
||||
if(~old_wr & req_wr) io_wr <= 1;
|
||||
if (wr_pending && !io_wr) begin
|
||||
io_wr <= 1;
|
||||
wr_pending <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -187,21 +230,25 @@ always @(posedge clk) begin
|
|||
stb_adv <= (old_ack & ~ack); // on falling edge
|
||||
end
|
||||
|
||||
reg buffer0_wr, buffer1_wr;
|
||||
|
||||
// store data on rising edge of ack, ...
|
||||
always @(posedge clk) begin
|
||||
buffer0_wr <= 0;
|
||||
buffer1_wr <= 0;
|
||||
if(stb_ack) begin
|
||||
if(phase == `PHASE_CMD_IN) cmd[cmd_cnt] <= din;
|
||||
if(phase == `PHASE_DATA_IN) begin
|
||||
if(data_cnt[0]) buffer_out1[data_cnt[8:1]] <= din;
|
||||
else buffer_out0[data_cnt[8:1]] <= din;
|
||||
if(phase == PHASE_CMD_IN) cmd[cmd_cnt] <= din;
|
||||
if(phase == PHASE_DATA_IN) begin
|
||||
buffer0_wr <= ~data_cnt[0];
|
||||
buffer1_wr <= data_cnt[0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// ... advance counter on falling edge
|
||||
always @(posedge clk) begin
|
||||
if(phase == `PHASE_IDLE) cmd_cnt <= 4'd0;
|
||||
else if(stb_adv && (phase == `PHASE_CMD_IN) && (cmd_cnt != 15)) cmd_cnt <= cmd_cnt + 4'd1;
|
||||
if(phase == PHASE_IDLE) cmd_cnt <= 4'd0;
|
||||
else if(stb_adv && (phase == PHASE_CMD_IN) && (cmd_cnt != 15)) cmd_cnt <= cmd_cnt + 4'd1;
|
||||
end
|
||||
|
||||
// count data bytes. don't increase counter while we are waiting for data from
|
||||
|
@ -221,7 +268,7 @@ wire [31:0] data_len =
|
|||
{ 16'd0, tlen }; // inquiry etc have length in bytes
|
||||
|
||||
always @(posedge clk) begin
|
||||
if((phase != `PHASE_DATA_OUT) && (phase != `PHASE_DATA_IN) && (phase != `PHASE_STATUS_OUT) && (phase != `PHASE_MESSAGE_OUT)) begin
|
||||
if((phase != PHASE_DATA_OUT) && (phase != PHASE_DATA_IN) && (phase != PHASE_STATUS_OUT) && (phase != PHASE_MESSAGE_OUT)) begin
|
||||
data_cnt <= 0;
|
||||
data_complete <= 0;
|
||||
end else begin
|
||||
|
@ -235,14 +282,14 @@ end
|
|||
// check whether status byte has been sent
|
||||
reg status_sent;
|
||||
always @(posedge clk) begin
|
||||
if(phase != `PHASE_STATUS_OUT) status_sent <= 0;
|
||||
if(phase != PHASE_STATUS_OUT) status_sent <= 0;
|
||||
else if(stb_adv) status_sent <= 1;
|
||||
end
|
||||
|
||||
// check whether message byte has been sent
|
||||
reg message_sent;
|
||||
always @(posedge clk) begin
|
||||
if(phase != `PHASE_MESSAGE_OUT) message_sent <= 0;
|
||||
if(phase != PHASE_MESSAGE_OUT) message_sent <= 0;
|
||||
else if(stb_adv) message_sent <= 1;
|
||||
end
|
||||
|
||||
|
@ -273,18 +320,21 @@ wire cmd_test_unit_ready = (op_code == 8'h00);
|
|||
wire cmd_read_capacity = (op_code == 8'h25);
|
||||
wire cmd_read_buffer = (op_code == 8'h3b); // fake
|
||||
wire cmd_write_buffer = (op_code == 8'h3c); // fake
|
||||
wire cmd_verify6 = (op_code == 8'h13); // fake
|
||||
wire cmd_verify10 = (op_code == 8'h2f); // fake
|
||||
|
||||
// valid command in buffer? TODO: check for valid command parameters
|
||||
wire cmd_ok = cmd_read || cmd_write || cmd_inquiry || cmd_test_unit_ready ||
|
||||
cmd_read_capacity || cmd_mode_select || cmd_format || cmd_mode_sense ||
|
||||
cmd_read_buffer | cmd_write_buffer;
|
||||
cmd_read_buffer || cmd_write_buffer || cmd_verify6 || cmd_verify10;
|
||||
|
||||
// latch parameters once command is complete
|
||||
reg [31:0] lba;
|
||||
reg [15:0] tlen;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(cmd_cpl && (phase == `PHASE_CMD_IN)) begin
|
||||
if (old_io_ack & ~io_ack) lba <= lba + 1'd1;
|
||||
if(cmd_cpl && (phase == PHASE_CMD_IN)) begin
|
||||
lba <= cmd6_cpl?{11'd0, lba6}:lba10;
|
||||
tlen <= cmd6_cpl?{7'd0, tlen6}:tlen10;
|
||||
end
|
||||
|
@ -304,16 +354,17 @@ wire [15:0] tlen10 = { cmd[7], cmd[8] };
|
|||
// on the rising edge
|
||||
always @(posedge clk) begin
|
||||
if(rst) begin
|
||||
phase <= `PHASE_IDLE;
|
||||
phase <= PHASE_IDLE;
|
||||
end else begin
|
||||
if(phase == `PHASE_IDLE) begin
|
||||
if(sel && din[ID]) // own id on bus during selection?
|
||||
phase <= `PHASE_CMD_IN;
|
||||
if(phase == PHASE_IDLE) begin
|
||||
if(sel && din[ID] && mounted) // own id on bus during selection?
|
||||
phase <= PHASE_CMD_IN;
|
||||
end
|
||||
|
||||
else if(phase == `PHASE_CMD_IN) begin
|
||||
else if(phase == PHASE_CMD_IN) begin
|
||||
// check if a full command is in the buffer
|
||||
if(cmd_cpl) begin
|
||||
$display("New command on target %d: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", ID, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], cmd[9]);
|
||||
// is this a supported and valid command?
|
||||
if(cmd_ok) begin
|
||||
// yes, continue
|
||||
|
@ -322,39 +373,76 @@ always @(posedge clk) begin
|
|||
// continue according to command
|
||||
|
||||
// these commands return data
|
||||
if(cmd_read || cmd_inquiry || cmd_read_capacity || cmd_mode_sense || cmd_read_buffer) phase <= `PHASE_DATA_OUT;
|
||||
if(cmd_read || cmd_inquiry || cmd_read_capacity || cmd_mode_sense || cmd_read_buffer) phase <= PHASE_DATA_OUT;
|
||||
// these commands receive dataa
|
||||
else if(cmd_write || cmd_mode_select || cmd_write_buffer) phase <= `PHASE_DATA_IN;
|
||||
else if(cmd_write || cmd_mode_select || cmd_write_buffer) phase <= PHASE_DATA_IN;
|
||||
// and all other valid commands are just "ok"
|
||||
else phase <= `PHASE_STATUS_OUT;
|
||||
else phase <= PHASE_STATUS_OUT;
|
||||
end else begin
|
||||
// no, report failure
|
||||
status <= `STATUS_CHECK_CONDITION;
|
||||
phase <= `PHASE_STATUS_OUT;
|
||||
phase <= PHASE_STATUS_OUT;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
else if(phase == `PHASE_DATA_OUT) begin
|
||||
if(data_complete) phase <= `PHASE_STATUS_OUT;
|
||||
else if(phase == PHASE_DATA_OUT) begin
|
||||
if(data_complete) phase <= PHASE_STATUS_OUT;
|
||||
end
|
||||
|
||||
else if(phase == `PHASE_DATA_IN) begin
|
||||
if(data_complete) phase <= `PHASE_STATUS_OUT;
|
||||
else if(phase == PHASE_DATA_IN) begin
|
||||
if(data_complete) phase <= PHASE_STATUS_OUT;
|
||||
end
|
||||
|
||||
else if(phase == `PHASE_STATUS_OUT) begin
|
||||
if(status_sent) phase <= `PHASE_MESSAGE_OUT;
|
||||
else if(phase == PHASE_STATUS_OUT) begin
|
||||
if(status_sent) phase <= PHASE_MESSAGE_OUT;
|
||||
end
|
||||
|
||||
else if(phase == `PHASE_MESSAGE_OUT) begin
|
||||
if(message_sent) phase <= `PHASE_IDLE;
|
||||
else if(phase == PHASE_MESSAGE_OUT) begin
|
||||
if(message_sent) phase <= PHASE_IDLE;
|
||||
end
|
||||
|
||||
else
|
||||
phase <= `PHASE_IDLE; // should never happen
|
||||
phase <= PHASE_IDLE; // should never happen
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
module scsi_dpram #(parameter DATAWIDTH=8, ADDRWIDTH=9)
|
||||
(
|
||||
input clock,
|
||||
|
||||
input [ADDRWIDTH-1:0] address_a,
|
||||
input [DATAWIDTH-1:0] data_a,
|
||||
input wren_a,
|
||||
output reg [DATAWIDTH-1:0] q_a,
|
||||
|
||||
input [ADDRWIDTH-1:0] address_b,
|
||||
input [DATAWIDTH-1:0] data_b,
|
||||
input wren_b,
|
||||
output reg [DATAWIDTH-1:0] q_b
|
||||
);
|
||||
|
||||
reg [DATAWIDTH-1:0] ram[0:(1<<ADDRWIDTH)-1];
|
||||
|
||||
always @(posedge clock) begin
|
||||
if(wren_a) begin
|
||||
ram[address_a] <= data_a;
|
||||
q_a <= data_a;
|
||||
end else begin
|
||||
q_a <= ram[address_a];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clock) begin
|
||||
if(wren_b) begin
|
||||
ram[address_b] <= data_b;
|
||||
q_b <= data_b;
|
||||
end else begin
|
||||
q_b <= ram[address_b];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Reference in New Issue
Block a user