      HED BASIC SYSTEM HIGH SPEED PUNCH DRIVER
*
************** BASIC SYSTEM HIGH SPEED PUNCH DRIVER ****************
*
*  OUTPUTS ASCII THROUGH THE HIGH SPEED PUNCH
*
*  CALL:  JSB 103B,I
*
*        (A) = NUMBER OF CHARACTERS TO BE PUNCHED
*        (B) = STARTING ADDRESS OF BUFFER
*
*
*     IF (A) IS >= 0  THEN OUTPUT (A) CHARACTERS
*     FOLLOWED BY A CARRIAGE RETURN-LINE FEED.
*
*     IF (A) < 0 THEN PUNCH -(A) CHARACTERS ONLY.
*
*     BUFFER CONTAINS ASCII CHARACTERS PACKED TWO PER WORD.
*
*     IF (B) = 0 OK ENTRY (A) FEED FRAMES ARE PUNCHED.
*     IF (A) = 0 OK ENTRY ONLY A CR/LF IS PUNCHED.
*
*
.PNCH NOP
PN1   JSB INIT      INITIALIZE FOR PUNCHING
PN2   JSB GETCH     GET NEXT CHARACTER FROM BUFFER
      JMP PN6       BUFFER EMPTY
PN3   OTA PNCH      LOAD PUNCH BUFFER
PN4   STC PNCH,C    GIVE PUNCH COMMAND
PN5   SFS PNCH
      JMP *-1       WAIT FOR PUNCH READY
      JMP PN2       GET NEXT CHARACTER
*
PN6   LDA IORI
      STA FINSH+1   RESTORE IOR INSTRUCTION
PN7   CLC PNCH      TURN OFF PUNCH
      SEZ,CLE,RSS   RECORD COMPLETE? CLEAR E
      JMP .PNCH,I   E=0, OUTPUT COMPLETE
      LDA M2        E=1, APPEND CR AND LF
      LDB CRLFA     LOAD ADDRESS OF CR AND LF
      JMP PN1       DO CR/LF
      HED BASIC SYSTEM HIGH SPEED PHOTO READER DRIVER
*
*************** BASIC SYSTEM PHOTO READER DRIVER  ******************
*
*  INPUTS TAPE RECORDS THROUGH THE PHOTO READER
*
*  CALL:  JSB 101B,I
*
*        (A) =  MAXIMUM NUMBER CHARS IN RECORD
*        (B) =  BUFFER STARTING ADDRESS
*
*   ON RETURN  (A)= -1  TOO MANY CHARACTERS IN RECORD
*              (A)= -2  END OF TAPE DETECTED
*              (A)= -3  NO TAPE OR GATE DOWN
*              (A)= NUMBER OF CHARACTERS IN RECORD
*
*           INPUT IS PACKED TWO CHARACTERS PER WORD IN BUFFER.
*
*           ALL RECORDS MUST BE TERMINATED WITH A LINE FEED.
*           THE NULL AND CARRIAGE RETURN CHARACTERS ARE IGNORED.
*
*           THE LEFT ARROW(S) - DELETE THE PREVIOUS CHARACTER(S).
*
*           AN ALT MODE ANYWHERE BEFORE THE LINE FEED DELETES ALL
*           CHARACTERS IN THE RECORD. THE RECORD IS IGNORED.
*
*      IF 10 NULL CHARACTERS ARE DETECTED BEFORE ANY CHARACTER,
*      READING IS TERMINATED AND THE RETURN IS WITH A NULL RECORD.
*
*
.HSPR NOP
      STA COUNT     SAVE LENGTH
      STB BUFSA     SAVE BUFFER STARTING ADDRESS
PR1   LDA M11
      STA EOTC      INITIALIZE EOT COUNTER
      LDB BUFSA
      STB BADDR     INITIALIZE BUFFER POINTER
      CLB           INITIALIZE CHARACTER COUNT
PR2   SZB,RSS       ANY NON-NULL CHARACTERS YET?
      SZA           NO, SKIP IF NULL
      JMP PR3
      ISZ EOTC      COUNT NULL
      JMP PR3       NOT YET 10 NULLS
      LDA M2        SET A TO INDICATE EOT (-2)
      JMP PR7       10 NULLS, TURN OFF READER & EXIT
PR3   STC RDR,C     REQUEST CHARACTER
      CLA           SET DELAY COUNT
PR4   INA,SZA,RSS   DELAY = 6.4 * 65K = .41 SECONDS
      JMP PR8       (A)=0, NO TAPE OR GATE DOWN
PR5   SFS RDR
      JMP PR4       NO FLAG, CHECK DELAY COUNT
