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
|
/*
SCSIBus.h
*/
#pragma once
#ifndef _SCSIBUS_H_
#define _SCSIBUS_H_
#include "machine/scsicb.h"
#include "machine/scsihle.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
#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_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 FORMAT_UNIT_TIMEOUT 5
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 );
/* Get/Set lines */
UINT8 get_scsi_line(UINT8 lineno);
void set_scsi_line(UINT8 line, UINT8 state);
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();
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);
scsihle_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 buffer[ADAPTEC_BUF_SIZE];
UINT16 data_idx;
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
|