

;
; This 16c57 prog can emulate an 16c84 using PICSim. PICEmu
; is connected direct with the RS232 port. (using 10K for
; the AMIGA TXD line). PortA and PortB are used for emulating
; the 16c84. portC is used for the serial connection. The
; communication speed is 38400 Baud @ 11.0592 Mhz clock.
;
;
; © Dirk Duesterberg, 14.12.1997
;
; duesterb@unixserv.rz.fh-hannover.de
; http://linux.rz.fh-hannover.de/~duesterb
;




;commands = 0x5x
;
;18 pin PIC Emulator soft for 16c57
;
;command0 = set tris RA, 1->, 1->
;command1 = set tris RB, 1->, 1->
;
;command4 = write RA,    1->, 1<-, 1->
;command5 = write RB,    1->, 1<-, 1->
;
;command8 = read RA,     1->, 1<-
;command9 = read RB,     1->, 1<-
;
;



		list	p=16c57





#define	c	03h,0			;carry bit
#define	dc	03h,1			;digit carry bit
#define	z	03h,2			;zero bit
#define	pd	03h,3			;power down bit
#define	to	03h,4			;time out bit
#define	pa0	03h,5			;page select bit (for '56 and '57 only)
#define	pa1	03h,6			;page select bit (for '57 only)


pc	=	02h			;program counter

RA	=	05h			;port a
RB	=	06h			;port b
RC	=	07h



#define	RXD	RC,1
#define	TXD	RC,2

#define beta

ram	=	08h			;begin of ram adress

	CBLOCK	ram			;constant block beginning

	  count0
	  count1

	  delaycntr
	  bitcntr
	  serdata
	  serbuf
	  charcounter
	ENDC				;end of block




clockspeed	=	.11059200			;clockspeed is 11.0592 Mhz
baudrate	=	.38400				;19200		;enter baudrate here


delay		=	(clockspeed/.4/baudrate-.12)/.4	;value for baudrate, 12 cycles fixed, 4 cycles delay


start		movlw	02h
		tris	RC
		movlw	0
		movwf	RC


:loop		decfsz	count0		;power up timer
		goto	:loop
		decfsz	count1
		goto	:loop



		movlw	'R'
		movwf	serdata
		call	send_byte



		movlw	'S'
		movwf	serdata
		call	send_byte




		movlw	'T'
		movwf	serdata
		call	send_byte






loop		movlw	0f0h
		andwf	serdata,w
		xorlw	050h		;data = 50h ?
		btfss	z
		goto	loop		;no match
		

		movf	serdata,w
		andlw	0fh		;clear upper nibble
		addwf	pc		;jumptable

		goto	command0	;write RA tristate register
		goto	command1	;write RB tristate register
		goto	command2	;write RC tristate register (not used)
		goto	command3
		goto	command4	;write RA latch
		goto	command5	;write RB latch
		goto	command6	;write RC latch  (not used)
		goto	command7
		goto	command8	;read RA pins
		goto	command9	;read RB pins
		goto	commandA	;read RC pins
		goto	commandB
		goto	commandC
		goto	commandD
		goto	commandE	
		goto	commandF	;version info





command0	call	receive_byte
		movf	serdata,w
		tris	RA
		goto	loop


command1	call	receive_byte
		movf	serdata,w
		tris	RB
		goto	loop



command2	goto	start
command3	goto	start


command4	movf	RA,w
		movwf	serdata
		call	send_byte	;send read data back (ACKnowledge)

		call	receive_byte
		movf	serdata,w
		movwf	RA

		goto	loop




command5	movf	RB,w
		movwf	serdata,w
		call	send_byte	;send read data back (ACKnowledge)

		call	receive_byte
		movf	serdata,w
		movwf	RB
	
		goto	loop



command6

command7	goto	start

command8	movf	RA,w		;read port
		movwf	serdata
		call	send_byte	;send read data back (ACKnowledge)
		goto	start

command9	movf	RB,w		;read port
		movwf	serdata
		call	send_byte	;send read data back (ACKnowledge)
		goto	loop

commandA	movlw	0aah
		movwf	serdata
		call	send_byte
		goto	loop




commandB
commandC
commandD
commandE	goto	start

commandF	clrf	charcounter
:loop		call	string
		andlw	0ffh
		btfsc	z
		goto	loop		;return to start if zero byte

		movwf	serdata		;move character to serial buffer
		call	send_byte
		incf	charcounter	;next character
		goto	:loop





string		movf	charcounter,w
		addwf	pc,f		;jump table with string followed by a zero byte. 


		ifdef	beta

		  space	2		;2 blank lines to listfile
		  messg "beta Version"	;message to listfile
		  space	2

		  retlw	"PIC 16c84 EMU beta version, bla, bla, bla",0ah,0ah	;string, two linefeeds

		else

		  space	2		;2 blank lines to listfile
		  messg "test Version"	;message to listfile
		  space	2

		  retlw	"PIC 16c84 EMU version 0.9",0ah,0ah	;string, two linefeeds

		endif


		retlw	0dh,0		;one cr, Zerobyte => stop sending








send_byte	bsf	TXD		;set TXD line, dirct connection
		movlw	8h		;Eight bits in a byte. 
		movwf	bitcntr

		call	bitdelay	;Start bit. ((delay * 4) + 4) cycles

xmit		rrf	serdata,f	;Rotate right moves data bits into
					;carry, starting with bit 0. 

		btfsc	c		;clear TXD if carry bit is set
		bcf	TXD		
		btfss	c		;set TXD if carry bit is clear
		bsf	TXD



		call	bitdelay	;Data bit.

		decfsz	bitcntr,f	;Not eight bits yet? Send next data bit
		goto	xmit

		bcf	TXD		;clear TXD
		rrf	serdata,f	;last rotation


		call	bitdelay	;Stop bit. ((delay * 4) + 4) cycles

		retlw	0



receive_byte	btfss	RXD
		goto	receive_byte	;wait until startbit

		movlw	8h		;Eight bits in a byte. 
		movwf	bitcntr

		call	halfbitdelay	;wait half bit


rcb		call	bitdelay	;wait one bit

		btfsc	RXD		;clear c if RXD is set
		bcf	c		
		btfss	RXD		;set c if RXD is clear
		bsf	c

		rrf	serdata,f

		decfsz	bitcntr,f	;Not eight bits yet? Receive next data bit
		goto	rcb

		call	halfbitdelay	;wait one half bit to get out of data area

		retlw	0


; To change the baud rate, substitute a new value for bitdelay at the beginning of
; this program. 



bitdelay	movlw	delay		;this bitdelay delays ((delay * 4) + 4) cycles
		movwf	delaycntr
:loop		nop
		decfsz	delaycntr,f
		goto	:loop		;this is an local loop
		retlw	0



halfbitdelay	movlw	delay/2 +1		;this bitdelay delays ((delay * 4) + 4)/2 cycles
		movwf	delaycntr
:loop		nop
		decfsz	delaycntr,f
		goto	:loop		;this is an local loop
		retlw	0




		org	7ff
		goto	start
