A zpragma.inc file is going to be added to the compile this time to specify that printf should support "%B" (16-bit binary number) and "%s" (0-terminated string). "%B" is not supported in the default library build so that's why this pragma file is needed. The example is a little more complicated than I wanted it to be for this reason but it's essential for the joke.
"zpragma.inc"
Code: Select all
// determine which converters printf supports
#pragma printf = "%B %s"
Code: Select all
; zcc +zxn -vn -startup=30 -clib=sdcc_iy zzz3.asm -o zzz3 -pragma-include:zpragma.inc -subtype=dot -create-app
; copy "ZZZ3" to /bin on the sd card and run with ".ZZZ3"
SECTION code_user
PUBLIC _main
EXTERN asm_write, asm_puts, asm_printf
_main:
; asm_write prints a buffer
ld hl,1 ; use stream attached to fd=1 (normally stdout)
ld de,msg
ld bc,msg_end - msg
call asm_write
; asm_puts prints a 0-terminated string to stdout
ld hl,msg
call asm_puts
; asm_printf prints a complex string
; the sdcc library requires parameters to be pushed in right to left order on the stack
ld hl,string
push hl ; %s - zero terminated string
ld hl,2
push hl ; %B - binary number
ld hl,format
push hl ; format string
call asm_printf
pop af
pop af
pop af ; clean up stack
; report success to esxdos
ld hl,0
ret
msg:
defm "Hello World!\n"
msg_end:
defb 0 ; 0-terminate string for asm_puts
format:
defm "There are %B types of people in the world:\nThose who understand %s and those who don't.\n", 0
string:
defm "binary", 0
asm_write ( https://github.com/z88dk/z88dk/blob/mas ... te.asm#L24 ) is very much like basic's PR_STRING in that a buffer of ascii text is given along with a length. This is a very lightweight print routine.
asm_puts ( https://github.com/z88dk/z88dk/blob/mas ... m_puts.asm ) is also fairly lightweight and will print a 0-terminated string.
asm_printf ( https://github.com/z88dk/z88dk/blob/mas ... tf.asm#L29 ) is C's monster print function and as you can see it can insert numbers, strings, etc into some output text as it is printed. This is an expensive function (in size) but it's quite nice to use if you need its functionality. The pragma in the zpragma.inc file limits printf to implement only converters that your program uses and this is helpful in keeping its size small.
The z88dk library is quite large and all you have to do to use functions in it is to declare the function EXTERN and then call it. The EXTERN directive tells the linker to find the code either in another file in your project or in the library.
In this case the advantage to using z88dk's io is that it doesn't use the rom (except for RST$10 in this particular startup) so that it's perfectly fine to print a string stored in the dot command itself. The downside is that because the rom is not used, the dot command will be bigger. "asm_printf" is a big contributor to this binary (probably 1500+ bytes) so if you don't need it, not using it will make the dot much smaller.