OSDN Git Service

[VM][General] Apply Upstream 2018-10-07.Still WIP.
[csp-qt/common_source_project-fm7.git] / source / src / vm / prnfile.cpp
index 53d591f..2fc3c93 100644 (file)
@@ -9,13 +9,29 @@
 
 #include "prnfile.h"
 
+#define EVENT_BUSY     0
+#define EVENT_ACK      1
+
 void PRNFILE::initialize()
 {
+       DEVICE::initialize();
        fio = new FILEIO();
-       register_frame_event(this);
        
-       value = -1;
-       strobe = false;
+       value = busy_id = ack_id = wait_frames = -1;
+       _PRINTER_STROBE_RISING_EDGE = osd->check_feature(_T("PRINTER_STROBE_RISING_EDGE"));
+//#ifdef PRINTER_STROBE_RISING_EDGE
+       if(_PRINTER_STROBE_RISING_EDGE) {
+               strobe = false;
+       } else {
+//#else
+       strobe = true;
+       }
+//#endif
+       res = busy = false;
+       set_busy(false);
+       set_ack(true);
+       
+       register_frame_event(this);
 }
 
 void PRNFILE::release()
@@ -27,52 +43,115 @@ void PRNFILE::release()
 void PRNFILE::reset()
 {
        close_file();
-       value = -1;
-       strobe = false;
+       
+       busy_id = ack_id = wait_frames = -1;
+       set_busy(false);
+       set_ack(true);
 }
 
 void PRNFILE::event_frame()
 {
-       if(fio->IsOpened() && --wait_frames == 0) {
+       if(wait_frames > 0 && --wait_frames == 0) {
                close_file();
        }
 }
 
-void PRNFILE::write_signal(int id, uint32 data, uint32 mask)
+void PRNFILE::write_signal(int id, uint32_t data, uint32_t mask)
 {
        if(id == SIG_PRINTER_DATA) {
-               value = data;
+               if(value == -1) {
+                       value = 0;
+               }
+               value &= ~mask;
+               value |= (data & mask);
        } else if(id == SIG_PRINTER_STROBE) {
-               bool new_strobe = ((data & mask) == 0);
-               bool falling = (strobe && !new_strobe);
+               bool new_strobe = ((data & mask) != 0);
+//#ifdef PRINTER_STROBE_RISING_EDGE
+               bool edge;
+               if(_PRINTER_STROBE_RISING_EDGE) {
+                       edge = (!strobe && new_strobe);
+               } else {
+//#else
+                       edge = (strobe && !new_strobe);
+               }
+//#endif
                strobe = new_strobe;
                
-               if(falling) {
+               if(edge && value != -1) {
                        if(!fio->IsOpened()) {
-                               if(value == -1) {
-                                       return;
-                               }
                                open_file();
                        }
                        fio->Fputc(value);
-                       // wait 10sec
-#ifdef SUPPORT_VARIABLE_TIMING
-                       wait_frames = (int)(vm->frame_rate() * 10.0 + 0.5);
-#else
-                       wait_frames = (int)(FRAMES_PER_SEC * 10.0 + 0.5);
-#endif
+                       
+                       // busy 1msec
+                       if(busy_id != -1) {
+                               cancel_event(this, busy_id);
+                       }
+                       register_event(this, EVENT_BUSY, 10000.0, false, &busy_id);
+                       set_busy(true);
+                       
+                       // wait 1sec and finish printing
+                       wait_frames = (int)(vm->get_frame_rate() * 1.0 + 0.5);
+               }
+       } else if(id == SIG_PRINTER_RESET) {
+               bool new_res = ((data & mask) != 0);
+               if(res && !new_res) {
+                       reset();
                }
+               res = new_res;
        }
 }
 
-uint32 PRNFILE::read_signal(int ch)
+uint32_t PRNFILE::read_signal(int ch)
 {
        if(ch == SIG_PRINTER_BUSY) {
-               return 0;
+               if(busy) {
+                       if(busy_id != -1) {
+                               cancel_event(this, busy_id);
+                               busy_id = -1;
+                       }
+                       set_busy(false);
+                       return 0xffffffff;
+               }
+       } else if(ch == SIG_PRINTER_ACK) {
+               if(ack) {
+                       return 0xffffffff;
+               }
        }
        return 0;
 }
 
+void PRNFILE::event_callback(int event_id, int err)
+{
+       if(event_id == EVENT_BUSY) {
+               busy_id = -1;
+               set_busy(false);
+       } else if(event_id == EVENT_ACK) {
+               ack_id = -1;
+               set_ack(true);
+       }
+}
+
+void PRNFILE::set_busy(bool value)
+{
+       if(busy && !value) {
+               // ack 10usec
+               if(ack_id != -1) {
+                       cancel_event(this, ack_id);
+               }
+               register_event(this, EVENT_ACK, 10.0, false, &ack_id);
+               set_ack(false);
+       }
+       busy = value;
+       write_signals(&outputs_busy, busy ? 0xffffffff : 0);
+}
+
+void PRNFILE::set_ack(bool value)
+{
+       ack = value;
+       write_signals(&outputs_ack, ack ? 0xffffffff : 0);
+}
+
 void PRNFILE::open_file()
 {
        create_date_file_path(file_path, _MAX_PATH, _T("txt"));
@@ -91,3 +170,32 @@ void PRNFILE::close_file()
        }
 }
 
+#define STATE_VERSION  2
+
+bool PRNFILE::process_state(FILEIO* state_fio, bool loading)
+{
+       if(loading) {
+               //close_file();
+       }
+       
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       state_fio->StateInt32(value);
+       state_fio->StateInt32(busy_id);
+       state_fio->StateInt32(ack_id);
+       state_fio->StateBool(strobe);
+       state_fio->StateBool(res);
+       state_fio->StateBool(busy);
+       state_fio->StateBool(ack);
+       
+       // post process
+       if(loading) {
+               wait_frames = -1;
+       }
+       return true;
+}
+