        NAM     TEACH 
  
* TEACH MORSE CODE
* COPYRIGHT (C) 1976, HOWARD CUNNINGHAM 
  
* REVISION HISTORY
* 
*       06/10/76 INITIAL VERSION
*       04/11/77 DOUBLE WEIGHT IF AVERAGE > 90 PCT. ADDED 
*       04/11/77 LETTER PROBABILITY NEVER ZERO ADDED
*       08/17/78 CONVERTED TO TEK ASSEMBLER
  
        ORG     0 
        JMP     TEACH 
  
* ASSEMBLY CONSTANTS
  
ACIA    EQU     $DB10   ACIA ADDRESS
ON      EQU     $41     TONE ON 
OFF     EQU     $01     TONE OFF
LINE    EQU     70      TERMINAL LINE LENGTH
FREQ    EQU     625     MACHINE CYCLES PER MSEC 
WPM     EQU     15      CHARACTER TRANSMISSION SPEED
IDLE    EQU     3*50    IDLE RESPONSE WAIT
  
* GLOBAL DATA 
  
NUM     FDB     4       NUMBER OF CHARACTERS IN ALPHABET
GIVE    FCB     IDLE    RESPONSE WAIT TIME IN SEC/50
COLUMN  FCB     0       COLUMNS REMAINING BEFORE END OF LINE
TONE    FCB     OFF     SIDETONE STATE
SEED    FDB     $C0DE 
  
* CHARACTER TABLES
  
MORSE   EQU     *-1 
        FCB     %11011,%100011,%10011,%1011 
        FCB     %111111,%101111,%100111,%1111 
        FCB     %111110,%11110,%10110,%1110 
        FCB     %10010,%1010,%110,%111
        FCB     %100001,%10001,%11001,%1001 
        FCB     %11101,%10101,%1101,%101
        FCB     %111100,%111000,%10100,%1100
        FCB     %110000,%100000,%11000,%10000 
        FCB     %1000,%100,%11,%10
MAXNUM  EQU     *-1-MORSE 
  
ASCII   FCB     $25     OVERALL PERCENTAGE
        FCC     'Q7ZG'
        FCC     '098O'
        FCC     '1JPW'
        FCC     'LRAM'
        FCC     '6BXD'
        FCC     'YCKN'
        FCC     '23FU'
        FCC     '45VH'
        FCC     'SITE'
  
ERROR   FCB     256*30/100  ASSUME NOMINAL AVERAGE
        RMB     MAXNUM



* SUBROUTINE PRESET 
* 
*       INITIALIZE I/O AND GLOBAL VARIABLES.
  
PRESET  LDX     #MAXNUM 
        LDA A   #255
PRE1    STA A   ERROR,X WORST CASE ERROR PROBABILITIES
        DEX 
        BNE     PRE1
        LDA A   #256*30/100 ASSUME NOMINAL AVERAGE
        STA A   ERROR 
        LDX     #4
        STX     NUM     MINIMUM SIZE
        LDA A   #IDLE 
        STA A   GIVE    AVERAGE SPEED 
        RTS 
  
  
* SUBROUTINE RANDOM 
* 
*       TAUSWORTH GENERATOR USING PRIMITIVE TRINOMIAL 
*       X**15 + X**4 + 1  WITH PERIOD 2**15 - 1.
*       RETURNS 0 < (B,A) < 2**15.
*       REF COMM. ACM 11,9 (SEPT 68) 641-644
  
RANDOM  LDA A   SEED+1  W=SEED
        LDA B   SEED
        ASR B           X=SHIFT(W,-4) 
        ROR A 
        ASR B 
        ROR A 
        ASR B 
        ROR A 
        ASR B 
        ROR A 
        EOR A   SEED+1  Y=XOR(W,X)
        EOR B   SEED
        STA A   SEED+1
        STA B   SEED
        TAB             Z=SHIFT(Y,15-4) 
        ASL B 
        ASL B 
        ASL B 
        AND B   #$7F
        EOR B   SEED    SEED=XOR(Y,Z) 
        STA B   SEED
        RTS 



