Omnimaga

Calculator Community => TI Calculators => ASM => Topic started by: Munchor on May 13, 2011, 03:38:10 pm

Title: David's Z80 Assembly Questions
Post by: Munchor on May 13, 2011, 03:38:10 pm
I decided to create a topic to gather all my z80 asm questions since I have a few and I'm still learning.

First of all, I'd like you guys to know how advanced I am, this was my (best?) program:

Code: [Select]
.nolist 
#include "ti83plus.inc" 
.list 
   .org userMem-2 
   .db $BB,$6D 
Init: 
  B_CALL _ClrLCDFull 
   
  ld hl,0
  ld (curCol), hl
  ld hl,Welcome
  B_CALL _PutS

  B_CALL _GetKey 
   
  cp kEnter 
   
  jr z,Win 
   
  B_CALL _ClrLCDFull 

  ld hl,0 
  ld (curCol), hl
   
  ld hl,LoseTxt 
   
  B_CALL _PutS 
   
  B_CALL _GetKey 
  B_CALL _ClrLCDFull 
  ret 

LoseTxt: 
  .db "LOSE",0   
   
Win: 
  B_CALL _ClrLCDFull

  ld hl,0 
  ld (curCol), hl
   
  ld hl,WinTxt

  B_CALL _PutS
  B_CALL _GetKey
  B_CALL _ClrLCDFull
  ret
WinTxt:
  .db "WIN",0
Welcome:
  .db "Press ",$C1,"ENTER]",0

If you run it, it asks you to press [ENTER], if you do, you win, if you don't, well you lose The Game.

My first question is how to make Axe-like loops in Asm? In Axe, I'd do something like Repeat getKey(15). How would I do that in Assembly?

Code: [Select]
TitleScreen:
 ;Title Screen code
Loop:
 ;Code
 cp kClear
 jr z, TitleScreen
 jr Loop

I thought of this, but I can't test it right now. Thanks :D

<Edit>
I actually tried this and it looped forever, freezing my calc:

Code: [Select]
Start:
  cp kClear
  jr z, End
  jr Start
End:
  ret

I'm pretty sure I'm doing something wrong, but I'm a bit rusty at z80 asm.
Title: Re: David's Z80 Assembly Questions
Post by: Ashbad on May 13, 2011, 03:47:50 pm
well, some simple loops:

for statement --

Code: [Select]
   LD B, number_of_loops
@
   ; code
   DJNZ {-1@}
@

Your getkey loop:

Code: [Select]
@
   BCALL(GetKey)
   CP kClear
   JP NZ, {-1@}
@
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 13, 2011, 04:11:11 pm
Oh my how stupid, I forgot about B_CALL (_GetKey).

Thanks a lot for reminding me of that, this worked:

Code: [Select]
Start:
  B_CALL (_GetKey)
  cp kClear
  jr z, End
  jr Start
End:
  ret

:)

I have a very big problem now, I know how to display images using iPutSprite, but I wanted to make a cursor. My problem was clearing the screen in the end of the loop (it wiped out some registers).
Title: Re: David's Z80 Assembly Questions
Post by: lookitsan00b on May 13, 2011, 04:55:10 pm
Actually, if you want something similar to getkey(15), you might want:
Code: [Select]
jr loop_Condition
loop:
 ;code
loop_Condition:
 b_call(getCSC) ;getCSC doesn't wait for a key to be pressed, _GetKey will.
 cp 15             ;Im not sure what the equate is called, prolly skClear
 jr nz,loop

As for wiping out registers, push and pop really help :D
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 13, 2011, 04:57:48 pm
Actually, if you want something similar to getkey(15), you might want:
Code: [Select]
jr loop_Condition
loop:
 ;code
loop_Condition:
 b_call(getCSC) ;getCSC doesn't wait for a key to be pressed, _GetKey will.
 cp 15             ;Im not sure what the equate is called, prolly skClear
 jr nz,loop

As for wiping out registers, push and pop really help :D

I guess that is indeed better. Also, kClear works for me.

Thanks to the getCSC bcall trick I think I can now make my cursor program.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 14, 2011, 04:30:09 am
Here's what I did:

Code: [Select]
Start:
  B_CALL (_ClrLCDFull)
