#!/bin/bash -xe
{ cat <<EOF
mode 2
print "Hello from basic 1"
memory &2000-1
load "c.bin"
call &2000
print "Hello from basic 2"
call &2000+38,&0102
print "Hello from basic 3"
EOF
}|nl -w1|unix2dos>c.bas
iDSK c.dsk -n -i c.bas -t 0
init=0x$(bc <<<"obase=16;ibase=16;2000+10")
cat > crt0_cpc.s <<EOF
; FILE: crt0.s
; Generic crt0.s for a Z80
; From SDCC..
; Modified to suit execution on the Amstrad CPC!
; by H. Hansen 2003

  .module crt0
	.globl	_main

	.area _HEADER (ABS)
;; Reset vector
	.org 	0x2000
	jp	init
	
	.org	$init

init:

;; Initialise global variables
  call    gsinit
	call	_main
	jp	_exit

	;; Ordering of segments for the linker.
	.area	_HOME
	.area	_CODE
  .area   _GSINIT
  .area   _GSFINAL
        
	.area	_DATA
  .area   _BSS
  .area   _HEAP

  .area   _CODE
__clock::
	ret
	
_exit::
	ret
	
	.area   _GSINIT
gsinit::	

.area   _GSFINAL
    	ret
EOF
sdasz80 -o crt0_cpc.s
cat > putchar.s <<'EOF'
; FILE: putchar.s
; Modified to suit execution on the Amstrad CPC
; by H. Hansen 2003
; adjusted for new calling convention by karme
; 2025

	.area _CODE
_putchar::       
_putchar_rr_s:: 
        	; ld      hl,#2
        	; add     hl,sp
        	; ld      a,(hl)
		ld      a,l
        	call    0xBB5A
        	ret
           
_putchar_rr_dbs::
        	ld      a,e
        	call    0xBB5A
        	ret
EOF
sdasz80 -o putchar.s

cat > c.c <<'EOF'
#include <stdio.h>

char
printnumber(int i) {
__asm
	ld l,0(ix)
	ld h,1(ix)
__endasm;
    printf("%d\r\n",i);
    return 0;
}

int main()
{
  printf("C %p\r\n",printnumber);
  return 0;
}
EOF
sdcc -mz80 --code-loc \
0x$(bc <<<"obase=16;ibase=16;2000+38") \
--data-loc 0 --no-std-crt0 \
crt0_cpc.rel putchar.rel c.c
makebin -p c.ihx|tail -c \
+$(bc <<<"ibase=16;2000+1")>c.bin
iDSK c.dsk -i c.bin -e 2000 -c 2000
mame cpc664 -flop1 c.dsk -skip_gameinfo \
-ab '\n\nrun "c\n' -str 10
pngtopnm \
$(ls -1tr ~/.mame/snap/cpc664/*.png|tail -n1)\
|pnmscale -yscale 2|pnmtopng > c.png
