Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: iAN CooG - 09 Luglio 2006, 16:35:33
-
Non si finisce mai di imparare dagli altri. Stavolta ho trovato un modo di temporizzare i rasters molto particolare, facendo delle JSR/RTS a vuoto :)
Notare come la routine rimane stabile nonostante usi $ea31 e non un flipflop su $d019 per decidere se saltare a $ea31 o $ea81 ma soprattutto sembri fregarsene delle badlines....
;original by hannenz
;adattato da iAN CooG/HokutoForce
;sys4096 attiva
;sys4099 disattiva
*=$1000
jmp irqon
jmp irqoff
irqon
sei
lda #$7f
sta $dc0d
bit $dc0d
lda #$32
sta $d012
lda $d011
and #$7f
sta $d011
lda #$81
sta $d01a
ldx #<irq
ldy #>irq
stx $0314
sty $0315
cli
frame rts
;--------------------------------------
irq dec $d019
nop ;timing
jsr frame;timing
jsr frame;timing
another
ldy #$00
gc ldx #$08
gcl lda colors,y
sta $d020
sta $d021
iny
dex
beq gc
lda frame;timing
jsr frame;timing
jsr frame;timing
jsr frame;timing
cpy #[endcolors-colors]
bcc gcl
;lda #$00; questi non servono se l'ultima volta ha gia' messo 0
;sta $d020
;sta $d021
jmp $ea31
;--------------------------------------
irqoff
sei
ldx #$31
stx $0314
ldy #$ea
sty $0315
lda #$f0
sta $d01a
lda #$81
sta $dc0d
bit $dc0d
cli
rts
;colorbars by iAN CooG :P
colors
byte $06,$00
byte $06,$0e,$00
byte $06,$0e,$03,$00
byte $06,$0e,$03,$01
byte $0c,$0b,$0f,$01,$0f,$0c,$0b
byte $01,$03,$0e,$06
byte $00,$03,$0e,$06
byte $00,$0e,$06
byte $00,$06
byte $00
byte $0B,$00
byte $0B,$0C,$00
byte $0B,$0C,$0F,$00
byte $0B,$0C,$0F,$01
byte $02,$0A,$07,$01,$07,$0A,$02
byte $01,$0F,$0C,$0B
byte $00,$0F,$0C,$0B
byte $00,$0C,$0B
byte $00,$0B
byte $00
byte $02,$00
byte $02,$0A,$00
byte $02,$0A,$07,$00
byte $02,$0A,$07,$01
byte $09,$08,$07,$01,$07,$08,$09
byte $01,$07,$0A,$02
byte $00,$07,$0A,$02
byte $00,$0A,$02
byte $00,$02
byte $00
byte $09,$00
byte $09,$08,$00
byte $09,$08,$07,$00
byte $09,$08,$07,$01
byte $0C,$05,$0D,$01,$0D,$05,$0C
byte $01,$07,$08,$09
byte $00,$07,$08,$09
byte $00,$08,$09
byte $00,$09
byte $00
byte $00
endcolors
-
Scusate la mia ignoranza, il significato di questo codice:
ldx #<irq
ldy #>irq
-
I segni di maggiore e minore stanno per byte alto e byte basso.
ldx #<irq
Carica nel registro X il byte basso dell'indirizzo corrispondente alla label "irq".
ldy #>irq
Carica nel registro Y il byte alto dell'indirizzo corrispondente alla label "irq".
Ad esempio se la label "irq" corrispondesse all'indirizzo $c034 l'assemblatore genererebbe
ldx #$34
ldy #$c0
-
Per chi volesse avere un'idea di cosa succede nella macchina non c'e' niente di
meglio che contare i ciclozzi :)
Il gestore di interrupt viene eseguito dopo 38-41 cicli (29 cicli per determinare la
sorgente dell'interrupt a $ff48,da sommare a 7 cicli per salvare sulla pila registri
e indirizzo di ritorno e a un numero compreso tra 2 e 5 cicli per terminare
l'esecuzione dell'istruzione prima della generazione dell'IRQ).
irq ;ciclo
dec $d019 ;44-47
nop ;timing 46-49
jsr frame;timing 58-61 <-- 12 cicli (6 x jsr+6 x rts)
jsr frame;timing 7-10
another
ldy #$00 ; 9-12
gc
ldx #$08 ;11-14
gcl
;--- *badline:CPU ferma* ---
lda colors,y ;58
sta $d020 ;62
sta $d021 ; 3 <-- linea 51
iny ; 5
dex ; 7
beq gc ; 9
lda frame;timing 13
jsr frame;timing 25
jsr frame;timing 37
jsr frame;timing 49
cpy #endcolors-colors ;51
bcc gcl ;54
jmp $ea31
Dai commenti si può notare come la prima scanline che viene colorata è la 51,perchè quando la routine viene chiamata il raster si trova ben oltre la metà della scanline 50.
Ogni 63 cicli esatti (la durata di una scanline nel sistema video PAL) si ripete il ciclo gcl,ma quando il registro x si azzera il raster si trova su una badline,per cui la CPU deve lasciar perdere il delay (le quattro istruzioni dopo beq gc ) altrimenti,dopo essere rimasta in interdizione per ben 40 cicli,$d020-$d021 verrebbero modificati ben oltre la metà della scanline succesiva (con conseguente spettinamento).
jmp $ea31 forza l'esecuzione dell'IRQ standard;al contempo non disturba in nesun modo la routine perchè viene eseguita fuori dalla zona video manipolata.