mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
td0_dsk: add new floppy system support for teledisk [Carl]
--- Lots of conflicting info out there, need more samples (8", fm)
This commit is contained in:
parent
b6d5cc992d
commit
e697bb3278
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -2081,6 +2081,7 @@ src/lib/formats/svi_cas.h svneol=native#text/plain
|
||||
src/lib/formats/svi_dsk.c svneol=native#text/plain
|
||||
src/lib/formats/svi_dsk.h svneol=native#text/plain
|
||||
src/lib/formats/td0_dsk.c svneol=native#text/plain
|
||||
src/lib/formats/td0_dsk.h svneol=native#text/plain
|
||||
src/lib/formats/thom_cas.c svneol=native#text/plain
|
||||
src/lib/formats/thom_cas.h svneol=native#text/plain
|
||||
src/lib/formats/thom_dsk.c svneol=native#text/plain
|
||||
|
@ -40,6 +40,7 @@ const floppy_format_type floppy_image_device::default_floppy_formats[] = {
|
||||
FLOPPY_IPF_FORMAT,
|
||||
FLOPPY_MFI_FORMAT,
|
||||
FLOPPY_MFM_FORMAT,
|
||||
FLOPPY_TD0_FORMAT,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "formats/imd_dsk.h"
|
||||
#include "formats/ipf_dsk.h"
|
||||
#include "formats/mfi_dsk.h"
|
||||
#include "formats/td0_dsk.h"
|
||||
|
||||
#define MCFG_FLOPPY_DRIVE_ADD(_tag, _slot_intf, _def_slot, _def_inp, _formats) \
|
||||
MCFG_DEVICE_ADD(_tag, FLOPPY_CONNECTOR, 0) \
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "emu.h"
|
||||
#include "flopimg.h"
|
||||
|
||||
#define BUFSZ 512 // new input buffer
|
||||
@ -55,7 +56,7 @@ struct tdlzhuf {
|
||||
|
||||
struct td0dsk_t
|
||||
{
|
||||
floppy_image_legacy *floppy_file;
|
||||
io_generic *floppy_file;
|
||||
UINT64 floppy_file_offset;
|
||||
|
||||
struct tdlzhuf tdctl;
|
||||
@ -87,7 +88,12 @@ struct td0dsk_t
|
||||
int Decode(UINT8 *buf, int len);
|
||||
};
|
||||
|
||||
static td0dsk_t td0dsk;
|
||||
//static td0dsk_t td0dsk;
|
||||
|
||||
struct floppy_image_legacy
|
||||
{
|
||||
struct io_generic io;
|
||||
};
|
||||
|
||||
|
||||
static struct td0dsk_tag *get_tag(floppy_image_legacy *floppy)
|
||||
@ -312,10 +318,10 @@ static floperr_t td0_get_indexed_sector_info(floppy_image_legacy *floppy, int he
|
||||
|
||||
int td0dsk_t::data_read(UINT8 *buf, UINT16 size)
|
||||
{
|
||||
if (floppy_file_offset + size > floppy_image_size(floppy_file) ) {
|
||||
size = floppy_image_size(floppy_file) - floppy_file_offset;
|
||||
if (floppy_file_offset + size > io_generic_size(floppy_file) ) {
|
||||
size = io_generic_size(floppy_file) - floppy_file_offset;
|
||||
}
|
||||
floppy_image_read(floppy_file,buf,floppy_file_offset,size);
|
||||
io_generic_read(floppy_file,buf,floppy_file_offset,size);
|
||||
floppy_file_offset += size;
|
||||
return size;
|
||||
}
|
||||
@ -654,7 +660,7 @@ int td0dsk_t::Decode(UINT8 *buf, int len) /* Decoding/Uncompressing */
|
||||
|
||||
FLOPPY_CONSTRUCT( td0_dsk_construct )
|
||||
{
|
||||
td0dsk_t *state = &td0dsk;
|
||||
td0dsk_t state;
|
||||
struct FloppyCallbacks *callbacks;
|
||||
struct td0dsk_tag *tag;
|
||||
UINT8 *header;
|
||||
@ -685,12 +691,12 @@ FLOPPY_CONSTRUCT( td0_dsk_construct )
|
||||
int rd;
|
||||
int off = 12;
|
||||
int size = 0;
|
||||
state->floppy_file = floppy;
|
||||
state->init_Decode();
|
||||
state->floppy_file_offset = 12;
|
||||
state.floppy_file = &(floppy->io);
|
||||
state.init_Decode();
|
||||
state.floppy_file_offset = 12;
|
||||
do
|
||||
{
|
||||
if((rd = state->Decode(obuf, BUFSZ)) > 0) size += rd;
|
||||
if((rd = state.Decode(obuf, BUFSZ)) > 0) size += rd;
|
||||
} while(rd == BUFSZ);
|
||||
memcpy(obuf,tag->data,12);
|
||||
free(tag->data);
|
||||
@ -699,11 +705,11 @@ FLOPPY_CONSTRUCT( td0_dsk_construct )
|
||||
return FLOPPY_ERROR_OUTOFMEMORY;
|
||||
}
|
||||
memcpy(tag->data,obuf,12);
|
||||
state->floppy_file_offset = 12;
|
||||
state->init_Decode();
|
||||
state.floppy_file_offset = 12;
|
||||
state.init_Decode();
|
||||
do
|
||||
{
|
||||
if((rd = state->Decode(obuf, BUFSZ)) > 0) {
|
||||
if((rd = state.Decode(obuf, BUFSZ)) > 0) {
|
||||
memcpy(tag->data+off,obuf,rd);
|
||||
off += rd;
|
||||
}
|
||||
@ -764,3 +770,259 @@ FLOPPY_DESTRUCT( td0_dsk_destruct )
|
||||
tag->data = NULL;
|
||||
return FLOPPY_ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
||||
formats/td0_dsk.h
|
||||
|
||||
Teledisk disk images
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "td0_dsk.h"
|
||||
|
||||
td0_format::td0_format()
|
||||
{
|
||||
}
|
||||
|
||||
const char *td0_format::name() const
|
||||
{
|
||||
return "td0";
|
||||
}
|
||||
|
||||
const char *td0_format::description() const
|
||||
{
|
||||
return "Teledisk disk image";
|
||||
}
|
||||
|
||||
const char *td0_format::extensions() const
|
||||
{
|
||||
return "td0";
|
||||
}
|
||||
|
||||
int td0_format::identify(io_generic *io, UINT32 form_factor)
|
||||
{
|
||||
UINT8 h[7];
|
||||
|
||||
io_generic_read(io, h, 0, 7);
|
||||
if((toupper(h[0]) == 'T') && (toupper(h[1]) == 'D'))
|
||||
{
|
||||
if((form_factor == floppy_image::FF_35) && ((h[6] == 3) || (h[6] == 4)))
|
||||
return 100;
|
||||
if((form_factor == floppy_image::FF_525) && ((h[6] == 1) || (h[6] == 2) || (h[6] == 3)))
|
||||
return 100;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool td0_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
|
||||
{
|
||||
int cell_count = 0;
|
||||
int track_count = 0;
|
||||
int head_count = 0;
|
||||
int track_spt;
|
||||
int offset = 0;
|
||||
const int max_size = 4*1024*1024; // 4MB ought to be large enough for any floppy
|
||||
UINT8 *imagebuf = global_alloc_array(UINT8, max_size);
|
||||
UINT8 header[12];
|
||||
|
||||
try
|
||||
{
|
||||
io_generic_read(io, header, 0, 12);
|
||||
head_count = header[9];
|
||||
|
||||
if(header[0] == 't')
|
||||
{
|
||||
td0dsk_t disk_decode;
|
||||
|
||||
disk_decode.floppy_file = io;
|
||||
disk_decode.init_Decode();
|
||||
disk_decode.floppy_file_offset = 12;
|
||||
disk_decode.Decode(imagebuf, max_size);
|
||||
}
|
||||
else
|
||||
io_generic_read(io, imagebuf, 12, io_generic_size(io));
|
||||
|
||||
if(header[7] & 0x80)
|
||||
offset = 10 + imagebuf[1] + (imagebuf[2] << 8);
|
||||
|
||||
track_spt = imagebuf[offset];
|
||||
if(track_spt == 255) // Empty file?
|
||||
throw false;
|
||||
|
||||
switch(header[6])
|
||||
{
|
||||
case 2:
|
||||
if((imagebuf[offset + 2] & 0x7f) == 2) // ?
|
||||
{
|
||||
cell_count = 166666;
|
||||
if(head_count == 2)
|
||||
image->set_variant(floppy_image::DSHD);
|
||||
else
|
||||
throw false; // single side hd?
|
||||
break;
|
||||
}
|
||||
/* no break; could be qd, won't know until tracks are counted */
|
||||
case 1:
|
||||
cell_count = 100000;
|
||||
if(head_count == 2)
|
||||
image->set_variant(floppy_image::DSDD);
|
||||
else
|
||||
image->set_variant(floppy_image::SSDD);
|
||||
break;
|
||||
case 4:
|
||||
if((imagebuf[offset + 2] & 0x7f) == 2) // ?
|
||||
{
|
||||
cell_count = 200000;
|
||||
if(head_count == 2)
|
||||
image->set_variant(floppy_image::DSHD);
|
||||
else
|
||||
throw false; // single side 3.5?
|
||||
break;
|
||||
}
|
||||
/* no break */
|
||||
case 3:
|
||||
cell_count = 100000;
|
||||
if(head_count == 2)
|
||||
{
|
||||
if(form_factor == floppy_image::FF_525) // is this correct?
|
||||
image->set_variant(floppy_image::DSQD);
|
||||
else
|
||||
image->set_variant(floppy_image::DSDD);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(form_factor == floppy_image::FF_525)
|
||||
image->set_variant(floppy_image::SSQD);
|
||||
else
|
||||
throw false; // single side 3.5?
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
while(track_spt != 255)
|
||||
{
|
||||
desc_pc_sector sects[256];
|
||||
UINT8 sect_data[65536];
|
||||
int sdatapos = 0;
|
||||
int track = imagebuf[offset + 1];
|
||||
int head = imagebuf[offset + 2] & 1;
|
||||
bool fm = (header[5] & 0x80) || (imagebuf[offset + 2] & 0x80); // ?
|
||||
offset += 4;
|
||||
for(int i = 0; i < track_spt; i++)
|
||||
{
|
||||
UINT8 *hs = &imagebuf[offset];
|
||||
UINT16 size;
|
||||
offset += 6;
|
||||
|
||||
sects[i].track = hs[0];
|
||||
sects[i].head = hs[1];
|
||||
sects[i].sector = hs[2];
|
||||
sects[i].size = hs[3];
|
||||
sects[i].deleted = (hs[4] & 4) == 4;
|
||||
sects[i].bad_crc = (hs[4] & 2) == 2;
|
||||
|
||||
if(hs[4] & 0x30)
|
||||
size = 0;
|
||||
else
|
||||
{
|
||||
offset += 3;
|
||||
size = 128 << hs[3];
|
||||
int j, k;
|
||||
switch(hs[8])
|
||||
{
|
||||
default:
|
||||
throw false;
|
||||
case 0:
|
||||
memcpy(§_data[sdatapos], &imagebuf[offset], size);
|
||||
offset += size;
|
||||
break;
|
||||
case 1:
|
||||
offset += 4;
|
||||
k = (hs[9] + (hs[10] << 8)) * 2;
|
||||
k = (k <= size) ? k : size;
|
||||
for(j = 0; j < k; j += 2)
|
||||
{
|
||||
sect_data[sdatapos + j] = hs[11];
|
||||
sect_data[sdatapos + j + 1] = hs[12];
|
||||
}
|
||||
if(k < size)
|
||||
memset(§_data[sdatapos + k], '\0', size - k);
|
||||
break;
|
||||
case 2:
|
||||
k = 0;
|
||||
while(k < size)
|
||||
{
|
||||
UINT16 len = imagebuf[offset];
|
||||
UINT16 rep = imagebuf[offset + 1];
|
||||
offset += 2;
|
||||
if(!len)
|
||||
{
|
||||
memcpy(§_data[sdatapos + k], &imagebuf[offset], rep);
|
||||
offset += rep;
|
||||
k += rep;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = (1 << len);
|
||||
rep = len * rep;
|
||||
rep = ((rep + k) <= size) ? rep : (size - k);
|
||||
for(j = 0; j < rep; j += len)
|
||||
memcpy(§_data[sdatapos + j + k], &imagebuf[offset], len);
|
||||
k += rep;
|
||||
offset += len;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sects[i].actual_size = size;
|
||||
|
||||
if(size)
|
||||
{
|
||||
sects[i].data = §_data[sdatapos];
|
||||
sdatapos += size;
|
||||
}
|
||||
else
|
||||
sects[i].data = NULL;
|
||||
}
|
||||
}
|
||||
track_count = track;
|
||||
if(fm)
|
||||
build_pc_track_fm(track, head, image, cell_count, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size));
|
||||
else
|
||||
build_pc_track_mfm(track, head, image, cell_count, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size));
|
||||
track_spt = imagebuf[offset];
|
||||
}
|
||||
if((track_count > 50) && (form_factor == floppy_image::FF_525)) // ?
|
||||
{
|
||||
if(image->get_variant() == floppy_image::DSDD)
|
||||
image->set_variant(floppy_image::DSQD);
|
||||
else if(image->get_variant() == floppy_image::SSDD)
|
||||
image->set_variant(floppy_image::SSQD);
|
||||
}
|
||||
throw true;
|
||||
}
|
||||
catch(bool ret)
|
||||
{
|
||||
global_free(imagebuf);
|
||||
return ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool td0_format::save(io_generic *io, floppy_image *image)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool td0_format::supports_save() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const floppy_format_type FLOPPY_TD0_FORMAT = &floppy_image_format_creator<td0_format>;
|
||||
|
||||
|
||||
|
24
src/lib/formats/td0_dsk.h
Normal file
24
src/lib/formats/td0_dsk.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef TD0_DSK_H_
|
||||
#define TD0_DSK_H_
|
||||
|
||||
#include "flopimg.h"
|
||||
|
||||
|
||||
class td0_format : public floppy_image_format_t
|
||||
{
|
||||
public:
|
||||
td0_format();
|
||||
|
||||
virtual int identify(io_generic *io, UINT32 form_factor);
|
||||
virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
|
||||
virtual bool save(io_generic *io, floppy_image *image);
|
||||
|
||||
virtual const char *name() const;
|
||||
virtual const char *description() const;
|
||||
virtual const char *extensions() const;
|
||||
virtual bool supports_save() const;
|
||||
};
|
||||
|
||||
extern const floppy_format_type FLOPPY_TD0_FORMAT;
|
||||
|
||||
#endif /* TD0_DSK_H_ */
|
@ -37,7 +37,7 @@
|
||||
#include "machine/upd7201.h"
|
||||
#include "machine/mc146818.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "machine/8237dma.h"
|
||||
#include "machine/am9517a.h"
|
||||
#include "machine/serial.h"
|
||||
#include "video/upd7220.h"
|
||||
#include "machine/upd765.h"
|
||||
@ -77,8 +77,8 @@ public:
|
||||
required_device<pic8259_device> m_pic_s;
|
||||
required_device<upd7201_device> m_scc;
|
||||
required_device<i8255_device> m_ppi;
|
||||
required_device<i8237_device> m_dma_1;
|
||||
required_device<i8237_device> m_dma_2;
|
||||
required_device<am9517a_device> m_dma_1;
|
||||
required_device<am9517a_device> m_dma_2;
|
||||
required_device<upd765a_device> m_fdc;
|
||||
required_device<upd7220_device> m_hgdc;
|
||||
required_device<mc146818_device> m_rtc;
|
||||
@ -340,7 +340,7 @@ void qx10_state::qx10_upd765_interrupt(bool state)
|
||||
|
||||
void qx10_state::drq_w(bool state)
|
||||
{
|
||||
m_dma_1->i8237_dreq0_w(!state);
|
||||
m_dma_1->dreq0_w(!state);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( qx10_state::fdd_motor_w )
|
||||
@ -369,9 +369,8 @@ READ8_MEMBER( qx10_state::qx10_30_r )
|
||||
*/
|
||||
WRITE_LINE_MEMBER(qx10_state::dma_hrq_changed)
|
||||
{
|
||||
i8237_device *device = machine().device<i8237_device>("8237dma_1");
|
||||
/* Assert HLDA */
|
||||
device->i8237_hlda_w(state);
|
||||
m_dma_1->hack_w(state);
|
||||
}
|
||||
|
||||
READ8_MEMBER( qx10_state::gdc_dack_r )
|
||||
@ -694,8 +693,8 @@ static ADDRESS_MAP_START( qx10_io , AS_IO, 8, qx10_state)
|
||||
// AM_RANGE(0x3b, 0x3b) GDC light pen req
|
||||
AM_RANGE(0x3c, 0x3c) AM_READWRITE(mc146818_data_r, mc146818_data_w)
|
||||
AM_RANGE(0x3d, 0x3d) AM_WRITE(mc146818_offset_w)
|
||||
AM_RANGE(0x40, 0x4f) AM_DEVREADWRITE("8237dma_1", i8237_device, i8237_r, i8237_w)
|
||||
AM_RANGE(0x50, 0x5f) AM_DEVREADWRITE("8237dma_2", i8237_device, i8237_r, i8237_w)
|
||||
AM_RANGE(0x40, 0x4f) AM_DEVREADWRITE("8237dma_1", am9517a_device, read, write)
|
||||
AM_RANGE(0x50, 0x5f) AM_DEVREADWRITE("8237dma_2", am9517a_device, read, write)
|
||||
// AM_RANGE(0xfc, 0xfd) Multi-Font comms
|
||||
ADDRESS_MAP_END
|
||||
|
||||
@ -920,7 +919,7 @@ void qx10_state::machine_start()
|
||||
|
||||
void qx10_state::machine_reset()
|
||||
{
|
||||
m_dma_1->i8237_dreq0_w(1);
|
||||
m_dma_1->dreq0_w(1);
|
||||
|
||||
m_memprom = 0;
|
||||
m_memcmos = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user