trunk/src/mess/machine/psxcard.c
| r20321 | r20322 | |
| 19 | 19 | // |
| 20 | 20 | // |
| 21 | 21 | |
| 22 | static const int block_size = 128; |
| 23 | static const int card_size = block_size * 1024; |
| 24 | |
| 22 | 25 | const device_type PSXCARD = &device_creator<psxcard_device>; |
| 23 | 26 | |
| 24 | 27 | enum transfer_states |
| r20321 | r20322 | |
| 37 | 40 | }; |
| 38 | 41 | |
| 39 | 42 | psxcard_device::psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 40 | | : device_t(mconfig, PSXCARD, "Sony PSX Memory Card", tag, owner, clock) |
| 43 | : device_t(mconfig, PSXCARD, "Sony PSX Memory Card", tag, owner, clock), |
| 44 | device_image_interface(mconfig, *this) |
| 41 | 45 | { |
| 42 | 46 | } |
| 43 | 47 | |
| 44 | 48 | void psxcard_device::device_start() |
| 45 | 49 | { |
| 46 | | cache=new unsigned char [128*1024]; |
| 47 | | |
| 48 | | memset(cache, 0, 128*1024); |
| 49 | | |
| 50 | 50 | m_owner = dynamic_cast<psx_controller_port_device *>(owner()); |
| 51 | 51 | m_ack_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(psxcard_device::ack_timer), this)); |
| 52 | 52 | |
| r20321 | r20322 | |
| 77 | 77 | m_owner->ack(); |
| 78 | 78 | } |
| 79 | 79 | |
| 80 | void psxcard_device::device_config_complete() |
| 81 | { |
| 82 | update_names(PSXCARD, "memcard", "mc"); |
| 83 | } |
| 84 | |
| 80 | 85 | // |
| 81 | 86 | // |
| 82 | 87 | // |
| r20321 | r20322 | |
| 88 | 93 | switch (state) |
| 89 | 94 | { |
| 90 | 95 | case state_illegal: |
| 91 | | if (to == 0x81) |
| 96 | if ((to == 0x81) && is_loaded()) |
| 92 | 97 | { |
| 93 | 98 | // printf("CARD: begin\n"); |
| 94 | 99 | state = state_command; |
| r20321 | r20322 | |
| 233 | 238 | printf("card: read block %d\n",addr); |
| 234 | 239 | #endif |
| 235 | 240 | |
| 236 | | if (addr<1024) |
| 241 | if (addr<(card_size/block_size)) |
| 237 | 242 | { |
| 238 | | memcpy(buf,cache+(addr*128),128); |
| 243 | fseek(addr*block_size, SEEK_SET); |
| 244 | fread(buf, block_size); |
| 239 | 245 | } else |
| 240 | 246 | { |
| 241 | | memset(buf,0,128); |
| 247 | memset(buf,0,block_size); |
| 242 | 248 | } |
| 243 | 249 | } |
| 244 | 250 | |
| r20321 | r20322 | |
| 252 | 258 | printf("card: write block %d\n",addr); |
| 253 | 259 | #endif |
| 254 | 260 | |
| 255 | | if (addr<1024) |
| 261 | if (addr<(card_size/block_size)) |
| 256 | 262 | { |
| 257 | | memcpy(cache+(addr*128),buf,128); |
| 263 | fseek(addr*block_size, SEEK_SET); |
| 264 | fwrite(buf, block_size); |
| 258 | 265 | } |
| 259 | 266 | } |
| 260 | 267 | |
| 261 | | // |
| 262 | | // |
| 263 | | // |
| 264 | | |
| 265 | 268 | unsigned char psxcard_device::checksum_data(const unsigned char *buf, const unsigned int sz) |
| 266 | 269 | { |
| 267 | 270 | unsigned char chk=*buf++; |
| r20321 | r20322 | |
| 270 | 273 | return chk; |
| 271 | 274 | } |
| 272 | 275 | |
| 276 | bool psxcard_device::call_load() |
| 277 | { |
| 278 | if(length() != card_size) |
| 279 | return IMAGE_INIT_FAIL; |
| 280 | return IMAGE_INIT_PASS; |
| 281 | } |
| 282 | |
| 283 | bool psxcard_device::call_create(int format_type, option_resolution *format_options) |
| 284 | { |
| 285 | UINT8 block[block_size]; |
| 286 | int i, ret; |
| 287 | |
| 288 | memset(block, '\0', block_size); |
| 289 | for(i = 0; i < (card_size/block_size); i++) |
| 290 | { |
| 291 | ret = fwrite(block, block_size); |
| 292 | if(ret != block_size) |
| 293 | return IMAGE_INIT_FAIL; |
| 294 | } |
| 295 | return IMAGE_INIT_PASS; |
| 296 | } |
| 297 | |
| 273 | 298 | void psxcard_device::do_card() |
| 274 | 299 | { |
| 275 | 300 | if(!m_bit) |
trunk/src/mess/machine/psxcard.h
| r20321 | r20322 | |
| 10 | 10 | #define MCFG_PSXCARD_ADD(_tag) \ |
| 11 | 11 | MCFG_DEVICE_ADD(_tag, PSXCARD, 0) |
| 12 | 12 | |
| 13 | | class psxcard_device : public device_t |
| 13 | class psxcard_device : public device_t, |
| 14 | public device_image_interface |
| 14 | 15 | { |
| 15 | 16 | public: |
| 16 | 17 | psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 17 | 18 | |
| 19 | virtual iodevice_t image_type() const { return IO_MEMCARD; } |
| 20 | |
| 21 | virtual bool is_readable() const { return 1; } |
| 22 | virtual bool is_writeable() const { return 1; } |
| 23 | virtual bool is_creatable() const { return 1; } |
| 24 | virtual bool must_be_loaded() const { return 0; } |
| 25 | virtual bool is_reset_on_load() const { return 0; } |
| 26 | virtual const char *file_extensions() const { return "mc"; } |
| 27 | virtual const option_guide *create_option_guide() const { return NULL; } |
| 28 | |
| 29 | virtual bool call_load(); |
| 30 | virtual bool call_create(int format_type, option_resolution *format_options); |
| 31 | |
| 18 | 32 | private: |
| 19 | | unsigned char pkt[0x8b], pkt_ptr, pkt_sz, cmd, *cache; |
| 33 | unsigned char pkt[0x8b], pkt_ptr, pkt_sz, cmd; |
| 20 | 34 | unsigned short addr; |
| 21 | 35 | int state; |
| 22 | 36 | |
| r20321 | r20322 | |
| 44 | 58 | public: |
| 45 | 59 | virtual void device_start(); |
| 46 | 60 | virtual void device_reset(); |
| 61 | virtual void device_config_complete(); |
| 47 | 62 | |
| 48 | 63 | void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_pad) do_card(); m_clock = state; } |
| 49 | 64 | void sel_w(bool state); |