Breaking 6502 apart

Topics pertaining to the emulation or simulation of the 65xx microprocessors and their peripheral chips.
Post Reply
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

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.
6502 addict
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

Todays speccy: complete ALU transistor schematics

Enjoy! :D
Attachments
ALU_trans.png
Last edited by org on Fri Jul 27, 2012 8:28 am, edited 4 times in total.
6502 addict
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Breaking 6502 apart

Post by GARTHWILSON »

GARTHWILSON wrote:
Dieter has updates coming too.
Mike just got them posted, at http://6502.org/users/dieter/index.htm . Thanks Mike!
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?
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

Todays speccy: ALU logic (missing BCD correction).

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 actually "DECIMAL SBUS ADJUST", not "DECIMAL SUBTRACT ADJUST".
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;
}
Attachments
ALU_sum.png
ALU_overflow.png
ALU_overflow.png (8.44 KiB) Viewed 2381 times
Last edited by org on Fri Jul 27, 2012 8:53 am, edited 10 times in total.
6502 addict
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

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:

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 );
        }
    }

}
Now everything is correct.

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
BCD correction is next.
6502 addict
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

DAA

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.
Can someone explain why it use such combinations ? :)

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 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 :

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
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Breaking 6502 apart

Post by BigEd »

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
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

Cool stuff :) You saved some time to me again :D
Is this patent still valid ? Can I use it in software simulation ? :)
6502 addict
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Breaking 6502 apart

Post by BigEd »

It's a 1976 grant date, so it must be expired now - 20 years is the term.
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

A bit cleaned ALU.

I'm ready to write its C simulator. Stay tuned ;)
Attachments
ALU_trans.png
6502 addict
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

I started my project on Google Code :

http://code.google.com/p/breaks/source/ ... ks6502/SRC
6502 addict
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Breaking 6502 apart

Post by BigEd »

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
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

This is "Other license". This mean its absolutely free to use, without any exceptions.
6502 addict
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: Breaking 6502 apart

Post by BigEd »

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."
User avatar
org
Posts: 201
Joined: 22 Jun 2012
Contact:

Re: Breaking 6502 apart

Post by org »

I really dont care )
6502 addict
Post Reply