Commodore manía

Commodore 64 => Desarrollo => Ensamblador => Mensaje iniciado por: Maniako en Julio 08, 2015, 00:49:44

Título: Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 08, 2015, 00:49:44
Buenas.

Como veo interes en aprender ensamblador (yo el que mas) , ire colgando por aquí las rutinas
que en su dia aprendí o me enseñaron. "Trasteocódigos" los llamaba (era un crio).

Me encantaria crear una colección con los aportes de todos para tener un lugar de consulta rápida ante esos momentos "¿y ahora como demonios hago esto?" .

Aqui van mis primeros aportes. Utilizo la ROM del basic para las operaciones. Ya se que no es lo mas rápido, pero la facilidad de uso ayudará (o eso espero) a los noveles como yo.
___________________________________________________________________________________
Este permite hacer calculos de 16bit. y los muestra en pantalla. Suma, resta, divide y multiplica enteros.
Muy útil para manejarse en la memoria de pantalla usando coordenadas por ejemplo.

Código: [Seleccionar]
;Creado en CBM prg Studio
; 10 SYS (4096)

*=$801


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

        *=$1000         ;inicio programa

facarg=$bc0c
intfac=$b391
sum=$b86a
res=$b853
mul=$ba2b
div=$bb12                       
facind=$bc9b
intasc=$bdcd

        lda #$01        ;hibyte 1ª cifra a calcular
        ldy #$18        ;lobyte 1ª cifra a calcular
        jsr intfac        ;
        jsr facarg       ;
        lda #$04        ;hibyte 2ª cifra a calcular
        ldy #$00        ;lobyte 2ª cifra a calcular
        jsr intfac       ;
        jsr sum         ;OPERACION ELEGIDA
        jsr facind      ;
        ldx $65         ;Resultado lobyte leido de $65
        lda $64         ;Resultado hibyte leido de $64
        jsr intasc      ;Imprimir resultado en pantalla (X=lobyte/Acu=Hibyte)

        rts
___________________________________________________________________________________
Aqui lo mismo pero usando la pagina cero (zeropage) para pokear el puntito dentro de las coordenadas que pongais en cordx y cordy.
Primero calculo la coordenada Y*40 para saltar a la columna a la que apunte y después le sumo 1024 al resultado.
La coordenada X, simplemente usando STA indirecto indizado por Y que contiene el valor de cordx...

Código: [Seleccionar]
;Creado en CBM prg Studio

;----------------------------------------------------------------------------------------
;Este bloque separado genera una linea basic para arrancar el programa
; 10 SYS (4096)

*=$801


        BYTE    $0E, $08, $0A, $00, $9E, $20, $28,  $34, $30, $39, $36, $29, $00, $00, $00
;-----------------------------------------------------------------------------------------
        *=$1000         ;inicio programa SYS4096

;Direcciones de las rutinas del basic necesarias.
facarg=$bc0c
intfac=$b391
sum=$b86a
res=$b853
mul=$ba2b
div=$bb12
facind=$bc9b

;Aqui están las coordenadas X e Y para que juguéis con ellas y poner el punto
;donde os apetezca.
cordx=#05       ;Coordenada X de pantalla. De 0 a 39
cordy=#24       ;Coordenada Y de pantalla. De 0 a 24

;Aqui el programa en cuestión.
        lda #00         ;hybyte
        ldy #cordy      ;lobyte la coordenada Y no pasa de 24
        jsr intfac      ;
        jsr facarg      ;
        lda #00         ;hibyte
        ldy #40         ;lobyte #40-$28. En la memoria de pantalla para bajar una linea se suma 40 ;)
        jsr intfac      ;
        jsr mul         ;Multiplica cordy * #40

        jsr facind      ;
        lda $64         ;Carga el hibyte resultado del calculo en el ACU
        ldy $65         ;Carga el lobyte resultado del calculo en Y
        jsr intfac      ;
        jsr facarg      ;
        lda #$04        ;La memoria de pantalla va de 0400 hasta 07E7
        ldy #$00        ;hibyte en ACU y lobyte en Y
        jsr intfac      ;
        jsr sum         ;Suma 0400 al resultado de (cordy*40)

        jsr facind      ;
        lda $64         ;Carga ACU con el hibyte resultado.
        ldx $65         ;Carga X con el lobyte resultado.
        sta $FC         ;Guarda hibyte en la zeropage.
        stx $FB         ;Guarda lobyte en la zeropage.
        ldy #cordx      ;Carga Y con el valor de cordx.
        lda #81         ;Carga ACU con el valor 81 (puntito).
        sta ($FB),y     ;Lo muestra en pantalla
        rts             ;Volver al BASIC


;Puede que no sea una forma muy rápida para hacer los calculos, pero si es más comprensible
;para usuarios noveles. Siempre estaré agradecido a JAVIER CANTERO por las ayudas que me
;brindo a la hora de programar en CM.

;Se puede usar para mover multitud de objetos en la memoria de pantalla.



Espero la ayuda de todos con correcciones , mejoras y vuestros trasteocódigos con los que aprendisteís o aprendeis.  ;)

___________________________________________________________________________________

Mostrar texto en pantalla en las coordenadas que se deseén
Aportado por R.Internacional en este hilo http://retroinvaders.com/commodoremania/foro/index.php/topic,1080.msg17747.html#msg17747 (http://retroinvaders.com/commodoremania/foro/index.php/topic,1080.msg17747.html#msg17747)

Código: [Seleccionar]
* = $1000 ; SYS 4096.
  LDX #$01 ; Carga X con #$01, que corresponde a la línea 1.
  LDY #$0A ; Carga el Y #$0A, que corresponde a la columna 10.
  JSR $E50C ; Salta a la subrutina en ROM $E50C, que sitúa el cursor en las coordenadas dadas en los valores de X e Y.
  LDA #<CADENA ; Carga A con el byte bajo de la posición donde empieza el texto.
  LDY #>CADENA ; Carga Y con el byte alto de la posición donde empieza el texto.
  JSR $AB1E ; Salta a la subrutina en ROM $AB1E, que imprime una cadena de caracteres.
  RTS ; Retorna al BASIC.
CADENA .TEXT "HOLA A TODOS!!!" ; Texto.
  .BYTE $00


___________________________________________________________________________________
Rutina multiplicación rápida
Aportado por Lobogris en el hilo: http://retroinvaders.com/commodoremania/foro/index.php/topic,637.msg9662.html#msg9662 (http://retroinvaders.com/commodoremania/foro/index.php/topic,637.msg9662.html#msg9662)
Código: [Seleccionar]
/*
  *************************************************************************************
                       RUTINA  DE  MULTIPLICACION RAPIDA * 320
 
  ENTRADAS:
  $fa     = numero multiplicador (1 byte, rango efectivo = 0 < 204)
 
  SALIDAS:
  $fb-$fc = resultado del multiplicador * 320 (precisión 16 bits)
 
  DETALLES:   
    Num. de ciclos          = 51 (+12 contando ciclos del JSR/RTS)
    Tamaño en memoria       = 29 bytes
    Max resultado teorico   = 255 * 320 = 81600 ($013EC0)
                            (no cabe en 16 bits, habria que adaptar resultado a 3 bytes)
    Max. resultado efectivo = 204 * 320 = 65280 ($FF00)
   
    Si se quiere optimizar para menor tamaño, se pueden incluir las rotaciones
    como una parte iterada dos veces por un bucle. Pero perdemos ciclos asi...

   FECHA CREACION: 05-03-13  ,   ULT. REV.: 05-03-13                           (LOBOGRIS)
  ***************************************************************************************
*/

fastMUL320:
            // Descomponiendo, resultado de n * 320 = (256 * n)  + (64 * n)
            // ahora vamos a calcular 64*numero
            // esto se consigue poniendo numero en la parte alta del resultado para obtener numero*256
            // y desplazaremos (todos los 16 bits) de resultado a la derecha 2 veces para
            // conseguir numero*64...
           
            lda numero
            clc                 // Primera rotacion lógica a la derecha (16 bits)
            lsr                 
            sta resultado+1     // Num. en parte alta resultado = multiplicar Num. * 256)
            lda resultado
            ror
            sta resultado       // Tras 1a rotación, resultado = 128 * numero
       
            clc                 // 2a rotacion a la derecha (16 bits)
            lda resultado+1
            lsr                 
            sta resultado+1
            lda resultado
            ror
            sta resultado       // aqui resultado = 64 * numero
           
            // Ahora haremos resultado = (numero * 256) + (numero * 64)
            lda numero          // Recupera numero. Al ponerlo parte alta = numero * 256
            adc resultado+1     // se añade a resultado*64 (parte alta es la única afectada)   
            sta resultado+1     // ¡Ahora resultado = 320 * numero!
            rts
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 08, 2015, 00:51:43
Reservado para futuros listados
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Julio 08, 2015, 03:45:45
gracias! y muy buena la idea de ir poniendo rutinas aca.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 08, 2015, 13:51:33
Me encantaria crear una colección con los aportes de todos para tener un lugar de consulta rápida ante esos momentos "¿y ahora como demonios hago esto?" .

Seguramente existe pero en inglés...

Quizás más adelante podemos hacer un hilo índice con chincheta, que enlace a esto que estais haciendo.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 08, 2015, 22:56:26
Seguramente existe pero en inglés...

Quizás más adelante podemos hacer un hilo índice con chincheta, que enlace a esto que estais haciendo.

Mi intención es recopilar todas las rutinas que se han posteado en el foro donde se enseñe a hacer algo dificil o lo mismo pero de maneras diferentes y poner las nuevas aportaciones para tener un punto de referencia desde donde empezar.

Ya me imagino que en inglés estara todo, pero si lo tenemos en castellano mejor. A mi el inglés me dificulta el aprendizaje. Puedo leerlo pero según como lo redacten se me cruzan los cables y no lo puedo traducir coerentemente y si uso el google translator... me desescojono con las traducciones .
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 08, 2015, 22:58:51
¿Cómo piensas hacerlo? organicemos así queda bien accesible :)
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 08, 2015, 23:16:09
¿Cómo piensas hacerlo? organicemos así queda bien accesible :)

Pues a base de copypaste y poner el link donde está publicado.
Una vez recopiladas ,las ordenaria por orden alfabetico o crearia un índice de consulta con lo que hay recopilado.
¿Alguna sugerencia?.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 08, 2015, 23:23:40
gracias! y muy buena la idea de ir poniendo rutinas aca.

Gracias a vosotros por colgar vuestros trabajos para que nos peleémos con ellos.
Cuando tu programa para manejo de interrupciones esté terminado, lo colgare aqui también.
Si lo documentas con comentarios que faciliten su comprensión mucho mejor  ;)
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 09, 2015, 05:22:11
Si quieres puedes ir haciendolo directamente en un hilo del foro y le pongo chincheta.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 09, 2015, 11:46:24
Si quieres puedes ir haciendolo directamente en un hilo del foro y le pongo chincheta.

Posteado a las 5:22:11... me lo parece a mi o los que tenemos un commodore no dormimos mucho?...  :-\
Somos como vampiros chupa 8 bits  ;D

Que susto me has dado, pensaba que estaba posteando en el privado.
Seguire posteando aqui las rutinas recopiladas y si teneís a bién cambiar algo o chinchetearlo , pues adelante.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 09, 2015, 14:35:59
Posteado a las 5:22:11... me lo parece a mi o los que tenemos un commodore no dormimos mucho?...  :-\
Somos como vampiros chupa 8 bits  ;D

Es que por la noche es cuando hay TRANQUILIDAAAADDDD... eso desde siempre de toda la vida, pero con mujer y cría se nota más.

Y además tener en cuenta que estoy en otro uso horario, hemisferio, continente y universo paralelo...
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Julio 09, 2015, 17:17:44
Quizas tenga sentido poner estas rutinas en macros de ensamblador, y ponerlas todas en un solo archivo.
De esa manera para usuarlas, solo hay que usar ese archivo en tu juego y listo.

La pregunta del millón es que ensamblador usar, ya que cada uno tiene su propio formato de macro :)

Y se podria poner en github ese archivo.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 09, 2015, 23:19:58
Las rutinas que he ido colgando (excepto las de Lobogris) son muy sencillas , solo hacen lo que hacen e implementarlas en un programa usando una macro sin adaptar antes el código no lo veo útil.

Naturalmente , los programas que si se puedan usar como macro si que se podria hacer lo que comentas.

Si alguién mas experto que yo (casi todos   ;)  )  puede modificarlas para ese uso, estaré encantado.

