Don't have an account? Register now to chat, post, use our tools, and much more.
Latest Headlines
Online Users
There are 105 users online: 5 members, 67 guests and 33 bots. Members: hesterd1914, jpitser, shkaboinka. Bots: VoilaBot (1), Spinn3r (2), Magpie Crawler (4), VoilaBot (8), Googlebot (17), MSN/Bing (1).
RSS & Social Media
SAX
You must log in to view the SAX chat widget
|
| Author |
Message |
|
mv2112
Newbie

Joined: 22 May 2012 Posts: 5 Location: New York
|
Posted: 23 May 2012 06:16:06 pm Post subject: Understanding a sprite routine |
|
|
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! |
|
| Back to top |
|
|
zeldaking
Power User

Joined: 31 Jul 2011 Posts: 470 Location: Utah
|
Posted: 23 May 2012 07:08:14 pm Post subject: |
|
|
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.
Last edited by zeldaking on 23 May 2012 10:45:34 pm; edited 1 time in total |
|
| Back to top |
|
|
mv2112
Newbie

Joined: 22 May 2012 Posts: 5 Location: New York
|
Posted: 23 May 2012 07:13:30 pm Post subject: |
|
|
| I'd rather make my own routine. I think i'd get more experience |
|
| Back to top |
|
|
zeldaking
Power User

Joined: 31 Jul 2011 Posts: 470 Location: Utah
|
Posted: 23 May 2012 07:14:43 pm Post subject: |
|
|
| Okay! I would be glad to help you along. As of right now you just need help on bit shifting? |
|
| Back to top |
|
|
mv2112
Newbie

Joined: 22 May 2012 Posts: 5 Location: New York
|
Posted: 23 May 2012 07:18:42 pm Post subject: |
|
|
| 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? |
|
| Back to top |
|
|
Deep Thought

Expert

Joined: 11 Mar 2010 Posts: 739 Location: The Universe
|
Posted: 24 May 2012 09:46:11 am Post subject: |
|
|
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). _________________
  |
|
| Back to top |
|
|
mv2112
Newbie

Joined: 22 May 2012 Posts: 5 Location: New York
|
Posted: 25 May 2012 09:56:55 pm Post subject: |
|
|
I'm almost embarrassed to display this code
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:
 |
|
| Back to top |
|
|
KermMartian

Site Admin

Joined: 14 Mar 2005 Posts: 55736 Location: Earth, Sol, Milky Way
|
Posted: 25 May 2012 10:09:58 pm Post subject: |
|
|
(1) I prefer lowercase opcodes; the uppercase ones give me a headache. 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. _________________
 |
|
| Back to top |
|
|
|
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
|
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
|
© Copyright 2000-2013 Cemetech & Kerm Martian :: Page Execution Time: 0.034077 seconds.
|