SRI-NOSC/dmr/oldstuff/backc.c
#define ASSEMBLY /* so C code will not be defined */
#include "../../h/param.h" /* get defines of various types */
.globl _backc / backs up one character in the queue
/ it's a mildly expensive operation -- use
/ with care
PS = 177776
.globl _cfreelist
#ifdef UCBUFMOD
KISA6 = 172354
.globl _clistp, _cu
#endif UCBUFMOD
_backc: / backc(arg)
/ first check to see if the queue is empty -- if so, return a
/ minus one to indicate that fact
mov 2(sp),r1 / q = arg
tst (r1) / if(q->count == 0)
bne 1f
mov $-1,r0 / return (-1)
rts pc
/ so there is at least one character in the queue. since we will
/ muck around with the list, we arrange for indivisibility and get
/ the last character (the tail pointer points one past the last
/ character in the queue).
1:
mov r2,-(sp) / save regs
mov r3,-(sp)
mov PS,-(sp) / save old priority
#ifndef UCBUFMOD
bis $340,PS / spl5()
bic $100,PS
#endif not UCBUFMOD
#ifdef UCBUFMOD
mov r4,-(sp)
mov KISA6-40,-(sp)
mov KISA6,r4
bis $340,PS / spl7()
mov _clistp,KISA6 / map in clist area
mov $77406,KISA6-40
#endif UCBUFMOD
mov 4(r1),r2 / c = *(t = --q->tail)&0377
movb -(r2),r0
mov r2,4(r1)
bic $!377,r0
/ decrement the queue counter and check to see if we removed the last
/ character. if we did, zap the queue pointers and arrange
/ for the return of the queue element to the free list.
dec (r1)+ / if(--q->count)
bne 5f
clr (r1)+ / q->head = 0
clr (r1)+ / q->tail = 0
bic $7,r2 / t =& not 7
br 6f
/ check to see if we just removed the first character in this queue
/ element. if we did, we must find its predecessor (which must exist,
/ since there is at least one other character in the queue). if not,
/ we can just peaceably go away.
5:
mov r2,r3 / if((t&7) == 2)
bic $!7,r3
cmp $2,r3
bne 4f
/ expensive part -- must search queue from front to find element
/ linked to this one -- it will become new tail
/ fix the pointers so they point at the beginning of the q element.
bic $7,r2 / t =& not 7
mov (r1),r3 / p = (q->head & not 7)
bic $7,r3
/ search down the queue until the predecessor is found
2:
cmp (r3),r2 / if(p->link != t)
beq 3f
mov (r3),r3 / p = p->link
bne 2b / loop if not end-of-list
br . / error, should not find it
/ fixup the end of the queue by making the last element point to
/ null and the tail pointer point past the last character in that
/ element.
3:
clr (r3) / p->link = 0
add $10,r3 / q->tail = ++p
mov r3,2(r1)
/ return the released queue element to the free list
6:
mov _cfreelist,(r2) / t->link = cfreelist
mov r2,_cfreelist / cfreelist = t
/ that's all -- return the character we removed to the caller.
4:
#ifdef UCBUFMOD
mov r4,KISA6 / map _u back in
mov (sp)+,KISA6-40
mov (sp)+,r4
#endif UCBUFMOD
mov (sp)+,PS
mov (sp)+,r3 / restore regs
mov (sp)+,r2
rts pc / return (c)