> Página 3

> Página 1 - Página 2 - Página 3 - Página 4 - Página 5 - Página 6

> | 11a - 11b - 11c - 11d - 11e - 11f - 11g - 12a - 12b - 12c - 13 - 14a - 14b - 15 | translate this page

> Página Cero | Basic ROM | Kernal ROM
> VIC II | SID | CIA

> A = Acumulador | X = Registro X | Y = Registro Y

> Nº 11a.- Imprimir un texto en pantalla
> Por Curtis White en _Bonkers_

> * = $1000 |  | ; SYS 4096.
> | LDX #0 | ; Carga X con #0, que es el valor inicial de un bucle.
> BUCLE | LDA TEXTO,X | ; Carga A con el valor de TEXTO y siguientes.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2 que saca a pantalla el carácter ASCII cuyo código está en A.
> | INX | ; Incrementa el valor del registro X.
> | CPX #13 | ; Compara el valor del registro X con #13, que es el final del texto.
> | BNE BUCLE | ; Salta a BUCLE hasta que el valor del registro X=#13.
> | RTS | ; Retorna al BASIC.
> TEXTO | .TEXT "HOLA A TODOS." | ; Este es el texto a imprimir. Como vemos tiene 13 caracteres.

> Para entender más: Como vemos, este programa utiliza la subrutina en ROM $FFD2 para imprimir y compara X con el número de caracteres que tiene el texto.
> Para aprender más: También podríamos hacer hacer lo siguiente pero ocuparíamos más espacio de memoria, aunque el formato es diferente ya que el texto tiene al final un .BYTE 0, que será el motivo de comparación con el valor de A.

> | LDX #0 | ; Carga X con #0, que es el valor inicial de un bucle.
> BUCLE | LDA TEXTO,X | ; Carga A con el valor de TEXTO y siguientes.
> | CMP #0 | ; Compara el valor de A con #0, que es el final del texto.
> | BEQ FIN | ; Salta a FIN cuando el valor del registro X=#0.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2 que saca a pantalla el carácter ASCII cuyo código está en A.
> | INX | ; Incrementa el valor de X.
> | JMP BUCLE | ; Salta a BUCLE hasta que el valor de X=#0.
> FIN | RTS | ; Retorna al BASIC.
> TEXTO | .TEXT "HOLA A TODOS." | ; Este es el texto a imprimir. Ya no importa el número de caracteres.
> | .BYTE 0 | ; Este es el famoso byte 0, que corresponde al fin del texto.

> Una segunda aplicación del anterior programa consiste en:

> Nº 11b.- Imprimir un texto en pantalla
> Po r fermhg, canal #c64 del irc-hispano

> * = $1000 |  | ; SYS 4096.
> | LDX #0 | ; Carga X con #0.
> BUCLE | LDA TEXTO,X | ; Carga A con el valor de TEXTO y siguientes.
> | STA $0400,X | ; Guarda el valor de A en la posición $0400 y siguientes #13 del mapa de memoria de pantalla.
> | INX | ; Incrementa el valor de X.
> | CPX #13 | ; Compara el valor de X con #13, que corresponde al final del texto.
> | BNE BUCLE | ; Salta a BUCLE hasta que X=#13.
> | RTS | ; Retorna al BASIC.
> TEXTO | .BYTE $08,$0F,$0C,$01,$20 | ; Texto.
> | .BYTE $01,$20,$14,$0F,$04 |
> | .BYTE $0F,$13,$2E |

> Para entender más: En este caso, para imprimir utilizamos el mapa de memoria de pantalla. Como vemos, hemos dado los datos de los caracteres de "HOLA A TODOS." en bytes sueltos. Lo que ocurre es que para las direcciones del mapa de la pantalla, los valores de las letras no son los mismos valores que usa el comando .TEXT"HOLA A TODOS", ya que, si escribimos esto último nos saldrán unos caracteres gráficos en lugar de las letras. Por lo tanto tenemos que restar #$40 a los valores del código de caracteres ASCII, excluyendo el caracter ESPACIO y ".".
> Para aprender más: Podemos cambiar el texto aunque tendremos que contar el número de caracteres que tiene para hacer la comparación.

> Una tercera aplicación del anterior programa consiste en:

> Nº 11c.- Imprimir una cadena en pantalla
> Por Blackspawn en Lemon 64

> * = $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 |

> Para entender más: Este programa es, aparentemente más rápido e ilustrativo que los anteriores, aunque todos son válidos.
> Para aprender más: Podemos situar el cursor en cualquier parte de la pantalla. Además podemos escribir la cadena de texto que queramos, recordando que al final de dicha cadena debe aparecer un .BYTE $00 ó .BYTE 0.

> Una cuarta aplicación del anterior programa consiste en:

> Nº 11d.- Imprimir una texto en pantalla
> Por Mozzy / WiDDY en Lemon 64

