Programming Basics: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
No edit summary
No edit summary
Line 29: Line 29:
==== Multiplication of arbitrary numbers ====
==== Multiplication of arbitrary numbers ====
The following routine multiplies two unsigned 16-bit numbers, and returns an unsigned 32-bit value.
The following routine multiplies two unsigned 16-bit numbers, and returns an unsigned 32-bit value.
<source lang="6502tasm">
<source lang="6502">
mulplr = $c0 ; ZP location = $c0
mulplr = $c0 ; ZP location = $c0
partial = mulplr+2 ; ZP location = $c2
partial = mulplr+2 ; ZP location = $c2
Line 71: Line 71:
Here's an example of the above <tt>_usmul</tt> routine in action, which multiplies 340*268:
Here's an example of the above <tt>_usmul</tt> routine in action, which multiplies 340*268:


<source lang="6502tasm">
<source lang="6502">
   lda #<340 ; Low byte of 16-bit decimal value 340  (value: $54)
   lda #<340 ; Low byte of 16-bit decimal value 340  (value: $54)
   sta mulplr
   sta mulplr
Line 120: Line 120:
Since the NES can't easily do something like <code>printf()</code> (or <code>echo</code> for those familiar with scripting), one of the easiest ways to test code is to output some audio.  Something along the lines of...
Since the NES can't easily do something like <code>printf()</code> (or <code>echo</code> for those familiar with scripting), one of the easiest ways to test code is to output some audio.  Something along the lines of...


<source lang="6502tasm">
<source lang="6502">
reset:
reset:
   lda #$01 ; square 1
   lda #$01 ; square 1

Revision as of 07:37, 25 August 2013

Opcodes and their operands

To be written.

Registers

To be written.

The stack

Main article: Stack

Math operations

Simple operations

Addition and subtraction

To be written.

Bitwise (factor of 2) multiplication and division

To multiply the value in A by two, use the instruction ASL A.

To divide the value in A by two, use the instruction LSR A.

To be written.

Complex operations

Multiplication of arbitrary numbers

The following routine multiplies two unsigned 16-bit numbers, and returns an unsigned 32-bit value. <source lang="6502"> mulplr = $c0 ; ZP location = $c0 partial = mulplr+2 ; ZP location = $c2 mulcnd = partial+2 ; ZP location = $c4

_usmul:

 pha
 tya
 pha

_usmul_1:

 ldy #$10	; Setup for 16-bit multiply

_usmul_2:

 lda mulplr	; Is low order bit set?
 lsr a
 bcc _usmul_4
 clc		; Low order bit set -- add mulcnd to partial product
 lda partial
 adc mulcnd
 sta partial
 lda partial+1
 adc mulcnd+1
 sta partial+1
Shift result into mulplr and get the next bit of the multiplier into the low order bit of mulplr.

_usmul_4:

 ror partial+1
 ror partial
 ror mulplr+1
 ror mulplr
 dey
 bne _usmul_2
 pla
 tay
 pla
 rts

</source>

Here's an example of the above _usmul routine in action, which multiplies 340*268:

<source lang="6502">

 lda #<340	; Low byte of 16-bit decimal value 340  (value: $54)
 sta mulplr
 lda #>340	; High byte of 16-bit decimal value 340 (value: $01) (makes $0154)
 sta mulplr+1
 lda #<268	; Low byte of 16-bit decimal value 268  (value: $0C)
 sta mulcnd
 lda #>268	; High byte of 16-bit decimal value 268 (value: $01) (makes $010C)
 sta mulcnd+1
 lda #0		; Must be set to zero (0)!
 sta partial
 sta partial+1
 jsr _usmul	; Perform multiplication
RESULTS
mulplr = Low byte of lower word (bits 0 through 7)
mulplr+1 = High byte of lower word (bits 8 through 15)
partial = Low byte of upper word (bits 16 through 23)
partial+1 = High byte of upper word (bits 24 through 31)

</source>

Division of arbitrary numbers

To be written.

Floating-point numbers

To be written.

Gaming: keeping score

To be written.

If you keep score in a binary number, you must convert it to a sequence of digits before displaying it. The article 16-bit BCD lists a subroutine to do this.

Making simple sounds

To be written.

Controller input

To be written.

Graphics (should be covered elsewhere!)

"Hello, world!" program

Since the NES can't easily do something like printf() (or echo for those familiar with scripting), one of the easiest ways to test code is to output some audio. Something along the lines of...

<source lang="6502"> reset:

 lda #$01	; square 1
 sta $4015
 lda #$08	; period low
 sta $4002
 lda #$02	; period high
 sta $4003
 lda #$bf	; volume
 sta $4000

forever:

 jmp forever

</source>