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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
print_mmss:
; calculate and print elapsed time
; uses the floating point ROM routines, because it's easier to code
; this way and we don't need speed here.
ldx #0 ; low byte of 256 (0)
stx FR0
inx
stx FR0+1 ; high byte of 256 (1)
jsr IFP ; FR0 now FP 256.0
jsr FMOVE ; FR1 = FR0 (both are 256.0)
jsr FMUL ; FR0 = FR0 * FR1 (65536.0) (and FR1 is now garbage, but...)
jsr FMOVE ; FR1 = FR0 (didn't need it anyway)
; cloksav is 3 bytes, MSB-first (like RTCLOK).
; first, convert the highest byte to jiffies:
ldx #0
stx FR0+1
lda cloksav
sta FR0
jsr IFP ; FR0 now cloksav in FP, FR1 = 65536.0
jsr FMUL ; FR0 = FR0 * FR1
jsr FMOVE ; FR1 = FR0, aka the high byte of cloksav in jiffies
; next, convert low 2 bytes of cloksav to FP...
lda cloksav+1
sta FR0+1
lda cloksav+2
sta FR0
jsr IFP ; ...ok, now:
jsr FADD ; add the high bytes in jiffies, result in FR0 again
; copy to fptmp before dividing (we need it later)
ldx #<fptmp
ldy #>fptmp
jsr FST0R
; we now have the 3-byte jiffy count in FR0 and fptmp.
; 3600 NTSC jiffies or 3000 PAL jiffies = 1 minute, so divide.
; floating point constants:
; 3600.0 is $41,$36,$00,$00,$00,$00
; 3000.0 is $41,$30,$00,$00,$00,$00
jsr load_jpm_fr1
jsr FDIV ; FR0 = FR0 / FR1 (and FR1 is now garbage)
; FR0 is now minutes elapsed (e.g. 1.5, for 90 sec). Only print the
; integer part...
; FP ROM has no equivalent to trunc(). You might think you could call
; FPI followed by IFP, but FPI rounds up (e.g. 1.5 comes out as 2,
; not 1). But it's not hard to do:
lda FR0 ; exponent
beq truncdone
and #$4f ; ignore sign
sec
sbc #$3f ; A gets either 1 or 2
tax
lda #0
truncloop:
sta FR0+1,x
inx
cpx #5
bne truncloop
truncdone:
; print digits in FR0
lda FR0
and #$03
sta tmp1
inc tmp1
ldx #0
floop:
lda FR0+1,x
jsr printhex
inx
cpx tmp1
bcc floop
floopdone:
; done printing minutes, let's have the separator
lda #':'
jsr printchr
; multiplication and division trash FR1, which is annoying.
jsr load_jpm_fr1
jsr FMUL
jsr FMOVE
; reload original jiffy count into FR0
ldx #<fptmp
ldy #>fptmp
jsr FLD0R
; subtract FR1. FR0 ends up with jiffies modulo jiffies-per-sec.
jsr FSUB
; load 0.6 into FR1 so we can divide by it.
; result will be number of centisec.
jsr zero_fr1
lda #$3f
sta FR1
lda #$60
sta FR1+1
jsr FDIV
; *now* we can actually make use of FPI's rounding!
jsr FPI
jsr IFP
; FR0 has division result, which is centiseconds.
; if the exponent is 0, we're OK. otherwise, shift down
; one byte so we print 00 for the seconds.
lda FR0
and #$0f
bne twodigits
lda FR0+1
sta FR0+2
lda #0
sta FR0+1
twodigits:
lda FR0+1
jsr printhex
lda #'.'
jsr printchr
lda FR0+2
jsr printhex
rts
; load jiffies-per-minute into FR1. needs done twice so
; it's a subroutine.
load_jpm_fr1:
jsr zero_fr1
lda #$41 ; excess-64 base-100 exponent and sign (bit 7 = 0 means positive)
sta FR1
ldx #$36 ; 1st mantissa BCD byte, NTSC
lda PAL
and #$0e
bne ntsc
ldx #$30 ; 1st mantissa BCD byte, PAL
ntsc:
stx FR1+1
rts
; ZF1 does *not* just clear out FR0, it uses the X reg as an 8-bit
; pointer (to zero page only).
zero_fr1:
ldx #FR1
jsr ZF1
rts
|