0 Members and 2 Guests are viewing this topic.
move.b #0,d0 | X move.b #20,d1 | Y lea spriteBox,a1 jsr drawSprite movea.l AMS_jumptable,%a5 | load the AMS jumptable to a5 movea.l 4*ngetchx(%a5),%a5 | ngetchx() jsr (%a5) bra exit|----------------------------| drawSprite: draw a sprite to LCD| d0 = X position| d1 = Y position| a1 = sprite locationdrawSprite: move.b d0,d2 | save X coord and.b #0x07,d0 | how much we need to rotate the sprite mulu #30,d1 | i think the screen is 30 bytes wide? lea LCD_MEM,a0 | start of LCD_MEM add d1,a0 | add the Y offset to a0 lsr #3,d2 | shift d2 (xCoord) right 3 bits add d2,a0 | add X offset to a0 move.b #7,d2 | display 8 rowsscreenLoop: move.w (a1)+,d1 | put the byte of data into d1 lsr.w d0,d1 | rotate byte of data 'd0' bits to the right eor.w d1,(a0) | xor (ExclusiveOR) the byte (well, word) into a0 (the LCD) lea 30(a0),a0 | shift down a row dbra d2,screenLoop | it's beyond me why d2=7 will draw 8 rows... it must break on -1? rtsspriteBox:.byte 0b11111111,0.byte 0b11111111,0.byte 0b11100111,0.byte 0b11000011,0.byte 0b11000011,0.byte 0b11100111,0.byte 0b11111111,0.byte 0b11111111,0
;a2=pointer to map datadrawTileMap: move.b (a2)+,mapWidth+3 ; the first byte contains the width of the map clr.l d1 ; d1 = y position on screen of current tile, set to 0 and clear out upper bytes move.l #6,d3 ; number of rows to draw;d0=x;d1=y;d2=col counter;d3=row counter;a2=mappointerdTM_vert clr.l d0 move.w #9,d2dTM_horiz: movem.w d0-d3,-(sp) ; push x/y and the counters onto the stack move.b (a2)+,d2 mulu.b #32,d2 ; each sprite is 32 bytes lea tiles(pc,d2),a1 bsr drawSpriteAligned movem.w (sp)+,d0-d3 ; retrieve pushed values add.w #16,d0 ; move over 16 pixels to draw next sprite dbra.w d2,dTM_horiz add.b #16,d1mapWidth: adda.w #00,a2 dbra.w d3,dTM_vert rts;----------------------------; drawSpriteAligned: draw an aligned sprite to LCD; d0 = X position; d1 = Y position; a2 = sprite locationdrawSpriteAligned: mulu.b #30,d1 ; screen is 30 bytes wide lea LCD_MEM,a0 ; start of LCD_MEM add d1,a0 ; add the Y offset to a0 divu.b #8,d0 ; divide d2 by 8 add d0,a0 ; add X offset to a0 move.w #15,d2 ; display 16 rowsdSA_loop: move.w (a1)+,d1 ; put the word of data into d1 eor.w d1,(a0) ; xor (ExclusiveOR) the byte (well, word) into a0 (the LCD) lea 30(a0),a0 ; shift down a row dbra d2,dSA_loop ; decrement and repeat until d2=0 (after the routine, d2 will = -1) rts
* mulu and divu usually have .w size, and they're not used in the usual sprite routines because they're very slow. mulu.w #30,dn is replaced by a series of add.w, lsl.w and sub.w; divu.w #8,dn is simply the much faster lsr.w #3, dn
* strictly speaking, the correct mnemonic for "dbra" is "dbf";
* "lea LCD_MEM,a0" should be "lea LCD_MEM.w,a0", to make sure that the assembler uses the shorter form;
* "add d1,a0" should be "adda.w d1,a0".
* "adda.w #00,a2" is superfluous
So divu.w #8 would be faster than lsr.w #3?
Quote"lea LCD_MEM,a0" should be "lea LCD_MEM.w,a0", to make sure that the assembler uses the shorter form;And it gets sign extended to a long-word?
"lea LCD_MEM,a0" should be "lea LCD_MEM.w,a0", to make sure that the assembler uses the shorter form;
Quote"add d1,a0" should be "adda.w d1,a0".The compiler fixed this for me, right?
"add d1,a0" should be "adda.w d1,a0".
Actually, the #00 gets overwritten through SMC: "move.b (a2)+,mapWidth+3" I'm not sure if this is good practice or not on the 68k, but it's something i do all the time in z80
How do the shift instructions work? Will an lsr.w #3,dn perform three shifts (like z80's slr rr \ slr rr \ slr rr)?
Or will shifting 1 bit use the same number of clocks as shifting 8 bits?
Do you know where i can find information on how long instructions take to execute? In the programmer's manual it lists the binary construction of each of the instructions, but i can't seem to find how many cycles an instruction will take.