PR6   LIA RDR,C     LOAD CHARACTER
      JSB PROCS     PROCESS CHARACTER
      JMP PR2       GET NEXT CHARACTER
      CPB M2        RUBOUT IN THIS RECORD?
      JMP PR1       YES, IGNORE RECORD
PR7   CLC RDR       TURN OFF READER
      JMP .HSPR,I
*
PR8   LDA M3        LOAD 'NO TAPE' STATUS
      JMP PR7
      HED BASIC SYSTEM TELETYPE INPUT DRIVER
*
******************* BASIC SYSTEM TELETYPE INPUT DRIVER *************
*
*   INPUTS FROM AN ASR 33/35 THROUGH THE
*   TELETYPE CONTROL BOARD FROM TAPE OR KEYBOARD
*
*    CALL:  JSB 104B,I
*
*        (A) =  MAXIMUM NUMBER CHARS IN RECORD
*        (B) =  BUFFER STARTING ADDRESS
*
*    RETURN:   (A)= -1  TOO MANY CHARACTERS IN RECORD
*              (A)= -2  RECORD DELETED
*              (A)= NUMBER OF CHARACTERS IN RECORD
*
*
*           THE CHARACTERS ARE PACKED TWO TO A WORD IN THE BUFFER
*
*           ALL RECORDS MUST BE TERMINATED WITH A LINE FEED
*           THE NULL AND CARRIAGE RETURN CHARACTERS ARE IGNORED
*
*           THE LEFT ARROW(S) - DELETE THE PREVIOUS CHARACTER(S).
*
*           AN ALT MODE ANYWHERE BEFORE THE LINE FEED DELETES ALL
*           CHARACTERS IN THE RECORD. THE RECORD IS IGNORED.
*
*
TTY.I NOP
      STA COUNT     SAVE LENGTH
      STB BADDR     SET BUFFER ADDRESS
      CLB           SET CHARACTER COUNTER
      LDA IMODE
TI.1  OTA TTY       SET TTY TO INPUT MODE
TI.2  STC TTY,C     REQUEST CHARACTER
      SFS TTY
      JMP *-1       WAIT FOR CHARACTER INPUT
TI.3  LIA TTY       LOAD CHARACTER
      JSB PROCS     PROCESS CHARACTER
      JMP TI.2      GET NEXT CHARACTER
TI.4  CLC TTY
      JMP TTY.I,I   RECORD COMPLETE RETURN
*
IMODE OCT 160000    LIST ONLY (INPUT-ASR 35)
      HED BASIC SYSTEM TELETYPE OUTPUT DRIVER
*
*************** BASIC SYSTEM TELETYPE OUTPUT DRIVER ****************
*
*    OUTPUTS ASCII RECORDS THROUGH THE TELETYPE PRINTER,
*    PUNCH, OR BOTH.
*
*    CALL:  JSB 102B,I
*
*          (A) = NUMBFR OF CHARACTERS TO BE OUTPUT
*          (B) = STARTING ADDRESS OF BUFFER
*
*
*     IF (A) IS >= 0  THEN OUTPUT (A) CHARACTERS
*     FOLLOWED BY A CARRIAGE RETURN-LINE FEED.
*
*     IF (A) < 0 THEN PUNCH -(A) CHARACTERS ONLY.
*
*     BUFFER CONTAINS ASCII CHARACTERS PACKED TWO PER WORD.
*
*     IF (B) = 0 OK ENTRY OUTPUT (A) FEED FRAMES.
*     IF (A) = 0 OK ENTRY ONLY A CR/LF IS OUTPUT.
*
*
TTY.P NOP
      JSB INIT      INITIALIZE AND SETUP
TP.1  LDA TTY       SAVE TTY INTERRUPT
      STA TEMPI       INSTRUCTION
      LDA LISTR
      CPA PLSTR     PLIST?
      LDA PMODE     YES
      CPA TLSTR     LIST?
      LDA LMODE    YES
      OTA TTY       SET TTY TO OUTPUT MODE
TP.2  STB TTY       PUT NOP INTO INTERRUPT CELL
TP.3  JSB GETCH     GET NEXT CHARACTER
      JMP TP.8      BUFFER EMPTY
TP.4  OTA TTY       LOAD TTY BOARD BUFFER
      STC TTY,C     GIVE PRINT COMMAND
TP.5  SFS TTY       WAIT FOR
      JMP *-1         FLAG
      LDA TEMPI
      SZA,RSS       IS INTERRUPT ENABLED?
      JMP TP.3      NO
*
*  THIS SECTION CHECKS IF A CHARACTER HAS BEEN TYPED FROM THE
*   KEYBOARD DURING OUTPUT ON TELETYPE.
*
TP.6  LIA TTY       LOAD FROM BOARD BUFFER
      CMA           FIRST 8 BITS SHOULD BE 1'S
      AND B177
      SZA,RSS
      JMP TP.3      NO KEY STRUCK, CONTINUE
      LDA IORI
      STA FINSH+1   RESTORE IOR INSTRUCTION
