How buffer input works

Entering the next program works fine, but when I ask for output to be displayed, DOS does not display anything! How is this possible?

        ORG     256
        mov     dx, msg1
        mov     ah, 09h                 ;DOS.WriteString
        int     21h
        mov     dx, buf
        mov     ah, 0Ah                 ;DOS.BufferedInput
        int     21h
        mov     dx, msg2
        mov     ah, 09h                 ;DOS.WriteString
        int     21h
        mov     dx, buf
        mov     ah, 09h                 ;DOS.WriteString
        int     21h
        mov     ax, 4C00h               ;DOS.TerminateWithExitcode
        int     21h
; --------------------------------------
msg1:   db      'Input : ', '$'
buf:    db      20 dup ('$')
msg2:   db      13, 10, 'Output : ', '$'
; --------------------------------------
+4
source share
2 answers

, (buf: db 20 dup ('$')),   $-,   . , DOS   0Ah  .
, $- - ,   $ .     .

int 21h AH=0Ah

Buffered STDIN Input   , Enter.   ,   3- ,   DS:DX.
, ,  2- .
- DOS,   . 1-   . 1  , 2. 254   255.
, ,   2- .   ( ) ,  . ,  .

, .

  • Escape .
    , , , .
  • Backspace .
    , , . , , , . , backspacing , 1- !
  • F6 (1Ah) .
    "^ Z".
  • F7 .
    "^ @".
  • ctrl Enter ( ), , .

. EDLIN.EXE,   DOS, ,   , .

  • F1 .
  • F2 + ... , .
  • F3 .
  • F4 + ... , .
  • F5 .
  • Escape .
  • Delete .
  • Insert .
  • Backspace .
  • Left , Backspace.
  • Right , F1.

. Tab - ASCII 9 (ASCII 32),   , 8.
. ASCII 9.

ctrl C/ctrl Break  .

,   .

1, STDIN.

        ORG     256                     ;Create .COM program
        cld
        mov     si, msg1
        call    WriteStringDOS
        mov     dx, buf
        mov     ah, 0Ah                 ;DOS.BufferedInput
        int     21h
        mov     si, msg2
        call    WriteStringDOS
        mov     si, buf+2
        movzx   bx, [si-1]              ;Get character count
        mov     word [si+bx+1], 10      ;Keep CR, append LF and 0
        call    WriteStringDOS
        mov     ax, 4C00h               ;DOS.TerminateWithExitcode
        int     21h
; --------------------------------------
; IN (ds:si) OUT ()
WriteStringDOS:
        pusha
        jmps    .b
.a:     mov     dl, al
        mov     ah, 02h                 ;DOS.DisplayCharacter
        int     21h                     ; -> AL
.b:     lodsb
        test    al, al
        jnz     .a
        popa
        ret
; --------------------------------------
buf:    db      255, 16, "I'm the template", 13, 255-16-1+2 dup (0)
msg1:   db      'Choose color ? ', 0
msg2:   db      10, 'You chose ', 0
; --------------------------------------

int 21h AH=3Fh

0 ( BX) ,   Enter. ( 127)     DOS. .
, DS:DX,  , CX. CX   , ,   .   , ,   !   .

, .

, .

ctrl C/ctrl Break  .

,

  • , .
  • , .

2a, " ", .

        ORG     256                     ;Create .COM program
        cld
        mov     si, msg1
        call    WriteStringDOS
        mov     dx, buf
        mov     cx, 127+2               ;Max input is 127 chars + CR + LF
        xor     bx, bx                  ;STDIN=0
        mov     ah, 3Fh                 ;DOS.ReadFileOrDevice
        int     21h                     ; -> AX CF
        jc      Exit
        mov     bx, ax                  ;Bytes count is less than CX
        mov     si, msg2
        call    WriteStringDOS
        mov     si, buf
        mov     [si+bx], bh             ;Keep CR and LF, append 0 (BH=0)
        call    WriteStringDOS
Exit:   mov     ax, 4C00h               ;DOS.TerminateWithExitcode
        int     21h
; --------------------------------------
; IN (ds:si) OUT ()
WriteStringDOS:
        pusha
        jmps    .b
