* * * * *

                     Timing code from inside an assembler

Back in March, I wrote about some 6809 optimizations [1] where I counted CPU
(Central Processing Unit) cycles by hand. I came across that code the other
day and thought to myself, my 6809 emulator [2] counts cycles, and I've
embedded it into my 6809 assembler [3]—how hard could it be to time code in
addition to testing it?

Turns out—not terribly hard. I added an option to the .TRON directive to
count cycles instead of printing code execution and have the .TROFF directive
print the cycle count (indirectly, since the code isn't run until the end of
the second pass of the assembler). Then I wrote up a few tests:

-----[ Assembly ]-----
       .test   "ROM-RAMx1-byte"
               ldx     #$8000
       .tron   timing
r2r1            sta     $FFDE
               lda     ,x
               sta     $FFDF
               sta     ,x+
               cmpx    #$FF00
               bne     r2r1
       .troff
               rts
       .endtst

;*****************************************************************

       .test   "ROM-RAMx2-byte"
               ldx     #$8000
       .tron   timing
r2r2            sta     $FFDE
               ldd     ,x
               sta     $FFDF
               std     ,x++
               cmpx    #$FF00
               bne     r2r2
       .troff
               rts
       .endtst

;*****************************************************************

       .test   "ROM-RAMx4-byte"
               ldx     #$8000
       .tron   timing
r2r4            sta     $FFDE
               ldd     ,x
               ldu     2,x
               sta     $FFDF
               std     ,x++
               stu     ,x++
               cmpx    #$FF00
               bne     r2r4
       .troff
               rts
       .endtst

;*****************************************************************

       .test   "ROM-RAMx8-byte"
savesp          equ     $0100
               orcc    #$50
               sts     savesp
               lds     #$FF00 - 8
       .tron   timing
r2r8            sta     $FFDE
               puls    u,x,y,d
               sta     $FFDF
               pshs    u,x,y,d
               leas    -8,s
               cmps    #$8000 - 8
               bne     r2r8
       .troff
               lds     savesp
               andcc   #$AF
               rts

       .endtst
-----[ END OF LINE ]-----

And upon running it:

-----[ shell ]-----
GenericUnixPrompt% a09 -ftest r2r.asm
ROM-RAMx1-byte:13: cycles=877824
ROM-RAMx2-byte:28: cycles=487680
ROM-RAMx4-byte:45: cycles=357632
ROM-RAMx8-byte:64: cycles=199136
-----[ END OF LINE ]-----

The results match what I calculated by hand, so that's good. It also found a
bug in the emulator—I had the wrong cycle count for one of the instructions.
It's a bit scary how easy it has become to test 6809 assembly code now that I
can do much of it when assembling the code.

[1] gopher://gopher.conman.org/0Phlog:2023/03/13.2
[2] https://github.com/spc476/mc6809
[3] https://github.com/spc476/a09

Email author at [email protected]