Loop:
  B_CALL (_GetKey)
  cp kClear
  jr z,End
  kr Loop
End:
  ret

So this will wait a for a [CLEAR] press and then close the loop.

I tried changing it to this:

Code: [Select]
Start:
  B_CALL (_ClrLCDFull)
Loop:
  B_CALL (_GetCSC)          ;The change is done here
  cp kClear
  jr z,End
  kr Loop
End:
  ret

And it freezes the calculator. Am I not using GetCSC the right way?
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 14, 2011, 09:41:07 am
_GetCSC uses different key codes than _GetKey. You should check for skClear (15), not kClear (9).
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 15, 2011, 07:25:26 am
I have a problem assembling now:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld ix,MyImage          ;Image
  ld b,8                 ;Height
  ld a,0                 ;X
  ld l,0                 ;Y

  call iPutSprite
  call iFastCopy

Loop:
  B_CALL (_GetKey)
  cp kClear
  jr z,End
  jr Loop
 
MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF
 
End:
  ret

That's my code, I'm trying to display an image, here's the output from the assembler:

Code: [Select]
----------------------------------
----- Assembling display1 for the TI-83/84 Plus...
Brass Z80 Assembler 1.0.4.11 - Ben Ryves 2005-2006
--------------------------------------------------
Assembling...
Error: Unsupported directive '.end:'. [zztemp.asm:27]
Pass 1 complete. (636ms).
Pass 1 failed, pass 2 therefore skipped.
Errors: 1, Warnings: 0.

I don't have any '.end' in my code :(
Title: Re: David's Z80 Assembly Questions
Post by: JosJuice on May 15, 2011, 07:26:56 am
Add an .end at the end.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 15, 2011, 07:32:33 am
This worked for me:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld ix,MyImage          ;Image
  ld b,8                 ;Height
  ld a,0                 ;X
  ld l,0                 ;Y

  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the bugger

  jr Loop

Loop:                    ;Waits for the user to press [CLEAR]
  B_CALL (_GetCSC)
  cp skClear
  ;jr z,End
  jr Loop
 
MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

Yes! I displayed an image! Now I'll try and make it move with the arrows.

<Edit>

I tried this to make the sprite move right when the user presses the right key:

Code: [Select]
Init:
  B_CALL (_ClrLCDFull)
  ld ix,MyImage          ;Image
  ld b,8                 ;Height
  ld a,0                 ;X
  ld l,0                 ;Y

  jr Loop

Loop:                    ;Waits for the user to press [CLEAR]
  B_CALL (_GetCSC)
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the bugger
 
  cp skRight
  call z,MoveRight
 
  jr Loop

MoveRight:
  inc l

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

However, the sprite isn't even displayed in the right place, is it because GetCSC exterminates registers?
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 15, 2011, 09:25:34 am
It's actually because END is a reserved keyword in Brass. You used it as a label in your original code, and Brass got confused why it had a colon after it.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 15, 2011, 09:32:08 am
Ah thanks a lot Deep Thought, that explains it, Mimas didn't have that problem.

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)

Loop:                    ;Waits for the user to press [CLEAR]
  B_CALL (_GetCSC)
 
  ld b,8
  ld ix,MyImage
  ld l,0
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the bugger
 
  cp skRight
  call z,MoveRight

  B_CALL (_ClrLCDFull)
 
  jr Loop

MoveRight:
  inc a

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

I tried this to display an image and make it move right when I press RIGHT. However, it has some problems.

I don't know what registers BCalls wipe out, where can I find such info?

Either way, when I press [CLEAR] with that code weird stuff happens.

Any ideas, I'm trying to make a sort of a cursor.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 15, 2011, 09:39:29 am
Ah thanks a lot Deep Thought, that explains it, Mimas didn't have that problem.

Blame TASM. They required the line ".end", then a newline, just to know that the file is done. Brass reserved "end" as a keyword for compatibility.

I don't know what registers BCalls wipe out, where can I find such info?

Either way, when I press [CLEAR] with that code weird stuff happens.

