!****************************************************************
!*                                                              *
!*         Little program reads frames from the SEESCAN board   *
!*                                                              *
!*                  Version 1.1   21 Nov 1986                   *
!*                                                              *
!****************************************************************

! Qsart routines pared to bare minimum.  See AJS:QSART etc for full version

%include "inc:util.imp"
%include "iff:iffinc.imp"
%constinteger ht = 256, wid = 256, ibyte=0
%conststring (15) %array lr(0:1) = "left", "right"
%conststring (15) %array rgb(0:2) = "red", "green", "blue"

%conststring (1) quotes=""""

%Begin
{}%bytearray t(0:255)
{}%integer tptr

%constant %integer boardaddr = 16_7FFA0    ;! Change as appropriate
%recordformat DEVICE FM(%byte bstatus,data,intvec,dstatus,x,mode,y,command)
@boardaddr %record(device fm) device
%integer i,n,yn,csum, images
%record (iffhdr fm) iffhdr

%routine set 9600 baud
  %constinteger mode1=16_4e,mode2=16_30,comm=16_37,reset=8,
                code=13 ;!9600 baud
  %on 0 %start
     Printline("**Bus error.") %unless event_sub=1
     %stop
  %Finish

  device_bstatus = reset; device_bstatus = 0
  device_mode = mode1;    device_mode = mode2+code
  device_dstatus = 0;     device_dstatus = 0
  device_dstatus = 0;     device_command = comm
%end

%integerfn get
!!   %while device_dstatus&2=0 %cycle; %Repeat
!!   %Result = device_data
    %label l1
L1: *BTST.b  #1,16_0007FFA3
    *beq     l1
    *clr.l   d0
    *move.b  16_0007FFA1,d0
    *rts
%End

%routine put(%Integer sym)
   %While device_dstatus&1=0 %cycle; %repeat
   device_data =sym
%End


%routine putstring(%string (255) s)
   %integer i
   %return %if s=""
   %for i=1,1,length(s) %cycle; put(charno(s,i)); %repeat
%end

%bytefn gethex2
   !Seescan produces 7-bit ASCII (observed)
!!   %integer a, b
!!   a=get-'0'; a=a+7 %if a>9
!!   b=get-'0'; b=b+7 %if b>9
!!   a=a<<4+b
!!   csum = csum+a
!!{}t(tptr)=a; tptr=tptr+1
!!   %result=a

!d0 = a; d1 = b

%label l1,l2,l3
    *clr.l   d0
L1: *BTST.b  #1,16_0007FFA3
    *beq     l1 
    *move.b  16_0007FFA1,d0
    *ADDi.b  #-48,D0
    *CMPi.b  #9,D0
    *BLE     L2 
    *ADDQ.b  #7,d0

L2: *BTST.b  #1,16_0007FFA3
    *beq     l2 
    *move.b  16_0007FFA1,d1
    *ADDi.b  #-48,D1
    *CMPi.b  #9,d1
    *BLE     L3 
    *ADDQ.b  #7,d1

L3: *LSL.b   #4,D0
    *ADD.b   d1,D0
    *ADD.b   D0,csum

! {}t(tptr)=a; tptr=tptr+1
    *MOVE.b  tptr,D3
    *LEA     t,A0
    *MOVE.B  D0,0(A0,D3.L)
    *ADDQ.b  #1,tptr

    *RTS     
%end

%integerfn gethex4
  %result=gethex2<<8+gethex2
%end

%routine pause(%integer msec)
   msec = msec + cputime
   %cycle; %repeatuntil cputime>=msec
%end

%routine hands on
   %integer c1,ptr,ctrl
   %bytearray buffer(0:63)
   !Transparent terminal.  Note APM switches cr and lf so we switch them back
   !rather than having to fiddle with EXEMPT MASK.  
   !Output to Seescan is buffered.  Output to VDU is not.

   printline("In Hands-on mode - ctrl-Z to exit")
   put(13)

   ptr=0
   %cycle
      ctrl = device_dstatus
      %if ctrl&2 # 0 %start
         c1 = device_data
         printsymbol(c1)
      %finish
      %if ctrl&1 # 0 %and ptr#0 %start
         ptr=ptr-1; device_data=buffer(ptr)
      %finish

      c1=testsymbol
      %if c1>=0 %start
         %exit %if c1=16_1A ;!Ctrl-Z
         %if c1=13 %or c1=10 %then c1=23-c1 %elsestart
            %if 'a'<=c1<='z' %then c1=c1-'a'+'A'
         %finish
         buffer(ptr)=c1; ptr=ptr+1
      %finish
   %repeat
%end

! Nicked from MET EDITH package..
! Aspect ratio of pictures should be 4:3 NOT 1:1 (x:y)
! The correct aspect ratioing is achieved by taking 4 points numbered
! (0,1,2,3) & interpolating them to points (0,1+1/3,2+2/3)
! o(A0) contains start addr of output line
! t(A1) contains start addr of current picture line
%routine alter aspect(%bytename o,t)

  *move.w #255,d0;!      Loop for all lines in origrinal picture
a:*move.w #63,d1;!       Loop for the 64 sets of 4 pts vertically
  *move.l a0,a2;!        Preserve addresses
  *move.l a1,a3
b:*move.b (a3),(a2);!    Copy current pt 0 to new pt 0
  *clr.l d2;!            Clear working registers
  *clr.l d3
  *clr.l d4
  *move.b 512(a3),d2;!   Get pt 1 one line up from pt 0(ie 512 bytes)
  *move.b 1024(a3),d3;!  Get pt 2 two lines up from pt 0
  *move.b 1536(a3),d4;!  Get pt 3 three lines up from pt 0
  *lsl.w  #1,d2;!        Multiply pt 1 by two (weighting factor in interpolation)
  *lsl.w  #1,d4;!        Multiply pt 3              ""           ""
  *add.w  d3,d2;!        Add in pt 2 to new pt 1
  *add.w  d3,d4;!        Add in pt 2 to new pt 3
  *divu   #3,d2;!        Divide by 3 to obtain pt 1+1/3
  *divu   #3,d4;!        Divide by 3 to obtain pt 2+2/3
  *move.b d2,512(a2);!   Store 1+1/3 one line up from current output point
  *move.b d4,1024(a2);!  Store 2+2/3 two lines up from current output point
  *adda.l #1536,a2;!     Move output pointer up three lines
  *adda.l #2048,a3;!     Move input pointer up four lines
  *dbra d1,b;!           Loop to do next group of 4 pts
  *adda.l #1,a0;!        Move output 1 place horizontally
  *adda.l #1,a1;!        Move input  1 place horizontally
  *dbra d0,a;!           Loop to do next vertical line

%end

%string(255) file, s1,s2
%integer c1,c2,msec
%byte %array image, stretch(0:65535)

%integer len, offset, junk, cfcount, rc, im

!---------- Initialise everything
set terminal mode(8)
set 9600 baud

!---------- Process the command line and extract parameters
file = cliparam
images=1 ;!monochrome
file=s1.s2 %and images=images*2 %if file -> s1.("-s").s2 ;!stereo
file=s1.s2 %and images=images*3 %if file -> s1.("-rgb").s2 ;!RGB colour triplet
printline("** WARNING - NO OUTPUT FILE SPECIFIED - SEESCAN.IFF ASSUMED **") %if file = ""
file="seescan" %if file=""

!---------- Grope the SEESCAN board
!Poll until transmitting a <return> provokes a '>' prompt.
%cycle
   c1=0
   put(27)
   put(13)
   msec = cputime + 2000
   %cycle
      %if device_dstatus&2 # 0 %start
         c1 = device_data & 16_7F
      %finish
   %repeatuntil cputime>=msec %or c1 = '>'
   printstring("Polling for Seescan board")
   %if c1=10 %or c1=13 %then c1='_'
   %if ' ' < c1 <= 126 %then space %and printsymbol(c1)
   newline
%repeatuntil c1 = '>'
printline("Seescan board groped OK")

!---------- Take the image(s)
prompt("Image Title:"); readline(s1)
!!prompt("Adjust aspect ratio?")
!!readsymbol(yn) %until yn='Y' %or yn='y' %or yn='N' %or yn='n'
!!yn=yn & 16_5f
yn='N'

rc = iff open file(file, iffhdr, iff write)

%if rc=0 %start
   iffhdr_ht    = ht
   iffhdr_ht    = (iffhdr_ht//4)*3 %if yn='Y'
   iffhdr_wid   = wid
   %if images=2 %or images=6 %then iffhdr_stereo=1
   %if images=3 %or images=6 %then iffhdr_images=3
   iffhdr_id    = 002436 ;!Serial no. of Seescan camera
   iffhdr_fstop = 140    ;!f/1.4
   iffhdr_focus = 16     ;!16mm
   iffhdr_title = "Seescan image - ".s1
   iffhdr_aspect= 16_0403;!rectangular pixels x=4 y=3
   rc = iff write header(iffhdr)
   %if rc=0 %start

      %for im=0,1,images-1 %cycle
         printstring("Set up to capture ")
         %if images=2 %then printstring(lr(im))
         %if images=3 %then printstring(rgb(im))
         %if images=6 %then printstring(lr(rem(im,3))." ".rgb(im//2))
         printstring(" image"); newline
      
         !---------- Give the user control till he hands back with a ctrl-Z
         hands on
      
         putstring("FREEZE"); put(13); put(10)
         pause(500)
         putstring("SAVE ".quotes."FILE".quotes." S"); put(13); put(10)
         n=0; c2=0; cfcount=0
         %cycle
           c1=get
           %if c1=':' %start
             csum=0
             tptr=0
             len=gethex2
             offset=gethex4
             junk=gethex2
             %for i=0,1,len-1 %cycle
                image(n)<- gethex2; n=n+1
             %repeat
             junk=gethex2
             %if csum&255#0 %start
                %for i=0,1,tptr-1 %cycle; phex2(t(i)); space; %repeat; spaces(3)
                phex2(csum); space; phex(n); newline
             %finish
             cfcount=cfcount+1 %if csum&255#0
           %elseif c1 = 13
             c2=c2+1; %if c2&63=0 %start
               %if cfcount=0 %then printsymbol('*') %else printsymbol('?') %and cfcount=0
             %finish
           %finish
         %repeatuntil testsymbol=16_1A %or n=65536

         %if yn='Y' %start
            alter aspect(image(0), stretch(0)) 
            rc = iff write image(iffhdr, addr(stretch(0)))
         %else
            rc = iff write image(iffhdr, addr(image(0)))
         %finish
      %repeat
      iff close file(iffhdr)
   %finish
%finish
%endofprogram

