More FPGA bitstream updates

This commit is contained in:
spicyjpeg 2024-06-27 08:35:02 +02:00
parent a1f3312aa2
commit c4ff4eb62e
No known key found for this signature in database
GPG Key ID: 5CC87404C01DF393
13 changed files with 835 additions and 367 deletions

View File

@ -35,7 +35,9 @@ make \
BUILD=Release \
PREFIX="$TOOLCHAIN_DIR/bin/mipsel-none-elf" \
FORMAT=elf32-littlemips \
FASTBOOT=true \
BOARD=system573 \
BOOT_MODE=psexe \
SPLASH_SCREEN=true \
EMBED_PSEXE="$PROJECT_DIR/build/${RELEASE_NAME}-tiny.psexe" \
|| exit 2

Binary file not shown.

View File

@ -79,28 +79,27 @@ Note that the number is different from the one used by Konami (`0x1234`).
| 14 | W | Output D2 (0 = grounded, 1 = high-z) |
| 15 | W | Output D3 (0 = grounded, 1 = high-z) |
### `0x1f6400ee` (FPGA, DDR/Mambo bitstream): **1-wire bus**
### `0x1f6400ee`: **1-wire bus**
When read:
| Bits | RW | Description |
| ----: | :- | :------------------------ |
| 0-11 | | _Unused_ |
| 0-7 | | _Unused_ |
| 8 | R | DS2433 1-wire bus readout |
| 9-11 | | _Unused_ |
| 12 | R | DS2401 1-wire bus readout |
| 13 | R | DS2433 1-wire bus readout |
| 14-15 | | _Unused_ |
| 13-15 | | _Unused_ |
When written:
| Bits | RW | Description |
| ----: | :- | :----------------------------------------------------------- |
| 0-11 | | _Unused_ |
| 0-7 | | _Unused_ |
| 8 | W | Drive DS2433 1-wire bus low (1 = pull to ground, 0 = high-z) |
| 9-11 | | _Unused_ |
| 12 | W | Drive DS2401 1-wire bus low (1 = pull to ground, 0 = high-z) |
| 13 | W | Drive DS2433 1-wire bus low (1 = pull to ground, 0 = high-z) |
| 14-15 | | _Unused_ |
Bit 13 is mapped to the bus of the (normally unpopulated) DS2433 footprint. It
is currently unclear whether and how Konami's bitstreams expose this bus.
| 13-15 | | _Unused_ |
## Building the bitstream

View File

