public static int[] LoadLUT(BasicMemory VKY) { // Read the color lookup tables int lutAddress = MemoryMap.GRP_LUT_BASE_ADDR - MemoryMap.VICKY_BASE_ADDR; int lookupTables = 4; int[] result = new int[lookupTables * 256]; for (int c = 0; c < lookupTables * 256; c++) { byte blue = VKY.ReadByte(lutAddress++); byte green = VKY.ReadByte(lutAddress++); byte red = VKY.ReadByte(lutAddress++); lutAddress++; result[c] = (0xFF << 24) + (red << 16) + (green << 8) + blue; } return(result); }
/// <summary> /// Returns a single row (byte) in the character data. /// </summary> /// <param name="CharacterCode">Character code</param> /// <param name="Row">Row in glpyh</param> /// <returns></returns> public byte Read(int CharacterCode, int Row) { if (CharacterData == null) { return(0); } int addr = StartAddress + CharacterCode * charHeight + Row; return(CharacterData.ReadByte(addr)); }
void Gpu_Paint(object sender, PaintEventArgs e) { paintCycle++; if (VICKY == null) { e.Graphics.DrawString("IO Memory Not Initialized", this.Font, TextBrush, 0, 0); return; } //if (VRAM == null) //{ // e.Graphics.DrawString("VRAM Not Initialized", this.Font, TextBrush, 0, 0); // return; //} //if (RAM == null || DesignMode) if (DesignMode) { e.Graphics.DrawString("RAM Not Initialized", this.Font, TextBrush, 0, 0); return; } // Read the Master Control Register byte MCRegister = VICKY.ReadByte(0); // Reading address $AF:0000 if (MCRegister == 0 || (MCRegister & 0x80) == 0x80) { e.Graphics.DrawString("Graphics Mode disabled", this.Font, TextBrush, 0, 0); return; } if (drawing) { return; } drawing = true; e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; if (MCRegister != 0 && MCRegister != 0x80) { StartOfFrame?.Invoke(); } Graphics g = Graphics.FromImage(frameBuffer); // Determine if we display a border int border_register = VICKY.ReadByte(4); bool displayBorder = (border_register & 1) == 1; int colOffset = VICKY.ReadByte(8); int rowOffset = VICKY.ReadByte(9); // Load Graphical LUTs graphicsLUT = LoadLUT(VICKY); // Apply gamma correct if ((MCRegister & 0x40) == 0x40) { gammaCorrection = LoadGammaCorrection(VICKY); } else { gammaCorrection = null; } // Default background color to border color // In Text mode, the border color is stored at $AF:0005. byte borderRed = VICKY.ReadByte(5); byte borderGreen = VICKY.ReadByte(6); byte borderBlue = VICKY.ReadByte(7); if (gammaCorrection != null) { borderRed = gammaCorrection[0x200 + borderRed]; borderGreen = gammaCorrection[0x100 + borderGreen]; borderBlue = gammaCorrection[borderBlue]; } int borderColor = (int)(0xFF000000 + (borderBlue << 16) + (borderGreen << 8) + borderRed); if (tileEditorMode) { g.Clear(Color.LightGray); DrawTextWithBackground("Tile Editing Mode", g, Color.Black, 240, 10); DrawTextWithBackground("Tile Editing Mode", g, Color.Black, 240, 455); } else { g.Clear(Color.FromArgb(borderColor)); } // Graphics Mode if ((MCRegister & 0x4) == 0x4) { byte backRed = VICKY.ReadByte(0xD); byte backGreen = VICKY.ReadByte(0XE); byte backBlue = VICKY.ReadByte(0xF); if (gammaCorrection != null) { backRed = gammaCorrection[0x200 + backRed]; backGreen = gammaCorrection[0x100 + backGreen]; backBlue = gammaCorrection[backBlue]; } int backgroundColor = (int)(0xFF000000 + (backBlue << 16) + (backGreen << 8) + backRed); Brush graphBackgroundBrush = new SolidBrush(Color.FromArgb(backgroundColor)); g.FillRectangle(graphBackgroundBrush, colOffset, rowOffset, 640 - 2 * colOffset, 480 - 2 * rowOffset); } // Bitmap Mode if ((MCRegister & 0x8) == 0x8) { DrawBitmap(frameBuffer, displayBorder); } for (int layer = 4; layer > 0; --layer) { if ((MCRegister & 0x10) == 0x10) { DrawTiles(frameBuffer, layer - 1, displayBorder); } if ((MCRegister & 0x20) == 0x20) { DrawSprites(frameBuffer, layer - 1, displayBorder); } } if ((MCRegister & 0x1) == 0x1) { int top = 0; if (ColumnsVisible < 1 || ColumnsVisible > MAX_TEXT_COLS) { Graphics graphics = Graphics.FromImage(frameBuffer); DrawTextWithBackground("ColumnsVisible invalid:" + ColumnsVisible.ToString(), graphics, Color.Black, 0, top); top += 12; } if (LinesVisible < 1 || LinesVisible > MAX_TEXT_LINES) { Graphics graphics = Graphics.FromImage(frameBuffer); DrawTextWithBackground("LinesVisible invalid:" + LinesVisible.ToString(), graphics, Color.Black, 0, top); top += 12; } if (top == 0) { DrawBitmapText(frameBuffer, colOffset, rowOffset); } } byte mouseReg = VICKY.ReadByte(0x700); MousePointerMode = (mouseReg & 1) == 1; if (MousePointerMode && !TileEditorMode) { DrawMouse(frameBuffer); } e.Graphics.DrawImage(frameBuffer, ClientRectangle); drawing = false; }