Mercurial > repos > blastem
view menu.s68 @ 940:4f4f8385da8d
Fix saving of SRAM/EEPROM when switching games in menu
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 25 Feb 2016 23:39:14 -0800 |
parents | 5e90fa4da2ec |
children | c96647630320 |
line wrap: on
line source
dc.l $0, start dc.l empty_handler dc.l empty_handler ;$10 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$20 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$30 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$40 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$50 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$60 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$70 dc.l int_4 dc.l empty_handler dc.l int_6 dc.l empty_handler ;$80 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$90 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$A0 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$B0 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$C0 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$D0 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$E0 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler ;$F0 dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.l empty_handler dc.b "SEGA GENESIS " dc.b "(c) 2015.JULY " dc.b "Menu " dc.b " " dc.b " " dc.b "Menu " dc.b " " dc.b " " dc.b "MP BlstMenu-00", 0, 0 dc.b " " dc.l $0, rom_end-1, $FF0000, $FFFFFF dc.b " " dc.b " " dc.b " " dc.b " " dc.b "JUE " ;register addresses VDP_DATA equ $C00000 VDP_CTRL equ $C00004 VDP_HV equ $C00008 Z80_RAM equ $A00000 IO_AREA equ $A10000 PAD1_DATA equ (IO_AREA + 3) PAD2_DATA equ (IO_AREA + 5) EXT_DATA equ (IO_AREA + 7) PAD1_CTRL equ (IO_AREA + 9) PAD2_CTRL equ (IO_AREA + 11) EXT_CTRL equ (IO_AREA + 13) MODE_1 equ 0 MODE_2 equ 1 SCROLL_A equ 2 WINDOW equ 3 SCROLL_B equ 4 SAT equ 5 BG_COLOR equ 7 HINT equ $A MODE_3 equ $B MODE_4 equ $C HSCROLL equ $D AUTOINC equ $F SCROLL EQU $10 WINDOW_H equ $11 WINDOW_V equ $12 DMALEN_L equ $13 DMALEN_H equ $14 DMASRC_L equ $15 DMASRC_M equ $16 DMASRC_H equ $17 VDP_VRAM_WRITE equ $40000000 VDP_CRAM_WRITE equ $C0000000 VDP_VSRAM_WRITE equ $40000010 VDP_DMA_FLAG equ $80 vdpregset macro move.w #(((\1) << 8) | $8000 | (\2)), (a1) endm vdpreg macro dc.w (((\1) << 8) | $8000 | (\2)) endm ;Writes a normal VDP command to the control port ;\1 - VDP address ;\2 - Access type vdpaccess macro move.l #((\2) | (\1) << 16 & $3FFF0000 | (\1) >> 14 & 3), (a1) endm ;Writes a DMA command to the control port ;\1 - Destination address ;\2 - Destination type startdma macro move.l #(\2 | VDP_DMA_FLAG | (\1 << 16) & $3FFF0000 | (\1 >> 14) & 3), (a1) endm DMA_SRC_68K equ 0 DMA_SRC_VRAM equ $C0 DMA_SRC_FILL equ $80 dmasrc macro move.l #($95009600 + (\1) << 15 & $FF0000 + (\1) >> 9 & $FF), (a1) move.w #($9700 + (\1) >> 17 & $7F | (\2)), (a1) endm dir_buffer equ $100000 menu_port equ $180000 MAX_DISPLAY equ 24 rsset $FFFF8000 x_pos rs.w 1 base_cmd rs.l 1 sprite_list rs.l 160 page_index rs.l MAX_DISPLAY+1 page_stack rs.l 1 page_pointers rs.l 1024 mouse_sprite rs.l 1 mouse_x rs.w 1 num_sprites rs.b 1 last_pad1 rs.b 1 last_pad2 rs.b 1 selected rs.b 1 more_pages rs.b 1 mouse_buf rs.b 3 mouse_shown rs.b 1 last_mbuttons rs.b 1 int_6: dmasrc sprite_list, DMA_SRC_68K ;set DMA length move.l #$94009300, d0 moveq #0, d1 move.b num_sprites.w, d1 add.w d1, d1 add.w d1, d1 move.b d1, d0 swap d0 lsr.w #8, d1 move.b d1, d0 move.l d0, (a1) startdma $C000, VDP_VRAM_WRITE ;read gamepad/mouse in port 1 lea PAD1_DATA, a2 bsr io_read cmp.b #3, d2 beq .mouse move.b last_pad1.w, d1 eor.b d0, d1 and.b d0, d1 move.b d0, last_pad1.w bsr handle_pad_buttons bra pad2 .mouse bsr handle_mouse pad2: ;read gamepad/mouse in port 2 lea PAD2_DATA, a2 bsr io_read cmp.b #3, d2 beq .mouse move.b last_pad2.w, d1 eor.b d0, d1 and.b d0, d1 move.b d0, last_pad2.w bsr handle_pad_buttons rte .mouse bsr handle_mouse rte ;d0 = SACBRLUD ;d1 = newly pressed buttons handle_pad_buttons: moveq #16, d2 btst #1, d1 bne down btst #0, d1 bne up btst #3, d1 bne right btst #2, d1 bne left btst #7, d1 bne select_entry btst #5, d1 bne select_entry handle_done: rts down: ;check if we are already at the bottom of the page moveq #1, d0 add.b (selected).w, d0 move.w d0, d1 add.w d0, d0 add.w d0, d0 lea page_index.w, a2 tst.l (0, a2, d0.w) beq handle_done move.b d1, (selected).w add.w d2, (sprite_list).w add.w d2, (sprite_list+8).w rts up: ;check if we are already at the top of the page move.b (selected).w, d0 beq handle_done subq #1, d0 move.b d0, (selected).w sub.w d2, (sprite_list).w sub.w d2, (sprite_list+8).w rts right: ;check that we have another page to go to tst.b more_pages.w beq handle_done ;switch to the next page move.l page_stack.w, a6 move.l (-4, a6), a6 addq #6, a7 bra render_page left: move.l page_stack.w, a5 ;check if we're already on the first page cmp.l #(page_pointers+8), a5 beq handle_done ;switch to previous page lea (-12, a5), a5 move.l (a5)+, a6 move.l a5, page_stack.w addq #6, a7 bra render_page select_entry: moveq #0, d0 move.b (selected).w, d0 add.w d0, d0 add.w d0, d0 lea page_index.w, a2 move.l (0, a2, d0.w), a2 tst.b (-1, a2) bne enter_dir ;regular file lea menu_port+8, a3 move.l a2, (a3) rts enter_dir: lea menu_port+4, a3 move.l a2, (a3) .wait_complete tst.w (a3) bne .wait_complete addq #6, a7 bra menu_start handle_mouse: move.b last_mbuttons.w, d4 eor.b d3, d4 and.b d3, d4 move.b d3, last_mbuttons.w move.b d0, d2 or.b d1, d2 beq .no_mouse_move tst.b mouse_shown.w bne .skip_show_check moveq #0, d2 move.b num_sprites.w, d2 move.w d2, d4 lsl.w #3, d4 lea sprite_list.w, a2 move.b d2, (-5, a2, d4.w) lea (0, a2, d4.w), a2 move.l a2, mouse_sprite.w move.l #$01000500, (a2)+ move.w #$8083, (a2) move.w #$100, mouse_x.w addq #1, d2 move.b d2, num_sprites.w move.b #1, mouse_shown.w .skip_show_check neg.w d1 move.l mouse_sprite.w, a2 add.w d1, (a2) add.w d0, mouse_x.w move.w mouse_x.w, d0 asr.w #1, d0 move.w d0, (6, a2) move.w (a2), d1 cmp.w #272, d1 blo .done cmp.w #655, d1 bhi .done and.w #$FFF0, d1 subq #8, d1 move.w d1, (sprite_list).w move.w d1, (sprite_list+8).w sub.w #264, d1 lsr.w #4, d1 move.b d1, selected.w .no_mouse_move btst #0, d4 bne select_entry .done rts int_4: empty_handler: rte id_lookup: dc.b $0, $1, $4, $5 dc.b $2, $3, $6, $7 dc.b $8, $9, $C, $D dc.b $A, $B, $E, $F io_read: ;read TH=1 move.b (a2), d0 ;read TH=0 move.b #0, (a2) nop nop move.b (a2), d1 ;reset TH to 1 move.b #$40, (a2) moveq #0, d2 ;4 ;calculate Mega Drive peripheral ID move.b d1, d2 ;4 lsr.b #1, d2 ;8, 12 or.b d1, d2 ;4, 16 and.b #5, d2 ;8, 24 move.b d0, d3 ;4 add.b d3, d3 ;4, 8 or.b d0, d3 ;4, 12 and.b #$A, d3 ;8, 20 or.b d3, d2 ;4 move.b (id_lookup, pc, d2.w), d2 ;14 cmp.b #$3, d2 beq .mouse cmp.b #$D, d2 bne .not_pad and.b #$3F, d0 and.b #$30, d1 add.b d1, d1 add.b d1, d1 or.b d1, d0 not.b d0 rts .not_pad: moveq #0, d0 rts .mouse: move.b #$60, (a2) move.b #$60, (PAD1_CTRL-PAD1_DATA, a2) move.b #$60, (a2) moveq #$f, d4 wait_hi_init: btst #4, (a2) beq wait_hi_init nop nop move.b #$20, (a2) nop nop moveq #$f, d4 move.b #0, (a2) .wait_lo btst #4, (a2) bne .wait_lo moveq #$f, d4 move.b #$20, (a2) .wait_hi btst #4, (a2) beq .wait_hi lea mouse_buf.w, a3 move.l a3, a4 moveq #2, d3 moveq #0, d0 loop: moveq #$f, d4 move.b #0, (a2) .wait_lo btst #4, (a2) bne .wait_lo move.b (a2), d0 lsl.b #4, d0 moveq #$f, d4 move.b #$20, (a2) .wait_hi btst #4, (a2) beq .wait_hi move.b (a2), d1 and.b #$f, d1 or.b d1, d0 move.b d0, (a3)+ dbra d3, loop ;end request move.b #$60, (a2) ;massage data moveq #0, d1 move.b d0, d1 move.b (a4)+, d3 move.b (a4), d0 btst #4, d3 beq xpos or.w #$FF00, d0 xpos btst #5, d3 beq ypos or.w #$FF00, d1 ypos ;set port config back to normal controller mode move.b #$40, (PAD1_CTRL-PAD1_DATA, a2) rts topcorner equ (button-font)/64 + 32 topmiddle equ topcorner+1 botcorner equ topmiddle+1 botmiddle equ botcorner+1 horiz_flip equ $800 vert_flip equ $1000 ; draws a button ; d0.w - x in cells ; d1.w - y in cells ; d2.w - width in cells ; ; clobbers a6 draw_button: ;multiply x by 2 add.w d0, d0 ;multiply y by 128 lsl.w #7, d1 add.w d1, d0 add.w #$A000, d0 move.w d0, d1 and.w #$3FFF, d0 rol.w #2, d1 and.w #3, d1 ori.w #(VDP_VRAM_WRITE >> 16), d0 swap d0 move.w d1, d0 move.l d0, (a1) move.w d2, d1 ;top left corner move.w #topcorner, (a0) subq #3, d1 bmi .notopmiddle .toploop: ;top middle move.w #topmiddle, (a0) dbra d1, .toploop .notopmiddle ;top right corner move.w #(topcorner | horiz_flip), (a0) ;go to next row in name table add.l #((2*64) << 16), d0 move.l d0, (a1) ;bottom left corner move.w #botcorner, (a0) subq #3, d2 bmi .nomiddlebot .botloop: ;bottom middle move.w #botmiddle, (a0) dbra d2, .botloop .nomiddlebot ;bottom right corner move.w #(botcorner | horiz_flip), (a0) rts initial_regs: vdpreg MODE_2, $4 ;Mode 5, everything turned off vdpreg MODE_1, $4 vdpreg SCROLL_A, $20 ;Scroll a table $8000 vdpreg SCROLL_B, $05 ;Scroll b table $A000 vdpreg SAT, $60 ;SAT table $C000 vdpreg BG_COLOR, 0 vdpreg HINT, $FF vdpreg MODE_3, 0 ;full screen scroll vdpreg MODE_4, $87 ;40 cell mode, double-res interlace vdpreg HSCROLL, 0 vdpreg AUTOINC, 2 vdpreg SCROLL, 1 ;64x32 scroll size end_initial_regs start: lea $FF0000, a0 moveq #0, d0 move.w #($10000/8 - 1), d1 .clearloop: move.l d0, (a0)+ move.l d0, (a0)+ dbra d1, .clearloop lea $C00000, a0 lea $C00004, a1 moveq #(end_initial_regs-initial_regs-1), d0 lea initial_regs.w, a2 .regloop move.w (a2)+, (a1) dbra d0, .regloop vdpaccess $0, VDP_CRAM_WRITE move.w #$020, (a0) move.w #$EEE, (a0) move.w #$222, (a0) ;init scroll table vdpaccess $0, VDP_VRAM_WRITE move.w #0, (a0) move.w #4, (a0) ;load tiles vdpaccess $800, VDP_VRAM_WRITE lea font(pc), a2 move.w #((buttonend-font)/4 - 1), d0 tloop: move.l (a2)+, (a0) dbra d0, tloop ;setup SAT ;;vdpaccess $C000, VDP_VRAM_WRITE lea sprite_list.w, a2 ;left arrow move.l #$01080501, (a2)+ move.l #$807F0086, (a2)+ ;right arrow move.l #$01080500, (a2)+ move.l #$887F01AA, (a2)+ move.b #2, num_sprites.w menu_start: lea page_pointers.w, a5 lea dir_buffer, a6 move.l a6, (a5)+ move.l a5, page_stack.w lea menu_port, a2 move.l a6, (a2) wait_complete: tst.w (a2) bne wait_complete render_page: ;clear name tables vdpaccess $8000, VDP_VRAM_WRITE moveq #32, d0 swap d0 move.b #32, d0 move.w #(64*64-1), d1 ploop: move.l d0, (a0) dbra d1, ploop ;moveq #0, d0 ;moveq #26, d1 ;moveq #6, d2 ;bsr draw_button move.l #$40860002, d3 move.l d3, (a1) move.l d3, base_cmd.w move.b #0, more_pages.w lea page_index.w, a3 moveq #MAX_DISPLAY-1, d7 file_loop: tst.b (a6)+ beq done_files addq #1, a6 ;TODO: Do something with directory flag ;skip over entries starting with a dot except .. cmp.b #$2E, (a6) bne normal cmp.b #$2E, (1, a6) beq normal addq #1, a6 .skip_loop: tst.b (a6)+ bne .skip_loop addq #1, d7 move.l a6, d6 bra skip normal: ;save entry pointer to page index move.l a6, (a3)+ ;print name on screen moveq #0, d0 bsr print_string move.l a6, d6 lea Newline(pc), a6 bsr print_string skip: ;word align pointer addq #1, d6 and.w #$FFFE, d6 move.l d6, a6 dbra d7, file_loop tst.b (a6) beq done_files move.b #1, more_pages.w done_files: move.l page_stack.w, a5 move.l a6, (a5)+ move.l a5, page_stack.w ;null terminate page_index moveq #0, d0 move.l d0, (a3) ;setup gamepads move.b #$40, PAD1_CTRL move.b #$40, PAD2_CTRL move.w #$8174, (a1) ;enable display, vertical interrupts, DMA wait_forever stop #2500 bra wait_forever Newline: dc.b $A, 0 align 1 ;Prints a null terminated string ;a6 - pointer to string ;a0 - VDP data port ;d0 - base tile attribute ; ;Clobbers: d1.w, d2.w, d3.l print_string: lea widths(pc), a5 move.w x_pos.w, d2 move.l base_cmd.w, d3 .loop moveq #0, d1 move.b (a6)+, d1 beq .end cmp.b #$A, d1 beq .newline tst.b (-32, a5, d1.w) beq .narrow add.w d0, d1 move.w d1, (a0) addq #2, d2 bra .loop .narrow add.w d0, d1 move.w d1, (a0) addq #1, d2 move.l d2, d1 ;switch to other plane and.w #$FFFE, d1 swap d1 eor.l #$20000000, d3 add.l d3, d1 move.l d1, (a1) bra .loop .newline moveq #0, d2 ;switch back to plane A and.l #$DFFFFFFF, d3 ;skip to next row add.l #$00800000, d3 move.l d3, (a1) bra .loop .end move.w d2, x_pos.w move.l d3, base_cmd.w rts align 1 font: incbin font_interlace_variable.tiles fontend arrow: incbin arrow.tiles arrowend: cursor: incbin cursor.tiles cursorend: button: incbin button.tiles buttonend: widths: dc.b 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1 dc.b 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0 dc.b 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1 dc.b 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 dc.b 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 rom_end: