summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine/scsidev.c
blob: 3e816e7090355161b87c9d08a754eca031c2ac7a (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
/***************************************************************************

 scsidev.c - Base class for scsi devices.

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

#include "scsidev.h"

typedef struct
{
	UINT8 command[16];
	int commandLength;
	int phase;
} SCSIDev;

static int scsidev_exec_command( SCSIInstance *scsiInstance, UINT8 *statusCode )
{
	UINT8 *command;
	int commandLength;
//  SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );
	SCSIGetCommand( scsiInstance, &command, &commandLength );

	switch( command[ 0 ] )
	{
		case 0x00: // TEST UNIT READY
			SCSISetPhase( scsiInstance, SCSI_PHASE_STATUS );
			return 0;

		default:
			logerror( "%08x: SCSIDEV unknown command %02x\n", activecpu_get_pc(), command[ 0 ] );
			return 0;
	}
}

static void scsidev_read_data( SCSIInstance *scsiInstance, UINT8 *data, int dataLength )
{
	UINT8 *command;
	int commandLength;
//  SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );
	SCSIGetCommand( scsiInstance, &command, &commandLength );

	switch( command[ 0 ] )
	{
		default:
			logerror( "%08x: SCSIDEV unknown read %02x\n", activecpu_get_pc(), command[ 0 ] );
			break;
	}
}

static void scsidev_write_data( SCSIInstance *scsiInstance, UINT8 *data, int dataLength )
{
	UINT8 *command;
	int commandLength;
//  SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );
	SCSIGetCommand( scsiInstance, &command, &commandLength );

	switch( command[ 0 ] )
	{
		default:
			logerror( "%08x: SCSIDEV unknown write %02x\n", activecpu_get_pc(), command[ 0 ] );
			break;
	}
}

static void scsidev_set_phase( SCSIInstance *scsiInstance, int phase )
{
	SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );
	our_this->phase = phase;
}

static int scsidev_get_phase( SCSIInstance *scsiInstance )
{
	SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );
	return our_this->phase;
}

static void scsidev_set_command( SCSIInstance *scsiInstance, void *command, int commandLength )
{
	SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );

	if( commandLength > sizeof( our_this->command ) )
	{
		/// TODO: output an error.
		return;
	}

	memcpy( our_this->command, command, commandLength );
	our_this->commandLength = commandLength;

	SCSISetPhase( scsiInstance, SCSI_PHASE_COMMAND );
}

static int scsidev_get_command( SCSIInstance *scsiInstance, void **command )
{
	SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );
	*command = our_this->command;
	return our_this->commandLength;
}

static void scsidev_alloc_instance( SCSIInstance *scsiInstance, int diskId )
{
	SCSIDev *our_this = SCSIThis( &SCSIClassDevice, scsiInstance );

	state_save_register_item_array( "scsidev", diskId, our_this->command );
	state_save_register_item( "scsidev", diskId, our_this->commandLength );
	state_save_register_item( "scsidev", diskId, our_this->phase );
}

static int scsidev_dispatch( int operation, void *file, INT64 intparm, void *ptrparm )
{
	switch( operation )
	{
		case SCSIOP_EXEC_COMMAND:
			return scsidev_exec_command( file, ptrparm );

		case SCSIOP_READ_DATA:
			scsidev_read_data( file, ptrparm, intparm );
			break;

		case SCSIOP_WRITE_DATA:
			scsidev_write_data( file, ptrparm, intparm );
			break;

		case SCSIOP_SET_PHASE:
			scsidev_set_phase( file, intparm );
			return 0;

		case SCSIOP_GET_PHASE:
			return scsidev_get_phase( file );

		case SCSIOP_SET_COMMAND:
			scsidev_set_command( file, ptrparm, intparm );
			return 0;

		case SCSIOP_GET_COMMAND:
			return scsidev_get_command( file, ptrparm );

		case SCSIOP_ALLOC_INSTANCE:
			*((SCSIInstance **) ptrparm) = SCSIMalloc( file );
			scsidev_alloc_instance( *((SCSIInstance **) ptrparm), intparm );
			return 0;

		case SCSIOP_DELETE_INSTANCE:
			free( file );
			return 0;
	}
	return 0;
}

const SCSIClass SCSIClassDevice =
{
	NULL,
	scsidev_dispatch,
	sizeof( SCSIDev )
};