        org   #0100
        write "language.com"
;
; ------ >>>  Labeldefinitionen  <<< -----------------
;
bdos    equ   #0005
fcb     equ   #0080

;
; ------ >>>  CP/M Version pr}fen  <<< ---------------
;
        ld    c,12        ;CP/M Version ermitteln
        call  bdos
        ld    a,l
        cp    #22
        ld    de,notcpm2  ;Zeiger auf Fehlermeldung
        jp    nz,prt_msg  ;Springe wenn nicht CP/M 2

;
; ------ >>>  Initialisierung  <<< -------------------
;
; In dieser Schleife wird, ausgehend vom Warmstart
; Einsprung bei #0000, die CALLSYS-Adresse gesucht.
; Beim 'kleinen AMSDOS' CP/M ist dies z.B. #AD33.
; Die Adresse wird je nach DOS-Version und CP/M Gr|~e
; automatisch richtig ermittelt. Der SYSCALL-Entry
; wird dann hinter die CALLs bei 'ERROFF' & 'ERROLD'
; geschrieben.
;
init    ld    hl,(#0001)
        ld    de,#0018
        add   hl,de
search  ld    a,(hl)
        inc   hl
        cp    #cd         ;Ist es ein CALL ?
        call  ld_hlhl
        jr    nz,search   ;Nein, dann weiter
;
        ld    (erroff+3),hl
        ld    (errold+3),hl

;
; ------ >>>  Programmstart  <<< ---------------------
;
start   ld    hl,fcb      ;Zeiger auf Default-FCB
        ld    a,(hl)      ;Parameter-L{nge -> 'A'
        and   a           ;Mit Parameter aufgerufen?
        jr    z,newpara   ;Nein, dann springe
;
        ld    b,a
skpspce inc   hl          ;F}hrende Leerzeichen
        ld    a,(hl)      ; vor dem Parameter
        cp    " "         ; }berlesen
        jr    nz,tst_par
        djnz  skpspce
;
tst_par ld    de,bad_par  ;Zeiger auf Fehlermeldung
        cp    "0"
        jp    c,prt_msg
        cp    "4"
        jp    nc,prt_msg

;
; ------ >>>  Neuen Zeichnsatz setzen  <<< -----------
;
setchar sub   "0"         ;#00 - #03 -> 'A'
        ld    c,a         ;Parameter -> 'C'
        ld    de,#0030

;
; ------ >>>  BIOS Funktion aufrufen  <<< ------------
;
jp_bios ld    hl,(#0001)
        add   hl,de
        jp    (hl)

;
; ------- >>>  Parameter-Sector lesen  <<< -----------
;
newpara call  erroff      ;Fehlermeldungen aus
;
        ld    c,#00       ;#00 = Drive A
        ld    de,#0018    ;Offset f}r SELDSK
        call  jp_bios     ;Laufwerk ausw{hlen
;
        ld    bc,#0000    ;Track 0
        ld    de,#001b    ;Offset f}r SETTRK
        call  jp_bios     ;Track setzen
;
        ld    bc,#0004    ;Record 4
        ld    de,#001e    ;Offset f}r SETTRK
        call  jp_bios     ;Record setzen
;
        ld    bc,puffer   ;Zeiger auf Record-Puffer
        ld    de,#0021    ;Offset f}r SETDMA
        call  jp_bios     ;DMA-Adresse setzen
;
        ld    de,#0024    ;Offset f}r READ
        call  jp_bios     ;Record lesen
        and   a           ;Lesefehler ?
        ld    de,readerr  ;Zeiger auf Fehlermeldung
        jr    nz,exit     ;Springe bei Lesefehler
;
        ld    a,(puffer+1);Ist der Parameter-Sector
        cp    #12         ; g}ltig ?
        ld    de,bad_sec  ;Zeiger auf Fehlermeldung
        jr    nz,exit     ;Springe wenn ung}ltig

;
; ------ >>>  Neuen Zeichensatz erfragen  <<< --------
;
ask_new ld    de,menue
        call  prt_msg
get_key ld    de,#0006    ;Offset f}r CONIN
        call  jp_bios
        cp    #03         ;CTRL-C ?
        jr    z,ctrl_c    ;Ja, dann zur}ck zum CCP
        cp    "0"
        jr    c,get_key
        cp    "4"
        jr    nc,get_key
