DataMuseum.dk

Presents historical artifacts from the history of:

Christian Rovsing CR7, CR8 & CR16 CP/M

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Christian Rovsing CR7, CR8 & CR16 CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦c6b303419⟧ TextFile

    Length: 48768 (0xbe80)
    Types: TextFile
    Names: »ROUTIN.SRC«

Derivation

└─⟦79fba5010⟧ Bits:30003902 Diskette til Rovsing CP/M maskine
    └─ ⟦this⟧ »ROUTIN.SRC« 

TextFile

$PAGELENGTH(44)
$TITLE(EDS 700 INPUT ROUTINES - DE LUXE V2.0)
$NOGE
;*************************************************************************
;
;	NAME:		ROUTIN.SRC
;
;	DESCRIPTION:	THIS FILE CONTAIN ALL THE ROUTINES THAT ARE
;			COMMON FOR SERIAL- AND KEYBOARD INPUT IN
;			THE EDS 700 SYSTEM.
;
;	PROGRAMMER:	PREBEN OBBEKAER. A/S MODULEX
;
;*************************************************************************
$EJECT

	NAME	ROUTINE

ROUTINE_1 SEGMENT CODE
POUTINE_2 SEGMENT BIT

PUBLIC CHANGE_ROUT,CONFIG_ROUT,CHANGE_UPDATE,CHANGE_DIGIT,CONF_DIGIT
PUBLIC CHANGE_2,DOWN_ARROW_ROUT,UP_ARROW_ROUT,LEFT_ARROW_ROUT
PUBLIC RIGHT_ARROW_ROUT,CONF_DELETE,CHANGE_DELETE,DECIMAL_ROUT
PUBLIC CHANGE_RETURN,COPY_12_ROUT,COPY_21_ROUT,NO_VAL_ROUT,INPUT_DELAY
PUBLIC GET_SK_BH,DATE_COMPONENT

EXTRN CODE(CHECK_STATUS,SEND_BUFFER,DEQ,GET_BUFFER)
EXTRN CODE(CLRBUF,CLEAR_SCREEN,WRITE_TEXT,WRITE_LINE,RCONF)
EXTRN CODE(CONF4,CONER,CONF,SIGNAL,WAIT,COPY,GET_TRANS)
EXTRN CODE(EDS_INPUT,ENQ,CURSOR_POS,SERIAL_SHARE)
EXTRN CODE(WRITE_DATE_LINE)

EXTRN NUMBER(EDS_STATUS,CONF_STATUS,RESOFF,CUTYPE,TYPENO,CURSOR)
EXTRN NUMBER(CUROW,CUCOL,DS1,INSEM,INPUTF,INPUTE,SR1,ROWNO,COLNO)
EXTRN NUMBER(TEX1,TYTEX,NODIG,SKPH,SKPL,DIGNO,MAXDIG,SOURCE_COL)
EXTRN NUMBER(DEST_COL,ROS,WOS,DOS,CONF_INPUT,MAX,ERR5,WSM,ESC,CR)
EXTRN NUMBER(ROUT_PNT,UP,PASSEM)

EXTRN BIT(ZERO,CHANGE_MODE,BUSY_ROUTINE,EMPTY,BUSY_UPDATING)
EXTRN BIT(UPDATE_MODE,CONFIG_MODE)

EXTRN DATA(BYTECNT,COMM_BYTE,BUFFER_AREA,SERKEY_STATUS,SCROLL)

$INCLUDE(:F1:MAC.SRC)

	RSEG	ROUTINE_2

DATE_COMPONENT:	DBIT	1	;INDICATING DATE COMPONENT
COLUMN_2:	DBIT	1	;INDICATING COPY FROM COLUMN 2

	RSEG	ROUTINE_1
	
$EJECT
;**********************************************************************
;
;	NAME:		CHANGE_ROUT
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "CHANGE"
;			KEY IS ACTIVATED. IT MOVES THE CURSOR FROM ONE
;			TYPE OF BOARDS TO THE NEXT. THE CURSOR POINTS
;			AT THE LEAST SIGNIFICANT DIGET IN FIRST ROW
;			AND FIRST COLUMN.
;
;************************************************************************

CHANGE_ROUT:
	CALL	CHECK_STATUS	;CHECK IF CONFIGURATION STATUS OK
	JZ	CHANGE_1	;JUMP IF OK
	LJMP	RESET		;OTHERWISE CONFIGURATE AGAIN
CHANGE_1:
	CLR 	ZERO		;THIS ROUTINE DO NOTHING
	MOV	DPTR,#EDS_STATUS;POINT AT SYSTEN STATUS BYTE
	MOVX	A,@DPTR		;READ STATUS
	JB	CHANGE_MODE,CHANGE_3	;JUMP IF ALREADY CHANGE MODE
	CLR	A		;OTHERWISE CLEAR STATUS
	SETB	CHANGE_MODE	;AND INDICATE CHANGE MODE NOW
	MOVX	@DPTR,A		;AND STORE STATUS AGAIN

; NOW USER MUST TYPE IN CHANGE CODE TO GO ON

	SETB	BUSY_ROUTINE	;INDICATE ROUTINE BUSY
	MOV	R0,#CONF_STATUS	;POINT AT STATUS BYTE FOR CONF 
	MOV	P2,#RESOFF	;IN RESERVED BYTE
	MOV	A,#9H		;INDICATE CHANGE CODE NEEDED
	MOVX	@R0,A		;
	LJMP	CONF4		;JUMP TO CONFIGURATION PART

; HERE WHEN CODE ACCEPTED

CHANGE_2:
	MOV	R0,#CUTYPE	;POINT AT CURRENT TYPE NO
	MOV	P2,#RESOFF	;
	CLR	A		;INDICATE FIRST TIME IN CHANGE MODE
	MOVX	@R0,A		;
	LJMP	CHANGE_4	;
CHANGE_3:
	JB	EMPTY,CHANGE_4	;IF THE BUFFER IS EMPTY THEN DO NOTHING
	CALL	STORE_SHARE	;OTHERWISE STORE SHARE IN BUFFER
	SETB	EMPTY		;
CHANGE_4:
	MOV	R0,#CUTYPE	;THE CURRENT TYPENO. IS INCREMENTED
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;AND IF TYPENO > MAX_TYPENO THEN
	MOVX	@R0,A		;CURRENT TYPENO := 1
	MOV	R7,A		;
	MOV	R0,#TYPENO	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,R7		;
	JNC	CHANGE_5	;
	MOV	R0,#CUTYPE	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
CHANGE_5:
	MOV	R0,#CURSOR	;CURSOR := LEAST SIGNIFICANT
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW STATUS ABOUT THE NEW TYPE MUST BE FETCHED FROM STORE

	CALL	GET_SK_BH	;GET EMPTY BUFFER

; NOW AN EMPTY BUFFER IS FOUND

	MOV	BYTECNT,#1H	;INITIATE BYTES FOR SENDING BUFFER
	MOV	COMM_BYTE,#DS1	;
	MOV	R0,#CUTYPE	;GET CURRENT TYPE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	MOV	BUFFER_AREA,A	;WRITE IT INTO BUFFER

; NOW BUFFER MUST BE SEND TO COMMAND TASK

	CALL	SEND_BUFFER	;SEND BUFFER TO STORE TASK
	%VENT	(250,INSEM)	;WAIT FOR BUFFER TO RETURN
	MOV	PSW,#0H		;
	MOV	A,#INPUTF	;
	CALL	DEQ		;TRY TO GET RETURN BUFFER FROM FULL QUEUE
	JNZ	CHANGE_6	;JUMP IF BUFFER FOUND
	LJMP	INPUT_DELAY	;

; HERE WHEN A BUFFER IS RECEIVED

CHANGE_6:
	CALL	GET_BUFFER	;READ BUFFER CONTENT
	CALL	CLRBUF		;AND RETURNATE BUFFER
	MOV	A,COMM_BYTE	;GET BUFFER COMMAND
	XRL	A,#SR1		;IF COMMAND <> RETURN STATUS 1
	JZ	CHANGE_7	;THEN DO NOTHING
	LJMP	INPUT_DELAY	;

; THE BUFFER WAS THE RIGHT ONE

CHANGE_7:
	MOV	A,BUFFER_AREA	;GET NO OF TYPES
	MOV	R0,#TYPENO	;
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;AND WRITE IT INTO RESERVED BYTE
	MOV	A,BUFFER_AREA+3	;GET NO OF ROWS
	MOV	R0,#ROWNO	;
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;AND WRITE IT INTO RESERVED BYTE
	MOV	A,BUFFER_AREA+4	;GET NO OF COLUMNS
	MOV	R0,#COLNO	;
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;AND WRITE IT INTO RESERVED BYTE
	MOV	R0,#DATE_COLUMN	;POINT AT STORE FOR DATE COLUMNS
	MOV	R2,#4		;COUNTER FOR NO OF COLUMNS
	MOV	R1,#BUFFER_AREA+10	;POINT AT POSITION IN BUFFER
CHANGE_8:
	MOV	A,@R1		;READ COLUMN
	MOVX	@R0,A		;AND WRITE IN STORE BYTES
	INC	R1		;POINT AT NEXT
	INC	R0		;
	DJNZ	R2,CHANGE_8	;COPY ALL 4
	MOV	R0,#DATE_COLUMN	;POINT AT STORE AGAIN
	MOV	R2,#4		;SET UP COUNTER
	MOV	R3,#1		;SET UP COUNTER FOR COLUMN NO
CHANGE_9:
	MOVX	A,@R0		;READ COLUMN BYTE
	JNZ	CHANGE_10	;JUMP IF DATE COMPONENT
	INC	R3		;OTHERWISE INCREMENT COLUMN NO
	INC	R0		;POINT AT NEXT
	DJNZ	R2,CHANGE_9	;TRY THEM ALL

; HERE IF NO DATE COMPONENTS AT THIS TYPE

	MOV	R0,#CUROW	;POINT AT STORE FOR CURRENT ROWNO
	MOV	A,#1		;START WITH ROW 1
	MOVX	@R0,A		;
	MOV	R0,#CUCOL	;POINT AT STORE FOR CURRENT COLUMN NO
	MOVX	A,@R0		;START WITH COLUMN 1
	JMP	CHANGE_12	;

