Autor Tema: Dudas en Ensamblador  (Leído 118752 veces)

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 11304
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Dudas en Ensamblador
« Respuesta #270 en: Julio 23, 2015, 23:19:36 »
Parece bastante compacto.

Yo al principio intenté optimizar lo más que podía pero inevitablemente no puedo dejar de pensar en "usos genericos" y siempre termino agregando cosas que quitan optimización pero permite un uso más general.

Así que ya metí tablas para colores, punteros, expandido x, y, color, límite de espacio de movimiento, librería para leer joystick, librería para sprites, etc... siempre termino liandome :P

Así va mas o menos el invento (con el joy2 se puede mover por "toda" la pantalla)

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 11304
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Dudas en Ensamblador
« Respuesta #271 en: Julio 23, 2015, 23:40:20 »
Lo único raro hasta ahora es que al ir para arriba va más rápido de lo normal... :?

Maniako

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 1013
  • SYS 8*4096
    • Ver Perfil
Re:Dudas en Ensamblador
« Respuesta #272 en: Julio 23, 2015, 23:49:20 »
Cuantos sprites en pantalla XD.

Si que es cierto que sube al doble de velocidad  :o
Cuelga el código a ver qué es.
LDA #$50
STA $0400
RTS
Lloré cuando conseguí hacer esto con el monitor del FC1.

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 11304
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Dudas en Ensamblador
« Respuesta #273 en: Julio 24, 2015, 00:36:38 »
Esta es la subrutina que va para arriba:

Código: [Seleccionar]
joy_up:
ldx #$00 ; seleccionar el sprite del personaje

lda #$40 ; validar que no supere límite asignado
cmp SPRITES_Y, x
bcs joy_up_end

lda SPRITES_Y, x ; decrementar coordenada Y
clc
sbc #$01
sta SPRITES_Y, x
joy_up_end:
rts

Pensé que podría tratarse del CLC pero lo cambié a SEI y es lo mismo...

riq

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 567
    • Ver Perfil
    • From the C64 until today, a developer's perspective
Re:Dudas en Ensamblador
« Respuesta #274 en: Julio 24, 2015, 01:19:08 »
Cambialo por SEC (no SEI).

Mejor aún... hace:

Código: [Seleccionar]
; Usa "dec", en vez de "sbc #$01"
        dec SPRITES_Y,x

; y borra todo este codigo
        lda SPRITES_Y, x ; decrementar coordenada Y
clc
sbc #$01
sta SPRITES_Y, x
« última modificación: Julio 24, 2015, 01:21:09 por riq »

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 11304
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Dudas en Ensamblador
« Respuesta #275 en: Julio 24, 2015, 01:58:20 »
:O

Qué manera de quitar código :D

Para incrementar un sprite por más de 1 pixel había pensado en hacer un loop, asi puedo ir validando pixel a pixel que no supere ciertos rangos.

pastbytes

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 534
  • SYS 0
    • Ver Perfil
Re:Dudas en Ensamblador
« Respuesta #276 en: Julio 24, 2015, 02:14:16 »
Todo esto esta muy bien como experimento, pero en la vida real uno no siempre avanza un sprite 1 punto a la vez, los juegos se hacen sincronizados con los 50hz de la pantalla, no se dibuja cada paso intermedio sino que cuando se va a mostrar la pantalla se dibuja todo donde debe aparecer. Por lo tanto las coordenadas de los sprites se almacenan en "variables" propias, no en los registros del VIC, y logicamente las coordenadas X usan 9 bits (dos bytes por cada sprite, o un byte por sprite mas otro byte para los MSB de los 8 sprites, tal como usa el VIC). Si tenemos un Pacman y el sprite tiene que salir por un lado y entrar por el otro, o si tenemos un juego donde el personaje entra en una puerta y sale en otro lado de la pantalla, cruzando la barrera de los 255 puntos, no podemos hacer un bucle para avanzar de una coordenada a otra solo para no complicarse la vida con coordenadas de 9 bits, ya que no sobra tiempo de proceso para eso.

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 11304
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Dudas en Ensamblador
« Respuesta #277 en: Julio 24, 2015, 02:16:36 »
Totalmente de acuerdo. Asi lo estoy haciendo yo.

