trunk/src/mess/drivers/hprot1.c
| r0 | r26923 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | HENRY Prot I - brazilian document timestamp printer |
| 4 | http://www.dataponto.com.br/protocoladores-prot1.html |
| 5 | |
| 6 | Driver by Felipe Sanches |
| 7 | Technical info at https://www.garoa.net.br/wiki/HENRY |
| 8 | |
| 9 | Licensed under GPLv2 or later. |
| 10 | |
| 11 | NOTE: Even though the MAME/MESS project has been adopting a non-commercial additional licensing clause, I do allow commercial usage of my portion of the code according to the plain terms of the GPL license (version 2 or later). This is useful if you happen to use my code in another project or in case the other MAME/MESS developers happen to drop the non-comercial clause completely. I suggest that other developers consider doing the same. --Felipe Sanches |
| 12 | |
| 13 | Changelog: |
| 14 | |
| 15 | 2014 JAN 03 [Felipe Sanches]: |
| 16 | * Initial driver skeleton |
| 17 | * Address lines bitswaping |
| 18 | * LCD works. We can see boot messages. |
| 19 | * Inputs are not working correctly |
| 20 | |
| 21 | TO-DO list: |
| 22 | |
| 23 | There seems to be an eeprom or a realtime clock placed at U2 (DIP8): |
| 24 | pin1 -> 8031 pin 14 (T0: Timer 0 external input) |
| 25 | pin2 -> crystal at X2 (labeled 32.768) |
| 26 | pin3 -> ? |
| 27 | pin4 -> GND |
| 28 | pin5 -> ? |
| 29 | pin6 -> 8031 pin 5 (Port 1 bit 4) |
| 30 | pin7 -> 8031 pin 4 (Port 1 bit 3) |
| 31 | pin8 -> VCC |
| 32 | |
| 33 | (no context): unmapped io memory write to 20003 = FF & FF |
| 34 | (no context): unmapped io memory write to 20002 = FF & FF |
| 35 | (no context): unmapped io memory write to 20001 = FF & FF |
| 36 | (no context): unmapped io memory write to 20000 = FF & FF |
| 37 | ':maincpu' (01EB): unmapped io memory write to 20001 = 7F & FF |
| 38 | ':maincpu' (01EE): unmapped io memory write to 20003 = FF & FF |
| 39 | ':maincpu' (01F0): unmapped io memory write to 20001 = 77 & FF |
| 40 | ':maincpu' (3500): unmapped io memory write to 20003 = FF & FF |
| 41 | ':maincpu' (0208): unmapped io memory write to 20001 = 77 & FF |
| 42 | ':maincpu' (13F7): unmapped io memory write to 20001 = 77 & FF |
| 43 | ':maincpu' (13EF): unmapped io memory write to 20001 = 67 & FF |
| 44 | ':maincpu' (13F7): unmapped io memory write to 20001 = 77 & FF |
| 45 | The last 2 lines repeat endlessly. |
| 46 | |
| 47 | ****************************************************************************/ |
| 48 | |
| 49 | #include "emu.h" |
| 50 | #include "cpu/mcs51/mcs51.h" |
| 51 | #include "video/hd44780.h" |
| 52 | #include "rendlay.h" |
| 53 | |
| 54 | class hprot1_state : public driver_device |
| 55 | { |
| 56 | public: |
| 57 | hprot1_state(const machine_config &mconfig, device_type type, const char *tag) |
| 58 | : driver_device(mconfig, type, tag) |
| 59 | , m_maincpu(*this, "maincpu") |
| 60 | , m_lcdc(*this, "hd44780") |
| 61 | { } |
| 62 | |
| 63 | //DECLARE_WRITE8_MEMBER(henry_io_w); |
| 64 | DECLARE_READ8_MEMBER(henry_io_r); |
| 65 | DECLARE_DRIVER_INIT(hprot1); |
| 66 | private: |
| 67 | virtual void machine_start(); |
| 68 | virtual void machine_reset(); |
| 69 | virtual void palette_init(); |
| 70 | required_device<cpu_device> m_maincpu; |
| 71 | required_device<hd44780_device> m_lcdc; |
| 72 | }; |
| 73 | |
| 74 | #define LOG_IO_PORTS 0 |
| 75 | |
| 76 | static ADDRESS_MAP_START(i80c31_prg, AS_PROGRAM, 8, hprot1_state) |
| 77 | AM_RANGE(0x0000, 0xffff) AM_ROM |
| 78 | ADDRESS_MAP_END |
| 79 | |
| 80 | DRIVER_INIT_MEMBER( hprot1_state, hprot1 ) |
| 81 | { |
| 82 | int i; |
| 83 | UINT8 *ROM = memregion("maincpu")->base(); |
| 84 | UINT8 bitswapped_ROM[0x10000]; |
| 85 | |
| 86 | for(i=0x0000;i<0x10000;i++) |
| 87 | bitswapped_ROM[i] = ROM[i]; |
| 88 | |
| 89 | for(i=0x0000;i<0x10000;i++) |
| 90 | ROM[BITSWAP16(i, 15, 14, 13, 12, 11, 10, 9, 8, 3, 2, 1, 0, 4, 5, 6, 7)] = bitswapped_ROM[i]; |
| 91 | } |
| 92 | |
| 93 | //A4 = display RS |
| 94 | //A5 = display R/W |
| 95 | //(A11 == 0) && (A10 == 0) => display CS |
| 96 | //(A14 == 1) && (A15 == 1) => enable signal for the mux that selects peripherals |
| 97 | //11?? 00?? ??00 ???? write data |
| 98 | //11?? 00?? ??01 ???? write command |
| 99 | //11?? 00?? ??10 ???? read data |
| 100 | //11?? 00?? ??11 ???? read command |
| 101 | //mirror=0x33cf |
| 102 | |
| 103 | //write: 0xc400 => U12 (?) |
| 104 | //write: 0xc800 => U11 (?) |
| 105 | //read: 0xc020 => display |
| 106 | //write: 0xc000 => display |
| 107 | //write: 0xc010 => display |
| 108 | |
| 109 | //P1.4 => WhatchDog Input (after timeout resets CPU) |
| 110 | |
| 111 | static ADDRESS_MAP_START(i80c31_io, AS_IO, 8, hprot1_state) |
| 112 | AM_RANGE(0x0000,0x7fff) AM_RAM |
| 113 | AM_RANGE(0xc000,0xc000) AM_MIRROR(0x33cf) AM_DEVWRITE("hd44780", hd44780_device, control_write) |
| 114 | AM_RANGE(0xc010,0xc010) AM_MIRROR(0x33cf) AM_DEVWRITE("hd44780", hd44780_device, data_write) |
| 115 | AM_RANGE(0xc020,0xc020) AM_MIRROR(0x33cf) AM_DEVREAD("hd44780", hd44780_device, control_read) |
| 116 | AM_RANGE(0xc030,0xc030) AM_MIRROR(0x33cf) AM_DEVREAD("hd44780", hd44780_device, data_read) |
| 117 | //AM_RANGE(MCS51_PORT_P0, MCS51_PORT_P3) AM_READWRITE(henry_io_r, henry_io_w) |
| 118 | AM_RANGE(MCS51_PORT_P0, MCS51_PORT_P3) AM_READ(henry_io_r) |
| 119 | ADDRESS_MAP_END |
| 120 | |
| 121 | static INPUT_PORTS_START( hprot1 ) |
| 122 | PORT_START("inputs") |
| 123 | PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Upper Black Button") PORT_CODE(KEYCODE_A) |
| 124 | PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Lower Black Button") PORT_CODE(KEYCODE_B) |
| 125 | PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Blue Button") PORT_CODE(KEYCODE_C) |
| 126 | PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Paper Detector") PORT_CODE(KEYCODE_D) |
| 127 | PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("XMIN Endstop") PORT_CODE(KEYCODE_E) |
| 128 | INPUT_PORTS_END |
| 129 | |
| 130 | void hprot1_state::machine_start() |
| 131 | { |
| 132 | } |
| 133 | |
| 134 | void hprot1_state::machine_reset() |
| 135 | { |
| 136 | } |
| 137 | |
| 138 | READ8_MEMBER(hprot1_state::henry_io_r) |
| 139 | { |
| 140 | switch (offset) |
| 141 | { |
| 142 | case 0x01: |
| 143 | { |
| 144 | UINT8 value = (ioport("inputs")->read()) & 0x67; |
| 145 | #if LOG_IO_PORTS |
| 146 | printf("value:%02X\n", value); |
| 147 | #endif |
| 148 | return value; |
| 149 | } |
| 150 | default: |
| 151 | #if LOG_IO_PORTS |
| 152 | printf("Unhandled I/O Read at offset 0x%02X (return 0)\n", offset); |
| 153 | #endif |
| 154 | return 0; |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | /* |
| 159 | WRITE8_MEMBER(hprot1_state::henry_io_w) |
| 160 | { |
| 161 | static UINT8 p0=0, p1=0, p2=0, p3=0; |
| 162 | switch (offset) |
| 163 | { |
| 164 | case 0x00: |
| 165 | { |
| 166 | if (data != p0) |
| 167 | { |
| 168 | p0=data; |
| 169 | #if LOG_IO_PORTS |
| 170 | printf("Write to P0: %02X\n", data); |
| 171 | #endif |
| 172 | } |
| 173 | break; |
| 174 | } |
| 175 | case 0x01: |
| 176 | { |
| 177 | if (data != p1) |
| 178 | { |
| 179 | p1=data; |
| 180 | if (data != 0xFF && data != 0xEF) |
| 181 | #if LOG_IO_PORTS |
| 182 | printf("Write to P1: %02X\n", data); |
| 183 | #endif |
| 184 | } |
| 185 | break; |
| 186 | } |
| 187 | case 0x02: |
| 188 | { |
| 189 | if (data != p2) |
| 190 | { |
| 191 | p2=data; |
| 192 | #if LOG_IO_PORTS |
| 193 | printf("Write to P2: %02X\n", data); |
| 194 | #endif |
| 195 | } |
| 196 | break; |
| 197 | } |
| 198 | case 0x03: |
| 199 | { |
| 200 | if (data != p3) |
| 201 | { |
| 202 | p3=data; |
| 203 | #if LOG_IO_PORTS |
| 204 | printf("Write to P3: %02X\n", data); |
| 205 | #endif |
| 206 | } |
| 207 | break; |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | */ |
| 212 | |
| 213 | void hprot1_state::palette_init() |
| 214 | { |
| 215 | palette_set_color(machine(), 0, MAKE_RGB(138, 146, 148)); |
| 216 | palette_set_color(machine(), 1, MAKE_RGB(92, 83, 88)); |
| 217 | } |
| 218 | |
| 219 | static const gfx_layout henry_prot_charlayout = |
| 220 | { |
| 221 | 5, 8, /* 5 x 8 characters */ |
| 222 | 256, /* 256 characters */ |
| 223 | 1, /* 1 bits per pixel */ |
| 224 | { 0 }, /* no bitplanes */ |
| 225 | { 3, 4, 5, 6, 7}, |
| 226 | { 0, 8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8}, |
| 227 | 8*8 /* 8 bytes */ |
| 228 | }; |
| 229 | |
| 230 | static GFXDECODE_START( hprot1 ) |
| 231 | GFXDECODE_ENTRY( "hd44780:cgrom", 0x0000, henry_prot_charlayout, 0, 1 ) |
| 232 | GFXDECODE_END |
| 233 | |
| 234 | static MACHINE_CONFIG_START( hprot1, hprot1_state ) |
| 235 | /* basic machine hardware */ |
| 236 | MCFG_CPU_ADD("maincpu", I80C31, XTAL_10MHz) |
| 237 | MCFG_CPU_PROGRAM_MAP(i80c31_prg) |
| 238 | MCFG_CPU_IO_MAP(i80c31_io) |
| 239 | |
| 240 | /* video hardware */ |
| 241 | MCFG_SCREEN_ADD("screen", LCD) |
| 242 | MCFG_SCREEN_REFRESH_RATE(50) |
| 243 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 244 | MCFG_SCREEN_UPDATE_DEVICE("hd44780", hd44780_device, screen_update) |
| 245 | MCFG_SCREEN_SIZE(6*16, 9*2) |
| 246 | MCFG_SCREEN_VISIBLE_AREA(0, 6*16-1, 0, 9*2-1) |
| 247 | MCFG_DEFAULT_LAYOUT(layout_lcd) |
| 248 | MCFG_PALETTE_LENGTH(2) |
| 249 | MCFG_GFXDECODE(hprot1) |
| 250 | |
| 251 | MCFG_HD44780_ADD("hd44780") |
| 252 | MCFG_HD44780_LCD_SIZE(2, 16) |
| 253 | MACHINE_CONFIG_END |
| 254 | |
| 255 | ROM_START( hprot1 ) |
| 256 | ROM_REGION( 0x10000, "maincpu", 0 ) |
| 257 | ROM_LOAD( "henry_prot1_rev1_v19.bin", 0x00000, 0x10000, CRC(dd7787fd) SHA1(61a37dd406b3440d568bd6da75a9fdc8a0f0e1e3) ) |
| 258 | ROM_END |
| 259 | |
| 260 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ |
| 261 | COMP( 2004, hprot1, 0, 0, hprot1, hprot1, hprot1_state, hprot1, "HENRY", "Henry Prot I v19 (REV.1)", GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND) |