├── LICENSE ├── README.md ├── build ├── cleanup ├── fs ├── Readme ├── root │ ├── bin │ │ ├── ar │ │ └── as │ ├── etc │ │ └── as2 │ └── tmp │ │ └── .gitkeep └── usr │ └── lib │ ├── bilib.a │ └── libb.a ├── source └── libb │ ├── char.s │ ├── chdir.s │ ├── chmod.s │ ├── chown.s │ ├── close.s │ ├── creat.s │ ├── ctime.s │ ├── execl.s │ ├── execv.s │ ├── exit.s │ ├── fork.s │ ├── fstat.s │ ├── getchr.s │ ├── getuid.s │ ├── gtty.s │ ├── hog.s │ ├── intr.s │ ├── lchar.s │ ├── link.s │ ├── makdir.s │ ├── open.s │ ├── printf.s │ ├── printn.s │ ├── putchr.s │ ├── quit.s │ ├── read.s │ ├── seek.s │ ├── setuid.s │ ├── sleep.s │ ├── stat.s │ ├── stty.s │ ├── time.s │ ├── unlink.s │ ├── wait.s │ └── write.s └── tools ├── Readme ├── apout ├── CHANGES ├── COPYRIGHT ├── LCLINT ├── LIMITATIONS ├── Makefile ├── README ├── TODO ├── aout.c ├── aout.h ├── apout.1 ├── branch.c ├── bsd_ioctl.c ├── bsd_signal.c ├── bsdtrap.c ├── bsdtrap.h ├── cpu.c ├── debug.c ├── defines.h ├── double.c ├── ea.c ├── fp.c ├── itab.c ├── ke11a.c ├── magic.c ├── main.c ├── single.c ├── v1trap.c ├── v1trap.h ├── v7trap.c └── v7trap.h └── disaout ├── Makefile ├── README ├── aout.c ├── aout.h ├── magic.c ├── main.c ├── opset.c ├── symbols.c └── syscalls.c /README.md: -------------------------------------------------------------------------------- 1 | # pdp11-B 2 | 3 | This project is an effort to recreate the B compiler for the PDP-11 as authentically as possible, given the few remaining code fragments from the earliest Unix sources and much educated guesswork. 4 | 5 | ### License 6 | The project is distributed under the terms of the GNU General Public License Version 3. 7 | 8 | ### Resources and Contributors 9 | The Unix Heritage Society [www.tuhs.org](https://www.tuhs.org/) 10 | unix-jun72 [github.com/DoctorWkt/unix-jun72](https://github.com/DoctorWkt/unix-jun72) 11 | Angelo Papenhoff [squoze.net](http://squoze.net/B) 12 | -------------------------------------------------------------------------------- /build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # build apout 4 | cd tools/apout 5 | make 6 | cd ../.. 7 | export APOUT_ROOT=$PWD/fs/root 8 | 9 | # extract /usr/lib/libb.a 10 | rm -rf libb 11 | mkdir libb 12 | cd libb 13 | ../tools/apout/apout ../fs/root/bin/ar x ../fs/usr/lib/libb.a 14 | cd .. 15 | 16 | # build and compare source/libb 17 | cd source 18 | echo char.s; ../tools/apout/apout ../fs/root/bin/as libb/char.s; diff a.out ../libb/char.o 19 | echo chdir.s; ../tools/apout/apout ../fs/root/bin/as libb/chdir.s; diff a.out ../libb/chdir.o 20 | echo chmod.s; ../tools/apout/apout ../fs/root/bin/as libb/chmod.s; diff a.out ../libb/chmod.o 21 | echo chown.s; ../tools/apout/apout ../fs/root/bin/as libb/chown.s; diff a.out ../libb/chown.o 22 | echo close.s; ../tools/apout/apout ../fs/root/bin/as libb/close.s; diff a.out ../libb/close.o 23 | echo creat.s; ../tools/apout/apout ../fs/root/bin/as libb/creat.s; diff a.out ../libb/creat.o 24 | echo ctime.s; ../tools/apout/apout ../fs/root/bin/as libb/ctime.s; diff a.out ../libb/ctime.o 25 | echo execl.s; ../tools/apout/apout ../fs/root/bin/as libb/execl.s; diff a.out ../libb/execl.o 26 | echo execv.s; ../tools/apout/apout ../fs/root/bin/as libb/execv.s; diff a.out ../libb/execv.o 27 | echo exit.s; ../tools/apout/apout ../fs/root/bin/as libb/exit.s; diff a.out ../libb/exit.o 28 | echo fork.s; ../tools/apout/apout ../fs/root/bin/as libb/fork.s; diff a.out ../libb/fork.o 29 | echo fstat.s; ../tools/apout/apout ../fs/root/bin/as libb/fstat.s; diff a.out ../libb/fstat.o 30 | echo getchr.s; ../tools/apout/apout ../fs/root/bin/as libb/getchr.s; diff a.out ../libb/getchr.o 31 | echo getuid.s; ../tools/apout/apout ../fs/root/bin/as libb/getuid.s; diff a.out ../libb/getuid.o 32 | echo gtty.s; ../tools/apout/apout ../fs/root/bin/as libb/gtty.s; diff a.out ../libb/gtty.o 33 | echo hog.s; ../tools/apout/apout ../fs/root/bin/as libb/hog.s; diff a.out ../libb/hog.o 34 | echo intr.s; ../tools/apout/apout ../fs/root/bin/as libb/intr.s; diff a.out ../libb/intr.o 35 | echo lchar.s; ../tools/apout/apout ../fs/root/bin/as libb/lchar.s; diff a.out ../libb/lchar.o 36 | echo link.s; ../tools/apout/apout ../fs/root/bin/as libb/link.s; diff a.out ../libb/link.o 37 | echo makdir.s; ../tools/apout/apout ../fs/root/bin/as libb/makdir.s; diff a.out ../libb/makdir.o 38 | echo open.s; ../tools/apout/apout ../fs/root/bin/as libb/open.s; diff a.out ../libb/open.o 39 | echo printf.s; ../tools/apout/apout ../fs/root/bin/as libb/printf.s; diff a.out ../libb/printf.o 40 | echo printn.s; ../tools/apout/apout ../fs/root/bin/as libb/printn.s; diff a.out ../libb/printn.o 41 | echo putchr.s; ../tools/apout/apout ../fs/root/bin/as libb/putchr.s; diff a.out ../libb/putchr.o 42 | echo quit.s; ../tools/apout/apout ../fs/root/bin/as libb/quit.s; diff a.out ../libb/quit.o 43 | echo read.s; ../tools/apout/apout ../fs/root/bin/as libb/read.s; diff a.out ../libb/read.o 44 | echo seek.s; ../tools/apout/apout ../fs/root/bin/as libb/seek.s; diff a.out ../libb/seek.o 45 | echo setuid.s; ../tools/apout/apout ../fs/root/bin/as libb/setuid.s; diff a.out ../libb/setuid.o 46 | echo sleep.s; ../tools/apout/apout ../fs/root/bin/as libb/sleep.s; diff a.out ../libb/sleep.o 47 | echo stat.s; ../tools/apout/apout ../fs/root/bin/as libb/stat.s; diff a.out ../libb/stat.o 48 | echo stty.s; ../tools/apout/apout ../fs/root/bin/as libb/stty.s; diff a.out ../libb/stty.o 49 | echo time.s; ../tools/apout/apout ../fs/root/bin/as libb/time.s; diff a.out ../libb/time.o 50 | echo unlink.s; ../tools/apout/apout ../fs/root/bin/as libb/unlink.s; diff a.out ../libb/unlink.o 51 | echo wait.s; ../tools/apout/apout ../fs/root/bin/as libb/wait.s; diff a.out ../libb/wait.o 52 | echo write.s; ../tools/apout/apout ../fs/root/bin/as libb/write.s; diff a.out ../libb/write.o 53 | cd .. 54 | 55 | # extract /usr/lib/bilib.a 56 | rm -rf bilib 57 | mkdir bilib 58 | cd bilib 59 | ../tools/apout/apout ../fs/root/bin/ar x ../fs/usr/lib/bilib.a 60 | cd .. 61 | 62 | # build and compare source/bilib 63 | cd source 64 | cd .. 65 | -------------------------------------------------------------------------------- /cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd tools/apout 4 | make clean 5 | cd ../.. 6 | 7 | rm -rf libb 8 | rm -rf bilib 9 | rm source/a.out -------------------------------------------------------------------------------- /fs/Readme: -------------------------------------------------------------------------------- 1 | The directories root/ and usr/ contain files from the "s2-bits tape", 2 | which Dennis Ritchie extracted from an old DECtape at Bell Labs, which is 3 | available here: 4 | 5 | https://www.tuhs.org/Archive/Distributions/Research/1972_stuff/ 6 | 7 | The files were sourced from the unix-jun72 project: 8 | 9 | https://github.com/DoctorWkt/unix-jun72 10 | -------------------------------------------------------------------------------- /fs/root/bin/ar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswier/pdp11-B/1c5490c35347424f0b9d09014d21cde2fa35a26f/fs/root/bin/ar -------------------------------------------------------------------------------- /fs/root/bin/as: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswier/pdp11-B/1c5490c35347424f0b9d09014d21cde2fa35a26f/fs/root/bin/as -------------------------------------------------------------------------------- /fs/root/etc/as2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswier/pdp11-B/1c5490c35347424f0b9d09014d21cde2fa35a26f/fs/root/etc/as2 -------------------------------------------------------------------------------- /fs/root/tmp/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswier/pdp11-B/1c5490c35347424f0b9d09014d21cde2fa35a26f/fs/root/tmp/.gitkeep -------------------------------------------------------------------------------- /fs/usr/lib/bilib.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswier/pdp11-B/1c5490c35347424f0b9d09014d21cde2fa35a26f/fs/usr/lib/bilib.a -------------------------------------------------------------------------------- /fs/usr/lib/libb.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rswier/pdp11-B/1c5490c35347424f0b9d09014d21cde2fa35a26f/fs/usr/lib/libb.a -------------------------------------------------------------------------------- /source/libb/char.s: -------------------------------------------------------------------------------- 1 | / B library -- char 2 | 3 | .globl .char 4 | .globl n7 5 | 6 | .text 7 | .char: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r1 12 | asl r1 13 | add (r5),r1 14 | movb (r1),r0 15 | mov r0,(r5)+ 16 | jmp n7 17 | -------------------------------------------------------------------------------- /source/libb/chdir.s: -------------------------------------------------------------------------------- 1 | / B library -- chdir 2 | 3 | .globl .chdir 4 | .globl n7 5 | 6 | .text 7 | .chdir: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,1f 13 | clr (r5) 14 | sys chdir; 1:.. 15 | sbc (r5)+ 16 | jmp n7 17 | -------------------------------------------------------------------------------- /source/libb/chmod.s: -------------------------------------------------------------------------------- 1 | / B library -- chmod 2 | 3 | .globl .chmod 4 | .globl n7 5 | 6 | .text 7 | .chmod: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,1f 13 | mov (r5)+,2f 14 | clr (r5) 15 | sys chmod; 1:..; 2:.. 16 | sbc (r5)+ 17 | jmp n7 18 | -------------------------------------------------------------------------------- /source/libb/chown.s: -------------------------------------------------------------------------------- 1 | / B library -- chown 2 | 3 | .globl .chown 4 | .globl n7 5 | 6 | .text 7 | .chown: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,1f 13 | mov (r5)+,2f 14 | clr (r5) 15 | sys chown; 1:..; 2:.. 16 | sbc (r5)+ 17 | jmp n7 -------------------------------------------------------------------------------- /source/libb/close.s: -------------------------------------------------------------------------------- 1 | / B library -- close 2 | 3 | .globl .close 4 | .globl n11 5 | 6 | .text 7 | .close: .+2 8 | .+2 9 | mov 4(r4),r0 10 | sys close 11 | jmp n11 12 | -------------------------------------------------------------------------------- /source/libb/creat.s: -------------------------------------------------------------------------------- 1 | / B library -- creat 2 | 3 | .globl .creat 4 | .globl n7 5 | 6 | .text 7 | .creat: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,1f 13 | mov (r5)+,2f 14 | sys creat; 1:..; 2:.. 15 | bcc 1f 16 | mov $-1,r0 17 | 1: 18 | mov r0,(r5)+ 19 | jmp n7 -------------------------------------------------------------------------------- /source/libb/ctime.s: -------------------------------------------------------------------------------- 1 | / B library -- close 2 | 3 | .globl .close 4 | .globl n11 5 | 6 | .text 7 | .close: .+2 8 | .+2 9 | mov 4(r4),r0 10 | sys close 11 | jmp n11 12 | -------------------------------------------------------------------------------- /source/libb/execl.s: -------------------------------------------------------------------------------- 1 | / B library -- execl 2 | 3 | .globl .execl 4 | .globl n11 5 | 6 | .text 7 | .execl: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,2f 13 | mov r5,3f 14 | 1: 15 | asl (r5)+ 16 | bne 1b 17 | sys exec; 2:..; 3:.. 18 | jmp n11 19 | -------------------------------------------------------------------------------- /source/libb/execv.s: -------------------------------------------------------------------------------- 1 | / B library -- execv 2 | 3 | .globl .execv 4 | .globl n11 5 | 6 | .text 7 | .execv: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,3f 13 | mov (r5),r0 14 | asl r0 15 | mov r5,4f 16 | mov r5,r1 17 | mov 2(r5),-(sp) 18 | 1: 19 | dec (sp) 20 | blt 2f 21 | mov (r0)+,(r1) 22 | asl (r1)+ 23 | bne 1b 24 | 2: 25 | tst (sp)+ 26 | clr (r1)+ 27 | sys exec; 3:..; 4:.. 28 | jmp n11 29 | -------------------------------------------------------------------------------- /source/libb/exit.s: -------------------------------------------------------------------------------- 1 | / B library -- exit 2 | 3 | .globl .exit 4 | 5 | .text 6 | .exit: .+2 7 | .+2 8 | sys exit 9 | -------------------------------------------------------------------------------- /source/libb/fork.s: -------------------------------------------------------------------------------- 1 | / B library -- fork 2 | 3 | .globl .fork 4 | .globl n7 5 | 6 | .text 7 | .fork: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | sys fork 12 | clr r0 13 | bcc 1f 14 | mov $-1,r0 15 | 1: 16 | mov r0,(r5)+ 17 | jmp n7 18 | -------------------------------------------------------------------------------- /source/libb/fstat.s: -------------------------------------------------------------------------------- 1 | / B library -- fstat 2 | 3 | .globl .fstat 4 | .globl n7 5 | 6 | .text 7 | .fstat: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r0 12 | asl (r5) 13 | mov (r5)+,1f 14 | clr (r5) 15 | sys fstat; 1:..; 05625 16 | jmp n7 17 | -------------------------------------------------------------------------------- /source/libb/getchr.s: -------------------------------------------------------------------------------- 1 | / B library -- getchar 2 | 3 | .globl .getchar 4 | .globl n7 5 | .globl .fin 6 | 7 | .text 8 | .getchar: 9 | .+2 10 | .+2 11 | mov r4,r5 12 | cmp (r5)+,(r5)+ 13 | mov .fin,r0 14 | sys read; ch; 01 15 | bcs 1f 16 | tst r0 17 | bne 2f 18 | 1: 19 | clr ch 20 | 2: 21 | mov ch,(r5)+ 22 | jmp n7 23 | 24 | ch: .=.+2 25 | .fin: 0 26 | -------------------------------------------------------------------------------- /source/libb/getuid.s: -------------------------------------------------------------------------------- 1 | / B library -- getuid 2 | 3 | .globl .getuid 4 | .globl n7 5 | 6 | .text 7 | .getuid: 8 | .+2 9 | .+2 10 | mov r4,r5 11 | cmp (r5)+,(r5)+ 12 | sys getuid 13 | mov r0,(r5)+; 14 | jmp n7 15 | -------------------------------------------------------------------------------- /source/libb/gtty.s: -------------------------------------------------------------------------------- 1 | / B library -- gtty 2 | 3 | .globl .gtty 4 | .globl n7 5 | 6 | .text 7 | .gtty: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r0 12 | asl (r5) 13 | mov (r5)+,0f 14 | clr (r5) 15 | sys gtty; 0:.. 16 | sbc (r5)+ 17 | jmp n7 18 | -------------------------------------------------------------------------------- /source/libb/hog.s: -------------------------------------------------------------------------------- 1 | / B library -- hog 2 | 3 | .globl .hog 4 | .globl n11 5 | 6 | .text 7 | .hog: .+2 8 | .+2 9 | sys hog 10 | jmp n11 11 | -------------------------------------------------------------------------------- /source/libb/intr.s: -------------------------------------------------------------------------------- 1 | / B library -- intr 2 | 3 | .globl .intr 4 | .globl n11 5 | 6 | .text 7 | .intr: .+2 8 | .+2 9 | mov 4(r4),r0 10 | cmp r0,$1 11 | bhi 1f 12 | mov r0,0f 13 | sys intr; 0:.. 14 | jmp n11 15 | 1: 16 | mov r0,3f 17 | mov r4,4f 18 | mov r2,5f 19 | sys intr; 2f 20 | jmp n11 21 | 2: 22 | mov 3f,r3 23 | mov *4f,r4 24 | mov 5f,r2 25 | jmp *(r3)+ 26 | 27 | 3: .=.+2 28 | 4: .=.+2 29 | 5: .=.+2 30 | -------------------------------------------------------------------------------- /source/libb/lchar.s: -------------------------------------------------------------------------------- 1 | / B library -- lchar 2 | 3 | .globl .lchar 4 | .globl n7 5 | 6 | .text 7 | .lchar: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r0 12 | asl r0 13 | add (r5)+,r0 14 | mov (r5)+,r1 15 | movb r1,(r0) 16 | jmp n7 17 | -------------------------------------------------------------------------------- /source/libb/link.s: -------------------------------------------------------------------------------- 1 | / B library -- link 2 | 3 | .globl .link 4 | .globl n7 5 | 6 | .text 7 | .link: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,0f 13 | asl (r5) 14 | mov (r5)+,1f 15 | clr (r5) 16 | sys link; 0:..; 1:.. 17 | sbc (r5)+ 18 | jmp n7 19 | -------------------------------------------------------------------------------- /source/libb/makdir.s: -------------------------------------------------------------------------------- 1 | / B library -- makdir 2 | 3 | .globl .makdir 4 | .globl n7 5 | 6 | .text 7 | .makdir: 8 | .+2 9 | .+2 10 | mov r4,r5 11 | cmp (r5)+,(r5)+ 12 | asl (r5) 13 | mov (r5)+,0f 14 | clr (r5) 15 | sys makdir; 0:.. 16 | sbc (r5)+ 17 | jmp n7 18 | -------------------------------------------------------------------------------- /source/libb/open.s: -------------------------------------------------------------------------------- 1 | / B library -- open 2 | 3 | .globl .open 4 | .globl n7 5 | 6 | .text 7 | .open: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,0f 13 | mov (r5)+,1f 14 | sys open; 0:..; 1:.. 15 | bcc 1f 16 | mov $-1,r0 17 | 1: 18 | mov r0,(r5)+ 19 | jmp n7 20 | -------------------------------------------------------------------------------- /source/libb/printf.s: -------------------------------------------------------------------------------- 1 | / B library -- close 2 | 3 | .globl .close 4 | .globl n11 5 | 6 | .text 7 | .close: .+2 8 | .+2 9 | mov 4(r4),r0 10 | sys close 11 | jmp n11 12 | -------------------------------------------------------------------------------- /source/libb/printn.s: -------------------------------------------------------------------------------- 1 | / B library -- printn 2 | 3 | .globl .printn 4 | .globl n11 5 | 6 | .text 7 | .printn: 8 | .+2 9 | .+2 10 | mov 4(r4),r0 11 | sys close 12 | jmp n11 13 | -------------------------------------------------------------------------------- /source/libb/putchr.s: -------------------------------------------------------------------------------- 1 | / B library -- putchar 2 | 3 | .globl .putchar 4 | .globl n7 5 | .globl n11 6 | .globl .flush 7 | .globl .fout 8 | 9 | .text 10 | .putchar: 11 | .+2 12 | .+2 13 | mov r4,r5 14 | cmp (r5)+,(r5)+ 15 | mov (r5)+,ch 16 | mov .fout,r0 17 | tstb ch+1 18 | beq 1f 19 | swab ch 20 | sys write; ch; 02 21 | 0403 22 | 1: 23 | sys write; ch; 01 24 | 2: 25 | jmp n7 26 | 27 | .flush: 28 | .+2 29 | n11 30 | 31 | ch: .=.+2 32 | .fout: 1 -------------------------------------------------------------------------------- /source/libb/quit.s: -------------------------------------------------------------------------------- 1 | / B library -- quit 2 | 3 | .globl .quit 4 | .globl n11 5 | 6 | .text 7 | .quit: .+2 8 | .+2 9 | mov 4(r4),r0 10 | cmp r0,$1 11 | bhi 1f 12 | mov r0,0f 13 | sys quit; 0:.. 14 | jmp n11 15 | 1: 16 | mov r0,3f 17 | mov r4,4f 18 | mov r2,5f 19 | sys quit; 2f 20 | jmp n11 21 | 2: 22 | mov 3f,r3 23 | mov *4f,r4 24 | mov 5f,r2 25 | jmp *(r3)+ 26 | 27 | 3: .=.+2 28 | 4: .=.+2 29 | 5: .=.+2 30 | -------------------------------------------------------------------------------- /source/libb/read.s: -------------------------------------------------------------------------------- 1 | / B library -- read 2 | 3 | .globl .read 4 | .globl n7 5 | 6 | .text 7 | .read: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r0 12 | asl (r5) 13 | mov (r5)+,0f 14 | mov (r5)+,1f 15 | sys read; 0:..; 1:.. 16 | bcc 1f 17 | mov $-1,r0 18 | 1: 19 | mov r0,(r5)+ 20 | jmp n7 21 | -------------------------------------------------------------------------------- /source/libb/seek.s: -------------------------------------------------------------------------------- 1 | / B library -- seek 2 | 3 | .globl .seek 4 | .globl n7 5 | 6 | .text 7 | .seek: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r0 12 | mov (r5)+,0f 13 | mov (r5)+,1f 14 | clr (r5) 15 | sys seek; 0:..; 1:.. 16 | sbc (r5)+ 17 | jmp n7 18 | -------------------------------------------------------------------------------- /source/libb/setuid.s: -------------------------------------------------------------------------------- 1 | / B library -- setuid 2 | 3 | .globl .setuid 4 | .globl n7 5 | 6 | .text 7 | .setuid: 8 | .+2 9 | .+2 10 | mov r4,r5 11 | cmp (r5)+,(r5)+ 12 | mov (r5)+,r0 13 | clr (r5) 14 | sys setuid 15 | sbc (r5)+ 16 | jmp n7 17 | -------------------------------------------------------------------------------- /source/libb/sleep.s: -------------------------------------------------------------------------------- 1 | / B library -- sleep 2 | 3 | .globl .sleep 4 | .globl n11 5 | 6 | sleep = 35. 7 | 8 | .text 9 | .sleep: .+2 10 | .+2 11 | mov 4(r4),r0 12 | sys sleep 13 | jmp n11 14 | -------------------------------------------------------------------------------- /source/libb/stat.s: -------------------------------------------------------------------------------- 1 | / B library -- stat 2 | 3 | .globl .stat 4 | .globl n7 5 | 6 | .text 7 | .stat: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | asl (r5) 12 | mov (r5)+,0f 13 | asl (r5) 14 | mov (r5)+,1f 15 | clr (r5) 16 | sys stat; 0:..; 1:.. 17 | sbc (r5)+ 18 | jmp n7 19 | -------------------------------------------------------------------------------- /source/libb/stty.s: -------------------------------------------------------------------------------- 1 | / B library -- stty 2 | 3 | .globl .stty 4 | .globl n7 5 | 6 | .text 7 | .stty: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r0 12 | asl (r5) 13 | mov (r5)+,0f 14 | clr (r5) 15 | sys stty; 0:..; 16 | sbc (r5)+ 17 | jmp n7 18 | -------------------------------------------------------------------------------- /source/libb/time.s: -------------------------------------------------------------------------------- 1 | / B library -- time 2 | 3 | .globl .time 4 | .globl n11 5 | 6 | .text 7 | .time: .+2 8 | .+2 9 | sys time 10 | mov 4(r4),r0 11 | asl r0 12 | mov ac,(r0)+ 13 | mov mq,(r0)+ 14 | jmp n11 15 | -------------------------------------------------------------------------------- /source/libb/unlink.s: -------------------------------------------------------------------------------- 1 | / B library -- unlink 2 | 3 | .globl .unlink 4 | .globl n7 5 | 6 | .text 7 | .unlink: 8 | .+2 9 | .+2 10 | mov r4,r5 11 | cmp (r5)+,(r5)+ 12 | asl (r5) 13 | mov (r5)+,0f 14 | clr (r5) 15 | sys unlink; 0:.. 16 | sbc (r5)+ 17 | jmp n7 18 | -------------------------------------------------------------------------------- /source/libb/wait.s: -------------------------------------------------------------------------------- 1 | / B library -- wait 2 | 3 | .globl .wait 4 | .globl n7 5 | 6 | .text 7 | .wait: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | sys wait 12 | bcc 1f 13 | mov $-1,r0 14 | 1: 15 | mov r0,(r5)+ 16 | jmp n7 17 | -------------------------------------------------------------------------------- /source/libb/write.s: -------------------------------------------------------------------------------- 1 | / B library -- write 2 | 3 | .globl .write 4 | .globl n7 5 | 6 | .text 7 | .write: .+2 8 | .+2 9 | mov r4,r5 10 | cmp (r5)+,(r5)+ 11 | mov (r5)+,r0 12 | asl (r5) 13 | mov (r5)+,0f 14 | mov (r5)+,1f 15 | sys write; 0:..; 1:.. 16 | bcc 1f 17 | mov $-1,r0 18 | 1: 19 | mov r0,(r5)+ 20 | jmp n7 -------------------------------------------------------------------------------- /tools/Readme: -------------------------------------------------------------------------------- 1 | The apout/ directory contains the Apout simulator for PDP-11 Unix a.out binaries. 2 | 3 | The disaout/ directoy contains a disassembler for a.out binraries. 4 | 5 | These were sourced from the unix-jun72 project: 6 | 7 | https://github.com/DoctorWkt/unix-jun72 8 | -------------------------------------------------------------------------------- /tools/apout/CHANGES: -------------------------------------------------------------------------------- 1 | 2.3 Beta1: to 10th June 2002 2 | ---------------------------- 3 | 4 | Changed debug statements in cpu.c to be TrapDebug statements as I was 5 | seeing output from these in the output file of 2.11BSD /lib/cpp. 6 | 7 | The problem with scripts has also been fixed, finally. I was passing 8 | the wrong path into the shell arguments. 9 | 10 | On a 1.6GHz Pentium 4 running FreeBSD 4.5, a make depend; make of the 11 | 2.11BSD GENERIC kernel takes 72 seconds. 12 | 13 | 2.3 Alpha3: to 1st June 2001 14 | ---------------------------- 15 | 16 | Added patches from Wilhelm B. Kloke wb@vestein.arb-phys.uni-dortmund.de 17 | to get Apout to run the Algol 68 binaries found which were added into 18 | the Unix Archive. 19 | 20 | A few changes for better Linux compilation. However, stream buffering 21 | doesn't seem to work on Linux, at least RedHat 6.2. 22 | 23 | 2.3 Alpha2: to 10th Jan 2000 24 | ---------------------------- 25 | 26 | Added partial support for 0407-magic binaries from 2nd Edition. At 27 | present, this is enough for the C compiler on Dennis Ritchie's s2.tar 28 | archive to work. It's also good enough for the C compiler to recompile 29 | the last1120c compiler, and for the last1120c compiler to recompile itself. 30 | 31 | Added code to support 512-byte block seeks on /dev files for 1st Edition 32 | binaries. This was required to get tap(1) to work. This should really 33 | only force 512-byte seeks on specific /dev/files, not all of them. 34 | 35 | A significant rearrangement of the code in aout.c was done to make it 36 | more logical. I wouldn't say it was much tidier than before, though. 37 | 38 | A redefinition of sigset_t in NetBSD stopped Apout from being compiled 39 | there. Thanks to Soren, bsdsignal.c was modified to fix this problem. 40 | 41 | Some small changes to the output from -inst to make it look better. 42 | Added a WRITEBASE #define to help improve performance just a bit more. 43 | 44 | 2.3 Alpha1: to 2nd Jan 2000 45 | --------------------------- 46 | 47 | Added nearly complete support for 0405-magic binaries from 1st Edition, 48 | including emulating the KE11A extended arithmetic element. Still some 49 | work needed here on both the trap handling and KE11A support. Thanks to 50 | Tim Shoppa (shoppa@trailing-edge.com) for his eae code. The 0407-magic 51 | binaries from Dennis Ritchie's s2.tar archive are not yet supported. I 52 | need the V2/V3 manuals from Norman Wilson for this. 53 | 54 | Some tidying up of the code has been done, using LCLINT and by hand. 55 | I've made a Debug() macro which make the code look a bit cleaner. 56 | 57 | Some memory leaks removed. Natives exec()s now inherit the original 58 | environment, not the emulated one. Some mov() functions split into 59 | separate functions to help improve performance. Added a workaround 60 | for date handling in V5/V6 ctime(): see tail of v7trap.c. 61 | 62 | Stream buffering variables consolidated into main.c and some bugs 63 | removed (e.g "rw" -> "w+"). 2.11BSD emulation now has stream buffering, 64 | but it is turned off by default as it doesn't seem to provide any 65 | improvement in performance. 66 | 67 | 2.2 Alpha9: to 2nd Mar 1999 68 | --------------------------- 69 | 70 | I've added magic numbers for some 2.9BSD binaries: all 2.9 binaries 71 | run in the V7 environment, which seems to work but I'm sure that 72 | 2.9 != V7. 73 | 74 | With help from Jonathan Naylor (g4klx@g4klx.demon.co.uk), and some work 75 | myself, I've managed to compile Apout under RedHat Linux 2.2. There are 76 | some 2.11BSD syscalls not implemented as a result, but I can recompile 77 | the V7 and the 2.11BSD kernels, which is a good indicator. 78 | 79 | 80 | 2.2 Alpha8: to 15th Jan 1999 81 | ---------------------------- 82 | 83 | These changes came about due to my attempt to compile the UNIX `nsys' 84 | kernel source code, dated 1973, with the 5th Edition development tools. 85 | 86 | Added better detection of some special UNIX a.out binaries: the 87 | environment for these binaries was being incorrectly set by aout.c. 88 | There is now a magic.c which fixes the problem. See also LIMITATIONS 89 | for a note of bugs in some a.out binaries. 90 | 91 | Modified v7trap.c to be much cleaner, and to look a bit more like 92 | bsdtrap.c. Introduced several small bugs in V5/V6/V7 syscall emulation, 93 | notably pipe() and dup(), by the cleanup. These are fixed. 94 | 95 | 96 | 2.2 Alpha7: to 11th Jan 1999 97 | ---------------------------- 98 | 99 | Modified the code to handle the syscall differences between 100 | V6 and V7: note that V5 and V6 are syscall identical. V6 has 101 | a different seek() and stat() to V7. 102 | 103 | Added a new file for 2.11BSD ioctls, did many of the terminal 104 | ioctls, and a few more syscalls. Now 2.11 vi runs. However, 105 | longjmp() doesn't work yet, because it requires working signals. 106 | 107 | Changed some types and #ifdefs for NetBSD and OpenBSD: thanks Soren! 108 | 109 | 110 | 2.2 Alpha6: to 6th Jan 1999 111 | --------------------------- 112 | 113 | Bugfixes: none that I can think of. 114 | 115 | Enhancements: tidied the code up somewhat. Changed uint -> u_int 116 | throughout. Added support for execution of native binaries: now I can 117 | run vi from inside 2.11 bin/sh, yay! Finally wrote the long-overdue 118 | manual page. Added RCS tags to all sources. Ensured that it compiled on 119 | FreeBSD 3.x and 2.1.x: I need to take it home for FreeBSD 2.2.x. 120 | 121 | 122 | 2.2 Alpha5: to 5th Jan 1999 123 | --------------------------- 124 | 125 | Bugfixes: fixed malloc bug, which was a too-large blksize from stat/fstat. 126 | Fixed the gtty/stty emulation, which was causing make to break. 127 | 128 | Enhancements: Apout can now run shell scripts. 2.11BSD overlay binaries 129 | are now supported, which is good news. I can now compile the 2.11 GENERIC 130 | kernel with no manual intervention. On a Pentium II 350MHz, this takes 131 | 4:16secs with an optimised Apout. 132 | 133 | 134 | 2.2 Alpha4: to 2nd Jan 1999 135 | --------------------------- 136 | 137 | Fixed more deficiencies in the 2.11BSD emulation, in particular 138 | fork(), vfork() and sbrk(). The argv/envp environment is better 139 | but still not totally correct, I think. Finally got the correct 140 | code for 2.11 readdir(). 141 | 142 | We now have a semi-working FP emulation. It's enough to keep 2.11 143 | happy, but it isn't very good. It will do for now. 144 | 145 | Many of the 2.11BSD syscalls are now implemented. Most are not 146 | verified, but a lot of 2.11BSD commands run, including sh, make, 147 | cc, date, cal. ls(1) goes into an infinite loop when doing ls -l, 148 | the inf. loop is in malloc(3). By substituting malloc(3) from 149 | Minix 1.3, this problem goes away. I don't know if it's a bug 150 | in the emulator, or in the 2.11 malloc() code. 151 | 152 | 153 | 2.2 Alpha3 to 5th Dec 1998 154 | -------------------------- 155 | 156 | Reorganised bsdtrap.[ch], and started work on the 157 | 2.11BSD emulated syscalls; this is surprisingly 158 | easy for many of them. 159 | 160 | 161 | Changes from 2.1 to 2.2 162 | ----------------------- 163 | 164 | + General code tidying up and niggling bug removal. 165 | + Code optimisation to speed things up, although 166 | I haven't quantified the improvement yet. 167 | + Separation of the binary loader and trap handlers 168 | from the main program. This doesn't do anything now, 169 | but it will make the emulation of several PDP-11 170 | environments (e.g 2.11BSD, RT-11) much easier to do. 171 | + Finished getting the stream buffering of I/O to work. 172 | I still don't know why fdopen doesn't work on "rw". 173 | + Some extra trap functionality, e.g basic signal handling. 174 | -------------------------------------------------------------------------------- /tools/apout/COPYRIGHT: -------------------------------------------------------------------------------- 1 | The Apout simulator is copyright Warren Toomey, and is protected by the 2 | following notice. 3 | 4 | /* Apout is a PDP-11 a.out simulator. 5 | * 6 | * For information contact: 7 | * 8 | * Email: wkt@tuhs.org 9 | * FTP: ftp://minnie.tuhs.org/pup/PDP-11/Sims/Apout 10 | * 11 | * Copyright 1995-2002, Warren Toomey 12 | * 13 | * Permission to use, copy, modify, and distribute this software and its 14 | * documentation for any purpose and without fee is hereby granted, provided 15 | * that the above copyright notice appear in all copies. Warren Toomey 16 | * makes no representations about the suitability of this software for any 17 | * purpose. It is provided "as is" without expressed or implied warranty. 18 | */ 19 | 20 | ------ 21 | 22 | The parts of Apout that deal with PDP-11 instruction emulation are derived 23 | from the PDP-11 simulator written by Eric A. Edwards, and are protected by 24 | the following notice. 25 | 26 | /* Parts of Apout are derived from 'pdp', a PDP-11 simulator. 27 | * 28 | * For information contact: 29 | * 30 | * Computer Science House 31 | * Attn: Eric Edwards 32 | * Box 861 33 | * 25 Andrews Memorial Drive 34 | * Rochester, NY 14623 35 | * 36 | * Email: mag@potter.csh.rit.edu 37 | * FTP: ftp.csh.rit.edu:/pub/csh/mag/pdp.tar.Z 38 | * 39 | * Copyright 1994, Eric A. Edwards 40 | * 41 | * Permission to use, copy, modify, and distribute this software and its 42 | * documentation for any purpose and without fee is hereby granted, provided 43 | * that the above copyright notice appear in all copies. Eric A. Edwards 44 | * makes no representations about the suitability of this software for any 45 | * purpose. It is provided "as is" without expressed or implied warranty. 46 | */ 47 | -------------------------------------------------------------------------------- /tools/apout/LCLINT: -------------------------------------------------------------------------------- 1 | aout.c Fri Sep 17 13:00:33 EST 1999 2 | branch.c Fri Sep 17 13:00:33 EST 1999 3 | bsd_ioctl.c Fri Sep 17 13:03:34 EST 1999 4 | bsd_signal.c 5 | bsdtrap.c 6 | cpu.c Fri Sep 17 15:04:05 EST 1999 bits to do 7 | debug.c Fri Sep 17 15:04:01 EST 1999 8 | double.c Fri Sep 17 15:08:46 EST 1999 9 | ea.c Fri Sep 17 15:10:51 EST 1999 10 | fp.c 11 | itab.c Fri Sep 17 13:00:33 EST 1999 12 | ke11a.c 13 | magic.c Fri Sep 17 13:00:33 EST 1999 14 | main.c 15 | single.c 16 | v7trap.c 17 | -------------------------------------------------------------------------------- /tools/apout/LIMITATIONS: -------------------------------------------------------------------------------- 1 | Bugs in Binaries 2 | ---------------- 3 | 4 | One of the V5 C compiler passes requires -DZERO_MEMORY: it must not 5 | initialise a variable properly. V5 and V6 ar(1) do not close a file 6 | descriptor after writing has finished. If Apout is compiled with 7 | stream buffering, when this file is copied it is truncated. Either 8 | turn off Apout stream buffering (a performance penalty), or patch 9 | ar.s to behave itself. The patch is: 10 | 11 | *** ar.s.orig Thu Jan 14 09:40:46 1999 12 | --- ar.s Thu Jan 14 09:41:12 1999 13 | *************** 14 | *** 444,449 **** 15 | --- 444,451 ---- 16 | bes crterr 17 | mov r0,afo 18 | sys write; magic; 2 19 | + mov tfo,r0 / need to close before reading 20 | + sys close 21 | 1: 22 | mov tfi,r0 23 | sys read; buf; 512. 24 | 25 | 26 | Floating-point Limitations 27 | -------------------------- 28 | 29 | PDP-11 doubles are treated as floats. FEA/FEC don't exist. 30 | FP errors are not dealt with. Mistrust FP results for now. 31 | 32 | Limitations for 7th Edition Emulation in Apout 2.3 33 | -------------------------------------------------- 34 | 35 | Note that V5 and V6 binaries are considered V7 binaries. Overlay 36 | binaries (type 0405) are not recognised. 37 | 38 | The errno values on the native system are not translated back to 39 | the V7 errno values. There is normally a 1-to-1 mapping, but V7 40 | only had 32 errno values; native errno values above this are going 41 | to confuse the emulated application. 42 | 43 | The following system calls are not implemented, and return an 44 | EPERM error to the application: phys(2), prof(2), ptrace(2), 45 | acct(2), mount(2), umount(2), times(2). The following system 46 | calls are ignored: lock(2), stime(2). 47 | 48 | The following systems calls are only partially implemented: 49 | 50 | signal(2): Only SIG_DFL and SIG_IGN are implemented. 51 | stty(2), gtty(2): These should work, but V7 stty(1) doesn't work. 52 | ioctl(2): Only enough to emulate stty(2) amd gtty(2). 53 | 54 | The emulated applications use the native filesystem. Native filenames bigger 55 | than 14 characters are truncated to 14 characters before being passed to 56 | the application. In a similar way, inode numbers bigger than 65,536 are 57 | truncated modulo 65,536 before being passed to the application. 58 | 59 | Limitations for 5th & 6th Edition Emulation in Apout 2.3 60 | -------------------------------------------------------- 61 | 62 | There seems to be a bug in V5/V6 ctime() which stops dates after 63 | November 1999 being displayed correctly. Apout works around this 64 | problem by modifying dates returned from system calls to be in 65 | the year 1998 if they are 1999 or later. 66 | 67 | Limitations for 2.9BSD Emulation in Apout 2.3 68 | --------------------------------------------- 69 | 70 | At present, 2.9BSD binaries are treated as V7 binaries, so the limitations 71 | above apply. This also means that overlays are not understood, and also the 72 | 2.9-specific system calls have not yet been implemented. 73 | 74 | Limitations for 2.11BSD Emulation in Apout 2.3 75 | ---------------------------------------------- 76 | 77 | Flags passed as arguments to the 2.11 syscalls are promoted to 32-bit 78 | ints and passed to the native syscall. The errno values on the native 79 | system are not translated back to the 2.11 errno values. To find out 80 | what syscalls have been implemented, grep for the word DONE in bsdtrap.c. 81 | 82 | The following 2.11 syscalls are not handled: 83 | 84 | S_GETSOCKOPT, S_SETSOCKOPT, S_SELECT, 85 | S_RECVMSG, S_SENDMSG, S_SENDTO, 86 | S_SIGBLOCK, S_SIGPAUSE, S_SIGRETURN, 87 | S_SIGSETMASK, S_SIGSTACK, S_SIGVEC 88 | 89 | Limitations for 1st Edition Emulation in Apout 2.3 90 | -------------------------------------------------- 91 | 92 | This is still in the experimental stages, with some problems with time 93 | values. The KE11A emulation is also incomplete. However, the following 94 | 0405-magic binaries from Dennis Ritchie's s2.tar archive are known to work: 95 | 96 | cat, cp, date, echo, ls, mkdir, sh, wc 97 | 98 | Most of the others seem to work as well, but I haven't tested them completely. 99 | The list of 0405-magic files on the s2 archive is: 100 | 101 | bin/: bin/mv 102 | bin/ar bin/od 103 | bin/bas bin/pr 104 | bin/cat bin/rew 105 | bin/chball bin/rmdir 106 | bin/check bin/roff 107 | bin/chown bin/sh 108 | bin/cmp bin/skip 109 | bin/cp bin/sort 110 | bin/date bin/stat 111 | bin/db bin/stty 112 | bin/dc bin/su 113 | bin/df bin/sum 114 | bin/du bin/tap 115 | bin/echo bin/tm 116 | bin/ed bin/tty 117 | bin/exit bin/wc 118 | bin/form bin/who 119 | bin/goto bin/write 120 | bin/if etc/getty 121 | bin/login etc/glob 122 | bin/ls etc/init 123 | bin/mail etc/msh 124 | bin/mesg /tc/suftab 125 | bin/mkdir 126 | 127 | The following 1st Edition system calls are not yet emulated: GTTY, STTY, TELL. 128 | 129 | Limitations for 2nd Edition Emulation in Apout 2.3 130 | -------------------------------------------------- 131 | 132 | The few 2nd Edition binaries with 0407-magic on the s2 archive can now 133 | be run with Apout. Essentially, they receive the same environment as 134 | the 1st Edition binaries, with a few small syscall differences. Note 135 | that, at present, I don't have a copy of the V2 manuals, so I can 136 | guarantee that 2nd Edition emulation still needs work. 137 | 138 | However, the emulation is good enough to allow the C compiler on the s2 139 | archive to compile the last1120c C compiler on Dennis Ritchie's homepage. 140 | 141 | The list of 0407-magic files in the s2 archive is below. I have starred 142 | those binaries that I know work with Apout. 143 | 144 | * bin/as usr/fort/fc1 145 | * bin/cc usr/fort/fc2 146 | bin/ds usr/fort/fc3 147 | bin/fc usr/fort/fc4 148 | bin/find usr/jack/a.out 149 | * bin/ld usr/jack/x.o 150 | bin/maki * usr/lib/c0 151 | bin/nm * usr/lib/c1 152 | * bin/size usr/lib/crt0.o 153 | bin/strip usr/lib/fr0.o 154 | bin/un usr/sys/a.out 155 | * etc/as2 156 | -------------------------------------------------------------------------------- /tools/apout/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Apout PDP-11 application emulator 2 | # 3 | # $Revision: 1.31 $ 4 | # $Date: 2008/05/19 13:42:39 $ 5 | # 6 | # You will need gcc if you choose the optimised compile below 7 | CC=gcc 8 | 9 | # Set the CFLAGS, LDFLAGS for speed or debugging. If you don't want 2.11BSD 10 | # emulation, then remove the -DEMU211 flag. 11 | # Set up the LIBS if required for your system 12 | # 13 | # These flags for doing debugging 14 | CFLAGS= -Wall -g -DEMU211 -DEMUV1 -DNATIVES -DRUN_V1_RAW \ 15 | -DDEBUG -DZERO_MEMORY -DWRITEBASE 16 | LDFLAGS= -g 17 | 18 | # These flags for speed 19 | #CFLAGS= -DEMU211 -DNATIVES -DINLINE=inline -O2 -Winline -Wall \ 20 | # -finline-functions -fomit-frame-pointer 21 | #LDFLAGS= 22 | 23 | # Any extra libraries required 24 | LIBS= -lm 25 | 26 | # Install destinations 27 | MANDIR=/usr/local/man/man1 28 | BINDIR=/usr/local/bin 29 | 30 | VERSION= apout2.3beta1 31 | SRCS= cpu.c aout.c aout.h branch.c double.c ea.c itab.c main.c ke11a.c \ 32 | single.c fp.c v7trap.c bsdtrap.c defines.h v7trap.h debug.c \ 33 | bsdtrap.h bsd_ioctl.c bsd_signal.c magic.c v1trap.c v1trap.h \ 34 | apout.1 apout.0 README COPYRIGHT CHANGES LIMITATIONS TODO Makefile 35 | OBJS= aout.o branch.o bsd_ioctl.o bsd_signal.o bsdtrap.o cpu.o debug.o \ 36 | double.o ea.o fp.o itab.o ke11a.o magic.o main.o single.o v1trap.o \ 37 | v7trap.o 38 | 39 | apout: $(OBJS) 40 | cc $(LDFLAGS) $(OBJS) -o apout $(LIBS) 41 | 42 | install: apout 43 | cp apout $(BINDIR) 44 | chmod 755 $(BINDIR)/apout 45 | cp apout.1 $(MANDIR) 46 | chmod 644 $(MANDIR)/apout.1 47 | 48 | clean: 49 | rm -rf apout *core $(OBJS) *.dbg $(VERSION) $(VERSION).tar.gz apout.0 50 | 51 | apout.0: apout.1 52 | nroff -man apout.1 > apout.0 53 | 54 | disttar: clean apout.0 55 | - mkdir $(VERSION) 56 | cp $(SRCS) $(VERSION) 57 | chmod -R go+rX $(VERSION) 58 | chmod -R u+w $(VERSION) 59 | chown -R wkt $(VERSION) 60 | tar vzcf $(VERSION).tar.gz $(VERSION) 61 | 62 | # Dependencies for object files 63 | aout.o: aout.c defines.h aout.h Makefile 64 | branch.o: branch.c defines.h Makefile 65 | bsd_ioctl.o: bsd_ioctl.c defines.h Makefile 66 | bsd_signal.o: bsd_signal.c defines.h bsdtrap.h Makefile 67 | bsdtrap.o: bsdtrap.c bsdtrap.h defines.h Makefile 68 | cpu.o: cpu.c defines.h Makefile 69 | debug.o: debug.c defines.h Makefile 70 | double.o: double.c defines.h Makefile 71 | ea.o: ea.c defines.h Makefile 72 | fp.o: fp.c defines.h Makefile 73 | itab.o: itab.c defines.h Makefile 74 | ke11a.o: ke11a.c defines.h Makefile 75 | magic.o: magic.c defines.h Makefile 76 | main.o: main.c defines.h Makefile 77 | single.o: single.c defines.h Makefile 78 | v1trap.o: v1trap.c v1trap.h defines.h Makefile 79 | v7trap.o: v7trap.c v7trap.h defines.h Makefile 80 | -------------------------------------------------------------------------------- /tools/apout/README: -------------------------------------------------------------------------------- 1 | Apout -- Simulate PDP-11 Unix a.out binaries 2 | Version 2.3 Beta 1 3 | 4 | Warren Toomey wkt@tuhs.org 5 | June 2002 6 | 7 | Introduction 8 | ------------ 9 | This program is a user-level simulator for UNIX a.out binaries. Binaries 10 | for V1, V2, V5, V6, V7, 2.9BSD and 2.11BSD can be run with this simulator. 11 | The user-mode PDP-11 instructions are simulated, and TRAP instructions 12 | are emulated by calling equivalent native-mode system calls. 13 | 14 | The advantages of an a.out simulator over a full-blown PDP-11 simulator are: 15 | 16 | + system calls can be done natively, thus speeding up execution 17 | + the simulator is less of a CPU-hog than a full-blown PDP-11 simulator 18 | + you don't need a simulated operating system or a simulated file system 19 | 20 | Apout can be obtained via anonymous ftp at minnie.tuhs.org in the 21 | directory pub/PDP-11/Sims/Apout. The directory pub/PDP-11/Sims/Apout/UnixBins 22 | contains tar archives of a.out binaries from several versions of UNIX. 23 | 24 | Status 25 | ------ 26 | The program is now at release 2.3 Alpha2. Most of the binaries from V5, V6 27 | and V7 run fine. All of the V5/V6/V7 system calls are caught, but some are 28 | ignored and some generate EPERM errors. The V1, V2, 2.9BSD and 2.11BSD 29 | environments are still under construction: see the file LIMITATIONS for 30 | details. Finally, the simulator won't run on a big-endian machine. 31 | 32 | INSTALLATION 33 | ------------ 34 | I have only tested this program on FreeBSD 2.x and 3.x, and on RedHat 35 | Linux 2.2. It should compile on a 32-bit little-endian machine with 36 | some form of Unix; you may need to change some header file includes etc. 37 | See `defines.h' for the details. In particular, if your system doesn't have 38 | types for: 39 | 40 | int8_t, int16_t, int32_t, u_int8_t, u_int16_t, u_int32_t 41 | 42 | or if your compiler doesn't have char=1 byte, short= 2 bytes, int=4 bytes, 43 | then alter the relevant typedefs in `defines.h'. 44 | 45 | The Makefile has two sets of CFLAGS/LDFLAGS: one set is for debugging, and 46 | the other set is for speed. If you define the C pre-processor macro `DEBUG', 47 | then this includes debugging code into the program. I use it quite heavily 48 | when trying to fix niggling problems. 49 | 50 | If you remove the -DEMU211 macro definition from the Makefile, the emulation 51 | of 2.11BSD will not be compiled in to the simulator. Similarly, if you remove 52 | the -DEMUV1 macro definition from the Makefile, the emulation of 1st and 2nd 53 | Edition UNIX will not be compiled in to the simulator. By default, EMUV1 54 | is disabled. 55 | 56 | 57 | Once you have configured apout, now type `make'. Hopefully, things will 58 | compile ok. You will eventually get the `apout' program. 59 | 60 | Now go find an old PDP-11 UNIX binary, e.g 7th Edition cal, and say: 61 | 62 | % setenv APOUT_ROOT / # for now 63 | % apout cal 1970 64 | 65 | If the simulator is working, the calendar for 1970 will be printed out. 66 | The V7 shell works, and from there, you can run other programs. 67 | 68 | % apout sh 69 | # ls -l 70 | output of ls 71 | # 72 | 73 | Finally, install apout in /usr/local/bin, and the manual page apout.1 in 74 | the appropriate place. If you can't use the man page because of incompatible 75 | macros, then apout.0 is a text file which has the pre-formatted man page. 76 | 77 | DEBUG OPTIONS 78 | ------------- 79 | When debugging is compiled in, the program has several options: 80 | 81 | -inst turns on instruction tracing, which is _very_ verbose 82 | -trap turns on TRAP tracing; not all syscalls have debugging code 83 | -jsr prints out the details of each jsr and rts 84 | -fp prints out some details of floating-point instructions 85 | 86 | All debugging output goes out to the file `apout.dbg'. These debugging options 87 | are mainly used for testing apout, and so the output in apout.dbg may not be 88 | very useful to you. 89 | 90 | ENVIRONMENT VARIABLES 91 | --------------------- 92 | Apout has the concept of a simulated root filesystem for the simulated PDP-11 93 | binaries. When working with filenames, if the filenames are relative, they 94 | stay relative. If the filenames are absolute (i.e /usr/...), then apout 95 | prepends the value of the environment variable APOUT_ROOT to the filename. 96 | This allows you to say: 97 | 98 | # setenv APOUT_ROOT /usr/misc/v7root 99 | 100 | before running apout to set the `root' of the filesystem wherever you want. 101 | You MUST set APOUT_ROOT before running apout. 102 | 103 | TODO 104 | ---- 105 | There's lots to do. Here's what I'd like to do, in a somewhat ordered list. 106 | 107 | + Verify that the instruction simulation and high priority 108 | the syscalls all work correctly 109 | + Complete some of the syscalls that are med priority 110 | not fully simulated 111 | + Speed the simulator up med priority 112 | 113 | SOURCE ORGANISATION 114 | ------------------- 115 | 116 | main.c parses any arguments, loads the binary and calls run() 117 | cpu.c holds the main instruction decode/execute loop 118 | itab.c holds function lookup tables for all instructions 119 | ea.c holds functions to decode the PDP-11 addressing modes 120 | debug.c holds strings for all emulated opcodes 121 | 122 | single.c single.c, double.c and branch.c hold most of the functions 123 | double.c which perform the PDP-11 user-mode instructions. The code 124 | branch.c in these files comes from a PDP-11 simulator by Eric Edwards 125 | fp.c partially emulates FP instructions 126 | 127 | aout.c determines what type of a.out the binary is, and what UNIX 128 | magic.c environment to set up. If V5/V6/V7, trap instructions fall 129 | v7trap.c into v7trap.c which runs them using native system calls 130 | v7trap.h 131 | 132 | v1trap.c if the binary is a 1st or 2nd Edition binary, traps fall 133 | v1trap.h into v1trap.c, which likewise does the syscalls natively 134 | ke11a.c emulates the KE11A extended arithmetic unit, used by V1/V2 135 | 136 | bsdtrap.c if the binary is a 2.11BSD binary, trap instructions fall 137 | bsdtrap.h into bsdtrap.c, which likewise does the syscalls natively 138 | bsd_ioctl.c 2.11BSD ioctl calls are handled with this file 139 | 140 | defines.h holds function & typedef prototypes and useful cpp macros 141 | -------------------------------------------------------------------------------- /tools/apout/TODO: -------------------------------------------------------------------------------- 1 | Things to do in the Apout Emulator 2 | ---------------------------------- 3 | 4 | Ensure stream buffering works! 5 | 6 | Do some decent testing and code reading to make me happier. 7 | 8 | Speed Apout up 9 | 10 | The biggest bottlenecks are the effective address calculations 11 | in ea.c. After compiling 2.11BSD /sys/GENERIC kernel with a 12 | gprof'd apout, we get: 13 | 14 | % cumulative self self total 15 | time seconds seconds calls ms/call ms/call name 16 | 64.9 3.64 3.64 .mcount (123) 17 | 6.1 3.99 0.34 1609635 0.00 0.00 load_src [5] 18 | 5.6 4.30 0.31 1665976 0.00 0.00 mov [4] 19 | 5.3 4.60 0.30 2 148.44 959.47 run [3] 20 | 3.4 4.79 0.19 1238127 0.00 0.00 load_dst [7] 21 | 2.2 4.91 0.12 602275 0.00 0.00 store_dst [10] 22 | 1.3 4.98 0.08 374121 0.00 0.00 loadb_src [12] 23 | 1.3 5.05 0.07 672481 0.00 0.00 store_dst_2 [13] 24 | 1.2 5.12 0.07 365911 0.00 0.00 cmp [6] 25 | 1.1 5.18 0.06 323386 0.00 0.00 movb [8] 26 | 1.1 5.24 0.06 515335 0.00 0.00 bne [15] 27 | 28 | Everything else is below 1%. It doesn't look like there is 29 | much room for improvement, maybe 10% worth? 30 | 31 | We could go to having 65,536 separate functions, one for 32 | each possible instruction. That would mean a large reorganisation 33 | of the source, and would result in a significantly larger 34 | binary for apout. 35 | 36 | I've broken open some of the mov() functions which has improved 37 | things a few percent. I did expand itab[] to 64K entries, but 38 | the improvement was negligible. However, I should come back & 39 | revisit this sometime. 40 | 41 | Would it be worth adding STREAM_BUFFERING into bsdtrap.c? Possibly. 42 | After a GENERIC kernel compile, I found that reads averaged 580 43 | chars/read, writes averaged 115 chars/write. However, after getting 44 | buffering to work in bsdtrap.c, I found that it actually slowed down 45 | the GENERIC kernel compile, so I've left the code in but disabled it. 46 | 47 | Finish off 2.11BSD emulation 48 | 49 | Finish off all the missing syscalls. This means I will have to 50 | learn how the new signal stuff actually works. Emulating signals 51 | is going to be really interesting, I can see! 52 | 53 | Enumerate and write all of the ioctls: yucko. That means all of 54 | the terminal stuff, blah! 55 | 56 | Fix up the floating-point 57 | 58 | If the UNIX binaries never use the FP error handling, then don't 59 | bother to implement it. We should, however, implement doubles. 60 | We should spend some time to ensure that the FP operations are 61 | accurate, both in terms of FP accuracy, and in giving results 62 | as if they were on a real PDP-11. 63 | 64 | Make it work on big-endian machines 65 | 66 | This would cause a lot of heartache in the code. It's not that 67 | pretty now, but can you imagine the #ifdefs once big-endian 68 | support is added? I guess some well-written macros could help. 69 | 70 | Tidy up the code 71 | 72 | In particular, aout.c is a mess. Should be more modular. 73 | -------------------------------------------------------------------------------- /tools/apout/aout.h: -------------------------------------------------------------------------------- 1 | /* aout.h - parse and load the contents of a UNIX a.out file, for 2 | * several flavours of PDP-11 UNIX 3 | * 4 | * $Revision: 1.5 $ 5 | * $Date: 2008/05/19 13:42:39 $ 6 | */ 7 | #include 8 | #define EIGHT_K 8192 9 | 10 | /* UNIX magic numbers for the a.out header */ 11 | #define V1_NORMAL 0405 /* normal: 1st Edition, six words long */ 12 | #define ANY_NORMAL 0407 /* normal: V5,V6,V7,2.11BSD */ 13 | #define ANY_ROTEXT 0410 /* read-only text: V5,V6,V7,2.11BSD */ 14 | #define ANY_SPLITID 0411 /* seperated I&D: V5,V6,V7,2.11BSD */ 15 | #define BSD_OVERLAY 0430 /* 2.11BSD overlay, non-separate */ 16 | #define BSD_ROVERLAY 0431 /* 2.11BSD overlay, separate */ 17 | #define ANY_SCRIPT 020443 /* Shell script, i.e #! */ 18 | #define A68_MAGIC 0 /* Algol68 binaries have these magic nums */ 19 | #define A68_DATA 0107116 /* Algol68 binaries have these magic nums */ 20 | #define V1_RAW 0104421 /* V1 'raw' binary: rm, ln, chmod from s2 21 | archive. */ 22 | 23 | #define UNKNOWN_AOUT 034567 /* An unknown a.out header */ 24 | 25 | /* a.out header for nearly all UNIX flavours */ 26 | struct exec { 27 | u_int16_t a_magic; /* magic number */ 28 | u_int16_t a_text; /* size of text segment */ 29 | u_int16_t a_data; /* size of initialised data */ 30 | u_int16_t a_bss; /* size of initialised bss */ 31 | u_int16_t a_syms; /* size of symbol table */ 32 | u_int16_t a_entry; /* entry point */ 33 | u_int16_t a_unused; /* unused */ 34 | u_int16_t a_flag; /* relocation info stripped */ 35 | /* 16 bytes up to here */ 36 | 37 | /* 2.11BSD overlay files have the following */ 38 | #define NOVL 15 39 | int16_t max_ovl; /* maximum overlay size */ 40 | u_int16_t ov_siz[NOVL]; /* size of the i'th overlay */ 41 | /* Note that if the file isn't a 2.11BSD */ 42 | /* overlay, we have to rewind to undo */ 43 | /* the read of this section */ 44 | }; 45 | 46 | /* Because V5, V6, V7 and 2.11BSD share several magic numbers 47 | * in their a.out headers, we must distinguish them so as to 48 | * set up the correct emulated environment. This is done by 49 | * observing the differences in their crt0.s code: they all 50 | * differ at position 021 51 | */ 52 | #define a_magic2 ov_siz[0] 53 | #define V2_M2 0177304 /* Doesn't apply to all, tho */ 54 | #define V6_M2 0010600 55 | #define V7_M2 0016600 56 | #define BSD_M2 0162706 57 | -------------------------------------------------------------------------------- /tools/apout/apout.1: -------------------------------------------------------------------------------- 1 | .\" Copyright Warren Toomey 2 | .\" 3 | .\" $Revision: 1.10 $ 4 | .\" $Date: 2008/05/15 03:20:52 $ 5 | .\" 6 | .Dd December, 2000 7 | .Dt APOUT 1 8 | .Os 9 | .Sh NAME 10 | .Nm apout 11 | .Nd run PDP-11 UNIX a.out binaries 12 | .Sh SYNOPSIS 13 | .Nm apout 14 | .Op Fl inst 15 | .Op Fl trap 16 | .Op Fl jsr 17 | .Op Fl fp 18 | .Ar file 19 | .Op Ar arguments ... 20 | .Sh DESCRIPTION 21 | .Nm apout 22 | runs the 23 | .Ar file 24 | which contains a PDP-11 UNIX a.out binary from one of the following 25 | versions of UNIX: 1st Edition, 2nd Edition, 5th Edition, 6th Edition, 26 | 7th Edition, 2.9BSD or 2.11BSD. Any arguments after the named 27 | .Ar file 28 | are passed as arguments to the a.out binary. 29 | .Pp 30 | User-mode PDP-11 instructions are interpreted and executed by 31 | .Nm apout, 32 | and system calls made by the interpreted a.out binary are performed 33 | by making real systems calls to the underlying native operating system. 34 | In this way, the interpreted a.out binary can interact with the real 35 | files and processes on the system. 36 | .Pp 37 | If 38 | .Nm apout 39 | has been compiled with debugging enabled, the following options are available: 40 | .Bl -tag -width trap 41 | .It Fl inst 42 | Output a line for each instruction emulated which gives: 43 | the PC in octal, the instruction in octal, the instruction's name, 44 | r0 to r6 in octal, and the values of the N, Z, V and C flags. 45 | .It Fl trap 46 | Output a line for each system call, which gives the name of the system 47 | call, possibly a list of arguments, and the value returned by the system 48 | call. 49 | .It Fl jsr 50 | Output a line for each 51 | .Ar jsr 52 | or 53 | .Ar rts 54 | giving the value of the new PC. For 2.11BSD overlay binaries, also output 55 | a line describing each overlay change. 56 | .It Fl fp 57 | For many of the emulated floating-point instructions, output a line 58 | describing the operation. 59 | .El 60 | .Pp 61 | If 62 | .Nm apout 63 | was not compiled with debugging enabled, none of these options exist. 64 | Any debugging output is directed to the file 65 | .Ar apout.dbg 66 | in the directory where 67 | .Nm apout 68 | was started. The debugging output is primarily designed to aid the 69 | developers of 70 | .Nm apout, 71 | and so it isn't exhaustive for all instructions, traps or floating-point 72 | operations. 73 | .Sh ENVIRONMENT VARIABLES 74 | .Nm apout 75 | requires one environment variable to be set: 76 | .Ev APOUT_ROOT. 77 | This variable names the `root' of the emulated filesystem. 78 | .Pp 79 | When 80 | .Nm apout 81 | works with filenames, if the filenames are relative, then they 82 | stay relative i.e all files on the system can be named, as long as they are 83 | given relative names. However, if the filenames are absolute, i.e they 84 | start with a slash, then 85 | .Nm apout 86 | prepends the value of the environment variable 87 | .Ev APOUT_ROOT 88 | to the filename. Therefore, if you have the 7th Edition files located in 89 | .Ar /usr/misc/v7root 90 | and you do: 91 | .Bd -literal 92 | % setenv APOUT_ROOT /usr/misc/v7root 93 | % apout $APOUT_ROOT/bin/sh 94 | $ 95 | .Ed 96 | .Pp 97 | then you will be greeted with the 7th Edition Bourne shell prompt as shown: 98 | you will still be in the directory where you started 99 | .Nm apout, 100 | but if you cd to /, then you will be taken to 101 | .Ar /usr/misc/v7root 102 | .Pp 103 | Note that you must set 104 | .Ev APOUT_ROOT 105 | before you can run 106 | .Nm apout. 107 | .Pp 108 | There is one other optional environment variable: 109 | .Ev APOUT_UNIX_VERSION. 110 | This is mainly required for UNIX binaries that use the 0407 header, 111 | which was used across several versions of UNIX, each with a different set 112 | of system calls. If APOUT_UNIX_VERSION is set, 113 | .Nm apout 114 | will use the given version when it cannot determine which version of UNIX a 115 | binary belongs to. The available values are "V1", "V2", "V3", "V4", "V5", "V6", 116 | "V7", "2.9BSD" and "2.11BSD". 117 | .Pp 118 | .Sh EMULATED ENVIRONMENT VARIABLES 119 | Initially, PDP-11 binaries run via 120 | .Nm apout 121 | receive the following set of emulated environment variables: 122 | .Bd -literal 123 | PATH /bin:/usr/bin:/usr/sbin:/usr/ucb:/usr/games:/usr/local/bin:. 124 | HOME / 125 | TERM vt100 126 | .Ed 127 | .Pp 128 | Emulated programs can, of course, change this emulated environment; 129 | they can also fork and exec other PDP-11 binaries, which will inherit the 130 | modified emulated environment. 131 | .Sh INTERACTION WITH NATIVE PROGRAMS 132 | Binaries that are interpreted by 133 | .Nm apout 134 | can interact with native programs in several ways: through files in the 135 | filesystem, and through pipes. For example, you can do the following: 136 | .Bd -literal 137 | % ls -lR | apout $APOUT_ROOT/bin/wc | lpr 138 | % apout $APOUT_ROOT/bin/sort < file | uniq > newfile 139 | .Ed 140 | .Pp 141 | where 142 | .Ar ls, 143 | .Ar lpr 144 | and 145 | .Ar uniq 146 | are native programs. 147 | .Pp 148 | If 149 | .Nm apout 150 | is compiled with the NATIVES preprocessor directive enabled, then native system 151 | binaries can be executed as well as PDP-11 binaries. For example: 152 | .Bd -literal 153 | % cd $APOUT_ROOT 154 | % ln -s `which vi` bin/vi Add vi into the filespace 155 | % apout bin/sh 156 | $ ls -l Run the PDP-11 ls 157 | .... 158 | $ vi kim.c Run the native vi 159 | $ cc -o kim kim.c Compile with the PDP-11 compiler 160 | .Ed 161 | .Pp 162 | Note that native executable receive the same environment variables inherited 163 | by the 164 | .Nm apout 165 | process, and not the emulated environment that 166 | .Nm apout 167 | passes to emulated executables. 168 | .Sh ERROR MESSAGES 169 | So as to distinguish from error messages generated by the interpreted PDP-11 170 | binaries, 171 | .Nm apout 172 | prepends the word `Apout' to the beginning of its error messages. Below is 173 | the list of error messages that 174 | .Nm apout 175 | can generate: 176 | .Bd -ragged 177 | Apout - V1 sectosixty too big 178 | Apout - can't malloc overlay! 179 | Apout - can't switch to empty overlay %d 180 | Apout - could not read 1st line of script 181 | Apout - couldn't load %s 182 | Apout - open_dir couldn't open %s 183 | Apout - out of argv space in script 184 | Apout - pid %d bad FP register used at PC 0%o 185 | Apout - pid %d bpt instruction at PC 0%o 186 | Apout - pid %d bus error at PC 0%06o 187 | Apout - pid %d emt instruction at PC 0%o 188 | Apout - pid %d halt instruction at PC 0%o 189 | Apout - pid %d illegal instruction %o at PC 0%o 190 | Apout - pid %d iot instruction at PC 0%o 191 | Apout - pid %d mark instruction at PC 0%o 192 | Apout - pid %d mfpd instruction at PC 0%o 193 | Apout - pid %d mtpd instruction at PC 0%o 194 | Apout - pid %d segmentation fault at PC 0%06o 195 | Apout - pid %d trap instruction at PC 0%o 196 | Apout - pid %d unimplemented instruction at PC 0%o 197 | Apout - pid %d unknown KE11 register 0%o 198 | Apout - pid %d waiti instruction at PC 0%o 199 | Apout - the %s syscall is not yet implemented 200 | Apout - the 2.11BSD %s syscall is not yet implemented 201 | Apout - unknown a.out format 0%o 202 | Apout - unknown magic in header: 0x%x 203 | Apout - unknown syscall %d at PC 0%o 204 | Apout cannot set the environment for the a.out %s 205 | Apout not compiled to support 1st Edition binaries 206 | Apout not compiled to support 2nd Edition binaries 207 | Apout not compiled to support 2.11BSD binaries 208 | .Ed 209 | .Sh CAVEATS 210 | As far as is known, the emulation of user-mode integer instructions is correct. 211 | The emulation of floating-point instructions is seriously deficient: 212 | only 32-bit floats are emulated: the extra 32-bits of precision in PDP-11 213 | doubles goes unused. None of the FP errors are emulated. 214 | .Pp 215 | The emulation of each of the emulated UNIX environments is mostly, 216 | but not fully, complete. Any UNIX system call environment is very 217 | sophisticated, and 218 | .Ar apout 219 | must translate from the emulated UNIX environment to the native one, and 220 | back. For an authorative description of what is missing from, or deficient 221 | in, each of the emulated UNIX environments, see the source files 222 | .Ar v1trap.c, 223 | .Ar v7trap.c 224 | and 225 | .Ar bsdtrap.c 226 | in the source directory for 227 | .Nm apout. 228 | You should also consult the file 229 | .Ar LIMITATIONS 230 | in the source directory for 231 | .Nm apout. 232 | .Sh SEE ALSO 233 | The latest source for 234 | .Nm apout 235 | can be obtained via anonymous ftp at minnie.tuhs.org in the directory 236 | pub/PDP-11/Sims/Apout. The directory pub/PDP-11/Sims/Apout/UnixBins 237 | contains tar archives of a.out binaries from several versions of UNIX. 238 | Information on PDP-11 UNIX can be found on the PUPS web page at 239 | http://minnie.tuhs.org/PUPS/ 240 | .Sh HISTORY 241 | The first version of 242 | .Nm apout 243 | appeared in 1995, and provided support for 6th and 7th Edition 244 | UNIX binaries. In 1998/1999, support was added for 2.11BSD binaries. 245 | In 1999/2000, support was added for 1st and 2nd Edition UNIX binaries. 246 | -------------------------------------------------------------------------------- /tools/apout/branch.c: -------------------------------------------------------------------------------- 1 | /* branch.c - Branch instructions, and instructions which are complex to do 2 | * 3 | * $Revision: 2.22 $ 4 | * $Date: 1999/12/27 04:38:29 $ 5 | */ 6 | #include "defines.h" 7 | 8 | /* We use the following macro for the branch instructions below */ 9 | 10 | #define do_branch() \ 11 | { offset = LOW8(ir); \ 12 | if (offset & SIGN_B) \ 13 | offset += 0177400; \ 14 | regs[PC] += (offset * 2); \ 15 | } \ 16 | 17 | static u_int16_t offset; 18 | 19 | void bne() { 20 | if (CC_Z==0) do_branch(); 21 | } 22 | void beq() { 23 | if (CC_Z==1) do_branch(); 24 | } 25 | void bpl() { 26 | if (CC_N==0) do_branch(); 27 | } 28 | void bmi() { 29 | if (CC_N==1) do_branch(); 30 | } 31 | void bhi() { 32 | if ((CC_Z==0) && (CC_C==0)) do_branch(); 33 | } 34 | void bvc() { 35 | if (CC_V==0) do_branch(); 36 | } 37 | void bvs() { 38 | if (CC_V==1) do_branch(); 39 | } 40 | void bcc() { 41 | if (CC_C==0) do_branch(); 42 | } 43 | void bcs() { 44 | if (CC_C==1) do_branch(); 45 | } 46 | 47 | /* br() - Branch Always. */ 48 | void br() { 49 | do_branch(); 50 | } 51 | 52 | 53 | /* blos() - Branch Lower or Same Instruction. */ 54 | void blos() { 55 | if ((CC_C!=0) || (CC_Z!=0)) do_branch(); 56 | } 57 | 58 | /* bge() - Branch Greater Than or Equal Instruction. */ 59 | void bge() { 60 | if ((CC_N ^ CC_V) == 0) do_branch(); 61 | } 62 | 63 | /* blt() - Branch Less Than Instruction. */ 64 | void blt() { 65 | if ((CC_N ^ CC_V) == 1) do_branch(); 66 | } 67 | 68 | /* ble() - Branch Less Than Or Equal Instruction. */ 69 | void ble() { 70 | if (((CC_N ^ CC_V) == 1) || ((CC_Z)!=0)) do_branch(); 71 | } 72 | 73 | /* bgt() - Branch Greater Than Instruction. */ 74 | void bgt() { 75 | if (((CC_N ^ CC_V) == 0) && ((CC_Z) == 0)) do_branch(); 76 | } 77 | 78 | /* jmp() - Jump Instruction. */ 79 | void jmp() { 80 | load_ea(); regs[PC]=dstword; 81 | } 82 | 83 | /* jsr() - Jump To Subroutine Instruction. */ 84 | void jsr() { 85 | load_ea(); 86 | srcword=regs[SRC_REG]; push(); 87 | regs[SRC_REG] = regs[PC]; 88 | regs[PC] = dstword; 89 | JsrDebug((dbg_file, "jsr to 0%o\n", dstword)); 90 | } 91 | 92 | /* rts() - Return From Subroutine Instruction. */ 93 | void rts() { 94 | regs[PC] = regs[DST_REG]; 95 | pop(); regs[DST_REG] = dstword; 96 | JsrDebug((dbg_file, "rts to 0%o\n", regs[PC])); 97 | } 98 | 99 | void scc() { 100 | if (ir & CC_NBIT) CC_N=1; 101 | if (ir & CC_ZBIT) CC_Z=1; 102 | if (ir & CC_VBIT) CC_V=1; 103 | if (ir & CC_CBIT) CC_C=1; 104 | } 105 | void ccc() { 106 | if (ir & CC_NBIT) CC_N=0; 107 | if (ir & CC_ZBIT) CC_Z=0; 108 | if (ir & CC_VBIT) CC_V=0; 109 | if (ir & CC_CBIT) CC_C=0; 110 | } 111 | 112 | /* sob() - Subtract One and Branch Instruction. */ 113 | void sob() { 114 | regs[SRC_REG] -= 1; 115 | if (regs[SRC_REG]) { 116 | regs[PC] -= (ir & 077) * 2; 117 | } 118 | } 119 | 120 | /* mfps() - Move from Processor Status Instruction. */ 121 | void mfps() { 122 | srcbyte=(u_int8_t)0; 123 | if (CC_N) srcbyte|= CC_NBIT; 124 | if (CC_Z) srcbyte|= CC_ZBIT; 125 | if (CC_V) srcbyte|= CC_VBIT; 126 | if (CC_C) srcbyte|= CC_CBIT; 127 | 128 | CHGB_CC_N(srcbyte); 129 | CHGB_CC_Z(srcbyte); 130 | CLR_CC_V(); 131 | 132 | if (DST_MODE) { 133 | storeb_dst(); 134 | } else { 135 | if (srcbyte & SIGN_B) { 136 | dstword = 0177400; 137 | } else { 138 | dstword = 0; 139 | } 140 | dstword += (u_int16_t)srcbyte; 141 | store_dst(); 142 | } 143 | } 144 | 145 | /* mtps() - Move to Processor Status Instruction. */ 146 | void mtps() { 147 | loadb_dst(); 148 | if (dstbyte & CC_NBIT) CC_N=1; 149 | if (dstbyte & CC_ZBIT) CC_Z=1; 150 | if (dstbyte & CC_VBIT) CC_V=1; 151 | if (dstbyte & CC_CBIT) CC_C=1; 152 | } 153 | 154 | /* mfpi() - Move From Previous Instruction Space Instruction. */ 155 | void mfpi() { 156 | loadp_dst(); push(); 157 | } 158 | 159 | 160 | /* mtpi() - To From Previous Instruction Space Instruction. */ 161 | void mtpi() { 162 | pop(); storep_dst(); 163 | } 164 | 165 | /* ash() - Arithmetic Shift Instruction. */ 166 | void ash() { 167 | u_int16_t temp; 168 | u_int16_t old; 169 | u_int16_t sign; 170 | u_int16_t count; 171 | 172 | temp = regs[SRC_REG]; 173 | load_dst(); 174 | old = temp; 175 | 176 | if ((dstword & 077) == 0) { /* no shift */ 177 | CHG_CC_N(temp); 178 | CHG_CC_Z(temp); 179 | CLR_CC_V(); 180 | return; 181 | } 182 | if (dstword & 040) { /* right shift */ 183 | count = 0100 - (dstword & 077); 184 | sign = temp & SIGN; 185 | while (count--) { 186 | if (temp & LSBIT) { 187 | SET_CC_C(); 188 | } else { 189 | CLR_CC_C(); 190 | } 191 | temp >>= 1; 192 | temp += sign; 193 | } 194 | } else { /* left shift */ 195 | count = dstword & 037; 196 | while (count--) { 197 | if (temp & SIGN) { 198 | SET_CC_C(); 199 | } else { 200 | CLR_CC_C(); 201 | } 202 | temp <<= 1; 203 | } 204 | } 205 | 206 | CHG_CC_N(temp); 207 | CHG_CC_Z(temp); 208 | 209 | if ((old & SIGN) == (temp & SIGN)) { 210 | CLR_CC_V(); 211 | } else { 212 | SET_CC_V(); 213 | } 214 | regs[SRC_REG] = temp; 215 | } 216 | 217 | 218 | /* mul() and divide() - Multiply and Divide Instructions. These work on 219 | * signed values, and we'll do the same. This may not be portable. */ 220 | 221 | union s_u_word { 222 | u_int16_t u_word; 223 | short s_word; 224 | }; 225 | 226 | union s_u_long { 227 | u_int32_t u_long; 228 | long s_long; 229 | }; 230 | 231 | void mul() { 232 | union s_u_word data1; 233 | union s_u_word data2; 234 | union s_u_long tmp; 235 | 236 | data1.u_word = regs[SRC_REG]; 237 | load_dst(); 238 | data2.u_word=dstword; 239 | 240 | tmp.s_long = ((long) data1.s_word) * ((long) data2.s_word); 241 | 242 | regs[SRC_REG] = (u_int16_t)(tmp.u_long >> 16); 243 | regs[(SRC_REG) | 1] = (u_int16_t)(tmp.u_long & 0177777); 244 | 245 | CLR_CC_ALL(); 246 | 247 | if (tmp.u_long == 0) 248 | SET_CC_Z(); 249 | else 250 | CLR_CC_Z(); 251 | 252 | if (tmp.u_long & 0x80000000) 253 | SET_CC_N(); 254 | else 255 | CLR_CC_N(); 256 | } 257 | 258 | void divide() { 259 | union s_u_long tmp; 260 | union s_u_long eql; 261 | union s_u_word data2; 262 | 263 | tmp.u_long = regs[SRC_REG]; 264 | tmp.u_long = tmp.u_long << 16; 265 | tmp.u_long += regs[(SRC_REG) | 1]; 266 | 267 | load_dst(); 268 | data2.u_word=dstword; 269 | 270 | if (data2.u_word == 0) { 271 | SET_CC_C(); 272 | SET_CC_V(); 273 | return; 274 | } else { 275 | CLR_CC_C(); 276 | } 277 | 278 | eql.s_long = tmp.s_long / data2.s_word; 279 | regs[SRC_REG] = (u_int16_t)eql.u_long & 0177777; 280 | 281 | if (eql.u_long == 0) 282 | SET_CC_Z(); 283 | else 284 | CLR_CC_Z(); 285 | 286 | if ((eql.s_long > 077777) || (eql.s_long < -0100000)) 287 | SET_CC_V(); 288 | else 289 | CLR_CC_V(); 290 | 291 | if (eql.s_long < 0) 292 | SET_CC_N(); 293 | else 294 | CLR_CC_N(); 295 | 296 | eql.s_long = tmp.s_long % data2.s_word; 297 | regs[(SRC_REG) | 1] = (u_int16_t)eql.u_long & 0177777; 298 | } 299 | 300 | /* ashc() - Arithmetic Shift Combined Instruction. */ 301 | void ashc() { 302 | u_int32_t temp; 303 | u_int32_t old; 304 | u_int32_t sign; 305 | u_int16_t count; 306 | 307 | temp = regs[SRC_REG]; 308 | temp <<= 16; 309 | temp += regs[(SRC_REG) | 1]; 310 | old = temp; 311 | load_dst(); 312 | 313 | if ((dstword & 077) == 0) { /* no shift */ 314 | 315 | CLR_CC_V(); 316 | 317 | if (temp & 0x80000000) { 318 | SET_CC_N(); 319 | } else { 320 | CLR_CC_N(); 321 | } 322 | 323 | if (temp) { 324 | CLR_CC_Z(); 325 | } else { 326 | SET_CC_Z(); 327 | } 328 | return; 329 | } 330 | if (dstword & 040) { /* right shift */ 331 | count = 0100 - (dstword & 077); 332 | sign = temp & 0x80000000; 333 | while (count--) { 334 | if (temp & LSBIT) { 335 | SET_CC_C(); 336 | } else { 337 | CLR_CC_C(); 338 | } 339 | temp >>= 1; 340 | temp += sign; 341 | } 342 | } else { /* left shift */ 343 | count = dstword & 037; 344 | while (count--) { 345 | if (temp & 0x80000000) { 346 | SET_CC_C(); 347 | } else { 348 | CLR_CC_C(); 349 | } 350 | temp <<= 1; 351 | } 352 | } 353 | 354 | if (temp & 0x80000000) 355 | SET_CC_N(); 356 | else 357 | CLR_CC_N(); 358 | 359 | if (temp) 360 | CLR_CC_Z(); 361 | else 362 | SET_CC_Z(); 363 | 364 | if ((old & 0x80000000) == (temp & 0x80000000)) { 365 | CLR_CC_V(); 366 | } else { 367 | SET_CC_V(); 368 | } 369 | 370 | regs[SRC_REG] = (u_int16_t)(temp >> 16); 371 | regs[(SRC_REG) | 1] = LOW16(temp); 372 | } 373 | 374 | /* xor() - Exclusive Or Instruction */ 375 | void xor() { 376 | tmpword = regs[SRC_REG]; 377 | 378 | load_dst(); 379 | 380 | tmpword = tmpword ^ dstword; 381 | 382 | CHG_CC_N(tmpword); 383 | CHG_CC_Z(tmpword); 384 | CLR_CC_V(); 385 | 386 | dstword=tmpword; store_dst_2(); 387 | } 388 | -------------------------------------------------------------------------------- /tools/apout/bsd_signal.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Much of this file comes from 2.11BSD's /usr/include/signal.h and is 3 | * Copyright (c) 1986 Regents of the University of California. 4 | * All rights reserved. The Berkeley software License Agreement 5 | * specifies the terms and conditions for redistribution. 6 | * 7 | * Code to deal with 2.11BSD signals 8 | */ 9 | #include "defines.h" 10 | #include 11 | #include "bsdtrap.h" 12 | 13 | 14 | #define NBSDSIG 32 15 | 16 | #define BSDSIGHUP 1 /* hangup */ 17 | #define BSDSIGINT 2 /* interrupt */ 18 | #define BSDSIGQUIT 3 /* quit */ 19 | #define BSDSIGILL 4 /* illegal instruct (not reset when caught) */ 20 | #define BSDSIGTRAP 5 /* trace trap (not reset when caught) */ 21 | #define BSDSIGIOT 6 /* IOT instruction */ 22 | #define BSDSIGEMT 7 /* EMT instruction */ 23 | #define BSDSIGFPE 8 /* floating point exception */ 24 | #define BSDSIGKILL 9 /* kill (cannot be caught or ignored) */ 25 | #define BSDSIGBUS 10 /* bus error */ 26 | #define BSDSIGSEGV 11 /* segmentation violation */ 27 | #define BSDSIGSYS 12 /* bad argument to system call */ 28 | #define BSDSIGPIPE 13 /* write on a pipe with no one to read it */ 29 | #define BSDSIGALRM 14 /* alarm clock */ 30 | #define BSDSIGTERM 15 /* software termination signal from kill */ 31 | #define BSDSIGURG 16 /* urgent condition on IO channel */ 32 | #define BSDSIGSTOP 17 /* sendable stop signal not from tty */ 33 | #define BSDSIGTSTP 18 /* stop signal from tty */ 34 | #define BSDSIGCONT 19 /* continue a stopped process */ 35 | #define BSDSIGCHLD 20 /* to parent on child stop or exit */ 36 | #define BSDSIGTTIN 21 /* to readers pgrp upon background tty read */ 37 | #define BSDSIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ 38 | #define BSDSIGIO 23 /* input/output possible signal */ 39 | #define BSDSIGXCPU 24 /* exceeded CPU time limit */ 40 | #define BSDSIGXFSZ 25 /* exceeded file size limit */ 41 | #define BSDSIGVTALRM 26 /* virtual time alarm */ 42 | #define BSDSIGPROF 27 /* profiling time alarm */ 43 | #define BSDSIGWINCH 28 /* window size changes */ 44 | #define BSDSIGUSR1 30 /* user defined signal 1 */ 45 | #define BSDSIGUSR2 31 /* user defined signal 2 */ 46 | #define bsdsigismember(set, signo) ((*(set) & (1L << ((signo) - 1))) != 0) 47 | 48 | #define BSDSIG_ERR -1 49 | #define BSDSIG_DFL 0 50 | #define BSDSIG_IGN 1 51 | 52 | /* 53 | * Signal vector "template" used in sigaction call. 54 | */ 55 | struct bsd_sigaction { 56 | int16_t sig_handler; /* signal handler */ 57 | u_int32_t sa_mask; /* signal mask to apply */ 58 | int16_t sa_flags; /* see signal options below */ 59 | }; 60 | 61 | #define BSD_ONSTACK 0x0001 /* take signal on signal stack */ 62 | #define BSD_RESTART 0x0002 /* restart system on signal return */ 63 | #define BSD_DISABLE 0x0004 /* disable taking signals on alternate stack */ 64 | #define BSD_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */ 65 | 66 | 67 | /* Translate 2.11BSD signal value to our value */ 68 | 69 | static int bsdsig[] = { 70 | 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGIOT, SIGEMT, 71 | SIGFPE, SIGKILL, SIGBUS, SIGSEGV, SIGSYS, SIGPIPE, SIGALRM, 72 | SIGTERM, SIGURG, SIGSTOP, SIGTSTP, SIGCONT, SIGCHLD, SIGTTIN, 73 | SIGTTOU, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, 74 | SIGUSR1, SIGUSR2 75 | }; 76 | 77 | /* We keep a set of struct sigactions 78 | * for each 2.11BSD signal 79 | */ 80 | struct bsd_sigaction Sigact[NBSDSIG]; 81 | 82 | 83 | /* Set all signals to their default value */ 84 | void set_bsdsig_dfl(void) 85 | { 86 | int i; 87 | 88 | for (i=0;i= NBSDSIG)) return(EINVAL); 102 | 103 | if (oa) { 104 | oact= (struct bsd_sigaction *)&dspace[oa]; 105 | memcpy(oact, &Sigact[sig], sizeof(struct bsd_sigaction)); 106 | } 107 | 108 | if (a) { 109 | act= (struct bsd_sigaction *)&dspace[a]; 110 | 111 | /* If required, map mask here */ 112 | /* Currently, the assumption is a 1-1 match */ 113 | sigemptyset(&(ouraction.sa_mask)); 114 | for (i=1; isa_mask), i) 116 | sigaddset(&(ouraction.sa_mask), i); 117 | } 118 | /* If required, map flags here */ 119 | ouraction.sa_flags= act->sa_flags; 120 | ouraction.sa_handler= sigcatcher; 121 | } 122 | 123 | i= sigaction(bsdsig[sig], &ouraction, NULL); 124 | if (i==-1) return(i); 125 | 126 | /* Else save the new sigaction */ 127 | act= (struct bsd_sigaction *)&dspace[a]; 128 | memcpy(&Sigact[sig], act, sizeof(struct bsd_sigaction)); 129 | return(i); 130 | } 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | /* For now, the rest commented out. One day I might 151 | * get around to implementing 2.11BSD signals properly 152 | */ 153 | 154 | #if 0 155 | int (*signal())(); 156 | 157 | typedef unsigned long sigset_t; 158 | 159 | 160 | /* 161 | * Flags for sigprocmask: 162 | */ 163 | #define BSDSIG_BLOCK 1 /* block specified signal set */ 164 | #define BSDSIG_UNBLOCK 2 /* unblock specified signal set */ 165 | #define BSDSIG_SETMASK 3 /* set specified signal set */ 166 | 167 | typedef int (*sig_t)(); /* type of signal function */ 168 | 169 | /* 170 | * Structure used in sigaltstack call. 171 | */ 172 | struct sigaltstack { 173 | char *ss_base; /* signal stack base */ 174 | int ss_size; /* signal stack length */ 175 | int ss_flags; /* SA_DISABLE and/or SA_ONSTACK */ 176 | }; 177 | #define MINBSDSIGSTKSZ 128 /* minimum allowable stack */ 178 | #define BSDSIGSTKSZ (MINBSDSIGSTKSZ + 384) /* recommended stack size */ 179 | 180 | /* 181 | * 4.3 compatibility: 182 | * Signal vector "template" used in sigvec call. 183 | */ 184 | struct sigvec { 185 | int (*sv_handler)(); /* signal handler */ 186 | long sv_mask; /* signal mask to apply */ 187 | int sv_flags; /* see signal options below */ 188 | }; 189 | #define SV_ONSTACK SA_ONSTACK /* take signal on signal stack */ 190 | #define SV_INTERRUPT SA_RESTART /* same bit, opposite sense */ 191 | #define sv_onstack sv_flags /* isn't compatibility wonderful! */ 192 | 193 | /* 194 | * 4.3 compatibility: 195 | * Structure used in sigstack call. 196 | */ 197 | struct sigstack { 198 | char *ss_sp; /* signal stack pointer */ 199 | int ss_onstack; /* current status */ 200 | }; 201 | 202 | /* 203 | * Information pushed on stack when a signal is delivered. 204 | * This is used by the kernel to restore state following 205 | * execution of the signal handler. It is also made available 206 | * to the handler to allow it to properly restore state if 207 | * a non-standard exit is performed. 208 | */ 209 | struct sigcontext { 210 | int sc_onstack; /* sigstack state to restore */ 211 | long sc_mask; /* signal mask to restore */ 212 | int sc_sp; /* sp to restore */ 213 | int sc_fp; /* fp to restore */ 214 | int sc_r1; /* r1 to restore */ 215 | int sc_r0; /* r0 to restore */ 216 | int sc_pc; /* pc to restore */ 217 | int sc_ps; /* psl to restore */ 218 | int sc_ovno /* overlay to restore */ 219 | }; 220 | 221 | /* 222 | * Macro for converting signal number to a mask suitable for 223 | * sigblock(). 224 | */ 225 | #define sigmask(m) (1L << ((m)-1)) 226 | #define sigaddset(set, signo) (*(set) |= 1L << ((signo) - 1), 0) 227 | #define sigdelset(set, signo) (*(set) &= ~(1L << ((signo) - 1)), 0) 228 | #define sigemptyset(set) (*(set) = (sigset_t)0, (int)0) 229 | #define sigfillset(set) (*(set) = ~(sigset_t)0, (int)0) 230 | #define sigismember(set, signo) ((*(set) & (1L << ((signo) - 1))) != 0) 231 | 232 | #endif /* 0 */ 233 | -------------------------------------------------------------------------------- /tools/apout/bsdtrap.h: -------------------------------------------------------------------------------- 1 | /* bsdtrap.h. Definitions for values and structures used in bsdtrap.c 2 | * 3 | * $Revision: 1.30 $ 4 | * $Date: 1999/03/01 19:14:16 $ 5 | */ 6 | 7 | /* In this file, we list the trap number for each system call, 8 | * and the structures associated with several of the systems 9 | * calls in 2.11BSD UNIX 10 | */ 11 | 12 | #define S_INDIR 0 13 | #define S_EXIT 1 14 | #define S_FORK 2 15 | #define S_READ 3 16 | #define S_WRITE 4 17 | #define S_OPEN 5 18 | #define S_CLOSE 6 19 | #define S_WAIT4 7 20 | #define S_CREAT 8 21 | #define S_LINK 9 22 | #define S_UNLINK 10 23 | #define S_EXECV 11 24 | #define S_CHDIR 12 25 | #define S_FCHDIR 13 26 | #define S_MKNOD 14 27 | #define S_CHMOD 15 28 | #define S_CHOWN 16 29 | #define S_CHFLAGS 17 30 | #define S_FCHFLAGS 18 31 | #define S_LSEEK 19 32 | #define S_GETPID 20 33 | #define S_MOUNT 21 34 | #define S_UMOUNT 22 35 | #define S_SYSCTL 23 36 | #define S_GETUID 24 37 | #define S_GETEUID 25 38 | #define S_PTRACE 26 39 | #define S_GETPPID 27 40 | #define S_STATFS 28 41 | #define S_FSTATFS 29 42 | #define S_GETFSSTAT 30 43 | #define S_SIGACTION 31 44 | #define S_SIGPROCMASK 32 45 | #define S_ACCESS 33 46 | #define S_SIGPENDING 34 47 | #define S_SIGALTSTACK 35 48 | #define S_SYNC 36 49 | #define S_KILL 37 50 | #define S_STAT 38 51 | #define S_GETLOGIN 39 52 | #define S_LSTAT 40 53 | #define S_DUP 41 54 | #define S_PIPE 42 55 | #define S_SETLOGIN 43 56 | #define S_PROFIL 44 57 | #define S_SETUID 45 58 | #define S_SETEUID 46 59 | #define S_GETGID 47 60 | #define S_GETEGID 48 61 | #define S_SETGID 49 62 | #define S_SETEGID 50 63 | #define S_ACCT 51 64 | #define S_OLDPHYS 52 65 | #define S_OLDLOCK 53 66 | #define S_IOCTL 54 67 | #define S_REBOOT 55 68 | #define S_SYMLINK 57 69 | #define S_READLINK 58 70 | #define S_EXECVE 59 71 | #define S_UMASK 60 72 | #define S_CHROOT 61 73 | #define S_FSTAT 62 74 | #define S_GETPAGESIZE 64 75 | #define S_VFORK 66 76 | #define S_SBRK 69 77 | #define S_VHANGUP 76 78 | #define S_GETGROUPS 79 79 | #define S_SETGROUPS 80 80 | #define S_GETPGRP 81 81 | #define S_SETPGRP 82 82 | #define S_SETITIMER 83 83 | #define S_WAIT 84 84 | #define S_GETITIMER 86 85 | #define S_GETHOSTNAME 87 86 | #define S_SETHOSTNAME 88 87 | #define S_GETDTABLESIZE 89 88 | #define S_DUP2 90 89 | #define S_UNUSED1 91 90 | #define S_FCNTL 92 91 | #define S_SELECT 93 92 | #define S_UNUSED2 94 93 | #define S_FSYNC 95 94 | #define S_SETPRIORITY 96 95 | #define S_SOCKET 97 96 | #define S_CONNECT 98 97 | #define S_ACCEPT 99 98 | #define S_GETPRIORITY 100 99 | #define S_SEND 101 100 | #define S_RECV 102 101 | #define S_SIGRETURN 103 102 | #define S_BIND 104 103 | #define S_SETSOCKOPT 105 104 | #define S_LISTEN 106 105 | #define S_SIGSUSPEND 107 106 | #define S_SIGVEC 108 107 | #define S_SIGBLOCK 109 108 | #define S_SIGSETMASK 110 109 | #define S_SIGPAUSE 111 110 | #define S_SIGSTACK 112 111 | #define S_RECVMSG 113 112 | #define S_SENDMSG 114 113 | #define S_GETTIMEOFDAY 116 114 | #define S_GETRUSAGE 117 115 | #define S_GETSOCKOPT 118 116 | #define S_READV 120 117 | #define S_WRITEV 121 118 | #define S_SETTIMEOFDAY 122 119 | #define S_FCHOWN 123 120 | #define S_FCHMOD 124 121 | #define S_RECVFROM 125 122 | #define S_SETREUID 126 123 | #define S_SETREGID 127 124 | #define S_RENAME 128 125 | #define S_TRUNCATE 129 126 | #define S_FTRUNCATE 130 127 | #define S_FLOCK 131 128 | #define S_SENDTO 133 129 | #define S_SHUTDOWN 134 130 | #define S_SOCKETPAIR 135 131 | #define S_MKDIR 136 132 | #define S_RMDIR 137 133 | #define S_UTIMES 138 134 | #define S_ADJTIME 140 135 | #define S_GETPEERNAME 141 136 | #define S_GETHOSTID 142 137 | #define S_SETHOSTID 143 138 | #define S_GETRLIMIT 144 139 | #define S_SETRLIMIT 145 140 | #define S_KILLPG 146 141 | #define S_NOSYS147 147 142 | #define S_SETQUOTA 148 143 | #define S_QUOTA 149 144 | #define S_GETSOCKNAME 150 145 | 146 | 147 | /* 148 | * System call names. 149 | */ 150 | #ifdef BSDTRAP_NAME 151 | char *bsdtrap_name[] = { 152 | "indir", /* 0 = indir */ 153 | "exit", /* 1 = exit */ 154 | "fork", /* 2 = fork */ 155 | "read", /* 3 = read */ 156 | "write", /* 4 = write */ 157 | "open", /* 5 = open */ 158 | "close", /* 6 = close */ 159 | "wait4", /* 7 = wait4 */ 160 | "creat", /* 8 = creat */ 161 | "link", /* 9 = link */ 162 | "unlink", /* 10 = unlink */ 163 | "execv", /* 11 = execv */ 164 | "chdir", /* 12 = chdir */ 165 | "fchdir", /* 13 = fchdir */ 166 | "mknod", /* 14 = mknod */ 167 | "chmod", /* 15 = chmod */ 168 | "chown", /* 16 = chown; now 3 args */ 169 | "chflags", /* 17 = chflags */ 170 | "fchflags", /* 18 = fchflags */ 171 | "lseek", /* 19 = lseek */ 172 | "getpid", /* 20 = getpid */ 173 | "mount", /* 21 = mount */ 174 | "umount", /* 22 = umount */ 175 | "__sysctl", /* 23 = __sysctl */ 176 | "getuid", /* 24 = getuid */ 177 | "geteuid", /* 25 = geteuid */ 178 | "ptrace", /* 26 = ptrace */ 179 | "getppid", /* 27 = getppid */ 180 | "statfs", /* 28 = statfs */ 181 | "fstatfs", /* 29 = fstatfs */ 182 | "getfsstat", /* 30 = getfsstat */ 183 | "sigaction", /* 31 = sigaction */ 184 | "sigprocmask", /* 32 = sigprocmask */ 185 | "access", /* 33 = access */ 186 | "sigpending", /* 34 = sigpending */ 187 | "sigaltstack", /* 35 = sigaltstack */ 188 | "sync", /* 36 = sync */ 189 | "kill", /* 37 = kill */ 190 | "stat", /* 38 = stat */ 191 | "getlogin", /* 39 = getlogin */ 192 | "lstat", /* 40 = lstat */ 193 | "dup", /* 41 = dup */ 194 | "pipe", /* 42 = pipe */ 195 | "setlogin", /* 43 = setlogin */ 196 | "profil", /* 44 = profil */ 197 | "setuid", /* 45 = setuid */ 198 | "seteuid", /* 46 = seteuid */ 199 | "getgid", /* 47 = getgid */ 200 | "getegid", /* 48 = getegid */ 201 | "setgid", /* 49 = setgid */ 202 | "setegid", /* 50 = setegid */ 203 | "acct", /* 51 = turn acct off/on */ 204 | "old phys", /* 52 = old set phys addr */ 205 | "old lock", /* 53 = old lock in core */ 206 | "ioctl", /* 54 = ioctl */ 207 | "reboot", /* 55 = reboot */ 208 | "old mpx - nosys", /* 56 = old mpxchan */ 209 | "symlink", /* 57 = symlink */ 210 | "readlink", /* 58 = readlink */ 211 | "execve", /* 59 = execve */ 212 | "umask", /* 60 = umask */ 213 | "chroot", /* 61 = chroot */ 214 | "fstat", /* 62 = fstat */ 215 | "#63", /* 63 = used internally */ 216 | "getpagesize", /* 64 = getpagesize */ 217 | "4.3 mremap - nosys", /* 65 = mremap */ 218 | "vfork", /* 66 = vfork */ 219 | "old vread - nosys", /* 67 = old vread */ 220 | "old vwrite - nosys", /* 68 = old vwrite */ 221 | "sbrk", /* 69 = sbrk */ 222 | "4.3 sstk - nosys", /* 70 = sstk */ 223 | "4.3 mmap - nosys", /* 71 = mmap */ 224 | "old vadvise - nosys", /* 72 = old vadvise */ 225 | "4.3 munmap - nosys", /* 73 = munmap */ 226 | "4.3 mprotect - nosys", /* 74 = mprotect */ 227 | "4.3 madvise - nosys", /* 75 = madvise */ 228 | "vhangup", /* 76 = vhangup */ 229 | "old vlimit - nosys", /* 77 = old vlimit */ 230 | "4.3 mincore - nosys", /* 78 = mincore */ 231 | "getgroups", /* 79 = getgroups */ 232 | "setgroups", /* 80 = setgroups */ 233 | "getpgrp", /* 81 = getpgrp */ 234 | "setpgrp", /* 82 = setpgrp */ 235 | "setitimer", /* 83 = setitimer */ 236 | "wait", /* 84 = wait */ 237 | "4.3 swapon - nosys", /* 85 = swapon */ 238 | "getitimer", /* 86 = getitimer */ 239 | "gethostname", /* 87 = gethostname */ 240 | "sethostname", /* 88 = sethostname */ 241 | "getdtablesize", /* 89 = getdtablesize */ 242 | "dup2", /* 90 = dup2 */ 243 | "nosys", /* 91 = unused */ 244 | "fcntl", /* 92 = fcntl */ 245 | "select", /* 93 = select */ 246 | "nosys", /* 94 = unused */ 247 | "fsync", /* 95 = fsync */ 248 | "setpriority", /* 96 = setpriority */ 249 | "socket", /* 97 = socket */ 250 | "connect", /* 98 = connect */ 251 | "accept", /* 99 = accept */ 252 | "getpriority", /* 100 = getpriority */ 253 | "send", /* 101 = send */ 254 | "recv", /* 102 = recv */ 255 | "sigreturn", /* 103 = sigreturn */ 256 | "bind", /* 104 = bind */ 257 | "setsockopt", /* 105 = setsockopt */ 258 | "listen", /* 106 = listen */ 259 | "sigsuspend", /* 107 = sigsuspend */ 260 | "sigvec", /* 108 = sigvec */ 261 | "sigblock", /* 109 = sigblock */ 262 | "sigsetmask", /* 110 = sigsetmask */ 263 | "sigpause", /* 111 = sigpause */ 264 | "sigstack", /* 112 = sigstack */ 265 | "recvmsg", /* 113 = recvmsg */ 266 | "sendmsg", /* 114 = sendmsg */ 267 | "old vtrace - nosys", /* 115 = old vtrace */ 268 | "gettimeofday", /* 116 = gettimeofday */ 269 | "getrusage", /* 117 = getrusage */ 270 | "getsockopt", /* 118 = getsockopt */ 271 | "4.3 resuba - nosys", /* 119 = resuba */ 272 | "readv", /* 120 = readv */ 273 | "writev", /* 121 = writev */ 274 | "settimeofday", /* 122 = settimeofday */ 275 | "fchown", /* 123 = fchown */ 276 | "fchmod", /* 124 = fchmod */ 277 | "recvfrom", /* 125 = recvfrom */ 278 | "setreuid", /* 126 = setreuid */ 279 | "setregid", /* 127 = setregid */ 280 | "rename", /* 128 = rename */ 281 | "truncate", /* 129 = truncate */ 282 | "ftruncate", /* 130 = ftruncate */ 283 | "flock", /* 131 = flock */ 284 | "old portal - nosys", /* 132 = old portal */ 285 | "sendto", /* 133 = sendto */ 286 | "shutdown", /* 134 = shutdown */ 287 | "socketpair", /* 135 = socketpair */ 288 | "mkdir", /* 136 = mkdir */ 289 | "rmdir", /* 137 = rmdir */ 290 | "utimes", /* 138 = utimes */ 291 | "4.2 sigreturn - nosys", /* 139 = old 4.2 sigreturn */ 292 | "adjtime", /* 140 = adjtime */ 293 | "getpeername", /* 141 = getpeername */ 294 | "gethostid", /* 142 = gethostid */ 295 | "sethostid", /* 143 = sethostid */ 296 | "getrlimit", /* 144 = getrlimit */ 297 | "setrlimit", /* 145 = setrlimit */ 298 | "killpg", /* 146 = killpg */ 299 | "#147", /* 147 = nosys */ 300 | "setquota", /* 148 = setquota */ 301 | "quota", /* 149 = quota */ 302 | "getsockname", /* 150 = getsockname */ 303 | }; 304 | #endif 305 | 306 | /* fcntl defines used by open */ 307 | #define BSD_RDONLY 0x0000 /* open for reading only */ 308 | #define BSD_WRONLY 0x0001 /* open for writing only */ 309 | #define BSD_RDWR 0x0002 /* open for reading and writing */ 310 | #define BSD_NONBLOCK 0x0004 /* no delay */ 311 | #define BSD_APPEND 0x0008 /* set append mode */ 312 | #define BSD_SHLOCK 0x0010 /* open with shared file lock */ 313 | #define BSD_EXLOCK 0x0020 /* open with exclusive file lock */ 314 | #define BSD_ASYNC 0x0040 /* signal pgrp when data ready */ 315 | #define BSD_FSYNC 0x0080 /* synchronous writes */ 316 | #define BSD_CREAT 0x0200 /* create if nonexistant */ 317 | #define BSD_TRUNC 0x0400 /* truncate to zero length */ 318 | #define BSD_EXCL 0x0800 /* error if already exists */ 319 | 320 | 321 | /* stat struct, used by S_STAT, S_FSTAT, S_LSTAT */ 322 | struct tr_stat 323 | { 324 | int16_t st_dev; 325 | u_int16_t st_ino; 326 | u_int16_t st_mode; 327 | int16_t st_nlink; 328 | u_int16_t st_uid; 329 | u_int16_t st_gid; 330 | int16_t st_rdev; 331 | int8_t st_size[4]; /* Alignment problems */ 332 | int8_t st_atim[4]; /* Alignment problems */ 333 | int16_t st_spare1; 334 | int8_t st_mtim[4]; /* Alignment problems */ 335 | int16_t st_spare2; 336 | int8_t st_ctim[4]; /* Alignment problems */ 337 | int16_t st_spare3; 338 | int8_t st_blksize[4]; /* Alignment problems */ 339 | int8_t st_blocks[4]; /* Alignment problems */ 340 | u_int16_t st_flags; 341 | u_int16_t st_spare4[3]; 342 | }; 343 | 344 | /* Directory entry */ 345 | #define TR_DIRBLKSIZ 512 346 | #define TR_MAXNAMLEN 63 347 | struct tr_direct { 348 | u_int16_t d_ino; /* inode number of entry */ 349 | u_int16_t d_reclen; /* length of this record */ 350 | u_int16_t d_namlen; /* length of string in d_name */ 351 | char d_name[TR_MAXNAMLEN+1]; /* name must be no longer than this */ 352 | }; 353 | 354 | /* used by S_ADJTIME */ 355 | struct tr_timeval { 356 | u_int32_t tv_sec; /* seconds */ 357 | u_int32_t tv_usec; /* and microseconds */ 358 | }; 359 | /* Used by S_GETTIMEOFDAY */ 360 | struct tr_timezone { 361 | int16_t tz_minuteswest; /* minutes west of Greenwich */ 362 | int16_t tz_dsttime; /* type of dst correction */ 363 | }; 364 | 365 | /* used in itimer calls */ 366 | struct tr_itimerval { 367 | struct tr_timeval it_interval; /* timer interval */ 368 | struct tr_timeval it_value; /* current value */ 369 | }; 370 | 371 | /* Used by socket calls */ 372 | struct tr_sockaddr { 373 | u_int16_t sa_family; /* address family */ 374 | char sa_data[14]; /* up to 14 bytes of direct address */ 375 | }; 376 | 377 | /* used in rlimit calls */ 378 | struct tr_rlimit { 379 | int32_t rlim_cur; /* current (soft) limit */ 380 | int32_t rlim_max; /* maximum value for rlim_cur */ 381 | }; 382 | 383 | struct tr_rusage { 384 | struct tr_timeval ru_utime; /* user time used */ 385 | struct tr_timeval ru_stime; /* system time used */ 386 | u_int32_t ru_maxrss; 387 | u_int32_t ru_ixrss; /* integral shared memory size */ 388 | u_int32_t ru_idrss; /* integral unshared data size */ 389 | u_int32_t ru_isrss; /* integral unshared stack size */ 390 | u_int32_t ru_minflt; /* page reclaims */ 391 | u_int32_t ru_majflt; /* page faults */ 392 | u_int32_t ru_ovly; /* overlay changes */ 393 | u_int32_t ru_nswap; /* swaps */ 394 | u_int32_t ru_inblock; /* block input operations */ 395 | u_int32_t ru_oublock; /* block output operations */ 396 | u_int32_t ru_msgsnd; /* messages sent */ 397 | u_int32_t ru_msgrcv; /* messages received */ 398 | u_int32_t ru_nsignals; /* signals received */ 399 | u_int32_t ru_nvcsw; /* voluntary context switches */ 400 | u_int32_t ru_nivcsw; /* involuntary context switches */ 401 | }; 402 | 403 | /* for writev, readv */ 404 | struct tr_iovec { 405 | u_int16_t iov_base; 406 | u_int16_t iov_len; 407 | }; 408 | 409 | 410 | /* A union which will point at the trap args, so that 411 | * we can get at the various args of different types 412 | */ 413 | typedef union { 414 | int16_t sarg[6]; /* Signed 16-bit args */ 415 | u_int16_t uarg[6]; /* Unsigned 16-bit args */ 416 | } arglist; 417 | 418 | #define sarg1 A->sarg[0] 419 | #define sarg2 A->sarg[1] 420 | #define sarg3 A->sarg[2] 421 | #define sarg4 A->sarg[3] 422 | #define sarg5 A->sarg[4] 423 | #define sarg6 A->sarg[5] 424 | #define uarg1 A->uarg[0] 425 | #define uarg2 A->uarg[1] 426 | #define uarg3 A->uarg[2] 427 | #define uarg4 A->uarg[3] 428 | #define uarg5 A->uarg[4] 429 | #define uarg6 A->uarg[5] 430 | -------------------------------------------------------------------------------- /tools/apout/cpu.c: -------------------------------------------------------------------------------- 1 | /* cpu.c - this holds the main loop for the emulator, plus generic 2 | * functions to deal with exceptional instructions and events 3 | * 4 | * $Revision: 1.26 $ 5 | * $Date: 2008/05/15 07:52:45 $ 6 | */ 7 | #include "defines.h" 8 | #include 9 | 10 | u_int8_t *ispace, *dspace; /* Instruction and Data spaces */ 11 | u_int16_t dwrite_base=2; /* Lowest addr where dspace writes can occur */ 12 | 13 | u_int16_t regs[8]; /* general registers */ 14 | u_int16_t ir; /* current instruction register */ 15 | u_int16_t *adptr; /* used in memory access macros */ 16 | u_int16_t ea_addr; /* stored address for dest modifying insts */ 17 | 18 | int CC_N=0; /* The processor status word is represented */ 19 | int CC_Z=0; /* by these four values. On some */ 20 | int CC_V=0; /* architectures, you may get a performance */ 21 | int CC_C=0; /* increase by using shorts or bytes */ 22 | 23 | u_int16_t dstword; /* These globals are used in the effective */ 24 | u_int16_t srcword; /* address calculations, mainly to save */ 25 | u_int16_t tmpword; /* parameter passing overheads in */ 26 | u_int8_t dstbyte; /* function calls */ 27 | u_int8_t srcbyte; 28 | u_int8_t tmpbyte; 29 | struct our_siglist *Sighead=NULL; /* List of pending signals */ 30 | struct our_siglist *Sigtail=NULL; /* List of pending signals */ 31 | void (*sigrunner)(void)= NULL; /* F'n that will run the signal */ 32 | 33 | #ifdef DEBUG 34 | extern char *iname[1024]; 35 | extern char *iname0[64]; /* Name of each instruction */ 36 | extern char *iname1[64]; 37 | char *name; 38 | #endif 39 | 40 | 41 | /* Run until told to stop. */ 42 | void run() { 43 | #ifdef DEBUG 44 | int i; 45 | 46 | if (trap_debug) { 47 | TrapDebug((dbg_file, "Just starting to run pid %d\n",(int)getpid())); 48 | TrapDebug((dbg_file, "Regs are ")); 49 | for (i=0;i<=PC;i++) TrapDebug((dbg_file, "%06o ",regs[i])); 50 | TrapDebug((dbg_file, "\n")); 51 | } 52 | #endif 53 | 54 | while (1) { 55 | 56 | /* Fetch and execute the instruction. */ 57 | 58 | #ifdef DEBUG 59 | lli_word(regs[PC], ir); 60 | if (inst_debug) { 61 | i= ir >> 6; 62 | switch (i) { 63 | case 0: name= iname0[ir & 077]; break; 64 | case 2: name= iname1[ir & 077]; break; 65 | default: name= iname[i]; 66 | } 67 | TrapDebug((dbg_file, "%06o %06o %4s ", regs[7], ir, name)); 68 | TrapDebug((dbg_file, "%06o %06o %06o %06o %06o %06o %06o ", 69 | regs[0], regs[1], regs[2], regs[3], 70 | regs[4], regs[5], regs[6])); 71 | TrapDebug((dbg_file, "NZVC1 %d%d%d%d\n",CC_N,CC_Z,CC_V,CC_C)); 72 | fflush(dbg_file); 73 | } 74 | regs[PC] += 2; itab[ir >> 6] (); 75 | if ((Sighead!=NULL) && (sigrunner!=NULL)) (void) (*sigrunner)(); 76 | #else 77 | /* When not debugging, we can manually unroll this inner loop */ 78 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 79 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 80 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 81 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 82 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 83 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 84 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 85 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 86 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 87 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 88 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 89 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 90 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 91 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 92 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 93 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 94 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 95 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 96 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 97 | lli_word(regs[PC], ir); regs[PC] += 2; itab[ir >> 6] (); 98 | if ((Sighead!=NULL) && (sigrunner!=NULL)) (void) (*sigrunner)(); 99 | #endif 100 | } 101 | } 102 | 103 | /* sim_init() - Initialize the cpu registers. */ 104 | void sim_init() { 105 | int x; 106 | 107 | for (x = 0; x < 8; ++x) { regs[x] = 0; } 108 | ir = 0; CLR_CC_ALL(); 109 | } 110 | 111 | void bus_error(int signo) 112 | { 113 | TrapDebug((dbg_file, "Apout - pid %d bus error at PC 0%06o\n", 114 | (int)getpid(), regs[PC])); 115 | TrapDebug((dbg_file, "%06o ", ir)); 116 | TrapDebug((dbg_file, "%o %o %o %o %o %o %o %o ", 117 | regs[0], regs[1], regs[2], regs[3], 118 | regs[4], regs[5], regs[6], regs[7])); 119 | TrapDebug((dbg_file, "NZVC2 are %d%d%d%d\n",CC_N,CC_Z,CC_V,CC_C)); 120 | exit(EXIT_FAILURE); 121 | } 122 | 123 | void seg_fault() { 124 | TrapDebug((dbg_file, "Apout - pid %d segmentation fault at PC 0%06o\n", 125 | (int)getpid(), regs[PC])); 126 | TrapDebug((dbg_file, "%06o ", ir)); 127 | TrapDebug((dbg_file, "%o %o %o %o %o %o %o %o ", 128 | regs[0], regs[1], regs[2], regs[3], 129 | regs[4], regs[5], regs[6], regs[7])); 130 | TrapDebug((dbg_file, "NZVC3 are %d%d%d%d\n",CC_N,CC_Z,CC_V,CC_C)); 131 | exit(EXIT_FAILURE); 132 | } 133 | 134 | void waiti() { 135 | TrapDebug((stderr, "Apout - pid %d waiti instruction at PC 0%o\n", 136 | (int)getpid(), regs[PC])); 137 | exit(EXIT_FAILURE); 138 | } 139 | void halt() { 140 | TrapDebug((stderr, "Apout - pid %d halt instruction at PC 0%o\n", 141 | (int)getpid(), regs[PC])); 142 | exit(EXIT_FAILURE); 143 | } 144 | void iot() { 145 | TrapDebug((stderr, "Apout - pid %d iot instruction at PC 0%o\n", 146 | (int)getpid(), regs[PC])); 147 | exit(EXIT_FAILURE); 148 | } 149 | void emt() { 150 | TrapDebug((stderr, "Apout - pid %d emt instruction at PC 0%o\n", 151 | (int)getpid(), regs[PC])); 152 | exit(EXIT_FAILURE); 153 | } 154 | void bpt() { 155 | TrapDebug((stderr, "Apout - pid %d bpt instruction at PC 0%o\n", 156 | (int)getpid(), regs[PC])); 157 | exit(EXIT_FAILURE); 158 | } 159 | void illegal() { 160 | TrapDebug((stderr, "Apout - pid %d illegal instruction %o at PC 0%o\n", 161 | (int)getpid(),ir, regs[PC])); 162 | exit(EXIT_FAILURE); 163 | } 164 | void not_impl() { 165 | TrapDebug((stderr, "Apout - pid %d unimplemented instruction at PC 0%o\n", 166 | (int)getpid(), regs[PC])); 167 | exit(EXIT_FAILURE); 168 | } 169 | void mark() { 170 | TrapDebug((stderr, "Apout - pid %d mark instruction at PC 0%o\n", 171 | (int)getpid(), regs[PC])); 172 | exit(EXIT_FAILURE); 173 | } 174 | void mfpd() { 175 | TrapDebug((stderr, "Apout - pid %d mfpd instruction at PC 0%o\n", 176 | (int)getpid(), regs[PC])); 177 | exit(EXIT_FAILURE); 178 | } 179 | void mtpd() { 180 | TrapDebug((stderr, "Apout - pid %d mtpd instruction at PC 0%o\n", 181 | (int)getpid(), regs[PC])); 182 | exit(EXIT_FAILURE); 183 | } 184 | void trap() { 185 | TrapDebug((stderr, "Apout - pid %d trap instruction at PC 0%o\n", 186 | (int)getpid(), regs[PC])); 187 | exit(EXIT_FAILURE); 188 | } 189 | void bad_FP_reg() { 190 | TrapDebug((stderr, "Apout - pid %d bad FP register used at PC 0%o\n", 191 | (int)getpid(), regs[PC])); 192 | exit(EXIT_FAILURE); 193 | } 194 | 195 | /* This is the generic function which catches 196 | * a signal, and appends it to the queue. 197 | */ 198 | void sigcatcher(int sig) 199 | { 200 | struct our_siglist *this; 201 | 202 | this= (struct our_siglist *)malloc(sizeof(struct our_siglist)); 203 | if (this==NULL) return; 204 | 205 | TrapDebug((dbg_file, "Caught signal %d\n",sig)); 206 | 207 | this->sig=sig; this->next=NULL; 208 | if (Sighead==NULL) { Sighead=Sigtail=this; } 209 | else { Sigtail->next= this; Sigtail=this; } 210 | } 211 | -------------------------------------------------------------------------------- /tools/apout/debug.c: -------------------------------------------------------------------------------- 1 | /* List of names for each instruction 2 | * 3 | * $Revision: 1.5 $ 4 | * $Date: 1999/01/05 22:50:48 $ 5 | */ 6 | #ifdef DEBUG 7 | char *iname0[64] = { 8 | "halt","waiti","illegal","bpt","iot","illegal","illegal","illegal", 9 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 10 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 11 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 12 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 13 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 14 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 15 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal" 16 | }; 17 | 18 | char *iname1[64] = { 19 | "rts","rts","rts","rts","rts","rts","rts","rts", 20 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 21 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 22 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 23 | "ccc","ccc","ccc","ccc","ccc","ccc","ccc","ccc", 24 | "ccc","ccc","ccc","ccc","ccc","ccc","ccc","ccc", 25 | "scc","scc","scc","scc","scc","scc","scc","scc", 26 | "scc","scc","scc","scc","scc","scc","scc","scc" 27 | }; 28 | 29 | char *iname[1024] = { 30 | "dositab0","jmp","dositab1","swabi","br","br","br","br", 31 | "bne","bne","bne","bne","beq","beq","beq","beq", 32 | "bge","bge","bge","bge","blt","blt","blt","blt", 33 | "bgt","bgt","bgt","bgt","ble","ble","ble","ble", 34 | "jsr","jsr","jsr","jsr","jsr","jsr","jsr","jsr", 35 | "clr","com","inc","dec","neg","adc","sbc","tst", 36 | "ror","rol","asr","asl","mark","mfpi","mtpi","sxt", 37 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 38 | "mov","mov","mov","mov","mov","mov","mov","mov", 39 | "mov","mov","mov","mov","mov","mov","mov","mov", 40 | "mov","mov","mov","mov","mov","mov","mov","mov", 41 | "mov","mov","mov","mov","mov","mov","mov","mov", 42 | "mov","mov","mov","mov","mov","mov","mov","mov", 43 | "mov","mov","mov","mov","mov","mov","mov","mov", 44 | "mov","mov","mov","mov","mov","mov","mov","mov", 45 | "mov","mov","mov","mov","mov","mov","mov","mov", 46 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 47 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 48 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 49 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 50 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 51 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 52 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 53 | "cmp","cmp","cmp","cmp","cmp","cmp","cmp","cmp", 54 | "bit","bit","bit","bit","bit","bit","bit","bit", 55 | "bit","bit","bit","bit","bit","bit","bit","bit", 56 | "bit","bit","bit","bit","bit","bit","bit","bit", 57 | "bit","bit","bit","bit","bit","bit","bit","bit", 58 | "bit","bit","bit","bit","bit","bit","bit","bit", 59 | "bit","bit","bit","bit","bit","bit","bit","bit", 60 | "bit","bit","bit","bit","bit","bit","bit","bit", 61 | "bit","bit","bit","bit","bit","bit","bit","bit", 62 | "bic","bic","bic","bic","bic","bic","bic","bic", 63 | "bic","bic","bic","bic","bic","bic","bic","bic", 64 | "bic","bic","bic","bic","bic","bic","bic","bic", 65 | "bic","bic","bic","bic","bic","bic","bic","bic", 66 | "bic","bic","bic","bic","bic","bic","bic","bic", 67 | "bic","bic","bic","bic","bic","bic","bic","bic", 68 | "bic","bic","bic","bic","bic","bic","bic","bic", 69 | "bic","bic","bic","bic","bic","bic","bic","bic", 70 | "bis","bis","bis","bis","bis","bis","bis","bis", 71 | "bis","bis","bis","bis","bis","bis","bis","bis", 72 | "bis","bis","bis","bis","bis","bis","bis","bis", 73 | "bis","bis","bis","bis","bis","bis","bis","bis", 74 | "bis","bis","bis","bis","bis","bis","bis","bis", 75 | "bis","bis","bis","bis","bis","bis","bis","bis", 76 | "bis","bis","bis","bis","bis","bis","bis","bis", 77 | "bis","bis","bis","bis","bis","bis","bis","bis", 78 | "add","add","add","add","add","add","add","add", 79 | "add","add","add","add","add","add","add","add", 80 | "add","add","add","add","add","add","add","add", 81 | "add","add","add","add","add","add","add","add", 82 | "add","add","add","add","add","add","add","add", 83 | "add","add","add","add","add","add","add","add", 84 | "add","add","add","add","add","add","add","add", 85 | "add","add","add","add","add","add","add","add", 86 | "mul","mul","mul","mul","mul","mul","mul","mul", 87 | "divide","divide","divide","divide","divide","divide","divide","divide", 88 | "ash","ash","ash","ash","ash","ash","ash","ash", 89 | "ashc","ashc","ashc","ashc","ashc","ashc","ashc","ashc", 90 | "xor","xor","xor","xor","xor","xor","xor","xor", 91 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 92 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 93 | "sob","sob","sob","sob","sob","sob","sob","sob", 94 | "bpl","bpl","bpl","bpl","bmi","bmi","bmi","bmi", 95 | "bhi","bhi","bhi","bhi","blos","blos","blos","blos", 96 | "bvc","bvc","bvc","bvc","bvs","bvs","bvs","bvs", 97 | "bcc","bcc","bcc","bcc","bcs","bcs","bcs","bcs", 98 | "emt","emt","emt","emt","trap","trap","trap","trap", 99 | "clrb","comb","incb","decb","negb","adcb","sbcb","tstb", 100 | "rorb","rolb","asrb","aslb","mtps","mfpd","mtpd","mfps", 101 | "illegal","illegal","illegal","illegal","illegal","illegal","illegal","illegal", 102 | "movb","movb","movb","movb","movb","movb","movb","movb", 103 | "movb","movb","movb","movb","movb","movb","movb","movb", 104 | "movb","movb","movb","movb","movb","movb","movb","movb", 105 | "movb","movb","movb","movb","movb","movb","movb","movb", 106 | "movb","movb","movb","movb","movb","movb","movb","movb", 107 | "movb","movb","movb","movb","movb","movb","movb","movb", 108 | "movb","movb","movb","movb","movb","movb","movb","movb", 109 | "movb","movb","movb","movb","movb","movb","movb","movb", 110 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 111 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 112 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 113 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 114 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 115 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 116 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 117 | "cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb","cmpb", 118 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 119 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 120 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 121 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 122 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 123 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 124 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 125 | "bitb","bitb","bitb","bitb","bitb","bitb","bitb","bitb", 126 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 127 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 128 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 129 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 130 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 131 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 132 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 133 | "bicb","bicb","bicb","bicb","bicb","bicb","bicb","bicb", 134 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 135 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 136 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 137 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 138 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 139 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 140 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 141 | "bisb","bisb","bisb","bisb","bisb","bisb","bisb","bisb", 142 | "sub","sub","sub","sub","sub","sub","sub","sub", 143 | "sub","sub","sub","sub","sub","sub","sub","sub", 144 | "sub","sub","sub","sub","sub","sub","sub","sub", 145 | "sub","sub","sub","sub","sub","sub","sub","sub", 146 | "sub","sub","sub","sub","sub","sub","sub","sub", 147 | "sub","sub","sub","sub","sub","sub","sub","sub", 148 | "sub","sub","sub","sub","sub","sub","sub","sub", 149 | "sub","sub","sub","sub","sub","sub","sub","sub", 150 | "fpset","ldfps","stfps","stst","clrf","tstf","absf","negf", 151 | "mulf","mulf","mulf","mulf","moddf","moddf","moddf","moddf", 152 | "addf","addf","addf","addf","ldf","ldf","ldf","ldf", 153 | "subf","subf","subf","subf","cmpf","cmpf","cmpf","cmpf", 154 | "stf","stf","stf","stf","divf","divf","divf","divf", 155 | "stexp","stexp","stexp","stexp","stcfi","stcfi","stcfi","stcfi", 156 | "stcdf","stcdf","stcdf","stcdf","ldexpp","ldexpp","ldexpp","ldexpp", 157 | "lcdif","lcdif","lcdif","lcdif","ldcdf","ldcdf","ldcdf","ldcdf" 158 | }; 159 | #endif 160 | -------------------------------------------------------------------------------- /tools/apout/double.c: -------------------------------------------------------------------------------- 1 | /* double.c - Double operand instructions. 2 | * 3 | * $Revision: 2.11 $ 4 | * $Date: 1999/12/27 10:19:40 $ 5 | */ 6 | #include "defines.h" 7 | 8 | static u_int32_t templong; 9 | 10 | 11 | /* mov() - Move Instruction. Move operations with registers as the source 12 | * and/or destination have been inlined. */ 13 | void 14 | mov() 15 | { 16 | 17 | if (SRC_MODE) { 18 | load_src(); dstword=srcword; 19 | } else { 20 | dstword = regs[SRC_REG]; 21 | } 22 | 23 | CHG_CC_N(dstword); 24 | CHG_CC_Z(dstword); 25 | CLR_CC_V(); 26 | 27 | if (DST_MODE) { 28 | store_dst(); 29 | } else { 30 | regs[DST_REG] = dstword; 31 | } 32 | } 33 | 34 | /* movsreg(), movsreg1() and movsreg1pc() can all be replaced with 35 | * mov() above. I've broken them out in an attempt to improve 36 | * performance. 37 | */ 38 | void 39 | movsreg() 40 | { 41 | dstword = regs[SRC_REG]; 42 | CHG_CC_N(dstword); 43 | CHG_CC_Z(dstword); 44 | CLR_CC_V(); 45 | 46 | if (DST_MODE) { 47 | store_dst(); 48 | } else { 49 | regs[DST_REG] = dstword; 50 | } 51 | } 52 | 53 | void 54 | movsreg1() 55 | { 56 | ll_word(regs[SRC_REG], dstword); 57 | CHG_CC_N(dstword); 58 | CHG_CC_Z(dstword); 59 | CLR_CC_V(); 60 | 61 | if (DST_MODE) { 62 | store_dst(); 63 | } else { 64 | regs[DST_REG] = dstword; 65 | } 66 | } 67 | 68 | void 69 | movsreg1pc() 70 | { 71 | lli_word(regs[PC], dstword) 72 | CHG_CC_N(dstword); 73 | CHG_CC_Z(dstword); 74 | CLR_CC_V(); 75 | 76 | if (DST_MODE) { 77 | store_dst(); 78 | } else { 79 | regs[DST_REG] = dstword; 80 | } 81 | } 82 | 83 | 84 | 85 | /* cmp() - Compare Instruction. */ 86 | void 87 | cmp() 88 | { 89 | load_src(); 90 | load_dst(); 91 | 92 | tmpword = ~dstword; 93 | templong = ((u_int32_t) srcword) + ((u_int32_t) (tmpword)) + 1; 94 | tmpword = LOW16(templong); 95 | 96 | CHG_CC_N(tmpword); 97 | CHG_CC_Z(tmpword); 98 | CHG_CC_VC(srcword, dstword, tmpword); /* was CHG_CC_V */ 99 | CHG_CC_IC(templong); 100 | } 101 | 102 | 103 | /* add() - Add Instruction. */ 104 | void 105 | add() 106 | { 107 | load_src(); 108 | load_dst(); 109 | 110 | templong = ((u_int32_t) srcword) + ((u_int32_t) dstword); 111 | tmpword = LOW16(templong); 112 | 113 | CHG_CC_N(tmpword); 114 | CHG_CC_Z(tmpword); 115 | CHG_CC_V(srcword, dstword, tmpword); 116 | CHG_CC_C(templong); 117 | 118 | dstword=tmpword; store_dst_2(); 119 | } 120 | 121 | /* Subtract Instruction. */ 122 | void 123 | sub() 124 | { 125 | load_src(); 126 | load_dst(); 127 | 128 | tmpword = ~srcword; 129 | templong = ((u_int32_t) dstword) + ((u_int32_t) tmpword) + 1; 130 | tmpword = LOW16(templong); 131 | 132 | CHG_CC_N(tmpword); 133 | CHG_CC_Z(tmpword); 134 | CHG_CC_VS(srcword, dstword, tmpword); /* was CHG_CC_V */ 135 | CHG_CC_IC(templong); 136 | 137 | dstword=tmpword; store_dst_2(); 138 | } 139 | 140 | 141 | /* bit() - Bit Test Instruction. */ 142 | void 143 | bit() 144 | { 145 | load_src(); 146 | load_dst(); 147 | 148 | dstword = srcword & dstword; 149 | 150 | CHG_CC_N(dstword); 151 | CHG_CC_Z(dstword); 152 | CLR_CC_V(); 153 | } 154 | 155 | /* bic() - Bit Clear Instruction. */ 156 | void 157 | bic() 158 | { 159 | load_src(); 160 | load_dst(); 161 | 162 | dstword = (~srcword) & dstword; 163 | CHG_CC_N(dstword); 164 | CHG_CC_Z(dstword); 165 | CLR_CC_V(); 166 | 167 | store_dst_2(); 168 | } 169 | 170 | 171 | /* bis() - Bit Set Instruction. */ 172 | void 173 | bis() 174 | { 175 | load_src(); 176 | load_dst(); 177 | 178 | dstword = srcword | dstword; 179 | 180 | CHG_CC_N(dstword); 181 | CHG_CC_Z(dstword); 182 | CLR_CC_V(); 183 | 184 | store_dst_2(); 185 | } 186 | 187 | /* movb() - Move Byte Instruction. Move operations with registers as the 188 | * source and/or destination have been inlined. */ 189 | void 190 | movb() 191 | { 192 | if (SRC_MODE) { 193 | loadb_src(); 194 | } else { 195 | srcbyte = LOW8(regs[SRC_REG]); 196 | } 197 | 198 | CHGB_CC_N(srcbyte); 199 | CHGB_CC_Z(srcbyte); 200 | CLR_CC_V(); 201 | 202 | /* move byte to a register causes sign extension */ 203 | 204 | if (DST_MODE) { 205 | storeb_dst(); 206 | } else { 207 | if (srcbyte & SIGN_B) 208 | regs[DST_REG] = (u_int16_t)0177400 + (u_int16_t)srcbyte; 209 | else 210 | regs[DST_REG] = (u_int16_t)srcbyte; 211 | } 212 | } 213 | 214 | /* cmpb() - Compare Byte Instruction. */ 215 | void 216 | cmpb() 217 | { 218 | u_int8_t data3; 219 | 220 | loadb_src(); 221 | loadb_dst(); 222 | 223 | data3 = (u_int8_t)~dstbyte; 224 | tmpword = ((u_int16_t) srcbyte) + ((u_int16_t) (data3)) + 1; 225 | data3 = LOW8(tmpword); 226 | 227 | CHGB_CC_N(data3); 228 | CHGB_CC_Z(data3); 229 | CHGB_CC_VC(srcbyte, dstbyte, data3); 230 | CHGB_CC_IC(tmpword); 231 | } 232 | 233 | 234 | /* bitb() - Bit Test Byte Instruction. */ 235 | void 236 | bitb() 237 | { 238 | loadb_src(); 239 | loadb_dst(); 240 | 241 | dstbyte = srcbyte & dstbyte; 242 | 243 | CHGB_CC_N(dstbyte); 244 | CHGB_CC_Z(dstbyte); 245 | CLR_CC_V(); 246 | } 247 | 248 | /* bicb() - Bit Clear Byte Instruction. */ 249 | void 250 | bicb() 251 | { 252 | loadb_src(); 253 | loadb_dst(); 254 | 255 | dstbyte = (u_int8_t)((~srcbyte) & dstbyte); 256 | 257 | CHGB_CC_N(dstbyte); 258 | CHGB_CC_Z(dstbyte); 259 | CLR_CC_V(); 260 | 261 | storeb_dst_2(); 262 | } 263 | 264 | 265 | /* bisb() - Bit Set Byte Instruction. */ 266 | 267 | void 268 | bisb() 269 | { 270 | loadb_src(); 271 | loadb_dst(); 272 | 273 | dstbyte = srcbyte | dstbyte; 274 | 275 | CHGB_CC_N(dstbyte); 276 | CHGB_CC_Z(dstbyte); 277 | CLR_CC_V(); 278 | 279 | storeb_dst_2(); 280 | } 281 | -------------------------------------------------------------------------------- /tools/apout/ea.c: -------------------------------------------------------------------------------- 1 | /* ea.c - Calculate, load, and store using the proper effective address as 2 | * specified by the current instruction. Also push and pop stack operations. 3 | * 4 | * $Revision: 2.17 $ 5 | * $Date: 1999/09/17 05:11:10 $ 6 | */ 7 | #include "defines.h" 8 | 9 | void 10 | load_ea(void) 11 | { 12 | u_int16_t indirect; 13 | 14 | switch (DST_MODE) { 15 | case 0: 16 | illegal(); 17 | return; 18 | case 1: 19 | dstword = regs[DST_REG]; 20 | return; 21 | case 2: 22 | dstword = regs[DST_REG]; /* this is wrong for 11/34 */ 23 | regs[DST_REG] += 2; 24 | return; 25 | case 3: 26 | indirect = regs[DST_REG]; /* this is wrong for 11/34 */ 27 | regs[DST_REG] += 2; 28 | lli_word(indirect, dstword); 29 | return; 30 | case 4: 31 | regs[DST_REG] -= 2; 32 | dstword = regs[DST_REG]; 33 | return; 34 | case 5: 35 | regs[DST_REG] -= 2; 36 | indirect = regs[DST_REG]; 37 | lli_word(indirect, dstword); 38 | return; 39 | case 6: 40 | lli_word(regs[PC], indirect); 41 | regs[PC] += 2; 42 | dstword = regs[DST_REG] + indirect; 43 | return; 44 | case 7: 45 | lli_word(regs[PC], indirect); 46 | regs[PC] += 2; 47 | indirect = regs[DST_REG] + indirect; 48 | ll_word(indirect, dstword); 49 | return; 50 | } 51 | illegal(); 52 | } 53 | 54 | 55 | INLINE void 56 | pop(void) 57 | { 58 | ll_word(regs[SP], dstword); 59 | regs[SP] += 2; 60 | } 61 | 62 | 63 | INLINE void 64 | push(void) 65 | { 66 | regs[SP] -= 2; 67 | sl_word(regs[SP], srcword); 68 | } 69 | 70 | 71 | void 72 | loadb_dst(void) 73 | { 74 | u_int16_t addr, indirect; 75 | 76 | switch (DST_MODE) { 77 | case 0: 78 | dstbyte = (u_int8_t)(regs[DST_REG] & 0377); 79 | return; 80 | case 1: 81 | addr = regs[DST_REG]; 82 | ea_addr = addr; 83 | if (DST_REG == PC) { 84 | lli_byte(addr, dstbyte) 85 | } else { 86 | ll_byte(addr, dstbyte); 87 | } 88 | return; 89 | case 2: 90 | addr = regs[DST_REG]; 91 | ea_addr = addr; 92 | if (DST_REG == PC) { 93 | lli_byte(addr, dstbyte) 94 | } else { 95 | ll_byte(addr, dstbyte); 96 | } 97 | if (DST_REG >= 6) 98 | regs[DST_REG] += 2; 99 | else 100 | regs[DST_REG] += 1; 101 | return; 102 | case 3: 103 | indirect = regs[DST_REG]; 104 | if (DST_REG == PC) { 105 | lli_word(indirect, addr) 106 | } else { 107 | ll_word(indirect, addr); 108 | } 109 | ea_addr = addr; 110 | ll_byte(addr, dstbyte); 111 | regs[DST_REG] += 2; 112 | return; 113 | case 4: 114 | if (DST_REG >= 6) 115 | regs[DST_REG] -= 2; 116 | else 117 | regs[DST_REG] -= 1; 118 | addr = regs[DST_REG]; 119 | ea_addr = addr; 120 | ll_byte(addr, dstbyte); 121 | return; 122 | case 5: 123 | regs[DST_REG] -= 2; 124 | indirect = regs[DST_REG]; 125 | ll_word(indirect, addr); 126 | ea_addr = addr; 127 | ll_byte(addr, dstbyte); 128 | return; 129 | case 6: 130 | lli_word(regs[PC], indirect); 131 | regs[PC] += 2; 132 | addr = regs[DST_REG] + indirect; 133 | ea_addr = addr; 134 | ll_byte(addr, dstbyte); 135 | return; 136 | case 7: 137 | lli_word(regs[PC], indirect); 138 | regs[PC] += 2; 139 | indirect = regs[DST_REG] + indirect; 140 | ll_word(indirect, addr); 141 | ea_addr = addr; 142 | ll_byte(addr, dstbyte); 143 | return; 144 | } 145 | illegal(); 146 | } 147 | 148 | 149 | void 150 | loadb_src(void) 151 | { 152 | u_int16_t addr, indirect; 153 | 154 | switch (SRC_MODE) { 155 | case 0: 156 | srcbyte = (u_int8_t)(regs[SRC_REG] & 0377); 157 | return; 158 | case 1: 159 | addr = regs[SRC_REG]; 160 | if (SRC_REG == PC) { 161 | lli_byte(addr, srcbyte); 162 | } else { 163 | ll_byte(addr, srcbyte); 164 | } 165 | return; 166 | case 2: 167 | addr = regs[SRC_REG]; 168 | if (SRC_REG == PC) { 169 | lli_byte(addr, srcbyte); 170 | } else { 171 | ll_byte(addr, srcbyte); 172 | } 173 | if (SRC_REG >= 6) 174 | regs[SRC_REG] += 2; 175 | else 176 | regs[SRC_REG] += 1; 177 | return; 178 | case 3: 179 | indirect = regs[SRC_REG]; 180 | if (SRC_REG == PC) { 181 | lli_word(indirect, addr) 182 | } else { 183 | ll_word(indirect, addr); 184 | } 185 | ll_byte(addr, srcbyte); 186 | regs[SRC_REG] += 2; 187 | return; 188 | case 4: 189 | if (SRC_REG >= 6) 190 | regs[SRC_REG] -= 2; 191 | else 192 | regs[SRC_REG] -= 1; 193 | addr = regs[SRC_REG]; 194 | ll_byte(addr, srcbyte); 195 | return; 196 | case 5: 197 | regs[SRC_REG] -= 2; 198 | indirect = regs[SRC_REG]; 199 | ll_word(indirect, addr); 200 | ll_byte(addr, srcbyte); 201 | return; 202 | case 6: 203 | lli_word(regs[PC], indirect); 204 | regs[PC] += 2; 205 | addr = regs[SRC_REG] + indirect; 206 | ll_byte(addr, srcbyte); 207 | return; 208 | case 7: 209 | lli_word(regs[PC], indirect); 210 | regs[PC] += 2; 211 | indirect = regs[SRC_REG] + indirect; 212 | ll_word(indirect, addr); 213 | ll_byte(addr, srcbyte); 214 | return; 215 | } 216 | illegal(); 217 | } 218 | 219 | void 220 | storeb_dst(void) 221 | { 222 | u_int16_t addr, indirect; 223 | 224 | switch (DST_MODE) { 225 | case 0: 226 | regs[DST_REG]&= 0xff00; 227 | regs[DST_REG]|= srcbyte; 228 | return; 229 | case 1: 230 | addr = regs[DST_REG]; 231 | sl_byte(addr, srcbyte); 232 | return; 233 | case 2: 234 | addr = regs[DST_REG]; 235 | sl_byte(addr, srcbyte); 236 | if (DST_REG >= 6) 237 | regs[DST_REG] += 2; 238 | else 239 | regs[DST_REG] += 1; 240 | return; 241 | case 3: 242 | indirect = regs[DST_REG]; 243 | ll_word(indirect, addr); 244 | sl_byte(addr, srcbyte); 245 | regs[DST_REG] += 2; 246 | return; 247 | case 4: 248 | if (DST_REG >= 6) /* xyz */ 249 | regs[DST_REG] -= 2; 250 | else 251 | regs[DST_REG] -= 1; 252 | addr = regs[DST_REG]; 253 | sl_byte(addr, srcbyte); 254 | return; 255 | case 5: 256 | regs[DST_REG] -= 2; 257 | indirect = regs[DST_REG]; 258 | ll_word(indirect, addr); 259 | sl_byte(addr, srcbyte); 260 | return; 261 | case 6: 262 | lli_word(regs[PC], indirect); 263 | regs[PC] += 2; 264 | addr = regs[DST_REG] + indirect; 265 | sl_byte(addr, srcbyte); 266 | return; 267 | case 7: 268 | lli_word(regs[PC], indirect); 269 | regs[PC] += 2; 270 | indirect = regs[DST_REG] + indirect; 271 | ll_word(indirect, addr); 272 | sl_byte(addr, srcbyte); 273 | return; 274 | } 275 | illegal(); 276 | } 277 | 278 | 279 | INLINE void 280 | storeb_dst_2(void) 281 | { 282 | if (DST_MODE == 0) { 283 | regs[DST_REG]&= 0xff00; 284 | regs[DST_REG]|= dstbyte; 285 | return; 286 | } 287 | sl_byte(ea_addr, dstbyte); 288 | } 289 | 290 | 291 | void 292 | loadp_dst(void) 293 | { 294 | u_int16_t addr, indirect; 295 | 296 | switch (DST_MODE) { 297 | case 0: 298 | srcword = regs[DST_REG]; 299 | return; 300 | case 1: 301 | addr = regs[DST_REG]; 302 | ll_word(addr, srcword); 303 | return; 304 | case 2: 305 | addr = regs[DST_REG]; 306 | ll_word(addr, srcword); 307 | regs[DST_REG] += 2; 308 | return; 309 | case 3: 310 | indirect = regs[DST_REG]; 311 | ll_word(indirect, addr); 312 | ll_word(addr, srcword); 313 | regs[DST_REG] += 2; 314 | return; 315 | case 4: 316 | regs[DST_REG] -= 2; 317 | addr = regs[DST_REG]; 318 | ll_word(addr, srcword); 319 | return; 320 | case 5: 321 | regs[DST_REG] -= 2; 322 | indirect = regs[DST_REG]; 323 | ll_word(indirect, addr); 324 | ll_word(addr, srcword); 325 | return; 326 | case 6: 327 | lli_word(regs[PC], indirect); 328 | regs[PC] += 2; 329 | addr = regs[DST_REG] + indirect; 330 | if (DST_REG == PC) 331 | lli_word(addr, srcword) 332 | else 333 | ll_word(addr, srcword); 334 | return; 335 | case 7: 336 | not_impl(); 337 | } 338 | illegal(); 339 | } 340 | 341 | 342 | void 343 | storep_dst(void) 344 | { 345 | u_int16_t addr, indirect; 346 | 347 | switch (DST_MODE) { 348 | case 0: 349 | regs[DST_REG] = dstword; 350 | return; 351 | case 1: 352 | addr = regs[DST_REG]; 353 | sl_word(addr, dstword); 354 | return; 355 | case 2: 356 | addr = regs[DST_REG]; 357 | sl_word(addr, dstword); 358 | regs[DST_REG] += 2; 359 | return; 360 | case 3: 361 | indirect = regs[DST_REG]; 362 | ll_word(indirect, addr); 363 | sl_word(addr, dstword); 364 | regs[DST_REG] += 2; 365 | return; 366 | case 4: 367 | regs[DST_REG] -= 2; 368 | addr = regs[DST_REG]; 369 | sl_word(addr, dstword); 370 | return; 371 | case 5: 372 | regs[DST_REG] -= 2; 373 | indirect = regs[DST_REG]; 374 | ll_word(indirect, addr); 375 | sl_word(addr, dstword); 376 | return; 377 | case 6: 378 | lli_word(regs[PC], indirect); 379 | regs[PC] += 2; 380 | addr = regs[DST_REG] + indirect; 381 | sl_word(addr, dstword); 382 | return; 383 | case 7: 384 | not_impl(); 385 | } 386 | illegal(); 387 | } 388 | 389 | 390 | void 391 | load_src(void) 392 | { 393 | u_int16_t addr, indirect; 394 | 395 | switch (SRC_MODE) { 396 | case 0: 397 | srcword = regs[SRC_REG]; 398 | return; 399 | case 1: 400 | addr = regs[SRC_REG]; 401 | if (SRC_REG == PC) { 402 | lli_word(addr, srcword) 403 | } else { 404 | ll_word(addr, srcword); 405 | } 406 | return; 407 | case 2: 408 | addr = regs[SRC_REG]; 409 | if (SRC_REG == PC) { 410 | lli_word(addr, srcword) 411 | } else { 412 | ll_word(addr, srcword); 413 | } 414 | regs[SRC_REG] += 2; 415 | return; 416 | case 3: 417 | indirect = regs[SRC_REG]; 418 | if (SRC_REG == PC) { 419 | lli_word(indirect, addr) 420 | } else { 421 | ll_word(indirect, addr); 422 | } 423 | regs[SRC_REG] += 2; /* is this right ? */ 424 | ll_word(addr, srcword); 425 | return; 426 | case 4: 427 | regs[SRC_REG] -= 2; 428 | addr = regs[SRC_REG]; 429 | ll_word(addr, srcword); 430 | return; 431 | case 5: 432 | regs[SRC_REG] -= 2; 433 | indirect = regs[SRC_REG]; 434 | ll_word(indirect, addr); 435 | ll_word(addr, srcword); 436 | return; 437 | case 6: 438 | lli_word(regs[PC], indirect); 439 | regs[PC] += 2; 440 | addr = regs[SRC_REG] + indirect; 441 | ll_word(addr, srcword); 442 | return; 443 | case 7: 444 | lli_word(regs[PC], indirect); 445 | regs[PC] += 2; 446 | indirect = regs[SRC_REG] + indirect; 447 | ll_word(indirect, addr); 448 | ll_word(addr, srcword); 449 | return; 450 | } 451 | illegal(); 452 | } 453 | 454 | 455 | void 456 | store_dst(void) 457 | { 458 | u_int16_t addr, indirect; 459 | 460 | switch (DST_MODE) { 461 | case 0: 462 | regs[DST_REG] = dstword; 463 | return; 464 | case 1: 465 | addr = regs[DST_REG]; 466 | sl_word(addr, dstword); 467 | return; 468 | case 2: 469 | addr = regs[DST_REG]; 470 | sl_word(addr, dstword); 471 | regs[DST_REG] += 2; 472 | return; 473 | case 3: 474 | indirect = regs[DST_REG]; 475 | ll_word(indirect, addr); 476 | regs[DST_REG] += 2; /* is this right ? */ 477 | sl_word(addr, dstword); 478 | return; 479 | case 4: 480 | regs[DST_REG] -= 2; 481 | addr = regs[DST_REG]; 482 | sl_word(addr, dstword); 483 | return; 484 | case 5: 485 | regs[DST_REG] -= 2; 486 | indirect = regs[DST_REG]; 487 | ll_word(indirect, addr); 488 | sl_word(addr, dstword); 489 | return; 490 | case 6: 491 | lli_word(regs[PC], indirect); 492 | regs[PC] += 2; 493 | addr = regs[DST_REG] + indirect; 494 | sl_word(addr, dstword); 495 | return; 496 | case 7: 497 | lli_word(regs[PC], indirect); 498 | regs[PC] += 2; 499 | indirect = regs[DST_REG] + indirect; 500 | ll_word(indirect, addr); 501 | sl_word(addr, dstword); 502 | return; 503 | } 504 | illegal(); 505 | } 506 | 507 | 508 | void 509 | load_dst(void) 510 | { 511 | u_int16_t addr, indirect; 512 | 513 | switch (DST_MODE) { 514 | case 0: 515 | dstword = regs[DST_REG]; 516 | return; 517 | case 1: 518 | addr = regs[DST_REG]; 519 | ea_addr = addr; 520 | if (DST_REG == PC) { 521 | lli_word(addr, dstword) 522 | } else { 523 | ll_word(addr, dstword); 524 | } 525 | return; 526 | case 2: 527 | addr = regs[DST_REG]; 528 | ea_addr = addr; 529 | if (DST_REG == PC) { 530 | lli_word(addr, dstword) 531 | } else { 532 | ll_word(addr, dstword); 533 | } 534 | regs[DST_REG] += 2; 535 | return; 536 | case 3: 537 | indirect = regs[DST_REG]; 538 | if (DST_REG == PC) { 539 | lli_word(indirect, addr) 540 | } else { 541 | ll_word(indirect, addr); 542 | } 543 | ea_addr = addr; 544 | ll_word(addr, dstword); 545 | regs[DST_REG] += 2; 546 | return; 547 | case 4: 548 | regs[DST_REG] -= 2; 549 | addr = regs[DST_REG]; 550 | ea_addr = addr; 551 | ll_word(addr, dstword); 552 | return; 553 | case 5: 554 | regs[DST_REG] -= 2; 555 | indirect = regs[DST_REG]; 556 | ll_word(indirect, addr); 557 | ea_addr = addr; 558 | ll_word(addr, dstword); 559 | return; 560 | case 6: 561 | lli_word(regs[PC], indirect); 562 | regs[PC] += 2; 563 | addr = regs[DST_REG] + indirect; 564 | ea_addr = addr; 565 | ll_word(addr, dstword); 566 | return; 567 | case 7: 568 | lli_word(regs[PC], indirect); 569 | regs[PC] += 2; 570 | indirect = regs[DST_REG] + indirect; 571 | ll_word(indirect, addr); 572 | ea_addr = addr; 573 | ll_word(addr, dstword); 574 | return; 575 | } 576 | illegal(); 577 | } 578 | 579 | 580 | INLINE void 581 | store_dst_2(void) 582 | { 583 | if (DST_MODE == 0) { 584 | regs[DST_REG] = dstword; 585 | return; 586 | } 587 | sl_word(ea_addr, dstword); 588 | } 589 | -------------------------------------------------------------------------------- /tools/apout/itab.c: -------------------------------------------------------------------------------- 1 | /* itab.c - Instruction decode table. 2 | * 3 | * $Revision: 2.12 $ 4 | * $Date: 1999/12/27 10:19:40 $ 5 | */ 6 | 7 | #include "defines.h" 8 | 9 | static _itab sitab0[64] = { 10 | halt, waiti, illegal, bpt, iot, illegal, illegal, illegal, 11 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 12 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 13 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 14 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 15 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 16 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 17 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal 18 | }; 19 | 20 | static _itab sitab1[64] = { 21 | rts, rts, rts, rts, rts, rts, rts, rts, 22 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 23 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 24 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 25 | ccc, ccc, ccc, ccc, ccc, ccc, ccc, ccc, 26 | ccc, ccc, ccc, ccc, ccc, ccc, ccc, ccc, 27 | scc, scc, scc, scc, scc, scc, scc, scc, 28 | scc, scc, scc, scc, scc, scc, scc, scc 29 | }; 30 | 31 | void 32 | dositab0(void) 33 | { 34 | sitab0[ir & 077] (); 35 | } 36 | 37 | void 38 | dositab1(void) 39 | { 40 | sitab1[ir & 077] (); 41 | } 42 | 43 | _itab itab[1024] = { 44 | dositab0, jmp, dositab1, swabi, br, br, br, br, 45 | bne, bne, bne, bne, beq, beq, beq, beq, 46 | bge, bge, bge, bge, blt, blt, blt, blt, 47 | bgt, bgt, bgt, bgt, ble, ble, ble, ble, 48 | jsr, jsr, jsr, jsr, jsr, jsr, jsr, jsr, 49 | clr, com, inc, dec, neg, adc, sbc, tst, 50 | ror, rol, asr, asl, mark, mfpi, mtpi, sxt, 51 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 52 | movsreg,movsreg,movsreg,movsreg,movsreg,movsreg,movsreg,movsreg, 53 | movsreg1,movsreg1,movsreg1,movsreg1,movsreg1,movsreg1,movsreg1,movsreg1pc, 54 | mov, mov, mov, mov, mov, mov, mov, mov, 55 | mov, mov, mov, mov, mov, mov, mov, mov, 56 | mov, mov, mov, mov, mov, mov, mov, mov, 57 | mov, mov, mov, mov, mov, mov, mov, mov, 58 | mov, mov, mov, mov, mov, mov, mov, mov, 59 | mov, mov, mov, mov, mov, mov, mov, mov, 60 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 61 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 62 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 63 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 64 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 65 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 66 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 67 | cmp, cmp, cmp, cmp, cmp, cmp, cmp, cmp, 68 | bit, bit, bit, bit, bit, bit, bit, bit, 69 | bit, bit, bit, bit, bit, bit, bit, bit, 70 | bit, bit, bit, bit, bit, bit, bit, bit, 71 | bit, bit, bit, bit, bit, bit, bit, bit, 72 | bit, bit, bit, bit, bit, bit, bit, bit, 73 | bit, bit, bit, bit, bit, bit, bit, bit, 74 | bit, bit, bit, bit, bit, bit, bit, bit, 75 | bit, bit, bit, bit, bit, bit, bit, bit, 76 | bic, bic, bic, bic, bic, bic, bic, bic, 77 | bic, bic, bic, bic, bic, bic, bic, bic, 78 | bic, bic, bic, bic, bic, bic, bic, bic, 79 | bic, bic, bic, bic, bic, bic, bic, bic, 80 | bic, bic, bic, bic, bic, bic, bic, bic, 81 | bic, bic, bic, bic, bic, bic, bic, bic, 82 | bic, bic, bic, bic, bic, bic, bic, bic, 83 | bic, bic, bic, bic, bic, bic, bic, bic, 84 | bis, bis, bis, bis, bis, bis, bis, bis, 85 | bis, bis, bis, bis, bis, bis, bis, bis, 86 | bis, bis, bis, bis, bis, bis, bis, bis, 87 | bis, bis, bis, bis, bis, bis, bis, bis, 88 | bis, bis, bis, bis, bis, bis, bis, bis, 89 | bis, bis, bis, bis, bis, bis, bis, bis, 90 | bis, bis, bis, bis, bis, bis, bis, bis, 91 | bis, bis, bis, bis, bis, bis, bis, bis, 92 | add, add, add, add, add, add, add, add, 93 | add, add, add, add, add, add, add, add, 94 | add, add, add, add, add, add, add, add, 95 | add, add, add, add, add, add, add, add, 96 | add, add, add, add, add, add, add, add, 97 | add, add, add, add, add, add, add, add, 98 | add, add, add, add, add, add, add, add, 99 | add, add, add, add, add, add, add, add, 100 | mul, mul, mul, mul, mul, mul, mul, mul, 101 | divide, divide, divide, divide, divide, divide, divide, divide, 102 | ash, ash, ash, ash, ash, ash, ash, ash, 103 | ashc, ashc, ashc, ashc, ashc, ashc, ashc, ashc, 104 | xor, xor, xor, xor, xor, xor, xor, xor, 105 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 106 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 107 | sob, sob, sob, sob, sob, sob, sob, sob, 108 | bpl, bpl, bpl, bpl, bmi, bmi, bmi, bmi, 109 | bhi, bhi, bhi, bhi, blos, blos, blos, blos, 110 | bvc, bvc, bvc, bvc, bvs, bvs, bvs, bvs, 111 | bcc, bcc, bcc, bcc, bcs, bcs, bcs, bcs, 112 | 113 | /* emt at itab[544] to itab[547] */ 114 | /* trap at itab[548] to itab[551] */ 115 | 116 | emt, emt, emt, emt, trap, trap, trap, trap, 117 | clrb, comb, incb, decb, negb, adcb, sbcb, tstb, 118 | rorb, rolb, asrb, aslb, mtps, mfpd, mtpd, mfps, 119 | illegal, illegal, illegal, illegal, illegal, illegal, illegal, illegal, 120 | movb, movb, movb, movb, movb, movb, movb, movb, 121 | movb, movb, movb, movb, movb, movb, movb, movb, 122 | movb, movb, movb, movb, movb, movb, movb, movb, 123 | movb, movb, movb, movb, movb, movb, movb, movb, 124 | movb, movb, movb, movb, movb, movb, movb, movb, 125 | movb, movb, movb, movb, movb, movb, movb, movb, 126 | movb, movb, movb, movb, movb, movb, movb, movb, 127 | movb, movb, movb, movb, movb, movb, movb, movb, 128 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 129 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 130 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 131 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 132 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 133 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 134 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 135 | cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, cmpb, 136 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 137 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 138 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 139 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 140 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 141 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 142 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 143 | bitb, bitb, bitb, bitb, bitb, bitb, bitb, bitb, 144 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 145 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 146 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 147 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 148 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 149 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 150 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 151 | bicb, bicb, bicb, bicb, bicb, bicb, bicb, bicb, 152 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 153 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 154 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 155 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 156 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 157 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 158 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 159 | bisb, bisb, bisb, bisb, bisb, bisb, bisb, bisb, 160 | sub, sub, sub, sub, sub, sub, sub, sub, 161 | sub, sub, sub, sub, sub, sub, sub, sub, 162 | sub, sub, sub, sub, sub, sub, sub, sub, 163 | sub, sub, sub, sub, sub, sub, sub, sub, 164 | sub, sub, sub, sub, sub, sub, sub, sub, 165 | sub, sub, sub, sub, sub, sub, sub, sub, 166 | sub, sub, sub, sub, sub, sub, sub, sub, 167 | sub, sub, sub, sub, sub, sub, sub, sub, 168 | fpset, ldfps, stfps, stst, clrf, tstf, absf, negf, 169 | mulf, mulf, mulf, mulf, moddf, moddf, moddf, moddf, 170 | addf, addf, addf, addf, ldf, ldf, ldf, ldf, 171 | subf, subf, subf, subf, cmpf, cmpf, cmpf, cmpf, 172 | stf, stf, stf, stf, divf, divf, divf, divf, 173 | stexp, stexp, stexp, stexp, stcfi, stcfi, stcfi, stcfi, 174 | stcdf, stcdf, stcdf, stcdf, ldexpp, ldexpp, ldexpp, ldexpp, 175 | lcdif, lcdif, lcdif, lcdif, ldcdf, ldcdf, ldcdf, ldcdf 176 | }; 177 | -------------------------------------------------------------------------------- /tools/apout/ke11a.c: -------------------------------------------------------------------------------- 1 | /* ke11a.c - this holds the emulation of the PDP 11/20 extended 2 | * arithmetic element. We only need this for 1st Edition a.out support. 3 | * Code kindly borrowed from the eae support written by Tim Shoppa 4 | * (shoppa@trailing-edge.com) for Bob Supnik's PDP-11 emulator. 5 | * 6 | * $Revision: 1.7 $ 7 | * $Date: 1999/12/28 03:57:31 $ 8 | */ 9 | #ifdef EMUV1 10 | #include "defines.h" 11 | #include 12 | 13 | void eae_wr(u_int16_t data, u_int16_t PA, int32_t access); 14 | void set_SR(void); 15 | 16 | /* I/O dispatch routine, I/O addresses 177300 - 177316 */ 17 | 18 | #define eae_DIV 0177300 /* Divide */ 19 | #define eae_AC 0177302 /* Accumulator */ 20 | #define eae_MQ 0177304 /* MQ */ 21 | #define eae_MUL 0177306 /* Multiply */ 22 | #define eae_SC 0177310 /* Step counter */ 23 | #define eae_SR 0177311 /* Status register */ 24 | #define eae_NOR 0177312 /* Normalize */ 25 | #define eae_LSH 0177314 /* Logical shift */ 26 | #define eae_ASH 0177316 /* Arithmetic shift */ 27 | #define WRITEB 1 /* Write of a byte */ 28 | #define WRITEW 2 /* Write of a word */ 29 | 30 | /* The MQ, AC, SC, and SR registers specify the state of the EAE */ 31 | /* Here we define them as int32's, though in real life the MQ and AC */ 32 | /* are 16 bits and the SC and SR are 8 bits */ 33 | 34 | int32_t MQ; /* Multiply quotient */ 35 | int32_t AC; /* Accumulator */ 36 | int32_t SC = 0; /* Shift counter */ 37 | int32_t SR; /* Status register */ 38 | 39 | 40 | /* Load a word from one of the KE11 registers */ 41 | int16_t kell_word(u_int16_t addr) 42 | { 43 | int16_t data; 44 | int pid; 45 | 46 | switch (addr) { 47 | case eae_DIV: 48 | data = 0; break; 49 | case eae_MQ: 50 | data = MQ; break; 51 | case eae_AC: /* high 16 bits of MQ */ 52 | data = AC; break; 53 | case eae_SC: 54 | set_SR(); 55 | data = (SR << 8) | SC; break; 56 | case eae_SR: 57 | set_SR(); 58 | data = (SR << 8); break; 59 | case eae_NOR: 60 | data = SC; break; 61 | case eae_LSH: 62 | case eae_ASH: 63 | case eae_MUL: 64 | data = 0; break; 65 | default: 66 | pid = getpid(); 67 | (void) fprintf(stderr, "Apout - pid %d unknown KE11 register 0%o\n", 68 | pid, addr); 69 | exit(EXIT_FAILURE); 70 | } 71 | return data; 72 | } 73 | 74 | /* Load a byte from one of the KE11 registers */ 75 | int8_t kell_byte(u_int16_t addr) 76 | { 77 | if (addr&1) printf("Hmm, KE11 access on 0%o\n",addr); 78 | return ((int8_t) kell_word(addr)); 79 | } 80 | 81 | /* Save a word to one of the KE11 registers */ 82 | void kesl_word(u_int16_t addr, u_int16_t word) 83 | { 84 | eae_wr(word, addr, WRITEW); 85 | } 86 | 87 | /* Save a byte to one of the KE11 registers */ 88 | void kesl_byte(u_int16_t addr, u_int8_t byte) 89 | { 90 | eae_wr(byte, addr, WRITEB); 91 | } 92 | 93 | void eae_wr(u_int16_t data, u_int16_t PA, int32_t access) 94 | { 95 | int32_t divisor, quotient, remainder; 96 | int32_t dividend, product; 97 | int32_t oldMQ; 98 | int pid; 99 | 100 | switch (PA) { 101 | case eae_DIV: 102 | SC = 0; 103 | dividend = (AC << 16) | MQ; 104 | divisor = data; 105 | if (divisor >> 15) divisor = divisor | ~077777; 106 | quotient = dividend / divisor; 107 | MQ = quotient & 0177777; 108 | remainder = dividend % divisor; 109 | AC = remainder & 0177777; 110 | SR = SR & 076; 111 | if ((quotient > 32767) || (quotient < -32768)) { /* did we overflow? */ 112 | if (dividend < 0) SR = SR | 0100; 113 | else SR = SR | 0200; 114 | } else { 115 | if (quotient < 0) SR = SR | 0300; 116 | } 117 | return; 118 | case eae_AC: 119 | AC = data; 120 | if ((access == WRITEB) & (data >> 7)) 121 | AC = AC | 0177400; 122 | return; 123 | case eae_AC + 1: 124 | printf("write to AC+1; data=%o", data); 125 | AC = (AC & 0377) | (data << 8); 126 | return; 127 | case eae_MQ: 128 | MQ = data; 129 | if ((access == WRITEB) & (data >> 7)) MQ = MQ | 0177400; 130 | if (MQ >> 15) AC = 0177777; 131 | else AC = 0; 132 | return; 133 | case eae_MQ + 1: 134 | printf("write to MQ+1; data=%o", data); 135 | MQ = (MQ & 0377) | (data << 8); 136 | if (MQ >> 15) AC = 0177777; 137 | else AC = 0; 138 | return; 139 | case eae_MUL: 140 | SC = 0; 141 | if (data >> 15) data = data | ~077777; 142 | if (MQ >> 15) MQ = MQ | ~077777; 143 | product = MQ * data; 144 | MQ = product & 0177777; 145 | AC = (product >> 16) & 0177777; 146 | SR = SR & 076; 147 | if (AC >> 15) SR = SR | 0300; /* set sign bit if necessary */ 148 | return; 149 | case eae_SC: 150 | if (access == WRITEB) return; /* byte writes are no-ops */ 151 | SR = (data >> 8) & 0177777; 152 | SC = data & 0000077; 153 | return; 154 | case eae_SR: 155 | return; /* this is a No-op */ 156 | case eae_NOR: /* Normalize */ 157 | MQ = (AC << 16) | MQ; /* 32-bit number to normalize in MQ */ 158 | for (SC = 0; SC < 31; SC++) { 159 | if (MQ == (0140000 << 16)) 160 | break; 161 | if ((((MQ >> 30) & 3) == 1) || (((MQ >> 30) & 3) == 2)) 162 | break; 163 | MQ = MQ << 1; 164 | } 165 | printf("SC = %o\r\n", SC); 166 | AC = (MQ >> 16) & 0177777; 167 | MQ = MQ & 0177777; 168 | return; 169 | case eae_LSH: /* Logical shift */ 170 | MQ=(AC<<16)|MQ; /* Form a temporary 32-bit entity */ 171 | oldMQ=MQ & 0x80000000; /* Save the sign bit for later */ 172 | SR=SR&0176; /* Clear overflow & carry bits */ 173 | data=data & 077; /* Convert data from 6-bit */ 174 | if (data>31) { 175 | data=64-data; /* Shift in a -ve direction */ 176 | SR=SR|((MQ>>(data-1))&1); /* Get the bit that went off the end */ 177 | MQ=MQ>>data; /* and do the right shift */ 178 | } else { /* Else left shift */ 179 | if ((MQ<<(data-1))&0x80000000) SR|=1; /* Get the bit off the end */ 180 | MQ=MQ<>16)&0177777; /* Save result in AC and MQ */ 185 | MQ=MQ&0177777; 186 | set_SR(); 187 | return; 188 | 189 | case eae_ASH: /* Arithmetic shift */ 190 | MQ=(AC<<16)|MQ; /* Form a temporary 32-bit entity */ 191 | oldMQ=MQ & 0x80000000; /* Save the sign bit for later */ 192 | SR=SR&0176; /* Clear overflow & carry bits */ 193 | data=data & 077; /* Convert data from 6-bit */ 194 | if (data>31) { 195 | data=64-data; /* Shift in a -ve direction */ 196 | divisor=1 << data; /* Work out the dividing factor */ 197 | SR=SR|((MQ>>(data-1))&1); /* Get the bit that went off the end */ 198 | MQ=MQ/divisor; /* and do the right shift */ 199 | } else { /* Else left shift */ 200 | product=1 << data; /* Work out the multiplying factor */ 201 | if ((MQ<<(data-1))&0x80000000) SR|=1; /* Get the bit off the end */ 202 | MQ=MQ*product; /* and do the left shift */ 203 | } 204 | oldMQ= oldMQ ^ MQ; /* Any difference in sign bit? */ 205 | if (oldMQ & 0x80000000) SR|=0200;/* Yes, set the overflow bit */ 206 | AC=(MQ>>16)&0177777; /* Save result in AC and MQ */ 207 | MQ=MQ&0177777; 208 | set_SR(); 209 | return; 210 | 211 | default: 212 | pid = getpid(); 213 | (void) fprintf(stderr, "Apout - pid %d unknown KE11 register 0%o\n", 214 | pid, PA); 215 | exit(EXIT_FAILURE); 216 | } 217 | } 218 | 219 | void set_SR(void) 220 | { 221 | SR = SR & 0301; /* clear the result bits we can set here */ 222 | if (((MQ & 0100000) == 0) && (AC == 0)) SR = SR | 002; 223 | if (((MQ & 0100000) == 0100000) && (AC == 0177777)) SR = SR | 002; 224 | 225 | if ((AC == 0) && (MQ == 0)) SR = SR | 0004; 226 | if (MQ == 0) SR = SR | 0010; 227 | if (AC == 0) SR = SR | 0020; 228 | if (AC == 0177777) SR = SR | 0040; 229 | } 230 | #endif /* EMUV1 */ 231 | -------------------------------------------------------------------------------- /tools/apout/magic.c: -------------------------------------------------------------------------------- 1 | /* magic.c - determine the environment for certain PDP-11 a.out binaries 2 | * 3 | * Some binaries in V1, V2, V5, V6, V7 and 2.11BSD are not caught with the 4 | * magic numbers in aout.c. If this is the case, we fall into the 5 | * special_magic() function, which calculates a checksum on the 6 | * a.out header. If it matches any of the checksums below, it returns 7 | * the appropriate environment value. Otherwise, it returns IS_UNKNOWN. 8 | * 9 | * $Revision: 1.15 $ 10 | * $Date: 2008/05/15 03:20:52 $ 11 | */ 12 | #include "defines.h" 13 | 14 | struct spec_aout { 15 | u_int32_t cksum; 16 | int environment; 17 | }; 18 | 19 | static struct spec_aout S[]= { 20 | { 0x1042c2, IS_V6 }, /* V6 bin/dc */ 21 | { 0x10f02, IS_V5 }, /* V5 etc/update */ 22 | { 0x11002, IS_V5 }, /* V5 bin/clri */ 23 | { 0x1117c2, IS_V7 }, /* V7 bin/roff */ 24 | { 0x11702, IS_V6 }, /* V6 etc/update */ 25 | { 0x11a82, IS_V5 }, /* V5 bin/sum */ 26 | { 0x1319c2, IS_V5 }, /* V5 usr/fort/fc1 */ 27 | { 0x1332c2, IS_V2 }, /* /lib/c0 dated Jun 30 1973 from s2 tape */ 28 | { 0x13642, IS_V5 }, /* V5 bin/rew */ 29 | { 0x139e02, IS_V5 }, /* V5 bin/dc */ 30 | { 0x13c0, IS_V6 }, /* V6 usr/lib/tmgc */ 31 | { 0x14042, IS_V6 }, /* V6 bin/tty */ 32 | { 0x143c2, IS_V5 }, /* V5 bin/tty */ 33 | { 0x152ac2, IS_V6 }, /* V6 usr/lib/tmg */ 34 | { 0x15f42, IS_V5 }, /* V5 bin/kill */ 35 | { 0x16802, IS_V5 }, /* V5 bin/dsw */ 36 | { 0x16902, IS_V5 }, /* V5 bin/mkdir */ 37 | { 0x1720c2, IS_V6 }, /* V6 bin/cdb */ 38 | { 0x17742, IS_V5 }, /* V5 usr/bin/pfe */ 39 | { 0x17cc2, IS_V5 }, /* V5 usr/bin/mesg */ 40 | { 0x18702, IS_V5 }, /* V5 bin/rmdir */ 41 | { 0x194c2, IS_V6 }, /* V6 bin/chgrp */ 42 | { 0x197c2, IS_V6 }, /* V6 bin/chown */ 43 | { 0x19a42, IS_V5 }, /* V5 bin/chown */ 44 | { 0x19b342, IS_V6 }, /* V6 usr/bin/nroff */ 45 | { 0x19f682, IS_V6 }, /* V6 usr/fort/fc1 */ 46 | { 0x1ae00, IS_V2 }, /* V2 bin/strip */ 47 | { 0x1b102, IS_V5 }, /* V5 bin/strip */ 48 | { 0x1ba02, IS_V6 }, /* V6 bin/strip */ 49 | { 0x1c342, IS_V5 }, /* V5 bin/cat */ 50 | { 0x1c8442, IS_V7 }, /* V7 usr/games/maze */ 51 | { 0x1cc782, IS_V6 }, /* V6 lib/fc0 */ 52 | { 0x1dfc2, IS_V5 }, /* V5 etc/getty */ 53 | { 0x1f9c2, IS_V2 }, /* /bin/nm dated Jun 30 1973 from s2 tape */ 54 | { 0x20202, IS_V5 }, /* V5 usr/games/bj */ 55 | { 0x21e42, IS_V6 }, /* V6 usr/bin/units */ 56 | { 0x23f82, IS_V5 }, /* V5 usr/bin/passwd */ 57 | { 0x260642, IS_V6 }, /* V6 lib/fc1 */ 58 | { 0x262a82, IS_211BSD }, /* 2.11 usr/new/m11 */ 59 | { 0x27e82, IS_V5 }, /* V5 usr/bin/grep */ 60 | { 0x290c2, IS_V7 }, /* V7 usr/games/cubic */ 61 | { 0x299c2, IS_V5 }, /* V5 usr/games/cubic */ 62 | { 0x2f482, IS_V5 }, /* V5 usr/bin/form */ 63 | { 0x3382, IS_V6 }, /* V6 bin/write */ 64 | { 0x326642, IS_V7 }, /* 2.9 awk */ 65 | { 0x33c42, IS_211BSD }, /* 2.11 usr/games/moo */ 66 | { 0x351382, IS_211BSD }, /* 2.11 usr/games/lib/zork */ 67 | { 0x3702, IS_V5 }, /* V5 usr/games/moo */ 68 | { 0x3b402, IS_V5 }, /* V5 bin/ar */ 69 | { 0x3cc02, IS_V2 }, /* /bin/size from from s2 tape */ 70 | { 0x4382, IS_V5 }, /* V5 bin/write */ 71 | { 0x451f42, IS_V7 }, /* 2.9 /lib/c1 */ 72 | { 0x47042, IS_211BSD }, /* 2.11 usr/games/ttt */ 73 | { 0x4fa02, IS_V5 }, /* V5 bin/ld */ 74 | { 0x51342, IS_211BSD }, /* 2.11 usr/games/bj */ 75 | { 0x53302, IS_V6 }, /* V6 usr/lib/suftab */ 76 | { 0x55882, IS_V7 }, /* 2.9 /bin/as */ 77 | { 0x54702, IS_V5 }, /* V5 usr/games/ttt */ 78 | { 0x55702, IS_V7 }, /* V7 bin/as */ 79 | { 0x5c342, IS_V2 }, /* /bin/cc dated Jun 30 1973 from s2 tape */ 80 | { 0x6f742, IS_V6 }, /* V6 usr/bin/sa */ 81 | { 0x7042, IS_V7 }, /* V7 bin/factor */ 82 | { 0x71702, IS_V7 }, /* V7 lib/as2 */ 83 | { 0x7342, IS_V5 }, /* V5 bin/du */ 84 | { 0x73782, IS_V7}, /* 2.9 /lib/as2 */ 85 | { 0x73e00, IS_V2 }, /* /bin/ld from s2 tape */ 86 | { 0x7a242, IS_V6 }, /* V6 lib/as2 */ 87 | { 0x7b102, IS_V6 }, /* V6 bin/as */ 88 | { 0x7d082, IS_V5 }, /* V5 bin/as */ 89 | { 0x7d6844, IS_V1 }, /* bin/cal from s2 tape */ 90 | { 0x7d942, IS_V5 }, /* V5 lib/as2 */ 91 | { 0x8002, IS_V5 }, /* V5 etc/lpd */ 92 | { 0x85842, IS_V5 }, /* V5 bin/ed */ 93 | { 0x8f00, IS_V6 }, /* V6 usr/lib/tmga */ 94 | { 0x915c2, IS_V6 }, /* V6 bin/bas */ 95 | { 0x94542, IS_V5 }, /* V5 bin/db */ 96 | { 0x98442, IS_V6 }, /* V6 usr/bin/ac */ 97 | { 0x9adc2, IS_V6 }, /* V6 bin/db */ 98 | { 0xa242, IS_V7 }, /* V7 bin/primes */ 99 | { 0xa4602, IS_V2 }, /* /bin/as from s2 tape */ 100 | { 0xa702, IS_V5 }, /* V5 bin/time */ 101 | { 0xad882, IS_V7 }, /* V7 bin/bas */ 102 | { 0xadc42, IS_V2 }, /* /usr/lib/c1 from s2 tape */ 103 | { 0xb5a82, IS_V6 }, /* V6 usr/bin/prof */ 104 | { 0xc1e42, IS_V5 }, /* V5 usr/bin/fed */ 105 | { 0xc3102, IS_V6 }, /* V6 bin/tp */ 106 | { 0xc8bc2, IS_V5 }, /* V5 bin/tp */ 107 | { 0xe1642, IS_V6 }, /* V6 usr/bin/roff */ 108 | { 0xe1f42, IS_V5 }, /* V5 usr/bin/roff */ 109 | { 0xec582, IS_V5 }, /* V5 bin/bas */ 110 | { 0xfc2, IS_V6 }, /* V6 usr/bin/typo */ 111 | { 0xfc002, IS_V2 }, /* /bin/as dated Jun 30 1973 from s2 tape */ 112 | { 0x38ec0, IS_V5 }, /* V5 bin/ar, Warrens */ 113 | { 0, 0 } 114 | }; 115 | 116 | /* cptr points at the start of the a.out header */ 117 | int special_magic(u_int16_t *cptr) 118 | { 119 | u_int32_t cksum=0; 120 | int i; 121 | char *unix_version; 122 | 123 | if (cptr==NULL) return(IS_UNKNOWN); 124 | /* Calculate the checksum */ 125 | for (i=0;i<8; i++) { cksum ^= cptr[i]; cksum = cksum<<1; } 126 | 127 | /* Try and find a match */ 128 | for (i=0; S[i].cksum!=0; i++) if (S[i].cksum==cksum) { 129 | TrapDebug((dbg_file, "This a.out has special magic %d\n",i)); 130 | return(S[i].environment); 131 | } 132 | 133 | /* See if user tells us what version to use */ 134 | if ((unix_version = getenv("APOUT_UNIX_VERSION"))) { 135 | if (!strcmp(unix_version, "V1")) return(IS_V1); 136 | if (!strcmp(unix_version, "V2")) return(IS_V2); 137 | if (!strcmp(unix_version, "V3")) return(IS_V3); 138 | if (!strcmp(unix_version, "V4")) return(IS_V4); 139 | if (!strcmp(unix_version, "V5")) return(IS_V5); 140 | if (!strcmp(unix_version, "V6")) return(IS_V6); 141 | if (!strcmp(unix_version, "V7")) return(IS_V7); 142 | if (!strcmp(unix_version, "2.9BSD")) return(IS_29BSD); 143 | if (!strcmp(unix_version, "2.11BSD")) return(IS_211BSD); 144 | } 145 | 146 | /* We can't tell what version of Unix, give up */ 147 | (void)printf("Apout - unknown magic in header: 0x%x\n",cksum); 148 | return(IS_UNKNOWN); 149 | } 150 | -------------------------------------------------------------------------------- /tools/apout/main.c: -------------------------------------------------------------------------------- 1 | /* Startup for apout. Parse arguments, load the binary, and run it. 2 | * 3 | * $Revision: 1.22 $ 4 | * $Date: 2002/06/10 11:44:21 $ 5 | */ 6 | #include 7 | #include "defines.h" 8 | 9 | /* The following array holds the FILE pointers that correspond to open file 10 | * descriptors. Only fds which are not ttys have FILE * pointers 11 | */ 12 | FILE *stream[NFILE]; 13 | char *streammode[NFILE]; /* Mode for each file - used for dup */ 14 | 15 | /* The following two buffers are used as */ 16 | /* part of the translation from virtal */ 17 | /* absolute filenames to native ones. We */ 18 | /* only have 2 buffers, so if you call */ 19 | /* xlate_filename() 3 times, the 1st return */ 20 | /* value will be destroyed. */ 21 | static char realfilename[2][2 * MAXPATHLEN]; 22 | static char *rfn[2]; 23 | static int whichrfn=0; 24 | char *apout_root=NULL; /* Root dir for simulated a.out */ 25 | 26 | #ifdef DEBUG 27 | /* Debugging flags */ 28 | int inst_debug= 0, /* Print a line before each instruction */ 29 | trap_debug= 0, /* Print details of each trap */ 30 | jsr_debug= 0, /* Print out each jsr */ 31 | fp_debug= 0; /* Print out each floating-point instruction */ 32 | FILE *dbg_file = NULL; /* Debugging output file */ 33 | char *progname = NULL; /* The program's name - used in debugging */ 34 | #endif 35 | 36 | void usage() 37 | { 38 | fprintf(stderr, "Usage: apout"); 39 | #ifdef DEBUG 40 | fprintf(stderr, " [-inst] [-trap] [-jsr] [-fp]"); 41 | #endif 42 | fprintf(stderr, " pdp11_binary\n"); 43 | exit(1); 44 | } 45 | 46 | int 47 | main(int argc, char **argv) 48 | { 49 | int i; 50 | 51 | /* Ensure, before we start, that certain types are right */ 52 | assert(sizeof(int8_t)==1); assert(sizeof(u_int8_t)==1); 53 | assert(sizeof(int16_t)==2); assert(sizeof(u_int16_t)==2); 54 | assert(sizeof(int32_t)==4); assert(sizeof(u_int32_t)==4); 55 | 56 | if (argc < 2) usage(); 57 | if (!strcmp(argv[1], "-help")) usage(); 58 | if (!strcmp(argv[1], "--help")) usage(); 59 | 60 | #ifdef DEBUG 61 | while (1) { 62 | if (!strcmp(argv[1], "-inst")) 63 | { inst_debug = 1; argc--; argv++; continue; } 64 | if (!strcmp(argv[1], "-trap")) 65 | { trap_debug = 1; argc--; argv++; continue; } 66 | if (!strcmp(argv[1], "-jsr")) 67 | { jsr_debug = 1; argc--; argv++; continue; } 68 | if (!strcmp(argv[1], "-fp")) 69 | { fp_debug = 1; argc--; argv++; continue; } 70 | break; 71 | } 72 | if (inst_debug|trap_debug|jsr_debug|fp_debug) 73 | dbg_file = fopen("apout.dbg", "w"); 74 | #endif 75 | 76 | /* Prepare arg list for emulated environment */ 77 | argc--; argv++; 78 | Argc= argc; Envp[0]=NULL; 79 | for (i=0; i2 calls earlier. 113 | */ 114 | char * xlate_filename(char *name) 115 | { 116 | int i=whichrfn; 117 | 118 | if (name == NULL) return (NULL); 119 | if (name[0] == '\0') return("."); /* Undocumented, but used in V7 */ 120 | if (name[0] != '/') return (name); /* Relative, keep it relative */ 121 | strcpy(rfn[i], name); /* Copy name into buffer */ 122 | whichrfn= 1 - whichrfn; /* Switch to other buffer next time */ 123 | return (realfilename[i]); 124 | } 125 | 126 | void set_apout_root(char *dirname) 127 | { 128 | strcpy(realfilename[0], dirname); 129 | strcpy(realfilename[1], dirname); 130 | rfn[0] = realfilename[0]; rfn[0] += strlen(realfilename[0]); 131 | rfn[1] = realfilename[1]; rfn[1] += strlen(realfilename[1]); 132 | } 133 | -------------------------------------------------------------------------------- /tools/apout/single.c: -------------------------------------------------------------------------------- 1 | /* single.c - Single operand instructions. 2 | * 3 | * $Revision: 2.10 $ 4 | * $Date: 1999/01/05 23:46:04 $ 5 | */ 6 | #include "defines.h" 7 | 8 | /* adc() - Add Carry Instruction. */ 9 | void 10 | adc() 11 | { 12 | load_dst(); 13 | 14 | if (CC_C) { /* do if carry is set */ 15 | if (dstword == MPI) 16 | SET_CC_V(); 17 | else 18 | CLR_CC_V(); 19 | if (dstword == NEG_1) 20 | SET_CC_C(); 21 | else 22 | CLR_CC_C(); 23 | dstword++; /* add the carry */ 24 | } else { 25 | CLR_CC_V(); 26 | CLR_CC_C(); 27 | } 28 | 29 | CHG_CC_N(dstword); 30 | CHG_CC_Z(dstword); 31 | 32 | store_dst_2(); 33 | } 34 | 35 | 36 | /* asl() - Arithmetic Shift Left Instruction. */ 37 | void 38 | asl() 39 | { 40 | load_dst(); 41 | 42 | if (dstword & SIGN) 43 | SET_CC_C(); 44 | else 45 | CLR_CC_C(); 46 | 47 | dstword <<= 1; 48 | 49 | CHG_CC_N(dstword); 50 | CHG_CC_Z(dstword); 51 | CHG_CC_V_XOR_C_N(); 52 | 53 | store_dst_2(); 54 | } 55 | 56 | /* asr() - Arithmetic Shift Right Instruction. */ 57 | void 58 | asr() 59 | { 60 | load_dst(); 61 | 62 | if (dstword & LSBIT) 63 | SET_CC_C(); 64 | else 65 | CLR_CC_C(); 66 | 67 | dstword = (dstword >> 1) + (dstword & SIGN); /* shift and replicate */ 68 | 69 | CHG_CC_N(dstword); 70 | CHG_CC_Z(dstword); 71 | 72 | CHG_CC_V_XOR_C_N(); 73 | 74 | store_dst_2(); 75 | } 76 | 77 | /* clr() - Clear Instruction. */ 78 | void 79 | clr() 80 | { 81 | CLR_CC_ALL(); SET_CC_Z(); 82 | dstword=0; store_dst(); 83 | } 84 | 85 | /* com() - Complement Instruction. */ 86 | void 87 | com() 88 | { 89 | load_dst(); 90 | 91 | dstword = ~dstword; 92 | 93 | CHG_CC_N(dstword); 94 | CHG_CC_Z(dstword); 95 | CLR_CC_V(); 96 | SET_CC_C(); 97 | 98 | store_dst_2(); 99 | } 100 | 101 | /* dec() - Decrement Instruction. */ 102 | void 103 | dec() 104 | { 105 | load_dst(); 106 | 107 | if (dstword == MNI) 108 | SET_CC_V(); 109 | else 110 | CLR_CC_V(); 111 | 112 | --dstword; 113 | 114 | CHG_CC_N(dstword); 115 | CHG_CC_Z(dstword); 116 | 117 | store_dst_2(); 118 | } 119 | 120 | /* inc() - Increment Instruction. */ 121 | void 122 | inc() 123 | { 124 | load_dst(); 125 | 126 | if (dstword == MPI) 127 | SET_CC_V(); 128 | else 129 | CLR_CC_V(); 130 | 131 | ++dstword; 132 | 133 | CHG_CC_N(dstword); 134 | CHG_CC_Z(dstword); 135 | 136 | store_dst_2(); 137 | } 138 | 139 | /* neg() - Negate Instruction. */ 140 | 141 | void 142 | neg() 143 | { 144 | load_dst(); 145 | 146 | dstword = (NEG_1 - dstword) + 1; 147 | 148 | CHG_CC_N(dstword); 149 | CHG_CC_Z(dstword); 150 | 151 | if (dstword == MNI) 152 | SET_CC_V(); 153 | else 154 | CLR_CC_V(); 155 | 156 | if (dstword == 0) 157 | CLR_CC_C(); 158 | else 159 | SET_CC_C(); 160 | 161 | store_dst_2(); 162 | } 163 | 164 | /* rol() - Rotate Left Instruction. */ 165 | void 166 | rol() 167 | { 168 | load_dst(); 169 | 170 | tmpword = dstword & SIGN; /* get sign bit */ 171 | dstword <<= 1; /* shift */ 172 | 173 | if (CC_C) /* roll in carry */ 174 | dstword += LSBIT; 175 | 176 | if (tmpword) /* roll out to carry */ 177 | SET_CC_C(); 178 | else 179 | CLR_CC_C(); 180 | 181 | CHG_CC_N(dstword); 182 | CHG_CC_Z(dstword); 183 | CHG_CC_V_XOR_C_N(); 184 | 185 | store_dst_2(); 186 | } 187 | 188 | 189 | /* ror() - Rotate Right Instruction. */ 190 | void 191 | ror() 192 | { 193 | load_dst(); 194 | 195 | tmpword = dstword & LSBIT; /* get low bit */ 196 | dstword >>= 1; /* shift */ 197 | 198 | if (CC_C) /* roll in carry */ 199 | dstword += SIGN; 200 | 201 | if (tmpword) /* roll out to carry */ 202 | SET_CC_C(); 203 | else 204 | CLR_CC_C(); 205 | 206 | CHG_CC_N(dstword); 207 | CHG_CC_Z(dstword); 208 | CHG_CC_V_XOR_C_N(); 209 | 210 | store_dst_2(); 211 | } 212 | 213 | /* sbc() - Subtract Carry Instruction. */ 214 | void 215 | sbc() 216 | { 217 | load_dst(); 218 | 219 | if (dstword == MNI) 220 | SET_CC_V(); 221 | else 222 | CLR_CC_V(); 223 | 224 | if (CC_C) { /* do if carry is set */ 225 | if (dstword) 226 | CLR_CC_C(); 227 | else 228 | SET_CC_C(); 229 | --dstword; /* subtract carry */ 230 | } else { 231 | CLR_CC_C(); 232 | } 233 | 234 | CHG_CC_N(dstword); 235 | CHG_CC_Z(dstword); 236 | 237 | store_dst_2(); 238 | } 239 | 240 | /* swabi() - Swap Bytes Instruction. */ 241 | void 242 | swabi() 243 | { 244 | u_int16_t data2; 245 | u_int16_t data3; 246 | 247 | load_dst(); 248 | 249 | data2 = (dstword << 8) & 0xff00; 250 | data3 = (dstword >> 8) & 0x00ff; 251 | dstword = data2 + data3; 252 | 253 | CLR_CC_ALL(); 254 | CHGB_CC_N(data3); /* cool, negative and zero */ 255 | CHGB_CC_Z(data3); /* checks done on low byte only */ 256 | 257 | store_dst_2(); 258 | } 259 | 260 | /* sxt() - Sign Extend Instruction. */ 261 | void 262 | sxt() 263 | { 264 | if (CC_N) { 265 | dstword = NEG_1; 266 | CLR_CC_Z(); 267 | } else { 268 | dstword = 0; 269 | SET_CC_Z(); 270 | } 271 | CLR_CC_V(); 272 | 273 | store_dst(); 274 | } 275 | 276 | /* tst() - Test Instruction. */ 277 | void 278 | tst() 279 | { 280 | load_dst(); 281 | 282 | CLR_CC_ALL(); 283 | CHG_CC_N(dstword); 284 | CHG_CC_Z(dstword); 285 | } 286 | 287 | /* tstb() - Test Byte Instruction. */ 288 | void 289 | tstb() 290 | { 291 | loadb_dst(); 292 | 293 | CHGB_CC_N(dstbyte); 294 | CHGB_CC_Z(dstbyte); 295 | CLR_CC_V(); 296 | CLR_CC_C(); 297 | 298 | } 299 | 300 | /* aslb() - Arithmetic Shift Left Byte Instruction. */ 301 | void 302 | aslb() 303 | { 304 | loadb_dst(); 305 | 306 | if (dstbyte & SIGN_B) 307 | SET_CC_C(); 308 | else 309 | CLR_CC_C(); 310 | 311 | dstbyte <<= 1; 312 | 313 | CHGB_CC_N(dstbyte); 314 | CHGB_CC_Z(dstbyte); 315 | CHG_CC_V_XOR_C_N(); 316 | 317 | storeb_dst_2(); 318 | } 319 | 320 | /* asrb() - Arithmetic Shift Right Byte Instruction. */ 321 | void 322 | asrb() 323 | { 324 | loadb_dst(); 325 | 326 | if (dstbyte & LSBIT) 327 | SET_CC_C(); 328 | else 329 | CLR_CC_C(); 330 | 331 | dstbyte = (dstbyte >> 1) + (dstbyte & SIGN_B); /* shift and replicate */ 332 | 333 | CHGB_CC_N(dstbyte); 334 | CHGB_CC_Z(dstbyte); 335 | CHG_CC_V_XOR_C_N(); 336 | 337 | storeb_dst_2(); 338 | } 339 | 340 | /* clrb() - Clear Byte Instruction. */ 341 | void 342 | clrb() 343 | { 344 | CLR_CC_ALL(); SET_CC_Z(); 345 | srcbyte=0; storeb_dst(); 346 | } 347 | 348 | 349 | /* comb() - Complement Byte Instruction. */ 350 | void 351 | comb() 352 | { 353 | loadb_dst(); 354 | 355 | dstbyte = ~dstbyte; 356 | 357 | CHGB_CC_N(dstbyte); 358 | CHGB_CC_Z(dstbyte); 359 | CLR_CC_V(); 360 | SET_CC_C(); 361 | 362 | storeb_dst_2(); 363 | } 364 | 365 | /* decb() - Decrement Byte Instruction. */ 366 | void 367 | decb() 368 | { 369 | loadb_dst(); 370 | 371 | if (dstbyte == MNI_B) 372 | SET_CC_V(); 373 | else 374 | CLR_CC_V(); 375 | 376 | --dstbyte; 377 | 378 | CHGB_CC_N(dstbyte); 379 | CHGB_CC_Z(dstbyte); 380 | 381 | storeb_dst_2(); 382 | } 383 | 384 | /* incb() - Increment Byte Instruction. */ 385 | void 386 | incb() 387 | { 388 | loadb_dst(); 389 | 390 | if (dstbyte == MPI_B) 391 | SET_CC_V(); 392 | else 393 | CLR_CC_V(); 394 | 395 | ++dstbyte; 396 | 397 | CHGB_CC_N(dstbyte); 398 | CHGB_CC_Z(dstbyte); 399 | 400 | storeb_dst_2(); 401 | } 402 | 403 | /* negb() - Negate Byte Instruction. */ 404 | void 405 | negb() 406 | { 407 | loadb_dst(); 408 | 409 | dstbyte = (NEG_1_B - dstbyte) + 1;/* hope this is right */ 410 | 411 | CHGB_CC_N(dstbyte); 412 | CHGB_CC_Z(dstbyte); 413 | 414 | if (dstbyte == MNI_B) 415 | SET_CC_V(); 416 | else 417 | CLR_CC_V(); 418 | 419 | if (dstbyte) 420 | SET_CC_C(); 421 | else 422 | CLR_CC_C(); 423 | 424 | storeb_dst_2(); 425 | } 426 | 427 | /* rolb() - Rotate Left Byte Instruction. */ 428 | void 429 | rolb() 430 | { 431 | loadb_dst(); 432 | 433 | tmpbyte = dstbyte & SIGN_B; /* get top bit */ 434 | dstbyte <<= 1; /* shift */ 435 | 436 | if (CC_C) /* roll in carry */ 437 | dstbyte = dstbyte + LSBIT; 438 | 439 | if (tmpbyte) /* roll out to carry */ 440 | SET_CC_C(); 441 | else 442 | CLR_CC_C(); 443 | 444 | CHGB_CC_N(dstbyte); 445 | CHGB_CC_Z(dstbyte); 446 | CHG_CC_V_XOR_C_N(); 447 | 448 | storeb_dst_2(); 449 | } 450 | 451 | /* rorb() - Rotate Right Byte Instruction. */ 452 | void 453 | rorb() 454 | { 455 | loadb_dst(); 456 | 457 | tmpbyte = dstbyte & LSBIT; /* get low bit */ 458 | dstbyte >>= 1; /* shift */ 459 | 460 | if (CC_C) /* roll in carry */ 461 | dstbyte += SIGN_B; 462 | 463 | if (tmpbyte) /* roll out to carry */ 464 | SET_CC_C(); 465 | else 466 | CLR_CC_C(); 467 | 468 | CHGB_CC_N(dstbyte); 469 | CHGB_CC_Z(dstbyte); 470 | CHG_CC_V_XOR_C_N(); 471 | 472 | storeb_dst_2(); 473 | } 474 | 475 | /* adcb() - Add Carry Byte Instruction. */ 476 | void 477 | adcb() 478 | { 479 | loadb_dst(); 480 | 481 | if (CC_C) { /* do if carry is set */ 482 | if (dstbyte == MPI_B) 483 | SET_CC_V(); 484 | else 485 | CLR_CC_V(); 486 | if (dstbyte == NEG_1_B) 487 | SET_CC_C(); 488 | else 489 | CLR_CC_C(); 490 | ++dstbyte; /* add the carry */ 491 | } else { 492 | CLR_CC_V(); 493 | CLR_CC_C(); 494 | } 495 | 496 | CHGB_CC_N(dstbyte); 497 | CHGB_CC_Z(dstbyte); 498 | 499 | storeb_dst_2(); 500 | } 501 | 502 | /* sbcb() - Subtract Carry Byte Instruction. */ 503 | void 504 | sbcb() 505 | { 506 | loadb_dst(); 507 | 508 | if (CC_C) { /* do if carry is set */ 509 | if (dstbyte) 510 | CLR_CC_C(); 511 | else 512 | SET_CC_C(); 513 | 514 | --dstbyte; /* subtract carry */ 515 | } else { 516 | CLR_CC_C(); 517 | } 518 | 519 | if (dstbyte == MNI_B) 520 | SET_CC_V(); 521 | else 522 | CLR_CC_V(); 523 | 524 | CHGB_CC_N(dstbyte); 525 | CHGB_CC_Z(dstbyte); 526 | 527 | storeb_dst_2(); 528 | } 529 | -------------------------------------------------------------------------------- /tools/apout/v1trap.h: -------------------------------------------------------------------------------- 1 | /* v1trap.h - Deal with 1st Edition trap instructions. 2 | * 3 | * $Revision: 1.1 $ 4 | * $Date: 1999/12/26 08:16:33 $ 5 | */ 6 | 7 | /* In this file, we list the trap number for each system call, 8 | * and the structures associated with several of the systems 9 | * calls in 1st Edition UNIX 10 | */ 11 | 12 | #define V1_RELE 0 13 | #define V1_EXIT 1 14 | #define V1_FORK 2 15 | #define V1_READ 3 16 | #define V1_WRITE 4 17 | #define V1_OPEN 5 18 | #define V1_CLOSE 6 19 | #define V1_WAIT 7 20 | #define V1_CREAT 8 21 | #define V1_LINK 9 22 | #define V1_UNLINK 10 23 | #define V1_EXEC 11 24 | #define V1_CHDIR 12 25 | #define V1_TIME 13 26 | #define V1_MKDIR 14 27 | #define V1_CHMOD 15 28 | #define V1_CHOWN 16 29 | #define V1_BREAK 17 30 | #define V1_STAT 18 31 | #define V1_SEEK 19 32 | #define V1_TELL 20 33 | #define V1_MOUNT 21 34 | #define V1_UMOUNT 22 35 | #define V1_SETUID 23 36 | #define V1_GETUID 24 37 | #define V1_STIME 25 38 | #define V1_QUIT 26 39 | #define V1_INTR 27 40 | #define V1_FSTAT 28 41 | #define V1_CEMT 29 42 | #define V1_SMDATE 30 43 | #define V1_STTY 31 44 | #define V1_GTTY 32 45 | #define V1_ILGINS 33 46 | 47 | 48 | char *v1trap_name[]= { 49 | "rele", 50 | "exit", 51 | "fork", 52 | "read", 53 | "write", 54 | "open", 55 | "close", 56 | "wait", 57 | "creat", 58 | "link", 59 | "unlink", 60 | "exec", 61 | "chdir", 62 | "time", 63 | "mkdir", 64 | "chmod", 65 | "chown", 66 | "break", 67 | "stat", 68 | "seek", 69 | "tell", 70 | "mount", 71 | "umount", 72 | "setuid", 73 | "getuid", 74 | "stime", 75 | "quit", 76 | "intr", 77 | "fstat", 78 | "cemt", 79 | "smdate", 80 | "stty", 81 | "gtty", 82 | "ilgins" 83 | }; 84 | 85 | 86 | struct tr_v1stat { 87 | u_int16_t inum; 88 | u_int16_t iflags; /* Mode */ 89 | u_int8_t inl; /* Links */ 90 | u_int8_t iuid; 91 | u_int16_t isize; 92 | int16_t iaddr[8]; /* Not used, I hope! */ 93 | u_int32_t ctime; 94 | u_int32_t mtime; 95 | u_int16_t unused; 96 | }; 97 | 98 | /* Values for v1stat iflags */ 99 | #define V1_ST_USED 0100000 100 | #define V1_ST_ISDIR 0040000 101 | #define V1_ST_MODIFIED 0020000 102 | #define V1_ST_LARGE 0010000 103 | #define V1_ST_SETUID 0000040 104 | #define V1_ST_EXEC 0000020 105 | #define V1_ST_OWNREAD 0000010 106 | #define V1_ST_OWNWRITE 0000004 107 | #define V1_ST_WRLDREAD 0000002 108 | #define V1_ST_WRLDWRITE 0000001 109 | 110 | /* A union which will point at the trap args, so that 111 | * we can get at the various args of different types 112 | */ 113 | typedef union { 114 | int16_t sarg[4]; /* Signed 16-bit args */ 115 | u_int16_t uarg[4]; /* Unsigned 16-bit args */ 116 | } arglist; 117 | 118 | #define sarg1 V1A.sarg[0] 119 | #define sarg2 V1A.sarg[1] 120 | #define sarg3 V1A.sarg[2] 121 | #define sarg4 V1A.sarg[3] 122 | #define uarg1 V1A.uarg[0] 123 | #define uarg2 V1A.uarg[1] 124 | #define uarg3 V1A.uarg[2] 125 | #define uarg4 V1A.uarg[3] 126 | -------------------------------------------------------------------------------- /tools/apout/v7trap.h: -------------------------------------------------------------------------------- 1 | /* v7trap.h - Deal with V7 trap instructions. Also do V5 and V6 syscalls. 2 | * 3 | * $Revision: 2.17 $ 4 | * $Date: 1999/12/26 08:16:33 $ 5 | */ 6 | 7 | /* In this file, we list the trap number for each system call, 8 | * and the structures associated with several of the systems 9 | * calls in 7th Edition UNIX 10 | */ 11 | 12 | #define S_INDIR 0 13 | #define S_EXIT 1 14 | #define S_FORK 2 15 | #define S_READ 3 16 | #define S_WRITE 4 17 | #define S_OPEN 5 18 | #define S_CLOSE 6 19 | #define S_WAIT 7 20 | #define S_CREAT 8 21 | #define S_LINK 9 22 | #define S_UNLINK 10 23 | #define S_EXEC 11 24 | #define S_CHDIR 12 25 | #define S_TIME 13 26 | #define S_MKNOD 14 27 | #define S_CHMOD 15 28 | #define S_CHOWN 16 29 | #define S_BREAK 17 30 | #define S_STAT 18 31 | #define S_LSEEK 19 32 | #define S_GETPID 20 33 | #define S_MOUNT 21 34 | #define S_UMOUNT 22 35 | #define S_SETUID 23 36 | #define S_GETUID 24 37 | #define S_STIME 25 38 | #define S_PTRACE 26 39 | #define S_ALARM 27 40 | #define S_FSTAT 28 41 | #define S_PAUSE 29 42 | #define S_UTIME 30 43 | #define S_STTY 31 44 | #define S_GTTY 32 45 | #define S_ACCESS 33 46 | #define S_NICE 34 47 | #define S_FTIME 35 48 | #define S_SYNC 36 49 | #define S_KILL 37 50 | #define S_DUP 41 51 | #define S_PIPE 42 52 | #define S_TIMES 43 53 | #define S_PROF 44 54 | #define S_SETGID 46 55 | #define S_GETGID 47 56 | #define S_SIGNAL 48 57 | #define S_ACCT 51 58 | #define S_PHYS 52 59 | #define S_LOCK 53 60 | #define S_IOCTL 54 61 | #define S_EXECE 59 62 | #define S_UMASK 60 63 | #define S_CHROOT 61 64 | 65 | 66 | char *v7trap_name[]= { 67 | "indir", 68 | "exit", 69 | "fork", 70 | "read", 71 | "write", 72 | "open", 73 | "close", 74 | "wait", 75 | "creat", 76 | "link", 77 | "unlink", 78 | "exec", 79 | "chdir", 80 | "time", 81 | "mknod", 82 | "chmod", 83 | "chown", 84 | "break", 85 | "stat", 86 | "lseek", 87 | "getpid", 88 | "mount", 89 | "umount", 90 | "setuid", 91 | "getuid", 92 | "stime", 93 | "ptrace", 94 | "alarm", 95 | "fstat", 96 | "pause", 97 | "utime", 98 | "stty", 99 | "gtty", 100 | "access", 101 | "nice", 102 | "ftime", 103 | "sync", 104 | "kill", 105 | "unknown", 106 | "unknown", 107 | "unknown", 108 | "dup", 109 | "pipe", 110 | "times", 111 | "prof", 112 | "unknown", 113 | "setgid", 114 | "getgid", 115 | "signal", 116 | "unknown", 117 | "unknown", 118 | "acct", 119 | "phys", 120 | "lock", 121 | "ioctl", 122 | "unknown", 123 | "unknown", 124 | "unknown", 125 | "unknown", 126 | "exece", 127 | "umask", 128 | "chroot" 129 | }; 130 | 131 | 132 | struct tr_v7stat { 133 | int16_t st_dev; 134 | u_int16_t st_ino; 135 | u_int16_t st_mode; 136 | int16_t st_nlink; 137 | int16_t st_uid; 138 | int16_t st_gid; 139 | int16_t st_rdev; 140 | int8_t st_size[4]; /* Alignment problems */ 141 | int8_t st_atim[4]; /* Alignment problems */ 142 | int8_t st_mtim[4]; /* Alignment problems */ 143 | int8_t st_ctim[4]; /* Alignment problems */ 144 | }; 145 | 146 | struct tr_v6stat { 147 | int16_t idev; /* Device */ 148 | int16_t inum; 149 | int16_t iflags; /* Mode */ 150 | int8_t inl; /* Links */ 151 | int8_t iuid; 152 | int8_t igid; 153 | u_int8_t isize0; /* Most significant 8 bits */ 154 | u_int16_t isize; 155 | int16_t iaddr[8]; /* Not used, I hope! */ 156 | u_int32_t atime; /* Alignment problems */ 157 | u_int32_t mtime; /* Alignment problems */ 158 | }; 159 | 160 | struct tr_timeb { 161 | u_int32_t time; 162 | u_int16_t millitm; 163 | int16_t timezone; 164 | int16_t dstflag; 165 | }; 166 | 167 | struct tr_sgttyb { 168 | int8_t sg_ispeed; /* input speed */ 169 | int8_t sg_ospeed; /* output speed */ 170 | int8_t sg_erase; /* erase character */ 171 | int8_t sg_kill; /* kill character */ 172 | int16_t sg_flags; /* mode flags */ 173 | }; 174 | 175 | /* 176 | * Values for sg_flags 177 | */ 178 | #define TR_TANDEM 01 179 | #define TR_CBREAK 02 180 | #define TR_LCASE 04 181 | #define TR_ECHO 010 182 | #define TR_CRMOD 020 183 | #define TR_RAW 040 184 | #define TR_ODDP 0100 185 | #define TR_EVENP 0200 186 | #define TR_ANYP 0300 187 | #define TR_XTABS 06000 188 | 189 | /* 190 | * Values for signal 191 | */ 192 | #define V7_SIG_DFL 0 193 | #define V7_SIG_IGN 1 194 | 195 | #define V7_NSIG 15 196 | 197 | #define V7_SIGHUP 1 /* hangup */ 198 | #define V7_SIGINT 2 /* interrupt */ 199 | #define V7_SIGQUIT 3 /* quit */ 200 | #define V7_SIGILL 4 /* illegal instruction (not reset when caught) */ 201 | #define V7_SIGTRAP 5 /* trace trap (not reset when caught) */ 202 | #define V7_SIGIOT 6 /* IOT instruction */ 203 | #define V7_SIGEMT 7 /* EMT instruction */ 204 | #define V7_SIGFPE 8 /* floating point exception */ 205 | #define V7_SIGKILL 9 /* kill (cannot be caught or ignored) */ 206 | #define V7_SIGBUS 10 /* bus error */ 207 | #define V7_SIGSEGV 11 /* segmentation violation */ 208 | #define V7_SIGSYS 12 /* bad argument to system call */ 209 | #define V7_SIGPIPE 13 /* write on a pipe with no one to read it */ 210 | #define V7_SIGALRM 14 /* alarm clock */ 211 | #define V7_SIGTERM 15 /* software termination signal from kill */ 212 | 213 | 214 | /* A union which will point at the trap args, so that 215 | * we can get at the various args of different types 216 | */ 217 | typedef union { 218 | int16_t sarg[4]; /* Signed 16-bit args */ 219 | u_int16_t uarg[4]; /* Unsigned 16-bit args */ 220 | } arglist; 221 | 222 | #define sarg1 V7A.sarg[0] 223 | #define sarg2 V7A.sarg[1] 224 | #define sarg3 V7A.sarg[2] 225 | #define sarg4 V7A.sarg[3] 226 | #define uarg1 V7A.uarg[0] 227 | #define uarg2 V7A.uarg[1] 228 | #define uarg3 V7A.uarg[2] 229 | #define uarg4 V7A.uarg[3] 230 | -------------------------------------------------------------------------------- /tools/disaout/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS= -g -Wall 2 | 3 | disaout: main.o aout.o magic.o opset.o syscalls.o symbols.o 4 | cc -o disaout main.o aout.o magic.o opset.o syscalls.o symbols.o 5 | 6 | clean: 7 | rm -f disaout *.o 8 | -------------------------------------------------------------------------------- /tools/disaout/README: -------------------------------------------------------------------------------- 1 | This is a start on a disassembler for PDP-11 a.out Unix binaries. There's 2 | still a lot to do. Right now I am concentrating on V1 and V2 binaries. I 3 | have re-used code from Apout, so later on we can also do binaries from 4 | V5/B6/V7, 2.9 and 2.11 BSD. I'd also like to parse symbol tables, but 5 | that's for later. 6 | 7 | I need to deal with the bss and initialised data sections of a binary. 8 | 9 | Lots to do, and it's very frustrating. 10 | 11 | Warren Toomey, Mon May 5 2008 12 | -------------------------------------------------------------------------------- /tools/disaout/aout.c: -------------------------------------------------------------------------------- 1 | #include "aout.h" 2 | 3 | /* This code borrowed from Apout */ 4 | 5 | extern int special_magic(u_int16_t *cptr); 6 | extern void load_0407_symbols(FILE *zin, int offset, int size, int base); 7 | 8 | int Binary; /* Type of binary this a.out is */ 9 | u_int8_t *ispace, *dspace; /* Instruction and Data spaces */ 10 | static u_int8_t darray[PDP_MEM_SIZE], iarray[PDP_MEM_SIZE]; 11 | 12 | /* 2.11BSD allows up to 16 8K overlays in the 0430 and 0431 a.out types. 13 | * Each overlay is loaded at the first 8K `click' above the end of the 14 | * main text. The following structures hold the overlays from the current 15 | * a.out, if there are any. Missing overlays have size 0 and pointer NULL. 16 | */ 17 | static struct { 18 | u_int16_t size; 19 | u_int8_t *ovlay; 20 | } ovlist[NOVL] = { 21 | {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, 22 | {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL}, 23 | {0, NULL}, {0, NULL}, {0, NULL} 24 | }; 25 | 26 | static u_int8_t *ovbase; /* Base address of 2.11BSD overlays */ 27 | 28 | /* Load the a.out header from the given file pointer, and return it. 29 | * Also return an integer describing which version of UNIX the a.out 30 | * belongs to. If errors on reading, return -1. 31 | */ 32 | int load_aout_header(FILE * zin, struct exec * E) 33 | { 34 | char *cptr; 35 | 36 | /* Read the a_magic value first */ 37 | /* This makes it easier to deal with */ 38 | /* parsing any script interpreter below */ 39 | if (fread(E, sizeof(u_int16_t), 1, zin) != 1) return (-1); 40 | 41 | switch (E->a_magic) { 42 | case ANY_SCRIPT: /* Shell script, return now */ 43 | return (IS_UNKNOWN); 44 | case V1_NORMAL: 45 | case ANY_NORMAL: /* These are recognised below */ 46 | case ANY_ROTEXT: 47 | case ANY_SPLITID: 48 | case BSD_OVERLAY: 49 | case BSD_ROVERLAY: 50 | case A68_MAGIC: 51 | break; 52 | 53 | default: /* Unrecognised binary, mark as such */ 54 | E->a_magic = UNKNOWN_AOUT; return (IS_UNKNOWN); 55 | } 56 | 57 | /* We can deal with this a.out, so */ 58 | /* read in the rest of the header */ 59 | cptr = (char *) &(E->a_text); 60 | if (fread(cptr, sizeof(struct exec) - sizeof(u_int16_t), 1, zin) != 1) 61 | return (-1); 62 | 63 | switch (E->a_magic) { 64 | case A68_MAGIC: if (E->a_data==A68_DATA) return(IS_A68); 65 | else { E->a_magic = UNKNOWN_AOUT; return (IS_UNKNOWN); } 66 | case V1_NORMAL: return (IS_V1); 67 | case BSD_OVERLAY: 68 | case BSD_ROVERLAY: return (IS_211BSD); 69 | case ANY_NORMAL: 70 | case ANY_ROTEXT: 71 | case ANY_SPLITID: /* Check crt0.o 2nd magic for V2/V6/V7/2.11BSD */ 72 | if (E->a_magic2 == V2_M2) return (IS_V2); 73 | if (E->a_magic2 == V6_M2) return (IS_V6); 74 | if (E->a_magic2 == V7_M2) return (IS_V7); 75 | if (E->a_magic2 == BSD_M2) return (IS_211BSD); 76 | 77 | /* Still no idea, use checksum to determine */ 78 | return(special_magic((u_int16_t *) E)); 79 | 80 | default: /* Should never get here */ 81 | E->a_magic = UNKNOWN_AOUT; return (IS_UNKNOWN); 82 | } 83 | } 84 | 85 | 86 | /* Load the named PDP-11 executable file into the disassembler's memory. 87 | * Returns 0 if ok, -1 if error. 88 | */ 89 | int load_a_out(const char *file, struct exec * e) 90 | { /* @globals errno,stdout,stderr; @ */ 91 | #define V12_MEMBASE 16384 /* Offset for V1/V2 binaries load */ 92 | FILE *zin; 93 | u_int8_t *ibase, *dbase, *bbase; /* Instruction, data, bss bases */ 94 | u_int16_t size; 95 | int i,j; 96 | 97 | if ((zin = fopen(file, "r"))==NULL) /* Open the file */ 98 | return (-1); 99 | 100 | Binary = load_aout_header(zin, e); /* Determine a.out & Unix type */ 101 | 102 | if (e->a_magic == ANY_SCRIPT) { 103 | return (-1); 104 | } 105 | if (e->a_magic == UNKNOWN_AOUT) { 106 | return (-1); 107 | } 108 | 109 | switch (e->a_magic) { 110 | case V1_NORMAL: /* V1 a.out binary looks like */ 111 | e->a_bss = e->a_syms; /* 0405 */ 112 | e->a_syms = e->a_data; /* size of text */ 113 | e->a_data = 0; /* size of symbol table */ 114 | /* reloc bits */ 115 | /* size of data (i.e bss) */ 116 | /* unused and zeroed */ 117 | /* We must rearrange fields */ 118 | /* Move back to start of V1 header */ 119 | if (fseek(zin, 0, SEEK_SET) != 0) { 120 | (void) fclose(zin); return (-1); 121 | } 122 | ispace = dspace = darray; 123 | ibase = &(ispace[V12_MEMBASE]); /* Load & run the binary starting */ 124 | dbase = &(ispace[e->a_text]); /* at address 16384 (040000) */ 125 | bbase = &(ispace[e->a_text + e->a_data]); 126 | e->a_entry = V12_MEMBASE + 12; /* Add 12 to skip over a.out hdr */ 127 | break; 128 | 129 | case A68_MAGIC: /* Algol 68 image */ 130 | if (fseek(zin, 0, SEEK_SET) != 0) { 131 | (void) fclose(zin); return (-1); 132 | } 133 | e->a_text= e->ov_siz[0]+1; 134 | e->a_data= 0; 135 | e->a_bss= 0160000-e->a_text; 136 | e->a_entry= e->a_flag; 137 | ibase = ispace = dspace = darray; 138 | dbase= ibase; 139 | bbase= &(ispace[e->a_text+e->a_data]); 140 | break; 141 | case ANY_NORMAL: 142 | /* Move back to end of V5/6/7 header */ 143 | if (fseek(zin, 16, SEEK_SET) != 0) { 144 | (void) fclose(zin); return (-1); 145 | } 146 | ibase = ispace = dspace = darray; 147 | 148 | if (Binary == IS_V2) { 149 | ibase = &(ispace[V12_MEMBASE]); 150 | e->a_entry = V12_MEMBASE; 151 | dbase = &(ispace[e->a_text + V12_MEMBASE]); 152 | bbase = &(ispace[e->a_text + e->a_data + V12_MEMBASE]); 153 | } else { 154 | dbase = &(ispace[e->a_text]); 155 | bbase = &(ispace[e->a_text + e->a_data]); 156 | } 157 | 158 | /* If there is a symbol table, load it */ 159 | if (e->a_syms) 160 | load_0407_symbols(zin, 16 + e->a_text + e->a_data,e->a_syms,e->a_entry); 161 | break; 162 | case ANY_ROTEXT: 163 | /* Move back to end of V5/6/7 header */ 164 | if (fseek(zin, 16, SEEK_SET) != 0) { 165 | (void) fclose(zin); return (-1); 166 | } 167 | /* @fallthrough@ */ 168 | case BSD_OVERLAY: 169 | /* Round up text area to next 8K boundary */ 170 | if (e->a_text % EIGHT_K) { 171 | size = EIGHT_K * (1 + e->a_text / EIGHT_K); 172 | } else size = e->a_text; 173 | /* And the next 8K boundary if overlays! */ 174 | if (e->a_magic == BSD_OVERLAY) { 175 | if (e->max_ovl % EIGHT_K) { 176 | size += EIGHT_K * (1 + e->max_ovl / EIGHT_K); 177 | } else size += e->max_ovl; 178 | } 179 | ibase = ispace = dspace = darray; 180 | dbase = &(ispace[size]); 181 | bbase = &(ispace[size + e->a_data]); 182 | break; 183 | case ANY_SPLITID: 184 | /* Move back to end of V5/6/7 header */ 185 | if (fseek(zin, 16, SEEK_SET) != 0) { 186 | (void) fclose(zin); return (-1); 187 | } 188 | /* @fallthrough@ */ 189 | case BSD_ROVERLAY: 190 | ibase = ispace = iarray; 191 | dbase = dspace = darray; 192 | bbase = &(dspace[e->a_data]); 193 | break; 194 | default: 195 | (void) fprintf(stderr, "Apout - unknown a.out format 0%o\n", e->a_magic); 196 | (void) fclose(zin); return (-1); 197 | } 198 | 199 | 200 | memset(darray, 0, PDP_MEM_SIZE); /* Clear all memory */ 201 | if (ispace != dspace) memset(iarray, 0, PDP_MEM_SIZE); 202 | 203 | /* Now load the text into ibase */ 204 | for (size = e->a_text; size;) { 205 | i = (int) fread(ibase, 1, (size_t) size, zin); 206 | if (i == -1) { (void) fclose(zin); return (i); } 207 | size -= i; 208 | ibase += i; 209 | } 210 | 211 | /* Now deal with any overlays */ 212 | if (Binary == IS_211BSD) 213 | switch (e->a_magic) { 214 | case BSD_OVERLAY: 215 | case BSD_ROVERLAY: 216 | /* Round up text area to next 8K boundary */ 217 | if (e->a_text % EIGHT_K) { 218 | size = EIGHT_K * (1 + e->a_text / EIGHT_K); 219 | } else size = e->a_text; 220 | ovbase = &ispace[size]; 221 | 222 | for (i = 0; i < NOVL; i++) { 223 | if (e->ov_siz[i] == 0) { 224 | ovlist[i].size = 0; 225 | ovlist[i].ovlay = NULL; 226 | continue; 227 | } 228 | /* Create memory for the overlay */ 229 | ovlist[i].size = e->ov_siz[i]; 230 | if (ovlist[i].ovlay) 231 | free(ovlist[i].ovlay); 232 | ovlist[i].ovlay = (u_int8_t *) malloc(e->ov_siz[i]); 233 | if (ovlist[i].ovlay == NULL) { 234 | fprintf(stderr, "Apout - can't malloc overlay!\n"); 235 | exit(-1); 236 | } 237 | /* Load the overlay into memory */ 238 | for (size = ovlist[i].size, ibase = ovlist[i].ovlay; size;) { 239 | j = fread(ibase, 1, size, zin); 240 | if (j == -1) { 241 | fclose(zin); return (j); 242 | } 243 | size -= j; 244 | ibase += j; 245 | } 246 | } 247 | } 248 | 249 | /* Now load the data into dbase */ 250 | if (dbase) 251 | for (size = e->a_data; size;) { 252 | i = (int) fread(dbase, 1, (size_t) size, zin); 253 | if (i == -1) { (void) fclose(zin); return (i); } 254 | size -= i; 255 | dbase += i; 256 | } 257 | 258 | /* Now clear the bss */ 259 | if ((bbase != 0) && (e->a_bss != 0)) 260 | memset(bbase, 0, (size_t) e->a_bss); 261 | 262 | 263 | (void) fclose(zin); 264 | return (0); 265 | } 266 | -------------------------------------------------------------------------------- /tools/disaout/aout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * aout.h - parse and load the contents of a UNIX a.out file, for several 3 | * flavours of PDP-11 UNIX 4 | * 5 | * $Revision: 1.7 $ $Date: 2008/05/06 01:09:01 $ 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #define EIGHT_K 8192 14 | #define PDP_MEM_SIZE 65536 /* Size of inst-space and data-space */ 15 | 16 | /* UNIX magic numbers for the a.out header */ 17 | #define V1_NORMAL 0405 /* normal: 1st Edition, six words long */ 18 | #define ANY_NORMAL 0407 /* normal: V5,V6,V7,2.11BSD */ 19 | #define ANY_ROTEXT 0410 /* read-only text: V5,V6,V7,2.11BSD */ 20 | #define ANY_SPLITID 0411 /* seperated I&D: V5,V6,V7,2.11BSD */ 21 | #define BSD_OVERLAY 0430 /* 2.11BSD overlay, non-separate */ 22 | #define BSD_ROVERLAY 0431 /* 2.11BSD overlay, separate */ 23 | #define ANY_SCRIPT 020443 /* Shell script, i.e #! */ 24 | #define A68_MAGIC 0 /* Algol68 binaries have these magic nums */ 25 | #define A68_DATA 0107116 /* Algol68 binaries have these magic nums */ 26 | 27 | #define UNKNOWN_AOUT 034567 /* An unknown a.out header */ 28 | 29 | /* Which version of UNIX this a.out comes from */ 30 | #define IS_UNKNOWN 0 31 | #define IS_V1 1 32 | #define IS_V2 2 33 | #define IS_V3 3 34 | #define IS_V4 4 35 | #define IS_V5 5 36 | #define IS_V6 6 37 | #define IS_V7 7 38 | #define IS_A68 68 39 | #define IS_29BSD 29 40 | #define IS_211BSD 211 41 | 42 | /* a.out header for nearly all UNIX flavours */ 43 | struct exec { 44 | u_int16_t a_magic; /* magic number */ 45 | u_int16_t a_text; /* size of text segment */ 46 | u_int16_t a_data; /* size of initialised data */ 47 | u_int16_t a_bss; /* size of initialised bss */ 48 | u_int16_t a_syms; /* size of symbol table */ 49 | u_int16_t a_entry; /* entry point */ 50 | u_int16_t a_unused; /* unused */ 51 | u_int16_t a_flag; /* relocation info stripped */ 52 | /* 16 bytes up to here */ 53 | 54 | /* 2.11BSD overlay files have the following */ 55 | #define NOVL 15 56 | int16_t max_ovl; /* maximum overlay size */ 57 | u_int16_t ov_siz[NOVL]; /* size of the i'th overlay */ 58 | /* Note that if the file isn't a 2.11BSD */ 59 | /* overlay, we have to rewind to undo */ 60 | /* the read of this section */ 61 | }; 62 | 63 | /* Symbol table entries for 0407 binaries */ 64 | struct sym0407 { 65 | u_int8_t name[8]; 66 | u_int16_t type; 67 | u_int16_t addr; 68 | }; 69 | 70 | #define ASYM_UNDEFINED 00 71 | #define ASYM_ABSOLUTE 01 72 | #define ASYM_TEXT 02 73 | #define ASYM_DATA 03 74 | #define ASYM_BSS 04 75 | #define ASYM_UNDEFEXT 40 76 | #define ASYM_ABSEXT 41 77 | #define ASYM_TEXTEXT 42 78 | #define ASYM_DATAEXT 43 79 | #define ASYM_BSSDEXT 44 80 | 81 | /* 82 | * Because V5, V6, V7 and 2.11BSD share several magic numbers in their a.out 83 | * headers, we must distinguish them so as to set up the correct emulated 84 | * environment. This is done by observing the differences in their crt0.s 85 | * code: they all differ at position 021 86 | */ 87 | #define a_magic2 ov_siz[0] 88 | #define V2_M2 0177304 /* Doesn't apply to all, tho */ 89 | #define V6_M2 0010600 90 | #define V7_M2 0016600 91 | #define BSD_M2 0162706 92 | 93 | 94 | /* 95 | * Some syscalls pass arguments in registers, some in words following the 96 | * trap instruction. For each Unix version, we keep an array of syscall 97 | * names, and the number of words following the trap 98 | */ 99 | struct syscallinfo { 100 | char *name; 101 | int numwords; 102 | }; 103 | 104 | /* 105 | * We try to infer symbols based on branch addresses, jsr addresses etc. We 106 | * keep two lists, instruction symbols and data symbols. Each one is kept in 107 | * this struct. 108 | */ 109 | struct symbol { 110 | char *name; 111 | int type; 112 | int size; /* # bytes, used by SYM_JSRTEXT and SYM_JSRDATA */ 113 | }; 114 | 115 | /* Symbol types */ 116 | #define SYM_BRANCH 0 117 | #define SYM_FUNCTION 1 118 | #define SYM_DATA 2 119 | #define SYM_JSRTEXT 3 /* Ascii string following jsr r5,xxx */ 120 | #define SYM_JSRDATA 4 /* Binary data following jsr r5,xxx */ 121 | -------------------------------------------------------------------------------- /tools/disaout/magic.c: -------------------------------------------------------------------------------- 1 | /* This code borrowed from Apout */ 2 | 3 | /* magic.c - determine the environment for certain PDP-11 a.out binaries 4 | * 5 | * Some binaries in V1, V2, V5, V6, V7 and 2.11BSD are not caught with the 6 | * magic numbers in aout.c. If this is the case, we fall into the 7 | * special_magic() function, which calculates a checksum on the 8 | * a.out header. If it matches any of the checksums below, it returns 9 | * the appropriate environment value. Otherwise, it returns IS_UNKNOWN. 10 | * 11 | * $Revision: 1.2 $ 12 | * $Date: 2008/05/06 01:09:01 $ 13 | */ 14 | #include "aout.h" 15 | 16 | struct spec_aout { 17 | u_int32_t cksum; 18 | int environment; 19 | }; 20 | 21 | static struct spec_aout S[]= { 22 | { 0x1042c2, IS_V6 }, /* V6 bin/dc */ 23 | { 0x10f02, IS_V5 }, /* V5 etc/update */ 24 | { 0x11002, IS_V5 }, /* V5 bin/clri */ 25 | { 0x1117c2, IS_V7 }, /* V7 bin/roff */ 26 | { 0x11702, IS_V6 }, /* V6 etc/update */ 27 | { 0x11a82, IS_V5 }, /* V5 bin/sum */ 28 | { 0x1319c2, IS_V5 }, /* V5 usr/fort/fc1 */ 29 | { 0x1332c2, IS_V2 }, /* /lib/c0 dated Jun 30 1973 from s2 tape */ 30 | { 0x13642, IS_V5 }, /* V5 bin/rew */ 31 | { 0x139e02, IS_V5 }, /* V5 bin/dc */ 32 | { 0x13c0, IS_V6 }, /* V6 usr/lib/tmgc */ 33 | { 0x14042, IS_V6 }, /* V6 bin/tty */ 34 | { 0x143c2, IS_V5 }, /* V5 bin/tty */ 35 | { 0x152ac2, IS_V6 }, /* V6 usr/lib/tmg */ 36 | { 0x15f42, IS_V5 }, /* V5 bin/kill */ 37 | { 0x16802, IS_V5 }, /* V5 bin/dsw */ 38 | { 0x16902, IS_V5 }, /* V5 bin/mkdir */ 39 | { 0x1720c2, IS_V6 }, /* V6 bin/cdb */ 40 | { 0x17742, IS_V5 }, /* V5 usr/bin/pfe */ 41 | { 0x17cc2, IS_V5 }, /* V5 usr/bin/mesg */ 42 | { 0x18702, IS_V5 }, /* V5 bin/rmdir */ 43 | { 0x194c2, IS_V6 }, /* V6 bin/chgrp */ 44 | { 0x197c2, IS_V6 }, /* V6 bin/chown */ 45 | { 0x19a42, IS_V5 }, /* V5 bin/chown */ 46 | { 0x19b342, IS_V6 }, /* V6 usr/bin/nroff */ 47 | { 0x19f682, IS_V6 }, /* V6 usr/fort/fc1 */ 48 | { 0x1b102, IS_V5 }, /* V5 bin/strip */ 49 | { 0x1ba02, IS_V6 }, /* V6 bin/strip */ 50 | { 0x1c342, IS_V5 }, /* V5 bin/cat */ 51 | { 0x1c8442, IS_V7 }, /* V7 usr/games/maze */ 52 | { 0x1cc782, IS_V6 }, /* V6 lib/fc0 */ 53 | { 0x1dfc2, IS_V5 }, /* V5 etc/getty */ 54 | { 0x1f9c2, IS_V2 }, /* /bin/nm dated Jun 30 1973 from s2 tape */ 55 | { 0x20202, IS_V5 }, /* V5 usr/games/bj */ 56 | { 0x21e42, IS_V6 }, /* V6 usr/bin/units */ 57 | { 0x23f82, IS_V5 }, /* V5 usr/bin/passwd */ 58 | { 0x260642, IS_V6 }, /* V6 lib/fc1 */ 59 | { 0x262a82, IS_211BSD }, /* 2.11 usr/new/m11 */ 60 | { 0x27e82, IS_V5 }, /* V5 usr/bin/grep */ 61 | { 0x290c2, IS_V7 }, /* V7 usr/games/cubic */ 62 | { 0x299c2, IS_V5 }, /* V5 usr/games/cubic */ 63 | { 0x2f482, IS_V5 }, /* V5 usr/bin/form */ 64 | { 0x3382, IS_V6 }, /* V6 bin/write */ 65 | { 0x326642, IS_V7 }, /* 2.9 awk */ 66 | { 0x33c42, IS_211BSD }, /* 2.11 usr/games/moo */ 67 | { 0x351382, IS_211BSD }, /* 2.11 usr/games/lib/zork */ 68 | { 0x3702, IS_V5 }, /* V5 usr/games/moo */ 69 | { 0x3b402, IS_V5 }, /* V5 bin/ar */ 70 | { 0x3cc02, IS_V2 }, /* /bin/size from from s2 tape */ 71 | { 0x4382, IS_V5 }, /* V5 bin/write */ 72 | { 0x451f42, IS_V7 }, /* 2.9 /lib/c1 */ 73 | { 0x47042, IS_211BSD }, /* 2.11 usr/games/ttt */ 74 | { 0x4fa02, IS_V5 }, /* V5 bin/ld */ 75 | { 0x51342, IS_211BSD }, /* 2.11 usr/games/bj */ 76 | { 0x53302, IS_V6 }, /* V6 usr/lib/suftab */ 77 | { 0x55882, IS_V7 }, /* 2.9 /bin/as */ 78 | { 0x54702, IS_V5 }, /* V5 usr/games/ttt */ 79 | { 0x55702, IS_V7 }, /* V7 bin/as */ 80 | { 0x5c342, IS_V2 }, /* /bin/cc dated Jun 30 1973 from s2 tape */ 81 | { 0x6f742, IS_V6 }, /* V6 usr/bin/sa */ 82 | { 0x7042, IS_V7 }, /* V7 bin/factor */ 83 | { 0x71702, IS_V7 }, /* V7 lib/as2 */ 84 | { 0x7342, IS_V5 }, /* V5 bin/du */ 85 | { 0x73782, IS_V7}, /* 2.9 /lib/as2 */ 86 | { 0x73e00, IS_V2 }, /* /bin/ld from s2 tape */ 87 | { 0x7a242, IS_V6 }, /* V6 lib/as2 */ 88 | { 0x7b102, IS_V6 }, /* V6 bin/as */ 89 | { 0x7d082, IS_V5 }, /* V5 bin/as */ 90 | { 0x7d6844, IS_V1 }, /* bin/cal from s2 tape */ 91 | { 0x7d942, IS_V5 }, /* V5 lib/as2 */ 92 | { 0x8002, IS_V5 }, /* V5 etc/lpd */ 93 | { 0x85842, IS_V5 }, /* V5 bin/ed */ 94 | { 0x8f00, IS_V6 }, /* V6 usr/lib/tmga */ 95 | { 0x915c2, IS_V6 }, /* V6 bin/bas */ 96 | { 0x94542, IS_V5 }, /* V5 bin/db */ 97 | { 0x98442, IS_V6 }, /* V6 usr/bin/ac */ 98 | { 0x9adc2, IS_V6 }, /* V6 bin/db */ 99 | { 0xa242, IS_V7 }, /* V7 bin/primes */ 100 | { 0xa4602, IS_V2 }, /* /bin/as from s2 tape */ 101 | { 0xa702, IS_V5 }, /* V5 bin/time */ 102 | { 0xad882, IS_V7 }, /* V7 bin/bas */ 103 | { 0xadc42, IS_V2 }, /* /usr/lib/c1 from s2 tape */ 104 | { 0xb5a82, IS_V6 }, /* V6 usr/bin/prof */ 105 | { 0xc1e42, IS_V5 }, /* V5 usr/bin/fed */ 106 | { 0xc3102, IS_V6 }, /* V6 bin/tp */ 107 | { 0xc8bc2, IS_V5 }, /* V5 bin/tp */ 108 | { 0xe1642, IS_V6 }, /* V6 usr/bin/roff */ 109 | { 0xe1f42, IS_V5 }, /* V5 usr/bin/roff */ 110 | { 0xec582, IS_V5 }, /* V5 bin/bas */ 111 | { 0xfc2, IS_V6 }, /* V6 usr/bin/typo */ 112 | { 0xfc002, IS_V2 }, /* /bin/as dated Jun 30 1973 from s2 tape */ 113 | { 0x38ec0, IS_V5 }, /* V5 bin/ar, Warrens */ 114 | { 0, 0 } 115 | }; 116 | 117 | /* cptr points at the start of the a.out header */ 118 | int special_magic(u_int16_t *cptr) 119 | { 120 | u_int32_t cksum=0; 121 | int i; 122 | 123 | if (cptr==NULL) return(IS_UNKNOWN); 124 | /* Calculate the checksum */ 125 | for (i=0;i<8; i++) { cksum ^= cptr[i]; cksum = cksum<<1; } 126 | 127 | /* Try and find a match */ 128 | for (i=0; S[i].cksum!=0; i++) if (S[i].cksum==cksum) { 129 | return(S[i].environment); 130 | } 131 | 132 | /* None, return 0 */ 133 | (void)fprintf(stderr, "Unknown magic in header: 0x%x\n",cksum); 134 | return(IS_UNKNOWN); 135 | } 136 | -------------------------------------------------------------------------------- /tools/disaout/main.c: -------------------------------------------------------------------------------- 1 | #include "aout.h" 2 | 3 | extern int load_a_out(const char *file, struct exec *E); 4 | extern int printins(int addr); 5 | extern void patch_symbols(void); 6 | extern void print_symtables(void); 7 | extern u_int8_t *ispace, *dspace; /* Instruction and Data spaces */ 8 | extern int doprint; 9 | int onepass = 0; /* Only do a single pass */ 10 | int printaddrs = 0; /* Print out addresses and words */ 11 | 12 | void dopass(struct exec *e) 13 | { 14 | int i; 15 | u_int16_t *iptr; 16 | for (i = e->a_entry; i < e->a_entry + e->a_text;) { 17 | iptr = (u_int16_t *) & ispace[i]; 18 | if (doprint && printaddrs) 19 | printf("%06o: %06o\t", i, *iptr); 20 | i += printins(i); 21 | } 22 | } 23 | 24 | void usage() 25 | { 26 | fprintf(stderr, "Usage: disaout [-1a] file\n"); 27 | exit(1); 28 | } 29 | 30 | int main(int argc, char *argv[]) 31 | { 32 | struct exec E; 33 | int ch, err; 34 | 35 | /* Get any arguments */ 36 | while ((ch = getopt(argc, argv, "1a")) != -1) { 37 | switch (ch) { 38 | case '1': 39 | onepass = 1; 40 | break; 41 | case 'a': 42 | printaddrs = 1; 43 | break; 44 | case '?': 45 | default: 46 | usage(); 47 | } 48 | } 49 | argc -= optind; 50 | argv += optind; 51 | 52 | 53 | /* Check we have an file to open */ 54 | if (argc != 1) 55 | usage(); 56 | 57 | /* Get the header details for the a.out file */ 58 | err = load_a_out(argv[0], &E); 59 | 60 | if (err == -1) { 61 | fprintf(stderr, "%s does not appear to be a PDP-11 a.out file\n", argv[0]); 62 | exit(1); 63 | } 64 | 65 | printf("/ text at 0%o, len 0%o, end 0%o\n", 66 | E.a_entry, E.a_text, E.a_entry + E.a_text); 67 | 68 | if (onepass == 0) { 69 | doprint = 0; 70 | dopass(&E); /* Do pass 1 to infer symbols */ 71 | patch_symbols(); 72 | /* print_symtables(); */ 73 | } 74 | doprint = 1; 75 | dopass(&E); /* Do pass 2 to print it out */ 76 | 77 | exit(0); 78 | } 79 | -------------------------------------------------------------------------------- /tools/disaout/opset.c: -------------------------------------------------------------------------------- 1 | /* This code borrowed from 2.11BSD adb */ 2 | 3 | #include "aout.h" 4 | 5 | extern void add_symbol(int addr, int type, int size); 6 | extern struct symbol *get_isym(int addr); 7 | extern struct symbol *get_dsym(int addr); 8 | 9 | extern u_int8_t *ispace, *dspace; /* Instruction and Data spaces */ 10 | extern struct syscallinfo *systab; 11 | extern int numsyscalls; 12 | 13 | int doprint = 0; /* Only print out if 1 */ 14 | int itype; /* Global equal to p->itype */ 15 | 16 | #define NSP 0 17 | #define ISYM 2 18 | #define DSYM 7 19 | 20 | /* instruction printing */ 21 | 22 | #define DOUBLE 0 23 | #define DOUBLW 1 24 | #define SINGLE 2 25 | #define SINGLW 3 26 | #define REVERS 4 27 | #define BRANCH 5 28 | #define NOADDR 6 29 | #define DFAULT 7 30 | #define TRAP 8 31 | #define SYS 9 32 | #define SOB 10 33 | #define JMP 11 34 | #define JSR 12 35 | 36 | struct optab { 37 | int mask; 38 | int val; 39 | int itype; 40 | char *iname; 41 | } optab[] = { 42 | { 0107777, 0010000, DOUBLE, "mov" }, 43 | { 0107777, 0020000, DOUBLE, "cmp" }, 44 | { 0107777, 0030000, DOUBLE, "bit" }, 45 | { 0107777, 0040000, DOUBLE, "bic" }, 46 | { 0107777, 0050000, DOUBLE, "bis" }, 47 | { 0007777, 0060000, DOUBLW, "add" }, 48 | { 0007777, 0160000, DOUBLW, "sub" }, 49 | { 0100077, 0005000, SINGLE, "clr" }, 50 | { 0100077, 0005100, SINGLE, "com" }, 51 | { 0100077, 0005200, SINGLE, "inc" }, 52 | { 0100077, 0005300, SINGLE, "dec" }, 53 | { 0100077, 0005400, SINGLE, "neg" }, 54 | { 0100077, 0005500, SINGLE, "adc" }, 55 | { 0100077, 0005600, SINGLE, "sbc" }, 56 | { 0100077, 0005700, SINGLE, "tst" }, 57 | { 0100077, 0006000, SINGLE, "ror" }, 58 | { 0100077, 0006100, SINGLE, "rol" }, 59 | { 0100077, 0006200, SINGLE, "asr" }, 60 | { 0100077, 0006300, SINGLE, "asl" }, 61 | { 0000077, 0000100, JMP, "jmp" }, 62 | { 0000077, 0000300, SINGLE, "swab" }, 63 | { 0000077, 0170100, SINGLW, "ldfps" }, 64 | { 0000077, 0170200, SINGLW, "stfps" }, 65 | { 0000077, 0170300, SINGLW, "stst" }, 66 | { 0000077, 0170400, SINGLW, "clrf" }, 67 | { 0000077, 0170500, SINGLW, "tstf" }, 68 | { 0000077, 0170600, SINGLW, "absf" }, 69 | { 0000077, 0170700, SINGLW, "negf" }, 70 | { 0000077, 0006700, SINGLW, "sxt" }, 71 | { 0000077, 0006600, SINGLW, "mtpi" }, 72 | { 0000077, 0106600, SINGLW, "mtpd" }, 73 | { 0000077, 0006500, SINGLW, "mfpi" }, 74 | { 0000077, 0106500, SINGLW, "mfpd" }, 75 | { 0000077, 0106700, SINGLW, "mfps" }, 76 | { 0000077, 0106400, SINGLW, "mtps" }, 77 | { 0000777, 0070000, REVERS, "mul" }, 78 | { 0000777, 0071000, REVERS, "div" }, 79 | { 0000777, 0072000, REVERS, "ash" }, 80 | { 0000777, 0073000, REVERS, "ashc" }, 81 | { 0377, 0000400, BRANCH, "br" }, 82 | { 0377, 0001000, BRANCH, "bne" }, 83 | { 0377, 0001400, BRANCH, "beq" }, 84 | { 0377, 0002000, BRANCH, "bge" }, 85 | { 0377, 0002400, BRANCH, "blt" }, 86 | { 0377, 0003000, BRANCH, "bgt" }, 87 | { 0377, 0003400, BRANCH, "ble" }, 88 | { 0377, 0100000, BRANCH, "bpl" }, 89 | { 0377, 0100400, BRANCH, "bmi" }, 90 | { 0377, 0101000, BRANCH, "bhi" }, 91 | { 0377, 0101400, BRANCH, "blos" }, 92 | { 0377, 0102000, BRANCH, "bvc" }, 93 | { 0377, 0102400, BRANCH, "bvs" }, 94 | { 0377, 0103000, BRANCH, "bcc" }, 95 | { 0377, 0103400, BRANCH, "bcs" }, 96 | { 0000000, 0000000, NOADDR, "halt" }, 97 | { 0000000, 0000001, NOADDR, "wait" }, 98 | { 0000000, 0000002, NOADDR, "rti" }, 99 | { 0000000, 0000003, NOADDR, "bpt" }, 100 | { 0000000, 0000004, NOADDR, "iot" }, 101 | { 0000000, 0000005, NOADDR, "reset" }, 102 | { 0000000, 0000006, NOADDR, "rtt" }, 103 | { 0377, 0171000, REVERS, "mulf" }, 104 | { 0377, 0171400, REVERS, "modf" }, 105 | { 0377, 0172000, REVERS, "addf" }, 106 | { 0377, 0172400, REVERS, "movf" }, 107 | { 0377, 0173000, REVERS, "subf" }, 108 | { 0377, 0173400, REVERS, "cmpf" }, 109 | { 0377, 0174000, DOUBLW, "movf" }, 110 | { 0377, 0174400, REVERS, "divf" }, 111 | { 0377, 0175000, DOUBLW, "movei" }, 112 | { 0377, 0175400, DOUBLW, "movfi" }, 113 | { 0377, 0176000, DOUBLW, "movfo" }, 114 | { 0377, 0176400, REVERS, "movie" }, 115 | { 0377, 0177000, REVERS, "movif" }, 116 | { 0377, 0177400, REVERS, "movof" }, 117 | { 0000000, 0170000, NOADDR, "cfcc" }, 118 | { 0000000, 0170001, NOADDR, "setf" }, 119 | { 0000000, 0170002, NOADDR, "seti" }, 120 | { 0000000, 0170011, NOADDR, "setd" }, 121 | { 0000000, 0170012, NOADDR, "setl" }, 122 | { 0000000, 0000007, NOADDR, "mfpt" }, 123 | { 0000077, 0007000, JMP, "csm" }, 124 | { 0000077, 0007300, SINGLW, "wrtlck" }, 125 | { 0000077, 0007200, SINGLW, "tstset" }, 126 | { 0000777, 0004000, JSR, "jsr" }, 127 | { 0000777, 0074000, DOUBLE, "xor" }, 128 | { 0000007, 0000200, SINGLE, "rts" }, 129 | { 0000017, 0000240, DFAULT, "cflg" }, 130 | { 0000017, 0000260, DFAULT, "sflg" }, 131 | { 0377, 0104000, TRAP, "emt" }, 132 | { 0377, 0104400, SYS, "sys" }, 133 | { 0000077, 0006400, TRAP, "mark" }, 134 | { 0000777, 0077000, SOB, "sob" }, 135 | { 0000007, 0000230, DFAULT, "spl" }, 136 | { 0177777, 0000000, DFAULT, "" } 137 | }; 138 | 139 | 140 | /* Heuristically determine what follows after a jsr r5,xxx. 141 | * Create a symbol for it, including the estimated size. 142 | * Return the length of the data in bytes. 143 | */ 144 | int guess_jsr_r5(int addr) 145 | { 146 | int a,len; 147 | int istext=1; 148 | 149 | /* Try an ASCII string first. Give up if we find a 150 | * non-printable and non-NUL character. 151 | */ 152 | for (a=addr,len=0;; a++,len++) { 153 | /* Found end of string which isn't zero length, stop now */ 154 | if (len && (ispace[a]=='\0')) { 155 | len++; break; 156 | } 157 | 158 | /* If char is not ASCII and not tab/newline, it's not a string */ 159 | if (!isprint(ispace[a]) && (ispace[a] != '\t') && (ispace[a] != '\n')) { 160 | istext=0; break; 161 | } 162 | } 163 | 164 | /* If not a string, guess a single word as argument */ 165 | if (!istext) { 166 | add_symbol(addr, SYM_JSRDATA, 2); 167 | return(2); 168 | } else { 169 | /* Ensure length is word-aligned */ 170 | if ((addr+len)%2) len++; 171 | add_symbol(addr, SYM_JSRTEXT, len); 172 | return(len); 173 | } 174 | } 175 | 176 | void printquoted(char *str) 177 | { 178 | while(*str) { 179 | switch(*str) { 180 | case '\n': printf("\\n"); break; 181 | case '\r': printf("\\r"); break; 182 | case '\b': printf("\\b"); break; 183 | default: printf("%c", *str); 184 | } 185 | str++; 186 | } 187 | printf("\\0"); 188 | } 189 | 190 | /* 191 | * Print out an operand. Return any increment to skip to reach the next 192 | * instruction. 193 | */ 194 | int paddr(char *str, int addr, int a, int lastr) 195 | { 196 | char *regname[] = {"r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc"}; 197 | u_int16_t var; 198 | int r; 199 | char *rptr; 200 | 201 | r = a & 07; 202 | a &= 070; 203 | 204 | if (doprint) 205 | printf(str); 206 | if (r == 7 && a & 020) { 207 | int jsrr5_skip=0; /* Amount to skip on a jsr r5,xxx */ 208 | if (a & 010) { 209 | if (doprint) 210 | putchar('*'); 211 | } 212 | if (a & 040) { 213 | 214 | var = (addr + 4) + ispace[addr + 2] + (ispace[addr + 3] << 8); 215 | if (doprint) { 216 | /* See if there is a label for that */ 217 | struct symbol *s; 218 | if (itype==JSR) s= get_isym(var); 219 | else s= get_dsym(var); 220 | if (s == NULL) 221 | printf("0%o", var); 222 | else 223 | printf("%s", s->name); 224 | 225 | /* We've hit a jsr r5,... */ 226 | if ((itype==JSR) && (lastr==5)) { 227 | s= get_isym(addr+4); 228 | if (s==NULL) { 229 | printf("Weird, no SYM_JSR\n"); 230 | } else { 231 | jsrr5_skip= s->size; 232 | if (s->type==SYM_JSRTEXT) { 233 | char *str= (char *)&ispace[addr+4]; 234 | printf("; <"); 235 | printquoted(str); 236 | printf(">; .even"); 237 | } else { 238 | u_int16_t var2= ispace[addr + 4] + (ispace[addr + 5] << 8); 239 | printf("; 0%o", var2); 240 | } 241 | } 242 | } 243 | } else { 244 | /* Register a function if this is a JSR, else data */ 245 | if (itype==JSR) { 246 | add_symbol(var, SYM_FUNCTION, 0); 247 | if (lastr==5) { 248 | jsrr5_skip= guess_jsr_r5(addr+4); 249 | } 250 | } 251 | else add_symbol(var, SYM_DATA, 0); 252 | } 253 | } else { 254 | var = ispace[addr + 2] + (ispace[addr + 3] << 8); 255 | if (doprint) 256 | printf("$0%o", var); 257 | } 258 | return (2+jsrr5_skip); 259 | } 260 | 261 | rptr = regname[r]; 262 | switch (a) { 263 | /* r */ 264 | case 000: 265 | if (doprint) 266 | printf(rptr); 267 | return (0); 268 | 269 | /* (r) */ 270 | case 010: 271 | if (doprint) 272 | printf("(%s)", rptr); 273 | return (0); 274 | 275 | /* *(r)+ */ 276 | case 030: 277 | if (doprint) 278 | putchar('*'); 279 | 280 | /* (r)+ */ 281 | case 020: 282 | if (doprint) 283 | printf("(%s)+", rptr); 284 | return (0); 285 | 286 | /* *-(r) */ 287 | case 050: 288 | if (doprint) 289 | putchar('*'); 290 | 291 | /* -(r) */ 292 | case 040: 293 | if (doprint) 294 | printf("-(%s)", rptr); 295 | return (0); 296 | 297 | /* *x(r) */ 298 | case 070: 299 | if (doprint) 300 | putchar('*'); 301 | 302 | /* x(r) */ 303 | case 060: 304 | var = ispace[addr + 2] + (ispace[addr + 3] << 8); 305 | if (doprint) 306 | printf("0%o(%s)", var, rptr); 307 | return (2); 308 | } 309 | return (0); 310 | } 311 | 312 | /* 313 | * Deal with double operands. Return any increment to skip to reach the next 314 | * instruction. 315 | */ 316 | int doubl(int addr, int a, int b) 317 | { 318 | int i = 0; 319 | int r= a & 07; /* Get the register from the 1st operand */ 320 | i += paddr(" ", addr, a, 0); 321 | i += paddr(",", addr + i, b, r); 322 | return (i); 323 | } 324 | 325 | void branch(char *str, int addr, int ins) 326 | { 327 | if (doprint) printf(str); 328 | if (ins & 0200) { 329 | ins |= 0177400; 330 | } 331 | 332 | /* Determine the branch address */ 333 | ins = (addr + (ins << 1) + 2) & 0177777; 334 | 335 | if (!doprint) { 336 | add_symbol(ins, SYM_BRANCH, 0); /* Add a branch symbol for it */ 337 | return; 338 | } 339 | 340 | /* Printing it, see if there is a label for that */ 341 | struct symbol *s = get_isym(ins); 342 | if (s == NULL) { 343 | printf("0%o", ins); 344 | return; 345 | } 346 | 347 | /* Yes there is, print it out */ 348 | printf("%s", s->name); 349 | if (s->type == SYM_BRANCH) { 350 | if (ins > addr) printf("f"); 351 | else printf("b"); 352 | } 353 | } 354 | 355 | /* 356 | * Given an address, disassemble and print out the instruction at that 357 | * address. Return any increment to skip to reach the next instruction. 358 | */ 359 | int printins(int addr) 360 | { 361 | unsigned int type; 362 | int byte; 363 | int incr = 2; 364 | int syscall; 365 | struct optab *p; 366 | struct symbol *s; 367 | 368 | /* Print out any instruction symbol */ 369 | if (doprint) { 370 | s = get_isym(addr); 371 | if (s) 372 | printf("%s:\n", s->name); 373 | } 374 | /* Get the instruction from the ispace array */ 375 | int ins = ispace[addr] + (ispace[addr + 1] << 8); 376 | 377 | type = DSYM; 378 | for (p = optab;; p++) { 379 | if ((ins & ~p->mask) == p->val) { 380 | break; 381 | } 382 | } 383 | if (doprint) 384 | printf("\t%s", p->iname); 385 | byte = ins & 0100000; 386 | ins &= p->mask; 387 | 388 | itype= p->itype; 389 | switch (p->itype) { 390 | 391 | case JMP: 392 | type = ISYM; 393 | 394 | case SINGLE: 395 | if (byte) { 396 | if (doprint) 397 | putchar('b'); 398 | } 399 | case SINGLW: 400 | incr += paddr(" ", addr, ins, 0); 401 | break; 402 | 403 | case REVERS: 404 | incr += doubl(addr, ins & 077, (ins >> 6) & 07); 405 | break; 406 | 407 | case JSR: 408 | type = ISYM; 409 | 410 | case DOUBLE: 411 | if (byte) { 412 | if (doprint) 413 | putchar('b'); 414 | } 415 | case DOUBLW: 416 | incr += doubl(addr, ins >> 6, ins); 417 | 418 | case NOADDR: 419 | break; 420 | 421 | case SOB: 422 | incr += paddr(" ", addr, (ins >> 6) & 07, 0); 423 | branch(",", addr, -(ins & 077)); 424 | break; 425 | 426 | case BRANCH: 427 | branch(" ", addr, ins); 428 | break; 429 | 430 | case SYS: 431 | if (ins < numsyscalls && systab[ins].name) { 432 | if (doprint) 433 | printf(" %s", systab[ins].name); 434 | /* Print any argument words following the syscall */ 435 | int n; 436 | for (n = 1; n <= systab[ins].numwords; n++) { 437 | int b = 2 * n; 438 | syscall = ispace[addr + b] + (ispace[addr + b + 1] << 8); 439 | if (doprint) 440 | printf("; 0%o", syscall); 441 | } 442 | /* Skip some number of words following the syscall */ 443 | incr += 2 * systab[ins].numwords; 444 | } else if (doprint) 445 | printf(" %d", ins); 446 | break; 447 | 448 | case TRAP: 449 | case DFAULT: 450 | default: 451 | if (doprint) 452 | printf(" 0%o", ins); 453 | } 454 | if (doprint) 455 | printf("\n"); 456 | return (incr); 457 | } 458 | -------------------------------------------------------------------------------- /tools/disaout/symbols.c: -------------------------------------------------------------------------------- 1 | /* Tables and functions to keep track of symbols */ 2 | 3 | #include "aout.h" 4 | 5 | struct symbol * isym[PDP_MEM_SIZE], * dsym[PDP_MEM_SIZE]; 6 | 7 | /* Array of structs holding details for each type of symbol */ 8 | struct symtype { 9 | char *format; 10 | int counter; 11 | struct symbol **table; 12 | } symtypelist[] = { 13 | { "%d", 1, isym }, 14 | { "func%d", 1, isym }, 15 | { "data%d", 1, dsym }, 16 | { "jsrtext%d", 1, isym }, 17 | { "jsrdata%d", 1, isym }, 18 | }; 19 | 20 | /* Debug code */ 21 | void print_symtables(void) 22 | { 23 | int i; 24 | for (i=0; i< PDP_MEM_SIZE; i++) { 25 | if (isym[i]!=NULL) 26 | printf("0%06o %d %d %s\n",i, isym[i]->type, isym[i]->size, isym[i]->name); 27 | if (dsym[i]!=NULL) 28 | printf("0%06o %d %d %s\n",i, dsym[i]->type, dsym[i]->size, dsym[i]->name); 29 | } 30 | } 31 | 32 | void add_symbol(int addr, int type, int size) 33 | { 34 | struct symbol *s; 35 | 36 | /* See if we have a symbol already defined at this address */ 37 | /* If there is one and its type is >= ours, don't put a new one in */ 38 | if ((symtypelist[type].table[addr] != NULL) && 39 | (symtypelist[type].table[addr]->type >= type)) return; 40 | 41 | /* No, so create one */ 42 | s= malloc(sizeof(struct symbol)); 43 | #if 0 44 | s->name= malloc(12); 45 | snprintf(s->name,12,symtypelist[type].format, symtypelist[type].counter++); 46 | #endif 47 | s->name= NULL; /* To be filled in later */ 48 | s->type= type; 49 | s->size= size; 50 | symtypelist[type].table[addr]= s; 51 | } 52 | 53 | /* Walk through both isym and dsym tables, giving them actual 54 | * symbol names. 55 | */ 56 | void patch_symbols(void) 57 | { 58 | int i,type; 59 | struct symbol *s; 60 | for (i=0; i< PDP_MEM_SIZE; i++) { 61 | if (isym[i]==NULL) continue; 62 | s= isym[i]; 63 | if (s->name != NULL) continue; 64 | type=s->type; 65 | s->name= malloc(12); 66 | snprintf(s->name,12,symtypelist[type].format, symtypelist[type].counter++); 67 | } 68 | for (i=0; i< PDP_MEM_SIZE; i++) { 69 | if (dsym[i]==NULL) continue; 70 | s= dsym[i]; s->name= malloc(12); 71 | type=s->type; 72 | snprintf(s->name,12,symtypelist[type].format, symtypelist[type].counter++); 73 | } 74 | } 75 | 76 | struct symbol * get_isym(int addr) 77 | { 78 | return(isym[addr]); 79 | } 80 | 81 | struct symbol * get_dsym(int addr) 82 | { 83 | return(dsym[addr]); 84 | } 85 | 86 | /* Walk the 0407 symbol table and load the symbols found */ 87 | void load_0407_symbols(FILE *zin, int offset, int size, int base) 88 | { 89 | struct sym0407 S; 90 | struct symbol *oursym; 91 | char name[9]; 92 | long curpos; 93 | 94 | /* Record where we are, and seek to the symbol table */ 95 | curpos= ftell(zin); 96 | if (fseek(zin, offset, SEEK_SET) != 0) { 97 | printf("Unable to load symbol table at offset %d\n", offset); 98 | return; 99 | } 100 | name[8]='\0'; /* Ensure we get a properly terminated string */ 101 | 102 | /* Walk the list */ 103 | while (size>0) { 104 | fread(&S, sizeof(S), 1, zin); size -= sizeof(S); 105 | memcpy(name, S.name, 8); 106 | S.addr += base; 107 | 108 | switch (S.type) { 109 | case ASYM_DATA: 110 | case ASYM_BSS: 111 | case ASYM_DATAEXT: 112 | case ASYM_BSSDEXT: 113 | oursym= malloc(sizeof(struct symbol)); 114 | oursym->name= strdup(name); 115 | oursym->type= SYM_DATA; 116 | oursym->size= 0; 117 | dsym[S.addr]= oursym; 118 | break; 119 | 120 | case ASYM_TEXT: 121 | case ASYM_TEXTEXT: 122 | oursym= malloc(sizeof(struct symbol)); 123 | oursym->name= strdup(name); 124 | /* If it starts with l[0-9], it's a branch */ 125 | if (name[0]=='l' && name[1] >= '0' && name[1] <= '9') 126 | oursym->type= SYM_BRANCH; 127 | else 128 | oursym->type= SYM_FUNCTION; 129 | oursym->size= 0; 130 | isym[S.addr]= oursym; 131 | break; 132 | } 133 | } 134 | fseek(zin, curpos, SEEK_SET); 135 | } 136 | -------------------------------------------------------------------------------- /tools/disaout/syscalls.c: -------------------------------------------------------------------------------- 1 | /* List of system calls, per UNIX version */ 2 | #include "aout.h" 3 | 4 | struct syscallinfo v1syscalls[]= { 5 | { "rele", 0 }, 6 | { "exit", 0 }, 7 | { "fork", 0 }, 8 | { "read", 2 }, 9 | { "write", 2 }, 10 | { "open", 2, }, 11 | { "close", 0 }, 12 | { "wait", 0 }, 13 | { "creat", 2 }, 14 | { "link", 2 }, 15 | { "unlink", 1 }, 16 | { "exec", 2 }, 17 | { "chdir", 1 }, 18 | { "time", 0 }, 19 | { "mkdir", 2 }, 20 | { "chmod", 2 }, 21 | { "chown", 2 }, 22 | { "break", 1 }, 23 | { "stat", 2 }, 24 | { "seek", 2 }, 25 | { "tell", 3 }, 26 | { "mount", 2 }, 27 | { "umount", 1 }, 28 | { "setuid", 1 }, 29 | { "getuid", 1 }, 30 | { "stime", 0 }, 31 | { "quit", 1 }, 32 | { "intr", 1 }, 33 | { "fstat", 2 }, 34 | { "cemt", 1 }, 35 | { "smdate", 1 }, 36 | { "stty", 2 }, 37 | { "gtty", 2 }, 38 | { "ilgins", 1 } 39 | }; 40 | 41 | struct syscallinfo bsd211syscalls[]= { 42 | { "indir", 0 }, 43 | { "exit", 0 }, 44 | { "fork", 0 }, 45 | { "read", 0 }, 46 | { "write", 0 }, 47 | { "open", 0 }, 48 | { "close", 0 }, 49 | { "wait4", 0 }, 50 | { NULL, 0 }, 51 | { "link", 0 }, 52 | { "unlink", 0 }, 53 | { "execv", 0 }, 54 | { "chdir", 0 }, 55 | { "fchdir", 0 }, 56 | { "mknod", 0 }, 57 | { "chmod", 0 }, 58 | { "chown", 0 }, 59 | { "chflags", 0 }, 60 | { "fchflags", 0 }, 61 | { "lseek", 0 }, 62 | { "getpid", 0 }, 63 | { "mount", 0 }, 64 | { "umount", 0 }, 65 | { "__sysctl", 0 }, 66 | { "getuid", 0 }, 67 | { "geteuid", 0 }, 68 | { "ptrace", 0 }, 69 | { "getppid", 0 }, 70 | { NULL, 0 }, 71 | { NULL, 0 }, 72 | { NULL, 0 }, 73 | { "sigaction", 0 }, 74 | { "sigprocmask", 0 }, 75 | { "access", 0 }, 76 | { "sigpending", 0 }, 77 | { "sigaltstack", 0 }, 78 | { "sync", 0 }, 79 | { "kill", 0 }, 80 | { "stat", 0 }, 81 | { "_getlogin", 0 }, 82 | { "lstat", 0 }, 83 | { "dup", 0 }, 84 | { "pipe", 0 }, 85 | { "setlogin", 0 }, 86 | { "profil", 0 }, 87 | { "setuid", 0 }, 88 | { "seteuid", 0 }, 89 | { "getgid", 0 }, 90 | { "getegid", 0 }, 91 | { "setgid", 0 }, 92 | { "setegid", 0 }, 93 | { "acct", 0 }, 94 | { "phys", 0 }, 95 | { "lock", 0 }, 96 | { "ioctl", 0 }, 97 | { "reboot", 0 }, 98 | { NULL, 0 }, 99 | { "symlink", 0 }, 100 | { "readlink", 0 }, 101 | { "execve", 0 }, 102 | { "umask", 0 }, 103 | { "chroot", 0 }, 104 | { "fstat", 0 }, 105 | { NULL, 0 }, 106 | { NULL, 0 }, 107 | { "pselect", 0 }, 108 | { "vfork", 0 }, 109 | { NULL, 0 }, 110 | { NULL, 0 }, 111 | { "sbrk", 0 }, 112 | { NULL, 0 }, 113 | { NULL, 0 }, 114 | { NULL, 0 }, 115 | { NULL, 0 }, 116 | { NULL, 0 }, 117 | { NULL, 0 }, 118 | { "vhangup", 0 }, 119 | { NULL, 0 }, 120 | { NULL, 0 }, 121 | { "getgroups", 0 }, 122 | { "setgroups", 0 }, 123 | { "getpgrp", 0 }, 124 | { "setpgrp", 0 }, 125 | { "setitimer", 0 }, 126 | { NULL, 0 }, 127 | { NULL, 0 }, 128 | { "getitimer", 0 }, 129 | { NULL, 0 }, 130 | { NULL, 0 }, 131 | { "getdtablesize", 0 }, 132 | { "dup2", 0 }, 133 | { NULL, 0 }, 134 | { "fcntl", 0 }, 135 | { "select", 0 }, 136 | { NULL, 0 }, 137 | { "fsync", 0 }, 138 | { "setpriority", 0 }, 139 | { "socket", 0 }, 140 | { "connect", 0 }, 141 | { "accept", 0 }, 142 | { "getpriority", 0 }, 143 | { "send", 0 }, 144 | { "recv", 0 }, 145 | { "sigreturn", 0 }, 146 | { "bind", 0 }, 147 | { "setsockopt", 0 }, 148 | { "listen", 0 }, 149 | { "sigsuspend", 0 }, 150 | { NULL, 0 }, 151 | { NULL, 0 }, 152 | { NULL, 0 }, 153 | { NULL, 0 }, 154 | { "old sigstack", 0 }, 155 | { "recvmsg", 0 }, 156 | { "sendmsg", 0 }, 157 | { NULL, 0 }, 158 | { "gettimeofday", 0 }, 159 | { "getrusage", 0 }, 160 | { "getsockopt", 0 }, 161 | { NULL, 0 }, 162 | { "readv", 0 }, 163 | { "writev", 0 }, 164 | { "settimeofday", 0 }, 165 | { "fchown", 0 }, 166 | { "fchmod", 0 }, 167 | { "recvfrom", 0 }, 168 | { NULL, 0 }, 169 | { NULL, 0 }, 170 | { "rename", 0 }, 171 | { "truncate", 0 }, 172 | { "ftruncate", 0 }, 173 | { "flock", 0 }, 174 | { NULL, 0 }, 175 | { "sendto", 0 }, 176 | { "shutdown", 0 }, 177 | { "socketpair", 0 }, 178 | { "mkdir", 0 }, 179 | { "rmdir", 0 }, 180 | { "utimes", 0 }, 181 | { NULL, 0 }, 182 | { "adjtime", 0 }, 183 | { "getpeername", 0 }, 184 | { NULL, 0 }, 185 | { NULL, 0 }, 186 | { "getrlimit", 0 }, 187 | { "setrlimit", 0 }, 188 | { "killpg", 0 }, 189 | { NULL, 0 }, 190 | { "setquota", 0 }, 191 | { "quota", 0 }, 192 | { "getsockname", 0 }, 193 | { NULL, 0 }, 194 | { "nostk", 0 }, 195 | { "fetchi", 0 }, 196 | { "ucall", 0 }, 197 | { "fperr", 0 }, 198 | }; 199 | 200 | struct syscallinfo *systab=v1syscalls; /* Pointer to one of the following tables */ 201 | int numsyscalls= 34; 202 | --------------------------------------------------------------------------------