Gamecoding in machinecode on a ZX81.
Re: Gamecoding in machinecode on a ZX81.
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:
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
Re: Gamecoding in machinecode on a ZX81.
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.
We have our screen set, now add some display
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
Re: Gamecoding in machinecode on a ZX81.
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
Re: Gamecoding in machinecode on a ZX81.
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?
Is that the correct outcome?
Re: Gamecoding in machinecode on a ZX81.
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.
Re: Gamecoding in machinecode on a ZX81.
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?
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?
Re: Gamecoding in machinecode on a ZX81.
yes, that is what it does. First changes on the screen visible.
Re: Gamecoding in machinecode on a ZX81.
Brilliant! Thanks.
Re: Gamecoding in machinecode on a ZX81.
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
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