.title	'Set emulation mode for 1280/5080'
	.ident	enable
	.pabs
	.phex
	.loc	100h

vers	==	'1'	; version
rev	==	'3'	; revision
mod	==	'A'	; modification
;
; update history:
;
; 1.3A 8/15/83	Added 5080 control p interface
;
; 1.3  7/11/83  Added code in to interface to 246
;
; 1.2  6/7/83	Add a few equates, .page listing,
;		clean up listing, add some comments,
;		set for release. DRB
;
;  A   6/6/83	cleaned up code as per test's
;		suggestions
;
; 1.1  6/2/83	added patch to bios for scr #48
;
; 1.0  5/23/83  wrote this utility to enable hardware
;		hand-shaking for various dms-1280
;		emulation modes.  Mike Pompa
.page
;
; CP/M equates
; 
bdos	==	5	;bdos entry point
conout	==	2	;console byte out
consout ==	9	;console string out
conin	==	1	;console byte input
conio	==	6	;direct console byte out
fcb	==	5ch
bios	==	0	;jmp to bios ept
;
; ASCII equates
;
ctrln	==	'N' & 1fh
ctrlf	==	'F' & 1fh
ctrltilde ==	'~' & 1fh
ctrlo	==	'O' & 1fh
esc	==	'[' & 1fh	; escape
cr	==	'M' & 1fh	; carriage rtrn
lf	==	'J' & 1fh	; linefeed
ctrlt	==	'T' & 1fh
ctrlr	==	'R' & 1fh

apost	==	"`"
chara	==	'A'
charf	==	'F'
tilde	==	'~'
quest	==	'?'
charla	==	'a'
slash	==	'/'
num	==	'0'
astr	==	'*'
at	==	'@'
opbrak	==	'['
nul	==	0
;
; misc equates
;
test	==	1	; 1=no 0=yes
NETuser ==	47h	; loc of network user #
master	==	0	; master's user #
standalone ==	0ffh	; standalone's user #
extjmp	==	5dh	; extended bios jmp table
biover	==	extjmp+(5*3) ; bios version offset
SetListType ==	extjmp+(16*3) ; esc sequences offset
 
.page
start:	
	pop	h	; save return to ccp
	shld	retpt
	sspd	sptr	; save stack ptr
	lxi	sp,stack ; load local stack

	lxi	d,signon ; sign-on version msg
	mvi	c,consout
	call	bdos

	lxi	h,option ; find terminal option
loop:
	lxi	d,fcb+1	; check cmd line option
	mvi	b,3
	call	blkcmp
	jz	output
	inx	h   ;increment past string ptr
	inx	h
	mov	a,m	; check if done
	cpi	0
	jnz	loop

	lxi	d,ask
	mvi	c,consout ; ask interactively
	call	bdos
again:
	mvi	c,conin	; get 1 byte answer
	call	bdos

	sui	num	;convert response to bin
	jc	error	;too low
	jz	finish	;zero option - skip patch
	cpi	maxopt+1;maximum option number	
	jnc	error	;too high
	dcr	a	;adjust displacement
	push	psw	;save a
	lxi	d,crlf	; new line
	mvi	c,consout
	call	bdos
	pop	psw	;restore a
	lxi	h,inttab ; get table base
	slar	a	; compute offset
	mov	c,a	; bc <- a
	mvi	b,0
	dad	b	; hl <- hl + bc
	jmp	output
error:
	lxi	d,notfound
	mvi	c,consout
	call	bdos
	jmp	again	; loop if invalid
.page	
;
; the emulation option has now been selected
; point hl to the character sequence to enable
; hardware handshaking and output the characters
; until we hit a 0 trailer
;
output:
	mov	a,M	; hl <- (hl)
	inx	h
	mov	h,M
	mov	l,a	; HL = ASCII message
next:
	mov	a,M	; get control char
	cpi	0	; done?
	jz	done	;yes

	push	h	
	mov	e,a	; send char to screen
	mvi	c,conio
	call	bdos
	pop	h

	inx	h	; bump to next char
	jmp	next
.page
; the characters after the hardware handshaking
; sequence are the buffer print off and buffer
; print on escape sequences that the bios
; needs to output periodically
;
; in bios versions < 246 we need to patch
; the bios to disable the adds ctrlp 
; printer code
;
; in the new bios, there is a new bios entrypoint
; SetListType to pass the control sequences to
; the bios via the hl and de register pairs
;
done:
	push	h	; ptr to buf prt esc seq

	lda	NETuser	; check network user #
	cpi	master	; at a master?
	jz	finish	; yes, don't do it
	cpi	standalone ; standalone?
	jz	finish	; yes, don't do it

	lda	bios+2 ; msb of bios jmp table
	mov	h,a
	mvi	l,biover ; offset into jmp table

	lxi	d,oldver ; where bios ver is
	mvi	b,verlen
	call	blkcmp
	jnz	newstyle ; must be version >245
	pop	h	; restore stack

	lxi	h,oldcode ; check for old code
	lxi	d,biocode ; where old code is
	mvi	b,codlen
	call	blkcmp
	jnz	finish	; no don't do it

	mvi	a,ret	; well, it seems ok, 
			; patch a ret operand
	sta	patch	; here goes nothing!
finish:
	lspd	sptr	; restore stack pointer
	lhld	retpt	; ptr to return to ccp
;
.ife test,[jmp	bios]	; reboot during test
	pchl		; return to ccp
