#include rti=2 iot=4 nop=240 .data . = . + 6000 / this code is actually origined to 0146000 getovr: jmp reado /jmp to overlay reading routine getdat: jmp readd /jmp to file reading routine chrget: jmp getchar /jmp to RT-11 .TTYIN emulator chrput: jmp putchar /jmp to RT-11 .TTYOUT emulator printit: jmp .print /jmp to RT-11 .PRINT emulator / setup registers and start pgm where it was interrupted start: mov sp,r0 1: tst (r0)+ /calculate environment pointer bne 1b tst (r0)+ mov r0,environ /save environment pointer sys SYS_getuid. /setuid back to user's mov r0,-(sp) clr -(sp) sys SYS_setuid. sys SYS_getgid. mov r0,2(sp) sys SYS_setgid. cmp (sp)+,(sp)+ clr (sp) mov $emtvec,-(sp) mov $7,-(sp) /7 is EMT mov $sigtramp,-(sp) tst -(sp) sys SYS_sigaction. /intercept EMTs add $10,sp mov $timval,-(sp) tst -(sp) sys SYS_gettimeofday. /get time-of-day cmp (sp)+,(sp)+ mov hival,otime /save high order mov lowval,otime+2 /save low order clr -(sp) /We have to use sigstack mov sp,sigstk /because 2.10 won't use mov $sigstk,-(sp) /a signal stack on the tst -(sp) /normal process stack unless sys SYS_sigstack. /it's inside the allocated add $6,sp /stack area. mov $4,r0 mov $140232,r1 mov $1,r2 mov $140442,r3 /from .SETTOP ?? mov $137724,r4 mov $20670,r5 mov $1102,sp jmp *$17332 sigtramp: jsr pc,(r0) /Signal trampoline for sigaction mov sp,r0 add $6,r0 mov r0,-(sp) tst -(sp) sys SYS_sigreturn. iot sigstk: 0 /Structure for sigstack call 0 emtvec: emtrap /interception routine 0; 0 /Bit 6 is EMT (7) 1 /Flag to run on our own signal stack timval: /Two longs in timeval hival: 0 lowval: 0; 0; 0 otime: 0; 0 /time at pgm start-up / environment pointer environ: 0 / file discriptor numbers ofd: 5 /doveraly open on fd5 (original RT-11 pgm) ifd: 4 /dindex.dat open on fd4 tfd: 3 /dtext.dat open on fd3 / disk i/o comes here reado: mov ofd,fd /load fd with overaly chan file discrip br readw /branch to common read routine readd: cmp *(sp),$0 /check for chan 0 (dindex.dat) bne 1f /skip if not mov ifd,fd /load index file discriptor br readw 1: cmp *(sp),$1 /check for chan 1 (dtext.dat) bne 2f /Oh oh! mov tfd,fd /load text file discriptor br readw 2: iot /bomb-out with dump / read common routine readw: mov (sp)+,retaddr /save return address mov r1,-(sp) /save r1 from mul mul $512.,r0 /block offset to byte offset clr -(sp) /offset is from beginning of file mov r1,-(sp) /store low word of offset on stack mov r0,-(sp) /and high word at next word on stack mov (pc)+,-(sp) /put file discriptor on stack fd: -1 /file discriptor tst -(sp) sys SYS_lseek. /seek to proper disk block add $12,sp /restore stack mov (sp)+,r1 /restore r1 mov (sp)+,r0 /load address for read asl (sp) /convert word count to byte count mov r0,-(sp) /put address on stack mov fd,-(sp) /load file discriptor on stack tst -(sp) sys SYS_read. add $12,sp /clean-up jmp *(pc)+ /return retaddr: -1 /return address / character input routine (.TTYIN) getchar: mov $1,-(sp) /read 1 character mov $char,-(sp) /into char clr -(sp) /read from standard input (0) tst -(sp) sys SYS_read. /read 1 character add $10,sp /clean up / special command processing tst r0 /EOF? bne 1f /nope sys SYS_exit. /yup 1: mov char,r0 /pick-up char cmp lastch,$'\n /last char a newline? bne 4f /nope - we're done cmp r0,$'> /save game? bne 2f /nope jsr pc,save br getchar 2: cmp r0,$'< /restore game? bne 3f /nope jsr pc,restor br getchar 3: cmp r0,$'! /escape to UNIX sh? beq 6f /yes! - go fork 4: mov r0,(pc)+ /save last char lastch: '\n cmp $12,r0 /char a linefeed (newline)? bne 5f /no mov $15,r0 /map LF to CR 5: rts pc /back to dungeon 6: sys SYS_fork. /fork! br child /daughter task returns here /parent returns here mov r1,-(sp) /protect r1 from wait clr -(sp) / rusage clr -(sp) / options clr -(sp) / status mov $-1,-(sp) / wpid tst -(sp) / fake return address sys SYS_wait4. / wait for daughter to complete add $5*2,sp mov (sp)+,r1 /restore r1 mov $3,-(sp) /write prompt when through mov $prom,-(sp) mov $1,-(sp) tst -(sp) sys SYS_write. add $10,sp br getchar /go get more input prom: > /input prompt characters .even / the following code is run by the daughter task child: clr -(sp) mov $sigdef,-(sp) mov $2,-(sp) /SIGQUIT clr -(sp) /no trampoline routine clr -(sp) /2.11 interface (return @) sys SYS_sigaction. add $12,sp mov environ,-(sp) /set environ pointer mov $shargs,-(sp) mov $shname,-(sp) tst -(sp) sys SYS_execve. /process "!" command line add $10,sp sys SYS_exit. sigdef: 0; 0; 0; 0 shname: .even shargs: sharg0; sharg1; 0 sharg0: <-c\0> sharg1: <-t\0> .even / save game save: tst -(sp) mov $600,-(sp) /mode mov $601,-(sp) /O_CREAT|O_TRUNC|O_WRONLY mov $savfil,-(sp) /path tst -(sp) /2.11 syscall convention sys SYS_open. /create output file bcc 1f /oops / this bit of nonsense is needed because 'serr' insists that all syscalls / take 10(8) bytes of stack. SYS_open takes 12 so we advance sp by 2 if the / open failed. Stuff a -1 in the return value so the check for failure can / / be made. Isn't assembly fun?! . tst (sp)+ br serr 1: add $12,sp mov r0,(pc)+ /save "save" file discriptor sfd: -1 / "save" file discriptor mov $17812.,-(sp) mov $22410,-(sp) mov r0,-(sp) tst -(sp) sys SYS_write. /write out data bcs rwerr /branch on error add $10,sp mov sfd,-(sp) /load "save" file discriptor tst -(sp) sys SYS_close. /close "save" file cmp (sp)+,(sp)+ mov $11.,-(sp) mov $svmsg,-(sp) mov $1,-(sp) /load standard output fd tst -(sp) sys SYS_write. /convey success add $10,sp rts pc /return svmsg: /success message .even / restore game restor: tst -(sp) clr -(sp) mov $savfil,-(sp) tst -(sp) sys SYS_open. /open "save" file bcs serr /branch on error add $10,sp mov r0,sfd /store "save" file fd mov $17812.,-(sp) mov $22410,-(sp) mov r0,-(sp) tst -(sp) sys SYS_read. /read data bcs rwerr /branch on failure add $10,sp mov sfd,-(sp) /load "save" file fd tst -(sp) sys SYS_close. /close the file cmp (sp)+,(sp)+ mov $14.,-(sp) mov $rsmsg,-(sp) mov $1,-(sp) /load char output fd sys SYS_write. /report success add $6,sp rts pc /return rsmsg: savfil: / "save" file name .even / open, read & write errors come here rwerr: mov sfd,-(sp) /close file on read/write error tst -(sp) sys SYS_close. cmp (sp)+,(sp)+ serr: add $10,sp mov $7.,-(sp) mov $ermsg,-(sp) mov $1,-(sp) /using standard output tst -(sp) sys SYS_write. / write "ERROR" message add $10,sp rts pc /return (exit for child) ermsg: .even / RT-11 .TTYOUT emulator putchar: mov r0,(pc)+ /save character char: 0 /char to print mov $1,-(sp) /write one character mov $char,-(sp) mov $1,-(sp) /load terminal output fd tst -(sp) sys SYS_write. /write it out add $10,sp rts pc /return / RT-11 .PRINT emulator .print: mov r1,-(sp) /save r1 & r2 mov r2,-(sp) mov r0,r1 /scan for terminator (right 7 bits 0) 1: movb (r1)+,r2 bic $177600,r2 bne 1b / terminator found movb -(r1),r2 /save terminator sub r0,r1 /size of string to output mov r1,-(sp) /save count mov r0,-(sp) mov $1,-(sp) /write to standard output tst -(sp) sys SYS_write. add $10,sp tstb r2 /skip crlf if 200 bit set in terminator bmi 2f mov $2,-(sp) mov $crlf,-(sp) mov $1,-(sp) tst -(sp) sys SYS_write. /output crlf add $10,sp 2: mov (sp)+,r2 /restore registers mov (sp)+,r1 rts pc crlf: <\r\n> .even emtrap: mov 6(sp),r0 /Get sigcontext mov 14(r0),-(sp) /Put old r0 on stack mov 16(r0),r0 /Pull old pc off stack cmp $104350,-(r0) /Check for EMT 350 beq .exit /Exit if it is. cmp $104375,(r0) /if EMT not 375 bne 3f / then abort with dump mov (sp),r0 /check for .GTIM cmp $10400,(r0) bne 1f tst (r0)+ /bump r0 mov r1,-(sp) /save r1 mov r2,-(sp) /save r2 mov (r0),r2 /get pointer clr -(sp) mov $timval,-(sp) tst -(sp) sys SYS_gettimeofday. /get current time add $6,sp mov lowval,r1 mov hival,r0 sub otime+2,r1 /subtract low order sbc r0 sub otime,r0 /subtract high order mov r1,-(sp) /save low order mul $60,r0 /convert seconds to ticks mov r1,(r2) /store high order mov (sp)+,r0 /restore low order mul $60,r0 /mult low order by 60 mov r1,2(r2) /store low in low order add r0,(r2) /add high to high add $6223,2(r2) /add fudge factor adc (r2) mov (sp)+,r2 /restore r2 & r1 mov (sp)+,r1 jbr 2f /go return from interrupt 1: cmp $16000,(r0)+ /check if .GVAL bne 3f cmp $300,(r0) /do .GVAL only of 300 bne 3f mov $121100,(sp) /load fake RT-11 config word 2: mov (sp)+,r0 /restore r0 rts pc /Return From Interrupt 3: mov (r0),r1 /Get emt number bic $177077,r1 /Fix up error message ash $-6,r1 add $60,r1 movb r1,emt mov (r0),r1 /Get emt number bic $177707,r1 /Fix up error message ash $-3,r1 add $60,r1 movb r1,emt+1 mov (r0),r1 /Get emt number bic $177770,r1 /Fix up error message add $60,r1 movb r1,emt+2 jsr pc,save /save game before blow-up mov $core62,-(sp) tst -(sp) sys SYS_chdir. /put core dump in special place cmp (sp)+,(sp)+ mov $29.,-(sp) /Write an explaination out mov $emtmsg,-(sp) mov $1,-(sp) tst -(sp) sys SYS_write. add $10,sp mov (sp)+,r0 /restore r0 rts pc /return emtmsg: emt: < kills you.\n> core62: .even /.EXIT emulator with a minor cleanup .exit: mov $2,-(sp) mov $crlf,-(sp) mov $1,-(sp) tst -(sp) sys SYS_write. sys SYS_exit.