> *= $1000 |  | ; SYS 4096.
> INI | JSR $E544 | ; Salta a la subrutina en ROM $E544, que inicializa la pantalla. Es como si limpiara la pantalla.
> | LDA #$00 | ; Carga A con #$00, que es el código del color negro.
> | STA $D020 | ; Guarda el valor #$00 en la dirección $D020, que corresponde al borde de la pantalla.
> | STA $D021 | ; Guarda el valor #$00 en la dirección $D021, que corresponde al fondo de la pantalla.
> | LDX #$00 | ; Carga X con #$00, que es el valor inicial de un bucle.
> L1 | LDA TEXT,X | ; Carga A con el valor de TEXT y siguientes.
> | STA $0400,X | ; Guarda el valor de A en la posición $0400 y siguientes.
> | LDA #$01 | ; Carga A con #$01, que es el código del color blanco.
> | STA $D800,X | ; Guarda el valor de A en la posición $D800 y siguientes.
> | INX | ; Incrementa el valor de X.
> | CPX #$04 | ; Compara el valor de X con #$04, que corresponde al final del texto.
> | BNE L1 | ; Salta a L1 hasta que X=#$04.
> L2 | JMP L2 | ; Sata a L2, provocando un bucle sin fin. Esta línea puede ser sustituida por un RTS.
> TEXT | .BYTE $08,$0F | ; Texto.
> | .BYTE $0C,$01 |

> Para entender más: Este programa es prácticamente igual al Nº 11b aunque, como vemos, tiene la particularidad de limpiar primero la pantalla con la subrutina en ROM $E544.
> Para aprender más: Podemos cambiar los colores de la pantalla. Nuevamente podemos introducir otro texto aunque tendremos que contar el número de caracteres que tiene para hacer la comparación.

> Una quinta aplicación consiste en:

> Nº 11e.- Imprimir un número en pantalla
> Por Warren Marshall en comp.sys.cbm, fermhg, canal #c64 del irc-hispano

> *= $1000 |  | ; SYS 4096.
> | LDX #15 | ; Carga X con #15, siendo el número que va a corresponder al eje Y de la pantalla.
> | LDY #20 | ; Carga Y con #20, siendo el número que va a corresponder al eje X de la pantalla.
> | CLC | ; Pone la bandera de acarreo a 0.
> | JSR $FFF0 | ; Salta a la subrutina en ROM $FFF0, que localiza el cursor según las coordenadas dadas en LDX y LDY.
> | LDA #0 | ; Carga A con #0.
> | LDX #15 | ; Carga X con el número en decimal que queremos que se imprima en pantalla.
> | JSR $BDCD | ; Salta a la subrutina $BDCD, que imprime dicho número en la pantalla.
> | RTS | ; Retorna al BASIC.

> Para entender más: Vemos cómo el cursor es colocado gracias a la subrutina en ROM $FFF0. Entonces ya conocemos dos formas de colocar el cursor. Sin embargo, en este caso el registro X toma la posición del eje Y, y el registro Y toma la posición del eje X.
> Para aprender más: Podemos situar el cursor en cualquier parte de la pantalla. Además podemos escribir cualquier número decimal, comprendido entre #0 y 255.

> Una aplicación parecida consiste en:

> Nº 11f.- Imprimir en una impresora
> Por Steve Judd en comp.sys.cbm, fermhg, canal #c64 del irc-hispano

> *= $1000 |  | ; SYS 8192.
> | LDA #4 | ; Carga A con #4.
> | TAX | ; Transfiere el contenido de A a X.
> | JSR $FE00 | ; Salta a la subrutina en ROM $FE00, que selecciona los parámetros a imprimir.
> | JSR $F34A | ; Salta a la subrutina en ROM $F34A, que es el código de OPEN.
> | LDX #4 | ; Carga X con #4, ya que perdió ese valor en el salto anterior, y que corresponde a la impresora.
> | JSR $F250 | ; Salta a la subrutina en ROM $F250, que, junto con el valor de X=#4, se encarga de activar la impresora.
> | LDX #0 | ; Carga X con #0, que es el valor inicial de un bucle.
> BUCLE | LDA TEXTO,X | ; Carga A con el valor de TEXTO y siguientes.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2 que saca a pantalla el carácter ASCII cuyo código está en A.
> | INX | ; Incrementa el valor de X.
> | CPX #13 | ; Compara el valor del registro X con #13, que es el final del texto.
> | BNE BUCLE | ; Salta a BUCLE hasta que el valor del registro X=#13.
> | RTS | ; Retorna al BASIC.
> TEXTO | .TEXT "HOLA A TODOS." | ; Texto de 13 caracteres.

> Para entender más: Este programa es exactamente igual que el Nº 11a, siendo la única diferencia el periférico de impresión, que en este caso es la impresora.
> Para aprender más: Si necesitamos imprimir algún texto en la impresora desde Código Máquina ya podemos hacerlo usando esta técnica.

> Otro tipo de aplicación consiste en:

> Nº 11g.- Imprimir el abecedario 6 veces y con distintos colores
> Por Arturo, canal #c64 del irc-hispano

