TITLE 'TEACH MORSE CODE' * TEACH MORSE CODE * COPYRIGHT (C) 1976, HOWARD CUNNINGHAM * REVISION HISTORY * * 10/02/76 INITIAL VERSION ADAPTED FROM 6800 * 10/07/76 DOUBLE WEIGHT IF AVERAGE > 90 PCT. ADDED. * 10/07/76 LETTER PROBABILITY NEVER ZERO ADDED. * 12/06/76 REVISED RANDOM AND REMOVED PUNCTUATION * TO SAVE SPACE IN 512 BYTE ROM. * 03/23/77 CORRECT TYPO IN DOUBLE WEIGHT PROBABILITY. * ASSEMBLY CONSTANTS LINE EQU 62 TERMINAL LINE LENGTH FREQ EQU 2000 MACHINE CYCLES PER MSEC WPM EQU 15 CHARACTER TRANSMISSION SPEED IDLE EQU 3*50 IDLE RESPONSE WAIT MAXNUM EQU 26+10 MAXIMUM NUMBER OF CHARACTERS PPIM EQU 0FH 8255 MODE SELECT * MONITOR SUBROUTINE ENTRIES CO EQU 8009H COMMAND OUTPUT CI EQU 8003H COMMAND INPUT CSTS EQU 8012H COMMAND INPUT STATUS EJECT ORG 40H RAM * GLOBAL DATA SEED DW 1234H RANDOM NUMBER (MUST BE NON-ZERO) NUM DW ERROR+4 SIZE OF CURRENT ALPHABET GIVE DB IDLE RESPONSE WAIT TIME IN SEC/50 TOLD DB 0 255 IF STUDENT WAS TOLD LETTER, 0 OTHERWISE COLUMN DB LINE PRINT POSITIONS REMAINING ON LINE * OBJECT TIME STACK DS 30 STACK DS 0 * ERROR RATE FUNCTION ORG 100H (MUST ORG AT MULTIPLE OF 100H) ERROR DB 255 TOTAL ERROR RATE DS MAXNUM * ENTRY POINT (FWA ROM) ORG 200H BEGIN JMP TEACH * CHARACTER CODE TABLES MORSE EQU *-1 DB 11011000B,11000100B,11001000B,11010000B DB 11111100B,11110100B,11100100B,11110000B DB 01111100B,01111000B,01101000B,01110000B DB 01001000B,01010000B,01100000B,11100000B DB 10000100B,10001000B,10011000B,10010000B DB 10111000B,10101000B,10110000B,10100000B DB 00111100B,00011100B,00101000B,00110000B DB 00001100B,00000100B,00011000B,00001000B DB 00010000B,00100000B,11000000B,01000000B ASCII DB 25H OVERALL PERCENTAGE DB 'Q7ZG' DB '098O' DB '1JPW' DB 'LRAM' DB '6BXD' DB 'YCKN' DB '23FU' DB '45VH' DB 'SITE' EJECT * MAIN PROGRAM TEACH * * ENTRY VIA JUMP. STACK POINTER IS REINITIALIZED. * INTERRUPTS ARE NOT USED. TEACH LXI S,STACK CALL PRESET TEA1 CALL GRAPH TEA2 CALL SELECT MVI A,0 STA TOLD CLEAR STUDENT TOLD FLAG TEA3 CALL SEND PUSH D CALL CSTS LOOK FOR ENTRY WHILE SENDING ANA A JZ TEA4 CALL CI DISCARD CHARACTER TEA4 MVI B,0 CLEAR RESPONSE TIME COUNTER MVI C,0 CLEAR CORRECT RESPONSE FLAG TEA5 PUSH B CALL RANDOM MIX UP NUMBERS CALL CSTS ANA A JZ TEA6 IF NO RESPONSE YET CALL CI GET CHARACTER POP B POP D CPI 0DH CR JZ TEA1 IF GRAPH COMMAND LXI H,ASCII-ERROR DAD D CMP M PUSH D JNZ TEA5 IF WRONG GUESS MOV C,A SET CORRECT RESPONSE FLAG JMP TEA7 TEA6 MVI C,20 CALL WAIT KILL SOME TIME POP B MOV A,B INR A MOV B,A ADVANCE TIME COUNTER LDA GIVE CMP B JNZ TEA5 IF SOME TIME LEFT LXI H,TOLD MVI M,255 RECORD TIMEOUT TEA7 MOV A,B COMPUTE NEW SPEED POP D STC CMC RAL RESPONSE TIME X 2 JNC TEA8 MVI A,255 SET TO MAXIMUM ON OVERFLOW TEA8 LXI H,GIVE MOV B,M CALL WEIGHT ADJUST SPEED MOV M,A LXI H,ASCII-ERROR DAD D PUSH B SAVE ANSWER MOV C,M CALL PRINT OUTPUT CORRECT ANSWER MVI C,' ' CALL PRINT DOUBLE SPACE MVI C,250 CALL WAIT POP B MOV A,C ANA A JZ TEA3 IF INCORRECT, TRY IT OVER CALL GRADE JMP TEA2 SPC 4 * SUBROUTINE PRESET * * INITIALIZE I/O AND GLOBAL VARIABLES PRESET LXI H,ERROR+MAXNUM PRE1 MVI M,255 SET ERRORS TO MAXIMUM DCR L JNZ PRE1 MVI M,256*30/100 GUESS AVERAGE OF 70 PERCENT LXI H,ERROR+4 SHLD NUM MINIMUM ALPHABET MVI A,IDLE STA GIVE AVERAGE SPEED LXI H,1234H SHLD SEED NON-ZERO RANDOM SEED MVI A,0A6H OUT PPIM PROGRAM MODE 1 OUTPUT RET SPC 4 * SUBROUTINE RANDOM * * TAUSWORTH GENERATOR USING PRIMITIVE TRINOMIAL * X**15 + X + 1 WITH PERIOD 2**15 - 1. * RETURNS 0 < (D,E) < 2**15. RANDOM LXI H,SEED MOV A,M STC CMC RAL MOV D,A INX H MOV A,M RAR XRA M MOV M,A MOV A,D DCX H XRA M JNC RAN1 XRI 60H RAN1 MOV M,A MOV E,A RET SPC 4 * SUBROUTINE SELECT * * ON EXIT (D,E) CONTAINS A POINTER TO THE SELECTED * CHARACTER IN THE ERROR TABLE. PRESERVES NO REGISTERS. SELECT CALL RANDOM MOV A,D CMA MAKE RANDOM NUMBER NEGATIVE MOV D,A SEL1 LHLD NUM BEGIN SCAN SEL2 MOV C,M GET ERROR RATE MVI B,0 INX B INSURE PROBABILITY IS NEVER ZERO XCHG DAD B ADD ERROR TO RANDOM NUMBER RC STOP LOOP ON CARRY OUT XCHG DCR L JNZ SEL2 SCAN REMAINDER OF TABLE JMP SEL1 START OVER SPC 4 * SUBROUTINE SEND * * THE CHARACTER REFERENCED BY (D,E) IS SENT AS MORSE CODE. * ON EXIT D,E ARE PRESERVED. SEND LXI H,MORSE-ERROR DAD D MOV B,M GET MORSE LETTER SEN1 MOV A,B STC CMC RAL GET NEXT ELEMENT IN CARRY MOV B,A MVI C,1200/WPM ONE DIT TIME IN MSEC JNC SEN2 MVI C,3*1200/WPM ONE DAH TIME SEN2 ANA A RZ IF LAST BIT WAS STOP BIT CALL BEEP MVI C,1200/WPM INTER-ELEMENT SPACE CALL WAIT JMP SEN1 LOOP FOR REMAINING BITS SPC 4 * SUBROUTINE WAIT * * DELAY C MSEC. ON EXIT A AND C ARE ZERO, * ALL OTHER REGS ARE PRESERVED. WAIT MVI A,FREQ/16 WAI1 DCR A JNZ WAI1 LOOP FOR A MSEC DCR C JNZ WAIT IF MORE MSEC TO GO RET SPC 4 * SUBROUTINE BEEP * * DELAY C MSEC WHILE GENERATING A 1000HZ SIDETONE. * OUTPUT IS ON 8255 PORT PC4. * ENTRY/EXIT SAME AS WAIT. BEEP MVI A,FREQ/16/2 BEE1 DCR A JNZ BEE1 LOOP FOR 1/2 MSEC MVI A,1001B SET PC4 OUT PPIM LOW TO HIGH ON OUTPUT BEE2 MVI A,FREQ/16/2 BEE3 DCR A JNZ BEE3 LOOP FOR SECOND 1/2 MSEC MVI A,1000B CLEAR PC4 OUT PPIM HIGH TO LOW ON OUTPUT DCR C JNZ BEEP IF MORE MSECS TO GO RET SPC 4 * SUBROUTINE WEIGHT * * COMPUTES A WEIGHTED MOVING AVERAGE * AS FOLLOWS, A = .875 * B + .125 * A * ALL OTHER REGS ARE PRESERVED. WEIGHT ADD B RAR (A+B)/2 ADD B RAR ((A+B)/2+B)/2 ADD B RAR (((A+B)/2+B)/2+B)/2 RET SPC 4 * SUBROUTINES RETURN, PRINT * * OUTPUT CR/LF OR CHARACTER IN C. * ON EXIT D,E AND A ARE PRESERVED. RETURN LXI H,COLUMN MVI M,LINE+2 MVI C,0DH CR CALL PRINT MVI C,0AH LF PRINT PUSH D PUSH PSW CALL CO POP PSW POP D LXI H,COLUMN DCR M JZ RETURN LOCAL CR/LF RET SPC 4 * SUBROUTINE GRADE * * INDIVIDUAL AND TOTAL ERROR RATES ARE * COMPUTED. THE SIZE OF THE ALPHABET IS * INCREASED IF PERFORMANCE IS ADAQUATE. * ON ENTRY D,C POINTS TO CHARACTER ERROR TABLE * ENTRY, (TOLD) IS 0 FOR CORRECT OR 255 FOR INCORRECT. GRADE LDA TOLD XCHG MOV B,M CALL WEIGHT ADJUST INDIVIDUAL RATE MOV M,A XCHG LXI H,ERROR LDA TOLD MOV B,M CALL WEIGHT ADJUST AVERAGE RATE MOV M,A CPI 256*30/100 JNC GRA3 IF BAD AVERAGE CPI 256*10/100 JNC GRA0 IF GOOD, BUT NOT GREAT XCHG MOV B,M LDA TOLD CALL WEIGHT COUNT SCORE TWICE IF HOT MOV M,A GRA0 LHLD NUM MVI A,256*40/100 GRA1 CMP M JC GRA3 IF BAD INDIVIDUAL RATE DCR L JNZ GRA1 GRA2 LXI H,NUM CHECK FOR COMPLETE ALPHABET MVI A,MAXNUM CMP M JZ GRA3 INR M ADD LETTER GRA3 RET SPC 4 * SUBROUTINE GRAPH * * THE PREDICTOR FUNCTION IS DISPLAYED. * ALL REGISTERS ARE DESTROYED. GRAPH LHLD NUM XCHG GPH1 CALL RETURN LXI H,ASCII-ERROR DAD D MOV C,M GET ASCII FOR CURRENT CHARACTER CALL PRINT MVI C,' ' MOV H,D MOV L,E MOV A,M B IS ERROR RATE GPH2 CALL PRINT PRINT BAR GRAPH MVI C,'*' SUI 255/LINE+1 JNC GPH2 IF A IS STILL POSITIVE MVI C,250 CALL WAIT SLOW DOWN FOR FAST DISPLAYS DCR E JP GPH1 LOOP FOR ALL BARS CALL CI JMP RETURN END