Merge from AppleWin-Tom (r396-423):

- Replaced all non-GPL modules with GPL ones (6821, AY8910, Z80)
  . 6821 now from VICE (was MAME)
  . AY8910 now from FUSE (was MAME)
  . Z80 now from VICE (was Z80Em)
- Fix for Willy Byte & MB support (strange 6522 behaviour!)
This commit is contained in:
tomch 2009-01-09 23:27:29 +00:00
parent 7c006f2c03
commit 67919881a8
40 changed files with 9839 additions and 6615 deletions

View File

@ -409,6 +409,14 @@
RelativePath=".\source\Video.h"
>
</File>
<File
RelativePath=".\source\z80emu.cpp"
>
</File>
<File
RelativePath=".\source\z80emu.h"
>
</File>
<Filter
Name="Debugger"
>
@ -512,10 +520,6 @@
RelativePath=".\source\Tfe\Tfesupp.h"
>
</File>
<File
RelativePath=".\source\Tfe\Types.h"
>
</File>
<File
RelativePath=".\source\Tfe\Uilib.cpp"
>
@ -526,38 +530,58 @@
</File>
</Filter>
<Filter
Name="Z80"
Name="Z80VICE"
>
<File
RelativePath=".\source\Z80\README.txt"
RelativePath=".\source\Z80VICE\daa.cpp"
>
</File>
<File
RelativePath=".\source\Z80\z80.cpp"
RelativePath=".\source\Z80VICE\daa.h"
>
</File>
<File
RelativePath=".\source\Z80\z80.h"
RelativePath=".\source\Z80VICE\z80.cpp"
>
</File>
<File
RelativePath=".\source\Z80\z80codes.h"
RelativePath=".\source\Z80VICE\z80.h"
>
</File>
<File
RelativePath=".\source\Z80\z80daa.h"
RelativePath=".\source\Z80VICE\z80mem.cpp"
>
</File>
<File
RelativePath=".\source\Z80\z80emu.cpp"
RelativePath=".\source\Z80VICE\z80mem.h"
>
</File>
<File
RelativePath=".\source\Z80\z80emu.h"
RelativePath=".\source\Z80VICE\z80regs.h"
>
</File>
</Filter>
<Filter
Name="CommonVICE"
>
<File
RelativePath=".\source\CommonVICE\6510core.h"
>
</File>
<File
RelativePath=".\source\Z80\z80io.h"
RelativePath=".\source\CommonVICE\alarm.h"
>
</File>
<File
RelativePath=".\source\CommonVICE\interrupt.h"
>
</File>
<File
RelativePath=".\source\CommonVICE\mem.h"
>
</File>
<File
RelativePath=".\source\CommonVICE\types.h"
>
</File>
</Filter>

View File

@ -1,531 +1,271 @@
// Based on MAME's 6821pia.c
// - by Kyle Kim (Apple in PC)
/*
* mc6821.c - MC6821 emulation for the 1571 disk drives with DD3.
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
//
// From mame.txt (http://www.mame.net/readme.html)
//
// VI. Reuse of Source Code
// --------------------------
// This chapter might not apply to specific portions of MAME (e.g. CPU
// emulators) which bear different copyright notices.
// The source code cannot be used in a commercial product without the written
// authorization of the authors. Use in non-commercial products is allowed, and
// indeed encouraged. If you use portions of the MAME source code in your
// program, however, you must make the full source code freely available as
// well.
// Usage of the _information_ contained in the source code is free for any use.
// However, given the amount of time and energy it took to collect this
// information, if you find new information we would appreciate if you made it
// freely available as well.
//
/*#define MC_DEBUG*/
#include "stdafx.h"
#include "6821.h"
// Ctrl-A(B) register bit mask define
/*
0 1
bit0 IRQ1_DISABLED IRQ1_ENABLED
bit1 C1_HIGH_TO_LOW C1_LOW_TO_HIGH
bit2 DDR_SELECTED OUTPUT_SELECTED
bit3 RESET_C2 SET_C2 ( C2_OUTPUT & C2_SETMODE )
bit3 STROBE_C1_RESET STROBE_E_RESET ( C2_OUTPUT & C2_STROBE_MODE )
bit4 C2_STROBE_MODE C2_SETMODE ( C2_OUTPUT )
bit3 IRQ2_DISABLED IRQ2_ENABLED ( C2_INPUT )
bit4 C2_HIGH_TO_LOW C2_HIGH_TO_LOW ( C2_INPUT )
bit5 C2_INPUT C2_OUTPUT
*/
#define PIA_IRQ1 0x80
#define PIA_IRQ2 0x40
#define SET_IRQ1(c) c |= PIA_IRQ1;
#define SET_IRQ2(c) c |= PIA_IRQ2;
#define CLEAR_IRQ1(c) c &= ~PIA_IRQ1;
#define CLEAR_IRQ2(c) c &= ~PIA_IRQ2;
#define IRQ1(c) ( c & PIA_IRQ1 )
#define IRQ2(c) ( c & PIA_IRQ2 )
#define IRQ1_ENABLED(c) ( c & 0x01 )
#define IRQ1_DISABLED(c) !( c & 0x01 )
#define C1_LOW_TO_HIGH(c) ( c & 0x02 )
#define C1_HIGH_TO_LOW(c) !( c & 0x02 )
#define OUTPUT_SELECTED(c) ( c & 0x04 )
#define DDR_SELECTED(c) !( c & 0x04 )
#define IRQ2_ENABLED(c) ( c & 0x08 )
#define IRQ2_DISABLED(c) !( c & 0x08 )
#define STROBE_E_RESET(c) ( c & 0x08 )
#define STROBE_C1_RESET(c) !( c & 0x08 )
#define SET_C2(c) ( c & 0x08 )
#define RESET_C2(c) !( c & 0x08 )
#define C2_LOW_TO_HIGH(c) ( c & 0x10 )
#define C2_HIGH_TO_LOW(c) !( c & 0x10 )
#define C2_SET_MODE(c) ( c & 0x10 )
#define C2_STROBE_MODE(c) !( c & 0x10 )
#define C2_OUTPUT(c) ( c & 0x20 )
#define C2_INPUT(c) !( c & 0x20 )
#define PIA_W_CALLBACK(st, val) \
if ( st.func ) st.func( this, st.objTo, 0, val )
if ( st.func ) st.func( st.objTo, val )
//////////////////////////////////////////////////////////////////////
/*-----------------------------------------------------------------------*/
/* MC6821 register functions. */
C6821::C6821()
void C6821::mc6821_write_pra(BYTE byte, unsigned int dnr)
{
Reset();
m_stOutA.objTo = NULL;
m_stOutA.func = NULL;
m_stOutB.objTo = NULL;
m_stOutB.func = NULL;
m_stOutCA2.objTo = NULL;
m_stOutCA2.func = NULL;
m_stOutCB2.objTo = NULL;
m_stOutCB2.func = NULL;
m_stOutIRQA.objTo = NULL;
m_stOutIRQA.func = NULL;
m_stOutIRQB.objTo = NULL;
m_stOutIRQB.func = NULL;
//if (mc6821[dnr].drive->parallel_cable == DRIVE_PC_DD3)
// parallel_cable_drive_write(byte, PARALLEL_WRITE, dnr);
mc6821[dnr].pra = byte;
if (mc6821[dnr].ddra) // AppleWin:TC
PIA_W_CALLBACK( m_stOutA, mc6821[dnr].pra & mc6821[dnr].ddra );
}
C6821::~C6821()
void C6821::mc6821_write_ddra(BYTE byte, unsigned int dnr)
{
//parallel_cable_drive_write((BYTE)((~byte) | mc6821[dnr].pra), PARALLEL_WRITE, dnr);
if (mc6821[dnr].ddra == byte) // AppleWin:TC
return;
mc6821[dnr].ddra = byte;
if (mc6821[dnr].ddra) // AppleWin:TC
PIA_W_CALLBACK( m_stOutA, mc6821[dnr].pra & mc6821[dnr].ddra );
}
void C6821::SetListenerA(void *objTo, mem_write_handler func)
BYTE C6821::mc6821_read_pra(unsigned int dnr)
{
m_stOutA.objTo = objTo;
m_stOutA.func = func;
BYTE byte = m_byIA; // AppleWin:TC
//BYTE byte = 0xff;
//int hs = 0;
//if ((mc6821[dnr].cra & 0x28) == 0x28)
// hs = 1;
//if (mc6821[dnr].drive->parallel_cable == DRIVE_PC_DD3)
// byte = parallel_cable_drive_read(hs);
mc6821[dnr].cra = (BYTE)(mc6821[dnr].cra & 0x7f);
mc6821[dnr].cra = (BYTE)(mc6821[dnr].cra & 0xbf); // AppleWin:TC (Clear IRQ2)
return (mc6821[dnr].pra & mc6821[dnr].ddra)
| (byte & ~(mc6821[dnr].ddra));
}
void C6821::SetListenerB(void *objTo, mem_write_handler func)
void C6821::mc6821_write_prb(BYTE byte, unsigned int dnr)
{
m_stOutB.objTo = objTo;
m_stOutB.func = func;
mc6821[dnr].prb = byte;
if (mc6821[dnr].ddrb) // AppleWin:TC
PIA_W_CALLBACK( m_stOutB, mc6821[dnr].prb & mc6821[dnr].ddrb );
}
void C6821::SetListenerCA2(void *objTo, mem_write_handler func)
void C6821::mc6821_write_ddrb(BYTE byte, unsigned int dnr)
{
m_stOutCA2.objTo = objTo;
m_stOutCA2.func = func;
if (mc6821[dnr].ddrb == byte) // AppleWin:TC
return;
mc6821[dnr].ddrb = byte;
if (mc6821[dnr].ddrb) // AppleWin:TC
PIA_W_CALLBACK( m_stOutB, mc6821[dnr].prb & mc6821[dnr].ddrb );
}
void C6821::SetListenerCB2(void *objTo, mem_write_handler func)
BYTE C6821::mc6821_read_prb(unsigned int dnr)
{
m_stOutCB2.objTo = objTo;
m_stOutCB2.func = func;
mc6821[dnr].crb = (BYTE)(mc6821[dnr].crb & 0x7f); // AppleWin:TC (Clear IRQ1)
mc6821[dnr].crb = (BYTE)(mc6821[dnr].crb & 0xbf); // AppleWin:TC (Clear IRQ2)
BYTE byte = m_byIB; // AppleWin:TC
return (mc6821[dnr].prb & mc6821[dnr].ddrb)
| (byte & ~(mc6821[dnr].ddrb));
}
BYTE C6821::Read(BYTE byRS)
void C6821::mc6821_write_cra(BYTE byte, unsigned int dnr)
{
BYTE retval = 0;
byRS &= 3;
switch ( byRS )
{
/******************* port A output/DDR read *******************/
case PIA_DDRA:
// read output register
if ( OUTPUT_SELECTED(m_byCTLA) )
{
// combine input and output values
retval = ( m_byOA & m_byDDRA ) | ( m_byIA & ~m_byDDRA );
// IRQ flags implicitly cleared by a read
CLEAR_IRQ1( m_byCTLA );
CLEAR_IRQ1( m_byCTLB );
UpdateInterrupts();
// CA2 is configured as output and in read strobe mode
if ( C2_OUTPUT(m_byCTLA) && C2_STROBE_MODE(m_byCTLA) )
{
// this will cause a transition low; call the output function if we're currently high
if ( m_byOCA2 )
PIA_W_CALLBACK( m_stOutCA2, 0 );
m_byOCA2 = 0;
// if the CA2 strobe is cleared by the E, reset it right away
if ( STROBE_E_RESET( m_byCTLA ) )
{
PIA_W_CALLBACK( m_stOutCA2, 1 );
m_byOCA2 = 1;
}
}
}
// read DDR register
else
{
retval = m_byDDRA;
}
break;
/******************* port B output/DDR read *******************/
case PIA_DDRB:
// read output register
if ( OUTPUT_SELECTED( m_byCTLB ) )
{
// combine input and output values
retval = ( m_byOB & m_byDDRB ) + ( m_byIB & ~m_byDDRB );
// IRQ flags implicitly cleared by a read
CLEAR_IRQ2( m_byCTLA );
CLEAR_IRQ2( m_byCTLB );
UpdateInterrupts();
}
/* read DDR register */
else
{
retval = m_byDDRB;
}
break;
/******************* port A control read *******************/
case PIA_CTLA:
// read control register
retval = m_byCTLA;
// when CA2 is an output, IRQA2 = 0, and is not affected by CA2 transitions.
if ( C2_OUTPUT( m_byCTLA ) )
retval &= ~PIA_IRQ2;
break;
/******************* port B control read *******************/
case PIA_CTLB:
retval = m_byCTLB;
// when CB2 is an output, IRQB2 = 0, and is not affected by CB2 transitions.
if ( C2_OUTPUT( m_byCTLB ) )
retval &= ~PIA_IRQ2;
break;
}
// static BYTE old_cra = 0;
//
// if ((old_cra & 0x38) != (byte & 0x38)) {
//#ifdef MC_DEBUG
// log_debug("MODE %02x", byte & 0x38);
//#endif
// old_cra = byte;
// }
return retval;
mc6821[dnr].cra = byte;
}
void C6821::Write(BYTE byRS, BYTE byData)
void C6821::mc6821_write_crb(BYTE byte, unsigned int dnr)
{
byRS &= 3;
switch( byRS )
{
/******************* port A output/DDR write *******************/
case PIA_DDRA:
// write output register
if ( OUTPUT_SELECTED( m_byCTLA ) )
{
// update the output value
m_byOA = byData;
// send it to the output function
if ( m_byDDRA )
PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
}
// write DDR register
else
{
if ( m_byDDRA != byData )
{
m_byDDRA = byData;
// send it to the output function
if ( m_byDDRA )
PIA_W_CALLBACK( m_stOutA, m_byOA & m_byDDRA );
}
}
break;
/******************* port B output/DDR write *******************/
case PIA_DDRB:
// write output register
if ( OUTPUT_SELECTED( m_byCTLB ) )
{
// update the output value
m_byOB = byData;
// send it to the output function
if ( m_byDDRB )
PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );
// CB2 is configured as output and in write strobe mode
if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) )
{
// this will cause a transition low; call the output function if we're currently high
if ( m_byOCB2 )
PIA_W_CALLBACK( m_stOutCB2, 0 );
m_byOCB2 = 0;
// if the CB2 strobe is cleared by the E, reset it right away
if ( STROBE_E_RESET( m_byCTLB ) )
{
PIA_W_CALLBACK( m_stOutCB2, 1 );
m_byOCB2 = 1;
}
}
}
// write DDR register
else
{
if ( m_byDDRB != byData )
{
m_byDDRB = byData;
// send it to the output function
if ( m_byDDRB )
PIA_W_CALLBACK( m_stOutB, m_byOB & m_byDDRB );
}
}
break;
/******************* port A control write *******************/
case PIA_CTLA:
// Bit 7 and 6 read only
byData &= 0x3f;
// CA2 is configured as output and in set/reset mode
if ( C2_OUTPUT( byData ) )
{
// determine the new value
int temp = SET_C2( byData ) ? 1 : 0;
// if this creates a transition, call the CA2 output function
if ( m_byOCA2 ^ temp)
PIA_W_CALLBACK( m_stOutCA2, temp );
// set the new value
m_byOCA2 = temp;
}
// update the control register
m_byCTLA = ( m_byCTLA & ~0x3F ) | byData;
// update externals
UpdateInterrupts();
break;
/******************* port B control write *******************/
case PIA_CTLB:
/* Bit 7 and 6 read only - PD 16/01/00 */
byData &= 0x3f;
// CB2 is configured as output and in set/reset mode
if ( C2_OUTPUT( byData ) )
{
// determine the new value
int temp = SET_C2( byData ) ? 1 : 0;
// if this creates a transition, call the CA2 output function
if ( m_byOCB2 ^ temp)
PIA_W_CALLBACK( m_stOutCB2, temp );
// set the new value
m_byOCB2 = temp;
}
// update the control register
m_byCTLB = ( m_byCTLB & ~0x3F ) | byData;
// update externals
UpdateInterrupts();
break;
}
mc6821[dnr].crb = byte;
}
void C6821::Reset()
{
m_byIA = 0;
m_byCA1 = 0;
m_byICA2 = 0;
m_byOA = 0;
m_byOCA2 = 0;
m_byDDRA = 0;
m_byCTLA = 0;
m_byIRQAState = 0;
/*-----------------------------------------------------------------------*/
/* MC6821 signals. */
m_byIB = 0;
m_byCB1 = 0;
m_byICB2 = 0;
m_byOB = 0;
m_byOCB2 = 0;
m_byDDRB = 0;
m_byCTLB = 0;
m_byIRQBState = 0;
void C6821::mc6821_set_signal(/*drive_context_t *drive_context,*/ int line)
{
unsigned int dnr = 0;
// dnr = drive_context->mynumber;
switch (line) {
case MC6821_SIG_CA1:
mc6821[dnr].cra = (BYTE)(mc6821[dnr].cra | 0x80);
break;
case MC6821_SIG_CA2:
mc6821[dnr].cra = (BYTE)(mc6821[dnr].cra | 0x40);
break;
case MC6821_SIG_CB1:
mc6821[dnr].crb = (BYTE)(mc6821[dnr].crb | 0x80);
break;
case MC6821_SIG_CB2:
mc6821[dnr].crb = (BYTE)(mc6821[dnr].crb | 0x40);
break;
}
}
void C6821::UpdateInterrupts()
/*-----------------------------------------------------------------------*/
/* MC6821 register read/write access. */
void C6821::mc6821_store_internal(WORD addr, BYTE byte, unsigned int dnr)
{
BYTE byNewState;
#ifdef MC_DEBUG
log_debug("MC WRITE ADDR: %i DATA:%02x CLK:%i",
addr, byte, drive_clk[dnr]);
#endif
// start with IRQ A
byNewState = 0;
if ( ( IRQ1( m_byCTLA ) && IRQ1_ENABLED( m_byCTLA ) ) ||
( IRQ2( m_byCTLA ) && IRQ2_ENABLED( m_byCTLA ) ) )
byNewState = 1;
if ( byNewState != m_byIRQAState )
{
m_byIRQAState = byNewState;
PIA_W_CALLBACK( m_stOutIRQA, m_byIRQAState );
}
/* then do IRQ B */
byNewState = 0;
if ( ( IRQ1( m_byCTLB ) && IRQ1_ENABLED( m_byCTLB ) ) ||
( IRQ2( m_byCTLB ) && IRQ2_ENABLED( m_byCTLB ) ) )
byNewState = 1;
if ( byNewState != m_byIRQBState )
{
m_byIRQBState = byNewState;
PIA_W_CALLBACK( m_stOutIRQB, m_byIRQBState );
}
switch (addr) {
case 0: // PIA_DDRA
if (mc6821[dnr].cra & 0x04)
mc6821_write_pra(byte, dnr);
else
mc6821_write_ddra(byte, dnr);
break;
case 1: // PIA_CTLA
mc6821_write_cra(byte, dnr);
break;
case 2: // PIA_DDRB
if (mc6821[dnr].crb & 0x04)
mc6821_write_prb(byte, dnr);
else
mc6821_write_ddrb(byte, dnr);
break;
case 3: // PIA_CTLB
mc6821_write_crb(byte, dnr);
break;
}
}
void C6821::SetCA1(BYTE byData)
BYTE C6821::mc6821_read_internal(WORD addr, unsigned int dnr)
{
byData = byData ? 1 : 0;
BYTE tmp = 0;
// the new state has caused a transition
if ( m_byCA1 ^ byData )
{
// handle the active transition
if ( ( byData && C1_LOW_TO_HIGH( m_byCTLA ) ) ||
( !byData && C1_HIGH_TO_LOW( m_byCTLA ) ) )
{
// mark the IRQ
SET_IRQ1(m_byCTLA);
switch (addr) {
case 0: // PIA_DDRA
if (mc6821[dnr].cra & 0x04)
tmp = mc6821_read_pra(dnr);
else
tmp = mc6821[dnr].ddra;
break;
case 1: // PIA_CTLA
tmp = mc6821[dnr].cra;
break;
case 2: // PIA_DDRB
if (mc6821[dnr].crb & 0x04)
tmp = mc6821_read_prb(dnr);
else
tmp = mc6821[dnr].ddrb;
break;
case 3: // PIA_CTLB
tmp = mc6821[dnr].crb;
break;
}
// update externals
UpdateInterrupts();
#ifdef MC_DEBUG
log_debug("MC READ ADDR: %i DATA:%02x CLK:%i",
addr, tmp, drive_clk[dnr]);
#endif
// CA2 is configured as output and in read strobe mode and cleared by a CA1 transition
if ( C2_OUTPUT( m_byCTLA ) && C2_STROBE_MODE( m_byCTLA ) && STROBE_C1_RESET( m_byCTLA ) )
{
// call the CA2 output function
if ( !m_byOCA2 )
PIA_W_CALLBACK( m_stOutCA2, 1 );
// clear CA2
m_byOCA2 = 1;
}
}
}
// set the new value for CA1
m_byCA1 = byData;
return tmp;
}
void C6821::SetCA2(BYTE byData)
void C6821::mc6821_reset_internal(unsigned int dnr)
{
byData = byData ? 1 : 0;
// CA2 is in input mode
if ( C2_INPUT( m_byCTLA ) )
{
// the new state has caused a transition
if ( m_byICA2 ^ byData )
{
// handle the active transition
if ( ( byData && C2_LOW_TO_HIGH( m_byCTLA ) ) ||
( !byData && C2_HIGH_TO_LOW( m_byCTLA ) ) )
{
// mark the IRQ
SET_IRQ2( m_byCTLA );
// update externals
UpdateInterrupts();
}
}
}
// set the new value for CA2
m_byICA2 = byData;
mc6821[dnr].pra = 0;
mc6821[dnr].ddra = 0;
mc6821[dnr].cra = 0;
mc6821[dnr].prb = 0;
mc6821[dnr].ddrb = 0;
mc6821[dnr].crb = 0;
}
void C6821::SetCB1(BYTE byData)
/*-----------------------------------------------------------------------*/
//static void REGPARM3 mc6821_store(drive_context_t *drv, WORD addr, BYTE byte)
//{
// mc6821_store_internal((WORD)(addr & 3), byte, drv->mynumber);
//}
//
//static BYTE REGPARM2 mc6821_read(drive_context_t *drv, WORD addr)
//{
// return mc6821_read_internal((WORD)(addr & 3), drv->mynumber);
//}
/*-----------------------------------------------------------------------*/
/* MC6821 external interface. */
/* Functions using drive context. */
void C6821::mc6821_init(/*drive_context_t *drv*/)
{
byData = byData ? 1 : 0;
// the new state has caused a transition
if ( m_byCB1 ^ byData )
{
// handle the active transition
if ( ( byData && C1_LOW_TO_HIGH( m_byCTLB ) ) ||
( !byData && C1_HIGH_TO_LOW( m_byCTLB ) ) )
{
// mark the IRQ
SET_IRQ1( m_byCTLB );
// update externals
UpdateInterrupts();
// CB2 is configured as output and in read strobe mode and cleared by a CA1 transition
if ( C2_OUTPUT( m_byCTLB ) && C2_STROBE_MODE( m_byCTLB ) && STROBE_C1_RESET( m_byCTLB ) )
{
// the IRQ1 flag must have also been cleared
if ( !IRQ1( m_byCTLB ) )
{
// call the CB2 output function
if ( !m_byOCB2 )
PIA_W_CALLBACK( m_stOutCB2, 1 );
// clear CB2
m_byOCB2 = 1;
}
}
}
}
// set the new value for CA1
m_byCB1 = byData;
//mc6821[drv->mynumber].drive = drv->drive;
}
void C6821::SetCB2(BYTE byData)
void C6821::mc6821_reset(/*drive_context_t *drv*/)
{
byData = byData ? 1 : 0;
// CA2 is in input mode
if ( C2_INPUT( m_byCTLB ) )
{
// the new state has caused a transition
if ( m_byICB2 ^ byData )
{
// handle the active transition
if ( ( byData && C2_LOW_TO_HIGH( m_byCTLB ) ) ||
( !byData && C2_HIGH_TO_LOW( m_byCTLB ) ) )
{
// mark the IRQ
SET_IRQ2( m_byCTLB );
// update externals
UpdateInterrupts();
}
}
}
// set the new value for CA2
m_byICB2 = byData;
mc6821_reset_internal();
}
void C6821::SetPA(BYTE byData)
{
m_byIA = byData;
}
void C6821::SetPB(BYTE byData)
{
m_byIB = byData;
}
BYTE C6821::GetPA()
{
return m_byOA & m_byDDRA;
}
BYTE C6821::GetPB()
{
return m_byOB & m_byDDRB;
}
//void mc6821_mem_init(struct drive_context_s *drv, unsigned int type)
//{
// drivecpud_context_t *cpud;
//
// cpud = drv->cpud;
//
// /* Setup parallel cable */
// if (type == DRIVE_TYPE_1541 || type == DRIVE_TYPE_1541II
// || type == DRIVE_TYPE_1570 || type == DRIVE_TYPE_1571
// || type == DRIVE_TYPE_1571CR) {
// if (drv->drive->parallel_cable == DRIVE_PC_DD3) {
// drivemem_set_func(cpud, 0x50, 0x60, mc6821_read, mc6821_store);
// }
// }
//}

View File

@ -1,68 +1,125 @@
// Motorola MC6821 PIA
/*
* mc6821.h - MC6821 emulation for the 1571 disk drives with DD3.
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
typedef void (*mem_write_handler) (void* objFrom, void* objTo, int nAddr, BYTE byData);
typedef void (*mem_write_handler) (void* objTo, BYTE byData);
typedef struct _STWriteHandler
typedef struct
{
void* objTo;
mem_write_handler func;
} STWriteHandler;
//
#define PIA_DDRA 0
#define PIA_CTLA 1
#define PIA_DDRB 2
#define PIA_CTLB 3
class C6821
{
public:
C6821();
virtual ~C6821();
C6821()
{
mc6821_reset();
m_stOutA.objTo = NULL;
m_stOutA.func = NULL;
m_stOutB.objTo = NULL;
m_stOutB.func = NULL;
};
BYTE GetPB();
BYTE GetPA();
void SetPB(BYTE byData);
void SetPA(BYTE byData);
void SetCA1( BYTE byData );
void SetCA2( BYTE byData );
void SetCB1( BYTE byData );
void SetCB2( BYTE byData );
void Reset();
BYTE Read( BYTE byRS );
void Write( BYTE byRS, BYTE byData );
~C6821() {};
void UpdateInterrupts();
// AppleWin:TC
void SetPA(BYTE byData) { m_byIA = byData; }
void SetPB(BYTE byData) { m_byIB = byData; }
void Reset() { mc6821_reset(); }
BYTE Read( BYTE byRS ) { return mc6821_read_internal(byRS); }
void Write( BYTE byRS, BYTE byData ) { mc6821_store_internal(byRS, byData); }
void SetListenerA( void *objTo, mem_write_handler func );
void SetListenerB( void *objTo, mem_write_handler func );
void SetListenerCA2( void *objTo, mem_write_handler func );
void SetListenerCB2( void *objTo, mem_write_handler func );
void SetListenerA(void *objTo, mem_write_handler func)
{
m_stOutA.objTo = objTo;
m_stOutA.func = func;
}
protected:
BYTE m_byIA;
BYTE m_byCA1;
BYTE m_byICA2;
BYTE m_byOA;
BYTE m_byOCA2;
BYTE m_byDDRA;
BYTE m_byCTLA;
BYTE m_byIRQAState;
void SetListenerB(void *objTo, mem_write_handler func)
{
m_stOutB.objTo = objTo;
m_stOutB.func = func;
}
// AppleWin:TC END
BYTE m_byIB;
BYTE m_byCB1;
BYTE m_byICB2;
BYTE m_byOB;
BYTE m_byOCB2;
BYTE m_byDDRB;
BYTE m_byCTLB;
BYTE m_byIRQBState;
private:
/* Signal values (for signaling edges on the control lines) */
#define MC6821_SIG_CA1 0
#define MC6821_SIG_CA2 1
#define MC6821_SIG_CB1 2
#define MC6821_SIG_CB2 3
//struct drive_s;
struct mc6821_s {
/* MC6821 register. */
BYTE pra;
BYTE ddra;
BYTE cra;
BYTE prb;
BYTE ddrb;
BYTE crb;
/* Drive structure */
// struct drive_s *drive;
};
typedef struct mc6821_s mc6821_t;
//struct drive_context_s;
void mc6821_init(/*struct drive_context_s *drv*/);
void mc6821_reset(/*struct drive_context_s *drv*/);
//extern void mc6821_mem_init(struct drive_context_s *drv, unsigned int type);
void mc6821_set_signal(/*struct drive_context_s *drive_context,*/ int line);
private:
// AppleWin:TC
void mc6821_write_pra(BYTE byte, unsigned int dnr=0);
void mc6821_write_ddra(BYTE byte, unsigned int dnr=0);
BYTE mc6821_read_pra(unsigned int dnr=0);
void mc6821_write_prb(BYTE byte, unsigned int dnr=0);
void mc6821_write_ddrb(BYTE byte, unsigned int dnr=0);
BYTE mc6821_read_prb(unsigned int dnr=0);
void mc6821_write_cra(BYTE byte, unsigned int dnr=0);
void mc6821_write_crb(BYTE byte, unsigned int dnr=0);
void mc6821_store_internal(WORD addr, BYTE byte, unsigned int dnr=0);
BYTE mc6821_read_internal(WORD addr, unsigned int dnr=0);
void mc6821_reset_internal(unsigned int dnr=0);
// AppleWin:TC END
private:
// AppleWin:TC
STWriteHandler m_stOutA;
STWriteHandler m_stOutB;
STWriteHandler m_stOutCA2;
STWriteHandler m_stOutCB2;
STWriteHandler m_stOutIRQA;
STWriteHandler m_stOutIRQB;
BYTE m_byIA; // InputA from 285
BYTE m_byIB; // InputB from 285
// AppleWin:TC END
/* mc6821 structure. */
#define DRIVE_NUM 1 // AppleWin:TC
mc6821_t mc6821[DRIVE_NUM];
};

