Menu

#529 Incorrect rendering using cga mode 4h 320*200*4 if x coordinate > certain value

0.74
open
nobody
None
1
2020-05-14
2020-05-13
Vadim Jh
No

Problem:
In cga mode 4h (320x200x4) if a pixel is put on screen using dos int 10h function 0ch, and cx regster contains big values (right part of screen) the pixel is put at the bottom of the screen.
Also screen seems distorted, the center is not at the center.

Steps:
1. Configure dosbox to resemble 8086 cpu machine=cga, cycles=1000-4000 (slightly faster so pixel moves faster)
2. Use attached test.com: cursor keys move the pixel on screen, esc exits.
3. Move pixel to the right of the screen, and try other positions

Expected:
Pixel can be moved to x coordinates > 255
Pixel starts at the center of 320*200 screen

Actual:
Pixel is drawn at the bottom (see screenshot or video) in incorrect positions
Pixel doesn't start at the center of screen.
The test.com works ok in 2 other 8086 emulators.

2 Attachments

Discussion

  • Vadim Jh

    Vadim Jh - 2020-05-13

    Fixed in Dosbox-X
    Affects online emulator https://virtualconsoles.com/online-emulators/dos/ so I can't showcase my program online.

     
  • ripsaw8080

    ripsaw8080 - 2020-05-13

    Thanks for the report. While there does seem to be an emulation issue involved, your program actually has a bug in it. You set DL=100 (0x64); however, DH is not zero because the DX register contains the PSP segment when the program is executed. Since INT 10/0C uses the DX register for the row number, and typical PSP segment in DOSBox will have DH=1, you end up asking to draw a pixel at row 356 (0x164). It should be a simple matter for you to fix your program by setting DH=0.

    The reason your program works as you expect on other emulators seems to be that CGA video memory read and write addresses are wrapped to 16K (&0x3FFF) in hardware. That seems reasonable at least, and may be a good change to make in DOSBox.

     
  • Vadim Jh

    Vadim Jh - 2020-05-13

    Thanks and sorry for the buggy test code. I confirm that setting dh=0 fixed the problem. I didn't clear it because other emu machine had used its own bios implementation of int 10h using only dl and stated this in its documentation. Now I've checked int 10h docs on wikipedia and fully understand that the full dx register is the standard.

     
  • ripsaw8080

    ripsaw8080 - 2020-05-13

    Glad to hear you have it fixed. I checked DOSBox SVN, and it already wraps CGA video memory addresses to 16K. It appears there might be some row/col clipping in real video BIOSes that result from divide and multiply processes, so that could be something worth investigation. However, not sure how the problem did not appear for you in DOSBox-X as it has the same PutPixel() code as DOSBox SVN for mode 4.

     
  • Vadim Jh

    Vadim Jh - 2020-05-14

    I have a couple of clues, but I'm not sure:
    I'm emulating cga machine and using .com files. When I was reading wikipedia stating that dx register is used and documentation for old PC clone which used dl, questions popped up in my head: "Is it only clone's feature? Did original PC XT use dl or dx? Does dosbox with cga machine emulate with completely different code than vga machine? Does it have different bios emulation? Is PSP setting in dosbox present in all real PCs starting from original PC, XT, AT?"

     
  • Vadim Jh

    Vadim Jh - 2020-05-14

    Also are you sure that dx register should contain PSP segment, wikipedia says "The segment address of the PSP is passed in the DS register when the program is executed." DX is not a DS.

     
  • Vadim Jh

    Vadim Jh - 2020-05-14

    Ok, original bios listing of XT uses full DX. (checked the manual)

     
  • ripsaw8080

    ripsaw8080 - 2020-05-14

    DOSBox-X has the same code for emulating INT 10/0C in mode 4 as SVN, so the video BIOS implementation does not appear to be a factor; however, it has raised the segment that programs load at compared to SVN, so the value of DH will almost certainly be more than 1 when programs execute, and that can cause different results because of the address wrapping.

    ES and DS (and SS for COM format) are set to the PSP segment on program execution, but DX is also set to that value. The initial values of BX, CX, DX, and BP are not well-documented for the DOS EXEC function, but DOSBox takes care to set all register values the same as real DOS for compatibility.

     

Log in to post a comment.