OpenCores
URL https://opencores.org/ocsvn/ssbcc/ssbcc/trunk

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [asmDef_9x8.py] - Diff between revs 11 and 12

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 11 Rev 12
Line 1... Line 1...
################################################################################
################################################################################
#
#
# Copyright 2012-2014, Sinclair R.F., Inc.
# Copyright 2012-2015, Sinclair R.F., Inc.
#
#
# Assembly language definitions for SSBCC 9x8.
# Assembly language definitions for SSBCC 9x8.
#
#
################################################################################
################################################################################
 
 
Line 437... Line 437...
    # Ensure the main body ends in a ".jump".
    # Ensure the main body ends in a ".jump".
    lastToken = rawTokens[-1];
    lastToken = rawTokens[-1];
    if firstToken['value'] == '.main':
    if firstToken['value'] == '.main':
      if (lastToken['type'] != 'macro') or (lastToken['value'] != '.jump'):
      if (lastToken['type'] != 'macro') or (lastToken['value'] != '.jump'):
        raise asmDef.AsmException('.main body does not end in ".jump" at %s' % lastToken['loc']);
        raise asmDef.AsmException('.main body does not end in ".jump" at %s' % lastToken['loc']);
    # Ensure functions and interrupts end in a ".jump" or ".return".
    # Ensure the interrupt body contains a ".returni" and does not contain any ".return"s.
    if firstToken['value'] in ('.function','.interrupt',):
    if firstToken['value'] == '.interrupt':
 
      for token in [token for token in rawTokens if (token['type'] == 'macro') and (token['value'] == '.return')]:
 
        raise asmDef.AsmException('".return" macro prohibited in .interrupt at %s' % token['loc']);
 
      foundReturni = [token for token in rawTokens if (token['type'] == 'macro') and (token['value'] == '.returni')];
 
      if not foundReturni:
 
        raise asmDef.AsmException('.returni missing in .interrupt body at %s' % rawTokens[0]['loc']);
 
      if (lastToken['type'] != 'macro') or (lastToken['value'] not in ('.jump','.returni',)):
 
        raise asmDef.AsmException('.interrupt must end in .jump or .returni instead of "%s" at %s' % (lastToken['value'],lastToken['loc'],));
 
    # Ensure functions end in a ".jump" or ".return".
 
    if firstToken['value'] == '.function':
      if (lastToken['type'] != 'macro') or (lastToken['value'] not in ('.jump','.return',)):
      if (lastToken['type'] != 'macro') or (lastToken['value'] not in ('.jump','.return',)):
        raise asmDef.AsmException('Last entry in ".function" or ".interrupt" must be a ".jump" or ".return" at %s' % lastToken['loc']);
        raise asmDef.AsmException('function "%s" must end in .jump or .return instead of "%s" at %s' % (firstToken['value'],lastToken['value'],lastToken['loc'],));
 
    # Ensure that .main and normal functions do not use ".returni".
 
    if firstToken['value'] in ('.main','.function',):
 
      for token in [token for token in rawTokens if (token['type'] == 'macro') and (token['value'] == '.returni')]:
 
        raise asmDef.AsmException('.returni prohibited outside .interrupt at %s' % token['loc']);
 
 
  ################################################################################
  ################################################################################
  #
  #
  # fill in symbols, etc. in the list of raw tokens.
  # fill in symbols, etc. in the list of raw tokens.
  #
  #
