'>Hxtr2-0.BSx debug "prog0" '============================================================== 'Milford Instruments http://www.milinst.com 'Hextor Design, Bug Commander - Behavioural Operating System 'and the Behavioural Controller programs by David Buckley '================================================================ '{$stamp BS2sx,Hxtr2-1,Hxtr2-2,Hxtr2-3,Hxtr2-4,Hxtr2-5,Hxtr2-6,Hxtr2-7} 'Unfortunately that was a long line, ask Parallax. '============================================================== 'Hxtr2-0.BSx - main 'Hxtr2-1.BSx - Activity sequencer 'Hxtr2-2.BSx - US Behaviour 'Hxtr2-3.BSx - Direct Control 'Hxtr2-4.BSx - Prog4 'Hxtr2-5.BSx - Prog5 'Hxtr2-6.BSx - Prog6 'Hxtr2-7.BSx - Utils- LCD menu and IR remote 'Hxtr2-Doc.BSx - Meta Commands and Program Headers '============================================================== 'Parallax bug fix for Windoz Editor ver1.1 'must have a debug stmnt as first executable stmnt in page0 'otherwise editor will not always load some higher pages. 'debug cls '============================================================== 'New '--- 'flags written to eeprom3 to make non volatile 'flags initialised to default after download, ' Fflagsvalid=flags.7 tested ' 'Required knowledge: ' 'Common RAM: 'Constants: Fdefaults 'Variables: Fflagsvalid 'Routine: mopt3 and mopt4 BRANCH used instead of repeated IFs 'Subroutine: 'Labels: 'LCD text: dms0 messages added to for FuseUS Fuseleds Fusefeel 'Behaviours: '============================================================== 'History '------- '15Aug05 FokLEDs,Fokfeelers,Fokus renamed FuseLEDs,Fusefeelers,FuseUS ' minor textual changes, formatting ' method of decrementing pointer without going through 0 tidied '============================================================== 'Activities name-table program1 '------------------------------ A_null con 0 A_chirp1 con 1 A_beep2 con 2 A_wiggle1 con 3 A_wiggle2 con 4 A_wiggle3 con 5 A_Qs4r170 con 6 A_Ts0r200 con 7 A_tround con 8 A_beg con 9 A_Rface con 10 A_Lface con 11 A_F5 con 12 A_R5 con 13 A_L5 con 14 A_BR con 15 A_BL con 16 A_L3 con 17 A_R3 con 18 A_L2 con 19 A_R2 con 20 A_Iflash con 21 A_Fbump con 22 A_FbumpRI1 con 23 A_FbumpLI2 con 24 A_FbumpBI3 con 25 A_last con 25 'last routine 'Ultrasonic-behaviour name-table program2 '---------------------------------------- US_null con 0 US_sitby con 1 US_beg con 2 US_hello con 3 US_wander con 4 US_user1 con 5 US_user2 con 6 US_user3 con 7 US_user4 con 8 US_last con 8 'last routine 'Utilities name-table program7 '------------------------------ U_KlcdCon con 1 U_KirCon con 2 U_last con 2 'last routine '-------------------------------------------------------------- 'common RAM '0 program to return to - all '1 Program option - Activity to do, USrules to do, Options '2 current Utility routine '3 usyawn0 - US-behaviour '4 usyawn1 - US-behaviour '5 irin - current IR value on change of pgm '6 oldbtn - current button on change of pgm '7 menc - last menu code '8 mopts - menu option OAUIP '9 flags - various flag bits ' bit0=irwatch - 0=>ignore IR signal, 1=>act on it ' bit1=useLEDs - 0=>ignore LED cmnds, 1=>enable LEDs ' (if pins remapped) ' bit2=usefeelers - 0=>ignore feelers ' bit3=useUS - 0=>don't run US routines ' bit4=warmIR - 1=>IR chip needs no warmup time ' bit7=flagsvalid - 0 after download, 1->ok 'Note there is no test for the stack being too big, beware of 'the stack growing down through 9! '60 down sequence stack '61 sequence stack pointer '62 letterbox for push and pop '63 active program number used by BS2Sx '-------------------------------------------------------------- 'LCD commands. 'For more detailed information see the ILM-216 User Manual. 'Function ASCII '-------- ----- 'Null 0 'Cursor home 1 'Hide cursor 4 'Show underline cursor 5 'Show blinking-block cursor 6 'Bell (not implemented with Hextor LCD) 7 'Backspace 8 'Horezontal tab (4 columns) 9 'Smart linefeed (cursor down one line) 10 'Vertical tab (cursor up one line) 11 'Formfeed (clear screen) 12 'Carriage return 13 'Backlight on 14 'Backlight off 15 'Accept cursor position entry 16 ' 64 is the start of the first line ' 80 is the start of the second line 'Format right aligned text 18 'Escape (ESC; start multipart instruction) 27 ' ------------------- ' | LCD | ' ------------------- 'LCD keys - bit0 bit1 bit2 bit3 '--------- initialisation data -------------------------------- 'leave room for - 0 default program to run ' 1 default choice in program ' 2 flags data @0,(2) 'always set to 0,0 after download prog0!!! flagb data (1) '--------- LCD messages - finish each message with Null ------- dbtxt data 12,4,16,80,"back < > do ",0 ddflt data 16,64,"Default",0 dOK data 16,78,"ok",0 dDO data 16,78,"DO",0 dnoDO data 16,78," ",0 dfon data 16,64,"flag set ON ",0 dfoff data 16,64,"flag set OFF ",0 dflgs data 12, " IR LEDsFeel US ",0 dON data " ON ",0 dOFF data " OFF",0 ' 'keep all following text 12 bytes long or addressing is wrong 'end each list with 0 '1=homecursor,"<12 chars>",0=null=>end of list dmo0 data 1,"OPTIONS v.2",0 '0 data 1,"Activities ",0 '1 data 1,"US behaviour",0 '2 data 1,"Programs ",0 '3 data 1,"Settings ",0 '4 data 0 dma0 data 1,"ACTIVITIES ",0 '0 data 1,"A_chirp1 ",0 '1 data 1,"A_beep2 ",0 '2 data 1,"A_wiggle1 ",0 '3 data 1,"A_wiggle2 ",0 '4 data 1,"A_wiggle3 ",0 '5 data 1,"A_Qs4r170 ",0 '6 data 1,"A_Ts0r200 ",0 '7 data 1,"A_tround ",0 '8 data 1,"A_beg ",0 '9 data 1,"A_Rface ",0 '10 data 1,"A_Lface ",0 '11 data 1,"A_F5 ",0 '12 data 1,"A_R5 ",0 '13 data 1,"A_L5 ",0 '14 data 1,"A_BR ",0 '15 data 1,"A_BL ",0 '16 data 1,"A_L3 ",0 '17 data 1,"A_R3 ",0 '18 data 1,"A_L2 ",0 '19 data 1,"A_R2 ",0 '20 data 1,"A_Iflash ",0 '21 data 1,"A_Fbump ",0 '22 data 1,"A_FbumpRI1 ",0 '23 data 1,"A_FbumpLI2 ",0 '24 data 1,"A_FbumpBI3 ",0 '25 data 0 dmu0 data 1,"US BEHAVIOUR",0 '0 data 1,"US_sitby ",0 '1 data 1,"US_beg ",0 '2 data 1,"US_hello ",0 '3 data 1,"US_wander ",0 '4 data 1,"US_user1 ",0 '5 data 1,"US_user2 ",0 '6 data 1,"US_user3 ",0 '7 data 1,"US_user4 ",0 '8 data 0 dmp0 data 1,"PROGRAMS ",0 '0 data 1,"Do LCD Keys ",0 '1 data 1,"Do IR Keys ",0 '2 data 1,"RUN BOScon ",0 '3 data 1,"RUN Prog4 ",0 '4 data 1,"RUN Prog5 ",0 '5 data 1,"RUN Prog6 ",0 '6 data 0 dms0 data 1,"SETTINGS ",0 '0 data 1,"BacklightON ",0 '1 data 1,"BacklightOFF",0 '2 data 1,"go DO choice",0 '3 data 1,"seeFlags ",0 '4 data 1,"IRwatchON ",0 '5 data 1,"IRwatchOFF ",0 '6 data 1,"LEDsON ",0 '7 data 1,"LEDsOFF ",0 '8 data 1,"FeelersON ",0 '9 data 1,"FeelersOFF ",0 '10 data 1,"USbehaveON ",0 '11 data 1,"USbehaveOFF ",0 '12 data 0 '-------------------------------------------------------------- BOStx con 0 'pin serial to BOS processor BOSrx con 1 'pin serial from BOS processor epower con 2 'pin high turns on power to electronics BOShalt con 3 'pin high halts current BOS move BOSbusy var in4 'pin BOS processor busy => high irrx con 5 'pin infra red comms in, i96n lcdtx con 6 'pin to send to LCD lcdrx con 7 'pin to receive from LCD Rled con 8 'pin high turns on right green led Lled con 9 'pin high turns on left red led outRled var out8 'pin high turns on right green led outLled var out9 'pin high turns on left red led ustx con 14 'pin ultrasonic commands, i96n usrx con 15 'pin ultrasonic data in, i96n i96n con 16624 '9600 baud, 8 bit, no parity, inverted poweruptime con 1500 'pause before powering up electronics nocmnd con 15 'Kir - no command pending BOScmnd var byte 'byte to send to BOS processor arg var word arg1 var arg.lowbyte 'command argument arg2 var arg.highbyte 'command argument argl var arg.lowbyte argh var arg.highbyte Prog var argh.highnib irin var byte 'infra-red command oldirin var byte 'old infra-red command lcdbtns var byte 'button states are in lower nibble tempb var lcdbtns btn1state var lcdbtns.bit0 btn2state var lcdbtns.bit1 btn3state var lcdbtns.bit2 btn4state var lcdbtns.bit3 btn var lcdbtns.highnib '0 - 4 current button oldbtn var nib '0 - 4 last button state lcdmsg var word 'pointer to current char in text lcdchar var byte 'character to send to LCD menc var byte 'current menu Choice mopts var byte 'Menu options set mendo var byte 'selection chosen by OK dmenc var byte 'DO default menu Choice dmopts var byte 'DO default Menu options set name var byte stkp var byte 'point to top of CommonRam stack dmbase var word 'pointer to entry 0 of current menu Fdefaults con %10001110 'default usON,FeelON,LEDsON,irOFF flags var byte 'various flags Firwatch var flags.bit0 '1=>watch for IR Fuseleds var flags.bit1 'future prog1 Fusefeel var flags.bit2 'future prog1 FuseUS var flags.bit3 'future prog2 FwarmIR var flags.bit4 Fflagsvalid var flags.bit7 'during downloading the power to the electronics is turned off, 'if it is turned back on again too soon the electronics do not 'power up properly,so wait 1 second before turning power on. 'Also lcd needs to initialise after power turned on. init: output Rled output Lled high Rled high Lled Prog =0 'only do default at poweron/reset get 5,irin get 6,oldbtn get 7,menc 'so we return to old menu option get 8,mopts get 9,flags 'bit0 - irwatch 1=>watch get 61,stkp 'get stack pointer if stkp<>0 then init1 'if 0 then poweron run0 'else omit stack initialisation 'and poweron wait new: put 61,61 'initialise stack pointer get 61,stkp 'get stack pointer read flagb,flags if Fflagsvalid=1 then putF write flagb,Fdefaults 'if not valid, initialise goto new putF: put 9,flags read 0,Prog 'default DO program pause poweruptime init1: high epower 'turn on electronics BOScmnd ="V" 'beep gosub tellBOSc 'once pause 200 gosub tellBOSc 'and again pause 50 'min pause 50 otherwise BOS 'misses first command - why? @? Qutil: get 2,dmenc 'current utility routine? if dmenc=0 then Qstack RUN 7 'continue with utility routine Qstack: if stkp<>61 then stackstart 'some routine on stack pause 500 'pause for lcd to initialise if Prog=0 then start lcdmsg =dbtxt :gosub lcd 'write button text lcdmsg =ddflt :gosub lcd 'default read 1,dmenc put 1,dmenc 'routine location RUN Prog 'Default DO stackstart: gosub pop_arg 'get which Prog gosub push_arg 'put info back put 1,0 'no common ram info on routine RUN Prog '---- Main Behaviour Controller --- start: toggle Rled pause 50 gosub lcdmenu 'returns mopts,menc,mendo<>0 FwarmIR =1 'if cold start IR chip will have warmed up 'by the time we get to here bmopts: branch mopts,[start,mopts1,mopts2,mopts3,mopts4] goto start mopts1:'Activities name =mendo goto dosequence mopts2:'US behaviours name =mendo goto dousbehave mopts3:'Programs branch mendo,[RunProgX,doKlcdCon,doKirCon,runBOScon] ' if mendo=1 then doKlcdCon ' if mendo=2 then doKirCon ' if mendo=3 then runBOScon goto RunProgX mopts4:'Settings branch mendo,[start,lightON,lightOFF,seeDflt,seeFlags] mendo =mendo -5 branch mendo,[irON,irOFF,ledsON,ledsOFF,feelON,feelOFF] mendo =mendo -6 branch mendo,[usON,usOFF] ' if mendo=1 then lightON ' if mendo=2 then lightOFF ' if mendo=3 then seeDflt ' if mendo=4 then seeFlags ' if mendo=5 then IRON ' if mendo=6 then IROFF goto start '------------- RUN leaves ---------------------- doKirCon: if Firwatch=0 then irOFF put 2,U_KirCon Prog =7 goto RUNProg '---------------------------------- doKlcdCon: 'Keys lcd Control put 2,U_KlcdCon Prog =7 goto RUNProg '------------------------------- dosequence: put 1,name Prog =1 goto RUNProg '------------------------------- dousbehave: put 1,name Prog =2 goto RUNProg '------------------------------- runBOScon: Prog =3 'run Direct BOS Control pgm goto RUNProg '------------------------------- RunProgX: 'mendo=4 => run 4 'mendo=5 => run 5 'mendo=6 => run 6 'mendo=7 => run 7 Prog =mendo goto RUNProg '------------------------------- RUNProg put 0,0 put 5,irin put 7,menc put 8,mopts run Prog 'run pgm '------------- leaves -------------------------- irON: Firwatch =1 :goto flagON irOFF: Firwatch =0 :goto flagOFF ledsON: Fuseleds =1 :goto flagON ledsOFF:Fuseleds =0 :goto flagOFF feelON: Fusefeel =1 :goto flagON feelOFF:Fusefeel =0 :goto flagOFF usON: FuseUS =1 :goto flagON usOFF: FuseUS =0 :goto flagOFF '--------------- flagON: lcdmsg =dfon :goto flagset flagOFF:lcdmsg =dfoff flagset:gosub lcd pause 2000 put 9,flags write flagb,flags goto start '---------------------------------- seeDflt:mopts =dmopts menc =dmenc goto start '---------------------------------- seeFlags:lcdmsg =dflgs :gosub lcd for arg1=0 to 3 if flags.lowbit(arg1)=1 then seeON seeOFF: lcdmsg =dOFF :gosub lcd :goto seenxt seeON: lcdmsg =dON :gosub lcd seenxt: next pause 2000 gosub btns if btn<>0 then seeFlags goto start '---------------------------------- lightON:serout lcdtx,i96n,[14] goto start '---------------------------------- lightOFF:serout lcdtx,i96n,[15] goto start '------------- subroutines --------------------- push: 'stacks the single byte in letterbox=commonRAM62 get 61,stkp '61 is stack pointer stkp =stkp -1 'next location get 62,tempb 'read letterbox put stkp,tempb 'push byte put 61,stkp 'save pointer return '------------------------------- pop: 'unstacks a single byte into letterbox=commonRAM62 get 61,stkp '61 is stack pointer get stkp,tempb 'pop byte stkp =stkp+1 max 61 'previous max top+1 put 62,tempb 'byte to letter box put 61,stkp 'save pointer return '------------------------------- push_arg: 'stacks the word arg put 62,argl gosub push put 62,argh gosub push return '------------------------------- pop_arg: 'unstacks the word arg gosub pop get 62,argh gosub pop get 62,argl return '------------------------------- lcdmenu: 'returns mopts = active menu ' menc = active menu displayed choice ' mendo = selected choice read 0,Prog 'read default DO read 1,dmenc 'read default DO lookup Prog,[0,1,2,3,3,3,3,3],dmopts mendo =0 lcdmsg =dbtxt :gosub lcd 'write button text lcdit: lookup mopts,[dmo0,dma0,dmu0,dmp0,dms0],dmbase lcdmsg =dmbase +(menc *14) :gosub lcd lcdmsg =dnoDO :gosub lcd if mopts<>dmopts or menc<>dmenc then lcdb 'no match if mopts=0 or menc=0 then lcdb 'can't DO mopts0|menc0 lcdDO: lcdmsg =dDO :gosub lcd 'indicate default DO lcdb: toggle Lled gosub btns 'returns highest btn 0 - 4 if btn=oldbtn then lcdb oldbtn =btn if btn=1 then lcd1 'back' if btn=2 then lcd2 '<' if btn=3 then lcd3 '>' if btn=4 then lcd4 'do' - we can use btns '<' '>' as well goto lcdb lcd1: if menc<>0 then lcd10 'else go up to top level menc =mopts :mopts =0 goto lcdmenu 'make sure all screen written lcd10: menc =0 goto lcdit lcd2: menc =menc min 1 -1 'can't wrap don't know end 'don't go through 0 goto lcdit lcd3: menc =menc +1 read (dmbase +(14*menc)),lcdchar if lcdchar=0 then lcd3a 'are we past last msg? goto lcdit lcd3a: menc =menc -1 'go back to end msg goto lcdit lcd4: if menc=0 then lcd1 'back up if mopts<>0 then lcd4x 'else goto next menu start mopts =menc :menc =0 :goto lcdit lcd4x: mendo =menc 'do it lcdmsg =dOK :gosub lcd 'tell us - being done lcd4x0: gosub btns if btn2state=1 then noDO '< button so noDO if btn3state=1 then lcddflt '> button so DO if btn<>0 then lcd4x0 'wait until finger off button return 'RETURN mopts,menc,mendo<>0 lcddflt:'default action '(2&4)'<'&'do' => clear DO, (3&4)'>'&'do' => set DO, if mopts>3 then lcdit branch mopts,[noDO,DOAct,DOUS,DOProg] noDO: dmenc =0 dmopts =0 Prog =0 goto writeDO DOAct: Prog =1 :goto setDO DOUS: Prog =2 :goto setDO DOProg: if menc<3 then DOP7 Prog =menc :menc =0 :goto setDO DOP7: Prog =7 :goto setDO 'menc =1,2 setDO: dmenc =menc dmopts =mopts writeDO:write 0,Prog 'write default DO write 1,dmenc 'write default DO goto lcdit '-------------------- lcd: read lcdmsg,lcdchar if lcdchar=0 then lcdret 'if 0 then end of msg serout lcdtx,i96n,[lcdchar] lcdmsg =lcdmsg +1 'point to next character goto lcd lcdret: return '-------------------- btns: lcdbtns =0 'set a default value serout lcdtx,i96n,[27,"K0"] 'ask LCD for button status serin lcdrx,i96n,200,nolcd,[lcdbtns] 'get byte nolcd: btn =NCD lcdbtns.lownib '0 - 4 return '-------------------- tellBOSc: 'used for the initialisation beeps & KeyCon pause 10 'give the BOS time to go into receive mode if BOSbusy=1 then tellBOSc 'wait until BOS not busy serout BOStx,i96n,[BOScmnd] return '------------------------ end program -------------------------