* MAIN PROGRAM TEACH
* 
*       ENTRY VIA POWER-UP RESET OR OTHERWISE; STACK POINTER
*       IS REINITIALIZED.  INTERRUPTS ARE NOT USED. 
  
TEACH   LDS     #STACK  ENTRY POINT 
        BSR     PRESET
TEA0    JSR     GRAPH 
TEA1    BSR     SELECT  SELECT AND
        CLR A           CLEAR ERROR FLAG
        PSH A 
TEA6    BSR     SEND    SEND CHARACTER
        TST     ACIA+1  CLEAR INPUT, IF ANY 
TEA2    LDA A   #1
        BIT A   ACIA
        BEQ     TEA3    IF NO RESPONSE YET
        LDA A   ACIA+1
        CMP A   #$D 
        BEQ     TEA0    IF SPECIAL COMMAND
        CMP A   ASCII,X 
        BNE     TEA2    IF WRONG GUESS
        BRA     TEA4
TEA3    LDA A   #20 
        BSR     WAIT
        INC B           ADVANCE TIME
        CMP B   GIVE
        BNE     TEA2    IF SOME TIME LEFT 
        PUL A           SET ERROR FLAG
        LDA A   #255
        PSH A 
TEA4    PSH A 
        LDA A   GIVE
        ASL B           COMPUTE NEW SPEED 
        BCC     TEA5
        LDA B   #255    SET TO MAX ON OVERFLOW
TEA5    BSR     WEIGHT  ADJUST SPEED
        STA A   GIVE
        LDA B   ASCII,X ANSWER
        BSR     PRINT 
        LDA B   #$20    SPACE 
        BSR     PRINT   DOUBLE SPACE
        LDA A   #250
        BSR     WAIT
        PUL A 
        CMP A   ASCII,X 
        BNE     TEA6    TRY LETTER OVER IF INCORRECT
        PUL A           GET ERROR FLAG
        BSR     GRADE   EVALUATE PERFORMANCE
        BRA     TEA1



* SUBROUTINE SELECT 
* 
*       ON EXIT X CONTAINS A CHARACTER POINTER SELECTED 
*       WITH PROBABILITIES PROPORTIONAL TO THEIR RESPECTIVE 
*       ERROR RATES.  REQUIRES AVERAGE ERROR
*       RATE > 5 FOR REASONABLE PROCESSING TIME.
  
SELECT  BSR     RANDOM
SEL1    LDX     NUM 
SEL2    SEC 
        SBC A   ERROR,X DECREMENT BY ERROR PROBABILITY
        SBC B   #0
        BMI     SEL3    IF RANDOM NUMBER HAS COUNTED PAST ZERO
        DEX 
        BNE     SEL2
        BRA     SEL1
SEL3    RTS 
  
  
* SUBROUTINE SEND 
* 
*       THE CHARACTER REFERENCED BY X IS TRANSMITTED
*       AS MORSE CODE. ON EXIT X IS PRESERVED, B IS ZERO. 
  
SEND    LDA B   MORSE,X GET MORSE BIT PATTERN 
        LSR B 
SEN1    LDA A   #ON 
        STA A   TONE
        LDA A   #1200/WPM DIT TIME IN MSEC
        BCC     SEN2
        LDA A   #3*1200/WPM DAH TIME
SEN2    BSR     WAIT
        LDA A   #OFF
        STA A   TONE
        BSR     PAUSE   INTER-ELEMENT SPACE 
        LSR B 
        BNE     SEN1    LOOP UNTIL ONLY STOP BIT REMAINS
        RTS 
  
  
* SUBROUTINES PAUSE, WAIT 
* 
*       DELAY ONE DIT TIME (PAUSE) OR A MSEC (WAIT).
*       ON EXIT A IS ZERO, B AND X ARE PRESERVED. 
  
PAUSE   LDA A   #1200/WPM 
WAIT    PSH B 
WAI1    LDA B   TONE
        STA B   ACIA
        LDA B   #FREQ/12 DELAY 1/2 MSEC 
WAI2    DEC B 
        BNE     WAI2
        LDA B   #OFF
        STA B   ACIA
        LDA B   #FREQ/12
WAI3    DEC B 
        BNE     WAI3
        DEC A 
        BNE     WAI1
        PUL B 
        RTS 
  
  
* SUBROUTINE WEIGHT 
* 
*       COMPUTES A WEIGHTED MOVING AVERAGE AS FOLLOWS,
*               A = .875 * A + .125 * B 
*       ON EXIT B IS DESTROYED. 
  
WEIGHT  PSH A 
        ABA 
        ROR A           (A+B)/2 
        PUL B 
        ABA 
        ROR A           ((A+B)/2+A)/2 
        ABA 
        ROR A           (((A+B)/2+A)/2+A)/2 
        RTS 
  
  
* SUBROUTINES RETURN, PRINT 
* 
*       OUTPUT CR/LF OR CHARACTER FROM B.  GENERATE LOCAL CR/LF 
*       WHEN REQUIRED.  ON EXIT A AND X ARE PRESERVED.
  
RETURN  LDA B   #LINE+2 RESET COLUMN COUNTER
        STA B   COLUMN
        LDA B   #$D 
        BSR     PRINT   OUTPUT CR 
        LDA B   #$A 
PRINT   PSH B 
        LDA B   #2
PRI1    BIT B   ACIA
        BEQ     PRI1    IF PREVIOUS CHARACTER INCOMPLETE
        PUL B 
        STA B   ACIA+1  SEND CHARACTER
        DEC     COLUMN
        BEQ     RETURN
        RTS 



* SUBROUTINE GRADE
* 
*       INDIVIDUAL AND TOTAL ERROR RATES ARE COMPUTED.
*       THE SIZE OF THE ALPHABET IS INCREASED IF
*       PERFORMANCE IS ADEQUATE.
*       ON ENTRY X IS CHARACTER POINTER, A IS 0 FOR CORRECT 
*       RESPONSE, 255 FOR INCORRECT OR NO RESPONSE. 
*       ON EXIT A, B AND X ARE DESTROYED. 
  
GRADE   PSH A 
        TAB 
        LDA A   ERROR,X 
        BSR     WEIGHT  ADJUST INDIVIDUAL RATE
        STA A   ERROR,X 
        LDA A   ERROR 
        PUL B 
        PSH B 
        BSR     WEIGHT  ADJUST AVERAGE RATE 
        STA A   ERROR 
        PUL B 
        CMP A   #256*30/100 
        BHI     GRA3    IF BAD AVERAGE
        CMP A   #256*10/100 
        BHI     GRA0    IF GOOD, BUT NOT GREAT
        LDA A   ERROR,X 
        BSR     WEIGHT  COUNT SCORE TWICE IF HOT
        STA A   ERROR,X 
GRA0    LDX     NUM 
        LDA A   #256*40/100 
GRA1    CMP A   ERROR,X CHECK INDIVIDUAL ERROR RATES
        BLS     GRA3    IF ANY ONE BELOW STANDARDS
        DEX 
        BNE     GRA1
GRA2    LDA A   #MAXNUM ADD NEW LETTER IF POSSIBLE
        CMP A   NUM+1 
        BEQ     GRA3
        INC     NUM+1 
GRA3    RTS 
  
  
* SUBROUTINE GRAPH
* 
*       THE PREDICTOR FUNCTION IS DISPLAYED.
*       ON EXIT A, B AND X ARE DESTROYED. 
  
GRAPH   LDX     NUM 
        INX 
GPH1    BSR     RETURN
        LDA B   ASCII-1,X CURRENT CHARACTER 
        BSR     PRINT 
        LDA B   #$20    SPACE 
        LDA A   ERROR-1,X 
GPH2    BSR     PRINT   PRINT BAR GRAPH 
        LDA B   #'* 
        SUB A   #255/LINE+1 
        BCC     GPH2    IF A STILL POSITIVE 
        DEX 
        BNE     GPH1    IF MORE BARS TO GO
GPH3    LDA A   ACIA
        ASR A 
        BCC     GPH3    PAUSE 
        BRA     RETURN



* STACK AREA
  
        RMB     15
STACK   EQU     *-1 
  
  
        END 
        MON 
