program tbohires; (* 80 col graphics for c128 cp/m *) (* integrated from various magazine articles and *) (* c128 prog ref guide *) (* leonard howie *) const vdcport=$d600; vdcplus1=$d601; (* port addresses for 8563 chip *) type mask_array = array[0..7] of byte; var waitport,portreg,regbyte:byte; x,y,lcol,lrow:integer; ytemp:real; m: mask_array; ChrAry:Array[0..8192] of byte; (* ============= screen plotting routines - 8563 vdc chip =========== *) (* 8 mar 87-bitmapping the 8563 video display controller *) (* commodore 128 cp/m - turbo pascal *) Procedure RamAddr(z:integer);Forward; procedure readvdc; (* this routine reads any 8563 register *) begin port[vdcport]:=portreg; (* desired register number to port *) repeat waitport:=(port[vdcport]) and 128; (* read address port value *) until waitport=128; (* until bit 7 is one *) regbyte:=port[vdcplus1]; (* then read the data port *) end; procedure writevdc; (* this routine writes to any 8563 register *) begin port[vdcport]:=portreg; (* desired register number to port *) repeat waitport:=(port[vdcport]) and 128; (* read address port value *) until waitport=128; (* until bit 7 is one *) port[vdcplus1]:=regbyte; (* then write to the data port *) end; (* Procedures Save_Char and Load_Char added 8/24/87 T. Dolan *) Procedure Save_Char; Begin WriteLn(^Z); WriteLn('Saving Character Ram to Memory'); For Y := 8192 to 16384 Do (* Start of VDC Char Ram *) Begin RamAddr(Y); Portreg := 31; (* Split 16 bit Value *) ReadVdc; (* Read Value from VDC Ram *) ChrAry[Y-8192] := RegByte; (* Store it in an array *) End; End; (* Load_Char has the same basic syntax as Save_Char only it writes the saved values back into the VDC Ram *) Procedure Load_Char; Begin For Y := 8192 to 16384 Do Begin RamAddr(Y); PortReg := 31; RegByte := ChrAry[Y-8192]; WriteVdc; End; End; procedure zeroram; begin regbyte:=0; portreg:=14; writevdc; (* all addresses at start of ram *) portreg:=15; writevdc; portreg:=18; writevdc; portreg:=19; writevdc; end; procedure setbitmap; (* put a 1 in bit 7, reg 25 for bitmap *) begin (* version 7a 8563 chip - value is 128 *) portreg:=25; (* versions 8 & 9 chips - value is 135 *) regbyte:=135; (* -otherwise horiz scroll is affected *) writevdc; end; procedure colormap; begin portreg:=26; regbyte:=144; (* good value for monochrome *) writevdc; (* go for self on color *) end; procedure fillmap(dumbyte:byte); begin zeroram; portreg:=31; regbyte:=dumbyte; for lrow:=1 to 200 do begin for lcol :=1 to 80 do writevdc; end; end; procedure setmask; (* set correspondence between remainder *) var l:integer; (* after (div 8) and position in byte *) begin m[7]:=1; for l:=6 downto 0 do m[l]:=2*m[l+1]; end; procedure ramaddr; (* set pointer to desired 8563 chip ram byte *) var hybyte,lobyte:byte; hyval,loval:integer; begin hyval:=hi(z); (* get hi & lo bytes of 16 bit int *) loval:=lo(z); hybyte:=ord(chr(hyval)); (* convert to byte *) lobyte:=ord(chr(loval)); portreg:=18; (* regs 18,19 pair is pointer to chip ram *) regbyte:=hybyte; writevdc; portreg:=19; regbyte:=lobyte; writevdc; end; procedure plotvdc(mapcol,maprow:integer); var (* plot a dot in vdc memory *) bytenr,leftbit,lmask:integer; savebyte:byte; begin bytenr:=maprow*80 + mapcol div 8; leftbit := mapcol mod 8; lmask := m[leftbit]; ramaddr(bytenr); portreg := 31; readvdc; savebyte := regbyte or lmask; ramaddr(bytenr); portreg := 31; regbyte := savebyte; writevdc; end; (* =================== demo-plotting example ======================= *) begin Save_Char; writeln; writeln('******** cp/m hires graphics example for the c-128 ********'); WriteLn('Hit Return to Continue'); readln(x); setbitmap; (* put 8563 in the bitmap mode *) colormap; (* set bitmap color *) fillmap(0); (* clear the screen *) setmask; (* compute pixel mask array m *) (* plot 1/2 of a parabola *) for x := 0 to 639 do begin ytemp := x*1.0; ytemp := ytemp*ytemp*199.0/(639.0*639.0); y := trunc(ytemp); plotvdc(x,y); end; Delay(500); (* hold the plot on screen *) writeLn(^G); PortReg := 25; regbyte := 71; (* Version 7a regbyte = 64 *) writevdc; (* Version 8 & 9 regbyte = 71 *) WriteLn(^Z); WriteLn(^[^[^['12'); WriteLn('Please wait while the character set is reloaded into VDC ram'); WriteLn; WriteLn('This will take a few seconds to do'); Load_Char; WriteLn('All Done'); end.