Apple-II: added DSK read/write support (#1011)
This commit is contained in:
@@ -7,6 +7,9 @@
|
||||
// SharpMz support
|
||||
#include "support/sharpmz/sharpmz.h"
|
||||
|
||||
// Apple 2 support
|
||||
#include "support/a2/dsk2nib_lib.h"
|
||||
|
||||
// Archie support
|
||||
#include "support/archie/archie.h"
|
||||
|
||||
|
||||
467
support/a2/dsk2nib_lib.cpp
Normal file
467
support/a2/dsk2nib_lib.cpp
Normal file
@@ -0,0 +1,467 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../file_io.h"
|
||||
#include "../../user_io.h"
|
||||
#include "../../hardware.h"
|
||||
|
||||
|
||||
#include "dsk2nib_lib.h"
|
||||
|
||||
// Constants from original dsk2nib.c
|
||||
#define TRACKS_PER_DISK 35
|
||||
#define SECTORS_PER_TRACK 16
|
||||
#define BYTES_PER_SECTOR 256
|
||||
#define BYTES_PER_TRACK 4096
|
||||
#define PRIMARY_BUF_LEN 256
|
||||
#define SECONDARY_BUF_LEN 86
|
||||
#define DATA_LEN (PRIMARY_BUF_LEN+SECONDARY_BUF_LEN)
|
||||
#define PROLOG_LEN 3
|
||||
#define EPILOG_LEN 3
|
||||
#define GAP1_LEN 48
|
||||
#define GAP2_LEN 5
|
||||
#define BYTES_PER_NIB_SECTOR 416
|
||||
#define BYTES_PER_NIB_TRACK 6656
|
||||
#define DEFAULT_VOLUME 254
|
||||
#define GAP_BYTE 0xff
|
||||
|
||||
// Structures from original
|
||||
typedef struct {
|
||||
uchar prolog[ PROLOG_LEN ];
|
||||
uchar volume[ 2 ];
|
||||
uchar track[ 2 ];
|
||||
uchar sector[ 2 ];
|
||||
uchar checksum[ 2 ];
|
||||
uchar epilog[ EPILOG_LEN ];
|
||||
} addr_t;
|
||||
|
||||
typedef struct {
|
||||
uchar prolog[ PROLOG_LEN ];
|
||||
uchar data[ DATA_LEN ];
|
||||
uchar data_checksum;
|
||||
uchar epilog[ EPILOG_LEN ];
|
||||
} data_t;
|
||||
|
||||
typedef struct {
|
||||
uchar gap1[ GAP1_LEN ];
|
||||
addr_t addr;
|
||||
uchar gap2[ GAP2_LEN ];
|
||||
data_t data;
|
||||
} nib_sector_t;
|
||||
|
||||
// Static data from original
|
||||
static uchar addr_prolog[] = { 0xd5, 0xaa, 0x96 };
|
||||
static uchar addr_epilog[] = { 0xde, 0xaa, 0xeb };
|
||||
static uchar data_prolog[] = { 0xd5, 0xaa, 0xad };
|
||||
static uchar data_epilog[] = { 0xde, 0xaa, 0xeb };
|
||||
static int soft_interleave[ SECTORS_PER_TRACK ] =
|
||||
{ 0, 7, 0xE, 6, 0xD, 5, 0xC, 4, 0xB, 3, 0xA, 2, 9, 1, 8, 0xF };
|
||||
static int phys_interleave[ SECTORS_PER_TRACK ] =
|
||||
{ 0, 0xD, 0xB, 9, 7, 5, 3, 1, 0xE, 0xC, 0xA, 8, 6, 4, 2, 0xF };
|
||||
|
||||
// Translation table for 6+2 encoding
|
||||
static uchar table[ 0x40 ] = {
|
||||
0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
|
||||
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
|
||||
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
|
||||
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
|
||||
0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
|
||||
0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
|
||||
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
|
||||
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||
};
|
||||
|
||||
// Helper functions from original
|
||||
static uchar translate(uchar byte) {
|
||||
return table[byte & 0x3f];
|
||||
}
|
||||
|
||||
static void odd_even_encode(uchar a[], int i) {
|
||||
a[0] = (i >> 1) & 0x55;
|
||||
a[0] |= 0xaa;
|
||||
a[1] = i & 0x55;
|
||||
a[1] |= 0xaa;
|
||||
}
|
||||
|
||||
static void nibbilize(uchar *src, data_t *data_field) {
|
||||
int i, index, section;
|
||||
uchar pair;
|
||||
uchar primary_buf[PRIMARY_BUF_LEN];
|
||||
uchar secondary_buf[SECONDARY_BUF_LEN];
|
||||
uchar *dest = data_field->data;
|
||||
|
||||
// Clear buffers
|
||||
memset(primary_buf, 0, PRIMARY_BUF_LEN);
|
||||
memset(secondary_buf, 0, SECONDARY_BUF_LEN);
|
||||
|
||||
// Nibbilize data into primary and secondary buffers
|
||||
for (i = 0; i < PRIMARY_BUF_LEN; i++) {
|
||||
primary_buf[i] = src[i] >> 2;
|
||||
|
||||
index = i % SECONDARY_BUF_LEN;
|
||||
section = i / SECONDARY_BUF_LEN;
|
||||
pair = ((src[i]&2)>>1) | ((src[i]&1)<<1); // swap the low bits
|
||||
secondary_buf[index] |= pair << (section*2);
|
||||
}
|
||||
|
||||
// XOR pairs of nibbilized bytes in correct order
|
||||
index = 0;
|
||||
dest[index++] = translate(secondary_buf[0]);
|
||||
|
||||
for (i = 1; i < SECONDARY_BUF_LEN; i++)
|
||||
dest[index++] = translate(secondary_buf[i] ^ secondary_buf[i-1]);
|
||||
|
||||
dest[index++] = translate(primary_buf[0] ^ secondary_buf[SECONDARY_BUF_LEN-1]);
|
||||
|
||||
for (i = 1; i < PRIMARY_BUF_LEN; i++)
|
||||
dest[index++] = translate(primary_buf[i] ^ primary_buf[i-1]);
|
||||
|
||||
data_field->data_checksum = translate(primary_buf[PRIMARY_BUF_LEN-1]);
|
||||
}
|
||||
|
||||
|
||||
// Convert NIB physical sector to logical sector using interleave tables
|
||||
static int phys_to_logical_sector(int phys_sector) {
|
||||
// Find which logical sector maps to this physical sector
|
||||
for (int i = 0; i < SECTORS_PER_TRACK; i++) {
|
||||
if (phys_interleave[i] == phys_sector) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0; // fallback
|
||||
}
|
||||
|
||||
void a2_readDsk2Nib(fileTYPE*fd, uint64_t offset, uchar *byte) {
|
||||
int nib_track = offset / BYTES_PER_NIB_TRACK;
|
||||
uint64_t track_offset = offset % BYTES_PER_NIB_TRACK;
|
||||
int volume = DEFAULT_VOLUME;
|
||||
|
||||
// Bounds check
|
||||
if (nib_track >= TRACKS_PER_DISK) {
|
||||
memset(byte, 0, 512);
|
||||
return;
|
||||
}
|
||||
|
||||
// Build entire NIB track in memory
|
||||
uchar nib_track_data[BYTES_PER_NIB_TRACK];
|
||||
|
||||
// Process all 16 sectors in this track
|
||||
for (int phys_sector = 0; phys_sector < SECTORS_PER_TRACK; phys_sector++) {
|
||||
// Convert physical sector to logical sector
|
||||
int logical_sector = phys_to_logical_sector(phys_sector);
|
||||
|
||||
// Get corresponding DSK soft sector
|
||||
int dsk_soft_sector = soft_interleave[logical_sector];
|
||||
|
||||
// Read DSK sector data
|
||||
uchar dsk_sector[BYTES_PER_SECTOR];
|
||||
off_t dsk_offset = (off_t)nib_track * BYTES_PER_TRACK + (off_t)dsk_soft_sector * BYTES_PER_SECTOR;
|
||||
|
||||
if (FileSeek(fd, dsk_offset, SEEK_SET))
|
||||
{
|
||||
if (FileReadAdv(fd, dsk_sector, BYTES_PER_SECTOR))
|
||||
{
|
||||
// good
|
||||
}
|
||||
else {
|
||||
memset(dsk_sector, 0, BYTES_PER_SECTOR);
|
||||
}
|
||||
} else {
|
||||
memset(dsk_sector, 0, BYTES_PER_SECTOR);
|
||||
}
|
||||
|
||||
|
||||
//if (lseek(fd, dsk_offset, SEEK_SET) == -1) {
|
||||
//} else if (read(fd, dsk_sector, BYTES_PER_SECTOR) != BYTES_PER_SECTOR) {
|
||||
// memset(dsk_sector, 0, BYTES_PER_SECTOR);
|
||||
//}
|
||||
|
||||
// Build NIB sector structure
|
||||
nib_sector_t nib_sector;
|
||||
|
||||
// Initialize gaps
|
||||
memset(nib_sector.gap1, GAP_BYTE, GAP1_LEN);
|
||||
memset(nib_sector.gap2, GAP_BYTE, GAP2_LEN);
|
||||
|
||||
// Set address field
|
||||
memcpy(nib_sector.addr.prolog, addr_prolog, 3);
|
||||
memcpy(nib_sector.addr.epilog, addr_epilog, 3);
|
||||
odd_even_encode(nib_sector.addr.volume, volume);
|
||||
odd_even_encode(nib_sector.addr.track, nib_track);
|
||||
odd_even_encode(nib_sector.addr.sector, logical_sector);
|
||||
int csum = volume ^ nib_track ^ logical_sector;
|
||||
odd_even_encode(nib_sector.addr.checksum, csum);
|
||||
|
||||
// Set data field
|
||||
memcpy(nib_sector.data.prolog, data_prolog, 3);
|
||||
memcpy(nib_sector.data.epilog, data_epilog, 3);
|
||||
nibbilize(dsk_sector, &nib_sector.data);
|
||||
|
||||
// Copy this sector to the track buffer
|
||||
memcpy(nib_track_data + phys_sector * BYTES_PER_NIB_SECTOR, &nib_sector, sizeof(nib_sector));
|
||||
}
|
||||
|
||||
// Copy requested 512 bytes from the track
|
||||
int bytes_to_copy = 512;
|
||||
int available_bytes = BYTES_PER_NIB_TRACK - track_offset;
|
||||
|
||||
if (available_bytes <= 0) {
|
||||
memset(byte, 0, 512);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytes_to_copy > available_bytes) {
|
||||
bytes_to_copy = available_bytes;
|
||||
}
|
||||
|
||||
memcpy(byte, nib_track_data + track_offset, bytes_to_copy);
|
||||
|
||||
// Fill remaining bytes with zeros if needed
|
||||
if (bytes_to_copy < 512) {
|
||||
memset(byte + bytes_to_copy, 0, 512 - bytes_to_copy);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions for NIB to DSK conversion
|
||||
static uchar odd_even_decode(uchar byte1, uchar byte2) {
|
||||
uchar byte;
|
||||
byte = (byte1 << 1) & 0xaa;
|
||||
byte |= byte2 & 0x55;
|
||||
return byte;
|
||||
}
|
||||
|
||||
static uchar untranslate(uchar x) {
|
||||
uchar *ptr;
|
||||
int index;
|
||||
if ((ptr = (uchar*)memchr(table, x, 0x40)) == NULL) {
|
||||
return 0; // Invalid byte, return 0 instead of fatal error
|
||||
}
|
||||
index = ptr - table;
|
||||
return index;
|
||||
}
|
||||
|
||||
// Parse a NIB sector from byte stream and extract DSK data
|
||||
static int parse_nib_sector(uchar *nib_data, int data_len, uchar *dsk_sector, int *track, int *sector) {
|
||||
int pos = 0;
|
||||
int state = 0;
|
||||
uchar primary_buf[PRIMARY_BUF_LEN];
|
||||
uchar secondary_buf[SECONDARY_BUF_LEN];
|
||||
uchar checksum;
|
||||
int i;
|
||||
|
||||
// State machine to parse NIB sector
|
||||
while (pos < data_len) {
|
||||
uchar byte = nib_data[pos++];
|
||||
|
||||
switch (state) {
|
||||
case 0: // Looking for address prolog D5
|
||||
if (byte == 0xd5) state = 1;
|
||||
break;
|
||||
|
||||
case 1: // Looking for address prolog AA
|
||||
if (byte == 0xaa) state = 2;
|
||||
else state = 0;
|
||||
break;
|
||||
|
||||
case 2: // Looking for address prolog 96
|
||||
if (byte == 0x96) state = 3;
|
||||
else state = 0;
|
||||
break;
|
||||
|
||||
case 3: // Read volume (first byte)
|
||||
if (pos >= data_len) return 0;
|
||||
odd_even_decode(byte, nib_data[pos++]); // Read volume but don't store
|
||||
state = 4;
|
||||
break;
|
||||
|
||||
case 4: // Read track (first byte)
|
||||
if (pos >= data_len) return 0;
|
||||
*track = odd_even_decode(byte, nib_data[pos++]);
|
||||
state = 5;
|
||||
break;
|
||||
|
||||
case 5: // Read sector (first byte)
|
||||
if (pos >= data_len) return 0;
|
||||
*sector = odd_even_decode(byte, nib_data[pos++]);
|
||||
state = 6;
|
||||
break;
|
||||
|
||||
case 6: // Read checksum (first byte)
|
||||
if (pos >= data_len) return 0;
|
||||
pos++; // Skip checksum, we don't validate it
|
||||
state = 7;
|
||||
break;
|
||||
|
||||
case 7: // Skip address epilog DE
|
||||
if (byte == 0xde) state = 8;
|
||||
break;
|
||||
|
||||
case 8: // Skip address epilog AA
|
||||
if (byte == 0xaa) state = 9;
|
||||
else state = 7;
|
||||
break;
|
||||
|
||||
case 9: // Skip address epilog EB, look for data prolog D5
|
||||
if (byte == 0xd5) state = 10;
|
||||
break;
|
||||
|
||||
case 10: // Looking for data prolog AA
|
||||
if (byte == 0xaa) state = 11;
|
||||
else state = 9;
|
||||
break;
|
||||
|
||||
case 11: // Looking for data prolog AD
|
||||
if (byte == 0xad) state = 12;
|
||||
else state = 9;
|
||||
break;
|
||||
|
||||
case 12: // Process data field
|
||||
// Read and decode the 342 data bytes plus checksum
|
||||
checksum = untranslate(byte);
|
||||
secondary_buf[0] = checksum;
|
||||
|
||||
// Read secondary buffer (85 more bytes)
|
||||
for (i = 1; i < SECONDARY_BUF_LEN; i++) {
|
||||
if (pos >= data_len) return 0;
|
||||
checksum ^= untranslate(nib_data[pos++]);
|
||||
secondary_buf[i] = checksum;
|
||||
}
|
||||
|
||||
// Read primary buffer (256 bytes)
|
||||
for (i = 0; i < PRIMARY_BUF_LEN; i++) {
|
||||
if (pos >= data_len) return 0;
|
||||
checksum ^= untranslate(nib_data[pos++]);
|
||||
primary_buf[i] = checksum;
|
||||
}
|
||||
|
||||
// Read and validate checksum
|
||||
if (pos >= data_len) return 0;
|
||||
checksum ^= untranslate(nib_data[pos++]);
|
||||
// Ignore checksum validation for now
|
||||
|
||||
// Denibbilize - reconstruct the 256-byte sector
|
||||
for (i = 0; i < PRIMARY_BUF_LEN; i++) {
|
||||
int index = i % SECONDARY_BUF_LEN;
|
||||
uchar bit0, bit1;
|
||||
|
||||
switch (i / SECONDARY_BUF_LEN) {
|
||||
case 0:
|
||||
bit0 = (secondary_buf[index] & 2) > 0;
|
||||
bit1 = (secondary_buf[index] & 1) > 0;
|
||||
break;
|
||||
case 1:
|
||||
bit0 = (secondary_buf[index] & 8) > 0;
|
||||
bit1 = (secondary_buf[index] & 4) > 0;
|
||||
break;
|
||||
case 2:
|
||||
bit0 = (secondary_buf[index] & 0x20) > 0;
|
||||
bit1 = (secondary_buf[index] & 0x10) > 0;
|
||||
break;
|
||||
default:
|
||||
bit0 = bit1 = 0;
|
||||
break;
|
||||
}
|
||||
dsk_sector[i] = (primary_buf[i] << 2) | (bit1 << 1) | bit0;
|
||||
}
|
||||
return 1; // Success
|
||||
|
||||
default:
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0; // Failed to parse
|
||||
}
|
||||
|
||||
void a2_writeDSK(fileTYPE* idx, uint64_t lba, int ack) {
|
||||
//printf("a2_writeDSK(lba:%lld ack:%d\n",lba,ack);
|
||||
// Fetch sector data from FPGA ...
|
||||
uchar chunk[512];
|
||||
EnableIO();
|
||||
spi_w(UIO_SECTOR_WR | ack);
|
||||
spi_block_read(chunk, user_io_get_width(), 512);
|
||||
DisableIO();
|
||||
|
||||
a2_writeNib2Dsk(idx, lba*512, chunk);
|
||||
}
|
||||
|
||||
void a2_readDSK(fileTYPE* idx, uint64_t lba, int ack) {
|
||||
//printf("a2_readDSK(lba:%lld ack:%d\n",lba,ack);
|
||||
uchar chunk[512];
|
||||
|
||||
a2_readDsk2Nib(idx, lba*512, chunk);
|
||||
|
||||
//printf("%x %x %x %x %x\n",chunk[0],chunk[1],chunk[2],chunk[3],chunk[4]);
|
||||
|
||||
EnableIO();
|
||||
spi_w(UIO_SECTOR_RD | ack);
|
||||
spi_block_write(chunk, user_io_get_width(), 512);
|
||||
DisableIO();
|
||||
}
|
||||
|
||||
|
||||
void a2_writeNib2Dsk(fileTYPE*fd, uint64_t offset, uchar *byte) {
|
||||
int nib_track = offset / BYTES_PER_NIB_TRACK;
|
||||
uint64_t track_offset = offset % BYTES_PER_NIB_TRACK;
|
||||
|
||||
// Bounds check
|
||||
if (nib_track >= TRACKS_PER_DISK) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to accumulate a full track's worth of NIB data to properly decode
|
||||
// This is a simplified approach - we'll try to parse sectors from the given 512 bytes
|
||||
static uchar track_buffer[BYTES_PER_NIB_TRACK];
|
||||
static int current_track = -1;
|
||||
static int bytes_accumulated = 0;
|
||||
|
||||
// If this is a new track, reset the buffer
|
||||
if (current_track != nib_track) {
|
||||
current_track = nib_track;
|
||||
bytes_accumulated = 0;
|
||||
memset(track_buffer, 0, BYTES_PER_NIB_TRACK);
|
||||
}
|
||||
|
||||
// Copy the 512 bytes into our track buffer at the appropriate offset
|
||||
int copy_len = 512;
|
||||
if (track_offset + copy_len > BYTES_PER_NIB_TRACK) {
|
||||
copy_len = BYTES_PER_NIB_TRACK - track_offset;
|
||||
}
|
||||
|
||||
if (copy_len > 0) {
|
||||
memcpy(track_buffer + track_offset, byte, copy_len);
|
||||
bytes_accumulated += copy_len;
|
||||
}
|
||||
|
||||
// Try to parse and write any complete sectors we can find
|
||||
// Look for sectors in the accumulated data
|
||||
int pos = 0;
|
||||
while (pos < bytes_accumulated - 400) { // Need at least 400 bytes for a sector
|
||||
uchar dsk_sector[BYTES_PER_SECTOR];
|
||||
int track_num, sector_num;
|
||||
|
||||
if (parse_nib_sector(track_buffer + pos, bytes_accumulated - pos, dsk_sector, &track_num, §or_num)) {
|
||||
// Successfully parsed a sector
|
||||
if (track_num == nib_track && sector_num < SECTORS_PER_TRACK) {
|
||||
// Map logical sector to soft sector using interleave
|
||||
int soft_sector = soft_interleave[sector_num];
|
||||
|
||||
// Calculate DSK file offset
|
||||
off_t dsk_offset = (off_t)track_num * BYTES_PER_TRACK + (off_t)soft_sector * BYTES_PER_SECTOR;
|
||||
|
||||
// Write sector to DSK file
|
||||
//if (lseek(fd, dsk_offset, SEEK_SET) != -1) {
|
||||
if (FileSeek(fd,dsk_offset, SEEK_SET))
|
||||
// if (lseek(fd, dsk_offset, SEEK_SET) != -1) {
|
||||
FileWriteAdv(fd, dsk_sector,BYTES_PER_SECTOR);
|
||||
//write(fd, dsk_sector, BYTES_PER_SECTOR);
|
||||
//}
|
||||
}
|
||||
pos += BYTES_PER_NIB_SECTOR; // Move to next sector
|
||||
} else {
|
||||
pos++; // Try next byte position
|
||||
}
|
||||
}
|
||||
}
|
||||
19
support/a2/dsk2nib_lib.h
Normal file
19
support/a2/dsk2nib_lib.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef DSK2NIB_LIB_H
|
||||
#define DSK2NIB_LIB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned char uchar;
|
||||
|
||||
// Library function for on-demand DSK to NIB conversion
|
||||
void a2_readDsk2Nib(fileTYPE*fd, uint64_t offset, uchar *byte);
|
||||
|
||||
// Library function for writing NIB data back to DSK format
|
||||
void a2_writeNib2Dsk(fileTYPE*fd, uint64_t offset, uchar *byte);
|
||||
|
||||
|
||||
void a2_writeDSK(fileTYPE* idx, uint64_t lba, int ack);
|
||||
void a2_readDSK(fileTYPE* idx, uint64_t lba, int ack);
|
||||
|
||||
|
||||
#endif
|
||||
32
user_io.cpp
32
user_io.cpp
@@ -43,6 +43,11 @@ static char core_path[1024] = {};
|
||||
static char rbf_path[1024] = {};
|
||||
|
||||
static fileTYPE sd_image[16] = {};
|
||||
|
||||
#define SD_TYPE_DEFAULT 0
|
||||
#define SD_TYPE_C64 1
|
||||
#define SD_TYPE_A2 2
|
||||
|
||||
static int sd_type[16] = {};
|
||||
static int sd_image_cangrow[16] = {};
|
||||
static uint64_t buffer_lba[16] = { ULLONG_MAX,ULLONG_MAX,ULLONG_MAX,ULLONG_MAX,
|
||||
@@ -2007,15 +2012,9 @@ int user_io_file_mount(const char *name, unsigned char index, char pre, int pre_
|
||||
int img_type = 0; // disk image type (for C128 core): bit 0=dual sided, 1=raw GCR supported, 2=raw MFM supported, 3=high density
|
||||
|
||||
sd_image_cangrow[index] = (pre != 0);
|
||||
sd_type[index] = 0;
|
||||
|
||||
sd_type[index] = SD_TYPE_DEFAULT ;
|
||||
if (len)
|
||||
{
|
||||
if (!strcasecmp(user_io_get_core_name(), "apple-ii"))
|
||||
{
|
||||
ret = dsk2nib(name, sd_image + index);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
if (x2trd_ext_supp(name))
|
||||
@@ -2030,7 +2029,7 @@ int user_io_file_mount(const char *name, unsigned char index, char pre, int pre_
|
||||
{
|
||||
img_type = c64_openGCR(name, sd_image + index, index);
|
||||
ret = img_type < 0 ? 0 : 1;
|
||||
sd_type[index] = 1;
|
||||
sd_type[index] = SD_TYPE_C64;
|
||||
if (!ret) FileClose(&sd_image[index]);
|
||||
|
||||
if (ret && is_c128())
|
||||
@@ -2052,13 +2051,18 @@ int user_io_file_mount(const char *name, unsigned char index, char pre, int pre_
|
||||
{
|
||||
img_type = c64_openGCR(name, sd_image + index, index);
|
||||
ret = img_type < 0 ? 0 : 1;
|
||||
sd_type[index] = 1;
|
||||
sd_type[index] = SD_TYPE_C64;
|
||||
if(!ret) FileClose(&sd_image[index]);
|
||||
}
|
||||
else if (!strcasecmp(name + len - 4, ".d81"))
|
||||
{
|
||||
img_type = G64_SUPPORT_HD | G64_SUPPORT_DS;
|
||||
}
|
||||
else if (!strcasecmp(name + len - 4, ".dsk") && ((!strcasecmp(user_io_get_core_name(), "apple-ii") || (!strcasecmp(user_io_get_core_name(), "TK2000") )) ))
|
||||
{
|
||||
printf("FOUND A2 DSK type\n");
|
||||
sd_type[index] = SD_TYPE_A2;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret && is_c128())
|
||||
@@ -3085,8 +3089,14 @@ void user_io_poll()
|
||||
blks = 1;
|
||||
}
|
||||
DisableIO();
|
||||
|
||||
if ((blks == G64_BLOCK_COUNT_1541+1 || blks == G64_BLOCK_COUNT_1571+1) && sd_type[disk])
|
||||
if ( sd_type[disk] == SD_TYPE_A2)
|
||||
{
|
||||
//if (op) printf("A2 %x %llu on %d\n", op,lba, disk);
|
||||
if (op == 2) a2_writeDSK(&sd_image[disk], lba, ack);
|
||||
else if (op & 1) a2_readDSK(&sd_image[disk], lba, ack);
|
||||
else break;
|
||||
}
|
||||
else if ((blks == G64_BLOCK_COUNT_1541+1 || blks == G64_BLOCK_COUNT_1571+1) && sd_type[disk]==SD_TYPE_C64)
|
||||
{
|
||||
if (op == 2) c64_writeGCR(disk, lba, blks-1);
|
||||
else if (op & 1) c64_readGCR(disk, lba, blks-1);
|
||||
|
||||
Reference in New Issue
Block a user