RESETVEKTOR CLR F1 ;Grafikflag = 0 JMP INIT INTERRUPTV DIS I JMP SERVICE --Interruptserviceroutine-- SERVICE MOV A,#0FFH OUTL P2,A SEL RB1 CALL RECCOM ;Kommando holen MOV R0,#20H MOV A,#40H ;prüfen, ob der Drucker XRL A,R0 ;adressiert ist; JNZ RET ;wenn Ja, dann mit MOV A,#41H ;'ACK' CALL SENDBYTE ;Kommando quittieren INC R0 MOV A,#53H ;'Status' 7 XRL A,R0 JZ STATUS XRL A,#04H ;'Write' ? JZ RECDATA MOV A,#45H ;'Error' CALL SENDBYTE ;an Rechner senden RET JMP RET SEL RB0 CLR A EN I RETR STATUS MOV A,#43H CALL SENDBYTE MOV A,#50H CALL SENDBYTE MOV A,#2EH CALL SENDBYTE MOV A,#4FH CALL SENDBYTE MOV A,#4BH CALL SENDBYTE MOV A,#19H CALL SENDBYTE JMP RET RECDATA INC R0 ;empfängt eine vom Rechner MOV A,R0 ;angegebene Anzahl von Bytes MOV R2,#29H ;und legt sie im Druckpuffer, XRL A,#4EH ;beginnend bei 28h ab. JZ REC ;R4 zeigt anschließend auf das MOV R2,#15H ;Pufferende. MOV A,R0 XRL A,R0 JZ REC MOV A,#1EH REC MOV R0,#27H MOV A,R2 MOV R3,A RECL INC R0 CALL RECBYTE MOV R0,A MOV A,#03H CALL WAIT-N ;warten,bis letztes Bit des DJNZ R2,RECL ;letzten Zeichens gesendet ist MOV A,#40H CALL WAIT-N ;"Höflichkeitspause" MOV A,#41H CALL SENDBYTE ;'ACK' senden MOV A,#27H ADD A,R3 SEL RB0 MOV R4,A ;R4:= Pufferende +1 MOV R0,#27H JMP RET RECCOM MOV R0,#20H ;Kommando empfangen und in MOV R2,#00H ;20h-24h ablegen MOV R3,#04H CLOOP CALL RECBYTE MOV R0,A NOP CLR C ADD A,R2 ADC A,#00H MOV R2,A MOV A,#04H CALL WAIT-N INC R0 DJNZ R3,CLOOP CALL RECBYTE MOV R0,A INC R0 XRL A,R2 MOV R0,A ;25h = 0 bei korrektem JMP * ;Empfang des Kommandos MOV A,#10H CALL WAIT-N MOV R0,#20H RET WAIT-N DEC A ;Verzögerung um N*9 Mikrosekunden WLOOP NOP ;(inklusive Aufruf und RET) NOP NOP DEC A JNZ WLOOP RET RECBYTE MOV R6,#08H ;empfängt ein Byte MOV R7,#00H ;vom Rechner WAITSTART IN A,P2 ;der Empfang läuft synchron ANL A,#40H ;zum Sendetakt des Rechners JNZ WAITSTART RLOOP JT0 * JT0 * IN A,P2 ANL A,#40H ORL A,R7 RR A MOV R7,A DJNZ R6,RLOOP RL A RL A RET SENDBYTE MOV R7,A ;ein Byte an Rechner senden MOV R6,#08H ;(asynchron) MOV A,#7FH OUTL P2,A ;Startbit senden NOP NOP SLOOP NOP MOV R4,#0CH DJNZ R4,* ;Verzögerung MOV A,R7 RR A MOV R7,A ORL A,#7FH OUTL P2,A DJNZ R6,SLOOP NOP MOV R4,#0CH DJNZ R4,* MOV A,#0FFH OUTL P2,A ;Stopbit senden MOV R4,#20H ;und DJNZ R4,* ;verzögern RET --Unterprogramme-- GETCHAR INC R0 MOV A,R4 XRL A,R0 ;Pufferende erreicht JNZ CEOL SEL RB1 MOV A,#43H ;'Complete' CALL SENDBYTE ;senders SEL RB0 WAITD MOV A,R4 XRL A,R0 JZ WAITD MOV A,R4 XRL A,R0 JZ WAITD JMP GETCHAR CEOL MOV A,#98H XRL A,R0 ;'EOL' JNZ GRET ;dann MOV A,R0 ;Pufferende INC A ;auf (R4+1) MOV R4,A ;setzen. GRET MOV A,R0 RET OUTBYTE IN A,P2 ANL A,#20H ;warten, bis JNZ OUTBYTE ;BUSY inaktiv ist CHKA IN A,P2 ANL A,#10H ;warten, bis JZ CHKA ;/ACK inaktiv ist MOV A,R0 OUTL P1,A MOVD P7,A ;/STR-Impuls an PIN25 erzeugen RET DECG MOV A,R2 ;Grafikzähler erniedrigen JZ DECR1 ;und gegebenenfalls MOV A,R1 ;Grafikflag löschen JNZ DECR1 DEC R2 DECR1 DEC R1 MOV A,R1 JNZ RETD ADD A,R2 JNZ RETD CLR F1 RETD RET --Hauptprogramm-- INIT EN I ;Interrupt freigeben und MOV A,#0FFH ;Port 2 initialisieren OUTL P2,A SEL RB0 MOV R0,#50H MOV R4,#50H CLR A MOV R1,A MOV R2,A MOV R3,A WAITST MOV A,R4 ;warten,bis zum ersten Hal XRL A,R0 ;Druckdaten empfangen wurden JZ WAITST MOV A,R4 XRL A,R0 JZ WAITST MAIN CALL GETCHAR ;Beginn der Hauptschleife JF1 GRAPH MOV A,R3 ANL A,#80H ;ESC-Sequenz JNZ ESCSEQ MOV A,#98H XRL A,R0 ;'EOL' JNZ NOEOL MOV R0,#00H ;'CR' CALL OUTBYTE MOV R0,#0AH ;'LF' CALL OUTBYTE JMP MAIN NOEOL MOV A,#1BH XRL A,R0 JNZ NOESC ;MSB R3=1 bedeutet, dass als MOV A,#80H ;letztes Zeichen ESC gesendet ORL A,R3 ;wurde (siehe oben bei 11A) MOV R3,A ;MSB in R3 setzen NOESC CALL OUTBYTE JMP MAIN ESCSEQ MOV A,#4BH ;'K' - ESC-Sequenz analysieren XRL A,R0 JZ GRM1 MOV A,#4CH ;'L' XRL A,R0 JZ GRM1 MOV A,#59H ;'Y' XRL A,R0 JZ GRM1 MOV A,#5AH ;'Z' XRL A,R0 JZ GRM1 MOV A,#2AH ;'*' XRL A,R0 JZ GRM2 MOV A,#5EH ;'^' (9-Nadel-Grafik) XRL A,R0 JNZ CLESC ;keine grafikrelevante Sequenz MOV A,#20H ORL A,R3 ;Bit R3.5 setzen ;indiziert MOV R3,A ;9-Nadel-Modus GRM2 MOV A,R3 ANL A,#F0H ORL A,#03H MOV R3,A JMP SETGR GRM1 MOV A,R3 ANL A,#F0H ORL A,#02H MOV R3,A SETGR CLR F1 CPL F1 ;Grafikmodus einschalten MOV A,R3 ANL A,#03H MOV R1,A CLESC MOV A,#7FH ANL A,R3 MOV R3,A JMP NOESC GRAPH CALL OUTBYTE MOV A,#03H ;überprüfen, ob noch Parameter ANL A,R3 ;zu übernehmen sind JZ NORM XRL A,#03H ;LSD (R3) =3, dann ist (R0) JZ DECR3 ;Grafikmodus XRL A,#01H ;LSD (R3) =1, JNZ LASTP ;dann ist (R0) = MOV A,R1 ;LOWBYTE des Grafikzählers ADD A,R0 MOV R1,A CLR A RLC A MOV R2,A ;übertrag in R2 JMP DECR3 LASTP MOV A,R2 ;(R0)=HIGHBYTE des Grafikzählers ADD A,R0 MOV R2,A MOV A,R3 ANL A,#20H ;9-Nadel-Grafik JZ DECR3 ;dann MOV A,R1 ;Grafikzähler verdoppeln ADD A,R1 ;anschließend einmal MOV R1,A ;dekrementieren, da der Grafik- MOV A,R2 ;zähler hier noch 'verläuft' ADC A,R2 MOV R2,A NORM CALL DECG MOV A,R3 ;anschließend: ANL A,#0FH ;Flag für 9-Nadel-Grafik MOV R3,A ;löschen DEC R3 CALL DECG JMP MAIN