Recent

Author Topic: How can I switch VGA X Mode from 320 to 640 on DOSBox?  (Read 1560 times)

Mr.Madguy

  • Sr. Member
  • ****
  • Posts: 455
How can I switch VGA X Mode from 320 to 640 on DOSBox?
« on: February 16, 2019, 08:52:44 pm »
Dunno, if somebody can help me with this problem, as it's very specific one. It isn't connected with FPC directly. I'm playing with VGA X Mode now and I have a problem. No matter, what I do, DOSBox refuses to switch from half-width resolution like 320/360 to full-width resolution like 640/720. I currently have problems with making screenshot of a problem, but what I see - is 320x240 picture, taking whole 640x480 screen, when every 2nd line is blank, instead of taking just 1/4 of it. I can change data of blank lines, i.e. vertical resolution is actually correct 480 one. It's horizontal resolution, that is wrong.

According to this article CRT registers should have the same data for both 320 and 640 modes. I.e. as in case of vertical resolution, being controlled by Maximum Scan Line register (and this one actually works perfectly for me), 2x/1x mode should be controlled by some register too. And according to this article, it's controlled by Dot Clock Rate bit. Problem is - it doesn't work. No matter, if I use 1 or 9 value for this register, result is still the same. 320/360 resolutions work perfectly, but 640/720 refuse to work, while switching to them via BIOS works as intended.

What can be wrong? Do I miss something?
« Last Edit: March 21, 2019, 10:43:17 am by Mr.Madguy »
DynamicData 3.0 is released!
Since now development is frozen - only optimization passes will be made at some point.
Lack of multiple inheritance turns it into abomination.

lucamar

  • Hero Member
  • *****
  • Posts: 2014
Re: How can I switch VGA X Mode from 320 to 640 on DOSBox?
« Reply #1 on: February 17, 2019, 01:04:38 am »
You should probably ask this in the Vogons forum but as an "apetitizer", check the value of "output" in the "[sdl]" section of your dosbox.conf Depending on your OS some values don't allow changing the size of the DOSBox window.

Check also "machine" in the "[dosbox]" section: IIRC only "vgaonly" is suppossed to be fully emulated.

This is asuming your code is doing what it should ... but it's very easy to foul up a VGA with a slip of the finger (when typing code).
« Last Edit: February 17, 2019, 01:13:46 am by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

Mr.Madguy

  • Sr. Member
  • ****
  • Posts: 455
Re: How can I switch VGA X Mode from 320 to 640 on DOSBox?
« Reply #2 on: February 17, 2019, 06:53:27 am »
You should probably ask this in the Vogons forum but as an "apetitizer", check the value of "output" in the "[sdl]" section of your dosbox.conf Depending on your OS some values don't allow changing the size of the DOSBox window.

Check also "machine" in the "[dosbox]" section: IIRC only "vgaonly" is suppossed to be fully emulated.

This is asuming your code is doing what it should ... but it's very easy to foul up a VGA with a slip of the finger (when typing code).
My output is OpenGL and vertical size actually changes.

I also thought, that something may be wrong with DOSBox itself. For example most games use 320x240 X Mode, so may be DOSBox just doesn't support higher resolutions. VgaOnly didn't help. Same problem. Interleaved 320x480 picture instead of 640x480 one. I know, that 512k VRAM and 128k video buffer support is required for this mode, but there would be different artifacts, if it wouldn't be supported. And 640x400, that should fit into 64k video buffer, doesn't work anyway.

UPD: QEMU gives the same result. Something must be wrong. I just can't believe, that there is not way to switch to 640 mode via VGA registers without using BIOS call. Yeah, I can use hack of a hack, i.e. double all timings. But in this case I'm not sure, that such program will work on real hardware. Timings are actually right for 640 mode. (4Fh + 1) x 8 = 640.
« Last Edit: February 17, 2019, 07:34:23 am by Mr.Madguy »
DynamicData 3.0 is released!
Since now development is frozen - only optimization passes will be made at some point.
Lack of multiple inheritance turns it into abomination.

lucamar

  • Hero Member
  • *****
  • Posts: 2014
Re: How can I switch VGA X Mode from 320 to 640 on DOSBox?
« Reply #3 on: February 17, 2019, 12:49:16 pm »
Have you tried in real hardware?
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.2/2.0.4  - FPC 3.0.4 on:
(K|L)Ubuntu 12..16, Windows XP SP3, various DOSes.

Mr.Madguy

  • Sr. Member
  • ****
  • Posts: 455
