
	NAME	Compass_II_Console

DGROUP	GROUP	DATA
CGROUP	GROUP	CODE
IGROUP	GROUP	CONST

	PUBLIC	ConCharOut
	PUBLIC	ConLineOut
	PUBLIC	XLOC, YLOC, ConsoleState, fontTable

EXTRN	FONT57:BYTE

display	equ	40h	; display is at 40h:0h

DSZB	EQU	9600
DWDB	EQU	40
LNSZB	EQU	400
EDSZB	EQU	DSZB

XHOME	EQU	0
YHOME	EQU	0
XLIMIT	EQU	314
YLIMIT	EQU	230
XINC	EQU	6
YINC	EQU	10

CR	EQU	0DH
LF	EQU	0AH
BS	EQU	08H
SPACE	EQU	20H
TAB	EQU	09H
TILDE	EQU	07EH

ConFirstLine EQU	0
ConLastLine  EQU	23

$EJ

TRUE	EQU	1
FALSE	EQU	0
ON	EQU	1
OFF	EQU	0
MOD16	EQU	000FH
NOCHAR	EQU	0FFH

; CHARACTER DISPLAY MASKS

DMSK15	EQU	003FFH
DMSK14	EQU	081FFH
DMSK13	EQU	0C0FFH
DMSK12	EQU	0E07FH
DMSK11	EQU	0F03FH
DMSK10	EQU	0F81FH
DMSK9	EQU	0FC0FH
DMSK8	EQU	0FE07H
DMSK7	EQU	0FF03H
DMSK6	EQU	0FF81H
DMSK5	EQU	0FFC0H
DLMSK4	EQU	0FFE0H
DHMSK4	EQU	07FFFH
DLMSK3	EQU	0FFF0H
DHMSK3	EQU	03FFFH
DLMSK2	EQU	0FFF8H
DHMSK2	EQU	01FFFH
DLMSK1	EQU	0FFFCH
DHMSK1	EQU	00FFFH
DLMSK0	EQU	0FFFEH
DHMSK0	EQU	007FFH

; CHARACTER INVERSION MASKS

IMSK15    EQU    0F800H
IMSK14    EQU    07C00H
IMSK13    EQU    03E00H
IMSK12    EQU    01F00H
IMSK11    EQU    00F80H
IMSK10    EQU    007C0H
IMSK9     EQU    003E0H
IMSK8     EQU    001F0H
IMSK7     EQU    000F8H
IMSK6     EQU    0007CH
IMSK5     EQU    0003EH
IMSK4     EQU    0001FH
ILMSK3    EQU    0000FH
IHMSK3    EQU    08000H
ILMSK2    EQU    00007H
IHMSK2    EQU    0C000H
ILMSK1    EQU    00003H
IHMSK1    EQU    0E000H
ILMSK0    EQU    00001H
IHMSK0    EQU    0F000H

CONST	SEGMENT	PUBLIC 'CONST'

; DISPLAY LINE START OFFSETS

DLOFST	DW	0	; 0
	DW	400	; 1
	DW	800	; 2
	DW	1200	; 3
	DW	1600	; 4
	DW	2000	; 5
	DW	2400	; 6
	DW	2800	; 7
	DW	3200	; 8
	DW	3600	; 9
	DW	4000	; 10
	DW	4400	; 11
	DW	4800	; 12
	DW	5200	; 13
	DW	5600	; 14
	DW	6000	; 15
	DW	6400	; 16
	DW	6800	; 17
	DW	7200	; 18
	DW	7600	; 19
	DW	8000	; 20
	DW	8400	; 21
	DW	8800	; 22
	DW	9200	; 23

CONST	ENDS

DATA	SEGMENT	PUBLIC	'DATA'

ConsoleState LABEL BYTE      ; start of ConsoleState
XLOC	DW	0	; CURSOR X POSITION
YLOC	DW	0	; CURSOR Y POSITION
cState	DB	0
scroll	DB	0
curChar	DB	0
upperFlag DB	0
nmiFlag	DB	0
fontTable DD	font57
spare	DB	0

DATA	ENDS

$EJ

CODE	SEGMENT	PUBLIC	'CODE'

	ASSUME	CS:CGROUP,DS:DGROUP,ES:IGROUP

DJMPTBL	DW	DBIT15
	DW	DBIT14
	DW	DBIT13
	DW	DBIT12
	DW	DBIT11
	DW	DBIT10
	DW	DBIT9
	DW	DBIT8
	DW	DBIT7
	DW	DBIT6
	DW	DBIT5
	DW	DBIT4
	DW	DBIT3
	DW	DBIT2
	DW	DBIT1
	DW	DBIT0

