Autor Tema: Rutinas de ensamblador con Laddh  (Leído 4745 veces)

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Rutinas de ensamblador con Laddh
« en: Abril 19, 2024, 13:11:48 »
Buenas commodorianos, inicio aquí este hilo, dirigido para los que como yo hace algunos años, tengan la chispa, la inquietud de querer hacer algo con su commodore64 en ensamblador y hacer algo más que darle a la palanca, pero se les hace un muro infranqueable y aún no se han atrevido a saltar del trampolín. En ensamblador, nada de gamemakers porque estaréis limitados a lo que hace el maker y os quedareis con las ganas. Nada de teoría y parrafadas técnicas porque ni yo me las se, vamos a lo práctico con un ejemplo que funciona, se pueda ver lo que hace, comentado y abierto a lo que se os ocurra. Por supuesto que algún libro del 6510, 6502 os tenéis que leer, no hace falta memorizar, solo pillar la idea, especialmente de las comparaciones.
Seguiremos el esqueleto de como yo lo fui aprendiendo.
Primero una rutina de Joystick para mover un sprite. En mi caso se acabo contiendo en Race.
Una rutina para presentar una pantalla gráfica de alta resolución. Se convirtió en Argos.
Una rutina para presentar un pantalla de caracteres editados. Se convirtió en Excalibur.
Una rutina de scroll por hardware lateral. Se convirtió en Mad Race.
Y si la cosa se anima y hay interés, pues lo que vaya saliendo.

Código: [Seleccionar]
; 10 SYS (2064) línea para que autoarranque el programa

*=$0801

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

*=$0810 ;inicio del programa

v = $d000       ;variable que apunta al chip VIC, el que gestiona todo lo gráfico

        jsr sprites     ;llamamos a la rutina para presentar el sprite en pantalla
loop    jsr raster_wait ;sin esto no veríamos nada, el código máquina es raaaaaapido               
        jsr PlayerControl ;la rutina para controlar el joystick
        jmp loop        ;vuelve al bucle principal

PlayerControl
        LDA $DC00   ;LEEMOS JOY
        AND #31     ;LA CUATRO DIRECCIONES ARRIBA ABAJO IZQ DER   
        CMP #30     ;MAS DIAGONALES Y FUEGO
        BEQ ARR
        CMP #29
        BEQ ABJ
        CMP #27
        BEQ IZQ
        CMP #23
        BEQ DER
        cmp #22
        beq derar
        cmp #21
        beq derab
        CMP #25
        BEQ IZQab
        CMP #26
        BEQ IZQar
        cmp #15
        beq fuego
        rts

arr     dec v+1 ;coordenada vertical del sprite 0
        rts
abj     inc v+1
        rts
izq     dec v   ;coordenada horizontal del sprite 0
        rts
der     inc v
        rts
derar   inc v
        dec v+1
        rts
derab   inc v
        inc v+1
        rts
izqab   dec v
        inc v+1
        rts
izqar   dec v
        dec v+1
        rts
fuego   inc $d020       ;cambia color del borde pantalla
        rts

raster_wait             ;espera línea raster 255, el raster pasa 50 veces por segundo
l       LDA #$ff        ;en pantalla
        CMP $D012
        BNE l
        BIT $d011
        BMI l
        rts

sprites lda #1
        sta v+21        ;activamos sprite 0
        sta v+28        ;activamos modo multicolor del sprite 0
        lda #192        ;puntero para indicar donde estan los datos del sprite, 192*64=12288
        sta 2040
        lda #1          ;color blanco a sprite 0
        sta v+39
        lda #14         ;color multicolor 1, para todos los sprites
        sta v+37
        lda #2          ;color multicolor 2, para todos los sprites
        sta v+38
        lda #100        ;coordenadas x,y del sprite 0
        sta v
        sta v+1
        rts

*=12288 ; la forma del sprite
 byte 9,86,0
 byte 37,86,0
 byte 149,86,0
 byte 85,86,0
 byte 85,170,170
 byte 86,37,86
 byte 86,37,86
 byte 86,37,86
 byte 86,37,90
 byte 86,42,168
 byte 86,42,168
 byte 86,47,250
 byte 86,47,254
 byte 86,47,254
 byte 86,47,254
 byte 86,42,170
 byte 85,170,0
 byte 85,86,0
 byte 149,86,0
 byte 37,86,0
 byte 9,86,0

