
        title   reass of if3000.rom
;       reass'd with raz8 v1.0 (c) jde 1989
;
; Interface fuer S3004 Centronics und Commodore
;
;       reass'd         : 19-Oct-89
;       last update     : 22-Oct-89
;       by Jonny Jonas
;
; Portbelegung
;
; P0  Speicher A8-A15
; P1  Speicher AD0-7
; P2  Daten Centronics
; P30 ATN
; P31 /STROBE
; P32 /ITXD
; P33 /IRTS
; P34 /IRXD
; P35 /ICTS
; P36 /BUSY
; P37 /DATA
;
; Speicherbelegung
;
;               0..0fh          ; R0..R15
tbufp1: equ     10h             ; Tastenbufferpointer 1
tbufp2: equ     11h             ; Tastenbufferpointer 2
tbuf:   equ     12h             ; Buffer 8 Bytes 12h..19h
bitz1:  equ     1ah             ; Bitzaehler RxD
rxdata: equ     1bh             ; Empfangsdaten von Schreibmaschine
pbufp1: equ     1ch             ; Druckerbuffer Pointer 1
pbufp2: equ     1dh             ; Druckerbuffer Pointer 2
pbuf:   equ     1eh             ; Druckerbuffer 48 Byte 1eh..4dh
zaehl1: equ     4eh             ; Zaehler 2 Byte
random: equ     50h             ; Speicher Random Codes 10 Bytes
mode1:  equ     5ah             ; bit 0 frei
;                               ; bit 1 Random Code Eingabe aktiv
;                               ; bit 2 1=Text Mode
;                               ; bit 3 1=ATN low gewesen
;                               ; bit 4 1=Sekundaer select
;                               ; bit 5 1=Timeout (kein Clock Bit)
;                               ; bit 6 1=Drucker selektiert
;                               ; bit 7 0=Centronics, 1=Commodore
hexbyt: equ     5bh             ; Zaehler HEX-Bytes/Zeile
mode2:  equ     5ch             ; bit 0 Printerbuffer voll
;                               ; bit 1 Zeichen im Printerbuffer
;                               ; bit 2 0=Textmode, 1=Graphicmode
;                               ; bit 3 1=Random Code ein
;                               ; bit 4 1=HEX-Dump Mode
;                               ; bit 5 1=Auto Linefeed
;                               ; bit 6 1=Init
;                               ; bit 7 1=Setup Mode
zanzah: equ     5dh             ; Zeilenanzahl in BCD
zzaehl: equ     5eh             ; Zeilenzaehler in BCD
zschrt: equ     5fh             ; Anzahl 1/2 Zeilenschaltungen fuer LF
;               60h..7fh        ; Stack 20 Byte
;
; Konstanten
;
o:      equ     7000h
esc:    equ     27
;
        org     0800h
;
        jp      o+p32int        ; p32
        db      0,0,0           ; p33
        db      0,0,0           ; p31
        jp      o+atnint        ; p30 ATN Commodore
        db      0,0,0           ; t0
        jp      o+t1int         ; t1
;
start:  di
        srp     #0
        ld      r8,#10h
        ld      r9,#72h
zero:   clr     @8
        inc     r8
        djnz    r9,zero
        ld      zanzah,#72h
        ld      p2,#0           ; Daten Centronics
        ld      p3,#11001111b
        ld      r8,#.h(initab)
        ld      r9,#.l(initab)
        ld      r10,#0f1h
        ldc     r11,@rr8
        incw    8
initi:  ldci    @r10,@rr8
        djnz    r11,initi
        ld      tbufp1,#tbuf
        ld      tbufp2,#tbuf
        call    clrpbu          ; Printerbuffer loeschen
        call    irq0fg+o        ; IRQ0 freigeben
        or      imr,#00001000b  ; IRQ3 freigeben
        jp      init1
;
initab: db      15,0,0,3,0,3,0ffh,21h,96h,14h,0,30h,0,0,0,80h
;
tbtxt:  db      0,0,0,1fh,0,0,0,0,8,9,0ah,0,0ch,1fh,0,0
        db      0,0,0,0,0,15h,0,0,18h,19h,0,1bh,0,0,0,0dh
        db      ' !"#$%&',27h,'()*+,-./'
        db      '0123456789:;',0,'=',0,'?'
        db      '@ABCDEFGHIJKLMNO'
        db      'PQRSTUVWXYZ',0,0,0,0,'_'
        db      '`',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        db      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7fh
        db      0,0,0,0,0,0,0,0,0,0,0,0,0,0dh,0,0
        db      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        db      ' ',0,0,0,0,0,0,0,0,0,0,0,13h,10h,3,15h
        db      0,14h,0,0,0,0,0,0,0,0,0,'[\]~',2
        db      '`',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        db      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        db      ' ',0,0,0,0,0,0,0,0,0,0,0,13h,10h,3,15h
        db      0,14h,0,0,0,0,0,0,0,0,0,'{|}~',0
