Commodore manía

Commodore 64 => Desarrollo => Ensamblador => Mensaje iniciado por: riq en Julio 07, 2015, 23:14:51

Título: Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 07, 2015, 23:14:51
¡Hola programadores!

Esto no pretende ser un curso de assembler, ni nada parecido.
Solo quiero compartir con Uds. las cosas que voy aprendiendo mientras desarrollo un jueguito. Nada de lo que les voy a contar es nuevo... todo respecto a la c64 ya esta descubierto y bien detallado en codebase64 y otros sitios. De hecho, es de ahí de donde yo aprendo casi todo de la c64.

¿Entonces por qué hago esto si ya esta todo descubierto? Bueno, porque no todo lo que esta en codebase64 se entiende facilmente. Creo que varios artículos presuponen que uno sabe ciertas cosas, y cuesta bastante seguirlos. Y además porque tengo ganas de hacerlo :)

Yendo al grano, mi primer aprendizaje es...

Cómo hacer un IRQ estable

Si alguna vez trataron de hacer un "raster bar", o un simple scroll fino usando IRQ, habrán notado que la primer linea del raster hace "flicker"... es como que se corre a veces un poco hacia la derecha, o la izquierda y no se sabe bien porque.

Lo que aprendí estos días, es saber porqué pasa eso, y como prevenirlo y de esa manera lograr efectos que se vean bien.

Así es como se ve la intro del jueguito que estoy haciendo:
(https://lh3.googleusercontent.com/-RvjtDMhKTq8/VZwfNp02USI/AAAAAAABTPQ/7Gg3Qc9FoSY/s640/the-race-aprendiendo.png)

Basicamente tiene 4 IRQs (Código https://github.com/ricardoquesada/c64-the-race/blob/ec5f2f6b6ec8e1b4c4ad32ca95834af1398aead2/src/intro.s#L108 (https://github.com/ricardoquesada/c64-the-race/blob/ec5f2f6b6ec8e1b4c4ad32ca95834af1398aead2/src/intro.s#L108) )

irq1: Pone una barrita violeta. Pone color gris de fondo. Comienza el scroll fino de arriba.
irq2: Pone una barrita violeta. Cambia los colores a negro. Termina el scroll fino.
irq3: Comienza el scroll fino de abajo y pone color gris de fondo.
irq4: Termina con el scroll fino y pone los colores a negro nuevamente.

Parece sencillo, pero para poner las barritas violetas me costó una eternidad.

El tema es que cuando uno esta dentro de una IRQ, el "raster beam" (o haz de luz... no se como se traduce) se sigue moviendo, entonces hay que cambiar los colores en los momentos justos.

(http://static1.squarespace.com/static/511651d6e4b0a31c035e30aa/t/5178e819e4b0bf1bde30ed23/1366878234203/dustlayer.com-screen-raster-cycles.png?format=1500w)

( Para saber bien qué es el raster y demás recomiendo leer este articulo: http://dustlayer.com/vic-ii/2013/4/25/vic-ii-for-beginners-beyond-the-screen-rasters-cycle )

Para simplificar las cosas, vamos a asumir que tenemos una c64 PAL (no NTSC).
Del gráfico se puede ver que el raster para hacer una linea entera tarda 63 ciclos de CPU. Y lo más interesante de todo que hay momentos en los que el raster no es visible.
Y es justamente en esos momentos cuando uno tiene que cambiar el color del fondo de pantalla... porque sino el color aparece cortado.

Ejemplo: Aca la barra violeta aparece "cortada"...y es que cambié el color mientras el "raster beam" estaba por la mitad.
(https://lh3.googleusercontent.com/-HnEeXrKFuww/VZwrBohX3kI/AAAAAAABTQI/HxItIECi78c/s800/the-race-raster-not-aligned.png)

Entonces la teoría es sencilla: cambiar el color cuando el "raster beam" esta invisible.

Ciclos, interrupciones y demás:

Cuando uno instala una interrupción raster, uno no puede saber con exactitud cuantos ciclos fueron ejecutados por la siguiente razón:
Supongamos que tengo mi IRQ instalado, y en estoy ejecutando en mi ciclo principal un código que hace algo.
Justo en ese momento se prende mi IRQ ("raster beam" esta en la posición deseada).
El tema es que como la CPU puede estar ejecutando una instrucción, hay que dejar que se termine de ejecutar esa instrucción para que se llama a mi IRQ. Y eso consume ciclos.
Y como hay instrucciones de hasta 7 ciclos, cuando se llama a mi IRQ yo no se cuantos ciclos entre 0 y 7 se ejecutaron de más.

Y es exactamente por este motivo que a veces los raster bars o efectos hacen "flicker"... ya que a veces estan corridos 0, 1, ... y hasta 7 ciclos hacia la "derecha".

Lo que aprendí es que hay varias técnicas para hacer el raster estable: http://codebase64.org/doku.php?id=base:making_stable_raster_routines (http://codebase64.org/doku.php?id=base:making_stable_raster_routines)
Pero la que yo estoy usando en la intro es la "doble IRQ": Basicamente uso una IRQ para lograr que la CPU esta ejecutando un NOP cuando se produzca la siguiente IRQ. Eso se logra poniendo varios NOPs dentro de la primera IRQ, y luego nunca volver (no usar "rti"). De esa manera me garantizo que solo va a haber entre 0 y 1 ciclos de diferencia (y no hasta 7 como antes)... y luego ese ciclo de "sobra" se arregla con una comparación.
Los detalles están aca: http://codebase64.org/doku.php?id=base:stable_raster_routine (http://codebase64.org/doku.php?id=base:stable_raster_routine) Si alguien no entiende algo de la técnica "Doble IRQ" con gusto lo explico.

Y eso... basicamente para poner esas 2 barras violetas, tuve que aprender a usar la "doble IRQ" y contar ciclos :)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 08, 2015, 00:24:03
En su momento jugué con el raster pero no a ese nivel.
Muchas gracias por colgar el código. Ahora toca estudiarlo. ;)

A ver si me animo a colgar algunas rutinas útiles para noveles como yo.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 08, 2015, 01:07:02
Este hilo va a ser MUY interesante :)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 08, 2015, 04:21:01
Las famosas "bad lines"

¿Qué carajo son las "bad lines"?
Algo que molesta mucho, pero al parecer se pueden hacer trucos muy buenos abusando de estas. Pero vamos a lo que nos importa:

Antes dije que el raster beam tardaba 63 ciclos en recorrer una linea de pantalla horizontalmente. Y eso sigue siendo verdad... pero cada 8 lineas, el VIC se consume como 40 ciclos para leer los punteros a los caracteres de esa linea. O sea que no siempre tenemos 63 ciclos por "raster line".
El algoritmo es:
Código: [Seleccionar]
// pseudo code
// puede que tenga que compara con 7 o 5 en vez de con 0... no hice muchas pruebas aún.
if (($d012 & scroll_fino_vertical) ==0)
   tengo_23_ciclos();
else
   tengo_63_ciclos();

¿y por qué molestan las Bad Lines? Basicamente si yo quiero cambiar el color de fondo en cada "raster line", lo que tengo que hacer es:

1) cambiar color
2) consumir los ciclos necesarios hasta llegar a 63
3) comparar si es el último color
4) si no, volver a 1)

Pero eso no funciona con las bad lines, porque cada 8 lines, solo tengo alrededor de 20 ciclos. Esto es lo que pasa:

