diff options
Diffstat (limited to 'src/devices/imagedev/floppy.cpp')
-rw-r--r-- | src/devices/imagedev/floppy.cpp | 273 |
1 files changed, 243 insertions, 30 deletions
diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp index 738412f5530..7d34bfe675c 100644 --- a/src/devices/imagedev/floppy.cpp +++ b/src/devices/imagedev/floppy.cpp @@ -19,10 +19,12 @@ #include "formats/cqm_dsk.h" #include "formats/dsk_dsk.h" #include "formats/pc_dsk.h" +#include "formats/ipf_dsk.h" #include "formats/fs_unformatted.h" #include "formats/fsblk_vec.h" +#include "screen.h" #include "speaker.h" #include "formats/imageutl.h" #include "zippath.h" @@ -37,6 +39,8 @@ #define PITCH_SEEK_SAMPLES 1 +#define FLUX_SCREEN 0 + #define FLOPSND_TAG "floppysound" // device type definition @@ -55,6 +59,7 @@ DEFINE_DEVICE_TYPE(FLOPPY_35_ED, floppy_35_ed, "floppy_35_ed", "3.5\" exte // generic 5.25" drives DEFINE_DEVICE_TYPE(FLOPPY_525_SSSD_35T, floppy_525_sssd_35t, "floppy_525_sssd_35t", "5.25\" single-sided single density 35-track floppy drive") DEFINE_DEVICE_TYPE(FLOPPY_525_SD_35T, floppy_525_sd_35t, "floppy_525_sd_35t", "5.25\" double-sided single density 35-track floppy drive") +DEFINE_DEVICE_TYPE(FLOPPY_525_VTECH, floppy_525_vtech, "floppy_525_vtech", "5.25\" single-sided single density VTECH floppy drive") DEFINE_DEVICE_TYPE(FLOPPY_525_SSSD, floppy_525_sssd, "floppy_525_sssd", "5.25\" single-sided single density floppy drive") DEFINE_DEVICE_TYPE(FLOPPY_525_SD, floppy_525_sd, "floppy_525_sd", "5.25\" single density floppy drive") DEFINE_DEVICE_TYPE(FLOPPY_525_SSDD, floppy_525_ssdd, "floppy_525_ssdd", "5.25\" single-sided double density floppy drive") @@ -168,6 +173,7 @@ void format_registration::add_pc_formats() add_mfm_containers(); add(FLOPPY_PC_FORMAT); + add(FLOPPY_IPF_FORMAT); } void format_registration::add(floppy_format_type format) @@ -175,9 +181,9 @@ void format_registration::add(floppy_format_type format) m_formats.push_back(format); } -void format_registration::add(filesystem_manager_type fs) +void format_registration::add(const filesystem_manager_t &fs) { - m_fs.push_back(fs); + m_fs.push_back(&fs); } void floppy_image_device::default_fm_floppy_formats(format_registration &fr) @@ -241,7 +247,6 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t input_format(nullptr), output_format(nullptr), image(), - fif_list(nullptr), index_timer(nullptr), tracks(0), sides(0), @@ -256,10 +261,13 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t revolution_count(0), cyl(0), subcyl(0), + amplifier_freakout_time(attotime::from_usec(16)), image_dirty(false), + track_dirty(false), ready_counter(0), m_make_sound(false), - m_sound_out(nullptr) + m_sound_out(nullptr), + m_flux_screen(*this, "flux") { extension_list[0] = '\0'; m_err = IMAGE_ERROR_INVALIDIMAGE; @@ -271,12 +279,8 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t floppy_image_device::~floppy_image_device() { - for(floppy_image_format_t *format = fif_list; format; ) { - floppy_image_format_t* tmp_format = format; - format = format->next; - delete tmp_format; - } - fif_list = nullptr; + for(floppy_image_format_t *format : fif_list) + delete format; } void floppy_image_device::setup_load_cb(load_cb cb) @@ -309,12 +313,12 @@ void floppy_image_device::setup_led_cb(led_cb cb) cur_led_cb = cb; } -void floppy_image_device::fs_enum::add(const filesystem_manager_t *manager, floppy_format_type type, u32 image_size, const char *name, const char *description) +void floppy_image_device::fs_enum::add(floppy_format_type type, u32 image_size, const char *name, const char *description) { - if(manager->can_format()) - m_fid->m_create_fs.emplace_back(fs_info(manager, type, image_size, name, description)); - if(manager->can_read()) - m_fid->m_io_fs.emplace_back(fs_info(manager, type, image_size, name, description)); + if(m_manager->can_format()) + m_fid->m_create_fs.emplace_back(fs_info(m_manager, type, image_size, name, description)); + if(m_manager->can_read()) + m_fid->m_io_fs.emplace_back(fs_info(m_manager, type, image_size, name, description)); } void floppy_image_device::fs_enum::add_raw(const char *name, u32 key, const char *description) @@ -329,27 +333,23 @@ void floppy_image_device::register_formats() format_registration_cb(fr); extension_list[0] = '\0'; - fif_list = nullptr; + fif_list.clear(); for(floppy_format_type fft : fr.m_formats) { // allocate a new format floppy_image_format_t *fif = fft(); - if(!fif_list) - fif_list = fif; - else - fif_list->append(fif); - + fif_list.push_back(fif); add_format(fif->name(), fif->description(), fif->extensions(), ""); image_specify_extension( extension_list, 256, fif->extensions() ); } fs_enum fse(this); - for(filesystem_manager_type fmt : fr.m_fs) + for(const filesystem_manager_t *fmt : fr.m_fs) { - auto ff = fmt(); - ff->enumerate_f(fse, form_factor, variants); - m_fs_managers.push_back(std::unique_ptr<filesystem_manager_t>(ff)); + fse.m_manager = fmt; + fmt->enumerate_f(fse, form_factor, variants); + m_fs_managers.push_back(fmt); } } @@ -358,7 +358,7 @@ void floppy_image_device::set_formats(std::function<void (format_registration &f format_registration_cb = formats; } -floppy_image_format_t *floppy_image_device::get_formats() const +const std::vector<floppy_image_format_t *> &floppy_image_device::get_formats() const { return fif_list; } @@ -387,6 +387,11 @@ void floppy_image_device::setup_write(floppy_image_format_t *_output_format) void floppy_image_device::commit_image() { + if(FLUX_SCREEN && track_dirty) { + flux_image_compute_for_track(((cyl << 2) | subcyl) >> (2 - image->get_resolution()), ss); + track_dirty = false; + } + image_dirty = false; if(!output_format || !output_format->supports_save()) return; @@ -473,6 +478,29 @@ void floppy_image_device::device_start() save_item(NAME(image_dirty)); save_item(NAME(ready_counter)); save_item(NAME(phases)); + + if(FLUX_SCREEN) { + m_flux_per_pixel_infos.resize(flux_screen_sx*flux_screen_sy); + flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data(); + for(int y = 0; y != flux_screen_sy; y++) { + int head = y >= flux_screen_sy / 2 ? 1 : 0; + int yc = (flux_screen_sy/2-1)/2 + (flux_screen_sy/2)*head; + int dy = y - yc; + for(int x = 0; x != flux_screen_sx; x++) { + const int xc = (flux_screen_sx - 1)/2; + int dx = x - xc; + int r = int(sqrt(dx*dx + dy*dy) + 0.5); + ppi->m_r = r; + if(r > flux_max_r || r < flux_min_r) + ppi->m_position = 0xffffffff; + else + ppi->m_position = int((200e6 / 2 / M_PI) * atan2(dy, dx) + 100000000.5) % 200000000; + ppi->m_combined_track = 0; + ppi->m_color = 0; + ppi ++; + } + } + } } void floppy_image_device::device_reset() @@ -514,7 +542,7 @@ floppy_image_format_t *floppy_image_device::identify(std::string filename) io.filler = 0xff; int best = 0; floppy_image_format_t *best_format = nullptr; - for (floppy_image_format_t *format = fif_list; format; format = format->next) + for (floppy_image_format_t *format : fif_list) { int score = format->identify(&io, form_factor, variants); if(score > best) { @@ -562,7 +590,7 @@ image_init_result floppy_image_device::call_load() io.filler = 0xff; int best = 0; floppy_image_format_t *best_format = nullptr; - for (floppy_image_format_t *format = fif_list; format; format = format->next) { + for (floppy_image_format_t *format : fif_list) { int score = format->identify(&io, form_factor, variants); if(score > best) { best = score; @@ -590,9 +618,147 @@ image_init_result floppy_image_device::call_load() if (!cur_load_cb.isnull()) return cur_load_cb(this); + flux_image_prepare(); + return image_init_result::PASS; } +void floppy_image_device::flux_image_prepare() +{ + if(!FLUX_SCREEN) + return; + + int tracks = 0, heads = 0, rez = 0; + image->get_maximal_geometry(tracks, heads); + rez = image->get_resolution(); + + int trackm = (tracks - 1) << rez; + int tmask = (1 << rez) - 1; + + m_flux_per_combined_track_infos.clear(); + m_flux_per_combined_track_infos.resize(trackm+1); + for(int track = 0; track <= trackm; track++) { + int refr = 200 + (trackm - 0.5 - track) * 290 / (trackm+1) + 200; + int span = int((200e6 / 2 / M_PI) / refr); + m_flux_per_combined_track_infos[track].m_span = span; + m_flux_per_combined_track_infos[track].m_track = track >> rez; + m_flux_per_combined_track_infos[track].m_subtrack = track & tmask; + } + + flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data(); + for(int head = 0; head != heads; head++) + for(unsigned int i=0; i != flux_screen_sx*flux_screen_sy/2; i++) { + if(ppi->m_position != 0xffffffff) { + int trk = (trackm + 1) * (flux_max_r - ppi->m_r) / (flux_max_r - flux_min_r + 1); + ppi->m_combined_track = trk; + m_flux_per_combined_track_infos[trk].m_pixels[head].push_back(ppi); + } + ppi++; + } + + for(auto &t : m_flux_per_combined_track_infos) { + std::sort(t.m_pixels[0].begin(), t.m_pixels[0].end(), [](const flux_per_pixel_info *a, const flux_per_pixel_info *b) -> bool { return a->m_position < b->m_position; }); + if(heads == 2) + std::sort(t.m_pixels[1].begin(), t.m_pixels[1].end(), [](const flux_per_pixel_info *a, const flux_per_pixel_info *b) -> bool { return a->m_position < b->m_position; }); + } + + for(int head = 0; head != heads; head++) + for(int track = 0; track <= trackm; track++) + flux_image_compute_for_track(track, head); +} + +void floppy_image_device::flux_image_compute_for_track(int track, int head) +{ + auto *pcti = m_flux_per_combined_track_infos.data() + track; + const std::vector<uint32_t> &buffer = image->get_buffer(pcti->m_track, head, pcti->m_subtrack); + int sz = buffer.size(); + if(!sz) { + for(flux_per_pixel_info *p : m_flux_per_combined_track_infos[track].m_pixels[head]) + p->m_color = 255; + return; + } + + int spos = pcti->m_pixels[head][0]->m_position - pcti->m_span + 200000000; + int bpos = sz; + while(bpos && (buffer[bpos-1] & floppy_image::TIME_MASK) < spos) + bpos --; + if(bpos == sz) + bpos = 0; + + int pspos = spos; + for(flux_per_pixel_info *p : m_flux_per_combined_track_infos[track].m_pixels[head]) { + int spos = p->m_position - pcti->m_span; + int epos = p->m_position + pcti->m_span; + if(spos < 0) + spos += 200000000; + if(epos >= 200000000) + epos -= 200000000; + + if(spos < pspos) + bpos = 0; + while(bpos != sz-1 && (buffer[bpos+1] & floppy_image::TIME_MASK) < spos) + bpos ++; + + int bpos2 = spos < epos ? bpos : 0; + while(bpos2 != sz-1 && (buffer[bpos2+1] & floppy_image::TIME_MASK) < epos) + bpos2 ++; + + int count; + if(bpos <= bpos2) + count = bpos2 - bpos; + else { + count = (sz - 1 - bpos) + bpos2; + if((buffer[0] ^ buffer[sz-1]) & floppy_image::MG_MASK) + count ++; + } + + count *= 5; + if(count > 255) + count = 255; + p->m_color = 255 - count; + pspos = spos; + } +} + +uint32_t floppy_image_device::flux_screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + if(image.get()) { + int ctrack = ((cyl << 2) | subcyl) >> (2 - image->get_resolution()); + if(mon) + ctrack = -1; + for(int y = cliprect.min_y; y <= cliprect.max_y; y++) { + int head = y >= flux_screen_sy / 2; + flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data() + y * flux_screen_sx + cliprect.min_x; + uint32_t *p = &bitmap.pix(y, cliprect.min_x); + for(int x = cliprect.min_x; x <= cliprect.max_x; x++) { + if(ppi->m_position == 0xffffffff) + *p++ = 0; + else { + u32 color = 0x010101 * ppi->m_color; + if(ppi->m_combined_track == ctrack && head == ss) + color &= 0x0000ff; + *p++ = color; + } + ppi++; + } + } + } else { + for(int y = cliprect.min_y; y <= cliprect.max_y; y++) { + flux_per_pixel_info *ppi = m_flux_per_pixel_infos.data() + y * flux_screen_sx + cliprect.min_x; + uint32_t *p = &bitmap.pix(y, cliprect.min_x); + for(int x = cliprect.min_x; x <= cliprect.max_x; x++) { + if(ppi->m_position == 0xffffffff) + *p++ = 0; + else + *p++ = 0x404040; + ppi++; + } + } + } + + return 0; +} + void floppy_image_device::call_unload() { cache_clear(); @@ -629,7 +795,7 @@ image_init_result floppy_image_device::call_create(int format_type, util::option output_format = nullptr; // search for a suitable format based on the extension - for(floppy_image_format_t *i = fif_list; i; i = i->next) + for(floppy_image_format_t *i : fif_list) { // only consider formats that actually support saving if(!i->supports_save()) @@ -648,6 +814,8 @@ image_init_result floppy_image_device::call_create(int format_type, util::option init_floppy_load(true); + flux_image_prepare(); + return image_init_result::PASS; } @@ -881,6 +1049,11 @@ void floppy_image_device::stp_w(int state) cache_clear(); stp = state; if ( stp == 0 ) { + if(FLUX_SCREEN && track_dirty) { + flux_image_compute_for_track(((cyl << 2) | subcyl) >> (2 - image->get_resolution()), ss); + track_dirty = false; + } + int ocyl = cyl; if ( dir ) { if ( cyl ) cyl--; @@ -936,6 +1109,12 @@ void floppy_image_device::seek_phase_w(int _phases) next_pos = 0; else if(next_pos > (tracks-1)*4) next_pos = (tracks-1)*4; + + if(FLUX_SCREEN && track_dirty) { + flux_image_compute_for_track(((cyl << 2) | subcyl) >> (2 - image->get_resolution()), ss); + track_dirty = false; + } + cyl = next_pos >> 2; subcyl = next_pos & 3; @@ -1094,7 +1273,7 @@ void floppy_image_device::cache_weakness_setup() return; } - cache_weak = cache_end_time.is_never() || (cache_end_time - cache_start_time >= attotime::from_usec(16)); + cache_weak = cache_end_time.is_never() || (cache_end_time - cache_start_time >= amplifier_freakout_time); if(!cache_weak) { cache_weak_start = attotime::never; return; @@ -1145,6 +1324,7 @@ void floppy_image_device::write_flux(const attotime &start, const attotime &end, return; image_dirty = true; + track_dirty = true; cache_clear(); attotime base; @@ -1704,6 +1884,14 @@ void floppy_image_device::device_add_mconfig(machine_config &config) { SPEAKER(config, FLOPSPK).front_center(); FLOPPYSOUND(config, FLOPSND_TAG, 44100).add_route(ALL_OUTPUTS, FLOPSPK, 0.5); + + if (FLUX_SCREEN) + { + SCREEN(config, m_flux_screen, SCREEN_TYPE_RASTER); + m_flux_screen->set_screen_update(FUNC(floppy_image_device::flux_screen_update)); + m_flux_screen->set_raw(30*(flux_screen_sx+1)*(flux_screen_sy+1), flux_screen_sx+1, 0, flux_screen_sx, flux_screen_sy+1, 0, flux_screen_sy); + m_flux_screen->set_physical_aspect(1, 2); + } } @@ -1907,6 +2095,31 @@ void floppy_525_sd_35t::setup_characteristics() set_rpm(300); variants.push_back(floppy_image::SSSD); + variants.push_back(floppy_image::DSSD); +} + +//------------------------------------------------- +// 5.25" single-sided single density, VTECH edition +//------------------------------------------------- + +floppy_525_vtech::floppy_525_vtech(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + floppy_image_device(mconfig, FLOPPY_525_VTECH, tag, owner, clock) +{ + amplifier_freakout_time = attotime::from_usec(64); +} + +floppy_525_vtech::~floppy_525_vtech() +{ +} + +void floppy_525_vtech::setup_characteristics() +{ + form_factor = floppy_image::FF_525; + tracks = 40; + sides = 1; + set_rpm(85); + + variants.push_back(floppy_image::SSSD); } //------------------------------------------------- |