%option "-LOW"
%begin
   ! (Quadruple Synchronous/Asynchronous Receiver/Transmitter)
   ! (RS232 board with four Signetics-2651-type chips)
   
  %include "Inc:util.imp"
  %include "rnp:utils.inc"

  %constant %integer boardaddr = 16_7FFC0
  %byte symbol

  %recordformat DEVICE FM(%byte bstatus,data,intvec,dstatus,x,mode,y,command)
   ! BSTATUS and INTVEC are board registers, X and Y "do not exist",
   ! DATA, DSTATUS, MODE, COMMAND are registers in the 2651s.

  @boardaddr %record(device fm) device

  %constant %integer mode1=16_4e,mode2=16_30,comm=16_37
   ! Hardware initialisation values:
   ! 1 stop bit, no parity, 8 bits, async 16*baud clock,
   ! internal clocks, normal operation, force RTS active,
   ! reset error, no break, enable rx, force DTR active, enable tx.

  %constant %integer errormask=16_38
   ! Dev status: [dsr|dcd|fe|oe|pe|txe/dsrc/dcdc|rxr|txr]

  %constant %integer txie=1,rxie=2,reset=8
   ! Board command/status: [inting|0|0|0|reset|txeie|rxrie|txrie]

  %constant %integerarray baudrate(0:15)=  46,   50,   75,  110,
                                          135,  150,  300,  600,
                                         1200, 1800, 2000, 2400,
                                         4800, 9600,19200,38400

  %constant %integer default baud code=13
@16_4000C1 %byteinteger vdus
@16_4000C3 %byteinteger vdud

  %routine gotoxy(%byteinteger x,y)
     printsymbol(27)
     printsymbol('Y')
     printsymbol(y+32)
     printsymbol(x+32)
  %end

  %routine set baud(%integer code)
  %integer state=0

    %on %event 0 %start
       gotoxy(0,7)
       %signal %event 15
    %finish
    ! Set up the device onboard board 
    device_bstatus = reset;   state = 1
    device_bstatus = 0;       state = 2
    device_mode = mode1;      state = 3
    device_mode = mode2+code; state = 4
    device_command = comm;    state = 5
  %end
   
  %routine show qsart status

     %on %event 0 %start
        gotoxy(0,7)
        %signal %event 15
     %finish
   
     printstring("QSART status:"); newline
     printstring("Channel 0")
     pbin2(device_bstatus,8)
     printstring(" / ");pbin2(device_dstatus,8)
     newline
  %end
   
! Bus error caused by absence of device generates event 0

  %predicate board check
  %byte status

     %on %event 0 %start
        printstring("Board not found"); newline
        %false
     %finish

     printstring("QSART ")
     status = device_bstatus
     printstring("Board 16_7FFC0");newline
     %true
  %end

! Allows event 0 traps
  %on %event 0,15 %start
     ->abort
  %finish

  %routine interrupt off
  %constbyte viof = 16_11
    *move.b #viof,vdus
  %end

  %routine interrupt on
  %constbyte vion = 16_91
    *move.b #vion,vdus
  %end

  %routine getsymbol(%byteintegername i)
loop:
    *btst #0,vdus
    *beq loop
    *move.b vdud,(a0)
  %end

  vt clear
  %if board check %then set baud(default baud code) %else ->abort
  interrupt off
  %cycle
     getsymbol(symbol)
     printsymbol(symbol)
     device_data=symbol
  %repeat %until symbol = 16_1A
  interrupt on

abort:
%endofprogram
