DataMuseum.dk

Presents historical artifacts from the history of:

CP/M

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

See our Wiki for more about CP/M

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦06a11777e⟧ TextFile

    Length: 18560 (0x4880)
    Types: TextFile
    Names: »CHARIO.Z80«

Derivation

└─⟦7303e23ba⟧ Bits:30003507 JET80 System diskette
    └─ ⟦this⟧ »CHARIO.Z80« 
└─⟦a844860b7⟧ Bits:30002858 CP/M Plus (tm) Version 3.0 for JET80
    └─ ⟦this⟧ »CHARIO.Z80« 
└─⟦c10cc8855⟧ Bits:30002859 CP/M Plus med Hit & Dit filoverførsel for JET80
    └─ ⟦this⟧ »CHARIO.Z80« 

TextFile

	TITLE	'CHARIO.Z80  I/O-HANDLER'

;**********************************************************
;* THIS MODULE TAKES CARE OF ALL CHAR I/O FUNCTIONS FOR   *
;* CP/M 3.0 .                                             *
;* A TABLE OF DEVICE-NAMES IS DEFINED TOGEATHER WITH A    *
;* DEVICE-HANDLER-TABLE WITH ADDRESSES AND ROUTINES.      *
;* THE INTERRUPT-DRIVEN KEYBOARD ROUTINE IS HERE.         *
;*                                                        *
;* THE GLOBAL SUBROUTINE 'INISTM' IS ALSO IN THIS MODULE. *
;**********************************************************
; LATEST CHANGE: 1984-06-21.  PSW.
; BIOSREVISION D.

	.Z80

	ENTRY	?CINIT,?CI,?CO,?CIST,?COST
	ENTRY	@CTBL
	ENTRY	INISTM
	ENTRY	KBDIRQ,UNKINT
	ENTRY	PIOGAI,PIOGBI
	ENTRY	C0BAUD,C1BAUD,SI1ATBL

	EXTRN	SIO1IV,CTCIRV,PIOIRV
	EXTRN	?PMSG
	PAGE	42
; SPECIAL CHARACTERS AND CONSTANS:

EOF	EQU	1AH			; CP/M END OF FILE CHAR (^Z)
CTRLC	EQU	'C'-'@'
FALSE	EQU	0
TRUE	EQU	NOT FALSE

MB$INPUT	EQU	00000001B	; DEVICE HANDLES INPUT
MB$OUTPUT	EQU	00000010B	; DEVICE HANDLES OUTPUT
MB$IN$OUT	EQU	MB$INPUT+MB$OUTPUT
MB$SOFTBAUD	EQU	00000100B	; SOFTWARE SELECTABLE BAUD RATE
MB$SERIAL	EQU	00001000B	; DEVICE USES PROTOCOL
MB$XON$XOFF	EQU	00010000B	; XON/XOFF PROTOCOL ON

; PORT-ADDRESSES.

SIO1AD	EQU	0		; MODEM/PRINTER - DATA
SIO1AC	EQU	SIO1AD+1	; MODEM/PRINTER - CONTROL/STATUS
SIO1BD	EQU	SIO1AD+2	; V24,TERMINAL - DATA
SIO1BC	EQU	SIO1AD+3	; V24,TERMINAL - CONTROL/STATUS
SIO2AD	EQU	4		; RS422/NETWORK - DATA
SIO2AC	EQU	SIO2AD+1	; RS422/NETWORK - CONTROL/STATUS
SIO2BD	EQU	SIO2AD+2	; 
SIO2BC	EQU	SIO2AD+3	; 
				; SUPPORTED WITH 1,228,800 Hz
CTC0	EQU	8		; CTC CHAN 0 - BAUDRATE SIO1A/TIMER
CTC1	EQU	CTC0+1		; CTC CHAN 1 - BAUDRATE SIO1B/TIMER
CTC2	EQU	CTC0+2		; CTC CHAN 2 - TIMER TO CTC3 (HALVED)
CTC3	EQU	CTC0+3		; CTC CHAN 3 - REALTIMECLOCK/COUNTER
				;
