Lots of changes. Maybe for the better, maybe not.
This commit is contained in:
parent
aaee3363c4
commit
fc0606303b
|
@ -2,5 +2,21 @@
|
||||||
|
|
||||||
all: ay8910test
|
all: ay8910test
|
||||||
|
|
||||||
ay8910test: ay8910.c
|
ay8910test: ay8910.o sound.o sndintrf.o
|
||||||
gcc -o ay8910test ay8910.c
|
gcc -o ay8910test sound.o ay8910.o sndintrf.o -lSDL
|
||||||
|
|
||||||
|
ay8910.o: ay8910.c
|
||||||
|
gcc -c -Wall ay8910.c
|
||||||
|
|
||||||
|
sound.o: sound.c
|
||||||
|
gcc -c -Wall sound.c
|
||||||
|
|
||||||
|
#streams.o: streams.c
|
||||||
|
# gcc -c -Wall streams.c
|
||||||
|
|
||||||
|
sndintrf.o: sndintrf.c
|
||||||
|
gcc -c -Wall sndintrf.c
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY clean:
|
||||||
|
rm ay8910test *.o
|
||||||
|
|
|
@ -61,9 +61,9 @@
|
||||||
| |
|
| |
|
||||||
GND GND
|
GND GND
|
||||||
|
|
||||||
Each Volume level x will select a different resistor Rx. Measurements from fpgaarcade.com
|
Each Volume level x will select a different resistor Rx. Measurements from
|
||||||
where used to calibrate channel mixing for the YM2149. This was done using
|
fpgaarcade.com were used to calibrate channel mixing for the YM2149. This was
|
||||||
a least square approach using a fixed RL of 1K Ohm.
|
done using a least square approach using a fixed RL of 1K Ohm.
|
||||||
|
|
||||||
For the AY measurements cited in e.g. openmsx as "Hacker Kay" for a single
|
For the AY measurements cited in e.g. openmsx as "Hacker Kay" for a single
|
||||||
channel were taken. These were normalized to 0 ... 65535 and consequently
|
channel were taken. These were normalized to 0 ... 65535 and consequently
|
||||||
|
@ -73,14 +73,13 @@ line e.g. with the formula used by pcmenc for the volume: vol(i) = exp(i/2-7.5).
|
||||||
The following is documentation from the code moved here and amended to reflect
|
The following is documentation from the code moved here and amended to reflect
|
||||||
the changes done:
|
the changes done:
|
||||||
|
|
||||||
Careful studies of the chip output prove that the chip counts up from 0
|
Careful studies of the chip output prove that the chip counts up from 0 until
|
||||||
until the counter becomes greater or equal to the period. This is an
|
the counter becomes greater or equal to the period. This is an important
|
||||||
important difference when the program is rapidly changing the period to
|
difference when the program is rapidly changing the period to modulate the
|
||||||
modulate the sound. This is worthwhile noting, since the datasheets
|
sound. This is worthwhile noting, since the datasheets say, that the chip
|
||||||
say, that the chip counts down.
|
counts down. Also, note that period = 0 is the same as period = 1. This is
|
||||||
Also, note that period = 0 is the same as period = 1. This is mentioned
|
mentioned in the YM2203 data sheets. However, this does NOT apply to the
|
||||||
in the YM2203 data sheets. However, this does NOT apply to the Envelope
|
Envelope period. In that case, period = 0 is half as period = 1.
|
||||||
period. In that case, period = 0 is half as period = 1.
|
|
||||||
|
|
||||||
Envelope shapes:
|
Envelope shapes:
|
||||||
C AtAlH
|
C AtAlH
|
||||||
|
@ -99,20 +98,35 @@ The envelope counter on the AY-3-8910 has 16 steps. On the YM2149 it
|
||||||
has twice the steps, happening twice as fast.
|
has twice the steps, happening twice as fast.
|
||||||
|
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// MAME headers
|
||||||
|
/*
|
||||||
|
#include "osdcomm.h"
|
||||||
|
#include "mamecore.h"
|
||||||
|
#include "deprecat.h"
|
||||||
|
|
||||||
#include "sndintrf.h"
|
#include "sndintrf.h"
|
||||||
#include "deprecat.h"
|
//#include "deprecat.h"
|
||||||
#include "streams.h"
|
#include "streams.h"
|
||||||
//#include "cpuintrf.h"
|
#include "cpuintrf.h"
|
||||||
|
*/
|
||||||
|
#include "sndint.h"
|
||||||
#include "ay8910.h"
|
#include "ay8910.h"
|
||||||
|
|
||||||
// lazyness
|
// lazyness
|
||||||
#define logerror printf
|
#define logerror printf
|
||||||
|
|
||||||
|
/* pen_t is used to represent pixel values in bitmaps */
|
||||||
|
typedef UINT32 pen_t;
|
||||||
|
|
||||||
|
/* stream_sample_t is used to represent a single sample in a sound stream */
|
||||||
|
typedef INT32 stream_sample_t;
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
|
||||||
* Defines
|
* Defines
|
||||||
*
|
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
#define MAX_OUTPUT 0x7fff
|
#define MAX_OUTPUT 0x7fff
|
||||||
|
@ -145,8 +159,19 @@ has twice the steps, happening twice as fast.
|
||||||
#define TONE_ENVELOPE(_psg, _chan) (((_psg)->regs[AY_AVOL + (_chan)] >> 4) & 1)
|
#define TONE_ENVELOPE(_psg, _chan) (((_psg)->regs[AY_AVOL + (_chan)] >> 4) & 1)
|
||||||
#define ENVELOPE_PERIOD(_psg) (((_psg)->regs[AY_EFINE] | ((_psg)->regs[AY_ECOARSE]<<8)))
|
#define ENVELOPE_PERIOD(_psg) (((_psg)->regs[AY_EFINE] | ((_psg)->regs[AY_ECOARSE]<<8)))
|
||||||
|
|
||||||
/*************************************
|
|
||||||
*
|
|
||||||
|
// prototypes
|
||||||
|
extern int sdl_init(int samplerate);
|
||||||
|
extern int sdlaudio_init(int samplerate);
|
||||||
|
extern void sdl_kill();
|
||||||
|
extern int sdl_create_buffers(void);
|
||||||
|
extern void sdl_destroy_buffers(void);
|
||||||
|
extern void sdl_cleanup_audio(int samplerate);
|
||||||
|
extern void sdl_callback(void *userdata, Uint8 *stream, int len);
|
||||||
|
extern void osd_update_audio_stream(int samplerate, INT16 *b, int s);
|
||||||
|
|
||||||
|
/**************************************
|
||||||
* Type definitions
|
* Type definitions
|
||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
@ -166,7 +191,7 @@ struct _ay8910_context
|
||||||
int index;
|
int index;
|
||||||
int streams;
|
int streams;
|
||||||
int ready;
|
int ready;
|
||||||
sound_stream *channel;
|
//sound_stream *channel;
|
||||||
const ay8910_interface *intf;
|
const ay8910_interface *intf;
|
||||||
INT32 register_latch;
|
INT32 register_latch;
|
||||||
UINT8 regs[16];
|
UINT8 regs[16];
|
||||||
|
@ -216,7 +241,7 @@ static const ay_ym_param ym2149_param_env =
|
||||||
1397, 1123, 925, 762, 578, 438, 332, 251 },
|
1397, 1123, 925, 762, 578, 438, 332, 251 },
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
/* RL = 1000, Hacker Kay normalized, 2.1V to 3.2V */
|
/* RL = 1000, Hacker Kay normalized, 2.1V to 3.2V */
|
||||||
static const ay_ym_param ay8910_param =
|
static const ay_ym_param ay8910_param =
|
||||||
{
|
{
|
||||||
|
@ -270,6 +295,7 @@ static const ay_ym_param ay8910_param =
|
||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
|
|
||||||
INLINE void build_3D_table(double rl, const ay_ym_param *par, const ay_ym_param *par_env, int normalize, double factor, int zero_is_off, INT32 *tab)
|
INLINE void build_3D_table(double rl, const ay_ym_param *par, const ay_ym_param *par_env, int normalize, double factor, int zero_is_off, INT32 *tab)
|
||||||
{
|
{
|
||||||
int j, j1, j2, j3, e, indx;
|
int j, j1, j2, j3, e, indx;
|
||||||
|
@ -393,8 +419,7 @@ static void ay8910_write_reg(ay8910_context *psg, int r, int v)
|
||||||
//if (r >= 11 && r <= 13 ) printf("%d %x %02x\n", PSG->index, r, v);
|
//if (r >= 11 && r <= 13 ) printf("%d %x %02x\n", PSG->index, r, v);
|
||||||
psg->regs[r] = v;
|
psg->regs[r] = v;
|
||||||
|
|
||||||
switch( r )
|
switch ( r ) {
|
||||||
{
|
|
||||||
case AY_AFINE:
|
case AY_AFINE:
|
||||||
case AY_ACOARSE:
|
case AY_ACOARSE:
|
||||||
case AY_BFINE:
|
case AY_BFINE:
|
||||||
|
@ -628,7 +653,7 @@ static void build_mixer_table(ay8910_context *psg)
|
||||||
*/
|
*/
|
||||||
build_3D_table(psg->intf->res_load[0], psg->par, psg->par_env, normalize, 3, psg->zero_is_off, psg->vol3d_table);
|
build_3D_table(psg->intf->res_load[0], psg->par, psg->par_env, normalize, 3, psg->zero_is_off, psg->vol3d_table);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
static void ay8910_statesave(ay8910_context *psg, int sndindex)
|
static void ay8910_statesave(ay8910_context *psg, int sndindex)
|
||||||
{
|
{
|
||||||
state_save_register_item("AY8910", sndindex, psg->register_latch);
|
state_save_register_item("AY8910", sndindex, psg->register_latch);
|
||||||
|
@ -651,7 +676,7 @@ static void ay8910_statesave(ay8910_context *psg, int sndindex)
|
||||||
state_save_register_item("AY8910", sndindex, psg->holding);
|
state_save_register_item("AY8910", sndindex, psg->holding);
|
||||||
state_save_register_item("AY8910", sndindex, psg->rng);
|
state_save_register_item("AY8910", sndindex, psg->rng);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
* Public functions
|
* Public functions
|
||||||
|
@ -664,8 +689,8 @@ void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay891
|
||||||
{
|
{
|
||||||
ay8910_context *info;
|
ay8910_context *info;
|
||||||
|
|
||||||
info = (ay8910_context*) auto_malloc(sizeof(*info));
|
info = malloc(sizeof(ay8910_context));
|
||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(ay8910_context));
|
||||||
info->index = sndindex;
|
info->index = sndindex;
|
||||||
info->intf = intf;
|
info->intf = intf;
|
||||||
if ((info->intf->flags & AY8910_SINGLE_OUTPUT) != 0)
|
if ((info->intf->flags & AY8910_SINGLE_OUTPUT) != 0)
|
||||||
|
@ -710,7 +735,7 @@ void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay891
|
||||||
info->channel = stream_create(0,info->streams,clock / 8 ,info,ay8910_update);
|
info->channel = stream_create(0,info->streams,clock / 8 ,info,ay8910_update);
|
||||||
|
|
||||||
ay8910_set_clock_ym(info,clock);
|
ay8910_set_clock_ym(info,clock);
|
||||||
ay8910_statesave(info, sndindex);
|
//ay8910_statesave(info, sndindex);
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
@ -754,7 +779,7 @@ void ay8910_set_volume(int chip,int channel,int volume)
|
||||||
void ay8910_set_clock_ym(void *chip, int clock)
|
void ay8910_set_clock_ym(void *chip, int clock)
|
||||||
{
|
{
|
||||||
ay8910_context *psg = chip;
|
ay8910_context *psg = chip;
|
||||||
stream_set_sample_rate(psg->channel, clock / 8 );
|
//stream_set_sample_rate(psg->channel, clock / 8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ay8910_write_ym(void *chip, int addr, int data)
|
void ay8910_write_ym(void *chip, int addr, int data)
|
||||||
|
@ -769,7 +794,7 @@ void ay8910_write_ym(void *chip, int addr, int data)
|
||||||
if (r == AY_ESHAPE || psg->regs[r] != data)
|
if (r == AY_ESHAPE || psg->regs[r] != data)
|
||||||
{
|
{
|
||||||
/* update the output buffer before changing the register */
|
/* update the output buffer before changing the register */
|
||||||
stream_update(psg->channel);
|
//stream_update(psg->channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
ay8910_write_reg(psg,r,data);
|
ay8910_write_reg(psg,r,data);
|
||||||
|
@ -798,16 +823,16 @@ int ay8910_read_ym(void *chip)
|
||||||
*/
|
*/
|
||||||
if (psg->intf->portAread)
|
if (psg->intf->portAread)
|
||||||
psg->regs[AY_PORTA] = (*psg->intf->portAread)(Machine, 0);
|
psg->regs[AY_PORTA] = (*psg->intf->portAread)(Machine, 0);
|
||||||
else
|
//else
|
||||||
logerror("PC %04x: warning - read 8910 #%d Port A\n",activecpu_get_pc(),psg->index);
|
//logerror("PC %04x: warning - read 8910 #%d Port A\n",activecpu_get_pc(),psg->index);
|
||||||
break;
|
break;
|
||||||
case AY_PORTB:
|
case AY_PORTB:
|
||||||
if ((psg->regs[AY_ENABLE] & 0x80) != 0)
|
if ((psg->regs[AY_ENABLE] & 0x80) != 0)
|
||||||
logerror("warning: read from 8910 #%d Port B set as output\n",psg->index);
|
logerror("warning: read from 8910 #%d Port B set as output\n",psg->index);
|
||||||
if (psg->intf->portBread)
|
if (psg->intf->portBread)
|
||||||
psg->regs[AY_PORTB] = (*psg->intf->portBread)(Machine, 0);
|
psg->regs[AY_PORTB] = (*psg->intf->portBread)(Machine, 0);
|
||||||
else
|
//else
|
||||||
logerror("PC %04x: warning - read 8910 #%d Port B\n",activecpu_get_pc(),psg->index);
|
// logerror("PC %04x: warning - read 8910 #%d Port B\n",activecpu_get_pc(),psg->index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return psg->regs[r];
|
return psg->regs[r];
|
||||||
|
@ -819,7 +844,7 @@ int ay8910_read_ym(void *chip)
|
||||||
*
|
*
|
||||||
*************************************/
|
*************************************/
|
||||||
|
|
||||||
static void *ay8910_start(const char *tag, int sndindex, int clock, const void *config)
|
void *ay8910_start(const char *tag, int sndindex, int clock, const void *config)
|
||||||
{
|
{
|
||||||
static const ay8910_interface generic_ay8910 =
|
static const ay8910_interface generic_ay8910 =
|
||||||
{
|
{
|
||||||
|
@ -831,7 +856,8 @@ static void *ay8910_start(const char *tag, int sndindex, int clock, const void *
|
||||||
return ay8910_start_ym(SOUND_AY8910, sndindex+16, clock, intf);
|
return ay8910_start_ym(SOUND_AY8910, sndindex+16, clock, intf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *ym2149_start(const char *tag, int sndindex, int clock, const void *config)
|
/*static void
|
||||||
|
*ym2149_start(const char *tag, int sndindex, int clock, const void *config)
|
||||||
{
|
{
|
||||||
static const ay8910_interface generic_ay8910 =
|
static const ay8910_interface generic_ay8910 =
|
||||||
{
|
{
|
||||||
|
@ -841,7 +867,7 @@ static void *ym2149_start(const char *tag, int sndindex, int clock, const void *
|
||||||
};
|
};
|
||||||
const ay8910_interface *intf = (config ? config : &generic_ay8910);
|
const ay8910_interface *intf = (config ? config : &generic_ay8910);
|
||||||
return ay8910_start_ym(SOUND_YM2149, sndindex+16, clock, intf);
|
return ay8910_start_ym(SOUND_YM2149, sndindex+16, clock, intf);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
static void ay8910_stop(void *chip)
|
static void ay8910_stop(void *chip)
|
||||||
{
|
{
|
||||||
|
@ -902,19 +928,34 @@ void ay8912_get_info(void *token, UINT32 state, sndinfo *info)
|
||||||
{
|
{
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case SNDINFO_PTR_START: info->start = ay8910_start; break;
|
case SNDINFO_PTR_START:
|
||||||
case SNDINFO_STR_NAME: info->s = "AY-3-8912A"; break;
|
info->start = ay8910_start;
|
||||||
default: ay8910_get_info(token, state, info); break;
|
break;
|
||||||
|
|
||||||
|
case SNDINFO_STR_NAME:
|
||||||
|
info->s = "AY-3-8912A";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ay8910_get_info(token, state, info);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ay8913_get_info(void *token, UINT32 state, sndinfo *info)
|
void ay8913_get_info(void *token, UINT32 state, sndinfo *info)
|
||||||
{
|
{
|
||||||
switch (state)
|
switch (state) {
|
||||||
{
|
case SNDINFO_PTR_START:
|
||||||
case SNDINFO_PTR_START: info->start = ay8910_start; break;
|
info->start = ay8910_start;
|
||||||
case SNDINFO_STR_NAME: info->s = "AY-3-8913A"; break;
|
break;
|
||||||
default: ay8910_get_info(token, state, info); break;
|
|
||||||
|
case SNDINFO_STR_NAME:
|
||||||
|
info->s = "AY-3-8913A";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ay8910_get_info(token, state, info);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -954,26 +995,29 @@ void ymz284_get_info(void *token, UINT32 state, sndinfo *info)
|
||||||
{
|
{
|
||||||
case SNDINFO_PTR_START: info->start = ym2149_start; break;
|
case SNDINFO_PTR_START: info->start = ym2149_start; break;
|
||||||
case SNDINFO_STR_NAME: info->s = "YMZ284"; break;
|
case SNDINFO_STR_NAME: info->s = "YMZ284"; break;
|
||||||
default: ay8910_get_info(token, state, info); break;
|
default:
|
||||||
|
ay8910_get_info(token, state, info);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ymz294_get_info(void *token, UINT32 state, sndinfo *info)
|
void ymz294_get_info(void *token, UINT32 state, sndinfo *info)
|
||||||
{
|
{
|
||||||
switch (state)
|
switch (state) {
|
||||||
{
|
case SNDINFO_PTR_START:
|
||||||
case SNDINFO_PTR_START: info->start = ym2149_start; break;
|
info->start = ym2149_start;
|
||||||
case SNDINFO_STR_NAME: info->s = "YMZ294"; break;
|
break;
|
||||||
default: ay8910_get_info(token, state, info); break;
|
|
||||||
|
case SNDINFO_STR_NAME:
|
||||||
|
info->s = "YMZ294";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ay8910_get_info(token, state, info);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
int
|
|
||||||
main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
printf("ay8910test.\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
*
|
*
|
||||||
|
@ -1002,9 +1046,25 @@ WRITE8_HANDLER( ay8910_control_port_1_w ) { ay8910_write_ym(sndti_token(SOUND_AY
|
||||||
WRITE8_HANDLER( ay8910_control_port_2_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data); }
|
WRITE8_HANDLER( ay8910_control_port_2_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data); }
|
||||||
WRITE8_HANDLER( ay8910_control_port_3_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data); }
|
WRITE8_HANDLER( ay8910_control_port_3_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data); }
|
||||||
WRITE8_HANDLER( ay8910_control_port_4_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data); }
|
WRITE8_HANDLER( ay8910_control_port_4_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data); }
|
||||||
WRITE16_HANDLER( ay8910_control_port_0_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data & 0xff); }
|
|
||||||
WRITE16_HANDLER( ay8910_control_port_1_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 1),0,data & 0xff); }
|
WRITE16_HANDLER( ay8910_control_port_0_lsb_w )
|
||||||
WRITE16_HANDLER( ay8910_control_port_2_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data & 0xff); }
|
{
|
||||||
|
if (ACCESSING_BITS_0_7)
|
||||||
|
ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_HANDLER( ay8910_control_port_1_lsb_w )
|
||||||
|
{
|
||||||
|
if (ACCESSING_BITS_0_7)
|
||||||
|
ay8910_write_ym(sndti_token(SOUND_AY8910, 1),0,data & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE16_HANDLER( ay8910_control_port_2_lsb_w )
|
||||||
|
{
|
||||||
|
if (ACCESSING_BITS_0_7)
|
||||||
|
ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
WRITE16_HANDLER( ay8910_control_port_3_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data & 0xff); }
|
WRITE16_HANDLER( ay8910_control_port_3_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data & 0xff); }
|
||||||
WRITE16_HANDLER( ay8910_control_port_4_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data & 0xff); }
|
WRITE16_HANDLER( ay8910_control_port_4_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data & 0xff); }
|
||||||
WRITE16_HANDLER( ay8910_control_port_0_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data >> 8); }
|
WRITE16_HANDLER( ay8910_control_port_0_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data >> 8); }
|
||||||
|
@ -1028,3 +1088,29 @@ WRITE16_HANDLER( ay8910_write_port_1_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_w
|
||||||
WRITE16_HANDLER( ay8910_write_port_2_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),1,data >> 8); }
|
WRITE16_HANDLER( ay8910_write_port_2_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),1,data >> 8); }
|
||||||
WRITE16_HANDLER( ay8910_write_port_3_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),1,data >> 8); }
|
WRITE16_HANDLER( ay8910_write_port_3_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),1,data >> 8); }
|
||||||
WRITE16_HANDLER( ay8910_write_port_4_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),1,data >> 8); }
|
WRITE16_HANDLER( ay8910_write_port_4_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),1,data >> 8); }
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
//running_machine *machine;
|
||||||
|
INT16 sounddata[100];
|
||||||
|
int i=0, sndindex=1, clock=500000;
|
||||||
|
ay8910_context *info;
|
||||||
|
const ay8910_interface ay8910_inf;
|
||||||
|
int sample_rate = 11025;
|
||||||
|
|
||||||
|
printf("ay8910test.\n");
|
||||||
|
for (i=0; i<100; ++i)
|
||||||
|
sounddata[i] = 32000 + 100 * i;
|
||||||
|
|
||||||
|
//machine = malloc(sizeof(running_machine));
|
||||||
|
sdlaudio_init(sample_rate);
|
||||||
|
info = ay8910_start(NULL, sndindex, clock, &ay8910_inf);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
osd_update_audio_stream(sample_rate,sounddata,100);
|
||||||
|
sdl_kill();
|
||||||
|
//free(machine);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#define __AY8910_H__
|
#define __AY8910_H__
|
||||||
|
|
||||||
//#include "osdcomm.h"
|
//#include "osdcomm.h"
|
||||||
#include "mamecore.h"
|
//#include "mamecore.h"
|
||||||
#include "memory.h"
|
//#include "memory.h"
|
||||||
//typedef UINT32 offs_t;
|
//typedef UINT32 offs_t;
|
||||||
|
|
||||||
//typedef UINT8 (*read8_machine_func) (ATTR_UNUSED running_machine *machine, ATTR_UNUSED offs_t offset);
|
//typedef UINT8 (*read8_machine_func) (ATTR_UNUSED running_machine *machine, ATTR_UNUSED offs_t offset);
|
||||||
|
@ -142,6 +142,7 @@ WRITE16_HANDLER( ay8910_write_port_4_msb_w );
|
||||||
/*********** An interface for SSG of YM2203 ***********/
|
/*********** An interface for SSG of YM2203 ***********/
|
||||||
|
|
||||||
void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay8910_interface *intf);
|
void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay8910_interface *intf);
|
||||||
|
void *ay8910_s(void *chip);
|
||||||
|
|
||||||
void ay8910_stop_ym(void *chip);
|
void ay8910_stop_ym(void *chip);
|
||||||
void ay8910_reset_ym(void *chip);
|
void ay8910_reset_ym(void *chip);
|
||||||
|
|
|
@ -56,6 +56,17 @@ typedef UINT64 FPTR;
|
||||||
typedef UINT32 FPTR;
|
typedef UINT32 FPTR;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct _running_machine
|
||||||
|
{
|
||||||
|
/* audio-related information */
|
||||||
|
int sample_rate; /* the digital audio sample rate */
|
||||||
|
|
||||||
|
/* debugger-related information */
|
||||||
|
UINT32 debug_flags; /* the current debug flags */
|
||||||
|
void * driver_data; /* drivers can hang data off of here instead of using globals */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* These are forward struct declarations that are used to break
|
/* These are forward struct declarations that are used to break
|
||||||
circular dependencies in the code */
|
circular dependencies in the code */
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
#ifndef __MEMORY_H__
|
#ifndef __MEMORY_H__
|
||||||
#define __MEMORY_H__
|
#define __MEMORY_H__
|
||||||
|
|
||||||
|
/*
|
||||||
#include "mamecore.h"
|
#include "mamecore.h"
|
||||||
#include "devintrf.h"
|
#include "devintrf.h"
|
||||||
#include "tokenize.h"
|
#include "tokenize.h"
|
||||||
#include "osdcomm.h"
|
#include "osdcomm.h"
|
||||||
|
*/
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
CONSTANTS
|
CONSTANTS
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
|
@ -150,7 +150,8 @@ typedef enum _sound_type sound_type;
|
||||||
/* Sound information constants */
|
/* Sound information constants */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
/* --- the following bits of info are returned as 64-bit signed integers --- */
|
/* --- the following bits of info are returned as 64-bit signed
|
||||||
|
* integers --- */
|
||||||
SNDINFO_INT_FIRST = 0x00000,
|
SNDINFO_INT_FIRST = 0x00000,
|
||||||
|
|
||||||
SNDINFO_INT_ALIAS = SNDINFO_INT_FIRST, /* R/O: alias to sound type for (type,index) identification */
|
SNDINFO_INT_ALIAS = SNDINFO_INT_FIRST, /* R/O: alias to sound type for (type,index) identification */
|
||||||
|
|
|
@ -12,15 +12,16 @@
|
||||||
#ifndef STREAMS_H
|
#ifndef STREAMS_H
|
||||||
#define STREAMS_H
|
#define STREAMS_H
|
||||||
|
|
||||||
#include "attotime.h"
|
#include "osdcomm.h"
|
||||||
|
#include "deprecat.h"
|
||||||
|
|
||||||
|
|
||||||
#include "mamecore.h"
|
#include "mamecore.h"
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
TYPE DEFINITIONS
|
TYPE DEFINITIONS
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
typedef struct _sound_stream sound_stream;
|
typedef struct _sound_stream sound_stream;
|
||||||
|
#if 0
|
||||||
|
|
||||||
typedef void (*stream_update_func)(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
typedef void (*stream_update_func)(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||||
|
|
||||||
|
@ -36,6 +37,7 @@ typedef void (*stream_update_func)(void *param, stream_sample_t **inputs, stream
|
||||||
/* initialize the streams engine */
|
/* initialize the streams engine */
|
||||||
void streams_init(running_machine *machine, attoseconds_t update_subseconds);
|
void streams_init(running_machine *machine, attoseconds_t update_subseconds);
|
||||||
|
|
||||||
|
#endif
|
||||||
/* set the tag to be associated with all streams allocated from now on */
|
/* set the tag to be associated with all streams allocated from now on */
|
||||||
void streams_set_tag(running_machine *machine, void *streamtag);
|
void streams_set_tag(running_machine *machine, void *streamtag);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,191 @@
|
||||||
|
Diskettstasjonkontrolleren i TIKI-100 Rev C
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
TIKI-100 inneholder en FD1767PL-02 eller en FD1797-PL diskettstasjonkontroller
|
||||||
|
fra Western Digital. I TIKI-100 er ikke FD17xx kretsens INTRQ tilkoblet, så
|
||||||
|
den vil ikke kunne generere interrupts.
|
||||||
|
|
||||||
|
FD17xx kretsen kontrolleres gjennom 4 I/O porter:
|
||||||
|
|
||||||
|
I/O-port 10H: Statusord / styreord
|
||||||
|
|
||||||
|
Ved skriving er dette kommandoregisteret. Ved lesing er det statusregisteret.
|
||||||
|
|
||||||
|
I/O-port 11H: Spornummer
|
||||||
|
|
||||||
|
Her kan spor-registeret skrives og leses.
|
||||||
|
|
||||||
|
I/O-port 12H: Sektornummer
|
||||||
|
|
||||||
|
Her kan sektor-registeret skrives og leses.
|
||||||
|
|
||||||
|
I/O-port 13H: Dataregister
|
||||||
|
|
||||||
|
Gjennom denne porten leses og skrives data til diskett.
|
||||||
|
|
||||||
|
Oversikt over kommandoer
|
||||||
|
|
||||||
|
Type Navn Bits i kommandoregister
|
||||||
|
---------------------------------------------
|
||||||
|
I Restore 0 0 0 0 h V r1 r0
|
||||||
|
I Seek 0 0 0 1 h V r1 r0
|
||||||
|
I Step 0 0 1 T h V r1 r0
|
||||||
|
I Step-In 0 1 0 T h V r1 r0
|
||||||
|
I Step-Out 0 1 1 T h V r1 r0
|
||||||
|
II Read Sector 1 0 0 m 1 1 U 0
|
||||||
|
II Write Sector 1 0 1 m 1 1 U a0
|
||||||
|
III Read Address 1 1 0 0 0 1 U 0
|
||||||
|
III Read Track 1 1 1 0 0 1 U 0
|
||||||
|
III Write Track 1 1 1 1 0 1 U 0
|
||||||
|
IV Force Interrupt 1 1 0 1 0 0 0 0
|
||||||
|
|
||||||
|
r1,r0: Stepping Motor Rate
|
||||||
|
0 0 = 6 ms
|
||||||
|
0 1 = 12 ms
|
||||||
|
1 0 = 20 ms
|
||||||
|
1 1 = 30 ms
|
||||||
|
V: Track Number Verify Flag
|
||||||
|
0 = ikke verifiser
|
||||||
|
1 = sjekk at sporregisteret tilsvarer spornummeret i første ID-felt på
|
||||||
|
målsporet
|
||||||
|
h: Head Load
|
||||||
|
0 = ikke senk lese/skrive hodet
|
||||||
|
1 = senk lese/skrive hodet
|
||||||
|
T: Track Update Flag
|
||||||
|
0 = ikke oppdater sporregister
|
||||||
|
1 = oppdater sporregister etter endt operasjon
|
||||||
|
U: Side select
|
||||||
|
0 = velg side 0
|
||||||
|
1 = velg side 1
|
||||||
|
m: Multiple Record Flag
|
||||||
|
0 = les/skriv kun 1 sektor
|
||||||
|
1 = les/skriv sektorer helt til hele sporet er dekket
|
||||||
|
a0: Data Address Mark
|
||||||
|
0 = dataadressemerket er 0fbH
|
||||||
|
1 = dataadressemerket er 0f8H (slettet dataadressemerke)
|
||||||
|
|
||||||
|
Statusregister
|
||||||
|
|
||||||
|
Type I kommandoer:
|
||||||
|
|
||||||
|
Bit Navn Forklaring
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
7 Not ready Stasjonen er ikke klar
|
||||||
|
6 Protected Skrivebeskyttet diskett
|
||||||
|
5 Alltid 1 i TIKI-100
|
||||||
|
4 Seek error Ønsket spor ikke verifisert
|
||||||
|
3 CRC error Gal CRC i ID-felt
|
||||||
|
2 Track 0 Hodet står over spor 0
|
||||||
|
1 Index Angir begynnelsen av første sektor
|
||||||
|
0 Busy Kommando under utførelse
|
||||||
|
|
||||||
|
Type II og III kommandoer:
|
||||||
|
|
||||||
|
Bit Navn Forklaring
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
7 Not ready Samme som for type I
|
||||||
|
6 Protected Lesekommandoer: ikke brukt
|
||||||
|
Skrivekommandoer: diskett er skrivebeskyttet
|
||||||
|
5 Record type/Write fault Les sektor: 1 = slettet dataadressemerke
|
||||||
|
0 = vanlig dataadressemerke
|
||||||
|
Skrivekommandoer: Skrivefeil
|
||||||
|
4 Record not found Ønsket spor, sektor eller side ikke funnet
|
||||||
|
3 CRC error Sammen med bit 4: Feil sjekksum i kontrollfelt
|
||||||
|
Uten bit 4: Feil sjekksum i datafelt
|
||||||
|
2 Lost data Prosessor har ikke håndtert DRQ raskt nok
|
||||||
|
1 Data request Kopi av DRQ, klar for overføring av neste byte
|
||||||
|
0 Busy Kommando under utførelse
|
||||||
|
|
||||||
|
Busy flagget settes når en kommando er under utførelse. Ingen kommando, utenom
|
||||||
|
"Force Interrupt" må legges inn i kommandoregisteret mens Busy er satt.
|
||||||
|
|
||||||
|
Type I kommandoer
|
||||||
|
|
||||||
|
Restore
|
||||||
|
|
||||||
|
Før hodet til spor 0 og oppdater sporregisteret.
|
||||||
|
Hvis ikke sporet finnes innen 255 flytt, settes "Seek error" i
|
||||||
|
statusregisteret.
|
||||||
|
|
||||||
|
Seek
|
||||||
|
|
||||||
|
Denne kommandoen antar at sporregisteret inneholder gjeldende spornummer og
|
||||||
|
dataregisteret inneholder ønsket målspor.
|
||||||
|
Fører hodet til sporet angitt i dataregisteret og oppdaterer sporregisteret.
|
||||||
|
|
||||||
|
Step
|
||||||
|
|
||||||
|
Flytt hodet ett spor i samme retning som det ble flyttet sist.
|
||||||
|
|
||||||
|
Step-In
|
||||||
|
|
||||||
|
Flytt hodet ett spor innover (mot økende spornummer).
|
||||||
|
|
||||||
|
Step-Out
|
||||||
|
|
||||||
|
Flytt hodet ett spor utover (mot spor 0).
|
||||||
|
|
||||||
|
Type II kommandoer
|
||||||
|
|
||||||
|
Legg ønsket sektor i sektorregisteret.
|
||||||
|
|
||||||
|
Read Sector
|
||||||
|
|
||||||
|
Overfører ønsket sektor byte for byte gjennom dataregisteret. Hver gang en byte
|
||||||
|
er klar for overføring settes "Data request" flagget i statusregisteret. Etter
|
||||||
|
endt operasjon settes "Recort type" flagget i statusregisteret.
|
||||||
|
|
||||||
|
Write Sector
|
||||||
|
|
||||||
|
Skriver ønsket sektor til diskett. Hver gang en byte kan skrives, settes "Data
|
||||||
|
request" flagget i statusregisteret. Diskettkontrolleren lager selv ID feltet
|
||||||
|
med riktig dataadressemerke og CRC.
|
||||||
|
|
||||||
|
Type III kommandoer
|
||||||
|
|
||||||
|
Read Address
|
||||||
|
|
||||||
|
Overfører gjennom dataregisteret det neste ID feltet som passeres. Hver gang en
|
||||||
|
byte er klar for overføring settes "Data request" flagget i statusregisteret.
|
||||||
|
ID feltet består av seks bytes:
|
||||||
|
1 spor
|
||||||
|
2 side
|
||||||
|
3 sektor
|
||||||
|
4 sektorlengde
|
||||||
|
0 = 128 bytes
|
||||||
|
1 = 256 bytes
|
||||||
|
2 = 512 bytes
|
||||||
|
3 = 1024 bytes
|
||||||
|
5,6 CRC
|
||||||
|
|
||||||
|
Read Track
|
||||||
|
|
||||||
|
Overfører hele sporet gjennom dataregisteret, inkludert ID felt og mellomrom.
|
||||||
|
Hver gang en byte er klar for overføring settes "Data request" flagget i
|
||||||
|
statusregisteret.
|
||||||
|
|
||||||
|
Write Track
|
||||||
|
|
||||||
|
Skriver et spor til diskett, inkludert mellomrom og ID felter. Brukes til
|
||||||
|
formatering av diskett. Bytes overføres gjennom dataregisteret. "Data request"
|
||||||
|
settes i statusregisteret når det er klart for neste byte.
|
||||||
|
Bytes f5H-feH tolkes som dataadressemerke. Spesielt tolkes f5H-f7H slik:
|
||||||
|
f5H Skriv a1H, nullstill CRC generator.
|
||||||
|
f6H Skriv c2H
|
||||||
|
f7H Skriv 2 bytes CRC.
|
||||||
|
|
||||||
|
Type IV kommandoer
|
||||||
|
|
||||||
|
Force Interrupt
|
||||||
|
|
||||||
|
Brukes til å stanse en pågående operasjon før den avsluttes på normalt vis,
|
||||||
|
eller sikre type I statusregister.
|
||||||
|
Hvis denne kommandoen settes mens en annen kommando utføres (busy = 1), vil
|
||||||
|
busy settes lik 0 og resten av statusregisteret er uforandret.
|
||||||
|
Hvis busy = 0 når denne kommandoen utføres vil statusregisteret slettes /
|
||||||
|
oppdateres og reflektere type I statusregister.
|
||||||
|
|
||||||
|
---
|
||||||
|
21 januar 2001
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
I/O-porter i TIKI-100 Rev C
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Adresse Retning Funksjon
|
||||||
|
--------------------------------------------------------
|
||||||
|
00-03 les/skriv Tastatur
|
||||||
|
04 les/skriv Seriekanal A, dataord
|
||||||
|
05 les/skriv Seriekanal B, dataord
|
||||||
|
06 les/skriv Seriekanal A, statusord/styreord
|
||||||
|
07 les/skriv Seriekanal B, statusord/styreord
|
||||||
|
08 les/skriv Parallellport A, dataord
|
||||||
|
09 les/skriv Parallellport B, dataord
|
||||||
|
0A les/skriv Parallellport A, statusord/styreord
|
||||||
|
0B les/skriv Parallellport B, statusord/styreord
|
||||||
|
0C-0F skriv Grafikk modus
|
||||||
|
10 les/skriv Diskettstasjon statusord/styreord
|
||||||
|
11 les/skriv Diskettstasjon spornummer-register
|
||||||
|
12 les/skriv Diskettstasjon sektor-register
|
||||||
|
13 les/skriv Diskettstasjon dataregister
|
||||||
|
14-15 skriv Grafikk fargeregister (pallett)
|
||||||
|
16 skriv Lyd og scroll peker
|
||||||
|
17 les/skriv Lyd og scroll data
|
||||||
|
18 les/skriv Tellerkrets (CTC) kanal 0
|
||||||
|
19 les/skriv Tellerkrets (CTC) kanal 1
|
||||||
|
1A les/skriv Tellerkrets (CTC) kanal 2
|
||||||
|
1B les/skriv Tellerkrets (CTC) kanal 3
|
||||||
|
1C-1F skriv Systemregister
|
||||||
|
|
||||||
|
Ledige I/O-porter:
|
||||||
|
|
||||||
|
20-7F Reservert TIKI-DATA
|
||||||
|
20-27 Winchester controller
|
||||||
|
60-6F Analog I/O (SINTEF)
|
||||||
|
60-67 RVO-kort (DIGI I/O)
|
||||||
|
70-77 Analog/Digital I/O
|
||||||
|
78-7B Lyspenn interface
|
||||||
|
7E-7F 8088/87 16 bit prosessor med 128k RAM
|
||||||
|
80-FF Ledig for bruk av andre enn TIKI-DATA
|
||||||
|
|
||||||
|
Alle adresser er i hex.
|
||||||
|
Der flere portadresser er angitt for ett og samme register, bør du benytte deg
|
||||||
|
av den første.
|
||||||
|
|
||||||
|
---
|
||||||
|
18 juni 2000
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
Lyd og scrolling i TIKI-100 Rev C
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
TIKI-100 inneholder en AY-3-8912 chip. Dette er en standard lydkrets som finnes
|
||||||
|
i mange andre datamaskiner, bl.a Amstrad CPC og ZX-Spectrum. Siden det finnes
|
||||||
|
mange gode tekster som omhandler programmering av denne kretsen, tar jeg bare
|
||||||
|
med det som gjelder spesielt for TIKI her.
|
||||||
|
|
||||||
|
AY-3-8912 har 15 registre som kontrollerer kretsens virkemåte. Den har 2
|
||||||
|
funksjoner; Hovedfunksjonen er lydgenerering, men den inneholder også en 8 bits
|
||||||
|
dataport. Denne dataporten er i TIKI-100 brukt til vertikal scrolling av
|
||||||
|
skjermen.
|
||||||
|
|
||||||
|
Tilgang til AY-3-8912 skjer gjennom 2 I/O-porter:
|
||||||
|
|
||||||
|
I/O-port 16H: Lyd og scroll peker
|
||||||
|
|
||||||
|
For å få tilgang til et av registrene i AY-3-8912, må det aktuelle
|
||||||
|
registernummeret skrives til denne porten.
|
||||||
|
|
||||||
|
I/O-port 17H: Lyd og scroll data
|
||||||
|
|
||||||
|
Etter at registernummeret er skrevet til I/O-port 16H, kan data til det aktuelle
|
||||||
|
registeret skrives/leses i denne porten.
|
||||||
|
|
||||||
|
Hardware scrolling
|
||||||
|
|
||||||
|
Som nevnt tidligere, benyttes AY-3-8912's dataport (register 14) til vertikal
|
||||||
|
scrolling. Hver gang prosessor eller videokrets prøver å få tilgang til grafikk-
|
||||||
|
hukommelsen, adderes innholdet i denne dataporten multiplisert med 128 til
|
||||||
|
verdien på adressebussen. Hvis f.eks prosessoren skal ha tak i innholdet i
|
||||||
|
adresse 0 i grafikkram, og innholdet i AY-3-8912's dataport er 10, vil
|
||||||
|
prosessoren i stedet få innholdet i adresse 0 + (10*128) MOD 32768 = 1280. Selv
|
||||||
|
om data i grafikkram ikke fysisk skifter plass, vil det i praksis føles som om
|
||||||
|
grafikkram-innholdet hopper oppover like mange linjer som dataportens innhold
|
||||||
|
øker med i verdi.
|
||||||
|
|
||||||
|
Med andre ord: For å scrolle skjermen oppover x antall linjer, legg x til
|
||||||
|
verdien som allerede ligger i AY-3-8912's dataport.
|
||||||
|
For å scrolle skjermen nedover x antall linjer, trekk x fra verdien som
|
||||||
|
allerede ligger i AY-3-8912's dataport.
|
||||||
|
|
||||||
|
---
|
||||||
|
26 juni 2001
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
@ -0,0 +1,116 @@
|
||||||
|
Parallellporter i TIKI-100 Rev C
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
TIKI-100 inneholder en Z80 PIO krets med 2 stk. 8-bits I/O porter
|
||||||
|
(hver med kvitteringssignalene RDY og STB).
|
||||||
|
Begge disse er koblet opp til parallellport P3. Se portbeskrivelsen
|
||||||
|
for mer informasjon om pinnetilordning.
|
||||||
|
|
||||||
|
Z80 PIO kontrolleres gjennom 4 I/O porter:
|
||||||
|
|
||||||
|
I/O-port 08H: Parallellport A, dataord
|
||||||
|
|
||||||
|
Her leses og skrives data for parallellport A.
|
||||||
|
|
||||||
|
I/O-port 09H: Parallellport B, dataord
|
||||||
|
|
||||||
|
Her leses og skrives data for parallellport B.
|
||||||
|
|
||||||
|
I/O-port 0AH: Parallellport A, styreord
|
||||||
|
|
||||||
|
Her skrives kontrollregisteret til parallellport A.
|
||||||
|
|
||||||
|
I/O-port 0BH: Parallellport B, styreord
|
||||||
|
|
||||||
|
Her skrives kontrollregisteret til parallellport B.
|
||||||
|
|
||||||
|
Operasjonsmodi
|
||||||
|
|
||||||
|
Parallellportene kan settes til en av 4 modi:
|
||||||
|
|
||||||
|
Modus 0: Data ut. Data skrevet til dataregisteret blir satt rett ut på
|
||||||
|
porten. De kan også leses tilbake. Når gyldige data settes ut
|
||||||
|
på porten, går RDY høy. STB kan settes høy av eksternt utstyr
|
||||||
|
for å indikere at data er lest.
|
||||||
|
Modus 1: Data inn. Porten klokker inn data utenfra når det eksterne
|
||||||
|
utstyret setter STB høy. Data kan hentes inn til CPU ved å
|
||||||
|
lese dataregisteret. Da blir samtidig RDY høy, og indikerer
|
||||||
|
til det eksterne utstyret at porten er klar for en ny byte.
|
||||||
|
Når STB settes høy, går RDY lav, og kretsen kan gi interrupt.
|
||||||
|
Modus 2: Bidireksjonal (både inn og ut). Bare port A kan fungere i
|
||||||
|
modus 2. Når port A settes til modus 2, må samtidig port B
|
||||||
|
settes til modus 2 og port B må settes til å ikke generere
|
||||||
|
interrupts.
|
||||||
|
Data ut er lik modus 0, bortsett fra at data bare settes ut
|
||||||
|
når ASTB er lav.
|
||||||
|
Data inn er lik modus 1, bortsett fra at kvitteringssignalene
|
||||||
|
og interruptmulighetene til port B benyttes.
|
||||||
|
Modus 3: Bit kontroll. Individuelle bits i parallellporten kan settes
|
||||||
|
enten til inn eller ut. RDY og STB er ikke brukt. I stedet
|
||||||
|
genereres en interrupt hvis interruptbetingelsene til
|
||||||
|
input-pinnene bestemt under programmering av porten er
|
||||||
|
oppfyllt.
|
||||||
|
|
||||||
|
Programmering
|
||||||
|
|
||||||
|
Programmering av porten foregår ved skriving til portens
|
||||||
|
kontrollregister.
|
||||||
|
|
||||||
|
Følgende styreord kan skrives til kontrollregisteret:
|
||||||
|
|
||||||
|
Mode Control Word:
|
||||||
|
|
||||||
|
Bit 6-7: Velger modus:
|
||||||
|
Bit 7 Bit 6
|
||||||
|
0 0 Modus 0
|
||||||
|
0 1 Modus 1
|
||||||
|
1 0 Modus 2
|
||||||
|
1 1 Modus 3
|
||||||
|
Når modus 3 velges, MÅ etterfølgende ord skrevet til
|
||||||
|
kontrollregisteret være et retningsord, der en ener i en
|
||||||
|
bitposisjon medfører at tilsvarende I/O-pinne vil bli en
|
||||||
|
inngang, mens en nuller vil medføre at I/O-pinnen blir en
|
||||||
|
utgang.
|
||||||
|
Bit 4-5: Ubrukt
|
||||||
|
Bit 0-3: Må settes til 1111 (identifiserer at dette er Mode Control
|
||||||
|
Word).
|
||||||
|
|
||||||
|
Interrupt Control Word:
|
||||||
|
|
||||||
|
Bit 7 = 1: Skrur på interruptfunksjonen
|
||||||
|
Bit 7 = 0: Skrur av interruptfunksjonen
|
||||||
|
Bit 6 = 1: OG funksjon, alle bit med i interruptbetingelsen må gå til
|
||||||
|
den definerte tilstanden for at interrupt skal genereres.
|
||||||
|
Bit 6 = 0: ELLER funksjon, interrupt genereres når minst ett bit går
|
||||||
|
til den definerte tilstanden.
|
||||||
|
Bit 5 = 1: Definert tilstand er høy
|
||||||
|
Bit 5 = 0: Definert tilstand er lav
|
||||||
|
Bit 4 = 1: Kun utvalgte bit er med i interruptbetingelsen. Neste byte
|
||||||
|
skrevet til kontrollregisteret må være et maskeord. Dersom
|
||||||
|
et utvalgt bit i maskeordet er satt vil den tilsvarende
|
||||||
|
pinnen i parallellporten IKKE monitoreres for interrupt.
|
||||||
|
Dersom bit 4 er satt, MÅ det altså skrives et slikt
|
||||||
|
maskeord til kontrollregisteret umiddelbart etterpå.
|
||||||
|
Uansett modus, ved å sette bit 4 til 1 vil alle ventende
|
||||||
|
interrupts bli slettet.
|
||||||
|
Bit 0-3: Må settes til 0111 (identifiserer at dette er Interrupt
|
||||||
|
Control Word).
|
||||||
|
|
||||||
|
Interrupt Disable Word:
|
||||||
|
|
||||||
|
Bit 7 = 1: Skrur på interrupts
|
||||||
|
Bit 7 = 0: Skrur av interrupts
|
||||||
|
Bit 4-6: Ubrukt
|
||||||
|
Bit 0-3: Må settes til 0011 (identifiserer at dette er Interrupt
|
||||||
|
Disable Word).
|
||||||
|
|
||||||
|
Interrupt Vector Word:
|
||||||
|
|
||||||
|
Bit 1-7: Setter interrupt vektoren som skal benyttes ved interrupts
|
||||||
|
(med implisitt 0 i minst signifikante bit).
|
||||||
|
Bit 0: Må settes til 0 (identifiserer at dette er Interrupt Vector
|
||||||
|
word).
|
||||||
|
|
||||||
|
---
|
||||||
|
18 august 2002
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
|
@ -0,0 +1,180 @@
|
||||||
|
Serieporter i TIKI-100 Rev C
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
TIKI-100 benytter seg av en Z80 DART som inneholder to asynkrone RS-232
|
||||||
|
serieporter.
|
||||||
|
|
||||||
|
DART kontrolleres gjennom 4 I/O porter:
|
||||||
|
|
||||||
|
I/O port 04H: Seriekanal A, dataord
|
||||||
|
|
||||||
|
Gjennom denne porten leses og skrives data til serieport A.
|
||||||
|
|
||||||
|
I/O port 05H: Seriekanal B, dataord
|
||||||
|
|
||||||
|
Gjennom denne porten leses og skrives data til serieport B.
|
||||||
|
|
||||||
|
I/O port 06H: Seriekanal A, statusord/styreord
|
||||||
|
|
||||||
|
Ved skriving er dette kommandoregisteret til port A, ved lesing er det
|
||||||
|
statusregisteret.
|
||||||
|
|
||||||
|
I/O port 07H: Seriekanal B, statusord/styreord
|
||||||
|
|
||||||
|
Ved skriving er dette kommandoregisteret til port B, ved lesing er det
|
||||||
|
statusregisteret.
|
||||||
|
|
||||||
|
DART's interne registre
|
||||||
|
|
||||||
|
Hver seriekanal har 3 leseregistre og 6 skriveregistre. Disse kan nås gjennom to
|
||||||
|
etterfølgende lese/skrive-operasjoner til kanalens kommandoregister. Først
|
||||||
|
skrives en peker til kommandoregisteret som angir hvilket register som ønskes,
|
||||||
|
deretter skrives/leses det aktuelle registeret gjennom den samme I/O
|
||||||
|
porten. Dersom en lese/skrive operasjon ikke kommer etter en gyldig peker, vil
|
||||||
|
register 0 benyttes.
|
||||||
|
|
||||||
|
Leseregister 0
|
||||||
|
|
||||||
|
Bit 7 = 1: BRK. Seriekanalen ligger på +V i mer enn 2 tegnlengder.
|
||||||
|
Bit 6: Ikke i bruk.
|
||||||
|
Bit 5 = 1: CTS. Modemsignalet CTS er satt.
|
||||||
|
Bit 3-4: Ikke i bruk.
|
||||||
|
Bit 2 = 1: TBE. Transmit Buffer Empty. Sender har sendt tegn og er klar for et
|
||||||
|
nytt. Rett etter initialisering av seriekanal kan et tegn
|
||||||
|
skrives til dataporten uten å sjekke denne biten først. Dette
|
||||||
|
fordi denne biten settes først etter at et tegn har blitt sendt,
|
||||||
|
og vil derfor ikke være satt før første tegn er sendt.
|
||||||
|
Bit 1 = 1: INT. Interrupt er satt
|
||||||
|
Bit 0 = 1: RXA. Receive Character Available, dvs. nytt tegn mottatt og kan leses
|
||||||
|
ut av dataporten. Denne biten blir nullstilt etter at dataporten
|
||||||
|
har blitt lest.
|
||||||
|
|
||||||
|
Leseregister 1
|
||||||
|
|
||||||
|
Bit 7: Ikke i bruk.
|
||||||
|
Bit 6 = 1: FF. Format feil, f.eks feil antall stopbits.
|
||||||
|
Bit 5 = 1: RXO. Receiver Overflow, dvs innkommende tegn har kommet fortere enn
|
||||||
|
de har blitt lest ut av dataporten.
|
||||||
|
Bit 4 = 1: PF. Paritetsfeil.
|
||||||
|
Bit 1-3: Ikke i bruk.
|
||||||
|
Bit 0 = 1: AS. Alt sendt.
|
||||||
|
|
||||||
|
Leseregister 2
|
||||||
|
|
||||||
|
Interruptvektor kan leses ut av dette registeret. Bit 0-3 kan variere, avhengig
|
||||||
|
av status dersom "Status affects vector" er satt.
|
||||||
|
|
||||||
|
Skriveregister 0
|
||||||
|
|
||||||
|
I skriveregister 0 settes peker for det neste registeret man vil nå gjennom
|
||||||
|
denne porten.
|
||||||
|
|
||||||
|
Bit 6-7: Ikke i bruk
|
||||||
|
Bit 3-5: Peker til neste register som skal nås
|
||||||
|
Bit 5 Bit 4 Bit 3 Register
|
||||||
|
0 0 0 0
|
||||||
|
0 0 1 1
|
||||||
|
0 1 0 2
|
||||||
|
0 1 1 3
|
||||||
|
1 0 0 4
|
||||||
|
1 0 1 5
|
||||||
|
Bit 0-2: Nullstillingskommando
|
||||||
|
Bit 2 Bit 1 Bit 0 Funksjon
|
||||||
|
0 1 0 Nullstill status interrupt
|
||||||
|
0 1 1 Nullstill hele kanalen
|
||||||
|
1 0 0 Sett interrupt når neste serietegn
|
||||||
|
mottas
|
||||||
|
1 0 1 Nullstill senderinterrupt
|
||||||
|
1 1 0 Nullstill feilmelding
|
||||||
|
1 1 1 Retur fra interrupt (bare kanal A)
|
||||||
|
|
||||||
|
Skriveregister 1
|
||||||
|
|
||||||
|
Bit 5-7: Ikke i bruk.
|
||||||
|
Bit 3-4: RXI.
|
||||||
|
Bit 4 Bit 3 Type mottakerinterrupt
|
||||||
|
0 0 Ingen mottaker interrupt
|
||||||
|
0 1 Sett mottaker interrupt ved første mottatte tegn
|
||||||
|
1 0 Interrupt på alle mottatte tegn, paritet endrer
|
||||||
|
vektor (aner ikke hva det vil si)
|
||||||
|
1 1 Interrupt på alle mottatte tegn, paritet endrer
|
||||||
|
ikke vektor
|
||||||
|
Bit 2 = 1: SAV. Status Affects Vector, dvs interruptvektoren endres avhengig av
|
||||||
|
årsaken til interruptet.
|
||||||
|
Bit 1 = 1: TXI. Sett interrupt når senderen er klar for neste tegn.
|
||||||
|
Bit 0 = 1: EXI. Sett interrupt ved endring av eksterne signaler.
|
||||||
|
|
||||||
|
Skriveregister 2
|
||||||
|
|
||||||
|
Interruptvektor, skriv inn ønsket interruptvektor her. Interruptvektoren er delt
|
||||||
|
mellom begge seriekanalene.
|
||||||
|
|
||||||
|
Skriveregister 3
|
||||||
|
|
||||||
|
Bit 6-7: Antall bits pr. tegn i mottakeren
|
||||||
|
Bit 6 Bit 5 Antall bits
|
||||||
|
0 0 5
|
||||||
|
0 1 6
|
||||||
|
1 0 7
|
||||||
|
1 1 8
|
||||||
|
Bit 5 = 1: AE. Auto Enable, dvs senderen slås automatisk av og på med signalet
|
||||||
|
CTS.
|
||||||
|
Bit 1-4: Ikke i bruk.
|
||||||
|
Bit 0 = 1: RXE. Receiver Enable, dvs starter mottakerfunksjon.
|
||||||
|
|
||||||
|
Skriveregister 4
|
||||||
|
|
||||||
|
Bit 6-7: Neddeling av klokkefrekvensen, dvs hvilket tall innkommende
|
||||||
|
klokkefrekvens skal deles med for å få antall baud.
|
||||||
|
Bit 7 Bit 6 Neddeling
|
||||||
|
0 0 1
|
||||||
|
0 1 16
|
||||||
|
1 0 32
|
||||||
|
1 1 64
|
||||||
|
Bit 4-5: Ikke i bruk.
|
||||||
|
Bit 2-3: Antall stopbits
|
||||||
|
Bit 3 Bit 2 Antall
|
||||||
|
0 0 Ugyldig
|
||||||
|
0 1 1
|
||||||
|
1 0 1,5
|
||||||
|
1 1 2
|
||||||
|
Bit 1 = 1: PN. Like paritet.
|
||||||
|
Bit 0 = 1: P. Paritet skal benyttes.
|
||||||
|
|
||||||
|
Skriveregister 5
|
||||||
|
|
||||||
|
Bit 7: Ikke i bruk.
|
||||||
|
Bit 5-6: TN Antall bits pr. tegn i senderen
|
||||||
|
Bit 6 Bit 5 Antall
|
||||||
|
0 0 5
|
||||||
|
0 1 7
|
||||||
|
1 0 6
|
||||||
|
1 1 8
|
||||||
|
Bit 4 = 1: SB. Send Break, dvs legg serieutgangen på -V.
|
||||||
|
Bit 3 = 1: TXE. Start senderfunksjonen.
|
||||||
|
Bit 2: Ikke i bruk.
|
||||||
|
Bit 1 = 1: RTS. Slå på Request To Send.
|
||||||
|
Bit 0: Ikke i bruk.
|
||||||
|
|
||||||
|
Interrupts
|
||||||
|
|
||||||
|
Jeg er usikker på en del av DART's interruptgenerering. Dette er hva jeg tror:
|
||||||
|
|
||||||
|
Interruptvektor deles mellom kanalene.
|
||||||
|
Dersom "Status Affects Vector" er satt, vil interruptvektoren som benyttes
|
||||||
|
forandres avhengig av status. Vektoren forandres slik:
|
||||||
|
|
||||||
|
Sender B, normal: Bit 3 = 0, bit 2 = 0, bit 1 = 0
|
||||||
|
Sender B, feil: Bit 3 = 0, bit 2 = 0, bit 1 = 1
|
||||||
|
Mottaker B, normal: Bit 3 = 0, bit 2 = 1, bit 1 = 0
|
||||||
|
Mottaker B, feil: Bit 3 = 0, bit 2 = 1, bit 1 = 1
|
||||||
|
|
||||||
|
Sender A, normal: Bit 3 = 1, bit 2 = 0, bit 1 = 0
|
||||||
|
Sender A, feil: Bit 3 = 1, bit 2 = 0, bit 1 = 1
|
||||||
|
Mottaker A, normal: Bit 3 = 1, bit 2 = 1, bit 1 = 0
|
||||||
|
Mottaker A, feil: Bit 3 = 1, bit 2 = 1, bit 1 = 1
|
||||||
|
|
||||||
|
---
|
||||||
|
28 juni 2001
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
Systemregisteret i TIKI-100 Rev C
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
I/O-port 1CH - Systemregister
|
||||||
|
|
||||||
|
Dette registeret benyttes til valg av minnekonfigurasjon, styring av lamper på
|
||||||
|
tastaturet, og styring av div diskett-funksjoner.
|
||||||
|
|
||||||
|
Bit nr Navn Aktiv Funksjon
|
||||||
|
----------------------------------------------------------
|
||||||
|
7 LMP1 LAV Lys i LOCK-tast lampe
|
||||||
|
6 MOTON HØY Slår på diskett-motor
|
||||||
|
5 LMP0 LAV Lys i GRAFIKK-tast lampe
|
||||||
|
4 SDEN HØY Enkel skrivetetthet på diskett
|
||||||
|
3 VIRE HØY Grafikk RAM i området 0000-7FFF
|
||||||
|
2 ROME LAV EPROM i området 0000-3FFF
|
||||||
|
1 DRIS1 HØY Velger diskettstasjon 1
|
||||||
|
0 DRIS0 HØY Velger diskettstasjon 0
|
||||||
|
|
||||||
|
Minnekonfigurasjon:
|
||||||
|
|
||||||
|
Bit 3 Bit 2 | Adresseområde
|
||||||
|
VIRE ROME | 0000-3FFF 4000-7FFF 8000-FFFF
|
||||||
|
---------------------------+------------------------------------
|
||||||
|
0 0 | EPROM RAM RAM
|
||||||
|
0 1 | RAM RAM RAM
|
||||||
|
1 0 | Reservert (ikke i bruk)
|
||||||
|
1 1 | GFX-RAM GFX-RAM RAM
|
||||||
|
|
||||||
|
Som du sikkert ser, har EPROM'en et adresseområde på 16k. Disse er fordelt på 2
|
||||||
|
sokler (U10 og U9) med hver sin 8k EPROM. Kun den første (U10) er i bruk, men
|
||||||
|
man kan sette inn en standard 2k, 4k eller 8k 28 pins EPROM i den andre sokkelen
|
||||||
|
(U9) hvis ønskelig. Den vil i såfall få området 2000-3FFF.
|
||||||
|
|
||||||
|
---
|
||||||
|
21 juni 2000
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
Tastaturet i TIKI-100 Rev. C
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Tastaturet består av en tastaturmatrise på 8 rader og 12 kolonner.
|
||||||
|
|
||||||
|
I/O-port 00H: Tastatur
|
||||||
|
|
||||||
|
Denne porten benyttes ved avlesning av tastaturet. All skriving til denne porten
|
||||||
|
nullstiller / resetter avlesningen og må gjøres før avlesning begynner. Deretter
|
||||||
|
kan hver enkelt tastatur kolonne avleses ved gjentatt lesing av denne porten.
|
||||||
|
Etter 12 leseoperasjoner har man hentet inn alle tastaturkolonnene.
|
||||||
|
Satt bit betyr tast IKKE nedtrykket.
|
||||||
|
F.eks: Hvis du etter å ha resatt tastaturet med en skriveoperasjon til port 0,
|
||||||
|
leser verdien 01111111B, betyr det at CTRL er nedtrykket.
|
||||||
|
|
||||||
|
Tastaturmatrise:
|
||||||
|
|
||||||
|
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||||
|
----+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||||
|
1 | CTRL | SHIFT | BRYT | RETUR | MLMROM | / (num) | SLETT | |
|
||||||
|
2 | GRAFIKK | 1 | ANGRE | a | < | z | q | LOCK |
|
||||||
|
3 | 2 | w | s | x | 3 | e | d | c |
|
||||||
|
4 | 4 | r | f | v | 5 | t | g | b |
|
||||||
|
5 | 6 | y | h | n | 7 | u | j | m |
|
||||||
|
6 | 8 | i | k | , | 9 | o | l | . |
|
||||||
|
7 | 0 | p | ø | - | + | å | æ | HJELP |
|
||||||
|
8 | @ | ^ | ' | VENSTRE | UTVID | F1 | F4 | SIDEOPP |
|
||||||
|
9 | F2 | F3 | F5 | F6 | OPP | SIDENED | VTAB | NED |
|
||||||
|
10 | + (num) | - (num) | * (num) | 7 (num) | 8 (num) | 9 (num) | % (num) | = (num) |
|
||||||
|
11 | 4 (num) | 5 (num) | 6 (num) | HTAB | 1 (num) | 0 (num) | . (num) | |
|
||||||
|
12 | HJEM | HØYRE | 2 (num) | 3 (num) | ENTER | | | |
|
||||||
|
----+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||||
|
|
||||||
|
(num) betyr at tasten er på det numeriske tastaturet.
|
||||||
|
|
||||||
|
---
|
||||||
|
27 august 2000
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
Tellere i TIKI-100 Rev C
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
TIKI-100 inneholder en Z80 CTC krets med 4 stk. 8-bits tellere.
|
||||||
|
|
||||||
|
Hver teller har en inngang og en utgang.
|
||||||
|
|
||||||
|
Slik er tellerkanalene koblet i TIKI-100:
|
||||||
|
|
||||||
|
Kanal 0 inn: 2MHz
|
||||||
|
Kanal 1 inn: 2MHz
|
||||||
|
Kanal 2 inn: Kanal 0 ut
|
||||||
|
Kanal 3 inn: Kanal 2 ut
|
||||||
|
|
||||||
|
Kanal 0 ut: BAR 0, til seriekanal A
|
||||||
|
Kanal 1 ut: BAR 1, til seriekanal B
|
||||||
|
Kanal 2 ut: BAR 2, til seriekanal A dersom jumper ST 28 B er kortsluttet
|
||||||
|
|
||||||
|
Normalt benyttes kanal 0 og 1 til å generere klokkefrekvenser til seriekanalene,
|
||||||
|
mens kanal 3 genererer avbruddssignaler.
|
||||||
|
Alternativt kan kanal 2 brukes til å generere klokkefrekvenser til seriekanal A
|
||||||
|
dersom ekstra lave hastigheter er nødvendig. Da kreves det at en bøyle (jumper)
|
||||||
|
på kretskortet kortsluttes (jumper ST 28 B)
|
||||||
|
|
||||||
|
Tellerne teller alltid ned fra en startverdi (tidskonstanten).
|
||||||
|
Når telleren kommer til 0, settes en puls ut på utgangen, og genererer evt. et
|
||||||
|
avbrudd.
|
||||||
|
|
||||||
|
I/O-porter 18H, 19H, 1AH, 1BH: Tellerkrets kanal 0, 1, 2, 3
|
||||||
|
|
||||||
|
Alle disse portene brukes likt, og styrer hhv teller 0, 1, 2 og 3.
|
||||||
|
|
||||||
|
Skriving til port:
|
||||||
|
|
||||||
|
Bit 7 = 1: Interrupt når teller kommer til 0
|
||||||
|
Bit 6 = 1: Tellermodus, pulser på separat inngang telles
|
||||||
|
Bit 6 = 0: Timermodus, nedtelling av 4MHz klokke
|
||||||
|
Bit 5 = 1: Nedskalering 256 når bit 6=0
|
||||||
|
Bit 5 = 0: Nedskalering 16 når bit 6=0
|
||||||
|
Bit 4 = 1: Teller på positiv flanke (negativ flanke hvis bit 4 = 0)
|
||||||
|
Bit 3: Skal alltid være 0 i TIKI-100
|
||||||
|
Bit 2 = 1: Neste ord som skrives hit er tidskonstanten
|
||||||
|
Bit 1 = 1: Reset. Teller stoppes, men ingen registre endres. Hvis både bit 1 og
|
||||||
|
2 er 1, fortsetter telleren etter at tidskonstanten er skrevet.
|
||||||
|
Bit 0: ? (bør settes til 1?)
|
||||||
|
|
||||||
|
Lesing av port:
|
||||||
|
|
||||||
|
Avlest verdi gir antall pulser igjen til 0.
|
||||||
|
|
||||||
|
---
|
||||||
|
18 juni 2000
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
Videokretsen i TIKI-100 Rev C
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
TIKI-100 inneholder kun bitmap-grafikk, dvs ingen tekstbaserte moduser.
|
||||||
|
Prosessoren kan skrive direkte til skjermhukommelsen hvis bit 2 og 3 i
|
||||||
|
systemregisteret (1CH) er satt.
|
||||||
|
Grafikkhukommelsen representeres på skjermen på den intuitivt riktige måten.
|
||||||
|
128 bytes per linje, alle disse bytene er etter hverandre i RAM. Totalt 256
|
||||||
|
linjer:
|
||||||
|
|
||||||
|
+---------------------------------------+
|
||||||
|
|byte 0 ... byte 127 |
|
||||||
|
|byte 128 ... byte 255 |
|
||||||
|
| . |
|
||||||
|
| . |
|
||||||
|
| . |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
|byte 32640 ... byte 32767 |
|
||||||
|
+---------------------------------------+
|
||||||
|
|
||||||
|
I/O-port 0CH - Modusregister
|
||||||
|
|
||||||
|
Bit 7 = 1: Skriv farge. Ved hver HBLANK legges fargen i fargeregister 14H inn i
|
||||||
|
pallettplass angitt av bit 0-3
|
||||||
|
Bit 6: Ikke brukt
|
||||||
|
Bit 4-5: Velger oppløsning
|
||||||
|
Bit 5 Bit 4
|
||||||
|
0 0
|
||||||
|
0 1 2 farger, 1024 kolonner
|
||||||
|
1 0 4 farger, 512 kolonner
|
||||||
|
1 1 16 farger, 256 kolonner
|
||||||
|
Alle 16 fargene i palletten benyttes av videokretsen i alle moduser.
|
||||||
|
Dersom ikke paletten settes slik det er tenkt kommer det fargerikt
|
||||||
|
rot på skjermen i 2 og 4 fargers modus. For 2-fargers modus: Sett
|
||||||
|
farge 2,4,6,8,10,12,14 lik farge 0, og farge 1,3,5,7,9,11,13,15 lik
|
||||||
|
farge 1. For 4-fargers modus: Sett farge 4,8,12 lik farge 0, farge
|
||||||
|
5,9,13 lik farge 1, farge 6,10,14 lik farge 2, og farge 7,11,15 lik
|
||||||
|
farge 3.
|
||||||
|
Bit 0-3: Hvilken plass i palletten fargen i fargeregisteret skal legges inn i
|
||||||
|
(hvis bit 7 = 1)
|
||||||
|
|
||||||
|
I/O-port 14H - Fargeregister
|
||||||
|
|
||||||
|
Dette brukes til mellomlagring av en farge før den lagres i palletten (se
|
||||||
|
modusregister). Farger blandes slik:
|
||||||
|
|
||||||
|
Bit 5-7: Rød intensitet
|
||||||
|
Bit 2-4: Grønn intensitet
|
||||||
|
Bit 0-1: Blå intensitet
|
||||||
|
|
||||||
|
Registeret er invertert, dvs at 0 gir sterkest intensitet og 7 (3 for blåfarge)
|
||||||
|
gir svakest intensitet.
|
||||||
|
|
||||||
|
Hardware-scrolling
|
||||||
|
|
||||||
|
Hardware scrolling styres gjennom dataporten på lydkretsen AY-3-8912. Les mer om
|
||||||
|
dette i egen tekst.
|
||||||
|
|
||||||
|
---
|
||||||
|
27 juni 2001
|
||||||
|
Asbjørn Djupdal, djupdal@stud.ntnu.no
|
||||||
|
|
Reference in New Issue