El tema de ensamblador A, B o C si que es un lio. En mis códigos siempre pogo el assembler que he utilizado, arriba del todo. Aunque con práctica, creo que al final los reconoceremos a simple vista, como en Matrix  ;D ;D ;D

Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 10, 2015, 06:43:39
Sere bobo. Con lo que me enseñastes ayer (Riq) , convertirlas para usar como macro es facil .
El problema es la disparidad de ensambladores , pero cada cual se lo tendra que adaptar.

No hay peor ciego que el que no sabe ver. ::)

Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 10, 2015, 14:02:22
Y se podria poner en github ese archivo.

Eso ya es terreno semi-desconocido para mi, pocas veces he tenido que usar algo de esto (subversion) asi que no puedo hacer...
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Mayo 29, 2016, 15:38:41
Hace tiempo que no colgaba nada por aquí y ya tocaba XD.

Gracias a Riq y a sus ejemplos de código he llegado entender como usar las interrupciones (o eso creo XD).

Aquí dejo el código fuente esperando que alguíen me muestre los fallos y como mejorar la rutina.
Es lo más básico necesario para hacerlas funcionar. Solo hace algo raro cuando provocas un ?syntax error, se "clava" un poco y vuelve a la normalidad. Después, por muchos ?Syntax error que hagas, ni se inmuta.

Hacer un NEW antes de introducir lineas basic, si no, se reseteará. ;)

Código: [Seleccionar]
;CBM prg studio.

; 10 SYS32768

*=$0801

        BYTE    $0B, $08, $0A, $00, $9E, $33, $32, $37, $36, $38, $00, $00, $00

*=$8000         ;Coloco el programa aquí para que no se desplace al
                ;entrar lineas de basic.
vector=vect;$0400
        ldx#0
        sta vector

       ; jsr$ff81        ;Limpiar pantalla
        sei                                   
        lda #%00011011  ;27 original. 26 no flickea.Hibyte del raster pero                             
        sta $D011       ;si no es 27 aparecen "pelos" en los bordes pantalla.
        lda #<irq1                         
        sta $0314                           
        lda #>irq1                         
        sta $0315                           
        lda #%00000001  ;#127 en el ejemplo. Basta con activar el timer A #1     
        sta $DC0D       ;Registro control de la cia                   
        lda #1                             
        sta $D01A       ;Registro mascara IRQ activada. IRQ ON.
        cli 
        rts             ;Salida al basic para pruebas.

main    ;El programa empezaria aquí.
        jmp main

irq1
        lda $D019       ;Reset bandera de registro reescribiendo encima su
        sta $D019       ;propio valor de nuevo.Si no, se queda activado y falla.
        ldx vector
        ldy linea,x
        sty $d012
        ldy color,x
        sty $d020
        lda linea+1,x    ;Siguente nuevo valor
        cmp #255
        beq salt0
        inc vector
        jmp $FEBC        ;Saltar a restaurar a partir de la rutina NMI.

salt0
        lda #0
        sta vector
       
        jmp $EA31       ;Rutina interrupcion normal Leer teclado y demás.     

linea   byte $32,$3A,$42,$4A,$52,$5A,$62,$6A,$72,$7A,$82,$8A,$92,$9A,$A2,$AA,$C8,$ff
color   byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f,$00
vect
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Mayo 29, 2016, 15:47:00
Ese Maniako interruptor :-)
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Mayo 29, 2016, 16:40:06
Esa!

No recuerdo haber visto mucho el "JMP $FEBC", pero esta bien lo que haces. Es lo mismo que hacer "JMP $EA81"... nada más que el EA81 es más popular que el FEBC.

El "LDA $D019; STA $D019" lo podes reemplazar por "LDA $D019"... creo que no hace falta el "STA $D019"... solo lo tenes que leer para hacer el "ack" de la interrupción.

Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Mayo 29, 2016, 18:13:35
Entonces están bien así?. No sabes la ilusión que me hace poder utilizarlas por fin jejeje.
Hay que escribir en D019 para limpiar la bandera de la interrupción. Si no, no funciona.
Pasa lo mismo que con los sprites creo recordar.

He probado con $EA81 y funciona igual. Usaré EA81 ya que es más fácil de recordar.
$EA31 y $EA81.
NMI no dar de comer al 3.
IRQ dar de comer al 3.
 ;D

Ahora a hacer scroll fuera del barrido de pantalla o mover los caracteres justo cuando el barrido sobrepase la zona donde se muestren para ganar tiempo de proceso.
Me queda aun mucho trabajo.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Mayo 29, 2016, 18:18:10
Ese Maniako interruptor :-)

No queriais programadores?. Pues en eso estoy.   :P

