Debugging in SP1

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
Posts: 59
Joined: Sun Oct 28, 2018 3:35 pm

Debugging in SP1

Post by jordi »


I am usually using zx_border as a way to trace code. Is there a way I could print a string while using sp1? When I tried I end with linker errors in regards of printf. I'm using this line for compiling
zcc +zx -v -clib=sdcc_iy -Cz--screen=screen.scr -startup=31 -DWFRAMES=3 -O3 @zproject.lst -o misifu -L$(VT_SOUND_LIB_SDCC_IY) -lvt_sound -create-app
I would like to be able to print cat x and y all the time, so I can debug it easier.

Well known member
Posts: 181
Joined: Sat Mar 10, 2012 4:18 pm

Post by Timmy »

Alvin can probably explain this better than I do, but if you look in the sp1.h file, you can find functions like

Code: Select all

void sp1_PrintAt(uint16_t row, uint16_t col, uint16_t colour, uint16_t tile)

void sp1_SetPrintPos(struct sp1_pss *ps, uint16_t row, uint16_t col)
void sp1_PrintString(struct sp1_pss *ps, uint8_t *s)
I usually use the top function (but it's slow), as I have no idea how to use the other 2, but there is not something like printf(), in that can you can write your own (or use my very slow one).
Posts: 50
Joined: Mon Mar 26, 2018 1:49 pm

Post by derekfountain »

You don't say what the linker error is, but using -startup=0 in your zcc line will probably solve it.

I've done something similar to what you're trying while using SP1 - include stdio.h then add a printf. It kinda works, sometimes, but the screen gets messy very quickly as the SP1 updater splatters all over the printed text. It's also slow and memory-expensive.

If that doesn't work, as Timmy says, you can use the SP1 string print routines with sprintf to build what you need. It'll work better with the screen, but it's not as simple as dropping a simple printf into your code.

I solved this problem myself using a completely different technique, described here:

but it isn't really a solution I'd expect anyone else to be able to use.

I'm not really sure what the best answer is, to be honest.
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

In your compile line "-startup=31" means you are getting a minimal crt with no streams (no stdout, stdin) so printf and scanf have nothing to connect to. As mentioned you can change your startup to something like "-startup=0" and then you will have stdin,stdout and can printf and scanf. But since that printing is done directly to screen, sp1 will overwrite it unless you tell sp1 to stay away from part of the screen or you do not draw in that part of the screen. It will also add a few k to your program size; you can keep printf small by adding a pragma that eliminates the % coverters you are not using and you can eliminate stdin entirely by adding a custom driver instantiation to your project.

Within sp1, you can use sp1_PrintAt() and sp1_PrintAtInv() to print individual characters as you've been doing. I wouldn't say it's slow but it is one char at a time and that does mean a character position calculation on each call.

sp1_PrintString() prints a string that can contain control codes. One of the things it's meant for is printing the entire screen for a level in a compact way without loops and individual PrintAt, so it should save memory if levels are printed this way. To print strings with it, you need a struct sp_pss (Print String Structure, ... sp1.h#L123 ) that holds print state - things like current x,y position and flags for what to do if when the text reaches the right edge or bottom of the screen.

Code: Select all

struct sp1_Rect fs = { 0, 0, 32, 24};   // rectangle covers full screen

struct sp1_pss pss = {
   &fs,   // print confined to this rectangle
   0,    // current x
   0,    // current y
   0,    // attribute mask - overwrite underlying colour
   0,    // sp1_update* must be consistent with x,y
   0    // visit function (set to zero)

sp1_SetPrintPos(&pss, 10, 10);   // this sets x,y and sp1_update* in pss
sp1_PrintString(&pss, "Hello World");
The printing uses background tiles. % converters as in printf do not work but if you need that you can sprintf to a buffer first and then print the string result.
The control codes it understands are listed here: ... ng.asm#L22
Notice that it follows the spectrum character set where \r means next line (not \n).
Posts: 59
Joined: Sun Oct 28, 2018 3:35 pm

Post by jordi »

Thank you so much to all, I'll apply them!!!
Post Reply