1 /*
2    Copyright (C) 1998,1999 Scott Dattalo
3    Copyright (C) 2014	Roy R. Rankin
4 
5 This file is part of the libgpsim library of gpsim
6 
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11 
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, see
19 <http://www.gnu.org/licenses/lgpl-2.1.html>.
20 */
21 
22 #include <stdio.h>
23 #include <iostream>
24 
25 #include "../config.h"
26 
27 #include "uart.h"
28 #include <assert.h>     // for assert
29 #include "pir.h"        // for PIR
30 #include "processor.h"  // for Processor
31 #include "stimuli.h"    // for IOPIN, SignalSink
32 #include "trace.h"      // for Trace, trace
33 
34 #define p_cpu ((Processor *)cpu)
35 
36 
37 // defining EUSART_PIN  causes TX pin direction to be set for EUSART devices
38 #define EUSART_PIN
39 //#define DEBUG
40 #if defined(DEBUG)
41 #define Dprintf(arg) {printf("%s:%d-%s() ",__FILE__,__LINE__,__FUNCTION__); printf arg; }
42 #else
43 #define Dprintf(arg) {}
44 #endif
45 
46 //--------------------------------------------------
47 //
48 //--------------------------------------------------
49 // Drive output for TX pin
50 class TXSignalSource : public SignalControl
51 {
52 public:
TXSignalSource(_TXSTA * _txsta)53     explicit TXSignalSource(_TXSTA *_txsta)
54         : m_txsta(_txsta)
55     {
56         assert(m_txsta);
57     }
~TXSignalSource()58     ~TXSignalSource() { }
getState()59     virtual char getState()
60     {
61         return m_txsta->getState();
62     }
release()63     virtual void release()
64     {
65         m_txsta->releasePin();
66     }
67 private:
68     _TXSTA *m_txsta;
69 };
70 
71 // Set TX pin to output
72 class TXSignalControl : public SignalControl
73 {
74 public:
TXSignalControl(_TXSTA * _txsta)75     explicit TXSignalControl(_TXSTA *_txsta)
76         : m_txsta(_txsta)
77     { }
~TXSignalControl()78     ~TXSignalControl() { }
getState()79     virtual char getState() { return '0'; }
release()80     virtual void release()
81     {
82         m_txsta->releasePin();
83     }
84 private:
85     _TXSTA *m_txsta;
86 };
87 
88 // set Synchronous DT pin direction
89 class RCSignalControl : public SignalControl
90 {
91 public:
RCSignalControl(_RCSTA * _rcsta)92     explicit RCSignalControl(_RCSTA *_rcsta)
93         : m_rcsta(_rcsta)
94     { }
~RCSignalControl()95     ~RCSignalControl() { }
getState()96     virtual char getState() { return '0'; }
97     //virtual char getState() { return m_rcsta->getDir(); }
release()98     virtual void release()
99     {
100         m_rcsta->releasePin();
101     }
102 private:
103     _RCSTA *m_rcsta;
104 };
105 
106 // Drive date of DT  pin when transmitting
107 class RCSignalSource : public SignalControl
108 {
109 public:
RCSignalSource(_RCSTA * _rcsta)110     explicit RCSignalSource(_RCSTA *_rcsta)
111         : m_rcsta(_rcsta)
112     {
113         assert(m_rcsta);
114     }
~RCSignalSource()115     ~RCSignalSource() { }
getState()116     virtual char getState()
117     {
118         return m_rcsta->getState();
119     }
release()120     virtual void release()
121     {
122         m_rcsta->releasePin();
123     }
124 private:
125     _RCSTA *m_rcsta;
126 };
127 
128 //--------------------------------------------------
129 //
130 //--------------------------------------------------
131 
132 // Report state changes on incoming RX pin
133 class RXSignalSink : public SignalSink
134 {
135 public:
RXSignalSink(_RCSTA * _rcsta)136     explicit RXSignalSink(_RCSTA *_rcsta)
137         : m_rcsta(_rcsta)
138     {
139         assert(_rcsta);
140     }
141 
setSinkState(char new3State)142     virtual void setSinkState(char new3State) { m_rcsta->setState(new3State); }
release()143     virtual void release() {delete this; }
144 private:
145     _RCSTA *m_rcsta;
146 };
147 
148 //--------------------------------------------------
149 //
150 //--------------------------------------------------
151 
152 // Report state changes on incoming Clock pin for Synchronous slave mode
153 class CLKSignalSink : public SignalSink
154 {
155 public:
CLKSignalSink(_RCSTA * _rcsta)156     explicit CLKSignalSink(_RCSTA *_rcsta)
157         : m_rcsta(_rcsta)
158     {
159         assert(_rcsta);
160     }
161 
setSinkState(char new3State)162     virtual void setSinkState(char new3State) { m_rcsta->clock_edge(new3State); }
163 //  virtual void release() { delete this; }
release()164     virtual void release() {delete this; }
165 private:
166     _RCSTA *m_rcsta;
167 };
168 
169 //-----------------------------------------------------------
_RCSTA(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)170 _RCSTA::_RCSTA(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
171     : sfr_register(pCpu, pName, pDesc),
172       rcreg(0), spbrg(0),
173       txsta(0), txreg(nullptr), sync_next_clock_edge_high(false),
174       rsr(0), bit_count(0), rx_bit(0), sample(0),
175       state(_RCSTA::RCSTA_DISABLED), sample_state(0),
176       future_cycle(0), last_cycle(0),
177       mUSART(pUSART),
178       m_PinModule(0), m_sink(0), m_cRxState('?'),
179       SourceActive(false), m_control(0), m_source(0), m_cTxState('\0'),
180       m_DTdirection('0'), bInvertPin(false),
181       old_clock_state(true)
182 {
183     assert(mUSART);
184 }
185 
~_RCSTA()186 _RCSTA::~_RCSTA()
187 {
188     if (SourceActive && m_PinModule)
189     {
190         m_PinModule->setSource(0);
191         m_PinModule->setControl(0);
192     }
193 
194     delete m_source;
195     delete m_control;
196 }
197 
198 //-----------------------------------------------------------
_TXSTA(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)199 _TXSTA::_TXSTA(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
200     : sfr_register(pCpu, pName, pDesc), txreg(0), spbrg(0),
201       rcsta(nullptr), tsr(0), bit_count(0),
202       mUSART(pUSART),
203       m_PinModule(0),
204       m_source(0),
205       m_control(0),
206       m_clkSink(0),
207       SourceActive(false),
208       m_cTxState('?'),
209       bInvertPin(false)
210 {
211     assert(mUSART);
212 }
213 
~_TXSTA()214 _TXSTA::~_TXSTA()
215 {
216     if (SourceActive && m_PinModule)
217     {
218         m_PinModule->setSource(0);
219         m_PinModule->setControl(0);
220     }
221 
222     delete m_source;
223     delete m_control;
224 }
225 
226 //-----------------------------------------------------------
_RCREG(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)227 _RCREG::_RCREG(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
228     : sfr_register(pCpu, pName, pDesc),
229       oldest_value(0), fifo_sp(0),  mUSART(pUSART), m_rcsta(0)
230 {
231     assert(mUSART);
232 }
233 
_TXREG(Processor * pCpu,const char * pName,const char * pDesc,USART_MODULE * pUSART)234 _TXREG::_TXREG(Processor *pCpu, const char *pName, const char *pDesc, USART_MODULE *pUSART)
235     : sfr_register(pCpu, pName, pDesc), m_txsta(0), m_rcsta(nullptr),
236       mUSART(pUSART), full(false)
237 {
238     assert(mUSART);
239 }
240 
241 
_BAUDCON(Processor * pCpu,const char * pName,const char * pDesc)242 _BAUDCON::_BAUDCON(Processor *pCpu, const char *pName, const char *pDesc)
243     : sfr_register(pCpu, pName, pDesc),
244       txsta(nullptr), rcsta(nullptr)
245 {
246 }
247 
_SPBRG(Processor * pCpu,const char * pName,const char * pDesc)248 _SPBRG::_SPBRG(Processor *pCpu, const char *pName, const char *pDesc)
249     : sfr_register(pCpu, pName, pDesc),
250       txsta(0), rcsta(0), brgh(0), baudcon(0), start_cycle(0), last_cycle(0),
251       future_cycle(0), running(false), skip(0)
252 {
253 }
254 
255 
_SPBRGH(Processor * pCpu,const char * pName,const char * pDesc)256 _SPBRGH::_SPBRGH(Processor *pCpu, const char *pName, const char *pDesc)
257     : sfr_register(pCpu, pName, pDesc), m_spbrg(0)
258 {
259 }
260 
261 //-----------------------------------------------------------
262 // TXREG - USART Transmit Register
263 //
264 // writing to this register causes the PIR1::TXIF bit to clear.
265 // my reading of the spec is this happens at the end of the next pic
266 // instruction. If the shift register is empty the bit will then be set
267 // one pic instruction later. Otherwise the bit is set when the shift
268 // register empties.  RRR 10/2014
269 
270 
put(unsigned int new_value)271 void _TXREG::put(unsigned int new_value)
272 {
273 
274     trace.raw(write_trace.get() | value.get());
275     value.put(new_value & 0xff);
276 
277     Dprintf(("txreg just got a new value:0x%x\n",new_value));
278     assert(m_txsta);
279     assert(m_rcsta);
280 
281     // The transmit register has data,
282     // so clear the TXIF flag
283 
284     full = true;
285     get_cycles().set_break(get_cycles().get() + 1, this);
286 
287     if(m_txsta->bTRMT() && m_txsta->bTXEN())
288     {
289         // If the transmit buffer is empty and the transmitter is enabled
290         // then transmit this new data now...
291 
292         get_cycles().set_break(get_cycles().get() + 2, this);
293         if (m_txsta->bSYNC())
294             m_rcsta->sync_start_transmitting();
295         else
296             m_txsta->start_transmitting();
297     }
298     else if(m_txsta->bTRMT() && m_txsta->bSYNC())
299     {
300         m_txsta->value.put(m_txsta->value.get() & ~ _TXSTA::TRMT);
301     }
302 
303 }
304 
put_value(unsigned int new_value)305 void _TXREG::put_value(unsigned int new_value)
306 {
307     put(new_value);
308 
309     update();
310 }
311 
callback()312 void _TXREG::callback()
313 {
314     Dprintf(("TXREG callback - time:%" PRINTF_GINT64_MODIFIER "x full %d\n",get_cycles().get(), full));
315     if (full)
316     {
317         mUSART->full();
318         full = false;
319     }
320     else
321     {
322         mUSART->emptyTX();
323     }
324 }
callback_print()325 void _TXREG::callback_print()
326 {
327     std::cout << "TXREG " << name() << " CallBack ID " << CallBackID << '\n';
328 }
329 //-----------------------------------------------------------
330 // TXSTA - setIOpin - assign the I/O pin associated with the
331 // the transmitter.
332 
333 
setIOpin(PinModule * newPinModule)334 void _TXSTA::setIOpin(PinModule *newPinModule)
335 {
336     if (!m_source)
337     {
338         m_source = new TXSignalSource(this);
339         m_control = new TXSignalControl(this);
340     }
341     else if (m_PinModule)	// disconnect old pin
342     {
343         disableTXPin();
344     }
345 
346     m_PinModule = newPinModule;
347     if (bTXEN() && rcsta->bSPEN())
348     {
349         enableTXPin();
350     }
351 }
352 
disableTXPin()353 void _TXSTA::disableTXPin()
354 {
355     if (m_PinModule)
356     {
357         m_PinModule->setSource(0);
358         m_PinModule->setControl(0);
359         SourceActive = false;
360         m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
361         if (m_clkSink)
362         {
363             m_PinModule->removeSink(m_clkSink);
364             m_clkSink->release();
365             m_clkSink = 0;
366         }
367         m_PinModule->updatePinModule();
368     }
369 }
370 
setCKpin(PinModule * ck_pin)371 void _TXSTA::setCKpin(PinModule *ck_pin)
372 {
373 
374     if (!SourceActive)
375         m_PinModule = ck_pin;
376 }
enableTXPin()377 void _TXSTA::enableTXPin()
378 {
379     assert(m_PinModule);
380 
381     if (m_PinModule && !SourceActive)
382     {
383         char out;
384         char reg_no = *(name().c_str() + 5);
385         if (bSYNC())
386         {
387             char ck[4] = "CK";
388             if (reg_no)
389             {
390                 ck[2] = reg_no;
391                 ck[3] = 0;
392             }
393             m_PinModule->getPin().newGUIname(ck);
394             out = '0';
395             if (!bCSRC())	  // slave clock
396             {
397                 if (!m_clkSink)
398                 {
399                     m_clkSink = new CLKSignalSink(rcsta);
400                     m_PinModule->addSink(m_clkSink);
401                     rcsta->set_old_clock_state(m_PinModule->getPin().getState());
402                 }
403                 mUSART->emptyTX();
404                 return;
405             }
406         }
407         else
408         {
409             char tx[4] = "TX";
410             if (reg_no)
411             {
412                 tx[2] = reg_no;
413                 tx[3] = 0;
414             }
415             m_PinModule->getPin().newGUIname(tx);
416             out = '1';
417         }
418         m_PinModule->setSource(m_source);
419 #ifdef EUSART_PIN
420         if (mUSART->IsEUSART())
421             m_PinModule->setControl(m_control);
422 #else
423         m_PinModule->setControl(m_control);
424 #endif
425         putTXState(out);
426         SourceActive = true;
427     }
428 
429     mUSART->emptyTX();
430 }
431 
releasePin()432 void _TXSTA::releasePin()
433 {
434     if (m_PinModule && SourceActive)
435     {
436         m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
437         m_PinModule->setControl(0);
438         SourceActive = false;
439     }
440 }
441 
442 //-----------------------------------------------------------
443 // TXSTA - putTXState - update the state of the TX output pin
444 //
445 
putTXState(char newTXState)446 void _TXSTA::putTXState(char newTXState)
447 {
448     m_cTxState = bInvertPin ? newTXState ^ 1 : newTXState;
449 
450     if (m_PinModule)
451         m_PinModule->updatePinModule();
452 }
453 
454 //-----------------------------------------------------------
455 // TXSTA - Transmit Register Status and Control
456 
put_value(unsigned int new_value)457 void _TXSTA::put_value(unsigned int new_value)
458 {
459     put(new_value);
460 
461     update();
462 }
463 
put(unsigned int new_value)464 void _TXSTA::put(unsigned int new_value)
465 {
466     unsigned int old_value = value.get();
467 
468     trace.raw(write_trace.get() | value.get());
469 
470     if (! mUSART->IsEUSART() )
471         new_value &= ~SENDB;      // send break only supported on EUSART
472 
473     // The TRMT bit is controlled entirely by hardware.
474     // It is high if the TSR has any data.
475 
476     //RRRvalue.put((new_value & ~TRMT) | ( (bit_count) ? 0 : TRMT));
477     value.put((new_value & ~TRMT) | (old_value & TRMT));
478 
479     Dprintf(("%s TXSTA value=0x%x\n",name().c_str(), value.get()));
480 
481     if ((old_value ^ value.get()) & TXEN)
482     {
483 
484         // The TXEN bit has changed states.
485         //
486         // If transmitter is being enabled and the transmit register
487         // has some data that needs to be sent, then start a
488         // transmission.
489         // If the transmitter is being disabled, then abort any
490         // transmission.
491 
492         if (value.get() & TXEN)
493         {
494             Dprintf(("TXSTA - enabling transmitter\n"));
495             if (rcsta->bSPEN())
496             {
497 
498                 if (bSYNC() && ! bTRMT() && !rcsta->bSREN() && !rcsta->bCREN())
499                 {
500                     // need to check bTRMT before calling enableTXPin
501                     enableTXPin();
502                     rcsta->sync_start_transmitting();
503                 }
504                 else
505                     enableTXPin();
506             }
507         }
508         else
509         {
510             stop_transmitting();
511             mUSART->full();         // Turn off TXIF
512             disableTXPin();
513 
514         }
515     }
516 }
517 //------------------------------------------------------------
518 //
getState()519 char _TXSTA::getState()
520 {
521     return m_cTxState;
522 }
523 
524 
525 // _TXSTA::stop_transmitting()
526 //
stop_transmitting()527 void _TXSTA::stop_transmitting()
528 {
529     Dprintf(("stopping a USART transmission\n"));
530 
531     bit_count = 0;
532     value.put(value.get() | TRMT);
533 
534     // It's not clear from the documentation as to what happens
535     // to the TXIF when we are aborting a transmission. According
536     // to the documentation, the TXIF is set when the TXEN bit
537     // is set. In other words, when the Transmitter is enabled
538     // the txreg is emptied (and hence TXIF set). But what happens
539     // when TXEN is cleared? Should we clear TXIF too?
540     //
541     // There is one sentence that says when the transmitter is
542     // disabled that the whole transmitter is reset. So I interpret
543     // this to mean that the TXIF gets cleared. I could be wrong
544     // (and I don't have a way to test it on a real device).
545     //
546     // Another interpretation is that TXIF retains it state
547     // through changing TXEN. However, when SPEN (serial port) is
548     // set then the whole usart is reinitialized and TXIF will
549     // get set.
550     //
551     //  txreg->full();   // Clear TXIF
552 
553 }
554 
start_transmitting()555 void _TXSTA::start_transmitting()
556 {
557     Dprintf(("starting a USART transmission\n"));
558 
559     // Build the serial byte that's about to be transmitted.
560     // I doubt the pic really does this way, but gpsim builds
561     // the entire bit stream including the start bit, 8 data
562     // bits, optional 9th data bit and the stop, and places
563     // this into the tsr register. But since the contents of
564     // the tsr are inaccessible, I guess we'll never know.
565     //
566     // (BTW, if you look carefully you may puzzle over why
567     //  there appear to be 2 stop bits in the packet built
568     //  below. Well, it's because the way gpsim implements
569     //  the transmit logic. The second stop bit doesn't
570     //  actually get transmitted - it merely causes the first
571     //  stop bit to get transmitted before the TRMT bit is set.
572     //
573     //  RRR I believe the above paragraph is a mis-understanding
574     //  The tsr register becomes empty, and the TRMT flag goes high,
575     //  when we start to transmit the stop bit. Note that transmision
576     //  is synchronous with the baud clock, so the start of transmision
577     //  of a new character waits for the next callback. This delay maybe,
578     //  in fact, the stop bit of the previous transmision,
579     //
580     //  [Recall that the TRMT bit indicates when the tsr
581     //  {transmit shift register} is empty. It's not tied to
582     //  an interrupt pin, so the pic application software
583     //  most poll this bit.
584     //
585     //  RRR Also The following is wrong:
586     //  This bit is set after the STOP
587     //  bit is transmitted.] This is a cheap trick that saves
588     //  one comparison in the callback code.)
589 
590     // The start bit, which is always low, occupies bit position
591     // zero. The next 8 bits come from the txreg.
592     assert(txreg);
593     if (!txreg)
594         return;
595     if (value.get() & SENDB)
596     {
597         transmit_break();
598         return;
599     }
600     tsr = txreg->value.get() << 1;
601 
602     // Is this a 9-bit data transmission?
603     if (value.get() & TX9)
604     {
605         // Copy the stop bit and the 9th data bit to the tsr.
606         // (See note above for the reason why two stop bits
607         // are appended to the packet.)
608 
609         tsr |= ( (value.get() & TX9D) ? (3 << 9) : (2 << 9));
610         bit_count = 11;  // 1 start, 9 data, 1 stop
611     }
612     else
613     {
614         // The stop bit is always high. (See note above
615         // for the reason why two stop bits are appended to
616         // the packet.)
617         tsr |= (1 << 9);
618         bit_count = 10;  // 1 start, 8 data, 1 stop
619     }
620 
621 
622     // Set a callback breakpoint at the next SPBRG edge
623     if(cpu)
624         get_cycles().set_break(spbrg->get_cpu_cycle(1), this);
625 
626 
627     // The TSR now has data, so clear the Transmit Shift
628     // Register Status bit.
629 
630     trace.raw(write_trace.get() | value.get());
631     value.put(value.get() & ~TRMT);
632 
633 }
634 
transmit_break()635 void _TXSTA::transmit_break()
636 {
637     Dprintf(("starting a USART sync-break transmission\n"));
638 
639     // A sync-break is 13 consecutive low bits and one stop bit. Use the
640     // standard transmit logic to achieve this
641 
642     if (!txreg)
643         return;
644 
645     tsr = 1 << 13;
646 
647     bit_count = 14;  // 13 break, 1 stop
648 
649     // The TSR now has data, so clear the Transmit Shift
650     // Register Status bit.
651 
652     trace.raw(write_trace.get() | value.get());
653     value.put(value.get() & ~TRMT);
654 
655     callback();
656 }
657 
transmit_a_bit()658 void _TXSTA::transmit_a_bit()
659 {
660     if (bit_count)
661     {
662         Dprintf(("Transmit bit #%x: bit val:%u time:0x%" PRINTF_GINT64_MODIFIER "x\n",
663                  bit_count, (tsr & 1), get_cycles().get()));
664 
665         putTXState((tsr & 1) ? '1' : '0');
666 
667         tsr >>= 1;
668 
669         --bit_count;
670     }
671 }
672 
673 
674 
callback()675 void _TXSTA::callback()
676 {
677     Dprintf(("TXSTA callback - time:%" PRINTF_GINT64_MODIFIER "x\n", get_cycles().get()));
678 
679     transmit_a_bit();
680 
681     if (!bit_count)
682     {
683 
684         value.put(value.get() & ~SENDB);
685 
686         // tsr is empty.
687         // If there is any more data in the TXREG, then move it to
688         // the tsr and continue transmitting other wise set the TRMT bit
689 
690         // (See the note above about the 'extra' stop bit that was stuffed
691         // into the tsr register.
692 
693         if (mUSART->bIsTXempty())
694             value.put(value.get() | TRMT);
695         else
696         {
697             start_transmitting();
698             mUSART->emptyTX();
699         }
700 
701     }
702     else
703     {
704         // bit_count is non zero which means there is still
705         // data in the tsr that needs to be sent.
706 
707         if (cpu)
708         {
709             get_cycles().set_break(spbrg->get_cpu_cycle(1), this);
710         }
711     }
712 
713 }
714 
callback_print()715 void _TXSTA::callback_print()
716 {
717     std::cout << "TXSTA " << name() << " CallBack ID " << CallBackID << '\n';
718 }
719 
720 //-----------------------------------------------------------
721 // Receiver portion of the USART
722 //-----------------------------------------------------------
723 //
724 // First RCSTA -- Receiver Control and Status
725 // The RCSTA class controls the usart reception. The PIC usarts have
726 // two modes: synchronous and asynchronous.
727 // Asynchronous reception:
728 //   Asynchronous reception means that there is no external clock
729 // available for telling the usart when to sample the data. Sampling
730 // timing is all based upon the PIC's oscillator. The SPBRG divides
731 // this clock down to a frequency that's appropriate to the data
732 // being received. (e.g. 9600 baud defines the rate at which data
733 // will be sent to the pic - 9600 bits per second.) The start bit,
734 // which is a high to low transition on the receive line, defines
735 // when the usart should start sampling the incoming data.
736 //   The pic usarts sample asynchronous data three times in "approximately
737 // the middle" of each bit. The data sheet is not exactly specific
738 // on what's the middle. Consequently, gpsim takes a stab/ educated
739 // guess on when these three samples are to be taken. Once the
740 // three samples are taken, then simple majority summing determines
741 // the sample e.g. if two out of three of the samples are high, then
742 // then the data bit is considered high.
743 //
744 //-----------------------------------------------------------
745 // RCSTA::put
746 //
put(unsigned int new_value)747 void _RCSTA::put(unsigned int new_value)
748 {
749     unsigned int diff;
750     unsigned int readonly = value.get() & (RX9D | OERR | FERR);
751 
752     diff = new_value ^ value.get();
753     trace.raw(write_trace.get() | value.get());
754     assert(txsta);
755     assert(txsta->txreg);
756     assert(rcreg);
757     // If SPEN being turned off, clear all readonly bits
758     if (diff & SPEN && !(new_value & SPEN))
759     {
760         readonly = 0;
761         // clear receive stack (and rxif)
762         rcreg->pop();
763         rcreg->pop();
764     }
765     // if CREN is being cleared, make sure OERR is clear
766     else if (diff & CREN && !(new_value & CREN))
767         readonly &= (RX9D | FERR);
768     value.put( readonly   |  (new_value & ~(RX9D | OERR | FERR)));
769 
770     if (!txsta->bSYNC()) // Asynchronous case
771     {
772         if (diff & (SPEN | CREN)) // RX status change
773         {
774             if ((value.get() & (SPEN | CREN)) == SPEN )
775             {
776                 if (txsta->bTXEN()) txsta->enableTXPin();
777                 spbrg->start();
778             }
779             else if ((value.get() & (SPEN | CREN)) == (SPEN | CREN))
780             {
781                 enableRCPin();
782                 if (txsta->bTXEN()) txsta->enableTXPin();
783                 spbrg->start();
784                 start_receiving();
785                 // If the rx line is low, then go ahead and start receiving now.
786                 if (m_cRxState == '0' || m_cRxState == 'w')
787                     receive_start_bit();
788                 // Clear overrun error when turning on RX
789                 value.put( value.get() & (~OERR) );
790             }
791             else 		// RX off, check TX
792             {
793                 if (m_PinModule)
794                     m_PinModule->getPin().newGUIname(
795                         m_PinModule->getPin().name().c_str());
796                 stop_receiving();
797                 state = RCSTA_DISABLED;
798 
799                 if (bSPEN())	// RX off but TX may still be active
800                 {
801                     if (txsta->bTXEN()) 		//TX output active
802                         txsta->enableTXPin();
803                     else				// TX off
804                         txsta->disableTXPin();
805                 }
806                 return;
807             }
808         }
809     }
810     else    				// synchronous case
811     {
812 
813         if (diff & RX9)
814         {
815             if (bRX9())
816                 bit_count = 9;
817             else
818                 bit_count = 8;
819         }
820         if (diff & (SPEN | CREN | SREN )) // RX status change
821         {
822             // Synchronous transmit (SREN & CREN == 0)
823             if ((value.get() & (SPEN | SREN | CREN)) == SPEN)
824             {
825                 enableRCPin(DIR_OUT);
826                 if (txsta->bTXEN()) txsta->enableTXPin();
827                 return;
828             }
829             // Synchronous receive (SREN | CREN != 0)
830             else if (value.get() & (SPEN))
831             {
832                 enableRCPin(DIR_IN);
833                 txsta->enableTXPin();
834                 rsr = 0;
835                 if (bRX9())
836                     bit_count = 9;
837                 else
838                     bit_count = 8;
839                 if (txsta->bCSRC()) // Master mode
840                 {
841                     sync_next_clock_edge_high = true;
842                     txsta->putTXState('0');  // clock low
843                     callback();
844                 }
845 
846                 return;
847             }
848             else	// turn off UART
849             {
850                 if (m_PinModule)
851                 {
852                     m_PinModule->getPin().newGUIname(
853                         m_PinModule->getPin().name().c_str());
854                     if (m_sink)
855                     {
856                         m_PinModule->removeSink(m_sink);
857                         m_sink->release();
858                         m_sink = 0;
859                     }
860                 }
861                 txsta->disableTXPin();
862             }
863         }
864     }
865 
866 }
867 
enableRCPin(char direction)868 void _RCSTA::enableRCPin(char direction)
869 {
870     if (m_PinModule)
871     {
872         char reg_no = *(name().c_str() + 5);
873         if (txsta->bSYNC()) // Synchronous case
874         {
875             if (!m_source)
876             {
877                 m_source = new RCSignalSource(this);
878                 m_control = new RCSignalControl(this);
879             }
880             if (direction == DIR_OUT)
881             {
882                 m_DTdirection = '0';
883                 if (SourceActive == false)
884                 {
885                     m_PinModule->setSource(m_source);
886                     m_PinModule->setControl(m_control);
887                     SourceActive = true;
888                 }
889                 putRCState('0');
890             }
891             else
892             {
893                 m_DTdirection = '1';
894                 if (SourceActive == true)
895                 {
896                     m_PinModule->setSource(0);
897                     m_PinModule->setControl(0);
898                     m_PinModule->updatePinModule();
899                 }
900             }
901             char dt[4] = "DT";
902             dt[2] = reg_no;
903             dt[3] = 0;
904             m_PinModule->getPin().newGUIname(dt);
905 
906         }
907         else		// Asynchronous case
908         {
909             char rx[4] = "RX";
910             rx[2] = reg_no;
911             rx[3] = 0;
912             m_PinModule->getPin().newGUIname(rx);
913         }
914 
915     }
916 
917 }
918 
disableRCPin()919 void _RCSTA::disableRCPin()
920 {
921 }
922 
releasePin()923 void _RCSTA::releasePin()
924 {
925     if (m_PinModule && SourceActive)
926     {
927         m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
928         m_PinModule->setControl(0);
929         SourceActive = false;
930     }
931 }
932 
put_value(unsigned int new_value)933 void _RCSTA::put_value(unsigned int new_value)
934 {
935     put(new_value);
936 
937     update();
938 }
939 
940 //-----------------------------------------------------------
941 // RCSTA - putRCState - update the state of the DTx output pin
942 //                      only used for Synchronous mode
943 //
944 
putRCState(char newRCState)945 void _RCSTA::putRCState(char newRCState)
946 {
947     bInvertPin = mUSART->baudcon.rxdtp();
948     m_cTxState = bInvertPin ? newRCState ^ 1 : newRCState;
949 
950     if (m_PinModule)
951         m_PinModule->updatePinModule();
952 }
953 
954 //-----------------------------------------------------------
955 // RCSTA - setIOpin - assign the I/O pin associated with the
956 // the receiver.
957 
setIOpin(PinModule * newPinModule)958 void _RCSTA::setIOpin(PinModule *newPinModule)
959 {
960     if (m_sink)
961     {
962         if (m_PinModule)
963         {
964             m_PinModule->removeSink(m_sink);
965             if (value.get() & SPEN)
966                 m_PinModule->getPin().newGUIname(m_PinModule->getPin().name().c_str());
967         }
968     }
969     else
970         m_sink = new RXSignalSink(this);
971 
972     m_PinModule = newPinModule;
973     if (m_PinModule)
974     {
975         m_PinModule->addSink(m_sink);
976         old_clock_state = m_PinModule->getPin().getState();
977         if (value.get() & SPEN)
978             m_PinModule->getPin().newGUIname("RX/DT");
979     }
980 
981 }
982 
983 //-----------------------------------------------------------
984 // RCSTA - setState
985 // This gets called whenever there's a change detected on the RX pin.
986 // The usart is only interested in those changes when it is waiting
987 // for the start bit. Otherwise, the rcsta callback function will sample
988 // the rx pin (if we're receiving).
989 
990 
setState(char new_RxState)991 void _RCSTA::setState(char new_RxState)
992 {
993     Dprintf((" %s setState:%c\n",name().c_str(), new_RxState));
994 
995     m_cRxState = new_RxState;
996 
997     if ((state == RCSTA_WAITING_FOR_START) && (m_cRxState == '0' || m_cRxState == 'w'))
998         receive_start_bit();
999 }
1000 
1001 //  Transmit in synchronous mode
1002 //
sync_start_transmitting()1003 void _RCSTA::sync_start_transmitting()
1004 {
1005     assert(txreg);
1006 
1007     rsr = txreg->value.get();
1008     if (txsta->bTX9())
1009     {
1010         rsr |= (txsta->bTX9D() << 8);
1011         bit_count = 9;
1012     }
1013     else
1014         bit_count = 8;
1015     txsta->value.put(txsta->value.get() & ~ _TXSTA::TRMT);
1016     if (txsta->bCSRC())
1017     {
1018         sync_next_clock_edge_high = true;
1019         txsta->putTXState('0');		// clock low
1020         callback();
1021     }
1022 }
1023 
set_old_clock_state(char new3State)1024 void _RCSTA::set_old_clock_state(char new3State)
1025 {
1026     bool state = (new3State == '1' || new3State == 'W');
1027     state = mUSART->baudcon.txckp() ? !state : state;
1028     old_clock_state = state;
1029 }
1030 
clock_edge(char new3State)1031 void _RCSTA::clock_edge(char new3State)
1032 {
1033     bool state = (new3State == '1' || new3State == 'W');
1034 
1035     // invert clock, if requested
1036     state = mUSART->baudcon.txckp() ? !state : state;
1037     if (old_clock_state == state) return;
1038     old_clock_state = state;
1039     if (value.get() & SPEN)
1040     {
1041         // Transmitting ?
1042         if ((value.get() & ( CREN | SREN)) == 0)
1043         {
1044             if (state)	// clock high, output data
1045             {
1046                 if (bit_count)
1047                 {
1048                     putRCState((rsr & 1) ? '1' : '0');
1049                     rsr >>= 1;
1050                     bit_count--;
1051                 }
1052             }
1053             else
1054             {
1055                 if(mUSART->bIsTXempty())
1056                 {
1057                     txsta->value.put(txsta->value.get() | _TXSTA::TRMT);
1058                 }
1059                 else
1060                 {
1061                     sync_start_transmitting();
1062                     mUSART->emptyTX();
1063                 }
1064             }
1065         }
1066         else		// receiving
1067         {
1068             if (!state) // read data as clock goes low
1069             {
1070                 bool data = m_PinModule->getPin().getState();
1071                 data = mUSART->baudcon.rxdtp() ? !data : data;
1072 
1073                 if (bRX9())
1074                     rsr |= data << 9;
1075                 else
1076                     rsr |= data << 8;
1077 
1078                 rsr >>= 1;
1079                 if (--bit_count == 0)
1080                 {
1081                     rcreg->push(rsr);
1082                     if (bRX9())
1083                         bit_count = 9;
1084                     else
1085                         bit_count = 8;
1086                     rsr = 0;
1087                 }
1088             }
1089         }
1090     }
1091 
1092 }
1093 
1094 //-----------------------------------------------------------
1095 // RCSTA::receive_a_bit(unsigned int bit)
1096 //
1097 // A new bit needs to be copied to the the Receive Shift Register.
1098 // If the receiver is receiving data, then this routine will copy
1099 // the incoming bit to the rsr. If this is the last bit, then a
1100 // check will be made to see if we need to set up for the next
1101 // serial byte.
1102 // If this is not the last bit, then the receive state machine.
1103 
receive_a_bit(unsigned int bit)1104 void _RCSTA::receive_a_bit(unsigned int bit)
1105 {
1106     // If we're waiting for the start bit and this isn't it then
1107     // we don't need to look any further
1108     Dprintf(("%s receive_a_bit state:%u bit:%u time:0x%" PRINTF_GINT64_MODIFIER "x\n",
1109              name().c_str(), state, bit, get_cycles().get()));
1110 
1111     if( state == RCSTA_MAYBE_START)
1112     {
1113         if (bit)
1114             state = RCSTA_WAITING_FOR_START;
1115         else
1116             state = RCSTA_RECEIVING;
1117         return;
1118     }
1119     if (bit_count == 0)
1120     {
1121         // we should now have the stop bit
1122         if (bit)
1123         {
1124             // got the stop bit
1125             // If the rxreg has data from a previous reception then
1126             // we have a receiver overrun error.
1127             // cout << "rcsta.rsr is full\n";
1128 
1129             if((value.get() & RX9) == 0)
1130                 rsr >>= 1;
1131 
1132             // Clear any framing error
1133             value.put(value.get() & (~FERR) );
1134 
1135             // copy the rsr to the fifo
1136             if(rcreg)
1137                 rcreg->push( rsr & 0x1ff);
1138 
1139             Dprintf(("%s _RCSTA::receive_a_bit received 0x%02X\n",name().c_str(), rsr & 0x1ff));
1140 
1141         }
1142         else
1143         {
1144             //no stop bit; framing error
1145             value.put(value.get() | FERR);
1146 
1147             // copy the rsr to the fifo
1148             if(rcreg)
1149                 rcreg->push( rsr & 0x1ff);
1150         }
1151         // If we're continuously receiving, then set up for the next byte.
1152         // FIXME -- may want to set a half bit delay before re-starting...
1153         if(value.get() & CREN)
1154             start_receiving();
1155         else
1156             state = RCSTA_DISABLED;
1157         return;
1158     }
1159 
1160 
1161     // Copy the bit into the Receive Shift Register
1162     if (bit)
1163         rsr |= 1 << 9;
1164 
1165     //cout << "Receive bit #" << bit_count << ": " << (rsr&(1<<9)) << '\n';
1166 
1167     rsr >>= 1;
1168     bit_count--;
1169 
1170 }
1171 
stop_receiving()1172 void _RCSTA::stop_receiving()
1173 {
1174     rsr = 0;
1175     bit_count = 0;
1176     state = RCSTA_DISABLED;
1177 }
1178 
start_receiving()1179 void _RCSTA::start_receiving()
1180 {
1181     Dprintf(("%s The USART is starting to receive data\n", name().c_str()));
1182 
1183     rsr = 0;
1184     sample = 0;
1185 
1186     // Is this a 9-bit data reception?
1187     bit_count = (value.get() & RX9) ? 9 : 8;
1188 
1189     state = RCSTA_WAITING_FOR_START;
1190 }
1191 
overrun()1192 void _RCSTA::overrun()
1193 {
1194     value.put(value.get() | _RCSTA::OERR);
1195 }
1196 
set_callback_break(unsigned int spbrg_edge)1197 void _RCSTA::set_callback_break(unsigned int spbrg_edge)
1198 {
1199     if (cpu && spbrg)
1200     {
1201         unsigned int time_to_event
1202             = ( spbrg->get_cycles_per_tick() * spbrg_edge ) / TOTAL_SAMPLE_STATES;
1203         get_cycles().set_break(get_cycles().get() + time_to_event, this);
1204     }
1205 }
1206 
receive_start_bit()1207 void _RCSTA::receive_start_bit()
1208 {
1209     Dprintf(("%s USART received a start bit\n", name().c_str()));
1210 
1211     if ((value.get() & (CREN | SREN)) == 0)
1212     {
1213         Dprintf(("  but not enabled\n"));
1214         return;
1215     }
1216 
1217     if (txsta && (txsta->value.get() & _TXSTA::BRGH))
1218         set_callback_break(BRGH_FIRST_MID_SAMPLE);
1219     else
1220         set_callback_break(BRGL_FIRST_MID_SAMPLE);
1221 
1222     sample = 0;
1223     sample_state = RCSTA_WAITING_MID1;
1224     state = RCSTA_MAYBE_START;
1225 }
1226 
1227 //------------------------------------------------------------
callback()1228 void _RCSTA::callback()
1229 {
1230     Dprintf(("RCSTA callback. %s time:0x%" PRINTF_GINT64_MODIFIER "x\n", name().c_str(), get_cycles().get()));
1231 
1232     if (txsta->bSYNC())	// Synchronous mode RX/DT is data, TX/CK is clock
1233     {
1234         if (sync_next_clock_edge_high)	// + edge of clock
1235         {
1236             sync_next_clock_edge_high = false;
1237             txsta->putTXState('1');	// Clock high
1238             // Transmit
1239             if ((value.get() & (SPEN | SREN | CREN)) == SPEN)
1240             {
1241                 if (bit_count)
1242                 {
1243                     putRCState((rsr & 1) ? '1' : '0');
1244                     rsr >>= 1;
1245                     bit_count--;
1246                 }
1247             }
1248         }
1249         else	// - clock edge
1250         {
1251             sync_next_clock_edge_high = true;
1252             txsta->putTXState('0');	//clock low
1253             // Receive Master mode
1254             if ((value.get() & (SPEN | SREN | CREN)) != SPEN)
1255             {
1256 
1257                 if (value.get() & OERR)
1258                     return;
1259                 bool data = m_PinModule->getPin().getState();
1260                 data = mUSART->baudcon.rxdtp() ? !data : data;
1261                 if (bRX9())
1262                     rsr |= data << 9;
1263                 else
1264                     rsr |= data << 8;
1265                 rsr >>= 1;
1266                 if (--bit_count == 0)
1267                 {
1268                     rcreg->push(rsr);
1269                     if (bRX9())
1270                         bit_count = 9;
1271                     else
1272                         bit_count = 8;
1273                     rsr = 0;
1274                     value.put(value.get() & ~SREN);
1275                     if ((value.get() & (SPEN | SREN | CREN)) == SPEN )
1276                     {
1277                         enableRCPin(DIR_OUT);
1278                         return;
1279                     }
1280                 }
1281             }
1282             else		// Transmit, clock low
1283             {
1284                 if (bit_count == 0 && !mUSART->bIsTXempty())
1285                 {
1286                     sync_start_transmitting();
1287                     mUSART->emptyTX();
1288                     return;
1289                 }
1290                 else if(bit_count == 0 && mUSART->bIsTXempty())
1291                 {
1292                     txsta->value.put(txsta->value.get() | _TXSTA::TRMT);
1293                     putRCState('0');
1294                     return;
1295                 }
1296             }
1297         }
1298         if (cpu && (value.get() & SPEN))
1299         {
1300             future_cycle = get_cycles().get() + spbrg->get_cycles_per_tick();
1301             get_cycles().set_break(future_cycle, this);
1302         }
1303     }
1304     else
1305     {
1306         // A bit is sampled 3 times.
1307         switch (sample_state)
1308         {
1309         case RCSTA_WAITING_MID1:
1310             if (m_cRxState == '1' || m_cRxState == 'W')
1311                 sample++;
1312 
1313             if(txsta && (txsta->value.get() & _TXSTA::BRGH))
1314                 set_callback_break(BRGH_SECOND_MID_SAMPLE - BRGH_FIRST_MID_SAMPLE);
1315             else
1316                 set_callback_break(BRGL_SECOND_MID_SAMPLE - BRGL_FIRST_MID_SAMPLE);
1317 
1318             sample_state = RCSTA_WAITING_MID2;
1319 
1320             break;
1321 
1322         case RCSTA_WAITING_MID2:
1323             if (m_cRxState == '1' || m_cRxState == 'W')
1324                 sample++;
1325 
1326             if(txsta && (txsta->value.get() & _TXSTA::BRGH))
1327                 set_callback_break(BRGH_THIRD_MID_SAMPLE - BRGH_SECOND_MID_SAMPLE);
1328             else
1329                 set_callback_break(BRGL_THIRD_MID_SAMPLE - BRGL_SECOND_MID_SAMPLE);
1330 
1331             sample_state = RCSTA_WAITING_MID3;
1332 
1333             break;
1334 
1335         case RCSTA_WAITING_MID3:
1336             if (m_cRxState == '1' || m_cRxState == 'W')
1337                 sample++;
1338 
1339             receive_a_bit( (sample >= 2));
1340             sample = 0;
1341 
1342             // If this wasn't the last bit then go ahead and set a break for the next bit.
1343             if(state==RCSTA_RECEIVING)
1344             {
1345                 if(txsta && (txsta->value.get() & _TXSTA::BRGH))
1346                     set_callback_break(TOTAL_SAMPLE_STATES - (BRGH_THIRD_MID_SAMPLE - BRGH_FIRST_MID_SAMPLE));
1347                 else
1348                     set_callback_break(TOTAL_SAMPLE_STATES - (BRGL_THIRD_MID_SAMPLE - BRGL_FIRST_MID_SAMPLE));
1349 
1350                 sample_state = RCSTA_WAITING_MID1;
1351             }
1352 
1353             break;
1354 
1355         default:
1356             //cout << "Error RCSTA callback with bad state\n";
1357             // The receiver was probably disabled in the middle of a reception.
1358             ;
1359         }
1360     }
1361 
1362 }
1363 
1364 //-----------------------------------------------------------
callback_print()1365 void _RCSTA::callback_print()
1366 {
1367     std::cout << "RCSTA " << name() << " CallBack ID " << CallBackID << '\n';
1368 }
1369 
1370 //-----------------------------------------------------------
1371 // RCREG
1372 //
push(unsigned int new_value)1373 void _RCREG::push(unsigned int new_value)
1374 {
1375     trace.raw(write_trace.get() | value.get());
1376 
1377     if (fifo_sp >= 2)
1378     {
1379 
1380         if (m_rcsta)
1381             m_rcsta->overrun();
1382 
1383         Dprintf(("%s receive overrun\n", name().c_str()));
1384 
1385     }
1386     else
1387     {
1388 
1389         Dprintf(("%s pushing uart reception onto rcreg stack, value received=0x%x\n",name().c_str(), new_value));
1390         fifo_sp++;
1391         oldest_value = value.get();
1392         value.put(new_value & 0xff);
1393         if (m_rcsta)
1394         {
1395             unsigned int rcsta = m_rcsta->value.get();
1396             if (new_value & 0x100)
1397                 rcsta |= _RCSTA::RX9D;
1398             else
1399                 rcsta &= ~ _RCSTA::RX9D;
1400             m_rcsta->value.put(rcsta);
1401         }
1402     }
1403 
1404     mUSART->set_rcif();
1405 }
1406 
pop()1407 void _RCREG::pop()
1408 {
1409     if (fifo_sp == 0)
1410         return;
1411 
1412     if (--fifo_sp == 1)
1413     {
1414         value.put(oldest_value & 0xff);
1415         if (m_rcsta)
1416         {
1417             unsigned int rcsta = m_rcsta->value.get();
1418             if (oldest_value & 0x100)
1419                 rcsta |= _RCSTA::RX9D;
1420             else
1421                 rcsta &= ~ _RCSTA::RX9D;
1422             m_rcsta->value.put(rcsta);
1423         }
1424     }
1425 
1426     if (fifo_sp == 0)
1427         mUSART->clear_rcif();
1428 }
1429 
get_value()1430 unsigned int _RCREG::get_value()
1431 {
1432     return value.get();
1433 }
1434 
get()1435 unsigned int _RCREG::get()
1436 {
1437     pop();
1438     trace.raw(read_trace.get() | value.get());
1439     return value.get();
1440 }
1441 
1442 
1443 
1444 
1445 //-----------------------------------------------------------
1446 // SPBRG - Serial Port Baud Rate Generator
1447 //
1448 // The SPBRG is essentially a continuously running programmable
1449 // clock. (Note that this will slow the simulation down if the
1450 // serial port is not used. Perhaps gpsim needs some kind of
1451 // pragma type thing to disable cpu intensive peripherals...)
1452 
get_next_cycle_break()1453 void _SPBRG::get_next_cycle_break()
1454 {
1455     future_cycle = last_cycle + get_cycles_per_tick();
1456 
1457     if (cpu)
1458     {
1459         if (future_cycle <= get_cycles().get())
1460         {
1461             Dprintf(("%s future %" PRINTF_GINT64_MODIFIER "d <= now %" PRINTF_GINT64_MODIFIER "d\n", name().c_str(), future_cycle, get_cycles().get()));
1462             last_cycle = get_cycles().get();
1463             future_cycle = last_cycle + get_cycles_per_tick();
1464         }
1465         get_cycles().set_break(future_cycle, this);
1466     }
1467 
1468     //Dprintf(("SPBRG::callback next break at 0x%" PRINTF_GINT64_MODIFIER "x\n",future_cycle));
1469 }
1470 
get_cycles_per_tick()1471 unsigned int _SPBRG::get_cycles_per_tick()
1472 {
1473     unsigned int cpi = (cpu) ? p_cpu->get_ClockCycles_per_Instruction() : 4;
1474     unsigned int brgval, cpt, ret;
1475 
1476     if ( baudcon && baudcon->brg16() )
1477     {
1478         brgval =  ( brgh ? brgh->value.get() * 256 : 0 ) + value.get();
1479         cpt = 4;    // hi-speed divisor in 16-bit mode is 4
1480     }
1481     else
1482     {
1483         brgval = value.get();
1484         cpt = 16;   // hi-speed divisor in 8-bit mode is 16
1485     }
1486 
1487     if ( txsta && (txsta->value.get() & _TXSTA::SYNC) )
1488     {
1489         // Synchronous mode - divisor is always 4
1490         // However, code wants two transitions per bit
1491         // to generate clock for master mode, so use 2
1492         cpt = 2;
1493     }
1494     else
1495     {
1496         // Asynchronous mode
1497         if(txsta && !(txsta->value.get() & _TXSTA::BRGH))
1498         {
1499             cpt *= 4;   // lo-speed divisor is 4 times hi-speed
1500         }
1501     }
1502 
1503     ret = ((brgval + 1) * cpt) / cpi;
1504     ret = ret ? ret : 1;
1505     return ret;
1506 }
1507 
start()1508 void _SPBRG::start()
1509 {
1510     if (running)
1511         return;
1512 
1513     if (! skip  || get_cycles().get() >= skip)
1514     {
1515         if (cpu)
1516             last_cycle = get_cycles().get();
1517         skip = 0;
1518     }
1519     running = true;
1520 
1521     start_cycle = last_cycle;
1522 
1523     get_next_cycle_break();
1524 
1525     Dprintf((" SPBRG::start   last_cycle:0x%" PRINTF_GINT64_MODIFIER "x: future_cycle:0x%" PRINTF_GINT64_MODIFIER "x\n",last_cycle,future_cycle));
1526 }
1527 
put(unsigned int new_value)1528 void _SPBRG::put(unsigned int new_value)
1529 {
1530     trace.raw(write_trace.get() | value.get());
1531     value.put(new_value);
1532 
1533     Dprintf((" SPBRG value=0x%x\n",value.get()));
1534     //Prevent updating last_cycle until all current breakpoints have expired
1535     //Otherwise we see that rx/tx periods get screwed up from now until future_cycle
1536     future_cycle = last_cycle + get_cycles_per_tick();
1537     skip = future_cycle;
1538     Dprintf((" SPBRG value=0x%x skip=0x%" PRINTF_GINT64_MODIFIER "x last=0x%" PRINTF_GINT64_MODIFIER "x cycles/tick=0x%x\n",value.get(), skip, last_cycle, get_cycles_per_tick()));
1539 }
1540 
put_value(unsigned int new_value)1541 void _SPBRG::put_value(unsigned int new_value)
1542 {
1543     put(new_value);
1544 
1545     update();
1546 }
1547 
put(unsigned int new_value)1548 void _SPBRGH::put(unsigned int new_value)
1549 {
1550     trace.raw(write_trace.get() | value.get());
1551     value.put(new_value);
1552 
1553     if (m_spbrg)
1554         m_spbrg->set_start_cycle();
1555 }
1556 
set_start_cycle()1557 void _SPBRG::set_start_cycle()
1558 {
1559     //Prevent updating last_cycle until all current breakpoints have expired
1560     //Otherwise we see that rx/tx persiods get screwed up from now until future_cycle
1561     future_cycle = last_cycle + get_cycles_per_tick();
1562     skip = future_cycle;
1563 }
1564 
put_value(unsigned int new_value)1565 void _SPBRGH::put_value(unsigned int new_value)
1566 {
1567     put(new_value);
1568 
1569     update();
1570 }
1571 
1572 //--------------------------
1573 //guint64 _SPBRG::get_last_cycle()
1574 //
1575 // Get the cpu cycle corresponding to the last edge of the SPBRG
1576 //
1577 
get_last_cycle()1578 guint64 _SPBRG::get_last_cycle()
1579 {
1580     // There's a chance that a SPBRG break point exists on the current
1581     // cpu cycle, but has not yet been serviced.
1582     if (cpu)
1583         return (get_cycles().get() == future_cycle) ? future_cycle : last_cycle;
1584     else
1585         return 0;
1586 }
1587 
1588 //--------------------------
1589 //guint64 _SPBRG::get_cpu_cycle(unsigned int edges_from_now)
1590 //
1591 //  When the SPBRG is enabled, it becomes a free running counter
1592 // that's synchronous with the cpu clock. The frequency of the
1593 // counter depends on the mode of the usart:
1594 //
1595 //  Synchronous mode:
1596 //    baud = cpu frequency / 4 / (spbrg.value + 1)
1597 //
1598 //  Asynchronous mode:
1599 //   high frequency:
1600 //     baud = cpu frequency / 16 / (spbrg.value + 1)
1601 //   low frequency:
1602 //     baud = cpu frequency / 64 / (spbrg.value + 1)
1603 //
1604 // What this routine will do is return the cpu cycle corresponding
1605 // to a (rising) edge of the spbrg clock.
1606 
get_cpu_cycle(unsigned int edges_from_now)1607 guint64 _SPBRG::get_cpu_cycle(unsigned int edges_from_now)
1608 {
1609     // There's a chance that a SPBRG break point exists on the current
1610     // cpu cycle, but has not yet been serviced.
1611     guint64 cycle = (get_cycles().get() == future_cycle) ? future_cycle : last_cycle;
1612 
1613     return edges_from_now * get_cycles_per_tick() + cycle;
1614 }
1615 
callback()1616 void _SPBRG::callback()
1617 {
1618     if (skip)
1619     {
1620         Dprintf((" SPBRG skip=0x%" PRINTF_GINT64_MODIFIER "x, cycle=0x%" PRINTF_GINT64_MODIFIER "x\n", skip, get_cycles().get()));
1621     }
1622     if (! skip  || get_cycles().get() >= skip)
1623     {
1624         last_cycle = get_cycles().get();
1625         skip = 0;
1626     }
1627 
1628     //Dprintf(("SPBRG rollover at cycle:0x%" PRINTF_GINT64_MODIFIER "x\n",last_cycle));
1629 
1630     if ((rcsta && rcsta->bSPEN()) || (txsta && txsta->bTXEN()))
1631     {
1632         // If the serial port is enabled, then set another
1633         // break point for the next clock edge.
1634         get_next_cycle_break();
1635 
1636     }
1637     else
1638     {
1639         running = false;
1640     }
1641 }
1642 
1643 //-----------------------------------------------------------
1644 // TXSTA - Transmit Register Status and Control
1645 
put_value(unsigned int new_value)1646 void _BAUDCON::put_value(unsigned int new_value)
1647 {
1648     put(new_value);
1649 
1650     update();
1651 }
1652 
put(unsigned int new_value)1653 void _BAUDCON::put(unsigned int new_value)
1654 {
1655     unsigned int old_value = value.get();
1656 
1657     trace.raw(write_trace.get() | value.get());
1658 
1659     // The RCIDL bit is controlled entirely by hardware.
1660     new_value &= ~RCIDL;
1661     if ( rcsta->rc_is_idle() ) new_value |= RCIDL;
1662 
1663     value.put(new_value);
1664 
1665     Dprintf(("%s BAUDCON value=0x%x\n",name().c_str(), value.get()));
1666 
1667 
1668     if ( (old_value ^ value.get()) & TXCKP)
1669     {
1670 
1671         // The TXCKP bit has changed states.
1672         //
1673         txsta->set_pin_pol ((value.get() & TXCKP) ? true : false);
1674     }
1675 }
1676 
1677 //--------------------------------------------------
1678 // member functions for the USART
1679 //--------------------------------------------------
initialize(PIR * _pir,PinModule * tx_pin,PinModule * rx_pin,_TXREG * _txreg,_RCREG * _rcreg)1680 void USART_MODULE::initialize(PIR *_pir,
1681                               PinModule *tx_pin, PinModule *rx_pin,
1682                               _TXREG *_txreg, _RCREG *_rcreg)
1683 {
1684     assert(_txreg && _rcreg);
1685 
1686     pir = _pir;
1687 
1688     spbrg.txsta = &txsta;
1689     spbrg.rcsta = &rcsta;
1690 
1691     txreg = _txreg;
1692 
1693     txreg->assign_rcsta(&rcsta);
1694     txreg->assign_txsta(&txsta);
1695 
1696     rcreg = _rcreg;
1697     rcreg->assign_rcsta(&rcsta);
1698 
1699     txsta.txreg = txreg;
1700     txsta.rcsta = &rcsta;
1701     txsta.spbrg = &spbrg;
1702     txsta.bit_count = 0;
1703     txsta.setIOpin(tx_pin);
1704 
1705     rcsta.rcreg = rcreg;
1706     rcsta.spbrg = &spbrg;
1707     rcsta.txsta = &txsta;
1708     rcsta.txreg = txreg;
1709     rcsta.setIOpin(rx_pin);
1710 }
1711 
setIOpin(PinModule * pin,int data)1712 void USART_MODULE::setIOpin(PinModule *pin, int data)
1713 {
1714 
1715     switch (data)
1716     {
1717     case TX_PIN:
1718         txsta.setIOpin(pin);
1719         break;
1720 
1721     case RX_PIN:
1722         rcsta.setIOpin(pin);
1723         break;
1724 
1725     case CK_PIN:
1726         txsta.setCKpin(pin);
1727         break;
1728 
1729     }
1730 }
1731 
bIsTXempty()1732 bool USART_MODULE::bIsTXempty()
1733 {
1734     if (m_txif)
1735         return m_txif->Get();
1736     return pir ? pir->get_txif() : true;
1737 }
1738 
emptyTX()1739 void USART_MODULE::emptyTX()
1740 {
1741     Dprintf(("usart::empty - setting TXIF %s\n", txsta.name().c_str()));
1742 
1743     if (txsta.bTXEN())
1744     {
1745         if (m_txif)
1746             m_txif->Trigger();
1747         else if (pir)
1748             pir->set_txif();
1749         else
1750             assert(pir);
1751     }
1752 }
1753 
full()1754 void USART_MODULE::full()
1755 {
1756     Dprintf((" txreg::full - clearing TXIF\n"));
1757     if (m_txif)
1758         m_txif->Clear();
1759     else if(pir)
1760         pir->clear_txif();
1761     else
1762         assert(pir);
1763 }
1764 
set_rcif()1765 void USART_MODULE::set_rcif()
1766 {
1767     Dprintf((" - setting RCIF\n"));
1768     if (m_rcif)
1769         m_rcif->Trigger();
1770     else if(pir)
1771         pir->set_rcif();
1772 }
1773 
clear_rcif()1774 void USART_MODULE::clear_rcif()
1775 {
1776     Dprintf((" - clearing RCIF\n"));
1777     if (m_rcif)
1778         m_rcif->Clear();
1779     else if(pir)
1780         pir->clear_rcif();
1781 }
1782 
1783 //--------------------------------------------------
USART_MODULE(Processor * pCpu)1784 USART_MODULE::USART_MODULE(Processor *pCpu)
1785     : txsta(pCpu,"","USART Transmit Status",this),    // Don't set names incase there are two UARTS
1786       rcsta(pCpu,"","USART Receive Status",this),
1787       spbrg(pCpu,"","Serial Port Baud Rate Generator"),
1788       txreg(nullptr), rcreg(nullptr), pir(nullptr),
1789       spbrgh(pCpu,"spbrgh","Serial Port Baud Rate high byte"),
1790       baudcon(pCpu,"baudcon","Serial Port Baud Rate Control"),
1791       is_eusart(false)
1792 {
1793     baudcon.txsta = &txsta;
1794     baudcon.rcsta = &rcsta;
1795 }
1796 
~USART_MODULE()1797 USART_MODULE::~USART_MODULE()
1798 {
1799 }
1800 
mk_rcif_int(PIR * reg,unsigned int bit)1801 void USART_MODULE::mk_rcif_int(PIR *reg, unsigned int bit)
1802 {
1803     m_rcif = std::unique_ptr<InterruptSource>(new InterruptSource(reg, bit));
1804 }
1805 
mk_txif_int(PIR * reg,unsigned int bit)1806 void USART_MODULE::mk_txif_int(PIR *reg, unsigned int bit)
1807 {
1808     m_txif = std::unique_ptr<InterruptSource>(new InterruptSource(reg, bit));
1809 }
1810 
1811 //--------------------------------------------------
set_eusart(bool is_it)1812 void USART_MODULE::set_eusart(bool is_it )
1813 {
1814     if (is_it)
1815     {
1816         spbrgh.assign_spbrg ( &spbrg );
1817         spbrg.baudcon = &baudcon;
1818         spbrg.brgh = &spbrgh;
1819         is_eusart = true;
1820     }
1821     else
1822     {
1823         spbrgh.assign_spbrg ( 0 );
1824         spbrg.baudcon = 0;
1825         spbrg.brgh = 0;
1826         is_eusart = false;
1827     }
1828 }
1829 
1830