public void WriteRegister(UInt16 adr, byte abyte)
{
switch (adr)
{
case 0x00:
case 0x02:
case 0x04:
case 0x06:
case 0x08:
case 0x0a:
case 0x0c:
case 0x0e:
mx[adr >> 1] = (UInt16)((mx[adr >> 1] & 0xff00) | abyte);
break;
case 0x10:
{
int i, j;
mx8 = abyte;
for (i = 0, j = 1; i < 8; i++, j <<= 1)
{
if ((mx8 & j) != 0)
mx[i] |= 0x100;
else
mx[i] &= 0xff;
}
break;
}
case 0x01:
case 0x03:
case 0x05:
case 0x07:
case 0x09:
case 0x0b:
case 0x0d:
case 0x0f:
my[adr >> 1] = abyte;
break;
case 0x11:
{ // Control register 1
ctrl1 = abyte;
y_scroll = (UInt16)(abyte & 7);
UInt16 new_irq_raster = (UInt16)((irq_raster & 0xff) | ((abyte & 0x80) << 1));
if (irq_raster != new_irq_raster && raster_y == new_irq_raster)
raster_irq();
irq_raster = new_irq_raster;
if ((abyte & 8) != 0)
{
dy_start = ROW25_YSTART;
dy_stop = ROW25_YSTOP;
}
else
{
dy_start = ROW24_YSTART;
dy_stop = ROW24_YSTOP;
}
// In line $30, the DEN bit controls if Bad Lines can occur
if (raster_y == 0x30 && (abyte & 0x10) != 0)
bad_lines_enabled = true;
// Bad Line condition?
is_bad_line = (raster_y >= FIRST_DMA_LINE && raster_y <= LAST_DMA_LINE && ((raster_y & 7) == y_scroll) && bad_lines_enabled);
display_idx = ((ctrl1 & 0x60) | (ctrl2 & 0x10)) >> 4;
break;
}
case 0x12:
{ // Raster counter
UInt16 new_irq_raster = (UInt16)((irq_raster & 0xff00) | abyte);
if (irq_raster != new_irq_raster && raster_y == new_irq_raster)
raster_irq();
irq_raster = new_irq_raster;
break;
}
case 0x15: // Sprite enable
me = abyte;
break;
case 0x16: // Control register 2
ctrl2 = abyte;
x_scroll = (UInt16)(abyte & 7);
display_idx = ((ctrl1 & 0x60) | (ctrl2 & 0x10)) >> 4;
break;
case 0x17: // Sprite Y expansion
mye = abyte;
spr_exp_y |= (byte)~abyte;
break;
case 0x18: // Memory pointers
vbase = abyte;
matrix_base = (UInt16)((abyte & 0xf0) << 6);
char_base = (UInt16)((abyte & 0x0e) << 10);
bitmap_base = (UInt16)((abyte & 0x08) << 10);
break;
case 0x19: // IRQ flags
irq_flag = (byte)(irq_flag & (~abyte & 0x0f));
if ((irq_flag & irq_mask) != 0) // Set master bit if allowed interrupt still pending
irq_flag |= 0x80;
else
_cpu.ClearVICIRQ(); // Else clear interrupt
break;
case 0x1a: // IRQ mask
irq_mask = (byte)(abyte & 0x0f);
if ((irq_flag & irq_mask) != 0)
{ // Trigger interrupt if pending and now allowed
irq_flag |= 0x80;
_cpu.TriggerVICIRQ();
}
else
{
irq_flag &= 0x7f;
_cpu.ClearVICIRQ();
}
break;
case 0x1b: // Sprite data priority
mdp = abyte;
break;
case 0x1c: // Sprite multicolor
mmc = abyte;
break;
case 0x1d: // Sprite X expansion
mxe = abyte;
break;
case 0x20: ec_color = colors[ec = abyte]; break;
case 0x21: b0c_color = colors[b0c = abyte]; break;
case 0x22: b1c_color = colors[b1c = abyte]; break;
case 0x23: b2c_color = colors[b2c = abyte]; break;
case 0x24: b3c_color = colors[b3c = abyte]; break;
case 0x25: mm0_color = colors[mm0 = abyte]; break;
case 0x26: mm1_color = colors[mm1 = abyte]; break;
case 0x27:
case 0x28:
case 0x29:
case 0x2a:
case 0x2b:
case 0x2c:
case 0x2d:
case 0x2e:
spr_color[adr - 0x27] = colors[sc[adr - 0x27] = abyte];
break;
}
}