10 REM *****************************************
   20 REM *  I2C-Communication for Amstrad NC100  *
   30 REM *   over printer port pin 1 (SCL out),  *
   40 REM * 9 (SDA out), 10 (SCL in), 11 (SDA in) *
   50 REM *      (C) H.-J. Boehling 29.07.99      *
   60 REM * www.germany.net/teilnehmer/101.107378 *
   70 REM * www.isis.de/members/~boehling         *
   80 REM *****************************************
   85 REM Downloaded from Tim's Amstrad NC Users' Site
   86 REM http://www.ncus.org.uk
   90 REM
  100 REM +++ I2C test ++++++++++++++++++++++++++++
  110 REM The test sends out 0 to 255 to a PCF8574 and read back   
  120 CLS:ADDR=&40:REM ADDR=I2C address
  130 FOR BYTE_OUT=0 TO 255
  140   PROC_SEND_DATA (ADDR,BYTE_OUT)
  150   IF (ACK OR OUT)>0 THEN 220
  160   PROC_READ_DATA (ADDR)
  170   IF (ACK OR OUT)>0 THEN 220
  180   PRINT "Read back:";BYTE_IN
  190 NEXT 
  200 GOTO 130
  210 END
  220 REM +++ I2C Transmission Error ++++++++++++++
  230 PROC_I2C_STOP
  240 IF ACK>0 THEN PRINT "ACK failed!"
  250 IF OUT>0 THEN PRINT "Time out!" 
  260 FOR I=65 TO 1 STEP -4:SOUND 1,1,I,1:NEXT
  270 GOTO 140
  280 REM *** Send Data to I2C ********************
  290 DEF PROC_SEND_DATA (ADDR,BYTE_OUT):REM I2C address and Byte to send
  300 PROC_I2C_START:REM Set start condition
  310 PROC_I2C_OUT (ADDR AND &FE):REM Set write mode and send address out
  320 PROC_I2C_OUT (BYTE_OUT):REM Send byte out 
  330 PROC_I2C_STOP:REM Stop condition
  340 ENDPROC
  350 REM *** Read Data from I2C ******************
  360 DEF PROC_READ_DATA (ADDR):REM I2C address
  370 PROC_I2C_START:REM Start condition  
  380 PROC_I2C_OUT (ADDR OR 1):REM Set read mode and send address out
  390 PROC_I2C_IN:REM read byte in 
  400 PROC_I2C_STOP:REM Stop condition
  410 ENDPROC
  420 REM === I2C Send Byte =======================
  430 DEF PROC_I2C_OUT (BYTE_OUT)
  440 BIT=&80:WERT=1
  450 FOR I=1 TO 8
  460   SDA=(BYTE_OUT AND BIT)*WERT:REM Set data to bit of byte
  470   BIT=BIT/2:WERT=WERT+WERT:REM Set pointer to next bit
  480   PUT &30,&BF:REM Make clock low
  490   PUT &40,SDA:REM Send bit out
  500   PUT &30,&FF:REM Make clock high
  510 NEXT
  520 REM --- Get ACK -----------------------------
  530 PUT &30,&BF:REM Make clock low
  540 PUT &40,&80:REM Make data high
  550 PUT &30,&FF:REM Make clock high
  560 ACK=GET(&A0) AND 2:REM If data is high ACK failed
  570 PUT &30,&BF:REM Make clock low
  580 ENDPROC 
  590 REM === I2C Get Byte ========================
  600 DEF PROC_I2C_IN
  610 BYTE_IN=0:WERT=64
  620 FOR I=1 TO 8
  630   PUT &30,&BF:REM Make clock low
  640   PUT &30,&FF:REM Make clock high
  650   SDA=(GET(&A0) AND 2)*WERT:REM Read data...
  660   BYTE_IN=BYTE_IN OR SDA:REM ...to bit of byte
  670   WERT=WERT/2:REM Set pointer to next bit
  680 NEXT
  690 REM --- Do ACK ------------------------------
  700 PUT &30,&BF:REM Make clock low
  710 PUT &40,&00:REM Make data low to set ACK ok
  720 PUT &30,&FF:REM Make clock high
  730 ENDPROC 
  740 REM === I2C Start condition =================
  750 DEF PROC_I2C_START
  760 OUT=0: REM Reset time out counter
  770 PUT &40,&80:REM Make data high
  780 PUT &30,&FF:REM Make clock high
  790 IF OUT=3 THEN 820: REM Wait 3 times for clock and data high 
  800 IF (GET(&A0) AND 3)<>3 THEN OUT=OUT+1: GOTO 790
  810 PUT &40,&00:REM Make data low (start condition)  
  820 ENDPROC
  830 REM === I2C Stop condition ==================
  840 DEF PROC_I2C_STOP
  850 PUT &40,&00:REM Make data low
  860 PUT &30,&FF:REM Make clock high
  870 PUT &40,&80:REM Make data high
  880 ENDPROC