; HERE IF DATE COMPONENT AT THIS TYPE

CHANGE_10:
	MOV	R0,#CUROW	;POINT AT STORE FOR CURRENT ROWNO
	CLR	A		;START WITH ROW 0
	MOVX	@R0,A		;
	MOV	R0,#CUCOL	;POINT AT STORE FOR CURRENT COLUMN NO
	JBC	COLUMN_2,CHANGE_11	;JUMP IF JUST BEEN COPY 2 TO 1
	MOV	A,R3		;GET COLUMN NO
	MOVX	@R0,A		;AND STORE
	JMP	CHANGE_12	;
CHANGE_11:
	MOV	A,#2		;SET CURSOR UP TO COLUMN 2
	MOVX	@R0,A		;AND STORE
CHANGE_12:
	MOV	A,SERKEY_STATUS	;
	DEC	A		;
	JNZ	CHANGE_TO_SCREEN;WRITE SCREEN FULL OF SHARES
	LJMP 	GET_SHARE	;GET A NEW SHARE AND WRITE IT

; HERE IS THE ROUTINE IS USED BY THE SERIAL TASK. THE WHOLE SCREEN MUST 
; BE FILLED WITH SHARES ABOUT THE NEW TYPE.

CHANGE_TO_SCREEN:
	CALL	CLEAR_SCREEN	;
	MOV	R0,#2H		;WRITE HEADLINE IN LINE 2
	MOV	R1,#15H		;START IN COLUNM 10
	MOV	A,#TEX1		;
	MOV	R4,#0FFH	;JUST WRITE TEXT
	CALL	WRITE_TEXT	;

; NEXT WRITE WHICH TYPE TO WORK ON NOW

	MOV	R0,#CUTYPE	;GET CURRENT TYPENO
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	MOV	R5,A		;
	MOV	R4,#0H		;
	MOV	R1,#3H		;WRITE IN ROW 3 COL 3 ON SCREEN
	MOV	R0,#4H		;
	MOV	A,#TYTEX	;
	CALL	WRITE_TEXT	;WRITE TEXT ON SCREEN

; HERE WHEN READY TO WRITE SHARES ON SCREEN

	MOV	R0,#CUROW	;POINT AT CURRENT LINE NO
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;READ CURRENT ROWNO
	JNZ	CTSC0		;JUMP IF NOT DATE COMP LINE
	CALL	WRITE_DATE_LINE	;OTHERWISE WRITE DATE COMPONENTS
CTSC0:	MOV	R0,#ROWNO	;GET MAX NO OF LINES AT THIS TYPE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,#15H		;IS MAX NO OF LINES > 20
	JC	CTSC1		;JUMP IF NO
	MOV	R1,#14H		;IF YES THEN JUST WRITE THE FIRST 20 LINES
	LJMP	CTSC2		;
CTSC1:	MOVX	A,@R0		;IF NO OF LINES < 20 THEN WRITE THEM ALL
	MOV	R1,A		;

; R1 NOW CONTAIN NO OF LINES TO WRITE

CTSC2:	MOV	R0,#DIGNO	;POINT AT COUNTER FOR LINE NO
	MOV	A,#1		;START WITH LINE 1
	MOVX	@R0,A		;AND STORE
CTSC3:	MOV	SCROLL,#0H	;
	MOV 	A,R1		;
	MOV	R0,#NODIG	;
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;
	CALL	WRITE_LINE	;WRITE ONE LINE
	MOV	R0,#DIGNO	;GET CURRENT ROWNO
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;AND INCREMENT IT
	MOVX	@R0,A		;
	MOV	R0,#NODIG	;
	MOVX	A,@R0		;
	MOV	R1,A		;
	DJNZ	R1,CTSC3	;CONTINUE UNTIL ALL LINES WRITTEN

; FINALLY SET CURSOR TO POINT AT THE SHARE IN FIRST LINE AND FIRST COLUMN

	LJMP	GET_SHARE	;WRITE SHARE AND POSITION CURSOR

$EJECT
;************************************************************************
;
;	NAME:		DOWN_ARROW_ROUT
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "DOWN ARROW"
;			KEY IS ACTIVATED. IT MOVES THE CURSOR DOWN ONE
;			ROW AND DON'T CHANGE COLOUMNO.
;
;**************************************************************************

DOWN_ARROW_ROUT:
	CLR 	ZERO		;THIS ROUTINE DO NOTHING
	JB	EMPTY,DOA1	;IF THE BUFFER IS EMPTY THEN DO NOTHING
	CALL	STORE_SHARE	;
	SETB	EMPTY		;
DOA1:	MOV	R0,#CUROW	;THE CURRENT ROWNO. IS INCREMENTED
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;AND IF ROWNO > MAX_ROWNO THEN
	MOVX	@R0,A		;CURRENT ROWNO := 1
	MOV	R7,A		;
	MOV	R0,#ROWNO	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,R7		;
	JNC	DOA2		;
	MOV	R0,#CUROW	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
DOA2:	MOV	R0,#CURSOR	;CURSOR := LEAST SIGNIFICANT
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW A NEW SHARE MUST BE FETCHED FROM STORE

	LJMP	GET_SHARE	;GET NEW SHARE AND WRITE

$EJECT
;**************************************************************************
;
;	NAME:		UP_ARROW_ROUT
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "UP ARROW"
;			KEY IS ACTIVATED. IT MOVES THE CURSOR UP ONE
;			ROW AND DON'T CHANGE COLOUMNO.
;
;**************************************************************************

UP_ARROW_ROUT:
	CLR 	ZERO		;THIS ROUTINE DO NOTHING
	JB	EMPTY,UPA1	;IF THE BUFFER IS EMPTY THEN DO NOTHING
	CALL	STORE_SHARE	;
	SETB	EMPTY		;
UPA1:	JB	DATE_COMPONENT,UPA2	;JUMP IF DATE_COMPONENT
	MOV	R0,#CUROW	;THE CURRENT ROWNO. IS INCREMENTED
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	DEC	A		;AND IF ROWNO > MAX_ROWNO THEN
	MOVX	@R0,A		;CURRENT ROWNO := 1
	JNZ	UPA3		;
	MOV	R0,#CUCOL	;POINT AT CURRENT COLUMN NO
	MOVX	A,@R0		;READ CURRENT COLUMN NO
	MOV	R0,#DATE_COLUMN	;POINT AT STORE FOR DATE COMP COLUMNS
	DEC	A		;
	ADD	A,R0		;ADD COLUMN NO TO TABLE START
	MOV	R0,A		;SET UP POINTER TO TABLE
	MOVX	A,@R0		;READ IF ANY DATE COMP
	JNZ	UPA3		;JUMP IF A DATE COMPONENT
UPA2:	MOV	R0,#ROWNO	;
	MOVX	A,@R0		;
	MOV	R0,#CUROW	;
	MOVX	@R0,A		;
UPA3:	MOV	R0,#CURSOR	;CURSOR := LEAST SIGNIFICANT
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW A NEW SHARE MUST BE FETCHED FROM STORE

	LJMP	GET_SHARE	;GET NEW SHARE AND WRITE

$EJECT
;*************************************************************************
;
;	NAME:		LEFT_ARROW_ROUT
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "LEFT ARROW"
;			KEY IS ACTIVATED. IT MOVES THE CURSOR ONE COLUMN
;			TO THE LEFT, AND ONLY CHANGES THE ROWNO IF NO MORE
;			COLUMNS TO MOVE. THEN ROWNO IS DECREMENTED.
;
;**************************************************************************

LEFT_ARROW_ROUT:
	JB	DATE_COMPONENT,LEA4	;JUMP IF DATE COMPONENT
	MOV	R0,#CURSOR	;THE CURSOR IS MOVED ONE CHARACTER 
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;TO THE LEFT
	INC	A		;
	MOVX	@R0,A		;
	CLR	C		;IF CURSOR = MAX CURSOR THEN
	SUBB	A,#8H		;MOVE CURSOR ONE COLUMN TO THE LEFT
	JNC	LEA1		;
	LJMP	DISPLAY_SHARE	;
LEA1:	JB	EMPTY,LEA2	;IF THE BUFFER IS EMPTY THEN DO NOTHING
	CALL	STORE_SHARE	;
	SETB	EMPTY		;
LEA2:	CLR	ZERO		;
	MOV	R0,#CUCOL	;CURRENT COLUMNNO IS DECREMENTED BY ONE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	DEC	A		;
	MOVX	@R0,A		;CURRENT COLUMNNO = MAX COLUMNNO
	JNZ	LEA3		;
	MOV	R0,#COLNO	;
	MOVX	A,@R0		;
	MOV	R0,#CUCOL	;
	MOVX	@R0,A		;
	MOV	R0,#CUROW	;CURRENT ROWNO IS DECREMENTED BY ONE
	MOVX	A,@R0		;AND IF IT REACHES 0 THEN
	DEC	A		;CURRENT ROWNO = MAX ROWNO
	MOVX	@R0,A		;
	JNZ	LEA3		;
LEA2A:	MOV	R0,#ROWNO	;
	MOVX	A,@R0		;
	MOV	R0,#CUROW	;
	MOVX	@R0,A		;
LEA3:	MOV	R0,#CURSOR	;CURSOR := LEAST SIGNIFICANT
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW A NEW SHARE MUST BE FETCHED FROM STORE

	LJMP	GET_SHARE	;GET SHARE AND WRITE IT

; HERE IF EDITING IN DATE COMPONENT

LEA4:	MOV	R0,#CURSOR	;POINT AT STORE FOR CURSOR POSITION
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;READ CURSOR POSITION
	DEC	A		;DECREMENT POSITION
	MOVX	@R0,A		;AND STORE AGAIN
	JZ	LEA7		;JUMP IF CHANGE TO ANOTHER DISPLAY
	MOV	B,A		;OTHERWISE STORE NEW CURSOR POS
	XRL	A,#6		;IS NEW POSITION = 6
	JZ	LEA5		;JUMP IF IT IS
	MOV	A,B		;OTHERWISE GET POSITION AGAIN
	XRL	A,#3		;IS NEW POSITION = 3
	JNZ	LEA6		;JUMP IF NOT
