;*BM
;	$Header: appacc.m65,v 1.8 88/12/22 09:17:48 medin Locked $
;********************************
;*                              *
;*  APPLE COMMUNICATIONS CARD   *
;*     DRIVER FOR KERMIT 3      *
;*                              *
;*   VERSION MODIFICATIONS BY   *
;*         I. CHUANG            *
;*                              *
;*    LAST DATE: 29/JULY/86     *
;*                              *
;$Log:	appacc.m65,v $
;Revision 1.8  88/12/22  09:17:48  medin
; Use the time count for the wait routine

;Revision 1.7  88/03/28  13:24:16  medin
; Correct bug in flow control.

;Revision 1.6  88/01/15  08:42:57  medin
;New origin for 3.81

;Revision 1.5  87/06/29  10:47:49  medin
; Change wait rtn to use apple rom wait, change org for 3.78.

;Revision 1.4  87/05/13  18:08:21  medin
; Change org to correspond with 3.76

;Revision 1.3  87/02/20  23:50:42  medin
; Put version in the hearld so we can keep track of the com drivers
;also. Thanks Rhoda.

;DONT FORGET TO UPDATE THE VERSION
;Revision 1.2  86/12/22  10:49:26  medin
; New initialization from Ike. The acc now initializes itself internally
;and doesnt require the "IN#?" to start the card up. Thanks to Ike for the
;latest and for Rhoda for testing it.

;Revision 1.1  86/10/28  10:35:15  medin
;Initial revision

;********************************

 ORG $1003 ; START DEFINITIONS AT $1003

;*   VECTOR FOR COM CARDS STARTS HERE
;*       LOCATION $1003 FOR DATA
;*       LOCATION $1020 FOR ROUTINE JUMPS
;*       LOCATION $1040 FOR MAIN ROUTINES

SSCDBD .blkb 1 ;CONT BAUD INDEX(ALA SUPER SERIAL CARD) USED BY

;*             INIT
;*             6 - 300 BAUD
;*             7 - 600
;*             ECT.

 .blkb 1
CRDNAM .word HERLD
KERSLI .blkb 1 ; COM SLOT $N0
KERINS .blkb 1 ; FORCE INITIALIZATION FLAG-WHEN 0
ENDKER .blkb 2 ; ADDRESS OF END OF MAIN KERMIT
FLOWFG .blkb 1 ;FLOW CTRL (XON/OFF) FLG TRUE WHEN HI BIT SET
tl0end	.word	endcom	;[1.6] end of this routine
timect	.blkb	1	;[1.8] 1 ms delay via rom wait rtn
 ORG SSCDBD+29 ;FUTURE EXPANSION
 JMP TL2INT ; INITIALIZE COM CARD
 JMP TL2CMD ; COMMAND FOR ACIA IN A

;*    0 - HANG UP
;*    $0B - SET BAUD
;*    $0C - SET BREAK ON THE LINE
;*    $91 - XON
;*    $93 - XOFF
;*    ROUTINE WILL RETURN FALSE(0) IF UNABLE

 JMP TL2CP ; CHECK FOR INPUT CH READY-0 FALSE
 JMP TL2GPC ; GET INPUT CH
 JMP TL2PPC ; PUT OUTPUT CHARACTER
 JMP TL2EXI ; RESET CARD AND RESTORE INITIALIZED

 ORG SSCDBD+29+32 ; FUTURES
;[1.5]WAIT .blkb 3 ; WAIT ROUTINE-A REG CONTAINS MILLISECONDS
WAIT .blkb 3 ; WAIT ROUTINE-apple rom rtn 220=125ms,198=100ms,25=2ms ...
PRSTR .blkb 3 ; PRINT STRING-X=LSB,Y=MSB OF NULL TERMINATED STRING
URDKEY .blkb 3 ; READ KEYBOARD
PRCRLF .blkb 3 ; PRINT CR AND LF
TELCNC .blkb 3 ;CHECK FOR KEYBOARD CHARACTER
TELSPA .blkb 3 ;SET CHARACTER PARITY

;********************************
;* MAIN CODE STARTS HERE

 ORG $7f00	;[1.9]
START = *

CR = $D ; <CR>
APINC1 = $3 ; FIRST INIT CHAR FOR 6850 ACIA
APINC2 = $11 ; SECOND INIT (8-BITS)
HCTRLQ = $91 ;^Q WITH HIGH BIT SET
HCTRLS = $93 ;^S  "
HCTRLZ = $9A ;^Z  "
CTRLQ = $11 ; ^Q
CTRLS = $13 ; ^S
CSWL = $36
CSWH = $37
INITKR0 = $15
MSTRINI = $03 		; initialize the acia control register

IRQL = $3FE
IRQH = $3FF
RDKEY = $FD0C ; READ A CH FROM CURRENT INPUT DEVICE
COUT = $FDED ; PRINT A CH TO CURRENT OUTPUT DEVICE
SETIO2 = $FE93 ; PLACE FOR PR#0
KR0PCH = $C08F ; BASE FOR PORT CHAR LOCATION
KR0PST = $C08E ; BASE FOR PORT STROBE LOCATIONS
KBD = $C000 ; KEYBOARD CHARACTER INPUT LOCATION