;
tbgrph: db      0,0,0,1fh,0,0,0,0,8,9,0ah,0,0ch,1fh,0,0
        db      0,0,0,0,0,15h,0,0,18h,19h,0,1bh,0,0,0,0dh
        db      ' !"#$%&',27h,'()*+,-./'
        db      '0123456789:;',0,'=',0,'?'
        db      '@abcdefghijklmno'
        db      'pqrstuvwxyz{|}~_'
        db      '`ABCDEFGHIJKLMNO'
        db      'PQRSTUVWXYZ[\]',0,7fh
        db      0,0,0,0,0,0,0,0,0,0,0,0,0,0dh,0,0
        db      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        db      ' ',0,0,0,0,0,0,0,0,0,0,0,13h,10h,3,15h
        db      0,14h,0,0,0,0,0,0,0,0,0,'{|}~',2
        db      '`ABCDEFGHIJKLMNO'
        db      'PQRSTUVWXYZ[\]',0,0
        db      ' ',0,0,0,0,0,0,0,0,0,0,0,13h,10h,3,15h
        db      0,14h,0,0,0,0,0,0,0,0,0,'{|}~',0
;
tb3004: db      0,0,19h,46h,0,0,0,0             ; 00
        db      72h,79h,9fh,0,0ch,78h,0,0       ; 08
        db      6,27h,45h,44h,7,29h,15h,23h     ; 10
        db      7ah,7bh,0,1bh,0,0,0,77h         ; 18
        db      71h,42h,43h,41h,48h,4,2,17h     ; 20
        db      1dh,1fh,1bh,25h,64h,62h,63h,40h ; 28
        db      0dh,11h,10h,0fh,0eh,0ch,0bh,0ah ; 30
        db      9,8,13h,3bh,0,2eh,0,35h         ; 38
        db      3dh,30h,18h,20h,14h,34h,3eh,1ch ; 40
        db      12h,21h,32h,24h,2ch,16h,2ah,1eh ; 48
        db      2fh,1ah,36h,33h,37h,28h,22h,2dh ; 50
        db      26h,31h,38h,3fh,3ch,3ah,19h,1   ; 58
        db      2bh,61h,4eh,57h,53h,5ah,49h,60h ; 60
        db      55h,5,4bh,50h,4dh,4ah,5ch,5eh   ; 68
        db      5bh,52h,59h,58h,56h,5dh,4fh,4ch ; 70
        db      5fh,51h,54h,65h,66h,67h,47h,7fh ; 78
        db      0,67h,44h,0,65h,0,0,45h         ; 80
        db      0,0,46h,0,0,0,3fh,0             ; 88
        db      0,0,0,0,66h,0,0,0               ; 90
        db      0,3ch,3ah,0,6,0,0,0             ; 98
        db      0,0,0,0,0,0,0,0                 ; a0
        db      0,0,0,0,0,0,3,29h               ; a8
        db      23h,0,0,27h,0,0,0,0             ; b0
        db      0,0,0,0,0,0,0,0                 ; b8
        db      0,0,0,0,0,0,0,0                 ; c0
        db      0,0,0,0,0,0,0,0                 ; c8
        db      0,0,0,0,0,0,0,0                 ; d0
        db      0,0,0,0,0,0,0,0                 ; d8
        db      0,47h,0,0,0,0,7,0               ; e0
        db      0,0,0,0,0,0,0,0                 ; e8
        db      0,0,0,0,0,0,0,0                 ; f0
        db      39h,0,0,0,0,15h,0,0             ; f8
;
init1:  call    out91
        ld      r8,#96h
        call    print
        ld      r8,#0
        call    print
        ld      r14,#100        ; Laenge
        call    bell1
;
mainlp: tm      mode2,#42h      ; Init oder Zeichen im Printerbuffer
        jr      nz,tasbe1       ; ja
        decw    zaehl1
        jr      nz,tasbe1
        call    out92           ; Code 92h senden (Parameter holen)
tasbe1: call    serin1+o        ; Zeichen aus Tastenbuffer holen
        jr      nc,bufout       ; kein Zeichen da
        tm      mode2,#80h      ; Setup Mode?
        jr      z,tasbe2        ; nein
        call    chktas
        jr      c,tasbe1        ; erlaubtes Zeichen
        and     mode2,#7fh      ; Setup Mode Flag loeschen
tasbe2: ld      r14,#.h(spetab)
        ld      r15,#.l(spetab)
tasbe3: ldc     r9,@rr14        ; Code aus Tabelle
        and     r9,r9
        jr      z,tasbe4        ; Tabellenende
        incw    rr14
        ldc     r10,@rr14       ; JP Adresse aus Tabelle
        incw    rr14
        ldc     r11,@rr14
        incw    rr14
        cp      r8,r9           ; Vergleich Tastencode mit Tabellencode
        jr      nz,tasbe3       ; ungleich
        ld      r14,r10
        ld      r15,r11
        call    out91x
        jp      @rr14
;
tasbe4: call    zabein
        cp      r8,#83h         ; Zeilenzaehler loeschen
        jr      nz,tasbe5
        clr     zzaehl
tasbe5: call    zzaeh           ; Zeilen zaehlen
bufout: call    input+o
        tm      p3,#8           ; RTS
        jr      nz,mainlp       ; RTS high Sendeverbot
        call    getprb          ; Zeichen aus Printerbuffer holen
        jr      nc,mainlp       ; Buffer leer
        tm      mode2,#40h      ; Init?
        jr      z,bufou1        ; nein
        push    r8
        call    out91x
        pop     r8
bufou1: ld      r12,r8
        tm      mode1,#80h      ; Centronics Mode
        jr      z,bufou4        ; ja
        inc     r8              ; Zeichen=0ffh?
        jr      nz,bufou2       ; nein
        or      mode2,#4        ; Graphic Mode einschalten
        jr      mainl1          ; naechstes Zeichen holen
