Changeset 53c4be3 in thomson


Ignore:
Timestamp:
Feb 5, 2012, 3:25:32 PM (12 years ago)
Author:
Adrien Destugues <pulkomandy@…>
Branches:
main
Children:
1b74fa2
Parents:
c2a9854
Message:
  • Support for ZX spectrup TAP files.

git-svn-id: svn://localhost/thomson@17 85ae3b6b-dc8f-4344-a89d-598714f2e4e5

Location:
elec/CrO2/software
Files:
4 added
8 edited

Legend:

Unmodified
Added
Removed
  • elec/CrO2/software/Makefile

    rc2a9854 r53c4be3  
    2323all: $(PROGRAM)
    2424
    25 $(PROGRAM): $(PROJECT).o device.o gui.o k5.o
     25$(PROGRAM): $(PROJECT).o device.o gui.o k5.o Tape.o zxtape.o
    2626        $(CC) -o $(PROGRAM) $^ $(LIBS)
    2727
  • elec/CrO2/software/cro2.cpp

    rc2a9854 r53c4be3  
    3636
    3737                        // load file
    38                         K5 file(argv[2]);
     38                        Tape* file = Tape::load(argv[2]);
    3939
    40                         dev.write(file);
     40                        dev.write(*file);
     41
     42                        delete file;
    4143                }else{
    4244                        // TODO print usage
  • elec/CrO2/software/device.cpp

    rc2a9854 r53c4be3  
    99#include "device.h"
    1010#include "k5.h"
     11
     12#include <typeinfo>
    1113
    1214bool Device::initOnce = false;
     
    134136
    135137
    136 int Device::write(uint8_t* buffer, size_t size, int blktype)
     138int Device::write(const uint8_t* buffer, size_t size, int blktype)
    137139{
    138140        int rqtype = (size == 0) ? USB_ENDPOINT_IN:USB_ENDPOINT_OUT;
     
    143145
    144146
    145 void Device::write(K5& file)
     147void Device::write(const Tape& file) throw (const char*)
    146148{
    147149        for (int k = 0; k < file.getBlockCount(); k++)
     
    151153                        Sleep(1000);
    152154
    153                 K5::Block block = file.getBlock(k);
    154 
    155                 int nBytes = write(block.data, block.length - 1, block.type);
    156                         // TODO error handling
     155                const Tape::Block& block = file.getBlock(k);
     156                try {
     157                        const K5::Block& moblock = dynamic_cast<const K5::Block&>(block);
     158                        write(moblock.data, moblock.length - 1, moblock.type);
     159                                // TODO error handling on write
     160                } catch (std::bad_cast x) {
     161                        throw "Only MO5 files supported so far. Sorry!";
     162                };
    157163
    158164                // TODO wait for correct time (read status from usb OR compute from size+type)
  • elec/CrO2/software/device.h

    rc2a9854 r53c4be3  
    1010#include <lusb0_usb.h>
    1111
    12 class K5;
     12class Tape;
    1313
    1414class Device
     
    2020
    2121                int read(uint8_t* buffer, size_t max); // Fill the buffer with data from device
    22                 int write(uint8_t* buffer, size_t size, int blktype);
    23                 void write(K5& file);
     22                int write(const uint8_t* buffer, size_t size, int blktype);
     23                void write(const Tape& file) throw (const char*);
    2424                uint8_t getStatus();
    2525
  • elec/CrO2/software/gui.cpp

    rc2a9854 r53c4be3  
    1313#include <string.h>
    1414#include <sstream>
    15 #include <iostream>
     15#include <ios>
    1616
    1717#include <iupcontrols.h>
     
    9494        Callback<Gui, int, int, int>::create(blocklist, "SELECTION_CB", this, &Gui::selectBlock);
    9595
    96         Ihandle* hexEd = IupMatrix(NULL);
     96        hexEd = IupMatrix(NULL);
    9797
    9898        // Setup title cells
    99         IupSetAttribute(hexEd, "NUMLIN", "16");
     99        IupSetAttribute(hexEd, "FONT", "Courier, 10");
     100        IupSetAttribute(hexEd, "FONT*:17", "Courier, 10");
    100101        IupSetAttribute(hexEd, "NUMCOL", "17");
    101         IupSetAttribute(hexEd, "WIDTHDEF", "12");
    102         IupSetAttribute(hexEd, "WIDTH17", "48");
    103         IupSetAttribute(hexEd, "USETITLESIZE", "YES");
    104         IupSetAttribute(hexEd, "FONT", "Courier, Bold 12");
     102        IupSetAttribute(hexEd, "WIDTHDEF", "10");
     103        IupSetAttribute(hexEd, "WIDTH17", "105");
     104        IupSetAttribute(hexEd, "WIDTH0", "12");
     105        IupSetAttribute(hexEd, "HEIGHT0", "8");
     106        IupSetAttribute(hexEd, "SIZE", "400x230");
    105107        IupSetAttribute(hexEd, "EXPAND", "YES");
     108        IupSetAttribute(hexEd, "ALIGNMENT", "ALEFT");
    106109        Callback<Gui, const char*, int, int>::create(hexEd, "VALUE_CB", this, &Gui::matVal);
    107110       
     
    173176        {
    174177                // Load file
    175                 file = new K5(name);
     178                try {
     179                        file = Tape::load(name);
     180                } catch (const char* error) {
     181                        puts(error);
     182                        return IUP_DEFAULT;
     183                }
    176184
    177185                // Fill in EXPLORE tab
     
    179187                int lastfile = -1;
    180188
     189                IupSetAttribute(blocklist, "DELNODE", "ALL");
     190
    181191                for (int i = 0; i < count; ++i)
    182192                {
    183                         const K5::Block& blk = file->getBlock(i);
    184                         switch(blk.type)
     193                        const Tape::Block& blk = file->getBlock(i);
     194                        if (blk.isFile())
    185195                        {
    186                                 case 0:
    187                                         //start block
    188                                         char name[12];
    189                                         memcpy(name, blk.data, 11);
    190                                         name[11] = 0;
    191                                        
    192                                         IupSetAttributeId(blocklist, "INSERTBRANCH", lastfile, name);
    193                                         lastfile = i;
    194                                         break;
    195                                 case 0xFF:
    196                                         // end block
    197                                         IupSetAttributeId(blocklist, "ADDLEAF", i-1, "EOF");
     196                                IupSetAttributeId(blocklist, "INSERTBRANCH", lastfile, blk.getName().c_str());
     197                                lastfile = i;
     198                        } else {
     199                                IupSetAttributeId(blocklist, "ADDLEAF", i-1, blk.getName().c_str());
     200                                if (blk.isControl())
    198201                                        IupSetAttributeId(blocklist, "IMAGE", i, "IMGLEAF");
    199                                         break;
    200                                 default:
    201                                         // regular block
    202                                         IupSetAttributeId(blocklist, "ADDLEAF", i-1, "DATA");
    203                                         break;
    204202                        }
    205203                }
     
    217215        if (what)
    218216        {
    219                 IupSetAttribute(hexEd, "REDRAW", "ALL");
     217                selblock = id;
     218                std::ostringstream att;
     219                att << (file->getBlock(id).length / 16);
     220                IupSetAttribute(hexEd, "NUMLIN", att.str().c_str());
     221
     222                IupSetAttribute(hexEd, IUP_REDRAW, "ALL");
     223        } else if (selblock == id) {
     224                selblock = -1;
    220225        }
    221226
     
    223228}
    224229
    225 const char* Gui::matVal(int x, int y)
    226 {
    227         if (x == 0)
    228         {
    229                 switch(y)
     230const char* Gui::matVal(int y, int x)
     231{
     232        if (y == 0)
     233        {
     234                switch(x)
    230235                {
    231236                        case 0:
     
    237242                                std::ostringstream name;
    238243                                name << std::hex;
    239                                 name << (y-1);
     244                                name << (x-1);
    240245                                return name.str().c_str();
    241246                        }
     
    243248        }
    244249
    245         if (y == 0)
    246         {
    247                 return "C";
    248         }
    249 
    250         return "V";
     250        if (x == 0)
     251        {
     252                std::ostringstream name;
     253                name << std::hex;
     254                name << (y-1)*16;
     255                return name.str().c_str();
     256        }
     257
     258        if (file == NULL || selblock < 0 || selblock >= file->getBlockCount())
     259                return "";
     260        const Tape::Block& block = file->getBlock(selblock);
     261
     262        if (x == 17)
     263        {
     264                int off = (y-1)*16;
     265                std::ostringstream txt;
     266                for(int j = 0; j < 16; j++)
     267                {
     268                        if (off + j >= block.length)
     269                                break;
     270                        char c = block.data[off+j];
     271                        if (isprint(c))
     272                                txt << c;
     273                        else
     274                                txt << '.';
     275                }
     276                return txt.str().c_str();
     277        } else {
     278
     279                int pos = (y-1) * 16 + (x-1);
     280                if (pos >= block.length)
     281                        return "";
     282
     283                return toHex(block.data[pos]);
     284        }
    251285}
    252286
     
    263297        return IUP_DEFAULT;
    264298}
     299
     300const char* Gui::toHex(int val)
     301{
     302        std::ostringstream str;
     303        str.flags(std::ios_base::hex | std::ios_base::uppercase);
     304        str.width(2);
     305        str.fill('0');
     306        str << val;
     307        return str.str().c_str();
     308}
  • elec/CrO2/software/gui.h

    rc2a9854 r53c4be3  
    99#include <cstdio>
    1010
    11 class K5;
     11class Tape;
    1212
    1313class Gui {
     
    2020                int menu_exit();
    2121
    22                 K5* file;
     22                Tape* file;
    2323
    2424                // Control
     
    2727                // Explore
    2828                int selectBlock(int id, int what);
    29                 const char* matVal(int x, int y);
     29                const char* matVal(int y, int x);
     30                const char* toHex(int val);
     31               
     32                int selblock;
    3033                Ihandle* blocklist;
    3134                Ihandle* hexEd;
  • elec/CrO2/software/k5.cpp

    rc2a9854 r53c4be3  
    1010#include <string.h>
    1111
    12 K5::Block::Block(int length,uint8_t type)
    13 {
    14         this->length = length;
    15         data = new uint8_t[length];
    16         this->type = type;
    17 }
    18 
    19 K5::Block::Block(const Block& other)
    20 {
    21         length = other.length;
    22         type = other.type;
    23         data = new uint8_t[length];
    24         memcpy(data, other.data, length);
    25 }
    26 
    27 const K5::Block& K5::Block::operator=(const Block& other)
    28 {
    29         delete[] data;
    30                 // May not be null ?
    31 
    32         length = other.length;
    33         type = other.type;
    34         data = new uint8_t[length];
    35         memcpy(data, other.data, length);
    36 
    37         return *this;
    38 }
    39 
    40 K5::Block::~Block()
    41 {
    42         delete[] data;
    43 }
    44 
    45 
    46 K5::K5(const char* name)
     12K5::K5(const char* name) throw (const char*)
    4713{
    4814        std::ifstream stream(name, std::ifstream::in | std::ifstream::binary);
     
    6531                if (blksize == 0) blksize = 256;
    6632                blksize --;
    67                 Block block(blksize, blktype);
    68                 stream.read((char*)block.data, block.length);
     33                Block* block = new Block(blksize, blktype);
     34                stream.read((char*)block->data, block->length);
    6935
    7036                blocks.push_back(block);
    71 /*
    72                 if (block.type == 0)
    73                 {
    74                         printf("FILE: %.11s\n",block.data);
    75                 }
    76                
    77                 printf("blk type %d size %d (%d)\n", block.type, block.length, (int)stream.tellg());
    78 */
    7937        } while (stream.good());
    8038
     
    8341}
    8442
    85 int K5::getBlockCount()
     43
     44K5::Block::Block(int length, uint8_t type)
     45        : Tape::Block(length)
    8646{
    87         return blocks.size();
     47        this->type = type;
    8848}
    8949
    90 K5::Block K5::getBlock(int id)
     50bool K5::Block::isFile() const
    9151{
    92         return blocks[id];
     52        return type == 0;
    9353}
     54
     55bool K5::Block::isControl() const
     56{
     57        return (type == 0) || (type == 0xFF);
     58}
     59
     60const std::string K5::Block::getName() const
     61{
     62        if (isFile())
     63        {
     64                char name[12];
     65                memcpy(name, data, 11);
     66                name[11] = 0;
     67                return std::string(name);
     68        }
     69
     70        if (isControl()) return std::string("EOF");
     71        return std::string("DATA");
     72}
  • elec/CrO2/software/k5.h

    rc2a9854 r53c4be3  
    55 */
    66
    7 #include <stdint.h>
    8 #include <vector>
     7#include "Tape.h"
    98
    10 class K5 {
     9class K5: public Tape {
    1110        public:
    12                 K5(const char* filename);
     11                friend class Tape;
    1312
    14                 class Block {
     13                class Block: public Tape::Block
     14                {
    1515                        public:
    1616                                Block(int length, uint8_t type);
    17                                 Block(const Block& other);
    18                                 ~Block();
    19                                 const Block& operator=(const Block& other);
    2017
    21                                 int length;
    22                                 uint8_t* data;
     18                                bool isFile() const;
     19                                bool isControl() const;
     20                                const std::string getName() const;
     21
    2322                                uint8_t type;
    2423                        private:
    25                                 Block();
     24                                Block() = delete;
    2625                };
    2726
    28                 int getBlockCount();
    29                 Block getBlock(int number);
    30 
    3127        private:
    32                 K5();
    33                 std::vector<Block> blocks;
     28                K5(const char* filename) throw (const char*);
     29                K5() = delete;
    3430};
Note: See TracChangeset for help on using the changeset viewer.