Autore Topic: Any Given Screen Position  (Letto 2505 volte)

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Any Given Screen Position
« il: 24 Maggio 2009, 22:47:48 »
Buonasera a tutti,

dopo aver scritto una routine di DMA Delay ho voluto cimentarmi nella naturale evoluzione di quell'effetto.
Il programma che allego in questo thread é un esempio di AGSP (Any Given Screen Position): questo effetto si ottiene usando DMA Delay per gli spostamenti orizzontali (modulo 8) ed il linecrunch per quelli verticali (modulo 7).
Analogamente al caso precedente, non viene effettuata alcuna modifica nei valori dello schermo, lo scrolling é totalmente hardware.
Questo effetto si presta molto bene alla realizzazione di platform, non fosse per quei maledettissimi 8 byte degli sprite pointers (per i quali esistono delle soluzioni compromesso).
Noterete che lo schermo risulta più piccolo del normale, ciò é dovuto al fatto che nella zona superiore vengono realizzati gli effetti e vengono coperti usando una delle modalità grafiche illegali (EBCM+BITMAP).
Cambiando colore al bordo ($d020) si può notare l'area interessata.
Per i più curiosi, commentando le linee 132,133,175,176,203 é possibile gestire "a mano" il riposizionamento dello schermo usando le seguenti variabili:
$F7: Posizione verticale (0-206)
$F9: Posizione orizzontale (0-39)
La posizione verticale é gestibile per linea, quella orizzontale per carattere.
Al solito, commenti, consigli ecc... son sempre i benvenuti!
Ecco il source:

Codice: [Seleziona]
; AGSP - By Freshness
;
; Grazie iAN, ci sono ancora alcuni FIX tuoi nella parte di
; inizializzazione dell'IRQ e nei comandi basic!
;
;

NOPOpcode = $EA
rastline  = $2E;

ypospre   = $F7; Posizione base pre-fixing
ypos   = $F8; Posizione verticale
XValue   = $F9; Shift verticale dovuto al DMA
Increment = $FA; Incremento verticale (0-7)
CrunchShf = $FB; Shift orizzontale dovuto al crunch
setDEN    = $FC; Imposta il primo valore di $d011 per frame
sinuspos  = $FD; Indice delle sinustable
xpos      = $FE; Posizione orizzontale corrente
temp   = $FF; Uso generico



*=$0801
  word eoprg
  word 2009
  byte $9E,[intro]d,":",$8f,$0d,"AGSP BY FRESHNESS79"
  byte 0
eoprg
  word 0

intro
  lda #$72        ; Attivazione schermo (D011 - bit DEN)
  sta setDEN  
  lda #$00        ; Resetta la posizione della sinus table
  sta $d020  ; Resetta il colore del bordo (nero),
  sta XValue; Coordinata X fissa,
  sta sinuspos; Indice sinustable,
  sta Increment; Incremento coordinata Y
  jsr initIRQ      ; Inizializzazione raster IRQ
  cli              ; Interrupt attivati
  rts


; ***************************************************
; * Routine di sincronizzazione a doppio raster IRQ *
; ***************************************************
; La prima chiamata IRQ e' su JMP, quindi l'incertezza e' di 1-3 cicli
; Il primo handler permette di ridurla a 1-2 cicli: IRQ arriva sulla NOP
; Il secondo handler infine grazie ad un confronto a fine raster elimina
; l'ultima possibile incertezza

fstirq  ; 2E
  lsr $d019        ; 6 + (36 Kernal IRQ) + (da 2 a 4 JMP)
  inc $d012        ; 6 interrupt al prossimo raster
  lda #<secirq    ; 2 reimposto il vettore IRQ perche' punti
  sta $0314        ; 4 al secondo handler
  cli              ; 2 attivo gli interrupt
  nop              ; 2 (63-65) <= IRQ
  nop              ; 2 (65-67) <= IRQ
  nop
  nop
  nop
  nop
  brk              ; Qua non ci si arriva mai, lascio BRK per test

