CSEG SEGMENT
     ASSUME CS:CSEG,DS:DSEG

CSLENGTH PROC
; S (Segment) = [BP+6]
; S (Offset)  = [BP+4]
; Z = [BP-2]
     PUSH BP
     MOV  BP,SP
     SUB  SP,2
     PUSH DS
     PUSH BX
     PUSH SI
     MOV  WORD PTR [BP-2],0  ; Z := 0
LLOOP:
     MOV  DS,[BP+6]          ; While S[Z] <> #0 Do
     MOV  BX,[BP+4]
     MOV  SI,[BP-2]
     CMP  BYTE PTR [BX+SI],0
     JE   LEND
     INC  WORD PTR [BP-2]    ; Inc(Z)
     JMP  LLOOP
LEND:
     MOV  AX,[BP-2]          ; Length := Z
     POP  SI
     POP  BX
     POP  DS
     MOV  SP,BP
     POP  BP
     RET  4
CSLENGTH ENDP

INVERT PROC
; X = [BP+8]
; S (Segment) = [BP+6]
; S (Offset)  = [BP+4]
; C = [BP-1]
; Z = [BP-3]
     PUSH BP
     MOV  BP,SP
     SUB  SP,3
     PUSH DS
     PUSH AX
     PUSH BX
     PUSH SI
     MOV  AX,[BP+6]  ; Z := Length(S)
     PUSH AX
     MOV  AX,[BP+4]
     PUSH AX
     CALL CSLENGTH
     MOV  [BP-3],AX  ; If X < Z Div 2 Then
     MOV  AX,[BP-3]
     SHR  AX,1
     CMP  [BP+8],AX
     JAE  IEND
     MOV  DS,[BP+6]  ; C := S[X]
     MOV  BX,[BP+4]
     MOV  SI,[BP+8]
     MOV  AL,[BX+SI]
     MOV  [BP-1],AL
     MOV  SI,[BP-3]  ; S[X] := S[Z-X-1]
     SUB  SI,[BP+8]
     DEC  SI
     MOV  AL,[BX+SI]
     MOV  SI,[BP+8]
     MOV  [BX+SI],AL
     MOV  AL,[BP-1]  ; S[Z-X-1] := C
     MOV  SI,[BP-3]
     SUB  SI,[BP+8]
     DEC  SI
     MOV  [BX+SI],AL
     MOV  AX,[BP+8]  ; Invert(X+1,S)
     INC  AX
     PUSH AX
     MOV  AX,[BP+6]
     PUSH AX
     MOV  AX,[BP+4]
     PUSH AX
     CALL INVERT
IEND:
     POP  SI
     POP  BX
     POP  AX
     POP  DS
     MOV  SP,BP
     POP  BP
     RET  6
INVERT ENDP

OUTPUT PROC
; X = [BP+8]
; S (Segment) = [BP+6]
; S (Offset)  = [BP+4]
     PUSH BP
     MOV  BP,SP
     PUSH DS
     PUSH AX
     PUSH BX
     PUSH DX
     PUSH SI
     MOV  DS,[BP+6]          ; If S[X] <> #0 Then
     MOV  BX,[BP+4]
     MOV  SI,[BP+8]
     CMP  BYTE PTR [BX+SI],0
     JE   OEND
     MOV  AH,2               ; Write(S[X])
     MOV  DL,[BX+SI]
     INT  21h
     MOV  AX,[BP+8]          ; Output(X+1,S)
     INC  AX
     PUSH AX
     MOV  AX,[BP+6]
     PUSH AX
     MOV  AX,[BP+4]
     PUSH AX
     CALL OUTPUT
OEND:
     POP  SI
     POP  DX
     POP  BX
     POP  AX
     POP  DS
     POP  BP
     RET  6
OUTPUT ENDP

