Breaking 6502 apart
Re: Breaking 6502 apart
I decided to release sources of ALU and LOGIC :
http://ogamespec.com/6502/ALU.psd
http://ogamespec.com/6502/LOGIC.psd
Remember, this is still W.I.P.
http://ogamespec.com/6502/ALU.psd
http://ogamespec.com/6502/LOGIC.psd
Remember, this is still W.I.P.
6502 addict
Re: Breaking 6502 apart
Todays speccy: complete ALU transistor schematics
Enjoy!
Enjoy!
Last edited by org on Fri Jul 27, 2012 8:28 am, edited 4 times in total.
6502 addict
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Breaking 6502 apart
GARTHWILSON wrote:
Dieter has updates coming too.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Breaking 6502 apart
Todays speccy: ALU logic (missing BCD correction).
DSA is actually "DECIMAL SBUS ADJUST", not "DECIMAL SUBTRACT ADJUST".
DSA is applied before loading accumulator (AC), after BCD correction.
EDIT: important condition:
Code: Select all
// A/B INPUT
if ( NDB_ADD ) BI = ~DB;
if ( DB_ADD ) BI = DB;
if ( ADL_ADD ) BI = ADL;
if ( SB_ADD ) AI = SB;
if ( 0_ADD ) AI = 0;
// LOGIC (based on NAND/NOR)
NOR = ~(AI | BI);
NAND = ~(AI & BI);
if ( ORS ) ADD = NOR;
if ( ANDS ) ADD = NAND;
if ( SRS ) ADD = NAND >> 1; // next bit feed previous result
if ( EORS ) {
nEOR[0,2,4,6] = ~ (~NOR & NAND)
EOR[1,3,5,7] = ~ (~NAND | NOR)
ADD[0,2,4,6] = nEOR[0,2,4,6]
ADD[1,3,5,7] = ~EOR[1,3,5,7]
}
// ARITHMETIC
// BCD correction run-flow : DAA -> ALU -> ADD -> DSA -> SB -> AC.
// DECIMAL ADDER ADJUST (detect decimal carry and halfcarry)
// ...
// input carry driver I_ADDC comes in inverted form
// carry chain
carry_out = I_ADDC;
// bits 0,2,4,6
carry_in = carry_out;
carry_out = ~(NAND[0,2,3,6] & carry_in) & ~NOR[0,2,4,6];
SUM[0,2,4,6] = ~(nEOR[0,2,4,6] & ~carry_in) & (nEOR[0,2,4,6] | ~carry_in);
// bits 1,3,5,7
carry_in = carry_out;
carry_out = ~(~NOR[1,3,5,7] & carry_in) & NAND[1,3,5,7];
SUM[1,3,5,7] = ~(EOR[1,3,5,7] & ~carry_in) & (EOR[1,3,5,7] | ~carry_in);
// trans-level implementation of summator see in ALU_sum.png
// overflow test
carry6_out = carry_in;
if ( PHI2 ) AVR_Latch = ~(NOR7 & carry6_out) & (NAND7 | carry6_out);
AVR = AVR_Latch;
if ( SUMS) ADD = SUM;
// High-level implementation :
// s = AI + BI + ~I_ADDC;
// SUM = ~ ( s & 0xFF );
// carry_out = s >> 8;
// ADDER HOLD (register holds data in inverted logic)
if ( ADD_ADL ) ADL = ~ADD;
if ( ADD_SB06 ) SB = (SB & 0x80) | (~ADD & 0x7F);
if ( ADD_SB7 ) SB = (SB & 0x7F) | (~ADD & 0x80);
// DECIMAL SBUS ADJUST (affects SBus lines)
// ...
// ACCUMULATOR
if ( SB_DB ) DB = SB;
if ( SB_AC ) AC = SB;
if ( AC_SB ) SB = AC;
if ( AC_DB ) DB = AC;
if ( 0_ADH0 ) ADH &= ~0x01;
if ( 0_ADH17 ) ADH &= 0x01;DSA is applied before loading accumulator (AC), after BCD correction.
EDIT: important condition:
Code: Select all
if ( PHI2 )
{
NDB_ADD = DB_ADD = ADL_ADD = 0_ADD = 0;
SB_AC = AC_SB = AC_DB = 0;
ADH = 0;
}
Last edited by org on Fri Jul 27, 2012 8:53 am, edited 10 times in total.
6502 addict
Re: Breaking 6502 apart
Previous post need some corrections... I'm writing test program ATM, errors will be fixed later.
EDIT: fixed ALU SUM errors and wrote test program:
Now everything is correct.
BCD correction is next.
EDIT: fixed ALU SUM errors and wrote test program:
Code: Select all
#include <stdio.h>
int nand (int a, int b, int bit )
{
int bit_a = (a >> bit) & 1;
int bit_b = (b >> bit) & 1;
return (~ (bit_a & bit_b)) & 1;
}
int nor (int a, int b, int bit )
{
int bit_a = (a >> bit) & 1;
int bit_b = (b >> bit) & 1;
return (~ (bit_a | bit_b)) & 1;
}
int noteor (int a, int b, int bit )
{
return ~ (~nor(a,b,bit) & nand(a,b,bit));
}
int eor (int a, int b, int bit )
{
return ~ (~nand(a,b,bit) | nor(a,b,bit));
}
int alusum ( int a, int b, int carry_in, int *carry, int numbits )
{
int bit;
int carry_out = ~carry_in;
int sum = 0, s;
for (bit=0; bit<numbits; bit++)
{
if ( bit & 1 ) {
carry_in = carry_out & 1;
carry_out = ~(~nor(a,b,bit) & carry_in) & nand(a,b,bit);
s = ~(eor(a,b,bit) & ~carry_in) & (eor(a,b,bit) | ~carry_in);
}
else {
carry_in = carry_out & 1;
carry_out = ~(nand(a,b,bit) & carry_in) & ~nor(a,b,bit);
s = ~(noteor(a,b,bit) & ~carry_in) & (noteor(a,b,bit) | ~carry_in);
}
//printf ( "%i: %i %i %i %i %i\n", bit, (a >> bit) & 1, (b >> bit) & 1, s & 1, carry_in & 1, carry_out & 1);
sum |= (s & 1) << bit;
}
*carry = ~carry_out & 1;
return ~sum & ((1 << numbits) - 1);
}
void logic_test ( int a, int b )
{
int bit;
for (bit=0; bit<8; bit++)
{
printf ( "NAND=%i ", nand(a, b, bit) );
printf ( "NOR=%i ", nor(a, b, bit) );
printf ( "EOR=%i \n", eor(a, b, bit) );
printf ( "!EOR=%i \n", noteor(a, b, bit) );
}
}
main ()
{
int a, b, sum, carry;
//logic_test ( 0x35, 0x53 );
printf ( "6502 ALU test.\n" );
printf ( " A B S C\n" );
for ( a=0; a<256; a++ )
{
for (b=0; b<256; b++)
{
sum = alusum ( a, b, 0, &carry, 8 );
printf ( "%02X %02X %02X %01X\n", a, b, sum, carry );
}
}
}
Code: Select all
6502 ALU test.
A B S C
03 F9 FC 0
03 FA FD 0
03 FB FE 0
03 FC FF 0
03 FD 00 1
03 FE 01 1
03 FF 02 1
04 00 04 0
04 01 05 0
6502 addict
Re: Breaking 6502 apart
DAA
I disentangled decimal carry lookahead logic, driven by DAA:
Can someone explain why it use such combinations ? 
ALU Carry out route
ALU Carry out is combination of bit7 carry out and high-nibble DecimalCarry.
ALU carry out later outputs to ACR line and also feeds by DSA (controlled by DAA latch).
Decimal half carry has affect only on bit3 of carry-out chain :
I disentangled decimal carry lookahead logic, driven by DAA:
Code: Select all
carry0_out = ~(NAND0 & I_ADDC) & ~NOR0;
A = ~( ~(~NAND1 & carry0_out) | NOR2 );
B = ~(EOR3 | ~NAND2);
C = ~(EOR1 | ~NAND1) & ~carry0_out & (~NAND2 | NOR2);
DecimalHalfCarry = A & (B | C) & ~DAA;
(Decimal Half Carry is low when DAA driver is high)
A = ~ (~(~NAND5 & carry4_out) | EOR6);
B = ~(~NAND6 | EOR7);
C = ~(~NAND5 | XOR5) & ~(carry4_out | ~EOR6);
DecimalCarry = A & (B | C) & ~DAA;
(DecimalCarry is low when DAA driver is high)
Human-readable explanation:
Decimal HalfCarry is set, when AI and BI are in following combinations:
| AI | BI |
|----|----|
| X3 | X7 |
| X7 | X3 |
| XF | XB |
| XB | XF |
Decimal Carry is set, when AI and BI are in following combinations:
| AI | BI |
|----|----|
| 2X | 3X |
| 3X | 2X |
| 3X | 3X |
| AX | BX |
| BX | AX |
| BX | BX |
X - mean any number 0-F.
ALU Carry out route
Code: Select all
// Carry out.
if (PHI2 ) DAA_Latch = ~DAA
CarryOut = ~(DecimalCarry | ~carry7_out)
DSA_CarryOut = ~(CarryOut | ~DAA_Latch)
ACR = ~CarryOut; // to random logic
ALU carry out later outputs to ACR line and also feeds by DSA (controlled by DAA latch).
Decimal half carry has affect only on bit3 of carry-out chain :
Code: Select all
// bits 1,3,5,7
carry_in = carry_out;
carry_out = ~(~NOR[1,3,5,7] & carry_in) & NAND[1,3,5,7];
if (bit == 3 && DecimalHalfCarry) carry_out = 0;
SUM[1,3,5,7] = ~(EOR[1,3,5,7] & ~carry_in) & (EOR[1,3,5,7] | ~carry_in);
6502 addict
Re: Breaking 6502 apart
For the equations, you could check the patent which is linked from this post
viewtopic.php?p=8859#p8859
You might find some of the info on the visual6502 wiki useful too
http://visual6502.org/wiki/index.php?ti ... ecimalMode
Cheers
Ed
viewtopic.php?p=8859#p8859
You might find some of the info on the visual6502 wiki useful too
http://visual6502.org/wiki/index.php?ti ... ecimalMode
Cheers
Ed
Re: Breaking 6502 apart
Cool stuff
You saved some time to me again 
Is this patent still valid ? Can I use it in software simulation ?
Is this patent still valid ? Can I use it in software simulation ?
6502 addict
Re: Breaking 6502 apart
It's a 1976 grant date, so it must be expired now - 20 years is the term.
Re: Breaking 6502 apart
A bit cleaned ALU.
I'm ready to write its C simulator. Stay tuned
I'm ready to write its C simulator. Stay tuned
6502 addict
Re: Breaking 6502 apart
6502 addict
Re: Breaking 6502 apart
Excellent, thanks for sharing: starred and RSS-subscribed.
(As ever, it would be great if you'd paste in a BSD or GPL license)
Cheers
Ed
(As ever, it would be great if you'd paste in a BSD or GPL license)
Cheers
Ed
Re: Breaking 6502 apart
This is "Other license". This mean its absolutely free to use, without any exceptions.
6502 addict
Re: Breaking 6502 apart
That's great: in that case CC0 would be ideal - it only takes a sentence. (You have copyright as soon as you create it, and you can't really lose it - you need to license your work somehow if you want grant access to others, even if your intent is to impose no restrictions)
Cheers
Ed
http://creativecommons.org/choose/zero/
http://paulmillr.com/posts/simple-descr ... -licenses/
"To the extent possible under law, the person who associated CC0 with this work has waived all copyright and related or neighboring rights to this work."
Cheers
Ed
http://creativecommons.org/choose/zero/
http://paulmillr.com/posts/simple-descr ... -licenses/
"To the extent possible under law, the person who associated CC0 with this work has waived all copyright and related or neighboring rights to this work."