I started looking at how sdcc compiles C for the Z-80. In order to write assembly for the processor, I need to knwo the calling convention. After all, I need to write putchar() and getchar() to use the GPIO/SPI CPLD to talk to the MAX3110E.

The calling convention is that arguments are pushed onto the stack from right to left. Return values are returned in L for 8 bit, HL for 16 bit, and DEHL for 32 bit return values.

The other part that’s important to know is who saves registers. The default is that the caller saves them. The problem is when the caller calls a small function that doens’t use registers. In this case, it would be nice to let the the callee save the registers. One way of doing this is using the –callee-saves function-list or –callee-saves-all. Also the __naked option can be used on the function definition. Finally, #pragma callee_saves can be used. Except, I didn’t notice any of that working. SO right now, I’m concluding that it is not supported on the Z-80 port. So, I’ll just assume it’s always caller saved and the functions can just use any register (except IX).

I’m not sure why some functions use IX and some don’t. But it probably doesn’t really matter too much. I just have to know how to use IX if I want and how not to if I don’t.

Here is some sample C code to see how the calling convention works.

 1 int plus(int a, int b, int c)
 2 {
 3     int sum;
 4     sum = a + b + c;
 5     return sum;
 6 }
 7 
 8 
 9 int plusplus(int d, int e, int f)
10 {
11     int sum = 0;
12     int i;
13     for (i = 0; i < 5; i++)
14     {
15         sum += plus(d, e, f);
16     }
17     return sum;
18 }

Here is the assembly.  The <– notes are mine.

  1 ;--------------------------------------------------------
  2 ; File Created by SDCC : free open source ANSI-C Compiler
  3 ; Version 3.5.2 #9283 (MINGW64)
  4 ; This file was generated Mon Aug 17 20:12:13 2015
  5 ;--------------------------------------------------------
  6  .module argtest
  7  .optsdcc -mz80
  8  
  9 ;--------------------------------------------------------
 10 ; Public variables in this module
 11 ;--------------------------------------------------------
 12  .globl _plusplus
 13  .globl _plus
 14 ;--------------------------------------------------------
 15 ; special function registers
 16 ;--------------------------------------------------------
 17 ;--------------------------------------------------------
 18 ; ram data
 19 ;--------------------------------------------------------
 20  .area _DATA
 21 ;--------------------------------------------------------
 22 ; ram data
 23 ;--------------------------------------------------------
 24  .area _INITIALIZED
 25 ;--------------------------------------------------------
 26 ; absolute external ram data
 27 ;--------------------------------------------------------
 28  .area _DABS (ABS)
 29 ;--------------------------------------------------------
 30 ; global & static initialisations
 31 ;--------------------------------------------------------
 32  .area _HOME
 33  .area _GSINIT
 34  .area _GSFINAL
 35  .area _GSINIT
 36 ;--------------------------------------------------------
 37 ; Home
 38 ;--------------------------------------------------------
 39  .area _HOME
 40  .area _HOME
 41 ;--------------------------------------------------------
 42 ; code
 43 ;--------------------------------------------------------
 44  .area _CODE
 45 ;argtest.c:1: int plus(int a, int b, int c)
 46 ; ---------------------------------
 47 ; Function plus
 48 ; ---------------------------------
 49 _plus::
 50 ;argtest.c:4: sum = a + b + c;
 51  ld hl,#4 <-- No IX. Why?
 52  add hl,sp
 53  ld iy,#2
 54  add iy,sp
 55  ld a,0 (iy)
 56  add a, (hl)
 57  ld d,a
 58  ld a,1 (iy)
 59  inc hl
 60  adc a, (hl)
 61  ld e,a
 62  ld a,d
 63  ld hl,#6
 64  add hl,sp
 65  add a, (hl)
 66  ld d,a
 67  ld a,e
 68  inc hl
 69  adc a, (hl)
 70  ld h,a
 71  ld l, d
 72 ;argtest.c:5: return sum;
 73  ret
 74 ;argtest.c:9: int plusplus(int d, int e, int f)
 75 ; ---------------------------------
 76 ; Function plusplus
 77 ; ---------------------------------
 78 _plusplus::
 79  call ___sdcc_enter_ix ; <-- sets up ix -- see below
 80 ;argtest.c:11: int sum = 0;
 81 ;argtest.c:13: for (i = 0; i < 5; i++)
 82  ld hl,#0x0000
 83  ld e,l
 84  ld d,h
 85 00102$:
 86 ;argtest.c:15: sum += plus(d, e, f);
 87  push hl  ; <-- caller save HL for for _plus (sum)
 88  push de  ; <-- caller save DE for for _plus (i)
 89  ld c,8 (ix)
 90  ld b,9 (ix)
 91  push bc
 92  ld c,6 (ix)
 93  ld b,7 (ix)
 94  push bc
 95  ld c,4 (ix)
 96  ld b,5 (ix)
 97  push bc
 98  call _plus
 99  pop af <-- throw away passed parameter d
100  pop af <-- throw away passed parameter e
101  pop af <-- throw away passed parameter f
102  ld c,l <-- return value low
103  ld b,h <-- return value high
104  pop de <-- restore caller saved registers
105  pop hl <-- restore caller saved registers
106  add hl,bc
107 ;argtest.c:13: for (i = 0; i < 5; i++)
108  inc de
109  ld a,e
110  sub a, #0x05
111  ld a,d
112  rla
113  ccf
114  rra
115  sbc a, #0x80
116  jr C,00102$
117 ;argtest.c:17: return sum;
118  pop ix
119  ret ; <-- HL already has sum
120  .area _CODE
121  .area _INITIALIZER
122  .area _CABS (ABS)

This is part of the library:

 1 ;--------------------------------------------------------------------------
 2 ;  crtenter.s
 3 ;
 4 ;  Copyright (C) 2015, Alan Cox, Philipp Klaus Krause
 5 ;
 6 ;  This library is free software; you can redistribute it and/or modify it
 7 ;  under the terms of the GNU General Public License as published by the
 8 ;  Free Software Foundation; either version 2, or (at your option) any
 9 ;  later version.
10 ;
11 ;  This library is distributed in the hope that it will be useful,
12 ;  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;  GNU General Public License for more details.
15 ;
16 ;  You should have received a copy of the GNU General Public License
17 ;  along with this library; see the file COPYING. If not, write to the
18 ;  Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
19 ;   MA 02110-1301, USA.
20 ;
21 ;  As a special exception, if you link this library with other files,
22 ;  some of which are compiled with SDCC, to produce an executable,
23 ;  this library does not by itself cause the resulting executable to
24 ;  be covered by the GNU General Public License. This exception does
25 ;  not however invalidate any other reasons why the executable file
26 ;   might be covered by the GNU General Public License.
27 ;--------------------------------------------------------------------------
28 
29  .area   _CODE
30 
31  .globl ___sdcc_enter_ix
32 
33 ; Factor out some start of function code to reduce code size
34 
35 ___sdcc_enter_ix:
36  pop hl ; return address
37  push ix ; save frame pointer
38  ld ix, #0
39  add ix, sp ; set ix to the stack frame
40  jp (hl) ; and return