LEA5:	MOV	A,B		;OTHERWISE GET NEW POSITION
	DEC	A		;AND DECREMENT AGAIN
	MOVX	@R0,A		;AND STORE AGAIN
LEA6:	JMP	DISPLAY_SHARE	;WRITE SHARE

; HERE IF CHANGE TO NEW DISPLAY

LEA7:	JB	EMPTY,LEA7A	;JUMP IF NO BUFFER IN SYSTEM
	CALL	STORE_DISPLAY	;OTHERWISE STORE SHARE
	SETB	EMPTY		;
LEA7A:	MOV	R0,#CUCOL	;POINT AT CURRENT COLUMN NO
	MOVX	A,@R0		;READ CURRENT COLUMN NO
	MOV	R3,A		;
	MOV	R0,#DATE_COLUMN	;POINT AT STORE FOR DATE COMP POS
	DEC	A		;
	ADD	A,R0		;ADD	OFFSET TO TABLE START
	MOV	R0,A		;SET UP POINTER TO TABLE
LEA8:	DEC	R0		;DECREMENT POINTERE
	DEC	R3		;DECREMENT COLUMN NO
	MOV	A,R3		;GET NEW COLUMN NO
	JZ	LEA10		;JUMP IF NO MORE COLUMNS
	MOVX	A,@R0		;OTHERWISE READ FROM TABLE
	JNZ	LEA9		;JUMP IF DATE COMPONENT
	JMP	LEA8		;OTHERWISE TRY NEXT

; HERE WHEN COLUMN FOUND

LEA9:	MOV	R0,#CUCOL	;POINT AT CURRENT COLUMN NO
	MOV	A,R3		;GET NEW COLUMN NO
	MOVX	@R0,A		;AND STORE
	JMP	LEA3		;

; HERE IF NO MORE COLUMNS

LEA10:	MOV	R0,#COLNO	;POINT AT MAX NO OF COLUMNS
	MOVX	A,@R0		;READ MAX NO
	MOV	R0,#CUCOL	;POINT AT STORE FOR CURRENT COLUMN
	MOVX	@R0,A		;AND STORE
	JMP	LEA2A		;

$EJECT
;************************************************************************
;
;	NAME:		RIGHT_ARROW_ROUT
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "RIGHT ARROW"
;			KEY IS ACTIVATED. IT MOVES THE CURSOR ONE CHARACTER
;			TO THE RIGHT. IF NO MORE CHARACTERS IN DISPLAY, THE
;			CURSOR MOVES ONE COLUMN TO THE RIGHT.
;
;*************************************************************************

RIGHT_ARROW_ROUT:
	JB	DATE_COMPONENT,RIA4	;JUMP IF DATE COMPONENT
	MOV	R0,#CURSOR	;THE CURSOR IS DECREMENTED BY
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;ONE
	DEC	A		;IF CURSOR = 0 THEN IT MOVES
	MOVX	@R0,A		;ONE COLUMN TO THE RIGHT
	JZ	RIA1		;OTHERWISE JUMP
	LJMP	DISPLAY_SHARE	;
RIA1:	JB	EMPTY,RIA2	;IF THE BUFFER IS EMPTY THEN DO NOTHING
	CALL	STORE_SHARE	;
	SETB	EMPTY		;
RIA2:	CLR	ZERO			;
	MOV	R0,#CUCOL	;THE CURRENT COLNO. IS INCREMENTED
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;AND IF COLNO > MAX_COLNO THEN
	MOVX	@R0,A		;CURRENT COLNO := 1
	MOV	R7,A		;
	MOV	R0,#COLNO	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,R7		;
	JNC	RIA3		;
RIA2A:	MOV	R0,#CUCOL	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
	MOV	R0,#CUROW	;CURRENT ROWNO IS INCREMENTED BY ONE
	MOVX	A,@R0		;
	INC	A		;IF CURRENT ROWNO > MAX ROWNO THEN
	MOVX	@R0,A		;CURRENT ROWNO = 1
	MOV	R6,A		;
	MOV	R0,#ROWNO	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,R6		;
	JNC	RIA3		;
	MOV	R0,#CUROW	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
RIA3:	MOV	R0,#CURSOR	;CURSOR := LEAST SIGNIFICANT
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW A NEW SHARE MUST BE FETCHED FROM STORE

	LJMP	GET_SHARE	;GET NEW SHARE

; HERE IF EDITING IN DATE COMPONENT

RIA4:	MOV	R0,#CURSOR	;POINT AT STORE FOR CURSOR POSITION
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;READ CURSOR POSITION
	INC	A		;INCREMENT POSITION
	MOVX	@R0,A		;AND STORE AGAIN
	MOV	B,A		;STORE POSITION
	XRL	A,#9		;IS NEW POSITION TOO BIG
	JZ	RIA7		;JUMP IF CHANGE TO ANOTHER DISPLAY
	MOV	A,B		;GET NEW POSITION
	XRL	A,#6		;IS NEW POSITION = 6
	JZ	RIA5		;JUMP IF IT IS
	MOV	A,B		;OTHERWISE GET POSITION AGAIN
	XRL	A,#3		;IS NEW POSITION = 3
	JNZ	RIA6		;JUMP IF NOT
RIA5:	MOV	A,B		;OTHERWISE GET NEW POSITION
	INC	A		;AND INCREMENT AGAIN
	MOVX	@R0,A		;AND STORE AGAIN
RIA6:	JMP	DISPLAY_SHARE	;WRITE SHARE

; HERE IF CHANGE TO NEW DISPLAY

RIA7:	JB	EMPTY,RIA8	;JUMP IF NO BUFFER IN SYSTEM
	CALL	STORE_DISPLAY	;OTHERWISE STORE SHARE
	SETB	EMPTY		;
RIA8:	MOV	R0,#COLNO	;POINT AT MAX COLUMN NO
	MOVX	A,@R0		;READ MAX NO
	INC	A		;
	MOV	R5,A		;AND STORE TEMP
	MOV	R0,#CUCOL	;POINT AT CURRENT COLUMN NO
	MOVX	A,@R0		;READ CURRENT COLUMN NO
	MOV	R3,A		;
	MOV	R0,#DATE_COLUMN	;POINT AT STORE FOR DATE COMP POS
	DEC	A		;
	ADD	A,R0		;ADD	OFFSET TO TABLE START
	MOV	R0,A		;SET UP POINTER TO TABLE
RIA9:	INC	R0		;INCREMENT POINTERE
	INC	R3		;INCREMENT COLUMN NO
	MOV	A,R3		;GET NEW COLUMN NO
	XRL	A,R5		;IS COLUMN TOO BIG
	JZ	RIA11		;JUMP IF NO MORE COLUMNS
	MOVX	A,@R0		;OTHERWISE READ FROM TABLE
	JNZ	RIA10		;JUMP IF DATE COMPONENT
	JMP	RIA9		;OTHERWISE TRY NEXT

; HERE WHEN COLUMN FOUND

RIA10:	MOV	R0,#CUCOL	;POINT AT CURRENT COLUMN NO
	MOV	A,R3		;GET NEW COLUMN NO
	MOVX	@R0,A		;AND STORE
	JMP	RIA3		;

; HERE IF NO MORE COLUMNS

RIA11:	JMP	RIA2A		;

$EJECT
;*************************************************************************
;
;	NAME:		DELETE
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "DELETE"
;			KEY IS ACTIVATED. IT DELETES BUFFER CONTENT
;			AND WRITES A 0 IN DISPLAY.
;
;*************************************************************************

CONF_DELETE:
	MOV	R0,#CONF_INPUT	;ROUTINE CLEAR THE UNTIL NOW TYPED VALUE
	MOV	P2,#RESOFF	;
	CLR	A		;
	MOVX	@R0,A		;
	LJMP	RCONF		;

CHANGE_DELETE:
	CLR 	ZERO		;
	MOV	R0,#SKPH	;POINTER TO BUFFER
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;FROM RESERVED BYTES
	MOV	DPH,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	DPL,A		;POINTER -> LINK.H IN BH
	INC	DPTR		;
	INC	DPTR		;POINTER -> BUFADR.H IN BH
	MOVX	A,@DPTR		;
	MOV	R2,A		;THE START ADR OF BUFFER IS
	INC	DPTR		;
	MOVX	A,@DPTR		;STORED IN R4 AND R5
	MOV	R3,A		;
	SETB	EMPTY		;
	MOV	DPH,R2		;POINTER -> START OF BUFFER
	MOV	DPL,R3		;
	INC	DPTR		;
	INC	DPTR		;
	INC	DPTR		;POINTER -> FIRST DIGIT IN SHARE
	JB	DATE_COMPONENT,DEL2	;JUMP IF DATE COMPONENT
	MOV	A,#'0'		;LEAST SIGN. DIGIT MUST BE 0
	MOVX	@DPTR,A		;
	INC	DPTR		;
	MOV	R1,#6H		;
	MOV	A,#' '		;
DEL1:	MOVX	@DPTR,A		;AND THE LAST DIGITS MUST BE SP
	INC	DPTR		;
	DJNZ	R1,DEL1		;
DEL1A:	MOV	R0,#CURSOR	;THE CURSOR = 1
	MOV	P2,#RESOFF	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
	MOV	R0,#DIGNO	;
	CLR	A		;
	MOVX	@R0,A		;
	CLR	EMPTY		;
	SETB	ZERO		;

; THIS BUFFER MUST BE COPIED AND THE NEW ONE SEND TO DISPLAY TASK

	LJMP	DISPLAY_SHARE	;WRITE NEW SHARE

; HERE IF DATE COMPONENT

DEL2:	MOV	R3,#3		;COUNTER TO NO OF 00 BLOCKS
	JMP	DEL4		;
DEL3:	MOV	A,#'.'		;READY TO WRITE <.>
	MOVX	@DPTR,A		;WRITE TO BUFFER
	INC	DPTR		;
DEL4:	MOV	R2,#2		;COUNTER TO NO OF 0 IN BLOCK
	MOV	A,#'0'		;READY TO WRITE 0
DEL5:	MOVX	@DPTR,A		;WRITE TO BUFFER
	INC	DPTR		;POINT AT NEXT
	DJNZ	R2,DEL5		;WRITE WHOLE BLOCK
	DJNZ	R3,DEL3		;WRITE ALL BLOCKS
	JMP	DEL1A		;

