summaryrefslogtreecommitdiff
path: root/extras/wram.py
diff options
context:
space:
mode:
Diffstat (limited to 'extras/wram.py')
m---------extras0
-rw-r--r--extras/wram.py313
2 files changed, 0 insertions, 313 deletions
diff --git a/extras b/extras
new file mode 160000
+Subproject dfe657177453423987544798d9763b2938874b4
diff --git a/extras/wram.py b/extras/wram.py
deleted file mode 100644
index b6d7fc6..0000000
--- a/extras/wram.py
+++ /dev/null
@@ -1,313 +0,0 @@
-# coding: utf-8
-"""
-RGBDS BSS section and constant parsing.
-"""
-
-import os
-
-
-def separate_comment(line):
- if ';' in line:
- i = line.find(';')
- return line[:i], line[i:]
- return line, None
-
-
-def rgbasm_to_py(text):
- return text.replace('$', '0x').replace('%', '0b')
-
-
-def make_wram_labels(wram_sections):
- wram_labels = {}
- for section in wram_sections:
- for label in section['labels']:
- if label['address'] not in wram_labels.keys():
- wram_labels[label['address']] = []
- wram_labels[label['address']] += [label['label']]
- return wram_labels
-
-def bracket_value(string, i=0):
- return string.split('[')[1 + i*2].split(']')[0]
-
-class BSSReader:
- """
- Read rgbasm BSS/WRAM sections and associate labels with addresses.
- Also reads constants/variables, even in macros.
- """
- sections = []
- section = None
- address = None
- macros = {}
- constants = {}
-
- section_types = {
- 'VRAM': 0x8000,
- 'SRAM': 0xa000,
- 'WRAM0': 0xc000,
- 'WRAMX': 0xd000,
- 'HRAM': 0xff80,
- }
-
- def __init__(self, *args, **kwargs):
- self.__dict__.update(kwargs)
-
- def read_bss_line(self, l):
- parts = l.strip().split(' ')
- token = parts[0].strip()
- params = ' '.join(parts[1:]).split(',')
-
- if token in ['ds', 'db', 'dw']:
- if any(params):
- length = eval(rgbasm_to_py(params[0]), self.constants.copy())
- else:
- length = {'ds': 1, 'db': 1, 'dw': 2}[token]
- self.address += length
- # assume adjacent labels to use the same space
- for label in self.section['labels'][::-1]:
- if label['length'] == 0:
- label['length'] = length
- else:
- break
-
- elif token in self.macros.keys():
- macro_text = '\n'.join(self.macros[token]) + '\n'
- for i, p in enumerate(params):
- macro_text = macro_text.replace('\\'+str(i+1),p)
- macro_text = macro_text.split('\n')
- macro_reader = BSSReader(
- sections = list(self.sections),
- section = dict(self.section),
- address = self.address,
- constants = self.constants,
- )
- macro_sections = macro_reader.read_bss_sections(macro_text)
- self.section = macro_sections[-1]
- if self.section['labels']:
- self.address = self.section['labels'][-1]['address'] + self.section['labels'][-1]['length']
-
-
- def read_bss_sections(self, bss):
-
- if self.section is None:
- self.section = {
- "labels": [],
- }
-
- if type(bss) is str:
- bss = bss.split('\n')
-
- macro = False
- macro_name = None
- for line in bss:
- line = line.lstrip()
- line, comment = separate_comment(line)
- line = line.strip()
- split_line = line.split()
- split_line_upper = map(str.upper, split_line)
-
- if not line:
- pass
-
- elif line[-4:].upper() == 'ENDM':
- macro = False
- macro_name = None
-
- elif macro:
- self.macros[macro_name] += [line]
-
- elif line[-5:].upper() == 'MACRO':
- macro_name = line.split(':')[0]
- macro = True
- self.macros[macro_name] = []
-
- elif 'INCLUDE' == line[:7].upper():
- filename = line.split('"')[1]
- self.read_bss_sections(open(filename).readlines())
-
- elif 'SECTION' == line[:7].upper():
- if self.section: # previous
- self.sections += [self.section]
-
- section_def = line.split(',')
- name = section_def[0].split('"')[1]
- type_ = section_def[1].strip()
- if len(section_def) > 2:
- bank = bracket_value(section_def[2])
- else:
- bank = None
-
- if '[' in type_:
- self.address = int(rgbasm_to_py(bracket_value(type_)), 16)
- else:
- if self.address == None or bank != self.section['bank'] or self.section['type'] != type_:
- self.address = self.section_types.get(type_, self.address)
- # else: keep going from this address
-
- self.section = {
- 'name': name,
- 'type': type_,
- 'bank': bank,
- 'start': self.address,
- 'labels': [],
- }
-
- elif ':' in line:
- # rgbasm allows labels without :, but prefer convention
- label = line[:line.find(':')]
- if '\\' in label:
- raise Exception, line + ' ' + label
- if ';' not in label:
- section_label = {
- 'label': label,
- 'address': self.address,
- 'length': 0,
- }
- self.section['labels'] += [section_label]
- self.read_bss_line(line.split(':')[-1])
-
- elif any(x in split_line_upper for x in ['EQU', '=', 'SET']): # TODO: refactor
- for x in ['EQU', '=', 'SET']:
- if x in split_line_upper:
- index = split_line_upper.index(x)
- real = split_line[index]
- name, value = map(' '.join, [split_line[:index], split_line[index+1:]])
- value = rgbasm_to_py(value)
- self.constants[name] = eval(value, self.constants.copy())
-
- else:
- self.read_bss_line(line)
-
- self.sections += [self.section]
- return self.sections
-
-def read_bss_sections(bss):
- reader = BSSReader()
- return reader.read_bss_sections(bss)
-
-
-def constants_to_dict(constants):
- """Deprecated. Use BSSReader."""
- return dict((eval(rgbasm_to_py(constant[constant.find('EQU')+3:constant.find(';')])), constant[:constant.find('EQU')].strip()) for constant in constants)
-
-def scrape_constants(text):
- if type(text) is not list:
- text = text.split('\n')
- bss = BSSReader()
- bss.read_bss_sections(text)
- constants = bss.constants
- return {v: k for k, v in constants.items()}
-
-def read_constants(filepath):
- """
- Load lines from a file and grab any constants using BSSReader.
- """
- lines = []
- if os.path.exists(filepath):
- with open(filepath, "r") as file_handler:
- lines = file_handler.readlines()
- return scrape_constants(lines)
-
-class WRAMProcessor(object):
- """
- RGBDS BSS section and constant parsing.
- """
-
- def __init__(self, config):
- """
- Setup for WRAM parsing.
- """
- self.config = config
-
- self.paths = {}
-
- if hasattr(self.config, "wram"):
- self.paths["wram"] = self.config.wram
- else:
- self.paths["wram"] = os.path.join(self.config.path, "wram.asm")
-
- if hasattr(self.config, "hram"):
- self.paths["hram"] = self.config.hram
- else:
- self.paths["hram"] = os.path.join(self.config.path, "hram.asm")
-
- if hasattr(self.config, "gbhw"):
- self.paths["gbhw"] = self.config.gbhw
- else:
- self.paths["gbhw"] = os.path.join(self.config.path, "gbhw.asm")
-
- def initialize(self):
- """
- Read constants.
- """
- self.setup_wram_sections()
- self.setup_wram_labels()
- self.setup_hram_constants()
- self.setup_gbhw_constants()
-
- self.reformat_wram_labels()
-
- def read_wram_sections(self):
- """
- Opens the wram file and calls read_bss_sections.
- """
- wram_content = None
- wram_file_path = self.paths["wram"]
-
- with open(wram_file_path, "r") as wram:
- wram_content = wram.readlines()
-
- wram_sections = read_bss_sections(wram_content)
- return wram_sections
-
- def setup_wram_sections(self):
- """
- Call read_wram_sections and set a variable.
- """
- self.wram_sections = self.read_wram_sections()
- return self.wram_sections
-
- def setup_wram_labels(self):
- """
- Make wram labels based on self.wram_sections as input.
- """
- self.wram_labels = make_wram_labels(self.wram_sections)
- return self.wram_labels
-
- def read_hram_constants(self):
- """
- Read constants from hram.asm using read_constants.
- """
- hram_constants = read_constants(self.paths["hram"])
- return hram_constants
-
- def setup_hram_constants(self):
- """
- Call read_hram_constants and set a variable.
- """
- self.hram_constants = self.read_hram_constants()
- return self.hram_constants
-
- def read_gbhw_constants(self):
- """
- Read constants from gbhw.asm using read_constants.
- """
- gbhw_constants = read_constants(self.paths["gbhw"])
- return gbhw_constants
-
- def setup_gbhw_constants(self):
- """
- Call read_gbhw_constants and set a variable.
- """
- self.gbhw_constants = self.read_gbhw_constants()
- return self.gbhw_constants
-
- def reformat_wram_labels(self):
- """
- Flips the wram_labels dictionary the other way around to access
- addresses by label.
- """
- self.wram = {}
-
- for (address, labels) in self.wram_labels.iteritems():
- for label in labels:
- self.wram[label] = address