Sunteți pe pagina 1din 36

Ministerul Educaiei al Republicii Moldova

Universitatea Tehnic a Moldovei


Catedra: Automatic i Tehnologii Informaionale

RAPORT
Lucrare de laborator Nr.4
la Sisteme de operare: mecanisme interne i
principii de proiectare
Tema: Dezvoltarea nucleului i adugarea de funcionaliti

A efectuat:

st. gr.
SI-141
Ecate
rina Nemerenco
A verificat:

lect. asistent
Sergiu Ciudin

Chiinu 2016

Scopul lucrrii: Dezvoltarea nucleului de la laboratorul nr.3 i de implimentat


modificri conform condiiilor.
1. Sarcina lucrrii
Pentru laboratorul Nr.4 avem de prezentat instana de meniu a sistemului de
operare dezvoltat de noi. Aceasta reprezentare va fi efectuat n urmtoarele
moduri:
1) Textual - o forma de manipulare cu funcionalitile de sistem, la fel ca o
linie de comanda (CMD), recunoatere mesaj textual.
2) Grafic (simplu) - utiliznd KeyUP & KeyDOWN, vom selecta din meniul
nostru funcionalitatea dorit.
3) Grafic (advanced) - utilizm TAB pentru a selecta elementele din MENU i
TOATE ArrowKey (left,right,up,down) pentru a selecta funcionalitatea
implementat de voi.
Condiii:
Pentru fiecare condiie se vor respecta funcionalitile de sistem conform
baremului:
- SYSINFO (utiliznd CPUID afim informaia despre conf. hardware )
- BEEP (de generat o melodie utiliznd speaker-ul bios. play)
- DRAW (desenarea unui dreptunghi: a.dreptunghic - b.obtuzunghic c.ascuitunghic)

- CALC (suma/diferena i nmulirea/mprirea a 2 numere ntregi, modul de


apelare: calc a +; -; *; / b)
- TIME (printarea timpului de sistem comanda time)
- ABOUT (info despre sistem i autor)

Mersul lucrari:
Pentru efectuarea acestei lucrri de laborator avem nevoie s nsuim
ntreruperile BIOS i s le utilizm mpreun cu limbajul assembler pentru a putea
efectua sarcina propus.
n cadrul laboratorului am utilizat ntreruperile:
-

10h afiarea la ecran a caracterului/irului


13h ntrerupere pentru apelarea BIOS-ului
16h ntrerupere pentru apelarea lucrului cu tastatura
19h restartarea sistemului
15h ntrerupere pentru ateptare a unui anumit timp n milisecunde
Funcia org 07c00h este o directiv a limbajului assembler ce define te unde

va fi plasat codul n cadrul execuiei.


1.1.

Bootloaderul

Pentru nceput creem bootloader-ul care se nscrie pe sectorul 1 al discului i


este executat primul. Bootloader-ul acesta va ncrca deodat al 2-lea sector al
sistemului citind 2 sectoare.
1.2.

Loading

Loading-ul este pagina de ncrcare a sistemului de operare(Figura 1). Aici


are afiarea animaiei i verificarea memoriei RAM depeasc 10MB, n caz
contrar se afieaz un mesaj de eroare i se restarteaz sistemul.

Figura 1 Fereastra de ncrcare a sistemului


n fereastra de ncrcare a sistemului se observ o bar de ncrcare de
diferite culori care arat statutul sistemului de ncrcare. n timpul ncrcrii are loc
verificarea memoriei RAM, dac aceasta depete 10 MB, n caz contrar apare un
mesaj de eroare n centrul ecranului i are loc restartarea sistemului. Dup
ncrcarea sistemului de operare are loc apelarea sectorului 4 i se citesc 6 blocuri
de memorie, aceasta reprezint kernelul sistemului.
1.3.

Kernel-ul

Kernelul sistemului este plasat pe sectorul 4 al discului, aici are loc toate
activitile principale, precum deschiderea meniului(Figura 2), executarea anumitor
funcii, etc. Dup condiia noastr sistemul de operare trebuie s conin
urmtoarele funcii: System Info, Beep, Draw, Calculator, Time, About. Kernelul
este i nucleul sistemului de operare, el conine meniul, i celelalte funcii, dar i
apeluri spre poriunile de memorie care conin anumite funcii.

Figura 2 Kernel-ul
n figura dat se poate observa meniul sistemului de operare, care con ine
denumirea sistemului de operare, meniul acestuia dar i butoanele ce pot fi
accesate pentru a dirija cu sistemul de operare. Pentru navigarea n meniu se
folosesc butoanele UP i DOWN, butonul ENTER selecteaz funcia aleas, iar
butonul ESC restarteaz sistemul. Pentru utilizarea acestor funcii am folosit un
contor, i n dependen de meniul selectat se execut i se coloreaz opiunea
selectat, iar la micare prin meniu se incrimenteaz sau se decrementeaz contorul
i se mic meniul.
Primul punct din meniu reprezint System Info(Figura 3). Acest punct
afieaz la ecran informaia despre sistem, iar aceasta se face dup selectarea
punctului dat din meniu, i n caz cnd este apsat tasta Enter are loc saltul la
funcia de afiare a informaiei despre sistem.

