Standard ROM entrypoints?

The place for codemasters or beginners to talk about programming any language for the Spectrum.
Post Reply
hjalfi
Drutt
Posts: 28
Joined: Wed Jul 18, 2018 11:58 am

Re: Standard ROM entrypoints?

Post by hjalfi »

Ast A. Moore wrote: Thu Jul 19, 2018 6:28 pm Again, there are no “universal” entry points—each programmer uses mostly arbitrary points based on his particular needs.
[...]
Those tutorials you refer to, simply use a subset of “most commonly used shortcuts” to ease a novice into programming in languages other than Sinclair BASIC.
Yes, precisely. There must be, somewhere in the community, information about which of these routines do useful things, and how to call them. Otherwise people wouldn't use them. This must be written down somewhere in a easier-to-digest form them just groping through the raw disassembly --- so, where?
Last edited by hjalfi on Thu Jul 19, 2018 9:48 pm, edited 1 time in total.
AndyC
Dynamite Dan
Posts: 1388
Joined: Mon Nov 13, 2017 5:12 am

Re: Standard ROM entrypoints?

Post by AndyC »

hjalfi wrote: Thu Jul 19, 2018 9:38 pm Yes! This! This is exactly what I'm looking for! What are these shortcuts? Is there a known set of useful ones? What registers do they use? How do I use them? Is this stuff actually written down somewhere, or is this just tribal knowledge passed as samizdat from developer to developer?
You'll find it's sporadic at best. Pretty much RST #10 for printing a character (occasionally accompanied by the hint you should really do a Channel Select call first but can often get away without it) and maybe the odd routine entry point that any one given developer particularly favours. A lot of tutorials were designed around games and the Sinclair ROM routines are eye-wateringly slow for doing anything so many people just write their own (with the exception of maybe doing something like finding an LDIR/RET pair in ROM to circumvent contention).
hjalfi
Drutt
Posts: 28
Joined: Wed Jul 18, 2018 11:58 am

Re: Standard ROM entrypoints?

Post by hjalfi »

Note that I rewrote my last post to be less obviously frustrated --- sorry about that.

I'm used to the BBC Micro, which has a significantly more complex operating system (like, it actually has an operating system). The Spectrum's so much simpler, better understood and has such a larger community that I refuse to believe that what I'm looking for isn't out there somewhere...
AndyC
Dynamite Dan
Posts: 1388
Joined: Mon Nov 13, 2017 5:12 am

Re: Standard ROM entrypoints?

Post by AndyC »

hjalfi wrote: Thu Jul 19, 2018 9:51 pm The Spectrum's so much simpler, better understood and has such a larger community that I refuse to believe that what I'm looking for isn't out there somewhere...
And therein lies the problem. The Speccy hardware is so simple that is bonkers insanely easier to just write the routines directly (and gain gads of speed) than to use the ROM calls. Particularly because the ROM was mainly designed to squeeze into 8K (from the ZX81) and is heavily tuned for size over performance.

And, as someone who does a fair bit of CPC coding, yes this does seem insane.
User avatar
Ast A. Moore
Rick Dangerous
Posts: 2640
Joined: Mon Nov 13, 2017 3:16 pm

Re: Standard ROM entrypoints?

Post by Ast A. Moore »

hjalfi wrote: Thu Jul 19, 2018 9:38 pm
Ast A. Moore wrote: Thu Jul 19, 2018 6:28 pm [Those tutorials you refer to, simply use a subset of “most commonly used shortcuts” to ease a novice into programming in languages other than Sinclair BASIC.
Yes! This! This is exactly what I'm looking for! What are these shortcuts? Is there a known set of useful ones? What registers do they use? How do I use them? Is this stuff actually written down somewhere, or is this just tribal knowledge passed as samizdat from developer to developer?
Buddy, no offense, but I’ve already answered all of these questions. More than once. ;) Everything you need to know is in Logan and O’Hara’s book (and the excellent hypertext version thereof you’ve already discovered on your own). Read, experiment, learn. That’s how the cookie crumbles. There was never an officially documented breakdown of the Spectrum ROM from Sinclair Research or Amstrad. All the tutorials use the information found in that book or original discoveries (or someone else’s discoveries). Period.

A word of advice: Don’t get too hung up on the ROM routines. Their goal was universality (within the scope of the BASIC interpreter and the operating system) and being able to squeeze into 16K. Some are good in a pinch, but for the most part they’re painfully slow (and sometimes buggy, too). The print character routine (the famous Restart 16 one) is notoriously slow. It’s trivial to speed it up five or six times with a lot smaller footprint.

I think your frustration comes from misplaced expectations. The Spectrum is a very, very, very, very simple machine. A lot of programmers’ ingenuity originated out of necessity, rather than from studying some tome of sacred knowledge. People came up with creative and brilliant ways of making the simple (and quirky) hardware do amazing things because they were constantly inventing new approaches, and not because they looked for a set of standard ones. For the most part, the only thing we knew for certain was where our towel was. We never took trains or buses, we hitchhiked.
Every man should plant a tree, build a house, and write a ZX Spectrum game.

Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
AndyC
Dynamite Dan
Posts: 1388
Joined: Mon Nov 13, 2017 5:12 am