$EJECT
;************************************************************************
;
;	NAME:		DECIMAL_ROUT
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "." KEY
;			IS ACTIVATED. IT PUTS A . AFTER THE CHARACTER
;			THAT THE CURSOR POINTS AT.
;
;*************************************************************************

DECIMAL_ROUT:
	JB	DATE_COMPONENT,DEC0	;JUMP IF DATE COMPONENT
	JNB	EMPTY,DEC1	;
DEC0:	LJMP	INPUT_DELAY	;
DEC1:	MOV	R0,#SKPH	;POINTER TO BUFFER
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;FROM RESERVED BYTES
	MOV	DPH,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	DPL,A		;POINTER -> LINK.H IN BH
	INC	DPTR		;
	INC	DPTR		;POINTER -> BUFADR.H IN BH
	MOVX	A,@DPTR		;
	MOV	R4,A		;THE STARTADR OF BUFFER IS
	INC	DPTR		;
	MOVX	A,@DPTR		;STORED IN R4 AND R5
	MOV	R5,A		;
	MOV	DPH,R4		;POINTER -> START OF BUFFER
	MOV	DPL,R5		;
	INC	DPTR		;
	INC	DPTR		;
	INC	DPTR		;POINTER -> FIRST DIGIT IN SHARE
	MOV	R2,DPH		;
	MOV	R3,DPL		;STORE THIS POINTER IN R2 AND R3

; NOW CHECK IF DIGIT RIGHT TO CURSOR POS IS SPACE (SP)

	MOV	R0,#CURSOR	;GET CURSOR POSITION
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	DEC	A		;AND DECREMENT
	MOV	R0,A		;
	JZ	DEC5		;IF NEW POS = 0 THEN JUMP
DEC2:	DJNZ	R0,DEC3		;LOOK THROUGH BUFFER TO CURSOR POS
	MOVX	A,@DPTR		;WHEN POS RIGHT TO CURSOR FOUND THEN
	XRL	A,#' '		;READ DIGIT AND COMPAIRE TO SP
	JNZ	DEC4		;IF NOT EQUAL THEN CONTINUE
	LJMP	INPUT_DELAY	;OTHERWISE DO NOTHING
DEC3:	INC	DPTR		;
	LJMP	DEC2		;

; IF THERE IS ANY . IN SHARE, THEN IT IS CLEARED AND ALL DIGITS
; TO THE LEFT IS SHIFTED ONE POSITION TO THE RIGHT.

DEC4:	CLR	ZERO		;
DEC5:	MOV	DPH,R2		;SET UP POINTER FOR FIRST DIGIT
	MOV	DPL,R3		;
	MOV	R1,#0H		;
	MOV	R0,#7H		;
DEC6:	MOVX	A,@DPTR		;GET DIGIT
	INC	R1		;
	XRL	A,#2EH		;AND SEE IF IT IS A .
	JZ	DEC7		;JUMP IF IT IS
	INC	DPTR		;
	DJNZ	R0,DEC6		;
	LJMP	DEC10		;IF NO . THEN JUMP

; NOW A . HAS BEEN FOUND

DEC7:	DJNZ	R0,DEC8		;
	LJMP	DEC10		;
DEC8:	PUSH	DPH		;STORE POINTER IN STACK
	PUSH	DPL		;
	INC	DPTR		;
	MOV	R4,DPH		;STORE POINTER TO SOURCE DIGIT
	MOV	R5,DPL		;IN R4 AND R5
DEC9:	MOV	DPH,R4		;GET POINTER
	MOV	DPL,R5		;
	MOVX	A,@DPTR		;AND GET DIGIT
	INC	DPTR		;
	MOV	R4,DPH		;STORE SOURCE POINTER
	MOV	R5,DPL		;
	POP	DPL		;GET DEST. POINTER
	POP	DPH		;
	MOVX	@DPTR,A		;AND WRITE DIGIT
	INC	DPTR		;
	PUSH	DPH		;
	PUSH	DPL		;STORE DEST. POINTER
	DJNZ	R0,DEC9		;
	POP	DPL		;CLEAR STACK
	POP	DPH		;
	MOV	A,#' '		;AND WRITE A SP IN LAST POS
	MOVX	@DPTR,A		;
	MOV	R0,#CURSOR	;
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	XCH	A,R1		;
	CLR	C		;
	SUBB	A,R1		;
	JNC	DEC10		;
	MOVX	A,@R0		;
	DEC	A		;
	MOVX	@R0,A		;
	JNZ	DEC10		;
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW PUT IN A . AT THE CURSOR POSITION AND SHIFT ALL DIGITS TO
; THE LEFT ONE POSITION TO THE LEFT.

DEC10:	MOV	DPH,R2		;POINTER -> FIRST DIGIT IN SHARE
	MOV	DPL,R3		;
	MOV	R0,#CURSOR	;GET CURSOR
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	MOV	R0,A		;
	MOV	R1,#7H		;
DEC11:	DJNZ	R0,DEC12	;GO THROUGH SHARE UNTIL CURSOR POS
	LJMP	DEC13		;
DEC12:	DEC	R1		;
	INC	DPTR		;
	LJMP	DEC11		;

; NOW POINTER -> DIGIT THAT CURSOR POINTS AT

DEC13:	MOVX	A,@DPTR		;GET DIGIT
	MOV	B,A		;
	MOV	A,#'.'		;AND WRITE . INSTEAD
	MOVX	@DPTR,A		;
	INC	DPTR		;
	DEC	R1		;
DEC14:	MOVX	A,@DPTR		;
	MOV	R0,A		;NOW ROTATE ALL LEFT CHARACTERS
	MOV	A,B		;
	MOVX	@DPTR,A		;
	MOV	B,R0		;
	INC	DPTR		;
	DJNZ	R1,DEC14	;
	JB	ZERO,DEC15	;
	MOV	R0,#CURSOR	;GET CURSOR
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;
	MOVX	@R0,A		;
	CLR	C		;
	SUBB	A,#8H		;
	JC	DEC15		;
	MOV	A,#1H		;
	MOVX	@R0,A		;

; THIS BUFFER MUST BE COPIED AND THE NEW ONE SEND TO DISPLAY TASK

DEC15:	MOV	R0,#MAXDIG	;
	MOV	P2,#RESOFF	;
	MOV	A,#7H		;
	MOVX	@R0,A		;
	JNB	ZERO,DEC16	;JUMP IF NOT IN ZERO MODE
	MOV	R0,#DIGNO	;OTHERWISE GET DIGITNO
	MOVX	A,@R0		;
	JNZ	DEC16		;JUMP IF ALREADY DIGITS
	INC	A		;OTHERWISE INCREMENT DIGITNO
	MOVX	@R0,A		;
DEC16:	LJMP	DISPLAY_SHARE	;WRITE NEW SHARE

$EJECT
;**************************************************************************
;
;	NAME:		CHANGE_RETURN
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "RETURN"
;			KEY IS ACTIVATED.
;
;***************************************************************************

CHANGE_RETURN:
	JNB	DATE_COMPONENT,RET0	;JUMP IF NOT DATE COMPONENT
	JMP	RIA7		;OTHERWISE JUMP
	CLR 	ZERO		;EXECUTE RCONF ROUTINE
	JB	EMPTY,RET1	;IF THE BUFFER IS EMPTY THEN DO NOTHING
	CALL	STORE_SHARE	;
	SETB	EMPTY		;
RET1:	MOV	R0,#CUCOL	;THE CURRENT COLNO. IS INCREMENTED
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;AND IF COLNO > MAX_COLNO THEN
	MOVX	@R0,A		;CURRENT COLNO := 1
	MOV	R7,A		;
	MOV	R0,#COLNO	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,R7		;
	JNC	RET2		;
	MOV	R0,#CUCOL	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
	MOV	R0,#CUROW	;CURRENT ROWNO IS INCREMENTED
	MOVX	A,@R0		;
	INC	A		;
	MOVX	@R0,A		;
	MOV	R7,A		;IF CURRENT ROWNO > MAX ROWNO
	MOV	R0,#ROWNO	;THEN CURRENT ROWNO = 1
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,R7		;
	JNC	RET2		;
	MOV	R0,#CUROW	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
RET2:	MOV	R0,#CURSOR	;CURSOR := LEAST SIGNIFICANT
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW A NEW SHARE MUST BE FETCHED FROM STORE

	LJMP	GET_SHARE	;GET SHARE AND WRITE IT

$EJECT
;******************************************************************************
;
;	NAME:		COPY_12_ROUT
;
;	DESCRIPTION:	THIS ROUTINE IS EXECUTED WHEN THE SHIFT AND 1 KEYS
;			IS ACTIVATED AT THE SAME TIME. IT COPIES THE SHARES
;			IN COLUMN 1 TO COLUMN 2.
;
;*****************************************************************************

COPY_12_ROUT:
	MOV	R0,#SOURCE_COL	;INDICATE WHICH COLUMN TO COPY FROM
	MOV	P2,#RESOFF	;
	MOV	A,#1H		;COPY FROM COLUMN 1
	MOVX	@R0,A		;
	MOV	R0,#DEST_COL	;INDICATE WHICH COLUMN TO COPY TO
	MOV	A,#2H		;COPY TO COLUMN 2
	MOVX	@R0,A		;
	LJMP	COPY_COLUMN	;JUMP TO COPY ROUTINE

$EJECT
;**************************************************************************
;
;	NAME:		COPY_21_ROUT
;
;	DESCRIPTION:	THIS ROUTINE IS EXECUTED WHEN THE SHIFT AND 2 KEYS
;			IS ACTIVATED AT THE SAME TIME. IT COPIES THE SHARES
;			IN COLUMN 2 TO COLUMN 1
;
;**************************************************************************

COPY_21_ROUT:
	MOV	R0,#SOURCE_COL	;INDICATE WHICH COLUMN TO COPY FROM
	MOV	P2,#RESOFF	;
	MOV	A,#2H		;COPY FROM COLUMN 2
	MOVX	@R0,A		;
	MOV	R0,#DEST_COL	;INDICATE WHICH COLUMN TO COPY TO
	MOV	A,#1H		;COPY TO COLUMN 1
	MOVX	@R0,A		;
	SETB	COLUMN_2	;INDICATE CURSOR IN COLUMN 2
	LJMP	COPY_COLUMN	;JUMP TO COPY ROUTINE

$EJECT
;**************************************************************************
;
;	NAME:		COPY_COLUMN
;
;	DESCRIPTION:	THIS ROUTINE COPIES THE SHARES IN ONE COLUMN TO
;			ANOTHER COLUMN. THE COLUMNS MUST BE EITHER COL
;			1 OR COL 2 AND ROUTINE ONLY EXECUTES IF 2 COLUMNS
;			AT THIS TYPE.
;
;	INPUT:		SOURCE COLUMNNO IN RESERVED BYTE SOURCE_COL
;			DEST COLUMNNO IN RESERVED BYTE DEST_COL
;
;***************************************************************************

COPY_COLUMN:
	MOV	R0,#COLNO	;READ NO OF COLUMNS AT THIS TYPE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;FROM RESERVED BYTE
	MOV	B,A		;AND STORE
	MOV	A,#1H		;
	CLR	C		;IS NO OF COLUMNS > 1
	SUBB	A,B		;
	JC	CO_CO2		;JUMP IF IT IS
	LJMP	INPUT_DELAY	;OTHERWISE DO NOTHING
CO_CO2:	JB	EMPTY,CO_CO3	;JUMP IN NO BUFFER OCCUPIED IN SYSTEM
	CALL	STORE_SHARE	;OTHERWISE STORE OCCUPIED BUFFER
	SETB	EMPTY		;
CO_CO3:	MOV	R0,#DATE_COLUMN	;POINT AT STORE FOR DATE COMP POS
	MOVX	A,@R0		;READ COLUMN SPEC
	JZ	CO_CO3A		;JUMP IF NO DATE COMPONENT
	INC	R0		;OTHERWISE POINT AT NEXT
	MOVX	A,@R0		;READ COLUMN SPEC
	JZ	CO_CO3A		;JUMP IF NO DATE COMPONENT
	MOV	R0,#CUROW	;OTHERWISE POINT AT STORE FOR CURRENT ROW
	CLR	A		;INDICATE ROW 0
	MOVX	@R0,A		;AND STORE
	JMP	CO_CO4		;COPY COLUMN
CO_CO3A:MOV	R0,#CUROW	;SET CURRENT ROWNO TO 1
	MOV	A,#1H		;
	MOVX	@R0,A		;

; NOW TRY TO GET AN EMPTY BUFFER

CO_CO4:	CALL	GET_SK_BH	;GET AN EMPTY BUFFER
	MOV	BYTECNT,#3H	;PREPAIRE TO GET SHARE FROM SOURCE COLUMN
	MOV	COMM_BYTE,#DOS	;COMMAND = DEMAND ONE SHARE
	MOV	R0,#CUTYPE	;GET CURRENT TYPENO
	MOV	P2,#RESOFF	;FROM RESERVED BYTE
	MOVX	A,@R0		;
	MOV	BUFFER_AREA,A	;AND WRITE INTO BUFFER BYTES
	MOV	R0,#CUROW	;GET CURRENT ROWNO
	MOVX	A,@R0		;FROM RESERVED BYTES
	MOV	BUFFER_AREA+1,A	;AND WRITE INTO BUFFER BYTES
	MOV	R0,#SOURCE_COL	;GET SOURCE COLUMNNO
	MOVX	A,@R0		;FROM RESERVED BYTES
	MOV	BUFFER_AREA+2,A	;AND WRITE INTO BUFFER BYTES
	CALL	SEND_BUFFER	;SEND DEMAND BUFFER

; NOW WAIT FOR BUFFER TO RETURN

	%VENT	(200,INSEM)	;WAIT FORV BUFFER TO RETURN
	MOV	PSW,#0H		;
	MOV	A,#INPUTF		;LOOK IN FULL QUEUE
	CALL	DEQ		;LOOK IN QUEUE IF ANY BUFFER
	JNZ	CO_CO7		;JUMP IF ONE FOUND
	LJMP	CO_CO9		;OTHERWISE TRY NEXT LINE

; HERE IF FULL BUFFER FOUND

CO_CO7:	CALL	GET_BUFFER	;READ BUFFER_CONTENT
	MOV	A,COMM_BYTE	;AND LOOK AT COMMAND
	XRL	A,#ROS		;IS COMMAND = RETURN ONE SHARE
	JZ	CO_CO8		;JUMP IF IT IS
	CALL	CLRBUF		;
	LJMP	CO_CO9		;OTHERWISE TRY NEXT LINE

; HERE IF BUFFER CONTAIN SHARE FROM SOURCE COLUMN

CO_CO8:	MOV	R0,#DEST_COL	;GET NO OF DEST COLUMN
	MOV	P2,#RESOFF	;FROM RESERVED BYTE
	MOVX	A,@R0		;
	MOV	BUFFER_AREA+2,A	;AND WRITE INTO BUFFER BYTES
	MOV	COMM_BYTE,#WOS	;COMMAND = WRITE ONE SHARE
	CALL	SEND_BUFFER	;SEND BUFFER

; HERE WHEN ONE LINE HAS BEEN COPIED

CO_CO9:	MOV	R0,#CUROW	;GET CURRENT LINENO
	MOV	P2,#RESOFF	;FROM RESERVED BYTE
	MOVX	A,@R0		;
	INC	A		;AND INCREMENT IT
	MOVX	@R0,A		;STORE AGAIN
	MOV	B,A		;STORE IN B TOO
	MOV	R0,#ROWNO	;GET MAX NO OF LINES
	MOVX	A,@R0		;
	CLR	C		;IS NEW LINENO > MAX NO OF LINES
	SUBB	A,B		;
	JC	CO_CO10		;JUMP IF IT IS
	LJMP	CO_CO4		;OTHERWISE CONTINUE WITH NEXT LINE

; HERE WHEN ALL LINES COPIED

CO_CO10:MOV	R0,#CUTYPE	;GET CURRENT TYPENO
	MOVX	A,@R0		;FROM RESERVED BYTE
	DEC	A		;AND DECREMENT	
	MOVX	@R0,A		;
	LJMP	CHANGE_ROUT	;INITIATE TO THIS TYPE AGAIN

$EJECT
;*************************************************************************
;
;	NAME:		NO_VAL_ROUTINE
;
;	DESCRIPTION:	THIS FUNCTION IS EXECUTED WHEN THE "SHIFT 3"
;			KEY IS ACTIVATED. IT DELETES BUFFER CONTENT
;			AND WRITES A - IN DISPLAY.
;
;*************************************************************************

NO_VAL_ROUTINE:
	JNB	DATE_COMPONENT,N_V_R1	;JUMP IF NOT DATE COMPONENT
	JMP	INPUT_DELAY	;
N_V_R1:	CLR 	ZERO		;
	MOV	R0,#SKPH	;POINTER TO BUFFER
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;FROM RESERVED BYTES
	MOV	DPH,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	DPL,A		;POINTER -> LINK.H IN BH
	INC	DPTR		;
	INC	DPTR		;POINTER -> BUFADR.H IN BH
	MOVX	A,@DPTR		;
	MOV	R2,A		;THE START ADR OF BUFFER IS
	INC	DPTR		;
	MOVX	A,@DPTR		;STORED IN R4 AND R5
	MOV	R3,A		;
	SETB	EMPTY		;
	MOV	DPH,R2		;POINTER -> START OF BUFFER
	MOV	DPL,R3		;
	INC	DPTR		;
	INC	DPTR		;
	INC	DPTR		;POINTER -> FIRST DIGIT IN SHARE
	MOV	A,#'-'		;LEAST SIGN. DIGIT MUST BE -
	MOVX	@DPTR,A		;
	INC	DPTR		;
	MOV	R1,#6H		;
	MOV	A,#' '		;
N_V_R3:	MOVX	@DPTR,A		;AND THE LAST DIGITS MUST BE SP
	INC	DPTR		;
	DJNZ	R1,N_V_R3	;
	MOV	R0,#CURSOR	;THE CURSOR = 1
	MOV	P2,#RESOFF	;
	MOV	A,#1H		;
	MOVX	@R0,A		;
	MOV	R0,#DIGNO	;
	CLR	A		;
	MOVX	@R0,A		;
	CLR	EMPTY		;
	SETB	ZERO		;

; THIS BUFFER MUST BE COPIED AND THE NEW ONE SEND TO DISPLAY TASK

	LJMP	DISPLAY_SHARE	;WRITE NEW SHARE

$EJECT
;**************************************************************************
;
;	NAME:		CHANGE_UPDATE
;
;	DESCRIPTION:	THIS ROUTINE IS EXECUTED WHEN THE UPDATE KEY
;			IS ACTIVATED. IT SENDS AN UPDATE MESSAGE TO
;			BOARD TASK.
;
;***************************************************************************

CHANGE_UPDATE:
	JNB 	BUSY_UPDATING,UPD1	;JUMP IF NOT BUSY
	LJMP	INPUT_DELAY	;OTHERWISE DO NOTHING
UPD1:	SETB	BUSY_UPDATING	;INDICATE NOW BUSY
	MOV	DPTR,#EDS_STATUS;POINT AT EDS SYSTEM STATUS BYTE
	CLR	A		;CLEAR STATUS
	SETB	UPDATE_MODE	;AND INDICATE UPDATE MODE
	MOVX	@DPTR,A		;STORE STATUS
	CLR	ZERO		;
	JB	EMPTY,UPD2	;IF ANY BUFFER STORED IN TASK
	CALL	STORE_SHARE	;THEN SEND IT TO STORE 
	SETB	EMPTY		;
	%TVENT	(2)		;

UPD2:	CALL	GET_SK_BH	;GET AN EMPTY BUFFER TO SEND UPDATE MESSAGE IN

; NOW AN EMPTY BUFFER IS FOUND

	MOV	BYTECNT,#0H	;INITIATE BYTES FOR SENDING BUFFER
	MOV	COMM_BYTE,#UP	;
	CALL	SEND_BUFFER	;
	MOV	SERKEY_STATUS,#0H	;
	LJMP	INPUT_DELAY	;

$EJECT
; THIS ROUTINE GIVES CPU TO OTHER TASKS AND THEN LOOKS FOR INPUT AGAIN

