// license:BSD-3-Clause
// copyright-holders:Wilbert Pol,Vas Crabb
/*****************************************************************************
*
* includes/osborne1.h
*
****************************************************************************/
#ifndef OSBORNE1_H_
#define OSBORNE1_H_
#include "emu.h"
#include "cpu/z80/z80.h"
#include "sound/speaker.h"
#include "bus/ieee488/ieee488.h"
#include "machine/6821pia.h"
#include "machine/6850acia.h"
#include "machine/ram.h"
#include "machine/wd_fdc.h"
class osborne1_state : public driver_device
{
public:
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */// license:BSD-3-Clause
// copyright-holders:Angelo Salese, Mariusz Wojcieszek
#include "emu.h"
#include "debugger.h"
#include "scudsp.h"
static const char *const ALU_Commands[] =
{
" ", /* 0000 */
"AND ", /* 0001 */
"OR ", /* 0010 */
"XOR ", /* 0011 */
"ADD ", /* 0100 */
"SUB ", /* 0101 */
"AD2 ", /* 0110 */
"ALU?", /* 0111 */
"SR ", /* 1000 */
"RR ", /* 1001 */
"SL ", /* 1010 */
"RL ", /* 1011 */
"ALU?", /* 1100 */
"ALU?", /* 1101 */
"ALU?", /* 1110 */
"RL8 ", /* 1111 */
};
static const char *const X_Commands[] =
{
"", /* 000 */
"", /* 001 */ /* NOP? check instruction @ 0x0B */
"MOV MUL,P", /* 010 */
"MOV %s,P", /* 011 */
"MOV %s,X", /* 100 */
};
static const char *const Y_Commands[] =
{
"", /* 000 */
"CLR A", /* 001 */
"MOV ALU,A", /* 010 */
"MOV %s,A", /* 011 */
"MOV %s,Y", /* 100 */
};
static const char *const D1_Commands[] =
{
"", /* 00 */
"MOV %I8,%d", /* 01 */
"???", /* 10 */
"MOV %S,%d", /* 11 */
};
static const char *const SourceMemory[] =
{
"M0", /* 000 */
"M1", /* 001 */
"M2", /* 010 */
"M3", /* 011 */
"MC0", /* 100 */
"MC1", /* 101 */
"MC2", /* 110 */
"MC3", /* 111 */
};
static const char *const SourceMemory2[] =
{
"M0", /* 0000 */
"M1", /* 0001 */
"M2", /* 0010 */
"M3", /* 0011 */
"MC0", /* 0100 */
"MC1", /* 0101 */
"MC2", /* 0110 */
"MC3", /* 0111 */
"???", /* 1000 */
"ALL", /* 1001 */
"ALH", /* 1010 */
"???", /* 1011 */
"???", /* 1100 */
"???", /* 1101 */
"???", /* 1110 */
"???", /* 1111 */
};
static const char *const DestMemory[] =
{
"MC0", /* 0000 */
"MC1", /* 0001 */
"MC2", /* 0010 */
"MC3", /* 0011 */
"RX", /* 0100 */
"PL", /* 0101 */
"RA0", /* 0110 */
"WA0", /* 0111 */
"???", /* 1000 */
"???", /* 1001 */
"LOP", /* 1010 */
"TOP", /* 1011 */
"CT0", /* 1100 */
"CT1", /* 1101 */
"CT2", /* 1110 */
"CT3", /* 1111 */
};
static const char *const DestDMAMemory[] =
{
"M0", /* 000 */
"M1", /* 001 */
"M2", /* 010 */
"M3", /* 011 */
"PRG", /* 100 */
"???", /* 101 */
"???", /* 110 */
"???", /* 111 */
};
static const char *const MVI_Command[] =
{
"MVI %I,%d", /* 0 */
"MVI %I,%d,%f", /* 1 */
};
static const char *const JMP_Command[] =
{
"JMP %IA",
"JMP %f,%IA",
};
static const char *const DMA_Command[] =
{
"DMA%H%A D0,%M,%I",
"DMA%H%A %s,D0,%I",
"DMA%H%A D0,%M,%s",
"DMA%H%A %s,D0,%s",
};
static void scudsp_dasm_prefix( const char* format, char* buffer, uint32_t *data )
{
for ( ; *format; format++ )
{
if ( *format == '%' )
{
switch( *++format )
{
case 'H':
if ( *data )
{
strcpy( buffer, "H" );
}
else
{
*buffer = 0;
}
break;
case 'A':
if ( *data == 0 )
{
strcpy( buffer, "0" );
}
else if ( *data == 1 )
{
*buffer = 0;
}
else
{
sprintf( buffer, "%d", 1 << (*data - 1) );
}
break;
case 's':
strcpy( buffer, SourceMemory[ *data & 0x7 ] );
break;
case 'd':
strcpy( buffer, DestMemory[ *data & 0xf ] );
break;
case 'S':
strcpy( buffer, SourceMemory2[ *data & 0xf ] );
break;
case 'I':
++format;
if ( *format == '8' )
{
sprintf( buffer, "#$%x", *data );
}
else if ( *format == 'A' )
{
sprintf( buffer, "$%X", *data );
}
else
{
--format;
sprintf( buffer, "#$%X", *data );
}
break;
case 'f':
if ( !(*data & 0x20) )
{
strcpy( buffer, "N" );
buffer++;
}
switch( *data & 0xf )
{
case 0x3:
strcpy( buffer, "ZS" );
break;
case 0x2:
strcpy( buffer, "S" );
break;
case 0x4:
strcpy( buffer, "C" );
break;
case 0x8:
strcpy( buffer, "T0" );
break;
case 0x1:
strcpy( buffer, "Z" );
break;
default:
strcpy( buffer, "?" );
break;
}
break;
case 'M':
strcpy( buffer, DestDMAMemory[ *data ] );
break;
}
data++;
buffer += strlen( buffer );
}
else
{
*buffer++ = *format;
}
}
*buffer = 0;
}
static offs_t internal_disasm_scudsp(cpu_device *device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options)
{
uint32_t op = oprom[0]<<24|oprom[1]<<16|oprom[2]<<8|oprom[3]<<0;
unsigned size = 1;
// const char *sym, *sym2;
char temp_buffer[64];
uint32_t data[4];
switch( op >> 30 )
{
case 0:
if ( (op & 0x3F8E3000) == 0 )
{
util::stream_format(stream, "%-10s", "NOP");
break;
}
/* ALU */
util::stream_format(stream, "%s", ALU_Commands[ (op & 0x3c000000) >> 26]);
/* X-Bus */
data[0] = (op & 0x700000) >> 20;
if ( op & 0x2000000 )
{
scudsp_dasm_prefix( X_Commands[ 4 ], temp_buffer, data );
}
else
{
*temp_buffer = 0;
}
util::stream_format(stream, "%s", temp_buffer);
scudsp_dasm_prefix( X_Commands[ (op & 0x1800000) >> 23 ], temp_buffer, data );
util::stream_format(stream, "%s", temp_buffer);
data[0] = (op & 0x1C000 ) >> 14 ;
if ( op & 0x80000 )
{
scudsp_dasm_prefix( Y_Commands[4], temp_buffer, data );
}
else
{
*temp_buffer = 0;
}
util::stream_format(stream, "%s", temp_buffer);
scudsp_dasm_prefix( Y_Commands[ (op & 0x60000) >> 17 ], temp_buffer, data );
util::stream_format(stream, "%s", temp_buffer);
/* D1-Bus */
switch( (op & 0x3000) >> 12 )
{
case 0x1:
data[0] = (op & 0xFF);
data[1] = ((op & 0xF00) >> 8);
break;
case 0x3:
data[0] = (op & 0xF);
data[1] = ((op & 0xF00) >> 8);
break;
}
scudsp_dasm_prefix( D1_Commands[ (op & 0x3000) >> 12 ], temp_buffer, data);
util::stream_format(stream, "%s", temp_buffer);
break;
case 2:
if ( (op & 0x2000000) )
{
data[0] = op & 0x7FFFF;
data[1] = (op & 0x3C000000) >> 26;
data[2] = (op & 0x3F80000 ) >> 19;
scudsp_dasm_prefix( MVI_Command[1], temp_buffer, data); /* TODO: bad mem*/
stream << temp_buffer;
}
else
{
data[0] = op & 0x1FFFFFF;
data[1] = (op & 0x3C000000) >> 26;
scudsp_dasm_prefix( MVI_Command[0], temp_buffer, data ); /* TODO: bad mem*/
stream << temp_buffer;
}
break;
case 3:
switch((op >> 28) & 3)
{
case 0:
data[0] = (op & 0x4000) >> 14; /* H */
data[1] = (op & 0x38000) >> 15; /* A */
data[2] = (op & 0x700) >> 8; /* Mem */
data[3] = (op & 0xff);
scudsp_dasm_prefix( DMA_Command[(op & 0x3000) >> 12], temp_buffer, data );
stream << temp_buffer;
break;
case 1:
if ( op & 0x3F80000 )
{
data[0] = (op & 0x3F80000) >> 19;
data[1] = op & 0xff;
scudsp_dasm_prefix( JMP_Command[1], temp_buffer, data );
stream << temp_buffer;
}
else
{
data[0] = op & 0xff;
scudsp_dasm_prefix( JMP_Command[0], temp_buffer, data );
stream << temp_buffer;
}
break;
case 2:
stream << (op & 0x8000000 ? "LPS" : "BTM");
break;
case 3:
stream << (op & 0x8000000 ? "ENDI" : "END");
break;
}
break;
default:
stream << "???";
break;
}
return size;
}
CPU_DISASSEMBLE(scudsp)
{
std::ostringstream stream;
offs_t result = internal_disasm_scudsp(device, stream, pc, oprom, opram, options);
std::string stream_str = stream.str();
strcpy(buffer, stream_str.c_str());
return result;
}