;
;  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
	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
