; print jiffies as seconds, with possible decimal point, to the ; active screen. ; unsigned divide based on Ullrich von Bassewitz's runtime/udiv.s. ; uses FR0 as a temp, rather than any of cc65's ZP storage, ; to avoid clobbering. FR0 = $d4 acc16 = FR0 ; 16 bits remainder = FR0+2 ; 8 bits temp = FR0+3 ; 16 bits _hz = $f0 ; must agree with timers.h! .import _scr_act_printnum, _scr_putc_active .import mulax10 ; extern void print_jif_sec(unsigned int jiffies); .export _print_jif_sec _print_jif_sec: jsr divbyhz lda acc16 ldx acc16+1 jsr _scr_act_printnum ; print the seconds (it's OK if it's 0) lda remainder bne @printfrac rts ; if it was an even number of seconds, we're done @printfrac: lda #'.' ; otherwise, we need a decimal point... jsr _scr_putc_active lda remainder ; remainder is 0..(_hz-1), scale to 100ths of a sec. ldx #0 jsr mulax10 ; convenient cc65 runtime routine... jsr mulax10 ; AX now remainder * 100 sta acc16 stx acc16+1 jsr divbyhz ; acc16 = remainder / hz lda acc16 ; acc16 range is 0..99 (ignore hi byte) cmp #$0a ; does it need a leading zero? bcs @no_0 lda #'0' jsr _scr_putc_active lda acc16 ; clobbered by printing, reload @no_0: ldx acc16+1 jmp _scr_act_printnum ; print it, we're done ; NOTE: if we wanted to, we could round, by checking the high bit ; of remainder and adding one to acc16 before printing. not going ; to bother for now, making it look more accurate won't make it ; really *be* more accurate. ; divide 16-bit a/x by 8-bit _hz. ; result in acc16, remainder in remainder. divbyhz: sty temp sta acc16 stx acc16+1 lda #0 ldy #16 @L0: asl acc16 rol acc16+1 rol a bcs @L1 cmp _hz bcc @L2 @L1: sbc _hz inc acc16 @L2: dey bne @L0 sta remainder ldy temp rts