OpenCores
URL https://opencores.org/ocsvn/z3/z3/trunk

Subversion Repositories z3

[/] [z3/] [trunk/] [utils/] [zops.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 charcole
#include "common.h"
2
#include "file.h"
3
#include "mem.h"
4
#include "random.h"
5
#include "stack.h"
6
#include <ctype.h>
7
#include "SDL.h"
8
 
9
#define MAX_TOKEN_LEN 256
10
#define USE_BIOS 1
11
 
12
u16 randomseed=1;
13
 
14
enum
15
{
16
        SrcImmediate,
17
        SrcVariable
18
};
19
 
20
enum
21
{
22
        Form0OP,
23
        Form1OP,
24
        Form2OP,
25
        FormVAR
26
};
27
 
28
static int zeroOpStoreInstructions[]={};
29
static int oneOpStoreInstructions[]={0x01,0x02,0x03,0x04,0x08,0x0E,0x0F};
30
static int twoOpStoreInstructions[]={0x08,0x09,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
31
static int varOpStoreInstructions[]={0x00,0x07,0x0C,0x16,0x17,0x18,0x1E};
32
 
33
static int zeroOpBranchInstructions[]={0x05,0x06,0x0D};
34
static int oneOpBranchInstructions[]={0x00,0x01,0x02};
35
static int twoOpBranchInstructions[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x0A};
36
static int varOpBranchInstructions[]={0x17};
37
 
38
static char alphabetLookup[3][27]={
39
        { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' },
40
        { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' },
41
        { ' ', '\n','0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', ',', '!', '?', '_', '#', '\'','"', '/', '\\','-', ':', '(', ')' },
42
};
43
 
44
typedef struct ZOperand_s
45
{
46
        int value;
47
        int src;
48
} ZOperand;
49
 
50
typedef struct ZBranch_s
51
{
52
        int offset;
53
        int negate;
54
} ZBranch;
55
 
56
typedef struct ZInstruction_s
57
{
58
        int op;
59
        int form;
60
        int store;
61
        int numOps;
62
        ZBranch branch;
63
        ZOperand operands[4];
64
} ZInstruction;
65
 
66
typedef struct ZCallStack_s
67
{
68
        int returnAddr;
69
        int returnStore;
70
        int locals[16];
71
        int depth;
72
} ZCallStack;
73
 
74
typedef struct ZObject_s
75
{
76
        int addr;
77
        int propTable;
78
} ZObject;
79
 
80
typedef struct ZProperty_s
81
{
82
        int addr;
83
        int size;
84
        int bDefault;
85
} ZProperty;
86
 
87
typedef struct ZToken_s
88
{
89
        char token[MAX_TOKEN_LEN];
90
        int offset;
91
} ZToken;
92
 
93
typedef struct ZDictEntry_s
94
{
95
        int coded[4];
96
        int current;
97
} ZDictEntry;
98
 
99
typedef char byte;
100
 
101
static ZInstruction m_ins;
102
static int m_pc;
103
static int m_globalVariables;
104
static int m_abbrevTable;
105
static int m_objectTable;
106
static int m_dictionaryTable;
107
static int m_memSize;
108
static int m_memOffset;
109
static byte *rom;
110
static byte *memory;
111
static byte *biosRAM;
112
static u16 *screen;
113
static int m_numberstack[1024];
114
static stack m_stack;
115
static ZCallStack m_callstackcontents[1024];
116
static stack m_callStack;
117
 
118
int forceDynamic=0;
119
int curIdx=0;
120
int curX=0;
121
int curY=0;
122
int winXMin=0;
123
int winXMax=240-1;
124
int winYMin=0;
125
int winYMax=320-1;
126
SDL_Window *window;
127
SDL_Renderer *ren;
128
SDL_Texture *tex;
129
int mouseDown=0;
130
int mouseX=0;
131
int mouseY=0;
132
 
133
byte ReadMem(int addr)
134
{
135
        return memory[addr+m_memOffset];
136
}
137
 
138
void WriteMem(int addr, byte val)
139
{
140
        memory[addr+m_memOffset]=val;
141
}
142
 
143
byte ReadMemDyn(int addr)
144
{
145
        if (addr>=0x10000 && forceDynamic)
146
                return biosRAM[addr-0x10000];
147
        return memory[addr+m_memOffset];
148
}
149
 
150
void displayState();
151
 
152
void WriteMemDyn(int addr, byte val)
153
{
154
        if (addr>=0x10000)
155
        {
156
                if (1)//forceDynamic)
157
                        biosRAM[addr-0x10000]=val;
158
                else
159
                {
160
                        printf("Bad write:%x (PC:%x)\n", addr, m_pc);
161
                        displayState();
162
                }
163
        }
164
        else
165
        {
166
                memory[addr+m_memOffset]=val;
167
        }
168
}
169
 
170
int makeS16(int msb, int lsb)
171
{
172
        int ret=(msb<<8)+lsb;
173
        if ((ret&0x8000)!=0)
174
        {
175
                ret+=-0x10000;
176
        }
177
        return ret;
178
}
179
 
180
int makeU16(int msb, int lsb)
181
{
182
        return (msb<<8)+lsb;
183
}
184
 
185
int readBytePC()
186
{
187
        return ReadMem(m_pc++)&0xFF;
188
}
189
 
190
int readS16PC()
191
{
192
        int msb=readBytePC();
193
        int lsb=readBytePC();
194
        return makeS16(msb, lsb);
195
}
196
 
197
int readVariable(int var)
198
{
199
        if (var==0)
200
        {
201
                return *(int*)stackPop(&m_stack);
202
        }
203
        if (var<16)
204
        {
205
                return ((ZCallStack*)stackPeek(&m_callStack))->locals[var-1];
206
        }
207
        int off=2*(var-16);
208
        off+=m_globalVariables;
209
        return makeS16(ReadMem(off)&0xFF, ReadMem(off+1)&0xFF);
210
}
211
 
212
void setVariable(int var, int value)
213
{
214
        value&=0xFFFF;
215
        if ((value&0x8000)!=0)
216
        {
217
                value+=-0x10000;
218
        }
219
        if (var==0)
220
        {
221
                *(int*)stackPush(&m_stack)=value;
222
                return;
223
        }
224
        if (var<16)
225
        {
226
                ((ZCallStack*)stackPeek(&m_callStack))->locals[var-1]=value;
227
                return;
228
        }
229
        int off=2*(var-16);
230
        off+=m_globalVariables;
231
        WriteMem(off+0,(byte)((value&0xFF00)>>8));
232
        WriteMem(off+1,(byte)((value&0x00FF)>>0));
233
}
234
 
235
void setVariableIndirect(int var, int value)
236
{
237
        if (var==0)
238
        {
239
                stackPop(&m_stack);
240
        }
241
        setVariable(var, value);
242
}
243
 
244
int readVariableIndirect(int var)
245
{
246
        int ret=readVariable(var);
247
        if (var==0)
248
        {
249
                setVariable(var, ret);
250
        }
251
        return ret;
252
}
253
 
254
ZObject getObject(int id)
255
{
256
        ZObject ret;
257
        ret.addr=m_objectTable+2*31+9*(id-1);
258
        ret.propTable=makeU16(ReadMem(ret.addr+7)&0xFF, ReadMem(ret.addr+8)&0xFF);
259
        return ret;
260
}
261
 
262
ZProperty getProperty(ZObject obj, int id)
263
{
264
        ZProperty ret;
265
        int address=obj.propTable;
266
        int textLen=ReadMem(address++)&0xFF;
267
        address+=textLen*2;
268
        while (ReadMem(address)!=0)
269
        {
270
                int sizeId=ReadMem(address++)&0xFF;
271
                int size=1+(sizeId>>5);
272
                int propId=sizeId&31;
273
                if (propId==id)
274
                {
275
                        ret.addr=address;
276
                        ret.size=size;
277
                        ret.bDefault=FALSE;
278
                        return ret;
279
                }
280
                address+=size;
281
        }
282
        ret.addr=(m_objectTable+(id-1)*2)&0xFFFF;
283
        ret.size=2;
284
        ret.bDefault=TRUE;
285
        return ret;
286
}
287
 
288
void returnRoutine(int value)
289
{
290
        ZCallStack *cs=stackPop(&m_callStack);
291
        while (cs->depth<stackDepth(&m_stack))
292
        {
293
                readVariable(0);
294
        }
295
        if (cs->returnStore>=0)
296
        {
297
                setVariable(cs->returnStore, value);
298
        }
299
        m_pc=cs->returnAddr;
300
        if (cs->returnStore==-2)
301
        {
302
                returnRoutine(1);
303
        }
304
}
305
 
306
void doBranch(int cond, ZBranch branch)
307
{
308
        if (branch.negate)
309
        {
310
                cond=!cond;
311
        }
312
        if (cond)
313
        {
314
                if (branch.offset==0)
315
                        returnRoutine(0);
316
                else if (branch.offset==1)
317
                        returnRoutine(1);
318
                else
319
                        m_pc+=branch.offset-2;
320
        }
321
}
322
 
323
void readOperand(int operandType)
324
{
325
        if (operandType==3) //omitted
326
        {
327
                return;
328
        }
329
        ZOperand *operand = &m_ins.operands[m_ins.numOps++];
330
        switch (operandType)
331
        {
332
                case 0: // long constant
333
                        operand->value = readS16PC();
334
                        operand->src = SrcImmediate;
335
                        break;
336
                case 1: // small constant
337
                        operand->value = readBytePC();
338
                        operand->src = SrcImmediate;
339
                        break;
340
                case 2: // variable
341
                        operand->value = readVariable(readBytePC());
342
                        operand->src = SrcVariable;
343
                        break;
344
        }
345
}
346
 
347
void readShortForm(int opcode)
348
{
349
        int operand=(opcode>>4)&3;
350
        int op=opcode&15;
351
        m_ins.op=op;
352
        if (operand==3)
353
                m_ins.form=Form0OP;
354
        else
355
                m_ins.form=Form1OP;
356
        readOperand(operand);
357
}
358
 
359
void readLongForm(int opcode)
360
{
361
        int op=opcode&31;
362
        m_ins.op=op;
363
        m_ins.form=Form2OP;
364
        readOperand(((opcode&(1<<6))!=0)?2:1);
365
        readOperand(((opcode&(1<<5))!=0)?2:1);
366
}
367
 
368
void readVariableForm(int opcode)
369
{
370
        int op=opcode&31;
371
        int operandTypes=readBytePC();
372
        int i;
373
        m_ins.op=op;
374
        if ((opcode&0xF0)>=0xE0)
375
                m_ins.form=FormVAR;
376
        else
377
                m_ins.form=Form2OP;
378
        for (i=3; i>=0; i--)
379
        {
380
                readOperand((operandTypes>>(2*i))&3);
381
        }
382
}
383
 
384
int readStoreInstruction(int *match, int length, int op)
385
{
386
        int i;
387
        for (i=0; i<length; i++)
388
        {
389
                if (op==match[i])
390
                {
391
                        return readBytePC();
392
                }
393
        }
394
        return -1;
395
}
396
 
397
ZBranch readBranchInstruction(int *match, int length, int op)
398
{
399
        ZBranch ret;
400
        int i;
401
        for (i=0; i<length; i++)
402
        {
403
                if (op==match[i])
404
                {
405
                        int branch1=readBytePC();
406
                        if ((branch1&(1<<6))==0)
407
                        {
408
                                int branch2=readBytePC();
409
                                int offset=((branch1&63)<<8)+branch2;
410
                                if ((offset&(1<<13))!=0)
411
                                {
412
                                        offset+=-(1<<14);
413
                                }
414
                                ret.offset=offset;
415
                                ret.negate=((branch1&0x80)==0);
416
                                return ret;
417
                        }
418
                        else
419
                        {
420
                                ret.offset=branch1&63;
421
                                ret.negate=((branch1&0x80)==0);
422
                                return ret;
423
                        }
424
                }
425
        }
426
        ret.offset=0;
427
        ret.negate=FALSE;
428
        return ret;
429
}
430
 
431
void callRoutine(int address, int returnStore, int setOperands)
432
{
433
        if (address==0)
434
        {
435
                setVariable(returnStore, 0);
436
        }
437
        else
438
        {
439
                int numLocals=ReadMem(address++)%0xFF;
440
                int i;
441
                ZCallStack cs;
442
                cs.returnAddr=m_pc;
443
                cs.returnStore=returnStore;
444
                for (i=0; i<numLocals; i++)
445
                {
446
                        cs.locals[i]=makeS16(ReadMem(address)&0xFF, ReadMem(address+1)&0xFF);
447
                        address+=2;
448
                }
449
                if (setOperands)
450
                {
451
                        for (i=0; i<m_ins.numOps-1; i++)
452
                        {
453
                                cs.locals[i]=m_ins.operands[i+1].value;
454
                        }
455
                }
456
                cs.depth=stackDepth(&m_stack);
457
                m_pc=address;
458
                *(ZCallStack*)stackPush(&m_callStack)=cs;
459
        }
460
}
461
 
462
void callBIOS(int id, int doubleReturn)
463
{
464
        int addr=0x1E58B+5*id;
465
        callRoutine(2*makeU16(ReadMem(addr)&0xFF,ReadMem(addr+1)&0xFF), doubleReturn?-2:-1, TRUE);
466
}
467
 
468
void displayState()
469
{
470
        int i;
471
        printf("Next PC:%x\n", m_pc);
472
        printf("Form:%d Opcode:%d\n", m_ins.form, m_ins.op);
473
        printf("Num operands: %d\n", m_ins.numOps);
474
        for (i=0; i<m_ins.numOps; i++)
475
        {
476
                printf("Value:%d Src:%d\n", m_ins.operands[i].value, m_ins.operands[i].src);
477
        }
478
        printf("Store:%d Branch:%d %s\n", m_ins.store, m_ins.branch.offset, (m_ins.branch.negate?" Negated":" Normal"));
479
}
480
 
481
void dumpCurrentInstruction()
482
{
483
        int i;
484
        for (i=0; i<m_ins.numOps; i++)
485
        {
486
                printf("Arg:%d Value:%d\n", i, (m_ins.operands[i].value&0xFFFF));
487
        }
488
}
489
 
490
void haltInstruction()
491
{
492
        printf("\n\nUnimplemented instruction!\n");
493
        displayState();
494
        exit(1);
495
}
496
 
497
void illegalInstruction()
498
{
499
        printf("\n\nIllegal instruction!\n");
500
        displayState();
501
        exit(1);
502
}
503
 
504
int printText(int address)
505
{
506
        int pair1=0, pair2=0;
507
        int alphabet=0;
508
        int characters[3];
509
        int abbrNext=FALSE;
510
        int longNext=0;
511
        int longChar=0;
512
        int abbrChar=0;
513
        while ((pair1&0x80)==0)
514
        {
515
                int i;
516
                pair1=ReadMem(address++)&0xFF;
517
                pair2=ReadMem(address++)&0xFF;
518
                characters[0]=(pair1&0x7C)>>2;
519
                characters[1]=((pair1&3)<<3) + ((pair2&0xE0)>>5);
520
                characters[2]=pair2&0x1F;
521
                for (i=0; i<3; i++)
522
                {
523
                        if (longNext>0)
524
                        {
525
                                longChar<<=5;
526
                                longChar&=0x3FF;
527
                                longChar|=characters[i];
528
                                longNext--;
529
                                if (longNext==0)
530
                                {
531
                                        printf("%c", (char)longChar);
532
                                }
533
                        }
534
                        else if (!abbrNext)
535
                        {
536
                                if (characters[i]==6 && alphabet==2)
537
                                {
538
                                        longNext=2;
539
                                }
540
                                else if (characters[i]>=6)
541
                                {
542
                                        characters[i]-=6;
543
                                        printf("%c", alphabetLookup[alphabet][characters[i]]);
544
                                        alphabet=0;
545
                                }
546
                                else if (characters[i]==4)
547
                                {
548
                                        alphabet=1;
549
                                }
550
                                else if (characters[i]==5)
551
                                {
552
                                        alphabet=2;
553
                                }
554
                                else if (characters[i]==0)
555
                                {
556
                                        printf(" ");
557
                                }
558
                                else
559
                                {
560
                                        abbrChar=characters[i];
561
                                        abbrNext=TRUE;
562
                                }
563
                        }
564
                        else
565
                        {
566
                                int idx=32*(abbrChar-1)+characters[i];
567
                                int abbrevTable=m_abbrevTable+2*idx;
568
                                int abbrevAddress=makeU16(ReadMem(abbrevTable)&0xFF, ReadMem(abbrevTable+1)&0xFF);
569
                                printText(2*abbrevAddress);
570
                                abbrNext=FALSE;
571
                        }
572
                }
573
        }
574
        return address;
575
}
576
 
577
void removeObject(int childId)
578
{
579
        ZObject child=getObject(childId);
580
        int parentId=ReadMem(child.addr+4)&0xFF;
581
        if (parentId!=0)
582
        {
583
                ZObject parent=getObject(parentId);
584
                if ((ReadMem(parent.addr+6)&0xFF)==childId)
585
                {
586
                        WriteMem(parent.addr+6,ReadMem(child.addr+5)); // parent.child=child.sibling
587
                }
588
                else
589
                {
590
                        int siblingId=ReadMem(parent.addr+6)&0xFF;
591
                        while (siblingId!=0)
592
                        {
593
                                ZObject sibling=getObject(siblingId);
594
                                int nextSiblingId=ReadMem(sibling.addr+5)&0xFF;
595
                                if (nextSiblingId==childId)
596
                                {
597
                                        WriteMem(sibling.addr+5,ReadMem(child.addr+5)); // sibling.sibling=child.sibling
598
                                        break;
599
                                }
600
                                siblingId=nextSiblingId;
601
                        }
602
                        if (siblingId==0)
603
                        {
604
                                illegalInstruction();
605
                        }
606
                }
607
                WriteMem(child.addr+4,0);
608
                WriteMem(child.addr+5,0);
609
        }
610
}
611
 
612
void addChild(int parentId, int childId)
613
{
614
        ZObject child=getObject(childId);
615
        ZObject parent=getObject(parentId);
616
        WriteMem(child.addr+5,ReadMem(parent.addr+6)); // child.sibling=parent.child
617
        WriteMem(child.addr+4,(byte)parentId); // child.parent=parent
618
        WriteMem(parent.addr+6,(byte)childId); // parent.child=child
619
}
620
 
621
void zDictInit(ZDictEntry *entry)
622
{
623
        entry->current=0;
624
        entry->coded[0]=0;
625
        entry->coded[1]=0;
626
        entry->coded[2]=0x80;
627
        entry->coded[3]=0;
628
}
629
 
630
void zDictAddCharacter(ZDictEntry *entry, int code)
631
{
632
        code&=31;
633
        switch (entry->current)
634
        {
635
                case 0: entry->coded[0]|=code<<2; break;
636
                case 1: entry->coded[0]|=code>>3; entry->coded[1]|=(code<<5)&0xFF; break;
637
                case 2: entry->coded[1]|=code; break;
638
                case 3: entry->coded[2]|=code<<2; break;
639
                case 4: entry->coded[2]|=code>>3; entry->coded[3]|=(code<<5)&0xFF; break;
640
                case 5: entry->coded[3]|=code; break;
641
        }
642
        entry->current++;
643
}
644
 
645
ZDictEntry encodeToken(char* token)
646
{
647
        ZDictEntry ret;
648
        int tokenLen=strlen(token);
649
        int t;
650
        zDictInit(&ret);
651
        for (t=0; t<tokenLen; t++)
652
        {
653
                char curChar = token[t];
654
                int alphabet=-1;
655
                int code=-1;
656
                int a;
657
                for (a=0; a<3 && alphabet==-1; a++)
658
                {
659
                        int i;
660
                        for (i=0; i<27; i++)
661
                        {
662
                                if (curChar == alphabetLookup[a][i])
663
                                {
664
                                        alphabet=a;
665
                                        code=i;
666
                                        break;
667
                                }
668
                        }
669
                }
670
                if (alphabet==-1)
671
                {
672
                        zDictAddCharacter(&ret, 5);
673
                        zDictAddCharacter(&ret, 6);
674
                        zDictAddCharacter(&ret, curChar>>5);
675
                        zDictAddCharacter(&ret, curChar&31);
676
                }
677
                else
678
                {
679
                        if (alphabet>0)
680
                        {
681
                                int shift=alphabet+3;
682
                                zDictAddCharacter(&ret, shift);
683
                        }
684
                        zDictAddCharacter(&ret, code+6);
685
                }
686
        }
687
        for (t=0; t<6; t++) // pad
688
        {
689
                zDictAddCharacter(&ret, 5);
690
        }
691
        return ret;
692
}
693
 
694
int getDictionaryAddress(char* token, int dictionary)
695
{
696
        int entryLength = ReadMem(dictionary++)&0xFF;
697
        int numEntries = makeU16(ReadMem(dictionary+0)&0xFF, ReadMem(dictionary+1)&0xFF);
698
        ZDictEntry zde = encodeToken(token);
699
        int i;
700
        dictionary+=2;
701
        for (i=0; i<numEntries; i++)
702
        {
703
                if (zde.coded[0]==(ReadMem(dictionary+0)&0xFF) && zde.coded[1]==(ReadMem(dictionary+1)&0xFF)
704
                                && zde.coded[2]==(ReadMem(dictionary+2)&0xFF) && zde.coded[3]==(ReadMem(dictionary+3)&0xFF))
705
                {
706
                        return dictionary;
707
                }
708
                dictionary+=entryLength;
709
        }
710
        return 0;
711
}
712
 
713
int lexicalAnalysis(char* input, int parseBuffer, int maxEntries)
714
{
715
        static ZToken tokens[256];
716
        static char seps[256];
717
        int numTokens=0;
718
        int dictionaryAddress=m_dictionaryTable;
719
        int numSeperators=ReadMem(dictionaryAddress++);
720
        char *current=input;
721
        char *end=input+strlen(current);
722
        int i;
723
        for (i=0; i<numSeperators; i++)
724
        {
725
                seps[i]=(char)ReadMem(dictionaryAddress++);
726
        }
727
        while (current!=end)
728
        {
729
                char *space=strchr(current, ' ');
730
                char *min=end;
731
                int sepFound=FALSE;
732
                int tokLen;
733
                if (space==current)
734
                {
735
                        current++;
736
                        continue;
737
                }
738
                else if (space)
739
                {
740
                        min=space;
741
                }
742
                for (i=0; i<numSeperators; i++)
743
                {
744
                        char *sep=strchr(current, seps[i]);
745
                        if (sep==current)
746
                        {
747
                                tokens[numTokens].offset=current-input;
748
                                tokens[numTokens].token[0]=*current;
749
                                tokens[numTokens].token[1]='\0';
750
                                numTokens++;
751
                                current++;
752
                                sepFound=TRUE;
753
                                break;
754
                        }
755
                        else if (sep && sep<min)
756
                        {
757
                                min=sep;
758
                        }
759
                }
760
                if (sepFound)
761
                {
762
                        continue;
763
                }
764
 
765
                tokens[numTokens].offset=(int)(current-input);
766
                tokLen=MIN(min-current, MAX_TOKEN_LEN-1);
767
                strncpy(tokens[numTokens].token, current, tokLen);
768
                tokens[numTokens].token[tokLen]='\0';
769
                numTokens++;
770
                current=min;
771
        }
772
 
773
        for (i=0; i<numTokens && i<maxEntries; i++)
774
        {
775
                int outAddress=getDictionaryAddress(tokens[i].token, dictionaryAddress);
776
                WriteMem(parseBuffer++,(byte)((outAddress>>8)&0xFF));
777
                WriteMem(parseBuffer++,(byte)((outAddress>>0)&0xFF));
778
                WriteMem(parseBuffer++,(byte)strlen(tokens[i].token));
779
                WriteMem(parseBuffer++,(byte)(tokens[i].offset+1));
780
        }
781
 
782
        return MIN(maxEntries, numTokens);
783
}
784
 
785
void restart()
786
{
787
        memcpy(memory, rom, m_memSize);
788
        memset(biosRAM, 0, 0x10000);
789
        ASSERT(ReadMem(0)==3);
790
        m_globalVariables=makeU16(ReadMem(0xC)&0xFF, ReadMem(0xD)&0xFF);
791
        m_abbrevTable=makeU16(ReadMem(0x18)&0xFF, ReadMem(0x19)&0xFF);
792
        m_objectTable=makeU16(ReadMem(0xA)&0xFF, ReadMem(0xB)&0xFF);
793
        m_dictionaryTable=makeU16(ReadMem(0x8)&0xFF, ReadMem(0x9)&0xFF);
794
        m_pc=makeU16(ReadMem(6)&0xFF, ReadMem(7)&0xFF);
795
        //WriteMem(1,ReadMem(1)|(1<<4)); // status line not available
796
        //WriteMem(1,ReadMem(1)&~(1<<5)); // screen splitting available
797
        //WriteMem(1,ReadMem(1)&~(1<<6)); // variable pitch font
798
        //WriteMem(0x10,ReadMem(0x10)|(1<<0)); // transcripting
799
        //WriteMem(0x10,ReadMem(0x10)|(1<<1)); // fixed font
800
        stackInit(&m_stack, m_numberstack, sizeof(m_numberstack[0]), ARRAY_SIZEOF(m_numberstack));
801
        stackInit(&m_callStack, m_callstackcontents, sizeof(m_callstackcontents[0]), ARRAY_SIZEOF(m_callstackcontents));
802
#if USE_BIOS
803
        callBIOS(0,FALSE);
804
#endif
805
}
806
 
807
void process0OPInstruction()
808
{
809
        switch (m_ins.op)
810
        {
811
                case 0: //rtrue
812
                        returnRoutine(1);
813
                        break;
814
                case 1: //rfalse
815
                        returnRoutine(0);
816
                        break;
817
                case 2: //print
818
                        {
819
#if !USE_BIOS
820
                                m_pc=printText(m_pc);
821
#else
822
                                int origAddr=m_pc;
823
                                while (!(ReadMem(m_pc)&0x80))
824
                                {
825
                                        m_pc+=2;
826
                                }
827
                                m_pc+=2;
828
                                m_ins.operands[1].value=origAddr&1;
829
                                m_ins.operands[2].value=origAddr>>1;
830
                                m_ins.numOps=3;
831
                                callBIOS(1,FALSE);
832
#endif
833
                                break;
834
                        }
835
                case 3: //print_ret
836
                        {
837
#if !USE_BIOS
838
                                m_pc=printText(m_pc);
839
                                printf("\n");
840
                                returnRoutine(1);
841
#else
842
                                int origAddr=m_pc;
843
                                while (!(ReadMem(m_pc)&0x80))
844
                                {
845
                                        m_pc+=2;
846
                                }
847
                                m_pc+=2;
848
                                m_ins.operands[1].value=(origAddr&1)|2;
849
                                m_ins.operands[2].value=origAddr>>1;
850
                                m_ins.numOps=3;
851
                                callBIOS(1,TRUE);
852
#endif
853
                                break;
854
                        }
855
                case 4: //nop
856
                        break;
857
                case 5: //save
858
                        doBranch(FALSE, m_ins.branch);
859
                        break;
860
                case 6: //restore
861
                        doBranch(FALSE, m_ins.branch);
862
                        break;
863
                case 7: //restart
864
                        restart();
865
                        break;
866
                case 8: //ret_popped
867
                        returnRoutine(*(int*)stackPop(&m_stack));
868
                        break;
869
                case 9: //pop
870
                        stackPop(&m_stack);
871
                        break;
872
                case 0xA: //quit
873
#if !USE_BIOS
874
                        haltInstruction();
875
#else
876
                        callBIOS(6,FALSE);
877
#endif
878
                        break;
879
                case 0xB: //new_line
880
#if !USE_BIOS
881
                        printf("\n");
882
#else
883
                        m_ins.operands[1].value='\n';
884
                        m_ins.numOps=2;
885
                        callBIOS(2,FALSE);
886
#endif
887
                        break;
888
                case 0xC: //show_status
889
#if !USE_BIOS
890
                        haltInstruction();
891
#else
892
                        callBIOS(5,FALSE);
893
#endif
894
                        break;
895
                case 0xD: //verify
896
                        doBranch(TRUE, m_ins.branch);
897
                        break;
898
                case 0xE: //extended
899
                        illegalInstruction();
900
                        break;
901
                case 0xF: //piracy
902
//                      doBranch(TRUE, m_ins.branch);
903
                        forceDynamic=1;
904
                        break;
905
        }
906
}
907
 
908
void process1OPInstruction()
909
{
910
        switch (m_ins.op)
911
        {
912
                case 0: //jz
913
                        doBranch(m_ins.operands[0].value==0, m_ins.branch);
914
                        break;
915
                case 1: //get_sibling
916
                        {
917
                                ZObject child=getObject(m_ins.operands[0].value);
918
                                int siblingId=ReadMem(child.addr+5)&0xFF;
919
                                setVariable(m_ins.store, siblingId);
920
                                doBranch(siblingId!=0, m_ins.branch);
921
                                break;
922
                        }
923
                case 2: //get_child
924
                        {
925
                                ZObject child=getObject(m_ins.operands[0].value);
926
                                int childId=ReadMem(child.addr+6)&0xFF;
927
                                setVariable(m_ins.store, childId);
928
                                doBranch(childId!=0, m_ins.branch);
929
                                break;
930
                        }
931
                case 3: //get_parent_object
932
                        {
933
                                ZObject child=getObject(m_ins.operands[0].value);
934
                                setVariable(m_ins.store, ReadMem(child.addr+4)&0xFF);
935
                                break;
936
                        }
937
                case 4: //get_prop_len
938
                        {
939
                                int propAddress=(m_ins.operands[0].value&0xFFFF)-1;
940
                                int sizeId=ReadMem(propAddress)&0xFF;
941
                                int size=(sizeId>>5)+1;
942
                                setVariable(m_ins.store, size);
943
                                break;
944
                        }
945
                case 5: //inc
946
                        {
947
                                int value=readVariable(m_ins.operands[0].value);
948
                                setVariable(m_ins.operands[0].value, value+1);
949
                                break;
950
                        }
951
                case 6: //dec
952
                        {
953
                                int value=readVariable(m_ins.operands[0].value);
954
                                setVariable(m_ins.operands[0].value, value-1);
955
                                break;
956
                        }
957
                case 7: //print_addr
958
#if !USE_BIOS
959
                        printText(m_ins.operands[0].value);
960
#else
961
                        m_ins.operands[1].value=m_ins.operands[0].value&1;
962
                        m_ins.operands[2].value=m_ins.operands[0].value>>1;
963
                        m_ins.numOps=3;
964
                        callBIOS(1,FALSE);
965
#endif
966
                        break;
967
                case 8: //call_1s
968
                        m_memOffset=(m_ins.operands[0].value&3)*0x20000;
969
                        restart();
970
                        break;
971
                case 9: //remove_obj
972
                        {
973
                                removeObject(m_ins.operands[0].value);
974
                                break;
975
                        }
976
                case 0xA: //print_obj
977
                        {
978
#if !USE_BIOS
979
                                ZObject obj=getObject(m_ins.operands[0].value);
980
                                printText(obj.propTable+1);
981
#else
982
                                ZObject obj=getObject(m_ins.operands[0].value);
983
                                m_ins.operands[1].value=(obj.propTable+1)&1;
984
                                m_ins.operands[2].value=(obj.propTable+1)>>1;
985
                                m_ins.numOps=3;
986
                                callBIOS(1,FALSE);
987
#endif
988
                                break;
989
                        }
990
                case 0xB: //ret
991
                        returnRoutine(m_ins.operands[0].value);
992
                        break;
993
                case 0xC: //jump
994
                        m_pc+=m_ins.operands[0].value-2;
995
                        break;
996
                case 0xD: //print_paddr
997
#if !USE_BIOS
998
                        printText(2*(m_ins.operands[0].value&0xFFFF));
999
#else
1000
                        m_ins.operands[1].value=0;
1001
                        m_ins.operands[2].value=m_ins.operands[0].value;
1002
                        m_ins.numOps=3;
1003
                        callBIOS(1,FALSE);
1004
#endif
1005
                        break;
1006
                case 0xE: //load
1007
                        setVariable(m_ins.store, readVariableIndirect(m_ins.operands[0].value));
1008
                        break;
1009
                case 0xF: //not
1010
                        setVariable(m_ins.store, ~m_ins.operands[0].value);
1011
                        break;
1012
        }
1013
}
1014
 
1015
void process2OPInstruction()
1016
{
1017
        switch (m_ins.op)
1018
        {
1019
                case 0:
1020
                        illegalInstruction();
1021
                        break;
1022
                case 1: //je
1023
                        {
1024
                                int takeBranch=FALSE;
1025
                                int test=m_ins.operands[0].value;
1026
                                int i;
1027
                                for (i=1; i<m_ins.numOps; i++)
1028
                                {
1029
                                        if (test==m_ins.operands[i].value)
1030
                                        {
1031
                                                takeBranch=TRUE;
1032
                                                break;
1033
                                        }
1034
                                }
1035
                                doBranch(takeBranch, m_ins.branch);
1036
                                break;
1037
                        }
1038
                case 2: //jl
1039
                        doBranch(m_ins.operands[0].value<m_ins.operands[1].value, m_ins.branch);
1040
                        break;
1041
                case 3: //jg
1042
                        doBranch(m_ins.operands[0].value>m_ins.operands[1].value, m_ins.branch);
1043
                        break;
1044
                case 4: //dec_chk
1045
                        {
1046
                                int value=readVariable(m_ins.operands[0].value);
1047
                                value--;
1048
                                setVariable(m_ins.operands[0].value, value);
1049
                                doBranch(value<m_ins.operands[1].value, m_ins.branch);
1050
                                break;
1051
                        }
1052
                case 5: //inc_chk
1053
                        {
1054
                                int value=readVariable(m_ins.operands[0].value);
1055
                                value++;
1056
                                setVariable(m_ins.operands[0].value, value);
1057
                                doBranch(value>m_ins.operands[1].value, m_ins.branch);
1058
                                break;
1059
                        }
1060
                case 6: //jin
1061
                        {
1062
                                ZObject child=getObject(m_ins.operands[0].value);
1063
                                doBranch((ReadMem(child.addr+4)&0xFF)==m_ins.operands[1].value, m_ins.branch);
1064
                                break;
1065
                        }
1066
                case 7: //test
1067
                        {
1068
                                int flags=m_ins.operands[1].value;
1069
                                doBranch((m_ins.operands[0].value&flags)==flags, m_ins.branch);
1070
                                break;
1071
                        }
1072
                case 8: //or
1073
                        setVariable(m_ins.store, m_ins.operands[0].value|m_ins.operands[1].value);
1074
                        break;
1075
                case 9: //and
1076
                        setVariable(m_ins.store, m_ins.operands[0].value&m_ins.operands[1].value);
1077
                        break;
1078
                case 0xA: //test_attr
1079
                        {
1080
                                ZObject obj=getObject(m_ins.operands[0].value);
1081
                                int attr=m_ins.operands[1].value;
1082
                                int offset=attr/8;
1083
                                int bit=0x80>>(attr%8);
1084
                                doBranch((ReadMem(obj.addr+offset)&bit)==bit, m_ins.branch);
1085
                                break;
1086
                        }
1087
                case 0xB: //set_attr
1088
                        {
1089
                                ZObject obj=getObject(m_ins.operands[0].value);
1090
                                int attr=m_ins.operands[1].value;
1091
                                int offset=attr/8;
1092
                                int bit=0x80>>(attr%8);
1093
                                WriteMem(obj.addr+offset,ReadMem(obj.addr+offset)|bit);
1094
                                break;
1095
                        }
1096
                case 0xC: //clear_attr
1097
                        {
1098
                                ZObject obj=getObject(m_ins.operands[0].value);
1099
                                int attr=m_ins.operands[1].value;
1100
                                int offset=attr/8;
1101
                                int bit=0x80>>(attr%8);
1102
                                WriteMem(obj.addr+offset,ReadMem(obj.addr+offset)&~bit);
1103
                                break;
1104
                        }
1105
                case 0xD: //store
1106
                        setVariableIndirect(m_ins.operands[0].value, m_ins.operands[1].value);
1107
                        break;
1108
                case 0xE: //insert_obj
1109
                        {
1110
                                removeObject(m_ins.operands[0].value);
1111
                                addChild(m_ins.operands[1].value, m_ins.operands[0].value);
1112
                                break;
1113
                        }
1114
                case 0xF: //loadw
1115
                        {
1116
                                int address=((m_ins.operands[0].value&0xFFFF)+2*(m_ins.operands[1].value&0xFFFF));
1117
                                setVariable(m_ins.store, makeS16(ReadMemDyn(address)&0xFF, ReadMemDyn(address+1)&0xFF));
1118
                                forceDynamic=0;
1119
                                break;
1120
                        }
1121
                case 0x10: //loadb
1122
                        {
1123
                                int address=((m_ins.operands[0].value&0xFFFF)+(m_ins.operands[1].value&0xFFFF));
1124
                                setVariable(m_ins.store, ReadMemDyn(address)&0xFF);
1125
                                forceDynamic=0;
1126
                                break;
1127
                        }
1128
                case 0x11: //get_prop
1129
                        {
1130
                                ZObject obj=getObject(m_ins.operands[0].value);
1131
                                ZProperty prop=getProperty(obj, m_ins.operands[1].value);
1132
                                if (prop.size==1)
1133
                                {
1134
                                        setVariable(m_ins.store, ReadMem(prop.addr)&0xFF);
1135
                                }
1136
                                else if (prop.size==2)
1137
                                {
1138
                                        setVariable(m_ins.store, makeS16(ReadMem(prop.addr)&0xFF, ReadMem(prop.addr+1)&0xFF));
1139
                                }
1140
                                else
1141
                                {
1142
                                        illegalInstruction();
1143
                                }
1144
                                break;
1145
                        }
1146
                case 0x12: //get_prop_addr
1147
                        {
1148
                                ZObject obj=getObject(m_ins.operands[0].value);
1149
                                ZProperty prop=getProperty(obj, m_ins.operands[1].value);
1150
                                if (prop.bDefault)
1151
                                        setVariable(m_ins.store, 0);
1152
                                else
1153
                                        setVariable(m_ins.store, prop.addr);
1154
                                break;
1155
                        }
1156
                case 0x13: //get_next_prop
1157
                        {
1158
                                ZObject obj=getObject(m_ins.operands[0].value);
1159
                                if (m_ins.operands[1].value==0)
1160
                                {
1161
                                        int address=obj.propTable;
1162
                                        int textLen=ReadMem(address++)&0xFF;
1163
                                        address+=textLen*2;
1164
                                        int nextSizeId=ReadMem(address)&0xFF;
1165
                                        setVariable(m_ins.store, nextSizeId&31);
1166
                                }
1167
                                else
1168
                                {
1169
                                        ZProperty prop=getProperty(obj, m_ins.operands[1].value);
1170
                                        if (prop.bDefault)
1171
                                        {
1172
                                                illegalInstruction();
1173
                                        }
1174
                                        else
1175
                                        {
1176
                                                int nextSizeId=ReadMem(prop.addr+prop.size)&0xFF;
1177
                                                setVariable(m_ins.store, nextSizeId&31);
1178
                                        }
1179
                                }
1180
                                break;
1181
                        }
1182
                case 0x14: //add
1183
                        setVariable(m_ins.store, m_ins.operands[0].value+m_ins.operands[1].value);
1184
                        break;
1185
                case 0x15: //sub
1186
                        setVariable(m_ins.store, m_ins.operands[0].value-m_ins.operands[1].value);
1187
                        break;
1188
                case 0x16: //mul
1189
                        setVariable(m_ins.store, m_ins.operands[0].value*m_ins.operands[1].value);
1190
                        break;
1191
                case 0x17: //div
1192
                        setVariable(m_ins.store, m_ins.operands[0].value/m_ins.operands[1].value);
1193
                        break;
1194
                case 0x18: //mod
1195
                        setVariable(m_ins.store, m_ins.operands[0].value%m_ins.operands[1].value);
1196
                        break;
1197
                case 0x19: //call_2s
1198
                        illegalInstruction();
1199
                        break;
1200
                case 0x1A: //call_2n
1201
                        illegalInstruction();
1202
                        break;
1203
                case 0x1B: //set_colour
1204
                        illegalInstruction();
1205
                        break;
1206
                case 0x1C: //throw
1207
                        illegalInstruction();
1208
                        break;
1209
                case 0x1D:
1210
                        illegalInstruction();
1211
                        break;
1212
                case 0x1E:
1213
                        //printf("WriteReg: %04x %04x\n", m_ins.operands[0].value&0xFFFF, m_ins.operands[1].value&0xFFFF);
1214
                        if (m_ins.operands[0].value==0x22)
1215
                        {
1216
                                screen[curIdx%(320*240)]=m_ins.operands[1].value;
1217
                                curIdx++;
1218
                                curX++;
1219
                                if (curX>winXMax)
1220
                                {
1221
                                        curX=winXMin;
1222
                                        curY++;
1223
                                        if (curY>winYMax)
1224
                                        {
1225
                                                curY=winYMin;
1226
                                        }
1227
                                        curIdx=curY*240+curX;
1228
                                }
1229
                        }
1230
                        else if (m_ins.operands[0].value==0x20)
1231
                        {
1232
                                curX=m_ins.operands[1].value;
1233
                                curIdx=curY*240+curX;
1234
                        }
1235
                        else if (m_ins.operands[0].value==0x21)
1236
                        {
1237
                                curY=m_ins.operands[1].value;
1238
                                curIdx=curY*240+curX;
1239
                        }
1240
                        else if (m_ins.operands[0].value==0x50)
1241
                        {
1242
                                winXMin=m_ins.operands[1].value;
1243
                        }
1244
                        else if (m_ins.operands[0].value==0x51)
1245
                        {
1246
                                winXMax=m_ins.operands[1].value;
1247
                        }
1248
                        else if (m_ins.operands[0].value==0x52)
1249
                        {
1250
                                winYMin=m_ins.operands[1].value;
1251
                        }
1252
                        else if (m_ins.operands[0].value==0x53)
1253
                        {
1254
                                winYMax=m_ins.operands[1].value;
1255
                        }
1256
                        else if (m_ins.operands[0].value==7)
1257
                        {
1258
                                SDL_UpdateTexture(tex, NULL, screen, 240*sizeof(screen[0]));
1259
                                SDL_RenderClear(ren);
1260
                                SDL_RenderCopy(ren, tex, NULL, NULL);
1261
                                SDL_RenderPresent(ren);
1262
                                SDL_Delay(1);
1263
                        }
1264
                        break;
1265
                case 0x1F:
1266
                        illegalInstruction();
1267
                        break;
1268
        }
1269
}
1270
 
1271
void processVARInstruction()
1272
{
1273
        switch (m_ins.op)
1274
        {
1275
                case 0: // call
1276
                        callRoutine(2*(m_ins.operands[0].value&0xFFFF), m_ins.store, TRUE);
1277
                        break;
1278
                case 1: //storew
1279
                        {
1280
                                int address=((m_ins.operands[0].value&0xFFFF)+2*(m_ins.operands[1].value&0xFFFF));
1281
                                int value=m_ins.operands[2].value;
1282
                                WriteMemDyn(address,(byte)((value>>8)&0xFF));
1283
                                WriteMemDyn(address+1,(byte)(value&0xFF));
1284
                                forceDynamic=0;
1285
                                break;
1286
                        }
1287
                case 2: //storeb
1288
                        {
1289
                                int address=((m_ins.operands[0].value&0xFFFF)+(m_ins.operands[1].value&0xFFFF));
1290
                                int value=m_ins.operands[2].value;
1291
                                WriteMemDyn(address,(byte)(value&0xFF));
1292
                                forceDynamic=0;
1293
                                break;
1294
                        }
1295
                case 3: //put_prop
1296
                        {
1297
                                ZObject obj=getObject(m_ins.operands[0].value);
1298
                                ZProperty prop=getProperty(obj, m_ins.operands[1].value);
1299
                                if (!prop.bDefault)
1300
                                {
1301
                                        if (prop.size==1)
1302
                                        {
1303
                                                WriteMem(prop.addr,(byte)(m_ins.operands[2].value&0xFF));
1304
                                        }
1305
                                        else if (prop.size==2)
1306
                                        {
1307
                                                WriteMem(prop.addr+0,(byte)((m_ins.operands[2].value>>8)&0xFF));
1308
                                                WriteMem(prop.addr+1,(byte)(m_ins.operands[2].value&0xFF));
1309
                                        }
1310
                                }
1311
                                else
1312
                                {
1313
                                        illegalInstruction();
1314
                                }
1315
                                break;
1316
                        }
1317
                case 4: //sread
1318
                        {
1319
#if !USE_BIOS
1320
                                static char input[4096];
1321
                                int bufferAddr=m_ins.operands[0].value;
1322
                                int parseAddr=m_ins.operands[1].value;
1323
                                int maxLength=ReadMem(bufferAddr++)&0xFF;
1324
                                int maxParse=ReadMem(parseAddr++)&0xFF;
1325
                                int realInLen=0;
1326
                                int inLen;
1327
                                int i;
1328
                                fgets(input, sizeof(input), stdin);
1329
                                inLen=strlen(input);
1330
                                for (i=0; i<inLen && i<maxLength; i++)
1331
                                {
1332
                                        if (input[i]!='\r' && input[i]!='\n')
1333
                                        {
1334
                                                input[realInLen++]=tolower(input[i]);
1335
                                                WriteMem(bufferAddr++,(byte)input[i]);
1336
                                        }
1337
                                }
1338
                                input[realInLen]='\0';
1339
                                WriteMem(bufferAddr++,0);
1340
                                WriteMem(parseAddr,(byte)lexicalAnalysis(input, parseAddr+1, maxParse));
1341
#else
1342
                                m_ins.operands[2].value=m_ins.operands[0].value;
1343
                                m_ins.numOps=3;
1344
                                callBIOS(4,FALSE);
1345
#endif
1346
                                break;
1347
                        }
1348
                case 5: //print_char
1349
#if !USE_BIOS
1350
                        printf("%c", (char)m_ins.operands[0].value);
1351
#else
1352
                        m_ins.operands[1].value=m_ins.operands[0].value;
1353
                        m_ins.numOps=2;
1354
                        callBIOS(2,FALSE);
1355
#endif
1356
                        break;
1357
                case 6: //print_num
1358
#if !USE_BIOS
1359
                        printf("%d", m_ins.operands[0].value);
1360
#else
1361
                        m_ins.operands[1].value=m_ins.operands[0].value;
1362
                        m_ins.numOps=2;
1363
                        callBIOS(3,FALSE);
1364
#endif
1365
                        break;
1366
                case 7: //random
1367
                        {
1368
                                int maxValue=m_ins.operands[0].value;
1369
                                int ret=0;
1370
                                if (maxValue>0)
1371
                                {
1372
                                        randomseed=randomseed^(randomseed<<13);
1373
                                        randomseed=randomseed^(randomseed>>9);
1374
                                        randomseed=randomseed^(randomseed<<7);
1375
                                        ret=((randomseed&0x7FFF)%(maxValue))+1;
1376
                                }
1377
                                else if (maxValue<0)
1378
                                {
1379
                                        randomseed=maxValue;
1380
                                }
1381
                                setVariable(m_ins.store, ret);
1382
                                break;
1383
                        }
1384
                case 8: //push
1385
                        setVariable(0, m_ins.operands[0].value);
1386
                        break;
1387
                case 9: //pull
1388
                        setVariableIndirect(m_ins.operands[0].value, readVariable(0));
1389
                        break;
1390
                case 0xA: //split_window
1391
                        haltInstruction();
1392
                        break;
1393
                case 0xB: //set_window
1394
                        haltInstruction();
1395
                        break;
1396
                case 0xC: //call_vs2
1397
                        illegalInstruction();
1398
                        break;
1399
                case 0xD: //erase_window
1400
                        illegalInstruction();
1401
                        break;
1402
                case 0xE: //erase_line
1403
                        illegalInstruction();
1404
                        break;
1405
                case 0xF: //set_cursor
1406
                        illegalInstruction();
1407
                        break;
1408
                case 0x10: //get_cursor
1409
                        illegalInstruction();
1410
                        break;
1411
                case 0x11: //set_text_style
1412
                        illegalInstruction();
1413
                        break;
1414
                case 0x12: //buffer_mode
1415
                        illegalInstruction();
1416
                        break;
1417
                case 0x13: //output_stream
1418
                        haltInstruction();
1419
                        break;
1420
                case 0x14: //input_stream
1421
                        haltInstruction();
1422
                        break;
1423
                case 0x15: //sound_effect
1424
                        haltInstruction();
1425
                        break;
1426
                case 0x16: //read_char
1427
                        illegalInstruction();
1428
                        break;
1429
                case 0x17: //scan_table
1430
                        illegalInstruction();
1431
                        break;
1432
                case 0x18: //not
1433
                        illegalInstruction();
1434
                        break;
1435
                case 0x19: //call_vn
1436
                        illegalInstruction();
1437
                        break;
1438
                case 0x1A: //call_vn2
1439
                        illegalInstruction();
1440
                        break;
1441
                case 0x1B: //tokenise
1442
                        illegalInstruction();
1443
                        break;
1444
                case 0x1C: //encode_text
1445
                        illegalInstruction();
1446
                        break;
1447
                case 0x1D: //copy_table
1448
                        illegalInstruction();
1449
                        break;
1450
                case 0x1E: //print_table
1451
                        {
1452
                                //                      printf("GetTouch: %04x\n", m_ins.operands[0].value);
1453
                                SDL_Event e;
1454
                                while (SDL_PollEvent(&e))
1455
                                {
1456
                                        if (e.type == SDL_QUIT)
1457
                                                exit(1);
1458
                                        else if (e.type == SDL_MOUSEBUTTONDOWN)
1459
                                                mouseDown=1;
1460
                                        else if (e.type == SDL_MOUSEBUTTONUP)
1461
                                                mouseDown=0;
1462
                                        else if (e.type == SDL_MOUSEMOTION)
1463
                                        {
1464
                                                SDL_MouseMotionEvent *mm=(SDL_MouseMotionEvent*)&e;
1465
                                                mouseX=mm->x;
1466
                                                mouseY=mm->y;
1467
                                        }
1468
                                }
1469
                                if (m_ins.operands[0].value==0x93) // touching?
1470
                                        setVariable(m_ins.store, mouseDown?0:1024);
1471
                                else if (m_ins.operands[0].value==0x95) // X
1472
                                {
1473
                                        float m=(840.0f-170.0f)/(216.0f-23.0f);
1474
                                        float c=840.0f-216.0f*m;
1475
                                        float v=mouseX*m+c;
1476
                                        setVariable(m_ins.store, (int)MIN(MAX(v,0),1023));
1477
                                }
1478
                                else if (m_ins.operands[0].value==0x1A) // Y
1479
                                {
1480
                                        float m=(870.0f-720.0f)/(302.0f-243.0f);
1481
                                        float c=870.0f-302.0f*m;
1482
                                        float v=mouseY*m+c;
1483
                                        setVariable(m_ins.store, (int)MIN(MAX(v,0),1023));
1484
                                }
1485
                                else
1486
                                        setVariable(m_ins.store, 0);
1487
                                break;
1488
                        }
1489
                case 0x1F: //check_arg_count
1490
                        {
1491
                                int i;
1492
                                //printf("Blit: %04x %04x %04x %04x\n", m_ins.operands[0].value&0xFFFF, m_ins.operands[1].value&0xFFFF, m_ins.operands[2].value&0xFFFF, m_ins.operands[3].value&0xFFFF);
1493
                                forceDynamic=1;
1494
                                for (i=0; i<(m_ins.operands[1].value&0xFFFF); i++)
1495
                                {
1496
                                        byte data=ReadMemDyn(2*(m_ins.operands[0].value&0xFFFF)+i);
1497
                                        screen[curIdx%(320*240)]=(data&0x80)?m_ins.operands[3].value:m_ins.operands[2].value;
1498
                                        curIdx++;
1499
                                        screen[curIdx%(320*240)]=(data&0x40)?m_ins.operands[3].value:m_ins.operands[2].value;
1500
                                        curIdx++;
1501
                                        screen[curIdx%(320*240)]=(data&0x20)?m_ins.operands[3].value:m_ins.operands[2].value;
1502
                                        curIdx++;
1503
                                        screen[curIdx%(320*240)]=(data&0x10)?m_ins.operands[3].value:m_ins.operands[2].value;
1504
                                        curIdx++;
1505
                                        screen[curIdx%(320*240)]=(data&0x08)?m_ins.operands[3].value:m_ins.operands[2].value;
1506
                                        curIdx++;
1507
                                        screen[curIdx%(320*240)]=(data&0x04)?m_ins.operands[3].value:m_ins.operands[2].value;
1508
                                        curIdx++;
1509
                                        screen[curIdx%(320*240)]=(data&0x02)?m_ins.operands[3].value:m_ins.operands[2].value;
1510
                                        curIdx++;
1511
                                        screen[curIdx%(320*240)]=(data&0x01)?m_ins.operands[3].value:m_ins.operands[2].value;
1512
                                        curIdx++;
1513
                                        curX+=8;
1514
                                        if (curX>winXMax)
1515
                                        {
1516
                                                curX=winXMin;
1517
                                                curY++;
1518
                                                if (curY>winYMax)
1519
                                                {
1520
                                                        curY=winYMin;
1521
                                                }
1522
                                                curIdx=curY*240+curX;
1523
                                        }
1524
                                }
1525
                                SDL_UpdateTexture(tex, NULL, screen, 240*sizeof(screen[0]));
1526
                                SDL_RenderClear(ren);
1527
                                SDL_RenderCopy(ren, tex, NULL, NULL);
1528
                                SDL_RenderPresent(ren);
1529
                                SDL_Delay(1);
1530
                                forceDynamic=0;
1531
                                break;
1532
                        }
1533
        }
1534
}
1535
 
1536
void executeInstruction()
1537
{
1538
        m_ins.numOps=0;
1539
        //printf("\nPC:%05x ", m_pc);
1540
        //System.out.println(String.format("%04x", m_pc));
1541
        int opcode=readBytePC();
1542
        if ((opcode&0xC0)==0xC0)
1543
        {
1544
                readVariableForm(opcode);
1545
        }
1546
        else if ((opcode&0xC0)==0x80)
1547
        {
1548
                readShortForm(opcode);
1549
        }
1550
        else
1551
        {
1552
                readLongForm(opcode);
1553
        }
1554
        switch (m_ins.form)
1555
        {
1556
                case Form0OP:
1557
                        //printf("Doing op0:%2d\n", m_ins.op);
1558
                        m_ins.store=readStoreInstruction(zeroOpStoreInstructions,ARRAY_SIZEOF(zeroOpStoreInstructions),m_ins.op);
1559
                        m_ins.branch=readBranchInstruction(zeroOpBranchInstructions,ARRAY_SIZEOF(zeroOpBranchInstructions),m_ins.op);
1560
                        //dumpCurrentInstruction();
1561
                        process0OPInstruction();
1562
                        break;
1563
                case Form1OP:
1564
                        //printf("Doing op1:%2d Operands:%04x\n", m_ins.op, m_ins.operands[0].value&0xFFFF);
1565
                        m_ins.store=readStoreInstruction(oneOpStoreInstructions,ARRAY_SIZEOF(oneOpStoreInstructions),m_ins.op);
1566
                        m_ins.branch=readBranchInstruction(oneOpBranchInstructions,ARRAY_SIZEOF(oneOpBranchInstructions),m_ins.op);
1567
                        //dumpCurrentInstruction();
1568
                        process1OPInstruction();
1569
                        break;
1570
                case Form2OP:
1571
                        //printf("Doing op2:%2d Operands:%04x %04x\n", m_ins.op, m_ins.operands[0].value&0xFFFF, m_ins.operands[1].value&0xFFFF);
1572
                        m_ins.store=readStoreInstruction(twoOpStoreInstructions,ARRAY_SIZEOF(twoOpStoreInstructions),m_ins.op);
1573
                        m_ins.branch=readBranchInstruction(twoOpBranchInstructions,ARRAY_SIZEOF(twoOpBranchInstructions),m_ins.op);
1574
                        //dumpCurrentInstruction();
1575
                        process2OPInstruction();
1576
                        break;
1577
                case FormVAR:
1578
                        //if (m_ins.numOps==4)
1579
                        //      printf("Doing opvar:%2d Operands:%04x %04x %04x %04x\n", m_ins.op, m_ins.operands[0].value&0xFFFF, m_ins.operands[1].value&0xFFFF, m_ins.operands[2].value&0xFFFF, m_ins.operands[3].value&0xFFFF);
1580
                        //else if (m_ins.numOps==3)
1581
                        //      printf("Doing opvar:%2d Operands:%04x %04x %04x\n", m_ins.op, m_ins.operands[0].value&0xFFFF, m_ins.operands[1].value&0xFFFF, m_ins.operands[2].value&0xFFFF);
1582
                        //else if (m_ins.numOps==2)
1583
                        //      printf("Doing opvar:%2d Operands:%04x %04x\n", m_ins.op, m_ins.operands[0].value&0xFFFF, m_ins.operands[1].value&0xFFFF);
1584
                        //else if (m_ins.numOps==1)
1585
                        //      printf("Doing opvar:%2d Operands:%04x\n", m_ins.op, m_ins.operands[0].value&0xFFFF);
1586
                        //else
1587
                        //      printf("Doing opvar:%2d Operands:\n", m_ins.op);
1588
                        m_ins.store=readStoreInstruction(varOpStoreInstructions,ARRAY_SIZEOF(varOpStoreInstructions),m_ins.op);
1589
                        m_ins.branch=readBranchInstruction(varOpBranchInstructions,ARRAY_SIZEOF(varOpBranchInstructions),m_ins.op);
1590
                        //dumpCurrentInstruction();
1591
                        processVARInstruction();
1592
                        break;
1593
        }
1594
}
1595
 
1596
int main(int argc, char **argv)
1597
{
1598
        TFile fh;
1599
        if (argc!=2)
1600
        {
1601
                printf("Usage: zops game.z3\n");
1602
        }
1603
        else if (fileOpen(&fh, argv[1], TRUE))
1604
        {
1605
                m_memSize=fileSize(&fh);
1606
 
1607
                SDL_Init(SDL_INIT_VIDEO);
1608
                window = SDL_CreateWindow("TFTLCD",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,240,320,SDL_WINDOW_SHOWN);
1609
                if (window == NULL)
1610
                {
1611
                        printf("Could not create window: %s\n", SDL_GetError());
1612
                        return 1;
1613
                }
1614
                ren = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
1615
                if (ren == NULL)
1616
                {
1617
                        printf("Could not create renderer: %s\n", SDL_GetError());
1618
                        return 1;
1619
                }
1620
                tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, 240, 320);
1621
                if (tex == NULL)
1622
                {
1623
                        printf("Could not create texture: %s\n", SDL_GetError());
1624
                        return 1;
1625
                }
1626
 
1627
                rom=memAlloc(m_memSize);
1628
                memory=memAlloc(m_memSize);
1629
                biosRAM=memAlloc(0x10000);
1630
                screen=memAlloc(320*240*sizeof(u16));
1631
                fileReadData(&fh, rom, m_memSize);
1632
                fileClose(&fh);
1633
                restart();
1634
                while (1)
1635
                {
1636
                        executeInstruction();
1637
                }
1638
 
1639
                SDL_DestroyTexture(tex);
1640
                SDL_DestroyRenderer(ren);
1641
                SDL_DestroyWindow(window);
1642
                SDL_Quit();
1643
                return 0;
1644
        }
1645
        return 1;
1646
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.