+Cafeman #1 Posted July 7, 2011 I am going in circles trying to do this, and I'm hoping it'll be quicker to just ask somebody for help. What is the best way (simplest) to convert a variable named DragonKills from its hex value (say it is $25) into 2 bytes on-screen (antic 2) which would read "37", the decimal value? I know how to strip the HI and LO bytes and change (for example) a value of $01 to $11 which is the printable ASCII version of "1". I'm asking for the math or loop which takes a hex value and creates 2 bytes in memory called HI and LO which will have values of "$3" and "$7" to represent the decimal value of "37". thanks, A'rgh! (_)3 Quote Share this post Link to post Share on other sites
+GroovyBee #2 Posted July 7, 2011 For numbers in the decimal range 00 to 99 you can use the following :- Convert2Bcd: lda #0 sta BcdValue ldx #8 sed Convert2BcdLoop: asl Temp ; Contains DragonKills (or what ever you need to convert) lda BcdValue adc BcdValue sta BcdValue dex bne Convert2BcdLoop cld ; Convert to displayable characters. lda BcdValue lsr lsr lsr lsr clc adc #Offset_To_Convert_To_ASCII ; Convert to ASCII or a font (whatever you need to do). sta .... ; Write to video character memory. lda BcdValue and #$0F adc #Offset_To_Convert_To_ASCII sta ... ; Write to video character memory If you need the range 0 to 255 you need to add this line of code "sta BcdValue+1" before the loop and add the following :- lda BcdValue+1 adc BcdValue+1 sta BcdValue+1 after the first set of lda/adc/sta operations in the loop. Obviously you can unroll the loop or optimise as required. Hope that helps. 1 Quote Share this post Link to post Share on other sites
Heaven/TQA #3 Posted July 7, 2011 I am using a lookup table... digit_lo: 012345678901234567890... digit_hi: 000000000011111111112... Quote Share this post Link to post Share on other sites
Rybags #4 Posted July 7, 2011 (edited) That'd get a bit pricey if the value can range to 255. Lots of games just keep the score/lives as screen codes, ie directly in display RAM. Of course that's fine in most cases but not so great when you want to use them in calculations. If there's only the one variable for display/calculation then it might be easy to just keep a binary and screen code copy. But IMO the BCD is the best allrounder - it's easy to convert to screen code and not too much effort to get to binary if needed, but BCD can be used easily enough in general calculations anyway. If you dig around 6502.org there should be routines there to do stuff like converting 8-bit binary / BCD / ASCII. Also, if you can stand the kinda slow speed and losing all the RAM it uses, the inbuilt FP-ROM routines are there. Wouldn't use them during a game though (aside from text adventure or turn-based game). Edited July 7, 2011 by Rybags Quote Share this post Link to post Share on other sites
+Cafeman #5 Posted July 7, 2011 I modified GroovyBee's approach and it works fine. Here is the exact code for future reference. LoadStatsToScreen2 lda DragonKillsRank sta $383 ; work variable / memory location jsr Convert2Bcd lda $381 ; HI number sta $13ca ; screen memory lda $382 ; LO number sta $13cb ; screen memory ... other bcd convert jsr's here ... ; *** AdvII XE addition 7/7/2011 ***************************************************************************** XE ; *** 380 = work variable which will result in the converted bcd value - Ex: "$37" ; *** 381 = HI digit - Ex: "$3" ; *** 382 = LO digit - Ex: "$7" ; *** 383 = put the hexadecimal number you want converted to bcd in 4383. Ex: "$25" (which is decimal 37) Convert2Bcd: lda #0 sta $380 ;BcdValue ldx #8 sed Convert2BcdLoop: asl $383 ;input variable lda $380 ;BcdValue adc $380 ;BcdValue sta $380 ;BcdValue dex bne Convert2BcdLoop cld ; Convert to displayable characters. lda $380 ;BcdValue lsr a lsr a lsr a lsr a clc AND #%00001111 ;strip off left nibble ORA #%00010000 ;Convert to ASCII or a font (whatever you need to do). sta $381 ;store HI digit ; lda $380 ;BcdValue and #$0F ORA #%00010000 ;modify to ascii value for screen sta $382 ;store LO digit Covert2BcdExit rts ; *** AdvII XE END *************************************************************************************** XE END Quote Share this post Link to post Share on other sites
+Cafeman #6 Posted July 7, 2011 Lots of games just keep the score/lives as screen codes, ie directly in display RAM. Of course that's fine in most cases but not so great when you want to use them in calculations. If there's only the one variable for display/calculation then it might be easy to just keep a binary and screen code copy. But IMO the BCD is the best allrounder - it's easy to convert to screen code and not too much effort to get to binary if needed, but BCD can be used easily enough in general calculations anyway. If you dig around 6502.org there should be routines there to do stuff like converting 8-bit binary / BCD / ASCII. yeah, that's what I did for an earlier game of mine, Koffi: Yellow Kopter -- I just stored the score and lives as bcd right on-screen. But for this game I am checking the values of DragonKills and TimesEaten, etc, to derive a ranking (text), and then at the end of the game I need to convert them to displayable bcd. This worked. Quote Share this post Link to post Share on other sites
pps #7 Posted July 7, 2011 (edited) You could use the dec mode of the 6502 for the scores. Then you have the number always as dec, so no changing is needed. forget this comment. In one of my projects I have up to 65535 Points. They are stored in a word. So for displaying them I splited this into 5 digits from 0 to 9. Below you can find the code. ps1 to ps5 are the digits, points is the word The code is old and not optimized yet, but it works for me. ;--------------------------------------------- ;-- Punkte punkte lda #0 sta ps1 sta ps2 sta ps3 sta ps4 sta ps5 ;-- Highbyte zuerst lda points+1 sta pu clc lsr pu lda #0 adc #0 cmp #1 bne p512 ;-- 256 clc lda #6 adc ps5 sta ps5 clc lda #5 adc ps4 sta ps4 clc lda #2 adc ps3 sta ps3 ;-- 512 p512 clc lsr pu lda #0 adc #0 cmp #1 bne p1024 clc lda #2 adc ps5 sta ps5 clc lda #1 adc ps4 sta ps4 clc lda #5 adc ps3 sta ps3 p1024 clc lsr pu lda #0 adc #0 cmp #1 bne p2048 clc lda #4 adc ps5 sta ps5 clc lda #2 adc ps4 sta ps4 clc lda #0 adc ps3 sta ps3 clc lda #1 adc ps2 sta ps2 p2048 clc lsr pu lda #0 adc #0 cmp #1 bne p4096 clc lda #8 adc ps5 sta ps5 clc lda #4 adc ps4 sta ps4 clc lda #0 adc ps3 sta ps3 clc lda #2 adc ps2 sta ps2 p4096 clc lsr pu lda #0 adc #0 cmp #1 bne p8192 clc lda #6 adc ps5 sta ps5 clc lda #9 adc ps4 sta ps4 clc lda #0 adc ps3 sta ps3 clc lda #4 adc ps2 sta ps2 P8192 clc lsr pu lda #0 adc #0 cmp #1 bne p16384 clc lda #2 adc ps5 sta ps5 clc lda #9 adc ps4 sta ps4 clc lda #1 adc ps3 sta ps3 clc lda #8 adc ps2 sta ps2 p16384 clc lsr pu lda #0 adc #0 cmp #1 bne p32768 clc lda #4 adc ps5 sta ps5 clc lda #8 adc ps4 sta ps4 clc lda #3 adc ps3 sta ps3 clc lda #6 adc ps2 sta ps2 clc lda #1 adc ps1 sta ps1 p32768 clc lsr pu lda #0 adc #0 cmp #1 bne p1 clc lda #8 adc ps5 sta ps5 clc lda #6 adc ps4 sta ps4 clc lda #7 adc ps3 sta ps3 clc lda #2 adc ps2 sta ps2 clc lda #3 adc ps1 sta ps1 ;-- Lowbyte p1 lda points sta pu clc lsr pu lda #0 adc #0 cmp #1 bne p2 ;-- 1 clc lda #1 adc ps5 sta ps5 ;-- 2 p2 clc lsr pu lda #0 adc #0 cmp #1 bne p4 clc lda #2 adc ps5 sta ps5 p4 clc lsr pu lda #0 adc #0 cmp #1 bne p8 clc lda #4 adc ps5 sta ps5 p8 clc lsr pu lda #0 adc #0 cmp #1 bne p16 clc lda #8 adc ps5 sta ps5 p16 clc lsr pu lda #0 adc #0 cmp #1 bne p32 clc lda #6 adc ps5 sta ps5 clc lda #1 adc ps4 sta ps4 P32 clc lsr pu lda #0 adc #0 cmp #1 bne p64 clc lda #2 adc ps5 sta ps5 clc lda #3 adc ps4 sta ps4 p64 clc lsr pu lda #0 adc #0 cmp #1 bne p128 clc lda #4 adc ps5 sta ps5 clc lda #6 adc ps4 sta ps4 p128 clc lsr pu lda #0 adc #0 cmp #1 bne punktemalen clc lda #8 adc ps5 sta ps5 clc lda #2 adc ps4 sta ps4 clc lda #1 adc ps3 sta ps3 punktemalen ;-- da sind noch überläufe... lda ps5 cmp #10 beq p5st bmi p4sta p5st clc lda ps5 sbc #9 sta ps5 cmp #10 beq p5st2 bmi p5zehn inc ps4 jmp p5st p5st2 inc ps4 inc ps4 lda #0 sta ps5 jmp p4sta p5zehn inc ps4 ;------------ p4sta lda ps4 cmp #10 beq p4st bmi p3sta p4st clc lda ps4 sbc #9 sta ps4 cmp #10 beq p4st2 bmi p4zehn inc ps3 jmp p4st p4st2 inc ps3 inc ps3 lda #0 sta ps4 jmp p3sta p4zehn inc ps3 ;-------------- p3sta lda ps3 cmp #10 beq p3st bmi p2sta p3st clc lda ps3 sbc #9 sta ps3 cmp #10 beq p3st2 bmi p3zehn inc ps2 jmp p3st p3st2 inc ps2 inc ps2 lda #0 sta ps3 jmp p2sta p3zehn inc ps2 ;-------------- p2sta lda ps2 cmp #10 beq p2st bmi p1sta p2st clc lda ps2 sbc #9 sta ps2 cmp #10 beq p2st2 bmi p2zehn inc ps1 jmp p2st p2st2 inc ps1 inc ps1 lda #0 sta ps2 jmp p1sta p2zehn inc ps1 p1sta ;--------------------------- ldx #0 pl16 clc lda ps1,x adc #16 sta ps1,x inx cpx #5 bne pl16 ldx #0 ploop lda pkt,x sta text2,x inx cpx #4 bne ploop ldx #0 ploop2 lda ps1,x sta text2+4,x inx cpx #5 bne ploop2 rts pkt dta d'Pts:' ;--------------------------------------------- Edited July 7, 2011 by pps Quote Share this post Link to post Share on other sites
+Eagle #8 Posted July 7, 2011 no tables, no BCD mode http://codebase64.org/doku.php?id=base:32_bit_hexadecimal_to_decimal_conversion using lookup tables http://codebase64.org/doku.php?id=base:hexadecimal_to_decimal_conversion without lookup tables http://codebase64.org/doku.php?id=base:more_hexadecimal_to_decimal_conversion Quote Share this post Link to post Share on other sites
+GroovyBee #9 Posted July 7, 2011 clc AND #%00001111 ;strip off left nibble You can remove the above lines in your implementation. The 4 LSR's already leave the top nybble zeroed out. Quote Share this post Link to post Share on other sites
+Cafeman #10 Posted July 7, 2011 clc AND #%00001111 ;strip off left nibble You can remove the above lines in your implementation. The 4 LSR's already leave the top nybble zeroed out. It wasn't working for me. I compile with TASM. Could the LSR act differently across assemblers? Quote Share this post Link to post Share on other sites
+GroovyBee #11 Posted July 7, 2011 It wasn't working for me. I compile with TASM. Could the LSR act differently across assemblers? LSR should shift a 0 into bit7 as bit0 is shifted into carry. What hex value is the opcode for the instruction in your assembler? It should be 0x4A. Quote Share this post Link to post Share on other sites
+Cafeman #12 Posted July 8, 2011 I don't know. I stepped thru the code as you gave me to see where it wasn't working - I could have not entered something correctly, I don't know. But I made the additions based on what I observed happening, and the additional statements fixed it. I'm moving on. Thanks for the help very much! I have forgotten a lot. Quote Share this post Link to post Share on other sites
Kweepa #13 Posted July 30, 2011 Here's a lovely little routine from codebase64: ; Converts .A to 3 ASCII/PETSCII digits: .Y = hundreds, .X = tens, .A = ones ; modify for Atari by subtracting $20 from the constants? ldy #$2f ; this should be '0'-1 ldx #$3a ; this should be '0'+1 sec - iny sbc #100 bcs - - dex adc #10 bmi - adc #$2f ; this should be '0'-1 rts http://www.codebase64.org/doku.php?id=base:tiny_.a_to_ascii_routine Quote Share this post Link to post Share on other sites