Cuando domine todas estas cosas y me vea preparado, veremos si podemos modificar los juegos multicarga y pasarlos a lo que se necesite. Aún me queda mucho trabajo. :-[
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Mayo 29, 2016, 19:12:16
Hay que escribir en D019 para limpiar la bandera de la interrupción. Si no, no funciona.
Pasa lo mismo que con los sprites creo recordar.

Si, creo que tenez razón. Me estaba confundiendo con limpiar los timers CIA.
Yo uso "ASL $D019" en vez de "LDA $D019; STA $D019", y me sirve también para saber si la IRQ fue generada por raster o no.
Viendo código viejo mio (el de los 90s), veo que también usaba el "LDA $D019; STA $D019;".
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 12, 2016, 13:09:30
Despues de muchas pruebas con scroll de pantalla (sin scroll fino), he comprobado que al pobrecillo C64 le cuesta mucho esfuerzo mover 1000 caracteres de un sitio a otro.

Se pueden hacer rutinas cortas usando bucles, pero este modo crea frenos ya que hay que modificar valores, hacer comparaciones y saltar de nuevo para seguir trasladando caracteres.

Otra manera (para mi la mejor) es UNLOOP´ear XD. Riq me aconsejo sobre ello pero hasta que no hice pruebas, no me dí cuenta de lo que come en tiempo de proceso.

Aquí dejo tres ejemplos de código, uno con LOOPS y dos sin.
***********************************************************************
LOOPS:
Código: [Seleccionar]
;CBM prg STUDIO
;Scroll linea a linea . Solo mueve una linea cada vez que se llama.
;Intento de hacer scroll moviendo la linea que el raster acaba de mostrar
;para asi, aprovechar al máximo
;Lo le he puesto interrupciones por que aún es mas lento XD

; 10 SYS (4096)

*=$801

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


*=$1000
;
reset   lda #25
        sta ctrlinea
 
loop    ldx #39         ;#39 es el valor correcto

poke1   lda $0401
poke2   sta $0400
        jsr recoloca    ;Pasamos al siguiente caractera leer y pokear


pasa1   dex
        bne poke1
         
;Como es final de linea, dejamos lista la siguiente...
        lda poke2+1
        sta poke3+1
        lda poke2+2
        sta poke3+2
        lda $d012       ;Datos aleatorios tomados del raster
poke3   sta $0400       ;Y pokeados el final de la fila
       
       
        jsr recoloca    ;... deja lista la siguiente linea XD

;Una vez terminada la última linea de pantalla, puesta a cero de los vectores y vuelta a empezar.
;Puede ir fuera en la memoria normal. (fuera de la pag cero)
        dec ctrlinea
        bne fin
        lda #04
        sta poke1+2     ;HI
        sta poke2+2     ;HI
        lda #00
        sta poke2+1     ;LO
        lda #01
        sta poke1+1     ;LO
        jmp reset





fin     jmp loop        ;Deberia ser un RTS si la usas con JSR. En esta prueba
                        ;lo puse en loop continuo

;Rutina aumenta vectores de lectura/escritura de los caracteres de la linea.
recoloca
        inc poke1+1     ;LO
        bne pasa2
        inc poke1+2     ;HI
pasa2   inc poke2+1     ;LO
        bne pasa3
        inc poke2+2     ;HI
pasa3   rts


ctrlinea
*******************************************************************
UNLOOP:
Código: [Seleccionar]
;CBM prg STUDIO
;Esta forma es mucho mas rápida que un loop. Mucho mas.
; 10 SYS (4096)

*=$801

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

*=$1000

;Moviendo de der a izq.
main    ldx #01
        ldy #00

loop1   jsr move
        inx
        iny
        txa
        cmp #40
        beq fin

        jmp loop1

fin     jsr chars
;loop2   lda $d012       ;Bucle freno
;        bne loop2
        jmp main ;rts

;Rutina mover 8x8 pixels
move    ;X=Lectura. Y=Escritura.
        lda $0400,x
        sta $0400,y
        lda $0428,x
        sta $0428,y
        lda $0450,x
        sta $0450,y
        lda $0478,x
        sta $0478,y
        lda $04a0,x
        sta $04a0,y
        lda $04c8,x
        sta $04c8,y
        lda $04f0,x
        sta $04f0,y
        lda $0518,x
        sta $0518,y
        lda $0540,x
        sta $0540,y
        lda $0568,x
        sta $0568,y
        lda $0590,x
        sta $0590,y
        lda $05b8,x
        sta $05b8,y
        lda $05e0,x
        sta $05e0,y
        lda $0608,x
        sta $0608,y
        lda $0630,x
        sta $0630,y
        lda $0658,x
        sta $0658,y
        lda $0680,x
        sta $0680,y
        lda $06a8,x
        sta $06a8,y
        lda $06d0,x
        sta $06d0,y
        lda $06f8,x
        sta $06f8,y
        lda $0720,x
        sta $0720,y
        lda $0748,x
        sta $0748,y
        lda $0770,x
        sta $0770,y
        lda $0798,x
        sta $0798,y
        lda $07c0,x
        sta $07c0,y
        rts

;Rutina poner caracteres aleatorios a la derecha de la mantalla para ver como se desplaza
chars
        lda $d012
        sta $0427
        sta $044f
        sta $0477
        sta $049f
        sta $04c7
        sta $04ef
        sta $0517
        sta $053f
        sta $0567
        sta $058f
        sta $05b7
        sta $05df
        sta $0607
        sta $062f
        sta $0657
        sta $067f
        sta $06a7
        sta $06cf
        sta $06f7
        sta $071f
        sta $0747
        sta $076f
        sta $0797
        sta $07bf
        sta $07e7
        rts
**********************************************************************
UNLOOPS con IRQ:
Código: [Seleccionar]
;CBM prg STUDIO
;Pruebas de scroll de caracteres de la pantalla.El color negro es el tiempo que lleva
;ejecutar el desplazamiento de los caracteres un caracter hacia la izquierda.
;En lugar de desplazar la pantalla desde la misma interrupción, uso la interrupción para
;dar permiso al programa para desplazar los caracteres.
;No sé si me explico bién XD. Si es incorrecto hacerlo así,  no lo se, pero alargar el
;tiempo de la interrupción me parece incorrecto.
;De toda manera es un experimento para mejorar y aprender. A trastear señor@s.
;Si alguno averigua como acelerar esto aun más, que no se corte y lo diga. Grácias.
; 10 SYS (4096)

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

permiso=$FB     ;Usando pag cero para ahorrar ciclos (1) XD

*=$1000         ;Coloco el programa aquí para que no se desplace al
                ;entrar lineas de basic.

        jsr $ff81       ;Limpiar pantalla.
        sei             ;Desactivando interrupciones.                       
        lda #%00011011  ;27 original. 26 no flickea.Hibyte del raster pero                             
        sta $D011       ;si no es 27 aparecen "pelos" en los bordes pantalla.
        lda #<irq1                         
        sta $0314                           
        lda #>irq1                           
        sta $0315                           
        lda #%00000001  ;#127 en el ejemplo. Basta con activar el timer A #1     
        sta $DC0D       ;Registro control de la cia                   
        lda #1                             
        sta $D01A       ;Registro mascara IRQ activada. IRQ ON.
        cli             ;Conectando interrupciones.
        lda #230        ;#230 Linea del raster que activara el movimiento scroll
        sta $d012
        jsr random      ;Activa el SID para generar numeros aleatorios

main
        lda permiso     ;Tengo permiso para scroll?
        beq main        ;No, pues a esperar...
        ldx #02    ;De derecha a izq, no hace falta dibujar el ultimo caracter
        ldy #01    ;ya que queda por detras de el marco en pantalla de 38 caracteres.

        lda #0          ;Color negro para visionar tiempo
        sta $d020       ;es borrable 100% y ganamos ciclos.
loop1
        jsr move        ;Moviendo toda una columna
        inx
        iny
        cpx #40
        beq fin
        jmp loop1
fin
        jsr newchars
        lda #2          ;Color rojo para visionar tiempo
        sta $d020       ;Es borrable 100% y ganamos ciclos.
        lda #0          ;Desconectando el scroll .
        sta permiso
        jmp main        ;Vuelta al ruedo XD
irq1     
        asl $D019       ;Reset IRQ.ASL es consejo de Riq.Si no, se queda activado y falla.
        bcc salt0       ;Acarreo OFF? Salt0
sigue
        lda #1          ;Activando scroll desde las interrupciones para que se
        sta permiso     ;ejecuten fuera de las mismas.
        jmp $EA81       ;FEBC ;Saltar a restaurar a partir de la rutina NMI.
salt0
        jmp $EA7b ;$EA31       ;Rutina interrupcion normal Leer teclado, cursor y demás.     


;Rutina mover un caracter a la izq. Se puede usar en ambas direcciones jugando
;con X e Y.

move    ;X=Lectura. Y=Escritura.
;Aqui estan desconectadas las lineas que no interesan.
;Conectad y desconectad a placer para experimetar.
;Podreis ver lo que llega a consumir el mover 1000 caracteres.

;        lda $0400,x    ;Primera linea
;        sta $0400,y    ;Primera linea
        lda $0428,x     ;Segunda linea
        sta $0428,y     ;Segunda linea
        lda $0450,x     ;Tercera linea
        sta $0450,y     ;Tercera linea
        lda $0478,x     ;etc...
        sta $0478,y
        lda $04a0,x
        sta $04a0,y
        lda $04c8,x
        sta $04c8,y
        lda $04f0,x
        sta $04f0,y
        lda $0518,x
        sta $0518,y
        lda $0540,x
        sta $0540,y
        lda $0568,x
        sta $0568,y
        lda $0590,x
        sta $0590,y
        lda $05b8,x
        sta $05b8,y
        lda $05e0,x
        sta $05e0,y
        lda $0608,x
        sta $0608,y
        lda $0630,x
        sta $0630,y
        lda $0658,x
        sta $0658,y
        lda $0680,x
        sta $0680,y
        lda $06a8,x
        sta $06a8,y
        lda $06d0,x
        sta $06d0,y
        lda $06f8,x
        sta $06f8,y
        lda $0720,x
        sta $0720,y
        lda $0748,x
        sta $0748,y
        lda $0770,x
        sta $0770,y
 ;       lda $0798,x
 ;       sta $0798,y
 ;       lda $07c0,x
 ;       sta $07c0,y
        rts

;Rutina poner caracteres aleatorios a la derecha de la pantalla para ver como se desplaza.
newchars

;Leer valor aleatorio creado por el SID. Esto seria el siguiente caracter a mostrar del
;nivel del juego que andeis haciendo. Yo uso basura para ahorrar trabajo durante las pruebas XD
        LDA $D41B       ;Leyendo random del SID       
;Aqui estan desconectadas las lineas que no interesan.
;Conectad y desconectad a placer para experimentar.
;        sta $0427      ;Primera linea.
        sta $044f       ;Segunda linea.
        sta $0477       ;Tercera linea.
        sta $049f       ;etc...
        sta $04c7
        sta $04ef
        sta $0517
        sta $053f
        sta $0567
        sta $058f
        sta $05b7
        sta $05df
        sta $0607
        sta $062f
        sta $0657
        sta $067f
        sta $06a7
        sta $06cf
        sta $06f7
        sta $071f
        sta $0747
        sta $076f
        sta $0797
;        sta $07bf
;        sta $07e7
        rts

;Activar random usando el SID

random  LDA #$FF  ; maximum frequency value
        STA $D40E ; voice 3 frequency low byte
        STA $D40F ; voice 3 frequency high byte
        LDA #$80  ; noise waveform, gate bit off
        STA $D412 ; voice 3 control register
        RTS





Como podeis ver, sin loops hace que el programa crezca en tamaño, pero la velocidad bién lo vale.

Dejo los programas ya compilados para que podais abrirlos todos a la vez y apreciar la gran diferencia. Lo interesante es la que usa IRQ, mover la pantalla sin deformidades es esencial para cualquier juego y para eso, hay que moverla cuando el barrido de pantalla no esté un la "zona visual".

Si se desea mover toda la pantalla, se pueden usar técnicas de doble buffer como la descrita en este link:

http://1amstudios.com/2014/12/07/c64-smooth-scrolling/ (http://1amstudios.com/2014/12/07/c64-smooth-scrolling/)

En este otro link en el parrafo  Loop Unrolling hay una explicación con calculos de tiempo de procesos que lo deja bien claro.

http://www.antimon.org/code/Linus/demo_prog.html#SECTION000121000000000000000 (http://www.antimon.org/code/Linus/demo_prog.html#SECTION000121000000000000000)

Pero hasta que no haga pruebas con el double buffering, no comento XD.

Espero que os sea útil y didactico. Mi intención es incentivaros a trastear en CM y echar una mano para aprender comprendiendo, para mí algo esencial.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Junio 12, 2016, 15:01:49
¿El último parece ser el que va mejor no?
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 12, 2016, 15:14:58
Se ve mejor por que uso las IRQ para que no haga extraños , no como en el segundo ejemplo UNLOOP que no usa interrupciones y se ven los flicks. Va más deprisa moviendo pero se vé mal.


Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 12, 2016, 23:58:10
Yastoyotravez.

Una vez le vas cogiendo el gusanillo a programar, cuesta dejarlo.
Reconozco que me ha costado arrancar y recordar métodos y demás técnicas para crear los programas.

Aquí dejo otra pequeña rutina donde muevo un mapa de 64 caractéres, del 0 al 63.
Uso un tamaño de mapa que me premita controlar los limites con un simple AND#63, de esta manera consigues devolver a 0 el vector de lectura del mapa.

Basta de rollos, aquí dejo la rutina para que la destripeís y la mejoreís ahí donde no llego o no veo.

Código: [Seleccionar]
;CBM prg STUDIO
;Scroll de una pantalla de 64 caracteres (0-63) en multicolor.
;Sin scroll fino. Solo probando tamaños de mapas para futuras pantallas de 127 o 256
;caracteres.
;En $3800 estan los caracteres programables
;En $4000 el mapa en sí.
;Para encontrar el principio de cada linea, solo hay que ir sumandole #64 cada
;vez para poder leerla sin problemas.
;He escogido este tamaño para con simplemente un AND poder controlar el bucle sin fin.
;El mapa y los caracteres se han editado con VChar64 0.013. Muy practica.
;La proxima le meto scroll fino y a la siguiente, moverse en ambas direcciones en el eje X.

; 10 SYS4096

*=$0801

        BYTE    $0B, $08, $0A, $00, $9E, $34, $30, $39, $36, $00, $00, $00

vectscroll byte $00     ;Vector de lectura para el mapa.

*=$1000
        jsr $ff81       ;Limpiar pantala
        lda #15+16      ;Cambio vector punteros programables $3800
        sta $D018       ; #53272
 
        lda $d016       ;Multicolor ON
        ora #16
        sta $d016       ; #53270

        lda #0          ;Fondo negro

        sta $d021
        lda #9          ;Color 1 marrón
        sta $d022       ;#53282

        lda #13         ;Color 2 verde claro
        sta $d023       ;#53283

        lda #5         ;Verde coscuro
        sta $d800       ;#55296

;Ram de color. Solo una vez ya que no altero su valor.
        lda #13
        ldx #39
buc4    sta $da08,x     
        sta $da30,x     
        sta $da58,x     
        sta $da80,x     
        sta $daa8,x     
        sta $dad0,x     
        sta $daf8,x     
        sta $db20,x     
        sta $db48,x     
        sta $db70,x
        dex
        bpl buc4

loop2   ldy vectscroll  ;Se va sumando hasta llegar al final del mapa y vuelta a empezar
        ldx #0 ;Escritura en ram de pantalla.
loop1
;Ram pantalla
        lda $4000,y
        sta $0608,x
        lda $4040,y
        sta $0630,x
        lda $4080,y
        sta $0658,x
        lda $40c0,y
        sta $0680,x
        lda $4100,y
        sta $06a8,x
        lda $4140,y
        sta $06d0,x
        lda $4180,y
        sta $06f8,x
        lda $41c0,y
        sta $0720,x
        lda $4200,y
        sta $0748,x
        lda $4240,y
        sta $0770,x

        iny             ;Al registro Y lo pongo a cero cuando llega al final del mapa
        tya             ;y así, empieza a leer desde el principio otra vez.
        and #63         
        tay

        inx
        cpx #40         ;He llegado al final de la pantalla?
        bne loop1       ;No, pues a seguir

        inc vectscroll  ;Como he llegado al final, incremento el vector de lectura
        lda vectscroll  ;Y le hago un AND 63 para devolverlo a 0
        and #63        ;si es mayor que 63
        sta vectscroll  ;y lo guardo.

pasa0   lda $d012       ;Bucle de raster.
        bne pasa0       ;para frenar esto un poco y eliminar flick sin usar interrupciones de la manera clasica XD
        jmp loop2

*=$3800 ;Caracteres programables.
          BYTE $3C,$66,$6E,$6E,$60,$62,$3C,$00,$18,$3C,$66,$7E,$66,$66,$66,$00,$7C,$66
          BYTE $66,$7C,$66,$66,$7C,$00,$3C,$66,$60,$60,$60,$66,$3C,$00,$78,$6C,$66,$66,$66,$6C
          BYTE $78,$00,$7E,$60,$60,$78,$60,$60,$7E,$00,$7E,$60,$60,$78,$60,$60,$60,$00,$3C,$66
          BYTE $60,$6E,$66,$66,$3C,$00,$66,$66,$66,$7E,$66,$66,$66,$00,$3C,$18,$18,$18,$18,$18
          BYTE $3C,$00,$1E,$0C,$0C,$0C,$0C,$6C,$38,$00,$66,$6C,$78,$70,$78,$6C,$66,$00,$60,$60
          BYTE $60,$60,$60,$60,$7E,$00,$63,$77,$7F,$6B,$63,$63,$63,$00,$66,$76,$7E,$7E,$6E,$66
          BYTE $66,$00,$3C,$66,$66,$66,$66,$66,$3C,$00,$7C,$66,$66,$7C,$60,$60,$60,$00,$3C,$66
          BYTE $66,$66,$66,$3C,$0E,$00,$7C,$66,$66,$7C,$78,$6C,$66,$00,$3C,$66,$60,$3C,$06,$66
          BYTE $3C,$00,$7E,$18,$18,$18,$18,$18,$18,$00,$66,$66,$66,$66,$66,$66,$3C,$00,$66,$66
          BYTE $66,$66,$66,$3C,$18,$00,$63,$63,$63,$6B,$7F,$77,$63,$00,$66,$66,$3C,$18,$3C,$66
          BYTE $66,$00,$66,$66,$66,$3C,$18,$18,$18,$00,$7E,$06,$0C,$18,$30,$60,$7E,$00,$3C,$30
          BYTE $30,$30,$30,$30,$3C,$00,$0C,$12,$30,$7C,$30,$62,$FC,$00,$3C,$0C,$0C,$0C,$0C,$0C
          BYTE $3C,$00,$00,$18,$3C,$7E,$18,$18,$18,$18,$00,$10,$30,$7F,$7F,$30,$10,$00,$00,$00
          BYTE $00,$00,$00,$00,$00,$00,$18,$18,$18,$18,$00,$00,$18,$00,$66,$66,$66,$00,$00,$00
          BYTE $00,$00,$66,$66,$FF,$66,$FF,$66,$66,$00,$18,$3E,$60,$3C,$06,$7C,$18,$00,$62,$66
          BYTE $0C,$18,$30,$66,$46,$00,$3C,$66,$3C,$38,$67,$66,$3F,$00,$06,$0C,$18,$00,$00,$00
          BYTE $00,$00,$0C,$18,$30,$30,$30,$18,$0C,$00,$30,$18,$0C,$0C,$0C,$18,$30,$00,$00,$66
          BYTE $3C,$FF,$3C,$66,$00,$00,$00,$18,$18,$7E,$18,$18,$00,$00,$00,$00,$00,$00,$00,$18
          BYTE $18,$30,$00,$00,$00,$7E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$18,$00,$00,$03
          BYTE $06,$0C,$18,$30,$60,$00,$3C,$66,$6E,$76,$66,$66,$3C,$00,$18,$18,$38,$18,$18,$18
          BYTE $7E,$00,$3C,$66,$06,$0C,$30,$60,$7E,$00,$3C,$66,$06,$1C,$06,$66,$3C,$00,$06,$0E
          BYTE $1E,$66,$7F,$06,$06,$00,$7E,$60,$7C,$06,$06,$66,$3C,$00,$3C,$66,$60,$7C,$66,$66
          BYTE $3C,$00,$7E,$66,$0C,$18,$18,$18,$18,$00,$3C,$66,$66,$3C,$66,$66,$3C,$00,$3C,$66
          BYTE $66,$3E,$06,$66,$3C,$00,$00,$00,$18,$00,$00,$18,$00,$00,$00,$00,$18,$00,$00,$18
          BYTE $18,$30,$0E,$18,$30,$60,$30,$18,$0E,$00,$00,$00,$7E,$00,$7E,$00,$00,$00,$70,$18
          BYTE $0C,$06,$0C,$18,$70,$00,$3C,$66,$06,$0C,$18,$00,$18,$00,$EF,$FE,$55,$55,$55,$55
          BYTE $55,$55,$55,$55,$55,$55,$55,$55,$55,$55,$03,$03,$03,$03,$03,$03,$03,$03,$C0,$C0
          BYTE $C0,$C0,$C0,$C0,$C0,$C0,$FE,$BF,$FB,$EF,$BD,$75,$55,$55,$BE,$FB,$BF,$FB,$7E,$5F
          BYTE $55,$55,$00,$03,$0D,$0D,$35,$35,$35,$D5,$C0,$F0,$F0,$70,$7C,$57,$57,$57,$5F,$5F
          BYTE $5F,$5C,$5C,$7C,$7C,$FC,$00,$00,$00,$E0,$F0,$38,$18,$18,$18,$18,$1C,$0F,$07,$00
          BYTE $00,$00,$18,$18,$38,$F0,$E0,$00,$00,$00,$C0,$C0,$C0,$C0,$C0,$C0,$FF,$FF,$C0,$E0
          BYTE $70,$38,$1C,$0E,$07,$03,$03,$07,$0E,$1C,$38,$70,$E0,$C0,$FF,$FF,$C0,$C0,$C0,$C0
          BYTE $C0,$C0,$FF,$FF,$03,$03,$03,$03,$03,$03,$00,$3C,$7E,$7E,$7E,$7E,$3C,$00,$00,$00
          BYTE $00,$00,$00,$FF,$FF,$00,$36,$7F,$7F,$7F,$3E,$1C,$08,$00,$60,$60,$60,$60,$60,$60
          BYTE $60,$60,$00,$00,$00,$07,$0F,$1C,$18,$18,$C3,$E7,$7E,$3C,$3C,$7E,$E7,$C3,$00,$3C
          BYTE $7E,$66,$66,$7E,$3C,$00,$18,$18,$66,$66,$18,$18,$3C,$00,$06,$06,$06,$06,$06,$06
          BYTE $06,$06,$08,$1C,$3E,$7F,$3E,$1C,$08,$00,$18,$18,$18,$FF,$FF,$18,$18,$18,$C0,$C0
          BYTE $30,$30,$C0,$C0,$30,$30,$18,$18,$18,$18,$18,$18,$18,$18,$00,$00,$03,$3E,$76,$36
          BYTE $36,$00,$FF,$7F,$3F,$1F,$0F,$07,$03,$01,$00,$00,$00,$00,$00,$00,$00,$00,$F0,$F0
          BYTE $F0,$F0,$F0,$F0,$F0,$F0,$00,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$00
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$CC,$CC
          BYTE $33,$33,$CC,$CC,$33,$33,$03,$03,$03,$03,$03,$03,$03,$03,$00,$00,$00,$00,$CC,$CC
          BYTE $33,$33,$FF,$FE,$FC,$F8,$F0,$E0,$C0,$80,$03,$03,$03,$03,$03,$03,$03,$03,$18,$18
          BYTE $18,$1F,$1F,$18,$18,$18,$00,$00,$00,$00,$0F,$0F,$0F,$0F,$18,$18,$18,$1F,$1F,$00
          BYTE $00,$00,$00,$00,$00,$F8,$F8,$18,$18,$18,$00,$00,$00,$00,$00,$00,$FF,$FF,$00,$00
          BYTE $00,$1F,$1F,$18,$18,$18,$18,$18,$18,$FF,$FF,$00,$00,$00,$00,$00,$00,$FF,$FF,$18
          BYTE $18,$18,$18,$18,$18,$F8,$F8,$18,$18,$18,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$E0,$E0
          BYTE $E0,$E0,$E0,$E0,$E0,$E0,$07,$07,$07,$07,$07,$07,$07,$07,$FF,$FF,$00,$00,$00,$00
          BYTE $00,$00,$FF,$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,$FF,$03,$03
          BYTE $03,$03,$03,$03,$FF,$FF,$00,$00,$00,$00,$F0,$F0,$F0,$F0,$0F,$0F,$0F,$0F,$00,$00
          BYTE $00,$00,$18,$18,$18,$F8,$F8,$00,$00,$00,$F0,$F0,$F0,$F0,$00,$00,$00,$00,$F0,$F0
          BYTE $F0,$F0,$0F,$0F,$0F,$0F,$C3,$99,$91,$91,$9F,$99,$C3,$FF,$E7,$C3,$99,$81,$99,$99
          BYTE $99,$FF,$83,$99,$99,$83,$99,$99,$83,$FF,$C3,$99,$9F,$9F,$9F,$99,$C3,$FF,$87,$93
          BYTE $99,$99,$99,$93,$87,$FF,$81,$9F,$9F,$87,$9F,$9F,$81,$FF,$81,$9F,$9F,$87,$9F,$9F
          BYTE $9F,$FF,$C3,$99,$9F,$91,$99,$99,$C3,$FF,$99,$99,$99,$81,$99,$99,$99,$FF,$C3,$E7
          BYTE $E7,$E7,$E7,$E7,$C3,$FF,$E1,$F3,$F3,$F3,$F3,$93,$C7,$FF,$99,$93,$87,$8F,$87,$93
          BYTE $99,$FF,$9F,$9F,$9F,$9F,$9F,$9F,$81,$FF,$9C,$88,$80,$94,$9C,$9C,$9C,$FF,$99,$89
          BYTE $81,$81,$91,$99,$99,$FF,$C3,$99,$99,$99,$99,$99,$C3,$FF,$83,$99,$99,$83,$9F,$9F
          BYTE $9F,$FF,$C3,$99,$99,$99,$99,$C3,$F1,$FF,$83,$99,$99,$83,$87,$93,$99,$FF,$C3,$99
          BYTE $9F,$C3,$F9,$99,$C3,$FF,$81,$E7,$E7,$E7,$E7,$E7,$E7,$FF,$99,$99,$99,$99,$99,$99
          BYTE $C3,$FF,$99,$99,$99,$99,$99,$C3,$E7,$FF,$9C,$9C,$9C,$94,$80,$88,$9C,$FF,$99,$99
          BYTE $C3,$E7,$C3,$99,$99,$FF,$99,$99,$99,$C3,$E7,$E7,$E7,$FF,$81,$F9,$F3,$E7,$CF,$9F
          BYTE $81,$FF,$C3,$CF,$CF,$CF,$CF,$CF,$C3,$FF,$F3,$ED,$CF,$83,$CF,$9D,$03,$FF,$C3,$F3
          BYTE $F3,$F3,$F3,$F3,$C3,$FF,$FF,$E7,$C3,$81,$E7,$E7,$E7,$E7,$FF,$EF,$CF,$80,$80,$CF
          BYTE $EF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$E7,$E7,$E7,$E7,$FF,$FF,$E7,$FF,$99,$99
          BYTE $99,$FF,$FF,$FF,$FF,$FF,$99,$99,$00,$99,$00,$99,$99,$FF,$E7,$C1,$9F,$C3,$F9,$83
          BYTE $E7,$FF,$9D,$99,$F3,$E7,$CF,$99,$B9,$FF,$C3,$99,$C3,$C7,$98,$99,$C0,$FF,$F9,$F3
          BYTE $E7,$FF,$FF,$FF,$FF,$FF,$F3,$E7,$CF,$CF,$CF,$E7,$F3,$FF,$CF,$E7,$F3,$F3,$F3,$E7
          BYTE $CF,$FF,$FF,$99,$C3,$00,$C3,$99,$FF,$FF,$FF,$E7,$E7,$81,$E7,$E7,$FF,$FF,$FF,$FF
          BYTE $FF,$FF,$FF,$E7,$E7,$CF,$FF,$FF,$FF,$81,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$E7
          BYTE $E7,$FF,$FF,$FC,$F9,$F3,$E7,$CF,$9F,$FF,$C3,$99,$91,$89,$99,$99,$C3,$FF,$E7,$E7
          BYTE $C7,$E7,$E7,$E7,$81,$FF,$C3,$99,$F9,$F3,$CF,$9F,$81,$FF,$C3,$99,$F9,$E3,$F9,$99
          BYTE $C3,$FF,$F9,$F1,$E1,$99,$80,$F9,$F9,$FF,$81,$9F,$83,$F9,$F9,$99,$C3,$FF,$C3,$99
          BYTE $9F,$83,$99,$99,$C3,$FF,$81,$99,$F3,$E7,$E7,$E7,$E7,$FF,$C3,$99,$99,$C3,$99,$99
          BYTE $C3,$FF,$C3,$99,$99,$C1,$F9,$99,$C3,$FF,$FF,$FF,$E7,$FF,$FF,$E7,$FF,$FF,$FF,$FF
          BYTE $E7,$FF,$FF,$E7,$E7,$CF,$F1,$E7,$CF,$9F,$CF,$E7,$F1,$FF,$FF,$FF,$81,$FF,$81,$FF
          BYTE $FF,$FF,$8F,$E7,$F3,$F9,$F3,$E7,$8F,$FF,$C3,$99,$F9,$F3,$E7,$FF,$E7,$FF,$FF,$FF
          BYTE $FF,$00,$00,$FF,$FF,$FF,$F7,$E3,$C1,$80,$80,$E3,$C1,$FF,$E7,$E7,$E7,$E7,$E7,$E7
          BYTE $E7,$E7,$FF,$FF,$FF,$00,$00,$FF,$FF,$FF,$FF,$FF,$00,$00,$FF,$FF,$FF,$FF,$FF,$00
          BYTE $00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$FF,$FF,$CF,$CF,$CF,$CF,$CF,$CF
          BYTE $CF,$CF,$F3,$F3,$F3,$F3,$F3,$F3,$F3,$F3,$FF,$FF,$FF,$1F,$0F,$C7,$E7,$E7,$E7,$E7
          BYTE $E3,$F0,$F8,$FF,$FF,$FF,$E7,$E7,$C7,$0F,$1F,$FF,$FF,$FF,$3F,$3F,$3F,$3F,$3F,$3F
          BYTE $00,$00,$3F,$1F,$8F,$C7,$E3,$F1,$F8,$FC,$FC,$F8,$F1,$E3,$C7,$8F,$1F,$3F,$00,$00
          BYTE $3F,$3F,$3F,$3F,$3F,$3F,$00,$00,$FC,$FC,$FC,$FC,$FC,$FC,$FF,$C3,$81,$81,$81,$81
          BYTE $C3,$FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$FF,$C9,$80,$80,$80,$C1,$E3,$F7,$FF,$9F,$9F
          BYTE $9F,$9F,$9F,$9F,$9F,$9F,$FF,$FF,$FF,$F8,$F0,$E3,$E7,$E7,$3C,$18,$81,$C3,$C3,$81
          BYTE $18,$3C,$FF,$C3,$81,$99,$99,$81,$C3,$FF,$E7,$E7,$99,$99,$E7,$E7,$C3,$FF,$F9,$F9
          BYTE $F9,$F9,$F9,$F9,$F9,$F9,$F7,$E3,$C1,$80,$C1,$E3,$F7,$FF,$E7,$E7,$E7,$00,$00,$E7
          BYTE $E7,$E7,$3F,$3F,$CF,$CF,$3F,$3F,$CF,$CF,$E7,$E7,$E7,$E7,$E7,$E7,$E7,$E7,$FF,$FF
          BYTE $FC,$C1,$89,$C9,$C9,$FF,$00,$80,$C0,$E0,$F0,$F8,$FC,$FE,$FF,$FF,$FF,$FF,$FF,$FF
          BYTE $FF,$FF,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$0F,$FF,$FF,$FF,$FF,$00,$00,$00,$00,$00,$FF
          BYTE $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00,$3F,$3F,$3F,$3F,$3F,$3F
          BYTE $3F,$3F,$33,$33,$CC,$CC,$33,$33,$CC,$CC,$FC,$FC,$FC,$FC,$FC,$FC,$FC,$FC,$FF,$FF
          BYTE $FF,$FF,$33,$33,$CC,$CC,$00,$01,$03,$07,$0F,$1F,$3F,$7F,$FC,$FC,$FC,$FC,$FC,$FC
          BYTE $FC,$FC,$E7,$E7,$E7,$E0,$E0,$E7,$E7,$E7,$FF,$FF,$FF,$FF,$F0,$F0,$F0,$F0,$E7,$E7
          BYTE $E7,$E0,$E0,$FF,$FF,$FF,$FF,$FF,$FF,$07,$07,$E7,$E7,$E7,$FF,$FF,$FF,$FF,$FF,$FF
          BYTE $00,$00,$FF,$FF,$FF,$E0,$E0,$E7,$E7,$E7,$E7,$E7,$E7,$00,$00,$FF,$FF,$FF,$FF,$FF
          BYTE $FF,$00,$00,$E7,$E7,$E7,$E7,$E7,$E7,$07,$07,$E7,$E7,$E7,$3F,$3F,$3F,$3F,$3F,$3F
          BYTE $3F,$3F,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$F8,$F8,$F8,$F8,$F8,$F8,$F8,$F8,$00,$00
          BYTE $FF,$FF,$FF,$FF,$FF,$FF,$00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$00
          BYTE $00,$00,$FC,$FC,$FC,$FC,$FC,$FC,$00,$00,$FF,$FF,$FF,$FF,$0F,$0F,$0F,$0F,$F0,$F0
          BYTE $F0,$F0,$FF,$FF,$FF,$FF,$E7,$E7,$E7,$07,$07,$FF,$FF,$FF,$0F,$0F,$0F,$0F,$FF,$FF
          BYTE $FF,$FF,$0F,$0F,$0F,$0F,$F0,$F0,$F0,$F0
 

*=$4000 ;Mapa a mostrar 63x10 caracteres

          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$46,$45,$44,$47,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$46,$41,$41,$41,$41,$47,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$46,$44,$47,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$46,$41,$41,$41,$41,$41
          BYTE $41,$47,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$42,$41,$41,$41,$47,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$46,$41,$41
          BYTE $41,$41,$41,$41,$41,$41,$47,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$46,$40,$41,$41,$41,$48,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $46,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$47,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$42,$41,$41,$41,$41,$48
          BYTE $20,$20,$20,$20,$20,$20,$20,$46,$45,$47,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$46,$41,$41,$41,$41,$41,$41,$41,$41,$44,$44,$44,$44,$44,$44,$47,$20
          BYTE $20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$46,$40,$40,$41
          BYTE $41,$41,$48,$20,$20,$20,$20,$20,$20,$20,$46,$41,$41,$41,$47,$20,$20,$20,$46,$40
          BYTE $47,$20,$20,$20,$20,$20,$42,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41
          BYTE $41,$41,$48,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$42
          BYTE $41,$41,$41,$41,$41,$48,$20,$20,$20,$20,$20,$20,$46,$40,$41,$41,$41,$41,$41,$47
          BYTE $20,$46,$41,$41,$41,$47,$20,$20,$20,$20,$46,$41,$41,$41,$41,$41,$41,$41,$41,$41
          BYTE $41,$41,$41,$41,$41,$41,$47,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20,$20
          BYTE $20,$20,$20,$42,$41,$41,$41,$41,$41,$47,$20,$20,$20,$20,$20,$46,$41,$41,$41,$41
          BYTE $41,$41,$41,$41,$44,$41,$41,$41,$41,$41,$47,$20,$20,$46,$41,$41,$41,$41,$41,$41
          BYTE $41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$47,$20,$20,$20,$20,$20,$20,$44,$45
          BYTE $44,$45,$44,$44,$44,$45,$44,$45,$44,$45,$44,$45,$44,$45,$44,$45,$44,$44,$44,$45
          BYTE $44,$45,$45,$45,$44,$45,$44,$45,$44,$45,$44,$44,$45,$45,$44,$45,$44,$44,$44,$45
          BYTE $44,$45,$44,$45,$44,$45,$44,$45,$45,$45,$44,$45,$44,$45,$44,$45,$44,$45,$44,$45
          BYTE $44,$45

Seguiré colgando mis avances. Espero que le sea util a alguién XD
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 14, 2016, 10:37:22
Solo hace algo raro cuando provocas un ?syntax error, se "clava" un poco y vuelve a la normalidad. Después, por muchos ?Syntax error que hagas, ni se inmuta.


He leido que eso lo hace al recolocar la memoria basic, al parecer reclama espacio. No se el por qué si ya sabe el tamaño de la única linea de basic.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Dashiad en Junio 14, 2016, 11:33:46
Maniako,
Comentas que:
Citar
Lo interesante es la que usa IRQ, mover la pantalla sin deformidades es esencial para cualquier juego y para eso, hay que moverla cuando el barrido de pantalla no esté un la "zona visual".
Corrigeme si me equivoco: lo que no debe pasar, es que el raster intercepte una zona de la pantalla que se está cambiando en ese momento, cierto?
Es decir, si hablamos de caracteres: una vez que el raster ha pasado por la primera fila de caracteres, debería ser posible cambiarla sin que hubiera flicker. Mientras el raster no "alcance" a nuestro código, y nuestro código no "adelante" al raster, no debería haber problemas..
O sea, si se pusiera 1 interrupción en cada badline a partir de la primera, en esa interrupción se podría repintar los caracteres de la línea anterior.
Si esto es así, el tiempo disponible para repintar la pantalla, no es sólo el tiempo en el que el raster está en el borde, sino cualquier momento, siempre que el raster ni adelante, ni alcance al código..
Es esto así?
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 14, 2016, 12:44:12
Maniako,
Comentas que:Corrigeme si me equivoco: lo que no debe pasar, es que el raster intercepte una zona de la pantalla que se está cambiando en ese momento, cierto?

Exacto. una vez el raster ha pasado la zona en la que deseas que haya cambios, los haces.

Es decir, si hablamos de caracteres: una vez que el raster ha pasado por la primera fila de caracteres, debería ser posible cambiarla sin que hubiera flicker. Mientras el raster no "alcance" a nuestro código, y nuestro código no "adelante" al raster, no debería haber problemas..

Eso seria lo ideal, pero la rutina que uses en ese intervalo de linea, no debe durar más tiempo que hasta la siguiente linea que vayas a cambiar.
Si tu rutina de movimiento consume 9 o más lineas del raster, a la siguiénte interrupción para movel la siguiente linea (8 lineas) ya no lllegas a tiempo y empiezan los fallos.

O sea, si se pusiera 1 interrupción en cada badline a partir de la primera, en esa interrupción se podría repintar los caracteres de la línea anterior.

El tiempo disponible hasta la siguiente linea a mover es el límite.
En la rutina de arcoirirs, se ve perfecta por que no hago más que cambiar el color Se podria poner toda la pantalla a barras , queda bonito, pero ya se captaba lo que queria compartir.
Tengo pendiente algo como lo que comentas pero como experimento.
Prefiero aprender a usar el doble bufer, una segunda pantalla donde aplicar los cambios según donde tengas el scroll fino. Tengo que leermelo más y probarlo.

Si esto es así, el tiempo disponible para repintar la pantalla, no es sólo el tiempo en el que el raster está en el borde, sino cualquier momento, siempre que el raster ni adelante, ni alcance al código..
Es esto así?

Si , correcto. Hay gente que hace maravillas y me encantaria llegar a ese nivel ;)
Hasta que no empecé con las interrupciones no me dí cuenta de lo importante que es el optimizar el código al máximo y contar los ciclos .