Line 737... Line 750...
    Finally, ensure the function address space does not exceed the absolute
    Finally, ensure the function address space does not exceed the absolute
    8192 address limit.
    8192 address limit.
    """
    """
    self.functionEvaluation = dict(list=list(), length=list(), body=list(), address=list());
    self.functionEvaluation = dict(list=list(), length=list(), body=list(), address=list());
    nextStart = 0;
    nextStart = 0;
    # ".main" is always required.
    # ".interrupt" is optionally required (and is sure to exist by this
    self.functionEvaluation['list'].append('.main');
    # function call if it is required).  The interrupt handler always starts at
    self.functionEvaluation['length'].append(self.main['length']);
    # address 3 so that address 0 can be a jump to ".main".
    self.functionEvaluation['body'].append(self.main['tokens']);
 
    self.functionEvaluation['address'].append(nextStart);
 
    nextStart = nextStart + self.functionEvaluation['length'][-1];
 
    # ".interrupt" is optionally required (and is sure to exist by this function
 
    # call if it is required).
 
    if self.interrupt:
    if self.interrupt:
 
      nextStart = 3;
      self.functionEvaluation['list'].append('.interrupt');
      self.functionEvaluation['list'].append('.interrupt');
      self.functionEvaluation['length'].append(self.interrupt['length']);
      self.functionEvaluation['length'].append(self.interrupt['length']);
      self.functionEvaluation['body'].append(self.interrupt['tokens']);
      self.functionEvaluation['body'].append(self.interrupt['tokens']);
      self.functionEvaluation['address'].append(nextStart);
      self.functionEvaluation['address'].append(nextStart);
      nextStart = nextStart + self.functionEvaluation['length'][-1];
      nextStart = nextStart + self.functionEvaluation['length'][-1];
 
    # ".main" is always required.
 
    self.functionEvaluation['list'].append('.main');
 
    self.functionEvaluation['length'].append(self.main['length']);
 
    self.functionEvaluation['body'].append(self.main['tokens']);
 
    self.functionEvaluation['address'].append(nextStart);
 
    nextStart = nextStart + self.functionEvaluation['length'][-1];
    # Loop through the required function bodies as they are identified.
    # Loop through the required function bodies as they are identified.
    ix = 0;
    ix = 0;
    while ix < len(self.functionEvaluation['body']):
    while ix < len(self.functionEvaluation['body']):
      for token in self.functionEvaluation['body'][ix]:
      for token in self.functionEvaluation['body'][ix]:
        if (token['type'] == 'macro') and (token['value'] in ('.call','.callc',)):
        if (token['type'] == 'macro') and (token['value'] in ('.call','.callc',)):
Line 1063... Line 1078...
    # .callc
    # .callc
    elif token['value'] == '.callc':
    elif token['value'] == '.callc':
      self.EmitPush(fp,token['address'] & 0xFF,'');
      self.EmitPush(fp,token['address'] & 0xFF,'');
      self.EmitOpcode(fp,self.specialInstructions['callc'] | (token['address'] >> 8),'callc '+token['argument'][0]['value']);
      self.EmitOpcode(fp,self.specialInstructions['callc'] | (token['address'] >> 8),'callc '+token['argument'][0]['value']);
      self.EmitOptArg(fp,token['argument'][1]);
      self.EmitOptArg(fp,token['argument'][1]);
 
    # .dis
 
    elif token['value'] == '.dis':
 
      if not self.interruptsEnabled:
 
        raise Exception('Program Bug -- interrupts not enabled');
 
      dis_outport = self.interrupt_dis_outport;
 
      self.EmitPush(fp,self.OutportAddress(dis_outport),dis_outport);
 
      self.EmitOpcode(fp,self.InstructionOpcode('outport'),'outport (.dis)');
 
    # .ena
 
    elif token['value'] == '.ena':
 
      if not self.interruptsEnabled:
 
        raise Exception('Program Bug -- interrupts not enabled');
 
      ena_outport = self.interrupt_ena_outport;
 
      self.EmitPush(fp,self.OutportAddress(ena_outport),ena_outport);
 
      self.EmitOpcode(fp,self.InstructionOpcode('outport'),'outport (.ena)');
    # .fetch
    # .fetch
    elif token['value'] == '.fetch':
    elif token['value'] == '.fetch':
      name = token['argument'][0]['value'];
      name = token['argument'][0]['value'];
      ixBank = self.Emit_GetBank(name);
      ixBank = self.Emit_GetBank(name);
      self.EmitOpcode(fp,self.specialInstructions['fetch'] | ixBank,'fetch '+name);
      self.EmitOpcode(fp,self.specialInstructions['fetch'] | ixBank,'fetch '+name);
