Refactor controller runtime code generation
[lsnes.git] / include / library / controller-parse-asmgen.hpp
blobb06ff2f6d95c4f46d4c5ddffd56e13438055f742
1 #ifndef _library__controller_parse_asmgen__hpp__included__
2 #define _library__controller_parse_asmgen__hpp__included__
4 #include "assembler.hpp"
6 namespace codegen
8 //Emit function prologue for serialization function. This also Initializes the read position to start of
9 //serialization buffer.
11 //The serialization function takes three parameters. In order:
12 // - Dummy pointer (to be ignored).
13 // - Readonly controller state (pointer).
14 // - serialization output buffer (pointer).
16 template<class T> void emit_serialize_prologue(T& a, assembler::label_list& labels);
18 //Emit code to serialize a button.
20 //The button is emitted to current write position as specified character if set, '.' if not set. Advances write
21 //position by one byte.
23 //Parameters:
24 // - offset: The byte in controller state the button bit is in (0-based).
25 // - mask: Bitmask for the button bit.
26 // - ch: The character to use for writing pressed button.
28 template<class T> void emit_serialize_button(T& a, assembler::label_list& labels, int32_t offset, uint8_t mask,
29 uint8_t ch);
31 //Emit code to serialize an axis.
33 //Call write_axis_value() in order to serialize the axis. Advance write position by indicated number of bytes.
35 //Parameters:
36 // - offset: The low byte of axis in controller state (the high byte is at <offset>+1). This field is signed.
38 template<class T> void emit_serialize_axis(T& a, assembler::label_list& labels, int32_t offset);
40 //Emit code to write a pipe sign ('|').
42 //Emit a '|' to current write position. Advance write position by one byte.
44 template<class T> void emit_serialize_pipe(T& a, assembler::label_list& labels);
46 //Emit function epilogue for serialization function.
48 //Serialization function returns the number of bytes in serialized output. The return type is size_t.
50 template<class T> void emit_serialize_epilogue(T& a, assembler::label_list& labels);
52 //Emit function prologue for deserialization function. This also initializes the read position to start of
53 //serialization buffer.
55 //The serialization function takes three parameters. In order:
56 // - Dummy pointer (to be ignored).
57 // - controller state to be modified (pointer).
58 // - readonly serialization input buffer (pointer).
60 template<class T> void emit_deserialize_prologue(T& a, assembler::label_list& labels);
62 //Emit code to clear the controller state.
64 //Parameters:
65 // - size: The number of bytes in controller state.
66 template<class T> void emit_deserialize_clear_storage(T& a, assembler::label_list& labels, int32_t size);
68 //Emit code to deserialize button.
70 //- If the current read position has '|', jump to <next_pipe> without advancing or modifying controller state.
71 //- If the current read position has '\r', \n' or '\0', jump to <end_deserialize> without advancing or modifying
72 // controller state.
73 //- If the current read position has anything except '.' or ' ', set the corresponding bit in controller state.
74 //- If the first two cases do not apply, advance read position by one byte.
76 // Parameters:
77 // - offset: The byte offset in controller state the button bit is in (0-based).
78 // - mask: Bitmask for the button bit.
79 // - next_pipe: Label to jump to when finding '|'.
80 // - end_deserialize: Label to jump to when finding end of input.
82 template<class T> void emit_deserialize_button(T& a, assembler::label_list& labels, int32_t offset,
83 uint8_t mask, assembler::label& next_pipe, assembler::label& end_deserialize);
85 //Emit code to deserialize axis.
87 //Call read_axis_value() in order to deserialize the value. Advance read position by indicated number of bytes.
89 // Parameters:
90 // - offset: The low byte of axis in controller state (the high byte is at <offset>+1). This field is signed.
92 template<class T> void emit_deserialize_axis(T& a, assembler::label_list& labels, int32_t offset);
94 //Emit code to skip until next pipe ('|')
96 //While current read position does not contain '|', '\r', '\n' nor '\0', advance current read position.
97 //If '|' is encountered, jump to <next_pipe>. If '\r', '\n' or '\0' is encountered, jump to <deserialize_end>.
99 // Parameters:
100 // - next_pipe: Address to jump to if '|' is found.
101 // - deserialize_end: Address to jump to if '\r', '\n' or '\0' is found.
103 template<class T> void emit_deserialize_skip_until_pipe(T& a, assembler::label_list& labels,
104 assembler::label& next_pipe, assembler::label& deserialize_end);
106 //Emit code to advance read position by one byte.
108 //Advance the read position by one byte. This is used to skip '|' bytes.
110 template<class T> void emit_deserialize_skip(T& a, assembler::label_list& labels);
112 //Emit code to arrange deserialization function to return DESERIALIZE_SPECIAL_BLANK instead of byte count.
114 //This changes the return value of deserialization function to DESERIALIZE_SPECIAL_BLANK.
116 template<class T> void emit_deserialize_special_blank(T& a, assembler::label_list& labels);
118 //Emit function epilogue for serialization function.
120 //Deserialization function returns the number of bytes in serialized input (or the special value
121 //DESERIALIZE_SPECIAL_BLANK). The return type is size_t.
123 template<class T> void emit_deserialize_epilogue(T& a, assembler::label_list& labels);
125 //Emit function prologue for Read function.
127 //The read function takes four parameters. In order:
128 // - Dummy pointer (to be ignored).
129 // - controller state to be queried.
130 // - controller number (unsigned)
131 // - control index number (unsigned)
133 //Initialze pending return value to 0.
135 template<class T> void emit_read_prologue(T& a, assembler::label_list& labels);
137 //Emit function epilogue for read function.
139 //The read function returns the pending return value (short):
140 // - 0 => Invalid control, or released button.
141 // - 1 => Pressed button.
142 // - (other) => Axis value.
144 template<class T> void emit_read_epilogue(T& a, assembler::label_list& labels);
146 //Emit dispatch code for read/write function.
148 //Read dispatch table immediately after the code generated by this and jump to obtained address. The table layout
149 //is controls from low to high number, controllers from low to high number. Each controller has 2^<ilog2controls>
150 //entries.
152 // Parameters:
153 // - controllers: Number of controllers.
154 // - ilog2controls: Two's logarithm of number of controls per controller (rounded up).
155 // - end: Label pointing to code causing read/write function to return.
157 template<class T> void emit_read_dispatch(T& a, assembler::label_list& labels,
158 unsigned controllers, unsigned ilog2controls, assembler::label& end);
160 //Emit a jump pointer.
162 //Emits a jump pointer read by emit_read_dispatch() and returns reference to the pointer target.
164 // Return value:
165 // - The newly created label to code this jumps to.
167 template<class T> assembler::label& emit_read_label(T& a, assembler::label_list& labels);
169 //Emit a specfied jump pointer.
171 //Emits a jump pointer read by emit_read_dispatch() pointing to specified label.
173 // Parameters:
174 // - b: The code to jump to.
176 template<class T> void emit_read_label_bad(T& a, assembler::label_list& labels, assembler::label& b);
178 //Emit code to read button value.
180 //If the specified bit is set, set pending return value to 1. Then jump to <end>.
182 // Parameters:
183 // - l: Label for the code fragment itself (this needs to be defined).
184 // - end: Code to return from the read function.
185 // - offset: Byte offset within controller state (0-based).
186 // - mask: Bitmask for the button bit.
188 template<class T> void emit_read_button(T& a, assembler::label_list& labels, assembler::label& l,
189 assembler::label& end, int32_t offset, uint8_t mask);
191 //Emit code to read axis value.
193 //Set pending return value to value in specified location. Then jump to <end>.
195 // Parameters:
196 // - l: Label for the code fragment itself (this needs to be defined).
197 // - end: Code to return from the read function.
198 // - offset: Low byte offset in controller state (high byte is at <offset>+1). Signed.
200 template<class T> void emit_read_axis(T& a, assembler::label_list& labels, assembler::label& l,
201 assembler::label& end, int32_t offset);
203 //Emit function prologue for Write function.
205 //The write function takes five parameters. In order:
206 // - Dummy pointer (to be ignored).
207 // - controller state to be queried.
208 // - controller number (unsigned)
209 // - control index number (unsigned)
210 // - value to write (short).
212 template<class T> void emit_write_prologue(T& a, assembler::label_list& labels);
214 //Emit epilogue for write function.
216 //Write function does not return anything.
218 template<class T> void emit_write_epilogue(T& a, assembler::label_list& labels);
220 //Emit code to write button value.
222 //If the value to write is nonzero, set specified bit to 1, otherwise set it to 0. Then jump to <end>.
224 // Parameters:
225 // - l: Label for the code fragment itself (this needs to be defined).
226 // - end: Code to return from the write function.
227 // - offset: Byte offset within controller state (0-based).
228 // - mask: Bitmask for the button bit.
230 template<class T> void emit_write_button(T& a, assembler::label_list& labels, assembler::label& l,
231 assembler::label& end, int32_t offset, uint8_t mask);
233 //Emit code to write axis value.
235 //Write the value to write to specified location. Then jump to <end>.
237 // Parameters:
238 // - l: Label for the code fragment itself (this needs to be defined).
239 // - end: Code to return from the write function.
240 // - offset: Low byte offset in controller state (high byte is at <offset>+1). Signed.
242 template<class T> void emit_write_axis(T& a, assembler::label_list& labels, assembler::label& l,
243 assembler::label& end, int32_t offset);
246 #endif