diff --git a/TIKI-100_emul-src/messaudio/Makefile b/TIKI-100_emul-src/messaudio/Makefile index c95f440..2d5f778 100644 --- a/TIKI-100_emul-src/messaudio/Makefile +++ b/TIKI-100_emul-src/messaudio/Makefile @@ -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 diff --git a/TIKI-100_emul-src/messaudio/ay8910.c b/TIKI-100_emul-src/messaudio/ay8910.c index ecd048c..17c9358 100644 --- a/TIKI-100_emul-src/messaudio/ay8910.c +++ b/TIKI-100_emul-src/messaudio/ay8910.c @@ -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 +#include +#include + +// 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: @@ -608,8 +633,8 @@ static void ay8910_update(void *param,stream_sample_t **inputs, stream_sample_t static void build_mixer_table(ay8910_context *psg) { - int normalize = 0; - int chan; + int normalize = 0; + int chan; if ((psg->intf->flags & AY8910_LEGACY_OUTPUT) != 0) { @@ -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; +} + diff --git a/TIKI-100_emul-src/messaudio/ay8910.h b/TIKI-100_emul-src/messaudio/ay8910.h index 03e30c2..7ac93c8 100644 --- a/TIKI-100_emul-src/messaudio/ay8910.h +++ b/TIKI-100_emul-src/messaudio/ay8910.h @@ -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); diff --git a/TIKI-100_emul-src/messaudio/deprecat.h b/TIKI-100_emul-src/messaudio/deprecat.h index 6f32993..2ef3d80 100644 --- a/TIKI-100_emul-src/messaudio/deprecat.h +++ b/TIKI-100_emul-src/messaudio/deprecat.h @@ -10,7 +10,7 @@ ***************************************************************************/ -#pragma once +#pragma once #ifndef __DEPRECAT_H__ #define __DEPRECAT_H__ diff --git a/TIKI-100_emul-src/messaudio/mamecore.h b/TIKI-100_emul-src/messaudio/mamecore.h index 5d3953e..bb7b904 100644 --- a/TIKI-100_emul-src/messaudio/mamecore.h +++ b/TIKI-100_emul-src/messaudio/mamecore.h @@ -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 */ diff --git a/TIKI-100_emul-src/messaudio/memory.h b/TIKI-100_emul-src/messaudio/memory.h index a72b487..ce3ffbe 100644 --- a/TIKI-100_emul-src/messaudio/memory.h +++ b/TIKI-100_emul-src/messaudio/memory.h @@ -14,12 +14,12 @@ #ifndef __MEMORY_H__ #define __MEMORY_H__ - +/* #include "mamecore.h" #include "devintrf.h" #include "tokenize.h" #include "osdcomm.h" - +*/ /*************************************************************************** CONSTANTS ***************************************************************************/ diff --git a/TIKI-100_emul-src/messaudio/sndintrf.h b/TIKI-100_emul-src/messaudio/sndintrf.h index acd2bff..087a969 100644 --- a/TIKI-100_emul-src/messaudio/sndintrf.h +++ b/TIKI-100_emul-src/messaudio/sndintrf.h @@ -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 */ diff --git a/TIKI-100_emul-src/messaudio/streams.h b/TIKI-100_emul-src/messaudio/streams.h index 9d1f262..3f488aa 100644 --- a/TIKI-100_emul-src/messaudio/streams.h +++ b/TIKI-100_emul-src/messaudio/streams.h @@ -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); diff --git a/reference/disk.txt b/reference/disk.txt new file mode 100644 index 0000000..a5ca209 --- /dev/null +++ b/reference/disk.txt @@ -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 + diff --git a/reference/ioporter.txt b/reference/ioporter.txt new file mode 100644 index 0000000..1fb22ee --- /dev/null +++ b/reference/ioporter.txt @@ -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 + diff --git a/reference/lyd.txt b/reference/lyd.txt new file mode 100644 index 0000000..d0d5a2c --- /dev/null +++ b/reference/lyd.txt @@ -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 + diff --git a/palette.png b/reference/palette.png similarity index 100% rename from palette.png rename to reference/palette.png diff --git a/reference/parallell.txt b/reference/parallell.txt new file mode 100644 index 0000000..0447bf2 --- /dev/null +++ b/reference/parallell.txt @@ -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 diff --git a/reference/serie.txt b/reference/serie.txt new file mode 100644 index 0000000..2b09eff --- /dev/null +++ b/reference/serie.txt @@ -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 + diff --git a/reference/sysreg.txt b/reference/sysreg.txt new file mode 100644 index 0000000..0e7dbee --- /dev/null +++ b/reference/sysreg.txt @@ -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 + diff --git a/reference/tastatur.txt b/reference/tastatur.txt new file mode 100644 index 0000000..db41427 --- /dev/null +++ b/reference/tastatur.txt @@ -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 + diff --git a/reference/teller.txt b/reference/teller.txt new file mode 100644 index 0000000..cff5354 --- /dev/null +++ b/reference/teller.txt @@ -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 + diff --git a/tiki100.pal b/reference/tiki100.pal similarity index 100% rename from tiki100.pal rename to reference/tiki100.pal diff --git a/reference/video.txt b/reference/video.txt new file mode 100644 index 0000000..71f2461 --- /dev/null +++ b/reference/video.txt @@ -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 + diff --git a/z80-documented-v0.91.pdf b/reference/z80-documented-v0.91.pdf similarity index 100% rename from z80-documented-v0.91.pdf rename to reference/z80-documented-v0.91.pdf