; млллллллм мллллллллм млллллллм ;оллллп пп плллммм пп олллл пллн ;олллн лпллл пплллм ллллппллм ;оллллм мллл олллм мллл олллл мллл ; плллллллпл пллллллллп плллллллп [BITS 16] ;Set code generation to 16 bit mode [ORG 0x0100] ;Set code start address to 0100h [SEGMENT .text] ;Main code segment ;;; Reserve processes stack ;; init video mode mov ax, 0003h int 10h ;; save the stack mov [cs:Stack_Main], sp ;; init process 1 mov al, 0 mov bx, PROCESS_1 call InitProcess ;; init process 2 mov al, 1 mov bx, PROCESS_2 call InitProcess ;; init process 3 mov al, 2 mov bx, PROCESS_3 call InitProcess ;; init process 4 mov al, 3 mov bx, PROCESS_4 call InitProcess ;; init process 5 mov al, 4 mov bx, PROCESS_5 call InitProcess ;; Assign to ints call AssignIntFunction ;; start with process 1 running mov ax, [cs:Stacks] mov sp, ax mov [cs:Process], word 0 jmp PROCESS_1 ; say goodbye! let's go! ;;; SCHEDULER: (Interruption Handler) swap between active processes ; Parameters ; None ; Return ; None SCHEDULER: int 60h pusha pushf push es push ds mov bx, [cs:Process] ;; save stack: add bx, bx ; cx *= 2 mov [cs:Stacks+bx], sp ;; now, run the next process mov bx, [cs:Process] SCHEDULER_NextProcess: inc bx ; next process cmp bx, [cs:N_Processes] ; we reached the last process? jne SCHEDULER_NextProcess_Cont1 xor bx, bx ; back to the first process SCHEDULER_NextProcess_Cont1: mov cx, bx ; save bx add bx, bx ; bx *= 2 cmp [cs:Processes+bx], word 1 ; is this process active? je SCHEDULER_NextProcess_Cont ; no, back and try the next mov bx, cx ; restore bx jmp SCHEDULER_NextProcess SCHEDULER_NextProcess_Cont: mov [cs:Process], cx ; say the process that will run now mov sp, [cs:Stacks+bx] ; retore process stack pop ds pop es popf popa iret ;;; End: SCHEDULER ;;; PROCESS_1: print some text on the top of the screen ; Parameters ; None ; Return ; None PROCESS_1: mov si, STR_PROC_1 mov ax, cs mov ds, ax les di, [cs:VideoSegment] mov ah, 1Fh mov al, ' ' ;; clear the screen push bx xor bx, bx PROCESS_1_Loop1: inc bx stosw cmp bx, 12*80 ; 12 linhas de 80 colunas jne PROCESS_1_Loop1 ;; screen cleaned. ;; Enter the main loop (infinite loop) pop bx xor di, di xor cx, cx PROCESS_1_Loop_Main: PROCESS_1_Loop2: ;; load char from string and print on the screen lodsb cmp al, 0 je PROCESS_1_Loop2_NOPRINT stosw inc cx ;; Wait Loop PROCESS_1_Loop2_NOPRINT: push cx push dx xor cx, cx PROCESS_1_Loop3: inc cx xor dx, dx PROCESS_1_Loop4: inc dx cmp dx, 65535 jne PROCESS_1_Loop4 cmp cx, 100 jne PROCESS_1_Loop3 ;; end of the wait loop pop dx pop cx cmp cx, 12*80 jl PROCESS_1_Loop_Main_Cont xor di, di xor cx, cx PROCESS_1_Loop_Main_Cont: ;; we reach the end of the string? cmp al, 0 jne PROCESS_1_Loop2 ;; reset to the begining of the string, change the color mov si, STR_PROC_1 cmp ah, 1Fh je PROCESS_1_Color_2 PROCESS_1_Color_1: mov ah, 1Fh jmp PROCESS_1_Color_Cont PROCESS_1_Color_2: mov ah, 17h jmp PROCESS_1_Color_Cont PROCESS_1_Color_Cont: jmp PROCESS_1_Loop_Main; the loop that never finnishes! ;;; End: PROCESS_1 ;;; PROCESS_2: print some text on the center-left of the screen ; Parameters ; None ; Return ; None PROCESS_2: mov si, STR_PROC_2 mov ax, cs mov ds, ax les di, [cs:VideoSegment] mov di, 12*80*2 ; go to start position mov ah, 2Fh mov al, ' ' ;; clear the screen push bx push cx xor bx, bx PROCESS_2_Loop1_1: inc bx xor cx, cx PROCESS_2_Loop1_2: inc cx stosw cmp cx, 40 ; 40 columns jl PROCESS_2_Loop1_2 add di, 40*2 ; add 40 rows (2 bytes per row) cmp bx, 12 ; 12 rows jl PROCESS_2_Loop1_1 ;; screen cleaned. ;; Enter the main loop (infinite loop) pop cx pop bx les di, [cs:VideoSegment] mov di, 12*80*2 ; go to start position xor cx, cx xor bx, bx PROCESS_2_Loop_Main: PROCESS_2_Loop2: ;; load char from string and print on the screen lodsb cmp al, 0 je PROCESS_2_Loop2_NOPRINT stosw inc cx inc bx ;; Wait Loop: PROCESS_2_Loop2_NOPRINT: push cx push dx xor cx, cx PROCESS_2_Loop3: inc cx xor dx, dx PROCESS_2_Loop4: inc dx cmp dx, 65535 jne PROCESS_2_Loop4 cmp cx, 20 jne PROCESS_2_Loop3 ;; end of the wait loop pop dx pop cx cmp bx, 40 jl PROCESS_2_Loop_Main_Cont1 xor bx, bx add di, 40*2 PROCESS_2_Loop_Main_Cont1: cmp cx, 12*40 jl PROCESS_2_Loop_Main_Cont2 mov di, 12*80*2 ; go to start position xor cx, cx PROCESS_2_Loop_Main_Cont2: ;; we reach the end of the string? cmp al, 0 jne PROCESS_2_Loop2 ;; reset to the begining of the string, change the color mov si, STR_PROC_2 ;; Change colors cmp ah, 2Fh je PROCESS_2_Color_2 PROCESS_2_Color_1: mov ah, 2Fh jmp PROCESS_2_Color_Cont PROCESS_2_Color_2: mov ah, 57h jmp PROCESS_2_Color_Cont PROCESS_2_Color_Cont: jmp PROCESS_2_Loop_Main; the loop that never finnishes! ;;; End: PROCESS_2 ;;; PROCESS_3: copy the text at the center-left of the screen to the center-right ; Parameters ; None ; Return ; None PROCESS_3: lds si, [cs:VideoSegment]; read from ds:si les di, [cs:VideoSegment]; write to es:di mov si, 80*2*12 ; start reading from 12,0 mov di, 80*2*12+79*2; start writing to 12,79 (and dec) xor dx, dx PROCESS_3_Loop1: inc dx xor cx, cx PROCESS_3_Loop2: inc cx ;; read and write from video memory lodsw mov [es:di], ax sub di, 2 cmp cx, 40 jl PROCESS_3_Loop2 ;; end of column loop add si, 40*2 add di, 80*2+40*2 cmp dx, 12 jl PROCESS_3_Loop1 ;; end of line loop jmp PROCESS_3 ;;; End: PROCESS_3 ;;; PROCESS_4: Play sounds ; Parameters ; None ; Return ; None PROCESS_4: ;; Activates the PC Speaker in al, 61h ; get data from 61h or al, 11b ; set bits 0 and 1 out 61h, al ; send data to 61h ;; Activates the PC Speaker Controller mov ax, 0b6h out 43h, ax PROCESS_4_SetMusic: mov si, 0 ; our counter PROCESS_4_Play: mov ax, [cs:PROC_4_MUSIC+si] add si, 2 cmp ax, 0FFFFh je PROCESS_4_SetMusic out 42h, al ; -play the sound xchg ah, al ; - out 42h, al ; - xchg ah, al ;; wait xor cx, cx PROCESS_4_Loop1: inc cx xor dx, dx PROCESS_4_Loop2: inc dx cmp dx, 65535 jne PROCESS_4_Loop2 cmp cx, 200 jne PROCESS_4_Loop1 ;; end of wait loop jmp PROCESS_4_Play ;;; End: PROCESS_4 ;;; PROCESS_5: control other process ; Parameters ; None ; Return ; None PROCESS_5: ;; show initial processes status xor cx, cx PROCESS_5_Loop1: mov bx, cx add bx, bx ; bx *= 2 mov al, cl ; parameter to PrintProcessStatus mov dx, [cs:Processes+bx] ; get Process status mov ah, dl ; parameter to PrintProcessStatus call PrintProcessStatus inc cx cmp cx, [cs:N_Processes] jl PROCESS_5_Loop1 PROCESS_5_WaitKey: mov ah, 1 int 16h jz PROCESS_5_WaitKey ;; read key mov ah, 0 int 16h ;; check keys cmp al, 27 ; ESC jne PROCESS_5_NoQuit call Quit PROCESS_5_NoQuit: cmp al, '1' jl PROCESS_5 ; it's less than '1' cmp al, '4' jg PROCESS_5 ; it's greater than '4' sub al, '1' xor ah, ah mov bx, ax add bx, bx mov ax, [cs:Processes+bx] cmp ax, 1 je PROCESS_5_Toggle_Off PROCESS_5_Toggle_On: mov ax, 1 jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_Off: mov ax, 0 PROCESS_5_END_Toggle: mov [cs:Processes+bx], ax ; set process status jmp PROCESS_5 ;;; End: PROCESS_5 ;;; QUIT: exits the program, changing stack back to initial one and returning... ; Parameters: ; None ; Return: ; None Quit: ;; Restore ints call RestoreIntFunction mov sp, [Stack_Main] ;; clear the screen mov ah, 07h ; ah = bg | fg mov al, ' ' ; al = char ; Let es be the Video Segment les di, [cs:VideoSegment] ; video memory address: es = b800, di = 0000 xor bx, bx ;; clear the screen ; Main loop ( while (bx < screen_size) ) Loop_FillScreen: mov [es:bx], ax add bx, 2 cmp bx, 4000 jne Loop_FillScreen ;; shut down the speaker in al, 61h ; get data from 61h and al, 11111100b ; unset bits 0 and 1 out 61h, al ; send data to 61h ;; reboot! int 19h ret ;;; End: Quit ;;; PrintProcessStatus: print the process status in the last line ; Parameters: ; al: process number ; ah: process status: 1=Running, 0=Paused ; Return: ; none PrintProcessStatus: push es push ds pusha les di, [cs:VideoSegment] mov cx, cs mov ds, cx ; read from cs:si push ax ;; set position in screen mov di, 80*2*24 mov dl, al mov al, 20*2 mul dl xor ah, ah add di, ax pop ax cmp ah, 1 je PrintProcessStatus_Choose_Running PrintProcessStatus_Choose_Paused: mov si, STR_PROC_5_PAU mov dh, 04h ; red jmp PrintProcessStatus_END_Choose PrintProcessStatus_Choose_Running: mov si, STR_PROC_5_RUN mov dh, 02h ; green jmp PrintProcessStatus_END_Choose PrintProcessStatus_END_Choose: mov dl, al add dl, '0' inc dl mov ax, dx mov ah, 0Fh stosw mov al, ':' stosw mov ah, dh PrintProcessStatus_Loop1: lodsb cmp al, 0 je PrintProcessStatus_END_Loop1 stosw jmp PrintProcessStatus_Loop1 PrintProcessStatus_END_Loop1: popa pop ds pop es ret ;;; End: PrintProcessStatus ;;; InitProcess: ; Parameters: ; al: process number ; bx: process label ; Return: ; None InitProcess: pusha xor ah, ah mov si, sp ; save sp, we need to restore it later mov dx, ax ; save ax mov sp, Stack_Area+127; sp will be the process sp now xchg al, cl ; - mov al, 128 ; - mul cl ; ax = * 512 add sp, ax ; go to the position reserved to process mov ax, dx ; restore original ax ;; make the stack pushf ; save flags push cs ; save cs push bx ; PROCESS to stack pusha pushf push es push ds ;; save the stack add ax, ax ; ax *= 2 xchg ax, bx mov [cs:Stacks+bx], sp mov [cs:Processes+bx], word 1; Process is active ;; return to the old stack mov sp, si popa ret ;;; End: InitProcess ;;; AssignIntFunction: Assigns SCHEDULER as Clock int ; Parameters: ; - None ; Return ; - None AssignIntFunction: ; save parameters we will use pusha cli ; no interrupts by now les di, [IntSegment] ; es = interruption segment ;; Clock ;; Save actual interruption value mov dx, [es:8h*4] mov cx, [es:8h*4+2] mov [es:60h*4], dx mov [es:60h*4+2], cx ;; Assign new values mov ax, cs mov bx, SCHEDULER mov [es:8h*4], bx mov [es:8h*4+2], ax sti ; now interrupts are available again ; restore parameters we will use popa ret ;;; RestoreIntFunction: restore the previous assigned interruption ; Parameters: ; - None ; Return ; - None RestoreIntFunction: ;; save values pusha cli ; no ints les di, [IntSegment] ; es = interruption segment ;; Clock ;; retore interrupt xor ax, ax mov es, ax mov dx, [es:60h*4] mov cx, [es:60h*4+2] mov [es:8h*4], dx mov [es:8h*4+2], cx sti ; ints agains ;; restore values popa ret [SEGMENT .data] ;Initialised data segment VideoSegment DD 0B8000000h; Video memory segment IntSegment DD 000000000h; Interrupts segment Process DW 0; which process is active Processes DW 0,0,0,0,0; processes state Stack_Main DW 0; stack pointer Stacks DW 0,0,0,0,0 ; processes stack N_Processes DW 5 ; number of process we can held STR_PROC_1 DB "Why are you using this Microsoft shit?! Huh? BE FREE USE GNU/LINUX (or at least BSD)!!! -- Gustavo Sverzut Barbieri & Ivens Prates Telles Alves ",0 STR_PROC_2 DB "......................................... LINUX .-'`-. .. RULEZ ( O__O ) /\ .. ) \/ ( / | .. Say Hello to Tux/ \_/ / .. / |.-.-. / .. / \ ^ ) / .. ASCII ART by | \ + \ \ .. GSB .-.-.-./ ) \ .-._ .. \ ^ ^ /'-._.-' / '_\ ..oOo.oOo.oOo.o\___/._________.-|_____)o.................................................................................. LINUX .-'`-. .. RULEZ!!! ( o__o ) .. ) \/ ( _.- .. You: Hello Tux! / \_.-' / .. / |.-.-. / .. / \ ^ ) .-' .. ASCII ART by | \ + \ \ .. GSB .-.-.-./ ) .-.-.-. .. \ ^ ^ /'-._.-' \ ^ ^ / ..oOo.oOo.oOo.o\___/._________.\___/.oOo.................................................................................. LINUX .-'`-. .. RULEZ ( O__O ) .. ) \/ ( .. Tux: Hello! / \___.---. .. / |.-.-. _/ .. / \ ^ ) .--' .. ASCII ART by | \ + \ \ .. GSB .-.-.-./ ) \ .-._ .. \ ^ ^ /'-._.-' / '_\ ..oOo.oOo.oOo.o\___/._________.-|_____)o.................................................................................. LINUX .-'`-. .. RULEZ!!! ( o__o ) .. ) \/ ( _.- .. BOTH: NO PATENTS/ \_.-' / .. / |.-.-. / .. / \ ^ ) .-' .. ASCII ART by | \ + \ \ .. GSB .-.-.-./ ) \ .-._ .. \ ^ ^ /'-._.-' / '_\ ..oOo.oOo.oOo.o\___/._________.-|_____)o.........................................",0 PROC_4_MUSIC DW 1075,0,1075,0,1075,0,1075,1354,1808,1075,1354,1808,1075,1354,1808,1075,1354,1808,1139,1139,1354,1354,1808,1139,1354,1808,1139,1354,1808,1139,1354,1808,1075,1075,1354,1808,1075,1354,1808,1075,1075,1075,1075,1139,1206,1354,1354,1354,0FFFFh ; music to play STR_PROC_5_RUN DB "RUNNING",0 STR_PROC_5_PAU DB "PAUSED ",0 Author1 DB "Gustavo Sverzut Barbieri ",0 Author2 DB "Ivens Prates Telles Alves ",0 [SEGMENT .bss] ;Uninitialised data segment Stack_Area resw 128*5 ; StackSize * N_Processes