[Z80] Draw loop not working

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
namco
Dizzy
Posts: 94
Joined: Mon Dec 04, 2017 8:55 pm

[Z80] Draw loop not working

Post by namco » Fri Aug 09, 2019 12:10 pm

I'm a little stuck on my project where I want to loop a draw line procedure but only restrict for say, 5 times and to do it on keypress. The drawing routine works but it doesn't stop after the keypress and the subsequent limit of 3 in this code. Also when I reset the emulator (CSpect or Zeus - which I use for debugging) the emulator seems to initiate the keypress without asking. Sometimes it's as though the session was recorded and waits the same time and initiates the keypress.

Thanks for your help! :)

Code: Select all

    org 32768

Start:
    call 0D6BH ; Calls BASIC CLS command

	; Set BORDER colour to Black
	ld a, 00
	out ($fe),a

	; Set PAPER colour to Black
	ld a,7 ; Black PAPER white INK
	ld (23693),a
	call 3503 ; Calls routine to clear the screen
	
	; init fire position
	; y - starts from 0 (bottom of screen)
	ld a,(vCount)
	ld b,a
	; x
	ld a,(hCount)
	ld c,a
	; call PLOT
	call $22DF
	
	; clear last key pressed before game start
	ld a,0
	ld (23560),a

game:

displaySprite:

	ld a,0
	
	ld a,22 ; Set A with PRINT AT command
	rst 10h ; Call

	ld a,20 ; Set A with 7 (Y coord)
	rst 10h

	ld a,20 ; Set A with 8 (X coord)
	rst 10h
	
	ld a,0
	
	ld a,(23560) ; get last key pressed
	
	; Get key set for keys 1 - 4
	;ld b,$f7
	;ld c,$fe
	;in a,(c)
	;push af

	
	ld bc,0
	ld c,a
	call 6683
	;pop af
	
	ld a,0
	
	ld a,(23560) ; get last key pressed
	
	;cp 190
	;call z,fireLaser
	
	;cp 30 ; cspect
	;call z,fireLaser
	
	cp 49
	call z,preLaserLoop	
	
	call delay
	
	jp game

; start call list section

delay:
	ld b,3
	delay0:
	halt
	djnz delay0
ret

preLaserLoop:
	ld b,3
fireLaser:
	push bc
	
	call buildLaser
	
	pop bc
	djnz fireLaser

ret

buildLaser:
	
	; drawStraight ($2477/9335)
	; stacka ($2D28)
	; stackbc ($2D2B/11563 or 5)
	; unstacka ($1E94)
	
	; Update PLOT as that is based on x,y for DRAW
	; Remember that ZX Spectrum resolution is 256x192 pixels
	
	; 175 for vertical
	; 255 for horizontal
	
	; Address for X 23677
	; Address for Y 23678
	
	;put x&y on calculator stack
	;push af -- this could be causing looping issues with the code
	
	; I may have to test the fact that different angles mean diff sides of screen hit
	; so possible lookup table after testing??
	
	; X start
	;ld a,0
	
	;ld a,(hCount)
	ld a,(23677)
	cp 254
	jp z,skipV
	jp nc,skipV
	ld a,1
	ld hl,1
	ld de,0
	ld de,(hCount)
	add hl,de
	ld (hCount),hl
	call $2D28
	; X end
	
	; Y start
	;ld a,0 ; init for vCount
	
	;ld a,(vCount)
	ld a, (23678)
	cp 174
	jp z,skipV
	jp nc,skipV
	ld a,0
	ld hl,0
	ld de,0
	ld de,(vCount)
	add hl,de
	ld (vCount),hl
	call $2D28
	; Y end
	
	ld a,0
	
	ld a,22 ; Set A with PRINT AT command
	rst 10h ; Call

	ld a,20 ; Set A with 7 (Y coord)
	rst 10h

	ld a,20 ; Set A with 8 (X coord)
	rst 10h
	
	;ld a,(vCount)
	ld a,(23677)
	
	ld bc,0
	ld c,a
	call 6683
	
	
	; call drawStraight
	call $2477
skipV:
	;pop af -- related to push af at line 110
	
ret

vCount db 50
hCount db 100
; end call list section

exit:
ret



;output_sna "draw-laser.sna"

end 32768
0 x

User avatar
Sokurah
Microbot
Posts: 110
Joined: Tue Nov 14, 2017 10:38 am

Re: [Z80] Draw loop not working

Post by Sokurah » Fri Aug 09, 2019 12:48 pm

Hi James,

I think your method of reading the keys is flawed.
Thy this instead. Use SPACE to activate.
Is this what you're looking for?
(note that I haven't cleaned up the code ... much ;) ).

Code: Select all

    org 32768

Start:
    call 0D6BH ; Calls BASIC CLS command

	; Set BORDER colour to Black
	ld a, 00
	out ($fe),a

	; Set PAPER colour to Black
	ld a,7 ; Black PAPER white INK
	ld (23693),a
	call 3503 ; Calls routine to clear the screen
	
	; init fire position
	; y - starts from 0 (bottom of screen)
	ld a,(vCount)
	ld b,a
	; x
	ld a,(hCount)
	ld c,a
	; call PLOT
	call $22DF
	
	; clear last key pressed before game start
	ld a,0
	ld (23560),a

game:

displaySprite:

	ld a,0
	
	ld a,22 ; Set A with PRINT AT command
	rst 10h ; Call

	ld a,20 ; Set A with 7 (Y coord)
	rst 10h

	ld a,20 ; Set A with 8 (X coord)
	rst 10h
	
	xor	a
	
	ld a,(23560) ; get last key pressed
	
	; Get key set for keys 1 - 4
	;ld b,$f7
	;ld c,$fe
	;in a,(c)
	;push af

	
	ld bc,0
	ld c,a
	call 6683
	;pop af
	
	ld   bc,$7ffe
 	in   a,(c)
	rra
	jr   c,game

	call preLaserLoop	
	call delay
	jp game

; start call list section

delay:	ld b,3
delay0:	halt
	djnz delay0
	ret

preLaserLoop:
	ld b,3
fireLaser:
	push bc
	call buildLaser
	pop bc
	djnz fireLaser
	ret

buildLaser:
	
	; drawStraight ($2477/9335)
	; stacka ($2D28)
	; stackbc ($2D2B/11563 or 5)
	; unstacka ($1E94)
	
	; Update PLOT as that is based on x,y for DRAW
	; Remember that ZX Spectrum resolution is 256x192 pixels
	
	; 175 for vertical
	; 255 for horizontal
	
	; Address for X 23677
	; Address for Y 23678
	
	;put x&y on calculator stack
	;push af -- this could be causing looping issues with the code
	
	; I may have to test the fact that different angles mean diff sides of screen hit
	; so possible lookup table after testing??
	
	; X start
	;ld a,0
	
	;ld a,(hCount)
	ld a,(23677)
	cp 254
	jp z,skipV
	jp nc,skipV
	ld a,1
	ld hl,1
	ld de,0
	ld de,(hCount)
	add hl,de
	ld (hCount),hl
	call $2D28
	; X end
	
	; Y start
	;ld a,0 ; init for vCount
	
	;ld a,(vCount)
	ld a, (23678)
	cp 174
	jp z,skipV
	jp nc,skipV
	ld a,0
	ld hl,0
	ld de,0
	ld de,(vCount)
	add hl,de
	ld (vCount),hl
	call $2D28
	; Y end
	
	ld a,0
	
	ld a,22 ; Set A with PRINT AT command
	rst 10h ; Call

	ld a,20 ; Set A with 7 (Y coord)
	rst 10h

	ld a,20 ; Set A with 8 (X coord)
	rst 10h
	
	;ld a,(vCount)
	ld a,(23677)
	
	ld bc,0
	ld c,a
	call 6683
	
	
	; call drawStraight
	call $2477
skipV:
	;pop af -- related to push af at line 110
	
ret

vCount db 50
hCount db 100
; end call list section

exit:
ret



;output_sna "draw-laser.sna"

end 32768
0 x
Website: Tardis Remakes / Mostly remakes of Arcade and ZX Spectrum games.
My games for the Spectrum: Dingo, The Speccies, The Speccies 2, Vallation & Sqij.
Twitter: Sokurah

User avatar
Ast A. Moore
Dynamite Dan
Posts: 1134
Joined: Mon Nov 13, 2017 3:16 pm

Re: [Z80] Draw loop not working

Post by Ast A. Moore » Fri Aug 09, 2019 12:53 pm

Without getting into detailed analysis of your code, I can tell you right off the bat, that using the LAST_K system variable is usually a bad idea. A much more reliable and straightforward way of detecting a keypress is to actually scan the keyboard yourself. You can use the ROM routine if you don’t want to decode keypresses yourself:

Code: Select all

key_check
		call $28e		;use KEY-SCAN to fetch key code and load it into DE

		ld a,e			;load A with E to compare
		cp $ff			;if it’s FFh (no key pressed)
		jr z,key_check		;try again
If you’re not interested in the key code, then it’s even simpler:

Code: Select all

1$		call $28e		;fetch keypress status
		inc e
		jr z,1$
If you’re waiting for a particular key, then you can simply read from port 254 and mask off the top three bits. You’ll need to know which high byte to use, though. For example:

Code: Select all

		ld a,$f7		;is it “1” key (1–5 half-row)?
		in a,($fe)
		and 1
		call z,one_key_routine
0 x
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.

namco
Dizzy
Posts: 94
Joined: Mon Dec 04, 2017 8:55 pm

Re: [Z80] Draw loop not working

Post by namco » Tue Aug 13, 2019 12:31 pm

Thanks all. :D

I've not had chance to look back at my code yet but I will try and have a look over the weekend and will update.
0 x

namco
Dizzy
Posts: 94
Joined: Mon Dec 04, 2017 8:55 pm

Re: [Z80] Draw loop not working

Post by namco » Tue Aug 27, 2019 12:28 pm

Thanks to both for your help. I've also found out why Zeus was "copying my sessions" even when I'd not pressed anything. For some reason "Enable Replay" was checked. Unchecking this stopped it from mimicking my sessions.

On a related note. When I try this on CSpect and ZesarUX without the rom enabled, the game runs fine but when the rom is enabled the game doesn't work. Am I missing something?

[edit]: Just to clarify on the "rom". That is referring to the zxnext rom where you press space(?) to go to the main copyright screen.
0 x

Post Reply