qemu not writing to even memory addresses in video memory

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
dethboy
Posts: 14
Joined: Tue May 09, 2017 8:27 am

qemu not writing to even memory addresses in video memory

Post by dethboy »

I have written code that successfully switches to 320x200 linear 256-color mode and writes to the screen. In bochs it functions perfectly but in qemu it is skipping every other pixel. I stepped through with gdb and movb 0x01, address is being executed for each address but every second address doesn't get overwritten. anybody have a clue as to why this might be happening?
User avatar
Geri
Member
Member
Posts: 442
Joined: Sun Jul 14, 2013 6:01 pm

Re: qemu not writing to even memory addresses in video memor

Post by Geri »

vga or vesa?
Operating system for SUBLEQ cpu architecture:
http://users.atw.hu/gerigeri/DawnOS/download.html
dethboy
Posts: 14
Joined: Tue May 09, 2017 8:27 am

Re: qemu not writing to even memory addresses in video memor

Post by dethboy »

VGA
User avatar
Geri
Member
Member
Posts: 442
Joined: Sun Jul 14, 2013 6:01 pm

Re: qemu not writing to even memory addresses in video memor

Post by Geri »

seems like a nice qemu internal error. can you strip the code down to a few lines, and execute it?
Operating system for SUBLEQ cpu architecture:
http://users.atw.hu/gerigeri/DawnOS/download.html
dethboy
Posts: 14
Joined: Tue May 09, 2017 8:27 am

Re: qemu not writing to even memory addresses in video memor

Post by dethboy »

What do you mean? I need the whole mode swtiching code.
User avatar
Geri
Member
Member
Posts: 442
Joined: Sun Jul 14, 2013 6:01 pm

Re: qemu not writing to even memory addresses in video memor

Post by Geri »

you dont need protected mode. just do it in the boot loader. do not do anything else. lets see what happens.
Operating system for SUBLEQ cpu architecture:
http://users.atw.hu/gerigeri/DawnOS/download.html
dethboy
Posts: 14
Joined: Tue May 09, 2017 8:27 am

Re: qemu not writing to even memory addresses in video memor

Post by dethboy »

will have to write my own boot loader then :D
User avatar
Geri
Member
Member
Posts: 442
Joined: Sun Jul 14, 2013 6:01 pm

Re: qemu not writing to even memory addresses in video memor

Post by Geri »

[BITS 16]
[ORG 0x7C00];

switch vga mode
fill algorithm goes here

TIMES 510-($-$$) DB 0
DW 0xAA55


nasm it, copy to disk drive 0th sector, boot it
Operating system for SUBLEQ cpu architecture:
http://users.atw.hu/gerigeri/DawnOS/download.html
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: qemu not writing to even memory addresses in video memor

Post by alexfru »

Uninitialized or clobbered register or variable?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: qemu not writing to even memory addresses in video memor

Post by Brendan »

Hi,
dethboy wrote:I have written code that successfully switches to 320x200 linear 256-color mode and writes to the screen. In bochs it functions perfectly but in qemu it is skipping every other pixel. I stepped through with gdb and movb 0x01, address is being executed for each address but every second address doesn't get overwritten. anybody have a clue as to why this might be happening?
Without any code to give any kind of clue what might or might not be wrong; I'd assume that the bug is that your code to do video mode switching expects the video card to be 100% VGA compatible at the hardware (IO port) level (and not just at the "BIOS int 0x10" level).


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
dethboy
Posts: 14
Joined: Tue May 09, 2017 8:27 am

Re: qemu not writing to even memory addresses in video memor

Post by dethboy »

here is the mode switching and writing to video memory

Code: Select all

void port_3c0_write(uint8_t index, uint8_t data) {
    inb(0x3da); // read to clear index/data status
    outb(0x3c0, index); //send index
    outb(0x3c0, data); //send index
}

