I'm working on my own version of stack in assembly, and everything seems ok, but when I press enter (to place the blocks) the blocks always move once before actually stopping. Here is a gif that shows that, in which I try to place the blocks exactly on the blocks below it:

I think it might be a problem with my code, so I'll post it here:

Code:

#include "..\include\ti84pce.inc"
.assume ADL=1
.db     tExtTok,tAsm84CECmp
.org    userMem

   call _ClrScrnFull
   ;draw walls
   ld a,4
   call draw_wall
   ld a,21
   call draw_wall
   jp wallend
draw_wall:
   ld (curCol),a
   ld b,10
wall_loop:
   dec b
   ld a,$3A
   ld hl,curRow
   ld (hl),b
   call _PutMap
   jp nz,wall_loop
   ret
   
wallend:
   ;draw bottom stack
   ld a,9
   ld (curRow),a
   ld a,11
   ld (curCol),a
   ld a,$30
   call _PutC
   call _PutC
   call _PutC
   call _PutC
   ld a,8 ;initial height
loopa:
   ld (curRow),a
   ld a,(targetx)
   inc a
   ld (curCol),a
   ld a,$30
   ld hl, block_length
   ld b,(hl)
loopb:
   call _PutC
   djnz loopb
   
   ld hl,targetx
   ld c,(hl)
   inc c;increase c first so the player can't just hold down enter
loopc: ;while enter key not pressed
   call _GetCSC
   cp a,skEnter
   jp z,enter_pressed
   ;d will be the one to draw when going right, the one to erase when going left
   ;e will be the one to erase when going right, the one to draw when going left
   ld a,c
   ld hl,block_length
   add a,(hl)
   ld d,a
   ld e,c
smc1:
   inc c ;inc c ($0C) when going right, dec c ($0D) when going left
smc2:
   ld a,d ;ld a,d ($7A) when going right, ld a,e ($7B) when going left
   ld (curCol),a
   ld a,$30
   call _PutMap
smc3:
   ld a,e ;ld a,e ($7B) when going right, ld a,d ($7A) when going left
   ld (curCol),a
   ld a,$20
   call _PutMap
   ;time for delay
   ld hl,$0FFFFF
loopd:
   dec hl
   add hl,de
   or a,a
   sbc hl,de
   jp nz,loopd
   ;see if bumped into wall
smc4: ;you won't modify ld a, only the value after that, so only modify smc4+1
   ld a,17 ;bound left: 4, bound right: 21-block_length
   cp a,c
   jp z,reverse_dir
   jp loopc
   
reverse_dir:
   ld a,(direction)
   cp a,0
   jp z,turn_right
   ;turn left
   ld a,0
   ld (direction),a
   ld a,$0D
   ld (smc1),a
   ld a,$7B
   ld (smc2),a
   ld a,$7A
   ld (smc3),a
   ld a,4
   ld (smc4+1),a
   dec c
   jp loopc
turn_right:
   ld a,1
   ld (direction),a
   ld a,$0C
   ld (smc1),a
   ld a,$7A
   ld (smc2),a
   ld a,$7B
   ld (smc3),a
   ld a,21
   ld hl,block_length
   sub a,(hl)
   ld (smc4+1),a
   inc c
   jp loopc
enter_pressed:
   ld a,(targetx)
   cp a,c
   jp z,rightpos
   ;wrong pos
   
rightpos:
   ld a,(height)
   cp 0
   jp z,disp_gameover
   dec a
   ld (height),a
   jp loopa
disp_gameover:
   call _ClrScrnFull
smc6: ;modify youwin to youlose, not ld hl, so only do smc6+1
   ld hl,youwin
   ld a,0
   ld (curRow),a
   ld (curCol),a
   call _PutS
   ret
   
height:
.db 8
block_length:
.db 4
direction:
.db 1
targetx:
.db 11
youwin:
.db "You win!",0
youlose:
.db "You lose",0


Also, I'm kind of new to assembly, so a lot of things might not be optimized, and I'm not sure that is the best program structure possible.

Any help would be appreciated Very Happy
Let's just follow this code step by step. Let's say you pressed [ENTER]. Then it jumps to enter_pressed. There it first checks whether you were at the top line of the screen or not, and let's assume you weren't. Now you dec a and store it to the height BUT NOT TO THE CURROW. After that, you jump to loopa and there you inc a and display the 4 zeros. My idea is to also update (CurRow) before redrawing Smile

Anyway, here are some general tips:
- You have the variables block_length. It seems you aren't updating this value with the current code, so I recommend you just saying height .equ 8 before any code, instead of storing it in the memory. Saves at least 1 byte. Instead of getting it from the memory, just load it directly into a register.
- cp 0 can be "or a"
- dec b ... jp nz, **** can be djnz ****
- Use always (if possible) "jr" instead of "jp". Saves 2 bytes each and some clock cycles.

Hope this helps! Smile
PT_ wrote:
Let's just follow this code step by step. Let's say you pressed [ENTER]. Then it jumps to enter_pressed. There it first checks whether you were at the top line of the screen or not, and let's assume you weren't. Now you dec a and store it to the height BUT NOT TO THE CURROW. After that, you jump to loopa and there you inc a and display the 4 zeros. My idea is to also update (CurRow) before redrawing Smile

Anyway, here are some general tips:
- You have the variables block_length. It seems you aren't updating this value with the current code, so I recommend you just saying height .equ 8 before any code, instead of storing it in the memory. Saves at least 1 byte. Instead of getting it from the memory, just load it directly into a register.
- cp 0 can be "or a"
- dec b ... jp nz, **** can be djnz ****
- Use always (if possible) "jr" instead of "jp". Saves 2 bytes each and some clock cycles.

Hope this helps! Smile


Thanks a lot! I forgot to mention that the code isn't complete, I just want to solve this problem first before moving on.
block_length will be edited, and the reason I didn't use djnz in one section of the code was because after dec b, I needed to load b into (curRow).
Also, according to z80 heaven, jp takes up more space, but is slightly faster. Did that change for ez80?
Finally, the first line after loopa: is ld (curRow), a, so I'm sure (curRow) is loaded with the new height.
Just found out, I could replace ld a,0 with xor a,a.
  
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