secirq  ; $2F
  lda setDEN; 2w +38 (+0/1); Evita la badline
  sta $d011  ; 4 nella prima linea (la $30)    
  sec  ; 2 Serve per la sottrazione nel successivo ciclo
  lda ypos  ; 3 Imposta il contatore dello scroll  
  sta temp  ; 3 verticale
  ldx #$71  ; 2 Imposta il primo valore di crunching
  ldy #$00  ; 2 Resetta numero di linee "crunched"
  lda #$2F  ; 2 Stabilizzazione raster  
  eor $d012        ; 4 - 63 se il ritardo dovuto alla NOP era 1 (uso EOR per mantenere il carry)
  beq crunch      ; 3 effettuo un branch per allinearmi

; linecrunch
; ----------
; Spostamento verticale a blocchi di 7 linee per ciclo

crunch  ; Synced - line $30
  stx $d011  ; 4  Ciclo 11: abortisce la badline (linecrunch)
  ds  $12,NOPOpcode; 36w (18 NOPs)
  lda temp  ; 3  Aggiorna contatore scroll
  sbc #$07  ; 2  verticale
  sta temp  ; 3  
  bcc DmaDelay; 2/3  Se mancano meno di 7 linee va al Dma Delay
  nop  ; 2w
  nop  ; 2
  iny  ; 2    
  ldx lctable-1,y; 4  Carica il prossimo valore per il linecrunch
  bne crunch; 3 - 63 cicli totali


; Dma Delay
; ----------
; Spostamento orizzontale da 0 a 39 caratteri
    
DmaDelay  
  inc $d011  ; 6 fa in modo che la prossima linea non sia una bad line
  lda xpos  ; 3 calcolo dei cicli da aspettare
  lsr  ; 2 usando i due branch
  sta wdcc+1; 4
  bcc wdcc  ; 2/3 branch unitario (0/1)
wdcc  
  bpl *  ; 3 branch multiplo di 2 (2-38)
  ds  $13,NOPOpcode; 19 NOPs
  stx $d011  ; crea la bad line (DMA delay)
  

; Fine Tune Y
; ----------
; Spostamento verticale da 0 a 6 linee

FineTuneY  ; ciclo 55 sempre!
  sec  ; 2
  lda temp  ; 3
  sty temp  ; 3 Conto delle righe saltate
  sbc #$fa  ; 2 Rimanenti righe da scrollare (scroll fine)
  sbc temp  ; 3 Sottraggo le linee dovute alle righe saltate
  and #$07  ; 2
  eor #$77  ; 2 La direzione é contraria quindi 7-X
  sta $d011  ; 4 - 21 => 13

; Fine Tune X
; ----------
; Spostamento orizzontale da 0 a 7 pixel

FineTuneX  
  ldx sinuspos;sinuspos    
  lda sinuslow,x  ; Parte meno significativa dello spostamento
  sta $d016        ; orizzontale - scrolling fine  


; Impostazioni di fine IRQ

  lda #$56  ; Prossimo raster IRQ alla linea 83
  sta $d012  ;
  lsr $d019        ; Acknowledge del raster IRQ      
  lda #<irq3; Caricamento prossimo vettore IRQ
  sta $0314  ; Salvataggio vettore IRQ
  tsx  ;
  lda #$ff  ;
  sbx #$fa  ;
  txs              ; ripristino dello stack pointer
  jmp $ea81        ; Uscita dall'interruzione


; IRQ3
; ----
; Reimpostazione modalità testo
    
irq3
  lda $d011  ; Carica l'attuale valore di $d011
  and #$17      ; Elimina i bit della modalità illegale
  ldy #$58  ; Attende la raster line $58
  cpy $d012  ;
  bne *-3    ;
  sta $d011    ; Imposta $D011, da qua in poi si vede.
  lda #rastline; Imposta il raster IRQ del frame
  sta $d012  ; successivo
  lsr $d019    ; Ack dell'interruzione
  lda #<fstirq; Reimpostazione dell'IRQ handler,
  sta $0314    ; si torna al primo

  
; UpdatePos
; ---------
; Aggiornamento variabili relative alla posizione orizzontale e verticale