De todas maneras no soy un gurú en estas lides. llevo bastante tiempo documentandome y revisando códigos para encontrar como funcionan. No me gusta poner código sin entender para qué sirve.

Gracias a Riq, empece a enterarme un poco de como funcionaban realmente.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 15, 2016, 22:40:41
Por fin con algo de tiempo libre.
Me he puesto a hacer pruebas aprovechando la rutina de arcoiris para que podais comprobar los efectos de pasarse en tiempo entre las interrupciones y tratar de hacer más comprensible el "misterio" las IRQ.

Código: [Seleccionar]

;CMB prg STUDIO
; 10 SYS36864

*=$801

        BYTE    $0B, $08, $0A, $00, $9E, $33, $36, $38, $36, $34, $00, $00, $00


*=$9000         ;Coloco el programa aquí para que no se desplace al
                ;entrar lineas de basic.
vector=vect
        ldx #0
        stx vector
        jsr $ff81        ;Limpiar pantalla

        sei                                   
        lda #%00011011  ;27 original. 26 no flickea.Hibyte del raster pero                             
        sta $D011       ;si no es 27 aparecen "pelos" en los bordes pantalla.
        lda #<irq1                         
        sta $0314                           
        lda #>irq1                           
        sta $0315                           
        lda #%00000001  ;#127 en el ejemplo. Basta con activar el timer A #1     
        sta $DC0D       ;Registro control de la cia                   
        lda #1                             
        sta $D01A       ;Registro mascara IRQ activada. IRQ ON.
        cli 
        rts             ;Salida al basic para pruebas.

