												; this file is not to be assembled during the build 
												; process - this is a macro definition file
												; to be used as a source for macro expansion. do not 
												; assemble this file - leave it as it is
												;
												; also most macros have not been converted to use the
												; sub convention and still use the older macro system
												; convention - only parsefs has been converted
												;
#define,sub											;
												; sub macro - glb.smsl
												;
												; arguments
												; arg1 - reg 
												;
												; output
												; r9 - data in reg
												;
												; clobbers
												; r8, r9, r10, r11
												;
												; note - when packing data, data being appended must
												; not include 0x00. This was chosen since most args
												; that need this done are ASCII and this is not an
												; ASCII character.
												;
		mov r8, '%arg1'									; get it stable
		xor r10, r10									;
												;
	scan:											;
		mov r9, r8									;
		mov r11b, r9b									;
	rescan:											;
												;
		cmp r9b, '5'									;
		je r15?										;
		cmp r9b, '4'									;
		je r14?										;
		cmp r9b, '3'									;
		je r13?										;
		cmp r9b, '2'									;
		je r12?										;
		cmp r9b, '1'									;
		je r11?										;
		cmp r9, 'r'									;
		je rX?										;
												;
		cmp r11b, r9b									; check if we are at the end
		je notfound									;
												;
		jmp rescan									;
												;	
	rX?:											;
		shr r9 , 8									;
		cmp r9b, 'a'									;
		je rax?										;
		cmp r9, 'b'									;
		je rbX?										;
		cmp r9b, 'c'									;
		je rcx?										;
		cmp r9b, 'd'									;
		je rdX?										;
		cmp r9b, 's'									;
		je rsX?										;
		jmp rescan									;
												;
	rax?											;
		shr r9, 8									;
		cmp r9b, 'x'									;
		je rax										;
		jmp rescan									;
												;
	rbX?											;
		shr r9, 8									;
		cmp r9b, 'x'									;
		je rbx										;
		cmp r9, 'p'									;
		je rbp										;
		jmp rescan									;
												;
	rcx?											;
		shr r9, 8									;
		cmp r9b, 'x'									;
		je rcx										;
		jmp rescan									;
												;
	rdX?											;
		shr r9, 8									;
		cmp r9b, 'x'									;
		je rcx										;
		cmp r9b, 'i'									;
		je rdi										;
		jmp rescan									;
												;
	rsX?											;
		shr r9, 8									;
		cmp r9b, 'i'									;
		je rsi										;
		cmp r9b, 'p'									;
		je rsi										;
		jmp rescan									;
												;
												; do the ones for rax - rsb lowest level ones
												;
	r15?:											;
		shr r9, 8									;
		cmp r9b, '1'									;
		jne rescan									;
		shr r9, 8									;
		cmp r9b, 'r'									;
		je r15										;
		jmp rescan									;
												;
	r14?:											;
		shr r9, 8									;
		cmp r9b, '1'									;
		jne rescan									;
		shr r9, 8									;
		cmp r9b, 'r'									;
		je r14										;
		jmp rescan									;
												;
	r13?:											;
		shr r9, 8									;
		cmp r9b, '1'									;
		jne rescan									;
		shr r9, 8									;
		cmp r9b, 'r'									;
		je r13										;
		jmp rescan									;
												;
	r12?:											;
		shr r12, 8									;
		cmp r12b, '1'									;
		jne rescan									;
		shr r12, 8									;
		cmp r12b, 'r'									;
		je r12										;
		jmp rescan									;
												;
	r11?:											;
		shr r9, 8									;
		cmp r9b, '1'									;
		jne rescan									;
		shr r9, 8									;
		cmp r9b, 'r'									;
		je r11										;
		jmp rescan									;
												;
												;
	r15:											;
		mov r8, r15									;
												;
		shl r9, 16 									; data should now be at the end
	_r15:											;
		cmp r9b, 0x00									;
		shl r9, 8									;
		inc r10										;
		jne _r15									;
		shr r9, 8									;
	__r15:											;
		cmp r10, 0									;
		jne ___r15									;
		jmp cleanexit									;
												;
	___r15:											;
		shl r9, 8									;
		or r8b, r9b									;
		dec r10										;
		jmp __r15									;
												;
	r14:											;
		mov r8, r14									;
												;
		shl r9, 16 									; data should now be at the end
	_r14:											;
		cmp r9b, 0x00									;
		shl r9, 8									;
		inc r10										;
		jne _r14									;
		shr r9, 8									;
	__r14:											;
		cmp r10, 0									;
		jne ___r14									;
		jmp cleanexit									;
												;
	___r14:											;
		shl r9, 8									;
		or r8b, r9b									;
		dec r10										;
		jmp __r14									;
												;
	r13:											;
		mov r8, r13									;
												;
		shl r9, 16 									; data should now be at the end
	_r13:											;
		cmp r9b, 0x00									;
		shl r9, 8									;
		inc r10										;
		jne _r13									;
		shr r9, 8									;
	__r13:											;
		cmp r10, 0									;
		jne ___r13									;
		jmp cleanexit									;
												;
	___r13:											;
		shl r9, 8									;
		or r8b, r9b									;
		dec r10										;
		jmp __r13									;
												;
	r12:											;
		mov r8, r12									;
												;
		shl r9, 16 									; data should now be at the end
	_r12:											;
		cmp r9b, 0x00									;
		shl r9, 8									;
		inc r10										;
		jne _r12									;
		shr r9, 8									;
	__r12:											;
		cmp r10, 0									;
		jne ___r12									;
		jmp cleanexit									;
												;
	___r12:											;
		shl r9, 8									;
		or r8b, r9b									;
		dec r10										;
		jmp __r12									;
												;
	r11:											;
		mov r8, r11									;
												;
		shl r9, 16 									; data should now be at the end
	_r11:											;
		cmp r9b, 0x00									;
		shl r9, 8									;
		inc r10										;
		jne _r11									;
		shr r9, 8									;
	__r11:											;
		cmp r10, 0									;
		jne ___r11									;
		jmp cleanexit									;
												;
	___r11:											;
		shl r9, 8									;
		or r8b, r9b									;
		dec r10										;
		jmp __r11									;
												;
	notfound:										;
		mov r9, r8									; silently fail
		jmp cleanexit									;
												;
	hardexit:										; now here i would like to do something like
												; call,exit,'rax'
												; but exit calls this macro, so we just
		hlt										; halt the cpu since there is no clean
												; way to exit at this point
	cleanexit:										; the actual clean exit path
		nop										; just return to the caller
												;
												; handle other regs eventually
												;