TEMP .byte 00 ; WORK SPACE FOR DIAL
PINPTR .byte 00 ; INPUT BUFFER POINTER
INPTR .byte 00 ; INPUT BUFFER POINTER FOR GET
POUTPT .byte 00 ; OUTPUT BUFFER POINTER
OUTPTR .byte 00 ; " "  " FOR PUT
KSLI .byte 00 ; COM SLOT $0N
DCH:CR .byte 00 ; SAVE AREA FOR CONTROL REGISTER
kwrk01	.byte	1	;[1.8]

;********************************
;* NOW THE ASCII MESSAGES

HERLD nasc <APPLE COMM CARD V1.9> 1
BAD nasc <*****ERROR***** COM ROUTINES ASSEMBLED TOO LOW IN MEMORY> 1
DIALM2 nasc <AWAITING CARRIER....(ANY KEY ABORTS)> 1
DIALM3 nasc <CONNECTED.> 1

;********************************
;* MAIN INIT: CHECK LOAD LOC OK

TL2INT LDA #START^
 CMP ENDKER+1 ;ARE WE LOADED ABOVE MAIN
 BEQ DONTNO ;CANT TELL YET
 BCC TRBLE ;YES WE ARE IN TROUBLE
 BCS SETNM ;OK
DONTNO LDA #START\ ;WELL LETS CHECK 16 BITS
 CMP ENDKER
 BEQ SETNM ;WHEE JUST EXACTLY RIGHT
 BCS SETNM ;OK
TRBLE LDX #BAD\ ;GOT TO TELL SOMEONE
 LDY #BAD^
 JSR PRSTR ;PRINT THE MESSAGE
 JSR PRCRLF ;AND TERMINATE IT PROPERLY
 JMP $3D0

;********************************
;* SET THE INTERRUPT VECTOR

SETNM LDA #IRQHND
 STA IRQL
 LDA #IRQHND^
 STA IRQH
 lda	KERSLI ; CALCULATE $0N FROM $N0
 LSR A
 LSR A
 LSR A
 LSR A
 STA KSLI ; NOW WE HAVE $0SLOT
;		TAX		; slot index to x reg
		ldx	KERSLI		; get proper slot format
		LDA	#MSTRINI	; load the new master init code
		STA	KR0PST,X	; send it
		LDA	#INITKR0	; get the operating code
		STA	KR0PST,X	; send it

;********************************
;* CHECK FOR CARRIER

 LDX KERSLI ; GET DEVICE SLOT
 LDA KR0PCH,X ; ACCESS DATA
 LDA KR0PST,X ; NOW FOR THE STATUS
 AND #4 ; DO WE HAVE A CARRIER?
 BNE DOINIT ; YES,CARRY ON
 LDA #INITKR0
 STA DCH:CR
 STA KR0PST,X
 LDA #1 ; GIVE TRUE RETURN
 RTS ; ONLY WAY TO REACH THIS

;********************************
;* NO CARRIER FOUND, SO DO INIT

DOINIT LDX #DIALM2\ ; NOW FOR THE WAITING MSG
 LDY #DIALM2^
 JSR PRSTR ; PRINT IT
 LDX KERSLI ; THE SLOT AGAIN
 LDY KSLI ; SLOT*16
 LDA #INITKR0
 STA DCH:CR
 STA KR0PST,X
TLINI8 BIT KBD ; DO WE HAVE A CH FROM THE KEYBOARD
 BPL TLINI7 ; NO, TRY FOR CARRIER
 JSR RDKEY ; LETS DO THIS RIGHT
 LDA #0 ; GIVE A FALSE RETURN (0)
 RTS ;GIVE A FALSE RETURN (0)
TLINI7 LDA KR0PCH,X ; THE DATA
 LDA KR0PST,X ; AND NOW THE STATUS
 AND #4 ; CARRIER?
 BNE TLINI8 ; NOT YET TRY AGAIN
 JSR PRCRLF ;
 LDX #DIALM3\ ; TELL WE GOT CARRIER
 LDY #DIALM3^
 JSR PRSTR ;
 JSR PRCRLF ;
 LDA #0 ;START THE BUFFER AT 0
 STA PINPTR
 STA INPTR
 STA POUTPT ; "
 STA OUTPTR ; "
 LDA #1 ; GIVE A TRUE RETURN (NON 0)
 RTS ; FINALLY

TL2CP
 LDX KERSLI ; OFFSET INTO I/O LOCATIONS
TL0CP1 LDA KR0PST,X ; TRY FOR A CHARACTER
 AND #$01 ; CHECK FOR RECEIVE REGISTER FULL
 BEQ TL0CP7
 LDA KR0PCH,X ; GET CH
 LDY PINPTR ; GET PLACE TO STORE
 STA INBUF,Y ; IN BUF
 INC PINPTR ; READY FOR NEXT
 BIT FLOWFG ; HOW ABOUT FLOW CONTROL
 BPL TL0CP7 ; NO
 LDA INBUF,Y ; GET INPUT CH
 AND #$7F ; DROP PARITY ETC