uint8_t port_3c0_read(uint8_t index) {
    uint8_t retval;
    inb(0x3da); // read to clear index/data status
    outb(0x3c0, index); //send index
    retval = inb(0x3C1);
    inb(0x3da); // read to clear index/data status
    return retval;
}

void port_3c4_write(uint8_t index, uint8_t data) {
    outb(0x3c4, index);
    outb(0x3c5, data);
}

void port_3ce_write(uint8_t index, uint8_t data) {
    outb(0x3ce, index);
    outb(0x3cf, data);
}

void port_3d4_write(uint8_t index, uint8_t data) {
    outb(0x3d4, index);
    outb(0x3d5, data);
}

uint8_t port_3d4_read(uint8_t index) {
    outb(0x3d4, index);
    return inb(0x3d5);
}

void do_switch(void) {
// now let's try to switch to mode 13h 320x200x256 linear
    // dont know if the order makes a difference
    /*MISC*/
    outb(0x3c2, 0x63); //Miscellaneous Output Register
    
    /*sequencer*/
    port_3c4_write(0x00, 0x03); // ?
    port_3c4_write(0x01, 0x01); // clock mode register
    port_3c4_write(0x02, 0x05);
    port_3c4_write(0x03, 0x00); // character select
    port_3c4_write(0x04, 0x0e); // memory mode register
    
    // unlock the crtc regs
    uint8_t temp = port_3d4_read(0x03);
    port_3d4_write(0x03, temp | 80); // ors against f000 0000
    temp = port_3d4_read(0x11);
    port_3d4_write(0x11, temp & ~80); // ands against 0fff ffff
    
    /*CRTC*/
    port_3d4_write(0x00, 0x5f); // horizontal total
    port_3d4_write(0x01, 0x4f); // horizontal display enable end
    port_3d4_write(0x02, 0x50); // Horizontal Blank Start 
    port_3d4_write(0x03, 0x82); // horizontal blank end
    port_3d4_write(0x04, 0x54); // horizontal retrace start
    port_3d4_write(0x05, 0x80); // horizontal retrace end
    port_3d4_write(0x06, 0xbf); // horizontal vertical total
    port_3d4_write(0x07, 0x1f); // horizontal overflow register
    port_3d4_write(0x08, 0x00); // horizontal preset row scan
    port_3d4_write(0x09, 0x41); // maximum scan line
    port_3d4_write(0x0A, 0x00); // ?
    port_3d4_write(0x0B, 0x00); // ?
    port_3d4_write(0x0C, 0x00); // ?
    port_3d4_write(0x0D, 0x00); // ?
    port_3d4_write(0x0E, 0x00); // ?
    port_3d4_write(0x0F, 0x00); // ?
    port_3d4_write(0x10, 0x9c); // vertical retrace start
    port_3d4_write(0x11, 0x8e); // vertical retrace end vga_hardware page has 8e doesnt seem to make a difference
    port_3d4_write(0x12, 0x8f); // vertical display enable end
    port_3d4_write(0x13, 0x28); // logical width
    port_3d4_write(0x14, 0x40); // unsderline location
    port_3d4_write(0x15, 0x96); // vertical blank start
    port_3d4_write(0x16, 0xb9); // vertical blank end
    port_3d4_write(0x17, 0xa3); // mode control
    port_3d4_write(0x18, 0xff); // ?
    
    /*Graphics Controller*/
    port_3ce_write(0x00, 0x00); // ?
    port_3ce_write(0x01, 0x00); // ?
    port_3ce_write(0x02, 0x00); // ?
    port_3ce_write(0x03, 0x00); // ?
    port_3ce_write(0x04, 0x00); // ?
    port_3ce_write(0x05, 0x40); // mode register
    port_3ce_write(0x06, 0x05); // misc register
    port_3ce_write(0x07, 0x0f); // ?
    port_3ce_write(0x08, 0xff); // ?
    
    /*attribute controller*/
    port_3c0_write(0x00, 0x00); // ?
    port_3c0_write(0x01, 0x01); // ?
    port_3c0_write(0x02, 0x02); // ?
    port_3c0_write(0x03, 0x03); // ?
    port_3c0_write(0x04, 0x04); // ?
    port_3c0_write(0x05, 0x05); // ?
    port_3c0_write(0x06, 0x06); // ?
    port_3c0_write(0x07, 0x07); // ?
    port_3c0_write(0x08, 0x08); // ?
    port_3c0_write(0x09, 0x09); // ?
    port_3c0_write(0x0A, 0x0a); // ?
    port_3c0_write(0x0B, 0x0b); // ?
    port_3c0_write(0x0C, 0x0c); // ?
    port_3c0_write(0x0D, 0x0d); // ?
    port_3c0_write(0x0E, 0x0e); // ?
    port_3c0_write(0x0F, 0x0f); // ?
    port_3c0_write(0x10, 0x41); //mode control
    port_3c0_write(0x11, 0x00); //Overscan register
    port_3c0_write(0x12, 0x0f); //Color Plane Enable
    port_3c0_write(0x13, 0x00); //Horizontal panning
    port_3c0_write(0x14, 0x00); //color select
    
    // lock color palette
    inb(0x3da); // read to clear index/data status
    outb(0x3c0, 0x20); //send index, switches here everything turns to ffff
    
    video_ram = (uint8_t*) 0xa0000;
    
    while (video_ram < (uint8_t*) 0xAFA00) {
        *video_ram = (uint8_t) 0b00000001;
        video_ram++;
    }
}

