1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 #ifndef MAME_MACHINE_315_5881_CRYPT_H
4 #define MAME_MACHINE_315_5881_CRYPT_H
5 
6 #pragma once
7 
8 
9 typedef device_delegate<uint16_t (uint32_t)> sega_m2_read_delegate;
10 
DECLARE_DEVICE_TYPE(SEGA315_5881_CRYPT,sega_315_5881_crypt_device)11 DECLARE_DEVICE_TYPE(SEGA315_5881_CRYPT, sega_315_5881_crypt_device)
12 
13 
14 class sega_315_5881_crypt_device :  public device_t
15 {
16 public:
17 	// construction/destruction
18 	sega_315_5881_crypt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
19 
20 	uint16_t ready_r();
21 	void subkey_le_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
22 	void subkey_be_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
23 	void addrlo_w(uint16_t data);
24 	void addrhi_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
25 	uint16_t decrypt_le_r();
26 	uint16_t decrypt_be_r();
27 
28 	void iomap_64be(address_map &map);
29 	void iomap_le(address_map &map);
30 
31 	uint16_t do_decrypt(uint8_t *&base);
32 	void set_addr_low(uint16_t data);
33 	void set_addr_high(uint16_t data);
34 	void set_subkey(uint16_t data);
35 
36 	sega_m2_read_delegate m_read;
37 
38 	template <typename... T> void set_read_cb(T &&... args) { m_read.set(std::forward<T>(args)...); }
39 
40 protected:
41 	virtual void device_start() override;
42 	virtual void device_reset() override;
43 
44 private:
45 
46 	bool first_read;
47 
48 	enum {
49 //        BUFFER_SIZE = 32768, LINE_SIZE = 512,
50 		BUFFER_SIZE = 2, LINE_SIZE = 512,  // this should be a stream, without any 'BUFFER_SIZE' ? I guess the SH4 DMA implementation isn't on a timer tho?
51 		FLAG_COMPRESSED = 0x20000
52 	};
53 
54 	uint32_t key;
55 
56 	std::unique_ptr<uint8_t[]> buffer;
57 	std::unique_ptr<uint8_t[]> line_buffer;
58 	std::unique_ptr<uint8_t[]> line_buffer_prev;
59 	uint32_t prot_cur_address;
60 	uint16_t subkey, dec_hist;
61 	uint32_t dec_header;
62 
63 	bool enc_ready;
64 
65 	int buffer_pos, line_buffer_pos, line_buffer_size, buffer_bit, buffer_bit2;
66 	uint8_t buffer2[2];
67 	uint16_t buffer2a;
68 
69 	int block_size;
70 	int block_pos;
71 	int block_numlines;
72 	int done_compression;
73 
74 	struct sbox {
75 		uint8_t table[64];
76 		int inputs[6];      // positions of the inputs bits, -1 means no input except from key
77 		int outputs[2];     // positions of the output bits
78 	};
79 
80 	static const sbox fn1_sboxes[4][4];
81 	static const sbox fn2_sboxes[4][4];
82 
83 	static const int FN1GK = 38;
84 	static const int FN2GK = 32;
85 	static const int fn1_game_key_scheduling[FN1GK][2];
86 	static const int fn2_game_key_scheduling[FN2GK][2];
87 	static const int fn1_sequence_key_scheduling[20][2];
88 	static const int fn2_sequence_key_scheduling[16];
89 	static const int fn2_middle_result_scheduling[16];
90 
91 	static const uint8_t trees[9][2][32];
92 
93 	int feistel_function(int input, const struct sbox *sboxes, uint32_t subkeys);
94 	uint16_t block_decrypt(uint32_t game_key, uint16_t sequence_key, uint16_t counter, uint16_t data);
95 
96 	uint16_t get_decrypted_16();
97 	int get_compressed_bit();
98 
99 	void enc_start();
100 	void enc_fill();
101 	void line_fill();
102 
103 };
104 
105 #endif // MAME_MACHINE_315_5881_CRYPT_H
106