; SYSTEM I/O SYSTEM$$
;  1.1  1/18/79
;  USE WITH IMSAI VIO-A VIDEO DISPLAY BOARD ONLY
MSIZE	EQU	48
LAST	EQU	MSIZE*1024
FIRST	EQU	LAST-1536
LASTM	EQU	FIRST+4A0H
RELOC	EQU	100H-LASTM
;
 WIDTH   EQU     80         ; WIDTH OF LINE 
SIZE	EQU	80		; WIDTH OF SCREEN
 LINES   EQU     24         ; NUMBER OF LINES   
 NSCRL   EQU     LINES 
 BLK     EQU     020H   
;   
 TOP     EQU     0F000H         ; TOP OF TV SCREEN  
 WORDS   EQU     TOP+(NSCRL-1)*WIDTH  ; BEGINNING OF EDIT BUFFER   
WORDLO	EQU	WORDS AND 0FFH	;
 OULINE  EQU      WORDS-SIZE           ; POINTER TO OUTPUT BUFFER   
 CR      EQU     13             ;   
;   
         ORG     LASTM          ;START PROGRAM HERE  
	JMP	DTOU
	JMP	LISTR
	JMP	VIOMOD
 ;  
DTOU:
	MOV	A,C
	PUSH	D
	CALL	CHOUT
	POP	D
	RET
 ;  SCROLL UP ONE LINE  
 ;  
 SCRL:   MVI     B,NSCRL        ;SCROLL UP ONE LINE 
 SCRLX:  LXI     H,TOP          ;TO ADDRESS 
         LXI     D,TOP+SIZE      ;FROM ADDRESS  
         CALL    SCUP           ;SCROLL UP ONE LINE 
         CALL    ZERO           ;BLANK OUT LINE 3   
         RET                    ;   
 ;  
 ;  SCROLL UP   
 ;  
 SCUP:   MVI     C,WIDTH           ;SCROLL UP ONE LINE  
 SCUP2:  LDAX    D              ;PICK UP CHARACTER  
         ANI     7FH            ;STRIP OFF WHITE BACKGROUND 
         MOV     M,A            ;STORE IT IN NEW LOCATION   
         INX     H              ;ADJUST POINTERS
         INX     D              ;   
         DCR     C              ;DECREMENT CHARACTER COUNTER
         JNZ     SCUP2          ;LOOP   
	DCR	B		; DECREMENT LINE COUNTER
         JNZ     SCUP   
	RET
 ;  
 ;   BLANK OUT ONE LINE 
 ;  
 ZERO:   MVI     A,BLK          ;LOAD A-REG WITH BLANK CHARACTER
         MVI     C,WIDTH           ;LINE CHARACTER COUNT
 SC3:    MOV     M,A            ;STORE BLANK
         INX     H              ;   
         DCR     C              ;   
         JNZ     SC3            ;LOOP FOR ALL WIDTH CHARACTERS  
         RET                    ;   
 ;  
 ;  
 ;  
 CHOUT:  PUSH    H  
         MOV     C,A            ; SAVE CHARACTER
         PUSH    B              ;   
         LHLD    TVBUF          ;TV BUFFER CURRNET CHARACTER POINTER
         ANI     7FH            ;   
         CPI     CR             ;IS IT CR?  
         JZ      TVCR           ;IF SO, THEN SCROLL UP  
         CPI     95             ;ELSE CHECK FOR DELETE  
         JNZ     CH0            ;   
         DCX     H              ;IF CHAR IS DELETE, MOVE POINTER BA 
         JMP     CH2            ;   
 CH0:    CPI     BLK            ;IS CHAR CONTROL TYPE?  
         JC      CHEND          ;IF NOT, OUTPUT CHARACTER TO TV 
	MOV	A,L		; AT BEGINNING OF LINE ?
	CPI	WORDLO
	JNZ	CH1
         PUSH    B  
         CALL    SCRL   
         POP     B  
         LXI     H,OULINE     ;RESET EDIT BUFFER
         JMP     CH1
 TVCR:    PUSH B
         CALL    SCRL           ;SCROLL UP ONE LINE 
         POP B  
         LXI     H,OULINE     ;RESET EDIT BUFFER
         JMP     CH2            ;   
 CH1:    MOV     M,C            ;NOW, FINALLY, SAVE CHAR IN 
 CH3:    INX     H              ;IN BUFFER AND BUMP POINTER 
 CH2:    SHLD    TVBUF          ;SAVE POINTER   
 CHEND:  POP     B              ;   
         POP     H              ; RESTORE H AND L   
         MOV     A,C            ;   
         RET                    ;   
 ;  
 TVBUF:  DW    WORDS-WIDTH       ; LINE 23 

CSTAT	EQU	0	;STATUS PORT
CDATA	EQU	1	;DATA PORT
CPTR	EQU	10000000B	;READY BIT
LSTAT	EQU  CSTAT		;LIST STATUS PORT.
LCOM	EQU  2		;LIST COMMAND PORT.
LDATA	EQU  CDATA		;LIST DATA PORT.
LRBIT	EQU  CPTR	;LIST READY BIT.
LNULL	EQU  2		;LIST NULL COUNT.

;
; WRITE A CHARACTER ON LISTING DEVICE.
;
LISTR:
	MVI  A,0DH	;IF IT'S A CR,
	CMP  C		;THEN HOP OUT TO
	JZ   LINUL	;NULL ROUTINE.

LIST1:	IN   LSTAT	;READ LISTER STATUS.
	ANI  LRBIT	;LOOK AT READY BIT.

	JZ   LIST1	;READY WHEN HIGH.

	MOV  A,C	;GET DATA BYTE.
	OUT  LDATA	;PRINT IT.
	RET		;RETURN FROM LIST.

LINUL:	PUSH B		;SAVE B&C.
	MVI  B,LNULL	;GET NULL COUNT.
LINUL1:	CALL LIST1	;PRINT (CR FIRST).
	MVI  C,0	;GET NULL CHAR.
	DCR  B		;DECREMENT COUNTER.
	JNZ  LINUL1	;DO NEXT NULL.
	POP  B		;RESTORE B&C.
	MOV  A,C	;RESTORE A.
	RET		;RETURN FROM LIST.
;
;  INITIALIZE IMSAI VIDEO DISPLAY BOARD
;
VIOMOD:	MVI	A,08H		; SET MODE 2 FOR DTV
	STA	TOP+7FFH	; INITIALIZE IMSAI VIO-A BOARD
;
;  ERASE SCREEN
;
	LXI	H,TOP		; TOP OF SCREEN
	MVI	B,LINES+1		; LINES TO BE BLANKED
	MVI	C,SIZE		; COLUMNS TO BE BLANKED
	MVI	A,BLK		; BLANK CHAR.
CLR1:	MOV	M,A		; BLANK MEMORY LOCATION
	INX	H
	DCR	C
	JNZ	CLR1
	MVI	C,SIZE
	DCR	B
	JNZ	CLR1
	RET
         END