UpdatePos
  inc sinuspos; Incremento posizione sinus table
  ldx sinuspos; Carico in X l'indice
  lda sinusspeed,x; L'incremento é precalcolato e
  sta Increment; viene preso da una sinustable
  lda ypospre; Incremento posizione verticale
  clc  ;
  adc Increment;
  sta ypospre    ;
  cmp #$cf  ; Supera la dimensione massima? (200+7)
  bcc EndUpdate
  sbc #$cf  ; Si, sottrai 207, si riparte da 0
  sta ypospre  ;
  lda CrunchShf; Aumenta di 16 lo shift dovuto al linecrunch
  adc #$0f  ; Carry abilitato quindi +$10
  sta CrunchShf;
  cmp #$28  ; Lo shift ha superato i 40 caratteri?
  bcc EndUpdate    
  sbc #$28  ; Si, sottrai 40, si riparte da 0
  sta CrunchShf;
  lda ypospre; Shifta di 8 linee la posizione verticale
  adc #$07  ; Carry abilitato quindi +$07
  sta ypospre  


; EndUpdate
; ---------
; Calcola l'effettivo valore della posizione verticale ed orizzontale
    
EndUpdate      
  lda CrunchShf; Aggiunge lo shift dovuto al linecrunch
  adc sinushigh,x  ; all'attuale valore della sinustable
  adc XValue; Coordinata fissa
  cmp #$28  ; Confronta con 40
  ldy #$00  ;
  bcc HNoFix; Se supera 40, sottrai 40 ed segna 8 linee
  sbc #$28  ; da skippare nel linecrunch
  ldy #$08  ;
HNoFix
  sta xpos  ; Imposta il valore per il DMA Delay (X Coord)
  clc  ;
  tya  ; Fixa il valore della coordinata verticale con  
  adc ypospre; l'eventuale valore dovuto al DMA Delay
  sta ypos  ;
  jmp $ea31  ; Vai all'handler standard


  
; ************
; * Init IRQ *
; ************
;
; Disattivazione dell'interrupt standard,
; Impostazione della prima rasterline e dell'indirizzo
; del primo handler della routine di interrupt
; attivazione dei raster interrupt

initIRQ
  sei
  lda #$7f
  sta $dc0d
  sta $dd0d
  lda $dc0d;non dc0c ! - Fix iANCoog
  lda $dd0d;non dd0c !
  lda #$00
  sta $d011
  lda #rastline
  sta $d012
  lda #<fstirq
  sta $0314
  lda #>fstirq
  sta $0315
  lda #$01
  sta $d01a
  lsr $d019
  rts
  
lctable
  byte $72,$73,$74,$75,$76,$77,$70,$71,$72,$73,$74,$75,$76,$77,$70,$71
  byte $72,$73,$74,$75,$76,$77,$70,$71,$72,$73,$74,$75,$76,$77,$70,$71
    
align $100

sinuslow
  byte $07,$04,$00,$04,$00,$04,$00,$04,$00,$05,$01,$05,$01,$06,$02,$06
  byte $03,$07,$04,$00,$05,$01,$06,$02,$07,$04,$01,$06,$03,$00,$05,$02
  byte $07,$04,$02,$07,$05,$02,$00,$06,$03,$01,$07,$05,$03,$01,$00,$06
  byte $05,$03,$02,$01,$07,$06,$05,$04,$04,$03,$02,$02,$01,$01,$01,$01
  byte $00,$01,$01,$01,$01,$02,$02,$03,$04,$04,$05,$06,$07,$01,$02,$03
  byte $05,$06,$00,$01,$03,$05,$07,$01,$03,$06,$00,$02,$05,$07,$02,$04
  byte $07,$02,$05,$00,$03,$06,$01,$04,$07,$02,$06,$01,$05,$00,$04,$07
  byte $03,$06,$02,$06,$01,$05,$01,$05,$00,$04,$00,$04,$00,$04,$00,$04
  byte $07,$03,$07,$03,$07,$03,$07,$03,$07,$02,$06,$02,$06,$01,$05,$01
  byte $04,$00,$03,$07,$02,$06,$01,$05,$00,$03,$06,$01,$04,$07,$02,$05
  byte $00,$03,$05,$00,$02,$05,$07,$01,$04,$06,$00,$02,$04,$06,$07,$01
  byte $02,$04,$05,$06,$00,$01,$02,$03,$03,$04,$05,$05,$06,$06,$06,$06
  byte $06,$06,$06,$06,$06,$05,$05,$04,$03,$03,$02,$01,$00,$06,$05,$04
  byte $02,$01,$07,$06,$04,$02,$00,$06,$04,$01,$07,$05,$02,$00,$05,$03
  byte $00,$05,$02,$07,$04,$01,$06,$03,$00,$05,$01,$06,$02,$07,$03,$00
  byte $04,$01,$05,$01,$06,$02,$06,$02,$07,$03,$07,$03,$07,$03,$07,$03