User avatar
Geri
Member
Member
Posts: 442
Joined: Sun Jul 14, 2013 6:01 pm

Re: qemu not writing to even memory addresses in video memor

Post by Geri »

forget all about those graphics controller port writes. just delete them out from the code totally. they will not work. do the bios interrupt to switch the mode.
Operating system for SUBLEQ cpu architecture:
http://users.atw.hu/gerigeri/DawnOS/download.html
mallard
Member
Member
Posts: 280
Joined: Tue May 13, 2014 3:02 am
Location: Private, UK

Re: qemu not writing to even memory addresses in video memor

Post by mallard »

Brendan wrote: Without any code to give any kind of clue what might or might not be wrong; I'd assume that the bug is that your code to do video mode switching expects the video card to be 100% VGA compatible at the hardware (IO port) level (and not just at the "BIOS int 0x10" level).
Thankfully, that "expectation" is met by all current hardware and by QEMU's emulation.

The actual bug is that the "Map Mask" register (Sequencer register 0x02) is set incorrectly, only enabling planes 1 and 3 (value 0x05), it should be set to 0x0F to enable all planes. Clearly Bochs ignores this value in "Chain 4" mode, but QEMU doesn't (QEMU is likely more accurate to real hardware).

Switching modes by writing the registers absolutely does work when done correctly on every emulator and hardware that I've tried. If you have any problems with the VGA registers or anything not working as you expect, I'd strongly recommend this documentation. Far better than the very incomplete and often misleading "documentation" in the wiki.
Image
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: qemu not writing to even memory addresses in video memor

Post by dozniak »

Did you probably masked some plane registers inadvertently? Afaik even in this mode you need to enable planes writing to be able to ... actually write to them.
Learn to read.
dethboy
Posts: 14
Joined: Tue May 09, 2017 8:27 am

Re: qemu not writing to even memory addresses in video memor

Post by dethboy »

mallard wrote: The actual bug is that the "Map Mask" register (Sequencer register 0x02) is set incorrectly, only enabling planes 1 and 3 (value 0x05), it should be set to 0x0F to enable all planes. Clearly Bochs ignores this value in "Chain 4" mode, but QEMU doesn't (QEMU is likely more accurate to real hardware).
it worked! I went back to the place where got the register settings from and it was indeed an 0x0F. I specifically re-checked many times and it still got past me.

Is there any protocol regarding updatating the wiki?
Post Reply