summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/imagedev/floppy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/imagedev/floppy.cpp')
-rw-r--r--src/devices/imagedev/floppy.cpp172
1 files changed, 171 insertions, 1 deletions
diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp
index c73b7c87cb0..e0212fff4c2 100644
--- a/src/devices/imagedev/floppy.cpp
+++ b/src/devices/imagedev/floppy.cpp
@@ -24,6 +24,7 @@
#include "formats/fs_unformatted.h"
#include "formats/fsblk_vec.h"
+#include "screen.h"
#include "speaker.h"
#include "formats/imageutl.h"
#include "zippath.h"
@@ -38,6 +39,8 @@
#define PITCH_SEEK_SAMPLES 1
+#define FLUX_SCREEN 0
+
#define FLOPSND_TAG "floppysound"
// device type definition
@@ -261,7 +264,8 @@ floppy_image_device::floppy_image_device(const machine_config &mconfig, device_t
image_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;
@@ -475,6 +479,27 @@ void floppy_image_device::device_start()
save_item(NAME(image_dirty));
save_item(NAME(ready_counter));
save_item(NAME(phases));
+
+ 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()
@@ -592,9 +617,143 @@ 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()
+{
+ 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();
@@ -650,6 +809,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;
}
@@ -1207,6 +1368,8 @@ void floppy_image_device::write_flux(const attotime &start, const attotime &end,
}
buf.resize(cells);
+
+ flux_image_compute_for_track(((cyl << 2) | subcyl) >> (2 - image->get_resolution()), ss);
}
void floppy_image_device::write_zone(uint32_t *buf, int &cells, int &index, uint32_t spos, uint32_t epos, uint32_t mg)
@@ -1706,6 +1869,13 @@ 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);
+#endif
}