summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/naomim1.cpp
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
committer Miodrag Milanovic <mmicko@gmail.com>2015-11-08 12:56:12 +0100
commit7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch)
treef310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/mame/machine/naomim1.cpp
parenta57b46ae933badd7441ce1644711dbb851e2b504 (diff)
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/mame/machine/naomim1.cpp')
-rw-r--r--src/mame/machine/naomim1.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/mame/machine/naomim1.cpp b/src/mame/machine/naomim1.cpp
new file mode 100644
index 00000000000..84d2db5ecef
--- /dev/null
+++ b/src/mame/machine/naomim1.cpp
@@ -0,0 +1,230 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+#include "emu.h"
+#include "naomim1.h"
+
+const device_type NAOMI_M1_BOARD = &device_creator<naomi_m1_board>;
+
+DEVICE_ADDRESS_MAP_START(submap, 16, naomi_m1_board)
+ AM_RANGE(0x0a, 0x0b) AM_READ(actel_id_r)
+
+ AM_INHERIT_FROM(naomi_board::submap)
+ADDRESS_MAP_END
+
+naomi_m1_board::naomi_m1_board(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : naomi_board(mconfig, NAOMI_M1_BOARD, "Sega NAOMI M1 Board", tag, owner, clock, "naomi_m1_board", __FILE__)
+{
+}
+
+READ16_MEMBER(naomi_m1_board::actel_id_r)
+{
+ if (rombdid_tag && memregion(rombdid_tag) != NULL)
+ {
+ const UINT8 *bdid = memregion(rombdid_tag)->base();
+ return bdid[0] | (bdid[1] << 8);
+ }
+
+ return 0x0000;
+}
+
+void naomi_m1_board::device_start()
+{
+ naomi_board::device_start();
+
+ std::string skey = parameter("key");
+ if(!skey.empty())
+ key = strtoll(skey.c_str(), 0, 16);
+ else
+ {
+ logerror("%s: Warning: key not provided\n", tag());
+ key = 0;
+ }
+
+ buffer = auto_alloc_array(machine(), UINT8, BUFFER_SIZE);
+
+ save_pointer(NAME(buffer), BUFFER_SIZE);
+ save_item(NAME(dict));
+ save_item(NAME(hist));
+ save_item(NAME(rom_cur_address));
+ save_item(NAME(buffer_actual_size));
+ save_item(NAME(avail_bits));
+ save_item(NAME(encryption));
+ save_item(NAME(stream_ended));
+ save_item(NAME(has_history));
+}
+
+void naomi_m1_board::device_reset()
+{
+ naomi_board::device_reset();
+ encryption = false;
+ rom_cur_address = 0;
+ buffer_actual_size = 0;
+ has_history = false;
+ stream_ended = false;
+
+ memset(dict, 0, sizeof(dict));
+ memset(hist, 0, sizeof(hist));
+
+ avail_val = 0;
+ avail_bits = 0;
+}
+
+void naomi_m1_board::board_setup_address(UINT32 address, bool is_dma)
+{
+ rom_cur_address = address & 0x1fffffff;
+ encryption = (!(address & 0x20000000)) && is_dma;
+
+ if(encryption) {
+ enc_reset();
+ enc_fill();
+ }
+}
+
+void naomi_m1_board::board_get_buffer(UINT8 *&base, UINT32 &limit)
+{
+ if(encryption) {
+ base = buffer;
+ limit = BUFFER_SIZE;
+
+ } else {
+ base = m_region->base() + rom_cur_address;
+ limit = m_region->bytes() - rom_cur_address;
+ }
+}
+
+void naomi_m1_board::board_advance(UINT32 size)
+{
+ if(encryption) {
+ if(size < buffer_actual_size) {
+ memmove(buffer, buffer + size, buffer_actual_size - size);
+ buffer_actual_size -= size;
+ } else {
+ hist[0] = buffer[buffer_actual_size-2];
+ hist[1] = buffer[buffer_actual_size-1];
+ has_history = true;
+ buffer_actual_size = 0;
+ }
+ enc_fill();
+
+ } else
+ rom_cur_address += size;
+}
+
+UINT32 naomi_m1_board::get_decrypted_32b()
+{
+ UINT8 *base = m_region->base() + rom_cur_address;
+ UINT8 a = base[0];
+ UINT8 b = base[1];
+ UINT8 c = base[2];
+ UINT8 d = base[3];
+
+ rom_cur_address += 4;
+
+ UINT32 res = key ^ (((b^d) << 24) | ((a^c) << 16) | (b << 8) | a);
+ return res;
+}
+
+void naomi_m1_board::gb_reset()
+{
+ avail_val = 0;
+ avail_bits = 0;
+}
+
+inline UINT32 naomi_m1_board::lookb(int bits)
+{
+ if(bits > avail_bits) {
+ avail_val = (avail_val << 32) | get_decrypted_32b();
+ avail_bits += 32;
+ }
+ return (avail_val >> (avail_bits - bits)) & ((1 << bits)-1);
+}
+
+inline void naomi_m1_board::skipb(int bits)
+{
+ avail_bits -= bits;
+}
+
+inline UINT32 naomi_m1_board::getb(int bits)
+{
+ UINT32 res = lookb(bits);
+ skipb(bits);
+ return res;
+}
+
+void naomi_m1_board::enc_reset()
+{
+ gb_reset();
+ stream_ended = false;
+ has_history = false;
+ buffer_actual_size = 0;
+
+ for(int i=0; i<111; i++)
+ dict[i] = getb(8);
+}
+
+void naomi_m1_board::wb(UINT8 byte)
+{
+ if(dict[0] & 64)
+ if(buffer_actual_size < 2)
+ if(has_history)
+ buffer[buffer_actual_size] = hist[buffer_actual_size] - byte;
+ else
+ buffer[buffer_actual_size] = byte;
+ else
+ buffer[buffer_actual_size] = buffer[buffer_actual_size-2] - byte;
+ else
+ buffer[buffer_actual_size] = byte;
+
+ buffer_actual_size++;
+}
+
+void naomi_m1_board::enc_fill()
+{
+ while(buffer_actual_size < BUFFER_SIZE && !stream_ended) {
+ switch(lookb(3)) {
+ // 00+2 - 0000+esc
+ case 0: case 1: {
+ skipb(2);
+ int addr = getb(2);
+ if(addr)
+ wb(dict[addr]);
+ else
+ wb(getb(8));
+ break;
+ }
+
+ // 010+2
+ case 2:
+ skipb(3);
+ wb(dict[getb(2)+4]);
+ break;
+
+ // 011+3
+ case 3:
+ skipb(3);
+ wb(dict[getb(3)+8]);
+ break;
+
+ // 10+5
+ case 4: case 5:
+ skipb(2);
+ wb(dict[getb(5)+16]);
+ break;
+
+ // 11+6
+ case 6: case 7: {
+ skipb(2);
+ int addr = getb(6)+48;
+ if(addr == 111)
+ stream_ended = true;
+ else
+ wb(dict[addr]);
+ break;
+ }
+ }
+ }
+
+ while(buffer_actual_size < BUFFER_SIZE)
+ buffer[buffer_actual_size++] = 0;
+}