Files
AppleWin/source/Debugger/Debugger_Range.cpp
TomCh 1a68914a4a Fix all x64 warnings in the AppleWin proj (PR #1434)
NB. 10 warnings still in libyaml proj (but there's no upstream update - so will leave as-is).
2025-09-22 21:25:35 +01:00

236 lines
6.2 KiB
C++

/*
AppleWin : An Apple //e emulator for Windows
Copyright (C) 1994-1996, Michael O'Brien
Copyright (C) 1999-2001, Oliver Schmidt
Copyright (C) 2002-2005, Tom Charlesworth
Copyright (C) 2006-2010, Tom Charlesworth, Michael Pohoreski
AppleWin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
AppleWin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with AppleWin; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Description: Debugger Utility Range
*
* Author: Copyright (C) 2006-2010 Michael Pohoreski
*/
#include "StdAfx.h"
#include "Debug.h"
#include "../CardManager.h"
// Util - Range _______________________________________________________________
//===========================================================================
RangeType_t Range_GetPrefix(const int iArg, AddressPrefix_t* pAP)
{
if ((iArg + 1) >= MAX_ARGS)
return RANGE_NO_PREFIX;
if (g_aArgs[iArg + 1].eToken != TOKEN_FSLASH)
return RANGE_NO_PREFIX;
// Spec: (GH#451)
// [sN/][nn/][L<1|2>/][ROM/]<nnnn>
if (tolower(g_aArgs[iArg].sArg[0]) == 's') // slot
{
size_t len = strlen(g_aArgs[iArg].sArg);
pAP->nSlot = g_aArgs[iArg].sArg[len - 1] - '0'; // eg. s1 or sl1 or slot1
if (pAP->nSlot > 7)
{
ConsoleDisplayError("Address prefix out-of-range. Use slots 0-7.");
return RANGE_PREFIX_BAD;
}
}
else if (tolower(g_aArgs[iArg].sArg[0]) == 'l') // LC
{
size_t len = strlen(g_aArgs[iArg].sArg);
pAP->nLangCard = g_aArgs[iArg].sArg[len - 1] - '0'; // eg. l1 or lc1
if (pAP->nLangCard < 1 || pAP->nLangCard > 2)
{
ConsoleDisplayError("Address prefix out-of-range. Use lc 1 or 2.");
return RANGE_PREFIX_BAD;
}
}
else if (tolower(g_aArgs[iArg].sArg[0]) == 'r') // ROM
{
pAP->bIsROM = true;
}
else // bank (RamWorks or Saturn)
{
if (g_aArgs[iArg].nValue > 0x100) // Permit 00-100
{
ConsoleDisplayError("Address prefix out-of-range. Use bank 0-100 (or 0-7 for Saturn).");
return RANGE_PREFIX_BAD;
}
pAP->nBank = g_aArgs[iArg].nValue;
}
return RANGE_PREFIX_OK;
}
//===========================================================================
bool Range_GetAllPrefixes(int& iArg, const int nArg, int& dArgPrefix, AddressPrefix_t* pAP, bool slotCheck/*=true*/)
{
const int kArgsPerPrefix = 2;
for (int i = iArg; i < nArg; i += kArgsPerPrefix)
{
RangeType_t prefix = Range_GetPrefix(i, pAP);
if (prefix == RANGE_NO_PREFIX)
break;
if (prefix == RANGE_PREFIX_BAD)
return false;
dArgPrefix += kArgsPerPrefix;
iArg += kArgsPerPrefix; // done 1 prefix (2 args)
}
// Got all prefixes, so do some checks:
if (pAP->bIsROM &&
(pAP->nSlot != AddressPrefix_t::kSlotInvalid || pAP->nBank != AddressPrefix_t::kBankInvalid || pAP->nLangCard != AddressPrefix_t::kLangCardInvalid))
{
ConsoleDisplayError("Address prefix bad: 'r/' not permitted with other prefixes.");
return false;
}
if (pAP->nSlot != AddressPrefix_t::kSlotInvalid) // Currently setting a slot# means Saturn card
{
if (slotCheck)
{
if (pAP->nBank != AddressPrefix_t::kBankInvalid && pAP->nBank > 7)
{
ConsoleDisplayError("Address prefix bad: Saturn only supports banks 0-7.");
return false;
}
if (GetCardMgr().QuerySlot(pAP->nSlot) != CT_Saturn128K)
{
ConsoleDisplayError("Address prefix bad: No Saturn in slot.");
return false;
}
}
}
else // No slot# specified, so aux slot (for Extended 80Col or RamWorks card)
{
if (pAP->nBank != AddressPrefix_t::kBankInvalid)
{
if (!IsAppleIIeOrAbove(GetApple2Type()))
{
ConsoleDisplayError("Address prefix bad: Aux slot requires //e or above.");
return false;
}
}
}
return true;
}
//===========================================================================
bool Range_CalcEndLen( const RangeType_t eRange
, const WORD & nAddress1, const WORD & nAddress2
, WORD & nAddressEnd_, int & nAddressLen_ )
{
bool bValid = false;
if (eRange == RANGE_HAS_LEN)
{
// BSAVE 2000,0 Len=0 End=n/a
// BSAVE 2000,1 Len=1 End=2000
// 0,FFFF [,)
// End = FFFE = Len-1
// Len = FFFF
nAddressLen_ = nAddress2;
unsigned int nTemp = nAddress1 + nAddressLen_ - 1;
if (nTemp > _6502_MEM_END)
nTemp = _6502_MEM_END;
nAddressEnd_ = nTemp;
bValid = true;
}
else
if (eRange == RANGE_HAS_END)
{
// BSAVE 2000:2000 Len=0, End=n/a
// BSAVE 2000:2001 Len=1, End=2000
// 0:FFFF [,]
// End = FFFF
// Len = 10000 = End+1
nAddressEnd_ = nAddress2;
nAddressLen_ = nAddress2 - nAddress1 + 1;
bValid = true;
}
return bValid;
}
//===========================================================================
RangeType_t Range_Get( WORD & nAddress1_, WORD & nAddress2_, const int iArg/* =1 */)
{
nAddress1_ = g_aArgs[ iArg ].nValue;
if (nAddress1_ > _6502_MEM_END)
nAddress1_ = _6502_MEM_END;
nAddress2_ = 0;
int nTemp = 0;
RangeType_t eRange = RANGE_MISSING_ARG_2;
if ((iArg + 2) >= MAX_ARGS)
return eRange;
if (g_aArgs[ iArg + 1 ].eToken == TOKEN_COMMA)
{
// 0,FFFF [,) // Note the mathematical range
// End = FFFE = Len-1
// Len = FFFF
eRange = RANGE_HAS_LEN;
nTemp = g_aArgs[ iArg + 2 ].nValue;
nAddress2_ = nTemp;
}
else
if (g_aArgs[ iArg + 1 ].eToken == TOKEN_COLON)
{
// 0:FFFF [,] // Note the mathematical range
// End = FFFF
// Len = 10000 = End+1
eRange = RANGE_HAS_END;
nTemp = g_aArgs[ iArg + 2 ].nValue;
// i.e.
// FFFF:D000
// 1 2 Temp
// FFFF D000
// FFFF
// D000
if (nAddress1_ > nTemp)
{
nAddress2_ = nAddress1_;
nAddress1_ = nTemp;
}
else
nAddress2_ = nTemp;
}
// .17 Bug Fix: D000,FFFF -> D000,CFFF (nothing searched!)
// if (nTemp > _6502_MEM_END)
// nTemp = _6502_MEM_END;
return eRange;
}