  Help file for MK-Compiler V1.08 07/2015
  ---------------------------------------

  CONTACT
  -------

Author : guillaume.tello@orange.fr (write in french or english or spanish)
WEB    : http://gtello.pagesperso-orange.fr/

This program was written using PureBasic 4.41. It is freeware.
I'll be pleased to receive MK programs written with my compiler
and include them in my WEB page.

Thanks to:
   Eugene Troitskiy for corrections and cool ideas.

  BASIC OPERATIONS
  ----------------

First of all, the compiler is not case sensitive, so FRAC, or Frac or fRaC
are all the same.

To key in a number, use 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and '.'
Sign change can be written as CHS or /-/
The exponent starts with EE.

Example for -4.2*10^6:  4 . 2 CHS EE 6
-> Compiler facility: you can use the '$' prefix : $-4.2e6
and let the compiler do it for yourself.
(note that in this case, only one 'e' for exponent)

Operations are +, -, /, *, ENTER, CX, LASTX, X<>Y (exchange) and ROT (rotate)
               INT (or [X]), FRAC (or {X}), ABS (or |X|), SGN (sign of a number), MAX
               >HM, HM>, >HMS, HMS>, RND (random generator).

               Known bug in MAX: if X or Y is nul, then MAX returns zero.

Algebraic functions: SQR (for square root), 1/x, x (or x^2), x^y.
Scientific functions are: SIN, COS, TAN (or TG), ARCSIN, ARCCOS, ARCTAN (or ARCTG)
                          EXP (or E^X), LOG, LN, PI, 10^X

Binary functions are: AND, OR, XOR, NOT.


MK-161: ER09 and ER10 generate errors 9 and 10 and stop program.
------  GRPH displays graphic screen and SCR updates screen.
        PRGM gets one byte from Program memory.


  REGISTER USE
  ------------

A register can be one of the fifteen registers from 0 to 9 and a to e.
Store/Recall is done with STO and RCL.

STO 1 : store X into register 1.
RCL e : push register e on stack.

Values from 10 to 14 can replace registers from a to e.
RCL 10 is the same as RCL a, and STO (14) is the same as STO (e).

Indirect addressing is done with ()

STO (1) : store X into register pointed by R1.
RCL (e) : push on stack the register pointed by Re.
   Note that every time an indirect addressing is used with registers 0-3
   then the register is automatically decremented.
   The same when an indirect addressing is used with registers 4-6
   then the register is automatically incremented.

-> Compiler facility: you can rename a standard register with the following directive:

#reg r name

Example: #reg 5 count, and then you can use RCL count, STO (count), etc...

-> Compiler facility: =r is a short form for STO r
                      @r is a short form for RCL r

Example, instead of : RCL rate RCL dollar * STO euro
         you can use: @rate @dollar * =euro

This still works with indirect addressing: =(index) is the same as STO (index)
   store X into register pointed by index.


