PCjr: If memsize is 128KB or less, subtract 16KB from total memory at BIOS level, omit reserved graphics memory MCB block at the DOS level. Otherwise, report total memory and insert reserved MCB block as if PCjr with a sidecar that adds memory, which is also DOSBox SVN default and its only behavior

This commit is contained in:
Jonathan Campbell
2021-03-24 14:23:03 -07:00
parent b032480b75
commit 54f5f10494
2 changed files with 32 additions and 24 deletions

View File

@@ -561,37 +561,36 @@ void DOS_SetupMemory(void) {
* for subtracting 32KB from top of system memory for video memory. */
mcb.SetSize(/*normally 0x97FF*/(seg_limit-1) - DOS_MEM_START - mcb_sizes);
} else if (machine==MCH_PCJR) {
DOS_MCB mcb_devicedummy((uint16_t)0x2000);
/* If there is more than 128KB of RAM, then the MCB chain must be constructed
* to exclude video memory. In that case, the BIOS values in the BDA will report
* actual memory size. I think this is what those DOS drivers for PCjr do that
* enable the use of additional RAM provided by a sidecar.
*
* If there is 128KB or less, then construct a normal MCB. The BIOS will subtract
* 16KB from top of memory. */
if (seg_limit > ((128*1024)/16)) {
DOS_MCB mcb_devicedummy((uint16_t)0x2000);
/* FIXME: The PCjr can have built-in either 64KB or 128KB of RAM.
* RAM beyond 128KB is made possible with expansion sidecars.
* DOSBox-X needs to support memsizekb=64 or memsizekb=128,
* and adjust video ram location appropriately. */
/* TODO: Allow memsizekb=64 to emulate a PCjr without the memory extension */
/* NTS: BIOS takes 16KB off the top, therefore the 128-16 KB check */
if (seg_limit < (((128-16)*1024)/16))
E_Exit("PCjr requires at least 128K");
bool extend = seg_limit > ((128*1024)/16);
if (extend) {
/* memory from 128k to 640k is available */
mcb_devicedummy.SetPt((uint16_t)0x2000);
mcb_devicedummy.SetPSPSeg(MCB_FREE);
mcb_devicedummy.SetSize(/*0x9FFF*/(seg_limit-1) - 0x2000);
mcb_devicedummy.SetType(0x5a);
/* exclude PCJr graphics region */
mcb_devicedummy.SetPt((uint16_t)0x17ff);
mcb_devicedummy.SetPSPSeg(MCB_DOS);
mcb_devicedummy.SetSize(0x800);
mcb_devicedummy.SetType(0x4d);
/* memory below 96k */
mcb.SetSize(0x1800 - DOS_MEM_START - (2+mcb_sizes));
mcb.SetType(0x4d);
}
else {
/* Normal MCB chain, nothing special */
mcb.SetSize(/*normally 0x97FF*/(seg_limit-1) - DOS_MEM_START - mcb_sizes);
}
/* exclude PCJr graphics region */
mcb_devicedummy.SetPt((uint16_t)0x17ff);
mcb_devicedummy.SetPSPSeg(MCB_DOS);
mcb_devicedummy.SetSize(0x800);
mcb_devicedummy.SetType(extend ? 0x4d/*continue*/ : 0x5a/*end*/);
/* memory below 96k */
mcb.SetSize(0x1800 - DOS_MEM_START - (2+mcb_sizes));
mcb.SetType(0x4d);
} else {
#ifndef DEBUG_ALLOC
/* NTS: Testing suggests we can push as low as 4KB. However, Wikipedia and

View File

@@ -9369,6 +9369,15 @@ public:
LOG(LOG_MISC,LOG_DEBUG)("BIOS: setting tandy 128KB base region to %lxh",(unsigned long)tandy_128kbase);
}
else if (machine == MCH_PCJR) {
/* PCjr reserves the top of it's internal 128KB of RAM for video RAM.
* Sidecars can extend it past 128KB but it requires DOS drivers or TSRs
* to modify the MCB chain so that it a) marks the video memory as reserved
* and b) creates a new free region above the video RAM region.
*
* Therefore, only subtract 16KB if 128KB or less is configured for this machine.
*
* Note this is not speculation, it's there in the PCjr BIOS source code:
* [http://hackipedia.org/browse.cgi/Computer/Platform/PC%2c%20IBM%20compatible/Video/PCjr/IBM%20Personal%20Computer%20PCjr%20Hardware%20Reference%20Library%20Technical%20Reference%20%281983%2d11%29%20First%20Edition%20Revised%2epdf] ROM BIOS source code page A-16 */
if (t_conv <= (128+16)) {
if (t_conv > 128) t_conv = 128;
t_conv -= 16;