Elektronika MK-161

Version Française     Русская версия
WikipédiA



A calculator made in Russia with RPN logic and programmable!
Wonderful evolution from the MK-61/52 models with:
  • 10 000 program steps
  • 1000 registers
  • binary zone of 4096 bytes
  • text zone of 3072 bytes
  • 512 kB RAM disk for file storage
  • backlight graphic display 128×64
  • I/O port for storage, serial or parallel link
  • include software to manage the graphic interface with menus and dialogs

MK-Compiler Emulator The menus Extended programming USOMK-4 I/O module Disk UZVMK-1 Speed/Precision Graphic Interface


MK-Compiler

I wrote the MK-Compiler that allows you to write your program on a PC using a high-level language and to send them via RS-232 to the calculator. The program includes:
  • register names instead of numbers
  • automatic labels instead of addresses
  • structures such as FOR/NEXT, IF.THEN.ELSE, DO/WHILE, REPEAT/UNTIL
  • international notation compatibility for key labelling in the listings
  • The program zone, binary zone, and register zone into one signle source file
  • sending those three zones directly to the calculator
  • screen capture of both main and graphic screens into a PNG image

MK-Compiler's main screen


Download MK-COMPILER 161. Content:
  • The compiler itself for Windows V1.09 (july 2016).
  • the source of the compiler in PureBasic.
  • The help file.
  • The interface with 3 languages: English, French or Russian.
The main work of this compiler is to take your source code...

...and turn it into machine codes for the MK-161



Then you send the program to your calculator...

Next, an example of a program containing binary data.
And you can grab the main or graphic screen of the MK.

Next, screen capture of the main screen.
One example: PI calculation

     ; just one register required
#REG 0 N

DO
     ; display the prompt on the comment line
  #NUM ask
  EXEC \CPrintStringB

     ; wait for a value 
  INPUT

     ; stored in N
  STO N

     ; prepare the comment line for the answer
  #NUM result
  EXEC \CPrintStringB

     ; at start, sum is zero
  CX

     ; computes the sum of 1/n²=PI²/6
  FOR N
    @N X^2 1/X +
  NEXT

     ; corrections to find PI
  6 * SQR

     ; stop to display
  STOP
LOOP

     ; binary zone for text data
#BINARY

     ; TEXTN adds a leading 0A (new line) and 
     ; an ending nul character.
     ; newline is required to clear the comment line

ask:
#TEXTN "How many loops?"
result:
#TEXTN "Pi approximation"
Compiled listing

     PROGAM ZONE
  Step  | Code | Keys
-------------------------
  0000  |  01  | 1
  0001  |  00  | 0
  0002  |  00  | 0
  0003  |  00  | 0
  0004  |  F4  | PP M 
  0005  |  90  | 9 0
  0006  |  27  | 2 7
  0007  |  50  | R/S 
  0008  |  40  | M 0
  0009  |  01  | 1
  0010  |  00  | 0
  0011  |  01  | 1
  0012  |  07  | 7
  0013  |  F4  | PP M 
  0014  |  90  | 9 0
  0015  |  27  | 2 7
  0016  |  0D  | CX 
  0017  |  60  | RM 0
  0018  |  22  | F X^2 
  0019  |  23  | F 1/X 
  0020  |  10  | + 
  0021  |  5D  | F L0 
  0022  |  17  | 1 7
  0023  |  06  | 6 
  0024  |  12  | * 
  0025  |  21  | F SQRT 
  0026  |  50  | R/S 
  0027  |  51  | GOTO 
  0028  |  00  | 0 0
     BINARY ZONE
  Step  | Code | Comment
-------------------------
  1000  |  0A  | newline
  1001  |  48  | "H"
  1002  |  6F  | "o"
  1003  |  77  | "w"
  1004  |  20  | " "
  1005  |  6D  | "m"
  1006  |  61  | "a"
  1007  |  6E  | "n"
  1008  |  79  | "y"
  1009  |  20  | " "
  1010  |  6C  | "l"
  1011  |  6F  | "o"
  1012  |  6F  | "o"
  1013  |  70  | "p"
  1014  |  73  | "s"
  1015  |  3F  | "?"
  1016  |  00  | nul
  1017  |  0A  | newline
  1018  |  50  | "P"
  1019  |  69  | "i"
  1020  |  20  | " "
  1021  |  61  | "a"
  1022  |  70  | "p"
  1023  |  70  | "p"
  1024  |  72  | "r"
  1025  |  6F  | "o"
  1026  |  78  | "x"
  1027  |  69  | "i"
  1028  |  6D  | "m"
  1029  |  61  | "a"
  1030  |  74  | "t"
  1031  |  69  | "i"
  1032  |  6F  | "o"
  1033  |  6E  | "n"
  1034  |  00  | nul