.page
;
; a new bios entrypoint, SetListType was added
; in version 246 to accept the buffer print
; enable and buffer print disable escape
; sequences.
;
newstyle:
	pop	h	; restore stack
	inx	h	
	mov	d,M	; d <- 1st char disable
	inx	h
	mov	e,M	; e <- 2nd char disable

	inx	h
	mov	a,M
	inx	h
	mov	l,M	; l <- 2nd char enable
	mov	h,a	; h <- 1st char enable

	lxi	b,finish ; return here when done
	push	b

	lda	bios+2 ; msb of jmp table
	mov	b,a
	mvi	c,SetListType ; offset into table
	push	b	; simulate a call
	ret
.page
.sbttl 	'Subroutines'
;---------------
; Subroutine blkcmp:  Compare a block of bytes
;
; Reg in:    hl  points to one string
;	     de	 points to other string
;	     b	 is length to compare
;
; Reg out:   tz	 if match
;	     fz	 if mismatch
;	     hl	 points to end of str1
;	     de	 points to end of str2
; Destroyed: All
;
blkcmp:
	ldax	d
	cmp	m
	jrnz	scan
	inx	h
	inx	d
	djnz	blkcmp
	ret
;
scan:	inx	h
	inx	d
	djnz	scan
	ori	0ffh
	ret
.page
.sbttl	'CRT messages'
;
signon:	.ascii	[lf]'Enable 1280/5080 emulation mode, '
	.ascii	'version '
	.ascii	[vers]'.'[rev][mod][cr][lf][lf]'$'
ask:	.ascii	'0=exit 1=fr 2=tv 3=haz 4=adm 5=adds 6=5080: $'
notfound: .ascii [cr][lf]'option not found'
	.ascii	', re-enter: $'
crlf:	.ascii	[cr][lf]'$'
;
retpt:	.word	0
sptr:	.blkb	32
stack:
.page
.sbttl 'User Options'
; standard options are: fr tv haz adm adds 5080
; alternatively, use:   1  2  3   4   5    6
; several other common spellings and misspellings
;  are also acceptable, although not documented
;
; when run interactively, only digit options are valid
;
option:
	.ascii	'FR1'
	.word	fr100
	.ascii	'FR '
	.word	fr100
	.ascii	'1  '
	.word	fr100
;
	.ascii	'TV9'
	.word	tv910
	.ascii	'TE9'
	.word	tv910
	.ascii	'TV '
	.word	tv910
	.ascii	'2  '
	.word	tv910
;
	.ascii	'ADD'
	.word	adds
	.ascii	'ADS'
	.word	adds
	.ascii	'5  '
	.word	adds
;
	.ascii	'ADM'
	.word	adm
	.ascii	'4  '
	.word	adm
;
	.ascii	'HAZ'
	.word	haz
	.ascii	'H14'
	.word	haz
	.ascii	'3  '
	.word	haz

	.ascii	'508'
	.word	dms50
	.ascii	'500'
	.word	dms50
	.ascii	'6  '
	.word	dms50
;
	.byte	0
;
; option table for command line option
;
inttab:
	.word	fr100,tv910,haz,adm,adds,dms50
maxopt	==	(.-inttab)/2
.page
.sbttl 'Escape Sequences'
fr100:			; switches: d d d
	.ascii	'free'
	.byte	ctrln	;disable xon
	.ascii	'dom 1'
	.byte	esc,ctrlf ;enable hw hs
	.ascii	'00'
	.byte	0
	.byte	esc,charla ; buff prt off
	.byte	esc,apost  ; buff prt on

tv910:			; switches: u d d
	.ascii	'tele'
	.byte	ctrln	;disable xon
	.ascii	'video 9'
	.byte	esc,ctrlf ;enable hw hs
	.ascii	'10'
	.byte	0
	.byte	ctrlt,nul ;off
	.byte	ctrlr,nul ;on

haz:			; switches: d d u
	.ascii	'hazel'	
	.byte	esc,charla ; disable xon
	.ascii	'tine 1'
	.byte	esc,ctrlf ; enable hw hs
	.ascii	'420'
	.byte	0
	.byte	esc,quest	;off
	.byte	esc,astr	;on

adm:			; switches: u d d
	.ascii	'a'
	.byte	ctrlo ; disable bi dir port
	.ascii	'd'
	.byte	esc,apost ; disable xon
	.ascii	'm 3'
	.byte	esc,ctrlf ; enable hw hs
	.ascii	'/5'
	.byte	0
	.byte	esc,chara ; off
	.byte	esc,at	  ; on

adds:			; switches: d u d
	.ascii	'ad'
	.byte	ctrln	; disable xon
	.ascii	'ds 2'
	.byte	esc,tilde ;enable hw hs
	.ascii	'5'
	.byte	0
	.byte	esc,num+4 ; off
	.byte	esc,num+3 ; on
dms50:
	.ascii	'dms 5080'
	.byte	0
	.byte	nul,nul		;off
	.byte	esc,opbrak	;on
.page
.sbttl 'Patches for ^P problem'
; Equates and code for blkcmp and modification  of
; station BIOS so DMS-1280 works correctly
;
			; If it is the old version
oldver:			; a rst 0 is there
	rst	0
verlen	==	.-oldver
;
biocode	==	0ded4h	; The BIOS code to modify
			; starts at this addr and
oldcode:		; looks like this.
	cpi	'P'-40h
here:	rnz		; Here is where we want a RET
	mov	b,a
	lda	3
codlen	==	.-oldcode
			; the patch addr is set up 
patch	==	biocode+here-oldcode ; with an equate
;
	.end

