Previous 199869 Revisions Next

r41448 Thursday 29th October, 2015 at 10:45:52 UTC by Vasantha Crabb
osborne1 improvements [Vas Crabb]
* Bank low 16k according to schematics, passes memory test
* Correct vectoring of IEEE488 interrupt
* Implement RESET key (generates NMI, F12 by default)
[src/mame/drivers]osborne1.c
[src/mame/includes]osborne1.h
[src/mame/machine]osborne1.c

trunk/src/mame/drivers/osborne1.c
r249959r249960
373702 - Set BIT 9 signal (map bank 3 into F000-FFFF)
383803 - Clear BIT 9 signal (map bank 1/2 into F000-FFFF)
3939
40Selecting between bank 1 and bank 2 is also affected by M1 and IRQACK
41conditions using a set of three flipflops.
42
4043TODO:
41  - Implement ROM/IO bank selection properly
4244  - Implement serial port
43  - Implement reset key (generates NMI and affects bank selection)
4445  - Verify frequency of the beep/audio alarm.
4546
4647***************************************************************************/
r249959r249960
5253
5354
5455static ADDRESS_MAP_START( osborne1_mem, AS_PROGRAM, 8, osborne1_state )
55   AM_RANGE( 0x0000, 0x0FFF ) AM_READ_BANK("bank1") AM_WRITE( osborne1_0000_w )
56   AM_RANGE( 0x1000, 0x1FFF ) AM_READ_BANK("bank2") AM_WRITE( osborne1_1000_w )
57   AM_RANGE( 0x2000, 0x3FFF ) AM_READWRITE( osborne1_2000_r, osborne1_2000_w )
56   AM_RANGE( 0x0000, 0x0FFF ) AM_READ_BANK("bank_0xxx") AM_WRITE(bank_0xxx_w)
57   AM_RANGE( 0x1000, 0x1FFF ) AM_READ_BANK("bank_1xxx") AM_WRITE(bank_1xxx_w)
58   AM_RANGE( 0x2000, 0x3FFF ) AM_READWRITE(bank_2xxx_3xxx_r, bank_2xxx_3xxx_w)
5859   AM_RANGE( 0x4000, 0xEFFF ) AM_RAM
59   AM_RANGE( 0xF000, 0xFFFF ) AM_READ_BANK("bank3") AM_WRITE( osborne1_videoram_w )
60   AM_RANGE( 0xF000, 0xFFFF ) AM_READ_BANK("bank_fxxx") AM_WRITE(videoram_w)
6061ADDRESS_MAP_END
6162
6263
64static ADDRESS_MAP_START( osborne1_op, AS_DECRYPTED_OPCODES, 8, osborne1_state )
65   AM_RANGE( 0x0000, 0xFFFF ) AM_READ(opcode_r)
66ADDRESS_MAP_END
67
68
6369static ADDRESS_MAP_START( osborne1_io, AS_IO, 8, osborne1_state )
6470   ADDRESS_MAP_UNMAP_HIGH
6571   ADDRESS_MAP_GLOBAL_MASK(0xff)
66   AM_RANGE( 0x00, 0xff ) AM_WRITE( osborne1_bankswitch_w )
72   AM_RANGE( 0x00, 0xff ) AM_WRITE(bankswitch_w)
6773ADDRESS_MAP_END
6874
6975
7076static INPUT_PORTS_START( osborne1 )
7177   PORT_START("ROW0")
72   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH)   PORT_CHAR('[') PORT_CHAR(']')
78   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH)    PORT_CHAR('[') PORT_CHAR(']')
7379   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE)   PORT_CHAR('\'') PORT_CHAR('"')
7480   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13)
7581   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT)       PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
7682   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED)
77   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL)     PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
83   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_SHIFT_2)
7884   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB)          PORT_CHAR('\t')
7985   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC)          PORT_CHAR(UCHAR_MAMEKEY(ESC))
8086
r249959r249960
150156   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
151157   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
152158
159   PORT_START("RESET")
160   PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RESET") PORT_CODE(KEYCODE_F12)
161   PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED)
162   PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED)
163   PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
164   PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED)
165   PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED)
166   PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
167   PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED)
168
153169   PORT_START("CNF")
154170   PORT_CONFNAME(0x01, 0x00, "Video Output")
155171   PORT_CONFSETTING(0x00, "Standard")
r249959r249960
157173INPUT_PORTS_END
158174
159175
160static const z80_daisy_config osborne1_daisy_chain[] =
161{
162/*  { osborne1_z80_reset, osborne1_z80_irq_state, osborne1_z80_irq_ack, osborne1_z80_irq_reti, 0 }, */
163   { "osborne1_daisy" },
164   { NULL }
165};
166
167
168176/*
169177 * The Osborne-1 supports the following disc formats:
170178 * - Osborne single density: 40 tracks, 10 sectors per track, 256-byte sectors (100 KByte)
r249959r249960
176184 */
177185
178186static SLOT_INTERFACE_START( osborne1_floppies )
179   SLOT_INTERFACE( "525sssd", FLOPPY_525_SSSD ) // Siemens FDD 100-5, custom Osborne electronics
180   SLOT_INTERFACE( "525ssdd", FLOPPY_525_SSDD ) // MPI 52(?), custom Osborne electronics
187   SLOT_INTERFACE("525sssd", FLOPPY_525_SSSD) // Siemens FDD 100-5, custom Osborne electronics
188   SLOT_INTERFACE("525ssdd", FLOPPY_525_SSDD) // MPI 52(?), custom Osborne electronics
181189SLOT_INTERFACE_END
182190
183191
184192/* F4 Character Displayer */
185193static const gfx_layout osborne1_charlayout =
186194{
187   8, 10,                  /* 8 x 10 characters */
188   128,                    /* 128 characters */
189   1,                  /* 1 bits per pixel */
190   { 0 },                  /* no bitplanes */
191   /* x offsets */
195   8, 10,              // 8 x 10 characters
196   128,                // 128 characters
197   1,                  // 1 bits per pixel
198   { 0 },              // no bitplanes
199   // x offsets
192200   { 0, 1, 2, 3, 4, 5, 6, 7 },
193   /* y offsets */
201   // y offsets
194202   { 0*128*8, 1*128*8, 2*128*8, 3*128*8, 4*128*8, 5*128*8, 6*128*8, 7*128*8, 8*128*8, 9*128*8 },
195   8                   /* every char takes 16 x 1 bytes */
203   8                   // every char takes 16 x 1 bytes
196204};
197205
198206static GFXDECODE_START( osborne1 )
199   GFXDECODE_ENTRY( "chargen", 0x0000, osborne1_charlayout, 0, 1 )
207   GFXDECODE_ENTRY("chargen", 0x0000, osborne1_charlayout, 0, 1)
200208GFXDECODE_END
201209
202210
203211static MACHINE_CONFIG_START( osborne1, osborne1_state )
204   MCFG_CPU_ADD( "maincpu", Z80, MAIN_CLOCK/4 )
205   MCFG_CPU_PROGRAM_MAP( osborne1_mem)
206   MCFG_CPU_IO_MAP( osborne1_io)
207   MCFG_CPU_CONFIG( osborne1_daisy_chain )
212   MCFG_CPU_ADD("maincpu", Z80, MAIN_CLOCK/4)
213   MCFG_CPU_PROGRAM_MAP(osborne1_mem)
214   MCFG_CPU_DECRYPTED_OPCODES_MAP(osborne1_op)
215   MCFG_CPU_IO_MAP(osborne1_io)
216   MCFG_Z80_SET_IRQACK_CALLBACK(WRITELINE(osborne1_state, irqack_w))
208217
209   MCFG_DEVICE_ADD( "osborne1_daisy", OSBORNE1_DAISY, 0 )
210
211218   MCFG_SCREEN_ADD("screen", RASTER)
212219   MCFG_SCREEN_UPDATE_DRIVER(osborne1_state, screen_update)
213220   MCFG_SCREEN_RAW_PARAMS( MAIN_CLOCK, 1024, 0, 104*8, 260, 0, 24*10 )
trunk/src/mame/includes/osborne1.h
r249959r249960
1111
1212#include "emu.h"
1313#include "cpu/z80/z80.h"
14#include "cpu/z80/z80daisy.h"
1514#include "sound/beep.h"
1615#include "machine/6821pia.h"
1716#include "machine/6850acia.h"
r249959r249960
3938      m_ieee(*this, IEEE488_TAG),
4039      m_floppy0(*this, "mb8877:0:525ssdd"),
4140      m_floppy1(*this, "mb8877:1:525ssdd"),
42      m_row0(*this, "ROW0"),
43      m_row1(*this, "ROW1"),
44      m_row2(*this, "ROW2"),
45      m_row3(*this, "ROW3"),
46      m_row4(*this, "ROW4"),
47      m_row5(*this, "ROW5"),
48      m_row6(*this, "ROW6"),
49      m_row7(*this, "ROW7"),
41      m_keyb_row0(*this, "ROW0"),
42      m_keyb_row1(*this, "ROW1"),
43      m_keyb_row2(*this, "ROW2"),
44      m_keyb_row3(*this, "ROW3"),
45      m_keyb_row4(*this, "ROW4"),
46      m_keyb_row5(*this, "ROW5"),
47      m_keyb_row6(*this, "ROW6"),
48      m_keyb_row7(*this, "ROW7"),
49      m_btn_reset(*this, "RESET"),
5050      m_cnf(*this, "CNF"),
51      m_bank1(*this, "bank1"),
52      m_bank2(*this, "bank2"),
53      m_bank3(*this, "bank3"),
51      m_bank_0xxx(*this, "bank_0xxx"),
52      m_bank_1xxx(*this, "bank_1xxx"),
53      m_bank_fxxx(*this, "bank_fxxx"),
5454      m_region_maincpu(*this, "maincpu") { }
5555
5656   virtual void video_start();
r249959r249960
6969   required_device<floppy_image_device> m_floppy0;
7070   required_device<floppy_image_device> m_floppy1;
7171
72   DECLARE_WRITE8_MEMBER(osborne1_0000_w);
73   DECLARE_WRITE8_MEMBER(osborne1_1000_w);
74   DECLARE_READ8_MEMBER(osborne1_2000_r);
75   DECLARE_WRITE8_MEMBER(osborne1_2000_w);
76   DECLARE_WRITE8_MEMBER(osborne1_videoram_w);
77   DECLARE_WRITE8_MEMBER(osborne1_bankswitch_w);
78   DECLARE_WRITE_LINE_MEMBER(ieee_pia_irq_a_func);
72   DECLARE_WRITE8_MEMBER(bank_0xxx_w);
73   DECLARE_WRITE8_MEMBER(bank_1xxx_w);
74   DECLARE_READ8_MEMBER(bank_2xxx_3xxx_r);
75   DECLARE_WRITE8_MEMBER(bank_2xxx_3xxx_w);
76   DECLARE_WRITE8_MEMBER(videoram_w);
77   DECLARE_READ8_MEMBER(opcode_r);
78   DECLARE_WRITE8_MEMBER(bankswitch_w);
79   DECLARE_WRITE_LINE_MEMBER(irqack_w);
80
7981   DECLARE_READ8_MEMBER(ieee_pia_pb_r);
8082   DECLARE_WRITE8_MEMBER(ieee_pia_pb_w);
81   DECLARE_WRITE_LINE_MEMBER(video_pia_out_cb2_dummy);
83   DECLARE_WRITE_LINE_MEMBER(ieee_pia_irq_a_func);
84
8285   DECLARE_WRITE8_MEMBER(video_pia_port_a_w);
8386   DECLARE_WRITE8_MEMBER(video_pia_port_b_w);
87   DECLARE_WRITE_LINE_MEMBER(video_pia_out_cb2_dummy);
8488   DECLARE_WRITE_LINE_MEMBER(video_pia_irq_a_func);
85   DECLARE_DIRECT_UPDATE_MEMBER(osborne1_opbase);
8689
87   bool m_bank2_enabled;
88   UINT8   m_bit_9;
89   /* IRQ states */
90   bool m_pia_0_irq_state;
91   bool m_pia_1_irq_state;
9290   /* video related */
9391   UINT8   m_screen_pac;
9492   UINT8   m_resolution;
r249959r249960
9795   UINT8   m_new_start_y;
9896   emu_timer *m_video_timer;
9997   UINT8   *m_p_chargen;
100   /* bankswitch setting */
101   UINT8   m_bankswitch;
102   bool m_in_irq_handler;
10398   bool m_beep_state;
10499   DECLARE_DRIVER_INIT(osborne1);
105100   virtual void machine_reset();
r249959r249960
107102   TIMER_CALLBACK_MEMBER(setup_osborne1);
108103
109104protected:
110   required_ioport m_row0;
111   required_ioport m_row1;
112   required_ioport m_row2;
113   required_ioport m_row3;
114   required_ioport m_row4;
115   required_ioport m_row5;
116   required_ioport m_row6;
117   required_ioport m_row7;
105   required_ioport m_keyb_row0;
106   required_ioport m_keyb_row1;
107   required_ioport m_keyb_row2;
108   required_ioport m_keyb_row3;
109   required_ioport m_keyb_row4;
110   required_ioport m_keyb_row5;
111   required_ioport m_keyb_row6;
112   required_ioport m_keyb_row7;
113   required_ioport m_btn_reset;
114
118115   required_ioport m_cnf;
119   required_memory_bank m_bank1;
120   required_memory_bank m_bank2;
121   required_memory_bank m_bank3;
122   required_memory_region m_region_maincpu;
123116
124   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
125};
117   required_memory_bank m_bank_0xxx;
118   required_memory_bank m_bank_1xxx;
119   required_memory_bank m_bank_fxxx;
126120
121   required_memory_region m_region_maincpu;
127122
128// ======================> osborne1_daisy_device
123   // bank switch control bits
124   UINT8   m_ub4a_q;
125   UINT8   m_ub6a_q;
126   UINT8   m_rom_mode;
127   UINT8   m_bit_9;
129128
130class osborne1_daisy_device :   public device_t,
131                  public device_z80daisy_interface
132{
133public:
134   // construction/destruction
135   osborne1_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
129   bool set_rom_mode(UINT8 value);
130   bool set_bit_9(UINT8 value);
131   void update_irq();
136132
137private:
138   virtual void device_start();
139   // z80daisy_interface overrides
140   virtual int z80daisy_irq_state();
141   virtual int z80daisy_irq_ack();
142   virtual void z80daisy_irq_reti();
133   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
143134};
144135
145extern const device_type OSBORNE1_DAISY;
146
147136#endif /* OSBORNE1_H_ */
trunk/src/mame/machine/osborne1.c
r249959r249960
33/***************************************************************************
44
55There are three IRQ sources:
6- IRQ0
6- IRQ0 = IRQ from the serial ACIA
77- IRQ1 = IRQA from the video PIA
88- IRQ2 = IRQA from the IEEE488 PIA
99
10Interrupt handling on the Osborne-1 is a bit awkward. When an interrupt is
11taken by the Z80 the ROMMODE is enabled on each fetch of an instruction
12byte. During execution of an instruction the previous ROMMODE setting seems
13to be used. Side effect of this is that when an interrupt is taken and the
14stack pointer is pointing to 0000-3FFF then the return address will still
15be written to RAM if RAM was switched in.
16
1710***************************************************************************/
1811
1912#include "includes/osborne1.h"
2013
21#define RAMMODE     (0x01)
2214
23
24WRITE8_MEMBER( osborne1_state::osborne1_0000_w )
15WRITE8_MEMBER( osborne1_state::bank_0xxx_w )
2516{
26   /* Check whether regular RAM is enabled */
27   if ( !m_bank2_enabled || ( m_in_irq_handler && m_bankswitch == RAMMODE) )
28   {
29      m_ram->pointer()[ offset ] = data;
30   }
17   if (!m_rom_mode)
18      m_ram->pointer()[offset] = data;
3119}
3220
33
34WRITE8_MEMBER( osborne1_state::osborne1_1000_w )
21WRITE8_MEMBER( osborne1_state::bank_1xxx_w )
3522{
36   /* Check whether regular RAM is enabled */
37   if ( !m_bank2_enabled || ( m_in_irq_handler && m_bankswitch == RAMMODE) )
38   {
39      m_ram->pointer()[ 0x1000 + offset ] = data;
40   }
23   if (!m_rom_mode)
24      m_ram->pointer()[0x1000 + offset] = data;
4125}
4226
43
44READ8_MEMBER( osborne1_state::osborne1_2000_r )
27READ8_MEMBER( osborne1_state::bank_2xxx_3xxx_r )
4528{
46   UINT8   data = 0xFF;
29   if (!m_rom_mode)
30      return m_ram->pointer()[0x2000 + offset];
4731
48   /* Check whether regular RAM is enabled */
49   if ( !m_bank2_enabled )
32   // This isn't really accurate - bus fighting will occur for many values
33   // since each peripheral only checks two bits.  We just return 0xFF for
34   // any undocumented address.
35   UINT8   data = 0xFF;
36   switch (offset & 0x0F00)
5037   {
51      data = m_ram->pointer()[ 0x2000 + offset ];
38   case 0x100: /* Floppy */
39      data = m_fdc->read(space, offset & 0x03);
40      break;
41   case 0x200: /* Keyboard */
42      if (offset & 0x01)  data &= m_keyb_row0->read();
43      if (offset & 0x02)  data &= m_keyb_row1->read();
44      if (offset & 0x04)  data &= m_keyb_row3->read();
45      if (offset & 0x08)  data &= m_keyb_row4->read();
46      if (offset & 0x10)  data &= m_keyb_row5->read();
47      if (offset & 0x20)  data &= m_keyb_row2->read();
48      if (offset & 0x40)  data &= m_keyb_row6->read();
49      if (offset & 0x80)  data &= m_keyb_row7->read();
50      break;
51   case 0x400: /* SCREEN-PAC */
52      if (m_screen_pac) data &= 0xFB;
53      break;
54   case 0x900: /* IEEE488 PIA */
55      data = m_pia0->read(space, offset & 0x03);
56      break;
57   case 0xA00: /* Serial */
58      break;
59   case 0xC00: /* Video PIA */
60      data = m_pia1->read(space, offset & 0x03);
61      break;
5262   }
53   else
54   {
55      // This isn't really accurate - bus fighting will occur for many values
56      // since each peripheral only checks two bits.  We just return 0xFF for
57      // any undocumented address.
58      switch ( offset & 0x0F00 )
59      {
60      case 0x100: /* Floppy */
61         data = m_fdc->read( space, offset & 0x03 );
62         break;
63      case 0x200: /* Keyboard */
64         /* Row 0 */
65         if ( offset & 0x01 )    data &= m_row0->read();
66         /* Row 1 */
67         if ( offset & 0x02 )    data &= m_row1->read();
68         /* Row 2 */
69         if ( offset & 0x04 )    data &= m_row3->read();
70         /* Row 3 */
71         if ( offset & 0x08 )    data &= m_row4->read();
72         /* Row 4 */
73         if ( offset & 0x10 )    data &= m_row5->read();
74         /* Row 5 */
75         if ( offset & 0x20 )    data &= m_row2->read();
76         /* Row 6 */
77         if ( offset & 0x40 )    data &= m_row6->read();
78         /* Row 7 */
79         if ( offset & 0x80 )    data &= m_row7->read();
80         break;
81      case 0x400: /* SCREEN-PAC */
82         if (m_screen_pac) data &= 0xFB;
83         break;
84      case 0x900: /* IEEE488 PIA */
85         data = m_pia0->read(space, offset & 0x03);
86         break;
87      case 0xA00: /* Serial */
88         break;
89      case 0xC00: /* Video PIA */
90         data = m_pia1->read(space, offset & 0x03);
91         break;
92      }
93   }
9463   return data;
9564}
9665
97
98WRITE8_MEMBER( osborne1_state::osborne1_2000_w )
66WRITE8_MEMBER( osborne1_state::bank_2xxx_3xxx_w )
9967{
100#if 0
101   /* Check whether regular RAM is enabled */
102   if ( !m_bank2_enabled ||  (m_in_irq_handler && m_bankswitch == RAMMODE) )
68   if (!m_rom_mode)
10369   {
104      m_ram->pointer()[ 0x2000 + offset ] = data;
70      m_ram->pointer()[0x2000 + offset] = data;
10571   }
10672   else
10773   {
108      /* Handle writes to the I/O area */
109      if ( 0x100 == (offset & 0x900) ) /* Floppy */
74      // Handle writes to the I/O area
75      if ((offset & 0x900) == 0x100) // Floppy
11076         m_fdc->write(space, offset & 0x03, data);
111      if ( 0x400 == (offset & 0xC00) ) /* SCREEN-PAC */
112      {
113         m_resolution = data & 0x01;
114         m_hc_left = (data >> 1) & 0x01;
115      }
116      if ( 0x900 == (offset & 0x900) ) /* IEEE488 PIA */
77      if ((offset & 0x900) == 0x900) // IEEE488 PIA
11778         m_pia0->write(space, offset & 0x03, data);
118      if ( 0xA00 == (offset & 0xA00) ) /* Serial */
79      if ((offset & 0xA00) == 0xA00) // Serial
11980         /* not implemented */;
120      if ( 0xC00 == (offset & 0xC00) ) /* Video PIA */
121         m_pia1->write(space, offset & 0x03, data);
122   }
123#else
124   // This code is a nasty hack that doesn't reflect hardware operation,
125   // but it gets us by while the bank selection implementation is inadequate
126   if ( ! m_bank2_enabled )
127   {
128      m_ram->pointer()[ 0x2000 + offset ] = data;
129   }
130   else
131   {
132      if ( m_in_irq_handler && m_bankswitch == RAMMODE )
81      if ((offset & 0xC00) == 0x400) // SCREEN-PAC
13382      {
134         m_ram->pointer()[ 0x2000 + offset ] = data;
135      }
136      /* Handle writes to the I/O area */
137      switch( offset & 0x1F00 )
138      {
139      case 0x100: /* Floppy */
140         m_fdc->write(space, offset & 0x03, data);
141         break;
142      case 0x400: /* SCREEN-PAC */
14383         m_resolution = data & 0x01;
14484         m_hc_left = (data >> 1) & 0x01;
145         break;
146      case 0x900: /* IEEE488 PIA */
147         m_pia0->write(space, offset & 0x03, data );
148         break;
149      case 0xA00: /* Serial */
150         break;
151      case 0xC00: /* Video PIA */
152         m_pia1->write(space, offset & 0x03, data );
153         break;
15485      }
86      if ((offset & 0xC00) == 0xC00) // Video PIA
87         m_pia1->write(space, offset & 0x03, data);
15588   }
156#endif
15789}
15890
91WRITE8_MEMBER( osborne1_state::videoram_w )
92{
93   // Attribute RAM is only one bit wide - low seven bits are discarded and read back high
94   if (m_bit_9) data |= 0x7F;
95   reinterpret_cast<UINT8 *>(m_bank_fxxx->base())[offset] = data;
96}
15997
160WRITE8_MEMBER( osborne1_state::osborne1_videoram_w )
98READ8_MEMBER( osborne1_state::opcode_r )
16199{
162   /* Check whether the video attribute section is enabled */
163   if ( m_bit_9 )
164      data |= 0x7F;
100   // Update the flipflops that control bank selection and NMI
101   UINT8 const new_ub6a_q = (m_btn_reset->read() & 0x80) ? 1 : 0;
102   if (!m_rom_mode)
103   {
104      set_rom_mode(m_ub4a_q ? 0 : 1);
105      m_ub4a_q = m_ub6a_q;
106   }
107   m_ub6a_q = new_ub6a_q;
108   m_maincpu->set_input_line(INPUT_LINE_NMI, m_ub6a_q ? CLEAR_LINE : ASSERT_LINE);
165109
166   reinterpret_cast<UINT8 *>(m_bank3->base())[offset] = data;
110   // Now that's sorted out we can call the normal read handler
111   return m_maincpu->space(AS_PROGRAM).read_byte(offset);
167112}
168113
169
170WRITE8_MEMBER( osborne1_state::osborne1_bankswitch_w )
114WRITE8_MEMBER( osborne1_state::bankswitch_w )
171115{
172   switch ( offset & 0x03 )
116   switch (offset & 0x03)
173117   {
174118   case 0x00:
175      m_bank2_enabled = 1;
176      m_bankswitch = 0x00;
119      if (set_rom_mode(1))
120         m_ub4a_q = m_ub6a_q;
177121      break;
178122   case 0x01:
179      m_bank2_enabled = 0;
180      m_bankswitch = 0x01;
123      m_ub4a_q = 1;
124      m_ub6a_q = 1;
125      set_rom_mode(0);
126      m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
181127      break;
182128   case 0x02:
183      m_bit_9 = 1;
129      set_bit_9(1);
184130      break;
185131   case 0x03:
186      m_bit_9 = 0;
132      set_bit_9(0);
187133      break;
188134   }
189   if ( m_bank2_enabled )
190   {
191      m_bank1->set_base(m_region_maincpu->base());
192      m_bank2->set_base(m_region_maincpu->base());
193   }
194   else
195   {
196      m_bank1->set_base(m_ram->pointer());
197      m_bank2->set_base(m_ram->pointer() + 0x1000);
198   }
199   m_bank3->set_base(m_ram->pointer() + (m_bit_9 ? 0x10000 : 0xF000));
200   m_in_irq_handler = 0;
201135}
202136
203
204DIRECT_UPDATE_MEMBER(osborne1_state::osborne1_opbase)
137WRITE_LINE_MEMBER( osborne1_state::irqack_w )
205138{
206   if ( ( address & 0xF000 ) == 0x2000 )
207   {
208      if ( ! m_bank2_enabled )
209      {
210         direct.explicit_configure(0x2000, 0x2fff, 0x0fff, m_ram->pointer() + 0x2000);
211         return ~0;
212      }
213   }
214   return address;
139   // Update the flipflops that control bank selection and NMI
140   if (!m_rom_mode) set_rom_mode(m_ub4a_q ? 0 : 1);
141   m_ub4a_q = 0;
142   m_ub6a_q = (m_btn_reset->read() & 0x80) ? 1 : 0;
143   m_maincpu->set_input_line(INPUT_LINE_NMI, m_ub6a_q ? CLEAR_LINE : ASSERT_LINE);
215144}
216145
217146
218WRITE_LINE_MEMBER( osborne1_state::ieee_pia_irq_a_func )
219{
220   m_pia_0_irq_state = state;
221   m_maincpu->set_input_line(0, ( m_pia_1_irq_state ) ? ASSERT_LINE : CLEAR_LINE);
222}
223
224
225147READ8_MEMBER( osborne1_state::ieee_pia_pb_r )
226148{
227149   /*
228
229150       bit     description
230151
231152       0
r249959r249960
236157       5       DAV
237158       6       NDAC
238159       7       NRFD
239
240160   */
241
242161   UINT8 data = 0;
243162
244163   data |= m_ieee->eoi_r() << 3;
r249959r249960
249168   return data;
250169}
251170
252
253171WRITE8_MEMBER( osborne1_state::ieee_pia_pb_w )
254172{
255173   /*
256
257174       bit     description
258175
259176       0
r249959r249960
264181       5       DAV
265182       6       NDAC
266183       7       NRFD
267
268184   */
269
270185   m_ieee->eoi_w(BIT(data, 3));
271186   m_ieee->atn_w(BIT(data, 4));
272187   m_ieee->dav_w(BIT(data, 5));
r249959r249960
274189   m_ieee->nrfd_w(BIT(data, 7));
275190}
276191
192WRITE_LINE_MEMBER( osborne1_state::ieee_pia_irq_a_func )
193{
194   update_irq();
195}
277196
197
278198WRITE_LINE_MEMBER( osborne1_state::video_pia_out_cb2_dummy )
279199{
280200}
281201
282
283202WRITE8_MEMBER( osborne1_state::video_pia_port_a_w )
284203{
285204   m_fdc->dden_w(BIT(data, 0));
r249959r249960
293212   //logerror("Video pia port a write: %02X, density set to %s\n", data, data & 1 ? "FM" : "MFM" );
294213}
295214
296
297215WRITE8_MEMBER( osborne1_state::video_pia_port_b_w )
298216{
299217   m_new_start_y = data & 0x1F;
r249959r249960
317235   //logerror("Video pia port b write: %02X\n", data );
318236}
319237
320
321238WRITE_LINE_MEMBER( osborne1_state::video_pia_irq_a_func )
322239{
323   m_pia_1_irq_state = state;
324   m_maincpu->set_input_line(0, ( m_pia_1_irq_state ) ? ASSERT_LINE : CLEAR_LINE);
240   update_irq();
325241}
326242
327243
r249959r249960
357273TIMER_CALLBACK_MEMBER(osborne1_state::osborne1_video_callback)
358274{
359275   int const y = machine().first_screen()->vpos();
360   UINT8 ra=0;
276   UINT8 ra = 0;
361277
362   /* Check for start of frame */
363   if ( y == 0 )
364   {
365      /* Clear CA1 on video PIA */
278   // Check for start/end of visible area and clear/set CA1 on video PIA
279   if (y == 0)
366280      m_pia1->ca1_w(0);
367   }
368   if ( y == 240 )
369   {
370      /* Set CA1 on video PIA */
281   else if (y == 240)
371282      m_pia1->ca1_w(1);
372   }
373   if ( y < 240 )
283
284   if (y < 240)
374285   {
375286      ra = y % 10;
376      /* Draw a line of the display */
287      // Draw a line of the display
377288      bool const hires = m_screen_pac & m_resolution;
378289      UINT16 const row = (m_new_start_y + (y/10)) * 128 & 0xF80;
379290      UINT16 const col = (m_new_start_x & (hires ? 0x60 : 0x7F)) - ((hires && m_hc_left) ? 8 : 0);
r249959r249960
382293      for ( UINT16 x = 0; x < (hires ? 104 : 52); x++ )
383294      {
384295         UINT16 offs = row | ((col + x) & 0x7F);
385         UINT8 const chr = m_ram->pointer()[ 0xF000 + offs ];
386         UINT8 const dim = m_ram->pointer()[ 0x10000 + offs ] & 0x80;
296         UINT8 const chr = m_ram->pointer()[0xF000 + offs];
297         UINT8 const dim = m_ram->pointer()[0x10000 + offs] & 0x80;
387298
388         UINT8 const gfx = ((chr & 0x80) && (ra == 9)) ? 0xFF : m_p_chargen[ (ra << 7) | (chr & 0x7F) ];
299         UINT8 const gfx = ((chr & 0x80) && (ra == 9)) ? 0xFF : m_p_chargen[(ra << 7) | (chr & 0x7F)];
389300
390         /* Display a scanline of a character */
301         // Display a scanline of a character
391302         *p++ = BIT(gfx, 7) ? ( dim ? 2 : 1 ) : 0;
392303         if (!hires) { p[0] = p[-1]; p++; }
393304         *p++ = BIT(gfx, 6) ? ( dim ? 2 : 1 ) : 0;
r249959r249960
407318      }
408319   }
409320
410   if ( (ra==2) || (ra==6) )
411   {
412      m_beep->set_state( m_beep_state );
413   }
321   if ((ra == 2) || (ra == 6))
322      m_beep->set_state(m_beep_state);
414323   else
415   {
416      m_beep->set_state( 0 );
417   }
324      m_beep->set_state(0);
418325
419   m_video_timer->adjust(machine().first_screen()->time_until_pos(y + 1, 0 ));
326   // Check reset key if necessary - it affects NMI
327   if (!m_ub6a_q)
328      m_maincpu->set_input_line(INPUT_LINE_NMI, (m_btn_reset->read() && 0x80) ? CLEAR_LINE : ASSERT_LINE);
329
330   m_video_timer->adjust(machine().first_screen()->time_until_pos(y + 1, 0));
420331}
421332
422333TIMER_CALLBACK_MEMBER(osborne1_state::setup_osborne1)
r249959r249960
428339
429340void osborne1_state::machine_reset()
430341{
431   /* Initialize memory configuration */
432   osborne1_bankswitch_w( m_maincpu->space(AS_IO), 0x00, 0 );
342   // Initialize memory configuration
343   m_rom_mode = 0;
344   m_bit_9 = 1;
345   set_rom_mode(1);
346   set_bit_9(0);
433347
434   m_pia_0_irq_state = FALSE;
435   m_pia_1_irq_state = FALSE;
436   m_in_irq_handler = 0;
437
438348   m_screen_pac = 0 != (m_cnf->read() & 0x01);
439349   m_resolution = 0;
440350   m_hc_left = 0;
441351   m_p_chargen = memregion( "chargen" )->base();
442352
443   memset( m_ram->pointer() + 0x10000, 0xFF, 0x1000 );
444
445   address_space& space = m_maincpu->space(AS_PROGRAM);
446   space.set_direct_update_handler(direct_update_delegate(FUNC(osborne1_state::osborne1_opbase), this));
353   memset(m_ram->pointer() + 0x10000, 0xFF, 0x1000);
447354}
448355
449356
r249959r249960
452359   /* Configure the 6850 ACIA */
453360//  acia6850_config( 0, &osborne1_6850_config );
454361   m_video_timer = timer_alloc(TIMER_VIDEO);
455   m_video_timer->adjust(machine().first_screen()->time_until_pos(1, 0 ));
362   m_video_timer->adjust(machine().first_screen()->time_until_pos(1, 0));
456363
457364   timer_set(attotime::zero, TIMER_SETUP);
458365}
r249959r249960
463370   machine().first_screen()->register_screen_bitmap(m_bitmap);
464371}
465372
373
466374UINT32 osborne1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
467375{
468376   copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
469377   return 0;
470378}
471379
472/****************************************************************
473    Osborne1 specific daisy chain code
474****************************************************************/
475380
476const device_type OSBORNE1_DAISY = &device_creator<osborne1_daisy_device>;
477
478//**************************************************************************
479//  LIVE DEVICE
480//**************************************************************************
481
482//-------------------------------------------------
483//  z80ctc_device - constructor
484//-------------------------------------------------
485osborne1_daisy_device::osborne1_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
486   : device_t(mconfig, OSBORNE1_DAISY, "Osborne 1 daisy", tag, owner, clock, "osborne1_daisy", __FILE__),
487      device_z80daisy_interface(mconfig, *this)
381bool osborne1_state::set_rom_mode(UINT8 value)
488382{
383   if (value != m_rom_mode)
384   {
385      m_rom_mode = value;
386      if (m_rom_mode)
387      {
388         m_bank_0xxx->set_base(m_region_maincpu->base());
389         m_bank_1xxx->set_base(m_region_maincpu->base());
390      }
391      else
392      {
393         m_bank_0xxx->set_base(m_ram->pointer());
394         m_bank_1xxx->set_base(m_ram->pointer() + 0x1000);
395      }
396      return true;
397   }
398   else
399   {
400      return false;
401   }
489402}
490403
491//-------------------------------------------------
492//  device_start - device-specific startup
493//-------------------------------------------------
494
495void osborne1_daisy_device::device_start()
404bool osborne1_state::set_bit_9(UINT8 value)
496405{
406   if (value != m_bit_9)
407   {
408      m_bit_9 = value;
409      m_bank_fxxx->set_base(m_ram->pointer() + (m_bit_9 ? 0x10000 : 0xF000));
410      return true;
411   }
412   else
413   {
414      return false;
415   }
497416}
498417
499//**************************************************************************
500//  DAISY CHAIN INTERFACE
501//**************************************************************************
502
503//-------------------------------------------------
504//  z80daisy_irq_state - return the overall IRQ
505//  state for this device
506//-------------------------------------------------
507
508int osborne1_daisy_device::z80daisy_irq_state()
418void osborne1_state::update_irq()
509419{
510   osborne1_state *state = machine().driver_data<osborne1_state>();
511   return ( state->m_pia_1_irq_state ? Z80_DAISY_INT : 0 );
420   if (m_pia0->irq_a_state())
421      m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0xF0);
422   else if (m_pia1->irq_a_state())
423      m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0xF8);
424   else
425      m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, CLEAR_LINE, 0xFE);
512426}
513
514
515//-------------------------------------------------
516//  z80daisy_irq_ack - acknowledge an IRQ and
517//  return the appropriate vector
518//-------------------------------------------------
519
520int osborne1_daisy_device::z80daisy_irq_ack()
521{
522   osborne1_state *state = machine().driver_data<osborne1_state>();
523   /* Enable ROM and I/O when IRQ is acknowledged */
524   UINT8 old_bankswitch = state->m_bankswitch;
525
526   state->osborne1_bankswitch_w( state->m_maincpu->space(AS_IO), 0, 0 );
527   state->m_bankswitch = old_bankswitch;
528   state->m_in_irq_handler = 1;
529   return 0xF8;
530}
531
532//-------------------------------------------------
533//  z80daisy_irq_reti - clear the interrupt
534//  pending state to allow other interrupts through
535//-------------------------------------------------
536
537void osborne1_daisy_device::z80daisy_irq_reti()
538{
539}


Previous 199869 Revisions Next


© 1997-2024 The MAME Team