Plane_Top_1 equ $70000 ; High-res top section (RADAR etc) Plane_Top_2 equ $71000 ; Plane_Bott_1 equ $72000 ; High-res bottom section (Scores) Plane_Bott_2 equ $72C00 ; Plane_Back equ $74000 ; Background Plane_O_A equ $75900 ; Objects Plane_T_A equ $77200 ; Tanks Plane_E_A equ $78B00 ; Explosions Plane_O_B equ $7A400 ; Plane_T_B equ $7BD00 ; Plane_E_B equ $7D600 ; Sprite_Data equ $7F000 ; Sprite shape defns Sprite_Length equ 256 ; 15 lines, + 2 word * 4 vInt_1 equ $64 ; Interrupt vector base PlaneWidth equ 42 ; For mountains nFrags equ 9 ; Explosion bits nShells equ 3 ; Allow three nObjects equ 30 ; nObjects_T equ nObjects+2+nShells+nFrags*3; Normal equ %1 ; Alive Frag_F equ %1 ; Shell_F equ %1 ; oFlags equ 0 ; Object offsets oX equ 2 ; oY equ 4 ; oZ equ 6 ; oAngle equ 8 ; odX equ 10 ; odY equ 12 ; odZ equ 14 ; odAngle equ 16 ; opDisplay equ 18 ; opMove equ 22 ; opShot equ 26 ; oCnt equ 30 ; Various counters oCnt2 equ 32 ; opXS_Table equ 34 ; Ptr to X-Section data lObject equ 40 ; Length Min_X equ 0 ; For clip Min_Y equ 1 ; Max_X equ 319 ; Max_Y equ 150 ; Range equ $6000 ; Sight Max_OS equ $100 ; Object maxm. size Trivial_Clip equ Range-Max_OS ; Ignore if further Clip_X equ $2000+Max_OS ; Clipping constants Clip_Z equ Trivial_Clip ; Clip_MinZ equ $100 ; Floor_Y equ $100 ; Y of ground My_dTheta equ 3 ; move value My_dZ equ 200 ; Shell_SP equ 450 ; Shell_Life equ 50 ; Shell_Clip equ Shell_SP+100 ; Shell_Ang equ $30 ; Shell_Height equ $2C ; Shell_Width equ $30 ; For collision detect Sine_Tab equ $F800 ; Sine table Mountains equ $60000 ; Mountain table MW equ 452 ; Nasty width ExGravity equ 6 ; For Frags org $1000 ; Somewhere bsr Init_Things ; Init everything Next_Frame tst.b Frame_Count+3.l ; Wait for second int. beq.s Next_Frame ; bset #0,Frame_Change.l ; Assert a frame change Int_Wait btst #0,Frame_Change.l ; Changed frame ? bne.s Int_Wait ; No, wait clr.l Frame_Count.l ; Clear it move View_Angle.l,d2 ; Get angle to show mountains bsr Draw_Mountains ; Copy moutain data bsr Undraw_Old ; Clear display bsr Move_Player ; Move first object, viewpoint bsr Move_Objects ; Draw them bclr #1,Fire_Flag.l ; Fired ? (Clear) beq.s Wait_End ; No bsr My_Fire_Shell ; Fire a shell Wait_End btst #6,$BFE001.l ; Mouse button bne.s Next_Frame ; not pressed Exit rts ; Init_Things bsr Init_Kbd ; Set up key_array bsr Init_Mouse ; Set up mouse bsr Init_Ints ; Set up the interrupt handlers bsr Set_Up_VDU ; Create a play-fields etc bsr CLS ; Clear the play fields,etc bsr Draw_Horizon ; Put a line in bsr Set_Up_Tables ; Create rotate tables bsr Define_Sprites ; Show the sprites bsr Init_Objects ; Add some objects bsr Init_Player ; Set up viewer bsr Init_Paging ; Set up line lists etc bsr Init_Mount ; Set up the mountains rts ; Done Init_Mount move #-1,Mount_Angle.l ; Impossible angle rts ; Draw_Horizon move.l #Plane_Back+PlaneWidth*75,a0 ; move #PlaneWidth-1,d0 ; moveq #-1,d1 ; $FF DH_Lp move.b d1,[a0]+ ; Plant it dbra d0,DH_Lp ; Loop rts ; Done Draw_Mountains and #$3FF,d2 ; Clip angle cmp Mount_Angle.l,d2 ; Same as old angle ? beq.s DM_Done ; Yes, don't re-draw move d2,Mount_Angle.l ; Save new value mulu #52736,d2 ; Convert angle to pixel asl.l #2,d2 ; / 16384 swap d2 ; ; Now d2 is in the range 0 .. 3292 move d2,d0 ; Get rotate value not d0 and #%1111,d0 ; 0 .. F lsr #3,d2 ; Offset word and #$1FE,d2 ; ext.l d2 ; Make 32-bit add.l #Mountains,d2 ; Calc address move.l #Plane_Back+PlaneWidth*27-2,d1 ; Start address move.l #Regs,a6 ; Point at registers bsr Wait_Blit_Free ; Make sure it's free move #%1 0000 1 1 0 0 1 0 0 0 0 0 0,DMACON[a6] ; DMA move.l d2,BLTAPTH[a6] ; Set up source move.l d1,BLTDPTH[a6] ; Set up destination move #MW-41,BLTAMOD[a6] ; Skip rest of mountain data move #0,BLTDMOD[a6] ; Modulo to no-skip clr BLTCON1[a6] ; No special modes ror #4,d0 ; Align shift value or #%0000 1 0 0 1 11110000,d0 ; D := A move d0,BLTCON0[a6] ; Shift, mode move #(48*64) + 21,d0 ; 48 lines by full width move d0,BLTSIZE[a6] ; Trigger the blit DM_Done rts ; Done My_Fire_Shell move.l #My_Shells,a0 ; Point at shell space move #nShells-1,d0 ; This many MFS_Lp btst #0,oFlags+1[a0] ; Alive ? beq.s MFS_Got_One ; No, use it add.l #lObject,a0 ; Step dbra d0,MFS_Lp ; Loop rts ; No shells MFS_Got_One move.l #My_Object,a1 ; Point at data move #Shell_F,oFlags[a0]; Alive move oX[a1],oX[a0] ; Same X move oZ[a1],oZ[a0] ; Z clr oY[a0] ; Y move oAngle[a1],d2 ; Get view angle move d2,oAngle[a0] ; Set angle clr d0 ; X:=0 move #Shell_SP,d1 ; Z := Speed bsr Rotate ; Vector it move d0,odX[a0] ; move d1,odZ[a0] ; clr odY[a0] ; clr odAngle[a0] ; Save it move #Shell_Life,oCnt[a0] ; Lifetime move.l #omShell,opMove[a0] ; Move move.l #OD_Shell,opDisplay[a0]; Display MFS_Done rts ; Done Test_Explode bsr Find_Object ; Get first valid object beq.s TE_Done ; None alive move.l a0,a1 ; Point at object bsr Blow_Up ; Kill object TE_Done rts ; Done Find_Object move.l #Object_Table,a0; Start here move #nObjects-1,d0 ; Cnt FO_Lp btst #7,oFlags[a0] ; Visible ? beq.s FO_1 ; No, skip btst #0,oFlags+1[a0] ; Alive ? bne.s FO_Done ; Yes, found FO_1 add.l #lObject,a0 ; Skip dbra d0,FO_Lp ; Loop cmp d0,d0 ; Z FO_Done rts ; Done Blow_Up movem d7,-[sp] ; Save cnt move #3*nFrags-1,d7 ; There are this many bits move #nFrags-1,d5 ; Use this many move.l #Fragments,a2 ; First fragment bsr Quick_Rand ; Get random start angle move d0,d6 ; BU_Lp btst #0,oFlags+1[a2] ; Already alive ? bne.s BU_Next ; Yes, skip bsr.s BU_Add_Exp ; Add it dbra d5,BU_Next ; Another ? movem [sp]+,d7 ; Cnt rts ; All done BU_Next add.l #lObject,a2 ; Next dbra d7,BU_Lp ; Loop movem [sp]+,d7 ; Cnt rts ; Done BU_Add_Exp move #Frag_F,oFlags[a2]; Alive move oX[a1],oX[a2] ; Same X move oZ[a1],oZ[a2] ; Y move #Floor_Y,oY[a2] ; Z add #1024/nFrags,d6 ; Step angle move d6,d2 ; Angle and #$3FF,d2 ; move d2,oAngle[a2] ; Set angle bsr.s Get_Rand_Vel ; Get a random velocity move d0,odX[a2] ; move d1,odZ[a2] ; bsr Quick_Rand ; Get rand and #$7F,d0 ; Range add #28,d0 ; Min. neg d0 ; - ve move d0,odY[a2] ; Save it bsr Quick_Rand ; Get rand and #$7F,d0 ; Range sub #$40,d0 ; Min. move d0,odAngle[a2] ; Save it bsr Quick_Rand ; move d0,d1 ; Save rand and #$0003,d0 ; addq #1,d0 ; move d0,oCnt[a2] ; Bounce count := 0 move.l #omExplode,opMove[a2] ; Move move.l #OD_Frag,opDisplay[a2]; Display rts ; Done Get_Rand_Vel bsr Quick_Rand ; Random X and #$7F,d0 ; Range of rand add #36,d0 ; Min. clr d1 ; Z := 0 bra Rotate ; Angle it omShell subq #1,oCnt[a0] ; Dec. life beq omShell_Die ; Time-out move oX[a0],d0 ; Step it add odX[a0],d0 ; move d0,oX[a0] ; move oZ[a0],d0 ; add odZ[a0],d0 ; move d0,oZ[a0] ; ; Now test collide move #nObjects-1,d6 ; Loop cnt move.l #Object_Table,a1; Ptr omS_Lp move oFlags[a1],d0 ; Get flags and #$0001,d0 ; Alive ? beq omS_Next ; No, ignore it tst.l opXS_Table[a1] ; Can it be hit ? beq omS_Next ; No, ignore move oX[a1],d0 ; Get X sub oX[a0],d0 ; Relative X lsl #1,d0 ; Make 15-BIT asr #1,d0 ; move d0,d3 ; Save bpl.s omS_X1 ; In front ? neg d0 ; Make positive omS_X1 cmp #Shell_Clip,d0 ; In range ? bhi omS_Next ; No, ignore move oZ[a1],d1 ; Get Z sub oZ[a0],d1 ; Relative Z lsl #1,d1 ; Make 15-BIT asr #1,d1 ; move d1,d4 ; Save bpl.s omS_Z1 ; In front ? neg d1 ; Make positive omS_Z1 cmp #Shell_Clip,d1 ; In range ? bhi omS_Next ; No, ignore ; Now check Y, if required move d3,d0 ; X move d4,d1 ; Z move oAngle[a0],d2 ; Get shell angle neg d2 ; bsr Rotate ; Rotate into view ? cmp #Shell_Clip,d1 ; Out of range? bhi omS_Next ; Yes move.l opXS_Table[a1],a2 ; Point at X-Section table sub oAngle[a1],d2 ; Get relative angles neg d2 ; add d2,d2 ; *4 add d2,d2 ; and #$3FF*4,d2 ; Mask move d0,d1 ; Duplicate X add 0[a2,d2.w],d0 ; Calc LHS cmp #Shell_Width,d0 ; To right of shell ? bgt.s omS_Next ; Yes, miss add 2[a2,d2.w],d1 ; RHS cmp #-Shell_Width,d1 ; To left of shell ? blt.s omS_Next ; Yes, miss clr oFlags[a0] ; Kill shell clr oFlags[a1] ; Kill object bsr Blow_Up ; Explosion rts ; Done omS_Next add.l #lObject,a1 ; Step ptr dbra d6,omS_Lp ; Loop rts ; Done omShell_Die clr oFlags[a0] ; Kill it rts ; Done omExplode move oX[a0],d0 ; Step it add odX[a0],d0 ; move d0,oX[a0] ; move oZ[a0],d0 ; add odZ[a0],d0 ; move d0,oZ[a0] ; move odAngle[a0],d0 ; add oAngle[a0],d0 ; move d0,oAngle[a0] ; move oY[a0],d0 ; add odY[a0],d0 ; cmp #Floor_Y,d0 ; Hit floor ? bpl.s om_Ex_Bounce ; Yes move d0,oY[a0] ; move #ExGravity,d0 ; Accelerate add d0,odY[a0] ; rts ; Done om_Ex_Bounce subq #1,oCnt[a0] ; Bounced once more beq.s om_Ex_Kill ; Yes, kill it move odY[a0],d0 ; Get disp neg d0 ; Invert add d0,oY[a0] ; Restore asr #1,d0 ; /2 move d0,odY[a0] ; Replace asr odX[a0] ; Friction asr odZ[a0] ; rts ; Done om_Ex_Kill clr oFlags[a0] ; Kill it rts ; Done Quick_Rand move Rand_Ptr.l,d0 ; Get it addq #2,d0 ; Step it move d0,Rand_Ptr.l ; and #$FFFE,d0 ; Word boundary add *[pc,d0.w],d0 ; Read prog. add VPOSR+Regs.l,d0 ; + beam posn. add JOY0DAT+Regs.l,d0 ; More random rts ; Done Init_Player move #0,View_X.l ; Move around move #0,View_Z.l ; move #0,View_Angle.l ; rts ; Done Move_Player bsr tRight ; Right ? bne.s MP_L ; Yes, skip bsr tLeft ; Left then ? beq.s MP_S ; Straight sub #My_dTheta,View_Angle.l ; Change view bra.s MP_S ; Step MP_L bsr tLeft ; Left also ? bne.s MP_S ; Yes, straight add #My_dTheta,View_Angle.l ; Change view MP_S bsr tUp ; Ahead ? bne.s MP_A ; Yes, skip bsr tDown ; Behind then ? beq.s MP_Exit ; No, done move moveq #1,d3 ; Move backwards bra.s MP_D ; Step MP_A bsr tDown ; Back also ? bne.s MP_Exit ; Yes, done clr d3 ; Move forwards MP_D clr d0 ; X := 0 move #My_dZ,d1 ; Z := Vector move View_Angle.l,d2 ; Rotate vector bsr Rotate ; tst d3 ; Forwards or backwards ? beq.s MP_X ; Forwards neg d0 ; Negate it neg d1 ; MP_X add d0,View_X.l ; Step X add d1,View_Z.l ; Z MP_Exit rts ; Done OD_Shell nop OD_Frag move Disp_Angle.l,d2 ; Get angle move.l #Square_Tab_6,a1; Point at table bsr Get_Tab_Entry ; Get X,Z move d0,xv5.l ; move d1,zv5.l ; neg d2 ; draw backwards sub #Shell_Ang,d2 ; One side bsr Get_Tab_Entry ; Get X,Z move d0,xv1.l ; One side move d1,zv1.l ; add #2*Shell_Ang,d2 ; Other side bsr Get_Tab_Entry ; Get X,Z move d0,xv3.l ; One side move d1,zv3.l ; move Cent_Y.l,yv5.l ; move #Shell_Height/2,d0; dY add Cent_Y.l,d0 ; Bottom move d0,yv1.l ; move d0,yv3.l ; move #-(Shell_Height/2),d0; dY add Cent_Y.l,d0 ; Bottom move d0,yv2.l ; move d0,yv4.l ; ; Scale onto display move zv1.l,d4 ; move xv1.l,d3 ; bsr Obje_Div ; move d3,xv1.l ; move yv1.l,d3 ; bsr Obje_Div ; move d3,yv1.l ; move yv2.l,d3 ; bsr Obje_Div ; move d3,yv2.l ; move zv3.l,d4 ; move xv3.l,d3 ; bsr Obje_Div ; move d3,xv3.l ; move yv3.l,d3 ; bsr Obje_Div ; move d3,yv3.l ; move yv4.l,d3 ; bsr Obje_Div ; move d3,yv4.l ; move zv5.l,d4 ; move xv5.l,d3 ; bsr Obje_Div ; move d3,xv5.l ; move yv5.l,d3 ; bsr Obje_Div ; move d3,yv5.l ; ; Draw lines movem.l d7,-[sp] move xv1.l,d4 move yv1.l,d5 move xv1.l,d6 move yv2.l,d7 bsr Show_Line move xv3.l,d4 move yv3.l,d5 move xv3.l,d6 move yv4.l,d7 bsr Show_Line move xv1.l,d4 move yv1.l,d5 move xv3.l,d6 move yv3.l,d7 bsr Show_Line move xv1.l,d4 move yv2.l,d5 move xv3.l,d6 move yv4.l,d7 bsr Show_Line move xv1.l,d4 move yv1.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line move xv1.l,d4 move yv2.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line move xv3.l,d4 move yv3.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line move xv3.l,d4 move yv4.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line movem.l [sp]+,d7 ; Restore rts ; Done Get_Tab_Entry move d2,d3 ; Save angle add d3,d3 ; * 4 add d3,d3 ; and #$3FF*4,d3 ; Mask move 0[a1,d3.w],d0 ; X add Cent_X.l,d0 ; Center X move 2[a1,d3.w],d1 ; Z add Cent_Z.l,d1 ; Center Z rts ; Done OD_Pyramid1 move #-Floor_Y,d5 ; Top bra.s OD_P_1 ; OD_Pyramid2 move #-100,d5 ; Top bra.s OD_P_1 ; OD_Pyramid3 move #Floor_Y-110,d5 ; Top bra.s OD_P_1 ; OD_Pyramid move #30,d5 ; Top Y OD_P_1 move.l #Square_Tab_100,a1; Point to rotate table move Disp_Angle.l,d2 ; Theta bsr Do_Square_Base ; Calc base addresses move Cent_Z.l,d4 ; move d5,d3 ; Top Y bsr Obje_Div ; move d3,yv5.l ; move Cent_X.l,d3 ; Top X bsr Obje_Div ; move d3,xv5.l ; movem.l d7,-[sp] move xv1.l,d4 move yv1.l,d5 move xv2.l,d6 move yv2.l,d7 bsr Show_Line move xv2.l,d4 move yv2.l,d5 move xv3.l,d6 move yv3.l,d7 bsr Show_Line move xv3.l,d4 move yv3.l,d5 move xv4.l,d6 move yv4.l,d7 bsr Show_Line move xv4.l,d4 move yv4.l,d5 move xv1.l,d6 move yv1.l,d7 bsr Show_Line move xv1.l,d4 move yv1.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line move xv2.l,d4 move yv2.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line move xv3.l,d4 move yv3.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line move xv4.l,d4 move yv4.l,d5 move xv5.l,d6 move yv5.l,d7 bsr Show_Line movem.l [sp]+,d7 rts ; Done OD_Cube move #-Floor_Y,d5 ; Top Y bra.s OD_C_1 ; OD_Cube1 move #-50,d5 ; Top Y bra.s OD_C_1 ; OD_Cube2 move #Floor_Y-90,d5 ; Top Y OD_C_1 move.l #Square_Tab_100,a1; Point to rotate table move Disp_Angle.l,d2 ; Theta bsr Do_Square_Base ; Calc base addresses move zv1.l,d4 ; move d5,d3 ; Top Y bsr Obje_Div ; move d3,yv5.l ; move zv2.l,d4 ; move d5,d3 ; Top Y bsr Obje_Div ; move d3,yv6.l ; move zv3.l,d4 ; move d5,d3 ; Top Y bsr Obje_Div ; move d3,yv7.l ; move zv4.l,d4 ; move d5,d3 ; Top Y bsr Obje_Div ; move d3,yv8.l ; movem.l d7,-[sp] ; Base move xv1.l,d4 move yv1.l,d5 move xv2.l,d6 move yv2.l,d7 bsr Show_Line move xv2.l,d4 move yv2.l,d5 move xv3.l,d6 move yv3.l,d7 bsr Show_Line move xv3.l,d4 move yv3.l,d5 move xv4.l,d6 move yv4.l,d7 bsr Show_Line move xv4.l,d4 move yv4.l,d5 move xv1.l,d6 move yv1.l,d7 bsr Show_Line ; Sides move xv1.l,d4 move yv1.l,d5 move xv1.l,d6 move yv5.l,d7 bsr Show_Line move xv2.l,d4 move yv2.l,d5 move xv2.l,d6 move yv6.l,d7 bsr Show_Line move xv3.l,d4 move yv3.l,d5 move xv3.l,d6 move yv7.l,d7 bsr Show_Line move xv4.l,d4 move yv4.l,d5 move xv4.l,d6 move yv8.l,d7 bsr Show_Line ; Top move xv1.l,d4 move yv5.l,d5 move xv2.l,d6 move yv6.l,d7 bsr Show_Line move xv2.l,d4 move yv6.l,d5 move xv3.l,d6 move yv7.l,d7 bsr Show_Line move xv3.l,d4 move yv7.l,d5 move xv4.l,d6 move yv8.l,d7 bsr Show_Line move xv4.l,d4 move yv8.l,d5 move xv1.l,d6 move yv5.l,d7 bsr Show_Line movem.l [sp]+,d7 rts ; Done Do_Square_Base add d2,d2 ; * 4 add d2,d2 ; and #$3FF*4,d2 ; Mask move 0[a1,d2.w],d0 ; X move Cent_X.l,d1 ; Center X move d1,d3 ; X add d0,d3 ; move d3,xv1.l ; move d1,d3 ; sub d0,d3 ; move d3,xv3.l ; move Cent_Z.l,d1 ; Center Z move d1,d3 ; X add d0,d3 ; move d3,zv4.l ; move d1,d3 ; sub d0,d3 ; move d3,zv2.l ; move 2[a1,d2.w],d0 ; Z move Cent_X.l,d1 ; Center X move d1,d3 ; X add d0,d3 ; move d3,xv2.l ; move d1,d3 ; sub d0,d3 ; move d3,xv4.l ; move Cent_Z.l,d1 ; Center Z move d1,d3 ; X add d0,d3 ; move d3,zv1.l ; move d1,d3 ; sub d0,d3 ; move d3,zv3.l ; move xv1.l,d3 ; Divide onto screen move zv1.l,d4 ; bsr Obje_Div ; move d3,xv1.l ; move xv2.l,d3 ; move zv2.l,d4 ; bsr.s Obje_Div ; move d3,xv2.l ; move xv3.l,d3 ; move zv3.l,d4 ; bsr.s Obje_Div ; move d3,xv3.l ; move xv4.l,d3 ; move zv4.l,d4 ; bsr.s Obje_Div ; move d3,xv4.l ; move #Floor_Y,d3 ; Calc_Ys move zv1.l,d4 ; bsr.s Obje_Div ; move d3,yv1.l ; move #Floor_Y,d3 ; move zv2.l,d4 ; bsr.s Obje_Div ; move d3,yv2.l ; move #Floor_Y,d3 ; move zv3.l,d4 ; bsr.s Obje_Div ; move d3,yv3.l ; move #Floor_Y,d3 ; move zv4.l,d4 ; bsr.s Obje_Div ; move d3,yv4.l ; rts ; Done Obje_Div ext.l d3 ; Make 32-bit asl.l #4,d3 ; * 16 asl.l #5,d3 ; * 512 divs d4,d3 ; Scale onto window rts ; Done Set_Up_Tables move #$100,d3 ; Z move.l #Square_Tab_100,a0; bsr.s SUT_Square ; Set it up move #$60,d3 ; move.l #Square_Tab_6,a0; bsr.s SUT_Square ; ; Set up cross-section data move #$100,d3 ; Z at angle = 0 move.l #XS_100,a0 ; Table bsr.s SUT_Sq_XS ; Create X section move #$78,d3 ; move.l #XS_78,a0 ; bsr.s SUT_Sq_XS ; move #$43,d3 ; move.l #XS_43,a0 ; bsr.s SUT_Sq_XS ; move #$1,d3 ; move.l #XS_1,a0 ; bsr.s SUT_Sq_XS ; rts ; Create rotate tables SUT_Square clr d2 ; Initial angle SUT_S_Lp move d3,d1 ; Z clr d0 ; X bsr Rotate ; Rotate it move d0,[a0]+ ; X move d1,[a0]+ ; Z addq #1,d2 ; Step angle cmp #1024,d2 ; All done ? bne.s SUT_S_Lp ; No, loop rts ; Done SUT_Sq_XS clr d2 ; Initial angle SUT_Sq_XS_Lp move d3,d1 ; Z clr d0 ; X bsr Rotate ; Rotate it tst d0 ; Abs X bpl.s SSX_1 ; neg d0 ; SSX_1 tst d1 ; Abs Y bpl.s SSX_2 ; neg d1 ; SSX_2 cmp d0,d1 ; d1 > d0 ? bhi.s SSX_3 ; Yes exg d0,d1 ; Make d1 > d0 SSX_3 move d1,2[a0] ; Store RHS neg d1 ; LHS move d1,[a0] ; addq.l #4,a0 ; Step ptr addq #1,d2 ; Step angle cmp #1024,d2 ; All done ? bne.s SUT_Sq_XS_Lp ; No, loop rts ; Done Set_View_Rotate bsr.s Get_Sine ; Set angle to d2 move d3,VR_Sine.l ; Store it bsr.s Get_Cosine ; move d3,VR_Cosine.l ; rts ; Done Get_Sine movem.l d2/a0,-[sp] ; Save regs and #$3FF,d2 ; Clip 0 .. 1023 add d2,d2 ; 2 bytes per entry move.l #Sine_Tab,a0 ; Point to table move 0[a0,d2.w],d3 ; Get value movem.l [sp]+,d2/a0 ; Restore rts ; Get_Cosine movem.l d2/a0,-[sp] ; Save regs add #256,d2 ; Step along sine and #$3FF,d2 ; Clip 0 .. 1023 add d2,d2 ; 2 bytes per entry move.l #Sine_Tab,a0 ; Point to table move 0[a0,d2.w],d3 ; Get value movem.l [sp]+,d2/a0 ; Restore rts ; Rotate movem.l d2-d5/a0,-[sp] ; Save regs and #$3FF,d2 ; Clip 0 .. 1023 add d2,d2 ; 2 bytes per entry move.l #Sine_Tab,a0 ; Point to table move 0[a0,d2.w],d3 ; Get sine add #512,d2 ; Step along sine and #$7FE,d2 ; Clip (0 .. 1023) * 2 move 0[a0,d2.w],d2 ; Get cosine Do_Rotate move d0,d4 ; Save X move d1,d5 ; Save Z muls d2,d0 ; X.Cos asl.l #1,d0 ; swap d0 ; muls d3,d1 ; Z.Sin asl.l #1,d1 ; swap d1 ; add d1,d0 ; X := Z.Sin + X.Cos muls d3,d4 ; X.Sin asl.l #1,d4 ; swap d4 ; muls d2,d5 ; Z.Cos asl.l #1,d5 ; swap d5 ; move d5,d1 ; Z := Z.Cos - X.Sin sub d4,d1 ; movem.l [sp]+,d2-d5/a0 ; Restore rts ; Done View_Rotate movem.l d2-d5/a0,-[sp] ; Save regs move VR_Sine.l,d3 ; Rotate through view angle move VR_Cosine.l,d2 ; bra.s Do_Rotate ; Rotate it Move_Objects move.l #Object_Table,a0; Move and draw objects move View_Angle.l,d2 ; Viewing angle neg d2 ; and #$3FF,d2 ; Angle to rotate objects through bsr Set_View_Rotate ; Set up rotate move #nObjects_T-1,d7 ; Number MO_Lp bclr #7,oFlags[a0] ; Visible ? btst #0,oFlags+1[a0] ; Valid object ? beq MO_Next ; No, skip move.l opMove[a0],a1 ; Get address jsr [a1] ; Move object move oX[a0],d0 ; Get X sub View_X.l,d0 ; Relative X lsl #1,d0 ; Make 15-BIT asr #1,d0 ; move d0,d3 ; Save bpl.s MO_X1 ; In front ? neg d0 ; Make positive MO_X1 cmp #Trivial_Clip,d0 ; In sight ? bhi MO_Next ; No, ignore move oZ[a0],d1 ; Get Z sub View_Z.l,d1 ; Relative Z lsl #1,d1 ; Make 15-BIT asr #1,d1 ; move d1,d4 ; Save bpl.s MO_Z1 ; In front ? neg d1 ; Make positive MO_Z1 cmp #Trivial_Clip,d1 ; In sight ? bhi MO_Next ; No, ignore move d3,d0 ; X move d4,d1 ; Y bsr View_Rotate ; Rotate into view ? cmp #Clip_Z,d1 ; Visible ? bhi MO_Next ; No cmp #Clip_MinZ,d1 ; Visible ? bcs MO_Next ; No move d0,d2 ; Get X bpl.s MO_2 ; Abs neg d2 ; MO_2 cmp #Clip_X,d2 ; Visible ? bhi MO_Next ; No add d2,d2 ; In viewing cone ? cmp d1,d2 ; |2.X| <= Z ? bhi MO_Next ; No, not visible move d0,Cent_X.l ; Store center move d1,Cent_Z.l ; move oY[a0],Cent_Y.l ; move View_Angle.l,d2 ; View angle sub oAngle[a0],d2 ; Get relative angle neg d2 ; and #$3FF,d2 ; Clip move d2,Disp_Angle.l ; Save it bset #7,oFlags[a0] ; Yes, it's visible move.l opDisplay[a0],a1; Display it jsr [a1] ; MO_Next add.l #lObject,a0 ; Step ptr dbra d7,MO_Lp ; Loop rts ; All moved and drawn omRotate move oAngle[a0],d0 ; Rotate it add odAngle[a0],d0 ; and #$3FF,d0 ; 1024 angles move d0,oAngle[a0] ; Store rts ; Done omRun bsr omRotate ; Rotate it addq #1,odAngle[a0] move oX[a0],d0 ; Step it add odX[a0],d0 ; move d0,oX[a0] ; move oZ[a0],d0 ; add odZ[a0],d0 ; move d0,oZ[a0] ; rts ; Done Init_Objects move #nObjects-1,d7 ; Init this many move.l #Object_Table,a0 ; Point at data area move.l #Init_OT,a1 ; Initial data table move.l #Sine_Tab+100,a2 ; Random ptr IO_Lp bsr.s Init_Obj ; Initialise it add.l #lObject,a0 ; Move ptr dbra d7,IO_Lp ; Loop move #nObjects_T-nObjects,d7 ; Extra objects IO_Lp1 clr oFlags[a0] ; Terminate list of objects add.l #lObject,a0 ; Step dbra d7,IO_Lp1 ; Loop rts ; Done Init_Obj move [a1]+,d0 ; X move [a1]+,d1 ; Z move.l [a1]+,d2 ; ptr to DISPLAY routine move.l [a1]+,d5 ; Ptr to cross-section move.l #omRotate,d3 ; move moveq #0,d4 ; Angle Add_Obje move d0,oX[a0] ; Store X move d1,oZ[a0] ; Z clr oY[a0] ; On ground move d4,oAngle[a0] ; Angle of rotation move.l d2,opDisplay[a0]; DISPLAY routine move.l d3,opMove[a0] ; move move.l d5,opXS_Table[a0] ; Cross-Reference Table clr odX[a0] ; Don't move clr odZ[a0] ; clr odY[a0] ; move.b [a2]+,d1 and #$0007,d1 subq #3,d1 add d1,d1 move d1,odAngle[a0] ; Rate of rotation move #Normal,oFlags[a0]; Normal object rts ; Done Init_Paging clr Line_List_A.l ; Kill the line lists (none to undraw) clr Line_List_B.l ; rts ; Done Show_Line add #160,d4 ; Offset X add #160,d6 ; add #75,d5 ; Y add #75,d7 ; bsr Clip_Line ; Show it bcs.s CL_Done ; Not on screen movem d0-d7,-[sp] ; Save regs move d4,d0 move d5,d1 move d6,d2 move d7,d3 bsr Draw_Line ; Show it movem [sp]+,d0-d7 ; Restore CL_Done rts ; Done Undraw_Old move.l cPlane_O,a0 ; Point at memory move.l #Plane_T_A-Plane_O_A,d0 ; Length move #$0000,d1 ; Pattern bsr Blit_Clear ; Fill memory bra Wait_Blit_Free ; Wait till done ;Undraw_Old move.l pcLine_List.l,a0; Get ptr to line list ; Undraw them move.l #Regs,a6 ; Point at registers move #%1 0000 0 1 0 0 1 0 0 0 0 0 0,DMACON[a6] ; DMA UO_Lp tst [a0]+ ; End ? beq.s UO_Done ; Yes, done movem [a0],d0/d2/d3/d5-d7 ; Get regs add.l #7*2,a0 ; Step move.l [a0]+,d4 ; bsr Wait_Blit_Free ; Wait for blitter clr BLTBDAT[a6] ; Clear move #$8000,BLTADAT[a6] move #$FFFF,BLTAFWM[a6] move #$FFFF,BLTALWM[a6] move d2,BLTAMOD[a6] ; move d6,BLTBMOD[a6] ; move d7,BLTAPTL[a6] ; clr BLTAPTH[a6] ; move.l d4,BLTCPTH[a6] ; Start move.l d4,BLTDPTH[a6] ; " " move d0,BLTCON0[a6] ; Store them move d5,BLTCON1[a6] ; Octant move #PlaneWidth,d0 ; Width move d0,BLTCMOD[a6] ; Width move d0,BLTDMOD[a6] ; " " ; blt size and start move d3,BLTSIZE[a6] ; Trigger blit bra.s UO_Lp ; Try next UO_Done clr [a0] ; Kill list rts ; Done Clip_Line movem.l a0-a2,-[sp] ; Save regs move d6,a0 ; move d7,a1 ; sub d4,d6 ; dX sub d5,d7 ; dY move d7,a2 ; Temp save moveq #1,d7 ; Loop control Clip_0 exg d7,a2 ; bsr Bound ; move d0,d1 ; exg d4,a0 ; exg d5,a1 ; bsr Bound ; move d0,d2 ; or d1,d2 ; beq CL_Draw ; Entirely on screen move d0,d2 ; and d1,d2 ; bne CL_Fail ; Entirely off screen tst d0 ; Point B on screen ? beq Clip_4 ; Yes move #Max_Y,d3 ; btst #3,d0 ; too high ? bne Clip_1 ; Yes btst #2,d0 ; too low ? beq Clip_2 ; No, within bounds move #Min_Y,d3 ; Clip_1 bsr BorderY ; Clip B in Y bsr Bound ; move d0,d2 ; or d1,d2 ; beq CL_Draw ; Entirely on screen move d0,d2 ; and d1,d2 ; bne CL_Fail ; Entirely off screen tst d0 ; Point B on screen ? beq Clip_4 ; Yes Clip_2 move #Max_X,d3 ; btst #1,d0 ; too high ? bne Clip_3 ; Yes btst #0,d0 ; too low ? beq Clip_4 ; No, within bounds move #Min_X,d3 ; Clip_3 bsr BorderX ; Clip B in X Clip_4 exg d7,a2 ; dbf d7,Clip_0 ; If falling out of here then draw CL_Draw move a0,d6 ; move a1,d7 ; movem.l [sp]+,a0-a2 ; and.b #$FE,ccr ; rts ; CL_Fail movem.l [sp]+,a0-a2 ; or.b #$01,ccr ; rts ; BorderX move d0,-[sp] ; Save move d4,d0 ; sub d3,d0 ; muls d7,d0 ; divs d6,d0 ; neg d0 ; add d0,d5 ; move d3,d4 ; d3 holds X limit move [sp]+,d0 ; rts ; Done BorderY move d0,-[sp] ; Save move d5,d0 ; sub d3,d0 ; muls d6,d0 ; divs d7,d0 ; neg d0 ; add d0,d4 ; move d3,d5 ; d3 holds Y limit move [sp]+,d0 ; rts ; Done Bound clr d0 ; cmp #Min_X,d4 ; bge Bound1 ; bset #0,d0 ; bra Bound2 ; Bound1 cmp #Max_X,d4 ; ble Bound2 ; bset #1,d0 ; Bound2 cmp #Min_Y,d5 ; bge Bound3 ; bset #2,d0 ; bra Bound4 ; Bound3 cmp #Max_Y,d5 ; ble Bound4 ; bset #3,d0 ; Bound4 rts ; Done Oct_T defb 0 *4+1 ; defb 4 *4+1 ; defb 2 *4+1 ; defb 5 *4+1 ; defb 1 *4+1 ; defb 6 *4+1 ; defb 3 *4+1 ; defb 7 *4+1 ; Draw_Line move.l #PlaneWidth,d4 ; Width mulu d1,d4 ; Y1 * Bytes per line moveq #-$10,d5 ; No leading chars and d0,d5 ; Mask bottom 4 bits lsr #3,d5 ; /8 add d5,d4 ; Y1 * Bytes per line + X1/8 ; d4 now contains the start of the line (Needs base added) clr.l d5 ; 0 sub d1,d3 ; Y2-Y1 roxl.b #1,d5 ; Shift tst d3 ; Restore N flag bge.s DL_Y2gY1 ; dY positive neg d3 ; Abs DL_Y2gY1 sub d0,d2 ; X2-X1 roxl.b #1,d5 ; tst d2 ; Restore N flag bge.s DL_X2gX1 ; dX positive neg d2 ; Abs DL_X2gX1 move d3,d1 ; dY sub d2,d1 ; dY-dX bge.s DL_DYgDX ; exg d2,d3 ; Smaller Delat to d2 DL_DYgDX roxl.b #1,d5 ; d5 contains results of comparisons. move.b Oct_T[pc,d5],d5 ; Get matching octant add d2,d2 ; Smaller delta * 2 move d2,d6 ; 2*smaller delta sub d3,d2 ; 2dS-dL bge.s DL_SignN1 ; or.b #$40,d5 ; Set sign flag DL_SignN1 move d2,d7 ; 2dS-dL sub d3,d2 ; 2dS-2dL and #$000F,d0 ; Bottom 4 bits from X1 ror #4,d0 ; To START0-3 or #$0BCA,d0 ; USEx and LFx set addq #1,d3 ; Inc length lsl #6,d3 ; Length * 64 addq #2,d3 ; plus (Width = 2) add.l cPlane_O.l,d4 ; Plus bit-plane base ; Now draw it ; move.l pcLine_List,a6 ; Get ptr to line ; move #$1278,[a6]+ ; Flag valid ; movem d0/d2/d3/d5-d7,[a6] ; Save regs ; add.l #7*2,a6 ; Move ptr ; move.l d4,[a6]+ ; ; clr [a6] ; Terminate ; move.l a6,pcLine_List.l ; Save ptr move.l #Regs,a6 ; Point at registers bsr Wait_Blit_Free ; Wait for blitter move #%1 0000 0 1 0 0 1 0 0 0 0 0 0,DMACON[a6] ; DMA move #$FFFF,BLTBDAT[a6] ; Set or clear move #$8000,BLTADAT[a6] move #$FFFF,BLTAFWM[a6] move #$FFFF,BLTALWM[a6] move d2,BLTAMOD[a6] ; move d6,BLTBMOD[a6] ; move d7,BLTAPTL[a6] ; clr BLTAPTH[a6] ; move.l d4,BLTCPTH[a6] ; Start move.l d4,BLTDPTH[a6] ; " " move d0,BLTCON0[a6] ; Store them move d5,BLTCON1[a6] ; Octant move #PlaneWidth,d0 ; Width move d0,BLTCMOD[a6] ; Width move d0,BLTDMOD[a6] ; " " ; blt size and start move d3,BLTSIZE[a6] ; Trigger blit rts ; Done Define_Sprites move.l #Sprite_Table,a1; Point at sprite data moveq #0,d0 ; Sprite_No. DS_Lp move.l [a1]+,a0 ; Get sprite data move [a1]+,d1 ; X move [a1]+,d2 ; Y bsr.s Add_Sprite ; Change this sprite addq #1,d0 ; Next sprite cmp #24,d0 ; Done all ? bne.s DS_Lp ; Loop rts ; Done Add_Sprite movem.l d0-d3/a0-a1,-[sp] ; Save regs moveq #$07,d3 ; Get 'Y' bits and d0,d3 ; lsl #4,d3 ; * 256 (length of sprite group) lsl #4,d3 ; and #$0018,d0 ; Sprite group index (*8) lsl #3,d0 ; * 64 add d0,d3 ; Create address move d3,a1 ; Into ptr add.l #Sprite_Data,a1 ; Add base address add #$80,d1 ; Add X offset add #$30,d2 ; Add Y offset move d2,d0 ; Get Y lsl #4,d0 ; Align lsl #4,d0 ; move d1,d3 ; Save X lsr #1,d1 ; High bits of X move.b d1,d0 ; Create first word move d0,[a1]+ ; Save word and #$0001,d3 ; HSTART low bit move d2,d0 ; Get Y lsr #6,d0 ; Align VSTART top bit and #$0004,d0 ; Mask or d0,d3 ; HSTART,VSTART add #15,d2 ; Calc VSTOP move d2,d0 ; Get Y lsr #7,d0 ; Align VSTOP top bit and #$0002,d0 ; Mask or d0,d3 ; HSTART,VSTART,VSTOP lsl #4,d2 ; Align VSTOP lsl #4,d2 ; or d2,d3 ; Create second word move d3,[a1]+ ; Store it move #15-1,d0 ; Copy data AS_Lp move.l [a0]+,[a1]+ ; Copy one line dbra d0,AS_Lp ; Loop movem.l [sp]+,d0-d3/a0-a1 ; Restore rts ; Done Init_Ints move.l #vInt_1,a0 ; Set up vectors move.l #Int_1,[a0]+ ; 1 move.l #Int_2,[a0]+ ; 2 move.l #Int_3,[a0]+ ; 3 move.l #Int_4,[a0]+ ; 4 move.l #Int_5,[a0]+ ; 5 move.l #Int_6,[a0]+ ; 6 move.l #Int_7,[a0] ; 7 move.l #Regs,a6 ; Regs move #$7FFF,INTENA[a6] ; Kill ints move #$7FFF,INTREQ[a6] ; Kill pending ones move #%1 1 0 0 0 0000 0 0 1 1 000,INTENA[a6] ; Enable clr.l Frame_Count.l ; Number of frames clr.b cFrame.l ; Odd or Even move.b #1,Frame_Change.l ; Request a change clr.b Fire_Flag.l ; Not firing clr Rand_Ptr.l ; Start at 0 move #$2000,sr ; Enable ints rts ; Done Int_1 movem.l d0/a6,-[sp] ; Push regs move.l #Regs,a6 ; Point at regs move INTENAR[a6],d0 ; Get enable flags and #$4007,d0 ; Get level 1 beq.s I1_Done ; Spurious interrupt and INTREQR[a6],d0 ; Flag active ones and #$0007,d0 ; move d0,INTREQ[a6] ; Clear them I1_Done movem.l [sp]+,d0/a6 ; Restore regs rte ; Done Int_2 movem.l d0/a6,-[sp] ; Push regs move.l #Regs,a6 ; Point at regs move INTENAR[a6],d0 ; Get enable flags and #$4008,d0 ; Get level 2 beq.s I2_Done ; Spurious interrupt ; Deal with the keyboard, only possible int bsr Int_Kbd ; Cope with it move INTENAR[a6],d0 ; Get enable flags and INTREQR[a6],d0 ; Flag active ones and #$0008,d0 ; move d0,INTREQ[a6] ; Clear them I2_Done movem.l [sp]+,d0/a6 ; Restore regs rte ; Done Int_3 movem.l d0/a6,-[sp] ; Push regs move.l #Regs,a6 ; Point at regs move INTENAR[a6],d0 ; Get enable flags and #$4070,d0 ; Get level 3 beq.s I3_Done ; Spurious interrupt bsr Int_Copper ; Copper int (for now) move INTENAR[a6],d0 ; Get enable flags and INTREQR[a6],d0 ; Flag active ones and #$0070,d0 ; move d0,INTREQ[a6] ; Clear them I3_Done movem.l [sp]+,d0/a6 ; Restore regs rte ; Done Int_4 movem.l d0/a6,-[sp] ; Push regs move.l #Regs,a6 ; Point at regs move INTENAR[a6],d0 ; Get enable flags and #$4780,d0 ; Get level 4 beq.s I4_Done ; Spurious interrupt and INTREQR[a6],d0 ; Flag active ones and #$0780,d0 ; move d0,INTREQ[a6] ; Clear them I4_Done movem.l [sp]+,d0/a6 ; Restore regs rte ; Done Int_5 movem.l d0/a6,-[sp] ; Push regs move.l #Regs,a6 ; Point at regs move INTENAR[a6],d0 ; Get enable flags and #$5800,d0 ; Get level 5 beq.s I5_Done ; Spurious interrupt and INTREQR[a6],d0 ; Flag active ones and #$1800,d0 ; move d0,INTREQ[a6] ; Clear them I5_Done movem.l [sp]+,d0/a6 ; Restore regs rte ; Done Int_6 movem.l d0/a6,-[sp] ; Push regs move.l #Regs,a6 ; Point at regs move INTENAR[a6],d0 ; Get enable flags and #$6000,d0 ; Get level 6 beq.s I6_Done ; Spurious interrupt and INTREQR[a6],d0 ; Flag active ones and #$2000,d0 ; move d0,INTREQ[a6] ; Clear them I6_Done movem.l [sp]+,d0/a6 ; Restore regs Int_7 rte ; Done Int_Copper movem.l d0-d3/a0,-[sp] ; Save regs bclr #0,Frame_Change.l ; Swap screen pages ? beq IC_1 ; No, ok move.l Mouse_X.l,Game_X.l ; Copy mouse values move.l Page_Ptrs.l,a0 ; Get entry in Copper list bchg #0,cFrame.l ; Change frames beq.s IC_Set_B ; It was A, now it is B move #Plane_O_A and $FFFF,14[a0] ; Show Set A move #Plane_T_A and $FFFF,22[a0] ; move #Plane_E_A and $FFFF,30[a0] ; move.l #Plane_O_B,cPlane_O.l ; Draw onto Set B move.l #Plane_T_B,cPlane_T.l ; move.l #Plane_E_B,cPlane_E.l ; move.l #Line_List_B,pcLine_List.l ; Undraw from B bra IC_1 ; Done IC_Set_B move #Plane_O_B and $FFFF,14[a0] ; Show Set B move #Plane_T_B and $FFFF,22[a0] ; move #Plane_E_B and $FFFF,30[a0] ; move.l #Plane_O_A,cPlane_O.l ; Draw onto Set A move.l #Plane_T_A,cPlane_T.l ; move.l #Plane_E_A,cPlane_E.l ; move.l #Line_List_A,pcLine_List.l ; Undraw from A ; Move mouse IC_1 bsr tFire ; If fire, assert flag beq.s IC_2 ; No bset #0,Fire_Flag.l ; Pressed already ? bne.s IC_2a ; Yes bset #1,Fire_Flag.l ; Yes bra.s IC_2a ; Next IC_2 bclr #0,Fire_Flag.l ; Not pressed IC_2a move JOY0DAT[a6],d0 ; Show mouse counters move Mouse_Old.l,d1 ; Old counters move d0,Mouse_Old.l ; move Mouse_X.l,d2 ; Get current bsr.s Mouse_Calc ; Get displace move d2,Mouse_X.l ; Store lsr #4,d0 ; Get Y lsr #4,d0 ; lsr #4,d1 ; Get Y lsr #4,d1 ; move Mouse_Y.l,d2 ; Get current bsr.s Mouse_Calc ; Get displace move d2,Mouse_Y.l ; Store add.l #1,Frame_Count.l ; Inc count move.l #Test_Sprite,a0 ; Show it move #2,d0 ; Sprite 2 move Mouse_X.l,d1 ; X move Mouse_Y.l,d2 ; Y bsr Add_Sprite ; Show it movem.l [sp]+,d0-d3/a0 ; Restore rts ; Done Mouse_Calc sub.b d1,d0 ; Get difference move.b d0,d3 ; Get difference ext.w d3 ; Sign extend add d3,d2 ; Accumulate result rts ; Done Init_Mouse clr Mouse_X.l ; Set X clr Mouse_Y.l ; Y move JOY0DAT+Regs.l,Mouse_Old.l ; Get current mouse cnt rts ; Done Init_Kbd move.l #Key_States,a0 ; Clear key buffer move.l #$80-1,d0 ; No. of keys (assume more) IK_Lp clr.b [a0]+ ; Clear flag dbra d0,IK_Lp ; Loop rts ; Done Int_Kbd movem.l d0-d2/a0-a1,-[sp] ; Save regs move.l #$BFE001,a0 ; Point at CIA btst #3,$D00[a0] ; Key interrupt ? beq.s IK_NotKbd ; No, fail or.b #$40,$E00[a0] ; Make serial out (ACK) moveq #0,d0 ; Clear reg move.b $C00[a0],d0 ; Get char ror.b #1,d0 ; Shift into correct place not.b d0 ; Sent inverted move d0,d1 ; Get char and #$7F,d1 ; Get key code cmp.b #$68,d1 ; Valid key ? bhi IK_Status ; No, a status code, ignore it move.l #Key_States,a1 ; Point at key data btst #7,d0 ; Up or Down ? seq 0[a1,d1.w] ; 00 or FF IK_Status move #10,d0 ; Small delay dbra d0,* and.b #$BF,$E00[a0] ; Make serial out (ACK) IK_NotKbd movem.l [sp]+,d0-d2/a0-a1 ; Restore rts ; Done tLeft tst.b Key_States+$31.l ; Pressed = NZ bne.s tDone ; NZ btst #1,JOY1DAT+Regs.l ; Left ? tDone rts ; tRight tst.b Key_States+$32.l ; bne.s tDone ; btst #1,JOY1DAT+Regs+1.l ; Right ? rts ; tUp tst.b Key_States+$36.l ; bne.s tDone ; move JOY1DAT+Regs.l,d0 ; Up ? add #$100,d0 ; 01 or 10 and #$0200,d0 ; 10 or 11 rts ; tDown tst.b Key_States+$37.l ; bne.s tDone ; move JOY1DAT+Regs.l,d0 ; Up ? addq #1,d0 ; 01 or 10 and #$0002,d0 ; 10 or 11 rts ; tFire tst.b Key_States+$40.l ; bne.s tDone ; move.b $BFE001.l,d0 ; Get Joystick switch not d0 ; Wrong state and #$0080,d0 ; Bit 7 rts ; tMF tst.b Key_States+$4F.l ; rts tMN tst.b Key_States+$4E.l ; rts CLS move.l #Plane_Top_1,a0 ; Point at memory move.l #$EFFE,d0 ; Length move #$0000,d1 ; Pattern bsr.s Blit_Clear ; Fill memory bra Wait_Blit_Free ; Wait till done Blit_Clear move.l #Regs,a6 ; Point at regs bsr Wait_Blit_Free ; Make sure it's free move #%1 0000 1 1 0 0 1 0 0 0 0 0 0,DMACON[a6] ; DMA move d1,BLTCDAT[a6] ; Set fill word move.l a0,BLTDPTH[a6] ; Set up destination clr BLTDMOD[a6] ; Modulo to no-skip asr.l #1,d0 ; Convert length to words clr BLTCON1[a6] ; No special modes move #%0000 0 0 0 1 10101010,BLTCON0[a6] ; Shift,Use,D:=C moveq #$3F,d1 ; Extract non 64-words at a time part and d0,d1 ; beq.s BC_1 ; Nice boundary sub.l d1,d0 ; Even up blit with a small one first or #$40,d1 ; Make it one row X leftover words move d1,BLTSIZE[a6] ; Trigger the blit BC_1 move #$FFC0,d1 ; Now do upper bits and d0,d1 ; Get top 10 bits beq.s BC_2 ; Any to do ? sub.l d1,d0 ; Get remainder bsr Wait_Blit_Free ; Wait till free move d1,BLTSIZE[a6] ; Trigger next blit BC_2 swap d0 ; Check for any bits set in upper word beq.s BC_Done ; None, finished clr d1 ; Will do Blits 128 K at a time BC_Lp bsr Wait_Blit_Free ; Done last ? move d1,BLTSIZE[a6] ; Trigger a big blit subq #1,d0 ; DJNZ bne.s BC_Lp ; Do any more 128K blocks BC_Done rts ; Done, (blit still in progress) Wait_Blit_Free btst #14-8,DMACONR[a6] ; Still blitting ? (BBUSY) bne.s Wait_Blit_Free ; Loop rts ; Done Set_Up_VDU move.l #Regs,a6 ; Point at registers move #$03FF,DMACON[a6] ; Kill DMA bsr Init_Copper ; Set up list move #%1 00000 1 1 1 0 1 0 0 0 0 0,DMACON[a6] ; DMA rts ; Done Init_Copper move #%0 00000 0 0 1 0 0 0 0 0 0 0,DMACON[a6] ; copper DMA move.l #Copper_List,a0 ; Set up ptr to list move.l a0,COP1LCH[a6] ; Point at list move #DIWSTRT,[a0]+ ; DIWSTRT move #$3081,[a0]+ ; move #DIWSTOP,[a0]+ ; DIWSTOP move #$30C1,[a0]+ ; move #DDFSTRT,[a0]+ ; DDFSTRT move #$003C,[a0]+ ; move #DDFSTOP,[a0]+ ; DDFSTOP move #$00D0,[a0]+ ; move.l #Plane_Top_1,d0 ; Set up bit-planes bsr AC_Plane_1 ; move.l #Plane_Top_2,d0 ; bsr AC_Plane_2 ; bsr AC_Set_High_Res2 ; 2 bit planes, high res move.l #Top_Palette,a1 ; Point at palette moveq #0,d0 ; Palette entry moveq #4-1,d1 ; No. of entrys bsr AC_Palette ; Add colours bsr AC_Sprites ; Add the sprites move #Top_Sprite_Pal,a1; Set colours bsr AC_Sprite_Pal ; move #INTREQ,[a0]+ ; Request an interrupt move #%1 0000000000 1 0000,[a0]+ ; move.l #$6201FFFE,[a0]+; WAIT until line 49+(38) move #DDFSTRT,[a0]+ ; DDFSTRT move #$0038,[a0]+ ; move.l a0,Page_Ptrs.l ; Store ptr, we must swap these move.l #Plane_Back,d0 ; Set up bit-planes bsr AC_Plane_1 ; move.l #Plane_O_A,d0 ; bsr AC_Plane_2 ; move.l #Plane_T_A,d0 ; bsr AC_Plane_3 ; move.l #Plane_E_A,d0 ; bsr AC_Plane_4 ; bsr AC_Set_Low_Res4 ; 4 bit planes, low res move.l #Play_Palette,a1; Point at palette moveq #0,d0 ; Palette entry moveq #16-1,d1 ; No. of entrys bsr AC_Palette ; Add colours move #Play_Sprite_Pal,a1; Set colours bsr AC_Sprite_Pal ; bsr AC_Back_Pal ; Mountain colours move.l #$FC01FF00,[a0]+; WAIT until line 199 (+38) move #DDFSTRT,[a0]+ ; DDFSTRT move #$003C,[a0]+ ; move.l #Plane_Bott_1,d0 ; Set up bit-planes bsr AC_Plane_1 ; move.l #Plane_Bott_2,d0 ; bsr AC_Plane_2 ; bsr AC_Set_High_Res2 ; 2 bit planes, high res move.l #Bottom_Palette,a1 ; Point at palette moveq #0,d0 ; Palette entry moveq #4-1,d1 ; No. of entrys bsr AC_Palette ; Add colours move #Bott_Sprite_Pal,a1; Set colours bsr AC_Sprite_Pal ; ; Assert copper int. move.l #$FFFFFFFE,[a0]+; WAIT forever clr COPJMP1[a6] ; Use list 1 move #%1 00000 0 0 1 0 1 0 0 0 0 0,DMACON[a6] ; Sprites rts ; Done AC_Back_Pal move.l #$8101FFFE,d0 ; WAIT until start line move.l #Back_Pal,a1 ; Colours move #45-1,d1 ; No. of lines AC_BP_Lp move.l d0,[a0]+ ; Wait move #$0182,[a0]+ ; Pal. entry move [a1]+,[a0]+ ; Colour add.l #$1000000,d0 ; Next line dbra d1,AC_BP_Lp ; Loop rts ; Done AC_Palette add #$180,d0 ; Point at appropriate register ACP_Lp move d0,[a0]+ ; Select register move [a1]+,[a0]+ ; Read entry addq #2,d0 ; Step to next register dbra d1,ACP_Lp ; Loop rts ; Done AC_Plane_1 swap d0 ; High first ( nicer ) move #BPL1PTH,[a0]+ ; High word move d0,[a0]+ ; swap d0 ; Get low word move #BPL1PTL,[a0]+ ; Low word move d0,[a0]+ ; rts ; Done AC_Plane_2 swap d0 ; High first ( nicer ) move #BPL2PTH,[a0]+ ; High word move d0,[a0]+ ; swap d0 ; Get low word move #BPL2PTL,[a0]+ ; Low word move d0,[a0]+ ; rts ; Done AC_Plane_3 swap d0 ; High first ( nicer ) move #BPL3PTH,[a0]+ ; High word move d0,[a0]+ ; swap d0 ; Get low word move #BPL3PTL,[a0]+ ; Low word move d0,[a0]+ ; rts ; Done AC_Plane_4 swap d0 ; High first ( nicer ) move #BPL4PTH,[a0]+ ; High word move d0,[a0]+ ; swap d0 ; Get low word move #BPL4PTL,[a0]+ ; Low word move d0,[a0]+ ; rts ; Done AC_Sprites move #SPR0PTH,d0 ; First sprite register move #8-1,d1 ; Number of sprites move.l #Sprite_Data,d2 ; Point at first sprite ACS_Lp move d0,[a0]+ ; Write high address word swap d2 ; High word move d2,[a0]+ ; Copy word of ptr addq #2,d0 ; Next sprite addr move d0,[a0]+ ; Low address word swap d2 ; Low word move d2,[a0]+ ; Copy word of ptr addq #2,d0 ; Next sprite register add.l #Sprite_Length,d2 ; Next sprite addr dbra d1,ACS_Lp ; Loop rts ; Done AC_Sprite_Pal move #COLOUR17,[a0]+ ; 1 move [a1]+,[a0]+ ; move #COLOUR18,[a0]+ ; move [a1]+,[a0]+ ; move #COLOUR19,[a0]+ ; move [a1]+,[a0]+ ; move #COLOUR21,[a0]+ ; 2 move [a1]+,[a0]+ ; move #COLOUR22,[a0]+ ; move [a1]+,[a0]+ ; move #COLOUR23,[a0]+ ; move [a1]+,[a0]+ ; move #COLOUR25,[a0]+ ; 3 move [a1]+,[a0]+ ; move #COLOUR26,[a0]+ ; move [a1]+,[a0]+ ; move #COLOUR27,[a0]+ ; move [a1]+,[a0]+ ; move #COLOUR29,[a0]+ ; 4 move [a1]+,[a0]+ ; move #COLOUR30,[a0]+ ; move [a1]+,[a0]+ ; move #COLOUR31,[a0]+ ; move [a1]+,[a0]+ ; rts ; Done AC_Set_High_Res2 move #BPLCON0,[a0]+ ; BPLCON0 move #%1 010 0 0 1 0 0000 0 000,[a0]+ move #BPLCON1,[a0]+ ; BPLCON1 move #$0000,[a0]+ ; move #BPLCON2,[a0]+ ; BPLCON2 move #$0024,[a0]+ ; Sprites in front move #BPL1MOD,[a0]+ ; BPL1MOD move #$0000,[a0]+ ; move #BPL2MOD,[a0]+ ; BPL2MOD move #$0000,[a0]+ ; rts ; Done AC_Set_Low_Res4 move #BPLCON0,[a0]+ ; BPLCON0 move #%0 100 0 0 1 0 0000 0 000,[a0]+ move #BPLCON1,[a0]+ ; BPLCON1 move #$0000,[a0]+ ; move #BPLCON2,[a0]+ ; BPLCON2 move #$0024,[a0]+ ; Sprites in front move #BPL1MOD,[a0]+ ; BPL1MOD move #$0002,[a0]+ ; move #BPL2MOD,[a0]+ ; BPL2MOD move #$0002,[a0]+ ; rts ; Done Dummy_Sprite defl 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 Sight defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000001 00000000,%00000000 00000000 defw %00000001 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000001 00000000,%11100001 00001110 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000001 00000000,%00000001 00000000 defw %00000001 00000000,%00000001 00000000 defw %00000001 00000000,%00000001 00000000 defw %00000001 00000000,%00000001 00000000 defw %00000001 00000000,%00000001 00000000 Test_Sprite defw %00000001 00000000,%00000000 00000000 defw %00000001 00000000,%00000000 00000000 defw %00000001 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %11100001 00001110,%00000001 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 defw %00000001 00000000,%00000000 00000000 defw %00000001 00000000,%00000000 00000000 defw %00000001 00000000,%00000000 00000000 defw %00000000 00000000,%00000000 00000000 Top_Sprite_Pal defw $0666 ; 1 & 2 defw $0CCC defw $0FFF defw $0006 ; 3 & 4 defw $000C defw $000F defw $0060 ; 5 & 6 defw $00C0 defw $00F0 defw $0600 ; 7 & 8 defw $0C00 defw $0F00 Play_Sprite_Pal defw $0F00 ; 1 & 2 defw $00FF defw $0FFF defw $0066 ; 3 & 4 defw $00CC defw $00FF defw $0606 ; 5 & 6 defw $0C0C defw $0F0F defw $0666 ; 7 & 8 defw $0CCC defw $0FFF Bott_Sprite_Pal defw $0600 ; 1 & 2 defw $0C00 defw $0F00 defw $0606 ; 3 & 4 defw $0C0C defw $0F0F defw $0660 ; 5 & 6 defw $0CC0 defw $0FF0 defw $0666 ; 7 & 8 defw $0CCC defw $0FFF Top_Palette defw $0000 ; Colours for top window defw $000F ; defw $00F0 ; defw $0F00 ; Play_Palette defw $0000 ; Game palette defw $0FFF ; defw $000F ; defw $000F ; defw $00F0 ; defw $00F0 ; defw $00F0 ; defw $00F0 ; defw $0F00 ; defw $0F00 ; defw $0F00 ; defw $0F00 ; defw $0F00 ; defw $0F00 ; defw $0F00 ; defw $0F00 ; Bottom_Palette defw $0000 ; Colours for bottom defw $000F ; defw $00F0 ; defw $0F00 ; Sprite_Table defl Dummy_Sprite ; 0 defw 0,0 ; defl Dummy_Sprite ; 1 defw 16,0 ; defl Test_Sprite ; 2 defw 32,0 ; defl Dummy_Sprite ; 3 defw 48,0 ; defl Dummy_Sprite ; 4 defw 64,0 ; defl Dummy_Sprite ; 5 defw 80,0 ; defl Dummy_Sprite ; 6 defw 96,0 ; defl Dummy_Sprite ; 7 defw 112,0 ; ; Play area defl Sight ; 0 defw 161-8,118 ; defl Dummy_Sprite ; 1 defw 16,100 ; defl Dummy_Sprite ; 2 defw 32,100 ; defl Dummy_Sprite ; 3 defw 48,100 ; defl Dummy_Sprite ; 4 defw 64,100 ; defl Dummy_Sprite ; 5 defw 80,100 ; defl Dummy_Sprite ; 6 defw 96,100 ; defl Dummy_Sprite ; 7 defw 112,100 ; ; Bottom defl Dummy_Sprite ; 0 defw 0,200 ; defl Dummy_Sprite ; 1 defw 16,200 ; defl Dummy_Sprite ; 2 defw 32,200 ; defl Dummy_Sprite ; 3 defw 48,200 ; defl Dummy_Sprite ; 4 defw 64,200 ; defl Dummy_Sprite ; 5 defw 80,200 ; defl Dummy_Sprite ; 6 defw 96,200 ; defl Dummy_Sprite ; 7 defw 112,200 ; ; List of objects Init_OT defw $0000 ; X defw $3000 ; Z defl OD_Cube ; Display routine defl XS_100 ; Cross section table defw $D000 ; defw $F000 ; defl OD_Pyramid ; defl XS_1 ; defw $D000 ; defw $1000 ; defl OD_Cube1 ; defl XS_100 ; defw $D000 ; defw $3000 ; defl OD_Pyramid1 ; defl XS_78 ; defw $F000 ; defw $D000 ; defl OD_Cube2 ; defl 0 ; defw $F000 ; defw $F000 ; defl OD_Pyramid2 ; defl XS_43 ; defw $F000 ; defw $1000 ; defl OD_Cube ; defl XS_100 ; defw $F000 ; defw $3000 ; defl OD_Pyramid3 ; defl 0 ; defw $1000 ; defw $D000 ; defl OD_Cube1 ; defl XS_100 ; defw $1000 ; defw $F000 ; defl OD_Pyramid ; defl XS_1 ; defw $1000 ; defw $1000 ; defl OD_Cube2 ; defl 0 ; defw $1000 ; defw $3000 ; defl OD_Pyramid1 ; defl XS_78 ; defw $3000 ; defw $D000 ; defl OD_Cube1 ; defl XS_100 ; defw $3000 ; defw $F000 ; defl OD_Pyramid2 ; defl XS_43 ; defw $3000 ; defw $1000 ; defl OD_Cube2 ; defl 0 ; defw $3000 ; defw $3000 ; defl OD_Pyramid3 ; defl 0 ; defw $E000 ; defw $0000 ; defl OD_Cube1 ; defl XS_100 ; defw $D000 ; defw $D000 ; defl OD_Pyramid ; defl XS_1 ; defw $2000 ; defw $0000 ; defl OD_Cube2 ; defl 0 ; defw $0000 ; defw $E000 ; defl OD_Pyramid1 ; defl XS_78 ; defw $D600 ; defw $2800 ; defl OD_Cube ; defl XS_100 ; defw $0A00 ; defw $E500 ; defl OD_Pyramid2 ; defl XS_43 ; defw $A400 ; defw $B800 ; defl OD_Cube1 ; defl XS_100 ; defw $3800 ; defw $D600 ; defl OD_Pyramid3 ; defl 0 ; defw $E800 ; defw $D500 ; defl OD_Cube2 ; defl 0 ; defw $FE00 ; defw $3600 ; defl OD_Pyramid ; defl XS_1 ; defw $4800 ; defw $4500 ; defl OD_Cube ; defl XS_100 ; defw $4800 ; defw $7700 ; defl OD_Pyramid1 ; defl XS_78 ; defw $3400 ; defw $DF00 ; defl OD_Cube1 ; defl XS_100 ; defw $2F00 ; defw $7800 ; defl OD_Pyramid2 ; defl XS_43 ; defw $6800 ; defw $2800 ; defl OD_Cube2 ; defl 0 ; defw $5800 ; defw $3800 ; defl OD_Pyramid3 ; defl 0 ; defw $5800 ; defw $DF00 ; defl OD_Cube ; defl XS_100 ; defw $3A00 ; defw $4800 ; defl OD_Pyramid1 ; defl XS_78 ; defw $3800 ; defw $3800 ; defl OD_Cube1 ; defl XS_100 ; defw $6800 ; defw $3800 ; defl OD_Pyramid2 ; defl XS_43 ; defw $E800 ; defw $4800 ; defl OD_Cube2 ; defl 0 ; defw $7800 ; defw $2800 ; defl OD_Pyramid3 ; defl 0 ; defw $2800 ; defw $3800 ; defl OD_Cube1 ; defl XS_100 ; defw $5800 ; defw $E800 ; defl OD_Pyramid3 ; defl 0 ; Back_Pal defw $0EFE ; defw $0EFE ; defw $0DFD ; defw $0DFD ; defw $0CFC ; defw $0CFC ; defw $0CFC ; defw $0BFB ; defw $0AFA ; defw $09F9 ; defw $08F8 ; defw $07F7 ; defw $06F6 ; defw $05F5 ; defw $04E4 ; defw $03E3 ; defw $02E2 ; defw $01D1 ; defw $00D0 ; defw $00C0 ; defw $00C0 ; defw $00B0 ; defw $00B0 ; defw $00A0 ; defw $00A0 ; defw $0090 ; defw $0090 ; defw $0080 ; defw $0080 ; defw $0070 ; defw $0070 ; defw $0060 ; defw $0060 ; defw $0050 ; defw $0050 ; defw $0040 ; defw $0040 ; defw $0040 ; defw $0030 ; defw $0030 ; defw $0030 ; defw $0020 ; defw $0020 ; defw $0020 ; defw $222 ; org $4000 ; Data areas Mouse_X defs 2 ; Signed 16-bit Mouse_Y defs 2 ; Mouse_Old defs 2 ; H/W Mount_Angle defs 2 ; Current angle of mountains Frame_Count defs 4 ; No real use cFrame defs 1 ; Z or NZ Frame_Change defs 1 ; Z or NZ Fire_Flag defs 1 ; defs 1 ; Rand_Ptr defs 2 ; Page_Ptrs defs 4 ; Ptr to copper list cPlane_O defs 4 ; Base addresses of bit_planes cPlane_T defs 4 ; cPlane_E defs 4 ; Game_X defs 2 ; Signed 16-bit Game_Y defs 2 ; Cent_X defs 2 ; Object mid-point Cent_Z defs 2 ; Cent_Y defs 2 ; Disp_Angle defs 2 ; VR_Sine defs 2 ; VR_Cosine defs 2 ; xv1 defs 2 ; Screen X of vertex 1 xv2 defs 2 ; xv3 defs 2 ; xv4 defs 2 ; xv5 defs 2 ; xv6 defs 2 ; xv7 defs 2 ; xv8 defs 2 ; yv1 defs 2 ; Screen Y of vertex 1 yv2 defs 2 ; yv3 defs 2 ; yv4 defs 2 ; yv5 defs 2 ; yv6 defs 2 ; yv7 defs 2 ; yv8 defs 2 ; zv1 defs 2 ; Z of vertex 1 zv2 defs 2 ; zv3 defs 2 ; zv4 defs 2 ; zv5 defs 2 ; zv6 defs 2 ; zv7 defs 2 ; zv8 defs 2 ; Key_States defs $80 ; 00 or FF My_Object defs 2 ; Flags View_X defs 2 ; Viewpoint View_Y defs 2 ; View_Z defs 2 ; View_Angle defs 2 ; org My_Object+lObject ; Skip rest of data Object_Table defs lObject*nObjects ; Space for objects Enemy_Tank defs lObject ; Enemy Enemy_Shell defs lObject ; My_Shells defs lObject*nShells ; Fragments defs 3*nFrags*lObject ; Explosion bits defs lObject ; Dummy terminator pcLine_List defs 4 ; Ptr to draw line-list ; Z and X for every angle Square_Tab_100 defs 1024*2*2 ; Square table Square_Tab_6 defs 1024*2*2 ; ; Cross-section data, LHS and RHS for every angle XS_1 defs 1024*2*2 ; LHS and RHS for every angle XS_43 defs 1024*2*2 ; XS_78 defs 1024*2*2 ; XS_100 defs 1024*2*2 ; Line_List_A defs 2000 ; Buffer for lines on planes_A Line_List_B defs 2000 ; planes_B Copper_List defs 1000 ; Room for new copper list ; Equates for AMIGA registers BLTDDAT equ $00 DMACONR equ $02 VPOSR equ $04 VHPOSR equ $06 DSKDATR equ $08 JOY0DAT equ $0A JOY1DAT equ $0C CLXDAT equ $0E ADKCONR equ $10 POT0DAT equ $12 POT1DAT equ $14 POTGOR equ $16 SERDATR equ $18 DSKBYTR equ $1A INTENAR equ $1C INTREQR equ $1E DSKPTH equ $20 DSKPTL equ $22 DSKLEN equ $24 DSKDAT equ $26 REFPTR equ $28 VPOSW equ $2A VHPOSW equ $2C COPCON equ $2E SERDATA equ $30 SERPER equ $32 POTGO equ $34 JOYTEST equ $36 STREQU equ $38 STRVBL equ $3A STRHOR equ $3C STRLONG equ $3E ; Blitter BLTCON0 equ $40 BLTCON1 equ $42 BLTAFWM equ $44 BLTALWM equ $46 BLTCPTH equ $48 BLTCPTL equ $4A BLTBPTH equ $4C BLTBPTL equ $4E BLTAPTH equ $50 BLTAPTL equ $52 BLTDPTH equ $54 BLTDPTL equ $56 BLTSIZE equ $58 BLTCMOD equ $60 BLTBMOD equ $62 BLTAMOD equ $64 BLTDMOD equ $66 BLTCDAT equ $70 BLTBDAT equ $72 BLTADAT equ $74 DSKSYNC equ $7E ; Copper COP1LCH equ $80 COP1LCL equ $82 COP2LCH equ $84 COP2LCL equ $86 COPJMP1 equ $88 COPJMP2 equ $8A COPINS equ $8C DIWSTRT equ $8E DIWSTOP equ $90 DDFSTRT equ $92 DDFSTOP equ $94 DMACON equ $96 CLXCON equ $98 INTENA equ $9A INTREQ equ $9C ADKCON equ $9E AUD0LCH equ $A0 AUD0LCL equ $A2 AUD0LEN equ $A4 AUD0PER equ $A6 AUD0VOL equ $A8 AUD0DAT equ $AA AUD1LCH equ $B0 AUD1LCL equ $B2 AUD1LEN equ $B4 AUD1PER equ $B6 AUD1VOL equ $B8 AUD1DAT equ $BA AUD2LCH equ $C0 AUD2LCL equ $C2 AUD2LEN equ $C4 AUD2PER equ $C6 AUD2VOL equ $C8 AUD2DAT equ $CA AUD3LCH equ $D0 AUD3LCL equ $D2 AUD3LEN equ $D4 AUD3PER equ $D6 AUD3VOL equ $D8 AUD3DAT equ $DA ; Graphics BPL1PTH equ $E0 BPL1PTL equ $E2 BPL2PTH equ $E4 BPL2PTL equ $E6 BPL3PTH equ $E8 BPL3PTL equ $EA BPL4PTH equ $EC BPL4PTL equ $EE BPL5PTH equ $F0 BPL5PTL equ $F2 BPL6PTH equ $F4 BPL6PTL equ $F6 BPLCON0 equ $100 BPLCON1 equ $102 BPLCON2 equ $104 BPL1MOD equ $108 BPL2MOD equ $10A BPL1DAT equ $110 BPL2DAT equ $112 BPL3DAT equ $114 BPL4DAT equ $116 BPL5DAT equ $118 BPL6DAT equ $11A SPR0PTH equ $120 SPR0PTL equ $122 SPR1PTH equ $124 SPR1PTL equ $126 SPR2PTH equ $128 SPR2PTL equ $12A SPR3PTH equ $12C SPR3PTL equ $12E SPR4PTH equ $130 SPR4PTL equ $132 SPR5PTH equ $134 SPR5PTL equ $136 SPR6PTH equ $138 SPR6PTL equ $13A SPR7PTH equ $13C SPR7PTL equ $13E SPR0POS equ $140 SPR0CTL equ $142 SPR0DATA equ $144 SPR0DATB equ $146 SPR1POS equ $148 SPR1CTL equ $14A SPR1DATA equ $14C SPR1DATB equ $14E SPR2POS equ $150 SPR2CTL equ $152 SPR2DATA equ $154 SPR2DATB equ $156 SPR3POS equ $158 SPR3CTL equ $15A SPR3DATA equ $15C SPR3DATB equ $15E SPR4POS equ $160 SPR4CTL equ $162 SPR4DATA equ $164 SPR4DATB equ $166 SPR5POS equ $168 SPR5CTL equ $16A SPR5DATA equ $16C SPR5DATB equ $16E SPR6POS equ $170 SPR6CTL equ $172 SPR6DATA equ $174 SPR6DATB equ $176 SPR7POS equ $178 SPR7CTL equ $17A SPR7DATA equ $17C SPR7DATB equ $17E COLOUR00 equ $180 COLOUR01 equ $182 COLOUR02 equ $184 COLOUR03 equ $186 COLOUR04 equ $188 COLOUR05 equ $18A COLOUR06 equ $18C COLOUR07 equ $18E COLOUR08 equ $190 COLOUR09 equ $192 COLOUR10 equ $194 COLOUR11 equ $196 COLOUR12 equ $198 COLOUR13 equ $19A COLOUR14 equ $19C COLOUR15 equ $19E COLOUR16 equ $1A0 COLOUR17 equ $1A2 COLOUR18 equ $1A4 COLOUR19 equ $1A6 COLOUR20 equ $1A8 COLOUR21 equ $1AA COLOUR22 equ $1AC COLOUR23 equ $1AE COLOUR24 equ $1B0 COLOUR25 equ $1B2 COLOUR26 equ $1B4 COLOUR27 equ $1B6 COLOUR28 equ $1B8 COLOUR29 equ $1BA COLOUR30 equ $1BC COLOUR31 equ $1BE Regs equ $DFF000 ; System regs.