Pretty much everything you need is on WikiTI (http://wikiti.brandonw.net/index.php?title=Category:83Plus:BCALLs:By_Name). Just find the bcall and look up "Destroys".

And if you're ever too lazy to check, just assume it destroys everything. That's what a lot of them do, anyway. Plus it avoids issues where TI releases a new OS where a certain bcall uses more registers than before, and now you gotta rewrite the whole thing.

Any ideas, I'm trying to make a sort of a cursor.

Have you tried the DCS libs? It makes graphical stuff like that a ton easier.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 15, 2011, 09:42:07 am
I am using DCS Libs, iPutSprite and iFastCopy, but those are more like Ion.

Thanks a lot for WikiTI link I had forgotten about it.

I will take a look at more graphical functions of DCS Libs then.

I want a cursor, but not DCS's by the way, also:

Code: [Select]
B_CALL _ClrLCDFull

Destroys
All

xD
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 15, 2011, 09:47:06 am
Code: [Select]
B_CALL _ClrLCDFull

Destroys
All

xD

A lot of them do that. Even ones you'd expect to be saved (for whatever reason) often get destroyed. Like _DispHL: what it does is display the value of HL in decimal on the screen. You'd expect it to keep HL intact, so you can keep working on it, but it doesn't. It destroys everything except BC.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 15, 2011, 10:05:19 am
My goal is now to try and push b and then pop it so that everything goes allright.

Here's my plan:

Code: [Select]
Loop:
  ;Pop hl and save it to b, how do do this?
  ;Display image
  ;Store b to hl and then push it
  ;ClrLCDFull
  jr Loop

How to do the first and latter (the push and pop)? I can push and pop, but only hl, de, bc, I mean, 2 byte registers.

How can I do that with 1 byte registers? Thanks
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 15, 2011, 10:14:03 am
Just do it with loads.

Or if you want to make things easier, just push it and pop it and store HL on the stack. No need to move it to B.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 15, 2011, 01:17:49 pm
I made this code with the help of Runer and Deep Thought:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:                    ;Waits for the user to press [CLEAR]
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)
 
  B_CALL (_GetCSC)
  pop hl
  cp skRight
  call z,CheckMoveRight
 
  jr Loop
 
CheckMoveRight:
  ld a,h
  cp 87
 
  call c,MoveRight
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

You press right and the image goes right until it can't go more (X=88).

It doesn't work so well though :(
It works like the Catalog, when I first press it goes but only if I keep pressing the key it will go fast.
How can I change that? I'm using CSC...
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 15, 2011, 01:20:10 pm
CSC uses a system interrupt (TI's) that does that pause before repeating a key (it's part of the GetCSC routine). I think there's a way to change the pause (you could disable it entirely), but I don't know how that's done.

But if you're willing to work with direct input, you can do whatever you want from the key port.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 15, 2011, 01:22:35 pm
CSC uses a system interrupt (TI's) that does that pause before repeating a key (it's part of the GetCSC routine). I think there's a way to change the pause (you could disable it entirely), but I don't know how that's done.

But if you're willing to work with direct input, you can do whatever you want from the key port.

That's not B_CALL _GetKey is it? I think not :(

I thought CSC was the way to go for games :P
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 15, 2011, 01:24:37 pm
CSC uses a system interrupt (TI's) that does that pause before repeating a key (it's part of the GetCSC routine). I think there's a way to change the pause (you could disable it entirely), but I don't know how that's done.

But if you're willing to work with direct input, you can do whatever you want from the key port.

That's not B_CALL _GetKey is it? I think not :(

Nope, it's this: Low Level Key Input (http://eeezor.ec3club.tk/Files/Resources/Tutorials/ASMin28Days/lesson/day22.html)

On the other hand, Xeda made a Speedy Keys program (http://www.ticalc.org/archives/files/fileinfo/429/42913.html) that changes the pause. You should ask her how she did it.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 16, 2011, 09:14:52 am
I tried this code:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:                    ;Waits for the user to press [CLEAR]
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)
 
  ld a,$FB
  out (1),a
  in a,(1)
  cp $FB
  call z,CheckMoveRight
 
  jr Loop
 
CheckMoveRight:
  ld a,h
  cp 87
 
  call c,MoveRight
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

For direct input, but it doesn't seem to work, the image appears and then disappears quickly and press RIGHT ($FD) does nothing. I think it may also have something related to the stack.

Any ideas?

Thanks

<EDIT>

