Difference between revisions of "Number output in 6502 machine code"

From BeebWiki
Jump to: navigation, search
(Much better 32-bit Decimal Printout)
 
m (1 revision)
(No difference)

Revision as of 23:58, 28 August 2013

Print 8-bit Hexadecimal

Print value in A in hexadecimal padded with zeros.

   \ On entry, A=value to print
   \ On exit,  A corrupted
   
   .PrHex
   PHA                        :\ Save A
   LSR A:LSR A:LSR A:LSR A    :\ Move top nybble to bottom nybble
   JSR PrNybble               :\ Print this nybble
   PLA                        :\ Get A back and print bottom nybble
   .PrNybble
   AND #15                    :\ Keep bottom four bits
   CMP #10:BCC PrDigit        :\ If 0-9, jump to print
   ADC #6                     :\ Convert ':' to 'A'
   .PrDigit
   ADC #ASC"0":JMP OSWRCH     :\ Convert to character and print

Print 8-bit Hexadecimal (more cunning)

Print value in A in hexadecimal padded with zeros.

(I used http://www.obelisk.demon.co.uk/6502/algorithms.html to refresh my memory.)

   \ On entry, A=value to print
   \ On exit,  A corrupted
   
   .PrHex
   PHA                        :\ Save A
   LSR A:LSR A:LSR A:LSR A    :\ Move top nybble to bottom nybble
   JSR PrNybble
   PLA
   AND #15                    :\ Mask out original bottom nybble
   .PrNybble
   SED
   CLC
   ADC #&90                   :\ Produce &90-&99 or &00-&05
   ADC #&40                   :\ Produce &30-&39 or &41-&46
   CLD
   JMP OSWRCH                 :\ Print it

Print 8-bit Decimal

Print value in A in decimal padded with zeros.

   \ On entry, A=value to print
   \ On exit,  A corrupted
   
   .PrDec
   LDX #&FF:SEC               :\ Prepare for subtraction
   .PrDec100
   INX:SBC #100:BCS PrDec100  :\ Count how many 100s
   ADC #100:JSR PrDecDigit    :\ Print the 100s
   LDX #&FF:SEC               :\ Prepare for subtraction
   .PrDec10
   INX:SBC #10:BCS PrDec10    :\ Count how many 10s
   ADC #10:JSR PrDecDigit     :\ Print the 10s
   TAX                        :\ Pass 1s into X
   .PrDecDigit
   PHA:TXA                    :\ Save A, pass digit to A
   ORA #ASC"0":JSR OSWRCH     :\ Convert to character and print it
   PLA:RTS                    :\ Restore A and return

Print 32-bit Decimal

Print 32-bit value in decimal with no padding or specified character padding. Smaller numbers can be printed by entering at PrDec32lp with Y set to an appropriate number of digits, eg LDY #5 for printing a 16-bit number.

   \ -------------------------------------
   \ PrDec32 - Print 32-bit decimal number
   \ Originally from HADFS ROM source
   \ -------------------------------------
   \ On entry, num..num+3=number
   \           flg       =pad character or zero for no padding
   \           sub..sub+3=division workspace
   \ On exit, A,X,Y,num,sub,flg corrupted
   \ ---------------------------------------------------------
   .PrDec32
   LDY #9                         :\ 9+1 digits
   .PrDec32lp
   TYA:PHA                        :\ Save Y=power of ten
   JSR PrComma                    :\ Print a comma if needed
   LDX #3:LDA #0
   .Power10lp1
   STA sub,X:DEX:BPL Power10lp1   :\ sub=0
   INC sub:LDX #sub               :\ sub=1
   .Power10lp2
   JSR Times10X:DEY:BNE Power10lp2:\ sub=10^Y
   JSR DivideNum:JSR PrDigit      :\ Divide, print digit or pad character
   PLA:TAY:DEY:BNE PrDec32lp      :\ Loop through digits
   LDA num:BPL PrDig1             :\ Print final digit
   :
   .PrDigit
   BNE PrDig1                     :\ Non-zero, print digit
   LDA flg:BEQ PrDig2             :\ No pad character, return
   JMP OSWRCH                     :\ Pad character, print it
   .PrDig1
   ORA #ASC"0":JSR OSWRCH         :\ Print digit
   LDA #ASC"0":STA flg            :\ Print zeros from now on
   .PrDig2
   RTS
   :
   \ Print a comma every three digits
   \ Omit this code and JSR PrComma if no commas required
   \ ----------------------------------------------------
   .PrComma
   CPY #2:BEQ PrComma1
   CPY #5:BEQ PrComma1
   CPY #8:BEQ PrComma1
   .PrComma0
   RTS
   .PrComma1
   LDX flg:LDA #ASC","            :\ Prepare a comma
   CPX #ASC"0":BEQ PrComma2       :\ Zeros being printed, print comma
   TXA                            :\ Otherwise print pad character
   .PrComma2
   TAX:BEQ PrComma0:JMP OSWRCH    :\ Print if not null pad character
   :
   \ -------------------------------------
   \ DivideNum - Divide num by sub
   \ -------------------------------------
   \ On entry, num=32-bit number
   \           sub=32-bit divisor
   \ On exit,  A=num DIV sub, Z=(A=0)
   \           num=num MOD sub
   \           Y preserved, X corrupted
   \ ----------------------------------------
   .DivideNum
   LDX #255:SEC
   .DivLp
   INX
   LDA num+0:SBC sub+0:STA num+0
   LDA num+1:SBC sub+1:STA num+1
   LDA num+2:SBC sub+2:STA num+2
   LDA num+3:SBC sub+3:STA num+3
   BCS DivLp
   LDA num+0:ADC sub+0:STA num+0
   LDA num+1:ADC sub+1:STA num+1
   LDA num+2:ADC sub+2:STA num+2
   LDA num+3:ADC sub+3:STA num+3
   TXA:RTS
   :
   \ -------------------------------
   \ Times10 - Multiple number by 10
   \ -------------------------------
   \ On entry, X=>zero page number
   \ On exit, X,Y preserved, A,F corrupted
   \ -------------------------------------
   .Times10X
   JSR TimesTwo               :\ n*2
   LDA 3,X:PHA:LDA 2,X:PHA    :\ save n*2
   LDA 1,X:PHA:LDA 0,X:PHA
   JSR TimesTwo:JSR TimesTwo  :\ n*8
   PLA:ADC 0,X:STA 0,X        :\ n*8+n*2 = n*10
   PLA:ADC 1,X:STA 1,X
   PLA:ADC 2,X:STA 2,X
   PLA:ADC 3,X:STA 3,X
   RTS
   :
   .TimesTwo
   ASL 0,X:ROL 1,X            :\ n=n*2
   ROL 2,X:ROL 3,X:RTS
   :

Jgharston 07:51, 25 December 2011 (UTC)