.sbttl define macros from IN:K11MAC.MAC .nlist ; include file for kermit-11 ; ; Brian Nelson 01-Dec-83 13:56:12 k11inc = 1 ; the $RWDAT psect MUST be first for RT11 so that the added ; QUEUE words are never mapped by APR1 for the XM exec. .psect $rwdat ,rw,d,gbl,rel,con .psect $code ,ro,i,lcl,rel,con .psect $pdata ,ro,d,lcl,rel,con .psect soh = 1 ; packet start for synch cr = 15 ; a lonely carriage return lf = 12 ; it's normal companion ff = 14 ; sometimes a form feed is nice space = 40 ; don't ask del = 177 ; the RUBOUT esc = 33 ; and at last, escape r0 = %0 r1 = %1 r2 = %2 r3 = %3 r4 = %4 r5 = %5 sp = %6 pc = %7 .macro strcat dst,src mov src ,-(sp) mov dst ,-(sp) jsr pc ,strcat .globl strcat .endm strcat .macro strcmp s1,s2 mov s2 ,-(sp) mov s1 ,-(sp) call strcmp .globl strcmp .endm strcmp .macro strcpy dst,src mov src ,-(sp) mov dst ,-(sp) jsr pc ,strcpy .globl strcpy .endm strcpy .macro textsrc text .if b ,text .ift mov #fgetcr0,getcroutine clr tgetaddr .iff mov #tgetcr0,getcroutine mov text ,tgetaddr .endc .globl getcroutine,tgetaddr,fgetcr0,tgetcr0 .endm textsrc ; The following macro is for RT systems w/o clock. It will loop for ; the .twait, you must insert check as in: ; ; tst clkflg ; does this systems have a clock ; bne 10$ ; yes ; cpuwait #time ; no ; br 20$ ; ; 10$: .twait #rtwork,#timarg ; clock is present with twait support ; 20$: .macro cpuwait ticks ; loop for specified number of ticks mov ticks ,-(sp) ; Adjust the inner loop for timing of clr -(sp) ; 1/60 of a second (one clock tick) mov #13700/2,(sp) ; this inner loop takes 1/60 second dec (sp) ; with a vaule of 13700 (8) on a bne .-2 ; PDP 11/44, try 13700/2 for default. dec 2(sp) ; end of inner loop, now do the outer bne .-14 ; loop cmp (sp)+ ,(sp)+ ; all done .endm cpuwait ; Define IXOR macro to get around the mode restrictions for ; the hardware XOR instruction and to fix for RT11 systems ; that don't have the EIS chip option. .macro indexm reg ; check for auto increment/decrement .ntype $$$0 ,reg ; modes for macro's that can't have .if ne ,$$$0-27 ; always allow pc autoincrement $$$0 = <$$$0 & 177770>/10 ; these modes in their arg list. .ift ; .if ge ,$$$0-2 ; get the mode into 0..7 .ift ; if mode >= 2 and mode <= 5 then error .iif ge ,5-$$$0, .error ; can't use auto inc/dec mode here .endc ; .endc ; .endm indexm ; end of indexm macro .macro ixor reg,dst ; do this for rt11 versions .chksp reg ; can't allow SP args .chksp dst ; can't allow SP args indexm reg ; check for allowed addressing mode indexm dst ; check for allowed addressing mode mov reg ,-(sp) ; it's much simpler to do this bic dst ,@sp ; for all rt systems rather than bic reg ,dst ; to be selective bis (sp)+ ,dst ; all done .endm ixor ; for RT11 xor .macro xor reg,dst ixor reg,dst .endm xor .macro clrpar reg clr -(sp) bisb reg ,@sp call clrpar clr reg bisb (sp)+ ,reg .globl clrpar .endm clrpar .macro setpar src,dst movb src ,-(sp) call dopari movb (sp)+ ,dst global .endm setpar .macro tochar src,dst clr -(sp) bisb src ,@sp add #40 ,@sp movb (sp)+ ,dst .endm tochar .macro unchar src,dst clr -(sp) bisb src ,@sp sub #40 ,@sp movb (sp)+ ,dst .endm unchar .macro ctl src,dst clr -(sp) bisb src ,@sp call l$xor movb (sp)+ ,dst global .endm ctl .macro spack type,pnum,len,msg .if b ,len .ift .iif nb ,msg ,.error ; bad call to SPACK macro calls spack$ , .iff calls spack$ , .endc .globl null .endm spack .macro rpack len.a,pakn.a,msg.a sub #10 ,sp mov sp ,r1 calls rpack$ , mov (r1)+ ,len.a mov (r1)+ ,pakn.a mov @r1 ,r1 add #10 ,sp .endm rpack .macro strlen string mov string ,r0 call l$len global .endm strlen .macro push reg mov reg ,-(sp) .endm push .macro pop reg mov (sp)+ ,reg .endm pop .macro rodata .psect $pdata .endm rodata .macro code .psect $code .endm code .macro direrr val mov val ,-(sp) call direr$ .globl direr$ .endm direrr .macro copyz from,to,maxlen .if b,maxlen .ift clr -(sp) .iff mov maxlen ,-(sp) .endc mov from ,-(sp) mov to ,-(sp) call copyz$ .globl copyz$ .endm copyz .macro message txt,docr .save .psect $pdata $$ = . .if b , .ift .byte 15,12,0 .iff .asciz @txt@ .endc .even .restore mov #$$ ,-(sp) ; dump the text next please call mout ; to the terminal .globl mout ; perhaps .if nb , .ift .iif nb,docr, message .endc .endm message .macro scan ch,str mov str ,-(sp) clr -(sp) bisb ch ,@sp call scanch .globl scanch .endm scan .macro incm64 val save mov val ,r3 inc r3 clr r2 div #100 ,r2 mov r3 ,val unsave .endm incm64 .macro iferr lab tst r0 bne lab .endm iferr .macro .newline ; print crlf on channel 0 (KB:) call l$pcrlf .globl l$pcrlf .endm .newline .macro save list .if b , .ift save .iff .irp x, mov x,-(sp) .endr .endc .endm save .macro unsave list .if b , .ift unsave .iff .irp x, mov (sp)+,x .endr .endc .endm unsave .macro print s,l .print s,l .endm print .macro .print stradr ,strlen .ntype $$6 ,stradr .iif eq, $$6 - 25, .error stradr; can't use (r5)+ in .print .iif eq, $$6 - 45, .error stradr; can't use -(r5) in .print save ; Same as the RT11 .print but .if b ,strlen ; allows an optional length .ift ; to be passed as an argument. clr -(sp) .iff mov strlen ,-(sp) .endc mov stradr ,-(sp) mov sp ,r5 call l$ttyou ; Example: .print r5,#12. .globl l$ttyou add #4 ,sp ; .print #str unsave ; str: .asciz /HELLO/ .endm .print .MACRO GLOBAL LIST .GLOBL LIST .ENDM GLOBAL .MACRO .ASSUME ARG1,COND,ARG2 .IF COND - .IFF .ERROR ARG1 ;"COND ARG2" FAILS .ENDC .ENDM .ASSUME .macro .chksp arg .ntype $$5 ,arg .iif eq,<$$5 & 7>-6, .error arg ; Illegal use of SP(r6) in call .endm .chksp .macro decout val mov r5 ,-(sp) clr -(sp) mov val ,-(sp) mov sp ,r5 call l$wrdec cmp (sp)+ ,(sp)+ mov (sp)+ ,r5 .globl l$wrdec .endm decout .macro octout val calls l$wroct , .endm octout .macro deccvt val,buf,width mov r5 ,-(sp) .if b,width .ift clr -(sp) .iff mov width ,-(sp) .endc mov val ,-(sp) mov buf ,-(sp) mov sp ,r5 call l$cvtnum add #6 ,sp mov (sp)+ ,r5 .globl l$cvtn .endm deccvt ; CALLS macro ; ; subroutine call with arguements passed in an area ; pointed to by R5 (similiar to F4 and BP2). All args ; are pushed onto the stack, with the first args at ; the lower address and the last ones at the higher ; addresses. R5 will point to the SP before the call. ; R5 is saved and restored. .macro calls name,arglst,gbl ; standard call macro using ; the hardware stack (%6) for .if b, gbl .ift .globl name .iff .iif dif, 'gbl ,nogbl, .globl name .iif dif, 'gbl ,NOGBL, .globl name .endc $$ = 0 ; arguement transmission with .irp x , ; r5 passed as a pointer to $$ = $$ + 1 ; to the arguement list. The .endr ; called name is declared globl .if eq ,$$ ; No args present ? If so, gen .ift ; a simple jsr pc call to sub. jsr pc ,name ; No argument list given. .iff push r5 ; At least one arg in .if eq , $$ - 1 ; One arguement in the list .ift mov arglst ,-(sp) ; One arg. Generate less code .chksp arglst ; Check for SP modes on param. mov sp ,r5 ; Set pointer to argument list jsr pc ,name ; call the subroutine tst (sp)+ ; pop parameter list from stack pop r5 ; restore r5 pointer .iff ; argcount > 1 $$2 = $$ ; more than 1 arguement. Thus .rept $$ ; extract the args in reverse $$1 = 0 ; order so that we might save .irp x , ; a little core (4 words). $$1 = $$1 + 1 ; Scan the arg list until we .if eq , $$2 - $$1 ; we come to the last one we .ift ; before the one we just did. .chksp x ; Check for SP addressing mode. mov x ,-(sp) ; Push it, and exit the .irp. .mexit ; exit .endc .endr $$2 = $$2 - 1 ; backwards to previous arg. .endr mov sp ,r5 ; Set up the argument lst ptr. jsr pc ,name ; and go to the routine. .if ne , $$ - 2 ; Gen 'Add 2*argnum, sp' ? .ift ; yes, else gen CMP (sp)+,(sp)+ add #$$*2 ,sp ; fix the stack up, restore r5 .iff cmp (sp)+ ,(sp)+ .endc unsave ; restore r5 pointer .endc .endc .endm calls ; thats all .macro bdump adr,siz mov siz ,-(sp) mov adr ,-(sp) call dump$b global .endm bdump .macro dispat val,dsp,baseval,basedsp,default .save .if nb ,baseval .ift .psect genval ,ro,d,lcl,rel,con baseval: .psect gendsp ,ro,d,lcl,rel,con basedsp: .word default .iff .psect genval ,ro,d,lcl,rel,con .if b ,val .ift .byte 0 .even .iff .byte val .psect gendsp ro,d,lcl,rel,con .word dsp .endc .endc .restore .endm ; offset into local and remote's parameter vectors p.spsiz = 0 ; spsizinelength p.time = 1 ; timeout p.npad = 2 ; number of pad characters p.padc = 3 ; the pad character p.eol = 4 ; eol char p.qctl = 5 ; control chracter quoting p.qbin = 6 ; 8 bit quote p.chkt = 7 ; flavor of checksuming to do p.rept = 10 ; repeated character prefix p.capas = 11 ; capability bitmask p.vend = 17 ; end of parameter vector capa.a = 10 ; bit set for attribute handling log$pa = 1 ; if set in TRACE then log all packets log$fi = 2 ; if set in TRACE then log all files log$co = 4 ; virtual terminal logging to disk log$st = 10 ; state logging log$rp = 20 ; dump each rpack character to local tt log$io = 40 ; dump anything read or sent log$al = log$fi ! log$pa ; all bits possible in TRACE log$al = log$co ! log$st ! log$al ! log$rp ! log$io log$op = 100000 ; the logfile is open now par$od = 1 ; set parity odd par$ev = 2 ; set parity even par$ma = 3 ; set parity mark par$sp = 4 ; set parity space par$no = 5 ; set parity none terminal= -1 ; terminal text = 0 ; normal ascii text files binary = 1 ; image mode ter$cc = 1 ; if set for ttyini then allow ^C ter$xo = 2 ; if ter$bi then set xon/xoff back ter$bi = 4 ; use raw binary mode please ; NOTE: ter$bi overrides ter$cc always ter$pa = 10 con$esc = '\-100 sy$11m = 1 ; for rsx11m sy$ias = 3 ; for ias sy$rsts = 4 ; for rsts sy$vms = 5 ; for vms ame sy$mpl = 6 ; for m+ sy$rt = 7 ; for rt11 sy$pos = 11 sy$pro = 11 ; for p/os ?? tty = 0 ; vt100 = 1 ; vt200 = 2 vtpos = 3 vtprt11 = 4 $rdata = 1 $sdata = 2 .list