Friday, April 22, 2016

Write Your Own Operating System Tutorial: Lesson 5: Let’s Make It Interactive

[This is part of a larger tutorial.
Previous lesson     Table of Contents     Next lesson]

All of this printing stuff to the screen is fun, but no operating system would be any good at all if it did not provide any interactivity. Let’s make it read input from the keyboard. Again we will be using calls to a function in BIOS to read the keyboard.

We are going to be using function 0, interrupt 0x16. This is done easily with the following two instructions.

     xor  ah, ah    ; we want function zero
     int  0x16 ; wait for a keypress

This function causes the computer to pause and does not return until a key is pressed. This can be used in a “Press any key to continue” situation, or also if you want to get input from the user. The scan code of the key pressed will be returned in register AH, and the ASCII code is returned in AL.

Your assignment for this lesson is to write a simple boot program that demonstrates a bit of interactivity. Perhaps it could print a message each time a key is pressed. Or maybe allow the user to type at the keyboard and echo each character to the screen as it is typed.

If you get stuck, below is an example of my own. But it's no fair peeking until you’ve tried by yourself!

In the next lesson we will learn how to make our operating system larger than the single sector of the Boot Record.

;----------------------------------------------------------------------
; Interactivity Example Boot Program
;
; Joel Gompert 2001
;
; Disclaimer: I am not responsible for any results of the use of the contents
;   of this file
;----------------------------------------------------------------------
   org 0x7c00 ; This is where BIOS loads the bootloader


; Execution begins here
entry:
   jmp short begin ; jump over the DOS boot record data


; ----------------------------------------------------------------------
; data portion of the "DOS BOOT RECORD"
; ----------------------------------------------------------------------
brINT13Flag     DB      90H             ; 0002h - 0EH for INT13 AH=42 READ
brOEM           DB      'MSDOS5.0'      ; 0003h - OEM name & DOS version (8 chars)
brBPS           DW      512             ; 000Bh - Bytes/sector
brSPC           DB      1               ; 000Dh - Sectors/cluster
brResCount      DW      1               ; 000Eh - Reserved (boot) sectors
brFATs          DB      2               ; 0010h - FAT copies
brRootEntries   DW      0E0H            ; 0011h - Root directory entries
brSectorCount   DW      2880            ; 0013h - Sectors in volume, < 32MB
brMedia         DB      240             ; 0015h - Media descriptor
brSPF           DW      9               ; 0016h - Sectors per FAT
brSPH           DW      18              ; 0018h - Sectors per track
brHPC           DW      2               ; 001Ah - Number of Heads
brHidden        DD      0               ; 001Ch - Hidden sectors
brSectors       DD      0               ; 0020h - Total number of sectors
                DB      0               ; 0024h - Physical drive no.
                DB      0               ; 0025h - Reserved (FAT32)
                DB      29H             ; 0026h - Extended boot record sig 
brSerialNum     DD      404418EAH       ; 0027h - Volume serial number (random)
brLabel         DB      'Joels disk '   ; 002Bh - Volume label  (11 chars)
brFSID          DB      'FAT12   '      ; 0036h - File System ID (8 chars)
;------------------------------------------------------------------------


; --------------------------------------------
;  Boot program code begins here
; --------------------------------------------
; boot code begins at 0x003E
begin:
 xor ax, ax  ; zero out ax
 mov ds, ax  ; set data segment to base of RAM
 mov si, msg  ; load address of our message
 call putstr  ; print the message

loop1:
 xor ah, ah  ; function 0
 int 0x16  ; get a key from the keyboard

 mov si, charmsg ; load address of message
 call putstr  ; print the message

 mov ah, 0x0e ; function print character
 mov bl, 0x07 ; white on black
 int 0x10

 mov si, newline ; print a newline
 call putstr

 jmp loop1  ; just loop forever.

; --------------------------------------------
; data for our program

msg db 'Press a key.'
newline db 13,10,0
charmsg db 'Character: ',0

; ---------------------------------------------
; Print a null-terminated string on the screen
; ---------------------------------------------
putstr:
 push ax
putstrl:
 lodsb   ; AL = [DS:SI]
 or al, al  ; Set zero flag if al=0
 jz putstrd  ; jump to putstrd if zero flag is set
 mov ah, 0x0e ; video function 0Eh (print char)
 mov bx, 0x0007 ; color
 int 0x10
 jmp putstrl
putstrd:
 pop ax
 retn
;---------------------------------------------

size equ $ - entry
%if size+2 > 512
  %error "code is too large for boot sector"
%endif
 times (512 - size - 2) db 0

 db 0x55, 0xAA  ;2  byte boot signature
Previous lesson     Table of Contents     Next lesson

No comments:

Post a Comment