|
|
1.1 ! root 1: /* ! 2: * This version of kmc-cpu interface uses two circular buffers. ! 3: * Cmdbuf is used to pass command to kmc; ! 4: * statbuf is used to report status. ! 5: * Csr4~5 are the head/tail of the cmdbuf, and csr6~7 for statbuf. ! 6: * ! 7: * When csr0 is 0, kmc is idle and does nothing. ! 8: * The cpu will set csr to 1 and pass cmdbuf/statbuf addresses ! 9: * in csr4~7. ! 10: * Then the kmc will set csr0 to 2 and stay at this state forever. ! 11: * ! 12: * ! 13: * Permanently assigned registers: ! 14: * ! 15: * Channel dependent assigned registers: ! 16: * ! 17: * r14 - free kmc queue pointer ! 18: * r9 - channel # ! 19: * r8 - group number currently being serviced ! 20: * r10 - address of current line-table entry ! 21: */ ! 22: ! 23: #define C_RLEN 0 /* read length */ ! 24: #define C_RADDR 2 /* read address */ ! 25: #define C_RULEN 5 /* uncheck input in RADDR */ ! 26: #define C_XLEN 7 /* write length */ ! 27: #define C_XADDR 9 /* write address */ ! 28: #define C_RQ 12 /* un-ack input: in host memory */ ! 29: #define C_RBLEN 13 /* length */ ! 30: #define C_RB 15 /* un-check input: waiting for trailer */ ! 31: #define C_S 16 /* next seq# to be sent */ ! 32: #define C_R 17 /* last seq# echoed */ ! 33: #define C_A 18 /* last seq# acked */ ! 34: #define C_C 19 /* last seq# received */ ! 35: #define C_TA0 20 /* trailer: BOT/BOTM/BOTS/SOI */ ! 36: #define C_TA1 21 /* len of trailer data */ ! 37: #define C_TA2 22 /* 1st byte of trailer/SOI data */ ! 38: #define C_TA3 23 /* 2nd byte of trailer/SOI data */ ! 39: #define C_RSEQ 24 /* seq# for this block */ ! 40: #define C_XCNTL 25 /* cntl char following the data */ ! 41: #define C_X 26 /* state of the chan */ ! 42: #define C_X1 27 /* state of the chan (ovf from C_X) */ ! 43: #define C_Y 28 /* input state */ ! 44: #define C_ITIME 29 /* timer for last char input */ ! 45: #define C_INITIM 30 /* initial value for ITIME */ ! 46: ! 47: /* ! 48: * define bits in C_X ! 49: * bits 0-2 are exclusive ! 50: */ ! 51: #define XIDLE (1<<0) /* chan is uninitialized */ ! 52: #define XACT (1<<1) /* chan is initialized */ ! 53: #define XINIT (1<<2) /* chan is in the init stage */ ! 54: /* ! 55: * define bits in C_X1 (overflowed from C_X) ! 56: */ ! 57: #define XNIL (1<<0) /* send trailer only */ ! 58: #define XREJ (1<<3) /* hasn't rcv ECHO since last REJ */ ! 59: #define XBLK (1<<4) /* set if block mode, else char mode */ ! 60: #define XENQ (1<<5) /* has sent ENQ and not rcv ECHO yet */ ! 61: #define XACK (1<<6) /* C_S has been incremented since ENQ/CHECK */ ! 62: #define XBOTM (1<<7) /* send BOTM (instead of BOT) */ ! 63: /* ! 64: * define bits in C_Y ! 65: */ ! 66: #define YTIMACT (1<<0) /* timer active */ ! 67: #define YEXPIRE (1<<1) /* timer expires */ ! 68: #define YBLOCK (1<<5) /* rcv return on block boundary */ ! 69: #define YTIME (1<<6) /* rcv return on time expires */ ! 70: /* ! 71: * Define useful constants ! 72: */ ! 73: #define NIL 0377 ! 74: #define NULL 0377 ! 75: #define NUL 0377 ! 76: #define ZERO 0 ! 77: /* ! 78: * Datakit and protocol related constant ! 79: */ ! 80: #define DKCHUNK 16 /* packet size - don't change */ ! 81: #define CHANMODS 96 /* # of channels per module */ ! 82: #define NGRP CHANMODS/8-1 /* # of bytes for bit map */ ! 83: #define BUFSIZ 10 /* size of cmdbuf, statbuf, etc */ ! 84: #define MAXBADPK 64 /* bad packet received before complaining */ ! 85: #define DKBMASK 03 /* seq # is 0 to 3 */ ! 86: #define WINDOW 07 /* max window size */ ! 87: #define DKBLOCK 28 /* block size before trailer */ ! 88: #define BSIZE 64 /* size (9-bits) of each host buffer */ ! 89: #define BSIZE2 BSIZE*2 /* size in bytes */ ! 90: /* ! 91: * protocol cntl patterns ! 92: */ ! 93: #define I_SEQ 0010 /* 8 sequence numbers to end trailers */ ! 94: #define I_ECHO 0020 /* 8 echoes, data given to host */ ! 95: #define I_REJ 0030 /* 8 rejections, transmission error */ ! 96: #define I_ACK 0040 /* first of 8 acks, correct reception */ ! 97: #define I_BOT 0050 /* normal beginning of trailer */ ! 98: #define I_BOTM 0051 /* trailer with more data to follow */ ! 99: #define I_BOTS 0052 /* seq update algorithm on this trailer */ ! 100: #define I_SOI 0053 /* start of interrupt trailer */ ! 101: #define I_EOI 0054 /* end of interrupt trailer */ ! 102: #define I_ENQ 0055 /* xmitter request flow/error status */ ! 103: #define I_CHECK 0056 /* xmitter request error status */ ! 104: #define I_INITREQ 0057 /* request initialization */ ! 105: #define I_INIT0 0060 /* disable trailer processing */ ! 106: #define I_INIT1 0061 /* enable trailer processing */ ! 107: #define I_AINIT 0062 /* response to INIT0/INIT1 */ ! 108: /* ! 109: * command type ! 110: */ ! 111: #define KC_INIT 1 /* init: 0,0,0,0 */ ! 112: #define KC_SEND 2 /* send: len, cntl, mode, addr */ ! 113: #define KC_RCVB 3 /* rcv: len, time, mode, addr */ ! 114: #define KC_CLOSE 4 /* close: 0, 0, 0, 0 */ ! 115: #define KC_XINIT 5 /* re-init xmitter: 0, 0, 0, 0 */ ! 116: #define KC_CMD 6 /* cmd to kmc: cmd, 0, 0, 0 */ ! 117: #define KC_FLAG 7 /* i/oflag: iflag, oflaghi, oflaglo, 0 */ ! 118: #define KC_SOI 8 /* send express: (byte2<<8)|byte1, 0, 0, 0 */ ! 119: #define KC_TDK 9 /* send to tdk: ctl, 0, 0, 0 */ ! 120: /* ! 121: * report type ! 122: */ ! 123: #define KS_SEND 20 /* send: 0, 0, 0, 0 */ ! 124: #define KS_RDB 21 /* rcv: residue len, cntl, mode, 0 */ ! 125: #define KS_EOI 22 /* rcv express: (byte2<<8)|byte1, 0, 0, 0 */ ! 126: #define KS_CNTL 23 /* rcv tdk cntl: 0, cntl, 0, 0 */ ! 127: #define KS_ERR 24 /* error: code, 0, 0, 0 */ ! 128: /* ! 129: * sub command bits for KC_CMD ! 130: */ ! 131: #define OFLUSH (1<<1) /* Flush output */ ! 132: #define OSPND (1<<2) /* Suspend output */ ! 133: #define ORSME (1<<3) /* Resume output */ ! 134: /* ! 135: * KC_RCVB mode ! 136: */ ! 137: #define CBLOCK (1<<5) /* return on block boundary */ ! 138: #define CTIME (1<<6) /* return on time expires */ ! 139: /* ! 140: * KS_RDB mode ! 141: */ ! 142: #define SFULL (1<<0) /* buffer full */ ! 143: #define SCNTL (1<<1) /* cntl char rcv */ ! 144: #define SABORT (1<<3) /* rcv aborted */ ! 145: #define SBLOCK (1<<5) /* block boundary */ ! 146: #define STIME (1<<6) /* timer expires */ ! 147: /* ! 148: * define bit pattern ! 149: */ ! 150: #define BIT0 (1<<0) ! 151: #define BIT1 (1<<1) ! 152: #define BIT2 (1<<2) ! 153: #define BIT3 (1<<3) ! 154: #define BIT4 (1<<4) ! 155: #define BIT5 (1<<5) ! 156: #define BIT6 (1<<6) ! 157: #define BIT7 (1<<7) ! 158: ! 159: #define CLT0 0 ! 160: #define CLT1 010 ! 161: #define CLK1MS 16 ! 162: #define R_TIMER 6 /* multiple of 50 us (300us here) */ ! 163: /* ! 164: * head/tail of circular buffers ! 165: */ ! 166: #define HC csr4 /* head of cmdbuf */ ! 167: #define TC csr5 /* tail of cmdbuf */ ! 168: #define HS csr6 /* head of statbuf */ ! 169: #undef TS ! 170: #define TS csr7 /* tail of statbuf */ ! 171: /* ! 172: * Define bits in npr ! 173: */ ! 174: #define NRQ (1<<0) ! 175: #define OUT (1<<4) ! 176: #define BYTE (1<<7) ! 177: /* ! 178: * Define bits in nprx ! 179: */ ! 180: #define NEM (1<<0) ! 181: #define ACLO (1<<1) ! 182: #define PCLK (1<<4) ! 183: #define VEC4 (1<<6) ! 184: #define BRQ (1<<7) ! 185: /* ! 186: * Define check point code ! 187: */ ! 188: #define B0_KCSO (1<<0) /* enter KC_SOI cmd */ ! 189: #define B0_KCCM (1<<1) /* enter KC_CMD cmd */ ! 190: #define B0_KCFG (1<<2) /* enter KC_FLAG cmd */ ! 191: #define B0_KC1 (1<<3) /* enter KC_ONE cmd */ ! 192: #define B0_KCSD (1<<4) /* enter KC_SEND cmd */ ! 193: #define B0_KCRB (1<<5) /* enter KC_RCVB cmd */ ! 194: #define B0_KCIT (1<<6) /* enter KC_INIT cmd */ ! 195: #define B0_KCCS (1<<7) /* enter KC_CLOSE cmd */ ! 196: ! 197: #define B1_ENT (1<<0) /* enter output seg */ ! 198: #define B1_CNTL (1<<1) /* send XCNTL */ ! 199: #define B1_ERO (1<<2) /* enter robin */ ! 200: #define B1_SPK (1<<4) /* issue D_XPACK */ ! 201: #define B1_ENRO (1<<5) /* endrobin */ ! 202: #define B1_EXIT (1<<7) /* exit output */ ! 203: ! 204: #define B2_ENT (1<<0) /* enter input seq */ ! 205: #define B2_CNTL (1<<1) /* control packet */ ! 206: #define B2_SUP (1<<2) /* rcv sup cntl char */ ! 207: #define B2_NWWT (1<<3) /* rcv not well form trailer */ ! 208: #define B2_REP (1<<4) /* KS_RDB interrupt */ ! 209: #define B2_DATA (1<<6) /* data packet */ ! 210: #define B2_EXIT (1<<7) /* exit input seg */ ! 211: ! 212: #define B3_SEQ (1<<0) /* rcv SEQ */ ! 213: #define B3_ECHO (1<<1) /* rcv ECHO */ ! 214: #define B3_ACK (1<<2) /* rcv ACK */ ! 215: #define B3_REJ (1<<3) /* rcv REJ */ ! 216: #define B3_CHK (1<<4) /* rcv CHK */ ! 217: #define B3_ENQ (1<<5) /* rcv ENQ */ ! 218: ! 219: #define B4_EOI (1<<0) /* rcv EOI */ ! 220: #define B4_BOT (1<<1) /* rcv BOT */ ! 221: #define B4_IN1 (1<<2) /* rcv INIT1 */ ! 222: #define B4_IN0 (1<<3) /* rcv INIT0 */ ! 223: #define B4_AIN (1<<4) /* rcv AINIT*/ ! 224: #define B4_IREQ (1<<5) /* rcv INITREQ */ ! 225: ! 226: #define B5_ENT (1<<0) /* enter rcv */ ! 227: #define B5_PLEN (1<<1) /* plen >= RLEN */ ! 228: #define B5_ODD (1<<2) /* r_odd */ ! 229: #define B5_REP (1<<3) /* report READ comp */ ! 230: #define B5_MOVE (1<<4) /* partial buffer */ ! 231: #define B5_AJAX (1<<5) /* enter clean() */ ! 232: #define B5_EXIT (1<<6) /* exit rcv */ ! 233: #define B5_TIME (1<<7) /* timer expires */ ! 234: ! 235: #define B6_POST (1<<0) /* output postprocessing */ ! 236: #define B6_NL (1<<1) /* NL */ ! 237: #define B6_CR (1<<2) /* CR */ ! 238: #define B6_TAB (1<<3) /* TAB */ ! 239: #define B6_BS (1<<4) /* back space */ ! 240: #define B6_VT (1<<5) /* VT */ ! 241: #define B6_FF (1<<6) /* FF */ ! 242: ! 243: #define B7_IFL (1<<0) /* flush input */ ! 244: #define B7_OFL (1<<1) /* flush output */ ! 245: #define B7_OSP (1<<2) /* suspend output */ ! 246: #define B7_ORE (1<<3) /* resume output */ ! 247: #define B7_IUB (1<<4) /* unblock input */ ! 248: #define B7_IBL (1<<5) /* block input */ ! 249: #define B7_BRK (1<<6) /* send break */ ! 250: ! 251: /* ! 252: * Define error codes ! 253: */ ! 254: #define E_SW 00 /* dispatcher switch */ ! 255: #define E_BUS 01 /* Unibus error */ ! 256: #define E_IPANIC 02 /* input routine panic */ ! 257: #define E_CMD 03 /* command unknown */ ! 258: #define E_NOQB 04 /* run out of queue or buffer */ ! 259: #define E_DUP 05 /* duplicate SEND */ ! 260: #define E_ODKOVF 06 /* output routine panic */ ! 261: #define E_UMETA 07 /* un-recognized cntl char */ ! 262: #define E_SYS1 041 /* system error 1 */ ! 263: #define E_SYS2 042 /* system error 2 */ ! 264: ! 265: #ifdef DR11C ! 266: /* ! 267: * specific declarations for dr11-c ! 268: */ ! 269: #define DKRDONE (1<<7) /* 15-th bit */ ! 270: #define DKTDONE (1<<7) /* 7-th bit */ ! 271: #define DKCOM (3<<0) /* 01 bits */ ! 272: #define DKTENAB (1<<6) /* 6-th bit */ ! 273: #define DKRENAB (1<<5) /* 5-th bit */ ! 274: #define DKDATA (1<<0) /* 8-th bit */ ! 275: #define DKMARK (1<<1) /* 9-th bit */ ! 276: #define ILO idl ! 277: #define IHI idh ! 278: #define OLO odl ! 279: #define OHI odh ! 280: #define D_OSEQ 0 ! 281: #define D_READ 1 ! 282: #define D_WRITE 2 ! 283: #define D_XPACK 3 ! 284: #define D_WHEAD (1<<1) /* 9-th bit */ ! 285: #define D_WDATA (1<<0) /* data byte */ ! 286: #define D_WCNTL 0 /* control byte */ ! 287: #endif ! 288: #ifdef KDI ! 289: /* ! 290: * specific declarations for dki board ! 291: */ ! 292: #define ILO lur0 ! 293: #define IHI lur5 ! 294: #define OLO lur0 ! 295: #define OHI lur1 ! 296: #define DKFRDY (1<<0) /* data from dk ready */ ! 297: #define TRQRDY (1<<1) /* seq# rdy: xmit done */ ! 298: #define D_OSEQ (0<<6) ! 299: #define D_RESET (0<<6) ! 300: #define D_READ (1<<6) ! 301: #define D_WHEAD 0202 ! 302: #define D_WDATA 0201 ! 303: #define D_WCNTL 0200 ! 304: #define D_XPACK 0301 ! 305: #endif ! 306: ! 307: /* ! 308: * MACRO definition ! 309: */ ! 310: ! 311: /* ! 312: * Define the "BUSWAIT" macro ! 313: * not test NMEM is dangereous if memory does not exist, but fast ! 314: */ ! 315: #define BUSWAIT\ ! 316: 5: mov npr,brg;\ ! 317: br0 5b /* loop until ~NRQ */ ! 318: ! 319: /* ! 320: * Macros to get and release queue entries ! 321: * r14 points to the list of available queue entries ! 322: */ ! 323: #define FREEQ(X)\ ! 324: mov 03,brg;\ ! 325: and brg,X,%mar;\ ! 326: mov ~03,brg;\ ! 327: and brg,X,mar;\ ! 328: mov r14,mem;\ ! 329: mov X,brg;\ ! 330: mov brg,r14 ! 331: ! 332: #define GETQ(X,Y)\ ! 333: mov r14,brg;\ ! 334: brz Y;\ ! 335: mov brg,X;\ ! 336: mov 03,brg;\ ! 337: and brg,X,%mar;\ ! 338: mov ~03,brg;\ ! 339: and brg,X,mar;\ ! 340: mov mem,r14 ! 341: ! 342: /* ! 343: * QA(REG) : QA converts a queue pointer to mar & %mar form. ! 344: * REG is a scratch pad register and has the format: ! 345: * bits 7-2 from REG + 00 forms the offset within a page ! 346: * bits 1-0 is the page number ! 347: * Queues are 4-byte long, so it always fall in 4-byte boundary ! 348: * Queues can only be located in the first 4 pages ! 349: */ ! 350: #define QA(REG)\ ! 351: mov ~03,brg;\ ! 352: and brg,REG,mar;\ ! 353: mov 03,brg;\ ! 354: and brg,REG,%mar ! 355: ! 356: /* ! 357: * GEBI(X,ADDR) : get a free buffer index ! 358: * 'bmap' to 'bmap'+16 indicate 128 buffers, each 128 bytes. ! 359: * A '1' in i-th bit postion indicates i-th buffer is buzy ! 360: * GEBI finds the first free buffer and returns its number ! 361: * in register X. If no buffer is free, jump to ADDR ! 362: * Turn on i-th bit ! 363: * X can't be r0 ! 364: * using r0, X, brg, mar, %mar ! 365: */ ! 366: #define GEBI(X,ADDR)\ ! 367: mov 0,brg;\ ! 368: mov brg,X;\ ! 369: mov 1,brg;\ ! 370: mov brg,r0;\ ! 371: mov bmap,mar;\ ! 372: mov %bmap,%mar;\ ! 373: 5: mov mem,brg;\ ! 374: brz 8f;\ ! 375: 6: br0 7f;\ ! 376: br 9f;\ ! 377: 7: inc X;\ ! 378: asl r0;\ ! 379: mov 0,brg>>;\ ! 380: br 6b;\ ! 381: 8: mov 8,brg|mar++;\ ! 382: add brg,X,X|brg;\ ! 383: br7 ADDR;\ ! 384: br 5b;\ ! 385: 9: or mem,r0,mem ! 386: ! 387: /* ! 388: * IBEG(X) : return buffer index X to pool (i.e. turn off bit in 'bmap') ! 389: * X can't be r0 ! 390: * using r0, X, brg, mar, %mar ! 391: */ ! 392: #define IBEG(X)\ ! 393: mov X,brg;\ ! 394: brz 9f;\ ! 395: mov bmap0,mar;\ ! 396: mov %bmap0,%mar;\ ! 397: 6: mov 8,brg|mar++;\ ! 398: sub brg,X;\ ! 399: brc 6b;\ ! 400: add brg,X;\ ! 401: mov 1,brg;\ ! 402: mov brg,r0;\ ! 403: 7: dec X;\ ! 404: brz 8f;\ ! 405: asl r0,r0|brg;\ ! 406: br 7b;\ ! 407: 8: mov 0,r0;\ ! 408: addn brg,r0;\ ! 409: and mem,r0,mem;\ ! 410: 9: ! 411: ! 412: /* ! 413: * BITA(I,X,Y,Z): buffer index (in I) to address (X:LSB, Y, Z:MSB) ! 414: */ ! 415: #define BITA(I,X,Y,Z)\ ! 416: mov baddr,mar;\ ! 417: mov %baddr,%mar;\ ! 418: mov mem,X|mar++;\ ! 419: mov mem,Y|mar++;\ ! 420: mov mem,Z;\ ! 421: 8: dec I;\ ! 422: brz 9f;\ ! 423: mov BSIZE2,brg;\ ! 424: add brg,X;\ ! 425: adc Y;\ ! 426: adc Z;\ ! 427: br 8b;\ ! 428: 9: ! 429: ! 430: /* ! 431: * Subroutine CALL and RETURN macros ! 432: */ ! 433: #define CALL(X,SAVE)\ ! 434: mov %SAVE,%mar;\ ! 435: mov SAVE,mar;\ ! 436: mov %9f,mem|mar++;\ ! 437: mov 9f,mem;\ ! 438: mov %X,brg;\ ! 439: mov brg,pcr;\ ! 440: jmp X;\ ! 441: 9: ! 442: ! 443: #define RETURN(SAVE) \ ! 444: mov %SAVE,%mar;\ ! 445: mov SAVE,mar;\ ! 446: mov mem,pcr|mar++;\ ! 447: jmp (mem) ! 448: ! 449: /* ! 450: * ERROR(X) --- store error code in brg, jump to errlog ! 451: */ ! 452: #define ERROR(X) \ ! 453: mov %errlog,brg;\ ! 454: mov brg,pcr;\ ! 455: mov X,brg;\ ! 456: jmp errlog ! 457: ! 458: /* ! 459: * Macro BRB(X,Y,Z): if bit Y is on in X, then branch to Z ! 460: * X is a scratch pat register ! 461: * Macro BRP(X,Y,Z): if bit Y is on in X, then branch to Z ! 462: * X may not be a scratch pat register ! 463: */ ! 464: #define BRB(X,Y,Z) \ ! 465: mov ~Y,brg;\ ! 466: or brg,X,-;\ ! 467: brz Z ! 468: #define BRP(X,Y,Z) \ ! 469: mov X,r0;\ ! 470: mov ~Y,brg;\ ! 471: or brg,r0,-;\ ! 472: brz Z ! 473: ! 474: /* ! 475: * CHK(X,Y): set flag X on Y-th check word ! 476: */ ! 477: #ifdef CHECK ! 478: #define CHK(X,Y)\ ! 479: mov Y,brg;\ ! 480: mov brg,r0;\ ! 481: mov check,brg;\ ! 482: add brg,r0,mar;\ ! 483: mov %check,%mar;\ ! 484: mov X,brg;\ ! 485: mov brg,r0;\ ! 486: or mem,r0,mem ! 487: #else ! 488: #define CHK(X,Y) ! 489: #endif ! 490: ! 491: /* ! 492: * CHK1(X,Y): set flag X on Y-th check word ! 493: * same as CHK except restore page register (r8) ! 494: */ ! 495: #ifdef CHECK ! 496: #define CHK1(X,Y)\ ! 497: CHK(X,Y);\ ! 498: mov r8,%mar ! 499: #else ! 500: #define CHK1(X,Y) ! 501: #endif ! 502: ! 503: /* ! 504: * GLTE(CHAN) : CHAN is the channel # ! 505: * LTE size is 32 bytes for each channel ! 506: * When exit, r8(%mar), r10(mar) = addr of LTE ! 507: * Using r8, r10, brg, mar, mem ! 508: */ ! 509: #define GLTE(CHAN)\ ! 510: mov CHAN,brg;\ ! 511: mov brg,brg>>;\ ! 512: mov brg,brg>>;\ ! 513: mov brg,brg>>;\ ! 514: mov brg,r8;\ ! 515: mov 0340,brg;\ ! 516: and brg,r8,brg;\ ! 517: mov brg,r10|mar;\ ! 518: mov 037,brg;\ ! 519: and brg,r8;\ ! 520: mov %dzst,brg;\ ! 521: add brg,r8,r8|%mar ! 522: ! 523: /* ! 524: * INCA(X,Y,Z,AMOUNT) - inc the content of registers X, Y, Z ! 525: * (Z most significant) by AMOUNT ! 526: * X, Y, Z are scratch pad registers ! 527: * Using X, Y, Z, brg ! 528: */ ! 529: #define INCA(X,Y,Z,AMOUNT)\ ! 530: mov AMOUNT,brg;\ ! 531: add brg,X;\ ! 532: adc Y;\ ! 533: adc Z ! 534: ! 535: /* ! 536: * SPUTTWO(Z,ERR) - put two bytes from odl & odh to cpu ! 537: * cpu addresses are in oal (bits 7-0), oah (bits 15-8), ! 538: * and Z (bits 17-16) ! 539: * If error, go to ERR. ! 540: * When exit, cpu addresses are NOT incremented by 2 ! 541: * Does NOT wait for UNIBUS to complete ! 542: * Using r0, r1, brg, npr, oal, oah, odl, odh, mar, mem, X, Y, Z. ! 543: */ ! 544: #define SPUTTWO(Z,ERR)\ ! 545: asl Z,brg;\ ! 546: mov brg,r0;\ ! 547: asl r0;\ ! 548: mov nprx,r1;\ ! 549: mov ~(BRQ|ACLO|(3<<2)),brg;\ ! 550: and brg,r1,brg;\ ! 551: or brg,r0,nprx /* set up bits 17-16 */;\ ! 552: mov NRQ|OUT,brg;\ ! 553: mov brg,npr /* issue unibus request */;\ ! 554: BUSWAIT ! 555: ! 556: /* ! 557: * PUTTWO(X,Y,Z,ERR) - put two bytes from odl & odh to cpu ! 558: * cpu addresses are stored in X (bits 7-0) ! 559: * Y (bits 15-8) and Z (bits 17-16) ! 560: * If error, go to ERR. ! 561: * When exit, cpu addresses are incremented by 2 ! 562: * Using r0, r1, brg, npr, oal, oah, odl, odh, mar, mem, X, Y, Z. ! 563: */ ! 564: #define PUTTWO(X,Y,Z,ERR)\ ! 565: mov X,brg;\ ! 566: mov brg,oal;\ ! 567: mov Y,brg;\ ! 568: mov brg,oah;\ ! 569: SPUTTWO(Z,ERR);\ ! 570: INCA(X,Y,Z,2);\ ! 571: BUSWAIT ! 572: ! 573: /* ! 574: * SPUTONE(Z,ERR) - put one bytes from odl/odh to cpu ! 575: * cpu addresses are in oal (bits 7-0), oah (bits 15-8), ! 576: * and Z (bits 17-16) ! 577: * If error, go to ERR. ! 578: * When exit, cpu addresses are NOT incremented by 1 ! 579: * Does NOT wait for UNIBUS to complete ! 580: * Using r0, r1, brg, npr, oal, oah, odl, odh, mar, mem, Z. ! 581: */ ! 582: #define SPUTONE(Z,ERR)\ ! 583: asl Z,brg;\ ! 584: mov brg,r0;\ ! 585: asl r0;\ ! 586: mov nprx,r1;\ ! 587: mov ~(BRQ|ACLO|(3<<2)),brg;\ ! 588: and brg,r1,brg;\ ! 589: or brg,r0,nprx /* set up bits 17-16 */;\ ! 590: mov NRQ|OUT|BYTE,brg;\ ! 591: mov brg,npr /* issue unibus request */;\ ! 592: BUSWAIT ! 593: ! 594: /* ! 595: * PUTONE(X,Y,Z,ERR) - put one bytes from odl/odh to cpu ! 596: * cpu addresses are stored in X (bits 7-0) ! 597: * Y (bits 15-8) and Z (bits 17-16) ! 598: * If error, go to ERR. ! 599: * When exit, cpu addresses are incremented by 1 ! 600: * Using r0, r1, brg, npr, oal, oah, odl, odh, mar, mem, X, Y, Z. ! 601: */ ! 602: #define PUTONE(X,Y,Z,ERR)\ ! 603: mov X,brg;\ ! 604: mov brg,oal;\ ! 605: mov Y,brg;\ ! 606: mov brg,oah;\ ! 607: SPUTONE(Z,ERR);\ ! 608: INCA(X,Y,Z,1);\ ! 609: BUSWAIT ! 610: ! 611: /* ! 612: * SGETTWO(X,Y,Z,ERR) - get two bytes into idl & idh from cpu ! 613: * cpu addresses are stored in X (bits 7-0) ! 614: * Y (bits 15-8) and Z (bits 17-16) ! 615: * If error, go to ERR. ! 616: * Does NOT wait for UNIBUS to complete ! 617: * When exit, cpu addresses are incremented by 2 ! 618: * Using r0, brg, npr, ial, iah, idl, idh, mar, mem, X, Y, Z. ! 619: */ ! 620: #define SGETTWO(X,Y,Z,ERR)\ ! 621: mov X,brg;\ ! 622: mov brg,ial;\ ! 623: mov Y,brg;\ ! 624: mov brg,iah;\ ! 625: asl Z,brg;\ ! 626: mov brg,r0;\ ! 627: asl r0;\ ! 628: mov NRQ,brg;\ ! 629: or brg,r0,npr;\ ! 630: INCA(X,Y,Z,2);\ ! 631: BUSWAIT ! 632: ! 633: /* ! 634: * GETTWO(X,Y,Z,ERR) - get two bytes into idl & idh from cpu ! 635: * cpu addresses are stored in X (bits 7-0) ! 636: * Y (bits 15-8) and Z (bits 17-16) ! 637: * If error, go to ERR. ! 638: * When exit, cpu addresses are incremented by 2 ! 639: * Using r0, brg, npr, ial, iah, idl, idh, mar, mem, X, Y, Z. ! 640: */ ! 641: #define GETTWO(X,Y,Z,ERR)\ ! 642: SGETTWO(X,Y,Z,ERR);\ ! 643: BUSWAIT ! 644: ! 645: /* ! 646: * MOD1(X,Y,Z) : Z = (X==Y)? 0 : X ! 647: * X, Y, Z are scratch pad registers ! 648: * X, Y won't be changed when returned ! 649: * Using brg ! 650: */ ! 651: #define MOD1(X,Y,Z)\ ! 652: mov X,brg;\ ! 653: addn brg,Y,-;\ ! 654: brz 8f;\ ! 655: br 9f;\ ! 656: 8: mov 0,brg;\ ! 657: 9: mov brg,Z ! 658: ! 659: /* ! 660: * MOD0(X,Y,Z) - Z = (X<0)? (X+Y) : (X) ! 661: * X, Y, Z are scratch pad registers ! 662: * X, Y won't be changed when returned ! 663: * Using brg ! 664: */ ! 665: #define MOD0(X,Y,Z)\ ! 666: mov X,brg;\ ! 667: br7 8f;\ ! 668: br 9f;\ ! 669: 8: add brg,Y,brg;\ ! 670: 9: mov brg,Z ! 671: ! 672: /* ! 673: * TIMES(W,X,Y,Z) - Y(hibyte)Z(low) = W * X ! 674: * W, X, Y, Z are scratch pad registers ! 675: * W, X, Y, Z can't be the same ! 676: * X, Y, Z can't be r0 ! 677: * X, W won't be changed when returned ! 678: * Using brg, r0 ! 679: */ ! 680: #define TIMES(W,X,Y,Z)\ ! 681: mov 0,brg;\ ! 682: mov brg,Y;\ ! 683: mov brg,Z;\ ! 684: mov W,brg;\ ! 685: mov brg,r0;\ ! 686: mov X,brg;\ ! 687: 8: dec r0;\ ! 688: brz 9f;\ ! 689: add brg,Z;\ ! 690: adc Y;\ ! 691: br 8b;\ ! 692: 9: ! 693: ! 694: /* ! 695: * BIT(X,Y) - bit pattern - Y = (1 << (x)) ! 696: * X, Y are scratch pat registers and can't be the same ! 697: * usually 0 <= X <= 7 ! 698: */ ! 699: #define BIT(X,Y)\ ! 700: mov 1,brg;\ ! 701: mov brg,Y;\ ! 702: 8: dec X;\ ! 703: brz 9f;\ ! 704: asl Y;\ ! 705: br 8b;\ ! 706: 9: ! 707: ! 708: /* ! 709: * SENDDATA(HI,LO) : send HI to lur1 and LO to lur0 ! 710: * using brg, lur0, lur1, lur2 (if KDI) ! 711: * using brg, odl, odh, oal, oah, mem, mar, npr, nprx, r0 (DR11C) ! 712: */ ! 713: #define SENDDATA(HI,LO) \ ! 714: mov HI,brg;\ ! 715: mov brg,OHI;\ ! 716: mov LO,brg;\ ! 717: mov brg,OLO;\ ! 718: SENDD ! 719: ! 720: #ifdef KDI ! 721: #ifdef CPM422 ! 722: /* ! 723: * cpm422 can't send an envelop within 2us ! 724: * using brg, r0 ! 725: */ ! 726: #define D422(X) DELAY(X) ! 727: #else ! 728: #define D422(X) ! 729: #endif ! 730: /* ! 731: * DELAY(X): some time ! 732: * delay 400*(X+1) ns ! 733: * using r0, brg ! 734: */ ! 735: #define DELAY(X) \ ! 736: mov X,brg;\ ! 737: mov brg,r0;\ ! 738: 9: dec r0;\ ! 739: brc 9b ! 740: ! 741: /* ! 742: * READDATA(LOC) : read data in lur0 (lo byte) and lur5 (hi byte) ! 743: * if data is not ready (i.e. DKFRDY (bit 0) is not set), goto LOC. ! 744: * using lur0, lur1, lur5, lur6, brg ! 745: */ ! 746: #define READDATA(LOC) \ ! 747: mov lur6,brg;\ ! 748: br0 8f;\ ! 749: br LOC;\ ! 750: 8: ! 751: ! 752: /* ! 753: * SENDD : OLO and OHI have been loaded, just trigger lur2 ! 754: */ ! 755: #define SENDD\ ! 756: mov 0,brg;\ ! 757: mov brg,lur2 /* strobe */ ! 758: ! 759: /* ! 760: * SENDHEAD(CHAN): send DKMARK with channel # ! 761: * using brg, lur0, lur1, lur2 ! 762: */ ! 763: #define SENDHEAD(CHAN)\ ! 764: SENDDATA(D_WHEAD,CHAN) ! 765: ! 766: /* ! 767: * SENDPACK(SEQ) : send seq# to seq fifo ! 768: * SEQ is in a scratch pad register ! 769: * using brg, lur1, lur2, SEQ ! 770: * using also lur6 to check that the transmitter becomes ! 771: * ready again. We busy wait until it does. ! 772: * We the read the sequence number so that the busy ! 773: * wait loop will be valid the next time ! 774: */ ! 775: #define SENDPACK(SEQ) \ ! 776: mov D_XPACK,brg;\ ! 777: mov brg,lur1;\ ! 778: SENDD;\ ! 779: 1: mov lur6,brg;\ ! 780: br1 1f;\ ! 781: br 1b;\ ! 782: 1: mov D_OSEQ,brg;\ ! 783: mov brg,lur1;\ ! 784: mov lur1,brg /*read strobe*/ ! 785: ! 786: /* ! 787: * SENDCMD(CMD) ! 788: */ ! 789: #define SENDCMD(CMD)\ ! 790: mov CMD,brg;\ ! 791: mov brg,lur1;\ ! 792: D422(3) ! 793: ! 794: #else ! 795: /* ! 796: * DR11-C specific macros ! 797: */ ! 798: /* ! 799: * DELAY(X): DR11C is slow enough and don't need delay ! 800: */ ! 801: #define DELAY(X) ! 802: ! 803: /* ! 804: * READCMD : read csr word in the DR-11C ! 805: * Input: csraddr is the csr unibus address ! 806: * Output: idl (low-byte) and idh (hi-byte) of the csr ! 807: * Using ial, iah, mar, mem, r0, brg, npr ! 808: */ ! 809: #define READCMD\ ! 810: mov %csraddr,%mar;\ ! 811: mov csraddr,mar;\ ! 812: READDR ! 813: ! 814: /* ! 815: * READDATA : read dki word of the DR-11C ! 816: * Input: dkiaddr is the dki unibus address ! 817: * Output: idl (low-byte) and idh (hi-byte) of the dki ! 818: * Using ial, iah, mar, mem, r0, brg, npr ! 819: */ ! 820: #define READDATA(LOC)\ ! 821: READCMD;\ ! 822: mov idh,brg;\ ! 823: br7 9f;\ ! 824: br LOC;\ ! 825: 9:;\ ! 826: mov %dkiaddr,%mar;\ ! 827: mov dkiaddr,mar;\ ! 828: READDR ! 829: ! 830: /* ! 831: * READDR : read a word whose unibus addr is pointed by mar ! 832: */ ! 833: #define READDR\ ! 834: mov mem,ial|mar++;\ ! 835: mov mem,iah|mar++;\ ! 836: mov mem,r0;\ ! 837: asl r0;\ ! 838: asl r0;\ ! 839: mov NRQ,brg;\ ! 840: or brg,r0,npr;\ ! 841: BUSWAIT ! 842: ! 843: /* ! 844: /* ! 845: * WRITEDR : write odl and odh to unibus addr pointed by mar ! 846: */ ! 847: #define WRITEDR\ ! 848: mov nprx,r0;\ ! 849: mov ~(BRQ|ACLO|(3<<2)),brg;\ ! 850: and brg,r0,brg;\ ! 851: mov mem,oal|mar++;\ ! 852: mov mem,oah|mar++;\ ! 853: mov mem,r0;\ ! 854: asl r0;\ ! 855: asl r0;\ ! 856: or brg,r0,nprx;\ ! 857: mov OUT|NRQ,brg;\ ! 858: mov brg,npr;\ ! 859: BUSWAIT ! 860: ! 861: /* ! 862: * SENDCMD : Issue a DR-11C command by outputing csr ! 863: * Using odl, odh, oal, oah, mar, mem, brg, npr, nprx, r0 ! 864: */ ! 865: #define SENDCMD(CMD)\ ! 866: mov CMD,brg;\ ! 867: mov brg,odl;\ ! 868: mov 0,brg;\ ! 869: mov brg,odh;\ ! 870: mov %csraddr,%mar;\ ! 871: mov csraddr,mar;\ ! 872: WRITEDR ! 873: ! 874: /* ! 875: * SENDD: OHI, OLO have been loaded ! 876: * Using odl, odh, oal, oah, mar, mem, brg, npr, nprx, r0 ! 877: */ ! 878: #define SENDD\ ! 879: mov %dkoaddr,%mar;\ ! 880: mov dkoaddr,mar;\ ! 881: WRITEDR ! 882: ! 883: /* ! 884: * SENDHEAD(CHAN) : send DKMARK with channel # ! 885: * channel # can't be in r0 ! 886: * using odl, odh, oal, oah, mar, %mar, mem, brg, npr, nprx, r0 ! 887: */ ! 888: #define SENDHEAD(CHAN) \ ! 889: SENDCMD(D_WRITE);\ ! 890: SENDDATA(D_WHEAD,CHAN) ! 891: ! 892: /* ! 893: * SENDPACK(SEQ) : send seq# to seq fifo ! 894: * SEQ can't be in r0 ! 895: * using odl, odh, oal, oah, mar, %mar, mem, brg, npr, nprx, r0 ! 896: */ ! 897: #define SENDPACK(SEQ) \ ! 898: SENDCMD(D_XPACK);\ ! 899: SENDDATA(SEQ,ZERO) ! 900: ! 901: #endif ! 902: ! 903: /* ! 904: * Data definitions ! 905: */ ! 906: .data ! 907: /* ! 908: * Global data structures ! 909: */ ! 910: .org 0 ! 911: /* ! 912: * check point code ! 913: */ ! 914: check: .byte 0,0,0,0,0,0,0 ! 915: /* ! 916: * 1 ms timer ! 917: * 16 times 50-us timer expires ==> set this timer ! 918: */ ! 919: clk1ms: .byte 0 ! 920: /* ! 921: * 5 sec timer : 4096 * 1ms ! 922: * Every time clk1ms expires (1ms gone by), clk5s gets decremented ! 923: */ ! 924: clk5s: .byte 0,0 ! 925: /* ! 926: * temp storage ! 927: */ ! 928: tmp: .byte 0,0,0,0,0,0,0,0,0,0,0,0 ! 929: /* ! 930: * return code: code, lenlo, lenhi, cntl, mode ! 931: */ ! 932: repinfo: .byte 0 ! 933: replen: .byte 0,0 ! 934: repctl: .byte 0 ! 935: repmode: .byte 0 ! 936: /* ! 937: * report seq# ! 938: */ ! 939: kseq: .byte 0 ! 940: /* ! 941: * # of bad packets received so far ! 942: */ ! 943: badpack: .byte 0 ! 944: /* ! 945: * temp storage for output routine ! 946: */ ! 947: blklen: .byte 0 ! 948: /* ! 949: * a flag indicates a cntl char was rcv (used in subr.s) ! 950: */ ! 951: icntl: .byte 0 ! 952: /* ! 953: * input state: bit7 - RBLEN>0; bit0 - 1st byte of a pair is now in odl ! 954: */ ! 955: iflag: .byte 0 ! 956: /* ! 957: * chan# ! 958: */ ! 959: chan: .byte 0 ! 960: /* ! 961: * seq# ! 962: */ ! 963: pseq: .byte 0 ! 964: /* ! 965: * save r13/r12/r1/... when calling 'rcv' ! 966: */ ! 967: rcvsave: .byte 0,0,0,0 ! 968: /* ! 969: * save area for r12 in report ! 970: */ ! 971: repsave: .byte 0,0,0,0 ! 972: /* ! 973: * buffer map: 16 locations indicate 16*8 (128) buffers, each 128 bytes ! 974: */ ! 975: bmap0: .byte 0 ! 976: bmap: .org .+16 ! 977: /* ! 978: * timer map: for max 96 channels ! 979: */ ! 980: timemap: .org .+12 ! 981: /* ! 982: * bit pattern ! 983: */ ! 984: bitpatt: .byte BIT0,BIT1,BIT2,BIT3,BIT4,BIT5,BIT6,BIT7 ! 985: /* ! 986: * starting addresses of host buffer ! 987: */ ! 988: baddr: .byte 0,0,0 ! 989: /* ! 990: * Addresses for cmdbuf, tail of cmdbuf, statbuf, head of statbuf, ! 991: */ ! 992: cbaddr: .byte 0,0,0 ! 993: cbtail: .byte 0,0,0 ! 994: sbaddr: .byte 0,0,0 ! 995: sbhead: .byte 0,0,0 ! 996: /* ! 997: * CALL/RETURN return address ! 998: */ ! 999: s.send: .byte 0,0 ! 1000: s.rcv: .byte 0,0 ! 1001: s.report: .byte 0,0 ! 1002: s.clean: .byte 0,0 ! 1003: s.copy1: .byte 0,0 ! 1004: s.cktimer: .byte 0,0 ! 1005: s.strailer: .byte 0,0 ! 1006: /* ! 1007: * dr11c specific ! 1008: */ ! 1009: #ifdef DR11C ! 1010: /* ! 1011: * every time PCLK expires, r_timer gets decremented. ! 1012: * if r_timer reaches -1, then read CSR to check R/TDONE ! 1013: */ ! 1014: r_timer: .byte 0 ! 1015: /* ! 1016: * UNIBUS addresses for the DR11C ! 1017: * Bits 7-0 in 1st byte, 15-8 in 2nd, 17-16 in 3rd (right-adjust) ! 1018: */ ! 1019: csraddr: .byte 0,0,0 ! 1020: dkoaddr: .byte 0,0,0 ! 1021: dkiaddr: .byte 0,0,0 ! 1022: #endif ! 1023: /* ! 1024: * output active queue ! 1025: */ ! 1026: outq: .byte NIL ! 1027: outq1: .byte NIL /* work area */ ! 1028: ! 1029: /* ! 1030: * Queue entries ! 1031: */ ! 1032: inqueue: ! 1033: .org 4*256 ! 1034: /* ! 1035: * LTE tables from page 4 to 15, each entry is 32 bytes ! 1036: */ ! 1037: dzst: ! 1038: /* ! 1039: * Instruction text starts here ! 1040: */ ! 1041: .text ! 1042: /* ! 1043: * Segment 0 ! 1044: * ! 1045: * This is the main segment ! 1046: */ ! 1047: .org 0 ! 1048: seg0: ! 1049: init: ! 1050: /* ! 1051: * Set csr0 to idle state (i.e. 0) ! 1052: */ ! 1053: mov 0,brg ! 1054: mov brg,csr0 ! 1055: /* ! 1056: * initialize all global variables ! 1057: */ ! 1058: mov brg,mar ! 1059: mov brg,%mar ! 1060: mov inqueue-1,brg ! 1061: mov brg,r0 ! 1062: init1: ! 1063: mov 0,mem|mar++ ! 1064: dec r0 ! 1065: brc init1 ! 1066: /* ! 1067: * initialize special variables (~0) ! 1068: */ ! 1069: mov outq,mar ! 1070: mov %outq,%mar ! 1071: mov NIL,mem|mar++ ! 1072: mov NIL,mem|mar++ ! 1073: mov %bitpatt,%mar ! 1074: mov bitpatt,mar ! 1075: mov 7,r7 ! 1076: mov 1,r1 ! 1077: 1: ! 1078: mov r1,mem|mar++ ! 1079: dec r7 ! 1080: brz 2f ! 1081: asl r1 ! 1082: br 1b ! 1083: 2: ! 1084: /* ! 1085: * Initialize the free-buffer list ! 1086: * page 0-7 is for global data and queues ! 1087: * page 8-15 for LTE entries ! 1088: */ ! 1089: #define NLTE (CHANMODS+7)/8 ! 1090: #define NPQ 4 ! 1091: #define NQE ((NPQ*256-((inqueue+3)&~3))/4) ! 1092: /* ! 1093: * Initialize the list of available queue entries ! 1094: */ ! 1095: mov NIL,brg ! 1096: mov brg,r14 ! 1097: mov (inqueue+3)&~3,brg ! 1098: mov brg,r0 ! 1099: mov NQE-2,brg ! 1100: mov brg,r1 ! 1101: init4: ! 1102: FREEQ(r0) ! 1103: mov 4,brg /* queue is 4-byte long */ ! 1104: add brg,r0 ! 1105: adc r0 ! 1106: dec r1 ! 1107: brc init4 ! 1108: /* ! 1109: * Initialize LTE queue pointers ! 1110: */ ! 1111: mov CHANMODS-1,brg ! 1112: mov brg,r9 ! 1113: init6: ! 1114: /* ! 1115: * reset all LTE values: (can be done globally) ! 1116: */ ! 1117: GLTE(r9) ! 1118: mov 31,brg /* 32: size of LTE */ ! 1119: mov brg,r0 ! 1120: 1: ! 1121: mov 0,mem|mar++ ! 1122: dec r0 ! 1123: brc 1b ! 1124: /* ! 1125: * initialized C_X to idle and RQ/RB to nil ! 1126: * initailize whatever else is needed ! 1127: */ ! 1128: mov r8,%mar ! 1129: mov C_X,brg ! 1130: add brg,r10,mar ! 1131: mov XIDLE,mem ! 1132: mov C_RQ,brg ! 1133: add brg,r10,mar ! 1134: mov NIL,mem ! 1135: mov C_RB,brg ! 1136: add brg,r10,mar ! 1137: mov NIL,mem ! 1138: dec r9 ! 1139: brc init6 ! 1140: /* ! 1141: * Go to disp ! 1142: */ ! 1143: br disp ! 1144: /* ! 1145: * Dispatcher loop--keep looking for something to do ! 1146: */ ! 1147: disp: ! 1148: /* ! 1149: * If csr0 == 0, does nothing and loop. ! 1150: * If csr0 == 1, read addresses from csr2~7. ! 1151: * If csr0 == 2, normal operation (i.e. take command from ! 1152: * cmdbuff and put report to statbuf). ! 1153: */ ! 1154: mov csr0,brg ! 1155: mov 3,r3 ! 1156: and brg,r3,brg ! 1157: br1 disp2 /* normal operation */ ! 1158: br0 disp1 /* direct command */ ! 1159: mov brg,r0 ! 1160: dec r0,- ! 1161: brz disp /* idle */ ! 1162: ERROR(E_SW) ! 1163: disp1: ! 1164: /* ! 1165: * Get init information from structure pointed by csr2~4 ! 1166: * struct init { ! 1167: * paddr_t *cmdaddr; ! 1168: * paddr_t *stataddr; ! 1169: * paddr_t *bufaddr ! 1170: * paddr_t *csraddr ! 1171: * }; ! 1172: */ ! 1173: mov csr2,r13 ! 1174: mov csr3,r12 ! 1175: mov csr4,r11 ! 1176: GETTWO(r13,r12,r11,err_bus) ! 1177: mov idl,r5 ! 1178: GETTWO(r13,r12,r11,err_bus) ! 1179: mov cbaddr,mar ! 1180: mov %cbaddr,%mar ! 1181: mov idl,mem|mar++ /* cbaddr */ ! 1182: mov idh,mem|mar++ ! 1183: mov r5,mem|mar++ ! 1184: mov idl,mem|mar++ /* cbtail */ ! 1185: mov idh,mem|mar++ ! 1186: mov r5,mem|mar++ ! 1187: GETTWO(r13,r12,r11,err_bus) ! 1188: mov idl,r5 ! 1189: GETTWO(r13,r12,r11,err_bus) ! 1190: mov sbaddr,mar ! 1191: mov %sbaddr,%mar ! 1192: mov idl,mem|mar++ /* sbaddr */ ! 1193: mov idh,mem|mar++ ! 1194: mov r5,mem|mar++ ! 1195: mov idl,mem|mar++ /* sbhead */ ! 1196: mov idh,mem|mar++ ! 1197: mov r5,mem|mar++ ! 1198: GETTWO(r13,r12,r11,err_bus) ! 1199: mov idl,r5 ! 1200: GETTWO(r13,r12,r11,err_bus) ! 1201: mov baddr,mar ! 1202: mov %baddr,%mar ! 1203: mov idl,mem|mar++ /* bufaddr */ ! 1204: mov idh,mem|mar++ ! 1205: mov r5,mem|mar++ ! 1206: #ifdef KDI ! 1207: /* ! 1208: * Issue D_RESET command and set dko to 0 to clear all fifo's ! 1209: */ ! 1210: mov D_RESET,brg ! 1211: mov brg,lur1 ! 1212: mov brg,lur2 ! 1213: #else ! 1214: /* ! 1215: * Record the unibus address (csr) for this DR-11 ! 1216: * addr(dko) = addr(csr) + 2 ! 1217: * addr(dki) = addr(csr) + 4 ! 1218: */ ! 1219: GETTWO(r13,r12,r11,err_bus) ! 1220: mov idl,r5 ! 1221: GETTWO(r13,r12,r11,err_bus) ! 1222: mov idl,r7 ! 1223: mov idh,r6 ! 1224: mov 3,brg ! 1225: mov brg,r5 /* io page */ ! 1226: mov %csraddr,%mar ! 1227: mov csraddr,mar ! 1228: mov r7,mem|mar++ ! 1229: mov r6,mem|mar++ ! 1230: mov r5,mem|mar++ ! 1231: /* ! 1232: * Now mar points to dkoaddr ! 1233: */ ! 1234: mov 2,brg ! 1235: add brg,r7,mem|mar++ ! 1236: adc r6,mem|mar++ ! 1237: adc r5,mem|mar++ ! 1238: /* ! 1239: * Now mar points to dkiaddr ! 1240: */ ! 1241: mov 4,brg ! 1242: add brg,r7,mem|mar++ ! 1243: adc r6,mem|mar++ ! 1244: adc r5,mem ! 1245: /* ! 1246: * Issue D_OSEQ command and set dko to 0 to clear all fifo's ! 1247: */ ! 1248: mov D_OSEQ,brg ! 1249: mov brg,odl ! 1250: mov 0,brg ! 1251: mov brg,odh ! 1252: SENDCMD(D_OSEQ) ! 1253: SENDDATA(ZERO,ZERO) ! 1254: #endif ! 1255: /* ! 1256: * Now set csr0 to 2 (i.e. normal operation) ! 1257: * Set head/tail of all circular buffers to 0 ! 1258: */ ! 1259: mov 0,brg ! 1260: mov brg,csr2 ! 1261: mov brg,csr3 ! 1262: mov brg,csr4 ! 1263: mov brg,csr5 ! 1264: mov brg,csr6 ! 1265: mov brg,csr7 ! 1266: mov 2,brg ! 1267: mov brg,csr0 ! 1268: br disp ! 1269: ! 1270: disp2: ! 1271: /* ! 1272: * This is normal operation loop ! 1273: */ ! 1274: mov csr0,brg ! 1275: br0 disp2 ! 1276: /* ! 1277: * assume kmc is fast enough so that cmdbuf never overflows ! 1278: * If HC==TC, then no command available and loop ! 1279: */ ! 1280: mov HC,brg /* head of cmdbuf */ ! 1281: mov TC,r0 /* tail of cmdbuf */ ! 1282: addn brg,r0,- ! 1283: brz disp3 ! 1284: /* ! 1285: * Read the command pointed by TC ! 1286: * Put k_type in r1, k_chan in r9, k_len in r7-r6, ! 1287: * k_ctl/time in r5, k_mode in r4, k_addr in r3-r2-idl-idh ! 1288: */ ! 1289: mov cbtail,mar ! 1290: mov %cbtail,%mar ! 1291: mov mem,r13|mar++ ! 1292: mov mem,r12|mar++ ! 1293: mov mem,r11|mar++ ! 1294: GETTWO(r13,r12,r11,err_bus) ! 1295: mov idl,r1 ! 1296: GETTWO(r13,r12,r11,err_bus) ! 1297: mov idl,r9 ! 1298: GETTWO(r13,r12,r11,err_bus) ! 1299: mov idl,r7 ! 1300: mov idh,r6 ! 1301: GETTWO(r13,r12,r11,err_bus) ! 1302: mov idl,r5 ! 1303: mov idh,r4 ! 1304: GETTWO(r13,r12,r11,err_bus) ! 1305: mov idl,r3 ! 1306: mov idh,r2 ! 1307: GETTWO(r13,r12,r11,err_bus) ! 1308: /* ! 1309: * Now modify TC and cbtail. ! 1310: * If TC==BUFSIZ-1, then TC=0 and cbtail=cbaddr ! 1311: */ ! 1312: mov TC,r0 ! 1313: mov BUFSIZ-1,brg ! 1314: sub brg,r0,- /* TC-(BUFSIZ-1) */ ! 1315: brc 1f ! 1316: inc r0,TC ! 1317: br 2f ! 1318: 1: mov 0,brg /* reset TC */ ! 1319: mov brg,TC ! 1320: mov cbaddr,mar ! 1321: mov %cbaddr,%mar ! 1322: mov mem,r13|mar++ ! 1323: mov mem,r12|mar++ ! 1324: mov mem,r11 ! 1325: 2: ! 1326: /* ! 1327: * Restore cbtail ! 1328: */ ! 1329: mov cbtail,mar ! 1330: mov %cbtail,%mar ! 1331: mov r13,mem|mar++ ! 1332: mov r12,mem|mar++ ! 1333: mov r11,mem|mar++ ! 1334: /* ! 1335: * Decode the command ! 1336: * switch (k_type) { ! 1337: * case KC_SEND: goto kc_send; ! 1338: * case KC_RCVB: goto kc_rcvb; ! 1339: * case KC_SOI: goto kc_soi; ! 1340: * case KC_CMD: goto kc_cmd; ! 1341: * case KC_FLAG: goto kc_flag; ! 1342: * case KC_TDK: goto kc_tdk; ! 1343: * case KC_XINIT: goto kc_xinit; ! 1344: * case KC_CLOSE: goto kc_close; ! 1345: * case KC_INIT: goto kc_init; ! 1346: * } ! 1347: */ ! 1348: GLTE(r9) /* set up r8/r10 */ ! 1349: mov KC_SEND,brg ! 1350: addn brg,r1,- ! 1351: brz kc_send ! 1352: mov KC_RCVB,brg ! 1353: addn brg,r1,- ! 1354: brz kc_rcvb ! 1355: mov KC_SOI,brg ! 1356: addn brg,r1,- ! 1357: brz kc_soi ! 1358: mov KC_CMD,brg ! 1359: addn brg,r1,- ! 1360: brz kc_cmd ! 1361: mov KC_FLAG,brg ! 1362: addn brg,r1,- ! 1363: brz kc_flag ! 1364: mov KC_TDK,brg ! 1365: addn brg,r1,- ! 1366: brz kc_tdk ! 1367: mov KC_XINIT,brg ! 1368: addn brg,r1,- ! 1369: brz kc_xinit ! 1370: mov KC_CLOSE,brg ! 1371: addn brg,r1,- ! 1372: brz kc_close ! 1373: mov KC_INIT,brg ! 1374: addn brg,r1,- ! 1375: brz kc_init ! 1376: ERROR(E_CMD) ! 1377: br disp3 ! 1378: ! 1379: kc_init: ! 1380: /* ! 1381: * Process a KC_INIT command ! 1382: * r5 is either D_CALL or D_IDL1 ! 1383: * C_X = XINIT; goto kc_reset ! 1384: */ ! 1385: CHK1(B0_KCIT,0) ! 1386: mov C_X,brg ! 1387: add brg,r10,mar ! 1388: mov XINIT,mem ! 1389: br kc_reset /* expect to rcv D_TALK from ty-4 */ ! 1390: ! 1391: kc_xinit: ! 1392: /* ! 1393: * Process a KC_XINIT command ! 1394: * C_X = XINIT; C_XLEN = 0; send(INIT1); ! 1395: */ ! 1396: CHK1(B0_KCIT,0) ! 1397: mov C_X,brg ! 1398: add brg,r10,mar ! 1399: mov XINIT,mem|mar++ ! 1400: /* ! 1401: mov 0,mem ! 1402: */ ! 1403: mov C_XLEN,brg ! 1404: add brg,r10,mar ! 1405: mov 0,mem|mar++ ! 1406: mov 0,mem ! 1407: mov C_XCNTL,brg ! 1408: add brg,r10,mar ! 1409: mov 0,mem ! 1410: mov I_INIT1,brg ! 1411: mov brg,r1 ! 1412: CALL(send,s.send) /* can simply goto 'time' */ ! 1413: br disp3 ! 1414: ! 1415: kc_close: ! 1416: /* ! 1417: * process KC_CLOSE command ! 1418: * k_chan is the channel # ! 1419: * if (C_RLEN) report(KS_RDB, chan); ! 1420: * goto kc_reset ! 1421: */ ! 1422: CHK1(B0_KCCS,0) ! 1423: mov C_X,brg ! 1424: add brg,r10,mar ! 1425: mov XIDLE,mem|mar++ ! 1426: mov 0,mem /* C_X1 = 0 */ ! 1427: mov C_RLEN,brg ! 1428: add brg,r10,mar ! 1429: mov mem,r7|brg ! 1430: mov brg,r0|mar++ ! 1431: mov mem,r6 ! 1432: or mem,r0 ! 1433: dec r0,- ! 1434: brz kc_reset ! 1435: /* ! 1436: * report (KS_RDB,chan) with mode SABORT ! 1437: */ ! 1438: mov repinfo,mar ! 1439: mov %repinfo,%mar ! 1440: mov KS_RDB,mem|mar++ ! 1441: mov r7,mem|mar++ /* residue length */ ! 1442: mov r6,mem|mar++ ! 1443: mov 0,mem|mar++ /* cntl char */ ! 1444: mov SABORT,mem /* RCV mode */ ! 1445: CALL(report,s.report) ! 1446: kc_reset: ! 1447: /* ! 1448: * Reset RLEN, XLEN. ! 1449: * while (RQ!=NIL) free the queues and buffers ! 1450: */ ! 1451: mov r8,%mar ! 1452: mov C_RLEN,brg ! 1453: add brg,r10,mar ! 1454: mov 0,mem|mar++ ! 1455: mov 0,mem ! 1456: mov C_RBLEN,brg ! 1457: add brg,r10,mar ! 1458: mov 0,mem|mar++ ! 1459: mov 0,mem ! 1460: mov C_TA0,brg ! 1461: add brg,r10,mar ! 1462: mov 0,mem|mar++ ! 1463: mov 0,mem ! 1464: mov C_C,brg ! 1465: add brg,r10,mar ! 1466: mov 0,mem ! 1467: mov C_RQ,brg ! 1468: add brg,r10,mar ! 1469: mov mem,r2 ! 1470: brz kc_rs2 ! 1471: mov NIL,mem ! 1472: CALL(clean,s.clean) ! 1473: mov r8,%mar ! 1474: kc_rs2: ! 1475: mov C_RB,brg ! 1476: add brg,r10,mar ! 1477: mov mem,r2 ! 1478: brz kc_rs4 ! 1479: mov NIL,mem ! 1480: CALL(clean,s.clean) ! 1481: kc_rs4: ! 1482: mov r8,%mar ! 1483: mov C_XLEN,brg ! 1484: add brg,r10,mar ! 1485: mov 0,mem|mar++ ! 1486: mov 0,mem ! 1487: mov C_XCNTL,brg ! 1488: add brg,r10,mar ! 1489: mov 0,mem ! 1490: /* ! 1491: * remove chan# from 'outq' ! 1492: * r2 is running pointer for outq (currently looked at) ! 1493: * r3 is the next outq entry ! 1494: * r4 is the running pointer for outq1 ! 1495: */ ! 1496: mov outq,mar ! 1497: mov %outq,%mar ! 1498: mov mem,r2 ! 1499: kc_rs6: ! 1500: brz kc_rs14 ! 1501: QA(r2) ! 1502: mov mem,r3 ! 1503: mov NIL,mem|mar++ ! 1504: addn mem,r9,- ! 1505: brz kc_rs12 /* delete this chan# */ ! 1506: mov outq1,mar ! 1507: mov %outq1,%mar ! 1508: kc_rs8: ! 1509: mov mem,r4 ! 1510: brz kc_rs10 ! 1511: QA(r4) ! 1512: br kc_rs8 /* try to find the end of outq1 */ ! 1513: kc_rs10: ! 1514: /* ! 1515: * found the end of outq1, append r2 here ! 1516: */ ! 1517: mov r2,mem ! 1518: kc_rs11: ! 1519: /* ! 1520: * put r3 in r2 position ! 1521: */ ! 1522: mov r3,brg ! 1523: mov brg,r2 ! 1524: br kc_rs6 ! 1525: kc_rs12: ! 1526: FREEQ(r2) ! 1527: br kc_rs11 ! 1528: kc_rs14: ! 1529: /* ! 1530: * restore outq from outq1 ! 1531: */ ! 1532: mov outq1,mar ! 1533: mov %outq1,%mar ! 1534: mov mem,brg ! 1535: mov outq,mar ! 1536: mov %outq,%mar ! 1537: mov brg,mem|mar++ ! 1538: mov NIL,mem ! 1539: br disp3 ! 1540: kc_soi: ! 1541: /* ! 1542: * Process a KC_SOI command ! 1543: * send 2 bytes in r7 (lo) and r6 (hi) to chan r9 ! 1544: * bypass error/flow control mechanism ! 1545: */ ! 1546: CHK1(B0_KCSO,0) ! 1547: mov tmp,mar ! 1548: mov %tmp,%mar ! 1549: mov r9,mem|mar++ ! 1550: mov D_WHEAD,mem|mar++ ! 1551: mov I_SOI,mem|mar++ ! 1552: mov D_WCNTL,mem|mar++ ! 1553: mov r7,mem|mar++ ! 1554: mov D_WDATA,mem|mar++ ! 1555: mov r6,mem|mar++ ! 1556: mov D_WDATA,mem|mar++ ! 1557: mov I_EOI,mem|mar++ ! 1558: mov D_WCNTL,mem|mar++ ! 1559: mov ZERO,mem|mar++ /* seq# */ ! 1560: mov D_XPACK,mem|mar++ ! 1561: #ifdef DR11C ! 1562: SENDCMD(D_WRITE) /* for dr11-c */ ! 1563: #endif ! 1564: mov 0,brg ! 1565: mov brg,r5 ! 1566: kc_so1: ! 1567: mov %tmp,%mar ! 1568: mov tmp,brg ! 1569: add brg,r5,mar ! 1570: mov mem,OLO|mar++ ! 1571: mov mem,OHI|mar++ ! 1572: SENDD ! 1573: inc r5 ! 1574: inc r5 ! 1575: mov 10,brg ! 1576: addn brg,r5,- ! 1577: brz kc_so3 /* issue XPACK */ ! 1578: brc disp3 ! 1579: br kc_so1 ! 1580: kc_so3: ! 1581: SENDCMD(D_XPACK) /* dor dr11-c */ ! 1582: br kc_so1 ! 1583: ! 1584: kc_send: ! 1585: /* ! 1586: * Process a KC_SEND command ! 1587: * The format is: ! 1588: * k_chan is the chan # ! 1589: * r7-r6: XLEN; r5: XCNTL; r4: mode; idl-idh-r3: XADDR; ! 1590: */ ! 1591: CHK1(B0_KCSD,0) ! 1592: /* ! 1593: * If this chan already in output waiting (C_XLEN!=0), error ! 1594: */ ! 1595: mov C_XLEN,brg ! 1596: add brg,r10,mar ! 1597: mov mem,r0|mar++ ! 1598: or mem,r0 ! 1599: mov C_XCNTL,brg ! 1600: add brg,r10,mar ! 1601: or mem,r0 ! 1602: dec r0,- ! 1603: brz 1f ! 1604: br err_dup ! 1605: 1: ! 1606: /* ! 1607: * Fill LTE info ! 1608: */ ! 1609: mov C_XLEN,brg ! 1610: add brg,r10,mar ! 1611: mov r7,mem|mar++ /* C_XLEN */ ! 1612: mov r6,mem|mar++ ! 1613: mov idl,mem|mar++ /* C_XADDR */ ! 1614: mov idh,mem|mar++ ! 1615: mov r3,mem|mar++ ! 1616: mov C_XCNTL,brg ! 1617: add brg,r10,mar ! 1618: mov r5,mem ! 1619: /* ! 1620: * if mode = XBOTM (i.e. 1<<7), set this bit in C_X1; ! 1621: * otherwise reset this bit ! 1622: */ ! 1623: mov C_X1,brg ! 1624: add brg,r10,mar ! 1625: mov mem,r0 ! 1626: mov ~XBOTM,brg ! 1627: or brg,r4,- ! 1628: brz 1f ! 1629: and brg,r0,mem ! 1630: br 2f ! 1631: 1: ! 1632: orn brg,r0,mem ! 1633: 2: ! 1634: /* ! 1635: * if xlen (r7,r6) and xcntl (r5) are all 0, set XNIL for sending ! 1636: * trailer only ! 1637: */ ! 1638: mov r7,brg ! 1639: or brg,r6,brg ! 1640: or brg,r5 ! 1641: dec r5,- ! 1642: brz kc_sn6 ! 1643: /* ! 1644: * if the channel is not active (i.e. hasn't rcv ainit) ! 1645: */ ! 1646: mov C_X,brg ! 1647: add brg,r10,mar ! 1648: mov mem,brg ! 1649: br1 kc_sn2 /* XACT is set */ ! 1650: br disp3 ! 1651: kc_sn2: ! 1652: /* ! 1653: * this channel is output active: put it in 'outq' ! 1654: */ ! 1655: GETQ(r1,noqb) ! 1656: mov NIL,mem|mar++ ! 1657: mov r9,mem ! 1658: mov outq,mar ! 1659: mov %outq,%mar ! 1660: kc_sn3: ! 1661: mov mem,r2 ! 1662: brz kc_sn5 ! 1663: QA(r2) ! 1664: br kc_sn3 ! 1665: kc_sn5: ! 1666: mov r1,mem ! 1667: br disp3 ! 1668: kc_sn6: ! 1669: /* ! 1670: * send trailer mode is on (i.e. 0 data byte, no cntl byte) ! 1671: */ ! 1672: mov C_X,brg ! 1673: add brg,r10,mar ! 1674: mov mem,brg|mar++ ! 1675: mov mem,r7 ! 1676: mov XNIL,mem ! 1677: or mem,r7,mem ! 1678: br1 kc_sn7 ! 1679: br disp3 /* hasn't rcv ainit */ ! 1680: kc_sn7: ! 1681: CALL(strailer,s.strailer) ! 1682: br disp3 ! 1683: ! 1684: kc_rcvb: ! 1685: /* ! 1686: * process a receive-buffer command ! 1687: * The format is: ! 1688: * k_chan is the chan# to be input ! 1689: * r7-r6: RLEN; r5: INITIM; r4: mode; idl-idh-r3: RADDR; ! 1690: */ ! 1691: CHK1(B0_KCRB,0) ! 1692: mov C_RLEN,brg ! 1693: add brg,r10,mar ! 1694: mov mem,r13 ! 1695: mov r7,mem|mar++ ! 1696: mov mem,r12 ! 1697: mov r6,mem|mar++ ! 1698: mov idl,mem|mar++ /* RADDR */ ! 1699: mov idh,mem|mar++ ! 1700: mov r3,mem ! 1701: mov C_INITIM,brg ! 1702: add brg,r10,mar ! 1703: mov r5,mem ! 1704: mov C_Y,brg ! 1705: add brg,r10,mar ! 1706: mov r4,mem ! 1707: /* ! 1708: * If there was an unfinished read-buf, report it ! 1709: * i.e. if C_RLEN > 0 ! 1710: */ ! 1711: mov r13,brg ! 1712: or brg,r12,brg ! 1713: mov brg,r0 ! 1714: dec r0,- ! 1715: brz kc_rc4 ! 1716: /* ! 1717: * abort the old pending read ! 1718: * report whatever having been received ! 1719: */ ! 1720: mov %repinfo,%mar ! 1721: mov repinfo,mar ! 1722: mov KS_RDB,mem|mar++ ! 1723: mov r13,mem|mar++ ! 1724: mov r12,mem|mar++ /* residue length */ ! 1725: mov 0,mem|mar++ /* cntl */ ! 1726: mov SABORT,mem /* mode */ ! 1727: CALL(report,s.report) ! 1728: kc_rc4: ! 1729: /* ! 1730: * if (char mode && YTIME && (RB != NULL)) set YEXPIRE ! 1731: */ ! 1732: mov r8,%mar ! 1733: mov C_X1,brg ! 1734: add brg,r10,mar ! 1735: mov mem,r0 ! 1736: mov XBLK,brg ! 1737: orn brg,r0,- ! 1738: brz kc_rc7 ! 1739: mov C_Y,brg ! 1740: add brg,r10,mar ! 1741: mov mem,r0 ! 1742: mov YTIME,brg ! 1743: orn brg,r0,- ! 1744: brz 1f ! 1745: mov C_RB,brg ! 1746: br kc_rc8 ! 1747: 1: ! 1748: mov C_RB,brg ! 1749: add brg,r10,mar ! 1750: mov mem,brg ! 1751: brz disp3 ! 1752: /* ! 1753: * set YEXPIRE ! 1754: */ ! 1755: mov C_Y,brg ! 1756: add brg,r10,mar ! 1757: mov mem,r0 ! 1758: mov YEXPIRE,brg ! 1759: or brg,r0,mem ! 1760: kc_rc6: ! 1761: /* ! 1762: * call rcv to copy RQ/RB to RADDR ! 1763: */ ! 1764: CALL(rcv,s.rcv) /* copy C_RQ to RADDR */ ! 1765: br disp3 ! 1766: kc_rc7: mov C_RQ,brg ! 1767: kc_rc8: add brg,r10,mar ! 1768: mov mem,brg ! 1769: brz disp3 ! 1770: br kc_rc6 ! 1771: ! 1772: kc_cmd: ! 1773: /* ! 1774: * process KC_CMD command ! 1775: * k_chan is the chan # ! 1776: * r7 is the subcommand ! 1777: * only OFLUSH is implemented, others will be added later ! 1778: */ ! 1779: CHK1(B0_KCCM,0) ! 1780: br kc_rs4 ! 1781: ! 1782: kc_flag: ! 1783: /* ! 1784: * process KC_FLAG command ! 1785: * k_chan is the chan # ! 1786: * 1st two bytes (r7-r6) are iflag, next two (r5-r4) are oflag ! 1787: * TO BE DONE LATER ! 1788: CHK1(B0_KCFG,0) ! 1789: */ ! 1790: br disp3 ! 1791: ! 1792: kc_one: ! 1793: /* ! 1794: * process KC_ONE command ! 1795: * k_chan is the chan # ! 1796: * send one byte (control byte) in r7 to ty-4 ! 1797: * TO BE ADDED LATER ! 1798: CHK1(B0_KC1,0) ! 1799: */ ! 1800: br disp3 ! 1801: ! 1802: kc_tdk: ! 1803: /* ! 1804: * process KC_TDK command ! 1805: * k_chan is the chan # ! 1806: * TO BE ADDED LATER ! 1807: */ ! 1808: br disp3 ! 1809: ! 1810: kc_stime: ! 1811: /* ! 1812: * process KC_STIME command ! 1813: * k_chan is the chan # ! 1814: * r7 is the timer value ! 1815: * TO BE ADDED LATER ! 1816: */ ! 1817: br disp3 ! 1818: ! 1819: disp3: ! 1820: #ifdef KDI ! 1821: /* ! 1822: * check input data ready and output completion ! 1823: * input ready is indicated by DKFRDY (bit 0) ! 1824: * output ready is indicated by TRQRDY (bit 1) ! 1825: */ ! 1826: mov lur6,brg ! 1827: br0 csrck2 ! 1828: /* ! 1829: * since we are not reading seq fifo, bit 1 is always set ! 1830: br1 csrck4 ! 1831: */ ! 1832: #endif ! 1833: BRP(nprx,PCLK,tick) ! 1834: br disp2 ! 1835: ! 1836: tick: ! 1837: /* ! 1838: * 50-us timer expires, restart the timer ! 1839: */ ! 1840: mov nprx,r0 ! 1841: mov ~(BRQ|ACLO),brg ! 1842: and brg,r0 ! 1843: mov PCLK,brg ! 1844: or brg,r0,nprx ! 1845: #ifdef DR11C ! 1846: /* ! 1847: * Dec the r_timer, and goto r_expire if r_timer reaches -1 ! 1848: */ ! 1849: mov r_timer,mar ! 1850: mov %r_timer,%mar ! 1851: mov mem,r0 ! 1852: dec r0,mem ! 1853: brz r_expire ! 1854: br tick1 ! 1855: ! 1856: r_expire: ! 1857: /* ! 1858: * reset r_timer ! 1859: */ ! 1860: mov R_TIMER,mem ! 1861: /* ! 1862: * check input data ready, then output completion ! 1863: */ ! 1864: READCMD /* get csr in idl & idh */ ! 1865: /* ! 1866: * If there is an input character available then go to csrck2 ! 1867: * DKRDONE is 1<<15 in dkcsr ! 1868: */ ! 1869: mov idh,brg ! 1870: br7 csrck2 ! 1871: /* ! 1872: * If there is an output data request then go to csrck4 ! 1873: * DKTDONE is 1<<7 in dkcsr ! 1874: mov idl,brg ! 1875: br7 csrck4 ! 1876: */ ! 1877: #endif ! 1878: tick1: ! 1879: /* ! 1880: * dec the 1ms timer and return if the result is non-negative ! 1881: */ ! 1882: mov clk1ms,mar ! 1883: mov %clk1ms,%mar ! 1884: mov mem,r0 ! 1885: dec r0,mem ! 1886: brc tick10 ! 1887: mov CLK1MS,mem /* restore timer */ ! 1888: mov NGRP,brg ! 1889: mov brg,r6 ! 1890: tick2: ! 1891: /* ! 1892: * 1ms timer expires: dec ITIME for each input chan which on timemap ! 1893: * r6: row, r7: column, r5: map itself ! 1894: */ ! 1895: mov %timemap,%mar ! 1896: mov timemap,brg ! 1897: add brg,r6,mar ! 1898: mov mem,r5|brg|mar++ ! 1899: mov 7,r7 ! 1900: tick3: ! 1901: dec r5,- ! 1902: brz tick4 ! 1903: tick3.2: ! 1904: br7 tick5 ! 1905: asl r5,r5|brg ! 1906: dec r7 ! 1907: br tick3.2 ! 1908: tick3.5: ! 1909: asl r5,r5|brg ! 1910: dec r7 ! 1911: brc tick3 ! 1912: tick4: ! 1913: dec r6 ! 1914: brc tick2 ! 1915: br tick9 ! 1916: tick5: ! 1917: /* ! 1918: * found this channel (r6<<2 + r7) is timer active (i.e. YTIMACT) ! 1919: */ ! 1920: mov r6,brg ! 1921: mov brg,r9 ! 1922: asl r9 ! 1923: asl r9 ! 1924: asl r9 ! 1925: mov r7,brg ! 1926: add brg,r9 /* r9 is the chan # */ ! 1927: GLTE(r9) ! 1928: mov C_Y,brg ! 1929: add brg,r10,mar ! 1930: mov mem,r0 ! 1931: mov YTIME,brg ! 1932: orn brg,r0,- ! 1933: brz tick7 ! 1934: br timeerr ! 1935: tick7: ! 1936: /* ! 1937: * timer processing is enabled for this chan ! 1938: */ ! 1939: mov YEXPIRE,brg ! 1940: orn brg,r0,- ! 1941: brz timeerr ! 1942: mov YTIMACT,brg ! 1943: orn brg,r0,- ! 1944: brz 1f ! 1945: br timeerr /* timer not active */ ! 1946: 1: ! 1947: /* ! 1948: * timer is active, dec ITIME ! 1949: */ ! 1950: mov C_ITIME,brg ! 1951: add brg,r10,mar ! 1952: mov mem,r0 ! 1953: dec r0,mem ! 1954: brc tick3.5 /* not reach zero yet */ ! 1955: /* ! 1956: * timer expires: set YEXPIRE ! 1957: */ ! 1958: mov C_Y,brg ! 1959: add brg,r10,mar ! 1960: mov mem,r0 ! 1961: mov YEXPIRE,brg ! 1962: or brg,r0,mem ! 1963: /* ! 1964: * YEXPIRE is set: call 'rcv' ! 1965: */ ! 1966: mov %rcvsave,%mar ! 1967: mov rcvsave,mar ! 1968: mov r5,mem|mar++ ! 1969: mov r6,mem|mar++ ! 1970: mov r7,mem|mar++ ! 1971: CALL(rcv,s.rcv) ! 1972: mov %rcvsave,%mar ! 1973: mov rcvsave,mar ! 1974: mov mem,r5|mar++ ! 1975: mov mem,r6|mar++ ! 1976: mov mem,r7|mar++ ! 1977: CHK(B5_TIME,5) ! 1978: tick8: ! 1979: /* ! 1980: * reset timemap for this chan ! 1981: * the following was done in 'rcv' ! 1982: mov %bitpatt,%mar ! 1983: mov bitpatt,brg ! 1984: add brg,r7,mar ! 1985: mov mem,r0 ! 1986: mov %timemap,%mar ! 1987: mov timemap,brg ! 1988: add brg,r6,mar ! 1989: xor mem,r0,mem ! 1990: */ ! 1991: br tick3.5 ! 1992: timeerr: ! 1993: /* ! 1994: * should never happen: will be removed after being debugged ! 1995: */ ! 1996: mov 0222,brg ! 1997: mov brg,r15 ! 1998: br . ! 1999: ! 2000: tick9: ! 2001: /* ! 2002: * dec 5 sec timer, goto timeout if expires ! 2003: * steals this 50-us cycle and 'time' no returns ! 2004: */ ! 2005: mov clk5s,mar ! 2006: mov %clk5s,%mar ! 2007: mov mem,r0 ! 2008: dec r0 ! 2009: mov r0,mem|mar++ ! 2010: mov mem,r1 ! 2011: mov 0,brg ! 2012: subc brg,r1,mem ! 2013: and mem,r0,- ! 2014: brz time ! 2015: tick10: ! 2016: /* ! 2017: * if (outq) goto csrck4; ! 2018: * This is the replacement of sending a dummy packet to chan 511 ! 2019: */ ! 2020: mov outq,mar ! 2021: mov %outq,%mar ! 2022: mov mem,r0 ! 2023: brz disp2 ! 2024: csrck4: ! 2025: /* ! 2026: * Output data request--jump to output segment ! 2027: */ ! 2028: mov %out,brg ! 2029: mov brg,pcr ! 2030: jmp out ! 2031: csrck2: ! 2032: /* ! 2033: * Input data available--jump to input segment ! 2034: */ ! 2035: mov %in,brg ! 2036: mov brg,pcr ! 2037: jmp in ! 2038: ! 2039: time: ! 2040: /* ! 2041: * timeout routine ! 2042: * for each active chan, if (S != R+1) send ENQ ! 2043: */ ! 2044: /* ! 2045: * reinitialize the clk5s ! 2046: */ ! 2047: mov clk5s,mar ! 2048: mov %clk5s,%mar ! 2049: mov CLT0,mem|mar++ ! 2050: mov CLT1,mem ! 2051: mov CHANMODS,brg ! 2052: mov brg,r9 /* channel # */ ! 2053: time1: ! 2054: dec r9 ! 2055: brz disp2 ! 2056: GLTE(r9) /* setup r8/r10 for LTE */ ! 2057: mov C_X,brg ! 2058: add brg,r10,mar ! 2059: mov mem,brg ! 2060: br0 time1 /* bit 0 indicates un-initialized */ ! 2061: br1 time2 /* bit 1 indicates initialized */ ! 2062: /* ! 2063: * INIT1 was sent and no reply; keep sending INIT1 ! 2064: */ ! 2065: mov I_INIT1,brg ! 2066: br time3 ! 2067: time2: ! 2068: /* ! 2069: * chan is active, if (S!=R+1) send ENQ ! 2070: */ ! 2071: mov C_S,brg ! 2072: add brg,r10,mar ! 2073: mov mem,r1|mar++ ! 2074: mov mem,r0 ! 2075: inc r0 ! 2076: mov WINDOW,brg ! 2077: and brg,r0,brg ! 2078: addn brg,r1,- ! 2079: brz time1 ! 2080: mov C_X1,brg ! 2081: add brg,r10,mar ! 2082: mov mem,r0 ! 2083: mov ~(XACK|XREJ),brg ! 2084: and brg,r0 /* reset XACK and XREJ */ ! 2085: mov XENQ,brg ! 2086: or brg,r0,mem /* set XENQ */ ! 2087: mov I_ENQ,brg ! 2088: time3: ! 2089: mov brg,r1 ! 2090: CALL(send,s.send) /* argument in r9, r1 */ ! 2091: br time1 ! 2092: ! 2093: err_bus: ! 2094: /* ! 2095: * The Unibus transfer fails to complete within 20 usec ! 2096: * Clear NEM bit, queue the error, and go to disp ! 2097: */ ! 2098: mov nprx,r0 ! 2099: mov ~(BRQ|ACLO|NEM),brg ! 2100: and brg,r0,nprx ! 2101: ERROR(E_BUS) ! 2102: br disp ! 2103: ! 2104: err_dup: ! 2105: /* ! 2106: * Two SEND command ! 2107: */ ! 2108: ERROR(E_DUP) ! 2109: br disp ! 2110: ! 2111: noqb: ! 2112: /* ! 2113: * no queue or buffer ! 2114: */ ! 2115: ERROR(E_NOQB) ! 2116: br disp ! 2117: ! 2118: errlog: ! 2119: /* ! 2120: * r9 - chan# ! 2121: * brg - error code ! 2122: * after interrupt cpu, go to init and wait for reinitialization ! 2123: */ ! 2124: mov repinfo,mar ! 2125: mov %repinfo,%mar ! 2126: mov KS_ERR,mem|mar++ ! 2127: mov brg,mem ! 2128: CALL(report,s.report) ! 2129: br disp2 ! 2130: ! 2131: /* ! 2132: * End of segment 0 ! 2133: */ ! 2134: endseg0: ! 2135: /* ! 2136: * Pick up code from other segments ! 2137: */ ! 2138: #include "output.s" ! 2139: #include "input.s" ! 2140: #include "subr.s"
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.