Enhanced Decimal on 65xx

Let's talk about anything related to the 6502 microprocessor.
Post Reply
Bryan Parkoff
Posts: 109
Joined: 25 Dec 2007

Enhanced Decimal on 65xx

Post by Bryan Parkoff »

Do you expect to ask the manufacturer to improve decimal mode on 65xx? The decimal mode allows to support Negative flag and Overflow flag 100% accurate.

Unfortunately, binary coded decimal in ADC and SBC instruction may set negative flag and overflow flag incorrectly when you want to use negative on the range of 5 through 9 and positive on the range of 0 through 4.

It is ideal to move negative from 7th bit to 8th bit. The byte size would look like 9 bit instead of 8 bit.

You put value into the register. The register checks the range of 5 through 9 on the value before it sets negative on 8th bit.

You may prefer to test BCD values to determine if negative flag or overflow flag is set so branch can be taken.

It is too complex logic and BCD is incompatible to some 65xx instructions which they only support 8-bit byte size, but not 9-bit byte size.

It would be nice to write small BCD routine on 65xx to overcome the limitation when you wish to test BCD's negative flag and overflow flag so branch can be taken.

Please let me know what you think and it is appropriate to do it.

Here is an example of my sample data below. I did post it previous thread, but this sample data looks clearer. Use this example below if you can write BCD routine with 9-bit byte size. It allows to expand from 4-bit nibble size to 8-bit byte size and 16-bit word size with one extra bit for negative.

0 + 0 = 0 N: 0 V: 0 Z: 1 C: 0
0 + 1 = 1 N: 0 V: 0 Z: 0 C: 0
0 + 2 = 2 N: 0 V: 0 Z: 0 C: 0
0 + 3 = 3 N: 0 V: 0 Z: 0 C: 0
0 + 4 = 4 N: 0 V: 0 Z: 0 C: 0
0 + 5 = 5 N: 1 V: 0 Z: 0 C: 0
0 + 6 = 6 N: 1 V: 0 Z: 0 C: 0
0 + 7 = 7 N: 1 V: 0 Z: 0 C: 0
0 + 8 = 8 N: 1 V: 0 Z: 0 C: 0
0 + 9 = 9 N: 1 V: 0 Z: 0 C: 0

1 + 0 = 1 N: 0 V: 0 Z: 0 C: 0
1 + 1 = 2 N: 0 V: 0 Z: 0 C: 0
1 + 2 = 3 N: 0 V: 0 Z: 0 C: 0
1 + 3 = 4 N: 0 V: 0 Z: 0 C: 0
1 + 4 = 5 N: 1 V: 1 Z: 0 C: 0
1 + 5 = 6 N: 1 V: 0 Z: 0 C: 0
1 + 6 = 7 N: 1 V: 0 Z: 0 C: 0
1 + 7 = 8 N: 1 V: 0 Z: 0 C: 0
1 + 8 = 9 N: 1 V: 0 Z: 0 C: 0
1 + 9 = 0 N: 0 V: 0 Z: 1 C: 1

2 + 0 = 2 N: 0 V: 0 Z: 0 C: 0
2 + 1 = 3 N: 0 V: 0 Z: 0 C: 0
2 + 2 = 4 N: 0 V: 0 Z: 0 C: 0
2 + 3 = 5 N: 1 V: 1 Z: 0 C: 0
2 + 4 = 6 N: 1 V: 1 Z: 0 C: 0
2 + 5 = 7 N: 1 V: 0 Z: 0 C: 0
2 + 6 = 8 N: 1 V: 0 Z: 0 C: 0
2 + 7 = 9 N: 1 V: 0 Z: 0 C: 0
2 + 8 = 0 N: 0 V: 0 Z: 1 C: 1
2 + 9 = 1 N: 0 V: 0 Z: 0 C: 1

3 + 0 = 3 N: 0 V: 0 Z: 0 C: 0
3 + 1 = 4 N: 0 V: 0 Z: 0 C: 0
3 + 2 = 5 N: 1 V: 1 Z: 0 C: 0
3 + 3 = 6 N: 1 V: 1 Z: 0 C: 0
3 + 4 = 7 N: 1 V: 1 Z: 0 C: 0
3 + 5 = 8 N: 1 V: 0 Z: 0 C: 0
3 + 6 = 9 N: 1 V: 0 Z: 0 C: 0
3 + 7 = 0 N: 0 V: 0 Z: 1 C: 1
3 + 8 = 1 N: 0 V: 0 Z: 0 C: 1
3 + 9 = 2 N: 0 V: 0 Z: 0 C: 1

