Base 100: Difference between revisions
TakuikaNinja (talk | contribs) (Add trivial examples for multiplication/division by 100.) |
TakuikaNinja (talk | contribs) m (Improve wording.) |
||
Line 139: | Line 139: | ||
=== Multiplication/Division by powers of 100 === | === Multiplication/Division by powers of 100 === | ||
Multiplication and division by powers of 100 are trivial in base 100, analogous to powers of 10 in base 10 (BCD) or powers of 2 in binary: | Multiplication and division by powers of 100 are trivial to do in base 100, analogous to powers of 10 in base 10 (BCD) or powers of 2 in binary: | ||
<pre> | <pre> |
Revision as of 05:18, 15 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
Byte to base 100 encoding
This takes in an unsigned 8-bit value in A and returns its base 100 encoding in X (high byte) and A (low byte):
; Parameter: A = byte to encode ; Returns base 100 encoding as: X = high byte, A = low byte ByteToBase100: ldx #0 ; Init high byte of result : cmp #100 ; 0~99 is valid bcc @ret inx sbc #100 ; Carry already set bcs :- ; Carry is guaranteed to be set @ret: rts
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 decrement
This decrements a 16-bit base 100 number by 1, while preventing it from going under 0:
SubOneCoin: lda Money ; Check if amount is 0 ora Money+1 beq :+ ; Otherwise decrement the amount lda #99 dec Money bpl :+ sta Money ; Base 100 underflow dec 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 underflow here lda Money+1 sbc Price+1 bmi NotEnoughFunds ; Write the new amount sta Money+1 lda Temp sta Money rts
Multiplication/Division by powers of 100
Multiplication and division by powers of 100 are trivial to do in base 100, analogous to powers of 10 in base 10 (BCD) or powers of 2 in binary:
; Multiply an 8-bit base 100 value by 100, storing the result in 16 bits Mult100: lda #0 ; Put a 0 in the low byte sta Res lda Value ; Put the input value in the high byte to multiply by 100 sta Res+1 rts ; Divide a 16-bit base 100 value by 100, storing the result in 16 bits Div100: lda #0 ; Put a 0 in the high byte sta Res+1 lda Value ; Put the input value in the low byte to divide by 100 sta Res rts