ugBASIC 1.18
An isomorphic BASIC language compiler for retrocomputers
Loading...
Searching...
No Matches
antic.h
Go to the documentation of this file.
1#ifndef __UGBC_ANTIC__
2#define __UGBC_ANTIC__
3
4/*****************************************************************************
5 * ugBASIC - an isomorphic BASIC language compiler for retrocomputers *
6 *****************************************************************************
7 * Copyright 2021-2026 Marco Spedaletti (asimov@mclink.it)
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *----------------------------------------------------------------------------
21 * Concesso in licenza secondo i termini della Licenza Apache, versione 2.0
22 * (la "Licenza"); è proibito usare questo file se non in conformità alla
23 * Licenza. Una copia della Licenza è disponibile all'indirizzo:
24 *
25 * http://www.apache.org/licenses/LICENSE-2.0
26 *
27 * Se non richiesto dalla legislazione vigente o concordato per iscritto,
28 * il software distribuito nei termini della Licenza è distribuito
29 * "COSì COM'è", SENZA GARANZIE O CONDIZIONI DI ALCUN TIPO, esplicite o
30 * implicite. Consultare la Licenza per il testo specifico che regola le
31 * autorizzazioni e le limitazioni previste dalla medesima.
32 ****************************************************************************/
33
34/****************************************************************************
35 * INCLUDE SECTION
36 ****************************************************************************/
37
38#include "../ugbc.h"
39
40/****************************************************************************
41 * CODE SECTION
42 ****************************************************************************/
43
44#define DLI_COUNT 1024
45
46/*
47
48Display Lists
49We introduced you briefly in chapter I to a graphics microprocessor called ANTIC that
50is capable of displaying any of fourteen graphics modes. Since any screen actually
51consists of a collection or vertical stack of these individual graphics modes, ANTIC
52looks to a program called the display list to determine in which graphics mode it
53should display the screen data. The fact that there is something resembling a graphics
54display instruction set makes the computer extremely flexible. It becomes possible to
55display any collection of graphics modes from data in screen memory that can be stored
56virtually anywhere within the computer's RAM memory. This flexibility allows the user
57to mix graphics modes and even scroll the screen in any direction by altering the
58portion of screen memory displayed.
59
60ANTIC, like most true microprocessors, has an instruction set that is used to write
61the display list program. The display list specifies three things: where the screen
62data is located, what display modes to use to interpret the screen data, and what
63special display options, if any, to implement.
64
65Antic Instruction Set
66ANTIC has a simple instruction set with only four basic instruction types.
67-there are map mode instructions, character mode instructions,
68 blank line instructions, and jump instructions.
69
70Map mode instructions instruct ANTIC to display a mode line as colored pixels,
71while character mode instructions tell ANTIC to display a mode line with character
72data either from its internal ROM or from your own custom designed set.
73Blank line instructions instruct ANTIC to display a number of horizontal scan
74lines with solid background color. Like GOTO statements in BASIC, jump instructions
75change the value in ANTIC's program counter so that it looks for its next opcode
76somewhere else.
77
78Special Options or Modifiers
79ANTIC also has a number of special options or modifiers to its map and character
80mode instructions. These are specified by setting one of four high bits in the
81instruction set. These options are load memory scan (LMS), display list interrupt
82(DLI), vertical scroll, and horizontal scroll.
83
84The load memory scan option is the most frequently used option for it occurs at
85least once in every display list. It specifies where the screen data is stored
86in memory. Technically, only one of these instructions is actually needed in
87any series of display modes because screen memory is usually continuous.
88However, if memory isn't continuous, either within a particular display mode
89or at the boundry between different modes, an LMS instruction is needed
90each time a new section of memory is used. Another instance where an
91additional LMS instruction is required, is in ANTIC modes E and F (GRAPHICS 8)
92where continuous screen memory crosses a 4K boundary. The load memory scan
93option is invoked by adding a decimal 64 ($40) to the map or character in the
94 mode instruction. This is equivalent to setting the sixth bit in the instruction.
95LMS instructions are three bytes long. The first byte is the opcode specifying
96the mode and the last two bytes contain the address of screen memory in low byte,
97high byte order.
98
99The other three modifiers are sometimes used by Assembly language programmers
100to achieve special effects. Setting bit 7 or adding 128 to the opcode enables
101a display list interrupt. Execution of this instruction causes ANTIC to force the
1026502 to generate an interrupt. The interrupt service routine will be at the
103address pointed to in memory locations 512,513 decimal ($200, 201).
104
105Display list interrupts are often used to change the colors in the color
106registers over part of a screen or to change between character sets midway
107down the screen. We will discuss these uses in detail in chapter
1086 and 4, respectively.
109
110Horizontal scrolling can be set up by adding 16 to the opcode or setting bit 4.
111Likewise, you enable vertical scrolling by adding 32 to the opcode or by
112setting bit five. These modifiers allow you to fine scroll the screen in
113either direction. Naturally if you are planning to scroll through memory
114by changing the start of screen memory, you will need to combine your
115scroll modifier with a load memory scan modifier.
116This technique will be shown in more detail in chapter 7.
117
118Note:
1191) Display List Interrupts can be enabled by adding 128 decimal, $80 Hex to above values
1202) Since it is impractical to do horizontal scrolling without a LMS instruction values are not referenced.
121
122load memory scan (LMS)
123
124*/
125
126#define DLI_MODE( _list, _n ) \
127 *_list++ = ((unsigned char)( /*0x30 |*/ _n ));
128
129#define DLI_MODE_VSCROLL( _list, _n ) \
130 *_list++ = ((unsigned char)( 0x20 | _n ));
131
132#define DLI_MODE_VSCROLL_IRQ( _list, _n ) \
133 *_list++ = ((unsigned char)( 0x20 | 0x80 | _n ));
134
135#define DLI_MODE_VHSCROLL( _list, _n ) \
136 *_list++ = ((unsigned char)( 0x10 | 0x20 | _n ));
137
138#define DLI_MODE_VHSCROLL_IRQ( _list, _n ) \
139 *_list++ = ((unsigned char)( 0x10 | 0x20 | 0x80 | _n ));
140
141#define DLI_LMS( _list, _n, _addr ) \
142 *_list++ = ((unsigned char)( /*0x30 |*/ 0x40 | ( _n ) )); \
143 *_list++ = ((unsigned char)( ( _addr ) & 0xff )); \
144 *_list++ = ((unsigned char)( ( _addr ) >> 8 ));
145
146#define DLI_LMS_IRQ( _list, _n, _addr ) \
147 *_list++ = ((unsigned char)( /*0x30 |*/ 0x40 | 0x80 | ( _n ) )); \
148 *_list++ = ((unsigned char)( ( _addr ) & 0xff )); \
149 *_list++ = ((unsigned char)( ( _addr ) >> 8 ));
150
151#define DLI_LMS_VSCROLL( _list, _n, _addr ) \
152 *_list++ = ((unsigned char)( 0x20 | 0x40 | ( _n ) )); \
153 *_list++ = ((unsigned char)( ( _addr ) & 0xff )); \
154 *_list++ = ((unsigned char)( ( _addr ) >> 8 ));
155
156#define DLI_LMS_VSCROLL_IRQ( _list, _n, _addr ) \
157 *_list++ = ((unsigned char)( 0x20 | 0x40 | 0x80 | ( _n ) )); \
158 *_list++ = ((unsigned char)( ( _addr ) & 0xff )); \
159 *_list++ = ((unsigned char)( ( _addr ) >> 8 ));
160
161#define DLI_LMS_VHSCROLL( _list, _n, _addr ) \
162 *_list++ = ((unsigned char)( 0x10 | 0x20 | 0x40 | ( _n ) )); \
163 *_list++ = ((unsigned char)( ( _addr ) & 0xff )); \
164 *_list++ = ((unsigned char)( ( _addr ) >> 8 ));
165
166#define DLI_LMS_VHSCROLL_IRQ( _list, _n, _addr ) \
167 *_list++ = ((unsigned char)( 0x10 | 0x20 | 0x40 | 0x80 | ( _n ) )); \
168 *_list++ = ((unsigned char)( ( _addr ) & 0xff )); \
169 *_list++ = ((unsigned char)( ( _addr ) >> 8 ));
170
171#define DLI_IRQ( _list, _n ) \
172 *_list++ = ((unsigned char)( /*0x10 |*/ 0x80 | _n ));
173
174#define DLI_HSCROLL( _list ) \
175 *_list++ = ((unsigned char)( 0x10 ));
176
177#define DLI_VSCROLL( _list ) \
178 *_list++ = ((unsigned char)( 0x20 ));
179
180/*
181
182display list interrupt (DLI)
183vertical scroll
184horizontal scroll
185
186
187Blanking Instructions
188
189The blanking instructions generate a certain number of blank scan lines in
190the color and luminance of the background or border color. From 1 to 8 blank scan lines
191can be generated by these opcodes. They are primarily used to correct the overscan on
192a television set.
193
194Instruction Comment
195Decimal Hex
196 0 0 1 Blank Line
197 16 10 2 Blank Lines
198 32 20 3 Blank Lines
199 48 30 4 Blank Lines
200 64 40 5 Blank Lines
201 80 50 6 Blank Lines
202 96 60 7 Blank Lines
203112 70 8 Blank Lines
204
205
206*/
207
208#define DLI_BLANK( _list, _n ) \
209 *_list++ = ((unsigned char)( ( (_n-1)<<4 ) ));
210
211
212/*
213
214Jump Instructions
215
216There are two jump instructions. The first (JMP) tells ANTIC to continue looking for
217instructions at a different address. It is equivalent to a GOTO in the display list.
218It is a three byte instruction with the address in low byte, high byte order following
219the opcode. Its only function is to provide a solution to the display list's
220inability to cross a 1K boundary. If for any reason your display list must cross
221a 1K boundary, then it must use a JMP instruction. Otherwise, don't worry about
222this instruction.
223
224Instruction Comment
225Decimal Hex
226 1 1 Jump to Location
227
228*/
229
230#define DLI_JMP( list, addr ) \
231 *list++ = ((unsigned char)(0x1)); \
232 *list++ = ((unsigned char)(addr&0xff)); \
233 *list++ = ((unsigned char)(addr>>8));
234
235
236/*
237The second jump instruction (JVB)-Jump and wait for Vertical Blank-is used in
238every display list. It is a three byte instruction; the address in low byte,
239high byte order follows the opcode. JVB tells ANTIC to jump to the start of the
240display list and wait for a new screen refresh to begin. Surprisingly, this
241address doesn't have to be accurate, because the OS keeps track of the top of
242the display list and passes it to ANTIC during the vertical blank. However,
243you should try to maintain the real address because if you use any SIO
244functions such as the disk drive or the printer, ANTIC won't be updated
245properly and the jump will be to the address that you specify in the instruction.
246
247Instruction Comment
248Decimal Hex
249 65 41 Jump & Wait for VBlank
250
251*/
252
253#define DLI_JVB( list, addr ) \
254 *list++ = ((unsigned char)(0x41)); \
255 *list++ = ((unsigned char)(addr&0xff)); \
256 *list++ = ((unsigned char)(addr>>8));
257
258void antic_initialization( Environment * _environment );
259void antic_finalization( Environment * _environment );
260
261void antic_next_raster( Environment * _environment );
262void antic_next_raster_at( Environment * _environment, char * _label, char * _positionlo, char * _positionhi );
263void antic_raster_at( Environment * _environment, char * _label, char * _positionlo, char * _positionhi );
264
265#endif
void antic_initialization(Environment *_environment)
Definition antic.c:120
void antic_raster_at(Environment *_environment, char *_label, char *_positionlo, char *_positionhi)
ANTIC: emit code to set raster irq
Definition antic.c:58
void antic_next_raster(Environment *_environment)
ANTIC: emit code to wait for next raster irq
Definition antic.c:84
void antic_finalization(Environment *_environment)
Definition antic.c:132
void antic_next_raster_at(Environment *_environment, char *_label, char *_positionlo, char *_positionhi)
ANTIC: emit code to wait for next raster irq at different position
Definition antic.c:103
struct _Environment Environment
Structure of compilation environment.