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 98 99 100 101 102 103 104 105 106 107 108 109 110
|
extern uint_32 rowscanaddress; //Row scan address!
extern uint_32 rowscancounter; //Row scan counter!
byte LOG_VRAM_WRITES = 0;
extern byte is_loadchartable; //Loading character table, so no logging?
//Allow wrap is used to determine the hardware rendering!
inline uint_32 determinewrap(VGA_Type *VGA, uint_32 addr,byte is_renderer)
{
return addr; //Disable changes: just take the default!
uint_32 result = addr; //Default: take address itself!
if (is_renderer) //Hardware side?
{
result -= rowscanaddress; //Substract the row scan address to get the base!
rowscanaddress = addresswrap(VGA,rowscanaddress); //Wrap if needed!
result += rowscanaddress; //Apply new row scan address!
result = patch_map1314(VGA,rowscanaddress,rowscanaddress,rowscancounter); //Allow patching of MAP13&14!
}
return result; //New offset!
}
inline byte getVRAM(VGA_Type *VGA,uint_32 fulloffset, byte is_renderer)
{
if (!VGA->VRAM_size) return 0; //No size!
if ((is_renderer&2)|(is_renderer&4)) //Allow double buffering?
{
if (!(VGA->VRAM_size&0x3)) //Bufferable VRAM (we need to be an exact multiple of 4 bytes)?
{
uint_32 multivals[4] = {0xFF000000,0x00FF0000,0x0000FF00,0x000000FF}; //Multiple values position!
byte multipos[4] = {24,16,8,0}; //The positions to look for!
if (is_renderer&2) //First buffer?
{
static uint_32 lastblock; //Last block of 4 values!
static uint_32 lastvals; //Last values!
if ((fulloffset&0xFFFFFFFB)!=lastblock) //Different block as last?
{
lastblock = (fulloffset&0xFFFFFFFB); //New block!
uint_32 *newval = (uint_32 *)&VGA->VRAM[SAFEMODUINT32(lastblock,VGA->VRAM_size)]; //The new value to read!
lastvals = *newval; //Read vals, making sure we loop arround at 4 bytes border!
}
return (((lastvals&multivals[fulloffset&3])>>multipos[fulloffset&3])&0xFF); //Take the buffered last block!
}
else if (is_renderer&4) //Second buffer?
{
static uint_32 lastblock2; //Last block of 4 values!
static uint_32 lastvals2; //Last values!
if ((fulloffset&0xFFFFFFFB)!=lastblock2) //Different block as last?
{
lastblock2 = (fulloffset&0xFFFFFFFB); //New block!
uint_32 *newval = (uint_32 *)&VGA->VRAM[SAFEMODUINT32(lastblock2,VGA->VRAM_size)]; //Read vals, making sure we loop arround at 4 bytes border!
lastvals2 = *newval; //Get!
}
return (((lastvals2&multivals[fulloffset&3])>>multipos[fulloffset&3])&0xFF); //Take the buffered last block!
}
}
}
return VGA->VRAM[SAFEMODUINT32(fulloffset,VGA->VRAM_size)]; //Give the data!
}
inline void putVRAM(VGA_Type *VGA,uint_32 fulloffset,byte value)
{
if (!VGA->VRAM_size) return; //No size!
VGA->VRAM[SAFEMODUINT32(fulloffset,VGA->VRAM_size)] = value; //Set the data!
}
//Direct access to VRAM, using start and offset!
inline byte readVRAMdirect(VGA_Type *VGA, uint_32 start, uint_32 offset, byte is_renderer) //Used in 256 color mode!
{
return getVRAM(VGA,determinewrap(VGA,start+offset,is_renderer),is_renderer); //The full protected offset!
}
inline void writeVRAMdirect(VGA_Type *VGA, uint_32 start, uint_32 offset, byte value, byte is_renderer) //See readVRAMdirect above!
{
putVRAM(VGA,determinewrap(VGA,start+offset,is_renderer),value); //The full protected offset!
}
//Planar access to VRAM, using
inline byte readVRAMplane(VGA_Type *VGA, uint_32 start, byte plane, uint_32 offset, byte is_renderer) //Read from a VRAM plane!
{
return getVRAM(VGA,determinewrap(VGA,((start+offset)<<2)|plane,is_renderer),is_renderer);
}
inline void writeVRAMplane(VGA_Type *VGA, uint_32 start, byte plane, uint_32 offset, byte value, byte is_renderer) //Write to a VRAM plane!
{
putVRAM(VGA,determinewrap(VGA,((start+offset)<<2)|plane,is_renderer),value);
}
//Bit from left to right starts with 0(value 128) ends with 7(value 1)
byte getBitPlaneBit(VGA_Type *VGA, uint_32 start, int plane, uint_32 offset, byte bit, byte is_renderer)
{
byte bits = readVRAMplane(VGA,start,plane,offset,is_renderer); //Get original bits!
return GETBIT(bits,7-bit); //Give the bit!
}
void setBitPlaneBit(VGA_Type *VGA, uint_32 start, int plane, uint_32 offset, byte bit, byte on, byte is_renderer)
{
byte bits = readVRAMplane(VGA,start,plane,offset,is_renderer); //Get original bits!
if (on) //To turn bit on?
{
bits = SETBIT1(bits,7-bit); //Turn bit on!
}
else //To turn bit off?
{
bits = SETBIT0(bits,7-bit); //Turn bit off!
}
writeVRAMplane(VGA,start,plane,offset,bits,is_renderer); //Write the modified value back!
}
|