;
bufou2: dec     r8
        ld      r10,#.h(tbtxt)  ; Codetabelle Textmode
        ld      r11,#.l(tbtxt)
        tm      mode2,#4        ; Graphic Mode
        jr      z,bufou3        ; nein
        ld      r10,#.h(tbgrph) ; Codetabelle Graphicmode
        ld      r11,#.l(tbgrph)
bufou3: call    comasc          ; wandeln Commodore in ASCII
        and     r8,r8
        jr      z,hexdm         ; Illegaler Code
bufou4: call    to3004          ; wandeln in 3004 Code
hexdm:  tm      mode2,#10h      ; HEX-Dump Mode?
        jr      z,escap         ; nein
        ld      r8,r12
        call    hexout
        ld      r8,#' '
        tm      mode2,#4        ; Graphic Mode
        jr      z,hexdm1        ; nein
        and     mode2,#0fbh     ; Textmode einschalten
        ld      r8,#'*'
hexdm1: call    printu          ; ASCII Drucken
        dec     hexbyt
        jr      nz,mainl1
        ld      hexbyt,#16
        call    crlf
mainl1: jp      mainlp
;
escap:  and     mode2,#0fbh     ; Graphicmode ausschalten
        cp      r12,#esc
        jr      nz,bufou5
;
; Bearbeitung von ESC-Folgen
;
esca1:  call    input+o
        call    getprb          ; Zeichen aus Printerbuffer holen
        jr      nc,esca1        ; Buffer leer
        inc     r8
        jr      z,esca1         ; 0ffh uebergehen
        dec     r8
        ld      r14,#.h(esctab-1)
        ld      r15,#.l(esctab-1)
esca2:  incw    rr14
        ldc     r9,@rr14        ; Zeichen aus Tabelle holen
        and     r9,r9
        jr      z,mainl1        ; Tabellenende
        incw    rr14
        cp      r8,r9           ; vergleichen
        jr      nz,esca2        ; nicht gefunden
        ldc     r8,@rr14        ; 3004 Code holen
        jr      bufou7          ; Code ausgeben
;
bufou5: cp      r12,#7fh        ; DEL
        jr      nz,formf        ; nein
        ld      r8,#95h         ; Init
        or      mode2,#40h      ; Flag Init
        jr      bufou7
;
formf:  cp      r12,#0ch        ; Formfeed?
        jr      nz,ranum        ; nein
        ld      r13,zzaehl
        call    zabei2
        sub     r9,r13
        jr      z,formf2
        ld      r13,r9
formf1: ld      r8,#75h         ; 1/2 Zeile abwaerts
        call    print
        djnz    r13,formf1
formf2: clr     zzaehl
        ld      r8,#78h         ; Wagenruecklauf
formf3: call    print
        jr      mainl2
;
ranum:  and     r8,r8           ; druckbares Zeichen?
        jr      nz,bufou6       ; ja
        cp      r12,#11h        ; Text Mode
        jr      z,mainl1        ; nicht als Random Code
        cp      r12,#91h        ; Graphic Mode
        jr      z,mainl1        ; nicht als Random Code
        ld      r14,#random     ; Adresse Random Codes
        ld      r15,#5          ; Anzahl Random Codes
ranum1: cp      r8,@r14
        jr      z,bufou8        ; Eintrag leer
        cp      r12,@r14
        jr      z,ranum2        ; gefunden
        inc     r14
        inc     r14
        djnz    r15,ranum1      ; weiter suchen
        jr      mainl2          ; nicht gefunden
;
ranum2: inc     r14
        ld      r8,@r14         ; neuen Code holen
bufou6: cp      r8,#78h         ; CR
        jr      nz,bufou7       ; nein
        tm      mode2,#20h      ; Auto Linefeed
        jr      z,bufou7        ; nein
        ld      r8,#77h         ; CRLF
bufou7: call    zabein          ; Zeilenabstand
        call    zzaeh           ; Zeilen zaehlen
        jr      formf3          ; Ausgabe R8
;
bufou8: tm      mode2,#8        ; Random Code ein
        jr      z,mainl2        ; nein
        push    r14
        push    r12
        ld      r8,r12
        call    hexout
        ld      r8,#71h         ; Space
        call    print
        or      mode1,#2        ; Flag Random Code Eingabe
        call    gettas          ; Zeichen von Tastatur holen
        and     mode1,#0fdh     ; Random Code Flag ruecksetzen
        pop     r12
        pop     r14
        ld      @r14,r12
        inc     r14
        ld      @r14,r8
        call    print
        ld      r8,#71h         ; Space
        jr      formf3          ; Ausgabe R8
;
modum:  xor     mode2,r8        ; Mode umschalten Bit in R8
        tm      mode2,r8        ; Mode eingeschaltet?
        jr      nz,modum2       ; ja
        call    bell            ; bei ausschalten 2*bell
        ld      r8,#2           ; Zeitkonstante
modum1: clr     r14             ; Zeitkonstante
        call    o+warte         ; Warteschleife
        djnz    r8,modum1
modum2: call    bell
mainl2: jp      mainlp
;
; Random Code ein/aus (0c9h) Code+E
;
spec9:  ld      r8,#8
        jr      modum
;
; Funtion (0e2h) Code+L Random Codes ausgeben/setzen
;
ranou:  ld      r14,#.h(txrand+o)
        ld      r15,#.l(txrand+o)
        ld      r13,#random     ; Adresse Random Codes
