mirror of
https://github.com/UzixLS/zx-sizif-xxs.git
synced 2025-07-19 07:11:28 +03:00
Compare commits
12 Commits
fw-2022111
...
master
Author | SHA1 | Date | |
---|---|---|---|
64a4bb69c0 | |||
df7f0e55e6 | |||
c8d83ac5c1 | |||
c69b7c8ba4 | |||
76b4d4d838 | |||
e7552c5743 | |||
a942f43c5a | |||
2b263995cc | |||
34a98edc64 | |||
948f4190f3 | |||
48ad108e9c | |||
671a748207 |
5
Makefile
5
Makefile
@ -12,11 +12,12 @@ all:
|
||||
build_rev:
|
||||
${MAKE} REV=${REV} -C rom_src/ clean all
|
||||
${MAKE} REV=${REV} -C rom/ clean all
|
||||
${MAKE} REV=${REV} -C fpga/syn/ clean build sof2jic
|
||||
${MAKE} REV=${REV} -C fpga/syn/ clean build sof2jic rbf2bin
|
||||
cp fpga/syn/output/rev_${REV}.jic ${OUTDIR}/rev_${REV}.jic
|
||||
cat fpga/syn/output/rev_${REV}.bin rom/sizif.rom > ${OUTDIR}/rev_${REV}.bin
|
||||
|
||||
clean:
|
||||
rm -f "${OUTDIR}"
|
||||
rm -rf "${OUTDIR}"
|
||||
${MAKE} -C fpga/syn/ clean
|
||||
${MAKE} -C fpga/tb/ clean
|
||||
${MAKE} -C rom_src/ clean
|
||||
|
@ -50,6 +50,11 @@ Sizif contains 512K RAM. 128K available via 7FFDh port, 128K via DFFDh (Profi st
|
||||
### SD card
|
||||
Sizif have preinstalled esxDOS firmware, which provides ability to load TAP, TRD, SCL, Z80 files and save snapshots. To use this you should format SD cart to FAT32 or FAT16 and unpack latest esxDOS release ([link](http://www.esxdos.org/index.html)) to card. Also it's recommended to install Long Filename Browser ([link](https://spectrumcomputing.co.uk/forums/viewtopic.php?t=2553)) to card.
|
||||
|
||||
### How to program
|
||||
There is two options:
|
||||
1. Program via JTAG connector using USB blaster and Quartus Programmer - use jic file from out folder.
|
||||
2. Program flash chip directly using TL866 or similar device - use bin file.
|
||||
|
||||
### Changelog & current status
|
||||
* Rev.A - first release. Please note the [errata](pcb/rev.A/ERRATA.txt).
|
||||
* Rev.B:
|
||||
|
@ -6,6 +6,7 @@ endpackage
|
||||
|
||||
|
||||
interface cpu_bus();
|
||||
reg [15:0] a_raw;
|
||||
reg [15:0] a;
|
||||
reg [7:0] d;
|
||||
reg iorq;
|
||||
@ -15,8 +16,7 @@ interface cpu_bus();
|
||||
reg rd;
|
||||
reg wr;
|
||||
|
||||
reg [15:0] a_reg;
|
||||
reg [7:0] d_reg;
|
||||
wire ioreq;
|
||||
wire memreq;
|
||||
reg ioreq;
|
||||
reg memreq;
|
||||
reg memreq_rise;
|
||||
endinterface
|
||||
|
153
fpga/rtl/cpu.sv
Normal file
153
fpga/rtl/cpu.sv
Normal file
@ -0,0 +1,153 @@
|
||||
import common::*;
|
||||
module cpu(
|
||||
input rst_n,
|
||||
input clk28,
|
||||
input clk14,
|
||||
input clk7,
|
||||
input clk35,
|
||||
input ck14,
|
||||
input ck7,
|
||||
|
||||
cpu_bus bus,
|
||||
|
||||
input [8:0] vc,
|
||||
input [8:0] hc,
|
||||
input video_contention,
|
||||
input [2:0] ram_page128,
|
||||
input machine_t machine,
|
||||
input turbo_t turbo,
|
||||
input init_done_in,
|
||||
input hold,
|
||||
|
||||
output reg n_rstcpu_out,
|
||||
output reg clkcpu,
|
||||
output clkcpu_ck,
|
||||
output reg n_int,
|
||||
output reg n_int_next,
|
||||
output snow,
|
||||
output contention
|
||||
);
|
||||
|
||||
|
||||
/* CONTENTION */
|
||||
wire iorq_contended = bus.ioreq && (~bus.a[0] || (bus.a == 16'hBF3B) || (bus.a == 16'hFF3B)) && (machine != MACHINE_S3);
|
||||
reg mreq_delayed, iorq_delayed;
|
||||
always @(posedge clkcpu)
|
||||
mreq_delayed <= bus.mreq;
|
||||
always @(posedge clkcpu)
|
||||
iorq_delayed <= iorq_contended;
|
||||
wire contention_page = (machine == MACHINE_S3)? ram_page128[2] : ram_page128[0];
|
||||
wire contention_addr = bus.a_raw[14] & (~bus.a_raw[15] | (bus.a_raw[15] & contention_page));
|
||||
wire contention_mem = !iorq_contended && !mreq_delayed && contention_addr;
|
||||
wire contention0 = video_contention && !iorq_delayed && (contention_mem || iorq_contended);
|
||||
assign contention = clkcpu && contention0 && turbo == TURBO_NONE && (machine == MACHINE_S48 || machine == MACHINE_S128 || machine == MACHINE_S3);
|
||||
assign snow = video_contention && contention_addr && bus.rfsh && bus.mreq && (machine == MACHINE_S48 || machine == MACHINE_S128);
|
||||
|
||||
|
||||
/* CLOCK */
|
||||
wire turbo_wait_cond = turbo == TURBO_14 && (bus.rd || bus.wr || (bus.iorq && bus.m1));
|
||||
reg [2:0] turbo_wait_reg;
|
||||
reg turbo_wait;
|
||||
always @* begin
|
||||
if (bus.iorq)
|
||||
turbo_wait <= turbo_wait_cond && !turbo_wait_reg[2];
|
||||
else
|
||||
turbo_wait <= turbo_wait_cond && !turbo_wait_reg[1];
|
||||
end
|
||||
always @(posedge clk28) begin
|
||||
if (clkcpu != clk14)
|
||||
turbo_wait_reg <= {turbo_wait_reg[1:0], turbo_wait_cond};
|
||||
end
|
||||
|
||||
reg clkcpu_prev;
|
||||
assign clkcpu_ck = clkcpu && !clkcpu_prev;
|
||||
always @(posedge clk28) begin
|
||||
clkcpu_prev <= clkcpu;
|
||||
if (contention || hold || turbo_wait)
|
||||
clkcpu <= clkcpu;
|
||||
else if (turbo == TURBO_14)
|
||||
clkcpu <= clk14;
|
||||
else if (turbo == TURBO_7 && ck14)
|
||||
clkcpu <= clk7;
|
||||
else if (turbo == TURBO_5 && ck14 && hc[1])
|
||||
clkcpu <= clk7;
|
||||
else if (turbo == TURBO_4 && ck14 && hc[1] && hc[2])
|
||||
clkcpu <= clk7;
|
||||
else if (ck7)
|
||||
clkcpu <= clk35;
|
||||
end
|
||||
|
||||
|
||||
/* INT GENERATOR */
|
||||
localparam INT_V_S48 = 248;
|
||||
localparam INT_H_S48 = 0;
|
||||
localparam INT_L_S48 = 6'd32;
|
||||
localparam INT_V_S128 = 248;
|
||||
localparam INT_H_S128 = 4;
|
||||
localparam INT_L_S128 = 6'd36;
|
||||
localparam INT_V_PENT = 239;
|
||||
localparam INT_H_PENT = 322;
|
||||
localparam INT_L_PENT = 6'd32;
|
||||
wire int_begin =
|
||||
(machine == MACHINE_S48)?
|
||||
vc == INT_V_S48 && hc == INT_H_S48 :
|
||||
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||
vc == INT_V_S128 && hc == INT_H_S128 :
|
||||
// Pentagon
|
||||
vc == INT_V_PENT && hc == INT_H_PENT ;
|
||||
wire [5:0] int_len =
|
||||
(machine == MACHINE_S48)?
|
||||
INT_L_S48 :
|
||||
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||
INT_L_S128 :
|
||||
// Pentagon
|
||||
INT_L_PENT ;
|
||||
|
||||
reg [5:0] int_cnt;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
int_cnt <= 0;
|
||||
n_int_next <= 1'b1;
|
||||
end
|
||||
else if ((int_cnt != 0 && clkcpu_ck) || (int_cnt == 0 && int_begin)) begin
|
||||
int_cnt <= int_cnt + 1'b1;
|
||||
n_int_next <= (int_cnt < int_len)? 1'b0 : 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
n_int <= 1'b1;
|
||||
else if (clkcpu_ck)
|
||||
n_int <= n_int_next;
|
||||
end
|
||||
|
||||
|
||||
/* RESET */
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
n_rstcpu_out <= 0;
|
||||
else if (!init_done_in)
|
||||
n_rstcpu_out <= 0;
|
||||
`ifdef TESTBENCH
|
||||
else if (hc[4])
|
||||
n_rstcpu_out <= 1'b1;
|
||||
`endif
|
||||
else if (vc[8])
|
||||
n_rstcpu_out <= 1'b1;
|
||||
end
|
||||
|
||||
|
||||
/* T-STATES COUNTER (for debug) */
|
||||
`ifdef TESTBENCH
|
||||
integer tstate;
|
||||
always @(posedge clkcpu) begin
|
||||
if (!n_int_next && n_int)
|
||||
tstate <= -1;
|
||||
else
|
||||
tstate <= tstate + 1;
|
||||
end
|
||||
`endif
|
||||
|
||||
|
||||
endmodule
|
@ -1,139 +0,0 @@
|
||||
import common::*;
|
||||
module cpucontrol(
|
||||
input rst_n,
|
||||
input clk28,
|
||||
input clk14,
|
||||
input clk7,
|
||||
input clk35,
|
||||
input ck14,
|
||||
input ck7,
|
||||
|
||||
cpu_bus bus,
|
||||
|
||||
input [8:0] vc,
|
||||
input [8:0] hc,
|
||||
input screen_contention,
|
||||
input [2:0] rampage128,
|
||||
input machine_t machine,
|
||||
input turbo_t turbo,
|
||||
input init_done_in,
|
||||
|
||||
output reg n_rstcpu,
|
||||
output reg clkcpu,
|
||||
output clkcpu_ck,
|
||||
output clkwait,
|
||||
output reg n_int,
|
||||
output n_int_next,
|
||||
output snow
|
||||
);
|
||||
|
||||
|
||||
/* CONTENTION */
|
||||
wire iorq_contended = bus.iorq && (~bus.a_reg[0] || (~bus.a_reg[1] && ~bus.a[15] && bus.wr)) && (machine != MACHINE_S3);
|
||||
reg mreq_delayed, iorq_delayed;
|
||||
always @(negedge clk28) if (clkcpu_ck)
|
||||
mreq_delayed <= bus.mreq;
|
||||
always @(negedge clk28) if (clkcpu_ck)
|
||||
iorq_delayed <= bus.iorq && ~bus.a_reg[0];
|
||||
wire contention_mem_page = (machine == MACHINE_S3)? rampage128[2] : rampage128[0];
|
||||
wire contention_mem_addr = bus.a[14] & (~bus.a[15] | (bus.a[15] & contention_mem_page));
|
||||
wire contention_mem = iorq_delayed == 1'b0 && mreq_delayed == 1'b0 && contention_mem_addr;
|
||||
wire contention_io = iorq_delayed == 1'b0 && iorq_contended;
|
||||
wire contention0 = screen_contention && (contention_mem || contention_io);
|
||||
wire contention = clkcpu && contention0 && turbo == TURBO_NONE && (machine == MACHINE_S48 || machine == MACHINE_S128 || machine == MACHINE_S3);
|
||||
assign snow = bus.a[14] && ~bus.a[15] && bus.rfsh && (machine == MACHINE_S48 || machine == MACHINE_S128);
|
||||
|
||||
|
||||
/* CLOCK */
|
||||
reg [3:0] turbo_wait;
|
||||
wire turbo_wait_trig0 = turbo == TURBO_14 && bus.mreq && !bus.rfsh;
|
||||
wire turbo_wait_trig1 = turbo == TURBO_14 && (bus.rd || bus.wr);
|
||||
reg turbo_wait_trig0_prev, turbo_wait_trig1_prev;
|
||||
always @(posedge clk28) begin
|
||||
turbo_wait[0] <= turbo_wait_trig0 && !turbo_wait_trig0_prev;
|
||||
turbo_wait[1] <= turbo_wait[0] || (turbo_wait_trig1 && !turbo_wait_trig1_prev);
|
||||
turbo_wait[2] <= turbo_wait[1];
|
||||
turbo_wait[3] <= turbo_wait[2];
|
||||
turbo_wait_trig0_prev <= turbo_wait_trig0;
|
||||
turbo_wait_trig1_prev <= turbo_wait_trig1;
|
||||
end
|
||||
|
||||
reg clkcpu_prev;
|
||||
assign clkcpu_ck = clkcpu && !clkcpu_prev;
|
||||
assign clkwait = contention || (|turbo_wait[3:1]);
|
||||
always @(posedge clk28) begin
|
||||
clkcpu_prev <= clkcpu;
|
||||
if (clkwait)
|
||||
clkcpu <= clkcpu;
|
||||
else if (turbo == TURBO_14)
|
||||
clkcpu <= clk14;
|
||||
else if (turbo == TURBO_7 && ck14)
|
||||
clkcpu <= clk7;
|
||||
else if (turbo == TURBO_5 && ck14 && hc[1])
|
||||
clkcpu <= clk7;
|
||||
else if (turbo == TURBO_4 && ck14 && hc[1] && hc[2])
|
||||
clkcpu <= clk7;
|
||||
else if (ck7)
|
||||
clkcpu <= clk35;
|
||||
end
|
||||
|
||||
|
||||
/* INT GENERATOR */
|
||||
localparam INT_V_S48 = 248;
|
||||
localparam INT_H_S48 = 0;
|
||||
localparam INT_V_S128 = 248;
|
||||
localparam INT_H_S128 = 4;
|
||||
localparam INT_V_PENT = 239;
|
||||
localparam INT_H_PENT = 322;
|
||||
wire int_begin =
|
||||
(machine == MACHINE_S48)?
|
||||
vc == INT_V_S48 && hc == INT_H_S48 :
|
||||
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||
vc == INT_V_S128 && hc == INT_H_S128 :
|
||||
// Pentagon
|
||||
vc == INT_V_PENT && hc == INT_H_PENT ;
|
||||
|
||||
reg [4:0] int_cnt;
|
||||
assign n_int_next = (|int_cnt)? 1'b0 : 1'b1;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
int_cnt <= 0;
|
||||
n_int <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
if (clkcpu_ck)
|
||||
n_int <= n_int_next;
|
||||
if ((int_cnt != 0 && clkcpu_ck) || (int_cnt == 0 && int_begin))
|
||||
int_cnt <= int_cnt + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/* RESET */
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
n_rstcpu <= 0;
|
||||
else if (!init_done_in)
|
||||
n_rstcpu <= 0;
|
||||
`ifdef TESTBENCH
|
||||
else if (hc[4])
|
||||
n_rstcpu <= 1'b1;
|
||||
`endif
|
||||
else if (vc[8])
|
||||
n_rstcpu <= 1'b1;
|
||||
end
|
||||
|
||||
|
||||
/* T-STATES COUNTER (for debug) */
|
||||
`ifdef TESTBENCH
|
||||
integer tstate;
|
||||
always @(posedge clkcpu) begin
|
||||
if (!n_int_next && n_int)
|
||||
tstate <= -1;
|
||||
else
|
||||
tstate <= tstate + 1;
|
||||
end
|
||||
`endif
|
||||
|
||||
|
||||
endmodule
|
@ -19,62 +19,71 @@ module divmmc(
|
||||
output reg sd_cs,
|
||||
|
||||
input rammap,
|
||||
input magic_mode,
|
||||
input magic_map,
|
||||
input mask_hooks,
|
||||
input mask_nmi_hook,
|
||||
input basic48_paged,
|
||||
|
||||
output reg [3:0] page,
|
||||
output map,
|
||||
output automap,
|
||||
output reg mapram,
|
||||
output ram,
|
||||
output ramwr_mask,
|
||||
output cpuwait
|
||||
output ext_wait_cycle2
|
||||
);
|
||||
|
||||
|
||||
reg automap0;
|
||||
reg automap_next;
|
||||
reg rom_m1_access, rom_m1_access0;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
automap_next <= 0;
|
||||
automap0 <= 0;
|
||||
rom_m1_access <= 0;
|
||||
rom_m1_access0 <= 0;
|
||||
end
|
||||
else if (bus.m1 && bus.memreq && !magic_map) begin
|
||||
if (!en_hooks || !en || rammap) begin
|
||||
automap_next <= 0;
|
||||
else if (bus.m1) begin
|
||||
rom_m1_access0 <= bus.a_raw[15:14] == 2'b00;
|
||||
end
|
||||
else if (bus.a_reg[15:3] == 13'h3FF) begin // exit vectors 1FF8-1FFF
|
||||
automap_next <= 0;
|
||||
end
|
||||
else if (
|
||||
bus.a_reg == 16'h0000 || // power-on/reset/rst0/software restart
|
||||
bus.a_reg == 16'h0008 || // syntax error
|
||||
bus.a_reg == 16'h0038 || // im1 interrupt/rst #38
|
||||
(bus.a_reg == 16'h0066 && !magic_mode) || // nmi routine
|
||||
bus.a_reg == 16'h04C6 || // tape save routine
|
||||
bus.a_reg == 16'h0562 // tape load and verify routine
|
||||
) begin
|
||||
automap_next <= 1'b1;
|
||||
end
|
||||
else if (bus.a_reg[15:8] == 8'h3D) begin // tr-dos mapping area
|
||||
automap_next <= 1'b1;
|
||||
automap0 <= 1'b1;
|
||||
end
|
||||
end
|
||||
else if (!bus.m1) begin
|
||||
automap0 <= automap_next;
|
||||
else begin
|
||||
rom_m1_access <= rom_m1_access0;
|
||||
end
|
||||
end
|
||||
|
||||
// #3Dxx entrypoint is critical for timings, so we're arming 'map' signal as soon as possible
|
||||
assign automap = automap0 || (bus.m1 && bus.memreq && !magic_map && en_hooks && en && !rammap && bus.a_reg[15:8] == 8'h3D);
|
||||
reg automap, automap_next;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
automap_next <= 0;
|
||||
automap <= 0;
|
||||
end
|
||||
else if (bus.m1 && bus.memreq_rise && !mask_hooks) begin
|
||||
if (!en_hooks || !en || rammap) begin
|
||||
automap_next <= 0;
|
||||
end
|
||||
else if (bus.a[15:3] == 13'h3FF) begin // exit vectors 1FF8-1FFF
|
||||
automap_next <= 0;
|
||||
end
|
||||
else if (
|
||||
(bus.a == 16'h0000) || // power-on/reset/rst0/software restart
|
||||
(bus.a == 16'h0008 && (basic48_paged || !rom_m1_access)) || // syntax error
|
||||
(bus.a == 16'h0038 && (basic48_paged || !rom_m1_access)) || // im1 interrupt/rst #38
|
||||
(bus.a == 16'h0066 && !mask_nmi_hook) || // nmi routine
|
||||
(bus.a == 16'h04C6 && (basic48_paged || !rom_m1_access)) || // tape save routine
|
||||
(bus.a == 16'h0562 && (basic48_paged || !rom_m1_access)) // tape load and verify routine
|
||||
) begin
|
||||
automap_next <= 1'b1;
|
||||
end
|
||||
else if (bus.a[15:8] == 8'h3D && (basic48_paged || !rom_m1_access)) begin // tr-dos mapping area
|
||||
automap_next <= 1'b1;
|
||||
automap <= 1'b1;
|
||||
end
|
||||
end
|
||||
else if (!bus.m1) begin
|
||||
automap <= automap_next;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
reg conmem, mapram;
|
||||
wire port_e3_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hE3;
|
||||
wire port_e7_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hE7;
|
||||
wire port_eb_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hEB;
|
||||
wire port_57_cs = en_zc && bus.ioreq && bus.a_reg[7:0] == 8'h57;
|
||||
wire port_77_cs = en_zc && bus.ioreq && bus.a_reg[7:0] == 8'h77;
|
||||
reg conmem;
|
||||
wire port_e3_cs = en && bus.ioreq && bus.a[7:0] == 8'hE3;
|
||||
wire port_e7_cs = en && bus.ioreq && bus.a[7:0] == 8'hE7;
|
||||
wire port_eb_cs = en && bus.ioreq && bus.a[7:0] == 8'hEB;
|
||||
wire port_57_cs = en_zc && bus.ioreq && bus.a[7:0] == 8'h57;
|
||||
wire port_77_cs = en_zc && bus.ioreq && bus.a[7:0] == 8'h77;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
page <= 0;
|
||||
@ -84,15 +93,15 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
else begin
|
||||
if (port_e3_cs && bus.wr) begin
|
||||
page <= bus.d_reg[3:0];
|
||||
mapram <= bus.d_reg[6] | mapram;
|
||||
conmem <= bus.d_reg[7];
|
||||
page <= bus.d[3:0];
|
||||
mapram <= bus.d[6] | mapram;
|
||||
conmem <= bus.d[7];
|
||||
end
|
||||
if (port_e7_cs && bus.wr) begin
|
||||
sd_cs <= bus.d_reg[0];
|
||||
sd_cs <= bus.d[0];
|
||||
end
|
||||
else if (port_77_cs && bus.wr) begin
|
||||
sd_cs <= bus.d_reg[1] | ~bus.d_reg[0];
|
||||
sd_cs <= bus.d[1] | ~bus.d[0];
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -112,7 +121,7 @@ end
|
||||
|
||||
reg [3:0] spi_cnt;
|
||||
wire spi_cnt_en = ~spi_cnt[3] | spi_cnt[2] | spi_cnt[1] | spi_cnt[0];
|
||||
assign cpuwait = ~spi_cnt[3];
|
||||
assign ext_wait_cycle2 = ~spi_cnt[3];
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
spi_cnt <= 0;
|
||||
@ -138,7 +147,7 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
spi_reg <= 0;
|
||||
else if ((port_eb_cs || port_57_cs) && bus.wr)
|
||||
spi_reg <= bus.d_reg;
|
||||
spi_reg <= bus.d;
|
||||
else if (spi_cnt[3] == 1'b0 && ck7)
|
||||
spi_reg[7:0] <= {spi_reg[6:0], sd_miso};
|
||||
end
|
||||
@ -151,12 +160,12 @@ end
|
||||
|
||||
assign map = automap | conmem;
|
||||
assign ram =
|
||||
(automap && bus.a[13]) ||
|
||||
(conmem && bus.a[13]) ||
|
||||
(automap && bus.a_raw[13]) ||
|
||||
(conmem && bus.a_raw[13]) ||
|
||||
(!conmem && automap && mapram);
|
||||
assign ramwr_mask =
|
||||
!bus.a[15] && !bus.a[14] &&
|
||||
(!bus.a[13] || page == 4'b0011) &&
|
||||
!bus.a_raw[15] && !bus.a_raw[14] &&
|
||||
(!bus.a_raw[13] || page == 4'b0011) &&
|
||||
!conmem && automap && mapram;
|
||||
|
||||
assign d_out_active = zc_rd | spi_rd;
|
||||
|
@ -2,6 +2,7 @@ import common::*;
|
||||
module magic(
|
||||
input rst_n,
|
||||
input clk28,
|
||||
input ck35,
|
||||
|
||||
cpu_bus bus,
|
||||
output [7:0] d_out,
|
||||
@ -13,10 +14,11 @@ module magic(
|
||||
|
||||
input magic_button,
|
||||
input pause_button,
|
||||
input div_automap,
|
||||
input div_paged,
|
||||
input basic48_paged,
|
||||
|
||||
output reg magic_mode,
|
||||
output magic_map,
|
||||
output reg magic_map,
|
||||
|
||||
output reg magic_reboot,
|
||||
output reg magic_beeper,
|
||||
@ -29,17 +31,19 @@ module magic(
|
||||
output reg ulaplus_en,
|
||||
output reg ay_en,
|
||||
output reg covox_en,
|
||||
output reg soundrive_en
|
||||
output reg soundrive_en,
|
||||
output reg sd_indication_en
|
||||
);
|
||||
|
||||
localparam magic_on_start = 1'b1;
|
||||
|
||||
reg magic_unmap_next;
|
||||
reg magic_map_next;
|
||||
reg magic_map0;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
n_nmi <= 1'b1;
|
||||
magic_mode <= 1'b1;
|
||||
magic_map0 <= 1'b1;
|
||||
magic_mode <= magic_on_start;
|
||||
magic_map <= magic_on_start;
|
||||
magic_map_next <= 0;
|
||||
magic_unmap_next <= 0;
|
||||
end
|
||||
@ -50,38 +54,37 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
magic_mode <= 1'b1;
|
||||
end
|
||||
|
||||
if (magic_map0 && bus.memreq && bus.rd && bus.a_reg == 16'hf000 && !magic_map_next) begin
|
||||
if (magic_map && bus.memreq && bus.rd && bus.a == 16'hf000 && !magic_map_next) begin
|
||||
magic_unmap_next <= 1'b1;
|
||||
magic_mode <= 1'b0;
|
||||
end
|
||||
else if (magic_map0 && bus.memreq && bus.rd && bus.a_reg == 16'hf008) begin
|
||||
else if (magic_map && bus.memreq && bus.rd && bus.a == 16'hf008) begin
|
||||
magic_unmap_next <= 1'b1;
|
||||
magic_map_next <= 1'b1;
|
||||
end
|
||||
else if (magic_unmap_next && !bus.memreq) begin
|
||||
magic_map0 <= 1'b0;
|
||||
magic_map <= 1'b0;
|
||||
magic_unmap_next <= 1'b0;
|
||||
end
|
||||
else if (magic_mode && bus.m1 && bus.memreq && (bus.a_reg == 16'h0066 || magic_map_next)) begin
|
||||
else if (magic_mode && bus.m1 && bus.memreq_rise && (bus.a == 16'h0066 || magic_map_next)) begin
|
||||
n_nmi <= 1'b1;
|
||||
magic_map0 <= 1'b1;
|
||||
magic_map <= 1'b1;
|
||||
magic_map_next <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// this signal is critical for timings, so we're arming it as soon as possible
|
||||
assign magic_map = magic_map0 || (magic_mode && bus.m1 && bus.memreq && (bus.a_reg == 16'h0066 || magic_map_next) && !magic_unmap_next);
|
||||
|
||||
|
||||
/* MAGIC CONFIG */
|
||||
wire config_cs = magic_map && bus.ioreq && bus.a_reg[7:0] == 8'hFF;
|
||||
turbo_t turbo0;
|
||||
reg autoturbo_en;
|
||||
wire config_cs = magic_map && bus.ioreq && bus.a[7:0] == 8'hFF;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
magic_reboot <= 0;
|
||||
magic_beeper <= 0;
|
||||
machine <= MACHINE_PENT;
|
||||
turbo <= TURBO_NONE;
|
||||
turbo0 <= TURBO_NONE;
|
||||
panning <= PANNING_ABC;
|
||||
joy_sinclair <= 0;
|
||||
divmmc_en <= 0;
|
||||
@ -90,27 +93,64 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
ay_en <= 1'b1;
|
||||
covox_en <= 1'b1;
|
||||
soundrive_en <= 1'b1;
|
||||
sd_indication_en <= 1'b1;
|
||||
autoturbo_en <= 1'b0;
|
||||
end
|
||||
else if (config_cs && bus.wr) case (bus.a_reg[15:8])
|
||||
8'h01: {magic_reboot, magic_beeper} <= bus.d_reg[1:0];
|
||||
8'h02: machine <= machine_t'(bus.d_reg[2:0]);
|
||||
8'h03: turbo <= turbo_t'(bus.d_reg[2:0]);
|
||||
8'h04: panning <= panning_t'(bus.d_reg[1:0]);
|
||||
8'h07: joy_sinclair <= bus.d_reg[0];
|
||||
8'h08: ay_en <= bus.d_reg[0];
|
||||
8'h09: {zc_en, divmmc_en} <= bus.d_reg[1:0];
|
||||
8'h0a: ulaplus_en <= bus.d_reg[0];
|
||||
8'h0b: {soundrive_en, covox_en} <= bus.d_reg[1:0];
|
||||
else if (config_cs && bus.wr) case (bus.a[15:8])
|
||||
8'h01: {magic_reboot, magic_beeper} <= bus.d[1:0];
|
||||
8'h02: machine <= machine_t'(bus.d[2:0]);
|
||||
8'h03: turbo0 <= turbo_t'(bus.d[2:0]);
|
||||
8'h04: panning <= panning_t'(bus.d[1:0]);
|
||||
8'h07: joy_sinclair <= bus.d[0];
|
||||
8'h08: ay_en <= bus.d[0];
|
||||
8'h09: {zc_en, divmmc_en} <= bus.d[1:0];
|
||||
8'h0A: ulaplus_en <= bus.d[0];
|
||||
8'h0B: {soundrive_en, covox_en} <= bus.d[1:0];
|
||||
8'h0C: sd_indication_en <= bus.d[0];
|
||||
8'h0E: autoturbo_en <= bus.d[0];
|
||||
endcase
|
||||
end
|
||||
|
||||
reg config_rd;
|
||||
wire [7:0] config_data = {4'b0000, div_automap, 1'b1, pause_button, magic_button};
|
||||
wire [7:0] config_data = {4'b0000, div_paged, 1'b1, pause_button, magic_button};
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
config_rd <= 0;
|
||||
else
|
||||
config_rd <= config_cs && bus.rd && bus.a_reg[15:8] == 8'h00;
|
||||
config_rd <= config_cs && bus.rd && bus.a[15:8] == 8'h00;
|
||||
end
|
||||
|
||||
|
||||
/* AUTOMATIC TURBO */
|
||||
reg [11:0] portfe_noturbo; // 1170uS
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
portfe_noturbo <= 0;
|
||||
else if (bus.ioreq && !bus.a[0])
|
||||
portfe_noturbo <= 1'b1;
|
||||
else if (|portfe_noturbo && ck35)
|
||||
portfe_noturbo <= portfe_noturbo + 1'b1;
|
||||
end
|
||||
reg basic48_ramclear_turbo;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
basic48_ramclear_turbo <= 0;
|
||||
else if (basic48_paged && bus.m1 && bus.a[15:6] == 10'b0001000111)
|
||||
basic48_ramclear_turbo <= 1'b1;
|
||||
else if (!basic48_paged || (bus.m1 && bus.a[15:6] != 10'b0001000111))
|
||||
basic48_ramclear_turbo <= 0;
|
||||
end
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
turbo <= TURBO_NONE;
|
||||
else if (autoturbo_en && div_paged && !magic_map)
|
||||
turbo <= TURBO_14;
|
||||
else if (autoturbo_en && |portfe_noturbo)
|
||||
turbo <= TURBO_NONE;
|
||||
else if (autoturbo_en && basic48_ramclear_turbo)
|
||||
turbo <= TURBO_14;
|
||||
else
|
||||
turbo <= turbo0;
|
||||
end
|
||||
|
||||
|
||||
|
207
fpga/rtl/mem.sv
Normal file
207
fpga/rtl/mem.sv
Normal file
@ -0,0 +1,207 @@
|
||||
import common::*;
|
||||
module mem(
|
||||
input rst_n,
|
||||
input clk28,
|
||||
cpu_bus bus,
|
||||
output reg [18:0] va,
|
||||
inout [7:0] vd,
|
||||
output reg n_vrd,
|
||||
output reg n_vwr,
|
||||
|
||||
output bus_valid,
|
||||
output cpuwait,
|
||||
output basic48_paged,
|
||||
|
||||
input machine_t machine,
|
||||
input turbo_t turbo,
|
||||
input cpu_contention,
|
||||
input magic_map,
|
||||
input [2:0] ram_page128,
|
||||
input rom_page128,
|
||||
input [2:0] port_1ffd,
|
||||
input [4:0] port_dffd,
|
||||
input [2:0] ram_pageext,
|
||||
input div_ram,
|
||||
input div_map,
|
||||
input div_ramwr_mask,
|
||||
input [3:0] div_page,
|
||||
|
||||
input snow,
|
||||
input video_page,
|
||||
input video_read_req,
|
||||
input [14:0] video_read_addr,
|
||||
output video_read_req_ack,
|
||||
output video_data_valid,
|
||||
|
||||
input [16:0] rom2ram_ram_address,
|
||||
input rom2ram_ram_wren,
|
||||
input [7:0] rom2ram_dataout,
|
||||
|
||||
input magic_dout_active,
|
||||
input [7:0] magic_dout,
|
||||
input up_dout_active,
|
||||
input [7:0] up_dout,
|
||||
input div_dout_active,
|
||||
input [7:0] div_dout,
|
||||
input turbosound_dout_active,
|
||||
input [7:0] turbosound_dout,
|
||||
input ports_dout_active,
|
||||
input [7:0] ports_dout
|
||||
);
|
||||
|
||||
|
||||
/* VA[18:13] map
|
||||
* 00xxxx 112Kb of roms
|
||||
* 00111x 16Kb of magic ram
|
||||
* 01xxxx 128Kb of divmmc memory
|
||||
* 10xxxx 128Kb of extended ram (via port dffd)
|
||||
* 11xxxx 128Kb of main ram
|
||||
*/
|
||||
|
||||
reg romreq, ramreq, ramreq_wr;
|
||||
reg [18:13] va_18_13;
|
||||
wire [15:0] a = bus.a_raw[15:0];
|
||||
always @* begin
|
||||
romreq = a[15:14] == 2'b00 &&
|
||||
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd[4] && !port_1ffd[0]));
|
||||
ramreq = !romreq;
|
||||
ramreq_wr = ramreq && div_ramwr_mask == 0;
|
||||
|
||||
if (romreq) va_18_13 =
|
||||
(magic_map) ? {5'd2, 1'b0} :
|
||||
(div_map) ? {5'd2, 1'b1} :
|
||||
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rom_page128 == 1'b0) ? {5'd4, a[13]} :
|
||||
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rom_page128 == 1'b1) ? {5'd5, a[13]} :
|
||||
(machine == MACHINE_S3 && port_1ffd[2] == 1'b1 && rom_page128 == 1'b0) ? {5'd6, a[13]} :
|
||||
(machine == MACHINE_S48) ? {5'd3, a[13]} :
|
||||
(rom_page128 == 1'b1) ? {5'd1, a[13]} :
|
||||
{5'd0, a[13]} ;
|
||||
else va_18_13 =
|
||||
(magic_map && a[15:14] == 2'b11) ? {2'b00, 3'b111, a[13]} :
|
||||
(magic_map) ? {3'b111, video_page, a[14:13]} :
|
||||
(div_map && a[15:13] == 3'b001) ? {2'b01, div_page} :
|
||||
(div_map && a[15:14] == 2'b00) ? {2'b01, 4'b0011} :
|
||||
(port_dffd[3] & a[15]) ? {2'b11, a[14], a[15], a[14], a[13]} :
|
||||
(port_dffd[3] & a[14]) ? {1'b1, ~ram_pageext[0], ram_page128, a[13]} :
|
||||
(port_1ffd[2] == 1'b0 && port_1ffd[0] == 1'b1) ? {2'b11, port_1ffd[1], a[15], a[14], a[13]} :
|
||||
(port_1ffd == 3'b101) ? {2'b11, ~(a[15] & a[14]), a[15], a[14], a[13]} :
|
||||
(port_1ffd == 3'b111) ? {2'b11, ~(a[15] & a[14]), (a[15] | a[14]), a[14], a[13]} :
|
||||
(a[15:14] == 2'b11) ? {1'b1, ~ram_pageext[0], ram_page128, a[13]} :
|
||||
{2'b11, a[14], a[15], a[14], a[13]} ;
|
||||
end
|
||||
|
||||
assign basic48_paged = (va_18_13[18:14] == 5'd1) ||
|
||||
(va_18_13[18:14] == 5'd3) ;
|
||||
|
||||
assign vd[7:0] =
|
||||
~n_vrd ? {8{1'bz}} :
|
||||
bus.wr ? {8{1'bz}} :
|
||||
rom2ram_ram_wren ? rom2ram_dataout :
|
||||
magic_dout_active ? magic_dout :
|
||||
up_dout_active ? up_dout :
|
||||
div_dout_active ? div_dout :
|
||||
turbosound_dout_active ? turbosound_dout :
|
||||
ports_dout_active ? ports_dout :
|
||||
(bus.m1 && bus.iorq) ? 8'hFF :
|
||||
bus.rd ? 8'hFF :
|
||||
{8{1'bz}} ;
|
||||
|
||||
localparam BUS_VALID_LATENCY = 2'd1;
|
||||
reg [1:0] bus_valid_step;
|
||||
localparam LATENCY = 2'd2;
|
||||
reg [1:0] step;
|
||||
localparam REQ_NONE = 3'd0;
|
||||
localparam REQ_CPU_RD = 3'd1;
|
||||
localparam REQ_CPU_WR = 3'd2;
|
||||
localparam REQ_VIDEO_RD = 3'd3;
|
||||
localparam REQ_ROM2RAM_WR = 3'd4;
|
||||
reg [2:0] current_req;
|
||||
reg cpuwait_reg;
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
va <= {va_18_13, {13{1'bz}}};
|
||||
n_vrd <= 1'b1;
|
||||
n_vwr <= 1'b1;
|
||||
cpuwait_reg <= 0;
|
||||
bus_valid_step <= 0;
|
||||
step <= 0;
|
||||
current_req <= REQ_NONE;
|
||||
end
|
||||
else begin
|
||||
if (step)
|
||||
step <= step - 1'd1;
|
||||
if (bus_valid_step)
|
||||
bus_valid_step <= bus_valid_step - 1'd1;
|
||||
if (!(bus.mreq && bus.rd))
|
||||
cpuwait_reg <= 0;
|
||||
|
||||
if (rom2ram_ram_wren) begin
|
||||
if (current_req != REQ_ROM2RAM_WR)
|
||||
step <= LATENCY;
|
||||
va <= {2'b00, rom2ram_ram_address};
|
||||
n_vrd <= 1'b1;
|
||||
n_vwr <= (current_req == REQ_ROM2RAM_WR && step == 0)? 1'b1 : 1'b0;
|
||||
bus_valid_step <= BUS_VALID_LATENCY;
|
||||
current_req <= REQ_ROM2RAM_WR;
|
||||
end
|
||||
else if (turbo == TURBO_14 && current_req == REQ_VIDEO_RD && step) begin
|
||||
// complete current request
|
||||
bus_valid_step <= BUS_VALID_LATENCY;
|
||||
end
|
||||
else if (bus.mreq && bus.wr && ramreq_wr) begin
|
||||
if (current_req != REQ_CPU_WR)
|
||||
step <= LATENCY;
|
||||
va <= {va_18_13, {13{1'bz}}};
|
||||
n_vrd <= 1'b1;
|
||||
n_vwr <= (current_req == REQ_CPU_WR && step == 0)? 1'b1 : 1'b0;
|
||||
current_req <= REQ_CPU_WR;
|
||||
end
|
||||
else if (bus.mreq && bus.rd) begin
|
||||
if (current_req != REQ_CPU_RD) begin
|
||||
step <= LATENCY;
|
||||
end
|
||||
else if (va[18:13] != va_18_13) begin
|
||||
cpuwait_reg <= 1'b1;
|
||||
step <= LATENCY;
|
||||
end
|
||||
else if (!step) begin
|
||||
cpuwait_reg <= 1'b0;
|
||||
end
|
||||
va <= {va_18_13, {13{1'bz}}};
|
||||
n_vrd <= 1'b0;
|
||||
n_vwr <= 1'b1;
|
||||
current_req <= REQ_CPU_RD;
|
||||
end
|
||||
else if ((bus.mreq || bus.iorq) && !bus.rfsh && !cpu_contention) begin
|
||||
va <= {va_18_13, {13{1'bz}}};
|
||||
n_vrd <= 1'b1;
|
||||
n_vwr <= 1'b1;
|
||||
current_req <= REQ_NONE;
|
||||
end
|
||||
else if (video_read_req) begin
|
||||
if (current_req != REQ_VIDEO_RD || !step)
|
||||
step <= LATENCY;
|
||||
va <= snow? {3'b111, video_page, video_read_addr[14:7], {7{1'bz}}} :
|
||||
{3'b111, video_page, video_read_addr} ;
|
||||
n_vrd <= 1'b0;
|
||||
n_vwr <= 1'b1;
|
||||
bus_valid_step <= BUS_VALID_LATENCY;
|
||||
current_req <= REQ_VIDEO_RD;
|
||||
end
|
||||
else begin
|
||||
va <= {va_18_13, {13{1'bz}}};
|
||||
n_vrd <= 1'b1;
|
||||
n_vwr <= 1'b1;
|
||||
current_req <= REQ_NONE;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign cpuwait = cpuwait_reg || (bus.mreq && bus.rd && current_req == REQ_CPU_RD && va[18:13] != va_18_13);
|
||||
assign bus_valid = bus_valid_step == 0;
|
||||
assign video_data_valid = current_req == REQ_VIDEO_RD && step == 0;
|
||||
assign video_read_req_ack = current_req == REQ_VIDEO_RD && step == 1'd1 && (!((bus.mreq || bus.iorq) && !bus.rfsh && !cpu_contention) || turbo == TURBO_14);
|
||||
|
||||
|
||||
endmodule
|
@ -1,107 +0,0 @@
|
||||
import common::*;
|
||||
|
||||
module memcontrol(
|
||||
input clk28,
|
||||
cpu_bus bus,
|
||||
output [18:0] va,
|
||||
inout [7:0] vd,
|
||||
output n_vrd,
|
||||
output n_vwr,
|
||||
|
||||
input machine_t machine,
|
||||
input screenpage,
|
||||
input screen_fetch,
|
||||
input screen_fetch_up,
|
||||
input snow,
|
||||
input [14:0] screen_addr,
|
||||
input magic_map,
|
||||
input [2:0] rampage128,
|
||||
input rompage128,
|
||||
input [2:0] port_1ffd,
|
||||
input [4:0] port_dffd,
|
||||
input [2:0] rampage_ext,
|
||||
input divmmc_en,
|
||||
input div_ram,
|
||||
input div_map,
|
||||
input div_ramwr_mask,
|
||||
input [3:0] div_page,
|
||||
|
||||
input [16:0] rom2ram_ram_address,
|
||||
input rom2ram_ram_wren,
|
||||
input [7:0] rom2ram_dataout,
|
||||
input magic_dout_active,
|
||||
input [7:0] magic_dout,
|
||||
input up_dout_active,
|
||||
input [7:0] up_dout,
|
||||
input div_dout_active,
|
||||
input [7:0] div_dout,
|
||||
input turbosound_dout_active,
|
||||
input [7:0] turbosound_dout,
|
||||
input ports_dout_active,
|
||||
input [7:0] ports_dout
|
||||
);
|
||||
|
||||
|
||||
/* VA[18:13] map
|
||||
* 00xxxx 112Kb of roms
|
||||
* 00111x 16Kb of magic ram
|
||||
* 01xxxx 128Kb of divmmc memory
|
||||
* 10xxxx 128Kb of extended ram (via port dffd)
|
||||
* 11xxxx 128Kb of main ram
|
||||
*/
|
||||
|
||||
reg romreq, ramreq, ramreq_wr;
|
||||
reg [18:13] va_18_13;
|
||||
always @(negedge clk28) begin
|
||||
romreq = bus.mreq && bus.a[15:14] == 2'b00 &&
|
||||
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd[4] && !port_1ffd[0]));
|
||||
ramreq = bus.mreq && !romreq;
|
||||
ramreq_wr = ramreq && bus.wr && div_ramwr_mask == 0;
|
||||
|
||||
if (romreq) va_18_13 = {2'd0,
|
||||
magic_map? {3'd2, 1'b0} :
|
||||
div_map? {3'd2, 1'b1} :
|
||||
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b0)? {3'd4, bus.a[13]} :
|
||||
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b1)? {3'd5, bus.a[13]} :
|
||||
(machine == MACHINE_S3 && port_1ffd[2] == 1'b1 && rompage128 == 1'b0)? {3'd6, bus.a[13]} :
|
||||
(machine == MACHINE_S48)? {3'd3, bus.a[13]} :
|
||||
(rompage128 == 1'b1)? {3'd1, bus.a[13]} :
|
||||
{3'd0, bus.a[13]} };
|
||||
else va_18_13 =
|
||||
magic_map & bus.a[15] & bus.a[14]? {2'b00, 3'b111, bus.a[13]} :
|
||||
magic_map? {3'b111, screenpage, bus.a[14:13]} :
|
||||
div_map & ~bus.a[15] & ~bus.a[14] & bus.a[13]? {2'b01, div_page} :
|
||||
div_map & ~bus.a[15] & ~bus.a[14]? {2'b01, 4'b0011} :
|
||||
port_dffd[3] & bus.a[15]? {2'b11, bus.a[14], bus.a[15], bus.a[14], bus.a[13]} :
|
||||
port_dffd[3] & bus.a[14]? {1'b1, ~rampage_ext[0], rampage128, bus.a[13]} :
|
||||
(port_1ffd[2] == 1'b0 && port_1ffd[0] == 1'b1)? {2'b11, port_1ffd[1], bus.a[15], bus.a[14], bus.a[13]} :
|
||||
(port_1ffd == 3'b101)? {2'b11, ~(bus.a[15] & bus.a[14]), bus.a[15], bus.a[14], bus.a[13]} :
|
||||
(port_1ffd == 3'b111)? {2'b11, ~(bus.a[15] & bus.a[14]), (bus.a[15] | bus.a[14]), bus.a[14], bus.a[13]} :
|
||||
bus.a[15] & bus.a[14]? {1'b1, ~rampage_ext[0], rampage128, bus.a[13]} :
|
||||
{2'b11, bus.a[14], bus.a[15], bus.a[14], bus.a[13]} ;
|
||||
end
|
||||
|
||||
assign n_vrd = (((bus.mreq && bus.rd) || screen_fetch) && !rom2ram_ram_wren)? 1'b0 : 1'b1;
|
||||
assign n_vwr = ((ramreq_wr && bus.wr && !screen_fetch) || rom2ram_ram_wren)? 1'b0 : 1'b1;
|
||||
|
||||
assign va[18:0] =
|
||||
rom2ram_ram_wren? {2'b00, rom2ram_ram_address} :
|
||||
screen_fetch && snow? {3'b111, screenpage, screen_addr[14:8], {8{1'bz}}} :
|
||||
screen_fetch? {3'b111, screenpage, screen_addr} :
|
||||
{va_18_13, {13{1'bz}}};
|
||||
|
||||
assign vd[7:0] =
|
||||
~n_vrd? {8{1'bz}} :
|
||||
bus.wr? {8{1'bz}} :
|
||||
rom2ram_ram_wren? rom2ram_dataout :
|
||||
magic_dout_active? magic_dout :
|
||||
up_dout_active? up_dout :
|
||||
div_dout_active? div_dout :
|
||||
turbosound_dout_active? turbosound_dout :
|
||||
ports_dout_active? ports_dout :
|
||||
(bus.m1 && bus.iorq)? 8'hFF :
|
||||
bus.rd? 8'hFF :
|
||||
{8{1'bz}};
|
||||
|
||||
|
||||
endmodule
|
@ -30,45 +30,32 @@ assign dac_l = dac_l_cnt[WIDTH];
|
||||
assign dac_r = dac_r_cnt[WIDTH];
|
||||
|
||||
wire [WIDTH-1:0] dac_next_l =
|
||||
{sd_l0, 1'b0} +
|
||||
{sd_l1, 1'b0} +
|
||||
{ay_a0, 1'b0} +
|
||||
{ay_a1, 1'b0} +
|
||||
(ay_acb? ay_c0 : ay_b0) +
|
||||
ay_b1 +
|
||||
{beeper, tape_out, tape_in, 7'b000000}
|
||||
{ay_a1, 1'b0} +
|
||||
{1'b0, ay_b1} +
|
||||
{sd_l0, 1'b0} +
|
||||
{sd_l1, 1'b0}
|
||||
;
|
||||
wire [WIDTH-1:0] dac_next_r =
|
||||
{sd_r0, 1'b0} +
|
||||
{sd_r1, 1'b0} +
|
||||
(ay_acb? {ay_b0, 1'b0} : {ay_c0, 1'b0}) +
|
||||
{ay_c1, 1'b0} +
|
||||
(ay_acb? ay_c0 : ay_b0) +
|
||||
ay_b1 +
|
||||
{beeper, tape_out, tape_in, 7'b000000}
|
||||
;
|
||||
wire [WIDTH-1:0] dac_next_mono =
|
||||
sd_r0 +
|
||||
sd_r1 +
|
||||
sd_l0 +
|
||||
sd_l1 +
|
||||
ay_a0 +
|
||||
ay_a1 +
|
||||
ay_b0 +
|
||||
ay_b1 +
|
||||
ay_c0 +
|
||||
ay_c1 +
|
||||
{beeper, tape_out, tape_in, 7'b000000}
|
||||
{1'b0, ay_b1} +
|
||||
{ay_c1, 1'b0} +
|
||||
{sd_r0, 1'b0} +
|
||||
{sd_r1, 1'b0}
|
||||
;
|
||||
|
||||
wire [WIDTH-1:0] dac_next_lr = {beeper, tape_out, tape_in, 7'd0};
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
dac_l_cnt <= 0;
|
||||
dac_r_cnt <= 0;
|
||||
end
|
||||
else begin
|
||||
dac_l_cnt <= dac_l_cnt[WIDTH-1:0] + (mono? dac_next_mono : dac_next_l);
|
||||
dac_r_cnt <= dac_r_cnt[WIDTH-1:0] + (mono? dac_next_mono : dac_next_r);
|
||||
dac_l_cnt <= dac_l_cnt[WIDTH-1:0] + dac_next_lr + dac_next_l + (mono? dac_next_r : {WIDTH{1'b0}});
|
||||
dac_r_cnt <= dac_r_cnt[WIDTH-1:0] + dac_next_lr + dac_next_r + (mono? dac_next_l : {WIDTH{1'b0}});
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -20,10 +20,10 @@ module ports(
|
||||
output reg tape_out,
|
||||
output reg beeper,
|
||||
output reg [2:0] border,
|
||||
output reg screenpage,
|
||||
output reg rompage128,
|
||||
output reg [2:0] rampage128,
|
||||
output reg [2:0] rampage_ext,
|
||||
output reg video_page,
|
||||
output reg rom_page128,
|
||||
output reg [2:0] ram_page128,
|
||||
output reg [2:0] ram_pageext,
|
||||
output reg [2:0] port_1ffd,
|
||||
output reg [4:0] port_dffd
|
||||
|
||||
@ -37,12 +37,12 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
port_ff_rd <= 0;
|
||||
else
|
||||
port_ff_rd <= bus.rd && bus.ioreq && !magic_map && port_ff_active &&
|
||||
(machine != MACHINE_S3) && (machine != MACHINE_PENT || bus.a_reg[7:0] == 8'hFF);
|
||||
(machine != MACHINE_S3) && (machine != MACHINE_PENT || bus.a[7:0] == 8'hFF);
|
||||
end
|
||||
|
||||
|
||||
/* PORT #FE */
|
||||
wire port_fe_cs = bus.ioreq && bus.a_reg[0] == 0;
|
||||
wire port_fe_cs = bus.ioreq && bus.a[0] == 0;
|
||||
reg port_fe_rd;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
@ -60,9 +60,9 @@ always @(negedge clk28 or negedge rst_n) begin
|
||||
border <= 0;
|
||||
end
|
||||
else if (port_fe_cs && bus.wr) begin
|
||||
beeper <= bus.d_reg[4];
|
||||
tape_out <= bus.d_reg[3];
|
||||
border <= bus.d_reg[2:0];
|
||||
beeper <= bus.d[4];
|
||||
tape_out <= bus.d[3];
|
||||
border <= bus.d[2:0];
|
||||
end
|
||||
end
|
||||
|
||||
@ -72,8 +72,8 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
else if (en_sinclair) begin
|
||||
kd0 <= kd
|
||||
& (bus.a_reg[12] == 0? {~kempston_data[1], ~kempston_data[0], ~kempston_data[2], ~kempston_data[3], ~kempston_data[4]} : 5'b11111) // 6-0 keys
|
||||
& (bus.a_reg[15] == 0? {1'b1, ~kempston_data[6], ~kempston_data[5], 2'b11} : 5'b11111 ) ; // b-space keys
|
||||
& (bus.a[12] == 0? {~kempston_data[1], ~kempston_data[0], ~kempston_data[2], ~kempston_data[3], ~kempston_data[4]} : 5'b11111) // 6-0 keys
|
||||
& (bus.a[15] == 0? {1'b1, ~kempston_data[6], ~kempston_data[5], 2'b11} : 5'b11111 ) ; // b-space keys
|
||||
end
|
||||
else begin
|
||||
kd0 <= kd;
|
||||
@ -83,49 +83,49 @@ end
|
||||
|
||||
/* PORT #7FFD */
|
||||
reg lock_7ffd;
|
||||
wire port_7ffd_cs = bus.ioreq && bus.a_reg[1] == 0 && bus.a_reg[15] == 0 &&
|
||||
(bus.a_reg[14] == 1'b1 || (!magic_map && machine != MACHINE_S3)) &&
|
||||
wire port_7ffd_cs = bus.ioreq && bus.a[1] == 0 && bus.a[15] == 0 &&
|
||||
(bus.a[14] == 1'b1 || (!magic_map && machine != MACHINE_S3)) &&
|
||||
(machine != MACHINE_S48 || magic_map) &&
|
||||
(lock_7ffd == 0 || port_dffd[4] == 1'b1);
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
rampage128 <= 0;
|
||||
screenpage <= 0;
|
||||
rompage128 <= 0;
|
||||
ram_page128 <= 0;
|
||||
video_page <= 0;
|
||||
rom_page128 <= 0;
|
||||
lock_7ffd <= 0;
|
||||
end
|
||||
else if (port_7ffd_cs && bus.wr) begin
|
||||
rampage128 <= bus.d_reg[2:0];
|
||||
screenpage <= bus.d_reg[3];
|
||||
rompage128 <= bus.d_reg[4];
|
||||
lock_7ffd <= bus.d_reg[5];
|
||||
ram_page128 <= bus.d[2:0];
|
||||
video_page <= bus.d[3];
|
||||
rom_page128 <= bus.d[4];
|
||||
lock_7ffd <= bus.d[5];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/* PORT #DFFD */
|
||||
wire port_dffd_cs = bus.ioreq && bus.a_reg == 16'hDFFD && (machine == MACHINE_PENT || magic_map);
|
||||
wire port_dffd_cs = bus.ioreq && bus.a == 16'hDFFD && (machine == MACHINE_PENT || magic_map);
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
rampage_ext <= 0;
|
||||
ram_pageext <= 0;
|
||||
port_dffd <= 0;
|
||||
end
|
||||
else if (port_dffd_cs && bus.wr) begin
|
||||
rampage_ext <= bus.d_reg[2:0];
|
||||
port_dffd <= bus.d_reg[4:0];
|
||||
ram_pageext <= bus.d[2:0];
|
||||
port_dffd <= bus.d[4:0];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/* PORT #1FFD */
|
||||
wire port_1ffd_cs = bus.ioreq && bus.a_reg[15:12] == 4'b0001 && !bus.a_reg[1] &&
|
||||
wire port_1ffd_cs = bus.ioreq && bus.a[15:12] == 4'b0001 && !bus.a[1] &&
|
||||
(machine == MACHINE_S3 || magic_map);
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
port_1ffd <= 0;
|
||||
end
|
||||
else if (port_1ffd_cs && bus.wr) begin
|
||||
port_1ffd <= bus.d_reg[2:0];
|
||||
port_1ffd <= bus.d[2:0];
|
||||
end
|
||||
end
|
||||
|
||||
@ -136,7 +136,7 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
kempston_rd <= 0;
|
||||
else
|
||||
kempston_rd <= en_kempston && bus.ioreq && bus.rd && bus.a_reg[5:0] == 6'h1F;
|
||||
kempston_rd <= en_kempston && bus.ioreq && bus.rd && bus.a[5:0] == 6'h1F;
|
||||
end
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ module ps2_rxtx#(
|
||||
|
||||
|
||||
localparam CLKWAIT_US = 1;
|
||||
localparam TOUT_US = 150;
|
||||
localparam TOUT_US = 200;
|
||||
localparam CLKWAIT_TICKS = int'(CLKWAIT_US*CLK_FREQ/1e6) + 1'b1;
|
||||
localparam TOUT_TICKS = int'(TOUT_US*CLK_FREQ/1e6) + 1'b1;
|
||||
reg [$clog2(TOUT_TICKS)-1:0] timer;
|
||||
|
@ -14,12 +14,12 @@ module soundrive(
|
||||
output reg [7:0] ch_r1
|
||||
);
|
||||
|
||||
wire covox_cs = en_covox && bus.ioreq && bus.a_reg[7:0] == 8'hFB;
|
||||
wire specdrum_cs = en_specdrum && bus.ioreq && bus.a_reg[7:0] == 8'hDF;
|
||||
wire soundrive_a_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h0F;
|
||||
wire soundrive_b_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h1F;
|
||||
wire soundrive_c_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h4F;
|
||||
wire soundrive_d_cs = en_soundrive && bus.ioreq && bus.a_reg[7:0] == 8'h5F;
|
||||
wire covox_cs = en_covox && bus.ioreq && bus.a[7:0] == 8'hFB;
|
||||
wire specdrum_cs = en_specdrum && bus.ioreq && bus.a[7:0] == 8'hDF;
|
||||
wire soundrive_a_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h0F;
|
||||
wire soundrive_b_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h1F;
|
||||
wire soundrive_c_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h4F;
|
||||
wire soundrive_d_cs = en_soundrive && bus.ioreq && bus.a[7:0] == 8'h5F;
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
@ -30,13 +30,13 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
else begin
|
||||
if ((covox_cs || specdrum_cs || soundrive_a_cs) && bus.wr)
|
||||
ch_l0 <= bus.d_reg;
|
||||
ch_l0 <= bus.d;
|
||||
if ((covox_cs || specdrum_cs || soundrive_b_cs) && bus.wr)
|
||||
ch_l1 <= bus.d_reg;
|
||||
ch_l1 <= bus.d;
|
||||
if ((covox_cs || specdrum_cs || soundrive_c_cs) && bus.wr)
|
||||
ch_r0 <= bus.d_reg;
|
||||
ch_r0 <= bus.d;
|
||||
if ((covox_cs || specdrum_cs || soundrive_d_cs) && bus.wr)
|
||||
ch_r1 <= bus.d_reg;
|
||||
ch_r1 <= bus.d;
|
||||
end
|
||||
end
|
||||
|
||||
|
169
fpga/rtl/top.sv
169
fpga/rtl/top.sv
@ -58,36 +58,18 @@ wire ps2_key_reset, ps2_key_pause;
|
||||
wire [2:0] border;
|
||||
wire magic_reboot, magic_beeper;
|
||||
wire up_active;
|
||||
wire clkwait;
|
||||
wire [2:0] rampage128;
|
||||
wire [2:0] ram_page128;
|
||||
wire init_done;
|
||||
wire screen_fetch, screen_fetch_next;
|
||||
wire mem_bus_valid;
|
||||
wire mem_wait;
|
||||
wire basic48_paged;
|
||||
wire sd_indication;
|
||||
|
||||
|
||||
/* CPU BUS */
|
||||
cpu_bus bus();
|
||||
reg bus_memreq, bus_ioreq;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
bus_ioreq <= 0;
|
||||
bus_memreq <= 0;
|
||||
end
|
||||
else if (!screen_fetch && !screen_fetch_next) begin
|
||||
bus.a_reg <= {a[15:13], va[12:0]};
|
||||
bus.d_reg <= vd;
|
||||
bus_ioreq <= n_iorq == 1'b0 && n_m1 == 1'b1;
|
||||
bus_memreq <= n_mreq == 1'b0 && n_rfsh == 1'b1;
|
||||
end
|
||||
else begin
|
||||
if (n_iorq)
|
||||
bus_ioreq <= 0;
|
||||
if (n_mreq)
|
||||
bus_memreq <= 0;
|
||||
end
|
||||
end
|
||||
always @(posedge clk168) begin
|
||||
bus.a <= {a[15:13], va[12:0]};
|
||||
bus.d <= vd;
|
||||
always @(negedge clk28) begin
|
||||
bus.a_raw <= {a[15:13], va[12:0]};
|
||||
bus.iorq <= ~n_iorq;
|
||||
bus.mreq <= ~n_mreq;
|
||||
bus.m1 <= ~n_m1;
|
||||
@ -95,8 +77,13 @@ always @(posedge clk168) begin
|
||||
bus.rd <= ~n_rd;
|
||||
bus.wr <= ~n_wr;
|
||||
end
|
||||
assign bus.ioreq = bus_ioreq & bus.iorq;
|
||||
assign bus.memreq = bus_memreq & bus.mreq;
|
||||
always @(posedge clk28) begin
|
||||
bus.a <= mem_bus_valid? {a[15:13], va[12:0]} : bus.a;
|
||||
bus.d <= mem_bus_valid? vd : bus.d;
|
||||
bus.ioreq <= (mem_bus_valid | bus.ioreq) & ~n_iorq & n_m1;
|
||||
bus.memreq <= (mem_bus_valid | bus.memreq) & ~n_mreq & n_rfsh;
|
||||
bus.memreq_rise <= mem_bus_valid & ~bus.memreq & ~n_mreq & n_rfsh;
|
||||
end
|
||||
|
||||
|
||||
/* RESET */
|
||||
@ -106,25 +93,23 @@ always @(posedge clk28) begin
|
||||
end
|
||||
|
||||
|
||||
/* SCREEN CONTROLLER */
|
||||
wire blink;
|
||||
wire [2:0] screen_border = {border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0]};
|
||||
/* VIDEO CONTROLLER */
|
||||
wire [5:0] r, g, b;
|
||||
wire hsync, vsync, csync0;
|
||||
wire screen_contention, port_ff_active;
|
||||
wire [14:0] screen_addr;
|
||||
wire video_contention, port_ff_active;
|
||||
wire video_read_req, video_read_req_ack, video_read_data_valid;
|
||||
wire [14:0] video_read_addr;
|
||||
wire [5:0] up_ink_addr, up_paper_addr;
|
||||
wire [7:0] up_ink, up_paper;
|
||||
wire [7:0] up_ink_data, up_paper_data;
|
||||
wire [8:0] vc, hc;
|
||||
wire [7:0] port_ff_data;
|
||||
wire clk14, clk7, clk35, ck14, ck7, ck35;
|
||||
screen screen0(
|
||||
video video0(
|
||||
.rst_n(usrrst_n),
|
||||
.clk28(clk28),
|
||||
|
||||
.machine(machine),
|
||||
.turbo(turbo),
|
||||
.border(screen_border),
|
||||
.border({border[2] ^ sd_indication, border[1] ^ magic_beeper, border[0]}),
|
||||
|
||||
.r(r),
|
||||
.g(g),
|
||||
@ -133,20 +118,19 @@ screen screen0(
|
||||
.vsync(vsync),
|
||||
.hsync(hsync),
|
||||
|
||||
.fetch_allow((!bus.iorq && !bus.mreq) || bus.rfsh || (clkwait && turbo == TURBO_NONE)),
|
||||
.fetch(screen_fetch),
|
||||
.addr(screen_addr),
|
||||
.fetch_next(screen_fetch_next),
|
||||
.fetch_data(bus.d),
|
||||
.read_req(video_read_req),
|
||||
.read_req_addr(video_read_addr),
|
||||
.read_req_ack(video_read_req_ack),
|
||||
.read_data_valid(video_read_data_valid),
|
||||
.read_data(vd),
|
||||
|
||||
.up_en(up_active),
|
||||
.up_ink_addr(up_ink_addr),
|
||||
.up_ink_data(up_ink_data),
|
||||
.up_paper_addr(up_paper_addr),
|
||||
.up_ink(up_ink),
|
||||
.up_paper(up_paper),
|
||||
.up_paper_data(up_paper_data),
|
||||
|
||||
.contention(screen_contention),
|
||||
.blink(blink),
|
||||
.contention(video_contention),
|
||||
.port_ff_active(port_ff_active),
|
||||
.port_ff_data(port_ff_data),
|
||||
|
||||
@ -184,7 +168,7 @@ ps2 #(.CLK_FREQ(28_000_000)) ps2_0(
|
||||
.clk(clk28),
|
||||
.ps2_clk_in(ps2_clk),
|
||||
.ps2_dat_in(ps2_dat),
|
||||
.zxkb_addr(bus.a_reg[15:8]),
|
||||
.zxkb_addr(bus.a[15:8]),
|
||||
.zxkb_data(ps2_kd),
|
||||
.key_magic(ps2_key_magic),
|
||||
.key_reset(ps2_key_reset),
|
||||
@ -198,8 +182,8 @@ ps2 #(.CLK_FREQ(28_000_000)) ps2_0(
|
||||
|
||||
|
||||
/* CPU CONTROLLER */
|
||||
wire n_int_next, clkcpu_ck, snow;
|
||||
cpucontrol cpucontrol0(
|
||||
wire n_int_next, clkcpu_ck, snow, cpu_contention;
|
||||
cpu cpu0(
|
||||
.rst_n(usrrst_n),
|
||||
.clk28(clk28),
|
||||
.clk14(clk14),
|
||||
@ -212,34 +196,38 @@ cpucontrol cpucontrol0(
|
||||
|
||||
.vc(vc),
|
||||
.hc(hc),
|
||||
.rampage128(rampage128),
|
||||
.ram_page128(ram_page128),
|
||||
.machine(machine),
|
||||
.turbo(turbo),
|
||||
.screen_contention(screen_contention),
|
||||
.hold(mem_wait),
|
||||
.video_contention(video_contention),
|
||||
.init_done_in(init_done),
|
||||
|
||||
.n_rstcpu(n_rstcpu),
|
||||
.n_rstcpu_out(n_rstcpu),
|
||||
.clkcpu(clkcpu),
|
||||
.clkcpu_ck(clkcpu_ck),
|
||||
.clkwait(clkwait),
|
||||
.n_int(n_int),
|
||||
.n_int_next(n_int_next),
|
||||
.snow(snow)
|
||||
.snow(snow),
|
||||
.contention(cpu_contention)
|
||||
);
|
||||
|
||||
|
||||
/* MAGIC */
|
||||
wire div_automap;
|
||||
wire div_map;
|
||||
wire div_mapram;
|
||||
wire [7:0] magic_dout;
|
||||
wire magic_dout_active;
|
||||
wire magic_mode, magic_map;
|
||||
wire joy_sinclair, up_en, ay_en, covox_en, soundrive_en;
|
||||
panning_t panning;
|
||||
wire divmmc_en, zc_en;
|
||||
wire divmmc_en, zc_en, sd_indication_en;
|
||||
assign sd_indication = sd_indication_en & ~sd_cs;
|
||||
|
||||
magic magic0(
|
||||
.rst_n(n_rstcpu),
|
||||
.clk28(clk28),
|
||||
.ck35(ck35),
|
||||
|
||||
.bus(bus),
|
||||
.d_out(magic_dout),
|
||||
@ -251,7 +239,8 @@ magic magic0(
|
||||
|
||||
.magic_button(ps2_key_magic),
|
||||
.pause_button(ps2_key_pause),
|
||||
.div_automap(div_automap),
|
||||
.div_paged(div_map && !div_mapram),
|
||||
.basic48_paged(basic48_paged),
|
||||
|
||||
.magic_mode(magic_mode),
|
||||
.magic_map(magic_map),
|
||||
@ -267,7 +256,8 @@ magic magic0(
|
||||
.ulaplus_en(up_en),
|
||||
.ay_en(ay_en),
|
||||
.covox_en(covox_en),
|
||||
.soundrive_en(soundrive_en)
|
||||
.soundrive_en(soundrive_en),
|
||||
.sd_indication_en(sd_indication_en)
|
||||
);
|
||||
|
||||
|
||||
@ -275,9 +265,9 @@ magic magic0(
|
||||
wire [7:0] ports_dout;
|
||||
wire ports_dout_active;
|
||||
wire beeper, tape_out;
|
||||
wire screenpage;
|
||||
wire rompage128;
|
||||
wire [2:0] rampage_ext;
|
||||
wire video_page;
|
||||
wire rom_page128;
|
||||
wire [2:0] ram_pageext;
|
||||
wire [2:0] port_1ffd;
|
||||
wire [4:0] port_dffd;
|
||||
ports ports0 (
|
||||
@ -302,10 +292,10 @@ ports ports0 (
|
||||
.tape_out(tape_out),
|
||||
.beeper(beeper),
|
||||
.border(border),
|
||||
.screenpage(screenpage),
|
||||
.rompage128(rompage128),
|
||||
.rampage128(rampage128),
|
||||
.rampage_ext(rampage_ext),
|
||||
.video_page(video_page),
|
||||
.rom_page128(rom_page128),
|
||||
.ram_page128(ram_page128),
|
||||
.ram_pageext(ram_pageext),
|
||||
.port_1ffd(port_1ffd),
|
||||
.port_dffd(port_dffd)
|
||||
);
|
||||
@ -338,7 +328,7 @@ turbosound turbosound0(
|
||||
/* COVOX & SOUNDRIVE */
|
||||
wire [7:0] soundrive_l0, soundrive_l1, soundrive_r0, soundrive_r1;
|
||||
soundrive soundrive0(
|
||||
.rst_n(usrrst_n),
|
||||
.rst_n(n_rstcpu),
|
||||
.clk28(clk28),
|
||||
.en_covox(covox_en),
|
||||
.en_specdrum(covox_en),
|
||||
@ -360,7 +350,7 @@ mixer mixer0(
|
||||
|
||||
.beeper(beeper ^ magic_beeper),
|
||||
.tape_out(tape_out),
|
||||
.tape_in(sd_miso_tape_in),
|
||||
.tape_in((divmmc_en || zc_en)? sd_indication : sd_miso_tape_in),
|
||||
.ay_a0(ay_a0),
|
||||
.ay_b0(ay_b0),
|
||||
.ay_c0(ay_c0),
|
||||
@ -381,7 +371,7 @@ mixer mixer0(
|
||||
|
||||
|
||||
/* DIVMMC */
|
||||
wire div_map, div_ram, div_ramwr_mask, div_dout_active;
|
||||
wire div_ram, div_ramwr_mask, div_dout_active;
|
||||
wire [7:0] div_dout;
|
||||
wire [3:0] div_page;
|
||||
wire sd_mosi0;
|
||||
@ -405,16 +395,17 @@ divmmc divmmc0(
|
||||
.sd_cs(sd_cs),
|
||||
|
||||
.rammap(port_dffd[4] | port_1ffd[0]),
|
||||
.magic_mode(magic_mode),
|
||||
.magic_map(magic_map),
|
||||
.mask_hooks(magic_map),
|
||||
.mask_nmi_hook(magic_mode),
|
||||
.basic48_paged(basic48_paged),
|
||||
|
||||
.page(div_page),
|
||||
.map(div_map),
|
||||
.automap(div_automap),
|
||||
.mapram(div_mapram),
|
||||
.ram(div_ram),
|
||||
.ramwr_mask(div_ramwr_mask)
|
||||
);
|
||||
assign sd_mosi_tape_out = (!divmmc_en && !zc_en)? tape_out : sd_mosi0;
|
||||
assign sd_mosi_tape_out = (divmmc_en || zc_en)? sd_mosi0 : tape_out;
|
||||
|
||||
|
||||
/* ULAPLUS */
|
||||
@ -430,10 +421,10 @@ ulaplus ulaplus0(
|
||||
.d_out_active(up_dout_active),
|
||||
|
||||
.active(up_active),
|
||||
.ink_addr(up_ink_addr),
|
||||
.paper_addr(up_paper_addr),
|
||||
.ink(up_ink),
|
||||
.paper(up_paper)
|
||||
.read_addr1(up_ink_addr),
|
||||
.read_data1(up_ink_data),
|
||||
.read_addr2(up_paper_addr),
|
||||
.read_data2(up_paper_data)
|
||||
);
|
||||
|
||||
|
||||
@ -483,7 +474,8 @@ asmi asmi0(
|
||||
|
||||
|
||||
/* MEMORY CONTROLLER */
|
||||
memcontrol memcontrol0(
|
||||
mem mem0(
|
||||
.rst_n(rst_n),
|
||||
.clk28(clk28),
|
||||
.bus(bus),
|
||||
.va(va),
|
||||
@ -491,26 +483,35 @@ memcontrol memcontrol0(
|
||||
.n_vrd(n_vrd),
|
||||
.n_vwr(n_vwr),
|
||||
|
||||
.bus_valid(mem_bus_valid),
|
||||
.cpuwait(mem_wait),
|
||||
.basic48_paged(basic48_paged),
|
||||
|
||||
.machine(machine),
|
||||
.screenpage(screenpage),
|
||||
.screen_fetch(screen_fetch),
|
||||
.snow(snow),
|
||||
.screen_addr(screen_addr),
|
||||
.turbo(turbo),
|
||||
.cpu_contention(cpu_contention),
|
||||
.magic_map(magic_map),
|
||||
.rampage128(rampage128),
|
||||
.rompage128(rompage128),
|
||||
.ram_page128(ram_page128),
|
||||
.rom_page128(rom_page128),
|
||||
.port_1ffd(port_1ffd),
|
||||
.port_dffd(port_dffd),
|
||||
.rampage_ext(rampage_ext),
|
||||
.divmmc_en(divmmc_en),
|
||||
.ram_pageext(ram_pageext),
|
||||
.div_ram(div_ram),
|
||||
.div_map(div_map),
|
||||
.div_ramwr_mask(div_ramwr_mask),
|
||||
.div_page(div_page),
|
||||
|
||||
.snow(snow),
|
||||
.video_page(video_page),
|
||||
.video_read_req(video_read_req),
|
||||
.video_read_addr(video_read_addr),
|
||||
.video_read_req_ack(video_read_req_ack),
|
||||
.video_data_valid(video_read_data_valid),
|
||||
|
||||
.rom2ram_ram_address(rom2ram_ram_address),
|
||||
.rom2ram_ram_wren(rom2ram_ram_wren),
|
||||
.rom2ram_dataout(rom2ram_dataout),
|
||||
|
||||
.magic_dout_active(magic_dout_active),
|
||||
.magic_dout(magic_dout),
|
||||
.up_dout_active(up_dout_active),
|
||||
|
@ -27,8 +27,8 @@ module turbosound(
|
||||
reg ay_bdir;
|
||||
reg ay_bc1;
|
||||
reg ay_sel;
|
||||
wire port_bffd = en && bus.ioreq && bus.a_reg[15] == 1'b1 && bus.a_reg[1] == 0;
|
||||
wire port_fffd = en && bus.ioreq && bus.a_reg[15] == 1'b1 && bus.a_reg[14] == 1'b1 && bus.a_reg[1] == 0;
|
||||
wire port_bffd = en && bus.ioreq && bus.a[15] == 1'b1 && bus.a[1] == 0;
|
||||
wire port_fffd = en && bus.ioreq && bus.a[15] == 1'b1 && bus.a[14] == 1'b1 && bus.a[1] == 0;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
ay_bc1 <= 0;
|
||||
@ -40,8 +40,8 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
ay_bdir <= port_bffd && bus.wr;
|
||||
if (!en_ts)
|
||||
ay_sel <= 0;
|
||||
else if (bus.ioreq && port_fffd && bus.wr && bus.d_reg[7:3] == 5'b11111)
|
||||
ay_sel <= bus.d_reg[0];
|
||||
else if (bus.ioreq && port_fffd && bus.wr && bus.d[7:3] == 5'b11111)
|
||||
ay_sel <= bus.d[0];
|
||||
end
|
||||
end
|
||||
|
||||
@ -65,7 +65,7 @@ YM2149 ym2149_0(
|
||||
.A8(~ay_sel),
|
||||
.BDIR(ay_bdir),
|
||||
.BC(ay_bc1),
|
||||
.DI(bus.d_reg),
|
||||
.DI(bus.d),
|
||||
.DO(ay_dout0),
|
||||
.SEL(1'b0),
|
||||
.MODE(1'b1),
|
||||
@ -80,7 +80,7 @@ YM2149 ym2149_1(
|
||||
.A8(ay_sel),
|
||||
.BDIR(ay_bdir),
|
||||
.BC(ay_bc1),
|
||||
.DI(bus.d_reg),
|
||||
.DI(bus.d),
|
||||
.DO(ay_dout1),
|
||||
.SEL(1'b0),
|
||||
.MODE(1'b0),
|
||||
|
@ -9,19 +9,21 @@ module ulaplus(
|
||||
output d_out_active,
|
||||
|
||||
output reg active,
|
||||
input [5:0] ink_addr,
|
||||
input [5:0] paper_addr,
|
||||
output reg [7:0] ink,
|
||||
output reg [7:0] paper
|
||||
|
||||
input [5:0] read_addr1,
|
||||
output reg [7:0] read_data1,
|
||||
input [5:0] read_addr2,
|
||||
output reg [7:0] read_data2
|
||||
);
|
||||
|
||||
|
||||
wire port_bf3b_cs = en && bus.ioreq && bus.a_reg == 16'hbf3b;
|
||||
wire port_ff3b_cs = en && bus.ioreq && bus.a_reg == 16'hff3b;
|
||||
wire port_bf3b_cs = en && bus.ioreq && bus.a == 16'hbf3b;
|
||||
wire port_ff3b_cs = en && bus.ioreq && bus.a == 16'hff3b;
|
||||
reg port_ff3b_rd;
|
||||
wire [7:0] port_ff3b_data = {7'b0000000, active};
|
||||
|
||||
reg [7:0] addr_reg;
|
||||
reg [2:0] read_req;
|
||||
reg [1:0] write_req;
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
@ -33,10 +35,11 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
else begin
|
||||
if (port_bf3b_cs && bus.wr)
|
||||
addr_reg <= bus.d_reg;
|
||||
addr_reg <= bus.d;
|
||||
if (port_ff3b_cs && bus.wr && addr_reg == 8'b01000000)
|
||||
active <= bus.d_reg[0];
|
||||
active <= bus.d[0];
|
||||
|
||||
read_req <= {read_req[1:0], port_ff3b_cs && bus.rd && addr_reg[7:6] == 2'b00};
|
||||
write_req <= {write_req[0], port_ff3b_cs && bus.wr && addr_reg[7:6] == 2'b00};
|
||||
port_ff3b_rd <= port_ff3b_cs && bus.rd;
|
||||
|
||||
@ -45,13 +48,7 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
wire write_req0 = write_req[0] && !write_req[1];
|
||||
reg read_step;
|
||||
wire [5:0] ram_a = write_req0? addr_reg[5:0] : read_step? ink_addr : paper_addr;
|
||||
wire [7:0] ram_q;
|
||||
ulaplus_ram pallete(ram_q, ram_a, bus.d_reg, write_req0, clk28);
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
read_step <= 0;
|
||||
@ -59,15 +56,24 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
read_step <= !read_step;
|
||||
end
|
||||
|
||||
wire read_req0 = read_req[0] && !read_req[1];
|
||||
wire write_req0 = write_req[0] && !write_req[1];
|
||||
wire [5:0] ram_a = (write_req0 || read_req0)? addr_reg[5:0] : read_step? read_addr2 : read_addr1;
|
||||
wire [7:0] ram_q;
|
||||
ulaplus_ram pallete(ram_q, ram_a, bus.d, write_req0, clk28);
|
||||
|
||||
reg [7:0] ram_q_reg;
|
||||
always @(posedge clk28) begin
|
||||
if (read_step)
|
||||
paper <= ram_q;
|
||||
if (read_req[1] && !read_req[2])
|
||||
ram_q_reg <= ram_q;
|
||||
else if (read_step)
|
||||
read_data1 <= ram_q;
|
||||
else
|
||||
ink <= ram_q;
|
||||
read_data2 <= ram_q;
|
||||
end
|
||||
|
||||
|
||||
assign d_out = port_ff3b_data;
|
||||
assign d_out = (addr_reg[7:6] == 2'b00)? ram_q_reg : port_ff3b_data;
|
||||
assign d_out_active = port_ff3b_rd;
|
||||
|
||||
endmodule
|
||||
|
175
fpga/rtl/screen.sv → fpga/rtl/video.sv
Executable file → Normal file
175
fpga/rtl/screen.sv → fpga/rtl/video.sv
Executable file → Normal file
@ -1,11 +1,9 @@
|
||||
`include "util.vh"
|
||||
import common::*;
|
||||
module screen(
|
||||
module video(
|
||||
input rst_n,
|
||||
input clk28,
|
||||
|
||||
input machine_t machine,
|
||||
input turbo_t turbo,
|
||||
input [2:0] border,
|
||||
|
||||
output reg [5:0] r,
|
||||
@ -15,23 +13,22 @@ module screen(
|
||||
output reg hsync,
|
||||
output reg csync,
|
||||
|
||||
input fetch_allow,
|
||||
output reg fetch,
|
||||
output fetch_next,
|
||||
output [14:0] addr,
|
||||
input [7:0] fetch_data,
|
||||
output read_req,
|
||||
output [14:0] read_req_addr,
|
||||
input read_req_ack,
|
||||
input read_data_valid,
|
||||
input [7:0] read_data,
|
||||
|
||||
output contention,
|
||||
output blink,
|
||||
output reg even_line,
|
||||
output port_ff_active,
|
||||
output [7:0] port_ff_data,
|
||||
|
||||
input up_en,
|
||||
output [5:0] up_ink_addr,
|
||||
input [7:0] up_ink_data,
|
||||
output [5:0] up_paper_addr,
|
||||
input [7:0] up_ink,
|
||||
input [7:0] up_paper,
|
||||
input [7:0] up_paper_data,
|
||||
|
||||
output [8:0] hc_out,
|
||||
output [8:0] vc_out,
|
||||
@ -43,7 +40,21 @@ module screen(
|
||||
output ck35
|
||||
);
|
||||
|
||||
/* SCREEN CONTROLLER */
|
||||
reg [8:0] vc;
|
||||
reg [10:0] hc0;
|
||||
wire [8:0] hc = hc0[10:2];
|
||||
assign vc_out = vc;
|
||||
assign hc_out = hc;
|
||||
|
||||
assign clk14 = hc0[0];
|
||||
assign clk7 = hc0[1];
|
||||
assign clk35 = hc0[2];
|
||||
assign ck14 = hc0[0];
|
||||
assign ck7 = hc0[0] & hc0[1];
|
||||
assign ck35 = hc0[0] & hc0[1] & hc0[2];
|
||||
|
||||
|
||||
/* SYNC SIGNALS */
|
||||
localparam H_AREA = 256;
|
||||
localparam V_AREA = 192;
|
||||
localparam SCREEN_DELAY = 13;
|
||||
@ -81,20 +92,6 @@ localparam V_SYNC_PENT = 8;
|
||||
localparam V_TBORDER_PENT = 64;
|
||||
localparam V_TOTAL_PENT = V_AREA + V_BBORDER_PENT + V_SYNC_PENT + V_TBORDER_PENT;
|
||||
|
||||
reg [8:0] vc;
|
||||
reg [10:0] hc0;
|
||||
wire [8:0] hc = hc0[10:2];
|
||||
|
||||
assign vc_out = vc;
|
||||
assign hc_out = hc;
|
||||
|
||||
assign clk14 = hc0[0];
|
||||
assign clk7 = hc0[1];
|
||||
assign clk35 = hc0[2];
|
||||
assign ck14 = hc0[0];
|
||||
assign ck7 = hc0[0] & hc0[1];
|
||||
assign ck35 = hc0[0] & hc0[1] & hc0[2];
|
||||
|
||||
wire hc0_reset =
|
||||
(machine == MACHINE_S48)?
|
||||
hc0 == (H_TOTAL_S48<<2) - 1'b1 :
|
||||
@ -111,14 +108,11 @@ wire vc_reset =
|
||||
vc == V_TOTAL_PENT - 1'b1 ;
|
||||
wire hsync0 =
|
||||
(machine == MACHINE_S48)?
|
||||
(hc >= (H_AREA + H_RBORDER_S48 + H_BLANK1_S48)) &&
|
||||
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48)) :
|
||||
(hc >= (H_AREA + H_RBORDER_S48 + H_BLANK1_S48)) && (hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48)) :
|
||||
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||
(hc >= (H_AREA + H_RBORDER_S128 + H_BLANK1_S128)) &&
|
||||
(hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128)) :
|
||||
(hc >= (H_AREA + H_RBORDER_S128 + H_BLANK1_S128)) && (hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128)) :
|
||||
// Pentagon
|
||||
(hc >= (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT)) &&
|
||||
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT)) ;
|
||||
(hc >= (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT)) && (hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT)) ;
|
||||
wire vsync0 =
|
||||
(machine == MACHINE_S48)?
|
||||
(vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48)) :
|
||||
@ -140,7 +134,6 @@ wire blank =
|
||||
((hc >= (H_AREA + H_RBORDER_PENT)) &&
|
||||
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT + H_BLANK2_PENT))) ;
|
||||
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
hc0 <= 0;
|
||||
@ -160,9 +153,8 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
reg [4:0] blink_cnt;
|
||||
assign blink = blink_cnt[$bits(blink_cnt)-1];
|
||||
wire blink = blink_cnt[$bits(blink_cnt)-1];
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
blink_cnt <= 0;
|
||||
@ -181,11 +173,24 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
|
||||
|
||||
/* SCREEN CONTROLLER */
|
||||
wire screen_show = (vc < V_AREA) && (hc0 >= (SCREEN_DELAY<<2) - 1) && (hc0 < ((H_AREA + SCREEN_DELAY)<<2) - 1);
|
||||
wire screen_update = hc0[4:0] == 5'b10011;
|
||||
wire border_update = (hc0[4:0] == 5'b10011) || (machine == MACHINE_PENT && ck7);
|
||||
wire bitmap_shift = hc0[1:0] == 2'b11;
|
||||
wire next_addr = hc0[4:0] == 5'b10000;
|
||||
wire next_addr = hc0[4:0] == 5'b10001;
|
||||
|
||||
reg screen_read, up_read;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
screen_read <= 0;
|
||||
up_read <= 0;
|
||||
end
|
||||
else begin
|
||||
screen_read <= (vc < V_AREA) && (hc0 > 17) && (hc0 < (H_AREA<<2) + 17);
|
||||
up_read <= screen_read && (screen_update || up_read);
|
||||
end
|
||||
end
|
||||
|
||||
reg [7:0] vaddr;
|
||||
reg [7:3] haddr;
|
||||
@ -200,71 +205,57 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
end
|
||||
|
||||
reg loading, loading_up;
|
||||
reg [7:0] bitmap, attr, bitmap_next, attr_next;
|
||||
reg [7:0] up_ink, up_paper;
|
||||
|
||||
reg read_step, read_step_cur;
|
||||
assign read_req = 1'b1; // just to simplify logic
|
||||
assign read_req_addr = (read_step == 1'd1)?
|
||||
{ 2'b10, vaddr[7:6], vaddr[2:0], vaddr[5:3], haddr[7:3] } :
|
||||
{ 5'b10110, vaddr[7:3], haddr[7:3] };
|
||||
assign up_ink_addr = up_read? { attr_next[7:6], 1'b0, attr_next[2:0] } : { 3'b0, border[2:0] };
|
||||
assign up_paper_addr = up_read? { attr_next[7:6], 1'b1, attr_next[5:3] } : { 3'b0, border[2:0] };
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
loading <= 0;
|
||||
loading_up <= 0;
|
||||
read_step <= 0;
|
||||
read_step_cur <= 0;
|
||||
attr_next <= 0;
|
||||
bitmap_next <= 0;
|
||||
end
|
||||
else begin
|
||||
loading <= (vc < V_AREA) && (hc0 > 15) && (hc0 < (H_AREA<<2) + 17);
|
||||
loading_up <= loading && (screen_update || loading_up);
|
||||
if (next_addr)
|
||||
read_step <= 0;
|
||||
else if (read_req_ack)
|
||||
read_step <= read_step + 1'd1;
|
||||
|
||||
if (read_req_ack)
|
||||
read_step_cur <= read_step;
|
||||
|
||||
if (read_data_valid && read_step_cur == 2'd0 && screen_read)
|
||||
attr_next <= read_data;
|
||||
else if (!screen_read && hc0[0])
|
||||
attr_next <= {2'b00, border[2:0], border[2:0]};
|
||||
|
||||
if (read_data_valid && read_step_cur == 2'd1 && screen_read)
|
||||
bitmap_next <= read_data;
|
||||
else if (!screen_read && hc0[0])
|
||||
bitmap_next <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
wire [7:0] attr_border = {2'b00, border[2:0], border[2:0]};
|
||||
|
||||
reg [7:0] bitmap, attr, bitmap_next, attr_next;
|
||||
reg [7:0] up_ink0, up_paper0;
|
||||
|
||||
reg [1:0] fetch_cnt;
|
||||
localparam FETCH_CYCLES = 2'd2;
|
||||
assign fetch_next = loading && (fetch_allow || (|fetch_cnt && fetch_cnt != FETCH_CYCLES && turbo == TURBO_14));
|
||||
|
||||
reg fetch_step;
|
||||
wire fetch_bitmap = fetch && fetch_step == 1'd0 && fetch_cnt == FETCH_CYCLES;
|
||||
wire fetch_attr = fetch && fetch_step == 1'd1 && fetch_cnt == FETCH_CYCLES;
|
||||
|
||||
assign addr = (fetch_step == 1'd0)?
|
||||
{ 2'b10, vaddr[7:6], vaddr[2:0], vaddr[5:3], haddr[7:3] } :
|
||||
{ 5'b10110, vaddr[7:3], haddr[7:3] };
|
||||
assign up_ink_addr = loading_up? { attr_next[7:6], 1'b0, attr_next[2:0] } : { 3'b0, attr_border[2:0] };
|
||||
assign up_paper_addr = loading_up? { attr_next[7:6], 1'b1, attr_next[5:3] } : { 3'b0, attr_border[2:0] };
|
||||
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
fetch <= 0;
|
||||
fetch_step <= 0;
|
||||
fetch_cnt <= 0;
|
||||
attr <= 0;
|
||||
bitmap <= 0;
|
||||
attr_next <= 0;
|
||||
bitmap_next <= 0;
|
||||
up_ink0 <= 0;
|
||||
up_paper0 <= 0;
|
||||
up_ink <= 0;
|
||||
up_paper <= 0;
|
||||
end
|
||||
else begin
|
||||
fetch <= fetch_next;
|
||||
if (fetch_cnt == FETCH_CYCLES) begin
|
||||
if (fetch_step == 1'd1)
|
||||
attr_next <= fetch_data;
|
||||
if (fetch_step == 1'd0)
|
||||
bitmap_next <= fetch_data;
|
||||
fetch_step <= fetch_step + 1'b1;
|
||||
fetch_cnt <= 0;
|
||||
end
|
||||
else if (fetch && fetch_next && !next_addr) begin
|
||||
fetch_cnt <= fetch_cnt + 1'b1;
|
||||
end
|
||||
else begin
|
||||
fetch_cnt <= 0;
|
||||
end
|
||||
|
||||
if (screen_show && screen_update)
|
||||
attr <= attr_next;
|
||||
else if (!screen_show && border_update)
|
||||
attr <= attr_border;
|
||||
attr <= {2'b00, border[2:0], border[2:0]};
|
||||
|
||||
if (screen_update)
|
||||
bitmap <= bitmap_next;
|
||||
@ -272,9 +263,9 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
bitmap <= {bitmap[6:0], 1'b0};
|
||||
|
||||
if (screen_update)
|
||||
up_ink0 <= up_ink;
|
||||
up_ink <= up_ink_data;
|
||||
if (screen_update)
|
||||
up_paper0 <= up_paper;
|
||||
up_paper <= up_paper_data;
|
||||
end
|
||||
end
|
||||
|
||||
@ -282,7 +273,7 @@ end
|
||||
/* ATTRIBUTE PORT */
|
||||
wire port_ff_attr = (machine == MACHINE_PENT) || hc[3:1] == 3'h6 || hc[3:1] == 3'h0;
|
||||
wire port_ff_bitmap = (hc[3] && hc[1]);
|
||||
assign port_ff_active = loading && (port_ff_attr || port_ff_bitmap);
|
||||
assign port_ff_active = screen_read && (port_ff_attr || port_ff_bitmap);
|
||||
assign port_ff_data =
|
||||
port_ff_attr? attr_next :
|
||||
port_ff_bitmap? bitmap_next :
|
||||
@ -291,15 +282,15 @@ assign port_ff_data =
|
||||
assign contention = (vc < V_AREA) && (hc < H_AREA) && (hc[2] || hc[3]);
|
||||
|
||||
|
||||
/* RGBS generation */
|
||||
/* RGBS OUTPUT */
|
||||
wire pixel = bitmap[7];
|
||||
always @(posedge clk28) begin
|
||||
if (blank)
|
||||
{g, r, b} = 0;
|
||||
else if (up_en) begin
|
||||
g[5:3] = pixel? up_ink0[7:5] : up_paper0[7:5];
|
||||
r[5:3] = pixel? up_ink0[4:2] : up_paper0[4:2];
|
||||
b[5:4] = pixel? up_ink0[1:0] : up_paper0[1:0];
|
||||
g[5:3] = pixel? up_ink[7:5] : up_paper[7:5];
|
||||
r[5:3] = pixel? up_ink[4:2] : up_paper[4:2];
|
||||
b[5:4] = pixel? up_ink[1:0] : up_paper[1:0];
|
||||
g[2:0] = g[5:3];
|
||||
r[2:0] = r[5:3];
|
||||
b[3:0] = {b[5:4], b[5:4]};
|
@ -12,6 +12,9 @@ sof2jic:
|
||||
mv output/zx_ula.jic "output/${REVISION}.jic"
|
||||
rm output/zx_ula.sof
|
||||
|
||||
rbf2bin:
|
||||
srec_cat output/rev_${REV}.rbf -binary -Bit_Reverse 2 -Byte_Swap 2 -o output/rev_${REV}.bin -binary
|
||||
|
||||
program_sof:
|
||||
quartus_pgm --no_banner --mode=jtag -o "P;output/${REVISION}.sof"
|
||||
|
||||
@ -24,6 +27,6 @@ clean:
|
||||
report:
|
||||
cat output/${REVISION}.*.smsg output/${REVISION}.*.rpt |grep -e Error -e Critical -e Warning |grep -v -e "Family doesn't support jitter analysis" -e "Force Fitter to Avoid Periphery Placement Warnings"
|
||||
|
||||
export PATH:=/opt/quartus13.0sp1/quartus/bin:/cygdrive/c/Hwdev/quartus130sp1/quartus/bin:${PATH}
|
||||
export PATH:=/opt/quartus13.0sp1/quartus/bin:/cygdrive/c/Hwdev/quartus130sp1/quartus/bin:/cygdrive/c/Dev/srec/bin/:${PATH}
|
||||
|
||||
-include Makefile.local
|
||||
|
@ -1,7 +1,7 @@
|
||||
create_clock -period 28MHz -name {clk28} [get_ports {clk_in}]
|
||||
|
||||
create_generated_clock -name {clkcpu} -divide_by 2 -source [get_ports {clk_in}] [get_registers {cpucontrol:cpucontrol0|clkcpu}]
|
||||
create_generated_clock -name {hc0[1]} -divide_by 4 -source [get_ports {clk_in}] [get_registers {screen:screen0|hc0[1]}]
|
||||
create_generated_clock -name {clkcpu} -divide_by 2 -source [get_ports {clk_in}] [get_registers {cpu:cpu0|clkcpu}]
|
||||
create_generated_clock -name {hc0[1]} -divide_by 4 -source [get_ports {clk_in}] [get_registers {video:video0|hc0[1]}]
|
||||
|
||||
derive_pll_clocks
|
||||
derive_clocks -period 14MHz
|
||||
@ -9,12 +9,12 @@ derive_clocks -period 14MHz
|
||||
set_multicycle_path -from {vencode:*|*} -to {vencode:*|*} -setup 4
|
||||
set_multicycle_path -from {vencode:*|*} -to {vencode:*|*} -hold 3
|
||||
|
||||
# One screen read cycle = ~71ns. SRAM speed = 55ns
|
||||
# One video read cycle = ~71ns. SRAM speed = 55ns
|
||||
# So we have about 16ns to setup control signals (n_vrd, n_vwr, va - 10ns) and read back data (vd - 6ns)
|
||||
set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vrd] 10ns
|
||||
set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports n_vwr] 10ns
|
||||
set_max_delay -from [get_pins -compatibility_mode screen0|*] -to [get_ports va[*]] 10ns
|
||||
set_max_delay -from [get_ports vd[*]] -to [get_pins -compatibility_mode screen0|*] 6ns
|
||||
set_max_delay -from [get_pins -compatibility_mode video0|*] -to [get_ports n_vrd] 10ns
|
||||
set_max_delay -from [get_pins -compatibility_mode video0|*] -to [get_ports n_vwr] 10ns
|
||||
set_max_delay -from [get_pins -compatibility_mode video0|*] -to [get_ports va[*]] 10ns
|
||||
set_max_delay -from [get_ports vd[*]] -to [get_pins -compatibility_mode video0|*] 6ns
|
||||
|
||||
set_false_path -from * -to [get_ports {snd_l}]
|
||||
set_false_path -from * -to [get_ports {snd_r}]
|
||||
|
@ -171,12 +171,12 @@ set_global_assignment -name VHDL_FILE ../rtl/vencode.vhd
|
||||
set_global_assignment -name VERILOG_INCLUDE_FILE ../rtl/ps2_codes.vh
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mixer.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/soundrive.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/screen.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/video.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ports.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/magic.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpucontrol.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/memcontrol.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpu.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mem.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ulaplus.sv
|
||||
set_global_assignment -name VERILOG_FILE ../rtl/ps2.v
|
||||
@ -197,4 +197,6 @@ set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA
|
||||
set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON
|
||||
set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION OFF
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
@ -170,12 +170,12 @@ set_global_assignment -name VHDL_FILE ../rtl/vencode.vhd
|
||||
set_global_assignment -name VERILOG_INCLUDE_FILE ../rtl/ps2_codes.vh
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mixer.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/soundrive.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/screen.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/video.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ports.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/magic.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpucontrol.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/memcontrol.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpu.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mem.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ulaplus.sv
|
||||
set_global_assignment -name VERILOG_FILE ../rtl/ps2.v
|
||||
@ -197,4 +197,6 @@ set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA
|
||||
set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON
|
||||
set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION OFF
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
@ -170,12 +170,12 @@ set_global_assignment -name VHDL_FILE ../rtl/vencode.vhd
|
||||
set_global_assignment -name VERILOG_INCLUDE_FILE ../rtl/ps2_codes.vh
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mixer.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/soundrive.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/screen.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/video.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ports.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/magic.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpucontrol.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/memcontrol.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/cpu.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/mem.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/ulaplus.sv
|
||||
set_global_assignment -name VERILOG_FILE ../rtl/ps2.v
|
||||
@ -198,4 +198,6 @@ set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA
|
||||
set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE BALANCED
|
||||
set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON
|
||||
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION OFF
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
@ -44,13 +44,21 @@ Loop:
|
||||
|
||||
ORG #8000 // mapped #0000
|
||||
MagicROM_Start:
|
||||
ld sp, #8000
|
||||
ld bc, #09ff ; divmmc = 1
|
||||
ld a, 1 ; ...
|
||||
out (c), a ; ...
|
||||
ld bc, #03ff ; cpu freq = 7mhz
|
||||
ld a, 3 ; ...
|
||||
ld bc, #02ff ; machine = 128
|
||||
ld a, 1 ; ...
|
||||
out (c), a ; ...
|
||||
ld bc, #03ff ; cpu freq = 14mhz
|
||||
ld a, 4 ; ...
|
||||
out (c), a ; ...
|
||||
.100 in a, (#fe)
|
||||
ld bc, #0000
|
||||
ld de, #5000
|
||||
ld hl, #6000
|
||||
ldir
|
||||
push bc
|
||||
jp #f008
|
||||
ORG #F000
|
||||
|
BIN
out/fpga.rev.A.bin
vendored
Normal file
BIN
out/fpga.rev.A.bin
vendored
Normal file
Binary file not shown.
BIN
out/fpga.rev.B.bin
vendored
Normal file
BIN
out/fpga.rev.B.bin
vendored
Normal file
Binary file not shown.
BIN
out/fpga.zero.rev.A.bin
vendored
Normal file
BIN
out/fpga.zero.rev.A.bin
vendored
Normal file
Binary file not shown.
@ -1,7 +1,11 @@
|
||||
ifneq ($(wildcard ../.git),)
|
||||
VERSION := $(shell git describe --abbrev=6 --long --dirty --always --tags --first-parent)
|
||||
endif
|
||||
|
||||
export PATH:=/cygdrive/c/Hwdev/sjasmplus/:/cygdrive/c/Dev/srec/:${PATH}
|
||||
|
||||
REV=D
|
||||
SJOPTS=-DSIZIFXXS -DREV_${REV}
|
||||
SJOPTS=-DSIZIFXXS -DREV_${REV} -DVERSION=\"${VERSION}\"
|
||||
|
||||
.PHONY: all clean .FORCE
|
||||
.FORCE:
|
||||
@ -19,3 +23,5 @@ clean:
|
||||
srec_cat $< -binary -o $@ -intel
|
||||
|
||||
test: main_test.bin
|
||||
|
||||
-include Makefile.local
|
||||
|
@ -31,6 +31,9 @@ ay DB 1
|
||||
sd DB 2
|
||||
ulaplus DB 1
|
||||
dac DB 3
|
||||
sdind DB 1
|
||||
_reserv4 DB 0
|
||||
autoturbo DB 0
|
||||
ENDS
|
||||
|
||||
CFG_DEFAULT CFG_T
|
||||
|
@ -1,5 +1,6 @@
|
||||
ASSERT __SJASMPLUS__ >= 0x011402 ; SjASMPlus 1.20.2
|
||||
OPT --syntax=abf
|
||||
DEVICE ZXSPECTRUM48
|
||||
OPT --syntax=F
|
||||
|
||||
; Startup handler
|
||||
ORG #0000
|
||||
@ -497,13 +498,22 @@ wait_for_keys_release:
|
||||
include font.asm
|
||||
include strings.asm
|
||||
|
||||
DISPLAY "Free space: ",/D,#1FE8-$
|
||||
ASSERT $ < #1FE8
|
||||
DISPLAY "Free space: ",/D,fwinfo-$," (",$,")"
|
||||
ASSERT $ < fwinfo
|
||||
|
||||
|
||||
; Just some string at the end of ROM
|
||||
ORG #1FE8
|
||||
DB 0,"End of Sizif Magic ROM",0
|
||||
; Just some firmware info at the end of ROM
|
||||
ORG #2000-(fwinfo.end-fwinfo)
|
||||
fwinfo:
|
||||
DB 0
|
||||
.version:
|
||||
DB VERSION, 0
|
||||
.date
|
||||
DB __DATE__, 0
|
||||
.time:
|
||||
DB __TIME__, 0
|
||||
DB "End of Sizif Magic ROM", 0
|
||||
.end
|
||||
|
||||
; Variables
|
||||
ORG #C000
|
||||
|
@ -37,10 +37,18 @@ menudefault: MENU_DEF 20
|
||||
MENUENTRY_T str_sd menu_sd_value_cb menu_sd_cb
|
||||
MENUENTRY_T str_ulaplus menu_ulaplus_value_cb menu_ulaplus_cb
|
||||
MENUENTRY_T str_dac menu_dac_value_cb menu_dac_cb
|
||||
MENUENTRY_T str_menuadv 0 menu_menuadv_cb
|
||||
MENUENTRY_T str_exit menu_exit_value_cb menu_exit_cb
|
||||
MENUENTRY_T 0
|
||||
.end:
|
||||
|
||||
menuadv: MENU_DEF 22
|
||||
MENUENTRY_T str_sd_indication menu_sdind_value_cb menu_sdind_cb
|
||||
MENUENTRY_T str_autoturbo menu_autoturbo_value_cb menu_autoturbo_cb
|
||||
MENUENTRY_T str_back 0 menu_back_cb
|
||||
MENUENTRY_T 0
|
||||
.end:
|
||||
|
||||
|
||||
|
||||
menu_machine_value_cb:
|
||||
@ -48,73 +56,89 @@ menu_machine_value_cb:
|
||||
ld a, (cfg.machine)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_machine_48_end-2
|
||||
DW str_machine_128_end-2
|
||||
DW str_machine_3e_end-2
|
||||
DW str_machine_pentagon_end-2
|
||||
DW str_machine_48.end-2
|
||||
DW str_machine_128.end-2
|
||||
DW str_machine_3e.end-2
|
||||
DW str_machine_pentagon.end-2
|
||||
|
||||
menu_clock_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.clock)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_cpu_35_end-2
|
||||
DW str_cpu_44_end-2
|
||||
DW str_cpu_52_end-2
|
||||
DW str_cpu_7_end-2
|
||||
DW str_cpu_14_end-2
|
||||
DW str_cpu_35.end-2
|
||||
DW str_cpu_44.end-2
|
||||
DW str_cpu_52.end-2
|
||||
DW str_cpu_7.end-2
|
||||
DW str_cpu_14.end-2
|
||||
|
||||
menu_panning_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.panning)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_panning_mono_end-2
|
||||
DW str_panning_abc_end-2
|
||||
DW str_panning_acb_end-2
|
||||
DW str_panning_mono.end-2
|
||||
DW str_panning_abc.end-2
|
||||
DW str_panning_acb.end-2
|
||||
|
||||
menu_joystick_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.joystick)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_joystick_kempston_end-2
|
||||
DW str_joystick_sinclair_end-2
|
||||
DW str_joystick_kempston.end-2
|
||||
DW str_joystick_sinclair.end-2
|
||||
|
||||
menu_sd_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.sd)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_off_end-2
|
||||
DW str_divmmc_end-2
|
||||
DW str_zc3e_end-2
|
||||
DW str_off.end-2
|
||||
DW str_divmmc.end-2
|
||||
DW str_zc3e.end-2
|
||||
|
||||
menu_ulaplus_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.ulaplus)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_off_end-2
|
||||
DW str_on_end-2
|
||||
DW str_off.end-2
|
||||
DW str_on.end-2
|
||||
|
||||
menu_dac_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.dac)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_off_end-2
|
||||
DW str_dac_covox_end-2
|
||||
DW str_dac_sd_end-2
|
||||
DW str_dac_covoxsd_end-2
|
||||
DW str_off.end-2
|
||||
DW str_dac_covox.end-2
|
||||
DW str_dac_sd.end-2
|
||||
DW str_dac_covoxsd.end-2
|
||||
|
||||
menu_exit_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (var_exit_reboot)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_exit_no_reboot_end-2
|
||||
DW str_exit_reboot_end-2
|
||||
DW str_exit_no_reboot.end-2
|
||||
DW str_exit_reboot.end-2
|
||||
|
||||
menu_sdind_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.sdind)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_off_short.end-2
|
||||
DW str_on_short.end-2
|
||||
|
||||
menu_autoturbo_value_cb:
|
||||
ld ix, .values_table
|
||||
ld a, (cfg.autoturbo)
|
||||
jp menu_value_get
|
||||
.values_table:
|
||||
DW str_off_short.end-2
|
||||
DW str_on_short.end-2
|
||||
|
||||
menu_value_get:
|
||||
sla a
|
||||
@ -203,6 +227,34 @@ menu_exit_cb:
|
||||
ld (var_exit_flag), a
|
||||
ret
|
||||
|
||||
menu_menuadv_cb:
|
||||
ld hl, menuadv
|
||||
call menu_init
|
||||
ret
|
||||
|
||||
menu_sdind_cb:
|
||||
ld a, (cfg.sdind)
|
||||
ld c, 1
|
||||
call menu_handle_press
|
||||
ld (cfg.sdind), a
|
||||
ld bc, #0cff
|
||||
out (c), a
|
||||
ret
|
||||
|
||||
menu_autoturbo_cb:
|
||||
ld a, (cfg.autoturbo)
|
||||
ld c, 1
|
||||
call menu_handle_press
|
||||
ld (cfg.autoturbo), a
|
||||
ld bc, #0eff
|
||||
out (c), a
|
||||
ret
|
||||
|
||||
menu_back_cb:
|
||||
call restore_screen
|
||||
ld hl, (var_menumain)
|
||||
jp menu_init
|
||||
|
||||
|
||||
; IN - A - variable to change
|
||||
; IN - C - max value
|
||||
|
@ -1,100 +1,45 @@
|
||||
MACRO DEFSTR _string
|
||||
DB _string,0
|
||||
@.end:
|
||||
ENDM
|
||||
DB 0
|
||||
|
||||
str_sizif: DB "SIZIF-XXS",0
|
||||
str_sizif_end:
|
||||
|
||||
str_pause DB " PAUSE ",0
|
||||
str_pause_end:
|
||||
|
||||
str_exit: DB "Exit",0
|
||||
str_exit_end:
|
||||
|
||||
str_exit_reboot: DB "& reboot ",0
|
||||
str_exit_reboot_end:
|
||||
|
||||
str_exit_no_reboot: DB " ",0
|
||||
str_exit_no_reboot_end:
|
||||
|
||||
str_on: DB " ON",0
|
||||
str_on_end:
|
||||
|
||||
str_off: DB " OFF",0
|
||||
str_off_end:
|
||||
|
||||
str_machine: DB "Machine",0
|
||||
str_machine_end:
|
||||
|
||||
str_machine_48: DB " 48",0
|
||||
str_machine_48_end:
|
||||
|
||||
str_machine_128: DB " 128",0
|
||||
str_machine_128_end:
|
||||
|
||||
str_machine_3e: DB " +3e",0
|
||||
str_machine_3e_end:
|
||||
|
||||
str_machine_pentagon: DB "Pentagon",0
|
||||
str_machine_pentagon_end:
|
||||
|
||||
str_cpu: DB "CPU freq",0
|
||||
str_cpu_end:
|
||||
|
||||
str_cpu_35: DB "3.5MHz",0
|
||||
str_cpu_35_end:
|
||||
|
||||
str_cpu_44: DB "4.4MHz",0
|
||||
str_cpu_44_end:
|
||||
|
||||
str_cpu_52: DB "5.2MHz",0
|
||||
str_cpu_52_end:
|
||||
|
||||
str_cpu_7: DB " 7MHz",0
|
||||
str_cpu_7_end:
|
||||
|
||||
str_cpu_14: DB " 14MHz",0
|
||||
str_cpu_14_end:
|
||||
|
||||
str_panning: DB "Panning",0
|
||||
str_panning_end:
|
||||
|
||||
str_panning_abc: DB " ABC",0
|
||||
str_panning_abc_end:
|
||||
|
||||
str_panning_acb: DB " ACB",0
|
||||
str_panning_acb_end:
|
||||
|
||||
str_panning_mono: DB "Mono",0
|
||||
str_panning_mono_end:
|
||||
|
||||
str_joystick: DB "Joystick",0
|
||||
str_joystick_end:
|
||||
|
||||
str_joystick_kempston: DB "Kempston",0
|
||||
str_joystick_kempston_end:
|
||||
|
||||
str_joystick_sinclair: DB "Sinclair",0
|
||||
str_joystick_sinclair_end:
|
||||
|
||||
str_sd: DB "SD card",0
|
||||
str_sd_end:
|
||||
|
||||
str_divmmc: DB "DivMMC",0
|
||||
str_divmmc_end:
|
||||
|
||||
str_zc3e: DB "ZC/+3e",0
|
||||
str_zc3e_end:
|
||||
|
||||
str_ulaplus: DB "ULA+",0
|
||||
str_ulaplus_end
|
||||
|
||||
str_dac: DB "DAC",0
|
||||
str_dac_end
|
||||
|
||||
str_dac_covox: DB " Covox",0
|
||||
str_dac_covox_end
|
||||
|
||||
str_dac_sd: DB " SD",0
|
||||
str_dac_sd_end
|
||||
|
||||
str_dac_covoxsd: DB "Covox+SD",0
|
||||
str_dac_covoxsd_end
|
||||
str_sizif: DEFSTR "SIZIF-XXS"
|
||||
str_pause: DEFSTR " PAUSE "
|
||||
str_exit: DEFSTR "Exit"
|
||||
str_exit_reboot: DEFSTR "& reboot "
|
||||
str_exit_no_reboot: DEFSTR " "
|
||||
str_on: DEFSTR " ON"
|
||||
str_off: DEFSTR " OFF"
|
||||
str_on_short: DEFSTR " ON"
|
||||
str_off_short: DEFSTR "OFF"
|
||||
str_machine: DEFSTR "Machine"
|
||||
str_machine_48: DEFSTR " 48"
|
||||
str_machine_128: DEFSTR " 128"
|
||||
str_machine_3e: DEFSTR " +3e"
|
||||
str_machine_pentagon: DEFSTR "Pentagon"
|
||||
str_cpu: DEFSTR "CPU freq"
|
||||
str_cpu_35: DEFSTR "3.5MHz"
|
||||
str_cpu_44: DEFSTR "4.4MHz"
|
||||
str_cpu_52: DEFSTR "5.2MHz"
|
||||
str_cpu_7: DEFSTR " 7MHz"
|
||||
str_cpu_14: DEFSTR " 14MHz"
|
||||
str_panning: DEFSTR "Panning"
|
||||
str_panning_abc: DEFSTR " ABC"
|
||||
str_panning_acb: DEFSTR " ACB"
|
||||
str_panning_mono: DEFSTR "Mono"
|
||||
str_joystick: DEFSTR "Joystick"
|
||||
str_joystick_kempston: DEFSTR "Kempston"
|
||||
str_joystick_sinclair: DEFSTR "Sinclair"
|
||||
str_sd: DEFSTR "SD card"
|
||||
str_divmmc: DEFSTR "DivMMC"
|
||||
str_zc3e: DEFSTR "ZC/+3e"
|
||||
str_ulaplus: DEFSTR "ULA+"
|
||||
str_dac: DEFSTR "DAC"
|
||||
str_dac_covox: DEFSTR " Covox"
|
||||
str_dac_sd: DEFSTR " SD"
|
||||
str_dac_covoxsd: DEFSTR "Covox+SD"
|
||||
str_menuadv: DEFSTR "Advanced..."
|
||||
str_sd_indication: DEFSTR "SD indication"
|
||||
str_autoturbo: DEFSTR "Auto CPU freq"
|
||||
str_back: DEFSTR "Go back..."
|
||||
|
Reference in New Issue
Block a user