From http://www.jwz.org/xscreensaver/xscreensaver-5.30.tar.gz
[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   PROG_START = 0x600 /* The default entry point for the program */
51 };
52
53 typedef enum{
54   SINGLE, IMMEDIATE_VALUE, IMMEDIATE_GREAT, 
55     IMMEDIATE_LESS, INDIRECT_X, INDIRECT_Y,
56     ZERO, ZERO_X, ZERO_Y,
57     ABS_VALUE, ABS_OR_BRANCH, ABS_X, ABS_Y,
58     ABS_LABEL_X, ABS_LABEL_Y, DCB_PARAM
59 } m6502_AddrMode;
60
61 typedef struct machine_6502 machine_6502;
62
63 typedef struct {
64   char name[MAX_CMD_LEN];
65   Bit8 Imm;
66   Bit8 ZP;
67   Bit8 ZPX;
68   Bit8 ZPY;
69   Bit8 ABS;
70   Bit8 ABSX;
71   Bit8 ABSY;
72   Bit8 INDX;
73   Bit8 INDY;
74   Bit8 SNGL;
75   Bit8 BRA;
76   void (*func) (machine_6502*, m6502_AddrMode);
77 } m6502_Opcodes;
78
79 /* Used to cache the index of each opcode */
80 typedef struct {
81   Bit8 index;
82   m6502_AddrMode adm;
83 } m6502_OpcodeIndex;
84
85 /* Plotter is a function that will be called everytime a pixel
86    needs to be updated. The first two parameter are the x and y
87    values. The third parameter is the color index:
88
89    Color Index Table
90    00 black      #000000
91    01 white      #ffffff
92    02 Red        #880000
93    03 seafoam    #aaffee
94    04 fuscia     #cc44cc
95    05 green      #00cc55
96    06 blue       #0000aa
97    07 Yellow     #eeee77
98    08 tangerine  #dd8855
99    09 brown      #664400
100    10 salmon     #ff7777
101    11 charcoal   #333333
102    12 smoke      #777777
103    13 lime       #aaff66
104    14 light blue #0088ff
105    15 gray       #bbbbbb
106
107    The plotter state variable of the machine gets passed as the forth
108    parameter. You can use this parameter to store state information.
109
110 */
111 typedef void (*m6502_Plotter) (Bit8, Bit8, Bit8, void*);
112
113 struct machine_6502 {
114   BOOL codeCompiledOK;
115   Bit8 regA;
116   Bit8 regX;
117   Bit8 regY;
118   Bit8 regP;
119   Bit16 regPC; /* A pair of 8 bit registers */
120   Bit16 regSP;
121   Bit16 defaultCodePC;
122   Bit8 memory[MEM_64K];
123   BOOL runForever;
124   int labelPtr;
125   BOOL codeRunning;
126   int myInterval;
127   m6502_Opcodes opcodes[NUM_OPCODES];
128   int screen[32][32];
129   int codeLen;
130   m6502_OpcodeIndex opcache[0xff];
131   m6502_Plotter plot;
132   void *plotterState;
133 };
134
135 /* build6502() - Creates an instance of the 6502 machine */
136 machine_6502 *m6502_build(void);
137
138 /* destroy6502() - compile the file and exectue it until the program
139    is finished */
140 void m6502_destroy6502(machine_6502 *machine);
141
142 /* eval_file() - Compiles and runs a file until the program is
143    finished */
144 void m6502_eval_file(machine_6502 *machine, const char *filename, 
145                m6502_Plotter plot, void *plotterState);
146
147 /* start_eval_file() - Compile the file and execute the first
148    instruction */
149 void m6502_start_eval_file(machine_6502 *machine, const char *filename, 
150                      m6502_Plotter plot, void *plotterState);
151
152 /* XXX
153 void m6502_start_eval_binary(machine_6502 *machine, Bit8 *program,
154                        unsigned int proglen,
155                        Plotter plot, void *plotterState);
156 */
157
158 void m6502_start_eval_string(machine_6502 *machine, const char *code,
159                        m6502_Plotter plot, void *plotterState);
160
161 /* next_eval() - Execute the next insno of machine instructions */
162 void m6502_next_eval(machine_6502 *machine, int insno);
163
164 /* hexDump() - Dumps memory to output */
165 void m6502_hexDump(machine_6502 *machine, Bit16 start, 
166              Bit16 numbytes, FILE *output);
167
168 /* Disassemble() - Prints the assembly code for the program currently
169    loaded in memory.*/
170 void m6502_disassemble(machine_6502 *machine, FILE *output);
171
172 /* trace() - Prints to output the current value of registers, the
173    current nmemonic, memory address and value. */
174 void m6502_trace(machine_6502 *machine, FILE *output);
175
176 /* save_program() - Writes a binary file of the program loaded in
177    memory. */
178 /* XXX
179 void save_program(machine_6502 *machine, const char *filename);
180 */
181 #endif /* __ASM6502_H__ */