;  *****************************************************
;  *               P C - C O M  V1.1          4Mhz     *
;  * Unterstuezt INSTAT, OUTSTAT, COM$ und simuliert   *
;  * einen CE-125 Drucker (LPRINT und LLIST moeglich)  *
;  * P26/Dout, P27/STR, P25/Din, P24/ACK               *
;  *****************************************************

;  Hauptroutine, erkennt die einzelnen Befehle und
;  ruft die entsprechenden Unterprogramme auf.
        jmp  Start        ;Programstart nach Reset
        nop               ;Platzhalter
        jmp  Break        ;Interupt erkannt
Start   anl p2,#11001110b ;Din, Ack und TxD auf Lowpegel
        eni               ;Interupt erlauben
Back    call Liespc       ;Befehlsbyte einlesen
        mov  r2,a         ;und merken
        add  a,#89H       ;INSTAT?
        jz   Instat       ;Wenn ja dann springen
        mov  a,r2         ;Befehlsbyte zurueckholen
        add  a,#8FH       ;OUTSTAT?
        jz   Outstat      ;Wenn ja dann springen
        mov  a,r2         ;Befehlsbyte zurueckholen
        add  a,#D5H       ;COM$?
        jz   com          ;Wenn ja dann springen
        mov  a,r2         ;Byte zurueckholen
        add  a,#FDH       ;ist es ETX?
        jz   back         ;wenn ja dann unterdruecken
        mov  a,r2         ;Byte zurueckholen
        call Crlf         ;Fuegt vor jedem CR ein LF ein
;        call RS232W       ;Kein Befehl
        call Centr
        jmp  Back         ;Auf zum naechsten Byte

;  Startet den MCS48 bei einem All-Clear neu
Break   clr  a
        mov  PSW,a
Brlop   jni  Brlop        ;Warten bis der PC All-Clear loescht
        call Enint        ;Interupts freigeben
        jmp Start         ;Neustart
Enint   retr


;  Liest ein Byte vom PC und schreibt es auf Port1 des 8039
Outstat call Liespc       ;Datenbyte von Outstat einlesen
        outl p1,a         ;und auf Port1 ausgeben
        call Liespc       ;Endekennung einlesen
        add  a,#F3H       ;War es 0DH?
        jnz  Error        ;Wenn nein dann Fehler
        jmp  Back         ;Naechsten Befehl

;  Liest Port1 vom 8039 und sendet das Byte zum PC
Instat  call Wait         ;auf den PC1245/51 warten
        in   a,p1         ;Port1 einlesen
        call Writepc      ;und zum Sharp senden
        call Wait         ;Der Sharp ist langsam!
        mov  a,#0DH       ;Endekennung laden
        call Writepc      ;und absenden
        jmp  Back         ;Naechsten Befehl

;  Warteschleife, wird immer aufgerufen bevor ein Byte
;  zum PC1245/51 gesendet wird
Wait    mov r1,#FFH       ;Kurze Warteroutine damit
Ulop    djnz r1,Ulop      ;der PC mitkommt
        ret

;  Senderoutine P26/Dout, P27/STR, P25/Din, P24/ACK
;  Benutzt R0,R2,R3,Akku
Writepc anl p2,#11011111b ;Datenbit loeschen
        mov  r3,#08H      ;Bytezaehler setzen
        mov  r2,a         ;Datenbyte merken
Wnext   mov  a,r2         ;Datenbyte aus R2 holen
        rrc  a            ;Datenbit in Carry, Bit 0 zuerst
        mov  r2,a         ;Die restlichen Datenbits merken
        jnc  Nullb        ;Wenn Carry=0 naechsten Befehl ueberspringen
        orl p2,#00100000b ;Sonst Din setzen
Nullb   orl p2,#00010000b ;ACK auf Highpegel
        mov  r0,#80H      ;maximale Wartezeit
Wwait   in a,p2           ;Port2 fuer STR einlesen
        rlc  a            ;STR in Carry schieben
        jc   Strokay      ;Wenn STR=1 dann weiter
        djnz r0,Wwait     ;auf STR warten
        jmp  Brk          ;Kein STR Sharp unterbrach uebertragung
Strokay anl p2,#11101111b ;ACK loeschen
Pwait   in a,p2           ;Wurde STR
        rlc  a            ;geloescht?
        jc   Pwait        ;Wenn nein dann warten
        anl p2,#11011111b ;Datenbit loeschen
        djnz r3,Wnext     ;Fuer alle acht Bits wiederholen
        ret               ;Fertig

;  Bringt das PSW in den Anfangszustand
Brk     mov a,#00000000b  ;Stack zuruecksetzen
        mov PSW,a
        jmp 0             ;Neustart

;  Dem PC1245/51 wird mitgeteilt das ein Fehler
;  erkannt wurde. Dann wird neu gestartet.
Error   orl p2,#00100000b ;Din wird zur Fehlermeldung gesetzt
        mov r2,#80H       ;warten
Err1    mov r3,#FFH
Err2    djnz r3,Err2
        djnz r2,Err1
        jmp  Brk          ;Stack zuruecksetzen und neu starten


