Fun with CBM arithmetics

Basic and Machine Language

Moderator: Moderators

User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Proposal for a patch

Post by Mike »

Here's my proposal for a patch:

1. It is intended to keep the optimization,
2. It must be ensured, that the routine at $D983 is always called with C=1,
3. It must be ensured, that the contents of $68 are 0 upon calling $D983.

The routine in question is buried (too) deep into the BASIC ROM, and it is not vectored.
A patch will require the replacement of the BASIC ROM.

4. DA5B JMP $D983 needs to be rerouted to a suitably 'empty' place within $C000 .. $DFFF,
5. one possible candidate might be the range $DF53 .. $DF70:

The addresses $DF53 .. $DF70 contain only $AA's and are located after two tables, which contain powers of 10 and TI conversion constants, but the conversion loop beginning at $DE66 (spanning to $DEC2) stops at Y=$24 or Y=$3C and never reaches into $DF53 .. $DF70. There are also no other references in the BASIC ROM to that address range.

[...]

Edit: I replaced the original version of the patch with a revised one (download). For the source, see a few posts further down this topic.
Last edited by Mike on Thu Feb 20, 2014 5:10 pm, edited 2 times in total.
User avatar
orion70
VICtalian
Posts: 4337
Joined: Thu Feb 02, 2006 4:45 am
Location: Piacenza, Italy
Occupation: Biologist

Re: Fun with CBM arithmetics

Post by orion70 »

Congrats on being the first to release software in 2014 :)
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Fun with CBM arithmetics

Post by Mike »

orion70 wrote:Congrats on being the first to release software in 2014 :)
PM sent. :)
User avatar
Kweepa
Vic 20 Scientist
Posts: 1314
Joined: Fri Jan 04, 2008 5:11 pm
Location: Austin, Texas
Occupation: Game maker

Re: Fun with CBM arithmetics

Post by Kweepa »

Checked out the other emulators in VICE.
BASIC 2, 3.5 and 4 suffer from this bug, but it's absent in BASIC 7.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Fun with CBM arithmetics

Post by Mike »

In the last two days I checked the patched BASIC ROM in two installations of VICE on my notebook.

As a picture is more worth than a thousand words, I got the idea to use my Mandelbrot zoomer for illustrating purposes: :mrgreen:

Here's a co-ordinate set, where both x- and y-coordinates just straddle across a critical interval:

Code: Select all

x_min = -0.531250128
x_max = -0.531249872
y_min =  0.531249904
y_max =  0.531250096
1024 Iterations
Now for the results, with the original ROM to the left (download) and with the patched ROM to the right (download):

Image Image

Parts of the left picture are distorted and torn, compared to the right picture.

Here's the same co-ordinate set computed on the PC, same display algorithm, just higher resolution:

Image

Edit: refined example
Last edited by Mike on Thu Feb 20, 2014 5:11 pm, edited 1 time in total.
User avatar
Jeff-20
Denial Founder
Posts: 5759
Joined: Wed Dec 31, 1969 6:00 pm

Re: Fun with CBM arithmetics

Post by Jeff-20 »

I love it.
High Scores, Links, and Jeff's Basic Games page.
User avatar
buzbard
Vic 20 Devotee
Posts: 213
Joined: Sun Jul 03, 2005 9:10 am

Re: Fun with CBM arithmetics

Post by buzbard »

Nice work Mike! Thanks. :D
Kweepa wrote:Nice find!
The same bug is of course in the c64...
Here's the same patch modified for the C64.

Code: Select all

10 open2,8,2,"basic,s,r"
11 open3,8,3,"basic-p,s,w"
12 fort=40960to49151
13 get#2,a$:a=asc(a$+chr$(0))
14 ift=47708thena= 83:goto22
15 ift=47709thena=191:goto22
16 ift=48979thena=133:goto22
17 ift=48980thena=104:goto22
18 ift=48981thena= 56:goto22
19 ift=48982thena= 76:goto22
20 ift=48983thena=131:goto22
21 ift=48984thena=185
22 print#3,chr$(a);
23 next
24 close3
25 close2
The VIC and the C64 have almost exactly the same BASIC ROM just located in different memory ranges.
VIC - C000-DFFF
C64 - A000-BFFF
Ray..
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Fun with CBM arithmetics

Post by Mike »

On the C64, it is also possible to copy the BASIC-ROM into the RAM, and patch it there. Here's a program which does exactly this:

Code: Select all

1 POKE1,PEEK(1)AND248OR7
2 FORT=40960TO53247:POKET,PEEK(T):NEXT
3 POKE47708,83:POKE47709,191
4 FORT=0TO5:READA:POKE48979+T,A:NEXT
5 POKE1,PEEK(1)AND248OR6
6 DATA133,104,56,76,131,185
Here's a revised version of the patch, which installs an own routine to handle the mantissa in the free range of $DF53 .. $DF70, and does not anymore 're-use' the normalize routine. Even if it now uses up some more bytes of that free space, it is now implemented as it should have been done in the first place. The jump at $DA5B now is altered to:

Code: Select all

.DA5B  4C 5A DF  JMP $DF5A
... and the routine at $DF5A now is:

Code: Select all

.DF5A  A5 29     LDA $29
.DF5C  85 70     STA $70
.DF5E  A5 28     LDA $28
.DF60  85 29     STA $29
.DF62  A5 27     LDA $27
.DF64  85 28     STA $28
.DF66  A5 26     LDA $26
.DF68  85 27     STA $27
.DF6A  A0 01     LDY #$01
.DF6C  98        TYA
.DF6D  4A        LSR A
.DF6E  85 26     STA $26
.DF70  60        RTS
This is, what the original shortcut at $D983 was supposed to do, only that one fails under those circumstances I already described in the earlier postings. The following program applies the new patch to a *.bin file of the BASIC ROM:

Code: Select all

10 OPEN2,8,2,"BASIC,S,R"
11 OPEN3,8,3,"BASIC-P,S,W"
12 READB,C,D
13 FORT=49152TO57343
14 GET#2,A$:A=ASC(A$+CHR$(0))
15 IFB<>TTHEN18
16 IFA<>CTHENPRINT"BAD SOURCE FILE!":GOTO20
17 A=D:READB,C,D
18 PRINT#3,CHR$(A);
19 NEXT
20 CLOSE3
21 CLOSE2
22 :
23 DATA 55900,131, 90
24 DATA 55901,217,223
25 DATA 57178,170,165
26 DATA 57179,170, 41
27 DATA 57180,170,133
28 DATA 57181,170,112
29 DATA 57182,170,165
30 DATA 57183,170, 40
31 DATA 57184,170,133
32 DATA 57185,170, 41
33 DATA 57186,170,165
34 DATA 57187,170, 39
35 DATA 57188,170,133
36 DATA 57189,170, 40
37 DATA 57190,170,165
38 DATA 57191,170, 38
39 DATA 57192,170,133
40 DATA 57193,170, 39
41 DATA 57194,170,160
42 DATA 57195,170,  1
43 DATA 57196,170,152
44 DATA 57197,170, 74
45 DATA 57198,170,133
46 DATA 57199,170, 38
47 DATA 57200,170, 96
48 DATA    -1, -1, -1
I also found some interesting reference about those early implementations of Microsoft BASIC on the 65xx. The owner of the blog reconstructed one single source code repository for CBM BASIC V1, OSI BASIC, AppleSoft I, KIM-1 BASIC, CBM BASIC V2 (PET), Intellivision Keyboard Component BASIC and MicroTAN BASIC ... and with the exception of OSI BASIC (it only uses a 3-byte mantissa, thus the error can't happen there) all share that bug in the multiplication routine ...!
Kweepa wrote:Checked out the other emulators in VICE.
BASIC 2, 3.5 and 4 suffer from this bug, but it's absent in BASIC 7.
Yes, I saw that, too. The bug is absent in V7, because Commodore effectively disabled the optimization that caused it. Of course, that means that multiplication now is generally slower on the C128.

Even *more* interesting is, that they somehow came to the same conclusions about the carry flag as I did, but they were not quite sure about how to handle it. In the BASIC ROM, the routine is located at $8A55:

Code: Select all

.8A55  D0 04     BNE $8A5B
.8A57  EA        NOP
.8A58  4C 62 89  JMP $8962
.8A5B [...]
... with $8962 again being the short-cut. At $8A57, they had possibly put a SEC before - and then decided to go the save route by disabling the optimization instead (only in one of five cases, the routine is still called over $8A55, all other 4 calls enter at $8A5B). Anyway they had more than enough space in the ROM to do it right, but alas. :(
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Fun with CBM arithmetics

Post by Mike »

Mike wrote:A patch will require the replacement of the BASIC ROM.
In case you've been wondering what became of this, look here. :mrgreen:
Kakemoms
Vic 20 Nerd
Posts: 740
Joined: Sun Feb 15, 2015 8:45 am

Re: Fun with CBM arithmetics

Post by Kakemoms »

I am hoping to get this patch (and others) into the SuperVixen. It will be in a copy of Basic in the external cartridge, so not a replacement ROM, but patched during copy to external RAM.

I am wondering if anyone has a list of such patches? I am thinking about a file format to get them loaded and patched during boot, so that anyone finding such problems in the future, will also be able to add their own patch.

What do you think about it?
Last edited by Kakemoms on Sat Feb 17, 2018 6:01 pm, edited 1 time in total.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Fun with CBM arithmetics

Post by Mike »

Regards your question of a feasible file format: you'd most probably be content with a *.prg file that executes the patch by copying the original ROM contents, doing a check whether it works on the original byte values it aims to replace, and putting the replacement bytes there. Much similar to how I proceeded with the file based patch here.
Kakemoms wrote:I am wondering if anyone ha[s] a list of such patches?
From what I know, this is probably the first - and thus far only one - direct patch of the VIC-20 BASIC ROM.

There are other known bugs in the CBM BASIC interpreter, but they are mostly irrelevant or easy to avoid: broken type checks lead to overflow of the string stack in the IF ... THEN clause and POS() function with bogus string arguments, or to crashes as with the statement PRINT 5+"A"+-5 ... then there is also a bug in the line number parse routine, which results in a warm start or crash upon entering a certain range of (invalid!) line numbers. In other cases, it is rather easy to improve the BASIC interpreter by means of a BASIC extension/wedge or USR() function - if you count the slowness of the SQR() function as "bug".

As I wrote earlier in the thread, the multiplication routine is buried too deep in the interpreter, and it is not vectored. A soft replacement would require a duplication of a good deal of ROM code of the expression parser down to the multiplication routine itself, and that fixed shortcut routine. We are talking about way more than 1K code here. And it also only helps BASIC programs: machine code programs that happen to use the arithmetic routines of the interpreter have no other choice than to call the multiply routine in the BASIC ROM directly - exactly because there is no vector pointing there - and thus will be in the dark about a soft loaded fix!

Those are the reasons I made a real job of replacing the BASIC ROM. The other alternative that came to my mind, supplying RAM under ROM, was more like taking a sledgehammer to crack a nut - at least for that single fix. :lol:
Kakemoms
Vic 20 Nerd
Posts: 740
Joined: Sun Feb 15, 2015 8:45 am

Re: Fun with CBM arithmetics

Post by Kakemoms »

Mike wrote:Those are the reasons I made a real job of replacing the BASIC ROM. The other alternative that came to my mind, supplying RAM under ROM, was more like taking a sledgehammer to crack a nut - at least for that single fix. :lol:
Well, there is no way to get the 65C02 to see the internal ROM, so it will have to be in RAM anyway. Thus a patch is straightforward..
wimoos
Vic 20 Afficionado
Posts: 345
Joined: Tue Apr 14, 2009 8:15 am
Website: http://wimbasic.webs.com
Location: Netherlands
Occupation: farmer

Re: Adding 0.1 + 0.2 in CBM float

Post by wimoos »

Mike,

This is just to let you know about this test I did.

I have now used your most recent patch on the Basic image. Starting VICE gives: "VIC20MEM: Error - Warning: Unknown Basic image. Sum: 31364 ($7A84)."
Schermafdruk van 2018-09-24 19-19-50.png
Reverting to the original Basic image:
Schermafdruk van 2018-09-24 19-24-23.png
Regards,

Wim.
VICE; selfwritten 65asmgen; tasm; maintainer of WimBasic
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Adding 0.1 + 0.2 in CBM float

Post by Mike »

Hi, wimoos,
wimoos wrote:This is just to let you know about this test I did.

I have now used your most recent patch on the Basic image. Starting VICE gives: "VIC20MEM: Error - Warning: Unknown Basic image. Sum: 31364 ($7A84)."

[...]
I suppose this counts as expected behaviour. It *is* an unknown BASIC ROM image as far as VICE is concerned.
[...]

Code: Select all

P=LOG(3)/LOG(2)
A=16^P
PRINT A    (... prints 81)
W%=A
PRINT W%   (... prints 80)
Reverting to the original Basic image:

Code: Select all

P=LOG(3)/LOG(2)
A=16^P
PRINT A    (... prints 81.0000001)
W%=A
PRINT W%   (... prints 81)
Now, if you do slightly more complex calculations with non-integer numbers (log(3)/log(2) = 1.5849625...) in the presence of rounding errors and implementation details of a given floating point system to ultimately try to construct integer numbers (+/- 1 or 2 ULP) - and then apply the INT() function (which is implicit here in the assignment to an integer variable) ... you just get those kind of results. Again, this is expected behaviour.

The patched BASIC calculates 16^(log(3)/log(2)) as just a little bit smaller than 81. Upon output with PRINT, that value is rounded up and prints as 81, but INT() (or the assignment to an integer variable) rounds down to 80. When you calculate A=-16^P (note the sign-inversion!), W%=A for the patched BASIC yields -81 and the original BASIC will result in -82, so there ...

Greetings,

Michael
User avatar
MrSterlingBS
Vic 20 Enthusiast
Posts: 167
Joined: Tue Jan 31, 2023 2:56 am
Location: Germany,Braunschweig

Re: Fun with CBM arithmetics

Post by MrSterlingBS »

I am playing with the NEW BASIC ROM and MG extension and found that the NEW BASIC ROM is about 0.8% faster than the OLD one!
Attachments
milkiway.zip
(195 Bytes) Downloaded 26 times
Last edited by Mike on Wed Aug 23, 2023 5:54 am, edited 1 time in total.
Post Reply