| |
Partz Account closed
Registered: Jun 2008 Posts: 17 |
Raster corruption
Just after a sanity check here really.... not begging for any deep analysis.
I've set up a simple raster interrupt of the form:
INT SEI ; Disable interrupts
LDA #$7F ; Disable timer interrupts
STA $DC0D
LDA #$01 ; Enable raster interrupts
STA $D01A
LDA #<IRQ ; Set up vector
STA $0314
LDA #>IRQ
STA $0315
LDA #$1B
STA $D011
LDA #$1 ; set up interrupt position
STA $D012
CLI
HALT JMP HALT
... So nothing to elaborate there. In my interrupt routine i have a font shown for about half the screen and then i'm changing font via $d018 further down the screen by busy waiting for $d012 to reach $85 an am also changing the screen colour at this point. What im finding is that 8 times out of ten my initial interrupt seems to trigger half way down the screen not at the top.... so for example, instead of he top half of the screen being white, only 1 raster line (approx) is white at or around position $85.
I haven't yet been able to find anything in my routines that would cause any corruption so was wondering if anyone else had experienced this and if maybe there was something wrong with my (admittedly niaive) set up above? As for code thats called in the interrupt its basically:
LDA #$1
STA $d019
LDA #$02
STA $d021
wait:
LDA $d012
CMP #$85
BNE wait
LDA #$0
STA $d021
JMP $EA31
... im doing a little more than the above - changing fonts, calling some music... but structurally is there any issue with the above in terms of waiting for the raster rather than setting up a second interrupt?
|
|
| |
JackAsser
Registered: Jun 2002 Posts: 2014 |
Structurally there is nothing wrong with the above. What bugs me is that you say you do a little more together with the fact that you acknowledge the interrupt immediatly. Consider for example that the little more brings you to a raster position > 1 after a wrap around and that you've acknowledged the IRQ. This will make the IRQ to retrigger again immediatly just after the RTI. F.e. somewhere around line $85 depending on how much extra the "little more" took.
Also I'm quite tired right now and can be plain wrong + that I really don't know shit about kernel stuff like 0314/0315/ea81/ea31, what registers are saved and what not... |
| |
Partz Account closed
Registered: Jun 2008 Posts: 17 |
Like i say, 8 out of ten times it works - but it is possible that something isn't being initialised correctly elsewhere and causing some routine to overrun due to some indeterminate state. I'll strip things down and see where this might be happening.
Thanks for the response. |
| |
TWW
Registered: Jul 2009 Posts: 545 |
Quote: Just after a sanity check here really.... not begging for any deep analysis.
I've set up a simple raster interrupt of the form:
INT SEI ; Disable interrupts
LDA #$7F ; Disable timer interrupts
STA $DC0D
LDA #$01 ; Enable raster interrupts
STA $D01A
LDA #<IRQ ; Set up vector
STA $0314
LDA #>IRQ
STA $0315
LDA #$1B
STA $D011
LDA #$1 ; set up interrupt position
STA $D012
CLI
HALT JMP HALT
... So nothing to elaborate there. In my interrupt routine i have a font shown for about half the screen and then i'm changing font via $d018 further down the screen by busy waiting for $d012 to reach $85 an am also changing the screen colour at this point. What im finding is that 8 times out of ten my initial interrupt seems to trigger half way down the screen not at the top.... so for example, instead of he top half of the screen being white, only 1 raster line (approx) is white at or around position $85.
I haven't yet been able to find anything in my routines that would cause any corruption so was wondering if anyone else had experienced this and if maybe there was something wrong with my (admittedly niaive) set up above? As for code thats called in the interrupt its basically:
LDA #$1
STA $d019
LDA #$02
STA $d021
wait:
LDA $d012
CMP #$85
BNE wait
LDA #$0
STA $d021
JMP $EA31
... im doing a little more than the above - changing fonts, calling some music... but structurally is there any issue with the above in terms of waiting for the raster rather than setting up a second interrupt?
Your initial set up looks correct.
However you can try this;
irq1:
lda #$01
sta $d019 //Ack the interrupt
lda #$85
sta $d012 //Set the next raster-interrupt
lda #$1b
sta $d011 //Don't forget this one
lda #$xx
sta $dd00
lda #$xx
sta $d018
lda #$xx
sta $d016
//Do you shit here
lda #<irq2
sta $0314
lda #>irq2
sta $0315
jmp $ea31
irq2:
lda #$01
sta $d019 //Ack the interrupt
lda #$01
sta $d012 //Set the next raster-interrupt
lda #$1b
sta $d011 //Don't forget this one
lda #$xx
sta $dd00
lda #$xx
sta $d018
lda #$xx
sta $d016
//Do you other shit here
lda #<irq1
sta $0314
lda #>irq1
sta $0315
jmp $ea31
Don't make the processor bussy to wait for something to happen. this is not what interrupts are about.
And if you still want to wait you'd be better off with:
lda #$85
cmp $d012
bne *-3
cheers! |
| |
SIDWAVE Account closed
Registered: Apr 2002 Posts: 2238 |
and nobody noticed that your code is bugged..
LDA #$1
STA $d019
LDA #$02 ;RED SCREEN
STA $d021
wait:
LDA $d012
CMP #$85
BNE wait
LDA #$0 ;BLACK SCREEN
STA $d021
JMP $EA31
Now look, at line $85 it sets d021 to 0, and immediately on next frame, it sets it to red.
simply there is a d012 wait missing before d021,2 |
| |
Kaizen
Registered: May 2009 Posts: 24 |
It seems that ACK CIA lacks...
SEI
LDA #$7F
STA $DC0D
LDA $DC0D <=== CIA1 interrupt acknowledge
etc.
;-) |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
It's better to just use
lda #$7f
sta $dc0d
lda #<irq
sta $0314
lda #>irq
sta $0315
lda #$1b
sta $d011
lda #1
sta $d012
sta $d01a
without SEI - that way you don't end up unacknowledged IRQs. Just enable raster IRQs as the last thing you do.
|
| |
Stryyker
Registered: Dec 2001 Posts: 468 |
Without SEI there is a small chance an interrupt can happen while you're setting up your new one - say writing one of the IRQ vectors without the other one being written to.
I prefer to acknowledge the interrupts after I have set it up so I know when the next interrupt will happen. |
| |
MagerValp
Registered: Dec 2001 Posts: 1078 |
No IRQs happen after lda #<irq. If one occurs just as you disable it, it'll get acknowledged by the kernal IRQ handler before sta $0314, so it's perfectly safe. |
| |
Partz Account closed
Registered: Jun 2008 Posts: 17 |
Quote: and nobody noticed that your code is bugged..
LDA #$1
STA $d019
LDA #$02 ;RED SCREEN
STA $d021
wait:
LDA $d012
CMP #$85
BNE wait
LDA #$0 ;BLACK SCREEN
STA $d021
JMP $EA31
Now look, at line $85 it sets d021 to 0, and immediately on next frame, it sets it to red.
simply there is a d012 wait missing before d021,2
Am I missing a trick there? I thought it would set to red when the interrupt fired which had been set up to tricker in the vertical blank?
Actually Jan, I had a peek at some interrupt code in your TST Amiganoid demo to put me straight (!?!) does that one take you back??.... I was lusting after the 2x2 font ;-)
I'm now using multiple interrupts and all is working perfectly. Its something I had wanted to get more comfortable with in anycase. Its been nearly 25 years since I dropped c64 coding for the Amiga but to be honest - i never did get beyond the glitchy raster bar stage back then.
I hadn't intended leaving the busy wait in place... it was really just a place holder for an area I've set aside for some colour bars but now everything is a lot more robust now. Thanks for all the insights :-) |
| |
Martin Piper
Registered: Nov 2007 Posts: 722 |
Quote: No IRQs happen after lda #<irq. If one occurs just as you disable it, it'll get acknowledged by the kernal IRQ handler before sta $0314, so it's perfectly safe.
You cannot be 100% sure of that because the following code sequence is not atomic:
LDA #$7F ; Disable timer interrupts
STA $DC0D
LDA #$01 ; Enable raster interrupts
STA $D01A
Since it isn't atomic you cannot be 100% sure one IRQ will enable the other kind of IRQ after the first STA turns it off. |
... 19 posts hidden. Click here to view all posts.... |
Previous - 1 | 2 | 3 - Next |