Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Andrea Odetti 2019-10-12 14:29:08 +01:00
commit 6c28c71e7f
21 changed files with 215 additions and 90 deletions

View file

@ -8,6 +8,22 @@ https://github.com/AppleWin/AppleWin/issues/new
Tom Charlesworth
1.29.3.0 - 12 Oct 2019
----------------------
. [Bug #700] Fixed ProDOS8 2.5.0 alpha6 (support INC $C08B to set LC to write mode).
. [Bug #695] Fixed WOZ 'Taipan' not booting.
- fixed reading write protect on a write access & support Sequencer Function.
. [Bug #668] Fixed WOZ 'Seafox' not booting.
- set machine = Unenhanced Apple //e or lower & need slot2 empty.
- disable SSC in slot-2 using: '-s2 empty' command line.
- added '-s1 empty', '-s3 empty' and '-s6 empty' too.
. [Bug #666] Debugger: support showing video v,h and cycle count.
- videoinfo <dec|hex|apple|real> to configure display.
- added auto-run of DebuggerAutoRun.txt on AppleWin initial start-up.
. [Bug #319] SmartPort return address was wrong when crossing page (fix to slot-7 HDD's firmware).
. [PR #687] Replace char * with std::string.
1.29.2.0 - 6 Sep 2019
---------------------
. [Change #678] Hotkeys to change emulation speed:

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,4 +1,11 @@
a65_w32 -b -l HDDRVR.A65 >hddrvr.lst
@del HDDRVR.BIN
rename 6502.bin HDDRVR.BIN
copy HDDRVR.BIN ..\..\resource
@REM ACME only ever returns 0!
acme.exe hddrvr.a65
@IF %ERRORLEVEL% NEQ 0 goto error
copy hddrvr.bin ..\..\resource
@goto end
:error
@echo "ACME failed"
:end

View file

@ -26,14 +26,15 @@
;
; Modified by Tom Charlesworth:
; . Fixed so it can be assembled by a65 v1.06
; . Updated so it can be assembled by ACME 0.96.4
; . Fixed so that ProDOS entrypoint is $c70a (26 Dev 2007) (Bug #12723)
; . Modified to support Apple Oasis' entrypoint: $c761 (8 Sept 2012) (Feature #5557)
; . Added support for SmartPort entrypoint (20 Oct 2012)
; - EG. "Prince of Persia (Original 3.5 floppy for IIc+).2mg"
; . GH#370 (Robert Hoem, 27 Oct 2016):
. Added a check against open-apple during boot to route boot to slot 6
. This happens after the first two blocks are loaded from the HD.
; . Added a check against open-apple during boot to route boot to slot 6
; . This happens after the first two blocks are loaded from the HD.
; . GH#319: smartport return address wrong when crossing page
; TODO:
; . Make code relocatable (so HDD controller card can go into any slot)
; . Remove support for Entrypoint_C746 (old AppleWin) & Entrypoint_C761 (Apple Oasis)
@ -41,6 +42,10 @@
; . Check SmartPort: Is it OK to trash Y and $42,..,$47 ?
;
!cpu 6502 ; Compatible with all Apple2's
!to "hddrvr.bin", plain
!sl "hddrvr.labels"
; constants
hd_execute = $c0f0
hd_error = $c0f1
@ -65,6 +70,8 @@ BUTTON0 = $C061
;; code
*= $c700 ; org $c700
!zone code
start
; Autoboot and ProDOS look at the following few opcodes to detect block devices
@ -102,14 +109,7 @@ Bootstrap
; error capturing code. Applewin is picky
; about code assigning data to registers and
; memory. The safest method is via I/O port
pha
lda hd_error
clc
cmp #1
bne noerr0
sec
noerr0
pla
ror hd_error ; Post: C=0 or 1
bcc hdboot
; no image ready, boot diskette image instead
@ -123,12 +123,14 @@ BootSlot6
SmartPort
pla
sta $46
adc #3 ; Pre: C=0, Post: C=0 or 1
tay
pla
sta $47 ; ($47) = &cmd_hdr
sta $47 ; ($46) = &cmd_hdr
adc #0
pha
lda $46
adc #3 ; Pre: C=0, Post: assume C=0
pha ; (sp).w += 3
tya
pha ; (sp).w += 3
ldy #1
lda ($46),y ; cmd
@ -137,7 +139,7 @@ SmartPort
bne SmartPort2
;======================================
; 2 unused bytes
; 8 unused bytes
*= $c746 ; org $c746
@ -231,12 +233,7 @@ cmdproc
bne skipSread
jsr sread
skipSread
lda hd_error
clc
cmp #1
bne noerr2
sec
noerr2
ror hd_error ; Post: C=0 or 1
pla
rts
@ -247,7 +244,7 @@ noerr2
; the emulated code increments the buffer by 1 on each read) to (memblock),y
; increment memblock+1 and read the second 256 bytes via hd_nextbyte.
;
; if I could figure out how to consistantly get applewin to update it's memory regions all
; if I could figure out how to consistently get applewin to update it's memory regions all
; this code can be moved into the emulation code (although, this is how I'd build the hardware
; anyway...)
@ -293,7 +290,9 @@ SmartPort3
bne cmdproc
;======================================
; 12 unused bytes
; 18 unused bytes
!zone data
; $CsFE = status bits (BAP p7-14)
; 7 = medium is removable
@ -308,12 +307,9 @@ SmartPort3
; $D7 = Removable, Interruptable, #Volumes=2, Supports write/read/status
; $BF = Removable, Interruptable, #Volumes=4, Supports format/write/read/status (KEGS / IIGS)
; datablock. This starts near the end of the firmware (at offset $FC)
;; data
*= $c7fc ; org $c7fc
.word $7fff ; how many blocks are on the device.
.byte $D7 ; specifics about the device (number of drives, read/write/format capability, etc)
.byte <Entrypoint_ProDOS ; entry point offset for ProDOS (must be $0a)
.end
!word $7fff ; how many blocks are on the device.
!byte $D7 ; specifics about the device (number of drives, read/write/format capability, etc)
!byte <Entrypoint_ProDOS ; entry point offset for ProDOS (must be $0a)

View file

@ -25,6 +25,14 @@
-s0 &lt;languagecard|lc&gt;<br>
Insert an Apple 16K Language Card into slot 0 in the original Apple II and use the F8 auto-start ROM.<br>
NB. The Apple II+ already defaults to having a Language Card, so this switch is not required.<br><br>
-s1 empty<br>
Remove the printer card from slot 1.<br><br>
-s2 empty<br>
Remove the SSC card from slot 2.<br><br>
-s3 empty<br>
Remove the Uthernet card from slot 3.<br><br>
-s6 empty<br>
Remove the Disk II controller card from slot 6.<br><br>
-s7 empty<br>
Remove the hard disk controller card from slot 7.<br>
Useful to allow a floppy disk to boot from slot 6, drive 1. Use in combination with -d1.<br><br>

View file

@ -229,7 +229,9 @@ MODE 2</span></b></font></font></p>
<p>
You can run custom batch or script files that contain debugger commands.&nbsp;
Scripts files do not echo their input; to print a string to the output console
window, use the <b>ECHO</b> command.
window, use the <b>ECHO</b> command. NB. When AppleWin initially starts-up, it
will attempt to auto-run '<b>DebuggerAutoRun.txt</b>' (located in the same folder
as AppleWin.exe).
</p>
<br>
<table border="0" cellpadding="2" cellspacing="0" width="80%">

Binary file not shown.

View file

@ -1,4 +1,4 @@
#define APPLEWIN_VERSION 1,29,2,0
#define APPLEWIN_VERSION 1,29,3,0
#define xstr(a) str(a)
#define str(a) #a

View file

@ -676,7 +676,7 @@ void LoadConfiguration(void)
g_bPrinterAppend = dwTmp ? true : false;
if(REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp)) // TODO: Change to REGVALUE_SLOT7
HD_SetEnabled(dwTmp ? true : false);
if(REGLOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp))
@ -762,10 +762,7 @@ bool SetCurrentImageDir(const std::string & pszImageDir)
int nLen = g_sCurrentDir.size();
if ((nLen > 0) && (g_sCurrentDir[ nLen - 1 ] != '\\'))
{
g_sCurrentDir[ nLen + 0 ] = '\\';
g_sCurrentDir.resize(nLen + 1);
}
g_sCurrentDir += '\\';
if( SetCurrentDirectory(g_sCurrentDir.c_str()) )
return true;

View file

@ -21,6 +21,7 @@ public:
m_SlotAux = CT_Empty;
m_Slot[4] = g_Slot[4];
m_Slot[5] = g_Slot[5];
m_Slot[7] = g_Slot[7];
}
const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other)

View file

@ -118,16 +118,28 @@ void CPropertySheetHelper::SaveCpuType(eCpuType NewCpuType)
REGSAVE(TEXT(REGVALUE_CPU_TYPE), NewCpuType);
}
void CPropertySheetHelper::SetSlot4(SS_CARDTYPE NewCardType)
void CPropertySheetHelper::SetSlot(UINT slot, SS_CARDTYPE newCardType)
{
g_Slot[4] = NewCardType;
REGSAVE(TEXT(REGVALUE_SLOT4), (DWORD)g_Slot[4]);
}
_ASSERT(slot < NUM_SLOTS);
if (slot >= NUM_SLOTS)
return;
void CPropertySheetHelper::SetSlot5(SS_CARDTYPE NewCardType)
{
g_Slot[5] = NewCardType;
REGSAVE(TEXT(REGVALUE_SLOT5), (DWORD)g_Slot[5]);
g_Slot[slot] = newCardType;
std::string slotText;
switch (slot)
{
case 0: slotText = REGVALUE_SLOT0; break;
case 1: slotText = REGVALUE_SLOT1; break;
case 2: slotText = REGVALUE_SLOT2; break;
case 3: slotText = REGVALUE_SLOT3; break;
case 4: slotText = REGVALUE_SLOT4; break;
case 5: slotText = REGVALUE_SLOT5; break;
case 6: slotText = REGVALUE_SLOT6; break;
case 7: slotText = REGVALUE_SLOT7; break;
}
REGSAVE(slotText.c_str(), (DWORD)g_Slot[slot]);
}
// Looks like a (bad) C&P from SaveStateSelectImage()
@ -395,15 +407,21 @@ void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew
SaveCpuType(ConfigNew.m_CpuType);
}
if (CONFIG_CHANGED_LOCAL(m_Slot[4]))
SetSlot4(ConfigNew.m_Slot[4]);
UINT slot = 4;
if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
SetSlot(slot, ConfigNew.m_Slot[slot]);
if (CONFIG_CHANGED_LOCAL(m_Slot[5]))
SetSlot5(ConfigNew.m_Slot[5]);
slot = 5;
if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
SetSlot(slot, ConfigNew.m_Slot[slot]);
// slot = 7;
// if (CONFIG_CHANGED_LOCAL(m_Slot[slot]))
// SetSlot(slot, ConfigNew.m_Slot[slot]);
if (CONFIG_CHANGED_LOCAL(m_bEnableHDD))
{
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), ConfigNew.m_bEnableHDD ? 1 : 0);
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), ConfigNew.m_bEnableHDD ? 1 : 0); // TODO: Change to REGVALUE_SLOT7
}
if (CONFIG_CHANGED_LOCAL(m_bEnableTheFreezesF8Rom))

