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