File diff suppressed because it is too large Load Diff

View File

@ -3,13 +3,83 @@
#define MAX_8910 4
void _AYWriteReg(int n, int r, int v);
void AY8910_write_ym(int chip, int addr, int data);
//-------------------------------------
// MAME interface
void _AYWriteReg(int chip, int r, int v);
//void AY8910_write_ym(int chip, int addr, int data);
void AY8910_reset(int chip);
void AY8910Update(int chip,INT16 **buffer,int length);
void AY8910Update(int chip, INT16** buffer, int nNumSamples);
void AY8910_InitAll(int nClock, int nSampleRate);
void AY8910_InitClock(int nClock);
BYTE* AY8910_GetRegsPtr(UINT nAyNum);
BYTE* AY8910_GetRegsPtr(UINT uChip);
void AY8910UpdateSetCycles();
//-------------------------------------
// FUSE stuff
typedef ULONG libspectrum_dword;
typedef UCHAR libspectrum_byte;
typedef SHORT libspectrum_signed_word;
/* max. number of sub-frame AY port writes allowed;
* given the number of port writes theoretically possible in a
* 50th I think this should be plenty.
*/
#define AY_CHANGE_MAX 8000
class CAY8910
{
public:
CAY8910();
virtual ~CAY8910() {};
void sound_ay_init( void );
void sound_init( const char *device );
void sound_ay_write( int reg, int val, libspectrum_dword now );
void sound_ay_reset( void );
void sound_frame( void );
BYTE* GetAYRegsPtr( void ) { return &sound_ay_registers[0]; }
static void SetCLK( double CLK ) { m_fCurrentCLK_AY8910 = CLK; }
private:
void sound_end( void );
void sound_ay_overlay( void );
private:
/* foo_subcycles are fixed-point with low 16 bits as fractional part.
* The other bits count as the chip does.
*/
unsigned int ay_tone_tick[3], ay_tone_high[3], ay_noise_tick;
unsigned int ay_tone_subcycles, ay_env_subcycles;
unsigned int ay_env_internal_tick, ay_env_tick;
unsigned int ay_tick_incr;
unsigned int ay_tone_period[3], ay_noise_period, ay_env_period;
//static int beeper_last_subpos[2] = { 0, 0 };
/* Local copy of the AY registers */
libspectrum_byte sound_ay_registers[16];
struct ay_change_tag
{
libspectrum_dword tstates;
unsigned short ofs;
unsigned char reg, val;
};
struct ay_change_tag ay_change[ AY_CHANGE_MAX ];
int ay_change_count;
// statics from sound_ay_overlay()
int rng;
int noise_toggle;
int env_first, env_rev, env_counter;
// Vars shared between all AY's
static double m_fCurrentCLK_AY8910;
};
#endif

View File

@ -30,7 +30,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#pragma hdrstop
#include <objbase.h>
#include "MouseInterface.h"
#include "z80\z80.h"
char VERSIONSTRING[16] = "xx.yy.zz.ww";
@ -376,9 +375,9 @@ void LoadConfiguration ()
{
DWORD dwComputerType;
if (LOAD(TEXT(REGVALUE_APPLE2_TYPE),&dwComputerType))
if (REGLOAD(TEXT(REGVALUE_APPLE2_TYPE),&dwComputerType))
{
LOAD(TEXT(REGVALUE_CLONETYPE),&g_uCloneType);
REGLOAD(TEXT(REGVALUE_CLONETYPE),&g_uCloneType);
if ((dwComputerType >= A2TYPE_MAX) || (dwComputerType >= A2TYPE_UNDEFINED && dwComputerType < A2TYPE_CLONE))
dwComputerType = A2TYPE_APPLE2EEHANCED;
@ -399,7 +398,7 @@ void LoadConfiguration ()
}
else // Support older AppleWin registry entries
{
LOAD(TEXT("Computer Emulation"),&dwComputerType);
REGLOAD(TEXT("Computer Emulation"),&dwComputerType);
switch (dwComputerType)
{
// NB. No A2TYPE_APPLE2E (this is correct)
@ -422,19 +421,19 @@ void LoadConfiguration ()
}
LOAD(TEXT("Joystick 0 Emulation"),&joytype[0]);
LOAD(TEXT("Joystick 1 Emulation"),&joytype[1]);
LOAD(TEXT("Sound Emulation") ,&soundtype);
REGLOAD(TEXT("Joystick 0 Emulation"),&joytype[0]);
REGLOAD(TEXT("Joystick 1 Emulation"),&joytype[1]);
REGLOAD(TEXT("Sound Emulation") ,&soundtype);
DWORD dwSerialPort;
if (LOAD(TEXT("Serial Port"),&dwSerialPort))
if (REGLOAD(TEXT("Serial Port"),&dwSerialPort))
sg_SSC.SetSerialPort(dwSerialPort);
LOAD(TEXT("Emulation Speed") ,&g_dwSpeed);
LOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);
LOAD(TEXT("Video Emulation") ,&videotype);
LOAD(TEXT("Monochrome Color") ,&monochrome);
LOAD(TEXT("Uthernet Active") ,(DWORD *)&tfe_enabled);
REGLOAD(TEXT("Emulation Speed") ,&g_dwSpeed);
REGLOAD(TEXT("Enhance Disk Speed"),(DWORD *)&enhancedisk);
REGLOAD(TEXT("Video Emulation") ,&videotype);
REGLOAD(TEXT("Monochrome Color") ,&monochrome);
REGLOAD(TEXT("Uthernet Active") ,(DWORD *)&tfe_enabled);
SetCurrentCLK6502();
@ -442,36 +441,36 @@ void LoadConfiguration ()
DWORD dwTmp;
if(LOAD(TEXT(REGVALUE_THE_FREEZES_F8_ROM), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_THE_FREEZES_F8_ROM), &dwTmp))
g_uTheFreezesF8Rom = dwTmp;
if(LOAD(TEXT(REGVALUE_SPKR_VOLUME), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_SPKR_VOLUME), &dwTmp))
SpkrSetVolume(dwTmp, PSP_GetVolumeMax());
if(LOAD(TEXT(REGVALUE_MB_VOLUME), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_MB_VOLUME), &dwTmp))
MB_SetVolume(dwTmp, PSP_GetVolumeMax());
if(LOAD(TEXT(REGVALUE_SOUNDCARD_TYPE), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_SOUNDCARD_TYPE), &dwTmp))
MB_SetSoundcardType((eSOUNDCARDTYPE)dwTmp);
if(LOAD(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), &dwTmp))
g_bSaveStateOnExit = dwTmp ? true : false;
if(LOAD(TEXT(REGVALUE_DUMP_TO_PRINTER), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_DUMP_TO_PRINTER), &dwTmp))
g_bDumpToPrinter = dwTmp ? true : false;
if(LOAD(TEXT(REGVALUE_CONVERT_ENCODING), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_CONVERT_ENCODING), &dwTmp))
g_bConvertEncoding = dwTmp ? true : false;
if(LOAD(TEXT(REGVALUE_FILTER_UNPRINTABLE), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_FILTER_UNPRINTABLE), &dwTmp))
g_bFilterUnprintable = dwTmp ? true : false;
if(LOAD(TEXT(REGVALUE_PRINTER_APPEND), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_PRINTER_APPEND), &dwTmp))
g_bPrinterAppend = dwTmp ? true : false;
if(LOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp))
HD_SetEnabled(dwTmp ? true : false);
char szHDFilename[MAX_PATH] = {0};
@ -480,23 +479,23 @@ void LoadConfiguration ()
if(RegLoadString(TEXT(REG_CONFIG), TEXT(REGVALUE_HDD_IMAGE2), 1, szHDFilename, sizeof(szHDFilename)))
HD_InsertDisk2(1, szHDFilename);
if(LOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp))
JoySetTrim((short)dwTmp, true);
if(LOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp))
JoySetTrim((short)dwTmp, false);
if(LOAD(TEXT(REGVALUE_SCROLLLOCK_TOGGLE), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_SCROLLLOCK_TOGGLE), &dwTmp))
g_uScrollLockToggle = dwTmp;
if(LOAD(TEXT(REGVALUE_MOUSE_IN_SLOT4), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_MOUSE_IN_SLOT4), &dwTmp))
g_uMouseInSlot4 = dwTmp;
if(LOAD(TEXT(REGVALUE_MOUSE_CROSSHAIR), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_MOUSE_CROSSHAIR), &dwTmp))
g_uMouseShowCrosshair = dwTmp;
if(LOAD(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW), &dwTmp))
g_uMouseRestrictToWindow = dwTmp;
#ifdef SUPPORT_CPM
if(LOAD(TEXT(REGVALUE_Z80_IN_SLOT5), &dwTmp))
if(REGLOAD(TEXT(REGVALUE_Z80_IN_SLOT5), &dwTmp))
g_uZ80InSlot5 = dwTmp;
if (g_uZ80InSlot5)
@ -527,7 +526,7 @@ void LoadConfiguration ()
Disk_LoadLastDiskImage(1);
dwTmp = 10;
LOAD(TEXT(REGVALUE_PRINTER_IDLE_LIMIT), &dwTmp);
REGLOAD(TEXT(REGVALUE_PRINTER_IDLE_LIMIT), &dwTmp);
Printer_SetIdleLimit(dwTmp);
char szUthernetInt[MAX_PATH] = {0};

