Jump to content

Category:6502 Assembly: Difference between revisions

m
no edit summary
mNo edit summary
Line 21:
 
Furthermore, although every machine that uses the 6502 architecture is different in some way, almost all of them, regardless of their total capacity for RAM, have the zero page dedicated for RAM (with the exception of the PC Engine/Turbografx-16 whose zero page is located at $2000.) Whether you're programming on the Apple II, the Commodore 64, or the NES, the zero page is still the zero page.
 
The 6502 has much fewer registers than its contemporaries, and as such the zero page is useful as a set of "registers," albeit slower. The 6502 is also limited in its stack operations, as it cannot push X or Y onto the stack directly, and must destroy the accumulator in order to do so. This creates a problem when a function needs to preserve multiple registers yet takes its input from the accumulator. The easiest solution is to use a zero page memory address to preserve the accumulator and the stack for X and Y. (Or vice versa.)
 
On the 65816, the zero page is called the "direct page," and it can be relocated. The 65816's D register points to the direct page. The location of the direct page can be changed at runtime using the <code>TCD</code> command. This feature lets the programmer set up different pages of RAM for different tasks, and switch the direct page to that page temporarily to speed up that task.
Line 336 ⟶ 338:
Unfortunately, almost all optimizations in assembly languages are at the expense of readability (probably the biggest reason why assembly isn't used as much these days), and this one is no exception. When programming in 6502 in particular you will find yourself committing all the taboos of modern programming, such as <code>BREAK</code>, <code>GOTO</code>, and sometimes even the dreaded, forbidden, <code>SELF-MODIFYING CODE!</code>
 
Here's another example of the trade-off between readability and efficient code.
<lang 6502asm>; compares the accumulator to a constant range of values.
; If the accumulator is within the bounds stored in the temp variables "lowerbound" and "upperbound" then y = 1, otherwise y = 0.
CompareRange_Constant:
CMP lowerbound
BCC outOfBounds
 
CMP upperbound
BCS outOfBounds ;assume the true upper bound is one less than the value stored here.
 
;number was in bounds
LDY #1
JMP end
 
outOfBounds:
LDY #0
end:
rts</lang>
 
The more efficient way is to do this, which yields the same result:
<lang 6502asm>; compares the accumulator to a constant range of values.
; If the accumulator is within the bounds stored in the temp variables "lowerbound" and "upperbound" then y = 1, otherwise y = 0.
CompareRange_Constant:
LDY #0 ;load this here at the beginning, before we even know the result.
CMP lowerbound ;compare ACCUMULATOR to lowerbound, not Y.
BCC outOfBounds
 
CMP upperbound
BCS outOfBounds ;assume the true upper bound is one less than the value stored here.
 
;number was in bounds
 
INY ;takes fewer bytes to encode than LDY #1. If out of bounds, this will get skipped and the function returns 0.
 
outOfBounds:
RTS</lang>
 
==Assembler Syntax==
1,489

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.