--- /dev/null
+*-------------------------------------------------------\r
+*\r
+* Sega startup code for the GNU Assembler\r
+* Translated from:\r
+* Sega startup code for the Sozobon C compiler\r
+* Written by Paul W. Lee\r
+* Modified from Charles Coty's code\r
+*\r
+*-------------------------------------------------------\r
+\r
+ dc.l 0x0,0x200\r
+ dc.l INT,INT,INT,INT,INT,INT,INT\r
+ dc.l INT,INT,INT,INT,INT,INT,INT,INT\r
+ dc.l INT,INT,INT,INT,INT,INT,INT,INT\r
+ dc.l INT,INT,INT,HBL,INT,VBL,INT,INT\r
+ dc.l INT,INT,INT,INT,INT,INT,INT,INT\r
+ dc.l INT,INT,INT,INT,INT,INT,INT,INT\r
+ dc.l INT,INT,INT,INT,INT,INT,INT,INT\r
+ dc.l INT,INT,INT,INT,INT,INT,INT\r
+ .ascii "SEGA GENESIS "\r
+ .ascii "notaz's Shadow / Hilight test "\r
+ .ascii "NOTAZ'S SHADOW HILIGHT TEST "\r
+ .ascii "GM 00000000-00"\r
+ .byte 0xa5,0xfb\r
+ .ascii "JD "\r
+ .byte 0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00\r
+ .byte 0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff\r
+ .ascii " "\r
+ .ascii " "\r
+ .ascii " "\r
+ .ascii "JUE "\r
+*debugee:\r
+* bra debugee\r
+ tst.l 0xa10008\r
+ bne SkipJoyDetect \r
+ tst.w 0xa1000c\r
+SkipJoyDetect:\r
+ bne SkipSetup\r
+ lea Table,%a5 \r
+ movem.w (%a5)+,%d5-%d7\r
+ movem.l (%a5)+,%a0-%a4 \r
+* Check Version Number \r
+ move.b -0x10ff(%a1),%d0\r
+ andi.b #0x0f,%d0 \r
+ beq WrongVersion \r
+* Sega Security Code (SEGA) \r
+ move.l #0x53454741,0x2f00(%a1)\r
+WrongVersion:\r
+ move.w (%a4),%d0\r
+ moveq #0x00,%d0 \r
+ movea.l %d0,%a6 \r
+ move %a6,%usp\r
+* Set VDP registers\r
+ moveq #0x17,%d1\r
+FillLoop: \r
+ move.b (%a5)+,%d5\r
+ move.w %d5,(%a4) \r
+ add.w %d7,%d5 \r
+ dbra %d1,FillLoop \r
+ move.l (%a5)+,(%a4) \r
+ move.w %d0,(%a3) \r
+ move.w %d7,(%a1) \r
+ move.w %d7,(%a2) \r
+L0250:\r
+ btst %d0,(%a1)\r
+ bne L0250 \r
+* Put initial values into a00000 \r
+ moveq #0x25,%d2\r
+Filla: \r
+ move.b (%a5)+,(%a0)+\r
+ dbra %d2,Filla\r
+ move.w %d0,(%a2) \r
+ move.w %d0,(%a1) \r
+ move.w %d7,(%a2) \r
+L0262:\r
+ move.l %d0,-(%a6)\r
+ dbra %d6,L0262 \r
+ move.l (%a5)+,(%a4) \r
+ move.l (%a5)+,(%a4) \r
+* Put initial values into c00000 \r
+ moveq #0x1f,%d3\r
+Filc0: \r
+ move.l %d0,(%a3)\r
+ dbra %d3,Filc0\r
+ move.l (%a5)+,(%a4) \r
+* Put initial values into c00000 \r
+ moveq #0x13,%d4\r
+Fillc1: \r
+ move.l %d0,(%a3)\r
+ dbra %d4,Fillc1\r
+* Put initial values into c00011 \r
+ moveq #0x03,%d5\r
+Fillc2: \r
+ move.b (%a5)+,0x0011(%a3) \r
+ dbra %d5,Fillc2 \r
+ move.w %d0,(%a2) \r
+ movem.l (%a6),%d0-%d7/%a0-%a6 \r
+ move #0x2700,%sr \r
+SkipSetup:\r
+ bra Continue\r
+Table:\r
+ dc.w 0x8000, 0x3fff, 0x0100, 0x00a0, 0x0000, 0x00a1, 0x1100, 0x00a1\r
+ dc.w 0x1200, 0x00c0, 0x0000, 0x00c0, 0x0004, 0x0414, 0x302c, 0x0754\r
+ dc.w 0x0000, 0x0000, 0x0000, 0x812b, 0x0001, 0x0100, 0x00ff, 0xff00 \r
+ dc.w 0x0080, 0x4000, 0x0080, 0xaf01, 0xd91f, 0x1127, 0x0021, 0x2600\r
+ dc.w 0xf977, 0xedb0, 0xdde1, 0xfde1, 0xed47, 0xed4f, 0xd1e1, 0xf108 \r
+ dc.w 0xd9c1, 0xd1e1, 0xf1f9, 0xf3ed, 0x5636, 0xe9e9, 0x8104, 0x8f01 \r
+ dc.w 0xc000, 0x0000, 0x4000, 0x0010, 0x9fbf, 0xdfff \r
+\r
+Continue:\r
+ tst.w 0x00C00004\r
+\r
+* set stack pointer\r
+* clr.l %a7\r
+ move.w #0,%a7\r
+\r
+* user mode\r
+ move.w #0x2300,%sr\r
+\r
+* clear Genesis RAM\r
+ lea 0xff0000,%a0\r
+ moveq #0,%d0\r
+clrram: move.w #0,(%a0)+\r
+ subq.w #2,%d0\r
+ bne clrram\r
+\r
+*---------------------------------------------------------- \r
+*\r
+* Load driver into the Z80 memory\r
+*\r
+*---------------------------------------------------------- \r
+\r
+* halt the Z80\r
+ move.w #0x100,0xa11100\r
+* reset it\r
+ move.w #0x100,0xa11200\r
+\r
+ lea Z80Driver,%a0\r
+ lea 0xa00000,%a1\r
+ move.l #Z80DriverEnd,%d0\r
+ move.l #Z80Driver,%d1\r
+ sub.l %d1,%d0\r
+Z80loop:\r
+ move.b (%a0)+,(%a1)+\r
+ subq.w #1,%d0\r
+ bne Z80loop\r
+\r
+* enable the Z80\r
+ move.w #0x0,0xa11100\r
+\r
+*---------------------------------------------------------- \r
+ jmp main\r
+\r
+INT: \r
+ rte\r
+\r
+HBL:\r
+ /* addq.l #1,htimer */\r
+ rte\r
+\r
+VBL:\r
+ /* addq.l #1,vtimer */\r
+ move.l #vtimer,a0\r
+ addq.l #1,(a0)\r
+ rte\r
+\r
+*------------------------------------------------\r
+*\r
+* Get a random number. This routine\r
+* was found in TOS.\r
+*\r
+* Output\r
+* ------\r
+* d0 = random number\r
+*\r
+*------------------------------------------------\r
+\r
+ .globl random\r
+\r
+random:\r
+ move.l rand_num,%d0\r
+ tst.l %d0\r
+ bne .L1\r
+ moveq #16,%d1\r
+ lsl.l %d1,%d0\r
+ or.l htimer,%d0\r
+ move.l %d0,rand_num\r
+.L1:\r
+ move.l #-1153374675,-(%sp)\r
+ move.l rand_num,-(%sp)\r
+ bsr lmul\r
+ addq.w #8,%sp\r
+ addq.l #1,%d0\r
+ move.l %d0,rand_num\r
+\r
+ lsr.l #8,%d0\r
+ and.l #16777215,%d0\r
+ rts\r
+\r
+\r
+*------------------------------------------------\r
+*\r
+* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg\r
+*\r
+* Permission is granted to anyone to use this software for any purpose\r
+* on any computer system, and to redistribute it freely, with the\r
+* following restrictions:\r
+* 1) No charge may be made other than reasonable charges for reproduction.\r
+* 2) Modified versions must be clearly marked as such.\r
+* 3) The authors are not responsible for any harmful consequences\r
+* of using this software, even if they result from defects in it.\r
+*\r
+*------------------------------------------------\r
+\r
+ldiv:\r
+ move.l 4(%a7),%d0\r
+ bpl ld1\r
+ neg.l %d0\r
+ld1:\r
+ move.l 8(%a7),%d1\r
+ bpl ld2\r
+ neg.l %d1\r
+ eor.b #0x80,4(%a7)\r
+ld2:\r
+ bsr i_ldiv /* d0 = d0/d1 */\r
+ tst.b 4(%a7)\r
+ bpl ld3\r
+ neg.l %d0\r
+ld3:\r
+ rts\r
+\r
+lmul:\r
+ move.l 4(%a7),%d0\r
+ bpl lm1\r
+ neg.l %d0\r
+lm1:\r
+ move.l 8(%a7),%d1\r
+ bpl lm2\r
+ neg.l %d1\r
+ eor.b #0x80,4(%a7)\r
+lm2:\r
+ bsr i_lmul /* d0 = d0*d1 */\r
+ tst.b 4(%a7)\r
+ bpl lm3\r
+ neg.l %d0\r
+lm3:\r
+ rts\r
+\r
+lrem:\r
+ move.l 4(%a7),%d0\r
+ bpl lr1\r
+ neg.l %d0\r
+lr1:\r
+ move.l 8(%a7),%d1\r
+ bpl lr2\r
+ neg.l %d1\r
+lr2:\r
+ bsr i_ldiv /* d1 = d0%d1 */\r
+ move.l %d1,%d0\r
+ tst.b 4(%a7)\r
+ bpl lr3\r
+ neg.l %d0\r
+lr3:\r
+ rts\r
+\r
+ldivu:\r
+ move.l 4(%a7),%d0\r
+ move.l 8(%a7),%d1\r
+ bsr i_ldiv\r
+ rts\r
+\r
+lmulu:\r
+ move.l 4(%a7),%d0\r
+ move.l 8(%a7),%d1\r
+ bsr i_lmul\r
+ rts\r
+\r
+lremu:\r
+ move.l 4(%a7),%d0\r
+ move.l 8(%a7),%d1\r
+ bsr i_ldiv\r
+ move.l %d1,%d0\r
+ rts\r
+*\r
+* A in d0, B in d1, return A*B in d0\r
+*\r
+i_lmul:\r
+ move.l %d3,%a2 /* save d3 */\r
+ move.w %d1,%d2\r
+ mulu %d0,%d2 /* d2 = Al * Bl */\r
+\r
+ move.l %d1,%d3\r
+ swap %d3\r
+ mulu %d0,%d3 /* d3 = Al * Bh */\r
+\r
+ swap %d0\r
+ mulu %d1,%d0 /* d0 = Ah * Bl */\r
+\r
+ add.l %d3,%d0 /* d0 = (Ah*Bl + Al*Bh) */\r
+ swap %d0\r
+ clr.w %d0 /* d0 = (Ah*Bl + Al*Bh) << 16 */\r
+\r
+ add.l %d2,%d0 /* d0 = A*B */\r
+ move.l %a2,%d3 /* restore d3 */\r
+ rts\r
+*\r
+*A in d0, B in d1, return A/B in d0, A%B in d1\r
+*\r
+i_ldiv:\r
+ tst.l %d1\r
+ bne nz1\r
+\r
+* divide by zero\r
+* divu #0,%d0 /* cause trap */\r
+ move.l #0x80000000,%d0\r
+ move.l %d0,%d1\r
+ rts\r
+nz1:\r
+ move.l %d3,%a2 /* save d3 */\r
+ cmp.l %d1,%d0\r
+ bhi norm\r
+ beq is1\r
+* A<B, so ret 0, rem A\r
+ move.l %d0,%d1\r
+ clr.l %d0\r
+ move.l %a2,%d3 /* restore d3 */\r
+ rts\r
+* A==B, so ret 1, rem 0\r
+is1:\r
+ moveq.l #1,%d0\r
+ clr.l %d1\r
+ move.l %a2,%d3 /* restore d3 */\r
+ rts\r
+* A>B and B is not 0\r
+norm:\r
+ cmp.l #1,%d1\r
+ bne not1\r
+* B==1, so ret A, rem 0\r
+ clr.l %d1\r
+ move.l %a2,%d3 /* restore d3 */\r
+ rts\r
+* check for A short (implies B short also)\r
+not1:\r
+ cmp.l #0xffff,%d0\r
+ bhi slow\r
+* A short and B short -- use 'divu'\r
+ divu %d1,%d0 /* d0 = REM:ANS */\r
+ swap %d0 /* d0 = ANS:REM */\r
+ clr.l %d1\r
+ move.w %d0,%d1 /* d1 = REM */\r
+ clr.w %d0\r
+ swap %d0\r
+ move.l %a2,%d3 /* restore d3 */\r
+ rts\r
+* check for B short\r
+slow:\r
+ cmp.l #0xffff,%d1\r
+ bhi slower\r
+* A long and B short -- use special stuff from gnu\r
+ move.l %d0,%d2\r
+ clr.w %d2\r
+ swap %d2\r
+ divu %d1,%d2 /* d2 = REM:ANS of Ahi/B */\r
+ clr.l %d3\r
+ move.w %d2,%d3 /* d3 = Ahi/B */\r
+ swap %d3\r
+\r
+ move.w %d0,%d2 /* d2 = REM << 16 + Alo */\r
+ divu %d1,%d2 /* d2 = REM:ANS of stuff/B */\r
+\r
+ move.l %d2,%d1\r
+ clr.w %d1\r
+ swap %d1 /* d1 = REM */\r
+\r
+ clr.l %d0\r
+ move.w %d2,%d0\r
+ add.l %d3,%d0 /* d0 = ANS */\r
+ move.l %a2,%d3 /* restore d3 */\r
+ rts\r
+* A>B, B > 1\r
+slower:\r
+ move.l #1,%d2\r
+ clr.l %d3\r
+moreadj:\r
+ cmp.l %d0,%d1\r
+ bhs adj\r
+ add.l %d2,%d2\r
+ add.l %d1,%d1\r
+ bpl moreadj\r
+* we shifted B until its >A or sign bit set\r
+* we shifted #1 (d2) along with it\r
+adj:\r
+ cmp.l %d0,%d1\r
+ bhi ltuns\r
+ or.l %d2,%d3\r
+ sub.l %d1,%d0\r
+ltuns:\r
+ lsr.l #1,%d1\r
+ lsr.l #1,%d2\r
+ bne adj\r
+* d3=answer, d0=rem\r
+ move.l %d0,%d1\r
+ move.l %d3,%d0\r
+ move.l %a2,%d3 /* restore d3 */\r
+ rts\r
+*---------------------------------------------------------- \r
+*\r
+* Z80 Sound Driver\r
+*\r
+*---------------------------------------------------------- \r
+Z80Driver:\r
+ dc.b 0xc3,0x46,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00\r
+ dc.b 0x00,0x00,0x00,0x00,0x00,0x00,0xf3,0xed\r
+ dc.b 0x56,0x31,0x00,0x20,0x3a,0x39,0x00,0xb7\r
+ dc.b 0xca,0x4c,0x00,0x21,0x3a,0x00,0x11,0x40\r
+ dc.b 0x00,0x01,0x06,0x00,0xed,0xb0,0x3e,0x00\r
+ dc.b 0x32,0x39,0x00,0x3e,0xb4,0x32,0x02,0x40\r
+ dc.b 0x3e,0xc0,0x32,0x03,0x40,0x3e,0x2b,0x32\r
+ dc.b 0x00,0x40,0x3e,0x80,0x32,0x01,0x40,0x3a\r
+ dc.b 0x43,0x00,0x4f,0x3a,0x44,0x00,0x47,0x3e\r
+ dc.b 0x06,0x3d,0xc2,0x81,0x00,0x21,0x00,0x60\r
+ dc.b 0x3a,0x41,0x00,0x07,0x77,0x3a,0x42,0x00\r
+ dc.b 0x77,0x0f,0x77,0x0f,0x77,0x0f,0x77,0x0f\r
+ dc.b 0x77,0x0f,0x77,0x0f,0x77,0x0f,0x77,0x3a\r
+ dc.b 0x40,0x00,0x6f,0x3a,0x41,0x00,0xf6,0x80\r
+ dc.b 0x67,0x3e,0x2a,0x32,0x00,0x40,0x7e,0x32\r
+ dc.b 0x01,0x40,0x21,0x40,0x00,0x7e,0xc6,0x01\r
+ dc.b 0x77,0x23,0x7e,0xce,0x00,0x77,0x23,0x7e\r
+ dc.b 0xce,0x00,0x77,0x3a,0x39,0x00,0xb7,0xc2\r
+ dc.b 0x4c,0x00,0x0b,0x78,0xb1,0xc2,0x7f,0x00\r
+ dc.b 0x3a,0x45,0x00,0xb7,0xca,0x4c,0x00,0x3d\r
+ dc.b 0x3a,0x45,0x00,0x06,0xff,0x0e,0xff,0xc3\r
+ dc.b 0x7f,0x00\r
+Z80DriverEnd:\r
+\r
+\r
--- /dev/null
+##################################################
+# #
+# Assemble with gas #
+# --register-prefix-optional --bitwise-or #
+# #
+##################################################
+
+.text
+.globl main
+
+##################################################
+# #
+# Register and bitmask definitions #
+# #
+##################################################
+
+.equ GFXDATA, 0xc00000
+.equ GFXCNTL, 0xc00004
+
+.equ VDP0_E_HBI, 0x10
+.equ VDP0_E_DISPLAY, 0x02
+.equ VDP0_PLTT_FULL, 0x04
+
+.equ VDP1_SMS_MODE, 0x80
+.equ VDP1_E_DISPLAY, 0x40
+.equ VDP1_E_VBI, 0x20
+.equ VDP1_E_DMA, 0x10
+.equ VDP1_NTSC, 0x00
+.equ VDP1_PAL, 0x08
+.equ VDP1_RESERVED, 0x04
+
+.equ VDP12_SPR_SHADOWS, 0x08
+.equ VDP12_SCREEN_V224, 0x00
+.equ VDP12_SCREEN_V448, 0x04
+.equ VDP12_PROGRESSIVE, 0x00
+.equ VDP12_INTERLACED, 0x02
+.equ VDP12_SCREEN_H256, 0x00
+.equ VDP12_SCREEN_H320, 0x81
+
+.equ VDP16_MAP_V32, 0x00
+.equ VDP16_MAP_V64, 0x10
+.equ VDP16_MAP_V128, 0x30
+.equ VDP16_MAP_H32, 0x00
+.equ VDP16_MAP_H64, 0x01
+.equ VDP16_MAP_H128, 0x03
+
+
+
+##################################################
+# #
+# MACROS #
+# #
+##################################################
+
+
+/* Write val to VDP register reg */
+.macro write_vdp_reg reg val
+ move.w #((\reg << 8) + 0x8000 + \val),(a3)
+.endm
+
+
+/* For immediate addresses */
+.macro VRAM_ADDR reg adr
+ move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
+.endm
+
+
+/* For indirect (variable) addresses.
+ Destroys d6-d7. */
+.macro VRAM_ADDR_var reg adr
+ move.l \adr,d6
+ move.l \adr,d7
+ and.w #0x3fff,d6
+ lsr.w #7,d7
+ lsr.w #7,d7
+ add.w #0x4000,d6
+ lsl.l #7,d6
+ lsl.l #7,d6
+ lsl.l #2,d6
+ or.l d7,d6
+ move.l d6,\reg
+.endm
+
+
+.macro CRAM_ADDR reg adr
+ move.l #(((0xc000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
+.endm
+
+
+/* For indirect (variable) addresses */
+.macro CRAM_ADDR_var reg adr
+ move.l \adr,d6
+ move.l \adr,d7
+ and.w #0x3fff,d6
+ lsr.w #7,d7
+ lsr.w #7,d7
+ add.w #0xc000,d6
+ lsl.l #7,d6
+ lsl.l #7,d6
+ lsl.l #2,d6
+ or.l d7,d6
+ move.l d6,\reg
+.endm
+
+
+.macro VSCROLL_ADDR reg adr
+ move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + ((\adr >> 14) | 0x10)),\reg
+.endm
+
+
+.macro HSCROLL_ADDR reg adr
+ move.l #(((0x4000 + (\adr & 0x3fff)) << 16) + (\adr >> 14)),\reg
+.endm
+
+
+#################################################
+# #
+# DATA #
+# #
+#################################################
+
+colors:
+ dc.w 0x0040,0x0080,0x000e,0x00e0,0x0e00,0x00ee
+pattern:
+ dc.l 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000
+ dc.l 0x22334455,0x22334455,0x22334455,0x22334455,0x22334455,0x22334455,0x22334455,0x22334455
+ /* shadow sprite */
+ dc.l 0x00000fff
+ dc.l 0x0000ffff
+ dc.l 0x00ffffff
+ dc.l 0x00ffffff
+ dc.l 0x0fffffff
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ /* */
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ dc.l 0x0fffffff
+ dc.l 0x00ffffff
+ dc.l 0x00ffffff
+ dc.l 0x0000ffff
+ dc.l 0x00000fff
+ /* */
+ dc.l 0xfff00000
+ dc.l 0xffff0000
+ dc.l 0xffffff00
+ dc.l 0xffffff00
+ dc.l 0xfffffff0
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ /* */
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ dc.l 0xffffffff
+ dc.l 0xfffffff0
+ dc.l 0xffffff00
+ dc.l 0xffffff00
+ dc.l 0xffff0000
+ dc.l 0xfff00000
+ /* hilight sprite */
+ dc.l 0x00000eee
+ dc.l 0x0000eeee
+ dc.l 0x00eeeeee
+ dc.l 0x00eeeeee
+ dc.l 0x0eeeeeee
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ /* */
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ dc.l 0x0eeeeeee
+ dc.l 0x00eeeeee
+ dc.l 0x00eeeeee
+ dc.l 0x0000eeee
+ dc.l 0x00000eee
+ /* */
+ dc.l 0xeee00000
+ dc.l 0xeeee0000
+ dc.l 0xeeeeee00
+ dc.l 0xeeeeee00
+ dc.l 0xeeeeeee0
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ /* */
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeeee
+ dc.l 0xeeeeeee0
+ dc.l 0xeeeeee00
+ dc.l 0xeeeeee00
+ dc.l 0xeeee0000
+ dc.l 0xeee00000
+
+
+sprite_data:
+ /* Y size link attr X */
+ dc.w 10+128; dc.b 0x05; dc.b 1; dc.w 0x6002; dc.w 0
+ dc.w 30+128; dc.b 0x05; dc.b 2; dc.w 0x6006; dc.w 0
+ dc.w 60+128; dc.b 0x05; dc.b 3; dc.w 0xe002; dc.w 0
+ dc.w 80+128; dc.b 0x05; dc.b 4; dc.w 0xe006; dc.w 0
+ dc.w 120+128; dc.b 0x05; dc.b 5; dc.w 0x6002; dc.w 0
+ dc.w 140+128; dc.b 0x05; dc.b 6; dc.w 0x6006; dc.w 0
+ dc.w 170+128; dc.b 0x05; dc.b 7; dc.w 0xe002; dc.w 0
+ dc.w 190+128; dc.b 0x05; dc.b 0; dc.w 0xe006; dc.w 0
+sprite_data_end:
+
+
+##################################################
+# #
+# MAIN PROGRAM #
+# #
+##################################################
+
+main:
+ /* Initialize VDP */
+ jsr init_gfx
+
+ /* Load color data */
+ movea.l #0,a3
+ move.l #colors,a4
+ moveq.l #6,d4
+ jsr load_colors
+
+ /* load patterns */
+ movea.l #0,a3
+ movea.l #pattern,a4
+ move.l #10,d4
+ jsr load_tiles
+
+ /* generate A layer map */
+ movea.l #0xe000+10*2,a6
+ move.l #28-1,d4
+lmaploop0:
+ movea.l a6,a3
+ jsr load_prepare
+
+ moveq.l #6-1,d3
+0: move.l #0x00010001,(a3)
+ dbra d3,0b
+
+ moveq.l #9-1,d3
+0: move.l #0x80018001,(a3)
+ dbra d3,0b
+
+ add.l #64*2,a6
+ dbra d4,lmaploop0
+
+ /* generate B layer map */
+ movea.l #0xc000+64*14*2,a3
+ jsr load_prepare
+
+ move.l #64*14/2-1,d3
+0: move.l #0x80008000,(a3)
+ dbra d3,0b
+
+ /* upload sprite data */
+ movea.l #0xfc00,a3
+ jsr load_prepare
+ movea.l #sprite_data,a0
+
+ move.l #(sprite_data_end-sprite_data)/2-1,d3
+0: move.l (a0)+,(a3)
+ dbra d3,0b
+
+ jsr wait_vsync
+
+##################################################
+# #
+# MAIN LOOP #
+# #
+##################################################
+
+forever:
+ movea.l #vtimer,a0
+ move.l (a0),d4
+ and.w #0x1ff,d4
+ movea.l #0xfc06,a6
+ moveq.l #8-1,d5
+
+0:
+ movea.l a6,a3
+ jsr load_prepare
+ move.w d4,(a3)
+ addq.w #8,a6
+ dbra d5,0b
+
+ jsr wait_vsync
+ bra forever
+
+
+
+#################################################
+# #
+# Initialize VDP registers #
+# #
+#################################################
+
+init_gfx:
+ move.l #GFXCNTL,a3
+ write_vdp_reg 0,(VDP0_E_DISPLAY + VDP0_PLTT_FULL)
+ write_vdp_reg 1,(VDP1_E_VBI + VDP1_E_DISPLAY + VDP1_E_DMA + VDP1_RESERVED)
+ write_vdp_reg 2,(0xe000 >> 10) /* Screen map a adress */
+ write_vdp_reg 3,(0xe000 >> 10) /* Window address */
+ write_vdp_reg 4,(0xc000 >> 13) /* Screen map b address */
+ write_vdp_reg 5,(0xfc00 >> 9) /* Sprite address */
+ write_vdp_reg 6,0
+ write_vdp_reg 7,1 /* Border color */
+ write_vdp_reg 10,1 /* Lines per hblank interrupt */
+ write_vdp_reg 11,0 /* 2-cell vertical scrolling */
+ write_vdp_reg 12,(VDP12_SCREEN_V224 | VDP12_SCREEN_H320 | VDP12_SPR_SHADOWS)
+ write_vdp_reg 13,(0x6000 >> 10) /* Horizontal scroll address */
+ write_vdp_reg 15,2
+ write_vdp_reg 16,(VDP16_MAP_V32 + VDP16_MAP_H64)
+ write_vdp_reg 17,0
+ write_vdp_reg 18,0xff
+ rts
+
+
+
+#################################################
+# #
+# Load tile data from ROM #
+# #
+# Parameters: #
+# a3: VRAM base #
+# a4: pattern address #
+# d4: number of tiles to load #
+# Destroys a2,d0,d6-d7... #
+# #
+#################################################
+
+load_tiles:
+ move.l #GFXCNTL,a2
+ VRAM_ADDR_var d0,a3
+ move.l d0,(a2)
+ lsl #3,d4
+
+ move.l #GFXDATA,a3
+ subq.l #1,d4
+_copy_tile_data:
+ move.l (a4)+,(a3)
+ dbra d4,_copy_tile_data
+
+ rts
+
+
+load_prepare:
+ move.l #GFXCNTL,a2
+ VRAM_ADDR_var d0,a3
+ move.l d0,(a2)
+ move.l #GFXDATA,a3
+
+ rts
+
+
+#################################################
+# #
+# Clear one of the screen maps #
+# #
+# Parameters: #
+# a0: Map address #
+# d0: Data to write to each map entry #
+# #
+#################################################
+
+clear_map:
+ move.l #GFXCNTL,a4
+ VRAM_ADDR_var d1,a0
+ move.l d1,(a4)
+ move.l #GFXDATA,a3
+ move.w #1023,d1 /* Loop counter */
+_clear_map_loop:
+ move.w d0,(a3)
+ move.w d0,(a3)
+ dbra d1,_clear_map_loop
+ rts
+
+
+#################################################
+# #
+# Load color data from ROM #
+# #
+# Parameters: #
+# a3: CRAM base #
+# a4: color list address #
+# d4: number of colors to load #
+# #
+#################################################
+
+load_colors:
+ move.l #GFXCNTL,a2
+ CRAM_ADDR_var d0,a3
+ move.l d0,(a2)
+
+ move.l #GFXDATA,a3
+ subq.w #1,d4
+_copy_color_data:
+ move.w (a4)+,(a3)
+ dbra d4,_copy_color_data
+
+ rts
+
+
+#################################################
+# #
+# Wait for next VBlank interrupt #
+# #
+#################################################
+
+wait_vsync:
+ movea.l #vtimer,a0
+ move.l (a0),a1
+_wait_change:
+ stop #0x2000
+ cmp.l (a0),a1
+ beq _wait_change
+ rts
+
+
+#################################################
+# #
+# RAM DATA #
+# #
+#################################################
+
+.bss
+.globl htimer
+.globl vtimer
+.globl rand_num
+htimer: .long 0
+vtimer: .long 0
+rand_num: .long 0
+scrollx: .long 0
+
+.end
+
+# vim:filetype=asmM68k