Joined: Mon Mar 27, 2006 6:33 am Posts: 707
|
Думаю сделать какое то описание этого процесса  Код на ForthEC для Колибри \ Allocate 28 bytes for the msg struct (actually 4+28) variable rng 19 rng ! variable rngh 1 rngh ! variable video-buffer video-buffer 4 + video-buffer ! 65000 allot variable screen screen 4 + screen ! 256000 allot variable msg 28 allot variable bih 36 allot variable palette here ( palette 4 + palette ! ) 1030 allot palette ! variable done variable last-time
: redraw notouch call init call main ret redraw: call draw_window wait_event: mov eax, 11 int 40h dec eax jz redraw dec eax jz key dec eax jz close ret close: ; button pressed; we have only one button, close mov eax, -1 int 40h key: ; key pressed, read it and ignore mov eax, 2 int 40h ret jmp wait_event touch ;
: draw_window notouch draw_window: mov eax, 12 mov ebx, 1 int 40h ; start redraw xor eax, eax mov ebx, 50*65536 + 330 ; 360 mov ecx, 150*65536 + 228 ; 228
mov edx, 33FFFFFFh mov edi, offset string ;title int 40h ; define&draw window
; mov eax, 4 ; mov ebx, 60*65536 + 10 ; mov ecx, 80000000h ; mov edx, offset string ; int 40h ; draw string
; mov ebx, 50000h ; mov eax,dword ptr [var_0000000] ; mov ecx,dword ptr [eax]
; mov eax, 47 ; mov edx, 20*65536 + 10 ; mov esi, 0h ; color ; int 40h ; draw number
mov eax,dword ptr [var_0000002] mov ebx, dword ptr [eax] ; mov edx, 2*65536 + 25 ; 150 x,y ; mov ecx, 320*65536 + 228 ; 50 size mov edx, 0*65536 + 0 ; 150 x,y mov ecx, 320*65536 + 200 ; 50 size
mov esi, 8 mov eax,dword ptr [var_0000006] mov edi,dword ptr [eax] mov ebp,0 mov eax,65 int 40h
mov eax, 12 mov ebx, 2 int 40h ; end redraw ret touch ;
\ Random number generator (borrowed from Paul Dixon) : random ( -- n ) rngh rng notouch pop esi pop edi mov edx,[edi] shr edx,1 mov eax,[esi] mov ecx,eax rcr ecx,1 rcl edx,1 mov [edi],edx shl eax,12 xor ecx,eax mov eax,ecx shr eax,20 xor ecx,eax mov [esi],ecx and ecx,191 mov eax,ecx touch a@ ;
\ This draws the actual fire : flames 12160 video-buffer @ + 12798 video-buffer @ + 160 0 do over over 82 0 do dup dup dup dup c@ swap 2 + c@ + swap 4 + c@ + swap 644 + c@ + 2 >> dup 0 <> if 1- then dup 8 << or dup 3 pick w! 2 pick 320 + w! swap 640 + swap 640 + loop over 640 - random 10 + swap c! drop drop swap 2 + swap 2 + loop drop drop ;
: setup-palette palette @ 1024 -1 fill palette @ 33 1 do i 3 << 1- \ pal c over 0 swap ! over 2 + over swap c! over 128 + 0 swap c! over 129 + over swap c! over 256 + c! 4 + loop drop ;
: draw-fire flames
;
: win-main \ { hInst -- } 320 done ! \ Keep looping until the window is closed begin draw-fire done @ dup 1- done ! 0= until ; : main notouch main: touch setup-palette \ Allocate room for a 320x200 bitmap, plus a little more
video-buffer 4 + video-buffer ! video-buffer @ 64000 0 fill notouch main1: touch win-main \ 19 rng ! notouch call redraw jmp main1 touch ; Полученный листинг MASM ; Generated by ForthEC
.686p .mmx .model flat,stdcall option casemap:none
include ani.inc
;##############################################################################
pushdw macro pval db 68h dd pval endm
;##############################################################################
.data db 'MENUET01' dd 1 dd offset _start dd offset bss_start dd offset bss_end dd offset stacktop dd 0, 0 title db 'HelloWorld test',0 string db 'FFire Demo',0 szFormatInt db "%d ",0 szFormatChar db "%hc",0 szBuffer db 256 dup(0) szCR db 13,0 szLF db 10,0
.data? bss_start label byte align 4 db 1000h dup (?) stacktop = $ stackBase dd ? dictptr dd ? dictionary dd 100000 dup(?) ipstackptr dd ? ipstack dd 256 dup(?) fpstackptr dd ? fpstack dq 128 dup(?) loopstackptr dd ? loopstack dd 64 dup(?) miscstackptr dd ? miscstack dd 64 dup(?) hOutput dd ? hInput dd ? caseVar dd ? lpCharsWritten dd ? scratch1 dd ? scratch2 dd ? returnaddress dd ? var_0000005 dd ? var_0000007 dd ? var_0000008 dd ? var_0000004 dd ? var_0000006 dd ? var_0000000 dd ? var_0000001 dd ? var_0000003 dd ? var_0000002 dd ? bss_end label byte
;##############################################################################
.code _start: mov fpstackptr,offset fpstack mov ipstackptr,offset ipstack add ipstackptr,1024 mov dictptr,offset dictionary mov miscstackptr,offset miscstack mov loopstackptr,offset loopstack
; redraw @@lbl_726564726177: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] call init call main ret redraw: call draw_window wait_event: mov eax, 11 int 40h dec eax jz redraw dec eax jz key dec eax jz close ret close: ; button pressed; we have only one button, close mov eax, -1 int 40h key: ; key pressed, read it and ignore mov eax, 2 int 40h ret jmp wait_event @@lbl_726564726177_return: mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax] ; draw_window @@lbl_647261775F77696E646F77: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] draw_window: mov eax, 12 mov ebx, 1 int 40h ; start redraw xor eax, eax mov ebx, 50*65536 + 330 ; 360 mov ecx, 150*65536 + 228 ; 228 mov edx, 33FFFFFFh mov edi, offset string ;title int 40h ; define&draw window ; mov eax, 4 ; mov ebx, 60*65536 + 10 ; mov ecx, 80000000h ; mov edx, offset string ; int 40h ; draw string ; mov ebx, 50000h ; mov eax,dword ptr [var_0000000] ; mov ecx,dword ptr [eax] ; mov eax, 47 ; mov edx, 20*65536 + 10 ; mov esi, 0h ; color ; int 40h ; draw number mov eax,dword ptr [var_0000002] mov ebx, dword ptr [eax] ; mov edx, 2*65536 + 25 ; 150 x,y ; mov ecx, 320*65536 + 228 ; 50 size mov edx, 0*65536 + 0 ; 150 x,y mov ecx, 320*65536 + 200 ; 50 size mov esi, 8 mov eax,dword ptr [var_0000006] mov edi,dword ptr [eax] mov ebp,0 mov eax,65 int 40h mov eax, 12 mov ebx, 2 int 40h ; end redraw ret @@lbl_647261775F77696E646F77_return: mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax] ; random @@lbl_72616E646F6D: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] push dword ptr [var_0000001] mov esi,dword ptr [var_0000000] pop edi mov edx,[edi] shr edx,1 mov eax,[esi] mov ecx,eax rcr ecx,1 rcl edx,1 mov [edi],edx shl eax,12 xor ecx,eax mov eax,ecx shr eax,20 xor ecx,eax mov [esi],ecx and ecx,191 mov eax,ecx push eax @@lbl_72616E646F6D_return: mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax] ; flames @@lbl_666C616D6573: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] add miscstackptr,4 mov eax,miscstackptr mov [eax-4],ebp mov ebp,loopstackptr pushdw 12160 mov eax,dword ptr [var_0000002] mov ebx,[eax] add [esp],ebx pushdw 12798 mov eax,dword ptr [var_0000002] mov ebx,[eax] add [esp],ebx mov dword ptr [esp-4],160 mov dword ptr [esp-8],0 sub esp,8 mov eax,ebp pop ecx pop edx add ebp,8 mov [eax],edx mov [eax+4],ecx @@loop_0000: push dword ptr [esp+4] push dword ptr [esp+4] pushdw 82 mov esi,0 add ebp,8 pop edi @@loop_0001: push dword ptr [esp] push dword ptr [esp] push dword ptr [esp] mov eax,[esp] movzx ebx,byte ptr [eax] mov eax,ebx pop ecx push eax lea eax,[ecx+2] movzx ebx,byte ptr [eax] add [esp],ebx pop eax pop ecx push eax lea eax,[ecx+4] movzx ebx,byte ptr [eax] add [esp],ebx pop eax pop ecx push eax lea eax,[ecx+644] movzx ebx,byte ptr [eax] add [esp],ebx mov ecx,2 shr dword ptr [esp],cl cmp dword ptr [esp],0 jz @@if_000000_false dec dword ptr [esp] @@if_000000_false: @@if_000000_true: mov eax,dword ptr [esp] shl eax,8 or [esp],eax mov eax,dword ptr [esp+8] mov ecx,dword ptr [esp] mov [eax],cx mov ecx,dword ptr [esp+8] add ecx,320 pop eax mov [ecx],ax pop eax pop ecx push eax lea eax,[ecx+640] pop ecx push eax push ecx add dword ptr [esp],640 inc esi cmp esi,edi jne @@loop_0001 @@loop_0001_end: sub ebp,8 push dword ptr [esp+4] mov eax,640 sub [esp],eax call @@lbl_72616E646F6D add dword ptr [esp],10 pop ecx pop eax mov [eax],cl lea esp,[esp+8] pop eax pop ecx push eax lea eax,[ecx+2] pop ecx push eax push ecx add dword ptr [esp],2 lea eax,[ebp-8] inc dword ptr [eax+4] mov ecx,[eax] cmp [eax+4],ecx jne @@loop_0000 @@loop_0000_end: sub ebp,8 lea esp,[esp+8] @@lbl_666C616D6573_return: sub miscstackptr,4 mov loopstackptr,ebp mov esi,miscstackptr mov ebp,[esi] mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax] ; setup-palette @@lbl_73657475702D70616C65747465: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] add miscstackptr,4 mov eax,miscstackptr mov [eax-4],ebp mov ebp,loopstackptr mov eax,dword ptr [var_0000006] push dword ptr [eax] pushdw 1024 mov eax,-1 pop ecx pop edi rep stosb mov eax,dword ptr [var_0000006] push dword ptr [eax] pushdw 33 mov esi,1 add ebp,8 pop edi @@loop_0002: push esi shl dword ptr [esp],3 dec dword ptr [esp] push dword ptr [esp+4] mov eax,0 pop ecx xchg eax,ecx mov [eax],ecx push dword ptr [esp+4] add dword ptr [esp],2 mov ecx,dword ptr [esp+4] pop eax mov [eax],cl push dword ptr [esp+4] add dword ptr [esp],128 mov eax,0 pop ecx xchg eax,ecx mov [eax],cl push dword ptr [esp+4] add dword ptr [esp],129 mov ecx,dword ptr [esp+4] pop eax mov [eax],cl push dword ptr [esp+4] add dword ptr [esp],256 mov eax,[esp] mov ecx,[esp+4] mov [eax],cl add esp,8 add dword ptr [esp],4 inc esi cmp esi,edi jne @@loop_0002 @@loop_0002_end: sub ebp,8 lea esp,[esp+4] @@lbl_73657475702D70616C65747465_return: sub miscstackptr,4 mov loopstackptr,ebp mov esi,miscstackptr mov ebp,[esi] mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax] ; draw-fire @@lbl_647261772D66697265: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] call @@lbl_666C616D6573 @@lbl_647261772D66697265_return: mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax] ; win-main @@lbl_77696E2D6D61696E: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] mov eax,dword ptr [var_0000007] mov dword ptr [eax],320 @@loop_0003: call @@lbl_647261772D66697265 mov eax,dword ptr [var_0000007] push dword ptr [eax] push dword ptr [esp] dec dword ptr [esp] mov eax,dword ptr [var_0000007] pop ecx mov [eax],ecx pop eax xor ecx,ecx sub esp,4 cmp eax,0 pop eax jnz @@loop_0003 @@loop_0003_end: @@lbl_77696E2D6D61696E_return: mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax] ; main @@lbl_6D61696E: sub ipstackptr,4 mov eax,ipstackptr pop dword ptr [eax] main: call @@lbl_73657475702D70616C65747465 push dword ptr [var_0000002] add dword ptr [esp],4 mov eax,dword ptr [var_0000002] pop ecx mov [eax],ecx mov eax,dword ptr [var_0000002] push dword ptr [eax] pushdw 64000 mov eax,0 pop ecx pop edi rep stosb main1: call @@lbl_77696E2D6D61696E call redraw jmp main1 @@lbl_6D61696E_return: mov eax,ipstackptr add ipstackptr,4 jmp dword ptr [eax]
;##############################################################################
init: mov fpstackptr,offset fpstack mov ipstackptr,offset ipstack add ipstackptr,1024 mov dictptr,offset dictionary mov miscstackptr,offset miscstack mov loopstackptr,offset loopstack
mov eax,dictptr mov var_0000000,eax add dictptr,4 mov eax,dword ptr [var_0000000] mov dword ptr [eax],19 mov eax,dictptr mov var_0000001,eax add dictptr,4 mov eax,dword ptr [var_0000001] mov dword ptr [eax],1 mov eax,dictptr mov var_0000002,eax add dictptr,4 push dword ptr [var_0000002] add dword ptr [esp],4 mov eax,dword ptr [var_0000002] pop ecx mov [eax],ecx mov eax,65000 add dictptr,eax mov eax,dictptr mov var_0000003,eax add dictptr,4 push dword ptr [var_0000003] add dword ptr [esp],4 mov eax,dword ptr [var_0000003] pop ecx mov [eax],ecx mov eax,256000 add dictptr,eax mov eax,dictptr mov var_0000004,eax add dictptr,4 mov eax,28 add dictptr,eax mov eax,dictptr mov var_0000005,eax add dictptr,4 mov eax,36 add dictptr,eax mov eax,dictptr mov var_0000006,eax add dictptr,4 push dword ptr [dictptr] mov eax,1030 add dictptr,eax mov eax,dword ptr [var_0000006] pop ecx mov [eax],ecx mov eax,dictptr mov var_0000007,eax add dictptr,4 mov eax,dictptr mov var_0000008,eax add dictptr,4
ret END _start Полученный листинг "ассемблируется" (превращается в obj), линкуется, транслируется (через использование скрипта doexe с помощью FASM) по методике описанной в Wiki P.S. Для понимания действий по формированию Flames для себя расписал действия с ячейками памяти по данному коду на листочке. (возможно имеет смысл отобразить дополнительно) и можно его, наверное если есть смысл, записать его более прозрачно средствами ForthEC или представить в виде мнемо-рисунка. Алгоритм формирования палитры более простой по действиям  (их можно переписать и на ассемблере) ForthEC тоже подвергся некоторым доработкам по способу запуска кода. Можно убрать ещё некоторую избыточность кода программы и поработать над компилятором ForthEC c опробованием разных опций оптимизации. Выполнение кода начинается с кода первого слова redraw (название в этом месте чисто номинальное и более подходит, что то сообразное Entry) А далее вызывается Init где производится инициализация стеков и main цикл по рисованию и опросу событий (в листинге ассемблера) notouch ... touch прямая вставка MASM кода без изменений для компилятора (переменные в ассемблере из Форт идентифицируются по номеру) Цикл по отрисовке заданного количество Flames в win-main избыточен (остался по недосмотру при "экспериментах" с кодом) наверное можно убрать. Работа примера не "оптимизировалась" для эмулятора (чем код необходимо дополнить) P.P.S. Тему можно как то переобозначить если дополнить другими "элементами" и их описанием этого решения (кому будет интересно) Есть интерес к рассмотрению "потенциала" и подводных камней данного подхода и варианты доработки "напильником" (головой и руками) Архив с примером и ForthEC вариантом для Kolibri OS (в файле readme указана последовательность запуска bat файлов) В системе должны присутствовать MASM32 и Euphoria (чувствительность к конкретной версии не проверялась 3-й или 4-ой) Attachment:
kol_forthec.zip [37.11 KiB]
Downloaded 223 times
Проект оригинального ForthEC находится здесь Последняя версия ForthEC от автора на github
Last edited by Kopa on Thu Apr 28, 2016 9:55 pm, edited 1 time in total.
|
|