summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/hp_dio/hp98620.h
blob: ca6d2ae9da2036e404b6d990e993b85b8be196ed (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
// license:BSD-3-Clause
// copyright-holders:Sven Schnelle

#ifndef MAME_BUS_HPDIO_98620_H
#define MAME_BUS_HPDIO_98620_H

#pragma once

#include "hp_dio.h"


namespace bus {
	namespace hp_dio {

class dio16_98620_device :
		public device_t,
		public device_dio32_card_interface
{
public:
	// construction/destruction
	dio16_98620_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

protected:
	dio16_98620_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);

	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;

	uint16_t dma_r(offs_t offset);
	void dma_w(offs_t offset, uint16_t data);

	DECLARE_WRITE_LINE_MEMBER(irq_w);

private:

	static constexpr int REG0_RESET_ARM_INT = 0x00;
	static constexpr int REG0_ADDRESS_HIGH = 0x00;
	static constexpr int REG0_ADDRESS_LOW = 0x02;
	static constexpr int REG0_TRANSFER_COUNT = 0x04;
	static constexpr int REG0_CONTROL_ARM = 0x06;
	static constexpr int REG0_STATUS = 0x06;

	static constexpr int REG1_RESET_ARM_INT = 0x08;
	static constexpr int REG1_ADDRESS_HIGH = 0x08;
	static constexpr int REG1_ADDRESS_LOW = 0x0a;
	static constexpr int REG1_TRANSFER_COUNT = 0x0c;
	static constexpr int REG1_CONTROL_ARM = 0x0e;
	static constexpr int REG1_STATUS = 0x0e;

	static constexpr uint8_t REG_CONTROL_IE = 1 << 0;
	static constexpr uint8_t REG_CONTROL_WORD = 1 << 1;
	static constexpr uint8_t REG_CONTROL_OUT = 1 << 2;
	static constexpr uint8_t REG_CONTROL_PRI = 1 << 3;
	static constexpr uint8_t REG_CONTROL_INT_MASK = 0x7;
	static constexpr int REG_CONTROL_INT_SHIFT = 4;


	static constexpr uint8_t REG_STATUS_ARMED = 1 << 0;
	static constexpr uint8_t REG_STATUS_INT = 1 << 1;

	/* general control registers */
	static constexpr int REG_1TQ4_ID_LOW = 0x10;
	static constexpr int REG_1TQ4_ID_HIGH = 0x12;
	static constexpr int REG_GENERAL_CONTROL = 0x14;
	static constexpr int REG_GENERAL_CONTROL_RESET0 = 1 << 4;
	static constexpr int REG_GENERAL_CONTROL_RESET1 = 1 << 5;

	/* channel specific registers */
	static constexpr int REG0_1TQ4_ADDRESS_HIGH = 0x100;
	static constexpr int REG0_1TQ4_ADDRESS_LOW = 0x102;
	static constexpr int REG0_1TQ4_TRANSFER_COUNT_HIGH = 0x104;
	static constexpr int REG0_1TQ4_TRANSFER_COUNT_LOW = 0x106;

	static constexpr int REG0_1TQ4_CONTROL = 0x108;
	static constexpr int REG0_1TQ4_STATUS = 0x10a;

	static constexpr uint16_t REG_1TQ4_CONTROL_LWORD = 1 << 8;
	static constexpr uint16_t REG_1TQ4_CONTROL_START = 1 << 15;

	static constexpr uint16_t REG_1TQ4_STATUS_ARMED = 1 << 0;
	static constexpr uint16_t REG_1TQ4_STATUS_INT = 1 << 1;

	/* registers */
	static constexpr int REG1_1TQ4_ADDRESS_HIGH = 0x200;
	static constexpr int REG1_1TQ4_ADDRESS_LOW = 0x202;
	static constexpr int REG1_1TQ4_TRANSFER_COUNT_HIGH = 0x204;
	static constexpr int REG1_1TQ4_TRANSFER_COUNT_LOW = 0x206;

	static constexpr int REG1_1TQ4_CONTROL = 0x208;
	static constexpr int REG1_1TQ4_STATUS = 0x20a;

	WRITE_LINE_MEMBER(dmar0_in) override;
	WRITE_LINE_MEMBER(dmar1_in) override;

	void dma_transfer(int channel);
	void update_irq();
	void update_ctrl(const int channel, const uint16_t data, const bool is_1tq4);
	uint16_t get_ctrl(const int channel);

	bool     m_installed_io;
	uint8_t  m_control;
	uint8_t  m_data;
	bool m_irq_state;

	struct dma_regs {
		uint32_t address = 0;
		uint32_t tc = 0;
		uint32_t control = 0;
		/* control register */
		int irq_level = 0;
		int tsz = 0;
		int subcount = 0;

		bool irq = false;
		bool ie = false;
		bool armed = false;

		bool dma_out = false;
		bool dma_pri = false; // TODO
		bool lword = false;
		bool word = false;
	} m_regs[2];

	bool m_dmar[2];
};

} } // namespace bus::hp_dio

DECLARE_DEVICE_TYPE_NS(HPDIO_98620, bus::hp_dio, dio16_98620_device)

#endif // MAME_BUS_HPDIO_98620_H