Figura 3 System Info


n figura dat se poate observa informaia despre sistem. Pentru afi area
acestora se utilizeaz o funcie de afiare a textelor.
writeMessage macro message,x,y,color,size
mov dl,x
mov dh,y
mov ah,02h
int 10h
mov cx,size
mov al,1
mov bl,color
mov bp,offset message
mov ah,13h
int 10h
endm

Pentru afiarea modelului de procesor se utilizeaz funcia CPUID, dar n


ciuda faptului ca Emu8086 este pe 16 bii, un poate fi utilizat n cazul acesta
regitri de 32 bii, care sunt necesari pentru utilizarea func iei CPUID. Din aceast
cauz n rndul procesorului sunt afiate linii, care un reprezint nimic pentru ca
citirea procesorului un este posibil de ctre sistemul de operare. Con ine 128 MB,
numai 64 sunt diponibil pentur citire. Iar pentru afiarea volumului se uitilizeaz
funcia predefinit PRINT+NUM_UNS.

include 'emu8086.inc'
DEFINE_PRINT_NUM_UNS
mov ah, 88h
int 15h
call PRINT_NUM_UNS

; Create procedure PRINT_NUM_UNS

Al 2-lea punct din meniul principal este funcia ce emite ni te sunete(Figura


4). Pentru emiterea lor se utilizeaz instruciunea 21h.

Figura 4 Beep
n figura dat se poate observa n centrul ecranului un text ce arat c
sunetele sunt redate, iar dup ce sunt redate toate sunetele n colul dreapta jos
apare mesajul de apsare a butonului ESC pentru a reveni la meniul principal.
mov dl, 07h
mov ah, 2
int 21h

Al 3-lea punct din meniu este desenarea a 3 treiunghiuri. La alegerea acestui


meniu din cadrul meniului principal apare pe ecran un alt meniu(Figura 5) care
propune utilizatorului mai multe opiuni de alegere a desenelor.

Figura 5 Menu Draw


n figura dat se poate observa meniul care se deschide la accesarea
punctului Draw. Aici utilizatorului i se propune 3 tipuri de triunghiuri care pot fi
desenate(dreptunghic, obtuz, ascuitunghic). Utilizatorul poate alege oricare dintre
ele prin apsarea tastelor 1,2 sau 3. La selectarea unui triunghi are loc cur irea
ecranului i desenarea pixel cu pixel a triunghiului(Figura 6).

Figura 6 Rectangular Traingle drawing


n figura dat se poate observa cum a fost desenat pixel cu pixel un triunghi
dreptunghic, iar la finisarea desenrii este afiat un text ce zice c la apsarea tastei
ESC se ntoarce la meniul precedent. Desenarea pixel cu pixel are loc cu ajutorul
ntreruperii 10h- scrimbarea culori pentru un singur pixel.
mov
mov
mov
u1:
int

cx,
dx,
al,
mov
10h

100
150
11
ah, 0ch

;
;
;
;

coloana
rindul
culoare
afisam pixel

dec dx
cmp dx, 50
jae u1

Al 4-lea punct din meniul principal este accesarea Calculatorului(Figura 7).


Acest calculator trebuie s poate face adunarea, scderea, nmulirea i mpr irea a
2 numere.

Figura 7 Calculator
n figura dat este afiat aplicaia calculatorului. Ea este apelat din blocul
de memorile cu numrul 17, i este nregistrat pe 2 sectoare. Acest calculator
citete de la tastatur 2 numere cu ajutorul funciei SCAN_NUM. Aceste numere
sunt nregistrate n variabile aparte. Pentru citirea semnului se verific operatorul
primit de la tastatur, n caz c un corespunde, este afi at un mesaj de eroare i
revine la meniul pincipal. Dup primirea datelor necesare are loc verificarea
operatorului care a fost introdus i executarea instruciunilor cuvenite.
; calculate:
cmp opr, '+'
je do_plus
cmp opr, '-'
je do_minus
cmp opr, '*'
je do_mult
cmp opr, '/'
je do_div

Al 5-lea punct din meniul principal este afiarea timpului sistemului(Figura


8). Afiarea acestuia are loc prin apelarea aplicaiei nscrise n sectorul 15 al
memoriei.

Figura 8 Time
n figura dat este afiat ora sistemului, ea este citit din BIOS, i este
afiat la ecran n formatul HH:MM:SS. La accesarea orei din meniu are loc
afiarea orei pentru cteva secunde, apoi are loc ntoarcerea la meniul principal.
Ora este citit cu ajutorul instruciunii 1ah, i n regitrii ch, cl, dh sunt nscrise ora,
minute, secunde, i are loc afiarea acestora la ecran. Ora este rennoit instant
timp de cteva secunde pn la revenirea n meniul principal.
inc count
mov ah, 02h
int 1ah
mov al, ch
call deci
mov word ptr hour, ax
mov al, cl
call deci
mov word ptr minu, ax
mov al, dh
call deci
mov word ptr seco, ax