(https://lh3.googleusercontent.com/-Bv21kZ6_bSE/VZyEyfxooQI/AAAAAAABTQw/r6sBpetjF24/s640/bad-lines.png)

Como pueden ver, cada 8 lineas, se desfasa todo porque estoy consumiendo 63 ciclos en vez de ~20.
Intenté comparar si estaba en una bad-line, y consumir solo ~20 ciclos... pero no me daban los ciclos ya que cada instrucción consume ciclos, y hacer todo ese calculo era muy caro.

Así que probé una rutinita distinta. Algo asi como esto:
Código: [Seleccionar]
        ; los ciclos consumidos estan a la derecha
; raster bars
ldx #0
: lda $d012 ; +4
cmp $d012 ; +4
beq *-3 ; +2
; wait for new raster line, change color then
lda raster_colors,x ; +4
sta $d021 ; +4
inx
cmp #$ff
bne :- ; +3

Y casi funciona bien...
(https://lh3.googleusercontent.com/-uvb40UWzEE8/VZyFDTKDywI/AAAAAAABTRA/-r7lzqyc6iw/s400/bad-lines2.png)

Pero si prestan atención cada 8 lineas se repite una linea (las malditas bad lines). Mucho mejor que el test anterior, pero molesto aún.

Todavía no se como solucionar este problema... lo que hice, es que en vez de modificar el color en cada linea, lo modifica cada 2, y así esta todo uniforme.

El código para dibujar cada 2 lineas es muy similar al anterior:
Código: [Seleccionar]
; raster bars
ldx #0
: lda $d012 ; +4
clc ; +2
adc #$02 ; +2
cmp $d012 ; +4
bne *-3 ; +2
; wait for new raster line, change color then
lda raster_colors,x ; +4
sta $d021 ; +4
inx ; +2
cmp #$ff ; +2
bne :- ; +3

El resultado final en la intro es algo así:
(https://lh3.googleusercontent.com/-KH5N3LYRLpI/VZyIeNJtRhI/AAAAAAABTRM/v2ep9fVOluk/s400/the-race-intro-colors.png)

La última versión del PRG siempre la van a poder bajar de aca: https://www.dropbox.com/s/x2grp14do6w4jyb/therace.prg?dl=0 (https://www.dropbox.com/s/x2grp14do6w4jyb/therace.prg?dl=0)

Y el código fuente siempre va a estar aca: https://github.com/ricardoquesada/c64-the-race (https://github.com/ricardoquesada/c64-the-race)

Muy buena información sobre las "bad lines" se puede encontrar aca: http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt (http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 08, 2015, 04:52:21
No tenía ni pero ni idea de esto...
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 08, 2015, 07:00:53
Desenrollando bucles
Ja ja... la solución era mucho más fácil de lo que creía :-)

El algoritmo que había presentado era el correcto, pero había que desenrollar el bucle. ¿Qué significa eso?
Código: [Seleccionar]
// pseudo código. Código enrollado:
for (int i=0;i<4;i++)
   inc $d020
Código: [Seleccionar]
; Mismo algoritmo pero con el bucle desenrollado
; me ahorro las comparaciones. Ocupa más espacio, pero es más rápido.
inc $d020
inc $d020
inc $d020
inc $d020

Eso hace que uno se ahorra las comparaciones (recordemos que solo tengo ~20 ciclos), y si bien el código es más feo y ocupa más bytes, es más rápido.

Al final el código me quedó así. Son 3 "repeats" anidados:
Código: [Seleccionar]
; 9 lines per char
.repeat 9
; 7 "buenas" lineas: Tengo que consumir 63 ciclos
.repeat 7
inx ; +2
lda raster_colors,x ; +4
sta $d021 ; +4
.repeat 25
nop ; +2 * 30
.endrepeat
bit $00 ; +3 = 63 ciclos
.endrepeat
; 1 "linea mala": Tengo que consumir 20 ciclos
inx ; +2
lda raster_colors,x ; +4
sta $d021 ; +4
.repeat 5
nop ; +2 * 5 = 20 ciclos
.endrepeat
.endrepeat

Gracias al poder de las macros, el código no es tan horrible y el resultado visual el que quería: Un color por linea sin que haya lineas duplicadas y sin "desfasajes":
(https://lh3.googleusercontent.com/-Yh_hhNNb0e4/VZyrte5Hq-I/AAAAAAABTRg/b-LIXI41gy0/s400/unrolling-loop.png)

Creo recordar que en este video hablaban que había que desenrollar todo para tener velocidad en la c64: https://www.youtube.com/watch?v=po9IY5Kf0Mo (https://www.youtube.com/watch?v=po9IY5Kf0Mo)

Aclaración: Hacer "raster bars" en el borde ($d020) es más fácil que en el fondo ($d021) ya que no se nota el desfasaje por las "bad lines"... el desfasaje esta, pero no se nota.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 08, 2015, 08:50:39
Me mata no saber inglés  :-[

Pero lo que explicas es "semicomprensible" para mi. Esta claro que tengo que practicar con ello para poder entenderlo del todo.
 
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 08, 2015, 08:58:45
@maniako: cualquier duda que tengas, preguntá nomás.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: pastbytes en Julio 08, 2015, 11:13:44
Supongo que eso se podria traducir como "desenrrollando bucles", y deduzco que es una manera de ver al bucle como un rollo de papel que tiene tantas capas como iteraciones tiene el bucle, al desenrrollarlo queda un codigo mas largo con lo mismo repetido varias veces.
Y si, cuando se necesita velocidad o tiempos muy criticos o predecibles, se suele escribir el codigo repetido varias veces aunque los cambios entre una y otra repeticion sean minimos, por lo general solo parametros distintos.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 08, 2015, 18:07:44
@pastbytes:
gracias. corregido.
Disculpen si a veces uso algunas palabras en ingles, pero es que muchas veces no se cual es la palabra en español. No se bien porque, pero por alguna razón en Argentina se usan muchas palabras del ingles en el mundo de la programación, sumado que al comienzo (digamos hace 20 años) los libros de programación que se conseguian en Argentina eran todos en ingles.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 13, 2015, 08:48:29
Cargando un archivo Koala

Se pueden usar varios modos gráficos en la Commodore 64: http://www.studiostyle.sk/dmagic/gallery/gfxmodes.htm (http://www.studiostyle.sk/dmagic/gallery/gfxmodes.htm)
pero yo solo se usar los oficiales: o sea el "bitmap alta resolución" y el "bitmap multicolor".

Y parece que en la C64 había un programa de dibujo llamado Koala Paint que generaba un formato bastante sencillo para los archivos que generaba.

Basicamente primero guardaba la información del bitmap, luego la definición de los colores %01, %10, luego del color %11, y luego el color del fondo (%00).

- bitmap (160x200/4) = 8000 bytes. Son 2 bits por color. Y se define por "celdas" de 8x8.
- color %01 y %10: (40x25) = 1000 bytes
- color %11: (40x25) = 1000 bytes
- color %00: 1 byte.

Más información sobre este modo aca: http://dustlayer.com/vic-ii/2013/4/26/vic-ii-for-beginners-screen-modes-cheaper-by-the-dozen

La rutinita para poner los colores en su lugar es esta, bastante sencilla:

Código: [Seleccionar]
;--------------------------------------------------------------------------
; init_koala_colors(void)
;--------------------------------------------------------------------------
; Args: -
; puts the koala colors in the correct address
; Assumes that bimap data was loaded in the correct position
;--------------------------------------------------------------------------
.proc init_koala_colors
KOALA_BITMAP_DATA = __GFX_LOAD__
KOALA_CHARMEM_DATA = KOALA_BITMAP_DATA + $1f40
KOALA_COLORMEM_DATA = KOALA_BITMAP_DATA + $2328
KOALA_BACKGROUND_DATA = KOALA_BITMAP_DATA + $2710

; Koala format
; bitmap:           $0000 - $1f3f = $1f40 ( 8000) bytes
; color %01 - %10:  $1f40 - $2327 = $03e8 ( 1000) bytes
; color %11:        $2328 - $270f = $03e8 ( 1000) bytes
; color %00:        $2710         =     1 (    1) byte
; total:                    $2710 (10001) bytes

ldx #$00
@loop:
; $0400: colors %01, %10
lda KOALA_CHARMEM_DATA,x
sta $0400,x
lda KOALA_CHARMEM_DATA+$0100,x
sta $0400+$0100,x
lda KOALA_CHARMEM_DATA+$0200,x
sta $0400+$0200,x
lda KOALA_CHARMEM_DATA+$02e8,x
sta $0400+$02e8,x

; $d800: color %11
lda KOALA_COLORMEM_DATA,x
sta $d800,x
lda KOALA_COLORMEM_DATA+$0100,x
sta $d800+$100,x
lda KOALA_COLORMEM_DATA+$0200,x
sta $d800+$200,x
lda KOALA_COLORMEM_DATA+$02e8,x
sta $d800+$02e8,x

inx
bne @loop

lda KOALA_BACKGROUND_DATA
sta $d021

rts
.endproc

El programa que estoy usando para generar imagenes Koalas es Timanthes: http://csdb.dk/release/?id=75871 Esta bueno, pero no es trivial como generar koalas validos.

En algún momento me gustaría aprender a generar y cargar imágenes avanzadas como la FLI y demás... pero sera en el futuro.

Mientras tanto estoy contento con el modo "160x200x16".

(https://lh3.googleusercontent.com/-T5EoWKFRW5U/VaNbp-FTiVI/AAAAAAABTV0/2L7yt4vX8p4/s400-Ic42/Screen%252520Shot%2525202015-07-12%252520at%25252011.21.06%252520PM.png)
Así va quedando la intro del jueguito.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: R. INTERNATIONAL en Julio 17, 2015, 13:34:37
  El tema del Raster es algo que desconozco y que tengo que aprender a medio plazo si o si,..por desgracia ahora estoy incomunicado por un virus y muchos de los enlaces del hilo no puedo verlos,..pero el hilo se le ve interesantisimo..

  Cuando tenga solucionado el problema prometo estudiarme el hilo porque aparte necesito por peles dominar ésta tecnica.

   Chao-
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 17, 2015, 21:54:13
Llevo ya dos semanas peleandome con este tema y esto es a lo que he llegado gracias a un libro en pdf.

Código: [Seleccionar]
;Escrito con CBM prg studio

; 10 SYS (4096)

*=$801

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

        sei        ;Stop IRQ's
        lda #27
        sta $D011 ;53265 Registro de contrl del VIC-II 00011011
        lda<inte  ;Guardando lobyte direccion del programa
        sta$0314  ;Desviando al programa hibyte
        lda>inte  ;Guardando hibyte direccion del programa
        sta$0315  ;Desviando al prorama lobyte     
        lda #127
        sta $DC0D ;56333 Registro control CIA 01111111
        lda#129
        sta $D01A ;53274 Registro mascara IRQ 10000001
        cli       ;Start IRQ's
        rts             ;Vuelta al basic
       
inte    LDA #$01
        STA $D019       ;Bandera de registro de IRQ. Activa bit 0 para comparacion de barrido
        LDX #$92        ;Altura del barrido para poner el negro
        LDY #$02 ;06    ;Color primera mitad pantalla   
        LDA $D012       ;Valor de barrido para comparar en IRQ
        BPL aa             ;Si es positivo...(<127)
        LDX #$32;01 32 justo empieza parte sup. pantalla    ;Altura de barrido para la primera pantalla
        LDY #$00        ;Color segunda mitad pantalla.
aa    STX $D012       ;Nuevo valor de barrido para comparar en IRQ.
        STY $D021       ;Color de fondo 0 o 2 segun sea.
        LDA $DC0D       ;Registro de control de la CIA 
        AND #$01        ;Bit interrupcion timer A.
        BEQ bb          ;Si no esta activado pasando
        JMP $EA31       ;Rutina ROM interrupt.
bb    JMP $FEBC       ;Continua con lo suyo.


Es lo mas sencillo que he llegado a comprender al 70%. Lo que hace Riq es de otro universo paralelo para mi  ;)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: R. INTERNATIONAL en Julio 17, 2015, 22:27:22
  Pues fijate para un Carnicero,...en cualquier caso lo importante es EL HIERRO!!! y luchar y luchar y aunque perezcamos en la batalla moriremos combatiendo!!,...ja,j,aj,aj,ja

  Tengo que probar todas estas rutinas,..buff se me acumula el trabajo, como siempre!!

   saludos.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 17, 2015, 22:28:44
@maniako: Va bien eso. Una pequeña optimización que podes hacer, es en vez de esperar que el raster llegue a cierta linea, le podes decir que el IRQ se llame cuando el raster este en una linea determinada:

Código: [Seleccionar]

; irq raster que se llame en la linea $80
lda #$80
sta $d012

; setear la irq
lda #<inter
sta $0314
lda #>inter
sta $0315

una cosa que me llamó la atención es que estas haciendo:

Código: [Seleccionar]
;
lda #127
sta $dc0d

... probablemente sea correcto y este perfecto. Pero yo no lo había visto antes dentro la rutina de IRQ. Pero ojo, yo tampoco tengo mucha experiencia en esto asi que como dije, probablemente este perfecto llamarla.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 17, 2015, 22:38:27
Riq, a buen profesional le preguntas  ;D ;D ;D

Buscaba una rutina comprensible y simple, sin paja y polvo para destriparla. Venia con un cargador en basic, abri el monitor del VICE y copié la rutina.

Como digo, no lo comprendo del todo y sigo dandole palos para ver por y para que es todo.

Esta rutina hace lo que comentas, pero si puedo hacerla mas simple mejor.

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 17, 2015, 22:41:27
  Pues fijate para un Carnicero,...en cualquier caso lo importante es EL HIERRO!!! y luchar y luchar y aunque perezcamos en la batalla moriremos combatiendo!!,...ja,j,aj,aj,ja

  Tengo que probar todas estas rutinas,..buff se me acumula el trabajo, como siempre!!

   saludos.

Me pasa igual. Solo tengo las noches para trastear y aprender. Por desgracia (o no), ser autodidacta consiste en encontrar las 1000 maneras diferentes de hacerlo mal para saber hacerlo bién.  ;)

Por eso creé el hilo de rutinas mas o menos útiles. Con rutinas sencillas se aprende y yo las necesito muuuuuy simples  ::)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 19, 2015, 05:57:48
La importancia de no saltar de página

La documentación del 6502/6510 dice que LDA $FFFF,x y STA $FFFF,x tardan 4 ciclos... salvo que se salta de página, y ahí tarda 5 ciclos.
( http://unusedino.de/ec64/technical/aay/c64/blda.htm )

La verdad que nunca le presté atención a ese detalle hasta hace unos días atras cuando noté que por alguna razón la "raster bar" no estaba sincronizada.

No entendia bien porque, hasta que me di cuenta que estaba haciendo el "salto de página" cuando accedia a esa memoria. Asi que lo único que tuve que hacer es poner los colores en la direccion para que haya salto de página.
El salto de página es algo así como:

Código: [Seleccionar]

*=$0800
    ldx #00
loop:
    lda colores,x
    sta $d800,x
    inx
    cpx #16
    bne loop

*=$5f8
colores:  .byte 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16

El color 8, salta de página... va la página $0500 a las $0600, y eso hace que esa operación tarde un ciclo más.

Respecto a esto, algo que aprendí a querer, son los segmentos del ca65... al principio me parecian que agregaban complejidad innecesaria, pero ahora que el proyecto se agrando, puedo mapear los segmentos a los lugares que necesito sin tener que cambiar el código. Asi es como se ven mis segmentos ahora, donde tengo en memoria 2 partes del juego: la pantalla del menu principal, y la pantalla del about
Código: [Seleccionar]
SEGMENTS {
    SIDMUSIC: load = RAM,      type = rw,  start = $1000, optional = yes, define = yes;

    #
    # About:
    #    GFX     $2000 - $2710 (Koala)
    #    CHARSET $4800 - $4fff
    #
    ABOUT_GFX:      load = RAM, type = rw,  start = $2000, optional = yes, define = yes;
    ABOUT_CHARSET:  load = RAM, type = rw,  start = $4800, optional = yes, define = yes;
    ABOUT_CODE:     load = RAM, type = rw,  start = $5000, optional = yes, define = yes;
    ABOUT_DATA:     load = RAM, type = rw,  start = $6000, optional = yes, define = yes;

    #
    # Main Screen:
    #    SCREEN  $8400 - $87FE
    #    CHARSET $8800 - $8FFF
    #
    MAIN_CODE:      load = RAM, type = rw,  start = $7000, optional = yes, define = yes;
    MAIN_SCREEN:    load = RAM, type = rw,  start = $8400, optional = yes, define = yes;
    MAIN_CHARSET:   load = RAM, type = rw,  start = $8800, optional = yes, define = yes;
}

de esta manera, si quiero cambiar la posición de algunos segmentos porque necesito usar la memoria de una manera diferente, solo tengo que editar un solo archivo en vez de editar varios.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 26, 2015, 18:16:58
Conversores de imagenes

Estuve usando Timanthes para convertir imágenes a formato Koala. Si bien el resultado estaba bien, Project One v0.5 es muy superior.
Project One no lo pude hacer andar en un Windows 8.1, pero me anduvo muy bien en una Mac con Wine instalado. El único truco es que hay que instalar gdiplus usando winetricks.
Y yo mucho más contento usando Wine que Windows ya que mi computadora principal es una Mac.

Asi me quedó el grafico luego de haberlo convertido con Project One:
(https://lh3.googleusercontent.com/-ffY6ZEI_p1c/VbUGNvmho5I/AAAAAAABTb4/3PtJxJx1gHk/s640-Ic42/Screen%252520Shot%2525202015-07-26%252520at%2525209.06.11%252520AM.png)

Project One tiene muchicismas más opciones para convertir imagenes y la el resultado es mucho mejor!

Downloads:
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 27, 2015, 00:21:50
Comparandola con la otra si, se ve mucho mejor. Mas colorida y ahora se ve el monociclo.

Tengo un block de notas que no deja de crecer con recomendaciones.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 27, 2015, 03:39:38
La imagen mejoró muchísimo! quizás tiene demasiado gris de fondo.

A ver que tal ese Project One
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Mode 2 en Julio 27, 2015, 10:40:02
Muchas gracias Riq por tan interesante aporte, soy cepecero (diría más bien que multisistemas en la actualidad) aunque me gustaría hacer algo para el C64 en un futuro.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 29, 2015, 19:01:12
Bancos de memoria: $1000 y $9000

Esto que voy a decir esta documentado en varios lados, pero yo por alguna razón me lo había prestado suficiente atención.

Como sabrán la C64 tiene 64k de RAM, pero el chip VIC solo puede ver 16k a la vez. Entonces para decirle al VIC que uso cierta parte de la memoria uno simplemente cambia el banco:

Por ejemplo, para usar el banco de $8000 - $BFFF se hace esto:

Código: [Seleccionar]
; Vic bank 2: $8000-$BFFF
lda $dd00
and #$fc
ora #1
sta $dd00

y eso hace que la pantalla, sprites y demas, que normalmente estan en el banco 0, ahora esten en el banco 2.

Pero si uno usa los bancos 0, 2 ($0000-$3FFFF y $8000-$BFFF) no se pueden usar la direcciones que estan entre $1000-$1FFF  y $9000-$9FFFF para poner sprites, graficos y charsets. Cuando le dicen al VIC que use esas direcciones, los lee de la ROM en vez de la RAM.

El jueguito va tomando forma... aún no hay jueguito, pero al menos ahora tiene un menu principal y un "choose rider".
https://www.dropbox.com/s/x2grp14do6w4jyb/therace.prg?dl=0
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 29, 2015, 20:33:22
Va tomando forma.

Me suena a Boulder Dash esa tipografía, ¿puede ser??

Sobre los bancos y lo de leer la ROM, ¿puede ser que haya algun truco para usar alguno de esos espacios? me suena algo el tema...
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 29, 2015, 20:43:52
Si, bien ahí. Son los fonts del Boulderdash... estoy tratando de darle un look muy retro al jueguito. Lo que quiero hacer es un juego que se parezca a los juegos del '82 / '83.
Quiero poner graficos y efectos muy muy básicos... Estoy un poco cansado de los jueguitos del iPhone / Android que dicen ser retros... entonces lo que quiero hacer es un juego "retro retro"... es decir, hacer un juego en una plataforma retro (la c64), y que el juego en si mismo sea retro para esa plataforma.

Entonces cuando alguien me diga "mira el super jueguito retro que tengo para el iPhone"... yo les voy a decir "Y mira el jueguito retro retro que hice yo para la c-64" :-)

Si, esos espacios se usan para poner código, o música... de hecho el espacio $1000 generalmente se usa para música... pero no los uses para poner nada que requiera que VIC los lea.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 30, 2015, 14:30:55
Vaya motivos para hacer un juego!! :D :P
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 30, 2015, 14:32:14
Si, bien ahí. Son los fonts del Boulderdash...
Es que soy un gran fan de ese juego.


estoy tratando de darle un look muy retro al jueguito. Lo que quiero hacer es un juego que se parezca a los juegos del '82 / '83.
A ver si lo consigues, los juegos de esa época tienen un sabor distinto.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 30, 2015, 15:59:02
... los juegos de esa época tienen un sabor distinto.

Ahora entiendo el porqué no conservais nada de esa época, OS LOS COMIAIS!!!  :o

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 30, 2015, 16:20:11
Capitán Literal al ataqueee! :-P
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 30, 2015, 16:42:32
Vaya motivos para hacer un juego!! :D :P

Ja. La idea del juego fue mutando mucho...  Desde hacer un juego de olimpiadas de monociclo par la PC, hasta a hacer el "muni race" en formato "retro retro" para la C64. Pero nada garantiza que es la idea final... quizas el mes que viene vuelva a cambiar de parecer :)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 30, 2015, 16:44:34
¿Porqué lo de "muni"?, mi cerebro está contaminado y al leer "muni" inmediatamente veo el diminutivo de Municipalidad...
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 30, 2015, 16:46:09
¿Porqué lo de "muni"?, mi cerebro está contaminado y al leer "muni" inmediatamente veo el diminutivo de Municipalidad...

muni = Mountain Unicycle... es como Mountain Bike, pero para monociclos.
Y es un deporte real... no es un invento mio :)

https://www.google.com/search?q=google+images&es_sm=91&source=lnms&tbm=isch&sa=X&ved=0CAcQ_AUoAWoVChMIoOaaoYyDxwIV0qSICh1d6Qq3&biw=1435&bih=778#tbm=isch&q=mountain+unicycle
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 30, 2015, 20:34:45
No tenía ni idea de este deporte!

En ese enlace he visto la foto que usaste, me parece que hay otras que se nota mejor que es un monociclo, por ejemplo esta:
(http://workinglife.org.au/wp-content/uploads/2013/02/unicycle.jpg)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 30, 2015, 21:48:56
gracias. es buena esa foto.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 30, 2015, 22:11:17
¿Mejor ahora?
(https://lh3.googleusercontent.com/-aUDoxnk5ez0/VbqEmBSLAEI/AAAAAAABTlQ/aF-XMyxj2tI/s400-Ic42/Screen%252520Shot%2525202015-07-30%252520at%2525201.09.24%252520PM.png)

Lo que me gustaba de la foto original, es que era yo el que estaba andado :-P
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 30, 2015, 22:16:51
Lo que me gustaba de la foto original, es que era yo el que estaba andado :-P
Lo sabía, mi 9º bit me decía que usaste esa foto era por eso! :D

Tampoco la descartes tan rapidamente!
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 30, 2015, 22:20:42
Viendo la foto original, tu conversión ha quedado muy parecida.

Bancos de memoria: $1000 y $9000

Pero si uno usa los bancos 0, 2 ($0000-$3FFFF y $8000-$BFFF) no se pueden usar la direcciones que estan entre $1000-$1FFF  y $9000-$9FFFF para poner sprites, graficos y charsets. Cuando le dicen al VIC que use esas direcciones, los lee de la ROM en vez de la RAM.



No lo sabia. Creia que tenia acceso a toda la RAM.
Estas cosas son las que me matan a la hora de tratar con mi pequeñin. Nunca lo he leido en ningún libro de los que tengo asi que, ¿como lo averiguas cuando tu programa falla antes de pegarte un tiro?.

Me falta aun mucha practica y leer mucha documentación.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 30, 2015, 23:01:34
No lo sabia. Creia que tenia acceso a toda la RAM.

Vos podes usar toda la RAM, los 64k.
Pero el VIC no puede ver la RAM que esta entre $1000-$1FFF y $9000-$9FFF.
O sea, vos podes poner código en esos lugares. Pero no pongas sprites, graficos y charsets.

Para más info leer este articulo: http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt
Ir a la sección 2.4.2
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Julio 30, 2015, 23:31:24
Parece ser un buen lugar para poner el código, no?
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 30, 2015, 23:32:03
Vos podes usar toda la RAM, los 64k.
Pero el VIC no puede ver la RAM que esta entre $1000-$1FFF y $9000-$9FFF.
O sea, vos podes poner código en esos lugares. Pero no pongas sprites, graficos y charsets.

Para más info leer este articulo: http://www.zimmers.net/cbmpics/cbm/c64/vic-ii.txt
Ir a la sección 2.4.2

Vaale. La memoria de color no se mueve selecciones el banco que selecciones , el VIC accede a 16k de cada página pero las zonas 0 y 2 contienen los carcteres en ROM . Creo que voy pilandolo , aunque la ROM CHAR no se mueve, el VIC no lo sabe y sigue saltandose ese hueco ¿no?.
 
Las zonas 1 y 3 son 100% aprovechables.

Me estoy releyendo los libros que tengo para ponerme al dia y en el GUIA DE REFERENCIA DEL COMMODORE 64 de Microelectronica y control comentan los mapas y los huecos.

Grácias por el fichero DOC.  Toda ayuda es poca  ;)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 30, 2015, 23:33:59
Parece ser un buen lugar para poner el código, no?

Nada que empleé el VIC debe ser puesto en esas zonas . Codigo , sin problemas o eso interpreto.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 31, 2015, 22:12:05
A mi me tiene frito el tema interrupciones.
Hay como 100 maneras diferentes para hacerlo, aunque este listado (que adjunto al post) para mi es el mas coherente y temendamente estable.
Riq, tu lo tienes dominado, pero a mi se me resiste. Emplearlas es fácil, pero comprender al 100% el por qué funciona aún se me escapa.

Con lo fácil que son las interrupciones en un Arduino ...  ::)
Te la dejo por si te sirve para el juego y por si puedes iluminarme un poco sobre este tema.

Código: [Seleccionar]

                             ; CBM prg Studio
; 10 SYS (4096)

*=$801

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

;Aparece el sprite 0 en las dos mitades de la pantalla, pero solo es por probar la rutina.

;Los valores de pantalla de rastreo en zona visible , van de 50 a 250.
;150 es el centro. 250+50=300  300/2=150 .

superior=50         ;Primera pantalla. La superior
inferior=150 ;150        ;Segunda pantalla. Inferior
                *=$1000
        lda #255
        sta 2040       ;Puntero sprite 0 en 255
        lda #1
        sta $d015       ;Sprite 0 activado
       

        sei         ; set interrupt disable flag
        ldy #$7f    ; $7f = %01111111
        sty $dc0d   ; Turn off CIAs Timer interrupts
        sty $dd0d   ; Turn off CIAs Timer interrupts
        lda $dc0d   ; cancel all CIA-IRQs in queue/unprocessed
        lda $dd0d   ; cancel all CIA-IRQs in queue/unprocessed
        lda #$01    ; Set Interrupt Request Mask...
        sta $d01a   ; ...we want IRQ by Rasterbeam
        lda #<irq   ; point IRQ Vector to our custom irq routine
        ldx #>irq
        sta $314    ; store in $314/$315
        stx $315   
        lda #superior    ; trigger first interrupt at row zero
        sta $d012
        lda $d011   ; Bit#0 of $d011 is basically...
        and #$7f    ; ...the 9th Bit for $d012
        sta $d011   ; we need to make sure it is set to zero
        cli         ; clear interrupt disable flag
        rts

irq     dec $d019 ; acknowledge IRQ
        lda $d012
        cmp #inferior
        beq rojo        ;Segunda mitad
        lda #0
        sta $d021        ;Color negro en pantalla
        lda #inferior
        sta $d012       ;Nuevo valor segnda pantalla
        lda #80
        sta $d000
        sta $d001
        jmp pasa

rojo    lda #2
        sta $d021        ;Color rojo en pantalla
        lda #superior
        sta $d012        ;nuevo valor primera mitad
        lda #200
        sta $d000
        sta $d001
pasa    jmp $ea31

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Agosto 01, 2015, 00:18:36
y por si puedes iluminarme un poco sobre este tema.

en concreto, ¿qué dudas tenes sobre las interrupciones?
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Agosto 01, 2015, 07:58:05
Como desviarlas no.
Es el por qué de como conseguir fluidez y estabilidad.
Veo muchas maneras de eliminar esos flicks que afean y dejar los cortes de cambio de color impecables, pero cada cual usa una manera distinta de manipular los registros del VIC para conseguirlo y eso me desorienta.

Usando las CIAS es sencillo conseguir que cada cierto tiempo se ejecute mi rutina, pero usando el RASTER para por ejemplo conseguir multiples SPRITES o diferentes modos graficos a la vez según donde esté la linea de barrido es mas lioso.
Cada cual usa técnicas que difieren unas de otras para conseguirlo.
Si por lo menos siguieran un patrón lo llegaria a comprender, pero hasta ahora solo coinciden en muy pocas cosas y contra mas rutinas leo, mas me confunden.


Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Agosto 01, 2015, 19:08:57
A mi me sirvió entender el porqué de la inestabilidad del raster para entender lo demás... así que empiezo por el principio:

¿por qué la IRQ del raster es inestable?

El barrido de la pantalla se hace unas 50 veces por segundo en PAL-B (la Commodore europea).
Y uno le puede decir a la commodore que te avise cuando empiece el barrido, y que te avise cuando el raster esta en cierta posición del barrido.

Supongamos que quiero que la interrupción me avise cuando el raster esta en la posición 50.
Entonces se hace lo tradicional de poner el vector $314 apuntando a donde queres, poner #50 en $d012, y demas.

Pero vas a ver que a veces sos llamado en el medio de la "scan line", o a veces al principio... como si fuera aleatorio.
Pero en verdad no es aleatorio, y sos llamado de acuerdo a lo siguiente:

a) Supongamos que el raster llega a la linea 50
b) La interrupción interrumpe lo que esta sucediendo en bucle principal
c) Para eso tiene que dejar terminar la instrucción que se este ejecutando
d) y luego pone en el stack A,X,Y, status y PC.
e) y luego te llama a tu código.

