source: buchla-68k/ram/smscrl.c@ 572daa7

Last change on this file since 572daa7 was 8c8b4e5, checked in by Thomas Lopatic <thomas@…>, 7 years ago

More volatile hardware accesses.

  • Property mode set to 100644
File size: 11.8 KB
Line 
1/*
2 =============================================================================
3 smscrl.c -- MIDAS-VII smooth scrolling functions
4 Version 37 -- 1989-11-16 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#define OLDSCRL 0
9
10#include "ram.h"
11
12#define SS_NSL 16 /* number of scrolled lines */
13#define SS_TOP (2 * (SS_NSL + 1)) /* total line count */
14#define SS_LIM (SS_TOP - SS_NSL) /* top line limit */
15#define SS_LEN 48 /* length of a scrolled line */
16#define NSCANS 14 /* number of scan lines */
17#define TOPSCAN (NSCANS - 1) /* top scan line */
18
19int8_t TheBuf[66]; /* display build buffer */
20
21int8_t *(*BakLine)(void); /* next line backward function pointer */
22int8_t *(*FwdLine)(void); /* next line forward function pointer */
23
24int16_t PdScDnF; /* scroll down flag */
25int16_t PdScUpF; /* scroll up flag */
26
27int16_t CurLine; /* top line being displayed */
28int16_t CurScan; /* current scan line */
29int16_t DupLine; /* write pointer for other page */
30int16_t ScrlObj; /* object descriptor table index */
31
32int8_t *LinePtr; /* line to scroll onto screen */
33
34uint16_t LineAtr; /* attribute for the new line */
35
36volatile uint16_t *LineBuf; /* current display memory pointer */
37volatile uint16_t *OldLine; /* old display memory pointer */
38volatile uint16_t *ScObAdr; /* display memory base pointer */
39
40int16_t LineCon = SS_LEN * 3; /* line offset constant */
41int16_t LineLen = SS_LEN; /* length of a scrolled line */
42int16_t SmScLim = SS_LIM; /* top line limit */
43int16_t SmScNsl = SS_NSL; /* number of scrolled lines */
44int16_t SmScTop = SS_TOP; /* total line count */
45
46/*
47 =============================================================================
48 LineFwd() -- return the next patch line in the forward direction
49 =============================================================================
50*/
51
52int8_t *LineFwd(void)
53{
54 register int16_t j, k;
55
56 for (j = 0; j < 48; j++)
57 TheBuf[j] = ' ';
58
59 TheBuf[0] = '\260';
60 TheBuf[48] = '\0';
61
62 if (0 EQ ptecpos)
63 return((int8_t *)NULL);
64
65 if (0 EQ (j = findnxt(ptecpos)))
66 return((int8_t *)NULL);
67
68 ptecpos = j;
69
70 memcpyw(&ptebuf.defnum, &patches[ptecpos].defnum, 6);
71 pteset = TRUE;
72 pte2buf();
73
74 k = ptecpos;
75
76 for (j = 0; j < 8; j++)
77 if (0 EQ (k = findnxt(k)))
78 return(TheBuf);
79
80 dspdfst(&TheBuf[ 2], patches[k].defnum);
81 dspdfst(&TheBuf[15], patches[k].stmnum);
82 dspdest(&TheBuf[28], &patches[k]);
83
84 for (j = 0; j < 50; j++)
85 if(TheBuf[j] EQ '\0')
86 TheBuf[j] = ' ';
87
88 TheBuf[48] = '\0';
89 return(TheBuf);
90}
91
92/*
93 =============================================================================
94 LineBak() -- return the next patch line in the backward direction
95 =============================================================================
96*/
97
98int8_t *LineBak(void)
99{
100 register int16_t j, k;
101
102 for (j = 0; j < 48; j++)
103 TheBuf[j] = ' ';
104
105 TheBuf[0] = '\260';
106 TheBuf[48] = '\0';
107
108 if (0 EQ ptecpos)
109 return((int8_t *)NULL);
110
111 if (0 EQ (j = findprv(ptecpos)))
112 return((int8_t *)NULL);
113
114 ptecpos = j;
115
116 memcpyw(&ptebuf.defnum, &patches[ptecpos].defnum, 6);
117 pteset = TRUE;
118 pte2buf();
119
120 k = ptecpos;
121
122 for (j = 0; j < 7; j++)
123 if (0 EQ (k = findprv(k)))
124 return(TheBuf);
125
126 dspdfst(&TheBuf[ 2], patches[k].defnum);
127 dspdfst(&TheBuf[15], patches[k].stmnum);
128 dspdest(&TheBuf[28], &patches[k]);
129
130 for (j = 0; j < 50; j++)
131 if(TheBuf[j] EQ '\0')
132 TheBuf[j] = ' ';
133
134 TheBuf[48] = '\0';
135 return(TheBuf);
136}
137
138/*
139 =============================================================================
140 WrVideo() -- write a line to the video display
141 =============================================================================
142*/
143
144void WrVideo(int16_t row, int16_t col, int8_t *str, uint16_t atr)
145{
146 register int8_t chr;
147
148 if (v_regs[5] & 0x0180)
149 vbank(0);
150
151 while ('\0' NE (chr = *str++)) {
152
153 vputcv(ScObAdr, row, col, chr,
154 (col EQ 0) ? PTBATR : atr, LineLen);
155
156 col++;
157 }
158}
159
160/*
161 =============================================================================
162 SetDTop() -- set the top line of the display
163 =============================================================================
164*/
165
166void SetDTop(int16_t row, int16_t scan)
167{
168 if (v_regs[5] & 0x0180)
169 vbank(0);
170
171 LineBuf = (uint16_t *)((int8_t *)ScObAdr + (row * LineCon));
172
173 if (OldLine NE LineBuf)
174 v_odtab[ScrlObj][2] = ((int32_t)LineBuf >> 1) & 0xFFFF;
175
176 OldLine = LineBuf;
177
178 v_odtab[ScrlObj][0] = (v_odtab[ScrlObj][0] & 0x0FFF) | (scan << 12);
179}
180
181/*
182 =============================================================================
183 UpdVid() -- update the video display on both pages
184 =============================================================================
185*/
186
187void UpdVid(int16_t row, int16_t col, int8_t *str, uint16_t atr)
188{
189 WrVideo(CurLine + row, col, str, atr);
190
191 DupLine = CurLine + SmScNsl + 2 + row;
192
193 if (DupLine < SmScTop)
194 WrVideo(DupLine, col, str, PTPATR);
195
196 DupLine = CurLine - SmScNsl - 2 + row;
197
198 if (DupLine GE 0)
199 WrVideo(DupLine, col, str, PTPATR);
200}
201
202/*
203 =============================================================================
204 bgncm() -- begin patch display cursor motion
205 =============================================================================
206*/
207
208void bgncm(void)
209{
210 register int16_t j;
211
212 memcpyw(&ptebuf.defnum, &patches[ptecpos].defnum, 6);
213 pteset = TRUE;
214 pte2buf();
215
216 memcpy(TheBuf, ptdebuf, 48);
217
218 for (j = 0; j < 50; j++)
219 if(TheBuf[j] EQ '\0')
220 TheBuf[j] = ' ';
221
222 TheBuf[0] = '\260';
223 TheBuf[1] = ' ';
224 TheBuf[48] = '\0';
225
226 UpdVid(7, 0, TheBuf, PTPATR);
227 ctcoff();
228}
229
230/*
231 =============================================================================
232 stopcm() -- stop patch display cursor motion
233 =============================================================================
234*/
235
236void stopcm(void)
237{
238 if (PdScDnF)
239 SetDTop(CurLine, CurScan = TOPSCAN);
240 else if (PdScUpF)
241 SetDTop(++CurLine, CurScan = TOPSCAN);
242
243 if (NOT ctcsw) { /* if we scrolled ... */
244
245 if (ptecpos) { /* if something is there ... */
246
247 /* refresh editing variables */
248
249 memcpyw(&ptebuf.defnum, &patches[ptecpos].defnum, 6);
250 pteset = TRUE;
251 pte2buf();
252 setptcv();
253
254 } else { /* ... nothing there */
255
256 voidpb(); /* void the patch buffer */
257 }
258 }
259
260 ctcon(); /* re-enable cursor */
261
262 PdScDnF = FALSE; /* turn off the scrolling flags */
263 PdScUpF = FALSE;
264}
265
266/*
267 =============================================================================
268 stopsm() -- stop sequence display cursor motion
269 =============================================================================
270*/
271
272void stopsm(void)
273{
274 if (PdScDnF)
275 SetDTop(CurLine, CurScan = TOPSCAN);
276 else if (PdScUpF)
277 SetDTop(++CurLine, CurScan = TOPSCAN);
278
279 memcpyw(&seqbuf, &seqtab[curslin], NSEQW);
280 dsqlin(sqdebuf, curslin);
281 sqdeflg = TRUE;
282 ctcon();
283
284 PdScDnF = FALSE;
285 PdScUpF = FALSE;
286}
287
288/*
289 =============================================================================
290 smscrl() -- smooth scroll the text display up or down
291 =============================================================================
292*/
293
294void smscrl(void)
295{
296 if (PdScUpF) { /* SCROLL UP (toward NEW data) ? */
297
298 if (CurScan EQ TOPSCAN) { /* ready for a new line ? */
299
300 if ((int8_t *)NULL NE (LinePtr = (*FwdLine)())) { /* get a line */
301
302 if (CurLine EQ SmScLim) { /* *** swap display pages *** */
303
304 /* update page we're going to */
305
306 WrVideo(SmScNsl, 0, LinePtr, LineAtr);
307
308 /* point at new page */
309
310 SetDTop(CurLine = 0, CurScan = TOPSCAN);
311
312 } else { /* *** stay on this page *** */
313
314 /* update scroll target line */
315
316 WrVideo(CurLine + SmScNsl, 0, LinePtr, LineAtr);
317
318 /* update other page if it's in range */
319
320 DupLine = CurLine - 2;
321
322 if (DupLine GE 0)
323 WrVideo(DupLine, 0, LinePtr, LineAtr);
324 }
325
326 /* do first scroll up of new line */
327
328 SetDTop(CurLine, --CurScan);
329 }
330
331 } else { /* scrolling -- scroll some more */
332
333 if (CurScan EQ 0)
334 SetDTop(++CurLine, CurScan = TOPSCAN);
335 else
336 SetDTop(CurLine, --CurScan);
337 }
338
339 } else if (PdScDnF) { /* SCROLL DOWN (toward old data) ? */
340
341 if (CurScan EQ TOPSCAN) { /* ready for a new line ? */
342
343 if ((int8_t *)NULL NE (LinePtr = (*BakLine)())) { /* get a line */
344
345 if (CurLine EQ 0) { /* *** swap display pages *** */
346
347 /* update page we're going to */
348
349 WrVideo(SmScLim - 1, 0, LinePtr, LineAtr);
350
351 /* point at new page */
352
353 SetDTop(CurLine = SmScLim - 1, CurScan = 0);
354
355 } else { /* *** stay on this page *** */
356
357 /* update scroll target line */
358
359 WrVideo(CurLine - 1, 0, LinePtr, LineAtr);
360
361 /* update other page if it's in range */
362
363 DupLine = CurLine + SmScNsl + 1;
364
365 if (DupLine < SmScTop)
366 WrVideo(DupLine, 0, LinePtr, LineAtr);
367
368 /* do first scroll down of new line */
369
370 SetDTop(--CurLine, CurScan = 0);
371 }
372 }
373
374 } else { /* scrolling -- scroll some more */
375
376 if (CurScan NE TOPSCAN)
377 SetDTop(CurLine, ++CurScan);
378 }
379 }
380}
381
382/*
383 =============================================================================
384 smxupd() -- patch / sequence smooth scroll X axis update
385 =============================================================================
386*/
387
388void smxupd(void)
389{
390 int16_t oldcx;
391
392 oldcx = cxval;
393
394 if (submenu) {
395
396 vtccol = XTOC(vtxval += cxrate);
397
398 if (vtccol > 60)
399 vtxval = CTOX(vtccol = 60);
400 else if (vtccol < 2)
401 vtxval = CTOX(vtccol = 2);
402
403 } else {
404
405 cxval += cxrate;
406
407 if (cxval > CTOX(48))
408 cxval = CTOX(48);
409 else if (cxval < CTOX(2))
410 cxval = CTOX(2);
411
412 if (cxval EQ oldcx)
413 return;
414
415 if (47 EQ XTOC(cxval)) {
416
417 if (v_regs[5] & 0x0180)
418 vbank(0);
419
420 vvputsv(obj10, 16, PDBORFG, PDSEQBG,
421 7, 0, "\260", 14, 14, cg3);
422
423 vsplot4(obj10, 16, PDPTRFG,
424 7, 0, "\274", 14, 14, cg3);
425
426 } else if (48 EQ XTOC(cxval)) {
427
428 if (v_regs[5] & 0x0180)
429 vbank(0);
430
431 vvputsv(obj10, 16, PDBORFG, PDSEQBG,
432 7, 0, "\260", 14, 14, cg3);
433
434 vsplot4(obj10, 16, PDPTRFG,
435 7, 0, "\277", 14, 14, cg3);
436
437 }
438
439 return;
440 }
441}
442
443/*
444 =============================================================================
445 smy_up() -- patch display smooth scrolling
446 =============================================================================
447*/
448
449void smy_up(int16_t tag)
450{
451
452 if (0 EQ ptecpos) { /* see if anything is there */
453
454 dptw(); /* try to find something ... */
455 return; /* ... may scroll next time */
456 }
457
458 if (ctcsw) /* if we haven't scrolled yet ... */
459 bgncm(); /* ... setup for scrolling */
460
461 if (tag < 0) { /* scroll up */
462
463 if (0 EQ findnxt(ptecpos))
464 return;
465
466 PdScUpF = TRUE;
467 PdScDnF = FALSE;
468 smscrl();
469
470 } else if (tag > 0) { /* scroll down */
471
472 if (0 EQ findprv(ptecpos))
473 return;
474
475 PdScDnF = TRUE;
476 PdScUpF = FALSE;
477 smscrl();
478 }
479}
480
481/*
482 =============================================================================
483 smyupd() -- patch display smooth scroll Y axis update
484 =============================================================================
485*/
486
487void smyupd(void)
488{
489 if (submenu) {
490
491 vtcrow = YTOR(vtyval += cyrate);
492
493 if (vtcrow > 23)
494 vtyval = RTOY(vtcrow = 23);
495 else if (vtcrow < 19)
496 vtyval = RTOY(vtcrow = 19);
497
498 }
499
500#if OLDSCRL
501 smy_up(cyrate);
502#endif
503}
504
505/*
506 =============================================================================
507 sqy_up() -- sequence smooth scrolling
508 =============================================================================
509*/
510
511void sqy_up(int16_t tag)
512{
513 if (ctcsw)
514 ctcoff();
515
516 if (tag < 0) { /* scroll up */
517
518 PdScUpF = TRUE;
519 PdScDnF = FALSE;
520 smscrl();
521
522 } else if (tag > 0) { /* scroll down */
523
524 PdScDnF = TRUE;
525 PdScUpF = FALSE;
526 smscrl();
527 }
528}
529
530/*
531 =============================================================================
532 sqyupd() -- sequence smooth scroll Y axis update
533 =============================================================================
534*/
535
536void sqyupd(void)
537{
538 if (submenu) {
539
540 vtcrow = YTOR(vtyval += cyrate);
541
542 if (vtcrow > 23)
543 vtyval = RTOY(vtcrow = 23);
544 else if (vtcrow < 19)
545 vtyval = RTOY(vtcrow = 19);
546
547 }
548
549#if OLDSCRL
550 sqy_up(cyrate);
551#endif
552}
553
Note: See TracBrowser for help on using the repository browser.