.a:     mov     dl, al
        mov     ah, 02h                 ;DOS.DisplayCharacter
        int     21h                     ; -> AL
.b:     lodsb
        test    al, al
        jnz     .a
        popa
        ret
; --------------------------------------
buf:    db      127+2+1 dup (0)
msg1:   db      'Choose color ? ', 0
msg2:   db      'You chose ', 0
; --------------------------------------

2b, " ", .

        ORG     256                     ;Create .COM program
        cld
        mov     si, msg1
        call    WriteStringDOS
        mov     dx, buf
        mov     cx, 1
        xor     bx, bx                  ;STDIN=0
        mov     ah, 3Fh                 ;DOS.ReadFileOrDevice
        int     21h                     ; -> AX CF
        jc      Exit
        mov     si, msg2
        call    WriteStringDOS
        mov     si, dx                  ;DX=buf, CX=1, BX=0
Next:   mov     ah, 3Fh                 ;DOS.ReadFileOrDevice
        int     21h                     ; -> AX CF
        jc      Exit
        call    WriteStringDOS          ;Display a single byte
        cmp     byte [si], 10
        jne     Next
Exit:   mov     ax, 4C00h               ;DOS.TerminateWithExitcode
        int     21h
; --------------------------------------
; IN (ds:si) OUT ()
WriteStringDOS:
        pusha
        jmps    .b
.a:     mov     dl, al
        mov     ah, 02h                 ;DOS.DisplayCharacter
        int     21h                     ; -> AL
.b:     lodsb
        test    al, al
        jnz     .a
        popa
        ret
; --------------------------------------
msg1:   db      'Choose color ? ', 0
msg2:   db      10, 'You chose '
buf:    db      0, 0
; --------------------------------------

int 2Fh AX=4810h

DOSKEY Buffered STDIN Input if   DOSKEY.COM TSR. ,  STDIN 0Ah (. ),   DOS,   DOSKEY.

  • Up .
  • Down .
  • F7 .
  • Alt F7 .
  • ... F8 (), ...
  • F9 .
  • Alt F10 .

DOS 6.2 128 ,   127 .   , 2-   .
DOS Win95 255 ,  DOSKEY.COM TSR doskey /line:255.   . Win95   , 0Ah.

ctrl C/ctrl Break  .

,   . , ,   DOSKEY, .   !  , ,   .
, ($T)   1- .   .   , COMMAND.COM,   , , .

, ,   . , ,   DOS!

3: DOSKEY.COM.

        ORG     256                     ;Create .COM program
        cld
        mov     ax, 4800h               ;DOSKEY.CheckInstalled
        int     2Fh                     ; -> AL
        test    al, al
        mov     si, err1
        jz      Exit_
Again:  mov     si, msg1
        call    WriteStringDOS
        mov     dx, buf
        mov     ax, 4810h               ;DOSKEY.BufferedInput
        int     2Fh                     ; -> AX
        test    ax, ax
        mov     si, err2
        jnz     Exit_
        cmp     [buf+1], al             ;AL=0
        je      Again                   ;Macro expansion needed
        mov     si, msg2
        call    WriteStringDOS
        mov     si, buf+2
        movzx   bx, [si-1]              ;Get character count (is GT 0)
        mov     word [si+bx+1], 10      ;Keep CR, append LF and 0
Exit_:  call    WriteStringDOS
Exit:   mov     ax, 4C00h               ;DOS.TerminateWithExitcode
        int     21h
; --------------------------------------
; IN (ds:si) OUT ()
WriteStringDOS:
        pusha
        jmps    .b
.a:     mov     dl, al
        mov     ah, 02h                 ;DOS.DisplayCharacter
        int     21h                     ; -> AL
.b:     lodsb
        test    al, al
        jnz     .a
        popa
        ret
; --------------------------------------
buf:    db      128, 0, 128+2 dup (0)
msg1:   db      'Choose color ? ', 0
msg2:   db      13, 10, 'You chose ', 0
err1:   db      'N/A', 13, 10, 0
err2:   db      'Failed', 13, 10, 0
; --------------------------------------

int 21h AH=08h

