Autore Topic: Un Test Per Gli Illegal Modes  (Letto 2716 volte)

Elder0010

  • Utente
  • **
  • Post: 75
    • http://csdb.dk/scener/?id=22731
  • Gioco Preferito: Rampage
Un Test Per Gli Illegal Modes
« il: 08 Luglio 2011, 00:41:06 »
Ciao ragazzi, vi mostro un po' di codice del mio demo (in progress per secoli di questo passo  :lol:).

Si tratta di uno scroller su tutto lo schermo, con una parte di schermo accesa e una spenta, di grandezza variabile. Per realizzarlo ho usato un pattern a "cubetti" (char mode), l'ho copiato su tutto lo schermo, che scrolla continuamente.

Poi, ho diviso lo schermo in aree (dall'alto in basso):
- area sempre accesa
- area "oscillante" accesa/spenta
- area centrale, con scritta
- area "oscillante" accesa / spenta
- area sempre accesa

L'effetto "a rimbalzo" è dato settando gli irq centrali leggendo da due sintables, con due diversi puntatori che oscillano tra un min e un max variabile.

La parte "spenta" è realizzata utilizzando $d011 con il valore #$7b (illegal mode). Sicuramente avrò peccato di scarsa ottimizzazione, al solito, ma vi mostro il risultato! In allegato, il prg compilato, i sorgenti e il resto :)

grazie a raffox per i cubetti!

Codice: [Seleziona]


   *=$0900
     sei          
    
    
     lda #$0
     jsr $1000
    
     lda #$35
   sta $01
    
    ;Inizializzo scroller
     lda #$0
     sta scrollcount
    
     lda $DD00
     and #%11111100
   ora #%00000011
     sta $DD00
    
    

   lda #$7f
   ldx #$01
   sta $dc0d  ; Turn off CIA 1 interrupts
   sta $dd0d  ; Turn off CIA 2 interrupts
   stx $d01a  ; Turn on raster interrupts

   lda #$1b
   ldx #$08
   ldy #$1c
   sta $d011    
   stx $d016    
   sty $d018  

   lda #<scrollcubes    
   ldx #>scrollcubes    
   ldy #$01  
   sta $fffe  
   stx $ffff
   sty $d012

   lda $dc0d  ; ACK CIA 1 interrupts
   lda $dd0d  ; ACK CIA 2 interrupts
   asl $d019  ; ACK VIC interrupts
    
    ;Setto colori sfondo e del testo (cubetti)
   lda #$0
   sta $d020
   lda #$0
   sta $d021
   lda #$6
   sta $d022
   lda #$0e
   sta $d023
   lda #$0f
   sta $d024

  
  
   lda #$d0
   sta $d016
  
   ldx #$0
clrsccubes    
   sta $0400,x  
   sta $0500,x
   sta $0600,x
   sta $0700,x
      
   dex
   bne clrsccubes

   ldx #$0
cc
   lda cubes,x
   sta $0400,x
   inx
   cpx #$2
   bne cc

   ldx #$2
   lda cubes,x
   sta $0428


   ldx #$3
   lda cubes,x    
   sta $0429

   ldx #$4
   lda cubes,x
   sta $0450
  
   ldx #$5
   lda cubes,x
   sta $0451
  
   ldx #$6
   lda cubes,x
   sta $0478
  
   ldx #$7
   lda cubes,x
   sta $0479

  
;Colori

   lda #$09
   ldx #$0
clo

   sta $d800   +$00,x
   sta $d800   +$100,x
   sta $d800   +$200,x
   sta $d800   +$300,x
  
   inx

   bne clo

;Copio un pattern
   ldx #$0
qlp
   lda $0400,x
   sta $0400+$2,x

   lda $0428,x
   sta $0428+$2,x
  
   lda $0450,x
   sta $0450+$2,x
  
   lda $0478,x
   sta $0478+$2,x
  
   inx
   cpx #$26
   bne qlp

  ;Ripeto su tutto lo schermo
   jsr clean_mid
   jsr cubecloner_top


cli

loop:

jmp loop    ; infinite loop


;SCHERMO OFF
scrollcubes:
   pha
   txa
   pha
   tya
   pha
  
   asl $d019    
  
   lda #$1b
   sta $d011
  
   lda #<cubes_sup_off  
   ldx #>cubes_sup_off  

  
   sta $fffe  
   stx $ffff
   ldx sup_sin_count
   ldy sin_sup,x
  
  ;ldy #$88
  ;ldy #$56
   sty $d012
  
   pla
   tay
   pla
   tax
   pla
   rti        ; return from interrupt
    
    
;SCHERMO OFF
cubes_sup_off

   asl $d019  ; ACK interrupt (to re-enable it)
  
   pha
   txa
   pha
   tya
   pha
  
   lda #$0
   sta $d020
  
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   nop
  
   lda #$7b
   sta $d011
   lda #<rasteropen  
   ldx #>rasteropen    
   ldy #$89  
   sta $fffe    
   stx $ffff
   sty $d012
  
   pla
   tay
   pla
   tax
   pla
   rti          

;Apertura 1
rasteropen:
   asl $d019    
  
   pha
   txa
   pha
   tya
   pha
  
  
   lda $d011
   and #%11101111
   sta $d011
  
   lda #$c0
   sta $d016
    
   lda #$16
   sta $d018

   inc scrollcount
  
   jsr show_endless
    
   ldy #$14
del1
  
   dey
   cpy #$0
   bne del1
  
   lda #$5
; sta $d021
  
   ldy #$13
del2
  
   dey
   cpy #$0
   bne del2
  
   lda #$0
; sta $d021
    
   lda #$1b
   sta $d011
  
   lda #<rasterclose  
   ldx #>rasterclose    
   ldy #$a1  
   sta $fffe    
   stx $ffff
   sty $d012
    
  
  
   pla
   tay
   pla
   tax
   pla
   rti          
    
    ;QUI INIZIANO LE OSCILLAZIONI ALL'INGIU'!
    ;SCHERMO OFF
rasterclose
   asl $d019    
    
   pha
   txa
   pha
   tya
   pha
  
   nop
   nop
    
   lda $d016
   and #%11110000
   ora scrollcount
   ora #%00010000
   sta $d016
  
   lda #$1c    ; screen at $0400, chars at $2000
   sta $d018

  
   lda #$7b
   sta $d011
   lda #<cubes_low_off  
   ldx #>cubes_low_off  
  
   sta $fffe  ; store in interrupt vector
   stx $ffff
   ldx low_sin_count
   ldy sin_inf,x
  ;ldy #$c0
  
  ;ldy #$da
   sty $d012
  
  
  ;inc s
  
   pla
   tay
   pla
   tax
   pla
   rti      


;SCHERMO OFF
cubes_low_off
  
   pha
   txa
   pha
   tya
   pha
  
   asl $d019  
  
   lda #$0
   sta $d020
  
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   nop
  
   lda #$9b
   sta $d011
   jsr $1003
   lda #<holdcubes  
   ldx #>holdcubes  
   ldy #$01    
   sta $fffe    
   stx $ffff
   sty $d012
    
  
  
   pla
   tay
   pla
   tax
   pla
   rti              
    
  ;Scrolling cubi e parte bassa dello schermo
holdcubes
   pha
   txa
   pha
   tya
   pha
  
   asl $d019  ; ACK interrupt
    
   lda #$1c  
   sta $d018


  
   lda scrollcount
   cmp #$7
   bne no_reset
  
   lda #$0
   sta scrollcount
  
  ;Copio un pattern
   ldx #$27
qloop  

   dex

   lda $0400-1,x
   sta $0400,x
  
   lda $0400+$28-1,x
   sta $0400+$28,x
  
   lda $0400+$28*2-1,x
   sta $0400+$28*2,x
  
   lda $0400+$28*3-1,x
   sta $0400+$28*3,x
  
   lda $0400+$28*4-1,x
   sta $0400+$28*4,x
  
   cpx #$0
   bne qloop
  
   lda $0402
   sta $0400
  
   lda $0400+$28*1+$2
   sta $0400+$28*1
  
   lda $0400+$28*2+$2
   sta $0400+$28*2
  
   lda $0400+$28*3+$2
   sta $0400+$28*3
  
   lda $0400+$28*4+$2
   sta $0400+$28*4
  

no_reset  
   lda #$1b
   sta $d011
  
   lda #<scrollcubes  
   ldx #>scrollcubes  
   ldy #$00  
  
  
      sta $fffe  
   stx $ffff
   sty $d012
    
      lda $d016
   and #%11110000
   ora scrollcount
   sta $d016
  
  ;inc $d020
   jsr cubecloner_top
  
  
  ;Bouncing degli irq
  
   lda sup_sin_count
   cmp sup_sin_max
   bpl max_not_reach
  
   lda sup_sin_max
   sec
   sbc #$7
   sta sup_sin_max
  

   dec sup_sin_count
   dec sup_sin_count
   dec sup_sin_count
   dec sup_sin_count

   inc low_sin_count
   inc low_sin_count
   inc low_sin_count
   inc low_sin_count
  
   jmp straight_exit
  
max_not_reach  
   inc sup_sin_count
   dec low_sin_count
  
straight_exit
    
   pla
   tay
   pla
   tax
   pla
   rti        ; return from interrupt
    


cubecloner_top
ldx #$0
  
frl
  
   lda $0400,x
   sta $0400+$28*4,x
   sta $0400+$28*8,x
   sta $0400+$28*16,x
   sta $0400+$28*20,x
   sta $0400+$28*24,x
   sta $0400+$28*28,x
  
   lda $0428,x
   sta $0428+$28*4,x
   sta $0428+$28*8,x
   sta $0428+$28*16,x
   sta $0428+$28*20,x
   sta $0428+$28*24,x
   sta $0428+$28*28,x
  
   lda $0450,x
   sta $0450+$28*4,x
   sta $0450+$28*8,x
   sta $0450+$28*12,x
   sta $0450+$28*16,x
   sta $0450+$28*20,x

  
   lda $0478,x
   sta $0478+$28*4,x
   sta $0478+$28*12,x
   sta $0478+$28*16,x
   sta $0478+$28*20,x
   sta $0478+$28*24,x
   sta $0478+$28*28,x
  
   inx
   cpx #$27
   bne frl
  
   rts
  
  


clean_mid
  
   lda #$20
   ldx #$0
cl_0  
   sta $0428+$28*8,x
   sta $0428+$28*12,x
   sta $0450+$28*8,x
   sta $0478+$28*8,x
   sta $0400+$28*12,x
  
  
   inx
   cpx #$28
  
   bne cl_0
   rts
  
show_endless
  
  
   ldy #$0
  
eelop  lda endless,y
  ;SEC
  ;adc #$40
   sta $05ef,y
  
   lda #$f
   sta $d9ef,y
   iny
   cpy #$9
   bne eelop
   rts
  

cubes
.byte $00,$01,$02,$03,$04,$05,$06,$07

endless
  .SCRU ".endless."
scrollcount
.byte $0

sup_sin_count
.byte $40

sup_sin_max
.byte $30

low_sin_count
.byte $20

sup_irq_count
.byte $0

*=$1000
incprg "music.dat"

*=$3000
incbin "cubetticc.chr"

sin_sup
incbin "SINSOR.P00"

sin_inf
incbin "SINSSK.P00"

« Ultima modifica: 22 Gennaio 2015, 00:26:03 da eregil »
lda #0 sta $d020 sta $d021

Freshness79

  • Utente
  • **
  • Post: 128
  • Gioco Preferito: Dizzy collection
Un Test Per Gli Illegal Modes
« Risposta #1 il: 08 Luglio 2011, 14:35:25 »
 'giorno coder.
L'effetto é carino ed il programma, a mio umilissimo parere, é fatto bene.
Due sole note tecniche:
- i due passaggi charmode-illegal ed illegal-charmode non sono perfettamente regolari in corrispondenza delle badline. Avendole animate velocemente non si nota molto per la verità e comunque é un problema che sto affrontando anch'io nel programmino che divide lo schermo (quello che hai visto in IRC).
Ho l'impressione che l'unica soluzione sia chiamare l'IRQ qualche linea prima, mettersi in sincrono col raster, "assorbire" l'eventuale badline ed infine al momento giusto switchare $d011. Più facile a dirsi che a farsi.
- un'ottimizzazione molto mirata al caso specifico: dal momento che il pattern che disegni é regolare (si ripete ogni 2 caratteril), invece di far scrollare l'intero schermo potresti preparare due schermate. Una con lo schermo normale e l'altra con lo schermo scrollato di un carattere a sinistra. Ogni 8 pixel scrollati poi ti basterà passare da uno schermo all'altro alternativamente.

A ME MI piace comunque!

Thumb up

antoniomauro

  • Utente
  • **
  • Post: 91
  • Gioco Preferito: IK+
Un Test Per Gli Illegal Modes
« Risposta #2 il: 08 Luglio 2011, 16:12:34 »
 Molto interessante!

Elder0010

  • Utente
  • **
  • Post: 75
    • http://csdb.dk/scener/?id=22731
  • Gioco Preferito: Rampage
Un Test Per Gli Illegal Modes
« Risposta #3 il: 08 Luglio 2011, 20:51:00 »
 Bene, grazie delle osservazioni!!

Per quanto riguarda l'ottimizzazione delle schermate, mi farebbe guadagnare altro rastertime! E' una buona cosa, considerato che le zone in alto e in basso non si spengono mai perchè ho bisogno di un sacco di  tempo per fare la copia di tutto lo schermo ad ogni frame...

Invece purtroppo ero a conoscenza del flicker.. ho tarato piu' possibile i ritardi e i colori per mascherare la faccenda :D :D il problema è che qui gli irq saltano continuamente per via di quelle due sintables con il lookup variabile e non vedo una via semplice per capire se sono in una badline o meno. Forse pensandoci a mente fresca mi verrà un'idea!
lda #0 sta $d020 sta $d021

Raffox

  • Administrator
  • Utente
  • *****
  • Post: 714
    • http://www.raffox.com
  • Gioco Preferito: Moonshadow (Idea)
Un Test Per Gli Illegal Modes
« Risposta #4 il: 08 Luglio 2011, 22:44:02 »
 
Citazione da: "Elder0010"
grazie a raffox per i cubetti!
Speriamo che il menestrello non legga... sennò chi lo sente!
Io ufficialmente faccio solo Pushover  :fagiano:  

pippo79

  • Utente
  • **
  • Post: 315
    • http://www.michelangelocarbonara.it
  • Gioco Preferito: last ninja 2
Un Test Per Gli Illegal Modes
« Risposta #5 il: 10 Luglio 2011, 16:42:21 »
Citazione da: "Raffox"
Citazione da: "Elder0010"
grazie a raffox per i cubetti!
Speriamo che il menestrello non legga... sennò chi lo sente!
Io ufficialmente faccio solo Pushover  :fagiano:

Il menestrello legge, ma è anche moooolto democratico...

E a parte ciò complimenti a Elder per il risultato ottenuto!

Raffox

  • Administrator
  • Utente
  • *****
  • Post: 714
    • http://www.raffox.com
  • Gioco Preferito: Moonshadow (Idea)
Un Test Per Gli Illegal Modes
« Risposta #6 il: 10 Luglio 2011, 16:53:49 »
 
Citazione da: "pippo79"
Il menestrello legge, ma è anche moooolto democratico...

E a parte ciò complimenti a Elder per il risultato ottenuto!
Ecco perché il menestrello ha tutta la mia infinita e incondizionata stima  ;)