Friday, 15 May 2015

assembly - Stable raster on C64 -



assembly - Stable raster on C64 -

using 6510 assembly on commodore 64, trying create stable raster effect. using double irq principle draw raster lines on screen. pad nops match 63 cycles every normal scanline, , 23 cycles every badline. realise there specific start line need set, in order match 8th iteration badline, no matter on line set first line or combination of nops use, can't timing right. want finish lines not "broken". can see doing wrong? code in kick assembler format. , here screenshot:

.pc = $0801 "basic upstart" :basicupstart($8000) .pc = $8000 "program" jsr $ff81 sei lda #$35 sta $01 jsr setupinterrupts cli jmp * setupinterrupts: lda #<int1 ldy #>int1 sta $fffe sty $ffff lda #$01 sta $d01a lda #$7f sta $dc0d sta $dd0d lda $dc0d lda $dd0d lda #$1b sta $d011 lda #$01 sta $d019 lda start sta $d012 rts start: .byte 56 int1: pha txa pha tya pha :stabilize() .for (var i=0; i<7; i++) { inc $d020 // 6 cycles inc $d021 // 6 cycles nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop // 24*2=48 cycles bit $ea // 3 cycles // = 63 cycles } inc $d020 // 6 cycles inc $d021 // 6 cycles nop nop nop nop // 4*2=8 cycles bit $ea // 3 cycles // = 23 cycles (badline) lda #$00 sta $d020 sta $d021 lda start sta $d012 lda #<int1 ldy #>int1 sta $fffe sty $ffff lda #$01 sta $d019 pla tay pla taxation pla rti .macro stabilize() { lda #<nextrasterlineirq sta $fffe lda #>nextrasterlineirq sta $ffff inc $d012 lda #$01 sta $d019 tsx cli nop nop nop nop nop nop nop nop nextrasterlineirq: txs ldx #$08 dex bne *-1 bit $00 lda $d012 cmp $d012 beq *+2 }

as understand you, problem isn't raster bars flickering (i.e. raster interrupt stable), sec line of raster-bar drawing on screen isn't red.

your problem bad lines. (see [1])

after have stabilized raster interrupt, code posted, "actual code" start running @ cycle 4 of rasterline $3a.

the sec line of raster-bar, want background color , border color red, bad line. (it raster-line $3b. since $d011 = $1b, bad-line, since lower 3 bits of $d011 , $d012 same)

on bad line, first inc (inc $d020) manages run, border color becomes red. sec inc (inc $d021) starts running, vic takes on before completes, , inc $d021 not completed until after vic has given bus back. (this 43 cycles later - i.e. setting background-color reddish delayed 43 cycles).

you had it, badline on different raster-line code expected , needed "push few cycles" both incs executed on badlines before beingness interrupted vic. (it bit late start executing 2 incs @ cycle 4 of badline, if want both of them executed before vic takes over)

updated example:

try replacing section of code:

.for (var i=0; i<7; i++) { inc $d020 // 6 cycles inc $d021 // 6 cycles nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop // 24*2=48 cycles bit $ea // 3 cycles // = 63 cycles } inc $d020 // 6 cycles inc $d021 // 6 cycles nop nop nop nop // 4*2=8 cycles bit $ea // 3 cycles // = 23 cycles (badline)

with this:

// delay cycle @ end of raster-line, have time execute both inc's on // each successive raster-line - in particular on badlines before vic takes on bus. .for (var i=0; i<28; i++) nop // illustrative purposes - not cool code :) .for (var i=0; i<8*6; i++) { inc $d020 // 6 cycles inc $d021 // 6 cycles .if ([i & %111] == 0) { // badline nop nop nop nop // 4*2=8 cycles } else { // non-badline nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop // 24*2=48 cycles bit $ea // 3 cycles // = 63 cycles } }

(warning: code quite wasteful memory-wise - same effect made normal loop) (instead of varying delay, alternatively force bad-lines away, modifying $d011, if don't plan display character graphics)

try checking out machine-code monitor in hoxs64 emulator. perfect debugging timing related issues. shows cycle of raster-line on @ given time (+it can break on interrupt taken).

hope helped :)

note, haven't throughly looked through stable-raster routine pitfalls, seems ok - approach right , don't have flickering. if start getting flickering raster-bars, know fix. ;)

in case reading not know badlines are:

cool references:

[1]: read more "bad lines" in vic-article (or "the vic-bible" deserves called): http://csdb.dk/release/?id=44685 (pdf) or http://vice-emu.sourceforge.net/plain/vic-article.txt (txt). see addendum: http://vice-emu.sourceforge.net/plain/vic-addendum.txt

basically, when vic-chip starts drawing first raster-line of text-line, steals 40-43 cycles cpu (see below why not 43). these raster-lines called "bad lines". on bad line there 20-23 cycles available, instead of 63.

(to more precise, badline occurs when 3 lowermost bits of $d011 equals 3 lowermost bits of $d012 (and we're not in border , screen haven't been "switched off" bit 4 of $d011))

the vic-chip uses lastly 40 of these 43 cycles read 40 characters displayed on text-line. cpu can't execute instructions during these 40 cycles.

during first 3 cycles of these 43 cycles, however, cpu can execute "write cycles" of instructions - write cycles, not read cycles. (see [2]) if time opcodes correctly, can execute of cycles of instructions during these 3 cycles. (note: instruction 3 write-cycles "brk", useless, in practice able utilize @ 2 of these 3 cycles useful).

note in add-on stealing cycles on badlines, vic steal cycles cpu on raster-lines sprites.

[2]: see "64doc" larn cycles of c64's different instructions write-cycles: http://vice-emu.sourceforge.net/plain/64doc.txt (write-cycles marked "w" in tables, , read-cycles marked "r")

[x]: ...and there lots of articles @ http://codebase64.org

assembly 6510

No comments:

Post a Comment