; hawk.macs -- standard Hawk definitions and macros ; language: SMAL32 assembly language, intended as an include file ; author: Douglas W. Jones ; date: June 2, 1997 ; revised: Feb. 27, 2002 - replace BCDGET with EX3ADJ instruction ; revised: Mar. 1, 2002 - add SSQADJ ; revised: Mar. 13, 2002 - add BTRUNC ; revised: July 18, 2002 - replace *ADJ with ADJUST, recode B* branches ; revised: July 22, 2002 - add MOVESL, BITTST improve error msgs ; revised: July 25, 2002 - recode Fxxx opcodes, add LOADL, STOREC ; revised: Jan 20, 2005 - delete old SXB,SXH opcodes ; ; example: at the head of a smal 32 source file, include this line: ; | ; | USE "hawk.macs" ; | ; --------------------- ; definitions of register symbols 0 to 15 EXT qREGq ; relocation base for registers, ; defined so that register symbols R0 = qREGq+0 ; cannot be confused with small R1 = qREGq+1 ; integers, thus tightening up the R2 = qREGq+2 ; assembly-time type checking R3 = qREGq+3 ; offered by this macro package R4 = qREGq+4 R5 = qREGq+5 R6 = qREGq+6 R7 = qREGq+7 R8 = qREGq+8 R9 = qREGq+9 RA = qREGq+10 ; hex names RB = qREGq+11 RC = qREGq+12 RD = qREGq+13 RE = qREGq+14 RF = qREGq+15 R10 = qREGq+10 ; decimal names also R11 = qREGq+11 R12 = qREGq+12 R13 = qREGq+13 R14 = qREGq+14 R15 = qREGq+15 ; --------------------- ; definitions of special CPU registers ; each distinct group of special registers has its own relocation ; base so that these symbols become illegal outside of contexts ; where that register group is used EXT qCPUq PSW = qCPUq+0 TPC = qCPUq+1 TMA = qCPUq+2 TSV = qCPUq+3 CYC = qCPUq+8 EXT qADJq BCD = qADJq+2 EX3 = qADJq+3 CMSB = qADJq+4 SSQ = qADJq+5 ; --------------------- ; service macros MACRO ALIGN =x IF x > 1 IF (x & 1) = 1 ERROR odd parameter to ALIGN ELSE ALIGN (x>>1) .=.+(ABS(.)&(x>>1)) ENDIF ENDIF ENDMAC ; --------------------- ; internal macros for common instruction formats MACRO qBOUNDq =x,=min,=max IF (x > max) ERROR x > max out of bounds ELSEIF (x < min) ERROR x < min out of bounds ENDIF ENDMAC MACRO qNZCONSTq =x IF (x = 0) ERROR constant 0 not allowed ENDIF ENDMAC MACRO qNZREGq =x IF (x = R0) ERROR R0 not allowed ENDIF ENDMAC MACRO qMEMREFq =op,=dst,=x,=const IF LEN(const)>0 H op ! (dst-qREGq << 8) ! (x-qREGq) H const ELSE H op ! (dst-qREGq << 8) H x - (.+2) ENDIF ENDMAC MACRO qBRANCHq =op,=const qCONSTq = const - (.+2) >> 1 qBOUNDq qCONSTq,-128,+127 IF qCONSTq = -1 ERROR branch to self not allowed ENDIF H op ! (qCONSTq & #FF) ENDMAC MACRO qONEREGq =op,=dst H op ! (dst-qREGq << 8) ENDMAC MACRO qONE5REGq =op,=dst,=x H op ! (dst-qREGq << 8) ! (x & #F) ENDMAC MACRO qTWOREGq =op,=dst,=x H op ! (dst-qREGq << 8) ! (x-qREGq) ENDMAC MACRO qSPECREGq =op,=dst,=x,=base H op ! (dst-qREGq << 8) ! (x-base) ENDMAC MACRO qTWO5REGq =op,=dst,=s1,=x qBOUNDq x,1,16 H op ! (dst-qREGq << 8) ! (s1-qREGq << 4) ! (x & #F) ENDMAC MACRO qTHREEREGq =op,=dst,=s1,=s2 H op ! (dst-qREGq << 8) ! (s1-qREGq << 4) ! (s2-qREGq) ENDMAC ; --------------------- ; macros for all HAWK opcodes MACRO MOVE =dst,=x qNZREGq dst qTWOREGq #F0F0,dst,x ENDMAC MACRO MOVECC =dst,=x qTWOREGq #F0E0,dst,x ENDMAC MACRO LOADS =dst,=x qNZREGq dst qTWOREGq #F0D0,dst,x ENDMAC MACRO LOADSCC =dst,=x qTWOREGq #F0C0,dst,x ENDMAC MACRO JSRS =dst,=x qTWOREGq #F0B0,dst,x ENDMAC MACRO STORES =dst,=x qNZREGq x qTWOREGq #F0A0,dst,x ENDMAC MACRO LOADL =dst,=x qNZREGq x qTWOREGq #F090,dst,x ENDMAC MACRO STOREC =dst,=x qNZREGq x qTWOREGq #F080,dst,x ENDMAC MACRO LEA =dst,=x,=const qNZREGq dst qMEMREFq #F070,dst,x,const ENDMAC MACRO LEACC =dst,=x,=const qMEMREFq #F060,dst,x,const ENDMAC MACRO LOAD =dst,=x,=const qNZREGq dst qMEMREFq #F050,dst,x,const ENDMAC MACRO LOADCC =dst,=x,=const qMEMREFq #F040,dst,x,const ENDMAC MACRO JSR =dst,=x,=const qMEMREFq #F030,dst,x,const ENDMAC MACRO STORE =dst,=x,=const qMEMREFq #F020,dst,x,const ENDMAC MACRO LIL =dst,=const qNZREGq dst qBOUNDq const,-#800000,#FFFFFF H #E000 ! (dst-qREGq << 8) ! ((const >> 16) & #FF) H const & #FFFF ENDMAC MACRO LIS =dst,=const qNZREGq dst qBOUNDq const,-#80,#FF H #D000 ! (dst-qREGq << 8) ! (const & #FF) ENDMAC MACRO ORIS =dst,=const qNZREGq dst qBOUNDq const,#00,#FF H #C000 ! (dst-qREGq << 8) ! (const & #FF) ENDMAC MACRO MOVESL =dst,=s1,=s2 qNZREGq s1 qTWO5REGq #B000,dst,s1,s2 ENDMAC MACRO ADDSL =dst,=s1,=s2 qNZREGq dst qTWO5REGq #A000,dst,s1,s2 ENDMAC MACRO ADDSR =dst,=s1,=s2 qTWO5REGq #9000,dst,s1,s2 ENDMAC MACRO ADDSRU =dst,=s1,=s2 qTWO5REGq #8000,dst,s1,s2 ENDMAC MACRO STUFFB =dst,=s1,=s2 qNZREGq dst qTHREEREGq #7000,dst,s1,s2 ENDMAC MACRO STUFFH =dst,=s1,=s2 qNZREGq dst qTHREEREGq #6000,dst,s1,s2 ENDMAC MACRO EXTB =dst,=s1,=s2 qNZREGq s1 qTHREEREGq #5000,dst,s1,s2 ENDMAC MACRO EXTH =dst,=s1,=s2 qNZREGq s1 qTHREEREGq #4000,dst,s1,s2 ENDMAC MACRO ADD =dst,=s1,=s2 qNZREGq s1 qNZREGq s2 qTHREEREGq #3000,dst,s1,s2 ENDMAC MACRO SUB =dst,=s1,=s2 qNZREGq s2 qTHREEREGq #2000,dst,s1,s2 ENDMAC MACRO TRUNC =dst,=src qNZREGq dst qBOUNDq src,1,16 qONE5REGq #10F0,dst,src ENDMAC MACRO SXT =dst,=src qNZREGq dst qBOUNDq src,1,16 qONE5REGq #10E0,dst,src ENDMAC MACRO BTRUNC =dst,=src qNZREGq dst qBOUNDq src,1,16 qONE5REGq #10D0,dst,src ENDMAC MACRO ADDSI =dst,=src qNZREGq dst qNZCONSTq src qBOUNDq src,-8,+7 qONE5REGq #10C0,dst,src ENDMAC MACRO AND =dst,=src qNZREGq src qNZREGq dst qTWOREGq #10B0,dst,src ENDMAC MACRO OR =dst,=src qNZREGq src qNZREGq dst qTWOREGq #10A0,dst,src ENDMAC MACRO EQU =dst,=src qNZREGq dst qTWOREGq #1090,dst,src ENDMAC MACRO ADDC =dst,=src qTWOREGq #1070,dst,src ENDMAC MACRO SUBB =dst,=src qTWOREGq #1060,dst,src ENDMAC MACRO ADJUST =dst,=src qNZREGq dst qSPECREGq #1050,dst,src,qADJq ENDMAC MACRO CPUGET =dst,=src qSPECREGq #1010,dst,src,qCPUq ENDMAC MACRO CPUSET =dst,=src qSPECREGq #1000,dst,src,qCPUq ENDMAC MACRO BGTU =const qBRANCHq #0F00,const ENDMAC MACRO BGT =const qBRANCHq #0E00,const ENDMAC MACRO BGE =const qBRANCHq #0D00,const ENDMAC MACRO BCR =const qBRANCHq #0C00,const ENDMAC MACRO BVR =const qBRANCHq #0B00,const ENDMAC MACRO BZR =const qBRANCHq #0A00,const ENDMAC MACRO BNR =const qBRANCHq #0900,const ENDMAC MACRO BLEU =const qBRANCHq #0700,const ENDMAC MACRO BLE =const qBRANCHq #0600,const ENDMAC MACRO BLT =const qBRANCHq #0500,const ENDMAC MACRO BCS =const qBRANCHq #0400,const ENDMAC MACRO BVS =const qBRANCHq #0300,const ENDMAC MACRO BZS =const qBRANCHq #0200,const ENDMAC MACRO BNS =const qBRANCHq #0100,const ENDMAC MACRO BR =const qBRANCHq #0000,const ENDMAC ; --------------------- ; macros for derived instructions MACRO TEST =x,=disp LOADCC R0,x,disp ENDMAC MACRO ADDI =dst,=src,=const IF LEN(const)>0 LEACC dst,src,const ELSE LEACC dst,dst,src ENDIF ENDMAC MACRO CMPI =x,=disp LEACC R0,x,-disp ENDMAC MACRO JUMP =x,=disp IF LEN(disp)>0 JSR R0,x,disp ELSE JSR R0,x ENDIF ENDMAC MACRO TESTS =x LOADSCC R0,x ENDMAC MACRO TESTR =x MOVECC R0,x ENDMAC MACRO JUMPS =x JSRS R0,x ENDMAC MACRO CLR =x LIS x,0 ENDMAC MACRO BNE =x BZR x ENDMAC MACRO BLTU =x BCR x ENDMAC MACRO BEQ =x BZS x ENDMAC MACRO BGEU =x BCS x ENDMAC MACRO NOP =x BR .+2 ENDMAC MACRO SL =dst,=src ADDSL dst,R0,src ENDMAC MACRO SR =dst,=src ADDSR dst,R0,src ENDMAC MACRO SRU =dst,=src ADDSRU dst,R0,src ENDMAC MACRO BITTST =s1,=s2 IF s2<16 ADDSR R0,s1,s2+1 ELSE MOVESL R0,s1,-(s2-32) ENDIF ENDMAC MACRO CMP =s1,=s2 SUB R0,s1,s2 ENDMAC MACRO NEG =dst,=src SUB dst,R0,src ENDMAC MACRO NOT =dst EQU dst,R0 ENDMAC MACRO ROL =dst ADDC dst,dst ENDMAC MACRO RTT =dst CPUGET R0,TPC ENDMAC MACRO LIW =dst, =const LIL dst, const >> 8 ORIS dst, const & #FF ENDMAC