*****************************************************
;FLASH WRITER CUSTOM CPM IO ROUTINES FOR 2D
;THINKERTOY.  DRIVER IS FOR PASCAL.
; MODES M.JACOBY  OCT.28,79
**************************************************
 ;	SYSTEM EQUATES
******************************************************
 MSIZE	EQU	48		;CP/M SYSTEM SIZE IN KBYTES
 BIAS	EQU	(MSIZE-16)*1024
 CPMB	EQU	2600H+BIAS	;LOCATION OF CCP
 BDOS	EQU	2E00H+BIAS	;LOCATION OF BDOS
 BIOS	EQU	3B00H+BIAS	;LOCATION OF BIOS
 USER	EQU	BIOS+380H	;START OF USER AREA
 OFFSET	EQU	1E80H-BIOS	;TO SYSGEN IMAGE
 ;
 ;*********************************************************
 ;	DISK PARAMETERS - DOUBLE DENSITY DISK JOCKEY
 ;*********************************************************
 ;	ON DISK			IN SYSGEN	IN 24K SYSTEM
 ;	TRACK	SECTOR		ADDRESS
 ;BOOT	0	1		 900H		0E700H
 ;CCP	1	1		0980H		4600H
 ;BDOS	1	17		1180H		4E00H
 ;BIOS	1	43		1E80H		5B00H
 ;MODE	1	49		21FFH		5E7FH
 ;USER	1	50-52		2200H		5E80H
 ;TOP OF SYSTEM			237FH		5FFFH
 ;
 ;DOUBLE DENSITY SKIP TABLE
 ;	1,2,19,20,37,38,3,4,21,22,39,40,5,6,23,24,41,42
 ;	7,8,25,26,43,44,9,10,27,28,45,46,11,12,29,30,47,48
 ;	13,14,31,32,49,50,15,16,33,34,51,52,17,18,35,36
 ;
 ;*********************************************************
 ;MODE BYTE OPTIONS AND DENSITY SETTINGS OF VARIOUS DRIVES
 ;*********************************************************
 ;
 	ORG	USER-8		;5E78H IN 24K SYSTEM
 DNSTY:	DB	1,0,1,1		;DRIVE B SD, OTHERS DD
 		;B0=DENSITY	0=SNGL,	1=DBL
 	DB	0		;RESERVED
 MODE:	DB	1		;MODE BYTE
 		;BIT0=1 DOES AUTO ON COLD BOOT
 		;BIT1=1 DOES AUTO ON WARM BOOT
 ;
  ;*********************************************************
 ;	SAMPLE USER AREA
 ;*********************************************************
 ;
 ;TTY EQUATES
 STATUS	EQU	0		;TTY STATUS PORT
 DATA	EQU	1		;TTY DATA PORT
 RDA	EQU	10H		;DATA AVAILABLE MASK
 RDAMSK	EQU	RDA		;SENSE IS ACTIVE LOW
 TBE	EQU	20H		;BUFFER EMPTY MASK
 TBEMSK	EQU	TBE		;SENSE IS ACTIVE LOW
 STOPCHR EQU	'Q'-40H		;STOPS EVERYTHING
 ;
 	ORG	USER		;5E80H IN DIST SYSTEM
 ;
 ;JUMP TABLE - JMPS MUST REMAIN HERE, IN SAME ORDER
 INIT	JMP	INITR		;INITIALIZATION
 CONST	JMP	TTYST		;CONSOLE STATUS
 CONIN	JMP	TTYIN		;CONSOLE INPUT
 CONOUT	JMP	DRIVE		;CONSOLE OUTPUT FLASHWRITER
 LIST	JMP	TTYOUT		;LIST OUTPUT
 PUNCH	JMP	TTYOUT		;PUNCH OUTPUT
 READER	JMP	TTYIN		;READER INPUT
 PRST	JMP	TTYPRST		;PRINTER STATUS
 ;
 ;*********************************************************
 ;CONSOLE INPUT CHAR TO REGISTER A
 ;*********************************************************
 TTYIN:
 	IN STATUS		;GET STATUS BYTE
 	ANI RDA			;EXAMINE STATUS BIT
 	XRI	RDAMSK		;MAKE ACTIVE LOW
 	JNZ	TTYIN		;LOOP FOR CHARACTER
 	IN	DATA		;INPUT THE CHARACTER
 	ANI	7FH		;STRIP PARITY
 	RET
 ;*********************************************************
 ;CONSOLE STATUS AND STOP ROUTINE
 ;*********************************************************
 TTYST:
 	IN	STATUS		;KEY PRESSED ?
 	ANI	RDA
 	XRI	RDAMSK
 	MVI	A,0		;NO  A=0
 	RNZ			;EXIT
 	CMA
	RET