ranou1: call    o+prints
        ld      r8,@r13
        and     r8,r8
        jr      z,ranou4
        push    r13
        push    r14
        call    hexout
        pop     r14
        call    o+prints
        pop     r13
        inc     r13
        ld      r8,@r13
        call    print
        call    gettas          ; Zeichen von Tastatur holen
        cp      r8,#7ah         ; T+
        jr      z,ranou2
        cp      r8,#7bh         ; T-
        jr      z,ranou6
        ld      @r13,r8
        call    print
ranou2: inc     r13
        cp      r13,#random+10
        jr      z,ranou4
ranou3: ld      r14,#.h(txtra0+o)
        ld      r15,#.l(txtra0+o)
        jr      ranou1
;
ranou4: call    crlf
ranou5: jr      mainl2
;
ranou6: ld      r12,r13
        dec     r13
        push    r13
ranou7: inc     r12
        cp      r12,#5ah
        jr      nc,ranou8
        ld      r11,@r12
        ld      @r13,r11
        inc     r13
        jr      ranou7
;
ranou8: clr     @0dh
        inc     r13
        clr     @0dh
        ld      r8,#'-'
        call    printu
        pop     r13
        jr      ranou3
;
; (0c6h)
;
spec6:  call    gettas          ; Zeichen von Tastatur holen
        cp      r8,#0cbh
        jr      z,versou        ; Programmversionsnummer ausgeben
        cp      r8,#0d1h
        jr      nz,ranou5       ; illegaler Code
;
; Funktion 0c6h+0d1h EPROM-Test
;
memtst: ld      p3m,#1
        ld      r12,#.h(csum+1+o)
        ld      r13,#.l(csum+1+o)
        clr     r15
memts1: decw    rr12
        ldc     r11,@rr12
        add     r15,r11
        and     r13,r13
        jr      nz,memts1
        cp      r12,#8
        jr      z,memts2
        cp      r12,#80h
        jr      nz,memts1
        ld      r12,#10h
        jr      memts1
;
memts2: inc     r15
        jr      nz,memtst       ; Fehler
        call    bell            ; OK
memts3: xor     p3,#40h         ; BUSY
        ld      r14,#1          ; Zeitkonstante
        call    o+warte         ; Warteschleife
        jr      memts3          ; Endlosschleife
;
; Funktion 0c6h+0cbh Versionsausgabe
;
versou: ld      r12,#.h(versio-1+o)
        ld      r13,#.l(versio-1+o)
        incw    rr12
        ldc     r8,@rr12
        and     r8,#0fh
        or      r8,#0c0h
        call    hexout
        incw    rr12
        ldc     r8,@rr12
        call    hexout
        jp      mainlp
;
; Hexdump Mode ein/aus
;
sped6:  ld      hexbyt,#16
        call    crlf
        ld      r8,#10h         ; Hexdump Bit
        jp      modum
;
; Initialice Function Code+I
;
setup:  ld      r14,#.h(txtini+o)
        ld      r15,#.l(txtini+o)
        call    o+prints
setup1: call    gettas          ; Zeichen von Tastatur holen
        cp      r8,#7ah         ; T+
        jr      nz,setup2
        or      mode2,#20h      ; Auto Linefeed ein
        ld      r8,#'Y'
        jr      setup3
;
setup2: cp      r8,#7bh         ; T-
        jr      nz,setup1
        and     mode2,#0dfh     ; Auto Linefeed aus
        ld      r8,#'N'
setup3: call    printu
        call    o+prints
        ld      r8,zanzah
        and     r8,#0f0h
        swap    r8
        or      r8,#'0'
        call    printu
        ld      r8,zanzah
        and     r8,#0fh
        or      r8,#'0'
        call    printu
        call    o+prints
setup4: call    gettas          ; Zeichen von Tastatur holen
        cp      r8,#7ah         ; T+
        jr      z,setup6        ; uebergehen
        call    toasc
        cp      r8,#'0'
        jr      c,setup4
        cp      r8,#'9'+1
        jr      nc,setup4
        push    8
        call    printu
        pop     8
        and     r8,#0fh
        tcm     zanzah,#0fh
        jr      z,setup5
        swap    r8
        ld      zanzah,r8
        or      zanzah,#0fh
        jr      setup4
;
setup5: and     zanzah,#0f0h
        or      zanzah,r8
setup6: call    o+prints
mainl3: jp      mainlp
;
; Funktion (0c2h) Code+A Werbetext ausgeben
;
werbe:  ld      r8,#85h         ; 1 1/2 Zeilig
        call    print
        ld      r8,#87h         ; 10 CPI
        call    print
        ld      r14,#.h(txtwer+o)
        ld      r15,#.l(txtwer+o)
        call    o+prints
        ld      r8,#88h         ; 12 CPI
        call    print
        call    o+prints
        ld      r8,#87h         ; 10 CPI
        call    print
        call    o+prints
        jr      mainl3
;
; 3004 Code in ASCII wandeln
;
toasc:  ld      r12,#0
        ld      r10,#.h(tb3004)
        ld      r11,#.l(tb3004)
        jr      toasc2
;
toasc1: inc     r12
        jr      z,toasc3
        incw    rr10
toasc2: ldc     r9,@rr10
        cp      r9,r8
        jr      nz,toasc1
toasc3: ld      r8,r12
        ret
;
; R8 in HEX wandeln Code in R8 und R14
;
hexum:  push    8
        and     r8,#0fh
        call    hexum1
        ld      r14,r8
        pop     8
        and     r8,#0f0h
        swap    r8