PIOAD	EQU	0CH		; PIO A DATA - CENTRONICS DATA
PIOAC	EQU	PIOAD+1		; PIO A CONTROL (WRITE ONLY)
PIOBD 	EQU	PIOAD+2		; PIO B DATA - CENTRONICS CTRL
				;         	   + MODEM CTRL
				; BIT0 CEN. *BUSY
				; BIT1 CEN. *PAPER EMPTY
				; BIT2 CEN. *SELECT
				; BIT3 CEN. *FAULT
				; BIT4 CEN. *STROBE
				; BIT5 CEN. *ACK
				; BIT6 PIO BUFFER DIRECTION CH. B
				; BIT7 PIO BUFFER DIRECTION CH. A
PIOBC	EQU	PIOAD+3		; PIO B CONTROL (WRITE ONLY)

SWITCH	EQU	1CH		; READABLE SWITCH
				; BIT3: CONSOLE BAUDRATE
				; xxxx0xxx  9600 BAUD
				; xxxx1xxx 19200 BAUD
				; BIT4: CONSOLE HANDSHAKE
				; xxx0xxxx NO HANDSHAKE
				; xxx1xxxx HANSHAKE
				; BIT5: TERMINAL TYPE
				; xx0xxxxx SERIAL
				; xx1xxxxx GRAPHIC

PIOGAD	EQU	20H		; PIO A GRAPHIC PORT DATA OUT (DISPLAY)
PIOGAC	EQU	PIOGAD+1	; PIO A GRAPHIC PORT CONTROL (WRITE ONLY)
PIOGBD	EQU	PIOGAD+2	; PIO B GRAPHIC PORT DATA IN (KBD)
PIOGBC	EQU	PIOGAD+3	; PIO B GRAPHIC PORT CONTROL (WRITE ONLY)
	PAGE
	CSEG			; BANK0
;**********************************************************
;*        NAME TABLE OF THE DEVICES IN THE SYSTEM.        *
;**********************************************************
@CTBL:	DEFB	'CRT   '	; DEVICE 0, CRT OR CONSOLE
	DEFB	MB$IN$OUT+MB$SERIAL+MB$SOFTBAUD
C0BAUD:	DEFB	14		; 9600 BAUD. WILL BE PATCHED.

	DEFB	'LPT   '	; DEVICE 1, SERIAL LINE PRINTER
	DEFB	MB$IN$OUT+MB$SERIAL+MB$SOFTBAUD
C1BAUD:	DEFB	14		; 9600 BAUD. WILL BE PATCHED.

	DEFB	'CEN   '	; DEVICE 2, CENTRONICS PARALLEL
	DEFB	MB$OUTPUT	; OUTPUT ONLY.
	DEFB	0		; NO BAUDRATE

	DEFB	'GRAPH '	; DEVICE 3, GRAPHIC TERMINAL
	DEFB	MB$IN$OUT
	DEFB	0		; NO BAUDRATE

	DEFB	0		; END TABLE

BDTBL:	DEFB	-1,0		; 0:  NONE
	DEFB	-1,0		; 1:    50
	DEFB	0,0C4H		; 2:    75
	DEFB	174,0C4H	; 3:   110
	DEFB	143,0C4H	; 4:   134.5
	DEFB	0,84H		; 5:   150
	DEFB	128,84H		; 6:   300
	DEFB	64,84H		; 7:   600
	DEFB	32,84H		; 8:  1200
	DEFB	-1,0		; 9:  1800
	DEFB	16,84H		;10:  2400
	DEFB	-1,0		;11:  3600
	DEFB	8,84H		;12:  4800
	DEFB	-1,0		;13:  7200
	DEFB	4,84H		;14:  9600
	DEFB	2,84H		;15: 19200
	DEFB	1,84H		;16: 38400
	DEFB	1,44H		;17: 76800

