; Copyright Xerox Corporation 1979, 1980, 1982

; PupBSPa.asm -- Assembly-language routines for BSP
;		- Companion to PupBSPb.bcpl

; Last modified May 17, 1982  2:10 PM by Taft

.ent BSPGets
.ent BSPPuts

.bext BSPGetCleanup
.bext BSPForceOutput
.bext offsetBSPStr

.srel

BSPGets: .BSPGets
BSPPuts: .BSPPuts

.nrel


; Routines implementing fast BSP streams

; The BSP stream structure is assumed to be the following:
;	@ST		; Words 0-11.
	iPBI=12.	; Current input packet buffer item
	iWordP=13.	; Ptr to word containing next byte
	iByteP=14.	; Next byte position: 0=left, 1=right
	iByteC=15.	; Input remaining byte count
	oPBI=16.	; Current output packet buffer item
	oWordP=17.	; Ptr to word containing next byte
	oByteP=18.	; Next byte position: 0=left, 1=right
	oByteC=19.	; Output remaining byte count


; BSPGets(str) - returns next byte from BSP Stream

.BSPGets:
	sta 3 1 2		; Save incremented return
	isz 1 2
	mov 0 3			; Stream pointer
	lda 0 @iWordP 3		; Get word containing desired byte
	dsz iByteP 3		; Which byte?
	 jmp getevn		; Left byte

; Get right (odd) byte and advance word pointer
	lda 1 c377		; Mask right byte
	and 1 0
	isz iWordP 3		; Advance word pointer
	dsz iByteC 3		; Decrement and test count
	 jmp @1 2		; Not exhausted, return
	jmp gets1		; Exhausted

; Get left (even) byte
getevn:	lda 1 c177400		; Mask left byte
	ands 1 0		; Right-justify
	mkone 1 1		; Reset byte position
	sta 1 iByteP 3
	dsz iByteC 3		; Decrement and test count
	 jmp @1 2		; Not exhausted, return

; Count now exhausted, call cleanup procedure
gets1:	mov 0 1			; Save data byte
	mov 3 0
	lda 3 @lvoffsetBSPStr	; Convert str to soc
	sub 3 0
	lda 3 @lvBSPGetCleanup	; BSPGetCleanup(soc, byte)
	jmp bcplExit

; Fast BSP streams (cont'd)

; BSPPuts(str, byte) - outputs byte on BSP Stream

.BSPPuts:
	sta 3 1 2		; Save incremented return
	isz 1 2
	mov 0 3			; Stream pointer
	lda 0 c377		; Get byte mask
	dsz oByteP 3		; Which byte?
	 jmp putevn		; Left byte

; Store right (odd) byte and advance word pointer
	and 0 1			; Mask out garbage in lh of byte
	lda 0 @oWordP 3		; Get previously stored lh byte
	add 0 1			; Append rh byte
	sta 1 @oWordP 3		; Store it back
	isz oWordP 3		; Advance word pointer
	mkminusone 0 0		; Prepare to return true
	dsz oByteC 3		; Decrement and test count
	 jmp @1 2		; Not exhausted, return
	jmp puts1		; Exhausted

; Store even (left) byte
putevn:	ands 0 1		; Mask byte and put in lh
	sta 1 @oWordP 3		; Store it (clear rh byte)
	mkone 1 1		; Reset byte position
	sta 1 oByteP 3
	mkminusone 0 0		; Prepare to return true
	dsz oByteC 3		; Decrement and test count
	 jmp @1 2		; Not exhausted, return

; Count now exhausted, call cleanup procedure
puts1:	mov 3 0
	lda 3 @lvoffsetBSPStr	; Convert str to soc
	sub 3 0
	mkzero 1 1
	lda 3 @lvBSPForceOutput	; BSPForceOutput(soc, false)
bcplExit:
	sta 3 2 2		; Bcpl procedure we exit to
	dsz 1 2			; Restore original return PC
	lda 3 1 2
	jmp @2 2

lvBSPGetCleanup: BSPGetCleanup
lvBSPForceOutput: BSPForceOutput
lvoffsetBSPStr: offsetBSPStr

c377:	377
c177400: 177400


	.end