OSDN Git Service

[VM][General] Add support T77 image ,XM7-Tape-Image.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 27 Feb 2015 07:42:22 +0000 (16:42 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 27 Feb 2015 07:42:22 +0000 (16:42 +0900)
source/src/qt/gui/menu_cmt.cpp
source/src/vm/datarec.cpp
source/src/vm/datarec.h

index c94b5d9..1f71fc3 100644 (file)
@@ -48,11 +48,11 @@ void Ui_MainWindow::open_cmt_dialog(bool play)
 #elif defined(_PC8001SR) || defined(_PC8801MA) || defined(_PC98DO)
   ext = play ? "*.cas *.cmt *.n80 *.t88" : "*.cas *.cmt";
 #elif defined(_MZ80A) || defined(_MZ80K) || defined(_MZ1200) || defined(_MZ700) || defined(_MZ800) || defined(_MZ1500)
-  ext = play ? "*.wav *.cas *.mzt *.m12" :"*.wav *.cas";
+  ext = play ? "*.wav *.cas *.mzt *.m12 *.t77" :"*.wav *.cas";
 #elif defined(_MZ80B) || defined(_MZ2000) || defined(_MZ2200)
   ext = play ? "*.wav *.cas *.mzt *.mti *.mtw *.dat" : "*.wav *.cas";
 #elif defined(_X1) || defined(_X1TWIN) || defined(_X1TURBO) || defined(_X1TURBOZ)
-  ext = play ? "*.wav *.cas *.tap" : "*.wav *.cas";
+  ext = play ? "*.wav *.cas *.tap *.t77" : "*.wav *.cas";
 #elif defined(_FM7) || defined(_FM77) || defined(_FM77AV) || defined(_FM77AV40)
   ext = "*.wav *.t77";
 #elif defined(TAPE_BINARY_ONLY)
index c58229a..6bca0bc 100644 (file)
@@ -268,11 +268,135 @@ void DATAREC::event_callback(int event_id, int err)
                        prev_clock = current_clock();
                        positive_clocks = negative_clocks = 0;
                }
