summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/akiko.h
blob: 49e2623adbe41eaff75cee8491d7c7377f5bac2b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// license:BSD-3-Clause
// copyright-holders:Mariusz Wojcieszek
/***************************************************************************

    Akiko

    Used in the Amiga CD32

    - CD-ROM controller
    - Builtin 1KB NVRAM
    - Chunky to planar converter

***************************************************************************/

#ifndef MAME_MACHINE_AKIKO_H
#define MAME_MACHINE_AKIKO_H

#pragma once

#include "cdrom.h"
#include "sound/cdda.h"


//**************************************************************************
//  INTERFACE CONFIGURATION MACROS
//**************************************************************************

#define MCFG_AKIKO_ADD(_tag) \
	MCFG_DEVICE_ADD(_tag, AKIKO, 0)

#define MCFG_AKIKO_MEM_READ_CB(_devcb) \
	downcast<akiko_device &>(*device).set_mem_r_callback(DEVCB_##_devcb);

#define MCFG_AKIKO_MEM_WRITE_CB(_devcb) \
	downcast<akiko_device &>(*device).set_mem_w_callback(DEVCB_##_devcb);

#define MCFG_AKIKO_INT_CB(_devcb) \
	downcast<akiko_device &>(*device).set_int_w_callback(DEVCB_##_devcb);

#define MCFG_AKIKO_SCL_HANDLER(_devcb) \
	downcast<akiko_device &>(*device).set_scl_handler(DEVCB_##_devcb);

#define MCFG_AKIKO_SDA_READ_HANDLER(_devcb) \
	downcast<akiko_device &>(*device).set_sda_read_handler(DEVCB_##_devcb);

#define MCFG_AKIKO_SDA_WRITE_HANDLER(_devcb) \
	downcast<akiko_device &>(*device).set_sda_write_handler(DEVCB_##_devcb);


//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> akiko_device

class akiko_device : public device_t
{
public:
	akiko_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	// callbacks
	template <class Object> devcb_base &set_mem_r_callback(Object &&cb) { return m_mem_r.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_mem_w_callback(Object &&cb) { return m_mem_w.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_int_w_callback(Object &&cb) { return m_int_w.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_scl_handler(Object &&cb) { return m_scl_w.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_sda_read_handler(Object &&cb) { return m_sda_r.set_callback(std::forward<Object>(cb)); }
	template <class Object> devcb_base &set_sda_write_handler(Object &&cb) { return m_sda_w.set_callback(std::forward<Object>(cb)); }

	DECLARE_READ32_MEMBER( read );
	DECLARE_WRITE32_MEMBER( write );

protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_stop() override;
	virtual void device_reset() override;
	virtual void device_add_mconfig(machine_config &config) override;

private:
	// 1X CDROM sector time in msec (300KBps)
	static constexpr int CD_SECTOR_TIME = (1000/((150*1024)/2048));

	// chunky to planar converter
	uint32_t m_c2p_input_buffer[8];
	uint32_t m_c2p_output_buffer[8];
	uint32_t m_c2p_input_index;
	uint32_t m_c2p_output_index;

	// i2c bus
	int m_i2c_scl_out;
	int m_i2c_scl_dir;
	int m_i2c_sda_out;
	int m_i2c_sda_dir;

	// cdrom
	uint32_t m_cdrom_status[2];
	uint32_t m_cdrom_address[2];
	uint32_t m_cdrom_track_index;
	uint32_t m_cdrom_lba_start;
	uint32_t m_cdrom_lba_end;
	uint32_t m_cdrom_lba_cur;
	uint16_t m_cdrom_readmask;
	uint16_t m_cdrom_readreqmask;
	uint32_t m_cdrom_dmacontrol;
	uint32_t m_cdrom_numtracks;
	uint8_t m_cdrom_speed;
	uint8_t m_cdrom_cmd_start;
	uint8_t m_cdrom_cmd_end;
	uint8_t m_cdrom_cmd_resp;

	cdda_device *m_cdda;
	cdrom_file *m_cdrom;

	std::unique_ptr<uint8_t[]> m_cdrom_toc;

	emu_timer *m_dma_timer;
	emu_timer *m_frame_timer;

	int m_cdrom_is_device;

	void nvram_write(uint32_t data);
	uint32_t nvram_read();

	uint8_t mem_r8(offs_t offset);
	void mem_w8(offs_t offset, uint8_t data);

	void c2p_write(uint32_t data);
	uint32_t c2p_read();

	void cdda_stop();
	void cdda_play(uint32_t lba, uint32_t num_blocks);
	void cdda_pause(int pause);
	uint8_t cdda_getstatus(uint32_t *lba);
	void set_cd_status(uint32_t status);

	TIMER_CALLBACK_MEMBER( frame_proc );
	TIMER_CALLBACK_MEMBER( dma_proc );

	void start_dma();
	void setup_response( int len, uint8_t *r1 );

	TIMER_CALLBACK_MEMBER( cd_delayed_cmd );
	void update_cdrom();

	// interface
	devcb_read16 m_mem_r;
	devcb_write16 m_mem_w;
	devcb_write_line m_int_w;
	devcb_write_line m_scl_w;
	devcb_read_line m_sda_r;
	devcb_write_line m_sda_w;
};

// device type definition
DECLARE_DEVICE_TYPE(AKIKO, akiko_device)

#endif // MAME_MACHINE_AKIKO_H