A strange alien command-line tool has appeared since 3.5: the Z80 profiler (ZP).
The Z80 profiler is included, for now, to AT3, but it may be exported to its own repository one day, since it is not really a music tool. However, it was easier for me to set it up this way!
It is a tool that executes a Z80 binary code and indicates how many NOPs (CPC NOPs) it took to execute the code. The code is executed many times, so that you could, say, profile a music player. At the end, the tool indicates the minimum, maximum and average NOP count. It can also produce a CSV report if you want to make some statistics.
Under the hood, a Z80 emulator runs your code as if you were calling the real code on the machine. But much faster!
How it works
The use is simple, and generic (you could profile a music player, your 3D code, or anything else):
- ZP loads your binary file at a given address.
- ZP optionally runs an init code on startup (typically, if you want to initialize a music player). A value in register A can be passed (useful to, say, select a subsong!)
- Then, ZP runs the main code 10000 times (this value can be changed).
- A report is shown or generated.
In order to know what to execute, ZP requires a Z80 binary file with a specific format:
- Two hooks must be given at the beginning of your code: the init hook (at address +0), and the exec hook (at address +3). Both these addresses can be changed.
- Once your init/exec code is finished, make a jump to #FFFF (this value can be changed).
A typical code would look like this, for the AKY player (but ANY code would work):
org #4000 ;It can be anything!
;Hooks.
jp Init ;Start +0. ZP will jump here to init.
jp Exec ;Start +3. ZP will jump here for each execution.
Init
;Init your code.
;Here, it is the initialization of a player, but it could be anything!
ld hl,Music_Start
call PLY_AKY_Init
jp #ffff ;Go back to the profiler. This address can be changed.
Exec
;This is the piece of code that will be called many times.
;Here, we call the player in order to profile it!
call PLY_AKY_Play
jp #ffff ;Go back to the profiler. This address can be changed.
Music_Start
include "AkyMusic.asm"
include "AkyMusic_playerconfig.asm"
include "PlayerAky.asm"
Running the tool
Assemble your code with any assembler. The command-line tool (present in the commandLineTools folder) can then simply be called like this:
Z80Profiler binary.bin
The default “load address” is #4000, but you can change it with the option --loadAddress.
ZP being independent from any machine, you can compile a binary at 0, or any address you feel like! Watch our however:
- The interruptions are disabled.
- The stack pointer is set at #FFFF by default (first written word is thus #FFFD / #FFFE).
- The “exit” address is #FFFF by default.
If these last bullet points bothers you, use the option --spAddress and --stopAddress to change them.
The output for the above could look like this:
Loaded the file in 0x4000.
Calling the initializaton code from address 0x4000.
Init code NOPs: 55
Calling the exec code from address 0x4003, 10000 times...
Exec code iteration 0. NOPs: 712
Exec code iteration 1000. NOPs: 546
Exec code iteration 2000. NOPs: 499
...
Profiling done!
Minimum NOPs: 458
Maximum NOPs: 811
Average NOPs: 539
Handy, right?
There are many options in this tool, so don’t hesitate to check them out (run the tool without parameter to get the help).
NOP counting
Things to know about the NOP counting:
- The NOP counting mechanism uses the “CPC” way of counting cycles. It differs a bit from other hardware. If you’re interested in me adding other options, please let me know!
- The counting shown already takes in account the hooks (JP at +0/+3) and the
JP #FFFFin your init/exec code. - If your setup has more instructions in the exec code (calling the player, doing this or that…), use the
--execOverheadNopsto indicate of how many NOPs to subtract to the end result (5 in the above case (call PLY_AKY_Play)).
Wrapping up
This small tool is experimental and still very young. I’d like to thank Krusty for suggesting it to me! It probably lacks some options I didn’t think of, so don’t hesitate to contact me if you have any!