INPUT_DELAY:
	%SSEND	(INSEM)		;
	%SVENT	(INSEM)		;GIVE CPU FREE
	MOV	PSW,#0H		;
	LJMP	EDS_INPUT	;LOOK FOR INPUT AGAIN

$EJECT
;************************************************************************
;
;	NAME:		DIGIT
;
;	DESCRIPTION:	THIS ROUTINE IS EXECUTED WHEN ONE OF THE DIGIT
;			KEYS IS ACTIVATED.  IT PUTS A DIGIT INTO SHARE
;			ON THE CURSORS POSITION.
;
;*************************************************************************

CHANGE_DIGIT:
	MOV	B,A		;STORE ACTIVE DIGIT IN B
	CALL	DIGDEF		;
	MOV	R0,#SKPH	;GET POINTER TO BUFFER WITH SHARE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;FROM RESERVED BYTES
	MOV	DPH,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	DPL,A		;
	INC	DPTR		;
	INC	DPTR		;POINTER -> BUFADR.H
	MOVX	A,@DPTR		;
	MOV	R4,A		;THE START ADR OF BUFFER
	INC	DPTR		;IS STORED IN R4 AND R5
	MOVX	A,@DPTR		;
	MOV	R5,A		;
	MOV	DPH,R4		;POINTER -> START OF BUFFER
	MOV	DPL,R5		;
	INC	DPTR		;
	INC	DPTR		;
	INC	DPTR		;POINTER -> LEAST SIGN. DIG IN SHARE

; HERE IF DIGIT MUST BE PUT IN THE CURSOR POS

	MOV	R0,#CURSOR	;
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;GET CURSOR
	MOV	R4,A		;
	JNB	DATE_COMPONENT,DIG0	;JUMP IF NOT DATE COMPONENT
	JMP	DATE_DIGIT	;
DIG0:	DEC	A		;DECREMENT CURSOR POS
	JNZ	DIG1		;
	JB	ZERO,DIG_ZERO	;JUMP IF ZER FLAG
DIG1:	MOV	R0,A		;AND STORE IN R0
	JZ	DIG5		;IF NEW POS = 0 THEN JUMP
	MOV	R1,#MAXDIG	;GET MAX NO OF DIGITS
	MOVX	A,@R1		;
	CLR	C		;
	SUBB	A,R4		;IS CURSOR POS > MAX POS
	JNC	DIG2		;JUMP IF NOT
	LJMP	INPUT_DELAY	;OTHERWISE DO NOTHING
DIG2:	DJNZ	R0,DIG3		;COUNT THROUGH SHARE UNTIL 
	JMP	DIG4		;
DIG3:	INC	DPTR		;CURSOR POSITION
	JMP	DIG2		;

; HERE WHEN POS LESS THAN CURSOR POS REACHED

DIG4:	MOVX	A,@DPTR		;READ DIGIT
	XRL	A,#' '		;IS DIGIT = SPACE
	INC	DPTR		;
	JNZ	DIG5		;JUMP IF NOT
	LJMP	INPUT_DELAY	;OTHERWISE DO NOTHING

; NOW POINTER = DIGIT THE CURSOR POINTS AT

DIG5:	CLR	ZERO		;
	MOVX	A,@DPTR		;GET THE CHARACTER TO WRITE OVER
	XRL	A,#'.'		;IF IT IS . THEN THE MOST SIGNIFICANT
	JNZ	DIG6		;IN A FULL SHARE MUST BE CLEARED
	PUSH  	DPH		;
	PUSH	DPL		;
	MOV	R0,#SKPH	;THAT MEANS THAT BYTE 10 IN BUFFER
	MOV	P2,#RESOFF	;MUST BE OVERWRITTEN WITH SP.
	MOVX	A,@R0		;
	MOV	DPH,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	DPL,A		;POINTER -> LINK.H IN BH
	INC	DPTR		;
	INC	DPTR		;POINTER -> BUFADR.H
	MOVX	A,@DPTR		;
	MOV	R4,A		;
	INC	DPTR		;
	MOVX	A,@DPTR		;
	MOV	DPL,A		;
	MOV	DPH,R4		;POINTER -> START OF BUFFER
	MOV	A,#9H		;ADD 9 TO GET TO LAST BUTE IN BUFFER
	ADD	A,DPL		;
	MOV	DPL,A		;
	CLR	A		;
	ADDC	A,DPH		;
	MOV	DPH,A		;
	MOV	A,#' '		;WRITE SPACE
	MOVX	@DPTR,A		;
	POP	DPL		;
	POP	DPH		;
DIG6:	MOV	A,B		;GET DIGIT
	MOVX	@DPTR,A		;AND STORE IN BUFFER
	MOV	R0,#MAXDIG	;GET MAX CURSOR POSITION
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;
	MOV	R1,A		;
	MOV	R0,#CURSOR	;GET CURSOR
	MOVX	A,@R0		;
	INC	A		;THE CURSOR IS INCREMENTED
	MOVX	@R0,A		;
	CLR	C		;
	SUBB	A,R1		;IF CURSOR > MAX CURSOR
	JC	DIG7		;THEN CURSOR = 1
	MOV	A,#1H		;
	MOVX	@R0,A		;
DIG7:	CALL	DIGDEF		;
	JMP	DISPLAY_SHARE	;WRITE NEW SHARE

; HERE IF DIGIT MUST BE PUT IN 0 POSITION AND OTHER DIGITS
; SHIFTED ONE POSITION TO THE LEFT.

DIG_ZERO:
	MOV	R0,#DIGNO	;GET DIGITNO IN SHARE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;
	MOVX	@R0,A		;
	DEC	A		;
	JZ	DIG_Z1		;
	INC	A		;
	CLR	C		;IF DIGITNO > MAX DIGITNO
	SUBB	A,#7H		;THEN DO NOTHING
	JNC	DIG_Z3		;
	MOV	R1,#7H		;
	MOV	A,B		;GET DIGIT
	MOV	B,A		;
	LJMP	DIG_Z2		;
DIG_Z1:	MOV	A,B		;
	MOVX	@DPTR,A		;
	LJMP	DIG_Z3		;
DIG_Z2:	MOVX	A,@DPTR		;ALL OTHER DIGITS IN SHARE
	MOV	R0,A		;MUST BE SHIFTED ONE POS
	MOV	A,B		;TO THE LEFT
	MOVX	@DPTR,A		;
	MOV	B,R0		;
	INC	DPTR		;
	DJNZ	R1,DIG_Z2	;

; NOW SEND SHARE TO DISPLAY

DIG_Z3:	LJMP	DISPLAY_SHARE	;WRITE NEW SHARE

; HERE WHEN DIGIT TYPED IN CONFIGURATION MODE

CONF_DIGIT:
	CLR	C		;
	SUBB	A,#'0'		;MAKE VALUE DECIMAL
	MOV	R1,A		;
	MOV	R0,#CONF_INPUT	;GET FURTHER TYPED NO
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	JNB	ACC.7,C_DIG1	;
	CLR	A		;
C_DIG1:	MOV	B,#0AH		;
	MUL	AB		;MULTIPLICATE OLD NO BY 10
	ADD	A,R1		;AND ADD NEW NO
	MOVX	@R0,A		;
	XCH	A,B		;
	JNZ	C_DIG2		;IF NO > 255 THEN ERROR
	JC	C_DIG2		;
	MOV	R0,#MAX		;
	MOVX	A,@R0		;GET MAX ALLOVED VALUE
	CLR	C		;
	SUBB	A,B		;AND COMPAIRE WITH ACTUAL VALUE
	JC	C_DIG2		;
	LJMP	RCONF		;

; HERE IF VALUE TYPED TOO LARGE

C_DIG2:	MOV	A,#ERR5		;
	LJMP	CONER		;

; HERE IF DIGIT INTO DATE COMPONENT

DATE_DIGIT:
	MOV	A,#8		;GET NO OF DIGITS
	CLR	C		;
	SUBB	A,R4		;SUBTRACT CURSOR POSITION
	ADD	A,DPL		;AND ADD OFFSET TO POINTER
	MOV	DPL,A		;
	JNC	D_DIG1		;JUMP IF NOT OVERFLOW
	INC	DPH		;INCREMENT HIGH BYTE POINTER
D_DIG1:	MOV	A,B		;GET NEW DIGIT
	MOVX	@DPTR,A		;AND STORE IN BUFFER
	JMP	DISPLAY_SHARE	;AND WRITE SHARE
 
$EJECT
;************************************************************************
;
;	NAME:		CONFIG_ROUT
;
;	DESCRIPTION:	THIS ROUTINE IS ACTIVATED WHEN THE CONFIG KEY
;			IS ACTIVATED. IT INITIATES SYSTEM TO CONFIGURATION
;			MODE.
;
;*************************************************************************

CONFIG_ROUT:
	MOV	DPTR,#EDS_STATUS;POINT AT SYSTEM STATUS BYTE
	MOVX	A,@DPTR		;READ STATUS
	JNB	CONFIG_MODE,CONFIG1	;JUMP IF NOT ALREADY IN CONFIG MODE
	LJMP	INPUT_DELAY	;
CONFIG1:CLR	A		;CLEAR STATUS
	SETB	CONFIG_MODE	;AND INDICATE CONFIG MODE NOW
	MOVX	@DPTR,A		;STORE STATUS AGAIN
	SETB	BUSY_ROUTINE	;INDICATE BUSY WITH NEW ROUTINE
	JB	EMPTY,CONFIG2	;IF A BUFFER IS STORED IN THE TASK
	CALL	STORE_SHARE	;THEN SEND IT TO THE STORE
	SETB	EMPTY		;
	%TVENT	(2)		;
CONFIG2:LJMP	CONF		;GO TO CONFIGURATION MODE

$EJECT
;************************************************************************
;
;	NAME:		DIGDEF
;
;	DESCRIPTION:	THIS ROUTINE WORKS ON THE BUFFER STORED IN THE
;			KEYBOARD OR SERIAL TASK. POINTER TO BH IN SKPH
;			AND SKPL. IT CALCULATES HOW MANY BYTES USED TO
;			SHARE IN BUFFER AND STORES RESULT IN MAXDIG.
;
;	OUTPUT:		MAXDIG = 6 IF NO . IN SHARE
;			MAXDIG = 7 IF . IN SHARE
;
;**************************************************************************