hexum1: cp      r8,#0ah
        jr      c,hexum2
        add     r8,#7
hexum2: add     r8,#30h
to3004: ld      r10,#.h(tb3004)
        ld      r11,#.l(tb3004)
comasc: add     r11,r8
        adc     r10,#0
        ldc     r8,@rr10
        ret
;
hexout: call    hexum
pr8r14: call    print
        ld      r8,r14
        jr      print
;
printu: call    to3004
print:  call    o+serout
        jr      nc,print
        ret
;
crlf:   ld      r8,#77h         ; crlf
        jr      print
;
out91x: or      mode2,#80h      ; Setup Mode Flag setzen
out91:  ld      r8,#91h
        and     mode2,#0bfh     ; Init Flag ruecksetzen
        ld      zaehl1,#80
        jr      print
;
out92:  ld      r8,#92h
        or      mode2,#40h      ; Init Flag setzen
        jr      print
;
gettas: call    input+o
        call    serin1+o        ; Zeichen aus Tastenbuffer holen
        jr      nc,gettas       ; kein Zeichen da
        call    chktas
        jr      c,gettas        ; nur gueltige Tasten zulassen
        scf
        ret
;
bell:   ld      r14,#20         ; Zeitkonstante
bell1:  ld      r8,#0aah        ; Bell
        jr      pr8r14
;
; Zeilenabstand nach R9
;
zabein: cp      r8,#84h         ; 1-zeilig
        jr      c,zabei1
        cp      r8,#87h         ; im Bereich 1 1/2 bis 2-zeilig
        jr      nc,zabei1       ; nein
        ld      r9,r8           ; in halbzeilenscritte wandeln
        and     r9,#3
        add     r9,#2
        and     zschrt,#0f8h
        or      zschrt,r9
zabei1: ret
;
zabei2: rcf
        ld      r9,zanzah
        ld      r11,r9
        and     r9,#0f0h
        rrc     r9
        ld      r10,r9
        rrc     r9
        rrc     r9
        add     r10,r9
        ld      r9,r11
        and     r9,#0fh
        add     r9,r10
        rlc     r9
        ret
;
; Zeilen zaehlen
;
zzaeh:  cp      r8,#75h         ; 1/2 Zeile abwaerts
        ld      r9,#1
        jr      z,zzaeh2
        cp      r8,#76h         ; 1/2 Zeile hoch
        ld      r9,#0ffh
        jr      z,zzaeh2
        cp      r8,#77h         ; CRLF
        jr      z,zzaeh1
        cp      r8,#9fh         ; LF
        jr      nz,zzaeh5
zzaeh1: ld      r9,zschrt
        and     r9,#7
zzaeh2: cp      r9,#0ffh
        jr      nz,zzaeh3
        sub     zzaehl,#1
        jr      zzaeh4
;
zzaeh3: add     zzaehl,9
zzaeh4: jr      nc,zzaeh5
        call    zabei2
        add     zzaehl,9
        ret
;
zzaeh5: call    zabei2
        cp      r9,zzaehl
        jr      nc,zzaeh6
        sub     zzaehl,9
zzaeh6: ret
;
; Tastencode pruefen
;
chktas: cp      r8,#0f8h
        jr      nc,chkta3
        cp      r8,#0b0h
        jr      c,chkta1
        cp      r8,#0c0h
        jr      c,chkta3
chkta1: cp      r8,#84h
        jr      c,chkta2
        cp      r8,#8ah
        jr      c,chkta3
chkta2: rcf
        ret
;
; 84..89, b0..bf, f8..ff
;
chkta3: scf
        ret
;
spetab: db      0c9h            ; Code+E
        dw      spec9           ; Random Code ein/aus
        db      0e2h            ; Code+L
        dw      ranou           ; Random Codes Setzen/Ausgeben
        db      0ddh            ; Code+I
        dw      setup           ; Initialize Function
        db      0d6h            ; Code+H
        dw      sped6           ; Hexdump Mode
        db      0c6h            ; Code+
        dw      spec6           ; EPROM-Test oder Versionsausgabe
        db      0c2h            ; Code+A
        dw      werbe           ; Werbetext ausgeben
        db      0
;
esctab: db      4dh,87h         ; 10 CPI
        db      4eh,88h         ; 12 CPI
        db      33h,84h         ; 1-zeilig
        db      34h,85h         ; 1 1/2 zeilig
        db      35h,86h         ; 2-zeilig
        db      31h,7ah         ; TAB+
        db      38h,7bh         ; TAB-
        db      32h,7ch         ; Clear all TAB
        db      55h,75h         ; 1/2 Zeile vorwaerts
        db      44h,76h         ; 1/2 Zeile rueckwaerts
        db      0
;
; Zeichen aus R8 in Buffer schreiben
;
inprbu: ld      r9,pbufp1
        inc     r9
        cp      r9,#pbuf+48
        jr      nz,inprb1
        ld      r9,#pbuf
inprb1: cp      9,pbufp2
        jr      z,inprb4
        ld      @pbufp1,r8      ; Daten speichern
        ld      pbufp1,r9
        or      mode2,#2        ; Zeichen im Buffer
        sub     r9,pbufp2
        jr      c,inprb3
        cp      r9,#40
        jr      c,inprb4        ; mehr als 8 Zeichen frei
inprb2: or      mode2,#1        ; Buffer voll
        scf
        ret
;
inprb3: cp      9,#0f8h
        jr      nc,inprb2       ; Mehr als 8 Zeichen frei
