00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "instruction.h"
00023 #include "parser.h"
00024 #include "pic14.h"
00025
00026 #include <cassert>
00027 #include <kdebug.h>
00028 #include <iostream>
00029 using namespace std;
00030
00031 bool LEDSegTable[][7] = {
00032 { 1, 1, 1, 1, 1, 1, 0 },
00033 { 0, 1, 1, 0, 0, 0, 0 },
00034 { 1, 1, 0, 1, 1, 0, 1 },
00035 { 1, 1, 1, 1, 0, 0, 1 },
00036 { 0, 1, 1, 0 ,0, 1, 1 },
00037 { 1, 0, 1, 1, 0, 1, 1 },
00038 { 1, 0, 1, 1, 1, 1, 1 },
00039 { 1, 1, 1, 0, 0, 0, 0 },
00040 { 1, 1, 1, 1, 1, 1, 1 },
00041 { 1, 1, 1, 0, 0, 1, 1 },
00042 { 1, 1, 1, 0, 1, 1, 1 },
00043 { 0, 0, 1, 1, 1, 1, 1 },
00044 { 1, 0, 0, 1, 1, 1, 0 },
00045 { 0, 1, 1, 1, 1, 0, 1 },
00046 { 1, 0, 0, 1, 1, 1, 1 },
00047 { 1, 0, 0, 0, 1, 1, 1 }
00048 };
00049
00050
00051
00052 PIC14::PIC14( Microbe * master, Type type )
00053 {
00054 mb = master;
00055 m_pCode = 0;
00056 m_type = type;
00057
00058 }
00059
00060
00061 PIC14::~PIC14()
00062 {
00063 }
00064
00065 PortPin PIC14::toPortPin( const QString & portPinString )
00066 {
00067 QString port;
00068 int pin = -1;
00069
00070
00071 if ( portPinString.length() == 3 )
00072 {
00073 port = QString("PORT%1").arg( portPinString[1].upper() );
00074 pin = QString( portPinString[2] ).toInt();
00075 }
00076 else
00077 {
00078 int dotpos = portPinString.find(".");
00079 if ( dotpos == -1 )
00080 return PortPin();
00081
00082 port = portPinString.left(dotpos);
00083 pin = portPinString.mid(dotpos+1).toInt();
00084 }
00085
00086 PortPin portPin( port, pin );
00087
00088 if ( isValidPortPin( portPin ) )
00089 return portPin;
00090 else
00091 return PortPin();
00092 }
00093
00094
00095 void PIC14::mergeCode( Code * code )
00096 {
00097 m_pCode->merge( code );
00098 }
00099
00100
00101 uchar PIC14::gprStart() const
00102 {
00103 switch ( m_type )
00104 {
00105 case P16C84:
00106 case P16F84:
00107 return 0xc;
00108
00109 case P16F627:
00110 case P16F628:
00111 return 0x20;
00112
00113 case unknown:
00114 break;
00115 }
00116
00117 kdError() << k_funcinfo << "Unknown PIC type = " << m_type << endl;
00118 return 0xc;
00119 }
00120
00121
00122 PIC14::Type PIC14::toType( const QString & _text )
00123 {
00124 QString text = _text.upper().simplifyWhiteSpace().remove('P');
00125
00126 if ( text == "16C84" )
00127 return P16C84;
00128
00129 if ( text == "16F84" )
00130 return P16F84;
00131
00132 if ( text == "16F627" )
00133 return P16F627;
00134
00135 if ( text == "16F628" )
00136 return P16F628;
00137
00138 cerr << QString("%1 is not a known PIC identifier\n").arg(_text);
00139 return unknown;
00140 }
00141
00142
00143 QString PIC14::minimalTypeString() const
00144 {
00145 switch ( m_type )
00146 {
00147 case P16C84:
00148 return "16C84";
00149
00150 case P16F84:
00151 return "16F84";
00152
00153 case P16F627:
00154 return "16F627";
00155
00156 case P16F628:
00157 return "16F628";
00158
00159 case unknown:
00160 break;
00161 }
00162
00163 kdError() << k_funcinfo << "Unknown PIC type = " << m_type << endl;
00164 return 0;;
00165 }
00166
00167
00168 void PIC14::postCompileConstruct( const QStringList &interrupts )
00169 {
00170 m_pCode->append( new Instr_raw("\n\tEND\n"), Code::Subroutine );
00171
00172 if ( interrupts.isEmpty() )
00173 {
00174
00175
00176
00177
00178 m_pCode->append(new Instr_goto("_start"), Code::InterruptHandler);
00179 m_pCode->queueLabel( "_start", Code::LookupTable );
00180 return;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 m_pCode->append(new Instr_goto("_start"), Code::InterruptHandler);
00196
00197 m_pCode->append(new Instr_raw("ORG 0x4"), Code::InterruptHandler);
00198
00199
00200
00201
00202 m_pCode->append(new Instr_movwf("W_TEMP"), Code::InterruptHandler);
00203 m_pCode->append(new Instr_swapf("STATUS",0), Code::InterruptHandler);
00204 m_pCode->append(new Instr_movwf("STATUS_TEMP"), Code::InterruptHandler);
00205
00206 QStringList::ConstIterator interruptsEnd = interrupts.end();
00207 for( QStringList::ConstIterator it = interrupts.begin(); it != interruptsEnd; ++it )
00208 {
00209
00210 m_pCode->append(new Instr_btfsc("INTCON",QString::number(interruptNameToBit((*it), true))), Code::InterruptHandler);
00211 m_pCode->append(new Instr_goto("_interrupt_" + (*it)), Code::InterruptHandler);
00212
00213 }
00214
00215
00216
00217
00218 m_pCode->queueLabel( "_interrupt_end", Code::InterruptHandler );
00219 m_pCode->append(new Instr_swapf("STATUS_TEMP",0), Code::InterruptHandler );
00220 m_pCode->append(new Instr_movwf("STATUS"), Code::InterruptHandler );
00221 m_pCode->append(new Instr_swapf("W_TEMP",1), Code::InterruptHandler );
00222 m_pCode->append(new Instr_swapf("W_TEMP",0), Code::InterruptHandler );
00223 m_pCode->append(new Instr_retfie());
00224
00225 m_pCode->queueLabel( "_start", Code::LookupTable );
00226 }
00227
00228 int PIC14::interruptNameToBit(const QString &name, bool flag)
00229 {
00230
00231
00232 if( name == "change" )
00233 {
00234 if(flag) return 0;
00235 else return 3;
00236 }
00237 else if( name == "timer" )
00238 {
00239 if(flag) return 2;
00240 else return 5;
00241 }
00242 else if( name == "external" )
00243 {
00244 if(flag) return 1;
00245 else return 4;
00246 }
00247
00248 return -1;
00249 }
00250
00251
00252 bool PIC14::isValidPort( const QString & portName ) const
00253 {
00254 return ( portName == "PORTA" || portName == "porta" ||
00255 portName == "PORTB" || portName == "portb" );
00256 }
00257
00258
00259 bool PIC14::isValidPortPin( const PortPin & portPin ) const
00260 {
00261 if ( portPin.port() == "PORTA" )
00262 return (portPin.pin() >= 0) && (portPin.pin() <= 4);
00263
00264 if ( portPin.port() == "PORTB" )
00265 return (portPin.pin() >= 0) && (portPin.pin() <= 7);
00266
00267 return false;
00268 }
00269
00270
00271 bool PIC14::isValidTris( const QString & trisName ) const
00272 {
00273 return ( trisName == "TRISA" || trisName == "trisa" ||
00274 trisName == "TRISB" || trisName == "trisb" );
00275 }
00276
00277
00278 bool PIC14::isValidInterrupt( const QString & interruptName ) const
00279 {
00280 if(m_type == "P16F84" || m_type =="P16C84")
00281 {
00282 return ( interruptName == "change" ||
00283 interruptName == "timer" ||
00284 interruptName == "external" );
00285 }
00286 return false;
00287 }
00288
00289
00290 void PIC14::setConditionalCode( Code * ifCode, Code * elseCode )
00291 {
00292 m_ifCode = ifCode;
00293 m_elseCode = elseCode;
00294 }
00295
00296 void PIC14::Sgoto(const QString &label)
00297 {
00298 m_pCode->append( new Instr_goto(label) );
00299 }
00300
00301 void PIC14::Slabel(const QString &label)
00302 {
00303
00304 m_pCode->queueLabel( label, Code::Middle );
00305 }
00306
00307 void PIC14::Send()
00308 {
00309 m_pCode->append( new Instr_sleep() );
00310 }
00311
00312 void PIC14::Ssubroutine( const QString &procName, Code * subCode )
00313 {
00314 m_pCode->queueLabel( procName, Code::Subroutine );
00315 m_pCode->merge( subCode, Code::Subroutine );
00316 m_pCode->append( new Instr_return(), Code::Subroutine );
00317 }
00318
00319 void PIC14::Sinterrupt( const QString &procName, Code * subCode )
00320 {
00321 m_pCode->queueLabel( "_interrupt_" + procName, Code::Subroutine );
00322
00323
00324 m_pCode->append( new Instr_bcf("INTCON",QString::number(interruptNameToBit(procName,true))) );
00325 m_pCode->merge( subCode, Code::Subroutine );
00326
00327 m_pCode->append( new Instr_goto("_interrupt_end"), Code::Subroutine );
00328 }
00329
00330
00331 void PIC14::Scall(const QString &name)
00332 {
00333 m_pCode->append( new Instr_call(name) );
00334 }
00335
00336
00337 void PIC14::Ssetlh( const PortPin & portPin, bool high)
00338 {
00339 if(high)
00340 m_pCode->append( new Instr_bsf( portPin.port(),QString::number(portPin.pin()) ) );
00341 else
00342 m_pCode->append( new Instr_bcf( portPin.port(), QString::number(portPin.pin()) ) );
00343 }
00344
00345 void PIC14::rearrangeOpArguments( QString * val1, QString * val2, LocationType * val1Type, LocationType * val2Type)
00346 {
00347 if( *val2Type == work && *val1Type != work )
00348 {
00349 LocationType tempType = *val2Type;
00350 QString tempVal = *val2;
00351
00352 *val2Type = *val1Type;
00353 *val2 = *val1;
00354
00355 *val1Type = tempType;
00356 *val1 = tempVal;
00357 }
00358 }
00359
00360 void PIC14::add( QString val1, QString val2, LocationType val1Type, LocationType val2Type )
00361 {
00362 rearrangeOpArguments( &val1, &val2, &val1Type, &val2Type );
00363
00364 switch(val1Type)
00365 {
00366 case num: m_pCode->append(new Instr_movlw( val1.toInt( 0, 0 ) )); break;
00367 case work: break;
00368 case var: m_pCode->append(new Instr_movf(val1,0)); break;
00369 }
00370
00371 switch(val2Type)
00372 {
00373 case num: m_pCode->append(new Instr_addlw(val2.toInt( 0, 0 ))); break;
00374 case work: break;
00375 case var: m_pCode->append(new Instr_addwf(val2,0)); break;
00376 }
00377 }
00378
00379 void PIC14::subtract( const QString & val1, const QString & val2, LocationType val1Type, LocationType val2Type )
00380 {
00381 switch(val2Type)
00382 {
00383 case num: m_pCode->append(new Instr_movlw( val2.toInt( 0, 0 ) )); break;
00384 case work: break;
00385 case var: m_pCode->append(new Instr_movf(val2,0)); break;
00386 }
00387 switch(val1Type)
00388 {
00389 case num: m_pCode->append(new Instr_sublw(val1.toInt( 0, 0 ))); break;
00390 case work: break;
00391 case var: m_pCode->append(new Instr_subwf(val1,0)); break;
00392 }
00393 }
00394
00395 void PIC14::assignNum(const QString & val)
00396 {
00397 m_pCode->append(new Instr_movlw(val.toInt( 0, 0 )));
00398 }
00399
00400 void PIC14::assignVar(const QString &val)
00401 {
00402 m_pCode->append(new Instr_movf(val,0));
00403 }
00404
00405 void PIC14::saveToReg(const QString &dest)
00406 {
00407 m_pCode->append(new Instr_movwf(dest));
00408 }
00409
00410 void PIC14::saveResultToVar( const QString & var )
00411 {
00412 m_pCode->append( new Instr_movwf( var ) );
00413 }
00414
00415 void PIC14::mul(QString val1, QString val2, LocationType val1Type, LocationType val2Type)
00416 {
00417 multiply();
00418
00419 rearrangeOpArguments( &val1, &val2, &val1Type, &val2Type );
00420
00421
00422 switch(val1Type)
00423 {
00424 case num: m_pCode->append(new Instr_movlw(val1.toInt( 0, 0 ))); break;
00425 case work: break;
00426 case var: m_pCode->append(new Instr_movf(val1,0)); break;
00427 }
00428
00429 m_pCode->append(new Instr_movwf("__i"));
00430
00431
00432 switch(val2Type)
00433 {
00434 case num: m_pCode->append(new Instr_movlw(val2.toInt( 0, 0 ))); break;
00435 case work: break;
00436 case var: m_pCode->append(new Instr_movf(val2,0)); break;
00437 }
00438
00439 m_pCode->append(new Instr_movwf("__j"));
00440 m_pCode->append(new Instr_call("__picfunc_multiply"));
00441 m_pCode->append(new Instr_movf("__result",0));
00442 }
00443
00444
00445 void PIC14::multiply()
00446 {
00447 if ( m_pCode->instruction("__picfunc_multiply") )
00448 return;
00449
00450 m_pCode->queueLabel( "__picfunc_multiply", Code::Subroutine );
00451 m_pCode->append(new Instr_clrf("__result"), Code::Subroutine );
00452
00453 m_pCode->queueLabel( "__picfunc_multiply_loop", Code::Subroutine );
00454 m_pCode->append(new Instr_movf("__i",0), Code::Subroutine );
00455 m_pCode->append(new Instr_btfsc("__j","0"), Code::Subroutine );
00456 m_pCode->append(new Instr_addwf("__result",1), Code::Subroutine );
00457 m_pCode->append(new Instr_bcf("STATUS","C"), Code::Subroutine );
00458 m_pCode->append(new Instr_rrf("__j",1), Code::Subroutine );
00459 m_pCode->append(new Instr_bcf("STATUS","C"), Code::Subroutine );
00460 m_pCode->append(new Instr_rlf("__i",1), Code::Subroutine );
00461 m_pCode->append(new Instr_movf("__j",1), Code::Subroutine );
00462 m_pCode->append(new Instr_btfss("STATUS","Z"), Code::Subroutine );
00463 m_pCode->append(new Instr_goto("__picfunc_multiply_loop"), Code::Subroutine );
00464 m_pCode->append(new Instr_return(), Code::Subroutine );
00465 }
00466
00467
00468 void PIC14::div( const QString & val1, const QString & val2, LocationType val1Type, LocationType val2Type)
00469 {
00470 divide();
00471
00472
00473
00474
00475
00476 switch(val1Type)
00477 {
00478 case num: m_pCode->append(new Instr_movlw(val1.toInt( 0, 0 ))); break;
00479 case work: break;
00480 case var: m_pCode->append(new Instr_movf(val1,0)); break;
00481 }
00482
00483 m_pCode->append(new Instr_movwf("__i"));
00484
00485
00486 switch(val2Type)
00487 {
00488 case num: m_pCode->append(new Instr_movlw(val2.toInt( 0, 0 ))); break;
00489 case work: break;
00490 case var: m_pCode->append(new Instr_movf(val2,0)); break;
00491 }
00492
00493 m_pCode->append(new Instr_movwf("__j"));
00494
00495 m_pCode->append(new Instr_call("__picfunc_divide"));
00496 m_pCode->append(new Instr_movf("__result",0));
00497 }
00498
00499 void PIC14::divide()
00500 {
00501 m_pCode->queueLabel( "__picfunc_divide", Code::Subroutine );
00502 m_pCode->append(new Instr_movf("__j",1), Code::Subroutine );
00503 m_pCode->append(new Instr_btfsc("STATUS","2"), Code::Subroutine );
00504 m_pCode->append(new Instr_return(), Code::Subroutine );
00505 m_pCode->append(new Instr_clrf("__result"), Code::Subroutine );
00506 m_pCode->append(new Instr_movlw(1), Code::Subroutine );
00507 m_pCode->append(new Instr_movwf("__k"), Code::Subroutine );
00508
00509 m_pCode->queueLabel( "__divide_shift", Code::Subroutine );
00510 m_pCode->append(new Instr_bcf("STATUS","C"), Code::Subroutine );
00511 m_pCode->append(new Instr_rlf("__k",1), Code::Subroutine );
00512 m_pCode->append(new Instr_bcf("STATUS","C"), Code::Subroutine );
00513 m_pCode->append(new Instr_rlf("__j",1), Code::Subroutine );
00514 m_pCode->append(new Instr_btfss("__j","7"), Code::Subroutine );
00515 m_pCode->append(new Instr_goto("__divide_shift"), Code::Subroutine );
00516
00517 m_pCode->queueLabel( "__divide_loop", Code::Subroutine );
00518 m_pCode->append(new Instr_movf("__j",0), Code::Subroutine );
00519 m_pCode->append(new Instr_subwf("__i",1), Code::Subroutine );
00520 m_pCode->append(new Instr_btfsc("STATUS","C"), Code::Subroutine );
00521 m_pCode->append(new Instr_goto("__divide_count"), Code::Subroutine );
00522 m_pCode->append(new Instr_addwf("__i",1), Code::Subroutine );
00523 m_pCode->append(new Instr_goto("__divide_final"), Code::Subroutine );
00524
00525 m_pCode->queueLabel( "__divide_count", Code::Subroutine );
00526 m_pCode->append(new Instr_movf("__k",0), Code::Subroutine );
00527 m_pCode->append(new Instr_addwf("__result",1), Code::Subroutine );
00528
00529 m_pCode->queueLabel( "__divide_final", Code::Subroutine );
00530 m_pCode->append(new Instr_bcf("STATUS","C"), Code::Subroutine );
00531 m_pCode->append(new Instr_rrf("__j",1), Code::Subroutine );
00532 m_pCode->append(new Instr_bcf("STATUS","C"), Code::Subroutine );
00533 m_pCode->append(new Instr_rrf("__k",1), Code::Subroutine );
00534 m_pCode->append(new Instr_btfss("STATUS","C"), Code::Subroutine );
00535 m_pCode->append(new Instr_goto("__divide_loop"), Code::Subroutine );
00536 m_pCode->append(new Instr_return(), Code::Subroutine );
00537 }
00538
00539
00540 Code * PIC14::ifCode()
00541 {
00542 return m_ifCode;
00543 }
00544
00545
00546 Code * PIC14::elseCode()
00547 {
00548 return m_elseCode;
00549 }
00550
00551
00552 void PIC14::ifInitCode( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type )
00553 {
00554
00555
00556
00557 switch(val1Type)
00558 {
00559 case num:
00560 m_pCode->append(new Instr_movlw(val1.toInt( 0, 0 )));
00561 break;
00562
00563 case work:
00564 break;
00565
00566 case var:
00567 m_pCode->append(new Instr_movf(val1,0));
00568 break;
00569 }
00570
00571 switch(val2Type)
00572 {
00573 case num:
00574 m_pCode->append(new Instr_sublw(val2.toInt( 0, 0 )));
00575 break;
00576
00577 case work:
00578 kdError() << k_funcinfo << "Cannot subtract working from working!" << endl;
00579 break;
00580
00581 case var:
00582 m_pCode->append(new Instr_subwf(val2,0));
00583 break;
00584 }
00585 }
00586
00587 void PIC14::equal( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type )
00588 {
00589 ifInitCode( val1, val2, val1Type, val2Type );
00590 const QString labelEnd = mb->uniqueLabel()+"_endif";
00591 const QString labelFalse = mb->uniqueLabel()+"_case_false";
00592
00593 m_pCode->append(new Instr_btfss("STATUS","2"));
00594 m_pCode->append(new Instr_goto(labelFalse));
00595
00596 mergeCode( ifCode() );
00597
00598 m_pCode->append(new Instr_goto(labelEnd));
00599
00600 m_pCode->queueLabel( labelFalse );
00601 mergeCode( elseCode() );
00602 m_pCode->queueLabel( labelEnd );
00603 }
00604
00605 void PIC14::notEqual( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type )
00606 {
00607 ifInitCode( val1, val2, val1Type, val2Type );
00608 const QString labelEnd = mb->uniqueLabel()+"_endif";
00609 const QString labelFalse = mb->uniqueLabel()+"_case_false";
00610
00611 m_pCode->append(new Instr_btfsc("STATUS","2"));
00612 m_pCode->append(new Instr_goto(labelFalse));
00613
00614 mergeCode( ifCode() );
00615
00616 m_pCode->append(new Instr_goto(labelEnd));
00617
00618 m_pCode->queueLabel( labelFalse );
00619 mergeCode( elseCode() );
00620 m_pCode->queueLabel( labelEnd );
00621 }
00622
00623 void PIC14::greaterThan( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type )
00624 {
00625 ifInitCode( val1, val2, val1Type, val2Type );
00626 const QString labelEnd = mb->uniqueLabel()+"_endif";
00627 const QString labelFalse = mb->uniqueLabel()+"_case_false";
00628
00629 m_pCode->append(new Instr_btfsc("STATUS","0"));
00630 m_pCode->append(new Instr_goto(labelFalse));
00631
00632 mergeCode( ifCode() );
00633 m_pCode->append(new Instr_goto(labelEnd));
00634
00635 m_pCode->queueLabel( labelFalse );
00636 mergeCode( elseCode() );
00637 m_pCode->queueLabel( labelEnd );
00638 }
00639
00640 void PIC14::lessThan( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type )
00641 {
00642 cout << k_funcinfo << endl;
00643 ifInitCode( val1, val2, val1Type, val2Type );
00644 const QString labelEnd = mb->uniqueLabel()+"_endif";
00645 const QString labelFalse = mb->uniqueLabel()+"_case_false";
00646
00647 m_pCode->append(new Instr_btfss("STATUS","0"));
00648 m_pCode->append(new Instr_goto(labelFalse));
00649 m_pCode->append(new Instr_btfsc("STATUS","2"));
00650 m_pCode->append(new Instr_goto(labelFalse));
00651
00652 mergeCode( ifCode() );
00653
00654 m_pCode->append(new Instr_goto(labelEnd));
00655
00656 m_pCode->queueLabel( labelFalse );
00657 mergeCode( elseCode() );
00658 m_pCode->queueLabel( labelEnd );
00659 }
00660
00661 void PIC14::greaterOrEqual( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type )
00662 {
00663 ifInitCode( val1, val2, val1Type, val2Type );
00664 const QString labelEnd = mb->uniqueLabel()+"_endif";
00665 const QString labelTrue = mb->uniqueLabel()+"_case_true";
00666
00667 m_pCode->append(new Instr_btfsc("STATUS","2"));
00668 m_pCode->append(new Instr_goto(labelTrue));
00669 m_pCode->append(new Instr_btfss("STATUS","0"));
00670 m_pCode->append(new Instr_goto(labelTrue));
00671
00672 mergeCode( elseCode() );
00673
00674 m_pCode->append(new Instr_goto(labelEnd));
00675
00676 m_pCode->queueLabel( labelTrue );
00677 mergeCode( ifCode() );
00678 m_pCode->queueLabel( labelEnd );
00679 }
00680
00681 void PIC14::lessOrEqual( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type )
00682 {
00683 ifInitCode( val1, val2, val1Type, val2Type );
00684 const QString labelEnd = mb->uniqueLabel()+"_endif";
00685 const QString labelFalse = mb->uniqueLabel()+"_case_false";
00686
00687 m_pCode->append(new Instr_btfss("STATUS","0"));
00688 m_pCode->append(new Instr_goto(labelFalse));
00689
00690 mergeCode( ifCode() );
00691 m_pCode->append(new Instr_goto(labelEnd));
00692
00693 m_pCode->queueLabel( labelFalse );
00694 mergeCode( elseCode() );
00695 m_pCode->queueLabel( labelEnd );
00696 }
00697
00698
00699 void PIC14::Swhile( Code * whileCode, const QString &expression)
00700 {
00701 QString result;
00702 QString ul = mb->uniqueLabel();
00703
00704 whileCode->append( new Instr_goto(ul) );
00705
00706 m_pCode->queueLabel( ul, Code::Middle );
00707
00708
00709 m_parser->compileConditionalExpression( expression, whileCode, 0 );
00710 }
00711
00712
00713 void PIC14::Srepeat( Code * repeatCode, const QString &expression)
00714 {
00715 QString result;
00716 QString ul = mb->uniqueLabel();
00717
00718 Code * elseCode = new Code;
00719 elseCode->append( new Instr_goto(ul) );
00720
00721 m_pCode->queueLabel( ul );
00722 m_pCode->merge( repeatCode );
00723
00724
00725 m_parser->compileConditionalExpression( expression, 0, elseCode );
00726 }
00727
00728 void PIC14::Sif( Code * ifCode, Code * elseCode, const QString &expression)
00729 {
00730 m_parser->compileConditionalExpression( expression, ifCode, elseCode );
00731 }
00732
00733
00734 void PIC14::Sfor( Code * forCode, Code * initCode, const QString &expression, const QString &variable, const QString &step, bool stepPositive)
00735 {
00736 QString ul = mb->uniqueLabel();
00737
00738 if ( step == "1" )
00739 {
00740 if (stepPositive)
00741 forCode->append(new Instr_incf(variable,1));
00742 else
00743 forCode->append(new Instr_decf(variable,1));
00744 }
00745 else
00746 {
00747 forCode->append(new Instr_movlw(step.toInt( 0, 0 )));
00748 if (stepPositive)
00749 forCode->append(new Instr_addwf(variable,1));
00750 else
00751 forCode->append(new Instr_subwf(variable,1));
00752 }
00753 forCode->append(new Instr_goto(ul));
00754
00755 m_pCode->merge( initCode );
00756
00757 m_pCode->queueLabel( ul );
00758
00759 m_parser->compileConditionalExpression( expression, forCode, 0 );
00760 }
00761
00762
00763 void PIC14::Spin( const PortPin & portPin, bool NOT)
00764 {
00765 QString lowLabel, highLabel, postLabel;
00766 lowLabel = mb->uniqueLabel();
00767 highLabel = mb->uniqueLabel();
00768 postLabel = mb->uniqueLabel();
00769
00770
00771
00772
00773
00774 if(NOT)
00775 m_pCode->append(new Instr_btfsc( portPin.port(), QString::number( portPin.pin() ) ));
00776
00777 else
00778 m_pCode->append(new Instr_btfss( portPin.port(), QString::number( portPin.pin() ) ));
00779
00780 m_pCode->append(new Instr_goto(lowLabel));
00781 mergeCode( ifCode() );
00782 m_pCode->append(new Instr_goto(postLabel));
00783
00784 m_pCode->queueLabel( lowLabel );
00785 mergeCode( elseCode() );
00786
00787 m_pCode->queueLabel( postLabel );
00788 }
00789
00790
00791 void PIC14::Sdelay( unsigned length_us, Code::InstructionPosition pos )
00792 {
00793 if ( length_us == 0 )
00794 return;
00795
00796 if ( length_us > 50070524 )
00797 {
00798 length_us += 50267642;
00799 int l = length_us/50070530;
00800 length_us -= l * 50070530;
00801 int k = length_us/196355;
00802
00803 m_pCode->append( new Instr_movlw( l ), pos );
00804 m_pCode->append( new Instr_movwf( "__l" ), pos );
00805 m_pCode->append( new Instr_movlw( k ), pos );
00806 m_pCode->append( new Instr_movwf( "__k" ), pos );
00807
00808 mb->addDelayRoutineWanted( Delay_50S );
00809 }
00810
00811 else if ( length_us > 196350 )
00812 {
00813 length_us += 197116;
00814 int k = length_us/196355;
00815 length_us -= k * 196355;
00816 int j = length_us/770;
00817