-------------------------

  Addr  |  Name
-------------------------
B 1000  |  ASK
B 1017  |  RESULT
-------------------------

   Reg  |  Name
-------------------------
     0  |  N
  9027  |  \CPRINTSTRINGB
-------------------------

--     END OF FILE     --
Running:

Back to step 0000 with B/O, then run the program with R/S.
First screen:


I tried 500 iterations (key in 500 then R/S), here is the corresponding PI value:


You can press R/S again to enter a new value. I tried 10000:


The emulator eMKatic MK-161

MK-Compiler can be used together with the emulator eMKatic MK-161 as it generates the files used by the emulator.



The emulator running my program PI Monte Carlo
Just add this line:
#MKFiles 2
in your source code and the compiler will generate the three files according to what your program uses:
  • *.MKP: program file
  • *.MKB: binary file
  • *.MKD: decimal file


Run the emulator and, with a right clic, make this pop-up appear:


Select the line as show to load your files.

eMKatic supports localization and you can download language files. For example, english:

As of version 1.04, MK-Compiler is able to call directly the emulator sending it all files created.

  • Option 5: set the path to your emulator.
  • Option 8: after a compilation, directly test your program


The menus

Next you'll find the keys used when navigating through the menus.

Some keys can have different actions according to the context.

You access the root of the menu with OUTPUT



Below, you get the copy of the Menus labelled both in russian and in english. You can clic to develop one part or to close it, as you would do it on the calculator:

Tout ouvrir | Tout fermer

Extended programming


Some functions are available through read/write in pseudo registers 9000-9999.
How to key in a STO or RCL from the keyboard:
  • To read: Р Р ИП nnnn
  • To write: Р Р П nnnn
There are lots of functions covering a wide range of domains:
  • The graphism
  • The keyboard
  • The interrupts, timers, clock
  • The files
  • The graphic interface
This can be useful, the key codes :
--
ON
35
36
34
--
22
P
31
Р-ГРД-Г
37
32
ВЫХОД
33
ВВОД
20
F
23
шг→
24
шг←
25
В/О
26 (*)
С/П
21
K
27
ИП
28
П
29
БП
30
ПП
07
7
08
8
09
9
16
-
18
÷
04
4
05
5
06
6
15
+
17
×
01
1
02
2
03
3
19
14
B↑
00
0
10
,
11
/-/
12
ВП
13
Cx

Note : code 26 is never returned as it stops the program. Keys ON and Light do not return any code.


Some examples for download


Font
File Demo
Inter Music
Sprite
Use #FONT/#DEFCHAR to redefine characters.
Use #FINDFILE/#CREATEFILE/#LOADFILE to manage folders and files.
Use an interrupt to play music while some lines are displayed.
Use #DEFGRAPH to define sprites and display them (below, the example)


Example


This programs takes a value 0, 1 or 2 in input and then displays 20 times the corresponding pattern at random screen positions.
The choice is 0=star, 1=square et 2=circle. At the end, the program waits for a key, you can enter a new value and press R/S.
       ; used registers

#reg 0 Index
#reg e ObjectAddress

DO

       ; computes the pattern address
       ; in BINARY memory using a table

  ENTER
  #NUM Table + PRGM
  $1000 +
  STO ObjectAddress

       ; clear screen

  0 EXEC \CLS

       ; for 20 loops

  $20 STO Index

  FOR Index

       ; random coordinates
    $56 RND *
    $120 RND * SET \x0y0

       ; then the pattern is drawn
    @ObjectAddress EXEC \PUTGB

  NEXT

       ; display the graphic screen
  GRPH

       ; wait for a key
  REPEAT
    GET \NEXTKEY
    NOT
  UNTIL(x<>0)

       ; wait for a new value
  INPUT

LOOP
    
       ; table with 3 addresses
Table:
#DAL star square circle #END
       ; swap to BINARY memory
#BINARY

star:
#DEFGRAPH
  *..*..*
  .*.*.*.
  ..***..
  *******
  ..***..
  .*.*.*. 
  *..*..*
#END

square:
#DEFGRAPH
  *******
  *.....*
  *.....*
  *.....*
  *.....*
  *.....*
  *.....*
  *******
#END

circle:
#DEFGRAPH
  ..***..
  .*...*.
  *.....*
  *.....*
  *.....*
  *.....*
  .*...*.
  ..***..
#END
Here are the screen shots of the three possibilities:


The 20 stars, value 0.


The 20 squares, value 1.


