Improvements for Real mode assembly I tutorial

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
WaterOS
Member
Member
Posts: 25
Joined: Mon Jan 16, 2017 3:39 pm

Improvements for Real mode assembly I tutorial

Post by WaterOS »

Hey... These are improvements with a few more commands. This is for people who want more commands (like pause, cls). I do not own this code. To make the code smaller, you can remove the first part (putting ax into registers and putting 0x7C00 into stack pointer). You can even replace mov ds, ax and etc. with xor dx, dx. However, it's still good doing things like this but it is not really required.

This can be used as a bootloader or kernel. The point of this thread is nothing to do with post boosting, causing harmful things happen etc. This is an extended version of the shell tutorial of Real mode assembly I.

By the way, talking about hacks with programming, the space part in backspace is kinda like a hack. Never mind. It doesn't have to work on 100 unique computers.

You want your Windows games on it, huh? Well, if that's you wanna do, do it! It might take years but if you really want to make an OS that runs Windows stuff on it, it's gonna be really hard. Good luck. Remember now. I think you could try emulating the DOS API. The source code has been released.

Want a GUI? You can do that in a month if you know what to write (using some INT 10h functions etc).
However, voice recognition won't work. No RAD tools. Completely void of it :) the ones who don't understand the joke: Void is what is used in programming... Voice takes years.

Copyright (c) OSDev Wiki

Code: Select all

 org 0x7C00   ; add 0x7C00 to label addresses
 bits 16      ; tell the assembler we want 16 bit code
 
   mov ax, 0  ; set up segments
   mov ds, ax
   mov es, ax
   mov ss, ax     ; setup stack
   mov sp, 0x7C00 ; stack grows downwards from 0x7C00
 
   mov si, welcome
   call print_string
 
 mainloop:
   mov si, prompt
   call print_string
 
   mov di, buffer
   call get_string
 
   mov si, buffer
   cmp byte [si], 0  ; blank line?
   je mainloop       ; yes, ignore it
 
   mov si, buffer
   mov di, cmd_hi  ; "hi" command
   call strcmp
   jc .helloworld
 
   mov si, buffer
   mov di, cmd_help  ; "help" command
   call strcmp
   jc .help

   mov si, buffer
   mov di, cmd_cls
   call strcmp
   jc .cls

   mov si, buffer
   mov di, cmd_pause
   call strcmp
   jc .pause

  mov si, buffer
  mov di, cmd_reboot ; This might not work (test it first)
  call strcmp
  jc .reboot
 
   mov si,badcommand
   call print_string
   jmp mainloop 

 .reboot:
 jmp word 0xffff:0000
 cli
 hlt

 .pause:
 mov si, pause_msg
 call print_string
 mov ah, 00
 int 16h

 jmp mainloop

 
 .helloworld:
   mov si, msg_helloworld
   call print_string
 
   jmp mainloop
 
 .help:
   mov si, msg_help
   call print_string
 
   jmp mainloop

  .cls:
   mov al, 02
   mov ah, 00
   int 10h

   jmp mainloop
 
 welcome db 'Welcome to My OS!', 0x0D, 0x0A, 0
 msg_helloworld db 'Hello OSDev World!', 0x0D, 0x0A, 0
 badcommand db 'Bad command entered.', 0x0D, 0x0A, 0
 prompt db '>', 0
 cmd_hi db 'hi', 0
 cmd_help db 'help', 0
 cmd_cls db 'cls', 0
 cmd_pause db 'pause', 0x0D, 0x0A, 0
 pause_msg db 'Press any key to continue...', 0
 msg_help db 'My OS: Commands: hi, help, cls, pause, reboot', 0x0D, 0x0A, 0
 cmd_reboot db 'reboot', 0
 buffer times 64 db 0
 
 ; ================
 ; calls start here
 ; ================
 
 print_string:
   lodsb        ; grab a byte from SI
 
   or al, al  ; logical or AL by itself
   jz .done   ; if the result is zero, get out
 
   mov ah, 0x0E
   int 0x10      ; otherwise, print out the character!
 
   jmp print_string
 
 .done:
   ret
 
 get_string:
   xor cl, cl
 
 .loop:
   mov ah, 0
   int 0x16   ; wait for keypress
 
   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 and enter
 
   mov ah, 0x0E
   int 0x10      ; 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 [di], 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
 
 strcmp:
 .loop:
   mov al, [si]   ; grab a byte from SI
   mov bl, [di]   ; grab a byte from DI
   cmp al, bl     ; are they equal?
   jne .notequal  ; nope, we're done.
 
   cmp al, 0  ; are both bytes (they were equal before) null?
   je .done   ; yes, we're done.
 
   inc di     ; increment DI
   inc si     ; increment SI
   jmp .loop  ; loop!
 
 .notequal:
   clc  ; not equal, clear the carry flag
   ret
 
 .done:    
   stc  ; equal, set the carry flag
   ret
 
   times 510-($-$$) db 0
   dw 0AA55h ; some BIOSes require this signature
Post Reply