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.
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
getc:
mov AH, 00h
int 16h
ret
get_command:
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
ret
Progress????
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
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
get_command:
xor CL, CL
mov AX,
mov ES, AX
xor AX, AX
mov DI, AX
.loop:
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
.backspace:
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
.done:
mov al, 0 ; null terminator
stosb
mov ah, 0x0E
mov al, 0x0D
int 0x10
mov al, 0x0A
int 0x10 ; newline
ret
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
.top:
lodsb
cmp al, 0
jz .done
int 10h
jmp short .top
.done
pop ds
...
Or so...
Might as well put "putc" back, since you're printing something for "backspace" and a CR/LF at the end...
Best,
Frank
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
.top:
lodsb
cmp al, 0
jz .done
int 10h
jmp short .top
.done
pop ds
...
Or so...
Might as well put "putc" back, since you're printing something for "backspace" and a CR/LF at the end...
Best,
Frank