- 30000 , Qaru , ...

? , :

  • , (.) 1-
  • , (:) 2
  • - (SIMO), push cx si push cx push si.
+3

int 21h AH=08h

, ( !), Microsoft, EDLIN.EXE COMMAND.COM.
,   .   DOS. STDIN   08h,  ctrl C/ctrl Break   - BIOS Int 10h AH=09h   . ,   .

BufferedInput   DOS.BufferedInput.   , ,     , .

  • Left .
  • Right .
  • Home .
  • End .
  • ctrl Home .
  • ctrl End .
  • Delete .
  • Backspace .
  • Escape .
  • Return .

,   (, ).   . DOS, :

  • .
  • .

, ,   . .
,   ( ASCII 9) .

ctrl C/ctrl Break  .

,   .

  , , , .
, - . , .

4: STDIN.

        ORG     256                     ;Create .COM program
        cld
        mov     si, msg1
        call    WriteStringDOS
        mov     dx, buf
        call    BufferedInput           ;Replaces 'mov ah, 0Ah : int 21h'
        mov     si, msg2
        call    WriteStringDOS
        mov     si, buf+2
        movzx   bx, [si-1]              ;Get character count
        mov     word [si+bx+1], 10      ;Keep CR, append LF and 0
        call    WriteStringDOS
        mov     ax, 4C00h               ;DOS.TerminateWithExitcode
        int     21h
; --------------------------------------
; IN (ds:si) OUT ()
WriteStringDOS:
        pusha
        jmps    .b
.a:     mov     dl, al
        mov     ah, 02h                 ;DOS.DisplayCharacter
        int     21h                     ; -> AL
.b:     lodsb
        test    al, al
        jnz     .a
        popa
        ret
; --------------------------------------
; IN (ds:dx) OUT ()
BufferedInput:

; Entry DS:DX   Buffer of max 1+1+255 bytes
;               1st byte is size of storage space starting at 3rd byte
;               2nd byte is size of old (CR-terminated) string, 0 if none
;               Storage space can contain old (CR-terminated) string
; Exit  DS:DX   Nothing changed if header bytes were invalid
;               1st byte unchanged
;               2nd byte is size of new CR-terminated string
;               Storage space contains new CR-terminated string
; Local [bp-1]  PAGE    Display page
;       [bp-2]  STORE   Size of storage space
;       [bp-3]  ROW     Row of input box
;       [bp-4]  COL     Column of input box
;       [bp-5]  SHIFT   Number of characters shifted out on the leftside
;       [bp-6]  INBOX   Size of input box
;       [bp-7]  LIX     Number of characters in current input string
;       [bp-8]  CIX     Position of cursor in current input string
;       [bp-10] FLAGS   Bit[0] is ON for normal keyboard input

        pusha
        mov     si, dx
        lodsw                           ; -> SI points at storage space
        test    al, al                  ;AL is size of storage space
        jz      .Quit                   ;No storage space!
        cmp     ah, al                  ;AH is size of old string
        jnb     .Quit                   ;Old string too long!
        mov     bl, al

        sub     sp, 256                 ;Local edit buffer (max size)
        mov     bp, sp
        mov     ah, 0Fh                 ;BIOS.GetVideoMode
        int     10h                     ; -> AL=Mode AH=Cols BH=Page
        push    bx                      ;STORE and PAGE
        mov     bl, ah
        mov     ah, 03h                 ;BIOS.GetCursor
        int     10h                     ; -> CX=Shape DL=Col DH=Row
        push    dx                      ;COL and ROW
        sub     bl, dl                  ;Size of the widest inbox
        xor     bh, bh
        push    bx                      ;INBOX and SHIFT
        push    bx                      ;CIX and LIX (replaces 'sub sp, 2')

        call    .ESC                    ;Clear edit buffer, reset some vars
        mov     cl, [si-1]              ;Size of old string (starts at SI)
        jmps    .b
.a:     lodsb                           ;Storage space gives old string
        push    cx si
        call    .Asc                    ;Input old string
        pop     si cx
