added jump shortcut mnemonics to MU8A
This commit is contained in:
@@ -163,6 +163,23 @@ specifications: here, it's `[selector] [value] [jumpaddr]` as opposed to
|
|||||||
`[value] [jumpaddr] [selector]`. This has been done for more convenient
|
`[value] [jumpaddr] [selector]`. This has been done for more convenient
|
||||||
jump programming by selecting the condition as the first operand.
|
jump programming by selecting the condition as the first operand.
|
||||||
|
|
||||||
|
The shortcut mnemonics for the jump operations are as follows:
|
||||||
|
|
||||||
|
* `jeq` is a shortcut to `jmp 0` (direct jump if equals to zero)
|
||||||
|
* `jgt` is a shortcut to `jmp 1` (direct jump if greater than zero)
|
||||||
|
* `jlt` is a shortcut to `jmp 2` (direct jump if less than zero)
|
||||||
|
* `jge` is a shortcut to `jmp 3` (direct jump if greater than or equals to zero)
|
||||||
|
* `jle` is a shortcut to `jmp 4` (direct jump if less than or equals to zero)
|
||||||
|
* `jne` is a shortcut to `jmp 5` (direct jump if not equals to zero)
|
||||||
|
* `juc` is a shortcut to `jmp 6 0` (direct unconditional jump)
|
||||||
|
* `ieq` is a shortcut to `jmp 7` (indirect jump if equals to zero)
|
||||||
|
* `igt` is a shortcut to `jmp 8` (indirect jump if greater than zero)
|
||||||
|
* `ilt` is a shortcut to `jmp 9` (indirect jump if less than zero)
|
||||||
|
* `ige` is a shortcut to `jmp 10` (indirect jump if greater than or equals to zero)
|
||||||
|
* `ile` is a shortcut to `jmp 11` (indirect jump if less than or equals to zero)
|
||||||
|
* `ine` is a shortcut to `jmp 12` (indirect jump if not equals to zero)
|
||||||
|
* `iuc` is a shortcut to `jmp 13 0` (indirect unconditional jump)
|
||||||
|
|
||||||
### Port input and output
|
### Port input and output
|
||||||
|
|
||||||
For the commands 3 and 4, mu808 supports optional non-zero port numbers, where
|
For the commands 3 and 4, mu808 supports optional non-zero port numbers, where
|
||||||
@@ -226,18 +243,19 @@ the MU8A assembly file to convert it into a plain text based machine code
|
|||||||
representation:
|
representation:
|
||||||
|
|
||||||
1. Remove all comments (starting with `;` until the end of the line).
|
1. Remove all comments (starting with `;` until the end of the line).
|
||||||
2. Record the current line number N (not counting completely empty lines),
|
2. Replace all jump shortcuts according to the above mnemonics.
|
||||||
|
3. Record the current line number N (not counting completely empty lines),
|
||||||
starting with 1.
|
starting with 1.
|
||||||
3. Split the line into space-delimited fields (1-based numbering as well).
|
4. Split the line into space-delimited fields (1-based numbering as well).
|
||||||
4. Check if the first field starts with `:`. If so, mark the mapping between
|
5. Check if the first field starts with `:`. If so, mark the mapping between
|
||||||
the field text and the number N, then remove the field from the set
|
the field text and the number N, then remove the field from the set
|
||||||
(so that the field 2 becomes field 1 and so on).
|
(so that the field 2 becomes field 1 and so on).
|
||||||
5. If the field 1 is not already a number, replace the field 1 mnemonic text
|
6. If the field 1 is not already a number, replace the field 1 mnemonic text
|
||||||
with the numeric opcode if it can be found. If it's not a number and the
|
with the numeric opcode if it can be found. If it's not a number and the
|
||||||
mnemonic cannot be found, report an error and halt the process.
|
mnemonic cannot be found, report an error and halt the process.
|
||||||
6. Prepend N and the space to the current line and write the result into the
|
7. Prepend N and the space to the current line and write the result into the
|
||||||
target file.
|
target file.
|
||||||
7. After the steps 1 to 6 are complete for every line, replace every label
|
8. After the steps 1 to 7 are complete for every line, replace every label
|
||||||
occurrence in the mapping with the corresponding number in the target file.
|
occurrence in the mapping with the corresponding number in the target file.
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
|
|||||||
+21
-1
@@ -17,13 +17,33 @@ import sys, re, struct
|
|||||||
mnemos = ['nop', 'jmp', 'iat', 'out', 'inp', 'set', 'cpy', 'fma',
|
mnemos = ['nop', 'jmp', 'iat', 'out', 'inp', 'set', 'cpy', 'fma',
|
||||||
'sub', 'div', 'mdf', 'abs', 'sqr', 'nel', 'tri', 'rnd']
|
'sub', 'div', 'mdf', 'abs', 'sqr', 'nel', 'tri', 'rnd']
|
||||||
|
|
||||||
|
# mu808 jump shortcuts
|
||||||
|
jmp_shorts = {
|
||||||
|
'jeq': 'jmp 0', # direct jump if equals to zero
|
||||||
|
'jgt': 'jmp 1', # direct jump if greater than zero
|
||||||
|
'jlt': 'jmp 2', # direct jump if less than zero
|
||||||
|
'jge': 'jmp 3', # direct jump if greater than or equals to zero
|
||||||
|
'jle': 'jmp 4', # direct jump if less than or equals to zero
|
||||||
|
'jne': 'jmp 5', # direct jump if not equals to zero
|
||||||
|
'juc': 'jmp 6 0', # direct unconditional jump
|
||||||
|
'ieq': 'jmp 7', # indirect jump if equals to zero
|
||||||
|
'igt': 'jmp 8', # indirect jump if greater than zero
|
||||||
|
'ilt': 'jmp 9', # indirect jump if less than zero
|
||||||
|
'ige': 'jmp 10', # indirect jump if greater than or equals to zero
|
||||||
|
'ile': 'jmp 11', # indirect jump if less than or equals to zero
|
||||||
|
'ine': 'jmp 12', # indirect jump if not equals to zero
|
||||||
|
'iuc': 'jmp 13 0' # indirect unconditional jump
|
||||||
|
}
|
||||||
|
|
||||||
# converts the MU8A source code to the plaintext machine code representation
|
# converts the MU8A source code to the plaintext machine code representation
|
||||||
def assemble(source):
|
def assemble(source):
|
||||||
labels = {}
|
labels = {}
|
||||||
out = ''
|
out = ''
|
||||||
lno = 0
|
lno = 0
|
||||||
vreg = re.compile(r'\s+')
|
vreg = re.compile(r'\s+')
|
||||||
for line in source.split('\n'):
|
for shrt, meaning in jmp_shorts.items(): # replace the jump shortcuts
|
||||||
|
source = source.replace(shrt, meaning)
|
||||||
|
for line in source.split('\n'): # parse the main code
|
||||||
fields = []
|
fields = []
|
||||||
line = line.split(';')[0].strip()
|
line = line.split(';')[0].strip()
|
||||||
if len(line) > 0: # actual line to be counted on
|
if len(line) > 0: # actual line to be counted on
|
||||||
|
|||||||
Reference in New Issue
Block a user