A Working Console

A Working Console

Robbert Haarman

2010-12-11


Introduction

In the previous chapter, we developed a kernel with a keyboard driver that printed the characters that the user typed on the screen. In this chapter, we will save the characters to a buffer and implement a function that reads a character from this buffer if any are available. This will allow us to write simple interactive programs.


The Input Buffer

We will use a circular buffer to store the characters typed at the keyboard. A circular buffer consists of a block of memory and two indices, one of which indicates the beginning of the data, the other one the end. When an item is placed in the buffer, the end indexis incremented. When an item is taken from the buffer, the begin index is incremented. When an index runs past the end of the block, it wraps around to the beginning. This is what makes the buffer circular.

Of course, the circular nature of the buffer means that we run the risk of the writing task overwriting values that the reading task has not yet read, or the reading task reading values that have not yet been written. We say that the buffer is empty if the begin and end indices are equal, and full if incrementing the end index (wrapping it around as necessary) would make it equal to the begin index. Then, we prevent the writing task from writing to a full buffer, and the reading process from reading from an empty one.


The Code

We change the keyboard interrupt service routine from the previous chapter, by replacing the part that prints the received character by the following code:


mov bl, [cs:lastInput]
inc bl
and bl, 15
cmp bl, [cs:firstInput]
je .end	; buffer full, discard character
xor bh, bh
mov [cs:inputBuffer + bx - 1], al
mov [cs:lastInput], bl

Then, we define the following function to read characters from the buffer:


readChar:
; Read character
; In: none
; Out: ASCII code in AL
; Global:
;	firstInput (modified)
mov bl, [cs:firstInput]
.loop0:
cmp bl, [cs:lastInput]
jne .end
hlt
jmp .loop0
.end:
xor bh, bh
mov al, [cs:inputBuffer + bx]
inc bl
and bl, 15
mov [cs:firstInput], bl
ret

The hlt halts the CPU until an IRQ occurs. Since we know the condition we are testing for can only change after the occurrence of an IRQ, we can safely do this. On some systems, it saves power.

Finally, we define the following function to read a line from the console:


readLine:
; Read line
; In:
;	buffer address (word)
;	buffer size (word)
; Out:
;	string length (ax)
push bp
mov bp, sp
mov di, [bp + 4]
push es
push ds
pop es
mov cx, [bp + 6]
.loop0:
call readChar
cmp al, 13
je .end
stosb
loop .loop0
.end:
pop es
sub di, [bp + 4]
mov ax, di
pop bp
ret

Files

The file console_kernel.asm contains the source for the kernel developed in this chapter.

Next part: System Calls

Valid XHTML 1.1! Valid CSS! Viewable with Any Browser