home *** CD-ROM | disk | FTP | other *** search
- ; This file contains the definition of the macros and other items which
- ; generally define the structure of the implementation.
-
- mexp 0 ; Set non-zero for expansions
-
- ; =======================
-
- ; Flag codes for various word types. The actual values are quite
- ; arbitrary, but let us do conditional comparison on numeric values
- ; rather than strings, which is faster and uses less memory during
- ; assembly.
-
- inline equ 0
- docode equ 1
- docol equ 3
- docon equ 5
- doval equ 6
- doObj equ 7
- dovbl equ 8
- dovect equ 9
- doDynVect equ 4
- spec equ 10
- xinfo equ 11
- nocode equ 12
- doObjPtr equ 13
- xinfoN equ 14
-
- xinfoMk equ $4E58 ; This is UNLK A0 which never appears in
- ; Mops code. (Pretty unlikely anywhere!!)
-
- ; ========================
-
- FCBlen equ 204
- HOLDlen equ 30
- PADlen equ 200
- TIBlen equ 400
- ErrDumpLen equ 200
- MaxDump equ (ErrDumpLen / 8) - 5
-
- FBlkLen equ FCBlen + HOLDlen + PADlen + TIBlen + ErrDumpLen + 8
- ; The extra 8 is for the object header
-
- ; ========================
-
- hbase equ 0
-
- ; Codes for handler routines. These must all be negative.
-
- inl_h equ -1
-
- ; The following codes are used to table jump to the right routine within
- ; Handlers, and so must be negative and even.
-
- col_h equ -2
- call_h equ col_h
- const_h equ -4
- val_h equ -6
- create_h equ -8
- vect_h equ -10
- pm_h equ -12
- at_h equ -14
- store_h equ -16
- callstr_h equ -18
- reg_h equ -20
- obj_h equ -22
- does_h equ -24
- loc_h equ -26
- LitAddr equ -28
- PushDesc_h equ -30
- cmp_h equ -32
- hLiteral equ -34
- CompExit equ -36
- CompJSRLong equ -38
- pif equ -40
- compPlLoop equ -42
- hmentry equ -44
- hplentry equ -46
- heb equ -48
- hStkObj equ -50
- hDoEx equ -52
- hgenaddr equ -54
- hgenxaddr equ -56
- class_h equ -58
- hcompimp equ -60
- objPtr_h equ -62
- bit_h equ -64
- swap_h equ -66
- hLoadBA equ -68
- FixDoes equ -70
- hPatch equ -72
- Floc_h equ -74
- Fcon_h equ -76
- Fval_h equ -78
- FP1_h equ -80
- FP2_h equ -82
- FPcmp_h equ -84
- hcompFPUL equ -86
- FCRcon_h equ -88
- class_in_mod_h equ -90
- imported_h equ -92
- hColA equ -94
- shift_h equ -96
- hDefnEnd equ -98
- Fat_h equ -100
- Fst_h equ -102
- builds_h equ -104
- MultDiv_h equ -106
- Move_h equ -108
- AlignedMove_h equ -110
- hNoOpt equ -112
- colNoOpt_h equ -114
- hComputedJMP equ -116
- dynVect_h equ -118
-
-
- ; =======================
-
- ; MACROS
-
- ; =======================
-
- ; Push and pop macros - modified to use A6 instead of A7.
-
- push.b macrox &1
- move.b &1,-(a6)
- endm
-
- push.w macrox &1
- move.w &1,-(a6)
- endm
-
- push macrox &1
- move.w &1,-(a6)
- endm
-
- push.l macrox &1
- move.l &1,-(a6)
- endm
-
- pop.b macrox &1
- move.b (a6)+,&1
- endm
-
- pop.w macrox &1
- move.w (a6)+,&1
- endm
-
- pop macrox &1
- move.w (a6)+,&1
- endm
-
- pop.l macrox &1
- move.l (a6)+,&1
- endm
-
-
- ; Since we are using A5 as the module base reg, we need to reset it to CurrentA5
- ; over many system calls. We also need to save RP (A7) in case the system calls
- ; us back (i.e. to a :PROC). So here we define macros to set up for a system call
- ; then restore things after the system returns.
-
- SavA5 macrox
- jsr DoSavA5-base(a3)
- endm
-
- RstA5 macrox
- exg a6,a7
- move.l (a7)+,a5
- endm
-
-
- ; N assembles a push of the parameter as a literal number, with optimization.
-
- N macrox &1
- if &1 = 0
- CLR.L -(A6)
- else
- if (&1 < 128) or (-(&1) <= 128)
- MOVEQ #&1,D0
- PUSH.L D0
- else
- PUSH.L #&1
- endi
- endi
- endm
-
-
- ADD_M macrox &1
- if (&1 <= 8)
- ADDQ.L #&1,(A6)
- else
- ADDI.L #&1,(A6)
- endi
- endm
-
- SUB_M macrox &1
- if (&1 <= 8)
- SUBQ.L #&1,(A6)
- else
- SUBI.L #&1,(A6)
- endi
- endm
-
-
- ; CONSTANTs - fetches of these are optimized, since we have the value
- ; available.
-
- CONST macrox &1,&2,&3,&4 ; len, name, label, value
- head &1,&2,&3,docon
- h const_h
- &3 dc.l &4
- &3_con equ &4
- endm
-
- NCONST macrox &1,&2 ; Constant with no head
- nohead &1,docon
- h const_h
- &1 dc.l &2
- &1_con equ &2
- endm
-
-
- FCon macrox &1
- if &1_con = 0
- CLR.L -(A6)
- else
- if (&1_con < 128) or (-(&1_con) <= 128)
- MOVEQ #&1_con,D0
- PUSH.L D0
- else
- PUSH.L &1-base(A3)
- endi
- endi
- endm
-
-
- ; VALUEs - these have 3 "methods", fetch, increment, store.
-
- VALU macrox &1,&2,&3,&4 ; len, name, label, value
- head &1,&2,&3,doval
- h val_h
- if "&4" <> ""
- &3 dc.l &4
- else
- &3 dc.l 0
- endi
- endm
-
- NVALU macrox &1,&2 ; Value with no header
- nohead &1,doval
- h val_h
- if "&2" <> ""
- &1 dc.l &2
- else
- &1 dc.l 0
- endi
- endm
-
- FVal macrox &1
- PUSH.L &1-base(A3)
- endm
-
- IncVal macrox &1
- POP.L D0
- ADD.L D0,&1-base(A3)
- endm
-
- ToVal macrox &1
- POP.L &1-base(A3)
- endm
-
- ZVal macrox &1
- CLR.L &1-base(A3)
- endm
-
-
- ; Variables. Note in this assembly we don't automatically allocate
- ; storage for a variable. An explicit byte n or whatever must be
- ; done.
-
- VARBL macrox &1,&2,&3,&4
- head &1,&2,&3,dovbl
- h create_h
- &3
- endm
-
- rVbl macrox &1
- LEA &1,A0
- PUSH.L A0
- endm
-
-
- ; Vectors. These have 3 "methods" - execute, fetch, store.
- ; System vectors have a default value, 4 bytes after the normal value.
- ; The normal value is a relocatable address, but we assume the default
- ; is within the normal dic range, so we use a straight JMP.
- ; Dynamic vectors (new with Mops 2.5) are useful for calling words in a (locked)
- ; module. They have to be set at run time since they use an absolute address.
-
- SVECT macrox &1,&2,&3,&4 ; len, name, label, default value
- head &1,&2,&3,dovect
- h vect_h
- &3 jsr DoExVect-base(a3)
- dc.l 0
- if "&4" <> ""
- bra &4
- else
- bra null
- endi
- endm
-
- DynVECT macrox &1,&2,&3 ; len, name, label
- head &1,&2,&3,doDynVect
- h dynVect_h
- &3 jsr DoExDynVect-base(a3)
- dc.l 0
- endm
-
- NVECT macrox &1 ; Vector with no header and no default
- nohead &1,dovect
- &1 jsr DoExVect-base(a3)
- dc.l 0
- endm
-
-
- ExVect macrox &1
- jsr &1-base(a3)
- endm
-
- SetVect macrox &1,&2
- lea &1,a0
- push.l a0
- lea &2+4-base(a3),a0
- jsr DoToVect-base(A3)
- endm
-
- ClrVect macrox &1
- clr.l &1+4-base(a3)
- endm
-
- ExDynVect macrox &1
- jsr &1-base(a3)
- endm
-
- ; ================
-
- pushop macrox &1
- PUSH.W &1-base(A3)
- CLR.W -(A6)
- endm
-
- compop macrox &1
- pushop &1
- parms wcomma
- endm
-
-
- ; Compyl is the macro equivalent of COMPILE (now replaced by POSTPONE).
- ; It assembles a call to (COMP) which either moves in inline code or calls
- ; the compilation handler for the given word.
-
- compyl macrox &1
- rVbl &1
- bsr doPcomp
- endm
-
-
- NEXT macrox
- rts
- endm
-
- H macrox &1
- dc.w &1
- endm
-
- INL macro &1
- dc.w .xx-*-2
- &1 &1_m
- .xx rts
- endm
-
- USE macrox &1
- &1 &1_m
- rts
- endm
-
-
- TOKEN macrox &1
- if &1_t = inline
- &1_m
- else
- if (&1_t = doval) or (&1_t = doObjPtr)
- FVal &1
- else
- if &1_t = docon
- FCon &1
- else
- if (&1_t = dovbl) or (&1_t = doObj)
- rVbl &1
- else
- if &1_t = dovect
- exVect &1
- else
- BSR &1
- endi
- endi
- endi
- endi
- endi
- endm
-
-
- HCODE macrox &1,&2
- if "&2" <> ""
- dc.w &2
- else
- dc.w &1
- endi
- endm
-
-
- ; CODE is called by HEAD and NOHEAD.
- ; It's easily the most complex macro here, so I'd better give some commentary:
- ; The first if..endi section handles the case where we need a descriptor pushed
- ; at compile-time. This is indicated by the "pushDesc_h" handler code. Then
- ; comes the xinfoMk which tells EXECUTE that this isn't code, then the byte count
- ; of the extra info, which in this case is 2 bytes for the descriptor type & subtype,
- ; and 2 bytes for the "real" handler code.
- ;
- ; Next we get rid of the case where there are no parameters after &1.
- ; Then after that we deal with all the mutually exclusive special cases with
- ; nested if..endi sections.
-
- CODE macrox &1,&2,&3,&4 ; label,flag,opt,alt-hndlr-code
- if "&3" <> ""
- dc.w pushDesc_h
- dc.w xinfoMk
- dc.w 4
- dc.w &3
- endi
-
- if "&2" = ""
- &1_t set docode
- Hcode call_h,&4
- &1
- else
-
- &1_t set &2
-
- if &2 = inline
- inl &1
-
- else
-
- if &2 = doObj
- Hcode obj_h,&4
- dc.w 6
- dc.l nilP_con
- dc.w -6
- &1
- else
-
- if &2 = doObjPtr
- Hcode objPtr_h,&4
- &1 dc.l nilP_con
- dc.l 0
-
- else
-
- if &2 = xinfo
- Hcode call_h,&4
- dc.w xinfoMk
- dc.w &1-*-2
-
- else
-
- if &2 = xinfoN
- Hcode call_h,&4
- dc.w xinfoMk
- dc.w 0
-
- else
-
- if ( &2 = docode ) or ( &2 = spec ) or ( &2 = docol ) or ( &2 = nocode )
- Hcode call_h,&4
- &1
- endi
- endi
- endi
- endi
- endi
- endi
- endi
- endm
-
-
- linkit macrox &1
- if q%1 = 0
- dc.l 0
- else
- dc.l q%1+d-*
- endi
- q%1 set *-d-4
- endm
-
- ; The HEAD macro defines a dictionary header.
- ; The flag field identifies what kind of word this is. If the flag is
- ; "docol", "inline", "spec" or null, it is a word that is called
- ; by a JSR, and we assemble the handler field and linking code here.
- ; If the flag is anything else, we assume that HEAD has been called from
- ; another macro that is looking after everything, so we just assemble the
- ; header.
- ; The opt field is non-zero if this word can begin a sequence where
- ; optimization of the compiled code is zero. The opt field is left in
- ; 2 bytes at the start of the definition; at compile time this field is
- ; left in CompFlg.
-
- HEAD macrox &1,&2,&3,&4,&5,&6 ; len-byte,name,label,flag,opt,alt-hdlr
- align
- loc
- linkit &1 and 7
- dc.b &1 or $80
- text &&2
- align
- code &3,&4,&5,&6
- endm
-
-
- NOHEAD macrox &1,&2,&3,&4 ; label, flag, opt, alt-hdlr
- code &1,&2,&3,&4
- endm
-
-
- COMH macrox &1
- MOVEQ #&1,D0
- PUSH.L D0
- parms wcomma
- endm
-
- CALLH macrox &1
- if "&1" <> ""
- MOVEQ #&1,D0
- endi
- BSR CallHandlers
- endm
-
- JUMPH macrox &1
- if "&1" <> ""
- MOVEQ #&1,D0
- endi
- BRA CallHandlers
- endm
-
-
- NOOPT macrox
- bsr doNoOpt
- endm
-
-
- PARMS macrox &1,&2,&3,&4,&5,&6
- token &1
- IF "&2" <> ""
- token &2
- ENDI
- IF "&3" <> ""
- token &3
- ENDI
- IF "&4" <> ""
- token &4
- ENDI
- IF "&5" <> ""
- token &5
- ENDI
- IF "&6" <> ""
- token &6
- ENDI
- endm
-
-
- BRANCH macrox &1
- BRA.S &1
- endm
-
- QBRANCH macrox &1
- TST.L (A6)+
- BNE.S &1
- endm
-
- ZBRANCH macrox &1
- TST.L (A6)+
- BEQ.S &1
- endm
-
- EQBRANCH macrox &1,&2
- CMPI.L #&1,(A6)+
- BEQ.S &2
- endm
-
- NEBRANCH macrox &1,&2
- CMPI.L #&1,(A6)+
- BNE.S &2
- endm
-
- msg macrox &1
- JSR pdotq-base(a3)
- text #&&1
- align
- endm
-
- abq macrox &1
- JSR pabq
- text #&&1
- align
- endm
-
-
- ; testing *************
- ;
- ;d
- ;
- ;q0 set 0
- ;q1 set 0
- ;q2 set 0
- ;q3 set 0
- ;q4 set 0
- ;q5 set 0
- ;q6 set 0
- ;q7 set 0
- ;
- ; dc.w 123
- ;
- ; head 5,BLOGGS,bloggs
- ; dc.l 9876
- ;
- ; valu 4,HAHA,haha,25
- ;
- ; "Push a descriptor" test
- ;otCMP equ $26
- ;tsGE equ otCMP*256 + $C
- ;setTrue
- ;setFalse
- ;
- ; head 2,>=,ge,docode,tsGE
- ; CMPM.L (A6)+,(A6)+
- ; BGE.S setTrue
- ; BRA.S setFalse
- ;
- ; Push a descriptor with inline
- ;nip_m macrox
- ; POP.L (A6)
- ; endm
- ; head 3,NIP,nip,inline,tsCCOK
- ;
- ; "xinfo" test
- ; head 3,YYY,yyy,xinfo
- ; dc.w 123
- ; dc.w 456
- ;yyy moveq #1,d0
- ; rts
- ;
- ; xinfo with inline
- ;
- ;otADD equ $21
- ;
- ;plus_m macrox
- ; POP.L D0
- ; ADD.L D0,(A6)
- ; endm
- ;
- ; head 1,+,plus,xinfo,,pm_h
- ; dc.w otADD
- ; use plus
- ;
- ;
- ; head 7,LOCPARM,locparm,nocode,,loc_h
- ;
- ;
- ; varbl 7,CONTEXT,context
- ;
- ; dc.l q0+d-*
- ; dc.l q1+d-*
- ; dc.l q2+d-*
- ; dc.l q3+d-*
- ; dc.l q4+d-*
- ; dc.l q5+d-*
- ; dc.l q6+d-*
- ; dc.l q7+d-*
- ;
- ;