1: #include <syscall.h> 2: rti=2 3: iot=4 4: nop=240 5: 6: .data 7: . = . + 6000 8: / this code is actually origined to 0146000 9: 10: getovr: 11: jmp reado /jmp to overlay reading routine 12: getdat: 13: jmp readd /jmp to file reading routine 14: chrget: 15: jmp getchar /jmp to RT-11 .TTYIN emulator 16: chrput: 17: jmp putchar /jmp to RT-11 .TTYOUT emulator 18: printit: 19: jmp .print /jmp to RT-11 .PRINT emulator 20: 21: / setup registers and start pgm where it was interrupted 22: 23: start: 24: mov sp,r0 25: 1: tst (r0)+ /calculate environment pointer 26: bne 1b 27: tst (r0)+ 28: mov r0,environ /save environment pointer 29: sys SYS_getuid. /setuid back to user's 30: mov r0,-(sp) 31: clr -(sp) 32: sys SYS_setuid. 33: sys SYS_getgid. 34: mov r0,2(sp) 35: sys SYS_setgid. 36: cmp (sp)+,(sp)+ 37: 38: clr (sp) 39: mov $emtvec,-(sp) 40: mov $7,-(sp) /7 is EMT 41: mov $sigtramp,-(sp) 42: tst -(sp) 43: sys SYS_sigaction. /intercept EMTs 44: add $10,sp 45: 46: mov $timval,-(sp) 47: tst -(sp) 48: sys SYS_gettimeofday. /get time-of-day 49: cmp (sp)+,(sp)+ 50: mov hival,otime /save high order 51: mov lowval,otime+2 /save low order 52: 53: clr -(sp) /We have to use sigstack 54: mov sp,sigstk /because 2.10 won't use 55: mov $sigstk,-(sp) /a signal stack on the 56: tst -(sp) /normal process stack unless 57: sys SYS_sigstack. /it's inside the allocated 58: add $6,sp /stack area. 59: 60: mov $4,r0 61: mov $140232,r1 62: mov $1,r2 63: mov $140442,r3 /from .SETTOP ?? 64: mov $137724,r4 65: mov $20670,r5 66: mov $1102,sp 67: 68: jmp *$17332 69: 70: sigtramp: 71: jsr pc,(r0) /Signal trampoline for sigaction 72: mov sp,r0 73: add $6,r0 74: mov r0,-(sp) 75: tst -(sp) 76: sys SYS_sigreturn. 77: iot 78: 79: sigstk: 0 /Structure for sigstack call 80: 0 81: 82: emtvec: 83: emtrap /interception routine 84: 0; 0 /Bit 6 is EMT (7) 85: 1 /Flag to run on our own signal stack 86: 87: timval: /Two longs in timeval 88: hival: 0 89: lowval: 0; 0; 0 90: otime: 0; 0 /time at pgm start-up 91: 92: / environment pointer 93: environ: 0 94: 95: / file discriptor numbers 96: 97: ofd: 5 /doveraly open on fd5 (original RT-11 pgm) 98: ifd: 4 /dindex.dat open on fd4 99: tfd: 3 /dtext.dat open on fd3 100: 101: / disk i/o comes here 102: 103: reado: 104: mov ofd,fd /load fd with overaly chan file discrip 105: br readw /branch to common read routine 106: 107: readd: 108: cmp *(sp),$0 /check for chan 0 (dindex.dat) 109: bne 1f /skip if not 110: mov ifd,fd /load index file discriptor 111: br readw 112: 113: 1: cmp *(sp),$1 /check for chan 1 (dtext.dat) 114: bne 2f /Oh oh! 115: mov tfd,fd /load text file discriptor 116: br readw 117: 118: 2: iot /bomb-out with dump 119: 120: / read common routine 121: 122: readw: 123: mov (sp)+,retaddr /save return address 124: mov r1,-(sp) /save r1 from mul 125: mul $512.,r0 /block offset to byte offset 126: clr -(sp) /offset is from beginning of file 127: mov r1,-(sp) /store low word of offset on stack 128: mov r0,-(sp) /and high word at next word on stack 129: 130: mov (pc)+,-(sp) /put file discriptor on stack 131: fd: -1 /file discriptor 132: tst -(sp) 133: sys SYS_lseek. /seek to proper disk block 134: add $12,sp /restore stack 135: mov (sp)+,r1 /restore r1 136: mov (sp)+,r0 /load address for read 137: asl (sp) /convert word count to byte count 138: mov r0,-(sp) /put address on stack 139: mov fd,-(sp) /load file discriptor on stack 140: tst -(sp) 141: sys SYS_read. 142: add $12,sp /clean-up 143: jmp *(pc)+ /return 144: retaddr: -1 /return address 145: 146: / character input routine (.TTYIN) 147: 148: getchar: 149: mov $1,-(sp) /read 1 character 150: mov $char,-(sp) /into char 151: clr -(sp) /read from standard input (0) 152: tst -(sp) 153: sys SYS_read. /read 1 character 154: add $10,sp /clean up 155: 156: / special command processing 157: 158: tst r0 /EOF? 159: bne 1f /nope 160: sys SYS_exit. /yup 161: 1: 162: mov char,r0 /pick-up char 163: cmp lastch,$'\n /last char a newline? 164: bne 4f /nope - we're done 165: 166: cmp r0,$'> /save game? 167: bne 2f /nope 168: jsr pc,save 169: br getchar 170: 2: 171: cmp r0,$'< /restore game? 172: bne 3f /nope 173: jsr pc,restor 174: br getchar 175: 3: 176: cmp r0,$'! /escape to UNIX sh? 177: beq 6f /yes! - go fork 178: 4: 179: mov r0,(pc)+ /save last char 180: lastch: '\n 181: cmp $12,r0 /char a linefeed (newline)? 182: bne 5f /no 183: mov $15,r0 /map LF to CR 184: 5: 185: rts pc /back to dungeon 186: 187: 6: 188: sys SYS_fork. /fork! 189: br child /daughter task returns here 190: /parent returns here 191: 192: mov r1,-(sp) /protect r1 from wait 193: 194: clr -(sp) / rusage 195: clr -(sp) / options 196: clr -(sp) / status 197: mov $-1,-(sp) / wpid 198: tst -(sp) / fake return address 199: sys SYS_wait4. / wait for daughter to complete 200: add $5*2,sp 201: mov (sp)+,r1 /restore r1 202: 203: mov $3,-(sp) /write prompt when through 204: mov $prom,-(sp) 205: mov $1,-(sp) 206: tst -(sp) 207: sys SYS_write. 208: add $10,sp 209: br getchar /go get more input 210: 211: prom: <!\n\>> /input prompt characters 212: .even 213: 214: / the following code is run by the daughter task 215: child: 216: clr -(sp) 217: mov $sigdef,-(sp) 218: mov $2,-(sp) /SIGQUIT 219: clr -(sp) /no trampoline routine 220: clr -(sp) /2.11 interface (return @) 221: sys SYS_sigaction. 222: add $12,sp 223: 224: mov environ,-(sp) /set environ pointer 225: mov $shargs,-(sp) 226: mov $shname,-(sp) 227: tst -(sp) 228: sys SYS_execve. /process "!" command line 229: add $10,sp 230: sys SYS_exit. 231: 232: sigdef: 233: 0; 0; 0; 0 234: 235: shname: </bin/sh\0> 236: .even 237: shargs: sharg0; sharg1; 0 238: sharg0: <-c\0> 239: sharg1: <-t\0> 240: .even 241: 242: / save game 243: 244: save: 245: tst -(sp) 246: mov $600,-(sp) /mode 247: mov $601,-(sp) /O_CREAT|O_TRUNC|O_WRONLY 248: mov $savfil,-(sp) /path 249: tst -(sp) /2.11 syscall convention 250: sys SYS_open. /create output file 251: bcc 1f /oops 252: 253: / this bit of nonsense is needed because 'serr' insists that all syscalls 254: / take 10(8) bytes of stack. SYS_open takes 12 so we advance sp by 2 if the 255: / open failed. Stuff a -1 in the return value so the check for failure can / 256: / be made. Isn't assembly fun?! <grin>. 257: 258: tst (sp)+ 259: br serr 260: 1: 261: add $12,sp 262: mov r0,(pc)+ /save "save" file discriptor 263: sfd: -1 / "save" file discriptor 264: mov $17812.,-(sp) 265: mov $22410,-(sp) 266: mov r0,-(sp) 267: tst -(sp) 268: sys SYS_write. /write out data 269: bcs rwerr /branch on error 270: add $10,sp 271: mov sfd,-(sp) /load "save" file discriptor 272: tst -(sp) 273: sys SYS_close. /close "save" file 274: cmp (sp)+,(sp)+ 275: mov $11.,-(sp) 276: mov $svmsg,-(sp) 277: mov $1,-(sp) /load standard output fd 278: tst -(sp) 279: sys SYS_write. /convey success 280: add $10,sp 281: rts pc /return 282: 283: svmsg: <Game saved\n> /success message 284: .even 285: 286: / restore game 287: 288: restor: 289: tst -(sp) 290: clr -(sp) 291: mov $savfil,-(sp) 292: tst -(sp) 293: sys SYS_open. /open "save" file 294: bcs serr /branch on error 295: add $10,sp 296: mov r0,sfd /store "save" file fd 297: mov $17812.,-(sp) 298: mov $22410,-(sp) 299: mov r0,-(sp) 300: tst -(sp) 301: sys SYS_read. /read data 302: bcs rwerr /branch on failure 303: add $10,sp 304: mov sfd,-(sp) /load "save" file fd 305: tst -(sp) 306: sys SYS_close. /close the file 307: cmp (sp)+,(sp)+ 308: mov $14.,-(sp) 309: mov $rsmsg,-(sp) 310: mov $1,-(sp) /load char output fd 311: sys SYS_write. /report success 312: add $6,sp 313: rts pc /return 314: 315: rsmsg: <Game restored\n> 316: 317: savfil: <dungeon.dat\0> / "save" file name 318: .even 319: 320: / open, read & write errors come here 321: 322: rwerr: 323: mov sfd,-(sp) /close file on read/write error 324: tst -(sp) 325: sys SYS_close. 326: cmp (sp)+,(sp)+ 327: serr: 328: add $10,sp 329: mov $7.,-(sp) 330: mov $ermsg,-(sp) 331: mov $1,-(sp) /using standard output 332: tst -(sp) 333: sys SYS_write. / write "ERROR" message 334: add $10,sp 335: rts pc /return (exit for child) 336: 337: ermsg: <Error\n> 338: .even 339: 340: / RT-11 .TTYOUT emulator 341: 342: putchar: 343: mov r0,(pc)+ /save character 344: char: 0 /char to print 345: mov $1,-(sp) /write one character 346: mov $char,-(sp) 347: mov $1,-(sp) /load terminal output fd 348: tst -(sp) 349: sys SYS_write. /write it out 350: add $10,sp 351: rts pc /return 352: 353: / RT-11 .PRINT emulator 354: 355: .print: 356: mov r1,-(sp) /save r1 & r2 357: mov r2,-(sp) 358: mov r0,r1 /scan for terminator (right 7 bits 0) 359: 1: 360: movb (r1)+,r2 361: bic $177600,r2 362: bne 1b 363: 364: / terminator found 365: 366: movb -(r1),r2 /save terminator 367: sub r0,r1 /size of string to output 368: mov r1,-(sp) /save count 369: mov r0,-(sp) 370: mov $1,-(sp) /write to standard output 371: tst -(sp) 372: sys SYS_write. 373: add $10,sp 374: tstb r2 /skip crlf if 200 bit set in terminator 375: bmi 2f 376: mov $2,-(sp) 377: mov $crlf,-(sp) 378: mov $1,-(sp) 379: tst -(sp) 380: sys SYS_write. /output crlf 381: add $10,sp 382: 2: 383: mov (sp)+,r2 /restore registers 384: mov (sp)+,r1 385: rts pc 386: 387: crlf: <\r\n> 388: .even 389: 390: emtrap: 391: mov 6(sp),r0 /Get sigcontext 392: mov 14(r0),-(sp) /Put old r0 on stack 393: mov 16(r0),r0 /Pull old pc off stack 394: cmp $104350,-(r0) /Check for EMT 350 395: beq .exit /Exit if it is. 396: cmp $104375,(r0) /if EMT not 375 397: bne 3f / then abort with dump 398: 399: mov (sp),r0 /check for .GTIM 400: cmp $10400,(r0) 401: bne 1f 402: tst (r0)+ /bump r0 403: mov r1,-(sp) /save r1 404: mov r2,-(sp) /save r2 405: mov (r0),r2 /get pointer 406: 407: clr -(sp) 408: mov $timval,-(sp) 409: tst -(sp) 410: sys SYS_gettimeofday. /get current time 411: add $6,sp 412: mov lowval,r1 413: mov hival,r0 414: 415: sub otime+2,r1 /subtract low order 416: sbc r0 417: sub otime,r0 /subtract high order 418: mov r1,-(sp) /save low order 419: mul $60,r0 /convert seconds to ticks 420: mov r1,(r2) /store high order 421: mov (sp)+,r0 /restore low order 422: mul $60,r0 /mult low order by 60 423: mov r1,2(r2) /store low in low order 424: add r0,(r2) /add high to high 425: add $6223,2(r2) /add fudge factor 426: adc (r2) 427: mov (sp)+,r2 /restore r2 & r1 428: mov (sp)+,r1 429: jbr 2f /go return from interrupt 430: 1: 431: cmp $16000,(r0)+ /check if .GVAL 432: bne 3f 433: cmp $300,(r0) /do .GVAL only of 300 434: bne 3f 435: mov $121100,(sp) /load fake RT-11 config word 436: 2: 437: mov (sp)+,r0 /restore r0 438: rts pc /Return From Interrupt 439: 3: 440: mov (r0),r1 /Get emt number 441: bic $177077,r1 /Fix up error message 442: ash $-6,r1 443: add $60,r1 444: movb r1,emt 445: mov (r0),r1 /Get emt number 446: bic $177707,r1 /Fix up error message 447: ash $-3,r1 448: add $60,r1 449: movb r1,emt+1 450: mov (r0),r1 /Get emt number 451: bic $177770,r1 /Fix up error message 452: add $60,r1 453: movb r1,emt+2 454: 455: jsr pc,save /save game before blow-up 456: mov $core62,-(sp) 457: tst -(sp) 458: sys SYS_chdir. /put core dump in special place 459: cmp (sp)+,(sp)+ 460: mov $29.,-(sp) /Write an explaination out 461: mov $emtmsg,-(sp) 462: mov $1,-(sp) 463: tst -(sp) 464: sys SYS_write. 465: add $10,sp 466: mov (sp)+,r0 /restore r0 467: rts pc /return 468: 469: emtmsg: 470: <A vicious emt > 471: emt: <xxx> 472: < kills you.\n> 473: 474: core62: 475: </usr/games/lib/coredumps\0> 476: .even 477: 478: /.EXIT emulator with a minor cleanup 479: .exit: 480: mov $2,-(sp) 481: mov $crlf,-(sp) 482: mov $1,-(sp) 483: tst -(sp) 484: sys SYS_write. 485: sys SYS_exit.