DIGDEF:	MOV	R0,#SKPH	;
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	MOV	DPH,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	DPL,A		;
	INC	DPTR		;
	INC	DPTR		;POINTER -> BUFADR.H
	MOVX	A,@DPTR		;
	PUSH	ACC		;
	INC	DPTR		;
	MOVX	A,@DPTR		;
	MOV	DPL,A		;
	POP	ACC		;
	MOV	DPH,A		;POINTER -> START OF BUFFER
	INC	DPTR		;
	INC	DPTR		;
	INC	DPTR		;POINTER -> FIRST DIGIT IN SHARE
	MOV	R0,#7H		;
DIGDEF1:MOVX	A,@DPTR		;GET DIGIT
	XRL	A,#'.'		;AND COMPAIRE WITH .
	JZ	DIGDEF2		;IF EQUAL THEN JUMP
	INC	DPTR		;
	DJNZ	R0,DIGDEF1	;
	CLR	C		;IF NO . IN SHARE THEN WRITE
	MOV	A,DPL		;SP IN BYTE 7 IN BUFFER
	SUBB	A,#1H		;
	MOV	DPL,A		;
	MOV	A,DPH		;
	SUBB	A,#0H		;
	MOV	DPH,A		;
	MOV	A,#' '		;
	MOVX	@DPTR,A		;
	MOV	R0,#MAXDIG	;
	MOV	P2,#RESOFF	;
	MOV	A,#6H		;
	MOVX	@R0,A		;
	RET			;

DIGDEF2:MOV	R0,#MAXDIG	;
	MOV	P2,#RESOFF	;
	MOV	A,#7H		;
	MOVX	@R0,A		;
	RET			;

$EJECT
;*************************************************************************
;
;	NAME:		STORE_SHARE
;
;	DESCRIPTION:	THIS IS A ROUTINE THAT SENDS A SHARE TO THE
;			STORE TASK. THE SHARE IS IN  THE BUFFER WHO'S
;			BUFFERHEAD START ADR IS IN SKPH AND SKPL.
;
;*************************************************************************

STORE_SHARE:
	MOV	R0,#SKPH	;GET POINTER TO BUFFERHEAD
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	MOV	R2,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	R3,A		;POINTER -> LINK.H IN BH
	CALL	GET_BUFFER	;
	MOV	COMM_BYTE,#WOS	;
	CALL	SEND_BUFFER	;
	RET			;

$EJECT
;***************************************************************************
;
;	NAME:		GET_SHARE
;
;	DESCRIPTION:	THIS IS A ROUTINE THAT DEMANDS FOR A NEW SHARE FROM
;			STORE TASK. WHEN THE NEW SHARE COMES IN A BUFFER THE
;			POINTER TO BH IS STORED IN SKPH AND SKPL. THE SHARE
;			IN BUFFER IS EITHER SEND TO THE DISPLAY TASK OR TO
;			THE SERIAL TASK.
;
;****************************************************************************

GET_SHARE:
	CLR	DATE_COMPONENT	;INDICATE NOT DATE COMPONENT
	CALL	GET_SK_BH	;GET AN EMPTY BUFFER

; HERE WHEN AN EMPTY BUFFER IS FOUND

GSH1:	MOV	BYTECNT,#3H	;
	MOV	COMM_BYTE,#DOS	;
	MOV	R0,#CUTYPE	;
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;GET CURRENT TYPE AND 
	MOV	BUFFER_AREA,A	;WRITE IT INTO BUFFER
	MOV	R0,#CUROW	;GET CURRENT ROWNO AND
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	JNZ	GSH1A		;JUMP IF NOT DATE COMPONENT
	SETB	DATE_COMPONENT	;
GSH1A:	MOV	BUFFER_AREA+1,A	;WRITE IT INTO BUFFER
	MOV	R0,#CUCOL	;
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;GET CURRENT COLUMNNO AND
	MOV	BUFFER_AREA+2,A	;WRITE IT INTO BUFFER
	CALL	SEND_BUFFER	;SEND BUFFER TO COMMAND TASK
GSH2:	%VENT	(250,INSEM)	;
	MOV	PSW,#0H		;
	MOV	A,#INPUTF	;
	CALL	DEQ		;
	MOV	R1,A		;STORE QUEUE SELECTOR
	JNZ	GSH3		;
	LJMP	INPUT_DELAY	;
GSH3:	MOV	R0,#SKPH	;STORE POINTER TO BUFFER IN RESERVED BYTES
	MOV	P2,#RESOFF	;
	MOV	A,R2		;
	MOVX	@R0,A		;
	MOV	R0,#SKPL	;
	MOV	A,R3		;
	MOVX	@R0,A		;
	CALL	GET_BUFFER	;
	MOV	A,COMM_BYTE	;
	XRL	A,#ROS		;IF COMMAND <> RETURN ONE SHARE THEN DO NOT.
	JZ	GSH4		;
	MOV	A,R1		;PUT BUFFER BACK TO QUEUE IT CAME FROM
	CALL	ENQ		;
	LJMP	GSH2		;

; NOW A NEW SHARE HAS BEEN FETCHED FROM STORE

GSH4:	MOV	A,BUFFER_AREA+3	;FIND OUT IF SHARE = 0
	XRL	A,#'0'		;THEN LSD = 0
	JZ	GSH5		;JUMP IF IT IS
	MOV	A,BUFFER_AREA+3	;GETR LSD AGAIN
	XRL	A,#'-'		;IS LSD = '-'
	JNZ	DISPLAY_SHARE	;JUMP IF NOT
GSH5:	MOV	R0,#BUFFER_AREA+4	;
	MOV	R1,#6		;COUNTER FOR CHECK
GSH6:	MOV	A,@R0		;THE REST OF THE DIGITS MUST THEN BE ' '
	XRL	A,#' '		;ARE THEY?
	JNZ	DISPLAY_SHARE	;JUMP IF NOT
	INC	R0		;
	DJNZ	R1,GSH6		;

; HERE IS SHARE = 0

	SETB	ZERO		;INDICATE ZERO MODE
	MOV	R0,#DIGNO	;ADJUST COUNTER
	MOV	P2,#RESOFF	;
	CLR	A		;
	MOVX	@R0,A		;
	JNB	DATE_COMPONENT,DISPLAY_SHARE	;JUMP IF NOT DATE COMP.
GSH7:	MOV	R3,#3		;COUNTER TO NO OF 00 BLOCKS
	JMP	GSH9		;
GSH8:	MOV	A,#'.'		;READY TO WRITE <.>
	MOVX	@DPTR,A		;WRITE TO BUFFER
	INC	DPTR		;
GSH9:	MOV	R2,#2		;COUNTER TO NO OF 0 IN BLOCK
	MOV	A,#'0'		;READY TO WRITE 0
GSH10:	MOVX	@DPTR,A		;WRITE TO BUFFER
	INC	DPTR		;POINT AT NEXT
	DJNZ	R2,GSH10	;WRITE WHOLE BLOCK
	DJNZ	R3,GSH8		;WRITE ALL BLOCKS

; THIS BUFFER MUST BE COPIED AND THE NEW ONE SEND TO DISPLAY TASK

DISPLAY_SHARE:
	MOV	A,SERKEY_STATUS	;
	DEC	A		;
	JNZ	SERIAL_WRITE	;
	CALL	DIGDEF		;
	MOV	A,#INPUTE	;GET AN EMPTY BUFFER
	CALL	DEQ		;
	JZ	GSHD1		;
	LJMP	GSHD2		;
GSHD1:	%SSEND	(INSEM)		;CONTINUE UNTIL AN EMPTY BUFFER IS FOUND
	%SVENT	(INSEM)		;
	MOV	PSW,#0H		;
	LJMP	DISPLAY_SHARE	;

; NOW AN EMPTY BUFFER IS FOUND

GSHD2:	MOV	R0,#SKPH	;GET POINTER TO SOURCE BUFFER
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;FROM RESERVED BYTES
	MOV	R4,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	R5,A		;
	CALL	COPY		;COPY BUFFER
	CALL	GET_BUFFER	;
	MOV	COMM_BYTE,#WSM	;
	MOV	R0,#CURSOR	;GET CURSOR POS
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	JB	DATE_COMPONENT,GSHD7	;JUMP IF DATE COMPONENT
 	MOV	R1,#BUFFER_AREA+3	;
	MOV	R0,A		;
GSHD3:	DJNZ	R0,GSHD4	;POINTER -> POS IN BUFFER
	LJMP	GSHD5		;
GSHD4:	INC	R1		;
	LJMP	GSHD3		;
GSHD5:	MOV	A,@R1		;IF CURSOR POSITION REACHED 
	SETB	ACC.7		;THEN SET BIT TO INDICATE CURSOR POS
	MOV	@R1,A		;

; NOW DEST BUFFER MUST BE SEND TO COMMAND TASK

	CALL	SEND_BUFFER	;
	CLR	EMPTY		;
	LJMP	INPUT_DELAY	;

; HERE IF DATE COMPONENT

GSHD7:	MOV	R0,A		;GET CURSOR POSITION
	MOV	R1,#BUFFER_AREA+10	;POINT AT MSB
GSHD8:	DJNZ	R0,GSHD9	;
	JMP	GSHD5		;JUMP AT CURSOR POSITION
GSHD9:	DEC	R1		;POINT AT NEXT
	JMP	GSHD8		;TRY NEXT

; HERE WHEN THIS ROUTINE IS USED BY THE SERIAL TASK

SERIAL_WRITE:
	CLR	EMPTY		;
	JNB	DATE_COMPONENT,SE_WR0	;JUMP IF NOT DATE COMPONENT
	JMP	SE_WR6A		;WRITE DATE COMP
SE_WR0:	MOV	R0,#CUROW	;GET ROWNO TO WRITE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,SCROLL	;SUBTRACT NO OF LINES SCROLLED
	JC	SE_WR1		;JUMP IF NEEDED TO SCROLL MORE LINES DOWN
	JZ	SE_WR2		;JUMP IF NEEDED TO SCROLL ONE LINE DOWN
	LJMP	SE_WR6		;JUMP IF NOT NEEDED TO SCROLL DOWN

