added jump shortcut mnemonics to MU8A

This commit is contained in:
Luxferre
2025-04-30 08:15:48 +03:00
parent 9eaffc7202
commit 8122ca07dd
2 changed files with 45 additions and 7 deletions
+24 -6
View File
@@ -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
View File
@@ -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