inprb4: ret
;
; Zeichen aus Printerbuffer holen
;
getprb: cp      pbufp1,pbufp2   ; Buffer leer?
        jr      z,getpr5        ; ja
        ld      r8,@pbufp2      ; Zeichen holen
        inc     pbufp2          ; Pointer weiterstellen
        cp      pbufp2,#pbuf+48 ; am Ende angekommen
        jr      nz,getpr1       ; nein
        ld      pbufp2,#pbuf    ; Pointer auf Anfang stellen
getpr1: cp      pbufp2,pbufp1   ; Buffer leer?
        jr      nz,getpr2       ; nein
        and     mode2,#0fdh     ; Kennzeichen Buffer leer
        jr      getpr4
;
getpr2: ld      r9,pbufp1       ; Fuellstand pruefen
        sub     r9,pbufp2
        jr      c,getpr6
        cp      r9,#40          ; Platz im Buffer?
        jr      nc,getpr4       ; nein
getpr3: and     mode2,#0feh     ; Kennzeichen Platz im Buffer
getpr4: scf
getpr5: ret
;
getpr6: cp      9,#0f8h         ; Platz im Buffer
        jr      c,getpr3        ; ja
        jr      getpr4          ; nein
;
; Printerbuffer loeschen
;
clrpbu: clr     mode2
        ld      r9,#pbuf
        ld      pbufp2,r9
        ld      pbufp1,r9
        ret
;
        org     1000h
;
; ATN Interrupt Commodore
;
atnint: tm      p3,#1           ; ATN
        jr      nz,atnin1       ; high ignorieren
        or      p3,#80h         ; mit DATA low bestaetigen
        or      mode1,#88h      ; Commodore + ATN
atnin1: iret
;
; Zeichen vom Commodore oder Centronics Interface holen
;
input:  tm      irq,#4          ; IRQ2 P31 STB Centronics
        jr      z,inpt1         ; nein
        tm      mode2,#1        ; Platz im Printerbuffer?
        jr      nz,inpt4        ; nein
        and     mode1,#7fh      ; Centronics Mode
        ld      r8,r2           ; P2 Daten Centronics holen
        com     r8              ; negieren
        and     irq,#0fbh       ; Interrupt ruecksetzen
        jp      inprbu          ; Zeichen in Buffer schreiben
;
inpt1:  tm      mode1,#8        ; IRQ3 P30 ATN Commodore
        jr      nz,inpt2        ; ja
        tm      mode1,#40h      ; Selektiert?
        jr      nz,inpt3        ; ja
        ret
;
inpt2:  ld      r14,#5          ; Zeitkonstante
        call    o+warte         ; Warteschleife
inpt3:  ld      r12,#.h(4000h)  ; Commodore Interface
        ldc     r14,@rr12
        tcm     r14,#2          ; CLK Bit
        jr      nz,inpt6        ; low
inpt4:  ret
;
inpt5:  tm      mode1,#2        ; Random Code Eingabe?
        jr      z,inpt4         ; nein
        and     irq,#0feh       ; Interrupt ruecknehmen
        jr      inpt13          ; Interrupts wieder freigeben
;
inpt6:  tm      mode2,#1        ; Platz im Printerbuffer
        jr      nz,inpt5        ; nein
        or      p3,#20h         ; CTS
inpt7:  and     bitz1,bitz1     ; Empfang von Schreibmaschine?
        jr      nz,inpt7        ; warten bis Ende wegen DI
        di                      ; Interrupts verbieten
        tm      mode1,#8        ; ATN low gewesen
        jr      z,inpt8         ; nein Datenuebertragung
        call    o+inpt19        ; Adressbyte holen
        cp      r8,#24h         ; Listener Adresse 4?
        jr      nz,inpt17       ; nein
        jr      inpt3           ; Zeichen holen
;
inpt8:  and     mode1,#0bfh     ; Select Bit ruecksetzen
        call    o+inpt26
        cp      r8,#11h         ; Text Mode?
        jr      nz,inpt9        ; nein
        or      mode1,#4        ; Text Mode ein
inpt9:  cp      r8,#91h         ; Graphic Mode?
        jr      nz,inpt10       ; nein
        and     mode1,#0fbh     ; Text Mode aus
inpt10: tm      mode1,#8        ; ATN low gewesen?
        jr      nz,inpt16       ; ja
        tm      mode1,#14h      ; Text Mode oder sekundaer select
        jr      z,inpt11        ; nein
        ld      r10,r8          ; Zeichen retten
        ld      r8,#0ffh        ; 0ffh in Buffer
        call    inprbu          ; Zeichen in Buffer schreiben
        ld      r8,r10          ; Zeichen rueckholen
inpt11: call    inprbu          ; Zeichen in Buffer schreiben
        tm      mode1,#20h      ; Timeout?
        jr      z,inpt15        ; nein
        tm      p3,#1           ; ATN low?
        jr      z,inpt14        ; ja, ATN Flag setzen
        and     p3,#7fh         ; DATA high
inpt12: and     irq,#0f6h       ; Interrupt ruecksetzen
        and     mode1,#0b7h     ; ATN und Select Flag ruecksetzen
inpt13: and     p3,#0dfh        ; CTS low
        ei
        ret
;
inpt14: or      mode1,#8        ; ATN Flag setzen
        jr      inpt3
;
inpt15: or      mode1,#40h      ; Select Flag setzen
        ret
;
inpt16: cp      r8,#3fh         ; Ende Listen (deselect)
        jr      nz,inpt15       ; nein
