Multiple 320x200x16 buffers on 128K

Discussions on programming older machines

Multiple 320x200x16 buffers on 128K

Postby josh2112 » Wed Sep 11, 2019 10:07 am

I have been experimenting with some assembly-language graphics programming on the PCjr. I have a stock PCjr, no add-ons except the 64k memory expansion that goes inside, to total 128K. I can set the mode to 320x200, 16-color and draw in the memory region 0x18000-0x1ffff. Now what I'd like to do is double-buffering by using the preceding 32k (0x10000-00x17999) as a compositing area, drawing there then copying rectangular regions into the actual video buffer.

It's working great on the latest DOSBox SVN, but just gives me a blank screen on the PCjr. I suspect that DOSBox's incomplete PCjr emulation is allowing me to "get away with" something that the PCjr is not.

I'm not setting any CRT/CPU page registers, because the CRT page register already defaults to page 6 (0x18000) which is where I want video to pull from. I'm using the 0x10000-0x17fff area as a buffer only, then copying to the upper region.

Is there something I need to do to let the PCjr know I want to use the whole upper half of the 128K? I've seen references to "reserving" extra video RAM via stuff like jrconfig with the v64 option, but what is it actually doing? I load vanilla DOS 2.1 (no pcjrmem, jrconfig, etc.) from a floppy and run my compiled .COM program which is very small, a couple hundred bytes at most. With this configuration, I should have access to at least the upper 64K of ram, right?
josh2112
 
Posts: 5
Joined: Thu Nov 08, 2018 9:23 am

Re: Multiple 320x200x16 buffers on 128K

Postby Trixter » Wed Sep 11, 2019 10:48 am

DOSBox is not a complete PCjr emulator; you'll have to test your code on the real thing.

PCjr VGA-addressable memory is from 0-128K in 16K pages, for 8 pages total. Which pages are visible is determined by the page registers as you found out. Doing anything with page 0 (0-16K) is an extremely bad idea since that's where the interrupt table lives, and page 1 (16K-32K) is going to be taken up with the operating system if your code isn't in a ROM cartridge. Assuming your code is up to 64K in size, it will run out of pages 2 and 3, so that leaves you with four CRT/CPU pages at 4, 5, 6, and 7. This is enough RAM to give you:

4 x 160x200x16 screens
4 x 320x200x4 screens
4 x 640x200x2 screens
2 x 320x200x16 screens
2 x 640x200x4 screens

This is all available on a stock 128K system running DOS 2.11. If you have a memory expansion to 256K or more, you must use the -v64 option with jrconfig.sys in order for that area to be avoided loading programs and data, leaving it alone for video use.

The BIOS will grab CRT pages starting from the top downward, as you found out, but it only handles one visible screen. To use a hidden and visible screen, and be able to swap between them, you are going to have to:

- Manipulate the CRT page registers
- Manage your own memory, carefully

You said you were using 0x100000-0x17fff for off-screen and then copying to onscreen. There's no need to do that -- as long as your writes are aligned in the same way as the visible screen, just use the CRT page registers to switch the hidden and visible screens.
You're all insane and trying to steal my magic bag!
Trixter
 
Posts: 599
Joined: Mon Sep 01, 2008 12:00 am
Location: Illinois, USA

Re: Multiple 320x200x16 buffers on 128K

Postby Trixter » Wed Sep 11, 2019 10:50 am

Also, in case this helps, I've attached some old PCjr support routines; they show using the BIOS to manipulate the the page registers, which is way easier than doing it yourself.
Attachments
PCJRSUPP.TXT
(12.98 KiB) Downloaded 3 times
You're all insane and trying to steal my magic bag!
Trixter
 
Posts: 599
Joined: Mon Sep 01, 2008 12:00 am
Location: Illinois, USA

Re: Multiple 320x200x16 buffers on 128K

Postby josh2112 » Wed Sep 11, 2019 11:24 am

Thanks for the reply Trixter!

Trixter wrote:DOSBox is not a complete PCjr emulator; you'll have to test your code on the real thing.

