home *** CD-ROM | disk | FTP | other *** search
- /*
- SG C Tools 1.0
-
- (C) 1993 Steve Goldsmith
- All Rights Reserved
-
- The VDC module provides a high level interface to access the C128's 8563 VDC
- (16K or 64K) chip. Functions are provided for high speed fills, copies,
- string output, etc. savevdc() should be called before any other VDC routines.
- This saves off key VDC registers and sets global 'vdc' prefixed vars. You are
- responsible for restoring any VDC RAM modified by your program. For example,
- if you over write RAM used by the character set for a bit map you must restore
- the character set before calling restorevdc() and exiting back to CP/M.
-
- Compiled with HI-TECH C 3.09 (CP/M-80).
- */
-
- #include <sys.h>
- #include <hitech.h>
- #include <string.h>
- #include <vdc.h>
-
- uchar vdcRegsToSave[] = /* vdc registers to save and restore */
- {0,1,2,3,4,5,6,7,8,9,10,11,12,13,
- 22,23,24,25,26,27,28,29,34,35,36};
- uchar vdcRegs[sizeof(vdcRegsToSave)-1]; /* saved vdc registers */
- uchar vdcScrHorz; /* vars initilized by savevdc() */
- uchar vdcScrVert;
- ushort vdcScrSize;
- ushort vdcDispMem;
- ushort vdcAttrMem;
-
- uchar invdc(uchar RegNum)
- {
- outp(vdcStatusReg,RegNum); /* internal vdc register to read */
- while ((inp(vdcStatusReg) & 0x80) == 0x00); /* wait for status bit to be set */
- return(inp(vdcDataReg)); /* read register */
- }
-
- void outvdc(uchar RegNum, uchar RegVal)
- {
- outp(vdcStatusReg,RegNum); /* internal vdc register to write */
- while ((inp(vdcStatusReg) & 0x80) == 0x00); /* wait for status bit to be set */
- outp(vdcDataReg,RegVal); /* write register */
- }
-
- void savevdc(void)
- {
- uchar I;
-
- for(I = 0; I < sizeof(vdcRegs); I++) /* save key vdc regs */
- vdcRegs[I] = invdc(vdcRegsToSave[I]);
- vdcScrHorz = invdc(vdcHzDisp); /* init global vdc vars */
- vdcScrVert = invdc(vdcVtDisp);
- vdcScrSize = vdcScrHorz*vdcScrVert;
- vdcDispMem = (ushort) ((invdc(vdcDspStAddrHi) << 8)+invdc(vdcDspStAddrLo));
- vdcAttrMem = (ushort) ((invdc(vdcAttrStAddrHi) << 8)+invdc(vdcAttrStAddrLo));
- }
-
- void restorevdc(void)
- {
- uchar I;
-
- for(I = 0; I < sizeof(vdcRegs); I++) /* restore vdc regs saved with savevdc() */
- outvdc(vdcRegsToSave[I],vdcRegs[I]);
- }
-
- /* set cursor's top and bottom scan lines and mode */
-
- void setcursorvdc(uchar Top, uchar Bottom, uchar Mode)
- {
- outvdc(vdcCurStScanLine,(Top | (Mode << 5)));
- outvdc(vdcCurEndScanLine,Bottom);
- }
-
- /* fast fill using block writes */
-
- void fillmemvdc(ushort FillMem, ushort FillLen, uchar Filler)
- {
- uchar Blocks, Remain, I;
-
- outvdc(vdcUpdAddrHi,(uchar) (FillMem >> 8));
- outvdc(vdcUpdAddrLo,(uchar) FillMem);
- outvdc(vdcVtSmScroll,(invdc(vdcVtSmScroll) & 0x7F));
- outvdc(vdcCPUData,Filler);
- if (FillLen > vdcMaxBlock)
- {
- Blocks = FillLen/vdcMaxBlock;
- Remain = FillLen%vdcMaxBlock;
- for(I = 1; I <= Blocks; I++)
- outvdc(vdcWordCnt,vdcMaxBlock);
- if (Remain > 1)
- outvdc(vdcWordCnt,--Remain);
- }
- else
- if (FillLen > 1)
- outvdc(vdcWordCnt,--FillLen);
- }
-
- /* fast copy using block copy */
-
- void copymemvdc(ushort SMem, ushort DMem, ushort CopyLen)
- {
- uchar Blocks, Remain, I;
-
- outvdc(vdcUpdAddrHi,(uchar) (DMem >> 8));
- outvdc(vdcUpdAddrLo,(uchar) DMem);
- outvdc(vdcVtSmScroll,(invdc(vdcVtSmScroll) | 0x80));
- outvdc(vdcBlkCpySrcAddrHi,(uchar) (SMem >> 8));
- outvdc(vdcBlkCpySrcAddrLo,(uchar) SMem);
- if (CopyLen > vdcMaxBlock)
- {
- Blocks = CopyLen/vdcMaxBlock;
- Remain = CopyLen%vdcMaxBlock;
- for(I = 1; I <= Blocks; I++)
- outvdc(vdcWordCnt,vdcMaxBlock);
- if (Remain > 0)
- outvdc(vdcWordCnt,Remain);
- }
- else
- if (CopyLen > 0)
- outvdc(vdcWordCnt,CopyLen);
- }
-
- /* sets which disp and attr page is showing */
-
- void setdsppagevdc(ushort DPage, ushort APage)
- {
- outvdc(vdcDspStAddrHi,(uchar) (DPage >> 8));
- outvdc(vdcDspStAddrLo,(uchar) DPage);
- outvdc(vdcAttrStAddrHi,(uchar) (APage >> 8));
- outvdc(vdcAttrStAddrLo,(uchar) APage);
- }
-
- /* copies disp and attr page to new pages */
-
- void copydspvdc(ushort SDPage, ushort SAPage, ushort DDPage, ushort DAPage)
- {
- copymemvdc(SDPage,DDPage,vdcScrSize);
- copymemvdc(SAPage,DAPage,vdcScrSize);
- }
-
- /* fast disp page clear with any byte */
-
- void clrscrvdc(uchar Ch)
- {
- fillmemvdc(vdcDispMem,vdcScrSize,Ch);
- }
-
- /* fast attr page clear with any byte */
-
- void clrattrvdc(uchar Attr)
- {
- fillmemvdc(vdcAttrMem,vdcScrSize,Attr);
- }
-
- /* fill disp mem given x and y offset in current page */
-
- void filldspvdc(uchar X, uchar Y, uchar CLen, uchar Ch)
- {
- fillmemvdc(vdcDispMem+Y*vdcScrHorz+X,CLen,Ch);
- }
-
- /* fill attr mem given x and y offset in current page */
-
- void fillattrvdc(uchar X, uchar Y, uchar ALen, uchar Attr)
- {
- fillmemvdc(vdcAttrMem+Y*vdcScrHorz+X,ALen,Attr);
- }
-
- /* fast vdc string print given x and y offset in current page */
-
- void printstrvdc(uchar X, uchar Y, uchar Attr, char * TextStr)
- {
- uchar I, TextLen;
- ushort DispOfs;
-
- DispOfs = vdcDispMem+Y*vdcScrHorz+X; /* calc disp mem offset */
- TextLen = strlen(TextStr);
- fillattrvdc(X,Y,TextLen,Attr); /* use block fill for attrs */
- outvdc(vdcUpdAddrHi,(uchar) (DispOfs >> 8));
- outvdc(vdcUpdAddrLo,(uchar) DispOfs); /* set addr of first char */
- for(I = 0; I < TextLen; I++) /* send str to vdc disp mem */
- outvdc(vdcCPUData,TextStr[I]);
- }
-