LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Compiling and Running C code for the Pasocom Mini

Root / General / [.]

amihartCreated:
Since the Pasocom Mini comes with a Z80 emulator based on the MZ-80K line of computers, it is possible to compile and run C code for it using the Small Device C Compiler. SDCC can compile to Z80 but it knows nothing about the particular machine you're working on. That means there are a couple things you need to do specific to that machine. First, you'd need to create some sort of hardware-specific library. Here's a simple one I wrote up in a few minutes to get you started: pasocom.h
#define TRUE 1
#define FALSE 0
typedef unsigned char uint8;
typedef unsigned char bool;
typedef unsigned short uint16;

void main();
void _PutS(char* str);
void _NewLine();
void _GetKey();
void __init__();

#include "pasocom.c"
pasocom.c
void __init__() __naked {
	main();
	__asm
		jp 0
	__endasm;
}

int strlen(char* str) {
	uint16 i = 0;
	while (str[i] != 0) i++;
	return i;
}

void print(char* str) {
	str[strlen(str)] = 0x0D; //C expects null-terminated but Pasocom is 0x0D-terminated
	_PutS(str);
}

void _PutS(char* str) {
	__asm
		ld d, 5(ix)
		ld e, 4(ix)
		call #0x0015
	__endasm;
	(void)str;
}

void _NewLine() {
	__asm
		call #0x0006
	__endasm;
}

void _GetKey() {
	__asm
		call #0x09B3
	__endasm;
}
This contains a few hardware-specific calls. This is nowhere near done, I didn't even bother adding the return value to _GetKey() since we're only using it to pause here. It's just barely enough to get this program to work. (I usually expand upon the library as I need more hardware-specific functionality in my code.) You could then do a simple "Hello, World" like this: hello.c
#include "pasocom.h"

void main() {
	print("HELLO WORLD"); //MZ-80K doesn't have lower-case letters
	_NewLine();
	_GetKey();
}
This will print "HELLO, WORLD", a newline, then wait for you to press something before ending the program. To compile it, we'll need to know something about the memory layout of the MZ-80K, luckily this is documented online. We can begin storing programs in memory at RAM address 0x1200, and we'll store any other data at 0xA000. So, to compile our "hello.c" program, we can just do this:
sdcc -mz80 --no-std-crt0 --reserve-regs-iy --data-loc 0xA000 --code-loc 0x1200 hello.c -o ~tmp.hex
"-mz80" sets SDCC to Z80 mode. "--nostd-crt0" tells SDCC not to use a CRT0. This gives SDCC some information about how to build our program, but this is unnecessary. "--reserve-regs-iy" tells SDCC not to touch the IY indexing register. I don't know if this is necessary but some machines that can cause crashes if you mess with it, so it's best just not to. "--data-loc 0xA000" tells SDCC to store data at memory address 0xA000. "-code-loc 0x1200" tells SDCC to where in memory our program will be located when it is ran. The output you get from this is "~tmp.hex". This is a hexadecimal file representing our compiled program. You'll need to convert it into a binary file. On Windows, there's a program called "hex2bin" that will do it for you. On Linux, you can convert it with sed and xxd:
echo $(cut -c 10- < ~tmp.hex | sed 's/..$//' | tr -d '\n') > ~tmp.hxs
xxd -r -p < ~tmp.hxs > hello.z80
Finally, delete all the files named "~tmp" as SDCC will create a lot of them.
rm -f ~tmp*
What you will be left with is your compiled program, in this case we named it "hello.z80". You can copy and paste this onto the SD card of Pasocom Mini. Press F12 to navigate to HAL Monitor, then type "LD"and press enter, then look for your program. When you select it, it will ask you where you want to load it into memory. The default is 0x1200, so don't change it and just hit "Load", and it should say "LOADED HELLO.Z80". Then you need to tell HAL Monitor to jump to the program. Do this by typing "G1200" and pressing enter. You will get this screen: The screen will stay there until you press a key, then it will return back to HAL-MONITOR. And that's the general idea of how you'd build C code to run on the Pasocom Mini.