-
Notifications
You must be signed in to change notification settings - Fork 1
/
nv_screen_rect_macs.asm
400 lines (336 loc) · 14.1 KB
/
nv_screen_rect_macs.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
//////////////////////////////////////////////////////////////////////////////
// nv_screen_rect_macs.asm
// Copyright(c) 2021 Neal Smith.
// License: MIT. See LICENSE file in root directory.
//////////////////////////////////////////////////////////////////////////////
// contains inline macros for rectangle related operations
// importing this file will not allocate any memory for data or code unless
// nv_c64_utils_data.asm hasn't yet been imported in which case it will be.
//////////////////////////////////////////////////////////////////////////////
#importonce
#if !NV_C64_UTIL_DATA
.error "Error - nv_math8_macs.asm: NV_C64_UTIL_DATA not defined. Import nv_c64_util_data.asm"
#endif
// the #if above doesn't seem to always work so..
// if data hasn't been imported yet, import it into default location
#importif !NV_C64_UTIL_DATA "nv_c64_util_default_data.asm"
#import "nv_math16_macs.asm"
.const CHAR_PIXEL_WIDTH = $0008
.const CHAR_PIXEL_HEIGHT = $0008
//////////////////////////////////////////////////////////////////////////////
// inline macro to convert the character x, y location on screen
// to screen pixel coordinates
// Params:
// X Reg: character's X loc on screen
// Y Reg: character's Y loc on screen
// macro params:
// rect_addr: the address to an 8 byte struct that holds 4
// 16bit values that will be filled with values
// that are the screen coords for the screen
// char location. the 16 bit values' order will be
// left, top, right, bottom
.macro nv_screen_rect_char_coord_to_screen_pixels(rect_addr)
{
.label r_left = rect_addr
.label r_top = rect_addr + 2
.label r_right = rect_addr + 4
.label r_bottom = rect_addr + 6
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
/////// put char's rectangle in rect
// LEFT
// (col * CHAR_PIXEL_WIDTH) + LEFT_OFFSET
nv_store16_immed(r_left, CHAR_PIXEL_WIDTH)
nv_mul16u_mem16u_x8u(r_left, r_left, NV_PROCSTAT_NONE)
nv_adc16x_mem_immed(r_left, LEFT_OFFSET, r_left)
// TOP
// (row * CHAR_PIXEL_HEIGHT) + TOP_OFFSET
nv_store16_immed(r_top, CHAR_PIXEL_HEIGHT)
nv_mul16u_mem16u_y8u(r_top, r_top, NV_PROCSTAT_NONE)
nv_adc16x_mem_immed(r_top, TOP_OFFSET, r_top)
// RIGHT
// add width to the left to get right
nv_adc16x_mem_immed(r_left, CHAR_PIXEL_WIDTH, r_right)
// BOTTOM
// add height to the top to get the bottom
nv_adc16x_mem_immed(r_top, CHAR_PIXEL_HEIGHT, r_bottom)
}
//////////////////////////////////////////////////////////////////////////////
// inline macro to convert the character x, y location on character screen
// to rectangle of screen pixel coordinates. This macro only updates the
// left and top part of the rectangle though. The right bottom will remain
// unchanged. To create the full rectangle this should be paired with
// the nv_screen_rect_char_coord_to_screen_pixels_right_bottom or the
// nv_screen_rect_char_coord_to_screen_pixels_expand_right_bottom macro
// Params:
// X Reg: character's X loc on screen
// Y Reg: character's Y loc on screen
// macro params:
// rect_addr: the address to an 8 byte struct that holds 4
// 16bit values that will be filled with values
// that are the screen coords for the left top
// for specified char location.
// the 16 bit values' order within the rect are be
// left, top, right, bottom
.macro nv_screen_rect_char_coord_to_screen_pixels_left_top(rect_addr)
{
.label r_left = rect_addr
.label r_top = rect_addr + 2
.label r_right = rect_addr + 4
.label r_bottom = rect_addr + 6
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
.const CHAR_PIXEL_WIDTH = $0008
.const CHAR_PIXEL_HEIGHT = $0008
/////// put char's rectangle in rect
// LEFT
// (col * CHAR_PIXEL_WIDTH) + LEFT_OFFSET
nv_store16_immed(r_left, CHAR_PIXEL_WIDTH)
nv_mul16u_mem16u_x8u(r_left, r_left, NV_PROCSTAT_NONE)
nv_adc16x_mem_immed(r_left, LEFT_OFFSET, r_left)
// TOP
// (row * CHAR_PIXEL_HEIGHT) + TOP_OFFSET
nv_store16_immed(r_top, CHAR_PIXEL_HEIGHT)
nv_mul16u_mem16u_y8u(r_top, r_top, NV_PROCSTAT_NONE)
nv_adc16x_mem_immed(r_top, TOP_OFFSET, r_top)
}
//////////////////////////////////////////////////////////////////////////////
// inline macro to convert the character x, y location on character screen
// to rectangle of screen pixel coordinates. This macro only updates the
// right and bottom part of the rectangle though. The left top will remain
// unchanged. To create the full rectangle this should be paired with
// the nv_screen_rect_char_coord_to_screen_pixels_left_top or the
// nv_screen_rect_char_coord_to_screen_pixels_expand_left_top macro
// Params:
// X Reg: character's X loc on screen
// Y Reg: character's Y loc on screen
// macro params:
// rect_addr: the address to an 8 byte struct that holds 4
// 16bit values that will be filled with values
// that are the screen coords for the right bottom
// for specified char location.
// the 16 bit values' order within the rect are be
// left, top, right, bottom
.macro nv_screen_rect_char_coord_to_screen_pixels_right_bottom(rect_addr)
{
//.label r_left = rect_addr
//.label r_top = rect_addr + 2
.label r_right = rect_addr + 4
.label r_bottom = rect_addr + 6
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
.const CHAR_PIXEL_WIDTH = $0008
.const CHAR_PIXEL_HEIGHT = $0008
/////// put char's right and bottom coords in rect
// RIGHT
// Set the right pixel coord value for char. First need to set it to
// the left coord and then add the pixel width to get to the right
nv_store16_immed(r_right, CHAR_PIXEL_WIDTH)
nv_mul16u_mem16u_x8u(r_right, r_right, NV_PROCSTAT_NONE)
nv_adc16x_mem_immed(r_right, LEFT_OFFSET, r_right)
// above code sets r_right to the left pixel position for char
// now add char pixel width to it and it will be the right pixel position
// for the char
nv_adc16x_mem_immed(r_right, CHAR_PIXEL_WIDTH, r_right)
// BOTTOM
// Set the bottom pixel coord value for char. First need to set it to
// the top coord and then add the pixel height to get to the bottom
nv_store16_immed(r_bottom, CHAR_PIXEL_HEIGHT)
nv_mul16u_mem16u_y8u(r_bottom, r_bottom, NV_PROCSTAT_NONE)
nv_adc16x_mem_immed(r_bottom, TOP_OFFSET, r_bottom)
// above code sets r_bottom to the top pixel position for char
// now add char pixel height to it and it will be the bottom pixel position
// for the char
nv_adc16x_mem_immed(r_bottom, CHAR_PIXEL_HEIGHT, r_bottom)
}
//////////////////////////////////////////////////////////////////////////////
// inline macro to expand a rect some number of characters in the
// x and y directions. before this macro code is executed the rect
// must already have the left, top coordinates filled in to be valid
// pixel values. This macro will add to those values to get the
// right, bottom pixel locations and fill those in the rect.
// Params:
// X Reg: the number of characters to expand in the X direction
// if pass zero then the resulting rectangle will be the width
// of one character
// Y Reg: the number of characters to expand the rect in the Y direction
// If pass zero then the resulting rectangle will be one char high
// macro params:
// rect_addr: the address to an 8 byte struct that holds 4
// 16bit values that will be filled with values
// that are the screen coords for the screen
// char location. the 16 bit values' order will be
// left, top, right, bottom
// before executing macro the left, top values must be
// filled in with valid screen/pixel coordinates
.macro nv_screen_rect_char_coord_to_screen_pixels_expand_right_bottom(rect_addr)
{
.label r_left = rect_addr
.label r_top = rect_addr + 2
.label r_right = rect_addr + 4
.label r_bottom = rect_addr + 6
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
.const CHAR_PIXEL_WIDTH = $0008
.const CHAR_PIXEL_HEIGHT = $0008
/////// put char's rectangle in rect
// RIGHT
nv_store16_immed(r_right, CHAR_PIXEL_WIDTH) // start width
nv_mul16u_mem16u_x8u(r_right, r_right, NV_PROCSTAT_NONE) // mul by X for inc
nv_adc16x(r_left, r_right, r_right)
nv_adc16x_mem_immed(r_right, CHAR_PIXEL_WIDTH, r_right)
// BOTTOM
// add height to the top to get the bottom
nv_store16_immed(r_bottom, CHAR_PIXEL_HEIGHT) // start width
nv_mul16u_mem16u_y8u(r_bottom, r_bottom, NV_PROCSTAT_NONE) // mul by Y for inc
nv_adc16x(r_top, r_bottom, r_bottom)
nv_adc16x_mem_immed(r_bottom, CHAR_PIXEL_HEIGHT, r_bottom)
}
//////////////////////////////////////////////////////////////////////////////
// function that returns the pixel X location for the left edge of the
// character at the specified character row and col
// function params:
// char_x: the column of the character for which the left edge will be
// returned
// char_y: the row of the character for which the left edge will be
// returned. Valid values depend on screen mode but default
// mode is 0-24
// returns: the screen pixel x location of the left edge of the char
// at (char_x, char_y) on the screen
.function nv_screen_rect_char_to_screen_pixel_left(char_x, char_y)
{
.var r_left
.var r_top
.var r_right
.var r_bottom
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
// LEFT
// (col * CHAR_PIXEL_WIDTH) + LEFT_OFFSET
.eval r_left = CHAR_PIXEL_WIDTH
.eval r_left = r_left * char_x
.eval r_left = r_left + LEFT_OFFSET
// TOP
// (row * CHAR_PIXEL_HEIGHT) + TOP_OFFSET
.eval r_top = CHAR_PIXEL_HEIGHT
.eval r_top = r_top * char_y
.eval r_top = r_top + TOP_OFFSET
// RIGHT
// add width to the left to get right
.eval r_right = r_left + CHAR_PIXEL_WIDTH
// BOTTOM
// add height to the top to get the bottom
.eval r_bottom = r_top + CHAR_PIXEL_HEIGHT
.return r_left
}
//////////////////////////////////////////////////////////////////////////////
// function that returns the pixel Y location for the top edge of the
// character at the specified character row and col
// function params:
// char_x: the column of the character for which the top edge will be
// returned
// char_y: the row of the character for which the top edge will be
// returned. Valid values depend on screen mode but default
// mode is 0-24
// returns: the screen pixel x location of the top edge of the char
// at (char_x, char_y) on the screen
.function nv_screen_rect_char_to_screen_pixel_top(char_x, char_y)
{
.var r_left
.var r_top
.var r_right
.var r_bottom
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
// LEFT
// (col * CHAR_PIXEL_WIDTH) + LEFT_OFFSET
.eval r_left = CHAR_PIXEL_WIDTH
.eval r_left = r_left * char_x
.eval r_left = r_left + LEFT_OFFSET
// TOP
// (row * CHAR_PIXEL_HEIGHT) + TOP_OFFSET
.eval r_top = CHAR_PIXEL_HEIGHT
.eval r_top = r_top * char_y
.eval r_top = r_top + TOP_OFFSET
// RIGHT
// add width to the left to get right
.eval r_right = r_left + CHAR_PIXEL_WIDTH
// BOTTOM
// add height to the top to get the bottom
.eval r_bottom = r_top + CHAR_PIXEL_HEIGHT
.return r_top
}
//////////////////////////////////////////////////////////////////////////////
// function that returns the pixel X location for the right edge of the
// character at the specified character row and col
// function params:
// char_x: the column of the character for which the right edge will be
// returned
// char_y: the row of the character for which the right edge will be
// returned. Valid values depend on screen mode but default
// mode is 0-24
// returns: the screen pixel x location of the right edge of the char
// at (char_x, char_y) on the screen
.function nv_screen_rect_char_to_screen_pixel_right(char_x, char_y)
{
.var r_left
.var r_top
.var r_right
.var r_bottom
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
// LEFT
// (col * CHAR_PIXEL_WIDTH) + LEFT_OFFSET
.eval r_left = CHAR_PIXEL_WIDTH
.eval r_left = r_left * char_x
.eval r_left = r_left + LEFT_OFFSET
// TOP
// (row * CHAR_PIXEL_HEIGHT) + TOP_OFFSET
.eval r_top = CHAR_PIXEL_HEIGHT
.eval r_top = r_top * char_y
.eval r_top = r_top + TOP_OFFSET
// RIGHT
// add width to the left to get right
.eval r_right = r_left + CHAR_PIXEL_WIDTH
// BOTTOM
// add height to the top to get the bottom
.eval r_bottom = r_top + CHAR_PIXEL_HEIGHT
.return r_right
}
//////////////////////////////////////////////////////////////////////////////
// function that returns the pixel X location for the bottom edge of the
// character at the specified character row and col
// function params:
// char_x: the column of the character for which the bottom edge will be
// returned
// char_y: the row of the character for which the bottom edge will be
// returned. Valid values depend on screen mode but default
// mode is 0-24
// returns: the screen pixel x location of the bottom edge of the char
// at (char_x, char_y) on the screen
.function nv_screen_rect_char_to_screen_pixel_bottom(char_x, char_y)
{
.var r_left
.var r_top
.var r_right
.var r_bottom
.const LEFT_OFFSET = 26
.const TOP_OFFSET = 53
// LEFT
// (col * CHAR_PIXEL_WIDTH) + LEFT_OFFSET
.eval r_left = CHAR_PIXEL_WIDTH
.eval r_left = r_left * char_x
.eval r_left = r_left + LEFT_OFFSET
// TOP
// (row * CHAR_PIXEL_HEIGHT) + TOP_OFFSET
.eval r_top = CHAR_PIXEL_HEIGHT
.eval r_top = r_top * char_y
.eval r_top = r_top + TOP_OFFSET
// RIGHT
// add width to the left to get right
.eval r_right = r_left + CHAR_PIXEL_WIDTH
// BOTTOM
// add height to the top to get the bottom
.eval r_bottom = r_top + CHAR_PIXEL_HEIGHT
.return r_bottom
}