mirror of
https://github.com/UzixLS/zx-sizif-xxs.git
synced 2025-07-19 07:11:28 +03:00
merge latest changes from sizif-512
* add 4.4 MHz and 5.2 MHz turbo modes * handle magic key press if initialization wasn't completed before * replace 'timings', 'ram', 'plus3' settings with one 'machine' setting * refactor memory controller * significantly improve classic timings * magic rom: fix 'h' font character * fix hanging of esxdos browser after magic key double press * enable divmmc (esxdos OS) by magic rom on poweron; add NO-OS option * improve pause ('f12' on ps/2 keyboard or 'start' on gamepad) * magic rom: handle C-key on sega gamepad as exit
This commit is contained in:
@ -1,7 +1,8 @@
|
|||||||
package common;
|
package common;
|
||||||
typedef enum { TIMINGS_PENT, TIMINGS_S48, TIMINGS_S128 } timings_t;
|
typedef enum { MACHINE_S48, MACHINE_S128, MACHINE_S3, MACHINE_PENT } machine_t;
|
||||||
typedef enum { TURBO_NONE, TURBO_7, TURBO_14 } turbo_t;
|
typedef enum { TURBO_NONE, TURBO_4, TURBO_5, TURBO_7, TURBO_14 } turbo_t;
|
||||||
typedef enum { RAM_512, RAM_48, RAM_128 } rammode_t;
|
typedef enum { PANNING_MONO, PANNING_ABC, PANNING_ACB } panning_t;
|
||||||
|
typedef enum { DIVMMC_OFF, DIVMMC_ON, DIVMMC_NOOS } divmmc_t;
|
||||||
endpackage
|
endpackage
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,16 +5,17 @@ module cpucontrol(
|
|||||||
input clk14,
|
input clk14,
|
||||||
input clk7,
|
input clk7,
|
||||||
input clk35,
|
input clk35,
|
||||||
|
input ck14,
|
||||||
|
input ck7,
|
||||||
|
|
||||||
cpu_bus bus,
|
cpu_bus bus,
|
||||||
|
|
||||||
input [8:0] vc,
|
input [8:0] vc,
|
||||||
input [8:0] hc,
|
input [8:0] hc,
|
||||||
|
input screen_contention,
|
||||||
input [2:0] rampage128,
|
input [2:0] rampage128,
|
||||||
input screen_loading,
|
input machine_t machine,
|
||||||
input turbo_t turbo,
|
input turbo_t turbo,
|
||||||
input timings_t timings,
|
|
||||||
input pause,
|
|
||||||
input ext_wait_cycle,
|
input ext_wait_cycle,
|
||||||
input init_done_in,
|
input init_done_in,
|
||||||
|
|
||||||
@ -29,17 +30,19 @@ module cpucontrol(
|
|||||||
|
|
||||||
|
|
||||||
/* CONTENTION */
|
/* CONTENTION */
|
||||||
|
wire iorq_contended = bus.iorq && (~bus.a[0] || (~bus.a[1] && ~bus.a[15]));
|
||||||
reg mreq_delayed, iorq_delayed;
|
reg mreq_delayed, iorq_delayed;
|
||||||
always @(posedge clkcpu)
|
always @(posedge clkcpu)
|
||||||
mreq_delayed <= bus.mreq;
|
mreq_delayed <= bus.mreq;
|
||||||
always @(posedge clkcpu)
|
always @(posedge clkcpu)
|
||||||
iorq_delayed <= bus.iorq;
|
iorq_delayed <= iorq_contended;
|
||||||
wire contention_mem_addr = bus.a[14] & (~bus.a[15] | (bus.a[15] & rampage128[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_mem = iorq_delayed == 1'b0 && mreq_delayed == 1'b0 && contention_mem_addr;
|
||||||
wire contention_io = iorq_delayed == 1'b0 && bus.iorq;
|
wire contention_io = iorq_delayed == 1'b0 && iorq_contended;
|
||||||
wire contention0 = screen_loading && (hc[2] || hc[3]) && (contention_mem || contention_io);
|
wire contention0 = screen_contention && (contention_mem || contention_io);
|
||||||
wire contention = clkcpu && contention0 && turbo == TURBO_NONE && timings != TIMINGS_PENT;
|
wire contention = clkcpu && contention0 && turbo == TURBO_NONE && (machine == MACHINE_S48 || machine == MACHINE_S128 || machine == MACHINE_S3);
|
||||||
assign snow = (timings != TIMINGS_PENT) && bus.a[14] && ~bus.a[15] && bus.rfsh;
|
assign snow = bus.a[14] && ~bus.a[15] && bus.rfsh && (machine == MACHINE_S48 || machine == MACHINE_S128);
|
||||||
|
|
||||||
|
|
||||||
/* CLOCK */
|
/* CLOCK */
|
||||||
@ -47,35 +50,47 @@ reg [2:0] turbo_wait;
|
|||||||
wire turbo_wait_trig0 = bus.rd || bus.wr;
|
wire turbo_wait_trig0 = bus.rd || bus.wr;
|
||||||
reg turbo_wait_trig1;
|
reg turbo_wait_trig1;
|
||||||
always @(posedge clk28) begin
|
always @(posedge clk28) begin
|
||||||
turbo_wait_trig1 <= turbo_wait_trig0;
|
|
||||||
turbo_wait[0] <= turbo == TURBO_14 && turbo_wait_trig0 && !turbo_wait_trig1;
|
turbo_wait[0] <= turbo == TURBO_14 && turbo_wait_trig0 && !turbo_wait_trig1;
|
||||||
turbo_wait[1] <= turbo_wait[0] && (bus.iorq || ext_wait_cycle);
|
turbo_wait[1] <= turbo_wait[0] && (bus.iorq || ext_wait_cycle);
|
||||||
turbo_wait[2] <= turbo_wait[1];
|
turbo_wait[2] <= turbo_wait[1];
|
||||||
|
turbo_wait_trig1 <= turbo_wait_trig0;
|
||||||
end
|
end
|
||||||
|
|
||||||
reg clkcpu_prev;
|
reg clkcpu_prev;
|
||||||
assign clkcpu_ck = clkcpu && ! clkcpu_prev;
|
assign clkcpu_ck = clkcpu && !clkcpu_prev;
|
||||||
assign clkwait = pause || contention || (|turbo_wait);
|
assign clkwait = contention || (|turbo_wait);
|
||||||
always @(negedge clk28) begin
|
always @(posedge clk28) begin
|
||||||
clkcpu_prev <= clkcpu;
|
clkcpu_prev <= clkcpu;
|
||||||
clkcpu <= clkwait? clkcpu : (turbo == TURBO_14)? clk14 : (turbo == TURBO_7)? clk7 : clk35;
|
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
|
end
|
||||||
|
|
||||||
|
|
||||||
/* INT GENERATOR */
|
/* INT GENERATOR */
|
||||||
localparam INT_V_S48 = 247;
|
localparam INT_V_S48 = 248;
|
||||||
localparam INT_H_S48 = 442;
|
localparam INT_H_S48 = 0;
|
||||||
localparam INT_V_S128 = 247;
|
localparam INT_V_S128 = 248;
|
||||||
localparam INT_H_S128 = 450;
|
localparam INT_H_S128 = 4;
|
||||||
localparam INT_V_PENT = 239;
|
localparam INT_V_PENT = 239;
|
||||||
localparam INT_H_PENT = 316;
|
localparam INT_H_PENT = 322;
|
||||||
wire int_begin =
|
wire int_begin =
|
||||||
(timings == TIMINGS_PENT)?
|
(machine == MACHINE_S48)?
|
||||||
vc == INT_V_PENT && hc == INT_H_PENT :
|
vc == INT_V_S48 && hc == INT_H_S48 :
|
||||||
(timings == TIMINGS_S128)?
|
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||||
vc == INT_V_S128 && hc == INT_H_S128 :
|
vc == INT_V_S128 && hc == INT_H_S128 :
|
||||||
// 48K
|
// Pentagon
|
||||||
vc == INT_V_S48 && hc == INT_H_S48 ;
|
vc == INT_V_PENT && hc == INT_H_PENT ;
|
||||||
|
|
||||||
reg [4:0] int_cnt;
|
reg [4:0] int_cnt;
|
||||||
assign n_int_next = (|int_cnt)? 1'b0 : 1'b1;
|
assign n_int_next = (|int_cnt)? 1'b0 : 1'b1;
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
@ -98,9 +113,25 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
n_rstcpu <= 0;
|
n_rstcpu <= 0;
|
||||||
else if (!init_done_in)
|
else if (!init_done_in)
|
||||||
n_rstcpu <= 0;
|
n_rstcpu <= 0;
|
||||||
else if (vc[0])
|
`ifdef TESTBENCH
|
||||||
|
else if (hc[4])
|
||||||
|
n_rstcpu <= 1'b1;
|
||||||
|
`endif
|
||||||
|
else if (vc[8])
|
||||||
n_rstcpu <= 1'b1;
|
n_rstcpu <= 1'b1;
|
||||||
end
|
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
|
endmodule
|
||||||
|
@ -20,25 +20,26 @@ module divmmc(
|
|||||||
input magic_mode,
|
input magic_mode,
|
||||||
input magic_map,
|
input magic_map,
|
||||||
|
|
||||||
output reg [3:0] div_page,
|
output reg [3:0] page,
|
||||||
output div_map,
|
output map,
|
||||||
output div_ram,
|
output reg automap,
|
||||||
output div_ramwr_mask,
|
output ram,
|
||||||
output div_wait
|
output ramwr_mask,
|
||||||
|
output cpuwait
|
||||||
);
|
);
|
||||||
|
|
||||||
reg div_automap, div_automap_next;
|
reg automap_next;
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
div_automap_next <= 0;
|
automap_next <= 0;
|
||||||
div_automap <= 0;
|
automap <= 0;
|
||||||
end
|
end
|
||||||
else if (bus.m1 && bus.memreq && magic_map == 0) begin
|
else if (bus.m1 && bus.memreq && !magic_map) begin
|
||||||
if (!en_hooks || !en || rammap) begin
|
if (!en_hooks || !en || rammap) begin
|
||||||
div_automap_next <= 0;
|
automap_next <= 0;
|
||||||
end
|
end
|
||||||
else if (bus.a_reg[15:3] == 13'h3FF) begin // exit vectors 1FF8-1FFF
|
else if (bus.a_reg[15:3] == 13'h3FF) begin // exit vectors 1FF8-1FFF
|
||||||
div_automap_next <= 0;
|
automap_next <= 0;
|
||||||
end
|
end
|
||||||
else if (
|
else if (
|
||||||
bus.a_reg == 16'h0000 || // power-on/reset/rst0/software restart
|
bus.a_reg == 16'h0000 || // power-on/reset/rst0/software restart
|
||||||
@ -48,37 +49,37 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
bus.a_reg == 16'h04C6 || // tape save routine
|
bus.a_reg == 16'h04C6 || // tape save routine
|
||||||
bus.a_reg == 16'h0562 // tape load and verify routine
|
bus.a_reg == 16'h0562 // tape load and verify routine
|
||||||
) begin
|
) begin
|
||||||
div_automap_next <= 1'b1;
|
automap_next <= 1'b1;
|
||||||
end
|
end
|
||||||
else if (bus.a_reg[15:8] == 8'h3D) begin // tr-dos mapping area
|
else if (bus.a_reg[15:8] == 8'h3D) begin // tr-dos mapping area
|
||||||
div_automap_next <= 1'b1;
|
automap_next <= 1'b1;
|
||||||
div_automap <= 1'b1;
|
automap <= 1'b1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else if (!bus.m1) begin
|
else if (!bus.m1) begin
|
||||||
div_automap <= div_automap_next;
|
automap <= automap_next;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
reg spi_rd;
|
reg spi_rd;
|
||||||
reg div_conmem, div_mapram;
|
reg conmem, mapram;
|
||||||
wire port_e3_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hE3;
|
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_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_eb_cs = en && bus.ioreq && bus.a_reg[7:0] == 8'hEB;
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
spi_rd <= 0;
|
spi_rd <= 0;
|
||||||
div_page <= 0;
|
page <= 0;
|
||||||
div_mapram <= 0;
|
mapram <= 0;
|
||||||
div_conmem <= 0;
|
conmem <= 0;
|
||||||
sd_cs <= 1'b1;
|
sd_cs <= 1'b1;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
spi_rd <= port_eb_cs && bus.rd;
|
spi_rd <= port_eb_cs && bus.rd;
|
||||||
if (port_e3_cs && bus.wr) begin
|
if (port_e3_cs && bus.wr) begin
|
||||||
div_page <= bus.d_reg[3:0];
|
page <= bus.d_reg[3:0];
|
||||||
div_mapram <= bus.d_reg[6] | div_mapram;
|
mapram <= bus.d_reg[6] | mapram;
|
||||||
div_conmem <= bus.d_reg[7];
|
conmem <= bus.d_reg[7];
|
||||||
end
|
end
|
||||||
if (port_e7_cs && bus.wr) begin
|
if (port_e7_cs && bus.wr) begin
|
||||||
sd_cs <= bus.d_reg[0];
|
sd_cs <= bus.d_reg[0];
|
||||||
@ -88,7 +89,7 @@ end
|
|||||||
|
|
||||||
reg [3:0] spi_cnt;
|
reg [3:0] spi_cnt;
|
||||||
wire spi_cnt_en = ~spi_cnt[3] | spi_cnt[2] | spi_cnt[1] | spi_cnt[0];
|
wire spi_cnt_en = ~spi_cnt[3] | spi_cnt[2] | spi_cnt[1] | spi_cnt[0];
|
||||||
assign div_wait = ~spi_cnt[3];
|
assign cpuwait = ~spi_cnt[3];
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n)
|
if (!rst_n)
|
||||||
spi_cnt <= 0;
|
spi_cnt <= 0;
|
||||||
@ -125,12 +126,15 @@ always @(posedge clk28) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
assign div_map = div_automap | div_conmem;
|
assign map = automap | conmem;
|
||||||
assign div_ram = (div_conmem == 1 && bus.a[13] == 1) ||
|
assign ram =
|
||||||
(div_automap == 1 && bus.a[13] == 1) ||
|
(automap && bus.a[13]) ||
|
||||||
(div_conmem == 0 && div_automap == 1 && div_mapram == 1);
|
(conmem && bus.a[13]) ||
|
||||||
assign div_ramwr_mask = bus.a[15] == 0 && bus.a[14] == 0 &&
|
(!conmem && automap && mapram);
|
||||||
(bus.a[13] == 0 || div_page == 4'b0011) && div_conmem == 0 && div_automap == 1 && div_mapram == 1;
|
assign ramwr_mask =
|
||||||
|
!bus.a[15] && !bus.a[14] &&
|
||||||
|
(!bus.a[13] || page == 4'b0011) &&
|
||||||
|
!conmem && automap && mapram;
|
||||||
|
|
||||||
assign d_out_active = spi_rd;
|
assign d_out_active = spi_rd;
|
||||||
assign d_out = spi_reg;
|
assign d_out = spi_reg;
|
||||||
|
@ -4,26 +4,28 @@ module magic(
|
|||||||
input clk28,
|
input clk28,
|
||||||
|
|
||||||
cpu_bus bus,
|
cpu_bus bus,
|
||||||
|
output [7:0] d_out,
|
||||||
|
output d_out_active,
|
||||||
|
|
||||||
input n_int,
|
input n_int,
|
||||||
input n_int_next,
|
input n_int_next,
|
||||||
output reg n_nmi,
|
output reg n_nmi,
|
||||||
|
|
||||||
input magic_button,
|
input magic_button,
|
||||||
|
input pause_button,
|
||||||
|
input sd_cd,
|
||||||
|
input div_automap,
|
||||||
|
|
||||||
output reg magic_mode,
|
output reg magic_mode,
|
||||||
output reg magic_map,
|
output reg magic_map,
|
||||||
|
|
||||||
output reg magic_reboot,
|
output reg magic_reboot,
|
||||||
output reg magic_beeper,
|
output reg magic_beeper,
|
||||||
output timings_t timings,
|
output machine_t machine,
|
||||||
output turbo_t turbo,
|
output turbo_t turbo,
|
||||||
output rammode_t ram_mode,
|
output panning_t panning,
|
||||||
output reg joy_sinclair,
|
output reg joy_sinclair,
|
||||||
output reg rom_plus3,
|
output divmmc_t divmmc_en,
|
||||||
output reg rom_alt48,
|
|
||||||
output reg mix_acb,
|
|
||||||
output reg mix_mono,
|
|
||||||
output reg divmmc_en,
|
|
||||||
output reg ulaplus_en,
|
output reg ulaplus_en,
|
||||||
output reg covox_en,
|
output reg covox_en,
|
||||||
output reg sd_en
|
output reg sd_en
|
||||||
@ -40,7 +42,7 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
magic_unmap_next <= 0;
|
magic_unmap_next <= 0;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if (magic_button == 1'b1 && n_int == 1'b1 && n_int_next == 1'b0) begin
|
if ((magic_button || pause_button) && n_int == 1'b1 && n_int_next == 1'b0) begin
|
||||||
if (!magic_mode)
|
if (!magic_mode)
|
||||||
n_nmi <= 1'b0;
|
n_nmi <= 1'b0;
|
||||||
magic_mode <= 1'b1;
|
magic_mode <= 1'b1;
|
||||||
@ -68,20 +70,16 @@ end
|
|||||||
|
|
||||||
|
|
||||||
/* MAGIC CONFIG */
|
/* MAGIC CONFIG */
|
||||||
wire config_cs = magic_map && bus.ioreq && bus.a_reg[7:0] == 8'hff;
|
wire config_cs = magic_map && bus.ioreq && bus.a_reg[7:0] == 8'hFF;
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
magic_reboot <= 0;
|
magic_reboot <= 0;
|
||||||
magic_beeper <= 0;
|
magic_beeper <= 0;
|
||||||
timings <= TIMINGS_PENT;
|
machine <= MACHINE_PENT;
|
||||||
turbo <= TURBO_NONE;
|
turbo <= TURBO_NONE;
|
||||||
mix_acb <= 0;
|
panning <= PANNING_ABC;
|
||||||
mix_mono <= 0;
|
|
||||||
ram_mode <= RAM_512;
|
|
||||||
rom_plus3 <= 1'b1;
|
|
||||||
rom_alt48 <= 0;
|
|
||||||
joy_sinclair <= 0;
|
joy_sinclair <= 0;
|
||||||
divmmc_en <= 1'b1;
|
divmmc_en <= DIVMMC_NOOS;
|
||||||
ulaplus_en <= 1'b1;
|
ulaplus_en <= 1'b1;
|
||||||
covox_en <= 1'b1;
|
covox_en <= 1'b1;
|
||||||
sd_en <= 1'b1;
|
sd_en <= 1'b1;
|
||||||
@ -89,18 +87,29 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
else if (config_cs && bus.wr) case (bus.a_reg[15:8])
|
else if (config_cs && bus.wr) case (bus.a_reg[15:8])
|
||||||
8'h00: magic_reboot <= bus.d_reg[0];
|
8'h00: magic_reboot <= bus.d_reg[0];
|
||||||
8'h01: magic_beeper <= bus.d_reg[0];
|
8'h01: magic_beeper <= bus.d_reg[0];
|
||||||
8'h02: timings <= timings_t'(bus.d_reg[1:0]);
|
8'h02: machine <= machine_t'(bus.d_reg[2:0]);
|
||||||
8'h03: turbo <= turbo_t'(bus.d_reg[1:0]);
|
8'h03: turbo <= turbo_t'(bus.d_reg[2:0]);
|
||||||
8'h04: {mix_mono, mix_acb} <= bus.d_reg[1:0];
|
8'h04: panning <= panning_t'(bus.d_reg[1:0]);
|
||||||
8'h05: rom_plus3 <= bus.d_reg[0];
|
|
||||||
8'h06: rom_alt48 <= bus.d_reg[0];
|
|
||||||
8'h07: joy_sinclair <= bus.d_reg[0];
|
8'h07: joy_sinclair <= bus.d_reg[0];
|
||||||
8'h08: ram_mode <= rammode_t'(bus.d_reg[1:0]);
|
8'h09: divmmc_en <= divmmc_t'(bus.d_reg[1:0]);
|
||||||
8'h09: divmmc_en <= bus.d_reg[0];
|
|
||||||
8'h0a: ulaplus_en <= bus.d_reg[0];
|
8'h0a: ulaplus_en <= bus.d_reg[0];
|
||||||
8'h0b: {sd_en, covox_en} <= bus.d_reg[1:0];
|
8'h0b: {sd_en, covox_en} <= bus.d_reg[1:0];
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
reg config_rd;
|
||||||
|
wire [7:0] config_data = {4'b0000, div_automap, sd_cd, 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'hFF;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
/* BUS CONTROLLER */
|
||||||
|
assign d_out_active = config_rd;
|
||||||
|
assign d_out = config_data;
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
120
fpga/rtl/memcontrol.sv
Normal file
120
fpga/rtl/memcontrol.sv
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import common::*;
|
||||||
|
|
||||||
|
module memcontrol(
|
||||||
|
input rst_n,
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* MEMORY CONTROLLER */
|
||||||
|
reg romreq, ramreq, ramreq_wr;
|
||||||
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
romreq = 1'b0;
|
||||||
|
ramreq = 1'b0;
|
||||||
|
ramreq_wr = 1'b0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
romreq = bus.mreq && !bus.rfsh && bus.a[14] == 0 && bus.a[15] == 0 &&
|
||||||
|
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd[4] && !port_1ffd[0]));
|
||||||
|
ramreq = bus.mreq && !bus.rfsh && !romreq;
|
||||||
|
ramreq_wr = ramreq && bus.wr && div_ramwr_mask == 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign n_vrd = ((((ramreq || romreq) && 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;
|
||||||
|
|
||||||
|
/* VA[18:13] map
|
||||||
|
* 00xxxx 128Kb 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 [18:13] ram_a;
|
||||||
|
always @(posedge clk28) begin
|
||||||
|
ram_a <=
|
||||||
|
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[14] & ~bus.a[15] & bus.a[13]? {2'b01, div_page} :
|
||||||
|
div_map & ~bus.a[14] & ~bus.a[15]? {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]} :
|
||||||
|
(port_1ffd == 3'b111)? {2'b11, ~(bus.a[15] & bus.a[14]), (bus.a[15] | bus.a[14]), bus.a[14]} :
|
||||||
|
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
|
||||||
|
|
||||||
|
reg [16:14] rom_a;
|
||||||
|
always @(posedge clk28) begin
|
||||||
|
rom_a <=
|
||||||
|
magic_map? 3'd2 :
|
||||||
|
div_map? 3'd3 :
|
||||||
|
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b0)? 3'd4 :
|
||||||
|
(machine == MACHINE_S3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b1)? 3'd5 :
|
||||||
|
(machine == MACHINE_S3 && port_1ffd[2] == 1'b1 && rompage128 == 1'b0)? 3'd6 :
|
||||||
|
(rompage128 == 1'b1)? 3'd1 :
|
||||||
|
3'd0;
|
||||||
|
end
|
||||||
|
|
||||||
|
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} :
|
||||||
|
romreq? {2'b00, rom_a[16:14], bus.a[13], {13{1'bz}}} :
|
||||||
|
{ram_a[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 :
|
||||||
|
8'hFF;
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
@ -2,9 +2,6 @@ import common::*;
|
|||||||
module ports(
|
module ports(
|
||||||
input rst_n,
|
input rst_n,
|
||||||
input clk28,
|
input clk28,
|
||||||
input en_128k,
|
|
||||||
input en_plus3,
|
|
||||||
input en_profi,
|
|
||||||
input en_kempston,
|
input en_kempston,
|
||||||
input en_sinclair,
|
input en_sinclair,
|
||||||
|
|
||||||
@ -12,13 +9,12 @@ module ports(
|
|||||||
output [7:0] d_out,
|
output [7:0] d_out,
|
||||||
output d_out_active,
|
output d_out_active,
|
||||||
|
|
||||||
input timings_t timings,
|
input machine_t machine,
|
||||||
input clkcpu_ck,
|
input port_ff_active,
|
||||||
input screen_loading,
|
input [7:0] port_ff_data,
|
||||||
input [7:0] attr_next,
|
|
||||||
input [4:0] kd,
|
input [4:0] kd,
|
||||||
input [7:0] kempston_data,
|
input [7:0] kempston_data,
|
||||||
input magic_button,
|
input magic_map,
|
||||||
input tape_in,
|
input tape_in,
|
||||||
|
|
||||||
output reg tape_out,
|
output reg tape_out,
|
||||||
@ -27,21 +23,21 @@ module ports(
|
|||||||
output reg screenpage,
|
output reg screenpage,
|
||||||
output reg rompage128,
|
output reg rompage128,
|
||||||
output reg [2:0] rampage128,
|
output reg [2:0] rampage128,
|
||||||
output reg [3:0] rampage_ext,
|
output reg [2:0] rampage_ext,
|
||||||
output reg [2:0] port_1ffd,
|
output reg [2:0] port_1ffd,
|
||||||
output reg port_dffd_d3,
|
output reg [4:0] port_dffd
|
||||||
output reg port_dffd_d4
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* PORT #FF */
|
/* PORT #FF */
|
||||||
wire [7:0] port_ff_data = attr_next;
|
|
||||||
reg port_ff_rd;
|
reg port_ff_rd;
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n)
|
if (!rst_n)
|
||||||
port_ff_rd <= 0;
|
port_ff_rd <= 0;
|
||||||
else
|
else
|
||||||
port_ff_rd <= bus.rd && bus.ioreq && (timings != TIMINGS_PENT || bus.a_reg[7:0] == 8'hFF) && screen_loading;
|
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);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -56,14 +52,14 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
reg [4:0] kd0;
|
reg [4:0] kd0;
|
||||||
wire [7:0] port_fe_data = {~magic_button, tape_in, 1'b1, kd0};
|
wire [7:0] port_fe_data = {1'b1, tape_in, 1'b1, kd0};
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(negedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
beeper <= 0;
|
beeper <= 0;
|
||||||
tape_out <= 0;
|
tape_out <= 0;
|
||||||
border <= 0;
|
border <= 0;
|
||||||
end
|
end
|
||||||
else if (port_fe_cs && bus.wr && clkcpu_ck) begin // clkcpu_ck to synchronize border
|
else if (port_fe_cs && bus.wr) begin
|
||||||
beeper <= bus.d_reg[4];
|
beeper <= bus.d_reg[4];
|
||||||
tape_out <= bus.d_reg[3];
|
tape_out <= bus.d_reg[3];
|
||||||
border <= bus.d_reg[2:0];
|
border <= bus.d_reg[2:0];
|
||||||
@ -86,7 +82,9 @@ end
|
|||||||
|
|
||||||
|
|
||||||
/* PORT #7FFD */
|
/* PORT #7FFD */
|
||||||
wire port_7ffd_cs = en_128k && bus.ioreq && bus.a_reg[1] == 0 && bus.a_reg[15] == 0 && (bus.a_reg[14] == 1'b1 || !en_plus3);
|
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)) &&
|
||||||
|
(machine != MACHINE_S48 || magic_map);
|
||||||
reg lock_7ffd;
|
reg lock_7ffd;
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
@ -95,7 +93,7 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
rompage128 <= 0;
|
rompage128 <= 0;
|
||||||
lock_7ffd <= 0;
|
lock_7ffd <= 0;
|
||||||
end
|
end
|
||||||
else if (port_7ffd_cs && bus.wr && (lock_7ffd == 0 || port_dffd_d4 == 1'b1)) begin
|
else if (port_7ffd_cs && bus.wr && (lock_7ffd == 0 || port_dffd[4] == 1'b1)) begin
|
||||||
rampage128 <= bus.d_reg[2:0];
|
rampage128 <= bus.d_reg[2:0];
|
||||||
screenpage <= bus.d_reg[3];
|
screenpage <= bus.d_reg[3];
|
||||||
rompage128 <= bus.d_reg[4];
|
rompage128 <= bus.d_reg[4];
|
||||||
@ -105,23 +103,21 @@ end
|
|||||||
|
|
||||||
|
|
||||||
/* PORT #DFFD */
|
/* PORT #DFFD */
|
||||||
wire port_dffd_cs = en_profi && bus.ioreq && bus.a_reg == 16'hDFFD;
|
wire port_dffd_cs = bus.ioreq && bus.a_reg == 16'hDFFD && (machine == MACHINE_PENT || magic_map);
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
rampage_ext <= 0;
|
rampage_ext <= 0;
|
||||||
port_dffd_d3 <= 0;
|
port_dffd <= 0;
|
||||||
port_dffd_d4 <= 0;
|
|
||||||
end
|
end
|
||||||
else if (port_dffd_cs && bus.wr) begin
|
else if (port_dffd_cs && bus.wr) begin
|
||||||
rampage_ext <= bus.d_reg[2:0];
|
rampage_ext <= bus.d_reg[2:0];
|
||||||
port_dffd_d3 <= bus.d_reg[3];
|
port_dffd <= bus.d_reg[4:0];
|
||||||
port_dffd_d4 <= bus.d_reg[4];
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
/* PORT #1FFD */
|
/* PORT #1FFD */
|
||||||
wire port_1ffd_cs = en_plus3 && bus.ioreq && bus.a_reg == 16'h1FFD;
|
wire port_1ffd_cs = bus.ioreq && bus.a_reg == 16'h1FFD && (machine == MACHINE_S3 || magic_map);
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
port_1ffd <= 0;
|
port_1ffd <= 0;
|
||||||
|
@ -136,8 +136,7 @@ always @(posedge clk or negedge rst_n) begin
|
|||||||
`PS2_PGDN: key2_pgdn <= is_press;
|
`PS2_PGDN: key2_pgdn <= is_press;
|
||||||
|
|
||||||
`PS2_F5: key_magic <= is_press;
|
`PS2_F5: key_magic <= is_press;
|
||||||
`PS2_F11: key_pause <= 1'b0;
|
`PS2_F12: key_pause <= is_press;
|
||||||
`PS2_F12: key_pause <= 1'b1;
|
|
||||||
`PS2_DELETE: key2_del <= is_press;
|
`PS2_DELETE: key2_del <= is_press;
|
||||||
|
|
||||||
`PS2_KP_8: joy_up <= is_press;
|
`PS2_KP_8: joy_up <= is_press;
|
||||||
|
@ -4,12 +4,12 @@ module screen(
|
|||||||
input rst_n,
|
input rst_n,
|
||||||
input clk28,
|
input clk28,
|
||||||
|
|
||||||
input timings_t timings,
|
input machine_t machine,
|
||||||
input [2:0] border,
|
input [2:0] border,
|
||||||
|
|
||||||
output reg [2:0] r,
|
output reg [2:0] r,
|
||||||
output reg [2:0] g,
|
output reg [2:0] g,
|
||||||
output reg [2:0] b,
|
output reg [1:0] b,
|
||||||
output reg vsync,
|
output reg vsync,
|
||||||
output reg hsync,
|
output reg hsync,
|
||||||
output reg csync,
|
output reg csync,
|
||||||
@ -20,9 +20,11 @@ module screen(
|
|||||||
output [14:0] addr,
|
output [14:0] addr,
|
||||||
input [7:0] fetch_data,
|
input [7:0] fetch_data,
|
||||||
|
|
||||||
output loading,
|
output contention,
|
||||||
output blink,
|
output blink,
|
||||||
output reg [7:0] attr_next,
|
output reg even_line,
|
||||||
|
output port_ff_active,
|
||||||
|
output [7:0] port_ff_data,
|
||||||
|
|
||||||
input up_en,
|
input up_en,
|
||||||
output [5:0] up_ink_addr,
|
output [5:0] up_ink_addr,
|
||||||
@ -43,24 +45,24 @@ module screen(
|
|||||||
/* SCREEN CONTROLLER */
|
/* SCREEN CONTROLLER */
|
||||||
localparam H_AREA = 256;
|
localparam H_AREA = 256;
|
||||||
localparam V_AREA = 192;
|
localparam V_AREA = 192;
|
||||||
localparam SCREEN_DELAY = 8;
|
localparam SCREEN_DELAY = 13;
|
||||||
|
|
||||||
localparam H_LBORDER_S48 = 48 - SCREEN_DELAY;
|
localparam H_LBORDER_S48 = 54 - SCREEN_DELAY;
|
||||||
localparam H_RBORDER_S48 = 48 + SCREEN_DELAY;
|
localparam H_RBORDER_S48 = 53 + SCREEN_DELAY;
|
||||||
localparam H_BLANK1_S48 = 17;
|
localparam H_BLANK1_S48 = 12;
|
||||||
localparam H_SYNC_S48 = 33;
|
localparam H_SYNC_S48 = 33;
|
||||||
localparam H_BLANK2_S48 = 46;
|
localparam H_BLANK2_S48 = 40;
|
||||||
localparam H_TOTAL_S48 = H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48 + H_BLANK2_S48 + H_LBORDER_S48;
|
localparam H_TOTAL_S48 = H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48 + H_BLANK2_S48 + H_LBORDER_S48;
|
||||||
localparam V_BBORDER_S48 = 56;
|
localparam V_BBORDER_S48 = 56;
|
||||||
localparam V_SYNC_S48 = 8;
|
localparam V_SYNC_S48 = 8;
|
||||||
localparam V_TBORDER_S48 = 56;
|
localparam V_TBORDER_S48 = 56;
|
||||||
localparam V_TOTAL_S48 = V_AREA + V_BBORDER_S48 + V_SYNC_S48 + V_TBORDER_S48;
|
localparam V_TOTAL_S48 = V_AREA + V_BBORDER_S48 + V_SYNC_S48 + V_TBORDER_S48;
|
||||||
|
|
||||||
localparam H_LBORDER_S128 = 48 - SCREEN_DELAY;
|
localparam H_LBORDER_S128 = 58 - SCREEN_DELAY;
|
||||||
localparam H_RBORDER_S128 = 48 + SCREEN_DELAY;
|
localparam H_RBORDER_S128 = 57 + SCREEN_DELAY;
|
||||||
localparam H_BLANK1_S128 = 25;
|
localparam H_BLANK1_S128 = 12;
|
||||||
localparam H_SYNC_S128 = 33;
|
localparam H_SYNC_S128 = 33;
|
||||||
localparam H_BLANK2_S128 = 46;
|
localparam H_BLANK2_S128 = 40;
|
||||||
localparam H_TOTAL_S128 = H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128 + H_BLANK2_S128 + H_LBORDER_S128;
|
localparam H_TOTAL_S128 = H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128 + H_BLANK2_S128 + H_LBORDER_S128;
|
||||||
localparam V_BBORDER_S128 = 55;
|
localparam V_BBORDER_S128 = 55;
|
||||||
localparam V_SYNC_S128 = 8;
|
localparam V_SYNC_S128 = 8;
|
||||||
@ -78,12 +80,13 @@ localparam V_SYNC_PENT = 8;
|
|||||||
localparam V_TBORDER_PENT = 64;
|
localparam V_TBORDER_PENT = 64;
|
||||||
localparam V_TOTAL_PENT = V_AREA + V_BBORDER_PENT + V_SYNC_PENT + V_TBORDER_PENT;
|
localparam V_TOTAL_PENT = V_AREA + V_BBORDER_PENT + V_SYNC_PENT + V_TBORDER_PENT;
|
||||||
|
|
||||||
reg [`CLOG2(`MAX(V_TOTAL_S128, V_TOTAL_PENT))-1:0] vc;
|
reg [8:0] vc;
|
||||||
reg [`CLOG2(`MAX(H_TOTAL_S128, H_TOTAL_PENT))+1:0] hc0;
|
reg [10:0] hc0;
|
||||||
wire [`CLOG2(`MAX(H_TOTAL_S128, H_TOTAL_PENT))-1:0] hc = hc0[$bits(hc0)-1:2];
|
wire [8:0] hc = hc0[10:2];
|
||||||
|
|
||||||
assign vc_out = vc;
|
assign vc_out = vc;
|
||||||
assign hc_out = hc;
|
assign hc_out = hc;
|
||||||
|
|
||||||
assign clk14 = hc0[0];
|
assign clk14 = hc0[0];
|
||||||
assign clk7 = hc0[1];
|
assign clk7 = hc0[1];
|
||||||
assign clk35 = hc0[2];
|
assign clk35 = hc0[2];
|
||||||
@ -92,49 +95,49 @@ assign ck7 = hc0[0] & hc0[1];
|
|||||||
assign ck35 = hc0[0] & hc0[1] & hc0[2];
|
assign ck35 = hc0[0] & hc0[1] & hc0[2];
|
||||||
|
|
||||||
wire hc0_reset =
|
wire hc0_reset =
|
||||||
(timings == TIMINGS_PENT)?
|
(machine == MACHINE_S48)?
|
||||||
hc0 == (H_TOTAL_PENT<<2) - 1'b1 :
|
hc0 == (H_TOTAL_S48<<2) - 1'b1 :
|
||||||
(timings == TIMINGS_S128)?
|
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||||
hc0 == (H_TOTAL_S128<<2) - 1'b1 :
|
hc0 == (H_TOTAL_S128<<2) - 1'b1 :
|
||||||
// 48K
|
// Pentagon
|
||||||
hc0 == (H_TOTAL_S48<<2) - 1'b1 ;
|
hc0 == (H_TOTAL_PENT<<2) - 1'b1 ;
|
||||||
wire vc_reset =
|
wire vc_reset =
|
||||||
(timings == TIMINGS_PENT)?
|
(machine == MACHINE_S48)?
|
||||||
vc == V_TOTAL_PENT - 1'b1 :
|
vc == V_TOTAL_S48 - 1'b1:
|
||||||
(timings == TIMINGS_S128)?
|
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||||
vc == V_TOTAL_S128 - 1'b1 :
|
vc == V_TOTAL_S128 - 1'b1 :
|
||||||
// 48K
|
// Pentagon
|
||||||
vc == V_TOTAL_S48 - 1'b1;
|
vc == V_TOTAL_PENT - 1'b1 ;
|
||||||
wire hsync0 =
|
wire hsync0 =
|
||||||
(timings == TIMINGS_PENT)?
|
(machine == MACHINE_S48)?
|
||||||
(hc >= (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT)) &&
|
(hc >= (H_AREA + H_RBORDER_S48 + H_BLANK1_S48)) &&
|
||||||
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT)) :
|
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48)) :
|
||||||
(timings == TIMINGS_S128)?
|
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||||
(hc >= (H_AREA + H_RBORDER_S128 + H_BLANK1_S128)) &&
|
(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 + H_SYNC_S128)) :
|
||||||
// 48K
|
// Pentagon
|
||||||
(hc >= (H_AREA + H_RBORDER_S48 + H_BLANK1_S48)) &&
|
(hc >= (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT)) &&
|
||||||
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48)) ;
|
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT)) ;
|
||||||
wire vsync0 =
|
wire vsync0 =
|
||||||
(timings == TIMINGS_PENT)?
|
(machine == MACHINE_S48)?
|
||||||
(vc >= (V_AREA + V_BBORDER_PENT)) && (vc < (V_AREA + V_BBORDER_PENT + V_SYNC_PENT)) :
|
(vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48)) :
|
||||||
(timings == TIMINGS_S128)?
|
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||||
(vc >= (V_AREA + V_BBORDER_S128)) && (vc < (V_AREA + V_BBORDER_S128 + V_SYNC_S128)) :
|
(vc >= (V_AREA + V_BBORDER_S128)) && (vc < (V_AREA + V_BBORDER_S128 + V_SYNC_S128)) :
|
||||||
// 48K
|
// Pentagon
|
||||||
(vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48)) ;
|
(vc >= (V_AREA + V_BBORDER_PENT)) && (vc < (V_AREA + V_BBORDER_PENT + V_SYNC_PENT)) ;
|
||||||
wire blank =
|
wire blank =
|
||||||
(timings == TIMINGS_PENT)?
|
(machine == MACHINE_S48)?
|
||||||
((vc >= (V_AREA + V_BBORDER_PENT)) && (vc < (V_AREA + V_BBORDER_PENT + V_SYNC_PENT))) ||
|
((vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48))) ||
|
||||||
((hc >= (H_AREA + H_RBORDER_PENT)) &&
|
((hc >= (H_AREA + H_RBORDER_S48)) &&
|
||||||
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT + H_BLANK2_PENT))) :
|
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48 + H_BLANK2_S48))) :
|
||||||
(timings == TIMINGS_S128)?
|
(machine == MACHINE_S128 || machine == MACHINE_S3)?
|
||||||
((vc >= (V_AREA + V_BBORDER_S128)) && (vc < (V_AREA + V_BBORDER_S128 + V_SYNC_S128))) ||
|
((vc >= (V_AREA + V_BBORDER_S128)) && (vc < (V_AREA + V_BBORDER_S128 + V_SYNC_S128))) ||
|
||||||
((hc >= (H_AREA + H_RBORDER_S128)) &&
|
((hc >= (H_AREA + H_RBORDER_S128)) &&
|
||||||
(hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128 + H_BLANK2_S128))) :
|
(hc < (H_AREA + H_RBORDER_S128 + H_BLANK1_S128 + H_SYNC_S128 + H_BLANK2_S128))) :
|
||||||
// 48K
|
// Pentagon
|
||||||
((vc >= (V_AREA + V_BBORDER_S48)) && (vc < (V_AREA + V_BBORDER_S48 + V_SYNC_S48))) ||
|
((vc >= (V_AREA + V_BBORDER_PENT)) && (vc < (V_AREA + V_BBORDER_PENT + V_SYNC_PENT))) ||
|
||||||
((hc >= (H_AREA + H_RBORDER_S48)) &&
|
((hc >= (H_AREA + H_RBORDER_PENT)) &&
|
||||||
(hc < (H_AREA + H_RBORDER_S48 + H_BLANK1_S48 + H_SYNC_S48 + H_BLANK2_S48))) ;
|
(hc < (H_AREA + H_RBORDER_PENT + H_BLANK1_PENT + H_SYNC_PENT + H_BLANK2_PENT))) ;
|
||||||
|
|
||||||
|
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
@ -166,30 +169,61 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
blink_cnt <= blink_cnt + 1'b1;
|
blink_cnt <= blink_cnt + 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
reg hsync0_delayed;
|
||||||
|
always @(posedge clk28)
|
||||||
|
hsync0_delayed <= hsync0;
|
||||||
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
|
if (!rst_n)
|
||||||
|
even_line <= 0;
|
||||||
|
else if (hsync0 && !hsync0_delayed)
|
||||||
|
even_line <= ~even_line;
|
||||||
|
end
|
||||||
|
|
||||||
wire [7:0] attr_border = {2'b00, border[2:0], 3'b000};
|
|
||||||
|
|
||||||
reg [7:0] bitmap, attr, bitmap_next;
|
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'b10001;
|
||||||
|
|
||||||
|
reg [7:0] vaddr;
|
||||||
|
reg [7:3] haddr;
|
||||||
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
vaddr <= 0;
|
||||||
|
haddr <= 0;
|
||||||
|
end
|
||||||
|
else if (next_addr) begin
|
||||||
|
vaddr <= vc[7:0];
|
||||||
|
haddr <= hc[7:3];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg loading;
|
||||||
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
|
if (!rst_n)
|
||||||
|
loading <= 0;
|
||||||
|
else
|
||||||
|
loading <= (vc < V_AREA) && (hc0 > 15) && (hc0 < (H_AREA<<2) + 17);
|
||||||
|
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 fetch_step;
|
reg fetch_step;
|
||||||
wire fetch_bitmap = fetch && fetch_step == 1'd1;
|
wire fetch_bitmap = fetch && fetch_step == 2'd0;
|
||||||
wire fetch_attr = fetch && fetch_step == 1'd0;
|
wire fetch_attr = fetch && fetch_step == 2'd1;
|
||||||
|
assign fetch_next = loading && fetch_allow;
|
||||||
|
|
||||||
assign addr = fetch_bitmap?
|
assign addr = fetch_bitmap?
|
||||||
{ 2'b10, vc[7:6], vc[2:0], vc[5:3], hc[7:3] } :
|
{ 2'b10, vaddr[7:6], vaddr[2:0], vaddr[5:3], haddr[7:3] } :
|
||||||
{ 5'b10110, vc[7:3], hc[7:3] };
|
{ 5'b10110, vaddr[7:3], haddr[7:3] };
|
||||||
|
|
||||||
reg [7:0] up_ink0, up_paper0;
|
|
||||||
assign up_ink_addr = { attr_next[7:6], 1'b0, attr_next[2:0] };
|
assign up_ink_addr = { attr_next[7:6], 1'b0, attr_next[2:0] };
|
||||||
assign up_paper_addr = { attr_next[7:6], 1'b1, attr_next[5:3] };
|
assign up_paper_addr = { attr_next[7:6], 1'b1, attr_next[5:3] };
|
||||||
|
|
||||||
assign loading = (vc < V_AREA) && (hc < H_AREA || hc0_reset);
|
|
||||||
wire screen_show = (vc < V_AREA) && (hc0 >= (SCREEN_DELAY<<2) - 2) && (hc0 < ((H_AREA + SCREEN_DELAY)<<2) - 2);
|
|
||||||
wire screen_update = vc < V_AREA && hc <= H_AREA && hc != 0 && hc0[4:0] == 5'b11110;
|
|
||||||
wire border_update = !screen_show && ((timings == TIMINGS_PENT && ck7) || hc0[4:0] == 5'b11110);
|
|
||||||
wire bitmap_shift = hc0[1:0] == 2'b10;
|
|
||||||
|
|
||||||
assign fetch_next = loading && fetch_allow;
|
|
||||||
|
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
always @(posedge clk28 or negedge rst_n) begin
|
||||||
if (!rst_n) begin
|
if (!rst_n) begin
|
||||||
fetch <= 0;
|
fetch <= 0;
|
||||||
@ -198,12 +232,14 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
bitmap <= 0;
|
bitmap <= 0;
|
||||||
attr_next <= 0;
|
attr_next <= 0;
|
||||||
bitmap_next <= 0;
|
bitmap_next <= 0;
|
||||||
|
up_ink0 <= 0;
|
||||||
|
up_paper0 <= 0;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if (ck14) begin
|
if (ck14) begin
|
||||||
if (fetch)
|
if (fetch)
|
||||||
fetch_step <= fetch_step + 1'b1;
|
fetch_step <= fetch_step + 1'b1;
|
||||||
fetch <= fetch_next;
|
fetch <= fetch_allow;
|
||||||
|
|
||||||
if (fetch_attr)
|
if (fetch_attr)
|
||||||
attr_next <= fetch_data;
|
attr_next <= fetch_data;
|
||||||
@ -211,12 +247,14 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
attr_next <= attr_border;
|
attr_next <= attr_border;
|
||||||
if (fetch_bitmap)
|
if (fetch_bitmap)
|
||||||
bitmap_next <= fetch_data;
|
bitmap_next <= fetch_data;
|
||||||
|
else if (!loading)
|
||||||
|
bitmap_next <= 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (border_update)
|
if (screen_show && screen_update)
|
||||||
attr <= attr_border;
|
|
||||||
else if (screen_update)
|
|
||||||
attr <= attr_next;
|
attr <= attr_next;
|
||||||
|
else if (!screen_show && border_update)
|
||||||
|
attr <= attr_border;
|
||||||
|
|
||||||
if (screen_update)
|
if (screen_update)
|
||||||
bitmap <= bitmap_next;
|
bitmap <= bitmap_next;
|
||||||
@ -225,28 +263,42 @@ always @(posedge clk28 or negedge rst_n) begin
|
|||||||
|
|
||||||
if (screen_update)
|
if (screen_update)
|
||||||
up_ink0 <= up_ink;
|
up_ink0 <= up_ink;
|
||||||
if (screen_update || (!screen_show && !loading))
|
if (screen_update)
|
||||||
up_paper0 <= up_paper;
|
up_paper0 <= up_paper;
|
||||||
end
|
end
|
||||||
end
|
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_data =
|
||||||
|
port_ff_attr? attr_next :
|
||||||
|
port_ff_bitmap? bitmap_next :
|
||||||
|
8'hFF;
|
||||||
|
|
||||||
|
assign contention = (vc < V_AREA) && (hc < H_AREA) && (hc[2] || hc[3]);
|
||||||
|
|
||||||
|
|
||||||
/* RGBS generation */
|
/* RGBS generation */
|
||||||
wire pixel = bitmap[7];
|
wire pixel = bitmap[7];
|
||||||
always @(posedge clk28) begin
|
always @(posedge clk28) begin
|
||||||
if (blank)
|
if (blank)
|
||||||
{g, r, b} = 0;
|
{g, r, b} = 0;
|
||||||
else if (up_en) begin
|
else if (up_en) begin
|
||||||
g = pixel? up_ink0[7:5] : up_paper0[7:5];
|
g = pixel? up_ink0[7:5] : up_paper0[7:5];
|
||||||
r = pixel? up_ink0[4:2] : up_paper0[4:2];
|
r = pixel? up_ink0[4:2] : up_paper0[4:2];
|
||||||
b[2:1] = pixel? up_ink0[1:0] : up_paper0[1:0];
|
b = pixel? up_ink0[1:0] : up_paper0[1:0];
|
||||||
b[0] = |b[2:1];
|
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
{g[2], r[2], b[2]} = (pixel ^ (attr[7] & blink))? attr[2:0] : attr[5:3];
|
{g[2], r[2], b[1]} = (pixel ^ (attr[7] & blink))? attr[2:0] : attr[5:3];
|
||||||
{g[1], r[1], b[1]} = {g[2] & attr[6], r[2] & attr[6], b[2] & attr[6]};
|
{g[1], r[1], b[0]} = {g[2] & attr[6], r[2] & attr[6], b[1] & attr[6]};
|
||||||
{g[0], r[0], b[0]} = {g[2], r[2], b[2]};
|
{g[0], r[0]} = {g[2], r[2]};
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk28) begin
|
||||||
csync = ~(vsync0 ^ hsync0);
|
csync = ~(vsync0 ^ hsync0);
|
||||||
vsync = ~vsync0;
|
vsync = ~vsync0;
|
||||||
hsync = ~hsync0;
|
hsync = ~hsync0;
|
||||||
|
227
fpga/rtl/top.sv
227
fpga/rtl/top.sv
@ -48,11 +48,9 @@ pll pll0(.inclk0(clk_in), .c0(clk40), .c1(clk20), .locked(rst_n));
|
|||||||
|
|
||||||
|
|
||||||
/* SHARED DEFINITIONS */
|
/* SHARED DEFINITIONS */
|
||||||
timings_t timings;
|
machine_t machine;
|
||||||
turbo_t turbo;
|
turbo_t turbo;
|
||||||
rammode_t ram_mode;
|
wire ps2_key_reset, ps2_key_pause;
|
||||||
reg pause = 0;
|
|
||||||
wire ps2_key_pause, ps2_key_reset;
|
|
||||||
wire [2:0] border;
|
wire [2:0] border;
|
||||||
wire magic_reboot, magic_beeper;
|
wire magic_reboot, magic_beeper;
|
||||||
wire up_active;
|
wire up_active;
|
||||||
@ -102,30 +100,25 @@ always @(posedge clk28) begin
|
|||||||
usrrst_n <= (!rst_n || ps2_key_reset || magic_reboot)? 1'b0 : 1'b1;
|
usrrst_n <= (!rst_n || ps2_key_reset || magic_reboot)? 1'b0 : 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
/* PAUSE */
|
|
||||||
always @(posedge clk28) begin
|
|
||||||
if (n_int == 1'b0 && bus.rfsh)
|
|
||||||
pause <= ps2_key_pause;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
/* SCREEN CONTROLLER */
|
/* SCREEN CONTROLLER */
|
||||||
wire blink;
|
wire blink;
|
||||||
wire [2:0] screen_border = {border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0] ^ (pause & blink)};
|
wire [2:0] screen_border = {border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0]};
|
||||||
wire [2:0] r, g, b;
|
wire [2:0] r, g;
|
||||||
|
wire [1:0] b;
|
||||||
wire hsync;
|
wire hsync;
|
||||||
|
wire screen_contention, port_ff_active;
|
||||||
|
wire [14:0] screen_addr;
|
||||||
wire [5:0] up_ink_addr, up_paper_addr;
|
wire [5:0] up_ink_addr, up_paper_addr;
|
||||||
wire [7:0] up_ink, up_paper;
|
wire [7:0] up_ink, up_paper;
|
||||||
wire screen_loading;
|
|
||||||
wire [14:0] screen_addr;
|
|
||||||
wire [7:0] attr_next;
|
|
||||||
wire [8:0] vc, hc;
|
wire [8:0] vc, hc;
|
||||||
|
wire [7:0] port_ff_data;
|
||||||
wire clk14, clk7, clk35, ck14, ck7, ck35;
|
wire clk14, clk7, clk35, ck14, ck7, ck35;
|
||||||
screen screen0(
|
screen screen0(
|
||||||
.rst_n(rst_n),
|
.rst_n(usrrst_n),
|
||||||
.clk28(clk28),
|
.clk28(clk28),
|
||||||
|
|
||||||
.timings(timings),
|
.machine(machine),
|
||||||
.border(screen_border),
|
.border(screen_border),
|
||||||
|
|
||||||
.r(r),
|
.r(r),
|
||||||
@ -141,16 +134,17 @@ screen screen0(
|
|||||||
.fetch_next(screen_fetch_next),
|
.fetch_next(screen_fetch_next),
|
||||||
.fetch_data(bus.d),
|
.fetch_data(bus.d),
|
||||||
|
|
||||||
.loading(screen_loading),
|
|
||||||
.blink(blink),
|
|
||||||
.attr_next(attr_next),
|
|
||||||
|
|
||||||
.up_en(up_active),
|
.up_en(up_active),
|
||||||
.up_ink_addr(up_ink_addr),
|
.up_ink_addr(up_ink_addr),
|
||||||
.up_paper_addr(up_paper_addr),
|
.up_paper_addr(up_paper_addr),
|
||||||
.up_ink(up_ink),
|
.up_ink(up_ink),
|
||||||
.up_paper(up_paper),
|
.up_paper(up_paper),
|
||||||
|
|
||||||
|
.contention(screen_contention),
|
||||||
|
.blink(blink),
|
||||||
|
.port_ff_active(port_ff_active),
|
||||||
|
.port_ff_data(port_ff_data),
|
||||||
|
|
||||||
.vc_out(vc),
|
.vc_out(vc),
|
||||||
.hc_out(hc),
|
.hc_out(hc),
|
||||||
.clk14(clk14),
|
.clk14(clk14),
|
||||||
@ -210,16 +204,17 @@ cpucontrol cpucontrol0(
|
|||||||
.clk14(clk14),
|
.clk14(clk14),
|
||||||
.clk7(clk7),
|
.clk7(clk7),
|
||||||
.clk35(clk35),
|
.clk35(clk35),
|
||||||
|
.ck14(ck14),
|
||||||
|
.ck7(ck7),
|
||||||
|
|
||||||
.bus(bus),
|
.bus(bus),
|
||||||
|
|
||||||
.vc(vc),
|
.vc(vc),
|
||||||
.hc(hc),
|
.hc(hc),
|
||||||
.rampage128(rampage128),
|
.rampage128(rampage128),
|
||||||
.screen_loading(screen_loading),
|
.machine(machine),
|
||||||
|
.screen_contention(screen_contention),
|
||||||
.turbo(turbo),
|
.turbo(turbo),
|
||||||
.timings(timings),
|
|
||||||
.pause(pause),
|
|
||||||
.ext_wait_cycle(div_wait || up_active),
|
.ext_wait_cycle(div_wait || up_active),
|
||||||
.init_done_in(init_done),
|
.init_done_in(init_done),
|
||||||
|
|
||||||
@ -234,32 +229,39 @@ cpucontrol cpucontrol0(
|
|||||||
|
|
||||||
|
|
||||||
/* MAGIC */
|
/* MAGIC */
|
||||||
|
wire div_automap;
|
||||||
|
wire [7:0] magic_dout;
|
||||||
|
wire magic_dout_active;
|
||||||
wire magic_mode, magic_map;
|
wire magic_mode, magic_map;
|
||||||
wire divmmc_en, joy_sinclair, rom_plus3, rom_alt48, mix_acb, mix_mono, up_en, covox_en, sd_en;
|
wire joy_sinclair, up_en, covox_en, sd_en;
|
||||||
|
panning_t panning;
|
||||||
|
divmmc_t divmmc_en;
|
||||||
magic magic0(
|
magic magic0(
|
||||||
.rst_n(usrrst_n),
|
.rst_n(n_rstcpu),
|
||||||
.clk28(clk28),
|
.clk28(clk28),
|
||||||
|
|
||||||
.bus(bus),
|
.bus(bus),
|
||||||
|
.d_out(magic_dout),
|
||||||
|
.d_out_active(magic_dout_active),
|
||||||
|
|
||||||
.n_int(n_int),
|
.n_int(n_int),
|
||||||
.n_int_next(n_int_next),
|
.n_int_next(n_int_next),
|
||||||
.n_nmi(n_nmi),
|
.n_nmi(n_nmi),
|
||||||
|
|
||||||
.magic_button(ps2_key_magic),
|
.magic_button(ps2_key_magic),
|
||||||
|
.pause_button(ps2_key_pause),
|
||||||
|
.sd_cd(sd_cd),
|
||||||
|
.div_automap(div_automap),
|
||||||
|
|
||||||
.magic_mode(magic_mode),
|
.magic_mode(magic_mode),
|
||||||
.magic_map(magic_map),
|
.magic_map(magic_map),
|
||||||
|
|
||||||
.magic_reboot(magic_reboot),
|
.magic_reboot(magic_reboot),
|
||||||
.magic_beeper(magic_beeper),
|
.magic_beeper(magic_beeper),
|
||||||
.timings(timings),
|
.machine(machine),
|
||||||
.turbo(turbo),
|
.turbo(turbo),
|
||||||
.ram_mode(ram_mode),
|
|
||||||
.joy_sinclair(joy_sinclair),
|
.joy_sinclair(joy_sinclair),
|
||||||
.rom_plus3(rom_plus3),
|
.panning(panning),
|
||||||
.rom_alt48(rom_alt48),
|
|
||||||
.mix_acb(mix_acb),
|
|
||||||
.mix_mono(mix_mono),
|
|
||||||
.divmmc_en(divmmc_en),
|
.divmmc_en(divmmc_en),
|
||||||
.ulaplus_en(up_en),
|
.ulaplus_en(up_en),
|
||||||
.covox_en(covox_en),
|
.covox_en(covox_en),
|
||||||
@ -273,31 +275,26 @@ wire ports_dout_active;
|
|||||||
wire beeper, tape_out;
|
wire beeper, tape_out;
|
||||||
wire screenpage;
|
wire screenpage;
|
||||||
wire rompage128;
|
wire rompage128;
|
||||||
wire [3:0] rampage_ext;
|
wire [2:0] rampage_ext;
|
||||||
wire [2:0] port_1ffd;
|
wire [2:0] port_1ffd;
|
||||||
wire port_dffd_d3;
|
wire [4:0] port_dffd;
|
||||||
wire port_dffd_d4;
|
|
||||||
ports ports0 (
|
ports ports0 (
|
||||||
.rst_n(usrrst_n),
|
.rst_n(n_rstcpu),
|
||||||
.clk28(clk28),
|
.clk28(clk28),
|
||||||
|
|
||||||
.bus(bus),
|
.bus(bus),
|
||||||
.d_out(ports_dout),
|
.d_out(ports_dout),
|
||||||
.d_out_active(ports_dout_active),
|
.d_out_active(ports_dout_active),
|
||||||
|
|
||||||
.en_128k(ram_mode == RAM_512 || ram_mode == RAM_128),
|
|
||||||
.en_plus3(rom_plus3),
|
|
||||||
.en_profi(ram_mode == RAM_512),
|
|
||||||
.en_kempston(!joy_sinclair),
|
.en_kempston(!joy_sinclair),
|
||||||
.en_sinclair(joy_sinclair),
|
.en_sinclair(joy_sinclair),
|
||||||
|
|
||||||
.timings(timings),
|
.machine(machine),
|
||||||
.clkcpu_ck(clkcpu_ck),
|
.port_ff_active(port_ff_active),
|
||||||
.screen_loading(screen_loading),
|
.port_ff_data(port_ff_data),
|
||||||
.attr_next(attr_next),
|
|
||||||
.kd(ps2_kd),
|
.kd(ps2_kd),
|
||||||
.kempston_data({3'b000, ps2_joy_fire, ps2_joy_up, ps2_joy_down, ps2_joy_left, ps2_joy_right}),
|
.kempston_data({3'b000, ps2_joy_fire, ps2_joy_up, ps2_joy_down, ps2_joy_left, ps2_joy_right}),
|
||||||
.magic_button(ps2_key_magic),
|
.magic_map(magic_map),
|
||||||
.tape_in(sd_miso_tape_in),
|
.tape_in(sd_miso_tape_in),
|
||||||
|
|
||||||
.tape_out(tape_out),
|
.tape_out(tape_out),
|
||||||
@ -308,8 +305,7 @@ ports ports0 (
|
|||||||
.rampage128(rampage128),
|
.rampage128(rampage128),
|
||||||
.rampage_ext(rampage_ext),
|
.rampage_ext(rampage_ext),
|
||||||
.port_1ffd(port_1ffd),
|
.port_1ffd(port_1ffd),
|
||||||
.port_dffd_d3(port_dffd_d3),
|
.port_dffd(port_dffd)
|
||||||
.port_dffd_d4(port_dffd_d4)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -318,7 +314,7 @@ wire turbosound_dout_active;
|
|||||||
wire [7:0] turbosound_dout;
|
wire [7:0] turbosound_dout;
|
||||||
wire [7:0] ay_a0, ay_b0, ay_c0, ay_a1, ay_b1, ay_c1;
|
wire [7:0] ay_a0, ay_b0, ay_c0, ay_a1, ay_b1, ay_c1;
|
||||||
turbosound turbosound0(
|
turbosound turbosound0(
|
||||||
.rst_n(usrrst_n),
|
.rst_n(n_rstcpu),
|
||||||
.clk28(clk28),
|
.clk28(clk28),
|
||||||
.ck35(ck35),
|
.ck35(ck35),
|
||||||
.en(1'b1),
|
.en(1'b1),
|
||||||
@ -328,8 +324,6 @@ turbosound turbosound0(
|
|||||||
.d_out(turbosound_dout),
|
.d_out(turbosound_dout),
|
||||||
.d_out_active(turbosound_dout_active),
|
.d_out_active(turbosound_dout_active),
|
||||||
|
|
||||||
.pause(pause),
|
|
||||||
|
|
||||||
.ay_a0(ay_a0),
|
.ay_a0(ay_a0),
|
||||||
.ay_b0(ay_b0),
|
.ay_b0(ay_b0),
|
||||||
.ay_c0(ay_c0),
|
.ay_c0(ay_c0),
|
||||||
@ -355,10 +349,9 @@ soundrive soundrive0(
|
|||||||
.ch_r1(soundrive_r1)
|
.ch_r1(soundrive_r1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* SOUND MIXER */
|
/* SOUND MIXER */
|
||||||
mixer mixer0(
|
mixer mixer0(
|
||||||
.rst_n(rst_n),
|
.rst_n(usrrst_n),
|
||||||
.clk28(clk28),
|
.clk28(clk28),
|
||||||
|
|
||||||
.beeper(beeper ^ magic_beeper),
|
.beeper(beeper ^ magic_beeper),
|
||||||
@ -375,8 +368,8 @@ mixer mixer0(
|
|||||||
.sd_r0(soundrive_r0),
|
.sd_r0(soundrive_r0),
|
||||||
.sd_r1(soundrive_r1),
|
.sd_r1(soundrive_r1),
|
||||||
|
|
||||||
.ay_acb(mix_acb),
|
.ay_acb(panning == PANNING_ABC),
|
||||||
.mono(mix_mono),
|
.mono(panning == PANNING_MONO),
|
||||||
|
|
||||||
.dac_l(snd_l),
|
.dac_l(snd_l),
|
||||||
.dac_r(snd_r)
|
.dac_r(snd_r)
|
||||||
@ -389,12 +382,12 @@ wire [7:0] div_dout;
|
|||||||
wire [3:0] div_page;
|
wire [3:0] div_page;
|
||||||
wire sd_mosi0;
|
wire sd_mosi0;
|
||||||
divmmc divmmc0(
|
divmmc divmmc0(
|
||||||
.rst_n(usrrst_n),
|
.rst_n(n_rstcpu),
|
||||||
.clk28(clk28),
|
.clk28(clk28),
|
||||||
.ck14(ck14),
|
.ck14(ck14),
|
||||||
.ck7(ck7),
|
.ck7(ck7),
|
||||||
.en(divmmc_en),
|
.en(divmmc_en == DIVMMC_ON || divmmc_en == DIVMMC_NOOS),
|
||||||
.en_hooks(~sd_cd),
|
.en_hooks(divmmc_en == DIVMMC_ON),
|
||||||
|
|
||||||
.bus(bus),
|
.bus(bus),
|
||||||
.d_out(div_dout),
|
.d_out(div_dout),
|
||||||
@ -405,15 +398,16 @@ divmmc divmmc0(
|
|||||||
.sd_sck(sd_sck),
|
.sd_sck(sd_sck),
|
||||||
.sd_cs(sd_cs),
|
.sd_cs(sd_cs),
|
||||||
|
|
||||||
.rammap(port_dffd_d4 | port_1ffd[0]),
|
.rammap(port_dffd[4] | port_1ffd[0]),
|
||||||
.magic_mode(magic_mode),
|
.magic_mode(magic_mode),
|
||||||
.magic_map(magic_map),
|
.magic_map(magic_map),
|
||||||
|
|
||||||
.div_page(div_page),
|
.page(div_page),
|
||||||
.div_map(div_map),
|
.map(div_map),
|
||||||
.div_ram(div_ram),
|
.automap(div_automap),
|
||||||
.div_ramwr_mask(div_ramwr_mask),
|
.ram(div_ram),
|
||||||
.div_wait(div_wait)
|
.ramwr_mask(div_ramwr_mask),
|
||||||
|
.cpuwait(div_wait)
|
||||||
);
|
);
|
||||||
assign sd_mosi = (~sd_cd)? sd_mosi0 : tape_out;
|
assign sd_mosi = (~sd_cd)? sd_mosi0 : tape_out;
|
||||||
|
|
||||||
@ -422,7 +416,7 @@ assign sd_mosi = (~sd_cd)? sd_mosi0 : tape_out;
|
|||||||
wire up_dout_active;
|
wire up_dout_active;
|
||||||
wire [7:0] up_dout;
|
wire [7:0] up_dout;
|
||||||
ulaplus ulaplus0(
|
ulaplus ulaplus0(
|
||||||
.rst_n(usrrst_n),
|
.rst_n(n_rstcpu),
|
||||||
.clk28(clk28),
|
.clk28(clk28),
|
||||||
.en(up_en),
|
.en(up_en),
|
||||||
|
|
||||||
@ -484,77 +478,46 @@ asmi asmi0(
|
|||||||
|
|
||||||
|
|
||||||
/* MEMORY CONTROLLER */
|
/* MEMORY CONTROLLER */
|
||||||
reg romreq, ramreq, ramreq_wr;
|
memcontrol memcontrol0(
|
||||||
always @(posedge clk28 or negedge rst_n) begin
|
.rst_n(rst_n),
|
||||||
if (!rst_n) begin
|
.clk28(clk28),
|
||||||
romreq = 1'b0;
|
.bus(bus),
|
||||||
ramreq = 1'b0;
|
.va(va),
|
||||||
ramreq_wr = 1'b0;
|
.vd(vd),
|
||||||
end
|
.n_vrd(n_vrd),
|
||||||
else begin
|
.n_vwr(n_vwr),
|
||||||
romreq = bus.mreq && !bus.rfsh && bus.a[14] == 0 && bus.a[15] == 0 &&
|
|
||||||
(magic_map || (!div_ram && div_map) || (!div_ram && !port_dffd_d4 && !port_1ffd[0]));
|
|
||||||
ramreq = bus.mreq && !bus.rfsh && !romreq;
|
|
||||||
ramreq_wr = ramreq && bus.wr && div_ramwr_mask == 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign n_vrd = ((((ramreq || romreq) && bus.rd) || screen_fetch) && !rom2ram_ram_wren)? 1'b0 : 1'b1;
|
.machine(machine),
|
||||||
assign n_vwr = ((ramreq_wr && bus.wr && !screen_fetch) || rom2ram_ram_wren)? 1'b0 : 1'b1;
|
.screenpage(screenpage),
|
||||||
|
.screen_fetch(screen_fetch),
|
||||||
|
.snow(snow),
|
||||||
|
.screen_addr(screen_addr),
|
||||||
|
.magic_map(magic_map),
|
||||||
|
.rampage128(rampage128),
|
||||||
|
.rompage128(rompage128),
|
||||||
|
.port_1ffd(port_1ffd),
|
||||||
|
.port_dffd(port_dffd),
|
||||||
|
.rampage_ext(rampage_ext),
|
||||||
|
.divmmc_en(divmmc_en != DIVMMC_OFF),
|
||||||
|
.div_ram(div_ram),
|
||||||
|
.div_map(div_map),
|
||||||
|
.div_ramwr_mask(div_ramwr_mask),
|
||||||
|
.div_page(div_page),
|
||||||
|
|
||||||
/* VA[18:13] map
|
.rom2ram_ram_address(rom2ram_ram_address),
|
||||||
* 00xxxx 128Kb of roms
|
.rom2ram_ram_wren(rom2ram_ram_wren),
|
||||||
* 00111x 16Kb of magic ram
|
.rom2ram_dataout(rom2ram_dataout),
|
||||||
* 01xxxx 128Kb of divmmc memory
|
.magic_dout_active(magic_dout_active),
|
||||||
* 10xxxx 128Kb of extended ram (via port dffd)
|
.magic_dout(magic_dout),
|
||||||
* 11xxxx 128Kb of main ram
|
.up_dout_active(up_dout_active),
|
||||||
*/
|
.up_dout(up_dout),
|
||||||
|
.div_dout_active(div_dout_active),
|
||||||
reg [18:13] ram_a;
|
.div_dout(div_dout),
|
||||||
always @(posedge clk28) begin
|
.turbosound_dout_active(turbosound_dout_active),
|
||||||
ram_a <=
|
.turbosound_dout(turbosound_dout),
|
||||||
magic_map & bus.a[15] & bus.a[14]? {2'b00, 3'b111, bus.a[13]} :
|
.ports_dout_active(ports_dout_active),
|
||||||
magic_map? {3'b111, screenpage, bus.a[14:13]} :
|
.ports_dout(ports_dout)
|
||||||
div_map & ~bus.a[14] & ~bus.a[15] & bus.a[13]? {2'b01, div_page} :
|
);
|
||||||
div_map & ~bus.a[14] & ~bus.a[15]? {2'b01, 4'b0011} :
|
|
||||||
port_dffd_d3 & bus.a[15]? {2'b11, bus.a[14], bus.a[15], bus.a[14], bus.a[13]} :
|
|
||||||
port_dffd_d3 & 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]} :
|
|
||||||
(port_1ffd == 3'b111)? {2'b11, ~(bus.a[15] & bus.a[14]), (bus.a[15] | bus.a[14]), bus.a[14]} :
|
|
||||||
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
|
|
||||||
|
|
||||||
reg [16:14] rom_a;
|
|
||||||
always @(posedge clk28) begin
|
|
||||||
rom_a <=
|
|
||||||
magic_map? 3'd2 :
|
|
||||||
div_map? 3'd3 :
|
|
||||||
(rom_plus3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b0)? 3'd4 :
|
|
||||||
(rom_plus3 && port_1ffd[2] == 1'b0 && rompage128 == 1'b1)? 3'd5 :
|
|
||||||
(rom_plus3 && port_1ffd[2] == 1'b1 && rompage128 == 1'b0)? 3'd6 :
|
|
||||||
(rompage128 == 1'b1 && rom_alt48 == 1'b1)? 3'd7 :
|
|
||||||
(rompage128 == 1'b1)? 3'd1 :
|
|
||||||
3'd0;
|
|
||||||
end
|
|
||||||
|
|
||||||
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} :
|
|
||||||
romreq? {2'b00, rom_a[16:14], bus.a[13], {13{1'bz}}} :
|
|
||||||
{ram_a[18:13], {13{1'bz}}};
|
|
||||||
|
|
||||||
assign vd[7:0] =
|
|
||||||
~n_vrd? {8{1'bz}} :
|
|
||||||
rom2ram_ram_wren? rom2ram_dataout :
|
|
||||||
up_dout_active? up_dout :
|
|
||||||
div_dout_active? div_dout :
|
|
||||||
turbosound_dout_active? turbosound_dout :
|
|
||||||
ports_dout_active? ports_dout :
|
|
||||||
~n_wr? {8{1'bz}} :
|
|
||||||
8'hFF;
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -166,6 +166,7 @@ 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/magic.sv
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/divmmc.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/cpucontrol.sv
|
||||||
|
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/memcontrol.sv
|
||||||
set_global_assignment -name VERILOG_FILE ../rtl/chroma_gen.v
|
set_global_assignment -name VERILOG_FILE ../rtl/chroma_gen.v
|
||||||
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
|
set_global_assignment -name SYSTEMVERILOG_FILE ../rtl/turbosound.sv
|
||||||
set_global_assignment -name VHDL_FILE ../rtl/ym2149.vhd
|
set_global_assignment -name VHDL_FILE ../rtl/ym2149.vhd
|
||||||
|
@ -5,6 +5,7 @@ SRC_T80=./t80/t80n_pack.vhd ./t80/t80n.vhd ./t80/t80n_alu.vhd ./t80/t80n_mcode.v
|
|||||||
all: testbench_zx_ula
|
all: testbench_zx_ula
|
||||||
|
|
||||||
testbench_zx_ula: IVFLAGS+=-I./az80/ -I./t80/ -I../rtl/
|
testbench_zx_ula: IVFLAGS+=-I./az80/ -I./t80/ -I../rtl/
|
||||||
|
testbench_zx_ula: VLOGFLAGS+=+define+TESTBENCH
|
||||||
testbench_zx_ula: testbench_zx_ula.v ../rtl/common.sv $(wildcard stubs/*.v ../rtl/*.vhd ../rtl/*.v ../rtl/*.sv)
|
testbench_zx_ula: testbench_zx_ula.v ../rtl/common.sv $(wildcard stubs/*.v ../rtl/*.vhd ../rtl/*.v ../rtl/*.sv)
|
||||||
testbench_zx_ula: ${SRC_T80}
|
testbench_zx_ula: ${SRC_T80}
|
||||||
testbench_zx_ula: rom.mem
|
testbench_zx_ula: rom.mem
|
||||||
|
@ -1,26 +1,19 @@
|
|||||||
DEVICE ZXSPECTRUM48
|
DEVICE ZXSPECTRUM48
|
||||||
|
|
||||||
ORG #0000
|
ORG #8000 // mapped #0000
|
||||||
Start:
|
Start:
|
||||||
nop
|
nop
|
||||||
jp Main
|
jp #1000
|
||||||
|
|
||||||
ORG #0038
|
ORG #8038
|
||||||
Int1:
|
Int1:
|
||||||
jp #1ff8
|
reti
|
||||||
ORG #00FF
|
|
||||||
DB #38
|
|
||||||
|
|
||||||
ORG #0066
|
ORG #8066
|
||||||
Nmi:
|
Nmi:
|
||||||
jp #1ffa
|
|
||||||
push af
|
|
||||||
ld a, #08
|
|
||||||
out (#ff), a
|
|
||||||
pop af
|
|
||||||
retn
|
retn
|
||||||
|
|
||||||
ORG #1000
|
ORG #9000
|
||||||
Main:
|
Main:
|
||||||
im 2
|
im 2
|
||||||
ei
|
ei
|
||||||
@ -46,15 +39,8 @@ Main:
|
|||||||
jp #1fff
|
jp #1fff
|
||||||
Loop:
|
Loop:
|
||||||
halt
|
halt
|
||||||
jp Loop
|
jr Loop
|
||||||
|
|
||||||
ORG #1FF8 // DivROM exit vector
|
|
||||||
reti
|
|
||||||
ORG #1FFA // DivROM exit vector
|
|
||||||
retn
|
|
||||||
ORG #1FFF // DivROM exit vector
|
|
||||||
nop
|
|
||||||
jp #3D00
|
|
||||||
|
|
||||||
ORG #C000 // mapped #0000
|
ORG #C000 // mapped #0000
|
||||||
DivROM_Start:
|
DivROM_Start:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
`timescale 100ps/10ps
|
`timescale 1ns/100ps
|
||||||
module testbench_zx_ula();
|
module testbench_zx_ula();
|
||||||
|
|
||||||
reg rst_n;
|
reg rst_n;
|
||||||
@ -6,7 +6,8 @@ reg clk28;
|
|||||||
|
|
||||||
|
|
||||||
/* CPU */
|
/* CPU */
|
||||||
wire rstcpu_n;
|
wire clkcpu;
|
||||||
|
wire n_rstcpu;
|
||||||
wire [15:0] a_cpu, a_cpu_cpu;
|
wire [15:0] a_cpu, a_cpu_cpu;
|
||||||
wire [7:0] d_cpu_o, d_cpu_i;
|
wire [7:0] d_cpu_o, d_cpu_i;
|
||||||
wire n_rd, n_rd_cpu;
|
wire n_rd, n_rd_cpu;
|
||||||
@ -19,7 +20,7 @@ wire n_int;
|
|||||||
wire n_nmi;
|
wire n_nmi;
|
||||||
|
|
||||||
T80na cpu1(
|
T80na cpu1(
|
||||||
.RESET_n(rstcpu_n),
|
.RESET_n(n_rstcpu),
|
||||||
.CLK_n(clkcpu),
|
.CLK_n(clkcpu),
|
||||||
.WAIT_n(1'b1),
|
.WAIT_n(1'b1),
|
||||||
.INT_n(n_int),
|
.INT_n(n_int),
|
||||||
@ -72,7 +73,7 @@ wire sd_mosi_miso;
|
|||||||
zx_ula zx_ula1(
|
zx_ula zx_ula1(
|
||||||
.clk_in(clk28),
|
.clk_in(clk28),
|
||||||
.clkcpu(clkcpu),
|
.clkcpu(clkcpu),
|
||||||
.n_rstcpu(rstcpu_n),
|
.n_rstcpu(n_rstcpu),
|
||||||
.a(a_cpu[15:13]),
|
.a(a_cpu[15:13]),
|
||||||
.vd(vd),
|
.vd(vd),
|
||||||
.va(va),
|
.va(va),
|
||||||
@ -138,51 +139,63 @@ assign d_cpu_i = vd;
|
|||||||
// assign a_cpu = a_cpu_cpu;
|
// assign a_cpu = a_cpu_cpu;
|
||||||
|
|
||||||
/* CPU SIGNALS (Z84C0020 timings) */
|
/* CPU SIGNALS (Z84C0020 timings) */
|
||||||
assign #400 n_rd = n_rd_cpu; //TdCf(RDf)
|
assign #40 n_rd = n_rd_cpu; //TdCf(RDf)
|
||||||
assign #400 n_wr = n_wr_cpu; //TdCf(WRf)
|
assign #40 n_wr = n_wr_cpu; //TdCf(WRf)
|
||||||
assign #400 n_iorq = n_iorq_cpu; //TdCr(IORQf)
|
assign #40 n_iorq = n_iorq_cpu; //TdCr(IORQf)
|
||||||
assign #400 n_mreq = n_mreq_cpu; //TdCf(MREQf)
|
assign #40 n_mreq = n_mreq_cpu; //TdCf(MREQf)
|
||||||
assign #450 n_m1 = n_m1_cpu; //TdCr(M1f)
|
assign #45 n_m1 = n_m1_cpu; //TdCr(M1f)
|
||||||
assign #600 n_rfsh = n_rfsh_cpu; //TdCr(RFSHf)
|
assign #60 n_rfsh = n_rfsh_cpu; //TdCr(RFSHf)
|
||||||
assign #570 a_cpu = a_cpu_cpu; //TdCr(A)
|
assign #57 a_cpu = a_cpu_cpu; //TdCr(A)
|
||||||
|
|
||||||
/* CPU SIGNALS (Z84C0008 timings) */
|
/* CPU SIGNALS (Z84C0008 timings) */
|
||||||
// assign #700 n_rd = n_rd_cpu; //TdCf(RDf)
|
//assign #70 n_rd = n_rd_cpu; //TdCf(RDf)
|
||||||
// assign #600 n_wr = n_wr_cpu; //TdCf(WRf)
|
//assign #60 n_wr = n_wr_cpu; //TdCf(WRf)
|
||||||
// assign #550 n_iorq = n_iorq_cpu; //TdCr(IORQf)
|
//assign #55 n_iorq = n_iorq_cpu; //TdCr(IORQf)
|
||||||
// assign #600 n_mreq = n_mreq_cpu; //TdCf(MREQf)
|
//assign #60 n_mreq = n_mreq_cpu; //TdCf(MREQf)
|
||||||
// assign #700 n_m1 = n_m1_cpu; //TdCr(M1f)
|
//assign #70 n_m1 = n_m1_cpu; //TdCr(M1f)
|
||||||
// assign #950 n_rfsh = n_rfsh_cpu; //TdCr(RFSHf)
|
//assign #95 n_rfsh = n_rfsh_cpu; //TdCr(RFSHf)
|
||||||
// assign #800 a_cpu = a_cpu_cpu; //TdCr(A)
|
//assign #80 a_cpu = a_cpu_cpu; //TdCr(A)
|
||||||
|
|
||||||
/* CPU SIGNALS (Z84C0004 timings) */
|
/* CPU SIGNALS (Z84C0004 timings) */
|
||||||
// assign #850 n_rd = n_rd_cpu; //TdCf(RDf)
|
// assign #85 n_rd = n_rd_cpu; //TdCf(RDf)
|
||||||
// assign #800 n_wr = n_wr_cpu; //TdCf(WRf)
|
// assign #80 n_wr = n_wr_cpu; //TdCf(WRf)
|
||||||
// assign #750 n_iorq = n_iorq_cpu; //TdCr(IORQf)
|
// assign #75 n_iorq = n_iorq_cpu; //TdCr(IORQf)
|
||||||
// assign #850 n_mreq = n_mreq_cpu; //TdCf(MREQf)
|
// assign #85 n_mreq = n_mreq_cpu; //TdCf(MREQf)
|
||||||
// assign #1000 n_m1 = n_m1_cpu; //TdCr(M1f)
|
// assign #100 n_m1 = n_m1_cpu; //TdCr(M1f)
|
||||||
// assign #1300 n_rfsh = n_rfsh_cpu; //TdCr(RFSHf)
|
// assign #130 n_rfsh = n_rfsh_cpu; //TdCr(RFSHf)
|
||||||
// assign #1100 a_cpu = a_cpu_cpu; //TdCr(A)
|
// assign #110 a_cpu = a_cpu_cpu; //TdCr(A)
|
||||||
|
|
||||||
|
|
||||||
|
/* SIMULATION SIGNALS */
|
||||||
|
initial begin
|
||||||
|
n_magic = 1;
|
||||||
|
#50000
|
||||||
|
// n_magic = 0;
|
||||||
|
#50000
|
||||||
|
n_magic = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
/* CLOCKS & RESET */
|
/* CLOCKS & RESET */
|
||||||
initial begin
|
initial begin
|
||||||
rst_n = 0;
|
rst_n = 0;
|
||||||
#3000 rst_n = 1;
|
#300 rst_n = 1;
|
||||||
end
|
end
|
||||||
|
|
||||||
always begin
|
always begin
|
||||||
clk28 = 0;
|
clk28 = 0;
|
||||||
#178 clk28 = 1;
|
#17.8 clk28 = 1;
|
||||||
#179;
|
#17.9;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
/* TESTBENCH CONTROL */
|
/* TESTBENCH CONTROL */
|
||||||
initial begin
|
initial begin
|
||||||
$dumpfile("testbench_zx_ula.vcd");
|
$dumpfile("testbench_zx_ula.vcd");
|
||||||
$dumpvars();
|
$dumpvars;
|
||||||
#5000000 $finish;
|
#500_000 $finish;
|
||||||
// #200000000 $finish;
|
// #21_000_000 $finish;
|
||||||
|
// #41_000_000 $finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
35
rom/Makefile
35
rom/Makefile
@ -1,12 +1,23 @@
|
|||||||
all:
|
# Each bank = 16Kb
|
||||||
cat 128-0.rom \
|
bank00=128-0.rom # 0x00000
|
||||||
128-1.rom \
|
bank01=128-1.rom # 0x04000
|
||||||
../rom_src/main.bin \
|
bank02=../rom_src/main.bin # 0x08000
|
||||||
ESXMMC.BIN ESXMMC.BIN \
|
bank03=ESXMMC.BIN ESXMMC.BIN # 0x0C000
|
||||||
dvmen3e0.rom \
|
bank04=dvmen3e0.rom # 0x10000
|
||||||
dvmen3e1.rom \
|
bank05=dvmen3e1.rom # 0x14000
|
||||||
dvmen3e2.rom \
|
bank06=dvmen3e2.rom # 0x18000
|
||||||
opense.rom \
|
bank07=zero8k.bin zero8k.bin # 0x1C000
|
||||||
>sizif.bin
|
|
||||||
objcopy --input-target=binary --output-target=ihex sizif.bin sizif.hex
|
sizif.rom: ${bank00} ${bank01} ${bank02} ${bank03} ${bank04} ${bank05} ${bank06} ${bank07}
|
||||||
rm sizif.bin
|
|
||||||
|
%.rom:
|
||||||
|
cat $+ > $@
|
||||||
|
|
||||||
|
%.hex: %.rom
|
||||||
|
objcopy --input-target=binary --output-target=ihex $< $@
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := all
|
||||||
|
all: sizif.hex
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f sizif.rom sizif.hex
|
||||||
|
BIN
rom/opense.rom
BIN
rom/opense.rom
Binary file not shown.
BIN
rom/zero8k.bin
Normal file
BIN
rom/zero8k.bin
Normal file
Binary file not shown.
@ -1,6 +1,7 @@
|
|||||||
export PATH:=/cygdrive/c/Hwdev/sjasmplus/:/cygdrive/c/Dev/srec/:${PATH}
|
export PATH:=/cygdrive/c/Hwdev/sjasmplus/:/cygdrive/c/Dev/srec/:${PATH}
|
||||||
|
|
||||||
SJOPTS='-DSIZIFXXS'
|
REV=D
|
||||||
|
SJOPTS=-DSIZIFXXS
|
||||||
|
|
||||||
.PHONY: all clean .FORCE
|
.PHONY: all clean .FORCE
|
||||||
.FORCE:
|
.FORCE:
|
||||||
|
@ -1,35 +1,45 @@
|
|||||||
|
POWERON_DELAY EQU 40 ; *20ms, for ps/2 keyboard initialization
|
||||||
|
|
||||||
MENU_ENTER_DELAY EQU 40 ; 400ms
|
MENU_ENTER_DELAY EQU 40 ; 400ms
|
||||||
MENU_LEAVE_DELAY EQU 2 ; 20ms
|
MENU_LEAVE_DELAY EQU 2 ; 20ms
|
||||||
MENU_HOLDCHECK_DELAY EQU 7
|
|
||||||
|
|
||||||
MENU_WIDTH EQU 20
|
|
||||||
MENU_HEIGHT EQU MENU_ITEMS+2
|
|
||||||
|
|
||||||
MENU_X EQU (32-MENU_WIDTH)/2
|
|
||||||
MENU_Y EQU (24-MENU_HEIGHT)/2
|
|
||||||
|
|
||||||
MENU_HEADER_ATTR EQU #47
|
|
||||||
MENU_BODY_ATTR EQU #78
|
|
||||||
MENU_SELECT_ATTR EQU #68
|
|
||||||
|
|
||||||
INPUT_REPEAT EQU 2
|
INPUT_REPEAT EQU 2
|
||||||
INPUT_REPEAT_FIRST EQU 11
|
INPUT_REPEAT_FIRST EQU 11
|
||||||
INPUT_BEEP_DELAY EQU 255
|
INPUT_BEEP_DELAY EQU 255
|
||||||
|
|
||||||
|
MENU_WIDTH EQU 20
|
||||||
|
MENU_X EQU (32-MENU_WIDTH)/2
|
||||||
|
MENU_HEADER_ATTR EQU #47
|
||||||
|
MENU_BODY_ATTR EQU #78
|
||||||
|
MENU_SELECT_ATTR EQU #68
|
||||||
|
|
||||||
|
PAUSE_WIDTH EQU 7
|
||||||
|
PAUSE_HEIGHT EQU 3 ; see pause.asm to really change
|
||||||
|
PAUSE_X EQU (32-PAUSE_WIDTH)/2
|
||||||
|
PAUSE_Y EQU (24-PAUSE_HEIGHT)/2
|
||||||
|
PAUSE_BODY_ATTR EQU #00
|
||||||
|
PAUSE_TEXT_ATTR EQU #C7
|
||||||
|
|
||||||
STRUCT CFG_T
|
STRUCT CFG_T
|
||||||
_reserv0 DB 0
|
_reserv0 DB 0
|
||||||
_reserv1 DB 0
|
_reserv1 DB 0
|
||||||
timings DB 0
|
machine DB 3
|
||||||
clock DB 0
|
clock DB 0
|
||||||
panning DB 0
|
panning DB 1
|
||||||
plus3 DB 0
|
custom_rom DB 0
|
||||||
rom48 DB 0
|
rom48 DB 0
|
||||||
joystick DB 0
|
joystick DB 0
|
||||||
ram DB 0
|
_reserv2 DB 0
|
||||||
divmmc DB 1
|
divmmc DB 2
|
||||||
ulaplus DB 1
|
ulaplus DB 1
|
||||||
dac DB 3
|
dac DB 3
|
||||||
|
ENDS
|
||||||
|
|
||||||
|
STRUCT CFGEXT_T
|
||||||
|
tsfm DB 1
|
||||||
|
saa DB 1
|
||||||
|
gs DB 1
|
||||||
ENDS
|
ENDS
|
||||||
|
|
||||||
CFG_DEFAULT CFG_T
|
CFG_DEFAULT CFG_T
|
||||||
|
CFGEXT_DEFAULT CFGEXT_T
|
||||||
|
@ -125,7 +125,7 @@ print_char:
|
|||||||
print_string:
|
print_string:
|
||||||
ld a, (hl) ; A = *string
|
ld a, (hl) ; A = *string
|
||||||
or a ; if (A == 0) - exit
|
or a ; if (A == 0) - exit
|
||||||
jr z, .return ; ...
|
ret z ; ...
|
||||||
push bc
|
push bc
|
||||||
push hl
|
push hl
|
||||||
call print_char
|
call print_char
|
||||||
@ -134,7 +134,6 @@ print_string:
|
|||||||
inc hl ; string++
|
inc hl ; string++
|
||||||
inc c ; column++
|
inc c ; column++
|
||||||
jr print_string
|
jr print_string
|
||||||
.return:
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -151,7 +150,7 @@ print_string:
|
|||||||
print_string_rev:
|
print_string_rev:
|
||||||
ld a, (hl) ; A = *string
|
ld a, (hl) ; A = *string
|
||||||
or a ; if (A == 0) - exit
|
or a ; if (A == 0) - exit
|
||||||
jr z, .return ; ...
|
ret z ; ...
|
||||||
push bc
|
push bc
|
||||||
push hl
|
push hl
|
||||||
call print_char
|
call print_char
|
||||||
@ -160,7 +159,6 @@ print_string_rev:
|
|||||||
dec hl ; string--
|
dec hl ; string--
|
||||||
dec c ; column--
|
dec c ; column--
|
||||||
jr print_string_rev
|
jr print_string_rev
|
||||||
.return:
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -280,22 +278,23 @@ draw_menu:
|
|||||||
push hl ; IX = menu first item addr
|
push hl ; IX = menu first item addr
|
||||||
pop ix ; ...
|
pop ix ; ...
|
||||||
.line_loop:
|
.line_loop:
|
||||||
ld l, (ix+0) ; HL = menu_t.textaddr
|
ld l, (ix+MENUENTRY_T.text_addr+0) ; HL = menuentry_t.textaddr
|
||||||
ld h, (ix+1) ; ...
|
ld h, (ix+MENUENTRY_T.text_addr+1) ; ...
|
||||||
ld a, h ; if (HL == 0) - exit
|
ld a, h ; if (HL == 0) - exit
|
||||||
or l ; ...
|
or l ; ...
|
||||||
jr z, .return ; ...
|
ret z ; ...
|
||||||
push bc
|
|
||||||
push de
|
push de
|
||||||
|
push bc
|
||||||
push ix
|
push ix
|
||||||
call print_string ; print menu item text
|
call print_string ; print menu item text
|
||||||
pop ix
|
pop ix
|
||||||
pop de
|
|
||||||
pop bc
|
pop bc
|
||||||
|
pop de
|
||||||
|
dec sp ; DE will be restored in .skip_val
|
||||||
|
dec sp ; ...
|
||||||
.print_val:
|
.print_val:
|
||||||
push de ; will be restored in .skip_val
|
ld l, (ix+MENUENTRY_T.value_cb_addr+0) ; HL = menuentry_t.value_cb_addr
|
||||||
ld l, (ix+2) ; HL = menu_t.value_cb_addr
|
ld h, (ix+MENUENTRY_T.value_cb_addr+1) ; ...
|
||||||
ld h, (ix+3) ; ...
|
|
||||||
ld a, h ; if (HL == 0) - skip value print
|
ld a, h ; if (HL == 0) - skip value print
|
||||||
or l ; ...
|
or l ; ...
|
||||||
jr z, .skip_val ; ...
|
jr z, .skip_val ; ...
|
||||||
@ -313,7 +312,7 @@ draw_menu:
|
|||||||
ld a, b ; row += 8
|
ld a, b ; row += 8
|
||||||
add a, 8 ; ...
|
add a, 8 ; ...
|
||||||
ld b, a ; ...
|
ld b, a ; ...
|
||||||
ld de, MENU_T ; IX = IX + sizeof(menu_t)
|
ld de, MENUENTRY_T ; IX = IX + sizeof(menuentry_t)
|
||||||
add ix, de ; ...
|
add ix, de ; ...
|
||||||
pop de ; restore E - columns
|
pop de ; restore E - columns
|
||||||
jr .line_loop
|
jr .line_loop
|
||||||
@ -332,17 +331,16 @@ draw_menu:
|
|||||||
; OUT - B - garbage
|
; OUT - B - garbage
|
||||||
; OUT - E - garbage
|
; OUT - E - garbage
|
||||||
; OUT - HL - garbage
|
; OUT - HL - garbage
|
||||||
draw_menu_item_line:
|
draw_attribute_line:
|
||||||
call coords_to_attribute_address ; HL = attribute address
|
call coords_to_attribute_address ; HL = attribute address
|
||||||
.loop:
|
.loop:
|
||||||
ld a, e ; if (columns == 0) - exit
|
ld a, e ; if (columns == 0) - exit
|
||||||
or a ; ...
|
or a ; ...
|
||||||
jr z, .return ; ...
|
ret z ; ...
|
||||||
ld (hl), d ; write attribute
|
ld (hl), d ; write attribute
|
||||||
inc hl ; column++
|
inc hl ; column++
|
||||||
dec e ; columns--
|
dec e ; columns--
|
||||||
jr .loop
|
jr .loop
|
||||||
.return:
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -721,13 +721,13 @@ font_latin_small_letter_g:
|
|||||||
DG --###---
|
DG --###---
|
||||||
|
|
||||||
font_latin_small_letter_h:
|
font_latin_small_letter_h:
|
||||||
|
DG --------
|
||||||
DG -#------
|
DG -#------
|
||||||
DG -#------
|
DG -#------
|
||||||
DG -####---
|
DG -####---
|
||||||
DG -#---#--
|
DG -#---#--
|
||||||
DG -#---#--
|
DG -#---#--
|
||||||
DG -#---#--
|
DG -#---#--
|
||||||
DG -#---#--
|
|
||||||
DG --------
|
DG --------
|
||||||
|
|
||||||
font_latin_small_letter_i:
|
font_latin_small_letter_i:
|
||||||
|
@ -14,7 +14,7 @@ input_read:
|
|||||||
in a, (#1f) ; ...
|
in a, (#1f) ; ...
|
||||||
bit 7, a ; detect presence by 7th bit
|
bit 7, a ; detect presence by 7th bit
|
||||||
jr nz, .enter ; ...
|
jr nz, .enter ; ...
|
||||||
and #1f ; mask useless bits
|
and #3f ; mask useless bits
|
||||||
ld b, a ; ...
|
ld b, a ; ...
|
||||||
.enter:
|
.enter:
|
||||||
ld a, #bf ; read keys
|
ld a, #bf ; read keys
|
||||||
@ -85,9 +85,16 @@ input_read:
|
|||||||
ret
|
ret
|
||||||
.sinclair_09876_6:
|
.sinclair_09876_6:
|
||||||
bit 4, a ; handle 6 (LEFT) key
|
bit 4, a ; handle 6 (LEFT) key
|
||||||
jr nz, .return ; ...
|
jr nz, .sinclair_ssmnb ; ...
|
||||||
set 1, b ; ...
|
set 1, b ; ...
|
||||||
ret
|
ret
|
||||||
|
.sinclair_ssmnb:
|
||||||
|
ld a, #7f ; read keys
|
||||||
|
in a, (#fe) ; ...
|
||||||
|
bit 2, a ; handle M (EXIT) key (in Sinclair mode sega C button is mapped to M)
|
||||||
|
jr nz, .return ; ...
|
||||||
|
set 5, b ; ...
|
||||||
|
ret
|
||||||
.space_break:
|
.space_break:
|
||||||
ld a, #7f ; read keys
|
ld a, #7f ; read keys
|
||||||
in a, (#fe) ; ...
|
in a, (#fe) ; ...
|
||||||
@ -128,7 +135,7 @@ input_read:
|
|||||||
; OUT - BC - garbage
|
; OUT - BC - garbage
|
||||||
input_beep:
|
input_beep:
|
||||||
or a
|
or a
|
||||||
jr z, .return
|
ret z
|
||||||
IFDEF TEST_BUILD
|
IFDEF TEST_BUILD
|
||||||
ld a, #10 ; blink border
|
ld a, #10 ; blink border
|
||||||
out (#fe), a ; ...
|
out (#fe), a ; ...
|
||||||
@ -142,7 +149,6 @@ input_beep:
|
|||||||
ld a, 1 ; blink border back
|
ld a, 1 ; blink border back
|
||||||
ld bc, #01ff ; ...
|
ld bc, #01ff ; ...
|
||||||
out (c), a ; ...
|
out (c), a ; ...
|
||||||
.return:
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
356
rom_src/main.asm
356
rom_src/main.asm
@ -4,11 +4,15 @@
|
|||||||
app_begin:
|
app_begin:
|
||||||
; Startup handler
|
; Startup handler
|
||||||
ORG #0000
|
ORG #0000
|
||||||
|
ex de, hl ; EB opcode used by CPLD to determine magic ROM presence
|
||||||
|
ex de, hl ; ...
|
||||||
jp startup_handler
|
jp startup_handler
|
||||||
DB 0,"Sizif Magic ROM",0
|
DB 0,"Sizif Magic ROM",0
|
||||||
|
|
||||||
; NMI handler
|
; NMI handler
|
||||||
ORG #0066
|
ORG #0066
|
||||||
|
ex de, hl ; EB opcode used by CPLD to determine magic ROM presence
|
||||||
|
ex de, hl ; ...
|
||||||
jp nmi_handler
|
jp nmi_handler
|
||||||
|
|
||||||
; INT IM1 handler
|
; INT IM1 handler
|
||||||
@ -35,8 +39,23 @@ startup_handler:
|
|||||||
ld ix, #5800 ; draw 4 rygb boxes on left top corner to indicate boot
|
ld ix, #5800 ; draw 4 rygb boxes on left top corner to indicate boot
|
||||||
ld (ix+0), #D2 ; r
|
ld (ix+0), #D2 ; r
|
||||||
ld (ix+1), #F6 ; y
|
ld (ix+1), #F6 ; y
|
||||||
call init_config
|
call check_initialized
|
||||||
|
jr z, .warm_boot
|
||||||
|
im 1 ; wait for ps/2 keyboard ready
|
||||||
|
ld b, POWERON_DELAY ; ...
|
||||||
|
.loop ; ...
|
||||||
|
ei ; ...
|
||||||
|
halt ; ...
|
||||||
|
djnz .loop ; ...
|
||||||
|
call init_default_config
|
||||||
|
call detect_sd_card
|
||||||
|
call detect_ext_board
|
||||||
|
call check_custom_rom
|
||||||
|
.warm_boot:
|
||||||
|
call load_config
|
||||||
call init_cpld
|
call init_cpld
|
||||||
|
call save_initialized
|
||||||
|
call mute_saa1099 ; saa1099 does not have reset pin
|
||||||
ld (ix+2), #E4 ; g
|
ld (ix+2), #E4 ; g
|
||||||
ld (ix+3), #C9 ; b
|
ld (ix+3), #C9 ; b
|
||||||
ld hl, 0
|
ld hl, 0
|
||||||
@ -55,18 +74,25 @@ nmi_handler:
|
|||||||
ld (var_magic_enter_cnt), a
|
ld (var_magic_enter_cnt), a
|
||||||
ld (var_magic_leave_cnt), a
|
ld (var_magic_leave_cnt), a
|
||||||
.loop:
|
.loop:
|
||||||
call check_magic_delay
|
call check_entering_pause ; A[1] == 1 if pause button is pressed
|
||||||
call check_magic_hold ; A == 1 if we are entering menu, A == 2 if we are leaving to...
|
bit 1, a ; ...
|
||||||
bit 0, a ; ...default nmi handler, A == 0 otherwise
|
jp nz, enter_pause ; ...
|
||||||
jp nz, main ; ...
|
call delay_10ms ;
|
||||||
bit 1, a ; ...
|
call check_entering_menu ; A == 1 if we are entering menu, A == 2 if we are leaving to...
|
||||||
jr z, .loop ; ...
|
bit 0, a ; ...default nmi handler, A == 0 otherwise
|
||||||
|
jp nz, enter_menu ; ...
|
||||||
|
bit 1, a ; ...
|
||||||
|
jr z, .loop ; ...
|
||||||
.leave:
|
.leave:
|
||||||
xor a ; disable border
|
xor a ; disable border
|
||||||
ld bc, #01ff ; ...
|
ld bc, #01ff ; ...
|
||||||
out (c), a ; ...
|
out (c), a ; ...
|
||||||
ld hl, #0066 ; jump to default nmi handler
|
ld bc, #ffff ; if divmmc paged - just do retn
|
||||||
jp exit_with_jp ; ...
|
in a, (c) ; ...
|
||||||
|
bit 3, a ; ...
|
||||||
|
jr nz, exit_with_ret ; ...
|
||||||
|
ld hl, #0066 ; otherwise jump to default nmi handler
|
||||||
|
jr exit_with_jp ; ...
|
||||||
|
|
||||||
|
|
||||||
; IN - HL - jump address
|
; IN - HL - jump address
|
||||||
@ -90,80 +116,193 @@ exit_with_ret:
|
|||||||
jp Exit_vector-1
|
jp Exit_vector-1
|
||||||
|
|
||||||
|
|
||||||
init_config:
|
check_initialized:
|
||||||
ld hl, cfg_initialized ; if (cfg_initialized == "magic word") {restore cfg} else {default cfg}
|
ld hl, cfg_initialized ; if (cfg_initialized == "magic word") Z = 0, else Z = 1
|
||||||
ld a, #B1 ; ...
|
ld a, #B1 ; ...
|
||||||
cpi ; ... hl++
|
cpi ; ... hl++
|
||||||
jr nz, .init_default ; ...
|
ret nz ; ...
|
||||||
ld a, #5B ; ...
|
ld a, #5B ; ...
|
||||||
cpi ; ... hl++
|
cpi ; ... hl++
|
||||||
jr nz, .init_default ; ...
|
ret nz ; ...
|
||||||
ld a, #00 ; ...
|
ld a, #00 ; ...
|
||||||
cpi ; ... hl++
|
cpi ; ... hl++
|
||||||
jr nz, .init_default ; ...
|
ret nz ; ...
|
||||||
ld a, #B5 ; ...
|
ld a, #B5 ; ...
|
||||||
cpi ; ... hl++
|
cpi ; ... hl++
|
||||||
jr nz, .init_default ; ...
|
ret
|
||||||
jr .restore ; ...
|
|
||||||
.init_default:
|
save_initialized:
|
||||||
ld bc, CFG_T ; cfg_saved = cfg_default
|
|
||||||
ld de, cfg_saved ; ...
|
|
||||||
ld hl, CFG_DEFAULT ; ...
|
|
||||||
ldir ; ...
|
|
||||||
.restore:
|
|
||||||
ld bc, CFG_T ; cfg = cfg_saved
|
|
||||||
ld de, cfg ; ...
|
|
||||||
ld hl, cfg_saved ; ...
|
|
||||||
ldir ; ...
|
|
||||||
.save_magic:
|
|
||||||
ld hl, #5BB1 ; cfg_initialized = "magic word"
|
ld hl, #5BB1 ; cfg_initialized = "magic word"
|
||||||
ld (cfg_initialized+0), hl ; ...
|
ld (cfg_initialized+0), hl ; ...
|
||||||
ld hl, #B500 ; ...
|
ld hl, #B500 ; ...
|
||||||
ld (cfg_initialized+2), hl ; ...
|
ld (cfg_initialized+2), hl ; ...
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
init_default_config:
|
||||||
|
ld bc, CFG_T+CFGEXT_T ; cfg_saved = cfg_default
|
||||||
|
ld de, cfg_saved ; ...
|
||||||
|
ld hl, CFG_DEFAULT ; ...
|
||||||
|
ldir ; ...
|
||||||
|
|
||||||
|
load_config:
|
||||||
|
ld bc, CFG_T+CFGEXT_T ; cfg = cfg_saved
|
||||||
|
ld de, cfg ; ...
|
||||||
|
ld hl, cfg_saved ; ...
|
||||||
|
ldir ; ...
|
||||||
|
ret ; ...
|
||||||
|
|
||||||
save_config:
|
save_config:
|
||||||
ld bc, CFG_T ; cfg_saved = cfg
|
ld bc, CFG_T+CFGEXT_T ; cfg_saved = cfg
|
||||||
ld de, cfg_saved ; ...
|
ld de, cfg_saved ; ...
|
||||||
ld hl, cfg ; ...
|
ld hl, cfg ; ...
|
||||||
ldir ; ...
|
ldir ; ...
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
init_cpld:
|
init_cpld:
|
||||||
.check_ram48k:
|
.check_alt48rom:
|
||||||
ld a, (cfg.ram) ; if ram == 48K - run basic48
|
ld a, (cfg.rom48) ; if alternative 48k rom enabled - disable 128 menu
|
||||||
cp 1 ; ...
|
or a ; ... this is required because 128 menu isn't compatible
|
||||||
jr nz, .check_plus3_disabled ; ...
|
jr z, .check_7ffd_disabled ; ... with currently used Looking Glass 48K rom
|
||||||
ld a, #10 ; ...
|
ld a, (cfg.machine) ; ... however +3e works with looking glass flawlessly
|
||||||
ld bc, #7ffd ; ...
|
cp 2 ; ...
|
||||||
out (c), a ; ...
|
jr z, .check_7ffd_disabled ; ...
|
||||||
ld a, #4 ; ...
|
ld a, #10 ; ...
|
||||||
ld bc, #1ffd ; ...
|
ld bc, #7ffd ; ...
|
||||||
out (c), a ; ...
|
out (c), a ; ...
|
||||||
jr .do_load
|
.check_7ffd_disabled:
|
||||||
.check_plus3_disabled:
|
ld a, (cfg.machine) ; if machine == 48 - set 7ffd rom to basic48
|
||||||
ld a, (cfg.plus3) ; if plus3 disabled - set 1ffd rom to basic48
|
or a ; ... this is required for case when machine will be
|
||||||
or a ; ... this is required for case when plus3 will be
|
jr nz, .check_1ffd_disabled ; ... changed later by magic menu - this prevents
|
||||||
jr nz, .do_load ; ... activated later by magic menu - this prevents
|
ld a, #10 ; ... hang if user changes machine while basic48 active
|
||||||
ld a, #4 ; ... hang if user activating plus3 while basic48 active
|
ld bc, #7ffd ; ...
|
||||||
ld bc, #1ffd ; ...
|
out (c), a ; ...
|
||||||
out (c), a ; ...
|
.check_1ffd_disabled:
|
||||||
|
ld a, (cfg.machine) ; if machine != +3 - set 1ffd rom to basic48
|
||||||
|
cp 2 ; ... this is required for case when +3 will be
|
||||||
|
jr z, .do_load ; ... activated later by magic menu - this prevents
|
||||||
|
ld a, #4 ; ... hang if user activate +3 while basic48 active
|
||||||
|
ld bc, #1ffd ; ...
|
||||||
|
out (c), a ; ...
|
||||||
.do_load:
|
.do_load:
|
||||||
ld b, CFG_T ; B = registers count
|
ld b, CFG_T ; B = registers count
|
||||||
ld c, #ff ;
|
ld c, #ff ;
|
||||||
ld hl, cfg+CFG_T-1 ; HL = &cfg[registers count-1]
|
ld hl, cfg+CFG_T-1 ; HL = &cfg[registers count-1]
|
||||||
otdr ; do { b--; out(bc, *hl); hl--; } while(b)
|
otdr ; do { b--; out(bc, *hl); hl--; } while(b)
|
||||||
|
.do_load_ext: ; same for extension board
|
||||||
|
ld d, CFGEXT_T ; ...
|
||||||
|
ld b, #e1 ; ...
|
||||||
|
ld c, #ff ; ...
|
||||||
|
ld hl, cfgext ; ...
|
||||||
|
.do_load_ext_loop: ; ...
|
||||||
|
ld a, (hl) ; ...
|
||||||
|
out (c), a ; ...
|
||||||
|
inc hl ; ...
|
||||||
|
inc b ; ...
|
||||||
|
dec d ; ...
|
||||||
|
jr nz, .do_load_ext_loop ; ...
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
detect_sd_card:
|
||||||
|
ld a, #ff ; read sd_cd state in bit 2 of #FFFF port
|
||||||
|
in a, (#ff) ; ...
|
||||||
|
bit 2, a ; check sd_cd == 0 (card is insert)
|
||||||
|
jr z, .is_insert ; yes?
|
||||||
|
.no_card:
|
||||||
|
xor a ; divmmc = OFF
|
||||||
|
ld (cfg_saved.divmmc), a ; ...
|
||||||
|
ret
|
||||||
|
.is_insert:
|
||||||
|
ld a, 1 ; divmmc = ON
|
||||||
|
ld (cfg_saved.divmmc), a ; ...
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; OUT - A = 1 if ext board present, 0 otherwise
|
||||||
|
; OUT - F - garbage
|
||||||
|
; OUT - BC - garbage
|
||||||
|
detect_ext_board:
|
||||||
|
ld b, #e0 ; read port #e0ff
|
||||||
|
ld c, #ff ; ...
|
||||||
|
in a, (c) ; ...
|
||||||
|
ld b, a ; if (result & 0xF0 != 0) - return
|
||||||
|
and #f0 ; ...
|
||||||
|
jr z, .detected ; ...
|
||||||
|
.not_detected:
|
||||||
|
xor a
|
||||||
|
ld (var_ext_presence), a
|
||||||
|
ret
|
||||||
|
.detected
|
||||||
|
ld a, 1
|
||||||
|
ld (var_ext_presence), a
|
||||||
|
xor a
|
||||||
|
bit 0, b ; check TSFM jumper
|
||||||
|
jr z, .cfg_tsfm
|
||||||
|
ld a, 1
|
||||||
|
.cfg_tsfm:
|
||||||
|
ld (cfgext_saved.tsfm), a
|
||||||
|
xor a
|
||||||
|
bit 1, b ; check SAA jumper
|
||||||
|
jr z, .cfg_saa
|
||||||
|
ld a, 1
|
||||||
|
.cfg_saa:
|
||||||
|
ld (cfgext_saved.saa), a
|
||||||
|
xor a
|
||||||
|
bit 2, b ; check GS jumper
|
||||||
|
jr z, .cfg_gs
|
||||||
|
ld a, 1
|
||||||
|
.cfg_gs:
|
||||||
|
ld (cfgext_saved.gs), a
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; Check if user holds 1/2/3/4 key on poweron. If true - boot with custom rom
|
||||||
|
check_custom_rom:
|
||||||
|
ld a, #f7 ; read 1-5 keys
|
||||||
|
in a, (#fe) ; ...
|
||||||
|
bit 0, a ; check key 1 pressed
|
||||||
|
jr z, .key1 ; ...
|
||||||
|
bit 1, a ; check key 2 pressed
|
||||||
|
jr z, .key2 ; ...
|
||||||
|
bit 2, a ; check key 3 pressed
|
||||||
|
jr z, .key3 ; ...
|
||||||
|
bit 3, a ; check key 4 pressed
|
||||||
|
jr z, .key4 ; ...
|
||||||
|
ret
|
||||||
|
.key1:
|
||||||
|
ld a, #80 ; rom #0
|
||||||
|
jr .reconfig
|
||||||
|
.key2:
|
||||||
|
ld a, #81 ; rom #1
|
||||||
|
jr .reconfig
|
||||||
|
.key3:
|
||||||
|
ld a, #82 ; rom #2
|
||||||
|
jr .reconfig
|
||||||
|
.key4:
|
||||||
|
ld a, #83 ; rom #3
|
||||||
|
.reconfig:
|
||||||
|
ld (cfg_saved.custom_rom), a ; set custom rom
|
||||||
|
xor a
|
||||||
|
ld (cfg_saved.divmmc), a ; disable divmmc
|
||||||
|
ld (cfg_saved.ulaplus), a ; disable ula+
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
; OUT - A bit 1 if we are entering pause, 0 otherwise
|
||||||
|
check_entering_pause:
|
||||||
|
ld a, #ff ; read pause key state in bit 1 of #FFFF port
|
||||||
|
in a, (#ff) ; ...
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
; OUT - A = 1 if we are entering menu, A = 2 if we are leaving menu, A = 0 otherwise
|
; OUT - A = 1 if we are entering menu, A = 2 if we are leaving menu, A = 0 otherwise
|
||||||
; OUT - F - garbage
|
; OUT - F - garbage
|
||||||
check_magic_hold:
|
check_entering_menu:
|
||||||
ld a, #ff ; read magic key state in bit 7 of #FE port
|
ld a, #ff ; read magic key state in bit 0 of #FFFF port
|
||||||
in a, (#fe) ; ...
|
in a, (#ff) ; ...
|
||||||
bit 7, a ; check key is hold
|
bit 0, a ; check key is hold
|
||||||
jr z, .is_hold ; yes?
|
jr nz, .is_hold ; yes?
|
||||||
.not_hold:
|
.not_hold:
|
||||||
ld a, (var_magic_leave_cnt) ; leave_counter++
|
ld a, (var_magic_leave_cnt) ; leave_counter++
|
||||||
inc a ; ...
|
inc a ; ...
|
||||||
@ -187,15 +326,21 @@ check_magic_hold:
|
|||||||
|
|
||||||
; OUT - AF - garbage
|
; OUT - AF - garbage
|
||||||
; OUT - BC - garbage
|
; OUT - BC - garbage
|
||||||
check_magic_delay:
|
delay_10ms:
|
||||||
ld c, MENU_HOLDCHECK_DELAY
|
ld c, 7
|
||||||
ld a, (cfg.clock)
|
ld a, (cfg.clock)
|
||||||
or a
|
or a
|
||||||
jr z, .loop
|
jr z, .loop
|
||||||
ld c, MENU_HOLDCHECK_DELAY*2
|
ld c, 9
|
||||||
dec a
|
dec a
|
||||||
jr z, .loop
|
jr z, .loop
|
||||||
ld c, MENU_HOLDCHECK_DELAY*4
|
ld c, 11
|
||||||
|
dec a
|
||||||
|
jr z, .loop
|
||||||
|
ld c, 7*2
|
||||||
|
dec a
|
||||||
|
jr z, .loop
|
||||||
|
ld c, 7*4
|
||||||
.loop:
|
.loop:
|
||||||
ld a, c
|
ld a, c
|
||||||
.loop_outer:
|
.loop_outer:
|
||||||
@ -223,14 +368,27 @@ get_im2_handler:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
save:
|
mute_saa1099:
|
||||||
.mute_saa1099:
|
|
||||||
ld bc, #ffff ; select saa register
|
ld bc, #ffff ; select saa register
|
||||||
ld a, #1c ; ...
|
ld a, #1c ; ...
|
||||||
out (c), a ; ...
|
out (c), a ; ...
|
||||||
ld b, #fe ; mute
|
ld b, #fe ; mute
|
||||||
xor a ; ...
|
xor a ; ...
|
||||||
out (c), a ; ...
|
out (c), a ; ...
|
||||||
|
ret
|
||||||
|
|
||||||
|
save:
|
||||||
|
.mute_gs:
|
||||||
|
ld a, (var_ext_presence) ; if (no_ext_pcb || gs_is_disabled) - skip gs
|
||||||
|
or a ; ...this is required to be compatible with DivIDE
|
||||||
|
jr z, .mute_saa1099 ; ...which uses same port #bb
|
||||||
|
ld a, (cfgext.gs) ; ...
|
||||||
|
or a ; ...
|
||||||
|
jr z, .mute_saa1099 ; ...
|
||||||
|
ld a, #fa ; send command Out zero_to_zero
|
||||||
|
out (#bb), a ; ...
|
||||||
|
.mute_saa1099:
|
||||||
|
call mute_saa1099
|
||||||
.save_ay:
|
.save_ay:
|
||||||
ld hl, var_save_ay ; select first AY chip in TurboSound
|
ld hl, var_save_ay ; select first AY chip in TurboSound
|
||||||
ld a, #ff ; ...
|
ld a, #ff ; ...
|
||||||
@ -287,11 +445,20 @@ restore:
|
|||||||
ldir
|
ldir
|
||||||
.restore_ay:
|
.restore_ay:
|
||||||
ld hl, var_save_ay+16 ; select second AY chip in TurboSound
|
ld hl, var_save_ay+16 ; select second AY chip in TurboSound
|
||||||
ld a, #fe ; ...
|
ld a, #fe ; ...
|
||||||
call .restore_ay_sub
|
call .restore_ay_sub
|
||||||
ld hl, var_save_ay ; select first AY chip in TurboSound
|
ld hl, var_save_ay ; select first AY chip in TurboSound
|
||||||
ld a, #ff ; ...
|
ld a, #ff ; ...
|
||||||
call .restore_ay_sub
|
call .restore_ay_sub
|
||||||
|
.restore_gs:
|
||||||
|
ld a, (var_ext_presence) ; if (no_ext_pcb || gs_is_disabled) - skip gs
|
||||||
|
or a ; ...this is required to be compatible with DivIDE
|
||||||
|
jr z, .restore_ret ; ...which uses same port #bb
|
||||||
|
ld a, (cfgext.gs) ; ...
|
||||||
|
or a ; ...
|
||||||
|
jr z, .restore_ret ; ...
|
||||||
|
ld a, #60 ; send command Get Song Position
|
||||||
|
out (#bb), a ; ...
|
||||||
.restore_ret:
|
.restore_ret:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -313,6 +480,16 @@ restore:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
enter_pause:
|
||||||
|
ld a, 1
|
||||||
|
ld (var_pause_flag), a
|
||||||
|
jr main
|
||||||
|
|
||||||
|
enter_menu:
|
||||||
|
xor a
|
||||||
|
ld (var_pause_flag), a
|
||||||
|
jr main
|
||||||
|
|
||||||
; Main program
|
; Main program
|
||||||
main:
|
main:
|
||||||
push de
|
push de
|
||||||
@ -330,23 +507,45 @@ main:
|
|||||||
ld (var_input_key), a
|
ld (var_input_key), a
|
||||||
ld (var_input_key_last), a
|
ld (var_input_key_last), a
|
||||||
ld (var_input_key_hold_timer), a
|
ld (var_input_key_hold_timer), a
|
||||||
|
ld (var_pause_is_released), a
|
||||||
ld (var_menu_current_item), a
|
ld (var_menu_current_item), a
|
||||||
ld (var_menu_animate_cnt), a
|
ld (var_menu_animate_cnt), a
|
||||||
|
|
||||||
call save
|
call save
|
||||||
call menu_init
|
ld a, (var_pause_flag)
|
||||||
|
or a
|
||||||
|
jr z, .menu_init
|
||||||
|
|
||||||
.loop:
|
.pause_init:
|
||||||
|
call pause_init
|
||||||
|
.pause_loop:
|
||||||
|
ei
|
||||||
|
halt
|
||||||
|
call pause_process
|
||||||
|
ld a, (var_exit_flag)
|
||||||
|
or a
|
||||||
|
jr z, .pause_loop
|
||||||
|
jr .wait_for_keys_release
|
||||||
|
|
||||||
|
.menu_init:
|
||||||
|
call check_initialized
|
||||||
|
jr z, .menu_init1
|
||||||
|
call init_default_config
|
||||||
|
call detect_ext_board
|
||||||
|
call load_config
|
||||||
|
call save_initialized
|
||||||
|
.menu_init1:
|
||||||
|
call menu_init
|
||||||
|
.menu_loop:
|
||||||
ei
|
ei
|
||||||
halt
|
halt
|
||||||
call input_process ; B = 32 if exit key pressed
|
call input_process ; B = 32 if exit key pressed
|
||||||
bit 5, b
|
bit 5, b
|
||||||
jr nz, .wait_for_keys_release
|
jr nz, .wait_for_keys_release
|
||||||
|
|
||||||
call menu_process
|
call menu_process
|
||||||
ld a, (var_exit_flag)
|
ld a, (var_exit_flag)
|
||||||
or a
|
or a
|
||||||
jr z, .loop
|
jr z, .menu_loop
|
||||||
|
|
||||||
.wait_for_keys_release:
|
.wait_for_keys_release:
|
||||||
ei
|
ei
|
||||||
@ -355,6 +554,10 @@ main:
|
|||||||
xor a
|
xor a
|
||||||
or b
|
or b
|
||||||
jr nz, .wait_for_keys_release
|
jr nz, .wait_for_keys_release
|
||||||
|
ld a, #ff ; read magic/pause keys state
|
||||||
|
in a, (#ff) ; ...
|
||||||
|
and #03 ; ...
|
||||||
|
jr nz, .wait_for_keys_release
|
||||||
|
|
||||||
.leave:
|
.leave:
|
||||||
call save_config
|
call save_config
|
||||||
@ -389,6 +592,7 @@ main:
|
|||||||
include config.asm
|
include config.asm
|
||||||
include draw.asm
|
include draw.asm
|
||||||
include input.asm
|
include input.asm
|
||||||
|
include pause.asm
|
||||||
include menu.asm
|
include menu.asm
|
||||||
include menu_structure.asm
|
include menu_structure.asm
|
||||||
include font.asm
|
include font.asm
|
||||||
@ -406,23 +610,7 @@ Readout_vector EQU #F008
|
|||||||
ORG #D500
|
ORG #D500
|
||||||
var_save_screen: .6912 DB 0
|
var_save_screen: .6912 DB 0
|
||||||
ORG #F020
|
ORG #F020
|
||||||
var_save_ay: .32 DB 0
|
include variables.asm
|
||||||
var_save_ulaplus: DB 0
|
|
||||||
var_sp_reg: DW 0
|
|
||||||
var_int_vector: DW 0
|
|
||||||
var_magic_enter_cnt: DB 0
|
|
||||||
var_magic_leave_cnt: DB 0
|
|
||||||
var_exit_flag: DB 0
|
|
||||||
var_exit_reboot: DB 0
|
|
||||||
var_input_key: DB 0
|
|
||||||
var_input_key_last: DB 0
|
|
||||||
var_input_key_hold_timer: DB 0
|
|
||||||
var_menu_current_item: DB 0
|
|
||||||
var_menu_animate_cnt: DB 0
|
|
||||||
|
|
||||||
cfg CFG_T
|
|
||||||
cfg_saved CFG_T
|
|
||||||
cfg_initialized: DB #B1, #5B, #00, #B5
|
|
||||||
|
|
||||||
ORG #FFBE
|
ORG #FFBE
|
||||||
Stack_top:
|
Stack_top:
|
||||||
|
@ -31,8 +31,9 @@ app_begin:
|
|||||||
call menu_process
|
call menu_process
|
||||||
ld a, #01
|
ld a, #01
|
||||||
out #fe, a
|
out #fe, a
|
||||||
jr .loop
|
ld a, (var_exit_flag)
|
||||||
|
or a
|
||||||
|
jr z, .loop
|
||||||
|
|
||||||
save_variables:
|
save_variables:
|
||||||
ret
|
ret
|
||||||
@ -42,24 +43,14 @@ includes:
|
|||||||
include config.asm
|
include config.asm
|
||||||
include draw.asm
|
include draw.asm
|
||||||
include input.asm
|
include input.asm
|
||||||
|
include pause.asm
|
||||||
include menu.asm
|
include menu.asm
|
||||||
include menu_structure.asm
|
include menu_structure.asm
|
||||||
include font.asm
|
include font.asm
|
||||||
include strings.asm
|
include strings.asm
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
var_exit_flag: DB 0
|
include variables.asm
|
||||||
var_exit_reboot: DB 0
|
|
||||||
var_input_key: DB 0
|
|
||||||
var_input_key_last: DB 0
|
|
||||||
var_input_key_hold_timer: DB 0
|
|
||||||
var_menu_current_item: DB 0
|
|
||||||
var_menu_animate_cnt: DB 0
|
|
||||||
|
|
||||||
cfg CFG_T
|
|
||||||
cfg_saved CFG_T
|
|
||||||
cfg_initialized: DB #B1, #5B, #00, #B5
|
|
||||||
|
|
||||||
|
|
||||||
DISPLAY "Application size: ",/D,$-app_begin
|
DISPLAY "Application size: ",/D,$-app_begin
|
||||||
CSPECTMAP "main_test.map"
|
CSPECTMAP "main_test.map"
|
||||||
|
@ -1,16 +1,29 @@
|
|||||||
menu_init:
|
menu_init:
|
||||||
ld b, MENU_Y
|
ld bc, MENU_T ; if (ext board present) var_menu = menuext; else var_menu = menu;
|
||||||
|
ld de, var_menu ; ...
|
||||||
|
ld hl, menu ; ...
|
||||||
|
ld a, (var_ext_presence) ; ...
|
||||||
|
or a ; ...
|
||||||
|
jr z, .set_menu ; ...
|
||||||
|
ld hl, menuext ; ...
|
||||||
|
.set_menu: ; ...
|
||||||
|
ldir ; ...
|
||||||
|
|
||||||
|
ld ix, var_menu
|
||||||
|
ld b, (ix+MENU_T.y_row)
|
||||||
ld c, MENU_X
|
ld c, MENU_X
|
||||||
ld d, MENU_HEIGHT
|
ld d, (ix+MENU_T.height)
|
||||||
ld e, MENU_WIDTH
|
ld e, MENU_WIDTH
|
||||||
call draw_box
|
call draw_box
|
||||||
|
|
||||||
|
ld ix, var_menu
|
||||||
ld hl, str_sizif
|
ld hl, str_sizif
|
||||||
ld b, MENU_Y*8
|
ld b, (ix+MENU_T.y_pixel)
|
||||||
ld c, MENU_X
|
ld c, MENU_X
|
||||||
call print_string
|
call print_string
|
||||||
|
|
||||||
ld b, MENU_Y*8
|
ld ix, var_menu
|
||||||
|
ld b, (ix+MENU_T.y_pixel)
|
||||||
ld c, MENU_X+MENU_WIDTH-6
|
ld c, MENU_X+MENU_WIDTH-6
|
||||||
ld e, 0
|
ld e, 0
|
||||||
call draw_logo
|
call draw_logo
|
||||||
@ -49,7 +62,8 @@ menu_animate_logo:
|
|||||||
ld a, 4 ; ...
|
ld a, 4 ; ...
|
||||||
sub e ; ...
|
sub e ; ...
|
||||||
ld e, a ; ...
|
ld e, a ; ...
|
||||||
ld b, MENU_Y*8 ; draw logo
|
ld ix, var_menu ;
|
||||||
|
ld b, (ix+MENU_T.y_pixel) ; draw logo
|
||||||
ld c, MENU_X+MENU_WIDTH-6 ; ...
|
ld c, MENU_X+MENU_WIDTH-6 ; ...
|
||||||
call draw_logo ; ...
|
call draw_logo ; ...
|
||||||
.return:
|
.return:
|
||||||
@ -60,7 +74,9 @@ menu_animate_logo:
|
|||||||
; OUT - BC - garbage
|
; OUT - BC - garbage
|
||||||
; OUT - DE - garbage
|
; OUT - DE - garbage
|
||||||
; OUT - HL - garbage
|
; OUT - HL - garbage
|
||||||
|
; OUT - IX - garbage
|
||||||
menu_handle_updown:
|
menu_handle_updown:
|
||||||
|
ld ix, var_menu
|
||||||
call input_key_get ; A = current_pressed_key
|
call input_key_get ; A = current_pressed_key
|
||||||
.down: ;
|
.down: ;
|
||||||
bit 2, a ; down?
|
bit 2, a ; down?
|
||||||
@ -68,11 +84,10 @@ menu_handle_updown:
|
|||||||
ld a, (var_menu_current_item) ;
|
ld a, (var_menu_current_item) ;
|
||||||
ld d, MENU_BODY_ATTR ; fill selected item with background color
|
ld d, MENU_BODY_ATTR ; fill selected item with background color
|
||||||
call menu_draw_selected_item ; ...
|
call menu_draw_selected_item ; ...
|
||||||
cp a, MENU_ITEMS-1 ; if (current_item == max) current_item = 0
|
|
||||||
jr nz, .down_increment ; ...
|
|
||||||
ld a, 255 ; ...
|
|
||||||
.down_increment ; ...
|
|
||||||
inc a ; current_item++
|
inc a ; current_item++
|
||||||
|
cp a, (ix+MENU_T.items) ; if (current_item == max) current_item = 0
|
||||||
|
jr nz, .return_save ; ...
|
||||||
|
ld a, 0 ; ...
|
||||||
jr .return_save ;
|
jr .return_save ;
|
||||||
.up: ;
|
.up: ;
|
||||||
bit 3, a ; up?
|
bit 3, a ; up?
|
||||||
@ -82,7 +97,7 @@ menu_handle_updown:
|
|||||||
call menu_draw_selected_item ; ...
|
call menu_draw_selected_item ; ...
|
||||||
or a ; if (current_item == 0) current_item = max
|
or a ; if (current_item == 0) current_item = max
|
||||||
jr nz, .up_decrement ; ...
|
jr nz, .up_decrement ; ...
|
||||||
ld a, MENU_ITEMS ; ...
|
ld a, (ix+MENU_T.items)
|
||||||
.up_decrement ; ...
|
.up_decrement ; ...
|
||||||
dec a ; current_item--
|
dec a ; current_item--
|
||||||
.return_save: ;
|
.return_save: ;
|
||||||
@ -104,17 +119,20 @@ menu_handle_action_left_right:
|
|||||||
ld d, a
|
ld d, a
|
||||||
and #13 ; action/left/right?
|
and #13 ; action/left/right?
|
||||||
jr z, .return
|
jr z, .return
|
||||||
ld a, d
|
ld ix, var_menu ; IX = &menu
|
||||||
|
ld c, (ix+MENU_T.addr+0) ; IX = &menu_entry
|
||||||
|
ld b, (ix+MENU_T.addr+1) ; ...
|
||||||
|
ld ixl, c ; ...
|
||||||
|
ld ixh, b ; ...
|
||||||
ld a, (var_menu_current_item) ; A = selected item index
|
ld a, (var_menu_current_item) ; A = selected item index
|
||||||
sla a ; A*8 (one menu entry - 8 bytes)
|
sla a ; A*8 (one menu entry - 8 bytes)
|
||||||
sla a ; ...
|
sla a ; ...
|
||||||
sla a ; ...
|
sla a ; ...
|
||||||
ld ix, menu ; IX = &menu
|
ld c, a ; IX = &menu_entry[index].callback
|
||||||
ld c, a ; IX = menu[index]
|
|
||||||
ld b, 0 ; ...
|
ld b, 0 ; ...
|
||||||
add ix, bc ; ...
|
add ix, bc ; ...
|
||||||
ld l, (ix+4) ; HL = menu[index].callback
|
ld l, (ix+MENUENTRY_T.callback+0) ; HL = menu_entry[index].callback
|
||||||
ld h, (ix+5) ; ...
|
ld h, (ix+MENUENTRY_T.callback+1) ; ...
|
||||||
ld a, h ; if (HL == 0) - exit
|
ld a, h ; if (HL == 0) - exit
|
||||||
or l ; ...
|
or l ; ...
|
||||||
jr z, .return ; ...
|
jr z, .return ; ...
|
||||||
@ -132,23 +150,30 @@ menu_handle_action_left_right:
|
|||||||
; OUT - BC - garbage
|
; OUT - BC - garbage
|
||||||
; OUT - E - garbage
|
; OUT - E - garbage
|
||||||
; OUT - HL - garbage
|
; OUT - HL - garbage
|
||||||
|
; OUT - IX - garbage
|
||||||
menu_draw_selected_item:
|
menu_draw_selected_item:
|
||||||
push af
|
push af
|
||||||
ld b, MENU_Y+1
|
ld ix, var_menu
|
||||||
|
ld b, (ix+MENU_T.y_row)
|
||||||
|
inc b
|
||||||
add b
|
add b
|
||||||
ld b, a
|
ld b, a
|
||||||
ld c, MENU_X
|
ld c, MENU_X
|
||||||
ld e, MENU_WIDTH
|
ld e, MENU_WIDTH
|
||||||
call draw_menu_item_line
|
call draw_attribute_line
|
||||||
pop af
|
pop af
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
menu_draw_menu:
|
menu_draw_menu:
|
||||||
ld b, MENU_Y*8+8
|
ld ix, var_menu
|
||||||
|
ld a, (ix+MENU_T.y_pixel)
|
||||||
|
add a, 8
|
||||||
|
ld b, a
|
||||||
ld c, MENU_X+1
|
ld c, MENU_X+1
|
||||||
ld e, MENU_WIDTH
|
ld e, MENU_WIDTH
|
||||||
ld hl, menu
|
ld l, (ix+MENU_T.addr+0)
|
||||||
|
ld h, (ix+MENU_T.addr+1)
|
||||||
call draw_menu
|
call draw_menu
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -1,34 +1,63 @@
|
|||||||
STRUCT MENU_T
|
STRUCT MENU_T
|
||||||
|
addr DW
|
||||||
|
items DB
|
||||||
|
height DB
|
||||||
|
y_row DB
|
||||||
|
y_pixel DB
|
||||||
|
ENDS
|
||||||
|
|
||||||
|
STRUCT MENUENTRY_T
|
||||||
text_addr DW
|
text_addr DW
|
||||||
value_cb_addr DW
|
value_cb_addr DW
|
||||||
callback DW
|
callback DW
|
||||||
reserved DW
|
reserved DW
|
||||||
ENDS
|
ENDS
|
||||||
|
|
||||||
menu:
|
MACRO MENUDESCR label_addr, items
|
||||||
MENU_T str_timings menu_timings_value_cb menu_timins_cb
|
MENU_T (label_addr) (items) (items+2) ((24-(items+2))/2) (((24-(items+2))/2)*8)
|
||||||
MENU_T str_cpu menu_clock_value_cb menu_clock_cb
|
ENDM
|
||||||
MENU_T str_panning menu_panning_value_cb menu_panning_cb
|
|
||||||
MENU_T str_dac menu_dac_value_cb menu_dac_cb
|
.menu:
|
||||||
MENU_T str_joystick menu_joystick_value_cb menu_joystick_cb
|
MENUENTRY_T str_machine menu_machine_value_cb menu_machine_cb
|
||||||
MENU_T str_ram menu_ram_value_cb menu_ram_cb
|
MENUENTRY_T str_cpu menu_clock_value_cb menu_clock_cb
|
||||||
MENU_T str_rom48 menu_rom48_value_cb menu_rom48_cb
|
MENUENTRY_T str_panning menu_panning_value_cb menu_panning_cb
|
||||||
MENU_T str_plus3 menu_plus3_value_cb menu_plus3_cb
|
MENUENTRY_T str_joystick menu_joystick_value_cb menu_joystick_cb
|
||||||
MENU_T str_divmmc menu_divmmc_value_cb menu_divmmc_cb
|
IFNDEF SIZIFXXS
|
||||||
MENU_T str_ulaplus menu_ulaplus_value_cb menu_ulaplus_cb
|
MENUENTRY_T str_rom48 menu_rom48_value_cb menu_rom48_cb
|
||||||
MENU_T str_exit menu_exit_value_cb menu_exit_cb
|
ENDIF
|
||||||
MENU_T 0
|
MENUENTRY_T str_divmmc menu_divmmc_value_cb menu_divmmc_cb
|
||||||
MENU_ITEMS EQU ($-menu)/MENU_T-1
|
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_exit menu_exit_value_cb menu_exit_cb
|
||||||
|
MENUENTRY_T 0
|
||||||
|
!menu: MENUDESCR .menu, ($-.menu)/MENUENTRY_T-1
|
||||||
|
|
||||||
|
.menuext:
|
||||||
|
MENUENTRY_T str_machine menu_machine_value_cb menu_machine_cb
|
||||||
|
MENUENTRY_T str_cpu menu_clock_value_cb menu_clock_cb
|
||||||
|
MENUENTRY_T str_panning menu_panning_value_cb menu_panning_cb
|
||||||
|
MENUENTRY_T str_joystick menu_joystick_value_cb menu_joystick_cb
|
||||||
|
MENUENTRY_T str_rom48 menu_rom48_value_cb menu_rom48_cb
|
||||||
|
MENUENTRY_T str_divmmc menu_divmmc_value_cb menu_divmmc_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_tsfm menu_tsfm_value_cb menu_tsfm_cb
|
||||||
|
MENUENTRY_T str_saa menu_saa_value_cb menu_saa_cb
|
||||||
|
MENUENTRY_T str_gs menu_gs_value_cb menu_gs_cb
|
||||||
|
MENUENTRY_T str_exit menu_exit_value_cb menu_exit_cb
|
||||||
|
MENUENTRY_T 0
|
||||||
|
!menuext: MENUDESCR .menuext, ($-.menuext)/MENUENTRY_T-1
|
||||||
|
|
||||||
|
|
||||||
menu_timings_value_cb:
|
menu_machine_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
ld a, (cfg.timings)
|
ld a, (cfg.machine)
|
||||||
jp menu_value_get
|
jp menu_value_get
|
||||||
.values_table:
|
.values_table:
|
||||||
DW str_timings_pentagon_end-2
|
DW str_machine_48_end-2
|
||||||
DW str_timings_48_end-2
|
DW str_machine_128_end-2
|
||||||
DW str_timings_128_end-2
|
DW str_machine_3e_end-2
|
||||||
|
DW str_machine_pentagon_end-2
|
||||||
|
|
||||||
menu_clock_value_cb:
|
menu_clock_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
@ -36,17 +65,32 @@ menu_clock_value_cb:
|
|||||||
jp menu_value_get
|
jp menu_value_get
|
||||||
.values_table:
|
.values_table:
|
||||||
DW str_cpu_35_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_7_end-2
|
||||||
DW str_cpu_14_end-2
|
DW str_cpu_14_end-2
|
||||||
|
|
||||||
menu_panning_value_cb:
|
menu_panning_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
|
ld a, (var_ext_presence) ; if (ext_board && tsfm) - use ABC instead of ACB panning
|
||||||
|
or a ; ...
|
||||||
|
jr z, .no_tsfm ; ...
|
||||||
|
ld a, (cfgext.tsfm) ; ...
|
||||||
|
or a ; ...
|
||||||
|
jr z, .no_tsfm ; ...
|
||||||
|
ld a, (cfg.panning)
|
||||||
|
cp a, 2 ; if (panning == acb) panning = abc
|
||||||
|
jr c, .get ; ...
|
||||||
|
dec a ; ...
|
||||||
|
.get
|
||||||
|
jp menu_value_get
|
||||||
|
.no_tsfm:
|
||||||
ld a, (cfg.panning)
|
ld a, (cfg.panning)
|
||||||
jp menu_value_get
|
jp menu_value_get
|
||||||
.values_table:
|
.values_table:
|
||||||
|
DW str_panning_mono_end-2
|
||||||
DW str_panning_abc_end-2
|
DW str_panning_abc_end-2
|
||||||
DW str_panning_acb_end-2
|
DW str_panning_acb_end-2
|
||||||
DW str_panning_mono_end-2
|
|
||||||
|
|
||||||
menu_joystick_value_cb:
|
menu_joystick_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
@ -56,41 +100,14 @@ menu_joystick_value_cb:
|
|||||||
DW str_joystick_kempston_end-2
|
DW str_joystick_kempston_end-2
|
||||||
DW str_joystick_sinclair_end-2
|
DW str_joystick_sinclair_end-2
|
||||||
|
|
||||||
menu_ram_value_cb:
|
|
||||||
ld ix, .values_table
|
|
||||||
ld a, (cfg.ram)
|
|
||||||
or a
|
|
||||||
jr nz, .less_than_512K
|
|
||||||
ld a, (cfg.divmmc) ; 256K with divmmc
|
|
||||||
or a ; ...
|
|
||||||
jr z, .is_512K ; ...
|
|
||||||
ld a, 3 ; ...
|
|
||||||
jp menu_value_get
|
|
||||||
.is_512K:
|
|
||||||
xor a
|
|
||||||
.less_than_512K:
|
|
||||||
jp menu_value_get
|
|
||||||
.values_table:
|
|
||||||
DW str_ram_512_end-2
|
|
||||||
DW str_ram_48_end-2
|
|
||||||
DW str_ram_128_end-2
|
|
||||||
DW str_ram_256_end-2
|
|
||||||
|
|
||||||
menu_rom48_value_cb:
|
menu_rom48_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
ld a, (cfg.rom48)
|
ld a, (cfg.rom48)
|
||||||
jp menu_value_get
|
jp menu_value_get
|
||||||
.values_table:
|
.values_table:
|
||||||
DW str_rom48_default_end-2
|
DW str_rom48_default_end-2
|
||||||
DW str_rom48_alt_end-2
|
DW str_rom48_lg_end-2
|
||||||
|
DW str_rom48_opense_end-2
|
||||||
menu_plus3_value_cb:
|
|
||||||
ld ix, .values_table
|
|
||||||
ld a, (cfg.plus3)
|
|
||||||
jp menu_value_get
|
|
||||||
.values_table:
|
|
||||||
DW str_off_end-2
|
|
||||||
DW str_on_end-2
|
|
||||||
|
|
||||||
menu_divmmc_value_cb:
|
menu_divmmc_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
@ -99,6 +116,7 @@ menu_divmmc_value_cb:
|
|||||||
.values_table:
|
.values_table:
|
||||||
DW str_off_end-2
|
DW str_off_end-2
|
||||||
DW str_on_end-2
|
DW str_on_end-2
|
||||||
|
DW str_divmmc_noos_end-2
|
||||||
|
|
||||||
menu_ulaplus_value_cb:
|
menu_ulaplus_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
@ -118,6 +136,31 @@ menu_dac_value_cb:
|
|||||||
DW str_dac_sd_end-2
|
DW str_dac_sd_end-2
|
||||||
DW str_dac_covoxsd_end-2
|
DW str_dac_covoxsd_end-2
|
||||||
|
|
||||||
|
menu_tsfm_value_cb:
|
||||||
|
ld ix, .values_table
|
||||||
|
ld a, (cfgext.tsfm)
|
||||||
|
jp menu_value_get
|
||||||
|
.values_table:
|
||||||
|
DW str_off_end-2
|
||||||
|
DW str_on_end-2
|
||||||
|
|
||||||
|
menu_saa_value_cb:
|
||||||
|
ld ix, .values_table
|
||||||
|
ld a, (cfgext.saa)
|
||||||
|
jp menu_value_get
|
||||||
|
.values_table:
|
||||||
|
DW str_off_end-2
|
||||||
|
DW str_on_end-2
|
||||||
|
|
||||||
|
menu_gs_value_cb:
|
||||||
|
ld ix, .values_table
|
||||||
|
ld a, (cfgext.gs)
|
||||||
|
jp menu_value_get
|
||||||
|
.values_table:
|
||||||
|
DW str_off_end-2
|
||||||
|
DW str_on_end-2
|
||||||
|
|
||||||
|
|
||||||
menu_exit_value_cb:
|
menu_exit_value_cb:
|
||||||
ld ix, .values_table
|
ld ix, .values_table
|
||||||
ld a, (var_exit_reboot)
|
ld a, (var_exit_reboot)
|
||||||
@ -136,18 +179,18 @@ menu_value_get:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
menu_timins_cb:
|
menu_machine_cb:
|
||||||
ld a, (cfg.timings)
|
ld a, (cfg.machine)
|
||||||
ld c, 2
|
ld c, 3
|
||||||
call menu_handle_press
|
call menu_handle_press
|
||||||
ld (cfg.timings), a
|
ld (cfg.machine), a
|
||||||
ld bc, #02ff
|
ld bc, #02ff
|
||||||
out (c), a
|
out (c), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
menu_clock_cb:
|
menu_clock_cb:
|
||||||
ld a, (cfg.clock)
|
ld a, (cfg.clock)
|
||||||
ld c, 2
|
ld c, 4
|
||||||
call menu_handle_press
|
call menu_handle_press
|
||||||
ld (cfg.clock), a
|
ld (cfg.clock), a
|
||||||
ld bc, #03ff
|
ld bc, #03ff
|
||||||
@ -155,8 +198,19 @@ menu_clock_cb:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
menu_panning_cb:
|
menu_panning_cb:
|
||||||
|
ld a, (var_ext_presence) ; if (ext_board && tsfm) - do not allow to set ACB panning
|
||||||
|
or a ; ...
|
||||||
|
jr z, .no_tsfm ; ...
|
||||||
|
ld a, (cfgext.tsfm) ; ...
|
||||||
|
or a ; ...
|
||||||
|
jr z, .no_tsfm ; ...
|
||||||
|
ld a, (cfg.panning) ; ...
|
||||||
|
ld c, 1 ; ...
|
||||||
|
jr .load
|
||||||
|
.no_tsfm:
|
||||||
ld a, (cfg.panning)
|
ld a, (cfg.panning)
|
||||||
ld c, 2
|
ld c, 2
|
||||||
|
.load:
|
||||||
call menu_handle_press
|
call menu_handle_press
|
||||||
ld (cfg.panning), a
|
ld (cfg.panning), a
|
||||||
ld bc, #04ff
|
ld bc, #04ff
|
||||||
@ -172,36 +226,22 @@ menu_joystick_cb:
|
|||||||
out (c), a
|
out (c), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
menu_ram_cb:
|
|
||||||
ld a, (cfg.ram)
|
|
||||||
ld c, 2
|
|
||||||
call menu_handle_press
|
|
||||||
ld (cfg.ram), a
|
|
||||||
ld bc, #08ff
|
|
||||||
out (c), a
|
|
||||||
ret
|
|
||||||
|
|
||||||
menu_rom48_cb:
|
menu_rom48_cb:
|
||||||
ld a, (cfg.rom48)
|
ld a, (cfg.rom48)
|
||||||
ld c, 1
|
IFDEF REV_C
|
||||||
|
ld c, 1
|
||||||
|
ELSE
|
||||||
|
ld c, 2
|
||||||
|
ENDIF
|
||||||
call menu_handle_press
|
call menu_handle_press
|
||||||
ld (cfg.rom48), a
|
ld (cfg.rom48), a
|
||||||
ld bc, #06ff
|
ld bc, #06ff
|
||||||
out (c), a
|
out (c), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
menu_plus3_cb:
|
|
||||||
ld a, (cfg.plus3)
|
|
||||||
ld c, 1
|
|
||||||
call menu_handle_press
|
|
||||||
ld (cfg.plus3), a
|
|
||||||
ld bc, #05ff
|
|
||||||
out (c), a
|
|
||||||
ret
|
|
||||||
|
|
||||||
menu_divmmc_cb:
|
menu_divmmc_cb:
|
||||||
ld a, (cfg.divmmc)
|
ld a, (cfg.divmmc)
|
||||||
ld c, 1
|
ld c, 2
|
||||||
call menu_handle_press
|
call menu_handle_press
|
||||||
ld (cfg.divmmc), a
|
ld (cfg.divmmc), a
|
||||||
ld bc, #09ff
|
ld bc, #09ff
|
||||||
@ -226,6 +266,33 @@ menu_dac_cb:
|
|||||||
out (c), a
|
out (c), a
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
menu_tsfm_cb:
|
||||||
|
ld a, (cfgext.tsfm)
|
||||||
|
ld c, 1
|
||||||
|
call menu_handle_press
|
||||||
|
ld (cfgext.tsfm), a
|
||||||
|
ld bc, #e1ff
|
||||||
|
out (c), a
|
||||||
|
ret
|
||||||
|
|
||||||
|
menu_saa_cb:
|
||||||
|
ld a, (cfgext.saa)
|
||||||
|
ld c, 1
|
||||||
|
call menu_handle_press
|
||||||
|
ld (cfgext.saa), a
|
||||||
|
ld bc, #e2ff
|
||||||
|
out (c), a
|
||||||
|
ret
|
||||||
|
|
||||||
|
menu_gs_cb:
|
||||||
|
ld a, (cfgext.gs)
|
||||||
|
ld c, 1
|
||||||
|
call menu_handle_press
|
||||||
|
ld (cfgext.gs), a
|
||||||
|
ld bc, #e3ff
|
||||||
|
out (c), a
|
||||||
|
ret
|
||||||
|
|
||||||
menu_exit_cb:
|
menu_exit_cb:
|
||||||
bit 4, d ; action?
|
bit 4, d ; action?
|
||||||
jr nz, .exit
|
jr nz, .exit
|
||||||
@ -253,8 +320,8 @@ menu_handle_press:
|
|||||||
jr nz, .decrement
|
jr nz, .decrement
|
||||||
ret
|
ret
|
||||||
.increment:
|
.increment:
|
||||||
cp c ; if (value == max) value = 0
|
cp c ; if (value >= max) value = 0
|
||||||
jr z, .increment_roll ; ...
|
jr nc, .increment_roll ; ...
|
||||||
inc a ; else value++
|
inc a ; else value++
|
||||||
ret
|
ret
|
||||||
.increment_roll:
|
.increment_roll:
|
||||||
|
33
rom_src/pause.asm
Normal file
33
rom_src/pause.asm
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
pause_init:
|
||||||
|
ld d, PAUSE_BODY_ATTR
|
||||||
|
ld c, PAUSE_X
|
||||||
|
ld b, PAUSE_Y
|
||||||
|
ld e, PAUSE_WIDTH
|
||||||
|
call draw_attribute_line
|
||||||
|
ld b, PAUSE_Y+2
|
||||||
|
ld e, PAUSE_WIDTH
|
||||||
|
call draw_attribute_line
|
||||||
|
ld d, PAUSE_TEXT_ATTR
|
||||||
|
ld b, PAUSE_Y+1
|
||||||
|
ld e, PAUSE_WIDTH
|
||||||
|
call draw_attribute_line
|
||||||
|
ld b, (PAUSE_Y+1)<<3
|
||||||
|
ld hl, str_pause
|
||||||
|
call print_string
|
||||||
|
ret
|
||||||
|
|
||||||
|
pause_process:
|
||||||
|
ld a, #ff ; read pause key state in bit 1 of #FFFF port
|
||||||
|
in a, (#ff) ; ...
|
||||||
|
bit 1, a ; check key is hold
|
||||||
|
jr nz, .is_hold ; yes?
|
||||||
|
ld a, 1
|
||||||
|
ld (var_pause_is_released), a
|
||||||
|
ret
|
||||||
|
.is_hold:
|
||||||
|
ld a, (var_pause_is_released) ; if key wasnt released - do nothing
|
||||||
|
or a ; ...
|
||||||
|
ret z ; ...
|
||||||
|
ld a, 1 ; otherwise - var_exit_flag = 1
|
||||||
|
ld (var_exit_flag), a ; ...
|
||||||
|
ret
|
@ -10,6 +10,9 @@ str_sizif: DB "SIZIF-512",0
|
|||||||
str_sizif_end:
|
str_sizif_end:
|
||||||
ENDIF
|
ENDIF
|
||||||
|
|
||||||
|
str_pause DB " PAUSE ",0
|
||||||
|
str_pause_end:
|
||||||
|
|
||||||
str_exit: DB "Exit",0
|
str_exit: DB "Exit",0
|
||||||
str_exit_end:
|
str_exit_end:
|
||||||
|
|
||||||
@ -19,23 +22,26 @@ str_exit_reboot_end:
|
|||||||
str_exit_no_reboot: DB " ",0
|
str_exit_no_reboot: DB " ",0
|
||||||
str_exit_no_reboot_end:
|
str_exit_no_reboot_end:
|
||||||
|
|
||||||
str_on: DB " ON",0
|
str_on: DB " ON",0
|
||||||
str_on_end:
|
str_on_end:
|
||||||
|
|
||||||
str_off: DB " OFF",0
|
str_off: DB " OFF",0
|
||||||
str_off_end:
|
str_off_end:
|
||||||
|
|
||||||
str_timings: DB "Timings",0
|
str_machine: DB "Machine",0
|
||||||
str_timings_end:
|
str_machine_end:
|
||||||
|
|
||||||
str_timings_pentagon: DB "Pentagon",0
|
str_machine_48: DB " 48",0
|
||||||
str_timings_pentagon_end:
|
str_machine_48_end:
|
||||||
|
|
||||||
str_timings_128: DB " 128",0
|
str_machine_128: DB " 128",0
|
||||||
str_timings_128_end:
|
str_machine_128_end:
|
||||||
|
|
||||||
str_timings_48: DB " 48",0
|
str_machine_3e: DB " +3e",0
|
||||||
str_timings_48_end:
|
str_machine_3e_end:
|
||||||
|
|
||||||
|
str_machine_pentagon: DB "Pentagon",0
|
||||||
|
str_machine_pentagon_end:
|
||||||
|
|
||||||
str_cpu: DB "CPU freq",0
|
str_cpu: DB "CPU freq",0
|
||||||
str_cpu_end:
|
str_cpu_end:
|
||||||
@ -43,6 +49,12 @@ str_cpu_end:
|
|||||||
str_cpu_35: DB "3.5MHz",0
|
str_cpu_35: DB "3.5MHz",0
|
||||||
str_cpu_35_end:
|
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: DB " 7MHz",0
|
||||||
str_cpu_7_end:
|
str_cpu_7_end:
|
||||||
|
|
||||||
@ -76,29 +88,17 @@ str_rom48_end:
|
|||||||
str_rom48_default: DB "Default",0
|
str_rom48_default: DB "Default",0
|
||||||
str_rom48_default_end:
|
str_rom48_default_end:
|
||||||
|
|
||||||
str_rom48_alt: DB " Alt",0
|
str_rom48_lg: DB " LG",0
|
||||||
str_rom48_alt_end:
|
str_rom48_lg_end:
|
||||||
|
|
||||||
str_plus3: DB "+3",0
|
str_rom48_opense: DB " OpenSE",0
|
||||||
str_plus3_end:
|
str_rom48_opense_end:
|
||||||
|
|
||||||
str_divmmc: DB "DivMMC",0
|
str_divmmc: DB "DivMMC",0
|
||||||
str_divmmc_end:
|
str_divmmc_end:
|
||||||
|
|
||||||
str_ram: DB "RAM",0
|
str_divmmc_noos: DB "NO OS",0
|
||||||
str_ram_end:
|
str_divmmc_noos_end:
|
||||||
|
|
||||||
str_ram_48: DB " 48K",0
|
|
||||||
str_ram_48_end:
|
|
||||||
|
|
||||||
str_ram_128: DB "128K",0
|
|
||||||
str_ram_128_end:
|
|
||||||
|
|
||||||
str_ram_256: DB "256K",0
|
|
||||||
str_ram_256_end:
|
|
||||||
|
|
||||||
str_ram_512: DB "512K",0
|
|
||||||
str_ram_512_end:
|
|
||||||
|
|
||||||
str_ulaplus: DB "ULA+",0
|
str_ulaplus: DB "ULA+",0
|
||||||
str_ulaplus_end
|
str_ulaplus_end
|
||||||
@ -106,11 +106,20 @@ str_ulaplus_end
|
|||||||
str_dac: DB "DAC",0
|
str_dac: DB "DAC",0
|
||||||
str_dac_end
|
str_dac_end
|
||||||
|
|
||||||
str_dac_covox: DB " Covox",0
|
str_dac_covox: DB " Covox",0
|
||||||
str_dac_covox_end
|
str_dac_covox_end
|
||||||
|
|
||||||
str_dac_sd: DB "SounDrive",0
|
str_dac_sd: DB " SD",0
|
||||||
str_dac_sd_end
|
str_dac_sd_end
|
||||||
|
|
||||||
str_dac_covoxsd: DB " Covox+SD",0
|
str_dac_covoxsd: DB "Covox+SD",0
|
||||||
str_dac_covoxsd_end
|
str_dac_covoxsd_end
|
||||||
|
|
||||||
|
str_tsfm: DB "TSFM+MIDI",0
|
||||||
|
str_tsfm_end
|
||||||
|
|
||||||
|
str_saa: DB "SAA1099",0
|
||||||
|
str_saa_end
|
||||||
|
|
||||||
|
str_gs: DB "GS",0
|
||||||
|
str_gs_end
|
||||||
|
23
rom_src/variables.asm
Normal file
23
rom_src/variables.asm
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
var_save_ay: .32 DB 0
|
||||||
|
var_save_ulaplus: DB 0
|
||||||
|
var_sp_reg: DW 0
|
||||||
|
var_int_vector: DW 0
|
||||||
|
var_magic_enter_cnt: DB 0
|
||||||
|
var_magic_leave_cnt: DB 0
|
||||||
|
var_exit_flag: DB 0
|
||||||
|
var_exit_reboot: DB 0
|
||||||
|
var_input_key: DB 0
|
||||||
|
var_input_key_last: DB 0
|
||||||
|
var_input_key_hold_timer: DB 0
|
||||||
|
var_pause_flag: DB 0
|
||||||
|
var_pause_is_released: DB 0
|
||||||
|
var_menu_current_item: DB 0
|
||||||
|
var_menu_animate_cnt: DB 0
|
||||||
|
var_menu: MENU_T
|
||||||
|
var_ext_presence: DB 1
|
||||||
|
|
||||||
|
cfg CFG_T
|
||||||
|
cfgext CFGEXT_T
|
||||||
|
cfg_saved CFG_T
|
||||||
|
cfgext_saved CFGEXT_T
|
||||||
|
cfg_initialized: DB #B1, #5B, #00, #B5
|
Reference in New Issue
Block a user