+       } else if(event_id == EVENT_UPDATE_T77) {
+               if(rec) {
+                       is_t77 = false;
+                       register_event(this, EVENT_SIGNAL, 9.0, false, &register_id); // SKIP
+               }
+               if(play) {
+                       if(total_count < total_length && ff_rew == 0) {
+                               emu->out_message(_T("CMT: Play (%d %%)"), get_tape_ptr());
+                       }
+                       bool signal = in_signal;
+                       if(ff_rew == 0) {
+                               uint8 hi, lo;
+                               double usec;
+                               if(buffer_ptr < buffer_length) {
+                                       hi = buffer[buffer_ptr++];
+                                       lo = buffer[buffer_ptr++];
+                                       rawdata = ((uint16)hi << 8) | (uint16)lo;
+                                       if((rawdata & 0x8000) == 0) {
+                                               signal = false;
+                                       } else {
+                                               signal = true;
+                                       }
+                                       total_count = total_count + (rawdata & 0x7fff); 
+                                       usec = (double)(rawdata & 0x7fff);
+                                       usec = usec * 9.0;
+                                       register_event(this, EVENT_UPDATE_T77, usec, false, &register_id); // NEXT CYCLE
+                               } else {
+                                       signal = false;
+                               }
+                       } else  if(ff_rew < 0) {
+                               if((buffer_ptr = max(buffer_ptr - 1, 0)) == 0) {
+                                       set_remote(false);      // top of tape
+                                       signal = false;
+                               } else {
+                                       uint8 hi, lo;
+                                       uint32 count = 0;
+                                       int i;
+                                       for(i = 0; i < 8; i++) {
+                                               hi = buffer[buffer_ptr];
+                                               lo = buffer[buffer_ptr + 1];
+                                               count = count + (((uint32)hi << 8) | (uint32)lo) & 0x7fff;
+                                               buffer_ptr -= 2;
+                                               if(buffer_ptr < 0) break;
+                                       }
+                                       signal = false;
+                                       if(buffer_ptr >= 0) {
+                                               register_event(this, EVENT_UPDATE_T77, (double)count * 9.0, false, &register_id); // NEXT CYCLE
+                                       } else {
+                                               set_remote(false);
+                                       }
+                               }
+                       } else {
+                               if((buffer_ptr = min(buffer_ptr + 1, buffer_length)) == buffer_length) {
+                                       set_remote(false);      // end of tape
+                                       signal = false;
+                               } else  {
+                                       uint8 hi, lo;
+                                       uint32 count = 0;
+                                       int i;
+                                       for(i = 0; i < 8; i++) {
+                                               hi = buffer[buffer_ptr];
+                                               lo = buffer[buffer_ptr + 1];
+                                               count = count + (((uint32)hi << 8) | (uint32)lo) & 0x7fff;
+                                               buffer_ptr += 2;
+                                               if(buffer_ptr >= buffer_length) break;
+                                       }
+                                       signal = false;
+                                       if(buffer_ptr <= buffer_length) {
+                                               register_event(this, EVENT_UPDATE_T77, (double)count * 9.0, false, &register_id); // NEXT CYCLE
+                                       } else {
+                                               set_remote(false);
+                                       }
+                               }
+                       }
+                       if(signal != in_signal) {
+                               in_signal = signal;
+#ifdef DATAREC_SOUND
+                               {
+                                       if(ff_rew == 0) {
+                                               if(signal) {
+                                                       sound_sample =  mix_datarec_volume;
+                                               } else {
+                                                       sound_sample = -mix_datarec_volume;
+                                               }
+                                       } else {
+                                               sound_sample = 0;
+                                       }
+                               }
+#endif
+                               signal_changed++;
+                               write_signals(&outputs_out, in_signal ? 0xffffffff : 0);
+                       }
+#if 1                  // chek apss state
+                       if(apss_buffer != NULL) {
+                               int ptr = (apss_ptr++) % (sample_rate * 2);
+                               if(apss_buffer[ptr]) {
+                                       apss_count--;
+                               }
+                               if(in_signal) {
+                                       apss_count++;
+                               }
+                               apss_buffer[ptr] = in_signal;
+                               
+                               if(apss_ptr >= sample_rate * 2) {
+                                       double rate = (double)apss_count / (double)(sample_rate * 2);
+                                       if(rate > 0.9 || rate < 0.1) {
+                                               if(apss_signals) {
+                                                       if(apss_remain > 0) {
+                                                               apss_remain--;
+                                                       } else if(apss_remain < 0) {
+                                                               apss_remain++;
+                                                       }
+                                                       write_signals(&outputs_apss, 0xffffffff);
+                                                       apss_signals = false;
+                                               }
+                                       } else {
+                                               if(!apss_signals) {
+                                                       write_signals(&outputs_apss, 0);
+                                                       apss_signals = true;
+                                               }
+                                       }
+                               }
+                       }
+#endif
+               }
+               update_event();
        }
 }
 
-
-
 void DATAREC::set_remote(bool value)
 {
        if(remote != value) {
@@ -327,17 +451,26 @@ void DATAREC::update_event()
        if(remote && (play || rec)) {
                if(register_id == -1) {
                        if(ff_rew != 0) {
-                               register_event(this, EVENT_SIGNAL, 1000000. / sample_rate / DATAREC_FF_REW_SPEED, true, &register_id);
+                         if(is_t77) {
+                               register_event(this, EVENT_UPDATE_T77,  9.0, false, &register_id);
+                         } else {
+                               register_event(this, EVENT_SIGNAL, 1000000. / sample_rate / DATAREC_FF_REW_SPEED, true, &register_id);
+                         }
                                if(ff_rew > 0) {
                                        emu->out_message(_T("CMT: Fast Forward"));
                                } else {
                                        emu->out_message(_T("CMT: Fast Rewind"));
                                }
                        } else {
-                               register_event(this, EVENT_SIGNAL, 1000000. / sample_rate, true, &register_id);
+                               if(is_t77) {
+                                       if(register_id == -1) register_event(this, EVENT_UPDATE_T77, 9.0, false, &register_id);
+                               } else {
+                                       register_event(this, EVENT_SIGNAL, 1000000. / sample_rate, true, &register_id);
+                               }
                                if(play) {
-                                       if(buffer_ptr < buffer_length) {
-                                               emu->out_message(_T("CMT: Play (%d %%)"), 100 * buffer_ptr / buffer_length);
+                                       int l = get_tape_ptr();
+                                       if((l >= 0) && (l <= 100)) {
+                                               emu->out_message(_T("CMT: Play (%d %%)"), l);
                                        } else {
                                                emu->out_message(_T("CMT: Play"));
                                        }
@@ -429,6 +562,13 @@ bool DATAREC::play_tape(_TCHAR* file_path)
                                load_cas_image();
                                play = is_wav = true;
                        }
+               } else if(check_file_extension(file_path, _T(".t77"))) {
+                       // standard cas image for my emulator
+                       if((buffer_length = load_t77_image()) != 0) {
+                               buffer = (uint8 *)malloc(buffer_length);
+                               load_t77_image();
+                               play = is_wav = true;
+                       }
                }
                play_fio->Fclose();
        }
@@ -444,7 +584,6 @@ bool DATAREC::play_tape(_TCHAR* file_path)
                        write_signals(&outputs_out, signal ? 0xffffffff : 0);
                        in_signal = signal;
                }
-               
                // initialize apss
                apss_buffer_length = sample_rate * 2;
                apss_buffer = (bool *)calloc(apss_buffer_length, 1);
@@ -477,6 +616,7 @@ bool DATAREC::rec_tape(_TCHAR* file_path)
                        // initialize buffer
                        buffer[0] = out_signal ? 0x80 : 0;
                }
+               is_t77 = false;
                rec = true;
                update_event();
        }
@@ -488,6 +628,7 @@ void DATAREC::close_tape()
        close_file();
        
        play = rec = is_wav = false;
+       is_t77 = false;
        buffer_ptr = buffer_length = 0;
        update_event();
        
@@ -544,8 +685,10 @@ int DATAREC::load_cas_image()
        play_fio->Fread(tmp_header, sizeof(tmp_header), 1);
        
        if(memcmp(tmp_header, "SORDM5", 6) == 0) {
+               is_t77 = false;
                return load_m5_cas_image();
        } else if(memcmp(tmp_header, momomomomomo, 6) == 0) {
+               is_t77 = false;
                return load_p6_image(false);
        }
        
@@ -560,6 +703,7 @@ int DATAREC::load_cas_image()
                        ptr++;
                }
        }
+       is_t77 = false;
        return ptr;
 }
 
@@ -574,6 +718,7 @@ int DATAREC::load_wav_image(int offset)
        play_fio->Fseek(offset, FILEIO_SEEK_SET);
        play_fio->Fread(&header, sizeof(header), 1);
        if(header.format_id != 1 || !(header.sample_bits == 8 || header.sample_bits == 16)) {
+               is_t77 = false;
                return 0;
        }
        play_fio->Fseek(header.fmt_chunk.size - 16, FILEIO_SEEK_CUR);
@@ -791,6 +936,7 @@ int DATAREC::load_wav_image(int offset)
                }
                free(tmp_buffer);
        }
+       is_t77 = false;
        return loaded_samples;
 }
 
@@ -801,7 +947,7 @@ void DATAREC::save_wav_image()
                rec_fio->Fwrite(buffer, buffer_ptr, 1);
        }
        uint32 length = rec_fio->Ftell();
-       
+       is_t77 = false; 
        wav_header_t wav_header;
        wav_chunk_t wav_chunk;
        
