 

;PAGE	91

;	.PAGE
;	.TITLE	'DISPLAY HANDLER	-- 10-30-78 --	DISPLC'
;
; HANDLER DEPENDENT EQUATES
;
CLRCOD	=	$7D	;CLEAR SCREEN ATASCI CODE
CNTL1	=	$9F	;POKEY KEY CODE FOR ^1
;
FRMADR	=	SAVADR
TOADR	=	MLTTMP
;
 

;PAGE	92

;	.PAGE
;
;
	.ORG	EDITRV
;
; SCREEN EDITOR HANDLER ENTRY POINT
;
EDITOR: .WORD	EOPEN-1
	.WORD	RETUR1-1		;(CLOSE)
	.WORD	EGETCH-1
	.WORD	EOUTCH-1
	.WORD	RETUR1-1		;(STATUS)
	.WORD	NOFUNC-1		;(SPECIAL)
	JMP	PWRONA
	.BYTE	0			;ROM FILLER BYTE
;
	.ORG	SCRENV
;
; DISPLAY HANDLER ENTRY POINT
;
DISPLA: .WORD	DOPEN-1
	.WORD	RETUR1-1		;(CLOSE)
	.WORD	GETCH-1
	.WORD	OUTCH-1
	.WORD	RETUR1-1		;(STATUS)
	.WORD	DRAW-1			;(SPECIAL)
	JMP	PWRONA
	.BYTE	0			;ROM FILLER BYTE
;
	.ORG	KEYBDV
;
;
; KEYBOARD HANDLER ENTRY POINT
;
KBDHND: .WORD	RETUR1-1
	.WORD	RETUR1-1		;(CLOSE)
	.WORD	KGETCH-1
	.WORD	NOFUNC-1		;(OUTCH)
	.WORD	RETUR1-1		;(STATUS)
	.WORD	NOFUNC-1		;(SPECIAL)
	JMP	PWRONA
	.BYTE	0			;ROM FILLER BYTE
;
;
; INTERRUPT VECTOR TABLE ENTRY
	.ORG	VCTABL-INTABS+VKEYBD
	.WORD	PIRQ5		;KEYBOARD IRQ INTERRUPT VECTOR
 

;PAGE	93

		.ORG	KBDORG
;
PWRONA: LDA	#$FF
	STA	CH
	LDA	MEMTOP+1
	AND	#$F0		;INSURE 4K PAGE BOUNDARY
	STA	RAMTOP
	LDA	#$40		;DEFAULT TO UPPER CASE ALPHA AT PWRON
	STA	SHFLOK
	RTS			;POWER ON COMPLETED
 

;PAGE	94

;	.PAGE
;
;
; BEGIN DISPLAY HANDLER OPEN PROCESSING
;
DOPEN:	LDA	ICAX2Z		;GET AUX 2 BYTE
	AND	#$F
	BNE	OPNCOM		;IF MODE ZERO, CLEAR ICAX1Z
EOPEN:	LDA	ICAX1Z		;CLEAR "CLR INHIBIT" AND "MXD MODE" BITS
	AND	#$F
	STA	ICAX1Z
	LDA	#0
OPNCOM: STA	DINDEX
	LDA	#$E0		;INITIALIZE GLOBAL VBLANK RAM
	STA	CHBAS
	LDA	#2
	STA	CHACT
	STA	SDMCTL		;TURN OFF DMA NEXT VBLANK
	LDA	#SUCCES
	STA	DSTAT		;CLEAR STATUS
	LDA	#$C0		;DO IRQEN
	ORA	POKMSK
	STA	POKMSK
	STA	IRQEN
	LDA	#0
	STA	TINDEX		;TEXT INDEX MUST ALWAYS BE 0
	STA	ADRESS
	STA	SWPFLG
	STA	CRSINH		;TURN CURSOR ON AT OPEN
	LDY	#14		;CLEAR TAB STOPS
	LDA	#1		;INIT TAB STOPS TO EVERY 8 CHARACTERS
CLRTBS: STA	TABMAP,Y
	DEY
	BPL	CLRTBS
	LDX	#4		;LOAD COLOR REGISTERS
DOPEN8: LDA	COLRTB,X
	STA	COLOR0,X
	DEX
	BPL	DOPEN8
	LDY	RAMTOP		;DO TXTMSC=$2C40 (IF MEMTOP=3000)
	DEY
	STY	TXTMSC+1
	LDA	#$60
	STA	TXTMSC
	LDX	DINDEX
	LDA	ANCONV,X	;CONVERT IT TO ANTIC CODE
	BNE	DOPENA		;IF ZERO, IT IS ILLEGAL
OPNERR: LDA	#BADMOD		;SET ERROR STATUS
	STA	DSTAT
DOPENA: STA	HOLD1
	LDA	RAMTOP		;SET UP AN INDIRECT POINTER
	STA	ADRESS+1
	LDY	ALOCAT,X	;ALLOCATE N BLOCKS OF 40 BYTES
DOPEN1: LDA	#40
 

;PAGE	95

	JSR	DBSUB
	DEY
	BNE	DOPEN1
	LDA	GPRIOR		;CLEAR GTIA MODES
	AND	#$3F
	STA	OPNTMP+1
	TAY
	CPX	#8		;TEST IF 320X1
	BCC	NOT8
	TXA			;GET 2 LOW BITS
	ROR	A
	ROR	A
	ROR	A
	AND	#$C0		;NOW 2 TOP BITS
	ORA	OPNTMP+1
	TAY
	LDA	#16		;SUBTRACT 16 MORE FOR PAGE BOUNDARY
	JSR	DBSUB
	CPX	#11		;TEST MODE 11
	BNE	NOT8		;IF MODE = 11
	LDA	#6		;PUT GTIA LUM VALUE INTO BACKGROUND REGISTER
	STA	COLOR4
NOT8:	STY	GPRIOR		;STORE NEW PRIORITY
	LDA	ADRESS		;SAVE MEMORY SCAN COUNTER ADDRESS
	STA	SAVMSC
	LDA	ADRESS+1
	STA	SAVMSC+1
VBWAIT: LDA	VCOUNT		;WAIT FOR NEXT VBLANK BEFORE MESSING
	CMP	#$7A		;WITH THE DISPLAY LIST
	BNE	VBWAIT
	JSR	DBDEC		;START PUTTING DISPLAY LIST RIGHT UNDER RAM
	LDA	PAGETB,X	;TEST IF DISPLAY LIST WILL BE IN TROUBLE
	BEQ	NOMOD		;OF CROSSING A 256 BYTE PAGE BOUNDARY
	LDA	#$FF		;IF SO, DROP DOWN A PAGE
	STA	ADRESS
	DEC	ADRESS+1
NOMOD:	LDA	ADRESS		;SAVE END OF DISPLAY LIST FOR LATER
	STA	SAVADR
	LDA	ADRESS+1
	STA	SAVADR+1
	JSR	DBDDEC		;(DOUBLE BYTE DOUBLE DECREMENT)
	LDA	#$41		;(ANTIC) WAIT FOR VBLANK AND JMP TO TOP
	JSR	STORE
	STX	OPNTMP
	LDA	#24		;INITIALIZE BOTSCR
	STA	BOTSCR
	LDA	DINDEX		;DISALLOW MIXED MODE IF MODE.GE.9
	CMP	#9
	BCS	NOTMXD
	LDA	ICAX1Z		;TEST MIXED MODE
	AND	#$10
	BEQ	NOTMXD
	LDA	#4
	STA	BOTSCR
 

;PAGE	96

	LDX	#2		;ADD 4 LINES OF TEXT AT BOTTOM OF SCREEN
DOPEN2: LDA	#2
	JSR	STORE
	DEX
	BPL	DOPEN2
	LDY	RAMTOP		;RELOAD MSC FOR TEXT
	DEY
	TYA
	JSR	STORE
	LDA	#$60
	JSR	STORE
	LDA	#$42
	JSR	STORE
	CLC
	LDA	#MXDMDE-NUMDLE ;POINT X AT MIXED MODE TABLE
	ADC	OPNTMP
	STA	OPNTMP
NOTMXD: LDY	OPNTMP
	LDX	NUMDLE,Y	;GET NUMBER OF DISPLAY LIST ENTRIES
DOPEN3: LDA	HOLD1		;STORE N DLE'S
	JSR	STORE
	DEX
	BNE	DOPEN3
	LDA	DINDEX		;DO THE MESSY 320X1 PROBLEM
	CMP	#8
	BCC	DOPEN5
	LDX	#93		;GET REMAINING NUMBER OF DLE'S
	LDA	RAMTOP		;RELOAD MEMORY SCAN COUNTER
	SEC
	SBC	#$10
	JSR	STORE
	LDA	#0
	JSR	STORE
	LDA	#$4F		;(ANTIC) RELOAD MSC CODE
	JSR	STORE
DOPEN4: LDA	HOLD1		;DO REMAINING DLE'S
	JSR	STORE
	DEX
	BNE	DOPEN4
DOPEN5: LDA	SAVMSC+1	;POLISH OFF DISPLAY LIST
	JSR	STORE
	LDA	SAVMSC
	JSR	STORE
	LDA	HOLD1
	ORA	#$40
	JSR	STORE
	LDA	#$70		;24 BLANK LINES
	JSR	STORE
	LDA	#$70
	JSR	STORE
	LDA	ADRESS		;SAVE DISPLAY LIST ADDRESS
	STA	SDLSTL
	LDA	ADRESS+1
	STA	SDLSTL+1
 

;PAGE	97

	LDA	#$70		;ADD LAST BLANK LINE ENTRY
	JSR	STORE		;POSITION ADRESS=SDLSTL-1
	LDA	ADRESS		;STORE NEW MEMTOP
	STA	MEMTOP
	LDA	ADRESS+1
	STA	MEMTOP+1
	LDA	SAVADR
	STA	ADRESS
	LDA	SAVADR+1
	STA	ADRESS+1
	LDA	SDLSTL+1
	JSR	STORE
	LDA	SDLSTL
	JSR	STORE
	LDA	DSTAT		;IF ERROR OCURRED ON ALLOCATION, OPEN THE ED
	BPL	DOPEN9
	PHA			;SAVE STATUS
	JSR	EOPEN		;OPEN THE EDITOR
	PLA			;RESTORE STATUS
	TAY			;AND RETURN IT TO CIO
	RTS
DOPEN9: LDA	ICAX1Z		;TEST CLEAR INHIBIT BIT
	AND	#$20
	BNE	DOPEN7
	JSR	CLRSCR		;CLEAR SCREEN
	STA	TXTROW		;AND HOME TEXT CURSOR (AC IS ZERO)
	LDA	LMARGN
	STA	TXTCOL
DOPEN7: LDA	#$22		;EVERYTHING ELSE IS SET UP
	ORA	SDMCTL		;SO TURN ON DMACTL
	STA	SDMCTL
	JMP	RETUR2
;
;
GETCH:	JSR	RANGE		;GETCH DOES INCRSR, GETPLT DOESN'T
	JSR	GETPLT
	JSR	INATAC		;CONVERT INTERNAL CODE TO ATASCII
	JSR	INCRSB
	JMP	RETUR1
GETPLT: JSR	CONVRT		;CONVERT ROW/COLUMN TO ADRESS
	LDA	(ADRESS),Y
	AND	DMASK
SHIFTD: LSR	SHFAMT		;SHIFT DATA DOWN TO LOW BITS
	BCS	SHIFT1
	LSR	A
	BPL	SHIFTD		;(UNCONDITIONAL)
SHIFT1: STA	CHAR
	CMP	#0		;RESTORE FLAGS ALSO
	RTS
;
;
;
OUTCH:	STA	ATACHR
	JSR	RANGE
 

;PAGE	98

;	JSR	OFFCRS
OUTCHA: LDA	ATACHR		;TEST FOR CLEAR SCREEN
	CMP	#CLRCOD
	BNE	OUTCHE
	JSR	CLRSCR
	JMP	RETUR2
OUTCHE: LDA	ATACHR		;TEST FOR CARRIAGE RETURN
	CMP	#CR
	BNE	OUTCHB
	JSR	DOCRWS		;DO CR
	JMP	RETUR2
OUTCHB: JSR	OUTPLT
	JSR	INCRSR
	JMP	RETUR2
;
;
OUTPLT: LDA	SSFLAG		;*****LOOP HERE IF START/STOP FLAG IS NON-0
	BNE	OUTPLT
	LDX	#2
CRLOOP: LDA	ROWCRS,X	;SAVE CURSOR LOCATION FOR DRAW LINE TO DRAW
	STA	OLDROW,X
	DEX
	BPL	CRLOOP
	LDA	ATACHR		;CONVERT ATASCII(ATACHR) TO INTERNAL(CHAR)
	TAY			;SAVE ATACHR
	ROL	A
	ROL	A
	ROL	A
	ROL	A
	AND	#3
	TAX			;X HAS INDEX INTO ATAINT
	TYA			;RESTORE ATACHR
	AND	#$9F		;STRIP OFF COLUMN ADDRESS
	ORA	ATAINT,X	;OR IN NEW COLUMN ADDRESS
OUTCH2: STA	CHAR
	JSR	CONVRT
	LDA	CHAR
SHIFTU: LSR	SHFAMT		;SHIFT UP TO PROPER POSITION
	BCS	SHIFT2
	ASL	A
	JMP	SHIFTU
SHIFT2: AND	DMASK
	STA	TMPCHR		;SAVE SHIFTED DATA
	LDA	DMASK		;INVERT MASK
	EOR	#$FF
	AND	(ADRESS),Y	;MASK OFF OLD DATA
	ORA	TMPCHR		;OR IN NEW DATA
	STA	(ADRESS),Y
	RTS
;
;
RETUR2: JSR	GETPLT		;DO CURSOR ON THE WAY OUT
	STA	OLDCHR
	LDX	DINDEX		;GRAPHICS HAVE INVISIBLE CURSOR
 

;PAGE	99

	BNE	RETUR1
	LDX	CRSINH		;TEST CURSOR INHIBIT
	BNE	RETUR1
	EOR	#$80		;TOGGLE MSB
	JSR	OUTCH2		;DISPLAY IT
RETUR1: LDY	DSTAT		;RETURN TO CIO WITH STATUS IN Y
	LDA	#SUCCES
	STA	DSTAT		;SET STATUS= SUCCESSFUL COMPLETION
	LDA	ATACHR		;PUT ATACHR IN AC FOR RETURN TO CIO
NOFUNC: RTS			;(NON-EXISTENT FUNCTION RETURN POINT)
;
;
;
; END OF DISPLAY HANDLER
;
 

;PAGE	100

;	.PAGE
;
;
;
;
EGETCH: JSR	SWAP
	JSR	ERANGE
	LDA	BUFCNT		;ANYTHING IN THE BUFFER?
	BNE	EGETC3		;YES
	LDA	ROWCRS		;NO, SO SAVE BUFFER START ADDRESS
	STA	BUFSTR
	LDA	COLCRS
	STA	BUFSTR+1
EGETC1: JSR	KGETCH		;LET'S FILL OUR BUFFER
	STY	DSTAT		; SAVE KEYBOARD STATUS		; KH!!!
	LDA	ATACHR		;TEST FOR CR
	CMP	#CR
	BEQ	EGETC2
	JSR	DOSS		;NO, SO PRINT IT
	JSR	SWAP		;JSR DOSS DID SWAP SO SWAP BACK
	LDA	LOGCOL		;BEEP IF NEARING LOGICAL COL 120
	CMP	#113
	BNE	EGETC6
	JSR	BELL
EGETC6: JMP	EGETC1
EGETC2: JSR	OFFCRS		;GET BUFFER COUNT
	JSR	DOBUFC
	LDA	BUFSTR		;RETURN A CHARACTER
	STA	ROWCRS
	LDA	BUFSTR+1
	STA	COLCRS
EGETC3: LDA	BUFCNT
	BEQ	EGETC5
EGETC7: DEC	BUFCNT		;AND RETURN TILL BUFCNT=0
	BEQ	EGETC5
	LDA	DSTAT		;IF ERR, LOOP ON EGETC7 UNTIL BUFR IS EMPTIE
	BMI	EGETC7
	JSR	GETCH
	STA	ATACHR
	JMP	SWAP		;AND RETURN WITHOUT TURNING CURSOR BACK ON
EGETC5: JSR	DOCRWS		;DO REAL CARRIAGE RETURN
	LDA	#CR		;AND RETURN EOL
	STA	ATACHR
	JSR	RETUR2		;TURN ON CURSOR THEN SWAP
	STY	DSTAT		;SAVE KEYBOARD STATUS
	JMP	SWAP		;AND RETURN THROUGH RETUR1
;
JSRIND: JMP	(ADRESS)	;JSR TO THIS CAUSES JSR INDIRECT
;
EOUTCH: STA	ATACHR		;SAVE ATASCII VALUE
	JSR	SWAP
	JSR	ERANGE
DOSS:	JSR	OFFCRS		;TURN OFF CURSOR
	JSR	TSTCTL		;TEST FOR CONTROL CHARACTERS (Z=1 IF CTL)
 

;PAGE	101

	BEQ	EOUTC5
EOUTC6: ASL	ESCFLG		;ESCFLG ONLY WORKS ONCE
	JSR	OUTCHE
