home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
MBUG
/
MBUG094.ARC
/
HIRES4.I
< prev
next >
Wrap
Text File
|
1979-12-31
|
11KB
|
355 lines
{ Inline machine-code version of HiRes and HiDot
with comments/mnemonics (See Hires5a.i .... Hires5c.i)
Written by Daniel Prager 1986 }
{This code is an adaption of the HiDot function created by Daniel Prager 1986
to use the full Premium Graphics in Hires mode
modification by R.K.Hallworth, Donvale Christian School, April 1987}
{ The video driver ( procedure VDUOUT ) allows a complete mix of underline
(turn on with ESC '[' turn off with ESC ']' )
and highlighting
(turn on with ESC ')' turn off with ESC '(' )
see Hires4.pas for an sample of use }
Type
PCGs=Array [0..15] of byte;
Var ConOutAdr,CursPos :integer; {store location of bios VDU driver}
VDUstatus :array [1..6] of byte;{ESC,CURSPOS,LINE,UNDERLINE,INVERSE,EOL}
Scratch : PCGs; {Scratch for desired PCG}
VideoWidth:Integer;
Const
UsedPCGs=0;
procedure StorePCG(Ch:Char);
begin
inline($3E/ $01/$D3/$0B/$3A/CH/$6F/$26/0/$29/$29/$29/$29/
$11/$F000/$19/$11/SCRATCH/$01/16/0/$ED/$B0/$AF/
$D3/ $0B)
end;
Procedure ClearHiRes;
Var RAMBank,PCGByte:integer;
Begin
VDUstatus[1]:=0;
VDUstatus[2]:=0;
VDUstatus[6]:=0;
port[28]:=144;
For PCGByte:=0 to $7FF do Mem[$F000+PCGByte]:=0;
port[28]:=128;
For PCGByte:=0 to $7FF do Mem[$F000+PCGByte]:=32
end;
Procedure VduOut(Ch:Char);
Type
PCGs=Array [0..15] of byte;
Var Bt,count,PCGNo,PCGBank:byte;
PCGPos:Integer;
Scratch : PCGs; {Scratch for desired PCG}
Lines:Byte;
Const
TickArray:PCGs=(0,2,4,4,4,8,8,$48,$30,$10,0,0,0,0,0,0);
procedure StorePCG(Ch:Char);
begin
inline($3E/ $01/$D3/$0B/$3A/CH/$6F/$26/0/$29/$29/$29/$29/
$11/$F000/$19/$11/SCRATCH/$01/16/0/$ED/$B0/$AF/
$D3/ $0B)
end;
Procedure Invert;
begin
inline($06/16/$21/SCRATCH/$7E/$2F/$77/$23/$10/$FA)
end;
Procedure ScrollUp(Width:Integer);
Var LineWidth:Integer;
begin
LineWidth:=Width;
inline($18/14/$11/$F000/$2A/linewidth/$26/$F0/$01/1000/$ED/$B0/
$C9/$3E/$00/$D3/$0B/$CD/*-19/$3E/144/$D3/28/
$CD/*-26/$3E/128/$D3/28)
end;
Procedure SaveScratch;
begin
PCGBank:= (CursPos-$F000) shr 7;
PCGNo := (CursPos-$F000) and $7F;
Port[28]:=144;
Mem[CursPos]:=PCGBank;
Port[28]:=128+PCGBank;
PCGPos:=(PCGNo shl 4)+$F800;
Move(Scratch,Mem[PCGPos],16);
Port[28]:=128;
Mem[CursPos]:=PCGNo+128
end;
begin
Inline($F3/$F5/$C5/$D5/$E5/$DD/$E5/$FD/$E5); {SAVE REGISTERS ON STACK}
if VduStatus[1]<>1 then
begin
Case Ch of
' '..'}' :begin
CursPos:=CursPos+1;
If hi(CursPos)>=$F8 then CursPos:=$F7FF;
If (VduStatus[4]=1) or (VduStatus[5]=1)
then
begin
StorePCG(Ch);
If VduStatus[4]=1 then
begin
if VideoWidth=64
then Scratch[13]:=255 {underline}
else Scratch[9] :=255 {underline}
end;
if VDUstatus[5]=1 then invert;
SaveScratch;
end
else
begin
Port[28]:=144;
Mem[CursPos]:=0;
Port[28]:=128;
Mem[CursPos]:=Ord(Ch)
end;
Port[28]:=128;
end;
#13 :Begin
If VduStatus[6]=1 then CursPos:=Pred(CursPos);
CursPos:=(((CursPos+1) - $F000) div VideoWidth)*VideoWidth + $EFFF;
VduStatus[6]:=2;
end;
#10 :Begin
If VduStatus[6]=0 then VDUStatus[6]:=2;
CursPos:=CursPos+VideoWidth;
end;
#8,#127 :begin
If CursPos>=$F000 then
begin
Port[28]:=144;
Mem[CursPos]:=0;
Port[28]:=128;
Mem[CursPos]:=32;
CursPos:=CursPos-1
end;
end;
#128 :begin
CursPos:=Succ(CursPos);
Scratch:=TickArray;
SaveScratch;
end;
^G :Begin
ConOutPtr:=ConOutAdr;
Write(^G); {Beep}
ConOutPtr:=Addr(VduOut);
end;
^Z :begin
CursPos:=$F000-1;
ClearHiRes
end;
#27 :VDUstatus[1]:=1 {esc}
end;
end
else
Case VDUstatus[2] of
1:begin
VDUstatus[3]:=(Ord(Ch)-32) and $1f;
VDUstatus[2]:=2;
end;
2:begin
CursPos:=$F000-1+(VDUstatus[3]*VideoWidth)+((Ord(Ch)-32) and 63);
For Count:= 1 to 3 do VDUstatus[count]:=0
end
else
begin
Case Ch of
'=' :VDUstatus[2]:=1;
'[' :VduStatus[4]:=1;{UNDERLINE ON}
']' :VduStatus[4]:=0;
')' :VduStatus[5]:=1;{Highlight on}
'(' :VduStatus[5]:=0;
end;
If VduStatus[2]=0 then VDUstatus[1]:=0
end
end;
If VideoWidth=40 then lines:=24
else lines:=16;
If CursPos>=$F000+VideoWidth*Lines
then begin
CursPos:=Curspos-VideoWidth;
ScrollUp(VideoWidth);
end;
If VDUStatus[6]=2
then VDUStatus[6]:=0 {Cr sent (Start of new line)}
else VDUStatus[6]:=1;{Cr not sent at EOL}
Inline($FD/$E1/$DD/$E1/$E1/$D1/$C1/$F1/$FB); {RESTORE REGISTERS FROM STACK}
end;
function HiDot (A, B, F : Integer) : Boolean;
{Modified by R.K.Hallworth of Donvale Christian School for the
Premium using 64x16 screen
Function to alter a pixel anywhere on the screen. Returns TRUE if
successful and FALSE if there is an illegal parameter or if all PCGs have
been used. HiRes must be called prior to the first call to HiDot }
var
Scratch : array [0..15] of Byte; {Scratch for desired PCG}
Temp,Bank, {Temporary storage}
Memory,
Video : Integer; {Address in screen RAM of PCG to be
changed}
X,Y :Integer;
PCGAddr :Integer; {address of PCG}
Line, {Line of PCG to be changed}
PCG,PCGByte, {PCG at Mem[Video]}
Mask : Byte; {Mask to be applied to Scratch[Line]
to alter the correct dot}
H : Boolean; {Result of HiDot}
Type
MaskArray=array[0..7] of byte;
const
Masks:MaskArray=(1,2,4,8,16,32,64,128);
begin
X:=A;
Y:=B;
{DI}
Inline($F3/$F5/$C5/$D5/$E5/$DD/$E5/$FD/$E5); {SAVE REGISTERS ON STACK}
Inline($A7/$ED/$5B/X/$21/511/$ED/$52/$DA/*+25/$ED/$5B/Y/$21/>255/
$ED/$52/$DA/*+13/$3A/F/$D6/3/$D2/*+5/$C3/*+6/$97/$C3/*+237/
$2A/X/$7D/$0E/7/$A1/$A9/$E5/$5F/$16/0/$21/MASKS/$19/$7E/$E1/
$32/Mask/$06/$03/$CB/$3D/$CB/$3C/$D2/*+4/$CB/$FD/$10/$F5/$E5/
$2A/Y/$3E/15/$A5/$67/$3E/15/$94/$32/Line/$2A/Y/$7D/$16/240/$A2/
$AA/$6F/$06/0/$29/$29/$D1/$19/$E5/$11/$F000/$19/$22/Video/$97/
$D3/11/$7E/$32/PCG/$6F/$D6/127/$FA/*+21/$F1/$CB/$BD/$E5/$3E/144/
$D3/28/$2A/VIDEO/$7E/$C6/$80/$D3/$1C/$C3/*+39/$D1/$D5/$CB/$22/
$CB/$7B/$CA/*+4/$CB/$C2/$3E/144/$D3/28/$2A/VIDEO/$7A/$77/$C6/$80/
$D3/$1C/$E1/$7D/$E6/127/$6F/$E5/$7D/$C6/128/$2A/Video/$77/$E1/
$26/0/$29/$29/$29/$29/$11/$F800/$19/$22/PCGAddr/$3A/PCG/$6F/
$60/$D6/127/$F2/*+22/$3E/1/$D3/11/$29/$29/$29/$29/$11/$F000/$19/
$ED/$5B/PCGAddr/$0E/16/$ED/$B0/$97/$D3/11/$2A/PCGAddr/$ED/$5B/Line/
$16/0/$19/$46/$3A/Mask/$4F/$3A/F/$FE/0/$CA/*+12/$FE/1/$CA/*+13/
$78/$A9/$C3/*+14/$79/$2F/$A0/$C3/*+4/$78/$B1/$B8/$CA/*+3/$77/
$3E/1/$32/H/$3E/128/$D3/28);
{EI}
Inline($FD/$E1/$DD/$E1/$E1/$D1/$C1/$F1/$FB); {RESTORE REGISTERS FROM STACK}
HiDot := H
end;
Procedure SetVideo(Width:integer);
Var Count:byte;
procedure NORMAL;
{ Procedure to restore Inverse characters
to the PCG.
This procedure is derived from the disk
ROM routine at E02AH, which fills the
PCG with inverse characters of the
current font type.
}
begin { procedure normal }
inline($3E/$01/$D3/$0B/$21/$F000/$11/$F800/$7E/$2F/$12/
$23/$13/$CB/$5C/$28/$F7/$AF/$D3/$0B)
end; {procedure normal}
Procedure vdu_init;
begin
Inline($3E/0/$Db/9); {RESET VIDEO CLOCK SPEED}
inline ($21/*+52/$C5/$E5/6/$10/$78/$3D/$D3/$0C/$7E/$D3/
$0D/$2B/$10/$F6/6/$4B/$CD/*+5/$E1/$C1/$C9/
$E5/$21/$7A/0/$2B/$7C/$B5/$20/$FB/$10/$F6/$E1/$C9/
{Crtc Initialisation data for 80x24 screen}
{Data=>}$6b/$50/$58/$37/$1b/$05/$18/$1a/$48/$0a/$2a/$0a/$20/$00/$00/$00);
end;
begin {Set Video}
ClrScr;
CursPos:=$F000-1;
VideoWidth:=Width;
ConOutPtr:=Addr(VduOut); {Set to internal Vdu Driver}
For count:=1 to 6 do VDUstatus[count]:=0;
Case VideoWidth of
40:begin
Inline($3E/1/$DB/9);{HALVES VIDEO CLOCK SPEED}
inline ($21/*+52/$C5/$E5/6/$10/$78/$3D/$D3/$0C/$7E/$D3/
$0D/$2B/$10/$F6/6/$4B/$CD/*+5/$E1/$C1/$C9/
$E5/$21/$7A/0/$2B/$7C/$B5/$20/$FB/$10/$F6/$E1/$C9/
{Crtc Initialisation data for 40x24 screen}
{Data=>}$35/$28/$2D/$24/$1b/$05/$19/$1a/$48/$0a/$2a/$0a/$20/$00/$00/$00);
{Normal;}
end;
64:begin
Inline($3E/0/$Db/9); {RESET VIDEO CLOCK SPEED}
inline ($21/*+52/$C5/$E5/6/$10/$78/$3D/$D3/$0C/$7E/$D3/
$0D/$2B/$10/$F6/6/$4B/$CD/*+5/$E1/$C1/$C9/
$E5/$21/$7A/0/$2B/$7C/$B5/$20/$FB/$10/$F6/$E1/$C9/
107/64/81/55/18/9/$10/17/$48/$0F/$2F/$0F/
0/0/0/0) {64*16}
end;
80:begin
Vdu_init; {80*24 screen}
ConOutPtr:=ConOutAdr; {Set to standard video driver}
ClearHiRes;
normal; {Sets normal inverse characters}
end;
end;
ClrScr;
end;
Procedure Hires;
begin
SetVideo(64);
end;
Procedure SaveStandardVideoAddr;
begin
ConOutAdr:=ConOutPtr;
end;