sinushigh
  byte $14,$14,$14,$15,$15,$16,$16,$17,$17,$18,$18,$19,$19,$1A,$1A,$1B
  byte $1B,$1C,$1C,$1C,$1D,$1D,$1E,$1E,$1F,$1F,$1F,$20,$20,$20,$21,$21
  byte $22,$22,$22,$23,$23,$23,$23,$24,$24,$24,$25,$25,$25,$25,$25,$26
  byte $26,$26,$26,$26,$27,$27,$27,$27,$27,$27,$27,$27,$27,$27,$27,$27
  byte $27,$27,$27,$27,$27,$27,$27,$27,$27,$27,$27,$27,$27,$26,$26,$26
  byte $26,$26,$25,$25,$25,$25,$25,$24,$24,$24,$23,$23,$23,$23,$22,$22
  byte $22,$21,$21,$20,$20,$20,$1F,$1F,$1F,$1E,$1E,$1D,$1D,$1C,$1C,$1C
  byte $1B,$1B,$1A,$1A,$19,$19,$18,$18,$17,$17,$16,$16,$15,$15,$14,$14
  byte $14,$13,$13,$12,$12,$11,$11,$10,$10,$0F,$0F,$0E,$0E,$0D,$0D,$0C
  byte $0C,$0B,$0B,$0B,$0A,$0A,$09,$09,$08,$08,$08,$07,$07,$07,$06,$06
  byte $05,$05,$05,$04,$04,$04,$04,$03,$03,$03,$02,$02,$02,$02,$02,$01
  byte $01,$01,$01,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
  byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01,$01,$01
  byte $01,$01,$02,$02,$02,$02,$02,$03,$03,$03,$04,$04,$04,$04,$05,$05
  byte $05,$06,$06,$07,$07,$07,$08,$08,$08,$09,$09,$0A,$0A,$0B,$0B,$0B
  byte $0C,$0C,$0D,$0D,$0E,$0E,$0F,$0F,$10,$10,$11,$11,$12,$12,$13,$13

sinusspeed  
dc.b $4,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$2,$2
dc.b $2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$1,$1
dc.b $1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1
dc.b $1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1
dc.b $1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1
dc.b $1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1,$1
dc.b $1,$1,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2,$2
dc.b $2,$2,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3,$3
dc.b $4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$5,$5
dc.b $5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$6,$6
dc.b $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6
dc.b $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6
dc.b $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6
dc.b $6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6,$6
dc.b $6,$6,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5,$5
dc.b $5,$5,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4,$4
« Ultima modifica: 21 Gennaio 2015, 23:53:11 da eregil »

iAN CooG

  • Utente
  • **
  • Post: 1774
    • http://iancoog.altervista.org
  • Gioco Preferito: Turbo Assembler, ActionReplay Monitor, DiskDemon
Any Given Screen Position
« Risposta #1 il: 25 Maggio 2009, 21:18:42 »
Fantastico, ci scapperebbe un megaintro tipo questi
http://intros.c64.org/main.php?module=showintro&iid=358
http://intros.c64.org/main.php?module=showintro&iid=359
http://intros.c64.org/main.php?module=showintro&iid=1984

Complimenti per la costanza, ti auguro di mettere in pratica al piu' presto tutte queste conoscenze in una produzione di piu' ampio respiro. La scena C64 ha bisogno di bravi coders, sempre.
« Ultima modifica: 21 Gennaio 2015, 23:52:36 da eregil »
-=[]=--- iAN CooG/HVSC^C64Intros ---=[]=-
- http://hvsc.c64.org - http://intros.c64.org -