From: luser.droog@nospicedham.gmail.com   
      
   On Monday, May 14, 2018 at 10:27:59 PM UTC-5, Rod Pemberton wrote:   
   > On Fri, 11 May 2018 20:29:46 -0700 (PDT)   
   > luserdroog wrote:   
   >   
   > > I've settled on using si for now. bp seems tempting for this, but   
   > > you always have to have a displacement even if it's zero because   
   > > mod=0 r/m=6 does something else. So using si I have   
   > >   
   > > mov si, sp   
   > > mov ax, [si] ; smaller encoding   
   > >   
   > > and   
   > >   
   > > mov si, sp   
   > > mov ax, [si+2]   
   > >   
   > > For giggles, here's my draft so far. In a form which should   
   > > be convenient to plug into my emulator.   
   > >   
   >   
   > If you're loading SI, you can use LODSW. It will index SI for you.   
   > Use CLD or STD to set the direction, increment or decrement, for   
   > indexing.   
   >   
   > > $ cat forth.h   
   > > #define NEXT HEX3(ad,ff,e8)   
   > > #define CHAR(x) *#x   
   > > #define CHAR2(x,y) CHAR(x),CHAR(y)   
   > > #define CHAR3(x,y,z) CHAR2(x,y),CHAR(z)   
   > > #define CHAR4(w,x,y,z) CHAR2(w,x),CHAR2(y,z)   
   > > #define CHAR5(w,x,y,z,a) CHAR4(w,x,y,z),CHAR(a)   
   > > #define HEX(y) 0x##y   
   > > #define HEX2(x,y) HEX(x),HEX(y)   
   > > #define HEX3(x,y,z) HEX2(x,y),HEX(z)   
   > > #define HEX4(w,x,y,z) HEX2(w,x),HEX2(y,z)   
   > > #define HEX5(w,x,y,z,a) HEX4(w,x,y,z),HEX(a)   
   > >   
   > > static inline int   
   > > forth(char *mem){   
   > > char image[] = {   
   > > 0, 4, CHAR4(d,r,o,p), HEX(58), NEXT,   
   > > 0, 4, CHAR4(s,w,a,p), HEX4(58,5b,50,53), NEXT,   
   > > 0, 3, CHAR3(d,u,p),0, HEX5(8b,ec,8b,5,50), NEXT,   
   > > 0, 4. CHAR4(o,v,e,r), HEX6(8b,ec,8b,45,2,50), NEXT,   
   > > 0, 3, CHAR3(r,o,t),0, HEX6(58,5b,59,53,50,51), NEXT,   
   > > 0, 4, CHAR4(-,r,o,t), HEX6(58,5b,59,50,51,53), NEXT,   
   > > 0, 5, CHAR5(2,d,r,o,p),0, HEX2(58,59), NEXT,   
   > > 0, 4, CHAR4(2,d,u,p), HEX4(8b,ec,8b,5),HEX5(8b,5d,2,53,50), NEXT,   
   > > 0, 5, CHAR5(2,s,w,a,p),0, HEX4(58,5b,59,5a),HEX4(53,50,52,51),   
   > > NEXT, 0, 4, CHAR4(?,d,u,p),   
   > > HEX4(8b,ec,8b,5),HEX2(85,c0),HEX3(74,1,58), NEXT, 0, 2, CHAR2(1,+),   
   > > HEX4(8b,ec,ff,5), NEXT, 0, 2, CHAR2(1,-), HEX4(8b,ec,ff,d), NEXT,   
   > > 0, 1, CHAR(+),0, HEX5(58,8b,ec,1,5), NEXT,   
   > > 0, 1, CHAR(-),0, HEX5(58,8b,ec,29,5), NEXT,   
   > > 0, 1, CHAR(*),0, HEX5(58,5b,f7,eb,50), NEXT,   
   > > };   
   > > memcpy(mem, image, sizeof image);   
   > > }   
   > >   
   > >   
   >   
   > It works, but ouch.   
      
   Agreed. The file did not remain in that form for long.   
   I hope you'll also look at my later posts from May 12   
   which reads more nicely.   
      
   > Word alignment?   
      
   My plan was to ignore this at first. The target is my   
   own 8086 emulator which is missing roughly 1/3 of the   
   full instruction set.   
      
   > Is there some reason why putc() or putchar() i.e., send characters   
   > directly to an open tmpfile() file, wouldn't work in your macros?   
   >   
      
   No, I just hadn't consider that! That would simplify quite a bit   
   from the later versions.   
      
   > > Need to stitch up the link fields somehow.   
   >   
   > Of course, &image[XX], provides the address: image+XX. However, you   
   > only have a byte to encode a length to the next primitive. You could   
   > subtract two addresses. The problem is that any time you insert or   
   > delete bytes into any Forth word within image[], /all/ of the XX   
   > indexes from there onwards to the end of the dictionary, become   
   > incorrect and must be manually adjusted, since their values have been   
   > hard coded. BTDT.   
   >   
   > Now, if you called putc() or putchar() in your macros to write the   
   > bytes out to a file, then you could create a wrapper routine for putc()   
   > or putchar(), say i_putc(), which also increments a counter variable   
   > every time you output a character to a file. This variable would give   
   > you the current index position within image[]. Any time the char was   
   > '\0', you'd save the counter to subtract to later subtract from the   
   > current counter to obtain the LFA offset. Of course, that would mean   
   > that you'd need to use something other than '\0' for word padding the   
   > name field, e.g., perhaps a space.   
   >   
      
   Yes, that does seem like a good approach. I've gone in a different   
   direction with more complicated macros. But I am tempted to backtrack   
   and build the image with smaller functional pieces which are then   
   combined.   
      
   Still a work in progress, but here's the latest draft. It's now split   
   into several files.   
      
   $ for i in ppnarg.h asm8086.h applyx.h forth.h ; do echo ---- $i: ---- ; cat   
   $i ; done && echo -- && cpp -P forth.h   
   ---- ppnarg.h: ----   
   /*   
    * The PP_NARG macro evaluates to the number of arguments that have been   
    * passed to it.   
    *   
    * Laurent Deniau, "__VA_NARG__," 17 January 2006, (29 November   
   2007).   
    */   
   #define PP_NARG(...) PP_NARG_(__VA_ARGS__,PP_RSEQ_N())   
   #define PP_NARG_(...) PP_ARG_N(__VA_ARGS__)   
      
   #define PP_ARG_N( \   
    _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \   
    _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \   
    _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \   
    _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \   
    _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \   
    _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \   
    _61,_62,_63,N,...) N   
      
   #define PP_RSEQ_N() \   
    63,62,61,60, \   
    59,58,57,56,55,54,53,52,51,50, \   
    49,48,47,46,45,44,43,42,41,40, \   
    39,38,37,36,35,34,33,32,31,30, \   
    29,28,27,26,25,24,23,22,21,20, \   
    19,18,17,16,15,14,13,12,11,10, \   
    9,8,7,6,5,4,3,2,1,0   
   ---- asm8086.h: ----   
      
   #define LEA(to,m,r,r_m) to+0x8d,MRM(m,r,r_m)   
   #define MOV(to,m,r,r_m) to+0x8b,MRM(m,r,r_m)   
   #define ADD(to,m,r,r_m) to+0x03,MRM(m,r,r_m)   
   #define SUB(to,m,r,r_m) to+0x2b,MRM(m,r,r_m)   
   #define F -2   
   #define MRM(m,r,r_m) 0##m##r##r_m   
   #define Z 0   
   #define B 1   
   #define W 2   
   #define R 3   
   #define AX 0   
   #define CX 1   
   #define DX 2   
   #define BX 3   
   #define SP 4   
   #define BP 5   
   #define SI 6   
   #define DI 7   
   #define BX_SI 0   
   #define BX_DI 1   
   #define BP_SI 2   
   #define BP_DI 3   
   #define SI_ 4   
   #define DI_ 5   
   #define BP_ 6   
   #define BX_ 7   
   #define TEST(m,r,r_m) 0x85,MRM(m,r,r_m)   
   #define IMUL(m, r_m) 0xf7,MRM(m,5,r_m)   
   #define INC_(m, r_m) 0xff,MRM(m,0,r_m)   
   #define DEC_(m, r_m) 0xff,MRM(m,1,r_m)   
   #define JMP_(m, r_m) 0xff,MRM(m,5,r_m)   
   #define POP(r) 0x58+r   
   #define PUSH(r) 0x50+r   
   #define ADDAX 0x05   
   #define LODS 0xAD   
   #define JZ 0x74   
   ---- applyx.h: ----   
   #include "ppnarg.h"   
      
   /* need extra level to force extra eval */   
   #define Paste(a,b) a ## b   
   #define XPASTE(a,b) Paste(a,b)   
      
      
   /* APPLYXn variadic X-Macro by M Joshua Ryan */   
   /* Free for all uses. Don't be a jerk. */   
   /* I got bored after typing 15 of these. */   
      
   [continued in next message]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|