PCjr VGA-addressable memory is from 0-128K in 16K pages, for 8 pages total. Which pages are visible is determined by the page registers as you found out. Doing anything with page 0 (0-16K) is an extremely bad idea since that's where the interrupt table lives, and page 1 (16K-32K) is going to be taken up with the operating system if your code isn't in a ROM cartridge. Assuming your code is up to 64K in size, it will run out of pages 2 and 3, so that leaves you with four CRT/CPU pages at 4, 5, 6, and 7. This is enough RAM to give you:

4 x 160x200x16 screens
4 x 320x200x4 screens
4 x 640x200x2 screens
2 x 320x200x16 screens
2 x 640x200x4 screens


That's what I thought. So there's nothing wrong with my scheme. Except if the .COM file is actually 64K, it's going to take four pages (they're 16k each). But right now it's like 800 bytes maximum -- I'm just experimenting.

Trixter wrote:This is all available on a stock 128K system running DOS 2.11. If you have a memory expansion to 256K or more, you must use the -v64 option with jrconfig.sys in order for that area to be avoided loading programs and data, leaving it alone for video use.


Good, so none of this config is necessary for my setup.

Trixter wrote:The BIOS will grab CRT pages starting from the top downward, as you found out, but it only handles one visible screen. To use a hidden and visible screen, and be able to swap between them, you are going to have to:

- Manipulate the CRT page registers
- Manage your own memory, carefully

You said you were using 0x100000-0x17fff for off-screen and then copying to onscreen. There's no need to do that -- as long as your writes are aligned in the same way as the visible screen, just use the CRT page registers to switch the hidden and visible screens.


Yes, that's an exercise for the future ;-) Right now I just want to keep the video address where it is, and use the preceding 32K area as a "scratchpad".

So if I understand, there should be nothing wrong with what I'm trying to do. If I boot up to DOS, no drivers or extra stuff, and run my sub-1K .COM program, it should have free access to the whole area from 64K to 128K. Then the problem is in my code :-/ Something is wrong that DOSBox is letting me slide by on, but the PCjr is not.

Thanks!
josh2112
 
Posts: 5
Joined: Thu Nov 08, 2018 9:23 am

Re: Multiple 320x200x16 buffers on 128K

Postby Trixter » Wed Sep 11, 2019 12:06 pm

josh2112 wrote:Then the problem is in my code :-/ Something is wrong that DOSBox is letting me slide by on, but the PCjr is not.


Agreed. I'm a critic of some uses of DOSBox; this is one of them. DOSBox is great for when you have no hardware. It is an impediment for when you DO have hardware.
You're all insane and trying to steal my magic bag!
Trixter
 
Posts: 599
Joined: Mon Sep 01, 2008 12:00 am
Location: Illinois, USA

Re: Multiple 320x200x16 buffers on 128K

Postby josh2112 » Wed Sep 11, 2019 12:31 pm

Ok, I'm pretty sure my problem is the stack pointer.

I didn't think about the fact that the stack pointer is at the end of the 64K segment at which my .COM file is loaded. So no matter how low in memory DOSBox loads my program, the stack pointer is going to be well into pages 4-5 (0x10000+) which is the "hidden page" area I was hoping to use.

Interestingly enough, the last official release of DOSBox (0.74-3) is setting my stack pointer to 0xa4e on inintialization (found this out through the use of DEBUG.COM), and my program works perfectly there. When I get home I'll see if I can get DEBUG.COM onto my PCjr and verify this.

So... can I move the stack pointer? Is that kosher? I've experimented with it and it seems to solve my problems completely -- just putting a "mov sp, 0x2000" at the beginning of my code to bring SP down out of the 64K+ area. I know that puts the onus on me to juggle the growing size of the program against the expected depth of my stack. Just part of assembly programming I guess.

Is there a better or more accepted way to tell COMMAND.COM I don't need my stack pointer way up in the stratosphere because I want to use that memory?
josh2112
 
Posts: 5
Joined: Thu Nov 08, 2018 9:23 am

Re: Multiple 320x200x16 buffers on 128K

Postby Trixter » Wed Sep 11, 2019 2:33 pm