View File

@ -89,9 +89,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "MouseInterface.h"
#ifdef SUPPORT_CPM
#include "z80\z80.h"
#include "z80\z80emu.h"
#include "z80\z80io.h"
#include "z80emu.h"
#include "Z80VICE\z80.h"
#include "Z80VICE\z80mem.h"
#endif
#define AF_SIGN 0x80
@ -932,7 +932,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles)
#ifdef SUPPORT_CPM
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = InternalZ80Execute(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
#endif
@ -1240,7 +1240,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles)
#ifdef SUPPORT_CPM
if (g_ActiveCPU == CPU_Z80)
{
const UINT uZ80Cycles = InternalZ80Execute(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles)
}
else
#endif
@ -1630,9 +1630,8 @@ void CpuInitialize ()
CpuNmiReset();
#ifdef SUPPORT_CPM
// Z80
InitTables();
Z80_Reset();
z80mem_initialize();
z80_reset();
#endif
}
@ -1738,7 +1737,7 @@ void CpuReset()
#ifdef SUPPORT_CPM
g_ActiveCPU = CPU_6502;
Z80_Reset();
z80_reset();
#endif
}

View File

@ -66,8 +66,8 @@ enum AppMode_e
#define TITLE_PAUSED TEXT(" Paused ")
#define TITLE_STEPPING TEXT("Stepping")
#define LOAD(a,b) RegLoadValue(TEXT("Configuration"),a,1,b)
#define SAVE(a,b) RegSaveValue(TEXT("Configuration"),a,1,b)
#define REGLOAD(a,b) RegLoadValue(TEXT("Configuration"),a,1,b)
#define REGSAVE(a,b) RegSaveValue(TEXT("Configuration"),a,1,b)
// Configuration
#define REG_CONFIG "Configuration"

View File

@ -0,0 +1,87 @@
/*
* 6510core.h - Core definitions for the MOS 6510 CPU emulation.
*
* Written by
* Ettore Perazzoli <ettore@comm2000.it>
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _6510CORE_H
#define _6510CORE_H
/* Masks to extract information. */
#define OPINFO_DELAYS_INTERRUPT_MSK (1 << 8)
#define OPINFO_DISABLES_IRQ_MSK (1 << 9)
#define OPINFO_ENABLES_IRQ_MSK (1 << 10)
/* Return nonzero if `opinfo' causes a 1-cycle interrupt delay. */
#define OPINFO_DELAYS_INTERRUPT(opinfo) \
((opinfo) & OPINFO_DELAYS_INTERRUPT_MSK)
/* Return nonzero if `opinfo' has changed the I flag from 0 to 1, so that an
IRQ that happened 2 or more cycles before the end of the opcode should be
allowed. */
#define OPINFO_DISABLES_IRQ(opinfo) \
((opinfo) & OPINFO_DISABLES_IRQ_MSK)
/* Return nonzero if `opinfo' has changed the I flag from 1 to 0, so that an
IRQ that happened 2 or more cycles before the end of the opcode should not
be allowed. */
#define OPINFO_ENABLES_IRQ(opinfo) \
((opinfo) & OPINFO_ENABLES_IRQ_MSK)
/* Set the information for `opinfo'. `number' is the opcode number,
`delays_interrupt' must be non-zero if it causes a 1-cycle interrupt
delay, `disables_interrupts' must be non-zero if it disabled IRQs. */
#define OPINFO_SET(opinfo, \
number, delays_interrupt, disables_irq, enables_irq) \
((opinfo) = ((number) \
| ((delays_interrupt) ? OPINFO_DELAYS_INTERRUPT_MSK : 0) \
| ((disables_irq) ? OPINFO_DISABLES_IRQ_MSK : 0) \
| ((enables_irq) ? OPINFO_ENABLES_IRQ_MSK : 0)))
/* Set whether the opcode causes the 1-cycle interrupt delay according to
`delay'. */
#define OPINFO_SET_DELAYS_INTERRUPT(opinfo, delay) \
do { \
if ((delay)) \
(opinfo) |= OPINFO_DELAYS_INTERRUPT_MSK; \
} while (0)
/* Set whether the opcode disables previously enabled IRQs according to
`disable'. */
#define OPINFO_SET_DISABLES_IRQ(opinfo, disable) \
do { \
if ((disable)) \
(opinfo) |= OPINFO_DISABLES_IRQ_MSK; \
} while (0)
/* Set whether the opcode enables previously disabled IRQs according to
`enable'. */
#define OPINFO_SET_ENABLES_IRQ(opinfo, enable) \
do { \
if ((enable)) \
(opinfo) |= OPINFO_ENABLES_IRQ_MSK; \
} while (0)
#endif

View File

@ -0,0 +1,191 @@
/*
* alarm.h - Alarm handling.
*
* Written by
* Ettore Perazzoli <ettore@comm2000.it>
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _ALARM_H
#define _ALARM_H
#include "..\CommonVICE\types.h"
#define ALARM_CONTEXT_MAX_PENDING_ALARMS 0x100
typedef void (*alarm_callback_t)(CLOCK offset, void *data);
/* An alarm. */
struct alarm_s {
/* Descriptive name of the alarm. */
char *name;
/* Alarm context this alarm is in. */
struct alarm_context_s *context;
/* Callback to be called when the alarm is dispatched. */
alarm_callback_t callback;
/* Index into the pending alarm list. If < 0, the alarm is not
pending. */
int pending_idx;
/* Call data */
void *data;
/* Link to the next and previous alarms in the list. */
struct alarm_s *next, *prev;
};
typedef struct alarm_s alarm_t;
struct pending_alarms_s {
/* The alarm. */
struct alarm_s *alarm;
/* Clock tick at which this alarm should be activated. */
CLOCK clk;
};
typedef struct pending_alarms_s pending_alarms_t;
/* An alarm context. */
struct alarm_context_s {
/* Descriptive name of the alarm context. */
char *name;
/* Alarm list. */
struct alarm_s *alarms;
/* Pending alarm array. Statically allocated because it's slightly
faster this way. */
pending_alarms_t pending_alarms[ALARM_CONTEXT_MAX_PENDING_ALARMS];
unsigned int num_pending_alarms;
/* Clock tick for the next pending alarm. */
CLOCK next_pending_alarm_clk;
/* Pending alarm number. */
int next_pending_alarm_idx;
};
typedef struct alarm_context_s alarm_context_t;
/* ------------------------------------------------------------------------ */
extern alarm_context_t *alarm_context_new(const char *name);
extern void alarm_context_init(alarm_context_t *context, const char *name);
extern void alarm_context_destroy(alarm_context_t *context);
extern void alarm_context_time_warp(alarm_context_t *context, CLOCK warp_amount,
int warp_direction);
extern alarm_t *alarm_new(alarm_context_t *context, const char *name,
alarm_callback_t callback, void *data);
extern void alarm_destroy(alarm_t *alarm);
extern void alarm_unset(alarm_t *alarm);
extern void alarm_log_too_many_alarms(void);
/* ------------------------------------------------------------------------- */
#if 1 //TC
/* Inline functions. */
/*inline*/ static CLOCK alarm_context_next_pending_clk(alarm_context_t *context)
{
return context->next_pending_alarm_clk;
}
/*inline*/ static void alarm_context_update_next_pending(alarm_context_t *context)
{
CLOCK next_pending_alarm_clk = (CLOCK)~0L;
unsigned int next_pending_alarm_idx;
unsigned int i;
next_pending_alarm_idx = context->next_pending_alarm_idx;
for (i = 0; i < context->num_pending_alarms; i++) {
CLOCK pending_clk = context->pending_alarms[i].clk;
if (pending_clk <= next_pending_alarm_clk) {
next_pending_alarm_clk = pending_clk;
next_pending_alarm_idx = i;
}
}
context->next_pending_alarm_clk = next_pending_alarm_clk;
context->next_pending_alarm_idx = next_pending_alarm_idx;
}
/*inline*/ static void alarm_context_dispatch(alarm_context_t *context,
CLOCK cpu_clk)
{
CLOCK offset;
unsigned int idx;
alarm_t *alarm;
offset = (CLOCK)(cpu_clk - context->next_pending_alarm_clk);
idx = context->next_pending_alarm_idx;
alarm = context->pending_alarms[idx].alarm;
(alarm->callback)(offset, alarm->data);
}
/*inline*/ static void alarm_set(alarm_t *alarm, CLOCK cpu_clk)
{
alarm_context_t *context;
int idx;
context = alarm->context;
idx = alarm->pending_idx;
if (idx < 0) {
unsigned int new_idx;
/* Not pending yet: add. */
new_idx = context->num_pending_alarms;
if (new_idx >= ALARM_CONTEXT_MAX_PENDING_ALARMS) {
alarm_log_too_many_alarms();
return;
}
context->pending_alarms[new_idx].alarm = alarm;
context->pending_alarms[new_idx].clk = cpu_clk;
context->num_pending_alarms++;
if (cpu_clk < context->next_pending_alarm_clk) {
context->next_pending_alarm_clk = cpu_clk;
context->next_pending_alarm_idx = new_idx;
}
alarm->pending_idx = new_idx;
} else {
/* Already pending: modify. */
context->pending_alarms[idx].clk = cpu_clk;
if (context->next_pending_alarm_clk > cpu_clk
|| idx == context->next_pending_alarm_idx)
alarm_context_update_next_pending(context);
}
}
#endif // TC
#endif

View File

@ -0,0 +1,314 @@
/*
* interrupt.h - Implementation of 6510 interrupts and alarms.
*
* Written by
* Ettore Perazzoli <ettore@comm2000.it>
* André Fachat <fachat@physik.tu-chemnitz.de>
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _INTERRUPT_H
#define _INTERRUPT_H
#include <stdio.h>
#include "..\CommonVICE\types.h"
/* Define the number of cycles needed by the CPU to detect the NMI or IRQ. */
#define INTERRUPT_DELAY 2
#define INTRRUPT_MAX_DMA_PER_OPCODE (7+10000)
/* These are the available types of interrupt lines. */
enum cpu_int {
IK_NONE = 0,
IK_NMI = 1 << 0,
IK_IRQ = 1 << 1,
IK_RESET = 1 << 2,
IK_TRAP = 1 << 3,
IK_MONITOR = 1 << 4,
IK_DMA = 1 << 5,
IK_IRQPEND = 1 << 6
};
struct interrupt_cpu_status_s {
/* Number of interrupt lines. */
unsigned int num_ints;
/* Define, for each interrupt source, whether it has a pending interrupt
(IK_IRQ, IK_NMI, IK_RESET and IK_TRAP) or not (IK_NONE). */
unsigned int *pending_int;
/* Name for each interrupt source */
char **int_name;
/* Number of active IRQ lines. */
int nirq;
/* Tick when the IRQ was triggered. */
CLOCK irq_clk;
/* Number of active NMI lines. */
int nnmi;
/* Tick when the NMI was triggered. */
CLOCK nmi_clk;
/* If an opcode is intercepted by a DMA, save the number of cycles
left at the start of this particular DMA (needed by *_set_irq() to
calculate irq_clk). */
unsigned int num_dma_per_opcode;
unsigned int num_cycles_left[INTRRUPT_MAX_DMA_PER_OPCODE];
CLOCK dma_start_clk[INTRRUPT_MAX_DMA_PER_OPCODE];
/* If 1, do a RESET. */
int reset;
/* If 1, call the trapping function. */
int trap;
/* Debugging function. */
void (*trap_func)(WORD, void *data);
/* Data to pass to the debugging function when called. */
void *trap_data;
/* Pointer to the last executed opcode information. */
unsigned int *last_opcode_info_ptr;
/* Number of cycles we have stolen to the processor last time. */
int num_last_stolen_cycles;
/* Clock tick at which these cycles have been stolen. */
CLOCK last_stolen_cycles_clk;
unsigned int global_pending_int;
void (*nmi_trap_func)(void);
void (*reset_trap_func)(void);
/* flag for interrupt_restore to handle CPU snapshots before 1.1 */
int needs_global_restore;
};
typedef struct interrupt_cpu_status_s interrupt_cpu_status_t;
/* ------------------------------------------------------------------------- */
extern void interrupt_log_wrong_nirq(void);
extern void interrupt_log_wrong_nnmi(void);
extern void interrupt_trigger_dma(interrupt_cpu_status_t *cs, CLOCK cpu_clk);
extern void interrupt_ack_dma(interrupt_cpu_status_t *cs);
extern void interrupt_fixup_int_clk(interrupt_cpu_status_t *cs, CLOCK cpu_clk,
CLOCK *int_clk);
#if 0 // TC
/* Set the IRQ line state. */
inline static void interrupt_set_irq(interrupt_cpu_status_t *cs,
unsigned int int_num,
int value, CLOCK cpu_clk)
{
if (cs == NULL || int_num >= cs->num_ints)
return;
if (value) { /* Trigger the IRQ. */
if (!(cs->pending_int[int_num] & IK_IRQ)) {
cs->nirq++;
cs->global_pending_int = (cs->global_pending_int
| (unsigned int)(IK_IRQ | IK_IRQPEND));
cs->pending_int[int_num] = (cs->pending_int[int_num]
| (unsigned int)IK_IRQ);
/* This makes sure that IRQ delay is correctly emulated when
cycles are stolen from the CPU. */
/*log_debug("ICLK %i", cpu_clk);*/
if (cs->last_stolen_cycles_clk <= cpu_clk)
cs->irq_clk = cpu_clk;
else
interrupt_fixup_int_clk(cs, cpu_clk, &(cs->irq_clk));
}
} else { /* Remove the IRQ condition. */
if (cs->pending_int[int_num] & IK_IRQ) {
if (cs->nirq > 0) {
cs->pending_int[int_num] =
(cs->pending_int[int_num] & (unsigned int)~IK_IRQ);
if (--cs->nirq == 0)
cs->global_pending_int =
(cs->global_pending_int & (unsigned int)~IK_IRQ);
} else {
interrupt_log_wrong_nirq();
}
}
}
}
/* Set the NMI line state. */
inline static void interrupt_set_nmi(interrupt_cpu_status_t *cs,
unsigned int int_num,
int value, CLOCK cpu_clk)
{
if (cs == NULL || int_num >= cs->num_ints)
return;
if (value) { /* Trigger the NMI. */
if (!(cs->pending_int[int_num] & IK_NMI)) {
if (cs->nnmi == 0 && !(cs->global_pending_int & IK_NMI)) {
cs->global_pending_int = (cs->global_pending_int | IK_NMI);
/* This makes sure that NMI delay is correctly emulated when
cycles are stolen from the CPU. */
if (cs->last_stolen_cycles_clk <= cpu_clk)
cs->nmi_clk = cpu_clk;
else
interrupt_fixup_int_clk(cs, cpu_clk, &(cs->nmi_clk));
}
cs->nnmi++;
cs->pending_int[int_num] = (cs->pending_int[int_num] | IK_NMI);
}
} else { /* Remove the NMI condition. */
if (cs->pending_int[int_num] & IK_NMI) {
if (cs->nnmi > 0) {
cs->nnmi--;
cs->pending_int[int_num] =
(cs->pending_int[int_num] & ~IK_NMI);
#if 0
/* It should not be possible to remove the NMI condition,
only interrupt_ack_nmi() should clear it. */
if (cpu_clk == cs->nmi_clk)
cs->global_pending_int = (enum cpu_int)
(cs->global_pending_int & ~IK_NMI);
#endif
} else {
interrupt_log_wrong_nnmi();
}
}
}
}
/* Change the interrupt line state: this can be used to change both NMI
and IRQ lines. It is slower than `interrupt_set_nmi()' and
`interrupt_set_irq()', but is left for backward compatibility (it works
like the old `setirq()'). */
inline static void interrupt_set_int(interrupt_cpu_status_t *cs, int int_num,
enum cpu_int value, CLOCK cpu_clk)
{
interrupt_set_nmi(cs, int_num, (int)(value & IK_NMI), cpu_clk);
interrupt_set_irq(cs, int_num, (int)(value & IK_IRQ), cpu_clk);
}
/* ------------------------------------------------------------------------- */
/* This function must be called by the CPU emulator when a pending NMI/IRQ
request is served. */
inline static void interrupt_ack_nmi(interrupt_cpu_status_t *cs)
{
cs->global_pending_int =
(cs->global_pending_int & ~IK_NMI);
if (cs->nmi_trap_func)
cs->nmi_trap_func();
}
inline static void interrupt_ack_irq(interrupt_cpu_status_t *cs)
{
cs->global_pending_int =
(cs->global_pending_int & ~IK_IRQPEND);
}
#endif
/* ------------------------------------------------------------------------- */
/* Extern functions. These are defined in `interrupt.c'. */
struct snapshot_module_s;
extern interrupt_cpu_status_t *interrupt_cpu_status_new(void);
extern void interrupt_cpu_status_destroy(interrupt_cpu_status_t *cs);
extern void interrupt_cpu_status_init(interrupt_cpu_status_t *cs,
unsigned int *last_opcode_info_ptr);
extern void interrupt_cpu_status_reset(interrupt_cpu_status_t *cs);
extern void interrupt_trigger_reset(interrupt_cpu_status_t *cs, CLOCK cpu_clk);
extern unsigned int interrupt_cpu_status_int_new(interrupt_cpu_status_t *cs,
const char *name);
extern void interrupt_ack_reset(interrupt_cpu_status_t *cs);
extern void interrupt_set_reset_trap_func(interrupt_cpu_status_t *cs,
void (*reset_trap_func)(void));
extern void interrupt_maincpu_trigger_trap(void (*trap_func)(WORD,
void *data), void *data);
extern void interrupt_do_trap(interrupt_cpu_status_t *cs, WORD address);
extern void interrupt_monitor_trap_on(interrupt_cpu_status_t *cs);
extern void interrupt_monitor_trap_off(interrupt_cpu_status_t *cs);
extern void interrupt_cpu_status_time_warp(interrupt_cpu_status_t *cs,
CLOCK warp_amount,
int warp_direction);
extern int interrupt_read_snapshot(interrupt_cpu_status_t *cs,
struct snapshot_module_s *m);
extern int interrupt_read_new_snapshot(interrupt_cpu_status_t *cs,
struct snapshot_module_s *m);
extern int interrupt_write_snapshot(interrupt_cpu_status_t *cs,
struct snapshot_module_s *m);
extern int interrupt_write_new_snapshot(interrupt_cpu_status_t *cs,
struct snapshot_module_s *m);
extern void interrupt_restore_irq(interrupt_cpu_status_t *cs, int int_num,
int value);
extern void interrupt_restore_nmi(interrupt_cpu_status_t *cs, int int_num,
int value);
extern int interrupt_get_irq(interrupt_cpu_status_t *cs, int int_num);
extern int interrupt_get_nmi(interrupt_cpu_status_t *cs, int int_num);
extern void interrupt_set_nmi_trap_func(interrupt_cpu_status_t *cs,
void (*nmi_trap_func)(void));
/* ------------------------------------------------------------------------- */
extern interrupt_cpu_status_t *maincpu_int_status;
extern CLOCK maincpu_clk;
extern CLOCK drive_clk[2];
/* For convenience... */
#define maincpu_set_irq(int_num, value) \
interrupt_set_irq(maincpu_int_status, (int_num), (value), maincpu_clk)
#define maincpu_set_irq_clk(int_num, value, clk) \
interrupt_set_irq(maincpu_int_status, (int_num), (value), (clk))
#define maincpu_set_nmi(int_num, value) \
interrupt_set_nmi(maincpu_int_status, (int_num), (value), maincpu_clk)
#define maincpu_set_nmi_clk(int_num, value, clk) \
interrupt_set_nmi(maincpu_int_status, (int_num), (value), (clk))
#define maincpu_set_int(int_num, value) \
interrupt_set_int(maincpu_int_status, (int_num), (value), maincpu_clk)
#define maincpu_set_int_clk(int_num, value, clk) \
interrupt_set_int(maincpu_int_status, (int_num), (value), (clk))
#define maincpu_trigger_reset() \
interrupt_trigger_reset(maincpu_int_status, maincpu_clk)
#endif