IJMPTBL    DW    IBIT15
    DW    IBIT14
    DW    IBIT13
    DW    IBIT12
    DW    IBIT11
    DW    IBIT10
    DW    IBIT9
    DW    IBIT8
    DW    IBIT7
    DW    IBIT6
    DW    IBIT5
    DW    IBIT4
    DW    IBIT3
    DW    IBIT2
    DW    IBIT1
    DW    IBIT0

$EJ

; THIS ROUTINE OUTPUTS THE PL/M PARAMETER TO THE 
; CURRENT CURSOR POSITION. THE PL/M CALL IS:

;    CALL CharOut ( char );
;      DECLARE char BYTE;

; CR -> CURSOR TO LEFT MARGIN OF CURRENT LINE.
; BS -> CURSOR LEFT 1 CHARACTER UNLESS AT LEFT
;         MARGIN.
; LF -> CURSOR DOWN 1 LINE. IF AT BOTTOM OF SCREEN
;         THEN SCROLL UP ONE LINE.

ConCharOut PROC FAR

	PUSH	DS
	MOV	AX,DATA
	MOV	DS,AX
	PUSH	BP
	MOV	BP,SP
	CALL	INVCSR
	MOV	AX,[BP+8]		; PARAMETER
	CALL	ICHAROUT
	CALL	INVCSR
	POP	BP
	POP	DS
	RET	2

ConCharOut ENDP

$EJ

; THIS ROUTINE EXECUTES REPETITIVE CHAROUT CALLS.
; THE PL/M INTERFACE IS:

;   CALL ConLineOut (textPtr,count);
;      DECLARE textPtr POINTER; /* 4 BYTEs */
;      DECLARE count   WORD;

ConLineOut PROC FAR

	PUSH	DS
	MOV	AX,DATA
	MOV	DS,AX
	PUSH	BP
	MOV	BP,SP
	CALL	INVCSR
	MOV	AX,[BP+12]	; SEGMENT
	MOV	ES,AX
	MOV	DI,[BP+10]	; ADDRESS
	MOV	CX,[BP+8]		; COUNT
OUTLP:
	MOV	AL,ES:[DI]
	PUSH	ES
	PUSH	CX
	PUSH	DI
	CALL	ICHAROUT
	POP	DI
	POP	CX
	POP	ES
	INC	DI
	LOOP	OUTLP

	CALL	INVCSR
	POP	BP
	POP	DS
	RET	6

ConLineOut ENDP

$EJ

; THIS IS THE INTERNAL CHAROUT ROUTINE USED BY
; CONCHAROUT AND CONLINEOUT.

ICHAROUT:

	CMP	AL,CR
	JE	IS_CR
	CMP	AL,LF
	JE	IS_LF
	CMP	AL,BS
	JE	IS_BS

	CMP	XLOC,XLIMIT
	JLE	xFits
	MOV	XLOC,XHOME
         ADD	YLOC,YINC
xFits:
	CMP	YLOC,YLIMIT
	JLE	yFits
	MOV	YLOC,YLIMIT
	PUSH	AX
	CALL	SCROLLUP
	POP	AX
yFits:
	AND	AH,0
	MOV	DI,AX
	LES	BX,fontTable
	MOV	CL, BYTE PTR ES:[BX]
	AND	CH,0
	MOV	BX,XLOC
	MOV	DX,YLOC
	CALL	DSPCHR

	ADD	XLOC,XINC
	CMP	XLOC,XLIMIT
	JLE	nextFits
	MOV	XLOC,XHOME
         JMP	IS_LF
nextFits:
	RET

IS_BS:

; CANNOT BACKSPACE PAST LEFT MARGIN.

	CMP	XLOC,XHOME
	JE	EXIT
	SUB	XLOC,XINC
EXIT:
	RET

IS_CR:	MOV	XLOC,XHOME
	RET

IS_LF:
         ADD	YLOC,YINC
	CMP	YLOC,YLIMIT
	JLE	NOSCROLL
	MOV	YLOC,YLIMIT
	CALL	SCROLLUP
NOSCROLL:
	RET

$EJ

; THIS ROUTINE SCROLLS THE SCREEN UP BY ONE
; DISPLAY LINE. THE BOTTOM LINE IS BLANKED.

SCROLLUP:
	PUSH	DS
	MOV	AX,CONST
	MOV	ES,AX
	MOV	BX,ConFirstLine
	SHL	BX,1
	MOV	DI, WORD PTR ES:DLOFST [BX]
	MOV	AX,DI
	ADD	AX,LNSZB
	MOV	SI,AX
	MOV	BX,ConLastLine
	SHL	BX,1
	MOV	CX, WORD PTR ES:DLOFST [BX]
	SUB	CX,DI
	SHR	CX,1
	MOV	AX,DISPLAY
	MOV	DS,AX
	MOV	ES,AX
	CLD
	REP	 MOVSW

	MOV	WORD PTR [DI],0
	MOV	SI,DI
	INC	DI
	INC	DI
	MOV	CX,(LNSZB-2)/2
	CLD
	REP	MOVSW
	POP	DS
	RET

$EJ

; THIS ROUTINE DISPLAYS THE ASCII CHARACTER
; AT THE SPECIFIED X-Y COORDINATE. 
;	
;	DI	ASCII CHARACTER
;	BX	X POSITION
;	DX	Y POSITION
;	CX	FONT SIZE
;
; THE X-Y DOT IS AT THE UPPER LEFT OF THE
; CHARACTER TO BE DISPLAYED. THE CHARACTER
; IS DISPLAYED IN A 5X8 CELL. THE EIGHTH ROW
; IS USED FOR DESCENDERS.

DSPCHR:
	CMP	DI,CX
	JL	legal
	MOV	DI,CX
	DEC	DI
legal:
	PUSH	DS
	MOV	AX,DATA
	MOV	DS,AX

	LES	AX,fontTable
	ADD	DI,AX
	ADD	DI,8		; skip over font header

; DISPLAY WORD = 40*Y + X/16

	MOV	AX,DX
	SHL	AX,1
	SHL	AX,1
	SHL	AX,1	; 8*Y

	SHL	DX,1
	SHL	DX,1
	SHL	DX,1
	SHL	DX,1
	SHL	DX,1	; 32*Y

	ADD	DX,AX	; 40*Y

; X MOD 16 SPECIFIES THE LEFTMOST BIT IN THE
; WORD. USE THIS FOR WORD JUMP TABLE OFFSET.

	MOV	SI,BX
	AND	SI,MOD16
	SHL	SI,1

	SHR	BX,1
	SHR	BX,1
	SHR	BX,1
	SHR	BX,1
	SHL	BX,1		; X/16

	ADD	BX,DX		; 32*Y+X/16
	MOV	DX,CX
	MOV	CH,8

	MOV	AX,DISPLAY
	MOV	DS,AX

$EJ

; BX -> WORD
; DI =  CURRENT ROW
; SI =  JUMP TABLE ADDRESS
; CH =  ROW COUNTER
; AX =  CURRENT FONT ROW (LEFT JUSTIFIED)
; DX =  FONTSZ

DNXTROW:
	MOV	AH, BYTE PTR ES:[DI]
	AND	AL,0
	JMP	WORD PTR CS:DJMPTBL [SI]

DBIT15:
	AND	WORD PTR [BX],DMSK15
	OR	[BX],AX
	JMP	DCONT

DBIT14:
	SHR	AX,1
	AND	WORD PTR [BX],DMSK14
	OR	[BX],AX
	JMP	DCONT

DBIT13:
	SHR	AX,1
	SHR	AX,1
	AND	WORD PTR [BX],DMSK13
	OR	[BX],AX
	JMP	DCONT

$EJ

DBIT12:
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1
	AND	WORD PTR [BX],DMSK12
	OR	[BX],AX
	JMP	DCONT

DBIT11:
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1
	AND	WORD PTR [BX],DMSK11
	OR	[BX],AX
	JMP	DCONT

DBIT10:
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1
	SHR	AX,1
	AND	WORD PTR [BX],DMSK10
	OR	[BX],AX
	JMP	DCONT

DBIT9:
	MOV	AL,AH
	AND	AH,0
	SHL	AX,1
	SHL	AX,1
	AND	WORD PTR [BX],DMSK9
	OR	[BX],AX
	JMP	DCONT

DBIT8:
	MOV	AL,AH
	AND	AH,0
	SHL	AX,1
	AND	WORD PTR [BX],DMSK8
	OR	[BX],AX
	JMP	DCONT

$EJ

DBIT7:
	MOV	AL,AH
	AND	AH,0
	AND	WORD PTR [BX],DMSK7
	OR	[BX],AX
	JMP	DCONT

DBIT6:
	MOV	AL,AH 
	AND	AH,0
	SHR	AX,1
	AND	WORD PTR [BX],DMSK6
	OR	[BX],AX
	JMP	DCONT

DBIT5:
	MOV	AL,AH
	AND	AH,0
	SHR	AX,1
	SHR	AX,1
	AND	WORD PTR [BX],DMSK5
	OR	[BX],AX
	JMP	DCONT