; BVC TL2CP4 ; YES,HOW ABOUT ^S RECEIVED?, NO
 CMP #CTRLQ ; IS THIS CONTINUE(START UP OUTPUTING)
 BNE TL2CP4 ; NO, CHECK FOR ^S
 LDA FLOWFG ; TATTLE ABOUT THE CONTINUE
 AND #$BF ;
 STA FLOWFG ;
 DEC PINPTR ; FORGET ABOUT THIS CHARACTER
TL2CP2 LDY OUTPTR ; SEE IF ANY TO OUTPUT
 CPY POUTPT ; WELL?
 BEQ TL0CP7 ; NO MORE WE HAVE PUT ALL
TL2CP3 LDA KR0PST,X ; CHECK STATUS FOR OUTPUT
 AND #$10 ; READY?
 BEQ TL2CP3 ; NO, SPIN
 LDA OUTBUF,Y ; OUTPUT CH
 STA KR0PCH,X ; BYE
 INC OUTPTR ; READY FOR NEXT
 JMP TL2CP2 ;
TL2CP4 CMP #CTRLS ; IS THIS STOP?
 BNE TL0CP7 ; NO
 LDA #$40 ; YES, TATTLE
 ORA FLOWFG ;
 STA FLOWFG ; NOW EVERYONE KNOWS
 DEC PINPTR ; FORGET ABOUT THE ^S CHARACTER
TL0CP7
 LDA PINPTR
 CMP INPTR
;*; NO CHARACTER, RETURN FALSE(ZERO)
;*; SUCCESSFUL RETURN, RETURN TRUE(NON 0)
 RTS ; ..

TL2GPC
 LDX INPTR ;GET WHERE THE CH IS
 LDA INBUF,X ;GET CH
 INC INPTR
TL0RTC RTS ; AND RETURN

TL2PPC
 PHA ; HOLD THE BYTE TO SEND
 LDX KERSLI ; GET I/O LOCATION OFFSET
TL0PP1 LDA KR0PST,X ; GET THE STATUS BYTE
 AND #$02 ; ISOLATE THE FLAG WE WANT (TRE)
 BEQ TL0PP2 ; TRANSMIT REGISTER IS NOT EMPTY, TRY AGAIN
 BIT FLOWFG ; FLOW CONTROL?
 BPL TL2PP0 ; NO
 BVC TL2PP0 ; SHOULD WE STOP OUTPUTING?,NO
 LDY POUTPT ; YES, SAVE THIS CH IN BUFFER
 PLA
 STA OUTBUF,Y ;
 INC POUTPT ; TELL HOW MANY
 RTS ; THATS ALL
TL2PP0 ;
 PLA ; FETCH THE DATA BYTE OFF THE STACK
 STA KR0PCH,X ; STUFF IT AT THE PROPER LOC TO SEND IT
 RTS ; AND RETURN
TL0PP2 JSR TL0CP1 ;GO CHECK FOR AN INPUT CH
 JMP TL0PP1 ;TRY OUTPUT AGAIN

TL2EXI
EXIT9 RTS

TL2CMD ;FIND OUT WHAT COMMAND
 BEQ TL0DRP ;ITS D
 CMP #$0C
 BEQ BREAK
 CMP #$B
 BEQ TL2RTS
 CMP #HCTRLQ
 BEQ TL2SAC
 CMP #HCTRLS
 BEQ TL2SAC
TL2FLS LDA #0
TL2RTS RTS
TL2SAC	;[1.7] LDA FLOWFG ; DO WE HAVE FLOW CONTROL?
	;[1.7] BPL TL2FLS ; NO RETURN FALSE
 AND #$7F
 JSR TELSPA ; SET PARITY
 JSR TL2PPC ; OUTPUT CHAR
 LDA #1
 RTS ; TRUE RETURN
TL0DRP LDX KERSLI
;*STA KR0PCC,X ; SHUT IT DOWN
 LDA #1
 RTS
BREAK LDY KERSLI ; GET SLOT*16
 LDA DCH:CR ; GET SAVED CTRL REG
 ORA #$60 ; SET BREAK FLAG
 STA KR0PST,Y
;[1.5] LDA #233 ; WAIT FOR 233 MS
;[1.8]	lda	#220	;[1.5] wait 125 ms
	lda	#233	;[1.8] wait 233 ms
	sta	kwrk01	;[1.8]
break3	lda	timect	;[1.8] 1 ms at a time
 JSR WAIT
	dec	kwrk01	;[1.8]
	bne	break3	;[1.8]
;[1.8]	lda	#206	;[1.5] wait 108 ms for a total of 233ms
;[1.8]	jsr	WAIT	;[1.5]
 LDA DCH:CR ; GET SAVED CTRL REG AGAIN
 AND #$9F
 LDY KERSLI
 STA KR0PST,Y ; STOP BREAK SIGNAL
 RTS

;********************************
;* IRQ HANDLER

IRQHND LDA $45
 RTI

;********************************
;* BUFFERS

INBUF .blkb 256 ; INPUT BUFFER
OUTBUF .blkb 256 ; OUTPUT BUFFER
endcom			;[1.6]
