; FastStreamsA.asm -- companion file to FastStreamsB.bcpl
; Copyright Xerox Corporation 1979
; Last modified July 12, 1979  3:50 PM by Taft

; BCPL frame offsets
savedPC = 1
temp = 2

; outgoing procedures
.bext CurrentPos, Dirty, SetDirty

; outgoing statics
.bext fastChStream, fastWstream

; incoming statics
.bext Noop, SysErr, StreamError

	.srel

fastChStream: .fchs
fastWstream: .fws
CurrentPos: .CurrentPos
Dirty:	.Dirty
SetDirty: .SetDirty

	.nrel
; the template below must parallel the FS structure declaration
.fs:
.fchs:	00		; ST.par1
	00		; ST.par2
	StreamError	; ST.close
	GetCh		; ST.gets
	PutCh		; ST.puts
	Noop		; ST.reset
	StreamError	; ST.putback
	SysErr		; ST.error
	Fendof		; ST.endof
	StreamError	; ST.stateof
	00		; ST.type
	00		; ST.par3

charPtr: 00		; stuff private to a fast stream
wordPtr: 00
count:	00
dirty:	00
eof:	00
putOverflow: SysErr
getOverflow: SysErr
getCC:	Noop
itemSize: 1		; 1 byte (charItem)
endPos: 00
savedGets: GetCh
lFS = .-.fs

.fws:	00		; word item version of fast stream
	00
	StreamError
	GetW
	PutW
	Noop
	StreamError
	SysErr
	Fendof
	StreamError
	00
	00

	00
	00
	00
	00
	00
	StreamError
	StreamError
	Noop
	2		; 2 bytes (wordItem)
	00
	GetW

	.srel

GetCh:	.GetCh
PutCh:	.PutCh

GetW:	.GetW
PutW:	.PutW

Fendof:	.Fendof

	.nrel

.rmask:	377
.lmask:	177400
.maxCC:	37

;---------------------------------------------------------------------------
.GetCh:				; Fast Gets (byte version)
;---------------------------------------------------------------------------
	sta 3 savedPC,2
	mov 0 3
	isz count-.fs,3
	 jmp .+2
	jmp callGetOv

	dsz charPtr-.fs,3
	jmp getOddCh
getEvenCh: isz wordPtr-.fs,3	; can't skip
	lda 0 @wordPtr-.fs,3
	lda 1 .lmask
	ands 1 0

; test for control char - we might not want this
GetCh1:	lda 1 .maxCC
	sgt 0 1
	 jmp gettingCC

done:	lda 3 savedPC,2		; lots of people come here
	jmp 1,3

getOddCh: mkone 0 0
	sta 0 charPtr-.fs,3
	lda 0 @wordPtr-.fs,3
	lda 1 .rmask
	and 1 0
	jmp GetCh1

; call getCC(character, stream)
gettingCC: mov 3 1
	lda 3 getCC-.fs,3
	jmp 1,3

;---------------------------------------------------------------------------
.PutCh:				; Fast Puts
;---------------------------------------------------------------------------
	sta 3 savedPC,2
	mov 0 3
	isz count-.fs,3
	 jmp .+2
	jmp callPutOv

	dsz charPtr-.fs,3
	 jmp putOddCh
putEvenCh: lda 0 .rmask
	isz wordPtr-.fs,3	; can't skip
	ands 0 1
PutCh1:	sta 1 temp,2
	lda 1 @wordPtr-.fs,3
	and 1 0
	lda 1 temp,2
	add 0 1
	sta 1 @wordPtr-.fs,3
	sta 3 dirty-.fs,3	; set non-zero (true)
	lda 3 savedPC,2
	jmp 1,3

putOddCh: mkone 0 0
	sta 0 charPtr-.fs,3
	lda 0 .rmask
	and 0 1
	movs 0 0
	jmp PutCh1

;---------------------------------------------------------------------------
.GetW:				; Fast Gets (word version)
;---------------------------------------------------------------------------
	sta 3 savedPC,2
	mov 0 3
	isz count-.fs,3
	 jmp .+2
	jmp callGetOv

	isz wordPtr-.fs,3	; can't skip
	lda 0 @wordPtr-.fs,3
	lda 3 savedPC,2
	jmp 1,3

callGetOv: dsz count-.fs,3	; can't skip
getOv1:	mov 3 0
	lda 3 getOverflow-.fs,3
	jmp 1,3


;---------------------------------------------------------------------------
.PutW:				; Fast Puts
;---------------------------------------------------------------------------
	sta 3 savedPC,2
	mov 0 3
	isz count-.fs,3
	 jmp .+2
	jmp callPutOv

	isz wordPtr-.fs,3	; can't skip
	sta 1 @wordPtr-.fs,3
	sta 3 dirty-.fs,3	; set non-zero (true)
	lda 3 savedPC,2
	jmp 1,3

callPutOv: dsz count-.fs,3	; can't skip
	mov 3 0
	lda 3 putOverflow-.fs,3
	jmp 1,3


;---------------------------------------------------------------------------
.Fendof:			; Fast Endofs
;---------------------------------------------------------------------------
	sta 3 savedPC,2
	mov 0 3
	lda 1 eof-.fs,3
	sz 1 1
	 jmp true
	lda 1 count-.fs,3
	inc# 1 1 szr
	 jmp false
	jmp getOv1


;---------------------------------------------------------------------------
.CurrentPos:
;---------------------------------------------------------------------------
	sta 3 savedPC 2
	mov 0 3
	lda 0 count-.fs 3
	inc 0 0
	lda 1 itemSize-.fs 3
	movr# 1 1 snc
	 movzl 0 0		; itemSize=2
	lda 1 endPos-.fs 3
	add 1 0
	jmp done


;---------------------------------------------------------------------------
.Dirty:
;---------------------------------------------------------------------------
	sta 3 savedPC 2
	mov 0 3
	lda 0 dirty-.fs 3
	sz 0 0
true:	 mkminusone 0 0 skp
false:	 mkzero 0 0
	jmp done


;---------------------------------------------------------------------------
.SetDirty:
;---------------------------------------------------------------------------
	sta 3 savedPC 2
	mov 0 3
	sta 1 dirty-.fs 3
	jmp done

	.end