' {$STAMP BS2}
' {$PBASIC 2.5}
' {$PORT COM7}
'E-Prom Reader, Writer & Editor V3
'By Steven R. Cypherd 1/7/2013
'There is no more room.
'Took out + formatting
'Added Insert & Delete
'Erase sets last string to 0s
'25C160 Serial E-Prom
'This is a 16K with 128 16 Byte pages
'E-Prom Pins
'	1	epCs	(13)	Chip Select
'	2	epSo	(11)	Serial Out
'	3	WP		(VDD)	Write Protect
'	4	VSS		(G)		Ground
'	5 epSi	(10)	Serial In
'	6 epCk	(12)	Serial Clock
'	7	H			(VDD)	Hold
'	8	V+		(VDD)	VDD
'Constants
'Serial E-Prom
epRead    CON 	%00000011 'Read + epAddr
epWrite   CON 	%00000010 'Write + epAddr
epWrtDI   CON 	%00000100 'Write Disable
epWrtEN		CON		%00000110 'Write Enable Before Write
epStatR   CON 	%00000101 'Read Status
epStatW   CON 	%00000001 'Write Status
epSi      CON 	10 'For ShiftIn command
epSo     	CON 	11
epCk      CON 	12
'Ports
epCs      PIN 	13
btn1      PIN 	6 	'B1 to pin, 10k to G. B2 to VDD
lit1	    PIN	7		'Led+ to R470 to pin. Led- G
'Variables
epAddr    VAR   Word
myStr     VAR   Byte(17)
runFlags  VAR   Byte
Btn1IN    VAR   runFlags.BIT0 'Button 1
InStr     VAR   runflags.BIT1 'String Entered
edStr     VAR   runFlags.BIT2 'Editting Strings
strOpn    VAR   runFlags.BIT3 'Opens E-Prom
insStr    VAR   runFlags.BIT4 'Insert String
delStr    VAR   runFlags.BIT5 'Delete String
delErs    VAR   runFlags.BIT6 'Del erase Str
eraseStr  VAR   runFlags.BIT7 'Erase String
tmp1      VAR   Byte
tmp2      VAR   Byte
tmp3      VAR   Byte
tmp4      VAR   Byte
tmp5      VAR   Byte
myStrS    VAR   Byte 'String count

main:
  btn1IN = 0
  edStr = 0
  epAddr = 0
  eraseStr = 0
  delErs = 0
  strOpn = 0
  insStr = 0
  delStr = 0
  InStr = 1
  'Starts NEW E-Prom myStrS = 0
  'Change myStrs 1 or higher loads from EEProm
  myStrS = 0
  HIGH epCs
  IF myStrS > 0 THEN
		READ 0, Word epAddr, myStrS
		DEBUG CR, "You have ", DEC myStrS, " strings"
    strOpn = 1
    GOTO StringsOut
  ELSE
    GOTO CmdDisplay
    ENDIF

doIt:
  IF edStr = 1 THEN
  	edStr = 0
    strOpn = 1
    IF myStrS > 0 THEN GOTO StringsOut
    ENDIF

  HIGH lit1
  IF btn1 = 0 THEN WriteString
  btn1IN = 1
  HIGH lit1
  DEBUG "10 is Edit New", CR
  DEBUG "20 set String COUNT", CR
  DEBUG "30 is display, 40 String # Edit", CR
  DEBUG "50 Delete, 55 Insert", CR
  DEBUG "60 Erase On, 65 Erase Off", CR
  DEBUG "90 write Str Count, 95 read Str Cnt", CR
  DEBUG "Enter Command :or 0 to clear", CR
  DEBUGIN DEC tmp1
  strOpn = 1
  IF tmp1 = 10 THEN
    InStr = 0
    GOTO WriteString
  ELSEIF tmp1 = 20 THEN
    DEBUG "Enter Last String #"
    DEBUGIN DEC tmp1
    IF tmp1 = 0 THEN GOTO CmdDisplay
    inStr = 1
    myStrs = tmp1
    GOTO StringsOut
  ELSEIF tmp1 = 30 THEN
    IF myStrS > 0 THEN
      GOTO StringsOut
      ENDIF
    DEBUG "No Strings", CR
  ELSEIF tmp1 = 40 THEN
    DEBUG "Enter string # to Edit", CR
    DEBUGIN DEC tmp1
    IF tmp1 = 0 THEN GOTO CmdDisplay
    edStr = 1
    InStr = 0
    tmp5 = tmp1
    tmp1 = tmp1 - 1
    epAddr = 16 * tmp1
    LOW epCs
    GOSUB loadStr
    GOTO WriteString
  ELSEIF tmp1 = 50 THEN
    DEBUG "String # to Delete", CR
    DEBUGIN DEC tmp1
    IF tmp1 = 0 THEN GOTO CmdDisplay
    GOTO StringDelete
  ELSEIF tmp1 = 55 THEN
    DEBUG "String # to Insert", CR
    DEBUGIN DEC tmp1
    IF tmp1 = 0 THEN GOTO CmdDisplay
    GOTO StringInsert
  ELSEIF tmp1 = 60 THEN
  	eraseStr = 1
    DEBUG CR, "Erase On"
    GOTO StringsOut
  ELSEIF tmp1 = 65 THEN
  	eraseStr = 0
    DEBUG CR, "Erase Off"
    GOTO StringsOut
  ELSEIF tmp1 = 90 THEN
    DEBUG "Writing string count"
    WRITE 0, Word epAddr, myStrS
    GOTO StringsOut
  ELSEIF tmp1 = 95 THEN
    DEBUG "Getting strings"
    READ 0, Word epAddr, myStrS
    GOTO StringsOut
    ENDIF

CmdDisplay:
  strOpn = 0
  DEBUG CR, "Press the button for commands",CR
	GOTO WriteString

StringInsert:
  tmp5 = tmp1	'Can do 0 here
  tmp3 = myStrS
  myStrS = myStrS + 1
  tmp4 = myStrS
  insStr = 1
  epAddr = 16 * myStrS
  WRITE 0, Word epAddr, myStrS
strIns2:
  DEBUG "Ins", DEC tmp3
  epAddr = 16 * tmp3
  strOpn = 1
  LOW epCs
  PAUSE 5
  GOSUB loadStr
  epAddr = 16 * tmp4
  inStr = 0
  HIGH epCs
  PAUSE 5
  GOTO WriteString
strIns3:
  tmp3 = tmp3 - 1
  tmp4 = tmp4 - 1
  IF tmp4 >= tmp5 THEN strIns2
  DEBUG DEC tmp5, CR
  tmp5 = tmp5 - 1	'Math errors 16 * tmp5 - 1
  epAddr = 16 * tmp5	'is (16 * tmp5) - 1
  insStr = 0	'Address Off by 1 is wrong
  inStr = 0
  tmp5 = 0	'My fix for two edits
  edStr = 1	'Reads epAddr
  GOTO WriteString

StringDelete:
  tmp3 = tmp1 - 1
  IF myStrS = tmp3 THEN
    tmp3 = myStrS
    GOTO strDel4
    ENDIF
  tmp4 = tmp1
  delStr = 1
  delErs = eraseStr
strDel2:
  DEBUG "Del", DEC tmp3
  epAddr = 16 * tmp4
  strOpn = 1
  LOW epCs
  PAUSE 5
  GOSUB loadStr
  epAddr = 16 * tmp3
  inStr = 0
  HIGH epCs
  PAUSE 5
  GOTO WriteString
strDel3:
  tmp3 = tmp3 + 1
  tmp4 = tmp4 + 1
  IF tmp3 <= myStrS THEN strDel2
strDel4:
  IF delErs = 1 THEN
    FOR tmp1 = 0 TO 16
    	myStr(tmp1) = 0
      NEXT
    delErs = 0
    inStr = 0
    epAddr = 16 * myStrS
    GOTO WriteString
    ENDIF	'Best way to write string
  delStr = 0
  myStrS = myStrS - 1
  epAddr = 16 * myStrS
  WRITE 0, Word epAddr, myStrS
  strOpn = 1

'String output
StringsOut:
  DEBUG CR, "Strings", CR
  epAddr = 0
  LOW epCs
  PAUSE 5
  FOR tmp1 = 1 TO myStrS
    GOSUB loadStr	'Read in strings
    myStr(16) = 0
    DEBUG DEC tmp1, ". ", STR myStr, CR
    NEXT
  HIGH epCs 'Set Chip Select High - Close Command
  epAddr = myStrS * 16
  GOTO CmdDisplay

WriteString:'Enter a String
  IF InStr = 1 THEN WritePass
  IF insStr = 1 OR delStr = 1 THEN putInStr
  DEBUG "Enter a String up to 16 chars", CR
  IF edStr = 1 AND tmp5 <> 0 THEN
    DEBUG DEC tmp1, " is ", STR myStr, CR
    HIGH epCs
    ENDIF
  DEBUG "-------++------", CR
  'Command line editing doesn't work here
  DEBUGIN STR myStr\16\13
  myStr(16) = 0
  FOR tmp1 = 0 TO 16
    IF myStr(tmp1) = 0 THEN EXIT
    NEXT
  IF tmp1 = 0 THEN WritePass
  DEBUG "lenghth is ", DEC tmp1, CR
putInStr:
  LOW epCs 'Set Chip Select Low - Open Command
  PAUSE 5	'You must Enable Writing first
  SHIFTOUT epSi, epCk, MSBFIRST, [epWrtEN\8]
  PAUSE 5
  HIGH epCs	'You must Enter the command
  PAUSE 5
  LOW epCs 'Set Chip Select Low - Open Command
  PAUSE 5	'Then you write all 16 bytes(1 page)
  SHIFTOUT epSi, epCk, MSBFIRST, [epWrite\8, epAddr\16]
  PAUSE 5
  FOR tmp2 = 0 TO 15
    SHIFTOUT epSi, epCk, MSBFIRST, [myStr(tmp2)\8]
    PAUSE 5
    NEXT
  HIGH epCs	'Then you enter the write request
  PAUSE 10
  InStr = 1
  IF insStr = 1 THEN strIns3
  IF delStr = 1 THEN strDel3
  IF edStr = 0 THEN
    epAddr = epAddr + 16
    myStrS = myStrS + 1
    edStr = 1
    WRITE 0, Word epAddr, myStrS
  ELSE
    READ 0, Word epAddr, myStrs
    ENDIF
  DEBUG "Done Writing", CR
WritePass:
  IF btn1 = 1 THEN jp1
  btn1IN = 0
jp1:
  LOW lit1
  PAUSE 200
  GOTO doIt
END

'Subroutines ****************
loadStr:'Edit a String
  IF strOpn = 1 THEN
  	SHIFTOUT epSi, epCk, MSBFIRST, [epRead\8, epAddr\16]
    PAUSE 5
    strOpn = 0
    ENDIF
  FOR tmp2 = 0 TO 15	'Read string into myStr
    SHIFTIN epSo, epCk, MSBPRE, [myStr(tmp2)\8]
    PAUSE 2
    NEXT
  RETURN