; 	IN	DATA		;YES
; 	ANI	7FH		;GET CHARACTER
; 	CPI	STOPCHR		;CHARACTER=STOP?
; 	JZ	ST1
; 	MVI	A,0		;NO
; 	RET			;   EXIT
   				;CHECK FOR STOP KEY TO CONTINUE
; ST1	IN	STATUS		;KEY PRESSED ?
; 	ANI 	RDA
; 	XRI	RDAMSK
; 	MVI	A,0
;  	JNZ	ST1		;N0  GO BACK CHECK AGAIN
; 	RET			;YES ALL DONE
 ;
 ;
 ;*********************************************************
 ;CONSOLE OUTPUT CHAR FROM REGISTER C
 ;*********************************************************
 TTYOUT:
 	IN	STATUS		;GET STATUS BYTE
 	ANI	TBE		;EXAMINE STATUS BIT
 	XRI	TBEMSK		;MAKE ACTIVE LOW
 	JNZ	TTYOUT		;LOOP FOR CHAR
 	MOV	A,C		;CHAR INTO C REG
 	OUT	DATA		;AND OUTPUT
 	RET
 ;
 ;*********************************************************
 ;PRINTER STATUS CHECK, NOT YET IMPLEMENTED
 ;*********************************************************
 TTYPRST:
 	XRA	A		;NO CHAR READY
 	RET			;SO RET WITH ACC=0
 ;
 ;*********************************************************
 ;INITIALIZATION ROUTINE GOES HERE IF NEEDED
 ;MAKE SURE IT ENDS WITH A RET.
 ;*********************************************************
INITR:;	LXI	H,VADD
; 	SHLD	CURS
       	MVI	C,16H	;CLEAR SCREAN SYM.
 	CALL	DRIVE
	RET
 ;***********************************************************
 ;THIS AREA DEFINES THE EQUATES USED BY THE FLWR TYPE
 ;VIDEO DRIVERS.
 VADD	EQU	0F000H	;FLASHWRT BOARD RAM
 HADD	EQU	0F0H	;HI BYTE OF ADDRESS
 BS	EQU	'H'-40H	;BACK-SPACE
 LF	EQU	0AH	;LINE FEED
 ETB	EQU	'W'-40H ;CURSOR UP SYM
 DC3	EQU	'S'-40H	;CURSOR RIGHT.
 SYN	EQU	16H	;HOME AND CLEAR SCREEN
 RUB1	EQU	95H	;RUB CHAR
 SSEQ	EQU	1DH	;GOTOXY START SEQUENCE BYTE.
 ;
 ;**** DRIVE
 ;FLWR DRIVER WITH X-Y CURSOR ADDRESSING.
 ;CURSOR ADDRESSING IS DONE WITH THE SEQUENCE:
 ; 1DH,Y-BYTE,X-BYTE  (1DH,HORIZ,VERT).
 ;
 DRIVE:
	MOV	A,C
 	PUSH PSW	;SAVE REGISTERS
 	PUSH B
 	PUSH D
 	PUSH H
 	MOV	B,A
 	LHLD	XYADD	;SETUP FOR XY
 	LDA	XYFLAG	;OPERATION
 	ORA	A	;HAS IT BEEN SET
 	JNZ	DOX	;X-Y SEQ HAS STARTED.
 	MOV 	A,B	;GET BACK ACCUM.
 	CPI	SSEQ	;CHECK FOR FIRST GOTXY REQUEST.
 	JZ	STARTXY	;YEP, IT STARTED.
	CPI	07H	;BELL?
	JZ	GOBACK
	ORA	A	;NULL?
	JZ	GOBACK
DISPL	LHLD	CURS
	MOV	A,M	;TURN OF CURSER
	ANI	7FH
	MOV	M,A
	MOV	A,B
	CPI	BS	;(8)  BACKSPACE?
	JZ	BKSPC
	CPI	LF	;(10) LINEFEED?
	JZ	LNFD
	CPI	0DH	;(13)  CARRAIGE RETURN?
	JZ	CURET
	CPI	ETB	;(23)  REVERSE LINEFEED?
	JZ	RLINFD
	CPI	DC3	;(19)  FORWARD SPACE?
	JZ	FWSPC
	CPI	02H	;(2)   HOME CURSER
	JZ	HOMER
	CPI	SYN	;(22)  CLEAR AND HOME SCREEN?
	JZ	CLRSC
	CPI	RUB1	;(95)  RUBOUT?
	JZ	BKSPC
	CPI	1AH	;(26)  CLEAR WHOLE LINE?
	JZ	BLKLN
	CPI	1CH	;(28)  CLEAR TO END OF LINE?
	JZ	CLRLN
	CPI	19H	;(25)  CLEAR TO END OF SCREEN?
	JZ	CLR
	ANI	07FH
	MOV	M,A