La unica incógnita es c)... no se sabe que instrucción se esta ejecutando... y hay instrucciones que tardan 2 ciclos y otras que pueden tardar 7.
Y esos 5 ciclos de diferencia es el "randomness" que ves en las "raster inestables".

¿Como prevenirlos?

Hay distintas técnicas. La que yo estoy usando es una llamada "doble IRQ" que esta muy bien explicada aca:
http://codebase64.org/doku.php?id=base:stable_raster_routine

La idea es la siguiente:
Como no sabes lo que pasa en c), la idea es poner una primera IRQ llena de NOPs y luego otra, con la idea de que la segunda IRQ se llame cuando se estan ejecutando los NOPs... y luego un truquito más que esta explicado en ese documento.

El código mencionado ahí lo puse en esta macro en format CA65:
https://github.com/ricardoquesada/c64-the-muni-race/blob/master/src/mymacros.mac



Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Agosto 01, 2015, 20:15:03
Que interesante. En algún momento me gustaría probar algo de esto.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Agosto 02, 2015, 22:52:51
Estudiandolo estoy.

Grácias Riq  ;)

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Agosto 02, 2015, 22:55:42
Que interesante. En algún momento me gustaría probar algo de esto.

Es muy interesante y útil. La cosa tiene su miga  pero si consigues comprenderlo bién se pueden hacer virguerias. Llevo dias leyendo de todo para tratar de entenderlo. Soy duro de mollera  ;)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Agosto 02, 2015, 23:18:26
Soy duro de mollera  ;)

