blob: 4f4b66097b7c5718b93344a9f36201ad18c95c28 (
plain) (
tree)
|
|
// license:BSD-3-Clause
// copyright-holders:David Haywood
/* Serial Electronic Counter (SEC) */
#include "emu.h"
#include "sec.h"
void SEC::reset(void)
{
m_clk = 1;
m_curbyte = m_clks = n_reqpos = m_rxclk = m_rxlen = m_rxpos = 0;
}
void SEC::write_cs_line(uint8_t bit)
{
if ( bit )
{
if ( !enabled )
{
enabled = true;
m_rxdat = 0;
}
}
else
{
if ( enabled )
{
m_rxdat = 1;
}
enabled = false;
reset();
}
}
void SEC::write_data_line(uint8_t bit)
{
m_data = bit ? 1 : 0;
}
uint8_t SEC::read_data_line(void)
{
return m_rxdat;
}
void SEC::write_clock_line(uint8_t bit)
{
bit = bit ? 1 : 0;
if ( (m_clk ^ bit) & 1 )
{
if ( !bit )
{
m_curbyte = ( m_curbyte << 1 ) | m_data;
if ( m_rxclk == 8 )
{
m_rxclk = 0;
m_rxpos++;
m_rxlen--;
}
if ( m_rxlen )
m_rxdat = (m_reply[m_rxpos] & 0x80) >> 7;
else
m_rxdat = enabled ? 0 : 1;
}
else
{
m_clks++;
if ( m_rxlen )
{
m_reply[m_rxpos] <<= 1;
m_rxclk++;
}
if ( m_clks == 8 )
{
m_clks = 0;
if ( !m_rxlen )
{
m_request[n_reqpos++] = m_curbyte;
if ( chars_left )
{
chars_left--;
if ( !chars_left )
{
n_reqpos--;
Do_Command();
n_reqpos = 0;
}
}
if ( n_reqpos == 3 )
chars_left = m_curbyte + 1;
}
}
}
m_clk = bit;
}
}
void SEC::Do_Command(void)
{
m_last = m_request[1];
switch ( m_request[0] )
{
case SEC_REQUEST_VERSION: Cmd_Get_Ver(); break;
case SEC_REQUEST_STATUS: Cmd_Get_Sta(); break;
case SEC_REQUEST_MARKET: Cmd_Get_Mrk(); break;
case SEC_REQEUST_LAST_ERROR: Cmd_Get_Err(); break;
case SEC_REQUEST_FINGERPRNT: Cmd_Get_Fpr(); break;
case SEC_REQUEST_LAST_CMD: Cmd_Get_Lst(); break;
case SEC_REQUEST_COUNT_VAL: Cmd_Get_Cnt(); break;
case SEC_SET_NUM_COUNTERS: Cmd_Set_Ncn(); break;
case SEC_SET_MARKET: Cmd_Set_Mrk(); break;
case SEC_SET_COUNTER_TXT: Cmd_Set_Txt(); break;
case SEC_COUNT_INC_SMALL: Cmd_Inc_Sml(); break;
case SEC_COUNT_INC_MED: Cmd_Inc_Med(); break;
case SEC_COUNT_INC_LARGE: Cmd_Inc_Lrg(); break;
/* acknowledge these without doing anything */
case SEC_SHOW_TEXT: Cmd_NOP(); break;
case SEC_SHOW_COUNTER_VAL: Cmd_NOP(); break;
case SEC_SHOW_COUNTER_TXT: Cmd_NOP(); break;
case SEC_SHOW_BITPATTERN: Cmd_NOP(); break;
case SEC_COUNT_CYCLE_DISP: Cmd_NOP(); break;
case SEC_STOP_CYCLE: Cmd_NOP(); break;
case SEC_SELF_TEST: Cmd_NOP(); break;
}
}
uint8_t SEC::CalcByteSum(int length)
{
uint8_t csum = 0;
for ( int i = 0; i < 3 + length; i++ )
{
csum += m_reply[i];
}
return csum;
}
void SEC::Cmd_Get_Err(void)
{
m_reply[0] = SEC_DAT;
m_reply[1] = m_last;
m_reply[2] = 1;
m_reply[3] = 0; // Last Error
m_reply[4] = CalcByteSum(1);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 5;
}
void SEC::Cmd_Get_Fpr(void)
{
m_reply[0] = SEC_DAT;
m_reply[1] = m_last;
m_reply[2] = 4;
// fingerprint
m_reply[3] = 0x11;
m_reply[4] = 0x01;
m_reply[5] = 0x00;
m_reply[6] = 0x00;
m_reply[7] = CalcByteSum(4);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 8;
}
void SEC::Cmd_Get_Lst(void)
{
m_reply[0] = SEC_DAT;
m_reply[1] = m_last;
m_reply[2] = 4;
// Last Command (is this really 4 bytes?)
m_reply[3] = m_last;
m_reply[4] = 0x00;
m_reply[5] = 0x00;
m_reply[6] = 0x00;
m_reply[7] = CalcByteSum(4);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 8;
}
void SEC::Cmd_Get_Ver(void)
{
m_reply[0] = SEC_DAT;
m_reply[1] = m_last;
m_reply[2] = 3;
// version
m_reply[3] = '0';
m_reply[4] = '2';
m_reply[5] = 'E';
m_reply[6] = CalcByteSum(3);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 7;
}
void SEC::Cmd_Get_Cnt(void)
{
char temp[10];
sprintf(temp,"%07d0", m_counters[m_request[3]]);
m_reply[0] = SEC_DAT;
m_reply[1] = m_last;
m_reply[2] = 4;
m_reply[3] = ((temp[0] - 0x30) << 4) + (temp[1] - 0x30);
m_reply[4] = ((temp[2] - 0x30) << 4) + (temp[3] - 0x30);
m_reply[5] = ((temp[4] - 0x30) << 4) + (temp[5] - 0x30);
m_reply[6] = ((temp[6] - 0x30) << 4) + (temp[7] - 0x30);
m_reply[7] = CalcByteSum(4);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 8;
}
void SEC::Cmd_Get_Sta(void)
{
m_reply[0] = SEC_DAT;
m_reply[1] = m_last;
m_reply[2] = 1;
m_reply[3] = 0x20; // Status
m_reply[4] = CalcByteSum(1);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 5;
}
void SEC::Cmd_Get_Mrk(void)
{
m_reply[0] = SEC_DAT;
m_reply[1] = m_last;
m_reply[2] = 1;
m_reply[3] = m_market;
m_reply[4] = CalcByteSum(1);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 5;
}
void SEC::Cmd_Set_Ncn(void)
{
m_nocnt = m_request[3];
m_reply[0] = SEC_ACK;
m_reply[1] = m_last;
m_reply[2] = 0;
m_reply[3] = CalcByteSum(0);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 4;
}
void SEC::Cmd_Set_Mrk(void)
{
m_market = m_request[3];
m_reply[0] = SEC_ACK;
m_reply[1] = m_last;
m_reply[2] = 0;
m_reply[3] = CalcByteSum(0);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 4;
}
void SEC::Cmd_Set_Txt(void)
{
char valbuf[8];
uint8_t meter = m_request[3];
memcpy( valbuf, &m_request[4], 7);
valbuf[7] = 0;
strcpy(m_strings[meter], valbuf);
m_reply[0] = SEC_ACK;
m_reply[1] = m_last;
m_reply[2] = 0;
m_reply[3] = CalcByteSum(0);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 4;
}
void SEC::Cmd_Inc_Sml(void)
{
uint8_t meter = m_request[3];
uint8_t value = m_request[4] & 0xf;
m_counters[meter] += value;
m_reply[0] = SEC_ACK;
m_reply[1] = m_last;
m_reply[2] = 0;
m_reply[3] = CalcByteSum(0);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 4;
}
void SEC::Cmd_Inc_Med(void)
{
uint8_t meter = m_request[3];
uint8_t value = m_request[4];
m_counters[meter] += value;
m_reply[0] = SEC_ACK;
m_reply[1] = m_last;
m_reply[2] = 0;
m_reply[3] = CalcByteSum(0);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 4;
}
void SEC::Cmd_Inc_Lrg(void)
{
uint8_t meter = m_request[3];
uint8_t value = m_request[4] + 256 * m_request[5];
m_counters[meter] += value;
m_reply[0] = SEC_ACK;
m_reply[1] = m_last;
m_reply[2] = 0;
m_reply[3] = CalcByteSum(0);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 4;
}
void SEC::Cmd_NOP(void)
{
m_reply[0] = SEC_ACK;
m_reply[1] = m_last;
m_reply[2] = 0;
m_reply[3] = CalcByteSum(0);
m_rxpos = 0;
m_rxclk = 0;
m_rxlen = 4;
}
|