; ; BF interpreter for Menuet by VT ; ; Compile with FASM 1.60 or above ; use64 org 0x0 db 'MENUET64' ; Header identifier dq 0x01 ; Version dq START ; Start of code dq image_end ; Size of image dq 0x100000 ; Memory for app dq 0xffff0 ; Esp dq 0x00 ; Prm dq 0x00 ; Icon rex equ r8 rfx equ r9 ; image_end - source ; 0x10000 - app memory ; 0x20000 - display ; 0x80000 - sys. data ; 0x90000 - jump table - 8 steps - abs addresses START: call draw_window ; At first, draw the window still: mov rax , 10 ; Wait here for event int 0x60 test rax , 0x1 ; Window redraw jnz window_event test rax , 0x2 ; Keyboard press jnz key_event test rax , 0x4 ; Button press jnz button_event jmp still window_event: call draw_window jmp still key_event: mov rax , 0x2 ; Read the key and ignore int 0x60 jmp still interpreter: call load_file mov rdi , 0x10000 mov rcx , 0xe0000 mov rax , 0 cld rep stosb mov rdi , image_end dec rdi mov r15 , 0x10000 ; Pointer mov r14 , 0x20000 ; Output mov r13 , 0x00000 ; event check counter ipl0: inc r13 cmp r13 , 10000 jb noeventcheck mov r13 , 0 mov rax , 11 int 0x60 cmp rax , 0 je noevents test rax , 4 jz nobutton mov rax , 0x11 int 0x60 jmp ipl10 nobutton: test rax , 1 jz nowindow call draw_window nowindow: noevents: noeventcheck: inc rdi mov rax , [file_size] add rax , image_end cmp rdi , rax jae ipl10 mov r10b , [rdi] cmp r10b ,byte '>' jne noinc inc r15 jmp ipl0 noinc: cmp r10b ,byte '<' jne nodec dec r15 jmp ipl0 nodec: cmp r10b ,byte '+' jne noincat movzx rax , byte [r15] sub rax , rdi doinc: inc rdi cmp [rdi],byte '+' je doinc add rax , rdi dec rdi mov [r15],al jmp ipl0 noincat: cmp r10b ,byte '-' jne nodecat movzx rax , byte [r15] add rax , rdi dodec: inc rdi cmp [rdi],byte '-' je dodec sub rax , rdi dec rdi mov [r15],al jmp ipl0 nodecat: cmp r10b ,byte '.' jne noout mov al , [r15] cmp al , 10 jne nolf sub r14 , 0x20000 mov rax , r14 xor rdx , rdx add rax , 80 mov rbx , 80 div rbx mov rcx , rax imul rax , 80 mov r14 , rax add r14 , 0x20000 ; Test scroll value add rcx , 1000-29 cmp rcx , [scroll1] jb noout mov [scroll1],rcx call scroll_vertical call display_output jmp noout nolf: mov rcx , rax mov rax , r14 sub rax , 0x20000 mov rbx , 80 xor rdx , rdx div rbx cmp rdx , 79 je noout mov [r14],cl inc r14 call display_output jmp ipl0 noout: cmp r10b ,byte ',' jne noin mov rax , 10 int 0x40 mov rax , 2 int 0x40 mov al , ah mov [r15],al mov [r14],al inc r14 mov rax , 5 mov rbx , 2 int 0x60 call display_output mov rax , 5 mov rbx , 2 int 0x60 jmp ipl0 noin: cmp r10b ,byte '[' jne noloopstart cmp byte [r15],byte 0 jne loopstartfine ; In cache ? mov rbx , rdi sub rbx , image_end imul rbx , 8 add rbx , 0x90000 cmp [rbx],dword 0 je addnotfound mov rdi , [rbx] jmp foundloop addnotfound: mov rax , 1 loopsearch: inc rdi cmp [rdi],byte '[' jne nopl inc rax nopl: cmp [rdi],byte ']' jne nom dec rax cmp rax , 0 jne nom mov [rbx],rdi jmp foundloop nom: jmp loopsearch foundloop: loopstartfine: noloopstart: cmp r10b ,byte ']' jne noloopend cmp byte [r15],byte 0 je loopend ; In cache ? mov rbx , rdi sub rbx , image_end imul rbx , 8 add rbx , 0x90000 cmp [rbx],dword 0 je addnotfound2 mov rdi , [rbx] jmp loopendfine addnotfound2: mov rax , 1 loopbsearch: dec rdi cmp [rdi],byte ']' jne nom2 inc rax nom2: cmp [rdi],byte '[' jne nopl2 dec rax cmp rax , 0 jne nopl2 mov [rbx],rdi jmp loopendfine nopl2: jmp loopbsearch loopendfine: loopend: noloopend: jmp ipl0 ipl10: mov rax , 5 mov rbx , 2 int 0x60 call display_output ret button_event: mov rax , 0x11 int 0x60 ; rax = status ; rbx = button id cmp rbx , 1000 ; Vertical scroll values 1000+ jb no_vertical_scroll cmp rbx , 1999 ja no_vertical_scroll mov [scroll1], rbx call scroll_vertical call display_output jmp still no_vertical_scroll: cmp rbx , 0x10000001 jne no_application_terminate_button mov rax , 512 int 0x60 no_application_terminate_button: cmp rbx , 0x106 ; Menu jne no_application_terminate_menu mov rax , 0x200 int 0x60 no_application_terminate_menu: cmp rbx , 20 jne no_interpreter mov [scroll1],dword 1000 call scroll_vertical call interpreter jmp still no_interpreter: cmp rbx , 30 je read_file_name jmp still load_file: mov rax , 58 mov rbx , 0 mov rcx , 0 mov rdx , -1 mov r8 , image_end mov r9 , file_name int 0x60 mov [file_size],rbx ret draw_window: mov rax , 0xC ; Beginning of window draw mov rbx , 0x1 int 0x60 mov rax , 0x0 ; Draw window mov rbx , 75*0x100000000+520 ; x start & size mov rcx , 75*0x100000000+390 ; y start & size mov rdx , 0x0000000000ffffff ; type & border color mov r8 , 0x0000000000000001 ; draw flags mov r9 , window_label ; 0 or label - asciiz mov r10 , menu_struct ; 0 or pointer to menu struct int 0x60 mov rax , 8 mov rbx , 410 * 0x100000000 + 70 mov rcx , 45 * 0x100000000 + 17 mov rdx , 20 mov r8 , 0 mov r9 , button_text_run int 0x60 mov rax , 8 mov rbx , 330 * 0x100000000 + 70 mov rcx , 45 * 0x100000000 + 17 mov rdx , 21 mov r8 , 0 mov r9 , button_text_stop int 0x60 mov rax , 8 mov rbx , 22 * 0x100000000 + 225 mov rcx , 46 * 0x100000000 + 17 mov rdx , 30 mov r8 , 0 bts r8 , 63 mov r9 , 0 int 0x60 mov rax , 38 mov rbx , 5 mov rcx , 70 mov rdx , 515 mov r8 , rcx mov r9 , 0x000000 int 0x60 call print_file_name call display_output call scroll_vertical mov rax , 12 mov rbx , 2 int 0x60 ret display_output: push rdi mov rax , 26 mov rbx , 1 mov rcx , 0x80000 mov rdx , 1024 int 0x60 mov rax , [0x80000+5*8] cmp rax , [next_update] jb noupdate add rax , 1 mov [next_update],rax ; Display max 25 times a second mov rbx , [scroll1] sub rbx , 1000 imul rbx , 80 add rbx , 0x20000 mov rdx , 78 mov r10 , 30 dol0: push rax rbx rcx rdx mov rax , 13 mov rbx ,11* 0x100000000 + 6*80 mov rcx , rdx shl rcx , 32 add rcx , 10 mov rdx , 0xffffff int 0x60 pop rdx rcx rbx rax mov rax , 4 mov rcx , 11 mov rsi , 0x000000 mov r9 , 1 int 0x60 add rdx , 10 add rbx , 80 dec r10 jnz dol0 mov rax , 5 mov rbx , 20 ; int 0x60 noupdate: pop rdi ret scroll_vertical: ; Define vertical scroll mov rax , 113 mov rbx , 1 mov rcx , 1000 mov rdx , 500 mov r8 ,[scroll1] mov r9 , 250 mov r9 , 520 sub r9 , 18 mov r10 , 71 mov r11 , 390 sub r11 , 77 int 0x60 ret read_file_name: mov [posx],dword 0 mov [file_name],word '_' call print_file_name read_more_keys: mov rax , 10 int 0x60 cmp rax , 2 jne still mov rax , 2 int 0x60 cmp rbx , 10b jne no_special mov rex , 'Backspc ' cmp rcx , rex jne no_backspc cmp dword [posx],0 je read_more_keys dec dword [posx] mov rax , [posx] mov [file_name+rax],word '_' call print_file_name jmp read_more_keys no_backspc: no_special: cmp rbx , 11b jne no_enter mov rex , 'Enter ' cmp rcx , rex jne no_enter mov rax , [posx] mov [file_name+rax],byte 0 call print_file_name jmp still rootfetch: ; Fetch root jmp still no_enter: cmp rbx , 0 jne read_more_keys and cx , 0xff mov rax , [posx] mov [file_name+rax],cx inc dword [posx] mov [file_name+rax+1],word '_' call print_file_name jmp read_more_keys posx: dq 0x0 print_file_name: ; Rectangle mov rax , 38 mov rbx , 22 mov rdx , 300 sub rdx , 54 push rdx mov rcx , 46 mov r8 , 46 mov r9 , 0x202020 int 0x60 add rcx , 16 add r8 , 16 int 0x60 sub rcx , 16 mov rdx , rbx int 0x60 pop rbx mov rdx , rbx int 0x60 ; White mov rax , 13 mov rbx , 23 * 0x100000000 add rbx , 300 sub rbx , 77 mov rcx , 47 * 0x100000000 + 15 mov rdx , 0xffffff int 0x60 ; Text mov rax , 4 mov rbx , file_name mov rcx , 25 mov rdx , 51 mov rsi , 0x000000 mov r9 , 1 int 0x60 ret window_label: db 'BF -INTERPRETER',0 scroll1: dq 1000 scroll2: dq 405 file_name: db '/FD/1/MANDEL.TXT',0 file_size: dq 0x0 button_text_run: db 'RUN',0 button_text_stop: db 'STOP',0 next_update: dq 0x0 menu_struct: ; Menu Struct dq 0 ; Version dq 0x100 ; Start value of ID to return ( ID + Line ) ; Returned when menu closes and ; user made no selections. db 0,'FILE',0 ; ID = 0x100 + 1 db 1,'New',0 ; ID = 0x100 + 2 db 1,'Open..',0 ; ID = 0x100 + 3 db 1,'-',0 ; ID = 0x100 + 5 db 1,'Quit',0 ; ID = 0x100 + 6 db 255 ; End of Menu Struct image_end: