Ready64 Forum
Commodore 64 => Programmazione, Grafica e Musica => Topic aperto da: iAN CooG - 29 Dicembre 2004, 00:22:46
-
Codice derivato da un mini demo trovato in giro.
In pratica viene sfruttata la locazione 53272 come detto in precedenza per scambiare l'area video tra $0400 e $0000, l'ultima riga viene visualizzata a cavallo del bordo inferiore. Notare che la riga 26 condivide la memoria colore con la riga 25 (perche' la memoria colore e' sempre e solo una a $d800, anche se si cambia locazione alla memoria video)
;26 lines!
;adapted by -=[iAN CooG/HokutoForce]=-
;C64ASM version
tapebuf=$0334
line26t=$03c0
*=$0801
.word eop
.word 7102
.byte $9e
.asc "2061"
.byte 0
eop
.word 0
SEI
LDA $DC0D
AND #$7F
ORA #$01
STA $DC0D
LDA #$F8
STA $D012
LDA $D011
AND #$7F
STA $D011
LDA #$81
STA $D01A
lda #0 ; open border dirty byte
sta $3fff; not necessary if screen is black
;sta $d020
;sta $d021
ldy #(text26-newirq);$27
pr26
lda newirq,y
sta tapebuf,y
lda text26,y
sta line26t,y
ddd
dey
bpl pr26
LDA #<tapebuf
STA $0314
LDA #>tapebuf
STA $0315
CLI
RTS
newirq
LSR $D019
LDA $D012
CMP #$F8
BEQ l0
CMP #$F3
BEQ l1
LDA #$18
STA $D011
; screen @ 0400-07e7
LDA #$14
STA $D018
LDA #$F3
BNE l2
l1
LDA #$1F
STA $D011
; screen @ 0000-03e7
; 26th line is from 03c0 to 03e7
; color ram is the same as 25th line
LDA #$04
STA $D018
LDA #$F8
l2
STA $D012
JMP $FEBC; wastes irq return
l0
LDA #$10
STA $D011
LDA #$28
STA $D012
JMP $EA31; serve normal irq return
text26
.SCRU "THIS IS LINE 26 AT ADDR $03C0-$03E7 [00]"
eotext26
-
Versione complementare:stavolta la scritta compare nella parte superiore ed è allocata a partire da $3c00.
;26 lines!
;adapted by -=[iAN CooG/HokutoForce]=-
;versione linea superiore
;C64ASM version
tapebuf=$0334
line26t=$3c00
*=$0801
.word eop
.word 7102
.byte $9e
.asc "2061"
.byte 0
eop
.word 0
SEI
LDA $DC0D
AND #$7F
ORA #$01
STA $DC0D
LDA #$F3
STA $D012
LDA $D011
AND #$7F
STA $D011
LDA #$81
STA $D01A
lda #0; open border dirty byte
sta $3fff; not necessary if screen is black
;sta $d020
;sta $d021
ldy #(text26-newirq);$27
pr26
lda newirq,y
sta tapebuf,y
lda text26,y
sta line26t,y
ddd
dey
bpl pr26
LDA #<tapebuf
STA $0314
LDA #>tapebuf
STA $0315
CLI
RTS
newirq
LSR $D019
LDA $D012
CMP #$F8
BEQ l1
CMP #$2E
BEQ l0
LDA #$1F
STA $D011; ripristina lo scroll register
LDA #$14
STA $D018; ripristina la matrice caratteri
LDA #$F8
BNE l2
l1
LDA #$13; linea 248,apre il bordo
STA $D011
LDA #$2E; prox.interrupt alla linea 46
l2
STA $D012
CMP #$2E
BEQ waste
JMP $EA31; wastes irq return
l0
LDA #$18; linea 46,aggiunge una riga in alto
STA $D011
LDA #$F4
STA $D018; matrice caratteri @ $3c00-$3fe7
LDA #$35
STA $D012; prox.interrupt alla linea 53
waste JMP $FEBC
text26
.SCRU "THIS IS LINE 0 AT ADDR $3C00-$3FE7! [00]"
eotext26
-
Spiegazione del listato precedente
Poichè il registro di scrolling verticale del C64 è a 3 bit (bit 210 di $d011) lo schermo può oscillare su e giù,per uno scostamento massimo di 7 pixel.
Per questo motivo,è possibile aggiungere una riga di testo alle 25 già presenti (a dire il vero una riga di soli 7 pixel,quindi non proprio una riga completa).
In pratica,genero un'interruzione del raster alla linea 248,commutando il bit 3 di $d011;poi,prima della linea 48,shifto lo schermo caratteri tutto verso l'alto,setto il registro $d018 (bit 7-4) in modo che il chip video prelevi la matrice caratteri dalle locazioni $3c00-$3fe7,e tengo aperti i bordi commutando di nuovo il bit 3 di $d011.
Infine,alla linea 53 (o 54,in questo caso non c'e' problema perchè non è richiesto un timing ultra-preciso) shifto lo schermo tutto verso il basso e ripristino i bit 7-4 del registro $d018,in modo che il VIC-II prenda i codici sulla matrice video dalla consueta zona $400-$7e7 (1024-2023).
Il processo si ripete ad ogni frame.
Notare due cose:
Dopo l'interrupt alla linea 53 ripristino il normale IRQ saltando alla routine $ea31 per permettere il lampeggio del cursore,etc.
La matrice caratteri non è da confondere col set di caratteri,che indica al chip video la locazione da cui prendere i byte per le forme delle lettere e dei numeri
(bit 3-1 di $d018).
A chi è interessato:
Provare a far scorrere orizzontalmente le scritte sulle righe aggiunte nei listati precedenti.
Bye
-
Ed ecco la scritta scorrevole sulla seconda versione.Uso il registro $d016 per shiftare la prima riga verso sinistra di un pixel alla volta;a shift completato,muovo tutti i caratteri di una posizione verso sinistra (=routine swap),ponendo il primo carattere in coda alla riga (per ripetere lo scorrimento del messaggio).
;26 lines!
;adapted by -=[iAN CooG/HokutoForce]=-
;versione linea superiore con scroller orizzontale
;verso sinistra
;C64ASM version
tapebuf=$0334
line26t=$3c00
*=$0801
.word eop
.word 7102
.byte $9e
.asc "2061"
.byte 0
eop
.word 0
SEI
LDA #207
STA $02 ; registro ausiliario per lo scroller
LDA $DC0D
AND #$7F
ORA #$01
STA $DC0D
LDA #$F3
STA $D012
LDA $D011
AND #$7F
STA $D011
LDA #$81
STA $D01A
lda #0; open border dirty byte
sta $3fff; not necessary if screen is black
;sta $d020
;sta $d021
ldy #(text26-newirq);$27
pr26
lda newirq,y
sta tapebuf,y
lda text26,y
sta line26t,y
ddd
dey
bpl pr26
LDA #<tapebuf
STA $0314
LDA #>tapebuf
STA $0315
CLI
RTS
newirq
LDA $D012
CMP #$F8
BEQ l1
CMP #$2E
BEQ l0
LDA #$14
STA $D018; ripristina la matrice caratteri
LDA #200
STA $D016; ripristina lo scroll register h
LDA #$1F
STA $D011; ripristina lo scroll register v
LDA $02 ;<-
CMP #207 ;<-
BNE *+5 ;<-
JSR swap ;<-
LDA #$F8
BNE l2
l1
LDA #$13; linea 248,apre il bordo
STA $D011
LDA #$2E; prox.interrupt alla linea 46
l2
STA $D012
LSR $D019;<-
CMP #$2E
BEQ waste
JMP $EA31; wastes irq return
l0
LDA #$18; linea 46,aggiunge una riga in alto
STA $D011
LDA $02 ; <-
STA $D016; <- scroll verso sinistra
DEC $02 ; <-
CMP #200; <-
BNE *+6 ; <-
ADC #6 ; <-
STA $02 ; <- re-inizializza lo scroll register h
LDA #$F4
STA $D018; matrice caratteri @ $3c00-$3fe7
LDA #$36
STA $D012; prox.interrupt alla linea 54
waste LSR $D019
JMP $FEBC
; <-
swap LDX #0 ; routine di swap dei caratteri
LDY $3C00
LDA $3C01,X
STA $3C00,X
INX
CPX #40
BNE swap+5
STY $3C27
RTS
; <-
text26
.SCRU "THIS IS LINE 0 AT ADDR $3C00-$3FE7! [00]"
eotext26
Le parti aggiunte sono indicate con una freccetta :)