Skip to content

Slow VGA Fill? #42

@Stanlyhalo

Description

@Stanlyhalo

Not sure if this is an issue exactly. But I just got done with vid n.12. And in the video, his goes from the terminal then quickly to a screen with that glitchy background but fills to blue almost immediately. Mine takes about 2 seconds or so.

I've checked through my code base with the commit and some of the notes. I don't see if I did anything wrong? Is it something wrong with vm box? I gave it plenty of vram, memory, and I even tried to see if giving it more cores help (which I'd assume not because I would assume I need to make manual work of that in a custom os build).

VGA.hpp

class VGA {
protected:
    Port8Bit miscPort;
    Port8Bit crtcIndexPort;
    Port8Bit crtcDataPort;
    Port8Bit sequencerIndexPort;
    Port8Bit sequencerDataPort;
    Port8Bit graphicsControllerIndexPort;
    Port8Bit graphicsControllerDataPort;
    Port8Bit attributeControllerIndexPort;
    Port8Bit attributeControllerReadPort;
    Port8Bit attributeControllerWritePort;
    Port8Bit attributeControllerResetPort;

    void WriteRegisters(uint8* registers);
    uint8* GetFrameBufferSegment();
public:
    VGA();
    ~VGA();

    virtual bool SupportsMode(uint32 width, uint32 height, uint32 colorDepth);
    virtual bool SetMode(uint32 width, uint32 height, uint32 colorDepth);
    virtual uint8 GetColorIndex(uint8 r, uint8 g, uint8 b);
    virtual void SetPixel(uint32 x, uint32 y, uint8 colorIndex);
    virtual void SetPixel(uint32 x, uint32 y, uint8 r, uint8 g, uint8 b);
};

VGA.cpp

void VGA::WriteRegisters(uint8* registers) {
    miscPort.Write(*(registers++));

    for (uint8 i = 0; i < 5; i++) {
        sequencerIndexPort.Write(i);
        sequencerDataPort.Write(*(registers++));
    }
    
/*
    crtcIndexPort.Write(0x03);
    crtcDataPort.Write(crtcDataPort.Read() | 0x80);
    crtcIndexPort.Write(0x11);
    crtcDataPort.Write(crtcDataPort.Read() & ~0x80);

    registers[0x03] = registers[0x03] | 0x80;
    registers[0x11] = registers[0x11] & ~0x80;
    */
    crtcIndexPort.Write(0x09);
    crtcDataPort.Write(crtcDataPort.Read() | 0x80);
    crtcIndexPort.Write(0x16);
    crtcDataPort.Write(crtcDataPort.Read() & ~0x80);

    registers[0x09] = registers[0x09] | 0x80;
    registers[0x16] = registers[0x16] & ~0x80;

    for (uint8 i = 0; i < 25; i++) {
        crtcIndexPort.Write(i);
        crtcDataPort.Write(*(registers++));
    }
    
    for (uint8 i = 0; i < 9; i++) {
        graphicsControllerIndexPort.Write(i);
        graphicsControllerDataPort.Write(*(registers++));
    }

    for (uint8 i = 0; i < 21; i++) {
        attributeControllerResetPort.Read();
        attributeControllerIndexPort.Write(i);
        attributeControllerWritePort.Write(*(registers++));
    }

    attributeControllerResetPort.Read();
    attributeControllerIndexPort.Write(0x20);
}
uint8* VGA::GetFrameBufferSegment() {
    graphicsControllerIndexPort.Write(0x06);
    uint8 segmentNumber = graphicsControllerDataPort.Read() & (3 << 2);

    switch (segmentNumber) {
    default:
    case(0 << 2): return (uint8*)0x00000;
    case(1 << 2): return (uint8*)0xA0000;
    case(2 << 2): return (uint8*)0xB0000;
    case(3 << 2): return (uint8*)0xB8000;
    }
}


VGA::VGA() :
miscPort(0x3C2),
crtcIndexPort(0x3D4),
crtcDataPort(0x3D5),
sequencerIndexPort(0x3C4),
sequencerDataPort(0x3C5),
graphicsControllerIndexPort(0x3CE),
graphicsControllerDataPort(0x3CF),
attributeControllerIndexPort(0x3C0),
attributeControllerReadPort(0x3C1),
attributeControllerWritePort(0x3C0),
attributeControllerResetPort(0x3DA) {
    //
}
VGA::~VGA() {
    //
}

bool VGA::SupportsMode(uint32 width, uint32 height, uint32 colorDepth) {
    return width == 320 && height == 200 && colorDepth == 8;
}
bool VGA::SetMode(uint32 width, uint32 height, uint32 colorDepth) {
    if (!SupportsMode(width, height, colorDepth)) return false;

    unsigned char g_320x200x256[] = {
    /* MISC */
        0x63,
    /* SEQ */
        0x03, 0x01, 0x0F, 0x00, 0x0E,
    /* CRTC */
        0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
        0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x9C, 0x0E, 0x8F, 0x28,	0x40, 0x96, 0xB9, 0xA3,
        0xFF,
    /* GC */
        0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
        0xFF,
    /* AC */
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
        0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
        0x41, 0x00, 0x0F, 0x00,	0x00
    };

    WriteRegisters(g_320x200x256);
    return true;
}
uint8 VGA::GetColorIndex(uint8 r, uint8 g, uint8 b) {
    if (r == 0x00 && g == 0x00 && 0xA8)
        return 0x01;
    return 0x00;
}
void VGA::SetPixel(uint32 x, uint32 y, uint8 colorIndex) {
    uint8* pixelAddr = GetFrameBufferSegment() + 320*y + x;
    *pixelAddr = colorIndex;
}
void VGA::SetPixel(uint32 x, uint32 y, uint8 r, uint8 g, uint8 b) {
    SetPixel(x,y,GetColorIndex(r, g, b));
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions