< -->
;scrsvr.asm
;Пример простой задачи, реализующей нитевую многозадачность в DOS
.model tiny
.code
.386
org 100h
start:
mov ax, 1600h
int 2Fh
test al, al
jz no_windows
mov ax, 1827h
mov bx, offset message_err
mov cx, message_length/2
unxor:
xor word ptr [bx], ax
inc bx
inc bx
loop unxor
mov ah, 9
mov dx, offset message_err
int 21h
jmp exit_prg
no_windows:
mov ax, 13h
int 10h
call init_threads
mov bx, 1
push bp
mov bp, sp
push 1
x_inc equ word ptr [bp-2]
push 0
y_inc equ word ptr [bp-4]
push 128-4
coords_head equ word ptr [bp-6]
push 0
coords_tail equ word ptr [bp-8]
sub sp, 64*2
mov di, sp
mov cx, 64
mov ax, 10
push ds
pop es
rep stosw
line_coords equ word ptr [bp-(64*2)-8]
push 0A000h
pop es
main_loop:
call display_line
push bx
mov ebx, 50
call z_random
mov ax, word ptr x_inc
mov bx, word ptr y_inc
test dx, dx
jz rot_right
dec dx
jnz exit_rot
neg ax
xchg ax, bx
jmp short exit_rot
rot_right:
neg bx
xchg ax, bx
exit_rot:
mov word ptr x_inc, ax
mov word ptr y_inc, bx
pop bx
mov di, word ptr coords_head
mov cx, word ptr line_coords[di]
mov dx, word ptr line_coords[di+2]
add cx, word ptr y_inc
add dx, word ptr x_inc
add di, 4
and di, 127
mov word ptr coords_head, di
mov word ptr line_coords[di], cx
mov word ptr line_coords[di+2], dx
mov di, word ptr coords_tail
add di, 4
and di, 127
mov word ptr coords_tail, di
mov cx, -1
loop $
mov cx, -1
loop $
mov cx, -1
loop $
mov ah, 1
int 16h
jz main_loop
mov ah, 0
int 16h
leave
call shutdown_threads
mov ax, 3
int 10h
exit_prg:
int 20h
putpixel proc near
push di
lea ecx, [ecx*4+ecx]
shl cx, 6
add dx, cx
mov di, dx
mov al, bl
stosb
pop di
ret
putpixel endp
display_line proc near
mov di, word ptr coords_tail
continue_line_display:
cmp di, word ptr coords_head
je line_displayed
call display_point
add di, 4
and di, 127
jmp short continue_line_display
line_displayed:
call display_point
mov di, word ptr coords_tail
push bx
mov bx, 0
call display_point
pop bx
ret
display_line endp
display_point proc near
mov cx, word ptr line_coords[di]
mov dx, word ptr line_coords[di+2]
call putpixel
ret
display_point endp
z_random:
push ebx
cmp byte ptr zr_init_flag, 0
je zr_init
mov eax, zr_prev_rand
zr_cont:
mul dword ptr rnd_number
div dword ptr rnd_number2
mov zr_prev_rand, edx
pop ebx
mov eax, edx
xor edx, edx
div ebx
ret
zr_init:
push 0040h
pop fs
mov eax, fs:[006Ch]
mov zr_prev_rand, eax
mov byte ptr zr_init_flag, 1
jmp zr_cont ; ? short ?
rnd_number dd 16807
rnd_number2 dd 2147483647
zr_init_flag db 0 ; ? поменять местами?
zr_prev_rand dd 0
; Код диспетчера
thread_struc struc
_ax dw ?
_bx dw ?
_cx dw ?
_dx dw ?
_si dw ?
_di dw ?
_bp dw ?
_sp dw ?
_ip dw ?
_flags dw ?
thread_struc ends
init_threads proc near
pushf
pusha
push es
mov ax, 3508h
int 21h
mov word ptr old_int08h, bx
mov word ptr old_int08h+2, es
mov ax, 2508h
mov dx, offset int08h_handler
int 21h
pop es
popa
popf
mov thread1._ax, ax
mov thread2._ax, ax
mov thread1._bx, bx
mov thread2._bx, bx
mov thread1._cx, cx
mov thread2._cx, cx
mov thread1._dx, dx
mov thread2._dx, dx
mov thread1._si, si
mov thread2._si, si
mov thread1._di, di
mov thread2._di, di
mov thread1._bp, bp
mov thread2._bp, bp
mov thread1._sp, offset thread1_stack+512
mov thread2._sp, offset thread2_stack+512
pop ax
mov thread1._ip, ax
mov thread2._ip, ax
pushf
pop ax
mov thread1._flags, ax
mov thread2._flags, ax
mov sp, thread1._sp
jmp word ptr thread1._ip
init_threads endp
current_thread db 1
int08h_handler proc far
pushf
db 9Ah
old_int08h dd 0
mov save_di, di
mov save_si, si
pushf
cmp byte ptr current_thread, 1
je thread1_to_thread2
mov byte ptr current_thread, 1
mov si, offset thread1
mov di, offset thread2
jmp short order_selected
thread1_to_thread2:
mov byte ptr current_thread, 2
mov si, offset thread2
mov di, offset thread1
order_selected:
mov ax, [si]._si
push save_si
pop [di]._si
mov save_si, ax
mov ax, [si]._di
push save_di
pop [di]._di
mov save_di, ax
mov [di._ax], ax
mov ax, [si._ax]
mov [di._bx], bx
mov bx, [si._bx]
mov [di._cx], cx
mov cx, [si._cx]
mov [di._dx], dx
mov dx, [si._dx]
mov [di._bp], bp
mov bp, [si._bp]
pop [di._flags]
push [si._flags]
popf
pop [di._ip]
add sp, 4
mov [di._sp], sp
mov sp, [si._sp]
push [si._ip]
mov di, save_di
mov si, save_si
retn
called_far:
popf
pop bx
pop ax
mov bp, save_di
iret
int08h_handler endp
save_di dw ?
save_si dw ?
shutdown_threads proc near
mov ax, 2508h
lds dx, dword ptr old_int08h
int 21h
ret
shutdown_threads endp
message_err db "еµПґЗµПЅ8єъЗ8И°Й»ЗёЛґЗ8ЗёЖ¶ЕёВъъЙіЛІЙ8Е8cWt8ЗЅБ°ЛЅ8"
db "µВ8Пї·ЙјOHoPyPk6$"
message_length = $ - message_err
; "Внимание! Эта программа работает только в DOS режиме! "
; "(не из под Wowwaws)." x XOR 27h 18h
thread1 thread_struc <>
thread2 thread_struc <>
thread1_stack db 512 dup (?)
thread2_stack db 512 dup (?)
end start
Назад