MK-161: Registers can be from 0 to e, then 15 to 9999.
------  Indirection allowed only with registers 00-99
        SET/EXEC and GET can be used instead of STO and RCL.


  I/O Registers on the MK-161
  ---------------------------

  9000  \x0y0
    - SET \x0y0 : init x0 And y0 with x and y values on the stack (0-127 and 0-63)
    - GET \x0y0 : return x0 and y0 in x and y on the stack

  9001  \GMode
    - SET \GMode : init graphic mode with x value (0-7)
    - GET \GMode : return in x current graphic mode
    - (0: replace 1: And 2: Or 3: XOr 4: Not 5: Not And 6: Not Or 7: Not XOr)

  9002  \CharSpace
    - SET \CharSpace : init character spacing with x value (0-15)
    - GET \CharSpace : Return in x current graphic mode

  9003  \Font
    - SET \Font : set font face with x value (0-1-2-254)
    - GET \Font : return in x current font number
    - (0=small, 1=large, 2=large numbers, 254=user)

  9004  \GPtr
    - SET \GPtr : set pointer into graphic memory to x (0-1023)
    - GET \GPtr : return graphic pointer in x

  9005  \GRByte
    - STO \(GPtr) : store x (0-255) at GPtr location in memory
    - GET \(GPtr) : return in x the byte at GPtr location in memory

  9006  \(GPtr)+
    - Same as \(GPtr) but GPtr is automatically incremented after operation

  9007  \Scroll
    - EXEC \Scroll : move screen x line up (1-7), the new line is empty

  9008  \FScroll
    - Same as \Scroll but the new line is filled with black dots.

  9009  \UserFont
    - SET \UserFont : set address of user font (0-9999)

  9010  \Cls
    - EXEC \Cls : clear screen according to x
    - (0=clear, 1=fill, 2=clear+init settings, 3=fill+init settings)

  9011  \Plot
    - SET \Plot : plots a point at location x y
    - GET \Plot : return in x the state of the point x y (0=clear, 1=black)

  9012  \LineTo
    - EXEC \LineTo : draw a line from x0 y0 to x y

  9013  \FRect
    - EXEC \FRect : fill a rectangle from x0 y0 with width x and height y

  9014  \Rect
    - EXEC \Rect : draw a rectangle from x0 y0 with width x and height y

  9015  \PutGP
    - EXEC \PutGP : draw a graphic from address x (0-9999) in program memory to location x0 y0
    - (data organization: widht, height + data bytes)

  9016  \PutGB
    - EXEC \PutGP : draw a graphic from address x (1000-5095) in binary memory to location x0 y0

  9020  \PrintChar
    - EXEC \PrintChar : draw the char specified in x at location x0 y0. Then x0 is incremented to next char location

  9021  \PrintStringP
    - EXEC \PrintStringP: draw a string from address x (0-9999) in program memory to location x0 y0
    - string must end with 00 or FF

  9022  \PrintStringB
    - Same as PrintStringP but from binary memory (1000-5095)

  9023  \PrintNumber
    - EXEC \PrintNumber : display floating point number x at location x0 y0

  9024  \PrintFNumber
    - EXEC \PrintFNumber : display x as a formatted number. y= digits in the integer part, z=digits in the fract part
    - (y from 1 to 8, z from 0 to 7)

  9025  \CPrintChar
    - EXEC \CPrintChar : print char x in the current position in comment line.
    - if x=10 reset position and clear line

  9026  \CPrintStringP
    - EXEC \CPrintStringP : draw a string from address x (0-9999) in program memory to current location in comment line
    - start your string with char 10 to clear line

  9027  \CPrintStringB
    - Same as \CPrintStringP but from binary memory

  9028  \Inkey
    - GET \Inkey : if a key is currently pressed return in x its code, else return 255

  9029  \NextKey
    - GET \NextKey : return the code of a key pressed from the key buffer or 255 if buffer empty
    - (4 keys can be stored and the buffer is a FIFO queue)

  9030  \Index0
    - SET \Index0 : init index register 0 with X value (0-255) as a pointer into the Universal Byte buffer
    - GET \Index0 : return in X current value of index register 0
    - Note: the universal byte buffer (UBB) is a 256 bytes buffer.

  9031  \Index1
    - SET \Index1 : init index register 1 with X value (0-255) as a pointer into the UBB.
    - GET \Index1 : return in X current value of index register 1

  9032  \(Index0)
    - SET \(Index0) : store X (0-255) into the UBB at location pointed by Index0.
    - GET \(Index0) : return in X current value in UBB at location pointed by Index0

  9033  \(Index1)
    - SET \(Index1) : store X (0-255) into the UBB at location pointed by Index1.
    - GET \(Index1) : return in X current value in UBB at location pointed by Index1

  9034  \(Index1)+
    - SET \(Index1)+ : same as \(Index1) but then autoincrement Index1.
    - GET \(Index1)+ : same as \(Index1) but then autoincrement Index1.

  9035  \XtoString
    - SET \XtoSTring : convert X into a string into UBB pointed by Index0.

  9036  \XtoFString
    - SET \XtoSTring : convert X into a formatted string into UBB pointed by Index0.
    - Y is the number of digits in the integer part, Z the number of digits in the frac part.

  9037  \Xto8Bytes
    - SET \Xto8Bytes : convert X to 8 bytes (the standard storage for registers) into UBB pointed by Index0.
    - GET \Xto8Bytes : returns in X the value from 8 bytes taken from UBB pointed by Index0.

  9038  \Xto4Bytes
    - SET \Xto4Bytes : convert X to 4 bytes (short form with 7 signifiant digits) into UBB pointed by Index0.
    - GET \Xto4Bytes : returns in X the value from 4 bytes taken from UBB pointed by Index0.

  9039  \Mnemonic
    - EXEC \Mnemonic : X is a pointer into program memory (0-9999) and this returns the Mnemonic of the instruction at (X) into UBB pointed by Index0.

  9040  \Parity
    - EXEC \Parity : calculate the parity of the X value (0-255), return 1 if even number of 1, 0 if odd number of 1.

  9041  \ProgramCounter
    - GET \ProgramCounter : return the current program counter in X.

  9042  \PPtr
    - SET \PPtr : set pointer into program memory to x (0-9999)
    - GET \PPtr : return program pointer in x

  9043  \(PPtr)
    - GET \(PPtr) : Return in x the byte at PPtr location in memory

  9044  \(PPtr)+
    - Same as \(PPtr) but PPtr is automatically incremented after operation

  9045  \AngleMode
    - SET \AngleMode : set the angle mode according to X (0=degrees, 1=radians, 2=grads)
    - GET \AngleMode : return in X the current angle mode.

  9046  \Randomize
    - SET \Randomize : init the random number generator with X (0-65536)
    - GET \Randomize : return in X current random initiator

  9047  \CopyToNVRAM
    - SET \CopyToNVRAM : if X=1 then the next STO will also be performed in NVRAM, if X=0, only in RAM
    - This is only useful in programming mode. In direct mode every STO is duplicated.
    - GET \CopyToNVRAM : return current flag status in X.

  9048  \AutoStart

  9049  \NewtworkID
    - SET \NetworkID : set current network identifier to X (0-255)
    - GET \NetworkID : return in X the current network identifier.

  9050  \Timer0
    - SET \Timer0 : init timer 0 with x/100 sec (0-65535), timer is then decrementd until 0
    - if x<0 (-1 to -65535) then timer is incremented and when it reaches zero, it stars again at x
    - GET \Timer0 : return in x current timer value

  9051  \Timer1
    - Same as Timer0

  9052  \Sound
    - SET \Sound : produce a sound with frequency y (25-25000 Hz) and duration x/100 sec
    - GET \Sound : return in y the current frequency and in x the remaining time or 0 if no sound

  9053  \KeySound
    - Same as \Sound but to define the sound produced when a key is pressed

  9055  \Time
    - SET \Time : use x to set current time (format HH.MMSS)
    - GET \Time : return current time in x

  9056  \Day

  9057  \Month

  9058  \Year

  9059  \DayOfWeek

  9060  \TableLine
    - SET \TableLine : set current table line with X value (0-16383)
    - GET \TableLine : return in X the current table line.
    - The table memory consist of 16384 lines of 4 decimal numbers (16384x4x8=512 KB)

  9061  \Table1
    - SET \Table1 : store X in element 1 of current table line.
    - GET \Table1 : return in X the first element of current table line.

  9062  \Table2

  9063  \Table3

  9064  \Table4

  9065  \TableStatus
    - GET \TableStatus : return 0 if last table operation was OK, and 1 if there was an error.

  9090  \IOMode
    - SET \IOMode : define the parallel port mode (0-3)
    - (0=off 1=static 2=Centronic 3=Bidirectional)

  9092  \IOModule

  9100  \BinarySize
    - SET \BinarySize define the size of binary operations (from 1 to 4 bytes)
    - GET \BinarySize return in x the current setting

  9101  \PrintBinary
    - EXEC \PrintBinary display on the graphic screen at x0,y0 the binary form of the X value according to \BinarySize

  9102  \CPrintBinary
    - EXEC \CPrintBinary display on the comment line the binary form of the X value according to \BinarySize

  9103  \BinConv
    - SET \BinConv : convert X into its binary representation (according to BinarySize) and store it in the UBB pointed by Index0.
    - GET \BonConv : read as many bytes as BinarySize from UBB pointed by Index0 and returns the decimal value in X.

  9110  \StackDisplay
    - SET \StackDisplay : set the display of Y,Z and T according to X (0:normal, 1:full precision)
    - GET \StackDisplay : return in X the current stack display mode.

  9115  \PowerVoltage
    - GET \PowerVoltage : return in X the current volatge of battery.

  9116  \Model
    - GET \Model : return in X current model number (161 for the MK-161)

  9117  \Version
    - GET \Version : return in X the current firmware version (1.2 for version 1.20)

  9119  \PassWord

  9120  \DiskEnable
    - SET \DiskEnable : if X=1 then disk operations are enabled, if X=0 then they are not.
    - GET \DiskEnable : return in X current Disk Operations status.

  9121  \Disk
    - SET \Disk : set current disk (0=A, 1=B) and fill Disk Buffer with the root directory
    - Note: the disk buffer contains 64 entries with 32 bytes each for 64 files/subdirs:
    - byte0: file ID (0=Current dir; 2=subdir; 3=program; 4=decimal; 5=text; 6=binary)
    - byte1/2: starting cluster           byte3/22: 20 chars for NAME (padded with spaces)
    - byte23/30: 8 bytes with time/date   byte31: number of blocks (for programs only)

  9122  \GetDirLine
    - EXEC \GetDirLine : copies to the UBB pointed by Index0 the line from current directory pointed by X (0-63)

  9123  \Load
    - EXEC \Load : load file pointed by X (0-63) from current Disk Buffer
    - If file is a program, Y contains the starting block number
    - If file is a directory, this opens the directory and fills the new disk buffer

  9124  \Delete
    - EXEC \Delete : delete the file pointed by X (0-63), then the new directory is loaded. It can't delete program files!

  9125  \Create
    - EXEC \Create : create a file with ID X (2-6) and with a 20 bytes name stored into the UBB in the name field (Index0+3)
    - It can't create program files!
    - For data files, the data is automatically saved to the file.

  9126  \OverWrite
    - EXEC \OverWrite : rewrite new data over the file pointed by X (0-63)

  9128  \DiskControl
    - To validate a disk operation (9123 to 9126) you must store current X value in \DiskControl just before the operation
    - example: 7 SET \DiskControl EXEC \Delete

  9129  \DiskError
    - GET \DiskError : after every disk operation, returns 0 if OK or an error code as follows
    - 1: No disk                    2: Disk not formatted
    - 3: No space                   4: Catalog Full
    - 5: Error File/Directory       6: Can't perform operation
    - 7: File/Dir not selected      8: You don't have permission

  9130  \InterEnable
    - SET \InterEnable enables (x=1) or disables (x=0) the interrupt routines

  9131  \Inter1
    - SET \Inter1 set priority and vector for Interrupt 1 (x=priority disabled 0- Highest 255 and y=vector 0-9999)
    - Subroutine pointed by y must end with RTI

  9132  \Inter2

  9133  \Inter3

  9134  \Inter4

  9135  \Inter5

  9136  \Inter6

  9137  \Inter7

  9138  \Inter8

  9139  \Inter9

  9140  \Inter10

  9141  \Inter11

  9142  \Inter12

  9143  \Inter13

  9144  \Inter14

  9145  \Inter15

  9146  \Inter16

  9148  \InterClear
    - EXEC \InterClear if x=1 then clear all interrupt informations

  9149  \InterCall
    - EXEC \InterCall call interrupt x (1-16), does nothing if interrupt disabled

  9150  \InterTimer0
    - SET \InterTimer0 associate the end of timer with Interruption x (1-16)
    - if x=0 then no interrupt is associated with this event

  9151  \InterTimer1

  9152  \InterTimer2
    - This event is the end of a sound

  9153  \InterKeyPress
    - This event occurs when a key is pressed

  9154  \InterSerial1

  9155  \InterSerial2

  9156  \InterBusy
    - This event occurs when the parallel BUSY signal goes from 1 to 0

  9157  \InterKeyRelease
    - This event occurs when a key is released

  9158  \InterSerial3

  9170  \ADCMode

  9171  \ADCMux

  9172  \ADCPeriod

  9175  \ADC1

  9176  \ADC2

  9177  \ADC3

  9178  \ADC4

  9179  \ADCRecord

  9180  \ADCTime1

  9181  \ADCTime2

  9182  \ADCTime3

  9183  \ADCTime4

  9185  \ADC1U

  9186  \ADC2U

  9187  \ADC3U

  9188  \ADC4U

  9200  \FormEnable

  9201  \FormTable

  9202  \ActiveForm

  9203  \ActiveElement

  9208  \FormCommand
    - SET \FormCommand : execute command x (a key code or 64 for redraw) in a form
    - GET \FormCommand : return in x last executed command

  9209  \FormCommandStatus
    - GET \FormCommandStatus : return in x the result of last executed command
    - (0 Ok, 1 exec user program, 2 bad form id, 3 bad active elem, 4 bad command, 5 bad font, 6 bad char, 7 end of input)

  9210  \GetTableWord
    - EXEC \GetTableWord : take x as an index in a 2-bytes table pointed to by PPtr and return the corresponding word (0-65535)
    - Such table can be created with #DW/#END

  9211  \GetTableWordBCD
    - EXEC \GetTableWordBCD : take x as an index in a 2-bytes BCD table pointed to by PPtr and return the corresponding 4 digits value (0-9999)
    - Such table can be created with #DAF/#END

  9212  \GetTableWordK
    - EXEC \GetTableWordK : take x as a key in a 3-bytes table pointed to by PPtr and return the corresponding word (0-65535) that matches the key.
    - If the key is not found, then returns -1.
    - Such table can be created with #DWK/#END

  9213  \GetTableWordBCDK
    - EXEC \GetTableWordBCDK : take x as a key in a 3-bytes BCD table pointed to by PPtr and return the corresponding 4 digits value (0-9999) that matches the key.
    - If the key is not found, then returns -1.
    - Such table can be created with #DAFK/#END



  BASIC PROGRAMMING
  -----------------

