Skip to content

Commit

Permalink
added more tag functions in utility.lib
Browse files Browse the repository at this point in the history
  • Loading branch information
cnvogelg committed Jan 18, 2025
1 parent 5743c49 commit fcdb5c1
Show file tree
Hide file tree
Showing 8 changed files with 454 additions and 20 deletions.
1 change: 1 addition & 0 deletions amitools/vamos/lib/ExecLibrary.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from enum import IntEnum
from amitools.vamos.machine.regs import *
from amitools.vamos.libnative import MakeFuncs, InitStruct, MakeLib, LibFuncs, InitRes
from amitools.vamos.libcore import LibImpl
Expand Down
87 changes: 84 additions & 3 deletions amitools/vamos/lib/UtilityLibrary.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from math import trunc
from amitools.vamos.machine.regs import REG_D0, REG_D1, REG_A0, REG_A1
from amitools.vamos.astructs import APTR
from amitools.vamos.libcore import LibImpl
from amitools.vamos.libtypes import TagList, TagItem
from amitools.vamos.libtypes import TagList, TagItem, CommonTag, TagArray, Tag
from amitools.vamos.lib.util.AmiDate import *
from amitools.vamos.lib.util.flags import MapTagsFlag, FilterTagItemsFlag
from amitools.vamos.lib.lexec.flags import MemFlag
from amitools.vamos.log import *

from math import trunc


class UtilityLibrary(LibImpl):
def UDivMod32(self, ctx):
Expand Down Expand Up @@ -181,6 +182,86 @@ def FilterTagChanges(self, ctx, change_list: TagList, orig_list: TagList, apply)
elif apply:
orig_tag.set_data(tag_data)

def MapTags(self, ctx, tag_list: TagList, map_list: TagList, map_type):
if tag_list is None or map_list is None:
return
log_utility.info(
"MapTags(tag_list=%s, map_list=%s, map_type=%s)",
tag_list,
map_list,
map_type,
)
for tag in tag_list:
map_tag = map_list.find_tag(tag)
if map_tag:
log_utility.debug("map tag %s -> %s", tag, map_tag)
tag.set_tag(map_tag.get_data())
elif map_type == MapTagsFlag.MAP_REMOVE_NOT_FOUND:
log_utility.debug("remove tag %s", tag)
tag.remove()

def AllocateTagItems(self, ctx, num_tags) -> TagList:
log_utility.info("AllocateTagItems(num_tags=%s)", num_tags)
exec_lib = ctx.proxies.get_exec_lib_proxy()
size = num_tags * 8
addr = exec_lib.AllocVec(size, MemFlag.MEMF_CLEAR | MemFlag.MEMF_PUBLIC)
log_utility.info("addr=%08x", addr)
return TagList(ctx.mem, addr)

def CloneTagItems(self, ctx, tag_list: TagList) -> TagList:
log_utility.info("CloneTagItems(tag_list=%s)", tag_list)
num_items = len(tag_list)
log_utility.debug("num_items=%d", num_items)
new_tag_list = self.AllocateTagItems(ctx, num_items)
if new_tag_list is None:
return None
log_utility.debug("new_list=%s", new_tag_list)
tag_list.clone_to(new_tag_list)
return new_tag_list

def FreeTagItems(self, ctx, tag_list):
log_utility.info("FreeTagItems(addr=%08x)", tag_list)
exec_lib = ctx.proxies.get_exec_lib_proxy()
exec_lib.FreeVec(tag_list)

def RefreshTagItemClones(self, ctx, clone_list: TagList, orig_list: TagList):
log_utility.info(
"RefreshTagItemClones(clone=%s, orig=%s)", clone_list, orig_list
)
if clone_list is None:
return
if orig_list is None:
# if orig list is not available then clear clone
clone_list.get_first_tag().remove()
return
orig_list.clone_to(clone_list)

def TagInArray(self, ctx, tag_value, tag_array: TagArray):
log_utility.info("TagInArray(val=%08x, array=%s)", tag_value, tag_array)
return tag_array.find_tag(tag_value)

def FilterTagItems(self, ctx, tag_list: TagList, filter_array: TagArray, logic):
log_utility.info(
"FilterTagItems(tag_list=%s, filter_array=%s, logic=%s)",
tag_list,
filter_array,
logic,
)
valid = 0
for tag in tag_list:
found = filter_array.find_tag(tag)
if logic == FilterTagItemsFlag.TAGFILTER_AND:
if found:
valid += 1
else:
tag.remove()
elif logic == FilterTagItemsFlag.TAGFILTER_NOT:
if found:
tag.remove()
else:
valid += 1
return valid

# ---- Date -----

def Amiga2Date(self, ctx):
Expand Down
18 changes: 18 additions & 0 deletions amitools/vamos/lib/lexec/flags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from enum import IntFlag


class MemFlag(IntFlag):
MEMF_ANY = 0
MEMF_PUBLIC = 1 << 0
MEMF_CHIP = 1 << 1
MEMF_FAST = 1 << 2
MEMF_LOCAL = 1 << 8
MEMF_24BITDMA = 1 << 9
MEMF_KICK = 1 << 10

MEMF_CLEAR = 1 << 16
MEMF_LARGEST = 1 << 17
MEMF_REVERSE = 1 << 18
MEMF_TOTAL = 1 << 19

MEMF_NO_EXPUNGE = 1 << 31
11 changes: 11 additions & 0 deletions amitools/vamos/lib/util/flags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from enum import IntEnum