@@ -918,6 +1064,7 @@ int DATAREC::load_p6_image(bool is_p6t)
        
        int ptr = 0, remain = 0x10000, data;
        if(is_p6t) {
+               is_t77 = false;
                // get info block offset
                play_fio->Fseek(-4, FILEIO_SEEK_END);
                int length = play_fio->FgetInt32();
@@ -1028,6 +1175,7 @@ int DATAREC::load_tap_image()
        // check header
        uint8 header[4];
        play_fio->Fread(header, 4, 1);
+       is_t77 = false;
        
        if(header[0] == 'T' && header[1] == 'A' && header[2] == 'P' && header[3] == 'E') {
                // skip name, reserved, write protect notch
@@ -1133,6 +1281,7 @@ int DATAREC::load_mzt_image()
        play_fio->Fseek(0, FILEIO_SEEK_END);
        int file_size = play_fio->Ftell();
        play_fio->Fseek(0, FILEIO_SEEK_SET);
+       is_t77 = false;
        
        // load mzt file
        int ptr = 0;
@@ -1208,6 +1357,66 @@ int DATAREC::load_mzt_image()
        return ptr;
 }
 
+// T77 File. for FM-7.
+// See http://retropc.net/ryu/xm7/t77form.html .
+int DATAREC::load_t77_image(void)
+{
+       uint8 tmpbuf[17];
+       int file_size;
+       
+       total_count = 0;
+       total_length = 0;
+       sample_rate = 1.0e6 / 9.0;
+       is_t77 = false;
+       // Check Length
+       memset(tmpbuf, 0x00, 17);
+       
+       play_fio->Fseek(0, FILEIO_SEEK_END);
+       file_size = play_fio->Ftell();
+       //if(buffer_length < 18) return 0;
+       // Check MAGIC
+       play_fio->Fseek(0, FILEIO_SEEK_SET);
+       play_fio->Fread(tmpbuf, 16, 1);
+       tmpbuf[16] = '\0';
+       if(strcmp(tmpbuf, "XM7 TAPE IMAGE 0") != 0) return 0;
+       buffer_ptr = 0;
+       file_size = file_size - 16;
+       // MAGIC Ok.
+       is_t77 = true;
+       if(buffer == NULL) {
+               return file_size;
+       }
+       // OK, Now Read.
+       play_fio->Fread(buffer, file_size, 1);
+       //play_fio->Fclose();
+       
+       {
+               int tptr;
+               uint8 lo, hi;
+               uint64 val;
+               for(tptr = 0; tptr < file_size; tptr += 2) {
+                       hi = buffer[tptr];
+                       lo = buffer[tptr + 1];
+                       val = (hi * 256 + lo) & 0x7fff;
+                       total_length += val;
+               }
+       }
+       return file_size;
+}
+
+
+int DATAREC::get_tape_ptr(void)
+{
+       if(!is_t77) {
+               if((buffer_length == 0) || (buffer == NULL)) return -1;
+               return (100 * buffer_ptr) / buffer_length;
+       } else { // T77
+               if(total_count == 0) return -1;
+               return ((total_count * 100) / total_length);
+       }
+}
+
+
 #ifdef DATAREC_SOUND
 void DATAREC::mix(int32* sndbuffer, int cnt)
 {
index 83f8349..1915a42 100644 (file)
@@ -66,6 +66,9 @@ protected:
        int16 mix_datarec_volume;
 #endif
        bool is_wav;
+       bool is_t77;
+       int total_length, total_count;
+       uint16 rawdata;
        
        int apss_buffer_length;
        bool *apss_buffer;
@@ -81,7 +84,9 @@ protected:
        int load_m5_cas_image();
        int load_p6_image(bool is_p6t);
        int load_tap_image();
+       int load_t77_image();
        int load_mzt_image();
+       
 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)   
         unsigned int min(int x, unsigned int y) {
           if((unsigned int)x < y) return (unsigned int)x;
@@ -161,10 +166,7 @@ public:
        void set_remote(bool value);
        void set_ff_rew(int value);
        bool do_apss(int value);
-        virtual int get_tape_ptr(void) {
-               if((buffer_length == 0) || (buffer == NULL)) return -1;
-               return (100 * buffer_ptr) / buffer_length;
-       };
+        int get_tape_ptr(void);
    
 //#ifdef DATAREC_SOUND
 //     void initialize_sound(int rate, int samples);