' Getting USER-Input and executes Commands

Declare Sub DoCommand()
Declare Sub ExtractToken()
Declare Function GetNextTokenStr(ByVal pbLen_Max as Byte ) as String
Declare Function GetNextTokenLong(byVAl plMin as Long , byVal plMax as Long ) as Long
Declare Sub PrintParameterErrorl(plParamLow as Long , plParamHigh as Long)
Declare Sub PrintParameterCountError(byVal psParm_Anzahl as String)
Declare Sub GetInput(byVal pbByte as Byte)
Declare Sub PrintPrompt()
Declare Function GetLongFromBuffer(pbSRAMArray as Byte , byVal pbPos as Word) as Long
Declare Function GetWordFromBuffer(pbSRAMArray as Byte , byVal pbPos as Word) as Word

Declare Sub WriteFileDivVariables(pFN as Byte , pByte as Byte , pInt as Integer , pWord as Word , pLong as Long , pSingle as Single , pString as String , pDummy as Byte)
Declare Sub ReadFileDivVariables(pFN as Byte , pByte as Byte , pInt as Integer , pWord as Word , pLong as Long , pSingle as Single , pString1 as String , pString2 as String , pDummy as Byte)
Dim TransferBuffer_Write as Word
Const cpNo = 0                          '
Const cpYes = 1

Const cpToken_max = 10                  ' Count of Tokens in USER-Input
Const cpStrsep = " "                    ' Blank: Separator between tokens
Dim abInterpreterBuffer(512) as Byte
Const cPCInput_Len = 80                 ' max. length of user-Input
Dim gsPCInput as String * 80            ' holds user-input
Dim gbPosStrParts(cpToken_max) As Byte  ' for analysing user-input
Dim gbLenStrParts(cpToken_max) As Byte  '
Dim gbCntToken As Byte                  ' found tokens in user-input
Dim gbToken_Actual as Byte              ' actual handled token of user-input
Dim gbPCInPutError as Byte              ' holds error-code during analysing user-input
Dim gbPCInputPointer as Byte            ' string-pointer during user-input
Dim gsTestLine as String * 40


gbPCInputPointer = 1

Dim tByte1 as Byte

Dim gwTemp1 as Word
Dim bSec as BYte , bMin as BYte , bHour as Byte , bDay as Byte , bMonth as Byte , bYear as BYte

'End


Sub GetInput(pbByte as Byte)
    ' stores bytes from user and wait for CR (&H13)
   Print #1 , chr(pbByte);              ' echo back to user
   select case pbByte
      Case &H0D                         ' Line-end?
         print #1 , chr(&H0A)
         DoCommand                      ' analyse command and execute
         gbPCInputPointer = 1           ' reset for new user-input
         gsPCInput = ""
         PrintPrompt
      case &H08                         ' backspace ?
         decr gbPCInputPointer
      case Else                         ' store user-input
         mid(gsPCINput , gbPCInputPointer , 1) = pbByte
         incr gbPCInputPointer
         mid(gsPCInput , gbPCInputPointer , 1) = &H00       ' string-terminator
         if gbPCInputPointer > cPCInput_Len then       'don't exceed input-string
            gbPCInputPointer = cPCInput_Len
            print #1 , &H08
         end if
   end Select
End Sub


