mirror of
https://github.com/AppleWin/AppleWin.git
synced 2026-10-25 14:03:18 +00:00
1. Registry functions The set of functions are changed to consistently use bool arguments. The macros are changed to inline functions to improve type checking. RegSaveValue() are overloaded with help of templates to reduce typecasting at call sites. For instance, bool value would be converted consistently instead of relying on call sites to convert bool to int values. 2. Memory functions BOOL usages were unnecessary. Mostly internal usages which can simply be bool. 3. FrameBase Some member variables are changed to bool. BOOL was used because of those Registry functions. Additional changes: - Some expressions are forced to be bool when assigning to bool variables.
279 lines
9.7 KiB
C++
279 lines
9.7 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-2007, Tom Charlesworth, Michael Pohoreski, Nick Westgate
|
|
|
|
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: Parallel Printer Interface Card emulation
|
|
*
|
|
* Author: Nick Westgate, Stannev
|
|
*/
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "ParallelPrinter.h"
|
|
#include "Core.h"
|
|
#include "Memory.h"
|
|
#include "Pravets.h"
|
|
#include "Registry.h"
|
|
#include "YamlHelper.h"
|
|
#include "Interface.h"
|
|
|
|
#include "../resource/resource.h"
|
|
|
|
//===========================================================================
|
|
|
|
void ParallelPrinterCard::InitializeIO(LPBYTE pCxRomPeripheral)
|
|
{
|
|
const uint32_t PRINTDRVR_SIZE = APPLE_SLOT_SIZE;
|
|
BYTE* pData = GetFrame().GetResource(IDR_PRINTDRVR_FW, "FIRMWARE", PRINTDRVR_SIZE);
|
|
if(pData == NULL)
|
|
return;
|
|
|
|
memcpy(pCxRomPeripheral + m_slot*APPLE_SLOT_SIZE, pData, PRINTDRVR_SIZE);
|
|
|
|
RegisterIoHandler(m_slot, IORead, IOWrite, NULL, NULL, this, NULL);
|
|
}
|
|
|
|
//===========================================================================
|
|
bool ParallelPrinterCard::CheckPrint(void)
|
|
{
|
|
m_inactivity = 0;
|
|
if (m_file == NULL)
|
|
{
|
|
//char filepath[MAX_PATH * 2];
|
|
//strncpy(filepath, g_sProgramDir, MAX_PATH);
|
|
//_tcsncat(filepath, "Printer.txt", MAX_PATH);
|
|
//file = fopen(filepath, "wb");
|
|
if (m_bPrinterAppend )
|
|
m_file = fopen(ParallelPrinterCard::GetFilename().c_str(), "ab");
|
|
else
|
|
m_file = fopen(ParallelPrinterCard::GetFilename().c_str(), "wb");
|
|
}
|
|
return (m_file != NULL);
|
|
}
|
|
|
|
//===========================================================================
|
|
void ParallelPrinterCard::ClosePrint(void)
|
|
{
|
|
if (m_file != NULL)
|
|
{
|
|
fclose(m_file);
|
|
m_file = NULL;
|
|
#ifdef _WIN32
|
|
std::string ExtendedFileName = "copy \"";
|
|
ExtendedFileName.append (ParallelPrinterCard::GetFilename());
|
|
ExtendedFileName.append ("\" prn");
|
|
//if (g_bDumpToPrinter) ShellExecute(NULL, "print", Printer_GetFilename(), NULL, NULL, 0); //Print through Notepad
|
|
if (m_bDumpToPrinter)
|
|
system (ExtendedFileName.c_str ()); //Print through console. This is supposed to be the better way, because it shall print images (with older printers only).
|
|
#endif
|
|
}
|
|
m_inactivity = 0;
|
|
}
|
|
|
|
//===========================================================================
|
|
void ParallelPrinterCard::Destroy(void)
|
|
{
|
|
ClosePrint();
|
|
}
|
|
|
|
//===========================================================================
|
|
void ParallelPrinterCard::Update(const ULONG nExecutedCycles)
|
|
{
|
|
if (m_file == NULL)
|
|
return;
|
|
|
|
// if ((inactivity += totalcycles) > (Printer_GetIdleLimit () * 1000 * 1000)) //This line seems to give a very big deviation
|
|
if ((m_inactivity += nExecutedCycles) > (ParallelPrinterCard::GetIdleLimit () * 710000))
|
|
{
|
|
// inactive, so close the file (next print will overwrite or append to it, according to the settings made)
|
|
ClosePrint();
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
void ParallelPrinterCard::Reset(const bool powerCycle)
|
|
{
|
|
ClosePrint();
|
|
}
|
|
|
|
//===========================================================================
|
|
BYTE __stdcall ParallelPrinterCard::IORead(WORD, WORD address, BYTE, BYTE, ULONG)
|
|
{
|
|
UINT slot = ((address & 0xff) >> 4) - 8;
|
|
ParallelPrinterCard* card = (ParallelPrinterCard*)MemGetSlotParameters(slot);
|
|
|
|
card->CheckPrint();
|
|
return 0xFF; // status - TODO?
|
|
}
|
|
|
|
//===========================================================================
|
|
BYTE __stdcall ParallelPrinterCard::IOWrite(WORD, WORD address, BYTE, BYTE value, ULONG)
|
|
{
|
|
UINT slot = ((address & 0xff) >> 4) - 8;
|
|
ParallelPrinterCard* card = (ParallelPrinterCard*)MemGetSlotParameters(slot);
|
|
|
|
if (!card->CheckPrint())
|
|
return 0;
|
|
|
|
// only allow writes to the load output port (i.e., $C090)
|
|
if ((address & 0xF) != 0)
|
|
return 0;
|
|
|
|
BYTE c = value & 0x7F;
|
|
|
|
if (IsPravets(GetApple2Type()))
|
|
{
|
|
if (card->m_bConvertEncoding)
|
|
c = GetPravets().ConvertToPrinterChar(value);
|
|
}
|
|
|
|
if ((card->m_bFilterUnprintable == false) || (c>31) || (c==13) || (c==10) || (c>0x7F)) //c>0x7F is needed for cyrillic characters
|
|
fwrite(&c, 1, 1, card->m_file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
const std::string& ParallelPrinterCard::GetFilename(void)
|
|
{
|
|
return m_szPrintFilename;
|
|
}
|
|
|
|
#define DEFAULT_PRINT_FILENAME "Printer.txt"
|
|
|
|
void ParallelPrinterCard::SetFilename(const std::string& prtFilename)
|
|
{
|
|
if (!prtFilename.empty())
|
|
{
|
|
m_szPrintFilename = prtFilename;
|
|
}
|
|
else //No registry entry is available
|
|
{
|
|
m_szPrintFilename = g_sProgramDir + DEFAULT_PRINT_FILENAME;
|
|
RegSaveString(REG_CONFIG, REGVALUE_PRINTER_FILENAME, true, m_szPrintFilename);
|
|
}
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
void ParallelPrinterCard::GetRegistryConfig(void)
|
|
{
|
|
std::string regSection = RegGetConfigSlotSection(m_slot);
|
|
|
|
uint32_t dwTmp;
|
|
char szFilename[MAX_PATH];
|
|
|
|
if (RegLoadValue(regSection.c_str(), REGVALUE_DUMP_TO_PRINTER, true, &dwTmp))
|
|
SetDumpToPrinter(dwTmp ? true : false);
|
|
|
|
if (RegLoadValue(regSection.c_str(), REGVALUE_CONVERT_ENCODING, true, &dwTmp))
|
|
SetConvertEncoding(dwTmp ? true : false);
|
|
|
|
if (RegLoadValue(regSection.c_str(), REGVALUE_FILTER_UNPRINTABLE, true, &dwTmp))
|
|
SetFilterUnprintable(dwTmp ? true : false);
|
|
|
|
if (RegLoadValue(regSection.c_str(), REGVALUE_PRINTER_APPEND, true, &dwTmp))
|
|
SetPrinterAppend(dwTmp ? true : false);
|
|
|
|
if (RegLoadString(regSection.c_str(), REGVALUE_PRINTER_FILENAME, true, szFilename, MAX_PATH, ""))
|
|
SetFilename(szFilename);
|
|
|
|
if (RegLoadValue(regSection.c_str(), REGVALUE_PRINTER_IDLE_LIMIT, true, &dwTmp))
|
|
SetIdleLimit(dwTmp);
|
|
}
|
|
|
|
void ParallelPrinterCard::SetRegistryConfig(void)
|
|
{
|
|
std::string regSection = RegGetConfigSlotSection(m_slot);
|
|
RegSaveValue(regSection.c_str(), REGVALUE_DUMP_TO_PRINTER, true, GetDumpToPrinter());
|
|
RegSaveValue(regSection.c_str(), REGVALUE_CONVERT_ENCODING, true, GetConvertEncoding());
|
|
RegSaveValue(regSection.c_str(), REGVALUE_FILTER_UNPRINTABLE, true, GetFilterUnprintable());
|
|
RegSaveValue(regSection.c_str(), REGVALUE_PRINTER_APPEND, true, GetPrinterAppend());
|
|
RegSaveString(regSection.c_str(), REGVALUE_PRINTER_FILENAME, true, GetFilename());
|
|
RegSaveValue(regSection.c_str(), REGVALUE_PRINTER_IDLE_LIMIT, true, GetIdleLimit());
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
#define SS_YAML_KEY_INACTIVITY "Inactivity"
|
|
#define SS_YAML_KEY_IDLELIMIT "Printer Idle Limit"
|
|
#define SS_YAML_KEY_FILENAME "Print Filename"
|
|
#define SS_YAML_KEY_FILEOPEN "Is File Open"
|
|
#define SS_YAML_KEY_DUMPTOPRINTER "Dump To Printer"
|
|
#define SS_YAML_KEY_CONVERTENCODING "Convert Encoding"
|
|
#define SS_YAML_KEY_FILTERUNPRINTABLE "Filter Unprintable"
|
|
#define SS_YAML_KEY_APPEND "Printer Append"
|
|
#define SS_YAML_KEY_DUMPTOREALPRINTER "Enable Dump To Real Printer"
|
|
|
|
const std::string& ParallelPrinterCard::GetSnapshotCardName(void)
|
|
{
|
|
static const std::string name("Generic Printer");
|
|
return name;
|
|
}
|
|
|
|
void ParallelPrinterCard::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper)
|
|
{
|
|
YamlSaveHelper::Slot slot(yamlSaveHelper, ParallelPrinterCard::GetSnapshotCardName(), m_slot, 1);
|
|
|
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE);
|
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, m_inactivity);
|
|
yamlSaveHelper.SaveUint(SS_YAML_KEY_IDLELIMIT, m_printerIdleLimit);
|
|
yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, m_szPrintFilename);
|
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_FILEOPEN, (m_file != NULL) ? true : false);
|
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOPRINTER, m_bDumpToPrinter);
|
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_CONVERTENCODING, m_bConvertEncoding);
|
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_FILTERUNPRINTABLE, m_bFilterUnprintable);
|
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_APPEND, m_bPrinterAppend);
|
|
yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOREALPRINTER, m_bEnableDumpToRealPrinter);
|
|
}
|
|
|
|
bool ParallelPrinterCard::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT version)
|
|
{
|
|
if (version != 1)
|
|
Card::ThrowErrorInvalidVersion(CT_GenericPrinter, version);
|
|
|
|
m_inactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY);
|
|
m_printerIdleLimit = yamlLoadHelper.LoadUint(SS_YAML_KEY_IDLELIMIT);
|
|
m_szPrintFilename = yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME);
|
|
|
|
if (yamlLoadHelper.LoadBool(SS_YAML_KEY_FILEOPEN))
|
|
{
|
|
yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND); // Consume
|
|
m_bPrinterAppend = true; // Re-open print-file in append mode
|
|
BOOL bRes = CheckPrint();
|
|
if (!bRes)
|
|
throw std::runtime_error("Printer Card: Unable to resume printing to file");
|
|
}
|
|
else
|
|
{
|
|
m_bPrinterAppend = yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND);
|
|
}
|
|
|
|
m_bDumpToPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOPRINTER);
|
|
m_bConvertEncoding = yamlLoadHelper.LoadBool(SS_YAML_KEY_CONVERTENCODING);
|
|
m_bFilterUnprintable = yamlLoadHelper.LoadBool(SS_YAML_KEY_FILTERUNPRINTABLE);
|
|
m_bEnableDumpToRealPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOREALPRINTER);
|
|
|
|
return true;
|
|
}
|