Exemplo n.º 1
0
void DOS_FreeProcessMemory(Bit16u pspseg) {
	Bit16u mcb_segment=dos.firstMCB;
	DOS_MCB mcb(mcb_segment);
	for (;;) {
		if (mcb.GetPSPSeg()==pspseg) {
			mcb.SetPSPSeg(MCB_FREE);
		}
		if (mcb.GetType()==0x5a) {
			/* check if currently last block reaches up to the PCJr graphics memory */
			if ((machine==MCH_PCJR) && (mcb_segment+mcb.GetSize()==0x17fe) &&
			   (real_readb(0x17ff,0)==0x4d) && (real_readw(0x17ff,1)==8)) {
				/* re-enable the memory past segment 0x2000 */
				mcb.SetType(0x4d);
			} else break;
		}
		if (GCC_UNLIKELY(mcb.GetType()!=0x4d)) E_Exit("Corrupt MCB chain");
		mcb_segment+=mcb.GetSize()+1;
		mcb.SetPt(mcb_segment);
	}

	Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
	if (umb_start==UMB_START_SEG) {
		DOS_MCB umb_mcb(umb_start);
		for (;;) {
			if (umb_mcb.GetPSPSeg()==pspseg) {
				umb_mcb.SetPSPSeg(MCB_FREE);
			}
			if (umb_mcb.GetType()!=0x4d) break;
			umb_start+=umb_mcb.GetSize()+1;
			umb_mcb.SetPt(umb_start);
		}
	} else if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start);

	DOS_CompressMemory();
}
Exemplo n.º 2
0
void DOS_BuildUMBChain()
	{
	Bit16u first_umb_seg = DOS_PRIVATE_SEGMENT_END;
	Bit16u first_umb_size = 0xf000 - first_umb_seg - (TotEMSMB ? 0x1000 : 0);

	dos_infoblock.SetStartOfUMBChain(EndConvMem);
	dos_infoblock.SetUMBChainState(0);										// UMBs not linked yet

	DOS_MCB umb_mcb(first_umb_seg);
	umb_mcb.SetPSPSeg(MCB_FREE);											// Currently free
	umb_mcb.SetSize(first_umb_size-1);
	umb_mcb.SetType('Z');

	Bit16u mcb_segment = dos.firstMCB;										// Scan MCB-chain for last block
	DOS_MCB mcb(mcb_segment);
	while (mcb.GetType() != 'Z')
		{
		mcb_segment += mcb.GetSize()+1;
		mcb.SetPt(mcb_segment);
		}
	Bit16u cover_mcb = (Bit16u)(mcb_segment+mcb.GetSize()+1);				// A system MCB has to cover the space between the regular MCB-chain and the UMBs
	mcb.SetPt(cover_mcb);
	mcb.SetType('M');
	mcb.SetPSPSeg(0x0008);
	mcb.SetSize(first_umb_seg-cover_mcb-1);
	mcb.SetFileName("SC      ");
	}
Exemplo n.º 3
0
void DOS_BuildUMBChain(bool umb_active,bool ems_active) {
	if (umb_active  && (machine!=MCH_TANDY)) {
		Bit16u first_umb_seg = 0xd000;
		Bit16u first_umb_size = 0x2000;
		if(ems_active || (machine == MCH_PCJR)) first_umb_size = 0x1000;

		dos_infoblock.SetStartOfUMBChain(UMB_START_SEG);
		dos_infoblock.SetUMBChainState(0);		// UMBs not linked yet

		DOS_MCB umb_mcb(first_umb_seg);
		umb_mcb.SetPSPSeg(0);		// currently free
		umb_mcb.SetSize(first_umb_size-1);
		umb_mcb.SetType(0x5a);

		/* Scan MCB-chain for last block */
		Bit16u mcb_segment=dos.firstMCB;
		DOS_MCB mcb(mcb_segment);
		while (mcb.GetType()!=0x5a) {
			mcb_segment+=mcb.GetSize()+1;
			mcb.SetPt(mcb_segment);
		}

		/* A system MCB has to cover the space between the
		   regular MCB-chain and the UMBs */
		Bit16u cover_mcb=(Bit16u)(mcb_segment+mcb.GetSize()+1);
		mcb.SetPt(cover_mcb);
		mcb.SetType(0x4d);
		mcb.SetPSPSeg(0x0008);
		mcb.SetSize(first_umb_seg-cover_mcb-1);
		mcb.SetFileName("SC      ");

	} else {
		dos_infoblock.SetStartOfUMBChain(0xffff);
		dos_infoblock.SetUMBChainState(0);
	}
}
void DOS_BuildUMBChain(const char* use_umbs,bool ems_active) {
	if ((strcmp(use_umbs,"false")!=0) && (machine!=MCH_TANDY)) {
		Bit16u first_umb_seg=0xca00;
		Bit16u first_umb_size=0x600;

		if (strcmp(use_umbs,"max")==0) {
			first_umb_seg-=0x100;
			first_umb_size+=0x100;
		}

		dos_infoblock.SetStartOfUMBChain(UMB_START_SEG);
		dos_infoblock.SetUMBChainState(0);		// UMBs not linked yet

		DOS_MCB umb_mcb(first_umb_seg);
		umb_mcb.SetPSPSeg(0);		// currently free
		umb_mcb.SetSize(first_umb_size-1);
		umb_mcb.SetType(0x5a);

		/* Scan MCB-chain for last block */
		Bit16u mcb_segment=dos.firstMCB;
		DOS_MCB mcb(mcb_segment);
		while (mcb.GetType()!=0x5a) {
			mcb_segment+=mcb.GetSize()+1;
			mcb.SetPt(mcb_segment);
		}

		/* A system MCB has to cover the space between the
		   regular MCB-chain and the UMBs */
		Bit16u cover_mcb=(Bit16u)(mcb_segment+mcb.GetSize()+1);
		mcb.SetPt(cover_mcb);
		mcb.SetType(0x4d);
		mcb.SetPSPSeg(0x0008);
		mcb.SetSize(first_umb_seg-cover_mcb-1);
		mcb.SetFileName("SC      ");

		if (!ems_active && (strcmp(use_umbs,"max")==0) && (machine!=MCH_PCJR)) {
			Bit16u ems_umb_seg=0xe000;
			Bit16u ems_umb_size=0x1000;

			/* Continue UMB-chain */
			umb_mcb.SetSize(first_umb_size-2);
			umb_mcb.SetType(0x4d);

			DOS_MCB umb2_mcb(ems_umb_seg);
			umb2_mcb.SetPSPSeg(0);		// currently free
			umb2_mcb.SetSize(ems_umb_size-1);
			umb2_mcb.SetType(0x5a);

			/* A system MCB has to take out the space between the previous and this UMB */
			cover_mcb=(Bit16u)(first_umb_seg+umb_mcb.GetSize()+1);
			mcb.SetPt(cover_mcb);
			mcb.SetType(0x4d);
			mcb.SetPSPSeg(0x0008);
			mcb.SetSize(ems_umb_seg-cover_mcb-1);
			mcb.SetFileName("SC      ");
		}
	} else {
		dos_infoblock.SetStartOfUMBChain(0xffff);
		dos_infoblock.SetUMBChainState(0);
	}
}