Fun with CBM arithmetics

Basic and Machine Language

Moderator: Moderators

User avatar
Mike
Herr VC
Posts: 4849
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: 4849
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: 4849
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: 350
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: 4849
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: 183
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 44 times
Last edited by Mike on Wed Aug 23, 2023 5:54 am, edited 1 time in total.
User avatar
MrSterlingBS
Vic 20 Enthusiast
Posts: 183
Joined: Tue Jan 31, 2023 2:56 am
Location: Germany,Braunschweig

Re: Fun with CBM arithmetics

Post by MrSterlingBS »

without BASIC-patch ---------- with BASIC-patch

117521 ---------- 116585
117519 ---------- 116573
117567 ---------- 116509
117508 ---------- 116551
117553 ---------- 116550

117534 ---------- 116554

100% -------------- 99,2%
User avatar
Mike
Herr VC
Posts: 4849
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Fun with CBM arithmetics

Post by Mike »

MrSterlingBS wrote: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!

without BASIC-patch ---------- with BASIC-patch

[...]

100% -------------- 99,2%
That's an unintended but surely not unwelcome side effect. ;)

The routine in the patch gets called in 1 of 256 cases (when the given mantissa byte is zero) and does its job a little bit faster than the original re-used mantissa normalization routine. Edit: actually, the statistics are more in our favour. Quite some values processed in the program are small integer values (the screen co-ordinates in particular) which do have zeroes in their low mantissa bytes.

...

Something went wrong with "milkiway.zip". The *.prg file inside is corrupted and only 37 bytes long.
User avatar
MrSterlingBS
Vic 20 Enthusiast
Posts: 183
Joined: Tue Jan 31, 2023 2:56 am
Location: Germany,Braunschweig

Re: Fun with CBM arithmetics

Post by MrSterlingBS »

Okay, sorry for posting some source code again as text.
This version includes the faster sqr routine from WIMOS.
The graphic demo is from the FORUM64.

Code: Select all

0 sa=828
10 forn=0to57
20 read a%:pokesa+n,a%:next
30 data 32,43,220,240,52,16,3,76
40 data 72,210,32,199,219,165,97,56
50 data 233,129,8,74,24,105,1,40
60 data 144,2,105,127,133,97,169,4
70 data 133,103,32,202,219,169,92,160
80 data 0,32,15,219,169,87,160,0
90 data 32,103,216,198,97,198,103,208
100 data 233,96
105 @on:@clr
110 poke1,60:poke2,03
115 x1=80:x2=79:y1=96:y2=95
117 ti$="000000"
120 forx=1to80:fory=-96to95
125 w=atn(y/x):r=usr(x*x+y*y)
130 h=.5+sin(w+w+log(r)*10)/2
135 ifh<rnd(1)then145
140 @1,x1-x,y1+y:@1,x2+x,y2-y
145 next:next
150 te=ti
155 geta$
160 ifa$=""then155
165 @return
170 print"zeit: "te
User avatar
Mike
Herr VC
Posts: 4849
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Fun with CBM arithmetics

Post by Mike »

For the *.prg file and further discussion about this demo, check out this thread: MINIGRAFIK lineart.
Post Reply