main    ;El programa empezaria aquí.
        inc $D021
        jmp main
irq1     
                        ;Reset bandera de registro IRQ manipulando su valor.
        asl $D019       ;asl es consejo de Riq.Si no, se queda activado y falla.
        ldx vector
        ldy linea,x
        sty $d012
        ldy color,x
        sty $d020       ;Color marco
        lda linea+1,x   ;Siguente nuevo valor
        cmp #255
        beq salt0
        inc vector

;Bucle de freno para test de tiempo disponible
        ldx #24         ;Alterad este valor para pruebas de des-sincronismo
looop   lda $d012       ;Valor "aleatorio" del raster
        sta $0400,x     ;Lo pokeo en pantalla
        dex
        bne looop       ;Sigue el bucle hasta que X=0

        jmp $EA81       ;FEBC ;Saltar a restaurar a partir de la rutina NMI.
salt0
        lda #0
        sta vector
        jmp $EA31       ;Rutina interrupcion normal Leer teclado y demás.     

linea   byte $32,$3A,$42,$4A,$52,$5A,$62,$6A,$72,$7A,$82,$8A,$92,$9A,$A2,$AA,$C8,$ff
color   byte $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f,$00
vect    byte $00
freno   byte $00

He añadido un bucle para que podais experimentar aumentando o disminuyendo el tiempo del mismo. Este bucle representa el trabajo de mover una linea nada más acabe de pasar el raster (tal y como sugirió Dashiad) u otra cosa.

Mientras el tiempo del bucle sea menor al tiempo entre llamadas de interrupción, todo permanecerá estable.
En cuanto el tiempo del bucle sea mayor...

La verdad es que hay más tiempo del que creia, sin bucles , quizás de tiempo a mover toda una linea completa... Lo dejo para el que quiera trastear con este tema ;)

Otra idea. Usando esta rutina, se podria mostrar una linea de texto con dos colores a la vez e incluso hacer deslizar los dos colores arriba y abajo creando un efecto curioso.

A ver quién se anima.

EDITO:

Se puede ganar algo de tiempo si en vez de saltar a $EA31 donde se lee la tecla STOP y el parpadeo del cursor , saltamos a $EA61 saltandonos un buén cacho de código del sistema. Ando leyendo el listado de la ROM.

No es mucho, pero estas pequeñas ayudas pueden ser valiosas.
Está claro que el cursor dejará de parpadear y la tecla RUN/STOP deja de actuar a nivel del BASIC, pero generalmente no se suele trastear con el BASIC mientras juegas XD

Otro ahorro de tiempo es eliminando jmp$EA81 y pegando este código que es el mismo que se ejecuta en $EA81
 
       pla
        tay
        pla
        tax
        pla
        rti

Entre $EA61 y esto último se consigue algo mas de estabilidad .

Es cuestión de rascar ciclos.

Otra vez editando jajajaja. Esto engancha.

Si no necesitais el datasete, podeis saltar a $EA7B. Aun se consigue mas estabilidad. Desaparecen casi todos los flicks con el bucle a #28. Por lo menos es lo que aprecio con el VICE.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 20, 2016, 00:20:12
Otra chorrada de las mias  ::).

Generalmente hacer que un personaje de un juego salte con cierta "elegancia" a veces no es sencillo. Suele acabar saltando en angulos de 45 grados y personalmente nunca me ha gustado demasiado.

Se puede hacer uso de tablas para hacer el salto algo más natural o "redondo" (y para muchisimas otras cosas interesantes).
Aquí dejo este pequeño ejemplo, como siempre lo más sencillo que sé hacerlo (tampoco llego a mucho más XD) para una fácil comprensión.

Código: [Seleccionar]
;CMB prg STUDIO 3.8.0
;Usando tablas para saltar.
;He usado para el calculo de la trayectoria del salto el programa SINUS CREATOR.
;Es excelente para estos menesteres.

; 10 SYS4096

*=$0801

        BYTE    $0B, $08, $0A, $00, $9E, $34, $30, $39, $36, $00, $00, $00