View file

@ -14,8 +14,7 @@ public:
virtual ~CPropertySheetHelper(){}
void FillComboBox(HWND window, int controlid, LPCTSTR choices, int currentchoice);
void SetSlot4(SS_CARDTYPE NewCardType);
void SetSlot5(SS_CARDTYPE NewCardType);
void SetSlot(UINT slot, SS_CARDTYPE newCardType);
std::string BrowseToFile(HWND hWindow, TCHAR* pszTitle, TCHAR* REGVALUE,TCHAR* FILEMASKS);
void SaveStateUpdate();
int SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bool bSave);

View file

@ -6485,12 +6485,9 @@ Update_t CmdOutputRun (int nArgs)
else
{
char sText[ CONSOLE_WIDTH ];
ConsolePrintFormat( sText, "%sCouldn't load filename: %s%s"
, CHC_ERROR
, CHC_STRING
, sFileName.c_str()
);
}
ConsolePrintFormat(sText, "%sCouldn't load filename:", CHC_ERROR);
ConsolePrintFormat(sText, "%s%s", CHC_STRING, sFileName.c_str());
}
return ConsoleUpdate();
}
@ -8987,6 +8984,15 @@ void DebugInitialize ()
_Bookmark_Reset();
static bool doneAutoRun = false;
if (!doneAutoRun) // Don't re-run on a VM restart
{
doneAutoRun = true;
std::string pathname = g_sProgramDir + "DebuggerAutoRun.txt";
strcpy_s(g_aArgs[1].sArg, MAX_ARG_LEN, pathname.c_str());
CmdOutputRun(1);
}
CmdMOTD(0);
}