&endsec,conv											;
												;
												;
#define,parsefs											;
												; parsefs macro - glb.smsl
												;
												; arguments
												; arg1 - [sig|buff|state|proc|fsys]
												; arg2 - (memfs)
												; arg3 - (name)
												; arg4 - [creat|nocreat]
												;
												; output
												; r8  - pointer to file start
												; r9  - size of the file
												; r12 - 1s if creat created, 1s if nocreat exists
												;
												; clobbers
												; r8, r9, r12, r13, r14, r15
												;
		!startusablemem,(placeholder)							; define start of usable filesystem memory
		!endusablemem,(placeholder)							; define enf of usable filesystem memory
												;
	init:											; initalize standard values
		mov r13, '%arg1'								; put arg1 into a stable place
		mov qword r14, '%arg3'								; put arg3 into a stable place
		mov qword r8, '%arg2'								; put arg2 into a semi-stable place
		mov r15, *startusablemem							; set the start of usable memory (minus 1024)
		mov r9, *endusablemem								; set the end of usable memory
												;
		@call,conv,'r13'								; convert register to inline data
		mov r13, r9									; grab the return value
		@call,conv,'r14'								; same thing 2x 
		mov r14, r9									;
		@call,conv,'r8'									;
		mov r8, r9									;
												;
	searchfs:										; entry to filesystem search function
		add r15, 512									; increment record pointer
		cmp r15, r9									; check if at the end of usable memory
		jge hardexit									; if >=, goto exit case, else continue
		cmp [r15], r8									; compare arg2 to the memfs name
		jne searchfs									; if not equal, goto loop, else, fall through
												;
		cmp byte [r15 + 63], 0								; make sure it is vp12vmfsf format
		jne hardexit									; if not, exit, else, fall through
												;
	searchfile:										; entry to search for the file
		add r15, 512									; increment filesystem record pointer
		cmp r15, r11									; check if at the end of usable memory
		jge notfound									; if >=, goto notfound, else continue
		cmp [r15], r14									; check if file name matches
		jne searchfile									; if not equal, goto loop, else, fall through
												;
	handler:										; entry for handler
		cmp r13b, 'b'									; is arg1 a buffer?
		jz buffhandler									; if so, goto buffhandler
												;
		cmp r13b, 's'									; is arg1 a state?
		jz statehandler									; if so, goto statehander
												;
		cmp r13b, 'p'									; is arg1 a proc?
		jz prochandler									; if so, goto prochandler
												;
		cmp r13b, 'f'									; is arg1 an fsys?
		jz fsyshander									; if so, goto fsyshandler
												;
												; signal is the most common - fall through to it 
												; if no other matches
												; this also allows us to lazy parse so yay :D
												;
	sighandler:										; entry for signal handlers
		cmp r14b, [r15 + 63]								; verify file name
		jne hardexit									; if name is valid, continue, else, exit
		cmp r8b, [r15 + 127]								; verify filesystem name
		jne hardexit									; if name is valid, continue, else, exit
		mov r8, [r15 + 192]								; name no longer needed - set r8's output
		mov r12, 1									; set the found flag
												; end of shared code
		mov r9, 448									; signals are always 448 bytes, so set it
		jmp gracefulexit								; exit cleanly
												;
	buffhandler:										; entry for buffer handlers
		cmp r14b, [r15 + 63]								; verify file name
		jne hardexit									; if name is valid, continue, else, exit
		cmp r8b, [r15 + 127]								; verify filesystem name
		jne hardexit									; if name is valid, continue, else, exit
		mov r8, [r15 + 192]								; name no longer needed - set r8's output
		mov r12, 1									; set the found flag
												; end of shared code
		mov r9, [r15, + 188]								; buffers have a thingy for the size; this is it
		jmp gracefulexit								; exit cleanly
												;
	statehandler:										; entry for state handlers
		cmp r14b, [r15 + 63]								; verify file name
		jne hardexit									; if name is valid, continue, else, exit
		cmp r8b, [r15 + 127]								; verify filesystem name
		jne hardexit									; if name is valid, continue, else, exit
		mov r8, [r15 + 192]								; name no longer needed - set r8's output
		mov r12, 1									; set the found flag
												; end of shared code
		mov r9, 2496									; states are always the same size
		jmp gracefulexit								; exit cleanly
												;
	fsyshandler:										; entry for fsys handlers
		cmp r14b, [r15 + 63]								; verify file name
		jne hardexit									; if name is valid, continue, else, exit
		cmp r8b, [r15 + 127]								; verify filesystem name
		jne hardexit									; if name is valid, continue, else, exit
		mov r8, [r15 + 192]								; name no longer needed - set r8's output
		mov r12, 1									; set the found flag
												; end of shared code
		mov r9, 192									; fsys files are always the same size
		jmp gracefulexit								; exit cleanly
												;
	notfound:										; entry for creat/nocreat handling
		mov r12, '%arg4'								; move creat/nocreat flag to a stable place
		cmp r12, 'creat'								; check if nocreat set
		jne notfexit									; if not set, goto exit, else, fall through
												;
	creat:											; entry for if not found + creat case
		add r15, 512									; incriment filesystem record pointer
		cmp r15, r9									; check if at the end of usable mem
		je hardexit									; exit if so, else continue
		cmp [r15], 0									; check if zero (unallocated)
		je create									; if equal, goto handler
		jmp creat									; else, goto loop
												;
	create:											; entry to create the file
		mov [r15 + 56], r14								; set the name of the file
		mov [r15 + 120], r8								; set the memfs of the file
		mov [r15 + 184], r13								; set the type of the file
												;
		mov r12, 1									; set the creat flag
		jmp handler									; re-parse
												;
	hardexit:										; entry for standard exiting
												; id like to do something like
												;
												; call,parsefs,'fsys','rax','fsys','nocreat'
												; mov r8, [r8 + 191] 
												; call,exit,'r8'
												;
												; but this is not a good idea since exit
												; itself calls parsefs
		hlt										; so we just halt the CPU
												;
	notfexit:										; entry for exiting with nocreat
		mov r12, 0									; set r12 since it does not exist
												; fall through to the exit
												;
	gracefulexit:										; entry for the finish of the program
		nop										; just because
												;