ERETN:	JMP	SWAP		;AND RETURN THROUGH RETUR1
EOUTC5: LDA	DSPFLG		;DO DSPFLG AND ESCFLG
	ORA	ESCFLG
	BNE	EOUTC6		;IF NON-0 DISPLAY RATHER THAN EXECUTE IT
	ASL	ESCFLG
	INX			;PROCESS CONTROL CHARACTERS
	LDA	CNTRLS,X	;GET DISPLACEMENT INTO ROUTINE
	STA	ADRESS
	LDA	CNTRLS+1,X	;GET HIGH BYTE
	STA	ADRESS+1
	JSR	JSRIND		;DO COMPUTED JSR
	JSR	RETUR2		;DO CURSOR
	JMP	SWAP		;ALL DONE SO RETURN THROUGH RETUR1
;
;
;
;
; END SCREEN EDITOR
;
;
; BEGIN KEYBOARD HANDLER
;
;
;
;
KGETC2: LDA	#$FF
	STA	CH
KGETCH: LDA	ICAX1Z		;TEST LSB OF AUX1 FOR SPECIAL EDITOR READ MO
	LSR	A
	BCS	GETOUT
	LDA	#BRKABT
	LDX	BRKKEY		;TEST BREAK
	BEQ	K7		;IF BREAK, PUT BRKABT IN DSTAT AND CR IN ATA
	LDA	CH
	CMP	#$FF
	BEQ	KGETCH
	STA	HOLDCH		;SAVE CH FOR SHIFT LOCK PROC
	LDX	#$FF		;"CLEAR" CH
	STX	CH
	JSR	CLICK		;DO KEYBOARD AUDIO FEEDBACK (A IS OK)
KGETC3: TAX			;DO ASCCON
	CPX	#$C0		;TEST FOR CTL & SHIFT TOGETHER
	BCC	ASCC01
	LDX	#3		;BAD CODE
ASCC01: LDA	ATASCI,X
	STA	ATACHR		;DONE
	CMP	#$80		;DO NULLS
	BEQ	KGETC2
	CMP	#$81		;CHECK ATARI KEY
	BNE	KGETC1
	LDA	INVFLG
 

;PAGE	102

	EOR	#$80
	STA	INVFLG
	JMP	KGETC2		;DONT RETURN A VALUE
KGETC1: CMP	#$82		;CAPS/LOWER
	BNE	K1
	LDA	#0		;CLEAR SHFLOK
	STA	SHFLOK
	BEQ	KGETC2
K1:	CMP	#$83		;SHIFT CAPS/LOWER
	BNE	K2
	LDA	#$40
	STA	SHFLOK		;SHIFT BIT
	BNE	KGETC2
K2:	CMP	#$84		;CNTL CAPS/LOWER
	BNE	K3
	LDA	#$80		;CNTL BIT
	STA	SHFLOK
	BNE	KGETC2
K3:	CMP	#$85		;DO EOF
	BNE	K6
	LDA	#EOFERR
K7:	STA	DSTAT
	STA	BRKKEY		;RESTORE BREAK
GETOUT: LDA	#CR		;PUT CR IN ATACHR
	BNE	K8		;(UNCONDITIONAL)
K6:	LDA	HOLDCH		;PROCESS SHIFT LOCKS
	CMP	#$40		;REGULAR SHIFT AND CONTROL TAKE PRECEDENCE
	BCS	K5		;OVER LOCK
	LDA	ATACHR		;TEST FOR ALPHA
	CMP	#$61		;LOWER CASE A
	BCC	K5		;NOT ALPHA IF LT
	CMP	#$7B		;LOWER CASE Z+1
	BCS	K5		;NOT ALPHA IF GE
	LDA	SHFLOK		;DO SHIFT/CONTROL LOCK
	BEQ	K5		;IF NO LOCK, DONT RE-DO IT
	ORA	HOLDCH
	JMP	KGETC3		;DO RETRY
K5:	JSR	TSTCTL		;DONT INVERT MSB OF CONTROL CHARACTERS
	BEQ	K4
	LDA	ATACHR
	EOR	INVFLG
K8:	STA	ATACHR
K4:	JMP	RETUR1		;ALL DONE		;KH!!!
;
;
;PAGE	103

;	.PAGE
;
;
; CONTROL CHARACTER PROCESSORS
;
ESCAPE: LDA	#$80		;SET ESCAPE FLAG
	STA	ESCFLG
	RTS
CRSRUP: DEC	ROWCRS
	BPL	COMRET
	LDX	BOTSCR		;WRAPAROUND
	DEX
UPDNCM: STX	ROWCRS
COMRET: JMP	STRBEG		;COLVERT ROW AND COL TO LOGCOL AND RETURN
CRSRDN: INC	ROWCRS
	LDA	ROWCRS
	CMP	BOTSCR
	BCC	COMRET
	LDX	#0
	BEQ	UPDNCM		;(UNCONDITIONAL)
CRSRLF: DEC	COLCRS
	LDA	COLCRS
	BMI	CRSRL1		;(IF LMARGN=0, THIS ELIMINATES PROBLEM CASE)
	CMP	LMARGN
	BCS	COMRE1
CRSRL1: LDA	RMARGN
LFRTCM: STA	COLCRS
COMRE1: JMP	DOLCOL		;COLVERT ROW AND COL TO LOGCOL AND RETURN
CRSRRT: INC	COLCRS
	LDA	COLCRS
	CMP	RMARGN
	BCC	COMRE1
	BEQ	COMRE1		;(CAUSE BLE)
	LDA	LMARGN
	JMP	LFRTCM		;UNCONDITIONAL TO COMMON STORE
CLRSCR: JSR	PUTMSC
	LDY	#0
	TYA			;PUT 0 IN THE AC
CLRSC2: STA	(ADRESS),Y	;(AC IS ZERO)
	INY
	BNE	CLRSC2
	INC	ADRESS+1
	LDX	ADRESS+1
	CPX	RAMTOP
	BCC	CLRSC2
	LDA	#$FF		;CLEAN UP LOGICAL LINE BIT MAP
CLRSC3: STA	LOGMAP,Y	;(Y IS ZERO AFTER CLRSC2 LOOP)
	INY
	CPY	#4
	BCC	CLRSC3
HOME:	JSR	COLCR		;PLACE COLCRS AT LEFT EDGE
	STA	LOGCOL
	STA	BUFSTR+1
	LDA	#0
 

;PAGE	104

	STA	ROWCRS
	STA	COLCRS+1
	STA	BUFSTR
	RTS
;
BS:	LDA	LOGCOL		;BACKSPACE
	CMP	LMARGN
	BEQ	BS1
BSA:	LDA	COLCRS		;LEFT EDGE?
	CMP	LMARGN
	BNE	BS3		;NO
	JSR	DELTIM		;YES, SEE IF LINE SHOULD BE DELETED
BS3:	JSR	CRSRLF
	LDA	COLCRS
	CMP	RMARGN
	BNE	BS2
	LDA	ROWCRS
	BEQ	BS2
	JSR	CRSRUP
BS2:	LDA	#$20		;MAKE BACKSPACE DESTRUCTIVE
	STA	ATACHR
	JSR	OUTPLT
BS1:	JMP	DOLCOL		;AND RETURN
TAB:	JSR	CRSRRT		;BEGIN SEARCH
	LDA	COLCRS		;TEST FOR NEW LINE
	CMP	LMARGN
	BNE	TAB1		;NO
	JSR	DOCR		;DO CARRIAGE RETURN
	JSR	LOGGET		;CHECK IF END OF LOGICAL LINE
	BCC	TAB1		;NO, CONTINUE
	BCS	TAB2		;(UNCONDITIONAL)
TAB1:	LDA	LOGCOL		;CHECK FOR TAB STOP
	JSR	BITGET
	BCC	TAB		;NO, SO KEEP LOOKING
TAB2:	JMP	DOLCOL		;COLVERT ROW AND COL TO LOGCOL AND RETURN
SETTAB: LDA	LOGCOL
	JMP	BITSET		;SET BIT IN MAP AND RETURN
CLRTAB: LDA	LOGCOL
	JMP	BITCLR		;CLEAR " " " " "
INSCHR: JSR	PHACRS
	JSR	GETPLT		;GET CHARACTER UNDER CURSOR
	STA	INSDAT
	LDA	#0
	STA	SCRFLG
INSCH4: JSR	OUTCH2		;STORE DATA
	LDA	LOGCOL		;SAVE LOGCOL: IF AFTER INCRSA LOGCOL IS
	PHA			;< THAN IT IS NOW, END LOOP
	JSR	INCRSA		;SPECIAL INCRSR ENTRY POINT
	PLA
	CMP	LOGCOL
	BCS	INSCH3		;QUIT
INSCH1: LDA	INSDAT		;KEEP GOING
	PHA
	JSR	GETPLT
 
;PAGE	105

	STA	INSDAT
	PLA
	JMP	INSCH4
INSCH3: JSR	PLACRS
INSCH6: DEC	SCRFLG
	BMI	INSCH5		;IF SCROLL OCCURRED
	DEC	ROWCRS		;MOVE CURSOR UP
	BNE	INSCH6		;(UNCOND) CONTINUE UNTIL SCRFLG IS MINUS
INSCH5: JMP	DOLCOL		;CONERT ROW AND COL TO LOGCOL AND RETURN
;
;
DELCHR: JSR	PHACRS
DELCH1: JSR	CONVRT		;GET DATA TO THE RIGHT OF THE CURSOR
	LDA	ADRESS
	STA	SAVADR		;SAVE ADRESS TO KNOW WHERE TO PUT DATA
	LDA	ADRESS+1
	STA	SAVADR+1
	LDA	LOGCOL
	PHA
	JSR	INCRSB		;PUT CURSOR OVER NEXT CHARACTER
	PLA
	CMP	LOGCOL		;TEST NEW LOGCOL AGAINST OLD LOGCOL
	BCS	DELCH2		;IF OLD.GE.NEW THEN QUIT
	LDA	ROWCRS		;IS ROW OFF SCREEN?
	CMP	BOTSCR
	BCS	DELCH2		;YES, SO QUIT
	JSR	GETPLT		;GET DATA UNDER CURSOR
	LDY	#0
	STA	(SAVADR),Y	;PUT IT IN PREVIOUS POSITION
	BEQ	DELCH1		;AND LOOP (UNCONDITIONAL)
DELCH2: LDY	#0
	TYA
	STA	(SAVADR),Y	;CLEAR THE LAST POSITION
	JSR	DELTIA		;TRY TO DELETE A LINE
	JSR	PLACRS
	JMP	DOLCOL		;AND RETURN
INSLIN: SEC			;NORMAL INSLIN PUTS "1" INTO BIT MAP
INSLIA: JSR	EXTEND		;ENTRY POINT FOR C=0
	LDA	LMARGN		;DO CARRIAGE RETURN (NO LF)
	STA	COLCRS
	JSR	CONVRT		;GET ADDRESS
	LDA	ADRESS		;SET UP TO=40+FROM (FROM = CURSOR)
	STA	FRMADR
	CLC
	ADC	#40
	STA	TOADR
	LDA	ADRESS+1
	STA	FRMADR+1
	ADC	#0
	STA	TOADR+1
	LDX	ROWCRS		;SET UP LOOP COUNTER
	CPX	#23
	BEQ	INSLI2
INSLI1: JSR	MOVLIN
 
;PAGE	106

	INX
	CPX	#23
	BNE	INSLI1
INSLI2: JSR	CLRLIN		;CLEAR CURRENT LINE
	JMP	DOLCOL		;COLVERT ROW AND COL TO LOGCOL AND RETURN
DELLIN: JSR	DOLCOL		;GET BEGINNING OF LOG LINE (HOLD1)
DELLIA: LDY	HOLD1		;SQUEEZE BIT MAP
	STY	ROWCRS		;PUT CURSOR THERE
DELLIB: LDY	ROWCRS
DELLI1: TYA
	SEC
	JSR	LO2GET		;GET NEXT BIT
	PHP
	TYA
	CLC
	ADC	#120
	PLP
	JSR	BITPUT		;WRITE IT OVER PRESENT BIT
	INY
	CPY	#24
	BNE	DELLI1		;LOOP
	LDA	LOGMAP+2	;SET LSB
	ORA	#1
	STA	LOGMAP+2
DELLI2: LDA	LMARGN		;DELETE LINE OF DATA USING PART OF SCROLL
	STA	COLCRS		;CR NO LF
	JSR	CONVRT
	JSR	SCROL1
	JSR	LOGGET		;TEST NEXT LINE FOR CONTINUATION
; IS IT A NEW LOG LINE?
	BCC	DELLIB		;NO SO DELETE ANOTHER
	JMP	DOLCOL		;YES SO DOLCOL AND RETURN
BELL:	LDY	#$20
BELL1:	JSR	CLICK
	DEY
	BPL	BELL1
	RTS
 
;PAGE	107

;	.PAGE
;
;
; ROUTINES
;
;
; DOUBLE BYTE DECREMENT OF INDIRECT POINTER
; INCLUDING DB SUBTRACT AND DB DOUBLE DECREMENT
;
DBDDEC: LDA	#2
	BNE	DBSUB		;(UNCONDITIONAL)
;
; STORE DATA INDIRECT AND DECREMENT POINTER
; (PLACED HERE TO SAVE JMP DBDEC AFTER STORE)
STORE:	LDY	DSTAT		;RETURN ON ERROR
	BMI	STROK
	LDY	#0
STORE1: STA	(ADRESS),Y
;	JMP	DBDEC		; DECREMENT AND RETURN
;
DBDEC:	LDA	#1
DBSUB:	STA	SUBTMP
	LDA	DSTAT		;RETURN ON ERROR
	BMI	STROK
	LDA	ADRESS
	SEC
	SBC	SUBTMP
	STA	ADRESS
	BCS	DBSUB1
	DEC	ADRESS+1
DBSUB1: LDA	APPMHI+1	;MAKE SURE NOTHING EVER OVERWRITES APPMHI
	CMP	ADRESS+1
	BCC	STROK		;OK
	BNE	STRERR		;ERROR
	LDA	APPMHI
	CMP	ADRESS
	BCC	STROK
STRERR: LDA	#SCRMEM		;SHOW MEM TOO SMALL FOR SCREEN ERROR
	STA	DSTAT
STROK:	RTS
;
;
;
; CONVERT ROW/COLUMN CURSOR INTO REAL ADDRESS (FROM SAVMSC ON UP)
;
CONVRT: LDA	ROWCRS		;SAVE CURSOR
	PHA
	LDA	COLCRS
	PHA
	LDA	COLCRS+1
	PHA
	JSR	PUTMSC
	LDA	ROWCRS		;PUT 10*ROWCRS INTO MLTTMP
	STA	MLTTMP
 

;PAGE	108

	LDA	#0
	STA	MLTTMP+1
	LDA	MLTTMP		;QUICK X8
	ASL	A
	ROL	MLTTMP+1
	STA	HOLD1		;(SAVE 2X VALUE)
	LDY	MLTTMP+1		;""
	STY	HOLD2		;""
	ASL	A
	ROL	MLTTMP+1
	ASL	A
	ROL	MLTTMP+1
	CLC			;ADD IN 2X
	ADC	HOLD1
	STA	MLTTMP
	LDA	MLTTMP+1
	ADC	HOLD2
	STA	MLTTMP+1
	LDX	DINDEX		;NOW SHIFT MLTTMP LEFT DHLINE TIMES TO FINIS
	LDY	DHLINE,X	;MULTIPLY
CONVR1: DEY			;LOOP N TIMES
	BMI	CONVR2
	ASL	MLTTMP
	ROL	MLTTMP+1
	JMP	CONVR1
CONVR2: LDY	DIV2TB,X	;NOW DIVIDE HCRSR TO ACCOUNT FOR PARTIAL BYT
	LDA	COLCRS
	LDX	#7		;* TRICKY *
CONVR3: DEY
	BMI	CONVR4
	DEX
	LSR	COLCRS+1
	ROR	A
	ROR	TMPLBT		;SAVE LOW BITS FOR MASK
	JMP	CONVR3
CONVR4: INY			;SO Y IS ZERO UPON RETURN FROM THIS ROUTINE
	CLC
	ADC	MLTTMP		;ADD SHIFTED COLCRS TO MLTTMP
	STA	MLTTMP
	BCC	CONVR5
	INC	MLTTMP+1
