{###################################} {# Copyright (C) 1987 #} {# Lattice Logic Limited #} {# 9, Wemyss Place #} {# Edinburgh EH3 6DH #} {# Scotland #} {# #} {# All rights reserved #} {###################################} ! This module contains the support routines for the scrdrive package and ! edwin device driver for the definicon board's interface with the famous ! GEM package from Imp include DOS end of list from Imp include ASCII end of list from Imp include LogNames end of list from Imp include MCode end of list from Edwin include Consts end of list from Edwin include GemConst end of list from LL include Common end of list string(255) function Env String(string(31) Name, string(255) Variable) string(255) Value Value = Translate(Name."_".Variable) result = Value if Value # Name."_".Variable Value = Translate("LL_".Variable) result = Value if Value # "LL_".Variable result = "" end integer function Env Integer(string(31) Name, string(255) Variable, integer Default) on event * start result = Default finish Variable = Env String(Name, Variable) result = Default if Variable = "" result = S To I(Variable) end integer function Env Switch(string(31) Name, string(255) Variable, integer Exist, Not Exist) Variable = Env String(Name, Variable) result = Exist if Variable # "" result = Not Exist end {##############################################} {# #} {# Basic GEM Driver #} {# #} {##############################################} external string(31) spec Fname constant integer Screen Device = 1 constant integer Metafile Device = 31 own integer Current Device constant integer Max Vertices = 127 constant integer Max Ints = 128 record format Gem Parm Fm(integer Contrl, Intin, Ptsin, Intout, Ptsout) record format Gem Control Fm(short array C(0:11) or short Opcode, Ptsin Len, Ptsout Len, Intin Len, Intout Len, Sub Function, Handle) record format Gem Integer Fm(short array X(0: Max Ints-1)) record format Gem Vertice Fm(short array X(0: Max Vertices*2-1)) record format Gem Fm(record(Gem Parm Fm) Parm, record(Gem Control Fm) Contrl, short array Parms(0: 511), record(Gem Vertice Fm) Ptsin, Ptsout, record(Gem Integer Fm) Intin, Intout) own record(Gem Fm) Gem = 0 own integer Gem Buffer Size = 0 own integer Gem Addr = 0, Gem Log, MFDB Log, MFDB Addr own short name Opcode, Ptsin Len, Ptsout Len, Intin Len, Intout Len own short array name Ptsin, Ptsout, Intin, Intout, PA own record(Gem Parm Fm) name PB ! ! Keyboard type ahead held in a sort of circular buffer ! ! Nothing to read if read ptr=add ptr ! If buffer full add ptr will push read ptr on one ! own integer escape char external byte integer spec int flag alias "IMP___INT_FLAG" constant integer Max Type Ahead = 63 {must be a power of two-1} own byte array Buffer(0: Max Type Ahead) own integer add ptr=0 own integer read ptr=0 routine Advance(integer name Ptr) Ptr = (Ptr+1) & Max Type Ahead end routine Add To Buffer(byte Char) Buffer(Add Ptr) = Char Advance(Add Ptr) Advance(Read Ptr) if Read Ptr = Add Ptr end integer function Top Of Buffer result = -1 if Read Ptr = Add Ptr integer I = Buffer(Read Ptr) Advance(Read Ptr) result=i end routine Clear Buffer Read Ptr = Add Ptr end external routine do check alias "G_CK_INT" constant integer zero flag=64 record(Int Regs Fm) Regs Regs=0 Regs_Ah<-Dos Fn Direct Console IO Regs_Dl<-16_FF {wanting input} Int86(Dos Int Function Request,Regs) if regs_flags&zero flag=0 start if regs_al=escape char start int flag=1 Clear Buffer else Add To Buffer(regs_al) finish finish end routine check interrupt constant integer max cycle=50 own integer cycle=max cycle return if current device#screen device ! ! test for attempted interrupt every max cycles calls of the routine ! cycle=cycle-1 return if cycle>0 cycle=max cycle do check end predicate Interested In Return Values(integer Opcode) false if 2<=Opcode<=11 or Opcode=114 or 122<=Opcode<=123 true end routine copy arrays {load parameters into gem parameter block} integer j,p=ptsin len*2 PB_Intin=PB_ptsin+p*2 {2*2 bytes per vertice parameter} PB_ptsout=PB_intin+intin len*2 {2 bytes per integer parameter} PB_intout=PB_ptsout+40 {+max ptsout len*4} pa(j)=ptsin(j) for j=0,1,p-1 pa(p+j)=intin(j) for j=0,1,intin len-1 gem buffer size=size of(PB)+size of(gem_contrl)+p*2+intin len*2 gem buffer size=gem buffer size+130 if interested in return values(opcode) end {+max ptsout len*4+max intout len*2} routine copy back arrays {copy gem P.B. back into data structure} integer i,j i=intin len+ptsin len*2 ptsout(j)=pa(i+j) for j=0,1,ptsout len*2-1 i=intin len+ptsin len*2+20 {+max ptsout*2} intout(j)=pa(i+j) for j=0,1,intout len-1 end routine Initialise Gem own byte array MFDB(1:20)=0(*) return if Gem Addr # 0 Opcode == Gem_Contrl_Opcode Ptsin == Gem_Ptsin_X Ptsout == Gem_Ptsout_X Intin == Gem_Intin_X Intout == Gem_Intout_X Ptsin Len == Gem_Contrl_Ptsin Len Ptsout Len == Gem_Contrl_Ptsout Len Intin Len == Gem_Contrl_Intin Len Intout Len == Gem_Contrl_Intout Len PA == Gem_Parms PB == Gem_Parm Gem Log = Mal 86(Size Of(Gem) + 20) {Allocate memory for GEM parameters} Gem Addr = (Gem Log>>12) & 16_FFFF0 + (Gem Log & 16_FFFF) MFDB Log = Gem Log + Size Of(Gem) {The last 20 bytes holds a MFDB} MFDB Addr = Gem Addr + Size Of(Gem) {for scrolling raster operations} To86(MFDB(1), MFDB addr, 20) {MFDB is zero for physical dev} PB_Contrl = Gem Log + Addr(Gem_Contrl) - Addr(Gem) PB_Ptsin = Gem Log + Addr(Gem_Parms) - Addr(Gem) Escape Char = Env Integer(Fname, "ESCAPE_CHAR", 'Y'-'A'+1) Int Flag = 0 end own integer mouse addr own byte retf=16_cb,original byte=16_55 routine Do Gem record(Int Regs Fm) Regs=0 Regs_Ds<-Gem Log>>16 Regs_Dx<-Gem Log&16_FFFF Regs_Cx<-16_0473 Copy Arrays to86(retf,mouse addr,1) unless interested in return values(opcode) To86(Byte(Addr(Gem)),Gem Addr,Gem buffer size) Int86(16_EF,Regs) if interested in return values(opcode) start Fr86(Gem Addr,Byte(Addr(Gem)),Gem buffer size) copy back arrays else to86(original byte,mouse addr,1) finish Intin Len=0 Ptsin Len=0 check interrupt end ! ! set up the cursor so that it is displayed as much as possible ! routine cursor status(integer onoff) own integer status=hide cursor return if status=onoff status=onoff opcode=status ptsin len=0 intin len=1 intin(0)=1 do gem end routine gem command(short opc) ! make sure that the cursor is off if something is being drawn, ! otherwise it doesn't matter ! cursor status(hide cursor) unless interested in return values(opc) Opcode=opc end routine Add Ptsin(integer I,J) integer P=Ptsin Len*2 Ptsin(P)<-I Ptsin(P+1)<-J Ptsin Len=Ptsin Len+1 end routine add ptsin array(integer pts, integer array name xs,ys) integer i,p=Ptsin Len*2 for i=1,1,pts cycle ptsin(p)<-xs(i) ptsin(p+1)<-ys(i) p=p+2 repeat ptsin len=ptsin len+pts end routine Add Intin(integer I) Intin(Intin Len)<-I Intin Len=Intin Len+1 end routine Add String(byte name C Str) integer A = Addr(C Str) while Byte(A) # 0 and Intin Len <= Max Ints cycle Intin(Intin Len) = Byte(A) Intin Len = Intin Len+1 A = A+1 repeat end integer function clength(byte name cstr) integer i=0,a=addr(cstr) i=i+1 while byte(a+i)#0 result=i end {##############################################} {# #} {# EDWIN package support #} {# #} {##############################################} constant integer CGA = 200, EGA = 350, VGA = 480 constant integer Meta Width = 3800 {Not what you might expect from the} constant integer Meta Height = 2570 {documentation, but then what's new?} constant integer System Text Face = 1 constant integer Software Text Face = 2 external integer function spec Imp Creat alias "IMP_CREAT" - (string(255) Name, integer Mode) dynamic integer spec Errno alias "errno" constant integer Open Mode Write = 1 own integer Current Text Face own integer Graphics Standard own integer GEM Version ! ! Scrdrive package support. Remember to compile with the correct ! definicon map file ! external integer spec Off Y alias "OffY" external integer Letter X alias "LetterX" external integer Letter Y alias "LetterY" external integer Win X alias "WinX" external integer Win Y alias "WinY" external integer Max X alias "MaxX" external integer Max Y alias "MaxY" external integer Cur X alias "CurX" external integer Cur Y alias "CurY" external integer spec Char X alias "CharX" external integer spec Char Y alias "CharY" external integer Char Fixed alias "CharFixed" constant integer Default = 1, Background = 0 record format Environment Fm(integer array Variable(1:5) or integer Char Size, Line Style, Fill Mode, Colour, Raster Op) own record(Environment Fm) Current, Actual own integer Variable Char Size own integer real colours own integer screen aspect ratio own integer initialised edwin=0 external routine spec Edwin Line Style alias "EDWIN_DD_STYLE"(integer Style) external routine spec Edwin Colour alias "EDWIN_DD_COL"(integer mode) external routine spec Edwin Mode alias "EDWIN_DD_MODE"(integer mode) external routine spec Edwin Fill alias "EDWIN_DD_FILL"(integer mode) external routine spec Edwin Clear alias "EDWIN_DD_CLEAR" own integer Prev Dev, Prev Handle, Prev Mouse Addr, Prev Screen Size own integer Screen File Descriptor, Nul File Descriptor own integer Pts=0 own integer array Line X(0:Max Vertices-1) own integer array Line Y(0:Max Vertices-1) from Edwin include Gem Hatch own integer array Line Map(0:7) = 2_1111111111111111, 2_1100110011001100, 2_1111111110011100, 2_1100000011000000, 2_0001111000011110, 2_1010111111111010, 2_1110011111111100, 2_1110001110001110 constant integer Red Col = 16_00030000 constant integer Blu Col = 16_00000003 constant integer Gre Col = 16_00000300 constant integer Whi Col = 16_00030303 constant integer Bla Col = 16_00000000 constant integer Yel Col = 16_00030300 constant integer Mag Col = 16_00030003 constant integer Cya Col = 16_00000303 external integer array C Map(0:7) = Bla Col, Red Col, Yel Col, Yel Col, Cya Col, Cya Col, Cya Col, Whi Col external integer MonoChrome = 0 , BackGround Col = 0, ForeGround Col = 1, Text Col = 2, HighLight Col = 4 external integer array P map(0:15)=0,1,4,3,2,7,6,5,8,9,10,11,12,13,14,15 own string(127) fill pattern bitmap own integer Fill Type, Fonts, Extents Flag external routine Load Colours integer i for i=0, 1, 7 cycle Gem Command(Set Colour Representation) Add Intin(P Map(i)) Add Intin(333 * ( C Map(PMap(i)) >>16)) Add Intin(333 * (( C Map(PMap(i)) >>8 ) & 16_FF)) Add Intin(333 * ( C Map(PMap(i)) &16_FF)) Do Gem repeat end external routine Read Environment For alias "RD_ENV"(string(31) Name) string(16) Red Map, Green Map, Blue Map string(255) colour integer Map Length, i if Real Colours > 2 start if Name = "WAVE" start ! ! This is a frig to get the highlight col into slot 1 of the colour map. ! The xor function always results in the colour in slot one ! i = C map(PMap(Foregroundcol)) C Map(PMap(Foregroundcol)) = C map(PMap(Highlightcol)) C Map(PMap(Highlightcol)) = i i = foregroundcol foregroundcol = highlightcol highlightcol = i Load Colours else if Name = "EXERT" Load Colours else Backgroundcol = 0 Textcol = 1 Foregroundcol = 1 Highlightcol = 1 Red Map <- Env String(Name, "RED___INTENSITY") Green Map <- Env String(Name, "GREEN_INTENSITY") Blue Map <- Env String(Name, "BLUE__INTENSITY") Map Length = Length(Red Map) Map Length = Length(Green Map) if Length(Green Map) < Map Length Map Length = Length(Blue Map) if Length(Blue Map) < Map Length for i=0, 1, Map Length-1 cycle Gem Command(Set Colour Representation) Add Intin(PMap(i)) Add Intin(333 * (Char No(Red Map, i+1)-'0')) Add Intin(333 * (Char No(Green Map, i+1)-'0')) Add Intin(333 * (Char No(Blue Map, i+1)-'0')) Do Gem repeat finish finish Variable Char Size = Env Switch(Name, "VAR_CHAR_SIZE", 1, 0) Extents Flag = '`'{Env Integer(Name, "EXTENTS_FLAG", '`') Current_Char Size = Env Integer(Name, "CHAR_HEIGHT", 30) Current_Char Size = (Current_Char Size*72) // (25400//Screen Aspect Ratio) Current Text Face = Env Switch(Name, "FIXED_FONT", System Text Face, Software Text Face) Current Text Face = System Text Face if Fonts = 0 Gem Command(Set Text Face) Add Intin(Current Text Face) Do Gem end external routine Edwin Initialise alias "EDWIN_DD_INIT"- (integer name Max X, Max Y, integer Dev) record(Int Regs Fm) Regs=0 routine Open Screen constant integer array meta xl(1:2)=660,520 constant integer array meta yl(1:2)=32410,32630 constant integer array meta xh(1:2)=10060,4550 constant integer array meta yh(1:2)=26590,30100 short Mouse Segment, Mouse Offset integer i Actual_Variable(i) = -1 for i=1, 1, 5 Gem Command(Open Workstation) Add Intin(Current Device) Add Intin(1) {Line type} Add Intin(0) {Polyline colour} Add Intin(1) {Marker type} Add Intin(0) {Marker colour} Add Intin(Current Text face) Add Intin(0) {Text colour} Add Intin(2) {fill interior style} Add Intin(8) {fill style index} Add Intin(0) {Fill colour} Add Intin(2) {Raster coords} Do Gem stop if Gem_Contrl_Handle = 0 Max X = Intout(0) Max Y = Intout(1) Win X = Max X Win Y = Max Y Char Fixed = 0 Real Colours = Intout(13) MonoChrome = 1 if Real Colours < 3 Graphics Standard = CGA Graphics Standard = EGA if Max Y >= 300 Graphics Standard = VGA if Max Y >= 480 if GEM Version = 3 start Screen Aspect Ratio = (100*Max Y)//Graphics Standard else if Real Colours > 2 start Screen Aspect Ratio = 100 else Screen Aspect Ratio = 200 finish finish Gem Command(Fill Rectangle) Add Ptsin(0, 0) Add Ptsin(Win X, Win Y) Do Gem Gem Command(Exchange Cursor Change Vector) {Ugly repulsive fix} Do Gem {for the EGA card} Mouse Offset = Gem_Contrl_C(9) {basically prevents} Mouse Segment = Gem_Contrl_C(10) {a mouse interrupt} Gem Command(Exchange Cursor Change Vector) {being serviced while} Gem_Contrl_C(7) = Mouse Offset {a drawing operation} Gem_Contrl_C(8) = Mouse Segment {is being executed.} Do Gem Mouse Addr = Mouse Segment<<4 + Mouse Offset Fr 86(Mouse Addr, Original Byte, 1) Gem Command(Load Fonts) Add Intin(0) Do Gem Fonts = Intout(0) Gem Command(Set Polyline Line Type) Add Intin(7) Do Gem if current device=metafile device start ! ! use an escape command to change the name of the output file ! from the standard gemfile.gem filename to productname.gem ! eg draft.gem or cifview.gem ! gem command(escape) gem_contrl_sub function=100 charno(fname,length(fname)+1)=0 add string(charno(fname,1)) do gem gem command(escape) gem_contrl_sub function=99 add intin(0) add intin(meta width) add intin(meta height) do gem gem command(escape) gem_contrl_sub function=99 add intin(1) add intin(meta xl(prev screen size)) add intin(meta yl(prev screen size)) add intin(meta xh(prev screen size)) add intin(meta yh(prev screen size)) do gem finish end routine Redirect Stdout To NUL own integer Initialised Descriptors = 0 if Initialised Descriptors = 0 start Initialised Descriptors = 1 Nul File Descriptor = Imp Creat("NUL", Open Mode Write) if Nul File Descriptor <= 0 start Select Output(0) Print String("Error opening NUL: is ".I To S(Errno, 0).Snl) stop finish ! ! take note of original screen file handle before it is redirected ! Regs_Ah <- Dos Fn Duplicate a File Handle Regs_Bx <- 1 Int86(Dos Int Function Request, Regs) Screen File Descriptor = Regs_AX finish Regs_Ah <- Dos Fn Force a Duplicate of a Handle Regs_Bx <- Nul File Descriptor Regs_Cx <- 1 Int86(Dos Int Function Request, Regs) end GEM Version = Env Integer("GEM", "VER_NO", 1) if Initialised Edwin # 0 and Dev = 'D' start Max X = Win X Max Y = Win Y return finish if Dev = 'G' start {trying to produce a metafile} ! ! remember previous values ! Prev Screen Size = Screen Aspect Ratio Prev Mouse Addr = Mouse Addr Prev Dev = Current device Prev Handle = Gem_Contrl_Handle Current Device = Metafile Device else Current Device = Screen Device ! ! First thing to do is to disable control c interrupts because ! gem doesn't start up again after a control c interrupt ! *MOVD_#31,R0 *SVC ! Redirect Stdout To NUL {so the ^C doesn't get echoed to the screen} ! {and mess up the display} finish Initialised Edwin = 1 Initialise Gem Open Screen Read Environment For(Fname) Current_Raster Op = Replace Mode {This is how EDWIN will be started up} Current_Colour = Default Current_Fill Mode = Outline Current_Line Style = Normal Lines Edwin Clear end predicate Environment Changed true if Current_Char Size # Actual_Char Size true if Current_Colour # Actual_Colour true if Current_Fill Mode # Actual_Fill Mode true if Current_Line Style # Actual_Line Style true if Current_Raster Op # Actual_Raster Op false end routine Implement Environment routine Set Char Size Actual_Char Size = Current_Char Size Gem Command(Set Character Height Points Mode) Add Intin(Current_Char Size) Do Gem Letter X = Pts Out(0) Letter Y = Pts Out(1) Char X = Pts Out(2) Char X = (Char X*4)//5 if GEM Version = 3 and Current Text Face # 1 Char Y = Pts Out(3) Off Y = Char Y-Letter Y+1 Char Fixed = 1 end routine Set Colour integer Colour = Current_Colour Actual_Colour = Current_Colour Colour = 1 if Colour > Real Colours-1 Gem Command(Set Fill Colour Index) Add Intin(PMap(Colour)) Do Gem Gem Command(Set Text Colour Index) Add Intin(PMap(Colour)) Do Gem Gem Command(Set Polyline Colour Index) Add Intin(PMap(Colour)) Do Gem end routine Set Fill Style constant integer Max Mode = 15 integer Mode = Current_Fill Mode integer i Actual_Fill Mode = Current_Fill Mode Mode = 1 if Mode > Max Mode Gem Command(Set Fill Interior Style) if Mode > 1 start Add Intin(4) Do Gem Gem Command(Set User Defined Fill Pattern) Add Intin(Hatch Bitmap(Mode*16 + i)) for i=0, 1, 15 else Add Intin(Mode) finish Do Gem end routine Set Line Style Actual_Line Style = Current_Line Style Gem Command(Set User Defined Line Style Pattern) Add Intin(Line Map(Current_Line Style)) Do Gem end routine Set Write Mode constant integer array Op Map(Replace Mode: Invert Mode) = 1,4,2,3,3 Actual_Raster Op = Current_Raster Op Gem Command(Set Writing Mode) Add Intin(Op Map(Current_Raster Op)) Do Gem end routine Set Perimeter Gem Command(Set Fill Perimeter Visibility) if (Current_Raster Op = Replace Mode or Current_Raster Op = Or Mode) and Current_Colour # 0 start Add Intin(1) else Add Intin(0) finish Do Gem end Set Char Size unless Current_Char Size = Actual_Char Size Set Colour unless Current_Colour = Actual_Colour Set Fill Style unless Current_Fill Mode = Actual_Fill Mode Set Line Style unless Current_Line Style = Actual_Line Style Set Write Mode unless Current_Raster Op = Actual_Raster Op Set Perimeter end routine do line integer i return if Pts = 0 Gem Command(Polyline) Add Ptsin(Line X(i), Line Y(i)) for i=0, 1, Pts-1 Do Gem Pts = 0 end routine Flush Line Do Line Implement Environment if Environment Changed end routine Flush Environment return unless Environment Changed Do Line Implement Environment end external routine Edwin Update alias "EDWIN_DD_UPDATE" Flush Line return if Current Device = Metafile Device Gem Command(Update Workstation) Do Gem end external routine Edwin Rectangle alias "EDWIN_DD_RECT"(integer LX,LY,HX,HY) Flush Environment Gem Command(GDP) Gem_Contrl_Sub Function = Bar Add Ptsin(LX, LY) Add Ptsin(HX, HY) Do Gem end external routine Edwin Clear alias "EDWIN_DD_CLEAR" record(Environment Fm) Copy = Current return if Current Device # Screen Device Flush Line Edwin Fill(Solid) Edwin Mode(Replace Mode) Edwin Colour(Background) Edwin Rectangle(0, 0, Win X, Win Y) Current = Copy end external routine edwin dot alias "EDWIN_DD_DOT"(integer X, Y) Flush Environment Gem Command(Polymarker) Add Ptsin(X, Y) Do Gem end external routine Edwin Line alias "EDWIN_DD_LINE"(integer OX, OY, NX, NY) routine Start Line Line X(0) = OX Line Y(0) = OY Line X(1) = NX Line Y(1) = NY Pts = 2 end Flush Environment unless Pts = 0 start if Line X(Pts-1)=OX and Line Y(Pts-1)=OY and Pts<Max Vertices start Line X(Pts) = NX Line Y(Pts) = NY Pts = Pts+1 else if Line X(Pts-1)=NX and Line Y(Pts-1)=NY and Pts<Max Vertices Line X(Pts) = OX Line Y(Pts) = OY Pts = Pts+1 else Flush Line Start Line finish else Start Line finish end external routine Edwin Polygon alias "EDWIN_DD_POLY"- (integer Count, integer array name XS, YS) integer Seg = Count, Last Seg = 1, i Flush Environment Seg = Max Vertices if Seg > Max Vertices cycle if Current_Fill Mode = Outline or Count > Max Vertices start Gem Command(Polyline) else Gem Command(Filled Area) finish Add Ptsin(XS(i), YS(i)) for i=Last Seg, 1, Seg Do Gem exit if Seg = Count Last Seg = Seg Seg = Seg+Max Vertices-1 Seg = Count if Seg>Count repeat end external routine Edwin Circle alias "EDWIN_DD_CIRCLE"(integer X, Y, Rad) Flush Environment Gem Command(GDP) Gem_Contrl_Sub Function = Circle Add Ptsin(X, Y) Add Ptsin(0, 0) Add Ptsin(Rad,0) Do Gem end external routine Edwin Text alias "EDWIN_DD_TEXT" - (integer SX, SY, byte name Ch) integer Len = C Length(Ch) integer function Physical Width(byte name Ch) Gem Command(Inquire Text Extent) Add String(Ch) Do Gem result = Pts Out(4) end Flush Environment if Ch = Extents Flag start Ch == Byte(Addr(Ch)+1) Len = Len-1 Char X = 0 cycle Char X = Char X+Physical Width(Ch) exit unless Len > Max Ints Ch == Byte(Addr(Ch)+Max Ints) Len = Len-Max Ints repeat else cycle Gem Command(Text) Add Ptsin(SX, SY) Add String(Ch) Do Gem exit unless Len > Max Ints Ch == Byte(Addr(Ch)+Max Ints) SX = SX + Physical Width(Ch) Len = Len-Max Ints repeat finish end external routine Edwin Char Size alias "EDWIN_DD_CHAR"(integer Size) return unless Variable Char Size = 1 Current_Char Size = (Size*Screen Aspect Ratio)//100 end external routine Edwin Line Style alias "EDWIN_DD_STYLE"(integer Style) Current_Line Style = Style end external routine Edwin Colour alias "EDWIN_DD_COL"(integer Colour) Current_Colour = Colour end external routine Edwin Mode alias "EDWIN_DD_MODE"(integer Mode) Current_Raster Op = Mode end external routine Edwin Fill alias "EDWIN_DD_FILL"(integer Mode) Current_Fill Mode = Mode end routine Get Input(integer name State, X, Y, integer Req) own integer Last X = 500, Last Y = 400, Last Button = 0 integer Key signal 14, 6 if Current Device # Screen Device Flush Line Cursor Status(Show Cursor) cycle Key = Top Of Buffer {read type ahead before looking for new stuff} Key = BDos(Dos Fn Direct Console IO, 255) if Key < 0 if Key = Escape Char start Int Flag = 1 Key = 0 finish Gem Command(Sample Mouse Button State) Do Gem Key = 1 if Last Button = 0 and Int Out(0) # 0 Last Button = Int Out(0) repeat until Key # 0 or Req = 0 Last X = Pts Out(0) Last Y = Pts Out(1) State = Key {input from the keyboard} State = 4 if Int Out(0) = 1 {left button} State = 1 if Int Out(0) = 2 {middle button} State = 2 if Int Out(0) = 4 {right button} X = Last X Y = Win Y-Last Y end external routine Sample alias "EDWIN___B_SAM"(integer name state,x,y) Get Input(State, X, Y, 0) end external routine Cursor alias "EDWIN___B_REQ"(integer name state,x,y) Get Input(State, X, Y, 1) end external routine edwin term alias "EDWIN_DD_TERM" record(Int Regs Fm) Regs=0 short mouse segment,mouse offset return if initialised edwin=0 flush line gem command(close workstation) do gem if prev dev=0 start initialised edwin=0 prev dev=0 prev handle=0 gem_contrl_handle=0 current device=0 Regs_Ah <- Dos Fn Force a Duplicate of a Handle Regs_Bx <- screen file descriptor Regs_Cx <- 1 Int86(Dos Int Function Request,Regs) else current device=prev dev prev dev=0 gem_contrl_handle=prev handle prev handle=0 ! ! put back all the old defaults ! gem command(extended inquire) add intin(0) ;! get the open workstation values do gem Winx=intout(0) Winy=intout(1) real colours=intout(13) current_char size=0 mouse addr=prev mouse addr fr86(mouse addr,original byte,1) screen aspect ratio=prev screen size finish end {##############################################} {# #} {# SCRDRIVE package support #} {# #} {##############################################} own integer Graphics Mode = 0 own integer Graphics Offset = 0 external routine Set Up Scrdrive alias "SET_SCRD" Edwin Fill(1) Cur X = 0 Cur Y = 0 Max X = (Win X//Char X) - 1 Max X = 250 if Max X > 250 Max Y = (Win Y//CharY) - 1 Max Y = 250 if Max Y > 250 Graphics Offset = (Char Y//10) + 1 end external routine Init Screen alias "InitScreen"(integer X, Y) ! ignore parameters to begin with. May contain data about window ! sizing and positioning ! Edwin Initialise(Cur X, Cur Y, 'D') Set Up Scrdrive end external routine Kill Window alias "KillWindow" Edwin Term Initialised Edwin = 0 end external integer function TT Get alias "TTGet" integer Char Char = Top Of Buffer Char = BDos(Dos Fn Console Input Without Echo, 0) if Char < 0 result = US if Char = 0 result = Char end external integer function X TT Get alias "EDWIN_SCREEN_TTGET" result = TT Get end external routine Move To alias "MoveTo"(integer X, Y) if X > Max X then X = Max X else if X < 0 then X = 0 if Y > Max Y then Y = Max Y else if Y < 0 then Y = 0 Cur X = X Cur Y = Y end external routine X Move To alias "SCR_MOVE_TO"(integer X, Y) Move To(X, Y) end external routine Down Line alias "DownLine" Cur Y = Cur Y+1 if Cur Y < Max Y end external routine Up Line alias "UpLine" Cur Y = Cur Y-1 if Cur Y > 0 end external routine Home alias "Home" Cur X = 0 Cur Y = 0 end routine Graphic Chars(byte name C String) integer C Ptr, End X routine Vertical Line(integer X, Y) X = X*Char X + Char X//2 Y = Y*Char Y Edwin Line(X, Y+Graphics Offset, X, Y+Char Y-Graphics Offset) end routine Glitch(integer X, Y) X = X*Char X + Char X//2 Y = (Y+1)*Char Y Edwin Line(X, Y-Graphics Offset, X, Y-Char Y//2) end return if Graphics Mode = 0 if C Length(C String) < 2 start End X = (Cur X+1)*Char X {Overwriting current cursor position} else End X = Win X {Overwriting to end of line} finish Edwin Mode(Replace Mode) Edwin Colour(Background Col) Edwin Rectangle(Cur X*Char X, Cur Y*Char Y + (Graphics Offset-1), End X, (Cur Y+1)*Char Y - (Graphics Offset-1)) Edwin Colour(Foreground col) Edwin Line(Cur X*Char X, Cur Y*Char Y + Char Y//2, End X, Cur Y*Char Y + Char Y//2) C Ptr = Addr(C String) cycle if C String = 'w' start Glitch(Cur X, Cur Y) else if C String # 'q' Vertical Line(Cur X, Cur Y) finish C Ptr = C Ptr+1 Cur X = Cur X+1 C String == Byte(C Ptr) repeat until C String = 0 end external routine TT String alias "TTString"(byte name s) integer a=addr(s),i=addr(s),j integer len=clength(s) integer sx=cur x*char x integer sy=(cur y+1)*char y-OffY Flush Environment Gem Command(Set Writing Mode) Add Intin(1) {make sure it's replace mode} Do Gem if Graphics Mode=1 and not ('a'<=s<='z') start ! not graphics characters, so print them out a=a+1 while not ('a'<=byte(a)<='z') ! ! print out the characters ! gem command(text) add ptsin(sx,sy) add intin(byte(j)) for j=i,1,a do gem curx=curx+a-i Graphic Chars(byte(a)) else if Graphics Mode=1 Graphic Chars(s) else Edwin Colour(Text Col) Edwin Text(sx,sy,s) move to(curx+len,cury) finish end external routine TT Put alias "TTPut"(integer x) byte array cstr(0:1) if x=8 start {backspace} move to(curx-1,cury) if CurX>0 return finish cstr(0)=x cstr(1)=0 ttstring(cstr(0)) end external routine XTTPut alias "TTPUT"(integer X) TT Put(X) end routine Scr Cursor integer x,y x=cur x*char x y=(cur y+1)*char y Edwin Fill(1) Edwin Mode(4) Edwin Rectangle(x,y,x+letterx,y-chary) Edwin Mode(Replace Mode) end external routine Draw Cursor alias "DrawCursor" Scr Cursor end external routine Delete Cursor alias "DeleteCursor" Scr Cursor end external routine Rectangle alias "Rectangle"(integer X, Y, W, H) record(Environment Fm) Copy = Current Edwin Mode(Replace Mode) Edwin Fill(4) Edwin Colour(Foreground Col) Edwin Rectangle(X, Y+Off Y, X+W-1, Y+Off Y+H) Current = Copy end external routine Draw Line alias "DrawLine"(integer X, Y, X1, Y1) record(Environment Fm) Copy = Current Edwin Mode(Replace Mode) Edwin Fill(1) Edwin Colour(Foreground Col) Edwin Line(X, Y+Off Y, X1, Y1+Off Y) Current = Copy end routine Draw Dotted Line (integer X, Y1, Y2, Style) record(Environment Fm) Copy = Current Edwin Line Style(Style) Edwin Mode(3) Edwin Line(X, Y1+Off Y, X, Y2+Off Y) Edwin Update Current = Copy end external routine Draw Cursor Line alias "Draw_C_L"(integer X, Y1, Y2) Draw Dotted Line(X, Y1, Y2, 4) end external routine Draw Marker Line alias "Draw_M_L"(integer X, Y1, Y2) Draw Dotted Line(X, Y1, Y2, 3) end external routine Flush Output alias "FlushOutput" Edwin Update end external routine Clear Screen alias "ClearScreen" Edwin Clear end routine Clear Space(integer Y1, Y2) record(Environment Fm) Copy = Current Edwin Fill(1) Edwin Colour(Background Col) Edwin Mode(Replace Mode) Edwin Rectangle(0, Y1*Char Y, Win X, Y2*Char Y) Current = Copy end external routine Clear Line alias "ClearLine" Clear Space(Cur Y, Cur Y+1) end external routine Scroll alias "Scroll"(integer LLn, HLn, By) record(Environment Fm) Copy = Current integer Erase Line Gem Command(Copy Raster Opaque) Gem_Contrl_C(7) <- MFDB Log & 16_FFFF Gem_Contrl_C(8) <- MFDB Log >> 16 Gem_Contrl_C(9) <- MFDB Log & 16_FFFF Gem_Contrl_C(10) <- MFDB Log >> 16 Add Intin(3) {Replace what is there} HLn = HLn+1 if By < 0 start Add Ptsin(0, (LLn-By)*Char Y) Add Ptsin(Win X, HLn*Char Y) Add Ptsin(0, LLn*Char Y) Add Ptsin(Win X, (HLn+By)*Char Y) Erase Line = HLn else Add Ptsin(0, LLn*Char Y) Add Ptsin(Win X, (HLn-By)*Char Y) Add Ptsin(0, (LLn+By)*Char Y) Add Ptsin(Win X, HLn*Char Y) Erase Line = LLn finish Do Gem Clear Space(Erase Line, Erase Line+By) Edwin Colour(ForegroundCol) end external routine Scroll Up alias "ScrollUp"(integer N) Scroll(0, Max Y, -N) end external routine Scroll Down alias "ScrollDown"(integer N) Scroll(0, Max Y, N) end external routine Set Intensity alias "SetIntensity"(integer LoHi) own integer Highlight = 0, Hold Colour, Foregroundsave, Textsave return if LoHi = Highlight Highlight = LoHi Gem Command(Set Graphic Text Special Effects) Add Intin(LoHi) Do Gem if LoHi = 1 start Hold Colour = Current_Colour Edwin Colour(Highlight Col) Foregroundsave = ForeGroundCol Textsave = TextCol TextCol = HighlightCol ForeGroundCol = HighlightCol else Edwin Colour(Hold Colour) ForeGroundCol = Foregroundsave TextCol = Textsave finish end external routine X Set Intensity alias "SCR_SET_INTENSITY"(integer LoHi) Set Intensity(LoHi) end external routine Set Graphics alias "SetGraphics"(integer Mode) Graphics Mode = Mode end ! Revision: ! Rev 1 11/11/86 UJ 1) Proportionally spaced text is now ! produced by this device driver. A ! software font is now used in place ! of the original, fixed font. ! 2) Text sizing is carried out to the ! nearest multiple of the basic text ! size. The sizing info. is held in ! /lbin/llenv.d, in LL_CHAR_HEIGHT. ! Rev 2 18/11/86 UJ The fill paterns produced by this ! driver can be the standard Versatec ! patterns if the Env variable ! LL_POLY_FILL exists. If it names a file ! containing 14 16x16 bitmaps arranged as ! 16 integers, then this will be used to ! define the fill patterns. ! Rev 3 UJ EDWIN line drawing routine modified so ! that individual lines are compiled into ! polylines in order to save on metafile ! space. ! Rev 4 UJ Character sizing can be varied through ! EDWIN if the environmental variable ! <filename>_VAR_CHAR_SIZE exists. Initial ! character size is set with the variable ! <filename)_CHAR_SIZE. If the proportional ! text is not wanted, the variable ! <filename>_FIXED_FONT should exist. ! Rev 4 UJ The environmental variables RED___INTENSITY ! GREEN_INTENSITY and BLUE__INTENSITY define ! the colour map for the device. Digit values ! should be 0-3. ! Rev 5 UJ Whole module tidied up in order to speed ! up execution and reduce code size. ! Rev 6 23/06/88 IRG Added routine Draw Marker Line ! ! Rev 7 5/08/88 AET Added code for colour control ! Rev 8 20/oct/88 JGH Removed minimium char size test ! Removed suppression of variable line styles ! Rev 9 16/Jan/89 JGH Fixed code for Sample, no longer same as REQ! end of file