! System dependent stuff for IE
! APM/Mouse version - RMM and GDMR March 84

%option "-NOCHECK-NODIAG-FORCE"

%external %string (255) Copyright %alias "SYSDEP_(C)_RMM" = %c
                  "Copyright (C) Richard M. Marshall and George D. M. Ross 1984"

%externalroutine quote(%string(255) s); %end

%include "SYSDEP.INC"
%include "IE.INC"

!%include "Moose:Mouse.Inc"
%include "Src:Util.Imp"

! Heap stuff

%own %integer Times Marked = 0

%external %routine Initialise Heap Space %alias "IE_INIT_HEAP"
   Mark
   Times Marked = 1
%end

%external %routine Reset Heap Space %alias "IE_RESET_HEAP"
   %integer I

   Release %for I = 1, 1, Times Marked
%end

%external %record (Line fm) %map New Line fm %alias "IE_NEW_LINE" %c
                                             (%integer Characters)
   %record (Line fm) %name L

   Characters = (Characters + 3)&(\3)
   L == Record (Heap Get (Characters + Size Of Line FM))
   L_Max Length = Characters
   %result == L
%end

%external %routine Dispose Line FM %alias "IE_DISPOSE_LINE" %c
                                   (%record (Line fm) %name L)
   Heap Put (Addr (L))
%end {Dispose Line fm}


! File loading & unloading

%external %routine load buffer %alias "IE_LOAD_BUFFER" %c
                               (%record (buffer fm) %name buffer,
                                %string (127) file name)
   %record(line fm)%name current == nil, previous == nil, first == nil
   %integer N
   %byte %name In
   %integer Saved,
            SEM
   %byte %array Line Buffer (0 : 1023)

      %on 9, 2, 3 %start
         !! printstring("%signal ");  write(event_event, 0)
         !! space;  write(event_sub, 0)
         !! space;  write(event_extra, 0)
         !! space; printstring(event_message);  newline
         -> EOF %if Event_Event = 9
         -> Fails
      %finish

      select output(0);  !???

      !! printstring("Loading buffer with ");  printstring(filename)
      !! newline
      buffer_source file = file name

      Mark
      Times Marked = Times Marked + 1
      open input(3, filename);  select input(3)
      %cycle

         N = 0                {Length}
         In == Line Buffer (0)
         %cycle
            read symbol(in)
            !! print symbol(13) %if in = NL
            !! print symbol(in)
            %exit %if In = NL
            N = N + 1
            In == In [1]
         %repeat

         Current == New Line fm (N)

         Bulk Move (N, Line Buffer (0), Current_Text (1))

         Current_Length = N
         current_bits =  untouched

         %if previous == nil %start
            current_last == nil
            first == current
         %else
            previous_next == current
            current_last == previous
         %finish
         current_next == nil
         previous == current
      %repeat
   EOF:
      close input;  select input(0)
      Current == New Line fm (0)
      %if previous == nil %start
         current_last == nil
         first == current
      %else
         previous_next == current
         current_last == previous
      %finish
      current_next == nil
      current_bits  =  pseudo line;  ! the end marker, really...
      current_max Length = 0
      current_length = 0
      current_last  == previous
      buffer_first  == first
      buffer_last   == current
      buffer_changed = 0
      %return

   Fails:
      Release
      Times Marked = Times Marked - 1
      %signal 10, 0, 0, Event_Message
%end


%external %routine unload buffer %alias "IE_UNLOAD_BUFFER" %c
                                 (%record (buffer fm) %name buffer,
                                  %string (127) file name)
   %record(line fm)%name line
   %integer N,
            Save = Out Stream

      !! printstring("Unloading to ");  printstring(filename)
      !! newline
      Open Output (3, File Name)
      Select Output (3)
      line == buffer_first
      %while line ## nil %and line_bits & pseudo line = 0 %cycle
         %if Line_Length > 0 %start
            %for N = 1, 1, Line_Length %cycle
               Print Symbol (Line_Text (N))
            %repeat
         %finish
         New Line
         line == line_next
      %repeat
      Close Output
      Select Output (Save)
%end


! Journal file stuff comes here.....

%external %string (31) Actual Journal File %alias "IE_J_FILE" = "IE_JOURNAL"

%routine open journal
%end

%routine flush journal
%end

%external %routine put journal symbol %alias "IE_J_PUT" (%integer sym)
%end

{PUT JOURNAL STRING}

%external %routine put journal string %alias "IE_J_STRING" (%string (255) S)
   %integer I, ch

   %for I = 1, 1, length (S) %cycle
      ch = char no (S, I)
      put journal symbol (ch) %if ch >= ' '
   %repeat
%end {of put journal string}

{PUT JOURNAL INTEGER}

%external %routine put journal integer %alias "IE_J_INT" (%integer i)
   put journal string (I to S (i, 0))
%end {put journal integer}

%externalroutine set journal frequency %alias "IE_J_SET" (%integer new)
%end

%externalroutine keep journal %alias "IE_J_KEEP"
%end

%externalroutine scrap journal %alias "IE_J_SCRAP"
%end

! Miscellaneous useful things:
! Bulk move, Find string