;
        push  af          ;ASCII-Zeichen merken
        ld    c,a         ;ASCII-Zeichen -> 'A'
        ld    de,#0009    ;Offset f}r CONOUT
        call  jp_bios
        pop   af          ;Zeichen wieder -> 'A'
;
        sub   "0"
        ld    (puffer+#17),a
        ld    c,a
        call  setchar
;
        ld    de,go_down
        call  prt_msg
;
        ld    de,#0027    ;Offset f}r WRITE
        ld    c,#01       ;#01 => nondeferred write
        call  jp_bios     ;Record schreiben
        and   a           ;Schreibfehler ?
        ld    de,wrteerr  ;Zeiger auf Fehlermeldung
        jr    nz,exit     ;Springe bei Schreibfehler
;
        ld    de,finish   ;Zeiger auf End-Meldung
        jr    exit        ;Text ausgeben und zum CCP

;
; ------ >>>  Lade 'HL' aus 'HL' und 'HL+1'  <<< -----
;
ld_hlhl ld    a,(hl)
        inc   hl
        ld    h,(hl)
        ld    l,a
        ret

;
; ------ >>>  Abbruch durch CTRL-C  <<< --------------
;
ctrl_c  ld    de,go_down
        call  prt_msg
        ld    de,aborted

;
; ------ >>>  Programm beenden  <<< ------------------
;
exit    push  de          ;Zeiger auf Meldung merken
        call  errold      ;Altes Fehlerflag setzen
        pop   de          ;Zeiger auf Meldung-> 'DE'

;
; ------ >>>  ( Fehler- ) Meldung ausgeben  <<< ------
;
prt_msg ld    c,9         ;Textstring ausgeben
        jp    bdos        ; und zur}ck zum CCP

;
; ------ >>>  Error-Messages abschalten  <<< ---------
;
erroff  ld    a,#ff       ;#FF=> Fehlermeldungen aus
        call  $-$
        defw  #be80
        ld    (errold+1),a;Alten Zustand merken
        ret

;
; ------ >>>  Altes Error-Flag wieder setzen  <<< ----
;
errold  ld    a,$-$       ;Altes Error-Flag -> 'A'
        call  $-$
        defw  #be80
        ret

;
; ------ >>>  ( Fehler- ) Meldungen  <<< -------------
;
notcpm2 defb  #07,#0a,#0d
        defm  "Error: Requires CP/M 2.2"
        defb  #0a,#0d,"$"
;
bad_par defb  #07,#0a,#0d
        defm  "Error: Invalid parameter"
        defb  #0a,#0d,"$"
;
bad_sec defb  #07,#0a,#0d
        defm  "Error: Illegal parameter sector"
        defb  #0a,#0d,"$"
;
readerr defb  #07,#0a,#0d
        defm  "Error: Unable to read parameter sector"
        defb  #0a,#0d,"$"
;
wrteerr defb  #07
        defm  "Error: Unable to write parameter sector"
        defm  #0a,#0d,"$"
;
menue   defb  #0a,#0d
        defm  "LANGUAGE V1.0"
        defb  #0a,#0a,#0d
        defm  "Select new character set:_"
        defm  #0a,#0a,#0d
        defm  " 0 - USA",#0a,#0d
        defm  " 1 - France",#0a,#0d
        defm  " 2 - German",#0a,#0d
        defm  " 3 - UK                   "
        defm  #0b,#0b,#0b,#0b,#0b,"$"
;
go_down defb  #0a,#0a,#0a,#0a,#0a,#0a,#0a,#0d,"$"
;
aborted defm  "^C...aborted"
        defb  #0a,#0d,"$"
;
finish  defm  "LANGUAGE V1.0 finished"
        defb  #0a,#0d,"$"

;
; ------ >>>  DMA-Puffer f}r Parameter Sector  <<< ---
;
puffer  equ   $