@ -5,252 +5,199 @@ CONFIG PROHIBIT = "P154"; # DOUT
## System clocks
TIMESPEC "TS_clock29M" = PERIOD "clock29M" 29.4500 MHz HIGH 50 %;
#TIMESPEC "TS_clock19M" = PERIOD "clock19M" 19.6608 MHz HIGH 50 %;
NET "clockIn29M" LOC = "P160";
NET "clock29M" TNM = "clock29M";
#NET "clockIn19M" LOC = "P207";
#NET "clock19M" TNM = "clock19M";
## Host interface
NET "nHostRead" LOC = "P146";
NET "nHostRead" NODELAY;
NET "nHostWrite" LOC = "P145";
NET "nHostWrite" NODELAY;
NET "nHostEnable" LOC = "P142";
NET "nHostEnable" NODELAY;
NET "hostAddress[0]" LOC = "P117";
NET "hostAddress[0]" NODELAY;
NET "hostAddress[1]" LOC = "P116";
NET "hostAddress[1]" NODELAY;
NET "hostAddress[2]" LOC = "P115";
NET "hostAddress[2]" NODELAY;
NET "hostAddress[3]" LOC = "P114";
NET "hostAddress[3]" NODELAY;
NET "hostAddress[4]" LOC = "P113";
NET "hostAddress[4]" NODELAY;
NET "hostAddress[5]" LOC = "P112";
NET "hostAddress[5]" NODELAY;
NET "hostAddress[6]" LOC = "P110";
NET "hostAddress[6]" NODELAY;
NET "hostData[0]" LOC = "P138";
NET "hostData[0]" FAST;
NET "hostData[0]" DRIVE = 12;
NET "hostData[0]" NODELAY;
NET "hostData[1]" LOC = "P137";
NET "hostData[1]" FAST;
NET "hostData[1]" DRIVE = 12;
NET "hostData[1]" NODELAY;
NET "hostData[2]" LOC = "P136";
NET "hostData[2]" FAST;
NET "hostData[2]" DRIVE = 12;
NET "hostData[2]" NODELAY;
NET "hostData[3]" LOC = "P135";
NET "hostData[3]" FAST;
NET "hostData[3]" DRIVE = 12;
NET "hostData[3]" NODELAY;
NET "hostData[4]" LOC = "P134";
NET "hostData[4]" FAST;
NET "hostData[4]" DRIVE = 12;
NET "hostData[4]" NODELAY;
NET "hostData[5]" LOC = "P133";
NET "hostData[5]" FAST;
NET "hostData[5]" DRIVE = 12;
NET "hostData[5]" NODELAY;
NET "hostData[6]" LOC = "P132";
NET "hostData[6]" FAST;
NET "hostData[6]" DRIVE = 12;
NET "hostData[6]" NODELAY;
NET "hostData[7]" LOC = "P129";
NET "hostData[7]" FAST;
NET "hostData[7]" DRIVE = 12;
NET "hostData[7]" NODELAY;
NET "hostData[8]" LOC = "P128";
NET "hostData[8]" FAST;
NET "hostData[8]" DRIVE = 12;
NET "hostData[8]" NODELAY;
NET "hostData[9]" LOC = "P127";
NET "hostData[9]" FAST;
NET "hostData[9]" DRIVE = 12;
NET "hostData[9]" NODELAY;
NET "hostData[10]" LOC = "P126";
NET "hostData[10]" FAST;
NET "hostData[10]" DRIVE = 12;
NET "hostData[10]" NODELAY;
NET "hostData[11]" LOC = "P125";
NET "hostData[11]" FAST;
NET "hostData[11]" DRIVE = 12;
NET "hostData[11]" NODELAY;
NET "hostData[12]" LOC = "P124";
NET "hostData[12]" FAST;
NET "hostData[12]" DRIVE = 12;
NET "hostData[12]" NODELAY;
NET "hostData[13]" LOC = "P123";
NET "hostData[13]" FAST;
NET "hostData[13]" DRIVE = 12;
NET "hostData[13]" NODELAY;
NET "hostData[14]" LOC = "P122";
NET "hostData[14]" FAST;
NET "hostData[14]" DRIVE = 12;
NET "hostData[14]" NODELAY;
NET "hostData[15]" LOC = "P120";
NET "hostData[15]" FAST;
NET "hostData[15]" DRIVE = 12;
NET "hostData[15]" NODELAY;
## SRAM interface
NET "nSRAMRead" LOC = "P40";
NET "nSRAMRead" FAST;
NET "nSRAMRead" DRIVE = 12;
NET "nSRAMWrite" LOC = "P55";
NET "nSRAMWrite" FAST;
NET "nSRAMWrite" DRIVE = 12;
NET "nSRAMEnable" LOC = "P34";
NET "nSRAMEnable" FAST;
NET "nSRAMEnable" DRIVE = 12;
NET "sramAddress[0]" LOC = "P30";
NET "sramAddress[0]" FAST;
NET "sramAddress[0]" DRIVE = 12;
NET "sramAddress[1]" LOC = "P32";
NET "sramAddress[1]" FAST;
NET "sramAddress[1]" DRIVE = 12;
NET "sramAddress[2]" LOC = "P35";
NET "sramAddress[2]" FAST;
NET "sramAddress[2]" DRIVE = 12;
NET "sramAddress[3]" LOC = "P37";
NET "sramAddress[3]" FAST;
NET "sramAddress[3]" DRIVE = 12;
NET "sramAddress[4]" LOC = "P41";
NET "sramAddress[4]" FAST;
NET "sramAddress[4]" DRIVE = 12;
NET "sramAddress[5]" LOC = "P43";
NET "sramAddress[5]" FAST;
NET "sramAddress[5]" DRIVE = 12;
NET "sramAddress[6]" LOC = "P45";
NET "sramAddress[6]" FAST;
NET "sramAddress[6]" DRIVE = 12;
NET "sramAddress[7]" LOC = "P47";
NET "sramAddress[7]" FAST;
NET "sramAddress[7]" DRIVE = 12;
NET "sramAddress[8]" LOC = "P46";
NET "sramAddress[8]" FAST;
NET "sramAddress[8]" DRIVE = 12;
NET "sramAddress[9]" LOC = "P44";
NET "sramAddress[9]" FAST;
NET "sramAddress[9]" DRIVE = 12;
NET "sramAddress[10]" LOC = "P36";
NET "sramAddress[10]" FAST;
NET "sramAddress[10]" DRIVE = 12;
NET "sramAddress[11]" LOC = "P42";
NET "sramAddress[11]" FAST;
NET "sramAddress[11]" DRIVE = 12;
NET "sramAddress[12]" LOC = "P49";
NET "sramAddress[12]" FAST;
NET "sramAddress[12]" DRIVE = 12;
NET "sramAddress[13]" LOC = "P48";
NET "sramAddress[13]" FAST;
NET "sramAddress[13]" DRIVE = 12;
NET "sramAddress[14]" LOC = "P56";
NET "sramAddress[14]" FAST;
NET "sramAddress[14]" DRIVE = 12;
NET "sramAddress[15]" LOC = "P58";
NET "sramAddress[15]" FAST;
NET "sramAddress[15]" DRIVE = 12;
NET "sramAddress[16]" LOC = "P57";
NET "sramAddress[16]" FAST;
NET "sramAddress[16]" DRIVE = 12;
NET "sramData[0]" LOC = "P28";
NET "sramData[0]" FAST;
NET "sramData[0]" DRIVE = 12;
NET "sramData[0]" NODELAY;
NET "sramData[1]" LOC = "P24";
NET "sramData[1]" FAST;
NET "sramData[1]" DRIVE = 12;
NET "sramData[1]" NODELAY;
NET "sramData[2]" LOC = "P22";
NET "sramData[2]" FAST;
NET "sramData[2]" DRIVE = 12;
NET "sramData[2]" NODELAY;
NET "sramData[3]" LOC = "P21";
NET "sramData[3]" FAST;
NET "sramData[3]" DRIVE = 12;
NET "sramData[3]" NODELAY;
NET "sramData[4]" LOC = "P23";
NET "sramData[4]" FAST;
NET "sramData[4]" DRIVE = 12;
NET "sramData[4]" NODELAY;
NET "sramData[5]" LOC = "P27";
NET "sramData[5]" FAST;
NET "sramData[5]" DRIVE = 12;
NET "sramData[5]" NODELAY;
NET "sramData[6]" LOC = "P29";
NET "sramData[6]" FAST;
NET "sramData[6]" DRIVE = 12;
NET "sramData[6]" NODELAY;
NET "sramData[7]" LOC = "P31";
NET "sramData[7]" FAST;
NET "sramData[7]" DRIVE = 12;
NET "sramData[7]" NODELAY;
## DRAM interface
# TODO: trace these pins out
NET "dramControl[0]" LOC = "P188";
NET "dramControl[1]" LOC = "P189";
NET "dramControl[2]" LOC = "P190";
NET "dramControl[3]" LOC = "P191";
NET "dramControl[4]" LOC = "P193";
NET "dramControl[5]" LOC = "P194";
NET "dramControl[6]" LOC = "P196";
NET "dramControl[7]" LOC = "P197";
NET "dramControl[8]" LOC = "P198";
NET "dramControl[9]" LOC = "P199";
NET "dramControl[10]" LOC = "P200";
NET "dramControl[11]" LOC = "P201";
NET "dramAddress[0]" LOC = "P186";
NET "dramAddress[1]" LOC = "P184";
NET "dramAddress[2]" LOC = "P180";
NET "dramAddress[3]" LOC = "P178";
NET "dramAddress[4]" LOC = "P176";
NET "dramAddress[5]" LOC = "P174";
NET "dramAddress[6]" LOC = "P175";
NET "dramAddress[7]" LOC = "P177";
NET "dramAddress[8]" LOC = "P179";
NET "dramAddress[9]" LOC = "P181";
NET "dramAddress[10]" LOC = "P185";
NET "dramAddress[11]" LOC = "P187";
NET "dramData[0]" LOC = "P15";
NET "dramData[1]" LOC = "P14";
NET "dramData[2]" LOC = "P10";
NET "dramData[3]" LOC = "P8";
NET "dramData[4]" LOC = "P2";
NET "dramData[5]" LOC = "P206";
NET "dramData[6]" LOC = "P205";
NET "dramData[7]" LOC = "P204";
NET "dramData[8]" LOC = "P3";
NET "dramData[9]" LOC = "P4";
NET "dramData[10]" LOC = "P5";
NET "dramData[11]" LOC = "P9";
NET "dramData[12]" LOC = "P11";
NET "dramData[13]" LOC = "P17";
NET "dramData[14]" LOC = "P19";
NET "dramData[15]" LOC = "P20";
## MP3 decoder interface
NET "mp3Reset" LOC = "P152";
NET "mp3Ready" LOC = "P159";
NET "mp3ClockIn" LOC = "P163";
NET "mp3ClockOut" LOC = "P162";
NET "mp3SDA" LOC = "P150";
NET "mp3SCL" LOC = "P151";
NET "mp3StatusCS" LOC = "P149";
NET "mp3StatusError" LOC = "P168";
NET "mp3StatusFrameSync" LOC = "P161";
NET "mp3StatusDataReq" LOC = "P148";
NET "mp3InSDIN" LOC = "P167";
NET "mp3InBCLK" LOC = "P164";
NET "mp3InLRCK" LOC = "P166";
NET "mp3OutSDOUT" LOC = "P172";
NET "mp3OutBCLK" LOC = "P169";
NET "mp3OutLRCK" LOC = "P171";
## I2S audio output
NET "dacSDIN" LOC = "P96";
NET "dacBCLK" LOC = "P94";
NET "dacLRCK" LOC = "P95";
NET "dacMCLK" LOC = "P97";
## Light outputs
# TODO: figure out the actual pin order of the outputs
NET "lightBankA[0]" LOC = "P69";
NET "lightBankA[0]" SLOW;
NET "lightBankA[0]" DRIVE = 24;
NET "lightBankA[1]" LOC = "P70";
NET "lightBankA[1]" SLOW;
NET "lightBankA[1]" DRIVE = 24;
NET "lightBankA[2]" LOC = "P72";
NET "lightBankA[2]" SLOW;
NET "lightBankA[2]" DRIVE = 24;
NET "lightBankA[3]" LOC = "P73";
NET "lightBankA[3]" SLOW;
NET "lightBankA[3]" DRIVE = 24;
NET "lightBankA[4]" LOC = "P74";
NET "lightBankA[4]" SLOW;
NET "lightBankA[4]" DRIVE = 24;
NET "lightBankA[5]" LOC = "P75";
NET "lightBankA[5]" SLOW;
NET "lightBankA[5]" DRIVE = 24;
NET "lightBankA[6]" LOC = "P76";
NET "lightBankA[6]" SLOW;
NET "lightBankA[6]" DRIVE = 24;
NET "lightBankA[7]" LOC = "P80";
NET "lightBankA[7]" SLOW;
NET "lightBankA[7]" DRIVE = 24;
NET "lightBankB[0]" LOC = "P81";
NET "lightBankB[0]" SLOW;
NET "lightBankB[0]" DRIVE = 24;
NET "lightBankB[1]" LOC = "P82";
NET "lightBankB[1]" SLOW;
NET "lightBankB[1]" DRIVE = 24;
NET "lightBankB[2]" LOC = "P83";
NET "lightBankB[2]" SLOW;
NET "lightBankB[2]" DRIVE = 24;
NET "lightBankB[3]" LOC = "P84";
NET "lightBankB[3]" SLOW;
NET "lightBankB[3]" DRIVE = 24;
NET "lightBankAH[0]" LOC = "P84";
NET "lightBankAH[1]" LOC = "P83";
NET "lightBankAH[2]" LOC = "P82";
NET "lightBankAH[3]" LOC = "P81";
NET "lightBankAL[0]" LOC = "P80";
NET "lightBankAL[1]" LOC = "P76";
NET "lightBankAL[2]" LOC = "P75";
NET "lightBankAL[3]" LOC = "P74";
NET "lightBankBH[0]" LOC = "P73";
NET "lightBankBH[1]" LOC = "P72";
NET "lightBankBH[2]" LOC = "P70";
NET "lightBankBH[3]" LOC = "P69";
NET "lightBankD[0]" LOC = "P68";
NET "lightBankD[0]" SLOW;
NET "lightBankD[0]" DRIVE = 24;
NET "lightBankD[1]" LOC = "P67";
NET "lightBankD[1]" SLOW;
NET "lightBankD[1]" DRIVE = 24;
NET "lightBankD[2]" LOC = "P60";
NET "lightBankD[2]" SLOW;
NET "lightBankD[2]" DRIVE = 24;
NET "lightBankD[3]" LOC = "P59";
NET "lightBankD[3]" SLOW;
NET "lightBankD[3]" DRIVE = 24;
## General-purpose inputs (unused)
#NET "inputBank[0]" LOC = "P61";
#NET "inputBank[1]" LOC = "P62";
#NET "inputBank[2]" LOC = "P63";
#NET "inputBank[3]" LOC = "P64";
## Serial interfaces
# TODO: are pins 98 and 99 swapped?
NET "networkTXEnable" LOC = "P98";
NET "networkTX" LOC = "P99";
NET "networkRX" LOC = "P100";
NET "serialTX" LOC = "P89";
NET "serialRX" LOC = "P88";
NET "serialRTS" LOC = "P93";
NET "serialCTS" LOC = "P90";
NET "serialDTR" LOC = "P87";
NET "serialDSR" LOC = "P85";
## 1-wire bus
NET "ds2401" LOC = "P109";
NET "ds2401" SLOW;
NET "ds2401" DRIVE = 24;
NET "ds2433" LOC = "P107";
NET "ds2433" SLOW;
NET "ds2433" DRIVE = 24;
NET "ds2401" LOC = "P109";

