summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/gic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/gic.cpp')
-rw-r--r--src/mame/video/gic.cpp324
1 files changed, 0 insertions, 324 deletions
diff --git a/src/mame/video/gic.cpp b/src/mame/video/gic.cpp
deleted file mode 100644
index 65deaf5b7f7..00000000000
--- a/src/mame/video/gic.cpp
+++ /dev/null
@@ -1,324 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:David Viens
-/***************************************************************************
-
- gic.c
-
- GI AY-3-8800-1 (Datasheet exists as AY-3-8500-1 Graphics Interface Chip)
- For the GIMINI "Challenger" programmable game system.
-
- Really only ever used in the Unisonic Champion 2711
-
- More LA tests made by plgDavid on hardware pretty much confirmed what is found
- in the AY-3-8950-1 datasheet, but with more fine grained detail.
-
- the GIC does not have internal ram of any sort apart from shift registers,
- instead it relies on the external shared ram, (see page 7-85) Appendix AY-3-8950-1
-
- Unverified on LA (since the video pins are all connected into a composite mix):
- at line 46 it lowers GIC_BUSY, until line 240
-
- Verified using LA:
- It will read the external ram areas continuously while GIC_BUSY is low (for 12.36ms)
-
- (NOTE: OCTAL)
-
- 000,001,002,003,004,005, 110,111,112,113,114,115,116,117,120,121,122,123,124,125 (15 times - No first bg line?)
- 006,007,010,011,012,013, 110,111,112,113,114,115,116,117,120,121,122,123,124,125 (16 times)
-
- 014,015,016,017,020,021, 125,126,127,130,131,132,133,134,135,136,137,140,141,142 (16 times)
- 022,023,024,025,026,027, 125,126,127,130,131,132,133,134,135,136,137,140,141,142 (16 times)
-
- 030,031,032,033,034,035, 142,143,144,145,146,147,150,151,152,153,154,155,156,157 (16 times)
- 036,037,040,041,042,043, 142,143,144,145,146,147,150,151,152,153,154,155,156,157 (16 times)
-
- 044,045,046,047,050,051, 157,160,161,162,163,164,165,166,167,170,171,172,173,174 (16 times)
- 052,053,054,055,056,057, 157,160,161,162,163,164,165,166,167,170,171,172,173,174 (16 times)
-
- 060,061,062,063,064,065, 174,175,176,177,200,201,202,203,204,205,206,207,210,211 (16 times)
- 066,067,070,071,072,073, 174,175,176,177,200,201,202,203,204,205,206,207,210,211 (16 times)
-
- 074,075,076,077,100,101, 211,212,213,214,215,216,217,220,221,222,223,224,225,226 (16 times)
- 102,103,104,105,106,107, 211,212,213,214,215,216,217,220,221,222,223,224,225,226 (16 times)
-
- 000,001,002,003,004,005, 000,001,002,003,004,005,006,007,010,011,012,013,014,015 (once! padding?)
-
- for a total of (12*20*16) = 3840 RAM reads (3 clocks per read at 1.79MHz)
-
- Then it relinquishes control to the CPU by raising BUSREQ.
-
- Clocking in more detail: (in 1.79MHz clocks)
- boot:
- busy:1 5360 clocks
- busy:0 22116 clocks
- busy:1 7752 clocks
- busy:0 22116 clocks
- busy:1 7752 clocks
- (...)
-
- There are NO IRQ handshakes, just BUSREQ sync shared RAM
-
-***************************************************************************/
-
-#include "emu.h"
-#include "gic.h"
-#include "screen.h"
-
-// device type definition
-DEFINE_DEVICE_TYPE(GIC, gic_device, "gic", "AY-3-8800-1 GIC")
-
-
-//Font data taken from Paul Robson's simulator
-//http://worstconsole.blogspot.ca/2012/12/the-worstconsoleever.html
-//A real AY-3-8800-1 (dead) is going to decap for a good dump
-ROM_START( gic_font )
- ROM_REGION( 0x200, "cgrom", 0 )
- ROM_LOAD( "ay-3-8800-1.bin", 0x0000, 0x200, BAD_DUMP CRC(d9f11d2b) SHA1(60ef45d51d102cd3af78787008d9aed848137bee))
-ROM_END
-
-
-//-------------------------------------------------
-// gic_device - constructor
-//-------------------------------------------------
-
-gic_device::gic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : gic_device(mconfig, GIC, tag, owner, clock)
-{
-}
-
-
-gic_device::gic_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, type, tag, owner, clock)
- , device_sound_interface(mconfig, *this)
- , device_video_interface(mconfig, *this)
- , m_cgrom(*this, "cgrom")
- , m_audiocnt(0)
- , m_audioval(0)
- , m_audioreset(0)
- , m_ram(*this)
-{
-}
-
-const tiny_rom_entry *gic_device::device_rom_region() const
-{
- //there is only one... how do I get rid of this?
- return ROM_NAME( gic_font );
-}
-
-//-------------------------------------------------
-// device_start - device-specific startup
-//-------------------------------------------------
-
-void gic_device::device_start()
-{
- // Let the screen create our temporary bitmap with the screen's dimensions
- screen().register_screen_bitmap(m_bitmap);
-
- m_vblank_timer = timer_alloc(TIMER_VBLANK);
- m_vblank_timer->adjust( screen().time_until_pos(1, END_ACTIVE_SCAN + 18 ), 0, screen().scan_period() );
-
- // allocate the audio stream
- m_stream = stream_alloc( 0, 1, clock()/(2*228) );
-
- m_ram.resolve_safe(0xff);
-}
-
-
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void gic_device::device_reset()
-{
- m_audiocnt=0;
- m_audioval=0;
- m_audioreset=0;
-}
-
-#define GIC_CLUB 28
-#define GIC_SPACE 0
-
-void gic_device::draw_char_left(int startx, int starty, uint8_t code, bitmap_ind16 &bitmap){
- uint8_t*ptr = &m_cgrom[code*GIC_CHAR_H];
-
- for (size_t y=0;y<GIC_CHAR_H;y++){
- uint8_t current = *ptr++;
- uint8_t nextx=0;
- uint8_t curry= starty+y;
- for(uint8_t x=0x20;x!=0;x=x/2){
- if (current&x)
- m_bitmap.pix(curry,startx+nextx) = GIC_WHITE;
- nextx++;
- }
- }
-}
-
-void gic_device::draw_char_right(int startx, int starty, uint8_t code, bitmap_ind16 &bitmap, int bg_col){
- uint8_t*ptr = &m_cgrom[code*GIC_CHAR_H];
-
- for (size_t y=0;y<GIC_CHAR_H;y++){
- uint8_t current = *ptr++;
- uint8_t nextx=0;
- uint8_t curry= starty+y;
-
- m_bitmap.pix(curry,startx+nextx) = bg_col;
- nextx++;
- for(uint8_t x=0x20;x!=0;x=x/2){
- m_bitmap.pix(curry,startx+nextx) = (current&x)?GIC_WHITE:bg_col;
- nextx++;
- }
- m_bitmap.pix(curry,startx+nextx) = bg_col;
- nextx++;
- m_bitmap.pix(curry,startx+nextx) = bg_col;
- }
-}
-
-uint32_t gic_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
-{
- m_bitmap.fill(GIC_GREEN);
-
- size_t XSTART = BORDER_SIZE;
- size_t YSTART = START_ACTIVE_SCAN;
-
- //left hand side first
- uint8_t current=0;
- for(uint8_t cy=0;cy<GIC_LEFT_H;cy++){
- for(uint8_t cx=0;cx<GIC_LEFT_W;cx++){
- draw_char_left(XSTART+(cx*GIC_CHAR_W),
- YSTART+(cy*GIC_CHAR_H),
- m_ram(current),
- m_bitmap);
- current++;
- }
- }
-
- //right hand side is next
- current=0x48;//110 octal
- XSTART+=(GIC_LEFT_W*GIC_CHAR_W)+1;
-
- for(uint8_t cy=0;cy<GIC_RIGHT_H;cy++){
- for(uint8_t cx=0;cx<GIC_RIGHT_W;cx++){
- //complex case
- uint8_t data = m_ram(current++);
-
- size_t currX = (XSTART+ (cx*(3+GIC_CHAR_W)));
- size_t currUP = (YSTART+ (cy*(2*GIC_CHAR_H)));
- size_t currLOW = (YSTART+GIC_CHAR_H+(cy*(2*GIC_CHAR_H)));
-
- switch(data&0xC0){
- case 0x00:{
- //lower rectangle only, normal char
- draw_char_right(currX,currLOW,data,m_bitmap,GIC_GREEN);
- }break;
-
- //White block
- case 0xC0:{
- //upper rectangle
- draw_char_right(currX,currUP, GIC_SPACE,m_bitmap,GIC_WHITE);
- //lower rectangle
- draw_char_right(currX,currLOW,GIC_SPACE,m_bitmap,GIC_WHITE);
- }break;
-
- //Draw a card
- case 0x40:{
- int bgColor = (data&0x10)?GIC_RED:GIC_BLACK;
- //upper rectangle
- draw_char_right(currX,currUP, (data&0xF)+0x30,m_bitmap,bgColor);
- //lower rectangle
- draw_char_right(currX,currLOW,GIC_CLUB+((data&0x30)>>4),m_bitmap,bgColor);
- }break;
-
- default:printf("gic unknown char! %02X\n",data); break;
- }
- }
- }
-
- copybitmap( bitmap, m_bitmap, 0, 0, 0, 0, cliprect );
- return 0;
-}
-
-/* AUDIO SECTION */
-
-void gic_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch ( id )
- {
- case TIMER_VBLANK:
- //flag the audio to reset
- m_audioreset = 1;//phase need to reset! on next clock/228
- break;
- }
-}
-
-#define GIC_AUDIO_BYTE 0x96
-
-void gic_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
-{
- auto &buffer = outputs[0];
-
- //Audio is basic and badly implemented (doubt that was the intent)
- //The datasheet lists the 3 different frequencies the GIC can generate: 500,1000 and 2000Hz
- //but it is clear (for an audio guy at least) that the resulting spectrum
- //is not a pure square wave. In fact, the counter is reset on vertical sync!
- //http://twitter.com/plgDavid/status/527269086016077825
- //...thus creating a buzzing sound.
-
- //Dumping the audio pin value each time
- // either (PHI2 made a 0->1 transition (1.789MHz)
- // or (PHI1 made a 1->1 transition (1.789MHz)
- //I found that the granularity of audio transitions
- //(including phase resets and silences) was 228 clocks
- //The audio subsystem thus runs at 1.789MHz/228 = 7849.88Hz
-
- //when 1
- //normal period:912 clocks (228*4)
- //hi for 456 clocks
- //lo for 456 clocks
- //reset period: (each frame)
- //hi for 228 clocks
- //lo for 456 clocks
- //when 2
- //normal period lasts 1824 clocks (228*8)
- //hi for 912 clocks
- //lo for 912 clocks
- //reset period: (each frame)
- //hi for 912 (228*4)
- //lo for 1596 (228*7)
- //hi for 912 (228*4)
- //when 4
- //normal period lasts 3648 clocks (228*16)
- //hi for 1824(228*8)
- //lo for 1824(228*8)
- //Reset period:
- //lo for 1824(228*8)
- //hi for 2508(228*11)
- //lo for 1824(228*8)
- //hi for 1824(228*8)
-
- uint8_t audioByte = m_ram(GIC_AUDIO_BYTE)*2;
-
- if(!audioByte){
- buffer.fill(0);
-
- m_audioval = 0;
- m_audiocnt = 0;
- m_audioreset = 0;
- return;//early
- }
-
- //forced resynch @ 59.95Hz
- if(m_audioreset){
- m_audioval = 0;//forced low
- m_audiocnt = 0;
- m_audioreset = 0;
- }
-
- for(size_t i=0; i < buffer.samples(); i++){
- m_audiocnt++;
- if(m_audiocnt >= audioByte){
- m_audioval = !m_audioval;
- m_audiocnt=0;
- }
- buffer.put(i, m_audioval ? 1.0 : 0.0);
- }
-}