#include "memmap.i65" #include "dma.i65" menu_init: sep #$20 : .as rep #$10 : .xl lda #^ROOT_DIR ldx #!ROOT_DIR sta dirptr_bank stx dirptr_addr sta dirstart_bank stx dirstart_addr stz menu_state stz dirend_onscreen lda #$02 sta cursor_x lda #$09 sta cursor_y lda #$01 sta bar_xl lda #$3e sta bar_wl ldx #$0000 stx dirptr_idx stx menu_sel stx direntry_xscroll stx direntry_xscroll_state lda #$01 sta menu_dirty rep #$20 : .al lda #!dirlog sta dirlog_idx sep #$20 : .as lda #^dirlog sta dirlog_idx+2 rts menuloop: menuloop_s1 sep #$20 : .as rep #$10 : .xl lda isr_done lsr bcc menuloop_s1 stz isr_done jsr printtime jsr menu_updates ;update stuff, check keys etc lda menu_dirty ;is there ANY reason to redraw the menu? cmp #$01 beq menuloop_redraw ;then do jsr scroll_direntry bra menuloop_s1 menuloop_redraw stz menu_dirty jsr menu_statusbar jsr menu_redraw jsr menu_cleanup ;update phase 2 bra menuloop_s1 rts menu_cleanup: sep #$20 : .as rep #$10 : .xl lda dirend_onscreen ;end of file list on screen? beq menu_cleanup_out ; lda dirend_idx lsr lsr pha menu_cleanup_loop ;pad rest of screen with empty lines cmp listdisp ;end of screen reached? beq + ;then leave pha clc adc #$09 ;first line in text area inc sta print_y stz print_x lda #^space64 ldx #!space64 sta print_bank stx print_src stz print_pal lda #64 sta print_count jsr hiprint pla inc bra menu_cleanup_loop + pla cmp menu_sel beq menu_cleanup_out bpl menu_cleanup_out sta menu_sel menu_cleanup_out rts menu_updates: ;update selection, scroll etc lda menu_sel asl asl sta dirptr_idx lda menu_sel clc adc #$08 sta bar_yl lda #$3e sta bar_wl lda #$01 sta bar_xl ;get input jsr read_pad lda #$04 and pad1trig+1 bne key_down lda #$08 and pad1trig+1 bne key_up lda #$01 and pad1trig+1 bne key_right lda #$02 and pad1trig+1 bne key_left lda #$80 and pad1trig+1 bne key_b lda #$10 and pad1trig+1 bne key_start lda #$20 and pad1trig+1 bne key_select lda #$80 and pad1trig bne key_a lda #$40 and pad1trig bne key_x bra menuupd_out key_down jsr menu_key_down bra menuupd_out key_up jsr menu_key_up bra menuupd_out key_right jsr menu_key_right bra menuupd_out key_left jsr menu_key_left bra menuupd_out key_b jsr menu_key_b bra menuupd_out key_a jsr menu_key_a bra menuupd_out key_x jsr menu_key_x bra menuupd_out key_select jsr menu_key_select bra menuupd_out key_start jsr menu_key_start bra menuupd_out menuupd_out lda #$09 sta cursor_y rts menu_redraw: lda menu_state beq redraw_filelist ; cmp 1 ; beq redraw_main menu_redraw_out rts redraw_filelist ldy #$0000 sty dirptr_idx sty direntry_fits_idx stz dirend_idx stz dirend_onscreen redraw_filelist_loop ldy dirptr_idx tya lsr lsr cmp listdisp beq redraw_filelist_last rep #$20 : .al lda [dirptr_addr], y sta @dirent_addr iny iny sep #$20 : .as lda [dirptr_addr], y ; load fileinfo bank clc adc #$c0 ; add $C0 for memory map sta @dirent_bank ; store as current bank cmp #$c0 ; if bank was 0 -> dirend entry in DB beq redraw_filelist_dirend ; handle dirend iny lda [dirptr_addr], y iny sta @dirent_type sty dirptr_idx jsr print_direntry inc direntry_fits_idx bra redraw_filelist_loop redraw_filelist_dirend dey ; recover last valid direntry number dey ; (we had 2x iny of the direntry pointer above, beq + dey ; so account for those too) dey dey dey + sty dirend_idx ; dirend_idx <- last valid directory entry. lda #$01 ; encountered during redraw, so must be on screen sta dirend_onscreen bra redraw_filelist_out redraw_filelist_last ;check if next offscreen item is end of dir iny iny lda [dirptr_addr], y beq redraw_filelist_dirend redraw_filelist_out ldx #$0000 stx dirptr_idx brl menu_redraw_out print_direntry: lda cursor_y sta print_y inc sta cursor_y lda dirent_bank ldx dirent_addr phb pha plb lda @dirent_type and #$f0 cmp #$80 rep #$20 : .al bne dirent_is_file dirent_is_dir lda #$04 ;skip dir tgt sta @fd_fnoff lda #$01 ;different color for dirs bra dirent_type_cont dirent_is_file lda #$06 ;skip size string sta @fd_fnoff lda @dirent_type and #$00ff cmp #$0001 ;SMC -> palette 0 (white) bne + lda #$0000 bra dirent_type_cont + cmp #$0003 ;SPC -> palette 2 bne + lda #$0002 bra dirent_type_cont cmp #$0004 ;IPS -> palette 2 (green) bne + lda #$0002 bra dirent_type_cont + lda #$0000 ;default -> palette 0 dirent_type_cont sta @print_pal rep #$20 : .al txa clc adc @fd_fnoff tax sep #$20 : .as lda !0, x ;load offset of leaf (file) name inc rep #$20 : .al and #$00ff ;kill hi byte sta @fd_fnoff txa clc adc @fd_fnoff clc adc @direntry_xscroll sta @fd_fnoff plb lda cursor_x sta print_x sep #$20 : .as ldx fd_fnoff lda #54 sta print_count stx print_src lda dirent_bank sta print_bank jsr hiprint lda cursor_x clc adc print_done sta print_x lda print_over ldy direntry_fits_idx sta !direntry_fits, y lda #54 sec sbc print_done sta print_count lda #^space64 ldx #!space64 sta print_bank stx print_src jsr hiprint sep #$20 : .as lda dirent_type and #$f0 cmp #$80 bne dirent_is_file_2 lda #^text_dirmark ldx #!text_dirmark sta print_bank stx print_src bra dirent_type_cont_2 dirent_is_file_2 lda dirent_bank ldx dirent_addr sta print_bank stx print_src dirent_type_cont_2 lda #56 sta print_x lda #6 sta print_count jsr hiprint rts menu_key_down: jsr scroll_direntry_clean lda listdisp dec cmp menu_sel bne down_noscroll lda #$01 sta menu_dirty lda dirend_onscreen bne down_out rep #$20 : .al lda dirptr_addr clc adc #$04 bcc + inc dirptr_bank + sta dirptr_addr sep #$20 : .as rts down_noscroll lda dirend_onscreen beq + lda dirend_idx lsr lsr cmp menu_sel beq menuupd_lastcursor bcc menuupd_lastcursor + lda menu_sel inc sta menu_sel down_out rts menu_key_up: jsr scroll_direntry_clean lda menu_sel bne up_noscroll lda #$01 sta menu_dirty rep #$20 : .al lda dirptr_addr cmp dirstart_addr beq up_out sec sbc #$04 bcs + dec dirptr_bank + sta dirptr_addr bra up_out up_noscroll dec sta menu_sel up_out sep #$20 : .as rts menuupd_lastcursor jsr scroll_direntry_clean lda dirend_idx lsr lsr sta menu_sel rts ; go back one page menu_key_left: stz direntry_xscroll stz direntry_xscroll_state lda #$01 ; must redraw afterwards sta menu_dirty rep #$20 : .al lda dirptr_addr ; get current direntry pointer beq + ; special case: if 0, we are at the first entry in memory lsr lsr ; make comparable to listdisp cmp listdisp ; if there's less or equal previous entries... beq + ; ...than display lines, reset to directory start bcc + sec sbc listdisp ; subtract one screen page's worth of entries asl asl ; make comparable to dirstart_addr again cmp dirstart_addr ; check whether calculated offset is before... bcc + ; ...start of directory - sta dirptr_addr ; store new selected entry sep #$20 : .as rts + lda dirstart_addr ; reset pointer to start of directory stz menu_sel ; reset the selection cursor too bra - ; go forth one page menu_key_right: stz direntry_xscroll stz direntry_xscroll_state sep #$20 : .as lda dirend_onscreen bne menuupd_lastcursor lda #$01 sta menu_dirty rep #$20 : .al lda listdisp asl asl clc adc dirptr_addr sta dirptr_addr sep #$20 : .as rts menu_key_a: jsr select_item rts menu_key_select: rts menu_key_start: jsr select_last_file rts menu_key_b: stz direntry_xscroll stz direntry_xscroll_state rep #$20 : .al lda dirstart_addr beq skip_key_b sta dirptr_addr lda #$0000 sta menu_sel bra select_item skip_key_b sep #$20 : .as rts select_item: rep #$20 : .al lda menu_sel and #$00ff asl asl tay sep #$20 : .as iny iny iny lda [dirptr_addr], y cmp #$01 beq sel_is_file cmp #$03 beq sel_is_spc cmp #$04 beq sel_is_file cmp #$80 beq sel_is_dir cmp #$81 beq sel_is_parent select_item_cont rts sel_is_file jsr select_file bra select_item_cont sel_is_parent jsr select_parent bra select_item_cont sel_is_dir jsr select_dir bra select_item_cont sel_is_spc jsr select_spc bra select_item_cont select_file: ; have MCU load the rom dey rep #$20 : .al lda [dirptr_addr], y and #$00ff sta @MCU_PARAM+2 dey dey lda [dirptr_addr], y sta @MCU_PARAM sep #$20 : .as lda #$00 sta @$4200 sei lda #$01 sta @MCU_CMD select_file_fade: jsl @wram_fadeloop rts select_dir: tyx ; save old dir position rep #$20 : .al ldy #$0000 lda @dirstart_addr sta [dirlog_idx], y iny iny lda @dirstart_bank sta [dirlog_idx], y iny lda @dirptr_addr sta [dirlog_idx], y iny iny lda @dirptr_bank sta [dirlog_idx], y iny lda @menu_sel sta [dirlog_idx], y lda @dirlog_idx clc adc #$0008 sta @dirlog_idx sep #$20 : .as ;--- ; y = direntry ptr txy dey lda [dirptr_addr], y clc adc #$c0 sta @dirent_bank dey dey rep #$20 : .al lda [dirptr_addr], y sta @dirent_addr tax sep #$20 : .as lda @dirent_bank phb pha plb lda !2, x ; load linked dir start bank clc adc #$c0 sta @dirptr_bank sta @dirstart_bank rep #$20 : .al lda !0, x ; load linked dir start address sta @dirptr_addr sta @dirstart_addr lda #$0000 sta @menu_sel sta @direntry_xscroll sta @direntry_xscroll_state sep #$20 : .as lda #$01 sta @menu_dirty plb rts select_parent: rep #$20 : .al lda @dirlog_idx sec sbc #$0008 sta @dirlog_idx ldy #$0000 lda [dirlog_idx], y ; load dirstart_addr sta @dirstart_addr iny iny sep #$20 : .as lda [dirlog_idx], y ; load dirstart_bank sta @dirstart_bank iny rep #$20 : .al lda [dirlog_idx], y ; load dirptr_addr sta @dirptr_addr iny iny sep #$20 : .as lda [dirlog_idx], y ; load dirptr_bank sta @dirptr_bank iny rep #$20 : .al lda [dirlog_idx], y ; load menu_sel sta @menu_sel sep #$20 : .as lda #$01 sta @menu_dirty rts select_spc: dey rep #$20 : .al lda [dirptr_addr], y and #$00ff sta @MCU_PARAM+2 dey dey lda [dirptr_addr], y sta @MCU_PARAM sep #$20 : .as lda #CMD_LOADSPC sta @MCU_CMD wait_spc: lda @MCU_CMD cmp #$00 bne wait_spc jsr spcplayer jsr restore_screen rts menu_key_x: jsr mainmenu rts setup_224: php rep #$30 : .xl : .al lda #18 sta listdisp dec cmp menu_sel bmi setup_224_adjsel bra + setup_224_adjsel sta menu_sel + lda #18*64 sta textdmasize lda #$000b sta hdma_scroll+8 sep #$20 : .as lda #$0b sta $2110 lda #$00 sta $2110 lda #$00 sta barstep ora #$08 sta $2133 lda #$08 sta hdma_math_selection stz vidmode lda #$01 sta menu_dirty lda #^space64 ldx #!space64 sta print_bank stx print_src stz print_pal lda #64 sta print_count lda #27 sta print_y stz print_x jsr hiprint lda #28 sta print_y jsr hiprint jsr hiprint plp rts menu_statusbar pha phx php sep #$20 : .as rep #$10 : .xl lda #^text_statusbar_keys sta @print_bank rep #$20 : .al lda #!text_statusbar_keys sta @print_src sep #$20 : .as lda #$00 sta @print_pal lda #$02 sta @print_x lda #$40 sta @print_count lda listdisp clc adc #$0a clc adc vidmode sta @print_y jsr hiprint plp plx pla rts select_last_file: php sep #$20 : .as rep #$10 : .xl lda @LAST_STATUS bne + plp rts + jsr backup_screen lda #^text_last sta window_tbank ldx #!text_last stx window_taddr lda @last_win_x sta window_x inc inc sta bar_xl pha lda @last_win_y sta window_y inc sta bar_yl inc pha lda @last_win_w sta window_w lda @last_win_h sta window_h jsr draw_window stz print_pal lda #^LAST_GAME ldx #!LAST_GAME sta print_bank stx print_src stz print_pal pla sta print_y pla sta print_x lda #56 sta bar_wl sta print_count jsr hiprint - lda isr_done lsr bcc - jsr printtime jsr read_pad lda #$80 and pad1trig+1 bne + lda #$10 and pad1trig+1 beq - lda #$04 sta @MCU_CMD jmp select_file_fade + jsr restore_screen plp rts scroll_direntry_clean: lda #$01 sta direntry_xscroll_state stz direntry_xscroll stz direntry_xscroll_wait jsr scroll_direntry stz direntry_xscroll_state stz direntry_xscroll rts scroll_direntry: ldy menu_sel lda direntry_xscroll_state bne + lda direntry_fits, y bne scroll_direntry_enter ; stz direntry_xscroll_state rts scroll_direntry_enter lda #$01 sta direntry_xscroll_state stz direntry_xscroll_wait + lda direntry_xscroll_wait beq + dec direntry_xscroll_wait rts + lda direntry_xscroll bne scroll_direntry_scrollfast lda #$28 bra + scroll_direntry_scrollfast lda #$10 + sta direntry_xscroll_wait tya clc adc #$09 sta cursor_y lda #$02 sta cursor_x rep #$20 : .al lda menu_sel asl asl tay lda [dirptr_addr], y sta @dirent_addr iny iny sep #$20 : .as lda [dirptr_addr], y ; load fileinfo bank clc adc #$c0 ; add $C0 for memory map sta @dirent_bank ; store as current bank iny lda [dirptr_addr], y iny sta @dirent_type ldy menu_sel sty direntry_fits_idx phy jsr print_direntry ply lda direntry_fits, y bne + lda #$ff sta direntry_xscroll_state lda #$28 sta direntry_xscroll_wait + lda direntry_xscroll_state clc adc direntry_xscroll sta direntry_xscroll bne + lda #$01 sta direntry_xscroll_state + rts