1
0
mirror of https://github.com/UzixLS/zx-sizif-512.git synced 2025-07-19 07:11:36 +03:00

implement fast forward

This commit is contained in:
Eugene Lozovoy
2024-01-19 13:29:59 +03:00
parent e685cf03ac
commit 9c065aba10
7 changed files with 73 additions and 40 deletions

View File

@ -66,6 +66,7 @@ Sega gamepad support will be available starting from PCB rev.D (or Rev.C with sl
| Button | Function | | Button | Function |
| - | - | | - | - |
| F1 | Pause | | F1 | Pause |
| F2 | Fast forward |
| F5 | Magic button | | F5 | Magic button |
| F10 | Reboot | | F10 | Reboot |
| F12 | Reboot | | F12 | Reboot |

View File

@ -16,6 +16,7 @@ module cpu(
input [2:0] ram_page128, input [2:0] ram_page128,
input machine_t machine, input machine_t machine,
input turbo_t turbo, input turbo_t turbo,
input fastforward,
input hold, input hold,
input ext_wait_cycle1, input ext_wait_cycle1,
input ext_wait_cycle2, input ext_wait_cycle2,
@ -90,7 +91,13 @@ localparam INT_L_S128 = 6'd36;
localparam INT_V_PENT = 239; localparam INT_V_PENT = 239;
localparam INT_H_PENT = 322; localparam INT_H_PENT = 322;
localparam INT_L_PENT = 6'd32; localparam INT_L_PENT = 6'd32;
localparam INT_V_FF1 = 0;
localparam INT_V_FF2 = 106;
localparam INT_V_FF3 = 212;
localparam INT_H_FF = 0;
wire int_begin = wire int_begin =
(fastforward)?
(vc == INT_V_FF1 || vc == INT_V_FF2 || vc == INT_V_FF3) && hc == INT_H_FF :
(machine == MACHINE_S48)? (machine == MACHINE_S48)?
vc == INT_V_S48 && hc == INT_H_S48 : vc == INT_V_S48 && hc == INT_H_S48 :
(machine == MACHINE_S128 || machine == MACHINE_S3)? (machine == MACHINE_S128 || machine == MACHINE_S3)?

View File

@ -14,6 +14,7 @@ module magic(
input magic_button, input magic_button,
input pause_button, input pause_button,
input fastforward_button,
input div_paged, input div_paged,
input basic48_paged, input basic48_paged,
@ -40,7 +41,8 @@ module magic(
output reg sd_indication_en, output reg sd_indication_en,
output reg bright_boost, output reg bright_boost,
output reg zxkit1, output reg zxkit1,
output reg joy_a_up output reg joy_a_up,
output reg fastforward
); );
localparam magic_on_start = 1'b1; localparam magic_on_start = 1'b1;
@ -63,7 +65,7 @@ always @(posedge clk28 or negedge rst_n) begin
opcode_is_reading <= 0; opcode_is_reading <= 0;
end end
else begin else begin
if ((magic_button || pause_button) && n_int == 1'b1 && n_int_next == 1'b0) begin if ((magic_button || pause_button || fastforward_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;
@ -136,6 +138,7 @@ always @(posedge clk28 or negedge rst_n) begin
magic_reboot <= 0; magic_reboot <= 0;
magic_beeper <= 0; magic_beeper <= 0;
rom_wren <= 0; rom_wren <= 0;
fastforward <= 0;
end end
else if (config_cs && bus.wr) case (bus.a[15:8]) else if (config_cs && bus.wr) case (bus.a[15:8])
8'h01: {rom_wren, magic_reboot, magic_beeper} <= bus.d[2:0]; 8'h01: {rom_wren, magic_reboot, magic_beeper} <= bus.d[2:0];
@ -154,11 +157,12 @@ always @(posedge clk28 or negedge rst_n) begin
8'h0E: autoturbo_en <= bus.d[0]; 8'h0E: autoturbo_en <= bus.d[0];
8'h0F: zxkit1 <= bus.d[0]; 8'h0F: zxkit1 <= bus.d[0];
8'h10: joy_a_up <= bus.d[0]; 8'h10: joy_a_up <= bus.d[0];
8'h11: fastforward <= bus.d[0];
endcase endcase
end end
reg config_rd; reg config_rd;
wire [7:0] config_data = {4'b0000, div_paged, 1'b1, pause_button, magic_button}; wire [7:0] config_data = {4'b0000, div_paged, fastforward_button, pause_button, magic_button};
always @(posedge clk28 or negedge rst_n) begin always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) if (!rst_n)
config_rd <= 0; config_rd <= 0;
@ -189,6 +193,8 @@ end
always @(posedge clk28 or negedge rst_n) begin always @(posedge clk28 or negedge rst_n) begin
if (!rst_n) if (!rst_n)
turbo <= TURBO_NONE; turbo <= TURBO_NONE;
else if (fastforward)
turbo <= TURBO_14;
else if (autoturbo_en && div_paged && !magic_map) else if (autoturbo_en && div_paged && !magic_map)
turbo <= TURBO_14; turbo <= TURBO_14;
else if (autoturbo_en && |portfe_noturbo) else if (autoturbo_en && |portfe_noturbo)

View File

@ -16,6 +16,7 @@ module ps2#(
output reg key_magic, output reg key_magic,
output reg key_reset, output reg key_reset,
output reg key_pause, output reg key_pause,
output reg key_fastforward,
output reg joy_up, output reg joy_up,
output reg joy_down, output reg joy_down,
output reg joy_left, output reg joy_left,
@ -57,6 +58,7 @@ always @(posedge clk or negedge rst_n) begin
is_ext <= 0; is_ext <= 0;
key_magic <= 0; key_magic <= 0;
key_pause <= 0; key_pause <= 0;
key_fastforward <= 0;
{joy_up, joy_down, joy_left, joy_right, joy_fire} <= 0; {joy_up, joy_down, joy_left, joy_right, joy_fire} <= 0;
{key2_a, key2_b, key2_c, key2_d, key2_e, key2_f, key2_g, key2_h, key2_i, key2_j, key2_k, key2_l, key2_m, key2_n} <= 0; {key2_a, key2_b, key2_c, key2_d, key2_e, key2_f, key2_g, key2_h, key2_i, key2_j, key2_k, key2_l, key2_m, key2_n} <= 0;
{key2_o, key2_p, key2_q, key2_r, key2_s, key2_t, key2_u, key2_v, key2_w, key2_x, key2_y, key2_z, key2_0, key2_1} <= 0; {key2_o, key2_p, key2_q, key2_r, key2_s, key2_t, key2_u, key2_v, key2_w, key2_x, key2_y, key2_z, key2_0, key2_1} <= 0;
@ -137,6 +139,7 @@ always @(posedge clk or negedge rst_n) begin
`PS2_PGDN: key2_pgdn <= is_press; `PS2_PGDN: key2_pgdn <= is_press;
`PS2_F1: key_pause <= is_press; `PS2_F1: key_pause <= is_press;
`PS2_F2: key_fastforward <= is_press;
`PS2_F5: key_magic <= is_press; `PS2_F5: key_magic <= is_press;
`PS2_F10: key_reset0 <= is_press; `PS2_F10: key_reset0 <= is_press;
`PS2_F12: key_reset0 <= is_press; `PS2_F12: key_reset0 <= is_press;

View File

@ -109,6 +109,7 @@ wire joy_a_up;
wire div_map; wire div_map;
wire div_mapram; wire div_mapram;
wire basic48_paged; wire basic48_paged;
wire fastforward;
/* CPU BUS */ /* CPU BUS */
@ -230,7 +231,7 @@ rgb rgb0(
/* PS/2 KEYBOARD */ /* PS/2 KEYBOARD */
wire [4:0] ps2_kd; wire [4:0] ps2_kd;
wire ps2_key_magic; wire ps2_key_magic, ps2_key_fastforward;
wire ps2_joy_up, ps2_joy_down, ps2_joy_left, ps2_joy_right, ps2_joy_fire; wire ps2_joy_up, ps2_joy_down, ps2_joy_left, ps2_joy_right, ps2_joy_fire;
`ifndef REV_C `ifndef REV_C
ps2 #(.CLK_FREQ(28_000_000)) ps2_0( ps2 #(.CLK_FREQ(28_000_000)) ps2_0(
@ -243,6 +244,7 @@ ps2 #(.CLK_FREQ(28_000_000)) ps2_0(
.key_magic(ps2_key_magic), .key_magic(ps2_key_magic),
.key_reset(ps2_key_reset), .key_reset(ps2_key_reset),
.key_pause(ps2_key_pause), .key_pause(ps2_key_pause),
.key_fastforward(ps2_key_fastforward),
.joy_up(ps2_joy_up), .joy_up(ps2_joy_up),
.joy_down(ps2_joy_down), .joy_down(ps2_joy_down),
.joy_left(ps2_joy_left), .joy_left(ps2_joy_left),
@ -338,6 +340,7 @@ cpu cpu0(
.machine(machine), .machine(machine),
.video_contention(video_contention), .video_contention(video_contention),
.turbo(turbo), .turbo(turbo),
.fastforward(fastforward),
.hold(mem_wait), .hold(mem_wait),
.ext_wait_cycle2(ay_ext_wait_cycle2 | div_ext_wait_cycle2), .ext_wait_cycle2(ay_ext_wait_cycle2 | div_ext_wait_cycle2),
@ -389,6 +392,7 @@ magic magic0(
.magic_button(~n_magic || joy_mode || ps2_key_magic), .magic_button(~n_magic || joy_mode || ps2_key_magic),
.pause_button(ps2_key_pause || joy_start), .pause_button(ps2_key_pause || joy_start),
.fastforward_button(ps2_key_fastforward),
.div_paged(div_map && !div_mapram), .div_paged(div_map && !div_mapram),
.basic48_paged(basic48_paged), .basic48_paged(basic48_paged),
@ -415,7 +419,8 @@ magic magic0(
.sd_indication_en(sd_indication_en), .sd_indication_en(sd_indication_en),
.bright_boost(bright_boost), .bright_boost(bright_boost),
.zxkit1(zxkit1), .zxkit1(zxkit1),
.joy_a_up(joy_a_up) .joy_a_up(joy_a_up),
.fastforward(fastforward)
); );

View File

@ -46,6 +46,7 @@ bright DB BRIGHT_DEFAULT
autoturbo DB 0 autoturbo DB 0
zxkit1 DB 0 zxkit1 DB 0
joy_a_up DB 0 joy_a_up DB 0
fastforward DB 0
ENDS ENDS
STRUCT CFGEXT_T STRUCT CFGEXT_T

View File

@ -56,6 +56,8 @@ startup_handler:
call detect_external_bdi call detect_external_bdi
call check_custom_rom call check_custom_rom
.warm_boot: .warm_boot:
xor a
ld (cfg_saved.fastforward), a
call load_config call load_config
call init_cpld call init_cpld
call save_initialized call save_initialized
@ -80,15 +82,18 @@ 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
.key_wait_loop: .key_wait_loop:
call check_entering_pause ; A[1] == 1 if pause button is pressed xor a ;
bit 1, a ; ... in a, (#ff) ;
jp nz, .enter_pause ; ... bit 2, a ; A[2] == 1 if fastforward button is pressed
jr nz, .enter_fastforward ; ...
bit 1, a ; A[1] == 1 if pause button is pressed
jr nz, .enter_pause ; ...
call delay_10ms ; call delay_10ms ;
call check_entering_menu ; A == 1 if we are entering menu, A == 2 if we are leaving to... call check_entering_menu ; A == 1 if we are entering menu, A == 2 if we are leaving to...
bit 0, a ; ...default nmi handler, A == 0 otherwise cp 1 ; ...default nmi handler, A == 0 otherwise
jp nz, .enter_menu ; ... jr z, .enter_menu ; ...
bit 1, a ; ... cp 2 ; ...
jr z, .key_wait_loop ; ... jr nz, .key_wait_loop ; ...
.leave_no_key: .leave_no_key:
xor a ; disable border xor a ; disable border
ld bc, #01ff ; ... ld bc, #01ff ; ...
@ -96,10 +101,14 @@ nmi_handler:
ld bc, #00ff ; ... ld bc, #00ff ; ...
in a, (c) ; if divmmc paged - just do retn in a, (c) ; if divmmc paged - just do retn
bit 3, a ; ... bit 3, a ; ...
jr nz, exit_with_ret ; ... jp nz, exit_with_ret ; ...
ld hl, #0066 ; otherwise jump to default nmi handler ld hl, #0066 ; otherwise jump to default nmi handler
jr exit_with_jp ; ... jp exit_with_jp ; ...
.enter_fastforward:
ld hl, nmi_fastforward
ld (var_main_fun), hl
jr .enter
.enter_pause: .enter_pause:
ld hl, nmi_pause ld hl, nmi_pause
ld (var_main_fun), hl ld (var_main_fun), hl
@ -231,6 +240,8 @@ load_user_config:
.quirks: ; some options shouldn't be saved by user, so we just overwrite them from default config .quirks: ; some options shouldn't be saved by user, so we just overwrite them from default config
ld a, (CFG_DEFAULT.ay) ; AY should be disabled only by detect_external_ay ld a, (CFG_DEFAULT.ay) ; AY should be disabled only by detect_external_ay
ld (cfg_saved.ay), a ; ... ld (cfg_saved.ay), a ; ...
ld a, (CFG_DEFAULT.fastforward)
ld (cfg_saved.fastforward), a
ret ret
; OUT - A = 1 if error, 0 if ok ; OUT - A = 1 if error, 0 if ok
@ -420,13 +431,6 @@ check_custom_rom:
ret ret
; OUT - A bit 1 if we are entering pause, 0 otherwise
check_entering_pause:
xor a ; read pause key state in bit 1 of #00FF port
in a, (#ff) ; ...
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_entering_menu: check_entering_menu:
@ -458,6 +462,10 @@ check_entering_menu:
; OUT - AF - garbage ; OUT - AF - garbage
; OUT - BC - garbage ; OUT - BC - garbage
delay_10ms: delay_10ms:
ld c, 7*4
ld a, (cfg.fastforward)
or a
jr nz, .loop
ld c, 7 ld c, 7
ld a, (cfg.clock) ld a, (cfg.clock)
or a or a
@ -624,8 +632,18 @@ bootmenu:
ld hl, menuboot ld hl, menuboot
call menu_init call menu_init
call menu_input_loop call menu_input_loop
call wait_for_keys_release jp wait_for_keys_release
ret
nmi_fastforward:
ld a, (cfg.fastforward)
xor 1
ld (cfg.fastforward), a
ld bc, #11ff
out (c), a
ei
halt
jp wait_for_keys_release
nmi_pause: nmi_pause:
@ -639,19 +657,7 @@ nmi_pause:
ld a, (var_exit_flag) ld a, (var_exit_flag)
or a or a
jr z, .loop jr z, .loop
.wait_for_pause_key_release: jp wait_for_keys_release
xor a ; read magic/pause keys state from port #00FF
in a, (#ff) ; ...
and #03 ; ...
jr nz, .wait_for_pause_key_release
ei ; second read to fix start button bouncing on 8bitdo gamepad
halt ; ...
.wait_for_pause_key_release2:
xor a ; read magic/pause keys state from port #00FF
in a, (#ff) ; ...
and #03 ; ...
jr nz, .wait_for_pause_key_release2
ret
nmi_menu: nmi_menu:
@ -674,8 +680,7 @@ nmi_menu:
call menu_init call menu_init
.loop: .loop:
call menu_input_loop call menu_input_loop
call wait_for_keys_release jp wait_for_keys_release
ret
menu_input_loop: menu_input_loop:
@ -697,6 +702,9 @@ menu_input_loop:
wait_for_keys_release: wait_for_keys_release:
ld b, 2 ; second attempt to fix start button bouncing on 8bitdo gamepad
.attempt:
push bc
.loop: .loop:
ei ei
halt halt
@ -704,10 +712,12 @@ wait_for_keys_release:
xor a xor a
or b or b
jr nz, .loop jr nz, .loop
xor a ; read magic/pause keys state from port #00FF xor a ; read magic/pause/fastforward keys state from port #00FF
in a, (#ff) ; ... in a, (#ff) ; ...
and #03 ; ... and #07 ; ...
jr nz, .loop jr nz, .loop
pop bc
djnz .attempt
ret ret