(* GRAPHIC ROUTINES by Ken Nist *) type BitMap=array[0..5759] of integer; LongString=string[255]; Cmap=array[0..31] of byte; Smap=array[0..255] of byte; var HighResolution,VectorMode,drawing,DualMonitor: boolean; Gmode,Yfix,GDCpat,GDCmult,GDCfg,GDCbg,GDCalu,GDCps: byte; CharHPitch,CharVPitch,TopMargin,BottomMargin,LeftMargin,RightMargin: byte; Temp1,Temp2,Temp3,Gtemp,maxX: integer; const maxY: integer=239; procedure GraphicsOn; begin Gmode:=Gmode or $80; port[$53]:=$BF; { enable G.O. } port[$51]:=Gmode; if not DualMonitor then begin port[$57]:=$0D; port[$0A]:=$87 end end; { disable VT102 } procedure GraphicsOff; begin Gmode:=Gmode and $7F; { disable G.O. } port[$53]:=$BF; port[$51]:=Gmode; port[$0A]:=$83 end; { enable VT102 } procedure GPort (parm:LongString); var PP,QQ,RR,SS: integer; begin QQ:=length(parm); PP:=1; while PP15 then RR:=RR-7; SS:=ord(parm[PP+2])-48; if SS>15 then SS:=SS-7; port[ord(parm[PP])+32]:=(RR shl 4)+SS; PP:=PP+3 end end; procedure Gw56(word:integer); { port[$56]:=lo(word); port[$56]:=hi(word) } begin inline($8B/$86/word/$E6/$56/$8A/$C4/$E6/$56) end; procedure WaitForGDCNotBusy; begin inline($E4/$56/$A8/$02/$74/$0B/$B9/$00/$80/$E4/$56/$A8/$02/$74/$02/$E2/ $F8/$B0/$0D/$E6/$57/$E4/$56/$A8/$02/$74/$0B/$B9/$00/$80/$E4/$56/ $A8/$02/$75/$02/$E2/$F8/$B8/$0D/$04/$E6/$57/$B9/$00/$80/$E4/$56/ $84/$E0/$75/$02/$E2/$F8); { for QQ:=0 to $8000 do if (port[$56] and $02)=0 then goto G1; G1: port[$57]:=$4A; for QQ:=0 to $8000 do if (port[$56] and $02)=0 then goto G2; G2: for QQ:=0 to $8000 do if (port[$56] and $04)=4 then goto G3; G3:}end; procedure WaitForGDCIdle; label G4; var QQ: integer; begin WaitForGDCNotBusy; if not drawing then goto G4; for QQ:=0 to $8000 do if (port[$56] and $0F)=4 then goto G4; G4: end; procedure Pattern (pat,mult:integer); begin GDCpat:=pat; GDCmult:=mult; WaitForGDCIdle; port[$53]:=$FD; port[$51]:=16-GDCmult; port[$53]:=$FB; port[$51]:=GDCpat end; procedure LoadColorMap (var map: Cmap); begin WaitForGDCIdle; while (port[$56] and $20)<>0 do;{ wait for beginning of vertical retrace } inline($FA); while (port[$56] and $20)=0 do; inline($8B/$B6/map/$B0/$DF/$E6/$53/$B9/$20/ $00/$AC/$F6/$D0/$E6/$51/$E2/$F9/$FB) end; procedure LoadScrollMap (var map: Smap); begin WaitForGDCIdle; { This routine is extremely timing sensitive.} Gtemp:=Gmode and $DF; { It must start and end in the same vertical } inline($FA); { retrace period, and barely does so. } while (port[$56] and $20)<>0 do; inline($B9/$40/$1F/$E4/$56/$A8/$20/$75/$02/$E2/$F8/ $B0/$BF/$E6/$53/$A0/Gtemp/$E6/$51/ $B0/$7F/$E6/$53/$B2/$51/$32/$F6/ $8B/$B6/map/$B9/$10/$00/ $AD/$EE/$8A/$C4/$EE/$AD/$EE/$8A/$C4/$EE/ $AD/$EE/$8A/$C4/$EE/$AD/$EE/$8A/$C4/$EE/ $AD/$EE/$8A/$C4/$EE/$AD/$EE/$8A/$C4/$EE/ $AD/$EE/$8A/$C4/$EE/$AD/$EE/$8A/$C4/$EE/ $E2/$D6/$B0/$BF/$E6/$53/$A0/Gmode/$E6/$51/$FB) end; procedure Color (FG:integer); begin GDCfg:=FG; Gtemp:=(GDCfg shl 4)+(GDCbg and 15); inline($B0/$F7/$E6/$53/$A0/Gtemp/$E6/$51) end; procedure BackgroundColor (BG:integer); begin GDCbg:=BG; Gtemp:=(GDCfg shl 4)+(GDCbg and 15); inline($B0/$F7/$E6/$53/$A0/Gtemp/$E6/$51) end; procedure Operation (ALU,PlaneSelect: integer); begin GDCalu:=ALU; GDCps:=PlaneSelect; WaitForGDCIdle; port[$53]:=$EF; port[$51]:=(GDCalu shl 4)+(GDCps and 15 xor 15); end; procedure Ginitialize; var PP,QQ: integer; begin DualMonitor:=false; ErrorPtr:=ofs(GraphicsOff); { <--- This will disable graphics on a run } if HighResolution then begin { statement if it gets a compile error.} Gmode:=$31; maxX:=799; Yfix:=6; GPort('7003BF1316126306646086036036F0640747640') end else begin Gmode:=$30; maxX:=383; Yfix:=5; GPort('7003BF1306126166616046026036F0640747620') end; WaitForGDCNotBusy; GPort('76B7466007227706006006FF60F7786FF6FF74B60060060076F06F'); Pattern(255,1); Color(15); BackgroundColor(0); Operation(0,15); GPort('400500'); WaitForGDCNotBusy; GPort('3FE100'); for QQ:=0 to 15 do port[$52]:=$FF; WaitForGDCNotBusy; GPort('3FE10074960060074A6FF6FF74C6026FF63F7226FF6FF70D'); WaitForGDCIdle; end; procedure WriteRectangle(loX,hiX,loY,hiY: integer; var area: BitMap); var PP,QQ,RR,SS,TT,ZZ,ZZ1,ZZ2,mask: integer; begin for PP:=(loX shr 4) to (hiX shr 4) do begin TT:=PP shl 4; ZZ := swap(PP) - TT; mask:=$FFFF; if TT+15>hiX then mask:=mask shl (TT+15-hiX); if TT hiY then SS := hiY+1; ZZ1 := ZZ+RR; ZZ2 := ZZ+SS-1; inline($E4/$56/$A8/$02/$74/$0B/$B9/$00/$80/$E4/$56/$A8/$02/$74/ $02/$E2/$F8/$B0/$0D/$E6/$57/$E4/$56/$A8/$02/$74/$0B/$B9/ $00/$80/$E4/$56/$A8/$02/$75/$02/$E2/$F8/$B8/$0D/$04/$E6/ $57/$B9/$00/$80/$E4/$56/$84/$E0/$75/$02/$E2/$F8); for QQ:=ZZ1 to ZZ2 do begin {$R-} Gtemp:= not area[QQ]; {$R+} inline($A1/Gtemp/$E6/$52/$8A/$C4/$E6/$52); end; if SS = hiY+1 then for QQ:=hiy+1 to rr+7 do inline($B0/$00/$E6/$52/$E6/$52); Temp1:=PP+(RR shl Yfix); Temp2 := not mask; Temp3 := SS-RR-1; inline($B0/$49/$E6/$57/$A1/Temp1/$E6/$56/$8A/$C4/$E6/$56/$A1/ Temp2/$E6/$54/$8A/$C4/$E6/$55/$B0/$4C/$E6/$57/$B0/$00/ $E6/$56/$A1/Temp3/$E6/$56/$8A/$C4/$E6/$56/$B0/$22/$E6/ $57/$B0/$FF/$E6/$56/$E6/$56); end; end; end; procedure WriteRectangleOneByte (loX,loY,hiY: integer; var area: BitMap; mask,zz: integer); var QQ,RR,SS,ZZ1,ZZ2: integer; begin SS:=loY; while SS<=hiY do begin RR:=SS; SS:=SS+8; if SS > hiY then SS := hiY+1; ZZ1 := ZZ+RR; ZZ2 := ZZ+SS-1; inline($E4/$56/$A8/$02/$74/$0B/$B9/$00/$80/$E4/$56/$A8/$02/$74/ $02/$E2/$F8/$B0/$0D/$E6/$57/$E4/$56/$A8/$02/$74/$0B/$B9/ $00/$80/$E4/$56/$A8/$02/$75/$02/$E2/$F8/$B8/$0D/$04/$E6/ $57/$B9/$00/$80/$E4/$56/$84/$E0/$75/$02/$E2/$F8); for QQ:=ZZ1 to ZZ2 do begin {$R-} Gtemp:= not area[QQ]; {$R+} inline($A1/Gtemp/$E6/$52/$8A/$C4/$E6/$52); end; if SS = hiY+1 then for QQ:=hiy+1 to rr+7 do inline($B0/$00/$E6/$52/$E6/$52); Temp1:=(loX shr 4)+(RR shl Yfix); Temp2 := mask; Temp3 := SS-RR-1; inline($B0/$49/$E6/$57/$A1/Temp1/$E6/$56/$8A/$C4/$E6/$56/$A1/ Temp2/$E6/$54/$8A/$C4/$E6/$55/$B0/$4C/$E6/$57/$B0/$00/ $E6/$56/$A1/Temp3/$E6/$56/$8A/$C4/$E6/$56/$B0/$22/$E6/ $57/$B0/$FF/$E6/$56/$E6/$56); end; end; procedure WriteRectangleTwoBytes (loX,loY,hiY: integer; var area: BitMap; mask1,mask2,zz: integer); var QQ,RR,SS,ZZ1,ZZ2: integer; begin SS:=loY; while SS<=hiY do begin RR:=SS; SS:=SS+8; if SS > hiY then SS := hiY+1; ZZ1 := ZZ+RR; ZZ2 := ZZ+SS-1; inline($E4/$56/$A8/$02/$74/$0B/$B9/$00/$80/$E4/$56/$A8/$02/$74/ $02/$E2/$F8/$B0/$0D/$E6/$57/$E4/$56/$A8/$02/$74/$0B/$B9/ $00/$80/$E4/$56/$A8/$02/$75/$02/$E2/$F8/$B8/$0D/$04/$E6/ $57/$B9/$00/$80/$E4/$56/$84/$E0/$75/$02/$E2/$F8); for QQ:=ZZ1 to ZZ2 do begin {$R-} Gtemp:= not area[QQ]; {$R+} inline($A1/Gtemp/$E6/$52/$8A/$C4/$E6/$52); end; if SS = hiY+1 then for QQ:=hiy+1 to rr+7 do inline($B0/$00/$E6/$52/$E6/$52); Temp1:=(loX shr 4)+(RR shl Yfix); Temp2 := mask1; Temp3 := SS-RR-1; inline($B0/$49/$E6/$57/$A1/Temp1/$E6/$56/$8A/$C4/$E6/$56/$A1/ Temp2/$E6/$54/$8A/$C4/$E6/$55/$B0/$4C/$E6/$57/$B0/$00/ $E6/$56/$A1/Temp3/$E6/$56/$8A/$C4/$E6/$56/$B0/$22/$E6/ $57/$B0/$FF/$E6/$56/$E6/$56); end; SS:=loY; while SS<=hiY do begin RR:=SS; SS:=SS+8; if SS > hiY then SS := hiY+1; ZZ1 := ZZ+RR+240; ZZ2 := ZZ+SS+239; inline($E4/$56/$A8/$02/$74/$0B/$B9/$00/$80/$E4/$56/$A8/$02/$74/ $02/$E2/$F8/$B0/$0D/$E6/$57/$E4/$56/$A8/$02/$74/$0B/$B9/ $00/$80/$E4/$56/$A8/$02/$75/$02/$E2/$F8/$B8/$0D/$04/$E6/ $57/$B9/$00/$80/$E4/$56/$84/$E0/$75/$02/$E2/$F8); for QQ:=ZZ1 to ZZ2 do begin {$R-} Gtemp:= area[QQ]; {$R+} inline($A1/Gtemp/$34/$FF/$E6/$52/$8A/$C4/$34/$FF/$E6/$52); end; if SS = hiY+1 then for QQ:=hiy+1 to rr+7 do inline($B0/$00/$E6/$52/$E6/$52); Temp1:=(loX shr 4)+(RR shl Yfix)+1; Temp2 := mask2; Temp3 := SS-RR-1; inline($B0/$49/$E6/$57/$A1/Temp1/$E6/$56/$8A/$C4/$E6/$56/$A1/ Temp2/$E6/$54/$8A/$C4/$E6/$55/$B0/$4C/$E6/$57/$B0/$00/ $E6/$56/$A1/Temp3/$E6/$56/$8A/$C4/$E6/$56/$B0/$22/$E6/ $57/$B0/$FF/$E6/$56/$E6/$56); end; end;