BTLKUP:
	AND	0FH		; MASK MAX 15.
	RLA			; *2 FOR TABLE-LOOKUP
	LD	E,A		; INDEX TABLE FOR CTC CONSTANS.
	LD	D,0		; (IF CTC CONST.=0FFH, NO BAUD RATE
	LD	HL,BDTBL
	ADD	HL,DE
	LD	A,(HL)
	CP	-1
	RET	Z		; CANNOT SET THIS BAUD RATE
	INC	HL		; GET SIO BYTE.
	LD	B,(HL)
	RET
	PAGE
; INISTM -- WRITES A NUMBER OF BYTE TO ONE OR MORE PORTS.
; IN:		     HL = TABLE-ADDRESS.
;                    TABLEVIEW (BYTE BY BYTE):
;                    NO OF BYTES, PORT#, BYTE1,...,
;                    NO OF BYTES, PORT#, BYTE1,...,
;                    0 (DETERMINATOR).

INISTM:	LD	A,(HL)		; LOAD BYTE
	OR	A		; IS IT ZERO?
	RET	Z		; YES...TERMINATE
	LD	B,A		; NO...THEN IT IS A BYTE COUNTER.
	INC	HL		; NEXT BYTE, WHICH IS THE PORT#
	LD	C,(HL)		; STORED IN C.
	INC	HL		; POINT TO DATA BYTE1
	OTIR			; SEND (B) BYTES TO PORT (C)
	JR	INISTM		; GO ON.
	PAGE
;********************************************************
;*							*
;*		CONSOLE AND LIST DEVICE I/O		*
;*							*
;********************************************************

; ?CINIT --
; IN:			C = LOGICAL UNIT #
;
; IF THERE IS A PHYSICAL UNIT IN @CTBL FOR THIS LOGICAL UNIT,
; IT WILL BE INITILIZED WITH WITH BAUD RATE BYTE IN THE TABLE.
?CINIT:
	LD	B,C
	INC	B		; MAKE DEVICE # (RELATIVE 1)
	DJNZ	INIT1		; TEST IF DEV# IS 0

; INIT DEVICE 0			; CRT:
	LD	HL,SIO1IV	; SET SIOVECTOR
	LD	A,L
	LD	(SIOVEC),A
	LD	HL,CTCIRV	; SET CTCVECTOR
	LD	A,L
	LD	(CTCVEC),A
	IN	A,(SWITCH)	; READ SWITCH
	AND	00001000B	; BIT3 BAUDRATE
	JR	Z,INIT01
	LD	A,15		; 19200 BAUD
	LD	(C0BAUD),A
INIT01:	IN	A,(SWITCH)
	AND	00010000B	; BIT4 HANDSHAKE
	JR	Z,INIT02
	LD	A,11100001B	; Rx 8 BITS, AUTO ENABL., Rx ENABLE
	LD	(HANDSH),A
INIT02:	LD	A,(C0BAUD)
	CALL	BTLKUP
	RET	Z
	LD	(BAUDB),A
	LD	A,B
	LD	(CLKB),A
	LD	HL,SI1BTBL	; POINT TO INIT.TABLE
INSIO:	CALL	INISTM		; SEND TO THE PORT.
	DEC	C		; POINT TO THE DATA PORT
	IN	A,(C)		; CLEAR THE INPUT
	IN	A,(C)		; OF THE SIO.
	RET			; READY

INIT1:	DJNZ	INIT2		; JUMP IF NOT DEV #1.

; INIT DEV #1.			; LPT:
	LD	A,(C1BAUD)	; GET CHAR DEVICE 1 BAUD BYTE.
				; CALC BAUD RATE BYTES
INIT1B:	CALL	BTLKUP		; CHECK IN BAUD TABLE
	RET	Z		; NOT COORECT...RETURN
	LD	(BAUDA),A	; SET CTC COUNTER CONSTANT
	LD	A,B		; GET SIO CONSTANT
	LD	(CLKA),A	; SET IT
	LD	HL,SI1ATBL	; POINT TO THE INIT. TABLE
	JR	INSIO		; DO

INIT2:	DJNZ	INIT3		; JUMP IF NOT DEV #2

; INIT DEVICE #2		; CEN:
	LD	HL,PIOTBL	; POINT TO THE INIT. TABLE
	CALL	INISTM		; DO
	RET

INIT3:	DJNZ	INIT4		; JUMP IF NOT DEV #3
	
; INIT DEVICE #3		; GRAPH:
	LD	HL,PIOIRV	; POINT TO INTERRUPT VECTOR
	LD	A,L
	LD	(PIAVEC),A	; STORE LO BYTE IN TABLE
	INC	A
	INC	A		; PIOGB INTERRUPT
	LD	(PIBVEC),A
	LD	HL,PIOGTBL	; POINT TO INIT. TABLE
	CALL	INISTM		; DO
	
INIT4:	RET			; NO MORE DEVICES.
	PAGE
; ?CI:
; CHAR INPUT FROM DEVICE # IN REGISTER (B).

?CI:
	INC	B		; DEVICE # (RELATIVE 1)
	DJNZ	CI1		; JUMP IF NOT DEVICE #0

; CONIN -- CONSOLE CHAR INPUT. DEVICE #0.
; IN:			NONE.
; OUT:			A = CHAR (PARITY BIT = 0).
;			AF,DE,HL,BC WILL BE CHANGED.

CONIN:
	LD	HL,RNGCNT	; POINT TO THE RING BUFFER COUNTER.
	XOR	A		;        ZERO 
CONIN1:	OR	(HL)		; GET IT.
	JR	Z,CONIN1	; LOOP FOR CHAR.
	DI
	DEC	(HL)		; COUNT DOWN
	LD	DE,(RNGOUT)	; GET THE OUTPUT-POINTER
	LD	A,(DE)		; A=OUTPUT CHAR (PARITY RESET).
	AND	07FH		; CLEAR BIT 7
	LD	HL,RNGEND	; INC RING BUFFER-OUTPUT-POINTER
	SBC	HL,DE		; IS THE BUFFEREND?
	INC	DE		;        (INC)
	JR	NZ,CONIN2	; NO...JUMP
	LD	DE,RNGBEG	; SET BUFFER START
CONIN2:	LD	(RNGOUT),DE	; SAVE THE POINTER.
	EI
	RET

CI1:	DJNZ	CI2		; JUMP IF NOT DEVICE 1

; AUXIN -- GIVES INPUT FROM SIO1 A.
;
; IN:			NONE
; OUT:			A = CHAR.

AUXIN:	CALL	AUXIST		; CHAR IN SIO BUFFER?
	JR	Z,AUXIN		; NO...WAIT
	IN	A,(SIO1AD)	; READ CHAR
	RET

CI2:	DJNZ	CI3		; JUMP IF NOT DEVICE 2
; CENTRONICS IS DEVICE 2, OUTPUT ONLY.

CI4:	LD	A,EOF		; END-OF-FILE-TOKEN.
	RET
CI3:	DJNZ	CI4		; JUMP IF NOT DEVICE 3


; GRIN -- GRAPHIC KEYBOARD INPUT. DEVICE #3.
; IN:			NONE.
; OUT:			A = CHAR (PARITY BIT = 0).
;			AF,DE,HL,BC WILL BE CHANGED.

GRIN:
	LD	HL,GRCNT	; POINT TO THE RING BUFFER COUNTER.
	XOR	A		;        ZERO 
GRIN1:	OR	(HL)		; GET IT.
	JR	Z,GRIN1		; LOOP FOR CHAR.
	DI
	DEC	(HL)		; COUNT DOWN
	LD	DE,(GRNOUT)	; GET THE OUTPUT-POINTER
	LD	A,(DE)		; A=OUTPUT CHAR (PARITY RESET).
;	AND	07FH		; CLEAR BIT 7
	LD	HL,GRNEND	; INC RING BUFFER-OUTPUT-POINTER
	SBC	HL,DE		; IS THE BUFFEREND?
	INC	DE		;        (INC)
	JR	NZ,GRIN2	; NO...JUMP
	LD	DE,GRNBEG	; SET BUFFER START
GRIN2:	LD	(GRNOUT),DE	; SAVE THE POINTER.
	EI
	RET

	PAGE
; ?CO -- SEND A CHARACTER TO A CHOOSEN DEVICE.
; IN:			B = DEVICE #
;			C = CHAR.

?CO:
	INC	B		; MAKE DEVICE # (RELATIVE 1)
	DJNZ	CO1		; JUMP IF NOT DEVICE 0

; CONOUT -- SIO1B OUTPUT ROUTINE.
;
; IN:			C = CHAR --> SIO1B
; OUT:			A = WRITTEN CHAR.

CONOUT:
	CALL	CNOST		; TEST OUTPUT STATUS
	JR	Z,CONOUT	; WAIT FOR READY
	LD	A,C
	OUT	(SIO1BD),A
	RET	

CO1:	DJNZ	CO2		; JUMP IF NOT DEVICE 1

; AUXOUT --  SIO1A OUTPUT ROUTINE.
; IN:			C = CHAR --> SIO1A
; OUT:			A = WRITTEN CHAR

AUXOUT:
	CALL	AUXOST		; TEST OUTPUT STATUS
	JR	Z,AUXOUT	; WAIT FOR READY.
	LD	A,C
	OUT	(SIO1AD),A
	RET

CO2:	DJNZ	CO3		; JUMP IF NOT DEVICE 2

; LISTC --  CENTRONICS PARALLEL OUTPUT ROUTINE.
; IN:			C = CHAR --> PIOA
; OUT:			A = WRITTEN CHAR.

LISTC:	
;	LD	A,01010000B	; STROBE HIGH
;	OUT	(PIOBD),A
	
LISTC1:	CALL	LSTTST		; TEST OUTPUT STATUS
	JR	Z,LISTC1	; WAIT FOR READY.
	LD	A,C
	OUT	(PIOAD),A
	LD	A,01000000B	; STROBE
	OUT	(PIOBD),A
	LD	A,01010000B	; STROBE HIGH
	OUT	(PIOBD),A
	RET

CO3:	DJNZ	CO4		; JUMP IF NOT DEVICE 3

; GROUT -- GRAPHIC OUTPUT ROUTINE.
; IN:			C = CHAR --> PIOGA
; OUT:			A = WRITTEN CHAR

GROUT:	CALL	GROST		; TEST OUTPUT STATUS
	JR	Z,GROUT		; WAIT FOR READY
	LD	A,C
	DI
	OUT	(PIOGAD),A
	INC	(HL)		; HL -->GRSCNT
	EI
CO4:	RET
	PAGE
; ?CIST -- CHAR INPUT STATUS FROM CHOOSEN DEVICE.
; IN:			B = DEVICE #

?CIST:
	INC	B		; MAKE DEVICE # (RELATIVE 1)
	DJNZ	CIS1		; JUMP IF NOT DEVICE 0.

; CONST -- CONSOLE INPUT STATUS CHECK.
; IN:			NONE
; OUT:			A = 0, Z = 1 IF NO CHAR AVAIL.
;			A = 0FFH, Z = 0 AT LEAST ONE CHAR AVAIL.

CONST:
	LD	A,(RNGCNT)	; ANY CHAR IN THE BUFFER?
	OR	A
	RET	Z		; NO...RETURN
	OR	0FFH		; YES...SET FLAG
	RET 

CIS1:	DJNZ	CIS2		; JUMP IF NOT DEVICE 1.

; AUXIST -- AUXILIARY INPUT STATUS.
; IN:			NONE
; OUT:			A = 0, Z = 1 IF NOT READY
;			A = 0FFH, Z = 0 IF CHAR AVAIL.

AUXIST:
	IN	A,(SIO1AC)	; READY STATUS.
	AND	00000001B	; MASK Rx CHAR AVAILABLE
	RET	Z		; NOT READY...RETURN
	OR	0FFH		; MARK CHAR AVAIL
	RET

CIS2:	DJNZ	CIS3		; JUMP IF NOT DEVICE 2
; CENTRONICS DOES NOT HANDLE INPUT. RETURNS NOT READY.

CIS4:	XOR	A		; NOT READY
	RET
CIS3:	DJNZ	CIS4		; JUMP IF NOT DEVICE 3. NO MORE DEV.

; GRINST -- GRAPHIC INPUT STATUS.
; IN:			NONE
; OUT:			A = 0, Z = 1 IF NOT READY
;			A = 0FFH, Z = 0 IF CHAR AVAIL.

GRINST:
	LD	A,(GRCNT)	; TEST GR. CHAR. COUNTER
	OR	A
	RET	Z		; RETURN NO CHAR
	OR	0FFH		; SET READY
	RET
	PAGE
; ?COST -- CHARACTER OUTPUT STATUS FROM CHOOSEN DEVICE.
; IN:			B = DEVICE #.

?COST:
	INC	B		; MAKE DEVICE # (RELATIVE 1)
	DJNZ	COS1		; JUMP IF NOT DEVICE 0.

; CNOST: -- CONSOLE OUTPUT STATUS CHECK.
; IN:			NONE
; OUT:			A = 0, Z = 1 IF NOT READY
;			A = 0FFH, Z = 0 IF READY FOR OUTPUT

CNOST:
	IN	A,(SIO1BC)	; READ STATUS.
	AND	00000100B	; MASK Tx BUFFER EMPTY
	RET	Z		; NOT READY...RETURN
	OR	0FFH		; SET FLAG FOR READY OUTPUT.
	RET

COS1:	DJNZ	COS2		; JUMP IF NOT DEVICE 1.

; AUXOST -- AUXILIARY OUTPUT STATUS.
; IN:			NONE
; OUT:			A = 0, Z = 1 IF NOT READY
;			A = 0FFH, Z = 0 IF READY FOR OUTPUT.

AUXOST:
	IN	A,(SIO1AC)	; READ STATUS
	AND	00000100B	; MASK Tx BUFFER EMPTY
	RET	Z		; NOT READY...RETURN
	OR	0FFH		; SET FLAG FOR READY OUTPUT.
	RET

COS2:	DJNZ	COS3		; JUMP IF NOT DEVICE 2.

; LSTTST -- PARALLEL PORT TEST IF READY.
; IN:			NONE
; OUT: 			A = 0, Z = 1 IF NOT READY
;			A = 0FFH, Z = 0 IF READY FOR OUTPUT.

LSTTST:
	IN	A,(PIOBD)	; READ ACK AND BUSY.
	AND	00100001B
	CP	00100000B	; READY AND NOT BUSY
	LD	A,0FFH
	JR	Z,LSTT1		; YES...JUMP
	LD	A,0		; SET NOT READY
LSTT1:	AND	A
	RET

COS3:	DJNZ	COS4		; JUMP IF NOT DEVICE 3.

; GROST -- GRAPHIC OUTPUT STATUS.
; IN:			NONE
; OUT:			A = 0, Z = 1 IF NOT READY
;			A = 0FFH, Z = 0 IF READY FOR OUTPUT.

GROST:	LD	HL,GRSCNT	; GET STATUS COUNTER
	LD	A,(HL)
	CP	0FFH		; IS IT READY
	JR	Z,GROST1	; YES...JUMP
	XOR	A		; MARK NOT READY
GROST1:	OR	A
	RET

COS4:	XOR	A		; NOT READY. CAUSE NO
	RET			; MORE DEVICES.

	PAGE
; KBDIRQ -- CONSOLE KEYBOARD INTERRUPT SERVICE ROUTIN.
; USES LOCAL STACK IN ORDER NOT TO INTERFERE WITH THE
; USER PROGRAM STACK.

KBDIRQ:
	LD	(USRSK2),SP	; OWN STACK
	LD	SP,OWNSK2
	PUSH	AF		; SAVE REGISTERS.
	PUSH	DE
	PUSH	HL
	LD	HL,RNGCNT	; HL --> NO OF CHAR IN BUFFER
	LD	A,(HL)		; A = NO OF CHAR IN BUFFERT
	CP	RNGEND-RNGBEG	; IS BUFFER FULL?
	IN	A,(SIO1BD)	;         A = CHAR (CLR INTERRUPT)
	JR	Z,KBDIR2	; YES...JUST JUMP AND QUIT
	INC	(HL)		; INC CHAR-COUNTER 
	AND	07FH		; MASK PARITY
	LD	HL,(RNGIN)	; HL --> INPUT
	LD	(HL),A		; SAVE INPUT CHAR IN BUFFER.
	AND	A		; CLEAR CARRY BIT
	EX	DE,HL		; SAVE INPUT POINTER IN DE.
	LD	HL,RNGEND	; HL=BUFFEREND FOR TEST
	SBC	HL,DE		; POINTER AT END?
	INC	DE		;            INC
	JP	NZ,KBDIR1	; NO...JUMP
	LD	DE,RNGBEG	; SET POINTER TO BUFFERSTART
KBDIR1:	LD	(RNGIN),DE	; SAVE THE POINTER.
KBDIR2:	POP	HL		; USER REGS. BACK
	POP	DE
	POP	AF
	LD	SP,(USRSK2)	; AND USER STACK.

UNKINT:
	EI			; BACK FROM INTERRUPT.
	RETI

; PIOGAI -- INTERRUPT FROM GRAPHIC TERMINAL.
; TELLS TERMINAL READY.

PIOGAI:	PUSH	AF
	LD	A,0FFH
	LD	(GRSCNT),A
	POP	AF
	JR	UNKINT

; PIOGBI -- GRAPHIC KEYBOARD INTERRUPT SERVICE ROUTIN.

PIOGBI:	LD	(USRSK3),SP
	LD	SP,OWNSK3
	PUSH	AF		; SAVE REGISTERS.
	PUSH	DE
	PUSH	HL
	LD	HL,GRCNT	; HL --> NO OF CHAR IN BUFFER
	LD	A,(HL)		; A = NO OF CHAR IN BUFFERT
	CP	GRNEND-GRNBEG	; IS BUFFER FULL?
	IN	A,(PIOGBD)	;         A = CHAR (CLR INTERRUPT)
	JR	Z,PIOGB2	; YES...JUST JUMP AND QUIT
	INC	(HL)		; INC CHAR-COUNTER 
	LD	HL,(GRNIN)	; HL --> INPUT
	LD	(HL),A		; SPAR INPUT CHAR IN BUFFER.
	XOR	A
	EX	DE,HL		; SAVE INPUT POINTER IN DE.
	LD	HL,GRNEND	; HL=BUFFEREND FOR TEST
	SBC	HL,DE		; POINTER AT END?
	INC	DE		;            INC
	JP	NZ,PIOGB1	; NO...JUMP
	LD	DE,GRNBEG	; SET POINTER TO BUFFERSTART
PIOGB1:	LD	(GRNIN),DE	; SAVE THE POINTER.
PIOGB2:	POP	HL		; USER REGS. BACK
	POP	DE
	POP	AF
	LD	SP,(USRSK3)
	EI			; BACK FROM INTERRUPT.
	RETI

	PAGE
;**********************************************************
;*                    OTHER TABLES                        *
;**********************************************************
; NOTE: THE SIO1-TABLES ARE PATCHES FROM THE LOADER IN
;       BOOT.Z80-MODULE. 
;       IT VERY IMPORTANT THAT SIZE AND ORDER IN THIS
;       TABLES NOT ARE ALTERED.

SI1ATBL:			; MODEM/AUX/PRINTER.
	DEFB	3,CTC0		; 3 BYTES TO CTC CHAN 0
	DEFB	01000101B	; CTC0: INT. DIS, COUNTER MODE,
				; NEG. EDGE, TIME CONST. FOLLOWS,
				; COUNTING CONT.
BAUDA:	DEFB	4		; GIVES 307200 Hz TO SIO1A
CTCVEC:	DEFS	1		; CTCINTERRUPTVECTOR.

	DEFB	9,SIO1AC	; 9 BYTES TO SIO1 A/MODEM
	DEFB	18H		; RESET CHANNEL.
	DEFB	14H		; WR 4:
CLKA:	DEFB	10000100B	; x32 CLOCK, 1 STOP BIT, NO PARITY.
	DEFB	13H		; WR 3:
	DEFB	11100001B	; Rx 8 BITS, AUTO ENABL., Rx ENABLE.
	DEFB	15H		; WR 5:
	DEFB	11101010B	; DTR, Tx 8 BITS, Tx ENABLE, *RTS LOW.
	DEFB	01		; WR 1:
	DEFB	00000000B	; NO INTERRUPTS, UNMODIFIED INTERRUPT
				; VECTOR (BOTH CHANNELS).
	DEFB	0		; END TABLE.

SI1BTBL:
	DEFB	2,CTC1		; 2 BYTES TO CTC CHAN 1
	DEFB	01000101B	; CTC1: INT. DIS, COUNTER MODE,
				; NEG. EDGE, TIME CONST. FOLLOWS,
				; COUNTING CONT.
BAUDB:	DEFB	4		; GIVES 307200 Hz TO SIO1B.

	DEFB	11,SIO1BC	; 11 BYTES TO SIO1 B/TERMINAL
	DEFB	18H		; RESET CHANNEL
	DEFB	12H		; WR 2:
SIOVEC:	DEFS	1		; INTERRUPTVECTOR
	DEFB	14H		; WR 4:
CLKB:	DEFB	10000100B	; x32 CLOCK, 1 STOP BIT, NO PARITY
	DEFB	13H		; WR 3:
HANDSH:	DEFB	11000001B	; Rx 8 BITS, Rx ENABLE.
	DEFB	15H		; WR 5:
	DEFB	11101010B	; DTR, Tx 8 BITS, Tx ENABLE, *RTS LOW
	DEFB	01		; WR 1:
	DEFB	00011100B	; INT ON ALL Rx CHAR (PARITY DOES NOT
				; AFFECT VECTOR), STATUS AFFECTS VECTOR.
	DEFB	0		; END TABLE.

	PAGE

; PIO PORT A INIT TABLE

PIOTBL:	DEFB	2,PIOAC		; 2 BYTES TO PIO A CTLR-REG.
	DEFB	00001111B	; SELECT MODE 0 OPERATION
	DEFB	00000011B	; INTERUPT DISABLE.

; PIO PORT B INIT TABLE

	DEFB	4,PIOBC		; 4 BYTES TO PIO B CTRL-REG.
	DEFB	11001111B	; SELECT MODE 3 OPERATION
	DEFB	00101111B	; BIT 7,6,4=OUTPUT ALL OTHERS INPUTS
	DEFB	00110111B	; INTERRUPT CONTROL WORD = DISABLED
	DEFB	00000001B	; MASK WORD, ONLY MONITOR BIT 0.

; SET PIO A BUFFER FOR OUTPUT

	DEFB	1,PIOBD		; 1 BYTE TO PIO B  DATA
	DEFB	01010000B

; REAL TIME CLOCK INITIALIZATION TABLE

	DEFB	2,CTC2		; 2 BYTES TO CTC CHAN 2
	DEFB	01000101B	; CTC2: INT. DIS, COUNTER MODE,
				; NEG. EDGE, TIME CONST. FOLLOWS,
				; COUNTING CONT.
	DEFB	0		; GIVES 4800 Hz TO CTC3.


	DEFB	2,CTC3		; 2 BYTES TO CTC CHAN 3.
	DEFB	11000101B	; INT. ENABLED, COUNTER MODE
				; NEG. EDGE, TIME CONST. FOLLOWS,
				; COUNTING CONT.
	DEFB	240		; GIVES 20 Hz, WHICH IS DIVIDED
				; BY 2 (HARDWARE).
				; INERRUPT 10 times/second.
	DEFB	0		; END TABLE.

; INIT. GRAPHIC TERMINAL

PIOGTBL:
	DEFB	3,PIOGAC	; BYTES TO PIOGA CONTROL
PIAVEC:	DEFS	1		; VECTOR FOR A
	DEFB	00001111B	; OUTPUT ONLY. MODE 0
	DEFB	10000111B	; ENABLE INTERRUPT.

	DEFB	3,PIOGBC	; BYTES TO PIOGB CONTROL
PIBVEC:	DEFS	1		; VECTOR FOR B
	DEFB	01001111B	; INPUT ONLY. MODE 1
	DEFB	10000111B	; ENABLE INTERRUPT

	DEFB	0		; END TABLE.
	PAGE

USRSK2:	DEFS	2		; USER STACK SAVED HERE
	DEFS	10H		; LOCAL STACK.
OWNSK2	EQU	$
USRSK3:	DEFS	2
	DEFS	10H
OWNSK3	EQU	$


RNGCNT:	DEFB	0		; NO OF CHAR IN BUFFER
RNGIN:	DEFW	RNGBEG		; POINTS TO INPUT PLACE
RNGOUT:	DEFW	RNGBEG		; POINTS TO OUTPUT PLACE
				; IF EQU BUFFER IS EMPTY.
RNGBEG:	DEFS	22		; KEYBOARD RING BUFFER.
RNGEND	EQU	$-1


GRSCNT:	DEFB	0FFH		; GRAPHIC OUTPUT STATUS COUNTER (0FF=READY)
GRCNT:	DEFB	0		; NO OF CHAR IN GRAPHIC RING BUFFER
GRNIN:	DEFW	GRNBEG		; POINTER TO GRAPHIC INPUT PLACE
GRNOUT:	DEFW	GRNBEG		; POINTER TO GRAPHIC OUTPUT PLACE
GRNBEG:	DEFS	22		; GRAPHIC RING BUFFER
GRNEND	EQU	$-1
	END
«eof»