diff --git a/AtariST/.gitignore b/AtariST/.gitignore new file mode 100644 index 0000000..1ed0e43 --- /dev/null +++ b/AtariST/.gitignore @@ -0,0 +1,4 @@ +*.o +*.a +atarist/ +*.prg diff --git a/AtariST/APORN.gpl b/AtariST/APORN.gpl new file mode 100644 index 0000000..819d453 --- /dev/null +++ b/AtariST/APORN.gpl @@ -0,0 +1,20 @@ +GIMP Palette +Name: APORN +Columns: 16 +# + 73 36 36 Untitled +109 73 36 Untitled +146 73 36 Untitled +146 109 73 Untitled +182 109 73 Untitled +219 109 36 Untitled +182 146 109 Untitled +255 109 73 Untitled +219 146 109 Untitled +255 146 73 Untitled +255 146 109 Untitled +219 182 146 Untitled +255 182 109 Untitled +255 219 146 Untitled +255 219 182 Untitled +255 255 219 Untitled diff --git a/AtariST/BAKURA.gpl b/AtariST/BAKURA.gpl new file mode 100644 index 0000000..e955c2d --- /dev/null +++ b/AtariST/BAKURA.gpl @@ -0,0 +1,20 @@ +GIMP Palette +Name: BAKURA +Columns: 16 +# + 0 0 0 Untitled + 36 36 36 Untitled +109 73 73 Untitled + 73 109 146 Untitled +109 109 146 Untitled +146 109 73 Untitled +182 146 182 Untitled +219 146 73 Untitled +219 146 182 Untitled +146 182 219 Untitled +182 182 182 Untitled +219 182 146 Untitled +219 219 219 Untitled +219 219 255 Untitled +255 219 182 Untitled +255 255 255 Untitled diff --git a/AtariST/DaDither.64.exe b/AtariST/DaDither.64.exe new file mode 100644 index 0000000..d8dd198 Binary files /dev/null and b/AtariST/DaDither.64.exe differ diff --git a/AtariST/LIB.C b/AtariST/LIB.C new file mode 100644 index 0000000..2942530 --- /dev/null +++ b/AtariST/LIB.C @@ -0,0 +1,82 @@ +/************************************************************************/ +/* interface to the MINT kernel because you must not use GEMDOS or BIOS */ +/* calls in an XDD. */ +/* TC calling convention to stay compatible with TC's TCTOSLIB */ +/* Copyright: Dr. Thomas Redelberger, 2000 */ +/* Tab 4 */ +/************************************************************************/ +/* +$Id$ + */ + +#include "filesys.h" +#include "LIB.H" + +extern struct kerinfo *kernel; + +/* can use only kernel entry points in a MINT XDD */ + +int Cconws( const char *buf ) +{ + return (*kernel->dos_tab[0x09])((char*)buf); +} + + +long Dcntl(short a, long b, long c) +{ + return (*kernel->dos_tab[0x130])((short)a, (long)b, (long)c); +} + +int Tgettime(void) +{ + return (*kernel->dos_tab[0x2c])(); +} + + +int Tgetdate(void) +{ + return (*kernel->dos_tab[0x2a])(); +} + + +int Fcreate(char* a, short b) +{ + return (*kernel->dos_tab[0x3c])((char*)a, (short)b); +} + + +int Fopen(char* a, short b) +{ + return (*kernel->dos_tab[0x3d])((char*)a, (short)b); +} + + +int Fclose(short a) +{ + return (*kernel->dos_tab[0x3e])((short)a); +} + + +long Fread(short a, long b, char* c) +{ + return (*kernel->dos_tab[0xef])((short)a, (long)b, (char*)c); +} + + +long Fwrite(short a, long b, char* c) +{ + return (*kernel->dos_tab[0x40])((short)a, (long)b, (char*)c); +} + + +int Fdelete(char* a) +{ + return (*kernel->dos_tab[0x41])((char*)a); +} + + +int Fseek(long a, int b, int c) +{ + return (*kernel->dos_tab[0x42])((long)a, (int)b, (int)c); +} + diff --git a/AtariST/LIB.H b/AtariST/LIB.H new file mode 100644 index 0000000..1987648 --- /dev/null +++ b/AtariST/LIB.H @@ -0,0 +1,53 @@ +/************************************************************************/ +/* interface to the MINT kernel because you must nor use GEMDOS or BIOS */ +/* calls in an XDD */ +/* Copyright: Dr. Thomas Redelberger, 2000 */ +/* Tab 4 */ +/************************************************************************/ +/* +$Id$ + */ + +/* referenced by transport.h */ +typedef struct +{ + char d_reserved[21]; + unsigned char d_attrib; + unsigned int d_time; + unsigned int d_date; + unsigned long d_length; + char d_fname[14]; +} DTA; +typedef struct baspag +{ + void *p_lowtpa; + void *p_hitpa; + void *p_tbase; + long p_tlen; + void *p_dbase; + long p_dlen; + void *p_bbase; + long p_blen; + DTA *p_dta; + struct baspag *p_parent; + long p_resrvd0; + char *p_env; + char p_stdfh[6]; + char p_resrvd1; + char p_curdrv; + long p_resrvd2[18]; + char p_cmdlin[128]; +} BASPAG; + + +int Cconws( const char *buf ); +long Dcntl(short a, long b, long c); +int Tgettime(void); +int Tgetdate(void); +int Fcreate(char* a, short b); +int Fopen(char* a, short b); +int Fclose(short a); +long Fread(short a, long b, char* c); +long Fwrite(short a, long b, char* c); +int Fdelete(char* a); +int Fseek(long a, int b, int c); diff --git a/AtariST/LICENSE b/AtariST/LICENSE new file mode 100644 index 0000000..368a92a --- /dev/null +++ b/AtariST/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016/2018/2019 by Matthias Arndt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/AtariST/Makefile b/AtariST/Makefile new file mode 100644 index 0000000..ee2e03f --- /dev/null +++ b/AtariST/Makefile @@ -0,0 +1,27 @@ +CC=m68k-atari-mint-gcc +AS=m68k-atari-mint-gcc +AR=m68k-atari-mint-ar +RANLIB=m68k-atari-mint-ranlib + +CFLAGS=-Isrc -m68000 -O2 -fomit-frame-pointer -Wextra -Wall -std=c99 -nostdlib +ASFLAGS=-m68000 +ARFLAGS=cr +LDFLAGS= -Wl,--as-needed -s +TARGET=main.prg +ASM_SRC = ikbd.S jagpad.S atari_dma_sound.S lz4w.S +C_SRC = main.c keys.c psg.c dma_atari.c psgpcm.c atarist.c fonts.c + +all: $(TARGET) + +%.S.o: %.S + $(AS) $(ASFLAGS) -o $@ -c $< + +%.c.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + + +$(TARGET): startup.S $(C_SRC:.c=.c.o) $(ASM_SRC:.S=.S.o) + $(CC) $(CFLAGS) $^ -o $@ $(LIBS) $(LDFLAGS) + +clean: + rm -f *.o *.d $(LIBS) $(TARGET) diff --git a/AtariST/README.md b/AtariST/README.md new file mode 100644 index 0000000..65674d8 --- /dev/null +++ b/AtariST/README.md @@ -0,0 +1,18 @@ +# Paradize ST Sprite Kernel ported to gcc + +(c) 2016/2018/2019 by Matthias Arndt + +The MIT License applies to this software. Please refer to the file LICENSE for +further details. + +## Abstract + +This is a port of the Paradize ST Sprite Kernel to a GCC environment. +The original kernel was intended for use with GFABASIC and put into action with +the game "Attackwave" in 2009. + +The kernl allows handling of basic masked sprites on ST-Low screen without clipping. + +## Requirements +... + diff --git a/AtariST/RIK.png b/AtariST/RIK.png new file mode 100644 index 0000000..c6475f2 Binary files /dev/null and b/AtariST/RIK.png differ diff --git a/AtariST/RIKL.png b/AtariST/RIKL.png new file mode 100644 index 0000000..accc92d Binary files /dev/null and b/AtariST/RIKL.png differ diff --git a/AtariST/RIKN.png b/AtariST/RIKN.png new file mode 100644 index 0000000..3358858 Binary files /dev/null and b/AtariST/RIKN.png differ diff --git a/AtariST/TITLE b/AtariST/TITLE new file mode 100644 index 0000000..010e864 Binary files /dev/null and b/AtariST/TITLE differ diff --git a/AtariST/TITLE.PAL b/AtariST/TITLE.PAL new file mode 100644 index 0000000..0915ee6 Binary files /dev/null and b/AtariST/TITLE.PAL differ diff --git a/AtariST/TITLE.PNG b/AtariST/TITLE.PNG new file mode 100644 index 0000000..57e6f44 Binary files /dev/null and b/AtariST/TITLE.PNG differ diff --git a/AtariST/TITLE.RAW b/AtariST/TITLE.RAW new file mode 100644 index 0000000..bb73472 Binary files /dev/null and b/AtariST/TITLE.RAW differ diff --git a/AtariST/TITLE.lz b/AtariST/TITLE.lz new file mode 100644 index 0000000..75245b9 Binary files /dev/null and b/AtariST/TITLE.lz differ diff --git a/AtariST/TITLE.pi1 b/AtariST/TITLE.pi1 new file mode 100644 index 0000000..d7b311e Binary files /dev/null and b/AtariST/TITLE.pi1 differ diff --git a/AtariST/aplib.S b/AtariST/aplib.S new file mode 100644 index 0000000..9577351 --- /dev/null +++ b/AtariST/aplib.S @@ -0,0 +1,119 @@ +| unaplib_68000.s - aPLib decompressor for 68000 - 156 bytes +| in: a0 = start of compressed data +| a1 = start of decompression buffer +| out: d0 = decompressed size +| Copyright (C) 2020 Emmanuel Marty +| With parts of the code inspired by Franck "hitchhikr" Charlet +| This software is provided 'as-is', without any express or implied +| warranty. In no event will the authors be held liable for any damages +| arising from the use of this software. +| Permission is granted to anyone to use this software for any purpose, +| including commercial applications, and to alter it and redistribute it +| freely, subject to the following restrictions: +| 1. The origin of this software must not be misrepresented| you must not +| claim that you wrote the original software. If you use this software +| in a product, an acknowledgment in the product documentation would be +| appreciated but is not required. +| 2. Altered source versions must be plainly marked as such, and must not be +| misrepresented as being the original software. +| 3. This notice may not be removed or altered from any source distribution. + +.global apl_decompress +.global apl_decompress_ +.global _apl_decompress + +apl_decompress_: +_apl_decompress: +apl_decompress: + movem.l a2-a6/d2-d3,-(sp) + + moveq #-128,d1 | initialize empty bit queue + | plus bit to roll into carry + lea 32000.w,a2 | load 32000 offset constant + lea 1280.w,a3 | load 1280 offset constant + lea 128.w,a4 | load 128 offset constant + move.l a1,a5 | save destination pointer + +.literal: move.b (a0)+,(a1)+ | copy literal byte +.after_lit: moveq #3,d2 | set LWM flag + +.next_token: bsr.s .get_bit | read 'literal or match' bit + bcc.s .literal | if 0: literal + + bsr.s .get_bit | read '8+n bits or other type' bit + bcs.s .other_match | if 11x: other type of match + + bsr.s .get_gamma2 | 10: read gamma2-coded high offset bits + sub.l d2,d0 | high offset bits == 2 when LWM == 3 ? + bcc.s .no_repmatch | if not, not a rep-match + + bsr.s .get_gamma2 | read repmatch length + bra.s .got_len | go copy large match + +.no_repmatch: lsl.l #8,d0 | shift high offset bits into place + move.b (a0)+,d0 | read low offset byte + move.l d0,d3 | copy offset into d3 + + bsr.s .get_gamma2 | read match length + cmp.l a2,d3 | offset >= 32000 ? + bge.s .inc_by_2 | if so, increase match len by 2 + cmp.l a3,d3 | offset >= 1280 ? + bge.s .inc_by_1 | if so, increase match len by 1 + cmp.l a4,d3 | offset < 128 ? + bge.s .got_len | if so, increase match len by 2 +.inc_by_2: addq.l #1,d0 | increase match len by 1 +.inc_by_1: addq.l #1,d0 | increase match len by 1 + +.got_len: move.l a1,a6 | calculate backreference address + sub.l d3,a6 | (dest - match offset) + subq.l #1,d0 | dbf will loop until d0 is -1, not 0 +.copy_match: move.b (a6)+,(a1)+ | copy matched byte + dbf d0,.copy_match | loop for all matched bytes + moveq #2,d2 | clear LWM flag + bra.s .next_token | go decode next token + +.other_match: bsr.s .get_bit | read '7+1 match or short literal' bit + bcs.s .short_match | if 111: 4 bit offset for 1-byte copy + + moveq #1,d0 | 110: prepare match length + moveq #0,d3 | clear high bits of offset + move.b (a0)+,d3 | read low bits of offset + length bit + lsr.b #1,d3 | shift offset into place, len into carry + beq.s .done | check for EOD + addx.b d0,d0 | len = (1 << 1) + carry bit, ie. 2 or 3 + bra.s .got_len | go copy match + +.short_match: moveq #0,d0 | clear short offset before reading 4 bits + bsr.s .get_dibits | read a data bit into d0, one into carry + addx.b d0,d0 | shift second bit into d0 + bsr.s .get_dibits | read a data bit into d0, one into carry + addx.b d0,d0 | shift second bit into d0 + tst.b d0 | check offset value + beq.s .write_zero | if offset is zero, write a 0 + + move.l a1,a6 | calculate backreference address + sub.l d0,a6 | (dest - short offset) + move.b (a6),d0 | read matched byte +.write_zero: move.b d0,(a1)+ | write matched byte or 0 + bra.s .after_lit | set LWM flag and go decode next token + +.done: move.l a1,d0 | pointer to last decompressed byte + 1 + sub.l a6,d0 | minus start of decompression buffer = size + movem.l (sp)+,a2-a6/d2-d3 + rts + +.get_gamma2: moveq #1,d0 | init to 1 so it gets shifted to 2 below +.gamma2_loop: bsr.s .get_dibits | read data bit, shift into d0 + | and read continuation bit + bcs.s .gamma2_loop | loop until a 0 continuation bit is read + rts + +.get_dibits: bsr.s .get_bit | read bit + addx.l d0,d0 | shift into d0 + | fall through +.get_bit: add.b d1,d1 | shift bit queue, high bit into carry + bne.s .got_bit | queue not empty, bits remain + move.b (a0)+,d1 | read 8 new bits + addx.b d1,d1 | shift bit queue, high bit into carry + | and shift 1 from carry into bit queue +.got_bit: rts diff --git a/AtariST/atari_dma_sound.S b/AtariST/atari_dma_sound.S new file mode 100644 index 0000000..459b29c --- /dev/null +++ b/AtariST/atari_dma_sound.S @@ -0,0 +1,85 @@ + .text + + .globl _set_dma_sound + .globl _stop_dma_sound + .globl _set_dma_sound_noloop + +_set_dma_sound: + movem.l d5-d6,-(sp) + move.l 16(sp),d6 + move.l 12(sp),d5 + add.l d5,d6 + + pea setdma(pc) + move #38,-(sp) + trap #14 + addq.l #6,sp + + movem.l (sp)+,d5-d6 + rts + +_set_dma_sound_noloop: + movem.l d5-d6,-(sp) + move.l 16(sp),d6 + move.l 12(sp),d5 + add.l d5,d6 + + pea setdma_noloop(pc) + move #38,-(sp) + trap #14 + addq.l #6,sp + + movem.l (sp)+,d5-d6 + rts + +_stop_dma_sound: + clr.b 0xFFFF8901 + rts + +setdmaaddrsub: + swap d1 + move.b d1,1(a0) + swap d1 + clr.l d2 + move.b d1,d2 + lsr.w #8,d1 + move.b d1,3(a0) + move.b d2,5(a0) + rts + +setdma: + clr.b 0xFFFF8901.w + move.l d5,d1 + lea 0xFFFF8902.w,a0 + bsr.s setdmaaddrsub + + move.l d6,d1 + lea 12(a0),a0 + bsr.s setdmaaddrsub + + + moveq.l #1,d0 + ori.b #0x80,d0 + move.b d0,0xFFFF8921.w + + move.b #3,0xFFFF8901.w + rts + + +setdma_noloop: + clr.b 0xFFFF8901.w + move.l d5,d1 + lea 0xFFFF8902.w,a0 + bsr.s setdmaaddrsub + + move.l d6,d1 + lea 12(a0),a0 + bsr.s setdmaaddrsub + + + moveq.l #1,d0 + ori.b #0x80,d0 + move.b d0,0xFFFF8921.w + + move.b #1,0xFFFF8901.w + rts diff --git a/AtariST/atarist.c b/AtariST/atarist.c new file mode 100644 index 0000000..5203560 --- /dev/null +++ b/AtariST/atarist.c @@ -0,0 +1,240 @@ +#include +#include +#include +#include +#include +#include "ikbd.h" +#include "stsprite.h" +#include "wizzcat.h" +#include "sound.h" +#include "atarist.h" + +uint32_t isSoundDMA = 0; + +uint16_t system_pal[16]; +uint16_t savepal[16]; + +extern SoundDevice mainsound; + +#define PRINT(x) (void)Cconws(x) + + +#define COLOR_REG_BASE 0xff8240 +static void Save_HWPalette() +{ + volatile uint16_t* colorReg = (uint16_t*)COLOR_REG_BASE; + for (uint8_t i = 0; i < 16; i++) { savepal[i] = colorReg[i]; } +} + + +typedef struct +{ + uint32_t magic ; + uint32_t data ; +} COOKIE; + +static COOKIE *cookie_jar(void) +{ + COOKIE *cookie ; + cookie = *(COOKIE**) 0x5A0 ; + return(cookie) ; +} + +static COOKIE *cookie_find(char ident[4]) +{ + COOKIE *cookie ; + uint32_t magic ; + + ((char*)&magic)[0] = ident[0]; + ((char*)&magic)[1] = ident[1]; + ((char*)&magic)[2] = ident[2]; + ((char*)&magic)[3] = ident[3]; + + cookie = cookie_jar() ; + if (cookie == NULL) return(cookie) ; + while (cookie->magic != 0) + { + if (cookie->magic == magic) break; + cookie++ ; + } + + if (cookie->magic == 0) cookie = NULL ; + return(cookie) ; +} + + +void Init_Machine() +{ + COOKIE* is_cookie_mch = cookie_find("_MCH"); + isSoundDMA = 0; + mainsound = PSGPCM_device; + if (is_cookie_mch->data != 0) + { + isSoundDMA = 1; + mainsound = DMA_device; + } + + Save_HWPalette(); + + IKBD_Install(); + IKBD_MouseOn(); +} + +void Close_Machine() +{ + //Cconin(); + + // Restore palette + Setpalette(savepal); + + mainsound.Stop_Sound(); + mainsound.Uninit_Sound(); + + IKBD_Flush(); + IKBD_Uninstall(); +} + +unsigned char Load_Degas_PAL(char* path) +{ + short fp; + + // Open the file + fp = Fopen(path, 0); + if (fp < 0) { + return 1; + } + + // Skip the first 2 bytes + Fseek(2, fp, 0); + + // Read palette + Fread(fp, 32, system_pal); + Setpalette(system_pal); + + // Close the file + Fclose(fp); + + return 0; +} + + +unsigned char* Load_Degas(char* path, uint8_t loadpal) +{ + short fp; + unsigned char* data; + + // Open the file + fp = Fopen(path, 0); + if (fp < 0) { + return NULL; + } + + Fseek(2, fp, 0); + + Fread(fp, 32, system_pal); + if (loadpal) Setpalette(system_pal); + + // Allocate memory for data + data = (unsigned char *)Malloc(32000); + if (data == NULL) { + Fclose(fp); + return NULL; + } + + Fseek(34, fp, 0); + + // Read the image data + Fread(fp, 16000, data); + Fread(fp, 16000, data + 16000); + + // Close the file + Fclose(fp); + + return data; +} + +unsigned char Load_Pal(char* path) +{ + short fp; + + // Open the file + fp = Fopen(path, 0); + if (fp < 0) { + return 1; + } + + // Read palette + Fread(fp, 32, system_pal); + Setpalette(system_pal); + + // Close the file + Fclose(fp); + + return 0; +} + +#define CHUNK_SIZE 16000 + +unsigned char* Load_Data(const char* path, int32_t size) +{ + unsigned short handle; + unsigned char* data; + int32_t read_size = 0; + + handle = Fopen(path, 0); + data = (unsigned char *)Malloc(size); + + // Read the file in chunks + while(read_size < size) { + int32_t current_chunk_size = CHUNK_SIZE; + + // If the remaining size is less than the chunk size, adjust the current chunk size + if(size - read_size < CHUNK_SIZE) { + current_chunk_size = size - read_size; + } + + Fread(handle, current_chunk_size, data + read_size); + //gemdos(63, handle, current_chunk_size, data + read_size); + read_size += current_chunk_size; + } + + Fclose(handle); + + return data; +} + +void Free_Data(unsigned char* data) +{ + if (data) + { + Mfree(data); + data = NULL; + } +} + +void* memset __P ((void* __s, int __c, size_t __n)) +{ + uint32_t *dest = (uint32_t *)(__s); + __n = __n >> 2; + + while (__n--) { + *dest++ = __c; + } + return dest; +} + + +// Generic memcpy + +void* memcpy __P ((void* __dest, const void* __src, size_t __n)) +{ + uint32_t *src = (uint32_t *)(__src); + uint32_t *dest = (uint32_t *)(__dest); + __n = __n >> 2; + + while (__n--) { + *dest++ = *src++; + } + return dest; +} + diff --git a/AtariST/atarist.h b/AtariST/atarist.h new file mode 100644 index 0000000..48725ac --- /dev/null +++ b/AtariST/atarist.h @@ -0,0 +1,47 @@ +#ifndef ATARIST_H +#define ATARIST_H + +#include +#include +#include +#include +#include +#include "ikbd.h" +#include "stsprite.h" +#include "wizzcat.h" +#include "sound.h" + +extern uint32_t init_mode; +extern uint32_t isSoundDMA; + +#define NR_SPRITES 16 +extern st_sprite_t spr[NR_SPRITES]; + +extern unsigned int lz4w_unpack(void * source, void *destination); + +extern unsigned char* Load_Data(const char* path, int32_t size); +extern unsigned char Load_Degas_PAL(char* path); + +#define COPY_DATA(src, dest, nr_longs) \ + do { \ + uint32_t *src_ptr = (uint32_t *)(src); \ + uint32_t *dest_ptr = (uint32_t *)(dest); \ + uint16_t count = (nr_longs); \ + while (count--) { \ + *dest_ptr++ = *src_ptr++; \ + } \ + } while(0) + +extern void Init_Machine(); + +extern void Close_Machine(); + +extern unsigned char* Load_Degas(char* path, uint8_t loadpal); +extern unsigned char Load_Pal(char* path); + +extern void drawChar(char ch, unsigned short x, unsigned short y, unsigned char color_index); +extern void Draw_Text_Center(const char* str, unsigned short y, unsigned short color_index); +extern void Draw_Text(const char* str, unsigned short x, unsigned short y, unsigned short color_index); +extern void Free_Data(unsigned char* data); + +#endif diff --git a/AtariST/challenge.mod b/AtariST/challenge.mod new file mode 100644 index 0000000..52c3c5b Binary files /dev/null and b/AtariST/challenge.mod differ diff --git a/AtariST/convert.sh b/AtariST/convert.sh new file mode 100755 index 0000000..b839a89 --- /dev/null +++ b/AtariST/convert.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# input file +infile="$1" + +# output file for stripped data +outfile="$2" + +# output file for palette +palette_file="$3" + +# strip out the first 34 bytes, starting from 3rd byte +dd if="$infile" of="$outfile" bs=1 skip=34 + +# extract the first 32 bytes after the 2nd byte +dd if="$infile" of="$palette_file" bs=1 skip=2 count=32 + +# run lz4w.jar +java -jar lz4w.jar p "$outfile" "${outfile}.lz" diff --git a/AtariST/data.S b/AtariST/data.S new file mode 100644 index 0000000..d13d249 --- /dev/null +++ b/AtariST/data.S @@ -0,0 +1,20 @@ +.globl _VFastCopy128 + +_VFastCopy128: + move.l #19,d0 +.copy: + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + dbra d0,.copy + rts + + + + +.end diff --git a/AtariST/dma_atari.c b/AtariST/dma_atari.c new file mode 100644 index 0000000..d49e06c --- /dev/null +++ b/AtariST/dma_atari.c @@ -0,0 +1,121 @@ +/** @file src/audio/dsp_atari.c Atari DMA Sound implementation of the DSP. */ + +#include +#include +#include +#include +#include +#include "sound.h" + +typedef struct tagS +{ + unsigned char* data; + unsigned long size; +} SOUND; + + +/* STE/TT/Falcon DMA Sound is able to play at : + * 50066Hz 25033Hz 12517Hz 6258Hz + * (6258Hz is not available on falcon) */ +#define DMASOUND_FREQ 12517 +#define DMASOUND_BUFFER_SIZE 48182 + + +extern void set_dma_sound(void * buffer, unsigned int len); +extern void set_dma_sound_noloop(void * buffer, unsigned int len); +extern void stop_dma_sound(void); /* needs to be called in supervisor mode */ +//extern unsigned int get_dma_status(void); /* needs to be called in supervisor mode */ + +static unsigned char *s_stRamBuffer; +static uint32_t s_stRamBufferSize; + +static SOUND snd[4]; + +static inline void memset32(void *ptr, uint32_t value, size_t num) { + uint32_t* p = (uint32_t*) ptr; + while(num--) { + *p++ = value; + } +} + +static void DMA_free(uint8_t index) +{ + if (snd[index].data) Mfree(snd[index].data); +} + +void DMA_Stop(void) +{ + Supexec(stop_dma_sound); +} + +void DMA_Load(const char* path, uint8_t index) +{ + int fp; + unsigned short handle; + + DMA_Stop(); + DMA_free(index); + + fp = Fopen(path, 0); + Fseek(0, fp, SEEK_END); + handle = fp & 0xFFFF; + snd[index].size = Fseek(0, handle, 2); + Fseek(0, handle, 0); + snd[index].data = (unsigned char *)Malloc(snd[index].size); + Fread(handle, snd[index].size, snd[index].data); + Fclose(handle); +} + + + + +void DMA_Uninit(void) +{ + uint8_t i; + + DMA_Stop(); + if (s_stRamBuffer) + { + Mfree(s_stRamBuffer); + s_stRamBuffer = NULL; + } + s_stRamBufferSize = 0; + + for(i=0;i<4;i++) + DMA_free(i); + +} + +uint8_t DMA_Init(void) +{ + /* allocate ST RAM buffer for audio */ + s_stRamBufferSize = DMASOUND_BUFFER_SIZE; + s_stRamBuffer = (unsigned char *)Malloc(s_stRamBufferSize); + if(!s_stRamBuffer) { + s_stRamBufferSize = 0; + return 0; + } + return 1; +} + +void DMA_Play(unsigned char loop, uint8_t index) +{ + //memset32(s_stRamBuffer, 0, DMADMA_BUFFER_SIZE); + DMA_Stop(); + + if (loop == 1) + set_dma_sound(snd[index].data, snd[index].size); + + if (loop == 0) + set_dma_sound_noloop(snd[index].data, snd[index].size); +} + + +SoundDevice DMA_device = { + DMA_Init, + DMA_Uninit, + DMA_Load, + DMA_Play, + DMA_Stop +}; + diff --git a/AtariST/fonts.c b/AtariST/fonts.c new file mode 100644 index 0000000..4ce1e03 --- /dev/null +++ b/AtariST/fonts.c @@ -0,0 +1,338 @@ +#include +#include +extern void * physbase; + +size_t strlen (const char *str) +{ + for (size_t len = 0; ; ++str, ++len) { if (!*str) return len; } +} + + +unsigned char std_font[] = /* NSDL_FONT_VGA */ +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 000 (.) + 0x7E, 0x81, 0xA5, 0x81, 0xBD, 0x99, 0x81, 0x7E, // Char 001 (.) + 0x7E, 0xFF, 0xDB, 0xFF, 0xC3, 0xE7, 0xFF, 0x7E, // Char 002 (.) + 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00, // Char 003 (.) + 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00, // Char 004 (.) + 0x38, 0x7C, 0x38, 0xFE, 0xFE, 0x7C, 0x38, 0x7C, // Char 005 (.) + 0x10, 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x7C, // Char 006 (.) + 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, // Char 007 (.) + 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF, // Char 008 (.) + 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00, // Char 009 (.) + 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF, // Char 010 (.) + 0x0F, 0x07, 0x0F, 0x7D, 0xCC, 0xCC, 0xCC, 0x78, // Char 011 (.) + 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x7E, 0x18, // Char 012 (.) + 0x3F, 0x33, 0x3F, 0x30, 0x30, 0x70, 0xF0, 0xE0, // Char 013 (.) + 0x7F, 0x63, 0x7F, 0x63, 0x63, 0x67, 0xE6, 0xC0, // Char 014 (.) + 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99, // Char 015 (.) + 0x80, 0xE0, 0xF8, 0xFE, 0xF8, 0xE0, 0x80, 0x00, // Char 016 (.) + 0x02, 0x0E, 0x3E, 0xFE, 0x3E, 0x0E, 0x02, 0x00, // Char 017 (.) + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x7E, 0x3C, 0x18, // Char 018 (.) + 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00, // Char 019 (.) + 0x7F, 0xDB, 0xDB, 0x7B, 0x1B, 0x1B, 0x1B, 0x00, // Char 020 (.) + 0x3E, 0x63, 0x38, 0x6C, 0x6C, 0x38, 0xCC, 0x78, // Char 021 (.) + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x7E, 0x00, // Char 022 (.) + 0x18, 0x3C, 0x7E, 0x18, 0x7E, 0x3C, 0x18, 0xFF, // Char 023 (.) + 0x18, 0x3C, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 024 (.) + 0x18, 0x18, 0x18, 0x18, 0x7E, 0x3C, 0x18, 0x00, // Char 025 (.) + 0x00, 0x18, 0x0C, 0xFE, 0x0C, 0x18, 0x00, 0x00, // Char 026 (.) + 0x00, 0x30, 0x60, 0xFE, 0x60, 0x30, 0x00, 0x00, // Char 027 (.) + 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xFE, 0x00, 0x00, // Char 028 (.) + 0x00, 0x24, 0x66, 0xFF, 0x66, 0x24, 0x00, 0x00, // Char 029 (.) + 0x00, 0x18, 0x3C, 0x7E, 0xFF, 0xFF, 0x00, 0x00, // Char 030 (.) + 0x00, 0xFF, 0xFF, 0x7E, 0x3C, 0x18, 0x00, 0x00, // Char 031 (.) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 032 ( ) + 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00, // Char 033 (!) + 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 034 (") + 0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, // Char 035 (#) + 0x30, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x30, 0x00, // Char 036 ($) + 0x00, 0xC6, 0xCC, 0x18, 0x30, 0x66, 0xC6, 0x00, // Char 037 (%) + 0x38, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0x76, 0x00, // Char 038 (&) + 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 039 (') + 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00, // Char 040 (() + 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00, // Char 041 ()) + 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // Char 042 (*) + 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0x00, // Char 043 (+) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60, // Char 044 (,) + 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, // Char 045 (-) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, // Char 046 (.) + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, // Char 047 (/) + 0x7C, 0xC6, 0xCE, 0xDE, 0xF6, 0xE6, 0x7C, 0x00, // Char 048 (0) + 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xFC, 0x00, // Char 049 (1) + 0x78, 0xCC, 0x0C, 0x38, 0x60, 0xCC, 0xFC, 0x00, // Char 050 (2) + 0x78, 0xCC, 0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, // Char 051 (3) + 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x1E, 0x00, // Char 052 (4) + 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC, 0x78, 0x00, // Char 053 (5) + 0x38, 0x60, 0xC0, 0xF8, 0xCC, 0xCC, 0x78, 0x00, // Char 054 (6) + 0xFC, 0xCC, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, // Char 055 (7) + 0x78, 0xCC, 0xCC, 0x78, 0xCC, 0xCC, 0x78, 0x00, // Char 056 (8) + 0x78, 0xCC, 0xCC, 0x7C, 0x0C, 0x18, 0x70, 0x00, // Char 057 (9) + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00, // Char 058 (:) + 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60, // Char 059 (;) + 0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, // Char 060 (<) + 0x00, 0x00, 0xFC, 0x00, 0x00, 0xFC, 0x00, 0x00, // Char 061 (=) + 0x60, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x60, 0x00, // Char 062 (>) + 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00, 0x30, 0x00, // Char 063 (?) + 0x7C, 0xC6, 0xDE, 0xDE, 0xDE, 0xC0, 0x78, 0x00, // Char 064 (@) + 0x30, 0x78, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0x00, // Char 065 (A) + 0xFC, 0x66, 0x66, 0x7C, 0x66, 0x66, 0xFC, 0x00, // Char 066 (B) + 0x3C, 0x66, 0xC0, 0xC0, 0xC0, 0x66, 0x3C, 0x00, // Char 067 (C) + 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, // Char 068 (D) + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x62, 0xFE, 0x00, // Char 069 (E) + 0xFE, 0x62, 0x68, 0x78, 0x68, 0x60, 0xF0, 0x00, // Char 070 (F) + 0x3C, 0x66, 0xC0, 0xC0, 0xCE, 0x66, 0x3E, 0x00, // Char 071 (G) + 0xCC, 0xCC, 0xCC, 0xFC, 0xCC, 0xCC, 0xCC, 0x00, // Char 072 (H) + 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, // Char 073 (I) + 0x1E, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00, // Char 074 (J) + 0xE6, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0xE6, 0x00, // Char 075 (K) + 0xF0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, // Char 076 (L) + 0xC6, 0xEE, 0xFE, 0xFE, 0xD6, 0xC6, 0xC6, 0x00, // Char 077 (M) + 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0xC6, 0x00, // Char 078 (N) + 0x38, 0x6C, 0xC6, 0xC6, 0xC6, 0x6C, 0x38, 0x00, // Char 079 (O) + 0xFC, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0, 0x00, // Char 080 (P) + 0x78, 0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x1C, 0x00, // Char 081 (Q) + 0xFC, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0xE6, 0x00, // Char 082 (R) + 0x78, 0xCC, 0xE0, 0x70, 0x1C, 0xCC, 0x78, 0x00, // Char 083 (S) + 0xFC, 0xB4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, // Char 084 (T) + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xFC, 0x00, // Char 085 (U) + 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, // Char 086 (V) + 0xC6, 0xC6, 0xC6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00, // Char 087 (W) + 0xC6, 0xC6, 0x6C, 0x38, 0x38, 0x6C, 0xC6, 0x00, // Char 088 (X) + 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x78, 0x00, // Char 089 (Y) + 0xFE, 0xC6, 0x8C, 0x18, 0x32, 0x66, 0xFE, 0x00, // Char 090 (Z) + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00, // Char 091 ([) + 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x02, 0x00, // Char 092 (\) + 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, // Char 093 (]) + 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, // Char 094 (^) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // Char 095 (_) + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 096 (`) + 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x76, 0x00, // Char 097 (a) + 0xE0, 0x60, 0x60, 0x7C, 0x66, 0x66, 0xDC, 0x00, // Char 098 (b) + 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00, // Char 099 (c) + 0x1C, 0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0x76, 0x00, // Char 100 (d) + 0x00, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, // Char 101 (e) + 0x38, 0x6C, 0x60, 0xF0, 0x60, 0x60, 0xF0, 0x00, // Char 102 (f) + 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, // Char 103 (g) + 0xE0, 0x60, 0x6C, 0x76, 0x66, 0x66, 0xE6, 0x00, // Char 104 (h) + 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, // Char 105 (i) + 0x0C, 0x00, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, // Char 106 (j) + 0xE0, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0xE6, 0x00, // Char 107 (k) + 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, // Char 108 (l) + 0x00, 0x00, 0xCC, 0xFE, 0xFE, 0xD6, 0xC6, 0x00, // Char 109 (m) + 0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, // Char 110 (n) + 0x00, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, // Char 111 (o) + 0x00, 0x00, 0xDC, 0x66, 0x66, 0x7C, 0x60, 0xF0, // Char 112 (p) + 0x00, 0x00, 0x76, 0xCC, 0xCC, 0x7C, 0x0C, 0x1E, // Char 113 (q) + 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0xF0, 0x00, // Char 114 (r) + 0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0xF8, 0x00, // Char 115 (s) + 0x10, 0x30, 0x7C, 0x30, 0x30, 0x34, 0x18, 0x00, // Char 116 (t) + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, // Char 117 (u) + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x00, // Char 118 (v) + 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0xFE, 0x6C, 0x00, // Char 119 (w) + 0x00, 0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, // Char 120 (x) + 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, // Char 121 (y) + 0x00, 0x00, 0xFC, 0x98, 0x30, 0x64, 0xFC, 0x00, // Char 122 (z) + 0x1C, 0x30, 0x30, 0xE0, 0x30, 0x30, 0x1C, 0x00, // Char 123 ({) + 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, // Char 124 (|) + 0xE0, 0x30, 0x30, 0x1C, 0x30, 0x30, 0xE0, 0x00, // Char 125 (}) + 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Char 126 (~) + 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0x00, // Char 127 (.) + 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x18, 0x0C, 0x78, // Char 128 (.) + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, // Char 129 (.) + 0x1C, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, // Char 130 (.) + 0x7E, 0xC3, 0x3C, 0x06, 0x3E, 0x66, 0x3F, 0x00, // Char 131 (.) + 0xCC, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, // Char 132 (.) + 0xE0, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, // Char 133 (.) + 0x30, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, // Char 134 (.) + 0x00, 0x00, 0x78, 0xC0, 0xC0, 0x78, 0x0C, 0x38, // Char 135 (.) + 0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, // Char 136 (.) + 0xCC, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, // Char 137 (.) + 0xE0, 0x00, 0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, // Char 138 (.) + 0xCC, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, // Char 139 (.) + 0x7C, 0xC6, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, // Char 140 (.) + 0xE0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, // Char 141 (.) + 0xC6, 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, // Char 142 (.) + 0x30, 0x30, 0x00, 0x78, 0xCC, 0xFC, 0xCC, 0x00, // Char 143 (.) + 0x1C, 0x00, 0xFC, 0x60, 0x78, 0x60, 0xFC, 0x00, // Char 144 (.) + 0x00, 0x00, 0x7F, 0x0C, 0x7F, 0xCC, 0x7F, 0x00, // Char 145 (.) + 0x3E, 0x6C, 0xCC, 0xFE, 0xCC, 0xCC, 0xCE, 0x00, // Char 146 (.) + 0x78, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, // Char 147 (.) + 0x00, 0xCC, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, // Char 148 (.) + 0x00, 0xE0, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, // Char 149 (.) + 0x78, 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, // Char 150 (.) + 0x00, 0xE0, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, // Char 151 (.) + 0x00, 0xCC, 0x00, 0xCC, 0xCC, 0x7C, 0x0C, 0xF8, // Char 152 (.) + 0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, // Char 153 (.) + 0xCC, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00, // Char 154 (.) + 0x18, 0x18, 0x7E, 0xC0, 0xC0, 0x7E, 0x18, 0x18, // Char 155 (.) + 0x38, 0x6C, 0x64, 0xF0, 0x60, 0xE6, 0xFC, 0x00, // Char 156 (.) + 0xCC, 0xCC, 0x78, 0xFC, 0x30, 0xFC, 0x30, 0x30, // Char 157 (.) + 0xF8, 0xCC, 0xCC, 0xFA, 0xC6, 0xCF, 0xC6, 0xC7, // Char 158 (.) + 0x0E, 0x1B, 0x18, 0x3C, 0x18, 0x18, 0xD8, 0x70, // Char 159 (.) + 0x1C, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0x7E, 0x00, // Char 160 (.) + 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, // Char 161 (.) + 0x00, 0x1C, 0x00, 0x78, 0xCC, 0xCC, 0x78, 0x00, // Char 162 (.) + 0x00, 0x1C, 0x00, 0xCC, 0xCC, 0xCC, 0x7E, 0x00, // Char 163 (.) + 0x00, 0xF8, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0x00, // Char 164 (.) + 0xFC, 0x00, 0xCC, 0xEC, 0xFC, 0xDC, 0xCC, 0x00, // Char 165 (.) + 0x3C, 0x6C, 0x6C, 0x3E, 0x00, 0x7E, 0x00, 0x00, // Char 166 (.) + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x7C, 0x00, 0x00, // Char 167 (.) + 0x30, 0x00, 0x30, 0x60, 0xC0, 0xCC, 0x78, 0x00, // Char 168 (.) + 0x00, 0x00, 0x00, 0xFC, 0xC0, 0xC0, 0x00, 0x00, // Char 169 (.) + 0x00, 0x00, 0x00, 0xFC, 0x0C, 0x0C, 0x00, 0x00, // Char 170 (.) + 0xC3, 0xC6, 0xCC, 0xDE, 0x33, 0x66, 0xCC, 0x0F, // Char 171 (.) + 0xC3, 0xC6, 0xCC, 0xDB, 0x37, 0x6F, 0xCF, 0x03, // Char 172 (.) + 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 173 (.) + 0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, // Char 174 (.) + 0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, // Char 175 (.) + 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, // Char 176 (.) + 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, // Char 177 (.) + 0xDB, 0x77, 0xDB, 0xEE, 0xDB, 0x77, 0xDB, 0xEE, // Char 178 (.) + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // Char 179 (.) + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x18, 0x18, 0x18, // Char 180 (.) + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, // Char 181 (.) + 0x36, 0x36, 0x36, 0x36, 0xF6, 0x36, 0x36, 0x36, // Char 182 (.) + 0x00, 0x00, 0x00, 0x00, 0xFE, 0x36, 0x36, 0x36, // Char 183 (.) + 0x00, 0x00, 0xF8, 0x18, 0xF8, 0x18, 0x18, 0x18, // Char 184 (.) + 0x36, 0x36, 0xF6, 0x06, 0xF6, 0x36, 0x36, 0x36, // Char 185 (.) + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, // Char 186 (.) + 0x00, 0x00, 0xFE, 0x06, 0xF6, 0x36, 0x36, 0x36, // Char 187 (.) + 0x36, 0x36, 0xF6, 0x06, 0xFE, 0x00, 0x00, 0x00, // Char 188 (.) + 0x36, 0x36, 0x36, 0x36, 0xFE, 0x00, 0x00, 0x00, // Char 189 (.) + 0x18, 0x18, 0xF8, 0x18, 0xF8, 0x00, 0x00, 0x00, // Char 190 (.) + 0x00, 0x00, 0x00, 0x00, 0xF8, 0x18, 0x18, 0x18, // Char 191 (.) + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, 0x00, 0x00, // Char 192 (.) + 0x18, 0x18, 0x18, 0x18, 0xFF, 0x00, 0x00, 0x00, // Char 193 (.) + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x18, 0x18, 0x18, // Char 194 (.) + 0x18, 0x18, 0x18, 0x18, 0x1F, 0x18, 0x18, 0x18, // Char 195 (.) + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 196 (.) + 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, // Char 197 (.) + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, // Char 198 (.) + 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, // Char 199 (.) + 0x36, 0x36, 0x37, 0x30, 0x3F, 0x00, 0x00, 0x00, // Char 200 (.) + 0x00, 0x00, 0x3F, 0x30, 0x37, 0x36, 0x36, 0x36, // Char 201 (.) + 0x36, 0x36, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 202 (.) + 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x36, 0x36, 0x36, // Char 203 (.) + 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, // Char 204 (.) + 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 205 (.) + 0x36, 0x36, 0xF7, 0x00, 0xF7, 0x36, 0x36, 0x36, // Char 206 (.) + 0x18, 0x18, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, // Char 207 (.) + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x00, 0x00, 0x00, // Char 208 (.) + 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x18, 0x18, 0x18, // Char 209 (.) + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x36, 0x36, 0x36, // Char 210 (.) + 0x36, 0x36, 0x36, 0x36, 0x3F, 0x00, 0x00, 0x00, // Char 211 (.) + 0x18, 0x18, 0x1F, 0x18, 0x1F, 0x00, 0x00, 0x00, // Char 212 (.) + 0x00, 0x00, 0x1F, 0x18, 0x1F, 0x18, 0x18, 0x18, // Char 213 (.) + 0x00, 0x00, 0x00, 0x00, 0x3F, 0x36, 0x36, 0x36, // Char 214 (.) + 0x36, 0x36, 0x36, 0x36, 0xFF, 0x36, 0x36, 0x36, // Char 215 (.) + 0x18, 0x18, 0xFF, 0x18, 0xFF, 0x18, 0x18, 0x18, // Char 216 (.) + 0x18, 0x18, 0x18, 0x18, 0xF8, 0x00, 0x00, 0x00, // Char 217 (.) + 0x00, 0x00, 0x00, 0x00, 0x1F, 0x18, 0x18, 0x18, // Char 218 (.) + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Char 219 (.) + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // Char 220 (.) + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, // Char 221 (.) + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, // Char 222 (.) + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, // Char 223 (.) + 0x00, 0x00, 0x76, 0xDC, 0xC8, 0xDC, 0x76, 0x00, // Char 224 (.) + 0x00, 0x78, 0xCC, 0xF8, 0xCC, 0xF8, 0xC0, 0xC0, // Char 225 (.) + 0x00, 0xFC, 0xCC, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, // Char 226 (.) + 0x00, 0xFE, 0x6C, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, // Char 227 (.) + 0xFC, 0xCC, 0x60, 0x30, 0x60, 0xCC, 0xFC, 0x00, // Char 228 (.) + 0x00, 0x00, 0x7E, 0xD8, 0xD8, 0xD8, 0x70, 0x00, // Char 229 (.) + 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0xC0, // Char 230 (.) + 0x00, 0x76, 0xDC, 0x18, 0x18, 0x18, 0x18, 0x00, // Char 231 (.) + 0xFC, 0x30, 0x78, 0xCC, 0xCC, 0x78, 0x30, 0xFC, // Char 232 (.) + 0x38, 0x6C, 0xC6, 0xFE, 0xC6, 0x6C, 0x38, 0x00, // Char 233 (.) + 0x38, 0x6C, 0xC6, 0xC6, 0x6C, 0x6C, 0xEE, 0x00, // Char 234 (.) + 0x1C, 0x30, 0x18, 0x7C, 0xCC, 0xCC, 0x78, 0x00, // Char 235 (.) + 0x00, 0x00, 0x7E, 0xDB, 0xDB, 0x7E, 0x00, 0x00, // Char 236 (.) + 0x06, 0x0C, 0x7E, 0xDB, 0xDB, 0x7E, 0x60, 0xC0, // Char 237 (.) + 0x38, 0x60, 0xC0, 0xF8, 0xC0, 0x60, 0x38, 0x00, // Char 238 (.) + 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, // Char 239 (.) + 0x00, 0xFC, 0x00, 0xFC, 0x00, 0xFC, 0x00, 0x00, // Char 240 (.) + 0x30, 0x30, 0xFC, 0x30, 0x30, 0x00, 0xFC, 0x00, // Char 241 (.) + 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xFC, 0x00, // Char 242 (.) + 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xFC, 0x00, // Char 243 (.) + 0x0E, 0x1B, 0x1B, 0x18, 0x18, 0x18, 0x18, 0x18, // Char 244 (.) + 0x18, 0x18, 0x18, 0x18, 0x18, 0xD8, 0xD8, 0x70, // Char 245 (.) + 0x30, 0x30, 0x00, 0xFC, 0x00, 0x30, 0x30, 0x00, // Char 246 (.) + 0x00, 0x76, 0xDC, 0x00, 0x76, 0xDC, 0x00, 0x00, // Char 247 (.) + 0x38, 0x6C, 0x6C, 0x38, 0x00, 0x00, 0x00, 0x00, // Char 248 (.) + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, // Char 249 (.) + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, // Char 250 (.) + 0x0F, 0x0C, 0x0C, 0x0C, 0xEC, 0x6C, 0x3C, 0x1C, // Char 251 (.) + 0x78, 0x6C, 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, // Char 252 (.) + 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00, // Char 253 (.) + 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, // Char 254 (.) + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Char 255 (.) +}; + +uint16_t pixel[] = { 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100, + 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001 }; + +void setPixel(uint16_t x, uint16_t y, uint16_t colour) +{ + uint32_t ptr; + uint16_t* adr; + uint16_t mask = pixel[x & 0xF]; + + ptr = (uint32_t)physbase + ((y << 7) + (y << 5)) + ((x >> 4) << 3); + adr = (uint16_t*) ptr; + + *adr = (*adr & ~mask) | ((colour & 1) ? mask : 0); + adr++; + *adr = (*adr & ~mask) | ((colour & 2) ? mask : 0); + adr++; + *adr = (*adr & ~mask) | ((colour & 4) ? mask : 0); + adr++; + *adr = (*adr & ~mask) | ((colour & 8) ? mask : 0); +} + + +void drawChar(char ch, uint16_t x, uint16_t y, uint16_t colour) +{ + unsigned char i, j; + unsigned char *charSprite; + unsigned short plot_y; + + charSprite = (ch << 3) + std_font; // Updated line + // Draw charSprite as monochrome 8*8 image using given color + i = 8; + while (i--) + { + j = 8; + plot_y = y + i; + while (j--) + { + if((charSprite[i] >> j) & 1) + { + setPixel(x + (7 - j), plot_y, colour); + } + else + { + setPixel(x + (7 - j), y + i, 0); + } + } + } + x += 8; +} + +void Draw_Text(const char* str, unsigned short x, unsigned short y, unsigned short color_index) +{ + unsigned char i; + for(i = 0; str[i]; i++) + drawChar(str[i], x + (i << 3), y, color_index); +} + +void Draw_Text_Center(const char* str, unsigned short y, unsigned short color_index) +{ + unsigned char i; + uint16_t x; + uint16_t text_width; + text_width = strlen(str) << 3; + x = (320 - text_width) >> 1; + + for(i = 0; str[i]; i++) + drawChar(str[i], x + (i << 3), y, color_index); +} diff --git a/AtariST/frames1.png b/AtariST/frames1.png new file mode 100644 index 0000000..e2734f2 Binary files /dev/null and b/AtariST/frames1.png differ diff --git a/AtariST/frames2.png b/AtariST/frames2.png new file mode 100644 index 0000000..e3f6da9 Binary files /dev/null and b/AtariST/frames2.png differ diff --git a/AtariST/frames3.png b/AtariST/frames3.png new file mode 100644 index 0000000..b67b907 Binary files /dev/null and b/AtariST/frames3.png differ diff --git a/AtariST/frames4.png b/AtariST/frames4.png new file mode 100644 index 0000000..0fb38bc Binary files /dev/null and b/AtariST/frames4.png differ diff --git a/AtariST/frames5.png b/AtariST/frames5.png new file mode 100644 index 0000000..8bb9b59 Binary files /dev/null and b/AtariST/frames5.png differ diff --git a/AtariST/frames6.png b/AtariST/frames6.png new file mode 100644 index 0000000..112e236 Binary files /dev/null and b/AtariST/frames6.png differ diff --git a/AtariST/frames7.png b/AtariST/frames7.png new file mode 100644 index 0000000..2ac4934 Binary files /dev/null and b/AtariST/frames7.png differ diff --git a/AtariST/frames8.png b/AtariST/frames8.png new file mode 100644 index 0000000..bcf674e Binary files /dev/null and b/AtariST/frames8.png differ diff --git a/AtariST/frames9.png b/AtariST/frames9.png new file mode 100644 index 0000000..edf8d15 Binary files /dev/null and b/AtariST/frames9.png differ diff --git a/AtariST/ikbd.S b/AtariST/ikbd.S new file mode 100755 index 0000000..87cbc72 --- /dev/null +++ b/AtariST/ikbd.S @@ -0,0 +1,267 @@ +| +| IKBD 6301 interrupt routine +| (c) 2010/11/14 by Simon Sunnyboy / Paradize +| http://paradize.atari.org/ +| +| derived from a similar routine Copyright (C) 2002 Patrice Mandin +| +| +| This library is free software| you can redistribute it and/or +| modify it under the terms of the GNU Lesser General Public +| License as published by the Free Software Foundation| either +| version 2.1 of the License, or (at your option) any later version. +| +| This library is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY| without .even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +| Lesser General Public License for more details. +| +| You should have received a copy of the GNU Lesser General Public +| License along with this library| if not, write to the Free Software +| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +| + +.globl _IKBD_Install +.globl _IKBD_Uninstall +.globl _IKBD_Keyboard +.globl _IKBD_MouseX +.globl _IKBD_MouseY +.globl _IKBD_MouseB +.globl _IKBD_Joystick0 +.globl _IKBD_Joystick1 +.globl _IKBD_MouseOff +.globl _IKBD_MouseOn +.globl _IKBD_Mousemode + + .text +| ** installs the IKBD handler +_IKBD_Install: + movem.l d0-d1/a0-a1,-(sp) + + | Disable all interrupts + + move.w #0x2700,sr + + | Save MFP registers used for ACIA interrupt + + lea 0xfffffa00.w,a0 + btst #6,0x9(a0) + sne ikbd_ierb + btst #6,0x15(a0) + sne ikbd_imrb + + | Set our MFP routine + + move.l 0x118.w,old_ikbd + move.l #ikbd,0x118.w + bset #6,0xfffffa09.w | IERB + bset #6,0xfffffa15.w | IMRB + + | Set relative mouse motion mode + | needed because running a .tos or .ttp program + | disable the mouse (entering VT52 textmode) + + bsr _IKBD_MouseOn + + | Re-enable interrupts + + move.w #0x2300,sr + + movem.l (sp)+,d0-d1/a0-a1 + rts + +| ** reinstalls the old IKBD vector +_IKBD_Uninstall: + move.l a0,-(sp) + + | Disable interrupts + + move.w #0x2700,sr + + | Restore previous MFP registers + + lea 0xfffffa00.w,a0 + + bclr #6,0x9(a0) + tst.b ikbd_ierb + beq.s ikbd_restoreierb + bset #6,0x9(a0) +ikbd_restoreierb: + + bclr #6,0x15(a0) + tst.b ikbd_imrb + beq.s ikbd_restoreimrb + bset #6,0x15(a0) +ikbd_restoreimrb: + + move.l old_ikbd,0x118.w + + | Clear keyboard buffer + + lea 0xfffffc00.w,a0 +ikbd_clearbuffer: + btst #0,(a0) + beq.s ikbd_buffercleared + tst.b 2(a0) + bra.s ikbd_clearbuffer +ikbd_buffercleared: + + | Re-enable interrupts + + move.w #0x2300,sr + + move.l (sp)+,a0 + rts +| *** mouse off routine -> set joystick reporting *** +_IKBD_MouseOff: + move.b #0x12,0xfffffc02.w +wait_sticks: + btst #1,0xfffffc00.w + beq.s wait_sticks + move.b #0x14,0xfffffc02.w + | clear mouse buttons + clr.b _IKBD_MouseB + clr.b _IKBD_Mousemode + rts +| *** mouse on routine -> disable joystick and report mouse again *** +_IKBD_MouseOn: + move.b #0x08,0xfffffc02.w + | disable old joystick packets + clr.b _IKBD_Joystick0 + clr.b _IKBD_Joystick1 + move.b #0xff,_IKBD_Mousemode + rts +| custom IKBD vector + .even + .ascii "XBRA" + .ascii "IKBD" +old_ikbd: .skip 4 + +ikbd: + | test if byte coming from IKBD or MIDI + + btst #0,0xfffffc00.w + beq.s ikbd_endit + + movem.l d0-d1/a0,-(sp) + + move.b 0xfffffc02.w,d0 + + | Joystick packet ? + + cmp.b #0xff,d0 + beq.s ikbd_yes_joystick1 + + cmp.b #0xfe,d0 + beq.s ikbd_yes_joystick0 + + | Mouse packet ? + + cmp.b #0xf8,d0 + bmi.s ikbd_no_mouse + cmp.b #0xfc,d0 + bpl.s ikbd_no_mouse + +ikbd_yes_mouse: + and.b #3,d0 + move.b d0,_IKBD_MouseB + + move.l #ikbd_mousex,0x118.w | queue different irq vector for mouse packet + bra.s ikbd_endit_stack + +ikbd_yes_joystick0: + move.l #ikbd_poll_joystick0,0x118.w | queue joystick irq for next packet + bra.s ikbd_endit_stack + +ikbd_yes_joystick1: + move.l #ikbd_poll_joystick1,0x118.w | queue joystick irq for next packet + bra.s ikbd_endit_stack + + | Keyboard press/release + +ikbd_no_mouse: + move.b d0,d1 + lea _IKBD_Keyboard,a0 + and.l #0x7f,d1 | mask scancode + tas d0 + spl 0(a0,d1.w) | store -1 in scancode table + +ikbd_endit_stack: + movem.l (sp)+,d0-d1/a0 +ikbd_endit: + bclr #6,0xfffffa11.w | acknowledge IKBD interrupt + rte | ... and terminate the ISR + +ikbd_mousex: + | mouse packet? + + btst #0,0xfffffc00.w + beq.s ikbd_endit + + move.w d0,-(sp) + + move.b 0xfffffc02.w,d0 + ext.w d0 + add.w d0,_IKBD_MouseX + + move.w (sp)+,d0 + + move.l #ikbd_mousey,0x118.w + bra.s ikbd_endit + +ikbd_mousey: + | mouse packet? + + btst #0,0xfffffc00.w + beq.s ikbd_endit + + move.w d0,-(sp) + + move.b 0xfffffc02.w,d0 + ext.w d0 + add.w d0,_IKBD_MouseY + + move.w (sp)+,d0 + + move.l #ikbd,0x118.w + bra.s ikbd_endit + +ikbd_poll_joystick1: + | test if byte coming from joystick + + btst #0,0xfffffc00.w + beq.s ikbd_endit + + move.b 0xfffffc02.w,_IKBD_Joystick1 + + move.l #ikbd,0x118.w + bra.s ikbd_endit + +ikbd_poll_joystick0: + | test if byte coming from joystick 0 (mouse port) + + btst #0,0xfffffc00.w + beq.s ikbd_endit + + move.b 0xfffffc02.w,_IKBD_Joystick0 + + move.l #ikbd,0x118.w + bra.s ikbd_endit + + .bss + .even + +_IKBD_Keyboard: + .skip 128 + .even +_IKBD_MouseX: .skip 2 +_IKBD_MouseY: .skip 2 + .even +_IKBD_MouseB: .skip 1 +_IKBD_Mousemode: .skip 1 +_IKBD_Joystick0: .skip 1 +_IKBD_Joystick1: .skip 1 + .even +ikbd_ierb: .skip 1 +ikbd_imrb: .skip 1 + .end diff --git a/AtariST/ikbd.h b/AtariST/ikbd.h new file mode 100755 index 0000000..ed2e0e7 --- /dev/null +++ b/AtariST/ikbd.h @@ -0,0 +1,113 @@ +/* + * + * IKBD 6301 interrupt routine + * (c) 2010/11/14 by Simon Sunnyboy / Paradize + * http://paradize.atari.org/ + * + * derived from a similar routine Copyright (C) 2002 Patrice Mandin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _IKBD_H +#define _IKBD_H + +#include + +/* Constants for return values */ + +#define IKBD_MOUSE_BUTTON_LEFT (uint8_t)(0x02) +#define IKBD_MOUSE_BUTTON_RIGHT (uint8_t)(0x01) +#define IKBD_MOUSE_BOTH_BUTTONS (uint8_t)(0x03) + +#define IKBD_JOY_UP (uint8_t)(1<<0) +#define IKBD_JOY_DOWN (uint8_t)(1<<1) +#define IKBD_JOY_LEFT (uint8_t)(1<<2) +#define IKBD_JOY_RIGHT (uint8_t)(1<<3) +#define IKBD_JOY_FIRE (uint8_t)(1<<7) + +#define IKBD_KEY_PRESSED (uint8_t)(0xff) +#define IKBD_KEY_UNDEFINED (uint8_t)(0x80) +#define IKBD_KEY_RELEASED (uint8_t)(0x00) + +/* Constants for scancodes of important keys */ +#define IKBD_KEY_F1 59 +#define IKBD_KEY_F2 60 +#define IKBD_KEY_F3 61 +#define IKBD_KEY_F4 62 +#define IKBD_KEY_F5 63 +#define IKBD_KEY_F6 64 +#define IKBD_KEY_F7 65 +#define IKBD_KEY_F8 66 +#define IKBD_KEY_F9 67 +#define IKBD_KEY_F10 68 + +#define IKBD_KEY_SPACE 0x39 +#define IKBD_KEY_RETURN 0x1c +#define IKBD_KEY_UP 0x48 +#define IKBD_KEY_DOWN 0x50 +#define IKBD_KEY_LEFT 0x4b +#define IKBD_KEY_RIGHT 0x4d +#define IKBD_KEY_BACKSPACE 0x0e +#define IKBD_KEY_DELETE 0x53 +#define IKBD_KEY_ESC 0x01 +#define IKBD_KEY_TAB 0x0F +#define IKBD_KEY_CONTROL 0x1d +#define IKBD_KEY_ALT 0x38 +#define IKBD_KEY_LSHIFT 0x2a +#define IKBD_KEY_RSHIFT 0x36 +#define IKBD_KEY_INSERT 0x52 +#define IKBD_KEY_HELP 0x62 +#define IKBD_KEY_UNDO 0x61 +#define IKBD_KEY_CLRHOME 0x47 +#define IKBD_KEY_CAPSLOCK 0x3a + +/* data types */ +typedef struct +{ + int16_t x; + int16_t y; + uint16_t w; + uint16_t h; + uint8_t limit; + uint8_t b; +} IKBD_MouseData; + +/* Variables */ + +extern volatile IKBD_MouseData IKBD_Mouse; /* struct for mouse data */ + +extern volatile uint8_t IKBD_Keyboard[128]; /* Keyboard table */ +extern volatile uint8_t IKBD_Joystick0; /* Joystick on port 0 */ +extern volatile uint8_t IKBD_Joystick1; /* Joystick on port 1 */ + +/* function like access macros */ +#define IKBD_MOUSEX (IKBD_Mouse.x) +#define IKBD_MOUSEY (IKBD_Mouse.y) +#define IKBD_MOUSEK (IKBD_Mouse.b) +#define IKBD_STICK0 (IKBD_Joystick0) +#define IKBD_STICK1 (IKBD_Joystick1) + +/* Functions */ +void IKBD_Install(void); +void IKBD_Uninstall(void); +void IKBD_MouseOn(void); +void IKBD_MouseOff(void); +void IKBD_ReadMouse(void); +void IKBD_SetMouseThreshold(uint8_t); +void IKBD_SetMouseOrigin(int16_t, int16_t, uint16_t, uint16_t); +void IKBD_Flush(void); +uint8_t IKBD_IsKeyPressed(uint8_t); +#endif /* _IKBD_H */ diff --git a/AtariST/img.pi1 b/AtariST/img.pi1 new file mode 100644 index 0000000..3d7a9d1 Binary files /dev/null and b/AtariST/img.pi1 differ diff --git a/AtariST/jagpad.S b/AtariST/jagpad.S new file mode 100644 index 0000000..eb4aa7b --- /dev/null +++ b/AtariST/jagpad.S @@ -0,0 +1,203 @@ +# +# Jagpad Routine +# reading Jagpad A & B +# from some code found on the web +# +# (c) 2007 by Simon Sunnyboy / Paradize +# +# Returns :- +# pad0 = c1numpad,c1midbuts,c1firebuts,c1joypad +# pad1 = c2numpad,c2midbuts,c2firebuts,c2joypad +# contain bitwise representation in the form +# 1 4 7 * 3 6 9 # 2 5 8 0 o p c b a r l d u +# where o=option, p=pause, a/b/c=fire, r/l/d/u=directions. and rest are the phone pad. +# + +.globl _Jagpad_Read +.globl _pad0 +.globl _pad1 + +.text +# jagpad return values after call +_pad0: DC.L 0 +_pad1: DC.L 0 + +# local variables +c1numpad: DC.L 1 +c2numpad: DC.L 1 + + +_Jagpad_Read: movem.l D0-A2,-(SP) + clr.l D0 + clr.l D1 + clr.l D2 + clr.l D3 + clr.l D4 + clr.l D5 + clr.l D6 + clr.l D7 + movea.l #0,A0 + lea c1numpad(PC),A1 + lea c2numpad(PC),A2 + move.l #0,(A1) + move.l #0,(A2) + +# read row 1 + + move.w #0xFFEE,D0 + bsr read_controller + + move.w D1,D0 + andi.w #1,D0 + move.b D0,D3 + + move.w D1,D0 + andi.w #2,D0 + lsr.w #1,D0 + move.b D0,D4 + + move.w D1,D0 + andi.w #4,D0 + lsr.w #2,D0 + move.b D0,D6 + + move.w D1,D0 + andi.w #8,D0 + lsr.w #3,D0 + move.b D0,D7 + + move.w D2,D0 + andi.w #0x0F00,D0 + lsr.w #8,D0 + move.b D0,D5 + + move.w D2,D0 + andi.w #0xF000,D0 + lsr.w #8,D0 + lsr.w #4,D0 + movea.l D0,A0 + +# read row 2 + + move.w #0xFFDD,D0 + bsr read_controller + + move.w D1,D0 + andi.w #2,D0 + or.b D0,D4 + + move.w D1,D0 + andi.w #8,D0 + lsr.w #2,D0 + or.b D0,D7 + + move.w D2,D0 + andi.w #0x0F00,D0 + lsr.w #8,D0 + move.w D0,(A1) + + move.w D2,D0 + andi.w #0xF000,D0 + lsr.w #8,D0 + lsr.w #4,D0 + move.w D0,(A2) + +# read row 3 + + move.w #0xFFBB,D0 + bsr read_controller + + move.w D1,D0 + andi.w #2,D0 + lsl.w #1,D0 + or.b D0,D4 + + move.w D1,D0 + andi.w #8,D0 + lsr.w #1,D0 + or.b D0,D7 + + move.w D2,D0 + andi.w #0x0F00,D0 + lsr.w #4,D0 + or.l D0,(A1) + + move.w D2,D0 + andi.w #0xF000,D0 + lsr.w #8,D0 + or.l D0,(A2) + +# read row 4 + + move.w #0xFF77,D0 + bsr read_controller + + move.w D1,D0 + andi.w #2,D0 + or.b D0,D3 + + move.w D1,D0 + andi.w #8,D0 + lsr.w #2,D0 + or.b D0,D6 + + move.w D2,D0 + andi.w #0x0F00,D0 + or.l D0,(A1) + + move.w D2,D0 + andi.w #0xF000,D0 + lsr.w #4,D0 + or.l D0,(A2) + + lsl.l #7,D3 + lsl.l #4,D4 + or.l D4,D3 + or.l D5,D3 + + lsl.l #7,D6 + lsl.l #4,D7 + or.l D7,D6 + move.l A0,D2 + or.l D2,D6 + + move.l (A1),D2 ; d2 = c1numpad + lsl.l #5,D2 + move.l (A2),D5 ; d5 = c2numpad + lsl.l #5,D5 + + or.l D2,D3 + or.l D5,D6 + + move.l D3,D4 + andi.l #0b1111000000000000000000000,D4 + lsr.l #4,D4 + andi.l #0b11111111111111111,D3 + or.l D4,D3 + + move.l D6,D4 + andi.l #0b1111000000000000000000000,D4 + lsr.l #4,D4 + andi.l #0b11111111111111111,D6 + or.l D4,D6 + + lea _pad0(PC),A0 + move.l D3,(A0) + move.l D6,4(A0) + movem.l (SP)+,D0-A2 + rts + +read_controller: + move.w D0,0xFF9202 + move.w 0xFF9200,D1 + move.w 0xFF9202,D2 + + andi.w #0x0F,D1 + andi.w #0xFF00,D2 + + not.w D1 + not.w D2 + + rts +.end + diff --git a/AtariST/jagpad.h b/AtariST/jagpad.h new file mode 100644 index 0000000..4dfed81 --- /dev/null +++ b/AtariST/jagpad.h @@ -0,0 +1,54 @@ +/** + * @file jagpad.h + * @brief API for reading Atarai STE and Falcon 030 Pads + * @author Simon Sunnyboy / Paradize + * @copyright The MIT License applies. + */ + +#ifndef JAGPAD_H + #define JAGPAD_H + #include + + /* Button bitmap: 1 4 7 * 3 6 9 # 2 5 8 0 o p c b a r l d u */ + + #define JAGPAD_UP 0x00000001 + #define JAGPAD_DOWN 0x00000002 + #define JAGPAD_LEFT 0x00000004 + #define JAGPAD_RIGHT 0x00000008 + #define JAGPAD_BUT_A 0x00000010 + #define JAGPAD_BUT_B 0x00000020 + #define JAGPAD_BUT_C 0x00000040 + #define JAGPAD_BUT_PAUSE 0x00000080 + #define JAGPAD_BUT_OPTION 0x00000100 + #define JAGPAD_BUT_0 0x00000200 + #define JAGPAD_BUT_8 0x00000400 + #define JAGPAD_BUT_5 0x00000800 + #define JAGPAD_BUT_2 0x00001000 + #define JAGPAD_BUT_HASH 0x00002000 + #define JAGPAD_BUT_9 0x00004000 + #define JAGPAD_BUT_6 0x00008000 + #define JAGPAD_BUT_3 0x00010000 + #define JAGPAD_BUT_STAR 0x00020000 + #define JAGPAD_BUT_7 0x00040000 + #define JAGPAD_BUT_4 0x00080000 + #define JAGPAD_BUT_1 0x00100000 + + #define JAGPAD_FIRE (JAGPAD_BUT_A|JAGPAD_BUT_B|JAGPAD_BUT_C) + + /** + * @brief read jagpad A and B state into the global variables + * @details This routine is to be called cyclic, e.q. from a VBL interrupt. + */ + extern void Jagpad_Read(void); + + /** + * @brief Jagpad A state + */ + extern uint32_t pad0; + + /** + * @brief Jagpad A state + */ + extern uint32_t pad1; +#endif + diff --git a/AtariST/keys.c b/AtariST/keys.c new file mode 100755 index 0000000..2374acb --- /dev/null +++ b/AtariST/keys.c @@ -0,0 +1,95 @@ +/* + * + * IKBD 6301 interrupt routine + * (c) 2010/11/14 by Simon Sunnyboy / Paradize + * http://paradize.atari.org/ + * + * handling of key presses + * + * derived from a similar routine Copyright (C) 2002 Patrice Mandin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include "ikbd.h" +#include + +#define TIMER (*(volatile uint32_t const *)0x000004baUL) + +//extern volatile uint8_t IKBD_Mousemode; + +/* flushes all pending keyboard and joystick events */ +void IKBD_Flush() +{ + uint16_t i; + uint16_t flush_ok; + uint32_t tick; + + do + { + tick = TIMER; + /*if(IKBD_Mousemode != 0) + { + IKBD_ReadMouse(); + }*/ + flush_ok = (/* (IKBD_MOUSEK == 0) + &&*/(IKBD_STICK0 == 0) + &&(IKBD_STICK1 == 0)); + + for(i=0; i<128; i++) + { + if(IKBD_Keyboard[i] == IKBD_KEY_PRESSED) + { + (void)Cconws(".\r\n"); + flush_ok = 0; + break; /* allow some time to pass */ + } + } + /* await Timer C to count */ + while((tick + 10) < TIMER ) + { + /* wait for time */ + } + + + } while(!flush_ok); + return; +} + +/* returns and debounces a key by scancode */ +uint8_t IKBD_IsKeyPressed(uint8_t scancode) +{ + uint8_t keystatus; + + if(scancode & 0x80) + { + /* upper bit of scancode set -> scancode is invalid */ + return(IKBD_KEY_RELEASED); + } + else + { + keystatus = IKBD_Keyboard[scancode]; + + if((keystatus == IKBD_KEY_PRESSED)||(keystatus == IKBD_KEY_RELEASED)) + { + /* current key in defined state -> read it and set as read */ + IKBD_Keyboard[scancode] = IKBD_KEY_UNDEFINED; + return(keystatus); + } + } + /* undefined key state -> means key not pressed */ + return(IKBD_KEY_RELEASED); +} diff --git a/AtariST/lz4w.S b/AtariST/lz4w.S new file mode 100644 index 0000000..a0ae474 --- /dev/null +++ b/AtariST/lz4w.S @@ -0,0 +1,497 @@ +| MIT License - Copyright (c) 2019 Stephane Dallongeville +| +| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +| to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +| and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +| +| The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +| +| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +| DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +| OR OTHER DEALINGS IN THE SOFTWARE. + +.global lz4w_unpack +.global _lz4w_unpack +.global lz4w_unpack_ + +.macro LZ4W_NEXT + moveq #0, d1 + moveq #0, d0 + move.b (a0)+, d0 + move.b (a0)+, d1 + + add.w d0, d0 + add.w d0, d0 + move.l (a3,d0.w), a4 + jmp (a4) + .endm + + +lz4w_unpack: +_lz4w_unpack: +lz4w_unpack_: + move.l 4(%sp),%a0 + move.l 8(%sp),%a1 + +lz4w_unpack_a: + movem.l a2-a4, -(sp) + + lea .jump_table(pc), a3 + +.next: + LZ4W_NEXT + +.jump_table: + .long .lit0_mat0, .lit0_mat1, .lit0_mat2, .lit0_mat3, .lit0_mat4, .lit0_mat5, .lit0_mat6, .lit0_mat7, .lit0_mat8, .lit0_mat9, .lit0_matA, .lit0_matB, .lit0_matC, .lit0_matD, .lit0_matE, .lit0_matF + .long .lit1_mat0, .lit1_mat1, .lit1_mat2, .lit1_mat3, .lit1_mat4, .lit1_mat5, .lit1_mat6, .lit1_mat7, .lit1_mat8, .lit1_mat9, .lit1_matA, .lit1_matB, .lit1_matC, .lit1_matD, .lit1_matE, .lit1_matF + .long .lit2_mat0, .lit2_mat1, .lit2_mat2, .lit2_mat3, .lit2_mat4, .lit2_mat5, .lit2_mat6, .lit2_mat7, .lit2_mat8, .lit2_mat9, .lit2_matA, .lit2_matB, .lit2_matC, .lit2_matD, .lit2_matE, .lit2_matF + .long .lit3_mat0, .lit3_mat1, .lit3_mat2, .lit3_mat3, .lit3_mat4, .lit3_mat5, .lit3_mat6, .lit3_mat7, .lit3_mat8, .lit3_mat9, .lit3_matA, .lit3_matB, .lit3_matC, .lit3_matD, .lit3_matE, .lit3_matF + .long .lit4_mat0, .lit4_mat1, .lit4_mat2, .lit4_mat3, .lit4_mat4, .lit4_mat5, .lit4_mat6, .lit4_mat7, .lit4_mat8, .lit4_mat9, .lit4_matA, .lit4_matB, .lit4_matC, .lit4_matD, .lit4_matE, .lit4_matF + .long .lit5_mat0, .lit5_mat1, .lit5_mat2, .lit5_mat3, .lit5_mat4, .lit5_mat5, .lit5_mat6, .lit5_mat7, .lit5_mat8, .lit5_mat9, .lit5_matA, .lit5_matB, .lit5_matC, .lit5_matD, .lit5_matE, .lit5_matF + .long .lit6_mat0, .lit6_mat1, .lit6_mat2, .lit6_mat3, .lit6_mat4, .lit6_mat5, .lit6_mat6, .lit6_mat7, .lit6_mat8, .lit6_mat9, .lit6_matA, .lit6_matB, .lit6_matC, .lit6_matD, .lit6_matE, .lit6_matF + .long .lit7_mat0, .lit7_mat1, .lit7_mat2, .lit7_mat3, .lit7_mat4, .lit7_mat5, .lit7_mat6, .lit7_mat7, .lit7_mat8, .lit7_mat9, .lit7_matA, .lit7_matB, .lit7_matC, .lit7_matD, .lit7_matE, .lit7_matF + .long .lit8_mat0, .lit8_mat1, .lit8_mat2, .lit8_mat3, .lit8_mat4, .lit8_mat5, .lit8_mat6, .lit8_mat7, .lit8_mat8, .lit8_mat9, .lit8_matA, .lit8_matB, .lit8_matC, .lit8_matD, .lit8_matE, .lit8_matF + .long .lit9_mat0, .lit9_mat1, .lit9_mat2, .lit9_mat3, .lit9_mat4, .lit9_mat5, .lit9_mat6, .lit9_mat7, .lit9_mat8, .lit9_mat9, .lit9_matA, .lit9_matB, .lit9_matC, .lit9_matD, .lit9_matE, .lit9_matF + .long .litA_mat0, .litA_mat1, .litA_mat2, .litA_mat3, .litA_mat4, .litA_mat5, .litA_mat6, .litA_mat7, .litA_mat8, .litA_mat9, .litA_matA, .litA_matB, .litA_matC, .litA_matD, .litA_matE, .litA_matF + .long .litB_mat0, .litB_mat1, .litB_mat2, .litB_mat3, .litB_mat4, .litB_mat5, .litB_mat6, .litB_mat7, .litB_mat8, .litB_mat9, .litB_matA, .litB_matB, .litB_matC, .litB_matD, .litB_matE, .litB_matF + .long .litC_mat0, .litC_mat1, .litC_mat2, .litC_mat3, .litC_mat4, .litC_mat5, .litC_mat6, .litC_mat7, .litC_mat8, .litC_mat9, .litC_matA, .litC_matB, .litC_matC, .litC_matD, .litC_matE, .litC_matF + .long .litD_mat0, .litD_mat1, .litD_mat2, .litD_mat3, .litD_mat4, .litD_mat5, .litD_mat6, .litD_mat7, .litD_mat8, .litD_mat9, .litD_matA, .litD_matB, .litD_matC, .litD_matD, .litD_matE, .litD_matF + .long .litE_mat0, .litE_mat1, .litE_mat2, .litE_mat3, .litE_mat4, .litE_mat5, .litE_mat6, .litE_mat7, .litE_mat8, .litE_mat9, .litE_matA, .litE_matB, .litE_matC, .litE_matD, .litE_matE, .litE_matF + .long .litF_mat0, .litF_mat1, .litF_mat2, .litF_mat3, .litF_mat4, .litF_mat5, .litF_mat6, .litF_mat7, .litF_mat8, .litF_mat9, .litF_matA, .litF_matB, .litF_matC, .litF_matD, .litF_matE, .litF_matF + + + .rept 127 + move.l (a2)+, (a1)+ + .endr +.lmr_len_01: + move.l (a2)+, (a1)+ + move.w (a2)+, (a1)+ + LZ4W_NEXT + + .rept 127 + move.l (a2)+, (a1)+ + .endr +.lmr_len_00: + move.l (a2)+, (a1)+ + LZ4W_NEXT + + .rept 255 + move.w (a2)+, (a1)+ + .endr +.lm_len_00: + move.w (a2)+, (a1)+ + move.w (a2)+, (a1)+ + LZ4W_NEXT + +.litE_mat0: move.l (a0)+, (a1)+ +.litC_mat0: move.l (a0)+, (a1)+ +.litA_mat0: move.l (a0)+, (a1)+ +.lit8_mat0: move.l (a0)+, (a1)+ +.lit6_mat0: move.l (a0)+, (a1)+ +.lit4_mat0: move.l (a0)+, (a1)+ +.lit2_mat0: move.l (a0)+, (a1)+ + tst.b d1 | match offset null ? + beq .next | not a long match + +.long_match_1: + move.w (a0)+, d0 | get long offset (already negated) + + add.w d1, d1 | len = len * 2 + + add.w d0, d0 | bit 15 contains ROM source info + bcs.s .lm_rom + + lea -2(a1,d0.w), a2 | a2 = dst - (match offset + 2) + neg.w d1 + lea .lm_len_00(pc,d1.w), a4 + jmp (a4) + +.litF_mat0: move.l (a0)+, (a1)+ +.litD_mat0: move.l (a0)+, (a1)+ +.litB_mat0: move.l (a0)+, (a1)+ +.lit9_mat0: move.l (a0)+, (a1)+ +.lit7_mat0: move.l (a0)+, (a1)+ +.lit5_mat0: move.l (a0)+, (a1)+ +.lit3_mat0: move.l (a0)+, (a1)+ +.lit1_mat0: move.w (a0)+, (a1)+ + + tst.b d1 | match offset null ? + beq .next | not a long match + +.long_match_2: + move.w (a0)+, d0 | get long offset (already negated) + + add.w d1, d1 | len = len * 2 + + add.w d0, d0 | bit 15 contains ROM source info + bcs.s .lm_rom + + lea -2(a1,d0.w), a2 | a2 = dst - (match offset + 2) + neg.w d1 + lea .lm_len_00(pc,d1.w), a4 + jmp (a4) + +.lit0_mat0: | special case of lit=0 and mat=0 + tst.b d1 | match offset null ? + beq .done | not a long match --> done + +.long_match_3: + move.w (a0)+, d0 | get long offset (already negated) + + add.w d1, d1 | len = len * 2 + + add.w d0, d0 | bit 15 contains ROM source info + bcs.s .lm_rom + + lea -2(a1,d0.w), a2 | a2 = dst - (match offset + 2) + neg.w d1 + lea .lm_len_00(pc,d1.w), a4 + jmp (a4) + +.lm_rom: + add.w d1, d1 | len = len * 4 + lea -2(a0,d0.w), a2 | a2 = src - (match offset + 2) + move.l .lmr_jump_table(pc,d1.w), a4 + jmp (a4) + +.lmr_jump_table: + .long .lmr_len_00-0x00, .lmr_len_01-0x00, .lmr_len_00-0x02, .lmr_len_01-0x02, .lmr_len_00-0x04, .lmr_len_01-0x04, .lmr_len_00-0x06, .lmr_len_01-0x06, .lmr_len_00-0x08, .lmr_len_01-0x08, .lmr_len_00-0x0a, .lmr_len_01-0x0a, .lmr_len_00-0x0c, .lmr_len_01-0x0c, .lmr_len_00-0x0e, .lmr_len_01-0x0e + .long .lmr_len_00-0x10, .lmr_len_01-0x10, .lmr_len_00-0x12, .lmr_len_01-0x12, .lmr_len_00-0x14, .lmr_len_01-0x14, .lmr_len_00-0x16, .lmr_len_01-0x16, .lmr_len_00-0x18, .lmr_len_01-0x18, .lmr_len_00-0x1a, .lmr_len_01-0x1a, .lmr_len_00-0x1c, .lmr_len_01-0x1c, .lmr_len_00-0x1e, .lmr_len_01-0x1e + .long .lmr_len_00-0x20, .lmr_len_01-0x20, .lmr_len_00-0x22, .lmr_len_01-0x22, .lmr_len_00-0x24, .lmr_len_01-0x24, .lmr_len_00-0x26, .lmr_len_01-0x26, .lmr_len_00-0x28, .lmr_len_01-0x28, .lmr_len_00-0x2a, .lmr_len_01-0x2a, .lmr_len_00-0x2c, .lmr_len_01-0x2c, .lmr_len_00-0x2e, .lmr_len_01-0x2e + .long .lmr_len_00-0x30, .lmr_len_01-0x30, .lmr_len_00-0x32, .lmr_len_01-0x32, .lmr_len_00-0x34, .lmr_len_01-0x34, .lmr_len_00-0x36, .lmr_len_01-0x36, .lmr_len_00-0x38, .lmr_len_01-0x38, .lmr_len_00-0x3a, .lmr_len_01-0x3a, .lmr_len_00-0x3c, .lmr_len_01-0x3c, .lmr_len_00-0x3e, .lmr_len_01-0x3e + .long .lmr_len_00-0x40, .lmr_len_01-0x40, .lmr_len_00-0x42, .lmr_len_01-0x42, .lmr_len_00-0x44, .lmr_len_01-0x44, .lmr_len_00-0x46, .lmr_len_01-0x46, .lmr_len_00-0x48, .lmr_len_01-0x48, .lmr_len_00-0x4a, .lmr_len_01-0x4a, .lmr_len_00-0x4c, .lmr_len_01-0x4c, .lmr_len_00-0x4e, .lmr_len_01-0x4e + .long .lmr_len_00-0x50, .lmr_len_01-0x50, .lmr_len_00-0x52, .lmr_len_01-0x52, .lmr_len_00-0x54, .lmr_len_01-0x54, .lmr_len_00-0x56, .lmr_len_01-0x56, .lmr_len_00-0x58, .lmr_len_01-0x58, .lmr_len_00-0x5a, .lmr_len_01-0x5a, .lmr_len_00-0x5c, .lmr_len_01-0x5c, .lmr_len_00-0x5e, .lmr_len_01-0x5e + .long .lmr_len_00-0x60, .lmr_len_01-0x60, .lmr_len_00-0x62, .lmr_len_01-0x62, .lmr_len_00-0x64, .lmr_len_01-0x64, .lmr_len_00-0x66, .lmr_len_01-0x66, .lmr_len_00-0x68, .lmr_len_01-0x68, .lmr_len_00-0x6a, .lmr_len_01-0x6a, .lmr_len_00-0x6c, .lmr_len_01-0x6c, .lmr_len_00-0x6e, .lmr_len_01-0x6e + .long .lmr_len_00-0x70, .lmr_len_01-0x70, .lmr_len_00-0x72, .lmr_len_01-0x72, .lmr_len_00-0x74, .lmr_len_01-0x74, .lmr_len_00-0x76, .lmr_len_01-0x76, .lmr_len_00-0x78, .lmr_len_01-0x78, .lmr_len_00-0x7a, .lmr_len_01-0x7a, .lmr_len_00-0x7c, .lmr_len_01-0x7c, .lmr_len_00-0x7e, .lmr_len_01-0x7e + .long .lmr_len_00-0x80, .lmr_len_01-0x80, .lmr_len_00-0x82, .lmr_len_01-0x82, .lmr_len_00-0x84, .lmr_len_01-0x84, .lmr_len_00-0x86, .lmr_len_01-0x86, .lmr_len_00-0x88, .lmr_len_01-0x88, .lmr_len_00-0x8a, .lmr_len_01-0x8a, .lmr_len_00-0x8c, .lmr_len_01-0x8c, .lmr_len_00-0x8e, .lmr_len_01-0x8e + .long .lmr_len_00-0x90, .lmr_len_01-0x90, .lmr_len_00-0x92, .lmr_len_01-0x92, .lmr_len_00-0x94, .lmr_len_01-0x94, .lmr_len_00-0x96, .lmr_len_01-0x96, .lmr_len_00-0x98, .lmr_len_01-0x98, .lmr_len_00-0x9a, .lmr_len_01-0x9a, .lmr_len_00-0x9c, .lmr_len_01-0x9c, .lmr_len_00-0x9e, .lmr_len_01-0x9e + .long .lmr_len_00-0xa0, .lmr_len_01-0xa0, .lmr_len_00-0xa2, .lmr_len_01-0xa2, .lmr_len_00-0xa4, .lmr_len_01-0xa4, .lmr_len_00-0xa6, .lmr_len_01-0xa6, .lmr_len_00-0xa8, .lmr_len_01-0xa8, .lmr_len_00-0xaa, .lmr_len_01-0xaa, .lmr_len_00-0xac, .lmr_len_01-0xac, .lmr_len_00-0xae, .lmr_len_01-0xae + .long .lmr_len_00-0xb0, .lmr_len_01-0xb0, .lmr_len_00-0xb2, .lmr_len_01-0xb2, .lmr_len_00-0xb4, .lmr_len_01-0xb4, .lmr_len_00-0xb6, .lmr_len_01-0xb6, .lmr_len_00-0xb8, .lmr_len_01-0xb8, .lmr_len_00-0xba, .lmr_len_01-0xba, .lmr_len_00-0xbc, .lmr_len_01-0xbc, .lmr_len_00-0xbe, .lmr_len_01-0xbe + .long .lmr_len_00-0xc0, .lmr_len_01-0xc0, .lmr_len_00-0xc2, .lmr_len_01-0xc2, .lmr_len_00-0xc4, .lmr_len_01-0xc4, .lmr_len_00-0xc6, .lmr_len_01-0xc6, .lmr_len_00-0xc8, .lmr_len_01-0xc8, .lmr_len_00-0xca, .lmr_len_01-0xca, .lmr_len_00-0xcc, .lmr_len_01-0xcc, .lmr_len_00-0xce, .lmr_len_01-0xce + .long .lmr_len_00-0xd0, .lmr_len_01-0xd0, .lmr_len_00-0xd2, .lmr_len_01-0xd2, .lmr_len_00-0xd4, .lmr_len_01-0xd4, .lmr_len_00-0xd6, .lmr_len_01-0xd6, .lmr_len_00-0xd8, .lmr_len_01-0xd8, .lmr_len_00-0xda, .lmr_len_01-0xda, .lmr_len_00-0xdc, .lmr_len_01-0xdc, .lmr_len_00-0xde, .lmr_len_01-0xde + .long .lmr_len_00-0xe0, .lmr_len_01-0xe0, .lmr_len_00-0xe2, .lmr_len_01-0xe2, .lmr_len_00-0xe4, .lmr_len_01-0xe4, .lmr_len_00-0xe6, .lmr_len_01-0xe6, .lmr_len_00-0xe8, .lmr_len_01-0xe8, .lmr_len_00-0xea, .lmr_len_01-0xea, .lmr_len_00-0xec, .lmr_len_01-0xec, .lmr_len_00-0xee, .lmr_len_01-0xee + .long .lmr_len_00-0xf0, .lmr_len_01-0xf0, .lmr_len_00-0xf2, .lmr_len_01-0xf2, .lmr_len_00-0xf4, .lmr_len_01-0xf4, .lmr_len_00-0xf6, .lmr_len_01-0xf6, .lmr_len_00-0xf8, .lmr_len_01-0xf8, .lmr_len_00-0xfa, .lmr_len_01-0xfa, .lmr_len_00-0xfc, .lmr_len_01-0xfc, .lmr_len_00-0xfe, .lmr_len_01-0xfe + + + .macro COPY_MATCH count + add.w d1, d1 + neg.w d1 + lea -2(a1,d1.w), a2 | a2 = dst - ((match offset + 1) * 2) + + .rept ((\count)+1) + move.w (a2)+, (a1)+ + .endr + LZ4W_NEXT + .endm + +.litE_mat1: move.l (a0)+, (a1)+ +.litC_mat1: move.l (a0)+, (a1)+ +.litA_mat1: move.l (a0)+, (a1)+ +.lit8_mat1: move.l (a0)+, (a1)+ +.lit6_mat1: move.l (a0)+, (a1)+ +.lit4_mat1: move.l (a0)+, (a1)+ +.lit2_mat1: move.l (a0)+, (a1)+ +.lit0_mat1: + COPY_MATCH 1 + +.litF_mat1: move.l (a0)+, (a1)+ +.litD_mat1: move.l (a0)+, (a1)+ +.litB_mat1: move.l (a0)+, (a1)+ +.lit9_mat1: move.l (a0)+, (a1)+ +.lit7_mat1: move.l (a0)+, (a1)+ +.lit5_mat1: move.l (a0)+, (a1)+ +.lit3_mat1: move.l (a0)+, (a1)+ +.lit1_mat1: move.w (a0)+, (a1)+ + COPY_MATCH 1 + +.litE_mat2: move.l (a0)+, (a1)+ +.litC_mat2: move.l (a0)+, (a1)+ +.litA_mat2: move.l (a0)+, (a1)+ +.lit8_mat2: move.l (a0)+, (a1)+ +.lit6_mat2: move.l (a0)+, (a1)+ +.lit4_mat2: move.l (a0)+, (a1)+ +.lit2_mat2: move.l (a0)+, (a1)+ +.lit0_mat2: + COPY_MATCH 2 + +.litF_mat2: move.l (a0)+, (a1)+ +.litD_mat2: move.l (a0)+, (a1)+ +.litB_mat2: move.l (a0)+, (a1)+ +.lit9_mat2: move.l (a0)+, (a1)+ +.lit7_mat2: move.l (a0)+, (a1)+ +.lit5_mat2: move.l (a0)+, (a1)+ +.lit3_mat2: move.l (a0)+, (a1)+ +.lit1_mat2: move.w (a0)+, (a1)+ + COPY_MATCH 2 + +.litE_mat3: move.l (a0)+, (a1)+ +.litC_mat3: move.l (a0)+, (a1)+ +.litA_mat3: move.l (a0)+, (a1)+ +.lit8_mat3: move.l (a0)+, (a1)+ +.lit6_mat3: move.l (a0)+, (a1)+ +.lit4_mat3: move.l (a0)+, (a1)+ +.lit2_mat3: move.l (a0)+, (a1)+ +.lit0_mat3: + COPY_MATCH 3 + +.litF_mat3: move.l (a0)+, (a1)+ +.litD_mat3: move.l (a0)+, (a1)+ +.litB_mat3: move.l (a0)+, (a1)+ +.lit9_mat3: move.l (a0)+, (a1)+ +.lit7_mat3: move.l (a0)+, (a1)+ +.lit5_mat3: move.l (a0)+, (a1)+ +.lit3_mat3: move.l (a0)+, (a1)+ +.lit1_mat3: move.w (a0)+, (a1)+ + COPY_MATCH 3 + +.litE_mat4: move.l (a0)+, (a1)+ +.litC_mat4: move.l (a0)+, (a1)+ +.litA_mat4: move.l (a0)+, (a1)+ +.lit8_mat4: move.l (a0)+, (a1)+ +.lit6_mat4: move.l (a0)+, (a1)+ +.lit4_mat4: move.l (a0)+, (a1)+ +.lit2_mat4: move.l (a0)+, (a1)+ +.lit0_mat4: + COPY_MATCH 4 + +.litF_mat4: move.l (a0)+, (a1)+ +.litD_mat4: move.l (a0)+, (a1)+ +.litB_mat4: move.l (a0)+, (a1)+ +.lit9_mat4: move.l (a0)+, (a1)+ +.lit7_mat4: move.l (a0)+, (a1)+ +.lit5_mat4: move.l (a0)+, (a1)+ +.lit3_mat4: move.l (a0)+, (a1)+ +.lit1_mat4: move.w (a0)+, (a1)+ + COPY_MATCH 4 + +.litE_mat5: move.l (a0)+, (a1)+ +.litC_mat5: move.l (a0)+, (a1)+ +.litA_mat5: move.l (a0)+, (a1)+ +.lit8_mat5: move.l (a0)+, (a1)+ +.lit6_mat5: move.l (a0)+, (a1)+ +.lit4_mat5: move.l (a0)+, (a1)+ +.lit2_mat5: move.l (a0)+, (a1)+ +.lit0_mat5: + COPY_MATCH 5 + +.litF_mat5: move.l (a0)+, (a1)+ +.litD_mat5: move.l (a0)+, (a1)+ +.litB_mat5: move.l (a0)+, (a1)+ +.lit9_mat5: move.l (a0)+, (a1)+ +.lit7_mat5: move.l (a0)+, (a1)+ +.lit5_mat5: move.l (a0)+, (a1)+ +.lit3_mat5: move.l (a0)+, (a1)+ +.lit1_mat5: move.w (a0)+, (a1)+ + COPY_MATCH 5 + +.litE_mat6: move.l (a0)+, (a1)+ +.litC_mat6: move.l (a0)+, (a1)+ +.litA_mat6: move.l (a0)+, (a1)+ +.lit8_mat6: move.l (a0)+, (a1)+ +.lit6_mat6: move.l (a0)+, (a1)+ +.lit4_mat6: move.l (a0)+, (a1)+ +.lit2_mat6: move.l (a0)+, (a1)+ +.lit0_mat6: + COPY_MATCH 6 + +.litF_mat6: move.l (a0)+, (a1)+ +.litD_mat6: move.l (a0)+, (a1)+ +.litB_mat6: move.l (a0)+, (a1)+ +.lit9_mat6: move.l (a0)+, (a1)+ +.lit7_mat6: move.l (a0)+, (a1)+ +.lit5_mat6: move.l (a0)+, (a1)+ +.lit3_mat6: move.l (a0)+, (a1)+ +.lit1_mat6: move.w (a0)+, (a1)+ + COPY_MATCH 6 + +.litE_mat7: move.l (a0)+, (a1)+ +.litC_mat7: move.l (a0)+, (a1)+ +.litA_mat7: move.l (a0)+, (a1)+ +.lit8_mat7: move.l (a0)+, (a1)+ +.lit6_mat7: move.l (a0)+, (a1)+ +.lit4_mat7: move.l (a0)+, (a1)+ +.lit2_mat7: move.l (a0)+, (a1)+ +.lit0_mat7: + COPY_MATCH 7 + +.litF_mat7: move.l (a0)+, (a1)+ +.litD_mat7: move.l (a0)+, (a1)+ +.litB_mat7: move.l (a0)+, (a1)+ +.lit9_mat7: move.l (a0)+, (a1)+ +.lit7_mat7: move.l (a0)+, (a1)+ +.lit5_mat7: move.l (a0)+, (a1)+ +.lit3_mat7: move.l (a0)+, (a1)+ +.lit1_mat7: move.w (a0)+, (a1)+ + COPY_MATCH 7 + +.litE_mat8: move.l (a0)+, (a1)+ +.litC_mat8: move.l (a0)+, (a1)+ +.litA_mat8: move.l (a0)+, (a1)+ +.lit8_mat8: move.l (a0)+, (a1)+ +.lit6_mat8: move.l (a0)+, (a1)+ +.lit4_mat8: move.l (a0)+, (a1)+ +.lit2_mat8: move.l (a0)+, (a1)+ +.lit0_mat8: + COPY_MATCH 8 + +.litF_mat8: move.l (a0)+, (a1)+ +.litD_mat8: move.l (a0)+, (a1)+ +.litB_mat8: move.l (a0)+, (a1)+ +.lit9_mat8: move.l (a0)+, (a1)+ +.lit7_mat8: move.l (a0)+, (a1)+ +.lit5_mat8: move.l (a0)+, (a1)+ +.lit3_mat8: move.l (a0)+, (a1)+ +.lit1_mat8: move.w (a0)+, (a1)+ + COPY_MATCH 8 + +.litE_mat9: move.l (a0)+, (a1)+ +.litC_mat9: move.l (a0)+, (a1)+ +.litA_mat9: move.l (a0)+, (a1)+ +.lit8_mat9: move.l (a0)+, (a1)+ +.lit6_mat9: move.l (a0)+, (a1)+ +.lit4_mat9: move.l (a0)+, (a1)+ +.lit2_mat9: move.l (a0)+, (a1)+ +.lit0_mat9: + COPY_MATCH 9 + +.litF_mat9: move.l (a0)+, (a1)+ +.litD_mat9: move.l (a0)+, (a1)+ +.litB_mat9: move.l (a0)+, (a1)+ +.lit9_mat9: move.l (a0)+, (a1)+ +.lit7_mat9: move.l (a0)+, (a1)+ +.lit5_mat9: move.l (a0)+, (a1)+ +.lit3_mat9: move.l (a0)+, (a1)+ +.lit1_mat9: move.w (a0)+, (a1)+ + COPY_MATCH 9 + +.litE_matA: move.l (a0)+, (a1)+ +.litC_matA: move.l (a0)+, (a1)+ +.litA_matA: move.l (a0)+, (a1)+ +.lit8_matA: move.l (a0)+, (a1)+ +.lit6_matA: move.l (a0)+, (a1)+ +.lit4_matA: move.l (a0)+, (a1)+ +.lit2_matA: move.l (a0)+, (a1)+ +.lit0_matA: + COPY_MATCH 10 + +.litF_matA: move.l (a0)+, (a1)+ +.litD_matA: move.l (a0)+, (a1)+ +.litB_matA: move.l (a0)+, (a1)+ +.lit9_matA: move.l (a0)+, (a1)+ +.lit7_matA: move.l (a0)+, (a1)+ +.lit5_matA: move.l (a0)+, (a1)+ +.lit3_matA: move.l (a0)+, (a1)+ +.lit1_matA: move.w (a0)+, (a1)+ + COPY_MATCH 10 + +.litE_matB: move.l (a0)+, (a1)+ +.litC_matB: move.l (a0)+, (a1)+ +.litA_matB: move.l (a0)+, (a1)+ +.lit8_matB: move.l (a0)+, (a1)+ +.lit6_matB: move.l (a0)+, (a1)+ +.lit4_matB: move.l (a0)+, (a1)+ +.lit2_matB: move.l (a0)+, (a1)+ +.lit0_matB: + COPY_MATCH 11 + +.litF_matB: move.l (a0)+, (a1)+ +.litD_matB: move.l (a0)+, (a1)+ +.litB_matB: move.l (a0)+, (a1)+ +.lit9_matB: move.l (a0)+, (a1)+ +.lit7_matB: move.l (a0)+, (a1)+ +.lit5_matB: move.l (a0)+, (a1)+ +.lit3_matB: move.l (a0)+, (a1)+ +.lit1_matB: move.w (a0)+, (a1)+ + COPY_MATCH 11 + +.litE_matC: move.l (a0)+, (a1)+ +.litC_matC: move.l (a0)+, (a1)+ +.litA_matC: move.l (a0)+, (a1)+ +.lit8_matC: move.l (a0)+, (a1)+ +.lit6_matC: move.l (a0)+, (a1)+ +.lit4_matC: move.l (a0)+, (a1)+ +.lit2_matC: move.l (a0)+, (a1)+ +.lit0_matC: + COPY_MATCH 12 + +.litF_matC: move.l (a0)+, (a1)+ +.litD_matC: move.l (a0)+, (a1)+ +.litB_matC: move.l (a0)+, (a1)+ +.lit9_matC: move.l (a0)+, (a1)+ +.lit7_matC: move.l (a0)+, (a1)+ +.lit5_matC: move.l (a0)+, (a1)+ +.lit3_matC: move.l (a0)+, (a1)+ +.lit1_matC: move.w (a0)+, (a1)+ + COPY_MATCH 12 + +.litE_matD: move.l (a0)+, (a1)+ +.litC_matD: move.l (a0)+, (a1)+ +.litA_matD: move.l (a0)+, (a1)+ +.lit8_matD: move.l (a0)+, (a1)+ +.lit6_matD: move.l (a0)+, (a1)+ +.lit4_matD: move.l (a0)+, (a1)+ +.lit2_matD: move.l (a0)+, (a1)+ +.lit0_matD: + COPY_MATCH 13 + +.litF_matD: move.l (a0)+, (a1)+ +.litD_matD: move.l (a0)+, (a1)+ +.litB_matD: move.l (a0)+, (a1)+ +.lit9_matD: move.l (a0)+, (a1)+ +.lit7_matD: move.l (a0)+, (a1)+ +.lit5_matD: move.l (a0)+, (a1)+ +.lit3_matD: move.l (a0)+, (a1)+ +.lit1_matD: move.w (a0)+, (a1)+ + COPY_MATCH 13 + +.litE_matE: move.l (a0)+, (a1)+ +.litC_matE: move.l (a0)+, (a1)+ +.litA_matE: move.l (a0)+, (a1)+ +.lit8_matE: move.l (a0)+, (a1)+ +.lit6_matE: move.l (a0)+, (a1)+ +.lit4_matE: move.l (a0)+, (a1)+ +.lit2_matE: move.l (a0)+, (a1)+ +.lit0_matE: + COPY_MATCH 14 + +.litF_matE: move.l (a0)+, (a1)+ +.litD_matE: move.l (a0)+, (a1)+ +.litB_matE: move.l (a0)+, (a1)+ +.lit9_matE: move.l (a0)+, (a1)+ +.lit7_matE: move.l (a0)+, (a1)+ +.lit5_matE: move.l (a0)+, (a1)+ +.lit3_matE: move.l (a0)+, (a1)+ +.lit1_matE: move.w (a0)+, (a1)+ + COPY_MATCH 14 + +.litE_matF: move.l (a0)+, (a1)+ +.litC_matF: move.l (a0)+, (a1)+ +.litA_matF: move.l (a0)+, (a1)+ +.lit8_matF: move.l (a0)+, (a1)+ +.lit6_matF: move.l (a0)+, (a1)+ +.lit4_matF: move.l (a0)+, (a1)+ +.lit2_matF: move.l (a0)+, (a1)+ +.lit0_matF: + COPY_MATCH 15 + +.litF_matF: move.l (a0)+, (a1)+ +.litD_matF: move.l (a0)+, (a1)+ +.litB_matF: move.l (a0)+, (a1)+ +.lit9_matF: move.l (a0)+, (a1)+ +.lit7_matF: move.l (a0)+, (a1)+ +.lit5_matF: move.l (a0)+, (a1)+ +.lit3_matF: move.l (a0)+, (a1)+ +.lit1_matF: move.w (a0)+, (a1)+ + COPY_MATCH 15 + +.done: + move.w (a0)+, d0 | need to copy a last byte ? + bpl.s .no_byte + move.b d0, (a1)+ | copy last byte +.no_byte: + move.l a1, d0 + sub.l 20(sp), d0 | return op - dest + + movem.l (sp)+, a2-a4 + rts diff --git a/AtariST/lz4w.jar b/AtariST/lz4w.jar new file mode 100644 index 0000000..47f2f9b Binary files /dev/null and b/AtariST/lz4w.jar differ diff --git a/AtariST/main.c b/AtariST/main.c new file mode 100644 index 0000000..65088a6 --- /dev/null +++ b/AtariST/main.c @@ -0,0 +1,396 @@ +#include +#include +#include +#include +#include +#include "ikbd.h" +#include "sound.h" +#include "atarist.h" + +unsigned char* bmp[2]; +SoundDevice mainsound; + +#define DATA_FOLDER "DATA\\" + +void * physbase; +void *logbase; + +const char soundfiles[2][7][18] = +{ + { + DATA_FOLDER"SP1.TDY", + DATA_FOLDER"SP2.TDY", + DATA_FOLDER"SP3.TDY", + DATA_FOLDER"SP4.TDY", + DATA_FOLDER"SP5.TDY", + DATA_FOLDER"FUCK.TDY", + DATA_FOLDER"FUCK2.TDY", + }, + { + DATA_FOLDER"SP1.RAW", + DATA_FOLDER"SP2.RAW", + DATA_FOLDER"SP3.RAW", + DATA_FOLDER"SP4.RAW", + DATA_FOLDER"SP5.RAW", + DATA_FOLDER"FUCK.RAW", + DATA_FOLDER"FUCK2.RAW", + }, +}; + +unsigned char k, game_mode, text_progress; +#define FRAME_CURRENT text_progress +signed char diff; +unsigned char status; +unsigned char i; +unsigned short time_game; + + +#define KEEPITUP_GAME_STATUS 0 +#define STOP_GAME_STATUS 1 +#define FUCK_GAME_STATUS 2 +#define END_GAME_STATUS 3 + +const unsigned char status_level1[] = +{ + FUCK_GAME_STATUS, KEEPITUP_GAME_STATUS, + STOP_GAME_STATUS, FUCK_GAME_STATUS, KEEPITUP_GAME_STATUS, + STOP_GAME_STATUS, FUCK_GAME_STATUS, KEEPITUP_GAME_STATUS, + STOP_GAME_STATUS, FUCK_GAME_STATUS, + END_GAME_STATUS, END_GAME_STATUS +}; + +const char ingame_quote[5][5] = +{ + "GO!!\0", + "STOP\0", + "FUCK\0", + "END \0", +}; +const unsigned char jump[5] = +{ 3, 0xFF, 0, 0xFF, 1 }; + +static char bcd[4]; +static char hibcd[4]; + +void switch_gamemode(unsigned char mode) ; + + +#define add_score(add) \ + bcd[2] += add; \ + if (bcd[2] > 57) { \ + bcd[1]+= 1; \ + bcd[2] = 48; } \ + if (bcd[1] > 57) { \ + bcd[0]+= 1; \ + bcd[1] = 48; } \ + +#define decrease_score(dec) \ + bcd[2] -= dec; \ + if (bcd[2] < 48) \ + { \ + bcd[1]-= 1; \ + bcd[2] = 57; \ + } \ + if (bcd[1] < 48) \ + { \ + bcd[0]-= 1; \ + bcd[1] = 57; \ + } \ + + +uint8_t special_sound; + + +void Clear_Text() +{ + memset(physbase + 28000, 0, 32000-28000); +} + +void DrawHUD() +{ + Draw_Text("SCORE", 0, 180, 15); + Draw_Text(bcd, 0, 188, 15); + Draw_Text_Center(ingame_quote[status_level1[status]], 180, 15); +} + +/* +int main ( void ) +{ + uint8_t exitflag = 0; + logbase = Logbase(); + physbase = Physbase(); + + bmp[0] = Load_Data("DATA\\FRAME.RAW", 28160); + Load_Pal("DATA\\FRAME1.PAL"); + memcpy(logbase, bmp[0], 28160); + //lz4w_unpack(bmp[0], physbase); + + while(1){} + + return 0; +}*/ + + +int main ( void ) +{ + uint8_t exitflag = 0; + + logbase = Logbase(); + physbase = Physbase(); + + Setscreen(logbase, physbase, ST_LOW); + + Init_Machine(); + + mainsound.Init_Sound(); + + hibcd[0] = 48; + hibcd[1] = 48; + hibcd[2] = 48; + hibcd[3] = '\0'; + + switch_gamemode(0); + + while(exitflag == 0) + { + if(IKBD_IsKeyPressed(IKBD_KEY_ESC)) + { + exitflag = 1; + } + + switch(game_mode) + { + default: + if (IKBD_IsKeyPressed(IKBD_KEY_SPACE)) + { + switch_gamemode(jump[game_mode]); + } + break; + case 1: + time_game+=1; + + if (FRAME_CURRENT > 0 && status_level1[status] != END_GAME_STATUS) + { + if (status_level1[status] == STOP_GAME_STATUS) + { + if (!(bcd[2] == 48 && bcd[0] == 48 && bcd[1] == 48)) + { + decrease_score(1); + } + } + else + { + add_score(1); + } + + FRAME_CURRENT++; + if (FRAME_CURRENT > 8) FRAME_CURRENT = 0; + + //lz4w_unpack(bmp[FRAME_CURRENT], physbase); + memcpy(physbase, bmp[0] + (FRAME_CURRENT * 28160), 28160); + Draw_Text(bcd, 0, 188, 15); + } + + if (FRAME_CURRENT == 0) + { + if (IKBD_IsKeyPressed(IKBD_KEY_SPACE)) + { + mainsound.Play_Sound(0, special_sound); + if (special_sound == 1) + { + special_sound = 0; + } + FRAME_CURRENT = 1; + } + } + + + if (time_game > 128) + { + if (status_level1[status] == END_GAME_STATUS) + { + switch_gamemode(2); + } + else + { + time_game = 0; + status++; + if (status_level1[status] == KEEPITUP_GAME_STATUS) + { + special_sound = 1; + } + Draw_Text_Center(ingame_quote[status_level1[status]], 180, 15); + } + } + break; + case 3: + if (IKBD_IsKeyPressed(IKBD_KEY_SPACE)) + { + text_progress++; + + if (text_progress > 4) + { + switch_gamemode(4); + } + else + { + Clear_Text(); + switch(text_progress) + { + case 1: + lz4w_unpack(bmp[1], physbase); + Draw_Text("You're going to be the perfect victim", 0, 180, 15); + Draw_Text("for my games!", 0, 188, 15); + mainsound.Load_Sound(soundfiles[isSoundDMA][1], 0); + break; + case 2: + lz4w_unpack(bmp[0], physbase); + Draw_Text("I'm Rikuto, i offer you the chance to", 0, 180, 15); + Draw_Text("prove your worth in a trial", 0, 188, 15); + mainsound.Load_Sound(soundfiles[isSoundDMA][2], 0); + break; + case 3: + lz4w_unpack(bmp[1], physbase); + Draw_Text("Don't be scared, it'll be fun!", 0, 180, 15); + mainsound.Load_Sound(soundfiles[isSoundDMA][3], 0); + break; + case 4: + lz4w_unpack(bmp[0], physbase); + Draw_Text("Your challenge will be this: you'll be", 0, 180, 15); + Draw_Text("on the other end and punish them", 0, 188, 15); + mainsound.Load_Sound(soundfiles[isSoundDMA][4], 0); + break; + } + mainsound.Play_Sound(0, 0); + } + } + break; + } + + Vsync(); + } + + for(i=0;i<12;i++) + { + Free_Data(bmp[i]); + } + Close_Machine(); +} + +void switch_gamemode(unsigned char mode) +{ + game_mode = mode; + text_progress = 0; + status = 0; + time_game = 0; + special_sound = 0; + i = 0; + + for(i=0;i<2;i++) + { + Free_Data(bmp[i]); + } + + memset(physbase, 0, 32000); + + switch(mode) + { + case 0: + bmp[0] = Load_Data("DATA\\TITLE.LZ", 13262); + Load_Pal("DATA\\TITLE.PAL"); + lz4w_unpack(bmp[0], physbase); + //memcpy(physbase, bmp[0], 1); + + Draw_Text_Center("COPYRIGHT INFRINGEMENT", 16, 15); + Draw_Text_Center("THE REGRESSIVE RIGHT", 16+8, 15); + Draw_Text_Center("BY GAMEBLABLA 2023", 16+16, 15); + + Draw_Text_Center("PRESS SPACE TO PLAY", 160, 15); + Draw_Text("HISCORE", 0, 175, 15); + Draw_Text(hibcd, 0, 188, 15); + break; + case 1: + bcd[0] = 48; + bcd[1] = 48; + bcd[2] = 48; + bcd[3] = '\0'; + + //bmp[0] = Load_Data("DATA\\FRAME1.LZ"); + //bmp[1] = Load_Data("DATA\\FRAME2.LZ"); + //bmp[2] = Load_Data("DATA\\FRAME3.LZ"); + //bmp[3] = Load_Data("DATA\\FRAME4.LZ"); + //bmp[4] = Load_Data("DATA\\FRAME5.LZ"); + //bmp[5] = Load_Data("DATA\\FRAME6.LZ"); + //bmp[6] = Load_Data("DATA\\FRAME7.LZ"); + //bmp[7] = Load_Data("DATA\\FRAME8.LZ"); + //bmp[8] = Load_Data("DATA\\FRAME9.LZ"); + + bmp[0] = Load_Data("DATA\\FRAME.RAW", 253440); + Load_Pal("DATA\\FRAME1.PAL"); + memcpy(physbase, bmp[0], 28160); + + mainsound.Load_Sound(soundfiles[isSoundDMA][5], 0); + mainsound.Load_Sound(soundfiles[isSoundDMA][6], 1); + + DrawHUD(); + break; + case 2: + bmp[0] = Load_Data("DATA\\RIK.LZ", 18082); + Load_Pal("DATA\\RIK.PAL"); + lz4w_unpack(bmp[0], physbase); + + Draw_Text("Your SCORE was ", 0, 0, 15); + Draw_Text(bcd, 0, 16, 15); + + //Canonical approach, thanks calcmaniac + diff = bcd[0] - hibcd[0]; + if (diff == 0) + diff = bcd[1] - hibcd[1]; + if (diff == 0) + diff = bcd[2] - hibcd[2]; + + if (diff > 0) + { + hibcd[0] = bcd[0]; + hibcd[1] = bcd[1]; + hibcd[2] = bcd[2]; + } + + Clear_Text(); + + if (bcd[0] < 48+3) + { + Draw_Text("Guess you'll stay there for a while", 0, 180, 15); + } + else if (bcd[0] < 48+5) + { + Draw_Text("Not bad but you can do better!", 0, 180, 15); + Draw_Text("Otherwise you can't leave this place!", 0, 188, 15); + } + else + { + Draw_Text("Congrats! I'll leave you alone.", 0, 180, 15); + Draw_Text("This won't be the last of me!", 0, 188, 15); + } + break; + case 3: + bmp[0] = Load_Data("DATA\\RIK.LZ", 18082); + bmp[1] = Load_Data("DATA\\RIKL.LZ", 18148 ); + Load_Pal("DATA\\RIK.PAL"); + lz4w_unpack(bmp[0], physbase); + + Draw_Text("Oh my, what do we have here?", 0, 180, 15); + Draw_Text("You look so innocent", 0, 188, 15); + + mainsound.Load_Sound(soundfiles[isSoundDMA][0], 0); + mainsound.Play_Sound(0, 0); + break; + case 4: + Draw_Text("Your goal is to FUCK Zhongli!", 0, 8, 15); + Draw_Text("Follow the instructions to get points", 0, 16, 15); + Draw_Text("Penetrate him by pressing a key", 0, 24, 15); + Draw_Text("Good luck !", 0, 64, 15); + break; + } + +} diff --git a/AtariST/mouse.c b/AtariST/mouse.c new file mode 100755 index 0000000..e672ce4 --- /dev/null +++ b/AtariST/mouse.c @@ -0,0 +1,106 @@ +/* + * + * IKBD 6301 interrupt routine + * (c) 2010/11/14 by Simon Sunnyboy / Paradize + * http://paradize.atari.org/ + * + * mouse data collection + * + * derived from a similar routine Copyright (C) 2002 Patrice Mandin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ikbd.h" + +/* driver internal variables*/ +extern volatile uint8_t IKBD_MouseB; /* Mouse on port 0, buttons (driver internal) */ +extern volatile int16_t IKBD_MouseX; /* Mouse X position (driver internal) */ +extern volatile int16_t IKBD_MouseY; /* Mouse Y position (driver internal) */ + +/* variables */ +volatile IKBD_MouseData IKBD_Mouse; /* mouse data */ + +uint8_t MouseThreshold = 128; /* mouse threshold (255 = 200%) */ + +/* reads the accumulated mouse packets and updates the mouse position */ +void IKBD_ReadMouse() +{ + int16_t xoffset, yoffset; + + if(MouseThreshold > 0) + { + /* scale the mouse movement by the configurable threshold */ + xoffset = (int16_t)((int32_t)(IKBD_MouseX * MouseThreshold) / 128); + yoffset = (int16_t)((int32_t)(IKBD_MouseY * MouseThreshold) / 128); + } + else + { + /* 0% scaling is not allowed -> scale as 100% */ + xoffset = IKBD_MouseX; + yoffset = IKBD_MouseY; + } + + IKBD_Mouse.b = IKBD_MouseB; + IKBD_Mouse.x = IKBD_Mouse.x + xoffset; + IKBD_Mouse.y = IKBD_Mouse.y + yoffset; + + if(IKBD_Mouse.limit != 0) + { + /* mouse coordinates limitation is active? */ + if(IKBD_Mouse.x < 0) + { + IKBD_Mouse.x = 0; + } + else if(IKBD_Mouse.x > IKBD_Mouse.w) + { + IKBD_Mouse.x = IKBD_Mouse.w; + } + if(IKBD_Mouse.y < 0) + { + IKBD_Mouse.y = 0; + } + else if(IKBD_Mouse.y > IKBD_Mouse.h) + { + IKBD_Mouse.y = IKBD_Mouse.h; + } + } + + /* acknowledge accumulated mouse vector (driver internals) */ + IKBD_MouseX = 0; + IKBD_MouseY = 0; + return; +} + +/* allows to configure teh scaling of relative mouse movement */ +void IKBD_SetMouseThreshold(uint8_t new_threshold) +{ + MouseThreshold = new_threshold; + return; +} + +/* allows to set current mouse position and define the screen size */ +void IKBD_SetMouseOrigin(int16_t x, int16_t y, uint16_t w, uint16_t h) +{ + IKBD_Mouse.x = x; + IKBD_Mouse.y = y; + IKBD_Mouse.w = w; + IKBD_Mouse.h = h; + IKBD_Mouse.b = 0; + IKBD_Mouse.limit = 1; + IKBD_MouseX = 0; + IKBD_MouseY = 0; + return; +} diff --git a/AtariST/new_disk.st b/AtariST/new_disk.st new file mode 100644 index 0000000..e6aa1f6 Binary files /dev/null and b/AtariST/new_disk.st differ diff --git a/AtariST/pngtost.py b/AtariST/pngtost.py new file mode 100644 index 0000000..fe8b1f3 --- /dev/null +++ b/AtariST/pngtost.py @@ -0,0 +1,56 @@ +import sys +from PIL import Image +import struct +import numpy as np + +def rgb_to_rgb333(color): + r, g, b = color + # Scale the 8-bit RGB components to 3-bit + r >>= 5 + g >>= 5 + b >>= 5 + # Shift to correct positions + r <<= 8 + g <<= 4 + # Combine the components + return (r & 0x0700) | (g & 0x0070) | (b & 0x0007) + + + +def set320x200(x, y, colour, buffer): + ptr = (y * 80) + (x // 16) * 4 + pixel = x % 16 + for i in range(4): + if colour & (1 << i): + buffer[ptr + i] |= 1 << (15 - pixel) + else: + buffer[ptr + i] &= ~(1 << (15 - pixel)) + +def png_to_pi1(png_path, pi1_path): + # Load the PNG image + img = Image.open(png_path).convert('P') + width, height = img.size + pixels = list(img.getdata()) + palette = img.getpalette()[:16*3] + + # Translate the color data into the Degas PI1 format + pi1_palette = [rgb_to_rgb333(palette[i:i+3]) for i in range(0, len(palette), 3)] + + # Translate the pixel data into the Degas PI1 format + buffer = [0] * (width * height // 4) + for i, pixel in enumerate(pixels): + x = i % width + y = i // width + set320x200(x, y, pixel, buffer) + + # Write the translated data into a PI1 file + with open(pi1_path, 'wb') as f: + f.write(struct.pack('>H', 0)) # screen resolution + f.write(struct.pack('>16H', *pi1_palette)) # palette + f.write(struct.pack('>{}H'.format(len(buffer)), *buffer)) # pixel data + +# Example usage +if len(sys.argv) != 3: + print("Usage: python script.py input.png output.pi1") +else: + png_to_pi1(sys.argv[1], sys.argv[2]) diff --git a/AtariST/psg.c b/AtariST/psg.c new file mode 100644 index 0000000..d449f96 --- /dev/null +++ b/AtariST/psg.c @@ -0,0 +1,158 @@ +#include "psg.h" + +volatile uint8_t *PSG_reg_select = (volatile uint8_t *)0xFF8800; +volatile uint8_t *PSG_reg_write = (volatile uint8_t *)0xFF8802; + + +/* + * Writes the given byte value (0-255) to the given PSG register (0-15). This is a helper routine to be + * used by the other functions in this module. + */ + +void WritePsg(int reg, uint8_t val) +{ + *PSG_reg_select = reg; + *PSG_reg_write = val; +} + +/* + * useful for testing purposes. + */ + +uint8_t ReadPsg(int reg) +{ + *PSG_reg_select = reg; + return *PSG_reg_select; +} + +/* + * Loads the tone registers (coarse and fine) for the given channel (0=A, 1=B, 2=C) with the given + * 12-bit tuning. + */ + +void SetTone(int channel, int tuning) +{ + uint8_t rough_tone = ROUGH_MASK_12BIT(tuning); + uint8_t fine_tone = FINE_MASK_12BIT(tuning); + + switch (channel) + { + case CHANNEL_A: + WritePsg(R0, fine_tone); + WritePsg(R1, rough_tone); + break; + case CHANNEL_B: + WritePsg(R2, fine_tone); + WritePsg(R3, rough_tone); + break; + case CHANNEL_C: + WritePsg(R4, fine_tone); + WritePsg(R5, rough_tone); + break; + default: + break; + } +} + +/* + * Loads the volume register for the given channel. + * + * Bit 4 (mode): When M = 0 level is determined by b3, b2, b1, b0, + * When M = 1 level is determined by the 5 bit outpuit of e4, e3, e2, e1, and e0 of the envelope generator of the SSG. + */ + +void SetVolume(int channel, int volume) +{ + switch (channel) + { + case CHANNEL_A: + WritePsg(R8, volume); + break; + case CHANNEL_B: + WritePsg(R9, volume); + break; + case CHANNEL_C: + WritePsg(RA, volume); + break; + default: + break; + } +} + +/* + * Turns the given channel’s tone/noise signals on/off (0=off, 1=on). + */ + +void EnableChannel(int channel, int tone_on, int noise_on) +{ + if (!tone_on && !noise_on) + { + WritePsg(R7, IO_OFF); + return; + } + + switch (channel) + { + case CHANNEL_A: + if (tone_on && noise_on) + WritePsg(R7, IO_A_NOISEON_TONEON); + else if (noise_on) + WritePsg(R7, IO_A_NOISEON_TONEOFF); + else /* noise off */ + WritePsg(R7, IO_A_NOISEOFF_TONEON); + break; + case CHANNEL_B: + if (noise_on && noise_on) + WritePsg(R7, IO_B_NOISEON_TONEON); + else if (noise_on) + WritePsg(R7, IO_B_NOISEON_TONEOFF); + else /* noise off */ + WritePsg(R7, IO_B_NOISEOFF_TONEON); + break; + case CHANNEL_C: + if (tone_on && noise_on) + WritePsg(R7, IO_C_NOISEON_TONEON); + else if (noise_on) + WritePsg(R7, IO_C_NOISEON_TONEOFF); + else /* noise off */ + WritePsg(R7, IO_C_NOISEOFF_TONEON); + break; + default: + break; + } +} + +/* + * Silences all PSG sound production. + */ + +void StopSound(void) +{ + int count; + for (count = 0x1; count <= 0xd; count++) + WritePsg(count, 0); +} + +/* + * Loads the noise register with the given tuning. + */ + +void SetNoise(int tuning) +{ + WritePsg(R6, tuning); +} + +/* + * Loads the PSG envelope control registers with the given envelope shape and + * 16-bit sustain. + */ + +void SetEnvelope(int shape, unsigned int sustain) +{ + uint8_t fine = FINE_MASK_16BIT(sustain); + uint8_t rough = ROUGH_MASK_16BIT(sustain); + + WritePsg(RB, fine); + WritePsg(RC, rough); + WritePsg(RD, shape); +} diff --git a/AtariST/psg.h b/AtariST/psg.h new file mode 100644 index 0000000..48472b3 --- /dev/null +++ b/AtariST/psg.h @@ -0,0 +1,88 @@ +#ifndef PSG_H +#define PSG_H +#include /* for type t */ + +#define CHANNEL_A 0 +#define CHANNEL_B 1 +#define CHANNEL_C 2 + +#define MAKE_TONE_12BIT(f, r) (((f) << 4) | (r)) +#define ROUGH_MASK_12BIT(a) ((a)&0x000F) +#define FINE_MASK_12BIT(a) (((a)&0x0FF0) >> 4) + +#define MAKE_TONE_16BIT(f, r) (((f) << 8) | (r)) +#define ROUGH_MASK_16BIT(a) ((a)&0x00FF) +#define FINE_MASK_16BIT(a) (((a)&0xFF00) >> 8) + +#define R0 0x0 +#define R1 0x1 +#define R2 0x2 +#define R3 0x3 +#define R4 0x4 +#define R5 0x5 +#define R6 0x6 +#define R7 0x7 +#define R8 0x8 +#define R9 0x9 +#define RA 0xA +#define RB 0xB +#define RC 0xC +#define RD 0xD +#define RE 0xE +#define RF 0xF + +/* IOB IOC | C B A | C B A */ +#define IO_A_NOISEON_TONEON 0x36 /* 0 0 1 1 0 1 1 0 */ +#define IO_A_NOISEON_TONEOFF 0x37 /* 0 0 1 1 0 1 1 1 */ +#define IO_A_NOISEOFF_TONEON 0x3E /* 0 0 1 1 1 1 1 0 */ + +#define IO_B_NOISEON_TONEON 0x2D /* 0 0 1 0 1 1 0 1 */ +#define IO_B_NOISEON_TONEOFF 0x2F /* 0 0 1 0 1 1 1 1 */ +#define IO_B_NOISEOFF_TONEON 0x3D /* 0 0 1 1 1 1 0 1 */ + +#define IO_C_NOISEON_TONEON 0x1B /* 0 0 0 1 1 0 1 1 */ +#define IO_C_NOISEON_TONEOFF 0x1F /* 0 0 0 1 1 1 1 1 */ +#define IO_C_NOISEOFF_TONEON 0x3B /* 0 0 1 1 1 0 1 1 */ + +#define IO_OFF 0x3F /* 0 0 1 1 1 1 1 1 */ + +/* + * Envelope control register + * shapes, and sustain register bit values + * + * B3 B2 B1 B0 + * CONT ATT ALT HOLD + * + * 0 0 x x \_______________________ 0x00 + * 0 1 x x / |_____________________ 0x04 + * 1 0 0 0 \ |\ |\ |\ |\ |\ |\ |\ 0x08 + * 1 0 0 1 \_______________________ 0x09 + * 1 0 1 0 \ /\ /\ /\ /\ /\ / 0x0A + * 1 0 1 1 \ |-------------------- 0x0B + * 1 1 0 0 / | /| /| /| /| /| /| / 0x0C + * 1 1 0 1 / ______________________ 0x0D + * 1 1 1 0 / \ /\ /\ /\ /\ /\ 0x0E + * 1 1 1 1 / |_____________________ 0x0F + */ + +#define ENV_CONT_OFF_ATT_OFF 0x00 +#define ENV_CONT_OFF_ATT_ON 0x04 +#define ENV_CONT_ON_ATT_OFF_ALT_OFF_HOLD_OFF 0x08 +#define ENV_CONT_ON_ATT_OFF_ALT_OFF_HOLD_ON 0x09 +#define ENV_CONT_ON_ATT_OFF_ALT_ON_HOLD_OFF 0x0A +#define ENV_CONT_ON_ATT_OFF_ALT_ON_HOLD_ON 0x0B +#define ENV_CONT_ON_ATT_ON_ALT_OFF_HOLD_OFF 0x0C +#define ENV_CONT_ON_ATT_ON_ALT_OFF_HOLD_ON 0x0D +#define ENV_CONT_ON_ATT_ON_ALT_ON_HOLD_OFF 0x0E +#define ENV_CONT_ON_ATT_ON_ALT_ON_HOLD_ON 0x0F + +void SetEnvelope(int shape, unsigned int sustain); +void SetNoise(int tuning); +void StopSound(void); +void EnableChannel(int channel, int tone_on, int noise_on); +void SetVolume(int channel, int volume); +void SetTone(int channel, int tuning); +uint8_t ReadPsg(int reg); +void WritePsg(int reg, uint8_t val); + +#endif /* PSG_H */ diff --git a/AtariST/psgpcm.c b/AtariST/psgpcm.c new file mode 100644 index 0000000..696face --- /dev/null +++ b/AtariST/psgpcm.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include "psg.h" +#include "sound.h" + +typedef struct tagS +{ + unsigned char* data; + unsigned long size; +} SOUND; + +static SOUND snd[4]; + +static inline void memset32(void *ptr, uint32_t value, size_t num) { + uint32_t* p = (uint32_t*) ptr; + while(num--) { + *p++ = value; + } +} + +static void PSGPCM_free(uint8_t index) +{ + if (snd[index].data) Mfree(snd[index].data); +} + + +void PSGPCM_Stop(void) +{ + +} + +void PSGPCM_Load(const char* path, uint8_t index) +{ + int fp; + unsigned short handle; + + PSGPCM_Stop(); + PSGPCM_free(index); + + fp = Fopen(path, 0); + Fseek(0, fp, SEEK_END); + handle = fp & 0xFFFF; + snd[index].size = Fseek(0, handle, 2); + Fseek(0, handle, 0); + snd[index].data = (unsigned char *)Malloc(snd[index].size); + Fread(handle, snd[index].size, snd[index].data); + Fclose(handle); +} + + +void PSGPCM_Uninit(void) +{ + uint8_t i; + + SetVolume(CHANNEL_A, 0x0); + SetVolume(CHANNEL_B, 0x0); + + for(i=0;i<4;i++) + PSGPCM_free(i); + +} + +uint8_t PSGPCM_Init(void) +{ + SetTone(CHANNEL_A, 0); + SetTone(CHANNEL_B, 0); + SetTone(CHANNEL_C, 0); + return 1; +} + +void PSGPCM_Play(unsigned char loop, uint8_t index) +{ + uint32_t sample_size, current_sample; + unsigned char* mysample; + + current_sample = 0; + sample_size = snd[index].size; + mysample = snd[index].data; + + while(current_sample < sample_size) + { + uint8_t shift_value = (current_sample & 1) << 2; + SetVolume(CHANNEL_A, (mysample[current_sample] >> shift_value) & 0x0F); + SetVolume(CHANNEL_B, (mysample[current_sample] >> shift_value) & 0x0F); + SetVolume(CHANNEL_C, (mysample[current_sample] >> shift_value) & 0x0F); + current_sample++; + } + SetVolume(CHANNEL_A, 0x0); + SetVolume(CHANNEL_B, 0x0); + SetVolume(CHANNEL_C, 0x0); +} + + +SoundDevice PSGPCM_device = { + PSGPCM_Init, + PSGPCM_Uninit, + PSGPCM_Load, + PSGPCM_Play, + PSGPCM_Stop +}; + diff --git a/AtariST/reloc.bin b/AtariST/reloc.bin new file mode 100755 index 0000000..3ebd9c5 Binary files /dev/null and b/AtariST/reloc.bin differ diff --git a/AtariST/rikuto_laugh.png b/AtariST/rikuto_laugh.png new file mode 100644 index 0000000..3eb98b7 Binary files /dev/null and b/AtariST/rikuto_laugh.png differ diff --git a/AtariST/rikuto_normal.png b/AtariST/rikuto_normal.png new file mode 100644 index 0000000..5d5c01a Binary files /dev/null and b/AtariST/rikuto_normal.png differ diff --git a/AtariST/sound.h b/AtariST/sound.h new file mode 100644 index 0000000..1d61193 --- /dev/null +++ b/AtariST/sound.h @@ -0,0 +1,16 @@ +#ifndef SOUND_H +#define SOUND_H + +typedef struct MusicDevice { + unsigned char (*Init_Sound)(void); + void (*Uninit_Sound)(void); + + void (*Load_Sound)(const char* path, uint8_t index); + void (*Play_Sound)(unsigned char loop, uint8_t index); + void (*Stop_Sound)(); +} SoundDevice; + +extern SoundDevice PSGPCM_device; +extern SoundDevice DMA_device; + +#endif diff --git a/AtariST/startup.S b/AtariST/startup.S new file mode 100644 index 0000000..af3d286 --- /dev/null +++ b/AtariST/startup.S @@ -0,0 +1,203 @@ +| Multi Atari Boot code. +| If you have done an ST demo, use that boot to run it on these machines: +| +| ST, STe, Mega-ST,TT,Falcon,CT60 +| +| More info: +| http://leonard.oxg.free.fr/articles/multi_atari/multi_atari.html +| +| GNU as/gcc compatible startup code by mfro +| Integration (c) 2014 by Simon Sunnyboy / Paradize +| + + + .equ BASEPAGE_SIZE,0x100 + .equ STACK_SIZE,0x4000 + .equ MCH,0x5f4d4348 + .equ CT60,0x43543630 + + .text + .globl ___main + +start: + move.l 4(sp),a5 | address to basepage + move.l 0x0c(a5),d0 | length of text segment + add.l 0x14(a5),d0 | length of data segment + add.l 0x1c(a5),d0 | length of bss segment + add.l #STACK_SIZE+BASEPAGE_SIZE,d0 | length of stackpointer+basepage + move.l a5,d1 | address to basepage + add.l d0,d1 | end of program + and.l #0xfffffff0,d1 | align stack + move.l d1,sp | new stackspace + + move.l d0,-(sp) | mshrink() + move.l a5,-(sp) + clr.w -(sp) + move.w #0x4a,-(sp) + trap #1 + lea.l 12(sp),sp + + pea leonard_init | Offset 2 + move.w #38,-(sp) | Offset 0 + trap #14 | Call XBIOS Supexec() + addq.l #6,sp | Correct stack + + + + + +exit: + clr.w -(sp) + trap #1 + +___main: + rts + + + +leonard_init: + + move.l 0x5a0.w,d0 + beq noCookie + move.l d0,a0 + .loop: move.l (a0)+,d0 + beq noCookie + cmp.l #MCH,d0 + beq.s .find + cmp.l #CT60,d0 + bne.s .skip + +| CT60, switch off the cache + pea (a0) + + lea bCT60(pc),a0 + st (a0) + + clr.w -(a7) | param = 0 ( switch off all caches ) + move.w #5,-(a7) | opcode + move.w #160,-(a7) + trap #14 + addq.w #6,a7 + move.l (a7)+,a0 + .skip: + addq.w #4,a0 + bra.s .loop + +.find: move.w (a0)+,d7 + beq noCookie | STF + move.b d7,0x1fe.w + + cmpi.w #1,d7 + bne.s .noSTE + btst.b #4,1(a0) + beq.s .noMegaSTE + clr.b 0xffff8e21.w | 8Mhz MegaSTE + +.noMegaSTE: + bra noCookie + +.noSTE: +| here TT or FALCON + +| Always switch off the cache on these machines. + move.b bCT60(pc),d0 + bne.s .noMovec + +moveq #0,d0 +dc.l 0x4e7b0002 | movec d0,cacr | switch off cache +.noMovec: + +cmpi.w #3,d7 +bne.s noCookie + +| Here FALCON +move.w #0x59,-(a7) |check monitortype (falcon) +trap #14 +addq.l #2,a7 +lea rgb50(pc),a0 +subq.w #1,d0 +beq.s .setRegs +subq.w #2,d0 +beq.s .setRegs +lea vga50(pc),a0 + +.setRegs: +move.l (a0)+,0xffff8282.w +move.l (a0)+,0xffff8286.w +move.l (a0)+,0xffff828a.w +move.l (a0)+,0xffff82a2.w +move.l (a0)+,0xffff82a6.w +move.l (a0)+,0xffff82aa.w +move.w (a0)+,0xffff820a.w +move.w (a0)+,0xffff82c0.w +move.w (a0)+,0xffff8266.w +clr.b 0xffff8260.w +move.w (a0)+,0xffff82c2.w +move.w (a0)+,0xffff8210.w + +noCookie: + +| Set res for all machines exept falcon or ct60 +cmpi.b #3,0x1fe.w +beq letsGo + +clr.w -(a7) |set stlow (st/tt) +moveq #-1,d0 +move.l d0,-(a7) +move.l d0,-(a7) +move.w #5,-(a7) +trap #14 +lea 12(a7),a7 + +cmpi.b #2,0x1fe.w | enough in case of TT +beq.s letsGo + +move.w 0x468.w,d0 +.vsync: cmp.w 0x468.w,d0 +beq.s .vsync + +move.b #2,0xffff820a.w +clr.b 0xffff8260.w + + +letsGo: + + jsr _main + + rts + + vga50: dc.l 0x170011 + dc.l 0x2020E + dc.l 0xD0012 + dc.l 0x4EB04D1 + dc.l 0x3F00F5 + dc.l 0x41504E7 + dc.w 0x0200 + dc.w 0x186 + dc.w 0x0 + dc.w 0x5 + dc.w 0x50 + + rgb50: dc.l 0x300027 + dc.l 0x70229 + dc.l 0x1e002a + dc.l 0x2710265 + dc.l 0x2f0081 + dc.l 0x211026b + dc.w 0x0200 + dc.w 0x185 + dc.w 0x0 + dc.w 0x0 + dc.w 0x50 + + bCT60: dc.b 0 + .even + + + .bss + +_basepage: ds.l 1 +_program_length: + ds.l 1 + + .end diff --git a/AtariST/stsprite.h b/AtariST/stsprite.h new file mode 100644 index 0000000..c4e5279 --- /dev/null +++ b/AtariST/stsprite.h @@ -0,0 +1,101 @@ +/** + * @file stsprite.h + * + * STFM Sprite kernel for GCC + * @author (c) 2008/2009/2018/2019 by Simon Sunnyboy / Paradize + * @copyright http://paradize.atari.org/ + * + * Special thanks and acknowledgements: + * -- ggn / Paradize (for writing the Blitter sprite routine for HOG mode + * and for finding the bugfix of the halftone mode) + * -- Paranoid / Paradox (for helping me making SHARED MODE work) + * -- PeP (for finding a serious bug which did lead to strange effects) + * -- LP (for helping debugging the Halftone mode bug) + * + * Version 0.5a 24.03.2008 (different interface) + * Version 0.9 25.03.2008 + * Version 0.99 06.06.2008 (beta version with support for Blitter) + * Version 1.00 25.02.2009 (first release version - Halftone mode bugfix) + * 10.04.2018 (gcc port) + * + * Draws up to 16 sprites with different sizes on screen + * + * The routine uses screen format so you can directly take sprites from + * a DEGAS picture. + * + * NO CLIPPING OF SPRITES! + */ + +/** @addtogroup STSprite + * @{ + */ + +#ifndef STSPRITE_H +#define STSPRITE_H + +#include + +/** + * @brief sprite handling object + */ +typedef struct +{ + uint16_t active; /**< flag !=0 means: draw sprite */ + uint16_t x; /**< x coordinate */ + uint16_t y; /**< y coordinate */ + uint16_t width; /**< width of sprite in 16pixel steps, e.q. 1 <=> 16 pixels, 2 <=> 32 pixels */ + uint16_t height; /**< height of sprite in scanlines */ + void *maskptr; /**< pointer to sprite mask (data in ST-LOW screen format) */ + void *spriteptr; /**< pointer to sprite data (data in ST-LOW screen format) */ +} st_sprite_t; + +enum stsprite_blitter_mode +{ + STSPRITE_USE_CPU = 0, /**< ... */ + STSPRITE_USE_HOGMODE = 1, /**< ... */ + STSPRITE_USE_SHAREDMODE = 2 /**< ... */ +}; + +/** + * @brief draws given list of sprites on screen + * @details The destination screen address must have been set before with STSprite_SetLogbase + * @param spr_list points to sprite records + * @param nr_of_sprites_in_list contains number of available sprite records in list + */ +void STSprite_HandleDrawing ( st_sprite_t * spr_list, uint16_t nr_of_sprites_in_list ); + +/** + * @brief set destination screen address in RAM for all drawing routines + * @param dest_screen_ptr + */ +void STSprite_SetLogbase ( void * dest_screen_ptr ); + +/** + * @brief draw given sprite to screen using CPU routines + * @param sprdata points to sprite to be drawn (active setting is ignored) + */ +void STSprite_DrawCPU ( st_sprite_t * sprdata ); + +/** + * @brief draw given sprite to screen using Blitter in SHARED mode + * @attention Availability of Blitter is not checked! + * @param sprdata points to sprite to be drawn (active setting is ignored) + */ +void STSprite_DrawBlitter ( st_sprite_t * sprdata ); + +/** + * @brief draw given sprite to screen using Blitter in HOG mode + * @attention Availability of Blitter is not checked! + * @param sprdata points to sprite to be drawn (active setting is ignored) + */ +void STSprite_DrawBlitterHog ( st_sprite_t * sprdata ); + +/** + * @brief configure sprite drawing routine used by STSprite_HandleDrawing + * @param stsprite_blitter_mode according to STSPRITE_USE_... enums + */ +void STSprite_SetBlitterMode ( uint16_t stsprite_blitter_mode ); + +#endif + +/** @} */ diff --git a/AtariST/stsprite_kernel.S b/AtariST/stsprite_kernel.S new file mode 100644 index 0000000..ab16de6 --- /dev/null +++ b/AtariST/stsprite_kernel.S @@ -0,0 +1,453 @@ +| +| STFM Sprite kernel for GFABASIC +| (c) 2008/2009/2018 by Simon Sunnyboy / Paradize +| http://paradize.atari.org/ +| +| Special thanks and acknowledgements: +| -- ggn / Paradize (for writing the Blitter sprite routine for HOG mode +| and for finding the bugfix of the halftone mode) +| -- Paranoid / Paradox (for helping me making SHARED MODE work) +| -- PeP (for finding a serious bug which did lead to strange effects) +| -- LP (for helping debugging the Halftone mode bug) +| +| Version 0.5a 24.03.2008 (different interface) +| Version 0.9 25.03.2008 +| Version 0.99 06.06.2008 (beta version with support for Blitter) +| Version 1.00 25.02.2009 (first release version - Halftone mode bugfix) +| 10.04.2018 (gcc port) +| Version 1.01 16.04.2023 (bugfix C stack access for STSprite_Draw.... functions) +| +| Draws up to 16 sprites with different sizes on screen +| +| INPUTs: +| spritelist - points to a buffer containing 16 sprite structures +| logbase - points to the screen where the next call of the +| routine should draw the sprites to +| blitter - a flag to indicate whether the Blitter shall draw sprites +| +| data structure per sprite +| struct { +| WORD active; /* !=0 means: draw sprite */ +| WORD x; /* x coordinate */ +| WORD y; /* y coordinate */ +| WORD width; /* width of sprite in 16pixel steps */ +| WORD height; /* height of sprite in scanlines */ +| LONG *maskptr; /* pointer to sprite mask */ +| LONG *spriteptr; /* pointer to sprite data */ +| } sprite_record; +| +| The routine uses screen format so you can directly take sprites from +| a DEGAS picture. +| +| NO CLIPPING OF SPRITES! +| +| -- offsets into structure for sprite record -- +.equ active,0 +.equ x,2 +.equ y,4 +.equ width,6 +.equ height,8 +.equ maskptr,10 +.equ sprptr,14 +| -- the number of sprites to process -- +.equ numbersprites,16 + +| -- Blitter equates +.equ halftone,0 +.equ src_xinc,32 +.equ src_yinc,34 +.equ src_addr,36 +.equ endmask1,40 +.equ endmask2,42 +.equ endmask3,44 +.equ dst_xinc,46 +.equ dst_yinc,48 +.equ dst_addr,50 +.equ x_count ,54 +.equ y_count ,56 +.equ hop ,58 +.equ op ,59 +.equ line_num,60 +.equ skew ,61 + +.equ blitter,0xFFFF8A00 + +.globl _STSprite_HandleDrawing +.globl _STSprite_DrawCPU +.globl _STSprite_DrawBlitter +.globl _STSprite_DrawBlitterHog +.globl _STSprite_SetBlitterMode +.globl _STSprite_SetLogbase + +.text + +_STSprite_HandleDrawing: + move.l 4(sp),spritelist + move.w 8(sp),nr_sprites + bra spritekernel + +_STSprite_DrawCPU: + move.l a6,-(sp) + movea.l 8(sp),a6 | get pointer from stack to register and + movem.l D2-D7/A2-A5,-(sp) + move.w x(A6),D0 | load sprite parameters + move.w y(A6),D1 + move.w width(A6),D6 + move.w height(A6),D7 + movea.l maskptr(A6),A0 + movea.l sprptr(A6),A1 + move.l logbase, A2 + + bsr draw_4bplsprite + movem.l (SP)+,D2-D7/A2-A5 + move.l (SP)+,a6 + rts + +_STSprite_DrawBlitter: + move.l a6,-(sp) + movea.l 8(sp),a6 | get pointer from stack to register and + movem.l D2-D7/A2-A5,-(sp) + + move.w x(A6),D0 | load sprite parameters + move.w y(A6),D1 + move.w width(A6),D6 + move.w height(A6),D7 + movea.l maskptr(A6),A0 + movea.l sprptr(A6),A1 + move.l logbase, A2 + + bsr draw_4bplsprite_blitter + movem.l (SP)+,D2-D7/A2-A5 + move.l (SP)+,a6 + rts + +_STSprite_DrawBlitterHog: + move.l a6,-(sp) + movea.l 8(sp),a6 | get pointer from stack to register and + movem.l D2-D7/A2-A5,-(sp) + + move.w x(A6),D0 | load sprite parameters + move.w y(A6),D1 + move.w width(A6),D6 + move.w height(A6),D7 + movea.l maskptr(A6),A0 + movea.l sprptr(A6),A1 + move.l logbase, A2 + + bsr draw_4bplsprite_hog + movem.l (SP)+,D2-D7/A2-A5 + move.l (SP)+,a6 + rts + +_STSprite_SetBlitterMode: + move.w 4(sp),use_blitter + rts + +_STSprite_SetLogbase: + move.l 4(sp),logbase + rts + + +| jump table +entry: bra spritekernel | +0 draw sprites + bra draw_4bplsprite | +4 draw single sprite with CPU + bra draw_4bplsprite_blitter | +8 draw sprite with Blitter + +| data interface for GFABASIC: +spritelist: DC.L 0 | +12 pointer to sprite records +logbase: DC.L 0 | +16 pointer to screen +use_blitter: DC.W 0 | +20 flag to indicate: draw sprite with Blitter +nr_sprites: DC.W 16 | +22 number of sprites to draw + DC.W 0 + DC.L 0,0,0,0,0,0,0 | space for future additions + .even + .asciz "STFM Sprite Kernel by Paradize v1.01 (gcc version)" + .even +spritekernel: + movem.l D0-A6,-(SP) +| 'Choose Sprite routine' + move.w use_blitter(PC),D0 + tst.w D0 | use Blitter? + bne.s use_blitterrout | !=0 then yes +| no Blitter => use CPU sprite blit + lea draw_4bplsprite(PC),A6 | draw routine to use + bra.s continue_kernel +| Blitter activated => use Blitter sprite blit +use_blitterrout: + cmpi.w #1,D0 | Blitter == 1 + bne use_shared_mode | if == 1 then use hogmode + lea draw_4bplsprite_hog(PC),A6 + bra.s continue_kernel +use_shared_mode: + lea draw_4bplsprite_blitter(PC),A6 +continue_kernel: + + move.w nr_sprites(PC),D3 | loop counter + subq.w #1,D3 + + movea.l logbase(PC),A2 | load logbase to use + movea.l spritelist(PC),A5 | start of sprite records +| --- main loop sprite kernel --- +for_i_in_sprites: + tst.w active(A5) + beq.s next_sprite | if not active skip sprite +| 'copy sprite parameters' + move.w x(A5),D0 | load sprite parameters + move.w y(A5),D1 + move.w width(A5),D6 + move.w height(A5),D7 + movea.l maskptr(A5),A0 + movea.l sprptr(A5),A1 + + jsr (A6) | draw with selected routine + +next_sprite: + lea 18(A5),A5 | next sprite in list + dbra D3,for_i_in_sprites + movem.l (SP)+,D0-A6 + rts + +| 'CPU Sprite w/o preshift' +| +| Universal Sprite routine for STFM and STE +| (c) 2008 by Simon Sunnyboy / Paradize +| http://paradize.atari.org/ +| +| This source is based upon a snippet I found ages ago on the net. +| It was buggy and didn't work as expected. After understanding what's +| going on, I could fix pointer offsets and parameter calculation +| so that it is now working now. +| Credits to whoever wrote the first sketch of this code :) +| +| Draws a 4 bitplane sprite at any position on screen. This routine is for +| 320*200 ST-LOW. +| +| Sprite width : any multiple of 16pixel (the more the slower) +| Sprite height: any amount of scanlines +| +| Coordinates and sprites will not be clipped so be careful with borders! +| No preshift necessary (slower but saves memory) +| No background saving and restoring +| +| INPUT: d0.w: x position of sprite on screen (left side) +| d1.w: y position of sprite on screen (top side) +| d6.w: number of 16pixel blocks to do +| d7.w: number of Y lines to to +| a0: address of maskdata (screen format) +| a1: address of bitmapdata (screen format) +| a2: screen start address +| +draw_4bplsprite: + movem.l D0-A6,-(SP) + + clr.l D2 + move.w D0,D2 | shifts = x AND 16 = x MOD 16 + andi.w #0x0F,D2 | number of shifts + + andi.w #0xFFF0,D0 | xoffset = x DIV 8 + lsr.w #1,D0 + adda.w D0,A2 | screenstart + xoffset + mulu #160,D1 | y=y*160 + adda.l D1,A2 | screenstart + yoffset + + move.w #160,D4 | length of a scanline + move.w D6,D3 | get number of 16pixel rows + lsl.w #3,D3 | rows=rows*8 + sub.w D3,D4 | skip = 160 - rows*8 bytes + + subq.w #1,D7 | adjust loop counter + subq.w #1,D6 | adjust loop counter + move.w D6,D5 | backup xloop counter in d5.w. + +yloop: + +xloop: moveq #-1,D0 | prepare for maskshifting. + move.w (A0)+,D0 | get 16pixel maskdata in d0.w. + addq.l #6,A0 | skip 3 planes + ror.l D2,D0 | shift it! + and.w D0,0(A2) | mask bitplane 0. + and.w D0,2(A2) | mask bitplane 1. + and.w D0,4(A2) | mask bitplane 2. + and.w D0,6(A2) | mask bitplane 3. + swap D0 | get mask overspill in loword. + and.w D0,8(A2) | mask overspill bitplane 0. + and.w D0,10(A2) | mask overspill bitplane 1. + and.w D0,12(A2) | mask overspill bitplane 2. + and.w D0,14(A2) | mask overspill bitplane 3. + .rept 4 + moveq #0,D0 | prepare for bitmapshifting. + move.w (A1)+,D0 | get bitplane word in d0.w. + ror.l D2,D0 | shift it. + or.w D0,(A2)+ | paint bitplane into hole + swap D0 | get overspill in loword. + or.w D0,6(A2) | paint overspill bitplane + .endr + dbra D6,xloop | loop until all blocks done. + + adda.l D4,A0 | next scanline mask + adda.l D4,A1 | next scanline sprite data + adda.l D4,A2 | goto next screenline. + move.w D5,D6 | restore xloop counter. + dbra D7,yloop | loop until all lines done. + + movem.l (SP)+,D0-A6 + rts + +| 'Blitter sprite HOT RESTART' +| Sprite routine for Blitter in SHARED MODE +| designed and coded by ggn / Paradize +| +| same interfacing as CPU routine + +draw_4bplsprite_blitter: + movem.l D0-A6,-(SP) + lea blitter.w,A5 + +| +| Step 1: blit the mask +| + + addq.w #1,D6 + move.w D6,x_count(A5) + move.w #8,src_xinc(A5) + move.w #8,dst_xinc(A5) + move.w #160,D2 + subq.w #1,D6 + lsl.w #3,D6 + sub.w D6,D2 + + move.w D2,src_yinc(A5) + move.w D2,dst_yinc(A5) + mulu #160,D1 |eek! mulu!!! + move.w D0,D2 + lsr.w #1,D2 + andi.w #~0b111,D2 |(x/16)*8 + add.w D2,D1 |dest offset + lea 0(A2,D1.w),A2 |a2=dest address + moveq #-1,D2 + move.w D2,endmask2(A5) + and.b #15,D0 + lsr.w D0,D2 + move.w D2,endmask1(A5) + not.w D2 + move.w D2,endmask3(A5) + move.b #2,hop(A5) | Halftone mode + move.b #1,op(A5) |S AND D + move.b D0,skew(A5) + + moveq #3,D2 +blitmasks_shared: btst #7,0xFFFF8A3C | wait for Blitter to have finished + nop + bne.s blitmasks_shared + + + move.l A0,src_addr(A5) + move.l A2,dst_addr(A5) + move.w D7,y_count(A5) + move.b #128,line_num(A5) | hot restart +poll_blitter1: bset #7,0xFFFF8A3C | test and set Blitter busy bit + nop | idle a bit - to leave time for IRQs + bne.s poll_blitter1 + + addq.w #2,A0 + addq.w #2,A2 + dbra D2,blitmasks_shared + +| +| Step 2: blit the sprite +| +wait_blitter: btst #7,0xFFFF8A3C | wait for Blitter to finish + nop + bne.s wait_blitter + + + move.b #7,op(A5) |S OR D + subq.w #8,A2 + moveq #3,D2 +blitsprite_shared: btst #7,0xFFFF8A3C + nop + bne.s blitsprite_shared + + + move.l A1,src_addr(A5) + move.l A2,dst_addr(A5) + move.w D7,y_count(A5) + move.b #128,line_num(A5) +poll_blitter2: bset #7,0xFFFF8A3C | test and set Blitter busy bit + nop | idle a bit - to leave time for IRQs + bne.s poll_blitter2 + + + addq.w #2,A1 + addq.w #2,A2 + dbra D2,blitsprite + movem.l (SP)+,D0-A6 + rts + +| 'Blitter sprite HOGMODE' +| same but with using HOGMODE + +draw_4bplsprite_hog: + movem.l D0-A6,-(SP) + lea blitter.w,A5 + +| +| Step 1: blit the mask +| + + addq.w #1,D6 + move.w D6,x_count(A5) + move.w #8,src_xinc(A5) + move.w #8,dst_xinc(A5) + move.w #160,D2 + subq.w #1,D6 + lsl.w #3,D6 + sub.w D6,D2 + + move.w D2,src_yinc(A5) + move.w D2,dst_yinc(A5) + mulu #160,D1 |eek! mulu!!! + move.w D0,D2 + lsr.w #1,D2 + andi.w #~0b111,D2 |(x/16)*8 + add.w D2,D1 |dest offset + lea 0(A2,D1.w),A2 |a2=dest address + moveq #-1,D2 + move.w D2,endmask2(A5) + and.b #15,D0 + lsr.w D0,D2 + move.w D2,endmask1(A5) + not.w D2 + move.w D2,endmask3(A5) + move.b #2,hop(A5) |Halftone mode + move.b #1,op(A5) |S AND D + move.b D0,skew(A5) + + moveq #3,D2 +blitmasks: move.l A0,src_addr(A5) + move.l A2,dst_addr(A5) + move.w D7,y_count(A5) + move.b #192,line_num(A5) | Hogmode + addq.w #2,A0 + addq.w #2,A2 + dbra D2,blitmasks + +| +| Step 2: blit the sprite +| + + move.b #7,op(A5) |S OR D + subq.w #8,A2 + moveq #3,D2 +blitsprite: move.l A1,src_addr(A5) + move.l A2,dst_addr(A5) + move.w D7,y_count(A5) + move.b #192,line_num(A5) | Hog Mode + addq.w #2,A1 + addq.w #2,A2 + dbra D2,blitsprite + + movem.l (SP)+,D0-A6 + rts + +.end diff --git a/AtariST/wizzcat.S b/AtariST/wizzcat.S new file mode 100755 index 0000000..459f330 --- /dev/null +++ b/AtariST/wizzcat.S @@ -0,0 +1,93 @@ + # + # GCC interface for Wizzcat 12kHz Protracker replay (STE only) + # based on the Wizzcat interface by GT Turbo / Cerebral Vortex for GFABASIC + # + # GCC interface (c) 2014 by Simon Sunnyboy / Paradize (based upon AHCC interface) + # + + .globl _Wizzcat_Init + .globl _Wizzcat_Play + .globl _Wizzcat_Stop + + .equ Wizz, 0x57697A7A + + .text + +_Wizzcat_Init: + movem.l d0-a6,-(sp) + cmpi.l #Wizz,wizzcat_initmark + beq end_init + # relocate Wizzcat routine: + movem.l regs,d0-a6 + + lea wizzcat_rout,a0 + bsr reloc + # mark routine as ready + move.l #Wizz,wizzcat_initmark + clr.w wizzcat_playing +end_init: + movem.l (sp)+,d0-a6 + rts + +tunestart: dc.l 0 +tuneend: dc.l 0 + +_Wizzcat_Play: + move.l 4(sp),tunestart + move.l 8(sp),tuneend + + movem.l d0-a6,-(sp) + cmpi.l #Wizz,wizzcat_initmark + bne assert_wizzcat_failed + cmpi.w #0,wizzcat_playing + bne assert_wizzcat_failed + move.w #-1,wizzcat_playing + + movem.l regs,d0-d7 + move.l tunestart,a0 + move.l tuneend,a1 + movem.l regs,a2-a6 + + bsr wizzcat_rout + + movem.l (sp)+,d0-a6 + rts + +_Wizzcat_Stop: + movem.l d0-a6,-(sp) + cmpi.l #Wizz,wizzcat_initmark + bne assert_wizzcat_failed + cmpi.w #-1,wizzcat_playing + bne assert_wizzcat_failed + clr.w wizzcat_playing + + movem.l regs,d0-a6 + + bsr wizzcat_rout+2 + +assert_wizzcat_failed: + movem.l (sp)+,d0-a6 + rts + .even +reloc: + .incbin "reloc.bin" + .even +wizzcat_rout: + .incbin "wizzcat.bin" + .even + dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .even + .DATA +regs: + dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .even +wizzcat_initmark: + dc.l 0 +wizzcat_playing: + dc.w 0 + .even + + .END diff --git a/AtariST/wizzcat.bin b/AtariST/wizzcat.bin new file mode 100755 index 0000000..2052182 Binary files /dev/null and b/AtariST/wizzcat.bin differ diff --git a/AtariST/wizzcat.h b/AtariST/wizzcat.h new file mode 100755 index 0000000..859df7a --- /dev/null +++ b/AtariST/wizzcat.h @@ -0,0 +1,25 @@ +/* + * AHCC interface for Wizzcat 12kHz Protracker replay (STE only) + * based on the Wizzcat interface by GT Turbo / Cerebral Vortex for GFABASIC + * + * AHCC interface (c) 2011 by Simon Sunnyboy / Paradize + */ + + #ifndef _WIZZCAT_H + #define _WIZZCAT_H + + /** + * This function relocates the STE Wizzcat replay routine and makes it ready to use. + */ + void Wizzcat_Init(void); + /** + * This function starts playing a given Protracker file from address tune. + * tune_end defines the end of the tune address and should include approx 16KB + * of workspace behind the modfile. If the music is 50K long, add buffer space behind. + */ + void Wizzcat_Play(void *tune, void *tune_end); + /** + * This function stops the currently playing tune with the Wizzcat replay. + */ + void Wizzcat_Stop(void); + #endif