;
;
;
;

"cerem" timpul
transformind din hexa
in decimal
ore
;
; minute
;
;
; secunde
;
;

Al 6-lea punct din meniu este punctul About(Figura 9). Aici este afi at
informaia despre sistemul de operare.

Figura 9 About
n fereastra precedent se observ creatorul sistemei de operare iar mai jos
un mesaj ce indic c la apsarea tastei ESC are loc ntoarcerea n Meniu principal.
Mesajul este afiat cu ajutorul funciei de afiare a mesajelor text.

Concluzie
n urma efecturii acestei lucrri de laborator am studiat metodele de
reprezentare a ncrcrii sistemului utiliznd interfeele UI, am creat propriul
Kernel i propriul sistem de operare cu anumite funcii. Am utilizat func ii
principare ca funcia de citire a timpului din Bios, citire a memoriei RAM,
detectare a procesorului, utilizare a dispozitivelor grafice pentru a reprezenta
anumite figuri. n urma utilizrii acestora am creat cu succes un mic sistem de
operare, care are fereastr de ncrcare, anumite funci, printre care sunt nscrise pe
sectoare diferite.

#make_boot#

Anexa A
Bootloader.asm

org 07c00h
;=================kernel==================
push es
mov bx, 6000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now
mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 2
; number of sectors to read
mov ch, 0
; track number
mov cl, 2
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jmp 6000h:0000h ; jump to kernel
db 510-($-start) dup(0)
dw 0AA55h

Loading.asm
xor ax,ax
; ax=0
mov ax, 107h
int 10h
mov ch,32
; hide cursor
mov ah,1
; set cursor
int 10h
call ClrScr
jmp start
;=============Text Macro================
writeMessage macro message,x,y,color,size
pusha
mov dl,x
mov dh,y
mov ah,02h
int 10h
mov cx,size
mov al,1
mov bl,color
mov bp,offset message
mov ah,13h
int 10h
popa
endm
;===============Progress bar============
Cell:
pusha
mov ah,02h
int 10h
mov al,219
mov ah,09h
mov cx,1
int 10h
popa
ret

;==========Delay Macro==================
Sleep:
mov ah,86h
mov cx,3
int 15h
ret
;=============Clear Screen proc=========
ClrScr:
pusha
mov dx,0000h
mov ax,0200h ; seteaza cursorul
int 10h
mov bx,0000h ;culoare fundalului
mov ax,09DBh
mov cx,4000
int 10h
popa
ret
;===============Progress Bar============
start:
; 1
mov bl,0010b
mov dh,16
mov dl,25
call Cell
call Sleep
; 2
mov dh,16
mov dl,27
call Cell
;===Ram Check======
mov ah, 88h
int 15h
cmp ax,10240
jb noRam
call Sleep
; 3
mov dh,16
mov dl,29
call Cell
call Sleep
; 4
mov dh,16
mov dl,31
call Cell
call Sleep
; 5
mov dh,16
mov dl,33
call Cell
call Sleep
; 6
mov bl,1110b
mov dh,16
mov dl,35
call Cell
call Sleep
; 7
mov dh,16

mov dl,37
call Cell
call Sleep
; 8
mov dh,16
mov dl,39
call Cell
call Sleep
; 9
mov dh,16
mov dl,41
call Cell
call Sleep
; 10
mov dh,16
mov dl,43
call Cell
call Sleep
; 11
mov bl,1100b
mov dh,16
mov dl,45
call Cell
call Sleep
; 12
mov dh,16
mov dl,47
call Cell
call Sleep
; 13
mov dh,16
mov dl,49
call Cell
call Sleep
; 14
mov dh,16
mov dl,51
call Cell
call Sleep
; 15
mov bl,0100b
mov dh,16
mov dl,53
call Cell
call Sleep
;=================kernel==================
push es
mov bx, 2000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now
mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 6
; number of sectors to read
mov ch, 0
; track number
mov cl, 4
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jc noFloppy
jmp 2000h:0000 ; jump to kernel
noRam:
call ClrScr

writeMessage msg_no_ram, 30, 11, 1111b,17


mov ah,00h
int 16h
int 19h
noFloppy:
call ClrScr
pop es
writeMessage msg_no_floppy, 30, 11, 1111b,18
mov ah,00h
int 16h
;=========================DataSegement================
msg_no_ram
msg_no_floppy
contor

db
db
db

"No sufficient RAM" ;17


"No floppy on board" ;18
0

Kernel.asm
org 0000h
mov dl,10
mov pas,dl
call ClrScr
jmp Start
;=============Clear Screen proc=========
ClrScr:
pusha
mov dx,0000h
mov ax,0200h ; seteaza cursorul
int 10h
mov bx,0000h ;culoare fundalului
mov ax,09DBh
mov cx,4000
int 10h
popa
ret
;===========Message Macro===============
writeMessage macro message,x,y,color,size
mov dl,x
mov dh,y
mov ah,02h
int 10h
mov cx,size
mov al,1
mov bl,color
mov bp,offset message
mov ah,13h
int 10h
endm
;===========Wait========================
wait06:
mov ah,86h
mov cx,0x0009
int 15h
ret
;===========Beep========================
beep_sound:

mov dl, 07h


mov ah, 2
int 21h
ret
;===========Hexa transformation=========
deci:
; functia de transformare
push cx
; din hexazecimal in decimal
xor ah, ah
;
mov cl, 16
;
div cl
;
add ax, 3030h
;
pop cx
;
ret
;
;========================================================
CLEAR_SCREEN
PUSH
PUSH
PUSH
PUSH
PUSH

PROC near
AX
DS
BX
CX
DI

; procedura de curatire ecranului


;
; salvam registrele
;
;
;

MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
DEC
INT

AX,
DS,
AH,
AL,
BH,
CH,
CL,
DI,
DH,
DI,
DL,
DL
10h

40h
;
AX
;
06h
;
0
;
000_0111b ;
0
;
0
;
84h
;
[DI]
;
4Ah
;
[DI]
;
;

MOV
MOV
MOV
MOV
INT

BH,
DL,
DH,
AH,
10h

0
0
0
02

POP
POP
POP
POP
POP

DI
CX
BX
DS
AX

detectam parametrii ecranului


trecem prin fiecare linie
si reinitializam
cu culoarea indicata

; setam cursorul la virful ecranului


;
;
;
;
; restabilim registii
;
;
;
;

RET
CLEAR_SCREEN ENDP
;=========================================================
;=========================DataSegement================
UP
EQU
48h
DOWN
EQU
50h
pas
db 10

;-------Menu------

menu1
menu2
menu3

db
db
db

' ******************MENU****************** '


'*
*'
' **************************************** '

;-------Labels---label1
db
'- SYSTEM INFORMATION'
label2
db
'- BEEP'
;6
label3
db
'- DRAW'
;6
label4
db
'- CALCULATOR'
;10
label5
db
'- TIME'
;4
label6
db
'- ABOUT'
;5
label7
label8
label9
label10
label11
label12
label13

db
db
db
db
db
db
db

'Press'
'ENTER'
'ESC'
'UP/DOWN'
'to select'
'to restart'
'to move'

esc

db

'Press ESC to return' ;19

about1
about2
about3

db
db
db

'Catarina-OS'
;8
'Created by'
;10
'Ecaterina Nemerenco';19

;5
;5
;3
;7
;9
;10
;7

beep_play db

'Playing.....'

draw1
draw2
draw3
draw4

db
db
db
db

'Select triangle';15
'1 rectangular' ;13
'2 obtuse'
;8
'3 acute-angled' ;14

time_text
time_disp
count
hour
min
sec

dw
dw
db
dw
dw
dw

sysinfo1
sysinfo2
sysinfo2_1
sysinfo3
sysinfo3_1
sysinfo4

;12

'Current Time is:'


'00:00:00'
0
'00'
'00'
'00'
db
db
db
db
db
db

;18

'System info'
'System:'
'NasteaOS V1.0'
'CPU:'
'----'
'RAM:
'

;16
;8

;11
;7
;13
;4
;3
;4

key_wait:
mov ah,00h
int 16h
cmp al,27
je Start
jne key_wait
sys_info:
call CLEAR_SCREEN
;======System info=======
writeMessage sysinfo1,
35, 8,0010b,11
writeMessage sysinfo2,
30,11,1110b,7
writeMessage sysinfo2_1, 38,11,0111b,13
writeMessage sysinfo3,
30,12,1110b,4
writeMessage sysinfo3_1 38,12,0111b,4

;42

writeMessage sysinfo4,

30,13,1110b,8

include 'emu8086.inc'
DEFINE_PRINT_NUM_UNS
mov ah, 88h
int 15h
call PRINT_NUM_UNS

; Create procedure PRINT_NUM_UNS

writeMessage esc,60,24,1111b,19
;========================
jmp key_wait
beep:
call ClrScr
;======Beep =============
writeMessage beep_play, 29,10,0101b,12
call beep_sound
call beep_sound
call wait06
call beep_sound
call beep_sound
call wait06
call beep_sound
call wait06
call beep_sound
call beep_sound
call beep_sound
call beep_sound
call wait06
call beep_sound
call beep_sound
call beep_sound
call wait06
writeMessage esc,60,24,1111b,19
;========================
jmp key_wait
draw:
;=====Draw===============
Start_drawing:
call ClrScr
mov ch,32
; hide cursor
mov ah,1
; set cursor
int 10h
;=====Draw menu==========
writeMessage draw1, 30,8 ,1001b,15
writeMessage draw2, 30,10,1110b,13
writeMessage draw3, 30,11,1110b,8
writeMessage draw4, 30,12,1110b,14
writeMessage esc,
30,14,1111b,19

draw_key:
mov ah,00h
int 16h
cmp al,49
je tr_dr
cmp al,50
je tr_ob
cmp al,51

je tr_as
cmp al,27
je Start
jne draw_key
;========================
tr_dr:
; triunghi dreptunghic
call ClrScr
mov ah, 0
mov al, 13h
int 10h
mov cx, 100
; coloana
mov dx, 150
; rindul
mov al, 11
; culoare
u1: mov ah, 0ch
; afisam pixel
int 10h
dec dx
cmp dx, 50
jae u1
mov cx, 200
; coloana
mov dx, 150
; rindul
mov al, 11
; culoare
u2: mov ah, 0ch
; afisam pixel
int 10h
dec cx
cmp cx, 100
jae u2
mov cx, 200
; coloana
mov dx, 150
; rindul
mov al, 11
; culoare
u3: mov ah, 0ch
; afisam pixel
int 10h
dec
dec
cmp
jae

dx
cx
dx, 50
u3

writeMessage esc,
wait_key1:
mov ah,00h
int 16h
cmp al,27
je Stop_drawing
jne wait_key1

20,24,1111b,19

tr_ob:
; triunghi obtuz
call ClrScr
mov ah, 0
mov al, 13h
int 10h
mov cx, 150
; coloana
mov dx, 120
; rindul
mov al, 14
; culoare
u4: mov ah, 0ch
; afisam pixel
int 10h

dec
dec
dec
cmp
jae

dx
cx
cx
cx, 50
u4

mov cx, 150


; coloana
mov dx, 120
; rindul
mov al, 14
; culoare
u5: mov ah, 0ch
; afisam pixel
int 10h
dec
inc
inc
cmp
jbe

dx
cx
cx
cx, 250
u5

mov cx, 50
; coloana
mov dx, 70
; rindul
mov al, 14
; culoare
u6: mov ah, 0ch
; afisam pixel
int 10h
inc cx
cmp cx, 250
jbe u6
writeMessage esc,
20,24,1111b,19
wait_key2:
mov ah,00h
int 16h
cmp al,27
je Stop_drawing
jne wait_key2

tr_as:
; triungi ascutit
call ClrScr
mov ah, 0
mov al, 13h
int 10h
mov cx, 50
; coloana
mov dx, 150
; rindul
mov al, 13
; culoare
u7: mov ah, 0ch
; afisam pixel
int 10h
dec
inc
inc
cmp
jbe

dx
cx
cx
cx, 250
u7

mov cx, 150


; coloana
mov dx, 150
; rindul
mov al, 13
; culoare
u8: mov ah, 0ch
; afisam pixel
int 10h

dec
inc
cmp
jbe

dx
cx
cx, 250
u8

mov cx, 50
; coloana
mov dx, 150
; rindul
mov al, 13
; culoare
u9: mov ah, 0ch
; afisam pixel
int 10h
inc cx
cmp cx, 150
jbe u9
writeMessage esc,
20,24,1111b,19
wait_key3:
mov ah,00h
int 16h
cmp al,27
je Stop_drawing
jne wait_key3
Stop_drawing:
mov ah,00
mov al,03
int 10h
mov
mov
int
jmp

;
; intoarcem la text mode
;

ax, 1003h
; scoatem clipirea
bx, 0
; textului
10h
;
Start_drawing

;========================
jmp key_wait
calculator:
;call ClrScr
;=====Calculator=========
push es
mov bx, 1000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now
mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 2
; number of sectors to read
mov ch, 0
; track number
mov cl, 16
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jmp 1000h:0000h ; jump to kernel
;========================
jmp key_wait
time:
call ClrScr
;=====Time===============
push es
mov bx, 1000h
; ES:BX = 1000:000
mov es, bx
; es is 1000h now

mov bx, 0
; bx is 0 now
mov ah, 2
; load disk data into ES:BX, read sectors
mov al, 1
; number of sectors to read
mov ch, 0
; track number
mov cl, 15
; sector number (kernel is in the second sector)
mov dh, 0
; head number
mov dl, 0
; drive number
int 13h
; call BIOS
jmp 1000h:0000h ; jump to kernel
;========================
about:
call ClrScr
;=====About==============
writeMessage about1, 31,10,1010b,8
writeMessage about2, 30,12,1110b,10
writeMessage about3, 28,13,1110b,19
writeMessage esc,
60,24,1111b,19
;========================
jmp key_wait
RebotSystem:
int 19h
MoveDOWN:
cmp pas,20
je nimicDOWN
mov dl, pas
inc dl
inc dl
mov pas, dl
nimicDOWN:
jmp menu
MoveUP:
cmp pas,10
je nimicUP
mov dl, pas
dec dl
dec dl
mov pas, dl
nimicUP:
jmp menu
Enter_pressed:
cmp pas,10
je sys_info
cmp pas,12
je beep
cmp pas,14
je draw
cmp pas,16
je calculator
cmp pas,18
je time
cmp pas,20
je about
call ClrScr
jmp Start
Start:
mov ch,32

; hide cursor

mov ah,1
int 10h
call ClrScr

; set cursor

writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage
writeMessage

menu1,20,5, 1111b,42
menu2,20,6, 1111b,42
menu2,20,7,1111b,42
menu2,20,8,1111b,42
menu2,20,9,1111b,42
menu2,20,10,1111b,42
menu2,20,11,1111b,42
menu2,20,12,1111b,42
menu2,20,13,1111b,42
menu2,20,14,1111b,42
menu2,20,15,1111b,42
menu2,20,16,1111b,42
menu2,20,17,1111b,42
menu2,20,18,1111b,42
menu3,20,19,1111b,42

writeMessage label7, 0, 24,1111b,5


writeMessage label10,6, 24,1011b,7
writeMessage label13,14,24,1111b,7
writeMessage label7, 30,24,1111b,5
writeMessage label8, 36,24,1010b,5
writeMessage label11,42,24,1111b,9
writeMessage label7, 59,24,1111b,5
writeMessage label9, 65,24,1100b,3
writeMessage label12,69,24,1111b,10
menu:
cmp pas,10
je label1_t
jne label1_f
label1_t:
writeMessage label1,30,7,1100b,20
jmp next1
label1_f:
writeMessage label1,30,7,1110b,20
jmp next1
next1:
cmp pas,12
je label2_t
jne label2_f
label2_t:
writeMessage label2,30,9,1100b,6
jmp next2
label2_f:
writeMessage label2,30,9,1110b,6
jmp next2
next2:
cmp pas,14
je label3_t
jne label3_f
label3_t:
writeMessage label3,30,11,1100b,6
jmp next3
label3_f:
writeMessage label3,30,11,1110b,6
jmp next3

next3:
cmp pas,16
je label4_t
jne label4_f
label4_t:
writeMessage label4,30,13,1100b,12
jmp next4
label4_f:
writeMessage label4,30,13,1110b,12
jmp next4
next4:
cmp pas,18
je label5_t
jne label5_f
label5_t:
writeMessage label5,30,15,1100b,6
jmp next5
label5_f:
writeMessage label5,30,15,1110b,6
jmp next5
next5:
cmp pas,20
je label6_t
jne label6_f
label6_t:
writeMessage label6,30,17,1100b,7
jmp wait_for_key_press
label6_f:
writeMessage label6,30,17,1110b,7
jmp wait_for_key_press
wait_for_key_press:
mov ah,00h
int 16h
cmp ah,DOWN
je moveDOWN
cmp ah,UP
je moveUP
cmp al,27
je RebotSystem
cmp al,13
je Enter_pressed
jne wait_for_key_press

Time.asm

org 0000h
mov count,0
mov ch,32
mov ah,1
int 10h

; scotem clipirea
; textului

jmp start
hour
minu
seco
count

db
db
db
db

0, 0, ':'
0, 0, ':'
0, 0, 0
0

; ore
; minute
; secunde ceasului

start:
push
pop

cs
ds

; definim segment de date


;

mov
mov
int

ah, 00h
al, 03h
10h

; setam video mode 80x25


;
;

deseneaza_timpul:
mov ch,32
mov ah,1
int 10h

; scotem clipirea
; textului

inc count
mov ah, 02h
int 1ah
mov al, ch
call deci
mov word ptr hour, ax
mov al, cl
call deci
mov word ptr minu, ax
mov al, dh
call deci
mov word ptr seco, ax
mov
mov
mov
mov
int

ah,2
bh,0
dl,27h-4
dh,0ch
10h

lea
call

si, hour
print_string ;

;
;
;
;

"cerem" timpul
transformind din hexa
in decimal
ore
;
; minute
;
;
; secunde
;
;

; pozitionam
; la centrul
; ecranului
;
;
; afisam

call wait06
cmp count,20
je Stop
jmp deseneaza_timpul
print_string proc near
push
push

ax
si

next_char:
mov
al, [si]
cmp
al, 0
jz printed
;
inc
si
mov
ah, 0eh
int
10h
jmp
next_char
printed:

; procedura de afisarea stringului


; caracter cu caracter
;
; salvam registre in stiva
; incrementam string
; shi afisam litera curenta
; pina nu ajungem la null

pop
si
pop
ax
ret
print_string endp

; restabilim registre
;

deci:
push cx
xor ah, ah
mov cl, 16
div cl
add ax, 3030h
pop cx
ret

; functia de transformare
; din hexazecimal in decimal
;
;
;
;
;
;

wait06:
mov ah,86h
mov cx,0x0009
int 15h
ret
Stop:
push es
mov bx, 2000h
mov es, bx
mov bx, 0
mov ah, 2
mov al, 6
mov ch, 0
mov cl, 4
mov dh, 0
mov dl, 0
int 13h
jmp 2000h:0000

;
;
;
;
;
;
;
;
;
;
;

ES:BX = 1000:000
es is 1000h now
bx is 0 now
load disk data into ES:BX, read sectors
number of sectors to read
track number
sector number (kernel is in the second sector)
head number
drive number
call BIOS
jump to kernel

Calculator.asm

jmp start

;========================================================
CLEAR_SCREEN
PUSH
PUSH
PUSH
PUSH
PUSH

PROC near
AX
DS
BX
CX
DI

MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
DEC
INT

AX,
DS,
AH,
AL,
BH,
CH,
CL,
DI,
DH,
DI,
DL,
DL
10h

MOV
MOV

BH, 0
DL, 0

; procedura de curatire ecranului


;
; salvam registrele
;
;
;

40h
;
AX
;
06h
;
0
;
000_0111b ;
0
;
0
;
84h
;
[DI]
;
4Ah
;
[DI]
;
;

detectam parametrii ecranului


trecem prin fiecare linie
si reinitializam
cu culoarea indicata

; setam cursorul la virful ecranului


;

MOV
MOV
INT

DH, 0
AH, 02
10h

;
;
;

POP
POP
POP
POP
POP

DI
CX
BX
DS
AX

; restabilim registii
;
;
;
;

RET
CLEAR_SCREEN ENDP
;==============================================
writeMessage macro message,x,y,color,size
pusha
mov dl,x
mov dh,y
mov ah,02h
int 10h
mov cx,size
mov al,1
mov bl,color
mov bp,offset message
mov ah,13h
int 10h
popa
endm
;===============================================
PUTC
MACRO
char
PUSH
AX
MOV
AL, char
MOV
AH, 0Eh
INT
10h
POP
AX
ENDM
; define variables:
msg0
msg1
msg2
msg3
msg4
msg5
err1
smth

db
db
db
db
db
db
db
db

'Calculator'
'Enter 1 number: '
'Enter operator(+,-,*,/): '
'Enter 2 number: '
'Result: '
'Press any key to return...'
'Wrong operator!'
'and something...'

opr db '?'

; + - * / q

num1 dw ?
num2 dw ?
start:
call CLEAR_SCREEN
writeMessage msg0, 35, 3, 0011b,10
writeMessage msg1, 25, 5, 0111b,16
call scan_num

;10
;16
;25
;16
;8
;26
;15
;16

mov num1, cx
writeMessage msg2, 25, 6, 0111b, 25
; get operator:
mov ah, 10h
; single char input to AL.
int 16h
mov opr, al
putc al
cmp opr, 'q'
je exit

; q - exit in the middle.

cmp opr, '*'


jb wrong_opr
cmp opr, '/'
ja wrong_opr
writeMessage msg3, 25, 7, 0111b,16
call scan_num
mov num2, cx
writeMessage msg4, 25, 8, 0111b,8
; calculate:
cmp opr, '+'
je do_plus
cmp opr, '-'
je do_minus
cmp opr, '*'
je do_mult
cmp opr, '/'
je do_div
; none of the above....
wrong_opr:
writeMessage err1, 25, 10, 1100b, 15
exit:
writeMessage msg5, 25, 11, 1110b, 26
; wait for any key...
mov ah, 0
int 16h
push es
mov bx,
mov es,
mov bx,
mov ah,
mov al,
mov ch,
mov cl,
mov dh,
mov dl,
int 13h

2000h
bx
0
2
6
0
4
0
0

;
;
;
;
;
;
;
;
;
;

ES:BX = 1000:000
es is 1000h now
bx is 0 now
load disk data into ES:BX, read sectors
number of sectors to read
track number
sector number (kernel is in the second sector)
head number
drive number
call BIOS

jmp 2000h:0000

; jump to kernel

do_plus:
mov ax, num1
add ax, num2
call print_num
jmp exit
do_minus:
mov ax, num1
sub ax, num2
call print_num
jmp exit

; print ax value.

; print ax value.

do_mult:
mov ax, num1
imul num2 ; (dx ax) = ax * num2.
call print_num
; print ax value.
; dx is ignored (calc works with tiny numbers only).
jmp exit
do_div:
; dx is ignored (calc works with tiny integer numbers only).
mov dx, 0
mov ax, num1
idiv num2 ; ax = (dx ax) / num2.
cmp dx, 0
jnz approx
call print_num
; print ax value.
jmp exit
approx:
call print_num
; print ax value.
writeMessage smth, 36,8,0111b,16
jmp exit
; gets the multi-digit SIGNED number from the keyboard,
; and stores the result in CX register:
SCAN_NUM
PROC
NEAR
PUSH
DX
PUSH
AX
PUSH
SI
MOV

CX, 0

; reset flag:
MOV
CS:make_minus, 0
next_digit:
; get char from keyboard
; into AL:
MOV
AH, 00h
INT
16h
; and print it:
MOV
AH, 0Eh
INT
10h
; check for MINUS:
CMP
AL, '-'
JE
set_minus
; check for ENTER key:
CMP
AL, 0Dh ; carriage return?

JNE
JMP

not_cr
stop_input

CMP
JNE
MOV
MOV
DIV
MOV
PUTC
PUTC
JMP

AL, 8
backspace_checked
DX, 0
AX, CX
CS:ten
CX, AX
' '
8
next_digit

not_cr:
; 'BACKSPACE' pressed?
; remove last digit by
; division:
; AX = DX:AX / 10 (DX-rem).
; clear position.
; backspace again.