&endsec,parsefs											;
												;
#define,exit											;
												; exit macro - glb.smsl
												;
												; arguments
												; arg1 - id
												;
												; returns
												; nothing :D
												;
												; clobbers 
												; r8, r9, r10, r12, r13, r14, r15, rbx, rcx
												;
												; this macro is a bit special since it does not
												; return control back to the process calling it, 
												; so it is allowed to clobber process macros.
												;
	init:											; shared init
												;
		mov r10, '%arg1'								; move the id into a stable place
		@call,paresefs,fsys,rax,r10'.f',nocreat	; get the fsys file			;
		mov rbx, r8									; get the fsys entry into a stable place
		@call,parsefs,proc,r10,rbx'.p',nocreat	; find the process file			;
		mov rcx, r8									; get the process file entry into a stable place
												; this is done near the start, since this will
												; be used seveal times through the program. this
												; uses 2 extra registers but allows the macro to
												; only be called once. this is a tradeoff.
												;
	getdefproc:										; entry to get the default process id
												; rcx should hold the start of the fsys file
												; as placed by the init.
		mov byte r10, [rcx + 191]							; move the default id into a stable place
		mov byte rbx, [rcx + 312]							; get the process entry point
												;
	delfile:										; entry for deleting the file
		@call,parsefs,proc,r10,rbx'.p',nocreat						; find the process file
		mov qword [r8 - 192], 0								; delete the file (1)
		mov qword [r8 - 128], 0								; delete the file (2)
		mov qword [r8 - 64], 0								; delete the file (3)
		mov qword [r8], 0								; delete the file (4)
		mov qword [r8 + 64], 0								; delete the file (5)
		mov qword [r8 + 128], 0								; delete the file (6)
												;
	fixfsys:										; entry for fixing the fsys file
		mov byte [r10 + 191], rcx							; set the new controlling process process
		jmp rbx										; goto new process
												;
												; this macro does not need any exit cases
												; since this macro should not return an error
												; under normal execution. if this macro does
												; error, then something is seriously wrong.
