summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine/jvshost.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine/jvshost.c')
-rw-r--r--trunk/src/emu/machine/jvshost.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/jvshost.c b/trunk/src/emu/machine/jvshost.c
new file mode 100644
index 00000000000..438c75b538d
--- /dev/null
+++ b/trunk/src/emu/machine/jvshost.c
@@ -0,0 +1,157 @@
+#include "jvshost.h"
+#include "jvsdev.h"
+
+void jvs_host::add_device(jvs_device *dev)
+{
+ if(first_device)
+ first_device->chain(dev);
+ else
+ first_device = dev;
+}
+
+void jvs_host::device_start()
+{
+ save_item(NAME(send_size));
+ save_item(NAME(recv_size));
+ save_item(NAME(send_buffer));
+ save_item(NAME(recv_buffer));
+ save_item(NAME(recv_is_encoded));
+}
+
+void jvs_host::device_reset()
+{
+ send_size = recv_size = 0;
+ recv_is_encoded = false;
+ memset(send_buffer, 0, sizeof(send_buffer));
+ memset(recv_buffer, 0, sizeof(recv_buffer));
+}
+
+jvs_host::jvs_host(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, type, name, tag, owner, clock)
+{
+ first_device = 0;
+}
+
+void jvs_host::push(UINT8 val)
+{
+ send_buffer[send_size++] = val;
+}
+
+void jvs_host::commit_raw()
+{
+ recv_size = 0;
+ if(!send_size)
+ return;
+
+ // Message must:
+ // - have a non-zero destination in the first byte
+ // - have the message length without the two header bytes but with the checksum byte in the second byte
+ // - have at least one command byte
+ if(send_size < 3 || send_buffer[0] == 0x00 || send_buffer[1] != send_size-1) {
+ logerror("JVS checksum error\n");
+ // "This message is crap" doesn't exist so call it checksum error
+ recv_buffer[0] = 0x00;
+ recv_buffer[1] = 0x02;
+ recv_buffer[2] = 0x03;
+ recv_size = 3;
+
+ } else {
+ if(first_device) {
+ first_device->message(send_buffer[0], send_buffer+2, send_size-2, recv_buffer+2, recv_size);
+ recv_is_encoded = false;
+ if(recv_size) {
+ // Add the reply header, host is always destination 0x00
+ recv_buffer[0] = 0x00;
+ recv_buffer[1] = recv_size+1;
+ recv_size += 2;
+ }
+ } else
+ recv_size = 0;
+ }
+ send_size = 0;
+}
+
+void jvs_host::commit_encoded()
+{
+ recv_size = 0;
+ if(!send_size)
+ return;
+ decode(send_buffer, send_size);
+ commit_raw();
+}
+
+
+void jvs_host::get_raw_reply(const UINT8 *&buffer, UINT32 &size)
+{
+ if(recv_is_encoded) {
+ decode(recv_buffer, recv_size);
+ recv_is_encoded = false;
+ }
+ buffer = recv_buffer;
+ size = recv_size;
+}
+
+void jvs_host::get_encoded_reply(const UINT8 *&buffer, UINT32 &size)
+{
+ if(!recv_is_encoded) {
+ encode(recv_buffer, recv_size);
+ recv_is_encoded = true;
+ }
+ buffer = recv_buffer;
+ size = recv_size;
+}
+
+bool jvs_host::get_presence_line()
+{
+ return first_device != 0;
+}
+
+bool jvs_host::get_address_set_line()
+{
+ return first_device && first_device->get_address_set_line();
+}
+
+
+void jvs_host::encode(UINT8 *buffer, UINT32 &size)
+{
+ if(!size)
+ return;
+ UINT32 add = 1;
+ for(UINT32 i=0; i<size; i++)
+ if(buffer[i] == 0xd0 || buffer[i] == 0xe0)
+ add++;
+ UINT32 nsize = size+add;
+ for(UINT32 i=size; i; i--) {
+ UINT8 t = buffer[i-1];
+ if(t == 0xd0 || t == 0xe0) {
+ buffer[i+add-1] = t-1;
+ buffer[i+add-2] = 0xd0;
+ add--;
+ } else
+ buffer[i+add-1] = t;
+ }
+ buffer[0] = 0xe0;
+ UINT8 sum = 0;
+ for(UINT32 i=1; i<nsize; i++)
+ sum += buffer[i];
+ buffer[nsize++] = sum;
+ size = nsize;
+}
+
+void jvs_host::decode(UINT8 *buffer, UINT32 &size)
+{
+ if(!size)
+ return;
+ UINT32 pos = 0;
+ for(UINT32 i=0; i<size-1; i++) {
+ UINT8 t = buffer[i];
+ if(!i && t == 0xe0)
+ continue;
+ if(t == 0xd0) {
+ i++;
+ t = buffer[i]+1;
+ }
+ buffer[pos++] = t;
+ }
+ size = pos;
+}
+