Re: Standard ROM entrypoints?

Post by AndyC »

Spec-chums curious of the difference could do worse than grab a copy of the +3DOS manual and look at the documentation for that, which documents a bunch of entry points each apparently exactly three bytes long. That's because the ROM pretty much starts out with a block of code like:

Code: Select all

function1 JP implementation_of_function1
function2 JP implementation_of_function2
function3 JP implementation_of_function3
function4 JP implementation_of_function4
So that when you do a CALL function1, it will pass through to the real routine, even if it shifts around between implementations and the entry points will always be consistent (since a three byte JP is all it ever needs). This is pretty much the same pattern used in the CPC firmware jumpblock to call system routines (though there is often a RST instruction followed by a specially coded two bytes that encode the entry point in one of the system ROMs)
hjalfi
Drutt
Posts: 28
Joined: Wed Jul 18, 2018 11:58 am

Re: Standard ROM entrypoints?

Post by hjalfi »

Well, that was anticlimactic.

Code: Select all

var i: uint8 := 10;
while i != 0 loop
    print("I can do it ");
    print_i8(i);
    print(" time");
    if i != 1 then
        print("s");
    end if;
    print_newline();
    i := i - 1;
end loop;
...compiles to:

Image

The binary is pretty poor at 446 bytes, but I do notice that it appears to have decided to include the 32-bit division routine. I've been cross-compiling from a PC but there's no reason at all why you couldn't do this from a +3 running CP/M (if you were patient). The only ROM routine it's using is rst 0x16, and preserving iy.

Sadly, I don't think this is worth pursuing further --- without concrete information it's only really working by accident, so the only way forward is to essentially bolt on a complete operating system for the runtime, which is way out of scope. Still, I do have a project I need Cowgol-compiling-to-pure-code for, which this should work for.

If anyone discovers any decent docs, please get in touch!

Code is here: https://github.com/davidgiven/cowgol
AndyC
Dynamite Dan
Posts: 1388
Joined: Mon Nov 13, 2017 5:12 am

Re: Standard ROM entrypoints?

Post by AndyC »