Me parece de muy mala educación contradecir a un compañero :P

Ahora mismo estoy metido cargando revistas y libros a Ri, que tenía curro atrasado. Al mismo tiempo cargando también cosas a CBMes, asi que dejo este tema un poquito aparcado, pero en algun momento me pica de nuevo y sigo donde estaba.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Agosto 03, 2015, 00:03:55
Me parece de muy mala educación contradecir a un compañero :P

Así me gusta. Pero no sé si os a pasado alguna vez que ante una cosa obvia que la tienes delante , no la ves y cuando te das cuenta , te das de collejas por no pillarlo a la primera.

Así estoy yo con el raster. Ya comprendo que hay que desconctar algunas cosas para que las interrupciones NMI no te toquen las narices.

Cuando lo tenga aclarado (lo más básico y necesario para que funcionen, nada de virguerias) lo colgare , aunque supongo que en "dudas en ensamblador", que creo que pertenecen las dudas que tengo sobre esto.


Ahora mismo estoy metido cargando revistas y libros a Ri, que tenía curro atrasado. Al mismo tiempo cargando también cosas a CBMes, asi que dejo este tema un poquito aparcado, pero en algun momento me pica de nuevo y sigo donde estaba.

No es una competición  ;), pero siempre es agradable y divertido tener a más gente con niveles similares para ir evolucionando con los aportes e ideas de cada uno.

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Agosto 11, 2015, 03:02:57
timers

