; PUNCH.ASM: SIMPLE PORT-TO-PORT TRANSFER WITH FIFO
; DELIBERATELY BRIEF FOR FRONT PANEL TOGGLING
; VERS. 1.1 MARTIN EBERHARD 1 DECEMBER 2010
;
; THIS PROGRAM READS A BINARY FILE FROM 2SIO PORT 1
; AND WRITES IT TO PAPER TAPE AT 2SIO PORT 0.
; PORT 1 IS SET FOR 1 STOP BIT; PORT 0 IS SET FOR 2.
; PORT BUAD RATES ARE SET IN HARDWARE ON THE 2SIO.
; PORT 1 USES RTS/CTS FLOW CONTROL.
; INPUT DATA IS STASHED IN A 256-BYTE FIFO, WITH HIGH-
; WATER MARK AT 128 BYTES, AND LOW-WATER MARK AT 21 BYTES.
; THIS PROGRAM RUNS AT 100H. ITS FIFO IS AT 300H-3FFH.
;
; OPERATION:
;   TOGGLE-IN PROGRAM
;   RUN PROGRAM AT 100H
;   SET TELETYPE TO "LOCAL" AND TURN PUNCH ON
;   PRESS "HERE IS" A FEW TIMES TO MAKE A LEADER
;   SET TELETYPE TO "LINE"
;   SEND FILE (USING EXTERNAL MACHINE) TO PORT 1
;   WAIT FOR FILE TRANSFER TO COMPLETE AND PUNCHING TO END
;   SET TELETYPE TO "LOCAL"
;   PRESS "HERE IS" A FEW TIME TO MAKE A TRAILER
;   TURN OFF PUNCH

; 2SIO REGISTER EQUATES

A0CTRL	EQU	10H	;ACIA 0 CONTROL OUTPUT PORT
A0STAT	EQU	10H	;ACIA 0 STATUS INPUT PORT
A0TDR	EQU	11H	;ACIA 0 TX DATA REGISTER
A0RDR	EQU	11H	;ACIA 0 RX DATA REGISTER
A1CTRL	EQU	12H	;ACIA 1 CONTROL OUTPUT PORT
A1STAT	EQU	12H	;ACIA 1 STATUS INPUT PORT
A1TDR	EQU	13H	;ACIA 1 TX DATA REGISTER
A1RDR	EQU	13H	;ACIA 1 RX DATA REGISTER

; ACIA CONTROL REGISTER BITS

ACCDS1	EQU	00000001B	;COUNTER DIVIDE SEL 1
ACCDS2	EQU	00000010B	;COUNTER DIVIDE SEL 2
ACWS1	EQU	00000100B	;WORD SELECT 1
ACWS2	EQU	00001000B	;WORD SELECT 2
ACWS3	EQU	00010000B	;WORD SELECT 3
ACTC1	EQU	00100000B	;TX CONTROL 1
ACTC2	EQU	01000000B	;TX CONTROL 2
ACRXIE	EQU	10000000B	;RX INT ENABLE

ACRSET	EQU	00000011B	;MASTER RESET

;COMPOUND ACIA COMMANDS

AC0INIT	EQU	ACCDS1+ACWS3	;/16 CLOCK, 8 BITS+2 STOP
AC0REN	EQU	AC0INIT+ACTC2	;MAKES RTS ACTIVE
AC1INIT	EQU	ACCDS1+ACWS1+ACWS3 ;/16 CLK, 8 BITS+1 STOP
AC1CTS	EQU	AC1INIT+ACTC2	;MAKES RTS INACTIVE

; ACIA STATUS REGISTER BITS

ASRDRF	EQU	00000001B	;RX DATA REG FULL
ASTDRE	EQU	00000010B	;TX DATA REG EMPTY
ASDCD	EQU	00000100B	;DATA CARRIER DETECT
ASCTS	EQU	00001000B	;CLEAR TO SEND
ASFE	EQU	00010000B	;FRAMING ERROR
ASOVRN	EQU	00100000B	;RX OVERRUN ERROR
ASPE	EQU	01000000B	;PARITY ERROR
ASIRQ	EQU	10000000B	;INTERRUPT REQUEST

; PROGRAM EQUATES

FIFO	EQU	ACRSET*256	;BUFF ADDR AND RESET CMD

ORG 100H

; INITIALIZE 256-BYTE FIFO

	LXI	D,FIFO	;DE IS OUTPUT POINTER
	MOV	H,D		;HL IS INPUT POINTER
	MOV	L,E
	MOV	C,E		;BYTE COUNT=0

; INITIALIZE BOTH ACIAS

	MOV	A,H		;BUF ADDR HIGH BYTE IS ALSO RESET
	OUT	A0CTRL
	OUT	A1CTRL

	MVI	A,AC0INIT
	OUT	A0CTRL

; MAIN LOOP - 2 ENTRY POINTS

MAIN0:	INR	C		;C HAS BYTE COUNT+1

MAIN1:	MVI	A,AC1INIT	;ENABLE RS232 CMD

	CMP	C		;AC1INIT IS ALSO LOW-WATER MARK
	JC	CHKIN

	OUT	A1CTRL		;RE-ENABLE RS232-IN

;GET ANY PENDING RS232 DATA AND PUT IT IN THE FIFO

CHKIN:	IN	A1STAT		;RX DATA REG FULL?
	RRC			;ASRDRF IS BIT 0
	JNC	CHKOUT		;NO RS232 DATA NOW

	IN	A1RDR		;GET INPUT BYTE
	MOV	M,A		;STASH BYTE IN FIFO
	INR	L		;BUMP FIFO POINTER

	INR	C		;BUMP BYTE COUNT
	JP	NOCTS		;HIGH WATER: 128 BYTES

	MVI	A,AC1CTS	;DE-ASSERT CTS
	OUT	A1CTRL
NOCTS:

; SEND A FIFO BYTE TO THE PUNCH IF IT'S READY

CHKOUT:	IN	A0STAT		;TX DATA REG EMPTY?
	RRC			;ASTDRE IS BIT 1
	RRC
	JNC	CHKIN		;TDR STILL FULL

	DCR	C		;ANY BYTES IN FIFO?
	JZ	MAIN0		;NO: GO UNDO DCR C

	LDAX	D		;GET A FIFO BYTE
	OUT	A0TDR		;SEND BYTE TO PUNCH
	INR	E		;BUMP FIFO POINTER

	JMP	MAIN1		;GO CHECK INPUT
	
	END
