! "W N, R=    @ #D  D ҃TP  B ы e@W 0 ,"& 7   0ߋp@E A Ze      |@7x@ eE "  ɋ -lɋ e-RNHɋ ^?asge/as11.s { Zasge/as12.s  gasge/as13.s  %easge/as14.s  !_asge/as15.s G 'cdasge/as16.s  `+[asge/as17.s  0basge/as18.s  5easge/as19.s I ;86asge/as21.s 3 GT]asge/as22.s  Ndcasge/as23.s  Rbasge/as24.s ? V3dasge/as25.s  YXiasge/as26.s  ZHasge/as27.s A c]asge/as28.s O jfasge/as29.s  flYasge/geops  Mqasge/optab  uasge/run J Jasge/optab2  Yasge/symt.c 9 asge/symt2.c rpucc/procsy2.c D_pucc/procsy.c &LuЌ agen/bflink.c` agen/decode.c< ȭ>agen/ed.c\  9Qagen/encode.c@ agen/linkr5.c agen/linkv5.c" $8[agen/odt11x.m$i )Jagen/odt11x.s$oh .ɕagen/procsy_mir.doc 1ȴjagen/ps.c 4Bagen/spool20.c 6f/ / / interdata 70 assembler pass 0 indir = 0 jmp start go: jsr pc,assem movb pof,r0 sys write; outbuf; 512. movb pof,r0 sys close movb fbfil,r0 sys close tstb errflg bne aexit jsr r5,fcreat; a.tmp3 mov r0,r1 mov symend,0f sub $usymtab,0f sys indir; 9f .data 9: sys write; usymtab; 0:.. .text mov r1,r0 sys close sys exec; 2f; 1f mov $2f,r0 jsr r5,filerr; "?\n aexit: sys exit sys unlink; a.tmp1 sys unlink; a.tmp2 sys unlink; a.tmp3 sys exit .data 1: 2f a.tmp1 a.tmp2 a.tmp3 unglob: 3f 0 .text 2: fpass2: 3: <-g\0> .even filerr: mov r4,-(sp) mov r0,r4 mov r4,0f clr r0 1: tstb (r4)+ beq 1f inc r0 br 1b 1: mov r0,1f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 1:0 .text mov r5,0f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 2 .text tst (r5)+ mov (sp)+,r4 rts r5 fcreat: mov r4,-(sp) mov (r5)+,r4 mov r4,0f 1: sys indir; 9f .data 9: sys stat; 0:..; outbuf .text bec 2f mov r4,0f sys indir; 9f .data 9: sys creat; 0:..; 444 .text bes 2f mov (sp)+,r4 rts r5 2: incb 9.(r4) cmpb 9.(r4),$'z blos 1b mov r4,r0 jsr r5,filerr; "?\n sys exit 1: tstb (r4)+ beq 1f inc r0 br 1b 1: mov r0,1f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 1:0 .text mov r5,0f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 2 .text tst (r5)+ mov (sp)+,r4 rts r5 fcreat: mov r4,-(sp) mov (r5)+,r4 mov r4,0f 1: sys indir; 9f .data 9: sys stat; 0:..; outbuf .text bec 2f mov r4,0f sys indir; 9f .data 9: sys creat; 0:..; 44/ / / a2 -- interdata 70 assembler pass 1 error: incb errflg mov r0,-(sp) mov r1,-(sp) mov (r5)+,r0 tst *curarg beq 1f mov r0,-(sp) mov *curarg,r0 clr *curarg jsr r5,filerr; '\n mov (sp)+,r0 1: mov r2,-(sp) mov r3,-(sp) mov line,r3 movb r0,1f mov $1f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 1f; 7 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rts r5 .data 1: .even .text betwen: cmp r0,(r5)+ blt 1f cmp (r5)+,r0 blt 2f 1: tst (r5)+ 2: rts r5 putw: tst ifflg beq 1f cmp r4,$'\n bne 2f 1: mov r4,*obufp add $2,obufp cmp obufp,$outbuf+512. blo 2f mov $outbuf,obufp movb pof,r0 sys write; outbuf; 512. 2: rts pc ) mov line,r3 movb r0,1f mov $1f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 1f; 7 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rts r5 .data 1: .even .text betwen: cmp r0,(r5)+ b/ / / a3 -- interdata assembler pass 1 assem: jsr pc,readop jsr pc,checkeos br ealoop tst ifflg beq 3f cmp r4,$200 blos assem cmpb (r4),$21 /if bne 2f inc ifflg 2: cmpb (r4),$22 /endif bne assem dec ifflg br assem 3: mov r4,-(sp) jsr pc,readop cmp r4,$'= beq 4f cmp r4,$': beq 1f mov r4,savop mov (sp)+,r4 jsr pc,opline br ealoop 1: mov (sp)+,r4 cmp r4,$200 bhis 1f cmp r4,$1 / digit beq 3f jsr r5,error; 'x br assem 1: bitb $37,(r4) beq 1f jsr r5,error; 'm 1: bisb dot-2,(r4) mov dot,2(r4) br assem 3: mov numval,r0 jsr pc,fbcheck movb dotrel,curfbr(r0) asl r0 movb dotrel,nxtfb mov dot,nxtfb+2 movb r0,nxtfb+1 mov dot,curfb(r0) movb fbfil,r0 sys write; nxtfb; 4 br assem 4: jsr pc,readop jsr pc,expres mov (sp)+,r1 cmp r1,$200 bhis 1f jsr r5,error; 'x br ealoop 1: cmp r1,$dotrel bne 2f bic $40,r3 cmp r3,dotrel bne 1f 2: bicb $37,(r1) bic $!37,r3 bne 2f clr r2 2: bisb r3,(r1) mov r2,2(r1) br ealoop 1: jsr r5,error; '. movb $2,dotrel ealoop: cmp r4,$'; beq assem1 cmp r4,$'\n bne 1f inc line br assem1 1: cmp r4,$'\e bne 2f tst ifflg beq 1f jsr r5,error; 'x 1: rts pc 2: jsr r5,error; 'x 2: jsr pc,checkeos br assem1 jsr pc,readop br 2b assem1: jmp assem fbcheck: cmp r0,$9. bhi 1f rts pc 1: jsr r5,error; 'f clr r0 rts pc checkeos: cmp r4,$'\n beq 1f cmp r4,$'; beq 1f cmp r4,$'\e beq 1f add $2,(sp) 1: rts pc ,r3 bne 2f clr r2 2: bisb r3,(r1) mov r2,2(r1) br ealoop 1: jsr r5,error; '. movb $2,dotrel ealoop: cm/ / / a4 -- interdata assembler pass 1 rname: mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov $8,r5 mov $symbol+8.,r2 clr -(r2) clr -(r2) clr -(r2) clr -(r2) clr -(sp) clr -(sp) cmp r0,$'~ / symbol not for hash table bne 1f inc 2(sp) clr ch 1: jsr pc,rch movb chartab(r0),r3 ble 1f add r3,(sp) swab (sp) dec r5 blt 1b movb r3,(r2)+ br 1b 1: movb r0,ch mov (sp)+,r1 clr r0 tst (sp)+ beq 1f mov symend,r4 br 4f 1: div $hshsiz,r0 ashc $1,r0 add $hshtab,r1 1: sub r0,r1 cmp r1,$hshtab bhi 2f add $2*hshsiz,r1 2: mov $symbol,r2 mov -(r1),r4 beq 3f cmp (r2)+,(r4)+ bne 1b cmp (r2)+,(r4)+ bne 1b cmp (r2)+,(r4)+ bne 1b cmp (r2)+,(r4)+ bne 1b br 1f 3: mov symend,r4 mov r4,(r1) 4: mov $symbol,r2 mov r4,-(sp) add $20,r4 cmp r4,0f blos 4f add $512.,0f sys indir; 9f .data 9: sys break; 0:end .text 4: mov (sp)+,r4 mov (r2)+,(r4)+ mov (r2)+,(r4)+ mov (r2)+,(r4)+ mov (r2)+,(r4)+ clr (r4)+ clr (r4)+ mov r4,symend sub $4,r4 1: mov r4,-(sp) mov r4,r3 sub $8,r3 cmp r3,$usymtab blo 1f sub $usymtab,r3 clr r2 div $3,r2 mov r2,r4 add $4000,r4 / user symbol br 2f 1: sub $symtab,r3 clr r2 div $3,r2 mov r2,r4 add $1000,r4 / builtin symbol 2: jsr pc,putw mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 tst (sp)+ rts pc number: mov r2,-(sp) mov r3,-(sp) mov r5,-(sp) clr r1 clr r5 1: jsr pc,rch jsr r5,betwen; '0; '9 br 1f sub $'0,r0 mpy $10.,r5 add r0,r5 als $3,r1 add r0,r1 br 1b 1: cmp r0,$'b beq 1f cmp r0,$'f beq 1f cmp r0,$'. bne 2f mov r5,r1 clr r0 2: movb r0,ch mov r1,r0 mov (sp)+,r5 mov (sp)+,r3 mov (sp)+,r2 rts pc 1: mov r0,r3 mov r5,r0 jsr pc,fbcheck add $141,r0 cmp r3,$'b beq 1f add $10.,r0 1: mov r0,r4 mov (sp)+,r5 mov (sp)+,r3 mov (sp)+,r2 add $2,(sp) rts pc hnum: /hex number (dca) mov r2,-(sp) mov r3,-(sp) mov r5,-(sp) clr r1 1: jsr pc,rch jsr r5,betwen; '0; '9 br 1f sub $'0,r0 2: als $4,r1 add r0,r1 br 1b 1: jsr r5,betwen; 'a; 'f br 1f sub $'a-10.,r0 br 2b 1: movb r0,ch mov r1,r0 mov (sp)+,r5 mov (sp)+,r3 mov (sp)+,r2 rts pc rch: movb ch,r0 beq 1f clrb ch rts pc 1: dec inbfcnt blt 2f movb *inbfp,r0 inc inbfp bic $!177,r0 beq 1b rts pc 2: movb fin,r0 beq 3f sys read; inbuf;512. bcs 2f tst r0 beq 2f mov r0,inbfcnt mov $inbuf,inbfp br 1b 2: movb fin,r0 clrb fin sys close 3: decb nargs bgt 2f mov $'\e,r0 rts pc 2: tst ifflg beq 2f jsr r5,error; 'i jmp aexit 2: mov curarg,r0 tst (r0)+ mov (r0),0f mov r0,curarg incb fileflg sys indir; 9f .data 9: sys open; 0:0; 0 .text bec 2f mov 0b,r0 jsr r5,filerr; jmp aexit 2: movb r0,fin mov $1,line mov r4,-(sp) mov r1,-(sp) mov $5,r4 jsr pc,putw mov *curarg,r1 2: movb (r1)+,r4 beq 2f jsr pc,putw br 2b 2: mov $-1,r4 jsr pc,putw mov (sp)+,r1 mov (sp)+,r4 br 1b 2: movb fin,r0 clrb fin sys close 3: decb nargs bgt 2f mov $'\e,r0 rts pc 2: tst ifflg beq 2f jsr r5,error; 'i jmp aexit 2: mov curarg,r0 tst (r0)+ mov (r0),0f mov r0,curarg incb fileflg sys indir; 9f .data 9:/ / / a5 -- interdata 70 assembler pass 1 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,8f jsr pc,putw rts pc 8: jsr pc,rch _readop: mov r0,r4 movb chartab(r0),r1 bgt rdname jmp *1f-2(r1) hexnum fixor escp 8b retread dquote garb squote rdname skip rdnum retread string 1: escp: jsr pc,rch mov $esctab,r1 1: cmpb r0,(r1)+ beq 1f tstb (r1)+ bne 1b rts pc 1: movb (r1),r4 rts pc esctab: .byte '/, '/ .byte '\<, 035 .byte '>, 036 .byte '%, 037 .byte 0, 0 fixor: mov $037,r4 retread: rts pc rdname: movb r0,ch cmp r1,$'0 blo 1f cmp r1,$'9 blos rdnum 1: jmp rname hexnum: jsr pc,hnum br 1f rdnum: jsr pc,number br 1f rts pc squote: jsr pc,rsch br 1f dquote: jsr pc,rsch mov r0,-(sp) jsr pc,rsch swab r0 bis (sp)+,r0 1: mov r0,numval mov $1,r4 jsr pc,putw mov numval,r4 jsr pc,putw mov $1,r4 tst (sp)+ rts pc skip: jsr pc,rch mov r0,r4 cmp r0,$'\e beq 1f cmp r0,$'\n bne skip 1: rts pc garb: jsr r5,error; 'g br 8b string: mov $'<,r4 jsr pc,putw clr numval 1: jsr pc,rsch tst r1 bne 1f mov r0,r4 bis $400,r4 jsr pc,putw inc numval br 1b 1: mov $-1,r4 jsr pc,putw mov $'<,r4 tst (sp)+ rts pc rsch: jsr pc,rch cmp r0,$'\e beq 4f cmp r0,$'\n beq 4f clr r1 cmp r0,$'\\ bne 3f jsr pc,rch mov $schar,r2 1: cmpb (r2)+,r0 beq 2f tstb (r2)+ bpl 1b rts pc 2: movb (r2)+,r0 clr r1 rts pc 3: cmp r0,$'> bne 1f inc r1 1: rts pc 4: jsr r5,error; '< jmp aexit schar: .byte 'n, 012 .byte 't, 011 .byte 'e, 004 .byte '0, 000 .byte 'r, 015 .byte 'a, 006 .byte 'p, 033 .byte 0, -1 bis $400,r4 jsr pc,putw inc numval br 1b 1: mov $-1,r4 jsr pc,putw mov $'<,r4 tst (sp)+ rts pc rsch: jsr pc,rch cmp r0,$'\e beq 4f cmp r0,$'\n beq 4f clr r1 cmp r0,$'\\ bne 3f jsr pc,rch mov $schar,r2 1: cmpb (r2)+,r0 beq 2f tstb (r2)+ bpl 1b rts pc 2: movb (r2)+,r0 clr r1 rts pc 3: cmp r0,$'> bne 1f inc r1 1: rts pc 4: jsr r5,error; '< jmp aexit schar: .byte 'n, 012 .byte 't, 011 .byte 'e, 004 .by/ / / a6 -- interdata 70 assembler pass 1 / modified 5/4/77,dca- opl32 from errort opline: mov r4,r0 jsr r5,betwen; 0; 200 br 1f cmp r0,$'< bne xpr jmp opl17 xpr: jsr pc,expres add $2,dot rts pc 1: movb (r4),r0 cmp r0,$24 beq xpr jsr r5,betwen; 5; 36 br xpr mov r0,-(sp) jsr pc,readop mov (sp)+,r0 asl r0 jmp *1f-12(r0) 1: opl6 /map sf to rr opl6 opl7 opl10 opl11 opl12 errort errort errort opl16 opl17 opl20 opl21 opl22 opl23 xpr opl25 opl26 opl27 errort errort opl32 / *** fix from errort xpr xpr errort opl36 / btc, bfc opl12: jsr pc,expres cmp r4,$', jne oplea jsr pc,readop / branches opl36: mov $4,-(sp) jsr pc,expres cmp r4,$'( bne 0f / must be long branch a(x) jsr pc,getx br 1f 0: cmp r3,$24 /check reg beq 2f cmp r3,dotrel bne 1f sub dot,r2 bge 1f cmp r2,$-30. blt 1f 2: mov $2,(sp) 1: add (sp)+,dot rts pc opl7: jsr pc,expres cmp r4,$', beq 1f oplea: jsr pc,errora rts pc 1: jsr pc,readop opl10: opl11: / a(x) jsr pc,addres add $4,dot rts pc opl6: / sf,rr jsr pc,expres cmp r4,$', beq 1f jsr pc,errora 1: jsr pc,readop jsr pc,expres add $2,dot rts pc / .byte opl16: jsr pc,expres inc dot cmp r4,$', bne 1f jsr pc,readop br opl16 1: rts pc / < (.ascii) opl17: add numval,dot jsr pc,readop rts pc /.even opl20: inc dot bic $1,dot rts pc /.if opl21: jsr pc,expres tst r3 bne 1f jsr r5,error; 'U 1: tst r2 bne opl22 inc ifflg opl22: /endif rts pc /.globl opl23: cmp r4,$200 blo 1f bisb $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop br opl23 1: rts pc opl25: opl26: opl27: mov dotrel,r1 asl r1 mov dot,savdot-4(r1) mov savdot-[2*25](r0),dot asr r0 sub $25-2,r0 mov r0,dotrel rts pc / .common opl32: cmp r4,$200 blo 1f bis $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop jsr pc,expres rts pc 1: jsr r5,error; 'x rts pc addres: jsr pc,expres cmp r4,$'( bne 0f getx: jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp 0: rts pc errora: jsr r5,error; 'a rts pc errort: jsr r5,error; 't rts pc checkreg: cmp r2,$15. bhi 1f cmp r3,$1 beq 2f cmp r3,$4 bhi 2f 1: jsr pc,errora 2: rts pc errore: jsr r5,error; 'e rts pc checkrp: cmp r4,$') beq 1f jsr r5,error; ') rts pc 1: jsr pc,readop rts pc jsr pc,readop cmp r4,$', bne 1f jsr pc,readop jsr pc,expres rts pc 1: jsr r5,error; 'x rts pc addres: jsr pc,expres cmp r4,$'( bne 0f getx: jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp 0: rts pc errora: jsr r5,error; 'a rts p/ / / a7 -- interdata assembler pass 1 expres: mov r5,-(sp) mov $'+,-(sp) clr opfound clr r2 mov $1,r3 br 1f advanc: jsr pc,readop 1: mov r4,r0 jsr r5,betwen; 0; 177 br .+4 br 7f movb (r4),r0 mov 2(r4),r1 br oprand 7: cmp r4,$141 blo 1f cmp r4,$141+10. bhis 2f movb curfbr-141(r4),r0 asl r4 mov curfb-[2*141](r4),r2 bpl oprand jsr r5,error; 'f br oprand 2: clr r3 clr r2 br oprand 1: mov $esw1,r1 1: cmp (r1)+,r4 beq 1f tst (r1)+ bne 1b tst opfound bne 2f jsr pc,errore 2: tst (sp)+ mov (sp)+,r5 rts pc 1: jmp *(r1) esw1: '+; binop '-; binop '*; binop '/; binop '&; binop 037; binop 035; binop 036; binop '%; binop '[; brack '^; binop 1; exnum '!; binop 0; 0 binop: cmpb (sp),$'+ beq 1f jsr pc,errore 1: movb r4,(sp) br advanc exnum: mov numval,r1 mov $1,r0 br oprand brack: mov r2,-(sp) mov r3,-(sp) jsr pc,readop jsr pc,expres cmp r4,$'] beq 1f jsr r5,error; '] 1: mov r3,r0 mov r2,r1 mov (sp)+,r3 mov (sp)+,r2 oprand: inc opfound mov $exsw2,r5 1: cmp (sp),(r5)+ beq 1f tst (r5)+ bne 1b br eoprnd 1: jmp *(r5) exsw2: '+; exadd '-; exsub '*; exmul '/; exdiv 037; exor '&; exand 035;exlsh 036;exrsh '%; exmod '!; exnot '^; excmbin 0; 0 excmbin: mov r0,r3 / give left flag of right br eoprnd exrsh: neg r1 beq exlsh inc r1 clc ror r2 exlsh: jsr r5,combin; 0 als r1,r2 br eoprnd exmod: jsr r5,combin; 0 mov r1,-(sp) mov r2,r1 clr r0 dvd (sp)+,r0 mov r1,r2 br eoprnd exadd: jsr r5,combin; 0 add r1,r2 br eoprnd exsub: jsr r5,combin; 1 sub r1,r2 br eoprnd exand: jsr r5,combin; 0 com r1 bic r1,r2 br eoprnd exor: jsr r5,combin; 0 bis r1,r2 br eoprnd exmul: jsr r5,combin; 0 mpy r2,r1 mov r1,r2 br eoprnd exdiv: jsr r5,combin; 0 mov r1,-(sp) mov r2,r1 clr r0 dvd (sp)+,r0 mov r0,r2 br eoprnd exnot: jsr r5,combin; 0 com r1 add r1,r2 br eoprnd eoprnd: mov $'+,(sp) jmp advanc combin: mov r0,-(sp) bis r3,(sp) bic $!40,(sp) bic $!37,r0 bic $!37,r3 cmp r0,r3 ble 1f mov r0,-(sp) mov r3,r0 mov (sp)+,r3 1: tst r0 beq 1f tst (r5)+ beq 2f cmp r0,r3 bne 2f mov $1,r3 br 2f 1: tst (r5)+ clr r3 2: bis (sp)+,r3 rts r5 r eoprnd exmul: jsr r5,combin; 0 mpy r2,r1 mov r1,r2 br eoprnd exdiv: jsr r5,combin; 0 mov r1,-(sp) mov r2,r1 clr r0 dvd (sp)+,r0 mov r0,r2 br eoprnd exnot: jsr r5,combin; 0 com r1 add r1,r2 br eoprnd eoprnd: mov $'+,(sp) jmp advanc combin: mov r0,-(sp) bis r3,(sp) bic $!40,(sp) bic $!37,r0 bic $!37,r3 cmp r0,r3 ble 1f mov r0,-(sp) mov r/ / / a8 -- interdata assembler pass 1 chartab: .byte -14,-14,-14,-14,-02,-14,-14,-14 .byte -14,-22, -2,-14,-14,-22,-14,-14 .byte -14,-14,-14,-14,-14,-14,-14,-14 .byte -14,-14,-14,-14,-14,-14,-14,-14 .byte -22,-20,-16,-14,-20,-20,-20,-12 .byte -20,-20,-20,-20,-20,-20,056,-06 .byte 060,061,062,063,064,065,066,067 .byte 070,071,-20,-02,-00,-20,-14,-14 .byte -14,101,102,103,104,105,106,107 .byte 110,111,112,113,114,115,116,117 .byte 120,121,122,123,124,125,126,127 .byte -30,131,132,-20,-24,-20,-20,137 .byte -14,141,142,143,144,145,146,147 .byte 150,151,152,153,154,155,156,157 .byte 160,161,162,163,164,165,166,167 .byte 170,171,172,-14,-26,-14,176,-14 .data namedone:.byte 0 a.tmp1: a.tmp2: a.tmp3: .even curfb: -1;-1;-1;-1;-1;-1;-1;-1;-1;-1 obufp: outbuf symend: usymtab .bss curfbr: .=.+10. savdot: .=.+6 bufcnt: .=.+2 hshsiz = 1553. hshtab: .=2*hshsiz+. pof: .=.+1 wordf: .=.+1 fin: .=.+1 fbfil: .=.+1 fileflg:.=.+1 errflg: .=.+1 ch: .=.+1 .even symbol: .=.+8. obufc: .=.+2 outbuf: .=.+512. line: .=.+2 inbfcnt:.=.+2 ifflg: .=.+2 inbfp: .=.+2 nargs: .=.+2 curarg: .=.+2 opfound:.=.+2 savop: .=.+2 numval: .=.+2 nxtfb: .=.+4 usymtab:.=.+36. end: .text tm1a\0> a.tmp2: a.tmp3: .even curfb: -1;-1;-1;-1;-1;-1;-1;-1;-1;-1 obufp: outbuf symend: usymtab .bss curfbr: .=.+10. savdot: .=.+6 bufcnt: .=.+2 hshsiz = 1553. hshtab: .=2*hshsiz+. pof: .=.+1 wordf: .=.+1 fin: .=.+1 fbfil: .=.+1 fileflg:.=.+1 errflg: .=.+1 ch: .=.+1 .even sym/ / / a9 -- interdata assembler pass 1 / key to types / 0 undefined / 1 absolute / 2 text / 3 data / 4 bss / 5 sf / 6 rr / 7 rx and rs / 10 a(x) / 11 sys / 12 btc, bfc / 13 error / 14 error / 15 error / 16 .byte / 17 string (.ascii, "<") / 20 .even / 21 .if / 22 .endif / 23 .globl / 24 register / 25 .text / 26 .data / 27 .bss / 30 error / 31 error / 32 .comm / 33 estimated text / 34 estimated data / 35 error / 36 branches .data symtab: / special variables <.\0\0\0\0\0\0\0> ; dotrel: 02; dot: 0 <..\0\0\0\0\0\0> ; 01; dotdot: 0 / registers ; 24; 0 ; 24; 1 ; 24; 2 ; 24; 3 ; 24; 4 ; 24; 5 ; 24; 6 ; 24; 7 ; 24; 10 ; 24; 11 ; 24; 12 ; 24; 13 ; 24; 14 ; 24; 15 ; 24; 16 ; 24; 17 / system calls ; 1; 1 ; 1; 2 ; 1; 3 ; 1; 4 ; 1; 5 ; 1; 6 ; 1; 7 ; 1; 10 ; 1; 11 ; 1; 12 ; 1; 13 ; 1; 14 ; 1; 15 ; 1; 16 ; 1; 17 ; 1; 20 ; 1; 21 ; 1; 22 ; 1; 23 ; 1; 24 ; 1; 25 ; 1; 26 ; 1; 27 ; 1; 30 ; 1; 31 ; 1; 32 ; 1; 33 ; 1; 34 ; 1; 35 ; 1; 36 ; 1; 37 / short (SF) and register (RR) ; 5; 23000 ; 5; 22400 ; 5; 22000 ; 5; 23400 ; 5; 110400 ; 5; 110000 ; 5; 20000 ; 5; 20400 ; 5; 21000 ; 5; 21400 ; 6; 25000 ; 6; 117400 ; 6; 5000 ; 6; 7000 ; 6; 400 ; 6; 1400 ; 6; 1000 ; 6; 24400 ; 6; 4400 ; 6; 2400 ; 6; 26400 ; 6; 6400 ; 6; 112000 ; 6; 112400 ; 6; 111400 ; 6; 24000 ; 6; 4000 ; 6; 26000 ; 6; 6000 ; 6; 116000 ; 6; 117000 ; 6; 3000 ; 6; 113400 ; 6; 115400 ; 6; 114400 ; 6; 25400 ; 6; 116400 ; 6; 111000 ; 6; 5400 ; 6; 7400 ; 6; 113000 ; 6; 115000 ; 6; 114000 ; 6; 3400 ; 6; 2000 / RX and RS ; 7; 157400 ; 7; 45000 ; 7; 145000 ; 7; 60400 ; 7; 62400 ; 7; 62000 ; 7; 47000 ; 7; 42000 ; 7; 142000 ; 7; 40400 ; 12; 41400 ; 12; 41000 ; 7; 140000 ; 7; 140400 ; 7; 167400 ; 7; 40000 ; 7; 154000 ; 7; 63000 ; 7; 146000 ; 7; 156400 ; 7; 151000 ; 7; 155000 ; 7; 44400 ; 7; 144400 ; 7; 152000 ; 7; 42400 ; 7; 142400 ; 7; 166400 ; 7; 150000 ; 7; 46400 ; 7; 43400 ; 7; 43400 ; 7; 65000 ; 7; 64400 ; 7; 147400 ; 7; 45400 ; 7; 66400 ; 7; 64000 ; 7; 66000 ; 7; 60000 ; 7; 65400 ; 7; 146400 ; 7; 145400 ; 7; 151400 ; 7; 151400 ; 7; 144000 ; 7; 150400 ; 7; 46000 ; 7; 167000 ; 7; 47400 ; 7; 156000 ; 7; 43000 ; 7; 143000 ; 7; 157000 ; 7; 153400 ; 7; 166000 ; 7; 160400 ; 7; 155400 ; 7; 154400 ; 7; 165400 ; 7; 165000 ; 7; 63400 ; 7; 147000 ; 7; 141400 ; 7; 153000 / a(x) field only ; 10; 141000 ; 10; 161000 ; 10; 152400 / sys ; 11; 160400 /svc 0,?? / branches -- a(x) opcode given ; 36; 41400 ; 36; 41060 ; 36; 41460 ; 36; 41420 ; 36; 41020 ; 36; 41040 ; 36; 41440 ; 36; 41420 ; 36; 41020 ; 36; 41660 ; 36; 41500 ; 36; 41100 ; 36; 41600 ; 36; 41600 ; 36; 41200 ; 36; 41200 <.byte\0\0\0> ; 16; 0 <.even\0\0\0> ; 20; 0 <.if\0\0\0\0\0> ; 21; 0 <.endif\0\0> ; 22; 0 <.globl\0\0> ; 23; 0 <.text\0\0\0> ; 25; 0 <.data\0\0\0> ; 26; 0 <.bss\0\0\0\0> ; 27; 0 <.comm\0\0\0> ; 32; 0 ebsymtab: start: sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; aexit 1: mov sp,r5 mov (r5)+,r0 cmpb *2(r5),$'- bne 1f tst (r5)+ dec r0 br 2f 1: clr unglob 2: movb r0,nargs mov r5,curarg jsr r5,fcreat; a.tmp1 movb r0,pof jsr r5,fcreat; a.tmp2 movb r0,fbfil jsr pc,setup jmp go setup: mov $symtab,r1 1: clr r3 mov $8,r2 mov r1,-(sp) 2: movb (r1)+,r4 beq 2f add r4,r3 swab r3 sob r2,2b 2: clr r2 div $hshsiz,r2 ashc $1,r2 add $hshtab,r3 4: sub r2,r3 cmp r3,$hshtab bhi 3f add $2*hshsiz,r3 3: tst -(r3) bne 4b mov (sp)+,r1 mov r1,(r3) add $12.,r1 cmp r1,$ebsymtab blo 1b rts pc /overlay buffer inbuf = setup . =inbuf+512. clr unglob 2: movb r0,nargs mov r5,curarg jsr r5,fcreat; a.tmp1 movb r0,pof jsr r5,fcreat; a.tmp2 movb r0,fbfil jsr pc,setup jmp go setup: mov $symtab,r1 1: clr r3 mov $/ / / a21 -- interdata assembler pass 2 indir = 0 main: sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; aexit 1: jmp start / set up sizes and origins go: / read in symbol table mov $usymtab,r1 1: jsr pc,getw bvs 1f add $14,symsiz / count symbols jsr pc,getw jsr pc,getw jsr pc,getw jsr pc,getw mov r4,r0 bic $!37,r0 cmp r0,$2 /text blo 2f cmp r0,$3 /data bhi 2f add $31,r4 /mark "estimated" mov r4,(r1)+ jsr pc,getw mov r4,(r1)+ br 3f 2: clr (r1)+ clr (r1)+ jsr pc,getw 3: jsr pc,setbrk br 1b 1: / read in f-b definitions mov r1,fbbufp movb fbfil,fin clr ibufc 1: jsr pc,getw bvs 1f add $31,r4 / "estimated" mov r4,(r1)+ jsr pc,getw mov r4,(r1)+ jsr pc,setbrk br 1b 1: mov r1,endtable mov $100000,(r1)+ / set up input text file; initialize f-b table jsr pc,setup / do pass 1 jsr pc,assem / prepare for pass 2 cmp outmod,$777 beq 1f jmp aexit 1: clr dot mov $2,dotrel mov $..,dotdot clr brtabp movb fin,r0 sys close jsr r5,ofile; a.tmp1 movb r0,fin clr ibufc jsr pc,setup inc passno inc bsssiz bic $1,bsssiz mov txtsiz,r1 inc r1 bic $1,r1 mov r1,txtsiz mov datsiz,r2 inc r2 bic $1,r2 mov r2,datsiz mov r1,r3 mov r3,datbase / txtsiz mov r3,savdot+2 add r2,r3 mov r3,bssbase / txtsiz+datsiz mov r3,savdot+4 asl r3 add $20,r3 mov r3,symseek / 2*txtsiz+2*datsiz+20 sub r2,r3 mov r3,drelseek / 2*txtsiz+datsiz sub r1,r3 mov r3,trelseek / txtsiz+datsiz+20 sub r2,r3 mov r3,datseek / txtsiz+20 mov $usymtab,r1 1: jsr pc,doreloc add $4,r1 cmp r1,endtable blo 1b clr r0 jsr r5,oset; txtp mov trelseek,r0 jsr r5,oset; relp mov $8.,r2 mov $txtmagic,r1 1: mov (r1)+,r0 jsr r5,putw; txtp dec r2 bne 1b jsr pc,assem /polish off text and relocation jsr r5,flush; txtp jsr r5,flush; relp / append full symbol table mov symf,r0 mov r0,fin sys seek; 0; 0; clr ibufc mov symseek,r0 jsr r5,oset; txtp mov $usymtab,r1 1: jsr pc,getw bvs 1f mov r4,r0 jsr r5,putw; txtp jsr pc,getw mov r4,r0 jsr r5,putw; txtp jsr pc,getw mov r4,r0 jsr r5,putw; txtp jsr pc,getw mov r4,r0 jsr r5,putw; txtp mov (r1)+,r0 jsr r5,putw; txtp mov (r1)+,r0 jsr r5,putw; txtp jsr pc,getw jsr pc,getw br 1b 1: jsr r5,flush; txtp jmp aexit .data aexit: mov a.tmp1,0f sys unlink; 0:.. mov a.tmp2,0f sys unlink; 0:.. mov a.tmp3,0f sys unlink; 0:.. sys chmod; a.out; outmod: 777 sys exit .text filerr: mov *(r5),r5 1: movb (r5)+,ch beq 1f mov $1,r0 sys write; ch; 1 br 1b 1: mov $1,r0 sys write; qnl; 2 jmp aexit doreloc: movb (r1),r0 bne 1f bisb defund,(r1) 1: bic $!37,r0 cmp r0,$5 bhis 1f cmp r0,$3 blo 1f beq 2f add bssbase,2(r1) rts pc 2: add datbase,2(r1) 1: rts pc setbrk: mov r1,-(sp) add $20,r1 cmp r1,0f blo 1f add $512.,0f sys indir; 9f .data 9: sys break; 0: end .text 1: mov (sp)+,r1 rts pc setup: mov $curfb,r4 1: clr (r4)+ cmp r4,$curfb+40. blo 1b movb txtfil,fin clr ibufc clr r4 1: jsr pc,fbadv tstb (r4)+ cmp r4,$10. blt 1b rts pc ofile: mov *(r5),0f sys indir; 9f .data 9: sys open; 0:..; 0 .text bes 1f tst (r5)+ rts r5 1: jmp filerr bhis 1f cmp r0,$3 blo 1f beq 2f add bssbase,2(r1) rts pc 2: add datbase,2(r1) 1: rts pc setbrk: mov r1,-(sp) add $20,r1 cmp r1,0f blo 1f add $512.,0f sys indir; 9f .data 9: sys break; 0: end .text 1: mov (sp)+,r1 rts pc setup: mov $curfb,r4 1: clr (r4)+ cmp r4,$curfb+40. blo 1b movb txtfil,fin clr ibufc clr r4 1: jsr pc,fbadv tstb (r4)+ cmp r4,$10. blt 1b rts pc ofile: mov *(r5),0f sys indir; 9f .data 9: sys open; 0:..; / / / a2 -- interdata assembler pass 2 outw: cmp dot-2,$4 beq 9f bit $1,dot bne 1f add $2,dot tstb passno beq 8f cmp r3,$40 bne 2f / external references mov $666,outmod / make nonexecutable mov xsymbol,r3 sub $usymtab,r3 asl r3 bis $4,r3 / external relocation br 3f 2: bic $40,r3 / clear any ext bits cmp r3,$5 blo 4f cmp r3,$33 / est. text, data beq 6f cmp r3,$34 bne 7f 6: jsr r5,error; 'r 7: mov $1,r3 / make absolute 4: cmp r3,$2 blo 5f cmp r3,$4 bhi 5f add dotdot,r2 br 4f 5: 4: dec r3 bpl 3f clr r3 3: asl r3 mov r2,r0 jsr r5,putw; txtp add $2,*tseekp mov r3,r0 jsr r5,putw; relp add $2,*rseekp 8: rts pc 1: jsr r5,error; 'o clr r3 jsr pc,outb rts pc 9: jsr r5,error; 'x rts pc outb: cmp dot-2,$4 / test bss mode beq 9b cmp r3,$1 blos 1f jsr r5,error; 'r 1: tstb passno beq 2f mov r2,r0 bit $1,dot bne 1f swab r0 jsr r5,putw; txtp clr r0 jsr r5,putw; relp add $2,*rseekp add $2,*tseekp br 2f 1: mov txtp,r0 movb r2,-2(r0) 2: inc dot rts pc error: mov $666,outmod / make nonexecutable mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) mov $argb,r1 1: movb (r1),ch beq 1f clrb (r1)+ mov $1,r0 sys write; ch; 1 br 1b 1: mov (r5)+,r0 movb r0,0f mov line,r3 mov $0f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 0f; 7 mov (sp)+,r0 mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 rts r5 .data 0: .even .text betwen: cmp r0,(r5)+ blt 1f cmp (r5)+,r0 blt 2f 1: tst (r5)+ 2: rts r5 / make nonexecutable mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) mov $argb,r1 1: movb (r1),ch beq 1f clrb (r1)+ mov $1,r0 sys write; ch; 1 br 1b 1: mov (r5)+,r0 movb r0,0f mov line,r3 mov $0f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 0f; 7 mov (sp)+,r0 mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 rts r5 .data 0: .even .text betwen: cmp r0,(r5)+ blt 1f cmp (r5)+,r0 blt 2f / / / a4 -- interdata assembler pass 2 assem: jsr pc,readop cmp r4,$5 beq 2f cmp r4,$'< beq 2f jsr pc,checkeos br eal1 mov r4,-(sp) cmp (sp),$1 bne 1f mov $2,(sp) jsr pc,getw mov r4,numval 1: jsr pc,readop cmp r4,$'= beq 4f cmp r4,$': beq 1f mov r4,savop mov (sp)+,r4 2: jsr pc,opline dotmax: tstb passno bne eal1 movb dotrel,r0 asl r0 cmp dot,txtsiz-4(r0) blos ealoop mov dot,txtsiz-4(r0) eal1: jmp ealoop 1: mov (sp)+,r4 cmp r4,$200 bhis 1f cmp r4,$2 beq 3f jsr r5,error; 'x br assem 1: tstb passno bne 2f movb (r4),r0 bic $!37,r0 beq 5f cmp r0,$33 blt 6f cmp r0,$34 ble 5f 6: jsr r5,error; 'm 5: bic $37,(r4) bis dotrel,(r4) mov 2(r4),brdelt sub dot,brdelt mov dot,2(r4) br assem 2: cmp dot,2(r4) beq assem jsr r5,error; 'p br assem 3: mov numval,r4 jsr pc,fbadv asl r4 mov curfb(r4),r0 movb dotrel,(r0) mov 2(r0),brdelt sub dot,brdelt mov dot,2(r0) br assem 4: jsr pc,readop jsr pc,expres mov (sp)+,r1 cmp r1,$symtab /test for dot bne 1f bic $40,r3 cmp r3,dotrel / can't change relocation bne 2f cmp r3,$4 / bss bne 3f mov r2,dot br dotmax 3: sub dot,r2 bmi 2f mov r2,-(sp) 3: dec (sp) bmi 3f clr r2 mov $1,r3 jsr pc,outb br 3b 3: tst (sp)+ br dotmax 2: jsr r5,error; '. br ealoop 1: cmp r3,$40 bne 1f jsr r5,error; 'r 1: bic $37,(r1) bic $!37,r3 bne 1f clr r2 1: bisb r3,(r1) mov r2,2(r1) ealoop: cmp r4,$'\n beq 1f cmp r4,$'\e bne 9f rts pc 1: inc line 9: jmp assem checkeos: cmp r4,$'\n beq 1f cmp r4,$'; beq 1f cmp r4,$'\e beq 1f add $2,(sp) 1: rts pc fbadv: asl r4 mov nxtfb(r4),r1 mov r1,curfb(r4) bne 1f mov fbbufp,r1 br 2f 1: add $4,r1 2: cmpb 1(r1),r4 beq 1f tst (r1) bpl 1b 1: mov r1,nxtfb(r4) asr r4 rts pc 2: jsr r5,error; '. br ealoop 1: cmp r3,$40 bne 1f jsr r5,error; 'r 1: bic $37,(r1) bic $!37,r3 bne 1f clr r2 1: bisb r3,(r1) mov r2,2(r1) ealoop: cmp r4,$'\n beq 1f cmp r4,$'\e bne 9f rts pc 1: inc line 9: jmp assem checkeos: cmp r4,$'\n beq 1f cmp r4,$'; beq 1f / / / a4 -- interdata assembler pass 2 oset: mov r2,-(sp) mov (r5)+,r1 mov r0,r2 bic $!777,r0 add r1,r0 add $6,r0 mov r0,(r1)+ / next slot mov r1,r0 add $1004,r0 mov r0,(r1)+ / buf max mov r2,(r1)+ / seek addr mov (sp)+,r2 rts r5 putw: mov r1,-(sp) mov r2,-(sp) mov (r5)+,r2 mov (r2)+,r1 / slot cmp r1,(r2) / buf max bhis 1f mov r0,(r1)+ mov r1,-(r2) br 2f 1: tst (r2)+ mov r0,-(sp) jsr r5,flush1 mov (sp)+,r0 mov r0,*(r2)+ add $2,-(r2) 2: mov (sp)+,r2 mov (sp)+,r1 rts r5 flush: mov (r5)+,r2 cmp (r2)+,(r2)+ flush1: mov (r2)+,r1 mov r1,0f / seek address mov fout,r0 sys indir; 9f .data 9: sys seek; 0:..; 0 .text bic $!777,r1 add r2,r1 / write address mov r1,0f mov r2,r0 bis $777,-(r2) inc (r2) / new seek addr cmp -(r2),-(r2) sub (r2),r1 neg r1 mov r1,0f+2 / count mov r0,(r2) / new next slot mov fout,r0 sys indir; 9f .data 9: sys write; 0:..; .. .text rts r5 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,getw1 cmp r4,$200 blo 1f cmp r4,$4000 blo 2f add $usymtab-4000,r4 rts pc 2: add $symtab-1000,r4 1: rts pc getw: mov savop,r4 beq getw1 clr savop rts pc getw1: dec ibufc bgt 1f movb fin,r0 sys read; inbuf; 512. bes 3f asr r0 mov r0,ibufc bne 2f 3: mov $4,r4 sev rts pc 2: mov $inbuf,ibufp 1: mov *ibufp,r4 add $2,ibufp rts pc r0,(r2) / new next slot mov fout,r0 sys indir; 9f .data 9: sys write; 0:..; .. .text rts r5 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,getw1 cmp r4,$200 blo 1f cmp r4/ / / as25 is empty usymtab-4000,r4 rts pc 2: add $symtab-1000,r4 1: rts pc getw: mov savop,r4 beq getw1 clr savop rts pc getw1: dec ibufc bgt 1f movb fin,r0 sys read; inbuf; 512. bes 3f asr r0 mov r0,ibufc bne 2f 3: mov $4,r4 sev rts pc 2: mov $inbuf,ibufp 1: mov *ibufp,r4 add $2,ibufp rts pc r0,(r2) / new next slot mov fout,r0 sys indir; 9f .data 9: sys write; 0:..; .. .text rts r5 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,getw1 cmp r4,$200 blo 1f cmp r4/ / / a6 -- interdata assembler pass 2 opline: mov r4,r0 jsr r5,betwen; 0; 177 br 2f cmp r4,$5 beq opeof cmp r4,$'< bne xpr jmp opl17 xxpr: tst (sp)+ xpr: jsr pc,expres jsr pc,outw rts pc 2: movb (r4),r0 cmp r0,$24 /reg beq xpr cmp r0,$33 /est text beq xpr cmp r0,$34 / est data beq xpr jsr r5,betwen; 5; 36 br xpr mov 2(r4),-(sp) mov r0,-(sp) jsr pc,readop mov (sp)+,r0 asl r0 mov $adrbuf,r5 jmp *1f-10.(r0) 1: opl5 opl6 opl7 opl10 opl11 opl12 opl13 opl14 opl15 opl16 opl17 opl20 opl21 opl22 opl23 xxpr opl25 opl26 opl27 opl30 opl31 opl32 xxpr xxpr opl35 opl36 opeof: mov $1,line mov $20,-(sp) mov $argb,r1 1: jsr pc,getw tst r4 bmi 1f movb r4,(r1)+ dec (sp) bgt 1b tstb -(r1) br 1b 1: movb $'\n,(r1)+ clrb (r1)+ tst (sp)+ rts pc opl5: opl6: /sf and rr jsr pc,getr1 jsr pc,expres jsr pc,checkreg opls: bis (sp)+,r2 clr r3 jsr pc,outw rts pc getr1: jsr pc,expres jsr pc,checkreg ash $4,r2 bis r2,2(sp) jsr pc,readop rts pc opl7: /rx,rs jsr pc,getr1 opl10: / a(x) jsr pc,expres oplx: mov r2,(r5)+ mov r3,(r5)+ mov xsymbol,(r5)+ clr r2 cmp r4,$'( bne oplxx jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp oplxx: bis (sp)+,r2 clr r3 jsr pc,outw mov adrbuf,r2 mov adrbuf+2,r3 mov adrbuf+4,xsymbol jsr pc,outw rts pc opl11: / sys jsr pc,expres cmp r3,$2 blt 1f cmp r3,$5 bhi 1f jsr pc,checkreg 1: br opls opl13: opl14: opl15: opl30: opl31: opl35: jsr r5,error; 't rts pc opl12: jsr pc,getr1 opl36: /branches jsr pc,expres cmp r4,$'( jeq oplx cmp r3,$24 jeq oplbr / long-short stuff tstb passno bne 1f mov r2,r0 jsr pc,setbr cmp (sp)+,(r2)+ add r2,dot rts pc / pass 2 1: jsr pc,getbr bcs oplx cmp r3,dot-2 jne oplx sub dot,r2 bit $1,r2 beq 1f jsr r5,error; 'b 1: sub $8192.,(sp) / 2000 hex asr r2 bmi 1f / forward short cmp (sp),$8960. / 2300 hex jhis opls 2: sub $256.,(sp) jbr opls / bw short 1: neg r2 cmp (sp),$8960. bhis 2b bic $512.,(sp) jbr opls / reg branches oplbr: sub $16384.,(sp) jbr opls / .byte opl16: jsr pc,expres jsr pc,outb cmp r4,$', bne 1f jsr pc,readop br opl16 1: tst (sp)+ rts pc / < (.ascii) opl17: jsr pc,getw mov $1,r3 mov r4,r2 bmi 2f bic $!377,r2 jsr pc,outb br opl17 2: jsr pc,getw rts pc /.even opl20: bit $1,dot beq 1f cmp dot-2,$4 beq 2f / bss mode clr r2 clr r3 jsr pc,outb br 1f 2: inc dot 1: tst (sp)+ rts pc opl21: /if jsr pc,expres opl22: oplret: tst (sp)+ rts pc /.globl opl23: cmp r4,$200 blo 1f bisb $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop br opl23 1: tst (sp)+ rts pc / .text, .data, .bss opl25: opl26: opl27: inc dot bic $1,dot mov r0,-(sp) mov dot-2,r1 asl r1 mov dot,savdot-4(r1) tstb passno beq 1f jsr r5,flush; txtp jsr r5,flush; relp mov (sp),r2 add $txtseek-[2*25],r2 mov r2,tseekp mov (r2),r0 jsr r5,oset; txtp add $trelseek-txtseek,r2 mov (r2),r0 mov r2,rseekp jsr r5,oset; relp 1: mov (sp)+,r0 mov savdot-[2*25](r0),dot asr r0 sub $25-2,r0 mov r0,dot-2 / new . relocation tst (sp)+ rts pc opl32: cmp r4,$200 blo 1f mov r4,-(sp) jsr pc,readop jsr pc,readop jsr pc,expres mov (sp)+,r0 bit $37,(r0) bne 1f bis $40,(r0) mov r2,2(r0) 1: tst (sp)+ rts pc getx: jsr pc,expres mov r2,(r5)+ mov r3,(r5)+ mov xsymbol,(r5)+ cmp r4,$'( bne 2f jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp rts pc 2: clr r2 mov $24,r3 rts pc errora: jsr r5,error; 'a rts pc checkreg: cmp r2,$15. bhi 1f cmp r3,$1 blos 2f cmp r3,$5 blo 1f 2: rts pc 1: jsr pc,errora clr r2 clr r3 rts pc errore: jsr r5,error; 'e rts pc checkrp: cmp r4,$') beq 1f jsr r5,error; ') rts pc 1: jsr pc,readop rts pc setbr: mov brtabp,r1 cmp r1,$brlen blt 1f mov $2,r2 rts pc 1: inc brtabp clr -(sp) sub dot,r0 ble 1f sub brdelt,r0 1: jsr r5,betwen; -30.; 30. br 1f br 2f 1: mov r1,-(sp) bic $!7,(sp) mov $1,r0 ash (sp)+,r0 ash $-3,r1 bisb r0,brtab(r1) mov $2,(sp) 2: mov (sp)+,r2 rts pc getbr: mov brtabp,r1 cmp r1,$brlen blt 1f sec rts pc 1: mov r1,-(sp) bic $!7,(sp) neg (sp) inc brtabp ash $-3,r1 movb brtab(r1),r1 ash (sp)+,r1 ror r1 / 0-bit into c-bit rts pc : jsr pc,readop rts pc setbr: mov brtabp,r1 cmp r1,$brlen blt 1f mov $2,r2 rts pc 1: inc brtabp clr -(sp) sub dot,r0 ble 1f sub brdelt,r0 1: jsr r5,betwen; -30.; 30. br 1f br 2f 1: mov r1,-(sp) bic $!7,(sp) mov $1,r0 ash (sp)+,r0 ash $-3,r1 bisb r0,brtab(r1) mov $2,(sp) 2: mov (sp)+,r2 rts pc getbr: mov brtabp,r1 cmp r1,$brlen blt 1f sec rts pc 1: m/ / / a7 -- interdata assembler pass 2 expres: clr xsymbol expres1: mov r5,-(sp) mov $'+,-(sp) clr r2 mov $1,r3 br 1f advanc: jsr pc,readop 1: mov r4,r0 jsr r5,betwen; 0; 177 br .+4 br 7f movb (r4),r0 tst r0 bne 1f tstb passno beq 1f jsr r5,error; 'u 1: cmp r0,$40 bne 1f mov r4,xsymbol clr r1 br oprand 1: mov 2(r4),r1 br oprand 7: cmp r4,$141 blo 1f asl r4 mov curfb-[2*141](r4),r0 mov 2(r0),r1 movb (r0),r0 br oprand 1: mov $esw1,r1 1: cmp (r1)+,r4 beq 1f tst (r1)+ bne 1b tst (sp)+ mov (sp)+,r5 rts pc 1: jmp *(r1) esw1: '+; binop '-; binop '*; binop '/; binop '&; binop 037; binop 035; binop 036; binop '%; binop '[; brack '^; binop 1; exnum 2; exnum1 '!; binop 200; 0 binop: cmpb (sp),$'+ beq 1f jsr pc,errore 1: movb r4,(sp) br advanc exnum1: mov numval,r1 br 1f exnum: jsr pc,getw mov r4,r1 1: mov $1,r0 br oprand brack: mov r2,-(sp) mov r3,-(sp) jsr pc,readop jsr pc,expres1 cmp r4,$'] beq 1f jsr r5,error; '] 1: mov r3,r0 mov r2,r1 mov (sp)+,r3 mov (sp)+,r2 oprand: mov $exsw2,r5 1: cmp (sp),(r5)+ beq 1f tst (r5)+ bne 1b br eoprnd 1: jmp *(r5) exsw2: '+; exadd '-; exsub '*; exmul '/; exdiv 037; exor '&; exand 035;exlsh 036;exrsh '%; exmod '^; excmbin '!; exnot 200; 0 excmbin: mov r0,r3 br eoprnd exrsh: neg r1 beq exlsh inc r1 clc ror r2 exlsh: jsr r5,combin; relte2 als r1,r2 br eoprnd exmod: jsr r5,combin; relte2 mov r3,r0 mov r2,r3 clr r2 dvd r1,r2 mov r3,r2 mov r0,r3 br eoprnd exadd: jsr r5,combin; reltp2 add r1,r2 br eoprnd exsub: jsr r5,combin; reltm2 sub r1,r2 br eoprnd exand: jsr r5,combin; relte2 com r1 bic r1,r2 br eoprnd exor: jsr r5,combin; relte2 bis r1,r2 br eoprnd exmul: jsr r5,combin; relte2 mpy r2,r1 mov r1,r2 br eoprnd exdiv: jsr r5,combin; relte2 mov r3,r0 mov r2,r3 clr r2 dvd r1,r2 mov r0,r3 br eoprnd exnot: jsr r5,combin; relte2 com r1 add r1,r2 br eoprnd eoprnd: mov $'+,(sp) jmp advanc combin: tstb passno bne combin1 mov r0,-(sp) bis r3,(sp) bic $!40,(sp) bic $!37,r0 bic $!37,r3 cmp r0,r3 ble 1f mov r0,-(sp) mov r3,r0 mov (sp)+,r3 1: tst r0 beq 1f cmp (r5)+,$reltm2 bne 2f cmp r0,r3 bne 2f mov $1,r3 br 2f 1: tst (r5)+ clr r3 2: bis (sp)+,r3 rts r5 combin1: mov r1,-(sp) clr maxtyp jsr pc,maprel mov r0,r1 mpy $6,r1 mov r3,r0 jsr pc,maprel add (r5)+,r0 add r1,r0 movb (r0),r3 bpl 1f cmp r3,$-1 beq 2f jsr r5,error; 'r 2: mov maxtyp,r3 1: mov (sp)+,r1 rts r5 maprel: cmp r0,$40 bne 1f mov $5,r0 rts pc 1: bic $!37,r0 cmp r0,maxtyp blos 1f mov r0,maxtyp 1: cmp r0,$5 blos 1f mov $1,r0 1: rts pc X = -2 M = -1 reltp2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, 2, X, X, X, X .byte 0, 3, X, X, X, X .byte 0, 4, X, X, X, X .byte 0,40, X, X, X, X reltm2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, X, 1, X, X, X .byte 0, X, X, 1, X, X .byte 0, X, X, X, 1, X .byte 0, X, X, X, X, X relte2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, X, X, X, X .byte 0, X, X, X, X, X .byte 0, X, X, X, X, X .byte 0, X, X, X, X, X .byte 0, X, X, X, X, X r0,$5 blos 1f mov $1,r0 1: rts pc X = -2 M = -1 reltp2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, 2, X, X, X, X .byte 0, 3, X, X, X, X .byte 0, 4, X, X, X, X .byte 0,40, X, X, X, X reltm2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, X, 1, X, X, X .byte 0, X, X, 1, X, X .byte 0, X, X, X, 1, X .byte 0, X, X, X, X, X relte2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, X, X, X, X .byte 0, X, X, X, X, X .byte 0/ / / as8 -- interdata 70 assembler pass 2 qnl: a.out: .even a.outp: a.out .data a.tmp1: 0 a.tmp2: 0 a.tmp3: 0 tseekp: txtseek rseekp: trelseek txtmagic: br .+20 txtsiz: .=.+2 datsiz: .=.+2 bsssiz: .=.+2 symsiz: .=.+2 stksiz: .=.+2 exorig: .=.+2 .=.+2 txtseek: 20 datseek:.=.+2 .=.+2 trelseek:.=.+2 drelseek:.=.+2 .=.+2 symseek:.=.+2 .bss brlen = 1024. brtab: .=.+[brlen\/8.] brtabp: .=.+2 brdelt: .=.+2 fbbufp: .=.+2 defund: .=.+2 savdot: .=.+6 datbase:.=.+2 bssbase:.=.+2 fbfil: .=.+2 fin: .=.+2 ibufc: .=.+2 txtfil: .=.+2 symf: .=.+2 adrbuf: .=.+12. xsymbol:.=.+2 fout: .=.+2 ch: .=.+2 wordf: .=.+2 argb: .=.+22. line: .=.+2 savop: .=.+2 curfb: .=.+20. nxtfb: .=.+20. numval: .=.+2 maxtyp: .=.+2 relfil: .=.+2 ibufp: .=.+2 txtp: .=.+6+512. relp: .=.+6+512. passno: .=.+2 endtable:.=.+2 usymtab:.=.+20. end: .text .=.+2 .=.+2 symseek:.=.+2 .bss brlen = 1024. brtab: .=.+[brlen\/8.] brtabp: .=.+2 brdelt: .=.+2 fbbufp: .=.+2 defund: .=.+2 savdot: .=.+6 datbase:.=.+2 bssbase:.=.+2 fbfil: ./ / / as9 -- interdata assembler pass 2 .data symtab: / special variables dotrel: 02; dot: 0 01; dotdot: 0 24; 0 24; 1 24; 2 24; 3 24; 4 24; 5 24; 6 24; 7 24; 10 24; 11 24; 12 24; 13 24; 14 24; 15 24; 16 24; 17 1; 1 1; 2 1; 3 1; 4 1; 5 1; 6 1; 7 1; 10 1; 11 1; 12 1; 13 1; 14 1; 15 1; 16 1; 17 1; 20 1; 21 1; 22 1; 23 1; 24 1; 25 1; 26 1; 27 1; 30 1; 31 1; 32 1; 33 1; 34 1; 35 1; 36 1; 37 5; 23000 5; 22400 5; 22000 5; 23400 5; 110400 5; 110000 5; 20000 5; 20400 5; 21000 5; 21400 6; 25000 6; 117400 6; 5000 6; 7000 6; 400 6; 1400 6; 1000 6; 24400 6; 4400 6; 2400 6; 26400 6; 6400 6; 112000 6; 112400 6; 111400 6; 24000 6; 4000 6; 26000 6; 6000 6; 116000 6; 117000 6; 3000 6; 113400 6; 115400 6; 114400 6; 25400 6; 116400 6; 111000 6; 5400 6; 7400 6; 113000 6; 115000 6; 114000 6; 3400 6; 2000 7; 157400 7; 45000 7; 145000 7; 60400 7; 62400 7; 62000 7; 47000 7; 42000 7; 142000 7; 40400 12; 41400 12; 41000 7; 140000 7; 140400 7; 167400 7; 40000 7; 154000 7; 63000 7; 146000 7; 156400 7; 151000 7; 155000 7; 44400 7; 144400 7; 152000 7; 42400 7; 142400 7; 166400 7; 150000 7; 46400 7; 43400 7; 43400 7; 65000 7; 64400 7; 147400 7; 45400 7; 66400 7; 64000 7; 66000 7; 60000 7; 65400 7; 146400 7; 145400 7; 151400 7; 44000 7; 144000 7; 150400 7; 46000 7; 167000 7; 47400 7; 156000 7; 43000 7; 143000 7; 157000 7; 153400 7; 166000 7; 160400 7; 155400 7; 154400 7; 165400 7; 165000 7; 63400 7; 147000 7; 141400 7; 153000 10; 141000 10; 161000 10; 152400 11; 160400 36; 41400 36; 41060 36; 41460 36; 41420 36; 41020 36; 41040 36; 41440 36; 41420 36; 41020 36; 41660 36; 41500 36; 41100 36; 41600 36; 41600 36; 41200 36; 41200 16; 0 20; 0 21; 0 22; 0 23; 0 25; 0 26; 0 27; 0 32; 0 start: cmp (sp),$4 bge 1f jmp aexit 1: cmp (sp)+,$5 blt 1f mov $40,defund / globalize all undefineds 1: tst (sp)+ mov (sp)+,a.tmp1 mov (sp)+,a.tmp2 mov (sp)+,a.tmp3 jsr r5,ofile; a.tmp1 movb r0,txtfil jsr r5,ofile; a.tmp2 movb r0,fbfil jsr r5,ofile; a.tmp3 movb r0,symf movb r0,fin sys creat; a.out; 0 bec 1f jsr r5,filerr; a.outp 1: movb r0,fout jmp go / overlaid buffer inbuf = start . = inbuf+512. 36; 41200 36; 41200 16; 0 20; 0 21; 0 22; 0 23; 0 25; 0 26; 0 27; 0 32; 0 start: cmp (sp),$4 bge 1f jmp aexit 1: cmp (sp)+,$5 blt 1f mov $40,defund / globalize all undefineds 1: tst (sp)+ mov (sp)+,a.tmp1 mov (sp)+,a.tmp2 mov (sp)+,a.tmp3 .; 2; 0 ..;1;0 r0;24;0 r1;24;1 r2;24;2 r3;24;3 r4;24;4 r5;24;5 r6;24;6 r7;24;7 r8;24;8 r9;24;9 ra;24;a rb;24;b rc;24;c rd;24;d re;24;e rf;24;f exit;1;1 fork;1;2 read;1;3 write;1;4 open;1;5 close;1;6 wait;1;7 creat;1;8 link;1;9 unlink;1;a exec;1;b chdir;1;c time;1;d makdir;1;e chmod;1;f chown;1;10 break;1;11 stat;1;12 seek;1;13 tell;1;14 mount;1;15 umount;1;16 setuid;1;17 getuid;1;18 stime;1;19 fstat;1;1a mdate;1;1b stty;1;1c gtty;1;1d nice;1;1e signal;1;1f ais;5;2600 lcs;5;2500 lis;5;2400 sis;5;2700 slls;5;9100 srls;5;9000 btbs;5;2000 btfs;5;2100 bfbs;5;2200 bffs;5;2300 aer;6;2a00 air;6;9f00 ahr;6;0a00 achr;6;0e00 balr;6;0100 bfcr;6;0300 btcr;6;0200 cer;6;2900 chr;6;0900 clhr;6;0500 der;6;2d00 dhr;6;0d00 exbr;6;9400 epsr;6;9500 lbr;6;9300 ler;6;2800 lhr;6;0800 mer;6;2c00 mhr;6;0c00 mhur;6;9c00 ocr;6;9e00 ohr;6;0600 rbr;6;9700 rdr;6;9b00 rhr;6;9900 ser;6;2b00 ssr;6;9d00 stbr;6;9200 shr;6;0b00 schr;6;0f00 wbr;6;9600 wdr;6;9a00 whr;6;9800 xhr;6;0700 nhr;6;0400 ai;7;df00 ah;7;4a00 ahi;7;ca00 ahm;7;6100 abl;7;6500 atl;7;6400 ach;7;4e00 nh;7;4400 nhi;7;c400 bal;7;4100 bfc;7;4300 btc;7;4200 bxh;7;c000 bxle;7;c100 sla;7;ef00 sth;7;4000 wh;7;d800 rtl;7;6600 srhl;7;cc00 ss;7;dd00 stb;7;d200 wd;7;da00 ch;7;4900 chi;7;c900 clb;7;d400 clh;7;4500 clhi;7;c500 sll;7;ed00 stm;7;d000 dh;7;4d00 xh;7;4700 xhi;7;4700 ae;7;6a00 ce;7;6900 slha;7;cf00 sh;7;4b00 de;7;6d00 le;7;6800 me;7;6c00 ste;7;6000 se;7;6b00 slhl;7;cd00 shi;7;cb00 lb;7;d300 lh;7;d300 lh;7;4800 lhi;7;c800 lm;7;d100 mh;7;4c00 sra;7;ee00 sch;7;4f00 mhu;7;dc00 oh;7;4600 ohi;7;c600 oc;7;de00 rb;7;d700 srl;7;ec00 svc;7;e100 rd;7;db00 rh;7;d900 rll;7;eb00 rrl;7;ea00 rbl;7;6700 srha;7;ce00 thi;7;c300 lpsw;10;c200 sint;10;e200 al;10;d500 sys;11;e100 b;36;4300 bne;36;4230 beq;36;4330 bge;36;4310 blt;36;4210 bgt;36;4220 ble;36;4320 bpl;36;4310 bmi;36;4210 bhi;36;43b0 bvc;36;4340 bvs;36;4240 bhis;36;4380 bcc;36;4380 bcs;36;4280 blo;36;4280 .byte;16;0 .even;20;0 .if;21;0 .endif;22;0 .globl;23;0 .text;25;0 .data;26;0 .bss;27;0 .comm;32;0 0 sra;7;ee00 sch;7;4f00 mhu;7;dc00 oh;7;460<.\0\0\0\0\0\0\0> ; dotrel: 02; dot: 0 <..\0\0\0\0\0\0> ; 01; dotdot: 0 / registers ; 24; 0 ; 24; 1 ; 24; 2 ; 24; 3 ; 24; 4 ; 24; 5 ; 24; 6 ; 24; 7 ; 24; 10 ; 24; 11 ; 24; 12 ; 24; 13 ; 24; 14 ; 24; 15 ; 24; 16 ; 24; 17 / system calls ; 1; 1 ; 1; 2 ; 1; 3 ; 1; 4 ; 1; 5 ; 1; 6 ; 1; 7 ; 1; 10 ; 1; 11 ; 1; 12 ; 1; 13 ; 1; 14 ; 1; 15 ; 1; 16 ; 1; 17 ; 1; 20 ; 1; 21 ; 1; 22 ; 1; 23 ; 1; 24 ; 1; 25 ; 1; 26 ; 1; 27 ; 1; 30 ; 1; 31 ; 1; 32 ; 1; 33 ; 1; 34 ; 1; 35 ; 1; 36 ; 1; 37 / short (SF) and register (RR) ; 5; 23000 ; 5; 22400 ; 5; 22000 ; 5; 23400 ; 5; 110400 ; 5; 110000 ; 5; 20000 ; 5; 20400 ; 5; 21000 ; 5; 21400 ; 6; 25000 ; 6; 117400 ; 6; 5000 ; 6; 7000 ; 6; 400 ; 6; 1400 ; 6; 1000 ; 6; 24400 ; 6; 4400 ; 6; 2400 ; 6; 26400 ; 6; 6400 ; 6; 112000 ; 6; 112400 ; 6; 111400 ; 6; 24000 ; 6; 4000 ; 6; 26000 ; 6; 6000 ; 6; 116000 ; 6; 117000 ; 6; 3000 ; 6; 113400 ; 6; 115400 ; 6; 114400 ; 6; 25400 ; 6; 116400 ; 6; 111000 ; 6; 5400 ; 6; 7400 ; 6; 113000 ; 6; 115000 ; 6; 114000 ; 6; 3400 ; 6; 2000 / RX and RS ; 7; 157400 ; 7; 45000 ; 7; 145000 ; 7; 60400 ; 7; 62400 ; 7; 62000 ; 7; 47000 ; 7; 42000 ; 7; 142000 ; 7; 40400 ; 7; 41400 ; 7; 41000 ; 7; 140000 ; 7; 140400 ; 7; 167400 ; 7; 40000 ; 7; 154000 ; 7; 63000 ; 7; 146000 ; 7; 156400 ; 7; 151000 ; 7; 155000 ; 7; 44400 ; 7; 144400 ; 7; 152000 ; 7; 42400 ; 7; 142400 ; 7; 166400 ; 7; 150000 ; 7; 46400 ; 7; 43400 ; 7; 43400 ; 7; 65000 ; 7; 64400 ; 7; 147400 ; 7; 45400 ; 7; 66400 ; 7; 64000 ; 7; 66000 ; 7; 60000 ; 7; 65400 ; 7; 146400 ; 7; 145400 ; 7; 151400 ; 7; 151400 ; 7; 44000 ; 7; 144000 ; 7; 150400 ; 7; 46000 ; 7; 167000 ; 7; 47400 ; 7; 156000 ; 7; 43000 ; 7; 143000 ; 7; 157000 ; 7; 153400 ; 7; 166000 ; 7; 160400 ; 7; 155400 ; 7; 154400 ; 7; 165400 ; 7; 165000 ; 7; 63400 ; 7; 147000 ; 7; 141400 / a(x) field only ; 10; 141000 ; 10; 161000 ; 10; 152400 / branches ; 36; 41400 ; 36; 41060 ; 36; 41460 ; 36; 41420 ; 36; 41020 ; 36; 41040 ; 36; 41440 ; 36; 41420 ; 36; 41020 ; 36; 41660 ; 36; 41500 ; 36; 41100 ; 36; 41600 ; 36; 41600 ; 36; 41200 ; 36; 41200 <.byte\0\0\0> ; 16; 0 <.even\0\0\0> ; 20; 0 <.if\0\0\0\0\0> ; 21; 0 <.endif\0\0> ; 22; 0 <.globl\0\0> ; 23; 0 <.text\0\0\0> ; 25; 0 <.data\0\0\0> ; 26; 0 <.bss\0\0\0\0> ; 27; 0 <.comm\0\0\0> ; 32; 0 ; 36; 41020 ; 36; 41660 ; 36; 41500 ; 36; 41100 ; 36; 41600 ; 36; 41600 ; 36; 41200 ; 36; 41200 <.byte\0\0\0> ; 16; 0 <.even\0\0\0> ; 20; 0 <.if\0\0\0\0\0> ; 21; 0 <.enas as1?.s ld -n a.out mv a.out asge as as2?.s ld -n a.out mv a.out asge2 25; 0 <.data\0\0\0> ; 26; 0 <.bss\0\0\0\0> ; 27; 0 <.comm\0\0\0> ; 32; 0 ; 36; 41020 ; 36; 41660 ; 36; 41500 ; 36; 41100 ; 36; 41600 ; 36; 41600 ; 36; 41200 ; 36; 41200 <.byte\0\0\0> ; 16; 0 <.even\0\0\0> ; 20; 0 <.if\0\0\0\0\0> ; 21; 0 <.en dotrel: 02; dot: 0 01; dotdot: 0 24; 0 24; 1 24; 2 24; 3 24; 4 24; 5 24; 6 24; 7 24; 10 24; 11 24; 12 24; 13 24; 14 24; 15 24; 16 24; 17 1; 1 1; 2 1; 3 1; 4 1; 5 1; 6 1; 7 1; 10 1; 11 1; 12 1; 13 1; 14 1; 15 1; 16 1; 17 1; 20 1; 21 1; 22 1; 23 1; 24 1; 25 1; 26 1; 27 1; 30 1; 31 1; 32 1; 33 1; 34 1; 35 1; 36 1; 37 5; 23000 5; 22400 5; 22000 5; 23400 5; 110400 5; 110000 5; 20000 5; 20400 5; 21000 5; 21400 6; 25000 6; 117400 6; 5000 6; 7000 6; 400 6; 1400 6; 1000 6; 24400 6; 4400 6; 2400 6; 26400 6; 6400 6; 112000 6; 112400 6; 111400 6; 24000 6; 4000 6; 26000 6; 6000 6; 116000 6; 117000 6; 3000 6; 113400 6; 115400 6; 114400 6; 25400 6; 116400 6; 111000 6; 5400 6; 7400 6; 113000 6; 115000 6; 114000 6; 3400 6; 2000 7; 157400 7; 45000 7; 145000 7; 60400 7; 62400 7; 62000 7; 47000 7; 42000 7; 142000 7; 40400 7; 41400 7; 41000 7; 140000 7; 140400 7; 167400 7; 40000 7; 154000 7; 63000 7; 146000 7; 156400 7; 151000 7; 155000 7; 44400 7; 144400 7; 152000 7; 42400 7; 142400 7; 166400 7; 150000 7; 46400 7; 43400 7; 43400 7; 65000 7; 64400 7; 147400 7; 45400 7; 66400 7; 64000 7; 66000 7; 60000 7; 65400 7; 146400 7; 145400 7; 151400 7; 151400 7; 44000 7; 144000 7; 150400 7; 46000 7; 167000 7; 47400 7; 156000 7; 43000 7; 143000 7; 157000 7; 153400 7; 166000 7; 160400 7; 155400 7; 154400 7; 165400 7; 165000 7; 63400 7; 147000 7; 141400 10; 141000 10; 161000 10; 152400 36; 41400 36; 41060 36; 41460 36; 41420 36; 41020 36; 41040 36; 41440 36; 41420 36; 41020 36; 41660 36; 41500 36; 41100 36; 41600 36; 41600 36; 41200 36; 41200 16; 0 20; 0 21; 0 22; 0 23; 0 25; 0 26; 0 27; 0 32; 0 7; 151400 7; 151400 7; 44000 7; 144000 7; 150400 7; 46000 7; 167000 7; 47400 7; 156000 7; 43000 7; 143000 7; 157000 7; 153400 7; 166000 7; 160400 7; 155400 7; 154400 7; 165400 7; 165000 7; 63400 7; 147000 7; 141400 10; 141000 10; 161000 10; 15240int c; main(argc,argv) { register slen; for(;;){ printf("<"); slen=copy(slen=0); while( slen++ <8) printf("\\0"); printf(">"); while( slen++ <16) printf(" "); printf("\t;\t"); copy(); printf(";\t%o\n",hex()); } } hex() { register num,v; num=0; while( (v=hnum())>=0) num= (num<<4)|v; return(num); } hnum() { if( (c=getchar())>='0' && c<='9') return( c-'0'); if( c>='a' && c<='f') return( c-'a'+10); return(-1); } copy() { register l; l=0; while( (c=getchar())>0){ if( c==';') return(l); putchar(c); l++; } exit(); } tf("<"); slen=copy(slen=0); while( slen++ <8) printf("\\0"); printf(">"); while( slen++ <16) printf(" "); printf("\t;\t"); copy(); printf(";\t%o\n",hex()); } } hex() { register num,v; num=0; while( (v=hnum())>=0) num= (num<<4)|v; return(num); } hnum() { if( (c=getchar())>='0' && c<='9') return( c-'0'); if( c>='a' && c<='f') return( c-'a'+10); return(-1); } copy() { register l; l=0; while( (c=getchar())>0){ if( main(argc,argv) { register c; while( getchar() ){ while( (c=getchar()) != '\n'){ if( c==';' ) copy(); } } } copy() { register c; while( putchar( getchar()) != '\n'); } f("\t;\t"); copy(); printf(";\t%o\n",hex()); } } hex() { register num,v; num=0; while( (v=hnum())>=0) num= (num<<4)|v; return(num); } hnum() { if( (c=getchar())>='0' && c<='9') return( c-'0'); if( c>='a' && c<='f') return( c-'a'+10); return(-1); } copy() { register l; l=0; while( (c=getchar())>0){ if( # /* * bottom half of procsy program. * read procsy input, write to tty */ #define CR 0015 #define LF 0012 #define CTLB 0002 #define RUB 0177 #define CTLR 0022 #define CTLC 0003 #define BKSP 0010 #define SPACE 0040 #define CTLT 0024 #define CTLF 0006 #define CTLE 0005 #define CTLP 0020 #define CTLX 0030 #define UPRO 0136 #define LTRB 0102 #define ESC 0033 #define EOT 0021 int kbin,kbout,prin,prout,hflag; char buf[86]; extern int hold(); int p; main() { register char c; for ( p=1 ; p<=13 ; p++ ) signal(p,1); signal(1,hold); hflag=0; prin=dup(3); prout=dup(4); kbin=dup(5); kbout=dup(6); nxtchar: while ( (c=get1(prin)) != EOT ) { put1(kbout,c); } if ( hflag == 1 ) goto nxtchar; put1(prout,ESC); put1(prout,ESC); /*safe side*/ goto nxtchar; } get1(fd) { int c; read(fd,&c,1); return(c&0177); } put1(fd,c) { write(fd,&c,1); return(c); } hold() { signal(1,hold); if ( hflag == 0 ) { hflag++; }else{ hflag=0; put1(prout,ESC); put1(prout,ESC); } } <=13 ; p++ ) # /* procsy * procsy communicator program * based on a program by D. C. Anderson * P.U. CAD Lab ME Dept. * * modified by : S. Mahler * D. Fouts * date : Jan 8, 1977 * more mods - 1/14/76 S.M. * more mods, dca, 8/2/77 * Version : 2.00 */ #define CR 0015 #define LF 0012 #define CTLB 0002 #define RUB 0177 #define CTLC 0003 #define QUIT 003 #define CTLG 0007 #define BKSP 0010 #define SPACE 0040 #define CTLX 0030 #define UPRO 0136 #define LTRB 0102 #define TAB 011 #define EOT 021 #define CTLU 0025 #define ESC 033 #define CTLS 023 #define CTLQ 021 char ul1[] "/tmp/procsyunlockx"; char l1[] "/tmp/procsylockx"; char ttyf[] "/dev/ttyx"; int kbin,kbout,prin,prout,fflag,pid,kid,sflag; int prold[4],kbold[4]; int raw[] { 0,0,040 ,0}; /* raw tty mode */ int column,ctlcknt; int select -1; int pn; int quit(),force(); char port1[] {'2','3'}; char stat1[] {9,9 }; int nport 2; main(argc,argv) int argc; char *argv[]; { int c,p; char buf[86]; /* | stats will be set | -1 = no lock or unlock | 00 = locked | +1 = unlocked */ for(pn=0; pn= 0 ) stat1[pn]=1; } } if ( argc > 1 ) switch ( *argv[1] ) { case '1': select=0; break; case '2': select=1; break; } for(c=0; c Can't Fork."); quit(); } if ( kid == 0 ) { if ( (execl("./procsy2","procsy2",0)) < 0 ) perror("Procsy> Can't Exec."); quit(); } put1(prout,CTLB); /** top of polling loop **/ newchar: c=get1(kbin); switch(c) { case CTLU: unix(); break; sflag=1; kill(kid,1); break; case BKSP: case RUB: if ( p == 0 ) break; put1(kbout,BKSP); p--; break; case CR: case LF: buf[p++]= 0215; write(prout,buf,p); p=0; put1(kbout,CR); break; case CTLB: p=0; put1(kbout,UPRO); put1(kbout,LTRB); put1(prout,CTLB); break; case CTLX: case CTLC: case CTLS: case CTLG: case CTLQ: p=0; goto light; default: if ( p <= 85 ) { put1(kbout,c); buf[p++]=c|0200; } break; } goto newchar; light: kill(kid,9); while ( wait() != kid ) ; switch( c ) { case CTLG: getpr(); c= CTLB; break; case CTLS: sendpr(); c= CTLB; break; case CTLC: case CTLQ: quit(); case CTLX: setup(); c=CTLB; break; } goto rstart; } putit(fd,c) { if( c==TAB ) { tabout(fd); return; } put1(fd,c); if ( check(c) ) column++; else column=0; } tabout(fd) { int next; next= (column+8)&(0177770); while ( ++column < next ) put1(fd,' '); } check(c) { if( c==QUIT ) quit(); if ( c==CR || c==LF || c== 0177 || c==CTLB ) return(0); return(c); } waiteot(c) { put1(prout,c); while ( get1(prin) != EOT ); column=0; } get1(fd) { int c; read(fd,&c,1); return(c&0177); } put1(fd,c) { c =| 0200; write(fd,&c,1); return(c&0177); } gets(fd,str) int fd; char *str; { register char *s,c; s=str; while( check( c=get1(fd)) ) *s++= c; *s= '\0'; return(str); } puts(fd,str) int fd; char *str; { register char *s,c; s=str; while ( c= *s++) put1(fd,c); } quit() { link(l1,ul1 ); unlink(l1 ); stty(kbin,&kbold); stty(prin,&prold); signal(1,0); exit(); } sendpr() { register c,out,wdog; char buf[50]; int ufile[263],lines; lines=0; wdog=0; stty(kbin,&kbold); name: printf("\nUNIX filename: "); if( fopen(gets(kbin,buf),ufile) < 0 ) { printf("\nCan't open %s\n",buf); goto name; } printf("\nProcsy filename: "); gets(kbin,buf); puts(prout,"qru ttyset de=1 du=h ta=on es=off pa=off\215"); while( get1(prin) != EOT ); puts(prout,"qcr,\0"); puts(prout,buf); loop: waiteot(CR); wdog++; lines++; if( wdog == 20 ) { put1( kbout,'F' ); wdog=0; } while( (c=getc(ufile)) > 0 ) if( check(c) ) putit(prout,c); else goto loop; close(ufile[0]); waiteot(CR); puts(prout,"#s"); waiteot(CR); exit: ctlcknt=0; printf(" %d lines transfered - returning to link!",lines); stty(kbin,&raw); setup(); } getpr() { int ufd,wdog,sizeit; register c,p,lines; char buf[1600]; wdog=0; sizeit=sizeof(buf); stty(kbin,&kbold); uname: printf("\nUNIX filename: "); if( (ufd=creat(gets(kbin,buf),0666)) < 0 ) { printf("\nCan't create %s\n",buf); goto uname; } printf("\nProcsy filename: "); puts(prout,"qru ttyset de=1 du=h ta=on es=on pa=on ej=0\0"); waiteot(CR); gets(kbin,buf); puts(prout,"qdi,\0"); puts(prout,buf); puts(prout," ,sup\0"); lines=0; put1(prout,CR); for(;;) { p=0; while( (c=get1(prin)) != EOT ) { if( p>sizeit ) { printf("no EOT seen\n"); goto getout; } if( (buf[p++]=c) == CR ) { lines++; p--; if( wdog++ == 20 ) { wdog=0; put1( kbout,'T'); } } } if( buf[p-2]=='+' && buf[p-1]=='+') { write(ufd,buf,p-4); break; } if( p != 0 ) write(ufd,buf,p); put1(prout,ESC); } printf(" %d lines transfered - returning to link!",lines); getout: ctlcknt=0; setup(); put1( ufd,LF ); if( ufd>0 ) close(ufd); stty(kbin,&raw); nice(0); } force() { signal( 2,force ); put1( prout,CTLB ); fflag=1; if ( ctlcknt++ == 4 ) quit(); } setup() { puts(prout,"qru ttyset pa=on es=on de=1 ej=0 wi=137 fi=0 \215"); } unix() { int kpid,i,tpid,rstat; kill(kid,1); puts(kbout,"\n%%% "); if( (kpid=fork()) == 0 ) { stty(kbin,&kbold); execl("/bin/sh","%%% sh","-t",0); exit(); } if( kpid == -1) { perror("PROCSY> Can't shell fork()"); return; } while( (tpid=wait(&rstat)) != kpid ); puts(kbout,"\n___\n"); stty(kbin,&raw); kill(kid,1); put1(prout,CTLB); } 2,force ); put1( prout,CTLB ); fflag=1; if ( ctlcknt++ == 4 ) quit(); } setup() { puts(prout,"qru ttyset pa=on es=on de=1 ej=0 wi=137 fi=0 \215"); } unix() { int kpid,i,tpid,rstat; kill(kid,1); puts(kbout,"\n++ == 20 ) { wdog=0; put1( kbout,'T'); } } } if( buf[p-2]=='+' && buf[p-1]=='+') { write(ufd,buf,p-4); break; } if( p != 0 ) write(ufd,buf,p); put1(prout,ESC); } printf(" %d lines transfered - returning to link!",lines); getout: ctlcknt=0; setup(); put1( ufd,LF ); if( ufd>0 ) close(ufd); stty(kbin,&raw); nice(0); } force() { signal( 2,force ); put1( prout,CTLB ); fflag=1; if ( ctlcknt++ == 4 ) quit(); } setup() { puts(prout,"qru ttyset pa=on es=on de=1 ej=0 wi=137 fi=0 \015"); } unix() { int kpid,i,tpid,rstat; kill(kid,1); nice(2); puts(kbout,"\r\n%%% "); if( (kpid=fork()) == 0 ) { stty(kbin,&kbold); execl("/bin/sh","%%%% sh","-t",0); exit(); } if( kpid == -1) { perror("PROCSY> Can't shell fork()"); return; } while( (tpid=wait(&rstat)) != kpid ); puts(kbout,"\n___\n"); stty(kbin,&raw); kill(kid,1); put1(prout,CTLB); nice(0); } t,CTLB ); fflag=1; if ( ctlcknt++ == 4 ) quit(); } setup() { puts(prout,"qru ttyset pa=on es=on de=1 ej=00> ; 7; 155400 ; 7; 154400 ; 7; 165400 ; 7; 165000 ; 7; 63400 ; 7; 147000 ; 7; 141400 / a(x) field only ; 10; 141000 ; 10; 161000 ; 10; 152400 / branches ; 36; 41400 ; 36; 41060 ; 36; 41460 ; 36; 41420 ; 36; 41020 ; 36; 41040 ; 36; 41440 ; 36; 41420 ; 36; 41020 ; 36; 41660 ; 36; 41500 ; 36; 41100 ; 36; 41600 ; 36; 41600 ; 36; 41200 ; 36; 41200 <.byte\0\0\0> ; 16; 0 <.even\0\0\0> ; 20; 0 <.if\0\0\0\0\0> ; 21; 0 <.endif\0\0> ; 22; 0 <.globl\0\0> ; 23; 0 <.text\0\0\0> ; 25; 0 <.data\0\0\0> ; 26; 0 <.bss\0\0\0\0> ; 27; 0 <.comm\0\0\0> ; 32; 0 ; 36; 41020 ; 36; 41660 ; 36; 41500 ; 36; 41100 ; 36; 41600 ; 36; 41600 ; 36; 41200 ; 36; 41200 <.byte\0\0\0> ; 16; 0 <.even\0\0\0> ; 20; 0 <.if\0\0\0\0\0> ; 21; 0 <.en dotrel: 02; dot: 0 01; dotdot: 0 24; 0 24; 1 24; 2 24; 3 24; 4 24; 5 24; 6 24; 7 24; 10 24; 11 24; 12 24; 13 24; 14 24; 15 24; 16 24; 17 1; 1 1; 2 1; 3 1; 4 1; 5 1; 6 1; 7 1; 10 1; 11 1; 12 1; 13 1; 14 1; 15 1; 16 1; 17 1; 20 1; 21 1; 22 1; 23 1; 24 1; 25 1; 26 1; 27 1; 30 1; 31 1; 32 1; 33 1; 34 1; 35 1; 36 1; 37 5; 23000 5; 22400 5; 22000 5; 23400 5; 110400 5; 110000 5; 20000 5; 20400 5; 21000 5; 21400 6; 25000 6; 117400 6; 5000 6; 7000 6; 400 6; 1400 6; 1000 6; 24400 6; 4400 6; 2400 6; 26400 6; 6400 6; 112000 6; 112400 6; 111400 6; 24000 6; 4000 6; 26000 6; 6000 6; 116000 6; 117000 6; 3000 6; 113400 6; 115400 6; 114400 6; 25400 6; 116400 6; 111000 6; 5400 6; 7400 6; 113000 6; 115000 6; 114000 6; 3400 6; 2000 7; 157400 7; 45000 7; 145000 7; 60400 7; 62400 7; 62000 7; 47000 7; 42000 7; 142000 7; 40400 7; 41400 7; 41000 7; 140000 7; 140400 7; 167400 7; 40000 7; 154000 7; 63000 7; 146000 7; 156400 7; 151000 7; 155000 7; 44400 7; 144400 7; 152000 7; 42400 7; 142400 7; 166400 7; 150000 7; 46400 7; 43400 7; 43400 7; 65000 7; 64400 7; 147400 7; 45400 7; 66400 7; 64000 7; 66000 7; 60000 7; 65400 7; 146400 7; 145400 7; 151400 7; 151400 7; 44000 7; 144000 7; 150400 7; 46000 7; 167000 7; 47400 7; 156000 7; 43000 7; 143000 7; 157000 7; 153400 7; 166000 7; 160400 7; 155400 7; 154400 7; 165400 7; 165000 7; 63400 7; 147000 7; 141400 10; 141000 10; 161000 10; 152400 36; 41400 36; 41060 36; 41460 36; 41420 36; 41020 36; 41040 36; 41440 36; 41420 36; 41020 36; 41660 36; 41500 36; 41100 36; 41600 36; 41600 36; 41200 36; 41200 16; 0 20; 0 21; 0 22; 0 23; 0 25; 0 26; 0 27; 0 32; 0 7; 151400 7; 151400 7; 44000 7; 144000 7; 150400 7; 46000 7; 167000 7; 47400 7; 156000 7; 43000 7; 143000 7; 157000 7; 153400 7; 166000 7; 160400 7; 155400 7; 154400 7; 165400 7; 165000 7; 63400 7; 147000 7; 141400 10; 141000 10; 161000 10; 15240as as1?.s ld -n a.out mv a.out asge as as2?.s ld -n a.out mv a.out asge2 1440 36; 41420 36; 41020 36; 41660 36; 41500 36; 41100 36; 41600 36; 41600 36; 41200 36; 41200 16; 0 20; 0 21; 0 22; 0 23; 0 25; 0 26; 0 27; 0 32; 0 7; 151400 7; 151400 7; 44000 7; 144000 7; 150400 7; 46000 7; 167000 7; 47400 7; 156000 7; 43000 7; 143000 7; 157000 7; 153400 7; 166000 7; 160400 7; 155400 7; 154400 7; 165400 7; 165000 7; 63400 7; 147000 7; 141400 10; 141000 10; 161000 10; 15240J & 6  |w j    %   %   ~   ww   uPww  7@%0 %94.e%a" %feww  H7 %;   hw|w j~wDe   % wL7 7 ׯ-  (w7  .weB J ӕ- R r f e0 @ >2 ҋ D~8 ӕ0 $f v Le0 9e  7we&  m  ~    ~ w7 n d `0   LWp `e0eӕ?f4 ,*P   @f  7 -f   7 ߎ 7| 7 zf@@& HADCBF<\0> ; ; %o dox f.ecsl<rcrt0.ostartasgesymt~mainargcargvslen~hexvnum~hnum~copylprintf.oformploop,rjustndigitgnumwidthndfndswtabdecimaloctalhexfloat scien.characstringlogicalremote<prbufFprstrNffltpr.oputchr.oflgetchr.o:badretnexit.o|csv.osavr5$_exit"|_main"_c$csv"_printf"_copy"_hex"cret"_hnum"_getchar":_putchar"pfloat"pscien"_flush"_fout$_errno$_fin$,rjustndigitgnumwidthndfndswtabdecimaloctalhexfloat scien.characstringlogicalremote<prbufFprstrNffltpr.oputchr.oflgetchr.o:badretnexit.o|csv.osavr5$_exit"|_main"int c; main(argc,argv) { register slen; for(;;){ printf("<"); slen=copy(slen=0); while( slen++ <8) printf("\\0"); printf(">"); while( slen++ <16) printf(" "); printf("\t;\t"); copy(); printf(";\t%o\n",hex()); } } hex() { register num,v; num=0; while( (v=hnum())>=0) num= (num<<4)|v; return(num); } hnum() { if( (c=getchar())>='0' && c<='9') return( c-'0'); if( c>='a' && c<='f') return( c-'a'+10); return(-1); } copy() { register l; l=0; while( (c=getchar())>0){ if( c==';') return(l); putchar(c); l++; } exit(); } tf("<"); slen=copy(slen=0); while( slen++ <8) printf("\\0"); printf(">"); while( slen++ <16) printf(" "); printf("\t;\t"); copy(); printf(";\t%o\n",hex()); } } hex() { register num,v; num=0; while( (v=hnum())>=0) num= (num<<4)|v; return(num); } hnum() { if( (c=getchar())>='0' && c<='9') return( c-'0'); if( c>='a' && c<='f') return( c-'a'+10); return(-1); } copy() { register l; l=0; while( (c=getchar())>0){ if( 4D & 6  w  % %; ww  \% wf ,P   @f  J7 4J-|f jBd\B  7L H D76 7 4f@@& HADCBFJcrt0.ostartsymt2.o~mainargcargvc~copyBcputchr.o\flgetchr.obadretexit.ocsv.osavr5$B_exit"_main"csv"_getchar"_copy"Bcret"&_putchar"\_flush"_fout$D_errno$:_fin$< @f  J7 4J-|f jBd\B  7L H D76 7 4f@@& HADCBFJcrt0.ostartsymt2.o~mainargcargvc~copyBcputchr.o\flgetchr.obadretexit.ocsv.osamain(argc,argv) { register c; while( getchar() ){ while( (c=getchar()) != '\n'){ if( c==';' ) copy(); } } } copy() { register c; while( putchar( getchar()) != '\n'); }  4J-|f jBd\B  7L H D76 7 4f@@& HADCBFJcrt0.ostartsymt2.o~mainargcargvc~copyBcputchr.o\flgetchr.obadretexit.ocsv.osa/ pasla test pin = r9 pout = r10 data = r11 ocrec = r12 oc2 = r13 stat = r14 ocsnd = r15 br start .data regs: X10;X11;0;1;X70;0;3 .text start: lm pin,regs ocr pin,oc2 in1: ocr pin,ocrec in: ssr pin,stat btc 5,inerr bcs in rdr pin,data out1: ocr pout,ocsnd out: ssr pout,stat btc 5,outerr bcs out wdr pout,data out2: ssr pout,stat btc 5,outerr bcs out2 br in1 inerr: br inerr outerr: br outerr ~copyBcputchr.o\flgetchr.obadretexit.ocsv.osa# /* | Decode.c - decode a file encode.c ed | Author : Stephen J. Mahler | Date : Jan. 22, 1977 */ #define LOW 0100 #define BIAS 0100 #define HIGH 0117 #define MASK 0017 #define NL 0012 int lines; main() { register char chold,c; register int kontrol; kontrol=2; while( (c=getchar()) != '\0' ) { switch ( c ) { case NL: if( kontrol != 2 ) { printf("Bad Line Length for output "); printf("line number %d\n",lines); exit(); } lines++; break; default: kontrol= 3 - kontrol; if( cHIGH ) { printf("Illegal Char Found |oct|chr|"); printf("| %o | %c |\n",c,c); exit(); } switch( kontrol ) { case 1: chold= (((c-BIAS)&MASK)<<4); break; case 2: chold=| (((c-BIAS)&MASK) ); putchar(chold); } } } } itch ( c ) { case NL: if( kontrol != 2 ) { printf("Bad Line Length for output "); printf("line number %d\n",lines); exit(); } lines++; break; default: kon0> ;6; 2400 ;6; 26400 ;6; 6400 ;6; 112000 ;6; 112400 ;6; 111400 ;6; 24000 ;6; 4000 ;6; 26000 ;6; 6000 ;6; 116000 ;6; 117000 ;6; 3000 ;6; 113400 ;6; 115400 ;6; 114400 ;6; 25400 ;6; 116400 ;6; 111000 ;6; 5400 ;6; 7400 ;6; 113000 ;6; 115000 ;6; 114000 ;6; 3400 ;6; 2000 ;7; 157400 ;7; 45000 ;7; 145000 ;7; 60400 ;7; 62400 ;7; 62000 ;7; 47000 ;7; 42000 ;7; 142000 ;7; 40400 ;7; 41400 ;7; 41000 ;7; 140000 ;7; 140400 ;7; 167400 ;7; 40000 ;7; 154000 ;7; 63000 ;7; 146000 ;7; 156400 ;7; 151000 ;7; 155000 ;7; 44400 ;7; 144400 ;7; 152000 ;7; 42400 ;7; 142400 ;7; 166400 ;7; 150000 ;7; 46400 ;7; 43400 ;7; 43400 ;7; 65000 ;7; 64400 ;7; 147400 ;7; 45400 ;7; 66400 ;7; 64000 ;7; 66000 ;7; 60000 ;7; 60000 ;7; 65400 ;7; 146400 ;7; 145400 ;7; 151400 ;7; 151400 ;7; 44000 ;7; 144000 ;7; 150400 ;7; 46000 ;7; 167000 ;7; 47400 ;7; 156000 ;7; 43000 ;7; 143000 ;7; 157000 ;7; 153400 ;7; 166000 ;7; 160400 ;7; 155400 ;7; 154400 ;7; 165400 ;7; 165000 ;7; 63400 ;7; 147000 ;7; 141400 ;10; 141000 ;10; 161000 ;10; 152400 ;36; 41400 ;36; 41060 ;36; 41460 ;36; 41420 ;36; 41020 ;36; 41040 ;36; 41440 ;36; 41420 ;36; 41020 ;36; 41660 ;36; 41500 ;36; 41100 ;36; 41600 ;36; 41600 ;36; 41200 ;36; 41200 <\0\0\0\0> ;10; 141000 ;10; 161000 ;10; 152400 ;36; 41400 = NDR11 ) { u.u_error = ENXIO; return; } p= &dr11[dev.d_minor]; if( p-> lock ==0){ p-> lock++; p->addr=add= DRADDR - (dev.d_minor*8); junk=add->rbuf; /* clear any hanging input */ add->csr= (INPINT | OUTINT); } else u.u_error = ENXIO; } drclose(dev) { extern lbolt; register struct dr *p; p= &dr11[dev.d_minor]; while( p->outq.c_cc) sleep( &lbolt,PDR); while( getc(&p->inpq) >= 0); p->lock=0; (p->addr)->csr=0; } drwrite(dev) { register struct dr *p; register c,w; extern lbolt; p= &dr11[dev.d_minor]; w=0; while( (c=cpass()) >= 0){ spl5(); while( p->outq.c_cc > DRHIWAT) sleep(&p->outq,PDR); while( putc(c,&p->outq) < 0) sleep( &lbolt,PDR); if( ++w == 2){ w=0; drxint(dev); } spl0(); } } drread(dev) { register struct dr *p; register c,w; p= &dr11[dev.d_minor]; spl5(); do{ while( (c=getc(&p->inpq))<0) sleep(&p->inpq,PDR); } while ( passc(c) >= 0); spl0(); } drxint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_minor]; if( ((p->addr)->csr & OUTRDY) ==0) return; if( (w= (p->outq.c_cc)) >= 2){ (p->addr)->xbuf = (getc(&p->outq)<<8) | getc(&p->outq); (p->addr)->csr =| OUTINT; if( (w=-2)==0 || w==DRLOWAT) wakeup(&p->outq); } else (p->addr)->csr =& ~OUTINT; } drrint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_minor]; w= (p->addr)->rbuf; putc(w,&p->inpq); putc(w>>8, &p->inpq); wakeup(&p->inpq); } spl0(); } drxint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_minor]; if( ((p->addr)->csr & OUTRDY) ==0) return; if( (w= (p->outq.c_cc)) >= 2){ (p->addr)->xbuf = (getc(&p->outq)<<8) | getc(&p->outq); (p->addr)->csr =| OUTINT; if( (w=-2)==0 || w==DRLOWAT) wakeup(&p->outq); } else (p->addr)->csr =& ~OUTINT; } drrint(dev) { register struct dr *p; register int c,w; p= &dr11[dev.d_min# /* * c grafic system support routines */ struct params{ /* parameter passing structure */ int pnum; /* parameter number */ int pval; } param; parm(pn,val) int pn,val; { extern gfd; param.pnum= pn&07; param.pval=val; write(gfd, ¶m, 4); } strng(s) char *s; { register char c,*p; extern gfd; p=s; c=1; while( *p++ ) c++; if( c= (++c)&0177776 ) { param.pnum = 010; write(gfd, ¶m, 2); write(gfd, s, c); } } func(fn) int fn; { extern gfd; int fnn; if( (fnn=fn&077)>017) write(gfd, &fnn, 2); } funcr(fn,cnt,buf) char buf[]; int fn, *cnt; { extern gfd; int fnn; if( (fnn=fn&077) > 017){ write(gfd, &fnn, 2); read(gfd, &fnn,2); *cnt=fnn; if( fnn>0 ){ read(gfd, buf, 2*fnn); } } } =val; write(gfd, ¶m, 4); } strng(s) char *s; { register char c,*p; extern gfd; p=s; c=1; while( *p++ ) c++; if( c= (++c)&0177776 ) { param.pnum = 010; write(gfd, ¶m, 2); write(gfd, s, c); } } func(fn) int fn; { extern gfd; int fnn; if( (fnn=fn&077)>017) wri subroutine cursor(x,y,key) c... toggle tektronix into cursor mode. c.. cursor mode exited by hitting any key. c... returns: c x,y = corrds of cursor relative to current origin. c key = charactor hit. c... integer xcur,ycur common/com502/xcur,ycur,xorg,yorg,fact,istate common/tek001/ipen,ihiy,iextra,loy,ihix,lox,ivmode data iesc,isub,igs/27,26,29/ c... toggle into cursor mode call xdl11(iesc) call xdl11(isub) c... read character and position bytes call rdl11(key) call rdl11(khix) call rdl11(klox) call rdl11(khiy) call rdl11(kloy) call rdl11(kdum) c... toggle back into graph mode call xdl11(igs) call xdl11(lox) c... convert bytes to screen coords rel. to current origin ky=(khiy.and.31)*128+(kloy.and.31)*4 kx=(khix.and.31)*128+(klox.and.31)*4 x=(kx/280.-xorg)/fact y=(ky/280.-yorg)/fact key=key.and.127 return end subroutine erase data iesc,iff/27,12/ c... erase and delay one second for circuits to reset call xdl11(iesc) call xdl11(iff) call delay(1.) return end call rdl11(khiy) call rdl11(kloy) call rdl11(kdum) c... toggle back into graph mode call xdl11(igs) call xdl11(lox) c... convert bytes to screen coords rel. to current origin ky=(khiy.and.31)*128+(kloy.and.31)*4 kx=(khix.and.31)*128+(klox.and.31)*4 x=(kx/280.-xorg)/fact y=(ky/280.-yorg)/fact key=key.and.127 return end subroutine erase data iesc,iff/27,12/ c... erase and delay one second for circuits to reset call xdl11(iesc) call xdl11(iff) call delay(1.) subroutine plot(x,y,ip) integer xcur,ycur common/com502/xcur,ycur,xorg,yorg,fact,istate common/tek001/ipen,ihiy,iextra,loy,ihix,lox,ivmode common/tek002/lastx,lasty,lcode,ixl,ixr,iyb,iyt integer ie(28) data iesc,igs,ius/27,29,31/ c... c pen codes c 0 use (x,y) as absolute coords to position beam, c and set current plotting origin to (x,y). c 1 same type vector as in previous call. c 2 solid c 3 blank c 4 dotted c 5 point c 6 short dash c 7 long dash c 8 dot-dash c... c negative ip resets current plotting origin to x,y. c... c note: use setmod to change types of vectors c normal (default) c defocused c writethru c...... data ie(1),ie(2),ie(3),ie(4),ie(5),ie(6),ie(7), & ie(8),ie(9),ie(10),ie(11),ie(12),ie(13),ie(14), & ie(15),ie(16),ie(17),ie(18),ie(19),ie(20), & ie(21),ie(22),ie(23),ie(24),ie(25),ie(26),ie(27),ie(28)/ & 17, 96, 96, 97, 96, 99, 100, 98, 17, 17, &17,104,104,105,104,107,108,106,17,17, & 17,112,112,113,112,115,116,114 / if (istate.ne.2) call plots if (ip/ / / a6 -- interdata 70 assembler pass 1 opline: mov r4,r0 jsr r5,betwen; 0; 200 br 1f cmp r0,$'< bne xpr jmp opl17 xpr: jsr pc,expres add $2,dot rts pc 1: movb (r4),r0 cmp r0,$24 beq xpr jsr r5,betwen; 5; 36 br xpr mov r0,-(sp) jsr pc,readop mov (sp)+,r0 asl r0 jmp *1f-12(r0) 1: opl6 /map sf to rr opl6 opl7 opl10 opl11 opl12 errort errort errort opl16 opl17 opl20 opl21 opl22 opl23 xpr opl25 opl26 opl27 errort errort errort xpr xpr errort opl36 / btc, bfc opl12: jsr pc,expres cmp r4,$', jne oplea jsr pc,readop / branches opl36: mov $4,-(sp) jsr pc,expres cmp r4,$'( bne 0f / must be long branch a(x) jsr pc,getx br 1f 0: cmp r3,$24 /check reg beq 2f cmp r3,dotrel bne 1f sub dot,r2 bge 1f cmp r2,$-30. blt 1f 2: mov $2,(sp) 1: add (sp)+,dot rts pc opl7: jsr pc,expres cmp r4,$', beq 1f oplea: jsr pc,errora rts pc 1: jsr pc,readop opl10: opl11: / a(x) jsr pc,addres add $4,dot rts pc opl6: / sf,rr jsr pc,expres cmp r4,$', beq 1f jsr pc,errora 1: jsr pc,readop jsr pc,expres add $2,dot rts pc / .byte opl16: jsr pc,expres inc dot cmp r4,$', bne 1f jsr pc,readop br opl16 1: rts pc / < (.ascii) opl17: add numval,dot jsr pc,readop rts pc /.even opl20: inc dot bic $1,dot rts pc /.if opl21: jsr pc,expres tst r3 bne 1f jsr r5,error; 'U 1: tst r2 bne opl22 inc ifflg opl22: /endif rts pc /.globl opl23: cmp r4,$200 blo 1f bisb $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop br opl23 1: rts pc opl25: opl26: opl27: mov dotrel,r1 asl r1 mov dot,savdot-4(r1) mov savdot-[2*25](r0),dot asr r0 sub $25-2,r0 mov r0,dotrel rts pc / .common opl32: cmp r4,$200 blo 1f bis $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop jsr pc,expres rts pc 1: jsr r5,error; 'x rts pc addres: jsr pc,expres cmp r4,$'( bne 0f getx: jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp 0: rts pc errora: jsr r5,error; 'a rts pc errort: jsr r5,error; 't rts pc checkreg: cmp r2,$15. bhi 1f cmp r3,$1 beq 2f cmp r3,$4 bhi 2f 1: jsr pc,errora 2: rts pc errore: jsr r5,error; 'e rts pc checkrp: cmp r4,$') beq 1f jsr r5,error; ') rts pc 1: jsr pc,readop rts pc jsr pc,readop cmp r4,$', bne 1f jsr pc,readop jsr pc,expres rts pc 1: jsr r5,error; 'x rts pc addres: jsr pc,expres cmp r4,$'( bne 0f getx: jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp 0: rts pc errora: jsr r5,error; 'a rts pc errort: jsr r5,error; 't rts pc checkreg: cmp r2,$15. bhi 210 ix1=ixs iy1=iys lcode=0 go to 40 c..store end point info for next time 220 lastx=ix2 lasty=iy2 lcode=ncode return c... send three bytes before turning off beam. c... reset to normal 230 call xdl11 (igs) call xdl11 (iesc) call xdl11 (ie(2)) call xdl11 (ius) istate=0 return end xdl11 (j5) if (iact.lt.3) go to 220 ipb=itmp ipc=itmp2 if (iact.eq.4) go to 210 c..go back and draw to end point. iact=2 ix=ix2 iy=iy2 go to 120 c..must clip other end. subroutine string(stg,ns,isize) c... print string on tektronix using hardware character set. c stg is the string to be printed c ns is the number of characters in the string (100 max.) c isize is the desired hardware character size (1-4, 1=smallest) c... dimension xinc(4),yinc(4) integer*1 stg(100),b integer xcur,ycur common/com502/xcur,ycur,xorg,yorg,fact,istate common/tek001/ipen,ihiy,iextra,loy,ihix,lox,ivmode data iesc,igs,ius/27,29,31/ data last,xinc(1),xinc(2),xinc(3),xinc(4),yinc(1),yinc(2), & yinc(3),yinc(4) & /0,.1085,.119,.1785,.196,.168,.1855,.287,.315/ call where(x,y,f) if(isize.eq.0)isize=last if(isize.gt.4)return c.. send three characters to eliminate any timing problem call xdl11(igs) call xdl11(igs) call xdl11(lox) call xdl11(ius) if(isize.eq.last)go to 2 last=isize call xdl11(iesc) is=60-isize call xdl11(is) 2 do 4 i=1,ns b=stg(i) c... check for lf if(b.eq.10)y=y-yinc(isize) c... check for cr if(b.eq.13)x=0. 4 call xdl11(b) x=x+ns*xinc(isize) call plot(x,y,3) return end 119,.1785,.196,.168,.1855,.287,.315/ call where(x,y,f) if(isize.eq.0)isize=last if(isize.gt.4)return c.. send three characters to eliminate any timing problem call xdl11(igs) call xdl11(igs) call xdl11(lox) call xdl11(ius) if(isize.eq.last)go to 2 last=isize call xdl11(iesc) is=60-isize call xdl11(is) 2 do 4 i=1,ns b=stg(i) c... check for lf if(b.eq.10)y=y-yinc(isize) c... check for cr if(b.eq.13)x=0. 4 call xdl11(b) x=x+ns*xinc( subroutine dorun(nrun,rint) c... c perform run-coded point plot on tektronix using multiple intensities c nrun = number of times to repeat this intensity. c neg. nrun signals start of new scan line. c rint = relative intensity (0. - 1.) c... integer xcur,ycur common/com502/xcur,ycur,xorg,yorg,fact,istate common/tek001/ipen,ihiy,iextra,loy,ihix,lox,ivmode common/run001/ixst,iyst,ixdel,iydel,index,mode data iesc,ifs,ius/27,28,31/ if(rint.lt.0.or.rint.gt.1.)go to 101 knt=iabs(nrun) if(mode.eq.0)go to 1000 if(nrun.gt.0)go to 2 go to 1 c... initialize c... starting corner 1000 ix=ixst iy=iyst go to 2 c... start new scan line 1 mode=2 iy=iy+iydel ix=ixst 2 if(iy.lt.0.or.iy.gt.4095)return j1=((iy/128).and.31)+32 j3=((iy/4).and.31)+96 ycur=iy tint=rint*63. int=tint+64 if(int.eq.126)int=62 if(int.eq.127)int=63 c... set intensity in special point plot mode if(mode.eq.1)go to 3 call xdl11(iesc) call xdl11(ifs) mode=1 3 call xdl11(int) c... set up for skip if 0. intensity if(int.ne.64)go to 4 ix=ix+ixdel*(knt-1) knt=1 c... set point plot mode if multiple run 4 if(knt.eq.1)go to 5 call xdl11(ius) call xdl11(ifs) mode=2 5 do 30 loop=1,knt if(ix.lt.0.or.ix.gt.4095)go to 30 j2=(iy.and.3)*4+(ix.and.3)+96 j4=((ix/128).and.31)+32 j5=((ix/4).and.31)+64 xcur=ix c... send address bytes if(j1.eq.ihiy)go to 10 ihiy=j1 call xdl11(j1) 10 if(j2.eq.iextra)go to 12 iextra=j2 call xdl11(j2) go to 14 12 if(j4.ne.ihix)go to 14 if(j3.eq.loy)go to 16 14 loy=j3 call xdl11(j3) 16 if(j4.eq.ihix)go to 20 18 ihix=j4 call xdl11(j4) 20 call xdl11(j5) lox=j5 30 ix=ix+ixdel return 101 write(6,200) 200 format(/' intensities must be scaled 0.-1.'/) stop end 30 j2=(iy.and.3)*4+(ix.and.3)+96 j4=((ix/128).and.31)+32 j5=((ix/4).and.31)+64 xcur=ix c... send address bytes if(j1.eq.ihiy)go to 10 ihiy=j1 call xdl11(j1) 10 if(j2.eq.iextra)go to 12 iextra=j2 call xdl11(j2) go to 14 12 if(j4.ne.ihix)go to 14 if(j3.eq/ / / a9 -- interdata assembler pass 1 / key to types / 0 undefined / 1 absolute / 2 text / 3 data / 4 bss / 5 sf / 6 rr / 7 rx and rs / 10 a(x) / 11 sys / 12 btc, bfc / 13 error / 14 error / 15 error / 16 .byte / 17 string (.ascii, "<") / 20 .even / 21 .if / 22 .endif / 23 .globl / 24 register / 25 .text / 26 .data / 27 .bss / 30 error / 31 error / 32 .comm / 33 estimated text / 34 estimated data / 35 error / 36 branches .data symtab: / special variables <.\0\0\0\0\0\0\0> ; dotrel: 02; dot: 0 <..\0\0\0\0\0\0> ; 01; dotdot: 0 / registers ; 24; 0 ; 24; 1 ; 24; 2 ; 24; 3 ; 24; 4 ; 24; 5 ; 24; 6 ; 24; 7 ; 24; 10 ; 24; 11 ; 24; 12 ; 24; 13 ; 24; 14 ; 24; 15 ; 24; 16 ; 24; 17 / system calls ; 1; 1 ; 1; 2 ; 1; 3 ; 1; 4 ; 1; 5 ; 1; 6 ; 1; 7 ; 1; 10 ; 1; 11 ; 1; 12 ; 1; 13 ; 1; 14 ; 1; 15 ; 1; 16 ; 1; 17 ; 1; 20 ; 1; 21 ; 1; 22 ; 1; 23 ; 1; 24 ; 1; 25 ; 1; 26 ; 1; 27 ; 1; 30 ; 1; 31 ; 1; 32 ; 1; 33 ; 1; 34 ; 1; 35 ; 1; 36 ; 1; 37 / short (SF) and register (RR) ; 5; 23000 ; 5; 22400 ; 5; 22000 ; 5; 23400 ; 5; 110400 ; 5; 110000 ; 5; 20000 ; 5; 20400 ; 5; 21000 ; 5; 21400 ; 6; 25000 ; 6; 117400 ; 6; 5000 ; 6; 7000 ; 6; 400 ; 6; 1400 ; 6; 1000 ; 6; 24400 ; 6; 4400 ; 6; 2400 ; 6; 26400 ; 6; 6400 ; 6; 112000 ; 6; 112400 ; 6; 111400 ; 6; 24000 ; 6; 4000 ; 6; 26000 ; 6; 6000 ; 6; 116000 ; 6; 117000 ; 6; 3000 ; 6; 113400 ; 6; 115400 ; 6; 114400 ; 6; 25400 ; 6; 116400 ; 6; 111000 ; 6; 5400 ; 6; 7400 ; 6; 113000 ; 6; 115000 ; 6; 114000 ; 6; 3400 ; 6; 2000 / RX and RS ; 7; 157400 ; 7; 45000 ; 7; 145000 ; 7; 60400 ; 7; 62400 ; 7; 62000 ; 7; 47000 ; 7; 42000 ; 7; 142000 ; 7; 40400 ; 12; 41400 ; 12; 41000 ; 7; 140000 ; 7; 140400 ; 7; 167400 ; 7; 40000 ; 7; 154000 ; 7; 63000 ; 7; 146000 ; 7; 156400 ; 7; 151000 ; 7; 155000 ; 7; 44400 ; 7; 144400 ; 7; 152000 ; 7; 42400 ; 7; 142400 ; 7; 166400 ; 7; 150000 ; 7; 46400 ; 7; 43400 ; 7; 43400 ; 7; 65000 ; 7; 64400 ; 7; 147400 ; 7; 45400 ; 7; 66400 ; 7; 64000 ; 7; 66000 ; 7; 60000 ; 7; 65400 ; 7; 146400 ; 7; 145400 ; 7; 151400 ; 7; 151400 ; 7; 144000 ; 7; 150400 ; 7; 46000 ; 7; 167000 ; 7; 47400 ; 7; 156000 ; 7; 43000 ; 7; 143000 ; 7; 157000 ; 7; 153400 ; 7; 166000 ; 7; 160400 ; 7; 155400 ; 7; 154400 ; 7; 165400 ; 7; 165000 ; 7; 63400 ; 7; 147000 ; 7; 141400 ; 7; 153000 / a(x) field only ; 10; 141000 ; 10; 161000 ; 10; 152400 / branches -- a(x) opcode given ; 36; 41400 ; 36; 41060 ; 36; 41460 ; 36; 41420 ; 36; 41020 ; 36; 41040 ; 36; 41440 ; 36; 41420 ; 36; 41020 ; 36; 41660 ; 36; 41500 ; 36; 41100 ; 36; 41600 ; 36; 41600 ; 36; 41200 ; 36; 41200 <.byte\0\0\0> ; 16; 0 <.even\0\0\0> ; 20; 0 <.if\0\0\0\0\0> ; 21; 0 <.endif\0\0> ; 22; 0 <.globl\0\0> ; 23; 0 <.text\0\0\0> ; 25; 0 <.data\0\0\0> ; 26; 0 <.bss\0\0\0\0> ; 27; 0 <.comm\0\0\0> ; 32; 0 ebsymtab: start: sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; aexit 1: mov sp,r5 mov (r5)+,r0 cmpb *2(r5),$'- bne 1f tst (r5)+ dec r0 br 2f 1: clr unglob 2: movb r0,nargs mov r5,curarg jsr r5,fcreat; a.tmp1 movb r0,pof jsr r5,fcreat; a.tmp2 movb r0,fbfil jsr pc,setup jmp go setup: mov $symtab,r1 1: clr r3 mov $8,r2 mov r1,-(sp) 2: movb (r1)+,r4 beq 2f add r4,r3 swab r3 sob r2,2b 2: clr r2 div $hshsiz,r2 ashc $1,r2 add $hshtab,r3 4: sub r2,r3 cmp r3,$hshtab bhi 3f add $2*hshsiz,r3 3: tst -(r3) bne 4b mov (sp)+,r1 mov r1,(r3) add $12.,r1 cmp r1,$ebsymtab blo 1b rts pc /overlay buffer inbuf = setup . =inbuf+512. clr unglob 2: movb r0,nargs mov r5,curarg jsr r5,fcreat; a.tmp1 movb r0,pof jsr r5,fcreat; a.tmp2 movb r0,fbfil jsr pc,setup jmp go setup: mov $symtab,r1 1: clr r3 mov $8,r2 mov r1,-(sp) 2: movb (r1)+,r4 beq 2f a lis 1,1 sth r1,name name: svc 1,0 e( getchar() ){ while( (c=getchar()) != '\n'){ if( c==';' ) copy(); } } } copy() { register c; while( putchar( getchar()) != '\n'); }  4J-|f jBd\B  7L H D76 7 4f@@& HADCBFJcrt0.ostartsymt2.o~mainargcargvc~copyBcputchr.o\flgetchr.obadretexit.ocsv.osa Xffff X1 1+2-1 ais+1 e: svc 1,0 e( getchar() ){ while( (c=getchar()) != '\n'){ if( c==';' ) copy(); } } } copy() { register c; while( putchar( getchar()) != '\n'); }  4J-|f jBd\B  7L H D76 7 4f@@& HADCBFJcrt0.ostartsymt2.o~mainargcargvc~copyBcputchr.o\flgetchr.obadretexit.ocsv.osa/ / / a6 -- interdata assembler pass 2 opline: mov r4,r0 jsr r5,betwen; 0; 177 br 2f cmp r4,$5 beq opeof cmp r4,$'< bne xpr jmp opl17 xxpr: tst (sp)+ xpr: jsr pc,expres jsr pc,outw rts pc 2: movb (r4),r0 cmp r0,$24 /reg beq xpr cmp r0,$33 /est text beq xpr cmp r0,$34 / est data beq xpr jsr r5,betwen; 5; 36 br xpr mov 2(r4),-(sp) mov r0,-(sp) jsr pc,readop mov (sp)+,r0 asl r0 mov $adrbuf,r5 jmp *1f-10.(r0) 1: opl5 opl6 opl7 opl10 opl11 opl12 opl13 opl14 opl15 opl16 opl17 opl20 opl21 opl22 opl23 xxpr opl25 opl26 opl27 opl30 opl31 opl32 xxpr xxpr opl35 opl36 opeof: mov $1,line mov $20,-(sp) mov $argb,r1 1: jsr pc,getw tst r4 bmi 1f movb r4,(r1)+ dec (sp) bgt 1b tstb -(r1) br 1b 1: movb $'\n,(r1)+ clrb (r1)+ tst (sp)+ rts pc opl5: opl6: /sf and rr jsr pc,getr1 jsr pc,expres jsr pc,checkreg opls: bis (sp)+,r2 clr r3 jsr pc,outw rts pc getr1: jsr pc,expres jsr pc,checkreg ash $4,r2 bis r2,2(sp) jsr pc,readop rts pc opl7: /rx,rs jsr pc,getr1 opl10: / a(x) jsr pc,expres oplx: mov r2,(r5)+ mov r3,(r5)+ mov xsymbol,(r5)+ clr r2 cmp r4,$'( bne oplxx jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp oplxx: bis (sp)+,r2 clr r3 jsr pc,outw mov adrbuf,r2 mov adrbuf+2,r3 mov adrbuf+4,xsymbol jsr pc,outw rts pc opl11: / sys jsr pc,expres cmp r3,$2 blt 1f cmp r3,$5 bhi 1f jsr pc,checkreg 1: br opls opl13: opl14: opl15: opl30: opl31: opl35: jsr r5,error; 't rts pc opl12: jsr pc,getr1 opl36: /branches jsr pc,expres cmp r4,$'( jeq oplx cmp r3,$24 jeq oplbr / long-short stuff tstb passno bne 1f mov r2,r0 jsr pc,setbr cmp (sp)+,(r2)+ add r2,dot rts pc / pass 2 1: jsr pc,getbr bcs oplx cmp r3,dot-2 jne oplx sub dot,r2 bit $1,r2 beq 1f jsr r5,error; 'b 1: sub $8192.,(sp) / 2000 hex asr r2 bmi 1f / forward short cmp (sp),$8960. / 2300 hex jhis opls 2: sub $256.,(sp) jbr opls / bw short 1: neg r2 cmp (sp),$8960. bhis 2b bic $512.,(sp) jbr opls / reg branches oplbr: sub $16384.,(sp) jbr opls / .byte opl16: jsr pc,expres jsr pc,outb cmp r4,$', bne 1f jsr pc,readop br opl16 1: tst (sp)+ rts pc / < (.ascii) opl17: jsr pc,getw mov $1,r3 mov r4,r2 bmi 2f bic $!377,r2 jsr pc,outb br opl17 2: jsr pc,getw rts pc /.even opl20: bit $1,dot beq 1f cmp dot-2,$4 beq 2f / bss mode clr r2 clr r3 jsr pc,outb br 1f 2: inc dot 1: tst (sp)+ rts pc opl21: /if jsr pc,expres opl22: oplret: tst (sp)+ rts pc /.globl opl23: cmp r4,$200 blo 1f bisb $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop br opl23 1: tst (sp)+ rts pc / .text, .data, .bss opl25: opl26: opl27: inc dot bic $1,dot mov r0,-(sp) mov dot-2,r1 asl r1 mov dot,savdot-4(r1) tstb passno beq 1f jsr r5,flush; txtp jsr r5,flush; relp mov (sp),r2 add $txtseek-[2*25],r2 mov r2,tseekp mov (r2),r0 jsr r5,oset; txtp add $trelseek-txtseek,r2 mov (r2),r0 mov r2,rseekp jsr r5,oset; relp 1: mov (sp)+,r0 mov savdot-[2*25](r0),dot asr r0 sub $25-2,r0 mov r0,dot-2 / new . relocation tst (sp)+ rts pc opl32: cmp r4,$200 blo 1f mov r4,-(sp) jsr pc,readop jsr pc,readop jsr pc,expres mov (sp)+,r0 bit $37,(r0) bne 1f bis $40,(r0) mov r2,2(r0) 1: tst (sp)+ rts pc getx: jsr pc,expres mov r2,(r5)+ mov r3,(r5)+ mov xsymbol,(r5)+ cmp r4,$'( bne 2f jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp rts pc 2: clr r2 mov $24,r3 rts pc errora: jsr r5,error; 'a rts pc checkreg: cmp r2,$15. bhi 1f cmp r3,$1 blos 2f cmp r3,$5 blo 1f 2: rts pc 1: jsr pc,errora clr r2 clr r3 rts pc errore: jsr r5,error; 'e rts pc checkrp: cmp r4,$') beq 1f jsr r5,error; ') rts pc 1: jsr pc,readop rts pc setbr: mov brtabp,r1 cmp r1,$brlen blt 1f mov $2,r2 rts pc 1: inc brtabp clr -(sp) sub dot,r0 ble 1f sub brdelt,r0 1: jsr r5,betwen; -30.; 30. br 1f br 2f 1: mov r1,-(sp) bic $!7,(sp) mov $1,r0 ash (sp)+,r0 ash $-3,r1 bisb r0,brtab(r1) mov $2,(sp) 2: mov (sp)+,r2 rts pc getbr: mov brtabp,r1 cmp r1,$brlen blt 1f sec rts pc 1: mov r1,-(sp) bic $!7,(sp) neg (sp) inc brtabp ash $-3,r1 movb brtab(r1),r1 ash (sp)+,r1 ror r1 / 0-bit into c-bit rts pc : jsr pc,readop rts pc setbr: mov brtabp,r1 cmp r1,$brlen blt 1f mov $2,r2 rts pc 1: inc brtabp clr -(sp) sub dot,r0 ble 1f sub brdelt,r0 1: jsr r5,betwen; -30.; 30. br 1f br 2f 1: mov r1,-(sp) bic $!7,(sp) mov $1,r0 ash (sp)+,r0 ash $-3,r1 bisb r0,brtab(r1) mov $2,(sp) 2: mov (sp)+,r2 rts pc getbr: mov brtabp,r1 cmp r1,$brlen blt 1f sec rts pc 1: m/ / / as9 -- interdata assembler pass 2 .data symtab: / special variables dotrel: 02; dot: 0 01; dotdot: 0 24; 0 24; 1 24; 2 24; 3 24; 4 24; 5 24; 6 24; 7 24; 10 24; 11 24; 12 24; 13 24; 14 24; 15 24; 16 24; 17 1; 1 1; 2 1; 3 1; 4 1; 5 1; 6 1; 7 1; 10 1; 11 1; 12 1; 13 1; 14 1; 15 1; 16 1; 17 1; 20 1; 21 1; 22 1; 23 1; 24 1; 25 1; 26 1; 27 1; 30 1; 31 1; 32 1; 33 1; 34 1; 35 1; 36 1; 37 5; 23000 5; 22400 5; 22000 5; 23400 5; 110400 5; 110000 5; 20000 5; 20400 5; 21000 5; 21400 6; 25000 6; 117400 6; 5000 6; 7000 6; 400 6; 1400 6; 1000 6; 24400 6; 4400 6; 2400 6; 26400 6; 6400 6; 112000 6; 112400 6; 111400 6; 24000 6; 4000 6; 26000 6; 6000 6; 116000 6; 117000 6; 3000 6; 113400 6; 115400 6; 114400 6; 25400 6; 116400 6; 111000 6; 5400 6; 7400 6; 113000 6; 115000 6; 114000 6; 3400 6; 2000 7; 157400 7; 45000 7; 145000 7; 60400 7; 62400 7; 62000 7; 47000 7; 42000 7; 142000 7; 40400 12; 41400 12; 41000 7; 140000 7; 140400 7; 167400 7; 40000 7; 154000 7; 63000 7; 146000 7; 156400 7; 151000 7; 155000 7; 44400 7; 144400 7; 152000 7; 42400 7; 142400 7; 166400 7; 150000 7; 46400 7; 43400 7; 43400 7; 65000 7; 64400 7; 147400 7; 45400 7; 66400 7; 64000 7; 66000 7; 60000 7; 65400 7; 146400 7; 145400 7; 151400 7; 44000 7; 144000 7; 150400 7; 46000 7; 167000 7; 47400 7; 156000 7; 43000 7; 143000 7; 157000 7; 153400 7; 166000 7; 160400 7; 155400 7; 154400 7; 165400 7; 165000 7; 63400 7; 147000 7; 141400 7; 153000 10; 141000 10; 161000 10; 152400 36; 41400 36; 41060 36; 41460 36; 41420 36; 41020 36; 41040 36; 41440 36; 41420 36; 41020 36; 41660 36; 41500 36; 41100 36; 41600 36; 41600 36; 41200 36; 41200 16; 0 20; 0 21; 0 22; 0 23; 0 25; 0 26; 0 27; 0 32; 0 start: cmp (sp),$4 bge 1f jmp aexit 1: cmp (sp)+,$5 blt 1f mov $40,defund / globalize all undefineds 1: tst (sp)+ mov (sp)+,a.tmp1 mov (sp)+,a.tmp2 mov (sp)+,a.tmp3 jsr r5,ofile; a.tmp1 movb r0,txtfil jsr r5,ofile; a.tmp2 movb r0,fbfil jsr r5,ofile; a.tmp3 movb r0,symf movb r0,fin sys creat; a.out; 0 bec 1f jsr r5,filerr; a.outp 1: movb r0,fout jmp go / overlaid buffer inbuf = start . = inbuf+512. 36; 41200 36; 41200 16; 0 20; 0 21; 0 22; 0 23; 0 25; 0 26; 0 27; 0 32; 0 start: cmp (sp),$4 bge 1f jmp aexit 1: cmp (sp)+,$5 blt 1f mov $40,defund / globalize all undefineds 1: tst (sp)+ mov (sp)+,a.tmp1 mov (sp)+,a.tmp2 mov (sp)+,a.tmp3 jsr r5,ofile# /* | Encode - Push upper and lower case | down PROCSYs' throat | | Author : L. Huggins | Rewrite: S. Mahler - in C for UNIX | | Date : Jan. 15, 1977 | Version: 2.00 */ char obuf[210]; int p,p1,p2,p3; #define NL 0012 #define CR 0015 #define LNIB 0017 #define HNIB 0360 #define NNIB 0000 main() { register char c; p=1; while ( (c=getchar()) != '\0' ) { switch ( c ) { default: obuf[p++]= ((c&HNIB)>>4)|0100; obuf[p++]= (c&LNIB)|0100; if ( p >= 200 ) { write(2,"TMC !!!",7); exit(); } break; case CR: case NL: obuf[p++]= ((c&HNIB)>>4)|0100; obuf[p]= (c&LNIB)|0100; p1= (p>>1); p2= (p1&077776); write(1,obuf+1,p2); printf("\n"); p3=p-p2; write(1,obuf+p2+1,p3); printf("\n"); p=1; break; } } write(2,"\nComplete !\n",12); } ster char c; p=1; while ( (c=getchar()) != '\0' ) { switch ( c ) { default: obuf[p++]= ((c&HNIB)>>4)|0100; obuf[p++]= (c&LNIB)|0100; if ( p >= 200 ) { write(2,"TMC !!!# #define CR 0015 #define LF 0012 #define CTLB 0002 #define RUB 0177 #define CTLR 0022 #define CTLC 0003 #define BKSP 0010 #define SPACE 0040 #define CTLT 0024 #define CTLF 0006 #define CTLE 0005 #define CTLP 0020 #define CTLX 0030 #define UPRO 0136 #define LTRB 0102 #define ESC 0033 #define EOT 0021 int kbin,kbout,prin,prout,hflag; char buf[85]; extern int hold(); int p; main() { register char c; for ( p=1 ; p<=13 ; p++ ) signal(p,1); signal(1,hold); hflag=0; prin=dup(3); prout=dup(4); kbin=dup(5); kbout=dup(6); nxtchar: while ( (c=get1(prin)) != EOT ) { put1(kbout,c); } if ( hflag == 1 ) goto nxtchar; put1(prout,ESC); put1(prout,ESC); /*safe side*/ goto nxtchar; } get1(fd) { int c; read(fd,&c,1); return(c&0177); } put1(fd,c) { write(fd,&c,1); return(c); } hold() { signal(1,hold); if ( hflag == 0 ) { hflag++; }else{ hflag=0; put1(prout,ESC); put1(prout,ESC); } } <=13 ; p++ ) signal(p,1); signal(1,hold); hflag=0; prin=dup(3); prout=dup(4); kbin=dkbold); name: printf("\nunix file name: "); if( fopen(gets(kbin,buf),ufile) < 0 ) { printf("\ncan't open %s\n",buf); goto name; } printf("\nprocsy file name: "); gets(kbin,buf); puts(prout,"qen,de=9999,ej=of\015\0"); while( get1(prin) != EOT) ; puts(prout,"QCRE,\0"); puts(prout,buf); loop: waiteot(CR); while( (c=getc(ufile))>0) if( check(c) ) putit(prout,c); else goto loop; close(ufile[0]); waiteot(CR); puts(prout,"#s"); waiteot(CR); exit: printf("\nreturning to procsy\n"); stty(kbin,&raw); } getpr() { int ufd; register c,p,lines; char buf[1600]; stty(kbin,&kbold); uname: printf("\nunix file name: "); if( (ufd=creat(gets(kbin,buf),0666))<0){ printf("\ncan't create %s\n",buf); goto uname; } printf("\nprocsy file name: "); gets(kbin,buf); puts(prout,"QEN,DE=20,EJ=ON,TA=ON,DU=HA\0"); waiteot(CR); puts(prout,"QDI,\0"); puts(prout,buf); puts(prout,",SUP,RS\0"); lines=0; for(;;){ put1(prout,CR); p=0; while( (c=get1(prin)) != EOT){ if( p> sizeof(buf) ){ printf("no EOT seen\n"); goto getout; } if( (buf[p++]=c) == CR) { lines++; p-- ;} } if( buf[p-2]=='+' && buf[p-1]=='+') { write(ufd,buf,p-4); break; } write(ufd,buf,p-1); } printf("%d lines- back to procsy\n",lines); getout: if( ufd>0) close(ufd); stty(kbin,&raw); } ,DE=20,EJ=ON,TA=ON,DU=HA\0"); waiteot(CR); puts(prout,"QDI,\0"); puts(prout,buf); puts(prout,",SUP,RS\0"); lines=0; for(;;){ put1(prout,CR); p=0; while( (c=get1(prin)) != EOT){ if( p> sizeof(buf) ){ / interdata opcode test .text x=r1 ai r1,a(x) air r1,r2 ah r1,a(x) ahi r1,n(x) n=Xffff ahr r1,r2 ahm r1,a(x) a: m = 15. ais r1,m abl r1,a(x) atl r1,a(x) ach r1,a(x) achr r1,r2 nh r1,a(x) nhi r1,a(x) nhr r1,r2 al a(x) bal r1,a(x) balr r1,r2 bfc m,a(x) bfcr m,r2 btc m,a(x) btcr m,r2 btbs m,d btfs m,d d = 1 bfbs m,d bffs m,d bxh r1,a(x) bxle r,a(x) ch r,a(x) chi r,n(x) r = r1 chr r,r dh r,a(x) dhr r,r exbr r,r epsr r,r xh r,a(x) xhi r,a(x) xhr r,r ae r,a(x) aer r,r ce r,a(x) cer r,r de r,a(x) der r,r le r,a(x) ler r,r me r,a(x) mer r,r ste r,a(x) se r,a(x) ser r,r lb r,a(x) lbr r,r lcs r,m lh r,a(x) lhi r,m(x) lhr r,r lis r,m lm r,a(x) lpsw a(x) mh r,a(x) mhr r,r mhu r,a(x) mhur r,r oh r,a(x) ohi r,n(x) ohr r,r oc r,a(x) ocr r,r rd r,a(x) rdr r,r rb r,a(x) rbr r,r rh r,a(x) rhr r,r rll r,n(x) rrl r,n(x) rbl r,a(x) rtl r,a(x) ss r,a(x) ssr r,r sla r,n(x) sll r,n(x) slha r,n(x) slhl r,n(x) slls r,m sra r,n(x) srl r,n(x) srha r,n(x) srhl r,n(x) srls r,m sint a(x) stb r,a(x) stbr r,r sth r,a(x) stm r,a(x) sh r,a(x) shi r,n(x) shr r,r sis r,m sch r,a(x) schr r,r svc r,a(x) thi r,n(x) wb r,a(x) wbr r,r wd r,a(x) wdr r,r wh r,a(x) whr r,r / branches 1: br a br 1f br 1b bne a bne 1f bne 1b beq a beq 1b beq 1f bge a bge 1b bge 1f bge r blt a blt 1b blt 1f blt r bgt a bgt 1b bgt 1f bgt r ble a ble 1b ble 1f ble r 1: bpl a bpl 1b bpl 1f bpl r bmi a bmi 1b bmi 1f bmi r bhi a bhi 1b bhi 1f bhi r 1: bvc a bvc 1b bvc 1f bvc r bvs a bvs 1b bvs 1f bvs r bhis a bhis 1b bhis 1f bhis r bcc a bcc 1b bcc 1f bcc r bcs a bcs 1b bcs 1f bcs r bcs 1f(r) 1: blo a blo 1b blo 1f 1: blo r blo 1b(r) .byte 1,2,3,4 .even .=.+1 .even bne 1f bne 1b beq a beq 1b beq 1f bge a bge 1b bge 1f bge r blt a blt 1b blt 1f blt r bgt a bgt 1b bgt 1f bgt r ble a ble 1b ble 1f ble r 1: bpl a bpl 1b bpl 1f bpl r bmi a bmi 1b bmi 1f # /* * procsy -- procsy communicator program * d. anderson, may,1976 * version 2. */ #define TAB 011 #define QUIT 3 #define EOL 4 #define BREAK 5 #define SEND 023 #define GET 07 #define LF 012 #define CR 015 #define EOT 021 #define CTLB 02 char ttyf[] "/dev/ttyn"; int kbin,kbout,prin,prout; int prold[3], kbold[3]; int raw[] { 0,0,040 }; /* raw tty mode */ int column; int quit(); main(argc,argv) int argc; char *argv[]; { register c; if( argc<2 ) { printf("usage: procsy ttyn\n"); exit(); } ttyf[8] = *argv[1]; if( (prin=open(ttyf,0))<=0){ printf("can't open %s-input\n",ttyf); exit(); } if( (prout=open(ttyf,1))<=0){ printf("can't open %s-output\n",ttyf); exit(); } kbin=dup(0); kbout=dup(1); gtty(kbin,&kbold); gtty(prin,&prold); stty(prin,&raw); signal(1,1); signal(1,quit); put1(prout,CTLB); for(;;){ stty(kbin,&kbold); while( (c=get1(prin)) != EOT) putit(kbout,c); stty(kbin,&raw); while( check(c=get1(kbin))) switch( c) { default: putit(prout,c); column--; putit(kbout,c); break; case GET: stty(kbin,&kbold); getpr(); stty(kbin,&raw); break; case SEND: stty(kbin,&kbold); sendpr(); stty(kbin,&raw); break; } putit(prout,c); } } putit(fd,c) { if( c==TAB ) { tabout(fd); return; } put1(fd,c); if( check(c) ) column++; else column=0; } tabout(fd) { do put1(fd,' '); while (++column & 07); } check(c) { if( c==QUIT) quit(); if( c==CR || c==LF || c==0177 || c==CTLB || c== -1) return(0); return(c); } waiteot(c) { put1(prout,c); while( get1(prin) != EOT ); column=0; } get1(fd) { int c; if( read(fd,&c,1) == 1) return(c&0177); else return(-1); } put1(fd,c) { c =| 0200; write(fd,&c,1); return(c&0177); } gets(fd,str) int fd; char *str; { register char *s,c; s=str; while( check( c=get1(fd))) *s++=c; *s= '\0'; return(str); } puts(fd,str) int fd; char *str; { register char *s,c; s=str; while( c= *s++) put1(fd,c); } quit() { signal(1,0); stty(kbin,&kbold); stty(prin,&prold); exit(); } sendpr() { register c,out; char buf[50]; int ufile[263]; int mode; name: printf("\nunix file name: "); if( fopen(gets(kbin,buf),ufile) < 0 ) { printf("\ncan't open %s\n",buf); goto name; } printf("\nprocsy file name: "); gets(kbin,buf); printf("\nbinary(b) or coded(c) ? "); gets(kbin,&mode); puts(prout,"qen,ta=on,ru=off,wi=120,eo=204,br=205"); waiteot(CR); puts(prout,"mutil"); waiteot(EOL); put1(prout,'c'); if( mode == 'b' ) put1(prout,'b'); else put1(prout,'c'); puts(prout,"f,tty,"); puts(prout,buf); loop: waiteot(EOL); while( (c=getc(ufile))>0) if( check(c) ) putit(prout,c); else { if( mode == 'b' ) put1(prout,LF); goto loop; } close(ufile[0]); put1(prout,BREAK); waiteot(EOL); waiteot(CTLB); puts(prout,"log"); waiteot(EOL); puts(prout,"qen,ru=on,eo=15,br=43"); waiteot(EOL); exit: printf("\nreturning to procsy\n"); } getpr() { int ufd; register c,p,lines; char buf[1600]; stty(kbin,&kbold); uname: printf("\nunix file name: "); if( (ufd=creat(gets(kbin,buf),0666))<0){ printf("\ncan't create %s\n",buf); goto uname; } printf("\nprocsy file name: "); gets(kbin,buf); puts(prout,"QEN,DE=20,EJ=ON,TA=ON,DU=HA\0"); waiteot(CR); puts(prout,"QDI,\0"); puts(prout,buf); puts(prout,",SUP,RS\0"); lines=0; for(;;){ put1(prout,CR); p=0; while( (c=get1(prin)) != EOT){ if( p> sizeof(buf) ){ printf("no EOT seen\n"); goto getout; } if( (buf[p++]=c) == CR) { lines++; p-- ;} } if( buf[p-2]=='+' && buf[p-1]=='+') { write(ufd,buf,p-4); break; } write(ufd,buf,p-1); } printf("%d lines- back to procsy\n",lines); getout: if( ufd>0) close(ufd); } ; puts(prout,"QEN,DE=20,EJ=ON,TA=ON,DU=HA\0"); waiteot(CR); puts(prout,"QDI,\0"); puts(prout,buf); puts(prout,",SUP,RS\0"); lines=0; for(;;){ put1(prout,CR); p=0; while( (c=get1(prin)) != EOT){ if( p> sizeof(buf) ){ printf("no EOT seen\n"); goto getout; } if( (buf[p++]=c) == CR) { lines++; p-- ;} } if( buf[p-2]=='+' && buf[p-1]=='+') { write(ufd# /* | Brute Force Link | | by | Stephen J. Mahler | 10-76 */ #define BKSP 010 #define CTLCHR 020 /* Ctl-P of course */ #define SPACE 040 #define RUB 0177 char fname[] "/dev/ttyx"; int destkb,desttt,status,whoami; int lbuf[3],tbuf[3],temp[3]; int file,rstat; int c; int fake; /* we will now fake out the world | first make fd3=so and fd1=fd2 */ char ul1[] "/tmp/miracleunlock1"; char ul2[] "/tmp/miracleunlock2"; char l1[] "/tmp/miraclelock1"; char l2[] "/tmp/miraclelock2"; int select,stat1,stat2; char port1,port2; char buf[38] ; main(argc,argv) int argc; char *argv[]; { port1= 'i'; port2= 'j'; stat1=stat2=999; /* | stats 1 and to will be set | +1 = avail | 00 = avail | -1 = avail */ if ( (stat(l1,buf) < 0 ) && (stat(ul1,buf) < 0 ) ) { stat1= -1; goto ps2; } stat1=0; if ( (stat(ul1,buf)) >= 0 ) { stat1=1; } ps2: if ( (stat(l2,buf) < 0 ) && (stat(ul2,buf) < 0 ) ) { stat2= -1; goto psf; } stat2=0; if( (stat(ul2,buf)) >= 0 ) { stat2=1; } psf: if ( argc == 1 ) { select=0; goto choose; } switch ( *argv[1] ) { case '1': select=1; break; case '2': select=2; break; default: select=0; } choose: if ( select == 2 ) goto choose2; switch ( stat1 ) { case -1: printf("\nMiracle Port 1 is out of service.\n"); control: if ( select == 1 ) exit(-1); else break; case 0: printf("\nMiracle Port 1 is IN USE.\n"); goto control; case 1: printf("\nLinking via Miracle Port 1.\n"); fname[8]= port1; goto begin; default: syserr: printf("MIRACLE> System Error Notify Mahler.\n"); abort(); } choose2: if ( select == 1 ) goto noluck; switch ( stat2 ) { case -1: printf("Miracle Port 2 is out of service.\n"); break; case 0: printf("Miracle Port 2 is IN USE.\n"); break; case 1: printf("Linking via Miracle Port 2.\n"); fname[8]=port2; goto begin; default: goto syserr; } noluck: exit(); begin: if ( fname[8] == port1 ) { link( ul1,l1 ); unlink( ul1 ); }else{ link( ul2,l2 ); unlink( ul2 ); } fake=dup(1); close(1); dup(2); printf("\nStarting......"); if ( (destkb=open(fname,0)) < 0 ) { printf("Can't open target source.\n"); exit(); } if ( (desttt=open(fname,1)) < 0 ) { printf("Can't open target sink.\n"); exit(); } /* | At this point we must put the target device in raw mode. */ if( gtty(destkb,&tbuf) < 0 ) { printf("Target must be a teletype port !\n"); exit(); } temp[0]=tbuf[0]; temp[1]=tbuf[1]; temp[2]= 0040; if( stty(destkb,&temp) < 0 ) { printf("Can't put target in RAW mode.\n"); exit(); } /* | And if the local source is a KB: put it in raw. */ file = 0; if( gtty(0,&lbuf) < 0 ) { printf("File Transfer.\r\n"); file = 1; goto proceed; } temp[0]=lbuf[0]; temp[1]=lbuf[0]; temp[2]= 0352; if( stty(0,&temp) < 0 ) { printf("Changing device types ?\n"); exit(); } printf("Keyboard Communications.\r\n"); proceed: printf("\r\n"); /* now the fake-out ends | put all back as it was */ close(1); dup(3); close(3); whoami=fork(); if(whoami == 0) goto child; parent: if(whoami == -1) { printf("link> Can't reverse circuit !\n"); exit(); } evermore: while ( (rstat=read(0,&c,1)) != '\0' ) { if( c == CTLCHR ) goto killkid; if( c == '\0' ) goto killkid; if( c == '\n' && file == 1 ) { c="\r";} if ( c == RUB ) { printf("\b \b"); } if( (write(desttt,&c,1)) < 0 ) { printf("Write Error on target sink.\n"); goto killkid; } } if( rstat < 0 ) { printf("Read Error on local source.\n"); goto killkid; } else { printf("End of File on local source.\n"); goto killkid; } killkid: kill(whoami,2); if ( fname[8] == port1 ) { link( l1,ul1 ); unlink( l1 ); }else{ link( l2,ul2 ); unlink( l2 ); } stty(0,&lbuf); stty(destkb,&tbuf); exit(); /* this section sets up the reverse channel */ child: printf("Link Established !\r\n"); forever: if( (read(destkb,&c,1)) < 0 ) { printf("Read Error on target source.\n"); exit(); } if( (write(1,&c,1)) < 0 ) { printf("Write Error on local sink.\n"); exit(); } goto forever; } source.\n"); goto killkid; } killkid: kill(whoami,2); if ( fname[8] == port1 ) { link( l1,ul1 ); unlink( l1 ); }else{ link( l2,ul2 ); unlink( l2 ); } stty(0,&lbuf); stty(destkb,&tbuf); exit(); /* this section sets up the reverse channel */ child: printf("Link Established !\r\n"); forever: if( (read(destkb,&c,1)) < 0 ) { printf("Read Error on target source.\n"); exit(); } if( (w# /* * Editor */ #define SIGHUP 1 #define SIGINTR 2 #define SIGQUIT 3 #define FNSIZE 64 #define LBSIZE 512 #define ESIZE 128 #define GBSIZE 256 #define NBRA 5 #define EOF -1 #define CBRA 1 #define CCHR 2 #define CDOT 4 #define CCL 6 #define NCCL 8 #define CDOL 10 #define CEOF 11 #define CKET 12 #define STAR 01 #define error goto errlab #define READ 0 #define WRITE 1 int peekc; int lastc; char bkfile[26] "/tmp/bkup/xxxxxxxxxxxxxx"; char savedfile[FNSIZE]; char file[FNSIZE]; char linebuf[LBSIZE]; char rhsbuf[LBSIZE/2]; char expbuf[ESIZE+4]; int circfl; int *zero; int *dot; int *dol; int save_dot; /* flag--whether this command saves dot or not */ int brcount 1; /* number of lines to output on "newline" command */ int num; int *endcore; int *fendcore; int line_num; /* integer for line number on output */ char *fmtlno {" %6l="}; /* format for line-number output */ int *addr1; int *addr2; int *old_a1; /* previous address */ int *old_a2; /* " " */ char genbuf[LBSIZE]; int count[2]; char *e_prompt ">"; /* editor command prompt */ int prompt1 0; /* flag--enable or disable ALL prompting */ int prompt2 1; /*flag--enable or disable line-num prompts */ int text_was_modified 0; /* flag--on if text was modified */ int globf2 0; /* kludge for "-f" */ int num_reads 0; /* indicator to aid text_was_modified-- /* first read isn't really a modify */ char *nextip; char *linebp; int ninbuf; int io; int pflag; int eflg; /* echo input flag */ int fflg; /* "file" flag */ int sflg; /* "silent" flag -- no extra output */ int onhup; int onquit; int listf; int col; char *globp; int tfile -1; int tline; char *tfname; char *loc1; char *loc2; char *locs; char ibuff[512]; int iblock -1; char obuff[512]; int oblock -1; int ichanged; int nleft; int errfunc(); int *errlab errfunc; char TMPERR[] "TMP"; int names[26]; char *braslist[NBRA]; char *braelist[NBRA]; int name_did_change 0; /* 1-changed */ int ecflag 0; /* 1-from "e"*/ main(argc, argv) char **argv; { register char *p1, *p2; extern int onintr(); onquit = signal(SIGQUIT, 1); onhup = signal(SIGHUP, 1); printf("\nNed, v2.20\n"); while(argc-- > 1){ argv++; if(**argv == '-') switch((*argv)[1]){ case 'q': signal(SIGQUIT,0); break; case 'e': eflg++; break; case 's': sflg++; break; case 'f': fflg++; break; case 'n': prompt1 = 0; break; default: printf("bad flag: %s",*argv); exit(); } else { p1 = *argv; p2 = savedfile; while(*p2++ = *p1++) {} if(fflg) { globp = "a\n"; globf2 = 1; } else globp = "r"; } } fendcore = sbrk(0); init(); if ((signal(SIGINTR, 1) & 01) == 0) signal(SIGINTR, onintr); setexit(); do commands(); while(are_you_sure()); if(fflg){ globp = "w\n"; commands(); } unlink(tfname); } /*page */ commands() { int getfile(), gettty(); register *a1, c; register char *p; int i,r; for (;;) { if (pflag) { pflag = 0; addr1 = addr2 = dot; goto print; } if(!globp){ if(prompt2) puts2(e_prompt); old_a1 = addr1; old_a2 = addr2; } addr1 = 0; addr2 = 0; if((peekc = getchar()) == '='){ peekc = 0; addr1 = old_a1; addr2 = old_a2; if((c = peekc = getchar()) == '\n') c = 'p'; else peekc = 0; } else { r = 1; do { addr1 = addr2; if ((a1 = address())==0) { c = getchar(); break; } addr2 = a1; if ((c=getchar()) == ';') { c = ','; dot = a1; } } while (c==',' && r-- > 0); } if (addr1==0) addr1 = addr2; line_num = (addr1? addr1 : dot) - zero; /*page */ switch(c) { case 'A': case 'a': setdot(); newline(); line_num++; r = append(gettty, addr2); text_was_modified =+ r; continue; case 'B': case 'b': num = 0; while( '0' <= (c = getchar()) && c <= '9' ) num = num*10 + c-'0'; peekc = c; newline(); if(num > 0) brcount = num; else brcount =1; continue; case 'C': case 'c': delete(); r = append(gettty, addr1-1); text_was_modified =+ r; continue; case 'D': case 'd': delete(); text_was_modified = 1; continue; case 'E': case 'e': if(fflg) errmsg(236,"can't change filename"); setnoaddr(); if ((peekc = getchar()) != ' ') errmsg(239,"illegal file name syntax"); /* if(text_was_modified && !are_you_sure()) /* error; */ savedfile[0] = 0; init(); addr2 = zero; text_was_modified = 0; name_did_change = 0; ecflag = 1; num_reads = 0; goto caseread; case 'F': case 'f': setnoaddr(); if ((c = getchar()) != '\n') { if(fflg) errmsg(254,"can't change file name"); peekc = c; savedfile[0] = 0; filename(); } puts(savedfile); continue; case 'G': case 'g': global(1); continue; case 'I': case 'i': setdot(); nonzero(); newline(); r = append(gettty, addr2-1); text_was_modified =+ r; continue; case 'K': case 'k': if ((c = getchar()) < 'a' || c > 'z') errmsg(276,"syntax is K[a-z]"); newline(); setdot(); nonzero(); names[c-'a'] = *addr2 | 01; continue; case 'M': case 'm': move(0); text_was_modified = 1; continue; case 'N': case 'n': newline(); prompt1++; prompt1 =& 01; printf("%sline numbers\n",(prompt1? "" : "no ")); continue; case '\n': if (addr2==0) { addr2 = dot+1; line_num++; addr1 = addr2; if(brcount != 1) { addr2 = dot + brcount; if(addr2 > dol) addr2 = dol; if(addr2 < zero) addr2 = zero; } } goto print; case 'L': case 'l': listf++; case 'P': case 'p': save_dot = 0; if((c = getchar()) == 'p' || c == 'l') { save_dot = 1; addr1 = zero+1; addr2 = dol; } else peekc = c; newline(); print: setdot(); nonzero(); a1 = addr1; do { if(prompt1 && prompt2) { line_num = a1 - zero; printf(fmtlno,line_num); } puts(getline(*a1++)); } while (a1 <= addr2); if(!save_dot) dot = addr2; save_dot = 0; listf = 0; continue; case 'Q': case 'q': setnoaddr(); newline(); return; case 'R': case 'r': caseread: filename(); if ((io = open(file, 0)) < 0) { lastc = '\n'; printf("can't read %s\n",file); error; } setall(); ninbuf = 0; r = append(getfile, addr2); printf("%l lines\n",r); exfile(); if(num_reads++) text_was_modified =+ r; else text_was_modified = 0; continue; case 'S': case 's': setdot(); nonzero(); substitute(globp); text_was_modified = 1; continue; case 'T': case 't': move(1); continue; case 'V': case 'v': global(0); continue; case 'W': case 'w': setall(); filename(); if( text_was_modified == 0 && name_did_change == 0 ) { printf("You made no changes! Write NOT performed.\n"); continue; } if ((io = creat(file, 0666)) < 0){ printf("can't create %s\n",file); error; } if(dol == zero){ printf("[nothing written]\n"); continue; } nonzero(); putfile(); exfile(); /* attempt to stop hardware error problems */ for( i=10; i<16; i++ ) { if( file[i-10] != '\0' ) bkfile[i]=file[i-10]; } for( i=16; i<22; i++ ) { bkfile[i]=tfname[i-10]; } setall(); printf("Creating Backup copy %s.\n",bkfile); if( (io = creat(bkfile,0600)) < 0 ) { printf("ed> Can't creat %s.\n",bkfile); exfile(); goto abrtbkup; } if ( dol == zero ) { printf("[nothing backed-up]\n"); exfile(); goto abrtbkup; } nonzero(); putfile(); exfile(); text_was_modified = 0; abrtbkup: continue; case '!': unix(); continue; case EOF: return; } errmsg(396,"unrecognized command"); } } /*page */ address() { register *a1, minus, c; int n, relerr; minus = 0; a1 = 0; for (;;) { c = getchar(); if ('0'<=c && c<='9') { n = 0; do { n =* 10; n =+ c - '0'; } while ((c = getchar())>='0' && c<='9'); peekc = c; if (a1==0) a1 = zero; if (minus<0) n = -n; a1 =+ n; minus = 0; continue; } relerr = 0; if (a1 || minus) relerr++; switch(c) { case ' ': case '\t': continue; case '+': minus =+ brcount; if (a1==0) a1 = dot; continue; case '-': case '^': minus =- brcount; if (a1==0) a1 = dot; continue; case '?': case '/': compile(c); a1 = dot; for (;;) { if (c=='/') { a1++; if (a1 > dol) a1 = zero; } else { a1--; if (a1 < zero) a1 = dol; } if (execute(0, a1)) break; if (a1==dot) errmsg(462,"string not found"); } break; case '$': a1 = dol; break; case '.': a1 = dot; break; case '\'': if ((c = getchar()) < 'a' || c > 'z') errmsg(476," ' must be followed by [a-z]"); for (a1=zero; a1<=dol; a1++) if (names[c-'a'] == (*a1|01)) break; break; default: peekc = c; if (a1==0) return(0); a1 =+ minus; if(a1 < zero) a1 = zero; else if(a1 > dol) a1 = dol; return(a1); } if (relerr) errmsg(494,"\"relerror\" (?)"); } } setdot() { if (addr2 == 0) addr1 = addr2 = dot; if (addr1 > addr2) errmsg(503,"lower address bound > upper one"); } setall() { if (addr2==0) { addr1 = zero+1; addr2 = dol; if (dol==zero) addr1 = zero; } setdot(); } setnoaddr() { if (addr2) errmsg(520,"address illegal here"); } nonzero() { if(addr1 <= zero) errmsg(532,"non-existant line number"); if(addr2 > dol) errmsg(534,"bottom of file reached"); } newline() { register c; if ((c = getchar()) == '\n') return; if (c=='p' || c=='l' || c=='P' || c=='L' ) { pflag++; if (c=='l') listf++; if (getchar() == '\n') return; } errmsg(542,"command syntax error"); } filename() { register char *p1, *p2; register c; count[1] = 0; c = getchar(); if (c=='\n' || c==EOF) { p1 = savedfile; if (*p1==0) errmsg(555,"null file name illegal"); p2 = file; while (*p2++ = *p1++); return; } if (c!=' ') errmsg(561,"file name syntax"); while ((c = getchar()) == ' '); if (c=='\n') errmsg(564,"null file name illegal"); p1 = file; do { *p1++ = c; } while ((c = getchar()) != '\n'); *p1++ = 0; if (savedfile[0]==0) { p1 = savedfile; p2 = file; while (*p1++ = *p2++); } if( ecflag != 1 ) name_did_change = 1; ecflag = 0; } exfile() { close(io); io = -1; } onintr() { signal(SIGINTR, onintr); putchar('\n'); lastc = '\n'; errmsg(588,"INTERUPT!"); } errfunc() { register c; listf = 0; /* puts("?"); */ count[0] = 0; seek(0, 0, 2); pflag = 0; if (globp) lastc = '\n'; globp = 0; peekc = lastc; while ((c = getchar()) != '\n' && c != EOF); if (io > 0) { close(io); io = -1; } reset(); } getchar() { if (lastc=peekc) { peekc = 0; return(lastc); } if (globp) { if ((lastc = *globp++) != 0) return(lastc); globp = 0; if(globf2 == 0) return(EOF); globf2 = 0; } if (read(0, &lastc, 1) <= 0) return(lastc = EOF); lastc =& 0177; return(echo(lastc)); } echo(ch) { if(eflg) putchar(ch); return(ch); } gettty() { register c, gf; register char *p; p = linebuf; gf = globp; if(prompt1 && prompt2) { printf(fmtlno,line_num++); flush_buf(); } while ((c = getchar()) != '\n') { if (c==EOF) { if (gf) peekc = c; return(c); } if ((c =& 0177) == 0) continue; *p++ = c; if (p >= &linebuf[LBSIZE-2]) errmsg(660,"input line too long"); } *p++ = 0; if (linebuf[0]=='.' && linebuf[1]==0) return(EOF); return(0); } getfile() { register c; register char *lp, *fp; lp = linebuf; fp = nextip; do { if (--ninbuf < 0) { if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) return(EOF); fp = genbuf; } if (lp >= &linebuf[LBSIZE]) errmsg(682,"line in file too long"); /* ( 512 chars) */ if ((*lp++ = c = *fp++ & 0177) == 0) { lp--; continue; } if (++count[1] == 0) ++count[0]; } while (c != '\n'); *--lp = 0; nextip = fp; return(0); } putfile() { int *a1; register char *fp, *lp; register nib; nib = 512; fp = genbuf; a1 = addr1; do { lp = getline(*a1++); for (;;) { if (--nib < 0) { write(io, genbuf, fp-genbuf); nib = 511; fp = genbuf; } if (++count[1] == 0) ++count[0]; if ((*fp++ = *lp++) == 0) { fp[-1] = '\n'; break; } } } while (a1 <= addr2); write(io, genbuf, fp-genbuf); } append(f, a) int (*f)(); { register *a1, *a2, *rdot; int nline, tl; struct { int integer; }; nline = 0; dot = a; while ((*f)() == 0) { if (dol >= endcore) { if (sbrk(1024) == -1) errmsg(743,"file overflows available memory"); endcore.integer =+ 1024; } tl = putline(); nline++; a1 = ++dol; a2 = a1+1; rdot = ++dot; while (a1 > rdot) *--a2 = *--a1; *rdot = tl; } return(nline); } unix() { register savint, pid, rpid; int retcode; setnoaddr(); if ((pid = fork()) == 0) { signal(SIGHUP, onhup); signal(SIGQUIT, onquit); execl("/bin/sh", "sh", "-t", 0); exit(); } savint = signal(SIGINTR, 1); while ((rpid = wait(&retcode)) != pid && rpid != -1); signal(SIGINTR, savint); puts("!"); } delete() { register *a1, *a2, *a3; setdot(); newline(); nonzero(); a1 = addr1; a2 = addr2+1; a3 = dol; dol =- a2 - a1; do *a1++ = *a2++; while (a2 <= a3); a1 = addr1; if (a1 > dol) a1 = dol; dot = a1; } getline(tl) { register char *bp, *lp; register nl; lp = linebuf; bp = getblock(tl, READ); nl = nleft; tl =& ~0377; while (*lp++ = *bp++) if (--nl == 0) { bp = getblock(tl=+0400, READ); nl = nleft; } return(linebuf); } putline() { register char *bp, *lp; register nl; int tl; lp = linebuf; tl = tline; bp = getblock(tl, WRITE); nl = nleft; tl =& ~0377; while (*bp = *lp++) { if (*bp++ == '\n') { *--bp = 0; linebp = lp; break; } if (--nl == 0) { bp = getblock(tl=+0400, WRITE); nl = nleft; } } nl = tline; tline =+ (((lp-linebuf)+03)>>1)&077776; return(nl); } getblock(atl, iof) { extern read(), write(); register bno, off; bno = (atl>>8)&0377; off = (atl<<1)&0774; if (bno >= 255) { /* puts(TMPERR); */ errmsg(841,"file too large (TMPERR)"); } nleft = 512 - off; if (bno==iblock) { ichanged =| iof; return(ibuff+off); } if (bno==oblock) return(obuff+off); if (iof==READ) { if (ichanged) blkio(iblock, ibuff, write); ichanged = 0; iblock = bno; blkio(bno, ibuff, read); return(ibuff+off); } if (oblock>=0) blkio(oblock, obuff, write); oblock = bno; return(obuff+off); } blkio(b, buf, iofcn) int (*iofcn)(); { seek(tfile, b, 3); if ((*iofcn)(tfile, buf, 512) != 512) { /* puts(TMPERR); */ errmsg(870,"I/O error on temp file"); } } init() { register char *p; register pid; close(tfile); tline = 0; iblock = -1; oblock = -1; tfname = "/tmp/exxxxx"; ichanged = 0; pid = getpid(); for (p = &tfname[11]; p > &tfname[6];) { *--p = (pid&07) + '0'; pid =>> 3; } close(creat(tfname, 0600)); tfile = open(tfname, 2); brk(fendcore); dot = zero = dol = fendcore; endcore = fendcore - 2; } global(k) { register char *gp; register c; register int *a1; char globuf[GBSIZE]; if (globp) errmsg(905,"recursive global command"); setall(); nonzero(); if ((c=getchar())=='\n') errmsg(909,"missing global pattern"); compile(c); gp = globuf; while ((c = getchar()) != '\n') { if (c==EOF) errmsg(914,"missing global commands"); if (c=='\\') { c = getchar(); if (c!='\n') *gp++ = '\\'; } *gp++ = c; if (gp >= &globuf[GBSIZE-2]) errmsg(922,"global command list too long"); } *gp++ = '\n'; *gp++ = 0; for (a1=zero; a1<=dol; a1++) { *a1 =& ~01; if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k) *a1 =| 01; } for (a1=zero; a1<=dol; a1++) { if (*a1 & 01) { *a1 =& ~01; dot = a1; globp = globuf; commands(); a1 = zero; } } } substitute(inglob) { register gsubf, *a1, nl; int getsub(); gsubf = compsub(); /* 0 or 1 depending on 'g' */ for (a1 = addr1; a1 <= addr2; a1++) { if (execute(0, a1)==0) continue; inglob =| 01; dosub(); if (gsubf) { while (*loc2) { if (execute(1)==0) break; dosub(); } } *a1 = putline(); nl = append(getsub, a1); a1 =+ nl; addr2 =+ nl; } if (inglob==0) errmsg(974,"substitute pattern not found"); } compsub() { register seof, c; register char *p; int gsubf; if ((seof = getchar()) == '\n') errmsg(976,"missing sub string"); compile(seof); p = rhsbuf; for (;;) { c = getchar(); if (c=='\\') c = getchar() | 0200; if (c=='\n') errmsg(984,"missing string terminator"); if (c==seof) break; *p++ = c; if (p >= &rhsbuf[LBSIZE/2]) errmsg(989,"string2 too long"); } *p++ = 0; /* This checks for global */ if ((peekc = getchar()) == 'g' || peekc == 'G') { peekc = 0; newline(); return(1); } newline(); return(0); } getsub() { register char *p1, *p2; p1 = linebuf; if ((p2 = linebp) == 0) return(EOF); while (*p1++ = *p2++); linebp = 0; return(0); } dosub() { register char *lp, *sp, *rp; int c; lp = linebuf; sp = genbuf; rp = rhsbuf; while (lp < loc1) *sp++ = *lp++; while (c = *rp++) { if (c=='&') { sp = place(sp, loc1, loc2); continue; } else if (c<0 && (c =& 0177) >='1' && c < NBRA+'1') { sp = place(sp, braslist[c-'1'], braelist[c-'1']); continue; } *sp++ = c&0177; if (sp >= &genbuf[LBSIZE]) errmsg(1033,"sub string too long"); } lp = loc2; loc2 = sp + linebuf - genbuf; while (*sp++ = *lp++) if (sp >= &genbuf[LBSIZE]) errmsg(1039,"substituted string too big"); lp = linebuf; sp = genbuf; while (*lp++ = *sp++); } place(asp, al1, al2) { register char *sp, *l1, *l2; sp = asp; l1 = al1; l2 = al2; while (l1 < l2) { *sp++ = *l1++; if (sp >= &genbuf[LBSIZE]) errmsg(1055,"sub string too long"); } return(sp); } move(cflag) { register int *adt, *ad1, *ad2; int getcopy(); setdot(); nonzero(); if ((adt = address())==0) errmsg(1068,"missing move destination address"); newline(); ad1 = addr1; ad2 = addr2; if (cflag) { ad1 = dol; append(getcopy, ad1++); ad2 = dol; } ad2++; if (adt= ad2) { dot = adt++; reverse(ad1, ad2); reverse(ad2, adt); reverse(ad1, adt); } else errmsg(1091,"move destination not found"); } reverse(aa1, aa2) { register int *a1, *a2, t; a1 = aa1; a2 = aa2; for (;;) { t = *--a2; if (a2 <= a1) return; *a2 = *a1; *a1++ = t; } } getcopy() { if (addr1 > addr2) return(EOF); getline(*addr1++); return(0); } compile(aeof) { register eof, c; register char *ep; char *lastep; char bracket[NBRA], *bracketp; int nbra; int cclcnt; ep = expbuf; eof = aeof; bracketp = bracket; nbra = 0; if ((c = getchar()) == eof) { if (*ep==0) errmsg(1132,"null string illegal"); return; } circfl = 0; if (c=='^') { c = getchar(); circfl++; } if (c=='*') { /* if first = *, then quote it */ *ep++ = CCHR; *ep++ = c; c = 0; } peekc = c; for (;;) { if (ep >= &expbuf[ESIZE]) goto cerror; c = getchar(); if (c==eof) { *ep++ = CEOF; return; } if (c!='*') lastep = ep; switch (c) { case '\\': if ((c = getchar())=='(') { if (nbra >= NBRA){ printf("too many \("); goto cerror; } *bracketp++ = nbra; *ep++ = CBRA; *ep++ = nbra++; continue; } if (c == ')') { if (bracketp <= bracket){ printf("unbalanced ("); goto cerror; } *ep++ = CKET; *ep++ = *--bracketp; continue; } *ep++ = CCHR; if (c=='\n'){ printf("\\n illegal in pattern"); goto cerror; } *ep++ = c; continue; case '.': *ep++ = CDOT; continue; case '\n': printf("missing string terminator"); goto cerror; case '*': if (*lastep==CBRA || *lastep==CKET){ printf("illegal use of *"); goto cerror; } *lastep =| STAR; continue; case '$': if ((peekc=getchar()) != eof) goto defchar; *ep++ = CDOL; continue; case '[': *ep++ = CCL; *ep++ = 0; cclcnt = 1; if ((c=getchar()) == '^') { c = getchar(); ep[-2] = NCCL; } do { if (c=='\n'){ printf("missing ]"); goto cerror; } *ep++ = c; cclcnt++; if (ep >= &expbuf[ESIZE]){ printf("pattern too complicated"); goto cerror; } } while ((c = getchar()) != ']'); lastep[1] = cclcnt; continue; defchar: default: *ep++ = CCHR; *ep++ = c; } } cerror: expbuf[0] = 0; putchar('\n'); error; } execute(gf, addr) int *addr; { register char *p1, *p2, c; if (gf) { if (circfl) return(0); p1 = linebuf; p2 = genbuf; while (*p1++ = *p2++); locs = p1 = loc2; } else { if (addr==zero) return(0); p1 = getline(*addr); locs = 0; } p2 = expbuf; if (circfl) { loc1 = p1; return(advance(p1, p2)); } /* fast check for first character */ if (*p2==CCHR) { c = p2[1]; do { if (*p1!=c) continue; if (advance(p1, p2)) { loc1 = p1; return(1); } } while (*p1++); return(0); } /* regular algorithm */ do { if (advance(p1, p2)) { loc1 = p1; return(1); } } while (*p1++); return(0); } advance(alp, aep) { register char *lp, *ep, *curlp; char *nextep; lp = alp; ep = aep; for (;;) switch (*ep++) { case CCHR: if (*ep++ == *lp++) continue; return(0); case CDOT: if (*lp++) continue; return(0); case CDOL: if (*lp==0) continue; return(0); case CEOF: loc2 = lp; return(1); case CCL: if (cclass(ep, *lp++, 1)) { ep =+ *ep; continue; } return(0); case NCCL: if (cclass(ep, *lp++, 0)) { ep =+ *ep; continue; } return(0); case CBRA: braslist[*ep++] = lp; continue; case CKET: braelist[*ep++] = lp; continue; case CDOT|STAR: curlp = lp; while (*lp++); goto star; case CCHR|STAR: curlp = lp; while (*lp++ == *ep); ep++; goto star; case CCL|STAR: case NCCL|STAR: curlp = lp; while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); ep =+ *ep; goto star; star: do { lp--; if (lp==locs) break; if (advance(lp, ep)) return(1); } while (lp > curlp); return(0); default: errmsg(1376,"\"advance\" error (?)"); } } cclass(aset, ac, af) { register char *set, c; register n; set = aset; if ((c = ac) == 0) return(0); n = *set++; while (--n) if (*set++ == c) return(af); return(!af); } char line[70]; char *linp line; flush_buf() { if(linp>line) { write(1,line,linp-line); linp = line; } } puts2(as) { register char *sp; sp = as; while (*sp) putchar(*sp++); if(linp>line) { write(1,line,linp-line); linp=line; } } puts(as) { register char *sp; sp=as; col=0; while(*sp) putchar(*sp++); putchar('\n'); } putchar(ac) { register char *lp; register c; lp = linp; c = ac; if (listf) { col++; if (col >= 72) { col = 0; *lp++ = '\\'; *lp++ = '\n'; } if (c=='\t') { c = '>'; goto esc; } if (c=='\b') { c = '<'; esc: *lp++ = '-'; *lp++ = '\b'; *lp++ = c; goto out; } if (c<' ' && c!= '\n') { *lp++ = '\\'; *lp++ = (c>>3)+'0'; *lp++ = (c&07)+'0'; col =+ 2; goto out; } } *lp++ = c; out: if(c == '\n' || lp >= &line[64]) { linp = line; write(1, line, lp-line); return; } linp = lp; } are_you_sure() { register int c,n; if(!text_was_modified || fflg) return(0); while(1) { printf("\ndid you forget to save your text? "); for(n=0; n<5; n++) { flush_buf(); if((c=getchar())<=0) return(0); if(c != '\n') skip_rest(); switch(c) { case 'Y': case 'y': return(1); case 'N': case 'n': return(0); } printf("yes or no? "); } } } skip_rest() { register int c; while((c=getchar())>0 && c != '\n') {} } errmsg(n,s) char *s; { printf("%4d: %s\n",n,s); goto errlab; } gister int c,n; if(!text_was_modified || fflg) return(0); while(1) { printf("\ndid you forget to save your text? "); for(n=0; n<5; n++) { flush_buf(); if((c=getchar())<=0) return(0); if(c != '\n') skip_rest(); switch(c) { case 'Y': case 'y': return(1); case 'N': case 'n': return(0); # /* link * link communicator program * based on a program by D. C. Anderson * P.U. CAD Lab ME Dept. * * modified by : S. Mahler * D. Fouts * date : Jan 8, 1977 * more mods - 1/14/76 S.M. * Version : 2.00 */ # #define CR 0015 #define LF 0012 #define CTLB 0002 #define RUB 0177 #define CTLR 0022 #define CTLC 0003 #define BKSP 0010 #define SPACE 0040 #define CTLT 0024 #define CTLF 0006 #define CTLE 0005 #define CTLP 0020 #define CTLX 0030 #define UPRO 0136 #define LTRB 0102 #define TAB 011 #define LOG 014 #define QUIT 020 #define SEND 006 #define GET 024 #define LF 012 #define CR 015 #define EOT 021 #define LTRR 0122 #define LTRU 0125 #define CTLU 0025 #define CTLB 02 #define ATTEN 003 #define ESC 033 #define CTLS 023 #define CTLQ 021 #define SETUP 030 /* ctl-x */ #define CMND 036 /* RS */ char ul1[] "/tmp/procsyunlock1"; char ul2[] "/tmp/procsyunlock2"; char l1[] "/tmp/procsylock1"; char l2[] "/tmp/procsylock2"; char ttyf[] "/dev/ttyn"; int kbin,kbout,prin,prout,fflag,pid,kid,sflag; int prold[3],kbold[3]; int raw[] { 0,0,040 }; /* raw tty mode */ int column,select,stat1,stat2,ctlcknt; int quit(),force(); char port1,port2; main(argc,argv) int argc; char *argv[]; { int c,p; char buf[85]; fflag=0; sflag=0; port1= 'g'; port2= 'h'; stat1=stat2=999; /* | stats 1 and to will be set | +1 = avail | 00 = avail | -1 = avail */ if ( (stat(l1,buf) < 0 ) && (stat(ul1,buf) < 0 ) ) { stat1= -1; goto ps2; } stat1=0; if ( (stat(ul1,buf)) >= 0 ) { stat1=1; } ps2: if ( (stat(l2,buf) < 0 ) && (stat(ul2,buf) < 0 ) ) { stat2= -1; goto psf; } stat2=0; if( (stat(ul2,buf)) >= 0 ) { stat2=1; } psf: if ( argc == 1 ) { select=0; goto choose; } switch ( *argv[1] ) { case '1': select=1; break; case '2': select=2; break; default: select=0; } choose: if ( select == 2 ) goto choose2; switch ( stat1 ) { case -1: printf("\nProcsy Port 1 is out of service.\n"); control: if ( select == 1 ) exit(-1); else break; case 0: printf("\nProcsy Port 1 is IN USE.\n"); goto control; case 1: printf("\nLinking via Procsy Port 1.\n"); ttyf[8]= port1; goto begin; default: syserr: printf("PROCSY> System Error Notify Mahler.\n"); abort(); } choose2: if ( select == 1 ) goto noluck; switch ( stat2 ) { case -1: printf("Procsy Port 2 is out of service.\n"); break; case 0: printf("Procsy Port 2 is IN USE.\n"); break; case 1: printf("Linking via Procsy Port 2.\n"); ttyf[8]=port2; goto begin; default: goto syserr; } noluck: exit(); begin: if ( ttyf[8] == port1 ) { link( ul1,l1 ); unlink( ul1 ); }else{ link( ul2,l2 ); unlink( ul2 ); } if( ( prin= open( ttyf,0 ) ) <= 0 ){ printf(" can't open %s-input \n",ttyf); exit(); } if( ( prout= open( ttyf,1 ) ) <= 0 ){ printf(" can't open %s-output \n",ttyf); exit(); } kbin= dup(0); kbout= dup(1); gtty(kbin,&kbold); stty(kbin,&raw); gtty(prin,&prold); stty(prin,&raw); signal(1,1); signal(2,force); rstart: if ( (kid=fork()) < 0 ) { perror("Procsy> Can't Fork."); quit(); } if ( kid == 0 ) { if ( (execl("/bin/procsyrvs","procsyrvs",0)) < 0 ) perror("Procsy> Can't Exec."); quit(); } put1(prout,CTLB); newchar: read(kbin,&c,1); if ( sflag == 1 ) { kill(kid,1); sflag=0; goto newchar; } switch(c) { case CMND: unix(); break; case CTLQ: sflag=0; kill(kid,1); break; case CTLU: p=0; put1(kbout,UPRO); put1(kbout,LTRU); goto crlf; case CTLS: sflag=1; kill(kid,1); break; case BKSP: case RUB: if ( p == 0 ) break; put1(kbout,BKSP); put1(kbout,SPACE); put1(kbout,BKSP); p--; break; case CTLR: put1(kbout,UPRO); put1(kbout,LTRR); crlf: put1(kbout,CR); put1(kbout,LF); write(kbout,buf,p); break; case CR: case LF: buf[p++]= '\015'; write(prout,buf,p); p=0; put1(kbout,CR); break; case CTLB: p=0; put1(kbout,UPRO); put1(kbout,LTRB); put1(prout,CTLB); break; case CTLX: setup(); break; case CTLC: case CTLF: case CTLE: case CTLP: case CTLT: p=0; if ( c == CTLE ) c = CTLP; goto light; default: if ( p <= 85 ) { put1(kbout,c); buf[p++]=c; } break; } goto newchar; light: kill(kid,9); while ( wait() != kid ) ; switch( c ) { default: printf( "Procsy> System Error 'D'"); break; case GET: getpr(); c= CTLB; break; case SEND: sendpr(); c= CTLB; break; case CTLP: quit(); case ATTEN: atten: emul(); c= CTLB; break; case SETUP: setup(); c=CTLB; break; } goto rstart; } putit(fd,c) { if( c==TAB ) { tabout(fd); return; } put1(fd,c); if ( check(c) ) column++; else column=0; } tabout(fd) { int next; next= (column+8)&(0177770); while ( ++column < next ) put1(fd,' '); } check(c) { if( c==QUIT ) quit(); if ( c==CR || c==LF || c== 0177 || c==CTLB ) return(0); return(c); } waiteot(c) { put1(prout,c); while ( get1(prin) != EOT ); column=0; } get1(fd) { int c; read(fd,&c,1); return(c&0177); } put1(fd,c) { write(fd,&c,1); return(c); } gets(fd,str) int fd; char *str; { register char *s,c; s=str; while( check( c=get1(fd)) ) *s++= c; *s= '\0'; return(str); } puts(fd,str) int fd; char *str; { register char *s,c; s=str; while ( c= *s++) put1(fd,c); } quit() { if ( ttyf[8] == port1 ) { link( l1,ul1 ); unlink( l1 ); }else{ link( l2,ul2 ); unlink( l2 ); } stty(kbin,&kbold); stty(prin,&prold); signal(1,0); exit(); } sendpr() { register c,out,wdog; char buf[50]; int ufile[263],lines; lines=0; wdog=0; stty(kbin,&kbold); name: printf("\nUNIX filename: "); if( fopen(gets(kbin,buf),ufile) < 0 ) { printf("\nCan't open %s\n",buf); goto name; } printf("\nProcsy filename: "); gets(kbin,buf); puts(prout,"qru ttyset de=1 du=h ta=on es=off pa=off\015"); while( get1(prin) != EOT ); puts(prout,"qcr,\0"); puts(prout,buf); loop: waiteot(CR); wdog++; lines++; if( wdog == 20 ) { put1( kbout,'F' ); wdog=0; } while( (c=getc(ufile)) > 0 ) if( check(c) ) putit(prout,c); else goto loop; close(ufile[0]); waiteot(CR); puts(prout,"#s"); waiteot(CR); exit: ctlcknt=0; printf(" %d lines transfered - returning to link!",lines); stty(kbin,&raw); setup(); } getpr() { int ufd,wdog,sizeit; register c,p,lines; char buf[1600]; wdog=0; sizeit=sizeof(buf); stty(kbin,&kbold); uname: printf("\nUNIX filename: "); if( (ufd=creat(gets(kbin,buf),0666)) < 0 ) { printf("\nCan't create %s\n",buf); goto uname; } printf("\nProcsy filename: "); puts(prout,"qru ttyset de=1 du=h ta=on es=on pa=on ej=0\0"); waiteot(CR); gets(kbin,buf); puts(prout,"qdi,\0"); puts(prout,buf); puts(prout," ,sup\0"); lines=0; put1(prout,CR); for(;;) { p=0; while( (c=get1(prin)) != EOT ) { if( p>sizeit ) { printf("no EOT seen\n"); goto getout; } if( (buf[p++]=c) == CR ) { lines++; p--; if( wdog++ == 20 ) { wdog=0; put1( kbout,'T'); } } } if( buf[p-2]=='+' && buf[p-1]=='+') { write(ufd,buf,p-4); break; } if( p != 0 ) write(ufd,buf,p); put1(prout,ESC); } printf(" %d lines transfered - returning to link!",lines); getout: ctlcknt=0; setup(); put1( ufd,LF ); if( ufd>0 ) close(ufd); stty(kbin,&raw); nice(0); } emul() { char c,cl; ask: printf("\nContinue-Exit-or-Transfer (c/e/t) ? "); c='\015'; do { cl=c; read(kbin,&c,1); write(kbout,&c,1); } while ( c != '\015' ); printf("\015\012"); switch ( cl ) { case 'c': case 'C': return; case 't': case 'T': trans(); break; case 'e': case 'E': quit(); default: goto ask; } } trans() { char c,cl; c='\015'; printf("\nTo Procsy from UNIX (y/n) ? "); do { cl=c; read(kbin,&c,1); write(kbout,&c,1); } while ( c != '\015' ); if ( cl == 'y' || cl == 'Y' ) { sendpr(); return; } c='\015'; printf("\nTo UNIX from Procsy (y/n) ? "); do { cl=c; read(kbin,&c,1); write(kbout,&c,1); } while (c != '\015'); if ( cl == 'y' || cl == 'Y' ) { getpr(); return; } } force() { signal( 2,force ); put1( prout,CTLB ); fflag=1; if ( ctlcknt++ == 4 ) quit(); } setup() { puts(prout,"qru ttyset pa=on es=on de=1 ej=0 wi=137 fi=0 \015"); } unix() { int kpid,i,tpid,rstat; kill(kid,1); nice(2); puts(kbout,"\r\n%%% "); if( (kpid=fork()) == 0 ) { stty(kbin,&kbold); execl("/bin/sh","%%%% sh","-t",0); exit(); } if( kpid == -1) { perror("PROCSY> Can't shell fork()"); return; } while( (tpid=wait(&rstat)) != kpid ); puts(kbout,"\n___\n"); stty(kbin,&raw); kill(kid,1); put1(prout,CTLB); nice(0); } ); fflag=1; if ( ctlcknt++ == 4 ) quit(); } setup() { puts(prout,"qru ttyset pa=on es=on de=1 ej=0 wi=137 fi=0 \015"); } unix() { int kpid,i,tpid,rstat; kill(kid,1); nice(2); puts(kbout,"\r\n%%% "); if( (kpid=fork()) == 0 ) { stty(kbin,&kbold); execl("/bin/sh","%%%% sh","-t",0); exit(); } if( kpid == -1); ODT-11X -- Vunix1A ; 7 FEB 77 ** L. HUGGINS ; ;DIFFERENCES BETWEEN THIS VERSION AND THE ORIGINAL DEC OPERATION: ;I. USER PROGRAM DIFFERENCES ; A. Vunix1A does not reside in high core, but is intended ; to be assembled as a part of the user program, e.g. ; macro userfile1.m userfile2.m ... odt11x.m ; Alternately, the files may be linked using linkr, e.g. ; linkr userfile1.obj userfile1.obj ... odt11x.obj ; The resulting executable file will be named odt11x.out ; B. ODT must be executed first. ODT itself must then be ; used to start execution of the user program being ; debugged after setting desired breakpoints, etc. This ; is best accompolished by adding a JMP instruction as ; the first executable instruction of the user program, ; i.e. JMP O.ODT ; The effect of this is to move all the user program ; code 4 bytes higher in core. Normally, ODT would then ; start the user program by executing the following ; command: 4;g ; C. In the event the program being debugged "hangs" or ; if at any time during its execution a return to ODT is ; desired, this may be acheived by striking the SHIFT-CTRL-FS ; key (issue a quit) on the terminal. ODT should then respond ; with a "Bad Entry" breakpoint. Upon this reentry, ODT will ; remember all previously set breakpoints, but a ;g ; command will be necessary to resume program execution (a ; ;p is illegal after a Bad Entry). A Bad Entry also disables ; single instruction and testing modes. The address printed ; after the BE is that of the instruction following the one ; which actually caused the entry. ; D. It is not permissible to set ODT breakpoints within an ; area of pure text that has been linked to be shared. ODT ; modifies the program instruction codes when it inserts ; breakpoints. Generally it is best to relink the entire ; program to remove read-only restrictions before trying to ; debug using ODT. ; ;II. ODT COMMAND DIFFERENCES. ; A. Unix buffers an entire line of characters and waits till ; it receives a newline char before submitting any of the ; typed input to ODT. This implies the following: ; 1. The normal char erasure procedures are active ; 2. The LINE FEED, , and RETURN, , keys are normally ; both returned to ODT as the char. ; 3. All ODT commands must be terminated by typing a or ; key in order to be effected. ; B. The DEC ODT function of the key (close of an open ; word) is replaced with the char "c" ; C. The concept of a settable ODT priority has been dropped ; because of the operation under Unix. ; D. The character(s) is not discarded; therefore, it ; must not be used anywhere in an ODT command! ; E. As a convenience in single instruction mode a (or ) ; will, if no words are open, simulate the ;p command and ; cause execution of a single user program instruction. ; F. New commands. ; 1. A <$> followed immediately by a will cause the ; breakpoint time value of all registers to be printed (but ; not opened for modification). Similarily, a $b followed ; immediately by a will cause all breakpoint addresses ; to be listed. ; 2. A second new command is which allows a temporary ; escape from ODT to execute a line of text as a Unix ; command. The procedure is identical to that used by the ; text editor "ed". One of the more important uses of this ; feature is to call the Unix db & nm programs to combine their ; strengths with those of ODT. The maximum number of characters ; that may be entered on a line is 50. That limit may be ; easily increased by changing the value of the label O.MAXL ; 3. An ODT session may be terminated, i.e. return to Unix, ; by typing the % key, just like the program db. ; 4. The most powerful of the new commands allows one to ; detect whenever any specified word (or byte) content ; is either modified or reaches a specific value. This ; testing is accompolished in conjunction with the search ; mask. If, after initializing the mask and its associated ; two words as described below, ODT is operated in test ; mode the content of the designated address is tested ; every time a breakpoint is encountered. Of course, ; if ODT is operating in single instruction mode, this ; implies that the instruction which caused modification ; of the target address content can be detected. ; The use procedure is: ; a. Open the mask location, i.e. type $m/. After ; ODT prints the current value of the mask, type the ; value against which you wish to have the target ; address content compared (followed by a ). ; b. Step "a" results in a change of the mask and opens ; the next ODT word. Into this open word place the ; target address (followed again by a ). ; c. Step "b" stores the target address and opens the ; next ODT word (mask+4). The non-zero value placed ; in this location determines the type of testing ; which occurs on the target address content. If a ; positive number is placed in this location, the target ; address is treated as a word address; negative numbers ; (-1=177777) cause the target address to be treated as ; a byte address. If the absolute value of the content ; is 1, a breakpoint printout will occur whenever the ; content of the target address is identical to the ; content of the mask location. If the absolute value ; of the number in mask+4 is greater than 1, a ; printout will occur whenever the content of the ; target address differs from the mask, i.e. when the ; content of the target address has been modified. ; d. Set ODT into testing mode by typing the command ; ;2t. Actually, any non-zero value can appear ; after the semi-colon. The command ;t clears ; the test mode flag in ODT. These procedures ; exactly parallel those described in DEC's ODT ; manual for setting and clearing the single ; instruction mode flag. ; e. Once testing mode has been selected, the remaining ; procedures for using ODT are unchanged. If it is ; desired to have the target address tested after ; each instruction, ODT should be set to single ; instruction mode. Once execution of the user ; program has been started the content of the target ; address will be tested after each instruction. ; Of course, after the first single instruction ; breakpoint, it is possible to have the ; program execute many instructions without ODT ; returning control to the user (but still testing ; after each instruction) by use of the command ; N;p where N is the maximum number of instructions ; to execute with testing. In the event that the ; desired match occurs prior to completion of N ; instructions, ODT will print "te" followed by ; the address of the instruction following the ; one which modified the target address so as to ; meet the testing criterion. If, instead of testing ; after each instruction, the target address is to ; be tested only at each breakpoint, the same ; procedures should be followed without setting ; ODT to single instruction mode. ; f. The content of any register may be tested by ; specifying the target address as the ODT location ; at which the user registers are stored upon ; breakpoint entries. These addresses may be ; determined by opening the individual register ; locations, e.g. if it is desired to know the ; ODT address at which register 0 is stored proceed ; as follows: type $0/ to open the location ; of r0 and then type to open the adjacent ; location (which contains the stored r1 content) ; and print its ODT address; the r0 storage address ; is 2 less than where r1 is stored. It is possible ; to test on the contents of a register byte by ; specifying byte testing mode as explained above and ; then using the appropriate ODT register storage ; address for the byte to be tested. ; A word of caution is in order concerning the use ; of single instruction mode to execute large blocks ; of code. Program execution time increases by ; 1-2 orders of magnitude!. SYS = TRAP ;SYSTEM CALLS USE A TRAP TRAP EXIT=SYS+1 FORK=SYS+2 READ=SYS+3 WRITE=SYS+4 SWAIT=SYS+7 EXEC=SYS+11. SIGNAL=SYS+48. .GLOBL O.ODT .TITLE O.O.DT .NLIST SYM O.BKP = 16 ;NUMBER OF BREAKPOINTS-1 MULT. BY 2 TRT = 3 ;TRT INSTRUCTION FOR BREAK PTS O.TBT = 20 ;T-BIT MASK - STATUS REGISTER ; INITIALIZE ODT O.ODT: MOV SP,O.USP ;SAVE USER'S STACK MOV #O.UR0,SP ;NOW USE INTERNAL ODT STACK CLR O.S ;DISABLE SINGLE INSTR & TESTING MOVB #-1,O.P ;DISALLOW PROCEED SIGNAL ;CATCH BPT TRAPS 5,O.BRK SIGNAL ;CATCH QUIT SIGNAL 3,O.ENTR JMP O.RALL ;CLEAR BREAKPOINT TABLES ; LIST VALUE OF ALL STORED REGS AND STATUS O.ALLR: MOV #O.UR0,R2 ;LOC OF SAVED REGS MOV #O.RNAM,R1 ;ADDR OF SPECIAL REG NAMES MOV #"r/,R5 ;ASCII REG NAME MINUS 400 O.ALL0: MOV #2,O.BW ;SHOW WORD DATA O.ALL1: ADD #400,R5 ;CHANGE REG NAME O.ALL2: JSR R5,O.FTY1 ;PRINT REG NAME JSR R5,O.FTYP ;FOLLOWED BY = .BYTE '=,0 MOV (R2)+,R0 ;GET REG CONTENTS JSR R5,O.CADV ;OUTPUT THE VALUE MOV R5,R0 ;GET NO. INTO SWAB R0 ; LOW BYTE POSITION. CMPB R0,#'5 ;STILL 0-5? BLO O.ALL1 ;YES, DO NEXT ONE BHI O.ALL6 ;HAVE WE ISSUED NEW LINE? JSR R5,O.FTYP ;NO, START NEW LINE .BYTE 015,012 O.ALL6: CMPB R5,#'b ;PRINTING BREAKPOINTS? BNE O.ALL7 ;NO CMP R2,#O.ADR1+O.BKP+4;DONE? BLO O.ALL1 ;NO BR O.ALL5 O.ALL7: CMP R1,#O.RNAM+4 ;FINISHED WITH REGS? BHI O.ALL5 ;YES MOV (R1)+,R5 ;GET REG NAME BR O.ALL2 ;ONCE MORE ROUND MULBERRY BUSH O.ALL5: JSR R5,O.FTYP ; .BYTE 015,012 BR O.DCD ; SPECIAL NAME HANDLER ; DEPENDS UPON THE EXPLICIT ORDER OF THE TWO TABLES O.TL AND O.UR0 O.REGT: CMPB (R0),#012 ;IS NEXT? BEQ O.ALLR ;YES, PRINT ALL REGS MOV #O.TL,R4 ;TABLE START ADDRESS O.RSP: CMPB @R0,(R4)+ ;IS THIS THE CORRECT CHARACTER? BEQ O.SP ;JUMP IF YES CMP #O.TL+O.LG,R4 ;IS THE SEARCH DONE? BHI O.RSP ;BRANCH IF NOT MOVB @R0,R4 BICB #177770,R4 ;MASK OFF OCTAL O.SP1: ASL R4 ADD #O.UR0,R4 ;GENERATE ADDRESS INC R2 ;SET FOUND FLAG CMPB (R0)+,#'b ;ARE BREAKPOINTS DESIRED? BNE O.SCA1 ;NO CMPB (R0),#012 ;YES, ALL OF THEM? BNE O.SCA1 ;NO MOV #O.ADR1,R2 ;LOC OF BREAKPOINT ADDRESSES MOV #"b/,R5 ;ASCII NAME MINUS 400 BR O.ALL0 O.SP: SUB #O.TL-7,R4 ;GO FIND NEXT CHARACTER BR O.SP1 ; _ HANDLER - OPEN INDEXED ON THE PC O.ORPC: JSR R5,O.TCLS ;TEST WORD MODE AND CLOSE ADD @R2,R2 ;COMPUTE ADD #2,R2 ; NEW ADDRESS O.PCS: MOV R2,O.CAD ;UPDATE CAD JMP O.OP2A ;GO FINISH UP O.ORAB: JSR R5,O.TCLS ;TEST WORD MODE AND CLOSE MOV @R2,R2 ;GET ABSOLUTE ADDRESS BR O.PCS O.ORRB: JSR R5,O.TCLS ;TEST AND CLOSE MOVB @R2,R1 ;COMPUTE NEW ADDR & EXTEND SIGN ASL R1 ;R2=2(@R2) ADD #2,R1 ; +2 ADD R1,R2 ; +PC BR O.PCS O.TCLS: JSR PC,O.CLSE ;CLOSE CURRENT CELL CMP #2,O.BW ;ONLY WORD MODE ALLOWED BNE O.TCL1 ;BRANCH IF ERROR MOV O.CAD,R2 ;CURRENT ADDRESS IN R2 RTS R5 O.TCL1: TST (SP)+ BR O.ERR ;POP A WORD AND SHOW THE ERROR ; GO EXECUTE THE INPUT LINE AS A UNIX COMMAND O.UNIX: MOV R0,O.ARG2 ;SET UP SYS EXEC ARGUMENT O.UNN1: CMPB (R0)+,#012 ;END OF LINE? BNE O.UNN1 ;NO, CONTINUE LOOKING CLRB -(R0) ;MAKE A NULL BYTE FORK ;GO START UP OTHER COMMAND BR O.UNIN ;CHILD PROCESS START BCS O.ERR ;NO PROCESS SPACE AVAILABLE SWAIT ;WAIT FOR CHILD TO TERMINATE JSR R5,O.FTYP ;OUTPUT RETURN INDICATION .BYTE '!,012 ; A ! BR O.DCD ;RETURN TO ODT O.UNIN: EXEC ;CHILD EXECUTE COMMAND O.NAME,O.ARGS O.ARGS: O.NAME ;REPEAT PROGRAM NAME O.ARG1 O.ARG2: 0 ;VALUE INSERTED BY EXECUTION 0 ;TERMINATE TABLE ; PROCESS s - SINGLE INSTRUCTION MODE OR t - TEST MODE O.TEST: MOV #O.T,R3 ;SHOW IT'S TEST MODE BR O.SI0 O.SNGL: MOV #O.S,R3 ;SHOW SINGLE MODE O.SI0: TST R2 ;SEE IF TURN "ON" OR "OFF" BNE O.SI1 ;BRANCH IF TURNING IT ON CLRB (R3) ;CLEAR THE FLAG BR O.DCD ;CONTINUE THE SCAN O.SI1: MOVB #-1,(R3) ;SET THE FLAG BR O.DCD ; SEMI-COLON PROCESSOR O.SEMI: MOV R2,R3 ;A SEMI-COLON HAS BEEN RECEIVED MOV R4,R5 ;NUMERIC FLAG TO R3, CONTENTS TO R5 BR O.SCA0 ;GO BACK FOR MORE ; COMMAND DECODER - ODT11X ; ALL REGISTERS MAY BE USED (R0-R5), O.ERR: JSR R5,O.FTYP ; OUTPUT ? .BYTE '?,012 O.DCD: CLR O.BW ;CLOSE ALL JSR R5,O.FTYP ;TYPE * .BYTE 015,'* O.DCD2: CLR R3 ;R3 IS A SAVE REGISTER FOR R2 CLR R5 ;R5 IS A SAVE REGISTER FOR R4 ; GENERAL CHARACTER INPUT ROUTINE -- ODT11X ; AN ENTIRE LINE OF INPUT IS RETURNED IN THE BUFFER AREA O.ICHR O.MAXL = 50. ;MAXIMUM INPUT LINE LENGTH O.SCAN: CLR R0 ;TERMINAL FILE DESCRIPTOR READ ;GET ONE LINE FROM SYSTEM O.ICHR,O.MAXL CMP R0,#O.MAXL ;LINE LENGTH OK? BGE O.ERR ;NO, DUMP IT MOV #O.ICHR,R0 ;POINT TO BUFFER O.SCA0: CLR R4 ; R4 CONTAINS THE CONVERTED OCTAL CLR R2 ; R2 IS THE NUMBER FOUND FLAG O.SCA1: CMPB #'0,@R0 ;COMPARE WITH ASCII 0 BHI O.CLGL ;CHECK LEGALITY IF NON-NUMERIC CMPB #'7,@R0 ;COMPARE WITH ASCII 7 BLO O.CLGL ;CHECK LEGALITY IF NOT OCTAL MOVB (R0)+,R1 ;GET THE CHAR BIC #177770,R1 ;CONVERT TO BCD ASL R4 ; MAKE ROOM ASL R4 ; IN ASL R4 ; R4 ADD R1,R4 ;PACK THREE BITS IN R4 INC R2 ;R2 HAS NUMERIC FLAG BR O.SCA1 ; AND TRY AGAIN O.CLGL: CLR R1 ;CLEAR INDEX O.LGL1: CMPB @R0,O.LGCH(R1) ;DO CODES MATCH? BEQ O.LGL2 ;JUMP IF YES INC R1 ; SET INDEX FOR NEXT SEARCH CMP R1,#O.CLGT ;IS THE SEARCH DONE? BLO O.LGL1 ;RE-LOOP BR O.ERR ; OOPS! O.LGL2: ASL R1 ;MULTIPLY BY TWO INC R0 ;SKIP THE CHAR JMP @O.LGDR(R1) ;GO TO PROPER ROUTINE ; PROCESS / AND \ - OPEN WORD OR BYTE O.WRD: MOV #2,O.BW ;OPEN WORD BR O.WB1 O.BYT1: ROL R4 ;GET THE ADDRESS BACK O.BYT: MOV #1,O.BW ;OPEN BYTE O.WB1: TST R2 ;GET VALUE IF R2 IS NON-ZERO BEQ O.WRD1 ;SKIP OTHERWISE MOV R4,O.DOT ;PUT VALUE IN DOT MOV R4,O.CAD ; ALSO IN CAD O.WRD1: CMP #1,O.BW ;CHECK BYTE MODE BEQ O.WRD2 ;JUMP IF BYTE MOV O.CAD,R4 ASR R4 ;MOVE ONE BIT TO CARRY BCS O.BYT1 ;JUMP IF ODD ADDRESS MOV @O.CAD,R0 ;GET CONTENTS OF WORD BR O.WRD3 O.WRD2: MOVB @O.CAD,R0 ;GET CONTENTS OF BYTE O.WRD3: JSR R5,O.CADV ;GO GET AND TYPE OUT @CAD BR O.DCD2 ;GO BACK TO DECODER ; PROCESS c - CLOSE OPEN WORD/BYTE O.CRET: JSR PC,O.CLSE ;CLOSE LOCATION O.DCDA: BR O.DCD ;RETURN TO DECODER ; PROCESS , OPEN NEXT WORD O.OLD: INCB O.SEQ ;SET NEED O.DOT TO O.CAD MOVE O.OP1: TST O.BW ;ANYTHING OPEN? BNE O.OP6 ;YES, OPEN NEXT ONE TSTB O.S ;NO, MAYBE ;P FOR SNGL STEP O.ERR2: BEQ O.ERR ;NO, ERROR JMP O.PROC ;SIMULATE A ;P O.OP6: JSR PC,O.CLSE ;CLOSE PRESENT CELL TSTB O.SEQ ;SEE IF < COMMAND BEQ O.OP5 ;BRANCH IF NOT MOV O.DOT,O.CAD ;GO TO THE FORMER STREAM O.OP5: CLRB O.SEQ ;CLEAR THE FLAG ADD O.BW,O.CAD ;GENERATE NEW ADDRESS O.OP2: MOV O.CAD,O.DOT ;INITIALIZE DOT O.OP2A: JSR R5,O.FTYP ; .BYTE 015,0 MOV O.BW,-(SP) ;SAVE BW MOV #2,O.BW ;SET TO TYPE FULL WORD ADDRESS MOV O.CAD,R0 ;NUMBER TO TYPE JSR R5,O.CADV ; TYPE OUT ADDRESS MOV @SP,O.BW ;RESTORE BW DEC (SP)+ ;IS IT BYTE MODE? BEQ O.OP3 ;JUMP IF YES MOV #'/,R5 ;TYPE A / O.OP4: JSR R5,O.FTY1 BR O.WRD1 ;GO PROCESS IT O.OP3: MOV #'\,R5 ;TYPE A \ BR O.OP4 ; PROCESS ^, OPEN PREVIOUS WORD O.BACK: TST O.BW ; ^ RECEIVED BEQ O.ERR2 ;ERROR IF NOTHING OPEN JSR PC,O.CLSE SUB O.BW,O.CAD ;GENERATE NEW ADDRESS BR O.OP2 ;GO DO THE REST ; b HANDLER - SET AND REMOVE BREAKPOINTS O.BKPT: MOV #O.TRTC,R0 ASL R4 ;MULTIPLY NUMBER BY TWO TST R3 BEQ O.REMB ;IF R3 IS ZERO GO REMOVE BREAKPOINT ASR R5 ;GET ONE BIT TO CARRY BCS O.ERR1 ;BADNESS IF ODD ADDRESS ASL R5 ;RESTORE ONE BIT ADD #O.ADR1,R4 TST R2 BNE O.SET1 ;JUMP IF SPECIFIC CELL O.SET: CMP R0,@R4 ;IS THIS CELL FREE? BEQ O.SET1 ;JUMP IF YES CMP R4,#O.BKP+O.ADR1;ARE WE AT THE END OF OUR ROPE BHIS O.ERR1 ;YES, THERE IS NOTHING FREE TST (R4)+ ;INCREMENT BY TWO BR O.SET O.SET1: CMP R4,#O.BKP+O.ADR1 BHI O.ERR1 ;ERROR IF TOO LARGE MOV R5,@R4 ;SET BREAKPOINT BR O.DCDA ;RETURN O.REMB: TST R2 BEQ O.RALL ;GO REMOVE ALL CMP R4,#O.BKP BHI O.ERR1 ;JUMP IF NUMBER TOO LARGE MOV R0,O.ADR1(R4) ;CLEAR BREAKPOINT CLR O.CT(R4) ;CLEAR COUNT ALSO O.DCDB: BR O.DCDA O.RALL: CLR R4 MOV #O.TRTC,R0 O.RM1: CMP R4,#O.BKP+2 ;ALL DONE? BHI O.DCDA ;JUMP IF YES MOV R0,O.ADR1(R4) ;RESET BKPT MOV #TRT,O.UIN(R4) ;RESET CONTENTS OF TABLE CLR O.CT(R4) ;CLEAR COUNT TST (R4)+ ;INCREMENT BY TWO BR O.RM1 ; PROCESS o, COMPUTE OFFSET O.OFST: CMP #2,O.BW ;CHECK WORD MODE BNE O.ERR1 ;ERROR IF NOT CORRECT MODE TST R3 ;WAS SEMI-COLON TYPED? BEQ O.ERR1 ;NO, CALL IT AN ERROR O.OF2: SUB O.CAD,R5 ;COMPUTE DEC R5 DEC R5 ; 16 BIT OFFSET MOV R5,R0 JSR R5,O.CADV ;NUMBER IN R0 - WORD MODE MOV R5,R0 ASR R0 ;DIVIDE BY TWO BCS O.OF1 ;ERROR IF ODD CMP #-200,R0 ;OUT OF BRANCH RANGE? BGT O.OF1 ;YES, DO NOT TYPE CMP #177,R0 ;WHAT ABOUT FORWARD BR? BLT O.OF1 ;IT'S OUT OF RANGE DEC O.BW ;SET TEMPORARY BYTE MODE JSR R5,O.CADV ;NUMBER IN R0 - BYTE MODE INC O.BW ;RESTORE WORD MODE O.OF1: JMP O.DCD2 ;ALL DONE ; SEARCHES - $MSK HAS THE MASK ; $MSK+2 HAS THE FWA ; $MSK+4 HAS THE LWA O.EFF: INC R1 ;SET EFFECTIVE SEARCH BR O.WDS O.WSCH: CLR R1 ;SET WORD SEARCH O.WDS: TST R3 ;CHECK FOR OBJECT FOUND BEQ O.ERR1 ;ERROR IF NO OBJECT MOV #2,O.BW ;SET WORD MODE MOV O.MSK+2,R2 ;SET ORIGIN MOV O.MSK,R4 ;SET MASK COM R4 O.WDS2: CMP R2,O.MSK+4 ; IS THE SEARCH ALL DONE? BHI O.DCDB ; YES MOV @R2,R0 ; GET OBJECT TST R1 ;NO BNE O.EFF1 ;BRANCH IF EFFECTIVE SEARCH XOR R5,R0 O.WDS3: BNE O.WDS4 ;RE-LOOP IF NO MATCH MOV R4,-(SP) ;REGISTERS R2,R4, AND R5 ARE SAFE MOV R2,R0 ;GET READY TO TYPE JSR R5,O.CADV ; TYPE ADDRESS JSR R5,O.FTYP ;TYPE / .BYTE '/,0 MOV @R2,R0 ;GET CONTENTS JSR R5,O.CADV ;TYPE CONTENTS JSR R5,O.FTYP .BYTE 015,012 MOV (SP)+,R4 ; RESTORE R4 O.WDS4: TST (R2)+ ;INCREMENT TO NEXT CELL AND BR O.WDS2 ; RETURN O.ERR1: JMP O.ERR ;INTERMEDIATE HELP O.EFF1: CMP R0,R5 ; IS (X)=K? BEQ O.WDS3 ;TYPE IF EQUAL MOV R0,R3 ;(X) TO R3 ADD R2,R3 ;(X)+X INC R3 INC R3 ;(X)+X+2 CMP R3,R5 ;IS (X)+X+2=K? BEQ O.WDS3 ;BRANCH IF EQUAL MOVB R0,R0 ASL R0 ;MULTIPLY BY TWO INC R0 INC R0 ADD R2,R0 ;ADD PC CMP R0,R5 ;IS THE RESULT A PROPER REL. BRANCH? BR O.WDS3 ; PROCESS g - GO O.GO: TST R3 ;WAS K; TYPED? BEQ O.ERR1 ; TYPE ? IF NOT ASR R5 ;CHECK LOW ORDER BIT BCS O.ERR1 ;ERROR IF ODD NUMBER ASL R5 ;RESTORE WORD MOV R5,O.UPC ;SET UP NEW PC O.TBIT: CLRB O.TB ;CLEAR T-BIT FLAG BIS #O.TBT,O.UST ;SET T-BIT JUST IN CASE TSTB O.S ;SINGLE INSTRUCTION MODE? BNE O.GO2 ;YES, PROCEED WITH T-BIT SET BIC #O.TBT,O.UST ;NO, CLEAR T-BIT O.GO1: MOV #O.BKP,R4 ;RESTORE ALL BREAKPOINTS O.RS1: MOV @O.ADR1(R4),O.UIN(R4) ;SAVE CONTENTS MOV O.TRTC,@O.ADR1(R4) ;REPLACE WITH TRT SUB #2,R4 ;POINT TO NEXT ONE BGE O.RS1 ;RE-LOOP UNTIL DONE O.GO2: MOV (SP)+,R0 ;RESTORE MOV (SP)+,R1 MOV (SP)+,R2 ; REGISTERS MOV (SP)+,R3 ; 1 MOV (SP)+,R4 ; THRU MOV (SP)+,R5 ; 5 MOV O.USP,SP ;RESTORE USER STACK MOV O.UST,-(SP) ; AND STATUS MOV O.UPC,-(SP) ; AND PC O.RTIT: RTT ;THIS IS "RTI" IF 11/20... ;..."RTT" IF 11/45 OR 11/70 ; PROCESS p - PROCEED ; ONLY ALLOWED AFTER A BREAKPOINT O.PROC: MOVB O.P,R0 ;ILLEGAL TO PROCEED? BLT O.ERR1 ;NOT LEGAL TST R2 ;CHECK FOR ILLEGAL COUNT BNE O.ERR1 ;JUMP IF ILLEGAL MOV R5,O.CT(R0) ;YES, PUT AWAY COUNT O.TBI1: TSTB O.S ;SEE IF SINGLE INSTR MODE BNE O.TBIT ;IF SO, EXIT NOW INCB O.TB ;SET T-BIT FLAG BIS #O.TBT,O.UST ;SET T-BIT BR O.GO2 ; BREAKPOINT HANDLER O.ENTR: MOVB #-1,O.P ;QUIT SIGNAL, DISALLOW PROCEED, CLR O.S ; SINGLE STEP AND TESTING. MOV R0,-(SP) ;TEMP STORE TO PERMIT SIGNAL CALL SIGNAL ;RESET QUIT SIGNAL 3,O.ENTR MOV (SP)+,R0 ;RESTORE QUIT TIME R0 O.BRK: MOV (SP)+,O.UPC ;SAVE STATUS AND PC MOV (SP)+,O.UST MOV SP,O.USP ;SAVE USER STACK ADDRESS MOV #O.USP,SP ;SET TO INTERNAL STACK MOV R5,-(SP) ;SAVE MOV R4,-(SP) ; REGISTERS MOV R3,-(SP) ;0 MOV R2,-(SP) ; THRU MOV R1,-(SP) ; 5 MOV R0,-(SP) MOV O.UPC,R5 ;GET PC, IT POINTS TO THE TRT TSTB O.TB ;T-BIT SET? BNE O.TBIT ;YES MOV #O.BKP,R4 ;REMOVE ALL BREAKPOINTS O.R1: MOV O.UIN(R4),@O.ADR1(R4) ;CLEAR BREAKPOINT SUB #2,R4 ;POINT TO NEXT BREAKPOINT BGE O.R1 ;RE-LOOP UNTIL DONE TSTB O.S ;SEE IF SINGLE INSTRUCTION IS GOING BNE O.B4 ;IF SO, HANDLE THERE TST -(R5) ;POINT TO BREAK ADDR MOV R5,O.UPC MOV #O.BKP,R4 ;GET A COUNTER O.B1: CMP R5,O.ADR1(R4) ;COMPARE WITH LIST BEQ O.B2 ;JUMP IF FOUND SUB #2,R4 BGE O.B1 ;RE-LOOP UNTIL FOUND JSR R5,O.FTYP ;NOTHING FOUND, SHOW .BYTE 'B,'E ; A BAD ENTRY MOV R5,R0 TST (R0)+ ;POP OVER ABOVE ADJUSTMENT MOV R0,O.UPC BR O.B3 ; & CONTINUE O.B4: MOVB #O.BKP+2,R4 ;SET BREAK POINT HIGH + 1 MOV R5,O.ADR1(R4) ;STORE NEXT PC VALUE FOR TYPE OUT O.B2: MOVB R4,O.P ;ALLOW PROCEED TSTB O.T ;TESTING MODE? BEQ O.T0 ;NO, GET ON WITH IT MOV #O.MSK,R2 ;POINT TO TEST INFO MOV (R2)+,R4 ;GET COMPARISON MASK MOV (R2)+,R3 ;ADDR FOR TESTING MOV (R2)+,R2 ;TYPE OF TEST BMI O.T5 ;IT'S A BYTE TEST BIC #1,R3 ;MAKE SURE IT'S A WORD ADDR DEC R2 ;TEST FOR AGREE OR DISAGREE? BEQ O.T4 ;AGREE CMP R4,(R3) ;TEST FOR DISAGREEMENT O.T8: BEQ O.T1 ;SAME, RESUME BR O.T7 ;IT'S DIFFERENT, TELL WORLD O.T4: CMP R4,(R3) ;IDENTICAL? BR O.T9 O.T5: INC R2 ;TEST AGREE OR DISAGREE? BEQ O.T6 ;AGREE CMPB R4,(R3) ;TEST FOR DISAGREEMENT BR O.T8 O.T6: CMPB R4,(R3) ;ANY CHANGE? O.T9: BNE O.T1 ;NO, FORWARD MARCH O.T7: JSR R5,O.FTYP ;SHOW TEST CONSITIONS MET. .BYTE 't,'e MOV R5,R0 ;GET BREAK ADDR BR O.B3 O.T1: MOVB O.P,R4 ;GET BREAKPOINT NO. BACK O.T0: DEC O.CT(R4) BGT O.TBI1 ;JUMP IF REPEAT INC O.CT(R4) ;RESET COUNT MOVB R4,R5 ASR R5 SWAB R5 ;PUT IN HIGH BYTE ADD #"b0,R5 ;ASCII BREAKPOINT NAME JSR R5,O.FTY1 MOV #2,O.BW ; SET WORD MODE JSR R5,O.FTYP ;PRINT ; .BYTE ';,0 MOV O.ADR1(R4),R0 ;GET ADDRESS OF BREAK O.B3: JSR R5,O.CADV ;TYPE ADDRESS JMP O.ALL5 ; THEN TO DECODER ; TYPE OUT CONTENTS OF WORD OR BYTE WITH ONE TRAILING SPACE ; WORD IS IN R0 O.CADV: MOV #6,R3 ;# OF DIGITS MOV #-2,R4 ;# OF BITS FIRST-3 MOV R5,-(SP) ;MAKE R5 AVAILABLE CMP #1,O.BW ;SEE IF WORD MODE BNE O.SPC ;BRANCH IF SO SUB #3,R3 ;ONLY DO 3 DIGITS INC R4 ;DO 2 BITS FIRST SWAB R0 ;AND TURN R0 AROUND O.SPC: MOV R0,-(SP) ;SAVE R0 O.V3: CLR R5 O.V0: ADD #3,R4 ;COMPUTE THE NUMBER OF BITS TO DO CLR R0 O.V1: ROL (SP) ;GET A BIT ROL R0 ;STORE IT AWAY DEC R4 ;DECREMENT COUNTER BGT O.V1 ;LOOP IF MORE BITS NEEDED ADD #'0,R0 ;CONVERT TO ASCII BIS R0,R5 ;PUT ASCII CHAR IN R5 DEC R3 ;SEE IF MORE TO DO BLE O.V2 ;EXIT SWAB R5 TSTB R5 ;BOTH DIGITS READY? BEQ O.V0 ;NO, GET ANOTHER JSR R5,O.FTY1 ;TYPE THEM OUT BR O.V3 O.V2: SWAB R5 ;PUT CHARS IN PROPER ORDER JSR R5,O.FTY1 ;OUTPUT LAST CHAR(S) TST (SP)+ ;GET RID OF JUNK MOV (SP)+,R5 ;RESTORE RETURN ADDR MOV #040,O.OCHR ;PUT A IN BUFFER BR O.FTY3 ;FALL THRU TO PRINT IT ; GENERAL CHAR OUTPUT ROUTINE FOR 1 OR 2 CHARACTERS. IF ONLY ; 1 CHAR IS TO BE SENT, THE HIGH BYTE OF THE CHAR WORD MUST ; BE 0. ; O.FTY1 IS THE ENTRY IF THE CHAR(S) WAS IN R5 PRIOR TO THE ; CALL (WHICH PUTS IT ON THE STACK FOR SUBROUTINE EXECUTION.) O.FTY1: MOV (SP),O.OCHR ;MOV CHAR(S) TO BUFFER BR O.FTY2 O.FTYP: MOV (R5)+,O.OCHR ;CHAR(S) TO OUTPUT BUFFER O.FTY2: CLR R0 ;USE TERMINAL FILE DESCRIPTOR TSTB O.OCHR+1 ;1 OR 2 CHARACTERS? BEQ O.FTY3 ;ONLY 1 WRITE,O.OCHR,2 ;OUTPUT TWO CHARS RTS R5 O.FTY3: WRITE,O.OCHR,1 ;OUTPUT A CHAR RTS R5 ; CLOSE WORD OR BYTE AND EXIT, ; UPON ENTERING, R2 HAS NUMERIC FLAG, R4 HAS CONTENTS O.CLSE: TST R2 ;IF NO NUMBER WAS TYPED THERE IS BEQ O.CLS1 ;NO CHANGE TO THE OPEN CELL CMP #1,O.BW BEQ O.CLS2 ;JUMP IF BYTE MODE BHI O.CLS1 ;JUMP IF ALREADY CLOSED MOV R4,@O.CAD ;STORE WORD RTS PC O.CLS2: MOVB R4,@O.CAD ;STORE BYTE O.CLS1: RTS PC O.EXIT: EXIT ;BACK TO STD UNIX O.LGDR: O.SEMI ; ; SEMI-COLON O.WRD ; / OPEN WORD O.BYT ; \ OPEN BYTE O.CRET ; c CLOSE O.REGT ; $ REGISTER OPS O.GO ; g GO TO ADDRESS K O.OP1 ; MODIFY, CLOSE, OPEN NEXT O.ORPC ; _ OPEN RELATED, INDEX - PC O.OLD ; < RETURN TO OLD SEQUENCE AND OPEN O.BACK ; ^ OPEN PREVIOUS O.OFST ; o OFFSET O.WSCH ; w SEARCH WORD O.EFF ; e SEARCH EFFECTIVE ADDRESS O.BKPT ; b BREAKPOINTS O.PROC ; p PROCEED O.ORAB ; @ OPEN RELATED, ABSOLUTE O.ORRB ; > OPEN RELATED, REL. BRANCH O.SNGL ; s SINGLE INSTRUCTION MODE O.TEST ; t TEST MODE O.UNIX ; ! EXECUTE UNIX FOR A WHILE O.EXIT ; BACK TO UNIX O.LGL = .-O.LGDR ;LGL MUST EQUAL 2X CHLGT ALWAYS O.BW: 0 ; =0 - ALL CLOSED, ; =1 - BYTE OPEN, ; =2 - WORD OPEN O.DOT: 0 ; ORIGIN ADDRESS O.WDFG: .BYTE 0 ;SEARCH FLAG = 1 - EFFECTIVE O.TB: .BYTE 0 ;T-BIT FLAG ; = 0 - WORD O.P: .BYTE 0 ;PROCEED FLAG = -2 IF MANUAL ENTRY ; -1 IF NO PROCEED ALLOWED ; 0-7 IF ALLOWED O.SEQ: .BYTE 0 ;FLAG FOR < COMMAND O.LGCH: .BYTE '; ; .BYTE '/ ; / .BYTE '\ ; \ .BYTE 'c ; c - CLOSE .BYTE '$ ; $ .BYTE 'g ; g .BYTE 012 ; .BYTE '_ ; _ .BYTE '< ; < .BYTE '^ ; ^ .BYTE 'o ; o .BYTE 'w ; w .BYTE 'e ; e .BYTE 'b ; b .BYTE 'p ; p .BYTE '@ ; @ .BYTE '> ; > .BYTE 's ; s .BYTE 't ; t .BYTE '! ; ! .BYTE '% ; % - EXIT O.CLGT = .-O.LGCH ;TABLE LENGTH O.TL: .BYTE 's ;DO 1 .BYTE 0 ;NOT 2 .BYTE 'm ;CHANGE 3 .BYTE 0 ;THE 4 .BYTE 0 ;ORDER 5 .BYTE 'b ;HERE 6 O.LG = .-O.TL O.NAME: .ASCIZ @/bin/sh@ O.ARG1: .ASCIZ /-c/ .EVEN O.TRTC: TRT ;TRT USED FOR BREAK POINTS O.RNAM: .BYTE 's,'p ;SPECIAL REG NAMES MUST START ; & END ON WORD BOUNDARY. .BYTE 'p,'c .BYTE 's,'t O.S: .BYTE 0 ;SINGLE INSTR FLAG(NEEDS WORD BNDY) ;0 IF NOT ACTIVE ;-1 IF ACTIVE ;NO BREAK BOINTS MAY BE SET WHILE IN ;SINGLE INSTRUCTION MODE O.T: .BYTE 0 ; TEST FLAG (MUST BE ADJACENT O.S) O.OCHR: .BYTE 0,0 ;OUTPUT BUFFER(NEEDS WORD BOUNDARY) O.ICHR: ;INPUT LINE BUFFER . = .+O.MAXL .EVEN ;THE ORDER OF THE FOLLOWING ENTRIES IS CRITICAL . = .+14 ;ALLOW FOR ODT'S STACK O.UR0: 0 ;USER R0 0 ; R1 0 ; R2 0 ; R3 0 ; R4 0 ; R5 O.USP: 0 ;USER SP O.UPC: 0 ;USER PC O.UST: 0 ;USER ST O.PRI: 0 ;ODT PRIORITY (NOT USED IN Vunix1A) O.CAD = O.PRI ;USE O.PRI TO STORE CURRENT ADDR O.MSK: 0 ;MASK 0 ;LOW LIMIT 0 ;HIGH LIMIT ; BREAK POINT LISTS, ADR1 = ADRESS OF BREAKPOINT,CT = COUNT, ; UIN = CONTENTS O.ADR1: . = .+O.BKP+4 O.CT: . = .+O.BKP+4 O.UIN: . = .+O.BKP+4 .END R OF THE FOLLOWING ENTRIES IS CRITICAL/ ODT-11X -- Vunix1A / 7 FEB 77 ** L. HUGGINS / /DIFFERENCES BETWEEN THIS VERSION AND THE ORIGINAL DEC OPERATION: /I. USER PROGRAM DIFFERENCES / A. Vunix1A does not reside in high core, but is intended / to be assembled as a part of the user program, e.g. / as userfile1.s userfile2.s ... odt11x.s / B. ODT must be executed first. ODT itself must then be / used to start execution of the user program being / debugged after setting desired breakpoints, etc. This / is best accompolished by adding a JMP instruction as / the first executable instruction of the user program, / i.e. JMP O.ODT / The effect of this is to move all the user program / code 4 bytes higher in core. Normally, ODT would then / start the user program by executing the following / command: 4;g / C. In the event the program being debugged "hangs" or / if at any time during its execution a return to ODT is / desired, this may be acheived by striking the SHIFT-CTRL-FS / key (issue a quit) on the terminal. ODT should then respond / with a "Bad Entry" breakpoint. Upon this reentry, ODT will / remember all previously set breapoints, but a ;g / command will be necessary to resume program execution (a / ;p is illegal after a Bad Entry). A Bad Entry also disables / single instruction and testing modes. The address printed / after the BE is that of the instruction following the one / which actually caused the entry. / D. It is not permissible to set ODT breadpoints within an / area of pure text that has been linked to be shared. ODT / modifies the program instruction codes when it inserts / breakpoints. Generally it is best to relink the entire / program to remove read-only restrictions before trying to / debug using ODT. / /II. ODT COMMAND DIFFERENCES. / A. Unix buffers an entire line of characters and waits till / it receives a newline char before submitting any of the / typed input to ODT. This implies the following: / 1. The normal char erasure procedures are active / 2. The LINE FEED, , and RETURN, , keys are normally / both returned to ODT as the char. / 3. All ODT commands must be terminated by typing a or / key in order to be effected. / B. The DEC ODT function of the key (close of an open / word) is replaced with the char "c" / C. The concept of a settable ODT priority has been dropped / because of the operation under Unix. / D. The character(s) is not discarded; therefore, it / must not be used anywhere in an ODT command! / E. As a convenience in single instruction mode a (or ) / will, if no words are open, simulate the ;p command and cause / execution of a single user program instruction. / F. New commands. / 1. A <$> followed immediately by a will cause the / breakpoint time value of all registers to be printed (but / not opened for modification). Similarily, a $b followed / immediately by a will cause all breakpoint addresses / to be listed. / 2. A second new command is which allows a temporary / escape from ODT to execute a line of text as a Unix / command. The procedure is identical to that used by the / text editor "ed". One of the more important uses of this / feature is to call the Unix db & nm programs to combine their / strengths with those of ODT. The maximum number of characters / that may be entered on a line is 50. That limit may be / easily increased by changing the value of the label O.MAXL / 3. An ODT session may be terminated, i.e. return to Unix, / by typing the % key, just like the program db. / 4. The most powerful of the new commands allows one to / detect whenever any specified word (or byte) content / is either modified or reaches a specific value. This / testing is accompolished in conjunction with the search / mask. If, after initializing the mask and its associated / two words as described below, ODT is operated in test / mode the content of the designated address is tested / every time a breakpoint is encountered. Of course, / if ODT is operating in single instruction mode, this / implies that the instruction which caused modification / of the target address content can be detected. / The use procedure is: / a. Open the mask location, i.e. type $m/. After / ODT prints the current value of the mask, type the / value against which you wish to have the target / address content compared (followed by a ). / b. Step "a" results in a change of the mask and opens / the next ODT word. Into this open word place the / target address (followed again by a ). / c. Step "b" stores the target address and opens the / next ODT word (mask+4). The non-zero value placed / in this location determines the type of testing / which occurs on the target address content. If a / positive number is placed in this location, the target / address is treated as a word address; negative numbers / (-1=177777) cause the target address to be treated as / a byte address. If the absolute value of the content / is 1, a breakpoint printout will occur whenever the / content of the target address is identical to the / content of the mask location. If the absolute value / of the number in mask+4 is greater than 1, a / printout will occur whenever the content of the / target address differs from the mask, i.e. when the / content of the target address has been modified. / d. Set ODT into testing mode by typing the command / ;2t. Actually, any non-zero value can appear / after the semi-colon. The command ;t clears / the test mode flag in ODT. These procedures / exactly parallel those described in DEC's ODT / manual for setting and clearing the single / instruction mode flag. / e. Once testing mode has been selected, the remaining / procedures for using ODT are unchanged. If it is / desired to have the target address tested after / each instruction, ODT should be set to single / instruction mode. Once execution of the user / program has been started the content of the target / address will be tested after each instruction. / Of course, after the first single instruction / breakpoint, it is possible to have the / program execute many instructions without ODT / returning control to the user (but still testing / after each instruction) by use of the command / N;p where N is the maximum number of instructions / to execute with testing. In the event that the / desired match occurs prior to completion of N / instructions, ODT will print "te" followed by / the address of the instruction following the / one which modified the target address so as to / meet the testing criterion. If, instead of testing / after each instruction, the target address is to / be tested only at each breakpoint, the same / procedures should be followed without setting / ODT to single instruction mode. / f. The content of any register may be tested by / specifying the target address as the ODT location / at which the user registers are stored upon / breakpoint entries. These addresses may be / determined by opening the individual register / locations, e.g. if it is desired to know the / ODT address at which register 0 is stored proceed / as follows: type $0/ to open the location / of r0 and then type to open the adjacent / location (which contains the stored r1 content) / and print its ODT address; the r0 storage address / is 2 less than where r1 is stored. It is possible / to test on the contents of a register byte by / specifying byte testing mode as explained above and / then using the appropriate ODT register storage / address for the byte to be tested. / A word of caution is in order concerning the use / of single instruction mode to execute large blocks / of code. Program execution time increases by / 1-2 orders of magnitude!. .globl o.odt o.bkp = 16 /number of breakpoints-1 mult. by 2 trt = 3 /trt instruction for break pts o.tbt = 20 /t-bit mask - status register rtt = 6 / initialize odt o.odt: mov sp,o.usp /save user's stack mov $o.ur0,sp /now use odt internal stack clr o.s /disable single instr & testing movb $-1,o.p /disallow proceed sys signal;5;o.brk /catch bpt traps sys signal;3;o.entr /catch quit signal jmp o.rall /clear breakpoint tables / list value of all stored regs and status o.allr: mov $o.ur0,r2 /loc of saved regs mov $o.rnam,r1 /addr of special reg names mov $"r/,r5 /ascii reg name minus 400 o.all0: mov $2,o.bw /show word data o.all1: add $400,r5 /change reg name o.all2: jsr r5,o.fty1 /print reg name jsr r5,o.ftyp /followed by = .byte '=,0 mov (r2)+,r0 /get reg contents jsr r5,o.cadv /output the value mov r5,r0 /get no. into swab r0 / low byte position. cmpb r0,$'5 /still 0-5? blo o.all1 /yes, do next one bhi o.all6 /have we issued new line? jsr r5,o.ftyp /no, start new line .byte 015,012 o.all6: cmpb r5,$'b /printing breakpoints? bne o.all7 /no cmp r2,$o.adr1+o.bkp+4/done? blo o.all1 /no br o.all5 o.all7: cmp r1,$o.rnam+4 /finished with regs? bhi o.all5 /yes mov (r1)+,r5 /get next reg name br o.all2 /once more round mulberry bush o.all5: jsr r5,o.ftyp / .byte 015,012 br o.dcd / special name handler / depends upon the explicit order of the two tables o.tl and o.ur0 o.regt: cmpb (r0),$012 /is next? beq o.allr /yes, print all regs mov $o.tl,r4 /table start address o.rsp: cmpb *r0,(r4)+ /is this the correct character? beq o.sp /jump if yes cmp $o.tl+o.lg,r4 /is the search done? bhi o.rsp /branch if not movb *r0,r4 bicb $177770,r4 /mask off octal o.sp1: asl r4 add $o.ur0,r4 /generate address inc r2 /set found flag cmpb (r0)+,$'b /are breakpoints desired? bne o.sca1 /no cmpb (r0),$012 /yes, all of them? bne o.sca1 /no mov $o.adr1,r2 /loc of breakpoint addresses mov $"b/,r5 /ascii name minus 400 br o.all0 o.sp: sub $o.tl-7,r4 /go find next character br o.sp1 / _ handler - open indexed on the pc o.orpc: jsr r5,o.tcls /test word mode and close add *r2,r2 /compute add $2,r2 / new address o.pcs: mov r2,o.cad /update cad jmp o.op2a /go finish up o.orab: jsr r5,o.tcls /test word mode and close mov *r2,r2 /get absolute address br o.pcs o.orrb: jsr r5,o.tcls /test and close movb *r2,r1 /compute new addr & extend sign asl r1 /r2=2(*r2) add $2,r1 / +2 add r1,r2 / +pc br o.pcs o.tcls: jsr pc,o.clse /close current cell cmp $2,o.bw /only word mode allowed bne o.tcl1 /branch if error mov o.cad,r2 /current address in r2 rts r5 o.tcl1: tst (sp)+ br o.err /pop a word and show the error / go execute the input line as a unix command o.unix: mov r0,o.arg2 /set up sys exec argument o.unn1: cmpb (r0)+,$012 /end of line? bne o.unn1 /no, continue looking clrb -(r0) /make a null byte sys fork /go start up other command br o.unin /child process start bcs o.err /no process space available sys wait /wait for child to terminate jsr r5,o.ftyp /output return indication .byte '!,012 / a ! br o.dcd /return to odt o.unin: sys exec;o.name;o.args/child execute command o.args: o.name /repeat program name o.arg1 o.arg2: 0 /value inserted by execution 0 /terminate table / process s - single instruction mode or t - test mode o.test: mov $o.t,r3 /show it's test mode br o.si0 o.sngl: mov $o.s,r3 /show single mode o.si0: tst r2 /see if turn "on" or "off" bne o.si1 /branch if turning it on clrb (r3) /clear the flag br o.dcd /continue the scan o.si1: movb $-1,(r3) /set the flag br o.dcd / semi-colon processor o.semi: mov r2,r3 /a semi-colon has been received mov r4,r5 /numeric flag to r3, contents to r5 br o.sca0 /go back for more / command decoder - odt11x / all registers may be used (r0-r5), o.err: jsr r5,o.ftyp / output ? .byte '?,012 o.dcd: clr o.bw /close all jsr r5,o.ftyp /type * .byte 015,'* o.dcd2: clr r3 /r3 is a save register for r2 clr r5 /r5 is a save register for r4 / general character input routine -- odt11x / an entire line of input is returned in the buffer area o.ichr o.maxl = 50. /maximum input line length o.scan: clr r0 /terminal file descriptor sys read;o.ichr;o.maxl/get one line from system cmp r0,$o.maxl /line length ok? bge o.err /no, dump it mov $o.ichr,r0 /point to buffer o.sca0: clr r4 / r4 contains the converted octal clr r2 / r2 is the number found flag o.sca1: cmpb $'0,*r0 /compare with ascii 0 bhi o.clgl /check legality if non-numeric cmpb $'7,*r0 /compare with ascii 7 blo o.clgl /check legality if not octal movb (r0)+,r1 /get the char bic $177770,r1 /convert to bcd asl r4 / make room asl r4 / in asl r4 / r4 add r1,r4 /pack three bits in r4 inc r2 /r2 has numeric flag br o.sca1 / and try again o.clgl: clr r1 /clear index o.lgl1: cmpb *r0,o.lgch(r1) /do codes match? beq o.lgl2 /jump if yes inc r1 / set index for next search cmp r1,$o.clgt /is the search done? blo o.lgl1 /re-loop br o.err / oops! o.lgl2: asl r1 /multiply by two inc r0 /skip the char jmp *o.lgdr(r1) /go to proper routine / process / and \ - open word or byte o.wrd: mov $2,o.bw /open word br o.wb1 o.byt1: rol r4 /get the address back o.byt: mov $1,o.bw /open byte o.wb1: tst r2 /get value if r2 is non-zero beq o.wrd1 /skip otherwise mov r4,o.dot /put value in dot mov r4,o.cad / also in cad o.wrd1: cmp $1,o.bw /check byte mode beq o.wrd2 /jump if byte mov o.cad,r4 asr r4 /move one bit to carry bcs o.byt1 /jump if odd address mov *o.cad,r0 /get contents of word br o.wrd3 o.wrd2: movb *o.cad,r0 /get contents of byte o.wrd3: jsr r5,o.cadv /go get and type out *cad br o.dcd2 /go back to decoder / process c - close open word/byte o.cret: jsr pc,o.clse /close location o.dcda: br o.dcd /return to decoder / process , open next word o.old: incb o.seq /set need o.dot to o.cad move o.op1: tst o.bw /anything open? bne o.op6 /yes, open next one tstb o.s /no, maybe ;p for sngl step o.err2: beq o.err /no luck, error jmp o.proc /simulate a ;p o.op6: jsr pc,o.clse /close present cell tstb o.seq /see if < command beq o.op5 /branch if not mov o.dot,o.cad /go to the former stream o.op5: clrb o.seq /clear the flag add o.bw,o.cad /generate new address o.op2: mov o.cad,o.dot /initialize dot o.op2a: jsr r5,o.ftyp / .byte 015,0 mov o.bw,-(sp) /save bw mov $2,o.bw /set to type full word address mov o.cad,r0 /number to type jsr r5,o.cadv / type out address mov *sp,o.bw /restore bw dec (sp)+ /byte mode? beq o.op3 /jump if yes mov $'/,r5 /type a / o.op4: jsr r5,o.fty1 br o.wrd1 /go process it o.op3: mov $'\\,r5 /type a \ br o.op4 / process ^, open previous word o.back: tst o.bw / ^ received beq o.err2 /error if nothing open jsr pc,o.clse sub o.bw,o.cad /generate new address br o.op2 /go do the rest / b handler - set and remove breakpoints o.bkpt: mov $o.trtc,r0 asl r4 /multiply number by two tst r3 beq o.remb /if r3 is zero go remove breakpoint asr r5 /get one bit to carry bcs o.err1 /badness if odd address asl r5 /restore one bit add $o.adr1,r4 tst r2 bne o.set1 /jump if specific cell o.set: cmp r0,*r4 /is this cell free? beq o.set1 /jump if yes cmp r4,$o.bkp+o.adr1/are we at the end of our rope bhis o.err1 /yes, there is nothing free tst (r4)+ /increment by two br o.set o.set1: cmp r4,$o.bkp+o.adr1 bhi o.err1 /error if too large mov r5,*r4 /set breakpoint br o.dcda /return o.remb: tst r2 beq o.rall /go remove all cmp r4,$o.bkp bhi o.err1 /jump if number too large mov r0,o.adr1(r4) /clear breakpoint clr o.ct(r4) /clear count also o.dcdb: br o.dcda o.rall: clr r4 mov $o.trtc,r0 o.rm1: cmp r4,$o.bkp+2 /all done? bhi o.dcda /jump if yes mov r0,o.adr1(r4) /reset bkpt mov $trt,o.uin(r4) /reset contents of table clr o.ct(r4) /clear count tst (r4)+ /increment by two br o.rm1 / process o, compute offset o.ofst: cmp $2,o.bw /check word mode bne o.err1 /error if not correct mode tst r3 /was semi-colon typed? beq o.err1 /no, call it an error o.of2: sub o.cad,r5 /compute dec r5 dec r5 / 16 bit offset mov r5,r0 jsr r5,o.cadv /number in r0 - word mode mov r5,r0 asr r0 /divide by two bcs o.of1 /error if odd cmp $-200,r0 /out of branch range? bgt o.of1 /yes, do not type cmp $177,r0 /what about forward br? blt o.of1 /it's out of range dec o.bw /set temporary byte mode jsr r5,o.cadv /number in r0 - byte mode inc o.bw /restore word mode o.of1: jmp o.dcd2 /all done / searches - $msk has the mask / $msk+2 has the fwa / $msk+4 has the lwa o.eff: inc r1 /set effective search br o.wds o.wsch: clr r1 /set word search o.wds: tst r3 /check for object found beq o.err1 /error if no object mov $2,o.bw /set word mode mov o.msk+2,r2 /set origin mov o.msk,r4 /set mask com r4 o.wds2: cmp r2,o.msk+4 / is the search all done? bhi o.dcdb / yes mov *r2,r0 / get object tst r1 /no bne o.eff1 /branch if effective search xor r5,r0 o.wds3: bne o.wds4 /re-loop if no match mov r4,-(sp) /registers r2,r4, and r5 are safe mov r2,r0 /get ready to type jsr r5,o.cadv / type address jsr r5,o.ftyp /type / .byte '/,0 mov *r2,r0 /get contents jsr r5,o.cadv /type contents jsr r5,o.ftyp .byte 015,012 mov (sp)+,r4 / restore r4 o.wds4: tst (r2)+ /increment to next cell and br o.wds2 / return o.err1: jmp o.err /intermediate help o.eff1: cmp r0,r5 / is (x)=k? beq o.wds3 /type if equal mov r0,r3 /(x) to r3 add r2,r3 /(x)+x inc r3 inc r3 /(x)+x+2 cmp r3,r5 /is (x)+x+2=k? beq o.wds3 /branch if equal movb r0,r0 asl r0 /multiply by two inc r0 inc r0 add r2,r0 /add pc cmp r0,r5 /is the result a proper rel. branch? br o.wds3 / process g - go o.go: tst r3 /was k; typed? beq o.err1 / type ? if not asr r5 /check low order bit bcs o.err1 /error if odd number asl r5 /restore word mov r5,o.upc /set up new pc o.tbit: clrb o.tb /clear t-bit flag bis $o.tbt,o.ust /set t-bit just in case tstb o.s /single instruction mode? bne o.go2 /yes, proceed with t-bit set bic $o.tbt,o.ust /no, clear t-bit o.go1: mov $o.bkp,r4 /restore all breakpoints o.rs1: mov *o.adr1(r4),o.uin(r4) /save contents mov o.trtc,*o.adr1(r4) /replace with trt sub $2,r4 /point to next one bge o.rs1 /re-loop until done o.go2: mov (sp)+,r0 /restore mov (sp)+,r1 mov (sp)+,r2 / registers mov (sp)+,r3 / 1 mov (sp)+,r4 / thru mov (sp)+,r5 / 5 mov o.usp,sp /restore user stack mov o.ust,-(sp) / and status mov o.upc,-(sp) / and pc o.rtit: rtt /this is "rti" if 11/20... /..."rtt" if 11/45 or 11/70 / process p - proceed / only allowed after a breakpoint o.proc: movb o.p,r0 /illegal to proceed? blt o.err1 /not legal tst r2 /check for illegal count bne o.err1 /jump if illegal mov r5,o.ct(r0) /yes, put away count o.tbi1: tstb o.s /see if single instr mode bne o.tbit /if so, exit now incb o.tb /set t-bit flag bis $o.tbt,o.ust /set t-bit br o.go2 / breakpoint handler o.entr: movb $-1,o.p /quit signal, disallow proceed, clr o.s / single step and testing. mov r0,-(sp) /temp store to permit signal call sys signal;3;o.entr /reset quit signal mov (sp)+,r0 /restore quit time r0 o.brk: mov (sp)+,o.upc /save status and pc mov (sp)+,o.ust mov sp,o.usp /save user stack address mov $o.usp,sp /set to internal stack mov r5,-(sp) /save mov r4,-(sp) / registers mov r3,-(sp) /0 mov r2,-(sp) / thru mov r1,-(sp) / 5 mov r0,-(sp) mov o.upc,r5 /get pc, it points to the trt tstb o.tb /t-bit set? bne o.tbit /yes mov $o.bkp,r4 /remove all breakpoints o.r1: mov o.uin(r4),*o.adr1(r4) /clear breakpoint sub $2,r4 /point to next breakpoint bge o.r1 /re-loop until done tstb o.s /see if single instruction is going bne o.b4 /if so, handle there tst -(r5) /point to break addr mov r5,o.upc mov $o.bkp,r4 /get a counter o.b1: cmp r5,o.adr1(r4) /compare with list beq o.b2 /jump if found sub $2,r4 bge o.b1 /re-loop until found jsr r5,o.ftyp /nothing found, show .byte 'B,'E / a bad entry mov r5,r0 tst (r0)+ /pop over above adjustment mov r0,o.upc br o.b3 / & continue o.b4: movb $o.bkp+2,r4 /set break point high + 1 mov r5,o.adr1(r4) /store next pc value for type out o.b2: movb r4,o.p /allow proceed tstb o.t /testing mode? beq o.t0 /no, get on with it mov $o.msk,r2 /point to test info mov (r2)+,r4 /get comparison mask mov (r2)+,r3 /addr for testing mov (r2)+,r2 /type of test bmi o.t5 /it's a byte test bic $1,r3 /make sure it's a word addr dec r2 /test for agree or disagree? beq o.t4 /agree cmp r4,(r3) /test for disagreement o.t8: beq o.t1 /same, resume br o.t7 /it's different, tell world o.t4: cmp r4,(r3) /identical? br o.t9 o.t5: inc r2 /test agree or disagree? beq o.t6 /agree cmpb r4,(r3) /test for disagreement br o.t8 o.t6: cmpb r4,(r3) /any change? o.t9: bne o.t1 /no, forward march o.t7: jsr r5,o.ftyp /show test consitions met. .byte 't,'e mov r5,r0 /get break addr br o.b3 o.t1: movb o.p,r4 /get breakpoint no. back o.t0: dec o.ct(r4) bgt o.tbi1 /jump if repeat inc o.ct(r4) /reset count movb r4,r5 asr r5 swab r5 /put in high byte add $"b0,r5 /make ascii name jsr r5,o.fty1 mov $2,o.bw / set word mode jsr r5,o.ftyp /print ; .byte ';,0 mov o.adr1(r4),r0 /get address of break o.b3: jsr r5,o.cadv /type address jmp o.all5 / then to decoder / type out contents of word or byte with one trailing space / word is in r0 o.cadv: mov $6,r3 /# of digits mov $-2,r4 /# of bits first-3 mov r5,-(sp) /make r5 available cmp $1,o.bw /see if word mode bne o.spc /branch if so sub $3,r3 /only do 3 digits inc r4 /do 2 bits first swab r0 /and turn r0 around o.spc: mov r0,-(sp) /save r0 o.v3: clr r5 o.v0: add $3,r4 /compute the number of bits to do clr r0 o.v1: rol (sp) /get a bit rol r0 /store it away dec r4 /decrement counter bgt o.v1 /loop if more bits needed add $'0,r0 /convert to ascii bis r0,r5 /put ascii char in r5 dec r3 /see if more to do ble o.v2 /exit swab r5 tstb r5 /both digits ready? beq o.v0 /no, get another jsr r5,o.fty1 /type them out br o.v3 o.v2: swab r5 /put chars in proper order jsr r5,o.fty1 /output last char(s) tst (sp)+ /get rid of junk mov (sp)+,r5 /restore return addr mov $040,o.ochr /put a in buffer br o.fty3 /fall thru to print it / general char output routine for 1 or 2 characters. if only / 1 char is to be sent, the high byte of the char word must / be 0. / o.fty1 is the entry if the char(s) was in r5 prior to the / call (which puts it on the stack for subroutine execution.) o.fty1: mov (sp),o.ochr /mov char(s) to buffer br o.fty2 o.ftyp: mov (r5)+,o.ochr /char(s) to output buffer o.fty2: clr r0 /use terminal file descriptor tstb o.ochr+1 /1 or 2 characters? beq o.fty3 /only 1 sys write;o.ochr;2 /output 2 chars rts r5 o.fty3: sys write;o.ochr;1 /output a char rts r5 / close word or byte and exit, / upon entering, r2 has numeric flag, r4 has contents o.clse: tst r2 /if no number was typed there is beq o.cls1 /no change to the open cell cmp $1,o.bw beq o.cls2 /jump if byte mode bhi o.cls1 /jump if already closed mov r4,*o.cad /store word rts pc o.cls2: movb r4,*o.cad /store byte o.cls1: rts pc o.exit: sys exit /back to std unix o.lgdr: o.semi ; / semi-colon o.wrd / / open word o.byt / \ open byte o.cret / c close o.regt / $ register ops o.go / g go to address k o.op1 / modify, close, open next o.orpc / _ open related, index - pc o.old / < return to old sequence and open o.back / ^ open previous o.ofst / o offset o.wsch / w search word o.eff / e search effective address o.bkpt / b breakpoints o.proc / p proceed o.orab / @ open related, absolute o.orrb / > open related, rel. branch o.sngl / s single instruction mode o.test / t test mode o.unix / ! execute unix for a while o.exit / back to unix o.lgl = .-o.lgdr /lgl must equal 2x chlgt always o.bw: 0 / =0 - all closed, / =1 - byte open, / =2 - word open o.dot: 0 / origin address o.wdfg: .byte 0 /search flag = 1 - effective o.tb: .byte 0 /t-bit flag / = 0 - word o.p: .byte 0 /proceed flag = -2 if manual entry / -1 if no proceed allowed / 0-7 if allowed o.seq: .byte 0 /flag for < command o.lgch: .byte '; / .byte '/ / / .byte '\\ / \ .byte 'c / c - close .byte '$ / $ .byte 'g / g .byte 012 / .byte '_ / _ .byte '< / < .byte '^ / ^ .byte 'o / o .byte 'w / w .byte 'e / e .byte 'b / b .byte 'p / p .byte '@ / @ .byte '> / > .byte 's / s .byte 't / t .byte '! / ! .byte '% / % - exit o.clgt = .-o.lgch /table length o.tl: .byte 's /do 1 .byte 0 /not 2 .byte 'm /change 3 .byte 0 /the 4 .byte 0 /order 5 .byte 'b /here 6 o.lg = .-o.tl o.name: o.arg1: <-c\0> .even o.trtc: trt /trt used for break points o.rnam: /special reg names, must start / & end on word boundary. o.s: .byte 0 /single instr flag(needs word bndy) /0 if not active /-1 if active /no break boints may be set while in /single instruction mode o.t: .byte 0 / test flag (must be adjacent o.s) o.ochr: .byte 0,0 /output buffer(needs word boundary) o.ichr: /input line buffer . = .+o.maxl .even /the order of the following entries is critical . = .+14 /allow for odt's stack o.ur0: 0 /user r0 0 / r1 0 / r2 0 / r3 0 / r4 0 / r5 o.usp: 0 /user sp o.upc: 0 /user pc o.ust: 0 /user st o.pri: 0 /odt priority (not used in vunix1a) o.cad = o.pri /use o.pri to store current addr o.msk: 0 /mask 0 /low limit 0 /high limit / break point lists, adr1 = adress of breakpoint,ct = count, / uin = contents o.adr1: . = .+o.bkp+4 o.ct: . = .+o.bkp+4 o.uin: . = .+o.bkp+4 e order of the following entries is critical . = .+14 /allow for odt's stack o.ur0: 0 /user r0 0 / r1 0 / r2 0 / r3 0 / r4 0 / r5 o.usp: 0 /user sp o.upc: 0 /user pc o.ust: 0 /user st o.pri: 0 /odt priority (not used in vunix1a) o.cad = o.pri /use o.pri to store current addr o.msk: 0 /mask 0 /low limit 0 /high limit / break point lists, adr1 = adress of br.de pp .sp 1 .ti +6 .. .ce PROCSY/MIRACLE OPERATION VIA UNIX .sp 2 .ti+20 Author: Stephen J. Mahler .sp 1 .fo 'Jan. 22, 1976'-%-'PROCSY/MIRACLE Ver 2.00'' .pp High speed lines connect UNIX to both the Agricultural Data Network (formerly Proj. MIRACLE, now ADN) and the university Dual-Mace system via the remote terminal system, PROCSY. The high speed lines serve two major goals: (1) to allow transfer of data or program files between computing systems, and (2) allow any UNIX terminal to function as though it was connected to the hosting system. .sp 2 .ce Entering "LINK" Mode .pp Follow standard UNIX login procedure (see login(I) ) to establish the "%" prompt from shell. The basic command (procsy for PROCSY, miracle for ADN) is then entered. If no other parameters are given and a RETURN () is issued, the link will be attempted on both ports of the requested type. If either or both ports are "out of service" or busy the user is notified. If a port is free the link is established and the user notified which port is being used. Note that the link will be established with the first available port. This leads to the following trap for the unwary user. If port 1 is busy and the user issues a procsy the program will assign port 2. The user on port 1 finishes his work and breaks his link ( more on this later ). If the user on port 2 breaks his link ( for reasons to be seen later ) and reissues a procsy the system will assign port 1. Unfortunately all of the user's work is still up on port 2. To combat this scenario the user has available a parameter on the command to force selection of a port as described below. .sp 2 .ce Link to Specified Port .pp When the first parameter is a number in the range of legal ports ( for now 1 or 2 ) the link is attempted only to the requested port. If the parameter is not of legal value it is ignored and a link is established to the first available port. .br .ti+10 .ul Examples .sp1 .ti+15 % miracle - link to first available .ti +35 MIRACLE Port .ti+15 % procsy 2 - link to PROCSY Port 2 .ti+15 % procsy one - link to first available .ti +35 PROCSY Port .sp 2 .ce File Transfers .pp Transfers of files between UNIX and PROCSY are very easy for the user. For transfers to PROCSY from UNIX: .br First, establish the link between UNIX and PROCSY. Next log-in to PROCSY ( see PROCSY document L0-PROCSY or L0-PIRATE ). If a CTL-C is typed, the UNIX system will ask if you wish to continue,exit, or transfer. Continue will just restore the link. Exit will abort the link. Please note that this also leaves the port logged on under your account. Transfer will cause UNIX to inquire which direction the file transfer is to proceed. The first question will be : "To PROCSY from UNIX" this is the proper direction so answer it with a " y ". At this juncture the name of the file on the UNIX system and the name of the new file for PROCSY will be requested. Remember to use the file naming conventions for each system. The target file name ( PROCSY file name ) must .ul not be a local file ( UNIX sends a QCR TARGETNAME ). After the file names have been specified the computers begin file transfer. After every 20 lines an 'F' is printed on the terminal to indicate the transfer is progressing in the *F*rom direction ( relative to UNIX ). When the transfer is complete the number of lines transfered is printed and the link is restored for keyboard commands. .sp 2 For transfers to UNIX from PROCSY: .br The transfer of file in the reverse direction is just as easy. The differences are as follows : (1) The file must be a local PROCSY file before transfer is requested and (2) the questions regarding direction must be answered to reflect the direction of transfer. The UNIX file name is "creat"ed such that if the file exsists and the user has create permission, the content of that file .ul is replaced by the transferred information. Again, after every 20 lines a 'T' is printed to show the transfer is progressing *T*oward UNIX . .pp After the transfer begins , it may be aborted by issueing a Ctl-B. If the direction was to PROCSY the link will return in PROCSY edit mode ( that is edit/qed ). The user should issue an s to end the edit. When the PROCSY prompt "+++" returns the users should type a Ctl-X to reset the terminal environment ( more information in notes section ). No special action is required if the transfer was to UNIX. .sp2 .ce Exiting "LINK" Mode .pp The user exits his link by typing a Ctl-E (Exit) or Ctl-P (from 11/20 days). Exiting does not perform a logout on the host system which must be accomplished prior to breaking the link. If the users fails to logout his account and files will be accessable to the next UNIX user how is assigned that port. .sp2 .ce Quick Controls .pp The expirenced user might prefer to not answer all the questions when a Ctl-C is struck. The following control functions are available: .sp 2 .ti +15 Ctl-T - Transfer TOWARD .ti +15 Ctl-F - Transfer FROM .ti +15 Ctl-U - Delete current line (see notes) .ti +15 Ctl-P - Exit from link .ti +15 Ctl-E - EXIT from link .ti +15 Ctl-X - Set terminal environment .ti +15 Ctl-R - RETYPE line (see notes) .ti +15 Ctl-S - STOP output scrolling (see notes) .ti +15 Ctl-Q - Force scrolling toggle .sp 2 .ce Notes and Quirks .pp No file transfers with MIRACLE are supported at this time. .pp Due to extreme dependence on terminal environment it is suggested that Ctl-X be issued whenever the first PROCSY prompt ( +++ ) is recieved during a terminal login unless the startup macro from id CGS is used (see GENLIB document). In addition if any operation seems to fail or the output on the terminal is dropping characters, reissue the Ctl-X. After the prompt returns reissue the operation. .pp The link buffers the users input line, that is none of the characters are sent to the host system until a or Line Feed is typed. This allows rubout to perform a character erase ( like a '%' in PROCSY). In addition, the line erase ( rubout in PROCSY ) is issued by typing a Ctl-U. Both of these line editing features assume a CRT terminal. If the user is on a Teletype or TI700 series the output gets very difficult to read. The Ctl-R has been implemented to solve this problem. By issueing the proper number of rubouts ( this could be hard to detect as stated above ) and striking a Ctl-R the current line is *R*etyped and the users may continue typing. .pp The PROCSY link is very dependent on signals from the Modcomp for controlling data transmission. The user should never alter the tape, pause, escape, eject, or depth parameters of the terminal environment. Please ignore this if you don't understand terminal environment. .pp Ctl-S is used to stop a long display on a CRT terminal (PROCSY only). The link is set up such that a full line is .ul always displayed and the next characters after the "pause" is released will be a and a . The "pause" is released by typing any key. The key issued is totally ignored by both systems (UNIX and PROCSY). This "pause" mode may also be force toggled by typing a Ctl-Q. A side effect of this is a "pause" issued via a Ctl-Q may only be released by a Ctl-Q. .pp Files transfered TO UNIX have 1 blank line prepended and files transfered FROM UNIX have 1 blank line appended . .pp The catastrophic abort command is five consecutive Ctl-C s. characters after the "pause" is released will be a and a . The "pause" is released by typing any key. The key issued is totally ignored by both systems (UNIX and PROCSY). This "pause" mode may also be force toggled by typing a Ctl-Q. A side effect of this is a "# /* * ps - process status * examine and print certain things about processes */ #include "/usr/sys/param.h" #include "/usr/sys/proc.h" #include "/usr/sys/tty.h" #include "/usr/sys/user.h" struct { char name[8]; int type; char *value; } nl[3]; struct proc proc[NPROC]; struct tty tty; struct user u; int temp; int lflg; int kflg; int xflg; int tflg; int aflg; int mem; int swap; int stbuf[257]; int ndev; char devc[65]; int devl[65]; int devt[65]; char *coref; struct ibuf { char idevmin, idevmaj; int inum; int iflags; char inl; char iuid; char igid; char isize0; int isize; int iaddr[8]; char *ictime[2]; char *imtime[2]; int fill; }; int obuf[259]; main(argc, argv) char **argv; { struct proc *p; int n, b; int i, c, mtty; char *ap; int uid, puid; obuf[0] = 1; if (argc>1) { ap = argv[1]; while (*ap) switch (*ap++) { case 'a': aflg++; break; case 't': tflg++; break; case 'x': xflg++; break; case 'l': lflg++; break; case 'k': kflg++; break; } } if(chdir("/dev") < 0) { printf("cannot change to /dev\n"); done(); } setup(&nl[0], "_proc"); setup(&nl[1], "_swapdev"); nlist(argc>2? argv[2]:"/unix", nl); if (nl[0].type==0) { printf("No namelist\n"); return; } coref = "/dev/mem"; if(kflg) coref = "/usr/sys/core"; if ((mem = open(coref, 0)) < 0) { printf("No mem\n"); done(); } seek(mem, nl[1].value, 0); read(mem, &nl[1].value, 2); seek(mem, nl[0].value, 0); read(mem, proc, sizeof proc); getdev(); mtty = ttyn(0); uid = getuid() & 0377; if(lflg) printf("TT Flags&State UID PID QP ADDR SZ WCHAN Command\n"); else printf("TTY PID COMMAND\n"); for (i=0; i>3); if (proc[i].p_wchan) printf("%7o", proc[i].p_wchan); else printf(" "); } if (proc[i].p_stat==5) printf(" "); else prcom(i); printf("\n"); } done(); } getdev() { register struct { int dir_ino; char dir_n[14]; } *p; register i, c; int f; char dbuf[512]; int sbuf[20]; f = open("/dev"); if(f < 0) { printf("cannot open /dev\n"); done(); } swap = -1; c = 0; loop: i = read(f, dbuf, 512); if(i <= 0) { close(f); if(swap < 0) { printf("no swap device\n"); done(); } ndev = c; return; } while(i < 512) dbuf[i++] = 0; for(p = dbuf; p < dbuf+512; p++) { if(p->dir_ino == 0) continue; if(p->dir_n[0] == 't' && p->dir_n[1] == 't' && p->dir_n[2] == 'y' && p->dir_n[4] == 0 && p->dir_n[3] != 0) { if(stat(p->dir_n, sbuf) < 0) continue; devc[c] = p->dir_n[3]; devl[c] = sbuf->iaddr[0]; c++; continue; } if(swap >= 0) continue; if(stat(p->dir_n, sbuf) < 0) continue; if((sbuf->iflags & 060000) != 060000) continue; if(sbuf->iaddr[0] == nl[1].value) swap = open(p->dir_n, 0); } goto loop; } setup(p, s) char *p, *s; { while (*p++ = *s++); } prcom(i) { int baddr, laddr, mf; register int *ip; register char *cp, *cp1; int c, nbad; baddr = 0; laddr = 0; if (proc[i].p_flag&SLOAD) { laddr = proc[i].p_addr; mf = mem; } else { baddr = proc[i].p_addr; mf = swap; } laddr =+ proc[i].p_size - 8; baddr =+ laddr>>3; laddr = (laddr&07)<<6; seek(mf, baddr, 3); seek(mf, laddr, 1); if (read(mf, stbuf, 512) != 512) return(0); for (ip = &stbuf[256]; ip > &stbuf[0];) { if (*--ip == -1) { cp = ip+1; if (*cp==0) cp++; nbad = 0; for (cp1 = cp; cp1 < &stbuf[256]; cp1++) { c = *cp1; if (c==0) *cp1 = ' '; else if (c < ' ' || c > 0176) { if (++nbad >= 5) { *cp1++ = ' '; break; } *cp1 = '?'; } } while (*--cp1==' ') *cp1 = 0; printf(lflg?" %.16s":" %.64s", cp); return(1); } } return(0); } done() { fflush(obuf); exit(); } putchar(c) { putc(c, obuf); } (ip = &stbuf[256]; ip > &stbuf[0];) { if (*--ip == # /* | SPOOL20 - Fake the lp: for the 11/20 system | | Author : Stephen J. Mahler | Date : Jan 10, 1977 | Mods : Mar 03, 1977 | | This program reads from ttyj and writes to a /tmp file | until a line containing on a LF is seen. At that | time the /tmp file is given to opr for printing. | Routine fresh attempts to give the filename sequence | a fresh start. */ int fd,knt; char tfile[] "/tmp/spool20a"; char xon[] "\021\021\000"; char xoff[] "\023\000"; char thold; int kbfd,ttmod[3]; main() { extern int shutdn(); int kid,tmp,ttmp; char buf[256]; signal(1,shutdn); nice(1); if ( ( kbfd=open("/dev/ttyj",2) ) < 0 ) { perror("Spool20> Can't open input tty"); exit(); } ttmod[0]=0; ttmod[1]=0; ttmod[2]=0300; stty(kbfd,ttmod); file: write(kbfd,xon,2); if ( (fd=creat(tfile,0444)) < 0 ) { perror("Spool20> Can't open /tmp file."); abort(); } readmore: write(kbfd,xon,2); knt=read(kbfd,&buf,255); write(kbfd,xoff,1); if ( knt == 1 ) goto peof; writemore: write(fd,&buf,knt); goto readmore; peof: close(fd); thold=tfile[12]; fresh(1); kid=fork(); if ( kid == 0 ) goto kidkod; if ( kid == -1) { perror("Spool20> No Fork"); abort(); } waiting: tmp=wait(ttmp); if ( tmp != kid ) goto waiting; nxtnam(); goto file; kidkod: execl("/bin/opr","spool20 opr-ing",tfile,0 ); exit(); } shutdn() { close(fd); fresh(0); } nxtnam() { if ( tfile[12]++ > 'z' ) { thold='a'; fresh(0); } } fresh (type) int type; { char buf[36]; /* | if type = 0 then stay till lpd finished | if type !=0 then return if lpd busy */ running: if ( stat("/usr/lpd/lock",buf) >= 0 ) { /* deamon running */ if ( type != 0 ) return; printf("b-sleep"); sleep(15); goto running; } if ( type == 1 ) { link ( tfile , "/tmp/spoolxx" ); } for( tfile[12]='a'; tfile[12]<='z'; tfile[12]++ ) unlink(tfile); tfile[12]= thold; if ( type == 1 ) { link ( "/tmp/spoolxx" , "/tmp/spool20a" ); unlink ( "/tmp/spoolxx" ); tfile[12]='a'; } } uf[36]; /* | if type = 0 then stay t @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2 *$&2 2u2qQ[*7 \R qQ[n2@AA@AAlAlAlAlAlAlAL@L@@3A333A33pA`ALA9A&Aff@\AzB1K1M1B2K2M2Y1Y2V1V2@B@@B@IA~l]]7 6YJl^7 *Y^^k^^^7 Y ^hon3k^"^7 Y ^hon$3 ^hon&3k"^7 X ^hon@3k^"^7 Xk^^"^7 Xk]]^7 XJl*^7 X2^<^k<^<^^7 |X6^hon36^hon3k*^7 `X6^hon3k<^^7 FX6^hon3k<^*^7 ,Xk]]^7 XF^P^Jl^7 XJ^hon4kP^*^7 WkP^P^*^7 Wk]]*^7 Wk]P^^7 Wk]Z^*^7 Wk]]^7 WJl"^7 Wd^n^kn^]*^7 xWr^h^n4kn^*^7 bWh^hon4r^h^n4k*^7 >Wh^hon4k]*^7 $Wk]]*^7 WJl^7 Wk^^*^7 Vk^^^7 VJl^7 Vx^^k^^^7 V^,^܃nZ5k^"^7 Vk^^^7 V]n^]^Tp^7 |V&^j^7 hV^&^^7 RV^&^k^^*^7 8Vo^^^z5T^hon5^^܃n5k^7 Vi*^"^^7 U^^^hon$6k^^7 Uk^^*^7 U^honL6k^^7 Uk^^*^7 Uk^^^7 Ul*^7 Uj7 zUl^7 nUj7 dUl_7 XUj_7 LUkx^ _^7 o^^N_7r"_N_^7 Tn^X8onZ76^X_Z_d_nF]n^]nn_^h_]6^o^n_^t7o^^"^n7p_z_܃hohPT]]]>TP^P܃hohPT]$^]>z_hPT]^]>^PhPT]^]>$^]]6 _z_rPT^]]>^PrPT^$^]>z_horPT^^]>^PhorPT^^]>^^]6 _^_^_*W6 _]6 _l^7 S__nt8k_^7 Si*^__7 xSLj^7 lSl_7 `Sk__^7 PSj*^7 DSj^7 8S_^__T&`]n]n>on8]]]_]n]n>on9$^]]__hPT]|^]>_rPT^|^]>WnP>&WnS>Wd_]7 R]n]nNont9n9^$^]nPn^_TW>^$^]nW>]n]nNon9n9^$^]nSn^_T"W>^$^]n&W>Wd_]7 R`]n`l^7 R]ho`T``n":p7 Q]r^T܃&^k__^7 Qj^7 Q^_܃&(`^7 Q^_܃&,`k(`,`*^7 zQ `^n>on:n:]n]n>on:]`]_]n]n>on:$^`]__hPT]|^]>_rPT^|^]> `n6`6`n ;p7 P^Tn$;X7 P`^^]n>onD;n;`]n]nNon\;n|;|^^]nW>^^]nW>]n]nNon;n;^^]n"W>^^]n&W>0`_nNon;n;Wn`vP>&Wn`vS>Wd_]7 Po^6`_:o^``968`]n]n>on,<^H_]nS>]n]n>onL<^H_]nV>^VonZ<l7 O_Vonp<l7 O_B`l^7 ~Ok__^7 nOi*^^F`7 ^OPB`N_^7 LOSnV>SnSn<`܃V>SB`N`^7 OVnS>WnS>VnV>WnV>SnSn<`܃&T`SnvT`&^`b`l`]n^z^PnvT`f`X`T^܃z^*W>z^SnvT`f`X`T^܃z^rZ>o^^N_T=]Von=l7 VNlv`7 DNS o=S o=]Von= x`|``_B``7 N^Von> o$> o&> x`|``"_^]7 MrPN_^x`|`*^7 MrSN_^x`|`"^7 Mk"_`^7 Mk``*^7 Mk``^7 xMi*^*^`7 hMk"_`^7 XMk``"^7 HMk``^7 8Mi*^*^`7 (Mn?l_7 Mk``^7 Mi*^``7 LVg`x^^``7 L_Von8?l7 L`^X8onR?^`&_`^^܃nf?X7 L`]n^z^*W o?z^rZ o?c7 nLo`^N_x?l_7 XLk`x^^7 HLi*^^`7 8Ll^7 ,Lj^7 Lk__^7 Li*^aa7 L_^^n@k_^7 Ki*^0_a7 K__nF@k_^7 Ki*^0a2a7 K_Banr@k_^7 Ki*^LaNa7 |K_r^n@k_^7 fKi*^v`da7 PK]Von@j7 @K.W o@vZ o@c7 KmP7 K|P]nNonA_VonAl7 J|P]n>on*An>|Pnan>on:AnP|P$^n>onJAnA|P^nNonZAnAl_7 Jkvax^^7 Ji*^za|a7 JԧN_PSr7 pJn?|Pp`nNonAn@7 RJn?^VonAl7 >Jc _ _7 $JX_a_a_l^7 Jj^7 Ik__^7 Ii*^aa7 I_^^n@Bk_^7 Ii*^aa7 I__nlBk_^7 Ii*^v`a7 I]VonBj7 rIl"^7 `Ij"^7 TIkaa^7 DIi*^aa7 4Ik,_a^7 $Ii*^^b7 Ik,_ b^7 Ii*^^b7 Hk,_b^7 Hi*^^b7 Hk,_$b^7 Hi*^^(b7 Hkax^^7 Hi*^_0b7 H]n^z^ 2 oCz^P2 oCk^7 jHj^7 ^Ho^^^zC^VonCj7 DHl_7 2Hj_7 &H]n^z^ 2n ^܃@^܃nDz^P2n ^@^܃nDk^7 Gb^2 o6Di*^*^7 Go^^^Ck _>b^7 Gj^7 Gk>bb`^7 Gi*^*^Bb7 Gkx^Fb^7 vGj^7 jGkJbNb^7 ZGi*^*^Rb7 JGk _Vb^7 :Gj^7 .Gk>bZb^7 Gi*^*^^b7 Gkx^bb^7 Fj^7 FkJbfb^7 Fi*^*^jb7 Fl^7 Fj*^7 F_Von\Ej7 FmP7 F|Pnan>onEnP|P$^n>onEn O nnbrb7 jFj^nbrb^7 XF|P]nNonEndE]n^z^ 2nvnbnE7 (F ^XFonEn0Fz^P2nvrbnF7 E ^XFon&Fn0F荰^|bn>Fo^^^EndEvb^n>onNFnFlb7 Ekx``^7 Eb|b2 o~Fi*^*^7 Ei*^^b7 tEz|b2 oFVgva`^b7 VE~bVonFl7 FE227 2ER_]n>onFn OndEl^7 Ej^7 Ebbkaa^7 Di*^ab7 Dk,_a^7 Di*^*^b7 Dk,_ b^7 Di*^*^b7 Dk,_b^7 Di*^*^b7 |Dk,_$b^7 lDi*^*^b7 \D^VonGj7 LDl"^7 :Dj"^7 .Dbb^n^z^ 2 oHz^P2 oHk^7 Cj^7 Co^^bG^Von0Hj7 Cl^7 Cj*^7 C nnbrb7 Cj^nbrb^7 CmP7 C|P$^n>onHn O|Pnan>onHnP|P]nNonHnPH]n^^bzb 2nvnbnH7 4C ^XFonHnBIzbP2nvrbnI7 C ^XFonInBIb]n>on,I荰^pb$^n>on>I荰^bnPIo^^bHnPHb$^n>on`In~Jbbl^7 Bj^7 Bkaa^7 tBi*^0ab7 dBk,_a^7 TBi*^v`b7 DBk,_ b^7 4Bi*^^b7 $Bk,_b^7 Bi*^bb7 Bk,_$b^7 Ai*^v`b7 Ak,_c^7 Ai*^ cc7 Ak,_*c^7 Ai*^_.c7 A^VonrJj7 AnGbbbp]b^nNonJnJʧ7 ^A227 PAnAb|^n>onJbp] b|^n>onJnAb^nNonJnKlb7 Akx`r^]c`cTnL7 ?~c]^]>o^^N_hLnAb]^nJon(Mbbn^^n,^&c]^n8on^MnMp^]6^`cr^TcXFonMnM`cr^TnMc7 r>,^X8onMr^ho~c^_Tp^]>cfc7 8>,^X8onMr^~c^_Tp^]>]^]6ccfc7 =`cr^TXJon,N~cho]^]>o^^N_.MnAb]^nJonPNbbn^^ndNp7 =,^&c]^n8onNnN~c`cTp^]>c`cX8onNnNcfc7 P=,^X8onN~cho^_Tp^]>cfc7 =~c`cT]^]>o^^N_VNnA]VonOl7 <^Von.Ol7 <^VonDOl7 <|^VonZOl7 <p`VonpOl7 <~bVonOl7 <_VonOl7 j<2v_2ZP2nP2_2dP2xP2nW>2nW>2n"W>2n&W>R_]n>onPnAnh7l]7 ;l_7 ;ka_^7 ;i^ac7 ; ^PhPrP |P\&&\D\2u\\>^h\\\6^W>@^RJ^ML>T^H^^C?h^>@r^9|^4A\^+^& B\^\$^B^L?DONE^&&\?^s \ \_f@ \ EMPTY FILEA0_UAHIT KEYSET TO RETURN\\#= h_9\z_0_+_&_!__RUNGE KUTTA CALCULATIONS \ _&&\A_jAff@ff_cD`^GD `Y\\(`K4D\BF`<SCALE b`.@p`'\0AADISPLACEMENTCTIMEBABY1BffY2@A@33(&&\ENTER REAL TIME SPEED COEFFICIENT (F6.3)`s(F6.3)READY 1= SEE MOVEMENT 2= MODIFY PARAMETERS 4= SAVE GRAPH LaG@8= GET STORED GRAPH 31= EXIT\SA33GRAPH BEING SAVED AsA331= ENTER SPECIFIED PARAMETER2= PROCEED TO CALCULATIONS&&\31= EXIT`AAINITIAL CONDITIONSY1(0) LAY2(0) 9AV1(0) &AffV2(0) CHANGE INPUTf@ffY1 A@33 AF1FAffYAY2A̖AffF2\ \ = (F8.3)\INPUT TO CHANGE F1F2Y1Y2\TYPE OF INPUT SIN WAVESQUARE WAVE RAMP WAVE CONSTANT@THIS PARAMETER NOT IN USE A33CREATE INPUT@VALUE pA(F8.3)PERIODjc#(F8.3)AMPLITUDE c(F8.3)c HAVE A NICE DAY &&\7 ncA@L?L?̌ff&fff܃&ffi7 (j7 'j7 'ffnfff܃f܃&fkfff7 'ffvfnZdkff7 'ffndffvfndkf7 ~'ffndgfvfndkf7 R'ff܃ndgfvfndkf7 &'ff܃neffvfn ekf7 &gfvfn,ekff7 &kfcf7 &kfff7 & gfvfnnekff7 &ffnegfvfnekf7 j&ff܃negfvfnekf7 >&(gfvfnekff7 &kfcf7 &kcff7 %j2g7 %fzf4g܃&f>gff܃&cofff$dHgcfVonXfj7 %fnpfj7 %F@f@c&@\c_c\cYcVcSfP?fKfF f@\f5L?f0g*? g%@g .?{g?(g+@2gT@z>g @HgAe&&\7  .qn i |gl7 $ggk$i7 j$i$i&i(i7 Z$j7 P$:i(mBi7 >$ongngongnhonhn\hon$hnfhoo2oo2onHhnzhonXhnzhng:inh4i,inFonvhP:inh4iin8onhD:i2:iiBij7 j#4i,inFonhi$i:ii7 N#ng4i,in>onhngn:io ni\won~iVonhl7 #Ff\@> \\\ \ 0\0:\:\\.\. \ -\-E\E\7  yw:iii7 J"ii7 6"Bi7 *"F7  t!jj7 "Bj7 !F7 V a8Y4jHj7 !BJj7 !F7 " i8Yhj|j7 !B~j7 !F7  , zjj7 f!Bj7 Z!F7  zQDBj7 :!F7  [q`"Bj7 !F7 ~ S@ kk7 kl7 n2kk7 Fkl7 nZkk7 pkk7 Bk7 F7  e}kl7 Z nkl7 J kl7 2 nkl7 " kl7  Bl7 F7 X w2lFl7 BHl7 F7 $ zflzl7 B|l7 F7  wl7 lll7 Xll7 DBl7 8F@7  ;;KmmmmmnF\@mCe&&\7 F ETnRmbPm8mnmn>onhmnmbPm8mnm,oDPmFmnPmbPm8m omPmmmPmPm:m7 \ :mnmn>onmFnhm\\\ :7  EwnP n7 F97 b SwPnnjn7 jn o6np7 rnT>ln oVnp7 rnT>F8|nC&&\\\&&&&\&Ca\\&\\   `\ `\\AaP AaH \  \\@a&\\X4%]@D&&7 jw f7  ~w @A&&ff 7 TwT    sp `sp `œBp@b\  \pf\  \z\6 6 &  f 6A  v  6N\z\   B -  e \A@@ AwnD C  %  v v w0f&\z\z\ N A f C%v   \   &5 5 `6 6 % \\\f&\ "   &@ &&f&f  @D   \`ȕ `̠%%  `&& A3 AaA.W *W#,&@  e     `&wr2 ET ffe f@& `f % fef fE`@  %   @ re@'f&f& e fU%e"f" RTFO   wZ 4- w,&f&    `@ ` B        @ v6&f&  UAѕ  NAMESEQ Bffe"&&f"fe" w222re@  f  &  @@@@=@ R@_@ c@n@  n 0 & R <  , W r 8 @  `A  ` %51 1 1 1 1 1  RH2 rr2 r rr rr & Xe  &" ˥0 & " 20PpЊz'O<z'P<z'Q<f'R<M'S<E'T<z'U< 'V<E'<""z's&f]f@@eX \ e\@a\Ba\Aa@e\Aa@te\Aa@ e\Aa@te\\g\e\ \\\ \g\e\ \\\ \&g\&e\& \&\&\& \&b\&\b\\\\g\\e\\ g\g\e\ \\\ \b\\e\\ FC C  \v\\\\\\\\\\\\\\\\\\\\R\PP\\ދe @v & n   & & &&  U Ba& ^Ǝ m  ƎҎ5E (&f& v  RL!F ~  <7 r 2w& & J!b]\ҎҎ& ܥU@  ߋ%@w @w w A@EUw Bw D~ w @w 7 %Az~@w 7 |%vZ F ї~22uqQ[<ާ&*Rs,>ާ>:dxAާVR* Bާ f> vIƴj Rzz9wKOƴ Rffv@ Dާ D*ާ D>ާ DRާ DR Dfƴ Dfn Dzƴ7 s,nnn7 nzn Щ>n Щn0܃>o&. nn7 nznDЩ>nDЩn0܃>o&.|ʨn7 6 nznLЩ>nLЩn܃>o&.ب"n7 nzn(Щ>o&.0 nn ЩnDЩnT܃LЩnT܃(Щn܃^T܃>o&.VFX@>Xة\\\De&&\@\\^AhA&&\@AePe& & &&ffzz ~eLeBa(%eAa@ g\Aa@ tg\g\7 :dxnVn\n@AL@@pnnnVnzX8on>nVnhonV>ovnx$VnX8ond$V6$VnX8on$V6$VnX8on$V6$VnX8on$V6l7 Dj7 8pnnk 7 "n\ oi7 iv7 nV o"7 bh܃&ovn֨ nnk 7 n\ oti7 iv7 ~nV o7 dbh܃&ovnxP Īnnk 7 .n\ oi7 iv̪7 nV oЪ7 bh܃&ovnʩVon@j7 ت FX P  :7\.(#=  \ = (F7.3)@A?\= (F7.3)\= (F7.3)f@ff&&\7 ZZ nnΫonbwon~ҫnЫܫЫޫbޫn૲nNon>nJoثЫګ F*ޫn\7 t7 B7 FX@\ ! \ Aa@ g\Aa@ tg\g\p\ r\p\ r\p\ r\p\ r\7 j7 j7 j7 Vonj7 l7 k7 j7 n 7 j7 m*7 $,n>onnNVonl7 nj 7 \Vonj7 LVonШj7 6Vonj7 F\\ \ \\\\7 vn(F8.4) (F7.3) (F7.2) (F8.1) (F6.0,1H(F7.0) ̾>̀L>L>̀??LL̀?&ff??&@ffܿ(?zTz0@ףܿ(?zTz0@ףԬnj7 l.Ԭn7 J.ԨB7 . 7 ㌄n,7 $α&7 ⌄n2α&7 . n0܃@^7 ⊄nn: ܃n7 nj7 lBn"7 T.RL\LdLXJonީnP\\d^n6o^fnFo2ondV^nNoV n܃LXFo,on$d\dj&(nެ܃(n&(n܃(nެ܃&nT&άnk7 dHd o`7 Jᒭެ܃&܃&nT܃&o@n: ެ܃&n: ܃&ĭz$nv&z$nެ܃&k7 nkĭ7 ഭެ&&ĭkĭ7 ~ެ&&k7 Zo@V: ȭ ҭ\dnګB7 ,n7 ܭ&nެ܃(Ƭn& nX>on<έ nX>onjp@7 ߊT܃܃&n|k7 i 7 lF@h@e@ b@_(Hh\ެO=5JE@;\\\\\:!}@p\LCV\\\e&&\8H B@;61*ȭ%ҭ @ܭu>?= C A?33?&&\7 Z vL@nnf",6@nJJn0T܃&L Jn:&T܃&PDn>onЮkLPT7 8kLP7 "lJFXXf\@ &@ #\&0:D \e&&\7  ZZ nnLon bwon~PnNZN\b\ n^nNonnȯoVNXFh\nگf 7 *f7 Bj7 FX@\ ! \    Jb " \\ @a  &  . & @  $<  7  7 j  % 6 @7 8T>%\% d& f6& f N&&@&&7 X    @A ff7 Ʊ w8ffff7 Z豎w D@@/   Ċ&7 ` w & Dr)&&]   5@5@7 ܃Tʲʲ܃܃܃܃ Բ܃޲޲f&\  \& \\r1@\[?\ we ?U?*@ڪAD@@/ ĊwD@@/ Ċw@ w b r\ J\Aa@ g\Aa@ tg\g\g\e\ \\\ \g\e\ \\\ \g\e\ \\\ \b\\\\p\ r\p\ r\p\ r\p\ r\p\ r\p\ r\p\ r\p\ r\p\ r\7 9wKnn@AA̶fҶԶn𶜳 o j7 .⶜ oonƶvT&ԶnzഔnvTn"7 `$܃&4.X8onε.$&4zഔnX47 &֌j8&B<XFonndFҶ6 FX@Lf\\C>8Ir/*@X"%.@8 BFP@TZ dAe&&\7 e lF7 kHLV7 piXZ\7 `Ԅ$ oVglpt~7 DlF7 8kHLV7 (iXZ7 Ԅ( oVglpt7 ƴ$X|7 j7 j|7 vVonDl7 jV7 PVonfl7 j7 ӨVonl7 ~j7 lӰVonl7 \j7 JӸVon̸l7 :lF7 (ӨVon o o ާ ƽнԽڽ޽7 , o@0 oBvVonDާ ƽн7 0nT& l7 kƽ޽V7 jX7 l7 vkڽV7 fiX7 VҸVonj7 F n(27 2,,n܃&6,nv60nTʽ܃&:j޽:|7 mD7 >潲n>on2nȹj7 ѸVonLl7 nvLT&V`:PnJonz`iF7 `np7 rP&hb܃nk:V7 LZnr޽7 4.| n(27 ",,n܃&6,nv60nTʽ܃&:bP܃&hjh:|7 αrX7 Ќ潲nNonfb܃nZk:X7 :l66|7 .FX8onnro|rzȺ:Pn8onnPnr:rn:rnTpl>o|r:tn:nFTpt>l7 kڽV7 iX7 ϸVonJj7 mD7 >潲n>onnnRj޽޽|7 ϸVonl7 x@Vonl7 b4Vonj7 LvVonмj7 6PVonj7 Vonj7 Vonj7 Fx\2\ \ @A@33\ MINIMUM VALUE A@ff\(F7.3)MAXIMUM VALUE (F7.3)vA\ \  \ ʽe0AԽ`3@33TIMEA\INPUT CG#BBHIT KEYSET TO START 6/\P">Z\l\\\&&\L?HIT KEYSET TO RETURN&&\D!7  ܃Tྀw(&&\,K! 0@&&\\HpCHC7 v@nnnl 7 j 7  oH oJBVonLާ "&*8:>7 RVon o oާ "&LZ^b7 vH"&J7 Fڵܵ޵H"&X7 kZ:d7 iJfh7 FXXX0A3@33DISPLACEMENT AC\TIME\AHIT KEYSET TO RETURNg\\e\\ \\\\\\ \\&g\&e\& \&\&\& \