That's the default location for the stack pointer, so real DOS is doing the correct thing; no idea why dosbox is doing something else. Can you move the stack pointer? Absolutely, which is why MOV SS,reg disables interrupts for the very next instruction (which is supposed to be a MOV SP,reg).

Wait, dosbox might not be setting SP that low -- that's just the init reg when in debug. If you execute the first instruction of your program in debug.com with "t" in dosbox, then type "r", is SP still that low, or does it move to FFFE like it's supposed to?
You're all insane and trying to steal my magic bag!
Trixter
 
Posts: 599
Joined: Mon Sep 01, 2008 12:00 am
Location: Illinois, USA

Re: Multiple 320x200x16 buffers on 128K

Postby josh2112 » Thu Sep 12, 2019 7:00 am

Trixter wrote:That's the default location for the stack pointer, so real DOS is doing the correct thing; no idea why dosbox is doing something else. Can you move the stack pointer? Absolutely, which is why MOV SS,reg disables interrupts for the very next instruction (which is supposed to be a MOV SP,reg).

Wait, dosbox might not be setting SP that low -- that's just the init reg when in debug. If you execute the first instruction of your program in debug.com with "t" in dosbox, then type "r", is SP still that low, or does it move to FFFE like it's supposed to?


No, it stays at its initial value. I guess I shouldn't be surprised that DOSBox's COMMAND.COM (which is based on DOS 5?) behaves differently than DOS 2.11.

But I did find the problem, and now my code works perfectly on the PCjr! Stack location was definitely an issue but I also found a separate coding error -- I declared a data-section variable as a byte, and pushed it onto the stack as a word. As the very last piece of data in the file, I guess a zero was next to it when run under DOSBox but on the PCjr, 0xC8 was the next byte so that got combined with the variable and pushed onto the stack.

Thanks again for your help! I'm sure I'll be asking more questions as this thing progresses...
josh2112
 
Posts: 5
Joined: Thu Nov 08, 2018 9:23 am

Re: Multiple 320x200x16 buffers on 128K

Postby josh2112 » Thu Sep 12, 2019 12:52 pm

So everything works now, but I have another question...

Via DEBUG.COM, I noticed my PCjr is loading my .COM program at segment 0x0B2A. This is almost 46K into my 128K of total memory. Which means if I want to be able to use all of the top 64K as two 320x200 screens, I need to keep my memory usage (program, stack, other variables) under 18K total!

This seems like an incredibly high starting address. There are no drivers or TSRs being loaded, no autoexec.bat or config.sys -- just booting straight into DOS and running my .COM program. I can't imagine all of that 46K is in use. So what's causing DOS to load my .COM program so high up in memory, and can I persuade it to go lower?

(I do have a couple expansion boards on the side (parallel port, 64K memory which I'm not using, and speech attachment), but like I said, no drivers are being loaded for any of these so they shouldn't be contributing to the RAM usage.)
josh2112
 
Posts: 5
Joined: Thu Nov 08, 2018 9:23 am

Re: Multiple 320x200x16 buffers on 128K

Postby Trixter » Thu Sep 12, 2019 1:32 pm

josh2112 wrote:Which means if I want to be able to use all of the top 64K as two 320x200 screens, I need to keep my memory usage (program, stack, other variables) under 18K total!


Correct!

So what's causing DOS to load my .COM program so high up in memory, and can I persuade it to go lower?


Well, debug is also loaded. So DOS+DEBUG.COM = 46K. Your program will have more memory available not loaded under debug.

While IBM provided a 320x200x16 and 640x200x4 mode, I don't think they meant for them to be used with two video pages on a 128K system. When IMAGIC wrote Touchdown Football, they used 4 160x200x16 video pages for the field, and wrote a custom boot loader so that they didn't need to load DOS first, so that's how they fit everything into 128KB.

It might be best to keep your expectations limited to .COM files for PCjr development :-)
You're all insane and trying to steal my magic bag!
Trixter
 
Posts: 599
Joined: Mon Sep 01, 2008 12:00 am
Location: Illinois, USA


Return to Programming

Who is online

Users browsing this forum: No registered users and 2 guests