4 + 0 = 4 N: 0 V: 0 Z: 0 C: 0
4 + 1 = 5 N: 1 V: 1 Z: 0 C: 0
4 + 2 = 6 N: 1 V: 1 Z: 0 C: 0
4 + 3 = 7 N: 1 V: 1 Z: 0 C: 0
4 + 4 = 8 N: 1 V: 1 Z: 0 C: 0
4 + 5 = 9 N: 1 V: 0 Z: 0 C: 0
4 + 6 = 0 N: 0 V: 0 Z: 1 C: 1
4 + 7 = 1 N: 0 V: 0 Z: 0 C: 1
4 + 8 = 2 N: 0 V: 0 Z: 0 C: 1
4 + 9 = 3 N: 0 V: 0 Z: 0 C: 1

5 + 0 = 5 N: 1 V: 0 Z: 0 C: 0
5 + 1 = 6 N: 1 V: 0 Z: 0 C: 0
5 + 2 = 7 N: 1 V: 0 Z: 0 C: 0
5 + 3 = 8 N: 1 V: 0 Z: 0 C: 0
5 + 4 = 9 N: 1 V: 0 Z: 0 C: 0
5 + 5 = 0 N: 0 V: 1 Z: 1 C: 1
5 + 6 = 1 N: 0 V: 1 Z: 0 C: 1
5 + 7 = 2 N: 0 V: 1 Z: 0 C: 1
5 + 8 = 3 N: 0 V: 1 Z: 0 C: 1
5 + 9 = 4 N: 0 V: 1 Z: 0 C: 1

6 + 0 = 6 N: 1 V: 0 Z: 0 C: 0
6 + 1 = 7 N: 1 V: 0 Z: 0 C: 0
6 + 2 = 8 N: 1 V: 0 Z: 0 C: 0
6 + 3 = 9 N: 1 V: 0 Z: 0 C: 0
6 + 4 = 0 N: 0 V: 0 Z: 1 C: 1
6 + 5 = 1 N: 0 V: 1 Z: 0 C: 1
6 + 6 = 2 N: 0 V: 1 Z: 0 C: 1
6 + 7 = 3 N: 0 V: 1 Z: 0 C: 1
6 + 8 = 4 N: 0 V: 1 Z: 0 C: 1
6 + 9 = 5 N: 1 V: 0 Z: 0 C: 1

7 + 0 = 7 N: 1 V: 0 Z: 0 C: 0
7 + 1 = 8 N: 1 V: 0 Z: 0 C: 0
7 + 2 = 9 N: 1 V: 0 Z: 0 C: 0
7 + 3 = 0 N: 0 V: 0 Z: 1 C: 1
7 + 4 = 1 N: 0 V: 0 Z: 0 C: 1
7 + 5 = 2 N: 0 V: 1 Z: 0 C: 1
7 + 6 = 3 N: 0 V: 1 Z: 0 C: 1
7 + 7 = 4 N: 0 V: 1 Z: 0 C: 1
7 + 8 = 5 N: 1 V: 0 Z: 0 C: 1
7 + 9 = 6 N: 1 V: 0 Z: 0 C: 1

8 + 0 = 8 N: 1 V: 0 Z: 0 C: 0
8 + 1 = 9 N: 1 V: 0 Z: 0 C: 0
8 + 2 = 0 N: 0 V: 0 Z: 1 C: 1
8 + 3 = 1 N: 0 V: 0 Z: 0 C: 1
8 + 4 = 2 N: 0 V: 0 Z: 0 C: 1
8 + 5 = 3 N: 0 V: 1 Z: 0 C: 1
8 + 6 = 4 N: 0 V: 1 Z: 0 C: 1
8 + 7 = 5 N: 1 V: 0 Z: 0 C: 1
8 + 8 = 6 N: 1 V: 0 Z: 0 C: 1
8 + 9 = 7 N: 1 V: 0 Z: 0 C: 1

9 + 0 = 9 N: 1 V: 0 Z: 0 C: 0
9 + 1 = 0 N: 0 V: 0 Z: 1 C: 1
9 + 2 = 1 N: 0 V: 0 Z: 0 C: 1
9 + 3 = 2 N: 0 V: 0 Z: 0 C: 1
9 + 4 = 3 N: 0 V: 0 Z: 0 C: 1
9 + 5 = 4 N: 0 V: 1 Z: 0 C: 1
9 + 6 = 5 N: 1 V: 0 Z: 0 C: 1
9 + 7 = 6 N: 1 V: 0 Z: 0 C: 1
9 + 8 = 7 N: 1 V: 0 Z: 0 C: 1
9 + 9 = 8 N: 1 V: 0 Z: 0 C: 1
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

I have thought about this, but for the only decimal math I have done on the 65 family, I wrote my own floating-point routines and used sign and magnitude. +123.4567 for example was represented the same way as -123.4567, except for the sign bit. That was in my early 6502 days. If I were to re-do that project, I would use 16-bit fixed-point and scaled-integer hex math (with some 32-bit intermediate results). It is faster and more efficient with both data memory and program memory, and it is far more capable than I realized at the time, even for things like trig and log functions that I used to think required floating-point.
User avatar
BitWise
In Memoriam
Posts: 996
Joined: 02 Mar 2004
Location: Berkshire, UK
Contact:

