Page 1 of 2

Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 10:28 am
by djnzx48
Image
Z80 machine code has a lot of instructions, and it can be difficult trying to keep track of them all. Does PUSH decrement the stack pointer before or afterwards? What's the difference between IFF1 and IFF2? And what exactly does DAA even do?

Well, here's some good news: you don't have to memorise any of these instructions, since it turns out that all of them are in fact useless! (Cries of 'blow me down' and 'well I never'. Ed.) Well, it's true. And to prove it, here's a version of that gaming classic, Snake, where every single instruction is replaced with the humble LD. Nope, there's no trickery or self-modifying code going on here - it's all just LD instructions.

Download here: snake.tap
Runs on any 48K/128K Spectrum. Controls are QAOP or 5678.

Planned features: Extra levels, redefinable keys, multiple speed settings, online leaderboard, ability to make phone calls, VR support, Rolos dispensed when you win...

Source code available here if you want to experience the true horror. Viewer discretion is advised.

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 10:40 am
by RMartins
This could be useful, to someone starting to implement an emulator, since there are less instructions to implement to have something working on screen :lol:

But this is borderline madness :shock:

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 10:43 am
by Ersh
This is brilliant! :D

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 10:46 am
by Ast A. Moore
Hah! This is as insane as it is brilliant.

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 11:15 am
by R-Tape
Nope. It's too early in the morning for me to work out how you've made a functioning game with only LD instructions.

Are you loading opcodes into where the PC is?

Nice wee snake game, I can manage 19 (EDIT - didn't realise we had QAOP)

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 12:10 pm
by Ralf
Nope. It's too early in the morning for me to work out how you've made a functioning game with only LD instructions.
Metoo :)

So how does it work? You need loops, you need comparisons, you need jumps. Are you using self-modified code a lot to create these instructions with LDs to proper places in memory?

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 12:18 pm
by RMartins
He did mention ...
djnzx48 wrote: Tue May 29, 2018 10:28 am ... Nope, there's no trickery or self-modifying code going on here - it's all just LD instructions.

...

Source code available here if you want to experience the true horror. Viewer discretion is advised.
So go have a look :ugeek:
Spoiler
He did use some other instructions ... but it's mostly LDs.

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 6:37 pm
by Joefish
I did. Still can't figure out how he engineers a jump.
I'm guessing there are some long waits of repeated instructions and some pre-defined jump (or return stack) values being set up, so possibly waiting around for an interrupt to occur to trigger a jump..?

Though after all that effort, relying on ROM routines to read the keyboard seems a bit of a cop-out... :lol:

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 8:26 pm
by Ralf
Okay, now I'm after work. I looked at the code. I traced it in emulator with a debugger. And I don't still understand anything ;)

An explanation is warmly welcomed :)

Re: Crap Game: Snake but the only instruction is LD

Posted: Tue May 29, 2018 11:47 pm
by djnzx48
Thanks guys! :)
It's actually quite simple how it works. If you want to do a comparison between, say, B and C, you can just use:

LD H, somewhere
LD L, B
LD (HL), false
LD L, C
LD (HL), true
LD L, B
LD A, (HL)

Basically you're just loading some value into the memory location pointed to by B, and then doing the same for C. Then you load back the value from the first location. If you get back what you started, you know that it can't have been overwritten by C and so B <> C. However, if you get back the new value, B and C must be equal. Once you have the result from a comparison, you use that to index into one of many lookup tables, which is what the first 2000 lines of the code are setting up!

The jumps rely on IM1. I don't see how I can switch them off when I can't use DI! ;) The stack pointer is set to point to somewhere in the first few bytes of ROM, so that when the interrupt returns, it jumps to not the original return address but whatever value's in ROM. This is used to either jump back to the main loop, the setup phase for when you die, or a delay loop to slow the game down.

However, you're restricted in what addresses you can jump to because the interrupt calls the keyboard routine, and this must return properly so that the EI can execute and interrupts can occur again. So when this occurs the stack pointer must be in RAM. There's another trick though. The interrupt routine PUSHes AF, HL, BC and DE before calling the keyboard routine. Since an interrupt can only occur during the large block of dummy instructions at the end of the program, we don't care if these registers get corrupted. So that gives 8 possible addresses to jump to depending on which registers get PUSHed to ROM. Some of these addresses are too high in memory to be used, and some are too low and risk interfering with BASIC, so the three addresses used here are AFF3, C3FF, and CBC3.

Of course, if you used a +3, you could simply fill the entire memory up with LD instructions and then just wrap around when you reached the end, so none of this would be necessary.

There's a paper here where someone made a functioning Turing machine just using the MOV instruction on x86. They cheated though by using a JMP! Even crazier, there's an an entire C compiler using this idea!
Joefish wrote: Tue May 29, 2018 6:37 pm Though after all that effort, relying on ROM routines to read the keyboard seems a bit of a cop-out... :lol:
Well if you can find a peripheral for the Spectrum that uses memory-mapped IO, I'll gladly change it! :lol:

Re: Crap Game: Snake but the only instruction is LD

Posted: Wed May 30, 2018 1:23 am
by Seven.FFF
This is flippin’ genius. Infinite hats doffed to you!

Re: Crap Game: Snake but the only instruction is LD

Posted: Wed May 30, 2018 2:01 am
by MrPixel
I half expected the game code to start screaming at me to let it die. Viewer discretion indeed :lol:

Re: Crap Game: Snake but the only instruction is LD

Posted: Wed May 30, 2018 6:16 am
by djnzx48
Are there any other instructions this could be done with other than LD? I was thinking that the shift/rotate instructions look like the best bet, plus you can use the undocumented instructions such as LD B, RLC (IX+d). You could use this along with an address in ROM to effectively load a value into a register, except you'd have to account for the value being shifted over one.

Re: Crap Game: Snake but the only instruction is LD

Posted: Wed May 30, 2018 8:35 am
by djnzx48
Ah no, that wouldn't work because there doesn't seem to be a way to do jumps without somehow modifying the stack pointer, which you can't do with shifts/rotates. Using the all-RAM configuration on a +3 wouldn't really work either because the screen would get in the way.

I did consider either moving the stack to the location of the FRAMES system variable, or setting IY to point to the stack, so that when the interrupt routine increments FRAMES it increments the return address. This would only let you do 256 byte jumps, but if the calling code is after $FF00 it could potentially be used to jump into ROM which then does a RET to the desired location? So maybe a sequel is possible after all :)

Re: Crap Game: Snake but the only instruction is LD

Posted: Wed May 30, 2018 11:21 am
by R-Tape
djnzx48 wrote: Wed May 30, 2018 6:16 am Are there any other instructions this could be done with other than LD?
I'm still getting my head around this one! I can see how it loops by repeating LD A,(HL) and changing the stack so the interrupt does it for you, but I need to put a cold flannel on my head and work out how you can do everything else without even using CP!

I wouldn't have thought this possible.

Re: Crap Game: Snake but the only instruction is LD

Posted: Wed May 30, 2018 12:01 pm
by djnzx48
Well this technique is very limited :)

Instead of thinking of branches and choosing whether to do some computation or not based on a condition, you basically always do the computation, but set it up so that if the condition is false you end up with what you had before. So for example, the food always gets drawn every frame, but if there's still food on the screen or if the screen position where it's supposed to appear is occupied, it just draws whatever colour is already on the screen and so nothing changes. There's still a lot of things that are basically impossible to do without resorting to complicated loops, even just adding two numbers or checking whether one value is greater than another.

Re: Crap Game: Snake but the only instruction is LD

Posted: Wed May 30, 2018 10:25 pm
by MrPixel
is there a version for the WinAPE?

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 12:03 am
by MrPixel
djnzx48 wrote: Tue May 29, 2018 10:28 am Image
Z80 machine code has a lot of instructions, and it can be difficult trying to keep track of them all. Does PUSH decrement the stack pointer before or afterwards? What's the difference between IFF1 and IFF2? And what exactly does DAA even do?

Well, here's some good news: you don't have to memorise any of these instructions, since it turns out that all of them are in fact useless! (Cries of 'blow me down' and 'well I never'. Ed.) Well, it's true. And to prove it, here's a version of that gaming classic, Snake, where every single instruction is replaced with the humble LD. Nope, there's no trickery or self-modifying code going on here - it's all just LD instructions.

Download here: snake.tap
Runs on any 48K/128K Spectrum. Controls are QAOP or 5678.

Planned features: Extra levels, redefinable keys, multiple speed settings, online leaderboard, ability to make phone calls, VR support, Rolos dispensed when you win...

Source code available here if you want to experience the true horror. Viewer discretion is advised.
please remap the keys to traditional arrow or wasd please

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 12:32 am
by Seven.FFF
5678 *is* traditional arrow.

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 12:41 am
by Kweepa
Plays like a dream!

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 12:46 am
by djnzx48
I was thinking of adding WASD keys but that clashes with QAOP which is more 'traditional', IMHO. I'll probably add redefinable keys in a future update. I don't know anything about Amstrad machines, so no idea if anything like this is possible there.

EDIT: Would ESDF do? It's the same basic configuration but just shifted over one.

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 5:52 am
by djnzx48
[mention]MrPixel[/mention] there's a new update here adding ESDF controls in addition to the old QAOP and 5678 controls.

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 6:36 pm
by MrPixel
djnzx48 wrote: Thu May 31, 2018 12:46 am I was thinking of adding WASD keys but that clashes with QAOP which is more 'traditional', IMHO. I'll probably add redefinable keys in a future update. I don't know anything about Amstrad machines, so no idea if anything like this is possible there.

EDIT: Would ESDF do? It's the same basic configuration but just shifted over one.
what about I,j,k,l or plain arrow keys. i'm on a latop so the traditional 5,6,7,8 keys are in a straight vertical line, not marked. good game though. i'm amazed that you were able to pull this off. won't run in zxspin assembler though

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 6:48 pm
by MrPixel
so, the base game is good, impressive even. however, the snake lacks any sort of ability to reverse direction. maybe add in some sort of bumper (like in sonic CD in Collision Chaos) that would help the snake reverse direction. also, some music. take advantage of the Spectrum 128's capabilities and create something suitable. i would also suggest you remove the ground barriers as well as the ceiling as i had some trouble with them. your decision but keep it in mind. happy coding :D

Re: Crap Game: Snake but the only instruction is LD

Posted: Thu May 31, 2018 10:17 pm
by djnzx48
Yeah there are probably too many obstacles, I spent about 5 minutes making the layout for the game so it could definitely be improved. I'd like to add music but there's no way to play it with just the LD instruction, so it would have to be done with some ROM routine and things could get quite tricky. Not sure quite what you mean about reversing direction?