Exemple #1
0
        public ZMemory(byte[] data,
                       Action restart)
        {
            _restart = restart;
            Header   = new ZHeader(data.AsSpan(0, 31));
            if (Header.Version > 5)
            {
                throw new NotSupportedException("ZMachine > V5 not currently supported");
            }

            // Version specific offsets
            Offsets = VersionedOffsets.For(Header.Version);

            Manager = new MemoryManager(data);

            // ZMachine tables
            Abbreviations = new ZAbbreviations(Header, Manager);
            Dictionary    = new ZDictionary(Header, Manager, Abbreviations);
            ObjectTree    = new ZObjectTree(Header, Manager, Abbreviations);
            Globals       = new ZGlobals(Header, Manager);

            // Custom Stack with some abstractions for better testing.
            Stack = new ZStack();

            // Simple managers to abstract variable and argument usage
            VariableManager = new VariableManager(Stack, Globals);
            OperandManager  = new OperandManager(Manager, Stack, VariableManager);
        }
Exemple #2
0
        public ZObjectTree(ZHeader header,
                           IMemoryManager manager,
                           ZAbbreviations abbreviations)
        {
            _header = header;
            var objectTableData = manager.AsSpan(header.ObjectTable);// memory.AsSpan(header.ObjectTable);

            var(defaultProps, ptr) = GetDefaultProps(objectTableData);
            DefaultProperties      = defaultProps;

            var lastObject = false;

            ushort objNumber = 1;

            _dict = new Dictionary <ushort, IZMachineObject>();

            while (!lastObject && objNumber < 255)
            {
                // Objects end when the properties start!
                ushort objectAddress = (ushort)(header.ObjectTable + ptr);

                var min = _dict.Values.Any() ? _dict.Values.Min(v => v.PropertiesAddress) : ushort.MaxValue;
                lastObject = objectAddress >= min;
                if (!lastObject)
                {
                    var zObj = new ZMachineObject(objNumber, objectAddress, header, manager, abbreviations, DefaultProperties);
                    _dict.Add(objNumber, zObj);
                    ptr += zObj.BytesRead;

                    objNumber++;
                }
            }
        }
Exemple #3
0
        public ZsciiString(Span <byte> data, ZAbbreviations abbreviations, ZHeader header,
                           int zsciiWordsToUse = int.MaxValue)
        {
            _v2CharProvider = new V2CharProvider(abbreviations);
            _header         = header;
            var chars = GetZsciiChars(data, zsciiWordsToUse);

            BytesUsed = (ushort)(chars.Count / 3 * 2);

            String = DecodeZsciiChars(chars, abbreviations);
        }
Exemple #4
0
        public ZDictionary(ZHeader header, IMemoryManager manager, ZAbbreviations abbreviations)
        {
            var    bytes = manager.AsSpan(header.Dictionary);
            ushort addr  = 0;

            var numOfInputCodes = bytes[addr++];

            InputCodes = bytes.AsSpan(addr, numOfInputCodes).ToArray();
            addr      += numOfInputCodes;

            var zsciiStringArray = new ZsciiStringArray(bytes.AsSpan(addr), abbreviations, header);

            Words       = zsciiStringArray.Words;
            EntryLength = zsciiStringArray.EntryLength;
            WordStart   = (ushort)(addr + zsciiStringArray.WordStart);
        }
        public ZsciiStringArray(Span <byte> data, ZAbbreviations abbreviations, ZHeader header)
        {
            var bytes = data.ToArray();

            ushort ptr = 0;

            EntryLength = bytes[ptr++];
            var numEntries = bytes.GetUShort(ptr);

            ptr += 2;

            WordStart = ptr;

            Words = new string[numEntries];
            for (var i = 0; i < numEntries; i++)
            {
                var stringData = bytes.AsSpan(ptr);
                var zStr       = new ZsciiString(stringData, abbreviations, header, header.Version <= 3
                    ? 2 : 3);

                ptr     += EntryLength;
                Words[i] = zStr.String;
            }
        }
