88155
|
1 ;;; mixal-mode.el --- Major mode for the mix asm language.
|
|
2
|
|
3 ;; Copyright (C) 2003, 2004, 2005 Free Software Foundation
|
|
4
|
|
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.
|
|
9
|
|
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.
|
|
14
|
|
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., 51 Franklin Street, Fifth Floor, Boston,
|
|
18 ;; MA 02110-1301 USA
|
|
19
|
|
20 ;; Author: Pieter E.J. Pareit <pieter.pareit@gmail.com>
|
|
21 ;; Maintainer: Pieter E.J. Pareit <pieter.pareit@gmail.com>
|
|
22 ;; Created: 09 Nov 2002
|
|
23 ;; Version: 0.1
|
|
24 ;; Keywords: Knuth mix mixal asm mixvm "The Art Of Computer Programming"
|
|
25
|
|
26 ;;; Commentary:
|
|
27 ;; Major mode for the mix asm language.
|
|
28 ;; The mix asm language is described in "The Art Of Computer Programming".
|
|
29 ;;
|
|
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'.
|
|
34 ;;
|
|
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's
|
|
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'.
|
|
44 ;;
|
|
45 ;; Have fun.
|
|
46
|
|
47 ;;; History:
|
|
48 ;; Version 0.3:
|
|
49 ;; 12/10/05: Stefan Monnier <monnier@iro.umontreal.ca>
|
|
50 ;; Use font-lock-syntactic-keywords to detect/mark comments.
|
|
51 ;; Use [^ \t\n]+ to match the operand part of a line.
|
|
52 ;; Drop mixal-operation-codes.
|
|
53 ;; Build the mixal-operation-codes-alist immediately.
|
|
54 ;; Use `interactive' in mixal-describe-operation-code.
|
|
55 ;; Remove useless ".*$" at the end of some regexps.
|
|
56 ;; Fix the definition of comment-start-skip.
|
|
57 ;; 08/10/05: sync mdk and emacs cvs
|
|
58 ;; from emacs: compile-command and require-final-newline
|
|
59 ;; from mdk: see version 0.2
|
|
60 ;; correct my email address
|
|
61 ;; Version 0.2:
|
|
62 ;; 06/04/05: mixasm no longer needs -g option
|
|
63 ;; fontlocking of comments works in all? cases now
|
|
64 ;; added some more mixal-operation-codes
|
|
65 ;; Version 0.1:
|
|
66 ;; Version 0.1.1:
|
|
67 ;; 22/11/02: bugfix in fontlocking, needed to add a '-' to the regex.
|
|
68 ;; 19/11/02: completed implementing mixal-describe-operation-code.
|
|
69 ;; 13/11/02: implemented compile, mixal-run and mixal-debug.
|
|
70 ;; 10/11/02: implemented font-locking and syntax table.
|
|
71 ;; 09/11/02: started mixal-mode.
|
|
72
|
|
73 ;;; Code:
|
|
74 (defvar compile-command)
|
|
75
|
|
76 ;;; Key map
|
|
77 (defvar mixal-mode-map
|
|
78 (let ((map (make-sparse-keymap)))
|
|
79 (define-key map "\C-cc" 'compile)
|
|
80 (define-key map "\C-cr" 'mixal-run)
|
|
81 (define-key map "\C-cd" 'mixal-debug)
|
|
82 (define-key map "\C-ho" 'mixal-describe-operation-code)
|
|
83 map)
|
|
84 "Keymap for `mixal-mode'.")
|
|
85 ;; (makunbound 'mixal-mode-map)
|
|
86
|
|
87 ;;; Syntax table
|
|
88 (defvar mixal-mode-syntax-table
|
|
89 (let ((st (make-syntax-table)))
|
|
90 ;; We need to do a bit more to make fontlocking for comments work.
|
|
91 ;; See mixal-font-lock-syntactic-keywords.
|
|
92 ;; (modify-syntax-entry ?* "<" st)
|
|
93 (modify-syntax-entry ?\n ">" st)
|
|
94 st)
|
|
95 "Syntax table for `mixal-mode'.")
|
|
96
|
|
97 (defvar mixal-font-lock-label-face 'font-lock-variable-name-face
|
|
98 "Face name to use for label names.
|
|
99 Default value is that of `font-lock-variable-name-face', but you can modify
|
|
100 its value.")
|
|
101
|
|
102 (defvar mixal-font-lock-operation-code-face 'font-lock-keyword-face
|
|
103 "Face name to use for operation code names.
|
|
104 Default value is that of `font-lock-keyword-face', but you can modify its
|
|
105 value.")
|
|
106
|
|
107 (defvar mixal-font-lock-assembly-pseudoinstruction-face 'font-lock-builtin-face
|
|
108 "Face name to use for assembly pseudoinstruction names.
|
|
109 Default value is that of `font-lock-builtin-face', but you can modify its
|
|
110 value.")
|
|
111
|
|
112 (defvar mixal-assembly-pseudoinstructions
|
|
113 '("ORIG" "EQU" "CON" "ALF" "END")
|
|
114 "List of possible assembly pseudoinstructions.")
|
|
115
|
|
116 ;;;; Compilation
|
|
117 ;; Output from mixasm is compatible with default behavior of emacs,
|
|
118 ;; I just added a key (C-cc) and modified the make-command.
|
|
119
|
|
120 ;;;; Indentation
|
|
121 ;; Tabs works well by default.
|
|
122
|
|
123 ;;;; Describe
|
|
124 (defvar mixal-operation-codes-alist
|
|
125 ;; FIXME: the codes FADD, FSUB, FMUL, FDIV, JRAD, and FCMP were in
|
|
126 ;; mixal-operation-codes but not here. They should probably be added here.
|
|
127 ;;
|
|
128 ;; We used to define this with a backquote and subexps like ,(+ 8 3) for
|
|
129 ;; better clarity, but the resulting code was too big and caused the
|
|
130 ;; byte-compiler to eat up all the stack space. Even using
|
|
131 ;; `eval-when-compile' didn't help because the byte-compiler insists on
|
|
132 ;; compiling the code before evaluating it.
|
|
133 '((LDA loading "load A" 8 field
|
|
134 "Put in rA the contents of cell no. M.
|
|
135 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
136 zeros to make a word."
|
|
137 2)
|
|
138
|
|
139 (LDX loading "load X" 15 field
|
|
140 "Put in rX the contents of cell no. M.
|
|
141 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
142 zeros to make a word."
|
|
143 2)
|
|
144
|
|
145 (LD1 loading "load I1" 9 field
|
|
146 "Put in rI1 the contents of cell no. M.
|
|
147 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
148 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
|
|
149 to set anything more that that will result in undefined behavior."
|
|
150 2)
|
|
151
|
|
152 (LD2 loading "load I2" 10 field
|
|
153 "Put in rI2 the contents of cell no. M.
|
|
154 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
155 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
|
|
156 to set anything more that that will result in undefined behavior."
|
|
157 2)
|
|
158
|
|
159 (LD3 loading "load I3" 11 field
|
|
160 "Put in rI3 the contents of cell no. M.
|
|
161 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
162 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
|
|
163 to set anything more that that will result in undefined behavior."
|
|
164 2)
|
|
165
|
|
166 (LD4 loading "load I4" 12 field
|
|
167 "Put in rI4 the contents of cell no. M.
|
|
168 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
169 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
|
|
170 to set anything more that that will result in undefined behavior."
|
|
171 2)
|
|
172
|
|
173 (LD5 loading "load I5" 13 field
|
|
174 "Put in rI5 the contents of cell no. M.
|
|
175 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
176 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
|
|
177 to set anything more that that will result in undefined behavior."
|
|
178 2)
|
|
179
|
|
180 (LD6 loading "load I6" 14 field
|
|
181 "Put in rI6 the contents of cell no. M.
|
|
182 Uses a + when there is no sign in subfield. Subfield is left padded with
|
|
183 zeros to make a word. Index registers only have 2 bytes and a sign, Trying
|
|
184 to set anything more that that will result in undefined behavior."
|
|
185 2)
|
|
186
|
|
187 (LDAN loading "load A negative" 16 field
|
|
188 "Put in rA the contents of cell no. M, with opposite sign.
|
|
189 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
190 Subfield is left padded with zeros to make a word."
|
|
191 2)
|
|
192
|
|
193 (LDXN loading "load X negative" 23 field
|
|
194 "Put in rX the contents of cell no. M, with opposite sign.
|
|
195 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
196 Subfield is left padded with zeros to make a word."
|
|
197 2)
|
|
198
|
|
199 (LD1N loading "load I1 negative" 17 field
|
|
200 "Put in rI1 the contents of cell no. M, with opposite sign.
|
|
201 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
202 Subfield is left padded with zeros to make a word. Index registers only
|
|
203 have 2 bytes and a sign, Trying to set anything more that that will result
|
|
204 in undefined behavior."
|
|
205 2)
|
|
206
|
|
207 (LD2N loading "load I2 negative" 18 field
|
|
208 "Put in rI2 the contents of cell no. M, with opposite sign.
|
|
209 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
210 Subfield is left padded with zeros to make a word. Index registers only
|
|
211 have 2 bytes and a sign, Trying to set anything more that that will result
|
|
212 in undefined behavior."
|
|
213 2)
|
|
214
|
|
215 (LD3N loading "load I3 negative" 19 field
|
|
216 "Put in rI3 the contents of cell no. M, with opposite sign.
|
|
217 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
218 Subfield is left padded with zeros to make a word. Index registers only
|
|
219 have 2 bytes and a sign, Trying to set anything more that that will result
|
|
220 in undefined behavior."
|
|
221 2)
|
|
222
|
|
223 (LD4N loading "load I4 negative" 20 field
|
|
224 "Put in rI4 the contents of cell no. M, with opposite sign.
|
|
225 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
226 Subfield is left padded with zeros to make a word. Index registers only
|
|
227 have 2 bytes and a sign, Trying to set anything more that that will result
|
|
228 in undefined behavior."
|
|
229 2)
|
|
230
|
|
231 (LD5N loading "load I5 negative" 21 field
|
|
232 "Put in rI5 the contents of cell no. M, with opposite sign.
|
|
233 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
234 Subfield is left padded with zeros to make a word. Index registers only
|
|
235 have 2 bytes and a sign, Trying to set anything more that that will result
|
|
236 in undefined behavior."
|
|
237 2)
|
|
238
|
|
239 (LD6N loading "load I6 negative" 22 field
|
|
240 "Put in rI6 the contents of cell no. M, with opposite sign.
|
|
241 Uses a + when there is no sign in subfield, otherwise use the opposite sign.
|
|
242 Subfield is left padded with zeros to make a word. Index registers only
|
|
243 have 2 bytes and a sign, Trying to set anything more that that will result
|
|
244 in undefined behavior."
|
|
245 2)
|
|
246
|
|
247 (STA storing "store A" 24 field
|
|
248 "Store in cell Nr. M the contents of rA.
|
|
249 The modification of the operation code represents the subfield of the
|
|
250 memory cell that is to be overwritten with bytes from a register. These
|
|
251 bytes are taken beginning by the rightmost side of the register. The
|
|
252 sign of the memory cell is not changed, unless it is part of the subfield."
|
|
253 2)
|
|
254
|
|
255 (STX storing "store X" 31 field
|
|
256 "Store in cell Nr. M the contents of rX.
|
|
257 The modification of the operation code represents the subfield of the
|
|
258 memory cell that is to be overwritten with bytes from a register. These
|
|
259 bytes are taken beginning by the rightmost side of the register. The
|
|
260 sign of the memory cell is not changed, unless it is part of the subfield."
|
|
261 2)
|
|
262
|
|
263 (ST1 storing "store I1" 25 field
|
|
264 "Store in cell Nr. M the contents of rI1.
|
|
265 The modification of the operation code represents the subfield of the
|
|
266 memory cell that is to be overwritten with bytes from a register. These
|
|
267 bytes are taken beginning by the rightmost side of the register. The
|
|
268 sign of the memory cell is not changed, unless it is part of the subfield.
|
|
269 Because index registers only have 2 bytes and a sign, the rest of the bytes
|
|
270 are assumed to be 0."
|
|
271 2)
|
|
272
|
|
273 (ST2 storing "store I2" 26 field
|
|
274 "Store in cell Nr. M the contents of rI2.
|
|
275 The modification of the operation code represents the subfield of the
|
|
276 memory cell that is to be overwritten with bytes from a register. These
|
|
277 bytes are taken beginning by the rightmost side of the register. The
|
|
278 sign of the memory cell is not changed, unless it is part of the subfield.
|
|
279 Because index registers only have 2 bytes and a sign, the rest of the bytes
|
|
280 are assumed to be 0."
|
|
281 2)
|
|
282
|
|
283 (ST3 storing "store I3" 27 field
|
|
284 "Store in cell Nr. M the contents of rI3.
|
|
285 The modification of the operation code represents the subfield of the
|
|
286 memory cell that is to be overwritten with bytes from a register. These
|
|
287 bytes are taken beginning by the rightmost side of the register. The
|
|
288 sign of the memory cell is not changed, unless it is part of the subfield.
|
|
289 Because index registers only have 2 bytes and a sign, the rest of the bytes
|
|
290 are assumed to be 0."
|
|
291 2)
|
|
292
|
|
293 (ST4 storing "store I4" 28 field
|
|
294 "Store in cell Nr. M the contents of rI4.
|
|
295 The modification of the operation code represents the subfield of the
|
|
296 memory cell that is to be overwritten with bytes from a register. These
|
|
297 bytes are taken beginning by the rightmost side of the register. The
|
|
298 sign of the memory cell is not changed, unless it is part of the subfield.
|
|
299 Because index registers only have 2 bytes and a sign, the rest of the bytes
|
|
300 are assumed to be 0."
|
|
301 2)
|
|
302
|
|
303 (ST5 storing "store I5" 29 field
|
|
304 "Store in cell Nr. M the contents of rI5.
|
|
305 The modification of the operation code represents the subfield of the
|
|
306 memory cell that is to be overwritten with bytes from a register. These
|
|
307 bytes are taken beginning by the rightmost side of the register. The
|
|
308 sign of the memory cell is not changed, unless it is part of the subfield.
|
|
309 Because index registers only have 2 bytes and a sign, the rest of the bytes
|
|
310 are assumed to be 0."
|
|
311 2)
|
|
312
|
|
313 (ST6 storing "store I6" 30 field
|
|
314 "Store in cell Nr. M the contents of rI6.
|
|
315 The modification of the operation code represents the subfield of the
|
|
316 memory cell that is to be overwritten with bytes from a register. These
|
|
317 bytes are taken beginning by the rightmost side of the register. The
|
|
318 sign of the memory cell is not changed, unless it is part of the subfield.
|
|
319 Because index registers only have 2 bytes and a sign, the rest of the bytes
|
|
320 are assumed to be 0."
|
|
321 2)
|
|
322
|
|
323 (STJ storing "store J" 32 field
|
|
324 "Store in cell Nr. M the contents of rJ.
|
|
325 The modification of the operation code represents the subfield of the
|
|
326 memory cell that is to be overwritten with bytes from a register. These
|
|
327 bytes are taken beginning by the rightmost side of the register. The sign
|
|
328 of rJ is always +, sign of the memory cell is not changed, unless it is
|
|
329 part of the subfield. The default field for STJ is (0:2)."
|
|
330 2)
|
|
331
|
|
332 (STZ storing "store zero" 33 field
|
|
333 "Store in cell Nr. M '+ 0'.
|
|
334 The modification of the operation code represents the subfield of the
|
|
335 memory cell that is to be overwritten with zeros."
|
|
336 2)
|
|
337
|
|
338 (ADD arithmetic "add" 1 field
|
|
339 "Add to A the contents of cell Nr. M.
|
|
340 Subfield is padded with zero to make a word.
|
|
341 If the result is to large, the operation result modulo 1,073,741,823 (the
|
|
342 maximum value storable in a MIX word) is stored in `rA', and the overflow
|
|
343 toggle is set to TRUE."
|
|
344 2)
|
|
345
|
|
346 (SUB arithmetic "subtract" 2 field
|
|
347 "Subtract to A the contents of cell Nr. M.
|
|
348 Subfield is padded with zero to make a word.
|
|
349 If the result is to large, the operation result modulo 1,073,741,823 (the
|
|
350 maximum value storable in a MIX word) is stored in `rA', and the overflow
|
|
351 toggle is set to TRUE."
|
|
352 2)
|
|
353
|
|
354 (MUL arithmetic "multiply" 3 field
|
|
355 "Multiplies the contents of cell Nr. M with A, result is 10 bytes and stored in rA and rX.
|
|
356 The sign is + if the sign of rA and cell M where the same, otherwise, it is -"
|
|
357 10)
|
|
358
|
|
359 (DIV arithmetic "divide" 4 field
|
|
360 "Both rA and rX are taken together and divided by cell Nr. M, quotient is placed in rA, remainder in rX.
|
|
361 The sign is taken from rA, and after the divide the sign of rA is set to + when
|
|
362 both the sign of rA and M where the same. Divide by zero and overflow of rA
|
|
363 result in undefined behavior."
|
|
364 12)
|
|
365
|
|
366 (ENTA address-transfer "enter A" 48
|
|
367 "Literal value is stored in rA.
|
|
368 Indexed, stores value of index in rA."
|
|
369 1)
|
|
370
|
|
371 (ENTX address-transfer "enter X" 55
|
|
372 "Literal value is stored in rX.
|
|
373 Indexed, stores value of index in rX."
|
|
374 1)
|
|
375
|
|
376 (ENT1 address-transfer "Enter rI1" 49
|
|
377 "Literal value is stored in rI1.
|
|
378 Indexed, stores value of index in rI1."
|
|
379 1)
|
|
380
|
|
381 (ENT2 address-transfer "Enter rI2" 50
|
|
382 "Literal value is stored in rI2.
|
|
383 Indexed, stores value of index in rI2."
|
|
384 1)
|
|
385
|
|
386 (ENT3 address-transfer "Enter rI3" 51
|
|
387 "Literal value is stored in rI3.
|
|
388 Indexed, stores value of index in rI3."
|
|
389 1)
|
|
390
|
|
391 (ENT4 address-transfer "Enter rI4" 52
|
|
392 "Literal value is stored in rI4.
|
|
393 Indexed, stores value of index in rI4."
|
|
394 1)
|
|
395
|
|
396 (ENT5 address-transfer "Enter rI5" 53
|
|
397 "Literal value is stored in rI5.
|
|
398 Indexed, stores value of index in rI5."
|
|
399 1)
|
|
400
|
|
401 (ENT6 address-transfer "Enter rI6" 54
|
|
402 "Literal value is stored in rI6.
|
|
403 Indexed, stores value of index in rI6."
|
|
404 1)
|
|
405
|
|
406 (ENNA address-transfer "enter negative A" 48
|
|
407 "Literal value is stored in rA with opposite sign.
|
|
408 Indexed, stores value of index in rA with opposite sign."
|
|
409 1)
|
|
410
|
|
411 (ENNX address-transfer "enter negative X" 55
|
|
412 "Literal value is stored in rX with opposite sign.
|
|
413 Indexed, stores value of index in rX with opposite sign."
|
|
414 1)
|
|
415
|
|
416 (ENN1 address-transfer "Enter negative rI1" 49
|
|
417 "Literal value is stored in rI1 with opposite sign.
|
|
418 Indexed, stores value of index in rI1 with opposite sign."
|
|
419 1)
|
|
420
|
|
421 (ENN2 address-transfer "Enter negative rI2" 50
|
|
422 "Literal value is stored in rI2 with opposite sign.
|
|
423 Indexed, stores value of index in rI2 with opposite sign."
|
|
424 1)
|
|
425
|
|
426 (ENN3 address-transfer "Enter negative rI3" 51
|
|
427 "Literal value is stored in rI3 with opposite sign.
|
|
428 Indexed, stores value of index in rI3 with opposite sign."
|
|
429 1)
|
|
430
|
|
431 (ENN4 address-transfer "Enter negative rI4" 52
|
|
432 "Literal value is stored in rI4 with opposite sign.
|
|
433 Indexed, stores value of index in rI4 with opposite sign."
|
|
434 1)
|
|
435
|
|
436 (ENN5 address-transfer "Enter negative rI5" 53
|
|
437 "Literal value is stored in rI5 with opposite sign.
|
|
438 Indexed, stores value of index in rI5 with opposite sign."
|
|
439 1)
|
|
440
|
|
441 (ENN6 address-transfer "Enter negative rI6" 54
|
|
442 "Literal value is stored in rI6 with opposite sign.
|
|
443 Indexed, stores value of index in rI6 with opposite sign."
|
|
444 1)
|
|
445
|
|
446 (INCA address-transfer "increase A" 48
|
|
447 "Increase register A with the literal value of M.
|
|
448 On overflow the overflow toggle is set."
|
|
449 1)
|
|
450
|
|
451 (INCX address-transfer "increase X" 55
|
|
452 "Increase register X with the literal value of M.
|
|
453 On overflow the overflow toggle is set."
|
|
454 1)
|
|
455
|
|
456 (INC1 address-transfer "increase I1" 49
|
|
457 "Increase register I1 with the literal value of M.
|
|
458 The result is undefined when the result does not fit in
|
|
459 2 bytes."
|
|
460 1)
|
|
461
|
|
462 (INC2 address-transfer "increase I2" 50
|
|
463 "Increase register I2 with the literal value of M.
|
|
464 The result is undefined when the result does not fit in
|
|
465 2 bytes."
|
|
466 1)
|
|
467
|
|
468 (INC3 address-transfer "increase I3" 51
|
|
469 "Increase register I3 with the literal value of M.
|
|
470 The result is undefined when the result does not fit in
|
|
471 2 bytes."
|
|
472 1)
|
|
473
|
|
474 (INC4 address-transfer "increase I4" 52
|
|
475 "Increase register I4 with the literal value of M.
|
|
476 The result is undefined when the result does not fit in
|
|
477 2 bytes."
|
|
478 1)
|
|
479
|
|
480 (INC5 address-transfer "increase I5" 53
|
|
481 "Increase register I5 with the literal value of M.
|
|
482 The result is undefined when the result does not fit in
|
|
483 2 bytes."
|
|
484 1)
|
|
485
|
|
486 (INC6 address-transfer "increase I6" 54
|
|
487 "Increase register I6 with the literal value of M.
|
|
488 The result is undefined when the result does not fit in
|
|
489 2 bytes."
|
|
490 1)
|
|
491
|
|
492 (DECA address-transfer "decrease A" 48
|
|
493 "Decrease register A with the literal value of M.
|
|
494 On overflow the overflow toggle is set."
|
|
495 1)
|
|
496
|
|
497 (DECX address-transfer "decrease X" 55
|
|
498 "Decrease register X with the literal value of M.
|
|
499 On overflow the overflow toggle is set."
|
|
500 1)
|
|
501
|
|
502 (DEC1 address-transfer "decrease I1" 49
|
|
503 "Decrease register I1 with the literal value of M.
|
|
504 The result is undefined when the result does not fit in
|
|
505 2 bytes."
|
|
506 1)
|
|
507
|
|
508 (DEC2 address-transfer "decrease I2" 50
|
|
509 "Decrease register I2 with the literal value of M.
|
|
510 The result is undefined when the result does not fit in
|
|
511 2 bytes."
|
|
512 1)
|
|
513
|
|
514 (DEC3 address-transfer "decrease I3" 51
|
|
515 "Decrease register I3 with the literal value of M.
|
|
516 The result is undefined when the result does not fit in
|
|
517 2 bytes."
|
|
518 1)
|
|
519
|
|
520 (DEC4 address-transfer "decrease I4" 52
|
|
521 "Decrease register I4 with the literal value of M.
|
|
522 The result is undefined when the result does not fit in
|
|
523 2 bytes."
|
|
524 1)
|
|
525
|
|
526 (DEC5 address-transfer "decrease I5" 53
|
|
527 "Decrease register I5 with the literal value of M.
|
|
528 The result is undefined when the result does not fit in
|
|
529 2 bytes."
|
|
530 1)
|
|
531
|
|
532 (DEC6 address-transfer "decrease I6" 54
|
|
533 "Decrease register I6 with the literal value of M.
|
|
534 The result is undefined when the result does not fit in
|
|
535 2 bytes."
|
|
536 1)
|
|
537
|
|
538 (CMPA comparison "compare A" 56 field
|
|
539 "Compare contents of A with contents of M.
|
|
540 The field specifier works on both fields. The comparison indicator
|
|
541 is set to LESS, EQUAL or GREATER depending on the outcome."
|
|
542 2)
|
|
543
|
|
544 (CMPX comparison "compare X" 63 field
|
|
545 "Compare contents of rX with contents of M.
|
|
546 The field specifier works on both fields. The comparison indicator
|
|
547 is set to LESS, EQUAL or GREATER depending on the outcome."
|
|
548 2)
|
|
549
|
|
550 (CMP1 comparison "compare I1" 57 field
|
|
551 "Compare contents of rI1 with contents of M.
|
|
552 The field specifier works on both fields. The comparison indicator
|
|
553 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
|
|
554 have a value of 0."
|
|
555 2)
|
|
556
|
|
557 (CMP2 comparison "compare I2" 58 field
|
|
558 "Compare contents of rI2 with contents of M.
|
|
559 The field specifier works on both fields. The comparison indicator
|
|
560 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
|
|
561 have a value of 0."
|
|
562 2)
|
|
563
|
|
564 (CMP3 comparison "compare I3" 59 field
|
|
565 "Compare contents of rI3 with contents of M.
|
|
566 The field specifier works on both fields. The comparison indicator
|
|
567 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
|
|
568 have a value of 0."
|
|
569 2)
|
|
570
|
|
571 (CMP4 comparison "compare I4" 60 field
|
|
572 "Compare contents of rI4 with contents of M.
|
|
573 The field specifier works on both fields. The comparison indicator
|
|
574 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
|
|
575 have a value of 0."
|
|
576 2)
|
|
577
|
|
578 (CMP5 comparison "compare I5" 61 field
|
|
579 "Compare contents of rI5 with contents of M.
|
|
580 The field specifier works on both fields. The comparison indicator
|
|
581 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
|
|
582 have a value of 0."
|
|
583 2)
|
|
584
|
|
585 (CMP6 comparison "compare I6" 62 field
|
|
586 "Compare contents of rI6 with contents of M.
|
|
587 The field specifier works on both fields. The comparison indicator
|
|
588 is set to LESS, EQUAL or GREATER depending on the outcome. Bit 1,2 and 3
|
|
589 have a value of 0."
|
|
590 2)
|
|
591
|
|
592 (JMP jump "jump" 39
|
|
593 "Unconditional jump.
|
|
594 Register J is set to the value of the next instruction that would have
|
|
595 been executed when there was no jump."
|
|
596 1)
|
|
597
|
|
598 (JSJ jump "jump, save J" 39
|
|
599 "Unconditional jump, but rJ is not modified."
|
|
600 1)
|
|
601
|
|
602 (JOV jump "jump on overflow" 39
|
|
603 "Jump if OV is set (and turn it off).
|
|
604 Register J is set to the value of the next instruction that would have
|
|
605 been executed when there was no jump."
|
|
606 1)
|
|
607
|
|
608 (JNOV jump "Jump on no overflow" 39
|
|
609 "Jump if OV is not set (and turn it off).
|
|
610 Register J is set to the value of the next instruction that would have
|
|
611 been executed when there was no jump."
|
|
612 1)
|
|
613
|
|
614 (JL jump "Jump on less" 39
|
|
615 "Jump if '[CM] = L'.
|
|
616 Register J is set to the value of the next instruction that would have
|
|
617 been executed when there was no jump."
|
|
618 1)
|
|
619
|
|
620 (JE jump "Jump on equal" 39
|
|
621 "Jump if '[CM] = E'.
|
|
622 Register J is set to the value of the next instruction that would have
|
|
623 been executed when there was no jump."
|
|
624 1)
|
|
625
|
|
626 (JG jump "Jump on greater" 39
|
|
627 "Jump if '[CM] = G'.
|
|
628 Register J is set to the value of the next instruction that would have
|
|
629 been executed when there was no jump."
|
|
630 1)
|
|
631
|
|
632 (JGE jump "Jump on not less" 39
|
|
633 "Jump if '[CM]' does not equal 'L'.
|
|
634 Register J is set to the value of the next instruction that would have
|
|
635 been executed when there was no jump."
|
|
636 1)
|
|
637
|
|
638 (JNE jump "Jump on not equal" 39
|
|
639 "Jump if '[CM]' does not equal 'E'.
|
|
640 Register J is set to the value of the next instruction that would have
|
|
641 been executed when there was no jump."
|
|
642 1)
|
|
643
|
|
644 (JLE jump "Jump on not greater" 39
|
|
645 "Jump if '[CM]' does not equal 'G'.
|
|
646 Register J is set to the value of the next instruction that would have
|
|
647 been executed when there was no jump."
|
|
648 1)
|
|
649
|
|
650 (JAN jump "jump A negative" 40
|
|
651 "Jump if the content of rA is negative.
|
|
652 Register J is set to the value of the next instruction that would have
|
|
653 been executed when there was no jump."
|
|
654 1)
|
|
655
|
|
656 (JAZ jump "jump A zero" 40
|
|
657 "Jump if the content of rA is zero.
|
|
658 Register J is set to the value of the next instruction that would have
|
|
659 been executed when there was no jump."
|
|
660 1)
|
|
661
|
|
662 (JAP jump "jump A positive" 40
|
|
663 "Jump if the content of rA is positive.
|
|
664 Register J is set to the value of the next instruction that would have
|
|
665 been executed when there was no jump."
|
|
666 1)
|
|
667
|
|
668 (JANN jump "jump A non-negative" 40
|
|
669 "Jump if the content of rA is non-negative.
|
|
670 Register J is set to the value of the next instruction that would have
|
|
671 been executed when there was no jump."
|
|
672 1)
|
|
673
|
|
674 (JANZ jump "jump A non-zero" 40
|
|
675 "Jump if the content of rA is non-zero.
|
|
676 Register J is set to the value of the next instruction that would have
|
|
677 been executed when there was no jump."
|
|
678 1)
|
|
679
|
|
680 (JANP jump "jump A non-positive" 40
|
|
681 "Jump if the content of rA is non-positive.
|
|
682 Register J is set to the value of the next instruction that would have
|
|
683 been executed when there was no jump."
|
|
684 1)
|
|
685
|
|
686 (JXN jump "jump X negative" 47
|
|
687 "Jump if the content of rX is negative.
|
|
688 Register J is set to the value of the next instruction that would have
|
|
689 been executed when there was no jump."
|
|
690 1)
|
|
691
|
|
692 (JXZ jump "jump X zero" 47
|
|
693 "Jump if the content of rX is zero.
|
|
694 Register J is set to the value of the next instruction that would have
|
|
695 been executed when there was no jump."
|
|
696 1)
|
|
697
|
|
698 (JXP jump "jump X positive" 47
|
|
699 "Jump if the content of rX is positive.
|
|
700 Register J is set to the value of the next instruction that would have
|
|
701 been executed when there was no jump."
|
|
702 1)
|
|
703
|
|
704 (JXNN jump "jump X non-negative" 47
|
|
705 "Jump if the content of rX is non-negative.
|
|
706 Register J is set to the value of the next instruction that would have
|
|
707 been executed when there was no jump."
|
|
708 1)
|
|
709
|
|
710 (JXNZ jump "jump X non-zero" 47
|
|
711 "Jump if the content of rX is non-zero.
|
|
712 Register J is set to the value of the next instruction that would have
|
|
713 been executed when there was no jump."
|
|
714 1)
|
|
715
|
|
716 (JXNP jump "jump X non-positive" 47
|
|
717 "Jump if the content of rX is non-positive.
|
|
718 Register J is set to the value of the next instruction that would have
|
|
719 been executed when there was no jump."
|
|
720 1)
|
|
721
|
|
722 (J1N jump "jump I1 negative" 41
|
|
723 "Jump if the content of rI1 is negative.
|
|
724 Register J is set to the value of the next instruction that would have
|
|
725 been executed when there was no jump."
|
|
726 1)
|
|
727
|
|
728 (J1Z jump "jump I1 zero" 41
|
|
729 "Jump if the content of rI1 is zero.
|
|
730 Register J is set to the value of the next instruction that would have
|
|
731 been executed when there was no jump."
|
|
732 1)
|
|
733
|
|
734 (J1P jump "jump I1 positive" 41
|
|
735 "Jump if the content of rI1 is positive.
|
|
736 Register J is set to the value of the next instruction that would have
|
|
737 been executed when there was no jump."
|
|
738 1)
|
|
739
|
|
740 (J1NN jump "jump I1 non-negative" 41
|
|
741 "Jump if the content of rI1 is non-negative.
|
|
742 Register J is set to the value of the next instruction that would have
|
|
743 been executed when there was no jump."
|
|
744 1)
|
|
745
|
|
746 (J1NZ jump "jump I1 non-zero" 41
|
|
747 "Jump if the content of rI1 is non-zero.
|
|
748 Register J is set to the value of the next instruction that would have
|
|
749 been executed when there was no jump."
|
|
750 1)
|
|
751
|
|
752 (J1NP jump "jump I1 non-positive" 41
|
|
753 "Jump if the content of rI1 is non-positive.
|
|
754 Register J is set to the value of the next instruction that would have
|
|
755 been executed when there was no jump."
|
|
756 1)
|
|
757
|
|
758 (J2N jump "jump I2 negative" 41
|
|
759 "Jump if the content of rI2 is negative.
|
|
760 Register J is set to the value of the next instruction that would have
|
|
761 been executed when there was no jump."
|
|
762 1)
|
|
763
|
|
764 (J2Z jump "jump I2 zero" 41
|
|
765 "Jump if the content of rI2 is zero.
|
|
766 Register J is set to the value of the next instruction that would have
|
|
767 been executed when there was no jump."
|
|
768 1)
|
|
769
|
|
770 (J2P jump "jump I2 positive" 41
|
|
771 "Jump if the content of rI2 is positive.
|
|
772 Register J is set to the value of the next instruction that would have
|
|
773 been executed when there was no jump."
|
|
774 1)
|
|
775
|
|
776 (J2NN jump "jump I2 non-negative" 41
|
|
777 "Jump if the content of rI2 is non-negative.
|
|
778 Register J is set to the value of the next instruction that would have
|
|
779 been executed when there was no jump."
|
|
780 1)
|
|
781
|
|
782 (J2NZ jump "jump I2 non-zero" 41
|
|
783 "Jump if the content of rI2 is non-zero.
|
|
784 Register J is set to the value of the next instruction that would have
|
|
785 been executed when there was no jump."
|
|
786 1)
|
|
787
|
|
788 (J2NP jump "jump I2 non-positive" 41
|
|
789 "Jump if the content of rI2 is non-positive.
|
|
790 Register J is set to the value of the next instruction that would have
|
|
791 been executed when there was no jump."
|
|
792 1)
|
|
793
|
|
794 (J3N jump "jump I3 negative" 41
|
|
795 "Jump if the content of rI3 is negative.
|
|
796 Register J is set to the value of the next instruction that would have
|
|
797 been executed when there was no jump."
|
|
798 1)
|
|
799
|
|
800 (J3Z jump "jump I3 zero" 41
|
|
801 "Jump if the content of rI3 is zero.
|
|
802 Register J is set to the value of the next instruction that would have
|
|
803 been executed when there was no jump."
|
|
804 1)
|
|
805
|
|
806 (J3P jump "jump I3 positive" 41
|
|
807 "Jump if the content of rI3 is positive.
|
|
808 Register J is set to the value of the next instruction that would have
|
|
809 been executed when there was no jump."
|
|
810 1)
|
|
811
|
|
812 (J3NN jump "jump I3 non-negative" 41
|
|
813 "Jump if the content of rI3 is non-negative.
|
|
814 Register J is set to the value of the next instruction that would have
|
|
815 been executed when there was no jump."
|
|
816 1)
|
|
817
|
|
818 (J3NZ jump "jump I3 non-zero" 41
|
|
819 "Jump if the content of rI3 is non-zero.
|
|
820 Register J is set to the value of the next instruction that would have
|
|
821 been executed when there was no jump."
|
|
822 1)
|
|
823
|
|
824 (J3NP jump "jump I3 non-positive" 41
|
|
825 "Jump if the content of rI3 is non-positive.
|
|
826 Register J is set to the value of the next instruction that would have
|
|
827 been executed when there was no jump."
|
|
828 1)
|
|
829
|
|
830 (J4N jump "jump I4 negative" 41
|
|
831 "Jump if the content of rI4 is negative.
|
|
832 Register J is set to the value of the next instruction that would have
|
|
833 been executed when there was no jump."
|
|
834 1)
|
|
835
|
|
836 (J4Z jump "jump I4 zero" 41
|
|
837 "Jump if the content of rI4 is zero.
|
|
838 Register J is set to the value of the next instruction that would have
|
|
839 been executed when there was no jump."
|
|
840 1)
|
|
841
|
|
842 (J4P jump "jump I4 positive" 41
|
|
843 "Jump if the content of rI4 is positive.
|
|
844 Register J is set to the value of the next instruction that would have
|
|
845 been executed when there was no jump."
|
|
846 1)
|
|
847
|
|
848 (J4NN jump "jump I4 non-negative" 41
|
|
849 "Jump if the content of rI4 is non-negative.
|
|
850 Register J is set to the value of the next instruction that would have
|
|
851 been executed when there was no jump."
|
|
852 1)
|
|
853
|
|
854 (J4NZ jump "jump I4 non-zero" 41
|
|
855 "Jump if the content of rI4 is non-zero.
|
|
856 Register J is set to the value of the next instruction that would have
|
|
857 been executed when there was no jump."
|
|
858 1)
|
|
859
|
|
860 (J4NP jump "jump I4 non-positive" 41
|
|
861 "Jump if the content of rI4 is non-positive.
|
|
862 Register J is set to the value of the next instruction that would have
|
|
863 been executed when there was no jump."
|
|
864 1)
|
|
865
|
|
866 (J5N jump "jump I5 negative" 41
|
|
867 "Jump if the content of rI5 is negative.
|
|
868 Register J is set to the value of the next instruction that would have
|
|
869 been executed when there was no jump."
|
|
870 1)
|
|
871
|
|
872 (J5Z jump "jump I5 zero" 41
|
|
873 "Jump if the content of rI5 is zero.
|
|
874 Register J is set to the value of the next instruction that would have
|
|
875 been executed when there was no jump."
|
|
876 1)
|
|
877
|
|
878 (J5P jump "jump I5 positive" 41
|
|
879 "Jump if the content of rI5 is positive.
|
|
880 Register J is set to the value of the next instruction that would have
|
|
881 been executed when there was no jump."
|
|
882 1)
|
|
883
|
|
884 (J5NN jump "jump I5 non-negative" 41
|
|
885 "Jump if the content of rI5 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."
|
|
888 1)
|
|
889
|
|
890 (J5NZ jump "jump I5 non-zero" 41
|
|
891 "Jump if the content of rI5 is non-zero.
|
|
892 Register J is set to the value of the next instruction that would have
|
|
893 been executed when there was no jump."
|
|
894 1)
|
|
895
|
|
896 (J5NP jump "jump I5 non-positive" 41
|
|
897 "Jump if the content of rI5 is non-positive.
|
|
898 Register J is set to the value of the next instruction that would have
|
|
899 been executed when there was no jump."
|
|
900 1)
|
|
901
|
|
902 (J6N jump "jump I6 negative" 41
|
|
903 "Jump if the content of rI6 is negative.
|
|
904 Register J is set to the value of the next instruction that would have
|
|
905 been executed when there was no jump."
|
|
906 1)
|
|
907
|
|
908 (J6Z jump "jump I6 zero" 41
|
|
909 "Jump if the content of rI6 is zero.
|
|
910 Register J is set to the value of the next instruction that would have
|
|
911 been executed when there was no jump."
|
|
912 1)
|
|
913
|
|
914 (J6P jump "jump I6 positive" 41
|
|
915 "Jump if the content of rI6 is positive.
|
|
916 Register J is set to the value of the next instruction that would have
|
|
917 been executed when there was no jump."
|
|
918 1)
|
|
919
|
|
920 (J6NN jump "jump I6 non-negative" 41
|
|
921 "Jump if the content of rI6 is non-negative.
|
|
922 Register J is set to the value of the next instruction that would have
|
|
923 been executed when there was no jump."
|
|
924 1)
|
|
925
|
|
926 (J6NZ jump "jump I6 non-zero" 41
|
|
927 "Jump if the content of rI6 is non-zero.
|
|
928 Register J is set to the value of the next instruction that would have
|
|
929 been executed when there was no jump."
|
|
930 1)
|
|
931
|
|
932 (J6NP jump "jump I6 non-positive" 41
|
|
933 "Jump if the content of rI6 is non-positive.
|
|
934 Register J is set to the value of the next instruction that would have
|
|
935 been executed when there was no jump."
|
|
936 1)
|
|
937
|
|
938 (SLA miscellaneous "shift left A" 6
|
|
939 "Shift to A, M bytes left.
|
|
940 Hero's will be added to the right."
|
|
941 2)
|
|
942
|
|
943 (SRA miscellaneous "shift right A" 6
|
|
944 "Shift to A, M bytes right.
|
|
945 Zeros will be added to the left."
|
|
946 2)
|
|
947
|
|
948 (SLAX miscellaneous "shift left AX" 6
|
|
949 "Shift AX, M bytes left.
|
|
950 Zeros will be added to the right."
|
|
951 2)
|
|
952
|
|
953
|
|
954 (SRAX miscellaneous "shift right AX" 6
|
|
955 "Shift AX, M bytes right.
|
|
956 Zeros will be added to the left."
|
|
957 2)
|
|
958
|
|
959 (SLC miscellaneous "shift left AX circularly" 6
|
|
960 "Shift AX, M bytes left circularly.
|
|
961 The bytes that fall off to the left will be added to the right."
|
|
962 2)
|
|
963
|
|
964 (SRC miscellaneous "shift right AX circularly" 6
|
|
965 "Shift AX, M bytes right circularly.
|
|
966 The bytes that fall off to the right will be added to the left."
|
|
967 2)
|
|
968
|
|
969 (MOVE miscellaneous "move" 7 number
|
|
970 "Move MOD words from M to the location stored in rI1."
|
|
971 (+ 1 (* 2 number)))
|
|
972
|
|
973 (NOP miscellaneous "no operation" 0 ignored
|
|
974 "No operation, M and F are not used by the machine."
|
|
975 1)
|
|
976
|
|
977 (HLT miscellaneous "halt" 5
|
|
978 "Halt.
|
|
979 Stop instruction fetching."
|
|
980 1)
|
|
981
|
|
982 (IN input-output "input" 36 unit
|
|
983 "Transfer a block of words from the specified unit to memory.
|
|
984 The transfer starts at address M."
|
|
985 1)
|
|
986
|
|
987 (OUT input-output "output" 37 unit
|
|
988 "Transfer a block of words from memory.
|
|
989 The transfer starts at address M to the specified unit."
|
|
990 1)
|
|
991
|
|
992 (IOC input-output "input-output control" 35 unit
|
|
993 "Perform a control operation.
|
|
994 The control operation is given by M on the specified unit."
|
|
995 1)
|
|
996
|
|
997 (JRED input-output "jump ready" 38 unit
|
|
998 "Jump to M if the specified unit is ready."
|
|
999 1)
|
|
1000
|
|
1001 (JBUS input-output "jump busy" 34 unit
|
|
1002 "Jump to M if the specified unit is busy."
|
|
1003 1)
|
|
1004
|
|
1005 (NUM conversion "convert to numeric" 5
|
|
1006 "Convert rAX to its numerical value and store it in rA.
|
|
1007 the register rAX is assumed to contain a character representation of
|
|
1008 a number."
|
|
1009 10)
|
|
1010
|
|
1011 (CHAR conversion "convert to characters" 5
|
|
1012 "Convert the number stored in rA to a character representation.
|
|
1013 The converted character representation is stored in rAX."
|
|
1014 10))
|
|
1015
|
|
1016 "Alist that contains all the possible operation codes for mix.
|
|
1017 Each elt has the form
|
|
1018 (OP-CODE GROUP FULL-NAME C-BYTE F-BYTE DESCRIPTION EXECUTION-TIME)
|
|
1019 Where OP-CODE is the text of the opcode as an symbol,
|
|
1020 FULL-NAME is the human readable name as a string,
|
|
1021 C-BYTE is the operation code telling what operation is to be performed,
|
|
1022 F-BYTE holds a modification of the operation code which can be a symbol
|
|
1023 or a number,
|
|
1024 DESCRIPTION contains an string with a description about the operation code and
|
|
1025 EXECUTION-TIME holds info about the time it takes, number or string.")
|
|
1026 ;; (makunbound 'mixal-operation-codes-alist)
|
|
1027
|
|
1028
|
|
1029 ;;; Font-locking:
|
|
1030 (defvar mixal-font-lock-syntactic-keywords
|
|
1031 ;; Normal comments start with a * in column 0 and end at end of line.
|
|
1032 '(("^\\*" (0 '(11))) ;(string-to-syntax "<") == '(11)
|
|
1033 ;; Every line can end with a comment which is placed after the operand.
|
|
1034 ;; I assume here that mnemonics without operands can not have a comment.
|
|
1035 ("^[[:alnum:]]*[ \t]+[[:alnum:]]+[ \t]+[^ \n\t]+[ \t]*\\([ \t]\\)[^\n \t]"
|
|
1036 (1 '(11)))))
|
|
1037
|
|
1038 (defvar mixal-font-lock-keywords
|
|
1039 `(("^\\([A-Z0-9a-z]+\\)"
|
|
1040 (1 mixal-font-lock-label-face))
|
|
1041 (,(regexp-opt (mapcar (lambda (x) (symbol-name (car x)))
|
|
1042 mixal-operation-codes-alist) 'words)
|
|
1043 . mixal-font-lock-operation-code-face)
|
|
1044 (,(regexp-opt mixal-assembly-pseudoinstructions 'words)
|
|
1045 . mixal-font-lock-assembly-pseudoinstruction-face)
|
|
1046 ("^[A-Z0-9a-z]*[ \t]+[A-ZO-9a-z]+[ \t]+\\(=.*=\\)"
|
|
1047 (1 font-lock-constant-face)))
|
|
1048 "Keyword highlighting specification for `mixal-mode'.")
|
|
1049 ;; (makunbound 'mixal-font-lock-keywords)
|
|
1050
|
|
1051 (defvar mixal-describe-operation-code-history nil
|
|
1052 "History list for describe operation code.")
|
|
1053
|
|
1054 (defun mixal-describe-operation-code (op-code)
|
|
1055 "Display the full documentation of OP-CODE."
|
|
1056 (interactive
|
|
1057 (list
|
|
1058 (let* ((completion-ignore-case t)
|
|
1059 ;; we already have a list, but it is not in the right format
|
|
1060 ;; transform it to a valid table so completition can use it
|
|
1061 (table (mapcar '(lambda (elm)
|
|
1062 (cons (symbol-name (car elm)) nil))
|
|
1063 mixal-operation-codes-alist))
|
|
1064 ;; prompt is different depending on we are close to a valid op-code
|
|
1065 (have-default (assq (intern-soft (current-word))
|
|
1066 mixal-operation-codes-alist))
|
|
1067 (prompt (concat "Describe operation code "
|
|
1068 (if have-default
|
|
1069 (concat "(default " (current-word) "): ")
|
|
1070 ": "))))
|
|
1071 ;; As the operation code to the user.
|
|
1072 (completing-read prompt table nil t nil
|
|
1073 'mixal-describe-operation-code-history
|
|
1074 (current-word)))))
|
|
1075 ;; get the info on the op-code and output it to the help buffer
|
|
1076 (let ((op-code-help (assq (intern-soft op-code) mixal-operation-codes-alist)))
|
|
1077 (when op-code-help
|
|
1078 (with-output-to-temp-buffer (buffer-name (get-buffer-create "*Help*"))
|
|
1079 (princ op-code) (princ " is an mix operation code\n\n")
|
|
1080 (princ (nth 5 op-code-help)) (terpri) (terpri)
|
|
1081 (princ " group: ") (princ (nth 1 op-code-help)) (terpri)
|
|
1082 (princ " nice name: ") (princ (nth 2 op-code-help)) (terpri)
|
|
1083 (princ " OPCODE / C: ") (princ (nth 3 op-code-help)) (terpri)
|
|
1084 (princ " MOD / F: ") (princ (nth 4 op-code-help)) (terpri)
|
|
1085 (princ " time: ") (princ (nth 6 op-code-help)) (terpri)))))
|
|
1086
|
|
1087 ;;;; Running
|
|
1088 (defun mixal-run ()
|
|
1089 "Run mixal file in current buffer, assumes that file has been compiled."
|
|
1090 (interactive)
|
|
1091 (mixvm (concat "mixvm -r -t -d "
|
|
1092 (file-name-sans-extension (buffer-file-name)))))
|
|
1093
|
|
1094 (defun mixal-debug ()
|
|
1095 "Start mixvm for debugging.
|
|
1096 Assumes that file has been compiled with debugging support."
|
|
1097 (interactive)
|
|
1098 (mixvm (concat "mixvm "
|
|
1099 (file-name-sans-extension (buffer-file-name)))))
|
|
1100
|
|
1101 ;;;###autoload
|
|
1102 (define-derived-mode mixal-mode fundamental-mode "mixal"
|
|
1103 "Major mode for the mixal asm language.
|
|
1104 \\{mixal-mode-map}"
|
|
1105 (set (make-local-variable 'comment-start) "*")
|
|
1106 (set (make-local-variable 'comment-start-skip) "^\\*[ \t]*")
|
|
1107 (set (make-local-variable 'font-lock-defaults)
|
|
1108 `(mixal-font-lock-keywords nil nil nil nil
|
|
1109 (font-lock-syntactic-keywords . ,mixal-font-lock-syntactic-keywords)
|
|
1110 (parse-sexp-lookup-properties . t)))
|
|
1111 ;; might add an indent function in the future
|
|
1112 ;; (set (make-local-variable 'indent-line-function) 'mixal-indent-line)
|
|
1113 (set (make-local-variable 'compile-command) (concat "mixasm "
|
|
1114 buffer-file-name))
|
|
1115 ;; mixasm will do strange when there is no final newline,
|
|
1116 ;; so let Emacs ensure that it is always there
|
|
1117 (set (make-local-variable 'require-final-newline)
|
|
1118 mode-require-final-newline))
|
|
1119
|
|
1120 ;;;###autoload
|
|
1121 (add-to-list 'auto-mode-alist '("\\.mixal\\'" . mixal-mode))
|
|
1122
|
|
1123 (provide 'mixal-mode)
|
|
1124
|
|
1125 ;; arch-tag: be7c128a-bf61-4951-a90e-9398267ce3f3
|
|
1126 ;;; mixal-mode.el ends here
|