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