please dont rip this site

Minimal Controller Idea


Small device with a pre-programmed microcontroller like a z8 programmed with code to drive a small LCD panel, scan some key switches, communicate on a serial port and read or write to an EEPROM. Any left over pins are available for general purpose IO. On power up, it tries to read and execute a byte code language like the CUMP Byte Code or BitScope Command Set from the serial port, if a device is connected or from the EEPROM if not.

Registers: 8 bit unless indicated

FLAGS

NUM stores numbers from the command text

SRC and DST reference one of the 125 8 bit registers or (high bit set) one of the available devices (LCD/Keys, Serial, EEPROM, IO). The default setting is LCD/Keys. The DST is set first, and the SRC/DST flag toggled so that SRC is loaded next at which point the current operation and comparison are performed. If SRC is not loaded (zero), NUM is the SRC. After each operation SRC is cleared. At the end of each line, SRC/DST and DST is cleared.

OP stores the operation to perform once we have a SRC (we should already have a DST) or when the line ends. Since there is only one SRC at a time, binary operations like addition always accumulate into DST. i.e. DST is the implied second source in binary operations. The default operation, when no other is specified, is copy. i.e. if only a DST, then a SRC are specified, the value of the SRC is simply written to the DST. OP is not cleared so that " can escape ".

Bytecode:

The goal here is to get as close to a high level language, or at least a very understandable syntax, without including a compiler, and using the minimum resources possible to interpret the bytecodes. How little code can interpret something that at least looks like a HLL?

0-9 A-F	nibble swap NUM, load hex digit into low nibble of NUM. 
	Conversion from/to decimal is too much.
:	Copy operation, effectivly a noop. Not really needed, included only for readability.
a-z	set SRC or DST to register. a is register 0. b is register 4. z is 100.
	a:5 sets register 0 to 5. a:b copies register 4 to register 0.
	NUM is added to the register address first. 3a is the third byte after the start of a. 
	Register 125 is 7Da or 19z (19h=25d, z=100, +25=125) SRC, DST, etc start at 5z.
	After SRC is loaded, SRC/DST is set and the next address is loaded to DST.
@	Set operation to index. When SRC is loaded, replace with the value at that address
	 and clear op. This sets the stage for another op and SRC.
	e.g. b@a sets the DST to the address of b plus the value of a. 
"	(Quote) Text. Each following char is copied to the DST until the ending quote.
	If the operation was already " when a new starting " is seen, 
	put a " to the dest then enter text mode. "Push ""START""" prints Push "START"
+	set operation to add. a+b adds b to a. a:b+5 sets a to b then adds 5. 
	if there is no SRC, the NUM is used as the SRC. a+1 increments a.
	maybe if last op was +, load 1 into NUM. a++ increments a.
-	set operation to add, pre operation to negate or not, and set carry
&	set operation to bitwise AND. a-&b ANDs a with NOT b. a&-b subtracts b from a (& is ignored)
|	set operation to bitwise OR
=	set compare type to equal
<	set compare type to less than
>	set compare type to greater than
~	Not. Toggle true/false flag. Use with greater less and equal. 
		; e.g. a<b~ will set the true flag if a is greater than or equal to b.
		; >~ is less than or equal too. <~ is greater than or equal too. =~ is not equal
?	skip to the next line if the comparison fails (not TRUE)
K	(Local) set SRC or DST to the LCD/Keys. 
	The actual value stored is 0x88
	NUM is used to select the position?
T	(Terminal) set SRC or DST to the Serial port. 0x89
P	(Port) set SRC or DST to IO pins. The value stored will be 0x80-0x87
	NUM before P selects the port if more than 1 available. stored in the lower 3 bits of the value.
	NUM after P selects the pin. These are 1 to 8, not 0 to 7 so that 0 can indicate the entire port.
I	(In) set the Port or Port pin in DST to an Input
O	(Out) set the Port or Port pin in DST to an Output
H	(High) set the Port pin(s) in DST to high. e.g. P1H sets port 0, pin 1 (the second pin) high.
L	(Low) set the Port pin(s) in DST to low. e.g. 2PL sets all pins on port 2 low.
	When the pin is an input, H and L set or clear TRUE based on the pins value.
J	(Jump) move NUM lines 

Quote Escaping

Case '"' //Start putting out text
 while
  temp = SerialGet // after the '"'
  temp=='"'? // but two quotes
   LCDPutChr temp // puts out a quote chr
   temp = SerialGet // after the '"'
- - - - Until temp '"' //Until the next quote

"Push ""START"""

  1. While true
    
  2. - CMD = GetCMD
    
  3. - Select CMD
    
  4. 
      
  5. - - Case '"' 			//A After a '"'
    
  6. - - - temp = GetCMD 		//B  start reading text
    
  7. - - - temp=='"'? 		//C  but two quotes
    
  8. - - - - PutDST temp 		//D  puts out a quote chr
    
  9. - - - While temp NOT '"' 	//E Until the next quote
    
  10. - - - - PutDST temp 		//F  put out chrs
    
  11. - - - - temp = GetCMD 		//G  and read more text
    

