I don't think that will crash your program, but do you realize you are loading 16 bits (2 bytes) into curRow? If fShipX is immediately followed by fShipY, then there shouldn't be a problem, though. I don't think that's what's causing your program to crash. You could try loading fShipX into a and then loading a into curRow.
oh, wait... so "LD HL,(fShipX)" loads the number both into H and L?

if it isnt that, then maybe it's the Keydirection code. if memory serves me right, that was something like:

Code:

getKeyDirec:
BCall GetCSC
cp skUp
jq nz,ckUp            ;nz or z, i cant remember which i had..
cp skRight
jq nz,ckRt
cp skDown
jq nz,ckDn
cp skLeft
jq nz,ckLt
RET

and this was the code for one of the ck's:

Code:

LD HL,(fshipX)                     ;Or fshipY
INC HL                                ;this is DEC for up and left
LD (fshipX),HL                     ;Or fshipY


perhaps im not loading/saving the variable right?
It is probably z, otherwise you will always jump to ckUp unless you press
[Up].

As for your other code, ld hl,(fShipX) loads the value stared at fShipX's address into l, then loads the value at fShipX+1 into h. hl is a two-byte register, so it will load two bytes from memory. When you store it back into fShipX, you are overwriting whatever value was at fShipX+1, though most likely that won't change anything since i don't think your X value will ever carry/wrap (go > 255). If you want to use a one-byte register (which will also be slightly faster) you can use a. A smaller version might be something like this:

Code:
    ld hl,fShipX   ;note, no parentheses. we are loading the address into hl, not the value stored at fShipX
    ld a,(hl)
    inc a
    ld (hl),a
It's smaller and faster as working with registers generally is compared to working with immediate values and loading to and from immediate addresses.

Again, that doesn't seem like it would cause the program to crash.
well, i got the movement to work with

Code:

LD A,(fShipX)
INC A
LD (fShipX),A

...and then i saw your post. oh well.
however, i still cannot Exit the program.
i have 2 buttons assigned, graph and Enter, that go to a label called Exit.

Code:

Exit:
Call ScrSet        ;clears screen, sets curRow and curCol to 0
RET

well, when i press either button the indicator flashes (probably from ScrSet), but the game continues. any suggestions?
curRow holds a Y value, and the address one byte after it, curCol, holds an X value. Make sure you have that straight Wink
To improve on chickendude's code, there's no need to use the A register unless you need fShipX's value later. You can do this instead:

Code:
ld hl, fShipX ;note, no parentheses. we are loading the address into hl, not the value stored at fShipX
inc (hl)

If you needed the value in A as well, you could just add a "ld a,(hl)" at the end.
well, i got it to work-not trying to optimize it or anything yet.
but for the exit issue?
Well, make sure you're jumping to Exit, and not calling it. In general, make sure the stack doesn't have any additional values on it before you jump to Exit. If for some reason you are exiting from a deep series of calls, you can force your way out of that, but usually that's not the case.
i am using JQ, not Call. and, far as i know, i dont use Push/Pop in my program. as for series calls, the main calls the Ship updater, which calls the Get direction code. so when i press Graph/Enter, it JQs to Exit, which calls a clearscreen, which returns, and hits another Return code. i guess JQ doesnt kill the Call stack? if so, how do i get rid of all the stack?
calcdude84se wrote:
curRow holds a Y value, and the address one byte after it, curCol, holds an X value. Make sure you have that straight Wink
To improve on chickendude's code, there's no need to use the A register unless you need fShipX's value later. You can do this instead:

Code:
ld hl, fShipX ;note, no parentheses. we are loading the address into hl, not the value stored at fShipX
inc (hl)

If you needed the value in A as well, you could just add a "ld a,(hl)" at the end.
Though you'll usually want to test to make sure you aren't going beyond a certain value (ie 8 or whatever the last valid curRow value is) so you probably will need to load it into a Wink Though you're right, that would be faster/smaller and there was no boundary-checking in the original version Smile

There are two common ways of clearing the stack:
1. Simply popping until there are no more values (pushed by your program, that is) left on the stack.
2. Saving the stack when you start your program and then loading that value back into sp. For example:

Code:
    ld (initSP),sp
;... main program
exit:
    ld sp,(initSP)
    ret


Generally you'll want to make sure you know where the stack is at and the flow of your program will make the 2nd option unnecessary. But it does sound like a stack issue. It seems like you are just jumping back to your ship updater routine.

Code:
main:
   call shipupdater
;<--Entry 1: stack points here
;...
shipupdater:
   call get
;<--Entry 2: stack points here, previous value points to Entry 1
;...
get:
   jr quit
quit:    ;currently stack points to Entry 2
;a ret here would send you to Entry 2 (next byte after the call to get)
   pop hl ;now stack points to Entry 1
;a ret here would send you to Entry 1 (next byte after call to shipupdater)
   pop hl ;now stack is clear
   ret ;will take you to TI-OS
Perfect! thanks for helping me solve this. i used the first one, and now the exit code works. now to get on with the rest of the development.