View File

@ -6,6 +6,7 @@
## Input and preliminary optimization
read_verilog src/main.v
read_verilog src/spartanxl.v
hierarchy -check -top FPGA
proc
@ -39,23 +40,23 @@ clean
## FPGA-specific mapping
dfflegalize -cell $_DFFE_PP?P_ r -cell $_DLATCH_PP?_ r
opt_expr -mux_undef -noclkinv
abc -g gates
techmap -map src/techmap.v
clean
xilinx_dffopt -lut4
clkbufmap -buf BUFGLS O:I
iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O -toutpad OBUFT ~T:I:O -tinoutpad IOBUFT ~T:O:I:IO -ignore IFDX D -ignore IFDXI D -ignore OFDX Q -ignore OFDXI Q -ignore OFDTX O -ignore OFDTXI O
#clkbufmap -buf BUFGLS O:I
iopadmap -bits -inpad IBUF O:I -ignore IPAD IPAD -ignore OPAD OPAD -ignore IOPAD IOPAD -ignore IFDX D -ignore IFDXI D -ignore BUFGLS I
iopadmap -bits -outpad OBUF I:O -toutpad OBUFT ~T:I:O -tinoutpad IOBUFT ~T:O:I:IO -ignore IPAD IPAD -ignore OPAD OPAD -ignore IOPAD IOPAD -ignore OFDX Q -ignore OFDXI Q -ignore OFDTX O -ignore OFDTXI O
extractinv -inv INV O:I
techmap -map src/techmap.v
clean
## Output
# FIXME: for some reason invoking hierarchy here results in $or/$reduce_or
# primitives being added back when using wired-or
#hierarchy -check
autoname
hierarchy -check
stat -tech xilinx
check -noinit
blackbox =A:whitebox

View File

@ -20,7 +20,7 @@ ngdbuild synth.edf synth.ngd ^
-uc ..\fpga.ucf ^
-p %TARGET% ^
|| exit /b 2
map -o mapped.ncd synth.ngd ^
map -o mapped.ncd synth.ngd mapped.pcf ^
-p %TARGET% ^
-cm %COVER_MODE% ^
-os %OPTIMIZATION_MODE% ^
@ -29,7 +29,7 @@ map -o mapped.ncd synth.ngd ^
-detail ^
|| exit /b 2
par mapped.ncd fpga.ncd ^
par mapped.ncd fpga.ncd mapped.pcf ^
-w ^
-detail ^
|| exit /b 3

View File

