ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
blit_define.c
Go to the documentation of this file.
1/*****************************************************************************
2 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
3 *****************************************************************************
4 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *----------------------------------------------------------------------------
18 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
19 * (la "Licenza"); è proibito usare questo file se non in conformità alla
20 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
21 *
22 * http://www.apache.org/licenses/LICENSE-2.0
23 *
24 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
25 * il software distribuito nei termini della Licenza è distribuito
26 * "COSÌ COM'È", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
27 * implicite. Consultare la Licenza per il testo specifico che regola le
28 * autorizzazioni e le limitazioni previste dalla medesima.
29 ****************************************************************************/
30
31/****************************************************************************
32 * INCLUDE SECTION
33 ****************************************************************************/
34
35#include "../../ugbc.h"
36
37/****************************************************************************
38 * CODE SECTION
39 ****************************************************************************/
40
41extern char DATATYPE_AS_STRING[][16];
42
43static void blit_define_bltu( Environment * _environment, int _op, char * _a, char * _c ) {
44
45 // outline3("; blit_define_bltu( %d, %s, %s )", _op, _a, _c );
46
47 if ( _op == ( 1 << _environment->currentModeBW ) + 3 ) {
48
50 outline0("; bltu C = (2^bpp-1) if A > 0 (threshold)");
51 switch( _environment->currentModeBW ) {
52 case 1:
53 outline1("LD A, %s", _a );
54 outline1("LD %s, A", _c );
55 break;
56 case 2:
57 outline0("LD A, 0" );
58 outline1("LD %s, A", _c );
59 outline1("LD A, %s", _a );
60 outline0("AND $11" );
61 outline0("CMP 0" );
62 outline1("JR Z, %sthreshold1", label );
63 outline0("LD A, $11" );
64 outline1("LD %s, A", _c );
65 outhead1("%sthreshold1:", label );
66 outline1("LD A, %s", _a );
67 outline0("AND $22" );
68 outline0("CMP 0" );
69 outline1("JR Z, %sthreshold2", label );
70 outline0("LD A, $22" );
71 outline1("OR %s", _c );
72 outline1("LD %s, A", _c );
73 outhead1("%sthreshold2:", label );
74 outline1("LD A, %s", _a );
75 outline0("AND $44" );
76 outline0("CMP 0" );
77 outline1("JR Z, %sthreshold3", label );
78 outline0("LD A, $44" );
79 outline1("OR %s", _c );
80 outline1("LD %s, A", _c );
81 outhead1("%sthreshold3:", label );
82 outline1("LD A, %s", _a );
83 outline0("AND $88" );
84 outline0("CMP 0" );
85 outline1("JR Z, %sthreshold4", label );
86 outline0("LD A, $88" );
87 outline1("OR %s", _c );
88 outline1("LD %s, A", _c );
89 outhead1("%sthreshold4:", label );
90 break;
91 case 4:
92 outline0("LD A, 0" );
93 outline1("LD %s, A", _c );
94 outline1("LD A, %s", _a );
95 outline0("AND $aa" );
96 outline0("CMP 0" );
97 outline1("JR Z, %sthreshold1", label );
98 outline0("LD A, $aa" );
99 outline1("LD %s, A", _c );
100 outhead1("%sthreshold1:", label );
101 outline1("LD A, %s", _a );
102 outline0("AND $55" );
103 outline0("CMP 0" );
104 outline1("JR Z, %sthreshold2", label );
105 outline0("LD A, $55" );
106 outline1("OR %s", _c );
107 outline1("LD %s, A", _c );
108 outhead1("%sthreshold2:", label );
109 break;
110 }
111 } else if ( _op == ( 1 << _environment->currentModeBW ) + 2 ) {
112 outline0("; bltu C = 0 (ignore)");
113 outline0("LD A, 0" );
114 outline1("LD %s, A", _c );
115 } else if ( _op == ( 1 << _environment->currentModeBW ) + 1 ) {
116 outline0("; bltu C = !A (not)");
117 outline1("LD A, %s", _a );
118 outline0("XOR $ff");
119 outline1("LD %s, A", _c );
120 } else if ( _op == ( 1 << _environment->currentModeBW ) ) {
121 outline0("; bltu C = A (copy)");
122 outline1("LD A, %s", _a );
123 outline1("LD %s, A", _c );
124 } else if ( _op < ( 1 << _environment->currentModeBW ) ) {
125 unsigned char value = 0;
126 switch( _environment->currentModeBW ) {
127 case 1:
128 if ( _op ) {
129 value = 0xff;
130 } else {
131 value = 0x00;
132 }
133 break;
134 case 2:
135 value = ( ( _op & 0x1 ) );
136 value |= ( ( ( _op & 0x2 ) ) << 3 );
137 value = value | ( value << 1 ) | ( value << 2 ) | ( value << 3 );
138 break;
139 case 4:
140 value = ( ( _op & 0x8 ) >> 3 );
141 value |= ( ( ( _op & 0x2 ) ) << 1 );
142 value |= ( ( ( _op & 0x4 ) ) << 2 );
143 value |= ( ( ( _op & 0x1 ) ) << 6 );
144 value = value | ( value << 1 );
145 break;
146 }
147 outline0("; bltu C = value");
148 outline1("LD A, $%2.2x", value );
149 outline1("LD %s, A", _c );
150 }
151
152}
153
154static void blit_define_bltb( Environment * _environment, int _op, char * _a, char * _b, char * _d ) {
155
156 // outline4("; blit_define_bltb( %d, %s, %s, %s )", _op, _a, _b, _d );
157
158 if ( _op == 0 ) {
159 outline0("; bltb C = A and B");
160 outline1("LD A, %s", _a );
161 outline1("LD %s, A", _d );
162 outline1("LD A, %s", _b );
163 outline1("AND %s", _d );
164 outline1("LD %s, A", _d );
165 } else if ( _op == 1 ) {
166 outline0("; bltb C = A or B");
167 outline1("LD A, %s", _a );
168 outline1("LD %s, A", _d );
169 outline1("LD A, %s", _b );
170 outline1("OR %s", _d );
171 outline1("LD %s, A", _d );
172 } else if ( _op == 2 ) {
173 outline0("; bltb C = A xor B");
174 outline1("LD A, %s", _a );
175 outline1("LD %s, A", _d );
176 outline1("LD A, %s", _b );
177 outline1("XOR %s", _d );
178 outline1("LD %s, A", _d );
179 } else if ( _op == 3 ) {
180 outline0("; bltb C = A");
181 outline1("LD A, %s", _a );
182 outline1("LD %s, A", _d );
183 } else if ( _op == 4 ) {
184 outline0("; bltb C = B");
185 outline1("LD A, %s", _b );
186 outline1("LD %s, A", _d );
187 } else if ( _op == 5 ) {
188 outline0("; bltb C = A if B>0, 0 if B=0");
190 switch( _environment->currentModeBW ) {
191 case 1:
192 outline1("LD A, %s", _a );
193 outline1("AND %s", _b );
194 outline1("LD %s, A", _d );
195 break;
196 case 2:
197 outline1("LD A, %s", _a );
198 outline1("LD %s, A", _d );
199 outline1("LD A, %s", _b );
200 outline0("AND $11" );
201 outline0("CMP 0" );
202 outline1("JR NZ, %smask1", label );
203 outline1("LD A, %s", _d );
204 outline0("AND $ee" );
205 outline1("LD %s, A", _d );
206 outhead1("%smask1:", label );
207 outline1("LD A, %s", _b );
208 outline0("AND $22" );
209 outline0("CMP 0" );
210 outline1("JR NZ, %smask2", label );
211 outline1("LD A, %s", _d );
212 outline0("AND $dd" );
213 outline1("LD %s, A", _d );
214 outhead1("%smask2:", label );
215 outline1("LD A, %s", _b );
216 outline0("AND $44" );
217 outline0("CMP 0" );
218 outline1("JR NZ, %smask3", label );
219 outline1("LD A, %s", _d );
220 outline0("AND $bb" );
221 outline1("LD %s, A", _d );
222 outhead1("%smask3:", label );
223 outline1("LD A, %s", _b );
224 outline0("AND $88" );
225 outline0("CMP 0" );
226 outline1("JR NZ, %smask4", label );
227 outline1("LD A, %s", _d );
228 outline0("AND $77" );
229 outline1("LD %s, A", _d );
230 outhead1("%smask4:", label );
231 break;
232 case 4:
233 outline1("LD A, %s", _a );
234 outline1("LD %s, A", _d );
235 outline1("LD A, %s", _b );
236 outline0("AND $aa" );
237 outline0("CMP 0" );
238 outline1("JR NZ, %smask1", label );
239 outline1("LD A, %s", _d );
240 outline0("AND $55" );
241 outline1("LD %s, A", _d );
242 outhead1("%smask1:", label );
243 outline1("LD A, %s", _b );
244 outline0("AND $55" );
245 outline0("CMP 0" );
246 outline1("JR NZ, %smask2", label );
247 outline1("LD A, %s", _d );
248 outline0("AND $aa" );
249 outline1("LD %s, A", _d );
250 outhead1("%smask2:", label );
251 break;
252 }
253 }
254
255}
256
267void blit_define( Environment * _environment, char * _name, int _sop, int _mop, int _smop, int _iop, int _dop, int _idop, int _top ) {
268
269 // outline0("; blit_define( ....)" );
270
271 char blitLabel[MAX_TEMPORARY_STORAGE]; sprintf( blitLabel, "_%sblit", _name );
272 char skipLabel[MAX_TEMPORARY_STORAGE]; sprintf( skipLabel, "_%sskip", _name );
273
274 cpu_jump( _environment, skipLabel );
275 cpu_label( _environment, blitLabel );
276
277 // B = s(x,y)
278 // IYL = d(x, y)
279 // IYH = m(x, y)
280
281 outline0("PUSH HL");
282 outline0("PUSH DE");
283
284 // BLITSU
285 blit_define_bltu( _environment, _sop, "B", "H" );
286
287 // BLITMU
288 blit_define_bltu( _environment, _mop, "IYH", "L" );
289
290 // BLITSM
291 blit_define_bltb( _environment, _smop, "H", "L", "D" );
292
293 // BLITSMU
294 blit_define_bltu( _environment, _iop, "D", "H" );
295
296 // BLITDU
297 blit_define_bltu( _environment, _dop, "IYL", "L" );
298
299 // BLITT
300 blit_define_bltb( _environment, _idop, "H", "L", "D" );
301
302 // BLITTU
303 blit_define_bltu( _environment, _top, "D", "E" );
304
305 outline0("LD A, E");
306 outline0("POP DE");
307 outline0("POP HL");
308
309 cpu_return( _environment );
310 cpu_label( _environment, skipLabel );
311
312}
313
314static const char BLIT_SOURCES_REGISTER[][4] = {
315 "IYL", // destination
316 "B", // source 1
317 "IYH", // source 2
318};
319
320void blit_define_begin_compound( Environment * _environment, char * _name ) {
321
322 // outline1("; blit_define_begin_compound( %s )", _name );
323
324 char blitLabel[MAX_TEMPORARY_STORAGE]; sprintf( blitLabel, "_%sblit", _name );
325 char skipLabel[MAX_TEMPORARY_STORAGE]; sprintf( skipLabel, "_%sskip", _name );
326
327 if ( variable_exists( _environment, _name ) ) {
329 }
330 Variable * var = variable_define( _environment, _name, VT_BLIT, 0 );
331
332 memset( &_environment->blit, 0, sizeof( Blit ) );
333
334 _environment->blit.name = strdup( _name );
335 _environment->blit.realName = strdup( var->realName );
336
337 cpu_jump( _environment, skipLabel );
338 cpu_label( _environment, blitLabel );
339
340 cpu_blit_initialize( _environment );
341
342}
343
344void blit_define_compound_operand_to_register( Environment * _environment, int _register, int _source ) {
345
346 // outline2("; blit_define_compound_operand_to_register( %d, %d )", _register, _source );
347
348 char * reg = cpu_blit_register_name( _environment, _register ) ;
349
350 outline1( "LD A, %s", &BLIT_SOURCES_REGISTER[_source][0] );
351 outline1( "LD %s, A", reg );
352
353}
354
355void blit_define_compound_unary( Environment * _environment, int _operation, int _operand, int _result ) {
356
357 blit_define_bltu( _environment, _operation, cpu_blit_register_name( _environment, _operand ), cpu_blit_register_name( _environment, _result ) );
358
359}
360
361void blit_define_compound_binary( Environment * _environment, int _operation, int _operand1, int _operand2, int _result ) {
362
363 blit_define_bltb( _environment, _operation, cpu_blit_register_name( _environment, _operand1 ), cpu_blit_register_name( _environment, _operand2 ), cpu_blit_register_name( _environment, _result ) );
364
365}
366
367void blit_define_end_compound( Environment * _environment, int _result ) {
368
369 // outline1("; blit_define_end_compound( %d )", _result );
370
371 char skipLabel[MAX_TEMPORARY_STORAGE]; sprintf( skipLabel, "_%sskip", _environment->blit.name );
372 char blitStageAreaName[MAX_TEMPORARY_STORAGE]; sprintf( blitStageAreaName, "%sbs", _environment->blit.name );
373
374 Variable * blitStageArea = variable_define( _environment, blitStageAreaName, VT_BUFFER, 0 );
375 variable_resize_buffer( _environment, blitStageArea->name, _environment->blit.usedMemory );
376
377 char * reg = cpu_blit_register_name( _environment, _result ) ;
378
379 outline1( "LD A, %s", reg );
380
381 cpu_blit_finalize( _environment );
382
383 cpu_return( _environment );
384 cpu_label( _environment, skipLabel );
385
386}
char * cpu_blit_register_name(Environment *_environment, int _register)
Definition 6309.c:6417
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_blit_finalize(Environment *_environment)
Definition 6309.c:6410
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
void cpu_return(Environment *_environment)
Definition 6309.c:4030
void cpu_blit_initialize(Environment *_environment)
Definition 6309.c:6403
int variable_exists(Environment *_environment, char *_name)
Variable * variable_resize_buffer(Environment *_environment, char *_destination, int _size)
Resize the (static) size of a buffer.
Variable * variable_define(Environment *_environment, char *_name, VariableType _type, int _value)
Define a variable for the program.
void blit_define(Environment *_environment, char *_name, int _sop, int _mop, int _smop, int _iop, int _dop, int _idop, int _top)
Emit ASM code for BLIT IMAGE [image] AT [int],[int].
void blit_define_compound_binary(Environment *_environment, int _operation, int _operand1, int _operand2, int _result)
void blit_define_compound_unary(Environment *_environment, int _operation, int _operand, int _result)
void blit_define_begin_compound(Environment *_environment, char *_name)
void blit_define_compound_operand_to_register(Environment *_environment, int _register, int _source)
void blit_define_end_compound(Environment *_environment, int _result)
int usedMemory
Definition ugbc.h:2167
char * name
Definition ugbc.h:2164
char * realName
Definition ugbc.h:2165
Blit blit
Definition ugbc.h:2474
int currentModeBW
Definition ugbc.h:2701
char * name
Definition ugbc.h:979
char * realName
Definition ugbc.h:982
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
struct _Blit Blit
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_BLIT
Definition ugbc.h:519
@ VT_BUFFER
Definition ugbc.h:477
#define outline0(s)
Definition ugbc.h:4252
#define CRITICAL_BLIT_ALREADY_DEFINED(n)
Definition ugbc.h:3615
#define outline1(s, a)
Definition ugbc.h:4253
#define MAKE_LABEL
Definition ugbc.h:3351
#define outhead1(s, a)
Definition ugbc.h:4247
char DATATYPE_AS_STRING[][16]