; HERE WHEN NEEDED TO SCROLL MORE THAN ONE LINE DOWN

SE_WR1:	MOV	A,SCROLL	;GET NO OF LINES TO SCROLL
	MOV	R0,#NODIG	;AND STORE IN RESERVED BYTE
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;
	CLR	C		;IS NO > 20
	SUBB	A,#21		;
	JC	SE_WR3		;JUMP IF NOT
	MOV	A,#20		;OTHERWISE JUST 20 LINES
	MOVX	@R0,A		;
	LJMP	SE_WR3		;

; HERE WHEN ONE LINE MUST BE INSERTED AT THE TOP OF SCREEN

SE_WR2:	MOV	A,#1H		;NO OF LINES TO SCROLL DOWN
	MOV	R0,#NODIG	;STORE NO IN RESERVED BYTE
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;

; NOW SCROLL SCREEN NO OF LINES DOWN

SE_WR3:	CALL	GET_TRANS	;GET TRANSMITTER BUFFER
	MOV	R0,#6H		;
	MOV	R1,#0H		;INSERT ONE LINE AT LINE NO 5 ON SCREEN
	CALL	CURSOR_POS	;INITIATE CURSOR POSITION
	MOV	A,#ESC		;
	MOVX	@DPTR,A		;A LINE IS INSERTED BY A ESCAPE SEQUENSE
	INC	DPTR		;
	MOV	A,#5BH		;SEQUENSE = ESC Æ NO L
	MOVX	@DPTR,A		;
	INC	DPTR		;
	MOV	R0,#NODIG	;GET NO OF LINES TO SCROLL
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	MOV	B,#0AH		;
	DIV	AB		;IF NO > 9 THEN WRITW TWO CHARACTERS
	JZ	SE_WR4		;
	ADD	A,#30H		;
	MOVX	@DPTR,A		;
	INC	DPTR		;
SE_WR4:	MOV	A,B		;GET LEAST SIGNIFICANT CHARACTER
	ADD	A,#30H		;
	MOVX	@DPTR,A		;
	INC	DPTR		;
	MOV	A,#'L'		;
	MOVX	@DPTR,A		;
	INC	DPTR		;
	CLR	A		;
	MOVX	@DPTR,A		;FINALLY WRITE A 0 TO INDICATE END OF MESSAGE
	SETB	TI		;
	MOV	R0,#NODIG	;GET NO OF LINES SCROLLED
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	DEC	A		;
	JNZ	SE_WR5		;JUMP IF SCROLLED MORE THAN ONE LINE
	DEC	SCROLL		;
	CALL	WRITE_LINE	;WRITE THE NEW LINE
	LJMP	SE_WR6A		;JUMP AND POSITION CURSOR

; HERE WHEN NEEDED TO INSERT MORE THAN ONE LINE

SE_WR5:	MOV	SCROLL,#0H	;
	CALL	WRITE_LINE	;WRITE A LINE ON SCREEN
	MOV	R0,#CUROW	;GET CURRENT ROWNO
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	INC	A		;AND INCREMENT IT
	MOVX	@R0,A		;AND STORE IT AGAIN
	MOV	R0,#NODIG	;GET NO OF LINES TO INSERT
	MOVX	A,@R0		;
	DEC	A		;AND DECREMENT	
	MOVX	@R0,A		;
	JNZ	SE_WR5		;CONTINUE UNTIL ALL LINES WRITTEN
	MOV	R0,#CUROW	;
	MOV	A,#1H		;FINALLY WRITE FIRST LINE ONCE MORE
	MOVX	@R0,A		;TO POSITION CURSOR
	LJMP	SE_WR6A		;JUMP AND POSITION CURSOR

; HERE WHEN NOT NESSESARY TO INSERT LINE AT TOP OF SCREEN

SE_WR6:	MOV	R0,#CUROW	;GET LINENO TO WRITE
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	CLR	C		;
	SUBB	A,SCROLL	;SUBTRACT NO OF LINES SCROLLED
	CLR	C		;
	SUBB	A,#15H		;IF LINENO ON SCREEN > 20 THEN
	JZ	SE_WR7		;JUMP IF NEEDED TO SCROLL ONE LINE UP
	JNC	SE_WR8		;JUMP IF NEEDED TO SCROLL MORE LINES UP

; HERE WHEN NO SCROLL NEEDED

SE_WR6A:MOV	R0,#SKPH	;GET POINTER TO SHARE BUFFER
	MOVX	A,@R0		;
	MOV	R2,A		;
	MOV	R0,#SKPL	;
	MOVX	A,@R0		;
	MOV	R3,A		;
	CALL	GET_BUFFER	;READ BUFFER CONTENT
	MOV	R0,#CUROW	;POINT AT STORE FOR CURRENT ROWNO
	MOV	A,BUFFER_AREA+1	;GET CURRENT NO
	MOVX	@R0,A		;AND STORE
	MOV	R0,#CUCOL	;POINT AT STORE FOR CURRENT COLUMN NO
	MOV	A,BUFFER_AREA+2	;GET CURRENT NO
	MOVX	@R0,A		;AND STORE
	CALL	SERIAL_SHARE	;
	LJMP	INPUT_DELAY	;

; HERE WHEN JUST NEEDED TO SCROLL ONE LINE UP

SE_WR7:	MOV	A,#1H		;
	MOV	R0,#NODIG	;STORE NO OF LINES TO SCROLL
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;
	LJMP	SE_WR9		;

; HERE WHEN NEEDED TO SCROLL MORE LINES

SE_WR8:	INC	A		;NUMBER OF LINES TO SCROLL
	MOV	SCROLL,A	;
	MOV	R0,#NODIG	;STORE NUMBER
	MOV	P2,#RESOFF	;
	MOVX	@R0,A		;
	CLR	C		;
	SUBB	A,#21		;IS NO OF LINES > 20
	JC	SE_WR9		;JUMP IF NOT
	MOV	A,#20		;OTHERWISE JUST 20 LINES
	MOVX	@R0,A		;

; HERE WHEN SCROLL NEEDED <=> DELETE LINES AT TOP OF SCREEN

SE_WR9:	CALL	GET_TRANS	;GET TRANSMITTER BUFFER
	MOV	R0,#6H		;
	MOV	R1,#0H		;DELETE THE LINE NO 5 ON SCREEN
	CALL	CURSOR_POS	;
	MOV	A,#ESC		;
	MOVX	@DPTR,A		;A LINE IS DELETED BY AN ESCAPE SEQUENSE
	INC	DPTR		;
	MOV	A,#5BH		;SEQUENSE = ESC Æ NO M
	MOVX	@DPTR,A		;
	INC	DPTR		;
	MOV	R0,#NODIG	;GET NO OF LINES TO SCROLL
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	MOV	B,#0AH		;
	DIV	AB		;IF NO > 9 THEN WRITE 2 CHARACTERS
	JZ	SE_WR10		;
	ADD	A,#30H		;CALCULATE ASCII VALUE
	MOVX	@DPTR,A		;
	INC	DPTR		;
SE_WR10:MOV	A,B		;
	ADD	A,#30H		;LEAST SIGNIFICANT DIGIT
	MOVX	@DPTR,A		;
	INC	DPTR		;
	MOV	A,#'M'		;
	MOVX	@DPTR,A		;
	INC	DPTR		;
	CLR	A		;WRITE A 0 TO INDICATE END OF MESSAGE
	MOVX	@DPTR,A		;
	SETB	TI		;
	MOV	R0,#NODIG	;GET NO OF LINES TO INSERT
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	DEC	A		;
	JNZ	SE_WR11		;JUMP IF NEEDED TO INSERT MORE THAN ONE LINE
	INC	SCROLL		;
	CALL	WRITE_LINE	;WRITE THE NEW LINE
	LJMP	SE_WR6A		;

SE_WR11:CALL	WRITE_LINE	;WRITE ONE LINE ON SCREEN
	MOV	R0,#CUROW	;GET CURRENT ROWNO
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;
	DEC	A		;DECREMENT IT AND STORE IT AGAIN
	MOVX	@R0,A		;
	MOV	R0,#NODIG	;GET NO OF LINES TO INSERT
	MOVX	A,@R0		;
	DEC	A		;AND DECREMENT
	MOVX	@R0,A		;
	JNZ	SE_WR11		;CONTINUE UNTIL ALL LINES INSERTED
	MOV	R0,#ROWNO	;GET MAX NO OF LINES
	MOVX	A,@R0		;
	MOV	R0,#CUROW	;AND WRITE INTO CURRENT LINENO
	MOVX	@R0,A		;
	LJMP	SE_WR6A		;

$EJECT
;************************************************************************
;
;	NAME:		GET_SK_BH
;
;	DESCRIPTION:	THIS ROUTINE GETS A BH FROM THE EMPTY QUEUE IN
;			THE INPUT TASK.
;
;	INPUT:		
;
;	OUTPUT:		ADR OF BH IN R2 AND R3
;
;*************************************************************************

GET_SK_BH:
	MOV	A,#INPUTE	;TRY TO GET EMPTY BUFFER
	CALL	DEQ		;
	JNZ	GET_SK2		;JUMP IF ONE FOUND
	MOV	R0,#ROUT_PNT	;OTHERWISE THE RETURN ADRESS
	MOV	P2,#RESOFF	;MUST BE STORED
	POP	ACC		;GET HIGH BYTE RETURN ADRESS
	MOVX	@R0,A		;AND STORE
	INC	R0		;
	POP	ACC		;GET LOW BYTE RETURN ADRESS
	MOVX	@R0,A		;
	%SSEND	(INSEM)		;DEACTIVATE AND WAIT
	%SVENT	(INSEM)		;
	MOV	PSW,#0H		;
	MOV	R0,#ROUT_PNT+1	;THE RETURN ADRESS MUST BE PUT BACK
	MOV	P2,#RESOFF	;
	MOVX	A,@R0		;GET LOW BYTE RETURN ADRESS
	PUSH	ACC		;AND STACK
	DEC	R0		;
	MOVX	A,@R0		;GET HIGH BYTE RETURN ADRESS
	PUSH	ACC		;AND STACK
	LJMP	GET_SK_BH	;

; HERE IF BUFFER FROM SERIAL TASK

GET_SK2:RET			;



END«eof»