16 #include "cbmcopy_int.h"
20 static const unsigned char turboread1541[] = {
21 #include "turboread1541.inc"
24 static const unsigned char turboread1571[] = {
25 #include "turboread1571.inc"
28 static const unsigned char turboread1581[] = {
29 #include "turboread1581.inc"
32 static const unsigned char turbowrite1541[] = {
33 #include "turbowrite1541.inc"
36 static const unsigned char turbowrite1571[] = {
37 #include "turbowrite1571.inc"
40 static const unsigned char turbowrite1581[] = {
41 #include "turbowrite1581.inc"
49 static struct _transfers
52 const char *name, *abbrev;
56 { &cbmcopy_s1_transfer,
"auto",
"a%1" },
57 { &cbmcopy_s1_transfer,
"serial1",
"s1" },
58 { &cbmcopy_s2_transfer,
"serial2",
"s2" },
59 { &cbmcopy_pp_transfer,
"parallel",
"p%" },
60 { &cbmcopy_std_transfer,
"original",
"o%" },
64 static int check_drive_type(
CBM_FILE fd,
unsigned char drive,
66 cbmcopy_message_cb msg_cb)
72 if(
cbm_identify( fd, drive, &settings->drive_type, &type_str ))
74 msg_cb( sev_warning,
"could not identify drive, using no turbo" );
78 msg_cb( sev_info,
"identified a %s drive", type_str );
85 static int send_turbo(
CBM_FILE fd,
unsigned char drive,
int write,
87 const unsigned char *turbo,
size_t turbo_size,
88 const unsigned char *start_cmd,
size_t cmd_len,
89 cbmcopy_message_cb msg_cb)
93 trf = transfers[settings->transfer_mode].trf;
98 if(trf->exit_turbo != NULL)
102 cbm_upload( fd, drive, 0x500, turbo, turbo_size );
103 msg_cb( sev_debug,
"uploading %d bytes turbo code", turbo_size );
104 if(trf->upload_turbo(fd, drive, settings->drive_type, write) == 0)
107 msg_cb( sev_debug,
"initializing transfer code" );
108 if(trf->start_turbo(fd, write) == 0)
110 msg_cb( sev_debug,
"done" );
115 msg_cb( sev_fatal,
"could not start turbo" );
121 msg_cb( sev_debug,
"no turbo code upload is required", turbo_size );
123 trf->upload_turbo(fd, drive, settings->drive_type, write);
124 trf->start_turbo(fd, write);
130 msg_cb( sev_fatal,
"Unsupported transfer mode for this device" );
136 static int cbmcopy_read(
CBM_FILE fd,
139 int track,
int sector,
142 unsigned char **filedata,
143 size_t *filedata_size,
144 cbmcopy_message_cb msg_cb,
145 cbmcopy_status_cb status_cb)
151 unsigned char buf[48];
152 const unsigned char *turbo;
159 msg_cb( sev_debug,
"using transfer mode '%s'",
160 transfers[settings->transfer_mode].name);
161 trf = transfers[settings->transfer_mode].trf;
163 if(check_drive_type( fd, drive, settings, msg_cb ))
168 switch(settings->drive_type)
171 turbo = turboread1541;
172 turbo_size =
sizeof(turboread1541);
177 turbo = turboread1571;
178 turbo_size =
sizeof(turboread1571);
181 turbo = turboread1581;
182 turbo_size =
sizeof(turboread1581);
185 msg_cb( sev_warning,
"*** unknown drive type" );
196 if(transfers[settings->transfer_mode].abbrev[0] ==
'o')
208 cbm_open( fd, drive, SA_READ, NULL, 0 );
209 if(cbmname_len == 0) cbmname_len = strlen( cbmname );
216 cbm_open( fd, drive, SA_READ,
"#", 1 );
222 msg_cb( sev_fatal,
"could not open file for reading: %s", buf );
231 msg_cb( sev_debug,
"start read at %d/%d", track, sector );
233 sprintf( (
char*)buf,
"U4:%c%c", (
unsigned char)track, (
unsigned char)sector );
235 SETSTATEDEBUG((
void)0);
236 if(send_turbo(fd, drive, 0, settings,
237 turbo, turbo_size, buf, 5, msg_cb) == 0)
239 msg_cb( sev_debug,
"start of copy" );
240 status_cb( blocks_read );
252 SETSTATEDEBUG(DebugBlockCount=0);
254 while( (error = trf->check_error(fd, 0)) == 0 )
256 SETSTATEDEBUG((
void)0);
259 SETSTATEDEBUG(DebugBlockCount++);
267 *filedata = realloc(*filedata, *filedata_size + 254);
268 SETSTATEDEBUG((
void)0);
272 i = trf->read_blk( fd, (*filedata) + blocks_read * 254, 254, msg_cb);
273 msg_cb( sev_debug,
"number of bytes read for block %d: %d", blocks_read, i );
275 SETSTATEDEBUG((
void)0);
308 *filedata_size += 254;
311 SETSTATEDEBUG((
void)0);
312 status_cb( ++blocks_read );
316 SETSTATEDEBUG((
void)0);
320 msg_cb( sev_debug,
"done" );
321 SETSTATEDEBUG(DebugBlockCount=-1);
322 trf->exit_turbo( fd, 0 );
323 SETSTATEDEBUG((
void)0);
336 SETSTATEDEBUG((
void)0);
341 msg_cb( sev_warning,
"file copy ended with error status: %s", buf );
350 char *cbmcopy_get_transfer_modes()
352 const struct _transfers *t;
358 for(t = transfers; t->name; t++)
360 size += (strlen(t->name) + 1);
368 for(t = transfers; t->name; t++)
370 strcpy(dst, t->name);
371 dst += (strlen(t->name) + 1);
380 int cbmcopy_get_transfer_mode_index(
const char *name)
382 const struct _transfers *t;
393 tm_len = strlen(name);
394 for(i = 0, t = transfers; t->name; i++, t++)
396 if(strcmp(name, t->name) == 0)
401 if(t->abbrev[strlen(t->abbrev)-1] ==
'%')
403 abbrev_len = strlen(t->abbrev) - 1;
404 if(abbrev_len <= tm_len && strncmp(t->name, name, tm_len) == 0)
411 if(strcmp(name, t->abbrev) == 0)
420 int cbmcopy_check_auto_transfer_mode(
CBM_FILE cbm_fd,
int auto_transfermode,
int drive)
423 assert(strcmp(transfers[0].name,
"auto") == 0);
425 if (auto_transfermode == 0)
429 unsigned char testdrive;
442 return cbmcopy_get_transfer_mode_index(
"parallel");
450 if (
cbm_identify(cbm_fd, (
unsigned char)drive, &device_type, NULL) == 0)
461 return cbmcopy_get_transfer_mode_index(
"original");
476 for (testdrive = 4; testdrive < 31; ++testdrive)
479 if (testdrive == drive)
482 if (
cbm_identify(cbm_fd, testdrive, &device_type, NULL) == 0)
487 return cbmcopy_get_transfer_mode_index(
"serial1");
495 return cbmcopy_get_transfer_mode_index(
"serial2");
498 return auto_transfermode;
510 settings->transfer_mode = 0;
522 const unsigned char *filedata,
524 cbmcopy_message_cb msg_cb,
525 cbmcopy_status_cb status_cb)
530 unsigned char drive = (
unsigned char) drivei;
532 unsigned char buf[48];
533 const unsigned char *turbo;
537 msg_cb( sev_debug,
"using transfer mode `%s'",
538 transfers[settings->transfer_mode].name);
539 trf = transfers[settings->transfer_mode].trf;
541 if(check_drive_type( fd, drive, settings, msg_cb ))
546 switch(settings->drive_type)
549 turbo = turbowrite1541;
550 turbo_size =
sizeof(turbowrite1541);
555 turbo = turbowrite1571;
556 turbo_size =
sizeof(turbowrite1571);
559 turbo = turbowrite1581;
560 turbo_size =
sizeof(turbowrite1581);
563 msg_cb( sev_warning,
"*** unknown drive type" );
574 if(transfers[settings->transfer_mode].abbrev[0] ==
'o')
581 cbm_open( fd, drive, SA_WRITE, NULL, 0 );
582 if(cbmname_len == 0) cbmname_len = strlen( cbmname );
589 msg_cb( sev_fatal,
"could not open file for writing: %s", buf );
596 SETSTATEDEBUG((
void)0);
597 if(send_turbo(fd, drive, 1, settings,
598 turbo, turbo_size, (
unsigned char*)
"U4:", 3, msg_cb) == 0)
600 msg_cb( sev_debug,
"start of copy" );
601 status_cb( blocks_written );
613 SETSTATEDEBUG(DebugBlockCount=0);
615 while( filedata_size > 0 )
618 i = filedata_size <= 254 ? filedata_size : 255;
620 SETSTATEDEBUG(DebugBlockCount++);
623 i = trf->write_blk( fd, filedata, (
unsigned char)i, msg_cb );
624 if ( (i != 254) && (i != filedata_size) )
632 SETSTATEDEBUG((
void)0);
633 if ( trf->check_error( fd, 1 ) != 0 )
652 status_cb( ++blocks_written );
653 SETSTATEDEBUG((
void)0);
655 filedata_size -= 254;
658 msg_cb( sev_debug,
"done" );
660 SETSTATEDEBUG((
void)0);
661 trf->exit_turbo( fd, 1 );
662 SETSTATEDEBUG((
void)0);
667 msg_cb( sev_warning,
"file copy ended with error status: %s", buf );
676 int cbmcopy_read_file_ts(
CBM_FILE fd,
679 int track,
int sector,
680 unsigned char **filedata,
681 size_t *filedata_size,
682 cbmcopy_message_cb msg_cb,
683 cbmcopy_status_cb status_cb)
685 return cbmcopy_read(fd, settings, (
unsigned char) drive,
688 filedata, filedata_size,
699 unsigned char **filedata,
700 size_t *filedata_size,
701 cbmcopy_message_cb msg_cb,
702 cbmcopy_status_cb status_cb)
704 return cbmcopy_read(fd, settings, (
unsigned char) drive,
706 cbmname, cbmname_len,
707 filedata, filedata_size,
734 int write_block_generic(
CBM_FILE HandleDevice,
const void *data,
unsigned char size, write_byte_t wb_func, cbmcopy_message_cb msg_cb)
737 const unsigned char *pbuffer = data;
739 SETSTATEDEBUG((
void)0);
740 #ifdef LIBCBMCOPY_DEBUG
741 msg_cb( sev_debug,
"send byte count: %d", size );
743 if ( (pbuffer == NULL) || (wb_func( HandleDevice, size ) != 0) )
748 SETSTATEDEBUG(DebugByteCount=0);
754 #ifdef LIBCBMCOPY_DEBUG
755 msg_cb( sev_debug,
"send block data" );
759 SETSTATEDEBUG(DebugByteCount++);
760 if ( wb_func( HandleDevice, *(pbuffer++) ) != 0 )
769 SETSTATEDEBUG(DebugByteCount=-1);
796 int read_block_generic(
CBM_FILE HandleDevice,
void *data,
size_t size, read_byte_t rb_func, cbmcopy_message_cb msg_cb)
800 unsigned char *pbuffer = data;
802 SETSTATEDEBUG((
void)0);
804 c = rb_func( HandleDevice );
805 SETSTATEDEBUG((
void)0);
806 #ifdef LIBCBMCOPY_DEBUG
807 msg_cb( sev_debug,
"received byte count: %d", c );
817 if( (pbuffer == NULL) || (c > size) )
826 SETSTATEDEBUG(DebugByteCount=0);
827 #ifdef LIBCBMCOPY_DEBUG
828 msg_cb( sev_debug,
"receive block data (%d)", c );
832 SETSTATEDEBUG(DebugByteCount++);
833 *(pbuffer++) = rb_func( HandleDevice );
838 SETSTATEDEBUG(DebugByteCount=-1);
int CBMAPIDECL cbm_identify_xp1541(CBM_FILE HandleDevice, unsigned char DeviceAddress, enum cbm_device_type_e *CbmDeviceType, enum cbm_cable_type_e *CableType)
Identify the cable connected to a specific floppy drive.
int CBMAPIDECL cbm_listen(CBM_FILE HandleDevice, unsigned char DeviceAddress, unsigned char SecondaryAddress)
Send a LISTEN on the IEC serial bus.
int CBMAPIDECL cbm_device_status(CBM_FILE HandleDevice, unsigned char DeviceAddress, void *Buffer, size_t BufferLength)
Read the drive status from a floppy.
int CBMAPIDECL cbm_close(CBM_FILE HandleDevice, unsigned char DeviceAddress, unsigned char SecondaryAddress)
Close a file on the IEC serial bus.
int CBMAPIDECL cbm_raw_write(CBM_FILE HandleDevice, const void *Buffer, size_t Count)
Write data to the IEC serial bus.
int CBMAPIDECL cbm_unlisten(CBM_FILE HandleDevice)
Send an UNLISTEN on the IEC serial bus.
int CBMAPIDECL cbm_open(CBM_FILE HandleDevice, unsigned char DeviceAddress, unsigned char SecondaryAddress, const void *Filename, size_t FilenameLength)
Open a file on the IEC serial bus.
int CBMAPIDECL cbm_exec_command(CBM_FILE HandleDevice, unsigned char DeviceAddress, const void *Command, size_t Size)
Executes a command in the floppy drive.
int CBMAPIDECL cbm_identify(CBM_FILE HandleDevice, unsigned char DeviceAddress, enum cbm_device_type_e *CbmDeviceType, const char **CbmDeviceString)
Identify the connected floppy drive.
Define makros and functions which account for differences between the different architectures.
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.