summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/isa/omti8621.h
blob: 0308b61eee6e54f02262642271609031f38a299d (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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// license:BSD-3-Clause
// copyright-holders:Hans Ostermeyer,R. Belmont
/*
 * omti8621.h - SMS OMTI 8621 disk controller
 *
 *  Created on: August 30, 2010
 *      Author: Hans Ostermeyer
 *
 *  Converted to ISA device March 3, 2014 by R. Belmont
 *
 */

#ifndef MAME_BUS_ISA_OMTI8621_H
#define MAME_BUS_ISA_OMTI8621_H

#pragma once

#include "isa.h"
#include "machine/upd765.h"
#include "imagedev/floppy.h"

/***************************************************************************
 FUNCTION PROTOTYPES
 ***************************************************************************/

class omti_disk_image_device;

/* ----- device interface ----- */

class omti8621_device : public device_t, public device_isa16_card_interface
{
public:
	uint16_t read(offs_t offset, uint16_t mem_mask = 0xffff);
	void write(offs_t offset, uint16_t data, uint16_t mem_mask = 0xffff);

	static void set_verbose(int on_off);

protected:
	static constexpr unsigned OMTI_MAX_LUN = 1;
	static constexpr unsigned CDB_SIZE = 10;

	omti8621_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;
	virtual const tiny_rom_entry *device_rom_region() const override;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
	virtual void device_add_mconfig(machine_config &config) override;
	virtual ioport_constructor device_input_ports() const override;

	virtual uint8_t dack_r(int line) override;
	virtual void dack_w(int line, uint8_t data) override;
	virtual void dack_line_w(int line, int state) override;
	virtual void eop_w(int state) override;

	void set_interrupt(enum line_state line_state);

	required_device<upd765a_device> m_fdc;
	optional_device_array<floppy_connector, 2> m_floppy;
	required_ioport m_iobase;
	required_ioport m_biosopts;

	omti_disk_image_device *our_disks[OMTI_MAX_LUN+1];

	std::string cpu_context() const;

private:
	DECLARE_WRITE_LINE_MEMBER( fdc_irq_w );
	DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
	DECLARE_FLOPPY_FORMATS( floppy_formats );

	void fd_moten_w(uint8_t data);
	void fd_rate_w(uint8_t data);
	void fd_extra_w(uint8_t data);
	uint8_t fd_disk_chg_r();

	void fdc_map(address_map &map);

	uint16_t jumper;

	uint8_t omti_state;

	uint8_t status_port;
	uint8_t config_port;
	uint8_t mask_port;

	// command descriptor block
	uint8_t command_buffer[CDB_SIZE];
	int command_length;
	int command_index;
	int command_status;

	// data buffer
	std::vector<uint8_t> sector_buffer;
	uint8_t *data_buffer;
	int data_length;
	int data_index;

	// sense data
	uint8_t sense_data[4];

	// these are used only to satisfy dex
	uint32_t diskaddr_ecc_error;
	uint32_t diskaddr_format_bad_track;
	uint8_t alternate_track_buffer[4];
	uint32_t alternate_track_address[2];

	emu_timer *m_timer;

	uint8_t m_moten;

	bool m_installed;

	void clear_sense_data();
	void set_sense_data(uint8_t code, const uint8_t * cdb);
	void set_configuration_data(uint8_t lun);
	uint8_t get_lun(const uint8_t * cdb);
	uint8_t check_disk_address(const uint8_t *cdb);
	uint32_t get_disk_track(const uint8_t * cdb);
	uint32_t get_disk_address(const uint8_t * cdb);
	void set_data_transfer(uint8_t *data, uint16_t length);
	void read_sectors_from_disk(int32_t diskaddr, uint8_t count, uint8_t lun);
	void write_sectors_to_disk(int32_t diskaddr, uint8_t count, uint8_t lun);
	void copy_sectors(int32_t dst_addr, int32_t src_addr, uint8_t count, uint8_t lun);
	void format_track(const uint8_t * cdb);
	void set_esdi_defect_list(uint8_t lun, uint8_t head);

	template <typename Format, typename... Params> void logerror(Format &&fmt, Params &&... args) const;

	void log_command(const uint8_t cdb[], const uint16_t cdb_length);
	void log_data();
	void do_command(const uint8_t cdb[], const uint16_t cdb_length);
	uint8_t get_command_length(uint8_t command_byte);
	uint16_t get_data();
	void set_data(uint16_t data);
	void set_jumper(uint16_t disk_type);
	uint8_t read8(offs_t offset);
	void write8(offs_t offset, uint8_t data);
};

/* ----- omti8621 for PC device interface ----- */

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

DECLARE_DEVICE_TYPE(ISA16_OMTI8621, omti8621_pc_device)

/* ----- omti8621 for apollo device interface ----- */

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

	// get sector diskaddr of logical unit lun into data_buffer
	uint32_t get_sector(int32_t diskaddr, uint8_t *data_buffer, uint32_t length, uint8_t lun);

protected:
	virtual void device_add_mconfig(machine_config &config) override;
	virtual const tiny_rom_entry *device_rom_region() const override;
};

DECLARE_DEVICE_TYPE(ISA16_OMTI8621_APOLLO, omti8621_apollo_device)

//###############################################################

#endif // MAME_BUS_ISA_OMTI8621_H