> *= $1000 |  | ; SYS 4096.
> | LDX #1 | ; Carga X con #1, que es el valor inicial de un bucle, contador de las letras.
> | LDY #0 | ; Carga Y con #0, que es el valor inicial de un bucle, contador de las posiciones relativas.
> | LDA #15 | ; Carga A con #15, que es el valor del primer color.
> | STA $FB | ; Guarda A en la dirección $FB.
> BUCLE | LDA $FB | ; Carga A con el valor de la dirección $FB.
> | STA 55296,Y | ; Guarda A en la posición 55296 y siguientes.
> | TXA | ; Transfiere el valor de X a A.
> | STA 1024,Y | ; Guarda A en la posición 1024 y siguientes.
> | INY | ; Incrementa Y.
> | INX | ; Incrementa X.
> | CPX #27 | ; Compara el valor de X con #27, que es el siguiente caracter de los 26 del abecedario.
> | BNE BUCLE | ; Salta a BUCLE hasta que X=#27.
> | LDX #1 | ; Carga X con #1.
> | TYA | ; Transfiere el valor de Y a A.
> | CLC | ; Pone la bandera de acarreo a 0 para poder sumar.
> | ADC #14 | ; Suma #14 al valor de A .
> | TAY | ; Transfiere el valor de A a Y.
> | LDA $FB | ; Carga A con el valor de la dirección $FB.
> | SBC #1 | ; Resta #1 al valor de A.
> | STA $FB | ; Resta el valor de A.
> | CPY #240 | ; Compara el valor de A con #240, que sería el final de la sexta línea.
> | BCC BUCLE | ; Salta a BUCLE si el valor de Y es menor de #240
> | RTS | ; Retorna al BASIC.

> Para entender más: Este programa ha sido el resultado de una idea. Escribir el abecedario. Una vez conseguido se intentó copiar el mismo abecedario una línea más abajo y así hasta completar el primer bloque. Hemos añadido color pra diferenciar el proceso.
> Para aprender más: Podemos hacer lo mismo pero ahora con dígitos numéricos (0-9), o también incluyendo las letras del sistema hexadecimal (0-F).

> Nº 12a.- Procesador de Texto
> Por Curtis White en _Bonkers_

> *= $1000 |  | ; SYS 4096.
> INI | LDA #93 | ; Carga A con #93, que equilvadría a las teclas SHIFT-CLR/HOME, es decir, limpiaría la pantalla.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII cuyo código está en A.
> | LDA #$00 | ; Carga A con #$00, que es el código del color negro.
> | STA $D020 | ; Guarda el valor #$00 en la dirección $D020, que corresponde al borde de la pantalla.
> | STA $D021 | ; Guarda el valor #$00 en la dirección $D021, que corresponde al fondo de la pantalla.
> PPAL | JSR PROTEX | ; Salta a la subrutina PROTEX, que hará el proceso de texto.
> | JSR EFECTO | ; Salta a la subrutina EFECTO, que hará un efecto de colores.
> | JMP PPAL | ; Salta a PPAL, creando un bucle sin fin.
> PROTEX | JSR $FFE4 | ; Salta a la subrutina en ROM $FFE4, que espera una tecla.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII de la tecla pulsada, cuyo código está en A.
> | RTS | ; Retorno de subrutina.
> EFECTO | LDX #$00 | ; Carga X con #$00, que es el valor inicial de un bucle.
> BUCLE | LDA COLOR,X | ; Carga A con el valor de COLOR y siguientes.
> | STA $D020 | ; Guarda el valor #$00 en la dirección $D020.
> | INX | ; Incrementa el valor de X.
> | CPX #9 | ; Compara el valor de X con #9, número de colores.
> | BNE BUCLE | ; Salta a BUCLE hasta que X=#9.
> | RTS | ; Retorna al BASIC.
> COLOR | .BYTE 6,14,3,7,1 | ; Colores.
> | .BYTE 7,3,14,6 |

> Para entender más: Aquí tenemos un ejemplo de qué es, a modo de ilustración, un editor de textos convencional.
> Para aprender más: Podemos escribir el texto que queramos.

> Una segunda aplicación del anterior programa consiste en:

> Nº 12b.- Procesador de textos con adornos en los caracteres
> Por Curtis White en _Bonkers_

