forked from pret/pokeyellow
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'remotes/pokered/master'
- Loading branch information
Showing
16 changed files
with
3,279 additions
and
109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
Usage: python consts.py constants/some_constants.asm | ||
View numeric values of `const`ants. | ||
""" | ||
|
||
import sys | ||
import re | ||
|
||
const_value = 0 | ||
const_inc = 1 | ||
|
||
def asm_int(s): | ||
base = {'$': 16, '&': 8, '%': 2}.get(s[0], 10) | ||
return int(s if base == 10 else s[1:], base) | ||
|
||
def print_const(s, v): | ||
print(f'{s} == {v} == ${v:x}') | ||
|
||
def parse_for_constants(line): | ||
global const_value, const_inc | ||
if not (m := re.match(r'^\s+([A-Za-z_][A-Za-z0-9_@#]*)(?:\s+([^;\\n]+))?', line)): | ||
return | ||
macro, rest = m.groups() | ||
args = [arg.strip() for arg in rest.split(',')] if rest else [] | ||
if args and not args[-1]: | ||
args = args[:-1] | ||
if macro == 'const_def': | ||
const_value = asm_int(args[0]) if len(args) >= 1 else 0 | ||
const_inc = asm_int(args[1]) if len(args) >= 2 else 1 | ||
elif macro == 'const': | ||
print_const(args[0], const_value) | ||
const_value += const_inc | ||
elif macro == 'shift_const': | ||
print_const(args[0], 1 << const_value) | ||
print_const(args[0] + '_F', const_value) | ||
const_value += const_inc | ||
elif macro == 'const_skip': | ||
const_value += const_inc * (asm_int(args[0]) if len(args) >= 1 else 1) | ||
elif macro == 'const_next': | ||
const_value = asm_int(args[0]) | ||
|
||
def main(): | ||
if len(sys.argv) < 2: | ||
print(f'Usage: {sys.argv[0]} constants/some_constants.asm', file=sys.stderr) | ||
sys.exit(1) | ||
for filename in sys.argv[1:]: | ||
with open(filename, 'r', encoding='utf-8') as file: | ||
for line in file: | ||
parse_for_constants(line) | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#!/usr/bin/gawk -f | ||
|
||
# Usage: tools/free_space.awk [BANK=<bank_spec>] pokeyellow.map | ||
|
||
# The BANK argument allows printing free space in one, all, or none of the ROM's banks. | ||
# Valid arguments are numbers (in decimal "42" or hexadecimal "0x2a"), "all" or "none". | ||
# If not specified, defaults to "none". | ||
# The `BANK` argument MUST be before the map file name, otherwise it has no effect! | ||
# Yes: tools/free_space.awk BANK=all pokeyellow.map | ||
# No: tools/free_space.awk pokeyellow.map BANK=42 | ||
|
||
# Copyright (c) 2020, Eldred Habert. | ||
# SPDX-License-Identifier: MIT | ||
|
||
BEGIN { | ||
nb_banks = 0 | ||
free = 0 | ||
rom_bank = 0 # Safety net for malformed files | ||
|
||
# Default settings | ||
# Variables assigned via the command-line (except through `-v`) are *after* `BEGIN` | ||
BANK="none" | ||
} | ||
|
||
# Only accept ROM banks, ignore everything else | ||
toupper($0) ~ /^[ \t]*ROM[0X][ \t]+BANK[ \t]+#/ { | ||
nb_banks++ | ||
rom_bank = 1 | ||
split($0, fields, /[ \t]/) | ||
bank_num = strtonum(substr(fields[3], 2)) | ||
} | ||
|
||
function register_bank(amount) { | ||
free += amount | ||
rom_bank = 0 # Reject upcoming banks by default | ||
|
||
if (BANK ~ /all/ || BANK == bank_num) { | ||
printf "Bank %3d: %5d/16384 (%.2f%%)\n", bank_num, amount, amount * 100 / 16384 | ||
} | ||
} | ||
|
||
rom_bank && toupper($0) ~ /^[ \t]*EMPTY/ { | ||
# Empty bank | ||
register_bank(16384) | ||
} | ||
rom_bank && toupper($0) ~ /^[ \t]*SLACK:[ \t]/ { | ||
if ($2 ~ /\$[0-9A-F]+/) { | ||
register_bank(strtonum("0x" substr($2, 2))) | ||
} else { | ||
printf "Malformed slack line? \"%s\" does not start with '$'\n", $2 | ||
} | ||
} | ||
|
||
END { | ||
# Determine number of banks, by rounding to upper power of 2 | ||
total_banks = 2 # Smallest size is 2 banks | ||
while (total_banks < nb_banks) { | ||
total_banks *= 2 | ||
} | ||
|
||
# RGBLINK omits "trailing" ROM banks, so fake them | ||
bank_num = nb_banks | ||
while (bank_num < total_banks) { | ||
register_bank(16384) | ||
bank_num++ | ||
} | ||
|
||
total = total_banks * 16384 | ||
printf "Free space: %5d/%5d (%.2f%%)\n", free, total, free * 100 / total | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
""" | ||
Usage: python3 free_space.py [BANK=none] [pokeyellow.map] | ||
Calculate the free space in the ROM or its individual banks. | ||
The BANK argument allows printing free space in one, all, or none of the ROM's banks. | ||
Valid arguments are numbers (in decimal "42" or hexadecimal "0x2A"), "all" or "none". | ||
If not specified, defaults to "none". | ||
""" | ||
|
||
import sys | ||
|
||
from mapreader import MapReader | ||
|
||
def main(): | ||
print_bank = 'none' | ||
filename = 'pokeyellow.map' | ||
|
||
for arg in sys.argv[1:]: | ||
if arg.startswith('BANK='): | ||
print_bank = arg.split('=', 1)[-1] | ||
else: | ||
filename = arg | ||
|
||
if print_bank not in {'all', 'none'}: | ||
try: | ||
print_bank = (int(print_bank[2:], 16) | ||
if print_bank.startswith('0x') or print_bank.startswith('0X') | ||
else int(print_bank)) | ||
except ValueError: | ||
error = f'Error: invalid BANK: {print_bank}' | ||
if print_bank.isalnum(): | ||
error += f' (did you mean: 0x{print_bank}?)' | ||
print(error, file=sys.stderr) | ||
sys.exit(1) | ||
|
||
num_banks = 0x80 | ||
bank_size = 0x4000 # bytes | ||
total_size = num_banks * bank_size | ||
|
||
reader = MapReader() | ||
with open(filename, 'r', encoding='utf-8') as file: | ||
reader.read_map_data(file.readlines()) | ||
|
||
free_space = 0 | ||
per_bank = [] | ||
default_bank_data = {'sections': [], 'used': 0, 'slack': bank_size} | ||
for bank in range(num_banks): | ||
bank_data = reader.bank_data['ROM0 bank' if bank == 0 else 'ROMX bank'] | ||
data = bank_data.get(bank, default_bank_data) | ||
used, slack = data['used'], data['slack'] | ||
per_bank.append((used, slack)) | ||
free_space += slack | ||
|
||
free_percent = 100 * free_space / total_size | ||
print(f'Free space: {free_space}/{total_size} ({free_percent:.2f}%)') | ||
if print_bank != 'none': | ||
print() | ||
print('bank, used, free') | ||
for bank in range(num_banks): | ||
used, slack = per_bank[bank] | ||
if print_bank in {'all', bank}: | ||
print(f'${bank:02X}, {used}, {slack}') | ||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.