From c8a29324e37243218a150c441b2b45bb3b715ca0 Mon Sep 17 00:00:00 2001 From: d6 Date: Sat, 12 Nov 2022 20:28:09 -0500 Subject: [PATCH] proposal2.txt etc. --- extract-v2.py | 80 ++++++++++++++++++++++++++++++++++++ mksite.sh | 3 +- proposal2.txt | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 extract-v2.py create mode 100644 proposal2.txt diff --git a/extract-v2.py b/extract-v2.py new file mode 100644 index 0000000..3e84405 --- /dev/null +++ b/extract-v2.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +# currently only extracts text metadata + +import sys + +def error(msg): + print(msg) + sys.exit(1) + +def parsestr(data, start): + end = start + data[start:].find(b'\0') + return end + 1, data[start:end].decode('ascii') + +def parsefields(data, pos0): + pos1, name = parsestr(data, pos0) + pos2, version = parsestr(data, pos1) + pos3, author = parsestr(data, pos2) + pos4, desc = parsestr(data, pos3) + return {'name': name, 'version': version, 'author': author, 'desc': desc} + +def parse(data, pos0): + if len(data[pos0:]) < 6: + raise Exception('not enough data!') + a,b,c,d,e,f = data[pos0:pos0+6] + if a != 0xa0 or d != 0x80 or f != 0x37: + return None + else: + return (e, b, c) + +def toaddr(x, y): + return x * 256 + y - 256 + +def main(): + if len(sys.argv[1:]) != 1: + print('usage: %s ROMFILE' % sys.argv[0]) + sys.exit(1) + + f = open(sys.argv[1], 'rb') + data = f.read() + f.close() + + if len(data) < 6: + return error("file too small: %d bytes" % len(data)) + + (kind, x, y) = parse(data, 0) + if kind != 0xf0: + head = ''.join(['%02x' % n for n in data[0:6]]) + return error("file should start with 'a0____804037' but got %r" % head) + + icon_type = None + icon_data = None + + i = 6 + while True: + res = parse(data, i) + if res is None: + break + i += 6 + kind, x, y = res + xy = '%02x%02x' % (x, y) + if kind == 0xf2: + fields = parsefields(data, toaddr(x, y)) + print('fields: %r' % fields) + elif kind == 0xf4: + icon_type = x * 256 - y + print('icon type: %s' % xy) + elif kind == 0xf6: + # TODO: extract icon data as BMP or similar + print('icon data at %s' % xy) + elif kind == 0xf8: + print('maximum memory address is %s' % xy) + elif kind == 0xfa: + # TODO: parse manifest structure + print('manifest data at %s' % xy) + else: + print('unknown field: %02x (%s)' % (kind, xy)) + +if __name__ == "__main__": + main() diff --git a/mksite.sh b/mksite.sh index 14aacab..889cfbf 100755 --- a/mksite.sh +++ b/mksite.sh @@ -6,7 +6,8 @@ for NAME in about.txt asma.rom math32.tal test-math32.tal test-math32.py \ rainbow.tal drums.tal drums2.tal bfloat16.tal \ fix16.tal test-fix16.tal test-fix16.py \ tal-mode1.png tal.nanorc petscii.chr petscii.png petscii.html \ - tal-mode1.png tal.nanorc proposal.txt; + tal-mode1.png tal.nanorc \ + proposal.txt proposal2.txt extract-v2; do echo "-> $NAME" cp $NAME /var/www/plastic-idolatry.com/html/erik/nxu diff --git a/proposal2.txt b/proposal2.txt new file mode 100644 index 0000000..ec87df0 --- /dev/null +++ b/proposal2.txt @@ -0,0 +1,111 @@ +UXN ROM METADATA PROPOSAL v2 (wip) + +by d6 + +TL;DR SUMMARY + +i'm proposing a standardized "prelude" to uxn roms which can be used by +emulators but also by external programs to understand what a rom is and what +it can do. + +METADATA DEVICE + + PORT WIDTH NAME DESCRIPTION + f0 2 bytes version rom data/metadata version + f2 2 bytes fields address of text metadata fields + f4 2 bytes icon-type icon depth, transparency, and size + f6 2 bytes icon-data address of icon data + f8 2 bytes max-addr maximum memory address used + fa 2 bytes manifest potato manifest + fc 2 bytes unused + fe 2 bytes unused + +some requirements: + + - metadata writes must come before other writes + + writes must be: LIT2 ?? ?? LIT f? DEO2 (i.e. 6 bytes) + + writes to System/r, g, and b are treated as metadata + these are optional but provide hinting about icon rendering + they must have the form LIT2 ?? ?? LIT .System/r DEO2 + - version (f0) must come first + - after that, metadata writes can have any order + - this means roms with metadata have 6-48 bytes of header + + duplicate metadata writes will be ignored + + addresses in the zero page (i.e. 0000) are ignored + +this means that metadata parsers can read the header +in groups of six bytes. for example: + + - a0 WX YZ 80 f0 37 ( uxn version WXYZ ) + - a0 WX YZ 80 f2 37 ( metadata text fields start at address WXYZ ) + - a0 WX YZ 80 f4 37 ( icon depth, transparency, and size defined by WXYZ ) + - a0 WX YZ 80 f6 37 ( icon data starts at address WXYZ ) + - a0 WX YZ 80 f8 37 ( rom won't read/write addresses > WXYZ ) + - a0 WX YZ 80 fa 37 ( rom menu data starts at address WXYZ ) + +FIELD DESCRIPTIONS + +VERSION (f0) + +this is just a two byte value. my idea is to have a fixed first byte +for uxn (e.g. "u") and then use version numbers starting from 00, +which we would increase anytime we change the behavior of the VM +(either devices or opcodes). this would make it possible for emulators +to give good error messages when roms can't be supported. + +the first byte is present so that if someone later decides to fork uxn +they can choose a different letter. at that point how they use version +numbers is up to them (they could either do their own thing or follow +the uxn versions) but again it would make it easier to understand what +is going on. + +FIELDS (f2) + +this field is the address of the following four text fields: + + - name + - version + - author + - description + +the strings are each null-terminated, so the address should point to +the start of the name. fields can be empty. there is no fixed limit on +size but especially the first three fields should ideally fit on one +line of text. + +ICON TYPE (f4) + +icon depth, transparency, and size as specified by two bytes. + + bit 16: color 1 transparency (0x8000 transparent, 0x0000 opaque) + bits 15-10: unused + bit 9: color depth (0x0100 2-bit color, 0x0000 1-bit color) + bits 5-8: icon width in tiles (0x10 = 1 tile, 0x20 = 2 tiles, etc.) + bits 1-4: icon height in tiles (0x01 = 1 tile, 0x02 = 2 tiles, etc.) + +examples: + - 0x0000: no icon (0x0 icon size) + - 0x0011: 8x8 icons with 1-bit color and no transparency + - 0x8122: 16x16 icons with 2-bit color and transparency + - 0x8033: 24x24 icons with 2-bit color and no transparency + +ICON DATA (f6) + +this is a list of absolute addresses for tile data. its length is +determined by the dimensions specified in ICON TYPE. for example, if +icon type is 0x0022 (16x16 icon) then there would be 8 bytes +representing the addresses of 4 tiles. + +MAX ADDR (f8) + +this optional field lets a rom specificy the maximum address it will +read from or write to. currently it is purely informational but in the +future emulators could enforce this limit. it might also be useful for +an operating system running on varvara which is trying to +load/store/swap memory for multiple roms. + +MANIFEST (fa) + +this is the manifest data as specified by potato. + +see http://wiki.xxiivv.com/site/manifest.html