Exemple #6
0
        private string DecodeZsciiChars(List <byte> zChars, ZAbbreviations abbreviations)
        {
            _v2CharProvider.ResetTable();

            var sb = new StringBuilder();

            for (var i = 0; i < zChars.Count; i++)
            {
                if (zChars[i] == 0x00)
                {
                    sb.Append(" ");
                }
                else if (_header.Version <= 2)
                {
                    var zChar = zChars[i];

                    if (zChar == 1)
                    {
                        var abbrIdx = zChars[++i];
                        sb.Append(abbreviations.Abbreviations[abbrIdx]);
                    }
                    else
                    {
                        var(zCharTable, inc) = _v2CharProvider.GetCharTable(zChar);
                        i += inc;

                        if (i < zChars.Count)
                        {
                            zChar = zChars[i];
                            if (zChar == 6 && zCharTable[0] == ' ')
                            {
                                ushort x = (ushort)(zChars[i + 1] << 5 | zChars[i + 2]);
                                sb.Append(Convert.ToChar(x));
                                i += 2;
                            }

                            if (zChar > 5)
                            {
                                var realChar = zCharTable[zChar - 6];
                                sb.Append(realChar);
                            }
                        }
                    }
                }
//                else if (zChars[i] >= 0x01 && zChars[i] <= 0x03)
//                {
//                    ushort offset = (ushort)(32 * (chars[i] - 1) + chars[++i]);
//                    ushort lookup = (ushort)(_abbreviationsTable + (offset * 2));
//                    ushort wordAddr = GetWord(lookup);
//                    List<byte> abbrev = GetZsciiChars((ushort)(wordAddr * 2));
//                    sb.Append(DecodeZsciiChars(abbrev));
//                }
                //                else if (zChars[i] == 0x02 && _header.Version <= 2)
                //                {
                //                    sb.Append(Convert.ToChar((zChars[++i] - 6) + 'A'));
                //                }
                //                else if (zChars[i] == 0x03 && _header.Version <= 2)
                //                {
                //                    if (zChars.Count < i + 1)
                //                    {
                //                        sb.Append(Table[zChars[++i] - 6]);
                //                    }
                //                }
                //                else if (zChars[i] == 0x04 && _header.Version <= 2)
                //                {
                //                    sb.Append(Convert.ToChar((zChars[++i] - 6) + 'A'));
                //                }
                //                else if (zChars[i] == 0x05 && _header.Version <= 2)
                //                {
                //                    if (zChars.Count < i + 1)
                //                    {
                //                        sb.Append(Table[zChars[++i] - 6]);
                //                    }
                //                }
                else if (abbreviations != null && IsAbbreviation(zChars[i]))
                {
                    if (i + 1 <= zChars.Count - 1)
                    {
                        var offset = (ushort)(32 * (zChars[i] - 1) + zChars[++i]);
                        sb.Append(abbreviations.Abbreviations[offset]);
                    }
                }

                else if (zChars[i] == 0x04)
                {
                    sb.Append(Convert.ToChar((zChars[++i] - 6) + 'A'));
                }
                else if (zChars[i] == 0x05)
                {
                    if (i == zChars.Count - 1 || zChars[i + 1] == 0x05)
                    {
                        break;
                    }

                    if (zChars[i + 1] == 0x06)
                    {
                        var x = (ushort)(zChars[i + 2] << 5 | zChars[i + 3]);
                        i += 3;
                        sb.Append(Convert.ToChar(x));
                    }
                    else if (zChars[i + 1] == 0x07)
                    {
                        sb.AppendLine("");
                        i++;
                    }
                    else
                    {
                        sb.Append(Table[zChars[++i] - 6]);
                    }
                }
                else
                {
                    sb.Append(Convert.ToChar((zChars[i] - 6) + 'a'));
                }
            }

            return(sb.ToString());
        }
Exemple #7
0
 public static string Get(Span <byte> data, ZAbbreviations abbreviations, ZHeader header) => new ZsciiString(data, abbreviations, header).String;