bd7e79ca4b08db641b9c1f2aa41883f8cea4914f
[xscreensaver] / hacks / asm6502.h
1 /*
2  * Copyright (c) 2007 Jeremy English <jhe@jeremyenglish.org>
3  * 
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or 
10  * implied warranty.
11  * 
12  * Created: 07-May-2007 
13  */
14
15 /* 
16       This is a port of the javascript 6502 assembler, compiler and
17       debugger. The orignal code was copyright 2006 by Stian Soreng -
18       www.6502asm.com
19
20    The stack space is in page $100 to $1ff. The video buffer starts at
21    $200 and is 1024 bytes. Programs get loaded at address
22    $600. Address $fe is random and byte $ff is used for user input.
23
24    User input is disabled.
25 */
26
27 #ifndef __ASM6502_H__
28 #define __ASM6502_H__
29
30 typedef uint8_t  Bit8;
31 typedef uint16_t Bit16;
32 typedef uint32_t Bit32;
33
34 #undef  BOOL
35 #undef  TRUE
36 #undef  FALSE
37 #define BOOL  Bit8
38 #define TRUE  1
39 #define FALSE 0
40
41 enum {
42   MAX_LABEL_LEN = 80, 
43   NUM_OPCODES = 56, /* Number of unique instructions not counting DCB */
44   MEM_64K = 65536, /* We have 64k of memory to work with. */
45   MAX_PARAM_VALUE = 25, /* The number of values allowed behind dcb */
46   MAX_CMD_LEN = 4, /* Each assembly command is 3 characeters long */
47 /* The stack works from the top down in page $100 to $1ff */
48   STACK_TOP = 0x1ff,
49   STACK_BOTTOM = 0x100 
50 };
51
52 typedef enum{
53   SINGLE, IMMEDIATE_VALUE, IMMEDIATE_GREAT, 
54     IMMEDIATE_LESS, INDIRECT_X, INDIRECT_Y,
55     ZERO, ZERO_X, ZERO_Y,
56     ABS_VALUE, ABS_OR_BRANCH, ABS_X, ABS_Y,
57     ABS_LABEL_X, ABS_LABEL_Y, DCB_PARAM
58 } AddrMode;
59
60 typedef struct machine_6502 machine_6502;
61
62 typedef struct {
63   char name[MAX_CMD_LEN];
64   Bit8 Imm;
65   Bit8 ZP;
66   Bit8 ZPX;
67   Bit8 ZPY;
68   Bit8 ABS;
69   Bit8 ABSX;
70   Bit8 ABSY;
71   Bit8 INDX;
72   Bit8 INDY;
73   Bit8 SNGL;
74   Bit8 BRA;
75   void (*func) (machine_6502*, AddrMode);
76 } Opcodes;
77
78 /* Used to cache the index of each opcode */
79 typedef struct {
80   Bit8 index;
81   AddrMode adm;
82 } OpcodeIndex;
83
84 /* Plotter is a function that will be called everytime a pixel
85    needs to be updated. The first two parameter are the x and y
86    values. The third parameter is the color index:
87
88    Color Index Table
89    00 black      #000000
90    01 white      #ffffff
91    02 Red        #880000
92    03 seafoam    #aaffee
93    04 fuscia     #cc44cc
94    05 green      #00cc55
95    06 blue       #0000aa
96    07 Yellow     #eeee77
97    08 tangerine  #dd8855
98    09 brown      #664400
99    10 salmon     #ff7777
100    11 charcoal   #333333
101    12 smoke      #777777
102    13 lime       #aaff66
103    14 light blue #0088ff
104    15 gray       #bbbbbb
105
106    The plotter state variable of the machine gets passed as the forth
107    parameter. You can use this parameter to store state information.
108
109 */
110 typedef void (*Plotter) (Bit8, Bit8, Bit8, void*);
111
112 struct machine_6502 {
113   BOOL codeCompiledOK;
114   Bit8 regA;
115   Bit8 regX;
116   Bit8 regY;
117   Bit8 regP;
118   Bit16 regPC; /* A pair of 8 bit registers */
119   Bit16 regSP;
120   Bit8 memory[MEM_64K];
121   BOOL runForever;
122   int labelPtr;
123   BOOL codeRunning;
124   int myInterval;
125   Opcodes opcodes[NUM_OPCODES];
126   int screen[32][32];
127   int codeLen;
128   OpcodeIndex opcache[0xff];
129   Plotter plot;
130   void *plotterState;
131 };
132
133 /* build6502() - Creates an instance of the 6502 machine */
134 machine_6502 *build6502(void);
135
136 /* destroy6502() - compile the file and exectue it until the program
137    is finished */
138 void destroy6502(machine_6502 *machine);
139
140 /* eval_file() - Compiles and runs a file until the program is
141    finished */
142 void eval_file(machine_6502 *machine, char *filename, 
143                Plotter plot, void *plotterState);
144
145 /* start_eval_file() - Compile the file and execute the first
146    instruction */
147 void start_eval_file(machine_6502 *machine, char *filename, 
148                      Plotter plot, void *plotterState);
149
150 void start_eval_binary(machine_6502 *machine, Bit8 *program,
151                        unsigned int proglen,
152                        Plotter plot, void *plotterState);
153
154 /* next_eval() - Execute the next insno of machine instructions */
155 void next_eval(machine_6502 *machine, int insno);
156
157 /* hexDump() - Dumps memory to output */
158 void hexDump(machine_6502 *machine, Bit16 start, 
159              Bit16 numbytes, FILE *output);
160
161 /* trace() - Prints to output the current value of registers, the
162    current nmemonic, memory address and value. */
163 void trace(machine_6502 *machine, FILE *output);
164
165 /* save_program() - Writes a binary file of the program loaded in
166    memory. */
167 void save_program(machine_6502 *machine, char *filename);
168
169 #endif /* __ASM6502_H__ */