Line 1092... Line 1121...
      self.EmitOptArg(fp,token['argument'][1]);
      self.EmitOptArg(fp,token['argument'][1]);
    # .return
    # .return
    elif token['value'] == '.return':
    elif token['value'] == '.return':
      self.EmitOpcode(fp,self.specialInstructions['return'],'return');
      self.EmitOpcode(fp,self.specialInstructions['return'],'return');
      self.EmitOptArg(fp,token['argument'][0]);
      self.EmitOptArg(fp,token['argument'][0]);
 
    # .returni
 
    elif token['value'] == '.returni':
 
      if not self.interruptsEnabled:
 
        raise Exception('Program Bug -- interrupts not enabled');
 
      ena_outport = self.interrupt_ena_outport;
 
      self.EmitPush(fp,self.OutportAddress(ena_outport),ena_outport);
 
      self.EmitOpcode(fp,self.specialInstructions['return'],'return');
 
      self.EmitOpcode(fp,self.InstructionOpcode('outport'),'outport (.ena)');
    # .store
    # .store
    elif token['value'] == '.store':
    elif token['value'] == '.store':
      name = token['argument'][0]['value'];
      name = token['argument'][0]['value'];
      ixBank = self.Emit_GetBank(name);
      ixBank = self.Emit_GetBank(name);
      self.EmitOpcode(fp,self.specialInstructions['store'] | ixBank,'store '+name);
      self.EmitOpcode(fp,self.specialInstructions['store'] | ixBank,'store '+name);
Line 1144... Line 1181...
                        its range are to be converted into an instruction
                        its range are to be converted into an instruction
    """
    """
    # Write the program marker, address of .main, address or "[]" of .interrupt,
    # Write the program marker, address of .main, address or "[]" of .interrupt,
    # and the total program length.
    # and the total program length.
    fp.write(':program');
    fp.write(':program');
    fp.write(' %d' % self.functionEvaluation['address'][0]);
 
    if self.interrupt:
    if self.interrupt:
      fp.write(' %d' % self.functionEvaluation['address'][1]);
      fp.write(' %d' % self.functionEvaluation['address'][1]);  # .main
 
      fp.write(' %d' % self.functionEvaluation['address'][0]);  # .interrupt
    else:
    else:
      fp.write(' []');
      fp.write(' %d' % self.functionEvaluation['address'][0]);  # .main
 
      fp.write(' []');                                          # no .interrupt
    fp.write(' %d' % (self.functionEvaluation['address'][-1] + self.functionEvaluation['length'][-1]));
    fp.write(' %d' % (self.functionEvaluation['address'][-1] + self.functionEvaluation['length'][-1]));
    fp.write('\n');
    fp.write('\n');
    # Emit the bodies
    # Emit the bodies
 
    if self.interrupt:
 
      self.emitLabelList = '';
 
      mainAddress = self.functionEvaluation['address'][1];
 
      self.EmitPush(fp,mainAddress & 0xFF,name='');
 
      self.EmitOpcode(fp,self.specialInstructions['jump'] | (mainAddress >> 8),'jump .main');
 
      self.EmitOpcode(fp,self.InstructionOpcode('nop'),'nop');
    for ix in range(len(self.functionEvaluation['list'])):
    for ix in range(len(self.functionEvaluation['list'])):
      fp.write('- %s\n' % self.functionEvaluation['list'][ix]);
      fp.write('- %s\n' % self.functionEvaluation['list'][ix]);
      self.emitLabelList = '';
      self.emitLabelList = '';
      for token in self.functionEvaluation['body'][ix]:
      for token in self.functionEvaluation['body'][ix]:
        if token['type'] == 'value':
        if token['type'] == 'value':
