1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
uint_32 LogicalOperation(uint_32 input)
{
switch (ActiveVGA->registers->GraphicsRegisters.REGISTERS.DATAROTATEREGISTER.LogicalOperation)
{
case 0x00: /* None */
return input; //Unmodified
case 0x01: /* AND */
return input & ActiveVGA->registers->ExternalRegisters.DATALATCH.latch;
case 0x02: /* OR */
return input | ActiveVGA->registers->ExternalRegisters.DATALATCH.latch;
case 0x03: /* XOR */
return input ^ ActiveVGA->registers->ExternalRegisters.DATALATCH.latch;
};
return input; //Unknown, just give the input!
}
uint_32 BitmaskOperation(uint_32 input, byte bitmaskregister)
{
uint_32 result = 0; //Default: the result!4
byte bit;
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","BitmaskOperation on %08X, Bitmask: %02X, Startbit: %i, Width: %i",input,bitmaskregister,startbit,width); //Log it!
for (bit=0;bit<32;bit++) //Process all available bits!
{
if (bitmaskregister&(1<<(bit&7))) //Use bit from input?
{
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","Bitmask: take bit from input: %i(%i)",bit,((input&(1<<bit))>>bit)); //Take this bit from the input!
result |= input&(1<<bit); //Use the bit from input!
}
else //Use bit from latch?
{
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","Bitmask: take bit from latch: %i(%i)",bit,((ActiveVGA->registers->ExternalRegisters.DATALATCH.latch&(1<<bit))>>bit)); //Take this bit from the input!
result |= ActiveVGA->registers->ExternalRegisters.DATALATCH.latch&(1<<bit); //Use the bit from the latch!
}
}
return result; //Give the result!
}
void VGA_WriteModeOperation(byte planes, uint_32 offset, byte val)
{
if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA","Write %02X to plane %i...",val,plane);
uint_32 data = val; //Default to the value given!
byte curplane; //For plane loops!
switch (ActiveVGA->registers->GraphicsRegisters.REGISTERS.GRAPHICSMODEREGISTER.WriteMode) //What write mode?
{
case 0: //Read-Modify-Write operation!
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","VRAM write: Plane: %i, Offset: %05X, Value: %02X",plane,offset,val); //Log our write operation!
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","ROR on %02X",data);
data = (byte)ror((byte)val,ActiveVGA->registers->GraphicsRegisters.REGISTERS.DATAROTATEREGISTER.RotateCount); //Rotate it! Keep 8-bit data!
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","ROR'ED value: %02X",data);
data = ActiveVGA->ExpandTable[data]; //Make sure the data is on the all planes!
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","All planes value: %08X",data);
for (curplane=0;curplane<3;curplane++)
{
if (ActiveVGA->registers->GraphicsRegisters.REGISTERS.ENABLESETRESETREGISTER.EnableSetReset&(1<<curplane)) //Enable set/reset? (Mode 3 ignores this flag)
{
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","SetReset (%i) on %08X MASK=%08X",curplane,data,ActiveVGA->FillTable[1<<curplane]);
data = (data&(~ActiveVGA->FillTable[(1<<curplane)])) | ActiveVGA->FillTable[ActiveVGA->registers->GraphicsRegisters.REGISTERS.SETRESETREGISTER.SetReset&(1<<curplane)]; //Turn all those bits off, and the set/reset plane ON=0xFF for the plane and OFF=0x00!
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","AfterSetReset (%i): %08X, Set: %i",curplane,data,ActiveVGA->registers->GraphicsRegisters.REGISTERS.SETRESETREGISTER.SetReset&(1<<curplane));
}
}
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","AfterSetReset: %08X",data);
data = LogicalOperation(data); //Execute the logical operation!
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","AfterLogicalOperation: %08X",data);
data = BitmaskOperation(data,ActiveVGA->registers->GraphicsRegisters.REGISTERS.BITMASKREGISTER); //Execute the bitmask operation!
//if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA_VRAM","AfterBitmaskOperation: %08X",data);
break;
case 1: //Video-to-video transfer
data = ActiveVGA->registers->ExternalRegisters.DATALATCH.latch; //Use the latch!
break;
case 2: //Write color to all pixels in the source address byte of VRAM. Use Bit Mask Register.
data = ActiveVGA->FillTable[data]; //Replicate across all 8 bits of their respective planes.
data = LogicalOperation(data); //Execute the logical operation!
data = BitmaskOperation(data,ActiveVGA->registers->GraphicsRegisters.REGISTERS.BITMASKREGISTER); //Execute the bitmask operation fully!
break;
case 3: //Ignore enable set reset register!
data = ror(val,ActiveVGA->registers->GraphicsRegisters.REGISTERS.DATAROTATEREGISTER.RotateCount); //Rotate it! Keep 8-bit data!
data &= ActiveVGA->registers->GraphicsRegisters.REGISTERS.BITMASKREGISTER; //AND with the Bit Mask field.
data = BitmaskOperation(ActiveVGA->ExpandTable[ActiveVGA->registers->GraphicsRegisters.REGISTERS.SETRESETREGISTER.SetReset],data); //Use the generated data on the Set/Reset register
break;
}
byte planeenable = ActiveVGA->registers->SequencerRegisters.REGISTERS.MAPMASKREGISTER.MemoryPlaneWriteEnable; //Enabled planes from the register!
planeenable &= planes; //The actual planes to write to!
for (curplane=0;curplane<4;curplane++) //Process all planes!
{
if (planeenable&(1<<curplane)) //Modification of the plane?
{
if (LOG_VRAM_WRITES && !is_loadchartable) dolog("VGA","Writes to plane %i enabled!",curplane); //Enabled!
writeVRAMplane(ActiveVGA,0,curplane,offset,((data>>(curplane<<3))&0xFF)); //Write the plane from the data!
}
else if (LOG_VRAM_WRITES && !is_loadchartable) //Log it?
{
dolog("VGA","Writes to plane %i disabled!",curplane); //Disabled!
}
}
}
|