View File

@ -0,0 +1,95 @@
/*
* mem.h - Memory interface.
*
* Written by
* André Fachat <fachat@physik.tu-chemnitz.de>
* Ettore Perazzoli <ettore@comm2000.it>
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _MEM_H_
#define _MEM_H_
#include "..\CommonVICE\types.h"
typedef BYTE REGPARM1 read_func_t(WORD addr);
typedef read_func_t *read_func_ptr_t;
typedef void REGPARM2 store_func_t(WORD addr, BYTE value);
typedef store_func_t *store_func_ptr_t;
extern read_func_ptr_t *_mem_read_tab_ptr;
extern store_func_ptr_t *_mem_write_tab_ptr;
extern BYTE **_mem_read_base_tab_ptr;
extern int *mem_read_limit_tab_ptr;
extern BYTE mem_ram[];
extern BYTE *mem_page_zero;
extern BYTE *mem_page_one;
extern BYTE *mem_color_ram_cpu;
extern BYTE *mem_color_ram_vicii;
extern unsigned int mem_old_reg_pc;
extern BYTE *mem_chargen_rom_ptr;
extern void mem_initialize_memory(void);
extern void mem_powerup(void);
extern int mem_load(void);
extern void mem_get_basic_text(WORD *start, WORD *end);
extern void mem_set_basic_text(WORD start, WORD end);
extern void mem_toggle_watchpoints(int flag, void *context);
extern int mem_rom_trap_allowed(WORD addr);
extern void mem_set_bank_pointer(BYTE **base, int *limit);
extern void mem_color_ram_to_snapshot(BYTE *color_ram);
extern void mem_color_ram_from_snapshot(BYTE *color_ram);
extern read_func_t rom_read, rom_trap_read, zero_read;
extern store_func_t rom_store, rom_trap_store, zero_store;
extern read_func_t mem_read;
extern store_func_t mem_store;
/* ------------------------------------------------------------------------- */
/* Memory access functions for the monitor. */
extern const char **mem_bank_list(void);
extern int mem_bank_from_name(const char *name);
extern BYTE mem_bank_read(int bank, WORD addr, void *context);
extern BYTE mem_bank_peek(int bank, WORD addr, void *context);
extern void mem_bank_write(int bank, WORD addr, BYTE byte, void *context);
extern void mem_get_screen_parameter(WORD *base, BYTE *rows, BYTE *columns, int *bank);
typedef struct mem_ioreg_list_s {
const char *name;
WORD start;
WORD end;
unsigned int next;
} mem_ioreg_list_t;
extern mem_ioreg_list_t *mem_ioreg_list_get(void *context);
/* Snapshots. */
struct snapshot_s;
extern int mem_write_snapshot_module(struct snapshot_s *s, int save_roms);
extern int mem_read_snapshot_module(struct snapshot_s *s);
#endif

View File

@ -772,7 +772,7 @@ LRESULT CALLBACK FrameWndProc (
VideoRedrawScreen();
g_bDebuggerViewingAppleOutput = true; // +PATCH
}
SAVE(TEXT("Video Emulation"),videotype);
REGSAVE(TEXT("Video Emulation"),videotype);
}
else if ((wparam == VK_F11) && (GetKeyState(VK_CONTROL) >= 0)) // Save state (F11)

View File

@ -30,8 +30,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#pragma hdrstop
#include "MouseInterface.h"
#ifdef SUPPORT_CPM
#include "z80\z80emu.h"
#include "z80\z80.h"
#include "z80emu.h"
#include "Z80VICE\z80.h"
#include "Z80VICE\z80mem.h"
#endif
#include "..\resource\resource.h"
@ -1060,7 +1061,7 @@ void MemInitialize()
if (g_Slot4 == CT_MouseInterface)
sg_Mouse.Initialize(pCxRomPeripheral, 4); // $C400 : Mouse f/w
#ifdef SUPPORT_CPM
ConfigureSoftcard(pCxRomPeripheral, 5, g_uZ80InSlot5); // $C500 ; Z80 card
ConfigureSoftcard(pCxRomPeripheral, 5, g_uZ80InSlot5); // $C500 : Z80 card
#endif
DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w
HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w
@ -1115,7 +1116,7 @@ void MemReset ()
//Sets Caps Lock = false (Pravets 8A/C only)
#ifdef SUPPORT_CPM
Z80_Reset();
z80_reset();
#endif
}

View File

@ -2,7 +2,7 @@
enum
{
// Note: Alll are in bytes!
// Note: All are in bytes!
APPLE_SLOT_SIZE = 0x0100, // 1 page = $Cx00 .. $CxFF (slot 1 .. 7)
APPLE_SLOT_BEGIN = 0xC100, // each slot has 1 page reserved for it
APPLE_SLOT_END = 0xC7FF, //

View File

@ -81,7 +81,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#pragma hdrstop
#include <wchar.h>
#include "ay8910.h"
#include "AY8910.h"
#include "SSI263Phonemes.h"
@ -144,7 +144,8 @@ static SY6522_AY8910 g_MB[NUM_AY8910];
// Timer vars
static ULONG g_n6522TimerPeriod = 0;
static USHORT g_nMBTimerDevice = 0; // SY6522 device# which is generating timer IRQ
static const UINT TIMERDEVICE_INVALID = -1;
static UINT g_nMBTimerDevice = TIMERDEVICE_INVALID; // SY6522 device# which is generating timer IRQ
static UINT64 g_uLastCumulativeCycles = 0;
// SSI263 vars:
@ -159,7 +160,7 @@ static short* ppAYVoiceBuffer[NUM_VOICES] = {0};
static unsigned __int64 g_nMB_InActiveCycleCount = 0;
static bool g_bMB_RegAccessedFlag = false;
static bool g_bMB_Active = true;
static bool g_bMB_Active = false;
static HANDLE g_hThread = NULL;
@ -197,7 +198,9 @@ static const double g_f6522TimerPeriod_NoIRQ = CLK_6502 / 60.0; // Constant wha
// External global vars:
bool g_bMBTimerIrqActive = false;
#ifdef _DEBUG
UINT32 g_uTimer1IrqCount = 0; // DEBUG
#endif
//---------------------------------------------------------------------------
@ -235,7 +238,7 @@ static void StopTimer(SY6522_AY8910* pMB)
{
pMB->nTimerStatus = 0;
g_bMBTimerIrqActive = false;
g_nMBTimerDevice = 0;
g_nMBTimerDevice = TIMERDEVICE_INVALID;
}
//-----------------------------------------------------------------------------
@ -254,6 +257,7 @@ static void ResetSY6522(SY6522_AY8910* pMB)
static void AY8910_Write(BYTE nDevice, BYTE nReg, BYTE nValue, BYTE nAYDevice)
{
g_bMB_RegAccessedFlag = true;
SY6522_AY8910* pMB = &g_MB[nDevice];
if((nValue & 4) == 0)
@ -323,7 +327,6 @@ static void UpdateIFR(SY6522_AY8910* pMB)
static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
{
g_bMB_RegAccessedFlag = true;
g_bMB_Active = true;
SY6522_AY8910* pMB = &g_MB[nDevice];
@ -432,8 +435,6 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
if(pMB->nTimerStatus == 0)
break;
pMB->nTimerStatus = 0;
// Stop timer
StopTimer(pMB);
}
@ -455,7 +456,7 @@ static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue)
static BYTE SY6522_Read(BYTE nDevice, BYTE nReg)
{
g_bMB_RegAccessedFlag = true;
// g_bMB_RegAccessedFlag = true;
g_bMB_Active = true;
SY6522_AY8910* pMB = &g_MB[nDevice];
@ -509,7 +510,7 @@ static BYTE SY6522_Read(BYTE nDevice, BYTE nReg)
nValue = pMB->sy6522.IFR;
break;
case 0x0e: // IER
nValue = 0x80;
nValue = 0x80; // Datasheet says this is 0x80|IER
break;
case 0x0f: // ORA_NO_HS
nValue = pMB->sy6522.ORA;
@ -727,12 +728,28 @@ static void Votrax_Write(BYTE nDevice, BYTE nValue)
static void MB_Update()
{
if(!MockingboardVoice.bActive)
if (!MockingboardVoice.bActive)
return;
if (g_bFullSpeed)
{
// Keep AY reg writes relative to the current 'frame'
// - Required for Ultima3:
// . Tune ends
// . g_bFullSpeed:=true (disk-spinning) for ~50 frames
// . U3 sets AY_ENABLE:=0xFF (as a side-effect, this sets g_bFullSpeed:=false)
// o Without this, the write to AY_ENABLE gets ignored (since AY8910's /g_uLastCumulativeCycles/ was last set 50 frame ago)
AY8910UpdateSetCycles();
// TODO:
// If any AY regs have changed then push them out to the AY chip
return;
}
//
if(!g_bMB_RegAccessedFlag)
if (!g_bMB_RegAccessedFlag)
{
if(!g_nMB_InActiveCycleCount)
{
@ -756,13 +773,11 @@ static void MB_Update()
static DWORD dwByteOffset = (DWORD)-1;
static int nNumSamplesError = 0;
const double n6522TimerPeriod = MB_GetFramePeriod();
int nNumSamples;
double n6522TimerPeriod = MB_GetFramePeriod();
double nIrqFreq = g_fCurrentCLK6502 / n6522TimerPeriod + 0.5; // Round-up
int nNumSamplesPerPeriod = (int) ((double)SAMPLE_RATE / nIrqFreq); // Eg. For 60Hz this is 735
nNumSamples = nNumSamplesPerPeriod + nNumSamplesError; // Apply correction
const double nIrqFreq = g_fCurrentCLK6502 / n6522TimerPeriod + 0.5; // Round-up
const int nNumSamplesPerPeriod = (int) ((double)SAMPLE_RATE / nIrqFreq); // Eg. For 60Hz this is 735
int nNumSamples = nNumSamplesPerPeriod + nNumSamplesError; // Apply correction
if(nNumSamples <= 0)
nNumSamples = 0;
if(nNumSamples > 2*nNumSamplesPerPeriod)
@ -823,7 +838,7 @@ static void MB_Update()
//
double fAttenuation = g_bPhasorEnable ? 2.0/3.0 : 1.0;
const double fAttenuation = g_bPhasorEnable ? 2.0/3.0 : 1.0;
for(int i=0; i<nNumSamples; i++)
{
@ -831,7 +846,7 @@ static void MB_Update()
// L = Address.b7=0, R = Address.b7=1
int nDataL = 0, nDataR = 0;
for(unsigned int j=0; j<NUM_VOICES_PER_AY8910; j++)
for(UINT j=0; j<NUM_VOICES_PER_AY8910; j++)
{
// Slot4
nDataL += (int) ((double)ppAYVoiceBuffer[0*NUM_VOICES_PER_AY8910+j][i] * fAttenuation);
@ -871,7 +886,7 @@ static void MB_Update()
// Commit sound buffer
hr = MockingboardVoice.lpDSBvoice->Unlock((void*)pDSLockedBuffer0, dwDSLockedBufferSize0,
(void*)pDSLockedBuffer1, dwDSLockedBufferSize1);
(void*)pDSLockedBuffer1, dwDSLockedBufferSize1);
dwByteOffset = (dwByteOffset + (DWORD)nNumSamples*sizeof(short)*g_nMB_NumChannels) % g_dwDSBufferSize;
@ -1361,6 +1376,7 @@ void MB_Reset()
AY8910_reset(i);
}
g_bMB_Active = (g_SoundcardType != SC_NONE);
g_nPhasorMode = 0;
MB_Reinitialize(); // Reset CLK for AY8910s
}
@ -1529,15 +1545,13 @@ void MB_EndOfVideoFrame()
if(g_SoundcardType == SC_NONE)
return;
if(!g_bFullSpeed && !g_bMBTimerIrqActive && !(g_MB[0].sy6522.IFR & IxR_TIMER1))
if(!g_bMBTimerIrqActive)
MB_Update();
}
//-----------------------------------------------------------------------------
// Called by InternalCpuExecute() after every N opcodes
// OLD: Called by InternalCpuExecute() after every opcode
// OLD: void MB_UpdateCycles(USHORT nClocks)
// Called by CpuExecute() after every N opcodes (N = ~1000 @ 1MHz)
void MB_UpdateCycles(ULONG uExecutedCycles)
{
if(g_SoundcardType == SC_NONE)
@ -1565,7 +1579,9 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
if( bTimer1Underflow && (g_nMBTimerDevice == i) && g_bMBTimerIrqActive )
{
#ifdef _DEBUG
g_uTimer1IrqCount++; // DEBUG
#endif
pMB->sy6522.IFR |= IxR_TIMER1;
UpdateIFR(pMB);
@ -1573,7 +1589,9 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
if((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT)
{
// One-shot mode
StopTimer(pMB); // Phasor's playback code uses one-shot mode
// - Phasor's playback code uses one-shot mode
// - Willy Byte sets to one-shot to stop the timer IRQ
StopTimer(pMB);
}
else
{
@ -1583,8 +1601,17 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
StartTimer(pMB);
}
if(!g_bFullSpeed)
MB_Update();
MB_Update();
}
else if ( bTimer1Underflow
&& !g_bMBTimerIrqActive // StopTimer() has been called
&& (pMB->sy6522.IFR & IxR_TIMER1) // IRQ
&& ((pMB->sy6522.ACR & RUNMODE) == RM_ONESHOT) ) // One-shot mode
{
// Fix for Willy Byte - need to confirm that 6522 really does this!
// . It never accesses IER/IFR/TIMER1 regs to clear IRQ
pMB->sy6522.IFR &= ~IxR_TIMER1; // Deassert the TIMER IRQ
UpdateIFR(pMB);
}
}
}

View File

@ -1,7 +1,9 @@
#pragma once
extern bool g_bMBTimerIrqActive;
#ifdef _DEBUG
extern UINT32 g_uTimer1IrqCount; // DEBUG
#endif
void MB_Initialize();
void MB_Reinitialize();

View File

@ -108,22 +108,18 @@ Etc.
#define MODE_INT_ALL STAT_INT_ALL
//===========================================================================
WRITE_HANDLER( M6821_Listener_B )
void M6821_Listener_B( void* objTo, BYTE byData )
{
((CMouseInterface*)objTo)->On6821_B( byData );
}
WRITE_HANDLER( M6821_Listener_A )
void M6821_Listener_A( void* objTo, BYTE byData )
{
((CMouseInterface*)objTo)->On6821_A( byData );
}
//CALLBACK_HANDLER( MouseHandler )
//{
// ((CMouseInterface*)objTo)->OnMouseEvent();
//}
//===========================================================================
CMouseInterface::CMouseInterface() :
@ -131,7 +127,6 @@ CMouseInterface::CMouseInterface() :
{
m_6821.SetListenerB( this, M6821_Listener_B );
m_6821.SetListenerA( this, M6821_Listener_A );
// g_cDIMouse.SetMouseListener( this, MouseHandler );
Uninitialize();
Reset();

View File

@ -1,9 +1,6 @@
#include "6821.h"
#include "Common.h"
#define WRITE_HANDLER(func) void func( void* objFrom, void* objTo, int nAddr, BYTE byData )
#define CALLBACK_HANDLER(func) void func( void* objFrom, void* objTo, LPARAM lParam )
extern class CMouseInterface sg_Mouse;
class CMouseInterface
@ -49,9 +46,8 @@ protected:
void OnMouseEvent(bool bEventVBL=false);
void Clear();
friend WRITE_HANDLER( M6821_Listener_A );
friend WRITE_HANDLER( M6821_Listener_B );
//friend CALLBACK_HANDLER( MouseHandler );
friend void M6821_Listener_A( void* objTo, BYTE byData );
friend void M6821_Listener_B( void* objTo, BYTE byData );
void SetPositionAbs(int x, int y);
int ClampX();

View File

@ -307,14 +307,14 @@ static void ConfigDlg_OK(HWND window, UINT afterclose)
NewCloneType = NewApple2Type - A2TYPE_CLONE;
if ((NewApple2Type == A2TYPE_PRAVETS82) || (NewApple2Type == A2TYPE_PRAVETS8A) || (NewApple2Type == A2TYPE_PRAVETS8M))
SAVE(TEXT(REGVALUE_APPLE2_TYPE),A2TYPE_CLONE );
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE),A2TYPE_CLONE );
else
SAVE(TEXT(REGVALUE_APPLE2_TYPE),NewApple2Type );
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE),NewApple2Type );
SAVE(TEXT("Serial Port") ,sg_SSC.GetSerialPort());
SAVE(TEXT("Custom Speed") ,IsDlgButtonChecked(window,IDC_CUSTOM_SPEED));
SAVE(TEXT("Emulation Speed") ,g_dwSpeed);
SAVE(TEXT("Video Emulation") ,videotype);
REGSAVE(TEXT("Serial Port") ,sg_SSC.GetSerialPort());
REGSAVE(TEXT("Custom Speed") ,IsDlgButtonChecked(window,IDC_CUSTOM_SPEED));
REGSAVE(TEXT("Emulation Speed") ,g_dwSpeed);
REGSAVE(TEXT("Video Emulation") ,videotype);
//
@ -450,7 +450,7 @@ static BOOL CALLBACK ConfigDlgProc (HWND window,
if (g_dwSpeed == SPEED_NORMAL)
{
custom = 0;
LOAD(TEXT("Custom Speed"),(DWORD *)&custom);
REGLOAD(TEXT("Custom Speed"),(DWORD *)&custom);
}
CheckRadioButton(window, IDC_AUTHENTIC_SPEED, IDC_CUSTOM_SPEED, custom ? IDC_CUSTOM_SPEED : IDC_AUTHENTIC_SPEED);
SetFocus(GetDlgItem(window, custom ? IDC_SLIDER_CPU_SPEED : IDC_AUTHENTIC_SPEED));
@ -512,15 +512,15 @@ static void InputDlg_OK(HWND window, UINT afterclose)
g_uMouseShowCrosshair = IsDlgButtonChecked(window, IDC_MOUSE_CROSSHAIR) ? 1 : 0;
g_uMouseRestrictToWindow = IsDlgButtonChecked(window, IDC_MOUSE_RESTRICT_TO_WINDOW) ? 1 : 0;
SAVE(TEXT("Joystick 0 Emulation"),joytype[0]);
SAVE(TEXT("Joystick 1 Emulation"),joytype[1]);
SAVE(TEXT(REGVALUE_PDL_XTRIM),JoyGetTrim(true));
SAVE(TEXT(REGVALUE_PDL_YTRIM),JoyGetTrim(false));
SAVE(TEXT(REGVALUE_SCROLLLOCK_TOGGLE),g_uScrollLockToggle);
SAVE(TEXT(REGVALUE_MOUSE_IN_SLOT4),g_uMouseInSlot4);
SAVE(TEXT(REGVALUE_MOUSE_CROSSHAIR),g_uMouseShowCrosshair);
SAVE(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW),g_uMouseRestrictToWindow);
SAVE(TEXT(REGVALUE_Z80_IN_SLOT5),g_uZ80InSlot5);
REGSAVE(TEXT("Joystick 0 Emulation"),joytype[0]);
REGSAVE(TEXT("Joystick 1 Emulation"),joytype[1]);
REGSAVE(TEXT(REGVALUE_PDL_XTRIM),JoyGetTrim(true));
REGSAVE(TEXT(REGVALUE_PDL_YTRIM),JoyGetTrim(false));
REGSAVE(TEXT(REGVALUE_SCROLLLOCK_TOGGLE),g_uScrollLockToggle);
REGSAVE(TEXT(REGVALUE_MOUSE_IN_SLOT4),g_uMouseInSlot4);
REGSAVE(TEXT(REGVALUE_MOUSE_CROSSHAIR),g_uMouseShowCrosshair);
REGSAVE(TEXT(REGVALUE_MOUSE_RESTRICT_TO_WINDOW),g_uMouseRestrictToWindow);
REGSAVE(TEXT(REGVALUE_Z80_IN_SLOT5),g_uZ80InSlot5);
//
@ -729,10 +729,10 @@ static void SoundDlg_OK(HWND window, UINT afterclose, UINT uNewSoundcardType)
MB_SetSoundcardType((eSOUNDCARDTYPE)uNewSoundcardType);
SAVE(TEXT("Sound Emulation") ,soundtype);
SAVE(TEXT(REGVALUE_SPKR_VOLUME),SpkrGetVolume());
SAVE(TEXT(REGVALUE_MB_VOLUME),MB_GetVolume());
SAVE(TEXT(REGVALUE_SOUNDCARD_TYPE),(DWORD)MB_GetSoundcardType());
REGSAVE(TEXT("Sound Emulation") ,soundtype);
REGSAVE(TEXT(REGVALUE_SPKR_VOLUME),SpkrGetVolume());
REGSAVE(TEXT(REGVALUE_MB_VOLUME),MB_GetVolume());
REGSAVE(TEXT(REGVALUE_SOUNDCARD_TYPE),(DWORD)MB_GetSoundcardType());
//
@ -879,8 +879,8 @@ static void DiskDlg_OK(HWND window, UINT afterclose)
bool bHDDIsEnabled = IsDlgButtonChecked(window, IDC_HDD_ENABLE) ? true : false;
HD_SetEnabled(bHDDIsEnabled);
SAVE(TEXT("Enhance Disk Speed"),newdisktype);
SAVE(TEXT(REGVALUE_HDD_ENABLED), bHDDIsEnabled ? 1 : 0);
REGSAVE(TEXT("Enhance Disk Speed"),newdisktype);
REGSAVE(TEXT(REGVALUE_HDD_ENABLED), bHDDIsEnabled ? 1 : 0);
RegSaveString(TEXT("Configuration"), TEXT(REGVALUE_HDD_IMAGE1), 1, HD_GetFullName(0));
RegSaveString(TEXT("Configuration"), TEXT(REGVALUE_HDD_IMAGE2), 1, HD_GetFullName(1));
@ -1115,27 +1115,29 @@ static void AdvancedDlg_OK(HWND window, UINT afterclose)
// PrinterStateUpdate();
g_bSaveStateOnExit = IsDlgButtonChecked(window, IDC_SAVESTATE_ON_EXIT) ? true : false;
REGSAVE(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), g_bSaveStateOnExit ? 1 : 0);
SAVE(TEXT(REGVALUE_SAVE_STATE_ON_EXIT), g_bSaveStateOnExit ? 1 : 0);
g_bDumpToPrinter = IsDlgButtonChecked(window, IDC_DUMPTOPRINTER ) ? true : false;
SAVE(TEXT(REGVALUE_DUMP_TO_PRINTER), g_bDumpToPrinter ? 1 : 0);
REGSAVE(TEXT(REGVALUE_DUMP_TO_PRINTER), g_bDumpToPrinter ? 1 : 0);
g_bConvertEncoding = IsDlgButtonChecked(window, IDC_PRINTER_CONVERT_ENCODING ) ? true : false;
SAVE(TEXT(REGVALUE_CONVERT_ENCODING), g_bConvertEncoding ? 1 : 0);
REGSAVE(TEXT(REGVALUE_CONVERT_ENCODING), g_bConvertEncoding ? 1 : 0);
g_bFilterUnprintable = IsDlgButtonChecked(window, IDC_PRINTER_FILTER_UNPRINTABLE ) ? true : false;
SAVE(TEXT(REGVALUE_FILTER_UNPRINTABLE), g_bFilterUnprintable ? 1 : 0);
REGSAVE(TEXT(REGVALUE_FILTER_UNPRINTABLE), g_bFilterUnprintable ? 1 : 0);
g_bPrinterAppend = IsDlgButtonChecked(window, IDC_PRINTER_APPEND) ? true : false;
SAVE(TEXT(REGVALUE_PRINTER_APPEND), g_bPrinterAppend ? 1 : 0);
REGSAVE(TEXT(REGVALUE_PRINTER_APPEND), g_bPrinterAppend ? 1 : 0);
//
DWORD NewCloneType = (DWORD)SendDlgItemMessage(window, IDC_CLONETYPE, CB_GETCURSEL, 0, 0);
SAVE(TEXT(REGVALUE_CLONETYPE), NewCloneType);
SAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM),g_uTheFreezesF8Rom); // NB. Can also be disabled on Config page (when Apple2Type changes)
REGSAVE(TEXT(REGVALUE_CLONETYPE), NewCloneType);
REGSAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM),g_uTheFreezesF8Rom); // NB. Can also be disabled on Config page (when Apple2Type changes)
Printer_SetIdleLimit((short)SendDlgItemMessage(window, IDC_SPIN_PRINTER_IDLE , UDM_GETPOS, 0, 0));
SAVE(TEXT(REGVALUE_PRINTER_IDLE_LIMIT),Printer_GetIdleLimit());
REGSAVE(TEXT(REGVALUE_PRINTER_IDLE_LIMIT),Printer_GetIdleLimit());
eApple2Type NewApple2Clone = GetApple2Type(4, NewCloneType);
@ -1341,7 +1343,7 @@ static int gray_ungray_items(HWND hwnd)
int disabled = 0;
//resources_get_value("ETHERNET_DISABLED", (void *)&disabled);
LOAD(TEXT("Uthernet Disabled") ,(DWORD *)&disabled);
REGLOAD(TEXT("Uthernet Disabled") ,(DWORD *)&disabled);
get_disabled_state(&disabled);
if (disabled) {
@ -1496,9 +1498,9 @@ static void save_tfe_dialog(HWND hwnd)
CB_GETCURSEL, 0, 0);
tfe_enabled = active_value >= 1 ? 1 : 0;
SAVE(TEXT("Uthernet Active") ,tfe_enabled);
REGSAVE(TEXT("Uthernet Active") ,tfe_enabled);
} else {
SAVE(TEXT("Uthernet Active") ,0);
REGSAVE(TEXT("Uthernet Active") ,0);
}

