ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
vic20.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#ifdef __vic20__
36
37#include "../ugbc.h"
38
39/****************************************************************************
40 * CODE SECTION
41 ****************************************************************************/
42
43void vic20_xpen( Environment * _environment, char * _destination ) {
44
45 // MAKE_LABEL
46
47 // outline0("LDA $D013");
48 // outline0("ASL" );
49 // outline1("STA %s", _destination);
50 // outline1("BCC %s", label );
51 // outline0("LDA #1");
52 // outline1("STA _%s", address_displacement(_environment, _destination, "1"));
53 // outhead1("%s:", label );
54
55}
56
57void vic20_ypen( Environment * _environment, char * _destination ) {
58
59 // MAKE_LABEL
60
61 // outline0("LDA $d014");
62 // outline1("STA %s", _destination);
63 // outline0("LDA #0");
64 // outline1("STA %s", address_displacement(_environment, _destination, "1"));
65
66}
67
68void vic20_inkey( Environment * _environment, char * _pressed, char * _key ) {
69
71
72 outline0("LDA #$0");
73 outline1("STA %s", _pressed );
74 outline0("LDA #$0");
75 outline1("STA %s", _key );
76
77 outline0("LDX $c6");
78 outline0("CPX #$0");
79 outline1("BEQ %snokey", label );
80
81 outline0("LDA $0277" );
82 outline0("CMP #$FF");
83 outline1("BEQ %snopetscii", label );
84 outline1("STA %s", _key );
85 outline0("LDA #$FF");
86 outline1("STA %s", _pressed );
87
88 outline0("LDX #0");
89 outhead1("%sclkeys:", label);
90 outline0("LDA $0278,X" );
91 outline0("STA $0277,X" );
92 outline0("INX");
93 outline0("CPX $c6");
94 outline1("BNE %sclkeys", label);
95 outline0("DEC $c6");
96
97 outline1("JMP %snokey", label );
98
99 outhead1("%snopetscii:", label );
100 outline0("LDA #0");
101 outline1("STA %s", _key );
102 outhead1("%snokey:", label );
103
104}
105
106void vic20_wait_key_or_fire( Environment * _environment, int _port, int _release ) {
107
108}
109
110void vic20_wait_key_or_fire_semivar( Environment * _environment, char * _port, int _release ) {
111
112}
113
114void vic20_wait_fire( Environment * _environment, int _port, int _release ) {
115
116}
117
118void vic20_wait_fire_semivar( Environment * _environment, char * _port, int _release ) {
119
120}
121
122void vic20_scancode( Environment * _environment, char * _pressed, char * _scancode ) {
123
125
126 outline0("LDA #$0");
127 outline1("STA %s", _pressed );
128 outline0("LDA #$40");
129 outline1("STA %s", _scancode );
130
131 outline0("LDY $c5");
132 outline0("CPY #$40");
133 outline1("BEQ %snokey", label );
134
135 outline1("STY %s", _scancode );
136 outline0("LDA #$ff");
137 outline1("STA %s", _pressed );
138
139 outhead1("%snokey:", label );
140
141}
142
143void vic20_key_pressed( Environment * _environment, char *_scancode, char * _result ) {
144
146
147 char nokeyLabel[MAX_TEMPORARY_STORAGE];
148 sprintf( nokeyLabel, "%slabel", label );
149
150 Variable * temp = variable_temporary( _environment, VT_BYTE, "(pressed)" );
151
152 vic20_scancode( _environment, temp->realName, _result );
153 cpu_compare_8bit( _environment, _result, _scancode, temp->realName, 1 );
154 cpu_compare_and_branch_8bit_const( _environment, temp->realName, 0, nokeyLabel, 1 );
155 cpu_store_8bit( _environment, _result, 0xff );
156 cpu_jump( _environment, label );
157 cpu_label( _environment, nokeyLabel );
158 cpu_store_8bit( _environment, _result, 0x00 );
159 cpu_label( _environment, label );
160
161}
162
163void vic20_scanshift( Environment * _environment, char * _shifts ) {
164
165 // // 653
166 // // Shift key indicator. Bits:
167 // // Bit #0: 1 = One or more of left Shift, right Shift or Shift Lock is currently being pressed or locked.
168 // // Bit #1: 1 = Commodore is currently being pressed.
169 // // Bit #2: 1 = Control is currently being pressed.
170 // // NO SHIFT (0) - if no SHIFT key pressed;
171 // // LEFT SHIFT (1) - if the left SHIFT pressed;
172 // // RIGHT SHIFT (2) - if the right SHIFT pressed;
173 // // BOTH SHIFTS (3) - if both keys pressed.
174
175 // MAKE_LABEL
176
177 // outline0("LDA #0");
178 // outline1("STA %s", _shifts);
179 // outline0("LDA #$10");
180 // outline0("STA $DC00");
181 // outline0("LDA $DC01");
182 // outline0("AND #$80");
183 // outline1("BNE %snoleft", label);
184 // outline0("LDA #1");
185 // outline1("STA %s", _shifts);
186 // outhead1("%snoleft:", label );
187
188 // outline0("LDA #$20");
189 // outline0("STA $DC00");
190 // outline0("LDA $DC01");
191 // outline0("AND #$10");
192 // outline1("BNE %snoright", label);
193 // outline1("LDA %s", _shifts);
194 // outline0("ORA #2");
195 // outline1("STA %s", _shifts);
196 // outhead1("%snoright:", label );
197
198}
199
200void vic20_keyshift( Environment * _environment, char * _shifts ) {
201
202 // // On the same way, KEY SHIFT is used to report the current status of those keys
203 // // which cannot be detected by either INKEY$ or SCANCODE because they do not
204 // // carry the relevant codes. These control keys cannot be tested individually, or a test can be set up for any combination of such keys pressed together. A single call to the KEY SHIFT function can test for all eventualities, by examining a bit map in the following format:
205
206 // MAKE_LABEL
207
208 // outline0("LDA #0");
209 // outline1("STA %s", _shifts);
210 // outline0("LDA #$10");
211 // outline0("STA $DC00");
212 // outline0("LDA $DC01");
213 // outline0("AND #$80");
214 // outline1("BNE %snoleft", label);
215 // outline0("LDA #1");
216 // outline1("STA %s", _shifts);
217 // outhead1("%snoleft:", label );
218
219 // outline0("LDA #$20");
220 // outline0("STA $DC00");
221 // outline0("LDA $DC01");
222 // outline0("AND #$10");
223 // outline1("BNE %snoright", label);
224 // outline1("LDA %s", _shifts);
225 // outline0("ORA #2");
226 // outline1("STA %s", _shifts);
227 // outhead1("%snoright:", label );
228
229 // outline0("LDA $028D");
230 // outline0("AND #$01");
231 // outline1("BEQ %snocaps", label);
232 // outline1("LDA %s", _shifts);
233 // outline0("ORA #4");
234 // outline1("STA %s", _shifts);
235 // outhead1("%snocaps:", label );
236
237 // outline0("LDA $028D");
238 // outline0("AND #$04");
239 // outline1("BEQ %snocontrol", label);
240 // outline1("LDA %s", _shifts);
241 // outline0("ORA #8");
242 // outline1("STA %s", _shifts);
243 // outhead1("%snocontrol:", label );
244
245 // outline0("LDA $028D");
246 // outline0("AND #$02");
247 // outline1("BEQ %snoalt", label);
248 // outline1("LDA %s", _shifts);
249 // outline0("ORA #$30");
250 // outline1("STA %s", _shifts);
251 // outhead1("%snoalt:", label );
252
253}
254
255void vic20_clear_key( Environment * _environment ) {
256
257 // outline0("LDA #$0");
258 // outline0("STA $c6");
259
260}
261
262void vic20_sys_call( Environment * _environment, int _destination ) {
263
264 _environment->sysCallUsed = 1;
265
266 outline0("PHA" );
267 outline1("LDA #$%2.2x", (_destination & 0xff ) );
268 outline0("STA SYSCALL0+1");
269 outline1("LDA #$%2.2x", ((_destination>>8) & 0xff ) );
270 outline0("STA SYSCALL0+2");
271 outline0("PLA" );
272 outline0("JSR SYSCALL");
273
274}
275
276void vic20_timer_set_status_on( Environment * _environment, char * _timer ) {
277
279
280 if ( _timer ) {
281 outline1("LDX %s", _timer );
282 } else {
283 outline0("LDX #0" );
284 }
285 outline0("LDY #$1" );
286 outline0("JSR TIMERSETSTATUS" );
287
288}
289
290void vic20_timer_set_status_off( Environment * _environment, char * _timer ) {
291
293
294 if ( _timer ) {
295 outline1("LDX %s", _timer );
296 } else {
297 outline0("LDX #0" );
298 }
299 outline0("LDY #$0" );
300 outline0("JSR TIMERSETSTATUS" );
301
302}
303
304void vic20_timer_set_counter( Environment * _environment, char * _timer, char * _counter ) {
305
307
308 if ( _timer ) {
309 outline1("LDX %s", _timer );
310 } else {
311 outline0("LDX #0" );
312 }
313 if ( _counter ) {
314 outline1("LDA %s", _counter );
315 } else {
316 outline0("LDA #0" );
317 }
318 outline0("STA MATHPTR2");
319 if ( _counter ) {
320 outline1("LDA %s", address_displacement( _environment, _counter, "1" ) );
321 }
322 outline0("STA MATHPTR3");
323 outline0("JSR TIMERSETCOUNTER" );
324
325}
326
327void vic20_timer_set_init( Environment * _environment, char * _timer, char * _init ) {
328
330
331 if ( _timer ) {
332 outline1("LDX %s", _timer );
333 } else {
334 outline0("LDX #0" );
335 }
336 outline1("LDA %s", _init );
337 outline0("STA MATHPTR2");
338 outline1("LDA %s", address_displacement( _environment, _init, "1" ) );
339 outline0("STA MATHPTR3");
340 outline0("JSR TIMERSETINIT" );
341
342}
343
344void vic20_timer_set_address( Environment * _environment, char * _timer, char * _address ) {
345
347
348 if ( _timer ) {
349 outline1("LDX %s", _timer );
350 } else {
351 outline0("LDX #0" );
352 }
353 outline1("LDA #<%s", _address );
354 outline0("STA MATHPTR2");
355 outline1("LDA #>%s", _address );
356 outline0("STA MATHPTR3");
357 outline0("JSR TIMERSETADDRESS" );
358
359}
360
361void vic20_dload( Environment * _environment, char * _filename, char * _offset, char * _address, char * _size ) {
362
363 _environment->sysCallUsed = 1;
364
365 deploy( dload, src_hw_vic20_dload_asm);
366
368
369 Variable * filename = variable_retrieve( _environment, _filename );
370 Variable * tnaddress = variable_temporary( _environment, VT_ADDRESS, "(address of target_name)");
371 Variable * tnsize = variable_temporary( _environment, VT_BYTE, "(size of target_name)");
372
373 Variable * address = NULL;
374 if ( _address ) {
375 address = variable_retrieve( _environment, _address );
376 }
377 Variable * size = NULL;
378 if ( _size ) {
379 size = variable_retrieve( _environment, _size );
380 }
381
382 switch( filename->type ) {
383 case VT_STRING:
384 cpu_move_8bit( _environment, filename->realName, tnsize->realName );
385 cpu_addressof_16bit( _environment, filename->realName, tnaddress->realName );
386 cpu_inc_16bit( _environment, tnaddress->realName );
387 break;
388 case VT_DSTRING:
389 cpu_dsdescriptor( _environment, filename->realName, tnaddress->realName, tnsize->realName );
390 break;
391 }
392
393 outline1("LDA %s", tnaddress->realName);
394 outline0("STA TMPPTR");
395 outline1("LDA %s", address_displacement(_environment, tnaddress->realName, "1"));
396 outline0("STA TMPPTR+1");
397 outline1("LDA %s", tnsize->realName);
398 outline0("STA MATHPTR0");
399
400 if ( address ) {
401
402 outline1("LDA %s", address->realName);
403 outline0("STA TMPPTR2");
404 outline1("LDA %s", address_displacement(_environment, address->realName, "1"));
405 outline0("STA TMPPTR2+1");
406 outline0("LDA #0");
407 outline0("STA MATHPTR1");
408
409 }
410
411 outline0("JSR VIC20DLOAD");
412
413}
414
415void vic20_dsave( Environment * _environment, char * _filename, char * _offset, char * _address, char * _size ) {
416
417 _environment->sysCallUsed = 1;
418
419 deploy( dsave, src_hw_vic20_dsave_asm);
420
422
423 Variable * filename = variable_retrieve( _environment, _filename );
424 Variable * tnaddress = variable_temporary( _environment, VT_ADDRESS, "(address of target_name)");
425 Variable * tnsize = variable_temporary( _environment, VT_BYTE, "(size of target_name)");
426
427 Variable * address = NULL;
428 if ( _address ) {
429 address = variable_retrieve( _environment, _address );
430 }
431 Variable * size = NULL;
432 if ( _size ) {
433 size = variable_retrieve( _environment, _size );
434 }
435
436 switch( filename->type ) {
437 case VT_STRING:
438 cpu_move_8bit( _environment, filename->realName, tnsize->realName );
439 cpu_addressof_16bit( _environment, filename->realName, tnaddress->realName );
440 cpu_inc_16bit( _environment, tnaddress->realName );
441 break;
442 case VT_DSTRING:
443 cpu_dsdescriptor( _environment, filename->realName, tnaddress->realName, tnsize->realName );
444 break;
445 }
446
447 outline1("LDA %s", tnaddress->realName);
448 outline0("STA TMPPTR");
449 outline1("LDA %s", address_displacement(_environment, tnaddress->realName, "1"));
450 outline0("STA TMPPTR+1");
451 outline1("LDA %s", tnsize->realName);
452 outline0("STA MATHPTR0");
453
454 if ( address ) {
455
456 outline1("LDA %s", address->realName);
457 outline0("STA TMPPTR2");
458 outline1("LDA %s", address_displacement(_environment, address->realName, "1"));
459 outline0("STA TMPPTR2+1");
460 outline0("LDA #0");
461 outline0("STA MATHPTR1");
462
463 }
464
465 if ( size ) {
466
467 outline1("LDA %s", size->realName);
468 outline0("STA MATHPTR4");
469 outline1("LDA %s", address_displacement(_environment, size->realName, "1"));
470 outline0("STA MATHPTR5");
471
472 } else {
473
474 outline0("LDA #$00");
475 outline0("STA MATHPTR4");
476 outline0("STA MATHPTR5");
477
478 }
479
480 outline0("JSR VIC20DSAVE");
481
482}
483
484void vic20_put_key( Environment * _environment, char *_string, char * _size ) {
485
487
488 _environment->bitmaskNeeded = 1;
489
490 outline1("LDA %s", _string );
491 outline0("STA TMPPTR" );
492 outline1("LDA %s", address_displacement( _environment, _string, "1" ) );
493 outline0("STA TMPPTR+1" );
494
495 outline0("LDY #0");
496 outline0("LDX $c6");
497 outhead1("%sputkey:", label);
498 outline0("LDA (TMPPTR),Y" );
499 outline0("STA $0277,X" );
500 outline0("INY");
501 outline0("INX");
502 outline1("CPY %s", _size );
503 outline1("BNE %sputkey", label);
504 outline0("STX $c6");
505
506}
507#endif
void cpu_compare_8bit(Environment *_environment, char *_source, char *_destination, char *_other, int _positive)
CPU 6309: emit code to compare two 8 bit values
Definition 6309.c:811
void cpu_addressof_16bit(Environment *_environment, char *_source, char *_destination)
Definition 6309.c:1485
void cpu_label(Environment *_environment, char *_label)
Definition 6309.c:356
void cpu_store_8bit(Environment *_environment, char *_destination, int _value)
CPU 6309: emit code to store 8 bit
Definition 6309.c:761
void cpu_jump(Environment *_environment, char *_label)
Definition 6309.c:3739
void cpu_inc_16bit(Environment *_environment, char *_variable)
Definition 6309.c:4565
void cpu_move_8bit(Environment *_environment, char *_source, char *_destination)
CPU 6309: emit code to move 8 bit
Definition 6309.c:743
void cpu_dsdescriptor(Environment *_environment, char *_index, char *_address, char *_size)
Definition 6309.c:5977
void cpu_compare_and_branch_8bit_const(Environment *_environment, char *_source, int _destination, char *_label, int _positive)
CPU 6309: emit code to compare two 8 bit values and jump if they are equal/different
Definition 6309.c:876
unsigned char src_hw_6502_timer_asm[]
Definition 6502_timer.c:1
Variable * variable_retrieve(Environment *_environment, char *_name)
Variable * variable_temporary(Environment *_environment, VariableType _type, char *_meaning)
Define a temporary variable.
char * address_displacement(Environment *_environment, char *_address, char *_displacement)
int size
Definition _optimizer.c:678
void dload(Environment *_environment, char *_filename, char *_offset, char *_address, char *_bank, char *_size)
Emit code for DLOAD(...).
Definition dload.c:60
void dsave(Environment *_environment, char *_filename, char *_offset, char *_address, char *_size)
Emit code for DLOAD(...).
Definition dsave.c:58
int bitmaskNeeded
Definition ugbc.h:2659
int sysCallUsed
Definition ugbc.h:3162
char * realName
Definition ugbc.h:982
#define MAX_TEMPORARY_STORAGE
Definition ugbc.h:563
struct _Variable Variable
Structure of a single variable.
struct _Environment Environment
Structure of compilation environment.
@ VT_STRING
Definition ugbc.h:474
@ VT_BYTE
Definition ugbc.h:450
@ VT_ADDRESS
Definition ugbc.h:465
@ VT_DSTRING
Definition ugbc.h:483
#define outline0(s)
Definition ugbc.h:4252
#define outline1(s, a)
Definition ugbc.h:4253
#define deploy(s, e)
Definition ugbc.h:4288
#define MAKE_LABEL
Definition ugbc.h:3351
#define outhead1(s, a)
Definition ugbc.h:4247
void vic20_ypen(Environment *_environment, char *_destination)
Definition vic20.c:57
void vic20_key_pressed(Environment *_environment, char *_scancode, char *_result)
Definition vic20.c:143
void vic20_inkey(Environment *_environment, char *_pressed, char *_key)
Definition vic20.c:68
void vic20_scancode(Environment *_environment, char *_pressed, char *_scancode)
Definition vic20.c:122
void vic20_keyshift(Environment *_environment, char *_shifts)
Definition vic20.c:200
void vic20_clear_key(Environment *_environment)
Definition vic20.c:255
void vic20_timer_set_init(Environment *_environment, char *_timer, char *_init)
Definition vic20.c:327
void vic20_xpen(Environment *_environment, char *_destination)
Definition vic20.c:43
void vic20_put_key(Environment *_environment, char *_string, char *_size)
Definition vic20.c:484
void vic20_wait_fire(Environment *_environment, int _port, int _release)
Definition vic20.c:114
void vic20_timer_set_status_off(Environment *_environment, char *_timer)
Definition vic20.c:290
void vic20_timer_set_address(Environment *_environment, char *_timer, char *_address)
Definition vic20.c:344
void vic20_wait_key_or_fire(Environment *_environment, int _port, int _release)
Definition vic20.c:106
void vic20_sys_call(Environment *_environment, int _destination)
Definition vic20.c:262
void vic20_scanshift(Environment *_environment, char *_shifts)
Definition vic20.c:163
void vic20_dload(Environment *_environment, char *_filename, char *_offset, char *_address, char *_size)
Definition vic20.c:361
void vic20_timer_set_status_on(Environment *_environment, char *_timer)
Definition vic20.c:276
void vic20_wait_fire_semivar(Environment *_environment, char *_port, int _release)
Definition vic20.c:118
void vic20_timer_set_counter(Environment *_environment, char *_timer, char *_counter)
Definition vic20.c:304
void vic20_dsave(Environment *_environment, char *_filename, char *_offset, char *_address, char *_size)
Definition vic20.c:415
void vic20_wait_key_or_fire_semivar(Environment *_environment, char *_port, int _release)
Definition vic20.c:110