Lo que decía es que si quiero incrementar de a 4 (por ejemplo), puedo hacer un pequeño loop en donde se incrementa de a 1 y a la vez se valida que no supere ciertos limites, ya sea una coordenada o un muro.

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 11304
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Dudas en Ensamblador
« Respuesta #278 en: Julio 24, 2015, 02:25:39 »
Hice dos tablas, una es SPRITES_X_LO y la otra SPRITES_X_HI, donde voy actualizando las coordenadas y luego al final en un bucle actualizo todos los sprites con todos sus atributos, color, x, y, puntero, ampliaciones, etc.
Es optimizable obviamente pero para hacer algo genérico creo que está bien.

pastbytes

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 534
  • SYS 0
    • Ver Perfil
Re:Dudas en Ensamblador
« Respuesta #279 en: Julio 24, 2015, 02:29:54 »
Es suma de numeros de 9 bits, se suma 4 y se chequea carry para saber si el resultado es mayor a 255, no hace falta hacer eso 4 veces cuando se puede hacer el mismo codigo solo una vez. El valor de carry es lo que va al bit 9 de la coordenada del sprite. En algun momento va a haber que enfrentar el problema, muchas cosas requieren hacer operaciones matematicas con mas de 8 bits, por ejemplo el puntaje de un juego.

Maniako

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 1013
  • SYS 8*4096
    • Ver Perfil
Re:Dudas en Ensamblador
« Respuesta #280 en: Julio 24, 2015, 08:25:36 »
Entonces lo mejor es usar coordenadas de 0 a 255 pero moviendo dos pixels como recomendaron algunos posts atrás.
Si el numero es positivo <128 MSB off, si es negativo >127 MSB on.

LDA #$50
STA $0400
RTS
Lloré cuando conseguí hacer esto con el monitor del FC1.

pastbytes

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 534
  • SYS 0
    • Ver Perfil
Re:Dudas en Ensamblador
« Respuesta #281 en: Julio 24, 2015, 09:32:10 »
Es una solucion posible, pero lo ideal es hacer una rutina donde se le pase como parametros que sprite se quiere mover, y un byte conteniendo la distancia a mover, expresada como un numero con signo, lo que permitiria con la misma rutina mover un sprite en la coordenada X un numero de puntos arbitrario entre -128 y 127. Despues se podria implementar de forma separada una rutina que haga el chequeo de limites para corregir las coordenadas si el numero dio negativo o excedio los 344 puntos que me parece que es el maximo permitido por el VIC.
Pero el codigo no es mucho mas complejo que lo que ya se esta haciendo, por ejemplo si el sprite esta en la coordenada 250 y queremos avanzar 10 puntos a la derecha, se sumaria 250+10, esto daria como resultado 260, que excede el valor 255, representado en binario 260 = 100000100, que es un valor de 9 bits, el bit 8 (el noveno) queda en carry, los otros 8 bits quedan como resultado, que en decimal seria 00000100 = 4. El bit 8, que queda en carry despues de la suma, vale 256 (2^8), por lo que el resultado de la suma es justamente 256 + 4 = 260. Ese valor que queda en carry debemos colocarlo en el bit mas significativo de la coordenada X de ese sprite para que no se pierda, y el resultado (el valor 4) directamente en el registro de coordenada X del sprite.
En definitiva, el sprite antes tenia en X el valor 250, representado como 250 en la coordenada X y 0 en el MSB de la coordenada X, y luego de sumarle 10, pasaria a tener el valor 4 en X, y 1 en el MSB de la coordenada X. No es una cosa rara, simplemente es un numero de 9 bits, y se coloca el bit 8 de cada sprite en un unico registro, pero siempre tenemos que tomarlo como un numero de 9 bits al que se le puede sumar o restar cualquier numero. Hay que tener en cuenta que la suma de dos numeros de 8 bits puede dar como maximo un resultado de 9 bits, 255+255 = 510 = 1 11111110 en binario, esto es, carry = 1, y resultado igual a 11111110 = 254. No es mas que un numero de 9 (o 16 bits si se quiere redondear a bytes enteros) dividido en dos partes, pero el bit 8 siempre vale 256, en el ejemplo, 256+254 = 510.
Para restar coordenadas ya es un poco mas complejo, pero el codigo no es mucho mas largo, solo hay que pensarlo un poco mas.

Maniako

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 1013
  • SYS 8*4096
    • Ver Perfil
Re:Dudas en Ensamblador
« Respuesta #282 en: Julio 24, 2015, 11:19:29 »
Para restar solo hay que activar el Acarreo antes de la operación, si sigue activo no hay desbordamiento.
Si se desactiva, hay desbordamiento.

