;++
; RSXTEM - RSXMAKER RSX Template
;
; Copyright (c) 1986 by AutoSoft Incorporated
;
; See RSXMAKER.DOC for information.
;
;--

;+
; RSX Header RFLAGS Flag bit definitions
;-
FIRST	EQU	1	; First RSX inctalled
LAST	EQU	2	; Last RSX installed
NOREMOV	EQU	4	; RSX may be removed
REINIT	EQU	8	; Re-initialize on subsequent installation requests
MULTI	EQU	16	; Install another copy on subsequent installs
OVRLAY	EQU	32	; Overlay CCP if first RSX installed
NOMORE	EQU	64	; No more RSX's may be installed
NORELO	EQU	128	; Do not relocate this RSX
RELINI	EQU	256	; Call INIT routine after relocation

;+
; RSX Header Section begins here
;-
	ORG	100H		; Origin *must* be at 100H

;+
; Do not modify these 14 fields
;-
RSX:	JMP	RSTART		; Jump to real code (jumped to from 0005)
RSXRST:	JMP	RESET		; Reset handler
RINIT:	JMP	INIT		; Initialization code
RTERM:	JMP	TERM		; Termination code
RELST:	JMP	RSXCODE		; Start of relocatable code
DATAST:	JMP	RSXDATA		; Start of data section (copied as is)
RELEND:	JMP	RSXEND		; End of RSX code and data to be relocated
NXTWB:	JMP	$-$		; WBOOT path (filled in by RSXMAKER)
NEXT:	JMP	$-$		; BDOS path (filled in by RSXMAKER)
WBADR:	DW	$-$		; Filled in by RSXMAKER
WBJMP:	DW	$-$		; Filled in by RSXMAKER
RSIZE:	DW	RSXEND-RSX	; Size of RSX code and data
RSXID:	DB	'AutoSoft'	; ID - Must be 'AutoSoft'

;+
; The next three fields may be modified by the RSX programmer
;-
RFLAGS:	DW	RELINI+REINIT 	; RSX flags (combine with +)
RNAME:	DB	'7BIT    '	; Name - must be 8 bytes - pad on rt w/spaces
RDESC:	DB	'Convert IBM-char. to ASCII-char. and strip high bit.',0
		; Description (null terminated)


;+
; RSX Code Section begins here
;-
RSXCODE EQU $			; Executable code *only* between here
				; and RSXDATA (no in-line prints allowed)

;+
; Initialization Routine (end with RET)
;-
INIT:				; This *must* be the label

	MVI	L,01		; Get address of BIOS
	MVI	H,00
	MOV	A,M
	INX	H
	MOV	H,M
	MOV	L,A
	MVI	E,10		; Offset to address of console out
	MVI	D,0
	DAD	D		; Add to BIOS warm-boot address
	PUSH	H
	POP	D		; To DE
	SHLD	TEMP		; And store a safe place
	MOV	A,M		; Get address of BIOS-routine
	INX	H
	MOV	H,M
	MOV	L,A
	SHLD	STOP		; And place at end of our own routine		
	LXI	H,START		; Get start of our own routine
	MOV	A,L
	STAX	D
	INX	D		; And place it at BIOS jump table
	MOV	A,H
	STAX	D
	MVI	C,9		; Then write a message to the console
	LXI	D,INITMSG	;
	CALL	NEXT		;
	RET			; And return

;+
; Termination Routine (end with RET)
;-
TERM:				; This *must* be the label

	LHLD	TEMP		; Get address of BIOS jump
	PUSH	H
	POP	D
	LHLD	STOP		; And store address of BIOS routine
	MOV	A,L
	STAX	D
	INX	D
	MOV	A,H
	STAX	D
	MVI	C,9		; Then write a message to the console
	LXI	D,TERMMSG	;
	CALL	NEXT		;
	RET			; And return

;+
; BDOS Intercept Routine (end with JMP NEXT or RET)
;-
RSTART:				; This *must* be the label

	MVI	H,0		; Clear HL
	MVI	L,0
	DAD	SP		; Get current stack pointer
	SHLD	USRSTK		; Save it
	LXI	SP,LOCSTK	; Switch to local stack

	PUSH	B		;
	PUSH	PSW		;
;
	MOV	A,C		; Get BDOS call
	CPI	2		; Console output?
	JZ	OUTCHAR		; Then check character
	CPI	6		; Direct console i/o?
	JNZ	FINISH		; No, then go to BDOS
	MOV	A,E		; Get byte to BDOS
	CPI	0FDH		; Is it console output?
	JNC	FINISH		; No, then go to BDOS
OUTCHAR:
	MOV	A,E
	PUSH	D
	LXI	H,CTDATA1	; Point to character to be converted
	LXI	D,CTDATA2	; Point to new character
	MVI	B,6		; Number of characters
LOOP:
	CMP	M		; Compare with character
	JZ	FOUND
	INX	D		; Increase pointers
	INX	H
	DCR	B		; Decrease counter
	JNZ	LOOP
	POP	D
;
;
FINISH:
	POP	PSW		; Restore environment
	POP	B		;
	LHLD	USRSTK		; And stack pointer
	SPHL			;
	JMP	NEXT		; Pass control to next RSX
;
FOUND:
	LDAX	D		; Get new character
	POP	D
	MOV	E,A
	JMP	FINISH
;
START:				; This is the routine linked to
	MOV	A,C		; the console output routine
	ANI	7FH		; Remove high bit
	MOV	C,A
STOP	EQU	$+1
	JMP	$-$
;+
; WBOOT Intercept Routine (end with JMP NXTWB)
;-
RESET:	LXI	SP,LOCSTK	; Local stack

	LHLD	RFLAGS		; HL = flags word
	MOV	A,L		; Low byte
	ANI	FIRST		; First?
	JZ	NOT1ST		; If Z, no

	MVI	C,13		; Disk system reset
	CALL	NEXT		; (you might want to comment this and the
				; previous line out to speed up warm boots)

NOT1ST:	MOV	A,L		; Get flags
	ANI	LAST		; Last?
	JZ	NOTLST		; If Z, no

	LXI	H,RSX		; Else reload BDOS vector
	SHLD	0006		;
	LHLD	WBJMP		; HL -> WBOOT vector in BIOS jump table
	SHLD	0001		; Insert WBOOT vector
	INX	H		; Point past JMP
	LXI	D,RSXRST	; Our WB address
	MOV	M,E		; Copy it into BIOS jump table
	INX	H		;
	MOV	M,D		;

NOTLST:	JMP	NXTWB		; And pass control to next RSX (or CCP)

;+
; RSX Data Section
;-
RSXDATA EQU $			; Data *must* start here - no data
				; allowed before this point; no executable
				; code beyond.

TERMMSG:
	DB	'7 bit converter is removed.',13,10,'$'
INITMSG:
	DB	'7 bit converter is installed.',13,10,'$'
CTDATA1:
	DB	91H,9BH,86H,92H,9DH,8FH
CTDATA2:
	DB	7BH,7CH,7DH,5BH,5CH,5DH
;
TEMP:
	DS	2
	DS	16		; 16-byte stack
LOCSTK:				; Initial SP
USRSTK:	DW	0		; Caller's SP

RSXEND EQU $			; No code or data allowed beyond this label