View File

@ -20,7 +20,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
#include <time.h>
#include <windows.h>

View File

@ -27,7 +27,7 @@
#ifndef _TFE_H
#define _TFE_H
#include "types.h"
#include "..\CommonVICE\types.h"
#include <stdio.h>
/* define this only if VICE should write each and every frame received

View File

@ -28,7 +28,7 @@
#ifndef _TFEARCH_H
#define _TFEARCH_H
#include "types.h"
#include "..\CommonVICE\types.h"
extern int tfe_arch_init(void);
extern void tfe_arch_pre_reset(void);

View File

@ -1780,7 +1780,7 @@ void VideoChooseColor () {
VideoReinitialize();
if ((g_nAppMode != MODE_LOGO) && (g_nAppMode != MODE_DEBUG))
VideoRedrawScreen();
SAVE(TEXT("Monochrome Color"),monochrome);
REGSAVE(TEXT("Monochrome Color"),monochrome);
}
}

View File

@ -1,35 +0,0 @@
******* Z80Em *******
Portable Zilog Z80 Emulator
Version 1.2 (04-09-1997)
Copyright (C) Marcel de Kogel 1996,1997
This package contains a portable Z80 emulator. It includes two engines: One
written in pure C, which can be used on just about every 32+ bit system, and
one optimised for GCC/x86 (DJGPP, Linux, FreeBSD). It can be used to emulate
systems with multiple Z80s and systems with several different CPUs
You can use in your own applications, as long as proper credit is given,
no profit is made and I am notified. If you want to use this code for
commercial purposes, e.g. using it in commercial projects, selling it, etc.,
please contact me
To use the code, check the system dependent part of Z80.h, write your own
memory and I/O functions, which are declared in Z80IO.h, write your own
Interrupt(), Z80_Patch(), Z80_Reti() and Z80_Retn() functions, initialise
the Z80_IPeriod and Z80_IRQ variables, call Z80_Reset() to reset all registers
to their initial values or call Z80_SetRegs() to set all of them to pre-loaded
ones, and finally call Z80() or repeatedly call Z80_Execute(), the latter
option should be used in multi-processor emulations
For updates and examples on how to use this engine, check my homepage at
http://www.komkon.org/~dekogel/
History
-------
1.2 04-09-97 Fixed some more bugs
1.1 13-02-97 Fixed several bugs and compatibility problems
1.0 31-01-97 Initial release
Please send your comments and bug reports to
m.dekogel@student.utwente.nl

File diff suppressed because it is too large Load Diff

View File

@ -1,146 +0,0 @@
/*** Z80Em: Portable Z80 emulator *******************************************/
/*** ***/
/*** Z80.h ***/
/*** ***/
/*** This file contains the function prototypes and variable declarations ***/
/*** ***/
/*** Copyright (C) Marcel de Kogel 1996,1997 ***/
/*** You are not allowed to distribute this software commercially ***/
/*** Please, notify me, if you make any changes to this file ***/
/****************************************************************************/
#pragma once
/****************************************************************************/
/*** Machine dependent definitions ***/
/****************************************************************************/
/* #define DEBUG */ /* Compile debugging version */
/* #define X86_ASM */ /* Compile optimised GCC/x86 version */
#define LSB_FIRST /* Compile for low-endian CPU */
/* #define __64BIT__ */ /* Compile for 64 bit machines */
/* #define __128BIT__ */ /* Compile for 128 bit machines */
/****************************************************************************/
/* If your compiler doesn't know about inlined functions, uncomment this */
/****************************************************************************/
/* #define INLINE static */
#ifndef EMU_TYPES
#define EMU_TYPES
/****************************************************************************/
/* sizeof(byte)=1, sizeof(word)=2, sizeof(dword)>=4 */
/****************************************************************************/
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned dword;
typedef signed char offset;
/****************************************************************************/
/* Define a Z80 word. Upper bytes are always zero */
/****************************************************************************/
typedef union
{
#ifdef __128BIT__
#ifdef LSB_FIRST
struct { byte l,h,h2,h3,h4,h5,h6,h7,
h8,h9,h10,h11,h12,h13,h14,h15; } B;
struct { word l,h,h2,h3,h4,h5,h6,h7; } W;
dword D;
#else
struct { byte h15,h14,h13,h12,h11,h10,h9,h8,
h7,h6,h5,h4,h3,h2,h,l; } B;
struct { word h7,h6,h5,h4,h3,h2,h,l; } W;
dword D;
#endif
#elif __64BIT__
#ifdef LSB_FIRST
struct { byte l,h,h2,h3,h4,h5,h6,h7; } B;
struct { word l,h,h2,h3; } W;
dword D;
#else
struct { byte h7,h6,h5,h4,h3,h2,h,l; } B;
struct { word h3,h2,h,l; } W;
dword D;
#endif
#else
#ifdef LSB_FIRST
struct { byte l,h,h2,h3; } B;
struct { word l,h; } W;
dword D;
#else
struct { byte h3,h2,h,l; } B;
struct { word h,l; } W;
dword D;
#endif
#endif
} regpair;
#endif /* EMU_TYPES */
/****************************************************************************/
/*** End of machine dependent definitions ***/
/****************************************************************************/
#ifndef INLINE
#define INLINE static inline
#endif
/****************************************************************************/
/* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */
/* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128) */
/****************************************************************************/
typedef struct
{
regpair AF,BC,DE,HL,IX,IY,PC,SP;
regpair AF2,BC2,DE2,HL2;
unsigned IFF1,IFF2,HALT,IM,I,R,R2;
} Z80_Regs;
/****************************************************************************/
/* Set Z80_Trace to 1 when PC==Z80_Trap. When trace is on, Z80_Debug() is */
/* called after every instruction */
/****************************************************************************/
#ifdef DEBUG
extern int Z80_Trace;
extern int Z80_Trap;
void Z80_Debug(Z80_Regs *R);
#endif
extern int Z80_Running; /* When 0, emulation terminates */
extern int Z80_IPeriod; /* Number of T-states per interrupt */
extern int Z80_ICount; /* T-state count */
extern int Z80_IRQ; /* Current IRQ status. Checked after EI occurs */
#define Z80_IGNORE_INT -1 /* Ignore interrupt */
#define Z80_NMI_INT -2 /* Execute NMI */
DWORD InternalZ80Execute (ULONG totalcycles, ULONG uExecutedCycles);
unsigned Z80_GetPC (void); /* Get program counter */
void InitTables (void);
void Z80_GetRegs (Z80_Regs *Regs); /* Get registers */
void Z80_SetRegs (Z80_Regs *Regs); /* Set registers */
void Z80_Reset (void); /* Reset registers to the initial values */
//int Z80_Execute (void); /* Execute IPeriod T-States */
word Z80 (void); /* Execute until Z80_Running==0 */
void Z80_RegisterDump (void); /* Prints a dump to stdout */
void Z80_SetWaitStates (int n); /* Set number of memory wait states. */
/* This only affects opcode fetching, so */
/* wait state adjustment is still */
/* necessary in Z80_RDMEM, Z80_RDOP_ARG, */
/* Z80_RDSTACK and Z80_WRSTACK */
void Z80_Patch (Z80_Regs *Regs); /* Called when ED FE occurs. Can be used */
/* to emulate disk access etc. */
int Z80_Interrupt(void); /* This is called after IPeriod T-States */
/* have been executed. It should return */
/* Z80_IGNORE_INT, Z80_NMI_INT or a byte */
/* identifying the device (most often */
/* 0xFF) */
void Z80_Reti (void); /* Called when RETI occurs */
void Z80_Retn (void); /* Called when RETN occurs */
/****************************************************************************/
/* Definitions of functions to read/write memory and I/O ports */
/* You can replace these with your own, inlined if necessary */
/****************************************************************************/
#include "Z80IO.h"

View File