The 20 circles, value 2.
And the resulting compiled program:
     PROGAM ZONE
  Step  | Code | Keys
-------------------------
  0000  |  0E  | ENT 
  0001  |  00  | 0
  0002  |  00  | 0
  0003  |  04  | 4
  0004  |  08  | 8
  0005  |  10  | + 
  0006  |  28  | K PRGM 
  0007  |  01  | 1
  0008  |  00  | 0
  0009  |  00  | 0
  0010  |  00  | 0
  0011  |  10  | + 
  0012  |  4E  | M e
  0013  |  00  | 0 
  0014  |  F4  | PP M 
  0015  |  90  | 9 0
  0016  |  10  | 1 0
  0017  |  02  | 2
  0018  |  00  | 0
  0019  |  40  | M 0
  0020  |  05  | 5
  0021  |  06  | 6
  0022  |  3B  | K RAN 
  0023  |  12  | * 
  0024  |  01  | 1
  0025  |  02  | 2
  0026  |  00  | 0
  0027  |  3B  | K RAN 
  0028  |  12  | * 
  0029  |  F4  | PP M 
  0030  |  90  | 9 0
  0031  |  00  | 0 0
  0032  |  6E  | RM e
  0033  |  F4  | PP M 
  0034  |  90  | 9 0
  0035  |  16  | 1 6
  0036  |  5D  | F L0 
  0037  |  20  | 2 0
  0038  |  56  | K GRPH 
  0039  |  F6  | PP RM 
  0040  |  90  | 9 0
  0041  |  29  | 2 9
  0042  |  3A  | K NOT 
  0043  |  57  | F X!=0 
  0044  |  39  | 3 9
  0045  |  50  | R/S 
  0046  |  51  | GOTO 
  0047  |  00  | 0 0
  0048  |  00  | AL(0)
  0049  |  09  | AL(9)
  0050  |  12  | AL(18)
  
        BINARY ZONE
     Step  | Code | Comment
   -------------------------
     1000  |  07  | Width
     1001  |  07  | Height
     1002  |  49  | byte
     1003  |  2A  | byte
     1004  |  1C  | byte
     1005  |  7F  | byte
     1006  |  1C  | byte
     1007  |  2A  | byte
     1008  |  49  | byte
     1009  |  07  | Width
     1010  |  08  | Height
     1011  |  FF  | byte
     1012  |  81  | byte
     1013  |  81  | byte
     1014  |  81  | byte
     1015  |  81  | byte
     1016  |  81  | byte
     1017  |  FF  | byte
     1018  |  07  | Width
     1019  |  08  | Height
     1020  |  3C  | byte
     1021  |  42  | byte
     1022  |  81  | byte
     1023  |  81  | byte
     1024  |  81  | byte
     1025  |  42  | byte
     1026  |  3C  | byte
   -------------------------

     Addr  |  Name
   -------------------------
     0048  |  TABLE
   B 1000  |  STAR
   B 1009  |  SQUARE
   B 1018  |  CIRCLE
   -------------------------

      Reg  |  Name
   -------------------------
        0  |  INDEX
        e  |  OBJECTADDRESS
     9000  |  \X0Y0
     9010  |  \CLS
     9016  |  \PUTGB
     9029  |  \NEXTKEY
   -------------------------

   --     END OF FILE     --


Module USOMK-4

This module has two output canals to drive two relays and one input canal Open/Closed.
  • Canal A: relay command (output)
  • Canal B: repay command (output)
  • Canal C: test (input)

Programming the interface

  • Parallel regsiter R9090 (W)
    • If you set this register to 1, the port is in parallel mode. Required to work with this interface.

  • Command register R9092 (R/W)
    • Read this register to test the state on Canal C: bit 3 is on if OPEN and off if CLOSED (Value AND 8 = 0 if closed)
    • Write to the register to set the state of Canals A and B


    • Possible values:
      ValueCanal ACanal B
      1ONON
      3OFFON
      5ONOFF
      7OFFOFF
Exemple




Let's imagine that a door is wired to Canal C to know if it's open or closed. We want to switch an alarm ON everytime it's open and then switch the alarm OFF when it is closed again.
       ; parallel port
1 SET \IOmode
DO
       ; wait for canal C to be OPEN
  REPEAT
    GET \IOModule
    8 AND
  UNTIL(x<>0)

       ; if OPEN then switch ON alarm
       ; on canal A
  5 SET \IOModule

       ; wait for canal C to be closed
  REPEAT
    GET \IOModule
    8 AND
  UNTIL(x=0)

       ; when closed switch OFF alarm
       ; on canal A
  7 SET \IOModule

LOOP
Compiled listing:
     PROGAM ZONE
  Step  | Code | Keys
-------------------------
  0000  |  01  | 1 
  0001  |  F4  | PP M 
  0002  |  90  | 9 0
  0003  |  90  | 9 0
  0004  |  F6  | PP RM 
  0005  |  90  | 9 0
  0006  |  92  | 9 2
  0007  |  08  | 8 
  0008  |  37  | K AND 
  0009  |  57  | F X!=0 
  0010  |  04  | 0 4
  0011  |  05  | 5 
  0012  |  F4  | PP M 
  0013  |  90  | 9 0
  0014  |  92  | 9 2
  0015  |  F6  | PP RM 
  0016  |  90  | 9 0
  0017  |  92  | 9 2
  0018  |  08  | 8 
  0019  |  37  | K AND 
  0020  |  5E  | F X=0 
  0021  |  15  | 1 5
  0022  |  07  | 7 
  0023  |  F4  | PP M 
  0024  |  90  | 9 0
  0025  |  92  | 9 2
  0026  |  51  | GOTO 
  0027  |  04  | 0 4
-------------------------

   Reg  |  Name
-------------------------
  9090  |  \IOMODE
  9092  |  \IOMODULE
-------------------------

--     END OF FILE     --


Disk UZVMK-1

This module is seen as "Disk B" (compared to the internal RAM disk that is Disk A) and brings the exact amount of memory as Disk A : 512 kB. This allows you, for example, to get an exact copy of the internal memory for backup purposes.

The disk is organized in 2048 blocks of 264 bytes each. I suppose that 8 bytes in each block are reserved for internal managment and that only 256 bytes are used for your data. So 256×2048=512×1024=512 kB.


Speed and precision

On the MK-161, programming has been enhanced compared to the MK-61/52. A larger number of program steps, many more registers and a graphic screen for a better comfort and more friendly interface.

Precision Tests Speed tests
Forensic

This is a test on scientific functions, in degrees, you type:
arcsin(arccos(arctan(tan(cos(sin(9))))))


Result: 8,9999999772404.

The theoric value is 9 !
Hebdogiciel

20 =0 =1
2
FOR 0 SQR NEXT
FOR 1 X^2 NEXT
STOP
Result: 1,9999999837026

The theoric value is 2 !
Boucle simple:
0000 +
0001 GOTO 00
Starting with 1 1 1 0 on the stack and during 60 seconds, the sum is 95756.
It's about 800 times faster than the MK-61...
PI Calculation

Using the program above on this page:
  • 10.000 iterations : 1 min 09 sec.
  • 100.000 iterations : 11 min 29 sec
  • (result = 3.1415831)


Graphic Interface

This calculator provides a very good graphic interface with lots of options to manage menus, input and output of data, etc. But writing such a program is really hard as you have to fill lots of tables, pointers and data to make it work.

With MK-Compiler, in a really short time you can write programs that will look professional managing the graphic interface. Most of the work is done by the compiler and you just have to concentrate on your own routines.


Download some demo programs

Each archive contains the source, the compiled program, the file for emulator and short explanations.


Secret Number
Check
PI Monte Carlo
Atari
Use "RadioButtons", multiple menus, SELECT/ENDSELECT
Use checked lines.
Use the progress bar, multiple menus, FOR/NEXT, time calculation, sound.
Use a graphical menu with blocks inside an icon.


A commented example


#MKFiles 2

;--------------------
; Register definitons
;--------------------

#reg a GrainNum		; how many grains of sand per run
#reg b PiValue		; resulting PI approximation (for display)
#reg c Total		; accumulator of grains of sand through the runs
#reg d InsideCircle	; accumulator of grains inside the quarter of circle
#reg e Duration		; duration of a run in HH.MMSS (for display)
#reg 7 Address		; address of the subprogram corresponding to the active element
#reg 0 Hundred		; for looping
#reg 1 Iter		; idem
#reg 6 progress		; value from 9 to 116 for bar progression
#reg 5 done		; flag for second menu
#reg 4 limit		; to limit number of iterations
The program given in example computes an approximation of PI using the MonterCarlo's method:

If you drop at random grains of sand onto a square,



the probability that it falls into the quarter of circle is equal to:



So, you can simulate this and get an approximation of PI!


;--------------------
; Main Menu description
;--------------------

#MENU					; this is menu 0
	#STRING 1 "PI MonteCarlo"	; The title in big font
	#HLINE				; separator
	#VINPUTD "Hundreds grains :" 92 GrainNum verif
					; one "input" line to set GrainNum and
					; a verification routine to validate entry
	#ACTION "Run !" Calculation	; one "action" line (will go to Calculation)

	#OUTPUTD 0 "PI =" 32 PiValue	; one "output" line showing register PiValue
	#OUTPUTF 0 "Time :" 50 Duration 2 4
					; one "output" formatted line to display time
	#HLINE				; separator
	#ACTION "Exit !" ProgramEnd	; one "action" line (will go to ProgramEnd)
#ENDMENU
Here is the description of the Main Menu.

Here is what it will look like:



Click on
  • Hundreds grains to change the number of grains
  • Run ! to start calculating
  • Exit ! to quit the program


;--------------------
; Sub Menu description
;--------------------

#MENU					; this is menu 1
	#STRING 1 "Calculating..."	; a big title
	#BLANK 10			; jump lines
	#STARTRECT			; a rectangle to enclose...
	#PROGRESSBAR progress		; ... the progress bar based on register "progress"
	#ENDRECT			; close rectangle
	#BLANK 10			; jump lines
	#?LINK "Progress..." 0 Done "Done !"
					; conditional link, display "Progress" during calculation
					; and display "Done !" at the end (when register done=1)
					; this is a link to menu 0.
#ENDMENU
Here the sub menu when calculating

There you can see the progress bar:



When calculation is done...
...you can see your results !

Clic on "Done !" to go back to the main menu.

You get the value of PI and the calculation time.


That's all you have to do for the interface !

Then, this is a common program, you can see next the initializations of the variables.

The heart of the system is entirely included in the "#MENUMAINLOOP" that containss everything your program needs to manage the menus. Then all you have to do is to prepare the different sub programs that react to the interactions with the screen.
;--------------------
; My initializations
;--------------------

CX 
	=PiValue =Total =InsideCircle
	=Duration
	=done
1
	SET GrainNum				; default = 1 hundred = 100 grains per run
9
	SET progress				; 9 = 0% in the progress bar
$1000
	SET limit				; no more than 1000 hundreds
;--------------------
; The main loop here
;--------------------

#MENUMAINLOOP Address


The sub program executed with "Exit !" is simple!
ProgramEnd:					; if Exit! selected, just stop.
	STOP


The sub program executed after an input

is easy: it verifies that you don't exceed the limit and that your value is greater than zero.
verif:
	@GrainNum 				; entered value
	/-/
	IF(X>=0)THEN		
		1 =GrainNum			; if negative or nul, then back to 1
	ELSE
		@limit +
		IF(x<0)THEN			; if limit<entry
			@limit =GrainNum	; then back to limit
		ENDIF
	ENDIF
	RTN


;--------------------
; My subprograms
;--------------------

Note:						; subprogram to make a sound
	ENT $20 EXEC \Sound			; ENTERs the frequency, 20/100 sec for duration
	REPEAT
		GET \SOUND			; is sound terminated?
	UNTIL(x=0)				; if not equal to zero, go on
	RTN

Calculation:
	0 =done					; for conditional link		
	#GOTOMENU 1 0				; swap to menu 1, active element 0
	
	GET \TIME HMS> =Duration		; start time saved
	
	@GrainNum =Hundred			; for the loop
	SUM Total				; update the accumulator with new grains
	
	FOR Hundred				; for every hundred of grains
	
	    1 ENTER @Hundred @GrainNum / -	; compute progress bar position (9-116)
	    $107 * 9 + =progress		; according to loop value
	    #REDRAW				; and display new bar
		
	    $100 =Iter				; run for one hundred grains
	    FOR Iter
		RAN X^2 RAN X^2 + 1 -		; compare 1 with random x^2+y^2
		IF(x<0)THEN			; if <1 then
			1 SUM InsideCircle	; 1 on the accumulator
		ENDIF
	    NEXT
		
	NEXT
	
	$116 =progress				; progress bar at 100%
	1 =done					; change conditional link
	#REDRAW					; and display interface
	
	@InsideCircle @Total / $25 / =PiValue	; (inside/total) / 100 * 4 = PI
	
	GET \TIME HMS> 
	@Duration - >HMS =Duration		; newtime-starttime = duration
	
	$523 Gosub Note				; marvellous music to say it's done
	$880 Gosub Note
	$699 Gosub Note
	RTN
The sub program executed with "Run !"

It starts at "Calculation", some initializations are done (flags, start time, display second menu with progress bar).

Then the main loop updates the position of the progress bar and drops grains of sand by packets of 100.

When everything is done, Pi is computed, the total time calculated, flags are changed and you can hear a 3 notes music to know that it's over.

No return is forced to Main menu as the main loop will do it for us : at the end of calculation, you have to select "Done !" in the submenu, the is linked to menu 0.


Since December, 15th, 2007