From d79dd55a18cb158778fbdc796a60f27518d1f971 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 18 Jun 2024 06:53:54 -0400 Subject: cxrefbas and renumbas: round fractional line numbers like BASIC does. --- bcdfp.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'bcdfp.c') diff --git a/bcdfp.c b/bcdfp.c index 76157c1..a80e55d 100644 --- a/bcdfp.c +++ b/bcdfp.c @@ -1,8 +1,18 @@ #include +#include #include "bcdfp.h" +/* very dumb and limited BCD floating point conversions. + they're written this way because they're only required to + support line numbers, and I don't want to have to link with + the math library (-lm). */ + extern void die(const char *msg); +void die_range(void) { + die("Line number out of range (>65535)"); +} + unsigned char bcd2int(unsigned char bcd) { return (bcd >> 4) * 10 + (bcd & 0x0f); } @@ -12,24 +22,32 @@ unsigned char int2bcd(unsigned char i) { } unsigned short fp2int(const unsigned char *fp) { - unsigned short result = 0; + unsigned int result = 0; /* examine the exponent/sign byte */ if(fp[0] == 0) return 0; /* special case */ - if(fp[0] & 0x80) die("negative numbers not supported"); + if(fp[0] & 0x80) die("Negative line numbers not supported"); switch(fp[0]) { case 0x40: - result = bcd2int(fp[1]); break; + result = bcd2int(fp[1]); + if(fp[2] >= 0x50) result++; + break; case 0x41: - result = bcd2int(fp[1]) * 100 + bcd2int(fp[2]); break; + result = bcd2int(fp[1]) * 100 + bcd2int(fp[2]); + if(fp[3] >= 0x50) result++; + break; case 0x42: - result = bcd2int(fp[1]) * 10000 + bcd2int(fp[2]) * 100 + bcd2int(fp[3]); break; + result = bcd2int(fp[1]) * 10000 + bcd2int(fp[2]) * 100 + bcd2int(fp[3]); + if(fp[4] >= 0x50) result++; + break; default: - die("number out of range"); break; + die_range(); break; } - return result; + if(result > 0xffff) die_range(); + + return (unsigned short)result; } void int2fp(unsigned short num, unsigned char *fp) { -- cgit v1.2.3