@ -1,219 +0,0 @@
/*** Z80Em: Portable Z80 emulator *******************************************/
/*** ***/
/*** Z80Codes.h ***/
/*** ***/
/*** This file contains various macros used by the emulation engine ***/
/*** ***/
/*** Copyright (C) Marcel de Kogel 1996,1997 ***/
/*** You are not allowed to distribute this software commercially ***/
/*** Please, notify me, if you make any changes to this file ***/
/****************************************************************************/
#define M_POP(Rg) \
R.Rg.D=M_RDSTACK(R.SP.D)+(M_RDSTACK((R.SP.D+1)&65535)<<8); \
R.SP.W.l+=2
#define M_PUSH(Rg) \
R.SP.W.l-=2; \
M_WRSTACK(R.SP.D,R.Rg.D); \
M_WRSTACK((R.SP.D+1)&65535,R.Rg.D>>8)
#define M_CALL \
{ \
int q; \
q=M_RDMEM_OPCODE_WORD(); \
M_PUSH(PC); \
R.PC.D=q; \
Z80_ICount-=7; \
}
#define M_JP \
R.PC.D=M_RDOP_ARG(R.PC.D)+((M_RDOP_ARG((R.PC.D+1)&65535))<<8)
#define M_JR \
R.PC.W.l+=((offset)M_RDOP_ARG(R.PC.D))+1; Z80_ICount-=5
#define M_RET M_POP(PC); Z80_ICount-=6
#define M_RST(Addr) M_PUSH(PC); R.PC.D=Addr
#define M_SET(Bit,Reg) Reg|=1<<Bit
#define M_RES(Bit,Reg) Reg&=~(1<<Bit)
#define M_BIT(Bit,Reg) \
R.AF.B.l=(R.AF.B.l&C_FLAG)|H_FLAG| \
((Reg&(1<<Bit))? ((Bit==7)?S_FLAG:0):Z_FLAG)
#define M_AND(Reg) R.AF.B.h&=Reg; R.AF.B.l=ZSPTable[R.AF.B.h]|H_FLAG
#define M_OR(Reg) R.AF.B.h|=Reg; R.AF.B.l=ZSPTable[R.AF.B.h]
#define M_XOR(Reg) R.AF.B.h^=Reg; R.AF.B.l=ZSPTable[R.AF.B.h]
#define M_IN(Reg) \
Reg=DoIn(R.BC.B.l,R.BC.B.h); \
R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSPTable[Reg]
#define M_RLCA \
R.AF.B.h=(R.AF.B.h<<1)|((R.AF.B.h&0x80)>>7); \
R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&C_FLAG)
#define M_RRCA \
R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&0x01); \
R.AF.B.h=(R.AF.B.h>>1)|(R.AF.B.h<<7)
#define M_RLA \
{ \
int i; \
i=R.AF.B.l&C_FLAG; \
R.AF.B.l=(R.AF.B.l&0xEC)|((R.AF.B.h&0x80)>>7); \
R.AF.B.h=(R.AF.B.h<<1)|i; \
}
#define M_RRA \
{ \
int i; \
i=R.AF.B.l&C_FLAG; \
R.AF.B.l=(R.AF.B.l&0xEC)|(R.AF.B.h&0x01); \
R.AF.B.h=(R.AF.B.h>>1)|(i<<7); \
}
#define M_RLC(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg=(Reg<<1)|q; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_RRC(Reg) \
{ \
int q; \
q=Reg&1; \
Reg=(Reg>>1)|(q<<7); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_RL(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg=(Reg<<1)|(R.AF.B.l&1); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_RR(Reg) \
{ \
int q; \
q=Reg&1; \
Reg=(Reg>>1)|(R.AF.B.l<<7); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SLL(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg=(Reg<<1)|1; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SLA(Reg) \
{ \
int q; \
q=Reg>>7; \
Reg<<=1; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SRL(Reg) \
{ \
int q; \
q=Reg&1; \
Reg>>=1; \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_SRA(Reg) \
{ \
int q; \
q=Reg&1; \
Reg=(Reg>>1)|(Reg&0x80); \
R.AF.B.l=ZSPTable[Reg]|q; \
}
#define M_INC(Reg) \
++Reg; \
R.AF.B.l=(R.AF.B.l&C_FLAG)|ZSTable[Reg]| \
((Reg==0x80)?V_FLAG:0)|((Reg&0x0F)?0:H_FLAG)
#define M_DEC(Reg) \
R.AF.B.l=(R.AF.B.l&C_FLAG)|N_FLAG| \
((Reg==0x80)?V_FLAG:0)|((Reg&0x0F)?0:H_FLAG); \
R.AF.B.l|=ZSTable[--Reg]
#define M_ADD(Reg) \
{ \
int q; \
q=R.AF.B.h+Reg; \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h^0x80)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_ADC(Reg) \
{ \
int q; \
q=R.AF.B.h+Reg+(R.AF.B.l&1); \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h^0x80)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_SUB(Reg) \
{ \
int q; \
q=R.AF.B.h-Reg; \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_SBC(Reg) \
{ \
int q; \
q=R.AF.B.h-Reg-(R.AF.B.l&1); \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \
R.AF.B.h=q; \
}
#define M_CP(Reg) \
{ \
int q; \
q=R.AF.B.h-Reg; \
R.AF.B.l=ZSTable[q&255]|((q&256)>>8)|N_FLAG| \
((R.AF.B.h^q^Reg)&H_FLAG)| \
(((Reg^R.AF.B.h)&(Reg^q)&0x80)>>5); \
}
#define M_ADDW(Reg1,Reg2) \
{ \
int q; \
q=R.Reg1.D+R.Reg2.D; \
R.AF.B.l=(R.AF.B.l&(S_FLAG|Z_FLAG|V_FLAG))| \
(((R.Reg1.D^q^R.Reg2.D)&0x1000)>>8)| \
((q>>16)&1); \
R.Reg1.W.l=q; \
}
#define M_ADCW(Reg) \
{ \
int q; \
q=R.HL.D+R.Reg.D+(R.AF.D&1); \
R.AF.B.l=(((R.HL.D^q^R.Reg.D)&0x1000)>>8)| \
((q>>16)&1)| \
((q&0x8000)>>8)| \
((q&65535)?0:Z_FLAG)| \
(((R.Reg.D^R.HL.D^0x8000)&(R.Reg.D^q)&0x8000)>>13); \
R.HL.W.l=q; \
}
#define M_SBCW(Reg) \
{ \
int q; \
q=R.HL.D-R.Reg.D-(R.AF.D&1); \
R.AF.B.l=(((R.HL.D^q^R.Reg.D)&0x1000)>>8)| \
((q>>16)&1)| \
((q&0x8000)>>8)| \
((q&65535)?0:Z_FLAG)| \
(((R.Reg.D^R.HL.D)&(R.Reg.D^q)&0x8000)>>13)| \
N_FLAG; \
R.HL.W.l=q; \
}

File diff suppressed because it is too large Load Diff

View File

@ -1,70 +0,0 @@
/*** Z80Em: Portable Z80 emulator *******************************************/
/*** ***/
/*** Z80IO.h ***/
/*** ***/
/*** This file contains the prototypes for the functions accessing memory ***/
/*** and I/O ***/
/*** ***/
/*** Copyright (C) Marcel de Kogel 1996,1997 ***/
/*** You are not allowed to distribute this software commercially ***/
/*** Please, notify me, if you make any changes to this file ***/
/****************************************************************************/
/****************************************************************************/
/* Input a byte from given I/O port */
/****************************************************************************/
byte Z80_In (BYTE Port);
/****************************************************************************/
/* Output a byte to given I/O port */
/****************************************************************************/
void Z80_Out (BYTE Port,BYTE Value);
/****************************************************************************/
/* Read a byte from given memory location */
/****************************************************************************/
unsigned Z80_RDMEM(DWORD A);
/****************************************************************************/
/* Write a byte to given memory location */
/****************************************************************************/
void Z80_WRMEM(DWORD A,BYTE V);
/****************************************************************************/
/* Just to show you can actually use macros as well */
/****************************************************************************/
/*
extern byte *ReadPage[256];
extern byte *WritePage[256];
#define Z80_RDMEM(a) ReadPage[(a)>>8][(a)&0xFF]
#define Z80_WRMEM(a,v) WritePage[(a)>>8][(a)&0xFF]=v
*/
/****************************************************************************/
/* Z80_RDOP() is identical to Z80_RDMEM() except it is used for reading */
/* opcodes. In case of system with memory mapped I/O, this function can be */
/* used to greatly speed up emulation */
/****************************************************************************/
#define Z80_RDOP(A) Z80_RDMEM(A)
/****************************************************************************/
/* Z80_RDOP_ARG() is identical to Z80_RDOP() except it is used for reading */
/* opcode arguments. This difference can be used to support systems that */
/* use different encoding mechanisms for opcodes and opcode arguments */
/****************************************************************************/
#define Z80_RDOP_ARG(A) Z80_RDOP(A)
/****************************************************************************/
/* Z80_RDSTACK() is identical to Z80_RDMEM() except it is used for reading */
/* stack variables. In case of system with memory mapped I/O, this function */
/* can be used to slightly speed up emulation */
/****************************************************************************/
#define Z80_RDSTACK(A) Z80_RDMEM(A)
/****************************************************************************/
/* Z80_WRSTACK() is identical to Z80_WRMEM() except it is used for writing */
/* stack variables. In case of system with memory mapped I/O, this function */
/* can be used to slightly speed up emulation */
/****************************************************************************/
#define Z80_WRSTACK(A,V) Z80_WRMEM(A,V)

View File

@ -0,0 +1,547 @@
/*
* daa.c
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#include "daa.h"
#include "..\CommonVICE\types.h" // [AppleWin-TC]
const BYTE daa_reg_a[2048] = {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
0x28,0x29,0x30,0x31,0x32,0x33,0x34,0x35,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x38,0x39,0x40,0x41,0x42,0x43,0x44,0x45,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x50,0x51,0x52,0x53,0x54,0x55,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
0x58,0x59,0x60,0x61,0x62,0x63,0x64,0x65,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
0x68,0x69,0x70,0x71,0x72,0x73,0x74,0x75,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
0x78,0x79,0x80,0x81,0x82,0x83,0x84,0x85,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x90,0x91,0x92,0x93,0x94,0x95,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x98,0x99,0x00,0x01,0x02,0x03,0x04,0x05,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
0x28,0x29,0x30,0x31,0x32,0x33,0x34,0x35,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x38,0x39,0x40,0x41,0x42,0x43,0x44,0x45,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x50,0x51,0x52,0x53,0x54,0x55,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
0x58,0x59,0x60,0x61,0x62,0x63,0x64,0x65,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
0x68,0x69,0x70,0x71,0x72,0x73,0x74,0x75,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
0x78,0x79,0x80,0x81,0x82,0x83,0x84,0x85,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x90,0x91,0x92,0x93,0x94,0x95,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x98,0x99,0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
0xA8,0xA9,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
0xB8,0xB9,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
0xC8,0xC9,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
0xD8,0xD9,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
0xE8,0xE9,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
0xF8,0xF9,0x00,0x01,0x02,0x03,0x04,0x05,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
0x28,0x29,0x30,0x31,0x32,0x33,0x34,0x35,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x38,0x39,0x40,0x41,0x42,0x43,0x44,0x45,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x50,0x51,0x52,0x53,0x54,0x55,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
0x58,0x59,0x60,0x61,0x62,0x63,0x64,0x65,
0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,
0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,
0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,
0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,
0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,
0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,
0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,
0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,
0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,
0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,
0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,
0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,
0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,
0x7E,0x7F,0x80,0x81,0x82,0x83,0x84,0x85,
0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,
0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,
0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,
0x9E,0x9F,0x00,0x01,0x02,0x03,0x04,0x05,
0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,
0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,
0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,
0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,
0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,
0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,
0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,
0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,
0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,
0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,
0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,
0x6E,0x6F,0x70,0x71,0x72,0x73,0x74,0x75,
0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,
0x7E,0x7F,0x80,0x81,0x82,0x83,0x84,0x85,
0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,
0x8E,0x8F,0x90,0x91,0x92,0x93,0x94,0x95,
0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,
0x9E,0x9F,0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,
0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,
0xAE,0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,
0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,
0xBE,0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,
0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,
0xCE,0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,
0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,
0xDE,0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,
0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,
0xEE,0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,
0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,
0xFE,0xFF,0x00,0x01,0x02,0x03,0x04,0x05,
0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,
0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,
0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,
0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,
0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,
0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,
0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,
0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,
0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,
0x5E,0x5F,0x60,0x61,0x62,0x63,0x64,0x65,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x04,0x05,0x06,0x07,0x08,0x09,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x14,0x15,0x16,0x17,0x18,0x19,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
0x28,0x29,0x24,0x25,0x26,0x27,0x28,0x29,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x38,0x39,0x34,0x35,0x36,0x37,0x38,0x39,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x44,0x45,0x46,0x47,0x48,0x49,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
0x58,0x59,0x54,0x55,0x56,0x57,0x58,0x59,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
0x68,0x69,0x64,0x65,0x66,0x67,0x68,0x69,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
0x78,0x79,0x74,0x75,0x76,0x77,0x78,0x79,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x84,0x85,0x86,0x87,0x88,0x89,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x98,0x99,0x34,0x35,0x36,0x37,0x38,0x39,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x44,0x45,0x46,0x47,0x48,0x49,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
0x58,0x59,0x54,0x55,0x56,0x57,0x58,0x59,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
0x68,0x69,0x64,0x65,0x66,0x67,0x68,0x69,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
0x78,0x79,0x74,0x75,0x76,0x77,0x78,0x79,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x84,0x85,0x86,0x87,0x88,0x89,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x98,0x99,0x94,0x95,0x96,0x97,0x98,0x99,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
0xA8,0xA9,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,
0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
0xB8,0xB9,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
0xC8,0xC9,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,
0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
0xD8,0xD9,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
0xE8,0xE9,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
0xF8,0xF9,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x04,0x05,0x06,0x07,0x08,0x09,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x14,0x15,0x16,0x17,0x18,0x19,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
0x28,0x29,0x24,0x25,0x26,0x27,0x28,0x29,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
0x38,0x39,0x34,0x35,0x36,0x37,0x38,0x39,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x48,0x49,0x44,0x45,0x46,0x47,0x48,0x49,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
0x58,0x59,0x54,0x55,0x56,0x57,0x58,0x59,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
0x68,0x69,0x64,0x65,0x66,0x67,0x68,0x69,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
0x78,0x79,0x74,0x75,0x76,0x77,0x78,0x79,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x84,0x85,0x86,0x87,0x88,0x89,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x98,0x99,0x94,0x95,0x96,0x97,0x98,0x99,
0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,
0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,
0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,
0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x41,
0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,
0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,
0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,
0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,
0x92,0x93,0x34,0x35,0x36,0x37,0x38,0x39,
0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x41,
0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,
0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,
0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,
0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,
0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0,0xA1,
0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,
0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0,0xB1,
0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xC0,0xC1,
0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,
0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,0xD0,0xD1,
0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,
0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,
0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,
0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x41,
0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,
0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,0x60,0x61,
0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,
0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80,0x81,
0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90,0x91,
0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99 };
const BYTE daa_reg_f[2048] = {
0x44,0x00,0x00,0x04,0x00,0x04,0x04,0x00,
0x08,0x0C,0x10,0x14,0x14,0x10,0x14,0x10,
0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,
0x0C,0x08,0x30,0x34,0x34,0x30,0x34,0x30,
0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24,
0x2C,0x28,0x34,0x30,0x30,0x34,0x30,0x34,
0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20,
0x28,0x2C,0x10,0x14,0x14,0x10,0x14,0x10,
0x00,0x04,0x04,0x00,0x04,0x00,0x00,0x04,
0x0C,0x08,0x14,0x10,0x10,0x14,0x10,0x14,
0x04,0x00,0x00,0x04,0x00,0x04,0x04,0x00,
0x08,0x0C,0x34,0x30,0x30,0x34,0x30,0x34,
0x24,0x20,0x20,0x24,0x20,0x24,0x24,0x20,
0x28,0x2C,0x30,0x34,0x34,0x30,0x34,0x30,
0x20,0x24,0x24,0x20,0x24,0x20,0x20,0x24,
0x2C,0x28,0x90,0x94,0x94,0x90,0x94,0x90,
0x80,0x84,0x84,0x80,0x84,0x80,0x80,0x84,
0x8C,0x88,0x94,0x90,0x90,0x94,0x90,0x94,
0x84,0x80,0x80,0x84,0x80,0x84,0x84,0x80,
0x88,0x8C,0x55,0x11,0x11,0x15,0x11,0x15,
0x45,0x01,0x01,0x05,0x01,0x05,0x05,0x01,
0x09,0x0D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x05,0x01,0x05,0x01,0x01,0x05,
0x0D,0x09,0x31,0x35,0x35,0x31,0x35,0x31,
0x21,0x25,0x25,0x21,0x25,0x21,0x21,0x25,
0x2D,0x29,0x35,0x31,0x31,0x35,0x31,0x35,
0x25,0x21,0x21,0x25,0x21,0x25,0x25,0x21,
0x29,0x2D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x05,0x01,0x05,0x01,0x01,0x05,
0x0D,0x09,0x15,0x11,0x11,0x15,0x11,0x15,
0x05,0x01,0x01,0x05,0x01,0x05,0x05,0x01,
0x09,0x0D,0x35,0x31,0x31,0x35,0x31,0x35,
0x25,0x21,0x21,0x25,0x21,0x25,0x25,0x21,
0x29,0x2D,0x31,0x35,0x35,0x31,0x35,0x31,
0x21,0x25,0x25,0x21,0x25,0x21,0x21,0x25,
0x2D,0x29,0x91,0x95,0x95,0x91,0x95,0x91,
0x81,0x85,0x85,0x81,0x85,0x81,0x81,0x85,
0x8D,0x89,0x95,0x91,0x91,0x95,0x91,0x95,
0x85,0x81,0x81,0x85,0x81,0x85,0x85,0x81,
0x89,0x8D,0xB5,0xB1,0xB1,0xB5,0xB1,0xB5,
0xA5,0xA1,0xA1,0xA5,0xA1,0xA5,0xA5,0xA1,
0xA9,0xAD,0xB1,0xB5,0xB5,0xB1,0xB5,0xB1,
0xA1,0xA5,0xA5,0xA1,0xA5,0xA1,0xA1,0xA5,
0xAD,0xA9,0x95,0x91,0x91,0x95,0x91,0x95,
0x85,0x81,0x81,0x85,0x81,0x85,0x85,0x81,
0x89,0x8D,0x91,0x95,0x95,0x91,0x95,0x91,
0x81,0x85,0x85,0x81,0x85,0x81,0x81,0x85,
0x8D,0x89,0xB1,0xB5,0xB5,0xB1,0xB5,0xB1,
0xA1,0xA5,0xA5,0xA1,0xA5,0xA1,0xA1,0xA5,
0xAD,0xA9,0xB5,0xB1,0xB1,0xB5,0xB1,0xB5,
0xA5,0xA1,0xA1,0xA5,0xA1,0xA5,0xA5,0xA1,
0xA9,0xAD,0x55,0x11,0x11,0x15,0x11,0x15,
0x45,0x01,0x01,0x05,0x01,0x05,0x05,0x01,
0x09,0x0D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x05,0x01,0x05,0x01,0x01,0x05,
0x0D,0x09,0x31,0x35,0x35,0x31,0x35,0x31,
0x21,0x25,0x25,0x21,0x25,0x21,0x21,0x25,
0x2D,0x29,0x35,0x31,0x31,0x35,0x31,0x35,
0x25,0x21,0x21,0x25,0x21,0x25,0x25,0x21,
0x29,0x2D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x05,0x01,0x05,0x01,0x01,0x05,
0x0D,0x09,0x15,0x11,0x11,0x15,0x11,0x15,
0x05,0x01,0x01,0x05,0x01,0x05,0x05,0x01,
0x09,0x0D,0x35,0x31,0x31,0x35,0x31,0x35,
0x04,0x00,0x08,0x0C,0x0C,0x08,0x0C,0x08,
0x08,0x0C,0x10,0x14,0x14,0x10,0x14,0x10,
0x00,0x04,0x0C,0x08,0x08,0x0C,0x08,0x0C,
0x0C,0x08,0x30,0x34,0x34,0x30,0x34,0x30,
0x20,0x24,0x2C,0x28,0x28,0x2C,0x28,0x2C,
0x2C,0x28,0x34,0x30,0x30,0x34,0x30,0x34,
0x24,0x20,0x28,0x2C,0x2C,0x28,0x2C,0x28,
0x28,0x2C,0x10,0x14,0x14,0x10,0x14,0x10,
0x00,0x04,0x0C,0x08,0x08,0x0C,0x08,0x0C,
0x0C,0x08,0x14,0x10,0x10,0x14,0x10,0x14,
0x04,0x00,0x08,0x0C,0x0C,0x08,0x0C,0x08,
0x08,0x0C,0x34,0x30,0x30,0x34,0x30,0x34,
0x24,0x20,0x28,0x2C,0x2C,0x28,0x2C,0x28,
0x28,0x2C,0x30,0x34,0x34,0x30,0x34,0x30,
0x20,0x24,0x2C,0x28,0x28,0x2C,0x28,0x2C,
0x2C,0x28,0x90,0x94,0x94,0x90,0x94,0x90,
0x80,0x84,0x8C,0x88,0x88,0x8C,0x88,0x8C,
0x8C,0x88,0x94,0x90,0x90,0x94,0x90,0x94,
0x84,0x80,0x88,0x8C,0x8C,0x88,0x8C,0x88,
0x88,0x8C,0x55,0x11,0x11,0x15,0x11,0x15,
0x05,0x01,0x09,0x0D,0x0D,0x09,0x0D,0x09,
0x09,0x0D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x0D,0x09,0x09,0x0D,0x09,0x0D,
0x0D,0x09,0x31,0x35,0x35,0x31,0x35,0x31,
0x21,0x25,0x2D,0x29,0x29,0x2D,0x29,0x2D,
0x2D,0x29,0x35,0x31,0x31,0x35,0x31,0x35,
0x25,0x21,0x29,0x2D,0x2D,0x29,0x2D,0x29,
0x29,0x2D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x0D,0x09,0x09,0x0D,0x09,0x0D,
0x0D,0x09,0x15,0x11,0x11,0x15,0x11,0x15,
0x05,0x01,0x09,0x0D,0x0D,0x09,0x0D,0x09,
0x09,0x0D,0x35,0x31,0x31,0x35,0x31,0x35,
0x25,0x21,0x29,0x2D,0x2D,0x29,0x2D,0x29,
0x29,0x2D,0x31,0x35,0x35,0x31,0x35,0x31,
0x21,0x25,0x2D,0x29,0x29,0x2D,0x29,0x2D,
0x2D,0x29,0x91,0x95,0x95,0x91,0x95,0x91,
0x81,0x85,0x8D,0x89,0x89,0x8D,0x89,0x8D,
0x8D,0x89,0x95,0x91,0x91,0x95,0x91,0x95,
0x85,0x81,0x89,0x8D,0x8D,0x89,0x8D,0x89,
0x89,0x8D,0xB5,0xB1,0xB1,0xB5,0xB1,0xB5,
0xA5,0xA1,0xA9,0xAD,0xAD,0xA9,0xAD,0xA9,
0xA9,0xAD,0xB1,0xB5,0xB5,0xB1,0xB5,0xB1,
0xA1,0xA5,0xAD,0xA9,0xA9,0xAD,0xA9,0xAD,
0xAD,0xA9,0x95,0x91,0x91,0x95,0x91,0x95,
0x85,0x81,0x89,0x8D,0x8D,0x89,0x8D,0x89,
0x89,0x8D,0x91,0x95,0x95,0x91,0x95,0x91,
0x81,0x85,0x8D,0x89,0x89,0x8D,0x89,0x8D,
0x8D,0x89,0xB1,0xB5,0xB5,0xB1,0xB5,0xB1,
0xA1,0xA5,0xAD,0xA9,0xA9,0xAD,0xA9,0xAD,
0xAD,0xA9,0xB5,0xB1,0xB1,0xB5,0xB1,0xB5,
0xA5,0xA1,0xA9,0xAD,0xAD,0xA9,0xAD,0xA9,
0xA9,0xAD,0x55,0x11,0x11,0x15,0x11,0x15,
0x05,0x01,0x09,0x0D,0x0D,0x09,0x0D,0x09,
0x09,0x0D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x0D,0x09,0x09,0x0D,0x09,0x0D,
0x0D,0x09,0x31,0x35,0x35,0x31,0x35,0x31,
0x21,0x25,0x2D,0x29,0x29,0x2D,0x29,0x2D,
0x2D,0x29,0x35,0x31,0x31,0x35,0x31,0x35,
0x25,0x21,0x29,0x2D,0x2D,0x29,0x2D,0x29,
0x29,0x2D,0x11,0x15,0x15,0x11,0x15,0x11,
0x01,0x05,0x0D,0x09,0x09,0x0D,0x09,0x0D,
0x0D,0x09,0x15,0x11,0x11,0x15,0x11,0x15,
0x05,0x01,0x09,0x0D,0x0D,0x09,0x0D,0x09,
0x09,0x0D,0x35,0x31,0x31,0x35,0x31,0x35,
0x46,0x02,0x02,0x06,0x02,0x06,0x06,0x02,
0x0A,0x0E,0x02,0x06,0x06,0x02,0x0A,0x0E,
0x02,0x06,0x06,0x02,0x06,0x02,0x02,0x06,
0x0E,0x0A,0x06,0x02,0x02,0x06,0x0E,0x0A,
0x22,0x26,0x26,0x22,0x26,0x22,0x22,0x26,
0x2E,0x2A,0x26,0x22,0x22,0x26,0x2E,0x2A,
0x26,0x22,0x22,0x26,0x22,0x26,0x26,0x22,
0x2A,0x2E,0x22,0x26,0x26,0x22,0x2A,0x2E,
0x02,0x06,0x06,0x02,0x06,0x02,0x02,0x06,
0x0E,0x0A,0x06,0x02,0x02,0x06,0x0E,0x0A,
0x06,0x02,0x02,0x06,0x02,0x06,0x06,0x02,
0x0A,0x0E,0x02,0x06,0x06,0x02,0x0A,0x0E,
0x26,0x22,0x22,0x26,0x22,0x26,0x26,0x22,
0x2A,0x2E,0x22,0x26,0x26,0x22,0x2A,0x2E,
0x22,0x26,0x26,0x22,0x26,0x22,0x22,0x26,
0x2E,0x2A,0x26,0x22,0x22,0x26,0x2E,0x2A,
0x82,0x86,0x86,0x82,0x86,0x82,0x82,0x86,
0x8E,0x8A,0x86,0x82,0x82,0x86,0x8E,0x8A,
0x86,0x82,0x82,0x86,0x82,0x86,0x86,0x82,
0x8A,0x8E,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x03,0x07,0x07,0x03,0x07,0x03,0x03,0x07,
0x0F,0x0B,0x07,0x03,0x03,0x07,0x0F,0x0B,
0x07,0x03,0x03,0x07,0x03,0x07,0x07,0x03,
0x0B,0x0F,0x03,0x07,0x07,0x03,0x0B,0x0F,
0x27,0x23,0x23,0x27,0x23,0x27,0x27,0x23,
0x2B,0x2F,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x23,0x27,0x27,0x23,0x27,0x23,0x23,0x27,
0x2F,0x2B,0x27,0x23,0x23,0x27,0x2F,0x2B,
0x83,0x87,0x87,0x83,0x87,0x83,0x83,0x87,
0x8F,0x8B,0x87,0x83,0x83,0x87,0x8F,0x8B,
0x87,0x83,0x83,0x87,0x83,0x87,0x87,0x83,
0x8B,0x8F,0x83,0x87,0x87,0x83,0x8B,0x8F,
0xA7,0xA3,0xA3,0xA7,0xA3,0xA7,0xA7,0xA3,
0xAB,0xAF,0xA3,0xA7,0xA7,0xA3,0xAB,0xAF,
0xA3,0xA7,0xA7,0xA3,0xA7,0xA3,0xA3,0xA7,
0xAF,0xAB,0xA7,0xA3,0xA3,0xA7,0xAF,0xAB,
0x87,0x83,0x83,0x87,0x83,0x87,0x87,0x83,
0x8B,0x8F,0x83,0x87,0x87,0x83,0x8B,0x8F,
0x83,0x87,0x87,0x83,0x87,0x83,0x83,0x87,
0x8F,0x8B,0x87,0x83,0x83,0x87,0x8F,0x8B,
0xA3,0xA7,0xA7,0xA3,0xA7,0xA3,0xA3,0xA7,
0xAF,0xAB,0xA7,0xA3,0xA3,0xA7,0xAF,0xAB,
0xA7,0xA3,0xA3,0xA7,0xA3,0xA7,0xA7,0xA3,
0xAB,0xAF,0xA3,0xA7,0xA7,0xA3,0xAB,0xAF,
0x47,0x03,0x03,0x07,0x03,0x07,0x07,0x03,
0x0B,0x0F,0x03,0x07,0x07,0x03,0x0B,0x0F,
0x03,0x07,0x07,0x03,0x07,0x03,0x03,0x07,
0x0F,0x0B,0x07,0x03,0x03,0x07,0x0F,0x0B,
0x23,0x27,0x27,0x23,0x27,0x23,0x23,0x27,
0x2F,0x2B,0x27,0x23,0x23,0x27,0x2F,0x2B,
0x27,0x23,0x23,0x27,0x23,0x27,0x27,0x23,
0x2B,0x2F,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x03,0x07,0x07,0x03,0x07,0x03,0x03,0x07,
0x0F,0x0B,0x07,0x03,0x03,0x07,0x0F,0x0B,
0x07,0x03,0x03,0x07,0x03,0x07,0x07,0x03,
0x0B,0x0F,0x03,0x07,0x07,0x03,0x0B,0x0F,
0x27,0x23,0x23,0x27,0x23,0x27,0x27,0x23,
0x2B,0x2F,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x23,0x27,0x27,0x23,0x27,0x23,0x23,0x27,
0x2F,0x2B,0x27,0x23,0x23,0x27,0x2F,0x2B,
0x83,0x87,0x87,0x83,0x87,0x83,0x83,0x87,
0x8F,0x8B,0x87,0x83,0x83,0x87,0x8F,0x8B,
0x87,0x83,0x83,0x87,0x83,0x87,0x87,0x83,
0x8B,0x8F,0x83,0x87,0x87,0x83,0x8B,0x8F,
0xBE,0xBA,0xBE,0xBA,0xBA,0xBE,0x46,0x02,
0x02,0x06,0x02,0x06,0x06,0x02,0x0A,0x0E,
0x1E,0x1A,0x1E,0x1A,0x1A,0x1E,0x02,0x06,
0x06,0x02,0x06,0x02,0x02,0x06,0x0E,0x0A,
0x1A,0x1E,0x1A,0x1E,0x1E,0x1A,0x22,0x26,
0x26,0x22,0x26,0x22,0x22,0x26,0x2E,0x2A,
0x3A,0x3E,0x3A,0x3E,0x3E,0x3A,0x26,0x22,
0x22,0x26,0x22,0x26,0x26,0x22,0x2A,0x2E,
0x3E,0x3A,0x3E,0x3A,0x3A,0x3E,0x02,0x06,
0x06,0x02,0x06,0x02,0x02,0x06,0x0E,0x0A,
0x1A,0x1E,0x1A,0x1E,0x1E,0x1A,0x06,0x02,
0x02,0x06,0x02,0x06,0x06,0x02,0x0A,0x0E,
0x1E,0x1A,0x1E,0x1A,0x1A,0x1E,0x26,0x22,
0x22,0x26,0x22,0x26,0x26,0x22,0x2A,0x2E,
0x3E,0x3A,0x3E,0x3A,0x3A,0x3E,0x22,0x26,
0x26,0x22,0x26,0x22,0x22,0x26,0x2E,0x2A,
0x3A,0x3E,0x3A,0x3E,0x3E,0x3A,0x82,0x86,
0x86,0x82,0x86,0x82,0x82,0x86,0x8E,0x8A,
0x9A,0x9E,0x9A,0x9E,0x9E,0x9A,0x86,0x82,
0x82,0x86,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x3F,0x3B,0x3F,0x3B,0x3B,0x3F,0x03,0x07,
0x07,0x03,0x07,0x03,0x03,0x07,0x0F,0x0B,
0x1B,0x1F,0x1B,0x1F,0x1F,0x1B,0x07,0x03,
0x03,0x07,0x03,0x07,0x07,0x03,0x0B,0x0F,
0x1F,0x1B,0x1F,0x1B,0x1B,0x1F,0x27,0x23,
0x23,0x27,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x3F,0x3B,0x3F,0x3B,0x3B,0x3F,0x23,0x27,
0x27,0x23,0x27,0x23,0x23,0x27,0x2F,0x2B,
0x3B,0x3F,0x3B,0x3F,0x3F,0x3B,0x83,0x87,
0x87,0x83,0x87,0x83,0x83,0x87,0x8F,0x8B,
0x9B,0x9F,0x9B,0x9F,0x9F,0x9B,0x87,0x83,
0x83,0x87,0x83,0x87,0x87,0x83,0x8B,0x8F,
0x9F,0x9B,0x9F,0x9B,0x9B,0x9F,0xA7,0xA3,
0xA3,0xA7,0xA3,0xA7,0xA7,0xA3,0xAB,0xAF,
0xBF,0xBB,0xBF,0xBB,0xBB,0xBF,0xA3,0xA7,
0xA7,0xA3,0xA7,0xA3,0xA3,0xA7,0xAF,0xAB,
0xBB,0xBF,0xBB,0xBF,0xBF,0xBB,0x87,0x83,
0x83,0x87,0x83,0x87,0x87,0x83,0x8B,0x8F,
0x9F,0x9B,0x9F,0x9B,0x9B,0x9F,0x83,0x87,
0x87,0x83,0x87,0x83,0x83,0x87,0x8F,0x8B,
0x9B,0x9F,0x9B,0x9F,0x9F,0x9B,0xA3,0xA7,
0xA7,0xA3,0xA7,0xA3,0xA3,0xA7,0xAF,0xAB,
0xBB,0xBF,0xBB,0xBF,0xBF,0xBB,0xA7,0xA3,
0xA3,0xA7,0xA3,0xA7,0xA7,0xA3,0xAB,0xAF,
0xBF,0xBB,0xBF,0xBB,0xBB,0xBF,0x47,0x03,
0x03,0x07,0x03,0x07,0x07,0x03,0x0B,0x0F,
0x1F,0x1B,0x1F,0x1B,0x1B,0x1F,0x03,0x07,
0x07,0x03,0x07,0x03,0x03,0x07,0x0F,0x0B,
0x1B,0x1F,0x1B,0x1F,0x1F,0x1B,0x23,0x27,
0x27,0x23,0x27,0x23,0x23,0x27,0x2F,0x2B,
0x3B,0x3F,0x3B,0x3F,0x3F,0x3B,0x27,0x23,
0x23,0x27,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x3F,0x3B,0x3F,0x3B,0x3B,0x3F,0x03,0x07,
0x07,0x03,0x07,0x03,0x03,0x07,0x0F,0x0B,
0x1B,0x1F,0x1B,0x1F,0x1F,0x1B,0x07,0x03,
0x03,0x07,0x03,0x07,0x07,0x03,0x0B,0x0F,
0x1F,0x1B,0x1F,0x1B,0x1B,0x1F,0x27,0x23,
0x23,0x27,0x23,0x27,0x27,0x23,0x2B,0x2F,
0x3F,0x3B,0x3F,0x3B,0x3B,0x3F,0x23,0x27,
0x27,0x23,0x27,0x23,0x23,0x27,0x2F,0x2B,
0x3B,0x3F,0x3B,0x3F,0x3F,0x3B,0x83,0x87,
0x87,0x83,0x87,0x83,0x83,0x87,0x8F,0x8B,
0x9B,0x9F,0x9B,0x9F,0x9F,0x9B,0x87,0x83,
0x83,0x87,0x83,0x87,0x87,0x83,0x8B,0x8F
};

View File

@ -0,0 +1,36 @@
/*
* daa.h
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _DAA_H
#define _DAA_H
#include "..\CommonVICE\types.h" // [AppleWin-TC]
extern const BYTE daa_reg_a[];
extern const BYTE daa_reg_f[];
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
/*
* z80.h
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _Z80_H
#define _Z80_H
struct z80_regs_s;
extern struct z80_regs_s z80_regs;
//struct interrupt_cpu_status_s;
//struct alarm_context_s;
extern void z80_reset(void);
//extern void z80_mainloop(struct interrupt_cpu_status_s *cpu_int_status,
// struct alarm_context_s *cpu_alarm_context);
DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles);
//extern void z80_trigger_dma(void);
BYTE z80_RDMEM(WORD Addr);
void z80_WRMEM(WORD Addr, BYTE Value);
#endif

View File

@ -0,0 +1,452 @@
/*
* z80mem.c
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
//#include "vice.h"
#include <stdio.h>
#include <string.h>
//#include "c128mem.h" // [AppleWin-TC]
//#include "c128mmu.h"
//#include "c64cia.h"
//#include "c64io.h"
//#include "cmdline.h"
//#include "log.h"
//#include "mem.h"
//#include "resources.h"
//#include "sid.h"
//#include "sysfile.h"
//#include "types.h"
//#include "vdc-mem.h"
//#include "vdc.h"
//#include "vicii-mem.h"
//#include "vicii.h"
#include "..\CommonVICE\types.h" // [AppleWin-TC]
#include "z80mem.h"
#include "z80.h" // [AppleWin-TC] Added for z80_RDMEM() & z80_WRMEM
/* Z80 boot BIOS. */
BYTE z80bios_rom[0x1000];
/* Logging. */
//static log_t z80mem_log = LOG_ERR; // [AppleWin-TC]
/* Adjust this pointer when the MMU changes banks. */
static BYTE **bank_base;
static int *bank_limit = NULL;
unsigned int z80_old_reg_pc;
/* Pointers to the currently used memory read and write tables. */
read_func_ptr_t *_z80mem_read_tab_ptr;
store_func_ptr_t *_z80mem_write_tab_ptr;
BYTE **_z80mem_read_base_tab_ptr;
int *z80mem_read_limit_tab_ptr;
#define NUM_CONFIGS 8
/* Memory read and write tables. */
static store_func_ptr_t mem_write_tab[NUM_CONFIGS][0x101];
static read_func_ptr_t mem_read_tab[NUM_CONFIGS][0x101];
static BYTE *mem_read_base_tab[NUM_CONFIGS][0x101];
static int mem_read_limit_tab[NUM_CONFIGS][0x101];
store_func_ptr_t io_write_tab[0x101];
read_func_ptr_t io_read_tab[0x101];
//static const resource_int_t resources_int[] = { // [AppleWin-TC]
// { NULL }
//};
//
//int z80mem_resources_init(void)
//{
// return resources_register_int(resources_int);
//}
//
//static const cmdline_option_t cmdline_options[] =
//{
// { NULL }
//};
//
//int z80mem_cmdline_options_init(void)
//{
// return cmdline_register_options(cmdline_options);
//}
/* ------------------------------------------------------------------------- */
/* Generic memory access. */
#if 0
static void REGPARM2 z80mem_store(WORD addr, BYTE value)
{
_z80mem_write_tab_ptr[addr >> 8](addr, value);
}
static BYTE REGPARM1 z80mem_read(WORD addr)
{
return _z80mem_read_tab_ptr[addr >> 8](addr);
}
#endif
BYTE REGPARM1 bios_read(WORD addr)
{
return z80bios_rom[addr & 0x0fff];
}
void REGPARM2 bios_store(WORD addr, BYTE value)
{
z80bios_rom[addr] = value;
}
//static BYTE REGPARM1 z80_read_zero(WORD addr) // [AppleWin-TC]
//{
// return mem_page_zero[addr];
//}
//
//static void REGPARM2 z80_store_zero(WORD addr, BYTE value)
//{
// mem_page_zero[addr] = value;
//}
static BYTE REGPARM1 read_unconnected_io(WORD addr)
{
// log_message(z80mem_log, "Read from unconnected IO %04x", addr); // [AppleWin-TC]
return 0;
}
static void REGPARM2 store_unconnected_io(WORD addr, BYTE value)
{
// log_message(z80mem_log, "Store to unconnected IO %04x %02x", addr, value); // [AppleWin-TC]
}
#ifdef _MSC_VER
#pragma optimize("",off)
#endif
void z80mem_initialize(void)
{
int i, j;
/* Memory addess space. */
for (j = 0; j < NUM_CONFIGS; j++) {
for (i = 0; i <= 0x100; i++) {
mem_read_base_tab[j][i] = NULL;
mem_read_limit_tab[j][i] = -1;
mem_read_tab[j][i] = z80_RDMEM; // [AppleWin-TC]
mem_write_tab[j][i] = z80_WRMEM; // [AppleWin-TC]
}
}
_z80mem_read_tab_ptr = mem_read_tab[0];
_z80mem_write_tab_ptr = mem_write_tab[0];
_z80mem_read_base_tab_ptr = mem_read_base_tab[0];
z80mem_read_limit_tab_ptr = mem_read_limit_tab[0];
/* IO address space. */
/* At least we know what happens. */
for (i = 0; i <= 0x100; i++) {
io_read_tab[i] = read_unconnected_io;
io_write_tab[i] = store_unconnected_io;
}
#if 0 // [AppleWin-TC]
int i, j;
/* Memory addess space. */
for (j = 0; j < NUM_CONFIGS; j++) {
for (i = 0; i <= 0x100; i++) {
mem_read_base_tab[j][i] = NULL;
mem_read_limit_tab[j][i] = -1;
}
}
mem_read_tab[0][0] = bios_read;
mem_write_tab[0][0] = z80_store_zero;
mem_read_tab[1][0] = bios_read;
mem_write_tab[1][0] = z80_store_zero;
mem_read_tab[2][0] = z80_read_zero;
mem_write_tab[2][0] = z80_store_zero;
mem_read_tab[3][0] = z80_read_zero;
mem_write_tab[3][0] = z80_store_zero;
mem_read_tab[4][0] = z80_read_zero;
mem_write_tab[4][0] = z80_store_zero;
mem_read_tab[5][0] = z80_read_zero;
mem_write_tab[5][0] = z80_store_zero;
mem_read_tab[6][0] = z80_read_zero;
mem_write_tab[6][0] = z80_store_zero;
mem_read_tab[7][0] = z80_read_zero;
mem_write_tab[7][0] = z80_store_zero;
mem_read_tab[0][1] = bios_read;
mem_write_tab[0][1] = one_store;
mem_read_tab[1][1] = bios_read;
mem_write_tab[1][1] = one_store;
mem_read_tab[2][1] = one_read;
mem_write_tab[2][1] = one_store;
mem_read_tab[3][1] = one_read;
mem_write_tab[3][1] = one_store;
mem_read_tab[4][1] = one_read;
mem_write_tab[4][1] = one_store;
mem_read_tab[5][1] = one_read;
mem_write_tab[5][1] = one_store;
mem_read_tab[6][1] = one_read;
mem_write_tab[6][1] = one_store;
mem_read_tab[7][1] = one_read;
mem_write_tab[7][1] = one_store;
for (i = 2; i < 0x10; i++) {
mem_read_tab[0][i] = bios_read;
mem_write_tab[0][i] = ram_store;
mem_read_tab[1][i] = bios_read;
mem_write_tab[1][i] = ram_store;
mem_read_tab[2][i] = lo_read;
mem_write_tab[2][i] = lo_store;
mem_read_tab[3][i] = lo_read;
mem_write_tab[3][i] = lo_store;
mem_read_tab[4][i] = ram_read;
mem_write_tab[4][i] = ram_store;
mem_read_tab[5][i] = ram_read;
mem_write_tab[5][i] = ram_store;
mem_read_tab[6][i] = lo_read;
mem_write_tab[6][i] = lo_store;
mem_read_tab[7][i] = lo_read;
mem_write_tab[7][i] = lo_store;
}
for (i = 0x10; i <= 0x13; i++) {
mem_read_tab[0][i] = ram_read;
mem_write_tab[0][i] = ram_store;
mem_read_tab[1][i] = colorram_read;
mem_write_tab[1][i] = colorram_store;
mem_read_tab[2][i] = lo_read;
mem_write_tab[2][i] = lo_store;
mem_read_tab[3][i] = colorram_read;
mem_write_tab[3][i] = colorram_store;
mem_read_tab[4][i] = ram_read;
mem_write_tab[4][i] = ram_store;
mem_read_tab[5][i] = colorram_read;
mem_write_tab[5][i] = colorram_store;
mem_read_tab[6][i] = lo_read;
mem_write_tab[6][i] = lo_store;
mem_read_tab[7][i] = colorram_read;
mem_write_tab[7][i] = colorram_store;
}
for (i = 0x14; i <= 0x3f; i++) {
mem_read_tab[0][i] = ram_read;
mem_write_tab[0][i] = ram_store;
mem_read_tab[1][i] = ram_read;
mem_write_tab[1][i] = ram_store;
mem_read_tab[2][i] = lo_read;
mem_write_tab[2][i] = lo_store;
mem_read_tab[3][i] = lo_read;
mem_write_tab[3][i] = lo_store;
mem_read_tab[4][i] = ram_read;
mem_write_tab[4][i] = ram_store;
mem_read_tab[5][i] = ram_read;
mem_write_tab[5][i] = ram_store;
mem_read_tab[6][i] = lo_read;
mem_write_tab[6][i] = lo_store;
mem_read_tab[7][i] = lo_read;
mem_write_tab[7][i] = lo_store;
}
for (j = 0; j < NUM_CONFIGS; j++) {
for (i = 0x40; i <= 0xbf; i++) {
mem_read_tab[j][i] = ram_read;
mem_write_tab[j][i] = ram_store;
}
}
for (i = 0xc0; i <= 0xcf; i++) {
mem_read_tab[0][i] = ram_read;
mem_write_tab[0][i] = ram_store;
mem_read_tab[1][i] = ram_read;
mem_write_tab[1][i] = ram_store;
mem_read_tab[2][i] = top_shared_read;
mem_write_tab[2][i] = top_shared_store;
mem_read_tab[3][i] = top_shared_read;
mem_write_tab[3][i] = top_shared_store;
mem_read_tab[4][i] = ram_read;
mem_write_tab[4][i] = ram_store;
mem_read_tab[5][i] = ram_read;
mem_write_tab[5][i] = ram_store;
mem_read_tab[6][i] = top_shared_read;
mem_write_tab[6][i] = top_shared_store;
mem_read_tab[7][i] = top_shared_read;
mem_write_tab[7][i] = top_shared_store;
}
for (i = 0xd0; i <= 0xdf; i++) {
mem_read_tab[0][i] = ram_read;
mem_write_tab[0][i] = ram_store;
mem_read_tab[1][i] = ram_read;
mem_write_tab[1][i] = ram_store;
mem_read_tab[2][i] = top_shared_read;
mem_write_tab[2][i] = top_shared_store;
mem_read_tab[3][i] = top_shared_read;
mem_write_tab[3][i] = top_shared_store;
mem_read_tab[4][i] = ram_read;
mem_write_tab[4][i] = ram_store;
mem_read_tab[5][i] = ram_read;
mem_write_tab[5][i] = ram_store;
mem_read_tab[6][i] = top_shared_read;
mem_write_tab[6][i] = top_shared_store;
mem_read_tab[7][i] = top_shared_read;
mem_write_tab[7][i] = top_shared_store;
}
for (i = 0xe0; i <= 0xfe; i++) {
mem_read_tab[0][i] = ram_read;
mem_write_tab[0][i] = ram_store;
mem_read_tab[1][i] = ram_read;
mem_write_tab[1][i] = ram_store;
mem_read_tab[2][i] = top_shared_read;
mem_write_tab[2][i] = top_shared_store;
mem_read_tab[3][i] = top_shared_read;
mem_write_tab[3][i] = top_shared_store;
mem_read_tab[4][i] = ram_read;
mem_write_tab[4][i] = ram_store;
mem_read_tab[5][i] = ram_read;
mem_write_tab[5][i] = ram_store;
mem_read_tab[6][i] = top_shared_read;
mem_write_tab[6][i] = top_shared_store;
mem_read_tab[7][i] = top_shared_read;
mem_write_tab[7][i] = top_shared_store;
}
for (j = 0; j < NUM_CONFIGS; j++) {
mem_read_tab[j][0xff] = mmu_ffxx_read_z80;
mem_write_tab[j][0xff] = mmu_ffxx_store;
mem_read_tab[j][0x100] = mem_read_tab[j][0x0];
mem_write_tab[j][0x100] = mem_write_tab[j][0x0];
}
_z80mem_read_tab_ptr = mem_read_tab[0];
_z80mem_write_tab_ptr = mem_write_tab[0];
_z80mem_read_base_tab_ptr = mem_read_base_tab[0];
z80mem_read_limit_tab_ptr = mem_read_limit_tab[0];
/* IO address space. */
/* At least we know what happens. */
for (i = 0; i <= 0x100; i++) {
io_read_tab[i] = read_unconnected_io;
io_write_tab[i] = store_unconnected_io;
}
/*
io_read_tab[0x10] = colorram_read;
io_write_tab[0x10] = colorram_store;
io_read_tab[0x11] = colorram_read;
io_write_tab[0x11] = colorram_store;
io_read_tab[0x12] = colorram_read;
io_write_tab[0x12] = colorram_store;
io_read_tab[0x13] = colorram_read;
io_write_tab[0x13] = colorram_store;
*/
io_read_tab[0xd0] = vicii_read;
io_write_tab[0xd0] = vicii_store;
io_read_tab[0xd1] = vicii_read;
io_write_tab[0xd1] = vicii_store;
io_read_tab[0xd2] = vicii_read;
io_write_tab[0xd2] = vicii_store;
io_read_tab[0xd3] = vicii_read;
io_write_tab[0xd3] = vicii_store;
io_read_tab[0xd4] = sid_read;
io_write_tab[0xd4] = sid_store;
io_read_tab[0xd5] = mmu_read;
io_write_tab[0xd5] = mmu_store;
io_read_tab[0xd6] = vdc_read;
io_write_tab[0xd6] = vdc_store;
io_read_tab[0xd7] = d7xx_read;
io_write_tab[0xd7] = d7xx_store;
io_read_tab[0xd8] = colorram_read;
io_write_tab[0xd8] = colorram_store;
io_read_tab[0xd9] = colorram_read;
io_write_tab[0xd9] = colorram_store;
io_read_tab[0xda] = colorram_read;
io_write_tab[0xda] = colorram_store;
io_read_tab[0xdb] = colorram_read;
io_write_tab[0xdb] = colorram_store;
io_read_tab[0xdc] = cia1_read;
io_write_tab[0xdc] = cia1_store;
io_read_tab[0xdd] = cia2_read;
io_write_tab[0xdd] = cia2_store;
io_read_tab[0xde] = c64io1_read;
io_write_tab[0xde] = c64io1_store;
io_read_tab[0xdf] = c64io2_read;
io_write_tab[0xdf] = c64io2_store;
#endif
}
#ifdef _MSC_VER
#pragma optimize("",on)
#endif
void z80mem_set_bank_pointer(BYTE **base, int *limit)
{
bank_base = base;
bank_limit = limit;
}
void z80mem_update_config(int config)
{
_z80mem_read_tab_ptr = mem_read_tab[config];
_z80mem_write_tab_ptr = mem_write_tab[config];
_z80mem_read_base_tab_ptr = mem_read_base_tab[config];
z80mem_read_limit_tab_ptr = mem_read_limit_tab[config];
/*
if (bank_limit != NULL) {
*bank_base = _z80mem_read_base_tab_ptr[z80_old_reg_pc >> 8];
if (*bank_base != 0)
*bank_base = _z80mem_read_base_tab_ptr[z80_old_reg_pc >> 8]
- (z80_old_reg_pc & 0xff00);
*bank_limit = z80mem_read_limit_tab_ptr[z80_old_reg_pc >> 8];
}
*/
}
int z80mem_load(void)
{
// if (z80mem_log == LOG_ERR) // [AppleWin-TC]
// z80mem_log = log_open("Z80MEM");
z80mem_initialize();
return 0;
}

View File

@ -0,0 +1,64 @@
/*
* z80mem.h
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _Z80MEM_H
#define _Z80MEM_H
#ifdef WATCOM_COMPILE
#include "../mem.h"
#else
#include "..\CommonVICE\mem.h" // [AppleWin-TC]
#endif
#include "..\CommonVICE\types.h" // [AppleWin-TC]
extern int z80mem_resources_init(void);
extern int z80mem_cmdline_options_init(void);
extern void z80mem_set_bank_pointer(BYTE **base, int *limit);
extern void z80mem_update_config(int config);
extern int z80mem_load(void);
extern BYTE z80bios_rom[0x1000];
extern void z80mem_initialize(void);
/* Pointers to the currently used memory read and write tables. */
extern read_func_ptr_t *_z80mem_read_tab_ptr;
extern store_func_ptr_t *_z80mem_write_tab_ptr;
extern BYTE **_z80mem_read_base_tab_ptr;
extern int *z80mem_read_limit_tab_ptr;
extern BYTE REGPARM1 bios_read(WORD addr);
extern void REGPARM2 bios_store(WORD addr, BYTE value);
extern store_func_ptr_t io_write_tab[];
extern read_func_ptr_t io_read_tab[];
extern unsigned int z80_old_reg_pc;
#endif

View File

@ -0,0 +1,80 @@
/*
* z80regs.h
*
* Written by
* Andreas Boose <viceteam@t-online.de>
*
* This file is part of VICE, the Versatile Commodore Emulator.
* See README for copyright notice.
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA.
*
*/
#ifndef _Z80REGS_H
#define _Z80REGS_H
#include "..\CommonVICE\types.h" // [AppleWin-TC]
typedef struct z80_regs_s {
WORD reg_af;
WORD reg_bc;
WORD reg_de;
WORD reg_hl;
WORD reg_ix;
WORD reg_iy;
WORD reg_sp;
WORD reg_pc;
BYTE reg_i;
BYTE reg_r;
WORD reg_af2;
WORD reg_bc2;
WORD reg_de2;
WORD reg_hl2;
} z80_regs_t;
#define Z80_REGS_GET_AF(reg_ptr) ((reg_ptr)->reg_af)
#define Z80_REGS_GET_BC(reg_ptr) ((reg_ptr)->reg_bc)
#define Z80_REGS_GET_DE(reg_ptr) ((reg_ptr)->reg_de)
#define Z80_REGS_GET_HL(reg_ptr) ((reg_ptr)->reg_hl)
#define Z80_REGS_GET_IX(reg_ptr) ((reg_ptr)->reg_ix)
#define Z80_REGS_GET_IY(reg_ptr) ((reg_ptr)->reg_iy)
#define Z80_REGS_GET_SP(reg_ptr) ((reg_ptr)->reg_sp)
#define Z80_REGS_GET_PC(reg_ptr) ((reg_ptr)->reg_pc)
#define Z80_REGS_GET_I(reg_ptr) ((reg_ptr)->reg_i)
#define Z80_REGS_GET_R(reg_ptr) ((reg_ptr)->reg_r)
#define Z80_REGS_GET_AF2(reg_ptr) ((reg_ptr)->reg_af2)
#define Z80_REGS_GET_BC2(reg_ptr) ((reg_ptr)->reg_bc2)
#define Z80_REGS_GET_DE2(reg_ptr) ((reg_ptr)->reg_de2)
#define Z80_REGS_GET_HL2(reg_ptr) ((reg_ptr)->reg_hl2)
#define Z80_REGS_SET_AF(reg_ptr, val) ((reg_ptr)->reg_af = (val))
#define Z80_REGS_SET_BC(reg_ptr, val) ((reg_ptr)->reg_bc = (val))
#define Z80_REGS_SET_DE(reg_ptr, val) ((reg_ptr)->reg_de = (val))
#define Z80_REGS_SET_HL(reg_ptr, val) ((reg_ptr)->reg_hl = (val))
#define Z80_REGS_SET_IX(reg_ptr, val) ((reg_ptr)->reg_ix = (val))
#define Z80_REGS_SET_IY(reg_ptr, val) ((reg_ptr)->reg_iy = (val))
#define Z80_REGS_SET_SP(reg_ptr, val) ((reg_ptr)->reg_sp = (val))
#define Z80_REGS_SET_PC(reg_ptr, val) ((reg_ptr)->reg_pc = (val))
#define Z80_REGS_SET_I(reg_ptr, val) ((reg_ptr)->reg_i = (val))
#define Z80_REGS_SET_R(reg_ptr, val) ((reg_ptr)->reg_r = (val))
#define Z80_REGS_SET_AF2(reg_ptr, val) ((reg_ptr)->reg_af2 = (val))
#define Z80_REGS_SET_BC2(reg_ptr, val) ((reg_ptr)->reg_bc2 = (val))
#define Z80_REGS_SET_DE2(reg_ptr, val) ((reg_ptr)->reg_de2 = (val))
#define Z80_REGS_SET_HL2(reg_ptr, val) ((reg_ptr)->reg_hl2 = (val))
#endif

View File

@ -13,12 +13,12 @@
// Emula a CPU Z80
#include "..\StdAfx.h"
#include "StdAfx.h"
#include "z80emu.h"
// Variaveis
int CPMZ80Slot = 0;
int Z80_IRQ = 0;
static int CPMZ80Slot = 0;
int Z80_IRQ = 0; // Used by Z80Em
BYTE __stdcall CPMZ80_IONull(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft)
{
@ -37,16 +37,7 @@ BYTE __stdcall CPMZ80_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULO
//===========================================================================
void ConfigureSoftcard(LPBYTE pCxRomPeripheral, int Slot, UINT addOrRemove)
{
//LPBYTE pCxRomPeripheral = MemGetCxRomPeripheral();
//if (pCxRomPeripheral == NULL)
// return;
//UINT uOffset = (m_by6821B << 7) & 0x0700;
//memcpy(pCxRomPeripheral+m_uSlot*256, m_pSlotRom+uOffset, 256);
//if (mem)
// memcpy(mem+0xC000+m_uSlot*256, m_pSlotRom+uOffset, 256);
memset(pCxRomPeripheral + (Slot << 8), 0xFF, 256);
memset(pCxRomPeripheral + (Slot << 8), 0xFF, APPLE_SLOT_SIZE);
CPMZ80Slot = Slot;