*** empty log message ***
authorhachti <hachti>
Sat, 18 Nov 2006 10:01:34 +0000 (10:01 +0000)
committerhachti <hachti>
Sat, 18 Nov 2006 10:01:34 +0000 (10:01 +0000)
12 files changed:
pc-tools/ldc2/src/Makefile [new file with mode: 0644]
pc-tools/ldc2/src/data_block.cpp [new file with mode: 0644]
pc-tools/ldc2/src/data_block.hh [new file with mode: 0644]
pc-tools/ldc2/src/data_block_0.cpp [new file with mode: 0644]
pc-tools/ldc2/src/data_block_0.hh [new file with mode: 0644]
pc-tools/ldc2/src/hw_constants.hh [new file with mode: 0644]
pc-tools/ldc2/src/silent_code.cpp [new file with mode: 0644]
pc-tools/ldc2/src/silent_code.hh [new file with mode: 0644]
pc-tools/ldc2/src/tape_block.cpp [new file with mode: 0644]
pc-tools/ldc2/src/tape_block.hh [new file with mode: 0644]
pc-tools/ldc2/src/tape_block_vector.hh [new file with mode: 0644]
pc-tools/ldc2/src/test.cpp [new file with mode: 0644]

diff --git a/pc-tools/ldc2/src/Makefile b/pc-tools/ldc2/src/Makefile
new file mode 100644 (file)
index 0000000..a981863
--- /dev/null
@@ -0,0 +1,10 @@
+default: test
+
+*.o:*.hh
+
+test: test.o tape_block.o silent_code.o data_block.cpp data_block_0.o 
+       g++ -o$@ $^
+       
+
+clean: 
+       rm -rf test *.o *~
\ No newline at end of file
diff --git a/pc-tools/ldc2/src/data_block.cpp b/pc-tools/ldc2/src/data_block.cpp
new file mode 100644 (file)
index 0000000..15702b5
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "data_block.hh"
+#include "data_block_0.hh"
+
+
+data_block::data_block(tape_block& idol)
+  :tape_block(idol)
+{
+}
+
+data_block::~data_block(){
+}
+
+int data_block::get_type(){
+  if ((init_state==TBS_OK)&&word_data)
+    return (word_data[0]&0xf000)>>12;
+  else
+ return block_type;
+}
+
+int data_block::get_subtype(){
+  if (get_type()==0)
+    return (new data_block_0(*this))->get_subtype();
+  else return 0;
+}
diff --git a/pc-tools/ldc2/src/data_block.hh b/pc-tools/ldc2/src/data_block.hh
new file mode 100644 (file)
index 0000000..8b44754
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef DATA_BLOCK_HH
+#define DATA_BLOCK_HH
+
+#include "tape_block.hh"
+
+class data_block
+  : public tape_block
+{
+  //private: 
+  //data_block(); // Private constructor!
+public:
+   data_block(tape_block&);
+  ~data_block();
+
+virtual int get_type();
+virtual int get_subtype();
+
+};
+
+
+#endif
diff --git a/pc-tools/ldc2/src/data_block_0.cpp b/pc-tools/ldc2/src/data_block_0.cpp
new file mode 100644 (file)
index 0000000..96c4dc2
--- /dev/null
@@ -0,0 +1,19 @@
+#include "data_block_0.hh"
+#include "data_block.hh"
+
+data_block_0::data_block_0(data_block & org)
+  :data_block(org)
+{
+}
+
+data_block_0::~data_block_0()
+{
+}
+
+int data_block_0::get_subtype(){
+  if ((init_state==TBS_OK)&&word_size&&(data_block::get_type()==0)){
+    return (word_data[0]&0x0fc0)>>6;
+  }
+  else return data_block::get_subtype();
+}
+
diff --git a/pc-tools/ldc2/src/data_block_0.hh b/pc-tools/ldc2/src/data_block_0.hh
new file mode 100644 (file)
index 0000000..c34ee08
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef DATA_BLOCK_0_H
+#define DATA_BLOCK_0_H
+
+#include "data_block.hh"
+
+class data_block_0
+  : public data_block
+{
+ public:
+  data_block_0(data_block&);
+  virtual ~data_block_0();
+
+  int get_subtype();
+
+};
+
+#endif
diff --git a/pc-tools/ldc2/src/hw_constants.hh b/pc-tools/ldc2/src/hw_constants.hh
new file mode 100644 (file)
index 0000000..2ec1c87
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef HW_CONSTANTS_H
+#define HW_CONSTANTS_H
+
+/* Block start delimiter */
+#define BLOCK_START_DELIMITER 0x81
+
+#define MINIMUM_DATA_BLOCK_WORDSIZE 1
+
+/* Block end delimiters */
+#define EOB_LENGTH 1
+#define BLOCK_END_DELIMITER_1 0223 
+#define BLOCK_END_DELIMITER_2 0223
+
+/* End of Tape sequence
+ * If EOT_LENGTH is set to 2, EOT_1 becomes insignificant and so on
+ */
+#define EOT_LENGTH 3
+#define EOT_SEQ_1  0x83
+#define EOT_SEQ_2  0x93
+#define EOT_SEQ_3  0xff
+
+
+#endif
diff --git a/pc-tools/ldc2/src/silent_code.cpp b/pc-tools/ldc2/src/silent_code.cpp
new file mode 100644 (file)
index 0000000..0c00a32
--- /dev/null
@@ -0,0 +1,57 @@
+#include "silent_code.hh"
+
+//#include <stdio.h>
+
+unsigned char silent_demangle (unsigned char in)
+{
+    if (in & 64)
+       switch (in) {
+       case 0174:
+           return 05;
+           break;
+       case 0374:
+           return 045;
+           break;
+       case 0175:
+           return 012;
+           break;
+       case 0375:
+           return 052;
+           break;
+       case 0176:
+           return 021;
+           break;
+       case 0376:
+           return 061;
+           break;
+       case 0177:
+           return 023;
+           break;
+       case 0377:
+           return 063;
+           break;
+       default: // Illegal branch
+           return 0;
+           break;
+    } else {
+       if (in & 128)
+           in |= 32;
+       return in;
+    }
+    return 0; // Never executed
+}
+
+unsigned short combine466 (unsigned char *raw) {
+    unsigned short r1, r2, r3;
+    unsigned short result=0;
+    r1 = silent_demangle ((raw)[0]) & 017;
+    r2 = silent_demangle ((raw)[1]) & 077;
+    r3 = silent_demangle ((raw)[2]) & 077;
+
+    result=r3;
+    result|=r2<<6;
+    result|=r1<<12;
+ //    printf ("data: %02x %02x %02x   %04x \n",r1,r2,r3,result);
+    return result;
+}
+
diff --git a/pc-tools/ldc2/src/silent_code.hh b/pc-tools/ldc2/src/silent_code.hh
new file mode 100644 (file)
index 0000000..4212655
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef SILENT_CODE_H
+#define SILENT_CODE_H
+
+/*!
+ *\brief Demangle silent code frames to 6 bit frames
+ */
+extern unsigned char silent_demangle(unsigned char in);
+
+/*!
+ * Combine three mangled paper tape frames into 
+ * one 16 bit machine word
+ */
+extern unsigned short combine466(unsigned char* in);
+
+#endif
diff --git a/pc-tools/ldc2/src/tape_block.cpp b/pc-tools/ldc2/src/tape_block.cpp
new file mode 100644 (file)
index 0000000..81efc8c
--- /dev/null
@@ -0,0 +1,206 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "tape_block.hh"
+#include "data_block.hh"
+
+#include "silent_code.hh"
+#include "hw_constants.hh"
+
+tape_block::tape_block()
+{
+}
+
+tape_block::tape_block(tape_block & org){
+  block_type=org.block_type;
+  init_state=org.init_state;
+  data_read=org.data_read; 
+  raw_data=0;  
+  raw_size=org.raw_size;  
+  word_data=0;
+  word_size=org.word_size;              
+   if (raw_size){
+     raw_data=(unsigned char *)malloc(raw_size);
+     memcpy(raw_data,org.raw_data,raw_size);
+   }
+   if (word_size){
+     word_data=(unsigned short *)malloc(word_size*sizeof(unsigned short));
+     memcpy(word_data,org.word_data,word_size*sizeof(unsigned short));
+   }
+}
+
+tape_block::tape_block (int  fd,
+                       void(*input_start)(void *),
+                       void (*input_stop)(void *),
+                       void * start_stop_arg
+                       )
+{
+  unsigned char buffer;
+  int retval;
+  int eot_needed=EOT_LENGTH;
+  int eob_needed=EOB_LENGTH;
+  int block_complete=0;
+
+  block_type= TBT_DISCARD;
+  init_state= TBS_DEFAULT;
+  data_read = 0;
+  raw_data  = 0;
+  raw_size  = 0;
+  word_data = 0;
+  word_size = 0;
+  
+  if (input_start) input_start (start_stop_arg);
+
+  /* Look for block start in input stream */
+  do { 
+    retval=read(fd, &buffer, 1);
+    if (retval == 0){             // End of file
+      block_type=TBT_DISCARD;
+      init_state=TBS_EOF_LEGAL;
+      return;
+    }
+    if (retval == -1){            // Error reading from fd
+      block_type=TBT_DISCARD;
+      init_state=TBS_IOERR;
+      return;
+    }
+    data_read++;
+    
+    /* Look for end ot tape sequence */
+    switch(eot_needed){
+    case 3:
+      if (buffer==EOT_SEQ_1) eot_needed--;
+      else eot_needed=EOT_LENGTH;
+      break;
+    case 2:
+      if (buffer==EOT_SEQ_2) eot_needed--;
+      else eot_needed=EOT_LENGTH;
+      break;
+    case 1:
+      if (buffer==EOT_SEQ_3){
+       raw_data=(unsigned char*)malloc(3);
+       raw_size=3;
+       raw_data[0]=EOT_SEQ_1;
+       raw_data[1]=EOT_SEQ_2;
+       raw_data[2]=EOT_SEQ_3;
+       block_type =TBT_EOT;
+       init_state =TBS_OK;
+       return;
+      }
+      else eot_needed=EOT_LENGTH;
+      break;
+    }
+  } while (buffer != (unsigned char) BLOCK_START_DELIMITER);
+  
+
+  /* Now input the block data */
+  block_complete = 0;
+  do {
+    retval = read (fd, &buffer, 1);
+
+    if (retval == 0){             // End of file
+      block_type=TBT_DISCARD;
+      init_state=TBS_EOF_ILLEGAL;
+      return;
+    }
+    if (retval == -1){            // Error reading from fd
+      block_type=TBT_DISCARD;
+      init_state=TBS_IOERR;
+      return;
+    }
+    data_read++;                  // We have consumed a byte
+    
+    /* sort in the new byte */
+    raw_size++;
+    raw_data=(unsigned char*)realloc(raw_data,raw_size);
+    raw_data[raw_size-1]=buffer;
+
+    /* Look for end ot block sequence */
+    switch(eob_needed){
+    case 2:
+      if (buffer==BLOCK_END_DELIMITER_1) eob_needed--;
+      else eob_needed=EOB_LENGTH;
+      break;
+    case 1:
+      if (buffer==BLOCK_END_DELIMITER_2){
+       raw_size-=EOB_LENGTH; // Don't want the delimiter(s) in the data!
+       raw_data=(unsigned char*)realloc(raw_data,raw_size);
+       block_complete=1;
+      }
+      else eob_needed=EOB_LENGTH;
+      break;
+    }
+  }while (!block_complete);
+  if (input_stop) input_stop (start_stop_arg);
+  
+  /* Now we have the data in. */
+  
+  if (init_words()!=0){
+    init_state=TBS_CHECKSUM;
+    return;
+  }
+  
+  if (test_checksum()!=0){
+    init_state=TBS_CHECKSUM;
+    return;
+  }
+  
+  block_type=TBT_DATA;    
+  init_state=TBS_OK;
+}
+
+tape_block::~tape_block(){
+  free(raw_data);
+  free(word_data);
+}
+
+tape_block::tb_state_t tape_block::get_state(){
+  return init_state;
+}
+
+int tape_block::get_raw_size(){
+  return raw_size;
+}
+
+unsigned char * tape_block::get_raw_data(){
+  return raw_data;
+}
+
+int tape_block::get_type(){
+  int result=block_type;
+  if (block_type==TBT_DATA){
+    data_block * mb=new data_block(*this);
+    result=mb->get_type();
+  }
+  return result;
+}
+
+int tape_block::get_subtype(){
+  int result=0;
+  if (block_type==TBT_DATA){
+    data_block * mb=new data_block(*this);
+    result=mb->get_subtype();
+  }
+  return result;
+}
+
+int tape_block::init_words(){
+  word_size=raw_size/3;
+  if (word_size<MINIMUM_DATA_BLOCK_WORDSIZE) return 1; // Block too short!
+  word_data=(unsigned short *)malloc(raw_size*sizeof(unsigned short));
+  for (int pos=0; pos<word_size; pos++)
+    word_data[pos]=combine466(raw_data+3*pos);
+  return 0;
+}
+
+int tape_block::test_checksum(){
+  unsigned short sum=0;
+  for (int pos=0; pos<word_size-1;pos++)
+    //    sum^=word_data[pos];
+    sum+=word_data[pos];
+    
+  //  printf("cs:%04x\n",word_data[word_size-1]);
+  if (sum==word_data[word_size-1]) return 0;
+  else return 1;
+}
diff --git a/pc-tools/ldc2/src/tape_block.hh b/pc-tools/ldc2/src/tape_block.hh
new file mode 100644 (file)
index 0000000..8c1231f
--- /dev/null
@@ -0,0 +1,150 @@
+#ifndef TAPE_BLOCK_H
+#define TAPE_BLOCK_H
+
+
+/*!
+ *\brief Tape data block base class
+ *
+ * This class represents a Honeywell paper tape block.
+ * That may be some kind of data block or a end of tape mark.
+ */
+class tape_block{
+
+public: // types
+
+  /*!
+   * The block's initialisation state
+   */
+  typedef enum {
+    TBS_OK,          //!< Block successfully initialised
+    TBS_EOF_LEGAL,   //!< Legal EOF while initialising
+    TBS_EOF_ILLEGAL, //!< Illegal EOF while initialising
+    TBS_CHECKSUM,    //!< Checksum error 
+    TBS_IOERR,       //!< I/O-Error while reading
+    TBS_DEFAULT      //!< Block not initialised.
+  } tb_state_t;
+
+  /*!
+   * Tape block types
+   */
+  typedef enum {
+    TBT_DATA=0x10,   //!< Data block
+    TBT_EOT,         //!< End of tape block
+    TBT_DISCARD      //!< Invalid block, check block_type
+  } tb_type_t;
+
+protected: // methods
+  /*!
+   *\brief Protected default constructor
+   */
+  tape_block();
+
+public: // methods
+
+  tape_block(tape_block &);
+
+  /*!
+   *\brief Read-in constructor for file descriptor
+   *
+   * This constructor is used to read in the block's data via a file 
+   * descriptor.\\
+   * This is done in the following way:\\
+   * - input_start() is called.\\
+   * - Data is read from fd. Stops on end of file or end of block 
+   * or IO error. On EOF or IO error input_stop() is NOT called.\\
+   * - If there was no IO error the block's checksum is calculated 
+   * and checked.\
+   * - The block's type field is initialised.\\
+   * - input_stop() is called.\\
+   *\param fd_p A pointer to the device descriptor where 
+   * the data is taken from \\
+   *\param input_stop A pointer to a function called at the end of input\\
+   *\param input_start A pointer to a function called at the beginning 
+   * of input\\
+   *\param start_stop_arg A pointer passed to input_start and input_stop(). 
+  */
+  tape_block (int  fd_p,
+             void(*input_start)(void *)=0,
+             void (*input_stop)(void *)=0,
+             void * start_stop_arg=0
+             );
+  /*!
+   * The virtual destructor
+   */
+  virtual ~tape_block();
+
+  /*!
+   *\brief Query the block's state.
+   *
+   * If the state is not TBS_OK, the block must be discarded.
+   *\return The block's initialisation state
+   */
+  tb_state_t get_state();
+
+  /*!
+   *\brief Get size of the internal raw data buffer
+   *\return The size of the internal raw data buffer
+   */
+  int get_raw_size();
+
+  /*!
+   *\brief Access internal raw data buffer
+   *
+   * The raw data buffer contains all block data except the \\
+   * block start delimiter and block end delimiter.
+   *\return Pointer to internal raw data buffer of the block
+   */
+  unsigned char * get_raw_data();
+
+  /*
+   *\brief Determine the block's type
+   *
+   * This routine returns the block's type.\\
+   *\retval TBT_DATA if it's a data block
+   *\retval TBT_EOT if it's an end of tape mark
+   *\retval TBR_DISCARD if the block is unusable
+   *
+   *\note This function is virtual. That means that if the tape block in
+   * question is of the subtype data_block which overwrites this method,
+   * it will return the block type contained in the upper 4 bits of the
+   * first data word! Try to avoid testing for TBT_DATA.
+   */
+  virtual int get_type();
+  
+  /*!
+   *\brief Determine the block's subtype
+   *
+   * Some data block types have a subtype. This can be determined this way.
+   *\return Block subtype if the block object is of a suitable subclass
+   */
+  virtual int get_subtype();
+
+private:   // methods
+  /*!
+   *\brief Initialize word representation of data
+   *\retval 0 on success
+   *\retval 1 on error
+   */
+  int init_words(void);
+
+  /*!
+   *\brief Calculate and check checksum
+   *\retval 0 on success
+   *\retval 1 on error
+   */
+  int test_checksum(); 
+
+protected: // members
+  int block_type;             //!< type of this block
+  tb_state_t init_state;      //!< Initialisation state
+  int data_read;              //!< Total data consumption during intialisation
+  unsigned char * raw_data;   //!< Raw block data in bytes
+  int raw_size;               //!< Size of the raw data
+  unsigned short * word_data; //!< Data organized in machine words
+  int word_size;              //!< Size of the blocks in machine words
+
+}; // tape_block
+
+
+#endif
diff --git a/pc-tools/ldc2/src/tape_block_vector.hh b/pc-tools/ldc2/src/tape_block_vector.hh
new file mode 100644 (file)
index 0000000..cf50cb6
--- /dev/null
@@ -0,0 +1,14 @@
+#include <vector>
+
+#include "tape_block.hh"
+#include "data_block.hh"
+#include "tape_block_0.hh"
+
+class tape_block_vector
+  : protected vector<tape_block>
+{
+public: 
+  tape_block_vector();
+  tape_block_vector(tape_block_vector&);
+  
+};
diff --git a/pc-tools/ldc2/src/test.cpp b/pc-tools/ldc2/src/test.cpp
new file mode 100644 (file)
index 0000000..b6365fc
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "tape_block.hh"
+
+void tape_start(void* m){
+  printf("tape_start\n");
+}
+
+void tape_stop(void* m){
+  printf("tape_stop\n");
+}
+
+int main(){
+  tape_block * myblock=0;
+  do{
+    if (myblock) delete myblock;
+    myblock=new tape_block(0);
+        printf ("Block type:%2o-%o\n",myblock->get_type(),myblock->get_subtype());
+  } while (myblock->get_state()==tape_block::TBS_OK);
+  printf("---");
+  printf("State:%i\n",myblock->get_state());
+  printf("raw size:%i\n",myblock->get_raw_size());
+    return 0;
+}