> *= $2000 |  | ; SYS 8192.
> | LDA #0 | ; Carga A con #0.
> | STA $0286 | ; Guarda el valor #0 en la dirección $0286, lo que activa el color de nuestros caracteres que va a coincidir con el color del fondo de nuestra pantalla.
> | LDA #93 | ; Carga A con #93, que equilvadría a las teclas SHIFT-CLR/HOME, es decir, limpiaría la pantalla.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII cuyo código está en A.
> | LDA #$00 | ; Carga A con #$00, que es el código del color negro.
> | STA $D020 | ; Guarda el valor #$00 en la dirección $D020, que corresponde al borde de la pantalla.
> | LDA #$01 | ; Carga A con #$01, que es el código del color blanco.
> | STA $D021 | ; Guarda el valor #$01 en la dirección $D021, que corresponde al fondo de la pantalla.
> | SEI | ; Prohíbe las interrupciones IRQ, necesario para evitar que la CPU se centre en "otras cosas".
> COPYCHAR | LDA 1 | ; Carga A con el valor de la dirección $01, que es el registro del Chip 6510.
> | AND #251 | ; Efectúa un AND lógico entre A y #251.
> | STA 1 | ; Guarda el valor de A en la dirección $01 nuevamente.
> | LDX #$00 | ; Carga X con #$00, que es el valor inicial de un bucle.
> GETCHL | LDA 54272,X | ; Carga A con el valor de la dirección 54272 y siguientes.
> | STA 12288,X | ; Guarda el valor de A en la dirección 12288 y siguientes.
> | LDA 54272+256,X | ; Carga A con el valor de la dirección 54272 + 256 y siguientes.
> | STA 12288+256,X | ; Guarda el valor de A en la dirección 12288 + 256 y siguientes.
> | INX | ; Incrementa el valor de X.
> | CPX #255 | ; Compara el valor de X con #255.
> | BNE GETCHL | ; Salta a GETCHL hasta que X=#255.
> | LDA 1 | ; Carga A con el valor de la dirección $01.
> | ORA #4 | ; Ejecuta un OR lógico entre A y #4.
> | STA 1 | ; Guarda el valor de A en la dirección $01 nuevamente.
> | CLI | ; Permite las interrupciones IRQ.
> | LDA 53272 | ; Carga A con el valor de la dirección 53272.
> | AND #240 | ; Efectúa un AND lógico entre A y #240.
> | ORA #12 | ; Ejecuta un OR lógico entre A y #12.
> | STA 53272 | ; Guarda el valor de A en la dirección 53272 nuevamente.
> | LDA 53265 | ; Carga A con el valor de la dirección 53265.
> | ORA #64 | ; Ejecuta un OR lógico entre A y #64.
> | STA 53265 | ; Guarda el valor de A en la dirección 53265 nuevamente.
> MAIN | JSR PROTEX | ; Salta a la subrutina PROTEX, que hará el proceso de texto.
> | JSR MPLAY | ; Salta a la subrutina MPLAY, que hará los adornos.
> | JMP MAIN | ; Salta a MAIN, creando un bucle sin fin.
> PROTEX | JSR $FFE4 | ; Salta a la subrutina en ROM $FFE4, que espera una tecla.
> | CMP #134 | ; Compara el valor de la tecla pulsada con el valor el valor de la tecla F3.
> | BEQ RVSMODE | ; Si coincide con la tecla de función F3 salta a RVSMODE.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII de la tecla pulsada, cuyo código está en A.
> | RTS | ; Retorno de subrutina.
> RVSMODE | LDA FLIP1 | ; Carga A con el valor de la posición FLIP1.
> | CMP #0 | ; Compara el valor #0.
> | BNE RVSOFF | ; Salta a RVSOFF hasta que el valor de A=#0.
> RVSON | LDA #18 | ; Carga A con el valor #18, que corresponde a RVS/ON.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII de la tecla pulsada, cuyo código está en A.
> | LDA #1 | ; Carga A con el valor #1.
> | STA FLIP1 | ; Guarda el valor de A en la posición FLIP1.
> | RTS | ; Retorno de subrutina.
> RVSOFF | LDA #146 | ; Carga A con el valor #146, que corresponde a RVS/OFF.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII de la tecla pulsada, cuyo código está en A.
> | LDA #0 | ; Carga A con el valor #0.
> | STA FLIP1 | ; Guarda el valor de A en la posición FLIP1.
> | RTS | ; Retorno de subrutina.
> MPLAY | LDX #$00 | ; Carga X con #$00, que es el valor inicial de un bucle.
> MEMLOOP | LDA COL1,X | ; Carga A con el valor de COL1 y siguientes.
> | STA 53282 | ; Guarda el valor de A en la dirección 53282 nuevamente.
> | LDA COL2,X | ; Carga A con el valor de COL2 y siguientes.
> | STA 53283 | ; Guarda el valor de A en la dirección 53283 nuevamente.
> | LDA COL3,X | ; Carga A con el valor de COL3 y siguientes.
> | STA 53284 | ; Guarda el valor de A en la dirección 53284 nuevamente.
> | INX | ; Incrementa el valor de X.
> | CPX #9 | ; Compara el valor de X con #9.
> | BNE MEMLOOP | ; Salta a MEMLOOP hasta que X=#9.
> | RTS | ; Retorna al BASIC.
> COL1 | .BYTE 6,14,3,7,1,7,3,14,6 | ; Colores.
> COL2 | .BYTE 11,12,15,7,1,7,15,12,11 |
> COL3 | .BYTE 9,4,8,7,1,7,4,8,9 |
> FLIP1 | .BYTE 0 |

> Para entender más: Para comprender exactamente lo que realiza este pequeño programa tenemos que escribir normal y escribir utilizando las techas SHIFT+las demás teclas, además para ver el modo RVS/ON deberás pulsar F3. Verás como aparecen adornadas con destellos de luz producidos la subrutina MEMLOOP.
> Para aprender más: Podemos escribir el texto que queramos.

> Nº 12c.- Encabezado y pie de página
> Por John Iannetta en comp.sys.cbm

> *= $1000 |  | ; SYS 4096.
> | SEI | ; Prohíbe las interrupciones IRQ, necesario para evitar que la CPU se centre en "otras cosas".
> | LDA #<IRQ | ; Carga A con el byte bajo de IRQ.
> | STA $0314 | ; Guarda el valor de A en la dirección $0314.
> | LDA #>IRQ | ; Carga A con el byte alto de IRQ.
> | STY $0315 | ; Guarda el valor de A en la dirección $0315.
> | CLI | ; Permite las interrupciones IRQ.
> BUCLE1 | JSR $FFCF | ; Salta a la subrutina $FFCF en ROM, que espera la introducción de caracteres.
> | CMP #$0D | ; Compara el valor de A con #$0D, que corresponde a RETURN.
> | BNE BUCLE1 | ; Salta a BUCLE1 hasta que sea pulsada la tecla RETURN.
> | JSR $E716 | ; Salta a la subrutina $E716 en ROM, que imprime el caracter introducido en la pantalla.
> | BCC BUCLE1 | ; Una vez imprimido el caracter salta nuevamente a BUCLE1.
> BUCLE2 | LDA $D6 | ; Carga A con el valor de la posición $D6, que lee la línea de la posición del cursor.
> | CMP #$16 | ; Compara el valor de A con #$16, que corresponde a la línea 22.
> | BCC FIN | ; Si la línea donde está el cursor es la número 22 salta a FIN.
> | LDX #$08 | ; Carga X con #$08, que es el valor inicial de un bucle.
> CARRO1 | LDA $0470,X | ; Carga A con el valor de $0478 y siguientes.
> | STA $0448,X | ; Guarda el valor de A en las posiciones $0448 y siguientes, lo que produce el efecto del movimiento del carro en una máquina de escribir.
> | INX | ; Incrementa el valor de X.
> | BNE CARRO1 | ; Salta a CARRO1 hasta que X no haya recorrido toda la línea.
> CARRO2 | LDA $0570,X | ; Carga A con el valor de $0578 y siguientes.
> | STA $0548,X | ; Guarda el valor de A en las posiciones $0548 y siguientes, lo que produce el efecto del movimiento del carro en una máquina de escribir.
> | INX | ; Incrementa el valor de X.
> | BNE CARRO2 | ; Salta a CARRO2 hasta que X no haya recorrido toda la línea.
> CARRO3 | LDA $0670,X | ; Carga A con el valor de $0678 y siguientes.
> | STA $0648,X | ; Guarda el valor de A en las posiciones $0648 y siguientes, lo que produce el efecto del movimiento del carro en una máquina de escribir.
> | INX | ; Incrementa el valor de X.
> | BNE CARRO3 | ; Salta a CARRO3 hasta que X no haya recorrido toda la línea.
> | LDX #$27 | ; Carga X con #$27, que es el valor inicial de un bucle.
> | LDA #$20 | ; Carga A con #$20, que corresponde al caracter ESPACIO.
> PIE | STA $0748,X | ; Guarda el valor de A en las posiciones $0748 y siguientes, lo que produce el efecto de anulación de las últimas líneas de texto, algo así como pie de página, aunque no se puede escribir sobre él.
> | DEX | ; Decrementa el valor de X.
> | BPL PIE | ; Salta a PIE hasta que X=#$00.
> | CLC | ; Pone la bandera de acarreo a cero.
> | LDX #$15 | ; Carga X con #$15,que en decimal es #21 siendo el número que va a corresponder al eje Y de la pantalla.
> | LDY #$00 | ; Carga Y con #$00, siendo el número que va a corresponder al eje X de la pantalla.
> | JSR $FFF0 | ; Salta a la subrutina en ROM $FFF0 que localiza el cursor según las coordenadas dadas en LDX y LDY.
> FIN | JMP $EA31 | ; Salta a la subrutina en ROM $EA31, que se encarga de realizar las interrupciones.

> Para entender más: Como vemos tenemos un recorte del fondo de la pantalla tanto por arriba como por abajo.
> Para aprender más: Podemos escribir el texto que queramos. También podemos ajustar más el encabezado y pie de página consiguiendo escribir en pocas líneas.

> Nº 13.- Construcción de fuentes de letras
> Por fermhg, canal #c64 del irc-hispano

> Éste es el caracter de la letra A en el Commodore 64