Some instruction require an address to jump to. You can go on using absolute
addresses (from 0 to 104), but it's easier to define labels and let the compiler
calculate the addresses for you.

A label is defined with a name followed by a ':', its value is the current
step pointer.

Loops are L0, L1, L2 and L3.
    L0 label or L0 addr

Unconditional jumps are GOTO, GOSUB and RTN
    GOTO label, GOTO addr or even GOTO (r) for indirect addressing.
    The same for GOSUB.
    RTN returns from a GOSUB call.

Conditional jumps are x=0, x<0, x>=0, x<>0.
    x=0 label, x=0 addr, x=0 (r) for indirect addressing.
    The same for the other tests.
    Remember that the jump is only taken if the test is false!

You can halt the program with R/S (or STOP or INPUT according to the best meaning for you).

NOP can be used to fill a space, 'no operation'.

Example :

$20 =0 =1
2
here:
   SQR
L0 here

there:
   X^2
L1 there

STOP

This will be compiled as:
2 0 STO 0 STO 1
2 SQR L0 05 X^2 L1 08 R/S


MK-161: Steps are from 0000 to 9999.
------  Within the same hundred block, jumps use the short form of one byte.
        To jump from one block to another, a long jump with two bytes is used.
        RTI returns from a Interruption (-> PP RTN)


  ADVANCED PROGRAMMING
  --------------------