Post by BitWise »

I don't think that the negative and overflow flags can ever be set correctly on a microcomputer than processes BCD one byte at a time (and they don't have any meaningful interpretation).

In my youth I dabbled with an ICL4-30 mainframe (a predecessor of the IBM 360) which supported multi-byte packed decimal arithmetic. It used the top nybble of the most significant byte to hold the sign for the decimal value (C or F was +ve, D was -ve). So a +1234 in a 32-bit word would be C0001234 and -1234 would be D0001234.

(See http://publib.boulder.ibm.com/iseries/v ... 083170.htm)

The mainframe knows upfront at the start of any packed decimal instruction the sign of both numbers and the how many bytes will be involved. An 8-bit microcomputer on the other knows neither when a BCD addition or subtraction is performed but it does give you the tools you need to perform the task.

Assuming you keep the sign of each number seperate from its value (as in the mainframe examples) then before you add two multi-byte BCD values you first compare thier signs. If both numbers have the same sign you add the values and give the result the same sign as the first number. If then numbers have different signs then you subtract the values and invert the sign of the result if the first number was negative. For example

+3 + +4 => +(3+4) => +7
-3 + -4 -> -(3+4) => -7
+3 + -4 => +(3-4) => +(-1) => -1
-3 + +4 => -(3-4) -> -(-1) => +1

During the addition/subtraction phase you can detect overflow by looking at the carry flag after the most significant bytes of the value have been added/subtracted.
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

BitWise wrote:
I don't think that the negative and overflow flags can ever be set correctly on a microcomputer than processes BCD one byte at a time (and they don't have any meaningful interpretation).
By analogy with twos-complement, regarding 5-9 as negative (values -5 to -1) when in a leading digit seems to me a consistent interpretation. Negative means 5 or greater, and overflow means the signed range was exceeded by an addition or subtraction. One downside is that you'd always have to use an even number of decimal digits. The range for signed bcd would be -5000... to +4999... [edit: fix range]

This gets a mention in this orphan posting

Straying off topic a bit, I hadn't realised that the 65c02 does BCD a bit differently than the nmos 6502, and that the 65816 is different again. I read in Commodore World issue 12 an interview with Bill Mensch where he says he escaped patent trouble with the 65c02 by having not used the same decimal adjust circuitry as on the 6502 - he's a co-patentee of that circuitry, but the patent was MOS's [edit!] and they had been bought by Commodore. I don't know what he did for the 65816, but he regained the 1-cycle penalty and also fixed up the N and Z flags, according to Bruce's document.

That decimal adjust circuit is not simple though - I wonder if it came close to being on the critical path. (Circuit and equations given in patent 3991307) Or maybe incrementing the PC was critical? I see the 6800 used a carry-select approach for that.
Last edited by BigEd on Fri Sep 04, 2009 5:23 am, edited 1 time in total.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Post by BigDumbDinosaur »

Quote:
Straying off topic a bit, I hadn't realised that the 65c02 does BCD a bit differently than the nmos 6502, and that the 65816 is different again.
Hmm...the differences between NMOS and CMOS BCD have been described in the datasheet features summary for the 65C02 and 65C816 (also the C802) for as long as I can remember.

Back in the early 1990s, I implemented floating point BCD arithmetic on a 65C02 powered SBC, and eventually wrote a Fourier series evaluation add-on to the math package to compute transcendental functions, e.g., logs and such. It would not have been possible to implement this math package on the NMOS 6502 due to the failure of it to correctly handle the N and Z flags.

BCD on the 'C02 and 'C816 is eminently workable, as the number of clocks required to execute ADC and SBC are the same as if in binary mode. Encoding an ASCII number representation into BCD is easier than into, say, excess-128 or IEEE 754, and depending on the encoding algorithm in use, faster.

The two penalties present in using BCD on a 65Cxx processor are relatively slow multiplication and division (never strong points with these processors to begin with) and less efficient storage utilization (also true with BCD on other machine architectures). However, the fact that BCD can internally represent decimal fractions (e.g., 3/10) without error is useful if computations cannot tolerate small rounding contretemps.
Quote:
I read in Commodore World issue 12 an interview with Bill Mensch where he says he escaped patent trouble...
Any patents related to the NMOS '02 as developed by MOS (not Mostek -- that is an entirely different company) are in the public domain -- they would have expired around 1995. Of course, at the time Bill Mensch was working on his CMOS version, the patents were viable and Commodore, especially during its Jack Tramiel days, was quite aggressive about protecting IP. I'm sure Mensch had the 6501 debacle in mind as he worked. :)
Last edited by BigDumbDinosaur on Fri Sep 04, 2009 3:06 pm, edited 1 time in total.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Post by BigEd »

