2007-03-23 22:26:35 +00:00
/*
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
2007-04-01 15:24:52 +00:00
Copyright ( C ) 2006 - 2007 , Tom Charlesworth , Michael Pohoreski , Nick Westgate
2007-03-23 22:26:35 +00:00
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
*
2009-01-17 15:10:00 +00:00
* Author : Nick Westgate , Stannev
2007-03-23 22:26:35 +00:00
*/
# include "StdAfx.h"
2014-08-13 20:30:35 +00:00
2020-11-11 21:15:27 +00:00
# include "ParallelPrinter.h"
2020-11-26 21:50:06 +00:00
# include "Core.h"
2014-08-13 20:30:35 +00:00
# include "Memory.h"
2021-01-17 10:48:06 +00:00
# include "Pravets.h"
2014-08-13 20:30:35 +00:00
# include "Registry.h"
2015-12-05 16:50:27 +00:00
# include "YamlHelper.h"
2021-01-19 20:37:43 +00:00
# include "Interface.h"
2014-08-13 20:30:35 +00:00
2018-02-24 15:12:40 +00:00
# include "../resource/resource.h"
2007-03-23 22:26:35 +00:00
//===========================================================================
2007-05-28 11:16:42 +00:00
2022-03-18 22:04:34 +00:00
void ParallelPrinterCard : : InitializeIO ( LPBYTE pCxRomPeripheral )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
const DWORD PRINTDRVR_SIZE = APPLE_SLOT_SIZE ;
2021-01-19 20:37:43 +00:00
BYTE * pData = GetFrame ( ) . GetResource ( IDR_PRINTDRVR_FW , " FIRMWARE " , PRINTDRVR_SIZE ) ;
2007-03-23 22:26:35 +00:00
if ( pData = = NULL )
return ;
2022-03-18 22:04:34 +00:00
memcpy ( pCxRomPeripheral + m_slot * APPLE_SLOT_SIZE , pData , PRINTDRVR_SIZE ) ;
2007-05-28 11:16:42 +00:00
2022-03-18 22:04:34 +00:00
RegisterIoHandler ( m_slot , IORead , IOWrite , NULL , NULL , this , NULL ) ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2022-03-18 22:04:34 +00:00
bool ParallelPrinterCard : : CheckPrint ( void )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
m_inactivity = 0 ;
if ( m_file = = NULL )
{
2009-01-09 21:59:22 +00:00
//TCHAR filepath[MAX_PATH * 2];
//_tcsncpy(filepath, g_sProgramDir, MAX_PATH);
2022-03-18 22:04:34 +00:00
//_tcsncat(filepath, _T("Printer.txt"), MAX_PATH);
2009-01-09 21:59:22 +00:00
//file = fopen(filepath, "wb");
2022-03-18 22:04:34 +00:00
if ( m_bPrinterAppend )
m_file = fopen ( ParallelPrinterCard : : GetFilename ( ) . c_str ( ) , " ab " ) ;
2009-01-09 21:59:22 +00:00
else
2022-03-18 22:04:34 +00:00
m_file = fopen ( ParallelPrinterCard : : GetFilename ( ) . c_str ( ) , " wb " ) ;
}
return ( m_file ! = NULL ) ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2022-03-18 22:04:34 +00:00
void ParallelPrinterCard : : ClosePrint ( void )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
if ( m_file ! = NULL )
{
fclose ( m_file ) ;
m_file = NULL ;
2014-08-13 20:30:35 +00:00
std : : string ExtendedFileName = " copy \" " ;
2022-03-18 22:04:34 +00:00
ExtendedFileName . append ( ParallelPrinterCard : : GetFilename ( ) ) ;
2009-01-09 21:59:22 +00:00
ExtendedFileName . append ( " \" prn " ) ;
//if (g_bDumpToPrinter) ShellExecute(NULL, "print", Printer_GetFilename(), NULL, NULL, 0); //Print through Notepad
2022-03-18 22:04:34 +00:00
if ( m_bDumpToPrinter )
2009-01-09 21:59:22 +00:00
system ( ExtendedFileName . c_str ( ) ) ; //Print through console. This is supposed to be the better way, because it shall print images (with older printers only).
2022-03-18 22:04:34 +00:00
}
m_inactivity = 0 ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2022-03-18 22:04:34 +00:00
void ParallelPrinterCard : : Destroy ( void )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
ClosePrint ( ) ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2022-03-18 22:04:34 +00:00
void ParallelPrinterCard : : Update ( const ULONG nExecutedCycles )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
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 ( ) ;
}
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2022-03-18 22:04:34 +00:00
void ParallelPrinterCard : : Reset ( const bool powerCycle )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
ClosePrint ( ) ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2022-03-18 22:04:34 +00:00
BYTE __stdcall ParallelPrinterCard : : IORead ( WORD , WORD address , BYTE , BYTE , ULONG )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
UINT slot = ( ( address & 0xff ) > > 4 ) - 8 ;
ParallelPrinterCard * card = ( ParallelPrinterCard * ) MemGetSlotParameters ( slot ) ;
card - > CheckPrint ( ) ;
return 0xFF ; // status - TODO?
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2022-03-18 22:04:34 +00:00
BYTE __stdcall ParallelPrinterCard : : IOWrite ( WORD , WORD address , BYTE , BYTE value , ULONG )
2007-03-23 22:26:35 +00:00
{
2022-03-18 22:04:34 +00:00
UINT slot = ( ( address & 0xff ) > > 4 ) - 8 ;
ParallelPrinterCard * card = ( ParallelPrinterCard * ) MemGetSlotParameters ( slot ) ;
if ( ! card - > CheckPrint ( ) )
2021-01-17 10:48:06 +00:00
return 0 ;
2022-02-11 20:57:09 +00:00
// only allow writes to the load output port (i.e., $C090)
if ( ( address & 0xF ) ! = 0 )
return 0 ;
2021-01-17 10:48:06 +00:00
BYTE c = value & 0x7F ;
if ( IsPravets ( GetApple2Type ( ) ) )
2020-10-11 16:14:03 +00:00
{
2022-03-18 22:04:34 +00:00
if ( card - > m_bConvertEncoding )
2021-01-17 10:48:06 +00:00
c = GetPravets ( ) . ConvertToPrinterChar ( value ) ;
2020-10-11 16:14:03 +00:00
}
2022-03-18 22:04:34 +00:00
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 ) ;
2021-01-17 10:48:06 +00:00
2009-01-09 21:59:22 +00:00
return 0 ;
2007-03-23 22:26:35 +00:00
}
//===========================================================================
2009-01-09 21:59:22 +00:00
2022-03-18 22:04:34 +00:00
const std : : string & ParallelPrinterCard : : GetFilename ( void )
2009-01-09 21:59:22 +00:00
{
2022-03-18 22:04:34 +00:00
return m_szPrintFilename ;
2009-01-09 21:59:22 +00:00
}
2022-03-18 22:04:34 +00:00
# define DEFAULT_PRINT_FILENAME "Printer.txt"
void ParallelPrinterCard : : SetFilename ( const std : : string & prtFilename )
2009-01-09 21:59:22 +00:00
{
2019-09-06 16:34:25 +00:00
if ( ! prtFilename . empty ( ) )
2018-08-12 11:48:08 +00:00
{
2022-03-18 22:04:34 +00:00
m_szPrintFilename = prtFilename ;
2018-08-12 11:48:08 +00:00
}
2009-01-09 21:59:22 +00:00
else //No registry entry is available
{
2022-03-18 22:04:34 +00:00
m_szPrintFilename = g_sProgramDir + DEFAULT_PRINT_FILENAME ;
RegSaveString ( REG_CONFIG , REGVALUE_PRINTER_FILENAME , 1 , m_szPrintFilename ) ;
2009-01-09 21:59:22 +00:00
}
}
2022-03-18 22:04:34 +00:00
UINT ParallelPrinterCard : : GetIdleLimit ( void )
2009-01-09 21:59:22 +00:00
{
2022-03-18 22:04:34 +00:00
return m_printerIdleLimit ;
2009-01-09 21:59:22 +00:00
}
2022-03-18 22:04:34 +00:00
void ParallelPrinterCard : : SetIdleLimit ( UINT Duration )
2009-01-09 21:59:22 +00:00
{
2022-03-18 22:04:34 +00:00
m_printerIdleLimit = Duration ;
}
//===========================================================================
void ParallelPrinterCard : : GetRegistryConfig ( void )
{
std : : string regSection = RegGetConfigSlotSection ( m_slot ) ;
DWORD 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 , 1 , szFilename , MAX_PATH , TEXT ( " " ) ) )
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 ( ) ? 1 : 0 ) ;
RegSaveValue ( regSection . c_str ( ) , REGVALUE_CONVERT_ENCODING , TRUE , GetConvertEncoding ( ) ? 1 : 0 ) ;
RegSaveValue ( regSection . c_str ( ) , REGVALUE_FILTER_UNPRINTABLE , TRUE , GetFilterUnprintable ( ) ? 1 : 0 ) ;
RegSaveValue ( regSection . c_str ( ) , REGVALUE_PRINTER_APPEND , TRUE , GetPrinterAppend ( ) ? 1 : 0 ) ;
RegSaveString ( regSection . c_str ( ) , REGVALUE_PRINTER_FILENAME , TRUE , GetFilename ( ) ) ;
RegSaveValue ( regSection . c_str ( ) , REGVALUE_PRINTER_IDLE_LIMIT , TRUE , GetIdleLimit ( ) ) ;
2009-01-09 21:59:22 +00:00
}
2015-02-13 22:40:53 +00:00
//===========================================================================
2015-12-05 16:50:27 +00:00
# define SS_YAML_VALUE_CARD_PRINTER "Generic Printer"
# 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"
2022-03-18 22:04:34 +00:00
const std : : string & ParallelPrinterCard : : GetSnapshotCardName ( void )
2015-12-05 16:50:27 +00:00
{
static const std : : string name ( SS_YAML_VALUE_CARD_PRINTER ) ;
return name ;
}
2022-03-18 22:04:34 +00:00
void ParallelPrinterCard : : SaveSnapshot ( class YamlSaveHelper & yamlSaveHelper )
2015-12-05 16:50:27 +00:00
{
2022-03-18 22:04:34 +00:00
YamlSaveHelper : : Slot slot ( yamlSaveHelper , ParallelPrinterCard : : GetSnapshotCardName ( ) , m_slot , 1 ) ;
2015-12-05 16:50:27 +00:00
YamlSaveHelper : : Label state ( yamlSaveHelper , " %s: \n " , SS_YAML_KEY_STATE ) ;
2022-03-18 22:04:34 +00:00
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 ) ;
2015-12-05 16:50:27 +00:00
}
2022-03-18 22:04:34 +00:00
bool ParallelPrinterCard : : LoadSnapshot ( class YamlLoadHelper & yamlLoadHelper , UINT version )
2015-12-05 16:50:27 +00:00
{
2022-03-18 22:04:34 +00:00
if ( m_slot ! = SLOT1 ) // fixme
Card : : ThrowErrorInvalidSlot ( CT_GenericPrinter , m_slot ) ;
2015-12-05 16:50:27 +00:00
if ( version ! = 1 )
2022-01-30 21:25:40 +00:00
Card : : ThrowErrorInvalidVersion ( CT_GenericPrinter , version ) ;
2015-12-05 16:50:27 +00:00
2022-03-18 22:04:34 +00:00
m_inactivity = yamlLoadHelper . LoadUint ( SS_YAML_KEY_INACTIVITY ) ;
m_printerIdleLimit = yamlLoadHelper . LoadUint ( SS_YAML_KEY_IDLELIMIT ) ;
m_szPrintFilename = yamlLoadHelper . LoadString ( SS_YAML_KEY_FILENAME ) ;
2015-12-05 16:50:27 +00:00
2016-02-24 22:38:59 +00:00
if ( yamlLoadHelper . LoadBool ( SS_YAML_KEY_FILEOPEN ) )
2015-12-05 16:50:27 +00:00
{
2016-02-24 22:38:59 +00:00
yamlLoadHelper . LoadBool ( SS_YAML_KEY_APPEND ) ; // Consume
2022-03-18 22:04:34 +00:00
m_bPrinterAppend = true ; // Re-open print-file in append mode
2015-12-05 16:50:27 +00:00
BOOL bRes = CheckPrint ( ) ;
if ( ! bRes )
2021-12-18 16:37:28 +00:00
throw std : : runtime_error ( " Printer Card: Unable to resume printing to file " ) ;
2015-12-05 16:50:27 +00:00
}
else
{
2022-03-18 22:04:34 +00:00
m_bPrinterAppend = yamlLoadHelper . LoadBool ( SS_YAML_KEY_APPEND ) ;
2015-12-05 16:50:27 +00:00
}
2022-03-18 22:04:34 +00:00
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 ) ;
2015-12-05 16:50:27 +00:00
return true ;
}