1
0
mirror of https://github.com/UzixLS/zx-sizif-xxs.git synced 2025-07-18 23:01:40 +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:
UzixLS
2021-09-21 19:57:59 +03:00
parent 83081238ed
commit 0e572d9d69
28 changed files with 1183 additions and 645 deletions

View File

@ -1,6 +1,7 @@
export PATH:=/cygdrive/c/Hwdev/sjasmplus/:/cygdrive/c/Dev/srec/:${PATH}
SJOPTS='-DSIZIFXXS'
REV=D
SJOPTS=-DSIZIFXXS
.PHONY: all clean .FORCE
.FORCE:

View File

@ -1,35 +1,45 @@
POWERON_DELAY EQU 40 ; *20ms, for ps/2 keyboard initialization
MENU_ENTER_DELAY EQU 40 ; 400ms
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_FIRST EQU 11
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
_reserv0 DB 0
_reserv1 DB 0
timings DB 0
clock DB 0
panning DB 0
plus3 DB 0
rom48 DB 0
joystick DB 0
ram DB 0
divmmc DB 1
ulaplus DB 1
dac DB 3
_reserv0 DB 0
_reserv1 DB 0
machine DB 3
clock DB 0
panning DB 1
custom_rom DB 0
rom48 DB 0
joystick DB 0
_reserv2 DB 0
divmmc DB 2
ulaplus DB 1
dac DB 3
ENDS
STRUCT CFGEXT_T
tsfm DB 1
saa DB 1
gs DB 1
ENDS
CFG_DEFAULT CFG_T
CFGEXT_DEFAULT CFGEXT_T

View File

@ -125,7 +125,7 @@ print_char:
print_string:
ld a, (hl) ; A = *string
or a ; if (A == 0) - exit
jr z, .return ; ...
ret z ; ...
push bc
push hl
call print_char
@ -134,7 +134,6 @@ print_string:
inc hl ; string++
inc c ; column++
jr print_string
.return:
ret
@ -151,7 +150,7 @@ print_string:
print_string_rev:
ld a, (hl) ; A = *string
or a ; if (A == 0) - exit
jr z, .return ; ...
ret z ; ...
push bc
push hl
call print_char
@ -160,7 +159,6 @@ print_string_rev:
dec hl ; string--
dec c ; column--
jr print_string_rev
.return:
ret
@ -280,22 +278,23 @@ draw_menu:
push hl ; IX = menu first item addr
pop ix ; ...
.line_loop:
ld l, (ix+0) ; HL = menu_t.textaddr
ld h, (ix+1) ; ...
ld l, (ix+MENUENTRY_T.text_addr+0) ; HL = menuentry_t.textaddr
ld h, (ix+MENUENTRY_T.text_addr+1) ; ...
ld a, h ; if (HL == 0) - exit
or l ; ...
jr z, .return ; ...
push bc
ret z ; ...
push de
push bc
push ix
call print_string ; print menu item text
pop ix
pop de
pop bc
pop de
dec sp ; DE will be restored in .skip_val
dec sp ; ...
.print_val:
push de ; will be restored in .skip_val
ld l, (ix+2) ; HL = menu_t.value_cb_addr
ld h, (ix+3) ; ...
ld l, (ix+MENUENTRY_T.value_cb_addr+0) ; HL = menuentry_t.value_cb_addr
ld h, (ix+MENUENTRY_T.value_cb_addr+1) ; ...
ld a, h ; if (HL == 0) - skip value print
or l ; ...
jr z, .skip_val ; ...
@ -313,7 +312,7 @@ draw_menu:
ld a, b ; row += 8
add a, 8 ; ...
ld b, a ; ...
ld de, MENU_T ; IX = IX + sizeof(menu_t)
ld de, MENUENTRY_T ; IX = IX + sizeof(menuentry_t)
add ix, de ; ...
pop de ; restore E - columns
jr .line_loop
@ -332,17 +331,16 @@ draw_menu:
; OUT - B - garbage
; OUT - E - garbage
; OUT - HL - garbage
draw_menu_item_line:
draw_attribute_line:
call coords_to_attribute_address ; HL = attribute address
.loop:
ld a, e ; if (columns == 0) - exit
or a ; ...
jr z, .return ; ...
ret z ; ...
ld (hl), d ; write attribute
inc hl ; column++
dec e ; columns--
jr .loop
.return:
ret