inpt17: and     p3,#7fh         ; DATA high
inpt18: tm      p3,#1           ; ATN
        jr      z,inpt18        ; warten auf ATN high
        jr      inpt12
;
; Warteschleife Zeitkonstante in R14
;
warte:  ld      r15,#110
warte1: djnz    r15,warte1
        djnz    r14,warte
        ret
;
inpt19: and     mode1,#0c7h     ; ATN, Timeout und Sekundaer Flags ruecksetzen
        and     p3,#7fh         ; DATA high
inpt20: ldc     r14,@rr12
        tcm     r14,#2          ; CLK Bit
        jr      nz,inpt20       ; warten auf low
        call    o+compaw        ; Commodore Daten ser/par wandeln
        cp      r8,#24h         ; Listener Adresse 4?
        jr      z,inpt21        ; ja
        ret
;
inpt21: or      p3,#80h         ; DATA low
        ld      r14,#10         ; Zeitkonstante
        call    o+warte         ; Warteschleife
        tm      p3,#1           ; ATN
        jr      nz,inpt25
inpt22: ldc     r14,@rr12
        tcm     r14,#2          ; CLK Bit
        jr      z,inpt22        ; warten auf high
        and     p3,#7fh         ; DATA high
inpt23: ldc     r14,@rr12
        tcm     r14,#2          ; CLK Bit
        jr      nz,inpt23       ; warten auf low
        call    o+compaw        ; Commodore Daten ser/par wandeln
        or      p3,#80h         ; DATA low
        cp      r8,#67h         ; select Sekundaeradresse 7?
        jr      nz,inpt24       ; nein andere
        or      mode1,#10h      ; Sekundaer select Flag setzen
inpt24: ld      r8,#24h         ; Listener Adresse 4
inpt25: or      mode1,#40h      ; Drucker select Flag setzen
        ret
;
inpt26: and     mode1,#0d7h     ; ATN und Timeout Flags ruecksetzen
        tm      p3,#1           ; ATN
        jr      nz,inpt28       ; ATN high
        or      mode1,#8        ; ATN Flag setzen
        and     p3,#7fh         ; DATA high
inpt27: ldc     r14,@rr12
        tcm     r14,#2          ; CLK Bit
        jr      nz,inpt27       ; warten auf low
        jr      inpt30
;
inpt28: ld      r9,#17h         ; Zeitkonstante Timeout
        and     p3,#7fh         ; DATA high
inpt29: ldc     r14,@rr12
        tcm     r14,#2          ; CLK Bit
        jr      nz,inpt32       ; high
inpt30: call    o+compaw        ; Commodore Daten ser/par wandeln
        tm      mode1,#20h      ; Timeout?
        jr      nz,inpt31       ; ja
        or      p3,#80h         ; DATA low
        ret
;
inpt31: or      p3,#80h         ; DATA low
        ld      r14,#1          ; Zeitkonstante
        jp      o+warte         ; Warteschleife
;
inpt32: djnz    r9,inpt29
        or      mode1,#20h      ; Timeout Flag setzen
        call    o+inpt31        ; Daten kurz auf low
        jr      inpt28          ; Daten wieder auf high
;
; Commodore Daten seriell/parallel wandeln nach R8
;
compaw: clr     r8              ; Register fuer Empfangsdaten
        ld      r9,#8           ; Anzahl Datenbits
compa1: ldc     r14,@rr12       ; Daten holen
        tcm     r14,#2          ; CLK Bit
        jr      z,compa1        ; warten auf CLK high
        rrc     r14             ; Datenbit in CY
        ccf                     ; negieren
        rrc     r8              ; Byte schieben
compa2: ldc     r14,@rr12
        tcm     r14,#2          ; CLK Bit
        jr      nz,compa2       ; warten auf CLK low
        djnz    r9,compa1       ; 8 mal fuer ein Byte
        ret
;
; Software SIO zur Schreibmaschine
;
serout: tm      p3,#8           ; CTS von Schreibmaschine
        rcf
        jr      nz,serou7       ; nicht bereit
        ld      r9,#8           ; Anzahl Bits
        call    o+serou4        ; Startbit senden
serou1: ld      r10,#.h(serou2+o) ; RET-Adresse
        ld      r11,#.l(serou2+o)
        push    r11
        push    r10
        rr      r8              ; Byte schieben
        jr      nc,serou4       ; 0-Bit
        jr      serou3          ; 1-Bit
;
serou2: dec     r9
        jr      nz,serou1
        call    o+serou3        ; Stop-Bit senden
serou3: or      p3,#10h         ; 1-Bit senden
        jr      serou5
;
serou4: and     p3,#0efh        ; 0-Bit senden
        jr      serou5
;
serou5: ld      r10,#0a0h       ; Warteschleife
serou6: dec     r10
        jr      nz,serou6
        scf
serou7: ret
;
; Zeichen aus Tastaturbuffer holen
;
serin1: cp      tbufp1,tbufp2   ; Zeichen im Buffer
        jr      z,serin4        ; Buffer leer
        ld      r8,@tbufp2
        inc     tbufp2
        cp      tbufp2,#tbuf+8
        jr      nz,serin2
        ld      tbufp2,#tbuf
serin2: cp      tbufp2,tbufp1   ; Buffer leer?
        jr      nz,serin3       ; nein
        and     p3,#0dfh        ; CTS low