View file

@ -154,12 +154,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
const int DISPLAY_ZEROPAGE_COLUMN = INFO_COL_1;
const int DISPLAY_SOFTSWITCH_COLUMN = INFO_COL_1 - (CONSOLE_FONT_WIDTH/2) + 1; // 1/2 char width padding around soft switches
// Horizontal Column (pixels) of BPs, Watches & Mem
// Horizontal Column (pixels) of BPs, Watches
const int INFO_COL_2 = (62 * 7); // nFontWidth
const int DISPLAY_BP_COLUMN = INFO_COL_2;
const int DISPLAY_WATCHES_COLUMN = INFO_COL_2;
const int DISPLAY_MINIMEM_COLUMN = INFO_COL_2;
const int DISPLAY_VIDEO_SCANNER_COLUMN = INFO_COL_2;
// Horizontal Column (pixels) of VideoScannerInfo & Mem
const int INFO_COL_3 = (63 * 7); // nFontWidth
const int DISPLAY_MINIMEM_COLUMN = INFO_COL_3;
const int DISPLAY_VIDEO_SCANNER_COLUMN = INFO_COL_3;
#else
const int DISPLAY_CPU_INFO_LEFT_COLUMN = SCREENSPLIT1 // TC: SCREENSPLIT1 is not defined anywhere in the .sln!
@ -3654,38 +3657,48 @@ void DrawSubWindow_Data (Update_t bUpdate)
}
//===========================================================================
void DrawVideoScannerValue(int line, LPCTSTR name, int nValue, bool isVisible)
void DrawVideoScannerValue(int line, int vert, int horz, bool isVisible)
{
if (!((g_iWindowThis == WINDOW_CODE) || ((g_iWindowThis == WINDOW_DATA))))
return;
const int nFontWidth = g_aFontConfig[FONT_INFO]._nFontWidthAvg;
const int nameWidth = 2; // 2 chars
const int numberWidth = 3; // 3 chars
const int gapWidth = 1; // 1 space
const int totalWidth = (nameWidth + numberWidth) * 2 + gapWidth;
RECT rect;
rect.top = line * g_nFontHeight;
rect.bottom = rect.top + g_nFontHeight;
rect.left = DISPLAY_VIDEO_SCANNER_COLUMN;
rect.right = rect.left + (5 * nFontWidth);
rect.right = rect.left + (totalWidth * nFontWidth);
DebuggerSetColorBG(DebuggerGetColor(BG_VIDEOSCANNER_TITLE));
DebuggerSetColorFG(DebuggerGetColor(FG_VIDEOSCANNER_TITLE));
PrintText(name, rect);
for (int i = 0; i < 2; i++)
{
DebuggerSetColorBG(DebuggerGetColor(BG_VIDEOSCANNER_TITLE));
DebuggerSetColorFG(DebuggerGetColor(FG_VIDEOSCANNER_TITLE));
char sValue[8];
if (g_videoScannerDisplayInfo.isDecimal)
sprintf_s(sValue, sizeof(sValue), "%03u", nValue);
else
sprintf_s(sValue, sizeof(sValue), "%03X", nValue);
const int nValue = (i == 0) ? vert : horz;
// Needs to be far enough over, since 4 chars of ZeroPage symbol also calls us
const int nOffset = 2;
rect.left = DISPLAY_VIDEO_SCANNER_COLUMN + (nOffset * nFontWidth);
if (i == 0) PrintText("v:", rect);
else PrintText("h:", rect);
rect.left += nameWidth * nFontWidth;
if (!isVisible)
DebuggerSetColorFG(DebuggerGetColor(FG_VIDEOSCANNER_INVISIBLE)); // red
else
DebuggerSetColorFG(DebuggerGetColor(FG_VIDEOSCANNER_VISIBLE)); // green
PrintText(sValue, rect);
char sValue[8];
if (g_videoScannerDisplayInfo.isDecimal)
sprintf_s(sValue, sizeof(sValue), "%03u", nValue);
else
sprintf_s(sValue, sizeof(sValue), "%03X", nValue);
if (!isVisible)
DebuggerSetColorFG(DebuggerGetColor(FG_VIDEOSCANNER_INVISIBLE)); // red
else
DebuggerSetColorFG(DebuggerGetColor(FG_VIDEOSCANNER_VISIBLE)); // green
PrintText(sValue, rect);
rect.left += (numberWidth+gapWidth) * nFontWidth;
}
}
//===========================================================================
@ -3709,10 +3722,31 @@ void DrawVideoScannerInfo (int line)
}
}
const bool isVisible = NTSC_IsVisible();
DrawVideoScannerValue(line, v, h, NTSC_IsVisible());
line++;
DrawVideoScannerValue(line++, "h:", h, isVisible);
DrawVideoScannerValue(line++, "v:", v, isVisible);
//
const int nFontWidth = g_aFontConfig[FONT_INFO]._nFontWidthAvg;
const int nameWidth = 7;
const int numberWidth = 8;
const int totalWidth = nameWidth + numberWidth;
RECT rect;
rect.top = line * g_nFontHeight;
rect.bottom = rect.top + g_nFontHeight;
rect.left = DISPLAY_VIDEO_SCANNER_COLUMN;
rect.right = rect.left + (totalWidth * nFontWidth);
DebuggerSetColorBG(DebuggerGetColor(BG_VIDEOSCANNER_TITLE));
DebuggerSetColorFG(DebuggerGetColor(FG_VIDEOSCANNER_TITLE));
PrintText("cycles:", rect);
rect.left += nameWidth * nFontWidth;
char sValue[10];
sprintf_s(sValue, sizeof(sValue), "%08X", (UINT32)g_nCumulativeCycles);
PrintText(sValue, rect);
}
//===========================================================================