CONVR5: SEC			;* TRICKY *
CONVR6: ROR	TMPLBT		;SLIDE A "1" UP AGAINST LOW BITS (CONTINUE T
	CLC
	DEX			;AND FINISH SHIFT SO LOW BITS ARE
	BPL	CONVR6		;RIGHT JUSTIFIED.
	LDX	TMPLBT		;TMPLBT IS NOW THE INDEX INTO DMASKTB
	LDA	MLTTMP		;PREPARE FOR RETURN
	CLC
	ADC	ADRESS
	STA	ADRESS
	STA	OLDADR		;REMEMBER THIS ADDRESS FOR CURSOR
	LDA	MLTTMP+1
	ADC	ADRESS+1
 

;PAGE	109

	STA	ADRESS+1
	STA	OLDADR+1
	LDA	DMASKT,X
	STA	DMASK
	STA	SHFAMT
	PLA
	STA	COLCRS+1
	PLA
	STA	COLCRS
	PLA
	STA	ROWCRS
	RTS
;
;
; INCREMENT CURSOR AND DETECT BOTH END OF LINE AND END OF SCREEN
;
INCRSB: LDA	#0		;NON-EXTEND ENTRY POINT
	BEQ	INCRSC
INCRSR: LDA	#$9B		;SPECIAL CASE ELIMINATOR
INCRSC: STA	INSDAT
INCRSA: INC	LOGCOL		;(INSCHR ENTRY POINT)
	INC	COLCRS
	BNE	INCRS2		;DO HIGH BYTE
	INC	COLCRS+1
INCRS2: LDA	COLCRS		;TEST END OF LINE
	LDX	DINDEX
	CMP	COLUMN,X	;TEST TABLED VALUE FOR ALL SCREEN MODES
	BEQ	INC2A		;DO CR IF EQUAL
	CPX	#0		;MODE 0?
	BNE	INCRS3		;IF NOT, JUST RETURN
	CMP	RMARGN		;TEST AGAINST RMARGN
	BEQ	INCRS3		;EQUAL IS OK
	BCS	INC2A		;IF GREATER THAN, DO CR
INCRS3: RTS
INC2A:	CPX	#8		;CHECK MODE
	BCC	DOCR1		;NOT 320X1 SO DO IT
	LDA	COLCRS+1	;TEST MSD
	BEQ	INCRS3		;ONLY AT 64 SO DON'T DO IT
DOCR1:	LDA	DINDEX		;DON'T MESS WITH LOGMAP IF NO MODE ZERO
	BNE	DOCR
	LDA	LOGCOL		;TEST LINE OVERRUN
	CMP	#81
	BCC	DOCR1B		;IF LESS THAN 81 IT IS DEFINITELY NOT LINE 3
	LDA	INSDAT
	BEQ	DOCR		;ONLY DO LOG LINE OVERFLOW IF INSDAT <>0
	JSR	DOCRWS		;LOG LINE OVERFLOW IS SPECIAL CASE
	JMP	INCRS1		;RETURN
DOCR1B: JSR	DOCR		;GET IT OVER WITH
	LDA	ROWCRS
	CLC			;TEST LOGICAL LINE BIT MAP
	ADC	#120
	JSR	BITGET
	BCC	DOCR1A		;DON'T EXTEND IF OVERRUN IS INTO MIDDLE OF L
	LDA	INSDAT		;DON'T EXTEND IF INSDAT IS ZERO
 

;PAGE	110

	BEQ	DOCR1A		;(INSCHR SPECIAL CASE)
	CLC			;INSERT "0" INTO BIT MAP
	JSR	INSLIA
DOCR1A: JMP	DOLCOL		;CONVERT ROW AND COL TO LOGCOL AND RETURN
NOSCRL: LDA	#0		;DOCR WITHOUT SCROLL
	BEQ	NOSCR1		;(UNCONDITIONAL)
DOCRWS: LDA	#$9B		;DOCR WITH SCROLLING (NORMAL MODE)
NOSCR1: STA	INSDAT
DOCR:	JSR	COLCR		;PLACE COLCRS AT LEFT EDGE
	LDA	#0
	STA	COLCRS+1
	INC	ROWCRS
DOCR2:	LDX	DINDEX
	LDY	#24		;SET UP SCROLL LOOP COUNTER
	BIT	SWPFLG
	BPL	DOCR2A		;BRANCH IF NORMAL
	LDY	#4
	TYA
	BNE	DOCR2B		;(UNCONDITIONAL)
DOCR2A: LDA	NOROWS,X	;GET NO OF ROWS
DOCR2B: CMP	ROWCRS
	BNE	INCRS1
	STY	HOLD3
	TXA			;DON'T SCROLL IF MODE <> 0
	BNE	INCRS1
	LDA	INSDAT		;OR IF INSDAT = 0
	BEQ	INCRS1
;	LDA	INSDAT		IF INSDAT <> $9B THEN ROLL IN A 0
	CMP	#$9B		;TO EXTEND BOTTOM LOGICAL LINE
	SEC
	BEQ	DOCR4B
	CLC
DOCR4B: JSR	SCROLL		;LOOP BACK TO HERE IF >1 SCROLLS
	INC	SCRFLG
	DEC	BUFSTR		;ROWS MOVE UP SO BUFSTR SHOULD TOO
	DEC	HOLD3
	LDA	LOGMAP
	SEC			;FOR PARTIAL LINES, ROLL IN A "1"
	BPL	DOCR4B		;AGAIN IF PARTIAL LOGICAL LINE
	LDA	HOLD3		;PLACE CURSOR AT NEW LINE NEAR THE BOTTOM
	STA	ROWCRS
INCRS1: JMP	DOLCOL		;COLVERT ROW AND COL TO LOGCOL AND RETURN
;
;
; SUBEND: SUBTRACT ENDPT FROM ROWAC OR COLAC. (X=0 OR 2)
;
SUBEND: SEC
	LDA	ROWAC,X
	SBC	ENDPT
	STA	ROWAC,X
	LDA	ROWAC+1,X
	SBC	ENDPT+1
	STA	ROWAC+1,X
	RTS
 

;PAGE	111

;
;
; RANGE: DO CURSOR RANGE TEST. IF ERROR, POP STACK TWICE AND JMP RETURN
;	(ERANGE IS EDITOR ENTRY POINT AND TEST IF EDITOR IS OPEN.
;	IF IT ISNT IT OPENS THE EDITOR AND CONTINUES)
;
ERANGE: LDA	BOTSCR		;IF BOTSCR=4
	CMP	#4
	BEQ	RANGE		;THEN IT IS IN MIXED MODE AND OK
	LDA	DINDEX		;IF MODE = 0
	BEQ	RANGE		;THEN IT IS IN EDITOR MODE AND OK
	JSR	EOPEN		;IF NOT, OPEN EDITOR
RANGE:	LDA	#39		;***** RANGE CHECK RMARGN ***** SET UP AC
	CMP	RMARGN		;***** RANGE CHECK RMARGN ***** COMPARE
	BCS	RANGE3		;***** RANGE CHECK RMARGN ***** BRANCH GE
	STA	RMARGN		;***** RANGE CHECK RMARGN ***** BAD SO STORE
RANGE3: LDX	DINDEX
	LDA	NOROWS,X	;CHECK ROWS
	CMP	ROWCRS
	BCC	RNGERR		;(ERROR IF TABLE.GE.ROWCRS)
	BEQ	RNGERR
	CPX	#8			;CHECK FOR 320X1
	BNE	RANGE1		;SPECIAL CASE IT
	LDA	COLCRS+1
	BEQ	RNGOK		;IF HIGH BYTE IS 0, COL IS OK
	CMP	#1
	BNE	RNGERR		;IF >1, BAD
	BEQ	RANGE2		;IF 1, GO CHECK LOW BYTE
RANGE1: LDA	COLCRS+1	;FOR OTHERS, NON-ZERO HIGH BYTE IS BAD
	BNE	RNGERR
RANGE2: LDA	COLUMN,X	;CHECK LOW BYTE
	CMP	COLCRS
	BCC	RNGERR
	BEQ	RNGERR
RNGOK:	LDA	#SUCCES		;SET STATUS OK
	STA	DSTAT
	LDA	#BRKABT		;PREPARE BREAK ABORT STATUS
	LDX	BRKKEY		;CHECK BREAK KEY FLAG
	STA	BRKKEY		;'CLEAR' BREAK
	BEQ	RNGER2		;IF BREAK, QUIT IMMEDIATELY AND RETURN TO CI
	RTS
RNGERR: JSR	HOME		;ON RANGE ERROR, BRING CURSOR BACK
	LDA	#CRSROR		;SHOW CURSOR OVERRANGE ERROR
RNGER2: STA	DSTAT
RNGER1: PLA			;RESTORE STACK (THIS ROUTINE IS ALWAYS 1 LEV
	PLA			;AWAY FROM RETURN TO CIO)
	LDA	SWPFLG		;IF SWAPPED, SWAP BACK
	BPL	RETUR3
	JSR	SWAPA		;AND DON'T DO RETUR1
RETUR3: JMP	RETUR1		;RETURN TO CIO
;
;
;
; OFFCRS: RESTORE OLD DATA UNDER CURSOR SO IT CAN BE MOVED
;PAGE	112
;
OFFCRS: LDY	#0
	LDA	OLDCHR
	STA	(OLDADR),Y
	RTS
;
;
;
; BITMAP ROUTINES:
;
; BITCON: PUT MASK IN BITMSK AND INDEX IN X
; BITPUT: PUT CARRY INTO BITMAP
; BITROL: ROL CARRY INTO BOTTOM OF BITMAP (SCROLL)
; BITSET: SET PROPER BIT
; BITCLR: CLEAR PROPER BIT
; BITGET: RETURN CARRY SET IF BIT IS THERE
; LOGGET: DO BITGET FOR LOGMAP INSTEAD OF TABMAP
;
BITCON: PHA
	AND	#7
	TAX			;GET MASK
	LDA	MASKTB,X
	STA	BITMSK
	PLA			;PROCESS INDEX
	LSR	A
	LSR	A
	LSR	A
	TAX
	RTS
;
;
BITROL: ROL	LOGMAP+2
	ROL	LOGMAP+1
	ROL	LOGMAP
	RTS
;
;
BITPUT: BCC	BITCLR		;AND RETURN
; OTHERWISE FALL THROUGH TO BITSET AND RETURN
BITSET: JSR	BITCON
	LDA	TABMAP,X
	ORA	BITMSK
	STA	TABMAP,X
	RTS
;
BITCLR: JSR	BITCON
	LDA	BITMSK
	EOR	#$FF
	AND	TABMAP,X
	STA	TABMAP,X
	RTS
;
LOGGET: LDA	ROWCRS
LO1GET: CLC
 
;PAGE	113

LO2GET: ADC	#120
BITGET: JSR	BITCON
	CLC
	LDA	TABMAP,X
	AND	BITMSK
	BEQ	BITGE1
	SEC
BITGE1: RTS
;
;
;
;
; INATAC: INTERNAL(CHAR) TO ATASCII(ATACHR) CONVERSION
;
INATAC: LDA	CHAR
	LDY	DINDEX		;IF GRAPHICS MODES
	CPY	#3
	BCS	INATA1		;THEN DON'T CHANGE CHAR
	ROL	A
	ROL	A
	ROL	A
	ROL	A
	AND	#3
	TAX
	LDA	CHAR
	AND	#$9F
	ORA	INTATA,X
INATA1: STA	ATACHR
	RTS
;
;
;
; MOVLIN: MOVE 40 BYTES AT FRMADR TO TOADR SAVING OLD TOADR
;	DATA IN THE LINBUF. THEN MAKE NEXT FRMADR
;	BE AT LINBUF FOR NEXT TRANSFER & TOADR=TOADR+40
;
MOVLIN: LDA	#LINBUF/256 ;SET UP ADRESS=LINBUF=$247
	STA	ADRESS+1
;	LDA	#LINBUF.AND.$FF	; KH!!!
	LDA	#LINBUF & $FF	; ca65
	STA	ADRESS
	LDY	#39
MOVLI1: LDA	(TOADR),Y	;SAVE TO DATA
	STA	TMPCHR
	LDA	(FRMADR),Y	;STORE DATA
	STA	(TOADR),Y
	LDA	TMPCHR
	STA	(ADRESS),Y
	DEY
	BPL	MOVLI1
	LDA	ADRESS+1	;SET UP FRMADR=LAST LINE
	STA	FRMADR+1
	LDA	ADRESS
	STA	FRMADR
	CLC			;ADD 40 TO TOADR
 
;PAGE	114

	LDA	TOADR
	ADC	#40
	STA	TOADR
	BCC	MOVLI2
	INC	TOADR+1
MOVLI2: RTS
;
;
;
; EXTEND: EXTEND BIT MAP FROM ROWCRS (EXTEND LOGICAL LINE
;
EXTEND: PHP			;SAVE CARRY
	LDY	#23
EXTEN1: TYA
	JSR	LO1GET
	PHP
	TYA
	CLC
	ADC	#121
	PLP
	JSR	BITPUT
EXTEN3: DEY
	BMI	EXTEN4
	CPY	ROWCRS
	BCS	EXTEN1
EXTEN4: LDA	ROWCRS
	CLC
	ADC	#120
	PLP
	JMP	BITPUT		;STORE NEW LINE'S BIT AND RETURN
;
;
;
; CLRLIN: CLEAR LINE CURSOR IS ON
;
CLRLIN: LDA	LMARGN
	STA	COLCRS
	JSR	CONVRT
	LDY	#39
	LDA	#0
CLRLI1: STA	(ADRESS),Y
	DEY
	BPL	CLRLI1
	RTS
;
;
;
;
; SCROLL: SCROLL SCREEN
;
SCROLL: JSR	BITROL		;ROLL IN CARRY
	LDA	SAVMSC		;SET UP WORKING REGISTERS
	STA	ADRESS
	LDA	SAVMSC+1
 
;PAGE	115

	STA	ADRESS+1
SCROL1: LDY	#40	;LOOP
	LDA	(ADRESS),Y
	LDX	RAMTOP		;TEST FOR LAST LINE
	DEX
	CPX	ADRESS+1
	BNE	SCROL2
	LDX	#$D7
	CPX	ADRESS
	BCS	SCROL2
	LDA	#0		;YES SO STORE ZERO DATA FOR THIS ENTIRE LINE
SCROL2: LDY	#0
	STA	(ADRESS),Y
	INC	ADRESS
	BNE	SCROL1
	INC	ADRESS+1
	LDA	ADRESS+1
	CMP	RAMTOP
	BNE	SCROL1
	JMP	DOLCOL		;AND RETURN
;
;
; DOLCOL: DO LOGICAL COLUMN FROM BITMAP AND COLCRS
;
DOLCOL: LDA	#0		;START WITH ZERO
	STA	LOGCOL
	LDA	ROWCRS
	STA	HOLD1
DOLCO1: LDA	HOLD1		;ADD IN ROW COMPONENT
	JSR	LO1GET
	BCS	DOLCO2		;FOUND BEGINNING OF LINE
	LDA	LOGCOL		;ADD 40 AND LOOK BACK ONE
	CLC
	ADC	#40
	STA	LOGCOL
	DEC	HOLD1		;UP ONE LINE
	JMP	DOLCO1
DOLCO2: CLC			;ADD IN COLCRS
	LDA	LOGCOL
	ADC	COLCRS
	STA	LOGCOL
	RTS
;
;
;
; DOBUFC: COMPUTE BUFFER COUNT AS THE NUMBER OF BYTES FROM
;	BUFSTR TO END OF LOGICAL LINE WITH TRAILING SPACES REMOVED
;
DOBUFC: JSR	PHACRS
	LDA	LOGCOL
	PHA
	LDA	BUFSTR		;START
	STA	ROWCRS
	LDA	BUFSTR+1
 

;PAGE	116

	STA	COLCRS
	LDA	#1
	STA	BUFCNT
DOBUF1: LDX	#23		;NORMAL
	LDA	SWPFLG		;IF SWAPPED, ROW 3 IS THE LAST LINE ON SCREE
	BPL	DOB1
	LDX	#3
DOB1:	CPX	ROWCRS		;TEST IF CRSR IS AT LAST SCREEN POSITION
	BNE	DOBU1A
	LDA	COLCRS
	CMP	RMARGN
	BNE	DOBU1A
	INC	BUFCNT		;YES, SO FAKE INCRSR TO AVOID SCROLLING
	JMP	DOBUF2
DOBU1A: JSR	INCRSB
	INC	BUFCNT
	LDA	LOGCOL
	CMP	LMARGN
	BNE	DOBUF1		;NOT YET EOL
	DEC	ROWCRS		;BACK UP ONE INCRSR
	JSR	CRSRLF
DOBUF2: JSR	GETPLT		;TEST CURRENT COLUMN FOR NON-ZERO DATA
	BNE	DOBUF4		;QUIT IF NON-ZERO
	DEC	BUFCNT		;DECREMENT COUNTER
	LDA	LOGCOL		;BEGINNING OF LOGICAL LINE YET?
	CMP	LMARGN
	BEQ	DOBUF4		;YES, SO QUIT
	JSR	CRSRLF		;BACK UP CURSOR
	LDA	COLCRS		;IF LOGCOL=RMARGN, GO UP 1 ROW
	CMP	RMARGN
	BNE	DOBUF3
	DEC	ROWCRS
DOBUF3: LDA	BUFCNT
	BNE	DOBUF2		;LOOP UNLESS BUFCNT JUST WENT TO ZERO
DOBUF4: PLA
	STA	LOGCOL
	JSR	PLACRS
	RTS
;
;
;
;
; STRBEG: MOVE BUFSTR TO BEGINNING OF LOGICAL LINE.
;
STRBEG: JSR	DOLCOL		;USE DOLCOL TO POINT HOLD1 AT BOL
	LDA	HOLD1
	STA	BUFSTR
	LDA	LMARGN
	STA	BUFSTR+1
	RTS
;
;
;
;
;PAGE	117
;
; DELTIM: TIME TO DELETE A LINE IF IT IS EMPTY AND AN EXTENSION
;
DELTIA: LDA	LOGCOL		;IF LOGCOL<>LMARGN
	CMP	LMARGN		;THEN DONT MOVE UP ONE
	BNE	DELTIB		;LINE BEFORE TESTING DELTIM
	DEC	ROWCRS
DELTIB: JSR	DOLCOL
DELTIM: LDA	LOGCOL		;TEST FOR EXTENSION
	CMP	LMARGN
	BEQ	DELTI3		;NO
	JSR	CONVRT
	LDA	RMARGN		;SET UP COUNT
	SEC
	SBC	LMARGN
	TAY
DELTI1: LDA	(ADRESS),Y
	BNE	DELTI3		;FOUND A NON-0 SO QUIT AND RETURN
	DEY
	BPL	DELTI1
DELTI2: JMP	DELLIB		;DELETE A LINE AND RETURN
DELTI3: RTS
;
;
;
; TSTCTL: SEARCH CNTRLS TABLE TO SEE IF ATACHR IS A CNTL CHAR
;
TSTCTL: LDX	#45		;PREPARE TO SEARCH TABLE
TSTCT1: LDA	CNTRLS,X
	CMP	ATACHR
	BEQ	TSTCT2
	DEX
	DEX
	DEX
	BPL	TSTCT1
TSTCT2: RTS
;
;
;
; PUSH ROWCRS,COLCRS AND COLCRS+1
;
PHACRS: LDX	#2
PHACR1: LDA	ROWCRS,X
	STA	TMPROW,X
	DEX
	BPL	PHACR1
	RTS
;
;
; PULL COLCRS+1,COLCRS AND ROWCRS
;
PLACRS: LDX	#2
PLACR1: LDA	TMPROW,X
	STA	ROWCRS,X
 
;PAGE	118

	DEX
	BPL	PLACR1
	RTS
;
;
;
; SWAP: IF MIXED MODE, SWAP TEXT CURSORS WITH REGULAR CURSORS
;
SWAP:	JSR	SWAPA		;THIS ENTRY POINT DOES RETUR1
	JMP	RETUR1
SWAPA:	LDA	BOTSCR
	CMP	#24
	BEQ	SWAP3
	LDX	#11
SWAP1:	LDA	ROWCRS,X
	PHA
	LDA	TXTROW,X
	STA	ROWCRS,X
	PLA
	STA	TXTROW,X
	DEX
	BPL	SWAP1
	LDA	SWPFLG
	EOR	#$FF
	STA	SWPFLG
SWAP3:	RTS
;
;
; CLICK: MAKE CLICK THROUGH KEYBOARD SPEAKER
;
CLICK:	LDX	#$7F
CLICK1: STX	CONSOL
	STX	WSYNC
	DEX
	BPL	CLICK1
	RTS
;
;
; COLCR: PUTS EITHER 0 OR LMARGN INTO COLCRS BASED ON MODE AND SWPFLG
;
COLCR:	LDA	#0
	LDX	SWPFLG
	BNE	COLCR1
	LDX	DINDEX
	BNE	COLCR2
COLCR1: LDA	LMARGN
COLCR2: STA	COLCRS
	RTS
;
;
; PUTMSC: PUT SAVMSC INTO ADRESS
;
PUTMSC: LDA	SAVMSC		;SET UP ADDRESS
	STA	ADRESS
 
;PAGE	119

	LDA	SAVMSC+1
	STA	ADRESS+1
	RTS
;
;PAGE	120

;	.PAGE
;
;
; DRAW -- DRAW A LINE FROM OLDROW,OLDCOL TO NEWROW,NEWCOL
; (THE AL MILLER METHOD FROM BASKETBALL)
DRAW:	LDX	#0
	LDA	ICCOMZ		;TEST COMMAND: $11=DRAW $12=FILL
	CMP	#$11
	BEQ	DRAWA
	CMP	#$12		;TEST FILL
	BEQ	DRAWB		;YES
	LDY	#NVALID		;NO, SO RETURN INVALID COMMAND
	RTS
DRAWB:	INX
DRAWA:	STX	FILFLG
	LDA	ROWCRS		;PUT CURSOR INTO NEWROW,NEWCOL
	STA	NEWROW
	LDA	COLCRS
	STA	NEWCOL
	LDA	COLCRS+1
	STA	NEWCOL+1
	LDA	#1
	STA	ROWINC		;SET UP INITIAL DIRECTIONS
	STA	COLINC
	SEC
	LDA	NEWROW		;DETERMINE DELTA ROW
	SBC	OLDROW
	STA	DELTAR
	BCS	DRAW1		;DO DIRECTION AND ABSOLUTE VALUE
	LDA	#$FF		;BORROW WAS ATTEMPTED
	STA	ROWINC		;SET DIRECTION=DOWN
	LDA	DELTAR
	EOR	#$FF		;DELTAR = |DELTAR|
	CLC
	ADC	#1
	STA	DELTAR
DRAW1:	SEC
	LDA	NEWCOL		;NOW DELTA COLUMN
	SBC	OLDCOL
	STA	DELTAC
	LDA	NEWCOL+1	;TWO-BYTE QUANTITY
	SBC	OLDCOL+1
	STA	DELTAC+1
	BCS	DRAW2		;DIRECTION AND ABSOLUTE VALUE
	LDA	#$FF		;BORROW WAS ATTEMPTED
	STA	COLINC		;SET DIRECTION = LEFT
	LDA	DELTAC
	EOR	#$FF		;DELTAC = |DELTAC|
	STA	DELTAC
	LDA	DELTAC+1
	EOR	#$FF
	STA	DELTAC+1
	INC	DELTAC		;ADD ONE FOR TWOS COMPLEMENT
	BNE	DRAW2
 
;PAGE	121

	INC	DELTAC+1
DRAW2:	LDX	#2		;ZERO RAM FOR DRAW LOOP
	LDY	#0
	STY	COLAC+1
DRAW3A: TYA
	STA	ROWAC,X
	LDA	OLDROW,X
	STA	ROWCRS,X
	DEX
	BPL	DRAW3A
	LDA	DELTAC		;FIND LARGER ONE (ROW OR COL)
;	STA	COUNTR		(PREPARE COUNTR AND ENDPT)
;	STA	ENDPT
	INX			;MAKE X 0
	TAY
	LDA	DELTAC+1
	STA	COUNTR+1
	STA	ENDPT+1
	BNE	DRAW3		;AUTOMATICALLY LARGER IF MSD>0
	LDA	DELTAC
	CMP	DELTAR		;LOW COL >LOW ROW?
	BCS	DRAW3		;YES
	LDA	DELTAR
	LDX	#2
	TAY
DRAW3:	TYA			;PUT IN INITIAL CONDITIONS
	STA	COUNTR
	STA	ENDPT
	PHA			;SAVE AC
	LDA	ENDPT+1		;PUT LSB OF HIGH BYTE
	LSR	A		;INTO CARRY
	PLA			;RESTORE AC
	ROR	A		;ROR THE 9 BIT ACUMULATOR
	STA	ROWAC,X
DRAW4A: LDA	COUNTR		;TEST ZERO
	ORA	COUNTR+1
	BNE	DRAW11		;IF COUNTER IS ZERO, LEAVE DRAW
	JMP	DRAW10
DRAW11: CLC			;ADD ROW TO ROWAC (PLOT LOOP)
	LDA	ROWAC
	ADC	DELTAR
	STA	ROWAC
	BCC	DRAW5
	INC	ROWAC+1
DRAW5:	LDA	ROWAC+1		;COMPARE ROW TO ENDPOINT
	CMP	ENDPT+1		;IF HIGH BYTE OF ROW IS .LT. HIGH
	BCC	DRAW6		;BYTE OF ENDPT, BLT TO COLUMN
	BNE	DRAW5A
	LDA	ROWAC
	CMP	ENDPT		;LOW BYTE
	BCC	DRAW6		;ALSO BLT
DRAW5A: CLC			;GE SO MOVE POINT
	LDA	ROWCRS
	ADC	ROWINC
 
;PAGE	122

	STA	ROWCRS
	LDX	#0		;AND SUBTRACT ENDPT FROM ROWAC
	JSR	SUBEND
DRAW6:	CLC			;DO SAME FOR COLUMN (DOUBLE BYTE ADD)
	LDA	COLAC		;ADD
	ADC	DELTAC
	STA	COLAC
	LDA	COLAC+1
	ADC	DELTAC+1
	STA	COLAC+1
	CMP	ENDPT+1		;COMPARE HIGH BYTE
	BCC	DRAW8
	BNE	DRAW6A
	LDA	COLAC		;COMPARE LOW BYTE
	CMP	ENDPT
	BCC	DRAW8
DRAW6A: BIT	COLINC		;+ OR - ?
	BPL	DRAW6B
	DEC	COLCRS		;DO DOUBLE BYTE DECREMENT
	LDA	COLCRS
	CMP	#$FF
	BNE	DRAW7
	LDA	COLCRS+1
	BEQ	DRAW7		;DON'T DEC IF ZERO
	DEC	COLCRS+1
	BPL	DRAW7		;(UNCONDITIONAL)
DRAW6B: INC	COLCRS		;DO DOUBLE BYTE INCREMENT
	BNE	DRAW7
	INC	COLCRS+1
DRAW7:	LDX	#2		;AND SUBTRACT ENDPT FROM COLAC
	JSR	SUBEND
DRAW8:	JSR	RANGE
	JSR	OUTPLT		;PLOT POINT
	LDA	FILFLG		;TEST RIGHT FILL
	BEQ	DRAW9
	JSR	PHACRS
	LDA	ATACHR
	STA	HOLD4
DRAW8A: LDA	ROWCRS		;SAVE ROW IN CASE OF CR
	PHA
	JSR	INCRSA		;POSITION CURSOR ONE PAST DOT
	PLA			;RESTORE ROWCRS
	STA	ROWCRS
DRAW8C: JSR	RANGE
	JSR	GETPLT		;GET DATA
	BNE	DRAW8B		;STOP IF NON-ZERO DATA IS ENCOUNTERED
	LDA	FILDAT		;FILL DATA
	STA	ATACHR
	JSR	OUTPLT		;DRAW IT
	JMP	DRAW8A		;LOOP
DRAW8B: LDA	HOLD4
	STA	ATACHR
	JSR	PLACRS
DRAW9:	SEC			;DO DOUBLE BYTE SUBTRACT
 
;PAGE	123

	LDA	COUNTR
	SBC	#1
	STA	COUNTR
	LDA	COUNTR+1
	SBC	#0
	STA	COUNTR+1
	BMI	DRAW10
	JMP	DRAW4A
DRAW10: JMP	RETUR1
 
;PAGE	124

;	.PAGE
;
;
; TABLES
;
;
; MEMORY ALLOCATION
;
ALOCAT: .BYTE	24,16,10,10,16,28,52,100,196,196,196,196

;
;
;	NUMBER OF DISPLAY LIST ENTRIES
;
NUMDLE: .BYTE	23,23,11,23,47,47,95,95,97,97,97,97

MXDMDE: .BYTE	19,19,9,19,39,39,79,79,65,65,65,65 ;(EXT OF NUMDLE)

;
;
; ANTIC CODE FROM INTERNAL MODE CONVERSION TABLE
;
;	INTERNAL	ANTIC CODE	DESCRIPTION
;	0		2		40X2X8	CHARACTERS
;	1		6		20X5X8	""
;	2		7		20X5X16	""
;	3		8		40X4X8	GRAPHICS
;	4		9		80X2X4	""
;	5		A		80X4X4	""
;	6		B		160X2X2	""
;	7		D		160X4X2	""
;	8		F		320X2X1	""
;	9		SAME AS 8 BUT GTIA 'LUM' MODE
;	10		SAME AS 8 BUT GTIA 'COL/LUM REGISTER' MODE
;	11		SAME AS 8 BUT GTIA 'COLOR' MODE
;
ANCONV: .BYTE	2,6,7,8,9,$A,$B,$D,$F,$F,$F,$F ;ZEROS FOR RANGE TEST IN
;
;
; PAGE TABLE TELLS WHICH DISPLAY LISTS ARE IN DANGER OF
; CROSSING A 256 BYTE PAGE BOUNDARY
;
PAGETB: .BYTE	0,0,0,0,0,0,0,1,1,1,1,1
;
;
; THIS IS THE NUMBER OF LEFT SHIFTS NEEDED TO MULTIPLY
; COLCRS BY 10,20, OR 40.	(ROWCRS*10)/(2**DHLINE)
 
;PAGE	125

;
DHLINE: .BYTE	2,1,1,0,0,1,1,2,2,2,2,2
;
;
; COLUMN: NUMBER OF COLUMNS
;
COLUMN: .BYTE	40,20,20,40,80,80,160,160,64,80,80,80 ;MODE 8 IS SPECIAL
;
;
;
; NOROWS: NUMBER OF ROWS
;
NOROWS: .BYTE	24,24,12,24,48,48,96,96,192,192,192,192
;
;
;
;
; DIV2TB: HOW MANY RIGHT SHIFTS FOR HCRSR FOR PARTIAL BYTE MODES
;
DIV2TB: .BYTE	0,0,0,2,3,2,3,2,3,1,1,1
;
;
; DMASKT: DISPLAY MASK TABLE
;
DMASKT: .BYTE	$00,$FF,$F0,$0F
	.BYTE	$C0,$30,$0C,$03
;
; MASKTB: BIT MASK.	(ALSO PART OF DMASKTB! DO NOT SEPARATE)
;
MASKTB: .BYTE	$80,$40,$20,$10,$08,$04,$02,$01
;
;
;
COLRTB: .BYTE	$28,$CA,$94,$46,$00
;
;
;
;
; CNTRLS: CONTROL CODES AND THEIR DISPLACEMENTS INTO THE
;	CONTROL CHARACTER PROCESSORS
;
CNTRLS: .BYTE	$1B
	.WORD	ESCAPE
 
;PAGE	126

	.BYTE	$1C
	.WORD	CRSRUP
	.BYTE	$1D
	.WORD	CRSRDN
	.BYTE	$1E
	.WORD	CRSRLF
	.BYTE	$1F
	.WORD	CRSRRT
	.BYTE	$7D
	.WORD	CLRSCR
	.BYTE	$7E
	.WORD	BS
	.BYTE	$7F
	.WORD	TAB
	.BYTE	$9B
	.WORD	DOCRWS
	.BYTE	$9C
	.WORD	DELLIN
	.BYTE	$9D
	.WORD	INSLIN
	.BYTE	$9E
	.WORD	CLRTAB
	.BYTE	$9F
	.WORD	SETTAB
	.BYTE	$FD
	.WORD	BELL
	.BYTE	$FE
	.WORD	DELCHR
	.BYTE	$FF
	.WORD	INSCHR
;
;
;
;
;
; ATAINT: ATASCI TO INTERNAL TABLE
;
ATAINT: .BYTE	$40,$00,$20,$60
;
;
; INTATA: INTERNAL TO ATASCI TABLE
;
INTATA: .BYTE	$20,$40,$00,$60
;
;
; ATASCI: ATASCII CONVERSION TABLE
;
ATASCI: .BYTE	$6C,$6A,$3B,$80,$80,$6B,$2B,$2A ;LOWER CASE
	.BYTE	$6F,$80,$70,$75,$9B,$69,$2D,$3D
	.BYTE	$76,$80,$63,$80,$80,$62,$78,$7A
	.BYTE	$34,$80,$33,$36,$1B,$35,$32,$31
	.BYTE	$2C,$20,$2E,$6E,$80,$6D,$2F,$81
	.BYTE	$72,$80,$65,$79,$7F,$74,$77,$71
	.BYTE	$39,$80,$30,$37,$7E,$38,$3C,$3E
	.BYTE	$66,$68,$64,$80,$82,$67,$73,$61
	.BYTE	$4C,$4A,$3A,$80,$80,$4B,$5C,$5E ;UPPER CASE
	.BYTE	$4F,$80,$50,$55,$9B,$49,$5F,$7C
	.BYTE	$56,$80,$43,$80,$80,$42,$58,$5A
	.BYTE	$24,$80,$23,$26,$1B,$25,$22,$21
	.BYTE	$5B,$20,$5D,$4E,$80,$4D,$3F,$81
	.BYTE	$52,$80,$45,$59,$9F,$54,$57,$51
	.BYTE	$28,$80,$29,$27,$9C,$40,$7D,$9D
	.BYTE	$46,$48,$44,$80,$83,$47,$53,$41
	.BYTE	$0C,$0A,$7B,$80,$80,$0B,$1E,$1F ;CONTROL
	.BYTE	$0F,$80,$10,$15,$9B,$09,$1C,$1D
	.BYTE	$16,$80,$03,$80,$80,$02,$18,$1A
	.BYTE	$80,$80,$85,$80,$1B,$80,$FD,$80
	.BYTE	$00,$20,$60,$0E,$80,$0D,$80,$81
	.BYTE	$12,$80,$05,$19,$9E,$14,$17,$11
	.BYTE	$80,$80,$80,$80,$FE,$80,$7D,$FF
	.BYTE	$06,$08,$04,$80,$84,$07,$13,$01
;
;
PIRQ5:	LDA	KBCODE
	CMP	CH1		;TEST AGAINST LAST KEY PRESSED
	BNE	PIRQ3		;IF NOT, GO PROCESS KEY
	LDA	KEYDEL		;IF KEY DELAY BYTE > 0
	BNE	PIRQ4		;IGNORE KEY AS BOUNCE
PIRQ3:	LDA	KBCODE		;RESTORE AC
	CMP	#CNTL1		;TEST CONTROL 1 (SSFLAG)
	BNE	PIRQ1
	LDA	SSFLAG
	EOR	#$FF
	STA	SSFLAG
	BCS	PIRQ4		;(UNCONDITIONAL) MAKE ^1 INVISIBLE
PIRQ1:	STA	CH
	STA	CH1
	LDA	#3
	STA	KEYDEL		;INITIALIZE KEY DELAY FOR DEBOUNCE
	LDA	#0		;CLEAR COLOR SHIFT BYTE
	STA	ATRACT
PIRQ4:	LDA	#$30
	STA	SRTIMR
PIRQ2:	PLA
	RTI
;
;
	.BYTE	$FF,$FF,$FF,$FF,$FF,$FF
;
CRNTPC	=*
	.ORG	$14
KBDSPR: .BYTE	$FFF8-CRNTPC ;^GDISPLC IS TOO LONG
	.END
