578 lines
12 KiB
Plaintext
578 lines
12 KiB
Plaintext
BITS 16
|
|
org 0x7C00
|
|
cli
|
|
xor ax, ax
|
|
mov ds, ax
|
|
mov es, ax
|
|
mov ss, ax
|
|
mov sp, 0x8000
|
|
sti
|
|
mov ax, 3
|
|
int 0x10
|
|
mov bp, loading
|
|
mov ax, 0x1301
|
|
mov bx, 7
|
|
mov cx, 12
|
|
mov dx, 0x0102
|
|
int 0x10
|
|
mov bl, 2
|
|
mov ah, 2
|
|
mov dx, 0x0201
|
|
int 0x10
|
|
mov ah, 9
|
|
mov al, '.'
|
|
mov cx, 14
|
|
int 0x10
|
|
mov di, 0x0050
|
|
mov ax, 19
|
|
mov cx, 14
|
|
call read
|
|
mov di, 0x0210
|
|
mov ax, 1
|
|
mov cx, 9
|
|
call read
|
|
mov dx, 224
|
|
mov bx, 0x0500
|
|
search:
|
|
cld
|
|
mov si, filename
|
|
mov cx, 11
|
|
mov di, bx
|
|
repe cmpsb
|
|
je found
|
|
add bx, 32
|
|
dec dx
|
|
jz error
|
|
jmp search
|
|
read:
|
|
pusha
|
|
mov bl, 18
|
|
div bl
|
|
mov cl, ah
|
|
inc cl
|
|
xor ah, ah
|
|
mov bl, 2
|
|
div bl
|
|
mov ch, al
|
|
mov dh, ah
|
|
mov ax, cx
|
|
mov cx, 10
|
|
.retry:
|
|
push es
|
|
push cx
|
|
mov cx, ax
|
|
push cx
|
|
xor ax, ax
|
|
push dx
|
|
int 0x13
|
|
jc .failed
|
|
pop dx
|
|
pop cx
|
|
xor bx, bx
|
|
mov es, di
|
|
mov ax, 0x0201
|
|
int 0x13
|
|
jnc .success
|
|
.failed:
|
|
pop dx
|
|
pop ax
|
|
pop cx
|
|
pop es
|
|
loop .retry
|
|
mov bp, failure
|
|
mov ax, 0x1301
|
|
mov bx, 4
|
|
mov cx, 11
|
|
mov dx, 0x0401
|
|
int 0x10
|
|
mov ah, 0
|
|
int 0x16
|
|
int 0x19
|
|
.success:
|
|
pop cx
|
|
pop es
|
|
popa
|
|
add di, 32
|
|
inc ax
|
|
loop read
|
|
ret
|
|
found:
|
|
mov bp, [bx+26]
|
|
mov di, 0x0800
|
|
.block:
|
|
xor cx, cx
|
|
mov cl, 1
|
|
mov si, bp
|
|
.contig:
|
|
mov ax, 3
|
|
mul si
|
|
shr ax, 1
|
|
mov bx, ax
|
|
mov ax, word [(0x2100+bx)]
|
|
jc .odd
|
|
and ax, 0x0FFF
|
|
jmp .next
|
|
.odd:
|
|
shr ax, 4
|
|
.next:
|
|
inc si
|
|
cmp ax, si
|
|
jne .pass
|
|
inc cl
|
|
adc ch, 0
|
|
jmp .contig
|
|
.pass:
|
|
xchg bp, ax
|
|
dec ax
|
|
dec ax
|
|
mov dx, 1
|
|
mul dx
|
|
add ax, 33
|
|
call read
|
|
cmp bp, 0x0FF8
|
|
jb .block
|
|
.386
|
|
model flat
|
|
extrn strlen:proc
|
|
extrn isalnum:proc
|
|
extrn isxdigit:proc
|
|
.code
|
|
node.left equ 0
|
|
node.right equ 4
|
|
node.type equ 8
|
|
TYPE_S equ 0
|
|
TYPE_K equ 1
|
|
TYPE_I equ 2
|
|
TYPE_BI equ 3
|
|
section '.text' code readable executable writeable
|
|
proc _start
|
|
invoke HeapCreate, 0, 0, 0
|
|
mov DWORD [asmh], eax
|
|
invoke GetModuleHandleA, 0
|
|
invoke CreateDialogParamA, eax, 1, 0, DialogProc, 0
|
|
mov DWORD [hDlg], eax
|
|
invoke ShowWindow, eax, SW_SHOW
|
|
.message_loop:
|
|
invoke GetMessage, msg, 0, 0, 0
|
|
test eax, eax
|
|
je .quit
|
|
inc eax
|
|
jne .isdlg
|
|
push 1
|
|
jmp .die
|
|
.isdlg:
|
|
invoke IsDialogMessageA, hDlg, msg
|
|
test eax, eax
|
|
jne .message_loop
|
|
invoke TranslateMessage, msg
|
|
invoke DispatchMessage, msg
|
|
jmp .message_loop
|
|
.quit:
|
|
push 0
|
|
.die:
|
|
call [ExitProcess]
|
|
endp
|
|
proc DialogProc
|
|
push ebp
|
|
mov ebp, esp
|
|
sub esp, 16
|
|
mov edx, DWORD [ebp+12]
|
|
mov eax, DWORD [ebp+8]
|
|
mov ecx, DWORD [ebp+16]
|
|
cmp edx, WM_CLOSE
|
|
je .close_handler
|
|
cmp edx, WM_COMMAND
|
|
je .command_handler
|
|
cmp edx, WM_DESTROY
|
|
jne .no_op
|
|
invoke PostQuitMessage, 0
|
|
jmp .c_exit
|
|
.close_handler:
|
|
invoke DestroyWindow, eax
|
|
.c_exit:
|
|
xor ebx, ebx
|
|
inc ebx
|
|
jmp .die
|
|
.command_handler:
|
|
cmp cx, 2
|
|
jne .not_quit
|
|
invoke DestroyWindow, eax
|
|
.no_op:
|
|
xor ebx, ebx
|
|
jmp .die
|
|
.not_quit:
|
|
xor ebx, ebx
|
|
dec cx
|
|
jne .die
|
|
invoke GetDlgItem, eax, 3
|
|
mov DWORD [wnd], eax
|
|
invoke GetWindowTextLengthA, eax
|
|
mov ecx, esp
|
|
lea edx, [eax+1]
|
|
add eax, 17
|
|
and eax, 0xFFFFFFF0
|
|
sub ecx, eax
|
|
mov esp, ecx
|
|
mov BYTE [esp], 0
|
|
mov DWORD [ebp-12], ecx
|
|
invoke GetWindowTextA, DWORD [wnd], ecx, edx
|
|
mov ecx, DWORD [ebp-12]
|
|
call eval
|
|
invoke SetWindowText, DWORD [wnd], eax
|
|
.die:
|
|
lea esp, [ebp-8]
|
|
mov eax, ebx
|
|
pop ebx
|
|
pop esi
|
|
pop ebp
|
|
ret 16
|
|
endp
|
|
proc str_size
|
|
push esi ebx
|
|
xor esi, esi
|
|
mov ebx, eax
|
|
.loop:
|
|
cmp DWORD [ebx+node.type], TYPE_BI
|
|
jne .quit
|
|
mov eax, DWORD [ebx+node.left]
|
|
call str_size
|
|
mov ebx, DWORD [ebx+node.right]
|
|
lea esi, [esi+eax+2]
|
|
jmp .loop
|
|
.quit:
|
|
lea eax, [esi+1]
|
|
pop ebx esi
|
|
ret
|
|
endp
|
|
proc stringify
|
|
push ebx
|
|
mov ebx, eax
|
|
mov edx, DWORD [eax+node.type]
|
|
mov eax, DWORD [buf]
|
|
inc eax
|
|
mov DWORD [buf], eax
|
|
dec eax
|
|
cmp edx, TYPE_BI
|
|
jne .combinator
|
|
mov BYTE [eax], '('
|
|
mov eax, DWORD [ebx+node.left]
|
|
call stringify
|
|
mov eax, DWORD [ebx+node.right]
|
|
call stringify
|
|
mov eax, DWORD [buf]
|
|
mov BYTE [eax], ')'
|
|
inc eax
|
|
mov DWORD [buf], eax
|
|
dec eax
|
|
jmp .stop
|
|
.combinator:
|
|
mov dl, BYTE [ski+edx]
|
|
mov BYTE [eax], dl
|
|
.stop:
|
|
pop ebx
|
|
ret
|
|
endp
|
|
proc free
|
|
invoke HeapFree, DWORD [asmh], 0, eax
|
|
ret
|
|
endp
|
|
proc free_tree
|
|
push ebx
|
|
mov ebx, eax
|
|
cmp DWORD [eax+node.type], TYPE_BI
|
|
jne .no_children
|
|
mov eax, DWORD [eax+node.left]
|
|
call free_tree
|
|
mov eax, DWORD [ebx+node.right]
|
|
call free_tree
|
|
.no_children:
|
|
mov eax, ebx
|
|
pop ebx
|
|
jmp free
|
|
endp
|
|
proc alloc_node
|
|
push ebx
|
|
mov ebx, eax
|
|
invoke HeapAlloc, DWORD [asmh], HEAP_ZERO_MEMORY, 4 + 4 + 4
|
|
mov DWORD [eax+node.type], ebx
|
|
pop ebx
|
|
ret
|
|
endp
|
|
proc read_node
|
|
push ebx
|
|
mov eax, DWORD [code]
|
|
inc eax
|
|
mov DWORD [code], eax
|
|
dec eax
|
|
mov al, BYTE [eax]
|
|
cmp al, 'K'
|
|
je .read_k
|
|
jg .maybe_s
|
|
cmp al, '('
|
|
je .read_bitree
|
|
cmp al, 'I'
|
|
jne .parse_error
|
|
push TYPE_I
|
|
pop eax
|
|
jmp .build_node
|
|
.maybe_s:
|
|
cmp al, 'S'
|
|
jne .parse_error
|
|
xor eax, eax
|
|
jmp .build_node
|
|
.read_bitree:
|
|
push TYPE_BI
|
|
pop eax
|
|
call alloc_node
|
|
mov ebx, eax
|
|
call read_node
|
|
mov DWORD [ebx+node.left], eax
|
|
test eax, eax
|
|
je .nullify
|
|
call read_node
|
|
mov DWORD [ebx+node.right], eax
|
|
test eax, eax
|
|
je .nullify
|
|
inc DWORD [code]
|
|
jmp .die
|
|
.read_k:
|
|
xor eax, eax
|
|
inc eax
|
|
.build_node:
|
|
pop ebx
|
|
jmp alloc_node
|
|
.parse_error:
|
|
invoke MessageBoxA, 0, msge, 0, MB_OK
|
|
.nullify:
|
|
xor ebx, ebx
|
|
.die:
|
|
mov eax, ebx
|
|
pop ebx
|
|
ret
|
|
endp
|
|
proc dup_tree
|
|
push esi ebx
|
|
mov ebx, eax
|
|
mov eax, DWORD [eax+node.type]
|
|
call alloc_node
|
|
cmp DWORD [ebx+node.type], TYPE_BI
|
|
jne .shallow
|
|
mov esi, eax
|
|
mov eax, DWORD [ebx+node.left]
|
|
call dup_tree
|
|
mov DWORD [esi+node.left], eax
|
|
mov eax, DWORD [ebx+node.right]
|
|
call dup_tree
|
|
mov DWORD [esi+node.right], eax
|
|
mov eax, esi
|
|
.shallow:
|
|
pop ebx esi
|
|
ret
|
|
endp
|
|
proc eval_step
|
|
push edi esi ebx
|
|
mov ebx, eax
|
|
mov eax, DWORD [eax+node.left]
|
|
test eax, eax
|
|
je .no_left
|
|
cmp DWORD [eax+node.type], TYPE_I
|
|
jne .not_inode
|
|
mov esi, DWORD [ebx+node.right]
|
|
jmp .clean
|
|
.not_inode:
|
|
mov edx, DWORD [eax+node.left]
|
|
test edx, edx
|
|
je .no_left
|
|
cmp DWORD [edx+node.type], TYPE_K
|
|
jne .not_knode
|
|
mov esi, DWORD [eax+node.right]
|
|
mov eax, DWORD [ebx+node.right]
|
|
call free_tree
|
|
mov eax, DWORD [ebx+node.left]
|
|
mov eax, DWORD [eax+node.left]
|
|
.clean:
|
|
call free_tree
|
|
mov eax, ebx
|
|
call free
|
|
.yield_saved:
|
|
mov ebx, esi
|
|
jmp .done
|
|
cmp DWORD [ebx+node.type], TYPE_BI
|
|
jne .done
|
|
call eval_step
|
|
mov DWORD [ebx+node.left], eax
|
|
mov eax, DWORD [ebx+node.right]
|
|
call eval_step
|
|
mov DWORD [ebx+node.right], eax
|
|
.done:
|
|
mov eax, ebx
|
|
pop ebx esi edi
|
|
ret
|
|
endp
|
|
eval:
|
|
push esi ebx
|
|
mov ebx, ecx
|
|
mov DWORD [code], ecx
|
|
call read_node
|
|
test eax, eax
|
|
je .read_fail
|
|
call eval_step
|
|
mov esi, eax
|
|
call str_size
|
|
inc eax
|
|
invoke HeapAlloc, DWORD [asmh], 0, eax
|
|
mov DWORD [buf], eax
|
|
mov ebx, eax
|
|
mov eax, esi
|
|
call stringify
|
|
mov eax, DWORD [buf]
|
|
mov BYTE [eax], 0
|
|
mov eax, esi
|
|
call free_tree
|
|
.read_fail:
|
|
mov eax, ebx
|
|
pop ebx esi
|
|
ret
|
|
wnd: dd 0
|
|
msg MSG
|
|
hDlg: dd 0
|
|
asmh: dd 0
|
|
buf: dd 0
|
|
code: dd 0
|
|
ski: db 'SKI', 0
|
|
msge: db '?', 0
|
|
section '.rsrc' resource data readable
|
|
directory RT_DIALOG, dialogs
|
|
resource dialogs, 1, LANG_ENGLISH+SUBLANG_DEFAULT, demo
|
|
dialog demo,'SKI calculus',70,70,330,20,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME
|
|
dialogitem 'STATIC', '&Code: ', 4, 4, 5, 21, 9, WS_VISIBLE+WS_CHILD+WS_GROUP
|
|
dialogitem 'BUTTON', '&Quit', 2, 269, 4, 50, 11, BS_PUSHBUTTON+WS_CHILD+WS_VISIBLE+WS_GROUP
|
|
dialogitem 'BUTTON', '&Evaluate', 1, 218, 4, 50, 11, BS_DEFPUSHBUTTON+WS_CHILD+WS_VISIBLE+WS_GROUP
|
|
dialogitem 'EDIT', '', 3, 28, 3, 187, 14, ES_LEFT+WS_CHILD+WS_VISIBLE+WS_BORDER+WS_GROUP+ES_AUTOHSCROLL
|
|
enddialog
|
|
section '.idata' import data readable writable
|
|
library kernel32, 'KERNEL32.DLL', \
|
|
user32, 'USER32.DLL'
|
|
include 'api\kernel32.inc'
|
|
include 'api\user32.inc'
|
|
jae out_of_memory
|
|
push eax esi
|
|
clc
|
|
call near dword [esp+8]
|
|
pop ebx eax
|
|
dec eax
|
|
jz data_defined
|
|
mov esi,ebx
|
|
jmp duplicate_single_data_value
|
|
duplicate_zero_times:
|
|
cmp byte [esi],91h
|
|
jne skip_single_data_value
|
|
inc esi
|
|
skip_data_value:
|
|
call skip_symbol
|
|
jc invalid_argument
|
|
cmp byte [esi],92h
|
|
jne skip_data_value
|
|
inc esi
|
|
jmp data_defined
|
|
cmp al,'('
|
|
jne invalid_operand
|
|
mov al,[value_type]
|
|
push eax
|
|
cmp byte [esi],'.'
|
|
je invalid_value
|
|
call get_dword_value
|
|
call mark_relocation
|
|
stos dword [edi]
|
|
pop eax
|
|
mov [value_type],al
|
|
pop eax
|
|
call mark_relocation
|
|
stos word [edi]
|
|
ret
|
|
data_qwords:
|
|
call define_data
|
|
jc instruction_assembled
|
|
lods byte [esi]
|
|
cmp al,'('
|
|
je get_qword
|
|
cmp al,'?'
|
|
jne invalid_argument
|
|
mov ecx,1000
|
|
mul ecx
|
|
mov ebx,eax
|
|
mov eax,dword [buffer+4]
|
|
div ecx
|
|
OR AL,AL
|
|
JZ CURRISROOT
|
|
JMP SHORT SETDIRLP
|
|
CURRISROOT:
|
|
MOV WORD PTR [THISDPB+2],DS
|
|
PUSH CS
|
|
POP DS
|
|
ASSUME DS:DG
|
|
MOV WORD PTR [THISDPB],BX
|
|
MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 23H
|
|
INT 21H
|
|
MOV WORD PTR [CONTCH],BX
|
|
MOV WORD PTR [CONTCH+2],ES
|
|
MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 23H
|
|
MOV DX,OFFSET DG:INT_23
|
|
INT 21H
|
|
MOV AX,(GET_INTERRUPT_VECTOR SHL 8) OR 24H
|
|
INT 21H
|
|
MOV WORD PTR [HARDCH],BX
|
|
MOV WORD PTR [HARDCH+2],ES
|
|
MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 24H
|
|
MOV DX,OFFSET DG:INT_24
|
|
INT 21H
|
|
PUSH CS
|
|
POP ES
|
|
MOV DX,OFFSET DG:ROOTSTR
|
|
MOV AH,CHDIR
|
|
INT 21H
|
|
MOV DX,OFFSET DG:BADCD
|
|
JC CERROR2J
|
|
MOV DX,OFFSET DG:FAT
|
|
MOV AH,SET_DMA
|
|
INT 21H
|
|
MOV DX,OFFSET DG:VOLID
|
|
MOV AH,DIR_SEARCH_FIRST
|
|
INT 21H
|
|
CMP AL,-1
|
|
JZ NOTVOLID
|
|
CALL PRINTID
|
|
NOTVOLID:
|
|
LDS BX,[THISDPB]
|
|
ASSUME DS:NOTHING
|
|
MOV AX,[BX.dpb_sector_size]
|
|
MOV [SSIZE],AX
|
|
MOV AL,[BX.dpb_cluster_mask]
|
|
INC AL
|
|
MOV [CSIZE],AL
|
|
MOV AX,[BX.dpb_max_cluster]
|
|
MOV [MCLUS],AX
|
|
DEC AX
|
|
MOV [DSIZE],AX
|
|
MOV AL,[BX.dpb_FAT_size]
|
|
XOR AH,AH
|
|
MOV CX,AX
|
|
MUL [SSIZE]
|
|
ADD [FATMAP],AX
|
|
MOV AX,[FATMAP]
|
|
ADD AX,[MCLUS]
|
|
ADD AX,2
|
|
MOV [SECBUF],AX
|
|
ADD AX,[SSIZE]
|
|
ADD AX,20
|
|
MOV [STACKLIM],AX
|
|
MOV DI,CX
|
|
MOV CL,[BX.dpb_FAT_count]
|
|
MOV DX,[BX.dpb_first_FAT]
|
|
PUSH CS
|
|
POP DS
|
|
ASSUME DS:DG
|
|
MOV BX,OFFSET DG:FAT
|
|
MOV AL,[ALLDRV]
|
|
DEC AL
|
|
MOV AH,'1' |