The compiler offers many loops and structures to ease programming
and source reading.

Comments are really useful to help reading a code.
A comment starts with the ';' character, from this point the line is ignored.

In the following, 'test' stands for one of the four tests available:
   x=0, x<0, x>=0, x<>0.

REPEAT ... UNTIL(test)
   repeat enclosed instructions until test is true.

FOR r ... NEXT
   repeat the instructions according to the value of register r.
   This register must be 0, 1, 2 or 3.

FOR r ... WHILE(test) ... NEXT
   the same as before, but the loop goes on as long as the test is true.

DO ... LOOP
   infinite loop.

DO ... WHILE(test) ... LOOP
   the loop goes on as long as the test is true.

IF(test)GOTO label (or addr or (r) indirect register)
   jump to label/addr if test is true.
   note that in the listing, you'll find the reciprocal test.

IF(test)THEN ... ENDIF
   if test is true, then execute instructions enclosed by THEN/ENDIF
   else, jump after ENDIF.

IF(test)THEN ... ELSE ... ENDIF
   if test is true, then execute instructions enclosed by THEN/ELSE
   else, jump to instructions enclosed by ELSE/ENDIF.

SELECT reg0
   start a SELECT/ENDSELECT structure using value of register reg0

CASE= $val  or  CASE= @reg1 (CASE= can be written CASE)
   execute following instructions if reg0=$val or reg0=reg1
   else jump to next CASE/DEFAULT/ENDCASE

