40 votes

Comment afficher les sprites à la frontière sur C64?

J'ai vu des démos C64 montrant des sprites dans la zone de bordure de l'écran. Cela ne devrait pas être possible. Je pense qu'ils ont réussi à tromper la puce graphique en quelque sorte. Comment l'ont-ils fait exactement?

33voto

Peter Kofler Points 4421

Oui, vous avez besoin de l'assembleur. C'est une interruption calendrier truc. Le VIC est en mesure d'afficher des sprites à la frontière, mais le cadre est juste les cacher, de sorte que les sprites peuvent glisser begind il. Il est connecté aux lignes de balayage affichée par le VIC. Pour inférieure/supérieure de la frontière c'est très simple:

  • Programm une interruption, synchronisés pour commencer à une certaine ligne de balayage, 7 pixels ou qqch comme ça avant que le bord inférieur.
  • Définir le registre de VIC à rendre la frontière plus petits. (Il y a un registre qui peut le faire.)
  • VIC croit maintenant que la frontière déjà commencé et ne pas commencer à peindre.
  • -> Pas de bordure en bas.
  • Programm un autre interruption après la frontière réelle de jeu en arrière à l'original.

Pour les sprites dans le gauche/droite de la bordure, c'est plus compliqué parce que le processus doit être répété pour chaque ligne de balayage:

  • Programm une interruption, synchronisés pour commencer à une certaine ligne de balayage.
  • Ensuite, faire un peu Opr, jusqu'à ce que vous êtes 7 pixel avant de la bordure droite.
  • Définir le registre de VIC à rendre la frontière plus petits.
  • -> Pas de frontière sur le côté droit.
  • Faire quelques Opr, jusqu'à ce que vous êtes après la frontière réelle et remettre le registre à la valeur d'origine.
  • De faire à nouveau quelques Opr, jusqu'à l'étape 2.

Le problème est que tous ces Opr sont occupés attend et voler les cycles que vous avez pour votre stuff.

Mise à jour: j'ai été capable de trouver un peu de code pour vous, à partir d'un sprite scroller dans le bord inférieur. Voici le code. (Il a été arraché de démonstration.)

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

10voto

Toad Points 7868

il sont tous fondés sur le calendrier. Le c64 avait une méthode pour interroger l'exact emplacement vertical du faisceau d'électrons alors que c'était le dessin de l'écran. Lorsqu'une nouvelle ligne a commencé, vous avez dû attendre quelques cycles (vous pourriez de temps cela à l'aide de l'instruction NOP) et puis vous aviez à définir un registre hardware de la videochip qui était responsable de la définition de la screenmode (et la largeur de la bordure). Par la synchronisation exactement, et de le faire chaque scanline encore une fois, l'ensemble de la sideborder disparu.

La bordure inférieure allé loin avec une astuce similaire. Sur le scanline où la bordure verticale commencé à vous aussi, vous aviez à définir le mode vidéo qui invalide la bordure inférieure de cette image.

en effet, toute cette chose devait être fait dans l'assemblée. sinon, vous pourriez ne jamais obtenir le timing exact

comme une note de côté. Je pense que le sideborder astuce a été crédité pour la 1001 de l'équipage (un groupe néerlandais). Je ne suis pas sûr de qui a arraché la première bordure inférieure truc

9voto

Lars Haugseth Points 7377

Pour un bon tutoriel sur le sujet de l'ouverture de la frontière sur le C64, découvrez Pasi Ojala l'excellent article de C=Piratage Numéro 6.

Sans être trop technique, l'astuce utilise une fonctionnalité de la VIC puce pour vous permettre de passer entre 25/24 lignes et 40/38 colonnes de texte ou de graphiques, et implique le fait de ce changement, au bon moment, pour tromper le VIC en pensant qu'il a déjà changé les frontières, alors qu'en fait il n'a pas. Découvrez l'article ci-dessus pour une explication plus complète avec des exemples de code.

1voto

Toon Krijthe Points 36327

C'est il y a longtemps.

Je sais qu'il y a une solution qui s'appuient sur la fréquence du moniteur.

Avec un CRT, le pixel actuel est connu, même si c'était en dehors de l'écran normal. De sorte que vous pouvez manipuler la ray.

Quelque part dans mon junkpile il doit y avoir un C64 livres.

Futiles, mais les graphiques avec le VIC20 (le prédécesseur du C64) était amusant. Il n'y a aucun moyen de manipuler chaque pixel, mais vous pouvez changer les caractères existants. Si vous avez rempli l'écran avec tous les caractères de 0 à ... et changé les caractères de l'ensemble de pixels à l'écran. ;-).

-1voto

Skizz Points 30682

Le Timing est la clé. L'image a été créée à la frontière par l'évolution de l'overscan (frontière) couleur que les tubes du faisceau déplacé de gauche à droite. Il y a deux signaux de synchronisation nécessaire pour produire une image de rafraîchissement vertical et horizontal de l'actualisation. Par la détection lors de l'horizontale et à la verticale d'actualisation se produit, vous pouvez commencer une séquence d'instructions en assembleur pour modifier la bordure de couleur pour produire une image. Vous avez besoin de travailler sur le nombre de CPU clock ticks par des pixels de contour et de l'utiliser pour créer un code qui change les couleurs de bordure au point droit.

Il ne fonctionne pas très bien quand il s'agit de l'écriture de jeux que la charge du CPU est trop grande pour qu'il y ait tout le temps de le soulever pour le processus de saisie de l'utilisateur et de l'état de jeu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X