.b:     sub     cl, 1
        jnb     .a

        xor     bx, bx                  ;STDIN
        mov     ax, 4400h               ;DOS.GetDeviceInformation
        int     21h                     ; -> AX DX CF
        jc      .c                      ;Go default to keyboard
        test    dl, dl
        jns     .d                      ;Block device, not keyboard
        shr     dl, 1
.c:     adc     bx, bx                  ; -> BX=1 if Keyboard
.d:     push    bx                      ;FLAGS

.Main:  call    .Show                   ;Refresh input box on screen
        call    .Key                    ;Get key from DOS -> AX
        mov     bx, .Scans
        test    ah, ah
        jz      .f                      ;Not an extended ASCII
        mov     [cs:.Fail], ah          ;Sentinel
.e:     lea     bx, [bx+3]
        cmp     ah, [cs:bx-1]
        jne     .e
.f:     call    [cs:bx]
        jmps    .Main

.Quit:  popa                            ;Silently quiting just like DOS
        ret
; - - - - - - - - - - - - - - - - - - -
.Scans: db           .Asc
        db      4Bh, .s4B               ;<LEFT>
        db      4Dh, .s4D               ;<RIGHT>
        db      47h, .s47               ;<HOME>
        db      4Fh, .s4F               ;<END>
        db      77h, .s77               ;<CTRL-HOME>
        db      75h, .s75               ;<CTRL-END>
        db      53h, .s53               ;<DELETE>
.Fail:  db        ?, .Beep
; - - - - - - - - - - - - - - - - - - -
.Beep:  mov     ax, 0E07h               ;BIOS.TeletypeBell
        int     10h
        ret
; - - - - - - - - - - - - - - - - - - -
.Key:   call    :1
        test    ah, ah                  ;Extended ASCII requires 2 calls
        jnz     :2
:1:     mov     ah, 08h                 ;DOS.STDINInput
        int     21h                     ; -> AL
        mov     ah, 0
:2:     xchg    al, ah
        ret
; - - - - - - - - - - - - - - - - - - -
.Show:  test    word [bp-10], 1         ;FLAGS.Keyboard ?
        jz      :Ready                  ;No, input is redirected
        movzx   di, [bp-6]              ;INBOX
        movzx   si, [bp-5]              ;SHIFT
        mov     dx, [bp-4]              ;COL and ROW
        mov     cx, 1                   ;Replication count
        mov     bh, [bp-1]              ;PAGE
        mov     bl, 07h                 ;WhiteOnBlack
:Next:  mov     ah, 02h                 ;BIOS.SetCursor
        int     10h
        mov     al, [bp+si]
        mov     ah, 09h                 ;BIOS.WriteCharacterAndAttribute
        int     10h
        inc     dl                      ;Next column
        inc     si                      ;Next character
        dec     di
        jnz     :Next                   ;Process all of the input box

        mov     dx, [bp-4]              ;COL and ROW
        add     dl, [bp-8]              ;CIX
        sub     dl, [bp-5]              ;SHIFT
        mov     ah, 02h                 ;BIOS.SetCursor
        int     10h
:Ready: ret
; - - - - - - - - - - - - - - - - - - -
.BS:    cmp     byte [bp-8], 0          ;CIX
        jne     :1
        ret
:1:     call    .s4B                    ;<LEFT>
; ---   ---   ---   ---   ---   ---   --
; <DELETE>
.s53:   movzx   di, [bp-8]              ;CIX
        movzx   cx, [bp-7]              ;LIX
        sub     cx, di
        je      :2                      ;Cursor behind the current input
:1:     mov     dl, [bp+di+1]           ;Move down in edit buffer
        mov     [bp+di], dl
        inc     di
        dec     cx
        jnz     :1
        dec     byte [bp-7]             ;LIX
:2:     ret
; - - - - - - - - - - - - - - - - - - -
.RET:   xor     si, si
        mov     bx, [bp+256+10]         ;pusha.DX -> DS:BX
        mov     al, [bp-7]              ;LIX
        inc     bx
        mov     [bx], al                ;2nd byte is size of new string
        inc     bx
        jmps    :2
:1:     mov     dl, [bp+si]
        mov     [bx+si], dl             ;Storage space receives new string
        inc     si