%external %routine bulk move %alias "IE_BULK_MOVE" %c
                             (%integer bytes, 
                              %bytename from, to)
   %return %if Bytes = 0 %or %c
               From == To
   %if Addr (To) < Addr (From) %start
      *Subq.l #1, d0
   f loop:
      *move.b (a0)+, (a1)+
      *dbra   d0, f loop
   %else
      *add.l  d0, a0
      *add.l  d0, a1
      *subq.l #1, d0
   b loop:
      *move.b -(a0), -(a1)
      *dbra   d0, b loop
   %finish
%end

%external %integerfn find string %alias "IE_FIND_STRING" %c
                                 (%integer case mode,
                                  %string (*) %name Find, 
                                  %integer Start,
                                  %record (Line fm) %name Match)
   %bytename start match, current match, start find, current find
   %integer match length, current length, searches, start pos, it

      %result = 0 %if match_length < start

      start match == match_text(start)
      start find  == charno(find, 1)
      searches     = match_length - length(find) - start + 2
      start pos    = start
      %while searches > 0 %cycle
         current match == start match
         current find  == start find
         current length = length(find)
         %cycle
            it = current match
            it = it - 'a' + 'A' %if case mode = 0 %and 'a' <= it <= 'z'
            %exit %if it # current find
            current find  == current find  [1]
            current match == current match [1]
            current length = current length - 1
            %result = start pos %if current length = 0
         %repeat
         start match == start match [1]
         searches = searches - 1
         start pos = start pos + 1
      %repeat
      %result = 0
%end

%external %integer %function Reverse find string %alias "IE_REV_FIND" %c
                                 (%integer case mode,
                                  %string (*) %name Find, 
                                  %integer Start,
                                  %record (Line fm) %name Match)
   %bytename start match, current match, start find, current find
   %integer match length, current length, searches, start pos, it

      %if Start + Length (Find) > Match_Length %start
         Start = Match_Length - Length (Find) + 1
      %finish
      %result = 0 %if Start < 1
      start match == match_text(start)
      start find  == charno(find, 1)
      searches     = start
      start pos    = start
      %while searches > 0 %cycle
         current match == start match
         current find  == start find
         current length = length(find)
         %cycle
            it = current match
            it = it - 'a' + 'A' %if case mode = 0 %and 'a' <= it <= 'z'
            %exit %if it # current find
            current find  == current find  [1]
            current match == current match [1]
            current length = current length - 1
            %result = start pos %if current length = 0
         %repeat
         start match == start match [-1]
         searches = searches - 1
         start pos = start pos - 1
      %repeat
      %result = 0
%end

! Default Finders

%include "Terminal.Inc"

%record %format IE Stuff fm (%string (127) Memory,
                                           Last,
                                           Journal File,
                                           Profile File,
                                           Keyboard File,
                             %byte Terminal,
                             %integer Line, Position)

%own %record (IE Stuff fm) %name IE Stuff == Nil
%own %integer Stuff At = 0

%external %string (255) %function Default Profile %alias "IE_DEF_PRO"
   %string (127) P = "",
                 S
   %constant %string (20) Profile File = "Profile.IE"

!   %if IE Stuff == Nil %start
!      Stuff At = Ref Name ("IE_Stuff", Sys Dict)
!      IE Stuff == Record (Stuff At)
!   %finish
!   %if IE Stuff ## Nil %start
!      P = IE Stuff_Profile File
!   %finish
   %if P = "" %start
      %if Exists (Profile File) %start
         P = Profile File
!      %else
!         S = Current User . ":" . Profile File
!         P = S %if Exists (S)
      %finish
   %finish
   %result = P
%end {Default Profile}

%external %string (255) %function Default Keyboard %alias "IE_DEF_KEY"
   %constant %string (20) %array Default Keyboards (Visual 200 : WY 75) = %c
      "IE:V200.KIE",
      "IE:V55.KIE",
      "IE:VT100.KIE",
      "IE:VT220.KIE",
      "IE:F100.KIE",
      "IE:WY50.KIE",
      "IE:WY75.KIE"

   %string (127) K, S
   %constant %string (20) Keyboard File = "Keyboard.KIE"


   K = Default Keyboards (Terminal Model)
!   %if IE Stuff == Nil %start
!      Stuff At = Ref Name ("IE_Stuff", Sys Dict)
!      IE Stuff == Record (Stuff At)
!   %finish
!   %if IE Stuff ## Nil %and %c
!       IE Stuff_Keyboard File # "" %start
!      K = IE Stuff_Keyboard File
!   %else
!      %if Exists (Keyboard File) %start
!         K = Current Directory . ":" . Keyboard File
!      %else
!         S = Current User . ":" . Keyboard File
!         K = S %if Exists (S)
!      %finish
!   %finish
   %result = K
%end {Default Keyboard}

%external %string (255) %function Default Journal %alias "IE_DEF_JOU"
   %string (127) J = "IE_JOURNAL"

!   %if IE Stuff == Nil %start
!      Stuff At = Ref Name ("IE_Stuff", Sys Dict)
!      IE Stuff == Record (Stuff At)
!   %finish
!   %if IE Stuff ## Nil %and %c
!       IE Stuff_Journal File # "" %start
!      J = IE Stuff_Journal File
!   %finish
   %result = J
%end {Default Journal}
