Well, the assembler is proceeding apace... features so far include: Flag Equates:
Flags are local to labels, but each flag must be named uniquely. You can have more than one flag name per bit position though. eg. Say you're setting up the LMPR register for use later. You can set up the flags at the same time! LMPR: EQU 250 LMPR: EQUF 7 : WPROT, 6 : ROM1, 5 : ROM0 ... or even... FLAGS: EQUF 3 : DOTHIS, 2 : DOTHAT, 1:DOTHEOTHER, 0:ERROR However, in this case, FLAGS is not defined anywhere else; so LD A,(FLAGS) would give an undefined label error. However, you could still do LD A,FLAGS:DOTHIS and it'd be quite happy. And you'd access the flags like this... IN A,(LMPR) BIT LMPR:WPROT, A AND LMPR:ROM1 | LMPR:ROM0 Bit Value/Position operators: ~ returns a bit position (log2 n) @ returns a bit value (2^n) BIT, RES and SET's all have implicit bit position operators on all flags equates used. So, for the example above: IN A,(LMPR) BIT LMPR:WPROT, A ; is actually... BIT ~LMPR:WPROT,A All other uses of flags have an implicit bit-value operator. So for the AND part of the example above, that is: AND @LMPR:ROM1 | @LMPR:ROM0 Errors are generated if the @ operator is passed a value which is not a positive integer from 0-31, or if the ~ operator is passed a value which is not 2^n where 0 <= n <= 31. The BIT,RES and SET instructions, before utilising the value provided, will ensure that it is a +ve integer from 0-7 was passed in. If the value is not a positive integer (or zero), it will generate an error. If it is out of range (ie. > 7), it will be moved into range (& 7) and a warning will be generated. Macros work like this: DEFMACRO pushall l1: PUSH AF EX AF,AF' PUSH AF l2: PUSH DE PUSH BC PUSH HL EXX PUSH DE PUSH BC PUSH HL PUSH IX PUSH IY ENDMACRO To use the macro in your code, you'd do this: MACRO pushall To access the labels in the macro (which are local to the macro), you'd do this: OR A JP Z,mymacro:l2 mymacro: MACRO pushall ... passing data into macros works as in #DEFINE in C; you pass a string, and it gets tokenized. EG: DEFMACRO mymacro($rega,$regb) PUSH AF LD A,rega LD rega,regb LD regb,A POP AF ENDMACRO - but this needs more work. Other label operations: <label>:M - get physical output address of label (ie. the DISP address) <label>:P - get physical output page of label (ie. the DISP page) <label>:L - get length of code/string/values on the line that the label refers to. eg. label1: DEFB 0,1,2,3,4,5,6,7 ;label1:L = 8 label2: DEFM "Hi", "Hello" ;label2:L refers only to first string; so label2:L = 2 label3: DEFF 0.0F,0.3F ;label3:L = sizeof(float) * 2 Self-modifying code stuff: <label>:D - references the data part of an opcode eg. infix.storage: LD A,0 OR A JR NZ,blah LD A,23 LD (infix.storage:D),A ; equivalent to LD (infix.storage+1),A <label>:IX - references an index offset for an IX or IY operation eg. modify: LD A,(IX + 0) ... LD (modify:IX),32 ------------------------- Data defines: DEFB - define series of byte values DEFW - define series of word values DEFF - define series of floating point/fixed point values Yet to be defined. Some kind of switch mechanism will let you change how this works - eg. floating point? fixedpoint? SAM floating point? etc etc etc. DEFM - define string (not terminated) DEFZ - define string (zero terminated) DEFH - define string (bit 7 of last character is set) DEFS - fill N bytes with values eg. DEFS 30 ; fills the next 30 bytes with zeroes DEFS 10,2 ; fills the next 10 bytes with 0x02 DEFS 100, 1,2,3,4 ; fills the next 100 bytes with the repeating values 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4.... ... more to come... Si