oops, fixed the MOS/Mostek blunder. I kind of knew it was wrong as I wrote it. Also fixed the range.

I saw somewhere Bill Mensch saying that Tramiel put a lot of companies out of business, but put WDC in business. He would indeed surely have been as careful as he could.
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

It's true; Tramiel wasn't a very nice guy in the business arena. When the Japanese were threatening to invade the US with their MSX-architecture computers (arguably quite powerful for their time), Jack decided to push the VIC-20 to store shelves and undercut the MSX prices quite substantially. Commodore had vertical integration of its manufacturing, so they could afford to do this and still stay in business. The Japanese never had a chance.

Today, of course, any company with a lean manufacturing process in place would snow Commodore's old tactics trivially, even with a more horizontal set of suppliers. I know Toyota certainly were working with lean manufacturing (they invented it), but I don't think the process, philosophy, or methodology had spread to other sectors yet like it's doing today.

One of the reasons for this, of course, is that Commodore maintained a massive inventory of unsold computers. Manufacturing in such bulk was one of the reasons they were able to cut prices so much. When Commodore stopped manufacturing the C64, for example, look how long it took before they stopped flying off the shelves! Ditto for the Commodore-Amiga series. I think it took something like five years for the Amiga stocks to run out.

Yikes!

Anyway, this got a bit off-topic, even if tangentially related.
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Post by BigDumbDinosaur »

Quote:
It's true; Tramiel wasn't a very nice guy in the business arena. When the Japanese were threatening to invade the US with their MSX-architecture computers (arguably quite powerful for their time), Jack decided to push the VIC-20 to store shelves and undercut the MSX prices quite substantially.
The MSX architecture may have been promising but it was hobbled by use of the Z80. At the time when MSX was developed, a better processor choice might have been, assuming the Japanese wanted to stay with Zilog, the Z800. The Z800 was opcode compatible with the Z80 but could do 16 bit loads and stores, and could address 16 MB of RAM. However, as you correctly indicated, Tramiel's "scorched earth" business practices were something the Japs weren't ready to take on at the time.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
User avatar
BigDumbDinosaur
Posts: 9425
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Post by BigDumbDinosaur »

BigDumbDinosaur wrote:
Quote:
It's true; Tramiel wasn't a very nice guy in the business arena. When the Japanese were threatening to invade the US with their MSX-architecture computers (arguably quite powerful for their time), Jack decided to push the VIC-20 to store shelves and undercut the MSX prices quite substantially.
The MSX architecture may have been promising but it was hobbled by the use of the Z80. At the time when MSX was developed, a better processor choice might have been, assuming the Japanese wanted to stay with Zilog, the Z800. The Z800 was opcode compatible with the Z80 but could do 16 bit loads and stores, and could address 16 MB of RAM. However, as you correctly indicated, Tramiel's "scorched earth" business practices were something the Japs weren't ready to take on at the time.
BTW, almost forgot: MSX was actually started by Microsoft in Japan, probably one of Gates' first attempts to take over all aspects of computing. The formal introduction of MSX was in early 1983, a time when the Commodore 64 was starting to appear in stores. The rest, as they say, is history. MSX is a footnote in the home computer wars chapter, and the C-64 is the all-time bestseller.
x86?  We ain't got no x86.  We don't NEED no stinking x86!
kc5tja
Posts: 1706
Joined: 04 Jan 2003

Post by kc5tja »

BigDumbDinosaur wrote:
The MSX architecture may have been promising but it was hobbled by use of the Z80.
I wouldn't exactly call it "hobbled." Remember we're talking about architectures conceived in the 1978 to 1980 timeframe here.
Quote:
At the time when MSX was developed, a better processor choice might have been, assuming the Japanese wanted to stay with Zilog, the Z800.
When was that chip first released to the market? My sources suggest that its first tape appeared in 1985 timeframe, some two to three years after the Japanese started contemplating shipping MSX machines to the U.S.
Quote:
The Z800 was opcode compatible with the Z80 but could do 16 bit loads and stores,
Can you clarify this further? I distinctly remember coding in Z-80 assembly as a kid (I started at age 6!), and loading and storing BC, DE, HL, IX, and IY (and in some cases, SP) as single instructions were routine operations.
Quote:
could address 16 MB of RAM.
Considering that the average computer of the day was equipped with 4KiB of RAM, and installing 32KiB was considered a "holy sh*t" phenomenon, I doubt this would have had any kind of impact what-so-ever.

By the same logic, you could say that the 6502 hobbled the Commodore 128; they could easily have chosen to use the 65C816 which was under development at the same time (the C128 and Apple IIgs are contemporaries of each other).
Post Reply