+Karl G Posted August 7, 2019 Share Posted August 7, 2019 After much searching, I wasn't able to find an 8-bit BCD to binary routine that was both cycle-efficient and cycle-consistent. I made my own, posted below. I was wondering if others have a routine that is leaner than this one? It uses A, X, and one byte of temporary RAM. ; BCD value $0 - $99 is in A. Returns binary number 0-99 in A BCDtoBin sta Temp and #$0F tax lda Temp and #$F0 lsr lsr lsr sta Temp asl asl clc adc Temp sta Temp txa clc adc Temp rts 1 Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 7, 2019 Share Posted August 7, 2019 Neat! There might be a few different routines out there but I don't know of any. You could also do this to compress your routine further: ; BCD value $0 - $99 is in A. Returns binary number 0-99 in A BCDtoBin2: sta Temp and #$0F tax eor Temp lsr sta Temp lsr lsr adc Temp stx Temp adc Temp rts 1 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted August 7, 2019 Author Share Posted August 7, 2019 Nice! That is much more elegant now. ? Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 7, 2019 Share Posted August 7, 2019 I had a thought, and made a new routine. It is 2 cycles faster, and 2 bytes less than the previous. tax and #$F0 lsr lsr sta Temp lsr adc Temp sta Temp txa sec sbc Temp rts In one byte BCD number the high nibble is a base 10 value stored as a base 16. To convert subtract a value of 6 * (high nibble >> 4) from the original value. Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 7, 2019 Share Posted August 7, 2019 One cycle faster, one byte less... ; BCD value $0 - $99 is in A. Returns binary number 0-99 in A BCDtoBin4: tax and #$F0 lsr lsr sta Temp txa sec sbc Temp rol sbc Temp lsr rts 1 Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 7, 2019 Share Posted August 7, 2019 I'll post a table version. It is 5 cycles faster than the last version, but uses 6 bytes more. It is only useful if you need the speed. ; BCD value $0 - $99 is in A. Returns binary number 0-99 in A BCDtoBin5: tax lsr lsr lsr lsr tay txa sec sbc SixTable,Y rts SixTable: .byte 6*0 .byte 6*1 .byte 6*2 .byte 6*3 .byte 6*4 .byte 6*5 .byte 6*6 .byte 6*7 .byte 6*8 .byte 6*9 1 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted August 7, 2019 Author Share Posted August 7, 2019 Well, it is good to have in the thread for completeness for others who may be searching for a fast routine for whatever reason. Quote Link to comment Share on other sites More sharing options...
+mksmith Posted August 7, 2019 Share Posted August 7, 2019 There is a convert function in 7800basic Quote Link to comment Share on other sites More sharing options...
CPUWIZ Posted August 7, 2019 Share Posted August 7, 2019 I would throw ROM at it and make a lookup table. 1 Quote Link to comment Share on other sites More sharing options...
+Karl G Posted August 8, 2019 Author Share Posted August 8, 2019 1 hour ago, CPUWIZ said: I would throw ROM at it and make a lookup table. For 100 values? Nah... ? Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 8, 2019 Share Posted August 8, 2019 Went with 2 temps instead of a single temp and and an index register. This version saves 1 byte and 3 cycles over the BCDtoBin4 routine in post #5 above. ; BCD value $0 - $99 is in A. Returns binary number 0-99 in A BCDtoBin6: sta Temp and #$F0 lsr sta Temp2 lsr lsr adc Temp sec sbc Temp2 rts 3 Quote Link to comment Share on other sites More sharing options...
+Andrew Davie Posted August 8, 2019 Share Posted August 8, 2019 8 hours ago, Omegamatrix said: Went with 2 temps instead of a single temp and and an index register. This version saves 1 byte and 3 cycles over the BCDtoBin4 routine in post #5 above. ; BCD value $0 - $99 is in A. Returns binary number 0-99 in A BCDtoBin6: sta Temp and #$F0 lsr sta Temp2 lsr lsr adc Temp sec sbc Temp2 rts I like this, very clever. To explain for others... bcd format $XY = effectively 16X + Y (where X and Y are the decimal digits of the number) we want decimal format XY = effectively 10X + Y So we need to subtract 6X from the original number and we'll have our answer The code first isolates X (and #$F0) and then divides by 2, giving us 8X stored in Temp2 Then divides by 4, giving 2X, adds it to the original number so that's now (16+2)X + Y And finally subtracts 8X (in Temp2), giving (16+2-8)X + Y --> 10X + Y Lovely. 2 Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted August 23, 2019 Share Posted August 23, 2019 Late to the party, but this is some elegant coding right here! Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted August 24, 2019 Share Posted August 24, 2019 I think the last solution might be optimal. I would love to see some other ideas though. One thing I should mention is that I don't trust ASR anymore. I had problems with it before on an Jr. Otherwise it would be a quick way to save 2 cycles and 1 byte to just ASR #$F0. It is actually would be a very useful opcode if it was stable. Others have also noted the same problems that I had with ASR. Quote Link to comment Share on other sites More sharing options...
JeremiahK Posted August 25, 2019 Share Posted August 25, 2019 Not my favorite illegal opcode! ? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.