swapwm: added code for DISPLAY, still todo.
9 files changed, 142 insertions(+), 45 deletions(-)

M Makefile
M asm.fox
M bootstrap2.fox
M foxx.fox
M mandelbrot-mt.fox
M mandelbrot.fox
M playground.asm
M swapwm-config.def.fox
M swapwm.fox
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 ;