
The Complete Spectrum ROM Disassembly - MindGods
https://speccy.xyz/rom/
======
klelatti
This is awesome. I still have a copy of the original book from 1983 on my
bookshelf! This looks like a faithful reproduction with some added features to
make easier to use.

Looking forward to browsing some of the other code linked to from the site -
e.g. Manic Miner which was a particular favourite.

A couple of points about the Spectrum ROM.

\- Spectrum BASIC was very slow especially compared to BBC Basic. I think that
this was partly due to the constraints of having to fit everything into 16k vs
32k for the BBC - so code was optimised for size rather than speed.

\- It included a stack based VM for floating point operations which I think
was again mainly to reduce the code size (one byte for each operation rather
than three bytes for a subroutine call).

Would seem appropriate to give credit to the main author of the code, Steve
Vickers [1], who went on to found Jupiter Computing, makers of the Jupiter
Ace.

[1]
[https://web.archive.org/web/20110516082258/http://www.sincus...](https://web.archive.org/web/20110516082258/http://www.sincuser.f9.co.uk/004/newbiz.htm)

edit: added Steve Vickers credit.

~~~
Theodores
The Spectrum used the CPU and the ULA for everything. This resulted in a
cheaper price for the machine. Meanwhile the BBC had actual hardware. As an
example a simple beep would tie up CPU cycles on the Spectrum whereas the BBC
micro could define a sound envelope for something more than a beep and hand
that off to the AY-8192 sound chip.

The Z80 had plenty of features that the BBC micro's 6502 did not have, so the
code should have been quicker with fewer CPU cycles used and fewer lines of
code. But the lack of supporting hardware negated this gain.

BBC BASIC was also a more complete implementation of the language. So any code
written in BASIC was more efficient just because you didn't have to use your
own BASIC workarounds. Being able to drop into assembly language also helped,
the Spectrum lacked this option to truly turbo charge your code. The BBC used
16k for BASIC in ROM and had 16k for the OS. This enabled ROMs to be swapped
out so you could run BCPL or another ROM, e.g. Fortran.

The Spectrum had BASIC and the OS in 16k with 48k available for RAM. The BBC
could use more than 32k of RAM if installed, as per the later Master system
that used bank switching.

I am not familiar with the code but I would be surprised if the BBC Basic ROM
was anything less than a work of genius concise code. Every byte counted in
those days regardless of what home computer you were programming for.

~~~
jhallenworld
I recently was curious about the relative performance of the classic CPUs, so
I made this table to compare their memcpy performance:

[https://github.com/jhallen/joes-
sandbox/tree/master/classic-...](https://github.com/jhallen/joes-
sandbox/tree/master/classic-cpu)

~~~
Someone
I think you can speed up the 6502 version by moving it into the zero page and
not using indexed mode. Of course, zero page memory is even more restricted
than the 64kB you have in total, but that might be worth it in some cases.

Even if this isn’t in the zero page, it surprises me that those expensive x
indirect loads and stores are cheaper than worth having to increase the source
and destination addresses often, but that probably is because my 6502 is very
rusty.

Also: I stared at that code for a while, but couldn’t figure out why that _jmp
immer_ is there. If you move the 3 instructions starting at _lastpage_ to the
end, it can be removed, can’t it? (I didn’t check, but there may be further
code shuffles that do not decrease the number of instructions, but do decrease
the number of branches and with it, the number of cycles spent)

~~~
jhallenworld
I knew 6502 people would improve it :-)

>moving it into the zero page and not using indexed mode

I'm not sure I follow.. you mean restrict the memcpy to only within the zero-
page?

>jmp inner..

Yeah, it doesn't matter to much, not in the inner loop. You could move the
start of the code to right after the rts also..

~~~
Someone
No, moving the code into the zero page. See
[https://retrocomputing.stackexchange.com/a/92](https://retrocomputing.stackexchange.com/a/92)
for what the Basic in the Commodore 64 does.

Increasing an address is faster in the zero page, and self-modifying code is
faster. That combines the two.

~~~
jhallenworld
Oh I see:

    
    
                 inc $c9        5 cycles
        00c8:    lda $xxxx      4 cycles
    

vs.

    
    
             lda $xxxx,x    4
             inx            2
    

Mine is still faster...

~~~
Someone
Luckily, I said my 6502 is rusty :-). You can win a cycle increasing the high
byte of pointers, but that probably isn’t worth the zero page memory in most
cases.

------
acqq
The original book presenting the disassembly was:

[https://www.abebooks.co.uk/9780861611164/Complete-
Spectrum-R...](https://www.abebooks.co.uk/9780861611164/Complete-Spectrum-ROM-
Disassembly-Logan-0861611160/plp)

by Dr Ian Logan and Dr Frank O'Hara, 1983

