;
;  CREATED BY ACKMAN	APPE V3c.0
;
;  ADAPTADOR DE MANDO DE PSX PARA AMIGA CON EMULACION DE PAD CD32
;  PROCESADOR PIC16F84/10 MHZ
;
;bug en la rutina de comunicacion con el pad solucionado...
;
		DEVICE 16C84, XT_OSC, PROTECT_OFF, WDT_OFF

;  LITERALS

;  REGISTROS
TX_D		EQU	0X10	;CONTIENE EL BYTE A TRANSMITIR AL PAD PSX
OUT		EQU	0X11	;CONTIENE EL BYTE A PONER EN EL JOYSTIC DE AMIGA EN MODO NORMAL
FLAG		EQU	0X12	;REGISTRO DE FLAG INTERNOS DEL PROGRAMA
CONT3		EQU	0X13	;CONTADOR GENERICO 3
CONT2		EQU	0X14	;CONTADOR GENERICO 2
CONT1		EQU	0X15	;CONTADOR GENERICO 1
CD32TX		EQU	0X16	;CONTIENE EL DATO A TRANSMITIR AL AMIGA EN MODO CD32
BYTE2		EQU	0X17	;CONTIENE EL SEGUNDO BYTE UTIL RECIBIDO DEL PAD PSX
BYTE1		EQU	0X18	;CONTIENE EL PRIMER BYTE UTIL RECIBIDO DEL PAD PSX
BYTE		EQU	0X19	;CONTIENE EL BYTE QUE SE ESTA RECIBIENDO DEL PAD PSX
ALMACENS	EQU	0X1A	;CONTIENE EL VALOR DEL STATUS DURANTE LAS IRQ
ALMACENW	EQU	0X1B	;CONTIEN EL VALOR DE W DURANTE LAS IRQ
FIREVEL		EQU	0X1C	;CONTIEN LA VELOCIDAD DEL AUTOFIRE A MAS VALOR= MENOS VELOCIDAD
CD32TXB		EQU	0X1D 	;REGISTRO DE RESGUARDO DE VALOR A TRANSMITIR EN MODO CD32

; PORTA
DATA		EQU	0X00	;PIN 17		ENTRADA DE DATOS DEL PAD PSX
COMM		EQU	0X01	;PIN 18		SALIDA DE DATOS AL PAD PSX
CLK		EQU	0X02	;PIN 1		SALIDA DE SINCRONISMO AL PAD
ATT		EQU	0X03	;PIN 2		SALIDA DE ENABLE AL PAD, PARA LLAMAR SU ATENCION
ACK		EQU	0X04	;PIN 3		ENTRADA DE RECONOCIMIENTO DEL PAD

; PORTB				        MODO	NORMAL		CD32
FIRE2		EQU	0X00	;PIN 6		NO USE		ENABLE CD32
UP		EQU	0X01	;PIN 7		UP		--
LEFT		EQU	0X02	;PIN 8		LEFT		--	
DOWN		EQU	0X03	;PIN 9		DOWN		--
RIGHT		EQU	0X04	;PIN 10		RIGHT		--
FIRE1		EQU	0X05	;PIN 11		FIRE 1		DATA OUT
FIRE0		EQU	0X06	;PIN 12		FIRE 1		CLOCK IN
NCONN		EQU	0X07	;PIN 13		--		--	
							