Por supuesto hay mejores rutinas para leer el joy de una sola comparación, pero esta es buena para comprender como lo hace

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13836
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Rutinas de ensamblador con Laddh
« Respuesta #1 en: Abril 19, 2024, 19:15:41 »
Me parece una propuesta súper interesante, como bien dices una cosa asi puede ser la semilla de un juego.

Por saber algo más, ¿qué ensamblador estas usando?
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Re:Rutinas de ensamblador con Laddh
« Respuesta #2 en: Abril 19, 2024, 22:07:15 »
Siempre he utilizado el CBM Prg Studio, es cómodo, y tienes a mano los editores de sprites y caracteres.

PacoBlog64

  • Commodore Master
  • *****
  • Mensajes: 364
  • INC $D020
    • Ver Perfil
    • PacoBlog64
Re:Rutinas de ensamblador con Laddh
« Respuesta #3 en: Abril 20, 2024, 11:28:24 »
Excelente iniciativa, a ver si más gente se anima a programar en ensamblador de C64.
Commodoriano desde mis tiernos 7 añitos. ¿Quién necesita más de 1MHz, 64KB de RAM, 16 colores y 3 canales de sonido?

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Re:Rutinas de ensamblador con Laddh
« Respuesta #4 en: Abril 20, 2024, 11:37:43 »
Esa es la intención, a ver si colapsamos CSDB con nuestras producciones!!!  ;D

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13836
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Rutinas de ensamblador con Laddh
« Respuesta #5 en: Abril 20, 2024, 14:59:17 »
Siempre he utilizado el CBM Prg Studio, es cómodo, y tienes a mano los editores de sprites y caracteres.
Es el que yo hubiera elegido si al final no me hubiese metido con Turbo Rascal!
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Re:Rutinas de ensamblador con Laddh
« Respuesta #6 en: Abril 20, 2024, 18:57:15 »
Aaaaahg!, yo quería convertirte en talibán del asm!!!

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13836
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Rutinas de ensamblador con Laddh
« Respuesta #7 en: Abril 21, 2024, 01:17:53 »
Bueno, sigue siendo una posibilidad, pero no quiero arrancar "a lo bestia" en ensamblador :D

Pero ya me está pasando (bueno, la última vez que pude ponerme con esto) que alguna cosa que quería hacer ya estaba metiendo directamente código ensamblador... asi que tarde o temprano seguro me meteré de lleno.

Por ahora voy a ir aprovechando las funciones que ya vienen con TurboRascal para hacer las distintas cosas, como leer teclado, joystick, etc.
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Re:Rutinas de ensamblador con Laddh
« Respuesta #8 en: Abril 21, 2024, 12:12:11 »
Pues cuando utilices la función del Trascal del joy, en esta primera entrega tienes listado y ejemplo de como funciona la lectura del joystick, así también sabrás como funciona "por dentro"

Bieno

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 4012
  • PRINT"ADORA A TU COMMODORE"
    • Ver Perfil
    • bieno64
Re:Rutinas de ensamblador con Laddh
« Respuesta #9 en: Abril 22, 2024, 09:59:56 »
Muy buena idea, LADDH. Ira bien para los que queremos comenzar a hacer algo en ensamblador

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Re:Rutinas de ensamblador con Laddh
« Respuesta #10 en: Abril 22, 2024, 11:52:51 »
A por ello! y tu próxima aventura será sin más limitación que lo que imagines  ;)

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Re:Rutinas de ensamblador con Laddh
« Respuesta #11 en: Abril 26, 2024, 13:25:18 »
Siguiente entrega, añadimos un par de rutinas al programa anterior, la de carga de una pantalla en modo alta resolución multicolor, y una rutina mínima para ejecutar música por interrupciones.
Estas pantallas hires, quedan mas guapas y espectaculares pero a costa de una gran ocupación de memoria, 10k en este caso de un grafico en formato Koala, que añadimos al programa con el incbin (include binario) en la posición de memoria $2000 (8192), tenéis la rutina cargahr para ver como lo hace.
Demasiado, yo solo le veo utilidad como gráfico de presentación del programa y luego ocupar esas mismas posiciones de memoria al cargar el resto del programa.
Lo de las interrupciones, yo no he encontrado un solo sitio donde te lo expliquen concienzudamente, pero a grandes rasgos es aprovechar la misma rutina de interrupción del sistema que 50 veces por segundo chequea el teclado, pantalla, todo el sistema, añadiendo tú rutina al vector $0314-$0315, como podéis ver en el listado, esa rutina ejecuta un sid que tengamos en la posición $1000 de memoria, añadida con su correspondiente incbin.
Así ya veis, que simplemente añadiendo rutinas que tengáis por separado, acabara  convirtiéndose en un programa más presentable.

