''''''''''''''''''''''''''''''
''   PockeTerm              ''
''   Author: Vince Briel    ''
''   2009 Briel Computers   ''
''                          ''
''''''''''''''''''''''''''''''
'
'' Big thanks to Jeff Ledger on the VT100 code
'
'
'  Start of RAW code for testing  December 19,2008
'  Jan 10th added INVERSE mode
'  Jan 13 revised code for .04 working duel serial ports
'  Jan 15 fixed so xmodem could work by allowing data 0 up to be sent not 1 and up
'  Jan 21 added PC port on/off 7 bit ascii on/off
'  V.71 cls to cursor fixed
'  V.72 clsfrom cursor down working
'  V.73 fixed EEPROM read/write issue and no serial port functioning
'  V.74 ESC D and ESC L commands added, only 2 commands remaining
'  V.80 VT100 majority codes finished
'  V.81 Fixed cursor home to 0,0 and CLS to leave cursor where it is at after CLS
'  V.82 Made Function control keys CTRL-Fx to avoid accidental changes
'  V.83 Added CTRL-G beep sound effect
'  V.84 Added ESC[c and ESC[0c terminal ID command
'  V.85 Fixed scroll issue if beyond 36th line
'  V.86 Fixed terminal ID, now working added 300 & 115200 Baud rates
'  V.90 Added CTRL-F6 option for Carriage return to add line feed YES or NO
'  V.901 Fixed ESC[A-D so they work if no value is added
'  V.902 Modified so CR just does a Carriage Return and LF just does a linefeed
'  V.903 More adjustments to CR adjusted command
'  V.905 Fixed clear from cursor up ESC[1J did not clear line above cursor
''              Current VT-100 Code list
''
''      ESC[m                   Turn off character attributes
''      ESC[0m                  Turn off character attributes
''      ESC[1m                  Turn bold character on (reverse)
''      ESC[7m                  Turn reverse video on
''      ESC[nA                  Move cursor up n lines
''      ESC[nB                  Move cursor down n lines
''      ESC[nC                  Move cursor right n lines
''      ESC[nD                  Move cursor left n lines
''      ESC[H                   Move cursor to upper left corner
''      ESC[;H                  Move cursor to upper left corner
''      ESC[line;columnH        Move cursor to screen location v,h
''      ESC[f                   Move cursor to upper left corner
''      ESC[;f                  Move cursor to upper left corner
''      ESC[line;columnf        Move cursor to sceen location v,h
''      ESCD                    Move/scroll window up one line 
''      ESC[D                   Move/scroll window up one line 
''      ESCL                    Move/scroll window up one line (undocumented)
''      ESC[L                   Move/scroll window up one line (undocumented)
''      ESCM                    Move/scroll window down one line
''      ESCK                    Clear line from cursor right
''      ESC[0K                  Clear line from cursor right
''      ESC[1K                  Clear line from cursor left
''      ESC[2K                  Clear entire line
''      ESC[J                   Clear screen from cursor down
''      ESC[0J                  Clear screen from cursor down
''      ESC[1J                  Clear screen from cursor up
''      ESC[2J                  Clear entire screen
''      ESC[0c                  Terminal ID responds with [?1;0c for VT-100 no options
''      ESC[c                   Terminal ID responds with [?1;0c for VT-100 no options
''      Esc[value@              Insert one character
''      Esc[valueP              Delete one character
''
'' List of ignored codes
''
''      ESC[xxh                 All of the ESC[20h thru ESC[?9h commands
''      ESC[xxl                 All of the ESC[20i thru ESC[?9i commands
''      ESC=                    Alternate keypad mode
''      ESC<                    Enter/Exit ANSI mode
''      ESC>                    Exit Alternate keypad mode
''      Esc5n                   Device status report                            DSR  
''      Esc0n                   Response: terminal is OK                        DSR  
''      Esc3n                   Response: terminal is not OK                    DSR  
''      Esc6n                   Get cursor position                             DSR  
''      EscLine;ColumnR         Response: cursor is at v,h                      CPR
''      Esc#8                   Screen alignment display                        DECALN  
''      Esc[2;1y                Confidence power up test                        DECTST  
''      Esc[2;2y                Confidence loopback test                        DECTST  
''      Esc[2;9y                Repeat power up test                            DECTST  
''      Esc[2;10y               Repeat loopback test                            DECTST  
''      Esc[0q                  Turn off all four leds                          DECLL0  
''      Esc[1q                  Turn on LED #1                                  DECLL1  
''      Esc[2q                  Turn on LED #2                                  DECLL2  
''      Esc[3q                  Turn on LED #3                                  DECLL3  
''      Esc[4q                  Turn on LED #4                                  DECLL4  
  

'' IN DEVELOPMENT



'  Please report any bugs to vbriel@yahoo.com


CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
                                         
  Cursor     = 95
  VideoCls   = 0
  NUM        = %100
  CAPS       = %010
  SCROLL     = %001
  RepeatRate = 40
  video      = 16
  backspace  = $C8
'  semi       = 59
'  rowsnow    = 36
  
'  VT-100 values

'' Terminal Colors
   TURQUOISE         = $29
   BLUE              = $27
   BABYBLUE          = $95
   RED               = $C1
   GREEN             = $99
   GOLDBROWN         = $A2
   AMBERDARK         = $E2
   LAVENDER          = $A5
   WHITE             = $FF
   HOTPINK           = $C9
   GOLD              = $D9
   PINK              = $C5

 
   r1 = 31          'PC serial port receive line
   t1 = 30          'PC serial port transmit line
   r2 = 25          'Host device receive line
   t2 = 24          'Host device transmit line

   EEPROMAddr        = %1010_0000
   EEPROM_Base       = $7FE0
   i2cSCL            = 28

'' Sound Variables

   right = 10
   left  = 11
   
OBJ

  text: "VGA_1024v.905"                                                              ' VGA Terminal Driver  
  kb:   "keyboard"                                                              ' Keyboard driver
  ser:  "FullDuplexSerial256"                                                   ' Full Duplex Serial Controller
  ser2: "FullDuplexSerial2562"                                                  ' 2nd Full Duplex Serial Controller
  i2c:  "basic_i2c_driver"
VAR

  word key
  Byte Index
  Byte Rx
  Byte rxbyte
'  Long Stack[100]
  Byte temp
  Byte serdata
  Long Baud
  Byte termcolor
  Long BR[8]
  Long CLR[11]
  long  i2cAddress, i2cSlaveCounter
  Byte pcport
  Byte ascii
  Byte curset
  word eepromLocation
  Byte CR
  Byte LNM
PUB main | i,j,k,remote,remote2,record,vt100,byte2,byte3,byte1,byte4,byte5,byte6,byte7,loop,var1,col,row,temp2,tempbaud,source 




  CTRA:= %00110 << 26 + 0<<9 + right
  CTRB:= %00110 << 26 + 0<<9 + left
  DIRA[right]~~                 'Set Right Pin to output
  DIRA[left]~~                  'Set Left Pin to output
  source:=@PIANO
  LNM := 0                      'CR only sent
  i2c.Initialize(i2cSCL)
  tempbaud:=4
  CR := 0  '0= OFF 1 = CR AND LF
  ascii := 0   '0=no 1=yes
  pcport := 1 '1=pc port off, 2=on
  termcolor:=5
  curset := 5
  BR[0]:=300 
  BR[1]:=1200
  BR[2]:=2400
  BR[3]:=4800
  BR[4]:=9600
  BR[5]:=19200
  BR[6]:=38400
  BR[7]:=57600
  BR[8]:=115200
  CLR[1]:=TURQUOISE
  CLR[2]:=BLUE
  CLR[3]:=BABYBLUE
  CLR[4]:=RED
  CLR[5]:=GREEN
  CLR[6]:=GOLDBROWN
  CLR[7]:=WHITE
  CLR[8]:=HOTPINK
  CLR[9]:=GOLD
  CLR[10]:=PINK
  CLR[11]:=AMBERDARK

'' Determine if previous settings are stored in EEPROM, if so, retrive for user
  eepromLocation := EEPROM_Base                                                 'Point i2c to EEPROM storage
  temp2 := i2c.ReadByte(i2cSCL, EEPROMAddr, eepromLocation)                     'read test byte to see if data stored
  if temp2 == 55                                                                'we have previously recorded settings, so restore them
     eepromLocation +=4                                                         'increase to next location
     tempbaud := i2c.ReadLong(i2cSCL, EEPROMAddr, eepromLocation)               'read Baud as temp
     eepromLocation +=4                                                         
     termcolor := i2c.ReadLong(i2cSCL, EEPROMAddr, eepromLocation)              'read terminal color
     eepromLocation +=4                                                         
     pcport := i2c.ReadLong(i2cSCL, EEPROMAddr, eepromLocation)                 'read pcport on/off setting
     eepromLocation +=4
     ascii := i2c.ReadLong(i2cSCL, EEPROMAddr, eepromLocation)                  'read force 7bit setting
     eepromLocation +=4
     curset := i2c.ReadLong(i2cSCL, EEPROMAddr, eepromLocation)                 'read cursor type
     eepromLocation +=4
     CR := i2c.ReadLong(i2cSCL, EEPROMAddr, eepromLocation)                     'read CR W/LF ON/OFF
     waitcnt(clkfreq/200 + cnt)     



  
  Baud:=BR[tempbaud]                                                                                            
  text.start(video)
  text.color(CLR[termcolor])                                                                                                        
  kb.startx(26, 27, NUM, RepeatRate)                                            'Start Keyboard Driver
  ser.start(r1,t1,0,baud)                                                       'Start Port2 to PC
  ser2.start(r2,t2,0,baud)                                                      'Start Port1 to main device  
  Baud:=tempbaud
  text.cls(Baud,termcolor,pcport,ascii,CR)
'  text.clsupdate(Baud,termcolor,pcport,ascii,CR)
  text.inv(0)
  text.cursorset(curset)
  vt100:=0 
  repeat
    key := kb.key                                                               'Go get keystroke, then return here
    
    if key == 194 'up arrow
       ser2.str(string(27,"[A"))
    if key == 195 'down arrow
       ser2.str(string(27,"[B"))
       'ser2.out($0A)
    if key == 193 'right arrow
       ser2.str(string(27,"[C"))
    if key == 192 'left arrow
       ser2.str(string(27,"[D"))    
           
    if key >576
       if key <603
          key:=key-576
    if key > 608  and key < 635                                                 'Is it a control character?
       key:=key-608
    'if key >0
    '   text.dec(key)
    if key == 200
       key:=08
    if key == 203                                                               'Is it upper code for ESC key?
       key:= 27                                                                 'Yes, convert to standard ASCII value
    if key == 720               
      Baud++                                                                    'is ESC then + then increase baud or roll over
      if Baud > 8
         Baud:=0
      temp:=Baud
      Baud:=BR[temp]
      ser.stop
      ser2.stop
      ser.start(r1,t1,0,baud)                                                   'ready port for PC
      ser2.start(r2,t2,0,baud)                                                  'ready port for HOST
      Baud:=temp
      text.clsupdate(Baud,termcolor,pcport,ascii,CR)
      EEPROM
    if key == 721               
       if ++termcolor > 11
          termcolor:=1
       text.color(CLR[termcolor])
       'text.clsupdate(Baud,termcolor,pcport,ascii)
       EEPROM
    if key == 722               
       if pcport == 1
          pcport := 0
       else
          pcport := 1
       text.clsupdate(Baud,termcolor,pcport,ascii,CR)
       EEPROM
    if key == 723               
       if ascii == 0
          ascii := 1
       else
          ascii :=0
       text.clsupdate(Baud,termcolor,pcport,ascii,CR)
       EEPROM
    if key == 724               
       curset++
       if curset > 7
          curset := 1
       text.cursorset(curset)
       EEPROM
    if key == 725 'F6
       if CR == 1
          CR := 0
       else
          CR := 1
       text.clsupdate(Baud,termcolor,pcport,ascii,CR)
       EEPROM
    if key <128 and key > 0                                                     'Is the keystroke PocketTerm compatible?    was 96 
       ser2.tx(key)                                                             'Yes, so send it
       if key == 13
       'this probably needs to be if CR == 1
         if LNM == 1 or CR == 1'send both CR and LF?
           ser2.tx(10)          'yes, set by LNM ESC command, send LF also
       

       
'' END keyboard console routine


                                                                                           
'LOOK FOR SERIAL INPUT HERE
    if pcport == 0                                                              'Is PC turned on at console for checking? 
       remote2 := ser.rxcheck                                                   'Yes, look at the port for data                  
       if (remote2 > -1)                                                        'remote = -1 if no data
          ser2.tx(remote2)                                                      'Send the data out to the host device
          waitcnt(clkfreq/200 + cnt)                                            'Added to attempt eliminate dropped characters
    remote := ser2.rxcheck                                                      'Look at host device port for data
    if (remote > -1)
       if ascii == 1 'yes force 7 bit ascii
          if (remote > 127)
             remote := remote -128
       if pcport == 0       
          ser.tx(remote)
'Start of VT100 code
      if remote == 27                                                                                   'vt100 ESC code is being sent
         vt100:=1
         byte1:=0
         byte2:=0
         byte3:=0
         byte4:=0
         byte5:=0
         byte6:=0
         byte7:=0
         remote:=0
         temp2:=0                                                                                       'Don't display the ESC code
      if remote == 99 and vt100 == 1                                                                    'ESC c
         remote:=0
         vt100:=0
         text.inv(0)
         text.cls(Baud,termcolor,pcport,ascii,CR)
         text.home
         
      if remote == 61 and vt100 == 1                                                                              'lool for ESC=
         vt100:= remote := 0


      'put ESC D and ESC M here
      if remote == 77 and vt100 == 1 'AKA ESC M
         text.scrollM
         vt100 := 0
      if remote == 68 and vt100 == 1 'AKA ESC D
         if byte2 <> 91 and byte3 <> 91 and byte4 <> 91  'not esc[D   
            'text.scrollD
            vt100 := 0
      if remote == 76 and vt100 == 1 'AKA ESC L
      if remote == 91 and vt100 == 1                                                                    'look for open bracket [
         vt100:=2                                                                                       'start recording code
      if remote == 62 and vt100 == 1 or remote == 60 and vt100 == 1                                     'look for < & >
         vt100:=0 ' not sure why this is coming up, can't find in spec.
      if vt100==2 ''Check checking for VT100 emulation codes  
         if remote > 10
           byte7:=byte6
           byte6:=byte5                                                                                 ' My VTCode Mini Buffer
           byte5:=byte4
           byte4:=byte3
           byte3:=byte2                                                                                 'Record the last 7 bytes
           byte2:=byte1
           byte1:=remote
         
         if remote == 109                                                                               'look for lowercase m
            if byte2 == 91                                                                              'if [m turn off to normal set
               text.inv(0)
               vt100:=0
            if byte2 == 49 and vt100 > 0                                                                              'is it ESC[1m BOLD
               'text.inv(1)
               vt100 := 0
            if byte2  == 55 and vt100 > 0                                                                             'is it ESC[7m?
               text.inv(1)
               vt100 := 0
            if byte2  == 48 and vt100 > 0                                                                             '0 is back to normal
               text.inv(0)
               vt100:=0
            if byte2 == 52 and vt100 > 0                                                                'is it ESC[4m underline?
               vt100:=0                                                                                 'yes ignore
            if byte2 == 50 and vt100 >0                                                                 'is it ESC[2m dim text
               vt100:=0                                                                                 'yes ignore  
         if remote == 64                                                                                'look for ESC[value@ @=64   insert value spaces
            if byte4 == 91 'two digit value
               byte3:=byte3-48                                                                         'Grab 10's
               byte2:=byte2-48                                                                         'Grab 1's
               byte3:=byte3*10                                                                         'Multiply 10's
               byte3:=byte3+byte2                                                                      'Add 1's
               text.insertat(byte3)
            if byte3 == 91 'single digit value
               byte2:=byte2-48
               text.insertat(byte2)
            vt100 :=0   
         if remote == 80                                                                                'look for ESC[valueP P=64   delete value spaces
            if byte4 == 91 'two digit value
               byte3:=byte3-48                                                                         'Grab 10's
               byte2:=byte2-48                                                                         'Grab 1's
               byte3:=byte3*10                                                                         'Multiply 10's
               byte3:=byte3+byte2                                                                      'Add 1's
               text.delp(byte3)
            if byte3 == 91 'single digit value
               byte2:=byte2-48
               text.delp(byte2)
            vt100 :=0
         if remote == 104                                                                               'look for lowercase h set CR/LF mode
            if byte2 == 48 'if character before h is 0 maybe command is 20h
               if byte3 == 50 'if byte3 then it is for sure 20h
                 LNM := 0        
            vt100:=0

         if remote == 61                                                                                'lool for =
            vt100:=0

         if remote == 114                                                                               'look for lowercase r
            vt100:=0

         if remote == 108                                                                               'look for lowercase l
            if byte2 == 48 'if character before l is 0 maybe command is 20l
               if byte3 == 50 'if byte3 then it is for sure 20l
                 LNM := 1  '0 means CR/LF in CR mode only 
            vt100:=0

         if remote == 62  'look for >
            vt100:=0
         if remote == 77                                                                                'ESC M look for obscure scroll window code
            text.scrollM 
            vt100:=0
         if remote == 68 or remote == 76 ' look for ESC D  or ESC L
            text.scrollD
            vt100:=0
         if remote == 72 or remote == 102                                                               ' HOME CURSOR (uppercase H or lowercase f) 
            if byte2==91 or byte2==59                                                                   'look for [H or [;f
               text.home
               vt100:=0
            '' Check for X & Y with [H or ;f   -   Esc[Line;ColumnH

            else                                                                                        'here remote is either H or f       
              if byte4 == 59                                                                            'is col is greater than 9     ; ALWAYS if byte4=59
                byte3:=byte3-48                                                                         'Grab 10's
                byte2:=byte2-48                                                                         'Grab 1's
                byte3:=byte3*10                                                                         'Multiply 10's
                byte3:=byte3+byte2                                                                      'Add 1's
                col:=byte3                                                                              'Set cols
                                   
                if byte7 == 91                                                                          'Assume row number is greater than 9  if ; at byte 4 and [ at byte 7 greater than 9
                   byte6:=byte6-48                                                                      'Grab 10's
                   byte5:=byte5-48                                                                      'Grab 1's
                   byte6:=byte6*10                                                                      'Multiply 10's
                   byte6:=byte6+byte5                                                                   'Add 1's
                   row:=byte6

                if byte6 == 91                                                                          'Assume row number is less than 10
                   byte5:=byte5 - 48                                                                    'Grab 1's
                   row:=byte5

              if byte3 == 59                                                                            ' Assume that col is less an 10
                byte2:=byte2-48                                                                         'Grab 1's
                col:=byte2                                                                              'set cols

                if byte6 == 91                                                                          'Assume row number is greater than 9
                   byte5:=byte5-48                                                                      'Grab 10's
                   byte4:=byte4-48                                                                      'Grab 1's
                   byte5:=byte5*10                                                                      'Multiply 10's
                   byte5:=byte5+byte4                                                                   'Add 1's
                   row:=byte5
                if byte5 == 91                                                                          'Assume that col is greater than 10
                   byte4:=byte4-48                                                                       'Grab 1's
                   row:=byte4

              col:=col-1
              if row == -459
                 row:=1
              if col == -40    ' Patches a bug I havn't found.  *yet*
                 col := 58     ' A Microsoft approach to the problem. :)
              if row == -449
                 row := 2      ' Appears to be an issue with reading
              if row == -439   ' single digit rows.
                 row := 3
              if row == -429   ' This patch checks for the bug and replaces
                 row := 4      ' the faulty calculation.
              if row == -419
                 row := 5      ' Add to list to find the source of bug later.
              if row == -409
                 row := 6
              if row == -399
                 row := 7
              if row == -389
                 row := 8
              if row == -379
                 row := 9
              row--

              
              if row < 0
                 row:=0
              if col < 0
                 col:=0
              if row > 35
                 row :=35
              if col > 79
                 col := 79
              text.cursloc(col,row)
            vt100:=0
         if remote == 114       'ESCr 
            
               text.out(126)
         if remote == 74    '' CLEAR SCREEN
            if byte2==91    '' look for [J  '' clear screen from cursor to 25
               text.clsfromcursordown 
            'vt100:=0
            if byte2==50    '' look for [2J '' clear screen
               text.cls(Baud,termcolor,pcport,ascii,CR)
            if byte2==49     'look for [1J
               text.clstocursor
            if byte2==48     'look for [0J
               text.clsfromcursordown
            vt100:=0
         if remote == 66    '' CURSOR DOWN    Esc[ValueB
            if byte4 == 91 '' Assume number over 10
              byte3:=byte3-48
              byte2:=byte2-48
              byte3:=byte3*10
              byte3:=byte3+byte2
              var1:=byte3
            if byte3 == 91 '' Assume number is less 10
              byte2:=byte2-48
              var1:=byte2
            if byte2 == 91 ''ESC[B no numbers move down one
              'text.out($C3)
              var1 := 1
            loop:=0
            repeat until loop == var1
               loop++
               text.out($C3)

            vt100:=0


         if remote == 65    '' CURSOR UP   Esc[ValueA
            if byte4 == 91 '' Assume number over 10
              byte3:=byte3-48
              byte2:=byte2-48
              byte3:=byte3*10
              byte3:=byte3+byte2
              var1:=byte3
            if byte3 == 91 '' Assume number is less 10
              byte2:=byte2-48
              var1:=byte2
            if byte2 == 91 ''ESC[A no numbers move down one
            
              var1 := 1
            loop:=0
            repeat until loop == var1
               text.out($C2)
               loop++
            vt100:=0


         if remote == 67    '' CURSOR RIGHT   Esc[ValueC
            if byte4 == 91 '' Assume number over 10
              byte3:=byte3-48
              byte2:=byte2-48
              byte3:=byte3*10
              byte3:=byte3+byte2
              var1:=byte3
            if byte3 == 91 '' Assume number is less 10
              byte2:=byte2-48
              var1:=byte2
            if byte2 == 91 ''ESC[C no numbers move RIGHT one
            
              var1 := 1
            loop:=0
            repeat until loop == var1
               text.out($C1)
               loop++
            vt100:=0

         if remote == 68    '' CURSOR LEFT   Esc[ValueD  OR ESC[D
            if byte4 == 91 '' Assume number over 10
              byte3:=byte3-48
              byte2:=byte2-48
              byte3:=byte3*10
              byte3:=byte3+byte2
              var1:=byte3
            if byte3 == 91 '' Assume number is less 10
              byte2:=byte2-48
              var1:=byte2
            if byte2 == 91 ''ESC[D no numbers move LEFT one
            
              var1 := 1
            loop:=0
            repeat until loop == var1
               text.out($C0)   'was $C0
               loop++
            vt100:=0  
            
         if remote == 75   '' Clear line  Esc[K
           if byte2 == 91 '' Look for [
             text.clearlinefromcursor
             
             vt100:=0
           if byte2  == 48 ' look for [0K
              if byte3 == 91
                 text.clearlinefromcursor
                 
                 vt100:=0
           if byte2 == 49  ' look for [1K
              if byte3 == 91
                 text.clearlinetocursor
                 vt100 := 0
           if byte2 == 50 ' look for [2K
              if byte3 == 91
                 text.clearline
                 
                 vt100 := 0  

         if remote == 99 ' look for [0c or [c           ESC [ ? 1 ; Ps c Ps=0 for VT-100 no options
           if byte2 == 91 '' Look for [
                ser2.str(string(27,"[?1;0c"))
                vt100 := 0
           if byte2 == 48
                if byte3 == 91
                     ser2.str(string(27,"[?1;0c"))
                     vt100 := 0
         remote:=0 '' hide all codes from the VGA output.
      
      if record == 13 and remote == 13  ''LF CHECK
         if CR == 1
           text.out(remote)
         remote :=0
      if remote == 08
         remote := $C0    'now backspace just moves cursor, doesn't clear character
      if remote == 7
         sound(source, 4500)
     ' if remote == 10
     '    text.out($0A)     
      if remote > 8
         text.out(remote)
      record:=remote ''record last byte


PUB EEPROM | eepromData
        eepromLocation := EEPROM_Base
        
        i2c.WriteLong(i2cSCL, EEPROMAddr, eepromLocation, 55)
        eepromLocation +=4
        i2c.WriteLong(i2cSCL, EEPROMAddr, eepromLocation, Baud)
        eepromLocation +=4
        i2c.WriteLong(i2cSCL, EEPROMAddr, eepromLocation, termcolor)
        eepromLocation +=4
        i2c.WriteLong(i2cSCL, EEPROMAddr, eepromLocation, pcport)
        eepromLocation +=4
        i2c.WriteLong(i2cSCL, EEPROMAddr, eepromLocation, ascii)
        eepromLocation +=4
        i2c.WriteLong(i2cSCL, EEPROMAddr, eepromLocation, curset)
        eepromLocation +=4
        i2c.WriteLong(i2cSCL, EEPROMAddr, eepromLocation, CR)
        waitcnt(clkfreq/200 + cnt)
        


PUB Sound (pWav,speed):bOK|n,i,nextCnt,rate,dcnt,wait

  pWav+=44

  i:=0
  NextCnt:=cnt  '+15000

  'Play loop
  repeat i from 0 to 1200
    NextCnt+=speed
    waitcnt(NextCnt)
    FRQA:=(byte[pWav+i])<<24
    FRQB:=FRQA

PUB forever  | i
  repeat i from 0 to 1000
     waitcnt(i*32767)
DAT

PIANO
File "piano.wav"      '   <---  put your 8-bit PCM mono 8000 sample/second WAV