M Makefile +1 -1
@@ 26,7 26,7 @@ swapwm-config.fox:
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)
M asm.fox +30 -22
@@ 104,7 104,7 @@ 20 const [rax] 21 const [rcx] 22 const [
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 @@ 2c const [r12] 2d const [r13] 2e const [
: +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 @@ 2c const [r12] 2d const [r13] 2e const [
( 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 @@ 2c const [r12] 2d const [r13] 2e const [
\ 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 @@ 2c const [r12] 2d const [r13] 2e const [
\ 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 @@ r13 reg! r13! r14 reg! r14! r15 reg! r15
: 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, #
M bootstrap2.fox +56 -12
@@ 46,8 46,8 @@ main-tls
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 @@ m: ." ^ " # ffind ". # lit call, ;
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 @@ m: initprocstack () \ mov qword ptr [pro
: #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 )
M foxx.fox +5 -0
@@ 78,11 78,16 @@ s1
: 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
M mandelbrot-mt.fox +1 -0
@@ 1,5 1,6 @@
hex
+
28 const
#tasks \ # of blocks wich have to be rendered
M mandelbrot.fox +1 -1
@@ 192,7 192,7 @@ m: +if 78 ,1 \ js
: 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
M playground.asm +15 -0
@@ 131,3 131,18 @@ mov eax, c
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
+
M swapwm-config.def.fox +5 -3
@@ 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 @@ hex
\ 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
M swapwm.fox +28 -6
@@ 50,16 50,38 @@ sockfd \ x11 socket file handle
: dodbg dbg ." connect: sending connect request to server" \n edbg ;
: dodbg1 dbg ." connect: success" \n edbg ;
+( from sockaddr_un(3):
+#include <sys/un.h>
+
+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 @@ ignev
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 ;