From fb8e8801a3a3a9907e3dfeba239c3f07eb3a8933 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Mon, 31 Oct 2022 18:09:28 -0400 Subject: Print elapsed time in MM:SS.CC --- mmss.s | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 mmss.s (limited to 'mmss.s') diff --git a/mmss.s b/mmss.s new file mode 100644 index 0000000..f1423b5 --- /dev/null +++ b/mmss.s @@ -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 + 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 + 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 -- cgit v1.2.3