border sprite c64

border - ¿Cómo se muestran los sprites en el borde de C64?



(5)

He visto demostraciones geniales de C64 que muestran sprites en el área fronteriza de la pantalla. No debería ser posible; Creo que lograron engañar al chip gráfico de alguna manera. ¿Cómo exactamente lo hicieron?


El tiempo fue la clave. La imagen se creó en el borde cambiando el color del overscan (borde) a medida que el rayo del CRT se movía de izquierda a derecha. Se requieren dos señales de tiempo para producir una imagen: actualización vertical y actualización horizontal. Al detectar cuándo se produce la actualización horizontal y vertical, puede iniciar una secuencia de instrucciones del ensamblador para cambiar el color del borde y producir una imagen. Debe calcular la cantidad de marcas de reloj de la CPU por píxel de borde y usar eso para crear un código que cambie el color del borde en el punto correcto.

No funciona muy bien cuando se trata de escribir juegos, ya que la sobrecarga de la CPU es demasiado grande para que haya un aumento de tiempo para procesar la entrada del usuario y el estado del juego.


Eso fue hace mucho tiempo.

Sé que había una solución que dependía de la frecuencia del monitor.

Con un CRT, el píxel actual se conoce incluso si estaba fuera de la pantalla normal. Entonces puedes manipular el rayo.

En algún lugar de mi junkpile debe haber algunos libros C64.

Offtopic, pero los gráficos con el VIC20 (el predecesor del C64) fueron divertidos. No había forma de manipular cada píxel, pero podría cambiar los caracteres existentes. Entonces llenó la pantalla con todos los caracteres de 0 a ... y cambió los caracteres para establecer píxeles en la pantalla. ;-).


Para obtener un buen tutorial sobre el tema de la apertura de fronteras en el C64, consulte el excelente artículo de Pasi Ojala en C = Hacking Issue 6 .

Sin ser demasiado técnico, el truco utiliza una característica del chip VIC para permitirle cambiar entre 25/24 filas y 40/38 columnas de texto / gráficos, e implica hacer este cambio en el momento preciso para engañar al VIC y hacerle pensar ya ha cambiado las fronteras cuando en realidad no lo ha hecho. Consulte el artículo anterior para obtener una explicación más completa con ejemplos de código.


Sí, necesitas ensamblador. Es un truco de tiempo de interrupción. El VIC puede mostrar los sprites en el borde, pero el marco simplemente los está ocultando, por lo que los sprites pueden deslizarse detrás de él. Está conectado a líneas de exploración visualizadas por el VIC. Para bordes inferiores / superiores es bastante simple:

  • Programe una interrupción, sincronizada para comenzar en una determinada línea de escaneo, 7 píxeles o algo así antes del borde inferior.
  • Establezca el registro en VIC para hacer el borde más pequeño. (Hay un registro que puede hacer eso).
  • VIC ahora cree que el límite ya comenzó y no comienza a pintarlo.
  • -> Sin borde en la parte inferior.
  • Programar otra interrupción después del borde real para volver a establecer el original.

Para los sprites en los bordes izquierdo / derecho, es más complicado porque el proceso debe repetirse para cada línea de exploración:

  • Programe una interrupción, sincronizada para comenzar en cierta línea de exploración.
  • Luego haga algunos NOP hasta que tenga 7 píxeles antes del borde derecho.
  • Establezca el registro en VIC para hacer el borde más pequeño.
  • -> Sin borde en el lado derecho.
  • Haga algunos NOP hasta que esté detrás del borde real y vuelva a establecer el registro en el valor original.
  • Nuevamente haga algunos NOP hasta el paso 2.

El problema es que todos estos NOP están ocupados esperando y robando los ciclos que tienes para tus cosas.

Pude encontrar un código para ti, desde un scroll de sprites en el borde inferior. Aquí está el código. (Fue arrancado de una demo)

C198 78 SEI C199 20 2E C1 JSR C12E # clear sprite area C19C 20 48 C1 JSR C148 # init VIC C19F A9 BF LDA #BF # set up IRQ in C1BF C1A1 A2 C1 LDX #C1 C1A3 8D 14 03 STA 0314 C1A6 8E 15 03 STX 0315 C1A9 A9 1B LDA #1B C1AB 8D 11 D0 STA D011 C1AE A9 F7 LDA #F7 C1B0 8D 12 D0 STA D012 C1B3 A9 01 LDA #01 C1B5 8D 1A D0 STA D01A C1B8 A9 7F LDA #7F C1BA 8D 0D DC STA DC0D C1BD 58 CLI C1BE 60 RTS ---------------------------------- # init VIC C148 A2 00 LDX #00 C14A BD 88 C1 LDA C188,X C14D 9D 00 D0 STA D000,X # set first 16 values from table C150 E8 INX C151 E0 10 CPX #10 C153 D0 F5 BNE C14A C155 A9 FF LDA #FF C157 8D 15 D0 STA D015 C15A A9 00 LDA #00 C15C 8D 1C D0 STA D01C C15F A9 FF LDA #FF C161 8D 17 D0 STA D017 C164 8D 1D D0 STA D01D C167 A9 C0 LDA #C0 C169 8D 10 D0 STA D010 C16C A9 F8 LDA #F8 C16E A2 00 LDX #00 C170 9D F8 07 STA 07F8,X C173 18 CLC C174 69 01 ADC #01 C176 E8 INX C177 E0 08 CPX #08 C179 D0 F5 BNE C170 C17B A9 0E LDA #0E C17D A2 00 LDX #00 C17F 9D 27 D0 STA D027,X C182 E8 INX C183 E0 08 CPX #08 C185 D0 F8 BNE C17F C187 60 RTS ---------------------------------- # data set into VIC registers C188 00 F7 30 F7 60 F7 90 F7 C190 C0 F7 F0 F7 20 F7 50 F7 ---------------------------------- # main IRQ routine C1BF A2 08 LDX #08 C1C1 CA DEX C1C2 D0 FD BNE C1C1 C1C4 A2 28 LDX #28 # 40 or so lines C1C6 EA NOP # "timing" C1C7 EA NOP C1C8 EA NOP C1C9 EA NOP C1CA CE 16 D0 DEC D016 # fiddle register C1CD EE 16 D0 INC D016 C1D0 AC 12 D0 LDY D012 C1D3 88 DEY C1D4 EA NOP C1D5 98 TYA C1D6 29 07 AND #07 C1D8 09 18 ORA #18 C1DA 8D 11 D0 STA D011 C1DD 24 EA BIT EA C1DF EA NOP C1E0 EA NOP C1E1 CA DEX C1E2 10 E4 BPL C1C8 # repeat next line C1E4 A9 1B LDA #1B C1E6 8D 11 D0 STA D011 C1E9 A9 01 LDA #01 C1EB 8D 19 D0 STA D019 C1EE 20 00 C0 JSR C000 # call main code C1F1 4C 31 EA JMP EA31 # finish IRQ


Todo dependía del tiempo. El C64 tenía un método para consultar la ubicación vertical exacta del haz de electrones mientras dibujaba la pantalla. Cuando se iniciaba una nueva línea, tenías que esperar algunos ciclos (podías cronometrar esto usando la instrucción NOP) y luego tenías que establecer un registro de hardware del videochip que era responsable de configurar el modo de pantalla (y el ancho del borde). Al sincronizarlo exactamente, y al hacerlo en cada línea de escaneo otra vez, toda la frontera lateral desapareció.

El borde inferior se fue con un truco similar. En la línea de escaneo exacta donde se inició el borde vertical, también debe establecer el videomodo que deshabilitó el borde inferior para ese marco.

De hecho, todo esto tuvo que hacerse en asamblea. De lo contrario, nunca podrías tener el tiempo exacto.

Como nota al margen, creo que el truco sideborder fue acreditado a la tripulación 1001 (un grupo holandés). No estoy seguro de quién realizó el primer truco de la frontera inferior.