Recently I've been playing around with an Amstrad CPC emulator. I haven't written BASIC code for years, but back in the day I did actually use a CPC for real.

Anyway, looking at documentation online, I see the CPC has a CALL command, for executing arbitrary Z80 machine code subroutines. However, I'm having trouble finding much documentation about it; most command lists just say "if you don't know what this is, don't touch it!"

CALL is followed by the address of the machine code to execute. Presumably a simple return-from-subroutine instruction will take you back to BASIC when you're done.

That leaves the problem of how to pass data between BASIC and machine code. In particular, the CALL command seems to accept additional parameters after the start address, but it doesn't seem to be documented what these actually do. (Sadly, there doesn't appear to be a way to return results back to BASIC.)


Call accepts only integers and pointers as parameters; both are 16 bit values. The parameters are put on the BASIC stack. IX points to the top of that stack. The number of parameters is put into A. The machine code operation needs to take it from there, including figuring out (or just assuming) the data type of the parameters.

For an example, see e.g. http://www.cpcwiki.eu/index.php/Technical_information_about_Locomotive_BASIC ; but beware that the description is a little confusing.

Note that when you pass a pointer, you effectively pass by reference, so a value can be returned to the variable that is being pointed to.

  • Just to hit the other bit: and it's an RTS to return, such as I'm aware. – Tommy Oct 26 '20 at 22:17
  • 2
    @Tommy Rather RET, as it's an 80 type CPU. RTS would be 65/68 series. – Raffzahn Oct 26 '20 at 22:56
  • Also about "passing data", it sounds OP isn't aware that most things were done just with global state back in the day. You write data into memory locations or you set registers, and the machine code subroutines would act on it. – scrollbear Oct 26 '20 at 23:18
  • 1
    @Tommy :) SCNR - in fact, you made me peek into the 8080 chart beside my desk, just to be sure. Mixing mnemonics across CPUs is like a swamp at night ... – Raffzahn Oct 27 '20 at 9:58
  • 1
    Combined with the @ operator which allows you to get the address of BASIC variables, it looks like this should solve things nicely... – MathematicalOrchid Oct 27 '20 at 17:39

A few pointers:

  • A nice book for doing Z80 assembly from some HLL POV has always been Osborne's Z80 Assembly Language Subroutines.

  • For CPC specific addresses you might want to look at CPC related sites like the CPCWIKI

  • And the generic 8080 return instruction is RET (C9h)

  • Conditional return is RET xx with xx as condition.

  • 1
    These are great hints, but this site tends to discourage answers that depend on external links. You might prefer to include some example code from the linked sites to illustrate how parameters are passed and results returned to BASIC. – Mark Williams Oct 27 '20 at 8:47
  • 3
    “A few pointers” xkcd.com/138 – MathematicalOrchid Oct 27 '20 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.