La frecuencia de barrido de NTSC (commodore en EE.UU) es de 60 veces por segundo. La PAL-B (europa) es de 50-veces por segundo.
O sea, que el barrido en la NTSC es más rápido... asi que usar el raster-IRQ para tocar música no es muy buena idea.
Entonces ¿si queres hacer un jueguito que funcione en NTSC y PAL, y que la música corra a la misma velocidad que haces?

Podes cambiar el código de la música, pero algo más fácil es usar los timers de la CIA, y programar uno para que se ejecute 50 veces por segundo.
Programarlos es relativamente sencillo, pero lo que hay que tener en cuenta es que cuando el timer llega a 0, se genera una IRQ.

Entonces si uno ya tiene instalado un vector con el raster-IRQ, hay que diferenciar cuando la IRQ es de raster y cuando es de timer.
Es se puede hacer comprobando si $d019 esta en uno para saber si fue una interrupción por raster, o similar.

Si la IRQ es por timer, entonces solo ahí uno tiene que tocar la música... y de esa manera la música va a sonar a la misma velocidad tanto en NTSC como en PAL.

Quizás lo complicado es saber que valores hay que usar en el timer, porque la duración de un ciclo en NTSC y PAL son distintos... lo bueno es que todo esto ya fue hecho hace muchos años... entonces solo hay que usar, por ejemplo, estos números para programar el timer:

http://codebase64.org/doku.php?id=base:playing_music_on_pal_and_ntsc

Aca tengo código que lo usa (el scroller es el mismo del jueguito que estoy haciendo, pero fijense en la parte que dice "sync50hz" )
https://github.com/ricardoquesada/c64-casual-connect-15/blob/master/src/intro.s

y aca esta un .prg para que prueben


Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Agosto 11, 2015, 04:35:42
Que bueno todo... en serio.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Septiembre 14, 2015, 08:31:12
Optimizaciones...

Detectar colisiones usando la funcionalidad que trae el VIC esta bien, pero cuando uno quiere hacer cosas más complejas no es muy útil.
Por ejemplo, si a mi me interesa saber si mi sprite colisiona con ciertos caracteres, pero quiero ignorar otros, ya no me sirve usar la IRQ de sprite-caracteres que trae el VIC.

Entonces para detectar eso, uno tiene que hacer una simple rutina de "bounding box"
Y si bien hacer un bounding_box() no es complicado, lo más importante es hacerlo rápido, ya que se va a ejecutar 1 vez por por sprite en cada loop.

En la rutina que estoy haciendo, lo más lento era una multiplicación por 40 que hacía.
Código: [Seleccionar]
// saber que char hay en (x,y)
int char_index = y * 40 + x;

// Y se puede optimizar con
int char_index = (y * 32) + (y *8) + x;

// que es lo mismo que esto, pero más rápido
int char_index = (y << 5) + (y << 3) + x;

// pero lo más rápido de todo es hacer una tabla de multiplicaciones
// la tabla solo ocupa 50 bytes (25 words) ya que solo multiplico por valores entre 0 y 24, ya
// que solo hay 25 columnas
int char_index = tabla_de_mulitplicacion_de_40[y] + x;

así que lo que hice fue una tablita...  y para hacer la tablita me hice este tool:
https://github.com/ricardoquesada/c64-misc/blob/master/tools/mult_table_generator.py

A medida que voy avanzado con el jueguito, me estoy dando cuenta lo importante que es tener tablas de valores precalculados para todo, por dos simple razones:

- velocidad
- simplifica el código múchisimo :)

pero el problema es que las tablas hacen que consuma más memoria, lo cual puede ser un problema grande.


El jueguito va progresando poco a poco, todavía no tiene mucho, pero aunque ahora hay un "game scene" donde se puede mover el actor y hacerlo saltar y tiene detección de colisiones y salta bajo y alto. Se puede bajar de aca:
https://github.com/ricardoquesada/c64-the-muni-race/blob/master/bin/therace.prg?raw=true
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Septiembre 17, 2015, 22:01:00
Ya me gustaría llegar a ese nivel como para hacer una detección por boundingbox...

He mirado el prg, ¿tus personajes van desnudos? :D :D
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Septiembre 17, 2015, 22:01:42
Consejo: para empezar a jugar pon también que sirva el disparo, además de F1.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Septiembre 17, 2015, 22:36:22
Me gusta el efecto de gravedad en el salto.
¿Has hecho exprofeso que en el primer hueco haya como un fondo y en el segúndo,  caiga en un bucle infinito donde el monociclista alcanza velocidades supersónicas?.

Es divertido  ver como se acelera y aparece el efécto estroboscópico   ;D

