Category:6502 Assembly: Difference between revisions

m
Line 22:
 
==Ports==
Unlike the z80 and the x86 computers, the 6502 has no dedicated <code>IN</code> or <code>OUT</code> commands. Rather, connected equipment such as keyboards, joysticks, graphics cards, etc. are "memory-mapped," meaning that the programmer interacts with them indirectly by reading or writing to/from a specific memory address. The memory address of interest depends on the hardware you are programming for, and is different for every system. In addition, memory-mapped ports often have different properties than normal RAM:
 
* A read-only port is what it sounds like. Attempting to write to this address will not affect the contents.
 
* A write-only port can be written to, but reading it will result in undefined behavior. The value read from the address is not necessarily what was last stored in it. Often, programmers will keep a "shadow register" in RAM containing the value intended for the port, and the port is only ever actually written to by copying from the shadow register. If the value in the port is ever needed for a calculation, the shadow register is read in its place. To make this more strange, it's even possible to have these ports in ROM as well as RAM. For example, Castlevania 3 on the Famicom updates its sound hardware by writing to sections of the cartridge ROM. Needless to say, the cartridge ROM is not altered by these writes.
 
* It is possible that a port that can be read, will be altered after reading it. Furthermore, writing to one port can alter the contents in another. This is often seen in video RAM ports, where writing to the port responsible for storing background graphics will auto-increment the value stored in the port responsible for deciding where those graphics will be stored. (This is how the NES's picture processing unit operates.)
 
* Writing to ports with commands other than <code>LDA/LDX/LDY</code> will either fail or result in undefined behavior. For example, <code>INC</code> or <code>DEC</code> may not have the desired result.
 
* Some registers can only be written to by bit shifting, these so-called "shift registers" require you to load a value into the accumulator, then repeatedly alternating between <code>ROR</code>ing the accumulator and <code>ROL</code>ing the port.
 
Reading and writing to or from a memory-mapped port is not necessarily the same as reading or writing from standard RAM; ports can be read-only or write-only, the former meaning that an <code>STA/STX/STY</code> instruction will have undefined behavior, and the latter meaning that an <code>LDA/LDX/LDY</code> instruction will not return the value last stored in that location. In addition, reading/writing these ports is often limited to certain operations. Typically, only the <code>STA/STX/STY</code> instructions can be used to write to these. Trying to <code>INC</code> or <code>DEC</code> the value at a memory-mapped port, for example, is not guaranteed to have the desired effect. Some registers can only be written to by bit shifting, these so-called "shift registers" require you to load a value into the accumulator than repeatedly alternating between <code>ROR</code>ing the accumulator and <code>ROL</code>ing the port.
 
<b>Ultimately, the programmer will need to refer to the instruction manual for the hardware they are programming to find the locations of memory-mapped ports, and how to interact with them properly.</b>
 
==Interrupts==
The 6502 has two interrupt types: <code>NMI</code> (Non-Maskable Interrupt) and <code>IRQ</code>(Interrupt Request). 6502 machines use the last 6 bytes of their address space to hold a vector table containing (in order) the addresses of the NMI routine, the program's start, and the IRQ routine. On most computers this is defined by the firmware, but on the NES you will need to declare these locations yourself.
1,489

edits