; IfsFastStreamsA.asm -- IFS version
; Copyright Xerox Corporation 1979, 1980

; Last modified March 2, 1980  3:54 PM by Taft
; - use ObjCall to enter Bcpl procedures at entry rather than entry+1

; Derived from FastStreamsA.asm, OS 17 version
; 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

; The instruction
;	ObjCall n
; jumps to the procedure at @(AC0+n)
; Unlike the standard Calls mechanism, this one enters the called procedure
; at instruction 0 rather than instruction 1, and does not clobber AC3.

.dmr ObjCall = 65400

;---------------------------------------------------------------------------
.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
; IFS: flush this feature -- nobody uses it, and it's troublesome
; to implement in the IFS environment.
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)
; can't use ObjCall here because stream is in ac1, not ac0
; 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 savedPC,2
	ObjCall getOverflow-.fs


;---------------------------------------------------------------------------
.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 savedPC,2
	ObjCall putOverflow-.fs


;---------------------------------------------------------------------------
.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