TP.7  CLC TTY       TURN OFF TTY
      JSB I.STP,I   GO TO STOP
TP.8  CLC TTY       TURN OFF TTY
      LDA TEMPI
      CPA TT.II     IS INTERRUPT MODE SET?
      JSB I.ON      YES, RE-ENABLE KEYBOARD
      LDA IORI
      STA FINSH+1   RESTORE IOR INSTRUCTION
      SEZ,CLE,RSS   RECORD COMPLETE?   CLEAR  E
      JMP TTY.P,I   E=0, RECORD OUTPUT COMPLETE
      LDA M2        E=1, ADD A RETURN AND LINE FEED
      LDB CRLFA     LOAD ADDRESS OF CR AND LF
      JMP TTY.P+1   DO CR/LF
*
PMODE OCT 110000    PUNCH ONLY (ASR 35)
LMODE OCT 120000    LIST ONLY  (ASR 35)
*
TEMPI NOP
      SPC 5
*
*      THIS ROUTINE TURNS OFF THE TELETYPE INTERRUPT MODE
*
I.OFF NOP
      CLA
TI.5  STA TTY       SET NOP INTO INTERRUPT CELL
      CLC TTY       TURN OFF READ MODE
R.OFF NOP           SET TO CLC RDR IF RDR EXISTS
P.OFF NOP           SET TO CLC PNCH IF PNCH EXISTS
      JMP I.OFF,I   RETURN
      SPC 5
*
*      THIS ROUTINE TURNS ON THE TELETYPE INTERRUPT MODE
*
I.ON  NOP
      LDA TT.II
TI.6  STA TTY       SET JSB INTO INTERRUPT CELL
      LDA IMODE
TI.7  OTA TTY       SET TTY TO INPUT MODE
      STC TTY,C     SET TTY TO LOOK FOR INPUT
      JMP I.ON,I    RETURN
*
TT.II JSB I.STP,I   INTERRUPT LOCATION CODE
      HED CHARACTER PROCESSING SECTION FOR INPUT
*
*  CHARACTER PROCESSING SECTION FOR TTY AND PHOTOREADER
*
*      CALL:   JSB PROCS
*              (A) HOLDS CHARACTER
*
*      RETURN:    P+1 - GET NEXT CHARACTER
*                 P+2 - RECORD COMPLETE
*
PROCS NOP
      AND B177      STRIP BIT 7
      SZA,RSS       NULL?
      JMP PROCS,I   YES, IGNORE
      CPA .2        NO, CONTROL B ?
      JMP PROCS,I   YES, IGNORE
      CPA .3        NO, CONTROL C ?
      JMP PROCS,I   YES, IGNORE
      CPA LNFD      NO, LINE FEED?
      JMP PROCS,I   YES, IGNORE
      CPA B177      NO, RUBOUT?
      JMP PROCS,I   YES, IGNORE
      CPA AMODE     NO, ALT MODE?
      JMP CMPLT-1   YES, CANCEL RECORD
      CPA OMODE     NO, OLD ALT MODE?
      JMP CMPLT-1   YES, CANCEL RECORD
      CPA EMODE     NO, ESCAPE MODE?
      JMP CMPLT-1   YES, CANCEL RECORD
      CPA CRTN      NO, CARRIAGE RETURN?
      JMP CMPLT     YES, COMPLETE RECORD
      CPB COUNT     NO, BUFFER OVERFLOW?
      CCB           YES, LOOK FOR CARRIAGE RETURN
      SSB           LOOKING FOR CARRIAGE RETURN?
      JMP PROCS,I   YES, RETURN
      CPA LFTAR     NO, LEFT ARROW?
      JMP DLETE     YES, DELETE PREVIOUS CHARACTER
      SLB,INB       NO, CHECK ODD/EVEN FLAG
      JMP PROC2     B0 = 0, EVEN CHARACTER
PROC1 ALF,ALF       B0 = 1, ODD CHARACTER
      STA BADDR,I   RECORD HIGH CHARACTER
      JMP PROCS,I
PROC2 IOR BADDR,I   PACK TWO CHARACTERS
      STA BADDR,I   PUT IN BUFFER
      ISZ BADDR     INDEX BUFFER ADDRESS POINTER
      JMP PROCS,I
      SKP
