OpenCBM
libcbmcopy/pp.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version
5  * 2 of the License, or (at your option) any later version.
6  *
7  * Copyright 2001 Michael Klein <michael(dot)klein(at)puffin(dot)lb(dot)shuttle(dot)de>
8  * Copyright 2008 Spiro Trikaliotis
9  */
10 
11 #include "opencbm.h"
12 #include "cbmcopy_int.h"
13 
14 #include <stdlib.h>
15 
16 #include "arch.h"
17 
18 #include "opencbm-plugin.h"
19 
21 
23 
24 static const unsigned char ppr1541[] = {
25 #include "ppr-1541.inc"
26 };
27 
28 static const unsigned char ppr1571[] = {
29 #include "ppr-1571.inc"
30 };
31 
32 static const unsigned char ppw1541[] = {
33 #include "ppw-1541.inc"
34 };
35 
36 static const unsigned char ppw1571[] = {
37 #include "ppw-1571.inc"
38 };
39 
40 
41 static struct drive_prog
42 {
43  const unsigned char *prog;
44  size_t size;
45 } drive_progs[] =
46 {
47  { ppr1541, sizeof(ppr1541) },
48  { ppw1541, sizeof(ppw1541) },
49  { ppr1571, sizeof(ppr1571) },
50  { ppw1571, sizeof(ppw1571) }
51 };
52 
53 static int write_byte(CBM_FILE,unsigned char);
54 static unsigned char read_byte(CBM_FILE);
55 
76 static int write_blk(CBM_FILE HandleDevice, const void *Buffer, unsigned char Count, cbmcopy_message_cb msg_cb)
77 {
79  {
80 #ifdef LIBCBMCOPY_DEBUG
81  msg_cb( sev_debug, "send byte count: %d", Count );
82 #endif
83  SETSTATEDEBUG((void)0);
84  if ( (Buffer == NULL) || (opencbm_plugin_pp_cc_write_n( HandleDevice, &Count, 1 ) != 1) )
85  {
86  return -1;
87  }
88  SETSTATEDEBUG((void)0);
89 
90  if( Count == 0xff )
91  {
92  Count--;
93  }
94 
95 #ifdef LIBCBMCOPY_DEBUG
96  msg_cb( sev_debug, "send block data" );
97 #endif
98  return opencbm_plugin_pp_cc_write_n( HandleDevice, Buffer, Count );
99  }
100  else
101  {
102  SETSTATEDEBUG((void)0);
103  /* call generic byte oriented block handler */
104  return write_block_generic(HandleDevice, Buffer, Count, &write_byte, msg_cb);
105  }
106 }
107 
127 static int read_blk(CBM_FILE HandleDevice, void *Buffer, size_t Count, cbmcopy_message_cb msg_cb)
128 {
129  unsigned char c;
130  int rv = 0;
131 
133  {
134  SETSTATEDEBUG((void)0);
135  /* get the number of bytes that need to be transferred for this block */
136  if( opencbm_plugin_pp_cc_read_n(HandleDevice, &c, 1) != 1 )
137  {
138  return -1;
139  }
140 #ifdef LIBCBMCOPY_DEBUG
141  msg_cb( sev_debug, "received byte count: %d", c );
142 #endif
143  SETSTATEDEBUG((void)0);
144  rv = c;
145 
146  if( c == 0xff )
147  {
148  /* this is a flag that further bytes are following, so get a full block of 254 bytes */
149  c--;
150  }
151  if( (Buffer == NULL) || (c > Count) )
152  {
153  /* If the block size if greater than the available buffer, return with
154  * a fatal error since the turbo handlers always need to transfer a
155  * complete block. If there is no buffer allocated at all, fail also.
156  */
157  return -1;
158  }
159 #ifdef LIBCBMCOPY_DEBUG
160  msg_cb( sev_debug, "receive block data (%d)", c );
161 #endif
162  return (opencbm_plugin_pp_cc_read_n(HandleDevice, Buffer, c) != c )? -1 : rv;
163  /* (drive is busy now) */
164  }
165  else
166  {
167  /* call generic byte oriented block handler */
168  return read_block_generic(HandleDevice, Buffer, Count, &read_byte, msg_cb);
169  }
170 }
171 
172 static int write_byte(CBM_FILE fd, unsigned char c)
173 {
174  SETSTATEDEBUG((void)0);
175  cbm_pp_write(fd, c);
176  SETSTATEDEBUG((void)0);
178  SETSTATEDEBUG((void)0);
179 #ifndef USE_CBM_IEC_WAIT
180  while(cbm_iec_get(fd, IEC_DATA));
181 #else
182  cbm_iec_wait(fd, IEC_DATA, 0);
183 #endif
184 
185  SETSTATEDEBUG((void)0);
186  cbm_iec_set(fd, IEC_CLOCK);
187  SETSTATEDEBUG((void)0);
188 #ifndef USE_CBM_IEC_WAIT
189  while(!cbm_iec_get(fd, IEC_DATA));
190 #else
191  cbm_iec_wait(fd, IEC_DATA, 1);
192 #endif
193 
194  SETSTATEDEBUG((void)0);
195  return 0;
196 }
197 
198 static unsigned char read_byte(CBM_FILE fd)
199 {
200  unsigned char c;
201  SETSTATEDEBUG((void)0);
203  SETSTATEDEBUG((void)0);
204 #ifndef USE_CBM_IEC_WAIT
205  while(cbm_iec_get(fd, IEC_DATA));
206 #else
207  cbm_iec_wait(fd, IEC_DATA, 0);
208 #endif
209  SETSTATEDEBUG((void)0);
210  c = cbm_pp_read(fd);
211  SETSTATEDEBUG((void)0);
212  cbm_iec_set(fd, IEC_CLOCK);
213  SETSTATEDEBUG((void)0);
214 #ifndef USE_CBM_IEC_WAIT
215  while(!cbm_iec_get(fd, IEC_DATA));
216 #else
217  cbm_iec_wait(fd, IEC_DATA, 1);
218 #endif
219 
220  SETSTATEDEBUG((void)0);
221  return c;
222 }
223 
224 static int check_error(CBM_FILE fd, int write)
225 {
226  int error;
227 
228  SETSTATEDEBUG((void)0);
230  SETSTATEDEBUG((void)0);
231  cbm_iec_wait(fd, IEC_DATA, 0);
232  SETSTATEDEBUG((void)0);
233  error = cbm_iec_get(fd, IEC_CLOCK) == 0;
234  if(!error)
235  {
236  SETSTATEDEBUG((void)0);
237  cbm_iec_set(fd, IEC_DATA);
238  SETSTATEDEBUG((void)0);
239  cbm_iec_wait(fd, IEC_CLOCK, 0);
240  SETSTATEDEBUG((void)0);
242  SETSTATEDEBUG((void)0);
243  cbm_iec_set(fd, IEC_CLOCK);
244  }
245 
246  SETSTATEDEBUG((void)0);
247  return error;
248 }
249 
250 static int upload_turbo(CBM_FILE fd, unsigned char drive,
251  enum cbm_device_type_e drive_type, int write)
252 {
253  const struct drive_prog *p;
254  int dt;
255 
256  opencbm_plugin_pp_cc_read_n = cbm_get_plugin_function_address("opencbm_plugin_pp_cc_read_n");
257 
258  opencbm_plugin_pp_cc_write_n = cbm_get_plugin_function_address("opencbm_plugin_pp_cc_write_n");
259 
260  switch(drive_type)
261  {
262  case cbm_dt_cbm1541:
263  dt = 0;
264  break;
265 
266  case cbm_dt_cbm1570:
267  case cbm_dt_cbm1571:
268  dt = 1;
269  break;
270 
271  default:
272  return -1;
273  }
274 
275  p = &drive_progs[dt * 2 + (write != 0)];
276 
277  SETSTATEDEBUG((void)0);
278  cbm_upload(fd, drive, 0x680, p->prog, p->size);
279  SETSTATEDEBUG((void)0);
280  return 0;
281 }
282 
283 static int start_turbo(CBM_FILE fd, int write)
284 {
285  SETSTATEDEBUG((void)0);
286  cbm_iec_wait(fd, IEC_DATA, 1);
287  SETSTATEDEBUG((void)0);
288  return 0;
289 }
290 
291 static void exit_turbo(CBM_FILE fd, int write)
292 {
293  SETSTATEDEBUG((void)0);
294 // cbm_iec_wait(fd, IEC_DATA, 0);
295  SETSTATEDEBUG((void)0);
296 
298 
300 }
301 
302 DECLARE_TRANSFER_FUNCS(pp_transfer);
int CBMAPIDECL opencbm_plugin_pp_cc_read_n_t(CBM_FILE HandleDevice, unsigned char *data, unsigned int size)
read a block of data from the OpenCBM backend with protocol parallel/cbmcopy
unsigned char CBMAPIDECL cbm_pp_read(CBM_FILE HandleDevice)
Read a byte from a XP1541/XP1571 cable.
Definition: cbm.c:1244
int CBMAPIDECL opencbm_plugin_pp_cc_write_n(CBM_FILE HandleDevice, const unsigned char *data, unsigned int size)
Write data with parallel protocol (cbmcopy)
Plugin DLL interface.
int CBMAPIDECL opencbm_plugin_pp_cc_write_n_t(CBM_FILE HandleDevice, const unsigned char *data, unsigned int size)
write a block of data to the OpenCBM backend with protocol parallel/cbmcopy
#define IEC_DATA
Definition: opencbm.h:97
void CBMAPIDECL cbm_iec_set(CBM_FILE HandleDevice, int Line)
Activate a line on the IEC serial bus.
Definition: cbm.c:1341
int CBMAPIDECL cbm_iec_get(CBM_FILE HandleDevice, int Line)
Get the (logical) state of a line on the IEC serial bus.
Definition: cbm.c:1477
#define CBM_FILE
Definition: opencbm.h:87
void CBMAPIDECL cbm_iec_release(CBM_FILE HandleDevice, int Line)
Deactivate a line on the IEC serial bus.
Definition: cbm.c:1372
Definition: cbmctrl.c:1340
int CBMAPIDECL opencbm_plugin_pp_cc_read_n(CBM_FILE HandleDevice, unsigned char *data, unsigned int size)
Read data with parallel protocol (cbmcopy)
int CBMAPIDECL cbm_iec_wait(CBM_FILE HandleDevice, int Line, int State)
Wait for a line to have a specific state.
Definition: cbm.c:1448
cbm_device_type_e
Definition: opencbm.h:114
DLL interface for accessing the driver.
Define makros and functions which account for differences between the different architectures.
void *CBMAPIDECL cbm_get_plugin_function_address(const char *Functionname)
Get the function pointer for a function in a plugin.
Definition: cbm.c:2449
int CBMAPIDECL cbm_upload(CBM_FILE HandleDevice, unsigned char DeviceAddress, int DriveMemAddress, const void *Program, size_t Size)
Upload a program into a floppy's drive memory.
Definition: upload.c:133
void CBMAPIDECL cbm_pp_write(CBM_FILE HandleDevice, unsigned char Byte)
Write a byte to a XP1541/XP1571 cable.
Definition: cbm.c:1282
#define IEC_CLOCK
Definition: opencbm.h:98