0

Essentially what I am working on is building a simple console-based OS that is similar to MS-DOS in functionality. I understand that a project like this couldn't be easily maintained, and I don't really care ;). So here is what I have made so far:

   ;------------------------------------------------------
   ;|                 SMOS Shell Source                  |
   ;|          Kept under GPLv3 Open Source license      |
   ;|         (https://www.gnu.org/licenses/gpl.txt)     |
   ;------------------------------------------------------

BITS 16

start:
     mov ax, 07C0h
     add ax, 288
     mov ss, ax
     mov sp, 4096

     mov ax, 07C0h
     mov ds, ax
     jmp kool

kool:
    mov si, lineone
    call print_string
    mov si, linetwo
    call print_string
    mov si, linethree
    call print_string
    call newline
    mov si, shellprompt
    call print_string
    jmp type

shell:
    call newline
    mov si, shellprompt
    call print_string
    jmp type

    lineone db '----------------------',13,10,0
    linetwo db '|   WELCOME TO SMOS  |',13,10,0
    linethree db '----------------------',13,10,0
    shellprompt db 'smos> ',0
    break db 13,10,0



clearscreen:
    mov ah, 0x06
    mov al, 0
    int 10h
type:
    mov ah,0h
    int 16h
    jmp shell
print_string:
    mov ah, 0Eh

.repeat:
    lodsb
    cmp al, 0
    je done 
    int 10h 
    jmp .repeat
newline:
    mov si, break
    call print_string

done:
    ret


    times 510-($-$$) db 0
    dw 0xAA55

What I would like is a way to get a keypress and print it onto the smos> shell line. So if the user typed test it would display smos> test and if the user presses enter it will be able to be stored, and then acted upon. I have looked for anything similar to my question and you can see that in the type: function it stops the process until a key is pressed, which is an attempt I found. However, I can't figure out how to continue the code to get the result I explained. Anyway, remember when you're answering I'm new to assembly so treat me like a 5-year-old when explaining things. Thanks in advance!

  • What is the problem? You are using the BIOS interrupts, so everything should be smooth. Have you consulted the [RBIL](http://www.ctyme.com/intr/int.htm)? Start from int 10h and int 16h. – Margaret Bloom Apr 28 '18 at 07:06
  • I can't figure out how to do it. As I said, I'm new to Assembly. –  Apr 28 '18 at 07:44
  • To clarify, I want to use the print_screen function to output `al`. What I have done sets `al` to my ASCII character. I want to put that in a form of which I can use the print_string function for it, and also be able to store the typed characters for later use. –  Apr 28 '18 at 08:03
  • @DecstarG - And we can't see where the problem is. After waiting for the key to be pressed, the value of the key is returned in a register. You would likely have to save it somewhere (perhaps a `line_input` variable?), if you want to collect several keys. But otherwise you already *have* a solution. – Bo Persson Apr 28 '18 at 08:13
  • @Bo Persson - That is the problem, I don't know _how_ to save it to register. I would like to be able to save it like `myvar db, al,0`. `al` being the keystroke stored from `int 16h`. –  Apr 28 '18 at 08:20
  • Then it seems like you have perhaps jumped ahead of yourself and should do some other exercises before writing a new operating system. The instruction you are looking for is `mov something, al`, where `something` depends on *lots* of stuff that doesn't fit in a comment box. – Bo Persson Apr 28 '18 at 08:49

1 Answers1

1

Your question is too broad to be answered, but I can address the issue you seem to be stuck with at the moment:

That is the problem, I don't know how to save it to register. I would like to be able to save it like myvar db, al,0. al being the keystroke stored from int 16h. – DecstarG 4 hours ago

The trick is to save your keystrokes in memory.
First you'll have to reserve a block of memory, you can use the stack for that (See: What is stack frame in assembly?), or use a memory manager (See here: https://github.com/jakubbogucki/memoryManager), Or just use a fixed buffer in memory (see: 3.2.2 RESB and Friends: Declaring Uninitialized Data) that is only used for that.

Keep a close watch on buffer overflows, You must do checking to ensure you do not read and write past the end of the buffer.

Storing stuff in memory is simple:

keybuffer: resb 1024
endofbuffer: resb 1

mov si,keybuffer         ;get the keybuffer address
loop:
....                     ;get the keystroke somehow.
mov [si],al              ;Store the keystroke (assuming it's in AL             
inc si                   ;Go to the next space in the buffer
mov di,endofbuffer       ;Is the buffer full?
cmp di,si                ;
je BufferIsFull          ;yes, jump to the code to handle this.
jmp loop                 ;we're still good, keep reading keys.

If you want to have a look at someone else's attempt at writing an OS from scratch, check out: http://mikeos.sourceforge.net/write-your-own-os.html

Johan
  • 74,508
  • 24
  • 191
  • 319
  • MikeOS is exactly what tutorial his bootloader code is based on. Also no reason to waste a byte with `endofbuffer: resb 1`.Can simply be `endofbuffer:` since all one cares about is the address of the label. Also no reason to place `mov di,endofbuffer` in the loop itself – Michael Petch Apr 28 '18 at 14:03