I added a pop hl and now it displays the image, but nothing happens when I press RIGHT:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:                    ;Waits for the user to press [CLEAR]
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)
 
  pop hl                             :Added pop hl here
   
  ld a,$FB
  out (1),a
  in a,(1)
  cp $FB
  call z,CheckMoveRight
 
  jr Loop
 
CheckMoveRight:
  ld a,h
  cp 87
 
  call c,MoveRight
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

Here's the direct getkey code:

Code: [Select]
ld a,$FB
  out (1),a
  in a,(1)
  cp $FB
  call z,CheckMoveRight
 
  jr Loop
 
CheckMoveRight:
  ld a,h
  cp 87
 
  call c,MoveRight
  ret

$FB is the RIGHT keycode according to Z80 Asm in 28 Days.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 17, 2011, 08:11:10 am
Code: [Select]
  ld a,$FE
  out (1),a
  nop
  nop
  in a,(1)
  cp $FB
  call z,CheckMoveRight
 
  ld a,$FE
  out (1),a
  nop
  nop
  in a,(1)
  cp $FD
  call z,CheckMoveLeft
 
  ld a,$FE
  out (1),a
  nop
  nop
  in a,(1)
  cp $FE
  call z,CheckMoveDown
 
  ld a,$FE
  out (1),a
  nop
  nop
  in a,(1)
  cp $F7
  call z,CheckMoveUp

This getkeys code is currently not working for multi keys pressing so it won't go diagonal ways if I press both RIGHT and UP.

I also tried this, but also doesn't work:

Code: [Select]
ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 0,a
  call z,CheckMoveRight
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveDown
 
  bit 3,a
  call z,CheckMoveUp
Title: Re: David's Z80 Assembly Questions
Post by: Hot_Dog on May 18, 2011, 02:26:18 pm
Make sure that register A is not changed by the time your subroutine ends.  Otherwise you should save your value for A
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 18, 2011, 02:39:01 pm
I did it, so it looks like this now:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)
 
  pop hl
   
  ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 0,a
  call z,CheckMoveRight
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveDown
 
  bit 3,a
  call z,CheckMoveUp
 
  jr Loop
 
CheckMoveUp:
  push af
  ld a,l
  cp 0
 
  call nz,MoveUp
  pop af
  ret

MoveUp:
  dec l
  dec l
  ret

CheckMoveDown:
  push af
  ld a,l
  cp 56
 
  call nz,MoveDown
  pop af
  ret

MoveDown:
  inc l
  inc l
  ret

CheckMoveLeft:
  push af
  ld a,h
  cp 0
 
  call nz,MoveLeft
  pop af
  ret

MoveLeft:
  dec h
  dec h
  ret

CheckMoveRight:
  push af
  ld a,h
  cp 87
 
  call c,MoveRight
  pop af
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

It doesn't crash and some of the getkeys work but when i press <DOWN> it goes right and I can't always go right, and multi keypressing only works sometimes. What am I doing wrong?

Thanks in advance.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 18, 2011, 06:40:22 pm
Bit 0 is down, bit 2 is right.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 02:54:51 am
Bit 0 is down, bit 2 is right.

Thanks a lot, that sure worked!

I sort of get it because of the table I can see here (http://eeezor.ec3club.tk/Files/Resources/Tutorials/ASMin28Days/lesson/day22.html). The lowest value is stored in the lower bit (0).

The order is $FE, $FD, $FE, $F7. So 0,1,2,3, Down, Left,Right, Up.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 19, 2011, 10:32:38 am
Hence why with _GetCSC (and Axe), down, left, right, and up are 1, 2, 3, and 4 :)
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 10:36:14 am
Hence why with _GetCSC (and Axe), down, left, right, and up are 1, 2, 3, and 4 :)

Ah I see :D

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)      ;Clears the graph screen
 
  pop hl
 
  ;Start of gravity code
  push af
  push hl
 
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  and (hl)
  call z,SetGravity      ;If pixel below image is white, y=y+1
 
  pop hl
  pop af
  ;End of gravity code
 
  ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 0,a
  call z,CheckMoveDown
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveRight
 
  bit 3,a
  call z,CheckMoveUp
 
  jp Loop

SetGravity:
  inc l
  ret

CheckMoveUp:
  push af
  ld a,l
  cp 0
 
  call nz,MoveUp
  pop af
  ret