*=$1000
sprites=$D000   
;Activando sprite.
        lda eje
        sta sprites     ;Coordenada X sprite.
        sta sprites+1   ;Coordenada Y sprite.
        lda #1
        sta sprites+21  ;Conecta sprite 1
        lda #128
        sta $07f8       ;Puntero direccion sprite
        ldy #00
main
;Bucle de freno para poder ver como salta.
bu2     dec freno0
        bne bu2
        lda #10         ;Disminuyendolo acelera. Aumentandolo frena
        sta freno0
bu3     dec freno1
        bne bu2
;Fin bucle de freno0

;Aqui empieza el programa en sí.       
        inc sprites     ;Muevo sprite en X un pixel a la derecha.
        inc sprites     ;Muevo sprite en X un pixel a la derecha otra vez.
        lda eje         ;Eje Y del sprite. Aqui lo tengo en un valor fijo.
        sec             ;Activar acarreo antes de restar.
        sbc salty,y     ;Le resto el valor del salto que hay en la tabla.
        sta sprites+1   ;Y coloco el sprite en su nueva posicion.
        iny             ;aumento en uno el vector de lectura.
        cpy #16         ;Es =16?
        bne pasa0       ;No?. Pues pasando.
        ldy #00         ;Si es =16, lo pongo a 0 y vuelve a leer la tabla de salto.
pasa0   
        jmp main        ;Vuelta a  empezar.
       
;Tabla datos salto usando Y como vector de lectura.
salty   byte 2,4, 6,  8, 11, 14, 18, 19,19,19, 18, 15, 11,  6,  3,  0
;Si el salto no es de vuestro gusto, podeis ajustarlo a ojo.

*=$2000         ;Sprite puntero 128*64 =#8192-$2000
        BYTE 0,124,0,0,68,0,0,66,0,0,100,0,0,24,0,1,248,96,3,30
        BYTE 192,2,27,128,0,25,128,0,24,0,0,24,0,0,24,0,0,24,0,0
        BYTE 24,0,0,30,0,0,27,0,0,49,0,3,225,0,3,1,0,2,1,128
        BYTE 2,1,192,0

;Variables
eje     byte 100        ;Valor fijo de la posición del sprite.
freno0  byte 0          ;Para el freno
freno1  byte 0          ;Para el freno

Como se puede ver , he usado una herramienta para crear la tabla del salto. Se llama SINUS CREATOR. Es muy sencilla de usar . CBM prg STUDIO 3.8.0 lleva una herramienta similar pero tengo que aprender a usarla.

El programa se explica por si mismo, pero cualquier duda, ya sabeis donde estamos.

Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Junio 20, 2016, 00:24:15
Yo odio esos saltos angulares!
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 20, 2016, 08:09:27
Yo odio esos saltos angulares!

Yo también XD.
Pero no sirve solamente para hacer saltos , sirve también para mover enemigos con más naturalidad y muchas otras cosas. El límite es vuestra imaginación.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Junio 25, 2016, 02:32:34
Hola de nuevo gente.

Otra chorradilla que espero os sea de interes y sobre todo, útil.

Código: [Seleccionar]
;CBM prg STUDIO

; 10 SYS (4096)

*=$0801

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

;BLoque cabecera cartucho
;$8000 el LOBYTE del arranque del programa. Arranque en frio.
;$8001 el HIBYTE del arranque del programa normalmente $8009.

;$8002 el LOBYTE de la direccion de RESET o EXIT INTERRUPT. Arranque en caliente.
;$8003 el HIBYTE de la direccion de RESET o EXIT INTERRUPT normalmente $FEBC
;$8004 Caracter C $C3
;$8005 Caracter B $C2
;$8006 Caracter M $CD
;$8007 Caracter 8 $38
;$8008 Caracter 0 $30
;$8009 El progama empieza aqui.

                *=$8000
        byte $09,$80,$20,$80,$c3,$c2,$cd,$38,$30
                *=$8009

                ;Al pulsar RESET salta a esta rutina.
main    inc $d021       ;fondo
        jmp main
       
*=$8020         ;AL pulsar RUNSTOP+RESTORE o RESTORE, salta a esta rutina
main2   inc $D020      ;marco
        jmp main2


*=$1000         ;Programa principal.
                ;Incrementa los colores de fondo y marco.
main3   inc $d020
        inc $d021
        jmp main3

Al colocar en la dirección $8000 (es la que una un cartucho cuando está insertado) la cabecera de un cartucho, podemos controlar lo que hacer cuando alguíen pulsa RESET, RESTORE o RUNSTOP/RESTORE cambiando los vectores.

Podeis o bién, volver a arrancar vuestro programa o poner un aviso de "esto no se toca,piratilla" o lo que deseéis.

Como siempre, creo que el programa en si se explica solo a base de los comentarios.

Ahora a dormir que ya son las 2:37h.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Junio 25, 2016, 03:43:27
Ahora a dormir que ya son las 2:37h.

Esas horas en que mejor rinde uno :)
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Julio 01, 2016, 17:51:44

Se puede hacer uso de tablas para hacer el salto algo más natural o "redondo" (y para muchisimas otras cosas interesantes).
Aquí dejo este pequeño ejemplo, como siempre lo más sencillo que sé hacerlo (tampoco llego a mucho más XD) para una fácil comprensión.

Buenisimo, grandes progresos.
Hice un toolcito para hacer tablas también... no es nada del otro mundo, pero anda. Para los curiosos, esta aca: https://github.com/ricardoquesada/c64-misc/blob/master/tools/easing_table_generator.py
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 01, 2016, 17:58:09
Python, ese lenguaje... ;-)
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 01, 2016, 22:22:11
Buenisimo, grandes progresos.
Hice un toolcito para hacer tablas también... no es nada del otro mundo, pero anda. Para los curiosos, esta aca: https://github.com/ricardoquesada/c64-misc/blob/master/tools/easing_table_generator.py

Gracias!! Ando probando mil cosas mientras aprendo.

Me he bajado el PY , instalado el cliente 2.7.16 , lo abro con el shell ¿IDLE? y no arranca.
¿Que hay que hacer para compilar python? XD
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: pastbytes en Julio 01, 2016, 22:43:53
No es un interprete? Me parece que hay que llamar a python con el nombre del .py como parametro, no?
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Julio 01, 2016, 22:48:03
Si, es como dijo pastabytes.

Abrí una terminal (el cmd.exe en Windows), y hacé:

c:> python easing_table_generator.py
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Julio 01, 2016, 23:28:38
OK. Text mode ;).

Bajo windows es un asco, no se instala el path hacia el bin y hay que ir hasta la carpeta donde esta.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 02, 2016, 03:57:41
Python desde Windows es incomodo, hay que instalar cosas y liarse...
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Julio 02, 2016, 05:32:37
No uso windows, pero usé Windows durante varios años y si mal no recuerdo el instalador de python te ponia todo en el path... quizas cambió.

