If you're using devkitsms (SMSlib and PSGlib are its two parts), the controller scan is done in the interrupt service routine:
https://github.com/z88dk/z88dk/blob/mas ... sr.asm#L38
This isr is automatically put in place if you compile using a devkitsms crt. The crt is the code at address 0 that puts in code for the restarts, im1, nmi etc and devkitsms provides this for its api. The devkitsms crts are actually 16,17,18 (not 0,1,2 which are crts without devkitsms).
divkitsms page zero code:
https://github.com/z88dk/z88dk/blob/mas ... kitSMS.inc
the sms crts:
https://github.com/z88dk/z88dk/tree/mas ... ms/startup
16 = devkitsms, no printf driver
17 = devkitsms, printf driver without control codes
18 = devkitsms, printf driver with control codes
Unlike most targets, on the sms, printf is not immediately functional as you have to load a font into tile memory. This is described in the helloworld example:
https://github.com/z88dk/z88dk/tree/mas ... helloworld
A nice example of using devkitsms can be seen in astroforce although the source code organization is not ideal (there should never be code in header files):
https://github.com/z88dk/z88dk/tree/mas ... AstroForce
So I think you need to use startup=17 to get a devkitsms compile with printf driver. And then you'll need some code to load a font in and you'll need to separate the font's use of tiles from the tiles used for the game itself.