# HG changeset patch # User telesto # Date 1681845626 -7200 # Tue Apr 18 21:20:26 2023 +0200 # Node ID 03e730eb3bd96030b3cf058d368abb7270a1958e # Parent dfb5fbaeae5e41cbef49c4a2084942f3913e6675 swapwm: added code for DISPLAY, still todo. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ cp swapwm-config.def.fox swapwm-config.fox # replace no-debug.fox with debug.fox to see debug output -srcs-swapwm = system.fox fileio.fox no-debug.fox elf64.fox \ +srcs-swapwm = system.fox fileio.fox debug.fox elf64.fox \ bootstrap2.fox fileio.fox buf.fox \ swapwm-config.fox swapwm.fox bye.fox swapwm.o: fox $(srcs-swapwm) diff --git a/asm.fox b/asm.fox --- a/asm.fox +++ b/asm.fox @@ -104,7 +104,7 @@ 28 const [r8] 29 const [r9] 2a const [r10] 2b const [r11] 2c const [r12] 2d const [r13] 2e const [r14] 2f const [r15] - ( r1 -- reg ) + ( r1 -- regid ) : reg 7 and ; ( r1 -- mod ) @@ -142,8 +142,8 @@ : +ro swap rex.b, reg or ,1 ; \ the modrm.mod field. - ( r1 -- modrm.mod ) -: modrm.mod r.mod ; + ( r1 r2 -- modrm.mod ) +: modrm.mod r.mod swap r.mod and ; \ set the modrm.reg/opcode field to register/opcode n ( modrm r1 -- ) @@ -155,16 +155,6 @@ ( modrm r1 -- ) : modrm.r/m reg or ; - \ "indicates that the modrm byte of the instruction contains - \ a register operand and a r/m operand." - \ todo: only register-register supported - \ todo: check r1 and r2 if we have a mem and encode accordingly - \ we need to change the direction bit of the opcode eventually, - \ so put that on the stack as well: ( r1 r2 opcode -- ) - ( r1 r2 -- ) -: /r c0 swap modrm.r/m swap modrm.reg ,1 ; - - \ "Some instructions cannot make use of the REG portion of \ the ModR/M byte. Many of these instructions are \ "multiplexed" using this field, where a single opcode @@ -173,8 +163,20 @@ \ are specified by following the opcode with a slash (/) \ and a digit 0-7." \ encode /digit - ( r1 opcode modrm.opcode -- ) -: /digit swap ,1 over modrm.mod swap modrm.code swap modrm.r/m ,1 ; + ( r1 instruction_opcode modrm.opcode -- ) +: /digit swap ,1 over r.mod swap modrm.code swap modrm.r/m ,1 ; + + ( r1 r2 modrm.opcode -- ) +: /r reg /digit ; + + \ "indicates that the modrm byte of the instruction contains + \ a register operand and a r/m operand." + \ todo: only register-register supported + \ todo: check r1 and r2 if we have a mem and encode accordingly + \ we need to change the direction bit of the opcode eventually, + \ so put that on the stack as well: ( r1 r2 opcode -- ) + ( r1 r2 -- ) +: /r2 over over modrm.mod swap modrm.r/m swap modrm.reg ,1 ; ( r1 modrm -- ) : /0 0 /digit ; : /1 1 /digit ; : /2 2 /digit ; : /3 3 /digit ; @@ -185,25 +187,31 @@ \ push r/m64 ( r1 -- ) -: push m64? if 50 +ro ;; then ff /6 ; +: push m64? if ( push r64 ) 50 +ro ;; then ( push m64 ) ff /6 ; \ pop r/m64 ( r1 -- ) -: pop m64? if 58 +ro ;; then 8f /0 ; +: pop m64? if ( pop r64 ) 58 +ro ;; then ( pop m64 ) 8f /0 ; ( n -- ) -: cmpraxi rex.w, # +: cmpraxi rex.w, # : cmpeaxi 3d ,1 id ; -: andraxi rex.w, # +: andraxi rex.w, # : andeaxi 25 ,1 id ; +: 3dup uber uber uber ; + + \ set direction bit according to the r/m64 values + ( r/m64 r/m64 opcode -- opcode ) +: dir rpush nip r.mod c0 / rpop or ; + \ compile "opcode r1, r2" ( r1 r2 opcode -- ) -: oprr, rpush over over rex2, rpop ,1 /r ; +: oprr, rpush over over rex2, over over rpop dir ,1 /r2 ; \ compile "opcode(2bytes) r1, r2" ( r1 r2 opcode -- ) -: oprr,2 rpush over over rex2, rpop ,2 /r ; +: oprr,2 rpush over over rex2, rpop ,2 /r2 ; \ copy register r1 into register r2 ( r1 r2 -- ) @@ -258,7 +266,7 @@ : shlr, dup rex, c1 /4 ib ; ( n r1 r2 -- ) -: shrd, over over rex2, 0f ,1 ac ,1 /r ib ; +: shrd, over over rex2, 0f ,1 ac ,1 /r2 ib ; ( r1 -- r1*[e|r]ax ) : imulrax, dup rex, # diff --git a/bootstrap2.fox b/bootstrap2.fox --- a/bootstrap2.fox +++ b/bootstrap2.fox @@ -46,8 +46,8 @@ initmain \ exit program/forth -: bye () 0 3c # \ fall through - +: bye () 0 # \ fall through +: exit ( code ) 3c # \ fall through \ syscall with one parameter ( param syscall# -- err ) : syscall1 # @@ -188,6 +188,7 @@ over over - neg drop -if \n drop drop ;; then dup @ . space # 1 cell # lit - loop ; + \ init with procstack from bootstrap.asm, so we can \ debug in interprete mode procstack @ var @@ -200,22 +201,65 @@ : #args procstack @ @ ; -: env procstack @ #args # 1 cell # lit * + ; +: *env procstack @ #args 1+ 1+ # 1 cell # lit * + ; + + \ push the addr of the first instance of the sep byte + \ in the null-terminated string + ( *0str sep -- ) +: index rpush begin + dup @1 0=? 0if rdrop drop drop -1 ;; then + r - drop 0if ( found ) rdrop ;; then + 1+ + loop ; - \ returns the #bytes to the next \0 from addr, excluding the \0 byte - ( addr -- len ) -: len\0 dup - begin - dup @1 dup + drop - for 1+ next - neg ; + \ push the #bytes of the given null-terminated string + ( addr -- len ) +: len\0 dup begin + dup @1 0=? drop + for 1+ next - neg ; - \ print \0 terminated string - ( addr -- ) + ( from to size -- ) +: mcpy # 5751 ,2 \ push rcx; push rdi + c18948 ,3 \ mov rcx, rax + 3e8b48 ,3 \ mov rdi, [rsi] + 56 ,1 \ push rsi + 08768b48 ,4 \ mov rsi, [rsi+8] + a4f3 ,2 \ rep mobsb; direction flag must be 0 + 5e ,1 \ pop rsi + 10768d48 ,4 # \ lea rsi, [rsi+0x10]; 2nip + drop + # 595f ,2 # ; \ pop rdi; pop rcx + + \ print null-terminated string to stdout + ( addr -- ) : .\0 1 swap dup len\0 write drop ; -: env1 env @ . \n ; +: env *env begin + dup @ 0=? + for + .\0 \n 1 cell + + next drop drop ; + ( *0str -- addr|0 ) +: dpy \ needs at least 10 chars: DISPLAY=:0 + dup len\0 a - drop -if dup - ;; then + dup @8 3d59414c50534944 - drop + if dup - ;; then 8 + ( push value of variable ) ; + + +: display ( -- addr|0 ) *env begin + dup @ 0=? + for + dpy 0=? if nip ;; then + drop # 1 cell # lit + + next ( addr 0 -- ) nip ; + + " DISPLAY environment variable not set." string +no-display + +: #display display 0=? 0if no-display ". \n 1 exit ;; then + 1+ ( skip ":" ) ; \ print the stack whenever a word is called. ( *str ) diff --git a/foxx.fox b/foxx.fox --- a/foxx.fox +++ b/foxx.fox @@ -78,11 +78,16 @@ : x- tos regid nos regid subrr, xdrop ; : x+ tos regid nos regid addrr, xdrop ; +: test # rcx push rdi push rdi pop rcx pop [rax] push [rax] pop + rax [rax] movrr, + [rcx] rdx addrr, # ; \ 1 xpush 2 xpush x- xdup xswap x- xdup x- dup xdup xdup xdup xdup xdrop xdup 1 xpush 2 xpush xover xnip x+ : run initmain bye ; + + end-app start-with run " foxx.o" write-obj diff --git a/mandelbrot-mt.fox b/mandelbrot-mt.fox --- a/mandelbrot-mt.fox +++ b/mandelbrot-mt.fox @@ -1,5 +1,6 @@ hex + 28 const #tasks \ # of blocks wich have to be rendered diff --git a/mandelbrot.fox b/mandelbrot.fox --- a/mandelbrot.fox +++ b/mandelbrot.fox @@ -192,7 +192,7 @@ : close-file () fh @ fclose ; -: mb () initmain initprocstack env1 setup create-file write-header write-image +: mb () initmain initprocstack setup create-file write-header write-image close-file ." done " ( a emit ) bye ; end-app start-with mb " mandelbrot.o" write-obj diff --git a/playground.asm b/playground.asm --- a/playground.asm +++ b/playground.asm @@ -131,3 +131,18 @@ mov ebx, c lea eax, [eax*4+0x45534] cmp eax, 0x100 + +; memcpy +push rcx +push rdi +mov rcx, rax +mov rdi, [rsi] +push rsi +mov rsi, [rsi+8] +rep movsb +pop rsi +lea rsi, [rsi+16] +lodsq +pop rdi +pop rcx + diff --git a/swapwm-config.def.fox b/swapwm-config.def.fox --- a/swapwm-config.def.fox +++ b/swapwm-config.def.fox @@ -1,5 +1,7 @@ hex - \ socket name of the running x server. + + \ socket name of the running x server, see FILES section + \ in Xserver(7) \ default is DISPLAY=:0 \ \ this string is destroyed when connecting, @@ -8,9 +10,9 @@ \ of struct sockaddr_un. \ thatswhy we don't save the string as is, but with 16 bit \ in front of string data. - vhere 0 v,1 \ add a byte, because we need 16 bit (strlen) + vhere 0 v,1 \ add one byte, because we need 16 bit (strlen) " /tmp/.X11-unix/X0" drop dup vlabel -socket-name +socketaddr vhere - neg const sockaddr-size diff --git a/swapwm.fox b/swapwm.fox --- a/swapwm.fox +++ b/swapwm.fox @@ -50,16 +50,38 @@ : dodbg dbg ." connect: sending connect request to server" \n edbg ; : dodbg1 dbg ." connect: success" \n edbg ; +( from sockaddr_un(3): +#include + +struct sockaddr_un { + sa_family_t sun_family; /* Address family */ + char sun_path[]; /* Socket pathname */ +}; + +from /usr/include/sys/un.h: +/* Structure describing the address of an AF_LOCAL (aka AF_UNIX) socket. */ +struct sockaddr_un + { + __SOCKADDR_COMMON (sun_); + char sun_path[108]; /* Path name. */ + }; + +__SOCKADDR_COMMON point to sa_family_t: +sockaddr.h: typedef unsigned short int sa_family_t +unsigned short int is 16 bit +) + + ( we build up struct_un here, found in /usr/include/sys/un.h. the first attribute is an unsigned short int, which is 16 bit. we just use the socket name string here, because the 2nd attribute in sockaddr_un is a c string. we overwrite the 2 last bytes of the len field with the - required value. ) + required value. see also man 7 unix ) ( fd -- ) : connect \ first write family af-unix into len field as a word - dodbg sockfd @ socket-name af-unix over !2 + dodbg sockfd @ socketaddr af-unix over !2 sockaddr-size sys-connect syscall3 " connect" -panic dodbg1 ; @@ -748,15 +770,15 @@ Button2 btn=? 0if bpev.ev warp-win ;; then Button3 btn=? 0if bpev.ev 1 tile-win ;; then dodbg ; -: dodbg () dbg ." btnpress: button: " bpev.btn . - ." ; modifiers: " bpev.state . \n edbg ; - - -1 mask-ignore xor const + -1 mask-ignore xor const cleanmask \ filter out numlock and caps lock ( mask -- mask ) : clean-mask cleanmask and ; +: dodbg () dbg ." btnpress: button: " bpev.btn . + ." ; modifiers: " bpev.state . \n edbg ; + : btnpress () dodbg bpev.state clean-mask modmask1 - 0=? drop if btnpress2 ;; then btnpress1 ;