*** empty log message ***
[emacs.git] / lisp / progmodes / mixal-mode.el
blob72a0f2e9105f13a67e59d7e70763bb55969d8ac3
1 ;;; mixal-mode.el --- Major mode for the mix asm language.
3 ;; Copyright (C) 2003 Free Software Foundation
5 ;; This program is free software; you can redistribute it and/or
6 ;; modify it under the terms of the GNU General Public License as
7 ;; published by the Free Software Foundation; either version 2 of
8 ;; the License, or (at your option) any later version.
10 ;; This program is distributed in the hope that it will be
11 ;; useful, but WITHOUT ANY WARRANTY; without even the implied
12 ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 ;; PURPOSE. See the GNU General Public License for more details.
15 ;; You should have received a copy of the GNU General Public
16 ;; License along with this program; if not, write to the Free
17 ;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 ;; MA 02111-1307 USA
20 ;; Author: Pieter E.J. Pareit <pieter.pareit@skynet.be>
21 ;; Maintainer: Pieter E.J. Pareit <pieter.pareit@skynet.be>
22 ;; Created: 09 Nov 2002
23 ;; Version: 0.1
24 ;; Keywords: Knuth mix mixal asm mixvm "The Art Of Computer Programming"
26 ;;; Commentary:
27 ;; Major mode for the mix asm language.
28 ;; The mix asm language is described in "The Art Of Computer Programming".
30 ;; For optimal use, also use GNU MDK. Compiling needs mixasm, running
31 ;; and debugging needs mixvm and mixvm.el from GNU MDK. You can get
32 ;; GNU MDK from `https://savannah.gnu.org/projects/mdk/' and
33 ;; `ftp://ftp.gnu.org/pub/gnu/mdk'.
35 ;; To use this mode, place the following in your .emacs file:
36 ;; `(load-file "/PATH-TO-FILE/mixal-mode.el")'.
37 ;; When you load a file with the extension .mixal the mode will be started
38 ;; automatic. If you want to start the mode manual, use `M-x mixal-mode'.
39 ;; Font locking will work, the behavior of tabs is the same as emacs
40 ;; default behavior. You can compile a source file with `C-c c' you can
41 ;; run a compiled file with `C-c r' or run it in debug mode with `C-c d'.
42 ;; You can get more information about a particular operation code by using
43 ;; mixal-describe-operation-code or `C-h o'.
45 ;; Have fun.
47 ;;; History:
48 ;; Version 0.1:
49 ;; Version 0.1.1:
50 ;; 22/11/02: bugfix in fontlocking, needed to add a '-' to the regex.
51 ;; 19/11/02: completed implementing mixal-describe-operation-code.
52 ;; 13/11/02: implemented compile, mixal-run and mixal-debug.
53 ;; 10/11/02: implemented font-locking and syntax table.
54 ;; 09/11/02: started mixal-mode.
56 ;;; Code:
58 ;;; Key map
59 (defvar mixal-mode-map
60 (let ((map (make-sparse-keymap)))
61 (define-key map "\C-cc" 'compile)
62 (define-key map "\C-cr" 'mixal-run)
63 (define-key map "\C-cd" 'mixal-debug)
64 (define-key map "\C-ho" 'mixal-describe-operation-code)
65 map)
66 "Keymap for `mixal-mode'.")
67 ; (makunbound 'mixal-mode-map)
69 ;;; Syntax table
70 (defvar mixal-mode-syntax-table
71 (let ((st (make-syntax-table)))
72 (modify-syntax-entry ?* "<" st)
73 (modify-syntax-entry ?\n ">" st)
74 st)
75 "Syntax table for `dot-mode'.")
77 (defvar mixal-font-lock-label-face 'font-lock-variable-name-face
78 "Face name to use for label names.
79 Default value is that of `font-lock-variable-name-face', but you can modify
80 its value.")
82 (defvar mixal-font-lock-operation-code-face 'font-lock-keyword-face
83 "Face name to use for operation code names.
84 Default value is that of `font-lock-keyword-face', but you can modify its
85 value.")
87 (defvar mixal-font-lock-assembly-pseudoinstruction-face 'font-lock-builtin-face
88 "Face name to use for assembly pseudoinstruction names.
89 Default value is that of `font-lock-builtin-face', but you can modify its
90 value.")
92 (defvar mixal-operation-codes
93 '("NOP" "ADD" "FADD" "SUB" "FSUB" "MUL" "FMUL" "DIV" "FDIV" "NUM" "CHAR"
94 "HLT" "SLA" "SRA" "SLAX" "SRAX" "SLC" "SRC" "MOVE" "LDA" "LD1" "LD2" "LD3"
95 "LD4" "LD5" "LD6" "LDX" "LDAN" "LD1N" "LD2N" "LD3N" "LD4N" "LD5N" "LD6N"
96 "LDXN" "STA" "ST1" "ST2" "ST3" "ST4" "ST5" "ST6" "STX" "STJ" "STZ" "JBUS"
97 "IOC" "IN" "OUT" "JRAD" "JMP" "JSJ" "JOV" "JNOV"
98 "JAN" "J1N" "J2N" "J3N" "J4N" "J5N" "J6N" "JXN"
99 "JAZ" "J1Z" "J2Z" "J3Z" "J4Z" "J5Z" "J6Z" "JXZ"
100 "JAP" "J1P" "J2P" "J3P" "J4P" "J5P" "J6P" "JXP"
101 "JANN" "J1NN" "J2NN" "J3NN" "J4NN" "J5NN" "J6NN" "JXNN"
102 "JANZ" "J1NZ" "J2NZ" "J3NZ" "J4NZ" "J5NZ" "J6NZ" "JXNZ"
103 "JANP" "J1NP" "J2NP" "J3NP" "J4NP" "J5NP" "J6NP" "JXNP"
104 "INCA" "DECA" "ENTA" "ENNA" "INC1" "DEC1" "ENT1" "ENN1"
105 "INC2" "DEC2" "ENT2" "ENN2" "INC3" "DEC3" "ENT3" "ENN3" "INC4" "DEC4"
106 "ENT4" "ENN4" "INC5" "DEC5" "ENT5" "ENN5" "INC6" "DEC6" "ENT6" "ENN6"
107 "INCX" "DECX" "ENTX" "ENNX" "CMPA" "FCMP" "CMP1" "CMP2" "CMP3" "CMP4"
108 "CMP5" "CMP6" "CMPX")
109 "List of possible operation codes as strings.")
110 ; (makunbound 'mixal-operation-codes)
112 (defvar mixal-assembly-pseudoinstructions
113 '("ORIG" "EQU" "CON" "ALF" "END")
114 "List of possible assembly pseudoinstructions")
116 ;;; Font-locking:
117 (defvar mixal-font-lock-keywords
118 `(("^\\([A-Z0-9a-z]+\\).*$"
119 (1 mixal-font-lock-label-face))
120 (,(regexp-opt mixal-operation-codes 'words)
121 . mixal-font-lock-operation-code-face)
122 (,(regexp-opt
123 mixal-assembly-pseudoinstructions 'words)
124 . mixal-font-lock-assembly-pseudoinstruction-face)
125 ("^[A-Z0-9a-z]*[ \t]+[A-Z0-9a-z]+[ \t]+[\\-A-Z0-9a-z,():]*[\t]+\\(.*\\)$"
126 (1 font-lock-comment-face)))
127 "Keyword highlighting specification for `mixal-mode'.")
128 ; (makunbound 'mixal-font-lock-keywords)
130 ;;;; Compilation
131 ;; Output from mixasm is compatible with default behavior of emacs,
132 ;; I just added a key (C-cc) and modified the make-command.
134 ;;;; Indentation
135 ;; Tabs works well by default.
137 ;;;; Describe
138 (defvar mixal-operation-codes-alist '()
139 "Alist that contains all the possible operation codes for mix.
140 Each elt has the form (OP-CODE GROUP FULL-NAME C-BYTE F-BYTE DESCRIPTION EXECUTION-TIME)
141 Where OP-CODE is the text of the opcode as an symbol, FULL-NAME is the human readable name
142 as a string, C-BYTE is the operation code telling what operation is to be performed, F-BYTE holds
143 an modification of the operation code which can be a symbol or a number, DESCRIPTION contains
144 an string with a description about the operation code and EXECUTION-TIME holds info
145 about the time it takes, number or string.")
146 ; (makunbound 'mixal-operation-codes-alist)
148 (defun mixal-add-operation-code (op-code group full-name C-byte F-byte description execution-time)
149 "Add an operation code to the list that contains information about possible op code's."
150 (setq mixal-operation-codes-alist (cons (list op-code group full-name C-byte F-byte
151 description execution-time)
152 mixal-operation-codes-alist )))
154 ;; now add each operation code
156 (mixal-add-operation-code
157 'LDA 'loading "load A" 8 'field
158 "Put in rA the contents of cell no. M.
159 Uses a + when there is no sign in subfield. Subfield is left padded with
160 zeros to make a word."
163 (mixal-add-operation-code
164 'LDX 'loading "load X" 15 'field
165 "Put in rX the contents of cell no. M.
166 Uses a + when there is no sign in subfield. Subfield is left padded with
167 zeros to make a word."
170 (mixal-add-operation-code
171 'LD1 'loading "load I1" (+ 8 1) 'field
172 "Put in rI1 the contents of cell no. M.
173 Uses a + when there is no sign in subfield. Subfield is left padded with
174 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
175 to set anything more that that will result in undefined behavior."
178 (mixal-add-operation-code
179 'LD2 'loading "load I2" (+ 8 2) 'field
180 "Put in rI2 the contents of cell no. M.
181 Uses a + when there is no sign in subfield. Subfield is left padded with
182 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
183 to set anything more that that will result in undefined behavior."
186 (mixal-add-operation-code
187 'LD3 'loading "load I3" (+ 8 3) 'field
188 "Put in rI3 the contents of cell no. M.
189 Uses a + when there is no sign in subfield. Subfield is left padded with
190 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
191 to set anything more that that will result in undefined behavior."
194 (mixal-add-operation-code
195 'LD4 'loading "load I4" (+ 8 4) 'field
196 "Put in rI4 the contents of cell no. M.
197 Uses a + when there is no sign in subfield. Subfield is left padded with
198 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
199 to set anything more that that will result in undefined behavior."
202 (mixal-add-operation-code
203 'LD5 'loading "load I5" (+ 8 5) 'field
204 "Put in rI5 the contents of cell no. M.
205 Uses a + when there is no sign in subfield. Subfield is left padded with
206 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
207 to set anything more that that will result in undefined behavior."
210 (mixal-add-operation-code
211 'LD6 'loading "load I6" (+ 8 6) 'field
212 "Put in rI6 the contents of cell no. M.
213 Uses a + when there is no sign in subfield. Subfield is left padded with
214 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
215 to set anything more that that will result in undefined behavior."
218 (mixal-add-operation-code
219 'LDAN 'loading "load A negative" 16 'field
220 "Put in rA the contents of cell no. M, with opposite sign.
221 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
222 Subfield is left padded with zeros to make a word."
225 (mixal-add-operation-code
226 'LDXN 'loading "load X negative" 23 'field
227 "Put in rX the contents of cell no. M, with opposite sign.
228 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
229 Subfield is left padded with zeros to make a word."
232 (mixal-add-operation-code
233 'LD1N 'loading "load I1 negative" (+ 16 1) 'field
234 "Put in rI1 the contents of cell no. M, with opposite sign.
235 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
236 Subfield is left padded with zeros to make a word. Index registers only
237 have 2 bytes and a sign, Trying to set anything more that that will result
238 in undefined behavior."
241 (mixal-add-operation-code
242 'LD2N 'loading "load I2 negative" (+ 16 2) 'field
243 "Put in rI2 the contents of cell no. M, with opposite sign.
244 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
245 Subfield is left padded with zeros to make a word. Index registers only
246 have 2 bytes and a sign, Trying to set anything more that that will result
247 in undefined behavior."
250 (mixal-add-operation-code
251 'LD3N 'loading "load I3 negative" (+ 16 3) 'field
252 "Put in rI3 the contents of cell no. M, with opposite sign.
253 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
254 Subfield is left padded with zeros to make a word. Index registers only
255 have 2 bytes and a sign, Trying to set anything more that that will result
256 in undefined behavior."
259 (mixal-add-operation-code
260 'LD4N 'loading "load I4 negative" (+ 16 4) 'field
261 "Put in rI4 the contents of cell no. M, with opposite sign.
262 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
263 Subfield is left padded with zeros to make a word. Index registers only
264 have 2 bytes and a sign, Trying to set anything more that that will result
265 in undefined behavior."
268 (mixal-add-operation-code
269 'LD5N 'loading "load I5 negative" (+ 16 5) 'field
270 "Put in rI5 the contents of cell no. M, with opposite sign.
271 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
272 Subfield is left padded with zeros to make a word. Index registers only
273 have 2 bytes and a sign, Trying to set anything more that that will result
274 in undefined behavior."
277 (mixal-add-operation-code
278 'LD6N 'loading "load I6 negative" (+ 16 6) 'field
279 "Put in rI6 the contents of cell no. M, with opposite sign.
280 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
281 Subfield is left padded with zeros to make a word. Index registers only
282 have 2 bytes and a sign, Trying to set anything more that that will result
283 in undefined behavior."
286 (mixal-add-operation-code
287 'STA 'storing "store A" 24 'field
288 "Store in cell Nr. M the contents of rA.
289 The modification of the operation code represents the subfield of the
290 memory cell that is to be overwritten with bytes from a register. These
291 bytes are taken beginning by the rightmost side of the register. The
292 sign of the memory cell is not changed, unless it is part of the subfield."
295 (mixal-add-operation-code
296 'STX 'storing "store X" 31 'field
297 "Store in cell Nr. M the contents of rX.
298 The modification of the operation code represents the subfield of the
299 memory cell that is to be overwritten with bytes from a register. These
300 bytes are taken beginning by the rightmost side of the register. The
301 sign of the memory cell is not changed, unless it is part of the subfield."
304 (mixal-add-operation-code
305 'ST1 'storing "store I1" (+ 24 1) 'field
306 "Store in cell Nr. M the contents of rI1.
307 The modification of the operation code represents the subfield of the
308 memory cell that is to be overwritten with bytes from a register. These
309 bytes are taken beginning by the rightmost side of the register. The
310 sign of the memory cell is not changed, unless it is part of the subfield.
311 Because index registers only have 2 bytes and a sign, the rest of the bytes
312 are assumed to be 0."
315 (mixal-add-operation-code
316 'ST2 'storing "store I2" (+ 24 2) 'field
317 "Store in cell Nr. M the contents of rI2.
318 The modification of the operation code represents the subfield of the
319 memory cell that is to be overwritten with bytes from a register. These
320 bytes are taken beginning by the rightmost side of the register. The
321 sign of the memory cell is not changed, unless it is part of the subfield.
322 Because index registers only have 2 bytes and a sign, the rest of the bytes
323 are assumed to be 0."
326 (mixal-add-operation-code
327 'ST3 'storing "store I3" (+ 24 3) 'field
328 "Store in cell Nr. M the contents of rI3.
329 The modification of the operation code represents the subfield of the
330 memory cell that is to be overwritten with bytes from a register. These
331 bytes are taken beginning by the rightmost side of the register. The
332 sign of the memory cell is not changed, unless it is part of the subfield.
333 Because index registers only have 2 bytes and a sign, the rest of the bytes
334 are assumed to be 0."
337 (mixal-add-operation-code
338 'ST4 'storing "store I4" (+ 24 4) 'field
339 "Store in cell Nr. M the contents of rI4.
340 The modification of the operation code represents the subfield of the
341 memory cell that is to be overwritten with bytes from a register. These
342 bytes are taken beginning by the rightmost side of the register. The
343 sign of the memory cell is not changed, unless it is part of the subfield.
344 Because index registers only have 2 bytes and a sign, the rest of the bytes
345 are assumed to be 0."
348 (mixal-add-operation-code
349 'ST5 'storing "store I5" (+ 24 5) 'field
350 "Store in cell Nr. M the contents of rI5.
351 The modification of the operation code represents the subfield of the
352 memory cell that is to be overwritten with bytes from a register. These
353 bytes are taken beginning by the rightmost side of the register. The
354 sign of the memory cell is not changed, unless it is part of the subfield.
355 Because index registers only have 2 bytes and a sign, the rest of the bytes
356 are assumed to be 0."
359 (mixal-add-operation-code
360 'ST6 'storing "store I6" (+ 24 6) 'field
361 "Store in cell Nr. M the contents of rI6.
362 The modification of the operation code represents the subfield of the
363 memory cell that is to be overwritten with bytes from a register. These
364 bytes are taken beginning by the rightmost side of the register. The
365 sign of the memory cell is not changed, unless it is part of the subfield.
366 Because index registers only have 2 bytes and a sign, the rest of the bytes
367 are assumed to be 0."
370 (mixal-add-operation-code
371 'STJ 'storing "store J" 32 'field
372 "Store in cell Nr. M the contents of rJ.
373 The modification of the operation code represents the subfield of the
374 memory cell that is to be overwritten with bytes from a register. These
375 bytes are taken beginning by the rightmost side of the register. The sign
376 of rJ is always +, sign of the memory cell is not changed, unless it is
377 part of the subfield. The default field for STJ is (0:2)."
380 (mixal-add-operation-code
381 'STZ 'storing "store zero" 33 'field
382 "Store in cell Nr. M '+ 0'.
383 The modification of the operation code represents the subfield of the
384 memory cell that is to be overwritten with zeros."
387 (mixal-add-operation-code
388 'ADD 'arithmetic "add" 1 'field
389 "Add to A the contents of cell Nr. M.
390 Subfield is padded with zero to make a word.
391 If the result is to large, the operation result modulo 1,073,741,823 (the
392 maximum value storable in a MIX word) is stored in `rA', and the overflow
393 toggle is set to TRUE."
396 (mixal-add-operation-code
397 'SUB 'arithmetic "subtract" 2 'field
398 "Subtract to A the contents of cell Nr. M.
399 Subfield is padded with zero to make a word.
400 If the result is to large, the operation result modulo 1,073,741,823 (the
401 maximum value storable in a MIX word) is stored in `rA', and the overflow
402 toggle is set to TRUE."
405 (mixal-add-operation-code
406 'MUL 'arithmetic "multiply" 3 'field
407 "Multiplies the contents of cell Nr. M with A, result is 10 bytes and stored in rA and rX.
408 The sign is + if the sign of rA and cell M where the same, otherwise, it is -"
411 (mixal-add-operation-code
412 'DIV 'arithmetic "divide" 4 'field
413 "Both rA and rX are taken together and divided by cell Nr. M, quotient is placed in rA, remainder in rX.
414 The sign is taken from rA, and after the divide the sign of rA is set to + when
415 both the sign of rA and M where the same. Divide by zero and overflow of rA result
416 in undefined behavior."
419 (mixal-add-operation-code
420 'ENTA 'address-transfer "enter A" 48 2
421 "Literal value is stored in rA.
422 Indexed, stores value of index in rA."
425 (mixal-add-operation-code
426 'ENTX 'address-transfer "enter X" 55 2
427 "Literal value is stored in rX.
428 Indexed, stores value of index in rX."
431 (mixal-add-operation-code
432 'ENT1 'address-transfer "Enter rI1" (+ 48 1) 2
433 "Literal value is stored in rI1.
434 Indexed, stores value of index in rI1."
437 (mixal-add-operation-code
438 'ENT2 'address-transfer "Enter rI2" (+ 48 2) 2
439 "Literal value is stored in rI2.
440 Indexed, stores value of index in rI2."
443 (mixal-add-operation-code
444 'ENT3 'address-transfer "Enter rI3" (+ 48 3) 2
445 "Literal value is stored in rI3.
446 Indexed, stores value of index in rI3."
449 (mixal-add-operation-code
450 'ENT4 'address-transfer "Enter rI4" (+ 48 4) 2
451 "Literal value is stored in rI4.
452 Indexed, stores value of index in rI4."
455 (mixal-add-operation-code
456 'ENT5 'address-transfer "Enter rI5" (+ 48 5) 2
457 "Literal value is stored in rI5.
458 Indexed, stores value of index in rI5."
461 (mixal-add-operation-code
462 'ENT6 'address-transfer "Enter rI6" (+ 48 6) 2
463 "Literal value is stored in rI6.
464 Indexed, stores value of index in rI6."
467 (mixal-add-operation-code
468 'ENNA 'address-transfer "enter negative A" 48 3
469 "Literal value is stored in rA with opposite sign.
470 Indexed, stores value of index in rA with opposite sign."
473 (mixal-add-operation-code
474 'ENNX 'address-transfer "enter negative X" 55 3
475 "Literal value is stored in rX with opposite sign.
476 Indexed, stores value of index in rX with opposite sign."
479 (mixal-add-operation-code
480 'ENN1 'address-transfer "Enter negative rI1" (+ 48 1) 3
481 "Literal value is stored in rI1 with opposite sign.
482 Indexed, stores value of index in rI1 with opposite sign."
485 (mixal-add-operation-code
486 'ENN2 'address-transfer "Enter negative rI2" (+ 48 2) 3
487 "Literal value is stored in rI2 with opposite sign.
488 Indexed, stores value of index in rI2 with opposite sign."
491 (mixal-add-operation-code
492 'ENN3 'address-transfer "Enter negative rI3" (+ 48 3) 3
493 "Literal value is stored in rI3 with opposite sign.
494 Indexed, stores value of index in rI3 with opposite sign."
497 (mixal-add-operation-code
498 'ENN4 'address-transfer "Enter negative rI4" (+ 48 4) 3
499 "Literal value is stored in rI4 with opposite sign.
500 Indexed, stores value of index in rI4 with opposite sign."
503 (mixal-add-operation-code
504 'ENN5 'address-transfer "Enter negative rI5" (+ 48 5) 3
505 "Literal value is stored in rI5 with opposite sign.
506 Indexed, stores value of index in rI5 with opposite sign."
509 (mixal-add-operation-code
510 'ENN6 'address-transfer "Enter negative rI6" (+ 48 6) 3
511 "Literal value is stored in rI6 with opposite sign.
512 Indexed, stores value of index in rI6 with opposite sign."
515 (mixal-add-operation-code
516 'INCA 'address-transfer "increase A" 48 0
517 "Increase register A with the literal value of M.
518 On overflow the overflow toggle is set."
521 (mixal-add-operation-code
522 'INCX 'address-transfer "increase X" 55 0
523 "Increase register X with the literal value of M.
524 On overflow the overflow toggle is set."
527 (mixal-add-operation-code
528 'INC1 'address-transfer "increase I1" (+ 48 1) 0
529 "Increase register I1 with the literal value of M.
530 The result is undefined when the result does not fit in
531 2 bytes."
534 (mixal-add-operation-code
535 'INC2 'address-transfer "increase I2" (+ 48 2) 0
536 "Increase register I2 with the literal value of M.
537 The result is undefined when the result does not fit in
538 2 bytes."
541 (mixal-add-operation-code
542 'INC3 'address-transfer "increase I3" (+ 48 3) 0
543 "Increase register I3 with the literal value of M.
544 The result is undefined when the result does not fit in
545 2 bytes."
548 (mixal-add-operation-code
549 'INC4 'address-transfer "increase I4" (+ 48 4) 0
550 "Increase register I4 with the literal value of M.
551 The result is undefined when the result does not fit in
552 2 bytes."
555 (mixal-add-operation-code
556 'INC5 'address-transfer "increase I5" (+ 48 5) 0
557 "Increase register I5 with the literal value of M.
558 The result is undefined when the result does not fit in
559 2 bytes."
562 (mixal-add-operation-code
563 'INC6 'address-transfer "increase I6" (+ 48 6) 0
564 "Increase register I6 with the literal value of M.
565 The result is undefined when the result does not fit in
566 2 bytes."
569 (mixal-add-operation-code
570 'DECA 'address-transfer "decrease A" 48 1
571 "Decrease register A with the literal value of M.
572 On overflow the overflow toggle is set."
575 (mixal-add-operation-code
576 'DECX 'address-transfer "decrease X" 55 1
577 "Decrease register X with the literal value of M.
578 On overflow the overflow toggle is set."
581 (mixal-add-operation-code
582 'DEC1 'address-transfer "decrease I1" (+ 48 1) 1
583 "Decrease register I1 with the literal value of M.
584 The result is undefined when the result does not fit in
585 2 bytes."
588 (mixal-add-operation-code
589 'DEC2 'address-transfer "decrease I2" (+ 48 2) 1
590 "Decrease register I2 with the literal value of M.
591 The result is undefined when the result does not fit in
592 2 bytes."
595 (mixal-add-operation-code
596 'DEC3 'address-transfer "decrease I3" (+ 48 3) 1
597 "Decrease register I3 with the literal value of M.
598 The result is undefined when the result does not fit in
599 2 bytes."
602 (mixal-add-operation-code
603 'DEC4 'address-transfer "decrease I4" (+ 48 4) 1
604 "Decrease register I4 with the literal value of M.
605 The result is undefined when the result does not fit in
606 2 bytes."
609 (mixal-add-operation-code
610 'DEC5 'address-transfer "decrease I5" (+ 48 5) 1
611 "Decrease register I5 with the literal value of M.
612 The result is undefined when the result does not fit in
613 2 bytes."
616 (mixal-add-operation-code
617 'DEC6 'address-transfer "decrease I6" (+ 48 6) 1
618 "Decrease register I6 with the literal value of M.
619 The result is undefined when the result does not fit in
620 2 bytes."
623 (mixal-add-operation-code
624 'CMPA 'comparison "compare A" 56 'field
625 "Compare contents of A with contents of M.
626 The field specifier works on both fields. The comparison indicator
627 is set to LESS, EQUAL or GREATER depending on the outcome."
631 (mixal-add-operation-code
632 'CMPX 'comparison "compare X" 63 'field
633 "Compare contents of rX with contents of M.
634 The field specifier works on both fields. The comparison indicator
635 is set to LESS, EQUAL or GREATER depending on the outcome."
639 (mixal-add-operation-code
640 'CMP1 'comparison "compare I1" (+ 56 1) 'field
641 "Compare contents of rI1 with contents of M.
642 The field specifier works on both fields. The comparison indicator
643 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
644 have a value of 0."
648 (mixal-add-operation-code
649 'CMP2 'comparison "compare I2" (+ 56 2) 'field
650 "Compare contents of rI2 with contents of M.
651 The field specifier works on both fields. The comparison indicator
652 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
653 have a value of 0."
657 (mixal-add-operation-code
658 'CMP3 'comparison "compare I3" (+ 56 3) 'field
659 "Compare contents of rI3 with contents of M.
660 The field specifier works on both fields. The comparison indicator
661 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
662 have a value of 0."
666 (mixal-add-operation-code
667 'CMP4 'comparison "compare I4" (+ 56 4) 'field
668 "Compare contents of rI4 with contents of M.
669 The field specifier works on both fields. The comparison indicator
670 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
671 have a value of 0."
675 (mixal-add-operation-code
676 'CMP5 'comparison "compare I5" (+ 56 5) 'field
677 "Compare contents of rI5 with contents of M.
678 The field specifier works on both fields. The comparison indicator
679 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
680 have a value of 0."
684 (mixal-add-operation-code
685 'CMP6 'comparison "compare I6" (+ 56 6) 'field
686 "Compare contents of rI6 with contents of M.
687 The field specifier works on both fields. The comparison indicator
688 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
689 have a value of 0."
692 (mixal-add-operation-code
693 'JMP 'jump "jump" 39 0
694 "Unconditional jump.
695 Register J is set to the value of the next instruction that would have
696 been executed when there was no jump."
699 (mixal-add-operation-code
700 'JSJ 'jump "jump, save J" 39 1
701 "Unconditional jump, but rJ is not modified."
704 (mixal-add-operation-code
705 'JOV 'jump "jump on overflow" 39 2
706 "Jump if OV is set (and turn it off).
707 Register J is set to the value of the next instruction that would have
708 been executed when there was no jump."
711 (mixal-add-operation-code
712 'JNOV 'jump "Jump on no overflow" 39 3
713 "Jump if OV is not set (and turn it off).
714 Register J is set to the value of the next instruction that would have
715 been executed when there was no jump."
718 (mixal-add-operation-code
719 'JL 'jump "Jump on less" 39 4
720 "Jump if '[CM] = L'.
721 Register J is set to the value of the next instruction that would have
722 been executed when there was no jump."
726 (mixal-add-operation-code
727 'JE 'jump "Jump on equal" 39 5
728 "Jump if '[CM] = E'.
729 Register J is set to the value of the next instruction that would have
730 been executed when there was no jump."
734 (mixal-add-operation-code
735 'JG 'jump "Jump on greater" 39 6
736 "Jump if '[CM] = G'.
737 Register J is set to the value of the next instruction that would have
738 been executed when there was no jump."
742 (mixal-add-operation-code
743 'JGE 'jump "Jump on not less" 39 7
744 "Jump if '[CM]' does not equal 'L'.
745 Register J is set to the value of the next instruction that would have
746 been executed when there was no jump."
750 (mixal-add-operation-code
751 'JNE 'jump "Jump on not equal" 39 8
752 "Jump if '[CM]' does not equal 'E'.
753 Register J is set to the value of the next instruction that would have
754 been executed when there was no jump."
758 (mixal-add-operation-code
759 'JLE 'jump "Jump on not greater" 39 9
760 "Jump if '[CM]' does not equal 'G'.
761 Register J is set to the value of the next instruction that would have
762 been executed when there was no jump."
765 (mixal-add-operation-code
766 'JAN 'jump "jump A negative" 40 0
767 "Jump if the content of rA is negative.
768 Register J is set to the value of the next instruction that would have
769 been executed when there was no jump."
773 (mixal-add-operation-code
774 'JAZ 'jump "jump A zero" 40 1
775 "Jump if the content of rA is zero.
776 Register J is set to the value of the next instruction that would have
777 been executed when there was no jump."
781 (mixal-add-operation-code
782 'JAP 'jump "jump A positive" 40 2
783 "Jump if the content of rA is positive.
784 Register J is set to the value of the next instruction that would have
785 been executed when there was no jump."
789 (mixal-add-operation-code
790 'JANN 'jump "jump A non-negative" 40 3
791 "Jump if the content of rA is non-negative.
792 Register J is set to the value of the next instruction that would have
793 been executed when there was no jump."
797 (mixal-add-operation-code
798 'JANZ 'jump "jump A non-zero" 40 4
799 "Jump if the content of rA is non-zero.
800 Register J is set to the value of the next instruction that would have
801 been executed when there was no jump."
805 (mixal-add-operation-code
806 'JANP 'jump "jump A non-positive" 40 5
807 "Jump if the content of rA is non-positive.
808 Register J is set to the value of the next instruction that would have
809 been executed when there was no jump."
812 (mixal-add-operation-code
813 'JXN 'jump "jump X negative" 47 0
814 "Jump if the content of rX is negative.
815 Register J is set to the value of the next instruction that would have
816 been executed when there was no jump."
820 (mixal-add-operation-code
821 'JXZ 'jump "jump X zero" 47 1
822 "Jump if the content of rX is zero.
823 Register J is set to the value of the next instruction that would have
824 been executed when there was no jump."
828 (mixal-add-operation-code
829 'JXP 'jump "jump X positive" 47 2
830 "Jump if the content of rX is positive.
831 Register J is set to the value of the next instruction that would have
832 been executed when there was no jump."
836 (mixal-add-operation-code
837 'JXNN 'jump "jump X non-negative" 47 3
838 "Jump if the content of rX is non-negative.
839 Register J is set to the value of the next instruction that would have
840 been executed when there was no jump."
844 (mixal-add-operation-code
845 'JXNZ 'jump "jump X non-zero" 47 4
846 "Jump if the content of rX is non-zero.
847 Register J is set to the value of the next instruction that would have
848 been executed when there was no jump."
852 (mixal-add-operation-code
853 'JXNP 'jump "jump X non-positive" 47 5
854 "Jump if the content of rX is non-positive.
855 Register J is set to the value of the next instruction that would have
856 been executed when there was no jump."
859 (mixal-add-operation-code
860 'J1N 'jump "jump I1 negative" (+ 40 1) 0
861 "Jump if the content of rI1 is negative.
862 Register J is set to the value of the next instruction that would have
863 been executed when there was no jump."
867 (mixal-add-operation-code
868 'J1Z 'jump "jump I1 zero" (+ 40 1) 1
869 "Jump if the content of rI1 is zero.
870 Register J is set to the value of the next instruction that would have
871 been executed when there was no jump."
875 (mixal-add-operation-code
876 'J1P 'jump "jump I1 positive" (+ 40 1) 2
877 "Jump if the content of rI1 is positive.
878 Register J is set to the value of the next instruction that would have
879 been executed when there was no jump."
883 (mixal-add-operation-code
884 'J1NN 'jump "jump I1 non-negative" (+ 40 1) 3
885 "Jump if the content of rI1 is non-negative.
886 Register J is set to the value of the next instruction that would have
887 been executed when there was no jump."
891 (mixal-add-operation-code
892 'J1NZ 'jump "jump I1 non-zero" (+ 40 1) 4
893 "Jump if the content of rI1 is non-zero.
894 Register J is set to the value of the next instruction that would have
895 been executed when there was no jump."
899 (mixal-add-operation-code
900 'J1NP 'jump "jump I1 non-positive" (+ 40 1) 5
901 "Jump if the content of rI1 is non-positive.
902 Register J is set to the value of the next instruction that would have
903 been executed when there was no jump."
906 (mixal-add-operation-code
907 'J2N 'jump "jump I2 negative" (+ 40 1) 0
908 "Jump if the content of rI2 is negative.
909 Register J is set to the value of the next instruction that would have
910 been executed when there was no jump."
914 (mixal-add-operation-code
915 'J2Z 'jump "jump I2 zero" (+ 40 1) 1
916 "Jump if the content of rI2 is zero.
917 Register J is set to the value of the next instruction that would have
918 been executed when there was no jump."
922 (mixal-add-operation-code
923 'J2P 'jump "jump I2 positive" (+ 40 1) 2
924 "Jump if the content of rI2 is positive.
925 Register J is set to the value of the next instruction that would have
926 been executed when there was no jump."
930 (mixal-add-operation-code
931 'J2NN 'jump "jump I2 non-negative" (+ 40 1) 3
932 "Jump if the content of rI2 is non-negative.
933 Register J is set to the value of the next instruction that would have
934 been executed when there was no jump."
938 (mixal-add-operation-code
939 'J2NZ 'jump "jump I2 non-zero" (+ 40 1) 4
940 "Jump if the content of rI2 is non-zero.
941 Register J is set to the value of the next instruction that would have
942 been executed when there was no jump."
946 (mixal-add-operation-code
947 'J2NP 'jump "jump I2 non-positive" (+ 40 1) 5
948 "Jump if the content of rI2 is non-positive.
949 Register J is set to the value of the next instruction that would have
950 been executed when there was no jump."
954 (mixal-add-operation-code
955 'J3N 'jump "jump I3 negative" (+ 40 1) 0
956 "Jump if the content of rI3 is negative.
957 Register J is set to the value of the next instruction that would have
958 been executed when there was no jump."
962 (mixal-add-operation-code
963 'J3Z 'jump "jump I3 zero" (+ 40 1) 1
964 "Jump if the content of rI3 is zero.
965 Register J is set to the value of the next instruction that would have
966 been executed when there was no jump."
970 (mixal-add-operation-code
971 'J3P 'jump "jump I3 positive" (+ 40 1) 2
972 "Jump if the content of rI3 is positive.
973 Register J is set to the value of the next instruction that would have
974 been executed when there was no jump."
978 (mixal-add-operation-code
979 'J3NN 'jump "jump I3 non-negative" (+ 40 1) 3
980 "Jump if the content of rI3 is non-negative.
981 Register J is set to the value of the next instruction that would have
982 been executed when there was no jump."
986 (mixal-add-operation-code
987 'J3NZ 'jump "jump I3 non-zero" (+ 40 1) 4
988 "Jump if the content of rI3 is non-zero.
989 Register J is set to the value of the next instruction that would have
990 been executed when there was no jump."
994 (mixal-add-operation-code
995 'J3NP 'jump "jump I3 non-positive" (+ 40 1) 5
996 "Jump if the content of rI3 is non-positive.
997 Register J is set to the value of the next instruction that would have
998 been executed when there was no jump."
1002 (mixal-add-operation-code
1003 'J4N 'jump "jump I4 negative" (+ 40 1) 0
1004 "Jump if the content of rI4 is negative.
1005 Register J is set to the value of the next instruction that would have
1006 been executed when there was no jump."
1010 (mixal-add-operation-code
1011 'J4Z 'jump "jump I4 zero" (+ 40 1) 1
1012 "Jump if the content of rI4 is zero.
1013 Register J is set to the value of the next instruction that would have
1014 been executed when there was no jump."
1018 (mixal-add-operation-code
1019 'J4P 'jump "jump I4 positive" (+ 40 1) 2
1020 "Jump if the content of rI4 is positive.
1021 Register J is set to the value of the next instruction that would have
1022 been executed when there was no jump."
1026 (mixal-add-operation-code
1027 'J4NN 'jump "jump I4 non-negative" (+ 40 1) 3
1028 "Jump if the content of rI4 is non-negative.
1029 Register J is set to the value of the next instruction that would have
1030 been executed when there was no jump."
1034 (mixal-add-operation-code
1035 'J4NZ 'jump "jump I4 non-zero" (+ 40 1) 4
1036 "Jump if the content of rI4 is non-zero.
1037 Register J is set to the value of the next instruction that would have
1038 been executed when there was no jump."
1042 (mixal-add-operation-code
1043 'J4NP 'jump "jump I4 non-positive" (+ 40 1) 5
1044 "Jump if the content of rI4 is non-positive.
1045 Register J is set to the value of the next instruction that would have
1046 been executed when there was no jump."
1050 (mixal-add-operation-code
1051 'J5N 'jump "jump I5 negative" (+ 40 1) 0
1052 "Jump if the content of rI5 is negative.
1053 Register J is set to the value of the next instruction that would have
1054 been executed when there was no jump."
1058 (mixal-add-operation-code
1059 'J5Z 'jump "jump I5 zero" (+ 40 1) 1
1060 "Jump if the content of rI5 is zero.
1061 Register J is set to the value of the next instruction that would have
1062 been executed when there was no jump."
1066 (mixal-add-operation-code
1067 'J5P 'jump "jump I5 positive" (+ 40 1) 2
1068 "Jump if the content of rI5 is positive.
1069 Register J is set to the value of the next instruction that would have
1070 been executed when there was no jump."
1074 (mixal-add-operation-code
1075 'J5NN 'jump "jump I5 non-negative" (+ 40 1) 3
1076 "Jump if the content of rI5 is non-negative.
1077 Register J is set to the value of the next instruction that would have
1078 been executed when there was no jump."
1082 (mixal-add-operation-code
1083 'J5NZ 'jump "jump I5 non-zero" (+ 40 1) 4
1084 "Jump if the content of rI5 is non-zero.
1085 Register J is set to the value of the next instruction that would have
1086 been executed when there was no jump."
1090 (mixal-add-operation-code
1091 'J5NP 'jump "jump I5 non-positive" (+ 40 1) 5
1092 "Jump if the content of rI5 is non-positive.
1093 Register J is set to the value of the next instruction that would have
1094 been executed when there was no jump."
1098 (mixal-add-operation-code
1099 'J6N 'jump "jump I6 negative" (+ 40 1) 0
1100 "Jump if the content of rI6 is negative.
1101 Register J is set to the value of the next instruction that would have
1102 been executed when there was no jump."
1106 (mixal-add-operation-code
1107 'J6Z 'jump "jump I6 zero" (+ 40 1) 1
1108 "Jump if the content of rI6 is zero.
1109 Register J is set to the value of the next instruction that would have
1110 been executed when there was no jump."
1114 (mixal-add-operation-code
1115 'J6P 'jump "jump I6 positive" (+ 40 1) 2
1116 "Jump if the content of rI6 is positive.
1117 Register J is set to the value of the next instruction that would have
1118 been executed when there was no jump."
1122 (mixal-add-operation-code
1123 'J6NN 'jump "jump I6 non-negative" (+ 40 1) 3
1124 "Jump if the content of rI6 is non-negative.
1125 Register J is set to the value of the next instruction that would have
1126 been executed when there was no jump."
1130 (mixal-add-operation-code
1131 'J6NZ 'jump "jump I6 non-zero" (+ 40 1) 4
1132 "Jump if the content of rI6 is non-zero.
1133 Register J is set to the value of the next instruction that would have
1134 been executed when there was no jump."
1138 (mixal-add-operation-code
1139 'J6NP 'jump "jump I6 non-positive" (+ 40 1) 5
1140 "Jump if the content of rI6 is non-positive.
1141 Register J is set to the value of the next instruction that would have
1142 been executed when there was no jump."
1145 (mixal-add-operation-code
1146 'SLA 'miscellaneous "shift left A" 6 0
1147 "Shift to A, M bytes left.
1148 Hero's will be added to the right."
1152 (mixal-add-operation-code
1153 'SRA 'miscellaneous "shift right A" 6 1
1154 "Shift to A, M bytes right.
1155 Zeros will be added to the left."
1159 (mixal-add-operation-code
1160 'SLAX 'miscellaneous "shift left AX" 6 2
1161 "Shift AX, M bytes left.
1162 Zeros will be added to the right."
1167 (mixal-add-operation-code
1168 'SRAX 'miscellaneous "shift right AX" 6 3
1169 "Shift AX, M bytes right.
1170 Zeros will be added to the left."
1174 (mixal-add-operation-code
1175 'SLC 'miscellaneous "shift left AX circularly" 6 4
1176 "Shift AX, M bytes left circularly.
1177 The bytes that fall off to the left will be added to the right."
1181 (mixal-add-operation-code
1182 'SRC 'miscellaneous "shift right AX circularly" 6 4
1183 "Shift AX, M bytes right circularly.
1184 The bytes that fall off to the right will be added to the left."
1187 (mixal-add-operation-code
1188 'MOVE 'miscellaneous "move" 7 'number
1189 "Move MOD words from M to the location stored in rI1."
1190 '(+ 1 (* 2 number)))
1192 (mixal-add-operation-code
1193 'NOP 'miscellaneous "no operation" 0 'ignored
1194 "No operation, M and F are not used by the machine."
1197 (mixal-add-operation-code
1198 'HLT 'miscellaneous "halt" 5 2
1199 "Halt.
1200 Stop instruction fetching."
1203 (mixal-add-operation-code
1204 'IN 'input-output "input" 36 'unit
1205 "Transfer a block of words from the specified unit to memory.
1206 The transfer starts at address M."
1209 (mixal-add-operation-code
1210 'OUT 'input-output "output" 37 'unit
1211 "Transfer a block of words from memory.
1212 The transfer starts at address M to the specified unit."
1215 (mixal-add-operation-code
1216 'IOC 'input-output "input-output control" 35 'unit
1217 "Perform a control operation.
1218 The control operation is given by M on the specified unit."
1221 (mixal-add-operation-code
1222 'JRED 'input-output "jump ready" 38 'unit
1223 "Jump to M if the specified unit is ready."
1227 (mixal-add-operation-code
1228 'JBUS 'input-output "jump busy" 34 'unit
1229 "Jump to M if the specified unit is busy."
1232 (mixal-add-operation-code
1233 'NUM 'conversion "convert to numeric" 5 0
1234 "Convert rAX to its numerical value and store it in rA.
1235 the register rAX is assumed to contain a character representation of
1236 a number."
1239 (mixal-add-operation-code
1240 'CHAR 'conversion "convert to characters" 5 1
1241 "Convert the number stored in rA to a character representation.
1242 The converted character representation is stored in rAX."
1245 (defvar mixal-describe-operation-code-history nil
1246 "History list for describe operation code.")
1248 (defun mixal-describe-operation-code (&optional op-code)
1249 "Display the full documentation of OP-CODE."
1250 (interactive)
1251 ;; we like to provide completition and history, so do it ourself (interactive "?bla")?
1252 (unless op-code
1253 (let* ((completion-ignore-case t)
1254 ;; we already have a list, but it is not in the right format
1255 ;; transform it to a valid table so completition can use it
1256 (table (mapcar '(lambda (elm)
1257 (cons (symbol-name (car elm)) nil))
1258 mixal-operation-codes-alist))
1259 ;; prompt is different depending on we are close to a valid op-code
1260 (have-default (member (current-word) mixal-operation-codes))
1261 (prompt (concat "Describe operation code "
1262 (if have-default
1263 (concat "(default " (current-word) "): ")
1264 ": "))))
1265 ;; as the operation code to the user
1266 (setq op-code (completing-read prompt table nil t nil
1267 'mixal-describe-operation-code-history
1268 (current-word)))))
1269 ;; get the info on the op-code and output it to the help buffer
1270 (let ((op-code-help (assq (intern-soft op-code) mixal-operation-codes-alist)))
1271 (when op-code-help
1272 (with-output-to-temp-buffer (buffer-name (get-buffer-create "*Help*"))
1273 (princ op-code) (princ " is an mix operation code\n\n")
1274 (princ (nth 5 op-code-help)) (terpri) (terpri)
1275 (princ " group: ") (princ (nth 1 op-code-help)) (terpri)
1276 (princ " nice name: ") (princ (nth 2 op-code-help)) (terpri)
1277 (princ " OPCODE / C: ") (princ (nth 3 op-code-help)) (terpri)
1278 (princ " MOD / F: ") (princ (nth 4 op-code-help)) (terpri)
1279 (princ " time: ") (princ (nth 6 op-code-help)) (terpri)))))
1281 ;;;; Running
1282 (defun mixal-run ()
1283 "Run's mixal file in current buffer, assumes that file has been compiled"
1284 (interactive)
1285 (mixvm (concat "mixvm -r -t -d "
1286 (file-name-sans-extension (buffer-file-name)))))
1288 (defun mixal-debug ()
1289 "Starts mixvm for debugging, assumes that file has been compiled with debugging support"
1290 (interactive)
1291 (mixvm (concat "mixvm "
1292 (file-name-sans-extension (buffer-file-name)))))
1294 ;;;###autoload
1295 (define-derived-mode mixal-mode fundamental-mode "mixal"
1296 "Major mode for the mixal asm language.
1297 \\{mixal-mode-map}"
1298 (set (make-local-variable 'comment-start) "*")
1299 (set (make-local-variable 'comment-start-skip) "*")
1300 (set (make-local-variable 'font-lock-defaults) '(mixal-font-lock-keywords))
1301 ; might add an indent function in the future
1302 ; (set (make-local-variable 'indent-line-function) 'mixal-indent-line)
1303 (set (make-local-variable 'compile-command) (concat "mixasm -g "
1304 buffer-file-name))
1305 ;; mixasm will do strange when there is no final newline,
1306 ;; let emacs ensure that it is always there
1307 (set (make-local-variable 'require-final-newline) t))
1309 ;;;###autoload
1310 (add-to-list 'auto-mode-alist '("\\.mixal\\'" . mixal-mode))
1312 (provide 'mixal-mode)
1314 ;;; arch-tag: be7c128a-bf61-4951-a90e-9398267ce3f3
1315 ;;; mixal-mode.el ends here