CODE_DATA_SEG   SEGMENT
                ASSUME CS:CODE_DATA_SEG,DS:CODE_DATA_SEG
                ORG     100h

CR              EQU     13           ; Carriage Return
LF              EQU     10           ; Line Feed

DISP_BLOCK      PROC NEAR
                MOV     BX,0         ; BX : Indizierung BLOCK
                MOV     CX,16        ; CX (DISP_BLOCK) : Anzahl Zeilen
LINE_LOOP:
                CALL    DISP_LINE
                MOV     AH,02h       ; MS-DOS Funktion 2, Zeichenausgabe
                MOV     DL,CR        ; entspricht MOV DL,13
                INT     21h
                MOV     DL,LF        ; entspricht MOV DL,10
                INT     21h
                ADD     BX,16        ; naechste Zeile
                LOOP    LINE_LOOP    ; alle Zeilen bearbeitet ?
                INT     20h
DISP_BLOCK      ENDP

DISP_LINE       PROC NEAR
                PUSH    CX           ; CX aus DISP_BLOCK sichern
                MOV     CX,16        ; CX (DISP_LINE) : Anzahl Spalten
                PUSH    BX           ; Index sichern (Zeilenanfang)
HEX_LOOP:
                MOV     DL,BLOCK[BX] ; hoeherwertige Bits ausgeben
                PUSH    CX           ;   hoeherwertige Bits rechtsschieben
                MOV     CL,4
                SHR     DL,CL
                POP     CX
                CALL    WRITE_DIGIT
                MOV     DL,BLOCK[BX] ; niederwertige Bits ausgeben
                AND     DL,0Fh       ;   niederwertige Bits maskieren
                CALL    WRITE_DIGIT
                MOV     AH,02h       ; MS-DOS Funktion 2, Zeichenausgabe
                MOV     DL,' '
                INT     21h
                INC     BX           ; naechste Spalte
                LOOP    HEX_LOOP     ; alle Spalten (Zahlen) bearbeitet ?

                POP     BX           ; Index restaurieren (Zeilenanfang)
                PUSH    BX           ; Index sichern (Zeilenanfang)
                MOV     CX,16        ; CX (DISP_LINE) : Anzahl Spalten
ASCII_LOOP:
                MOV     AH,02h       ; MS-DOS Funktion 2, Zeichenausgabe
                MOV     DL,BLOCK[BX]
                CMP     DL,20h       ; Zeichen druckbar ?
                JAE     DRUCKBAR     ; ja, ausgeben
                MOV     DL,'.'       ; nein, stattdessen . ausgeben
DRUCKBAR:
                INT     21h
                INC     BX           ; naechste Spalte
                LOOP    ASCII_LOOP   ; alle Spalten (Zeichen) bearbeitet ?

                POP     BX           ; Index ruecksichern (Zeilenanfang)
                POP     CX           ; CX fuer DISP_BLOCK restaurieren
                RET
DISP_LINE       ENDP

WRITE_DIGIT     PROC NEAR
                ADD     DL,30h       ; ASC-II Code der Ziffer generieren
                CMP     DL,3Ah       ; Ziffer gehoert der Gruppe 0..9 an ?
                JB      DIGIT_OK
                ADD     DL,07h       ; ASC-II Code korrigieren
DIGIT_OK:
                MOV     AH,02h       ; MS-DOS Funktion 2, Zeichenausgabe
                INT     21h
                RET
WRITE_DIGIT     ENDP

BLOCK           DB 16 DUP (30h)      ; 16 Zeilen * 16 Spalten
                DB 16 DUP (31h)
                DB 16 DUP (32h)
                DB 16 DUP (33h)
                DB 16 DUP (34h)
                DB 16 DUP (35h)
                DB 16 DUP (36h)
                DB 16 DUP (37h)
                DB 16 DUP (38h)
                DB 16 DUP (39h)
                DB 16 DUP (3Ah)
                DB 16 DUP (3Bh)
                DB 16 DUP (3Ch)
                DB 16 DUP (3Dh)
                DB 16 DUP (3Eh)
                DB 16 DUP (3Fh)

CODE_DATA_SEG   ENDS
                END DISP_BLOCK