&endsec,exit											;
												;
#define,save											;
												; save macro - glb.smsl
												;
												; arguments
												; arg1 - memfs
												; arg2 - id
												;
												; returns
												; nothing :D
												;
												; clobbers
												; r8, r9, r10, r11, r12, r13, r14, r15
												;
	init:											; entry for the init
		; mov r10, '%arg1'								; get arg1 into a stable place
												; sadly, due to the lack of temporary
												; registers on amd64, arg1 cannot be 
												; moved to a stable or semi-stable place.
		mov r11, '%arg2'								; get arg2 inton a stable place
												;
	setstate:										; entry for creating the state file
		@call,parsefs,state,'%arg1',r11.'sav',creat 					; get the proc file
		mov r10, r8									; save the start of the state file
		mov [r10 + 63], r11								; set the id in the state file
		mov [r10 + 255], end								; set the re-entry point to the 'end' label
		mov [r10 + 319], 'arg1'								; set the filesystem name in the state file
												;
		@call,parsefs,proc,'arg1',r11'.proc',nocreat 					; get the proc file
		mov [r11 + 127], [r8 + 191]							; set the start memory
		mov [r11 + 191], [r8 + 255]							; set the end memory
												;
	general:										; entry to dump general registers
		add r11, 320									; set r11 to r11 + 320, aka the 
												; start of the general regs area
		mov [r11], rbx									; save rbx
		mov [r11 + 8], rcx								; save rcx
		mov [r11 + 16], rdx								; save rdx
		mov [r11 + 24], rsi								; save rsi
		mov [r11 + 32], rdi								; save rdi
												; rsp is not needed since vp12 is stackless
												; rbp is not needed since vp12 is stackless
												;
												;
	vector:											; entry to dump avx512 registers
												;
	end:											; continue
		nop										; just because
												;
												; finish this macro
												;
&endsec,save											;
												;
#define,yield											;
												; yield macro - glb.smsl
												;
												; arguments
												; arg1 - id to yield to
												;
												; returns
												; nothing :D
												;
												; clobbers
												; r8, r9, r10, r11, r12, r13, r14, r15, rbx
												;
												; this macro is a lil special, since it does
												; not return. this means it is allowed
												; to clobber process registers.
												;
												; this macro is pretty simple
												; it should not need labels
		@call,save,arg1									; create the save file
		mov r10, arg1									; get arg1 into a stable place
		@call,parsefs,proc,rax,r10'.prc',nocreat					; get the process file
		mov [r8 + 191], rbx								; get the process entry into a stable place
		@call,parsefs,fsys,rax,fsys,nocreat						; get the fsys file
		mov byte r11, [r8 + 191]							; get my process id into a stable place
		mov [r8 + 191], r11								; set the new controlling process
		jmp rbx										; goto the new process
												; this macro does not need an exit case,
												; as it should never exit. if it does,
												; then something is very much wrong.
&endsec,yield											;
												;
#define,fall											;
												; fall macro - glb.smsl
												;
												; arguments
												; arg1 - memfs
												;
												; clobbers
												; r8, r9, r10, r12, r13, r14, r15
												;
												; returns
												; none :D
		@call,parsefs,fsys,%arg1,fsys,nocreat						; get the fsys file
		mov r10, [r8 + 189]								; get my process ID
												;
												; first time needs extra handling
		@call,parsefs,proc,%arg1,r10'.proc',nocreat 					; get the first one
		inc r10										; inc the ID
		cmp r12, 1									; check if found
		jne isme									; I am the last one :D
												;
	loop:											; entry for le loop
		inc r10										; incriment the ID
		@call,parsefs,proc,%arg1,r10'.proc',nocreat					; find the file
		cmp r12, 1									; check if it exists
		je loop										; repeat if so
		@call,yield,%arg1,r10								; yield
												;
	isme:											; entry for the thing
		@call,yield,%arg1,0								; yield to proc 0 if so
												;
												; all this only works because process IDs are
												; numeric values from 0 to 255
&endsec,yield											;
