'Memory '8K of FRAM, 64K of EEPROM Storage 'RAM: 0000-1FFF=current program 'Storage: 64K, divided into 4 8KB program "slots" ' i.e. slot1=0000-1FFF 'each "slot" holds up to 4096 lines of chris++ code 'if occupied, first byte=1, bytes 1-7=Name 'user code begins execution from byte 8 'Actual "RAM" available to user programs = 48 bytes from $C0-$EF ' 'b0=current ShortBus ID 'b1="instruction" part of instruction 'b2=address/immediate part of instruction 'b3=accumulator 'b4=temp register (used internally) 'b5=unused 'w4 (b6,b7)=return address register (for branching/jumping) 'w3 (b8,b9)=Program Counter 'b10,b11,b12,b13 unused 'input 0 = ADC channel 'input 1 = serial input from shortbus 'input 2 = shortbus interrupt line (alert master) 'input 6 = keyboard clock 'input 7 = keyboard data 'serial_out= serial output to shortbus 'output 0 = unused 'output 1 = i2c 'output 2 = shortbus alert 'output 3 = unused 'output 4 = i2c 'output 5 = unused 'output 6 = acknowledge shortbus interrupt 'output 7 = unused symbol acc=b3 'Accumulator symbol PC=w3 'Program Counter symbol SBID=b0 'ShortBus ID symbol TEMP=b4 'Temporary internal register symbol tmpRTN=w4 'temporary return address symbol instr=b1 ' "Instruction" part of instruction word symbol oprnd=b2 symbol PChigh=b8 symbol PClow=b9 'preload ASCII conversion for ps/2 keyboard EEPROM $00,("?9?5312C?A864?'?") ' Function keys EEPROM $10,("?????Q1???ZSAW2?") ' Main keyboard keys EEPROM $20,("?CXDE43?? VFTR5?") EEPROM $30,("?NBHGY6???MJU78?") EEPROM $40,("?,KIO09??./L;P-?") EEPROM $50,("??'?[=?????]????") EEPROM $60,("?????????1?47???") ' Numeric keypad keys EEPROM $70,("0.2568??B+3-*9??") ' boot: i2cslave %10100000, i2cfast8, i2cword 'set i2c to preloaded program from 0000 to 0FFF 'i2cslave %10100100, i2cfast8, i2cword 'initializes 32kb FRAM setfreq m8 high 5 pause 18000 ' goto editor main: serout 5,T4800,("?fSelect Action:?nExecute [1]?nEdit [2]?nCompile [3]") sertxd("boot complete") setfreq m4 keyin setfreq m8 read keyvalue,b0 b0=b0-49 serout 5,T4800,(#b0) branch b0,(execute,boottexteditor,compiler) goto main execute: pause 200 serout 5,T4800,("?fRun Program[0-9]:") setfreq m4 keyin setfreq m8 pause 400 if keyvalue=118 then main read keyvalue,b0 serout 5,T4800,(b0,"?n") b0=b0-48 w3=b0*2048 w0=0 w1=0 w2=0 w4=0 w3=w3-2 goto readonce '==================================================================== '===================Chris++ Interpreter============================== '==================================================================== 'opload =00 LOD 2-bytes Indirect 'opadd =01 ADD 2-bytes Indirect 'opcomp =02 CMP 2-bytes Immediate 'opsub =03 SUB 2-bytes Indirect 'opjmp =04 JMP 4-bytes Immediate 'opcjmpeq =05 JEQ 4-bytes Immediate 'opstor =06 STR 2-bytes Indirect 'oploadimm =07 LDI 2-bytes Immediate 'sertoslave =08 SND 4-bytes Immediate 'opmult =09 MLT 2-bytes Indirect 'opdiv =0A DIV 2-bytes Indirect 'opcjmpnq =0B JNQ 4-bytes Immediate 'opgetkey =0C KEY 2-bytes ACC 'waitforslave =0D GET 2-bytes ACC 'opsetSBID =0E SSB 2-bytes Immediate 'opadc =0F ADC 2-bytes ACC 'opgetSBID =10 GSB 2-bytes ACC 'opdisp =11 DSP 2-bytes ACC 'opAND =12 AND 2-bytes Immediate 'opOR =13 ORX 2-bytes Immediate 'opXOR =14 XOR 2-bytes Immediate 'opANDNOT =15 ADT 2-bytes Immediate 'opORNOT =16 ONT 2-bytes Immediate 'opXNOR =17 XNR 2-bytes Immediate 'opEnd =18 END 2-bytes Immediate 'opRTN =19 RTN 2-bytes Immediate '===================================================================== readonce: readi2c PC,(instr,oprnd) readinst: readi2c (instr,oprnd) 'load byte containing actual instruction, then (address or immediate) part PC=PC+2 branch instr,(opload,opadd,opcomp,opsub,opjmp,opcjmpeq,opstor,oploadimm,sertoslave,opmult,opdiv,opcjmpnq,opgetkey,waitforslave,opsetSBID,opadc,opgetSBID,opdisp,opAND,opOR,opXOR,opANDNOT,opORNOT,opXNOR,opEnd,opRTN) goto readinst 'return to main opload: peek oprnd,acc 'load (value) into b3 (accumulator) goto readinst 'back to main opadd: peek oprnd,TEMP 'load value-to-be-added into b4 temp reg acc=acc+TEMP 'add (value) to accumulator goto readinst opcomp: if oprnd=acc then compeq 'compare immediate value to accumulator. If !=, 0->acc, else 255->acc acc=0 goto readinst compeq: acc=255 goto readinst opmult: 'acc=acc * (oprnd) peek oprnd,TEMP acc=acc*TEMP goto readinst opdiv: peek oprnd,TEMP 'acc = acc / (oprnd) acc=acc / TEMP goto readinst opsub: peek oprnd,TEMP 'acc=acc-(oprnd) acc=acc-TEMP goto readinst opjmp: tmpRTN=PC 'format: JMP XX HI LO, XX's are ignored, jumps to HILO address readi2c PC,(instr,oprnd) PChigh=instr PClow=oprnd PC=PC-2 readi2c PC,(instr,oprnd) goto readinst opcjmpeq: if acc=255 then cjmptru goto readinst cjmptru: tmpRTN=PC 'b5=temporary rtn register readi2c PC,(instr,oprnd) PChigh=instr PClow=oprnd PC=PC-2 readi2c PC,(instr,oprnd) goto readinst opcjmpnq: if acc<>255 then cjmptru goto readinst opstor: 'store (acc) in (oprnd) poke oprnd,acc goto readinst oploadimm: acc=oprnd 'load #oprnd into (acc) goto readinst sertoslave: high pin2 pause 2 readi2c PC,(instr,TEMP) 'load next 2 bytes, reusing instr byte because it's already been decoded PC=PC+2 'set PC to next instruction sertxd(SBID,oprnd,instr,TEMP) goto readinst waitforslave: if pin2=0 then waitforslave high 6 'turn on ACK line serin 1,N2400,SBID,acc 'set "current slave"=ID of sending slave, set accumulator=value low 6 goto readinst opgetkey: 'put (keyboard ASCII value) into accumulator setfreq m4 keyin setfreq m8 read keyvalue,acc goto readinst opsetSBID: SBID=oprnd 'sets current value of ShortBus ID goto readinst opadc: readadc 0,acc 'read pin 0, put it into the accumulator goto readinst opgetSBID: acc=SBID 'place current ShortBus ID into accumulator goto readinst opdisp: serout 5,T4800,(acc) 'sends value of accumulator to display goto readinst opAND: 'acc = logical AND of acc and immediate operand acc=acc & oprnd goto readinst opOR: 'acc = logical OR of acc and immediate operand acc=acc | oprnd goto readinst opXOR: 'acc = logical XOR of acc and immediate operand acc=acc ^ oprnd goto readinst opANDNOT: 'acc = logical AND NOT of acc and immediate operand acc=acc &/ oprnd goto readinst opORNOT: 'acc = logical OR NOT of acc and immediate operand acc=acc |/ oprnd goto readinst opXNOR: 'acc = logical XNOR of acc and immediate operand acc=acc ^/ oprnd goto readinst opEND: 'exit running code and return to editor serout 5,T4800,("?nPress any key...") setfreq m4 keyin setfreq m8 goto execute opRTN: PC=tmpRTN 'return from subroutine goto readinst 'return to main '=========================================================================================== '======================Dehexification============================= 'takes in a hex byte (i.e. for 9F, b12="9",b13="F") 'returns a binary byte at b12 (i.e. b12=159) dehexify: if b12>60 then dethexone b12=b12-48 b12=b12*16 dehexifytwo: if b13>60 then dethextwo b13=b13-48 b12=b12 | b13 return dethextwo: b13=b13-55 b12=b12 | b13 return dethexone: b12=b12-55 b12=b12*16 goto dehexifytwo '================================================================== '=========================================================================================== ' EXTREMELY SIMPLIFIED ASSEMBLER '=========================================================================================== symbol currentreadline=w0 'b0,b1 = location of code to be assembled symbol currentwriteline=w1 'b2,b3 = location to be written of assembled code compiler: serout 5,T4800,("?fRead Loc[1-4]???n") 'get which slot from the text editor to compile setfreq m4 keyin 'read key for "read location" setfreq m8 pause 400 if keyvalue=118 then main read keyvalue,b2 b2=b2-49 w1=b2*2048 currentreadline=40000+w1 serout 5,T4800,("?fWrite Loc[0-9]???n") pause 500 setfreq m4 keyin setfreq m8 if keyvalue=118 then boottexteditor read keyvalue,b4 b4=b4-48 currentwriteline=b4*2048 'fill in this location with which slot you want to write to pause 200 serout 5,T4800,("compiling...?n") pause 200 goto compileline compiledone: serout 5,T4800,("done") pause 2000 goto main compileline: w2=0 w3=0 w4=0 w5=0 w6=0 readi2c currentreadline,(b4,b5,b6) 'sertxd("L:",#currentreadline," mnemonic:",b4,b5,b6," ",#b4,",",#b5,",",#b6,13,10) 'debug b7=0 gosub deletterfy b4=b7 'b4=compiled opcode b5=b6 'b5=flag for 3 bytes currentreadline=currentreadline+4 'skips over leading letter of 2nd byte (usually an h) readi2c currentreadline,(b6,b7) 'reads operand 'sertxd("L:",#currentreadline," oprnd:",b6,b7,13,10) 'debug currentreadline=currentreadline+2 if b5<>0 then getaddr 'if 3-byte flag isn't set, get location, if it is, get extension currentreadline=currentreadline+1 'skip over leading letter of 3rd byte readi2c currentreadline,(b8,b9) 'reads first extension word 'sertxd("L:",#currentreadline," 2nd oprnd:",b8,b9,13,10) 'debug currentreadline=currentreadline+3 'skips over leading letter of 4th byte readi2c currentreadline,(b10,b11) 'sertxd("L:",#currentreadline," 3rd oprnd:",b10,b11,13,10) 'debug currentreadline=currentreadline+2 getaddr: 'Location to write to is currentwriteline 'opcode already stored in b4 b12=b6 b13=b7 gosub dehexify b6=b12 'operand stored in b6, because b5 still holds 3-byte flag b12=b8 'begin 2nd operand b13=b9 gosub dehexify b7=b12 'b7=2nd operand b12=b10 b13=b11 gosub dehexify b8=b12 'b8=3rd operand writei2c currentwriteline,(b4,b6) 'writes byte_1, byte_2 to currentwriteline pause 100 currentwriteline=currentwriteline+2 'increment address for location if b5<>0 then compileline writei2c w4,(b7,b8) 'writes extended operands pause 100 currentwriteline=currentwriteline+2 goto compileline deletterfy: if b4="L" and b5="O" then islod if b4="A" and b6="D" then isadd if b4="C" and b5="M" then iscmp if b4="S" and b6="U" then issub if b4="S" and b5="T" then isstr if b4="L" and b5="D" then isldi if b4="M" and b5="L" then ismlt if b4="D" and b5="I" then isdiv if b4="K" and b5="E" then iskey if b4="G" and b5="E" then isget if b4="S" and b5="S" then isssb if b4="A" and b6="C" then isadc if b4="G" and b5="S" then isgsb if b4="D" and b5="S" then isdsp if b4="A" and b5="N" then isand if b4="O" and b5="R" then isorx if b4="X" and b5="O" then isxor if b4="A" and b6="T" then isadt if b4="O" and b5="N" then isont if b4="X" and b5="N" then isxnr if b4="E" and b5="N" then isend if b4="R" and b5="T" then isrtn if b4="X" and b5="X" then compiledone b6=0 if b4="J" and b5="M" then isjmp if b4="J" and b5="E" then isjeq if b4="S" and b5="N" then issnd if b4="J" and b5="N" then isjnq serout 5,T4800,("Error!") goto main return 'b7=translated opcode 'b6=0 if necessary to read three bytes isrtn: inc b7 isend: inc b7 isxnr: inc b7 isont: inc b7 isadt: inc b7 isxor: inc b7 isorx: inc b7 isand: inc b7 isdsp: inc b7 isgsb: inc b7 isadc: inc b7 isssb: inc b7 isget: inc b7 iskey: inc b7 isjnq: inc b7 isdiv: inc b7 ismlt: inc b7 issnd: inc b7 isldi: inc b7 isstr: inc b7 isjeq: inc b7 isjmp: inc b7 issub: inc b7 iscmp: inc b7 isadd: inc b7 islod: return '================================================================================== '================================================================================== ' BASIC TEXT EDITOR '================================================================================== 'USES UPPER 32K OF MEMORY ON I2C CHIP: $9C40-$FFFF, divided into 24-byte pages of 4 'lines of code 'w0=current line ' symbol line=w0 symbol offset=b8 boottexteditor: line=$9C40 ' line=0 offset=0 serout 5,T4800,("?f*Welcome to Chris++*") serout 5,T4800,("[1] Edit?n[2] Clear Editor") pause 450 setfreq m4 keyin setfreq m8 pause 600 if keyvalue=30 then clearprogram serout 5,T4800,("?fChoose Program[1-4]") setfreq m4 keyin setfreq m8 pause 400 if keyvalue=118 then main read keyvalue,b2 b2=b2-49 w1=b2*2048 line=line+w1 gosub displaypage texteditor: setfreq m4 keyin setfreq m8 ' sertxd("L:",#line,",K:",#keyvalue,",O:",#offset,10,13) pause 200 select case keyvalue case 117 line=line-6 'up key goto text1 case 114 'down key line=line+6 goto text1 case 118 'escape key goto main case 107 'left arrow if offset=0 then text1 offset=offset-1 goto text1 case 116 'right arrow if offset=5 then text1 offset=offset+1 goto text1 case 102 'backspace if offset=0 then text1 offset=offset-1 line=line+offset writei2c line,(32) line=line-offset goto text1 endselect read keyvalue,b2 if offset = 5 then text2 line=line+offset writei2c line,(b2) line=line-offset offset=offset+1 text1: gosub displaypage goto texteditor text2: offset=0 line=line+5 writei2c line,(b2) line=line+1 goto text1 '=============================================================================================== '=============================================================================================== ' Display Page Routine '=============================================================================================== displaypage: pause 200 'pause to prevent LCD from erasing first line line=line-12 'set location back two lines readi2c line,(b2,b3,b4,b5,b6,b7) 'reads 1st line of code serout 5,T4800,("?f",b2,b3,b4,32,b5,b6,b7,"?y1?x00") 'prints first line of code line=line+6 'increment starting spot to next line readi2c line,(b2,b3,b4,b5,b6,b7) 'read 2nd line of code serout 5,T4800,(b2,b3,b4,32,b5,b6,b7,"?y2?x00") 'print 2nd line of code line=line+6 'increment starting spot to current line readi2c line,(b2,b3,b4,b5,b6,b7) 'read 3rd line of code serout 5,T4800,(b2,b3,b4,32,b5,b6,b7,"?y3?x00") 'print 3rd line of code line=line+6 'increment starting spot to next line readi2c line,(b2,b3,b4,b5,b6,b7) 'read 4th line of code serout 5,T4800,(b2,b3,b4,32,b5,b6,b7) 'print 4th line of code line=line-6 'reset line to original value if offset > 2 then curs1 'detect if the "gap" has been crossed or not serout 5,T4800,("?y2?x0",#offset) 'set cursor to current position return curs1: offset=offset+1 'increment "offset" for the gap serout 5,T4800,("?y2?x0",#offset) 'set cursor to current position offset=offset-1 'return offset to original value return 'return from displaypage routine '================================================================================================= clearprogram: serout 5,T4800,("?fClear Program[1-4]") setfreq m4 keyin setfreq m8 pause 400 if keyvalue=118 then main read keyvalue,b2 b2=b2-49 line=4000 w1=b2*2048 line=line+w1 serout 5,T4800,("?fClearing...") Do while b2 != "X" and b3 != "X" and b4 != "X" and line < 65530 readi2c line,(b2,b3,b4) writei2c line,(0,0,0,0,0,0) line=line+6 pause 225 Loop serout 5,T4800,("?nDone!") pause 2000 goto boottexteditor