Hacia la derecha desaparece y parece que sigue haciendo camino ya que tarda el mismo tiempo dedicado en volver como el que he invertido antes. Es curioso.

Pero tiene pinta de entretenido. Me gusta.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Septiembre 18, 2015, 00:02:35

He mirado el prg, ¿tus personajes van desnudos? :D :D

Ahora que me fijo... tienes razón  :D.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Septiembre 18, 2015, 01:40:53
Ja. Andar en monociclo desnudo no es algo que yo recomiende :) Son más mis limitaciones como artista gráfico que otra cosa.

El código todavía esta muy crudo... le falta muchísimo, y voy avanzado poco a poco. Me concentré solamente en hacer un mini algoritmo de colisiones. Mi siguiente paso creo que es mejorar el editor de caracteres que estoy haciendo (vchar64) para poder hacer un mapa más o menos decente.

Ya agregaré mejores animaciones, mejores graficos, sonidos y demás... quizas en 5 años lo termine :)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Septiembre 18, 2015, 08:17:59
Ja. Andar en monociclo desnudo no es algo que yo recomiende :)

Pués anda, que sin sillín...  :D

Ya agregaré mejores animaciones, mejores graficos, sonidos y demás... quizas en 5 años lo termine :)

Veo que eres optimista. Si necesitas ayuda en el apartado gráfico, tenemos un artista en el foro , Errazking. Es un crack!!  ;).
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Enero 04, 2016, 01:26:51
Pues aquí seguimos.

Estoy empezando un juego tipo Head On (por fin me he animado a intentar algo  ::)) y se me a ocurrido ir poniendo las rutinas que voy creando para que si veis alguno como añadir mejoras, pues me encantará aplicarlas si esta en mis posibilidades entenderlo.

La verdad es que es complicado el jueguecito, el hacer que los enemigos se muevan hacia el carril donde estoy desde cualquier dirección y posición de la pantalla es malnacido.

Intentaré crear unas tablas para que estas cosas las haga de manera automática sin "if thens" o comprobaciones eternas que compliquen el seguir/crear el programa
Ya iré colgando por aquí los progresos  ;)

Código: [Seleccionar]
;Creado en CBM prg STUDIO 3.6.0
;Pruebas para colocar sprite en pantalla partiendo de unas coordenadas de pantalla
;X de 0 a 39 e Y de 0 a 24
; 10 SYS4096

*=$801

        BYTE    $0B, $08, $0A, $00, $9E, $34, $30, $39, $36, $00, $00, $00
*=$1000 ;#4096

;Posición sprite en coordenadas X=0 e Y=0 de caracteres, en el sprite es X=#24 e Y=#50
;Formula de caracteres a sprites: Xcar*8+24 Ycar*8+50
facarg=$bc0c
intfac=$b391
sum=$b86a
res=$b853
mul=$ba2b
div=$bb12
facind=$bc9b
msb=$d010       ;Activar >255 sprites
posprites=$D000
spena=$D015
Posmemspr=$07f8 ;#2040

Xcar0=#30        ;Coordenada X coche 0 (el prota) 28*8=224 +24 de correccion=248.
                 ;Es el máximo sin tener que activar el msb
Ycar0=#00        ;Coordenada Y coche 0 (elprota)

;Posicionando y conectando sprites
        lda #1
        sta spena      ;Conecta sprite 0
        lda #24+50
        sta posprites   ;CoordX
        lda #50
        sta posprites+1 ;CoordY
        lda #192+2      ;#12288
        sta Posmemspr   ;Sprite en memoria
loop                    ;Inutil de momento, solo se ejecuta una vez
   
        lda #00         ;Desactiva el msb antes del cálculo
        sta msb         ;es mejorable, solo es para la prueba.

;Multiplicando la coordenada X en caracteres para conseguir la coordenada X del sprite:
;Vale también para la coordenada Y. De hecho, se llamará a esta rutina para calcular
;cada eje de cada coche.

;ACU y Registro Y se pueden cargar antes de llamar a esta rutina. Aqui los cargo a
;continuación para las pruebas.

        lda #00         ;HIBYTE  LoHi Es 0 por que va de 0 a 0 XD
        ldy #Xcar0      ;LOBYTE ;00XX coordenada X coche Va de 0 al 39
        jsr intfac      ;
        jsr facarg      ;
        lda #00         ;HIBYTE LoHi
        ldy #08         ;LOBYTE 0008 X8
        jsr intfac
        jsr mul         ;Resultado en $64 y $65 HIBYTE y LOBYTE respectivamente
        jsr facind
        lda $64         ;Resultado HI de multiplicar Xcar x 8 bits
        ldy $65         ;Resultado LO de multiplicar Xcar x 8 bits
        jsr intfac
        jsr facarg
        lda #00         
        ldy #24         ;Corrección de la posición del sprite , ya que coordnada
                        ;X o Y con valor 0, queda detrás del borde de la pantalla.

        jsr intfac
        jsr sum
        jsr facind
        ldy $65
        clc             ;Por si acaso XD
        lda $64         ;Si el numero calculado sobrepasa los 255, el Hibyte no sera 0
        beq sigue1      ;Si es cero, pasa de activar el msb
        lda #01         ;Si es > de 0 , pasa a activar el msb
        sta msb

sigue1  sty posprites ;posprites   ;
        rts             ;Vuelta al basic


*=$3000 ;#12288  12288/64=192 primer sprite
; Derecha
 BYTE 0,0,0
 BYTE 118,0,0
 BYTE 32,0,0
 BYTE 63,0,0
 BYTE 63,0,0
 BYTE 32,0,0
 BYTE 118,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0,0

; Izquierda
 BYTE 0,0,0
 BYTE 110,0,0
 BYTE 4,0,0
 BYTE 252,0,0
 BYTE 252,0,0
 BYTE 4,0,0
 BYTE 110,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0,0

; Abajo
 BYTE 0,0,0
 BYTE 66,0,0
 BYTE 126,0,0
 BYTE 90,0,0
 BYTE 24,0,0
 BYTE 90,0,0
 BYTE 90,0,0
 BYTE 24,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0,0

; Arriba
 BYTE 24,0,0
 BYTE 90,0,0
 BYTE 90,0,0
 BYTE 24,0,0
 BYTE 90,0,0
 BYTE 126,0,0
 BYTE 66,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0
 BYTE 0,0,0,0

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Enero 04, 2016, 01:30:04
Si modificáis Xcar0 de 0 a 39 (eje X), el coche aparecerá justo encima de ese carácter.
 
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Enero 04, 2016, 01:50:04
¿Este es el juego, no?

https://www.youtube.com/watch?v=jkCycCMJWdo
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Enero 04, 2016, 02:01:05
Casi. Este se mueve como un comecocos, el Head On arcade  se desplaza lateralmente hasta 2 o 3 carriles.
Ese va a "saltos" de 8 pixeles, por eso quiero usar un sprite para que se mueva suave.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: R. INTERNATIONAL en Enero 04, 2016, 22:15:16
  GUAU!!!!

   Animo Maniako,...super espectante me quedo!!,....es toda una alegria para mi ver como te lo curras!!!, me has dejado alucinado!!

   Un saludazo!!

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Marzo 22, 2016, 08:20:39
ahora que le agregué un editorcito de mapas al vchar64, pude recién seguir con el jueguito este que estoy haciendo. pero el juego es completamente distinto... creo que rescribí el 80% del código ya que decidí hacer un juego distinto al que pensé originalmente.

