; programm   :  switch.asm    version 1.01    23.09.1988
; syntax     :  a86
; aufgabe    : konvertierung von klein nach gross und umgekehrt

@read      equ    3fh                ;ber handle lesen
@write     equ    40h                ;ber handle schrieben
@dosver    equ    30h                ;dosversion feststellen
@prnstr    equ    09h                ;print ausgeben
cr         equ    0dh                ;carriage return character
lf         equ    0ah                ;line feed character
stdin      equ    0000h              ;standard input
stdout     equ    0001h              ;standard output
u          equ    01h                ;upper case option selected
buf_size   equ     1024              ;gr”sse des buffers
para_c     equ    b[80h]             ;anzahl der parameter
param_area equ     [81h]
up_mask    equ     11011111xb  ;maske fr lowercase
low_mask   equ     00100000xb  ;maske fr uppercase
           jmp main
baddos     db      cr,lf,'Dieses Programm ben”tigt DOS 2.0 oder gr”sser',cr,lf,'$'
nomem      db      cr,lf,'Zuwenig Speicher Programm-Abbruch',cr,lf,'$'
help       db      cr,lf,
           db      'SWITCH  Version 1.01      Public-Domain',cr,lf
           db      'angelehnt an lc.asm von d.whitmann ( chasm 4.09 )'
           db       cr,lf,
           db      'Kein Copyright   by ms',cr,lf
           db      cr,lf
           db      'SWITCH  konvertiert zwischen Gross und Klein',cr,lf
           db      'Aufruf: switch  [?] [/U] < ein.txt > aus.txt',cr,lf
           db      cr,lf
           db      'optionen:',cr,lf
           db      ' switch ?   = Hilfe',cr,lf
           db      ' switch /U  = Konvertierung in Gross',cr,lf
           db      ' switch     = Konvertierung in Klein',cr,lf
           db      cr,lf,'$'
options    db 00

main:      cmp para_c,0        ; wenn nur switch aufgerufen wurde,
           jg m1               ; dann hilfe ausgeben und programm
           mov ah,040          ; beenden
           mov bx,0002         ; auch mit schreiben durch handle
           mov cx,offset options  ; handle in bx=0002
           sub cx,offset help     ; dieses handle gibt immer auf den
           sub cx,1               ; bildschirm aus !
           mov dx,offset help
           int 021h
           mov ah,04ch           ; programm geregelt beenden
           int 021

m1:        call    setup          ;dosversion prfen
           call    process        ;und arbeiten
           mov     ah,04ch
           int     021h           ;programm beenden
setup:     mov     ah,@dosver     ;dosversion feststellen
           int     021h
           cmp     al,2           ;gr”sser als dos 2.00
           jae     a_help         ;ok, dann weiter
           mov     ah,@prnstr     ;unter dos 2.0 keine redirections
           mov     dx,offset baddos
           int     021h
           mov     ah,04ch
           int     021h
a_help:    xor     ch,ch
           mov     cl,para_c ;  "
           cmp     cl,00h          ;wurden optionen bergeben
           je      aexit           ;wenn nicht, dann in klein konvertieren
           mov     di,offset param_area
           mov     al,'?'
           repnz
           scasb
           jnz     a_par
           mov     ah,@prnstr      ;? , dann hilfe zeigen
           mov     dx,offset help
           int     21h             ; dann programm beenden
           mov     ah,04ch
           int     021h
a_par:     xor     ch,ch
           mov     cl,para_c
           mov     di,offset param_area
a_loop:    mov     al,'/'               ; die option fr gross-schrift wird
           repnz                        ; durch / eingeleitet
           scasb
           jnz     aexit
           mov     al,[di]        ;wenn / gefunden, dann n„chstes zeichen
           and     al,up_mask     ;bernehmen und in Grossbuchstaben umwandeln
           cmp     al,85          ;wurde ein u bergeben
           jne     a_pend
           or      b[options],u   ;wenn ja, dann den text in Grossbuchstaben
a_pend:    jmp     short a_loop   ;konvertieren
aexit:     ret

process:
bu1:       mov     ah,@read         ;ber standard-input jetzt den buffer
           mov     bx,stdin         ;vollmachen
           mov     cx,buf_size
           mov     dx,offset buf_in
           int     21h
           cmp     ax,00h          ; wenn keine zeichen gelesen wurden,
           jz      buexit          ; sind wir fertig
           push    ax
           mov     cx,ax            ;in cx die anzahl der zeichen retten
           mov     si,offset buf_in    ;jetzt von ein-buffer in den aus-buffer
           mov     di,offset buf_out
bu2:       lodsb
           jmp sonder            ;ist in al etwa ein deutsches sonderzeichen ?
mall:      cmp al,65             ;jetzt auf buchstaben prfen
           jb  bu4
           cmp al,90
           jbe bu3
           cmp al,97
           jb  bu4
           cmp al,122
           ja  bu4

bu3:       test b[options],u       ; soll in grossbuchstaben konvertiert werden
           jnz  bu_up
           or   al,low_mask
           jmp short bu4
bu_up:     and  al,up_mask
bu4:       stosb                   ; in den aus-buffer ablegen
           loop bu2                ; solange bis ein-buffer bearbeitet ist
           mov     ah,@write       ; jetzt ber standard-output ausgeben
           mov     bx,stdout
           pop     cx              ; soviel zeichen wurden gelesen
           mov     dx,offset buf_out
           int     21h
           jmp short    bu1        ; und alles von vorne
buexit:    ret

sonder:    test b[options],u       ; alles nur wegen den  ” „
           jz ma                   ; die deutschen sonderzeichen sollen
           cmp al,129              ; auch konvertiert werden
           jne mt1                 ; es geht auch ohne xlat,
           mov al,154              ; aber langsamer
           jmp short sondex
mt1:       cmp al,148
           jne mt2
           mov al,153
           jmp short sondex
mt2:       cmp al,132
           jne sondex
           mov al,142
           jmp short sondex
ma:        cmp al,154
           jne mt11
           mov al,129
           jmp short sondex
mt11:      cmp al,153
           jne mt12
           mov al,148
           jmp short sondex
mt12:      cmp al,142
           jne sondex
           mov al,132
sondex:    jmp mall

buf_in     db 0                 ; hierhin wird eingelesen
           org $+buf_size
buf_out    db 0                 ; ab hier wird ausgegeben