Sub DoCommand
   ' interpretes the user-input and execute
   ' Local variables
   Local lByte1 as Byte , lByte2 as Byte , lByte3 as Byte
   Local lInt1 as Integer , lInt2 as Integer
   Local lWord1 as Word , lWord2 as Word , lWord3 as Word
   Local lLong1 as Long , lLong2 as Long , lLong3 as Long , lLong4 as Long
   Local lSingle1 as Single
   Local lbPos as Byte

   Local lsToken as String * 20         ' Hold Tokens
   Local lbLen as Byte
   Local lwSRAMPointer as Word
   lDumpBase = 0
   ExtractToken                         ' token analysing
   gbToken_actual = 0                   ' reset to beginn of line (first token)
   gbPCInputError = cpNo
   gwtemp1 = 1
   If gbcntToken > 0 Then               ' is there any input

      lsToken = GetNextTokenStr(20)     ' get first string-token = command
      lstoken = ucase(lsToken)          ' all uppercase
      lwSRAMPointer = varptr(abInterpreterBuffer(1))
                                         ' Pointer to SRAM Buffer
      Select Case lsToken
         Case "CFI"                     ' Show CF-Card Information Block
              Print #1 , "Read Card Info"
              lByte1 = DriveGetIdentity(lwSRAMPointer)       ' read Info to SRAM
              TransferBuffer_Write = 0
              SRAMDump lwSRAMPointer , 512 , lDumpBase       ' Dump SRAM
              ' Get Count of Sectors in Compactflash-Card
              lLong1 = GetLongFromBuffer(abInterpreterBuffer(1) , 120) : lLong2 = lLong1 * 512
              print #1 , lLong1 ; " Sectors = " ; lLong2 ; " Bytes"
              ' Get Buffersize of Compactflash-Card
              lWord1 = GetWordFromBuffer(abInterpreterBuffer(1) , 42)
              lLong2 = lWord1 * 512
              print #1 , "CF-Buffersize = " ; lWord1 ; " Sectors = " ; lLong2 ; " Bytes"

         Case "CFR"                     ' Reset Compactflash Card
              lByte1 = DriveReset()

         Case "MBR"                     ' Show Masterboot record = Sector 0
            lLong1 = 0
            print #1 , "Read Master Boot Record ... " ;
            lByte1 = DriveReadSector(LWSRAMPointer , lLong1 )       ' read Sector to abInterpreterBuffer
            TransferBuffer_Write = 0
            print #1 , "done"
            SRAMDump lwSRAMPointer , 512 , lDumpBase       ' show abInterpreterBuffer
            print #1 , " " : Print #1 , "Partition-Table" : print #1 , " "
            lWord1 = 446                ' first partition entry starts at 446
            for lByte1 = 1 to 4
               lWord2 = lWord1 + 1
               if abInterpreterBuffer(lWord2) > 0 then
                  print #1 , "Partition " ; lByte1 ; " " ;
                  lWord2 = lWord1 + 8
                  lLong1 = GetLongFromBuffer(abInterpreterBuffer(1) , lWord2)
                  lWord2 = lWord1 + 12
                  lLong2 = GetLongFromBuffer(abInterpreterBuffer(1) , lWord2)
                  lLong3 = lLong1 + lLong2
                  print #1 , "Sector: " ; lLong1 ; " to " ; lLong3 ; " = " ; lLong2 ; " Sectors; ";
                  lWord2 = lWord1 + 5
                  lByte1 = abInterpreterBuffer(lWord2)
                  print #1 , "File-System Type: " ; hex(lByte1)
               end if
               lWord1 = lWord1 + 16
            next

         Case "SD"                      ' Sector Dump
            If gbCntToken = 2 then
               lLong1 = GetNextTokenLong(0 , 2000000)
               lLong2 = lLong1
            elseif gbCntToken = 3 then
               lLong1 = GetNextTokenLong(0 , 2000000)
               lLong2 = GetNextTokenLong(lLong1 , 2000000)
            else
                PrintparameterCountError "1, 2 "
                exit sub
            end if
            If gbPCInputError = cpNo then
               print #1 , "Dump Sectors from " ; lLong1 ; " to " ; lLong2
               for lLong3 = lLong1 to lLong2
                   print #1 , "Read Sector: " ; lLong3 ; " ... " ;
                   lwSRAMPointer = varptr(abInterpreterBuffer(1))
                   lByte1 = DriveReadSector(lwSRAMPointer , lLong3)
                   print "Driver-Return=" ; lbyte1 ; " TO= " ; gwTemp1
                   TransferBuffer_Write = 0
                   Print #1 , " done"
                   lDumpBase = 0
                   lwSRAMPointer = varptr(abInterpreterBuffer(1))
                   SRAMDump lwSRAMPointer , 512 , lDumpBase
               next
            End if

         Case "MD"                      ' Memory Dump
              lWord2 = 512
              if gbCntToken = 1 then
              elseif gbCntToken = 2 then
                 lLong1 = GetNextTokenLong(0 , &HFFFF)
                 lwSRAMPointer = lLong1 ' assign to word
              elseif gbCntToken = 3 then
                 lLong1 = GetNextTokenLong(0 , &HFFFF)
                 lwSRAMPointer = lLong1 ' assign to word
                 lLong2 = GetNextTokenLong(1 , &HFFFF)
                 lWord2 = lLong2
              else
                  PrintParameterCountError "0, 1, 2 "
              end if
              if gbPCInputError = cpNo then
                 lDumpBase = lwSRAMPointer
                 SRAMDump lwSRAMPointer , lWord2 , lDumpBase       ' Show 512 Bytes
              End if

         Case "SW"                      ' Sector Write
            If gbCntToken = 3 then
               lLong1 = GetNextTokenLong(0 , 2000000)
               lLong2 = GetNextTokenLong(1 , &H7F)
               lLong2 = lLong2 - 1
               lLong3 = lLong1 + lLong2
            elseif gbCntToken = 4 then
               lLong1 = GetNextTokenLong(0 , 2000000)
               lLong2 = GetNextTokenLong(1 , &H7F)
               lLong2 = lLong2 - 1
               lLong3 = lLong1 + lLong2
               lLong4 = GetNextTokenLong(0 , &HFFFF)
               lwSRAMPointer = lLong4
            else
               PrintparameterCountError "2, 3 "
               exit sub
            end if
            If gbPCInputError = cpNo then
               print #1 , "Write " ; lByte1 ; " Sector(s) to " ; lLong1 ; " at CF-Card from " ;
               if gbCntToken = 4 then
                  print #1 , "SRAM Address " ; hex(lwSRAMPointer) ; " ... " ;
               else
                  print #1 , "Transfer-Buffer ... " ;
               end if
               for llong2 = lLong1 to lLong3
                  print #1 , "Write Sector " ; lLong2 ; " from SRAM " ; hex(lwSRAMPointer)
                  lByte1 = DriveWriteSector(lwSRAMPointer , lLong2)
                  print "Driver-Return=" ; lbyte1 ; " TO= " ; gwTemp1
                  print #1 , " done"
                  if gbCntToken = 4 then
                     lwSRAMPointer = lwSRAMPointer + 512
                  end if
               next
            End If


         Case "TESTSW"                  ' Sector Write
            If gbCntToken = 3 then
               lLong1 = GetNextTokenLong(0 , 2000000)
               lLong2 = GetNextTokenLong(1 , 100)
               lLong2 = lLong2 - 1
               lLong3 = lLong1 + lLong2
            else
               PrintparameterCountError "2, 3 "
               exit sub
            end if
            If gbPCInputError = cpNo then
               lByte1 = 0
               for lLong2 = 1 to 512
                  abInterpreterBuffer(lLong2) = lByte1
                  incr lByte1
               next

               print #1 , "Write " ; lByte1 ; " Sector(s) to " ; lLong1 ; " at CF-Card from " ;

               for llong2 = lLong1 to lLong3
                  print #1 , "Write Sector " ; lLong2 ; " from SRAM " ; hex(lwSRAMPointer)
                  lByte1 = DriveWriteSector(lwSRAMPointer , lLong2)
                  print "Driver-Return=" ; lbyte1 ; " TO= " ; gwTemp1
                  print #1 , " done"

                     lwSRAMPointer = lwSRAMPointer + 4

               next
            End If


        Case "TESTSWF"                  ' Sector Write
            If gbCntToken = 3 then
               lLong1 = GetNextTokenLong(0 , 2000000)
               lLong2 = GetNextTokenLong(1 , 10000)
               lLong2 = lLong2 - 1
               lLong3 = lLong1 + lLong2
            else
               PrintparameterCountError "2, 3 "
               exit sub
            end if
            If gbPCInputError = cpNo then
               lByte1 = 0
               for lLong2 = 1 to 512
                  abInterpreterBuffer(lLong2) = lByte1
                  incr lByte1
               next

               print #1 , "Write " ; lByte1 ; " Sector(s) to " ; lLong1 ; " at CF-Card from " ;
               print #1 , time$
               for llong2 = lLong1 to lLong3
                  'print #1 , "Write Sector " ; lLong2 ; " from SRAM " ; hex(lwSRAMPointer)
                  lByte1 = DriveWriteSector(lwSRAMPointer , lLong2)
                  if lByte1 <> 0 then
                     exit for
                  end if
                  'print "Driver-Return=" ; lbyte1 ; " TO= " ; gwTemp1


                     lwSRAMPointer = lwSRAMPointer + 1

               next
               print #1 , " done at " ; Time$
            End If

         Case "TESTVAR"

            if gbCntToken = 8 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1          ' Filenumber
               lLong1 = GetNextTokenLong(0 , 255)
               lByte2 = lLong1          ' TestByte
               lLong1 = GetNextTokenLong( -30000 , 30000)
               lInt1 = lLong1           ' TestInt
               lLong1 = GetNExtTokenLong(0 , 60000)
               lWord1 = lLong1          ' TEstWord
               lLong1 = GetNextTokenLong( -1000000 , 1000000)
               lsToken = GetNextTokenStr(10)
               lSingle1 = val(lsToken)
               lsToken = GetNextTokenStr(20)
               if gbPCInputError = cpNo then
                  WriteFileDivVariables lByte1 , lByte2 , lInt1 , lWord1 , lLong1 , lSingle1 , lsToken , lByte1
               end if
               PrintDOSError
            else
               PrintparameterCountError "7 "
            end if

         Case "TESTVARR"

              if gbCntToken = 2 then
                 lLong1 = GetNextTokenLong(1 , 255)
                 lByte1 = lLong1
                 if gbPCInputError = cpNo then
                    ReadFileDivVariables lbyte1 , lBYte2 , lInt1 , lWord1 , lLong1 , lSingle1 , lsToken , gsTestline , lByte1
                    print #1 ,  gstestline ; " " ;lByte2 ; " " ;  lInt1 ; " " ; lWord1 ; " " ; lLong1 ; " " ; lSingle1 ; " " ; lsToken
                    PrintDOSError

                 endif
              else
                 PrintParameterCountError "1 "
              endif

         Case "MT"                      ' Fill Memory with Text
            if gbCntToken > 1 then
               lByte1 = gbPosStrParts(2)
               do
                 incr TRANSFERBUFFER_WRITE
                 lsToken = mid(gsPCInput , lByte1 , 1)
                 lByte2 = ASC(lsToken)
                 if lByte2 = 0 then     ' String Terminator
                    exit do
                 end if
                 abInterpreterBuffer(Transferbuffer_Write) = lByte2
                 incr lByte1
               loop until Transferbuffer_Write > 511
               decr TRANSFERBUFFER_WRITE       ' 1 based to 0 based
           End IF

         Case "MP"                      ' Memory Pointer for MB and MT
              if gbCntToken = 2 then
                 lLong1 = GetNextTokenLong(0 , 511)
                 if gbPCInputError = cpNo then
                    TransferBuffer_Write = lLong1
                 end if
              else
                  PrintParameterCountError "1 "
              End if

         Case "MB"                      'Fill Memory with Same Byte
            if gbCntToken > 1 then
               for lByte1 = 2 to gbCntToken
                   lLong1 = GetNextTokenLong(0 , 255)
                   if gbPCInputError = cpNo then
                      incr TransferBuffer_Write
                      lByte2 = lLong1
                      abInterpreterBuffer(TransferBuffer_Write) = lByte2
                      if TransferBuffer_Write >= 511 then
                         exit for
                      end if
                   else
                      exit for
                   end if
               next
            end if

         Case "MF"

            lLong2 = TransferBuffer_Write : lLong3 = 511
            if gbCntToken = 2 then
               lLong1 = GetNextTokenLong(0 , 255)
            elseif gbCntToken = 3 then
               lLong1 = GetNextTokenLong(0 , 255)
               lLong2 = GetNextTokenLong(0 , 511)
            elseif gbCntToken = 4 then
               lLong1 = GetNextTokenLong(0 , 255)
               lLong2 = GetNextTokenLong(0 , 511)
               lLong3 = GetNextTokenLong(lLong2 , 511)
            else
                printParameterCountError "1, 2, 3 "
                exit sub
            end if
            If gbPCInputError = cpNo then
               lByte1 = lLong1
               incr lLong2 : lWord2 = lLong2
               Incr lLong3 : lWord3 = lLong3
               for lWord1 = lWord2 to lWord3
                   abInterpreterBuffer(lWord1) = lByte1
               next
               TransferBuffer_Write = lWord1 - 1
            end if