Notice how something like "Push ""START""" gets executed: The first quote gets us to line //B above where temp gets loaded with "P". //C fails and //D is skipped. Since temp is no longer a quote, we are now inside the While that started at //E and we put the character out at //F and get another at //G repeatedly until we reach the second quote. At that point, we fall out of the loop, all the way back to the outer loop where we get another command

Comments:

Indexing

Let's think about the indexing of one array by another and how that can be supported with minimal effort. Lower case letters cause their address to be loaded to DST or SRC, not their value. If you want to addr an element of 'a' by an offset in 'i' then the value in 'i' must be added to the addr of 'a' . There are two ways to do this: Make the var code translate any existing value in SRC or DST from address to value before adding in the next var addr. Or: xlate the new var adr to a value before adding it to DST or SRC only when they are not empty.

Make lower case letters add their base address to what ever is in NUM before loading SRC or DST. This moves the offset before the variable so 5a is the same as b.

Copy operation?

One of the goals of this design is to have a syntax that is as close to a high level language as possible without a compiler. To that end, should we add a character for the default copy operation? e.g. a=b+1 is totally clear, but = is also needed for comparisons and really, no operation needs to be specified there at all: ab+1 does the same thing. a:b+1 is a possibility.

Double Operations?

Is it useful to detect and use the case of more than one operation being specified without a SRC between them? E.g. ++ for increment. &- for AND NOT (rather than -&). In some cases, the change requires a lot of work: a<=b is not as easy as it looks since a>b~ does the same job without requiring a new, combined operator. We can "fake" ++ by loading NUM with 1 when we see + and the last op was + as well. Is it worth it?

Repeated Operations?

If NUM is not zero when performing an operation, repeat the operation, after incrementing SRC and DST, then decrement NUM and loop until NUM is zero. So a:b3 copies register 4,5,6, and 7 to registers 0,1,2, and 3. If multibyte values are taken in LSB first (little endian) order, then a:b3+c3 actually moves a LONG at b to a then adds c as a LONG.

Program Counter

Something needs to address the EEPROM when instructions are being pulled from there. That is our program counter (PC). If we used one of the registers, we could affect the flow of the program with more than the skips. Use "p"?

It would be nice to come up with a clever way to save the current PC when jumping to a new location in the program. This would allow more complex flow control like call, parameter passing, and return to be written in the language itself. One possibility is to follow the 1802 model.

In an 1802, there is no specific program counter register. Instead, there are a set of general purpose registers R(x), any one of which can be used as the program counter called R(P). Another register (P) pointed to the register that would be used as the PC. There are also no call instruction. To call, you load another general purpose register wth the address of the subroutine, then set P (the PC pointer) to that register. The subroutine then executes and returns by setting P back to the original R.

For commonly used routines, you dedicate a register to the subroutine, and initiallize it to start, not at the beginning, but a few instructions into the sub. The sub, when it is ready to return, jumps back to it's very start, where P (the PC Pointer) is set back to the main PC, leaving the PC of the subroutine back at the entry point, ready for the next call.

Although the 1802 had a dedicated stack and jump instruction, I see no reason why these are really necessary: To jump, you just load the register being used as the PC with a new address.  To form a call/return stack, you can use the next GP register to point to the subroutine and the subroutine returns by decrementing P. (the real 1802 didn't have an inc or dec P instruction!).

The real trick is making that work in a way that looks more like standard subroutine and function calls in a higher level language.

Devices

LCD: Try to include space for a 15 pin header with an extra IO line on pin 15 to support e.g. 4x16 displays with a second Enable line.

Ports

P0.0
P0.1
P0.2

P2.0
P2.1
P2.2
P2.3
P2.4 LCD.D4
P2.5 LCD.D5
P2.6 LCD.D6
P2.7 LCD.D7

P3.0 AN1
P3.1 AN2
P3.2 AO1

Notes

There is a case that is currently unused: When DST has not be set (zero) and an operation or number is found in the command text. Can we think of a use for that? 9=a? is better programming practice than a=9? so maybe NUM should be the dest when DST is not loaded?

See also:


file: /techref/idea/minimalcontroller.htm, 11KB, , updated: 2008/7/26 14:37, local time: 2009/1/9 16:32,
TOP NEW HELP FIND: 
38.103.63.55:LOG IN
©2009 PLEASE DON'T RIP! DO: LINK / DIGG! / MAKE!

 ©2009 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it!
<A HREF="http://www.sxlist.com/techref/idea/minimalcontroller.htm"> Minimal Controller Idea</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page): A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Did you find what you needed?

 

Welcome to sxlist.com!


Site supported by
sales, advertizing,
& kind contributors
just like you!

Please don't rip/copy
(here's why

Copies of the site on CD
are available at minimal cost.
  'What can I do?' - SiCKO

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .