; млллллллм мллллллллм млллллллм ;оллллп пп плллммм пп олллл пллн ;олллн лпллл пплллм ллллппллм ;оллллм мллл олллм мллл олллл мллл ; плллллллпл пллллллллп плллллллп ;NASM-IDE ASM Assistant Assembler Project File [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 ;; save the stack mov [Stack_Main], sp ;; Process 1: mov sp, Stack_Area_P1+511; sp is now the P1 stack pushf ; save flags push cs ; save cs mov ax, PROCESS_1 push ax ; PROCESS_1 to stack pusha pushf push es push ds mov [Stack_P1], sp or [Processes], word 00001b; P1 is active mov ax, 0101h call PrintProcessStatus ;; Process 2: mov sp, Stack_Area_P2+511; sp is now the P2 stack pushf ; save flags push cs ; save cs mov ax, PROCESS_2 push ax ; PROCESS_2 to stack pusha pushf push es push ds mov [Stack_P2], sp or [Processes], word 00010b; P2 is active mov ax, 0102h call PrintProcessStatus ;; Process 3: mov sp, Stack_Area_P3+511; sp is now the P3 stack pushf ; save flags push cs ; save cs mov ax, PROCESS_3 push ax ; PROCESS_3 to stack pusha pushf push es push ds mov [Stack_P3], sp or [Processes], word 00100b; P3 is active mov ax, 0103h call PrintProcessStatus ;; Process 4: mov sp, Stack_Area_P4+511; sp is now the P4 stack pushf ; save flags push cs ; save cs mov ax, PROCESS_4 push ax ; PROCESS_4 to stack pusha pushf push es push ds mov [Stack_P4], sp or [Processes], word 01000b; P4 is active mov ax, 0104h call PrintProcessStatus ;; Process 5: mov sp, Stack_Area_P5+511; sp is now the P5 stack pushf ; save flags push cs ; save cs mov ax, PROCESS_5 push ax ; PROCESS_5 to stack pusha pushf push es push ds mov [Stack_P5], sp or [Processes], word 10000b; P5 is active ;;; Assign to ints call AssignIntFunction ;; starts with process 1 mov ax, [Stack_P1] mov sp, ax mov [Process], word 1; process 1 is running jmp PROCESS_1 ; go to process 1 ;;; 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 ;;; SCHEDULER: manage 4 processes runnig at the same time ; Parameters: ; - None ; Return ; - None SCHEDULER: int 60h ; call interruption ;; save values pusha pushf push es push ds SCHEDULER_SaveStack: cmp word [cs:Process], 00001b je SCHEDULER_SaveStack_P1 cmp word [cs:Process], 00010b je SCHEDULER_SaveStack_P2 cmp word [cs:Process], 00100b je SCHEDULER_SaveStack_P3 cmp word [cs:Process], 01000b je SCHEDULER_SaveStack_P4 cmp word [cs:Process], 10000b je SCHEDULER_SaveStack_P5 jmp SCHEDULER_END_SaveStack; shouln't occur, but... SCHEDULER_SaveStack_P1: mov [cs:Stack_P1], sp jmp SCHEDULER_END_SaveStack SCHEDULER_SaveStack_P2: mov [cs:Stack_P2], sp jmp SCHEDULER_END_SaveStack SCHEDULER_SaveStack_P3: mov [cs:Stack_P3], sp jmp SCHEDULER_END_SaveStack SCHEDULER_SaveStack_P4: mov [cs:Stack_P4], sp jmp SCHEDULER_END_SaveStack SCHEDULER_SaveStack_P5: mov [cs:Stack_P5], sp jmp SCHEDULER_END_SaveStack SCHEDULER_END_SaveStack: SCHEDULER_ChangeStack: cmp word [cs:Process], 10000b jge SCHEDULER_Restart mov ax, [cs:Process] shl ax,1 mov [cs:Process], ax jmp SCHEDULER_NewProcess SCHEDULER_Restart: mov word [cs:Process], 1 SCHEDULER_NewProcess: SCHEDULER_NewProcess_P1: cmp word [cs:Process], 00001b jne SCHEDULER_NewProcess_P2 mov ax, [cs:Processes] or ax, 11110b cmp ax, 11111b je SCHEDULER_ChangeStack_P1 jne SCHEDULER_ChangeStack; back and try again SCHEDULER_NewProcess_P2: cmp word [cs:Process], 00010b jne SCHEDULER_NewProcess_P3 mov ax, [cs:Processes] or ax, 11101b cmp ax, 11111b je SCHEDULER_ChangeStack_P2 jne SCHEDULER_ChangeStack; back and try again SCHEDULER_NewProcess_P3: cmp word [cs:Process], 00100b jne SCHEDULER_NewProcess_P4 mov ax, [cs:Processes] or ax, 11011b cmp ax, 11111b je SCHEDULER_ChangeStack_P3 jne SCHEDULER_ChangeStack; back and try again SCHEDULER_NewProcess_P4: cmp word [cs:Process], 01000b jne SCHEDULER_NewProcess_P5 mov ax, [cs:Processes] or ax, 10111b cmp ax, 11111b je SCHEDULER_ChangeStack_P4 jne SCHEDULER_ChangeStack; back and try again SCHEDULER_NewProcess_P5: ;; always run Process 5 jmp SCHEDULER_ChangeStack_P5 SCHEDULER_ChangeStack_P1: mov sp, [cs:Stack_P1] mov word [cs:Process], 00001b jmp SCHEDULER_END_ChangeStack SCHEDULER_ChangeStack_P2: mov sp, [cs:Stack_P2] mov word [cs:Process], 00010b jmp SCHEDULER_END_ChangeStack SCHEDULER_ChangeStack_P3: mov sp, [cs:Stack_P3] mov word [cs:Process], 00100b jmp SCHEDULER_END_ChangeStack SCHEDULER_ChangeStack_P4: mov sp, [cs:Stack_P4] mov word [cs:Process], 01000b jmp SCHEDULER_END_ChangeStack SCHEDULER_ChangeStack_P5: mov sp, [cs:Stack_P5] mov word [cs:Process], 10000b jmp SCHEDULER_END_ChangeStack SCHEDULER_END_ChangeStack: SCHEDULER_END: ;; restore values pop ds pop es popf popa iret ;;; PROCESS_1: print some text on the top of the screen 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 PROCESS_1_Loop2_NOPRINT: ;; wait some ticks 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! ;;; PROCESS_2: print some text on the center-left of the screen 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 PROCESS_2_Loop2_NOPRINT: ;; wait some ticks 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, 1 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 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! ;;; PROCESS_3: print some text on the center-left of the screen 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 dec di dec di 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 PROCESS_4: ;; Activates the PC Speaker push ax 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 pop ax cmp ax, 1026 je PROCESS_4_Sound2 PROCESS_4_Sound1: mov ax, 1026 jmp PROCESS_4_END_Sound PROCESS_4_Sound2: mov ax, 2274 PROCESS_4_END_Sound: 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, 10 jne PROCESS_4_Loop1 ;; end of wait loop ;; Closes the PC Speaker Controler push ax in al, 61h ; get data from 61h and al, 00b ; unset bits 0 and 1 out 61h, al ; send data to 61h pop ax jmp PROCESS_4 PROCESS_5: PROCESS_5_WaitKey: mov ah, 1 int 16h jz PROCESS_5_WaitKey ;; read key mov ah, 0 int 16h ;; will be used after, DO NOT CHANGE BX, CX until PROCESS_5_Toggle_* mov bx, [cs:Processes] mov cx, bx cmp al, '1' je PROCESS_5_Toggle_P1 cmp al, '2' je PROCESS_5_Toggle_P2 cmp al, '3' je PROCESS_5_Toggle_P3 cmp al, '4' je PROCESS_5_Toggle_P4 cmp al, 27 ; ESC jne PROCESS_5_NoQuit call Quit PROCESS_5_NoQuit: jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P1: or cx, 11110b cmp cx, 11111b jne PROCESS_5_Toggle_P1_On PROCESS_5_Toggle_P1_Off: mov ax, 0001h call PrintProcessStatus and bx, 11110b jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P1_On: mov ax, 0101h call PrintProcessStatus or bx, 00001b jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P2: or cx, 11101b cmp cx, 11111b jne PROCESS_5_Toggle_P2_On PROCESS_5_Toggle_P2_Off: mov ax, 0002h call PrintProcessStatus and bx, 11101b jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P2_On: mov ax, 0102h call PrintProcessStatus or bx, 00010b jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P3: or cx, 11011b cmp cx, 11111b jne PROCESS_5_Toggle_P3_On PROCESS_5_Toggle_P3_Off: mov ax, 0003h call PrintProcessStatus and bx, 11011b jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P3_On: mov ax, 0103h call PrintProcessStatus or bx, 00100b jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P4: or cx, 10111b cmp cx, 11111b jne PROCESS_5_Toggle_P4_On PROCESS_5_Toggle_P4_Off: mov ax, 0004h call PrintProcessStatus and bx, 10111b jmp PROCESS_5_END_Toggle PROCESS_5_Toggle_P4_On: mov ax, 0104h call PrintProcessStatus or bx, 01000b jmp PROCESS_5_END_Toggle PROCESS_5_END_Toggle: mov [cs:Processes], bx jmp PROCESS_5 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 ; Main loop ( while (bx < screen_size) ) Loop_FillScreen: mov [es:bx], ax add bx, 2 cmp bx, 4000 jne Loop_FillScreen ret ;;; 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 sub dl, 1 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 ; red jmp PrintProcessStatus_END_Choose PrintProcessStatus_END_Choose: mov dl, al add dl, '0' 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 [SEGMENT .data] ;Initialised data segment VideoSegment DD 0B8000000h; Video memory segment IntSegment DD 000000000h; Interrupts segment Process DW 00000; Processes DW 0000; Stack_Main DW 0; stack pointer Stack_P1 DW 0; process 1 stack pointer Stack_P2 DW 0; process 2 stack pointer Stack_P3 DW 0; process 3 stack pointer Stack_P4 DW 0; process 4 stack pointer Stack_P5 DW 0; process 5 stack pointer 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 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_P1 resb 512 Stack_Area_P2 resb 512 Stack_Area_P3 resb 512 Stack_Area_P4 resb 512 Stack_Area_P5 resb 512