From 9170ca860232c79be809e5a6cff01309ed419388 Mon Sep 17 00:00:00 2001 From: dschmenk Date: Sun, 14 Aug 2016 11:11:58 -0700 Subject: [PATCH] SdFat support from Arduino SPI slave --- src/inc/args.plh | 3 + src/inc/sdfat.plh | 30 +++++ src/inc/spiport.plh | 3 + src/inc/wireio.plh | 23 ++++ src/libsrc/args.pla | 33 ++++++ src/libsrc/sdfat.pla | 126 ++++++++++++++++++++ src/libsrc/spiport.pla | 240 +++++++++++++++++++++++++++++++++++++++ src/makefile | 22 +++- src/samplesrc/fatcat.pla | 49 ++++++++ src/vmsrc/cmd.pla | 7 +- 10 files changed, 532 insertions(+), 4 deletions(-) create mode 100644 src/inc/args.plh create mode 100644 src/inc/sdfat.plh create mode 100644 src/inc/spiport.plh create mode 100644 src/inc/wireio.plh create mode 100644 src/libsrc/args.pla create mode 100644 src/libsrc/sdfat.pla create mode 100644 src/libsrc/spiport.pla create mode 100644 src/samplesrc/fatcat.pla diff --git a/src/inc/args.plh b/src/inc/args.plh new file mode 100644 index 0000000..8c0c3ce --- /dev/null +++ b/src/inc/args.plh @@ -0,0 +1,3 @@ +import args + predef argFirst, argNext +end \ No newline at end of file diff --git a/src/inc/sdfat.plh b/src/inc/sdfat.plh new file mode 100644 index 0000000..29361eb --- /dev/null +++ b/src/inc/sdfat.plh @@ -0,0 +1,30 @@ +// +// FAT I/O object +// +import sdFAT + struc t_fatio + word dirGet + word dirSet + word dirNew + word dirRemove + word fileRename + word fileRemove + word fileExists + word fileOpenFirst + word fileOpenNext + word fileOpen + word fileClose + word fileRead + word fileWrite + word fileSync + word fileRewind + word fileSeek + word fileSeekOffset + word filePos + word fileSize + word fileTruncate + word fileIsDir + word fileIsFile + end + word sdFAT // sdFAT interface +end \ No newline at end of file diff --git a/src/inc/spiport.plh b/src/inc/spiport.plh new file mode 100644 index 0000000..dd71089 --- /dev/null +++ b/src/inc/spiport.plh @@ -0,0 +1,3 @@ +import spiport + predef spiXferByte, spiSend, spiRecv, spiWriteBuf, spiReadBuf, spiDelay +end diff --git a/src/inc/wireio.plh b/src/inc/wireio.plh new file mode 100644 index 0000000..5bb3302 --- /dev/null +++ b/src/inc/wireio.plh @@ -0,0 +1,23 @@ +// +// Wiring constants for Arduino +// +const PINHIGH = 1 +const PINLOW = 0 +const PINOUTPUT = 1 +const PININPUT = 0 +const PINPULLUP = 2 +// +// SPI commands to Wiring functions on Arduino +// +const CMDPINMODE = 3 +const CMDDIGREAD = 4 +const CMDDIGWRITE = 5 +const CMDANAREAD = 6 +const CMDANAWRITE = 7 +// +// SPI commands to serial functions on Arduino +// +const CMDSERMODE = 8 +const CMDSERAVAIL = 9 +const CMDSERREAD = 10 +const CMDSERWRITE = 11 diff --git a/src/libsrc/args.pla b/src/libsrc/args.pla new file mode 100644 index 0000000..7c96ea7 --- /dev/null +++ b/src/libsrc/args.pla @@ -0,0 +1,33 @@ +include "inc/cmdsys.plh" +const cmdline = $01FF + +def argDelim(str) + byte n + + // Strip leading spaces + while ^str and ^(str + 1) == ' ' + memcpy(str + 1, str + 2, ^str - 1) + ^str-- + loop + // Scan to trailing spaces (if any) + for n = 1 to ^str + if ^(str + n) <= ' ' + ^(str + n) = ^str - n + ^str = n - 1 + break + fin + next + return str +end + +export def argNext(str) + str = str + ^str + 1 + return argDelim(str) +end + +export def argFirst + // NULL terminate command line + ^(cmdline + ^cmdline + 1) = 0 + return argDelim(cmdline) +end + diff --git a/src/libsrc/sdfat.pla b/src/libsrc/sdfat.pla new file mode 100644 index 0000000..2f6809d --- /dev/null +++ b/src/libsrc/sdfat.pla @@ -0,0 +1,126 @@ +include "inc/spiport.plh" +// +// FAT I/O object +// +predef cwd, chdir, mkdir, rmdir, rename, remove, exists, openFirst, openNext, open +predef close, read, write, sync, rewind, seek, seekOfs, pos +predef size, truncate, isDir, isFile +// +// SD card FAT filesystem interface +// +export byte[] sdFAT +word[] = @cwd, @chdir, @mkdir, @rmdir, @rename, @remove, @exists, @openFirst, @openNext, @open +word[] = @close, @read, @write, @sync, @rewind, @seek, @seekOfs, @pos +word[] = @size, @truncate, @isDir, @isFile +// +// Directory related functions +// +def cwd(pathname) + byte namelen + + namelen = 0 + spiSend(15) + namelen = spiSend(15)//spiRecv + if namelen + spiReadBuf(pathname+1, namelen) + fin + ^pathname = namelen + return namelen +end + +def chdir(path) + spiWriteBuf(path + 1, ^path) + spiSend(16) // CHGDIR + return spiSend(16)//spiRecv +end + +def mkdir(path) +end + +def rmdir(path) +end + +def rename(newpath) +end + +def remove +end + +def exists(path) +end + +def openDir(cmd, filename) + byte namelen + + namelen = 0 + spiSend(cmd) + namelen = spiSend(cmd)//spiRecv + if namelen == 0xFF + namelen = 0 + fin + if namelen + spiReadBuf(filename+1, namelen) + fin + ^filename = namelen + return namelen +end +def openFirst(filename) // return filename in buffer + return openDir(22, filename) // OPENFIRST +end + +def openNext(filename) // return filename i buffer + return openDir(23, filename) // OPENNEXT +end + +// +// File related functions +// +def open(path) +end + +def close + spiSend(24) // CLOSE +end + +def read(buf, len) +end + +def write(buf, len) +end + +def sync +end + +def rewind +end + +def seek +end + +def seekOfs +end + +def pos +end + +def size +end + +def truncate +end + +def isDir + spiSend(35) // ISDIR + return spiSend(35)//spiRecv +end + +def isFile +end + +// +// Init SD card FAT filesystem +// +spiSend(14) // SDINIT +spiDelay(100) +return spiRecv <> '@' // Is Arduino READY? +done \ No newline at end of file diff --git a/src/libsrc/spiport.pla b/src/libsrc/spiport.pla new file mode 100644 index 0000000..e9bbf86 --- /dev/null +++ b/src/libsrc/spiport.pla @@ -0,0 +1,240 @@ +import cmdsys + predef call, putc +end +// +// Bit banged spi over gameport +// +asm spiInc +!SOURCE "vmsrc/plvmzp.inc" +end + +export asm spiXferByte(outbyte) + STA $C05A ; ENABLE SLAVE + LDY #0 ; ASSUME MSB IS ZERO + LDA ESTKL,X ; GET ARGUMENT + BPL + ; CHECK MSB + INY ; IT'S A ONE ++ STA $C058,Y ; WRITE BIT 7 + STA $C040 ; CLOCK + LDY #0 ; DOING THIS HERE GIVES TIME FOR OUTPUT TO BECOME STABLE - NOT REALLY NEEDEDd + ASL $C061 ; READ BIT 7 INTO CARRY + ROL ; ROTATE INTO ACC + BPL + ; REPEAT FOR ALL BITS + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ASL $C061 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ASL $C061 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ASL $C061 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ASL $C061 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ASL $C061 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ASL $C061 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + ASL $C061 + STA $C05B ; DISABLE SLAVE + ROL + STA ESTKL,X ; SAVE RETURN PARAMETER + RTS +end + +asm spiReadBytes(buf, len) + LDA ESTKL+1,X + STA DSTL + LDA ESTKH+1,X + STA DSTH + LDA ESTKL,X + BEQ + + INC ESTKH,X ++ LDY #$00 +- STA $C05A ; ENABLE SLAVE + STA $C040 ; CLOCK + ASL $C061 ; SHIFT IN ALL BITS STARTING WITH MSB + STA $C040 + ROL + ASL $C061 + STA $C040 + ROL + ASL $C061 + STA $C040 + ROL + ASL $C061 + STA $C040 + ROL + ASL $C061 + STA $C040 + ROL + ASL $C061 + STA $C040 + ROL + ASL $C061 + STA $C040 + ROL + ASL $C061 + STA $C05B ; DISABLE SLAVE + ROL + STA (DST),Y ; SAVE TO BUFFER + INY + BNE + + INC DSTH ++ DEC ESTKL,X + BNE - + DEC ESTKH,X + BNE - + INX ; REMOVE AN ARGUMENT + RTS +end + +asm spiWriteBytes(buf, len) + LDA ESTKL+1,X + STA SRCL + LDA ESTKH+1,X + STA SRCH + LDA ESTKL,X + BEQ + + INC ESTKH,X ++ +- STA $C05A ; ENABLE SLAVE + LDY #0 ; ASSUME MSB IS ZERO + LDA (SRC),Y ; GET BYTE + BPL + ; CHECK MSB + INY ; IT'S A ONE ++ STA $C058,Y ; WRITE BIT 7 + STA $C040 ; CLOCK + LDY #0 ; DOING THIS HERE GIVES TIME FOR OUTPUT TO BECOME STABLE + ROL ; ROTATE NEXT BIT TO SEND + BPL + ; REPEAT FOR ALL BITS + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + LDY #0 + ROL + BPL + + INY ++ STA $C058,Y + STA $C040 + STA $C05B ; DISABLE SLAVE + INC SRCL + BNE + + INC SRCH ++ DEC ESTKL,X + BNE - + DEC ESTKH,X + BNE - + INX ; REMOVE AN ARGUMENT + RTS +end + +export def spiDelay(time) + return call($fca8, time, 0, 0, 0) // DELAY +end + +export def spiSend(data) + byte timeout, status + + for timeout = 0 to 50 step 10 + status = spiXferByte(data) + if status <> $ff + return status + fin + spiDelay(timeout) + next + putc(status);putc('0'+data/10);putc('0'+data%10) + return status +end + +export def spiRecv + return spiSend(0) +end + +export def spiWriteBuf(buf, len) + spiSend(13) // CMD_BUF_WRITE + spiSend(len>>8) // LEN_HI + spiSend(len) // LEN_LO + return spiWriteBytes(buf, len) +end + +export def spiReadBuf(buf, len) + spiSend(12) // CMD_BUF_READ + spiSend(len>>8) // LEN_HI + spiSend(len) // LEN_LO + return spiReadBytes(buf, len) +end + +export def spiReset + byte timeout, status + ^$C05B + timeout = $FF + repeat + status = spiSend(0) + timeout-- + until status == '@' or !timeout // WAIT FOR READY + return status <> '@' +end + +return spiReset +done diff --git a/src/makefile b/src/makefile index a2aa05b..09acdad 100644 --- a/src/makefile +++ b/src/makefile @@ -9,6 +9,10 @@ ED = ED\#FF2000 SB = SB\#FF2000 ROD = ROD\#FE1000 SIEVE = SIEVE\#FE1000 +ARGS = ARGS\#FE1000 +SPIPORT = SPIPORT\#FE1000 +SDFAT = SDFAT\#FE1000 +FATCAT = FATCAT\#FE1000 WIZNET = WIZNET\#FE1000 UTHERNET2= UTHERNET2\#FE1000 UTHERNET= UTHERNET\#FE1000 @@ -53,7 +57,7 @@ TXTTYPE = .TXT #SYSTYPE = \#FF2000 #TXTTYPE = \#040000 -all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(PORTIO) +all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT) clean: -rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) @@ -110,6 +114,10 @@ $(SB): toolsrc/sb.pla $(PLVM02) $(PLASM) toolsrc/sb.pla ./$(PLASM) -A < toolsrc/sb.pla > toolsrc/sb.a acme --setpc 8192 -o $(SB) toolsrc/sb.a +$(ARGS): libsrc/args.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AM < libsrc/args.pla > libsrc/args.a + acme --setpc 4094 -o $(ARGS) libsrc/args.a + $(MEMMGR): libsrc/memmgr.pla $(PLVM02) $(PLASM) ./$(PLASM) -AM < libsrc/memmgr.pla > libsrc/memmgr.a acme --setpc 4094 -o $(MEMMGR) libsrc/memmgr.a @@ -162,6 +170,18 @@ $(TONE): libsrc/tone.pla $(PLVM02) $(PLASM) ./$(PLASM) -AM < libsrc/tone.pla > libsrc/tone.a acme --setpc 4094 -o $(TONE) libsrc/tone.a +$(FATCAT): samplesrc/fatcat.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AM < samplesrc/fatcat.pla > samplesrc/fatcat.a + acme --setpc 4094 -o $(FATCAT) samplesrc/fatcat.a + +$(SDFAT): libsrc/sdfat.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AM < libsrc/sdfat.pla > libsrc/sdfat.a + acme --setpc 4094 -o $(SDFAT) libsrc/sdfat.a + +$(SPIPORT): libsrc/spiport.pla $(PLVM02) $(PLASM) + ./$(PLASM) -AM < libsrc/spiport.pla > libsrc/spiport.a + acme --setpc 4094 -o $(SPIPORT) libsrc/spiport.a + $(PORTIO): libsrc/portio.pla $(PLVM02) $(PLASM) ./$(PLASM) -AM < libsrc/portio.pla > libsrc/portio.a acme --setpc 4094 -o $(PORTIO) libsrc/portio.a diff --git a/src/samplesrc/fatcat.pla b/src/samplesrc/fatcat.pla new file mode 100644 index 0000000..4d944e2 --- /dev/null +++ b/src/samplesrc/fatcat.pla @@ -0,0 +1,49 @@ +include "inc/cmdsys.plh" +include "inc/args.plh" +include "inc/sdfat.plh" + +word arg +byte[64] cwd +byte[64] pathname + +def fatCat(path) + byte filename[32] + + sdFAT:dirSet(path) + puts("Directory of "); puts(path); puts(":\n") + sdFAT:fileOpenFirst(@filename) + while filename + puts(" "); puts(@filename) + if sdFAT:fileIsDir(); putc('/'); fin + putln + sdFAT:fileClose() + sdFAT:fileOpenNext(@filename) + loop +end + +sdFAT:dirGet(@cwd) +if cwd[cwd] <> '/' // append '/' to cwd if needed + cwd++ + cwd[cwd] = '/' +fin +arg = argNext(argFirst) +if ^arg + while ^arg + if ^(arg + 1) <> '/' // relative path argument - append to cwd + memcpy(@pathname, @cwd, cwd + 1) + else + pathname = 0 // absolute path + fin + memcpy(@pathname + pathname + 1, arg + 1, ^arg) // append path argument + pathname = pathname + ^arg + if pathname[pathname] <> '/' + pathname++ + pathname[pathname] = '/' + fin + fatCat(@pathname) + arg = argNext(arg) + loop +else + fatCat(@cwd) +fin +done \ No newline at end of file diff --git a/src/vmsrc/cmd.pla b/src/vmsrc/cmd.pla index 9697de1..89b1969 100644 --- a/src/vmsrc/cmd.pla +++ b/src/vmsrc/cmd.pla @@ -33,7 +33,7 @@ predef loadmod, execmod, lookupstrmod // // System variable. // -word version = $0092 // 00.92 +word version = $0093 // 00.93 word systemflags = 0 word heap word xheap = $0800 @@ -1188,9 +1188,10 @@ def striptrail(strptr) for i = 1 to ^strptr if ^(strptr + i) <= ' ' ^strptr = i - 1 - return + return strptr fin next + return strptr end def parsecmd(strptr) byte cmd @@ -1317,7 +1318,7 @@ while 1 execsys(@cmdln) break is '+' - execmod(@cmdln) + execmod(striptrail(@cmdln)) break otherwise cout('?')