' ----------------------------------------------------------------------------
         Case "FS"                      ' init File Syste,
            lByte1 = 1
            lByte1 = InitFIleSystem(lByte1)
            if lByte1 = 0 then
               print #1 , "Filesystem: " ; gbFileSystem
               print #1 , "FAT Start Sector: " ; glFATFirstSector
               Print #1 , "Root Start Sector: " ; glRootFirstSector
               Print #1 , "Data First Sector: " ; glDataFirstSector
               Print #1 , "Max. Cluster Nummber: " ; gwMaxClusterNumber
               Print #1 , "Sectors per Cluster: " ; gbSectorsPerCluster
               Print #1 , "Root Entries: " ; gwRootEntries
               Print #1 , "Sectors per FAT: " ; gwSectorsPerFAT
               Print #1 , "Number of FATs: " ; gbNumberOfFATs
            else
               printDOSError
            End If

         Case "DIR"                     ' Directory
           If gbCntToken = 1 then
               lsToken = "*.*"
               Directory lsToken
           elseif gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               Directory lsToken
           else
              PrintParameterCountError "0 or 1 "
           End If

          Case "DIRT"                   ' Directory
           If gbCntToken = 1 then
               lsToken = "*.*"
               lWord1 = 7
               Directory1 lsToken , lWord1
           elseif gbCntToken = 3 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               lLong1 = GetNextTokenLong(0 , 1000)
               lWord1 = lLong1
               Directory1 lsToken , lWord1
           else
              PrintParameterCountError "0 or 1 "
           End If
          Case "DIR$"                   ' Directory
           If gbCntToken = 1 then
               gsTestline = Dir()
               print #1 , gstestline
               PrintDOSError
           elseif gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               gstestline = Dir(lsToken)
               print gsTestline
               PrintDOSError
           else
              PrintParameterCountError "0 or 1 "
           End If


         Case "FILEDATETIMEB"
           If gbCntToken = 1 then
               bSec = FileDateTime()
               if gbDOSError = 0 then
                  print #1 , bYear ; " " ; bmonth ; " " ; bDay ; " " ; bHour ; " " ; bmin ; " " ; bsec
               else
                  PrintDOSError
               end if
           elseif gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               bsec = FileDateTime(lsToken)
               if gbDOSError = 0 then
                  print #1 , bYear ; " " ; bmonth ; " " ; bDay ; " " ; bHour ; " " ; bmin ; " " ; bsec
               else
                  PrintDOSError
               end if
           else
              PrintParameterCountError "0 or 1 "
           End If


         Case "FILEDATETIMES"
           If gbCntToken = 1 then
               gsTestline = FileDateTime()
               print gsTestline
               PrintDOSError
           elseif gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               gstestline = FileDateTime(lsToken)
               print gsTestline
               PrintDOSError
           else
              PrintParameterCountError "0 or 1 "
           End If

         Case "FILELEN"
           If gbCntToken = 1 then
               lLong1 = FileLen()
               print #1 , lLong1
               PrintDOSError
           elseif gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               lLong1 = FileLen(lsToken)
               print lLong1
               PrintDOSError
           else
              PrintParameterCountError "0 or 1 "
           End If

         Case "GETATTR"
           If gbCntToken = 1 then
               lbyte1 = GetAttr0()
               print #1 , bin(lByte1)
               PrintDOSError
           elseif gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               lByte1 = GetAttr(lsToken)
               print #1 , bin(lByte1)
               PrintDOSError
           else
              PrintParameterCountError "0 or 1 "
           End If


         Case "TYPE"                    ' Type ASCII-file (sector by sector)
           if gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               lByte1 = PrintFile(lsToken)
               PrintDOSError
           else
              PrintParameterCountError "1 "
           End If

        Case "DUMP"                     ' Dump file
           if gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               lByte1 = DumpFile(lsToken)
               PrintDOSError
           else
              PrintParameterCountError "1 "
           End If

         Case "TYPEB"                   ' type ASCII-file (byte by byte)
           if gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               lByte1 = PrintFileB(lsToken)
               PrintDOSError
           else
              PrintParameterCountError "1 "
           End If


         Case "FOO"                     ' File open for Output
            if gbCntToken > 1 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               if gbCntToken > 2 then
                  lLong1 = getNextTokenLong(1 , 255)
                  lByte2 = lLong1
                  Open lsToken For Output as #lByte2
               else
                  lByte2 = FreeFile()
                  Open lsToken For Output as #lByte2
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               Else
                  Print #1 , "File# = " ; lByte2
               end if
           else
              PrintParameterCountError "1 "
           End If

         Case "FOI"                     ' File open for Input
            if gbCntToken > 1 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               if gbCntToken > 2 then
                  lLong1 = getNextTokenLong(1 , 255)
                  lByte2 = lLong1
                  Open lsToken For Input as #lByte2
               else
                  lByte2 = FreeFile()
                  Open lsToken For Input as #lByte2
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               Else
                  Print #1 , "File# = " ; lByte2
               end if
           else
              PrintParameterCountError "1 "
           End If


        Case "FOB"                      ' File open for Binary
            if gbCntToken > 1 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               if gbCntToken > 2 then
                  lLong1 = getNextTokenLong(1 , 255)
                  lByte2 = lLong1
                  Open lsToken For Binary as #lByte2
               else
                  lByte2 = FreeFile()
                  Open lsToken for Binary as #lByte2
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               Else
                  Print #1 , "File# = " ; lByte2
               end if
           else
              PrintParameterCountError "1 "
           End If

        Case "FOA"                      ' File open for Append
            if gbCntToken > 1 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               if gbCntToken > 2 then
                  lLong1 = getNextTokenLong(1 , 255)
                  lByte2 = lLong1
                  Open lsToken For Append as #lByte2
               else
                  lByte2 = Freefile()
                  Open lsToken For Append as #lByte2
               endif
               if gbDOSError = 0 then
                  Print #1 , "File# = " ; lByte2
               else
                  PrintDOSError
               end if
            else
              PrintParameterCountError "1 "
            End If

       Case "RLI"                       ' File line input
            if gbCntToken = 2 then
               lLong1 = GetNextTokenLong(1 , 255)       ' file#
               lByte1 = lLong1
               If gbPCInputError = cpNo then
                  Line Input #lByte1 , gstestline
                  if gbDOSError <> 0 then
                     PrintDOSError
                  else
                     print #1 , gstestline
                  end if
                End If
            else
               PrintParameterCountError "1 "
            End If

        case "LOC"                      ' File Location last read/write
             if gbCntToken = 2 then
                lLong1 = getNExtTokenLong(1 , 255)
                if gbPCInputError = cpNo then
                   lByte1 = lLong1
                   lLong2 = Loc(#lByte1)
                   if gbDOSError = 0 then
                      print #1 , lLong2
                   else
                      PrintDOSError
                   endif
                endif
             endif

        case "LOF"                      ' File Length
             if gbCntToken = 2 then
                lLong1 = getNExtTokenLong(1 , 255)
                if gbPCInputError = cpNo then
                   lByte1 = lLong1
                   lLong2 = Lof(#lByte1)
                   if gbDOSError = 0 then
                      print #1 , lLong2
                   else
                       PrintDOSError
                   endif
                endif
             else
                PrintParameterCountError "1 "
             endif

        case "SEEK"                     ' next byte position to read/write in file
             if gbCntToken = 2 then
                lLong1 = getNExtTokenLong(1 , 255)
                if gbPCInputError = cpNo then
                   lByte1 = lLong1
                   lLong2 = Seek(#lByte1)
                   if gbDOSError = 0 then
                      print #1 , lLong2
                   else
                       printdoserror
                   endif
                endif
             elseif gbCntToken = 3 then
                lLong1 = getNExtTokenLong(1 , 255)
                lLong2 = getNExtTokenLong(1 , 10000000)
                if gbPCInputError = cpNo then
                   lByte1 = lLong1
                   Seek #lByte1 , lLong2
                   printdoserror
                endif
             else
                PrintParameterCountError "1 or 2 "
             endif

         Case "DEL"                     ' delete file
            if gbCntToken = 2 then
               lsToken = GetNextTokenStr(12)
               lsToken = trim(lsToken)
               Kill lsToken
               PrintDOSError
           else
              PrintParameterCountError "1 "
           End If

         Case "WLI"                     ' Write line to file
            If gbCntToken = 3 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1
               lsToken = GetNextTokenStr(20)
               'print #lbyte1 , tstr1
               print #lByte1 , lstoken
               PrintDOSError
            else
               PrintParameterCountError "1 "
            End If

         Case "WLIM"                    ' write multiple lines to file
            If gbCntToken = 5 then
               lLong1 = GetNextTokenLong(1 , 255)
               lLong2 = GetNextTokenLong(1 , 10000)
               lLong3 = GetNextTokenLong(1 , 100000)
               lByte1 = lLong1
               lsToken = GetNextTokenStr(20)
               If gbPCInputError = cpNo then
                  for lLong4 = lLong2 to lLong3
                     gsTestLine = lsToken + " "
                     gsTestline = lsToken + str(lLong4)

                    print #lByte1 , gsTestLine
                    if gbdoserror <> 0 then
                       PrintDOSError
                       exit FOR
                    end if
                  next
               End If
            else
               PrintParameterCountError "4 "
            End If


         Case "WBY"                     ' Write byte to file
            If gbCntToken = 3 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1
               lsToken = GetNextTokenStr(1)
               lByte3 = asc(lstoken)    ' get first character
               lByte2 = FileByteOutput(lByte1 , lByte3)
               PrintDOSError
            else
               PrintParameterCountError "2 "
            End If

         Case "RBY"                     ' Read Byte from File
            If gbCntToken = 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1
               lByte2 = FileByteInput(lByte1 )
               if gbDOSError <> 0 then
                  PrintDOSError
               else
                  print #1 , chr(lByte2)
               end if
            else
               PrintParameterCountError "1 "
            End If

         Case "CLOSE"                   ' Close file
            If gbCntToken = 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1
               Close #lByte1
               PrintDOSError
            else
               PrintParameterCountError "1 "
            End If

         Case "FLUSH"                   ' flush file
            lByte2 = 0
            if gbCntToken = 1 then
               Flush
            elseif gbCntToken = 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1
               Flush #lByte1

            else
               PrintParameterCountError "0 or 1 "
            End If
            PrintDOSError

         case "BSAVE"                   ' save SRAM to file
            If gbCntToken = 4 then
                lsToken = GetNextTokenStr(12)       ' Filename
                lLong1 = GetNExtTokenLong(0 , &HFFFF)       ' Start
                lLong2 = GetNextTokenLong(1 , &HFFFF)       ' Length
                lWord1 = lLong1 : lWord2 = lLong2
                if gbPCInputError = cpNo then
                    BSave lsToken , lWord1 , lWord2
                    printDOSError
                end if
             else
               PrintParameterCountError "3 "
            End If

        case "BLOAD"                    ' load SRAM with file content
            If gbCntToken = 3 then
                lsToken = GetNextTokenStr(20)       ' Filename
                lLong1 = GetNExtTokenLong(0 , &HFFFF)       ' Start
                lWord1 = lLong1
                if gbPCInputError = cpNo then
                    BLoad lsToken , lWord1
                    PrintDOSError
                end if
             else
               PrintParameterCountError "2 "
            End If

        Case "FILEATTR"                 ' File open mode
            If gbCntToken = 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1
               lByte2 = FileAttr(lByte1)
               if lByte2 <> 0 then
                  print #1 , lByte2
               else
                  PrintDOSError
               end if
            else
               PrintParameterCountError "1 "
            End If

        Case "FREEFILE"                 ' File open mode
            If gbCntToken = 1 then
               lByte2 = FreeFile()
               if lByte2 <> 0 then
                  print #1 , lByte2
               else
                  PrintDOSError
               end if
            else
               PrintParameterCountError "no "
            End If

        Case "EOF"                      ' File open mode
            If gbCntToken = 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lByte1 = lLong1
               lByte2 = EOF(#lByte1)
               if gbDOSError = 0 then
                  print #1 , lByte2
               else
                  PrintDOSError
               end if
            else
               PrintParameterCountError "1 "
            End If


         Case "PUTL"
            If gbCntToken > 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lLong2 = GetNextTokenLong( -10000000 , 10000000)
               lByte1 = lLong1
               if gbCntToken > 3 then
                  lLong3 = GetNextTokenLong(1 , 10000000)
                  Put #lByte1 , lLong2 , lLong3
               else
                  Put #lByte1 , lLong2
               endif
               PrintDOSError
            else
               PrintParameterCountError "2 or 3 "
            End If

         Case "GETL"
            If gbCntToken > 1 then
               lLong1 = GETNextTokenLong(1 , 255)
               lByte1 = lLong1
               if gbCntToken > 2 then
                  lLong3 = GETNextTokenLong(1 , 10000000)
                  GET #lByte1 , lLong2 , lLong3
               else
                  GET #lByte1 , lLong2
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               else
                  print #1 , lLong2
               end if
            else
               PrintParameterCountError "1 or 2 "
            End If


         Case "PUTB"
            If gbCntToken > 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lLong2 = GetNextTokenLong(0 , 255)
               lByte1 = lLong1
               lByte3 = lLong2
               if gbCntToken > 3 then
                  lLong3 = GetNextTokenLong(1 , 10000000)
                  Put #lByte1 , lByte3 , lLong3
               else
                  Put #lByte1 , lByte3
               endif
               PrintDOSError
            else
               PrintParameterCountError "2 or 3 "
            End If

         Case "GETB"
            If gbCntToken > 1 then
               lLong1 = GETNextTokenLong(1 , 255)
               lByte1 = lLong1
               if gbCntToken > 2 then
                  lLong3 = GETNextTokenLong(1 , 10000000)
                  GET #lByte1 , lByte3 , lLong3
               else
                  GET #lByte1 , lByte3
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               else
                  print #1 , lByte3
               end if
            else
               PrintParameterCountError "1 or 2 "
            End If

         Case "PUTI"
            If gbCntToken > 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lLong2 = GetNextTokenLong( -32767 , 32767)
               lByte1 = lLong1
               lInt1 = lLong2
               if gbCntToken > 3 then
                  lLong3 = GetNextTokenLong(1 , 10000000)
                  Put #lByte1 , lInt1 , lLong3
               else
                  Put #lByte1 , lInt1
               endif
               PrintDOSError
            else
               PrintParameterCountError "2 or 3 "
            End If

         Case "PUTW"
            If gbCntToken > 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lLong2 = GetNextTokenLong(0 , 65635)
               lByte1 = lLong1
               lWord1 = lLong2
               if gbCntToken > 3 then
                  lLong3 = GetNextTokenLong(1 , 10000000)
                  Put #lByte1 , lWord1 , lLong3
               else
                  Put #lByte1 , lWord1
               endif
               PrintDOSError
            else
               PrintParameterCountError "2 or 3 "
            End If

         Case "GETI"
            If gbCntToken > 1 then
               lLong1 = GETNextTokenLong(1 , 255)
               lByte1 = lLong1
               if gbCntToken > 2 then
                  lLong3 = GETNextTokenLong(1 , 10000000)
                  GET #lByte1 , lInt1 , lLong3
               else
                  GET #lByte1 , lInt1
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               else
                  print #1 , lInt1
               end if
            else
               PrintParameterCountError "1 or 2 "
            End If

         Case "GETW"
            If gbCntToken > 1 then
               lLong1 = GETNextTokenLong(1 , 255)
               lByte1 = lLong1
               if gbCntToken > 2 then
                  lLong3 = GETNextTokenLong(1 , 10000000)
                  GET #lByte1 , lWord1 , lLong3
               else
                  GET #lByte1 , lWord1
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               else
                  print #1 , lWord1
               end if
            else
               PrintParameterCountError "1 or 2 "
            End If

         Case "PUTS"
            If gbCntToken > 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lstoken = GetNextTokenStr(20) : lsToken = trim(lsToken) : lSingle1 = val(lsToken)
               lByte1 = lLong1
               if gbCntToken > 3 then
                  lLong3 = GetNextTokenLong(1 , 10000000)
                  Put #lByte1 , lSingle1 , lLong3
               else
                  Put #lByte1 , lSingle1
               endif
               PrintDOSError
            else
               PrintParameterCountError "2 or 3 "
            End If

         Case "GETS"
            If gbCntToken > 1 then

               lLong1 = GETNextTokenLong(1 , 255)
               lByte1 = lLong1
               if gbCntToken > 2 then
                  lLong3 = GETNextTokenLong(1 , 10000000)
                  GET #lByte1 , lSingle1 , lLong3
               else
                  GET #lByte1 , lSingle1
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               else
                  print #1 , lSingle1
               end if
            else
               PrintParameterCountError "1 or 2 "
            End If

         Case "PUTT"
            If gbCntToken > 2 then
               lLong1 = GetNextTokenLong(1 , 255)
               lstoken = GetNextTokenStr(20) : lsToken = trim(lsToken)
               lByte1 = lLong1
               if gbCntToken > 3 then
                  lLong3 = GetNextTokenLong(1 , 100000000)
                  lLong4 = GetNextTokenLong(1 , 255)
                  Put #lByte1 , lsToken , lLong3 , lLong4
               else
                  Put #lByte1 , lsToken
               endif
               PrintDOSError
            else
               PrintParameterCountError "2 or 3 "
            End If

         Case "GETT"
            If gbCntToken > 1 then
               lsToken = ""
               lLong1 = GETNextTokenLong(1 , 255)
               lByte1 = lLong1
               if gbCntToken > 2 then
                  lLong3 = GetNextTokenLong(1 , 100000000)
                  lLong4 = GetNextTokenLong(1 , 255)
                  GET #lByte1 , lsToken , lLong3 , lLong4
               else
                  GET #lByte1 , lsToken
               endif
               if gbDOSError <> 0 then
                  PrintDOSError
               else
                  print #1 , lsToken
               end if
            else
               PrintParameterCountError "1 or 2 "
            End If

         Case "TIME"

            If gbCntToken = 1 Then
               print #1 , time$
            ElseIf gbCntToken = 2 Then
               Time$ = GetNextTokenStr(8)
            Else
               PrintParameterCountError "0 or 1"
            End If

         Case "DATE"

            If gbCntToken = 1 Then
               print #1 , DATE$
            ElseIf gbCntToken = 2 Then
               DATE$ = GetNextTokenStr(8)
            Else
               PrintParameterCountError "0 or 1"
            End If


         Case "DISKFREE"

            If gbCntToken = 1 Then
               lLong1 = DiskFree()
               print #1 , lLong1
            End If

         Case "DISKSIZE"
            lLong1 = DiskSize()
            print lLong1

         Case "ERROR"
            print #1 , "Last Error: " ; gbDOSError


         Case Else

            Print #1 , "Command '" ; gsPCInput ; "' not recognized"

      End Select

      if Transferbuffer_write > 511 then
         Transferbuffer_write = 0
      End if

   End If
End Sub



Sub ExtractToken
' Counts the Token in the Input-String: gsPCInput
' following variable and arrays are filled
' cntToken: Cont of Token
' PosStrParts: positions, where the tokens start
' LenStrParts: Count of bytes of each token

   Local Lstrlen As Byte
   Local LparseEnd As Byte
   Local Lpos1 As Byte , Lpos2 As Byte
   ' Init arrays with 0
   For Gbcnttoken = 1 To cpToken_max
      Gbposstrparts(gbcnttoken) = 0 : Gblenstrparts(gbcnttoken) = 0
   Next

   Gbcnttoken = 0
   gsPCInput = Trim(gsPCInput)
   Lstrlen = Len(gsPCInput)             ' how long is string
   If Lstrlen = 0 Then                  'no Input ?
      Exit Sub
   End If
   LparseEnd = 0
   Lpos1 = 0
   For Gbcnttoken = 1 To cpToken_max
      Incr Lpos1
      Lpos2 = Instr(lpos1 , gsPCInput , cpStrSep)       ' find next blank
      If Lpos2 = 0 Then                 ' no more found?
         Lpos2 = Lstrlen : Incr Lpos2 : LparseEnd = 1
      End If
      Gblenstrparts(gbcnttoken) = Lpos2 - Lpos1       ' Lenght of token
      Gbposstrparts(gbcnttoken) = Lpos1
      If LparseEnd = 1 Then
         Exit For
      End If
      Lpos1 = Lpos2
   Next
End Sub


Function GetNextTokenStr(ByVal pbLen_Max as Byte ) as String
   ' Returns next String-token from Input
   ' Parameter: pbLen_Max: Limit for string-length
   Local lbPos as Byte
   Local lbLen as Byte
   incr gbToken_actual                  ' switch to new/next token
   lbPos = gbPosStrParts(gbToken_actual)       ' at which position in string
   lbLen = gbLenStrParts(gbToken_actual)       ' how long
   If lbLen > pbLen_Max Then lbLen = pbLen_Max       ' to long?
   GetNextTokenStr = mid(gsPCInput , lbPos , lbLen)       ' return string
End Function


Function GetNextTokenLong(byVAl plMin as Long , byVal plMax as Long ) as Long
   ' returns a Long-Value from next Token and check for inside lower and upper limit
   ' plMin: minimum limit for return-value
   ' plMax: maximum limit for return-value
   Local lbPos as Byte
   Local lbLen as Byte
   Local lsToken as String * 12
   incr gbToken_actual                  ' switch to new/next token
   lbPos = gbPosStrParts(gbToken_actual)       ' at which position in string
   lbLen = gbLenStrParts(gbToken_actual)       ' how long
   If lbLen > 12 Then lbLen = 12        ' to long?
   if mid(gsPCInput , lbPos , 1) = "$" then       ' Is input a HEX vlue?
      incr lbPos : decr lbLen           ' adjust pointer to jump over $
      lsToken = mid(gsPCInput , lbPos , lbLen)
      GetNextTokenLong = hexval(lstoken)
   Else
       lsToken = mid(gsPCInput , lbPos , lbLen)
       GetNextTokenLong = val(lsToken)
   End if
   Select Case GetNextTokenLong         ' check for limits
      Case plMin to plMax               ' within limits, noting to do
      Case Else
         gbPCInputError = cpYes         ' Set Error Sign
         Print #1 , Spc(lbPos) ; "^ " ; "Parameter Error ";
         PrintParameterErrorL plMin , plMax       ' with wanted limits
   End Select
End Function


Sub PrintParameterCountError(byVAl psParm_Anzahl as String * 10)
   ' User message for wrong count of parameter
   Print #1 , "? " ; psParm_Anzahl ; " " ; "Parameter " ; "expected "
End Sub

Sub PrintParameterErrorl(plParamLow as Long , plParamHigh as Long)
   ' Print Limits at wrong Input - value
   Print #1 , " [ " ; plParamLow ; " ] - [ " ; plParamHigh ; " ] " ; "expected "
End Sub


Sub PrintPrompt()
    Print #1 ,
    Print #1 , hex(TransferBuffer_Write) ; ">" ;
End Sub


Function GetLongFromBuffer(pbSRAMArray as Byte , byVal pbPos as Word) as Long
   ' Extract a Long-Value from a Byte-Array
   ' pbSRAMArray: Byte-array, from which the Long-value should be extracted
   ' pbPos: Position, at which the Long-Value starts (0-based)
   loadadr pbSRAMArray , Z
   loadadr pbPos , X
   ld r24, x+
   ld r25, x+
   add zl, r24
   adc zh, r25
   loadadr GetLongFromBuffer , X
   ldi r24, 4
   !Call _mem2_copy
End Function


Function GetWordFromBuffer(pbSRAMArray as Byte , byVal pbPos as Word) as Word
   ' Extract a Word-value from a Byte-Array
   ' pbSRAMArray: Byte-array, from which the Word-value should be extracted
   ' pbPos: Position, at which the Word-Value starts (0-based)
   loadadr pbSRAMArray , Z
   loadadr pbPos , X
   ld r24, x+
   ld r25, x+
   add zl, r24
   adc zh, r25
   loadadr GetWordFromBuffer , X
   ldi r24, 2
   !Call _mem2_copy
End Function


Sub SRAMDump(pwSRAMPointer as Word , byVal pwLength as Word , plBase as Long)
    ' Dump a Part of SRAM to Print-Output #1
    ' pwSRAMPointer: (Word) Variable which holds the address of SRAM to dump
    ' pwLength: (Word) Count of Bytes to be dumped (1-based)
    Local lsDump as String * 16
    Local lByte1 as Byte , lByte2 as Byte
    Local lWord1 as Word , lWord2 as Word
    Local lLong1 as Long

    if pwLength > 0 then
      Decr pwLength
      for lword1 = 0 to pwLength
         lWord2 = lWord1 mod 16
         if lWord2 = 0 then
            if lWord1 > 0 then
               Print #1 , "  " ; lsDump
            end if
            lLong1 = plBase + lWord1
            Print #1 , hex(llong1) ; "  " ;
            lsDump = "                "
            lByte2 = 1
         end if
         lByte1 = Inp(pwSRAMPointer)
         incr pwSRAMPointer
         Print #1 , hex(lByte1) ; " " ;
         if lByte1 > 31 then
            mid(lsdump , lByte2 , 1) = lByte1
         else
             mid(lsdump , lByte2 , 1) = "."
         end if
         incr lByte2
      next
      Print #1 , "  " ; lsDump
    End if
    plBase = plBase + pwLength
End Sub

' -----------------------------------------------------------------------------
' copy Memory from (Z) nach (X)
' counts of bytes in r24
_mem2_copy:
   ld r25, z+
   st x+, r25
   dec r24
   brne _mem2_copy
   ret


Sub WriteFileDivVariables(pFN as Byte , pByte as Byte , pInt as Integer , pWord as Word , pLong as Long , pSingle as Single , pString as String. pDummy as Byte)
$EXTERNAL _GetFilehandle , _FileWriteComma , _FileWriteCRLF , _FileWriteDecByte , _FileWriteDecInt , _FileWriteDecWord , _FileWriteDecLong , _FileWriteDecSingle
$EXTERNAL _FileWriteStrConst , _FileWriteStringQuotationMark

    ' first get the file handle
    loadadr pFN , X
    ld r24, X
    !Call _GetFileHandle
    brcs _WriteFileDivVariables1

    ' now little bit tricky to load filehandle to Y+0/1 and keep link to Parameter of variable
    adiw yl, 2                          ' store pointer to filehandle into last dummy variable pointer
    st -Y, zh                           ' pointer to file handle
    st -Y, zl
    Ldi ZL,Low(_STRING150 * 2)
    Ldi ZH,High(_STRING150 * 2)
    !call _SET_RAMPZ
    !Call _FileWriteStrConst
    !Call _FileWriteComma

    ' Now a byte
    loadadr pByte , Z
    !Call _FileWriteDecByte

    ' Now a comma
    !Call _FileWriteComma

    ' Now an integer
    loadadr pInt , Z
    !Call _FileWriteDecInt

    ' Now a comma
    !Call _FileWriteComma

    ' now a Word
    loadadr pWord , Z
    !Call _FileWriteDecWord

    ' now a Comma
    !Call _FileWriteComma

    ' Now a long
    loadadr pLong , Z
    !Call _FileWriteDecLong

    ' Now a comma
    !Call _FileWriteComma

    ' Now a single
    loadadr pSingle , Z
    !Call _FileWriteDecSingle

    ' now a comma
    !Call _FileWriteComma

    ' Now a normal string
    loadadr pString , X
    !Call _FileWriteStringQuotationMark

    ' Now finish line with CR-LF
    !Call _FileWriteCRLF

    ' now should Y-Pointer be adjusted, but here not because of above mentioned trick
    'adiw yl, 2
_WriteFileDivVariables1:
end Sub


Sub ReadFileDivVariables(pFN as Byte , pByte as Byte , pInt as Integer , pWord as Word , pLong as Long , pSingle as Single , pString1 as String , pString2 as String , pDummy as Byte)
$EXTERNAL _GetFilehandle , _FileReadDec2Num , _FileReadDecSingle
$EXTERNAL _FileReadString

    ' first get the file handle
    loadadr pFN , X
    ld r24, X
    !Call _GetFileHandle
    brcs _ReadFileDivVariables1

    ' now little bit tricky to load filehandle to Y+0/1 and keep link to Parameter of variable
    adiw yl, 2                          ' store pointer to filehandle into last dummy variable pointer
    st -Y, zh                           ' pointer to file handle
    st -Y, zl

    loadadr pString2 , X
    ldi r20, 20
    !call _FileReadString


    !Call _FileReadDec2Num
    ' Now a byte
    loadadr pByte , X
    st X, r16

    ' Now an integer
    !Call _FileReadDec2Num
    loadadr pInt , X
    st X+, r16
    st X, r17


    ' now a Word
    !Call _FileReadDec2Num
    loadadr pWord , X
    st X+, r16
    st X+, r17

    ' Now a long

    !Call _FileReadDec2Num
    loadadr pLong , X
    st X+, r16
    st X+, r17
    st X+, r18
    st X+, r19

    ' Now a single
    !Call _FileReadDecSingle
    loadadr pSingle , X
    st X+, r13
    st X+, r14
    st X+, r15
    st X+, r16

    ' Now a string
    loadadr pString1 , X
    ldi r20, 20
    !call _FileReadString



    ' now should Y-Pointer be adjusted, but here not because of above mentioned trick
    'adiw yl, 2
_ReadFileDivVariables1:
end Sub


