Hey, this is my first post here, so i guess i'l do a little introduction. I'm mike, i'm 16 and i'v been doing C++ for around 5 years, dabbled in some java, x86 assembly, php, javascript. I've always wanted to learn z80 assembly ever since i starting writing programs in BASIC for my TI-84.

Now to my question:
I've been studying "learn ti-83+ assembly in 28 days", and I can't seem to wrap my head around how to take a sprite like this:

Code:
ball:
     .DB %00111100
     .DB %01111110
     .DB %11110111
     .DB %11110011
     .DB %11111111
     .DB %11111111
     .DB %01111110
     .DB %00111100

and copy it to PlotSScreen at a given X and Y. Since the project im currently working on (Pong) doesnt really require alot of graphics, i plan on a XOR routine. I could just find someone else's sprite routine, but i want to actually understand the logic behind the code.

Here is what i had in mind for a routine:
1. Let C = 0. this denotes what row we're on
2. Find Starting Byte - ([y+(c*y)]*12) + (x/8)
3. Copy Row C of Data from ball to PlotSScreen
4. Repeat steps 1 - 4 incrementing C untill C >= the height of the sprite(8 for ball)

The only problem i have is that i'm not sure how to handle when x%8 != 0. I know i have to shift bits but im not sure how to do that.
Any help would be appreciated!
Nice to meet you, mike. Why not introduce yourself here: http://www.cemetech.net/forum/viewtopic.php?t=4925 Just so everyone can get to know you.
Why not use Ion? This is a lot easier. For Ion this is all it takes:

Code:

    LD    A,1      ;A is X coordinate
    LD    L,1      ;L is Y coordinate
    LD    B,8      ;B is sprite width
    LD    IX, Sprite   ;pointer to the sprite
    Call  $4089  ;These two display it
    Call  $4092

So it is a lot easier, why not try it out. Ion is just improved sys Calls, making them alot more user friendly, it is still z80. If you still want that way, I am fine with telling you.
I'd rather make my own routine. I think i'd get more experience
Okay! I would be glad to help you along. As of right now you just need help on bit shifting?
Yeah, how would you do that? To save pixel data between 2 bytes, do you shift the data to the right, save it to the first byte, then shift the data to the left, and save it to the next byte?
The easy way is to shift it one way (generally to the right, to avoid messy issues with SLL) and collect the bits that have been shifted out in another register.

For example, if you had eight bits in D and you wanted to shift it one bit, leaving the bit in E, you could do SRL D \ RR E. (SRL D leaves the 0th bit in the carry flag, which gets copied to bit 7 of E with RR E).
I'm almost embarrassed to display this code Sad
Remember, i'm a noob.

So, basically the program either freeze or makes the screen output crap and then freeze/infinite loop of crap output.

The Broken code lies within drawSprite somewhere:

Code:
drawSprite: ;IX->Sprite HL->X DE->Y BC->Width/Height
      PUSH BC
      CALL getFirstByte
      LD DE, PlotSScreen
      ADD HL, DE
      LD D, 0
      LD E, A
      POP BC
      PUSH DE
      PUSH BC
      CP 0
      JR Z, ds_aligned
      JR ds_done

ds_SrowLoop:
ds_shiftLoop:
ds_aligned:
      POP BC
      LD D, B
      LD E, C
      LD A, 0
      DEC HL
      PUSH AF
ds_rowLoop:
      INC HL
      PUSH AF
      LD A, (IX)
      XOR (HL)
      LD (HL), A
      POP AF
      INC IX
      CP D
      JR C, ds_rowLoop

      POP AF
      INC A
      CP E
      JR Z, ds_done
      PUSH AF
      PUSH DE
      LD D, 0
      LD A, E
      ADD HL, DE
      POP DE
      LD A, 0
      JR ds_rowLoop
     
ds_done:
      b_call(_GrBufCpy)

      RET

getFirstByte: ;IN: X->HL Y->DE OUT: BYTEADDR->HL SHIFT->A
      PUSH HL
      LD D, 12
      CALL mult
      LD D, H
      LD E, L
      POP HL
      LD C, 8
      CALL div ; a->remainder
      ADD HL, DE
      RET

mult: ;d * e
      LD HL, 0
      XOR A
      OR D
      RET Z
      OR E
      RET Z
      LD B, D
      LD D, H
m_loop:
      ADD HL,DE
      DJNZ m_loop
      RET

div: ;HL/C->HL remainder->A
      XOR A
      LD B, 16
d_loop:
      ADD HL, HL
      RLA
      CP C
      JR C, $+4
      SUB C
      INC L
      DJNZ d_loop
      RET
bX:
      .DB 0

bY:
      .DB 0

velocity:
      .DB %11111111 ;4 left bits are x, 4 right bits are y; most significant bit
                   ;represents negative or positive
ball:
      .DB %00111100
      .DB %01111110
      .DB %11110111
      .DB %11110011
      .DB %11111111
      .DB %11111111
      .DB %01111110
      .DB %00111100


How i call it:

Code:
#INCLUDE "ti83plus.inc"
#DEFINE  ProgStart    $9D95
#DEFINE  sWidth       1
#DEFINE  sHeight      8
.LIST
.ORG    ProgStart - 2
.DB     t2ByteTok, tAsmCmp
      b_call(_ClrLCDFull)
      LD HL, 256
      LD DE, 1
      LD B, sWidth
      LD C, sHeight
      LD IX, ball
     
      CALL drawSprite
      RET

This is a gif of the screen output:

(1) I prefer lowercase opcodes; the uppercase ones give me a headache. Wink Personal preference, I guess, but almost everyone in the community uses lowercase ones.
(2) For getFirstByte, I wish you would use some of the libraries. I understand and applaud your attempts to understand how to do it yourself, but once you do, you'll be able to make much smaller programs. Here, iGetPixel will do the trick.
(3) 'cp 0' can be written smaller and faster as 'or a'
(4) I like to ident my code one extra tab for each push, then remove each ident for each pop. It makes it clearer how deep into the stack I am. Again, personal preference; just an idea.
(5) A smaller faster way to write 'ld a,0' is 'xor a'. Keep in mind that it will reset the 'z' and 'c' flags, if you care about that.
(6) grbufcpy is super-slow, and only works on some hardware. I know I'm harping on libraries, but Doors CS's iFastCopy is designed to work properly even on calculators with glitchy LCDs and on the Nspire.

(7) Your actual problem is too many pushes and not enough pops. For example, if your code jumps to ds_done from drawSprite, then it has two un-popped values. In the ds_aligned codepath, it never pops de.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement