Página 1 de 1
ayuda con hex a decimal mac65
Publicado: Jue Jul 19, 2018 10:52 pm
por dogdark
Estoy con el siguiente problema, necesito convertir el hexadecimal $44000 a decimal. por ende no puedo utilizar el floating point por que este solo trabaja hasta 2 bytes y un máximo de 65335, trate de todos los medios, incluso sumando de un byte a uno y comparando hasta llegar a la igualdad, pero el proceso es demasiado lento, casi 1 minuto. He revisado revistas manuales y ninguno da señal de algún código que pueda ayudar a realizar este proceso.
Código: Seleccionar todo
*=$2000
M=17
MEMORY
.BYTE $00,$00,$00,$9B
DISPONIBLE
.BYTE $00,$00,$00,$00,$00,$00,$9B
CALCULO
.BYTE $00,$00,$00,$00,$00,$00,$9B
SUMAMOSMEMORIA
LDX M
SUMAMOSMEMORIA?
CLC
LDA MEMORY+2
ADC #$00
STA MEMORY+2
LDA MEMORY+1
ADC #$40
STA MEMORY+1
LDA MEMORY
ADC #0
STA MEMORY
SUMAMOSMEMORIA??
CPX #0
BEQ FINSUMAMOSMEMORIA
DEX
JMP SUMAMOSMEMORIA?
FINSUMAMOSMEMORIA
RTS
INICIO
LDA #0
STA 710
LOOP
JMP LOOP
*=$02E0
.WORD INICIO
como se puede apreciar en el código tengo la variable M con un valor de 16 que realiza el bucle de SUMAMOSMEMORIA sumando de a $4000 bytes que equivale a 16384 y este resultado queda en MEMORY( $04 $40 $00) y eso quedo dejarlo como disponible ( $02,$07,$08,$05,$02,$08 ). Alguna idea de como realizar la conversión.
mas que nada algún código que permita poder pasar los hex a decimales y dejarlos byte por byte para pasarlos a ascii
Re: ayuda con hex a decimal mac65
Publicado: Vie Jul 20, 2018 1:49 am
por xt5
La verdad que me perdí bastante en la explicación, si te entiendo bien quieres tomar un valor de memoria y pasarlo a decimal en la impresión?
O sea, por ejemplo tienes en la memoria:
MEMORY
.BYTE $07,$5b,$cd,$15 ($75bcd15)
Y quieres transformarlo en los caracteres que conforman 123456789?
Si es así, tienes que ir poner el modulo de 10, dividir por 10 y así seguir...
Ejemplo
v=$44000
loop:
digito=v%10
v=v/10 # asumiendo que la división es de enteros
goto loop
Como hacerlo en assembler del 6502? ufff creo que hay algo de pega allí
Re: ayuda con hex a decimal mac65
Publicado: Vie Jul 20, 2018 3:24 am
por dogdark
si xt5. el tema es bien complicado. es pasar cualquier byte que vaya desde un $00 A $44000 y convertirlo en ascii. con el floating point no lo logre. me lee hasta $ffff
Re: ayuda con hex a decimal mac65
Publicado: Vie Jul 20, 2018 9:48 am
por xt5
No es tan difícil
Crea 2 funciones, una que desplace un numero grande en memoria hacia la izquierda (en bits) y otra que los sume, luego ejecuta lo siguiente:
a=0x44000
b=(a<<1)+a
c=b+(b<<4)
d=(a<<1)+(c<<3)+(c<<11)+(c<<19)+(b<<27)
e=d>>32
Y con eso tienes división por 10
A la tarde te lo explico, pero prueba.
Saludos
Re: ayuda con hex a decimal mac65
Publicado: Vie Jul 20, 2018 11:20 am
por vitoco
Si es que entiendo bien tu problema, tienes un número hexadecimal con un dígito en cada byte, y lo quieres llevar a decimal, pero también con 1 dígito en cada byte. Es decir, sólo estás cambiando el formato de despliegue de un número que en binario sería único.
Deberías separar en 2 cosas: convertir el hexadecimal en binario y luego convertir el binario en decimal.
Sin embargo, se me ocurre que podrías hacer un poco de álgebra para convertir los dígitos directamente de hex a dec y sumar, aprovechando el modo decimal del procesador 6502 para sumas usando nibbles de 0 a 9 en vez de 0 a F en cada par de los 4 bits de un byte.
Por ejemplo, el número hex de 6 dígitos $IJKLMN necesita 8 dígitos decimales, y se calcularía así:
N+M*16+L*(16*16)+K*(16*16*16)+L*(16*16*16*16)+J*(16*16*16*16*16)+I*(16*16*16*16*16*16)
Multiplicar por 16 es lo mismo que multiplicar por 10 y por 6 y luego sumar ambos resultados. La multiplicación por 10 es tan solo mover los nibbles a la izquierda (4 shifts de 1 bit), pero queda la del 6, y eso no es más que "enseñarle" la tabla del 6 al algoritmo, es decir, simplemente usar una tabla con los valores precalculados desde el 6*0 al 6*15, pero en formato de nibbles.
Por lo tanto, se puede tomar el primer caracter del hexadecimal, ver su correspondencia en formato de nibbles (otra tabla), ponerlo en el resultado en el byte menos significativo y luego por cada caracter adicional, hacer la operación de "multiplicación por 16" y sumarle el correspondiente nibble. Al final del ciclo tendrás el resultado en 4 bytes (8 nibbles) y sólo necesitarás un bucle adicional para obtener los 8 caracteres de la representación decimal.
¿Se entendió?
Si lo que propone xt5 no te resulta tan simple, hago un doble clic a la explicación y agrego detalles de como usar los nibbles y el modo decimal del 6502.
Re: ayuda con hex a decimal mac65
Publicado: Vie Jul 20, 2018 5:20 pm
por dogdark
a ver muchachos creo que plantié mal mi complicación.
tengo lo siguiente
Código: Seleccionar todo
muestrobytesencontrados
.byte "000000",$9b
bytesencontrados
.byte $00,$00,$00
en la cual yo tomo los bytes leidos desde un periferico X, por lo tanto esta puede ser desde $00, hasta $FFFFF, estos bytes leídos quedan en bytesencontrados, porque la capacidad de recibir me ocupa hasta 3 bytes, y lo que necesito es pasar los bytes encontrados(Total) a muestro bytes en codigo ascii con valores de 0 a 10.
como los bytes quedan en $44000 yo pienso que quedan de la siguiente manera, en $04,$40,$00
bytesencontrados+2 ($00)
bytesencontrados+1 ($40)
bytesencontrados ($04)
a lo mejor mi perspectiva es errónea.
Re: ayuda con hex a decimal mac65
Publicado: Vie Jul 20, 2018 5:38 pm
por xt5
Confirma si te entiendo bien, tu problema es pasar el valor $44000 a un string decimal en la pantalla, en el contexto atariano, sería:
Entrada:
.byte $04,$40,$00
o
.byte $00,$40,$04
Según el
endianness utilizado, pero ese detalle solo lo sabes tu.
Salida:
.byte $32, $37, $38, $35, $32, $38 # representación en ATASCII del número 278528
Es eso? de ser así lo que te digo sigue 100% en pie.
Re: ayuda con hex a decimal mac65
Publicado: Vie Jul 20, 2018 6:01 pm
por dogdark
exacto xt5, pasar un valor de byte a string decimal en pantalla. el manejo lo estoy haciendo con la primera accion, big-endian(he aprendido algo nuevo)
Re: ayuda con hex a decimal mac65
Publicado: Sab Jul 21, 2018 10:38 am
por vitoco
OK, entonces no era un hexadecimal en "pantalla" (un caracter por byte) sino que un integer de 3 bytes. Eso te ahorra la conversión a binario por un lado, y por otro habría que adaptar mi algoritmo a nibbles...
Re: ayuda con hex a decimal mac65
Publicado: Dom Jul 22, 2018 8:43 pm
por dogdark
Siguiendo los pasos que me han dado, se me ocurrió seguir los siguientes procesos. El primero el byte $040000 para poder pasarlo a decimal, le realizo un previo proceso que es convertirlo a bytes independientes que no superen el $0F, dando vueltas por todos lados me recordé como se pasaba un decimal a hexadecimal y usando la misma regla, me di cuenta que el computador es tonto, jjajja me acorde de mi profe de PHP.
Código: Seleccionar todo
dex a hex
$00/16 = 0
$00-(0*16) = 0
$00/16 = 0
$00-(0*16) = 0
$04/16 = 4
$00-(0*16) = 0
ya con eso pude obtener el paso de hexadecimal a como si fuera nibble, un pequeño engaño.
y el resultado lo incorpora como $00,$04,$00,$00,$00,$00
si fuese otro byte $053928
lo deja como $00,$05,$03,$09,$02,$08
tarea para la casa para la semana es realizar la conversión y suma de estos bytes a decimal
les dejo el código.
Código: Seleccionar todo
*=$2000
CALCULO
.BYTE $00,$00,$00,$00,$00,$00,$00,$00 ;7
.BYTE $00,$00,$00,$00,$00,$00,$00,$00 ;15
.BYTE $9B
TOTAL
.BYTE $04,$00,$00,$9B
MUESTROASCII
.BYTE "000000",$9B
;****************************
; LIMPIO CALCULO
;****************************
LIMPIOCALCULO
LDX #15
LIMPIOCALCULO?
LDA #$00
STA CALCULO,X
CPX #0
BEQ FINLIMPIOCALCULO
DEX
JMP LIMPIOCALCULO?
FINLIMPIOCALCULO
RTS
;****************************
; PROCESO EL TOTAL
;****************************
PROCESO.TOTAL
JSR LIMPIOCALCULO
LDX #2
LDY #5
PROCESO.TOTAL?
;CARGO EL PRIMER BYTE PARA CONVERTIR A NIBBLE
LDA TOTAL,X
STA CALCULO
;SOLICITO PROCESO DE PASO A NIBBLE
JSR CONVIERTO.A.NIBBLE
LDA CALCULO+14
STA MUESTROASCII,Y ;6
DEY
LDA CALCULO+13
STA MUESTROASCII,Y ;5
CPX #0
BEQ FIN.PROCESO.TOTAL
DEY
DEX
JMP PROCESO.TOTAL?
FIN.PROCESO.TOTAL
RTS
;****************************
;CONVERTIMOS LOS BYTES A NIBBLES
;****************************
CONVIERTO.A.NIBBLE
;CARGO EL BYTE MOMENTANEO Y LO GUARDO
;
LDA #$00
STA CALCULO+15
STA CALCULO+14
STA CALCULO+13
LDA CALCULO
STA CALCULO+15
;DIVIDO POR 16 EL BYTE
;PARA OBTENER EL BYTE LOW
LSR CALCULO ;2
LSR CALCULO ;4
LSR CALCULO ;8
LSR CALCULO ;16
;CARGO AL ACUMULADOR EL RESULTADO
;DE LA DIVISION *16
;Y LO GUARDO EN CALCULO+14
LDA CALCULO
STA CALCULO
STA CALCULO+13
ASL CALCULO ;2
ASL CALCULO ;4
ASL CALCULO ;8
ASL CALCULO ;16
LDA CALCULO
SEC
LDA CALCULO+15
SBC CALCULO
STA CALCULO+14
RTS
;FIN CONVERTIMOS BYTES A NIBBLES
INICIO
LDA #0
STA 710
LDA #1
STA 752
JSR PROCESO.TOTAL
LDX #<MUESTROASCII
LDY #>MUESTROASCII
JSR $C642
LOOP
JMP LOOP
*=$2E0
.WORD INICIO
les dejo el codigo en asm por si lo quieren descargar junto con su xex
Re: ayuda con hex a decimal mac65
Publicado: Dom Jul 22, 2018 10:08 pm
por xt5
Para cambiar de base, tienes que si o si tomar en consideración el numero completo como tal, no lo puedes hacer parcialmente, si tomas un nibble, byte, bit, etc, no te sirve, no lo puedes cambiar de base sin consideras TODOS los bits.
Encontré en Internet una solución demasiado clever, concisa y de pocos ciclos que hace exactamente lo que buscas, no te quiero spoilear si no la quieres ver aun, avísame si la puedo enlazar o si quieres seguir adelante con alguna otra solución y te voy echando una mano.
Otra cosa super importante, muchas veces te refieres a que quieres pasar "desde hexadecimal", en el contexto que lo usas eso no existe, solo quieres pasar valores de la memoria a decimal, no están almacenados de forma hexadecimal en memoria, solo es un numero representado por un conjunto de bits.
Saludos!!
Re: ayuda con hex a decimal mac65
Publicado: Dom Jul 22, 2018 10:25 pm
por dogdark
Xt5 dele no más con los códigos, son buen aporte, nunca será expoiler, al contrario es una gran ayuda, incluso se pueden usar esos mismos y modificarlos para poder usarlos para proyectos propios. se agradece de antemano.
la idea era mas que nada, es como lo vemos algunos la entrada de bytes, obviamente son solo bits en posiciones de memoria. pero en ese ejemplo que puse, los novatos como yo, apreciamos que el atari tiene ese comportamiento por dentro en la forma de realizar los cálculos. entonces sigo la temática que incluso e visto en video tutoriales.
hex a decimal
se multiplican
16 elevado a 5
$00
16 elevado a 4
$04
$00, $00 ,$00 ,$00 etc..... espero ideas en códigos mas resumidos para seguir estudiando.
Re: ayuda con hex a decimal mac65
Publicado: Dom Jul 22, 2018 11:32 pm
por xt5
El código está publicado aquí, junto con mas cosas interesantes:
http://www.obelisk.me.uk/6502/algorithms.html
Código: Seleccionar todo
; Convert an 16 bit binary value into a 24bit BCD value
BIN2BCD LDA #0 ;Clear the result area
STA RES+0
STA RES+1
STA RES+2
LDX #16 ;Setup the bit counter
SED ;Enter decimal mode
_LOOP ASL VAL+0 ;Shift a bit out of the binary
ROL VAL+1 ;... value
LDA RES+0 ;And add it into the result, doubling
ADC RES+0 ;... it at the same time
STA RES+0
LDA RES+1
ADC RES+1
STA RES+1
LDA RES+2
ADC RES+2
STA RES+2
DEX ;More bits to process?
BNE _LOOP
CLD ;Leave decimal mode
Es muy simpático, lo que hace es leer bit a bit la entrada y en cada pasada por cada bit, al valor acumulado le suma si mismo (es decir lo duplica) y cuando hace la suma tiene el bit en cuestión en carry, la magia es que la suma la hace en modo modo decimal.
Está genial y compacto, está versión es para una entrada de 16 bits, así que le tienes que dar soporte para 24 que es lo que necesitas en tu caso.
Saludos,
Re: ayuda con hex a decimal mac65
Publicado: Lun Jul 23, 2018 8:00 am
por dogdark
Muchas gracias xt5 por los códigos, es un tremendo aporte para aprender. Ahora con esta ayuda podré avanzar y revisar códigos, me falta mucho por aprender, al ser autodidacta se me complica la cosa, pero con la ayuda de ustedes muchas veces se me hace mas fácil. Revisare todo y haré código para mostrarlo y compartirlo a lo que lo termine.
Saludos.
Re: ayuda con hex a decimal mac65
Publicado: Lun Jul 23, 2018 9:32 pm
por dogdark
Hasta el momento me quedo funcionando hasta 99. algo es algo
Código: Seleccionar todo
*=$2000
CALCULO
.BYTE $00,$00,$00,$00,$00,$00,$9B
TOTALBYTES
.BYTE $63,$00,$00
CODIGO
.BYTE " ",$9B
LIMPIOCALCULO
LDX #5
LIMPIOCALCULO?
LDA #$00
STA CALCULO,X
CPX #0
BEQ FINCALCULO
DEX
JMP LIMPIOCALCULO?
FINCALCULO
RTS
; Convierta un valor binario de 16 bits en un valor de BCD de 24 bits
BIN2BCD
;BORRAMOS EL AREA DE CALCULO
JSR LIMPIOCALCULO
LDX # 16 ; Configurar el contador de bits
SED ; Entrar en modo decimal
LOOP
ASL TOTALBYTES+0 ; Cambia un poco el binario
ROL TOTALBYTES+1 ; ... valor
LDA CALCULO+0 ; y agréguelo al CALCULOultado, doblando
ADC CALCULO+0 ; ... al mismo tiempo
STA CALCULO+0
LDA CALCULO+1
ADC CALCULO+1
STA CALCULO+1
LDA CALCULO+2
ADC CALCULO+2
STA CALCULO+2
DEX ; ¿Más bits para procesar?
BNE LOOP
CLD ; Dejar modo decimal
; Imprima el valor BCD en A como dos dígitos ASCII
IMPRIMA
LDA CALCULO
PHA ; Guardar el valor de BCD
IMPRIMA?
LSR A ; desplaza los cuatro bits más significativos
LSR A ; ... en los cuatro menos significativos
LSR A
LSR A
ORA #$30 ; Hacer un dígito ASCII
STA CODIGO ; ... e imprímalo
PLA ; Recuperar el valor de BCD
AND #$0F ; enmascarar todos menos los 4 bits inferiores
ORA #$30 ; Hacer un dígito ASCII
STA CODIGO+1
RTS
INICIO
LDA #0
STA 710
JSR BIN2BCD
LDX #<CODIGO
LDY #>CODIGO
JSR $C642
LOOP2
JMP LOOP2
*=$2E0
.WORD INICIO
Re: ayuda con hex a decimal mac65
Publicado: Mar Jul 24, 2018 11:58 pm
por xt5
Aquí te dejo una implementación sencilla para números de hasta 24 bits
Código: Seleccionar todo
LISTING
1 0000 :
2 2000 : org $2000
3 2000 :
4 2000 : RES_ATASCII:
5 2000 : db $00, $00, $00, $00, $00, $00, $00, $00
5 2000 : 00 00 00 00 00 00 00 00
6 2008 : RES_BCD:
7 2008 : db $00, $00, $00, $00
7 2008 : 00 00 00 00
8 200C : VAL: db $00, $40, $04
8 200C : 00 40 04
9 200F :
10 200F : ; Convert an 16 bit binary value into a 24bit BCD value
11 200F : BIN2BCD:
12 200F : A9 00 lda #0 ;Clear the result area
13 2011 : 8D 08 20 sta RES_BCD+0
14 2014 : 8D 09 20 sta RES_BCD+1
15 2017 : 8D 0A 20 sta RES_BCD+2
16 201A : 8D 0B 20 sta RES_BCD+3
17 201D : A2 18 ldx #24 ;Setup the bit counter
18 201F : F8 sed ;Enter decimal mode
19 2020 : _LOOP: 0E 0C 20 asl VAL+0 ;Shift a bit out of the binary
20 2023 : 2E 0D 20 rol VAL+1
21 2026 : 2E 0E 20 rol VAL+2 ;... value
22 2029 : AD 08 20 lda RES_BCD+0 ;And add it into the result, doubling
23 202C : 6D 08 20 adc RES_BCD+0 ;... it at the same time
24 202F : 8D 08 20 sta RES_BCD+0
25 2032 : AD 09 20 lda RES_BCD+1
26 2035 : 6D 09 20 adc RES_BCD+1
27 2038 : 8D 09 20 sta RES_BCD+1
28 203B : AD 0A 20 lda RES_BCD+2
29 203E : 6D 0A 20 adc RES_BCD+2
30 2041 : 8D 0A 20 sta RES_BCD+2
31 2044 : AD 0B 20 lda RES_BCD+3
32 2047 : 6D 0B 20 adc RES_BCD+3
33 204A : 8D 0B 20 sta RES_BCD+3
34 204D : CA dex ;More bits to process?
35 204E : D0 D0 bne _LOOP
36 2050 : D8 cld ;Leave decimal mode
37 2051 : ;BRK
38 2051 : BCD2ATASCII:
39 2051 : A2 04 ldx #4
40 2053 : A0 00 ldy #0
41 2055 : _LOOP2:
42 2055 : BD 07 20 lda RES_BCD-1,X
43 2058 : 4A lsr
44 2059 : 4A lsr
45 205A : 4A lsr
46 205B : 4A lsr
47 205C : 09 30 ora #$30
48 205E : 99 00 20 sta RES_ATASCII,Y
49 2061 : BD 07 20 lda RES_BCD-1,X
50 2064 : 29 0F and #$0F
51 2066 : 09 30 ora #$30
52 2068 : 99 01 20 sta RES_ATASCII+1,Y
53 206B : C8 iny
54 206C : C8 iny
55 206D : CA dex
56 206E : D0 E5 bne _LOOP2
57 2070 : 00 brk
VAL: 28 85 27
RES_BCD: 28 85 27 00
RES_ATASCII: 30 30 32 37 38 35 32 38
Saludos
Re: ayuda con hex a decimal mac65
Publicado: Mié Jul 25, 2018 6:12 pm
por dogdark
Muchas gracias Xt5, estaba mirando el código y me parece que trabajas en mads. que es muy parecido al mac.
Re: ayuda con hex a decimal mac65
Publicado: Mié Jul 25, 2018 7:14 pm
por vitoco
Xt5, es demasiado simple la solución. No se me había ocurrido multiplicar por 2 en modo decimal simplemente sumando el valor consigo mismo en cada iteración. Güena!!!
Re: ayuda con hex a decimal mac65
Publicado: Mié Jul 25, 2018 9:21 pm
por dogdark
El codigo es bien reducido, y lo haces ver muy fácil de usar, cada día se aprende algo nuevo, muy agradecido.
Re: ayuda con hex a decimal mac65
Publicado: Mié Jul 25, 2018 9:38 pm
por xt5
vitoco escribió: ↑Mié Jul 25, 2018 7:14 pm
Xt5, es demasiado simple la solución. No se me había ocurrido multiplicar por 2 en modo decimal simplemente sumando el valor consigo mismo en cada iteración. Güena!!!
De hecho me lo voy a robar para un proyecto implementandolo en hardware, porque de base 10 a base 2 haciendo lo mismo es re fácil, pero como un compu común no suma en base 10 jamás se me hubiese iluminado la ampolleta.
dogdark escribió:
Muchas gracias Xt5, estaba mirando el código y me parece que trabajas en mads. que es muy parecido al mac.
No es MADS, es un playground que me hice en python, usa una versión modificada de
asm6502.py como assembler y
py65emu como emulador, entonces esto es lo que corro desde python:
Código: Seleccionar todo
import playground65
code = """
ORG $2000
RES_ATASCII:
DB $00, $00, $00, $00, $00, $00, $00, $00
RES_BCD:
DB $00, $00, $00, $00
VAL: DB $00, $40, $04
; Convert an 16 bit binary value into a 24bit BCD value
BIN2BCD:
LDA #0 ;Clear the result area
STA RES_BCD+0
STA RES_BCD+1
STA RES_BCD+2
STA RES_BCD+3
LDX #24 ;Setup the bit counter
SED ;Enter decimal mode
_LOOP: ASL VAL+0 ;Shift a bit out of the binary
ROL VAL+1
ROL VAL+2 ;... value
LDA RES_BCD+0 ;And add it into the result, doubling
ADC RES_BCD+0 ;... it at the same time
STA RES_BCD+0
LDA RES_BCD+1
ADC RES_BCD+1
STA RES_BCD+1
LDA RES_BCD+2
ADC RES_BCD+2
STA RES_BCD+2
LDA RES_BCD+3
ADC RES_BCD+3
STA RES_BCD+3
DEX ;More bits to process?
BNE _LOOP
CLD ;Leave decimal mode
;BRK
BCD2ATASCII:
LDX #4
LDY #0
_LOOP2:
LDA RES_BCD-1,X
LSR
LSR
LSR
LSR
ORA #$30
STA RES_ATASCII,Y
LDA RES_BCD-1,X
AND #$0F
ORA #$30
STA RES_ATASCII+1,Y
INY
INY
DEX
BNE _LOOP2
BRK
"""
p65=playground65.Playground65()
asm=p65.assemble(code)
p65.until_brk("BIN2BCD")
for l in asm:
print(l)
print("VAL: " + p65.dump("RES_BCD", 3))
print("RES_BCD: " + p65.dump("RES_BCD", 4))
print("RES_ATASCII: " + p65.dump("RES_ATASCII", 8))
Que asembla el código y lo ejecuta hasta llegar al BRK y luego me imprime el resultado en pantalla, es lo mas rápido que tengo para probar código 6502, lo adjunto.