published by Melbourne House, here is the scan of their catalog from these
times:

[http://www.ourdigitalheritage.org/archive/playitagain/wp-
con...](http://www.ourdigitalheritage.org/archive/playitagain/wp-
content/uploads/melbourne-catalog.pdf)

I see in the changelog of this project:

[https://speccy.xyz/rom/reference/changelog.html](https://speccy.xyz/rom/reference/changelog.html)

"20160709 The disassembly is now 'complete'.

\- Added annotations from The Complete Spectrum ROM Disassembly by Dr Ian
Logan and Dr Frank O'Hara"

The interesting aspect of this online version is its relation to

[https://skoolkit.ca/](https://skoolkit.ca/)

[https://skoolkit.ca/docs/skoolkit/whatis.html](https://skoolkit.ca/docs/skoolkit/whatis.html)

~~~
stevekemp
I know that Melbourne house was a (book) publisher, but mostly I think of them
as the publisher of software:

[https://www.filfre.net/2012/11/the-
hobbit/](https://www.filfre.net/2012/11/the-hobbit/)

------
beagle3
Ha! I couldn’t get this one in the local store in 1984, I had to do with [0],
which was inferior although still very helpful. When I sort through my boxes
in storage I suspect I’ll find it.

[0] [https://www.computinghistory.org.uk/det/41998/The-
Spectrum-M...](https://www.computinghistory.org.uk/det/41998/The-Spectrum-
Machine-Code-Reference-Guide-Microdrive-Interface-1-Complete-ROM-Disassembly/)

edit: I originally wrote that the author was Rodney Zacks but was mistaken --
googling found that it's by Richard Ross-Langley

~~~
rwmj
Rodney Zaks wrote the definitive guide to the Z80:
[https://en.wikipedia.org/wiki/Programming_the_Z80](https://en.wikipedia.org/wiki/Programming_the_Z80)

~~~
stevekemp
I have that book, even 30 years later. I've been referring to it a recently,
while using an Arduino to drive a Z80 chip (pretending to be I/O ports, and
RAM).

------
nickt
I’ve just picked up a copy of “The ZX Spectrum ULA: How to design a
microcomputer“ by Chris Smith with makes a good companion read to this, though
with the focus (obviously) being on the ULA.

[http://www.zxdesign.info/book/](http://www.zxdesign.info/book/)

------
jacquesm
I did something like this with a friend for the TRS80 Color Computer / Dragon
32, we found some really neat stuff in there, for instance how to enable the
upper 32 K RAM. Those were interesting times in the sense that it was possible
to know the function of _every_ instruction present in the memory of your
computer.

------
neilwilson
My favourite part of Spectrum basic was that everything was an expression.

Go to 23*N

------
samsaga2
There is no copyright problems with this?

~~~
nineteen999
Who is going to try and enforce the copyright in 2020? BSkyB?

------
fasteo
Good times indeed !

Off topic. Little quiz:

    
    
      RANDOMIZE USR 0
    

What for ?

~~~
rwmj
OK, here's one (for the ZX81). Why did I choose ports 16509 and 16514 for the
libvirt daemon
([https://libvirt.org/remote.html](https://libvirt.org/remote.html))?

~~~
klelatti
10 REM TAN

20 PRINT USR 16514

16514

~~~
rwmj
Good one. TAN (the keyword, not the 3 letters) is hex C9 which is also RET in
Z80 machine code. The address of the first byte after the keyword in the first
statement in a ZX81 program is 16514. USR 16514 calls this address, which
immediately returns. The PRINT statement then prints the result of the USR
expression, which is the contents of the BC register on return, which I guess
happens to contain the start address (since not otherwise set) as a side
effect of the implementation.

16509 is the address of the start of the program in memory. Bytes 16509-16510
are the line number (2 byte LSB int). Bytes 16511-16512 are the length of the
line. Byte 16513 is the command keyword (REM).

~~~
klelatti
After thirty odd years I still have these numbers encoded into and handful of
neurons somewhere.

Thank you for getting me to dig them out and great that they live on in
libvirt!

ps The memory mapping reminded me that ZX81 managed to squeeze a 32 x 24
screen into a 1k total RAM. I think someone managed to write a chess program
with those restrictions - but only using 8 x 8 or so of the screen.

~~~
rwmj
Indeed, 1K chess by David Horne:
[https://en.wikipedia.org/wiki/1K_ZX_Chess](https://en.wikipedia.org/wiki/1K_ZX_Chess)

I had this chess game on tape, and I've often wondered if the two are related,
but this one needed 16K:
[http://www.zx81stuff.org.uk/zx81/tape/ZXChessII(Black)](http://www.zx81stuff.org.uk/zx81/tape/ZXChessII\(Black\))

