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
Enhanced Decimal on 65xx
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
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.
- BitWise
- In Memoriam
- Posts: 996
- Joined: 02 Mar 2004
- Location: Berkshire, UK
- Contact:
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.
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
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
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).
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.
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
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.
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...
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!
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.
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.
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
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.
x86? We ain't got no x86. We don't NEED no stinking x86!
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
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.
x86? We ain't got no x86. We don't NEED no stinking x86!
BigDumbDinosaur wrote:
The MSX architecture may have been promising but it was hobbled by use of the Z80.
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.
Quote:
The Z800 was opcode compatible with the Z80 but could do 16 bit loads and stores,
Quote:
could address 16 MB of RAM.
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).