Skip to content

Slow VGA Fill? #42

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));
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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