MoveUp:
  dec l
  dec l
  ret

CheckMoveDown:
  push af
  ld a,l
  cp 56
 
  call nz,MoveDown
  pop af
  ret

MoveDown:
  inc l
  inc l
  ret

CheckMoveLeft:
  push af
  ld a,h
  cp 0
 
  call nz,MoveLeft
  pop af
  ret

MoveLeft:
  dec h
  dec h
  ret

CheckMoveRight:
  push af
  ld a,h
  cp 87
 
  call c,MoveRight
  pop af
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

I have new code, I need to decrease the y position of the sprite by 1 if the pixel below it is white to give a gravity effect. I'm using iGetSprite and have something wrong because there is no gravity at all.

What am I doing wrong?

Thanks in advance.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 19, 2011, 10:42:58 am
Where it is now, CALL z,SetGravity INC's the L returned by iGetPixel, which is then destroyed by the POP HL right after it. You never actually INC the L that you use for a Y-value.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 10:52:28 am
Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)      ;Clears the graph screen
 
  pop hl
 
  ;Start of gravity code
  push af
  push hl
 
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  pop hl
  pop af
 
  and (hl)
  call z,SetGravity      ;If pixel below image is white, y=y+1
 
 
  ;End of gravity code
 
  ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 0,a
  call z,CheckMoveDown
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveRight
 
  bit 3,a
  call z,CheckMoveUp
 
  jp Loop

SetGravity:
  inc l
  ret

CheckMoveUp:
  push af
  ld a,l
  cp 0
 
  call nz,MoveUp
  pop af
  ret

MoveUp:
  dec l
  dec l
  ret

CheckMoveDown:
  push af
  ld a,l
  cp 56
 
  call nz,MoveDown
  pop af
  ret

MoveDown:
  inc l
  inc l
  ret

CheckMoveLeft:
  push af
  ld a,h
  cp 0
 
  call nz,MoveLeft
  pop af
  ret

MoveLeft:
  dec h
  dec h
  ret

CheckMoveRight:
  push af
  ld a,h
  cp 87
 
  call c,MoveRight
  pop af
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

Fixed. Thanks a lot Deep Thought.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 19, 2011, 11:02:09 am
Np, and another thing: Don't be afraid to use gotos (JP/JR) in ASM. You could save a couple of bytes and some clock cycles by putting your MoveUp/MoveDown/MoveLeft/MoveRight routines inline (instead of in a separate CALL'd subroutine).
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 11:04:28 am
Np, and another thing: Don't be afraid to use gotos (JP/JR) in ASM. You could save a couple of bytes and some clock cycles by putting your MoveUp/MoveDown/MoveLeft/MoveRight routines inline (instead of in a separate CALL'd subroutine).

Ah yeah I only learnt how to use branched if's a while ago.

I have new code and a new problem:

Code: [Select]
;Draw line code
  push af
  push hl
  ld h,0
  ld l,63
  ld d,95
  ld e,63
  ld a,1
 
  call fastline
 
  pop hl
  pop af 
  ;End of draw line code
 
  ;Start of gravity code
  push af
  push hl
 
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  pop hl
  pop af
 
  and (hl)
  call z,SetGravity      ;If pixel below image is white, y=y+1
  ;End of gravity code
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 19, 2011, 11:12:40 am
POP HL \ POP AF now destroys the values returned by iGetPixel.

How about this: Use POP DE to put the value that was originally in HL (the X and Y coordinates) into DE. Then INC E instead of L in your SetGravity code. At the end of the routine, load DE into HL.
Title: Re: David's Z80 Assembly Questions
Post by: calc84maniac on May 19, 2011, 11:15:26 am
You're destroying the outputs of iGetPixel when you pop hl and pop af. Note that simply moving and (hl) before these pops won't help, because pop af changes the flags register. What does A hold, anyway?
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 11:15:50 am
That's actually a very good idea. I tried it but it's not working:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)      ;Clears the graph screen
 
  pop hl
 
  ;Draw line code
  push af
  push hl
  ld h,0
  ld l,63
  ld d,95
  ld e,63
  ld a,1
 
  call fastline
 
  pop hl
  pop af 
  ;End of draw line code
 
  ;Start of gravity code
  push af
  push hl
 
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  pop de
 
  pop af
 
  and (hl)
  call z,SetGravity      ;If pixel below image is white, y=y+1
  ld l,e
  ld h,d
  ;End of gravity code
 
  ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 0,a
  call z,CheckMoveDown
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveRight
 
  bit 3,a
  call z,CheckMoveUp
 
  jp Loop

SetGravity:
  inc e
  ret

CheckMoveUp:
  push af
  ld a,l
  cp 0
 
  call nz,MoveUp
  pop af
  ret

MoveUp:
  dec l
  dec l
  ret

CheckMoveDown:
  push af
  ld a,l
  cp 56
 
  call nz,MoveDown
  pop af
  ret

MoveDown:
  inc l
  inc l
  ret

CheckMoveLeft:
  push af
  ld a,h
  cp 0
 
  call nz,MoveLeft
  pop af
  ret

MoveLeft:
  dec h
  dec h
  ret

CheckMoveRight:
  push af
  ld a,h
  cp 87
 
  call c,MoveRight
  pop af
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

Am I loading DE into HL the right way?

@calc84maniac: a is the X of the sprite.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 19, 2011, 11:27:13 am
POP AF still destroys A before you do the AND (HL) check. Move POP AF after all the gravity code.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 11:36:10 am
Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)      ;Clears the graph screen
 
  ;Draw line code
  ld h,0
  ld l,63
  ld d,95
  ld e,63
  ld a,1
 
  call fastline
  ;End of draw line code
 
  ;Start of gravity code
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  and (hl)
  call z,SetGravity      ;If pixel below image is white, y=y+1
 
  ;End of gravity code
 
  pop hl
 
  ;Getkeys code
  ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveRight
 
  bit 3,a
  call z,CheckMoveUp
  ;End of getkeys code
 
  jp Loop

SetGravity:
  inc l
  ret

CheckMoveUp:
  push af
  ld a,l
  cp 0
 
  call nz,MoveUp
  pop af
  ret

MoveUp:
  dec l
  dec l
  ret
 
CheckMoveLeft:
  push af
  ld a,h
  cp 0
 
  call nz,MoveLeft
  pop af
  ret

MoveLeft:
  dec h
  dec h
  ret

CheckMoveRight:
  push af
  ld a,h
  cp 87
 
  call c,MoveRight
  pop af
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

I found out I don't need to push/pop af and did that, the gravity doesn't work at all though.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 19, 2011, 11:50:50 am
You still have POP HL after the SetGravity call, so anything you do to L in SetGravity is still destroyed.
Title: Re: David's Z80 Assembly Questions
Post by: Hot_Dog on May 19, 2011, 12:08:23 pm
Btw Scout, you're learning ASM as fast as I was, so give yourself a pat on the back.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 12:16:37 pm
Btw Scout, you're learning ASM as fast as I was, so give yourself a pat on the back.
/me pats himself on the back.

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)      ;Clears the graph screen
 
  ;Draw line code
  ld h,0
  ld l,63
  ld d,95
  ld e,63
  ld a,1
 
  call fastline
  ;End of draw line code
 
  ;Start of gravity code
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  pop hl
  call z,SetGravity      ;If pixel below image is white, y=y+1
 
  ;End of gravity code
 
  ;Getkeys code
  ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveRight
 
  bit 3,a
  call z,CheckMoveUp
  ;End of getkeys code
 
  jp Loop

SetGravity:
  inc l
  ret

CheckMoveUp:
  push af
  ld a,l
  cp 0
 
  call nz,MoveUp
  pop af
  ret

MoveUp:
  dec l
  dec l
  ret
 
CheckMoveLeft:
  push af
  ld a,h
  cp 0
 
  call nz,MoveLeft
  pop af
  ret

MoveLeft:
  dec h
  dec h
  ret

CheckMoveRight:
  push af
  ld a,h
  cp 87
 
  call c,MoveRight
  pop af
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF

Here's my updated code, the gravity works but the main sprite still goes through the black line, I'm pretty sure I'm checking the pixel beneath the sprite the wrong way:

Code: [Select]
;Start of gravity code
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  pop hl
  call z,SetGravity      ;If pixel below image is white, y=y+1
 
  ;End of gravity code

Basically what I want to do is Y-1 if there is no ON pixel beneath the sprite.