¿A esto te refieres?.

Lo del MSB (Most Significant Byte) lo entiendo. La cosa está en encontrar una manera aún mas simple , casi mecánica de hacer mover sprites (esto es fácil) activando o desctivando el MSB (ya es otro cantar) sin mucho código. Aunque no sé como aún.

Trabajare en ello este fin de semana, algo tengo pensado y solo falta comprobar si se puede pasar al mundo real.
 
Eso es lo que me encantaba de programar, una vez funciona lo que buscabas, ¿como lo hago más pequeño o simple? .
LDA #$50
STA $0400
RTS
Lloré cuando conseguí hacer esto con el monitor del FC1.

Maniako

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 1013
  • SYS 8*4096
    • Ver Perfil
Re:Dudas en Ensamblador
« Respuesta #283 en: Julio 26, 2015, 16:46:30 »
Bueno.
Aquí está el primer borrador de lo extraido de las enseñanzas de Pastbytes.

Solo manejo un sprite pero basta para comprobar el funcionamiento de la rutina.
Esta muy comentado todo, pero si necesitais alguna aclaración no hay problema.
No estaré al nivel de algunos cuando se explican (de 10) pero lo intentaré  ;)

Código: [Seleccionar]
                ;CMB prg studio
; 10 SYS (4096)

*=$801

        BYTE    $0E, $08, $0A, $00, $9E, $20, $28,  $34, $30, $39, $36, $29, $00, $00, $00

ciapra=$DC00    ; Joy2
msb=$D010       ;MSB >255
posprites=$D000   ;Coordenadas sprites D000-D00F
sprena=$D015     ;Sprites visibles o no
Posmemspr=$07f8  ;64*x Posicion memoria sprites 2040
temporal =$4000

*=$1000
       
;Conectando sprites:
        lda #255
        sta $d015       ;Conecto sprites
        ldy #00
loopsa  sta 2040,y        ;Pos mem sprite 0 2040-2047 sprite 0 al 7
        iny
        cpy #08
        bne loopsa

       
        ldy #00
        ldx #00
loopsb  lda corspritesx,x            ;Leo coordenadas sprites (solo el 0 para las pruebas)
        sta posprites,y     ;Posiciones coord X
        iny
        iny
        inx
        cpx #8
        bne loopsb

        ldy #00
        ldx #00
loopsc  lda corspritesy,x
        sta posprites+1,y
        iny
        iny
        inx
        cpx #8
        bne loopsc
        lda #00
        sta msb
       
;Empieza el programa en si------------------------------------------------------
inicio 
        lda ciapra              ;Joy2 en registro Y
        sec                     ;Activar CARRY. Necesario antes de restar.
        sbc #111                ;Resto 111 para que pueda usar los sumadores de movimiento
        tay                     ;Y=Acu. El registro Y leera el valor a sumar de la coordenada X del sprite
        ldx #$00                ;registro X .El valor del sprite a mover 0-7.
        lda corspritesx,x        ;Lectura de cordenadas X
        clc                     ;CARRY a 0 para la suma
        adc direccion,y         ;Sumar el valor de la dirección a la coordenada X
        sta temporal            ;Guardo nuevo valor coordenada X
        bcs test2               ;Si está el carry activado , posible MSB der...
       
;CARRY desactivado Posible MSB izq
test1   clc                     ;Carry a cero
        lda direccion,y         ;Lee el sumador (direccion)
        bmi msbonoff            ;Si es negativo (fd) pasa a rotar el bit MSB
        jmp cont                ;Si no, a seguir con el programa.

;CARRY activado Posible MSBder
test2   clc                     ;Carry a 0
        lda direccion,y         ;Lee el sumador (direccion)
        bpl msbonoff            ;Si es positivo (03) pasa a rotar el bit MSB
        jmp cont                ;Si no, a seguir con el programa

msbonoff
        lda msb                 ;Actual valor de MSB al ACU
        EOR valbmsb,x            ;Activar o desactivar el bit correspondiente
        sta msb

cont    lda temporal            ;Recupero el ACU
        sta posprites,x          ;Muevo sprite coordenada X
        sta corspritesx,x       ;Guardo coordenada actualizada

;Bucle de freno------------------------------------------------------------
        ldx #$ff
bucle1  ldy #$10
bucle2  dey
        bne bucle2
        dex
        bne bucle1
;Fin bucle de freno--------------------------------------------------------
        jmp inicio