hjalfi wrote: Thu Jul 19, 2018 11:02 pm Sadly, I don't think this is worth pursuing further --- without concrete information it's only really working by accident, so the only way forward is to essentially bolt on a complete operating system for the runtime, which is way out of scope. Still, I do have a project I need Cowgol-compiling-to-pure-code for, which this should work for.
You shouldn't entirely give up, it's a genuinely interesting idea. You might, however, want to document the required OS functionality somewhere as it's hard to determine from the codebase (especially if, like me, you don't grok 6502) and quite a few links in the GitHub documentation seem to 404. Also you might genuinely find it easier to try targetting the Amstrad first, Amstrad published an extensive reference in SOFT-968 (http://www.cpcwiki.eu/index.php/Soft968 ... 8_Firmware) and it's got a much cleaner design. What's more if you can nail it down to the firmware calls there, people can probably easily locate very similar entry points in the Spectrum ROM - RST #10 is effectively equivalent to CALL &BB5A, for example - because the Z80's non-orthagonal instruction set often lead to very similar patterns in terms of instruction passing.
User avatar
ZXDunny
Manic Miner
Posts: 498
Joined: Tue Nov 14, 2017 3:45 pm

Re: Standard ROM entrypoints?

Post by ZXDunny »

Was the 48k ROM image substantially different in the various flavours of Spectrum? In my experience, the entry points documented in the unofficial-but-pretty-much-used-by-everyone ROM disassembly are universal as long as you page in the 48k ROM on the 128k and above machines? That's the only one that really has any useful stuff (except for disk handling on the +3) in it anyway.
User avatar
djnzx48
Manic Miner
Posts: 729
Joined: Wed Dec 06, 2017 2:13 am
Location: New Zealand

Re: Standard ROM entrypoints?

Post by djnzx48 »

I don't think the 48K ROM really changed that much, but the Interface 1 ROM at least had a lot of routines shuffled around between versions. This article has a brief summary: http://www.users.globalnet.co.uk/~jg27p ... r18_27.htm
User avatar
1024MAK
Bugaboo
Posts: 3104
Joined: Wed Nov 15, 2017 2:52 pm
Location: Sunny Somerset in the U.K. in Europe

Re: Standard ROM entrypoints?

Post by 1024MAK »

I think the point that may have been missed is this: the ZX80, ZX81 and ZX Spectrum did not, and do not have an operating system.

The ZX80 ROM is 4K bytes in size and contains BASIC and just enough code to process the keyboard and screen.
The ZX81 ROM is 8K bytes in size. The BASIC was developed from the ZX80 and is enhanced, but again, there is no OS.
Yep, same story with the ZX Spectrum. The ROM is 16k bytes in size. The intent at the time was to include code to handle the forthcoming microdrives (but instead ended up with some unused space). Again, the BASIC was developed from the ZX81 and is enhanced, but again, there is no OS.

Compare this with a Acorn BBC. This has a 16k OS ROM (approx 3/4 k byte is mapped out for the I/O hardware area). Plus one or more sideways ROMs (each up to 16k bytes) containing language(s), filing systems or other programs, one of which is the BASIC. The Master 128 can even be used without BASIC being active as it has a simple command line.

Of course, Z80 code can be made more compact compared to 6502 code. But even so, it's a big difference.

The print RESTART routine when fed with the correct data is the most useful routine, as it can output any character to the screen or the ZX printer. Read the BASIC manual to understand the control codes/control characters that BASIC can use.
In the ROM, there is also a keyboard reading routine. And there is the BASIC bleeper routine.

As alluded to above, the writers of the ROM were aiming for as much functionality as possible in 16k bytes, as that is apparently what Sir Clive wanted. Hence the ROM routines are slow. Hence machine code programmers preferred to write and read from the hardware directly.

The screen is a memory mapped bit-map. The only strange thing being the actual layout.

Apart from the 'unused' space and a couple of other areas which were altered in the 128k, +2, +2A, +2B, +3 and +3B, the 'original' ROM (often called the 48k ROM, even though it's exactly the same as the ROM in the 16k ZX Spectrum) is the same across all ZX Spectrums (there was ONLY one official ZX Spectrum ROM until the Spanish developed the 128k machine). So most useful routines stayed in the same place. In the 128k etc models, it's wise to ensure that this ROM image is mapped in rather than the editor ROM or disk OS ROM.

Mark
:!: Standby alert :!:
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :dance
Looking forward to summer later in the year.
User avatar
Seven.FFF
Manic Miner
Posts: 736
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: Standard ROM entrypoints?

Post by Seven.FFF »

1024MAK wrote: Fri Jul 20, 2018 4:46 pm I think the point that may have been missed is this: the ZX80, ZX81 and ZX Spectrum did not, and do not have an operating system.
If you're ever tempted to think it did, you just have to look at the Acorn MOS to readjust your perspective :D

Garry Lancaster's NextZXOS is starting to turn +3eDOS into a useful operating system, with drivers and chained interrupts, and some system services.
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel NXTP ESP Update ESP Reset CSpect Plugins
hjalfi
Drutt
Posts: 28
Joined: Wed Jul 18, 2018 11:58 am

Re: Standard ROM entrypoints?

Post by hjalfi »

Yeah, the Acorn MOS is a bit of an unfair comparison; having 16kB BASIC + 16kB OS was unheard of luxury back then (and went a long way to explaining why the BBC Micro was so special, and so expensive).

A better comparison is the Commodore 64. (Also supported by Cowgol! https://pbs.twimg.com/media/DOnxU7CWkAA6a5N.jpg:large) It managed to pack into 20kB an 8kB OS, 8kB standard Microsoft Basic and a whole 4kB of character generator ROM (256 characters compared to the Spectrum's 128). The kernel was pretty crummy --- it wasn't even spelt correctly! --- but it did provide a set of standard entrypoints for console I/O, accessing devices, etc. See http://sta.c64.org/cbm64krnfunc.html. And that's on the 6502, which has maybe 20% worse code density than the Z80 (ref: http://web.eece.maine.edu/~vweaver/pape ... iccd09.pdf).

It'd be totally possible to implement a similar system, complete with Basic, into the Spectrum's 16kB ROM. You could even fit a DOS there --- Microsoft Extended Basic was 8kB of fairly rubbish 8080 code, the CP/M portable kernel is 3.5kB, the CP/M BIOS for talking to the hardware is another 3.5kB, leaving a whole kilobyte left over...
AndyC
Dynamite Dan
Posts: 1388
Joined: Mon Nov 13, 2017 5:12 am

Re: Standard ROM entrypoints?

Post by AndyC »

hjalfi wrote: Fri Jul 20, 2018 7:35 pm A better comparison is the Commodore 64. (Also supported by Cowgol! https://pbs.twimg.com/media/DOnxU7CWkAA6a5N.jpg:large) It managed to pack into 20kB an 8kB OS, 8kB standard Microsoft Basic and a whole 4kB of character generator ROM (256 characters compared to the Spectrum's 128). The kernel was pretty crummy --- it wasn't even spelt correctly! --- but it did provide a set of standard entrypoints for console I/O, accessing devices, etc. See http://sta.c64.org/cbm64krnfunc.html. And that's on the 6502, which has maybe 20% worse code density than the Z80 (ref: http://web.eece.maine.edu/~vweaver/pape ... iccd09.pdf).
True. Though not only is the kernel pretty crappy and limited, the BASIC implementation is massively lacking. Sinclair clearly wanted something the could show off the capabilities of their machine, particularly high res graphics and colour (remembering they're coming form the ZX81). Commodore on the other hand did the cheapest deal possible for a completely uncustomised version of Microsoft Basic (which was abnormal in and of itself, the usual process was to get Microsoft to extend it to cover machine capabilities).
Post Reply