*
*  THIS SECTION DELETES PREVIOUS CHARACTER(S)
*
DLETE SZB,RSS       IS BUFFER EMPTY?
      JMP PROCS,I   YES, RETURN
      CCA           NO
      ADB 0         DECREMENT CHARACTER COUNT
      SLB,RSS       LOW CHARACTER?
      JMP PROCS,I   YES
      ADA BADDR     NO, DECREMENT
      STA BADDR       ADDRESS POINTER
      LDA BADDR,I   GET LAST TWO CHARACTERS
      ALF,ALF
      AND B177      DELETE LAST CHARACTER
      JMP PROC1     STORE NEXT-TO-LAST CHARACTER
*
*  THIS SECTION PUTS COUNT IN A AND RETURNS TO P+2
*
      LDB M2        SET DELETE FLAG
CMPLT LDA 1         PUT CHARACTER COUNT IN A
      ISZ PROCS
      JMP PROCS,I
      SPC 5
*
*  SUBROUTINE  GETCH
*
*    RETURN IO P+1 ON EMPTY BUFFER
*    IF THE BUFFER IS NOT EMPTY, ELSE
*    RETURN TO P+2 WITH CHARACTER IN (A).
*
GETCH NOP
      CPB COUNT
      JMP GETCH,I   BUFFER EMPTY, P+1 RETURN
      LDA BADDR,I   GET TWO CHARACTERS
      SLB,RSS
      ALF,ALF       B EVEN, POSITION CHARACTER RIGHT
      SLB,INB       CHECK O/E, AND INDEX COUNT
      ISZ BADDR     B ODD, INCREMENT ADDRESS POINTER
FINSH AND B177      STRIP LEFT CHARACTER
      IOR B200      ADD BIT 7
      ISZ GETCH
      JMP GETCH,I   RETURN TO P+2
      HED 
*
*  INITIALIZES FOR OUTPUTTING A RECORD
*
INIT  NOP
      CCE,SSA       SET E=1, CHECK FOR (A) < 0
      CMA,CLE,INA   SET (E) = 0, (A) = -(A)
      STA COUNT     SAVE CHARACTER COUNT
      STB BADDR     SET BUFFER STARTING ADDRESS
      SZA
      SZB           LEADER/TRAILER ONLY?
      JMP *+4       NO
      LDA CLAI      YES, (B) = 0
      STA FINSH+1   SET CLEAR INSTRUCTION
      CLE           SET NO CR/LF
      CLB           INITIALIZE OUTPUT COUNT
      JMP INIT,I
      HED DATA, ADDRESSES, ETC.
*
*  COMMON DRIVER CONSTANTS AND ADDRESSES
*
M11   DEC -11
M3    DEC -3
M2    DEC -2
.2    DEC 2
.3    DEC 3
LNFD  OCT 12        LINE FEED
CRTN  OCT 15        CARRIAGE RETURN
EMODE OCT 33        ESCAPE
LFTAR OCT 137       LEFT ARROW
OMODE OCT 175       OBSOLETE ALT MODE
AMODE OCT 176       ALT MODE
B177  OCT 177       RUBOUT
B200  OCT 200
CLAI  CLA
IORI  IOR B200      ADD IN BIT 7
*
CRLFA DEF CRLF
CRLF  OCT 106612
*
BUFSA NOP           INITIAL BUFFER ADDRESS
BADDR NOP           CURRENT BUFFER ADDRESS
COUNT NOP           HOLDS RECORD LENGTH
EOTC  NOP           END-OF-TAPE COUNTER
*
*  BASE PAGE REFERENCE ENTRIES
*
      ORG 101B
      DEF I.STP,I   READER LINK INITIALIZED TO STOP
      DEF TTY.P     TTY OUTPUT ENTRY ADDRESS
      DEF 102B,I    PUNCH LINK INITIALIZED TO TTY
      DEF TTY.I     TTY INPUT ENTRY ADDRESS
I.STP NOP           LINK TO STOP ROUTINE
LWBM  NOP           LAST WORD OF USER SPACE
      NOP
FWAM  DEF 135B      FIRST WORD OF AVAILABLE MEMORY
LWAM  DEF TTY.I-1   LAST WORD OF AVAILABLE MEMORY
*
      ORG 123B
IMOFF DEF I.OFF     DISABLE KEYBOARD INTERRUPT
IMON  DEF I.ON      SET KEYBOARD INTERRUPT
TLINK DEF I.TTY+2000B    TTY INPUT INTERRUPT LINK
PLSTR DEF 103B,I    PLIST OUTPUT ADDRESS
LISTR DEF 102B,I    LIST DEVICE LINK
TLSTR DEF 102B,I    LIST OUTPUT ADDRESS
*
SYMTA EQU 117B
IOBFA EQU 131B      BUFFER ADDRESS
SBUFA EQU 134B      SYNTAX BUFFER ADDRESS
RDR   EQU 0
PNCH  EQU 0
TTY   EQU 0
TTYI  EQU TTY+1