- este va a tener sprites super simplificados (extremadamente simplificados)
- no va a tener graficos bitmap
- no va a redifinir caracteres. todo va a ser petscii + sprites
- va a ser multijugador
- tiene nueva pantalla de inicio, nueva pantalla de scores, nueva pantalla para jugar
- saque el "about"... lo tengo que reemplazar por otro cosa
- no se llama más "the muni race", ahora se llama "the uni games".
- la idea es que tenga un look super super pedorro... cuanto más pedorro mejor... nada de efectitos copados ni nada de eso... bien pedorro.... un look bien "retro retro".
- y la idea es que se tenga que jugar con un monociclo de verdad (el uni-stick)... jugar con un joystick va a ser posible (es asi como lo estoy testeando), pero la posta es jugarlo con monociclo de verdad. más sobre esto en el futuro...

va a tener 3 o 4 eventos:

- saltar escaleras hacia arriba (boton del joy, ó saltar con el monociclo)
- 100 metros carrera llana  (izq-der del joy, ó idling en el monociclo)
- 2k metros carrera llana  (izq-der del joy, ó idling en el monociclo)
- 2k cross-country con obstaculos (izq-der + boton del joy, ó idling + saltar con el monociclo)


aca esta el último binario:
https://github.com/ricardoquesada/c64-the-muni-race/raw/master/bin/therace.prg

y 2 screenshots pedorros del código actual:
(https://lh3.googleusercontent.com/-G0U1Wbbfeo0/VvDxcWEVQKI/AAAAAAABdl4/MaAoyrS_QdQpx9NjH9B38FePe5-jgeQiwCCo/s640-Ic42/Screen%2BShot%2B2016-03-22%2Bat%2B12.16.05%2BAM.png)
(https://lh3.googleusercontent.com/-JPw87NTIzPw/VvDxcSKPFyI/AAAAAAABdl8/sFwRp2qILYg1zZEJ2BR2ZjIwzXb-CHrpgCCo/s640-Ic42/Screen%2BShot%2B2016-03-22%2Bat%2B12.16.34%2BAM.png)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Marzo 22, 2016, 08:38:50
pero en definitiva... ¿qué aprendí de nuevo estos meses?

Básicamente que si uno quiere velocidad, hay que usar tablas para tooooodo.
es como si un programase "off-line". Se hacen todos los calculos pesados en una o varias tablas, y luego se usan con algún indice.

Las tablas (con ayuda de macros) se pueden usar en cálculos sencillos, como multiplicar. Si uno sabe que va a multiplicar por 15 ciertos números, lo mejor es tener una tabla con ese precalculado. ej:
Código: [Seleccionar]
mult15:
.repeat 10,I
    .byte 15*I
.endrepeat

lda mult15,8      ; multiplicar 8 * 15

hice estos dos toolcitos para generar distintos tipos de tablas:
- https://github.com/ricardoquesada/c64-misc/blob/master/tools/easing_table_generator.py
- https://github.com/ricardoquesada/c64-misc/blob/master/tools/mult_table_generator.py

y ademas fui descubriendo el poder de las macros del cc65. Muy poderoso, aunque supongo que los demas ensambladores son similares. ejemplo de macro que estoy usando:

Código: [Seleccionar]
ADDRESS0 = SCREEN_BASE+15*40        ; left eye
ADDRESS1 = SCREEN_BASE+15*40+2      ; right eye
ADDRESS2 = SCREEN_BASE+17*40        ; left arm
ADDRESS3 = SCREEN_BASE+17*40+2      ; right arm
ADDRESS4 = SCREEN_BASE+21*40+1      ; hub

ADDRESS5 = SCREEN_BASE+15*40+37     ; left eye
ADDRESS6 = SCREEN_BASE+15*40+39     ; right eye
ADDRESS7 = SCREEN_BASE+17*40+37     ; left arm
ADDRESS8 = SCREEN_BASE+17*40+39     ; right arm
ADDRESS9 = SCREEN_BASE+21*40+38     ; hub

addresses_lo:
.repeat 10,YY
        .byte <.IDENT(.CONCAT("ADDRESS", .STRING(YY)))
.endrepeat
addresses_hi:
.repeat 10,YY
        .byte >.IDENT(.CONCAT("ADDRESS", .STRING(YY)))
.endrepeat

basicamente esas macros me generan las direcciones "lo" y "hi" de las coordenadas que les paso... nada del otro mundo, pero me ahorran bastante tiempo.
creo que aprender las macros del ensablador es tan importante como aprender las instrucciones del 6502.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Marzo 22, 2016, 08:45:38
Cambio radical ;)

Veo que es pantalla partida. Estupendo para dos jugadores.
¿Vas a conectar un monociclo real al commodore? :o

Encoders, contadores y todo eso?.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Mayo 06, 2016, 01:27:39
voy avanzando poco a poco con el jueguito, pero creo que lo termino este año.

¿que aprendí ultimamente?

no mucho. pero hay dos que cosas que vale la pena mencionar:

- manejar el teclado de manera prolija es más complicado de lo que uno imagina.
- los sprites consumen "ciclos" en el rasterline... asi que cuando uno pone sprites, hay que hacer las cuentas nuevamente para tener un raster estable.


si alguien quiere probar el jueguito (version muy alpha aún, esta aca):
https://github.com/ricardoquesada/c64-the-uni-games/raw/master/bin/unigames.prg

Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Mayo 06, 2016, 02:08:34
Críticas:
- Cuando entras a SCORES (disparo) se tendría que poder volver con disparo.
- Jugarlo con las teclas en emulador es un poco complicado :D :D
- Los sprites de los protagonistas no son realistas
- En la pantalla de arriba, el barrido hace algunas cosas raras, supongo que a eso te referias con los ciclos.
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Mayo 06, 2016, 02:29:15
gracias!

- Jugarlo con las teclas en emulador es un poco complicado :D :D

¿cómo? ¿no tenes un unijoysticle para jugarlo?
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: josepzin en Mayo 06, 2016, 02:42:00
Vaya, ya he quedado obsoleto... :D
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 08, 2016, 20:17:26
otra cosita útil:
Para no tener que cargar cosas de disquete, es útil tener las distintas escenas del juego comprimidos en memoria (en caso que uno tenga varias escenas).
uno reserva un pedazo de memoria para una escena... digamos de $2400 a $8000, y luego todas la esceneas que esten comprimidas de $8000 a $fff0.
comprimo todo con exomizer, y la descompresión la hago con el descrompresor de exomizer.
todo el código esta aca: https://github.com/ricardoquesada/c64-the-uni-games


es es lo que estoy haciendo en la última versión del "uni games" (adjuntada).
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: Maniako en Julio 09, 2016, 00:09:23
Eh!! El personaje es de Grog Revenge XD.

¿Es cosa mia o el salto se retrasa unos pocos milisegundos?, Cuando intento saltar alguno de los obstáculos, tarda en reaccionar y me la pego.

La velocidad en doble scroll es muy buena!!.

Le echaré un ojo al código a ver qué aprendo.  :)
Título: Re:Assembler - Cosas que voy aprediendo
Publicado por: riq en Julio 09, 2016, 01:26:10
Eh!! El personaje es de Grog Revenge XD.

¿Es cosa mia o el salto se retrasa unos pocos milisegundos?, Cuando intento saltar alguno de los obstáculos, tarda en reaccionar y me la pego.

La velocidad en doble scroll es muy buena!!.

Le echaré un ojo al código a ver qué aprendo.  :)

Si, en particular es el personaje de BC's Quest For Tires, que esta basado en el comic B.C.
Y existe un tipo de monociclo llamado la "rueda BC" que esta inspirado en eso.
El jueguito es un poco un homenaje a eso. En el About cuento un poco eso.

Respecto al salto debería ser inmediato, sino es un bug. pero tené en cuenta que no se puede saltar ni bien aterrizas. En el nivel "Cyclo Cross" debería saltar inmediatamente casi siempre.