Annotation of qemu/hw/tc58128.c, revision 1.1

1.1     ! root        1: #include <assert.h>
        !             2: #include "vl.h"
        !             3: 
        !             4: #define CE1  0x0100
        !             5: #define CE2  0x0200
        !             6: #define RE   0x0400
        !             7: #define WE   0x0800
        !             8: #define ALE  0x1000
        !             9: #define CLE  0x2000
        !            10: #define RDY1 0x4000
        !            11: #define RDY2 0x8000
        !            12: #define RDY(n) ((n) == 0 ? RDY1 : RDY2)
        !            13: 
        !            14: typedef enum { WAIT, READ1, READ2, READ3 } state_t;
        !            15: 
        !            16: typedef struct {
        !            17:     uint8_t *flash_contents;
        !            18:     state_t state;
        !            19:     uint32_t address;
        !            20:     uint8_t address_cycle;
        !            21: } tc58128_dev;
        !            22: 
        !            23: static tc58128_dev tc58128_devs[2];
        !            24: 
        !            25: #define FLASH_SIZE (16*1024*1024)
        !            26: 
        !            27: void init_dev(tc58128_dev * dev, char *filename)
        !            28: {
        !            29:     int ret, blocks;
        !            30: 
        !            31:     dev->state = WAIT;
        !            32:     dev->flash_contents = qemu_mallocz(FLASH_SIZE);
        !            33:     memset(dev->flash_contents, 0xff, FLASH_SIZE);
        !            34:     if (!dev->flash_contents) {
        !            35:        fprintf(stderr, "could not alloc memory for flash\n");
        !            36:        exit(1);
        !            37:     }
        !            38:     if (filename) {
        !            39:        /* Load flash image skipping the first block */
        !            40:        ret = load_image(filename, dev->flash_contents + 528 * 32);
        !            41:        if (ret < 0) {
        !            42:            fprintf(stderr, "ret=%d\n", ret);
        !            43:            fprintf(stderr, "qemu: could not load flash image %s\n",
        !            44:                    filename);
        !            45:            exit(1);
        !            46:        } else {
        !            47:            /* Build first block with number of blocks */
        !            48:            blocks = (ret + 528 * 32 - 1) / (528 * 32);
        !            49:            dev->flash_contents[0] = blocks & 0xff;
        !            50:            dev->flash_contents[1] = (blocks >> 8) & 0xff;
        !            51:            dev->flash_contents[2] = (blocks >> 16) & 0xff;
        !            52:            dev->flash_contents[3] = (blocks >> 24) & 0xff;
        !            53:            fprintf(stderr, "loaded %d bytes for %s into flash\n", ret,
        !            54:                    filename);
        !            55:        }
        !            56:     }
        !            57: }
        !            58: 
        !            59: void handle_command(tc58128_dev * dev, uint8_t command)
        !            60: {
        !            61:     switch (command) {
        !            62:     case 0xff:
        !            63:        fprintf(stderr, "reset flash device\n");
        !            64:        dev->state = WAIT;
        !            65:        break;
        !            66:     case 0x00:
        !            67:        fprintf(stderr, "read mode 1\n");
        !            68:        dev->state = READ1;
        !            69:        dev->address_cycle = 0;
        !            70:        break;
        !            71:     case 0x01:
        !            72:        fprintf(stderr, "read mode 2\n");
        !            73:        dev->state = READ2;
        !            74:        dev->address_cycle = 0;
        !            75:        break;
        !            76:     case 0x50:
        !            77:        fprintf(stderr, "read mode 3\n");
        !            78:        dev->state = READ3;
        !            79:        dev->address_cycle = 0;
        !            80:        break;
        !            81:     default:
        !            82:        fprintf(stderr, "unknown flash command 0x%02x\n", command);
        !            83:        assert(0);
        !            84:     }
        !            85: }
        !            86: 
        !            87: void handle_address(tc58128_dev * dev, uint8_t data)
        !            88: {
        !            89:     switch (dev->state) {
        !            90:     case READ1:
        !            91:     case READ2:
        !            92:     case READ3:
        !            93:        switch (dev->address_cycle) {
        !            94:        case 0:
        !            95:            dev->address = data;
        !            96:            if (dev->state == READ2)
        !            97:                dev->address |= 0x100;
        !            98:            else if (dev->state == READ3)
        !            99:                dev->address |= 0x200;
        !           100:            break;
        !           101:        case 1:
        !           102:            dev->address += data * 528 * 0x100;
        !           103:            break;
        !           104:        case 2:
        !           105:            dev->address += data * 528;
        !           106:            fprintf(stderr, "address pointer in flash: 0x%08x\n",
        !           107:                    dev->address);
        !           108:            break;
        !           109:        default:
        !           110:            /* Invalid data */
        !           111:            assert(0);
        !           112:        }
        !           113:        dev->address_cycle++;
        !           114:        break;
        !           115:     default:
        !           116:        assert(0);
        !           117:     }
        !           118: }
        !           119: 
        !           120: uint8_t handle_read(tc58128_dev * dev)
        !           121: {
        !           122: #if 0
        !           123:     if (dev->address % 0x100000 == 0)
        !           124:        fprintf(stderr, "reading flash at address 0x%08x\n", dev->address);
        !           125: #endif
        !           126:     return dev->flash_contents[dev->address++];
        !           127: }
        !           128: 
        !           129: /* We never mark the device as busy, so interrupts cannot be triggered
        !           130:    XXXXX */
        !           131: 
        !           132: int tc58128_cb(uint16_t porta, uint16_t portb,
        !           133:               uint16_t * periph_pdtra, uint16_t * periph_portadir,
        !           134:               uint16_t * periph_pdtrb, uint16_t * periph_portbdir)
        !           135: {
        !           136:     int dev;
        !           137: 
        !           138:     if ((porta & CE1) == 0)
        !           139:        dev = 0;
        !           140:     else if ((porta & CE2) == 0)
        !           141:        dev = 1;
        !           142:     else
        !           143:        return 0;               /* No device selected */
        !           144: 
        !           145:     if ((porta & RE) && (porta & WE)) {
        !           146:        /* Nothing to do, assert ready and return to input state */
        !           147:        *periph_portadir &= 0xff00;
        !           148:        *periph_portadir |= RDY(dev);
        !           149:        *periph_pdtra |= RDY(dev);
        !           150:        return 1;
        !           151:     }
        !           152: 
        !           153:     if (porta & CLE) {
        !           154:        /* Command */
        !           155:        assert((porta & WE) == 0);
        !           156:        handle_command(&tc58128_devs[dev], porta & 0x00ff);
        !           157:     } else if (porta & ALE) {
        !           158:        assert((porta & WE) == 0);
        !           159:        handle_address(&tc58128_devs[dev], porta & 0x00ff);
        !           160:     } else if ((porta & RE) == 0) {
        !           161:        *periph_portadir |= 0x00ff;
        !           162:        *periph_pdtra &= 0xff00;
        !           163:        *periph_pdtra |= handle_read(&tc58128_devs[dev]);
        !           164:     } else {
        !           165:        assert(0);
        !           166:     }
        !           167:     return 1;
        !           168: }
        !           169: 
        !           170: static sh7750_io_device tc58128 = {
        !           171:     RE | WE,                   /* Port A triggers */
        !           172:     0,                         /* Port B triggers */
        !           173:     tc58128_cb                 /* Callback */
        !           174: };
        !           175: 
        !           176: int tc58128_init(struct SH7750State *s, char *zone1, char *zone2)
        !           177: {
        !           178:     init_dev(&tc58128_devs[0], zone1);
        !           179:     init_dev(&tc58128_devs[1], zone2);
        !           180:     return sh7750_register_io_device(s, &tc58128);
        !           181: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.