XDIRECTION PROC
; Z = [BP+8]
; Y = [BP+6]
; X = [BP+4]
     PUSH BP
     MOV  BP,SP
     PUSH AX
     PUSH DX
     MOV  DX,[BP+4]         ; Write(X:5)
     CALL DEZOUT
     CMP  WORD PTR [BP+8],1 ; If Z > 1 Then
     JBE  XDEND
     MOV  AX,[BP+8]         ; xDirection(Z-1,Y,X+Y)
     DEC  AX
     PUSH AX
     MOV  AX,[BP+6]
     PUSH AX
     ADD  AX,[BP+4]
     PUSH AX
     CALL XDIRECTION
XDEND:
     POP  DX
     POP  AX
     POP  BP
     RET  6
XDIRECTION ENDP

YDIRECTION PROC
; Z = [BP+6]
; Y = [BP+4]
     PUSH BP
     MOV  BP,SP
     PUSH AX
     PUSH DX
     MOV  AX,10             ; xDirection(10,Y,Y)
     PUSH AX
     MOV  AX,[BP+4]
     PUSH AX
     PUSH AX
     CALL XDIRECTION
     MOV  AH,2              ; WriteLn
     MOV  DL,13
     INT  21h
     MOV  DL,10
     INT  21h
     CMP  WORD PTR [BP+6],1 ; If Z > 1 Then
     JBE  YDEND
     MOV  AX,[BP+6]         ; yDirection(Z-1,Y+1)
     DEC  AX
     PUSH AX
     MOV  AX,[BP+4]
     INC  AX
     PUSH AX
     CALL YDIRECTION
YDEND:
     POP  DX
     POP  AX
     POP  BP
     RET  4
YDIRECTION ENDP

KLAUSUR PROC
     MOV  AX,DSEG
     MOV  DS,AX
     MOV  AX,0        ; Output(0,S)
     PUSH AX
     MOV  AX,SEG S
     PUSH AX
     MOV  AX,OFFSET S
     PUSH AX
     CALL OUTPUT
     MOV  AH,2        ; Write(' ','*',' ')
     MOV  DL,' '
     INT  21h
     MOV  DL,'*'
     INT  21h
     MOV  DL,' '
     INT  21h
     MOV  AX,0        ; Invert(0,S)
     PUSH AX
     MOV  AX,SEG S
     PUSH AX
     MOV  AX,OFFSET S
     PUSH AX
     CALL INVERT
     MOV  AX,0        ; Output(0,S)
     PUSH AX
     MOV  AX,SEG S
     PUSH AX
     MOV  AX,OFFSET S
     PUSH AX
     CALL OUTPUT
     MOV  AH,2        ; WriteLn
     MOV  DL,13
     INT  21h
     MOV  DL,10
     INT  21h
     MOV  DL,13       ; WriteLn
     INT  21h
     MOV  DL,10
     INT  21h
     MOV  AX,10       ; yDirection(10,1)
     PUSH AX
     MOV  AX,1
     PUSH AX
     CALL YDIRECTION
     MOV  AX,4C00h
     INT  21h
KLAUSUR ENDP

CSEG ENDS

IO   SEGMENT
     ASSUME CS:IO

DEZOUT PROC FAR
     PUSH AX
     PUSH BX
     PUSH CX
     PUSH DX
     MOV  AX,DX
     CMP  AX,0
     JE   DNULL3
     MOV  CX,5
DLOOP1:
     MOV  DX,0
     MOV  BX,10
     DIV  BX
     PUSH DX
     LOOP DLOOP1
     MOV  BX,0
     MOV  CX,5
DLOOP2:
     POP  DX
     ADD  BX,DX
     CMP  BX,0
     JE   DNULL1
     ADD  DL,'0'
     MOV  AH,2
     INT  21h
     JMP  DNULL2
DNULL1:
     MOV  DL,' '
     MOV  AH,2
     INT  21h
DNULL2:
     LOOP DLOOP2
     JMP  DEND
DNULL3:
     MOV  DL,'0'
     MOV  AH,2
     INT  21h
DEND:
     POP  DX
     POP  CX
     POP  BX
     POP  AX
     RET
DEZOUT ENDP

IO   ENDS

DSEG SEGMENT
S    DB   "Ein mal Eins",0,0,0,0
DSEG ENDS

SSEG SEGMENT STACK
     DW   1024 DUP (?)
SSEG ENDS

     END KLAUSUR