source: buchla-68k/ram/libdsp.c@ 6262b5c

Last change on this file since 6262b5c was 6262b5c, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Added include files for global functions and variables.

  • Property mode set to 100644
File size: 35.5 KB
Line 
1/*
2 =============================================================================
3 libdsp.c -- MIDAS librarian display
4 Version 64 -- 1988-11-17 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#define DEBUGRE 0
9#define DEBUGWE 0
10
11#include "all.h"
12
13#if (DEBUGRE|DEBUGWE)
14extern short debugsw;
15#endif
16
17#if DEBUGRE
18short debugre = 1;
19#endif
20
21#if DEBUGWE
22short debugwe = 1;
23#endif
24
25extern int16_t lcancel(int16_t lct);
26
27extern int32_t ptsizer(void);
28extern int32_t scsizer(void);
29extern int32_t sqsizer(void);
30
31/*
32
33*/
34
35/* things defined elsewhere */
36
37extern void (*point)(int16_t x, int16_t y, int16_t pen);
38
39extern void clrlsel(void);
40extern void _clsvol(void);
41extern void setgc(int16_t xv, int16_t yv);
42
43extern int16_t _bpbin;
44
45extern int16_t chtime;
46extern int16_t cmtype;
47extern int16_t cvtime;
48extern int16_t cxval;
49extern int16_t cyval;
50extern int16_t sgcsw;
51extern int16_t stccol;
52extern int16_t stcrow;
53extern int16_t submenu;
54extern int16_t thcwval;
55extern int16_t tvcwval;
56
57extern uint16_t *obj0, *obj2;
58
59extern int8_t *ldbxlb0[];
60extern int8_t vtlin1[], vtlin2[], vtlin3[];
61
62extern int16_t ldbox[][8];
63extern struct instdef idefs[];
64
65extern struct bpb *_thebpb;
66
67/*
68
69*/
70
71extern uint16_t *librob; /* display object pointer */
72
73extern int16_t catin; /* catalog read in flag */
74extern int16_t lrasw; /* append (TRUE) / replace (FALSE) score */
75extern int16_t lorchl; /* hi (TRUE) / lo (FALSE) orchestra */
76extern int16_t ldrow; /* fetch select row */
77extern int16_t ldslot; /* fetch select slot */
78extern int16_t lselsw; /* fetch select switch */
79extern int16_t ldkind; /* fetch file type */
80extern int16_t lstrsw; /* store state switch */
81extern int16_t lasgsw; /* assignments store switch */
82extern int16_t lksel; /* librarian key slot selector */
83extern int16_t lorchsw; /* hi orchestra (21 - 40) store switch */
84extern int16_t lorclsw; /* lo orchestra (01 - 20) store switch */
85extern int16_t lpatsw; /* patch store switch */
86extern int16_t lscrsw; /* score store switch */
87extern int16_t lseqsw; /* sequence store switch */
88extern int16_t ltunsw; /* tunings store switch */
89extern int16_t lwavsw; /* waveshapes store switch */
90extern int16_t ldelsw; /* delete switch */
91extern int16_t lderrsw; /* error message displayed switch */
92extern int16_t ldidsiz; /* getcat() did showsiz() switch */
93extern int16_t lmwtype; /* librarian message window type */
94extern int16_t ltagged; /* load tag update in progress flag */
95extern int16_t ndisp; /* display number currently up */
96
97extern int32_t lcsum; /* library checksum */
98extern int32_t ndbytes; /* bytes needed for storage */
99
100extern int8_t *lmln22; /* message window line 22 */
101extern int8_t *lmln23; /* message window line 23 */
102extern int8_t *lmln24; /* message window line 24 */
103
104extern int8_t ldfile[9]; /* file name field */
105extern int8_t ldcmnt[38]; /* comment field */
106extern int8_t ldmsg1[65]; /* messsage build area 1 */
107extern int8_t ldmsg2[65]; /* messsage build area 2 */
108extern int8_t ldmsg3[65]; /* messsage build area 3 */
109extern int8_t errbuf[65]; /* error message build area */
110
111extern struct octent *ldoct; /* object control table pointer */
112
113extern struct mlibhdr ldhead; /* library header */
114
115/* forward references */
116
117void ldpoint(int16_t x, int16_t y, int16_t pen);
118void ldswin(int16_t n);
119
120extern int16_t dspace(int16_t which);
121extern int16_t infield(int16_t row, int16_t col, struct fet *fetp);
122extern int16_t wrt_asg(int16_t slot);
123extern int16_t wrt_orc(int16_t slot, int16_t lorh);
124extern int16_t wrt_pat(int16_t slot);
125extern int16_t wrt_scr(int16_t slot);
126extern int16_t wrt_seq(int16_t slot);
127extern int16_t wrt_tun(int16_t slot);
128extern int16_t wrt_wav(int16_t slot);
129extern void arcurs(uint16_t icolor);
130extern void dswap(void);
131extern void itcini(uint16_t color);
132extern void itcpos(int16_t row, int16_t col);
133extern void ldermsg(int8_t *p1, int8_t *p2, int8_t *p3, uint16_t p4, uint16_t p5);
134extern void nospace(int8_t *et);
135extern void postio(void);
136extern void preio(void);
137extern void savefc(int16_t kind);
138extern void ttcini(uint16_t color);
139extern void vsndpal(int16_t pp[16][3]);
140
141/*
142
143*/
144
145int8_t *ftypes[][3] = { /* file types (must match libdsp.h) */
146
147 {"ASG", "Assignmnt", "Assignmnt"}, /* FT_ASG */
148 {"ORL", "Orchestra", "Orchestra"}, /* FT_ORL */
149 {"ORH", "Orchestra", "Orchestra"}, /* FT_ORH */
150 {"SCR", " Score", "Score"}, /* FT_SCR */
151 {"TUN", " Tuning", "Tuning"}, /* FT_TUN */
152 {"WAV", "Waveshape", "Waveshape"}, /* FT_WAV */
153 {"ORC", "Orchestra", "Orchestra"}, /* FT_ORC */
154 {"PAT", " Patch", "Patch"}, /* FT_PAT */
155 {"SEQ", " Sequence", "Sequence"} /* FT_SEQ */
156};
157
158int8_t ld_em1[] = "No files stored on disk";
159int8_t ld_em2[] = " by this operation";
160
161int16_t lbrpal[16][3] = { /* librarian color palette */
162
163 {0, 0, 0}, /* 0 */
164 {3, 3, 3}, /* 1 */
165 {1, 0, 0}, /* 2 */
166 {1, 1, 0}, /* 3 */
167 {2, 1, 0}, /* 4 (was 2, 2, 0) */
168 {1, 1, 0}, /* 5 */
169 {2, 1, 0}, /* 6 (was 2, 2, 0) */
170 {1, 0, 0}, /* 7 */
171 {0, 1, 1}, /* 8 (was 0, 1, 0) */
172 {1, 0, 0}, /* 9 */
173 {1, 1, 0}, /* 10 */
174 {2, 2, 2}, /* 11 */
175 {2, 3, 3}, /* 12 */
176 {3, 3, 0}, /* 13 */
177 {3, 0, 0}, /* 14 */
178 {0, 0, 0} /* 15 */
179};
180
181/*
182
183*/
184
185/*
186 =============================================================================
187 ftkind() -- return the file type for a given file catalog slot
188
189 ns = catalog slot index
190 -1 returned on error (returns 1..NFTYPES for a good type)
191 =============================================================================
192*/
193
194int16_t ftkind(int16_t ns)
195{
196 register int16_t i;
197
198 for (i = 0; i < NFTYPES; i++)
199 if (0 EQ memcmpu(filecat[ns].fcextn, ftypes[i][0], 3))
200 return(++i);
201
202 return(-1);
203}
204
205/*
206 =============================================================================
207 fctstr() -- return a string showing the file catalog entry type
208
209 ns = catalog slot index
210 just = 0: right justify string, 1: left justify string
211 =============================================================================
212*/
213
214int8_t *fctstr(int16_t ns, int16_t just)
215{
216 static int8_t fcbad[11];
217 register int16_t i;
218
219 for (i = 0; i < NFTYPES; i++)
220 if (0 EQ memcmpu(filecat[ns].fcextn, ftypes[i][0], 3))
221 return(ftypes[i][just ? 2 : 1]);
222
223 sprintf(fcbad, "?? %3.3s ??", filecat[ns].fcextn);
224 return(fcbad);
225}
226
227/*
228
229*/
230
231/*
232 =============================================================================
233 ocslot() -- determine if a slot is occupied
234 =============================================================================
235*/
236
237int16_t ocslot(int16_t slot)
238{
239 if (memcmp(filecat[slot].fcsize, "000", 3)
240 AND (0 NE filecat[slot].fcsize[0]))
241 return(TRUE);
242 else
243 return(FALSE);
244}
245
246/*
247 =============================================================================
248 ldline() -- determine which catalog line the cursor is on, if any
249 =============================================================================
250*/
251
252int16_t ldline(int16_t cy)
253{
254 if (cy > 292)
255 return(0);
256
257 if (cy < 14)
258 return(0);
259
260 return(cy / 14);
261}
262
263/*
264
265*/
266
267/*
268 =============================================================================
269 lin2slt() -- determine which slot a line corresponds to, if any
270
271 -1 returned on error (0..FCMAX-1 returned for a good slot)
272 =============================================================================
273*/
274
275int16_t lin2slt(int16_t line)
276{
277 register int16_t slot, row;
278
279 row = 0;
280
281 for (slot = 0; slot < FCMAX; slot++)
282 if (ocslot(slot))
283 if (++row EQ line)
284 return(slot);
285
286 return(-1);
287}
288
289/*
290 =============================================================================
291 exp_c() -- expand a 4 bit color to 16 bits
292 =============================================================================
293*/
294
295uint16_t exp_c(uint16_t c)
296{
297 c &= 0x000F; /* use low 4 bits as the basis */
298 c |= c << 4; /* turn them into 8 bits */
299 c |= c << 8; /* make it a full 16 bits */
300
301 return(c);
302}
303
304/*
305
306*/
307
308/*
309 =============================================================================
310 ldwmsg() -- display a message in the message window
311 =============================================================================
312*/
313
314void ldwmsg(int8_t *line1, int8_t *line2, int8_t *line3, uint16_t fgcolor, uint16_t bgcolor)
315{
316 lderrsw = FALSE; /* clear error switch */
317 lmwtype = 2; /* message type */
318 submenu = FALSE;
319
320 if (ndisp NE 0)
321 return;
322
323 bgcolor = exp_c(bgcolor); /* expand background color */
324 fgcolor = exp_c(fgcolor); /* expand foreground color */
325
326 if (v_regs[5] & 0x0180)
327 vbank(0);
328
329 /* clear the window */
330
331 vbfill4(librob, 128, ldbox[10][0], ldbox[10][1],
332 ldbox[10][2], ldbox[10][3], bgcolor);
333
334 if ((int8_t *)NULL NE line1)
335 tsplot4(librob, 64, fgcolor, ldbox[10][6], ldbox[10][7],
336 line1, 14);
337
338 if ((int8_t *)NULL NE line2)
339 tsplot4(librob, 64, fgcolor, (ldbox[10][6] + 1), ldbox[10][7],
340 line2, 14);
341
342 if ((int8_t *)NULL NE line3)
343 tsplot4(librob, 64, fgcolor, (ldbox[10][6] + 2), ldbox[10][7],
344 line3, 14);
345}
346
347/*
348
349*/
350
351/*
352 =============================================================================
353 chksum() -- checksum an area of memory
354 =============================================================================
355*/
356
357int32_t chksum(int8_t *area, int32_t len)
358{
359 register int32_t cs, i;
360
361 cs = 0L;
362
363 for (i = 0; i < len; i++)
364 cs += 0x000000FFL & *area++;
365
366 return(cs);
367}
368
369/*
370 =============================================================================
371 makelh() -- make a library header
372 =============================================================================
373*/
374
375void makelh(int16_t kind)
376{
377 memset(ldhead.l_csum, '?', 8); /* checksum */
378 memcpy(ldhead.l_name, ldfile, 8); /* file name */
379 memcpy(ldhead.l_type, ftypes[kind - 1][0], 3); /* file type */
380 memcpy(ldhead.l_cmnt, ldcmnt, 37); /* comment */
381
382 lcsum = chksum(ldhead.l_name, (int32_t)(LH_LEN - 8));
383}
384
385/*
386
387*/
388
389/*
390 =============================================================================
391 ldbusy() -- put up a "Busy" message
392 =============================================================================
393*/
394
395void ldbusy(int8_t *msg)
396{
397 if (ndisp NE 0)
398 return;
399
400 ldwmsg((int8_t *)NULL, " Busy - Please stand by", msg,
401 ldbox[10][4], ldbox[10][5]);
402}
403
404/*
405 =============================================================================
406 noslot() -- complain about not finding a slot we expected
407 =============================================================================
408*/
409
410void noslot(int16_t fctype)
411{
412 sprintf(ldmsg1, " the %s file,", ftypes[fctype - 1][2]);
413
414 ldermsg("Can't find a slot for",
415 ldmsg1, " and one was expected", LD_EMCF, LD_EMCB);
416}
417
418/*
419
420*/
421
422/*
423 =============================================================================
424 wr_ec() -- write with error checking
425 =============================================================================
426*/
427
428int16_t wr_ec(FILE *fp, int8_t *from, int32_t len)
429{
430 register int32_t count;
431 register int8_t c;
432 for (count = 0; count < len; count++) {
433
434 errno = 0;
435 c = *from++;
436
437 if (EOF EQ putc(c, fp)) {
438
439 sprintf(errbuf, "errno = %d", errno);
440
441 ldermsg("Disk may be full",
442 errbuf, (int8_t *)NULL, LD_EMCF, LD_EMCB);
443
444 fclose(fp);
445 postio(); /* restore LCD backlight */
446 return(FAILURE);
447 }
448
449#if DEBUGWE
450 if (debugsw AND debugwe)
451 printf(" %02.2X", 0x00FF & c);
452#endif
453 }
454
455 return(SUCCESS);
456}
457
458/*
459
460*/
461
462/*
463 =============================================================================
464 rd_ec() -- read with error checking
465 =============================================================================
466*/
467
468int16_t rd_ec(FILE *fp, int8_t *to, int32_t len)
469{
470 register int32_t count;
471 register int16_t c;
472
473 for (count = 0; count < len; count++) {
474
475 errno = 0;
476
477 if (EOF EQ (c = getc(fp))) {
478
479 sprintf(errbuf, "errno = %d", errno);
480
481 ldermsg("Unexpected EOF",
482 errbuf, (int8_t *)NULL, LD_EMCF, LD_EMCB);
483
484 fclose(fp);
485 postio(); /* restore LCD backlight */
486 return(FAILURE);
487
488 } else {
489
490 *to++ = c;
491
492#if DEBUGRE
493 if (debugsw AND debugre)
494 printf(" %02.2X", 0x00FF & c);
495#endif
496 }
497 }
498
499 return(SUCCESS);
500}
501
502/*
503
504*/
505
506/*
507 =============================================================================
508 srchcat() -- search the file catalog
509
510 returns -1 on 'not found', slot 0..FCMAX-1 if found
511 =============================================================================
512*/
513
514int16_t srchcat(int8_t extn[])
515{
516 register int16_t fcslot;
517
518 for (fcslot = 0; fcslot < FCMAX; fcslot++) {
519
520 if (ocslot(fcslot))
521 if (0 EQ (memcmp(filecat[fcslot].fcname, ldfile, 8))
522 AND (0 EQ memcmpu(filecat[fcslot].fcextn, extn, 3)))
523 return(fcslot);
524 }
525
526 return(-1);
527}
528
529/*
530 =============================================================================
531 clrcat() -- clear the file catalog
532 =============================================================================
533*/
534
535void clrcat(void)
536{
537 register int16_t i;
538 int8_t fcebuf[1 + sizeof (struct fcat)];
539
540 for (i = 0; i < FCMAX; i++) {
541
542 sprintf(fcebuf, "000 Empty-%02.2d ??? %-37.37s%c%c",
543 i, "1234567890123456789012345678901234567",
544 A_CR, A_LF);
545
546 memcpy(&filecat[i], fcebuf, sizeof (struct fcat));
547 }
548}
549
550/*
551
552*/
553
554/*
555 =============================================================================
556 clreq() -- return number of clusters needed for a file
557
558 Assumes the BPB pointer is valid.
559 =============================================================================
560*/
561
562int16_t clreq(int32_t bytes)
563{
564 register int16_t rclusts;
565 register int32_t clmask;
566
567 clmask = _thebpb->clsizb - 1;
568
569 rclusts = (bytes / _thebpb->clsizb)
570 + ((bytes & clmask) ? 1 : 0);
571
572 return(rclusts);
573}
574
575/*
576
577*/
578
579/*
580 =============================================================================
581 spacerq() -- return space required for storing a file
582 =============================================================================
583*/
584
585int16_t spacerq(int16_t kind)
586{
587 register int16_t howmuch;
588 register int32_t k;
589
590 k = 0L;
591
592 switch (kind) {
593
594 case FT_ASG: /* Assignment file */
595
596 k = (sizeof (struct asgent) * (int32_t)NASGLIB) + LH_LEN;
597 break;
598
599 case FT_ORL:
600 case FT_ORH:
601 case FT_ORC:
602
603 k = ((OR_LEN1 + (2 * OR_LEN2)) * (int32_t)NINORC) + LH_LEN;
604 break;
605
606 case FT_PAT: /* Patch file */
607
608 k = ptsizer() + LH_LEN;
609 break;
610
611 case FT_SCR: /* Score file */
612
613 k = scsizer() + LH_LEN;
614 break;
615
616 case FT_SEQ: /* Sequence file */
617
618 k = sqsizer() + LH_LEN;
619 break;
620
621 case FT_TUN: /* Tuning file */
622
623 k = (NTUNSLIB * 256L) + (NTUNSLIB * 32L) + LH_LEN;
624 break;
625
626 case FT_WAV: /* Waveshape file */
627
628 k = ((int32_t)NUMWAVS * OR_LEN2) + LH_LEN;
629 break;
630
631 default:
632
633 k = 0L;
634 break;
635 }
636/*
637
638*/
639 howmuch = k ? clreq(k) : -1;
640 ndbytes = k;
641 return(howmuch);
642}
643
644/*
645
646*/
647
648/*
649 =============================================================================
650 ckstor() -- check for storage type selection
651 =============================================================================
652*/
653
654int16_t ckstor(void)
655{
656 if (lasgsw) /* assignments */
657 return(SUCCESS);
658
659 if (lorchsw) /* hi orch */
660 return(SUCCESS);
661
662 if (lorclsw) /* lo orch */
663 return(SUCCESS);
664
665 if (lpatsw) /* patches */
666 return(SUCCESS);
667
668 if (lscrsw) /* score */
669 return(SUCCESS);
670
671 if (lseqsw) /* sequences */
672 return(SUCCESS);
673
674 if (ltunsw) /* tunings */
675 return(SUCCESS);
676
677 if (lwavsw) /* waveshapes */
678 return(SUCCESS);
679
680 return(FAILURE);
681}
682
683/*
684
685*/
686
687/*
688 =============================================================================
689 ckdups() -- check for duplicate file type entries in the file catalog
690 =============================================================================
691*/
692
693int16_t ckdups(void)
694{
695 if (lasgsw)
696 if (-1 NE srchcat("asg"))
697 return(FT_ASG);
698
699 if (lorchsw)
700 if (-1 NE srchcat("orh"))
701 return(FT_ORH);
702
703 if (lorclsw)
704 if (-1 NE srchcat("orl"))
705 return(FT_ORL);
706
707 if (lorchsw OR lorclsw)
708 if (-1 NE srchcat("orc"))
709 return(FT_ORC);
710
711 if (lpatsw)
712 if (-1 NE srchcat("pat"))
713 return(FT_PAT);
714
715 if (lscrsw)
716 if (-1 NE srchcat("scr"))
717 return(FT_SCR);
718
719 if (lseqsw)
720 if (-1 NE srchcat("seq"))
721 return(FT_SEQ);
722
723 if (ltunsw)
724 if (-1 NE srchcat("tun"))
725 return(FT_TUN);
726
727 if (lwavsw)
728 if (-1 NE srchcat("wav"))
729 return(FT_WAV);
730 return(0);
731}
732
733/*
734
735*/
736
737/*
738 =============================================================================
739 showsiz() -- display disk capacity and usage
740
741 Forces the disk to be read to get the BPB and FAT.
742 =============================================================================
743*/
744
745int16_t showsiz(void)
746{
747 register int16_t dcap, drem, dused;
748
749 _bpbin = FALSE; /* force disk to be read */
750
751 dcap = dspace(0);
752
753 if (dcap EQ -1) {
754
755 ldermsg("Disk not ready ?",
756 (int8_t *)NULL, (int8_t *)NULL,
757 LD_EMCF, LD_EMCB);
758
759 return(FAILURE);
760 }
761
762 drem = dspace(1);
763 dused = dcap - drem;
764
765 sprintf(ldmsg1, "Microdisk capacity %4u blocks", dcap);
766 sprintf(ldmsg2, "This disk consumes %4u blocks", dused);
767 sprintf(ldmsg3, "Available space is %4u blocks", drem);
768
769 ldwmsg(ldmsg1, ldmsg2, ldmsg3, ldbox[10][4], ldbox[10][5]);
770 return(SUCCESS);
771}
772
773/*
774
775*/
776
777/*
778 =============================================================================
779 getcat() -- get the file catalog from disk
780 =============================================================================
781*/
782
783int16_t getcat(int16_t msgsw)
784{
785 register FILE *fp;
786 int16_t rc, fesize;
787
788 ldidsiz = FALSE; /* we didn't show the size (yet) */
789 _bpbin = FALSE; /* guarantee we read the directory */
790 catin = FALSE; /* catalog not valid */
791
792 errno = 0;
793 preio(); /* kill LCD backlight */
794 fp = fopenb(CATNAME, "r"); /* open the catalog file */
795
796 if (NULL EQ fp) {
797
798 clrcat();
799 catin = TRUE;
800
801 if (msgsw) { /* see if we show the message */
802
803 showsiz();
804 ldidsiz = TRUE; /* showed the size */
805 }
806
807 return(SUCCESS); /* no catalog is OK, too */
808 }
809
810 fesize = sizeof(struct fcat);
811 memset(filecat, 0, sizeof (struct fcat) * FCMAX);
812
813/*
814
815*/
816 errno = 0;
817 rc = fread(filecat, fesize, FCMAX, fp);
818
819 if (rc NE FCMAX) {
820
821 if (rc) {
822
823 sprintf(ldmsg1, " fread returned %d", rc);
824 sprintf(ldmsg2, " errno = %d, fesize=%d",
825 errno, fesize);
826
827 ldermsg("Unable to read catalog",
828 ldmsg1, ldmsg2, LD_EMCF, LD_EMCB);
829
830 catin = FALSE;
831
832 } else {
833
834 ldermsg("File catalog is NULL",
835 (int8_t *)NULL, (int8_t *)NULL,
836 LD_EMCF, LD_EMCB);
837
838 clrcat();
839 catin = TRUE;
840 }
841
842 fclose(fp);
843 postio(); /* restore LCD backlight */
844 return(FAILURE);
845 }
846
847 catin = TRUE;
848 fclose(fp);
849 postio(); /* restore LCD backlight */
850 return(SUCCESS);
851}
852
853/*
854
855*/
856
857/*
858 =============================================================================
859 putcat() -- write the updated catalog on disk
860 =============================================================================
861*/
862
863int16_t putcat(void)
864{
865 register FILE *fp;
866 register int16_t i, rc, fesize;
867
868 for (i = 0; i < FCMAX; i++) { /* clean up the catalog */
869
870 filecat[i].fceol[0] = A_CR;
871 filecat[i].fceol[1] = A_LF;
872 }
873
874 errno = 0;
875 preio(); /* kill LCD backlight */
876 fp = fopenb(CATNAME, "w"); /* open the catalog file */
877
878 if (NULL EQ fp) {
879
880 sprintf(ldmsg2, " errno = %d", errno);
881
882 ldermsg("Unable to open catalog",
883 (int8_t *)NULL, ldmsg2, LD_EMCF, LD_EMCB);
884
885 return(FAILURE);
886 }
887
888 fesize = sizeof (struct fcat);
889
890/*
891
892*/
893 errno = 0;
894 rc = fwrite(filecat, fesize, FCMAX, fp);
895
896 if (rc NE FCMAX) {
897
898 if (rc) {
899
900 sprintf(ldmsg1, " fwrite returned %d", rc);
901 sprintf(ldmsg2, " errno = %d, fesize=%d",
902 errno, fesize);
903
904 ldermsg("Can't write catalog",
905 ldmsg1, ldmsg2, LD_EMCF, LD_EMCB);
906
907 } else {
908
909 sprintf(ldmsg2, " errno = %d", errno);
910
911 ldermsg("Disk may be full",
912 (int8_t *)NULL, ldmsg2,
913 LD_EMCF, LD_EMCB);
914 }
915
916 fclose(fp);
917 postio(); /* restore LCD backlight */
918 return(FAILURE);
919 }
920
921 fclose(fp);
922 postio(); /* restore LCD backlight */
923 return(SUCCESS);
924}
925
926/*
927
928*/
929
930/*
931 =============================================================================
932 dslslot() -- display a file catalog entry
933 =============================================================================
934*/
935
936void dslslot(int16_t slot, uint16_t fg, int16_t row)
937{
938 register uint16_t color, chilon, chilorc;
939 int16_t c;
940 int8_t buf[40];
941
942 if (ndisp NE 0)
943 return;
944
945 color = exp_c(fg); /* foreground color */
946 chilon = exp_c(ldbox[1][4]);
947 chilorc = exp_c(HILORC);
948
949 /* file type */
950
951 vcputsv(librob, 64, color, ldbox[1][5], row, 1, fctstr(slot, 0), 14);
952
953 /* load letter */
954
955 c = filecat[slot].fcp0;
956 buf[0] = 0x007F & c;
957 buf[1] = '\0';
958 vcputsv(librob, 64, (c & 0x0080) ? chilorc : chilon,
959 ldbox[1][5], row, 11, buf, 14);
960
961 /* file name */
962
963 memcpy(buf, filecat[slot].fcname, 8);
964 buf[8] = '\0';
965 vcputsv(librob, 64, color, ldbox[1][5], row, 13, buf, 14);
966
967 /* comment */
968
969 memcpy(buf, filecat[slot].fccmnt, 37);
970 buf[37] = '\0';
971 vcputsv(librob, 64, chilon, ldbox[1][5], row, 22, buf, 14);
972
973 /* size */
974
975 memcpy(buf, filecat[slot].fcsize, 3);
976 buf[3] = '\0';
977 vcputsv(librob, 64, chilon, ldbox[1][5], row, 60, buf, 14);
978}
979
980/*
981
982*/
983
984/*
985 =============================================================================
986 showcat() -- display the file catalog entries
987 =============================================================================
988*/
989
990int16_t showcat(void)
991{
992 register int16_t i, fcslot, fcrow, fcount;
993 register uint16_t color;
994
995 if (ndisp NE 0)
996 return(FAILURE);
997
998 ldswin(0); /* fix up the title */
999
1000 color = exp_c(ldbox[1][5]); /* background color */
1001
1002 if (v_regs[5] & 0x0180)
1003 vbank(0);
1004
1005 vbfill4(librob, 128, ldbox[1][0], ldbox[1][1],
1006 ldbox[1][2], ldbox[1][3], color);
1007
1008 color = ldbox[1][4]; /* foreground color */
1009
1010 fcrow = 1;
1011 fcount = 0;
1012
1013 for (fcslot = 0; fcslot < FCMAX; fcslot++) {
1014
1015 if (ocslot(fcslot)) {
1016
1017 dslslot(fcslot, color, fcrow);
1018 fcrow++;
1019 fcount++;
1020 }
1021 }
1022
1023 return(fcount);
1024}
1025
1026/*
1027
1028*/
1029
1030/*
1031 =============================================================================
1032 fcindex() -- display the file catalog
1033 =============================================================================
1034*/
1035
1036int16_t fcindex(void)
1037{
1038 if (NOT lderrsw)
1039 ldbusy(" Reading catalog");
1040
1041 if (getcat(1)) /* get catalog, possibly display size */
1042 return(FAILURE);
1043
1044 if (NOT lderrsw)
1045 showcat(); /* display the catalog */
1046
1047 /* show size if getcat() didn't */
1048
1049 if ((NOT ldidsiz) AND (NOT lderrsw))
1050 showsiz();
1051
1052 return(SUCCESS);
1053}
1054
1055/*
1056
1057*/
1058
1059/*
1060 =============================================================================
1061 streset() -- reset the switches after a store or an error
1062 =============================================================================
1063*/
1064
1065void streset(void)
1066{
1067 lstrsw = FALSE;
1068
1069 lasgsw = FALSE;
1070 lorchsw = FALSE;
1071 lorclsw = FALSE;
1072 lpatsw = FALSE;
1073 lscrsw = FALSE;
1074 lseqsw = FALSE;
1075 ltunsw = FALSE;
1076 lwavsw = FALSE;
1077
1078 ldswin(9);
1079}
1080
1081/*
1082 =============================================================================
1083 fcreset() -- reset the switches after a fetch or an error
1084 =============================================================================
1085*/
1086
1087void fcreset(void)
1088{
1089 lselsw = FALSE;
1090
1091 ldswin(6);
1092}
1093
1094/*
1095
1096*/
1097
1098/*
1099 =============================================================================
1100 getslot() -- find a free file catalog slot
1101
1102 returns -1 on error, slot # 0..FCMAX-1 if a slot was found
1103 =============================================================================
1104*/
1105
1106int16_t getslot(void)
1107{
1108 register int16_t i;
1109
1110 for (i = 0; i < FCMAX; i++)
1111 if (NOT ocslot(i))
1112 return(i);
1113
1114 return(-1);
1115}
1116
1117/*
1118 =============================================================================
1119 slotnam() -- return the file name for a slot
1120 =============================================================================
1121*/
1122
1123int8_t *slotnam(uint16_t slot, uint16_t kind)
1124{
1125 static int8_t thename[13];
1126
1127 sprintf(thename, "M7SLOT%02.2u.%-3.3s",
1128 slot, ftypes[kind - 1][0]);
1129
1130 return(thename);
1131}
1132
1133/*
1134
1135*/
1136
1137/*
1138 =============================================================================
1139 wrtfile() -- write a file on the disk
1140 =============================================================================
1141*/
1142
1143int16_t wrtfile(int16_t kind)
1144{
1145 register int16_t slot, flspace, tkind;
1146 int8_t sizetmp[4];
1147
1148 slot = getslot();
1149
1150 if (-1 EQ slot) {
1151
1152 noslot(kind);
1153 streset();
1154 return(FAILURE);
1155 }
1156
1157/*
1158
1159*/
1160
1161 switch (kind) {
1162
1163 case FT_ASG:
1164
1165 if (wrt_asg(slot))
1166 return(FAILURE);
1167 else
1168 break;
1169
1170 case FT_ORL: /* lo orch write */
1171
1172 if (wrt_orc(slot, 0))
1173 return(FAILURE);
1174 else
1175 break;
1176
1177 case FT_ORH: /* hi orch write */
1178
1179 if (wrt_orc(slot, 1))
1180 return(FAILURE);
1181 else
1182 break;
1183
1184 case FT_PAT:
1185
1186 if (wrt_pat(slot))
1187 return(FAILURE);
1188 else
1189 break;
1190
1191 case FT_SCR:
1192
1193 if (wrt_scr(slot))
1194 return(FAILURE);
1195 else
1196 break;
1197
1198 case FT_SEQ:
1199
1200 if (wrt_seq(slot))
1201 return(FAILURE);
1202 else
1203 break;
1204
1205/*
1206
1207*/
1208 case FT_TUN:
1209
1210 if (wrt_tun(slot))
1211 return(FAILURE);
1212 else
1213 break;
1214
1215 case FT_WAV:
1216
1217 if (wrt_wav(slot))
1218 return(FAILURE);
1219 else
1220 break;
1221
1222 default:
1223
1224 sprintf(ldmsg1, " kind=%d", kind);
1225
1226 ldermsg("bad wrtfile argument:",
1227 ldmsg1, (int8_t *)NULL, LD_EMCF, LD_EMCB);
1228
1229 return(FAILURE);
1230 }
1231
1232/*
1233
1234*/
1235
1236 /* update the file catalog */
1237
1238 if ((kind EQ FT_ORL) OR (kind EQ FT_ORH))
1239 tkind = FT_ORC;
1240 else
1241 tkind = kind;
1242
1243 flspace = spacerq(kind);
1244
1245 sprintf(sizetmp, "%03.3d", flspace); /* size */
1246 memcpy(filecat[slot].fcsize, sizetmp, 3);
1247
1248 memcpy(filecat[slot].fcname, ldfile, 8); /* name */
1249 memcpy(filecat[slot].fcextn, ftypes[tkind - 1][0], 3); /* type */
1250 memcpy(filecat[slot].fccmnt, ldcmnt, 37); /* comment */
1251
1252 savefc(kind);
1253
1254 filecat[slot].fceol[0] = A_CR;
1255 filecat[slot].fceol[1] = A_LF;
1256
1257 return(SUCCESS);
1258}
1259
1260/*
1261
1262*/
1263
1264/*
1265 =============================================================================
1266 writem() -- write selected files
1267 =============================================================================
1268*/
1269
1270int16_t writem(void)
1271{
1272 if (lasgsw) /* Assignments */
1273 if (wrtfile(FT_ASG))
1274 return(FAILURE);
1275
1276 if (lorchsw) /* Hi Orch */
1277 if (wrtfile(FT_ORH))
1278 return(FAILURE);
1279
1280 if (lorclsw) /* Lo Orch */
1281 if (wrtfile(FT_ORL))
1282 return(FAILURE);
1283
1284 if (lpatsw) /* Patches */
1285 if (wrtfile(FT_PAT))
1286 return(FAILURE);
1287
1288 if (lscrsw) /* Score */
1289 if (wrtfile(FT_SCR))
1290 return(FAILURE);
1291
1292 if (lseqsw) /* Sequences */
1293 if (wrtfile(FT_SEQ))
1294 return(FAILURE);
1295
1296 if (ltunsw) /* Tunings */
1297 if (wrtfile(FT_TUN))
1298 return(FAILURE);
1299
1300 if (lwavsw) /* Waveshapes */
1301 if (wrtfile(FT_WAV))
1302 return(FAILURE);
1303
1304 return(SUCCESS);
1305}
1306
1307/*
1308
1309*/
1310
1311/*
1312 =============================================================================
1313 storit() -- store selected files on disk
1314 =============================================================================
1315*/
1316
1317int16_t storit(void)
1318{
1319 register int16_t weneed, i, slotnd, slothv;
1320 int16_t rc, drem;
1321
1322 /* make sure the file is named */
1323
1324 if (0 EQ memcmp(ldfile, " ", 8)) {
1325
1326 ldermsg("File must be named",
1327 ld_em1, ld_em2, LD_EMCF, LD_EMCB);
1328
1329 streset();
1330 return(FAILURE);
1331 }
1332
1333 /* make sure something was selected */
1334
1335 if (ckstor()) {
1336
1337 ldermsg("No file type selected",
1338 ld_em1, ld_em2, LD_EMCF, LD_EMCB);
1339
1340 streset();
1341 return(FAILURE);
1342 }
1343
1344 if (NOT lderrsw)
1345 ldbusy(" Storing files");
1346
1347 if (getcat(0)) { /* get the catalog */
1348
1349 streset();
1350 return(FAILURE);
1351 }
1352
1353 /* find out how much space we need to store everything */
1354
1355 drem = dspace(1);
1356 slotnd = 0;
1357 weneed = 0;
1358
1359/*
1360
1361*/
1362 if (lasgsw) {
1363
1364 weneed += spacerq(FT_ASG);
1365 ++slotnd;
1366 }
1367
1368 if (lorchsw) {
1369
1370 weneed += spacerq(FT_ORH);
1371 ++slotnd;
1372 }
1373
1374 if (lorclsw) {
1375
1376 weneed += spacerq(FT_ORL);
1377 ++slotnd;
1378 }
1379
1380 if (lpatsw) {
1381
1382 weneed += spacerq(FT_PAT);
1383 ++slotnd;
1384 }
1385
1386 if (lscrsw) {
1387
1388 weneed += spacerq(FT_SCR);
1389 ++slotnd;
1390 }
1391
1392 if (lseqsw) {
1393
1394 weneed += spacerq(FT_SEQ);
1395 ++slotnd;
1396 }
1397
1398 if (ltunsw) {
1399
1400 weneed += spacerq(FT_TUN);
1401 ++slotnd;
1402 }
1403
1404 if (lwavsw) {
1405
1406 weneed += spacerq(FT_WAV);
1407 ++slotnd;
1408 }
1409
1410 if (drem < weneed) {
1411
1412 nospace("file");
1413 streset();
1414 return(FAILURE);
1415 }
1416
1417/*
1418
1419*/
1420
1421 /* see if we have enough catalog space */
1422
1423 slothv = 0;
1424
1425 for (i = 0; i < FCMAX; i++)
1426 if (NOT ocslot(i))
1427 ++slothv;
1428
1429 if (slothv < slotnd) {
1430
1431 nospace("file");
1432 streset();
1433 return(FAILURE);
1434 }
1435
1436 /* make sure the name is unique */
1437
1438 if (rc = ckdups()) {
1439
1440 sprintf(ldmsg1, "Duplicate %s", ftypes[rc - 1][2]);
1441 ldermsg(ldmsg1, ld_em1, ld_em2, LD_EMCF, LD_EMCB);
1442
1443 streset();
1444 return(FAILURE);
1445 }
1446
1447/*
1448
1449*/
1450
1451 /* write the files */
1452
1453 rc = writem();
1454
1455 if (NOT rc)
1456 ldbusy(" Writing catalog");
1457
1458 if (putcat()) {
1459
1460 _clsvol();
1461 streset();
1462 showcat();
1463 return(FAILURE);
1464 }
1465
1466 _clsvol();
1467 streset();
1468 showcat();
1469
1470 if (rc)
1471 return(FAILURE);
1472
1473 showsiz();
1474 return(SUCCESS);
1475}
1476
1477/*
1478
1479*/
1480
1481/*
1482 =============================================================================
1483 advlcur() -- advance the librarian display text cursor
1484 =============================================================================
1485*/
1486
1487void advlcur(void)
1488{
1489 register int16_t newcol;
1490
1491 if (infield(stcrow, stccol, curfet))
1492 cfetp = infetp;
1493 else
1494 return;
1495
1496 newcol = stccol + 1;
1497
1498 if (newcol LE cfetp->frcol)
1499 itcpos(stcrow, newcol);
1500
1501 cxval = stccol * 8;
1502 cyval = stcrow * 14;
1503}
1504
1505/*
1506 =============================================================================
1507 bsplcur() -- backspace the librarian display text cursor
1508 =============================================================================
1509*/
1510
1511void bsplcur(void)
1512{
1513 register int16_t newcol;
1514
1515 if (infield(stcrow, stccol, curfet))
1516 cfetp = infetp;
1517 else
1518 return;
1519
1520 newcol = stccol - 1;
1521
1522 if (newcol GE cfetp->flcol)
1523 itcpos(stcrow, newcol);
1524
1525 cxval = stccol * 8;
1526 cyval = stcrow * 14;
1527}
1528
1529/*
1530
1531*/
1532
1533/*
1534 =============================================================================
1535 ldswin() -- display a window
1536 =============================================================================
1537*/
1538
1539void ldswin(int16_t n)
1540{
1541 register int16_t cx, cy;
1542
1543 if (ndisp NE 0)
1544 return;
1545
1546 if ((n EQ 10) AND (lmwtype EQ 1))
1547 cx = exp_c(TTBACK); /* use black for the typewriter */
1548 else
1549 cx = exp_c(ldbox[n][5]); /* expand the background color */
1550
1551 /* first, fill the box with the background color */
1552
1553 if (v_regs[5] & 0x0180)
1554 vbank(0);
1555
1556 vbfill4(librob, 128, ldbox[n][0], ldbox[n][1], ldbox[n][2],
1557 ldbox[n][3], cx);
1558
1559 /* put in the box label */
1560
1561 tsplot4(librob, 64, ldbox[n][4], ldbox[n][6], ldbox[n][7],
1562 ldbxlb0[n], 14);
1563
1564/*
1565
1566*/
1567 switch (n) { /* final text - overlays above stuff */
1568
1569 case 0: /* titles */
1570
1571 point = ldpoint;
1572
1573 lseg( 8, 13, 79, 13, LUNDRLN);
1574 lseg( 88, 13, 95, 13, LUNDRLN);
1575 lseg(104, 13, 167, 13, LUNDRLN);
1576 lseg(176, 13, 471, 13, LUNDRLN);
1577 lseg(480, 13, 504, 13, LUNDRLN);
1578
1579 return;
1580
1581 case 1: /* index area */
1582
1583 return;
1584
1585 case 3: /* current file name */
1586
1587 tsplot4(librob, 64, ldbox[n][4], ldbox[n][6], ldbox[n][7],
1588 ldfile, 14);
1589 return;
1590
1591 case 5: /* current comment field */
1592
1593 tsplot4(librob, 64, ldbox[n][4], ldbox[n][6], ldbox[n][7],
1594 ldcmnt, 14);
1595 return;
1596
1597/*
1598
1599*/
1600
1601 case 7: /* "Replace" / "Append" */
1602
1603 if (lrasw)
1604 cy = exp_c(LD_SELC);
1605 else
1606 cy = ldbox[n][4];
1607
1608 tsplot4(librob, 64, cy, ldbox[n][6], ldbox[n][7],
1609 "Content", 14);
1610
1611 return;
1612
1613 case 8: /* "Hi Orch" / "Lo Orch" */
1614
1615 if (lselsw) {
1616
1617 ldkind = ftkind(ldslot);
1618
1619 if ((ldkind EQ FT_ORC) OR
1620 (ldkind EQ FT_ORL) OR
1621 (ldkind EQ FT_ORH))
1622 cy = exp_c(LD_SELC);
1623 else
1624 cy = ldbox[n][4];
1625
1626 } else {
1627
1628 cy = ldbox[n][4];
1629 }
1630
1631 tsplot4(librob, 64, cy, ldbox[n][6], ldbox[n][7],
1632 (lorchl ? "Hi Orch" : "Lo Orch"), 14);
1633
1634 return;
1635/*
1636
1637*/
1638 case 9: /* "Store" status */
1639
1640 cy = exp_c(lstrsw ? LD_SELC : ldbox[n][4]);
1641 tsplot4(librob, 64, cy, 22, 10, "Store", 14);
1642
1643 cy = exp_c(lscrsw ? LD_SELC : ldbox[n][4]);
1644 tsplot4(librob, 64, cy, 22, 17, "Score", 14);
1645
1646 cy = exp_c(lorchsw ? LD_SELC : ldbox[n][4]);
1647 tsplot4(librob, 64, cy, 22, 24, "Hi Orch", 14);
1648
1649
1650 cy = exp_c(lwavsw ? LD_SELC : ldbox[n][4]);
1651 tsplot4(librob, 64, cy, 23, 10, "Waves", 14);
1652
1653 cy = exp_c(lpatsw ? LD_SELC : ldbox[n][4]);
1654 tsplot4(librob, 64, cy, 23, 17, "Patch", 14);
1655
1656 cy = exp_c(lorclsw ? LD_SELC : ldbox[n][4]);
1657 tsplot4(librob, 64, cy, 23, 24, "Lo Orch", 14);
1658
1659
1660 cy = exp_c(lasgsw ? LD_SELC : ldbox[n][4]);
1661 tsplot4(librob, 64, cy, 24, 10, "Assgn", 14);
1662
1663 cy = exp_c(lseqsw ? LD_SELC : ldbox[n][4]);
1664 tsplot4(librob, 64, cy, 24, 17, "Seqnc", 14);
1665
1666 cy = exp_c(ltunsw ? LD_SELC : ldbox[n][4]);
1667 tsplot4(librob, 64, cy, 24, 24, "Tunings", 14);
1668
1669 return;
1670
1671 case 10: /* typewriter / error messages */
1672
1673 tsplot4(librob, 64, ldbox[n][4], 22, ldbox[n][7], lmln22, 14);
1674 tsplot4(librob, 64, ldbox[n][4], 23, ldbox[n][7], lmln23, 14);
1675 tsplot4(librob, 64, ldbox[n][4], 24, ldbox[n][7], lmln24, 14);
1676
1677 return;
1678 }
1679}
1680
1681/*
1682
1683*/
1684
1685/*
1686 =============================================================================
1687 lwins() -- display all librarian windows
1688 =============================================================================
1689*/
1690
1691void lwins(void)
1692{
1693 register int16_t i;
1694
1695 for (i = 0; i < 11; i++)
1696 ldswin(i);
1697}
1698
1699/*
1700 =============================================================================
1701 ldpoint() -- plot a point for the lseg function
1702 =============================================================================
1703*/
1704
1705void ldpoint(int16_t x, int16_t y, int16_t pen)
1706{
1707 if (v_regs[5] & 0x0180)
1708 vbank(0);
1709
1710 vputp(ldoct, x, y, exp_c(pen));
1711}
1712
1713/*
1714
1715*/
1716
1717/*
1718 =============================================================================
1719 ldbord() -- draw the border for the librarian display
1720 =============================================================================
1721*/
1722
1723void ldbord(void)
1724{
1725 point = ldpoint;
1726
1727 lseg( 0, 0, 511, 0, LBORD); /* outer border */
1728 lseg(511, 0, 511, 349, LBORD);
1729 lseg(511, 349, 0, 349, LBORD);
1730 lseg( 0, 349, 0, 0, LBORD);
1731
1732 lseg( 0, 293, 511, 293, LBORD); /* windows - H lines */
1733 lseg(511, 308, 0, 308, LBORD);
1734
1735 lseg( 79, 293, 79, 308, LBORD); /* windows - V lines */
1736 lseg(144, 293, 144, 308, LBORD);
1737 lseg(215, 293, 215, 308, LBORD);
1738 lseg( 71, 308, 71, 349, LBORD);
1739 lseg(256, 308, 256, 349, LBORD);
1740}
1741
1742/*
1743
1744*/
1745
1746/*
1747 =============================================================================
1748 lwclr() -- clear the message window text strings
1749 =============================================================================
1750*/
1751
1752void lmwclr(void)
1753{
1754 lmwtype = 0;
1755 submenu = FALSE;
1756
1757 lmln22 = "";
1758 lmln23 = "";
1759 lmln24 = "";
1760}
1761
1762/*
1763 =============================================================================
1764 lmwvtyp() -- load the typewriter into the message window text strings
1765 =============================================================================
1766*/
1767
1768void lmwvtyp(void)
1769{
1770 lmwtype = 1;
1771 submenu = TRUE;
1772
1773 lmln22 = vtlin1;
1774 lmln23 = vtlin2;
1775 lmln24 = vtlin3;
1776}
1777
1778/*
1779
1780*/
1781
1782/*
1783 =============================================================================
1784 libdsp() -- put up the librarian display
1785 =============================================================================
1786*/
1787
1788void libdsp(void)
1789{
1790 librob = &v_score[0]; /* setup display object pointer */
1791 obj0 = &v_curs0[0]; /* setup cursor object pointer */
1792 obj2 = &v_tcur[0]; /* setup typewriter cursor pointer */
1793 ldoct = &v_obtab[LIBROBJ]; /* setup object control table pointer */
1794
1795 lselsw = FALSE;
1796 ldelsw = FALSE;
1797 lstrsw = FALSE;
1798
1799 lasgsw = FALSE;
1800 lorchsw = FALSE;
1801 lorclsw = FALSE;
1802 lpatsw = FALSE;
1803 lscrsw = FALSE;
1804 lseqsw = FALSE;
1805 ltunsw = FALSE;
1806 lwavsw = FALSE;
1807
1808 lderrsw = FALSE;
1809 ltagged = FALSE;
1810 lksel = -1;
1811/*
1812
1813*/
1814 clrcat(); /* void the catalog */
1815 catin = FALSE;
1816
1817 lmwclr(); /* clear the message window text strings */
1818
1819 dswap(); /* initialize display */
1820
1821 if (v_regs[5] & 0x0180)
1822 vbank(0);
1823
1824 memsetw(librob, 0, 32767);
1825 memsetw(librob+32767L, 0, 12033);
1826
1827 SetObj(LIBROBJ, 0, 0, librob, 512, 350, 0, 0, LIBRFL, -1);
1828 SetObj( 0, 0, 1, obj0, 16, 16, LCURX, LCURY, OBFL_00, -1);
1829 SetObj( TTCURS, 0, 1, obj2, 16, 16, 0, 0, TTCCFL, -1);
1830
1831 arcurs(TTCURC); /* setup arrow cursor object */
1832 itcini(TTCURC); /* setup text cursor object */
1833 ttcini(TTCURC); /* setup typewriter cursor object */
1834
1835 ldbord(); /* draw the border */
1836 lwins();
1837
1838 vsndpal(lbrpal); /* setup the palette */
1839
1840 SetPri(LIBROBJ, LIBRPRI);
1841 SetPri(0, GCPRI); /* display the graphic cursor */
1842
1843 setgc(LCURX, LCURY);
1844
1845 chtime = thcwval; /* turn it into a text cursor */
1846 cvtime = tvcwval;
1847 cmtype = CT_TEXT;
1848 itcpos(cyval / 14, cxval >> 3);
1849}
1850
Note: See TracBrowser for help on using the repository browser.