;Fin del programa---------------------------------------------------------------
*=$3000
;Las 8 coordenadas de los sprites almacenadas aqui
corspritesx byte $f0,$f0,$f0,$f0,$f0,$f0,$f0,$f0
corspritesy byte $50,$60,$70,$80,$90,$a0,$b0,$c0
valbmsb byte $01,$02,$04,$08,$10,$20,$40,$80 ;Byte MSB a conectar o desconectar segun se necesite

;Joy Arriba=126- ABAJO=125- DERECHA=119 - IZQUIERDA=123 - DISPARO=111
;disparo 111-111=0
;DER 119-111=8
;IZQ 123-111=12
;ABA 125-111=14
;ARR 126-111=15
;              Dis                             der             izq     aba arr nada
direccion byte $00,$00,$00,$00,$00,$00,$00,$00,$03,$00,$00,$00,$fd,$00,$00,$00,$00,$00,$00,$00
;               0   1   2   3   4   5   6   7   8   9   10  11  12  13  15  15  16  17  18  19   
;Puedes borrar arriba y abajo para las pruebas.

;Intento de explicar su funcionamiento:

;Uso el valor directo del joystick para ahorrarme los comparadores de direccón.
;Disparo=111. Derecha=119. Izquierda=123. Abajo=125. Arriba=126. Nada=127
;Le resto 111 que es el mínimo (valor del disparo aunque no lo uso) y me da la dirección
;donde leer el valor a sumar para mover el sprite. Si pulsais disparo el funcionamiento puede
;volverse inestable al leer en cualquier lado de la memoria (valor aleatorio)

;Tened en cuenta que cuando sumas valores, al llegar a 255 y volver a sumar, se desborda el byte y
;este vuelve a su
;"inicio"" activando el flag CARRY. De esto me aprovecho para tratar de acortar el programa.

;Si A=255 y le sumo 1, da como resultado un 0 con el CARRY activado.
;Si le sumo a 255 (coordenada X actual) un 3, da 2 con CARRY activado.
;Luego solo comparo si el valor que se ha sumado a la coordenada es de signo POSITIVO
;y si lo es, activo el MSB

;Para izquierda casi lo mismo pero un poco mas lioso . Si le sumo a 3(coordenada actual) el valor 253,
;da como resultado 00 con carry activado (lo cual indica que no hemos cruzado al otro lado)

;En cambio, si a 2 (coordenada actual)le sumo 253, da como resultado 255 Con CARRY desactivado y aqui
;está el meollo de la cuestión. Esta vez si que hemos cruzado al otro lado y hay que activar
;el MSB del sprite en cuestión.
;Cuando no desborda, compruebo si el valor sumado es de signo NEGATIVO y si es así, cambio el MSB
;Es un poco lioso , lo se. Pero muy útil cuando se domina.

;Ocupo algo mas de memoria a base de coordenadas, pero con esto se consigue un programa
;que se ejecuta mas rápido (o eso creo) al ir eliminando comparadores.

;Este es el borrador, ¿se puede acortar aun mas?. Lo intentare XD.

;Tabla para tratar de aclarar la resta de las coordenadas:
;Coordenadas X       SUM
;            0    +  253 = 253   CARRY descativado
;            1    +  253 = 254   CARRY desactivado
;            2    +  253 = 255   CARRY desactivado
;            3    +  253 = 00    CARRY activado
;            4    +  253 = 01    CARRY activado
;            .........
;            251  +  253 = 248   CARRy activado
;            252  +  253 = 249   CARRY activado
;            253  +  253 = 250   CARRY activado   
;            254  +  253 = 251   CARRY activado
;            255  +  253 = 252   CARRY activado
;
; En movimientos decrecientes (izquierda), el flag CARRy siempre se activa
;pero no cruzamos al otro lado .
;Cuando no se activa, es cuando cruzamos al otro lado y hay que tocar al MSB del sprite en cuestión

;Gracias a PASTBYTES por sus aclaraciones y orientaciones. 
« última modificación: Julio 26, 2015, 17:31:19 por Maniako »
LDA #$50
STA $0400
RTS
Lloré cuando conseguí hacer esto con el monitor del FC1.

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 11304
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Dudas en Ensamblador
« Respuesta #284 en: Julio 27, 2015, 03:45:10 »
No está mal lo de tener valores negativos. Por ahora no lo voy a probar pero me imagino que así debería ser.

Llegado el momento miraré tu código.