más allá de eso, aprender un lenguaje script es muy util. desde esta boludez de poder generar tablitas para los saltos, hasta para parsear ciertos archivos SIDs, o manipular sprites, o lo que uno necesite.
las herramientas que hay para la c64 estan buenas, pero a veces no tiene lo que uno necesita... y ahí es donde python (o agregar cualquier otro lenguaje script) ayuda y mucho.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: pastbytes en Julio 02, 2016, 06:57:59
Yo pase de XP a Linux no hace tanto, pero el otro dia tuve que instalar un juego hecho en python en un PC Windows, y el instalador no agregaba python al path, pero daba la opcion de hacerlo, solo que habia que chequear una opcion que viene desactivada por defecto. Esta visible en la primera pantalla si no recuerdo mal, cuando se elige donde instalarlo, pero el que no lee y cliquea ok a todo no lo ve.  :D
Seguramente se puede asignar el tipo de archivo .py a python y luego solo se abririan los programas con doble click, yo hice un acceso directo del .py llamando a python porque solo me interesaba correr eso. En Linux solo hago doble click en los .py y abren.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Julio 02, 2016, 11:30:32
Cierto, a eso me refería. Algo que en otros SO es tan natural como abrir una imagen, en Windows se complica.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Octubre 11, 2016, 23:16:37
Aquí estamos de nuevo, todavía trasteando en ensamblador para tratar de que mi cerebro acabe de arrancar de una vez y me sea más fluido el programar, el tiempo que ha pasado desde que lo dejé, ha causado estragos  :(.

En esta ocasión he creado un programa que permite mover una nave en 16 direcciones diferentes manejándola con el JOY en port 2. Mi intención es usar esto en un futuro juego donde intentaré hacer que la nave tenga inercias al girar y se le aplique gravedad para alterar su trayectoria y así,  hacer las cosas más difíciles en el juego (y en la programación XD ).

Utilizo interrupciones para mover la nave y así, regular su velocidad de desplazamiento sin bucles de freno que consuman ciclos inútilmente, pero las utilizo solo para activar algunas rutinas en el tiempo de ejecución fuera de las interrupciones para mover los gráficos.
 
Es decir, no consumo tiempo de proceso durante las interrupciones, si no durante el proceso normal con la ventaja de evitar flicks al mover gráficos ya que se da el permiso justo cuando ha terminado de dibujar la pantalla .

Hago uso de tablas para manejar todo el cotarro usando el puntero del sprite a mover para tomar todas las decisiones necesarias. Seguro que había otra manera más complicada de hacerlo, pero no di con ella  ;D
La creé y pulí durante los 4 días que duro RetroBarcelona, a ratos libres.

Las variables MovX0 y MovY0, son las que controlan la cantidad de veces a esperar antes de desplazar un eje o el otro para conseguir que se desplace en 16 direcciones diferentes .

DEjeX0 y DEjeY0 contienen la dirección hacia donde mover la nave. 0=nada, 1=positivo (incrementa eje) , 2=negativo (decrementa eje).
 
La barrita de color que aparece por debajo de la pantalla, en el marco inferior , indica el tiempo de ejecución de las rutinas dentro del tiempo de IRQ pero fuera del mismo , no sé si ha quedado claro con mi explicación anterior XD.

Como siempre, he intentado comentarlo todo lo que me ha sido posible , así que aquí os dejo el código. De seguro es muy mejorable, pero es una buena introducción a otra manera de hacer las cosas.

Aquí lo tenéis. Destripadlo, trastearlo, en fin, lo que os apetezca. También he hecho que se active o desactive el MSB del sprite0 para poder navegar por toda la pantalla sin problemas.

Código: [Seleccionar]
;CBM PRG STUDIO 3.8.0

;CONSTANTES UNIVERSALES
;       $D000-$D010 SPRITE HORIZONTAL AND VERTICAL POSITION REGISTERS
SP0X    =       $D000   ; SPRITE 0 X POSITION
SP0Y    =       $D001   ; SPRITE 0 Y POSITION
SP1X    =       $D002   ; SPRITE 1 X POSITION
SP1Y    =       $D003   ; SPRITE 1 Y POSITION
SP2X    =       $D004   ; SPRITE 2 X POSITION
SP2Y    =       $D005   ; SPRITE 2 Y POSITION
SP3X    =       $D006   ; SPRITE 3 X POSITION
SP3Y    =       $D007   ; SPRITE 3 Y POSITION
SP4X    =       $D008   ; SPRITE 4 X POSITION
SP4Y    =       $D009   ; SPRITE 4 Y POSITION
SP5X    =       $D00A   ; SPRITE 5 X POSITION
SP5Y    =       $D00B   ; SPRITE 5 Y POSITION
SP6X    =       $D00C   ; SPRITE 6 X POSITION
SP6Y    =       $D00D   ; SPRITE 6 Y POSITION
SP7X    =       $D00E   ; SPRITE 7 X POSITION
SP7Y    =       $D00F   ; SPRITE 7 Y POSITION
MSIGX   =       $D010   ; MSB'S OF SPRITES 0-7 HORIZONTAL POSITIONS
;       POINTER SPRITES
POINSP0 =       $07F8   ; POINTER 2040 SPRITE O
POINSP1 =       $07F9   ; POINTER 2041 SPRITE 1
POINSP2 =       $07FA   ; POINTER 2042 SPRITE 2
POINSP3 =       $07FB   ; POINTER 2043 SPRITE 3
POINSP4 =       $07FC   ; POINTER 2044 SPRITE 4
POINSP5 =       $07FD   ; POINTER 2045 SPRITE 5
POINSP6 =       $07FE   ; POINTER 2046 SPRITE 6
POINSP7 =       $07FF   ; POINTER 2047 SPRITE 7
;       $D011-$D012 SCROLL & RASTER
SCROLY  =       $D011   ; VERTICAL FINE SCROLLING AND CONTROL REGISTER
RASTER  =       $D012   ; READ CURRENT RASTER SCAN LINE/WRITE LINE TO COMPARE
                                        ; FOR RASTER IRQ

SPENA   =       $D015   ; SPRITE ENABLE REGISTER
SCROLX  =       $D016   ; HORIZONTAL FINE SCROLLING AND CONTROL REGISTER
YXPAND  =       $D017   ; SPRITE VERTICAL EXPANSION REGISTER
VMCSB   =       $D018   ; VIC-II CHIP MEMORY CONTROL REGISTER
VICIRQ  =       $D019   ; VIC INTERRUPT FLAG REGISTER
IRQMSK  =       $D01A   ; IRQ MASK REGISTER
SPBGPR  =       $D01B   ; SPRITE TO FOREGROUND DISPLAY PRIORITY REGISTER
SPMC    =       $D01C   ; SPRITE MULTICOLOR REGISTERS
XXPAND  =       $D01D   ; SPRITE HORIZONTAL EXPANSION REGISTER
;       $D01E-$D01F SPRITE COLLISION DETECTION REGISTERS
SPSPCL  =       $D01E   ; SPRITE TO SPRITE COLLISION REGISTER
SPBGCL  =       $D01F   ; SPRITE TO FOREGROUND COLLISION REGISTER
;       $D020-$D026 VIC-II COLOR REGISTER
EXTCOL  =       $D020   ; BORDER COLOR REGISTER
BGCOL0  =       $D021   ; BACKGROUND COLOR 0

SPMC0   =       $D025   ; SPRITE MULTICOLOR 0
SPMC1   =       $D026   ; SPRITE MULTICOLOR 1
;       $D027-$D02E SPRITE COLOR REGISTERS
SP0COL  =       $D027   ; SPRITE 0 COLOR
SP1COL  =       $D028   ; SPRITE 1 COLOR
SP2COL  =       $D029   ; SPRITE 2 COLOR
SP3COL  =       $D02A   ; SPRITE 3 COLOR
SP4COL  =       $D02B   ; SPRITE 4 COLOR
SP5COL  =       $D02C   ; SPRITE 5 COLOR
SP6COL  =       $D02D   ; SPRITE 6 COLOR
SP7COL  =       $D02E   ; SPRITE 7 COLOR
;       $D02F-$D03F NOT CONNECTED
;       $D040-$D3FF VIC-II REGISTER IMAGES
;       $D419-$D41A GAME PADDLE INPUTS
;       $D41D-$D41F NOT CONNECTED
;       $D420-$D7FF SID REGISTER IMAGES
;       $D800-$DBFF COLOR RAM
COLRAM  =       $D800
; $DC00-$DC0F CIA #1
CIAPRA  =       $DC00   ; DATA PORT REGISTER A
CIAPRB  =       $DC01   ; DATA PORT REGISTER B
CIDDRA  =       $DC02   ; DATA DIRECTION REGISTER A
CIDDRB  =       $DC03   ; DATA DIRECTION REGISTER B
CIASDR  =       $DC0C   ; SERIAL DATA PORT
CIAICR  =       $DC0D   ; INTERRUPT CONTROL REGISTER
CIACRA  =       $DC0E   ; CONTROL REGISTER A
CIACRB  =       $DC0F   ; CONTROL REGISTER B
; $DC10-$DCFF CIA #1 REGISTER IMAGES
; $DD00-$DD0F CIA #2
; $DD10-$DDFF CIA #2 REGISTER IMAGES
LECOL   =       $0286   ; LETTER COLOR
GETIN   =   $FFE4
;------------------------------------------------------------

; 10 SYS4096

*=$0801

        BYTE    $0B, $08, $0A, $00, $9E, $34, $30, $39, $36, $00, $00, $00
;------------------------------------------------------------
*=$1000
        ;Conectando y colocando sprite para pruebas
        lda #1
        sta SPENA
        lda #192        ;$3800 ...#12288 $3000
        sta POINSP0
        lda #99
        sta SP0X
        sta SP0Y
        lda #0          ;Fondo negro
        sta $d021
        lda #1          ;Multicolor ON sprite 1
        sta SPMC       
        lda #1          ;Blanco
        sta SP0COL
        lda #2          ;Rojo
        sta SPMC0
        lda #6         ;Azul
        sta SPMC1
;Activando interrupciones
        sei                                   
        lda #%00011011  ;27 original. 26 no flickea.Hibyte del raster pero                             
        sta $D011       ;si no es 27 aparecen "pelos" en los bordes pantalla.
        lda #<irq                         
        sta $0314                           
        lda #>irq                           
        sta $0315                           
        lda #%00000001  ;#127 en el ejemplo. Basta con activar el timer A #1     
        sta $DC0D       ;Registro control de la cia                   
        lda #1                             
        sta $D01A       ;Registro mascara IRQ activada. IRQ ON.
        lda #250        ;Altura del barrido
        sta $d012
        cli
        jmp PREMAIN     ;Pasamos al programa normal saltandonos la rutina de irq.

IRQ    ;Programa ejecutado a cada interrupción.
        lda $d019               ;Reset bandera irq
        sta $d019               ;asi se desactiva la bandera y funcionan bien.
        lda #1                  ;Activando permiso de ejecucion fuera de pantalla (IRQ)
        sta Permiso             ;XD
        jmp $EA81       ;Rutina interrupcion normal Leer teclado y demás.     
                        ;EA81       ;FEBC ;Saltar a restaurar a partir de la rutina NMI.

;------------------------------------------------------------
;RESERVA DE VARIABLES EN EL PROGRAMA.

     ;El programa empieza aquí.
PREMAIN lda #0
        sta Dspr0               ;Pongo la nave en direccion hacia arriba (pruebas).
        clc
        adc #192
        sta POINSP0             ;Cambio el puntero sprite.
        jsr ResetEjeNaveX       ;Iniciando valores X
        jsr ResetEjeNavey       ;Iniciando valores Y

;DESPLAZAMIENTO NAVE RESPETANDO IRQ.

MAIN   
        lda Permiso             ;El raster esta a mas de 250?
        bne sigue0              ;Si=1 activado. Salta a ejecutar las rutinas irq dentro del tiempo de programa normal.
        jmp PASODEIRQ           ;Si=0 desactivado. Me largo a ejecutar los programas fuera de las IRQ.
sigue0
        lda #0          ;Desconecto el permiso de ejecución por IRQ
        sta Permiso     ;para evitar su ejecución constante. Si lo poneis a 1, vereis el programa a toda mecha XD.

        inc $d020               ;Testigo de la rutina (Borrable)Cambia el color del marco para ver cuanto tiempo ocupan los procesos.

;Leer joy2
        dec frenjoy     ;Freno joystick. Solo leé una vez cada 3 IRQ.
        bne paso3       ;No=0, paso de leer
        lda #3          ;Una vez cada 3 IRQ. Reconectar el freno. A mayor cifra, mayor arco decribe la nave.
        sta FrenJoy     ;xx ciclos antes de leeeer joy2

        lda CIAPRA      ;Leer joy2
        and #15         ;Solo movimiento der e izq.

        cmp #07         ;Derecha.
        bne paso1       ;No es derecha, paso a izq.
        clc             ;Borrar bandera de acarreo.
        inc DSpr0       
        lda DSpr0       ;Comprobando si pasa limite 15. La animación va del 0 al 15
        cmp #16
        bne paso2       ;Si no lo sobrepasa, pasa XD.
        lda #00         ;como si lo sobrepara, lo pone a 0
        sta DSpr0       ;y lo almacena.
        jmp paso2

paso1   clc
        cmp #11         ;Izquierda.
        bne paso3       ;No es izquierda?. Paso de todo.
        dec DSpr0
        lda DSpr0       ;Comprobando si pasa del limite <0 (255)
        cmp #255       
        bne paso2
        lda #15         ;Le doy el nuevo valor para mostrar el ciclo correcto.
        sta DSpr0


paso2   jsr ResetEjeNaveX       ;Como se ha "movido", inicializo de nuevo los valores de movimiento y dirección
        jsr ResetEjeNavey       ;de X e Y.
paso3   ;Se acabo joys
        lda DSpr0               ;Cojo su nuevo valor y cambio el sprite.     
        clc
        adc #192                ;Le sumo el valor de puntero del primer sprite de la animación.
        sta POINSP0


;Mover eje X
        lda MovX0Temp           ;Ciclos a esperar para mover el eje X
        beq PasoEjeX0           ;Sin decrementar la variable. 0=No mover.
        dec MovX0Temp
        bne PasoEjeX0           ;Si aún no es =0, paso de mover.
        lda DEjeX0Temp          ;Dirección hacia donde mover la nave.
        beq PasoEjeX0           ;Si=0, no mueve este eje.
        cmp #01                 ;1=Incrementa eje. 0=Decrementa eje.
        bne DecEjeX0
        lda SP0X
        clc                     ;Desactiva la bandera de acarreo antes de sumar.
        adc #01
        bcc paso4               ;Hay desbordamiento?
        tax                     ;Si lo hay: Guardo el valor de la coordenada.
        jsr msbx0               ;Salto a activar el MSB del sprite0
        txa                     ;Recupero el valor de la coordenada.
paso4   sta SP0X                ;y la pongo en el eje X
        jsr ResetEjeNaveX       ;Como se ha movido el eje, paso a reiniciar los valores de freno y dirección.
        jmp PasoEjeX0           ;Saltar hasta la rutina de mover eje Y
DecEjeX0                       
        lda SP0X
        sec                     ;Para restar hay que activar la bandera de acarreo.
        sbc #01
        bcs paso5               ;Sigue activado el acarreo?. =Si.Pasando de tocar el MSB.
        tax                     ;Guardo el valor de la coordenada.
        jsr msbx0               ;Salto a desactivar el MSB.
        txa                     
paso5 
        sta SP0X
        jsr ResetEjeNaveX       ;Como se ha movido el eje, paso a reiniciar los valores de freno y dirección.       

PasoEjeX0
;Mover eje Y. Lo mismo que con X pero al no tener que activar/desactivar el MSB, uso INC o DEC.
        lda MovY0Temp
        beq PasoEjeY0           ;Sin decrementar la variable. 0=No mover.
        dec MovY0Temp
        bne PasoEjeY0           ;Si aún no es =0, paso de mover.
        lda DEjeY0Temp
        beq PasoEjeY0           ;Si=0, no mueve este eje.
        cmp #01
        bne DecEjeY0
        inc SP0Y
        jsr ResetEjeNaveY
        jmp PasoEjeY0
DecEjeY0
        dec SP0Y
        jsr ResetEjeNavey

PasoEjeY0

        dec $d020               ;Testigo de la rutina (Borrable). Este debe ejecutarse al terminar con las rutinas que usen IRQ.

PASODEIRQ                          ;Final rutinas que usen IRQ.
;A PARTIR DE AQUÍ, SOLO RUTINAS LIBRES QUE SE EJECUTEN EL 100% DE CICLOS.
        nop
        nop
        nop
        jmp MAIN


;SUBRUTINAS .
;Cargar direccion de la nave y almacenar valores de dirección y bucles espera en sus respectivas variables.
ResetEjeNaveX
        clc
        ldx DSpr0               ;Carga direccion actual de la nave.
        lda MovX0,x             ;cargo valor fijo segun direccion
        sta MovX0Temp           ;y la guardo en el control de freno movimiento temporal X.
        lda DEjeX0,x            ;Cargo si suma o resta
        sta DEjeX0Temp          ;y la guardo en el control de dirección X.
        rts

ResetEjeNavey
        clc
        ldx DSpr0               ;Carga direccion actual de la nave
        lda MovY0,x             ;cargo valor fijo segun dirección
        sta MovY0Temp           ;y la guardo en el control de freno movimiento temporal Y.
        lda DEjeY0,x            ;Cargo si suma o resta
        sta DEjeY0Temp          ;y la guardo en el control de dirección Y.
        rts

;Activar o desactivar MSB sprite0
msbx0   clc
        lda MSIGX
        eor #01                 ;ON/OFF byte 1
        sta MSIGX
        rts

MovX0   byte $00,$02,$01,$01,$01,$01,$01,$02,$00,$02,$01,$01,$01,$01,$01,$02    ;bucles de espera antes de desplazar eje sprite0
MovY0   byte $01,$01,$01,$02,$00,$02,$01,$01,$01,$01,$01,$02,$00,$02,$01,$01    ;Idem
DEjeX0  byte $00,$01,$01,$01,$01,$01,$01,$01,$00,$02,$02,$02,$02,$02,$02,$02    ;Direccion ejes para saber si restar o sumar ese eje. 0=resta / 1=Suma / 255=nada
DEjeY0  byte $02,$02,$02,$02,$00,$01,$01,$01,$01,$01,$01,$01,$00,$02,$02,$02    ;Idem
MovX0Temp       byte $00        ;Variable
MovY0Temp       byte $00        ;Variable
DEjeX0Temp      byte $00        ;Variable
DEjeY0Temp      byte $00        ;Variable
DSpr0           byte $00        ;DireccionSprite0
FrenJoy         byte $10        ;Freno lectura joystick
Permiso         byte $00        ;Ejecutar o no rutinas por IRQ


;-------------------------------------------------------------------------------------------------------------------------------------

*=$3000         ;Los 16 sprites de la nave (0-15). sprites V2 #192-#203
;12288/64=192
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$08,$00,$00,$19,$00,$00,$0A,$00,$00,$36,$00,$00,$36,$00,$00,$3A,$00,$00,$EA,$80,$00,$F6,$80,$00,$D1,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$04,$00,$00,$02,$00,$00,$0D,$40,$00,$36,$00,$00,$FA,$00,$00,$EA,$00,$00,$56,$00,$00,$06,$00,$00,$06,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$00,$00,$02,$80,$00,$5D,$80,$00,$DD,$40,$00,$DB,$00,$00,$DA,$00,$00,$1A,$00,$00,$18,$00,$00,$08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$E0,$40,$00,$EA,$80,$00,$6D,$80,$00,$1D,$40,$00,$1A,$00,$00,$68,$00,$00,$60,$00,$00,$C0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$C0,$00,$00,$E1,$00,$00,$69,$00,$00,$36,$80,$00,$36,$80,$00,$69,$00,$00,$E1,$00,$00,$C0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$10,$00,$00,$E0,$00,$00,$68,$40,$00,$6A,$40,$03,$6D,$80,$03,$6D,$80,$03,$AA,$80,$00,$01,$00,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$18,$00,$00,$18,$00,$00,$1A,$00,$00,$5A,$40,$02,$FD,$00,$00,$BD,$80,$00,$2B,$80,$00,$02,$80,$00,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$02,$00,$00,$06,$00,$00,$16,$00,$00,$FA,$00,$00,$FA,$00,$00,$3D,$00,$00,$0D,$40,$00,$02,$00,$00,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$D1,$80,$00,$F6,$80,$00,$EA,$80,$00,$3A,$00,$00,$36,$00,$00,$36,$00,$00,$08,$00,$00,$19,$00,$00,$08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$34,$00,$00,$34,$00,$00,$39,$40,$00,$3A,$80,$00,$36,$80,$00,$36,$00,$00,$58,$00,$00,$20,$00,$00,$04,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0D,$00,$00,$3D,$00,$00,$39,$00,$00,$29,$40,$00,$DA,$80,$00,$5A,$80,$00,$9A,$00,$00,$A0,$00,$00,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$03,$00,$00,$0E,$00,$00,$0D,$00,$00,$39,$00,$00,$69,$00,$00,$D9,$00,$03,$5A,$40,$02,$AA,$80,$00,$40,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$03,$00,$00,$4B,$00,$00,$69,$00,$02,$D8,$00,$02,$D8,$00,$00,$6D,$00,$00,$4F,$00,$00,$03,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$40,$00,$02,$AA,$80,$03,$5A,$40,$00,$D9,$00,$00,$69,$00,$00,$39,$00,$00,$0D,$00,$00,$0E,$00,$00,$03,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$10,$00,$00,$A0,$00,$00,$9A,$00,$00,$5A,$80,$00,$DA,$80,$00,$29,$40,$00,$39,$00,$00,$3D,$00,$00,$0D,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81
          BYTE $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$04,$00,$00,$20,$00,$00,$58,$00,$00,$36,$00,$00,$36,$80,$00,$3A,$80,$00,$39,$40,$00,$34,$00,$00,$34,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$81


*=$4000         ;Pantalla de pruebas
                ;Desde #1104 hasta #2023 ($0450 hasta $07E7)
 







Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Octubre 11, 2016, 23:24:09
Superinteresante!!! ya lo miraré a ver que tal!
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Octubre 12, 2016, 00:02:49
Mola la mosca :)

