1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
; 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
|