> * = $1000 |  | ; SYS 4096.
> | LDA #$00 | ; Carga A con #$00, que es el código del color negro.
> | STA $D020 | ; Guarda el valor #$00 en la dirección $D020, que corresponde al borde de la pantalla.
> | STA $D021 | ; Guarda el valor #$00 en la dirección $D021, que corresponde al fondo de la pantalla.
> | LDA #$93 | ; Carga A con #$93, que equilvadría a las teclas SHIFT-CLR/HOME, es decir, limpiaría la pantalla..
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII cuyo código está en A.
> | LDA #$18 | ; Carga A con #$18 (%00011000), que activa los bits 3 y 4.
> | STA $D018 | ; Guarda el valor #$18 en la posición $D018, lo que permite generar la nueva fuente de letra.
> | LDA #$40 | ; Carga A con el primer caracter situado en CTER1.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII cuyo código está en A.
> | LDA #$41 | ; Carga A con el segundo caracter situado en CTER2.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII cuyo código está en A.
> | LDA #$42 | ; Carga A con el tercer caracter situado en CTER3.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII cuyo código está en A.
> | LDA #$43 | ; Carga A con el cuarto caracter situado en CTER4.
> | JSR $FFD2 | ; Salta a la subrutina en ROM $FFD2, que saca a pantalla el carácter ASCII cuyo código está en A.
> | LDX #$00 | ; Carga X con el valor #$00, que es el valor inicial de un bucle.
> BLANC | LDA #$01 | ; Carga A con #$01, que es el código del color blanco.
> | STA $D800,X | ; Guarda el valor #$01 en la posición $D800 y #4 siguientes del mapa de colores de la pantalla.
> | INX | ; Incrementa el valor de X.
> | CPX #$04 | ; Compara el valor de X con #$04.
> | BNE BLANC | ; Salta a BLANC hasta que X=#$04.
> BUCLE | JMP BUCLE | ; Sata a BUCLE, provocando un bucle sin fin.
> *= $2000 |  | ; El nuevo código necesariamente debe ensamblarse a partir de la dirección de memoria $2000. ; Éstos son los códigos de cada una de las letras.
> CTER1 | .BYTE $C3,$66,$66,$3E,$66,$66,$C3,$00 | ; 11000011, 01100110, 01100110, 01111110, 01100110, 0100110, 11000011, 00000000.
> CTER2 | .BYTE $00,$00,$3C,$66,$43,$66,$3C,$00 | ; 00000000, 00000000, 00111100, 01100110, 01000011, 01100110, 10111100, 00000000.
> CTER3 | .BYTE $38,$6C,$6C,$78,$E0,$70,$3F,$00 | ; 00111000, 01101100, 01101100, 01111000, 11100000, 01110000, 00111111, 00000000.
> CTER4 | .BYTE $00,$00,$3C,$66,$42,$66,$BF,$00 | ; 00000000, 00000000, 00111100, 01100110, 01000010, 01100110, 10111111, 00000000.

> Para entender más: Como vemos podemos hacer nuestra propia fuente de letra, en este caso, utilizando los cuatro primeros caracteres, que no tienen nada que ver con los cuatro primeros caracteres convencionales del Commodore 64.
> Para aprender más: Haz tu propia fuente de letra.

> Nº 14a.- Ejemplo de Sprite
> Por Linus Åkerlund, el sprite po r fermhg, canal #c64 del irc-hispano

> Ésto es un ejemplo de Sprite en el Commodore 64

> *= $1FAA |  | ; SYS 8106.
> | LDA #$01 | ; Carga A con #$01.
> | STA $D015 | ; Guarda el valor #$01 en la dirección $D015, lo que activa el Sprite 0.
> | STA $D027 | ; Guarda el valor #$01 en la dirección $D027, lo que colorea de blanco dicho Sprite.
> | LDA #$40 | ; Carga A con #$40.
> | STA $D000 | ; Guarda el valor #$40 en la dirección $D000, lo que hace colocar el Sprite en la posición #$40 del eje de coordenadas X.
> | STA $D001 | ; Guarda el valor #$40 en la dirección $D001, lo que hace colocar el Sprite en la posición #$40 del eje de coordenadas Y.
> | LDA #$80 | ; Carga A con #$80.
> | STA $07F8 | ; Activa el puntero. Los datos del Sprite estarán necesariamente en la posición de memoria $2000.
> BUCLE | LDA $D012 | ; Carga A con el valor de la posición $D012.
> | CMP #$FF | ; ¿Se está emitiendo el raster en la línea #$FF?.
> | BNE BUCLE | ; Salta a BUCLE hasta que A=#$FF.
> | LDA DIR | ; Carga A con el valor de la posición DIR, el cuál nos dice en qué dirección se moverá el Sprite.
> | BEQ DOWN | ; Si es 0, se moverá hacia abajo y hacia la derecha. ; Si es 1, se moverá hacia arriba y hacia la izquierda.
> | LDX COORD | ; Carga X con el valor de COORD, que son las coordenadas.
> | DEX | ; Decrementa el valor de X.
> | STX COORD | ; Guarda el valor cargado en X en la posición COORD.
> | STX $D000 | ; Guarda el valor cargado en X en la dirección $D000, lo que activa la nueva coordenada.
> | STX $D001 | ; Guarda el valor cargado en X en la dirección $D001, lo que activa la nueva coordenada.
> | CPX #$40 | ; Cuando vuelva al mismo sitio, es decir, cuando X=#$40 entonces...
> | BNE BUCLE | ; Salta a BUCLE hasta que X=#$40.
> | LDA #$00 | ; Carga A con #$00. Esto va a dar lugar a un cambio de dirección.
> | STA DIR | ; Guarda el valor #$00 en la posición DIR.
> | JMP BUCLE | ; Salta a BUCLE directamente.
> DOWN | LDX COORD | ; Carga X con el valor de COORD, que son las coordenadas.
> | INX | ; Incremente el valor de X.
> | STX COORD | ; Guarda el valor cargado en X en la posición COORD.
> | STX $D000 | ; Guarda el valor cargado en X en la dirección $D000, lo que activa la nueva coordenada.
> | STX $D001 | ; Guarda el valor cargado en X en la dirección $D001, lo que activa la nueva coordenada.
> | CPX #$E0 | ; Compara el valor de X con #$E0.
> | BNE BUCLE | ; Salta a BUCLE hasta que X=#$E0.
> | LDA #$01 | ; Carga A con #$01. Esto va a dar lugar a un cambio de dirección.
> | STA DIR | ; Guarda el valor #$01 en la posición DIR.
> | JMP BUCLE | ; Salta a BUCLE directamente.
> COORD | .BYTE $40 | ; Cordenadas.
> DIR | .BYTE $00 | ; Dirección: 0 = Abajo-derecha; 1 = Arriba-izquierda..
> * = $2000 |  | ; El nuevo código necesariamente debe ensamblarse a partir de la dirección de memoria $2000. ; Éstos son los códigos del sprite.
> | .BYTE 0,24,0 | ; 00000000, 00011000, 00000000.
> | .BYTE 28,60,56 | ; 00011100, 00111100, 00111000.
> | .BYTE 78,66,114 | ; 01001110, 01000010, 01110010.
> | .BYTE 3,231,192 | ; 00000011, 11100111, 11000000.
> | .BYTE 83,129,202 | ; 01010011, 10000001, 11001010.
> | .BYTE 72,153,18 | ; 01001000, 10011001, 00010010.
> | .BYTE 68,36,34 | ; 01000100, 00100100, 00100010.
> | .BYTE 82,66,74 | ; 01010010, 01000010, 01001010.
> | .BYTE 89,153,154 | ; 01011001, 10011001, 10011010.
> | .BYTE 93,60,186 | ; 01011101, 00111100, 10111010.
> | .BYTE 93,231,186 | ; 01011101, 11100111, 10111010.
> | .BYTE 93,60,186 | ; 01011101, 00111100, 10111010.
> | .BYTE 89,153,154 | ; 01011001, 10011001, 10011010.
> | .BYTE 82,66,74 | ; 01010010, 01000010, 01001010.
> | .BYTE 68,36,34 | ; 01000100, 00100100, 00100010.
> | .BYTE 72,153,18 | ; 01001000, 10011001, 00010010.
> | .BYTE 83,129,202 | ; 01010011, 10000001, 11001010.
> | .BYTE 3,231,192 | ; 00000011, 11100111, 11000000.
> | .BYTE 78,66,114 | ; 01001110, 01000010, 01110010.
> | .BYTE 28,60,56 | ; 00011100, 00111100, 00111000.
> | .BYTE 0,24,0 | ; 00000000, 00011000, 00000000.

