Hallo!
Gleich vorweg: ich bin ein totaler Neuling auf Assembler-Gebiet. Nun wollte ich mal anfangen mit einem einfachen Programm, das einen kleinen Sprite-Ball von links nach rechts (X=255) und wieder zurück usw. springen lässt. Alles mit konstantem Y-Wert. Das habe ich auch geschafft, aber es gibt Probleme. Damit das Ganze mit dem Bildschirm einigermaßen synchronisiert wird, habe ich einen einfachen Raster-IRQ eingesetzt, der bei Bildschirmzeile Null in meine Routine geht. Die Probleme sind:
- Der Bildschirm refresht 50 mal pro Sekunde. Wenn ich also einfach $d000 um eins erhöhe, sind das ca. 50 Pixel pro Sekunde und damit zu langsam. Aber einigermaßen smooth. Also bin ich zu einer Addition von #$04 übergegangen. Das ist zwar das Tempo, das ich mir vorgestellt habe, zieht aber Schlieren. Kann man das irgendwie vermeiden?
- Wenn der Ball nach links geht, läuft er schneller, obwohl ich genauso #$04 abziehe. Das verstehe ich nicht. Hat jemand eine Erklärung dafür?
Hier mein gesamter Code:
Code
- speed = $04
- *=$0801
- ;*** Startadresse BASIC-Zeile: 2018 SYS 2062
- !word main-2, 2018
- !byte $9e
- !text " 2062"
- !byte $00,$00,$00
- main
- jsr $e544 ;clear screen
- ldx #$00
- jsr createsprite
- lda #$01
- sta $d015
- lda #$18
- sta $d000
- lda #$92
- sta $d001
- jsr paintwall
- jsr set_irq
- jmp *
- ;*** unsere eigene Interrupt-Routine
- rasterIrq
- lda $d019
- bmi doRasterIrq ;wenn ja -> Raster IRQ
- lda $dc0d ;sonst, CIA-IRQ bestätigen
- cli ;IRQs erlauben
- jmp $ea31 ;und zur ROM-Routine springen
- ;*** hier beginnt die Raster-Interrupt-Funktion
- doRasterIrq
- sta $d019 ;IRQ bestätigen
- ; Main Routine
- ldx direction
- beq goright
- jmp goleft
- goright
- lda $d000
- clc
- adc #speed
- bcs swapdirection
- sta $d000
- jmp exitirq
- goleft
- lda $d000
- clc
- sbc #speed
- cmp #$19
- bcc swapdirection
- sta $d000
- jmp exitirq
- swapdirection
- lda direction
- eor #$01
- sta direction
- ; Main Routine end
- exitirq
- pla ;Y vom Stack
- tay
- pla ;X vom Stack
- tax
- pla ;Akku vom Stack
- rti ;Interrupt verlassen
- set_irq
- sei ;Interrupts sperren
- lda #<rasterIrq ;unsere Interrupt-Routine
- sta $0314 ;in den IRQ-Vector eingtragen
- lda #>rasterIrq ;auch das MSB
- sta $0315
- lda #$00 ;Bei $00 soll ein
- sta $d012 ;Raster-IRQ ausgelöst werden
- lda $d011 ;Zur Sicherheit auch noch
- and #%01111111 ;das höchste Bit für den
- sta $d011 ;gewünschten Raster-IRQ löschen
- lda $d01a ;IRQs vom
- ora #%00000001 ;VIC-II aktivieren
- sta $d01a
- cli ;Interrupts wieder erlauben
- paintwall
- lda #$1e
- sta $fb
- lda #$04
- sta $fc
- ldy #$00
- loop
- lda #101
- ldx #$00
- sta ($fb,x)
- jsr addfourty
- iny
- cpy #$19
- bne loop
- rts
- addfourty
- lda $fb
- clc
- adc #$28
- sta $fb
- bcs addcarry
- rts
- addcarry
- ldx $fc
- inx
- stx $fc
- rts
- createsprite ;expects x=0
- lda spritedata,x
- sta $0340,x
- inx
- cpx #$40
- bne createsprite
- lda #$0d
- sta $07f8
- sta $07f9
- rts
- spritedata
- !byte 0,0,0,$3c,0,0,$7e,0,0,$7e,0,0,$7e,0,0,$7e,0,0,$3c,0,0,0,0,0
- !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- !byte 0,0,0,0,0,0,0,0,0
- direction !byte $00