 10 ;
 20 ; DRIVERS I2C para porta Joystick
 30 ;
 40 ; danjovic@hotmail.com
 50 ; http://hotbit.blogspot.com
 60 ;
 70 ; Licenca de uso: GNU GPL
 80 ;
 90 ; Versao 0.2 22/04/2007
 100 ;
 110 ; #########################
 120 ;
 130 ; PSG Reg 15 Bits
 140 ;
 150 ASDA: EQU 0
 160 ASCL: EQU 1
 170 BSDA: EQU 2
 180 BSCL: EQU 3
 190 APWR: EQU 4
 200 BPWR: EQU 5
 210 ABSEL: EQU 6
 220 ;
 230 MSDA: EQU 10H ; (SDA In = TRGA)
 240 ;
 250 ; PSG Regs
 260 ;
 270 PSGAD: EQU 0A0H
 280 PSGWR: EQU 0A1H
 290 PSGRD: EQU 0A2H
 300 ;
 310 TIMEOUT: EQU 2000
 320 T1MS3MHZ: EQU 109
 330 T1MS7MHZ: EQU 220
 340 R8563ADR: EQU 10100010B
 350 E2PADR: EQU 10100000B
 360 ENOCHIP: EQU 01
 370 EOK: EQU 0
 380 CHPUT: EQU 0A2H
 390 ;
 400 ;
 410 ; #############################
 420 ;
 430 ORG 0A000H
 440 ;
 450 ;AND A  ; Seleciona porta JOY 1
 460 SCF    ; Seleciona porta JOY 2
 470 CALL J2CINIT
 480 LD A,E2PADR
 490 AND 0FEH ; Bit R/!W=0
 500 LD C,A
 510 LD HL,0820H
 520 CALL J2CP16ADR
 530 JR C,ERRO
 545 ;
 550 LD A,E2PADR
 560 OR 01    ; Bit R/!W=1
 561 LD C,A
 570 CALL J2CLOGON
 580 JR C,ERRO
 590 ;
 600 LD IY,0B100H
 610 LD HL,511
 620 ;
 630 LOOP:
 640 CALL J2CGBYTE
 650 LD (IY),C
 660 INC IY
 670 AND A ;CY=0 Gera ACK
 680 CALL J2CPAK
 690 DEC HL
 700 LD A,H
 710 OR L
 720 JR NZ,LOOP
 730 ;
 740 CALL J2CGBYTE ; Ultimo byte
 750 LD (IY),C     ; nao gera ACK
 760 SCF
 770 CALL J2CPAK
 780 CALL J2CSTOP
 790 ;
 800 AND A
 810 LD A,'+'
 820 JR ERR1
 830 ;
 840 ERRO: LD A,'-'
 850 ERR1:
 860 CALL CHPUT
 870 RET
 880 ;
 890 ;
 900 ; Le registros 2..8 do PCF8563
 910 ;
 920 RD8563:
 930 CALL J2CINIT
 940 LD A,R8563ADR
 950 AND 0FEH ; BIT R/!W=0
 960 LD HL,2  ; Registro inicial=2
 970 CALL J2CP8ADR
 980 RD85L1:
 990 JR C,R85F1  ; CY=1 chip nao resp
 1000 LD A,R8563ADR
 1010 OR 1     ; BIT R/!W=1
 1020 CALL J2CLOGON
 1030 JR C,RD85L1  ; Aguarda ACK
 1040 ;
 1050 LD HL,RTCBUF
 1060 LD B,7
 1070 ;
 1080 RD85L2:
 1090 CALL J2CGBYTE
 1100 LD (HL),A
 1110 INC HL
 1120 AND A      ; CY=0 gera ACK
 1130 CALL J2CPAK
 1140 DJNZ RD85L2
 1150 ;
 1160 CALL J2CGBYTE ; ultimo byte
 1170 LD (HL),A
 1180 SCF        ; CY=1 nao gera ACK
 1190 CALL J2CPAK
 1200 CALL J2CSTOP
 1210 ;
 1220 LD A,(VERBOSE)
 1230 OR A
 1240 LD A,'!'
 1250 CALL NZ,0A2H
 1260 RET
 1270 ;
 1280 R85F1:  ;erro. chip nao respondeu
 1290 CALL J2CSTOP
 1300 LD A,(VERBOSE)
 1310 OR A
 1320 LD A,'?'
 1330 CALL NZ,CHPUT
 1340 SCF
 1350 RET
 1360 ;
 1370 ;
 1380 ; Escr. registros 2..8 do PCF8563
 1390 ;
 1400 WR8563:
 1410 CALL J2CINIT
 1420 LD A,R8563ADR
 1430 AND 0FEH ; BIT R/!WR = 0
 1440 LD HL,02 ; Inicia no reg 2
 1450 CALL J2CP8ADR
 1460 JR C,W85F1
 1470 LD A,R8563ADR
 1480 ;
 1490 LD HL,RTCBUF
 1500 LD B,7
 1510 ;
 1520 WR85L1:
 1530 LD A,(HL)
 1540 INC HL
 1550 CALL J2CPB
 1560 CALL J2CGAK
 1570 JR C,W85F1 ; Erro se nao ACK
 1580 DJNZ WR85L1
 1590 CALL J2CSTOP
 1600 ;
 1610 LD A,(VERBOSE)
 1620 OR A
 1630 LD A,'%'
 1640 CALL NZ,CHPUT
 1650 RET
 1660 ;
 1670 W85F1: ; chip nao deu ACK
 1680 LD A,(VERBOSE)
 1690 OR A
 1700 LD A,'#'
 1710 CALL NZ,CHPUT
 1720 SCF
 1730 RET
 1740 ;
 1750 ;
 1760 ; #############################
 1770 ;
 1780 J2CINIT:
 1790 DI
 1800 LD A,15
 1810 OUT (PSGAD),A
 1820 IN A,(PSGRD)
 1830 LD (PSGSAV),A
 1840 JR C,BINIT
 1850 ;
 1860 AINIT:
 1870 RES ABSEL,A ; JOY A
 1880 SET APWR,A  ; Energiza HUB
 1890 OUT (PSGWR),A
 1900 CALL WAIT1MS ; Aguarda 1ms
 1910 SET ASDA,A ; SDA=1
 1920 OUT (PSGWR),A
 1930 RES ASCL,A  ; SCL=0
 1940 OUT (PSGWR),A
 1950 LD B,A
 1960 ;
 1970 CALL J2CSTOP
 1980 CALL J2CSTOP
 1990 CALL J2CSTOP
 2000 RET
 2010 ;
 2020 BINIT:
 2030 SET ABSEL,A ; JOY B
 2040 SET BPWR,A  ; Energiza HUB
 2050 OUT (PSGWR),A
 2060 CALL WAIT1MS ; Aguarda 1ms
 2070 SET BSDA,A ; SDA=1
 2080 OUT (PSGWR),A
 2090 RES BSCL,A  ; SCL=0
 2100 OUT (PSGWR),A
 2110 LD B,A
 2120 ;
 2130 CALL J2CSTOP
 2140 CALL J2CSTOP
 2150 CALL J2CSTOP
 2160 RET
 2170 ;
 2180 J2CSTOP:
 2190 LD A,B
 2200 BIT ABSEL,A ; Qual porta?
 2210 JR NZ,BSTOP
 2220 ;
 2230 ASTOP:
 2240 RES ASDA,A ; SDA=0
 2250 OUT (PSGWR),A
 2260 SET ASCL,A ; SCL=1
 2270 OUT (PSGWR),A
 2280 SET ASDA,A ; SDA=1
 2290 OUT (PSGWR),A
 2300 LD B,A ; Atualiza B
 2310 RET
 2320 ;
 2330 BSTOP:
 2340 RES BSDA,A ; SDA=0
 2350 OUT (PSGWR),A
 2360 SET BSCL,A ; SCL=1
 2370 OUT (PSGWR),A
 2380 SET BSDA,A ; SDA=1
 2390 OUT (PSGWR),A
 2400 LD B,A ; Atualiza B
 2410 RET
 2420 ;
 2430 J2CSTART:
 2440 LD A,B
 2450 BIT ABSEL,A
 2460 JR NZ,BSTART
 2470 ;
 2480 ASTART:
 2490 SET ASCL,A ; SCL=1
 2500 OUT (PSGWR),A
 2510 SET ASDA,A ; SDA=1
 2520 OUT (PSGWR),A
 2530 RES ASDA,A ; SDA=0
 2540 OUT (PSGWR),A
 2550 RES ASCL,A ; SCL=0
 2560 OUT (PSGWR),A
 2570 SET ASDA,A ; SDA=1
 2580 OUT (PSGWR),A
 2590 LD B,A
 2600 RET
 2610 ;
 2620 BSTART:
 2630 SET BSCL,A ; SCL=1
 2640 OUT (PSGWR),A
 2650 SET BSDA,A ; SDA=1
 2660 OUT (PSGWR),A
 2670 RES BSDA,A ; SDA=0
 2680 OUT (PSGWR),A
 2690 RES BSCL,A ; SCL=0
 2700 OUT (PSGWR),A
 2710 SET BSDA,A ; SDA=1
 2720 OUT (PSGWR),A
 2730 LD B,A
 2740 RET
 2750 ;
 2760 J2CPB:
 2770 LD A,B
 2780 BIT ABSEL,A
 2790 JR NZ,BPBYTE
 2800 ;
 2810 APBYTE:
 2820 LD B,8
 2830 ;
 2840 APBY1:
 2850 SLA C
 2860 RES ASDA,A
 2870 JR NC,APBY2 ; SDA=CY
 2880 SET ASDA,A
 2890 APBY2:
 2900 OUT (PSGWR),A
 2910 SET ASCL,A ; SCL=1
 2920 OUT (PSGWR),A
 2930 RES ASCL,A ; SCL=0
 2940 OUT (PSGWR),A
 2950 DJNZ APBY1
 2960 ;
 2970 SET ASDA,A ; SDA=1
 2980 OUT (PSGWR),A
 2990 LD B,A
 3000 RET
 3010 ;
 3020 BPBYTE:
 3030 LD B,8
 3040 ;
 3050 BPBY1:
 3060 SLA C
 3070 RES BSDA,A
 3080 JR NC,BPBY2 ; SDA=CY
 3090 SET BSDA,A
 3100 BPBY2:
 3110 OUT (PSGWR),A
 3120 SET BSCL,A ; SCL=1
 3130 OUT (PSGWR),A
 3140 RES BSCL,A ; SCL=0
 3150 OUT (PSGWR),A
 3160 DJNZ BPBY1
 3170 ;
 3180 SET BSDA,A ; SDA=1
 3190 OUT (PSGWR),A
 3200 LD B,A
 3210 RET
 3220 ;
 3230 J2CGBYTE:
 3240 LD A,B
 3250 BIT ABSEL,A
 3260 JR NZ,BGBYTE
 3270 ;
 3280 AGBYTE:
 3290 SET ASDA,A ; SDA=1
 3300 OUT (PSGWR),A
 3310 LD BC,0800H ; B=8, C=0
 3320 ;
 3330 AGBY1:
 3340 SET ASCL,A ; SCL=1
 3350 OUT (PSGWR),A
 3360 LD E,A     ; Salva A
 3370 LD A,14
 3380 OUT (PSGAD),A ; Selec REG 14
 3390 IN A,(PSGRD)
 3400 AND MSDA   ; Mascara bit TRIGGER
 3410 NEG ; CY=(A==0)
 3420 RL C
 3430 ;
 3440 LD A,15
 3450 OUT (PSGAD),A
 3460 LD A,E ; Recupera est reg 15
 3470 RES ASCL,A ; SCL=0
 3480 OUT (PSGWR),A
 3490 DJNZ AGBY1
 3500 ;
 3510 LD B,A
 3520 RET
 3530 ;
 3540 BGBYTE:
 3550 SET BSDA,A ; SDA=1
 3560 OUT (PSGWR),A
 3570 LD BC,0800H ; B=8, C=0
 3580 ;
 3590 BGBY1:
 3600 SET BSCL,A ; SCL=1
 3610 OUT (PSGWR),A
 3620 LD E,A     ; Salva A
 3630 LD A,14
 3640 OUT (PSGAD),A ; Selec REG 14
 3650 IN A,(PSGRD)
 3660 AND MSDA   ; Mascara bit TRIGGER
 3670 NEG ; CY=(A==0)
 3680 RL C
 3690 ;
 3700 LD A,15
 3710 OUT (PSGAD),A
 3720 LD A,E ; Recupera est reg 15
 3730 RES BSCL,A ; SCL=0
 3740 OUT (PSGWR),A
 3750 DJNZ BGBY1
 3760 ;
 3770 LD B,A
 3780 RET
 3790 ;
 3800 J2CPAK: ; PUT ACK
 3810 LD A,B
 3820 BIT ABSEL,A
 3830 JR NZ,BPAK
 3840 ;
 3850 APAK:
 3860 RES ASDA,A
 3870 OUT (PSGWR),A
 3880 JR NC,APAK1 ; SDA=CY
 3890 SET ASDA,A
 3900 ;
 3910 APAK1:
 3920 OUT (PSGWR),A
 3930 SET ASCL,A ; SCL=1
 3940 OUT (PSGWR),A
 3950 RES ASCL,A ; SCL=0
 3960 OUT (PSGWR),A
 3970 SET ASDA,A ; SDA=1
 3980 OUT (PSGWR),A
 3990 LD B,A
 4000 RET
 4010 ;
 4020 BPAK:
 4030 RES BSDA,A
 4040 OUT (PSGWR),A
 4050 JR NC,BPAK1 ; SDA=CY
 4060 SET BSDA,A
 4070 ;
 4080 BPAK1:
 4090 OUT (PSGWR),A
 4100 SET BSCL,A ; SCL=1
 4110 OUT (PSGWR),A
 4120 RES BSCL,A ; SCL=0
 4130 OUT (PSGWR),A
 4140 SET BSDA,A ; SDA=1
 4150 OUT (PSGWR),A
 4160 LD B,A
 4170 RET
 4180 ;
 4190 J2CGAK: ; GET ACK
 4200 LD A,B
 4210 BIT ABSEL,A
 4220 JR NZ,BGAK
 4230 ;
 4240 AGAK:
 4250 SET ASDA,A ; SDA=1
 4260 OUT (PSGWR),A
 4270 SET ASCL,A ; SCL=1
 4280 OUT (PSGWR),A
 4290 PUSH HL
 4300 LD HL,TIMEOUT
 4310 LD B,A  ; Salva est reg 15
 4320 ;
 4330 LD A,14
 4340 OUT (PSGAD),A; Sel REG 14
 4350 AGAK1:
 4360 IN A,(PSGRD)
 4370 AND MSDA ; checa e tbem clear CY
 4380 JR Z,AGAK2 ; Sai ao receber ACK
 4390 ;
 4400 DEC HL
 4410 LD A,H
 4420 OR L
 4430 JR NZ,AGAK1
 4440 ;
 4450 SCF ; Indica TIMEOUT
 4460 ;
 4470 AGAK2:
 4480 LD A,15
 4490 OUT (PSGAD),A ; Sel Reg 15
 4500 LD A,B
 4510 RES ASCL,A
 4520 OUT (PSGWR),A
 4530 LD B,A
 4540 POP HL
 4550 RET
 4560 ;
 4570 BGAK:
 4580 SET BSDA,A ; SDA=1
 4590 OUT (PSGWR),A
 4600 SET BSCL,A ; SCL=1
 4610 OUT (PSGWR),A
 4620 PUSH HL
 4630 LD HL,TIMEOUT
 4640 LD B,A  ; Salva est reg 15
 4650 ;
 4660 LD A,14
 4670 OUT (PSGAD),A; Sel REG 14
 4680 BGAK1:
 4690 IN A,(PSGRD)
 4700 AND MSDA ; checa e tbem clear CY
 4710 JR Z,BGAK2 ; Sai ao receber ACK
 4720 ;
 4730 DEC HL
 4740 LD A,H
 4750 OR L
 4760 JR NZ,BGAK1
 4770 ;
 4780 SCF ; Indica TIMEOUT
 4790 ;
 4800 BGAK2:
 4810 LD A,15
 4820 OUT (PSGAD),A ; Sel Reg 15
 4830 LD A,B
 4840 RES BSCL,A
 4850 OUT (PSGWR),A
 4860 LD B,A
 4870 POP HL
 4880 RET
 4890 ;
 4900 ;
 4910 J2CLOGON:
 4920 CALL J2CSTART
 4930 CALL J2CPB
 4940 CALL J2CGAK
 4950 RET
 4960 ;
 4970 J2CP16ADR:
 4980 CALL J2CLOGON
 4990 RET C
 5000 PADR2:
 5010 LD C,H
 5020 CALL J2CPB
 5030 CALL J2CGAK
 5040 RET C
 5050 LD C,L
 5060 CALL J2CPB
 5070 CALL J2CGAK
 5080 RET
 5090 ;
 5100 J2CP8ADR:
 5110 CALL J2CLOGON
 5120 RET C
 5130 P8ADR2:
 5140 LD C,L
 5150 CALL J2CPB
 5160 CALL J2CGAK
 5170 RET
 5180 ;
 5190 WAIT1MS:
 5200 PUSH HL
 5210 PUSH AF
 5220 LD HL,T1MS3MHZ
 5230 WAIT1: DEC HL
 5240 LD A,H
 5250 OR L
 5260 JR NZ,WAIT1
 5270 POP AF
 5280 POP HL
 5290 RET
 5300 ;
 5310 ZEND:
 5320 ;
 5330 ORG 0B000H
 5340 PSGSAV: DB 1
 5350 VERBOSE: DB 1
 5360 RTCBUF:  DS 7
 5370 ;
