1 /*
2  *  KCemu -- The emulator for the KC85 homecomputer series and much more.
3  *  Copyright (C) 1997-2010 Torsten Paul
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include <iostream>
21 #include <iomanip>
22 
23 #include "kc/system.h"
24 
25 #include "kc/kc.h"
26 #include "kc/z80.h"
27 #include "kc/c80/display.h"
28 
29 #include "libdbg/dbg.h"
30 
DisplayC80(void)31 DisplayC80::DisplayC80(void)
32 {
33   _idx = 0;
34   _reset = true;
35 
36   for (int a = 0;a < C80_NR_OF_LEDS;a++)
37     _led_value[a] = 0;
38 }
39 
~DisplayC80(void)40 DisplayC80::~DisplayC80(void)
41 {
42 }
43 
44 byte_t
get_led_value(int idx)45 DisplayC80::get_led_value(int idx)
46 {
47   return _led_value[idx];
48 }
49 
50 void
callback(void * data)51 DisplayC80::callback(void *data)
52 {
53   long idx = (long)data;
54 
55   DBG(2, form("KCemu/DisplayC80/callback",
56               "DisplayC80::callback(): idx = %d\n",
57               idx));
58 
59   if ((idx > 0) && (idx < 9))
60     {
61       _led_value[idx - 1] = pio->in_B_DATA();
62 
63       DBG(2, form("KCemu/DisplayC80/callback",
64 		  "DisplayC80::callback(): LED: [%d] %02x %02x %02x %02x - %02x %02x %02x %02x\n",
65 		  idx - 1,
66 		  _led_value[7], _led_value[6], _led_value[5], _led_value[4],
67 		  _led_value[3], _led_value[2], _led_value[1], _led_value[0]));
68     }
69 
70   pio->set_A_EXT(0x10, 0x10);
71 }
72 
73 int
callback_A_in(void)74 DisplayC80::callback_A_in(void)
75 {
76   return -1;
77 }
78 
79 int
callback_B_in(void)80 DisplayC80::callback_B_in(void)
81 {
82   return -1;
83 }
84 
85 void
callback_A_out(byte_t val)86 DisplayC80::callback_A_out(byte_t val)
87 {
88   int a5 = (val >> 5) & 1;
89   DBG(2, form("KCemu/DisplayC80/out_A",
90               "DisplayC80::out_A(): val = %02x, A5 = %d\n",
91               val, a5));
92 
93   if (a5)
94     {
95       _idx = 0;
96       _reset = true;
97     }
98   else
99     {
100       _reset = false;
101     }
102 }
103 
104 void
callback_B_out(byte_t val)105 DisplayC80::callback_B_out(byte_t val)
106 {
107   DBG(2, form("KCemu/DisplayC80/out_B",
108               "DisplayC80::out_B(): val = %02x, idx = %d, reset = %d\n",
109               val, _idx, _reset));
110 
111   if (_reset)
112     return;
113 
114   _idx++;
115   z80->addCallback(C80_DISPLAY_CB_OFFSET, this, (void *)_idx);
116   pio->set_A_EXT(0x10, 0x00);
117   pio->strobe_B();
118 }
119