class MapTagsFlag(IntEnum):
MAP_REMOVE_NOT_FOUND = 0
MAP_KEEP_NOT_FOUND = 1


class FilterTagItemsFlag(IntEnum):
TAGFILTER_AND = 0
TAGFILTER_NOT = 1
2 changes: 1 addition & 1 deletion amitools/vamos/libtypes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
from .process import CLI, Process, PathList

# util
from .tag import CommonTag, TagItem, TagList
from .tag import CommonTag, TagItem, TagList, Tag, TagArray
from .dostag import DosTag
153 changes: 142 additions & 11 deletions amitools/vamos/libtypes/tag.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from enum import IntEnum
from amitools.vamos.astructs import ULONG
from amitools.vamos.libstructs import TagItemStruct


Expand All @@ -18,6 +19,33 @@ class CommonTag(IntEnum):
]


class Tag(ULONG):
def __repr__(self):
return f"TagItem(@{self.addr:08x})"

def get_tag(self, map_enum=None, do_map=True):
tag = self.get()
if do_map:
try:
tag = CommonTag(tag)
except ValueError:
if map_enum:
try:
tag = map_enum(tag)
except ValueError:
pass
return tag

def set_tag(self, tag):
self.set(tag)

def next_tag(self):
return Tag(self.mem, self.addr + 4)

def is_done(self):
return self.get() == CommonTag.TAG_DONE


class TagItem(TagItemStruct):
def __repr__(self):
return f"TagItem(@{self.addr:08x})"
Expand Down Expand Up @@ -57,23 +85,17 @@ def succ_real_tag(self):
if succ:
return succ.next_real_tag()

def next_tag(self):
return TagItem(self.mem, self.addr + 8)

def get_tuple(self, map_enum=None, do_map=True):
tag = self.get_tag(map_enum=map_enum, do_map=do_map)
data = self.data.val
return (tag, data)

def get_tag(self, map_enum=None, do_map=True):
tag = self.tag.val
if do_map:
try:
tag = CommonTag(tag)
except ValueError:
if map_enum:
try:
tag = map_enum(tag)
except ValueError:
pass
return tag
tag = Tag(mem=self.mem, addr=self.addr)
return tag.get_tag(map_enum=map_enum, do_map=do_map)

def get_data(self):
return self.data.val
Expand All @@ -87,6 +109,16 @@ def set_data(self, data):
def remove(self):
self.tag.val = CommonTag.TAG_IGNORE

def end_list(self):
self.tag.val = CommonTag.TAG_DONE

def clone_to(self, tag):
tag.set_tag(self.get_tag())
tag.set_data(self.get_data())

def has_same_tag_data(self, tag):
return self.get_tag() == tag.get_tag() and self.get_data() == tag.get_data()


class TagListIter:
def __init__(self, tag):
Expand Down Expand Up @@ -179,6 +211,13 @@ def get_tag_data(self, tag_val, def_value=0):
else:
return def_value

def clone_to(self, tag_list):
new_tag = tag_list.get_first_tag()
for tag in self:
print(tag, new_tag, tag.get_tag())
tag.clone_to(new_tag)
new_tag = new_tag.next_tag()

@classmethod
def alloc(cls, alloc, *tag_list, label=None):
tag_list = list(tag_list)
Expand Down Expand Up @@ -211,3 +250,95 @@ def free(self):
self._alloc.free_memory(self._mem_obj)
self._alloc = None
self._mem_obj = None


class TagArrayIter:
def __init__(self, tag):
self.tag = tag

def __iter__(self):
return self

def __next__(self):
if self.tag.is_done():
raise StopIteration()
result = self.tag
self.tag = self.tag.next_tag()
return result


class TagArray:
def __init__(self, mem, addr):
self._mem = mem
self._addr = addr
self._alloc = None
self._mem_obj = None

def get_addr(self):
return self._addr

def get_mem(self):
return self._mem

def __repr__(self):
return f"[TagArray,@{self._addr:08x}]"

def __iter__(self):
tag = Tag(self._mem, self._addr)
return TagArrayIter(tag)

def __len__(self):
num = 0
for tag in self:
num += 1
return num

def to_list(self, map_enum=None, do_map=True):
"""convert tag list to python list"""
result = []
for tag in self:
val = tag.get_tag(map_enum=map_enum, do_map=do_map)
result.append(val)
return result

def find_tag(self, tag_val):
"""find tag and return True/False"""
if isinstance(tag_val, TagItem):
tag_val = tag_val.tag.val

for tag in self:
if tag.get_tag() == tag_val:
return True
return False

@classmethod
def alloc(cls, alloc, *tag_array, label=None):
tag_array = list(tag_array)
num_tags = len(tag_array)
if num_tags == 0:
tag_array.append(CommonTag.TAG_DONE)
num_tags == 1
# auto add TAG DONE if missing
elif tag_array[-1] != CommonTag.TAG_DONE:
tag_array.append(CommonTag.TAG_DONE)
num_tags += 1
# size of tag list
num_bytes = num_tags * 4
mem_obj = alloc.alloc_memory(num_bytes, label=label)
mem = alloc.get_mem()
addr = mem_obj.addr
# fill list
for tag in tag_array:
mem.w32(addr, tag)
addr += 4

tag_array = cls(mem, mem_obj.addr)
tag_array._alloc = alloc
tag_array._mem_obj = mem_obj
return tag_array

def free(self):
if self._alloc and self._mem_obj:
self._alloc.free_memory(self._mem_obj)
self._alloc = None
self._mem_obj = None
Loading

0 comments on commit fcdb5c1

Please sign in to comment.