:2:     sub     al, 1
        jnb     :1
        mov     byte [bx+si], 13        ;Terminating CR

        push    bx                      ;(1)
        call    .ESC                    ;Wipe clean the input box
        call    .Show                   ; and reset cursor
        pop     si                      ;(1) -> DS:SI
:3:     lodsb                           ;Final unrestricted display,
        mov     dl, al                  ; expanding tabs
        mov     ah, 02h                 ;DOS.DisplayCharacter
        int     21h                     ; -> AL
        cmp     dl, 13                  ;Cursor ends in far left column
        jne     :3

        lea     sp, [bp+256]            ;Free locals and edit buffer
        popa
        ret
; - - - - - - - - - - - - - - - - - - -
.ESC:   mov     di, 256                 ;Fill edit buffer with spaces
:1:     sub     di, 2
        mov     word [bp+di], "  "
        jnz     :1
        mov     [bp-8], di              ;DI=0 -> CIX=0 LIX=0
        mov     byte [bp-5], 0          ;SHIFT=0
        ret
; - - - - - - - - - - - - - - - - - - -
.Asc:   cmp     al, 8                   ;<BACKSPACE>
        je      .BS
        cmp     al, 13                  ;<RETURN>
        je      .RET
        cmp     al, 27                  ;<ESCAPE>
        je      .ESC
        cmp     al, 10                  ;Silently ignoring linefeed
        jne     :1                      ; in favor of input redirection
        ret
:1:     movzx   di, [bp-8]              ;CIX
        movzx   si, [bp-7]              ;LIX
        lea     dx, [si+1]
        cmp     dl, [bp-2]              ;STORE
        jb      :3
        jmp     .Beep                   ;Storage capacity reached
:2:     mov     dl, [bp+si-1]           ;Move up in edit buffer
        mov     [bp+si], dl
        dec     si
:3:     cmp     si, di
        ja      :2
        mov     [bp+si], al             ;Add newest character
        inc     byte [bp-7]             ;LIX
; ---   ---   ---   ---   ---   ---   --
; <RIGHT>
.s4D:   inc     byte [bp-8]             ;CIX
        mov     al, [bp-7]              ;LIX
        cmp     [bp-8], al              ;CIX
        jbe     .Shift
        mov     [bp-8], al              ;CIX
        ret
; - - - - - - - - - - - - - - - - - - -
; <LEFT>
.s4B:   sub     byte [bp-8], 1           ;CIX
        jnb     .Shift
; ---   ---   ---   ---   ---   ---   --
; <HOME>
.s47:   mov     byte [bp-8], 0          ;CIX
        jmps    .Shift
; - - - - - - - - - - - - - - - - - - -
; <END>
.s4F:   mov     al, [bp-7]              ;LIX
        mov     [bp-8], al              ;CIX
; ---   ---   ---   ---   ---   ---   --
.Shift: mov     dl, [bp-5]              ;SHIFT
        mov     al, [bp-8]              ;CIX
        cmp     al, dl
        jb      :1
        add     dl, [bp-6]              ;INBOX
        sub     al, dl
        jb      :2
        inc     al
        add     al, [bp-5]              ;SHIFT
:1:     mov     [bp-5], al              ;SHIFT
:2:     ret
; - - - - - - - - - - - - - - - - - - -
; <CTRL-HOME>
.s77:   call    .BS
        cmp     byte [bp-8], 0          ;CIX
        ja      .s77
        ret
; - - - - - - - - - - - - - - - - - - -
; <CTRL-END>
.s75:   call    .s53                    ;<DELETE>
        mov     al, [bp-8]              ;CIX
        cmp     al, [bp-7]              ;LIX
        jb      .s75
        ret
; --------------------------------------
buf:    db      255, 16, "I'm an OldString", 13, 255-16-1+2 dup (0)
msg1:   db      'Choose color ? ', 0
msg2:   db      10, 'You chose ', 0
; --------------------------------------

? , :

  • , (.) 1-
  • , (:) 2
  • - (SIMO), push cx si push cx push si.

Rich Edit Form Input, " ".

+2

Source: https://habr.com/ru/post/1689533/


All Articles