;
STATUS		EQU     3	; REGISTRO DE ESTADO
PORTA   	EQU     5	; REGISTRO DEL PUERTO A
PORTB   	EQU     6	; REGISTRO DEL PUERTO B
TRISA   	EQU     H'85'	; REGISTRO DE FUNCION PUERTO A 1=IN, 0=OUT
TRISB   	EQU     H'86'	; REGISTRO DE FUNCION PUERTO B 1=IN, 0=OUT
RP1     	EQU     6	; REGISTRO DE SELECCION DE BANCO, JUNTO CON RP0
RP0     	EQU     5	; IDEM RP1 00=B0, 01=B1, 10=B2, 11=B3
OPTION  	EQU     H'81'	; REGISTRO DE OPCIONES
INTCON		EQU	H'0B'	; REGISTRO DE ESTADO DE INTERRUPCIONES
Z		EQU	H'02'	; INDICADOR DE ZERO DE REGISTRO STATUS
C		EQU	H'00'	; INDICADOR DE ACARREO DE 8 BIT
DC		EQU	H'01'	; INDICADOR DE ACARREO DE LOS 4 BIT DE MENOS PESO
TMR0		EQU	H'01'	; REGISTRO DEL TEMPORIZADOR PRINCIPAL
;**** BITS DEL REGISTRO DE OPCIONES OPTION
RBPU		EQU 	7	;BIT DE CONEXION DE CARGAS PULL-UP PORTB (1=QUITADAS)
INTEDG		EQU	6 	;TIPO DE FLANCO DE INTERRUPCION EXTERNA (1= ASCENDENTE)
T0CS 		EQU	5	;FUENTE DE RELOG PARA TMR0 (1=EXTERNO)
T0SE		EQU	4	;TIPO DE FLANCO PARA TMR0 (1=DESCENDENTE)
PSA		EQU	3	;ASIGNACION DEL DIVISOR (1=WDT; 0=TMR0)
PS2		EQU 	2	;VALOR DEL PREDIVISOR
PS1		EQU	1	;
PS0		EQU	0	;
;**** BITS DEL REGISTRO DE INTERRUPCIONES INTCON
GIE		EQU	7	;BIT DE HABILITACION DE INTERRUPCIONES
PEIE		EQU	6	;BIT DE ACTIVACION DEL COMPARADOR
T0IE		EQU	5	;BIT ACTIVACION DE INTERRUPCION DE TMR0
INTE		EQU	4	;BIT ACTIVACION DE INTERRUPCION EXTERNA
RBIE		EQU	3	;BIT DE ACTIVACION DE PORTB
T0IF		EQU	2	;FLAG REBOSAMIENTO DE TMR0
INTF		EQU	1	;FLAG DE ESTADO INTERRUPCION EXTERNA
RBIF		EQU	0	;FLAG DE ESTADO INTERRUPCION PORTB

	NOP	
	CALL	PUERTOS
	CALL	DEFECTO
	GOTO	MAIN

CD32OUT:			;RUTINA DE ATENCION A IRQ
	MOVWF	ALMACENW	;GUARDA CONTENIDO DE W
	BSF	STATUS,RP0	;PONE FIRE0 COMO ENTRADA
	BSF	PORTB,FIRE0	;PONER FIRE0 COMO ENTRADA DE RELOG
	BCF	STATUS,RP0

WCLKE: 	BTFSC	PORTB,FIRE2	;ESPERA A QUE LA LINEA DE RELOG ESTE A 1
	GOTO	SALIR32		;Y COMPRUEBA QUE NO SE HAYA TERMINADO LA TRANSMISION
	BTFSS	PORTB,FIRE0
	GOTO	WCLKE	
	
TX32A:	BTFSS	CD32TX,0
	BCF	PORTB,FIRE1	;MANDA 0
	BTFSC	CD32TX,0
	BSF	PORTB,FIRE1	;MANDA 1
	RRF	CD32TX,F	;ROTA EL BYTE A MANDAR 

WCLKU:  BTFSC	PORTB,FIRE2	;ESPERA QUE LA LINEA DE RELOG ESTE A 0
	GOTO	SALIR32
	BTFSC	PORTB,FIRE0
	GOTO	WCLKU
        GOTO	WCLKE		;REPITE LA RUTINA

SALIR32:
	BSF	STATUS,RP0	;RESTABLECE F0 COMO SALIDA
	BCF	PORTB,FIRE0
	BCF	STATUS,RP0
;	MOVF	OUT,W		;COLOCA LOS DATOS EN LA SALIDA COMO ANTES DE LA IRQ
;	MOVWF	PORTB
	MOVF	CD32TXB,W	;RESTABLECE EL REGISTRO CD32TX, POR SI SE PRODUCE OTRA IRQ TEMPRANA
	MOVWF	CD32TX
	SWAPF	ALMACENW,F	;RESTAURA EL VALOR DE W COMO ANTES DE LA IRQ
	SWAPF	ALMACENW,W	;
	BCF	INTCON,INTF	;BORRA EL FLAG DE INTERRUPCION EXTERNA
	RETFIE

MAIN:
	CALL	PAD
	CALL	BIGDELAY
	CALL	BIGDELAY
	CALL	JOYOUT
	CALL	BIGDELAY
	CALL	PREP32
	CALL	BIGDELAY
	GOTO	MAIN

