34 |
|
#include "C64.h" |
35 |
|
#include "main.h" |
36 |
|
|
37 |
+ |
#define DEBUG 0 |
38 |
+ |
#include "debug.h" |
39 |
+ |
|
40 |
|
|
41 |
|
// Channel modes (IRC users listen up :-) |
42 |
|
enum { |
199 |
|
|
200 |
|
uint8 ImageDrive::Open(int channel, const uint8 *name, int name_len) |
201 |
|
{ |
202 |
+ |
D(bug("ImageDrive::Open channel %d, file %s\n", channel, name)); |
203 |
+ |
|
204 |
|
set_error(ERR_OK); |
205 |
|
|
206 |
|
// Channel 15: execute file name as command |
242 |
|
if (plain_name_len > 16) |
243 |
|
plain_name_len = 16; |
244 |
|
|
245 |
+ |
D(bug(" plain name %s, type %d, mode %d\n", plain_name, type, mode)); |
246 |
+ |
|
247 |
|
// Channel 0 is READ, channel 1 is WRITE |
248 |
|
if (channel == 0 || channel == 1) { |
249 |
|
mode = channel ? FMODE_WRITE : FMODE_READ; |
276 |
|
if (find_first_file(plain_name, plain_name_len, dir_track, dir_sector, entry)) { |
277 |
|
|
278 |
|
// File exists |
279 |
+ |
D(bug(" file exists, dir track %d, sector %d, entry %d\n", dir_track, dir_sector, entry)); |
280 |
|
ch[channel].dir_track = dir_track; |
281 |
|
ch[channel].dir_sector = dir_sector; |
282 |
|
ch[channel].entry = entry; |
342 |
|
} else { |
343 |
|
|
344 |
|
// File doesn't exist |
345 |
+ |
D(bug(" file not found\n")); |
346 |
+ |
|
347 |
|
// Set file type to SEQ if not specified in file name |
348 |
|
if (type == FTYPE_DEL) |
349 |
|
type = FTYPE_SEQ; |
366 |
|
|
367 |
|
uint8 ImageDrive::open_file_ts(int channel, int track, int sector) |
368 |
|
{ |
369 |
+ |
D(bug("open_file_ts track %d, sector %d\n", track, sector)); |
370 |
+ |
|
371 |
|
// Allocate buffer and set channel mode |
372 |
|
int buf = alloc_buffer(-1); |
373 |
|
if (buf == -1) { |
393 |
|
|
394 |
|
uint8 ImageDrive::create_file(int channel, const uint8 *name, int name_len, int type, bool overwrite) |
395 |
|
{ |
396 |
+ |
D(bug("create_file %s, type %d\n", name, type)); |
397 |
+ |
|
398 |
|
// Allocate buffer |
399 |
|
int buf = alloc_buffer(-1); |
400 |
|
if (buf == -1) { |
421 |
|
return ST_OK; |
422 |
|
} |
423 |
|
ch[channel].num_blocks = 1; |
424 |
+ |
D(bug(" first data block on track %d, sector %d\n", ch[channel].track, ch[channel].sector)); |
425 |
|
|
426 |
|
// Write directory entry |
427 |
|
memset(de, 0, SIZEOF_DE); |
644 |
|
|
645 |
|
uint8 ImageDrive::Close(int channel) |
646 |
|
{ |
647 |
+ |
D(bug("ImageDrive::Close channel %d\n", channel)); |
648 |
+ |
|
649 |
|
switch (ch[channel].mode) { |
650 |
|
case CHMOD_FREE: |
651 |
|
break; |
672 |
|
// Write last data block |
673 |
|
ch[channel].buf[0] = 0; |
674 |
|
ch[channel].buf[1] = ch[channel].buf_len - 1; |
675 |
+ |
D(bug(" writing last data block\n")); |
676 |
|
if (!write_sector(ch[channel].track, ch[channel].sector, ch[channel].buf)) |
677 |
|
goto free; |
678 |
|
|
690 |
|
de[DE_OVR_TRACK] = de[DE_OVR_SECTOR] = 0; |
691 |
|
} |
692 |
|
write_sector(ch[channel].dir_track, ch[channel].dir_sector, dir); |
693 |
+ |
D(bug(" directory entry updated\n")); |
694 |
|
} |
695 |
|
free: free_buffer(ch[channel].buf_num); |
696 |
|
ch[channel].buf = NULL; |
729 |
|
|
730 |
|
uint8 ImageDrive::Read(int channel, uint8 &byte) |
731 |
|
{ |
732 |
+ |
// D(bug("ImageDrive::Read channel %d\n", channel)); |
733 |
+ |
|
734 |
|
switch (ch[channel].mode) { |
735 |
|
case CHMOD_FREE: |
736 |
|
if (current_error == ERR_OK) |
756 |
|
|
757 |
|
// Read next block if necessary |
758 |
|
if (ch[channel].buf_len == 0 && ch[channel].buf[0]) { |
759 |
+ |
D(bug(" reading next data block track %d, sector %d\n", ch[channel].buf[0], ch[channel].buf[1])); |
760 |
|
if (!read_sector(ch[channel].buf[0], ch[channel].buf[1], ch[channel].buf)) |
761 |
|
return ST_READ_TIMEOUT; |
762 |
|
ch[channel].buf_ptr = ch[channel].buf + 2; |
797 |
|
|
798 |
|
uint8 ImageDrive::Write(int channel, uint8 byte, bool eoi) |
799 |
|
{ |
800 |
+ |
// D(bug("ImageDrive::Write channel %d, byte %02x, eoi %d\n", channel, byte, eoi)); |
801 |
+ |
|
802 |
|
switch (ch[channel].mode) { |
803 |
|
case CHMOD_FREE: |
804 |
|
if (current_error == ERR_OK) |
838 |
|
if (!alloc_next_block(track, sector, DATA_INTERLEAVE)) |
839 |
|
return ST_TIMEOUT; |
840 |
|
ch[channel].num_blocks++; |
841 |
+ |
D(bug("next data block on track %d, sector %d\n", track, sector)); |
842 |
|
|
843 |
|
// Write buffer with link to new block |
844 |
|
ch[channel].buf[0] = track; |
1020 |
|
|
1021 |
|
uint8 *de = dir + DIR_ENTRIES; |
1022 |
|
for (entry=0; entry<8; entry++, de+=SIZEOF_DE) { |
1023 |
< |
if (de[DE_TYPE] == 0) |
1023 |
> |
if (de[DE_TYPE] == 0) { |
1024 |
> |
D(bug(" allocated entry %d in dir track %d, sector %d\n", entry, track, sector)); |
1025 |
|
return true; |
1026 |
+ |
} |
1027 |
|
} |
1028 |
|
} |
1029 |
|
|
1031 |
|
int last_track = track, last_sector = sector; |
1032 |
|
if (!alloc_next_block(track, sector, DIR_INTERLEAVE)) |
1033 |
|
return false; |
1034 |
+ |
D(bug(" new directory block track %d, sector %d\n", track, sector)); |
1035 |
|
|
1036 |
|
// Write link to new block to last block |
1037 |
|
dir[DIR_NEXT_TRACK] = track; |
1102 |
|
if (p[byte] & (1 << bit)) { |
1103 |
|
|
1104 |
|
// Yes, allocate and decrement free block count |
1105 |
+ |
D(bug("allocating block at track %d, sector %d\n", track, sector)); |
1106 |
|
p[byte] &= ~(1 << bit); |
1107 |
|
p[0]--; |
1108 |
|
bam_dirty = true; |
1130 |
|
if (!(p[byte] & (1 << bit))) { |
1131 |
|
|
1132 |
|
// Yes, free and increment free block count |
1133 |
+ |
D(bug("freeing block at track %d, sector %d\n", track, sector)); |
1134 |
|
p[byte] |= (1 << bit); |
1135 |
|
p[0]++; |
1136 |
|
bam_dirty = true; |