> Para entender más: De esta manera hemos hecho nuestro sprite.
> Para aprender más: Haz tu propio sprite. Utilizando el joystick o el teclado puedes mover tu propio sprite.

> Nº 14b.- Rutina multi-sprites
> Por John P. Gibbons

> *= $1000 |  | ; SYS 4096.
> | LDX #$3F | ; Carga X con #$3F.
> | LDA #$FF | ; Carga A con #$FF.
> L1 | STA $0380,X | ; Guarda el valor #$FF en la dirección $0380 y siguientes, lo que dibuja los sprites como cuadrados (todos los bits activos).
> | DEX | ; Decrementa el valor de X.
> | BPL L1 | ; Salta a L1 hasta que el valor de X=#$00.
> | LDY #$07 | ; Carga Y con #$07.
> | LDX #$0E | ; Carga X con #$0E.
> BUCLE1 | LDA #$05 | ; Carga A con #$05.
> | STA $D027,Y | ; Guarda el valor #$05 en la dirección $D027 y 7 siguientes, lo que activa 8 sprites en pantalla.
> | LDA SPX,Y | ; Carga A con el valor de la posición SPX y 7 siguientes.
> | STA $D000,X | ; Guarda el valor de A en la dirección $D000 y 14 siguientes, lo que posiciona cada sprite en su coordenada X.
> | LDA #$0E | ; Carga A con #$0E.
> | STA $07F8,Y | ; Guarda el valor #$0E en la dirección $07F8 y 7 siguientes.
> | DEX | ; Decrementa el valor de X.
> | DEX | ; Decrementa de nuevo el valor de X.
> | DEY | ; Decrementa el valor de Y.
> | BPL BUCLE1 | ; Salta a BUCLE1 hasta que el valor de X=#$00.
> | LDA #$C0 | ; Carga A con #$C0.
> | STA $D010 | ; Guarda el valor #$C0 en la dirección $D010, lo que define la coordenada X te todos los sprites.
> | LDA #$00 | ; Carga A con #$00.
> | STA $D017 | ; Guarda el valor #$00 en la dirección $D017, lo que define los sprites como no expandidos verticalmente.
> | STA $D01D | ; Guarda el valor #$00 en la dirección $D01D, lo que define los sprites como no expandidos horizontalmente.
> | LDA #$FF | ; Carga A con #$FF.
> | STA $D015 | ; Guarda el valor #$FF en la dirección $D015, lo que activa todos los sprites.
> | SEI | ; Prohíbe las interrupciones IRQ, necesario para evitar que la CPU se centre en "otras cosas".
> | LDA #$7F | ; Carga A con #$7F.
> | STA $DC0D | ; Guarda el valor #$FF en la dirección $DC0D, lo que desactiva todas las interrupciones de la CIA 1.
> | LDA #$01 | ; Carga A con #$01.
> | STA $D01A | ; Guarda el valor #$01 en la dirección $D01A, lo que escribe en el registro de barrido el valor inicial.
> | STA $D019 | ; Guarda el valor #$01 en la dirección $D01A, lo que posiciona los sprites.
> | LDA #<IRQ | ; Carga A con el byte bajo de IRQ.
> | LDY #>IRQ | ; Carga Y con el byte alto de IRQ.
> | STA $0314 | ; Guarda el valor de A en la dirección $0314.
> | STY $0315 | ; Guarda el valor de Y en la dirección $0315.
> | JSR RESET | ; Salta a la subrutina RESET, que lleva la interrupción del raster al extremo superior de la pantalla.
> | CLI | ; Permite las interrupciones IRQ.
> WAIT | JMP WAIT | ; Salta a WAIT, lo que produce un bucle infinito
> SPX | .BYTE $40,$60,$80,$A0 | ; Estos son los valores de los bytes bajos de las coordenadas X de los 8 sprites.
> | .BYTE $C0,$E0,$00,$20 |
> IRQ | LDA #$01 | ; Carga A con #$01.
> | STA $D019 | ; Guarda el valor #$01 en la dirección $D01A, lo que escribe en el registro de barrido el valor inicial.
> | JSR SET | ; Salta a la subrutina SET, que cambia la coordenada Y de los 8 sprites.
> | JMP $EA81 | ; Salta a la dirección en ROM $EA81 que sale de IRQ y restaura los registros.
> SET | LDA $D012 | ; Carga A con el valor de la dirección $D012, lo que nos da el valor del raster.
> | CMP #$E5 | ; Compara el valor de A con #$E5, que corresponde al final de la pantalla aproximadamente.
> | BCC ONGO | ; Salta a ONGO si el valor de A es menor que #$E5.
> RESET | CLC | ; Pone la bandera de acarreo a 0 para poder sumar.
> | LDA #$30 | ; Carga A con #$30.
> ONGO | LDX #$0E | ; Carga X con #$0E.
> | ADC #$03 | ; Suma el contenido de A más #$03.
> OG1 | STA $D001,X | ; Guarda el valor de A en la dirección $D001 y 14 siguientes, lo que posiciona cada sprite en su coordenada Y.
> | DEX | ; Decrementa el valor de X.
> | DEX | ; Decrementa de nuevo el valor de X.
> | BPL OG1 | ; Salta a OG1 hasta que el valor de X=#$00.
> | ADC #$16 | ; Suma el contenido de A más #$16.
> | STA $D012 | ; Guarda el valor de A en la dirección $D012, lo que posiciona el raster en el valor dado por A.
> | LDA $D011 | ; Carga A con el valor de la dirección $D011.
> | AND #$7F | ; AND entre A y el valor %01111111 ($7F) que inhabilita el bit 7.
> | STA $D011 | ; Guarda el valor de A en la dirección $D011, lo que posiciona el raster en el extermo superior de la pantalla.
> | RTS | ; Retorna al BASIC.