;  Liest ein Byte vom PC1245/51
;  P26/Dout, P27/STR, P25/Din, P24/ACK
;  Benutzt R0,R2,R3,Akku
Liespc  mov  r3,#08H      ;Bytezaehler setzen
Again   in a,p2           ;Dout und STR einlesen
        rlc a             ;STR in Carry schieben
        jnc Again         ;Warten bis STR=1
        orl p2,#00010000b ;Ack setzen
        rlc a             ;Datenbit in Carry
        mov a,r2          ;Zwischenpeicher in Akku holen
        rrc a             ;Bit in Akku schieben (LSB zuerst)
        mov r2,a          ;Die gelesenen Bits merken
        mov r0,#50H       ;600 Mikrosek. warten
Wlop    djnz r0,Wlop
        anl p2,#11101111b ;ACK zuruecksetzen
        djnz r3,Again     ;Acht mal wiederholen
        mov a,r2          ;Datenbyte in Akku
        ret               ;Fertig

;  Unterprogramm fuer COM$ Befehl gibt die Versionsnummer
;  auf dem PC aus (Text im Sharpcode ab String)
Com     call wait         ;Auf PC warten
        mov a,#String     ;Akku auf Stringanfang
        mov r5,a          ;und in R5 sichern
nexcom  movp a,@a         ;Byte einlesen
        jz endcom         ;Wenn null dann ende
        call Writepc      ;sonst ausgeben
        inc r5            ;Adresse auf naechstes Byte
        mov a,r5          ;Adresse in Akku
        jmp nexcom        ;Solange bis Stringende
endcom  call wait         ;Auf PC warten
        mov a,#0DH        ;Endekennung laden
        call Writepc      ;und ausgeben
        jmp back          ;Naechster Befehl

;  Centronics-Schnittstelle
;  Erwartet Datenbyte im Akku
;  Benutzt Port1 fuer Daten, P20 als Strobe und T0 fuer Busy
Centr    outl p1,a
         anl  p2,#11111110b    ;Strobe setzen
         orl  p2,#00000001b    ;Strobe zurueck setzen
Cenlop   jt0  Cenlop
         ret

;  RS232-Sender fuer 4 Mhz
;  Erwartet das Datenbyte im Akku
;  Register R5, R6, Akku
;  Voreinstellung fuer 1200Baud
;  Logisch 1 = 5 Volt
;  Benutzt P20 als Ausgang
; RS232W   call warten          ;nur solange kein Handshake
;          mov  r5,#08H         ;acht Datenbits
;          orl  p2,#00000001b   ;Startbit setzen
;          mov  r6,#6CH         ;6CH/1200b 34H/2400B 18H/4800B 
0AH/9600b 03H/19200B
; Rw1      djnz r6,Rw1          ;Warteschleife fuer Startbit
; Rsp1     clr  c               ;Zeitausgleich 1 Zyklus
;          rrc  a               ;Datenbit in Carry
;          jnc   Rsp2           ;Datenbit=1?
;          anl  p2,#11111110b   ;Ja
;          jmp  Rsp3
; Rsp2     orl  p2,#00000001b   ;Nein
; Rsp3     clr  c
;          clr  c
;          mov  r6,#6AH         ;6AH/1200B 32H/2400B 16H/4800B 
08H/9600b 01H/19200B
; Rw2      djnz r6,Rw2          ;Warteschleife fuer Datenbit
;          djnz r5,Rsp1         ;acht mal wiederholen
;          mov  a,#00H
;          mov  a,#00H
;          orl  p2,#00000001b   ; 1 Stopbit
;          mov  r6,#6CH         ;6CH/1200B 34H/2400B 18H/4800B 
0AH/9600B 03H/19200B
; Rw3      djnz r6,Rw3          ;Warteschleife fuer Stopbit
; rend     anl  p2,#11111110b   ;Stopbit zuruecksetzen
;          ret

; Nur voraebergehend wartet bis der Empfaenger fertig ist
warten   mov  r5,#0AH
war1     mov  r6,#FFH
war2     djnz r6,war2
         djnz r5,war1
         ret
; Das Unterprogramm ersetzt das vom Sharp gelieferte Byte 0DH
; durch die Bytes 0AH und 0DH (Carriage Return und Line Feed)
Crlf     mov r2,a       ;Byte merken
         add a,#F3H     ;Ist es eine Carriage Return?
         jnz trl        ;Sprung wenn nicht
         mov a,#0AH     ;Wenn Ja, ein Line Feed ausgeben
;         call RS232W
         call centr
trl      mov a,r2       ;altes Byte zurueckholen
         ret            ;Ruecksprung

String  .Byte 60H       ;PC-COM V1.0
        .Byte 53H       ;Text im Sharpformat kein ASCII!
        .Byte 36H
        .Byte 53H
        .Byte 5FH
        .Byte 5DH
        .Byte 11H
        .Byte 66H
        .Byte 41H
        .Byte 4AH
        .Byte 40H
        .Byte 00H       ;Endekennung

    Source: geocities.com/edgar_pue/sharp/files/pc1251

               ( geocities.com/edgar_pue/sharp/files)                   ( geocities.com/edgar_pue/sharp)                   ( geocities.com/edgar_pue)