@ -1,40 +1,11 @@
/* Spartan-XL primitive library */
module BUF (input I, output O); endmodule
module INV (input I, output O); endmodule
module AND2 (input I0, input I1, output O); endmodule
module NAND2 (input I0, input I1, output O); endmodule
module AND2B1 (input I0, input I1, output O); endmodule
module OR2 (input I0, input I1, output O); endmodule
module NOR2 (input I0, input I1, output O); endmodule
module OR2B1 (input I0, input I1, output O); endmodule
module XOR2 (input I0, input I1, output O); endmodule
module XNOR2 (input I0, input I1, output O); endmodule
module BUFT (input I, input T, output O); endmodule
module FDCE (input D, input C, input CLR, input CE, output Q); endmodule
module FDPE (input D, input C, input PRE, input CE, output Q); endmodule
module LDCE_1 (input D, input G, input CLR, input GE, output Q); endmodule
module LDPE_1 (input D, input G, input PRE, input GE, output Q); endmodule
module IPAD (output IPAD); endmodule
module OPAD (input OPAD); endmodule
module IOPAD (inout IOPAD); endmodule
module IBUF (input I, output O); endmodule
module OBUF (input I, output O); endmodule
module OBUFT (input I, input T, output O); endmodule
module IOBUFT (input I, input T, output O, inout IO); endmodule
module BUFGLS (input I, output O); endmodule
module IFDX (input D, input C, input CE, output Q); endmodule
module IFDXI (input D, input C, input CE, output Q); endmodule
module OFDX (input D, input C, input CE, output Q); endmodule
module OFDXI (input D, input C, input CE, output Q); endmodule
module OFDTX (input D, input C, input CE, input T, output O); endmodule
module OFDTXI (input D, input C, input CE, input T, output O); endmodule
/* Top-level module */
module FPGA (
// These are technically inputs, however they are already wired up to pad
// primitives within the module. They are only exposed here in order to
// allow for a testbench to inject the clocks during simulation.
inout clockIn29M,
inout clockIn19M,
input nHostRead,
input nHostWrite,
input nHostEnable,
@ -47,54 +18,161 @@ module FPGA (
output [16:0] sramAddress,
inout [7:0] sramData,
output [7:0] lightBankA,
output [3:0] lightBankB,
output [11:0] dramControl,
output [11:0] dramAddress,
inout [15:0] dramData,
output mp3Reset,
input mp3Ready,
output mp3ClockIn,
input mp3ClockOut,
inout mp3SDA,
inout mp3SCL,
output mp3StatusCS,
input mp3StatusError,
input mp3StatusFrameSync,
input mp3StatusDataReq,
output mp3InSDIN,
output mp3InBCLK,
output mp3InLRCK,
input mp3OutSDOUT,
input mp3OutBCLK,
input mp3OutLRCK,
output dacSDIN,
output dacBCLK,
output dacLRCK,
output dacMCLK,
output [3:0] lightBankAH,
output [3:0] lightBankAL,
output [3:0] lightBankBH,
output [3:0] lightBankD,
inout ds2401,
inout ds2433
output networkTXEnable,
output networkTX,
input networkRX,
output serialTX,
input serialRX,
output serialRTS,
input serialCTS,
output serialDTR,
input serialDSR,
inout ds2433,
inout ds2401
);
genvar i;
/* Register definitions */
localparam SYS573D_FPGA_MAGIC = 8'h80;
localparam SYS573D_FPGA_MP3_PTR_H = 8'ha0;
localparam SYS573D_FPGA_MP3_PTR_L = 8'ha2;
localparam SYS573D_FPGA_MP3_ENDPTR_H = 8'ha4;
localparam SYS573D_FPGA_MP3_ENDPTR_L = 8'ha6;
localparam SYS573D_FPGA_MP3_COUNTER = 8'ha8;
localparam SYS573D_FPGA_MP3_KEY1 = 8'ha8;
localparam SYS573D_FPGA_MP3_FEED_STAT = 8'haa;
localparam SYS573D_FPGA_MP3_I2C = 8'hac;
localparam SYS573D_FPGA_MP3_FEED_CTRL = 8'hae;
localparam SYS573D_FPGA_DRAM_WRPTR_H = 8'hb0;
localparam SYS573D_FPGA_DRAM_WRPTR_L = 8'hb2;
localparam SYS573D_FPGA_DRAM_DATA = 8'hb4;
localparam SYS573D_FPGA_DRAM_RDPTR_H = 8'hb6;
localparam SYS573D_FPGA_DRAM_RDPTR_L = 8'hb8;
localparam SYS573D_FPGA_NET_DATA = 8'hc0;
localparam SYS573D_FPGA_DAC_COUNTER_H = 8'hca;
localparam SYS573D_FPGA_DAC_COUNTER_L = 8'hcc;
localparam SYS573D_FPGA_DAC_COUNTER_D = 8'hce;
localparam SYS573D_FPGA_LIGHTS_AH = 8'he0;
localparam SYS573D_FPGA_LIGHTS_AL = 8'he2;
localparam SYS573D_FPGA_LIGHTS_BH = 8'he4;
localparam SYS573D_FPGA_LIGHTS_D = 8'he6;
localparam SYS573D_FPGA_INIT = 8'he8;
localparam SYS573D_FPGA_MP3_KEY2 = 8'hea;
localparam SYS573D_FPGA_MP3_KEY3 = 8'hec;
localparam SYS573D_FPGA_DS_BUS = 8'hee;
/* System clocks */
wire clockIn29M, _clock29M;
wire clockIn19M, _clock19M;
wire clock29M, clock19M;
IPAD _clockPad29M ( .IPAD(clockIn29M) );
IPAD _clockPad19M ( .IPAD(clockIn19M) );
BUFGLS _clockBuf29M ( .I(clockIn29M), .O(_clock29M) );
BUFGLS _clockBuf19M ( .I(clockIn19M), .O(_clock19M) );
// ISE rejects global buffer primitives unless they are wired either to an
// IBUF (which results in suboptimal routing, as the dedicated IOB clock
// output is left unused) or directly to a pad primitive.
IPAD clockPad29M (.IPAD(clockIn29M));
IPAD clockPad19M (.IPAD(clockIn19M));
BUFGLS clockBuf29M (.I(clockIn29M), .O(clock29M));
BUFGLS clockBuf19M (.I(clockIn19M), .O(clock19M));
/* Host address decoding */
// The FPGA shall only respond to addresses in 0x80-0xef range, as 0xf0-0xff
// is used by the CPLD and 0x00-0x7f seems to be reserved for debugging
// hardware. Bit 0 of the 573's address bus is not wired to the FPGA as all
// registers are 16 bits wide.
wire hostAddrValid = hostAddress[6] & (hostAddress[5:3] != 3'b111);
wire hostRegRead = ~nHostEnable & ~nHostRead & nHostWrite;
wire hostRegWrite = ~nHostEnable & nHostRead & ~nHostWrite;
wire [7:0] hostRegister = { 1'b1, hostAddress[5:0], 1'b0 };
/* Host interface */
wire _nHostRead, _nHostWrite, _nHostEnable;
wire [6:0] _hostAddress;
wire [15:0] _hostDataIn;
wire [15:0] _hostDataOut;
reg [2:0] _delayedHostRegRead = 3'b000;
wire _hostDataInClock;
wire _nHostReadFPGA = _nHostRead || _nHostEnable;
wire _nHostWriteFPGA = _nHostWrite || _nHostEnable;
wire [15:0] hostDataIn;
wor [15:0] hostDataOut;
// IOB flip-flop primitives (IFDX, OFDX) are explicitly used whenever
// possible in order to minimize propagation delays and CLB usage.
IFDX _nHostReadBuf ( .C(_clock29M), .D(nHostRead), .Q(_nHostRead), .CE(1'b1) );
IFDX _nHostWriteBuf ( .C(_clock29M), .D(nHostWrite), .Q(_nHostWrite), .CE(1'b1) );
IFDX _nHostEnableBuf ( .C(_clock29M), .D(nHostEnable), .Q(_nHostEnable), .CE(1'b1) );
reg hostDataInValid = 1'b0;
reg hostDataOutValid = 1'b0;
// Data is latched in the input flip flops once the 573 *deasserts* either
// the chip select or the write strobe. Konami's bitstream routes this
// signal through a global net (_hostDataInClock), possibly since it is
// asynchronous and not tied to the main clock.
BUFGLS hostDataInUpdateBuf(.I(hostRegWrite), .O(_hostDataInClock));
wire hostDataInPending = ~hostRegWrite & hostDataInValid;
always @(posedge clock29M) begin
// Konami's bitstream pulls the output flip flops' clock enable low
// after 3 cycles if the register being read is in 0xa0-0xaf range (i.e.
// MP3 status and counters), in order to prevent any further updates
// while the counters are running. A 3-bit shift register is used to
// implement the delay.
_delayedHostRegRead <= { _delayedHostRegRead[1:0], hostRegRead };
// The direction of the bus is only changed on clock edges in order to
// prevent any data from being output before the output flip flops are
// updated.
hostDataInValid <= hostRegWrite;
hostDataOutValid <= hostAddrValid & hostRegRead;
end
generate
for (i = 0; i < 7; i++)
IFDX _hostAddressBuf (
.C(_clock29M), .D(hostAddress[i]), .Q(_hostAddress[i])
for (i = 0; i < 16; i = i + 1) begin
IFDX hostDataInReg (
.D(hostData[i]),
.C(~_hostDataInClock),
.CE(1'b1),
.Q(hostDataIn[i])
);
for (i = 0; i < 16; i++) begin
IFDX _hostDataInBuf (
.C(_clock29M), .D(hostData[i]), .Q(_hostDataIn[i]), .CE(1'b1)
);
OFDTX _hostDataOutBuf (
.C(_clock29M), .O(hostData[i]), .D(_hostDataOut[i]),
.CE(~_nHostReadFPGA), .T(_nHostReadFPGA)
OFDTX hostDataOutReg (
.D(hostDataOut[i]),
.C(clock29M),
.CE(~_delayedHostRegRead[2]),
.T(~hostDataOutValid),
.O(hostData[i])
);
end
endgenerate
@ -105,71 +183,107 @@ module FPGA (
assign nSRAMWrite = 1'b1;
assign nSRAMEnable = 1'b1;
assign sramAddress = 17'h1ffff;
assign sramData = 8'hff;
/* DRAM interface (currently unused) */
assign dramControl = 12'hfff;
assign dramAddress = 12'hfff;
/* MP3 decoder interface (currently unused) */
assign mp3Reset = 1'b1;
assign mp3ClockIn = 1'b1;
assign mp3StatusCS = 1'b1;
assign mp3InSDIN = 1'b1;
assign mp3InBCLK = 1'b1;
assign mp3InLRCK = 1'b1;
assign hostDataOut = (hostRegister == SYS573D_FPGA_MP3_I2C)
? { 2'h0, mp3SCL, mp3SDA, 12'h000 }
: 16'h0000;
reg mp3SDAState = 1'b0;
reg mp3SCLState = 1'b0;
always @(posedge clock29M)
if (hostDataInPending & (hostRegister == SYS573D_FPGA_MP3_I2C)) begin
mp3SDAState <= hostDataIn[12];
mp3SCLState <= hostDataIn[13];
end
assign mp3SDA = mp3SDAState ? 1'bz : 1'b0;
assign mp3SCL = mp3SCLState ? 1'bz : 1'b0;
/* I2S audio output */
assign dacSDIN = mp3OutSDOUT;
assign dacBCLK = mp3OutBCLK;
assign dacLRCK = mp3OutLRCK;
assign dacMCLK = mp3ClockOut;
/* Magic number */
assign hostDataOut = (hostRegister == SYS573D_FPGA_MAGIC)
? 16'h573f
: 16'h0000;
/* Light outputs */
wire [3:0] _lightBankData = _hostDataIn[15:12];
wire _lightBankA0Write = ~_nHostWriteFPGA & (_hostAddress == 7'h70);
wire _lightBankA1Write = ~_nHostWriteFPGA & (_hostAddress == 7'h71);
wire _lightBankBWrite = ~_nHostWriteFPGA & (_hostAddress == 7'h72);
wire _lightBankDWrite = ~_nHostWriteFPGA & (_hostAddress == 7'h73);
generate
for (i = 0; i < 4; i++) begin
// Use "inverted" flip-flops so that all lights are turned off on
// startup.
OFDXI _lightBankA0Buf (
.C(_clock29M), .Q(lightBankA[i + 4]), .D(_lightBankData[i]),
.CE(_lightBankA0Write)
);
OFDXI _lightBankA1Buf (
.C(_clock29M), .Q(lightBankA[i]), .D(_lightBankData[i]),
.CE(_lightBankA1Write)
);
OFDXI _lightBankBBuf (
.C(_clock29M), .Q(lightBankB[i]), .D(_lightBankData[i]),
.CE(_lightBankBWrite)
);
OFDXI _lightBankDBuf (
.C(_clock29M), .Q(lightBankD[i]), .D(_lightBankData[i]),
.CE(_lightBankDWrite)
);
for (i = 0; i < 4; i = i + 1) begin
reg [3:0] lightBankState = 4'b1111;
wire dataIn = hostDataIn[i + 12];
always @(posedge clock29M)
if (hostDataInPending)
case (hostRegister)
SYS573D_FPGA_LIGHTS_AH:
lightBankState[0] <= dataIn;
SYS573D_FPGA_LIGHTS_AL:
lightBankState[1] <= dataIn;
SYS573D_FPGA_LIGHTS_BH:
lightBankState[2] <= dataIn;
SYS573D_FPGA_LIGHTS_D:
lightBankState[3] <= dataIn;
endcase
// Note that XCS40XL IOBs actually have a tristate flip flop, but
// there seems to be no primitive exposed by ISE to force its usage.
assign lightBankAH[i] = lightBankState[0] ? 1'bz : 1'b0;
assign lightBankAL[i] = lightBankState[1] ? 1'bz : 1'b0;
assign lightBankBH[i] = lightBankState[2] ? 1'bz : 1'b0;
assign lightBankD[i] = lightBankState[3] ? 1'bz : 1'b0;
end
endgenerate
/* Serial interfaces (currently unused) */
assign networkTXEnable = 1'b1;
assign networkTX = 1'b1;
assign serialTX = 1'b1;
assign serialRTS = 1'b1;
assign serialDTR = 1'b1;
/* 1-wire bus */
wire _ds2401In, _ds2433In;
reg _ds2401Out, _ds2433Out;
assign hostDataOut = (hostRegister == SYS573D_FPGA_DS_BUS)
? { 3'h0, ds2401, 3'h0, ds2433, 8'h00 }
: 16'h0000;
// Note that the 1-wire pins are open drain and pulled low by writing 1
// (rather than 0) to the respective register bits, but not inverted when
// read.
IFDX _ds2401InBuf ( .C(_clock29M), .D(ds2401), .Q(_ds2401In), .CE(1'b1) );
IFDX _ds2433InBuf ( .C(_clock29M), .D(ds2433), .Q(_ds2433In), .CE(1'b1) );
OBUFT _ds2401OutBuf ( .O(ds2401), .I(1'b0), .T(~_ds2401Out) );
OBUFT _ds2433OutBuf ( .O(ds2433), .I(1'b0), .T(~_ds2433Out) );
reg ds2433State = 1'b0;
reg ds2401State = 1'b0;
wire _dsBusWrite = ~_nHostWriteFPGA & (_hostAddress == 7'h77);
always @(posedge _clock29M)
if (_dsBusWrite) begin
_ds2401Out <= _hostDataIn[12];
_ds2433Out <= _hostDataIn[13];
always @(posedge clock29M)
if (hostDataInPending & (hostRegister == SYS573D_FPGA_DS_BUS)) begin
ds2433State <= hostDataIn[8];
ds2401State <= hostDataIn[12];
end
/* Readable registers */
wire [15:0] _magicNumberData = 16'h573f;
wire [15:0] _dsBusData = { 2'h0, _ds2433In, _ds2401In, 12'h000 };
wire _magicNumberRead = ~_nHostReadFPGA & (_hostAddress == 7'h40);
wire _dsBusRead = ~_nHostReadFPGA & (_hostAddress == 7'h77);
assign _hostDataOut =
_magicNumberRead ? _magicNumberData :
_dsBusRead ? _dsBusData :
16'h0000;
// The 1-wire pins are pulled low by writing 1 (rather than 0) to the
// respective register bits, but not inverted when read.
assign ds2433 = ds2433State ? 1'b0 : 1'bz;
assign ds2401 = ds2401State ? 1'b0 : 1'bz;
endmodule

368
fpga/src/spartanxl.v Normal file
View File

@ -0,0 +1,368 @@
/* Logic primitives */
module BUF (input I, output O);
`ifndef SYNTHESIS
assign O = I;
`endif
endmodule
module INV (input I, output O);
`ifndef SYNTHESIS
assign O = ~I;
`endif
endmodule
module AND2 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = I0 & I1;
`endif
endmodule
module NAND2 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = ~(I0 & I1);
`endif
endmodule
module AND2B1 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = I0 & ~I1;
`endif
endmodule
module OR2 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = I0 | I1;
`endif
endmodule
module NOR2 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = ~(I0 | I1);
`endif
endmodule
module OR2B1 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = I0 | ~I1;
`endif
endmodule
module XOR2 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = (I0 != I1);
`endif
endmodule
module XNOR2 (input I0, input I1, output O);
`ifndef SYNTHESIS
assign O = (I0 == I1);
`endif
endmodule
module BUFT (input I, input T, output O);
`ifndef SYNTHESIS
assign O = T ? 1'bz : I;
`endif
endmodule
module FDCE (input D, input C, input CLR, input CE, output Q);
`ifndef SYNTHESIS
reg data;
assign Q = data;
initial
data = 1'b0;
always @(CLR)
data <= 1'b0;
always @(posedge C)
data <= CE ? D : data;
`endif
endmodule
module FDPE (input D, input C, input PRE, input CE, output Q);
`ifndef SYNTHESIS
reg data;
assign Q = data;
initial
data = 1'b1;
always @(PRE)
data <= 1'b1;
always @(posedge C)
data <= CE ? D : data;
`endif
endmodule
module LDCE_1 (input D, input G, input CLR, input GE, output Q);
`ifndef SYNTHESIS
reg data;
assign Q = data;
initial
data = 1'b0;
always @(CLR)
data <= 1'b0;
always @(~G)
data <= GE ? D : data;
`endif
endmodule
module LDPE_1 (input D, input G, input PRE, input GE, output Q);
`ifndef SYNTHESIS
reg data;
assign Q = data;
initial
data = 1'b1;
always @(PRE)
data <= 1'b1;
always @(~G)
data <= GE ? D : data;
`endif
endmodule
/* I/O primitives */
(* keep *) module BUFGLS (input I, output O);
`ifndef SYNTHESIS
BUF buffer (.I(I), .O(O));
`endif
endmodule
(* keep *) module IBUF (input I, output O);
`ifndef SYNTHESIS
BUF buffer (.I(I), .O(O));
`endif
endmodule
(* keep *) module OBUF (input I, output O);
`ifndef SYNTHESIS
BUF buffer (.I(I), .O(O));
`endif
endmodule
(* keep *) module OBUFT (input I, input T, output O);
`ifndef SYNTHESIS
BUFT buffer (.I(I), .T(T), .O(O));
`endif
endmodule
(* keep *) module IOBUFT (input I, input T, output O, inout IO);
`ifndef SYNTHESIS
assign O = IO;
BUFT buffer (.I(I), .T(T), .O(IO));
`endif
endmodule
(* keep *) module IFDX (input D, input C, input CE, output Q);
`ifndef SYNTHESIS
reg data;
assign Q = data;
initial
data = 1'b0;
always @(posedge C)
data <= CE ? D : data;
`endif
endmodule
(* keep *) module IFDXI (input D, input C, input CE, output Q);
`ifndef SYNTHESIS
reg data;
assign Q = data;
initial
data = 1'b1;
always @(posedge C)
data <= CE ? D : data;
`endif
endmodule
(* keep *) module OFDX (input D, input C, input CE, output Q);
`ifndef SYNTHESIS
IFDX ff (.D(D), .C(C), .CE(CE), .Q(Q));
`endif
endmodule
(* keep *) module OFDXI (input D, input C, input CE, output Q);
`ifndef SYNTHESIS
IFDXI ff (.D(D), .C(C), .CE(CE), .Q(Q));
`endif
endmodule
(* keep *) module OFDTX (input D, input C, input CE, input T, output O);
`ifndef SYNTHESIS
wire Q;
IFDX ff (.D(D), .C(C), .CE(CE), .Q(Q));
BUFT buffer (.I(Q), .T(T), .O(O));
`endif
endmodule
(* keep *) module OFDTXI (input D, input C, input CE, input T, output O);
`ifndef SYNTHESIS
wire Q;
IFDXI ff (.D(D), .C(C), .CE(CE), .Q(Q));
BUFT buffer (.I(Q), .T(T), .O(O));
`endif
endmodule
/* I/O pads */
(* keep *) module IPAD (output IPAD);
endmodule
(* keep *) module OPAD (input OPAD);
endmodule
(* keep *) module IOPAD (inout IOPAD);
endmodule
(* keep *) module UPAD (inout UPAD);
endmodule
(* keep *) module TDI (inout I);
endmodule
(* keep *) module TDO (input O);
endmodule
(* keep *) module TCK (inout I);
endmodule
(* keep *) module TMS (inout I);
endmodule
/* Fixed-function blocks (not simulated) */
(* keep *) module STARTUP (
input GSR,
input GTS,
input CLK,
output DONEIN,
output Q1Q4,
output Q2,
output Q3
);
endmodule
(* keep *) module OSC4 (
output F8M,
output F500K,
output F16K,
output F490,
output F15
);
endmodule
(* keep *) module BSCAN(
input TDI,
input TDO1,
input TDO2,
input TCK,
input TMS,
output TDO,
output DRCK,
output IDLE,
output SEL1,
output SEL2
);
endmodule
(* keep *) module RDBK (input TRIG, output DATA, output RIP);
endmodule
(* keep *) module RDCLK (input I);
endmodule
/* ISE built-in macros */
module CC8CE (
input C, input CLR, input CE, output [7:0] Q, output CEO, output TC
);
`ifndef SYNTHESIS
reg [7:0] data;
assign Q = data;
assign TC = &data;
assign CEO = TC & CE;
initial
data = 8'h00;
always @(CLR)
data <= 8'h00;
always @(posedge C)
data <= data + CE;
`endif
endmodule
module CC8CLE (
input [7:0] D, input L, input C, input CLR, input CE, output [7:0] Q,
output CEO, output TC
);
`ifndef SYNTHESIS
reg [7:0] data;
assign Q = data;
assign TC = &data;
assign CEO = TC & CE;
initial
data = 8'h00;
always @(CLR)
data <= 8'h00;
always @(posedge C)
if (L)
data <= D;
else
data <= data + CE;
`endif
endmodule
module CC16CE (
input C, input CLR, input CE, output [15:0] Q, output CEO, output TC
);
`ifndef SYNTHESIS
reg [15:0] data;
assign Q = data;
assign TC = &data;
assign CEO = TC & CE;
initial
data = 16'h0000;
always @(CLR)
data <= 16'h0000;
always @(posedge C)
data <= data + CE;
`endif
endmodule
module CC16CLE (
input [15:0] D, input L, input C, input CLR, input CE, output [15:0] Q,
output CEO, output TC
);
`ifndef SYNTHESIS
reg [15:0] data;
assign Q = data;
assign TC = &data;
assign CEO = TC & CE;
initial
data = 16'h0000;
always @(CLR)
data <= 16'h0000;
always @(posedge C)
if (L)
data <= D;
else
data <= data + CE;
`endif
endmodule

View File

@ -6,7 +6,7 @@
*/
(* techmap_celltype = "IOBUFT" *)
module _ISE_IOBUFT (inout IO, input I, output O, input T);
module _ISE_IOBUFT (input I, input T, output O, inout IO);
IBUF _TECHMAP_REPLACE_.ibuf (.I(IO), .O(O));
OBUFT _TECHMAP_REPLACE_.obuf (.O(IO), .I(I), .T(T));
endmodule
@ -63,7 +63,10 @@ endmodule
(* techmap_celltype = "$_TBUF_" *)
module _ISE_BUFT (input A, input E, output Y);
BUFT _TECHMAP_REPLACE_ ( .I(A), .T(~E), .O(Y) );
wire T;
INV _TECHMAP_REPLACE_.inv (.I(E), .O(T));
BUFT _TECHMAP_REPLACE_.buffer (.I(A), .T(T), .O(Y));
endmodule
(* techmap_celltype = "$_DFFE_PP0P_" *)

View File

@ -13,8 +13,12 @@ uint16_t _bankSwitchReg, _cartOutputReg, _miscOutputReg;
/* System initialization */
static constexpr int _RESET_DELAY = 5000;
static constexpr int _FPGA_INIT_DELAY = 1000;
static constexpr int _IDE_RESET_ASSERT_DELAY = 5000;
static constexpr int _IDE_RESET_CLEAR_DELAY = 50000;
static constexpr int _FPGA_RESET_DELAY = 5000;
static constexpr int _FPGA_STARTUP_DELAY = 50000;
static constexpr int _FPGA_INIT_REG_DELAY = 5000;
void init(void) {
// Remapping the base address is required in order for IDE DMA to work
@ -62,9 +66,9 @@ void initIOBoard(void) {
// Some of the digital I/O board's light outputs are controlled by the FPGA
// and cannot be turned off until the FPGA is initialized.
if (isDigitalIOPresent()) {
//SYS573D_CPLD_LIGHTS_B0 = 0xf000;
SYS573D_CPLD_LIGHTS_C0 = 0xf000;
SYS573D_CPLD_LIGHTS_C1 = 0xf000;
SYS573D_CPLD_LIGHTS_BL = 0xf000;
SYS573D_CPLD_LIGHTS_CL = 0xf000;
SYS573D_CPLD_LIGHTS_CH = 0xf000;
} else {
SYS573A_LIGHTS_A = 0x00ff;
SYS573A_LIGHTS_B = 0x00ff;
@ -75,10 +79,10 @@ void initIOBoard(void) {
void resetIDEDevices(void) {
SYS573_IDE_RESET = 0;
delayMicroseconds(_RESET_DELAY);
delayMicroseconds(_IDE_RESET_ASSERT_DELAY);
SYS573_IDE_RESET = 1;
delayMicroseconds(_RESET_DELAY);
delayMicroseconds(_IDE_RESET_CLEAR_DELAY);
}
/* JAMMA and RTC functions */
@ -231,6 +235,8 @@ bool loadRawBitstream(const uint8_t *data, size_t length) {
else
return false;
const uint16_t mask = SYS573D_CPLD_STAT_INIT | SYS573D_CPLD_STAT_DONE;
for (int i = 3; i; i--) {
SYS573D_CPLD_UNK_RESET = 0;
@ -243,22 +249,18 @@ bool loadRawBitstream(const uint8_t *data, size_t length) {
| SYS573D_CPLD_CTRL_DONE
| SYS573D_CPLD_CTRL_PROGRAM
| SYS573D_CPLD_CTRL_UNKNOWN;
delayMicroseconds(_FPGA_RESET_DELAY);
delayMicroseconds(_RESET_DELAY);
if (!(SYS573D_CPLD_STAT & SYS573D_CPLD_STAT_INIT))
if ((SYS573D_CPLD_STAT & mask) != SYS573D_CPLD_STAT_INIT)
continue;
writeFunc(data, length);
delayMicroseconds(_FPGA_STARTUP_DELAY);
const uint16_t mask = SYS573D_CPLD_STAT_INIT | SYS573D_CPLD_STAT_DONE;
if ((SYS573D_CPLD_STAT & mask) != mask)
continue;
for (int j = 15; j; j--) {
if ((SYS573D_CPLD_STAT & mask) == mask)
return true;
delayMicroseconds(_FPGA_INIT_DELAY);
}
}
return false;
@ -267,19 +269,19 @@ bool loadRawBitstream(const uint8_t *data, size_t length) {
void initKonamiBitstream(void) {
SYS573D_FPGA_INIT = 0xf000;
SYS573D_FPGA_INIT = 0x0000;
delayMicroseconds(_FPGA_INIT_DELAY);
delayMicroseconds(_FPGA_INIT_REG_DELAY);
SYS573D_FPGA_INIT = 0xf000;
delayMicroseconds(_FPGA_INIT_DELAY);
delayMicroseconds(_FPGA_INIT_REG_DELAY);
// Turn off all lights including the ones that were left on by init().
SYS573D_FPGA_LIGHTS_A0 = 0xf000;
SYS573D_FPGA_LIGHTS_A1 = 0xf000;
SYS573D_CPLD_LIGHTS_B0 = 0xf000;
SYS573D_FPGA_LIGHTS_B1 = 0xf000;
SYS573D_CPLD_LIGHTS_C0 = 0xf000;
SYS573D_CPLD_LIGHTS_C1 = 0xf000;
SYS573D_FPGA_LIGHTS_D0 = 0xf000;
SYS573D_FPGA_LIGHTS_AL = 0xf000;
SYS573D_FPGA_LIGHTS_AH = 0xf000;
SYS573D_CPLD_LIGHTS_BL = 0xf000;
SYS573D_FPGA_LIGHTS_BH = 0xf000;
SYS573D_CPLD_LIGHTS_CL = 0xf000;
SYS573D_CPLD_LIGHTS_CH = 0xf000;
SYS573D_FPGA_LIGHTS_D = 0xf000;
}
/* I2C driver */

View File

@ -153,11 +153,11 @@ static inline bool isDigitalIOPresent(void) {
}
static inline bool getDIO1Wire(void) {
return (SYS573D_FPGA_DS2401 >> 12) & 1;
return (SYS573D_FPGA_DS_BUS / SYS573D_FPGA_DS_BUS_DS2401) & 1;
}
static inline void setDIO1Wire(bool value) {
SYS573D_FPGA_DS2401 = (value ^ 1) << 12;
SYS573D_FPGA_DS_BUS = (value ^ 1) * SYS573D_FPGA_DS_BUS_DS2401;
}
/* Other APIs */

View File

@ -268,7 +268,10 @@ bool App::_atapiEjectWorker(void) {
if (!(dev.flags & ide::DEVICE_ATAPI))
continue;
auto error =
auto error = ide::DISC_CHANGED;
while (error == ide::DISC_CHANGED)
error =
ide::devices[0].startStopUnit(ide::START_STOP_MODE_OPEN_TRAY);
if (error) {

View File

@ -137,18 +137,47 @@ typedef enum {
SYS573D_CPLD_CTRL_UNKNOWN = 1 << 15
} Sys573DCPLDControlFlag;
typedef enum {
SYS573D_FPGA_DS_BUS_DS2433 = 1 << 8,
SYS573D_FPGA_DS_BUS_DS2401 = 1 << 12
} Sys573DFPGADSBusFlag;
#define SYS573D_FPGA_MAGIC _MMIO16(DEV0_BASE | 0x640080)
#define SYS573D_FPGA_LIGHTS_A1 _MMIO16(DEV0_BASE | 0x6400e0)
#define SYS573D_FPGA_LIGHTS_A0 _MMIO16(DEV0_BASE | 0x6400e2)
#define SYS573D_FPGA_LIGHTS_B1 _MMIO16(DEV0_BASE | 0x6400e4)
#define SYS573D_FPGA_LIGHTS_D0 _MMIO16(DEV0_BASE | 0x6400e6)
#define SYS573D_FPGA_MP3_PTR_H _MMIO16(DEV0_BASE | 0x6400a0)
#define SYS573D_FPGA_MP3_PTR_L _MMIO16(DEV0_BASE | 0x6400a2)
#define SYS573D_FPGA_MP3_ENDPTR_H _MMIO16(DEV0_BASE | 0x6400a4)
#define SYS573D_FPGA_MP3_ENDPTR_L _MMIO16(DEV0_BASE | 0x6400a6)
#define SYS573D_FPGA_MP3_COUNTER _MMIO16(DEV0_BASE | 0x6400a8)
#define SYS573D_FPGA_MP3_KEY1 _MMIO16(DEV0_BASE | 0x6400a8)
#define SYS573D_FPGA_MP3_FEED_STAT _MMIO16(DEV0_BASE | 0x6400aa)
#define SYS573D_FPGA_MP3_I2C _MMIO16(DEV0_BASE | 0x6400ac)
#define SYS573D_FPGA_MP3_FEED_CTRL _MMIO16(DEV0_BASE | 0x6400ae)
#define SYS573D_FPGA_DRAM_WRPTR_H _MMIO16(DEV0_BASE | 0x6400b0)
#define SYS573D_FPGA_DRAM_WRPTR_L _MMIO16(DEV0_BASE | 0x6400b2)
#define SYS573D_FPGA_DRAM_DATA _MMIO16(DEV0_BASE | 0x6400b4)
#define SYS573D_FPGA_DRAM_RDPTR_H _MMIO16(DEV0_BASE | 0x6400b6)
#define SYS573D_FPGA_DRAM_RDPTR_L _MMIO16(DEV0_BASE | 0x6400b8)
#define SYS573D_FPGA_NET_DATA _MMIO16(DEV0_BASE | 0x6400c0)
#define SYS573D_FPGA_DAC_COUNTER_H _MMIO16(DEV0_BASE | 0x6400ca)
#define SYS573D_FPGA_DAC_COUNTER_L _MMIO16(DEV0_BASE | 0x6400cc)
#define SYS573D_FPGA_DAC_COUNTER_D _MMIO16(DEV0_BASE | 0x6400ce)
#define SYS573D_FPGA_LIGHTS_AH _MMIO16(DEV0_BASE | 0x6400e0)
#define SYS573D_FPGA_LIGHTS_AL _MMIO16(DEV0_BASE | 0x6400e2)
#define SYS573D_FPGA_LIGHTS_BH _MMIO16(DEV0_BASE | 0x6400e4)
#define SYS573D_FPGA_LIGHTS_D _MMIO16(DEV0_BASE | 0x6400e6)
#define SYS573D_FPGA_INIT _MMIO16(DEV0_BASE | 0x6400e8)
#define SYS573D_FPGA_DS2401 _MMIO16(DEV0_BASE | 0x6400ee)
#define SYS573D_FPGA_MP3_KEY2 _MMIO16(DEV0_BASE | 0x6400ea)
#define SYS573D_FPGA_MP3_KEY3 _MMIO16(DEV0_BASE | 0x6400ec)
#define SYS573D_FPGA_DS_BUS _MMIO16(DEV0_BASE | 0x6400ee)
#define SYS573D_CPLD_UNK_RESET _MMIO16(DEV0_BASE | 0x6400f4)
#define SYS573D_CPLD_STAT _MMIO16(DEV0_BASE | 0x6400f6)
#define SYS573D_CPLD_CTRL _MMIO16(DEV0_BASE | 0x6400f6)
#define SYS573D_CPLD_BITSTREAM _MMIO16(DEV0_BASE | 0x6400f8)
#define SYS573D_CPLD_LIGHTS_C0 _MMIO16(DEV0_BASE | 0x6400fa)
#define SYS573D_CPLD_LIGHTS_C1 _MMIO16(DEV0_BASE | 0x6400fc)
#define SYS573D_CPLD_LIGHTS_B0 _MMIO16(DEV0_BASE | 0x6400fe)
#define SYS573D_CPLD_LIGHTS_CL _MMIO16(DEV0_BASE | 0x6400fa)
#define SYS573D_CPLD_LIGHTS_CH _MMIO16(DEV0_BASE | 0x6400fc)
#define SYS573D_CPLD_LIGHTS_BL _MMIO16(DEV0_BASE | 0x6400fe)