View File

@ -721,13 +721,13 @@ font_latin_small_letter_g:
DG --###---
font_latin_small_letter_h:
DG --------
DG -#------
DG -#------
DG -####---
DG -#---#--
DG -#---#--
DG -#---#--
DG -#---#--
DG --------
font_latin_small_letter_i:

View File

@ -14,7 +14,7 @@ input_read:
in a, (#1f) ; ...
bit 7, a ; detect presence by 7th bit
jr nz, .enter ; ...
and #1f ; mask useless bits
and #3f ; mask useless bits
ld b, a ; ...
.enter:
ld a, #bf ; read keys
@ -85,9 +85,16 @@ input_read:
ret
.sinclair_09876_6:
bit 4, a ; handle 6 (LEFT) key
jr nz, .return ; ...
jr nz, .sinclair_ssmnb ; ...
set 1, b ; ...
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:
ld a, #7f ; read keys
in a, (#fe) ; ...
@ -128,7 +135,7 @@ input_read:
; OUT - BC - garbage
input_beep:
or a
jr z, .return
ret z
IFDEF TEST_BUILD
ld a, #10 ; blink border
out (#fe), a ; ...
@ -142,7 +149,6 @@ input_beep:
ld a, 1 ; blink border back
ld bc, #01ff ; ...
out (c), a ; ...
.return:
ret

View File

@ -4,11 +4,15 @@
app_begin:
; Startup handler
ORG #0000
ex de, hl ; EB opcode used by CPLD to determine magic ROM presence
ex de, hl ; ...
jp startup_handler
DB 0,"Sizif Magic ROM",0
; NMI handler
ORG #0066
ex de, hl ; EB opcode used by CPLD to determine magic ROM presence
ex de, hl ; ...
jp nmi_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+0), #D2 ; r
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 save_initialized
call mute_saa1099 ; saa1099 does not have reset pin
ld (ix+2), #E4 ; g
ld (ix+3), #C9 ; b
ld hl, 0
@ -55,18 +74,25 @@ nmi_handler:
ld (var_magic_enter_cnt), a
ld (var_magic_leave_cnt), a
.loop:
call check_magic_delay
call check_magic_hold ; A == 1 if we are entering menu, A == 2 if we are leaving to...
bit 0, a ; ...default nmi handler, A == 0 otherwise
jp nz, main ; ...
bit 1, a ; ...
jr z, .loop ; ...
call check_entering_pause ; A[1] == 1 if pause button is pressed
bit 1, a ; ...
jp nz, enter_pause ; ...
call delay_10ms ;
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
jp nz, enter_menu ; ...
bit 1, a ; ...
jr z, .loop ; ...
.leave:
xor a ; disable border
ld bc, #01ff ; ...
out (c), a ; ...
ld hl, #0066 ; jump to default nmi handler
jp exit_with_jp ; ...
ld bc, #ffff ; if divmmc paged - just do retn
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
@ -90,80 +116,193 @@ exit_with_ret:
jp Exit_vector-1
init_config:
ld hl, cfg_initialized ; if (cfg_initialized == "magic word") {restore cfg} else {default cfg}
check_initialized:
ld hl, cfg_initialized ; if (cfg_initialized == "magic word") Z = 0, else Z = 1
ld a, #B1 ; ...
cpi ; ... hl++
jr nz, .init_default ; ...
ret nz ; ...
ld a, #5B ; ...
cpi ; ... hl++
jr nz, .init_default ; ...
ret nz ; ...
ld a, #00 ; ...
cpi ; ... hl++
jr nz, .init_default ; ...
ret nz ; ...
ld a, #B5 ; ...
cpi ; ... hl++
jr nz, .init_default ; ...
jr .restore ; ...
.init_default:
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:
ret
save_initialized:
ld hl, #5BB1 ; cfg_initialized = "magic word"
ld (cfg_initialized+0), hl ; ...
ld hl, #B500 ; ...
ld (cfg_initialized+2), hl ; ...
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:
ld bc, CFG_T ; cfg_saved = cfg
ld de, cfg_saved ; ...
ld hl, cfg ; ...
ldir ; ...
ld bc, CFG_T+CFGEXT_T ; cfg_saved = cfg
ld de, cfg_saved ; ...
ld hl, cfg ; ...
ldir ; ...
ret
init_cpld:
.check_ram48k:
ld a, (cfg.ram) ; if ram == 48K - run basic48
cp 1 ; ...
jr nz, .check_plus3_disabled ; ...
ld a, #10 ; ...
ld bc, #7ffd ; ...
out (c), a ; ...
ld a, #4 ; ...
ld bc, #1ffd ; ...
out (c), a ; ...
jr .do_load
.check_plus3_disabled:
ld a, (cfg.plus3) ; if plus3 disabled - set 1ffd rom to basic48
or a ; ... this is required for case when plus3 will be
jr nz, .do_load ; ... activated later by magic menu - this prevents
ld a, #4 ; ... hang if user activating plus3 while basic48 active
ld bc, #1ffd ; ...
out (c), a ; ...
.check_alt48rom:
ld a, (cfg.rom48) ; if alternative 48k rom enabled - disable 128 menu
or a ; ... this is required because 128 menu isn't compatible
jr z, .check_7ffd_disabled ; ... with currently used Looking Glass 48K rom
ld a, (cfg.machine) ; ... however +3e works with looking glass flawlessly
cp 2 ; ...
jr z, .check_7ffd_disabled ; ...
ld a, #10 ; ...
ld bc, #7ffd ; ...
out (c), a ; ...
.check_7ffd_disabled:
ld a, (cfg.machine) ; if machine == 48 - set 7ffd rom to basic48
or a ; ... this is required for case when machine will be
jr nz, .check_1ffd_disabled ; ... changed later by magic menu - this prevents
ld a, #10 ; ... hang if user changes machine while basic48 active
ld bc, #7ffd ; ...
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:
ld b, CFG_T ; B = registers count
ld c, #ff ;
ld hl, cfg+CFG_T-1 ; HL = &cfg[registers count-1]
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
; OUT - A = 1 if we are entering menu, A = 2 if we are leaving menu, A = 0 otherwise
; OUT - F - garbage
check_magic_hold:
ld a, #ff ; read magic key state in bit 7 of #FE port
in a, (#fe) ; ...
bit 7, a ; check key is hold
jr z, .is_hold ; yes?
check_entering_menu:
ld a, #ff ; read magic key state in bit 0 of #FFFF port
in a, (#ff) ; ...
bit 0, a ; check key is hold
jr nz, .is_hold ; yes?
.not_hold:
ld a, (var_magic_leave_cnt) ; leave_counter++
inc a ; ...
@ -187,15 +326,21 @@ check_magic_hold:
; OUT - AF - garbage
; OUT - BC - garbage
check_magic_delay:
ld c, MENU_HOLDCHECK_DELAY
delay_10ms:
ld c, 7
ld a, (cfg.clock)
or a
jr z, .loop
ld c, MENU_HOLDCHECK_DELAY*2
ld c, 9
dec a
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:
ld a, c
.loop_outer:
@ -223,14 +368,27 @@ get_im2_handler:
ret
save:
.mute_saa1099:
mute_saa1099:
ld bc, #ffff ; select saa register
ld a, #1c ; ...
out (c), a ; ...
ld b, #fe ; mute
xor 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:
ld hl, var_save_ay ; select first AY chip in TurboSound
ld a, #ff ; ...
@ -287,11 +445,20 @@ restore:
ldir
.restore_ay:
ld hl, var_save_ay+16 ; select second AY chip in TurboSound
ld a, #fe ; ...
ld a, #fe ; ...
call .restore_ay_sub
ld hl, var_save_ay ; select first AY chip in TurboSound
ld a, #ff ; ...
ld hl, var_save_ay ; select first AY chip in TurboSound
ld a, #ff ; ...
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:
ret
@ -313,6 +480,16 @@ restore:
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:
push de
@ -330,23 +507,45 @@ main:
ld (var_input_key), a
ld (var_input_key_last), a
ld (var_input_key_hold_timer), a
ld (var_pause_is_released), a
ld (var_menu_current_item), a
ld (var_menu_animate_cnt), a
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
halt
call input_process ; B = 32 if exit key pressed
bit 5, b
jr nz, .wait_for_keys_release
call menu_process
ld a, (var_exit_flag)
or a
jr z, .loop
jr z, .menu_loop
.wait_for_keys_release:
ei
@ -355,6 +554,10 @@ main:
xor a
or b
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:
call save_config
@ -389,6 +592,7 @@ main:
include config.asm
include draw.asm
include input.asm
include pause.asm
include menu.asm
include menu_structure.asm
include font.asm
@ -406,23 +610,7 @@ Readout_vector EQU #F008
ORG #D500
var_save_screen: .6912 DB 0
ORG #F020
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_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
include variables.asm
ORG #FFBE
Stack_top:

View File

@ -31,8 +31,9 @@ app_begin:
call menu_process
ld a, #01
out #fe, a
jr .loop
ld a, (var_exit_flag)
or a
jr z, .loop
save_variables:
ret
@ -42,24 +43,14 @@ includes:
include config.asm
include draw.asm
include input.asm
include pause.asm
include menu.asm
include menu_structure.asm
include font.asm
include strings.asm
variables:
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
include variables.asm
DISPLAY "Application size: ",/D,$-app_begin
CSPECTMAP "main_test.map"

View File

@ -1,16 +1,29 @@
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 d, MENU_HEIGHT
ld d, (ix+MENU_T.height)
ld e, MENU_WIDTH
call draw_box
ld ix, var_menu
ld hl, str_sizif
ld b, MENU_Y*8
ld b, (ix+MENU_T.y_pixel)
ld c, MENU_X
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 e, 0
call draw_logo
@ -49,7 +62,8 @@ menu_animate_logo:
ld a, 4 ; ...
sub e ; ...
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 ; ...
call draw_logo ; ...
.return:
@ -60,7 +74,9 @@ menu_animate_logo:
; OUT - BC - garbage
; OUT - DE - garbage
; OUT - HL - garbage
; OUT - IX - garbage
menu_handle_updown:
ld ix, var_menu
call input_key_get ; A = current_pressed_key
.down: ;
bit 2, a ; down?
@ -68,11 +84,10 @@ menu_handle_updown:
ld a, (var_menu_current_item) ;
ld d, MENU_BODY_ATTR ; fill selected item with background color
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++
cp a, (ix+MENU_T.items) ; if (current_item == max) current_item = 0
jr nz, .return_save ; ...
ld a, 0 ; ...
jr .return_save ;
.up: ;
bit 3, a ; up?
@ -82,7 +97,7 @@ menu_handle_updown:
call menu_draw_selected_item ; ...
or a ; if (current_item == 0) current_item = max
jr nz, .up_decrement ; ...
ld a, MENU_ITEMS ; ...
ld a, (ix+MENU_T.items)
.up_decrement ; ...
dec a ; current_item--
.return_save: ;
@ -104,17 +119,20 @@ menu_handle_action_left_right:
ld d, a
and #13 ; action/left/right?
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
sla a ; A*8 (one menu entry - 8 bytes)
sla a ; ...
sla a ; ...
ld ix, menu ; IX = &menu
ld c, a ; IX = menu[index]
ld c, a ; IX = &menu_entry[index].callback
ld b, 0 ; ...
add ix, bc ; ...
ld l, (ix+4) ; HL = menu[index].callback
ld h, (ix+5) ; ...
ld l, (ix+MENUENTRY_T.callback+0) ; HL = menu_entry[index].callback
ld h, (ix+MENUENTRY_T.callback+1) ; ...
ld a, h ; if (HL == 0) - exit
or l ; ...
jr z, .return ; ...
@ -132,23 +150,30 @@ menu_handle_action_left_right:
; OUT - BC - garbage
; OUT - E - garbage
; OUT - HL - garbage
; OUT - IX - garbage
menu_draw_selected_item:
push af
ld b, MENU_Y+1
ld ix, var_menu
ld b, (ix+MENU_T.y_row)
inc b
add b
ld b, a
ld c, MENU_X
ld e, MENU_WIDTH
call draw_menu_item_line
call draw_attribute_line
pop af
ret
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 e, MENU_WIDTH
ld hl, menu
ld l, (ix+MENU_T.addr+0)
ld h, (ix+MENU_T.addr+1)
call draw_menu
ret

View File

@ -1,34 +1,63 @@
STRUCT MENU_T
addr DW
items DB
height DB
y_row DB
y_pixel DB
ENDS
STRUCT MENUENTRY_T
text_addr DW
value_cb_addr DW
callback DW
reserved DW
ENDS
menu:
MENU_T str_timings menu_timings_value_cb menu_timins_cb
MENU_T str_cpu menu_clock_value_cb menu_clock_cb
MENU_T str_panning menu_panning_value_cb menu_panning_cb
MENU_T str_dac menu_dac_value_cb menu_dac_cb
MENU_T str_joystick menu_joystick_value_cb menu_joystick_cb
MENU_T str_ram menu_ram_value_cb menu_ram_cb
MENU_T str_rom48 menu_rom48_value_cb menu_rom48_cb
MENU_T str_plus3 menu_plus3_value_cb menu_plus3_cb
MENU_T str_divmmc menu_divmmc_value_cb menu_divmmc_cb
MENU_T str_ulaplus menu_ulaplus_value_cb menu_ulaplus_cb
MENU_T str_exit menu_exit_value_cb menu_exit_cb
MENU_T 0
MENU_ITEMS EQU ($-menu)/MENU_T-1
MACRO MENUDESCR label_addr, items
MENU_T (label_addr) (items) (items+2) ((24-(items+2))/2) (((24-(items+2))/2)*8)
ENDM
.menu:
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
IFNDEF SIZIFXXS
MENUENTRY_T str_rom48 menu_rom48_value_cb menu_rom48_cb
ENDIF
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_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 a, (cfg.timings)
ld a, (cfg.machine)
jp menu_value_get
.values_table:
DW str_timings_pentagon_end-2
DW str_timings_48_end-2
DW str_timings_128_end-2
DW str_machine_48_end-2
DW str_machine_128_end-2
DW str_machine_3e_end-2
DW str_machine_pentagon_end-2
menu_clock_value_cb:
ld ix, .values_table
@ -36,17 +65,32 @@ menu_clock_value_cb:
jp menu_value_get
.values_table:
DW str_cpu_35_end-2
DW str_cpu_44_end-2
DW str_cpu_52_end-2
DW str_cpu_7_end-2
DW str_cpu_14_end-2
menu_panning_value_cb:
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)
jp menu_value_get
.values_table:
DW str_panning_mono_end-2
DW str_panning_abc_end-2
DW str_panning_acb_end-2
DW str_panning_mono_end-2
menu_joystick_value_cb:
ld ix, .values_table
@ -56,41 +100,14 @@ menu_joystick_value_cb:
DW str_joystick_kempston_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:
ld ix, .values_table
ld a, (cfg.rom48)
jp menu_value_get
.values_table:
DW str_rom48_default_end-2
DW str_rom48_alt_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
DW str_rom48_lg_end-2
DW str_rom48_opense_end-2
menu_divmmc_value_cb:
ld ix, .values_table
@ -99,6 +116,7 @@ menu_divmmc_value_cb:
.values_table:
DW str_off_end-2
DW str_on_end-2
DW str_divmmc_noos_end-2
menu_ulaplus_value_cb:
ld ix, .values_table
@ -118,6 +136,31 @@ menu_dac_value_cb:
DW str_dac_sd_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:
ld ix, .values_table
ld a, (var_exit_reboot)
@ -136,18 +179,18 @@ menu_value_get:
ret
menu_timins_cb:
ld a, (cfg.timings)
ld c, 2
menu_machine_cb:
ld a, (cfg.machine)
ld c, 3
call menu_handle_press
ld (cfg.timings), a
ld (cfg.machine), a
ld bc, #02ff
out (c), a
ret
menu_clock_cb:
ld a, (cfg.clock)
ld c, 2
ld c, 4
call menu_handle_press
ld (cfg.clock), a
ld bc, #03ff
@ -155,8 +198,19 @@ menu_clock_cb:
ret
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 c, 2
.load:
call menu_handle_press
ld (cfg.panning), a
ld bc, #04ff
@ -172,36 +226,22 @@ menu_joystick_cb:
out (c), a
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:
ld a, (cfg.rom48)
ld c, 1
IFDEF REV_C
ld c, 1
ELSE
ld c, 2
ENDIF
call menu_handle_press
ld (cfg.rom48), a
ld bc, #06ff
out (c), a
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:
ld a, (cfg.divmmc)
ld c, 1
ld c, 2
call menu_handle_press
ld (cfg.divmmc), a
ld bc, #09ff
@ -226,6 +266,33 @@ menu_dac_cb:
out (c), a
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:
bit 4, d ; action?
jr nz, .exit
@ -253,8 +320,8 @@ menu_handle_press:
jr nz, .decrement
ret
.increment:
cp c ; if (value == max) value = 0
jr z, .increment_roll ; ...
cp c ; if (value >= max) value = 0
jr nc, .increment_roll ; ...
inc a ; else value++
ret
.increment_roll:

33
rom_src/pause.asm Normal file
View 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

View File

@ -10,6 +10,9 @@ str_sizif: DB "SIZIF-512",0
str_sizif_end:
ENDIF
str_pause DB " PAUSE ",0
str_pause_end:
str_exit: DB "Exit",0
str_exit_end:
@ -19,23 +22,26 @@ str_exit_reboot_end:
str_exit_no_reboot: DB " ",0
str_exit_no_reboot_end:
str_on: DB " ON",0
str_on: DB " ON",0
str_on_end:
str_off: DB " OFF",0
str_off_end:
str_timings: DB "Timings",0
str_timings_end:
str_machine: DB "Machine",0
str_machine_end:
str_timings_pentagon: DB "Pentagon",0
str_timings_pentagon_end:
str_machine_48: DB " 48",0
str_machine_48_end:
str_timings_128: DB " 128",0
str_timings_128_end:
str_machine_128: DB " 128",0
str_machine_128_end:
str_timings_48: DB " 48",0
str_timings_48_end:
str_machine_3e: DB " +3e",0
str_machine_3e_end:
str_machine_pentagon: DB "Pentagon",0
str_machine_pentagon_end:
str_cpu: DB "CPU freq",0
str_cpu_end:
@ -43,6 +49,12 @@ str_cpu_end:
str_cpu_35: DB "3.5MHz",0
str_cpu_35_end:
str_cpu_44: DB "4.4MHz",0
str_cpu_44_end:
str_cpu_52: DB "5.2MHz",0
str_cpu_52_end:
str_cpu_7: DB " 7MHz",0
str_cpu_7_end:
@ -76,29 +88,17 @@ str_rom48_end:
str_rom48_default: DB "Default",0
str_rom48_default_end:
str_rom48_alt: DB " Alt",0
str_rom48_alt_end:
str_rom48_lg: DB " LG",0
str_rom48_lg_end:
str_plus3: DB "+3",0
str_plus3_end:
str_rom48_opense: DB " OpenSE",0
str_rom48_opense_end:
str_divmmc: DB "DivMMC",0
str_divmmc_end:
str_ram: DB "RAM",0
str_ram_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_divmmc_noos: DB "NO OS",0
str_divmmc_noos_end:
str_ulaplus: DB "ULA+",0
str_ulaplus_end
@ -106,11 +106,20 @@ str_ulaplus_end
str_dac: DB "DAC",0
str_dac_end
str_dac_covox: DB " Covox",0
str_dac_covox: DB " Covox",0
str_dac_covox_end
str_dac_sd: DB "SounDrive",0
str_dac_sd: DB " SD",0
str_dac_sd_end
str_dac_covoxsd: DB " Covox+SD",0
str_dac_covoxsd: DB "Covox+SD",0
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
View 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