*ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ *³ ³ *³ File : display.asm ³ *³ Contents : DMA object handler ³ *³ Project : WWF Wrestlemania ³ *³ Programmer : ³ *³ ³ *³ COPYRIGHT (C) 1993 WILLIAMS ELECTRONICS GAMES, INC. ³ *³ ³ *ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ************************************************************************* .file "display.asm" .title "DMA object handler" .width 132 .option b,d,l,t .mnolist .include "gsp.equ" .include "sys.equ" .include "mproc.equ" .include "display.equ" .include "macros.h" .include "fontsimg.glo" .include "game.equ" .INCLUDE "PLYR.EQU" ****************************************************************************** * EXTERNAL REFERENCES .REF process_ptrs .ref special_screen .REF DUMRETS,WHICH_SCREEN .REF TOP_LEFT,BOT_RIGHT .def clear_objs .ref FRANIMQ .ref HALT .ref SYSCOPY .ref pal_getf .ref IRQSKYE ****************************************************************************** ;global variables .sect "OFIXED" OBJLST .long 0 ;*Active object list OFREE .long 0 ;*Free object block BAKLST .long 0 ;*Background list GND_Y .equ 116-40 GNDI_Y .equ 116 GNDI_W .equ 1277 GNDI_H .equ 138 GND_H .equ GNDI_H+40 GZBASE .equ 894 .bss present_pos,16 BSSX page_addr,32 .bss SCROLLX ,32 ;X scroll value .bss SCROLLY ,32 ;Y scroll value ;/ Must stay in order .bss WORLDTLX ,32 ;Left X screen coord (16:16) .bss WORLDTLY ,32 ;Top Y screen coord (16:16) .bss WORLDTL ,32 ;Top left world Y:X .bss SCRNTL ,32 ;TOP LEFT [Y,X] SCREEN (SCRN COORD.) .bss SCRNLR ,32 ;LOWER RIGHT [Y,X] SCREEN (SCRN COORD.) .bss dpage ,16 ;Display page; 0=Page0, -1=Page1 BSSX dtype ,16 ;Display type; 0=2D, 1=3D, -=Special BSSX dcode_p ,32 ;!0=*Special code (^ must = neg) .bss DMAQCUR ,32 ;Misc DMAQ position .bss OBJSTR,NOBJ*OBSIZ ;Object structure mem QSIZE .set (NOBJ+GNDI_H)*BQCELL QMSIZE .set NOBJ*BQCELL .bss dmaq0 ,QSIZE ;Main DMA queue BSSX DMAQ ,QMSIZE ;Misc DMA queue BSSX gndstat ,16 ;!0=Show ground BSSX gndpos_t ,16*GND_H BSSX gndx ,32 .bss DISPLAYON ,16 ;!0=Do display processing ; BSSX QDMAFLG ,16 ;!0=Misc DMAQ being updated BSSX _3dstat ,16 ;!0=Show polygons BSSX dma_foo ,32 .text ****************************************************************************** * NO CODE BEFORE DMA INT!!! (Cache aligned) * #***************************************************************************** * DMA interrupt * B12=*End of DMA regs * B13=DMAQ count-1 or Neg * B14=*Next DMAQ fetch SUBR dma_irq ;temp! ; move b14,@dma_foo,L move -*b14,-*b12,L ;[Y SCALE : X SCALE] move -*b14,-*b12,L ;[COLOR CONST : PAL REGISTER] move -*b14,-*b12,L ;[HEIGHT : WIDTH] move -*b14,-*b12,L ;[DEST Y : DEST X] move -*b14,-*b12,L ;[SOURCE ADDRESS] move -*b14,-*b12,L ;[CNTRL REG-DMA go! : OFFSET/CLIP] addi 0c0h,b12 ;DMAREGS (End of DMA) subk 1,b13 jrn #done ;Queue empty? RETI push b11 move @present_pos,b11 cmp b11,b13 jreq do_shadows pull b11 reti #done setf 1,0,0 ;Disable dma interrupt move b12,@INTENB+1 ;Clr X1E clr b13 ;For safety! subk 1,b13 ;-1 reti do_shadows pull b11 pushst dint callr PLACE_SHADOWS popst reti #***************************************************************************** * Load DMA Q from obj list (2D type) * A0=*Obj list * A4=*DMAQ next free spot * A13=Screen BR, A14=Screen TL * B2=Y offset for top of page : XPad offset * B4=World Y:X * B5=OFLAGS offset * B6=World center scrn X * 64K * B11=*DMACTRL dma_objlst2d ; movi [100h,100h],a5 ;A5=Y:X scale jruc #nxt .align #lp MOVE *A0(OFLAGS),A1 BTST B_NODISP,A1 JRNZ #nxt move *a0(OSCALE),a5,L move b5,a3 add a0,a3 move *a3+,a1 ;Get OFLAGS mmfm a3,a12,a11,a9,a8 move *a0(OYVAL),a10,L ;Get int Y move *a0(OXPOS),a2 ;X movx a2,a10 ;A10=Obj Y:X btst B_SCRNREL,a1 jrnz #noscl ;Screen relative XY? move b4,a6 ;A6=World TL Y:X subxy a6,a10 ;-world coord to get screen coord #noscl ;A8=Const:PAL ;A9=HEIGHT:WIDTH ;A10=Dest Y:X ;A11=*SAG ;A12=Offset:Ctrl btst B_BOBJ,a1 jrnz #is_bgnd_obj move *a0(ODOFF),a3,L ;display offset Y:X btst B_FLIPH,a12 jrz #no_x_flip0 movx a3,a2 neg a2 dec a2 ; -1 addxy a9,a2 ;- image width (gets added later) movx a2,a3 #no_x_flip0 ; btst B_FLIPV,a12 ; jrz #no_y_flip0 ; ; move a3,a2 ; srl 16,a2 ; neg a2 ; dec a2 ; -1 ; sll 16,a2 ; addxy a9,a2 ;- image height (gets added later) ; movy a2,a3 ; ;#no_y_flip0 subxy a3,a10 #is_bgnd_obj ;Check for flipping, clipping, adjust offset, sag ;Calc top,bot,left,right clips ;a2 = BR clip size clr a3 ;a3 = TL clip size move a10,a2 ;Dest Y:X addxy a9,a2 ; + HEIGHT:WIDTH = BR Y:X subxy a13,a2 ;A2=BR clip size JRYGE #clip_bot movy a3,a2 ;no bot clip if y neg #clip_bot JRXGE #clip_right movx a3,a2 ;no right clip if x neg #clip_right move a14,a7 ;screen TL subxy a10,a7 ; - DEST Y:X = TL clip size JRYLT #no_top_clip movy a7,a3 ;Top clip size btst 7,a12 ;zero compression on? jrnz #no_top_clip ;can't clip if it is movy a14,a10 ;Y start = window top edge #no_top_clip JRXLT #no_left_clip movx a7,a3 ;Left clip size btst 7,a12 jrnz #no_left_clip ;Zero compression on? movx a14,a10 ;X start = window left edge #no_left_clip move a2,b0 ;Save BR clip add a3,a2 ;TL clip + BR clip ;no need to use addxy as no signs + this sets Z for both jrz #noclip ;Zero clip? move a9,a6 ;Save HEIGHT:WIDTH subxy a2,a9 ;Get clipped size JRXLE #nxt ;Totally clipped? JRYLE #nxt btst 7,a12 jrz #nozc ;Zero compression off? move a6,a9 ;Restore v:h size jruc #noclip #nozc clr a1 movx a2,a1 ;x clip total move a1,a1 jrz #no_x_clip movx a9,a1 ;image width subk 8,a1 jrle #nxt ;<=8 wide? Skip so DMA doesn't lockup #no_x_clip movx a6,a9 ;Restore hsize movx a3,a1 ;A1=Left clip btst B_FLIPH,a12 jrz #no_x_flip subxy a1,a10 ;Original X move b0,a1 ;LClip=RClip zext a1,W ;clear Y portion subxy a1,a10 ;X-RClip #no_x_flip ; btst B_FLIPV,a12 ; jrz #no_y_flip ; ; move b0,a3 ;Bot clip ; ;#no_y_flip srl 16,a3 ;A3=Top or bot clip jrz #t0 zext a6,W ;clear Y portion mpyu a6,a3 ;T or B clip * width #t0 add a1,a3 ;Add x clip + y clip * width move a12,a1 sll 32-15,a1 ;Get bits 12-14 (PIXEL SIZE) srl 32-15+12,a1 jrnz #not8 movk 8,a1 #not8 mpys a1,a3 ;# of bits to skip add a3,a11 ;Add to SAG sll 16,a2 addxy a2,a12 ;Add clip offset to offset #noclip ;if image is flipped, dma plots from opposite end btst B_FLIPH,a12 jrz #300 movx a9,a1 ;image WIDTH subk 1,a1 zext a1 addxy a1,a10 ;+ WIDTH-1 #300 ; btst B_FLIPV,a12 ; jrz #400 ; move a9,a1 ;image HEIGHT ; srl 16,a1 ; subk 1,a1 ; sll 16,a1 ; addxy a1,a10 ;+ HEIGHT-1 ;#400 move b2,a1 addxy a1,a10 ;Add the page y offset : XPad rl 16,a12 ;Flip ctrl & offset mmtm a4,a5,a8,a9,a10,a11,a12 ;Save the dma regs addk 1,b13 ;+1 Q cnt jrgt #nxt ;DMA going? dint setf 1,0,0 ;>Enable DMA int movk 1,a1 move a1,@INTENB+1 ;X1E setf 16,1,0 move *b11,b0 jrn #dmaok ;DMA busy? move b13,b13 jrn #dmaok ;DMA int done? trap 1 ;Cause DMA int #dmaok eint #nxt move *a0,a0,L ;Get next link jrnz #lp ;More? rets .if 0 #***************************************************************************** * Load DMA Q from obj list (3D type) * A0=*Obj list * A4=*DMAQ next free spot * A13=Screen BR, A14=Screen TL * B2=Y offset for top of page : XPad offset * B4=World Y:X * B5=OFLAGS offset * B6=World center scrn X * 64K * B11=*DMACTRL dma_objlst3d movi [100h,100h],a5 ;A5=Y:X scale jruc #nxt .align #lp move b5,a3 add a0,a3 move *a3+,a1 ;Get OFLAGS mmfm a3,a12,a11,a9,a8 move *a0(OYVAL),a10,L ;Get int Y move *a0(OXPOS),a2 ;X movx a2,a10 ;A10=Obj Y:X btst B_SCRNREL,a1 jrnz #noscl ;Screen relative XY? move b4,a6 ;A6=World TL Y:X subxy a6,a10 ;-world coord to get screen coord #noscl ;A8=Const:PAL ;A9=HEIGHT:WIDTH ;A10=Dest Y:X ;A11=*SAG ;A12=Offset:Ctrl btst B_BOBJ,a1 jrnz #is_bgnd_obj move *a0(ODOFF),a3,L ;display offset Y:X btst B_FLIPH,a12 jrz #no_x_flip0 movx a3,a2 neg a2 dec a2 ; -1 addxy a9,a2 ;- image width (gets added later) movx a2,a3 #no_x_flip0 btst B_FLIPV,a12 jrz #no_y_flip0 move a3,a2 srl 16,a2 neg a2 dec a2 ; -1 sll 16,a2 addxy a9,a2 ;- image height (gets added later) movy a2,a3 #no_y_flip0 subxy a3,a10 #is_bgnd_obj ;Check for flipping, clipping, adjust offset, sag ;Calc top,bot,left,right clips ;a2 = BR clip size clr a3 ;a3 = TL clip size move a10,a2 ;Dest Y:X addxy a9,a2 ; + HEIGHT:WIDTH = BR Y:X subxy a13,a2 ;A2=BR clip size JRYGE #clip_bot movy a3,a2 ;no bot clip if y neg #clip_bot JRXGE #clip_right movx a3,a2 ;no right clip if x neg #clip_right move a14,a7 ;screen TL subxy a10,a7 ; - DEST Y:X = TL clip size JRYLT #no_top_clip movy a7,a3 ;Top clip size btst 7,a12 ;zero compression on? jrnz #no_top_clip ;can't clip if it is movy a14,a10 ;Y start = window top edge #no_top_clip JRXLT #no_left_clip movx a7,a3 ;Left clip size btst 7,a12 jrnz #no_left_clip ;Zero compression on? movx a14,a10 ;X start = window left edge #no_left_clip move a2,b0 ;Save BR clip add a3,a2 ;TL clip + BR clip ;no need to use addxy as no signs + this sets Z for both jrz #noclip ;Zero clip? move a9,a6 ;Save HEIGHT:WIDTH subxy a2,a9 ;Get clipped size JRXLE #nxt ;Totally clipped? JRYLE #nxt btst 7,a12 jrz #nozc ;Zero compression off? move a6,a9 ;Restore v:h size jruc #noclip #nozc clr a1 movx a2,a1 ;x clip total move a1,a1 jrz #no_x_clip movx a9,a1 ;image width subk 8,a1 jrle #nxt ;<=8 wide? Skip so DMA doesn't lockup #no_x_clip movx a6,a9 ;Restore hsize movx a3,a1 ;A1=Left clip btst B_FLIPH,a12 jrz #no_x_flip subxy a1,a10 ;Original X move b0,a1 ;LClip=RClip zext a1,W ;clear Y portion subxy a1,a10 ;X-RClip #no_x_flip btst B_FLIPV,a12 jrz #no_y_flip move b0,a3 ;Bot clip #no_y_flip srl 16,a3 ;A3=Top or bot clip jrz #t0 zext a6,W ;clear Y portion mpyu a6,a3 ;T or B clip * width #t0 add a1,a3 ;Add x clip + y clip * width move a12,a1 sll 32-15,a1 ;Get bits 12-14 (PIXEL SIZE) srl 32-15+12,a1 jrnz #not8 movk 8,a1 #not8 mpys a1,a3 ;# of bits to skip add a3,a11 ;Add to SAG sll 16,a2 addxy a2,a12 ;Add clip offset to offset #noclip ;if image is flipped, dma plots from opposite end btst B_FLIPH,a12 jrz #300 movx a9,a1 ;image WIDTH subk 1,a1 zext a1 addxy a1,a10 ;+ WIDTH-1 #300 btst B_FLIPV,a12 jrz #400 move a9,a1 ;image HEIGHT srl 16,a1 subk 1,a1 sll 16,a1 addxy a1,a10 ;+ HEIGHT-1 #400 move b2,a1 addxy a1,a10 ;Add the page y offset : XPad rl 16,a12 ;Flip ctrl & offset mmtm a4,a5,a8,a9,a10,a11,a12 ;Save the dma regs addk 1,b13 ;+1 Q cnt jrgt #nxt ;DMA going? dint setf 1,0,0 ;>Enable DMA int movk 1,a1 move a1,@INTENB+1 ;X1E setf 16,1,0 move *b11,b0 jrn #dmaok ;DMA busy? move b13,b13 jrn #dmaok ;DMA int done? trap 1 ;Cause DMA int #dmaok eint #nxt move *a0,a0,L ;Get next link jrnz #lp ;More? rets .endif #***************************************************************************** * Load DMA Q from obj list * A0=*Obj list * A4=*DMAQ next free spot * A13=Screen BR, A14=Screen TL * B2=Y offset for top of page : XPad offset * B4=World Y:X * B5=OFLAGS offset * B6=World center scrn X * 64K * B11=*DMACTRL dma_background movi [100h,100h],a5 ;A5=Y:X scale jruc #nxt .align #lp move b5,a3 add a0,a3 move *a3+,a1 ;Get OFLAGS mmfm a3,a12,a11,a9,a8 move *a0(OYVAL),a10,L ;Get int Y move *a0(OXPOS),a2 ;X movx a2,a10 ;A10=Obj Y:X btst B_SCRNREL,a1 jrnz #noscl ;Screen relative XY? move b4,a6 ;A6=World TL Y:X subxy a6,a10 ;-world coord to get screen coord #noscl ;A8=Const:PAL ;A9=HEIGHT:WIDTH ;A10=Dest Y:X ;A11=*SAG ;A12=Offset:Ctrl ;Check for flipping, clipping, adjust offset, sag ;Calc top,bot,left,right clips clr a3 ;A3=TL clip size move a10,a2 ;Dest Y:X addxy a9,a2 ; + HEIGHT:WIDTH = BR Y:X subxy a13,a2 ;A2=BR clip size JRYGE #clip_bot movy a3,a2 ;no bot clip if y neg #clip_bot JRXGE #clip_right movx a3,a2 ;no right clip if x neg #clip_right move a14,a7 ;screen TL subxy a10,a7 ; - DEST Y:X = TL clip size JRYLT #no_top_clip movy a7,a3 ;Top clip size btst 7,a12 ;zero compression on? jrnz #no_top_clip ;can't clip if it is movy a14,a10 ;Y start = window top edge #no_top_clip JRXLT #no_left_clip movx a7,a3 ;Left clip size btst 7,a12 jrnz #no_left_clip ;Zero compression on? movx a14,a10 ;X start = window left edge #no_left_clip move a2,b0 ;Save add a3,a2 ;TL clip+BR clip jrz #noclip ;Zero clip? move a9,a6 ;Save HEIGHT:WIDTH subxy a2,a9 ;Get clipped size JRXLE #nxt ;Totally clipped? JRYLE #nxt btst 7,a12 jrz #nozc ;Zero compression off? move a6,a9 ;Restore v:h size jruc #noclip #nozc clr a1 movx a2,a1 ;x clip total move a1,a1 jrz #no_x_clip movx a9,a1 ;image width subk 8,a1 jrle #nxt ;<=8 wide? Skip so DMA doesn't lockup #no_x_clip movx a6,a9 ;Restore hsize movx a3,a1 ;A1=Left clip btst B_FLIPH,a12 jrz #no_x_flip subxy a1,a10 ;Original X move b0,a1 ;LClip=RClip zext a1 subxy a1,a10 ;X-RClip #no_x_flip btst B_FLIPV,a12 jrz #no_y_flip move b0,a3 ;Bot clip #no_y_flip srl 16,a3 ;A3=Top or bot clip jrz #t0 zext a6 mpyu a6,a3 ;T or B clip * total hsize #t0 add a1,a3 ;Add left clip + tc*ths move a12,a1 sll 32-15,a1 ;Get bits 12-14 (PIXEL SIZE) srl 32-15+12,a1 jrnz #not8 movk 8,a1 #not8 mpys a1,a3 ;# of bits to skip add a3,a11 ;Add to SAG sll 16,a2 addxy a2,a12 ;Add clip offset to offset #noclip btst B_FLIPH,a12 ;if flipped, keep block jrz #300 ;in same position movx a9,a1 ;image WIDTH subk 1,a1 zext a1 addxy a1,a10 #300 btst B_FLIPV,a12 jrz #400 move a9,a1 ;image HEIGHT srl 16,a1 subk 1,a1 sll 16,a1 addxy a1,a10 #400 move b2,a1 addxy a1,a10 ;Add the page y offset : XPad rl 16,a12 ;Flip ctrl & offset mmtm a4,a5,a8,a9,a10,a11,a12 ;Save the dma regs addk 1,b13 ;+1 Q cnt jrgt #nxt ;DMA going? dint setf 1,0,0 ;>Enable DMA int movk 1,a1 move a1,@INTENB+1 ;X1E setf 16,1,0 move *b11,b0 jrn #dmaok ;DMA busy? move b13,b13 jrn #dmaok ;DMA int done? trap 1 ;Cause DMA int #dmaok eint #nxt move *a0,a0,L ;Get next link jrnz #lp ;More? rets #***************************************************************************** * Display object lists, called by DIRQ DISPLAY move @DISPLAYON,a0 jrz #novel movi DMACTRL,b11 ;B11=*DMACTRL ;this is for use on the pixel wash screen transition movi [PAGE1YO,SCRNXP],b2 movi [509,256],b3 ;dma window [ bottom : top ] move @special_screen,a1 jrnz #p1 movi SCRNXP,b2 ;B2=Page y offset : XPad offset movi [253,0],b3 ;dma window [ bottom : top ] move @dpage,a1 jrnz #p1 movi [PAGE1YO,SCRNXP],b2 movi [509,256],b3 ;dma window [ bottom : top ] #p1 move b2,@page_addr,L movi dmaq0+QSIZE,a4 ;A4=*DMAQ for new data (Top) clr b13 ;Kill DMA move b13,*b11 move b13,*b11 movi DMAREGS,b12 ;B12=*DMAREGS subk 1,b13 ;B13=Q count (-1) move a4,b14 ;B14=*DMAQ for next fetch (Top) ;------> SHAWN WAS SETTING DSZ (BIT6) ALSO ??????????????? movk BIT5,b0 ;DMAWIN (1 = BOTTOM:TOP) move b0,*b12(30h) ;DMACONF (Top/Bottom) move b3,*b12,L ;DMAWINDOW ; move @DISPLAYON,a0 ; jrz #doff ;Stop DMA of objects except for score? movi WORLDTLX,b0 ;Left X screen coord (16:16) move *b0+,b3,L ;left x [16:16] move *b0+,b4,L ;top y [16:16] srl 16,b3 ;int left x movx b3,b4 move b4,*b0,L ;top left world [Y:X] (WORLDTL) movi OFLAGS,b5 ;B5=Obj data offset move b4,b6 addi 200,b6 sll 16,b6 ;B6=World center scrn X * 64K move @SCRNLR,a13,L ;A13=Screen BR move @SCRNTL,a14,L ;A14=Screen TL move @TOP_LEFT,A0,L ADDXY A0,A14 MOVE @BOT_RIGHT,A0,L ADDXY A0,A13 movi BAKLST,a0 callr dma_background move b13,@present_pos movi OBJLST,a0 callr dma_objlst2d MOVE @WHICH_SCREEN,A0,L CALL A0 #doff move @DMAQCUR,a2,L movi DMAQ+QMSIZE,a1 cmp a1,a2 jrhs #noman ;Empty? move a1,@DMAQCUR,L ;Reset top of queue move b2,a5 #lp move -*a1,-*a4,L ;>Copy manual DMAQ to end of Q move -*a1,-*a4,L move -*a1,-*a4,L move -*a1,a0,L addxy a5,a0 ;+Y move a0,-*a4,L move -*a1,-*a4,L move -*a1,-*a4,L addk 1,b13 cmp a2,a1 jrhi #lp move *b11,b0 jrn #noman ;DMA busy? move b13,b13 jrn #noman ;DMA int done? setf 1,0,0 ;>Enable DMA int movk 1,a1 move a1,@INTENB+1 ;X1E setf 16,1,0 trap 1 ;Cause DMA int #noman move @HALT,a0 jrnz #novel ;Skip vel update? movi OBJLST,a0 callr vel_add #novel #x rets ;Null dma data nulldma .long >80000000,IROM,0,>00010001,0,>1000100 #***************************************************************************** * Velocity add loop * A0=*Obj list * Trashes A0-A7 .align #lp move a0,a1 addk OXVEL,a1 mmfm a1,a2,a3,a4,a5,a6,a7 ;A7=XV, A6=YV, A5=ZV, A4=X, A3=Y, A2=Z add a5,a2 ;Add ZVEL to Z move a2,-*a1,L add a6,a3 ;Add YVEL to Y (Uses hidden cycle!) move a3,-*a1,L add a7,a4 ;Add XVEL to X ^ move a4,-*a1,L vel_add move *a0,a0,L jrnz #lp ;!End? rets #***************************************************************************** * Manual DMA * A1=Constant color:Palette * A2=height:width * A3=Dest Y:X * A4=SAG * A5=Offset:Control * Trashes A0,A14 QDMAN ; movk 1,a0 ; move a0,@QDMAFLG ;Q being modified move @DMAQCUR,a14,L cmpi DMAQ,a14 jrls #x ;Q full? movi [100h,100h],a0 ;No scale rl 16,a5 ;Flip DMA & offset mmtm a14,a0,a1,a2,a3,a4,a5 rl 16,a5 ;Flip DMA & offset move a14,@DMAQCUR,L #x ; clr a0 ; move a0,@QDMAFLG rets .if 0 #******************************* * Turn on the 2d with scaling display mode * Trashes scratch SUBRP display_2dsclmodeon movi #drawcode,a0 move a0,@dcode_p,L movi -1,a0 move a0,@dtype rets #drawcode movi BAKLST,a0 callr dma_objlst2d movi OBJLST,a0 ;;;; jruc dma_objlst2dscl #******************************* * Turn on the 2d, with scaling and stars, display mode * Trashes scratch .asg SCRATCH+8*128*1024,STARBUF NSTARS .equ 900 STARSIZE .equ 32*6+16 SUBRP display_2dsclstarmodeon movi NSTARS,b0 ;>Init star array movi STARBUF,a1 movi -1,a0 #silp move a0,*a1,L ;X addi STARSIZE,a1 dsj b0,#silp movi #drawcode,a0 move a0,@dcode_p,L movi -1,a0 move a0,@dtype rets ******************************** * B2=Y offset for top of page : XPad offset * Trashes A0-A3,A5-A12,B0-B3 CFRAC .equ 2 .bss starcolor ,16 #drawcode PUSH a13,a14 PUSH b4 movk 3,a0 callr rnd move @starcolor,a6 add a0,a6 move a6,@starcolor sll 32-3-6,a6 srl 32-3,a6 ;Remove fraction sll 5+CFRAC,a6 movi NSTARS,a5 ;>Find a free star movi STARBUF,a2 movk 3,a3 #flp move *a2,a0,L ;X jrn #found addi STARSIZE,a2 #fnxt dsj a5,#flp jruc #nofree #found movi [200,0],a0 ;>Create star move a0,*a2+,L ;X movi [252,0],a0 move a0,*a2+,L ;Y clr a0 move a0,*a2+,L ;XV movi ->3e000,a0 move a0,*a2+,L ;YV movi >7ff,a0 callr rnd subi >3ff,a0 move a0,*a2+,L ;XA movi >3ff,a0 callr rnd addi >7ff,a0 move a0,*a2+,L ;YA move a6,*a2+ ;Color type dsj a3,#fnxt #nofree movi #star_p,a0 ;>Update stars calla pal_getf move a0,@DMACMAP movi 512*8,b3 lmo b3,b0 move b0,@CONVDP clr b4 movi 1<<(32-5-CFRAC),a11 movi [400,0],a13 ;A13=X max+1 movi [254,0],a14 ;A14=Y max+1 move b2,a12 movi NSTARS,b0 movi STARBUF,a8 #lp ; move *a8+,a2,L ;X ; move *a8+,a3,L ;Y ; move *a8+,a5,L ;XV ; move *a8+,a6,L ;YV ; move *a8+,a9,L ;XA ; move *a8+,a10,L ;YA mmfm a8,a2,a3,a5,a6,a9,a10 ;YA,XA,YV,XV,Y,X move *a8+,a1 ;Color move a10,a10 jrn #nxt add a2,a5 add a3,a6 add a5,a9 add a6,a10 cmp a13,a10 jrhs #offscr ;X off screen? cmp a14,a9 jrlo #plot ;Y on screen? #offscr movi -1,a0 move a0,*a8(-STARSIZE),L jruc #nxt #plot move a10,*a8(-STARSIZE),L move a9,*a8(-STARSIZE+32),L move a6,*a8(-STARSIZE+32*2),L move a5,*a8(-STARSIZE+32*3),L move a1,a0 sll 32-5-CFRAC,a0 add a11,a0 jrc #maxc ;Overflow? ; cmpi 32*4,a1 ; jrge #offscr addk 1,a1 move a1,*a8(-16) #maxc srl CFRAC,a1 ;Remove fraction srl 16,a10 movx a10,a9 addxy a12,a9 pixt a1,*a9.XY #nxt dsj b0,#lp PULL b4 PULL a13,a14 movi BAKLST,a0 callr dma_objlst2d movi OBJLST,a0 ;;; jruc dma_objlst2dscl #star_p .word 256 COLORW 01,01,01, 02,02,02, 03,03,03, 04,04,04 ;Grey COLORW 05,05,05, 06,06,06, 07,07,07, 08,08,08 COLORW 09,09,09, 10,10,10, 11,11,11, 12,12,12 COLORW 13,13,13, 14,14,14, 15,15,15, 16,16,16 COLORW 17,17,17, 18,18,18, 19,19,19, 20,20,20 COLORW 21,21,21, 22,22,22, 23,23,23, 24,24,24 COLORW 25,25,25, 26,26,26, 27,27,27, 28,28,28 COLORW 29,29,29, 30,30,30, 31,31,31, 31,31,31 COLORW 01,01,00, 02,02,00, 03,03,00, 04,04,00 ;Yellow COLORW 05,05,00, 06,06,00, 07,07,00, 08,08,00 COLORW 09,09,00, 10,10,00, 11,11,00, 12,12,00 COLORW 13,13,00, 14,14,00, 15,15,00, 16,16,00 COLORW 17,17,00, 18,18,00, 19,19,00, 20,20,00 COLORW 21,21,00, 22,22,00, 23,23,00, 24,24,00 COLORW 25,25,00, 26,26,00, 27,27,00, 28,28,00 COLORW 29,29,00, 30,30,00, 31,31,00, 31,31,00 COLORW 01,00,00, 02,00,00, 03,00,00, 04,00,00 ;Red COLORW 05,00,00, 06,00,00, 07,00,00, 08,00,00 COLORW 09,00,00, 10,00,00, 11,00,00, 12,00,00 COLORW 13,00,00, 14,00,00, 15,00,00, 16,00,00 COLORW 17,00,00, 18,00,00, 19,00,00, 20,00,00 COLORW 21,00,00, 22,00,00, 23,00,00, 24,00,00 COLORW 25,00,00, 26,00,00, 27,00,00, 28,00,00 COLORW 29,00,00, 30,00,00, 31,00,00, 31,00,00 COLORW 00,01,00, 00,02,00, 00,03,00, 00,04,00 ;Green COLORW 00,05,00, 00,06,00, 00,07,00, 00,08,00 COLORW 00,09,00, 00,10,00, 00,11,00, 00,12,00 COLORW 00,13,00, 00,14,00, 00,15,00, 00,16,00 COLORW 00,17,00, 00,18,00, 00,19,00, 00,20,00 COLORW 00,21,00, 00,22,00, 00,23,00, 00,24,00 COLORW 00,25,00, 00,26,00, 00,27,00, 00,28,00 COLORW 00,29,00, 00,30,00, 00,31,00, 00,31,00 COLORW 00,00,01, 00,00,02, 00,00,03, 00,00,04 ;Blue COLORW 00,00,05, 00,00,06, 00,00,07, 00,00,08 COLORW 00,00,09, 00,00,10, 00,00,11, 00,00,12 COLORW 00,00,13, 00,00,14, 00,00,15, 00,00,16 COLORW 00,00,17, 00,00,18, 00,00,19, 00,00,20 COLORW 00,00,21, 00,00,22, 00,00,23, 00,00,24 COLORW 00,00,25, 00,00,26, 00,00,27, 00,00,28 COLORW 00,00,29, 00,00,30, 00,00,31, 00,00,31 COLORW 00,00,01, 00,00,02, 00,00,03, 00,00,04 ;Lt blue COLORW 00,00,05, 00,00,06, 00,00,07, 00,00,08 COLORW 00,00,09, 01,01,10, 02,02,11, 03,03,12 COLORW 04,04,13, 05,05,14, 06,06,15, 07,07,16 COLORW 08,08,17, 09,09,18, 10,10,19, 11,11,20 COLORW 12,12,21, 14,14,22, 16,16,23, 18,18,24 COLORW 20,20,25, 22,22,26, 24,24,27, 26,26,28 COLORW 28,28,29, 30,30,30, 30,30,31, 31,31,31 COLORW 01,00,01, 02,00,02, 03,00,03, 04,00,04 ;Purple COLORW 05,00,05, 06,00,06, 07,00,07, 08,00,08 COLORW 09,00,09, 10,00,10, 11,00,11, 12,00,12 COLORW 13,00,13, 14,00,14, 15,00,15, 16,00,16 COLORW 17,00,17, 18,00,18, 19,00,19, 20,00,20 COLORW 21,00,21, 22,00,22, 23,00,23, 24,00,24 COLORW 25,00,25, 26,00,26, 27,00,27, 28,00,28 COLORW 29,00,29, 30,00,30, 31,00,31, 31,00,31 COLORW 00,01,01, 00,02,02, 00,03,03, 00,04,04 ;Cyan COLORW 00,05,05, 00,06,06, 00,07,07, 00,08,08 COLORW 00,09,09, 00,10,10, 00,11,11, 00,12,12 COLORW 00,13,13, 00,14,14, 00,15,15, 00,16,16 COLORW 00,17,17, 00,18,18, 00,19,19, 00,20,20 COLORW 00,21,21, 00,22,22, 00,23,23, 00,24,24 COLORW 00,25,25, 00,26,26, 00,27,27, 00,28,28 COLORW 00,29,29, 00,30,30, 00,31,31, 00,31,31 .endif ******************************** * Get random # with mask * A0=Mask * >A0=Rnd # (Pass CC) * Trashes scratch SUBRP rnd move @RAND,a1,L rl a1,a1 move @HCOUNT,a14 rl a14,a1 add sp,a1 move a1,@RAND,L and a1,a0 rets ******************************** * Zeros velocities for all objects on OBJLST STOPOBJS clr a0 movi OBJLST,a1 jruc so20 so10 move a0,*a1(OXVEL),L move a0,*a1(OYVEL),L move a0,*a1(OZVEL),L so20 move *a1,a1,L jrnz so10 rets ******************************** * Sort object list in Z:Y priority * Trashes A0-A7 .align SUBR obj_yzsort movi OBJLST,a0 movk 1,a1 ;Lowest Z sll 31,a1 ;Make >80000000 jruc yzlp yz0 move *a2(OZPOS),a6 ;Get Z move *a2(OYPOS),a7 ;Get Y cmp a1,a6 jrgt priok ;Next Z > Current Z? jrlt priswap cmp a5,a7 jrge priok ;Next Y > Current Y? priswap dint ;>Make current after next move a2,*a4,L ;Point last to next move *a2,*a0,L ;Point current to block after next move a0,*a2,L ;Point next to current eint move a2,a4 jruc yzlp ;Continue sort of current obj priok move a0,a4 ;A4=*Last obj move a2,a0 ;A0=*Current obj move a6,a1 ;A1=Current Z move a7,a5 ;A5=Current Y yzlp move *a0,a2,L ;A2=*Next obj jrnz yz0 rets ************************************************************************** * TEST IF OBJECT ON SCREEN * A8=OBJECT * RETURNS Z IF ON SCREEN *ENTER HERE AND PROVIDE YOUR OWN SCREEN BOUNDRIES SCRTSTG mmtm sp,a1,a2,a3 jruc scrtst1 *NORMAL SCREEN BOUNDRIES SCRTST mmtm sp,a1,a2,a3 move @SCRNTL,a2,L ;Get screen top left move @SCRNLR,a3,L ;Get screen lower rgt scrtst1 move *a8(OYPOS),a0 move *a8(OXPOS),a1 sll 16,a0 movx a1,a0 ;get top left of object move @WORLDTL,a1,L subxy a1,a0 ;subtract out world base move *a8(OSIZE),a1,L addxy a0,a1 ;get lower rt of object cmpxy a3,a0 ;is it lower than lower rt? JRYGE scrtf_d ;lower JRXGE scrtf_r ;to the right cmpxy a2,a1 JRYLE scrtf_u ;above... JRXLE scrtf_l ;to the left.. mmfm sp,a1,a2,a3 clr a0 ;On screen Z rets scrtf_l movk 1,a0 ;Pass NZ mmfm sp,a1,a2,a3 rets scrtf_r movk 2,a0 mmfm sp,a1,a2,a3 rets scrtf_u movk 3,a0 mmfm sp,a1,a2,a3 rets scrtf_d movk 4,a0 mmfm sp,a1,a2,a3 rets #******************************* * Initialize display system * Trashes scratch SUBR SPECIAL_DISPLAY_INIT pushst dint movi DIE+X2E,a0 move a0,@INTENB ;Display int on, DMA int off clr a0 move a0,@DMACTRL ;Init DMA move a0,@DMACTRL move a0,@CMAPSEL ;Clear color map select move a0,@DMATEST move a0,@DMACONF movi [511,0],a1 ;RIGHT:LEFT (full width to fix glitch) move a1,@DMAWINDOW,L movi 30h,a1 ;<--------------------check this!!!!!!!!!!! move a1,@DMACONF ;BOTTOM:TOP movi [509,0],a1 move a1,@DMAWINDOW,L movi [100h,100h],a1 move a1,@DMASCALEX,L movi -1,b13 ;DMAQ cnt MOVI DUMRETS,A1 MOVE A1,@WHICH_SCREEN,L CLR A0 MOVE A0,@TOP_LEFT,L MOVE A0,@BOT_RIGHT,L move a0,@special_screen callr clear_objs popst rets #******************************* * Initialize display system * Trashes scratch SUBR display_init pushst dint movi DIE+X2E,a0 move a0,@INTENB ;Display int on, DMA int off clr a0 move a0,@DMACTRL ;Init DMA move a0,@DMACTRL move a0,@CMAPSEL ;Clear color map select move a0,@DMATEST move a0,@DMACONF movi [511,0],a1 ;RIGHT:LEFT (full width to fix glitch) move a1,@DMAWINDOW,L movi 30h,a1 ;<--------------------check this!!!!!!!!!!! move a1,@DMACONF ;BOTTOM:TOP movi [509,0],a1 move a1,@DMAWINDOW,L movi [100h,100h],a1 move a1,@DMASCALEX,L movi -1,b13 ;DMAQ cnt clr a1 ;>Clr video mem movi (SCRNE-512*8*2)/64,b0 #clp move a0,*a1+,L move a0,*a1+,L dsj b0,#clp ;>Set autoerase lines movi 510*512*8,a1 ;Store to last 2 lines of bitmap movi ERASECOL,a14 ;Color pair movi 512*8*2/16,b0 #lp move a14,*a1+ dsj b0,#lp MOVI DUMRETS,A1 MOVE A1,@WHICH_SCREEN,L CLR A0 MOVE A0,@TOP_LEFT,L MOVE A0,@BOT_RIGHT,L move a0,@special_screen callr clear_objs popst rets clear_objs CLR A0 move a0,@WORLDTLX,L move a0,@WORLDTLY,L move a0,@WORLDTL,L move a0,@SCROLLX,L move a0,@SCROLLY,L move a0,@BAKLST,L ;Null backgnd object list move a0,@OBJLST,L ;Null object list move a0,@dcode_p,L movi SCRNST,a1 ;Screen top left [Y,X] move a1,@SCRNTL,L movi SCRNEND,a1 ;Screen lower right [Y,X] move a1,@SCRNLR,L movi DMAQ+QMSIZE,a1 move a1,@DMAQCUR,L ;Init misc DMA queue movi OBJSTR,a1,L ;>Init free list move a1,@OFREE,L movi NOBJ,b0 ;# of object blocks #olp move a1,a14 addi OBSIZ,a1 move a1,*a14,L ;link em up dsj b0,#olp move a0,*a14,L ;Null end rets ******************************** * Get a free object block * Trashes scratch * >A0=*Object or 0 (Z) GETOBJ move @OFREE,a0,L jrz nonelft ;None free? move *a0,a1,L move a1,@OFREE,L ;Unlink clr a1 move a1,*a0(OPLINK),L move a1,*a0(ODATA_p),L getox move a0,a0 rets nonelft .if DEBUG LOCKUP eint .else CALLERR 3,0 .endif jruc getox ******************************** * Add object to free list * Can trash A0-A1 (currently doesn't) FREEOBJ move @OFREE,*a0+,L subk 32,a0 move a0,@OFREE,L rets #******************************* * Unlink an object from object list * A0=*Obj * Trashes scratch ; SUBR obj_unlink ; ; movi OBJLST,a14 ; ;#lp move a14,a1 ;A1=*Prev ; move *a14,a14,L ;A14=*Next ; jrz #err ; cmp a14,a0 ; jrne #lp ; ; move *a0,*a1,L ;Unlink from obj list ; rets ; ;#err ; .if DEBUG ; LOCKUP ; eint ; .endif ; rets ******************************** * Insert an object block into an object list * List is sorted by increasing z and increasing y within constant z #******************************* * Insert background object * A0=*Obj * Trashes scratch INSBOBJ movi BAKLST,a14 jruc #strt ******************************** * Insert foreground object * A0=*Obj * Trashes scratch INSOBJ movi OBJLST,a14 #strt PUSH a2,a3,a4 move *a0(OZPOS),a1 move *a0(OYPOS),a4 #lp move a14,a2 ;A2=*prev move *a14,a14,L ;A14=*next jrz #x move *a14(OZPOS),a3 cmp a3,a1 jrgt #lp jrlt #x move *a14(OYPOS),a3 ;Test y position cmp a3,a4 jrgt #lp #x move a14,*a0,L ;Put *next in new block move a0,*a2,L ;Put *new in prev block PULL a2,a3,a4 rets #******************************* * Delete background object * A0=*Obj DELBOBJ movi BAKLST,a14 jruc #lp ******************************** * Delete foreground object * A8=*Obj DELOBJA8 move a8,a0 ******************************** * Delete foreground object * A0=*Obj * Trashes scratch DELOBJ movi OBJLST,a14 #lp move a14,a1 ;A1=*Prev move *a14,a14,L ;A14=*Next jrz delerr cmp a14,a0 jrne #lp move *a0,*a1,L ;Unlink from obj list clr a1 move a1,*a0(OXPOS) ;Indicates not in use for collisions move @OFREE,*a0+,L ;Add to free list subk 32,a0 move a0,@OFREE,L #x rets delerr .if DEBUG LOCKUP eint .else CALLERR 1,0 .endif jruc #x ******************************** * FRANIM list an object, delete it and DIE * A8=*Obj * A9=*FRANIM list FRQDELDIE JSRP FRANIMQ #******************************* * Delete foreground object and DIE * A8=*Obj DELOBJDIE movi OBJLST,a14 #lp move a14,a1 ;A1=*Prev move *a14,a14,L ;A14=*Next jrz doderr cmp a14,a8 jrne #lp move *a8,*a1,L ;Unlink from obj list clr a1 move a1,*a8(OXPOS) ;Indicates not in use for collisions move @OFREE,*a8+,L ;Add to free list subk 32,a8 move a8,@OFREE,L #x jauc SUCIDE doderr .if DEBUG LOCKUP eint .else CALLERR 1,0 .endif jruc #x #******************************* * Delete one class from the obj list * A0=OID * Trashes scratch obj_del1c clr a1 ******************************** * Delete a class from the obj list * A0=OID * A1=!Mask (Bits to remove) * Trashes scratch obj_delc move a2,b0 move a3,b1 movi OBJLST,a14 sext a0 andn a1,a0 ;Form match #lp move a14,a3 ;A3=*Prev move *a14,a14,L ;A14=*Next jrz #x #cmp move *a14(OID),a2 andn a1,a2 ;Mask cmp a0,a2 jrne #lp move *a14,*a3,L ;Unlink from obj list move @OFREE,*a14+,L ;Add to free list subk 32,a14 move a14,@OFREE,L move *a3,a14,L jrnz #cmp #x move b1,a3 move b0,a2 rets #******************************* * Check objlst for an object with a certain OID * A0=OID * A1=!Mask (Bits to remove) * >A0=*Obj or 0 (Z) * Trashes scratch EXISTOBJ move a2,b0 movi OBJLST,a14 sext a0 andn a1,a0 ;Form match #lp move *a14,a14,L jrz #x move *a14(OID),a2 andn a1,a2 ;Mask cmp a0,a2 jrne #lp #x move b0,a2 move a14,a0 rets #******************************* * Check if object on free list * A0=*Obj * >A0=*Obj or 0 (Z) * Trashes scratch ;ISFREE ; movi OFREE,a1 ; jruc #lp ******************************** * Check if object on OBJLST * A0=*Obj * >A0=*Obj or 0 (Z) * Trashes scratch ISOBJ movi OBJLST,a1 #lp move *a1,a1,L jrz #x ;End? cmp a0,a1 jrne #lp ;No match? move a0,a0 ;Clr Z rets #x clr a0 ;Set Z rets ******************************** * Add world coordinates to an object * A0=*Obj * Trashes scratch, !A0 SUBR obj_addworldxy move @WORLDTLX,a14,L move *a0(OXVAL),a1,L add a14,a1 move a1,*a0(OXVAL),L move @WORLDTLY,a14,L move *a0(OYVAL),a1,L add a14,a1 move a1,*a0(OYVAL),L rets ************************************************************************** * * * ADJNEWTL - ADJUST AN OBJECT TO A NEW SET OF X,Y WORLD COORDINATES * * BEFORE THEY ARE STORED(TAKE EFFECT). * * NOTE: CURRENT OBJECT COORDS. MUST BE ABSOLUTE WORLD. * * A0 = PTR TO OBJECT * * A4 = NEW WTLX, 32 BITS * * A5 = NEW WTLY, 32 BITS * ADJNEWTL PUSH a1,a2 CALLR GSCRNREL ;SCREEN RELATIVE PLEASE ADD A4,A1 ADD A5,A2 ;ADJUST MOVE A1,*A0(OXVAL),L MOVE A2,*A0(OYVAL),L ;STORE PULL a1,a2 RETS ************************************************************************** * * * GSCRNREL - GET THE SCREEN RELATIVE X,Y COORDINATES OF AN OBJECT * * IT IS ASSUMED THAT THE CURRENT X,Y COORDINATES ARE * * WORLD ABSOLUTE. * * A0 = PTR TO THE OBJECT BLOCK * * RETURNS * * A1 = X SCREEN RELATIVE, 32 BITS * * A2 = Y SCREEN RELATIVE, 32 BITS * GSCRNREL PUSH a5 MOVE @WORLDTLX,A5,L MOVE *A0(OXVAL),A1,L SUB A5,A1 MOVE @WORLDTLY,A5,L MOVE *A0(OYVAL),A2,L SUB A5,A2 PULL a5 RETS ************************************************************************** * * * SCRNRELV - MAKE THE X & Y VELOCITIES OF AN OBJECT RELATIVE TO THE * * SCREEN. IN OTHER WORDS, ADJUST THEM SO THAT THE CURRENT * * SCROLL RATE DOESN'T AFFECT THEM. * * A0 = PTR TO OBJECT * * * ************************************************************************** SCRNRELV PUSH a1,a5 MOVE @SCROLLX,A5,L MOVE *A0(OXVEL),A1,L ADD A5,A1 MOVE A1,*A0(OXVEL),L MOVE @SCROLLY,A5,L MOVE *A0(OYVEL),A1,L ADD A5,A1 MOVE A1,*A0(OYVEL),L PULL a1,a5 RETS ******************************** * Adjust current object image with respect to it's anipt and flip flags * A0=*Object * A2=New YVAL * A3=New XVAL * A4=New FLAGS (Only DMA bits) * Trashes A1,A14,B0-B1 * >A2=Adjusted YVAL * >A3=Adjusted XVAL GANISAG PUSH a4,a6,a7 PUSH a2 move *a0(OIMG),a1,L move *a1,a2,L ;ISIZE move a2,*a0(OSIZE),L callr GANIOF PULL a2 sub a6,a3 sub a7,a2 ;adjust upper left corner move a3,*a0(OXVAL),L move a2,*a0(OYVAL),L move *a1(ICTRL),a1 ;Get DMA flags andi >803f,a4 ;Kill mode bits or a1,a4 move a4,*a0(OCTRL),L ;&OFFSET PULL a4,a6,a7 rets ****************************************************************************** * Begin an object * A0=XVAL, A1=YVAL, A2=*IMG, A3=ZPOS, A4=FLAGS, A5=OID, A6=XVEL, A7=YVEL * >A8=*Obj * Trashes scratch BEGINOBJW move @WORLDTLX,a8,L ;Adjust for world coord add a8,a0 btst B_3D,a4 jrnz BEGINOBJ ;No Y add for 3D? move @WORLDTLY,a8,L add a8,a1 BEGINOBJ PUSH a2,a3,a4,a6,a7,a9,a10 move a0,a9 ;X move a1,a10 ;Y move *a2(ICMAP),a0,L ;Get *palette .if DEBUG jrnn bopalerr ;No palette? .endif calla pal_getf bo20 move @OFREE,a8,L ;Pointer to next available obj block jrz begobjerr ;No objs? move *a8,a1,L move a1,@OFREE,L ;Adjust pointer to free list move a0,*a8(OPAL),L ;Set palette & constant clr a0 move a0,*a8(ODATA_p),L ;Clr stuff move a0,*a8(OXANI),L move a0,*a8(OZVEL),L move a0,*a8(OMISC) move a0,*a8(ODOFF),L movi 01000100H,a0 move a0,*a8(OSCALE),L move a3,*a8(OZPOS) move a5,*a8(OID) move a6,*a8(OXVEL),L move a7,*a8(OYVEL),L move a2,a1 ;*Img move *a1,a2,L ;ISIZE callr GANIOF ;Adjust animation offset ;here!!!!!!!!!!!!!! move *a1(IANIOFFX),*a8(ODXOFF) ;display x offset move *a1(IANIOFFY),*a8(ODYOFF) ;display y offset move *a1(ISAG),a3,L ;Get top left sag ;;; sub a6,a9 ;- x anioff ;;; sub a7,a10 ;- y anioff move a9,*a8(OXVAL),L move a10,*a8(OYVAL),L move a1,*a8(OIMG),L move a2,*a8(OSIZE),L move a3,*a8(OSAG),L move a4,*a8(OFLAGS) move *a1(ICTRL),a0 ;Get DMA flags andi >803f,a4 ;Kill mode bits or a0,a4 move a4,*a8(OCTRL),L ;&OFSET PULL a2,a3,a4,a6,a7,a9,a10 move a13,*a8(OPLINK),L move a8,a0 jruc INSOBJ ;Insert object into list .if DEBUG bopalerr LOCKUP ;Object doesn't have pallette! eint clr a0 jruc bo20 .endif begobjerr .if DEBUG LOCKUP ;Out of objects! eint .else CALLERR 3,7 .endif move @OBJLST,a8,L ;Pass 1st obj on list PULL a2,a3,a4,a6,a7,a9,a10 rets #******************************* * Begin an object with specified palette * A0=XVAL, A1=YVAL, A2=*IMG, A3=ZPOS, A4=FLAGS, A5=OID, A6=XVEL, A7=YVEL * B0=*Palette * >A8=*Obj * Trashes scratch BEGINOBJWP move @WORLDTLX,a8,L ;Adjust for world coord add a8,a0 btst B_3D,a4 jrnz BEGINOBJP ;No Y add for 3D? move @WORLDTLY,a8,L add a8,a1 BEGINOBJP PUSH a2,a3,a4,a6,a7,a9,a10 move a0,a9 ;X move a1,a10 ;Y move b0,a0 ;Get *palette .if DEBUG jrnn #bopalerr ;No pallette? .endif calla pal_getf #bo20 move @OFREE,a8,L ;Pointer to next available obj block jrz begobjerr ;No objs? move *a8,a1,L move a1,@OFREE,L ;Adjust pointer to free list move a0,*a8(OPAL),L ;Set pallette & constant clr a0 move a0,*a8(ODATA_p),L ;Clr stuff move a0,*a8(OXANI),L move a0,*a8(OZVEL),L move a0,*a8(OMISC) move a0,*a8(ODOFF),L movi 01000100H,a0 move a0,*a8(OSCALE),L move a3,*a8(OZPOS) move a5,*a8(OID) move a6,*a8(OXVEL),L move a7,*a8(OYVEL),L move a2,a1 ;*Img move *a1,a2,L ;ISIZE callr GANIOF ;Adjust animation offset ;here!!!!!!!!!!!!!! move *a1(IANIOFFX),*a8(ODXOFF) ;display x offset move *a1(IANIOFFY),*a8(ODYOFF) ;display y offset move *a1(ISAG),a3,L ;Get top left sag ;;; sub a6,a9 ;- x anioff ;;; sub a7,a10 ;- y anioff move a9,*a8(OXVAL),L move a10,*a8(OYVAL),L move a1,*a8(OIMG),L move a2,*a8(OSIZE),L move a3,*a8(OSAG),L move a4,*a8(OFLAGS) move *a1(ICTRL),a0 ;Get DMA flags andi >803f,a4 ;Kill mode bits or a0,a4 move a4,*a8(OCTRL),L ;&OFSET PULL a2,a3,a4,a6,a7,a9,a10 move a13,*a8(OPLINK),L move a8,a0 jruc INSOBJ ;Insert object into list .if DEBUG #bopalerr LOCKUP ;Object doesn't have pallette! eint clr a0 jruc #bo20 .endif #******************************* * Set new image for an object * A1=*Image hdr * A4=New FLAGS * A8=*Obj * Trashes A1,A14 SUBR ANI PUSH a0,a2,a3,a4,a5,a6,a7 cmpi ROM,a1 jrlo anierr move a1,a3 move a4,a5 move *a8(OIMG),a1,L move *a8(OCTRL),a4 cmp a1,a3 jrne #1 ;Different img? sext a5 cmp a4,a5 jreq #x ;All the same? #1 move *a8(OSIZE),a2,L callr GANIOF ;Get old animation offset move a3,a1 ;New OIMG srl 6,a4 sll 6,a4 or a5,a4 ;Set new OCTRL move a6,a0 move a7,a5 move *a1(ISAG),a3,L ;Get top left sag move *a1,a2,L ;ISIZE callr GANIOF ;Get new animation offset move a1,*a8(OIMG),L sub a6,a0 ;Subtract new from old sub a7,a5 zext a4 ;Zero offset in A4 move a8,a6 ;Get push address of octrl,osag,osize addi OCTRL+>60,a6 mmtm a6,a2,a3,a4 ;Save new data subi OCTRL-OXVAL,a6 move *a6,a7,L ;New OXVAL add a0,a7 move a7,*a6+,L move *a6,a7,L ;New OYVAL add a5,a7 move a7,*a6,L #x PULL a0,a2,a3,a4,a5,a6,a7 rets anierr .if DEBUG LOCKUP eint .else CALLERR 2,7 .endif jruc #x #***************************************************************************** * Change an objects image (Doesn't check VFLIP) * A0=*New image * A1=New flip flags & const * A8=*Obj * Trashes scratch SUBRP obj_aniq PUSH a2,a3 cmpi ROM,a0 jrlo #anierr move a0,a2 move a1,a3 callr anipt_getxy move a2,*a8(OIMG),L move *a2(0),*a8(OSIZE),L move *a2(ISAG),*a8(OSAG),L setf 5,0,0 move *a2(ICTRL+7),*a8(OCTRL+7) ;Write 5 z comp bits setf 6,0,0 move a3,*a8(OCTRL) ;Write 6 low bits setf 16,1,0 move a0,a2 move a1,a3 callr anipt_getxy sub a0,a2 ;Subtract new from old sub a1,a3 move a8,a0 ;Get base address addi OXVAL,a0 move *a0,a14,L ;New OXVAL add a2,a14 move a14,*a0+,L move *a0,a14,L ;New OYVAL add a3,a14 move a14,*a0,L #x PULL a2,a3 rets #anierr .if DEBUG LOCKUP eint .else CALLERR 2,2 .endif jruc #x #******************************* * Get an objects anipt XY (Doesn't check VFLIP) * A8=*Obj * >A0=Scaled Ani X (16:16) * >A1=Scaled Ani Y * Trashes scratch SUBRP anipt_getxy move a2,b0 move *a8(OIMG),a2,L move *a2(IANIOFFX),a0 sll 16,a0 move *a2(IANIOFFY),a1 sll 16,a1 move *a8(OCTRL),a14 btst B_FLIPH,a14 jrz #x ;No flip? move *a2,a2 ;ISIZEX subk 1,a2 sll 16,a2 ;*64K neg a0 add a2,a0 ;+size #x move b0,a2 rets #******************************* * Change an objects image (doesn't check flip flags) * A0=*New image * A1=New OCTRL * A8=*Obj * Trashes scratch SUBRP obj_aniq_cnoff move a2,b0 move a1,*a8(OCTRL) ;Write new ctrl move *a8(OIMG),a14,L move *a14(IANIOFFX),a2 move *a14(IANIOFFY),a14 move a0,*a8(OIMG),L move *a0(0),*a8(OSIZE),L move *a0(ISAG),*a8(OSAG),L move *a0(IANIOFFY),a1 move *a0(IANIOFFX),a0 sub a0,a2 ;Subtract new from old sub a1,a14 sll 16,a2 sll 16,a14 move a8,a0 ;Get base address addi OXVAL,a0 move *a0,a1,L ;New OXVAL add a2,a1 move a1,*a0+,L move *a0,a1,L ;New OYVAL add a14,a1 move a1,*a0,L move b0,a2 rets ;#******************************* ;* Change an scaled objects image (Doesn't check VFLIP) ;* A0=*New image ;* A1=New OCTRL (low 8 bits) ;* A8=*Obj ;* Trashes scratch, A2,A3 ; ; ; SUBRP obj_aniq_scld ; ; ; cmpi ROM,a0 ; jrlo #anierr ; ; move a0,a2 ; move a1,a3 ; ;;;; calla anipt_getsclxy ; ; movb a3,*a8(OCTRL) ; ; move a2,*a8(OIMG),L ; move *a2(0),*a8(OSIZE),L ; move *a2(ISAG),*a8(OSAG),L ; ; move a0,a2 ; move a1,a3 ;;;; calla anipt_getsclxy ; ; sub a0,a2 ;Subtract new from old ; sub a1,a3 ; ; move a0,*a8(OXANI),L ;Save scaled anipt ; ; move a8,a0 ;Get base address ; addi OXVAL,a0 ; move *a0,a14,L ;New OXVAL ; add a2,a14 ; move a14,*a0+,L ; move *a0,a14,L ;New OYVAL ; add a3,a14 ; move a14,*a0,L ; ;#x rets ; ; ;#anierr ; .if DEBUG ; LOCKUP ; eint ; .else ; CALLERR 2,0 ; .endif ; jruc #x ******************************** * Get the x and y positions of an objects animation point * A8=*Object * Trashes scratch * >A2=Ani pt Y 16:16 * >A3=Ani pt X 16:16 GETANIXY PUSH a4,a6,a7 move *a8(OIMG),a1,L move *a8(OSIZE),a2,L move *a8(OCTRL),a4 callr GANIOF move *a8(OXVAL),a3,L move *a8(OYVAL),a2,L add a6,a3 add a7,a2 PULL a4,a6,a7 rets #******************************** * Get animation offset (Fast!) * A1=*Image header, A2=H:W, A4=OCTRL * Trashes A14 *Rets: * A6=X ani offset * 64K * A7=Y ani offset * 64K GANIOF move *a1(IANIOFF),a6,L cmpi IROM,a6 jrge #err #h clr a7 movy a6,a7 sll 16,a6 ;Move to upper word btst B_FLIPH,a4 jrz #v move a2,a14 subk 1,a14 sll 16,a14 ;Move W to upper word neg a6 add a14,a6 ;Sub Width-1 #v btst B_FLIPV,a4 jrz #x move a2,a14 neg a7 srl 16,a14 subk 1,a14 sll 16,a14 add a14,a7 ;Sub Hgt-1 #x rets #err clr a6 jruc #h #******************************* * Scale screen out (JSRP) .asg SCRATCH+8*256*1024,SCRNBUF .asg SCRNBUF+8*128*1024,PALBUF .bss scrnscl ,16 SUBR scrn_scaleout movk 1,a0 move a0,@HALT move @dtype,a0 PUSHP a0 move @gndstat,a0 PUSHP a0 movi >160,a0 move a0,@scrnscl movi #initcode,a0 move a0,@dcode_p,L movi -1,a0 move a0,@dtype clr a0 move a0,@gndstat move a0,@IRQSKYE #lp SLEEPK 1 movi scrnscl,a14 move *a14,a5 move a5,a0 srl 3,a0 add a0,a5 move a5,*a14 cmpi >7000,a5 jrlt #lp clr a0 move a0,@dcode_p,L PULLP a0 move a0,@gndstat PULLP a0 move a0,@dtype RETP #initcode callr scrn_copy movi scrn_scale,a0 move a0,@dcode_p,L jump a0 #******************************* * Initialization for scrn_scalein (JSRP) SUBR scrn_scaleininit dint #lp move @VCOUNT,a0 cmpi EOSINT,a0 jrlt #lp move @HSBLNK,a0 ;Blank screen move a0,@HEBLNK eint SLEEPK 2 RETP #******************************* * Scale screen in (JSRP) SUBR scrn_scalein PUSHP a8 move @HALT,a0 PUSHP a0 movk 1,a0 move a0,@HALT move @dtype,a0 PUSHP a0 move @gndstat,a0 PUSHP a0 move @dcode_p,a0,L PUSHP a0 movi >7000,a0 move a0,@scrnscl movi #initcode,a0 move a0,@dcode_p,L movi -1,a0 move a0,@dtype clr a0 move a0,@gndstat .if DEBUG ; movi >1a0,a0 ; move a0,@scrnscl ; SLEEP TSEC*2 .endif #lp SLEEPK 1 movi scrnscl,a14 move *a14,a5 move a5,a0 srl 2,a0 sub a0,a5 move a5,*a14 cmpi >100,a5 jrgt #lp PULLP a0 move a0,@dcode_p,L PULLP a0 move a0,@gndstat PULLP a0 move a0,@dtype PULLP a0 move a0,@HALT PULLP a8 RETP #initcode callr scrn_copy movi scrn_scaledison,a0 move a0,@dcode_p,L jruc scrn_scale #******************************* * B2=Y offset for top of page : XPad offset * Trashes A0-A3,A7 SUBRP scrn_copy move b2,a0 srl 16,a0 xori >100,a0 ;Flip to the page being shown sll 12,a0 ;*512*8 addi SCRNXP*8,a0 ;A0=*Scrn mem PUSH a0 movi SCRNBUF,a1 movi 254,a3 movi (512-400)*8,a7 #cslp movi 400/16,a2 #cslp2 move *a0+,*a1+,L move *a0+,*a1+,L move *a0+,*a1+,L move *a0+,*a1+,L dsj a2,#cslp2 add a7,a0 add a7,a1 dsj a3,#cslp move @SYSCOPY,a0 .if WWFUNIT andni PALENB,a0 move a0,@SYSCOPY .if DEBUG andni LEDON,a0 ori WROMINTCLR,a0 .endif .else andni 100000b,a0 move a0,@SYSCOPY .if DEBUG andni 1000000b,a0 .endif .endif move a0,@SYSCTRL PULL a0 movi PALBUF,a1 movi 254,a3 #cplp movi 400/16,a2 #cplp2 move *a0+,*a1+,L move *a0+,*a1+,L move *a0+,*a1+,L move *a0+,*a1+,L dsj a2,#cplp2 add a7,a0 add a7,a1 dsj a3,#cplp move @SYSCOPY,a0 .if WWFUNIT ori PALENB,a0 move a0,@SYSCOPY .if DEBUG andni LEDON,a0 ori WROMINTCLR,a0 .endif .else ori 100000b,a0 move a0,@SYSCOPY .if DEBUG andni 1000000b,a0 .endif .endif move a0,@SYSCTRL rets #******************************* * Copy screen data (throw out 1 in 5 pixels) * B2=Y offset for top of page : XPad offset SUBRP scrn_scale140 PUSH a4,a14 movi >140,a5 move b2,a1 srl 16,a1 addi 25,a1 sll 12,a1 ;*512*8 addi SCRNXP*8+40*8,a1 ;A1=*Scrn mem movi DMACMAP,a6 clr a7 ;Y line 8:8 #lp move a7,a2 srl 8,a2 sll 12,a2 ;*512*8 move a2,a3 addi SCRNBUF,a2 addi PALBUF,a3 movi 400/2/5,b0 ;Copy 1 line #cslp move *a3,*a6 ;Set pal latch addk 16,a3 move *a2+,*a1+ ;Copy 2 pixels move *a3,*a6 addk 16,a3 move *a2+,*a1+ move *a3,*a6 addk 16,a3 move *a2+,*a1+ move *a3,*a6 addk 16,a3 move *a2+,*a1+ addk 16,a3 addk 16,a2 dsj b0,#cslp addi (512-320)*8,a1 add a5,a7 cmpi 254<<8,a7 jrlt #lp #x PULL a4,a14 rets #******************************* * Copy screen data (throw out 1 in 3 pixels) * B2=Y offset for top of page : XPad offset SUBRP scrn_scale180 PUSH a4,a14 movi >180,a5 move b2,a1 srl 16,a1 addi 42,a1 sll 12,a1 ;*512*8 addi SCRNXP*8+68*8,a1 ;A1=*Scrn mem movi DMACMAP,a6 clr a7 ;Y line 8:8 #lp move a7,a2 srl 8,a2 sll 12,a2 ;*512*8 move a2,a3 addi SCRNBUF,a2 addi PALBUF,a3 movi 400/2/3,b0 ;Copy 1 line #cslp move *a3,*a6 ;Set pal latch addk 16,a3 move *a2+,*a1+ ;Copy 2 pixels move *a3,*a6 addk 16,a3 move *a2+,*a1+ addk 16,a3 addk 16,a2 dsj b0,#cslp addi (512-264)*8,a1 add a5,a7 cmpi 254<<8,a7 jrlt #lp #x PULL a4,a14 rets ******************************** SUBRP scrn_scaledison movi HEBLNKINIT,a0 ;Display on move a0,@HEBLNK movi scrn_scale,a0 move a0,@dcode_p,L #******************************* * Copy screen data with variable down scaling * B2=Y offset for top of page : XPad offset SUBRP scrn_scale move @scrnscl,a5 cmpi >168,a5 jrlt scrn_scale140 cmpi >190,a5 jrlt scrn_scale180 PUSH a4,a14 move b2,a9 srl 16,a9 movi 127<<8,a3 divu a5,a3 sub a3,a9 addi 127,a9 sll 12,a9 ;*512*8 addi (SCRNXP+200)*8,a9 ;A9=*Scrn mem movi 100<<8,a3 divu a5,a3 sll 4,a3 ;*16 sub a3,a9 movi DMACMAP,a6 clr a7 ;Y line 8:8 movi 200<<8,a10 #lp move a7,a2 srl 8,a2 sll 12,a2 ;*512*8 move a2,a3 move a9,a1 addi SCRNBUF,a2 addi PALBUF,a3 clr a8 ;X 8:8 #cslp move *a3,*a6 ;Set pal latch move *a2,*a1 ;Copy 2 pixels addk 16,a1 move a8,a0 add a5,a8 sra 8,a0 move a8,a14 sra 8,a14 sub a0,a14 #nxtp addk 16,a3 addk 16,a2 subk 1,a14 jrgt #nxtp cmp a10,a8 jrlt #cslp addi 512*8,a9 ;Next line add a5,a7 cmpi 254<<8,a7 jrlt #lp #x PULL a4,a14 rets #***************************************************************************** * Remove an object from OBJLST and move it to BAKLST * a0=*obj * Trashes a1,a14 SUBR fg2bg movi OBJLST,a1 #loop move a1,a14 move *a1,a1,L jrz #not_found cmp a0,a1 jrne #loop ;found it move *a0,*a14,L ;remove from OBJLST callr INSBOBJ ;add to BAKLST move *a0(ODXOFF),a1 ;adjust X and Y pos. BGND objects move *a0(OXPOS),a14 ; don't use anim points. sub a1,a14 move a14,*a0(OXPOS) clr a14 move a14,*a0(ODXOFF) move *a0(ODYOFF),a1 move *a0(OYPOS),a14 sub a1,a14 move a14,*a0(OYPOS) clr a14 move a14,*a0(ODYOFF) #not_found rets #***************************************************************************** * Create an object from one of jason's special header blocks. * >a0=*block * 01000100,a2 move a2,@DMASCALEX,L ; dma input #1 = scale ; movi bpal_black*>10000,a2 *TEMP movi 010101010h,a2 ; CLR A2 *TEMP move a2,@DMACMAP,L ; dma input #2 = const:palette * * setup dedicated registers * * b0 = dmactrl * b1 = worldtly * a2 = dma y:x size pointer * a3 = dma control:offset * a6 = dma y coordinate pointer * a12 = dma sag pointer * movi DMAVERT,a6 movk 1,a8 move a8,*a6(020h),W ; y size is always "1" movi DMAOFFST,a2 clr a8 move a8,*a2+,W ; offset is always "0" movi DMAHORIZ,b6 movi 02000000h,a7 movi DMASAGL,a12 move @page_addr,a5,L shad0 move *a3+,a9,L move *a9(OXPOS),a0,W zext a0,W ; sll 16,a13 ; or a13,a0 ; a0 = ani y:x for all pieces (world) move b1,a14 ; a14 = worldtly CLR A13 move @WORLDTLX+16,a13 SUBXY A13,A0 move @WORLDTLY+16,A13 SUBI 10,A13 SLL 16,A13 SUBXY A13,A0 addxy a5,a0 MOVE A0,B8 MOVE B8,*B6,L ;DO XPOS MOVE A0,B4 .ALIGN ************************************************************************** * * * piece by piece loop * * * ************************************************************************** shad2 move *a9(OYPOS),a10 jrn shad9 move *a9(OSAG),a10,L ; a10 = sag of this piece jrz shad9 ; sag = 0 ---> we are done add a7,a10 move *a9(OSIZEY),a13,W ; a13 = # of lines srl 3,a13 ; shadows are 1/4 the normal height move a13,b5 move *a9(OSIZEX),a11,W move a11,*a6(010h),W ; set a11 = x size for this piece move *a9(ODXOFF),A13 move *a9(OCTRL),a14,W btst B_FLIPH,a14 ; flip horizontal ? jreq shad1 NEG A13 shad1 move a14,a1 move a14,a4 sll 16+4,a1 srl 32-2,a1 ; a1 = trail multiplier sll 16+4+2,a4 srl 32-2,a4 ; a4 = lead multiplier ori DMACNZ,a14 MOVE B4,A0 SUBXY A13,A0 move a0,b8 move b8,*b6,W ; set x coordinate here !! srl 16,a0 move *a9(ODYOFF),A13 SRL 3,A13 SUBXY A13,A0 ************************************************************************** * * * line by line loop * * * ************************************************************************** shad4 shad3 move *b0,b3,W jrn shad3 ; wait for dma while busy sub A7,a10 move a10,*a12,L ; stuff sag add A7,a10 move a0,*a6,W ; set y coordinate move a14,*a2,W ; set the GO! bit dsjs b5,shad5 ************************************************************************** * * * do the last line again to fill in "holes" * * * ************************************************************************** inc a0 move a0,*a6,W ; set y 1 line down dec a0 shad6 move *b0,b3,W jrn shad6 ; wait for dma while busy move a14,*a2,W ; set the GO move *a3+,a9,L jruc shad2 * * skip 4 lines * shad5 move *b0,b3,W jrn shad5 ; wait for dma while busy inc a0 movk 8,b3 setf 8,0,0 ; field 0 is 8 bits (zero extend) shad7 move *a10+,a8,W ; grab a BYTE !! move a8,a13 sll 32-4,a13 srl 32-4,a13 ; mask off upper b.s. sll a4,a13 ; a13 = lead zeros srl 4,a8 sll a1,a8 ; a8 = trailing zeros add a8,a13 ; a13 = lead + trailing = all compressed zeros move a11,a8 ; a8 = x size sub a13,a8 ; a8 = uncompressed pixels to skip sll 1,a8 ; 2x add a8,a10 sll 1,a8 ; + 4x = 6 bits per pixel add a8,a10 ; a10 ---> sag for next line dsjs b3,shad7 ;xx setf 16,1,0 ; field 0 is back to 16 bits jruc shad4 shad9 mmfm sp,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14 mmfm sp,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14 rets ;****************************************************************************** ; ;PLACE_SHADOWS ; mmtm sp,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14 ; mmtm sp,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14 ; ; move @process_ptrs,a3,L ; jrz shad9 ; addi OBJ_BASE,a3 ; move *a3,a3,L ; addi 020h,a3 ; ; movi DMACTRL,b0 ;shad_1 move *b0,b3,W ; jrn shad_1 ; wait for dma while busy ; ; movi >01000100,a2 ; move a2,@DMASCALEX,L ; dma input #1 = scale ;; movi bpal_black*>10000,a2 ;*TEMP ; CLR A2 ;*TEMP ; move a2,@DMACMAP,L ; dma input #2 = const:palette ;* ;* setup dedicated registers ;* ;* b0 = dmactrl ;* b1 = worldtly ;* a2 = dma y:x size pointer ;* a3 = dma control:offset ;* a6 = dma y coordinate pointer ;* a12 = dma sag pointer ;* ; ; movi DMAVERT,a6 ; movk 1,a8 ; move a8,*a6(020h),W ; y size is always "1" ; movi DMAOFFST,a2 ; clr a8 ; move a8,*a2+,W ; offset is always "0" ; movi DMAHORIZ,b6 ; movi 02000000h,a7 ; movi DMASAGL,a12 ; move @page_addr,a5,L ; ;shad0 ; move *a3+,a9,L ; move *a9(OYPOS),a13,W ; move *a9(OXPOS),a0,W ; zext a0,W ; sll 16,a13 ; or a13,a0 ; a0 = ani y:x for all pieces (world) ; ; move b1,a14 ; a14 = worldtly ; CLR A13 ; move @WORLDTLX+16,a13 ; SUBXY A13,A0 ; ; move @WORLDTLY+16,A13 ; SLL 16,A13 ; ADDXY A13,A0 ; ; addxy a5,a0 ; MOVE A0,B8 ; MOVE B8,*B6,L ;DO XPOS ; ; MOVE A0,B4 ; ;************************************************************************** ;* * ;* piece by piece loop * ;* * ;************************************************************************** ; ;shad2 move *a9(OSAG),a10,L ; a10 = sag of this piece ; jrz shad9 ; sag = 0 ---> we are done ; ; add a7,a10 ; ; move *a9(OSIZEY),a13,W ; a13 = # of lines ; srl 2,a13 ; shadows are 1/4 the normal height ; move a13,b5 ; ; move *a9(OSIZEX),a11,W ; move a11,*a6(010h),W ; set a11 = x size for this piece ; ; move *a9(OCTRL),a14,W ; btst B_FLIPH,a14 ; flip horizontal ? ; jreq shad1 ; addxy a11,a0 ; yes, adjust coordinates for flip ; dec a0 ; and nudge.. ; ;shad1 move a14,a1 ; move a14,a4 ; sll 16+4,a1 ; srl 32-2,a1 ; a1 = trail multiplier ; sll 16+4+2,a4 ; srl 32-2,a4 ; a4 = lead multiplier ; ; ori DMACNZ,a14 ; ; MOVE B4,A0 ; move a0,b8 ; move b8,*b6,W ; set x coordinate here !! ; srl 16,a0 ; ;************************************************************************** ;* * ;* line by line loop * ;* * ;************************************************************************** ; ;shad4 ;shad3 move *b0,b3,W ; jrn shad3 ; wait for dma while busy ; ; sub A7,a10 ; move a10,*a12,L ; stuff sag ; add A7,a10 ; ; move a0,*a6,W ; set y coordinate ; move a14,*a2,W ; set the GO! bit ; dsjs b5,shad5 ; ;************************************************************************** ;* * ;* do the last line again to fill in "holes" * ;* * ;************************************************************************** ; inc a0 ; move a0,*a6,W ; set y 1 line down ; dec a0 ; ;shad6 move *b0,b3,W ; jrn shad6 ; wait for dma while busy ; ; move a14,*a2,W ; set the GO ; ; move *a3+,a9,L ; ; jruc shad2 ; ;* ;* skip 4 lines ;* ;shad5 move *b0,b3,W ; jrn shad5 ; wait for dma while busy ; ; inc a0 ; ; movk 4,b3 ; setf 8,0,0 ; field 0 is 8 bits (zero extend) ; ;shad7 move *a10+,a8,W ; grab a BYTE !! ; ; move a8,a13 ; sll 32-4,a13 ; srl 32-4,a13 ; mask off upper b.s. ; sll a4,a13 ; a13 = lead zeros ; ; srl 4,a8 ; sll a1,a8 ; a8 = trailing zeros ; ; add a8,a13 ; a13 = lead + trailing = all compressed zeros ; move a11,a8 ; a8 = x size ; sub a13,a8 ; a8 = uncompressed pixels to skip ; ; sll 1,a8 ; 2x ; add a8,a10 ; sll 1,a8 ; + 4x = 6 bits per pixel ; add a8,a10 ; a10 ---> sag for next line ; dsjs b3,shad7 ; ;;xx ; setf 16,1,0 ; field 0 is back to 16 bits ; jruc shad4 ; ;shad9 ; mmfm sp,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14 ; mmfm sp,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14 ; rets ; ****************************************************************************** .end