Código: [Seleccionar]
; 10 SYS (2064) línea para que autoarranque el programa

*=$0801

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

*=$0810 ;inicio del programa

v = $d000       ;variable que apunta al chip VIC, el que gestiona todo lo gráfico


        jsr cargahr     ;carga pantalla gráfica multicolor
        jsr musica      ;llama a rutina música por interrupciones
        jsr sprites     ;llamamos a la rutina para presentar el sprite en pantalla
loop    jsr raster_wait ;sin esto no veríamos nada, el código máquina es raaaaaapido               
        jsr PlayerControl ;la rutina para controlar el joystick
        jmp loop        ;vuelve al bucle principal


cargahr LDA #$01        ; Carga A con #$00, que es el código del color negro.
        STA $D020       ; Guarda el valor #$00 en la dirección $D020, que corresponde al borde de la pantalla.
        STA $D021       ; Guarda el valor #$00 en la dirección $D021, que corresponde al fondo de la pantalla.
        TAX             ; Transfiere el contenido de A a X. De esta manera carga X con #$00, que es el valor inicial de un bucle, ahorrando espacio de memoria.
COPIA   LDA $3F40,X     ; Carga A con el valor de la dirección $3F40 y siguientes.
        STA $0400,X     ; Guarda el valor de A en la posición $0400 y siguientes del mapa de memoria de la pantalla.
        LDA $4040,X     ; Carga A con el valor de la dirección $4040 y siguientes.
        STA $0500,X     ; Guarda el valor de A en la posición $0500 y siguientes.
        LDA $4140,X     ; Carga A con el valor de la dirección $4140 y siguientes.
        STA $0600,X     ; Guarda el valor de A en la posición $0600 y siguientes.
        LDA $4240,X     ; Carga A con el valor de la dirección $4240 y siguientes.
        STA $0700,X     ; Guarda el valor de A en la posición $0700 y siguientes.
        LDA $4328,X     ; Carga A con el valor de la dirección $4328 y siguientes.
        STA $D800,X     ; Guarda el valor de A en la posición $D800 y siguientes del mapa de colores de pantalla.
        LDA $4428,X     ; Carga A con el valor de la dirección $4428 y siguientes.
        STA $D900,X     ; Guarda el valor de A en la posición $D800 y siguientes.
        LDA $4528,X     ; Carga A con el valor de la dirección $4528 y siguientes.
        STA $DA00,X     ; Guarda el valor de A en la posición $D800 y siguientes.
        LDA $4628,X     ; Carga A con el valor de la dirección $4628 y siguientes.
        STA $DB00,X     ; Guarda el valor de A en la posición $D800 y siguientes.
        DEX             ; Decrementa el valor de X.
        BNE COPIA       ; Salta a COPIA hasta que el valor de X=#$00.
        LDA #$3B        ; Carga A con #$3B
        LDX #$18        ; Carga X con #$18
        LDY #$18        ; Carga Y con #$18, que determina que el código del bitmap realizado con el KOALA necesariamente debe ensamblarse a partir de la dirección de memoria $2000.
        STA $D011       ; Guarda el valor de A en la dirección $D011, que selecciona el modo bitmap.
        STX $D016       ; Guarda el valor de X en la dirección $D016, que selecciona el modo multicolor.
        STY $D018     
        rts

MUSICA    sei
          lda #<irq
          ldx #>irq
          sta $314
          stx $315
          lda #$00
          JSR $1000     ;INITIALIZE MUSIC
          cli
          RTS

irq       lda #$01
          STA $D019     ; ACK ANY RASTER IRQS
          JSR $1003     ;PLAY THE MUSIC
          jmp $ea31


