This project is largely based on the project with the name "Build a 6502 computer" from Ben Eater ( website ). His videos explaining the 6502 project in detail are available on YouTube.
The 15 address pins of the AT28C256 eeprom are connected to the 16 output pins of the two shift registers. The last pin Q7 of the second shift register controls the OE (output enable) pin, being active low. By sending 16 bits as address the highest (msb) bit determines reading or writing together with the WE (write enable) pin (see code (address >> 8) | (outputEnable ? 0x00 : 0x80)).
To read data from the EEPROM CE and OE must be low and WE high.
To write data to the EEPROM CE and WE must be low (active) and OE high.
To get the sd card working with the Arduino NANO the sdfat library is used. The standard sd library from Arduino doesn't work properly.
To speed the program up I added a few lines so only the first and last 1000 bytes are written.
To read the eeprom remove the sd card, no writing will occure only reading.
Not sure if the memory modules bought from various sources were okay, I wrote a small program to test read & write to RAM. PORTC (PC7) of the Mega is broken, so I used PORTD (PD7) instead.
>>> Code for Arduino MEGA <<<To practise 6502 assembly I use the online emulator from mass:werk website and assembler. Open the assembler page using the link on the emulator page. After the code is assembled successfully you can transfer the binary to the emulator and run it from there. For compiler directives, labels and such go to website .
Some tips:
An instruction using zero page addressing mode has only an 8 bit address operand. This limits it to addressing only the first 256 bytes of memory (e.g. $0000 to $00FF) where the most significant byte of the address is always zero. In zero page mode only the least significant byte of the address is held in the instruction making it shorter by one byte (important for space saving) and one less memory fetch during execution (important for speed).
The second page consists of memory addresses 0100 to 01FF and is the location of the 6502's stack.
You can only set this 8-bit stack pointer via the X register; you must place the value in the X register and transfer it to the stack pointer with the TXS (transfer X register to stack pointer) op code. Because the stack grows downward, it is good practice to initialize the stack pointer at the beginning of any 6502 program with the following code:
LDX #$FF ;set pointer to very top of stack
TXS
The 6502 clears the carry bit to indicate a borrow, but you have to set it first:
SEC ; carry set
SBC #ff ;subtract 255
BCC BORROW ;a borrow occurred
Comparison is a subtraction; comparing 5 to 6 would be a matter of subtracting 6 from 5 and setting the appropriate status flags. In this situation (5 minus 6) a borrow would occurs, indicated by a clear carry. Therefore, after a compare operation, a clear carry indicates less than, and a set carry indicates greater than or equal to.
Flags
The carry flag is only affected by arithmetic (ADC, SBC, and CMP,CPX,CPY compares) and shift operations (ASL, LSR, ROL, and ROR), except when explicitly changed (with CLC, SEC, or PLP).
Flags set or cleared with most operations are the Negative and Zero flags. The Negative flag reflects the state of the eighth (most significant) bit of the result of the operation, and the Zero flag is set whenever the result is equal to 0 (all bits cleared). All operations that work with a value set these flags, including the load (LDA, LDX, and LDY) and transfer (TAX, TAY, TSX, TXA, TXS, and TYA) op codes.
BIT op code
When used it will do a AND operation between memory and accumulator and place the eighth bit in the Negative flag and the seventh bit in the Overflow flag without affecting the contents of any register.
SED (set decimal mode)
In this mode only ADC and SBC are effected. The 4-bit nibbles are treated as decimals. This means that $1C (1 + 12) plus $1E (1 + 14) equals $30 (1+1(+c), 12+14(-10 overflow)= 16 => 0). Another example: $1a plus $10 also equals $30 (1+1(+c), 10+0(-10 overflow) = 0). One more: #$1f plus #$1f equals $34 (1+1(+c), 15+15(-10 overflow) = 20 => 4, remember that 16=>0, 17=>1,18=>2,19=>3,20=>4).