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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
/*
SCSIBus.h
*/
#pragma once
#ifndef _SCSIBUS_H_
#define _SCSIBUS_H_
#include "machine/scsicb.h"
#include "machine/scsidev.h"
/***************************************************************************
MACROS
***************************************************************************/
#define MCFG_SCSIBUS_ADD(_tag) \
MCFG_DEVICE_ADD(_tag, SCSIBUS, 0)
/***************************************************************************
CONSTANTS
***************************************************************************/
#define SCSI_LINE_SEL 0
#define SCSI_LINE_BSY 1
#define SCSI_LINE_REQ 2
#define SCSI_LINE_ACK 3
#define SCSI_LINE_CD 4
#define SCSI_LINE_IO 5
#define SCSI_LINE_MSG 6
#define SCSI_LINE_RESET 7
// Perhaps thse should be in scsi.h ?
#define SCSI_PHASE_BUS_FREE 8
#define SCSI_PHASE_SELECT 9
#define REQ_DELAY_NS 90
#define ACK_DELAY_NS 90
#define BSY_DELAY_NS 50
#define CMD_BUF_SIZE 32
#define ADAPTEC_BUF_SIZE 1024
// scsidev
#define SCSI_CMD_RECALIBRATE 0x01
#define SCSI_CMD_REQUEST_SENSE 0x03
#define SCSI_CMD_MODE_SELECT 0x15
#define SCSI_CMD_SEND_DIAGNOSTIC 0x1D
#define SCSI_CMD_BUFFER_WRITE 0x3B
#define SCSI_CMD_BUFFER_READ 0x3C
// scsihd
#define SCSI_CMD_FORMAT_UNIT 0x04
#define SCSI_CMD_SEARCH_DATA_EQUAL 0x31
#define SCSI_CMD_READ_DEFECT 0x37
#define IS_COMMAND(cmd) (command[0]==cmd)
#define IS_READ_COMMAND() ((command[0]==0x08) || (command[0]==0x28) || (command[0]==0xa8))
#define IS_WRITE_COMMAND() ((command[0]==0x0a) || (command[0]==0x2a))
#define SET_STATUS_SENSE(stat,sen) { status=(stat); sense=(sen); }
#define FORMAT_UNIT_TIMEOUT 5
//
// Status / Sense data taken from Adaptec ACB40x0 documentation.
//
#define SCSI_STATUS_OK 0x00
#define SCSI_STATUS_CHECK 0x02
#define SCSI_STATUS_EQUAL 0x04
#define SCSI_STATUS_BUSY 0x08
#define SCSI_SENSE_ADDR_VALID 0x80
#define SCSI_SENSE_NO_SENSE 0x00
#define SCSI_SENSE_NO_INDEX 0x01
#define SCSI_SENSE_SEEK_NOT_COMP 0x02
#define SCSI_SENSE_WRITE_FAULT 0x03
#define SCSI_SENSE_DRIVE_NOT_READY 0x04
#define SCSI_SENSE_NO_TRACK0 0x06
#define SCSI_SENSE_ID_CRC_ERROR 0x10
#define SCSI_SENSE_UNCORRECTABLE 0x11
#define SCSI_SENSE_ADDRESS_NF 0x12
#define SCSI_SENSE_RECORD_NOT_FOUND 0x14
#define SCSI_SENSE_SEEK_ERROR 0x15
#define SCSI_SENSE_DATA_CHECK_RETRY 0x18
#define SCSI_SENSE_ECC_VERIFY 0x19
#define SCSI_SENSE_INTERLEAVE_ERROR 0x1A
#define SCSI_SENSE_UNFORMATTED 0x1C
#define SCSI_SENSE_ILLEGAL_COMMAND 0x20
#define SCSI_SENSE_ILLEGAL_ADDRESS 0x21
#define SCSI_SENSE_VOLUME_OVERFLOW 0x23
#define SCSI_SENSE_BAD_ARGUMENT 0x24
#define SCSI_SENSE_INVALID_LUN 0x25
#define SCSI_SENSE_CART_CHANGED 0x28
#define SCSI_SENSE_ERROR_OVERFLOW 0x2C
#define SCSI_SENSE_SIZE 4
struct adaptec_sense_t
{
// parameter list
UINT8 reserved1[3];
UINT8 length;
// descriptor list
UINT8 density;
UINT8 reserved2[4];
UINT8 block_size[3];
// drive parameter list
UINT8 format_code;
UINT8 cylinder_count[2];
UINT8 head_count;
UINT8 reduced_write[2];
UINT8 write_precomp[2];
UINT8 landing_zone;
UINT8 step_pulse_code;
UINT8 bit_flags;
UINT8 sectors_per_track;
};
class scsibus_device : public device_t
{
public:
// construction/destruction
scsibus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
/* SCSI Bus read/write */
UINT8 scsi_data_r();
void scsi_data_w( UINT8 data );
DECLARE_READ8_MEMBER( scsi_data_r );
DECLARE_WRITE8_MEMBER( scsi_data_w );
/* Get/Set lines */
UINT8 get_scsi_line(UINT8 lineno);
void set_scsi_line(UINT8 line, UINT8 state);
DECLARE_READ_LINE_MEMBER( scsi_bsy_r );
DECLARE_READ_LINE_MEMBER( scsi_sel_r );
DECLARE_READ_LINE_MEMBER( scsi_cd_r );
DECLARE_READ_LINE_MEMBER( scsi_io_r );
DECLARE_READ_LINE_MEMBER( scsi_msg_r );
DECLARE_READ_LINE_MEMBER( scsi_req_r );
DECLARE_READ_LINE_MEMBER( scsi_ack_r );
DECLARE_READ_LINE_MEMBER( scsi_rst_r );
DECLARE_WRITE_LINE_MEMBER( scsi_bsy_w );
DECLARE_WRITE_LINE_MEMBER( scsi_sel_w );
DECLARE_WRITE_LINE_MEMBER( scsi_cd_w );
DECLARE_WRITE_LINE_MEMBER( scsi_io_w );
DECLARE_WRITE_LINE_MEMBER( scsi_msg_w );
DECLARE_WRITE_LINE_MEMBER( scsi_req_w );
DECLARE_WRITE_LINE_MEMBER( scsi_ack_w );
DECLARE_WRITE_LINE_MEMBER( scsi_rst_w );
/* Initialisation at machine reset time */
void init_scsibus(int sectorbytes);
protected:
// device-level overrides
virtual void device_start();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
int get_scsi_cmd_len(int cbyte);
UINT8 scsibus_driveno(UINT8 drivesel);
void scsi_change_phase(UINT8 newphase);
void set_scsi_line_now(UINT8 line, UINT8 state);
void set_scsi_line_ack(UINT8 state);
void scsi_in_line_changed(UINT8 line, UINT8 state);
void scsi_out_line_change(UINT8 line, UINT8 state);
void scsi_out_line_change_now(UINT8 line, UINT8 state);
void scsi_out_line_req(UINT8 state);
void scsibus_read_data();
void scsibus_write_data();
int datain_done();
int dataout_done();
void scsibus_exec_command();
void check_process_dataout();
void dump_command_bytes();
void dump_data_bytes(int count);
void dump_bytes(UINT8 *buff, int count);
scsidev_device *devices[8];
scsicb_device *m_scsicb;
UINT8 linestate;
UINT8 last_id;
UINT8 phase;
UINT8 command[CMD_BUF_SIZE];
UINT8 cmd_idx;
UINT8 is_linked;
UINT8 status;
UINT8 sense;
UINT8 buffer[ADAPTEC_BUF_SIZE];
UINT16 data_idx;
int xfer_count;
int bytes_left;
int data_last;
int sectorbytes;
emu_timer *req_timer;
emu_timer *ack_timer;
emu_timer *sel_timer;
emu_timer *dataout_timer;
};
// device type definition
extern const device_type SCSIBUS;
#endif
|