proposal2.txt etc.

This commit is contained in:
~d6 2022-11-12 20:28:09 -05:00
parent c7515aab22
commit c8a29324e3
3 changed files with 193 additions and 1 deletions

80
extract-v2.py Normal file
View File

@ -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()

View File

@ -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

111
proposal2.txt Normal file
View File

@ -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