View file

@ -101,7 +101,7 @@
class VideoScannerDisplayInfo
{
public:
VideoScannerDisplayInfo() : isDecimal(true), isHorzReal(true) {}
VideoScannerDisplayInfo() : isDecimal(false), isHorzReal(false) {}
bool isDecimal;
bool isHorzReal;

View file

@ -2005,8 +2005,6 @@ bool Disk2InterfaceCard::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT
m_enhanceDisk = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENHANCE_DISK);
m_floppyLatch = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_LATCH);
m_floppyMotorOn = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_MOTOR_ON);
m_seqFunc.writeMode = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_WRITE_MODE) ? 1 : 0;
m_seqFunc.loadMode = 0; // Wasn't saved until v5 - overwritten later if v5
if (version >= 2)
{
@ -2030,6 +2028,11 @@ bool Disk2InterfaceCard::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT
{
m_seqFunc.function = (SEQFUNC) yamlLoadHelper.LoadInt(SS_YAML_KEY_LSS_SEQUENCER_FUNCTION);
}
else
{
m_seqFunc.writeMode = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_WRITE_MODE) ? 1 : 0;
m_seqFunc.loadMode = 0; // Wasn't saved until v5
}
// Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1
for (UINT i=0; i<NUM_DRIVES; i++)

View file