also, im wondering if there is a way to place a charecter Backwards?
(example: -> becomes <-)
You'd have to load the sprite first then flip the bits. I don't know of any bcall that does it for you, though i think there is a bcall that will load the sprite for you. You'd then have to flip the bits yourself. I think there was an optimized routines "game" at MaxCoderz or maybe RevSoft a few years ago that had flipping the bits of a byte as one of the topics.
The short answer to your question is "no".
The longer answer is "It depends on what exactly you want."
Given the talk of curRow, I take it you're drawing things to the homescreen. I'm also going to assume you're using bcall(_PutMap) to place characters, with the effect that the OS never scrolls the screen, and that you're not reading textShadow at any point.
There's no support for drawing a character backwards. You have to do that yourself. With the assumptions listed above, your best choice is direct LCD output! Refer to http://wikiti.brandonw.net/index.php?title=83Plus:Ports:10 as I continue.
Basically, you'll have to draw any "special" characters yourself. Here's some untested, unoptimized, but commented code that can do that. Follow along with the comments in order to understand it.

Code:
putMapSprite:
;Draws the 8-byte sprite at HL to the screen in the same position that bcall(_PutMap) would
call lcd_wait ;Makes sure the LCD is ready. Defined below
xor a ;load a with 0. This is the LCD command to set 6-bit mode, which is what you need for the homescreen
out ($10),a ;$10 is the LCD command port
call lcd_wait
ld a,5
out ($10),a ;Set X-increment mode. This means data will be written to the screen downwards
;Note: 6-bit needs to be set; X-Incr should already be set, but it doesn't hurt
call lcd_wait
ld a,(curRow)
add a,a
add a,a
add a,a
or $80
out ($10),a ;Set the row to (curRow)*8--each character is 8 lines high
call lcd_wait
ld a,(curCol)
or $20
out ($10),a ;Set the column to (curCol)
;The "or"s above are to get the right command prefix
ld b,8 ;8 rows to copy
pms_loop:
call lcd_wait
ld a,(hl) ;get the byte at HL, where the sprite is
out ($11),a ;Write the byte to the LCD
inc hl ;move to the next byte
djnz pms_loop
call lcd_wait
ld a,1
out ($10),a ;Return the LCD to 8-bit mode, as various OS routines expect it to be so. You might be able to get away without this.
ret

lcd_wait:
in a,($10)
jp m,lcd_wait ;High bit of port $10 is set if busy
ret

So, just point HL at the sprite and call the routine and it will display the sprite. I don't know if there's a bcall to get the sprite for a certain character, but it would definitely be easier just to include the reversed sprite in your program.
Edit: I have tested similar code since starting to write this post that works, so it's sound at least in principle.
I think you might be able to use the LoadPattern bcall. Here's what 83psysroutines has to say:
Quote:
LoadPattern
Category: Display
Description: Loads the font pattern for a character to RAM. Also includes the character's width in pixels. This will work for both variable width and 5x7 fonts.

Inputs:
Registers: ACC = character equate
Flags: fracDrawLFont, (IY + fontFlags) = 1 to use Large 5x7 font, = 0 to use variable width font
Others: None

Outputs:
Registers: None
Flags: None
Others: For large 5x7 font: RAM @ lFont_record = width of character, seven-byte font
For variable width font: RAM @ sFont_record = width of character, seven-byte font
The first byte of the font is the pixel mapping for the top row and each subsequent byte is the next row. The LSB of each byte represents the right most pixel of a row.
Registers destroyed: All

Remarks:
If fracDrawLFont is set, it must be reset.
It seems it might just be easier for him to include the reversed sprite into the program itself and not rely on bcall(_LoadPattern). Or if he wants to use it, he really should calculate the reversed sprite and put it somewhere in RAM to cache it because having to calculate it every time would be slow.
well, so far ive used PutC, is PutMap the same?

@calcdude84se
What is the purpose of LCDwait?


@Chickendude
uhh, let me look over that some other time...
I agree, it'd be easier to just include the sprite (and the code would likely be smaller), but if you want to be able to flip every single character it might end up being smaller to find the characters, flip them, and store them in saferam.

@LuxenD: LCDwait is to make sure that you don't try to draw to the screen before it is ready to be drawn to. It waits until the LCD is ready then returns back to the main code.

To use that BCALL, i'd try something like:

Code:
   ld a,'Z'
   set fracDrawLFont,(iy+fontFlags) ;if you want to use the large font
   bcall(_LoadPattern)
   ld hl,lFont_record+1 ;sprite should be here
   ld a,(hl)
;flip sprite
Chickendude's got it. The only additional things I would note are that you want to reset fracDrawLFont after you've bcalled _LoadPattern, and that when you flip the sprite you don't flip all the bits as the top ones aren't actually part of the sprite.
Sorry for the delayed response. That is the proper syntax, but you are loading two bytes. If you want to load only the one byte at fShipX, use:


Code:

     ld a,(fShipX)
     ld (curRow),a

However, if fShipY happens to be a byte that you need to load to curCol, make sure fShipX and fShipY are next to each other, then you can load both at the same time using your code with HL.

As to why it may cause a crash, if you load an out-of-bounds value to the cursor coordinates, the OS does not do any error checking (it assumes it shouldn't need to and that assumption is valid Razz) Make sure curRow is 0 to 7 and curCol is 0 to 15. As it is, curRow is a Y coordinate, and curCol is an X coordinate, so you might want to change the order of your fShipX Wink
  
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 2 of 2
» 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