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