main
menu.s68
1 dc.l $0, start
2 dc.l empty_handler
3 dc.l empty_handler
4 ;$10
5 dc.l empty_handler
6 dc.l empty_handler
7 dc.l empty_handler
8 dc.l empty_handler
9 ;$20
10 dc.l empty_handler
11 dc.l empty_handler
12 dc.l empty_handler
13 dc.l empty_handler
14 ;$30
15 dc.l empty_handler
16 dc.l empty_handler
17 dc.l empty_handler
18 dc.l empty_handler
19 ;$40
20 dc.l empty_handler
21 dc.l empty_handler
22 dc.l empty_handler
23 dc.l empty_handler
24 ;$50
25 dc.l empty_handler
26 dc.l empty_handler
27 dc.l empty_handler
28 dc.l empty_handler
29 ;$60
30 dc.l empty_handler
31 dc.l empty_handler
32 dc.l empty_handler
33 dc.l empty_handler
34 ;$70
35 dc.l int_4
36 dc.l empty_handler
37 dc.l int_6
38 dc.l empty_handler
39 ;$80
40 dc.l empty_handler
41 dc.l empty_handler
42 dc.l empty_handler
43 dc.l empty_handler
44 ;$90
45 dc.l empty_handler
46 dc.l empty_handler
47 dc.l empty_handler
48 dc.l empty_handler
49 ;$A0
50 dc.l empty_handler
51 dc.l empty_handler
52 dc.l empty_handler
53 dc.l empty_handler
54 ;$B0
55 dc.l empty_handler
56 dc.l empty_handler
57 dc.l empty_handler
58 dc.l empty_handler
59 ;$C0
60 dc.l empty_handler
61 dc.l empty_handler
62 dc.l empty_handler
63 dc.l empty_handler
64 ;$D0
65 dc.l empty_handler
66 dc.l empty_handler
67 dc.l empty_handler
68 dc.l empty_handler
69 ;$E0
70 dc.l empty_handler
71 dc.l empty_handler
72 dc.l empty_handler
73 dc.l empty_handler
74 ;$F0
75 dc.l empty_handler
76 dc.l empty_handler
77 dc.l empty_handler
78 dc.l empty_handler
79 dc.b "SEGA GENESIS "
80 dc.b "(c) 2015.JULY "
81 dc.b "Menu "
82 dc.b " "
83 dc.b " "
84 dc.b "Menu "
85 dc.b " "
86 dc.b " "
87 dc.b "MP BlstMenu-00", 0, 0
88 dc.b " "
89 dc.l $0, rom_end-1, $FF0000, $FFFFFF
90 dc.b " "
91 dc.b " "
92 dc.b " "
93 dc.b " "
94 dc.b "JU "
95
96;register addresses
97VDP_DATA equ $C00000
98VDP_CTRL equ $C00004
99VDP_HV equ $C00008
100Z80_RAM equ $A00000
101IO_AREA equ $A10000
102PAD1_DATA equ (IO_AREA + 3)
103PAD2_DATA equ (IO_AREA + 5)
104EXT_DATA equ (IO_AREA + 7)
105PAD1_CTRL equ (IO_AREA + 9)
106PAD2_CTRL equ (IO_AREA + 11)
107EXT_CTRL equ (IO_AREA + 13)
108
109MODE_1 equ 0
110MODE_2 equ 1
111SCROLL_A equ 2
112WINDOW equ 3
113SCROLL_B equ 4
114SAT equ 5
115BG_COLOR equ 7
116HINT equ $A
117MODE_3 equ $B
118MODE_4 equ $C
119HSCROLL equ $D
120AUTOINC equ $F
121SCROLL EQU $10
122WINDOW_H equ $11
123WINDOW_V equ $12
124DMALEN_L equ $13
125DMALEN_H equ $14
126DMASRC_L equ $15
127DMASRC_M equ $16
128DMASRC_H equ $17
129
130VDP_VRAM_WRITE equ $40000000
131VDP_CRAM_WRITE equ $C0000000
132VDP_VSRAM_WRITE equ $40000010
133VDP_DMA_FLAG equ $80
134
135vdpregset macro
136 move.w #(((\1) << 8) | $8000 | (\2)), (a1)
137 endm
138
139vdpreg macro
140 dc.w (((\1) << 8) | $8000 | (\2))
141 endm
142
143;Writes a normal VDP command to the control port
144;\1 - VDP address
145;\2 - Access type
146vdpaccess macro
147 ifeq NARG-2
148 move.l #((\2) | (\1) << 16 & $3FFF0000 | (\1) >> 14 & 3), (a1)
149 else
150 move.l #((\2) | (\1) << 16 & $3FFF0000 | (\1) >> 14 & 3), \3
151 endif
152 endm
153
154;Writes a DMA command to the control port
155;\1 - Destination address
156;\2 - Destination type
157startdma macro
158 move.l #(\2 | VDP_DMA_FLAG | (\1 << 16) & $3FFF0000 | (\1 >> 14) & 3), (a1)
159 endm
160
161DMA_SRC_68K equ 0
162DMA_SRC_VRAM equ $C0
163DMA_SRC_FILL equ $80
164
165dmasrc macro
166 move.l #($95009600 + (\1) << 15 & $FF0000 + (\1) >> 9 & $FF), (a1)
167 move.w #($9700 + (\1) >> 17 & $7F | (\2)), (a1)
168 endm
169
170dir_buffer equ $100000
171menu_port equ $180000
172load_rom_port equ (menu_port+2*4)
173lock_on_port equ (menu_port+8*4)
174
175MAX_DISPLAY equ 24
176
177 rsset $FFFF8000
178x_pos rs.w 1
179base_cmd rs.l 1
180sprite_list rs.l 160
181page_index rs.l MAX_DISPLAY+1
182page_stack rs.l 1
183page_pointers rs.l 1024
184mouse_sprite rs.l 1
185menu_functions rs.l 1
186cursor_show_fun rs.l 1
187special_click rs.l 1
188rom_load_addr rs.l 1
189mouse_x rs.w 1
190selection_top rs.w 1
191selection_bot rs.w 1
192selection_mask rs.w 1
193num_sprites rs.b 1
194last_pad1 rs.b 1
195last_pad2 rs.b 1
196selected rs.b 1
197more_pages rs.b 1
198mouse_buf rs.b 3
199mouse_shown rs.b 1
200last_mbuttons rs.b 1
201num_menu rs.b 1
202num_slots rs.b 1
203port_off rs.b 1
204
205
206int_6:
207 dmasrc sprite_list, DMA_SRC_68K
208 ;set DMA length
209 move.l #$94009300, d0
210 moveq #0, d1
211 move.b num_sprites.w, d1
212 add.w d1, d1
213 add.w d1, d1
214 move.b d1, d0
215 swap d0
216 lsr.w #8, d1
217 move.b d1, d0
218 move.l d0, (a1)
219 startdma $C000, VDP_VRAM_WRITE
220
221 move.w (menu_port+4*7), d0
222 btst #0, d0
223 bne show_pause_menu
224
225 ;read gamepad/mouse in port 1
226 lea PAD1_DATA, a2
227
228 bsr io_read
229
230 cmp.b #3, d2
231 beq .mouse
232
233 move.b last_pad1.w, d1
234 eor.b d0, d1
235 and.b d0, d1
236 move.b d0, last_pad1.w
237
238 bsr handle_pad_buttons
239
240 bra pad2
241.mouse
242 bsr handle_mouse
243
244pad2:
245 ;read gamepad/mouse in port 2
246 lea PAD2_DATA, a2
247
248 bsr io_read
249
250 cmp.b #3, d2
251 beq .mouse
252
253 move.b last_pad2.w, d1
254 eor.b d0, d1
255 and.b d0, d1
256 move.b d0, last_pad2.w
257
258 bsr handle_pad_buttons
259 rte
260.mouse
261 bsr handle_mouse
262 rte
263
264
265;d0 = SACBRLUD
266;d1 = newly pressed buttons
267handle_pad_buttons:
268 tst.b num_menu.w
269 bne handle_buttons_menu
270 tst.b num_slots.w
271 bne handle_buttons_save
272 moveq #16, d2
273
274
275 btst #3, d1
276 bne right
277 btst #2, d1
278 bne left
279buttons_no_leftright
280 btst #1, d1
281 bne down
282 btst #0, d1
283 bne up
284 btst #7, d1
285 bne select_entry
286 btst #5, d1
287 bne select_entry
288handle_done:
289 rts
290handle_buttons_menu
291 moveq #48, d2
292 bra buttons_no_leftright
293handle_buttons_save
294 moveq #32, d2
295 bra buttons_no_leftright
296
297down:
298
299 ;check if we are already at the bottom of the page
300 moveq #1, d0
301 add.b (selected).w, d0
302 tst.b num_menu.w
303 bne .menu
304 tst.b num_slots.w
305 bne .slots
306 move.w d0, d1
307 add.w d1, d1
308 add.w d1, d1
309 lea page_index.w, a2
310 tst.l (0, a2, d1.w)
311 beq handle_done
312.do_move
313 move.b d0, (selected).w
314
315 add.w d2, (sprite_list).w
316 add.w d2, (sprite_list+8).w
317 rts
318.menu:
319 cmp.b num_menu.w, d0
320 beq handle_done
321 bra .do_move
322.slots:
323 cmp.b num_slots.w, d0
324 beq handle_done
325 bra .do_move
326
327up:
328 ;check if we are already at the top of the page
329 move.b (selected).w, d0
330 beq handle_done
331 subq #1, d0
332 move.b d0, (selected).w
333
334 sub.w d2, (sprite_list).w
335 sub.w d2, (sprite_list+8).w
336 rts
337
338right:
339 ;check that we have another page to go to
340 tst.b more_pages.w
341 beq handle_done
342 ;switch to the next page
343 move.l page_stack.w, a6
344 move.l (-4, a6), a6
345
346 addq #6, a7
347 bra render_page
348
349left:
350 move.l page_stack.w, a5
351 ;check if we're already on the first page
352 cmp.l #(page_pointers+8), a5
353 beq handle_done
354 ;switch to previous page
355 lea (-12, a5), a5
356 move.l (a5)+, a6
357 move.l a5, page_stack.w
358
359 addq #6, a7
360 bra render_page
361
362select_entry:
363 moveq #0, d0
364 move.b (selected).w, d0
365 add.w d0, d0
366 add.w d0, d0
367 tst.b num_menu.w
368 bne .select_menu_button
369 tst.b num_slots.w
370 bne .select_save_slot
371 lea page_index.w, a2
372 move.l (0, a2, d0.w), a2
373 tst.b (-1, a2)
374 bne enter_dir
375 ;regular file
376 move.l rom_load_addr.w, a3
377 move.l a2, (a3)
378
379 addq #6, a7
380 bra show_pause_menu
381.select_menu_button:
382 movea.l menu_functions.w, a2
383 move.l (0, a2, d0.w), a2
384 addq #6, a7
385 jmp (a2)
386.select_save_slot:
387 lea menu_port, a3
388 moveq #0, d0
389 move.b port_off.w, d0
390 add.w d0, a3
391 move.b selected.w, d0
392 move.l d0, (a3)
393 addq #6, a7
394 jmp show_pause_menu
395
396enter_dir:
397 lea menu_port+4, a3
398 move.l a2, (a3)
399.wait_complete
400 tst.w (a3)
401 bne .wait_complete
402 addq #6, a7
403 bra menu_start
404
405handle_mouse:
406 move.b last_mbuttons.w, d4
407 eor.b d3, d4
408 and.b d3, d4
409 move.b d3, last_mbuttons.w
410
411 move.b d0, d2
412 or.b d1, d2
413 beq .no_mouse_move
414
415
416 tst.b mouse_shown.w
417 bne .skip_show_check
418
419 moveq #0, d2
420 move.b num_sprites.w, d2
421 move.w d2, d4
422 lsl.w #3, d4
423 lea sprite_list.w, a2
424 move.b d2, (-5, a2, d4.w)
425 lea (0, a2, d4.w), a2
426 move.l a2, mouse_sprite.w
427 move.l #$00EA0500, (a2)+
428 move.w #$8083, (a2)
429 move.w #$100, mouse_x.w
430 addq #1, d2
431 move.b d2, num_sprites.w
432
433 move.b #1, mouse_shown.w
434
435 move.l cursor_show_fun.w, d2
436 beq .skip_show_check
437 move.l d2, a2
438 jsr (a2)
439
440
441.skip_show_check
442 neg.w d1
443 move.l mouse_sprite.w, a2
444 add.w d1, (a2)
445 add.w d0, mouse_x.w
446 move.w mouse_x.w, d0
447 asr.w #1, d0
448 move.w d0, (6, a2)
449 move.w (a2), d1
450 cmp.w selection_top.w, d1
451 blo .done
452 cmp.w selection_bot.w, d1
453 bhi .special_click
454 tst.b num_menu.w
455 bne .handle_menu
456 tst.b num_slots.w
457 bne .handle_slots
458 and.w #$FFF0, d1
459 subq #8, d1
460 move.w d1, (sprite_list).w
461 move.w d1, (sprite_list+8).w
462
463 sub.w #264, d1
464 lsr.w #4, d1
465 move.b d1, selected.w
466 bra .normal_click
467.handle_menu
468 ;TODO: FIXME
469 and.w #$FFF0, d1
470 moveq #0, d0
471 move.w d1, d0
472 sub.w selection_top.w, d0
473 divu.w #48, d0
474 swap d0
475 tst.w d0
476 beq .no_adjust
477
478 cmp.w #16, d0
479 bne .round_up
480 swap d0
481 sub.w #16, d1
482 bra .set_cursor_pos
483
484.round_up
485 swap d0
486 addq #1, d0
487 add.w #16, d1
488 bra .set_cursor_pos
489
490.no_adjust
491 swap d0
492.set_cursor_pos
493 move.w d1, (sprite_list).w
494 move.w d1, (sprite_list+8).w
495
496 move.b d0, selected.w
497
498 bra .normal_click
499.handle_slots
500 and.w #$FFE0, d1
501 subq #8, d1
502 move.w d1, (sprite_list).w
503 move.w d1, (sprite_list+8).w
504
505 sub.w #264, d1
506 lsr.w #5, d1
507 move.b d1, selected.w
508.normal_click
509 btst #0, d4
510 bne select_entry
511.done
512 rts
513.no_mouse_move
514 tst.b mouse_shown
515 bne .skip_show_check
516 rts
517.special_click:
518 btst #0, d4
519 beq .done
520 move.l special_click.w, d2
521 beq .done
522 move.l d2, a2
523 jmp (a2)
524int_4:
525empty_handler:
526 rte
527
528id_lookup:
529 dc.b $0, $1, $4, $5
530 dc.b $2, $3, $6, $7
531 dc.b $8, $9, $C, $D
532 dc.b $A, $B, $E, $F
533
534io_read:
535 ;read TH=1
536 move.b (a2), d0
537 ;read TH=0
538 move.b #0, (a2)
539 nop
540 nop
541 move.b (a2), d1
542 ;reset TH to 1
543 move.b #$40, (a2)
544
545 moveq #0, d2 ;4
546
547 ;calculate Mega Drive peripheral ID
548 move.b d1, d2 ;4
549 lsr.b #1, d2 ;8, 12
550 or.b d1, d2 ;4, 16
551 and.b #5, d2 ;8, 24
552
553 move.b d0, d3 ;4
554 add.b d3, d3 ;4, 8
555 or.b d0, d3 ;4, 12
556 and.b #$A, d3 ;8, 20
557
558 or.b d3, d2 ;4
559 move.b (id_lookup, pc, d2.w), d2 ;14
560
561
562 cmp.b #$3, d2
563 beq .mouse
564
565 cmp.b #$D, d2
566 bne .not_pad
567
568 and.b #$3F, d0
569 and.b #$30, d1
570 add.b d1, d1
571 add.b d1, d1
572 or.b d1, d0
573 not.b d0
574 rts
575.not_pad:
576 moveq #0, d0
577 rts
578
579.mouse:
580
581 move.b #$60, (a2)
582 move.b #$60, (PAD1_CTRL-PAD1_DATA, a2)
583 move.b #$60, (a2)
584
585 moveq #$f, d4
586wait_hi_init:
587 btst #4, (a2)
588 beq wait_hi_init
589 nop
590 nop
591 move.b #$20, (a2)
592 nop
593 nop
594 moveq #$f, d4
595 move.b #0, (a2)
596.wait_lo
597 btst #4, (a2)
598 bne .wait_lo
599 moveq #$f, d4
600 move.b #$20, (a2)
601.wait_hi
602 btst #4, (a2)
603 beq .wait_hi
604
605 lea mouse_buf.w, a3
606 move.l a3, a4
607 moveq #2, d3
608 moveq #0, d0
609loop:
610 moveq #$f, d4
611 move.b #0, (a2)
612.wait_lo
613 btst #4, (a2)
614 bne .wait_lo
615 move.b (a2), d0
616 lsl.b #4, d0
617 moveq #$f, d4
618 move.b #$20, (a2)
619.wait_hi
620 btst #4, (a2)
621 beq .wait_hi
622 move.b (a2), d1
623 and.b #$f, d1
624 or.b d1, d0
625 move.b d0, (a3)+
626
627 dbra d3, loop
628
629 ;end request
630 move.b #$60, (a2)
631
632
633 ;massage data
634 moveq #0, d1
635 move.b d0, d1
636 move.b (a4)+, d3
637 move.b (a4), d0
638
639 btst #4, d3
640 beq xpos
641 or.w #$FF00, d0
642xpos
643 btst #5, d3
644 beq ypos
645 or.w #$FF00, d1
646ypos
647 ;set port config back to normal controller mode
648 move.b #$40, (PAD1_CTRL-PAD1_DATA, a2)
649 rts
650
651topcorner equ (button-font)/64 + 32
652topmiddle equ topcorner+1
653botcorner equ topmiddle+1
654botmiddle equ botcorner+1
655horiz_flip equ $800
656vert_flip equ $1000
657
658; draws a button
659; d0.w - x in cells
660; d1.w - y in cells
661; d2.w - width in cells
662;
663; clobbers a6
664draw_button:
665 ;multiply x by 2
666 add.w d0, d0
667 ;multiply y by 128
668 lsl.w #7, d1
669 add.w d1, d0
670 add.w #$A000, d0
671 move.w d0, d1
672 and.w #$3FFF, d0
673 rol.w #2, d1
674 and.w #3, d1
675 ori.w #(VDP_VRAM_WRITE >> 16), d0
676 swap d0
677 move.w d1, d0
678 move.l d0, (a1)
679 move.w d2, d1
680 ;top left corner
681 move.w #topcorner, (a0)
682 subq #3, d1
683 bmi .notopmiddle
684.toploop:
685 ;top middle
686 move.w #topmiddle, (a0)
687 dbra d1, .toploop
688.notopmiddle
689 ;top right corner
690 move.w #(topcorner | horiz_flip), (a0)
691 ;go to next row in name table
692 add.l #((2*64) << 16), d0
693 move.l d0, (a1)
694 ;bottom left corner
695 move.w #botcorner, (a0)
696 subq #3, d2
697 bmi .nomiddlebot
698.botloop:
699 ;bottom middle
700 move.w #botmiddle, (a0)
701 dbra d2, .botloop
702.nomiddlebot
703 ;bottom right corner
704 move.w #(botcorner | horiz_flip), (a0)
705 rts
706
707;a5 - menu pointer
708;d6 - initial Y position of menu
709draw_menu:
710 moveq #0, d7
711 moveq #0, d5
712 ;clear out save slot state
713 move.b d5, num_slots.w
714 ;clear out event handlers
715 move.l d5, cursor_show_fun.w
716 move.l d5, special_click.w
717 ;select first item
718 move.b d7, selected.w
719 ;save menu pointer for second pass
720 movea.l a5, a4
721 ;adjust arrow mask
722 move.w #$FFE0, selection_mask.w
723.lenloop
724 tst.b (a5)
725 beq .lendone
726 addq #1, d5
727 movea.l a5, a6
728 bsr strlen
729 cmp.w d7, d0
730 blo .nochange
731 move.w d0, d7
732.nochange
733 lea (1, a5, d0.w), a5
734 bra .lenloop
735.lendone
736
737 addq #2, d7
738 move.b d5, num_menu.w
739
740 ;calculate X position
741 move.w d7, d4
742 lsr.w #1, d4
743 moveq #20, d5
744 sub.w d4, d5
745 ;calculate left arrow X
746 move.w d5, d4
747 lsl.w #3, d4
748 add.w #(128-24), d4
749 move.w d4, (sprite_list+6).w
750 ;calculate right arrow x
751 move.w d7, d3
752 lsl.w #3, d3
753 add.w d3, d4
754 add.w #32, d4
755 move.w d4, (sprite_list+6+8).w
756 ;update left arrow Y
757 move.w d6, d4
758 lsl.w #4, d4
759 add.w #256, d4
760 move.w d4, (sprite_list).w
761 move.w d4, (sprite_list+8).w
762 ;update mouse top limit
763 move.w d4, selection_top.w
764 ;restore menu pointer
765 movea.l a4, a5
766.drawloop
767 tst.b (a5)
768 beq .done
769 ;x pos
770 move.w d5, d0
771 ;y pos
772 move.w d6, d1
773 ;width
774 move.w d7, d2
775 bsr draw_button
776
777 movea.l a5, a6
778 bsr strlen
779 movea.l a5, a6
780 lea (1, a5, d0.w), a5
781 ;x pos
782 move.w d7, d1
783 lsr.w #1, d1
784 add.w d5, d1
785 lsr.w #1, d0
786 sub.w d0, d1
787 ;y pos
788 move.w d6, d2
789 ;base attribute
790 move.w #$206B, d0
791 bsr print_string_fixed
792
793 addq #3, d6
794 bra .drawloop
795.done
796 ;update mouse bottom limit
797 lsl.w #4, d6
798 add.w #224, d6
799 move.w d6, selection_bot.w
800 rts
801
802clear_screen:
803 ;clear name tables
804 vdpaccess $8000, VDP_VRAM_WRITE
805 moveq #32, d0
806 swap d0
807 move.b #32, d0
808 move.w #(64*64-1), d1
809ploop:
810 move.l d0, (a0)
811 dbra d1, ploop
812 rts
813
814initial_regs:
815 vdpreg MODE_2, $4 ;Mode 5, everything turned off
816 vdpreg MODE_1, $4
817 vdpreg SCROLL_A, $20 ;Scroll a table $8000
818 vdpreg SCROLL_B, $05 ;Scroll b table $A000
819 vdpreg SAT, $60 ;SAT table $C000
820 vdpreg BG_COLOR, 0
821 vdpreg HINT, $FF
822 vdpreg MODE_3, 0 ;full screen scroll
823 vdpreg MODE_4, $87 ;40 cell mode, double-res interlace
824 vdpreg HSCROLL, 0
825 vdpreg AUTOINC, 2
826 vdpreg SCROLL, 1 ;64x32 scroll size
827end_initial_regs
828
829start:
830 lea $FF0000, a0
831 moveq #0, d0
832 move.w #($10000/8 - 1), d1
833.clearloop:
834 move.l d0, (a0)+
835 move.l d0, (a0)+
836 dbra d1, .clearloop
837
838 lea $C00000, a0
839 lea $C00004, a1
840
841 moveq #(end_initial_regs-initial_regs-1), d0
842 lea initial_regs.w, a2
843.regloop
844 move.w (a2)+, (a1)
845 dbra d0, .regloop
846
847 vdpaccess $0, VDP_CRAM_WRITE
848 move.w #$400, (a0)
849 move.w #$EEE, (a0)
850 move.w #$222, (a0)
851
852 ;init scroll table
853 vdpaccess $0, VDP_VRAM_WRITE
854 move.w #0, (a0)
855 move.w #0, (a0)
856
857
858 ;load tiles
859 vdpaccess $800, VDP_VRAM_WRITE
860 lea font(pc), a2
861 move.w #((buttonend-font)/4 - 1), d0
862tloop:
863 move.l (a2)+, (a0)
864 dbra d0, tloop
865 move.w #((fontfixedend-fontfixed)/4 - 1), d0
866dtloop:
867 move.l (a2)+, d1
868 move.l d1, (a0)
869 move.l d1, (a0)
870 dbra d0, dtloop
871
872
873 ;setup SAT
874 ;;vdpaccess $C000, VDP_VRAM_WRITE
875
876 lea sprite_list.w, a2
877 ;left arrow
878 move.l #$01080501, (a2)+
879 move.l #$807F0086, (a2)+
880
881 ;right arrow
882 move.l #$01080500, (a2)+
883 move.l #$887F01AA, (a2)+
884 move.b #2, num_sprites.w
885
886show_main_menu:
887 bsr clear_screen
888 ;init vertical scroll RAM
889 vdpaccess $0, VDP_VSRAM_WRITE
890 move.w #-4, (a0)
891 move.w #0, (a0)
892
893 moveq #8, d6
894 move.l #main_menu_func, menu_functions.w
895 lea main_menu(pc), a5
896 bsr draw_menu
897 bra gamepad_setup
898
899show_pause_menu:
900 bsr clear_screen
901 ;init vertical scroll RAM
902 vdpaccess $0, VDP_VSRAM_WRITE
903 move.w #-4, (a0)
904 move.w #0, (a0)
905 moveq #8, d6
906 move.l #pause_menu_func, menu_functions.w
907 lea pause_menu(pc), a5
908 bsr draw_menu
909 bra gamepad_setup
910
911lock_on:
912 move.l #lock_on_port, rom_load_addr.w
913 bra menu_common
914menu_start:
915 move.l #load_rom_port, rom_load_addr.w
916menu_common:
917 moveq #0, d0
918 ;init vertical scroll RAM
919 vdpaccess $0, VDP_VSRAM_WRITE
920 move.w d0, (a0)
921 move.w d0, (a0)
922
923 ;reset arrow position
924 move.w #$0108, sprite_list.w
925 move.w #$0108, (sprite_list + 8).w
926 move.w #$0086, (sprite_list + 6).w
927 move.w #$01AA, (sprite_list + 6 + 8).w
928
929 ;reset selection
930 move.b d0, selected.w
931
932 ;reset special click handler
933 move.l d0, special_click.w
934
935
936 lea page_pointers.w, a5
937 lea dir_buffer, a6
938 move.l a6, (a5)+
939 move.l a5, page_stack.w
940 lea menu_port, a2
941 move.l a6, (a2)
942
943wait_complete:
944 tst.w (a2)
945 bne wait_complete
946
947render_page:
948 bsr clear_screen
949
950 ;clear menu state
951 move.b #0, num_menu.w
952 move.w #272, selection_top.w
953 move.w #655, selection_bot.w
954 move.w #$FFF0, selection_mask.w
955
956 ;init scroll table
957 vdpaccess $0, VDP_VRAM_WRITE
958 move.w #0, (a0)
959 move.w #4, (a0)
960
961 move.l #$40860002, d3
962 move.l d3, (a1)
963 move.l d3, base_cmd.w
964
965 move.b #0, more_pages.w
966 lea page_index.w, a3
967 moveq #MAX_DISPLAY-1, d7
968file_loop:
969 tst.b (a6)+
970 beq done_files
971 addq #1, a6 ;TODO: Do something with directory flag
972
973 ;skip over entries starting with a dot except ..
974 cmp.b #$2E, (a6)
975 bne normal
976 cmp.b #$2E, (1, a6)
977 beq normal
978 addq #1, a6
979.skip_loop:
980 tst.b (a6)+
981 bne .skip_loop
982 addq #1, d7
983 move.l a6, d6
984 bra skip
985normal:
986 ;save entry pointer to page index
987 move.l a6, (a3)+
988 ;print name on screen
989 moveq #0, d0
990 bsr print_string
991 move.l a6, d6
992
993 lea Newline(pc), a6
994 bsr print_string
995
996skip:
997 ;word align pointer
998 addq #1, d6
999 and.w #$FFFE, d6
1000 move.l d6, a6
1001
1002 dbra d7, file_loop
1003 tst.b (a6)
1004 beq done_files
1005 move.b #1, more_pages.w
1006done_files:
1007 move.l page_stack.w, a5
1008 move.l a6, (a5)+
1009 move.l a5, page_stack.w
1010
1011 ;null terminate page_index
1012 moveq #0, d0
1013 move.l d0, (a3)
1014
1015 tst.b mouse_shown
1016 beq .no_mouse
1017
1018 tst.b more_pages.w
1019 beq .no_next_page
1020
1021 ;draw Next button
1022 moveq #30, d0
1023 moveq #26, d1
1024 moveq #6, d2
1025 bsr draw_button
1026
1027 ;base attribute
1028 move.w #$206B, d0
1029 ;x pos
1030 moveq #32, d1
1031 ;y pos
1032 moveq #26, d2
1033 lea next_str(pc), a6
1034 bsr print_string_fixed
1035
1036.no_next_page
1037
1038 cmp.l #(page_pointers+8), a5
1039 beq .no_prev_page
1040
1041 ;draw Prev button
1042 moveq #3, d0
1043 moveq #26, d1
1044 moveq #6, d2
1045 bsr draw_button
1046
1047 ;base attribute
1048 move.w #$206B, d0
1049 ;x pos
1050 moveq #5, d1
1051 ;y pos
1052 moveq #26, d2
1053 lea prev_str(pc), a6
1054 bsr print_string_fixed
1055
1056.no_prev_page
1057
1058 move.l #0, cursor_show_fun.w
1059
1060 bra .done_page_buttons
1061.no_mouse
1062 move.l #show_prev_next_buttons, cursor_show_fun.w
1063.done_page_buttons
1064 move.l #handle_prev_next_click, special_click.w
1065
1066gamepad_setup:
1067 ;setup gamepads
1068 move.b #$40, PAD1_CTRL
1069 move.b #$40, PAD2_CTRL
1070
1071 move.w #$8174, (a1) ;enable display, vertical interrupts, DMA
1072
1073
1074wait_forever
1075 stop #2500
1076 bra wait_forever
1077
1078handle_prev_next_click:
1079 ;make sure we're actually low enough
1080 cmp.w #663, d1
1081 bls .no_prev_page
1082
1083
1084 tst.b more_pages.w
1085 beq .no_next_page
1086
1087 cmp.w #373, d0
1088 blo .no_next_page
1089
1090 cmp.w #419, d0
1091 bhi .no_next_page
1092
1093 ;switch to the next page
1094 move.l page_stack.w, a6
1095 move.l (-4, a6), a6
1096
1097 add.w #10, a7
1098 bra render_page
1099
1100.no_next_page
1101 cmp.l #(page_pointers+8), a5
1102 beq .no_prev_page
1103
1104 cmp.w #157, d0
1105 blo .no_prev_page
1106
1107 cmp.w #203, d0
1108 bhi .no_prev_page
1109
1110 ;switch to previous page
1111 lea (-12, a5), a5
1112 move.l (a5)+, a6
1113 move.l a5, page_stack.w
1114
1115 add.w #10, a7
1116 bra render_page
1117
1118.no_prev_page
1119 rts
1120
1121show_prev_next_buttons:
1122 movem.l d0-d2/a6, -(a7)
1123 tst.b more_pages.w
1124 beq .no_next_page
1125
1126 ;draw Next button
1127 moveq #30, d0
1128 moveq #26, d1
1129 moveq #6, d2
1130 bsr draw_button
1131
1132 ;base attribute
1133 move.w #$206B, d0
1134 ;x pos
1135 moveq #32, d1
1136 ;y pos
1137 moveq #26, d2
1138 lea next_str(pc), a6
1139 bsr print_string_fixed
1140
1141.no_next_page
1142
1143 cmp.l #(page_pointers+8), a5
1144 beq .no_prev_page
1145
1146 ;draw Prev button
1147 moveq #3, d0
1148 moveq #26, d1
1149 moveq #6, d2
1150 bsr draw_button
1151
1152 ;base attribute
1153 move.w #$206B, d0
1154 ;x pos
1155 moveq #5, d1
1156 ;y pos
1157 moveq #26, d2
1158 lea prev_str(pc), a6
1159 bsr print_string_fixed
1160
1161.no_prev_page
1162 move.l #0, cursor_show_fun.w
1163 movem.l (a7)+, d0-d2/a6
1164 rts
1165
1166show_about:
1167 bsr clear_screen
1168 moveq #1, d7
1169 lea about_text(pc), a6
1170 ;base attribute
1171 move.w #$006B, d0
1172.loop
1173 tst.b (a6)
1174 beq .done
1175 ;x pos
1176 moveq #1, d1
1177 ;y pos
1178 move.w d7, d2
1179 bsr print_string_fixed
1180 addq #1, d7
1181 bra .loop
1182.done
1183 moveq #8, d6
1184 move.l #about_menu_func, menu_functions.w
1185 lea about_menu(pc), a5
1186 bsr draw_menu
1187.wait
1188 stop #$2500
1189 bra .wait
1190
1191exit:
1192 move.l #1, menu_port+12
1193 bra exit
1194
1195resume:
1196 move.l #2, menu_port+12
1197 bra show_pause_menu
1198
1199show_save_slots:
1200 move.w #(256+26), sprite_list.w
1201 move.w #(256+26), (sprite_list+8).w
1202 move.w #(128+8), (sprite_list+6).w
1203 move.w #(128+320-24), (sprite_list+6+8).w
1204 move.w #(256+32), selection_top.w
1205 move.b #0, selected.w
1206 move.b #0, num_menu.w
1207 lea dir_buffer, a6
1208 lea menu_port+16, a3
1209 move.l a6, (a3)
1210.waitdone:
1211 tst.w (a3)
1212 bne .waitdone
1213 bsr clear_screen
1214 moveq #0, d0
1215
1216 moveq #0, d6
1217 moveq #2, d7
1218.slotloop
1219 tst.b (a6)
1220 beq .done
1221 addq #1, d6
1222 moveq #4, d1
1223 move.w d7, d2
1224 bsr print_string_fixed
1225 addq #2, d7
1226 bra .slotloop
1227.done
1228 lsl.w #4, d7
1229 add.w #248, d7
1230 move.w d7, selection_bot.w
1231 move.b d6, num_slots.w
1232 rts
1233
1234save_state:
1235 move.b #(5*4), port_off.w
1236 bsr show_save_slots
1237.wait
1238 stop #$2500
1239 bra .wait
1240
1241load_state:
1242 move.b #(6*4), port_off.w
1243 bsr show_save_slots
1244.wait
1245 stop #$2500
1246 bra .wait
1247
1248next_str:
1249 dc.b "Next", 0
1250prev_str:
1251 dc.b "Prev", 0
1252
1253about_text:
1254 dc.b "BlastEm v0.6.2", 0
1255 dc.b "Copyright 2011-2019 Michael Pavone", 0
1256 dc.b " ", 0
1257 dc.b "BlastEm is a high performance, open", 0
1258 dc.b "source (GPLv3) Genesis/Megadrive", 0
1259 dc.b "emulator.",0
1260 dc.b " ", 0
1261 dc.b " ", 0
1262 dc.b " ", 0
1263 dc.b " ", 0
1264 dc.b " --- Special Thanks ---", 0
1265 dc.b " ", 0
1266 dc.b "Nemesis: Documentatino and test ROMs", 0
1267 dc.b "Charles MacDonald: Documentation", 0
1268 dc.b "Eke-Eke: Documentation", 0
1269 dc.b "Bart Trzynadlowski: Documentation", 0
1270 dc.b "KanedaFR: Hosting the best Sega forum", 0
1271 dc.b "Titan: Awesome demos and documentation", 0
1272 dc.b "flamewing: BCD info and test ROM", 0
1273 dc.b "r57shell: Opcode size test ROM", 0
1274 dc.b "micky: Testing", 0
1275 dc.b "Sasha: Testing", 0
1276 dc.b "lol-frank: Testing", 0
1277 dc.b "Sik: Testing", 0
1278 dc.b "Tim Lawrence : Testing", 0
1279 dc.b "ComradeOj: Testing", 0
1280 dc.b "Vladikcomper: Testing", 0
1281 dc.b 0
1282
1283
1284Newline:
1285 dc.b $A, 0
1286
1287 align 1
1288
1289;Prints a null terminated string
1290;a6 - pointer to string
1291;a0 - VDP data port
1292;d0 - base tile attribute
1293;
1294;Clobbers: d1.w, d2.w, d3.l
1295print_string:
1296 lea widths(pc), a5
1297 move.w x_pos.w, d2
1298 move.l base_cmd.w, d3
1299.loop
1300 moveq #0, d1
1301 move.b (a6)+, d1
1302 beq .end
1303 cmp.b #$A, d1
1304 beq .newline
1305 tst.b (-32, a5, d1.w)
1306 beq .narrow
1307 add.w d0, d1
1308 move.w d1, (a0)
1309 addq #2, d2
1310 bra .loop
1311.narrow
1312 add.w d0, d1
1313 move.w d1, (a0)
1314 addq #1, d2
1315 move.l d2, d1
1316 ;switch to other plane
1317 and.w #$FFFE, d1
1318 swap d1
1319 eor.l #$20000000, d3
1320 add.l d3, d1
1321 move.l d1, (a1)
1322 bra .loop
1323.newline
1324 moveq #0, d2
1325 ;switch back to plane A
1326 and.l #$DFFFFFFF, d3
1327 ;skip to next row
1328 add.l #$00800000, d3
1329 move.l d3, (a1)
1330 bra .loop
1331.end
1332 move.w d2, x_pos.w
1333 move.l d3, base_cmd.w
1334 rts
1335
1336;Prints a null-terminated string with a fixed width font
1337;a6 - pointer to string
1338;a0 - VDP data port
1339;d0 - base tile attribute
1340;d1 - x col
1341;d2 - y col
1342;
1343print_string_fixed:
1344 ;multiply x by 2
1345 add.w d1, d1
1346 ;multiply y by 128
1347 lsl.w #7, d2
1348 add.w d2, d1
1349 add.w #$8000, d1
1350 move.w d1, d2
1351 and.w #$3FFF, d1
1352 rol.w #2, d2
1353 and.w #3, d2
1354 ori.w #(VDP_VRAM_WRITE >> 16), d1
1355 swap d1
1356 move.w d2, d1
1357 move.l d1, (a1)
1358.loop
1359 moveq #0, d1
1360 move.b (a6)+, d1
1361 beq .end
1362 add.w d0, d1
1363 move.w d1, (a0)
1364 bra .loop
1365.end
1366 rts
1367
1368;Returns string length in d0
1369;a6 - pointer to string
1370strlen:
1371 moveq #-1, d0
1372.loop
1373 addq #1, d0
1374 tst.b (a6)+
1375 bne .loop
1376 rts
1377
1378 align 1
1379font:
1380 incbin font_interlace_variable.tiles
1381fontend
1382arrow:
1383 incbin arrow.tiles
1384arrowend:
1385cursor:
1386 incbin cursor.tiles
1387cursorend:
1388button:
1389 incbin button.tiles
1390buttonend:
1391fontfixed:
1392 incbin font.tiles
1393fontfixedend:
1394
1395widths:
1396 dc.b 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1
1397 dc.b 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0
1398 dc.b 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1
1399 dc.b 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
1400 dc.b 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1
1401
1402main_menu:
1403 dc.b "Load ROM", 0
1404 dc.b "About", 0
1405 dc.b "Exit", 0
1406 dc.b 0
1407
1408 align 1
1409main_menu_func:
1410 dc.l menu_start
1411 dc.l show_about
1412 dc.l exit
1413
1414about_menu:
1415 dc.b "Return", 0
1416 dc.b 0
1417
1418 align 1
1419about_menu_func:
1420 dc.l show_main_menu
1421
1422pause_menu:
1423 dc.b "Resume", 0
1424 dc.b "Load ROM", 0
1425 dc.b "Lock On", 0
1426 dc.b "Save State", 0
1427 dc.b "Load State", 0
1428 dc.b "Exit", 0
1429 dc.b 0
1430
1431 align 1
1432pause_menu_func
1433 dc.l resume
1434 dc.l menu_start
1435 dc.l lock_on
1436 dc.l save_state
1437 dc.l load_state
1438 dc.l exit
1439
1440rom_end: