A contest to reduce code size

Programming the 6502 microprocessor and its relatives in assembly and other languages.
WillisBlackburn
Posts: 51
Joined: 14 Aug 2021

Re: A contest to reduce code size

Post by WillisBlackburn »

I'm happy to report that I've reduced the Apple II version down to 8,186 bytes! This version is the v0.3.2 tag on GitHub. There are a few bug fixes too, e.g., comparisons of negative numbers work correctly now.

My `ROUND` is not exactly the same as `INT(X+0.5)`; it's actually `INT(X+0.5*SGN(X))` which is either better or totally wrong. I need the `round` function in fp.s to implement `fexp` and `fsin`, and I optimized function dispatching so that BASIC functions that just wrap the floating point functions are almost free (in terms of space), so I was able to keep `ROUND`.

I'm still slower than Applesoft, but at least I'm not slower *and* larger.

More later on the other topics.
soci
Posts: 20
Joined: 18 Nov 2019

Re: A contest to reduce code size

Post by soci »

Name it "CINT". That's how it is called elsewhere and saves a byte too.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: A contest to reduce code size

Post by barrym95838 »

In TRS-80 Level 2 BASIC it's called FIX, for an additional byte of savings.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: A contest to reduce code size

Post by drogon »

Floating point is (IMO) badly handled by many languages (and programmers!) It's hard to get right and harder to please everyone with your interpretation of right ...

In the C world we have floor(), ceil() and rint(). Floor truncates to the nearest integer down, ceil truncates to an integer up and rint is round to nearest integer. Or you can changing the rounding direction, decide to raise exceptions or not then there's round to even or not ... Sometimes it' a bit much.

So is floor (-1.5) -1 (rounding to zero) or -2 (rounding down) ?

I'm in the process of implementing some ieee754 floating point routines on a platform with no hardware FP and looking at various libraries and how they work while implementing my own. It seems the GNU routine in one library I have; "fix" is close to floor rounding to zero. And that's all it has - other operations have to be synthesized.

I'd really like to see an IEEE754 library for the 65C02/816 but it'll have to wait. A down-side is that it's "only" 4 bytes rather than 5, but the reality is that we rarely need more precision than what that affords. Everything more is basically peacocking in our little Basic world.... However the advantages to a 5-byte format is the ease of manipulating a 4-byte mantissa - especially if you already have good, fast routines to manipulate 32-bit quantities (in e.g. BBC Basic). IEEE format needs unpacking and re-packing for each operation unless you have the means to fuse operations such as a multiply and add where you could keep them internally in their unpacked format. Now - some "classic" minicomputer Basics do have matrix operations, but they're rare in the microcomputer world.

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: A contest to reduce code size

Post by BigEd »

Five byte floats are handy for being able to store four byte integers…
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: A contest to reduce code size

Post by BigDumbDinosaur »

drogon wrote:
I'd really like to see an IEEE754 library for the 65C02/816 but it'll have to wait.
There is this for the 65C816...not sure if it meets your desires.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
WillisBlackburn
Posts: 51
Joined: 14 Aug 2021

Re: A contest to reduce code size

Post by WillisBlackburn »

BigEd wrote:
Five byte floats are handy for being able to store four byte integers…
You know, that what I had hoped. I thought, with a 32-bit significand, I can represent every 32-bit integer value.

Except not quite, for two reasons:

1. With a separate sign bit it's not possible represent -2,147,483,648, which you can represent with a 32-bit int. We *could* represent that if we stored the significand in two's complement form, though, which is what Woz did with his FP library. I actually did implement that originally, but it creates problems when you really need to negate a number that might be -2,147,483,648.

2. Even if you can represent -2,147,483,648, you can't easily print it, because you can really only safely print 9 digits. If you print 10 digits, and if the number is in the range -(2^31) to 2^31-1, you'll probably get the right output, but if the number is 5 billion-something, then the 10th digit will just be garbage.
soci
Posts: 20
Joined: 18 Nov 2019

Re: A contest to reduce code size

Post by soci »

Checked CINT on TRS80 and it does truncate (same like FIX) instead of round to nearest for some reason. And also noticed that INT on VC83 truncates instead of flooring.
WillisBlackburn
Posts: 51
Joined: 14 Aug 2021

Re: A contest to reduce code size

Post by WillisBlackburn »

soci wrote:
Checked CINT on TRS80 and it does truncate (same like FIX) instead of round to nearest for some reason. And also noticed that INT on VC83 truncates instead of flooring.
Interesting. I didn't know that INT is actually a floor function but it looks like Applesoft and Atari at least both work that way.
User avatar
barrym95838
Posts: 2056
Joined: 30 Jun 2013
Location: Sacramento, CA, USA

Re: A contest to reduce code size

Post by barrym95838 »

Screenshot 2026-03-26 185556.jpg
It's not clear to me what the difference is between INT and CINT, but it may be subtle.
Got a kilobyte lying fallow in your 65xx's memory map? Sprinkle some VTL02C on it and see how it grows on you!

Mike B. (about me) (learning how to github)
John West
Posts: 383
Joined: 03 Sep 2002

Re: A contest to reduce code size

Post by John West »

barrym95838 wrote:
It's not clear to me what the difference is between INT and CINT, but it may be subtle.
It's described in the manual: CINT returns an integer, INT returns an integer-valued single precision floating point number. Both are floor operations, so they'll both choose the same integer if it's in the range of their result type. However, INT(1000000.1) will give you 1000000.0, while CINT(1000000.1) gives an error because that's out of range.

There are four rounding operations in common use: floor rounds towards negative infinity, ceil rounds towards positive infinity, truncate rounds towards zero, round rounds towards the nearest integer. Round should return the nearest even integer if the fractional part is exactly one half, but simple implementations don't always do that.
WillisBlackburn
Posts: 51
Joined: 14 Aug 2021

Re: A contest to reduce code size

Post by WillisBlackburn »

Okay, you all wanted INT to do floor, so now it does floor.

Since now ROUND(X) is exactly INT(X+0.5), I removed ROUND to save 10 or so bytes.
Post Reply