src/mess/machine/hp48.c
| r14704 | r14705 | |
| 37 | 37 | #define HP48_MODULE_MASK_KNOWN 1 |
| 38 | 38 | #define HP48_MODULE_CONFIGURED 2 |
| 39 | 39 | |
| 40 | | /* port specification */ |
| 41 | | struct hp48_port_config |
| 42 | | { |
| 43 | | int port; /* port index: 0 or 1 (for port 1 and 2) */ |
| 44 | | int module; /* memory module where the port is visible */ |
| 45 | | int max_size; /* maximum size, in bytes 128 KB or 4 GB */ |
| 46 | | |
| 47 | | /* device instance names */ |
| 48 | | const char* brief_name; |
| 49 | | const char* name; |
| 50 | | |
| 51 | | }; |
| 52 | | |
| 53 | | |
| 54 | 40 | /*************************************************************************** |
| 55 | 41 | GLOBAL VARIABLES & CONSTANTS |
| 56 | 42 | ***************************************************************************/ |
| r14704 | r14705 | |
| 985 | 971 | /* ----- card images ------ */ |
| 986 | 972 | |
| 987 | 973 | /* port information configurations */ |
| 988 | | const struct hp48_port_config hp48sx_port1_config = { 0, 2, 128*1024, "p1", "port1" }; |
| 989 | | const struct hp48_port_config hp48sx_port2_config = { 1, 3, 128*1024, "p2", "port2" }; |
| 990 | | const struct hp48_port_config hp48gx_port1_config = { 0, 3, 128*1024, "p1", "port1" }; |
| 991 | | const struct hp48_port_config hp48gx_port2_config = { 1, 4, 4*1024*1024, "p2", "port2" }; |
| 974 | const struct hp48_port_interface hp48sx_port1_config = { 0, 2, 128*1024 }; |
| 975 | const struct hp48_port_interface hp48sx_port2_config = { 1, 3, 128*1024 }; |
| 976 | const struct hp48_port_interface hp48gx_port1_config = { 0, 3, 128*1024 }; |
| 977 | const struct hp48_port_interface hp48gx_port2_config = { 1, 4, 4*1024*1024 }; |
| 992 | 978 | |
| 979 | const device_type HP48_PORT = &device_creator<hp48_port_image_device>; |
| 980 | |
| 993 | 981 | /* helper for load and create */ |
| 994 | | static void hp48_fill_port( device_t* image ) |
| 982 | void hp48_port_image_device::hp48_fill_port() |
| 995 | 983 | { |
| 996 | | hp48_state *state = image->machine().driver_data<hp48_state>(); |
| 997 | | struct hp48_port_config* conf = (struct hp48_port_config*) image->static_config(); |
| 984 | hp48_state *state = machine().driver_data<hp48_state>(); |
| 985 | struct hp48_port_interface* conf = (struct hp48_port_interface*) static_config(); |
| 998 | 986 | int size = state->m_port_size[conf->port]; |
| 999 | | LOG(( "hp48_fill_port: %s module=%i size=%i rw=%i\n", conf->name, conf->module, size, state->m_port_write[conf->port] )); |
| 987 | LOG(( "hp48_fill_port: %s module=%i size=%i rw=%i\n", tag(), conf->module, size, state->m_port_write[conf->port] )); |
| 1000 | 988 | state->m_port_data[conf->port] = (UINT8*)malloc( 2 * size ); |
| 1001 | 989 | memset( state->m_port_data[conf->port], 0, 2 * size ); |
| 1002 | 990 | state->m_modules[conf->module].off_mask = 2 * (( size > 128 * 1024 ) ? 128 * 1024 : size) - 1; |
| r14704 | r14705 | |
| 1011 | 999 | } |
| 1012 | 1000 | |
| 1013 | 1001 | /* helper for start and unload */ |
| 1014 | | static void hp48_unfill_port( device_t* image ) |
| 1002 | void hp48_port_image_device::hp48_unfill_port() |
| 1015 | 1003 | { |
| 1016 | | hp48_state *state = image->machine().driver_data<hp48_state>(); |
| 1017 | | struct hp48_port_config* conf = (struct hp48_port_config*) image->static_config(); |
| 1004 | hp48_state *state = machine().driver_data<hp48_state>(); |
| 1005 | struct hp48_port_interface* conf = (struct hp48_port_interface*) static_config(); |
| 1018 | 1006 | state->m_modules[conf->module].off_mask = 0x00fff; /* 2 KB */ |
| 1019 | 1007 | state->m_modules[conf->module].read = NULL; |
| 1020 | 1008 | state->m_modules[conf->module].write = NULL; |
| r14704 | r14705 | |
| 1022 | 1010 | } |
| 1023 | 1011 | |
| 1024 | 1012 | |
| 1025 | | static DEVICE_IMAGE_LOAD( hp48_port ) |
| 1013 | bool hp48_port_image_device::call_load() |
| 1026 | 1014 | { |
| 1027 | | hp48_state *state = image.device().machine().driver_data<hp48_state>(); |
| 1028 | | struct hp48_port_config* conf = (struct hp48_port_config*) image.device().static_config(); |
| 1029 | | int size = image.length(); |
| 1015 | hp48_state *state = machine().driver_data<hp48_state>(); |
| 1016 | struct hp48_port_interface* conf = (struct hp48_port_interface*)static_config(); |
| 1017 | int size = length(); |
| 1030 | 1018 | if ( size == 0 ) size = conf->max_size; /* default size */ |
| 1031 | 1019 | |
| 1032 | 1020 | /* check size */ |
| 1033 | 1021 | if ( (size < 32*1024) || (size > conf->max_size) || (size & (size-1)) ) |
| 1034 | 1022 | { |
| 1035 | | logerror( "hp48: image size for %s should be a power of two between %i and %i\n", conf->name, 32*1024, conf->max_size ); |
| 1023 | logerror( "hp48: image size for %s should be a power of two between %i and %i\n", tag(), 32*1024, conf->max_size ); |
| 1036 | 1024 | return IMAGE_INIT_FAIL; |
| 1037 | 1025 | } |
| 1038 | 1026 | |
| 1039 | 1027 | state->m_port_size[conf->port] = size; |
| 1040 | | state->m_port_write[conf->port] = !image.is_readonly(); |
| 1041 | | hp48_fill_port( image ); |
| 1042 | | image.fread(state->m_port_data[conf->port], state->m_port_size[conf->port] ); |
| 1028 | state->m_port_write[conf->port] = !is_readonly(); |
| 1029 | hp48_fill_port( ); |
| 1030 | fread(state->m_port_data[conf->port], state->m_port_size[conf->port] ); |
| 1043 | 1031 | hp48_decode_nibble( state->m_port_data[conf->port], state->m_port_data[conf->port], state->m_port_size[conf->port] ); |
| 1044 | 1032 | return IMAGE_INIT_PASS; |
| 1045 | 1033 | } |
| 1046 | 1034 | |
| 1047 | | static DEVICE_IMAGE_CREATE( hp48_port ) |
| 1035 | bool hp48_port_image_device::call_create(int format_type, option_resolution *format_options) |
| 1048 | 1036 | { |
| 1049 | | hp48_state *state = image.device().machine().driver_data<hp48_state>(); |
| 1050 | | struct hp48_port_config* conf = (struct hp48_port_config*) image.device().static_config(); |
| 1037 | hp48_state *state = machine().driver_data<hp48_state>(); |
| 1038 | struct hp48_port_interface* conf = (struct hp48_port_interface*) static_config(); |
| 1051 | 1039 | int size = conf->max_size; |
| 1052 | 1040 | /* XXX defaults to max_size; get user-specified size instead */ |
| 1053 | 1041 | |
| r14704 | r14705 | |
| 1055 | 1043 | /* size must be a power of 2 between 32K and max_size */ |
| 1056 | 1044 | if ( (size < 32*1024) || (size > conf->max_size) || (size & (size-1)) ) |
| 1057 | 1045 | { |
| 1058 | | logerror( "hp48: image size for %s should be a power of two between %i and %i\n", conf->name, 32*1024, conf->max_size ); |
| 1046 | logerror( "hp48: image size for %s should be a power of two between %i and %i\n", tag(), 32*1024, conf->max_size ); |
| 1059 | 1047 | return IMAGE_INIT_FAIL; |
| 1060 | 1048 | } |
| 1061 | 1049 | |
| 1062 | 1050 | state->m_port_size[conf->port] = size; |
| 1063 | 1051 | state->m_port_write[conf->port] = 1; |
| 1064 | | hp48_fill_port( image ); |
| 1052 | hp48_fill_port(); |
| 1065 | 1053 | return IMAGE_INIT_PASS; |
| 1066 | 1054 | } |
| 1067 | 1055 | |
| 1068 | | static DEVICE_IMAGE_UNLOAD( hp48_port ) |
| 1056 | void hp48_port_image_device::call_unload() |
| 1069 | 1057 | { |
| 1070 | | hp48_state *state = image.device().machine().driver_data<hp48_state>(); |
| 1071 | | struct hp48_port_config* conf = (struct hp48_port_config*) image.device().static_config(); |
| 1058 | hp48_state *state = machine().driver_data<hp48_state>(); |
| 1059 | struct hp48_port_interface* conf = (struct hp48_port_interface*) static_config(); |
| 1072 | 1060 | LOG(( "hp48_port image unload: %s size=%i rw=%i\n", |
| 1073 | | conf->name, state->m_port_size[conf->port] ,state->m_port_write[conf->port] )); |
| 1061 | tag(), state->m_port_size[conf->port] ,state->m_port_write[conf->port] )); |
| 1074 | 1062 | if ( state->m_port_write[conf->port] ) |
| 1075 | 1063 | { |
| 1076 | 1064 | hp48_encode_nibble( state->m_port_data[conf->port], state->m_port_data[conf->port], state->m_port_size[conf->port] ); |
| 1077 | | image.fseek( 0, SEEK_SET ); |
| 1078 | | image.fwrite( state->m_port_data[conf->port], state->m_port_size[conf->port] ); |
| 1065 | fseek( 0, SEEK_SET ); |
| 1066 | fwrite( state->m_port_data[conf->port], state->m_port_size[conf->port] ); |
| 1079 | 1067 | } |
| 1080 | 1068 | free( state->m_port_data[conf->port] ); |
| 1081 | | hp48_unfill_port( image ); |
| 1069 | hp48_unfill_port(); |
| 1082 | 1070 | hp48_apply_modules(state); |
| 1083 | 1071 | } |
| 1084 | 1072 | |
| 1085 | | static DEVICE_START( hp48_port ) |
| 1073 | void hp48_port_image_device::device_start() |
| 1086 | 1074 | { |
| 1087 | | hp48_unfill_port( device ); |
| 1075 | hp48_unfill_port(); |
| 1088 | 1076 | } |
| 1089 | 1077 | |
| 1090 | | DEVICE_GET_INFO( hp48_port ) |
| 1078 | hp48_port_image_device::hp48_port_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 1079 | : device_t(mconfig, HP48_PORT, "HP48 memory card", tag, owner, clock), |
| 1080 | device_image_interface(mconfig, *this) |
| 1091 | 1081 | { |
| 1092 | | struct hp48_port_config* conf = device ? (struct hp48_port_config*) device->static_config() : NULL; |
| 1093 | | switch ( state ) |
| 1094 | | { |
| 1095 | | case DEVINFO_INT_TOKEN_BYTES: info->i = 1; break; |
| 1096 | | case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; |
| 1097 | | case DEVINFO_INT_IMAGE_TYPE: info->i = IO_MEMCARD; break; |
| 1098 | | case DEVINFO_INT_IMAGE_READABLE: info->i = 1; break; |
| 1099 | | case DEVINFO_INT_IMAGE_WRITEABLE: info->i = 1; break; |
| 1100 | | case DEVINFO_INT_IMAGE_CREATABLE: info->i = 1; break; |
| 1101 | | case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( hp48_port ); break; |
| 1102 | | case DEVINFO_FCT_IMAGE_LOAD: info->f = (genf *) DEVICE_IMAGE_LOAD_NAME( hp48_port ); break; |
| 1103 | | case DEVINFO_FCT_IMAGE_UNLOAD: info->f = (genf *) DEVICE_IMAGE_UNLOAD_NAME( hp48_port ); break; |
| 1104 | | case DEVINFO_FCT_IMAGE_CREATE: info->f = (genf *) DEVICE_IMAGE_CREATE_NAME( hp48_port ); break; |
| 1105 | | case DEVINFO_STR_IMAGE_BRIEF_INSTANCE_NAME: strcpy(info->s, conf ? conf->brief_name : ""); break; |
| 1106 | | case DEVINFO_STR_IMAGE_INSTANCE_NAME: strcpy(info->s, conf ? conf->name : ""); break; |
| 1107 | | case DEVINFO_STR_NAME: strcpy( info->s, "HP48 memory card"); break; |
| 1108 | | case DEVINFO_STR_FAMILY: strcpy(info->s, "HP48 memory card"); break; |
| 1109 | | case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; |
| 1110 | | case DEVINFO_STR_IMAGE_FILE_EXTENSIONS: strcpy(info->s, "crd"); break; |
| 1111 | | } |
| 1112 | 1082 | } |
| 1113 | 1083 | |
| 1084 | void hp48_port_image_device::device_config_complete() |
| 1085 | { |
| 1086 | update_names(HP48_PORT, "port", "p"); |
| 1087 | } |
| 1114 | 1088 | |
| 1115 | | |
| 1116 | | |
| 1117 | 1089 | /*************************************************************************** |
| 1118 | 1090 | MACHINES |
| 1119 | 1091 | ***************************************************************************/ |
| r14704 | r14705 | |
| 1265 | 1237 | { |
| 1266 | 1238 | hp48_machine_start( machine, HP48_GP ); |
| 1267 | 1239 | } |
| 1268 | | |
| 1269 | | DEFINE_LEGACY_IMAGE_DEVICE(HP48_PORT, hp48_port); |
src/mess/includes/hp48.h
| r14704 | r14705 | |
| 123 | 123 | |
| 124 | 124 | /****************************** cards ********************************/ |
| 125 | 125 | |
| 126 | | struct hp48_port_config; |
| 126 | /* port specification */ |
| 127 | struct hp48_port_interface |
| 128 | { |
| 129 | int port; /* port index: 0 or 1 (for port 1 and 2) */ |
| 130 | int module; /* memory module where the port is visible */ |
| 131 | int max_size; /* maximum size, in bytes 128 KB or 4 GB */ |
| 132 | }; |
| 127 | 133 | |
| 128 | | extern const struct hp48_port_config hp48sx_port1_config; |
| 129 | | extern const struct hp48_port_config hp48sx_port2_config; |
| 130 | | extern const struct hp48_port_config hp48gx_port1_config; |
| 131 | | extern const struct hp48_port_config hp48gx_port2_config; |
| 134 | class hp48_port_image_device : public device_t, |
| 135 | public device_image_interface, |
| 136 | public hp48_port_interface |
| 137 | { |
| 138 | public: |
| 139 | // construction/destruction |
| 140 | hp48_port_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 132 | 141 | |
| 133 | | DECLARE_LEGACY_IMAGE_DEVICE(HP48_PORT, hp48_port); |
| 142 | // image-level overrides |
| 143 | virtual iodevice_t image_type() const { return IO_MEMCARD; } |
| 134 | 144 | |
| 145 | virtual bool is_readable() const { return 1; } |
| 146 | virtual bool is_writeable() const { return 1; } |
| 147 | virtual bool is_creatable() const { return 1; } |
| 148 | virtual bool must_be_loaded() const { return 0; } |
| 149 | virtual bool is_reset_on_load() const { return 0; } |
| 150 | virtual const char *image_interface() const { return NULL; } |
| 151 | virtual const char *file_extensions() const { return "crd"; } |
| 152 | virtual const option_guide *create_option_guide() const { return NULL; } |
| 153 | |
| 154 | virtual bool call_load(); |
| 155 | virtual void call_unload(); |
| 156 | virtual bool call_create(int format_type, option_resolution *format_options); |
| 157 | protected: |
| 158 | // device-level overrides |
| 159 | virtual void device_config_complete(); |
| 160 | virtual void device_start(); |
| 161 | private: |
| 162 | void hp48_fill_port(); |
| 163 | void hp48_unfill_port(); |
| 164 | }; |
| 165 | |
| 166 | extern const struct hp48_port_interface hp48sx_port1_config; |
| 167 | extern const struct hp48_port_interface hp48sx_port2_config; |
| 168 | extern const struct hp48_port_interface hp48gx_port1_config; |
| 169 | extern const struct hp48_port_interface hp48gx_port2_config; |
| 170 | |
| 171 | // device type definition |
| 172 | extern const device_type HP48_PORT; |
| 173 | |
| 135 | 174 | #define MCFG_HP48_PORT_ADD(_tag, _intrf) \ |
| 136 | 175 | MCFG_DEVICE_ADD(_tag, HP48_PORT, 0) \ |
| 137 | 176 | MCFG_DEVICE_CONFIG(_intrf) |