If you disassemble any version of Microsoft BASIC for 6502, you’ll find this code in a function that normalizes the (simulated) floating point accumulator:
NORMALIZE_FAC6: inc FAC ; MANTISSA CARRIED, SO SHIFT RIGHT beq OVERFLOW ; OVERFLOW IF EXPONENT TOO BIG ror FAC+1 ror FAC+2 ror FAC+3 ror FAC+4 ror FACEXTENSION rts
Well, not any BASIC. All versions of
- Commodore BASIC (all versions, since 1977)
- AppleSoft BASIC (all versions, since 1977)
- Microsoft BASIC for the OHIO Scientific (all versions, since 1977)
- Microsoft BASIC for the rare Mattel Intellivision Keyboard Component (1980)
use this code, but if you look at the disassembly of
- Microsoft BASIC for the MOS KIM-1 (1977)
- Microsoft BASIC for the Tangerine Microtan 65 (1979)
you will see this code instead:
NORMALIZE_FAC6: inc FAC beq OVERFLOW lda #$00 bcc @1 lda #$80 @1: lsr FAC+1 ora FAC+1 sta FAC+1 lda #$00 bcc @2 lda #$80 @2: lsr FAC+2 ora FAC+2 sta FAC+2 lda #$00 bcc @3 lda #$80 @3 lsr FAC+3 ora FAC+3 sta FAC+3 lda #$00 bcc @4 lda #$80 @4: lsr FAC+4 ora FAC+4 sta FAC+4 lda #$00 bcc @5 lda #$80 @5: lsr FACEXTENSION ora FACEXTENSION sta FACEXTENSION rts
(Actually, the OHIO Scientific and Intellivision versions work on a 3 byte (“6 digit”) instead of a 4 byte (“9 digit”) mantissa, so the “FAC+4” part is missing.)
Similar replacement has happened in other parts of the floating point library. It seems to be a compile-time option of the assembly source code.
Todays puzzle is to find out why there are two versions of this code, and why the different computer vendors chose to use one version or another.
See comments for solution.
Easy one – because of the broken ROR instructions in early 6502 revs.
@MagerValp: That’s correct. 6502’s ROR was broken in such a way that it was even left out of the KIM-1 docs. However, the bug was fixed around ’77. Did Tangerine buy stockpiles of broken 6502’s for their Microtan?
Okay, part one is solved: The 6502 was introduced in september 1975, and all parts before June 1976 had a bug in ROR. But the second part of the question is: Why do exactly the two mentioned versions contain the workaround, and the others don’t? Marco is going the right direction there, but this needs more analysis. 🙂
Leaving it out of the KIM-1 makes sense, since the earliest 6502s would show up on said KIM-1s.
Microtan 65 sounds like quite the anomaly, as if the workaround was switched on in error. There’s a program listing in this magazine that has a ROR instruction on page 24, line 160: http://www.geoff.org.uk/microtan/images/microt3.gif
Unless, of course, it was just “ROR zpage” that was broken and “ROR A” was ok. What, exactly, was broken with ROR?
Other magazines here: http://www.geoff.org.uk/microtan/magazines.htm
I looked through a scan I have of MOSTEK’s Aug 1975 6502 manual and ROR in all forms is indeed absent, which hints (but does not state equivocally) it wasn’t tied to an address mode.
Right. The KIM-1 was introduced in late 1975, and there were definitely devices with faulty 6502 chips, so Microsoft BASIC for the KIM-1, which was introduced in 1977, couldn’t use ROR.
The Microtan 65 indeed is an anomaly. It was introduced in 1979, and there is no way there were using CPUs in their devices that had been manufactured three years before. The monitor ROM even uses ROR, here are two examples:
jsr LF556
php
ror $51
plp
adc #$00
[…]
asl $00
sec
ror $00
jsr LC558
So it is obvious that Tangerine used an incorrect build switch for Microsoft BASIC.
And this find also shows that there was always an actual build switch, as opposed to Microsoft replacing the workaround with the ROR code at some point.
Another plausible explanation could be that the Microtan developer prototype was assembled with an old 6502 chip, or that the firmware was developed on a KIM board.
Some poster (#20) in this thread on comp.sys.oric:
http://groups.google.de/group/comp.sys.oric/browse_frm/thread/7d56d4c734ef7bba/e4a0678550a2864f
suggests, that the ROR-fix was still present in Oric-1 machines, but removed in the overhauled Atmos ROMs.
@MagerVelp: That seems unlikely if the ROR instruction itself is in the Microtan’s own monitor ROM. 4 years from development to production also seems a bit long.
If you replace the macro expansions of ROR in Basic with actual ROR instructions, you free up a little bit of space that can be used for other things. I did this with a copy of Ohio Scientific 9-digit Disk Basic (which, like the company’s previous versions, used the macro expansion, not the ROR instruction). I used the bytes that were freed up to implement a RESTORE command and a few other enhancements and bug fixes, such as the ability to properly handle a statement like POKE A, PEEK(B).
Oops, that was supposed to read “a RESTORE <line number> command”. Simple RESTORE was of course always included. I also got rid of the NULL command while I was at it and replaced it with CALL. Other changes included fixing FRE to always return a positive value, and a computed GOTO (e.g. GOTO 100+10*X).
lda #$80
bcs @1
asl a
@1:
lsr FAC+1
ora FAC+1
sta FAC+1
… wastes one fewer byte for every invocation of the ror replacement macro …