Pero más me gustaría poder mirar y entender tu código!
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Octubre 12, 2016, 12:33:13
De aquí a un mes diré lo mismo XD, a ver si puedo explicarlo paso a paso.

Los tres primeros bloques se explican por si mismo.
             Constantes universales.
             Línea de BASIC para el arranque del programa.
             Conectando el sprite en modo multicolor y activar las interrupciones.
 
IRQ
             Aquí esta el programa que se ejecutará a cada interrupción por barrido.
             Este, lo único que hace es activar el permiso para que las rutinas que trabajarán
             dentro del tiempo de barrido fuera de la pantalla se ejecuten.
             ¿Con esto qué consigo?. Aparte de complicarme la vida XD, dejo que el código de 
             mover gráficos lo haga fuera de las interrupciones en tiempo normal de ejecución del   
             programa. ¿Para qué sirve?. Pues para que durante una interrupción se puedan leer
             teclado o joystick ya que en mis pruebas con las interrupciones, no podía leer ninguna
             entrada durante las mismas (o no sé hacerlo bién), además de un ejercicio para
             re-aprender a seguir un programa comprendiendo como piensa el commodore64 .

PREMAIN
            Coloco el puntero que indica el sprite a mostrar que a su vez, hace que el programa
            sepa hacia donde mover la nave gracias a las tablas que veremos más abajo.
            ResetEjeNaveX y ResetEjeNaveY , son subrutinas que dan los valores adecuados a las
            variables de trabajo. Veréis que hay redundancia, es por las futuras ampliaciones.

MAIN
            Aquí empieza el programa que se va a repetir en bucle.
            Las 3 primeras líneas comprueban si las interrupciones han dado su permiso para ejecutar
            el código. Si no es así, salta a ejecutar código "normal" fuera de las interrupciones.

        lda #0              ;Desconecto el permiso de ejecución por IRQ
        sta Permiso      ;para evitar su ejecución constante. Si lo poneis a 1, vereis el programa a toda
                               mecha XD.
            Una vez se permite la ejecución del código , anulo ese permiso para evitar que se ejecute
            constantemente. Debe ejecutarse solo a cada IRQ.

LEER JOY 2

            Esto no tiene misterio, si el valor es joy derecha o izquierda , incrementa o decrementa
            el valor del puntero del sprite0 y después compruebo si se sale del limite. Si es así, le
            otorgo el valor correcto y el ciclo continua.
           
MOVER EJE X

            Aquí empieza lo divertido.
            Mover una nave en 16 direcciones diferentes implica mover los ejes en tiempos variables.
            Desplazarse en ángulos rectos es sencillo, INC ejeX o ejeY.
            Las diagonales igual INC ejeX e INC ejeY a la vez. Pero esta manera solo consigue
            8 direcciones diferentes y hace los giros muy bruscos (para mi gusto).
            Pero las direcciones intermedias entre estos ángulos (8 más) , necesitan que uno de los
            ejes se ejecute dos veces mientras que el otro solo una vez, ahí
            entran las tablas y las comprobaciones para conseguirlo.
            MovX0Temp contiene el freno para el ejeX
            MovY0Temp contiene el freno para el ejeY.
            Si es 0 directamente, pasa, es decir, no mueve ese eje.
            Si no es 0, pasa a decrementar su valor hasta que sea 0 pero en el segundo paso,
            solo entonces se moverá ese eje.

             DEjeX0Temp contiene la dirección hacia donde se ha de mover el eje X.
             DEjeY0Temp contiene la dirección hacia donde se ha de mover el eje Y.

             Una vez movidos cada eje o cambiado el puntero del sprite0 , hago que se devuelvan
             los valores de nuevo para repetir el ciclo otra vez usando el puntero del sprite
             como guía para la lectura de las tablas.
             Para eso uso las subrutinas ResetEjeNaveX y ResetEjeNaveY.

PASODEIRQ

             A partir de aquí van las rutinas que se ejecutarán normalmente a cada ciclo sin importar
             las interrupciones (puntuación, detección de choques , lo que sea...).

MSBX0

            Activa o desactiva el MSB (bit más significativo) del eje X del sprite 0.
            Esta rutina solo se llama cada vez que hay desbordamiento al sumar o restar 1 (o 2 o 3 o...)
            al eje X.

Espero que esto ayude un poco a comprender su funcionamiento.
Esta rutina no solo vale para mover al protagonista, si no que también sirve para hacer mover enemigos siguiendo una tabla o patrón que le permitiría hacer giros bonitos (XD) antes de atacar o lo que vuestra imaginación os permita.

                 
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Octubre 12, 2016, 13:50:26
Buenísima la explicación, parece una buena forma de plantear el esqueleto de un juego.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: R. INTERNATIONAL en Octubre 12, 2016, 21:07:25
 Muy bueno!!,...ademas al "sintaxis" que utilizas conecta mucho conmigo,..dame tiempo para compilarla, estudiarla y destriparla, hay cosas que me interesan.

    Saludos Ferreos!
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Octubre 13, 2016, 12:14:10
Muy bueno!!,...ademas al "sintaxis" que utilizas conecta mucho conmigo,..dame tiempo para compilarla, estudiarla y destriparla, hay cosas que me interesan.

    Saludos Ferreos!

Todo el tiempo que quieras ;)

Seguiré trabajando y colgando lo que vaya aprendiendo.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: Maniako en Octubre 14, 2016, 23:42:57
He encontrado un error en mi código.
Ya lo he editado y solucionado.

Código: [Seleccionar]
;Leer joy2
        dec frenjoy     ;Freno joystick. Solo leé una vez cada 3 IRQ.
        bne paso3       ;No=0, paso de leer

Antes enviaba a paso2 y era un error. Ahora está corregido.
Sorry.
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: josepzin en Noviembre 14, 2016, 15:31:57
Esto es publicidad del curso de programación que están haciendo, pero igual es interesante. Multiplicando en código máquina.

Have you ever wondered how to multiply two numbers on Commodore 64?

Unfortunately it doesn't look like this:

Código: [Seleccionar]
lda #42
mul #5
The 6510 processor does not have a built in multiplication instruction.

Unless you are multiplying by a power of two.

In that case you can simply shift bits

Código: [Seleccionar]
lda #42
asl // a = a * 2 = 84
asl // a = a * 2 = 168
But in a general case we can't do that.

So what can we do?

Well, instead of multiplying forty-two by five, we can add forty-two five times.

Código: [Seleccionar]
  lda #0
  clc
  ldx #5
loop:
  adc #42
  dex
  bne loop
This get's the job done, but it's not very efficient (adding five forty two times would be even worse).

Can we improve this algorithm?

Sure, if we notice that

42 * 5 = 42 * 4 + 42

We can optimise the process using bit shifting operations.

Believe it or not, but the general version of this algorithm has been popular among...

Russian peasants...

few centuries ago...

Crazy right?

Anyway, if you want to learn how to apply this algorithm on the Commodore 64, take a look at the episode #067 - Multiplication.

You can also get it for free along with 13 other episodes.
https://gumroad.com/l/64bites
Título: Re:Rutinas en CM mas o menos útiles
Publicado por: riq en Noviembre 14, 2016, 17:17:54

42 * 5 = 42 * 4 + 42

We can optimise the process using bit shifting operations.

eso. y aunque multiplicar por 42 no es muy común, multiplicar por 320 si lo es, ya que es el ancho de la pantalla. y multiplicar por 320 se vuelve bastante sencillo ya que es:

Código: [Seleccionar]
320 = 256 + 64     en hexa sería: $140 = $100 + $40
320 = 2 ** 8 + 2 ** 6

pero 2 ** 8 es $100. O sea que multiplicar por 256 es super fácil. No hay que hacer nada.
y multiplicar por 64 es equivalente a hacer "valor << 6" (desde el LSB)... ó  "valor >> 2"  (desde el MSB).

entonces, y como ejemplo, supongamos que hay que multiplicar $bb * $140 (esta en hexa)

Código: [Seleccionar]
; multiplico por 256 ($100)
    lda #0
    sta resultado1_lo
    lda #$bb
    sta  resultado1_hi         ; no hay que hacer nada!, solo lo pongo en el MSB     

; multiplico por 64 ($40)
    lda #$bb
    lsr                                ; "dos shift rights" es más eficiente que hacer "seis shift left"
    ror resuldado2_lo
    lsr
    ror resuldado2_lo
    sta resultado2_hi

    ; y ahora tengo que hace la suma de 16-bit de resultado1 + resultado2

.byte resultado1_hi:
.byte resultado1_lo:
.byte resultado2_hi:
.byte resultado2_lo: