jmp opt and cleanups
[megadrive.git] / hexed / hexed.s
1 ##################################################
2 #                                                #
3 # Assemble with gas                              #
4 #   --register-prefix-optional --bitwise-or      #
5 #                                                #
6 ##################################################
7
8 .text
9 .globl main
10 .globl INT
11 .globl VBL
12
13 ##################################################
14 #                                                #
15 #        Register and bitmask definitions        #
16 #                                                #
17 ##################################################
18
19 .equ GFXDATA,           0xc00000
20 .equ GFXCNTL,           0xc00004
21
22 .equ VDP0_E_HBI,        0x10
23 .equ VDP0_E_DISPLAY,    0x02 
24 .equ VDP0_PLTT_FULL,    0x04 
25
26 .equ VDP1_SMS_MODE,     0x80
27 .equ VDP1_E_DISPLAY,    0x40
28 .equ VDP1_E_VBI,        0x20
29 .equ VDP1_E_DMA,        0x10
30 .equ VDP1_NTSC,         0x00
31 .equ VDP1_PAL,          0x08
32 .equ VDP1_MODE5,        0x04
33
34 .equ VDP12_STE,         0x08
35 .equ VDP12_SCREEN_V224, 0x00
36 .equ VDP12_SCREEN_V448, 0x04
37 .equ VDP12_PROGRESSIVE, 0x00
38 .equ VDP12_INTERLACED,  0x02
39 .equ VDP12_SCREEN_H256, 0x00
40 .equ VDP12_SCREEN_H320, 0x81
41
42 .equ VDP16_MAP_V32,     0x00
43 .equ VDP16_MAP_V64,     0x10
44 .equ VDP16_MAP_V128,    0x30
45 .equ VDP16_MAP_H32,     0x00
46 .equ VDP16_MAP_H64,     0x01
47 .equ VDP16_MAP_H128,    0x03
48
49 .equ MMODE_MAIN,        0
50 .equ MMODE_VAL_INPUT,   1
51 .equ MMODE_EDIT_VAL,    2
52 .equ MMODE_GOTO,        3
53 .equ MMODE_START_MENU,  4
54 .equ MMODE_GOTO_PREDEF, 5
55 .equ MMODE_JMP_ADDR,    6
56
57 .equ predef_addr_cnt,   ((predef_addrs_end-predef_addrs)/4)
58
59 ##################################################
60 #                                                #
61 #                   MACROS                       #
62 #                                                #
63 ##################################################
64
65
66 # Write val to VDP register reg
67 .macro write_vdp_r_dst reg val dst
68         move.w #((\reg << 8) + 0x8000 + \val),\dst
69 .endm
70
71 # Write val to VDP register reg, vdp addr in a3
72 .macro write_vdp_reg reg val
73         write_vdp_r_dst \reg, \val, (a3)
74 .endm
75
76 # Set up address in VDP, control port in dst
77 .macro VRAM_ADDR adr dst
78         move.l #(((0x4000 | (\adr & 0x3fff)) << 16) | (\adr >> 14)),\dst
79 .endm
80
81
82 # make VDP word from address adr and store in d0
83 .macro XRAM_ADDR_var adr
84         move.l \adr,d0
85         lsl.l #8,d0
86         lsl.l #8,d0
87         rol.l #2,d0
88         lsl.b #2,d0
89         lsr.l #2,d0
90 .endm
91
92
93 .macro VRAM_ADDR_var adr
94         XRAM_ADDR_var \adr
95         or.l #0x40000000,d0
96 .endm
97
98
99 .macro CRAM_ADDR_var adr
100         XRAM_ADDR_var \adr
101         or.l #0xc0000000,d0
102 .endm
103
104
105 # convert tile coords in d0, d1 to nametable addr to a0
106 .macro XY2NT
107         lsl.w           #6,d1
108         add.w           d1,d0
109         lsl.w           #1,d0
110         movea.l         #0xe000,a0
111         add.w           d0,a0
112 .endm
113
114 # check if some d-pad button (and modifier) is pressed
115 .macro do_dpad bit op val
116         btst.l          #\bit,d0
117         beq             0f
118         \op.l           \val,a6
119         bra             dpad_end
120 0:
121 .endm
122
123 # convert a6 to normal addr
124 #  destroys d0
125 .macro mk_a6_addr reg
126         move.l          a6,\reg
127         moveq.l         #0,d0
128         move.b          \reg,d0
129         lsr.l           #8,\reg
130         add.l           d0,\reg
131 .endm
132
133 .macro change_mode mode_new mode_back
134         and.w           #0xc0ff,d7
135         or.w            #(\mode_back<<11)|(\mode_new<<8),d7
136 .endm
137
138 .macro menu_text str x y pal
139         lea             \str,a0
140         move.l          #\x,d0
141         move.l          #\y,d1
142         move.l          #0x8000|(\pal<<13),d2
143         jsr             print
144 .endm
145
146 #################################################
147 #                                               #
148 #                    DATA                       #
149 #                                               #
150 #################################################
151
152 colors:
153         dc.w 0x0000,0x0eee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
154         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
155         dc.w 0x0000,0x02e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
156         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
157         dc.w 0x0000,0x0e44,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
158         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
159         dc.w 0x0000,0x044e,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
160         dc.w    0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
161 colors_end:
162
163
164 sprite_data:
165         /*         Y        size     link          attr        X */
166         dc.w       0;  dc.b 0x05;  dc.b 0;  dc.w 0x6002;  dc.w 0
167 sprite_data_end:
168
169 predef_addrs:
170         dc.l 0x000000, 0x200000, 0x400000, 0xa00000, 0xa10000
171         dc.l 0xa11100, 0xa12000, 0xa13000, 0xa14000, 0xc00000
172 predef_addrs_end:
173
174 safe_addrs:
175         dc.l 0x000000, 0x7fffff
176         dc.l 0xe00000, 0xffffff
177         dc.l 0xa00000, 0xa100ff
178         dc.l 0xa11000, 0xa113ff
179         dc.l 0xa12000, 0xa120ff
180         dc.l 0xa13000, 0xa130ff
181 safe_addrs_end:
182
183 txt_edit:
184         .ascii  "- edit -\0"
185 txt_a_confirm:
186         .ascii  "A-confirm\0"
187 txt_about:
188         .ascii  "hexed r1\0"
189 txt_goto:
190         .ascii  "Go to address\0"
191 txt_goto_predef:
192         .ascii  "Go to (predef)\0"
193 txt_jmp_addr:
194         .ascii  "Jump to address\0"
195 txt_dtack:
196         .ascii  "DTACK safety\0"
197 txt_dtack_err:
198         .ascii  "DTACK err?\0"
199 txt_exc:
200         .ascii  "Exception \0"
201
202 ##################################################
203 #                                                #
204 #               MAIN PROGRAM                     #
205 #                                                #
206 ##################################################
207
208 # global regs:
209 # a6 = page_start[31:8]|cursor_offs[7:0]
210 # d7 = old_inputs[31:16]|edit_bytes[15:14]|g_mode_old[13:11]|g_mode[10:8]|irq_cnt[7:0]
211 # d6 = edit_word_save[31:15]|edit_done[7]|no_dtack_detect[4]|autorep_cnt[3:0]
212 # d5 = main: tmp
213 #      edit: edit_word[31:8]|edit_pos[4:2]|byte_cnt[1:0]
214 #      menu: sel
215
216 .align 2
217
218 main:
219         /* mask irqs during init */
220         move.w          #0x2700,sr
221
222 .if 0
223         /* copy */
224         lea             (0,pc),a0
225         move.l          a0,d0
226         swap            d0
227         lsr.l           #4,d0
228         and.b           #0x0f,d0
229         cmp.b           #0,d0
230         bne             0f
231
232         move.w          #8000/2,d0
233         move.l          #0,a0
234         move.l          #0x400000,a1
235 1:
236         move.w          (a0)+,(a1)+
237         dbra            d0,1b
238 0:
239 .endif
240
241         movea.l         #0,a6
242         move.l          #0x8000,d7
243         moveq.l         #0,d6
244
245         /* Init pads */
246         move.b          #0x40,(0xa10009).l
247         move.b          #0x40,(0xa10003).l
248
249         /* Initialize VDP */
250         jsr             init_gfx
251
252         /* Load color data */
253         movea.l         #0,a0
254         movea.l         #colors,a1
255         moveq.l         #(colors_end-colors)/2,d0
256         jsr             load_colors
257
258         /* load font patterns */
259         lea             GFXDATA,a0
260         lea             font,a1
261         VRAM_ADDR       0,(GFXCNTL)
262         move.w          #128*8,d3
263 font_loop:
264         moveq.l         #8-1,d2
265         moveq.l         #0,d1
266         move.b          (a1)+,d0
267 0:
268         lsr.b           #1,d0
269         roxl.l          #1,d1
270         ror.l           #5,d1
271         dbra            d2,0b
272
273         rol.l           #1,d1           /* fixup */
274         move.l          d1,(a0)
275         dbra            d3,font_loop
276
277         /* generate A layer map */
278         movea.l         #0xe000,a1
279         move.l          #28-1,d4
280 lmaploop0:
281         movea.l         a1,a0
282         jsr             load_prepare
283
284         move.l          #64/2-1,d3
285 0:      move.l          #0x00000000,(a0)
286         dbra            d3,0b
287
288         add.l           #64*2,a1
289         dbra            d4,lmaploop0
290
291         /* generate B layer map */
292         movea.l         #0xc000,a0
293         jsr             load_prepare
294
295         move.l          #64*28/2-1,d3
296 0:      move.l          #0x00000000,(a0)
297         dbra            d3,0b
298
299         /* upload sprite data */
300         movea.l         #0xfc00,a0
301         jsr             load_prepare
302         movea.l         #sprite_data,a1
303
304         move.l          #(sprite_data_end-sprite_data)/2-1,d3
305 0:      move.l          (a1)+,(a0)
306         dbra            d3,0b
307
308         /* wait for vsync before unmask */
309         move.l          #GFXCNTL,a3
310 0:
311         move.w          (a3),d0
312         and.b           #8,d0
313         nop
314         nop
315         beq             0b
316
317         move.w          #0x2000,sr
318
319 ##################################################
320
321 forever:
322         jsr             wait_vsync
323         bra             forever
324
325
326 INT:
327         /* let's hope VRAM is already set up.. */
328         lea             txt_exc,a0
329         move.l          #9,d0
330         move.l          #27,d1
331         move.l          #0xe000,d2
332         jsr             print
333         bra             forever
334
335 ##################################################
336
337 VBL:
338         addq.b          #1,d7
339 #       movem.l         d0-d4/a0-a5,-(a7)
340
341         moveq.l         #0,d0
342         move.w          d7,d0
343         lsr.w           #6,d0
344         and.w           #0x1c,d0
345         move.l          (jumptab,pc,d0),a0
346         jmp             (a0)
347 jumptab:
348         dc.l            mode_main
349         dc.l            mode_val_input
350         dc.l            mode_edit_val   /* edit val in editor */
351         dc.l            mode_goto
352         dc.l            mode_start_menu
353         dc.l            mode_goto_predef
354         dc.l            mode_jmp_addr
355         dc.l            mode_main
356
357 ##################### main #######################
358
359 mode_main:
360         /* assume we will hang */
361         lea             txt_dtack_err,a0
362         move.l          #9,d0
363         move.l          #27,d1
364         move.l          #0xe000,d2
365         jsr             print
366
367         moveq.l         #0,d1
368         move.l          a6,d0
369         move.b          d0,d1
370         lsr.l           #8,d0
371         move.l          d0,a1           /* current addr */
372         lsr.b           #3,d1
373         neg.b           d1
374         add.b           #27-1,d1        /* line where the cursor sits */
375         swap            d1
376
377         movea.l         #0xe002,a2
378         move.l          #27-1,d5        /* line counter for dbra */
379         or.l            d1,d5
380
381 draw_row:
382         move.l          a2,a0
383         jsr             load_prepare
384
385         btst.l          #15,d7
386         beq             0f
387         move.w          #' ',(a0)
388 0:
389         /* addr */
390         move.l          a1,d2
391         moveq.l         #6,d3
392         jsr             print_hex_preped
393
394         btst.l          #4,d6
395         bne             draw_row_safe
396
397         bsr             get_safety_mask
398         cmp.b           #0xf,d0
399         beq             draw_row_safe
400
401 # unsafe or partially safe
402 draw_row_hsafe:
403         move.l          d0,d4
404         swap            d4              /* mask in upper word */
405         btst.l          #15,d7
406         bne             draw_row_hsafe_words_pre
407
408 draw_row_hsafe_bytes_pre:
409         /* 8 bytes */
410         moveq.l         #2,d3
411         move.w          #3,d4
412
413 draw_row_hsafe_bytes:
414         move.w          #' ',(a0)
415         move.b          d4,d0
416         add.b           #16,d0
417         btst.l          d0,d4
418         bne             0f
419         move.l          #'?'|('?'<<16),(a0)
420         move.w          #' ',(a0)
421         move.l          #'?'|('?'<<16),(a0)
422         bra             1f
423 0:
424         move.b          (0,a1),d2
425         jsr             print_hex_preped
426         move.w          #' ',(a0)
427         move.b          (1,a1),d2
428         jsr             print_hex_preped
429 1:
430         addq.l          #2,a1
431         dbra            d4,draw_row_hsafe_bytes
432
433         move.w          #' ',(a0)
434
435         move.l          d5,d0
436         swap            d0
437         cmp.w           d5,d0
438         beq             draw_cursor_unsafe_byte
439         bra             draw_chars_hsafe_pre
440
441 draw_row_hsafe_words_pre:
442         /* 4 shorts */
443         moveq.l         #4,d3
444         move.w          #3,d4
445
446 draw_row_hsafe_words:
447         move.w          #' ',(a0)
448         move.b          d4,d0
449         add.b           #16,d0
450         btst.l          d0,d4
451         bne             0f
452         move.l          #'?'|('?'<<16),(a0)
453         move.l          #'?'|('?'<<16),(a0)
454         bra             1f
455 0:
456         move.w          (a1),d2
457         jsr             print_hex_preped
458 1:
459         addq.l          #2,a1
460         dbra            d4,draw_row_hsafe_words
461
462         move.l          #(' '<<16)|' ',(a0)
463
464         move.l          d5,d0
465         swap            d0
466         cmp.w           d5,d0
467         beq             draw_cursor_unsafe_word
468
469 draw_chars_hsafe_pre:
470         subq.l          #8,a1
471         move.w          #3,d4
472         moveq.l         #0,d0
473
474 draw_chars_hsafe:
475         move.b          d4,d0
476         add.b           #16,d0
477         btst.l          d0,d4
478         bne             0f
479         move.l          #'?'|('?'<<16),(a0)
480         bra             draw_chars_hsafe_next
481 0:
482         btst.l          #15,d7          /* must perform correct read type */
483         bne             0f              /* doing byte reads on security reg hangs */
484         move.b          (0,a1),d0
485         lsl.l           #8,d0
486         move.b          (1,a1),d0
487         bra             1f
488 0:
489         move.w          (a1),d0
490 1:
491         ror.l           #8,d0
492         move.b          d0,d1
493         sub.b           #0x20,d1
494         cmp.b           #0x60,d1
495         blo             0f
496         move.b          #'.',d0
497 0:
498         move.w          d0,(a0)
499
500         move.b          #0,d0
501         rol.l           #8,d0
502         move.b          d0,d1
503         sub.b           #0x20,d1
504         cmp.b           #0x60,d1
505         blo             0f
506         move.b          #'.',d0
507 0:
508         move.w          d0,(a0)
509
510 draw_chars_hsafe_next:
511         addq.l          #2,a1
512         dbra            d4,draw_chars_hsafe
513
514         move.l          #(' '<<16)|' ',(a0)
515         add.w           #0x80,a2
516         dbra            d5,draw_row
517         bra             draw_status_bar
518
519
520 # normal draw
521 draw_row_safe:
522         btst.l          #15,d7
523         bne             draw_row_words
524
525 draw_row_bytes:
526         /* 8 bytes */
527         moveq.l         #2,d3
528         moveq.l         #8-1,d4
529 draw_bytes:
530         move.w          #' ',(a0)
531         move.b          (a1)+,d2
532         jsr             print_hex_preped
533         dbra            d4,draw_bytes
534
535         move.w          #' ',(a0)
536
537         move.l          d5,d0
538         swap            d0
539         cmp.w           d5,d0
540         beq             draw_cursor_byte
541         bra             draw_chars_pre
542
543 draw_row_words:
544         /* 4 shorts */
545         moveq.l         #4,d3
546         moveq.l         #4-1,d4
547 draw_words:
548         move.w          #' ',(a0)
549         move.w          (a1)+,d2
550         jsr             print_hex_preped
551         dbra            d4,draw_words
552
553         move.l          #(' '<<16)|' ',(a0)
554
555         move.l          d5,d0
556         swap            d0
557         cmp.w           d5,d0
558         beq             draw_cursor_word
559
560 draw_chars_pre:
561         /* 8 chars */
562         subq.l          #8,a1
563         moveq.l         #8-1,d4
564 draw_chars:
565         move.b          (a1)+,d0
566         move.b          d0,d1
567         sub.b           #0x20,d1
568         cmp.b           #0x60,d1
569         blo             0f
570         move.w          #'.',d0
571 0:
572         move.w          d0,(a0)
573         dbra            d4,draw_chars
574
575         move.l          #(' '<<16)|' ',(a0)
576
577         add.w           #0x80,a2
578         dbra            d5,draw_row
579
580
581 draw_status_bar:
582         /* status bar */
583         move.l          a2,a0
584         jsr             load_prepare
585
586         btst.l          #15,d7
587         beq             0f
588         move.w          #' ',(a0)
589 0:
590         mk_a6_addr      d2
591         move.l          #0x4006,d3
592         jsr             print_hex_preped
593
594         /* clear error */
595         moveq.l         #5-1,d0
596 0:
597         move.l          #' '|(' '<<16),(a0)
598         move.l          #' '|(' '<<16),(a0)
599         dbra            d0,0b
600
601
602         /* handle input */
603         jsr             get_input               /* x0cbrldu x1sa00du */
604
605         btst.l          #16+4,d0                /* A - scroll modifier */
606         beq             input_noa
607
608         do_dpad         16+0,  sub, #0x0800
609         do_dpad         16+1,  add, #0x0800
610         do_dpad         16+10, sub, #0xd800
611         do_dpad         16+11, add, #0xd800
612 input_noa:
613         moveq.l         #0,d1
614         move.w          d7,d1
615         lsr.w           #7,d1
616         lsr.w           #7,d1
617
618         do_dpad         0,  subq, #0x0008
619         do_dpad         1,  addq, #0x0008
620         do_dpad         10, sub, d1
621         do_dpad         11, add, d1
622
623 dpad_end:
624         /* update addr */
625         move.l          a6,d1
626         cmp.b           #0xf0,d1
627         blo             0f
628         sub.l           #0xd800,a6
629         add.w           #0x00d8,a6
630         bra             1f
631 0:
632         cmp.b           #0xd8,d1
633         blo             1f
634         add.l           #0xd800,a6
635         sub.w           #0x00d8,a6
636 1:
637
638         /* other btns */
639         moveq.l         #0,d1
640         btst.l          #12,d0                  /* B - switch byte/word mode */
641         beq             input_nob
642         bclr.l          #15,d7
643         add.w           #0x4000,d7              /* changes between 01 10 */
644         move.l          a6,d1
645         and.l           #1,d1
646         sub.l           d1,a6                   /* make even, just in case */
647
648 input_nob:
649         btst.l          #13,d0                  /* C - edit selected byte */
650         beq             input_noc
651
652         change_mode     MMODE_EDIT_VAL, MMODE_MAIN
653         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
654
655 input_noc:
656         btst.l          #5,d0                   /* Start - menu */
657         beq             input_nos
658
659         moveq.l         #0,d5
660         change_mode     MMODE_START_MENU, MMODE_MAIN
661         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_STE),(GFXCNTL)
662
663 input_nos:
664 vbl_end:
665 #       movem.l         (a7)+,d0-d4/a0-a5
666         rte
667
668
669 draw_cursor_unsafe_byte:
670         move.l          a6,d0
671         and.l           #7,d0           /* byte offs */
672         move.b          d0,d1
673         add.b           d0,d0
674         add.b           d1,d0           /* d0 *= 3 (chars) */
675         add.b           d0,d0
676         lea             (7*2,a2,d0),a0
677         jsr             load_prepare
678         move.l          #(0x2000|'?'|((0x2000|'?')<<16)),(a0)
679
680         move.l          a2,a0
681         add.w           #31*2,a0
682         jsr             load_prepare    /* restore a0 */
683         jmp             draw_chars_hsafe_pre
684
685 draw_cursor_unsafe_word:
686         move.l          a6,d0
687         and.l           #7,d0           /* byte offs */
688         move.l          d0,d1
689         lsr.b           #1,d1           /* which word */
690         move.b          d1,d2
691         lsl.b           #2,d2
692         add.b           d2,d1           /* num of chars to skip */
693         add.b           d1,d1
694
695         lea             (8*2,a2,d1),a0
696         jsr             load_prepare
697         move.l          #(0x2000|'?'|((0x2000|'?')<<16)),d0
698         move.l          d0,(a0)
699         move.l          d0,(a0)
700
701         move.l          a2,a0
702         add.w           #29*2,a0
703         jsr             load_prepare    /* restore a0 */
704         jmp             draw_chars_hsafe_pre
705
706
707 draw_cursor_byte:
708         move.l          a6,d0
709         and.l           #7,d0           /* byte offs */
710         move.w          #0x2002,d3
711
712         move.b          (-8,a1,d0),d2
713         move.b          d0,d1
714         add.b           d0,d0
715         add.b           d1,d0           /* d0 *= 3 (chars) */
716         add.b           d0,d0
717         lea             (7*2,a2,d0),a0
718         jsr             load_prepare
719         jsr             print_hex_preped
720
721         move.l          a2,a0
722         add.w           #31*2,a0
723         jsr             load_prepare    /* restore a0 */
724
725         jmp             draw_chars_pre
726
727 draw_cursor_word:
728         move.l          a6,d0
729         and.l           #7,d0           /* byte offs */
730         move.l          d0,d1
731         lsr.b           #1,d1           /* which word */
732         move.b          d1,d2
733         lsl.b           #2,d2
734         add.b           d2,d1           /* num of chars to skip */
735         add.b           d1,d1
736         move.w          #0x2004,d3
737
738         move.w          (-8,a1,d0),d2
739         lea             (8*2,a2,d1),a0
740         jsr             load_prepare
741         jsr             print_hex_preped
742
743         move.l          a2,a0
744         add.w           #29*2,a0
745         jsr             load_prepare    /* restore a0 */
746
747         jmp             draw_chars_pre
748
749
750 #################### hedit #######################
751
752 mode_edit_val:
753         btst.l          #7,d6
754         bne             mode_hedit_finish
755
756         /* read val to edit */
757         moveq.l         #0,d5
758         mk_a6_addr      d1
759         move.l          d1,a0
760         btst.l          #15,d7
761         bne             0f
762         move.b          (a0),d5
763         lsl.l           #8,d5
764         or.b            #1,d5
765         bra             1f
766 0:
767         move.w          (a0),d5
768         lsl.l           #8,d5
769         or.b            #2,d5
770 1:
771
772         change_mode     MMODE_VAL_INPUT, MMODE_EDIT_VAL
773         jmp             vbl_end
774
775 mode_hedit_finish:
776         /* write the val */
777         mk_a6_addr      d1
778         move.l          d1,a0
779         lsr.l           #8,d5
780
781         btst.l          #15,d7
782         bne             0f
783         move.b          d5,(a0)
784         bra             1f
785 0:
786         move.w          d5,(a0)
787 1:
788
789         bra             return_to_main
790
791 ##################### goto #######################
792
793 mode_goto:
794         btst.l          #7,d6
795         bne             mode_goto_finish
796
797         moveq.l         #0,d5
798         swap            d6
799         move.w          d6,d5
800         swap            d6
801         swap            d5
802         or.b            #3,d5           /* 3 bytes */
803         bclr.l          #7,d6
804         change_mode     MMODE_VAL_INPUT, MMODE_GOTO
805         jmp             vbl_end
806
807 mode_goto_finish:
808         lsr.l           #8,d5
809         move.l          d5,d0
810         move.l          d0,d1
811         and.l           #7,d1
812         and.b           #0xf8,d0
813         lsl.l           #8,d0
814         or.l            d1,d0
815         move.l          d0,a6
816
817         lsr.l           #8,d5
818         swap            d6
819         move.w          d5,d6
820         swap            d6
821
822         bra             return_to_main
823
824 ################### val edit #####################
825
826 mode_val_input:
827         /* frame */
828         movea.l         #0xe000+14*2+11*64*2,a1
829         moveq.l         #6-1,d1
830 0:
831         move.w          a1,a0
832         jsr             load_prepare
833         moveq.l         #11-1,d0
834 1:
835         move.w          #0,(a0)
836         dbra            d0,1b
837
838         add.w           #64*2,a1
839         dbra            d1,0b
840
841         /* text */
842         lea             txt_edit,a0
843         move.l          #15,d0
844         move.l          #11,d1
845         move.l          #0xc000,d2
846         jsr             print
847
848         lea             txt_a_confirm,a0
849         move.l          #15,d0
850         move.l          #15,d1
851         move.l          #0xc000,d2
852         jsr             print
853
854         /* edit field */
855         moveq.l         #0,d0
856         moveq.l         #0,d1
857         moveq.l         #0,d3
858         move.b          d5,d3
859         and.b           #3,d3           /* edit field bytes */
860
861         move.b          #19,d0
862         sub.b           d3,d0
863         move.b          #13,d1
864         move.l          d5,d2
865         lsr.l           #8,d2
866         add.b           d3,d3
867         or.w            #0x8000,d3
868         jsr             print_hex
869
870         /* current char */
871         moveq.l         #0,d0
872         moveq.l         #0,d1
873
874         and.w           #6,d3
875         move.b          #19,d0
876         move.b          d3,d1
877         lsr.b           #1,d1           /* length in bytes */
878         sub.b           d1,d0
879         move.b          d5,d1
880         lsr.b           #2,d1
881         and.b           #7,d1           /* nibble to edit */
882         add.b           d1,d0
883
884         sub.b           d1,d3
885         sub.b           #1,d3           /* chars to shift out */
886         lsl.b           #2,d3
887         add.b           #8,d3
888         move.l          d5,d2
889         lsr.l           d3,d2
890
891         move.b          #13,d1
892         move.w          #0xa001,d3
893         jsr             print_hex
894
895         /* handle input */
896         jsr             get_input       /* x0cbrldu x1sa00du */
897
898         move.w          d0,d1
899         and.w           #0x0f00,d1
900         beq             ai_no_dpad
901         move.b          d5,d1
902         and.b           #3,d1
903         add.b           d1,d1           /* nibble count */
904         sub.b           #1,d1           /* max n.t.e. val */
905         move.b          d5,d2
906         lsr.b           #2,d2
907         and.b           #7,d2           /* nibble to edit */
908
909         move.b          d0,d3
910         and.b           #3,d3
911         beq             ai_no_ud
912         moveq.l         #0,d3
913         moveq.l         #0,d4
914         move.b          #0xf,d3
915         move.b          #0x1,d4
916         sub.b           d2,d1
917         lsl.b           #2,d1
918         add.b           #8,d1
919         lsl.l           d1,d3           /* mask */
920         lsl.l           d1,d4           /* what to add/sub */
921         move.l          d5,d1
922         and.l           d3,d1
923         btst.l          #8,d0
924         beq             0f
925         add.l           d4,d1
926         bra             1f
927 0:
928         sub.l           d4,d1
929 1:
930         and.l           d3,d1
931         eor.l           #0xffffffff,d3
932         and.l           d3,d5
933         or.l            d1,d5
934         jmp             vbl_end
935
936 ai_no_ud:
937         btst.l          #10,d0
938         bne             0f
939         add.b           #1,d2
940         bra             1f
941 0:
942         sub.b           #1,d2
943 1:
944         cmp.b           #0,d2
945         bge             0f
946         move.b          d1,d2
947 0:
948         cmp.b           d1,d2
949         ble             0f
950         move.b          #0,d2
951 0:
952         and.b           #0xe3,d5
953         lsl.b           #2,d2
954         or.b            d2,d5
955         jmp             vbl_end
956
957 ai_no_dpad:
958         move.w          d0,d1
959         and.w           #0x1020,d1
960         beq             ai_no_sb
961
962         bra             return_to_main
963
964 ai_no_sb:
965         btst.l          #4,d0           /* A - confirm */
966         beq             ai_no_input
967         bset.l          #7,d6
968         move.w          d7,d1           /* back to prev mode */
969         and.w           #0x3800,d1
970         lsr.w           #3,d1
971         and.w           #0xc0ff,d7
972         or.w            d1,d7
973
974 ai_no_input:
975         jmp             vbl_end
976
977
978 ################### start menu ###################
979
980 mode_start_menu:
981         /* frame */
982         bsr             start_menu_box
983
984         /* text */
985         menu_text       txt_about,       13,  9, 1
986         menu_text       txt_goto,        13, 11, 0
987         menu_text       txt_goto_predef, 13, 12, 0
988         menu_text       txt_jmp_addr,    13, 13, 0
989         menu_text       txt_dtack,       13, 14, 0
990         menu_text       txt_a_confirm,   13, 16, 2
991
992         /* dtack safety on/off */
993         movea.l         #0xe000+26*2+14*64*2,a0
994         jsr             load_prepare
995         move.w          #0x8000|'O',(a0)
996         btst.l          #4,d6
997         bne             0f
998         move.w          #0x8000|'N',(a0)
999         bra             1f
1000 0:
1001         move.w          #0x8000|'F',(a0)
1002         move.w          #0x8000|'F',(a0)
1003 1:
1004
1005         /* cursor */
1006         movea.l         #0xe000+11*2+11*64*2,a0
1007         moveq.l         #0,d0
1008         move.b          d5,d0
1009         and.b           #3,d0
1010         lsl.w           #7,d0
1011         add.w           d0,a0
1012         jsr             load_prepare
1013         move.w          #'>',(a0)
1014
1015         /* input */
1016         jsr             get_input       /* x0cbrldu x1sa00du */
1017
1018         move.w          d0,d1
1019         and.w           #3,d1
1020         beq             msm_no_ud
1021         move.b          d5,d1
1022         and.b           #3,d1
1023         btst.l          #0,d0
1024         sne             d2
1025         or.b            #1,d2           /* up -1, down 1 */
1026         add.b           d2,d1
1027         cmp.b           #0,d1
1028         bge             0f
1029         move.b          #3,d1
1030 0:
1031         cmp.b           #3,d1
1032         ble             0f
1033         move.b          #0,d1
1034 0:
1035         and.b           #0xfc,d5
1036         or.b            d1,d5
1037         jmp             vbl_end
1038
1039 msm_no_ud:
1040         btst.l          #4,d0           /* A - confirm */
1041         beq             msm_no_a
1042         move.b          d5,d1
1043         and.b           #3,d1
1044         bne             0f
1045         change_mode     MMODE_GOTO, MMODE_MAIN
1046         bsr             start_menu_box
1047         jmp             vbl_end
1048 0:
1049         cmp.b           #1,d1
1050         bne             0f
1051         moveq.l         #0,d5
1052         change_mode     MMODE_GOTO_PREDEF, MMODE_MAIN
1053         bsr             start_menu_box
1054         jmp             vbl_end
1055 0:
1056         cmp.b           #2,d1
1057         bne             0f
1058         change_mode     MMODE_JMP_ADDR, MMODE_MAIN
1059         bsr             start_menu_box
1060         jmp             vbl_end
1061 0:
1062         cmp.b           #3,d1
1063         bne             0f
1064         bchg.l          #4,d6
1065         jmp             vbl_end
1066 0:
1067
1068 msm_no_a:
1069         move.w          d0,d1
1070         and.w           #0x3000,d1
1071         beq             msm_no_bc
1072         bra             return_to_main
1073
1074 msm_no_bc:
1075         jmp             vbl_end
1076
1077 start_menu_box:
1078         movea.l         #0xe000+10*2+8*64*2,a1
1079         move.w          #10-1,d1
1080 0:
1081         move.w          a1,a0
1082         jsr             load_prepare
1083         move.w          #20-1,d0
1084 1:
1085         move.w          #0,(a0)
1086         dbra            d0,1b
1087
1088         add.w           #64*2,a1
1089         dbra            d1,0b
1090         rts
1091
1092 ################### goto predef ##################
1093
1094 mode_goto_predef:
1095         /* frame */
1096         movea.l         #0xe000+14*2+8*64*2,a1
1097         move.l          #predef_addr_cnt+2-1,d1
1098 0:
1099         move.w          a1,a0
1100         jsr             load_prepare
1101         moveq.l         #10-1,d0
1102 1:
1103         move.w          #0,(a0)
1104         dbra            d0,1b
1105
1106         add.w           #64*2,a1
1107         dbra            d1,0b
1108
1109         /* draw addresses */
1110         movea.l         #0xe000+17*2+9*64*2,a1
1111         lea             predef_addrs,a2
1112         move.w          #predef_addr_cnt-1,d4
1113         move.l          #0x8006,d3
1114 mgp_da_loop:
1115         move.w          a1,a0
1116         jsr             load_prepare
1117         move.l          (a2)+,d2
1118         jsr             print_hex_preped
1119         add.w           #64*2,a1
1120         dbra            d4,mgp_da_loop
1121
1122         /* cursor */
1123         movea.l         #0xe000+15*2+9*64*2,a0
1124         moveq.l         #0,d0
1125         move.b          d5,d0
1126         lsl.w           #7,d0
1127         add.w           d0,a0
1128         jsr             load_prepare
1129         move.w          #'>',(a0)
1130
1131         /* input */
1132         jsr             get_input       /* x0cbrldu x1sa00du */
1133
1134         move.w          d0,d1
1135         and.w           #3,d1
1136         beq             mgp_no_ud
1137         btst.l          #0,d0
1138         sne             d2
1139         or.b            #1,d2           /* up -1, down 1 */
1140         add.b           d2,d5
1141         cmp.b           #0,d5
1142         bge             0f
1143         move.b          #predef_addr_cnt-1,d5
1144 0:
1145         cmp.b           #predef_addr_cnt-1,d5
1146         ble             0f
1147         move.b          #0,d5
1148 0:
1149         jmp             vbl_end
1150
1151 mgp_no_ud:
1152         btst.l          #4,d0           /* A - confirm */
1153         beq             mgp_no_a
1154         moveq.l         #0,d0
1155         move.b          d5,d0
1156         lsl.w           #2,d0
1157         lea             predef_addrs,a0
1158         move.l          (a0,d0),d5
1159         lsl.l           #8,d5
1160         jmp             mode_goto_finish
1161
1162 mgp_no_a:
1163         move.w          d0,d1
1164         and.w           #0x3000,d1
1165         beq             mgp_no_bc
1166         bra             return_to_main
1167
1168 mgp_no_bc:
1169         jmp             vbl_end
1170
1171 ##################### jmp ########################
1172
1173 mode_jmp_addr:
1174         btst.l          #7,d6
1175         bne             mode_jmp_finish
1176
1177         moveq.l         #0,d5
1178         or.b            #3,d5           /* 3 bytes */
1179         bclr.l          #7,d6
1180         change_mode     MMODE_VAL_INPUT, MMODE_JMP_ADDR
1181         jmp             vbl_end
1182
1183 mode_jmp_finish:
1184         lsr.l           #8,d5
1185         write_vdp_r_dst 1,(VDP1_E_DISPLAY | VDP1_MODE5),(GFXCNTL)       /* disable vint */
1186         move.l          d5,a0
1187         jmp             (a0)
1188
1189
1190 # go back to main mode
1191 return_to_main:
1192         bclr.l          #7,d6           /* not edited */
1193         change_mode     MMODE_MAIN, MMODE_MAIN
1194         write_vdp_r_dst 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320),(GFXCNTL)
1195         jmp             vbl_end
1196
1197
1198 #################################################
1199 #                                               #
1200 #         Initialize VDP registers              #
1201 #                                               #
1202 #################################################
1203
1204 init_gfx:
1205         move.l          #GFXCNTL,a3
1206         write_vdp_reg   0,(VDP0_E_DISPLAY | VDP0_PLTT_FULL)
1207         write_vdp_reg   1,(VDP1_E_VBI | VDP1_E_DISPLAY | VDP1_MODE5)
1208         write_vdp_reg   2,(0xe000 >> 10)        /* Screen map a adress */
1209         write_vdp_reg   3,(0xe000 >> 10)        /* Window address */
1210         write_vdp_reg   4,(0xc000 >> 13)        /* Screen map b address */
1211         write_vdp_reg   5,(0xfc00 >>  9)        /* Sprite address */
1212         write_vdp_reg   6,0     
1213         write_vdp_reg   7,0                     /* Backdrop color */
1214         write_vdp_reg   10,1                    /* Lines per hblank interrupt */
1215         write_vdp_reg   11,0                    /* 2-cell vertical scrolling */
1216         write_vdp_reg   12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320)
1217         write_vdp_reg   13,(0x8000 >> 10)       /* Horizontal scroll address */
1218         write_vdp_reg   15,2
1219         write_vdp_reg   16,(VDP16_MAP_V32 | VDP16_MAP_H64)      /* layer size */
1220         write_vdp_reg   17,0
1221         write_vdp_reg   18,0xff
1222         rts
1223
1224
1225 # get mask of bits representing safe words
1226 #  a1 - address to check
1227 #  destroys d0-d2, strips upper bits from a1
1228 get_safety_mask:
1229         move.l          a1,d1
1230         lsl.l           #8,d1
1231         lsr.l           #8,d1
1232         lea             safe_addrs,a1
1233         move.w          #(safe_addrs_end - safe_addrs)/8-1,d2
1234 0:
1235         move.l          (a1)+,d0
1236         cmp.l           d0,d1
1237         blt             1f
1238         move.l          (a1),d0
1239         cmp.l           d0,d1
1240         ble             addr_safe
1241 1:
1242         addq.l          #4,a1
1243         dbra            d2,0b
1244
1245         move.l          d1,a1
1246
1247         moveq.l         #0x0c,d0
1248         cmp.l           #0xa14000,d1
1249         beq             gsm_rts
1250
1251         moveq.l         #0x08,d0
1252         cmp.l           #0xa14100,d1
1253         beq             gsm_rts
1254
1255         /* check for VDP address */
1256         move.l          d1,d0
1257         swap            d0
1258         and.b           #0xe0,d0
1259         cmp.b           #0xc0,d0
1260         bne             addr_unsafe     /* not vdp */
1261
1262         move.l          d1,d0
1263         and.l           #0x0700e0,d0
1264         bne             addr_unsafe
1265
1266         move.l          d1,d0
1267         and.b           #0x1f,d0
1268         cmp.b           #0x04,d0
1269         blt             addr_hsafe_3    /* data port */
1270         cmp.b           #0x10,d0
1271         blt             addr_safe       /* below PSG */
1272         cmp.b           #0x18,d0
1273         bge             addr_safe       /* above PSG */
1274
1275 addr_unsafe:
1276         moveq.l         #0,d0           /* skip line */
1277         rts
1278
1279 addr_hsafe_3:
1280         moveq.l         #3,d0           /* skip 2 words */
1281         rts
1282
1283 addr_safe:
1284         move.l          d1,a1
1285         moveq.l         #0xf,d0
1286 gsm_rts:
1287         rts
1288
1289
1290 # read single phase from controller
1291 #  #a0 - addr
1292 #  d0 - result
1293 #  destroys d1,d2
1294 get_input:
1295         move.b          #0x40,(0xa10003)
1296         nop
1297         nop
1298         nop
1299         move.b          (0xa10003),d0
1300         move.b          #0x00,(0xa10003)
1301         lsl.w           #8,d0
1302         nop
1303         move.b          (0xa10003),d0
1304         eor.w           #0xffff,d0
1305
1306         swap            d7
1307         move.w          d7,d1
1308         eor.w           d0,d1           /* changed btns */
1309         move.w          d0,d7           /* old val */
1310         swap            d7
1311         and.w           d0,d1           /* what changed now */
1312         bne             0f
1313
1314         addq.b          #1,d6
1315         move.b          d6,d2
1316         and.b           #0x0f,d2        /* do autorepeat */
1317         cmp.b           #9,d2
1318         bne             1f
1319         move.w          d0,d1
1320 0:
1321         and.b           #0xf0,d6
1322 1:
1323         swap            d0
1324         move.w          d1,d0
1325         rts
1326
1327 # Prepare to write to VDP RAM @a0
1328 # sets a0 to VDP data port for convenience
1329 #  a0: VRAM base
1330 #  destroys d0
1331
1332 load_prepare:
1333         VRAM_ADDR_var   a0
1334         move.l          d0,(GFXCNTL).l
1335         move.l          #GFXDATA,a0
1336         rts
1337
1338
1339 # Load color data from ROM
1340 #  a0: CRAM base
1341 #  a1: color list address
1342 #  d0: number of colors to load
1343 #  destroys d1
1344
1345 load_colors:
1346         move.l          d0,d1
1347         CRAM_ADDR_var   a0
1348         move.l          d0,(GFXCNTL).l
1349
1350         move.l          #GFXDATA,a0
1351         subq.w          #1,d1
1352 0:
1353         move.w          (a1)+,(a0)
1354         dbra            d1,0b
1355
1356         rts
1357
1358
1359 # print
1360 #  a0 - string
1361 #  d0 - x
1362 #  d1 - y 
1363 #  d2 - tile_bits[15:11]
1364 #  destroys a1
1365
1366 print:
1367         move.l          a0,a1
1368         XY2NT
1369         jsr             load_prepare
1370         move.l          d2,d0
1371         and.w           #0xf800,d0
1372
1373 _print_loop:
1374         move.b          (a1)+,d0
1375         beq             _print_end
1376
1377         move.w          d0,(a0)
1378         jmp             _print_loop
1379
1380 _print_end:
1381         rts
1382
1383
1384 # print_hex
1385 #  d0 - x
1386 #  d1 - y 
1387 #  d2 - value
1388 #  d3 - tile_bits[15:11]|digit_cnt[7:0]
1389 #  destroys a0, preserves d3
1390
1391 print_hex:
1392         XY2NT
1393         jsr             load_prepare
1394
1395 print_hex_preped:
1396         moveq.l         #0,d0
1397         move.b          d3,d0
1398         move.l          d0,d1
1399         lsl.b           #2,d0
1400         ror.l           d0,d2           /* prep value */
1401         subq.l          #1,d1           /* count */
1402         move.w          d3,d0
1403         and.w           #0xf800,d0      /* keep upper bits in d0 */
1404
1405 _print_hex_loop:
1406         rol.l           #4,d2
1407         move.b          d2,d0
1408         and.b           #0xf,d0
1409
1410         add.b           #'0',d0
1411         cmp.b           #'9',d0
1412         ble             0f
1413         addq.b          #7,d0
1414 0:
1415         move.w          d0,(a0)
1416         dbra            d1,_print_hex_loop
1417
1418         rts
1419
1420
1421 # wait vertical sync
1422
1423 wait_vsync:
1424         move.b          d7,d0
1425 _wait_change:
1426         stop            #0x2000
1427         cmp.b           d7,d0
1428         beq             _wait_change
1429         rts
1430
1431
1432 #################################################
1433 #                                               #
1434 #                 RAM DATA                      #
1435 #                                               #
1436 #################################################
1437
1438 .bss
1439
1440 # nothing :)
1441
1442 .end
1443
1444 # vim:filetype=asmM68k