backspace_checked:
; allow only digits:
CMP
AL, '0'
JAE
ok_AE_0
JMP
remove_not_digit
ok_AE_0:
CMP
AL, '9'
JBE
ok_digit
remove_not_digit:
PUTC
8
; backspace.
PUTC
' '
; clear last entered not digit.
PUTC
8
; backspace again.
JMP
next_digit ; wait for next input.
ok_digit:
; multiply CX by 10 (first time the result is zero)
PUSH
AX
MOV
AX, CX
MUL
CS:ten
; DX:AX = AX*10
MOV
CX, AX
POP
AX
; check if the number is too big
; (result should be 16 bits)
CMP
DX, 0
JNE
too_big
; convert from ASCII code:
SUB
AL, 30h
; add AL to CX:
MOV
AH, 0
MOV
DX, CX
ADD
CX, AX
JC
too_big2
JMP
set_minus:
MOV
JMP
too_big2:
MOV
MOV
too_big:
MOV
DIV
MOV

; backup, in case the result will be too big.


; jump if the number is too big.

next_digit
CS:make_minus, 1
next_digit
CX, DX
DX, 0
AX, CX
CS:ten
CX, AX

; restore the backuped value before add.


; DX was zero before backup!
; reverse last DX:AX = AX*10, make AX = DX:AX / 10

PUTC
PUTC
PUTC
JMP
stop_input:
; check
CMP
JE
NEG
not_minus:
POP
POP
POP
RET
make_minus
SCAN_NUM

8
; backspace.
' '
; clear last entered digit.
8
; backspace again.
next_digit ; wait for Enter/Backspace.

flag:
CS:make_minus, 0
not_minus
CX
SI
AX
DX
DB
ENDP

; used as a flag.

; this procedure prints number in AX,


; used with PRINT_NUM_UNS to print signed numbers:
PRINT_NUM
PROC
NEAR
PUSH
DX
PUSH
AX
CMP
JNZ

AX, 0
not_zero

PUTC
JMP

'0'
printed

not_zero:
; the check SIGN of AX,
; make absolute if it's negative:
CMP
AX, 0
JNS
positive
NEG
AX
PUTC
positive:
CALL
printed:
POP
POP
RET
PRINT_NUM

'-'
PRINT_NUM_UNS
AX
DX
ENDP

; this procedure prints out an unsigned


; number in AX (not just a single digit)
; allowed values are from 0 to 65535 (FFFF)
PRINT_NUM_UNS
PROC
NEAR
PUSH
AX
PUSH
BX
PUSH
CX
PUSH
DX
; flag to prevent printing zeros before number:
MOV
CX, 1
; (result of "/ 10000" is always less or equal to 9).

MOV

BX, 10000

; 2710h - divider.

; AX is zero?
CMP
AX, 0
JZ
print_zero
begin_print:
; check divider (if zero go to end_print):
CMP
BX,0
JZ
end_print
; avoid printing zeros before number:
CMP
CX, 0
JE
calc
; if AX<BX then result of DIV will be zero:
CMP
AX, BX
JB
skip
calc:
MOV

CX, 0

; set flag.

MOV
DIV

DX, 0
BX

; AX = DX:AX / BX

; print
; AH is
ADD
PUTC

last digit
always ZERO, so it's ignored
AL, 30h
; convert to ASCII code.
AL

MOV

AX, DX

(DX=remainder).

; get remainder from last div.

skip:
; calculate BX=BX/10
PUSH
AX
MOV
DX, 0
MOV
AX, BX
DIV
CS:ten ; AX = DX:AX / 10
MOV
BX, AX
POP
AX
JMP
print_zero:
PUTC

(DX=remainder).

begin_print

'0'

end_print:
POP
POP
POP
POP
RET
PRINT_NUM_UNS

DX
CX
BX
AX
ENDP

ten
PRINT_NUM_UNS.
GET_STRING
PUSH
AX
PUSH
CX
PUSH
DI

DW
PROC

10
NEAR

; used as multiplier/divider by SCAN_NUM &

PUSH

DX

MOV

CX, 0

; char counter.

CMP
JBE

DX, 1
empty_buffer

; buffer too small?


;

DEC

DX

; reserve space for last zero.

;============================
; Eternal loop to get
; and processes key presses:
wait_for_key:
MOV
INT

AH, 0
16h

; get pressed key.

CMP
JZ

AL, 0Dh
exit_GET_STRING

CMP
JNE
JCXZ
DEC
DEC
PUTC
PUTC
PUTC
JMP

AL, 8
add_to_buffer
wait_for_key
CX
DI
8
' '
8
wait_for_key

; 'RETURN' pressed?

; 'BACKSPACE' pressed?
; nothing to remove!
; backspace.
; clear position.
; backspace again.

add_to_buffer:
CMP
JAE

CX, DX
wait_for_key

MOV
INC
INC

[DI], AL
DI
CX

; print the key:


MOV
AH, 0Eh
INT
10h
JMP
wait_for_key
;============================
exit_GET_STRING:
; terminate by null:
MOV
[DI], 0
empty_buffer:
POP
DX
POP
DI
POP
CX
POP
AX
RET
GET_STRING

ENDP

; buffer is full?
; if so wait for 'BACKSPACE' or 'RETURN'...