So I did this:

Code: [Select]
call iGetPixel
 
  and (hl)
  call z,SetGravity      ;If pixel below image is white, y=y+1
 
  ;End of gravity code
 
  pop hl                  ;Get old hl value
 
  ld a,l                  ;Set a to l to do some math with ti
  add a,e              ;I add e to a
 
  ld l,a            ;I set l to a, so if anything was increased to 'e', the 'y' position is also increased
...
SetGravity:
  ld e,0
  inc e
  ret

However, the sprite stills goes through the black line.
Title: Re: David's Z80 Assembly Questions
Post by: Deep Toaster on May 19, 2011, 01:00:33 pm
ADD A,E adds E regardless of whether or not SetGravity was called. E is never set to zero except in SetGravity, which means it's still 1 when you do that. Just move LD E,0 to the beginning (right before AND (HL)) and it should work.
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 19, 2011, 01:02:50 pm
I tried it Deep Thought as I got what you said (e is not being decreased when the pixel is white), but the square still goes through the line:

Code: [Select]
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
  ld hl,0
 
Loop:
 
  ld b,8
  ld ix,MyImage
  ld a,h
  push hl
 
  call iPutSprite        ;Display Image
  call iFastCopy         ;Put it in the buffer
 
  B_CALL(_GrBufClr)      ;Clears the graph screen
 
  ;Draw line code
  ld h,0
  ld l,63
  ld d,95
  ld e,63
  ld a,1
 
  call fastline
  ;End of draw line code
 
  ;Start of gravity code
  ld a,8
  add a,l
  ld e,a                 ;Sets e to y+8
 
  ld a,h                 ;Sets a to x
 
  call iGetPixel
 
  ld e,0
  and (hl)
  call z,SetGravity      ;If pixel below image is white, y=y+1
 
  ;End of gravity code
 
  pop hl
 
  ld a,l
  add a,e
 
  ld l,a
 
  ;Getkeys code
  ld a,$FE
  out (1),a
  nop
  nop
  nop
  in a,(1)
 
  bit 1,a
  call z,CheckMoveLeft
 
  bit 2,a
  call z,CheckMoveRight
 
  bit 3,a
  call z,CheckMoveUp
  ;End of getkeys code
 
  jp Loop

SetGravity:
  ld e,0
  inc e
  ret

CheckMoveUp:
  push af
  ld a,l
  cp 0
 
  call nz,MoveUp
  pop af
  ret

MoveUp:
  dec l
  dec l
  ret
 
CheckMoveLeft:
  push af
  ld a,h
  cp 0
 
  call nz,MoveLeft
  pop af
  ret

MoveLeft:
  dec h
  dec h
  ret

CheckMoveRight:
  push af
  ld a,h
  cp 87
 
  call c,MoveRight
  pop af
  ret

MoveRight:
  inc h
  inc h
  ret

MyImage:
  .db $FF,$81,$81,$81,$81,$81,$81,$FF
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 21, 2011, 03:41:19 pm
Bump?
Title: Re: David's Z80 Assembly Questions
Post by: Munchor on May 27, 2011, 05:12:25 pm
Code: [Select]
; Written for Doors CS 7.0 and higher
.nolist
#include "ti83plus.inc"
#include "dcs7.inc"
.list
   .org userMem-2
   .db $BB,$6D
Init:
  B_CALL (_ClrLCDFull)
 
  set textWrite,(IY + sGrFlags)
  SET fracDrawLFont,(IY + fontFlags)
 
  ld a,1
  ld (penCol), a
  ld a,1
  ld (penRow), a
  ld hl,Title
  B_CALL (_VPutS)
 
  ld h,0
  ld l,9
  ld d,95
  ld e,9
  ld a,1
  call fastline
 
  call iFastCopy
 
  B_CALL (_GetKey)
 
  ret
 
Title:
  .db "Hello World",0

I managed to display the text where I wanted it, the way I wanted it.

Now I want to display the value I have in hl (I will get it through a Bcall). How can I display a value of HL in that screen?

I know I can use DispHL, but DispHL is homescreen, so how to display it there?

Thanks

I also got this routine in Axe, can it be of use?

Code: [Select]
p_DispInt:
.db 3
B_CALL(_DispHL)