Re: How can I switch VGA X Mode from 320 to 640 on DOSBox?
« Reply #4 on: February 17, 2019, 01:02:04 pm »
Have you tried in real hardware?
No, unfortunately I don't have real hardware now. But what I've found, is that Seq register 01h bit 3 should work. From DOSBox Sources:
Code: C++  [Select]
  1. void write_p3c5(Bitu /*port*/,Bitu val,Bitu iolen) {
  2. //      LOG_MSG("SEQ WRITE reg %X val %X",seq(index),val);
  3.         switch(seq(index)) {
  4.         case 0:         /* Reset */
  5.                 seq(reset)=val;
  6.                 break;
  7.         case 1:         /* Clocking Mode */
  8.                 if (val!=seq(clocking_mode)) {
  9.                         // don't resize if only the screen off bit was changed
  10.                         if ((val&(~0x20))!=(seq(clocking_mode)&(~0x20))) {
  11.                                 seq(clocking_mode)=val;
  12.                                 VGA_StartResize();
  13.                         } else {
  14.                                 seq(clocking_mode)=val;
  15.                         }
  16.                         if (val & 0x20) vga.attr.disabled |= 0x2;
  17.                         else vga.attr.disabled &= ~0x2;
  18.                 }
  19.                 /* TODO Figure this out :)
  20.                         0       If set character clocks are 8 dots wide, else 9.
  21.                         2       If set loads video serializers every other character
  22.                                 clock cycle, else every one.
  23.                         3       If set the Dot Clock is Master Clock/2, else same as Master Clock
  24.                                 (See 3C2h bit 2-3). (Doubles pixels). Note: on some SVGA chipsets
  25.                                 this bit also affects the Sequencer mode.
  26.                         4       If set loads video serializers every fourth character clock cycle,
  27.                                 else every one.
  28.                         5       if set turns off screen and gives all memory cycles to the CPU
  29.                                 interface.
  30.                 */
  31.                 break;
  32.  
Code: C++  [Select]
  1. void VGA_StartResize(Bitu delay /*=50*/) {
  2.         if (!vga.draw.resizing) {
  3.                 vga.draw.resizing=true;
  4.                 if (vga.mode==M_ERROR) delay = 5;
  5.                 /* Start a resize after delay (default 50 ms) */
  6.                 if (delay==0) VGA_SetupDrawing(0);
  7.                 else PIC_AddEvent(VGA_SetupDrawing,(float)delay);
  8.         }
  9. }
  10.  
Code: C++  [Select]
  1. void VGA_SetupDrawing(Bitu /*val*/) {
  2.                 /* Check for 8 for 9 character clock mode */
  3.                 if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9;
  4.                 /* Check for pixel doubling, master clock/2 */
  5.                 if (vga.seq.clocking_mode & 0x8) {
  6.                         htotal*=2;
  7.                 }
  8.  
« Last Edit: February 17, 2019, 01:04:07 pm by Mr.Madguy »
DynamicData 3.0 is released!
Since now development is frozen - only optimization passes will be made at some point.
Lack of multiple inheritance turns it into abomination.

Mr.Madguy

  • Sr. Member
  • ****
  • Posts: 455
Re: How can I switch VGA X Mode from 320 to 640 on DOSBox?
« Reply #5 on: February 17, 2019, 04:13:07 pm »
Case is closed. All timings have to be doubled for 256 color modes, cuz, I guess, symbol is 4 pixel wide instead of 8 in this mode. I.e. 640/720 modes aren't actually possible for Mode X. Actually, possible, but, I guess, at 1/2 FPS. Dunno, if real hardware will be able to handle it.

UPD: Yeah, despite of wrong window aspect ratio in DOSBox (window has 1/2 of height, cuz due to some reasons DOSBox thinks, that horizontal resolution is 2x), 640/720 modes work with double timings. 128k frame buffer doesn't work though, so any modes higher than 640x400 work incorrectly. FPS should also be 30 instead of 60. Dunno, if this program will work on real hardware. Of course I can try to install FreeDos on flash drive and try it on my current computer. But I don't have time for this now and I'm not sure, that this test would give me accurate results. I also need to change lazy per-pixel rendering to fast per-plane one.
« Last Edit: February 17, 2019, 05:41:43 pm by Mr.Madguy »
DynamicData 3.0 is released!
Since now development is frozen - only optimization passes will be made at some point.
Lack of multiple inheritance turns it into abomination.

Mr.Madguy

  • Sr. Member
  • ****
  • Posts: 455
Re: How can I switch VGA X Mode from 320 to 640 on DOSBox?
« Reply #6 on: March 21, 2019, 10:43:03 am »
Does anybody have access to real VGA hardware? I mean REAL. Because my program works perfectly on DOSBox emulator, but when I try to run it from FreeDOS flash drive, it works correctly for standard BIOS modes, but just doesn't show any signs of life for VGA X. I.e. monitor just goes to no signal mode and then shuts down. I have modern Radeon card, so may be it just doesn't support anything beyond standard BIOS modes? I've debugged my program and dumped register values look good. I have just two doubtful things: 1) 160 mode retrace end value doesn't seem to be right. $80 means $20 or $40 (5 least significant bits are used, so $30 would be $90), but $20 is too small and $40 is too big. Should be something around $2E-$2F, i.e. value should be $8E or $8F. 2) There is contradictory information in Internet about MOR vertical sync values. Some sources say that 01=400 and 10=350 (DOSBox sources and register dump), but some sources say opposite. I've tried both variants and none of them works.

UPD. I've fixed some bugs and it works now (Forgot, that I had implemented sync disable for safety purposes and hadn't corrected register tables), but I'm still not sure about 160 horizontal mode (Is it even possible? May be "dot clock div 2" doesn't even work in 256 color mode?) and 350/400 vertical mode (both aren't stretched, i.e. shown in native aspect ratio), cuz my LCD monitor doesn't seem to respect any sync settings and behaves just like emulator.
« Last Edit: March 21, 2019, 01:15:14 pm by Mr.Madguy »
DynamicData 3.0 is released!
Since now development is frozen - only optimization passes will be made at some point.
Lack of multiple inheritance turns it into abomination.