Gamecoding in machinecode on a ZX81.

Any discussions related to the creation of new hardware or software for the ZX80 or ZX81
MrVertigo
Posts: 105
Joined: Fri May 27, 2022 9:06 pm

Re: Gamecoding in machinecode on a ZX81.

Post by MrVertigo »

Thanks!
bru65pag
Posts: 23
Joined: Sun Dec 20, 2015 12:09 pm

Re: Gamecoding in machinecode on a ZX81.

Post by bru65pag »

First, thanks a lot to Dr Beep for this nice tutorial.

My comment refers to chapter 6 of the tutorial. The random routine is not random on a ZX81 simulator (I tested with EightyOne and ZEsarUX). My simple explanation (correct me if I'm wrong) is that every time you load the file, the sequence is identical in the simulator, and the same FRAME value is read. It would not be the same if we were only loading the game, and had to enter RUN to start it, in which case FRAME could have a different value every time. For this reason, I altered the game a bit, and ask for the user to hit a key to start the game, allowing the FRAME value to become more random (the waitforkey loop routine is from bob @ https://bobs8bb.wordpress.com/). Here is the altered game:

Code: Select all

gamecode

waitforkey
	ld a,0
	in a,(254)
	cpl
	and %00011111
	jp z, waitforkey

; clear the "PRESS A KEY" message
	ld bc,#0305
	call field
	ld b,11				; number of chars to clear
loop_clear
	ld (hl),128
	inc hl
	djnz loop_clear


	ld bc,#0101			; B=1, C=1, first position on the screen
newdot
	push bc				; save xy player 
	call rnd			; get a random number	
	ld b,a				; set as Y
	call rnd			; get a next random number
	ld c,a				; st as X
	call field
	ld (hl),27+128		; place an inverted dot
	pop bc				; get xy player

moveloop
	call field
	ld (hl),"O"+101	; we write a "O" INVERTED on the screen

	push hl	
	ld hl,frames		; make hl point to the timecounter
	ld a,(hl)		; get the timecounter in A
	sub 2			; take of 2, the number we want to test
wfr
	cp (hl)			; test if the value is the same
	jr nz,wfr		; NOW WE WAIT UNTIL FRAMES MATCHES A!
	pop hl

	push bc			; NOW WE NEED TO SAVE BC!

wkey
	ld bc,(lastk)		; get key information
	ld a,c			; copy C in A to keep C
	inc a			; Test if NOKEY pressed
	jr z,wkey		; NO KEY, wait for key

	ld (hl),128		; we pressed a key, so we erase the old position

	call #7bd		; BC holds info about key, ROM can translated this here
	pop bc
	ld a,(hl)		; get character

	cp "O"-27		; did we press the "O"?
	jr nz,right		; we didn't go left
left
	dec c
	jr nz,okmove
	inc c			
	jr okmove
right
	cp "P"-27		; did we press "P", right
	jr nz,up		
	inc c			; move right
	ld a,c			; get new position
	cp 21			; test out of screen
	jr nz,okmove		; if not, move allowed
	dec c
	jr okmove
up
	cp "A"-27
	jr nz,down
	dec b
	jr nz,okmove
	inc b			
	jr okmove
down
	cp "Q"-27		; did we press "A", down
	jr nz,okmove		
	inc b			; move down
	ld a,b			; get new position
	cp 21			; test out of screen
	jr nz,okmove		; if not, move allowed
	dec b
okmove
	jr moveloop		; stay in playloop
		

; BC = XY, return HL=field on screen
field
	push bc			; save Y and X
	ld hl,screen-21-1	; always 1xY and 1xX added, line is 20+HALT
	ld de,21		; the size of 1 line (20 + HALT)
frow
	add hl,de		; add rows until B=0
	djnz frow		; DEC B, JR NZ frow
	add hl,bc		; B now 0, C is X, so HL now field on screen
	pop bc			; get back original Y X
	ret

rnd
	ld de,0			; get the pointer in ROM
	ld hl,(frames)		; for randomness get framecounter
	add hl,de		; add framecounter
	dec hl			; when framecounter is unchanged make sure a change is done
	ld a,h			; H can have any value, but ROM is #0000-#1FFF
	and #0f			; only #0000-#0f00 is what we use
	ld h,a			; set pointer back within ROM
	ld (rnd+1),hl		; save current pointer (selfmodifying code!!!)
	ld a,(hl)		; get value in ROM
range
	sub 20			; we need 0-19 only
	jr nc,range
	adc a,20		; undo last subtraction, range 1-20
	ret			; back to mainprogram


; the display file, Code the lines needed.
dfile 	db 118

; each line has text and a Newline
screen
	block 20, 128	; block places 20x character 128,inverted space
	db 118
	block 20, 128
	db 118
	block 4, 128
	db "P"+101,"R"+101,"E"+101,"S"+101,"S"+101, 128,"A"+101,128,"K"+101,"E"+101,"Y"+101
	block 5, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
	block 20, 128
	db 118
MrVertigo
Posts: 105
Joined: Fri May 27, 2022 9:06 pm

Re: Gamecoding in machinecode on a ZX81.

Post by MrVertigo »

Does the section below literally mean enter those two lines into the editor 20 times?

So:

block 20, 128
db 118
block 20, 128
db 118
block 20, 128
db 118

Etc....





Go to the dfile and erase the lines between the comments
"; each line has text and a Newline" and "; this byte fills the unused part of the screen"

Copy this part 20x into the deleted part.

Code: Select all

	block 20,128		; BLOCK places 20x character 128,inverted space
	db 118
We have our screen set, now add some display
dr beep
Posts: 2060
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: Gamecoding in machinecode on a ZX81.

Post by dr beep »

MrVertigo wrote: Sun Jul 30, 2023 3:08 pm Does the section below literally mean enter those two lines into the editor 20 times?

So:

block 20, 128
db 118
block 20, 128
db 118
block 20, 128
db 118

Etc....
For each line needed you place 20 lines.
BTW, this screen only has 20 positions, not 32.
You normally would need 25 DB 118 for a full screen, but you can also fill the screen with a single
DB #E9 after your last needed DB 118
MrVertigo
Posts: 105
Joined: Fri May 27, 2022 9:06 pm

Re: Gamecoding in machinecode on a ZX81.

Post by MrVertigo »

Thanks! I gave it a try, and the resulting program displayed a black square screen, twenty by twenty, with the character set in one single “pixel” in the top left corner, running ever faster through the characters.

Is that the correct outcome?
dr beep
Posts: 2060
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: Gamecoding in machinecode on a ZX81.

Post by dr beep »

MrVertigo wrote: Mon Jul 31, 2023 1:37 am Thanks! I gave it a try, and the resulting program displayed a black square screen, twenty by twenty, with the character set in one single “pixel” in the top left corner, running ever faster through the characters.

Is that the correct outcome?
The screen is an inverted screen as you can see on the BLOCK 20,128 (128 = inverted space)

As I recall the game would be chasing a character asap but it was not finished.
MrVertigo
Posts: 105
Joined: Fri May 27, 2022 9:06 pm

Re: Gamecoding in machinecode on a ZX81.

Post by MrVertigo »

I’m just at lesson 3 at the moment, Displaing On A Screen, so what I mean is- does this section of code:

gamecode
ld a,63
showa ld (screen),a
dec a
jr nz,showa
jr gamecode

Should this code only display an ever-changing character in one pixel at the top left corner of the screen, while the rest of the screen stays black and inverted? Or should other pixels on the screen change too?
dr beep
Posts: 2060
Joined: Thu Jun 16, 2011 8:35 am
Location: Boxmeer

Re: Gamecoding in machinecode on a ZX81.

Post by dr beep »

yes, that is what it does. First changes on the screen visible.
MrVertigo
Posts: 105
Joined: Fri May 27, 2022 9:06 pm

Re: Gamecoding in machinecode on a ZX81.

Post by MrVertigo »

Brilliant! Thanks.
MrVertigo
Posts: 105
Joined: Fri May 27, 2022 9:06 pm

Re: Gamecoding in machinecode on a ZX81.

Post by MrVertigo »

In Part 4) Input from the keyboard, there are two routines: nokey and upkey.

After dealing with nokey, it says:

“Get GAME1-002.ASM again in edit, we add a few lines
Again UNDER SHOWA add the following code.”

Here is my question: do we replace the nokey routine with the upkey routine, or do we KEEP the nokey routine and ADD the upkey routine into the code before it, like this:



upkey ld bc,(lastk)
inc c
jr nz,upkey


nokey ld bc,(lastk)
inc c
jr z,nokey
Post Reply