PAD:				;RUTINA DE LECTURA DE DATOS DEL PAD
	BCF	PORTA,ATT	;LLAMA LA ATENCION DEL PAD
	CALL	BIGDELAY	;ESPERA UN POCO
	MOVLW	0X01		;MANDA UN 01 AL PAD PARA RESETEARLO
	MOVWF	TX_D
	CALL	TX_RX
	CALL	BIGDELAY	;ESPERA OTRO POCO
	MOVLW	0X42		;MANDA UN 42 PARA PEDIR LOS DATOS DEL PAD
	MOVWF	TX_D
	CALL	TX_RX		; SIMULTANEAMENTE SE RECIBE EL TIPO DE PAD CONECTADO
				; 0X41=PAD DIGITAL/ 0X23=NEGCOM/ 0X73=ANALOGICO ROJO
				; 0X53=ANALOGICO VERDE/ 0X23=RATON PSX
				;**** PROXIMAMENTE SE DEBERIA HACER  COMPATIBILIDAD*****
	CALL	BIGDELAY	;ESPERA UN POCO
	CALL	TX_RX		; SE ENVIA UN DATO VACIO FF
				;SIMULTANEAMENTE SE RECIBE UN 0X5A INDICANDO QUE SE VA A TRANSMITIR
	CALL	BIGDELAY	;SE ESPERA OTRO POCO MAS
	CALL	TX_RX		;SE RECIBE EL PRIMER BYTE UTIL
	MOVF	BYTE,W
	MOVWF	BYTE1		;Y SE GUARDA EN EL REGISTRO BYTE1
	CALL	BIGDELAY	;OTRA PAUSA
	CALL	TX_RX		;SE RECIBE EL SEGUNDO BYTE UTIL
	MOVF	BYTE,W
	MOVWF	BYTE2		;Y SE GUARDA EN EL REGISTRO BYTE2
	CALL	BIGDELAY	;OTRA PEQUEÑA PAUSA
	BSF	PORTA,ATT	;SE DEJA LIBRE EL PAD, SE LE LIBERA DE ATENCION
	RETURN	




; CRONOCGRAMA DEL PROTOCOLO PARA MANDAR Y RECIBIR UN BYTE 
;        BIT0  BIT1  BIT2  BIT3  BIT4  BIT5  BIT6  BIT7
;clock---___---___---___---___---___---___---___---___------------
;data ---000000111111222222333333444444555555666666777777---------
;           *     *     *     *     *     *     *     *
;comm ---000000111111222222333333444444555555666666777777---------
;ack  ------------------------------------------------------___---
;        |-4µS-|

TX_RX:				;RUTINA QUE TRANSMITE Y RECIBE SIMULTANEAMENTE UN BYTE AL PAD
	MOVLW	0X08		;PONE EL NUMERO DE BIT A TRANSMITIR EN EL CONTADOR 3
	MOVWF	CONT3
LOOP_1:
	BCF	PORTA,CLK	;PONE A NIVEL BAJO LA LINEA DE RELOG
	BTFSC	TX_D,0		;PONE EL VALOR ADECUADO EN LA LINEA COMM
	BSF	PORTA,COMM
	BTFSS	TX_D,0
	BCF	PORTA,COMM
	RRF	TX_D,F		;ROTA EL BYTE A MANDAR
	RRF	BYTE,F		;ROTA EL BYTE A RECIBIR
	NOP			;ESPERA SIN HACER NADA AL MENOS 1.5 uS
	NOP
	NOP
	NOP
	NOP
	NOP	
	BCF	BYTE,7		
	BSF	PORTA,CLK	;PONE A UNO LA LINEA DE RELOG
	BTFSC	PORTA,DATA	;LEE EL DATO PRESENTE EN LA LINEA DATA
	BSF	BYTE,7
;	BSF	PORTA,CLK	;PONE A UNO LA LINEA DE RELOG
	NOP			;ESPERA SI HACER NADA AL MENOS 1.5uD
	NOP
	NOP
	NOP
	NOP
	NOP

	DECFSZ	CONT3,F		;COMPRUEBA SI ERA EL ULTIMO BIT
	GOTO	LOOP_1		;SI NO ES EL ULTIMO LEE EL SIGUIENTE
	MOVLW	0XFF		;SI ES EL ULTIMO CARGA FF EN EL REGISTRO A TRANSMITIR
	MOVWF	TX_D
	BSF	PORTA,COMM	;Y DEJA LA LINEA COMM A NIVEL ALTO
	RETURN	


;	CONTENIDO DE LOS BYTES TRANSMITIDOS POR EL PAD DIGITAL Y ANALOGICO ROJO
;	BIT7	BIT6	BIT5	BIT4	BIT3	BIT2	BIT1	BIT0
;BYTE1	IZQDA	ABAJO	DRCHA	ARRBA	STAR	-	-	SELECT
;BITE2	(|_|)	(X)	(O)	(/\)	R1	L1	R2	L2


;	CONTENIDO DEL BYTE DE TRANSMISION AL AMIGA EN MODO CD32
;	BIT7	BIT6	BIT5	BIT4	BIT3	BIT2	BIT1	BIT0
;CD32TX			PLAY	<<	>>	VERDE	AMRLL	ROJO
;EQU			START	L1	R1	(|_|)	(/\)	(X)



;EL BOTON AZUL NO ES NECESARIO TRANSMITIRLO QUE EQUIVALE A (O)