PlayerControl
        LDA $DC00   ;LEEMOS JOY
        AND #31     ;LA CUATRO DIRECCIONES ARRIBA ABAJO IZQ DER   
        CMP #30     ;MAS DIAGONALES Y FUEGO
        BEQ ARR
        CMP #29
        BEQ ABJ
        CMP #27
        BEQ IZQ
        CMP #23
        BEQ DER
        cmp #22
        beq derar
        cmp #21
        beq derab
        CMP #25
        BEQ IZQab
        CMP #26
        BEQ IZQar
        cmp #15
        beq fuego
        rts

arr     dec v+1 ;coordenada vertical del sprite 0
        rts
abj     inc v+1
        rts
izq     dec v   ;coordenada horizontal del sprite 0
        rts
der     inc v
        rts
derar   inc v
        dec v+1
        rts
derab   inc v
        inc v+1
        rts
izqab   dec v
        inc v+1
        rts
izqar   dec v
        dec v+1
        rts
fuego   inc $d020       ;cambia color del borde pantalla
        rts

raster_wait             ;espera línea raster 255, el raster pasa 50 veces por segundo
l       LDA #$ff        ;en pantalla
        CMP $D012
        BNE l
        BIT $d011
        BMI l
        rts

sprites lda #1
        sta v+21        ;activamos sprite 0
        sta v+28        ;activamos modo multicolor del sprite 0
        lda #37         ;puntero para indicar donde estan los datos del sprite, 37*64=2368
        sta 2040
        lda #1          ;color blanco a sprite 0
        sta v+39
        lda #14         ;color multicolor 1, para todos los sprites
        sta v+37
        lda #2          ;color multicolor 2, para todos los sprites
        sta v+38
        lda #100        ;coordenadas x,y del sprite 0
        sta v
        sta v+1
        rts

*=$1000
incbin"commodore_64.sid",126

*=$2000
incbin"hiresmcm.koa",2

*=2368  ; la forma del sprite
 byte 9,86,0
 byte 37,86,0
 byte 149,86,0
 byte 85,86,0
 byte 85,170,170
 byte 86,37,86
 byte 86,37,86
 byte 86,37,86
 byte 86,37,90
 byte 86,42,168
 byte 86,42,168
 byte 86,47,250
 byte 86,47,254
 byte 86,47,254
 byte 86,47,254
 byte 86,42,170
 byte 85,170,0
 byte 85,86,0
 byte 149,86,0
 byte 37,86,0
 byte 9,86,0

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13836
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Rutinas de ensamblador con Laddh
« Respuesta #12 en: Abril 28, 2024, 23:49:46 »
Ya estás casi entrando en la parte "mágica", eso de las interrupciones ;)

El gráfico que carga parece una captura del foro, no?

Cada gráfico de esos ciertamente ocupa un montón, pero ahora con los cartuchos "gratis", o sea el formato .CRT, cargarlas desde allí permite juegos como el del cerdito, con todos bitmaps de escenario. Aunque yo reconozco que me gusta la magia de los tiles, sin desmerecer para nada esos pantallones tremendos que hacen los grafistas.

Me sorprendió la simple que es poner en marcha una música :O
Eso sí que es algo que nunca hice ni cerca estuve de entender. Ya me pondré.
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

josepzin

  • Administrador
  • Commodore Master
  • *****
  • Mensajes: 13836
  • Commodoreador web
    • Ver Perfil
    • Mi blog
Re:Rutinas de ensamblador con Laddh
« Respuesta #13 en: Abril 28, 2024, 23:50:33 »
Próximo capítulo: que el sprite pase los X > 255
www.retroinvaders.com | www.commodoreplus.org  | josepzin.blogspot.com

Laddh

  • Desarrolladores
  • Commodore Master
  • ******
  • Mensajes: 253
    • Ver Perfil
Re:Rutinas de ensamblador con Laddh
« Respuesta #14 en: Abril 29, 2024, 11:22:08 »
Correcto, el gráfico es una captura de nuestro querido foro, filtrado por el GangEd para convertirlo en un fichero con formato Koala.
Sí, en la próxima entrega añadiremos la rutina para cargar una pantalla de caracteres editados junto a que los sprites sobrepasen el limite de los 255 en X.