diff options
author | B. Watson <urchlay@slackware.uk> | 2022-10-31 18:09:28 -0400 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2022-10-31 18:09:28 -0400 |
commit | fb8e8801a3a3a9907e3dfeba239c3f07eb3a8933 (patch) | |
tree | 1904371ab09dcff45593fb0c18ae9000f72ca292 /mmss.s | |
parent | b0d6af17e313ac574fc7db761c79a812ec2ecf15 (diff) | |
download | dla-asm-fb8e8801a3a3a9907e3dfeba239c3f07eb3a8933.tar.gz |
Print elapsed time in MM:SS.CC
Diffstat (limited to 'mmss.s')
-rw-r--r-- | mmss.s | 150 |
1 files changed, 150 insertions, 0 deletions
@@ -0,0 +1,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 |