DBIT4:
	ROL	AX,1
	ROL	AX,1
	ROL	AX,1
	ROL	AX,1
	ROL	AX,1
	AND	WORD PTR [BX],DLMSK4
	OR	[BX],AL
	AND	WORD PTR [BX+2],DHMSK4
	OR	[BX+3],AH
	JMP	DCONT

DBIT3:
	ROL	AX,1
	ROL	AX,1
	ROL	AX,1
	ROL	AX,1
	AND	WORD PTR [BX],DLMSK3
	OR	[BX],AL
	AND	WORD PTR [BX+2],DHMSK3
	OR	[BX+3],AH
	JMP	DCONT

$EJ

DBIT2:
	ROL	AX,1
	ROL	AX,1
	ROL	AX,1
	AND	WORD PTR [BX],DLMSK2
	OR	[BX],AL
	AND	WORD PTR [BX+2],DHMSK2
	OR	[BX+3],AH
	JMP	DCONT

DBIT1:
	ROL	AX,1
	ROL	AX,1
	AND	WORD PTR [BX],DLMSK1
	OR	[BX],AL
	AND	WORD PTR [BX+2],DHMSK1
	OR	[BX+3],AH
	JMP	DCONT

DBIT0:
	ROL	AX,1
	AND	WORD PTR [BX],DLMSK0
	OR	[BX],AL
	AND	WORD PTR [BX+2],DHMSK0
	OR	[BX+3],AH

DCONT:
	ADD	DI,DX	; fontsz
	ADD	BX,DWDB
	DEC	CH
	JZ	DEXIT
	JMP	DNXTROW
DEXIT:
	POP	DS
	RET

; THIS ROUTINE INVERTS THE CURSOR AT THE  
; SPECIFIED X-Y COORDINATE IF THE CURSOR IS
; ON. THE CURSOR IS AN UNDERBAR.
;
;    XLOC    X POSITION
;    YLOC    Y POSITION

INVCSR:
    CMP    CSTATE,ON
    JE     CSRON
    RET
CSRON:
    MOV    BX,XLOC
    MOV    DX,YLOC

    PUSH   DS
    MOV    AX,DISPLAY
    MOV    DS,AX
    MOV    AX,CONST
    MOV    ES,AX

    MOV    AX,DX
    SHL    AX,1
    SHL    AX,1
    SHL    AX,1

    SHL    DX,1
    SHL    DX,1
    SHL    DX,1
    SHL    DX,1
    SHL    DX,1

    ADD    DX,AX

    MOV    SI,BX
    AND    SI,MOD16
    SHL    SI,1

    SHR    BX,1
    SHR    BX,1
    SHR    BX,1
    SHR    BX,1
    SHL    BX,1

    ADD    BX,DX
    ADD    BX,DWDB*8

    JMP    WORD PTR CS:IJMPTBL [SI]
$EJ

IBIT15:
    XOR    WORD PTR [BX],IMSK15
    JMP    ICONT
IBIT14:
    XOR    WORD PTR [BX],IMSK14
    JMP    ICONT
IBIT13:
    XOR    WORD PTR [BX],IMSK13
    JMP    ICONT
IBIT12:
    XOR    WORD PTR [BX],IMSK12
    JMP    ICONT
IBIT11:
    XOR    WORD PTR [BX],IMSK11
    JMP    ICONT
IBIT10:
    XOR    WORD PTR [BX],IMSK10
    JMP    ICONT
IBIT9:
    XOR    WORD PTR [BX],IMSK9
    JMP    ICONT
IBIT8:
    XOR    WORD PTR [BX],IMSK8
    JMP    ICONT
IBIT7:
    XOR    WORD PTR [BX],IMSK7
    JMP    ICONT
IBIT6:
    XOR    WORD PTR [BX],IMSK6
    JMP    ICONT
IBIT5:
    XOR    WORD PTR [BX],IMSK5
    JMP    ICONT
IBIT4:
    XOR    WORD PTR [BX],IMSK4
    JMP    ICONT
IBIT3:
    XOR    WORD PTR [BX],ILMSK3
    XOR    WORD PTR [BX+2],IHMSK3
    JMP    ICONT
IBIT2:
    XOR    WORD PTR [BX],ILMSK2
    XOR    WORD PTR [BX+2],IHMSK2
    JMP    ICONT
IBIT1:
    XOR    WORD PTR [BX],ILMSK1
    XOR    WORD PTR [BX+2],IHMSK1
    JMP    ICONT
IBIT0:
    XOR    WORD PTR [BX],ILMSK0
    XOR    WORD PTR [BX+2],IHMSK0

$EJ

ICONT:
    POP    DS
    RET

CODE	ENDS

END