> Para entender más: Este programa muestra 64 sprites a la vez, utilizando el raster.
> Para aprender más: Puedes crear 8 sprites diferentes y verás como cada uno se repite más abajo 8 veces más.

> Nº 15.- Lector Musical
> Por Linus Åkerlund, la música por Drax

> *= $0FE0 |  | ; SYS 4064.
> | LDA #$00 | ; Carga A con #$00. Esto inicializa los valores de la rutina de música.
> | TAX | ; Transfiere el contenido de A al registro X.
> | TAY | ; Transfiere el contenido de A al registro Y.
> | JSR $1000 | ; Salta a la subrutina situada en la dirección $1000 que corresponde a la música. Esto inicializa la música.
> BUCLE | LDA $D012 | ; Carga A con el valor de la dirección $D012, lo que nos da el valor del raster.
> | CPX #$80 | ; Compara el valor de A con #$80, que corresponde a la mitad de la pantalla aproximadamente.
> | BNE BUCLE | ; Salta a BUCLE hasta que sea igual a #$80.
> | INC $D020 | ; Incrementa el valor de la dirección $D020, que corresponde al borde de la pantalla. Este incremento, junto con un bucle, produce un efecto de colores.
> | JSR $1003 | ; Salta a la subrutina situada en la dirección $1003 que ejecuta la música.
> | DEC $D020 | ; Decrementa el valor de la dirección $D020. Este incremento, junto con un bucle, produce un efecto de colores.
> | JMP BUCLE | ; Salta a BUCLE.

> Para entender más: Aquí tenemos un ejemplo de qué es, a modo de ilustración, un reproductor de música convencional. Para poder oir una música debemos tener su código a partir de las direcciones $1000/$1003.
> Para aprender más: Haz tu propia música utilizando por ejemplo el programa Demo Music Creator.