FWSPC:
	MOV	A,L
	ANI	3FH
	CPI	3FH
	JZ	RETRN
	INX	H
ONSCR	MOV	A,L
	ANI	3FH
	CPI	3FH
	JZ	RETRN
	MOV	A,H
	CPI	HADD+4
	JNZ	RETRN
	LXI	H,VADD
	LXI	D,VADD+64
SCROL	LDAX	D
	MOV	M,A
	INX	D
	INX	H
	MOV	A,D
	CPI	HADD+4
	JNZ	SCROL
BLKLN	MOV	A,L
	ANI	0C0H
	MOV	L,A
	SHLD	CURS
CLRLN	MVI	M,020H
	MOV	A,L
	ANI	3FH
	CPI	3FH
	INX	H
	JNZ	CLRLN
	LHLD	CURS
RETRN	MOV	A,M	;TURN ON CURSER
	ORI	80H
	MOV	M,A
	SHLD	CURS
GOBACK	POP	H
	POP	D
	POP	B
	POP	PSW
	RET
CLRSC	LXI	H,VADD
	SHLD	CURS
CLR	LHLD	CURS
WRSPC	MVI	M,20H
	INX	H
	MOV	A,H
	CPI	HADD+8
	JNZ	WRSPC
	JMP	RETRN-3
LNFD	LXI	D,64
	DAD	D
	JMP	ONSCR
BKSPC	DCX	H
	JMP	RETRN
RLINFD	LXI	D,-64		;REVERSE LINE FEED
	DAD	D
	JMP	RETRN
CURET:	MOV	A,L
	ANI	0C0H
	MOV	L,A
	JMP	RETRN
HOMER:	LXI	H,VADD
	JMP	RETRN
;BEGINNING OF XY ROUTINES
STARTXY MVI	L,0FFH
	SHLD	XYADD
	MOV	A,L
	STA	XYFLAG
	JMP	GOBACK
 DOX:	MVI	A,0FFH		;GETS HERE IF L HAS BEEN
 	CMP	L		;SET
 	JNZ	DOXY		;IF NO MATCH,STAGE IS SET
 	MOV	A,B		;A CONTAINS Y-BYTE NOW
	SUI	20H
	ANI	3FH
 	MOV	L,A		;BINARY VAL. TO L
 	SHLD	XYADD		;SAVE IT
 	JMP	GOBACK		;FOR LATER
 DOXY:	PUSH	H	;SAVE H,L
 	LHLD	CURS	;GET OLD CURSOR LOCATION
	MOV	A,M
	ANI	7FH
 	MOV	M,A	;RESTORE CHAR AND WIPE OUT CURSOR.
 	POP	H	;RESTORE LATEST H,L
 	MOV	A,B	;B CONTAINS X-BYTE NOW
	SUI	20H
	ANI	0FH
 	ORA	A		;IS IT A ZERO?
 	JZ	FIXCUR		;IF SO,SKIP DADS.
 	LXI	D,64		;NO. OF CHARS/LINE.
LDOWN:	DAD	D		;DOWN ONE LINE
 	DCR	A		;COUNT IT WITH X-BYTE
 	JNZ	LDOWN
FIXCUR:	XCHG		;H,L TO D,E
 	LXI	H,VADD		;GET BEGINNING
 	DAD	D		;H,L NOW POINTS AT X-Y ADDR.
CHKLOC: MOV	A,H
	CPI	HADD+4
	JM	ONSCRN
	JMP	ZIPIT
ONSCRN: SHLD	CURS		;X-Y ADDR IN CURS
 ZIPIT:	LXI	H,0		;BIG ZERO
 	SHLD	XYADD		;ZERO THIS, WE ARE DONE
 	XRA	A		;SMALL ZERO
	STA	XYFLAG	;SET THIS ALSO
	JMP	RETRN-3
 ;DEFINE STORAGE AREA FOR FLW DRIVER
 ;
 CURS	DW	VADD		;INITIALLY BOARD ADDRESS
 XYFLAG	DB	0		;INITIALLY ZERO
 XYADD	DW	0
