Base 100: Difference between revisions

From NESdev Wiki
Jump to navigationJump to search
(Add code example for 16-bit addition and clean up the other examples.)
Line 30: Line 30:
<pre>
<pre>
AddOneCoin:
AddOneCoin:
   lda #99
   lda #99 ; Check for cap of 9999
   cmp Money+1
   cmp Money+1
   bne :+
   bne :+
   cmp Money+0
   cmp Money+0
   bne :+
   bne :+
     rts
     rts ; Exit if cap already reached
   :
   :
 
  ; Otherwise increment the amount
   inc Money
   inc Money
   lda Money
   lda Money
   cmp #100
   cmp #100
   bne :+
   bcc :+
     lda #0
     lda #0 ; Base 100 overflow
     sta Money
     sta Money
     inc Money+1
     inc Money+1
   :
   :
  rts
</pre>
=== 16-bit addition ===
Here's an example that demonstrates base 100 addition, using a pair of 16-bit numbers. The result is clamped to 9999:
<pre>
AddPrizeMoney:
  lda Money
  clc
  adc Prize
  cmp #100
  bcc :+
    ; Carry is set if the code ends up in here
    sbc #100 ; Guaranteed to set carry
  :
  sta Money
  ; Carry will correctly reflect base 100 overflow here
  lda Money+1
  adc Prize+1
  cmp #100
  bcc :+
    lda #99 ; Cap amount at 9999
    sta Money
  :
  ; Write the new amount
  sta Money+1
   rts
   rts
</pre>
</pre>
Line 53: Line 80:


<pre>
<pre>
PurchaseItem:
   lda Money
   lda Money
   sec
   sec
Line 62: Line 90:
   :
   :
   sta Temp
   sta Temp
   ; Carry
   ; Carry will correctly reflect base 100 overflow here
   lda Money+1
   lda Money+1
   sbc Price+1
   sbc Price+1
Line 70: Line 98:
   lda Temp
   lda Temp
   sta Money
   sta Money
  rts
</pre>
</pre>


[[Category:Arithmetic]]
[[Category:Arithmetic]]

Revision as of 21:46, 10 April 2024

Unlike the regular 6502, the 2A03 does not have decimal mode. One workaround for this is to keep numbers in binary, and use a BCD conversion routine to convert to binary-coded decimal as needed. Base 100 is another workaround that simplifies displaying the numbers onscreen.

In base 100, a number consists of a series of bytes that range from 0-99 (or $00-$63 in hexadecimal). Unlike in regular 8-bit math, numbers wrap around at 100 instead of at 256, so $0063 + $0001 is $0100 instead of $0064. Given a base 100 number, you can use a 100-byte table to convert each byte to BCD, which is easy to display.

base_100_to_bcd:
  .byte $00, $01, $02, $03, $04, $05, $06, $07, $08, $09, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19
  .byte $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35, $36, $37, $38, $39
  .byte $40, $41, $42, $43, $44, $45, $46, $47, $48, $49, $50, $51, $52, $53, $54, $55, $56, $57, $58, $59
  .byte $60, $61, $62, $63, $64, $65, $66, $67, $68, $69, $70, $71, $72, $73, $74, $75, $76, $77, $78, $79
  .byte $80, $81, $82, $83, $84, $85, $86, $87, $88, $89, $90, $91, $92, $93, $94, $95, $96, $97, $98, $99

Alternatively for even more speed you can have two tables that separately provide the ones digit and the tens digit of the resulting BCD number, letting you display each byte with something as simple as:

  ldx base_100_number
  lda base_100_tens,x
  sta $2007
  lda base_100_ones,x
  sta $2007

Base 100 is good for numbers that you want to display and do addition and subtraction on, but don't need for more complicated math. It can be good for things like a score, an amount of currency, or a timer or countdown.

Code examples

16-bit increment

This increments a 16-bit base 100 number by 1, while preventing it from going over 9999:

AddOneCoin:
  lda #99 ; Check for cap of 9999
  cmp Money+1
  bne :+
  cmp Money+0
  bne :+
    rts ; Exit if cap already reached
  :
  ; Otherwise increment the amount
  inc Money
  lda Money
  cmp #100
  bcc :+
    lda #0 ; Base 100 overflow
    sta Money
    inc Money+1
  :
  rts

16-bit addition

Here's an example that demonstrates base 100 addition, using a pair of 16-bit numbers. The result is clamped to 9999:

AddPrizeMoney:
  lda Money
  clc
  adc Prize
  cmp #100
  bcc :+
    ; Carry is set if the code ends up in here
    sbc #100 ; Guaranteed to set carry
  :
  sta Money
  ; Carry will correctly reflect base 100 overflow here
  lda Money+1
  adc Prize+1
  cmp #100
  bcc :+
    lda #99 ; Cap amount at 9999
    sta Money
  :
  ; Write the new amount
  sta Money+1
  rts

16-bit subtraction

Here's an example that demonstrates base 100 subtraction, using a pair of 16-bit numbers:

PurchaseItem:
  lda Money
  sec
  sbc Price
  bpl :+
    ; Carry is clear if the code ends up in here
    adc #100
    clc
  :
  sta Temp
  ; Carry will correctly reflect base 100 overflow here
  lda Money+1
  sbc Price+1
  bmi NotEnoughFunds
  ; Write the new amount
  sta Money+1
  lda Temp
  sta Money
  rts