Line 1192... Line 1236...
  #
  #
  # Initialize the object.
  # Initialize the object.
  #
  #
  ################################################################################
  ################################################################################
 
 
  def __init__(self):
  def __init__(self,enableInterrupts):
    """
    """
    Initialize the tables definining the following:
    Initialize the tables definining the following:
      directly invokable instruction mnemonics and the associated opcodes
      directly invokable instruction mnemonics and the associated opcodes
      indirectly inivoked instruction mnemonics and the associated opcodes
      indirectly inivoked instruction mnemonics and the associated opcodes
        Note:  These are accessed through macros since they require an argument
        Note:  These are accessed through macros since they require an argument
Line 1204... Line 1248...
      directives (other than ".include")
      directives (other than ".include")
      macros with type restrictions for required arguments and defaults and
      macros with type restrictions for required arguments and defaults and
        restrictions for optional arguments\n
        restrictions for optional arguments\n
    Initialize lists and members to record memory attributes, stack lengths,
    Initialize lists and members to record memory attributes, stack lengths,
    body of the .main function, body of the optional .interrupt function,
    body of the .main function, body of the optional .interrupt function,
    current memory for variable definitions, etc.
    current memory for variable definitions, etc.\n
 
    If enableInterrupts is True, then also define the ".ena", ".dis", and
 
    ".returni" macros to enable and disable interrupts and to return from the
 
    interrupt handler.
    """
    """
 
 
    #
    #
    # Enumerate the directives
    # Enumerate the directives
    # Note:  The ".include" directive is handled within asmDef.FileBodyIterator.
    # Note:  The ".include" directive is handled within asmDef.FileBodyIterator.
Line 1247... Line 1294...
    self.AddInstruction('<<0',          0x001);
    self.AddInstruction('<<0',          0x001);
    self.AddInstruction('<<1',          0x002);
    self.AddInstruction('<<1',          0x002);
    self.AddInstruction('<<msb',        0x003);
    self.AddInstruction('<<msb',        0x003);
    self.AddInstruction('>r',           0x040);
    self.AddInstruction('>r',           0x040);
    self.AddInstruction('^',            0x052);
    self.AddInstruction('^',            0x052);
    #self.AddInstruction('dis',          0x01C);
 
    self.AddInstruction('drop',         0x054);
    self.AddInstruction('drop',         0x054);
    self.AddInstruction('dup',          0x008);
    self.AddInstruction('dup',          0x008);
    #self.AddInstruction('ena',          0x019);
 
    self.AddInstruction('inport',       0x030);
    self.AddInstruction('inport',       0x030);
    self.AddInstruction('lsb>>',        0x007);
    self.AddInstruction('lsb>>',        0x007);
    self.AddInstruction('msb>>',        0x006);
    self.AddInstruction('msb>>',        0x006);
    self.AddInstruction('nip',          0x053);
    self.AddInstruction('nip',          0x053);
    self.AddInstruction('nop',          0x000);
    self.AddInstruction('nop',          0x000);
Line 1334... Line 1379...
 
 
    self.memoryLength = dict();
    self.memoryLength = dict();
    self.stackLength = dict();
    self.stackLength = dict();
 
 
    #
    #
 
    # Conditional implementation of interrupts.
 
    #
 
 
 
    if type(enableInterrupts) != bool:
 
      raise Exception('Program Bug -- enableInterrupts must be a boolean');
 
    self.interruptsEnabled = enableInterrupts;
 
    if enableInterrupts:
 
      self.interrupt_dis_outport = 'O_INTERRUPT_DIS';
 
      self.interrupt_ena_outport = 'O_INTERRUPT_ENA';
 
      self.AddMacro('.dis',             2, []);
 
      self.AddMacro('.ena',             2, []);
 
      self.AddMacro('.returni',         3, []);
 
 
 
    #
    # Configure the containers for the expanded main, interrupt, function,
    # Configure the containers for the expanded main, interrupt, function,
    # macro, etc. definitions.
    # macro, etc. definitions.
    #
    #
 
 
    self.currentMemory = None;
    self.currentMemory = None;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.