diff --git a/README.md b/README.md index ddccc64..26638cc 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,23 @@ specifications: here, it's `[selector] [value] [jumpaddr]` as opposed to `[value] [jumpaddr] [selector]`. This has been done for more convenient 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 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: 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. -3. 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 +4. Split the line into space-delimited fields (1-based numbering as well). +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 (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 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. -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. Examples diff --git a/mu808asm.py b/mu808asm.py index 2ee8b56..12915b4 100755 --- a/mu808asm.py +++ b/mu808asm.py @@ -17,13 +17,33 @@ import sys, re, struct mnemos = ['nop', 'jmp', 'iat', 'out', 'inp', 'set', 'cpy', 'fma', '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 def assemble(source): labels = {} out = '' lno = 0 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 = [] line = line.split(';')[0].strip() if len(line) > 0: # actual line to be counted on