summaryrefslogtreecommitdiff
path: root/apps/plugins/xworld/vm.h
blob: 1409dd47e30ef087e33bc34175f74c9720258874 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2014 Franklin Wei, Benjamin Brown
 * Copyright (C) 2004 Gregory Montoir
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/

#ifndef __LOGIC_H__
#define __LOGIC_H__



#include "intern.h"

#define VM_NUM_THREADS 64
#define VM_NUM_VARIABLES 256
#define VM_NO_SETVEC_REQUESTED 0xFFFF
#define VM_INACTIVE_THREAD    0xFFFF


#define    VM_VARIABLE_RANDOM_SEED          0x3C

#define    VM_VARIABLE_LAST_KEYCHAR         0xDA

#define    VM_VARIABLE_HERO_POS_UP_DOWN     0xE5
#define    VM_VARIABLE_MUS_MARK             0xF4

#define    VM_VARIABLE_SCROLL_Y             0xF9
#define    VM_VARIABLE_HERO_ACTION          0xFA
#define    VM_VARIABLE_HERO_POS_JUMP_DOWN   0xFB
#define    VM_VARIABLE_HERO_POS_LEFT_RIGHT  0xFC
#define    VM_VARIABLE_HERO_POS_MASK        0xFD
#define    VM_VARIABLE_HERO_ACTION_POS_MASK 0xFE
#define    VM_VARIABLE_PAUSE_SLICES         0xFF

struct Mixer;
struct Resource;
struct Serializer;
struct SfxPlayer;
struct System;
struct Video;

//For threadsData navigation
#define PC_OFFSET 0
#define REQUESTED_PC_OFFSET 1
#define NUM_DATA_FIELDS 2

//For vmIsChannelActive navigation
#define CURR_STATE 0
#define REQUESTED_STATE 1
#define NUM_THREAD_FIELDS 2

struct VirtualMachine;

void vm_create(struct VirtualMachine*, struct Mixer *mix, struct Resource *res, struct SfxPlayer *ply, struct Video *vid, struct System *stub);
void vm_init(struct VirtualMachine*);

void vm_op_movConst(struct VirtualMachine*);
void vm_op_mov(struct VirtualMachine*);
void vm_op_add(struct VirtualMachine*);
void vm_op_addConst(struct VirtualMachine*);
void vm_op_call(struct VirtualMachine*);
void vm_op_ret(struct VirtualMachine*);
void vm_op_pauseThread(struct VirtualMachine*);
void vm_op_jmp(struct VirtualMachine*);
void vm_op_setSetVect(struct VirtualMachine*);
void vm_op_jnz(struct VirtualMachine*);
void vm_op_condJmp(struct VirtualMachine*);
void vm_op_setPalette(struct VirtualMachine*);
void vm_op_resetThread(struct VirtualMachine*);
void vm_op_selectVideoPage(struct VirtualMachine*);
void vm_op_fillVideoPage(struct VirtualMachine*);
void vm_op_copyVideoPage(struct VirtualMachine*);
void vm_op_blitFramebuffer(struct VirtualMachine*);
void vm_op_killThread(struct VirtualMachine*);
void vm_op_drawString(struct VirtualMachine*);
void vm_op_sub(struct VirtualMachine*);
void vm_op_and(struct VirtualMachine*);
void vm_op_or(struct VirtualMachine*);
void vm_op_shl(struct VirtualMachine*);
void vm_op_shr(struct VirtualMachine*);
void vm_op_playSound(struct VirtualMachine*);
void vm_op_updateMemList(struct VirtualMachine*);
void vm_op_playMusic(struct VirtualMachine*);

void vm_initForPart(struct VirtualMachine*, uint16_t partId);
void vm_setupPart(struct VirtualMachine*, uint16_t partId);
void vm_checkThreadRequests(struct VirtualMachine*);
void vm_hostFrame(struct VirtualMachine*);
void vm_executeThread(struct VirtualMachine*);

void vm_inp_updatePlayer(struct VirtualMachine*);
void vm_inp_handleSpecialKeys(struct VirtualMachine*);

void vm_snd_playSound(struct VirtualMachine*, uint16_t resNum, uint8_t freq, uint8_t vol, uint8_t channel);
void vm_snd_playMusic(struct VirtualMachine*, uint16_t resNum, uint16_t delay, uint8_t pos);

void vm_saveOrLoad(struct VirtualMachine*, struct Serializer *ser);
void vm_bypassProtection(struct VirtualMachine*);

typedef void (*OpcodeStub)(struct VirtualMachine*);

// The type of entries in opcodeTable. This allows "fast" branching
static const OpcodeStub vm_opcodeTable[] = {
    /* 0x00 */
    &vm_op_movConst,
    &vm_op_mov,
    &vm_op_add,
    &vm_op_addConst,
    /* 0x04 */
    &vm_op_call,
    &vm_op_ret,
    &vm_op_pauseThread,
    &vm_op_jmp,
    /* 0x08 */
    &vm_op_setSetVect,
    &vm_op_jnz,
    &vm_op_condJmp,
    &vm_op_setPalette,
    /* 0x0C */
    &vm_op_resetThread,
    &vm_op_selectVideoPage,
    &vm_op_fillVideoPage,
    &vm_op_copyVideoPage,
    /* 0x10 */
    &vm_op_blitFramebuffer,
    &vm_op_killThread,
    &vm_op_drawString,
    &vm_op_sub,
    /* 0x14 */
    &vm_op_and,
    &vm_op_or,
    &vm_op_shl,
    &vm_op_shr,
    /* 0x18 */
    &vm_op_playSound,
    &vm_op_updateMemList,
    &vm_op_playMusic
};

struct VirtualMachine {
    //This table is used to play a sound
    //static const uint16_t frequenceTable[];
    /* FW: moved from staticres.c to vm.c */

    struct Mixer *mixer;
    struct Resource *res;
    struct SfxPlayer *player;
    struct Video *video;
    struct System *sys;

    int16_t vmVariables[VM_NUM_VARIABLES];
    uint16_t _scriptStackCalls[VM_NUM_THREADS];

    uint16_t threadsData[NUM_DATA_FIELDS][VM_NUM_THREADS];
    // This array is used:
    //     0 to save the channel's instruction pointer
    //     when the channel release control (this happens on a break).

    //     1 When a setVec is requested for the next vm frame.

    uint8_t vmIsChannelActive[NUM_THREAD_FIELDS][VM_NUM_THREADS];

    struct Ptr _scriptPtr;
    uint8_t _stackPtr;
    bool gotoNextThread;
    bool _fastMode;
};
#endif