Lots of changes. Maybe for the better, maybe not.
This commit is contained in:
parent
aaee3363c4
commit
fc0606303b
|
@ -2,5 +2,21 @@
|
|||
|
||||
all: ay8910test
|
||||
|
||||
ay8910test: ay8910.c
|
||||
gcc -o ay8910test ay8910.c
|
||||
ay8910test: ay8910.o sound.o sndintrf.o
|
||||
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
|
||||
|
||||
Each Volume level x will select a different resistor Rx. Measurements from fpgaarcade.com
|
||||
where used to calibrate channel mixing for the YM2149. This was done using
|
||||
a least square approach using a fixed RL of 1K Ohm.
|
||||
Each Volume level x will select a different resistor Rx. Measurements from
|
||||
fpgaarcade.com were used to calibrate channel mixing for the YM2149. This was
|
||||
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
|
||||
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 changes done:
|
||||
|
||||
Careful studies of the chip output prove that the chip counts up from 0
|
||||
until the counter becomes greater or equal to the period. This is an
|
||||
important difference when the program is rapidly changing the period to
|
||||
modulate the sound. This is worthwhile noting, since the datasheets
|
||||
say, that the chip counts down.
|
||||
Also, note that period = 0 is the same as period = 1. This is mentioned
|
||||
in the YM2203 data sheets. However, this does NOT apply to the Envelope
|
||||
period. In that case, period = 0 is half as period = 1.
|
||||
Careful studies of the chip output prove that the chip counts up from 0 until
|
||||
the counter becomes greater or equal to the period. This is an important
|
||||
difference when the program is rapidly changing the period to modulate the
|
||||
sound. This is worthwhile noting, since the datasheets say, that the chip
|
||||
counts down. Also, note that period = 0 is the same as period = 1. This is
|
||||
mentioned in the YM2203 data sheets. However, this does NOT apply to the
|
||||
Envelope period. In that case, period = 0 is half as period = 1.
|
||||
|
||||
Envelope shapes:
|
||||
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.
|
||||
|
||||
***************************************************************************/
|
||||
#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 "deprecat.h"
|
||||
//#include "deprecat.h"
|
||||
#include "streams.h"
|
||||
//#include "cpuintrf.h"
|
||||
#include "cpuintrf.h"
|
||||
*/
|
||||
#include "sndint.h"
|
||||
#include "ay8910.h"
|
||||
|
||||
// lazyness
|
||||
#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
|
||||
*
|
||||
*************************************/
|
||||
|
||||
#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 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
|
||||
*
|
||||
*************************************/
|
||||
|
@ -166,7 +191,7 @@ struct _ay8910_context
|
|||
int index;
|
||||
int streams;
|
||||
int ready;
|
||||
sound_stream *channel;
|
||||
//sound_stream *channel;
|
||||
const ay8910_interface *intf;
|
||||
INT32 register_latch;
|
||||
UINT8 regs[16];
|
||||
|
@ -216,7 +241,7 @@ static const ay_ym_param ym2149_param_env =
|
|||
1397, 1123, 925, 762, 578, 438, 332, 251 },
|
||||
};
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* RL = 1000, Hacker Kay normalized, 2.1V to 3.2V */
|
||||
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)
|
||||
{
|
||||
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);
|
||||
psg->regs[r] = v;
|
||||
|
||||
switch( r )
|
||||
{
|
||||
switch ( r ) {
|
||||
case AY_AFINE:
|
||||
case AY_ACOARSE:
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
static void ay8910_statesave(ay8910_context *psg, int sndindex)
|
||||
{
|
||||
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->rng);
|
||||
}
|
||||
|
||||
*/
|
||||
/*************************************
|
||||
*
|
||||
* Public functions
|
||||
|
@ -664,8 +689,8 @@ void *ay8910_start_ym(sound_type chip_type, int sndindex, int clock, const ay891
|
|||
{
|
||||
ay8910_context *info;
|
||||
|
||||
info = (ay8910_context*) auto_malloc(sizeof(*info));
|
||||
memset(info, 0, sizeof(*info));
|
||||
info = malloc(sizeof(ay8910_context));
|
||||
memset(info, 0, sizeof(ay8910_context));
|
||||
info->index = sndindex;
|
||||
info->intf = intf;
|
||||
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);
|
||||
|
||||
ay8910_set_clock_ym(info,clock);
|
||||
ay8910_statesave(info, sndindex);
|
||||
//ay8910_statesave(info, sndindex);
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -769,7 +794,7 @@ void ay8910_write_ym(void *chip, int addr, int data)
|
|||
if (r == AY_ESHAPE || psg->regs[r] != data)
|
||||
{
|
||||
/* update the output buffer before changing the register */
|
||||
stream_update(psg->channel);
|
||||
//stream_update(psg->channel);
|
||||
}
|
||||
|
||||
ay8910_write_reg(psg,r,data);
|
||||
|
@ -798,16 +823,16 @@ int ay8910_read_ym(void *chip)
|
|||
*/
|
||||
if (psg->intf->portAread)
|
||||
psg->regs[AY_PORTA] = (*psg->intf->portAread)(Machine, 0);
|
||||
else
|
||||
logerror("PC %04x: warning - read 8910 #%d Port A\n",activecpu_get_pc(),psg->index);
|
||||
//else
|
||||
//logerror("PC %04x: warning - read 8910 #%d Port A\n",activecpu_get_pc(),psg->index);
|
||||
break;
|
||||
case AY_PORTB:
|
||||
if ((psg->regs[AY_ENABLE] & 0x80) != 0)
|
||||
logerror("warning: read from 8910 #%d Port B set as output\n",psg->index);
|
||||
if (psg->intf->portBread)
|
||||
psg->regs[AY_PORTB] = (*psg->intf->portBread)(Machine, 0);
|
||||
else
|
||||
logerror("PC %04x: warning - read 8910 #%d Port B\n",activecpu_get_pc(),psg->index);
|
||||
//else
|
||||
// logerror("PC %04x: warning - read 8910 #%d Port B\n",activecpu_get_pc(),psg->index);
|
||||
break;
|
||||
}
|
||||
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 =
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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 =
|
||||
{
|
||||
|
@ -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);
|
||||
return ay8910_start_ym(SOUND_YM2149, sndindex+16, clock, intf);
|
||||
}
|
||||
}*/
|
||||
|
||||
static void ay8910_stop(void *chip)
|
||||
{
|
||||
|
@ -902,19 +928,34 @@ void ay8912_get_info(void *token, UINT32 state, sndinfo *info)
|
|||
{
|
||||
switch (state)
|
||||
{
|
||||
case SNDINFO_PTR_START: info->start = ay8910_start; break;
|
||||
case SNDINFO_STR_NAME: info->s = "AY-3-8912A"; break;
|
||||
default: ay8910_get_info(token, state, info); break;
|
||||
case SNDINFO_PTR_START:
|
||||
info->start = ay8910_start;
|
||||
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)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SNDINFO_PTR_START: info->start = ay8910_start; break;
|
||||
case SNDINFO_STR_NAME: info->s = "AY-3-8913A"; break;
|
||||
default: ay8910_get_info(token, state, info); break;
|
||||
switch (state) {
|
||||
case SNDINFO_PTR_START:
|
||||
info->start = ay8910_start;
|
||||
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_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)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SNDINFO_PTR_START: info->start = ym2149_start; break;
|
||||
case SNDINFO_STR_NAME: info->s = "YMZ294"; break;
|
||||
default: ay8910_get_info(token, state, info); break;
|
||||
switch (state) {
|
||||
case SNDINFO_PTR_START:
|
||||
info->start = ym2149_start;
|
||||
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_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); }
|
||||
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_2_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data & 0xff); }
|
||||
|
||||
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_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_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); }
|
||||
|
@ -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_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); }
|
||||
|
||||
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__
|
||||
|
||||
//#include "osdcomm.h"
|
||||
#include "mamecore.h"
|
||||
#include "memory.h"
|
||||
//#include "mamecore.h"
|
||||
//#include "memory.h"
|
||||
//typedef UINT32 offs_t;
|
||||
|
||||
//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 ***********/
|
||||
|
||||
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_reset_ym(void *chip);
|
||||
|
|
|
@ -56,6 +56,17 @@ typedef UINT64 FPTR;
|
|||
typedef UINT32 FPTR;
|
||||
#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
|
||||
circular dependencies in the code */
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
#ifndef __MEMORY_H__
|
||||
#define __MEMORY_H__
|
||||
|
||||
|
||||
/*
|
||||
#include "mamecore.h"
|
||||
#include "devintrf.h"
|
||||
#include "tokenize.h"
|
||||
#include "osdcomm.h"
|
||||
|
||||
*/
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
|
|
@ -150,7 +150,8 @@ typedef enum _sound_type sound_type;
|
|||
/* Sound information constants */
|
||||
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_ALIAS = SNDINFO_INT_FIRST, /* R/O: alias to sound type for (type,index) identification */
|
||||
|
|
|
@ -12,15 +12,16 @@
|
|||
#ifndef STREAMS_H
|
||||
#define STREAMS_H
|
||||
|
||||
#include "attotime.h"
|
||||
#include "osdcomm.h"
|
||||
#include "deprecat.h"
|
||||
|
||||
|
||||
#include "mamecore.h"
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
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);
|
||||
|
||||
|
@ -36,6 +37,7 @@ typedef void (*stream_update_func)(void *param, stream_sample_t **inputs, stream
|
|||
/* initialize the streams engine */
|
||||
void streams_init(running_machine *machine, attoseconds_t update_subseconds);
|
||||
|
||||
#endif
|
||||
/* set the tag to be associated with all streams allocated from now on */
|
||||
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