CASE<  CASE>=  CASE<>  CASE!=
   same as CASE= but with a different test.

DEFAULT
   if every CASE fails, then execute following instructions

ENDSELECT
   close the SELECT structure

SUM r or SUM (r)
   replaced by sequence: RCL r + STO r
   the same if indirect addressing.(**)

MUL r or MUL (r)
   replaced by sequence: RCL r * STO r
   the same if indirect addressing.(**)

(**) with indirect addressing and registers 0 to 6, this will lead to an
error as the register is decremented/incremented when used.


MK-161: The jumps are automatically optimized to short form when possible with:
------  FOR/NEXT, REPEAT/UNTIL, DO/LOOP
        Jumps use the long form with WHILE, IF, ELSE.


  Other Directives for MK-161
  ---------------------------

#BINARY
   swap to binary zone (4kB addresses 1000 to 5095)
   in this mode only label definitions and the following directives are allowed:
   #TEXT/0 #DB/W/L #DEFGRAPH #DAL/F #INITB/W/L

#PROGRAM
   swap to program mode (default)

#BLOCK n
   in program mode set current address to 100*n
   in binary mode set current address to 1000+64*n

#TEXT + string
   add the bytes corresponding to the string characters

#TEXT0 + string
   same as #TEXT with an ending zero byte

#TEXTN + string
   same as #TEXT0 with leading 0A byte (new line)

#NUM + label or register
   insert as a constant the digits corresponding to the label or register value
   if the label is unresolved it will use 4 digits whatever its value.

#DB  (bytes) #END
   add bytes values (0-255)

#DW  (words) #END
   add words values (0-65536)
   you can access this table by index using \GetTableWord.

#DWK  (key + word) #END
   create a table with groups containing each a key byte (0-254) associated with a word value (0-65536)
   you can access this table by key using \GetTableWordK.

#DL  (longs) #END
   add longs values (0-4294967295)

#DEFGRAPH (lines) #END
   define a graphic bloc for use with \PutGP or \PutGB
   each line is a string with . for zero and * for one
   the two leading bytes containing the size of the block are automatically computed.

#FONT h     #ENDFONT
   enclose a user font definition. h is the common height in pixels of every character in the font.
   Inside, you can use #DEFCHAR/#END to define characters.
   See \UserFont and \Font registers to use your font.

#DEFCHAR c (lines) #END
   define character 'c' (0-254), character 255 can't be defined.
   (lines) are similar to #DEFGRAPH. You must respect the common height but the character width
   can be deffirent for every one.

#LOADIMAGE opt filename
   load an image (BMP, PNG, JPEG, TGA) and turn it into a graph as DEFGRAPH
   opt=0 no option, each point is turned into a grey level and black=0-49%, white=50-100%
   opt=1 negative image
   opt=2 apply a Floyd-Steinberg dithering
   opt=3 both

#DAL  (labels) #END
   add the low part of addresses (address mod 100) as bytes in hex

#DAF  (labels) #END
   add full addresses as words in BCD
   you can access this table by index using \GetTableWordBCD.

#DAFK  (key + label) #END
   create a table with groups containing each a key byte (0-254) and a word address in BCD (0-9999)
   you can access this table by key using \GetTableWordBCDK.

#BASE
   set the current location as base for the OFFSET directive

#OFFSET  (labels) #END
   add the offset of each label with the last #BASE as bytes in hex

#INITB n byte
   init a zone with n times the specified byte

#INITW n word
   init a zone with n times the specified word

#INITL n long
   init a zone with n times the specified long

#LabelList n
   Will list or not the internal labels in the compiled file (default is zero)
   n=0 : don't list internal labels (the ones for IF/SELECT/MENUS...)
   n=1 : list all labels including internal ones

#MOVE "SD"
   move bytes from source S to destination D, S and D can be:
   U (Universal Byte Buffer), P (program), G (Graphic), B (Binary)
   In input Z=source address, Y=dest address, X=number of bytes
   The routine uses Index1 (U), PPtr (P), Gptr (G), Reg4 (B) and register 3 for the loop.
   Example:
   adr 0 $12 #MOVE "PU" : move 12 bytes from program memory at adr To universal byte buffer at 0.

#REGtoBIN
   Z= first source register
   Y= destination Binary address (1000-5093)
   X= number of consecutive registers
   Copy registers from decimal zone to binary zone. Each one uses 8 bytes. So you can save a maximum of 512 registers.
   The routine uses registers 2, 3, 4, 5 and Index0 and Index1. Example:

   10 1000 6 #REGtoBIN
       saves 6 registers from register 10 (10-15) to binary zone 1000 to 1047.

#BINtoREG
   Z= Binary source address
   Y= destination first register
   X= number of consecutive registers
   Performs the reciprocal operation of #REGtoBIN, uses the same registers.


  File Management
  ---------------

The MK-161 has a 2048 bytes zone to load a directory. It contains 64 lines (0-63), each one
pointing at a file/directory name. Most File operations are performed through this memory zone
and the user has to specify in the X register the line containing the desired file (0-63).

So, the user has to know where is the file he wants, but the system lacks a 'search' function.
MK-Compiler provides one (see #ADDFILESEARCH).

Before any file operation, they must be enabled with:
1 SET \DiskEnable (this also loads the root directory of Disk A)

At the end of your program, you can use:
0 SET \DiskEnable

If the default disk is not the one you want, you can use:
d SET \Disk
   d = disk number (0=A and 1=B)
   This loads the root directory of this disk.


#FILENAME  "string"
   complete the string to 20 characters with spaces and add the corresponding bytes.
   this because a filename must be 20 chars long.

#FILENAMEID "string" Id
   as #FILENAME but adds a last byte containing the file ID.

#ADDFINDFILE
   The system doesn't provide a function to find a file in the current directory.
   This directive adds two subroutines called 'findfile' and 'findfileid' that make the job.
   You use them this way:

#FINDFILE is a short form for <Gosub findfile>
   Y = adr(*) is the address of a filename in program memory (see #FILENANE).
   X = id(**) is a file identifier (see \Disk)
   If found, the routine returns the file line in the directory (0-63)
   If not found, the routine returns -1.
   The routine uses Reg2, Reg3 for loops and \PPtr, \Index0=0 and \Index1 as pointers and the
   32 first bytes in the Universal byte buffer.
   (*) if the name is created with #TEXT0 with n characters (n<20), then only the first n
       characters are used for comparison. For example with #TEXT0 "DATA" you can find
       every file starting with DATA: DATA001, DATA2015, DATA, etc.
   (**) if id=-1 then the file identifier is not used for comparison. So you can find every kind of file
        (decimal, binary,...) sharing the same name.

#FINDFILEID is a short form for <GOSUB findfileid>
   X = adr, the address of a filename + ID (see #FILENAMEID)
   Returns the same as findfile.

#LOADFILE
   X = line of the desired file.
   If ID=0 then it is the parent directory, goes back to the parent.
   If ID=2 then it is a subdir, opens it.
   If ID=3 then it is a program, Y must contain the starting block number where to load.
   Else, loads the corresponding file in its zone: if you load a Decimal file, all registers are overwritten.

#DELETEFILE
   X = line of the desired file.
   Remove the file (can't remove programs or nonempty dirs)

#OVERWRITEFILE
   X = line of the desired file.
   replace old file content with current memory one (can't overwrite a program).

#COPYFILENAME
   X = adress of a valid filename that will be copied to the universal byte buffer at location 3.

#CREATEFILE
   X = file ID to be created (can't create programs)
   In the Universal byte buffer, location 3, must be the file name.
   When created, a file is automatically written with the corresponding memory content.


  Graphic Interface at Low Level
  ------------------------------

#FormTable id0 id1 ... #END
   prepare a table for forms using the graphic interface

#DefineForm id n
   start a form with its id an n active elements (from 0 to n-1)

#FormFlags f0 f1 ... (*)
   add the flag table (n elements) to the current form being defined
   flags determine the behaviour of an active element:
   bit0: Enable Arrows          bit4: Enable Output (Esc)
   bit1: Action if arrow        bit5: Action if Output
   bit2: Enable INPUT (Enter)   bit6: Enable periodic screen refresh
   bit3: Action if input        bit7: Don't clear screen before redraw

#FormInput f0 e0 f1 e1 ...(*)
   add the Input table (2n elements) to the current form being defined
   this table explains where to go if Input (or Enter) key is pressed on this element
   with two values f for form id and e for element.

#FormOutput f0 e0 f1 e1...(*)
   add the Output table (2n elements) to the current form being defined
   this table explains where to go if Output (or Esc) key is pressed on this element
   with two values f for form id and e for element.

#FormLeft e0 e1...(*)
   add the left transition table (n elements) to the current form being defined
   this table explains where to go if Left or Up key is pressed on this element

#FormRight e0 e1...(*)
   add the right transition table (n elements) to the current form being defined
   this table explains where to go if Right or Down key is pressed on this element

(*) for every table, if you replace de parameters with >> then the table can be
    merged with the next one if they share the same values.

#FormMainProgram
   define the start point of the main program in the current form being defined
   this program is executed every time the form needs to be redrawn.
   Here you can use the following instruction codes:
   #TAB x y            #LDX reg            #LDY reg            #TYPE n
   #ATYPE adr          #LDADR reg          #SQU attr x y       #FRAME attr x y
   #DRAWP attr adr     #DRAWB attr adr     #TXTP attr adr      #TXTB attr adr
   #TXTK attr reg      #PREXP attr reg     #PRFORM att reg m n #PRHEX attr reg
   #MCALL label        #RETUM              #LCALL adr          #RETUL
   #JNEZ reg label     #JM label           #END

#FormElements
   add the table of the individual program addresses for each element
   then you can use:

#FormElementProgram n
   define the start point of the individual program for element i (0 to n-1)
   then you can use the same instruction codes as in the main program.
   those programs are executed each time the element is active.


  Graphic Interface at High Level
  -------------------------------

#MENU and #ENDMENU
   enclose a menu definition. There can be several menus in the same program. The first one
   will be MENU 0, the next MENU 1 and so on.

#MENUESCL n
   a variant of #MENU where pressing the ESC key goes back to menu n
   without an explicit #LINK.

#MENUESCA
   a variant of #MENU where pressing the ESC key execute a routine named 'EscapeAction' that you must provide.
   If you have several menus using this option, you can use GET \ActiveForm to know wich menu has run the subprogram.
   In the routine 'EscapeAction', you can use #GOTOMENU to have the effect of #MENUESCL.

   Inside a menu, you can use the following words:

#STRING f text       (1)(2)(3)
   Add one line of text (not selectable) in font f (0=normal, 1=large, 2=big, 254=user)

#CSTRING f text      (1)(2)(3)
   Add one line of centered text (not selectable) in font f (0=normal, 1=large, 2=big, 254=user)
   The text is centered for known fonts (0,1,2) or else left aligned

#HLINE
   Add one horizontal line to separate items.

#BLANK n
   jump n graphic lines that will be blank.

#ACTION text adr       (1)(2)
   Add one selectable line with corresponding text that will run program at adr.

#LINK text menu       (1)(2)
   Add one selectable line with corresponding text that will go to the specified menu.

#INPUTD text tab reg       (1)(2)
   Add one selectable line that will make an input of the register value when selected.
   tab is the horizontal position of the number displayed (if -1 the register is not displayed)
   text is a text leading the number, you can leave it empty.

#VINPUTD text tab reg adr       (1)(2)
   Same as INPUTD but a subprogram at adr is run after the input
   so you can validate the entry or refuse it.

#INPUTH text tab reg or #VINPUTH text tab reg adr       (1)(2)
   The same as INPUTD or VINPUTD but in hexadecimal (both input and display).

#OUTPUTD f text tab reg       (1)(2)(3)
   Add one line using font f with both a text and a register value in decimal. The text can be empty.
   Tab is the horizontal position of the register on the line.

#OUTPUTH f text tab reg       (1)(2)(3)
   The same as OUTPUTD but in hexadecimal.

#OUTPUTF f text tab reg m n       (1)(2)(3)
   The same as OUTPUTD but formatted with m digits for INT part and n digits for DECIMAL part.

#PROGRESSBAR reg
   draw a progress bar with a white index that takes its position from register reg.
   This register must have a value from 9 (=0%) to 116 (=100%) before any redraw.
   For a progression at position n out of a total of T, formula is: reg = 107*n/T + 9

#CHECK text reg        (1)(2)
   as STRING but according to reg prints or not a leading check mark
   if reg=0 then CHECKED
   if reg=1 then not
   you must initialize the register to 0 or 1, any other value won't work!
   to change the state, just press ENTER on the line or change the reg in your program.

#RADIO "but1|but2|..." reg
   display one line with radio buttons, only one selected
   to change the selection, just press ENTER on it.
   the register contains the X coordinate of the selected rectangle.
   it must be initialized by your program to a correct value (see next).

#STOItoX reg n
   takes the stack as input value (from 0 to n-1 as a RADIO button option number)
   and convert it to the X required coordinate and stores it in reg.
   For example, to initialize a RADIO Button to option 1 out of 4: 
   1 #STOItoX reg 4

#RCLXtoI reg n
   takes the X coordinate in reg as input value and convert it as a RADIO button
   number (0 to n-1) that is put on the stack.
   For example, to know what option is selected out of 3 options:
   #RCLXtoI reg 3

#ICON opt adr
   add one image pointed by adr (defined with DEFGRAPH or LOADIMAGE), the image must be
   defined before the use of #ICON.
   opt is a bitfield:
   bit1 and bit 0 = 0 align left
                  = 1 center
                  = 2 align right
                  = 3 left with 8 pixels margin (as the text lines)
   bit 2 = 1 image is a background, following line will write over it
         = 0 image is inserted and following lines will be displayed after it.
   bit 3 = 1 blocks will be an enclosing rectangle
         = 0 blocks will be a filled rectangle

#BLOCKA adr x y w h
   define an 'action' block inside the last #ICON, ENTER will run the subprogram adr
   and the block inside the image starts at x y with w h dimensions.

#BLOCKL menu x y w h
   define a 'link' block inside the last #ICON. ENTER will go To the specified menu
   and the block inside the image starts at x y with w h dimensions.

#MATRIX n m
   if used just after a #ICON, specifies the number of possible blocks inside
   the image (n columns and m rows). Then, this simplifies the use of #BLOCKA/L as this:

#BLOCKA adr i j    or    #BLOCKL menu i j
   with i from 0 to n-1 and j from 0 to m-1
   so you don't have to compute the coordinates.

#STARTRECT and #ENDRECT
   Enclosed lines will appear into a rectangle.

#MENUMAINLOOP reg
   This line must appear AFTER all menu definitions. It adds to the program the main loop to manage
   the graphic interface and run your subprograms. It also adds, after this loop, all the data to
   define your menus.
   The register is used for an indirect addressing in the loop. You must specify a free register
   from 0 to 99. It is common to use register 7.

(1) The options that display a text have a conditional form based on the value of a register that acts as a flag.
    If the flag is zero, then the first text is displayed, if the flag is not zero then the alternative text is
    used. To use this you have to:
       - add ? just after the #
       - add two parameters : flag (the register) and textifnot0 (the alternative text)
    For example:
       #?ACTION text adr flag textifnot0
       or #?OUTPUTF f text tab reg m n flag textifnot0

(2) Instead of text as parameter, you can specify an indirect adressing (reg) with parenthesis.
    This register must point to a text located into the binary zone.
    You can combine this with option (1).

(3) If f=254 then you must provide a #BLANK instruction to shift down the vertical pointer as the
    user font height is not known.

#REDRAW
   this is just a short form for <6 4 STO 9208> that initiates a redraw of the graphic interface.
   Usually, you don't need it as the #MENUMAINLOOP manages the redraws. But, inside one subroutine,
   if you change a flag or a register value, you can redraw the interface while your program
   is running.

#GOTOMENU m e
   In your program, if you want to manually swap to another form, use this.
   It will go to menu m with active element e. It is a short form for <e STO 9203 m STO 9202>
   The menu is not displayed, it will be when you go back to the main loop
   or if you use #REDRAW.



  Optimizations for MK-161
  ------------------------


1) When you use #NUM with an unresolved label, it uses 4 digits by default.
   If you are sure that the reference will use less than 4 digits, you can
   replace the directive by #NUM3 for 3 digits, #NUM2 or even #NUM1.

2) By default, IF(test)THEN and ELSE use a long jump (two bytes for the address).
   If you are sure that the jump will be in the same hundred, you can force a short
   jump by adding a leading ! to the instruction.
   Example: !IF(x>=0)THEN SQR !ELSE /-/ SQR ENDIF

3) By default, WHILE(test) uses a long jump (two bytes for the address).
   Again, you can use !WHILE(test) to force a short jump and save one byte.

4) If you are working again with your source file and that every optimization
   can become unappropriate, you can use: #OPTIM 0 to disable every optimization.
   Default value is #OPTIM 1

Note: no control is made on optimizations, be sure of what you're doing!


  ERROR MESSAGES
  --------------

When the compiler reports an error, it precises the line containing the error.
According to your text editor, line numbers can start at 0 or 1. Default is 1.
If you want to change this, use this directive:

#FirstLine n (n being any number)


  COMPILE FOR EMULATOR USE
  ------------------------

This compiler can output the *.MK? files that can be loaded into both the MK.EXE manager
from SEMICO and the eMKatic Electronika MK-161 emulator.

The three types of files are generated according what your program uses:
  *.MKP the program file, *.MKB the binary file, *.MKD the decimal file.

The directive is this one:

#MKFiles n

n=0, no output (default value)
n=1, ask for saving the file when compilation is successfull.
n=2, auto save with same file name and adapting extension.


  Calling MK-COMPILER as a SLAVE program
  --------------------------------------

call : mk-compiler myfile.inf

One parameter is the info file, it is a text file that contains those lines:

path+name of source
path+name of dest
command number
path+name of C3

-> if command = 2
   compile source file to dest and eventually to C3 file.
   if a C3 file is present, then acts as if '#C3 2' was in the source.
   (note: in Slave mode, the #C3 directive is ignored)

-> if command = 7
   extract program from C3 file to source (dest is ignored)

-> if command = 8
   C3 is not a file name but a string with HEX codes
   convert those codes to a source (dest is ignored)

-> Upon return, you get a code : 
   00 : Ok, operation successfull
   01 : Can't read INF file
   02 : Unknown command in INF file
   03 : Can't open C3 file (with command 7)
   04 : Program not found in C3 file (command 7)
   05 : Bad HEX code string lenght (odd or null)
   06 : Bad HEX code in string
   07 : Can't create TXT file (command 7 or 8)
   08 : Can't open source (command 2)
   09 : Can't open destination (command 2)
   10 : Compilation error: low byte=10 and then error/256 = line number of error
        A message box opens with a compilation error giving more informations.




  -- END OF FILE --
