The software is coming along. The screen is now rendering at a consistent FPS based on the timer interrupt. The timer counts 50,000 clock cycles at a time, which at a 1mhz CPU comes out to 20 fps. The LED flashing in the video is flashing once per frame. Instead of running all game code in the IRQ handler, I instead added a wait for irq call. The IRQ handler simply sets a flag when interrupted, and the wait call spins until that flag is set. This way a minimal amount of code runs in the interrupt handler. The main game loop just calls wait each cycle.
I also figure this is best because cc65 triggers BRK whenever the runtime encounters a fault, and BRK causes a software interrupt to fire. If the majority of my code was actually in the interrupt handler, then I would never be able to react to or even detect a BRK properly.
I also now have sprite drawing fully working. Previously my sprite drawing routine was only working if the y offset of the sprite was on a page boundary of 0, 8, 16, etc... The routine is a bit complicated because it is optimized to move as many bits at a time as possibly straight into video memory, rather than the naive approach of calling getpixel / setpixel. Here is the routine, with really ugly variable names:
void drawSprite(unsigned char* sprite, unsigned char x, unsigned char y, unsigned char w, unsigned char h) {
unsigned char p = y/8;
unsigned char yoff = y%8;
unsigned char yoff_inv = 8-yoff;
unsigned char i = 0;
unsigned char il = 0;
unsigned char yp = 0;
unsigned char last = 0;
unsigned char* vmem = VIDEO_MEM; // + _char_x + (p*128);
for (i = 0; i < p; ++i) {
vmem += 128;
}
vmem += x;
i = 0;
for (yp = 0; yp < h; yp += 8) {
il += w;
last = 0;
for (; i < il; ++i) {
if (yoff > 0 && yp > 0) {
last = sprite[i - w] >> yoff_inv;
}
*vmem |= (sprite[i] << yoff) + last;
vmem++;
}
vmem += (128 - w);
}
// Go through last set of sprite data becasue it spills over into next page of VMEM
if (yoff > 0) {
i -= w;
for (; i < il; ++i) {
*vmem |= (sprite[i] >> yoff_inv);
++vmem;
}
}
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.