JOYOUT:
	MOVLW	0XFF
	MOVWF	OUT
	BTFSS	BYTE1,4		;SI SE PULSA ARRIBA
	BCF	OUT,UP
	BTFSS	BYTE1,5		;SI SE PULSA DERECHA
	BCF	OUT,RIGHT
	BTFSS	BYTE1,6		;SI SE PULSA ABAJO
	BCF	OUT,DOWN
	BTFSS	BYTE1,7		;SI SE PULSA IZQUIERDA
	BCF	OUT,LEFT	
	BTFSS	BYTE2,1		;SI SE PULSA R2
	CALL	AUTOFIRE
	BTFSS	BYTE2,5		;SI SE PULSA (O)
	BCF	OUT,FIRE1
	BTFSS	BYTE2,6		;SI SE PULSA (X)
	BCF	OUT,FIRE0
	MOVF	OUT,W
	MOVWF	PORTB
	RETURN	
AUTOFIRE:
	DECFSZ	FIREVEL,F
	RETURN	
	BCF	BYTE2,6
	MOVLW	0X04		;ESTE VALOR AJUSTA LA VELOCIDAD DE AUTOFIRE -=+VEL
	MOVWF	FIREVEL
	RETURN	

;
PREP32:
	;RUTINA TRADUCTORA DE PSX A PROTOCOLO CD32
	BSF	CD32TX,6
	BSF	CD32TX,7
	BTFSS	BYTE1,3		;SI SE PULSA STAR
	BCF	CD32TX,5	;EQUIVALE A PLAY/PAUSA
	BTFSS	BYTE2,2		;SI SE PULSA L1
	BCF	CD32TX,4	;EQUVALE A <<
	BTFSS	BYTE2,3		;SI SE PULSA R1
	BCF	CD32TX,3	;EQUVALE A >>
	BTFSS	BYTE2,4		;SI SE PULSA TRIANGULO
	BCF	CD32TX,1	;EQUVALE A AMARILLO	
	BTFSS	BYTE2,7		;SI SE PULSA CUADRADO 
	BCF     CD32TX,2        ;EQUIVALE A VERDE
	BTFSS	BYTE2,6		;SI SE PULSA (X)
	BCF	CD32TX,0	;EQUIVALE A ROJO
	BTFSC	BYTE1,3		;SI NO SE PULSA STAR
	BSF	CD32TX,5	;EQUIVALE A PLAY/PAUSA
	BTFSC	BYTE2,2		;SI NO SE PULSA L1
	BSF	CD32TX,4	;EQUVALE A <<
	BTFSC	BYTE2,3		;SI NO SE PULSA R1
	BSF	CD32TX,3	;EQUVALE A >>
	BTFSC	BYTE2,4		;SI NO SE PULSA TRIANGULO
	BSF	CD32TX,1	;EQUVALE A AMARILLO	
	BTFSC	BYTE2,7		;SI NO SE PULSA CUADRADO 
	BSF     CD32TX,2        ;EQUIVALE A VERDE
	BTFSC	BYTE2,6		;SI NO SE PULSA (X)
	BSF	CD32TX,0	;EQUIVALE A ROJO
	MOVF	CD32TX,W
	MOVWF	CD32TXB
	RETURN

PUERTOS:
	;ASIGNACION DE LAS PATILLAS DE I/O

	BSF	STATUS,RP0
	BSF	PORTA,DATA
	BCF	PORTA,COMM
	BCF	PORTA,CLK
	BCF	PORTA,ATT
	BCF	PORTB,FIRE0
	BCF	PORTB,FIRE1
	BSF	PORTB,FIRE2
	BCF	PORTB,UP
	BCF	PORTB,DOWN
	BCF	PORTB,LEFT
	BCF	PORTB,RIGHT
	BCF	OPTION,INTEDG
	BSF	OPTION,RBPU
	BSF	PORTB,4		;PUESTA COMO SALIDA PERO NO USADA
	BCF	STATUS,RP0

	RETURN	

DEFECTO:
	;ASIGNACION DE VALORES POR DEFECTO A REGISTROS Y PATILLAS
	;INICIALIZACION DE INTERRUPCIONES
	BSF	PORTA,ATT
	BSF	PORTA,CLK
	BSF	PORTA,COMM
	MOVLW	0X02
	MOVWF	FIREVEL
	BCF	INTCON,INTF
	BSF	INTCON,GIE
	BSF	INTCON,INTE

	RETURN	
	
DELAY:
	MOVWF	CONT1
LOOP1:
	DECFSZ	CONT1,F
	GOTO	LOOP1
	RETURN	
BIGDELAY:
	MOVLW	0X0A
	MOVWF	CONT2
	MOVLW	0X0A
LOOP2:
	CALL	DELAY
	DECFSZ	CONT2,F
	GOTO	LOOP2
	RETURN	
	END
