Mercurial > repos > blastem
view menu.s68 @ 915:9e882eca717e
Initial support for relative mouse mode and skeleton of support for capture mode. Avoid mouse position overflow in absolute mode. Allow absolute mode to be set by ROM DB.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 15 Dec 2015 20:01:50 -0800 |
parents | c030e4af32b7 |
children | f057975212e9 |
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 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 #((cursorend-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 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: 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: