Introduction:
After doing a couple intros for X86 DOS, I was looking intro trying my hands on something on a different platform. I had done some game related for a bunch of retro platforms in the past, so I started a bit of experimentation in getting something up and running for a bunch of platforms, talking to people like Fready (atari 8bit) and Spkr (atari st) to see if I could get something up and running.
However I was nowhere near something that would lead to a production any time soon, so I decided to try something completely different and try my hands on a ZX Spectrum production. Having been mostly a commodore guy back in the day I never ran into spectrum stuff a lot when I was younger. Furthermore, I didn't know any Z80 assembly but as it looked a bit similar to X86 assembler on the surface, I decided to give it a shot:
Setting a challenge:
Then I started to look around a party that would have a 256b intro compo for ZX Spectrum. Chaos Constructions was still a long way off, It seemed lost party was hosting a dedicated ZX Spectrum 256 byte intro competition. The thing was the party was already in 10 days. So I figured this would make for a nice personal challenge as I had a rigid deadline and end goal to work with.
Orientation phase:
As I was not familiar with the platform, I started my journey by basically watching all the 256b/128b intros for the ZX Spectrum on pouet / demozoo to see what is out there, which intros I like or dislike and to see what works and what doesn't. I'm planning to write seperate piece about my favorite ZX Spectrum prods (both demos and intros) in the future about this journey.
Getting my feet wet:
Now I needed to get started on actually coding, so after looking around for technical information about Z80 and Spectrum programming as well as an assembler. I quickly realised that Pasma and Sjasmplus were the most used assemblers these days that work on multiple platforms. Additonally I found a Z80 disassembler that allowed me to look at a few intros. As for emulation for some reason Fuse didn't work for me, so I switched around between using EightyOne (which I later changed for the better suited ZXSpin) and UnrealSpeccy for quick access
So yes... code then...
Now the tricky part was actually get off my ass and learn Z80 machine language. A weeklong journey of looking at tutorials, sourcecode, comparing Z80 to X86 instructions, creating simple programs and failing, rinse and repeat until I got something sensible on screen followd and literally caused me a headache.
However, this process lead to the basis for the Z80 section i wrote for the sizecoding.org website, where most of the things I found are documented and much better explained then I could do justice in this paragraph.
Sizecoding.org: Learning Z80 Assembler
Color control:
One of the things I wanted to do was to have fine control over the colors and pattern i'm using instead of rolling with the default 8 colors, so I set out to make a small tool that allowed me to quickly test out and export colordata.
With this tool I looked into 4 color ramps and a pattern that I could use for my intro.
How to start a 256b intro for the ZX Spectrum with limited knowledge of Z80 assembly
So now I had something on screen, I was looking to how to I looked intro the screen memory of the zx spectrum, and like most newbies this looked like a complex mess to me. I figured with okay color ramp color accessible via index and a good repeating pattern in screen, I could just focus on a more linear color-ram area and try to get something animating on screen.
Before I could do any effect, I needed to preparing the display with a proper pattern and color-indexing table. So I started by copying the colordata to a 256byte aligned area like so:
; copy colordata (6+2+1 = 9byte)
ld hl,colordata
ld de,0x9000
ld c,32
ldir
And then copying the pattern intro screen memory back to front:
ld h,0x57 ; ld hl,0x5700
loop3:
ld de,tiledata
ld b,8
loop2:
ld a,(de)
loop1:
ld (hl),a
inc l
jr nz,loop1
dec h
inc e
djnz loop2
bit 6,h
jr nz,loop3
The Screen Update loop
I started with a simple x and y loop like in which I will do my colorindex calculation, like so:
ld de, VPAGE
ld b,24
yloop:
ld c,32
xloop:
push bc
; fill coloindex
ld a,b
and a,c
storepixel: and 7 ; 0..7
add iyh ; add startcolor
ld (de),a ; write to vpage
inc de
pop bc
dec c
jr nz,xloop
djnz yloop
And then use the color-indexing table to pick up the index-data from VPAGE and copy it to COLORRAM using the 256-byte aligned colorindex table to remap indices to ZX Spectrum colors.
Effects
So now that I had some simple pattern up and running on my screen, I started to look into very simple effects I could do with my limited knowledge of Z80, whilst still looking okay. I knew that i had 4 sets of 8 color ramps and if I could switch between 4 different effects, I might be able to get away with a few simpler effects.
To make this work I needed a framecounter and effectcounter for switching between effects. Luckily the Z80 has 2 index registers IX and IY that can be accessed by there low and hi-byte. However using these registers comes at a slight size-penalty compared to the regular register pairs. Furthermore, using the IY register can lead to unexpected behavior as it is also used for Interrupts. I did learn this after releasing 2 intros for the ZX Spectrum, both of which runned flawlessly on my Spectrum +2 ;-)
To make things wobble in a nice kind of way. I looked at example code for a sine-table (calculated via Calculator functions) and used that for motion (I only learned how to ACTUALLY use the calculator functionality properly after the release of this intro when gasman pointed me to a good reference for it).
A 45 degree tilt makes the world a better place.
Furthermore, I tilted my coordinate system 45 degrees to make things look more interesting than they really are... This is what turns a simple rolling AND pattern of color indices intro something that is actually somewhat entertaining to watch.
So I ended up with 4 different effects based on different color-index calculations that made the intro look kinda meaty and hopefully pleasing to watch. With my last few spare bytes I added some sound by carefully find a piece of repeating memory that I could output to the AY soundchip and finished my intro just in time for the deadline. Mission completed!
Release
So by the end of the week I had an intro running and was ready to submit to Lostparty. However upon inquiring about submitting a ZX spectrum intro to the party, I was told there weren't enough other ZX Spectrum intros submitted and I could either add it to the atari 256byte intro competition or release it elsewhere.
So I decided to wait another week or 2 and release it at Flashparty 2020 in the combined 256 byte intro competition. This was a bit of a risk because it would be combined with all kinds of other and much more powerful platforms. Also I didn't know if the ZX Spectrum was a known platforms at all in the Americas. However, the risk paid of and I was able to win the 256 byte intro competition with my very first ZX Spectrum intro.
Conclusion:
Looking back i'm actually very proud of what i've been able to create on a platform I wasn't familiar with before and I would say the intro holds up very well among other ZX spectrum 256byte intros.
Now that I was on a roll, and wanted to continue by making my next intro in honor of Sir Clive's 80th birthday. But this my friends, I a story for another time....
For more information, you can download the intro at: demozoo.org