@ -147,7 +147,7 @@ struct HDD
ImageInfo* imagehandle; // Init'd by HD_Insert() -> ImageOpen()
bool bWriteProtected; // Needed for ImageOpen() [otherwise not used]
//
BYTE hd_error;
BYTE hd_error; // NB. Firmware requires that b0=0 (OK) or b0=1 (Error)
WORD hd_memblock;
UINT hd_diskblock;
WORD hd_buf_ptr;
@ -275,6 +275,7 @@ void HD_SetEnabled(const bool bEnabled)
return;
g_bHD_Enabled = bEnabled;
g_Slot[7] = bEnabled ? CT_GenericHDD : CT_Empty;
#if 0
// FIXME: For LoadConfiguration(), g_uSlot=7 (see definition at start of file)
@ -595,6 +596,12 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG
#if HD_LED
pHDD->hd_status_next = DISK_STATUS_OFF; // TODO: FIXME: ??? YELLOW ??? WARNING
#endif
if (pHDD->hd_error)
{
_ASSERT(pHDD->hd_error & 1);
pHDD->hd_error |= 1; // Firmware requires that b0=1 for an error
}
r = pHDD->hd_error;
break;
case 0xF2:

View file

@ -29,6 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "StdAfx.h"
#include "Applewin.h"
#include "CPU.h" // GH#700
#include "LanguageCard.h"
#include "Log.h"
#include "Memory.h"
@ -74,6 +75,10 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu
{
memmode |= MF_WRITERAM; // UTAIIe:5-23
}
else if (bWrite && pLC->GetLastRamWrite() && pLC->IsOpcodeRMWabs(uAddr)) // GH#700
{
memmode |= MF_WRITERAM;
}
}
else
{
@ -98,6 +103,31 @@ BYTE __stdcall LanguageCardUnit::IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValu
return bWrite ? 0 : MemReadFloatingBus(nExecutedCycles);
}
// GH#700: INC $C083/C08B (RMW) to write enable the LC
bool LanguageCardUnit::IsOpcodeRMWabs(WORD addr)
{
BYTE param1 = mem[(regs.pc - 2) & 0xffff];
BYTE param2 = mem[(regs.pc - 1) & 0xffff];
if (param1 != (addr & 0xff) || param2 != 0xC0)
return false;
BYTE opcode = mem[(regs.pc - 3) & 0xffff];
if (opcode == 0xEE || // INC abs
opcode == 0xCE || // DEC abs
opcode == 0x6E || // ROR abs
opcode == 0x4E || // LSR abs
opcode == 0x2E || // ROL abs
opcode == 0x0E) // ASL abs
return true;
if ((GetMainCpu() == CPU_65C02) && (
opcode == 0x1C || // TRB abs
opcode == 0x0C)) // TSB abs
return true;
return false;
}
//-------------------------------------
LanguageCardSlot0::LanguageCardSlot0(void)

View file

@ -19,6 +19,7 @@ public:
BOOL GetLastRamWrite(void) { return m_uLastRamWrite; }
void SetLastRamWrite(BOOL count) { m_uLastRamWrite = count; }
SS_CARDTYPE GetMemoryType(void) { return m_type; }
bool IsOpcodeRMWabs(WORD addr);
static BYTE __stdcall IO(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nExecutedCycles);