1
0
mirror of https://github.com/rzzzwilson/pymlac.git synced 2025-06-10 09:32:41 +00:00

Handling display instructions

This commit is contained in:
Ross Wilson
2016-02-07 12:20:18 +07:00
parent b5e9536887
commit 2ac5112e01

View File

@@ -28,6 +28,7 @@ import os
import copy
import string
import getopt
import traceback
######
# Globals
@@ -66,7 +67,11 @@ Undefined = None
# buffer for blocked code
BlockMaxSize = 255 # maximum size of buffer (words)
BlockBuffer = bytearray() # actual buffered words
BlockBufferBase = None # base address of the block
BlockBufferBase = None # base address of the block
# DEIM state
ShortVectorMode = False # True if within a DEIM/INC instruction
BeamState = 0 # 1 if beam is ON, 0 if OFF
######
# Mostly constant stuff
@@ -347,6 +352,8 @@ def error(msg):
print("%04d: %s" % (lnum, line))
print(msg)
print('-' * 80)
# traceback.print_stack()
# print('SymTable=%s' % str(SymTable))
ListFileHandle.write('-' * 80 + '\n')
ListFileHandle.write("%04d: %s\n" % (lnum, line))
@@ -589,6 +596,14 @@ def pass_1(lines):
ascii_words += 1
Dot += ascii_words
elif opcode == 'INC':
# start of short vector mode
if not addr:
error("INC pseudo-op must have a data field")
if label:
define_label(label, Dot, lnum)
Dot += 1
elif opcode == 'END':
# get the (optional) start address
if addr:
@@ -743,6 +758,31 @@ def pass_2(lines):
write_list(word_value, Dot, list_lnum, list_line)
Dot += 1
elif opcode == 'INC':
if not addr:
error("INC pseudo-op must have a data field")
if label:
try:
old_dot = SymTable[label]
if Dot != old_dot:
error("INC dot value has changed, "
"was %06o, is now %06o"
% (old_dot, Dot))
except KeyError:
error("INC label '%s' wasn't defined in first pass!?"
% label)
inc_fields = addr.split(',')
if len(inc_fields) != 2:
error("INC pseudo-op must have a two-part field")
(first_code, second_code) = inc_fields
high_byte = geninc(first_code)
low_byte = geninc(second_code)
word_value = (high_byte << 8) + low_byte
emit_word(word_value)
write_list(word_value, Dot, lnum, line)
Dot += 1
elif opcode == 'END':
# get optional start address
if addr:
@@ -793,6 +833,106 @@ def pass_2(lines):
if lnum - 1 > len(lines):
error("Something after the 'END' pseudo-op!?")
def genincfield(code):
"""Generate code value of INC sub-field.
The sub-field code may contain:
[+|-] n [+|-] n
"""
xneg = yneg = 0
# handle possible X +/- operation
if code[0] in '+-':
code = code[1:]
if code[0] == '+':
xneg = 0
elif code[0] == '-':
xneg = 1
# handle X numeric field
if code[0] not in '0123':
error('INC numeric X value must be 0, 1, 2 or 3')
x = int(code[0])
code = code[1:]
# handle possible Y +/- operation
if code[0] in '+-':
code = code[1:]
if code[0] == '+':
yneg = 0
elif code[0] == '-':
yneg = 1
# handle Y numeric field
if code[0] not in '0123':
error('INC numeric Y value must be 0, 1, 2 or 3')
y = int(code[0])
code = code[1:]
if len(code) > 0:
error('INC value has trailing characters')
return 0200 | (BeamState << 6) | (xneg << 5) | (x << 3) | (yneg << 2) | y
def geninc(code):
"""Generate the byte value for an INC code.
Two code fields follow and INC opcode, separated by ','.
Each field may contain:
E | F | [B|D] [+|-] n [+|-] n
Where 'E' may only be the firstcode in an INC chain, and 'n' must be one
of 0, 1, 2 or 3.
"""
global ShortVectorMode, BeamState
if code[0] == 'A': # make a byte
code = code[1:]
ShortVectorMode = False
return int(code)
elif code[0] == 'B': # beam on
BeamState = 1
return genincfield(code[1:])
elif code[0] == 'D': # beam off
BeamState = 0
return genincfield(code[1:])
elif code[0] == 'E': # enter INC mode
if ShortVectorMode:
error('Already in INC mode!?')
ShortVectorMode = True
BeamState = 1
return 0060
elif code[0] == 'F': # exit INC mode
ShortVectorMode = False
BeamState = 0
return 0171
elif code[0] == 'N': # ???
if not ShortVectorMode:
error('Not in INC mode!?')
return 0111
elif code[0] == 'P': # pause (filler)
if not ShortVectorMode:
error('Not in INC mode!?')
return 0200
elif code[0] == 'R': # ???
if not ShortVectorMode:
error('Not in INC mode!?')
return 0151
elif code[0] == 'X': # ???
if not ShortVectorMode:
error('Not in INC mode!?')
return 0010
elif code[0] == 'Y': # ???
if not ShortVectorMode:
error('Not in INC mode!?')
return 0001
elif code[0] in '0123+-':
return genincfield(code)
else:
error("Unrecognized INC code: '%s' (code=%s)" % (code[0], code))
def gen_code(lnum, line, dot, label, opcode, indirect, addr):
"""Assemble one line of code.