serin3: scf
serin4: ret
;
; Interrupt RxD von Schreibmaschine
;
p32int: and     imr,#0feh
        ld      bitz1,#10       ; Anzahl Bits (mit Start- und Stopbit)
        clr     rxdata
        ld      t1,#3
        or      tmr,#0ch
        ld      t1,#0ch
        iret
;
t1int:  dec     bitz1
        jr      z,t1int4
        cp      bitz1,#9
        jr      nz,t1int1
        tm      p3,#4           ; Startbit pruefen
        jr      nz,t1int4       ; fehlendes Startbit
        iret
;
t1int1: tm      p3,#4
        scf
        jr      nz,t1int2
        rcf
t1int2: rrc     rxdata
t1int3: iret
;
t1int4: and     tmr,#0f7h
        and     irq,#0feh
        or      imr,#1
        and     bitz1,bitz1
        jr      nz,t1int3
        ld      r5,tbufp1
        inc     r5
        cp      r5,#tbuf+8
        jr      nz,t1int5
        ld      r5,#tbuf
t1int5: cp      r5,tbufp2
        jr      z,t1int8
        ld      @tbufp1,rxdata
        ld      tbufp1,r5
        sub     r5,tbufp2
        jr      c,t1int7
        cp      r5,#4           ; Buffer voll
        jr      c,t1int8        ; nein
t1int6: or      p3,#20h         ; CTS high
        iret
;
t1int7: cp      r5,#0fch        ; Buffer voll
        jr      nc,t1int6       ; ja
t1int8: iret
;
irq0fg: di
        and     irq,#11111110b
        or      imr,#1
        and     p3,#11011111b   ; CTS low
        ei
        ret
;
prints: ldc     r8,@rr14        ; Zeichen holen
        and     r8,r8           ; ?0
        jr      z,prins2        ; Ende String mit 0
        tm      r8,#80h         ; ohne Umwandlung?
        jr      nz,prins1       ; ja
        push    r10
        call    to3004          ; Umwandeln ASCII => 3004 Code
        pop     r10
prins1: and     r8,#7fh
        call    print
        incw    rr14
        jr      prints
;
prins2: incw    rr14
        ret
;
txrand: db      0f7h
        db      '  RANDOMCODES',0f7h
        db      'HEX-CODE * FUNCTION'
txtra0: db      0f7h,'   ',0
        db      '          ',0
txtini: db      0f7h
        db      'INITIALIZE FUNCTION',0f8h
        db      '___________________',0f7h,0f7h
        db      'AUTOMATIC LINEFEED',0f7h,0f9h
        db      'YES - DEPRESS : T+',0f7h,0f9h
        db      'NO  - DEPRESS : T-',0f7h,0f9h
        db      '? ',0,0f7h
        db      'FORMFEED',0f7h,0f9h
        db      'ACTUAL CONTENT : ',0
        db      0f7h,0f9h
        db      'NO CHANGE - DEPRESS : T+',0f7h,0f9h
        db      'CHANGE    - DEPRESS : 00...99',0f7h,0f9h
        db      '? ',0
txtrdy: db      0f7h,'READY',0f7h,0
txtwer: db      0f7h
        db      'Ich bin die elektronische Typenradschreibmaschine f}r jedermann.',0f7h
        db      'F}r alle Schreibarbeiten daheim und unterwegs stehe ich Ihnen',0f7h
        db      'gerne zur Verf}gung.',0f7h,0f7h
        db      'Die Freude am Reisen k|nnen Sie schon meinem [u~eren, dem',0f7h
        db      'integrierten Koffer und ausklappbaren Tragegriff erkennen.',0f7h,0f7h
        db      'Ich bin eine einfach zu bedienende Schreibmaschine mit Funktio-',0f7h
        db      'nen wie:',0f7h
        db      '       . 20 Zeichen Sofortkorrektur',0f7h
        db      '       . komfortable Relocate-Korrektur',0f7h
        db      '       . gepufferte Tastatur f}r flotten Schreibbetrieb',0f7h
        db      '       . Dauerfunktion f}r alle Tasten',0f7h
        db      '       . intelligente Tabulator- und Randlogik',0f7h
        db      'sind f}r mich kein Problem.',0f7h,0f7h
        db      'Ich schreibe mit 1/10" oder',0,' schmal mit 1/12"-Schriftteilung',0,0f7h
        db      'in 3 unterschiedlichen Zeilenabst{nden.',0f7h,0f7h
        db      'Das Tollste an mir ist die Schnittstellenvorbereitung.',0f7h
        db      'Mit der angesteckten Interface-Box werde ich f}r Sie',0f7h
        db      'mit  beliebigen Computern zum intelligenten Schreibsystem.',0f7h
        db      'Ob mit',0f7h
        db      '       . Commodore',0f7h
        db      '       . Centronics oder',0f7h
        db      '       . V24/RS232 C - Interface',0f7h
        db      'betrieben, eigne ich mich als Sch|nschreibdrucker f}r unter-',0f7h
        db      'schiedliche Anwendungen.',0f7h,0f7h
        db      'Wenn ich Ihnen jetzt schon sympathisch bin, benutzen Sie mich.',0f7h
        db      '              Ich werde Sie endg}ltig }berzeugen',0f7h
        db      '          und Ihr st{ndiger B e g l e i t e r  sein.',0f7h,0
;
        org     17f9h
csum:   db      0               ; wird noch eingetragen
versio: dw      0b758h          ; Verison=C758
        db      0ffh,1,50h,1dh  ; ?
;
        end
