; Print AL space: mov al, ' ' putc: push bx xor bx, bx mov ah, 0x0e int 0x10 pop bx ret ; Print code string CS:SI putcs: push ds push cs pop ds call putds pop ds ret ; Print data string DS:SI putds: lodsb test al, al jz .ret call putc jmp putds .ret: ret crlf: mov al, 0x0A call putc mov al, 0x0D jmp putc print_dl: mov cl, 4 ; repeat 2 times call .c .c: mov al, dl shl dx, cl shr al, cl add al, 0x30 cmp al, 0x3a jl putc add al, 7 jmp putc print_dx: mov cl, 4 ; this double-call is essentially a 4 times repeating loop call .c1 .c1: call .c2 .c2: ; grab highest nibble from dx mov al, dh ; remove highest nibble from dx shl dx, cl ; shift away second-highest nibble that we accidentally copied shr al, cl ; map 0-9 to ascii codes for '0' to '9' add al, 0x30 ; if result is larger than '9', ... cmp al, 0x3a jl putc ; ... add 7 so we continue at 'A' add al, 7 jmp putc print_esbx: push cx push dx mov dx, es call print_dx mov al, ':' call putc mov dx, bx call print_dx pop dx pop cx ret ; Read character getc: xor ax, ax int 0x16 test al, al jz getc test al, 0x80 jnz getc ret ; Read uppercased character getcu: call getc cmp al, 'a' jc .ret cmp al, 'z' ja .ret and al, 0xDF .ret: ret ; Read hexadecimal character getch: call getcu ; everything above F is invalid cmp al, 'F' ja getch ; everything above or equal A is ok cmp al, 'A' jae .ret ; everything above 9 is invalid cmp al, '9' ja getc ; everything above or equal 0 is valid cmp al, '0' jae .ret ; everything above or equal ' ' is invalid cmp al, ' ' jae getch .ret: ret ; Read string into inbuf ; IN ingetc ptr to getc function ; inlen max number of chars gets: push bx mov di, inbuf ; calculate max pointer for writing mov dx, [inmin] .loop: call [ingetc] ; test for Ctrl+C, Enter and Backspace cmp al, 0x03 je .can cmp al, 0x0D je .enter cmp al, 0x08 je .bs ; ignore other ctl chars cmp al, 0x20 jc .loop ; check if we are full mov bx, di sub bx, inbuf ; bl is now number of characters we have cmp bl, dh jnc .loop stosb call putc jmp .loop ; backspace: print, print space, print backspace again .bs: cmp di, inbuf jbe .loop push ax call putc call space pop ax call putc dec di jmp .loop ; ctrl+c: return with carry set .can: stc pop bx ret ; enter: if enough chars, return .enter: mov bx, di sub bx, inbuf cmp bl, dl jc .loop xor al, al stosb pop bx ret