ok this is test code.. what I am trying to do is have 8 command line buffers so that when i press up or down arrow it will load the appropriate command line. but I'm having trouble saving them and retrieving them. I'm pretty sure address 0x9400:0x0000 is safe, but i could be wrong. This is in stage two, real mode. Each buffer is 64 bytes long. total of 512 bytes for the buffer, and an additional 16 bytes for other temporary data. (will be 4MiB for protected mode... don't ask). I've tried various ways of doing this and thought I had this memory issue working with another problem i had before. Everything goes fine until I add the code below the dashes. Not sure exactly what I'm doing wrong. Still waiting on books...  :sad:

i have chosen not to echo the inputs... yet. I would think it would still work.. a far as saving the values in memory. I then will print out the value in memory after I know it's saving. but as far as I can tell it's not getting to the ret... my very next call is to a function i know that works and continues to work if I omit this function entirely... but maybe I'm not pushing or popping right. Any help would be appreciated... if you need other code segments let me know.

keyboard_buffers_segment     dw 0x9400

mov  AH, 00h
int  16h

  call  getc
  cmp  AL, 00h                                ;Is this a special funtion?
  jz    get_command                        ;If it is ignore and continue
  cmp  AL, 0Dh                              ;Enter Key Pressed
  mov  SI, 0x00                                    ; set SI to 0x00
  mov  DS,         ;set Data Segment to 0x9400
  mov  , AL                                ;write AL to
  inc  SI                                      ;increment SI so we write to next position
  jne  get_command                        ;Continue if enter not pressed
Posted on 2009-11-06 19:28:10 by Goose007

much to my dismay i looked elsewhere and could find anything helpful that worked. I even tried the following code. it kinda works... except I still can't tell if it's going to the right place... is there a surefire way to print out an address in memory before and after to see if I'm at least changing it?  notice I commented out the putc call


xor CL, CL
mov AX,
mov ES, AX
xor AX, AX
  mov DI, AX
call getc

cmp al, 0x08 ; backspace pressed?
  je .backspace ; yes, handle it

  cmp al, 0x0D ; enter pressed?
  je .done ; yes, we're done

cmp cl, 0x3F  ; 63 chars inputted?
  je .loop ; yes, only let in backspace, enter or delete

; call putc  ; print out character

stosb  ; put character in buffer
inc cl
jmp .loop

cmp cl, 0 ; beginning of string?
  je .loop ; yes, ignore the key

dec di
mov byte , 0 ; delete character
dec cl ; decrement counter as well

mov ah, 0x0E
mov al, 0x08
int 10h ; backspace on the screen

mov al, ' '
int 10h ; blank character out

mov al, 0x08
int 10h ; backspace again

jmp .loop ; go to the main loop

mov al, 0 ; null terminator

mov ah, 0x0E
mov al, 0x0D
int 0x10
mov al, 0x0A
int 0x10 ; newline
Posted on 2009-11-06 22:10:00 by Goose007
Well... the most obvious problem with your first attempt is that you were setting si to zero every time through the loop. You increment it after saving the character, but then set it back to zero next time through, so everything was being saved to 9400h:0!

Your second attempt proves you know how to handle backspace, at least. :) It looks like it should work... for one command, at least. For a "command line history", you probably want to pass the buffer address as a parameter to "get_command", rather than explicitly set di within the routine. You may want to pass the segment as a parameter, too(?). It might be simpler to get it working with everything in one segment - I find that 64k is a "lot" of room. If you're going to put your buffers in a separate segment, you may want to put ds/es back the way they were before returning from the routine(?).

You didn't write "gets()" - you check to see that a character will fit in the buffer before saving it. Excellent! ("gets()" needs to be "terminated with extreme predjudice"... and its head mounted on a pike!) The way you're doing it, the buffer may not be zero-terminated. I think the way I dealt with that was to zero-terminate the buffer after every character was added, whether I was "done" or not (but, of course, making sure there was room in the buffer first!). It gets quite complicated - especially when you get to handling "insert" (if you're going to). Making sure you're not at the beginning of the buffer before doing "backspace" is a good start!

I started out with a simple "get string" (respecting the buffer length, of course!), and started adding features... right and left arrow keys, overwrite/insert (toggled with the insert key... with a changed cursor to indicate current mode). To implement "command line history", I wanted to be able to display a "default string" (editable), and handle up and down arrows. But I didn't want to always handle up/down, so I used a zero-terminated array of "extra keys to cause early termination", besides the usual 0Dh... It has gotten horribly convoluted!

As far as "writing what you saved" (or not)... the bytes do get saved (unless there's a CPU bug), but the question is "where?". The same question arises when you go to print it - "mov al, " and int 10h/0Eh will print something from somewhere. If you're storing it with "stosb", you might want "mov al, "... But if you make the same mistake both times, it might appear to work, but might not be storing where you intend. The main rule would be "pay attention to your segment registers", I guess.

If you temorarily replaced "putc" with a special routine that independently printed "where you expect this stuff to be", it might help(?).

call get_command

push ds
mov ax,
mov ds, ax
xor si, si
mov ah, 0Eh
mov bx, 7
cmp al, 0
jz .done
int 10h
jmp short .top
pop ds

Or so...

Might as well put "putc" back, since you're printing something for "backspace" and a CR/LF at the end...


Posted on 2009-11-07 05:02:04 by fbkotler