diff --git a/C64/main.c b/C64/main.c index 4dbad84..013ce7c 100644 --- a/C64/main.c +++ b/C64/main.c @@ -289,19 +289,20 @@ int main(void) { } FRAME_CURRENT++; - if (FRAME_CURRENT > 3) FRAME_CURRENT = 0; + if (FRAME_CURRENT > 4) FRAME_CURRENT = 0; switch(FRAME_CURRENT) { case 0: + case 1: Draw_firstframe(); break; - case 1: + case 2: Draw_frame2(); break; - case 2: + case 3: Draw_frame3(); break; - case 3: + case 4: Draw_frame4(); break; } diff --git a/PC88/.gitignore b/PC88/.gitignore new file mode 100644 index 0000000..06ae94c --- /dev/null +++ b/PC88/.gitignore @@ -0,0 +1,5 @@ +*.zx1 +*.bin +*.t88 +*.d88 +*.wav diff --git a/PC88/1.png b/PC88/1.png new file mode 100644 index 0000000..83ec80c Binary files /dev/null and b/PC88/1.png differ diff --git a/PC88/2612to2203.py b/PC88/2612to2203.py new file mode 100644 index 0000000..01fea22 --- /dev/null +++ b/PC88/2612to2203.py @@ -0,0 +1,220 @@ +#!/usr/bin/python3 + +# Conversion: +# FM 1-6: +# Same register numbers and values +# FM6/DAC: +# Disable +# Data blocks: +# ignore/skip +# SSG>PSG: (r0-rf) +# split data byte into register and data +# -change data to 16-bit were needed +# -noise on 1 channel(?) + +import sys + +""" Function defs """ + +def Usage(): + print("Usage:\n\ +$ 2612to2203.py /path/to/file.vgm\n") + +""" Conversion script """ + +# args test +if len(sys.argv) < 2: + Usage() + +# read in vgm file +f = open(sys.argv[1], 'rb') +inby = f.read() +f.close() + +# file type test +vgmstr = chr(inby[0]) + chr(inby[1]) + chr(inby[2]) + chr(inby[3]) +vgmver = inby[8] | (inby[9] << 8) +if((vgmstr != "Vgm ") and ((vgmver != 0x160) or (vgmver != 0x150))): + print("Error: Not a valid VGM v1.50/1.60 file!") + sys.exit() + +# main loop +outsong = [] +vgmptr = 0x34 + (inby[0x34] | (inby[0x35]<<8)) # 0x80 +datstart = vgmptr +i = 0 +while i < datstart: + outsong.append(inby[i]) + i += 1 +outsong.append(0x55) +outsong.append(0x7) +outsong.append(0b00111000) +# 477 +# 954 +# 1907 +while(vgmptr < len(inby)): + if inby[vgmptr] == 0x67: # data block, skip + vgmptr += 1 # 0x66 + vgmptr += 1 # data type + vgmptr += 1 # size low byte + sz = inby[vgmptr] | (inby[vgmptr+1]<<8) | (inby[vgmptr+2]<<16) | (inby[vgmptr+3]<<24) + vgmptr += sz + 3 + print('data block skipped by ' + str(sz) + ' bytes') + elif inby[vgmptr] == 0x50: + vgmptr += 1 # data + psgdat = inby[vgmptr] + # format: + # 10 bits - 0-2048 + r = (inby[vgmptr] & 0b01110000) >> 4 + # 3210 + d = inby[vgmptr] & 0b00001111 + d2 = 0 + # 3579540 + # 3993600 + # 1ac <> d6 + # get full data size for frequency + if((r == 0) or (r == 2) or (r == 4)): + vgmptr += 2 # data2 987654 + #print(hex(inby[vgmptr])) + d2 = (inby[vgmptr] & 0b00111111) << 4 + #d2 = d2 >> 8 + #print(hex(d+d2)) + if(r==0): + #print("tone 1 freq", end=' ') + d = d + d2 + d = int(d * 1.1157) + # print('real', d) + outsong.append(0x55) + outsong.append(0) + outsong.append(d & 0xff) + outsong.append(0x55) + outsong.append(1) + outsong.append((d & 0xff00) >> 8) + #print("PSG: r0,r1", hex(d & 0xff), hex((d & 0xff00) >> 8), end = ' ') + + elif(r==1): + #print("tone 1 att", end=' ') + if d == 0xf: + d = 0 + elif d == 0: + d = 0 + else: + v = 14 + if (d & 0b1000): + v -= 8 + if (d & 0b100): + v -= 4 + if (d & 0b10): + v -= 2 + if (d & 0b1): + v -= 1 + d = v + outsong.append(0x55) + outsong.append(8) + outsong.append(d) + #print("PSG: r8", d, end=' ') + elif(r==2): + #print("tone 2 freq", end=' ') + #print("PSG: r2,r3", hex(d & 0xff), hex(d2), end = ' ') + d = d + d2 + d = int(d * 1.1157) + outsong.append(0x55) + outsong.append(2) + outsong.append(d & 0xff) + outsong.append(0x55) + outsong.append(3) + outsong.append((d & 0xff00) >> 8) + #print("PSG: r2,r3", hex(d & 0xff), hex((d & 0xff00) >> 8), end = ' ') + + elif(r==3): + #print("tone 2 att", end=' ') + if d == 0xf: + d = 0 + elif d == 0: + d = 0 + else: + v = 14 + if (d & 0b1000): + v -= 8 + if (d & 0b100): + v -= 4 + if (d & 0b10): + v -= 2 + if (d & 0b1): + v -= 1 + d = v + outsong.append(0x55) + outsong.append(9) + outsong.append(d) + #print("PSG: r9", d, end=' ') + elif(r==4): + #print("tone 3 freq", end=' ') + #print("PSG: r4,r5", hex(d & 0xff), hex(d2), end = ' ') + d = d + d2 + d = int(d * 1.1157) + outsong.append(0x55) + outsong.append(4) + outsong.append(d & 0xff) + outsong.append(0x55) + outsong.append(5) + outsong.append((d & 0xff00) >> 8) + #print("PSG: r4,r5", hex(d & 0xff), hex((d & 0xff00) >> 8), end = ' ') + elif(r==5): + #print("tone 3 att", end=' ') + if d == 0xf: + d = 0 + elif d == 0: + d = 0 + else: + v = 14 + if (d & 0b1000): + v -= 8 + if (d & 0b100): + v -= 4 + if (d & 0b10): + v -= 2 + if (d & 0b1): + v -= 1 + d = v + outsong.append(0x55) + outsong.append(10) + outsong.append(d) + #print("PSG: r10", d, end=' ') + else: + print('error', r, d) + """ + elif(r==6): + print("noise ctl", end=' ') + # frequency is 0-2, 3 is "tone #3 output"? + d = d & 0b11 + d = d << 2 # x4 for now? + print("PSG: r6", d, end=' ') + outsong.append(6) + outsong.append(d & 0xf) + elif(r==7): + print("noise att", end=' ') + d = 15-d + d = int(d/2) + d = 1 # io input off, noise off, tone on FIXME + outsong.append(0x7) + outsong.append(d) + """ + + + #print('') + #print(d) + elif inby[vgmptr] == 0x62: + outsong.append(0x62) + elif inby[vgmptr] == 0x66: + outsong.append(0x66) + vgmptr = len(inby) + print("song end") + vgmptr += 1 + +#print(outsong) +f = open("outsong.vgm", 'wb') +i = 0 +while i < len(outsong): + #print(type(outsong[i])) + f.write(bytes([outsong[i]])) + i += 1 diff --git a/PC88/4.png b/PC88/4.png new file mode 100644 index 0000000..cb8bc18 Binary files /dev/null and b/PC88/4.png differ diff --git a/PC88/5.png b/PC88/5.png new file mode 100644 index 0000000..add29d2 Binary files /dev/null and b/PC88/5.png differ diff --git a/PC88/6.png b/PC88/6.png new file mode 100644 index 0000000..1ee5493 Binary files /dev/null and b/PC88/6.png differ diff --git a/PC88/C.gpl b/PC88/C.gpl new file mode 100644 index 0000000..0a92247 --- /dev/null +++ b/PC88/C.gpl @@ -0,0 +1,12 @@ +GIMP Palette +Name: C +Columns: 16 +# + 0 0 0 Untitled + 0 0 255 Untitled +255 0 0 Untitled +255 0 255 Untitled + 0 255 0 Untitled + 0 255 255 Untitled +255 255 0 Untitled +255 255 255 Untitled diff --git a/PC88/DaDither.64.exe b/PC88/DaDither.64.exe new file mode 100644 index 0000000..d8dd198 Binary files /dev/null and b/PC88/DaDither.64.exe differ diff --git a/PC88/README.md b/PC88/README.md new file mode 100644 index 0000000..c7bbb89 --- /dev/null +++ b/PC88/README.md @@ -0,0 +1,36 @@ +# Copyright Infringement for the PC-88 + +This is a port of a gay porn game that i made for numerous platforms, including the PC-88. +This is sort of basic and only supports V1 and the Beeper, the Yamaha sound chip isn't being used as it should +mostly due to the lack of suitable music for it and also because z88dk seemingly lacks FILE I/O for it (along with lacking support for adding files to the D88 image). + +# Usage + +To play the game, you have several options : +- Floppies (.D88) +- Tape/Casette (.WAV/.T88) + +The game loads entirely in RAM thus it should work from tape. +For the floppy version, it is self booting but you should boot it from N88, not N80 as +otherwise you'll only get B&W graphics. + +# Other technical aspects + +This uses Z88DK for the basic support of the PC-88 so many thanks to them ! +I had to write my own python script for converting PNG images to the PC-88's V1 format. +I haven't tried to figure out V2 too much but the only difference appears to be the remappable palette. + +Animating compressed graphics was a big problem on this. +In the end, i resorted to using another algo called LZ48 and it was slightly faster than even ZX1-Mega +while having decent compression ratios. + +I also sort of cheated by using the Red and Green layers as doing so reducing the overall effective size +from 48kb to 32kb, which makes it more bearable and we still get 4 colors. +Sure, no white color but it was a small loss in this case. + +In the end i sort of managed but you can still see some of the greenish remanants due to the green layer +still updating too slowly... :/ +I actually did get that even with uncompressed memcpy. +The only way i could possibly reduce this is with an unrolled 640 LDI loop but i'm not even sure that would be enough. + +I don't believe this kind of FMVs had been done on the PC-88 anyway. diff --git a/PC88/adpcm.py b/PC88/adpcm.py new file mode 100644 index 0000000..355e57b --- /dev/null +++ b/PC88/adpcm.py @@ -0,0 +1,85 @@ +import sys +import wave +import struct + +def clamp(n, smallest, largest): + return max(smallest, min(n, largest)) + +def convert_wav_to_adpcm(input_file, output_file): + step_table = [ + 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, + 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, + 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, + 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, + 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, + 32767 + ] + + index_table = [ + -1, -1, -1, -1, 2, 4, 6, 8, + -1, -1, -1, -1, 2, 4, 6, 8 + ] + + with wave.open(input_file, 'rb') as wav_file: + n_channels, sampwidth, framerate, n_frames, _, _ = wav_file.getparams() + assert n_channels == 1, "Input file must be mono" + assert sampwidth == 1, "Input file must be 8-bit" + + wav_data = wav_file.readframes(n_frames) + + sample = 0 + step_index = 0 + adpcm_data = bytearray() + + for i in range(0, len(wav_data), 2): + nibble1 = 0 + nibble2 = 0 + + for j in range(2): + diff = struct.unpack('b', wav_data[i + j:i + j + 1])[0] - sample + + sign = 0 + + if diff < 0: + sign = 8 + diff = -diff + + step = step_table[step_index] + delta = step >> 3 + + if diff > step_table[step_index] >> 1: + delta |= step >> 2 + diff -= step_table[step_index] >> 1 + + if diff > step_table[step_index] >> 2: + delta |= step >> 3 + diff -= step_table[step_index] >> 2 + + step_index = clamp(step_index + index_table[delta & 0x0F], 0, len(step_table) - 1) + + delta |= sign + sample += struct.unpack('b', struct.pack('B', (delta << 4) & 0xFF))[0] * step // 64 + + sample = clamp(sample, -128, 127) + + if j == 0: + nibble1 = delta + elif j == 1: + nibble2 = delta + + adpcm_byte = ((nibble1 << 4) | nibble2) & 0xFF + + adpcm_data.append(adpcm_byte) + + with open(output_file, 'wb') as adpcm_file: + adpcm_file.write(adpcm_data) + +if __name__ == "__main__": + if len(sys.argv) != 3: + print("Usage: python wav_to_okim6258_adpcm.py ") + sys.exit(1) + + input_file = sys.argv[1] + output_file = sys.argv[2] + + convert_wav_to_adpcm(input_file, output_file) diff --git a/PC88/backup/data.asm b/PC88/backup/data.asm new file mode 100644 index 0000000..808eeec --- /dev/null +++ b/PC88/backup/data.asm @@ -0,0 +1,47 @@ +;; data.asm + +SECTION rodata_user + +PUBLIC _frame1_b +PUBLIC _frame1_r +PUBLIC _frame1_g + +PUBLIC _anim1_g +PUBLIC _anim1_r + +PUBLIC _anim2_g +PUBLIC _anim2_r + +PUBLIC _anim3_g +PUBLIC _anim3_r + +PUBLIC _anim4_g +PUBLIC _anim4_r + +_frame1_b: + BINARY "bakurapc88_blue.zx1" +_frame1_r: + BINARY "bakurapc88_red.zx1" +_frame1_g: + BINARY "bakurapc88_green.zx1" + +_anim1_r: + BINARY "frame1_red.zx1" +_anim1_g: + BINARY "frame1_green.zx1" + + +_anim2_r: + BINARY "frame2_red.zx1" +_anim2_g: + BINARY "frame2_green.zx1" + +_anim3_r: + BINARY "frame3_red.zx1" +_anim3_g: + BINARY "frame3_green.zx1" + +_anim4_r: + BINARY "frame4_red.zx1" +_anim4_g: + BINARY "frame4_green.zx1" diff --git a/PC88/backup/main.c b/PC88/backup/main.c new file mode 100644 index 0000000..78ec03d --- /dev/null +++ b/PC88/backup/main.c @@ -0,0 +1,324 @@ +#include +#include +#include +#include +#include +#include + +#define SetBGColor(c) outp(0x52, c << 4); +#define SetBorderColor(c) outp(0x52, c); // PC8001 only? +#define SETBANK_BLUE() outp(0x5c, 0xff); +#define SETBANK_RED() outp(0x5d, 0xff); +#define SETBANK_GREEN() outp(0x5e, 0xff); +#define SETBANK_MAINRAM() outp(0x5f, 0xff); + +#define bit(n) (1 << n) + +#define FASTMEM_ON 1 +#define FASTMEM_OFF 0 +#define CLR_BLUE 1 + +#define SYS_CTL_REGB 0x31 +#define V1MODE_FLAG 0x80 + +#define vu8 volatile unsigned char +#define u8 unsigned char +#define u16 unsigned short +#define GetVRAMPos(x,y) (vu8*)(((y)*80)+0xc000 + (x)) + +#define EnableALU(fastmem) outp(ALU_MODE_CTRL, 0xC9|(fastmem<<4)); +#define ExpandedGVRAM_On() outp(EXPANDED_GVRAM_CTRL, 0x80); +#define ExpandedGVRAM_Off() outp(EXPANDED_GVRAM_CTRL, 0); +#define DisableALU(fastmem) outp(ALU_MODE_CTRL, 0x89|(fastmem<<4)); + +extern void ENABLE_GRAM(); +extern void DISABLE_GRAM(); + +void SetPixel(u16 x, u8 y, u8 c) +{ + u8 po = 7 - ((x & 0xff) % 8); + vu8* p = (vu8*)(0xc000) + (y * 80) + (u8)(x / 8); + + if(c & 0b001){ + SETBANK_BLUE() + *p |= bit(po); + } + if(c & 0b010){ + SETBANK_RED() + *p |= bit(po); + } + if(c & 0b100){ + SETBANK_GREEN() + *p |= bit(po); + } + +} + +extern unsigned char frame1_b[]; +extern unsigned char frame1_g[]; +extern unsigned char frame1_r[]; + +extern unsigned char anim1_b[]; +extern unsigned char anim1_g[]; +extern unsigned char anim1_r[]; + +extern unsigned char anim2_b[]; +extern unsigned char anim2_g[]; +extern unsigned char anim2_r[]; + +extern unsigned char anim3_b[]; +extern unsigned char anim3_g[]; +extern unsigned char anim3_r[]; + +extern unsigned char anim4_b[]; +extern unsigned char anim4_g[]; +extern unsigned char anim4_r[]; + +extern void dzx0_standard(); +extern void dzx1_mega(); + +static void SetTextVRAM() __z88dk_fastcall +{ + // Switch to TEXT VRAM + __asm + ld a, 0x00 + out (0x5F), a + __endasm; +} + +static void Clear_Text() __z88dk_fastcall +{ + // Switch to TEXT VRAM + __asm + ld a, 0x00 + out (0x5F), a + __endasm; + memset((void*)0xC000, 0, 16000); + + // Switch to graphics mode + /*__asm + ld a, 0x00 + out (0x5c), a + __endasm;*/ +} + +static void Draw_Bakura() __z88dk_fastcall +{ + __asm + ; ExpandedGVRAM_On + ld c, 0x35 + ld a, 0x80 + out (c), a + + ; EnableALU(FASTMEM_ON); + ld c, 0x32 + ld a, 16 + out (c), a + + ; Switch to Blue + ld a, 0xff + out (0x5c), a + + ld hl, _frame1_b + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _frame1_r + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _frame1_g + ld de, 0xC000 + call _dzx1_mega + + ; DisableALU(FASTMEM_OFF); + ld c, 0x32 + ld a, 0 + out (c), a + + ; ExpandedGVRAM_Off(); + ld c, 0x35 + ld a, 0 + out (c), a + + ; SetMAINRAMBANK(); + ld c, 0x55 + ld a, 0xff + out (c), a + __endasm; +} + +static void Draw_Frame1() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim1_r + ld de, 0xC000+4000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim1_g + ld de, 0xC000+4000 + call _dzx1_mega + __endasm; +} + +static void Draw_Frame2() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim2_r + ld de, 0xC000+4000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim2_g + ld de, 0xC000+4000 + call _dzx1_mega + __endasm; +} + +static void Draw_Frame3() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim3_r + ld de, 0xC000+4000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim3_g + ld de, 0xC000+4000 + call _dzx1_mega + __endasm; +} + +static void Draw_Frame4() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim4_r + ld de, 0xC000+4000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim4_g + ld de, 0xC000+4000 + call _dzx1_mega + __endasm; +} + + + +//pc88_fm_addr(); Check for FM, 0 if not found +//pc88_mode(); //2=V2, 1=V1, 0=N Mode +//pc88_8mhz(); Check if CPU is 8Mhz + +unsigned char FRAME_CURRENT; + +int main() +{ + if(pc88_mode() != 2) + { + puts_cons("V2 MODE ONLY"); + while(1){}; + } + + // Set V2 mode (640x200, 8 colors) + outp(0x5C, 0x62); + outp(0x5D, 0x00); + + //int TGI_MODE = 2; + //pc88_v2mode(); + //console_ioctl(IOCTL_GENCON_SET_MODE, &TGI_MODE); + //pc88_v2mode(); + //ENABLE_GRAM(); + + outp(0x5F, 0x00); // Switch back to text VRAM + gotoxy(0, 18); + puts_cons("Oh my, What do we have here ? You look so innocent..."); + //Clear_Text(); + //clg(); //Graphics only + + Draw_Bakura(); + + clg(); + + __asm + ; ExpandedGVRAM_On + ld c, 0x35 + ld a, 0x80 + out (c), a + + ; EnableALU(FASTMEM_ON); + ld c, 0x32 + ld a, 16 + out (c), a + __endasm; + + FRAME_CURRENT = 0; + + for(;;) + { + + + FRAME_CURRENT++; + if (FRAME_CURRENT > 3) FRAME_CURRENT = 0; + + switch(FRAME_CURRENT) + { + case 0: + Draw_Frame1(); + break; + case 1: + Draw_Frame2(); + break; + case 2: + Draw_Frame3(); + break; + case 3: + Draw_Frame4(); + break; + } + + + pc88_wait_vblank(); + } + return 0; +} diff --git a/PC88/bakura.png b/PC88/bakura.png new file mode 100644 index 0000000..9a8bf78 Binary files /dev/null and b/PC88/bakura.png differ diff --git a/PC88/bakurapc88.png b/PC88/bakurapc88.png new file mode 100644 index 0000000..cbc681a Binary files /dev/null and b/PC88/bakurapc88.png differ diff --git a/PC88/bakurapc88_blue.zx0 b/PC88/bakurapc88_blue.zx0 new file mode 100644 index 0000000..6984b21 Binary files /dev/null and b/PC88/bakurapc88_blue.zx0 differ diff --git a/PC88/bakurapc88_green.zx0 b/PC88/bakurapc88_green.zx0 new file mode 100644 index 0000000..6b49218 Binary files /dev/null and b/PC88/bakurapc88_green.zx0 differ diff --git a/PC88/bakurapc88_red.zx0 b/PC88/bakurapc88_red.zx0 new file mode 100644 index 0000000..0d2dcae Binary files /dev/null and b/PC88/bakurapc88_red.zx0 differ diff --git a/PC88/copyright_infringement b/PC88/copyright_infringement new file mode 100644 index 0000000..6b9e48c Binary files /dev/null and b/PC88/copyright_infringement differ diff --git a/PC88/data.asm b/PC88/data.asm new file mode 100644 index 0000000..ee62ac7 --- /dev/null +++ b/PC88/data.asm @@ -0,0 +1,58 @@ +;; data.asm + +SECTION rodata_user + +PUBLIC _frame1_b +PUBLIC _frame1_r +PUBLIC _frame1_g + +PUBLIC _title_b +PUBLIC _title_g +PUBLIC _title_r + +PUBLIC _anim1_g +PUBLIC _anim1_r + +PUBLIC _anim2_g +PUBLIC _anim2_r + +PUBLIC _anim3_g +PUBLIC _anim3_r + +PUBLIC _anim4_g +PUBLIC _anim4_r + +_title_b: + BINARY "titlescreen_blue.zx1" +_title_r: + BINARY "titlescreen_red.zx1" +_title_g: + BINARY "titlescreen_green.zx1" + +_frame1_b: + BINARY "bakurapc88_blue.zx1" +_frame1_r: + BINARY "bakurapc88_red.zx1" +_frame1_g: + BINARY "bakurapc88_green.zx1" + +_anim1_r: + BINARY "frame1_red.lz" +_anim1_g: + BINARY "frame1_green.lz" + + +_anim2_r: + BINARY "frame2_red.lz" +_anim2_g: + BINARY "frame2_green.lz" + +_anim3_r: + BINARY "frame3_red.lz" +_anim3_g: + BINARY "frame3_green.lz" + +_anim4_r: + BINARY "frame4_red.lz" +_anim4_g: + BINARY "frame4_green.lz" diff --git a/PC88/draw.s b/PC88/draw.s new file mode 100644 index 0000000..7866b87 --- /dev/null +++ b/PC88/draw.s @@ -0,0 +1,29 @@ + + + +PUBLIC _clear_plane + +defc ALU_MODE_CTRL = 0x32 +defc EXPANDED_ALU_CTRL = 0x34 +defc EXPANDED_GVRAM_CTRL = 0x35 +defc GVRAM_SEL_0 = 0x5c +defc GVRAM_SEL_1 = 0x5d +defc GVRAM_SEL_2 = 0x5e +defc MAINRAM_SEL = 0x5f + +_ENABLE_GRAM: + + ret + +_DISABLE_GRAM: + + ret + +_clear_plane: + ld hl,49152 ; 0xC000 + ld de,49153 ; 0xC001 + + ld bc,15999 ;80x200 - 1 + ld (hl),a + ldir + ret diff --git a/PC88/dzx0.asm b/PC88/dzx0.asm new file mode 100644 index 0000000..ce0252c --- /dev/null +++ b/PC88/dzx0.asm @@ -0,0 +1,63 @@ +; ----------------------------------------------------------------------------- +; ZX0 decoder by Einar Saukas & Urusergi +; "Standard" version (68 bytes only) +; ----------------------------------------------------------------------------- +; Parameters: +; HL: source address (compressed data) +; DE: destination address (decompressing) +; ----------------------------------------------------------------------------- + +PUBLIC _dzx0_standard + +_dzx0_standard: + ld bc, $ffff ; preserve default offset 1 + push bc + inc bc + ld a, $80 +dzx0s_literals: + call dzx0s_elias ; obtain length + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jr c, dzx0s_new_offset + call dzx0s_elias ; obtain length +dzx0s_copy: + ex (sp), hl ; preserve source, restore offset + push hl ; preserve offset + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore offset + ex (sp), hl ; preserve offset, restore source + add a, a ; copy from literals or new offset? + jr nc, dzx0s_literals +dzx0s_new_offset: + pop bc ; discard last offset + ld c, $fe ; prepare negative offset + call dzx0s_elias_loop ; obtain offset MSB + inc c + ret z ; check end marker + ld b, c + ld c, (hl) ; obtain offset LSB + inc hl + rr b ; last offset bit becomes first length bit + rr c + push bc ; preserve new offset + ld bc, 1 ; obtain length + call nc, dzx0s_elias_backtrack + inc bc + jr dzx0s_copy +dzx0s_elias: + inc c ; interlaced Elias gamma coding +dzx0s_elias_loop: + add a, a + jr nz, dzx0s_elias_skip + ld a, (hl) ; load another group of 8 bits + inc hl + rla +dzx0s_elias_skip: + ret c +dzx0s_elias_backtrack: + add a, a + rl c + rl b + jr dzx0s_elias_loop +; ----------------------------------------------------------------------------- diff --git a/PC88/dzx1.asm b/PC88/dzx1.asm new file mode 100644 index 0000000..0d53b09 --- /dev/null +++ b/PC88/dzx1.asm @@ -0,0 +1,304 @@ +; ----------------------------------------------------------------------------- +; ZX1 decoder by Einar Saukas & introspec +; "Mega" version (406 bytes, 25% faster) +; ----------------------------------------------------------------------------- +; Parameters: +; HL: source address (compressed data) +; DE: destination address (decompressing) +; ----------------------------------------------------------------------------- +PUBLIC _dzx1_mega +_dzx1_mega: + ld bc, $ffff ; preserve default offset 1 + ld (dzx1m_last_offset+1), bc + inc bc + jr dzx1m_literals0 + +dzx1m_new_offset6: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip6 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip6: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + add a, a ; obtain length + jp nc, dzx1m_length5 + add a, a + rl c + add a, a + jr nc, dzx1m_length3 +dzx1m_elias_length3: + add a, a + rl c + rl b + add a, a + jp c, dzx1m_elias_length1 +dzx1m_length1: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr c, dzx1m_new_offset0 +dzx1m_literals0: + inc c + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a ; obtain length + jr nc, dzx1m_literals7 +dzx1m_elias_literals7: + add a, a + rl c + rl b + add a, a + jp c, dzx1m_elias_literals5 +dzx1m_literals5: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset4 + inc c + add a, a ; obtain length + jr nc, dzx1m_reuse3 +dzx1m_elias_reuse3: + add a, a + rl c + rl b + add a, a + jp c, dzx1m_elias_reuse1 +dzx1m_reuse1: + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals0 + +dzx1m_new_offset0: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip0 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip0: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a ; obtain length + jp nc, dzx1m_length7 + add a, a + rl c + add a, a + jr nc, dzx1m_length5 +dzx1m_elias_length5: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_length3 +dzx1m_length3: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr c, dzx1m_new_offset2 +dzx1m_literals2: + inc c + add a, a ; obtain length + jr nc, dzx1m_literals1 +dzx1m_elias_literals1: + add a, a + rl c + rl b + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr c, dzx1m_elias_literals7 +dzx1m_literals7: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset6 + inc c + add a, a ; obtain length + jr nc, dzx1m_reuse5 +dzx1m_elias_reuse5: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_reuse3 +dzx1m_reuse3: + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals2 + +dzx1m_new_offset2: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip2 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip2: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + add a, a ; obtain length + jp nc, dzx1m_length1 + add a, a + rl c + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr nc, dzx1m_length7 +dzx1m_elias_length7: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_length5 +dzx1m_length5: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr c, dzx1m_new_offset4 +dzx1m_literals4: + inc c + add a, a ; obtain length + jr nc, dzx1m_literals3 +dzx1m_elias_literals3: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_literals1 +dzx1m_literals1: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset0 + inc c + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a ; obtain length + jr nc, dzx1m_reuse7 +dzx1m_elias_reuse7: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_reuse5 +dzx1m_reuse5: + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals4 + +dzx1m_new_offset4: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip4 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip4: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + add a, a ; obtain length + jp nc, dzx1m_length3 + add a, a + rl c + add a, a + jp nc, dzx1m_length1 +dzx1m_elias_length1: + add a, a + rl c + rl b + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr c, dzx1m_elias_length7 +dzx1m_length7: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jp c, dzx1m_new_offset6 +dzx1m_literals6: + inc c + add a, a ; obtain length + jp nc, dzx1m_literals5 +dzx1m_elias_literals5: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_literals3 +dzx1m_literals3: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset2 + inc c + add a, a ; obtain length + jp nc, dzx1m_reuse1 +dzx1m_elias_reuse1: + add a, a + rl c + rl b + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr c, dzx1m_elias_reuse7 +dzx1m_reuse7: + push hl ; preserve source +dzx1m_last_offset: + ld hl, 0 + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals6 + + jp dzx1m_new_offset6 +; ----------------------------------------------------------------------------- diff --git a/PC88/frame1.png b/PC88/frame1.png new file mode 100644 index 0000000..f91221b Binary files /dev/null and b/PC88/frame1.png differ diff --git a/PC88/frame1_green.lz b/PC88/frame1_green.lz new file mode 100644 index 0000000..746bddf Binary files /dev/null and b/PC88/frame1_green.lz differ diff --git a/PC88/frame1_red.lz b/PC88/frame1_red.lz new file mode 100644 index 0000000..7603c83 Binary files /dev/null and b/PC88/frame1_red.lz differ diff --git a/PC88/frame2.png b/PC88/frame2.png new file mode 100644 index 0000000..bcd98e2 Binary files /dev/null and b/PC88/frame2.png differ diff --git a/PC88/frame2_green.lz b/PC88/frame2_green.lz new file mode 100644 index 0000000..1690d3b Binary files /dev/null and b/PC88/frame2_green.lz differ diff --git a/PC88/frame2_red.lz b/PC88/frame2_red.lz new file mode 100644 index 0000000..4f8c1d4 Binary files /dev/null and b/PC88/frame2_red.lz differ diff --git a/PC88/frame3.png b/PC88/frame3.png new file mode 100644 index 0000000..f5ed651 Binary files /dev/null and b/PC88/frame3.png differ diff --git a/PC88/frame3_green.lz b/PC88/frame3_green.lz new file mode 100644 index 0000000..5b13200 Binary files /dev/null and b/PC88/frame3_green.lz differ diff --git a/PC88/frame3_red.lz b/PC88/frame3_red.lz new file mode 100644 index 0000000..04800ca Binary files /dev/null and b/PC88/frame3_red.lz differ diff --git a/PC88/frame4.png b/PC88/frame4.png new file mode 100644 index 0000000..5bd379a Binary files /dev/null and b/PC88/frame4.png differ diff --git a/PC88/frame4_green.lz b/PC88/frame4_green.lz new file mode 100644 index 0000000..1a1084c Binary files /dev/null and b/PC88/frame4_green.lz differ diff --git a/PC88/frame4_red.lz b/PC88/frame4_red.lz new file mode 100644 index 0000000..0020707 Binary files /dev/null and b/PC88/frame4_red.lz differ diff --git a/PC88/latest?cb=20170515095008 b/PC88/latest?cb=20170515095008 new file mode 100644 index 0000000..593a056 Binary files /dev/null and b/PC88/latest?cb=20170515095008 differ diff --git a/PC88/lib/_dzx1_mega.asm b/PC88/lib/_dzx1_mega.asm new file mode 100644 index 0000000..5bbe5ec --- /dev/null +++ b/PC88/lib/_dzx1_mega.asm @@ -0,0 +1,21 @@ + +; void dzx1_mega(void *src, void *dst) + +SECTION code_clib +SECTION code_compress_zx1 + +PUBLIC dzx1_mega + +EXTERN asm_dzx1_mega + +dzx1_mega: + + pop af + pop de + pop hl + + push hl + push de + push af + + jp asm_dzx1_mega diff --git a/PC88/lib/dzx1_mega.asm b/PC88/lib/dzx1_mega.asm new file mode 100644 index 0000000..f6a9732 --- /dev/null +++ b/PC88/lib/dzx1_mega.asm @@ -0,0 +1,306 @@ +; ----------------------------------------------------------------------------- +; ZX1 decoder by Einar Saukas & introspec +; "Mega" version (406 bytes, 25% faster) +; ----------------------------------------------------------------------------- +; Parameters: +; HL: source address (compressed data) +; DE: destination address (decompressing) +; ----------------------------------------------------------------------------- + +PUBLIC asm_dzx1_mega + +asm_dzx1_mega: + ld bc, $ffff ; preserve default offset 1 + ld (dzx1m_last_offset+1), bc + inc bc + jr dzx1m_literals0 + +dzx1m_new_offset6: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip6 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip6: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + add a, a ; obtain length + jp nc, dzx1m_length5 + add a, a + rl c + add a, a + jr nc, dzx1m_length3 +dzx1m_elias_length3: + add a, a + rl c + rl b + add a, a + jp c, dzx1m_elias_length1 +dzx1m_length1: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr c, dzx1m_new_offset0 +dzx1m_literals0: + inc c + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a ; obtain length + jr nc, dzx1m_literals7 +dzx1m_elias_literals7: + add a, a + rl c + rl b + add a, a + jp c, dzx1m_elias_literals5 +dzx1m_literals5: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset4 + inc c + add a, a ; obtain length + jr nc, dzx1m_reuse3 +dzx1m_elias_reuse3: + add a, a + rl c + rl b + add a, a + jp c, dzx1m_elias_reuse1 +dzx1m_reuse1: + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals0 + +dzx1m_new_offset0: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip0 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip0: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a ; obtain length + jp nc, dzx1m_length7 + add a, a + rl c + add a, a + jr nc, dzx1m_length5 +dzx1m_elias_length5: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_length3 +dzx1m_length3: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr c, dzx1m_new_offset2 +dzx1m_literals2: + inc c + add a, a ; obtain length + jr nc, dzx1m_literals1 +dzx1m_elias_literals1: + add a, a + rl c + rl b + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr c, dzx1m_elias_literals7 +dzx1m_literals7: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset6 + inc c + add a, a ; obtain length + jr nc, dzx1m_reuse5 +dzx1m_elias_reuse5: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_reuse3 +dzx1m_reuse3: + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals2 + +dzx1m_new_offset2: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip2 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip2: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + add a, a ; obtain length + jp nc, dzx1m_length1 + add a, a + rl c + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr nc, dzx1m_length7 +dzx1m_elias_length7: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_length5 +dzx1m_length5: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr c, dzx1m_new_offset4 +dzx1m_literals4: + inc c + add a, a ; obtain length + jr nc, dzx1m_literals3 +dzx1m_elias_literals3: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_literals1 +dzx1m_literals1: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset0 + inc c + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a ; obtain length + jr nc, dzx1m_reuse7 +dzx1m_elias_reuse7: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_reuse5 +dzx1m_reuse5: + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals4 + +dzx1m_new_offset4: + dec b + ld c, (hl) ; obtain offset LSB + inc hl + rr c ; single byte offset? + jr nc, dzx1m_msb_skip4 + ld b, (hl) ; obtain offset MSB + inc hl + rr b ; replace last LSB bit with last MSB bit + inc b + ret z ; check end marker + rl c +dzx1m_msb_skip4: + ld (dzx1m_last_offset+1), bc ; preserve new offset + ld bc, 1 + add a, a ; obtain length + jp nc, dzx1m_length3 + add a, a + rl c + add a, a + jp nc, dzx1m_length1 +dzx1m_elias_length1: + add a, a + rl c + rl b + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr c, dzx1m_elias_length7 +dzx1m_length7: + inc bc + push hl ; preserve source + ld hl, (dzx1m_last_offset+1) + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jp c, dzx1m_new_offset6 +dzx1m_literals6: + inc c + add a, a ; obtain length + jp nc, dzx1m_literals5 +dzx1m_elias_literals5: + add a, a + rl c + rl b + add a, a + jr c, dzx1m_elias_literals3 +dzx1m_literals3: + ldir ; copy literals + add a, a ; copy from last offset or new offset? + jp c, dzx1m_new_offset2 + inc c + add a, a ; obtain length + jp nc, dzx1m_reuse1 +dzx1m_elias_reuse1: + add a, a + rl c + rl b + ld a, (hl) ; load another group of 8 bits + inc hl + add a, a + jr c, dzx1m_elias_reuse7 +dzx1m_reuse7: + push hl ; preserve source +dzx1m_last_offset: + ld hl, 0 + add hl, de ; calculate destination - offset + ldir ; copy from offset + pop hl ; restore source + add a, a ; copy from literals or new offset? + jr nc, dzx1m_literals6 + + jp dzx1m_new_offset6 +; ----------------------------------------------------------------------------- diff --git a/PC88/lib/dzx1_mega_callee.asm b/PC88/lib/dzx1_mega_callee.asm new file mode 100644 index 0000000..551f18e --- /dev/null +++ b/PC88/lib/dzx1_mega_callee.asm @@ -0,0 +1,24 @@ + +; void dzx1_mega_callee(void *src, void *dst) + +SECTION code_clib +SECTION code_compress_zx1 + +PUBLIC dzx1_mega_callee + +EXTERN asm_dzx1_mega + +dzx1_mega_callee: + +IF __CPU_GBZ80__ + pop bc + pop de + pop hl + push bc +ELSE + pop hl + pop de + ex (sp),hl +ENDIF + + jp asm_dzx1_mega diff --git a/PC88/lz48.asm b/PC88/lz48.asm new file mode 100644 index 0000000..25cbc8b --- /dev/null +++ b/PC88/lz48.asm @@ -0,0 +1,99 @@ +; +; LZ48 decrunch +; + +; In ; HL=compressed data address +; ; DE=output data address +; Out ; HL last address of compressed data read (you must inc once for LZ48 stream) +; ; DE last address of decrunched data write +1 +; ; BC always 1 +; ; A always zero +; ; flags (Z,NC,P,PE) +; ; HL' address of lzunpack(if OPTIMIZE_JUMP=2) +; ; E' undetermined +; ; BC' always 0f10h +; Modif ; AF, BC, DE, HL, BC', E', HL' + + ;DEFINE OPTIMIZE_JUMP 2 +PUBLIC _LZ48_decrunch + +_LZ48_decrunch: + ldi + ld b,0 + + exx + ld bc,0f10h + exx + jr nextsequence + +loop: + ld e,a + rrca + rrca + rrca + rrca + + and b + cp b ; more bytes for literal length? + exx + + call nc,getadditionallength + +copyliteral: + ld c,a + ldir + + exx + ld a,e + and b +lzunpack: + cp b ; more bytes for match length? + inc a + exx + + call nc,getadditionallength + +readoffset: + ld c,a +; read encoded offset + sbc a,(hl) + sub c + ret z ; LZ48 end with zero offset + inc hl + push hl +; source=dest-copyoffset + ; A != 0 here + ld l,a + ld h,0ffh + add hl,de + ldir + inc b + ldi + ldi + + pop hl + +nextsequence: + ld a,(hl) + inc hl + + exx + cp c + jr nc,loop + jr lzunpack ; no literal bytes + + +lengthNC: + scf +lengthC: + inc c + ret nz + +getadditionallength: + ld c,(hl) ; get additional literal length byte + inc hl + add a,c ; compute literal length total + jr nc,lengthNC + inc b + jr lengthC + diff --git a/PC88/lz48.elf b/PC88/lz48.elf new file mode 100755 index 0000000..ec26399 Binary files /dev/null and b/PC88/lz48.elf differ diff --git a/PC88/lz48_v002.c b/PC88/lz48_v002.c new file mode 100644 index 0000000..4a05199 --- /dev/null +++ b/PC88/lz48_v002.c @@ -0,0 +1,325 @@ +/* LZ48 simple C source file / crappy version by roudoudou - Flower Corp. 2016 */ + +#include +#include +#include +#include + +int LZ48_encode_extended_length(unsigned char *odata, int length) +{ + int ioutput=0; + + while (length>=255) { + odata[ioutput++]=0xFF; + length-=255; + } + /* if the last value is 255 we must encode 0 to end extended length */ + odata[ioutput++]=length; + return ioutput; +} + +int LZ48_encode_block(unsigned char *odata,unsigned char *data, int literaloffset,int literalcpt,int offset,int maxlength) +{ + int ioutput=1; + int token=0; + int i; + + if (offset<0 || offset>255) { + fprintf(stderr,"internal offset error!"); + exit(-2); + } + + if (literalcpt<15) { + token=literalcpt<<4; + } else { + token=0xF0; + ioutput+=LZ48_encode_extended_length(odata+ioutput,literalcpt-15); + } + + for (i=0;i2) { + token|=(maxlength-3); + } else { + /* endoffset has no length */ + } + } else { + token|=0xF; + ioutput+=LZ48_encode_extended_length(odata+ioutput,maxlength-18); + } + + odata[ioutput++]=offset-1; + + odata[0]=token; + return ioutput; +} + +unsigned char *LZ48_encode(unsigned char *data, int length, int *retlength) +{ + int i,startscan,current=1,token,ioutput=1,curscan; + int maxoffset,maxlength,matchlength,literal=0,literaloffset=1; + unsigned char *odata=NULL; + + if (!length) return NULL; + + odata=malloc(length*1.1); + if (!odata) { + fprintf(stderr,"memory full"); + exit(-1); + } + + /* first byte always literal */ + odata[0]=data[0]; + + /* force short data encoding */ + if (length<5) { + token=(length-1)<<4; + odata[ioutput++]=token; + for (i=1;i=3 && matchlength>maxlength) { + maxoffset=startscan; + maxlength=matchlength; + } + startscan++; + } + if (maxlength) { + ioutput+=LZ48_encode_block(odata+ioutput,data,literaloffset,literal,current-maxoffset,maxlength); + current+=maxlength; + literaloffset=current; + literal=0; + } else { + literal++; + current++; + } + } + ioutput+=LZ48_encode_block(odata+ioutput,data,literaloffset,literal,0,0); + *retlength=ioutput; + return odata; +} + +void LZ48_decode(unsigned char *data, unsigned char *odata) +{ + int HL=0,DE=0; + int literallength,matchlength,HLmatch; + + odata[DE++]=data[HL++]; + + while (1) { + literallength=(data[HL] & 0xF0)>>4; + matchlength=(data[HL++] & 0xF); + + if (literallength==15) { + while (data[HL]==255) { + literallength+=255; + HL++; + } + literallength+=data[HL++]; + } + + while (literallength>0) { + odata[DE++]=data[HL++]; + literallength--; + } + + /* matchkey */ + if (matchlength==15) { + while (data[HL]==255) { + matchlength+=255; + HL++; + } + matchlength+=data[HL++]; + } + matchlength+=3; + if (data[HL]==0xFF) return; else HLmatch=DE-(data[HL++]+1); + + while (matchlength) { + odata[DE++]=odata[HLmatch++]; + matchlength--; + } + } +} + +unsigned char * LZ48_decrunch(unsigned char *data, int *osize) +{ + int literallength,matchlength; + int HL=1,DE=1; + unsigned char *odata=NULL; + + while (1) { + literallength=(data[HL] & 0xF0)>>4; + matchlength=(data[HL++] & 0xF); + if (literallength==15) { + while (data[HL]==255) { + literallength+=255; + HL++; + } + literallength+=data[HL++]; + } + + DE+=literallength; + HL+=literallength; + + /* matchkey */ + if (matchlength==15) { + while (data[HL]==255) { + matchlength+=255; + HL++; + } + matchlength+=data[HL++]; + } + matchlength+=3; + if (data[HL]==0xFF) break; else HL++; + + DE+=matchlength; + } + *osize=DE; + odata=malloc(*osize); + if (!odata) { + fprintf(stderr,"memory full\n"); + exit(-1); + } + LZ48_decode(data,odata); + return odata; +} + +void Usage() +{ + printf("usage: lz48 \n"); + printf("options are:\n"); + printf("-i \n"); + printf("-o \n"); + printf("-b hexatext output (enable if you forget outputfile)\n"); + printf("-d decrunch\n"); + printf("\n"); + exit(0); +} + +int ParseOptions(char **argv,int argc, char **inputfilename, char **outputfilename, int *hexoutput, int *crunch) +{ + int i=0; + + if (argv[i][0]=='-') + { + switch(argv[i][1]) + { + case 'O': + case 'o': + if (i+1 +#include +#include +#include +#include +#include +#include +#include "tetris.h" + +#define SetBGColor(c) outp(0x52, c << 4); +#define SetBorderColor(c) outp(0x52, c); // PC8001 only? +#define SETBANK_BLUE() outp(0x5c, 0xff); +#define SETBANK_RED() outp(0x5d, 0xff); +#define SETBANK_GREEN() outp(0x5e, 0xff); +#define SETBANK_MAINRAM() outp(0x5f, 0xff); + +#define bit(n) (1 << n) + +#define FASTMEM_ON 1 +#define FASTMEM_OFF 0 +#define CLR_BLUE 1 + +#define SYS_CTL_REGB 0x31 +#define V1MODE_FLAG 0x80 + +#define vu8 volatile unsigned char +#define u8 unsigned char +#define u16 unsigned short +#define GetVRAMPos(x,y) (vu8*)(((y)*80)+0xc000 + (x)) + +#define EnableALU(fastmem) outp(ALU_MODE_CTRL, 0xC9|(fastmem<<4)); +#define ExpandedGVRAM_On() outp(EXPANDED_GVRAM_CTRL, 0x80); +#define ExpandedGVRAM_Off() outp(EXPANDED_GVRAM_CTRL, 0); +#define DisableALU(fastmem) outp(ALU_MODE_CTRL, 0x89|(fastmem<<4)); + +extern void ENABLE_GRAM(); +extern void DISABLE_GRAM(); + +void SetPixel(u16 x, u8 y, u8 c) +{ + u8 po = 7 - ((x & 0xff) % 8); + vu8* p = (vu8*)(0xc000) + (y * 80) + (u8)(x / 8); + + if(c & 0b001){ + SETBANK_BLUE() + *p |= bit(po); + } + if(c & 0b010){ + SETBANK_RED() + *p |= bit(po); + } + if(c & 0b100){ + SETBANK_GREEN() + *p |= bit(po); + } + +} + +extern unsigned char frame1_b[]; +extern unsigned char frame1_g[]; +extern unsigned char frame1_r[]; + +extern unsigned char anim1_b[]; +extern unsigned char anim1_g[]; +extern unsigned char anim1_r[]; + +extern unsigned char anim2_b[]; +extern unsigned char anim2_g[]; +extern unsigned char anim2_r[]; + +extern unsigned char anim3_b[]; +extern unsigned char anim3_g[]; +extern unsigned char anim3_r[]; + +extern unsigned char anim4_b[]; +extern unsigned char anim4_g[]; +extern unsigned char anim4_r[]; + +extern void dzx0_standard(); +extern void dzx1_mega(); +extern void LZ48_decrunch(); + +static void SetTextVRAM() __z88dk_fastcall +{ + // Switch to TEXT VRAM + __asm + ld a, 0x00 + out (0x5F), a + __endasm; +} + +static void Clear_Text() __z88dk_fastcall +{ + // Switch to TEXT VRAM + __asm + ld a, 0x00 + out (0x5F), a + __endasm; + memset((void*)0xC000, 0, 16000); + + // Switch to graphics mode + /*__asm + ld a, 0x00 + out (0x5c), a + __endasm;*/ +} + +static void Draw_Bakura() __z88dk_fastcall +{ + __asm + ; ExpandedGVRAM_On + ld c, 0x35 + ld a, 0x80 + out (c), a + + ; EnableALU(FASTMEM_ON); + ld c, 0x32 + ld a, 16 + out (c), a + + ; Switch to Blue + ld a, 0xff + out (0x5c), a + + ld hl, _frame1_b + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _frame1_r + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _frame1_g + ld de, 0xC000 + call _dzx1_mega + + ; DisableALU(FASTMEM_OFF); + ld c, 0x32 + ld a, 0 + out (c), a + + ; ExpandedGVRAM_Off(); + ld c, 0x35 + ld a, 0 + out (c), a + + ; SetMAINRAMBANK(); + ld c, 0x55 + ld a, 0xff + out (c), a + __endasm; +} + +static void Draw_Frame1() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim1_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim1_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + +static void Draw_Frame2() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim2_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim2_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + +static void Draw_Frame3() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim3_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim3_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + +static void Draw_Frame4() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim4_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim4_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + + + +//pc88_fm_addr(); Check for FM, 0 if not found +//pc88_mode(); //2=V2, 1=V1, 0=N Mode +//pc88_8mhz(); Check if CPU is 8Mhz + +#define IRQ_OFF __asm di __endasm; +#define IRQ_ON __asm ei __endasm; + +unsigned char FRAME_CURRENT; + +u8* songStart; +static u8* songPointer; +static u8 SONGPLAYING = 0; + +void VGMPlayer(); + +void LoadVGM(const u8* sn) +{ + songPointer = sn + 0x40; // 1.50 FIXME + songStart = songPointer; + SONGPLAYING = 1; +} + +static void SetVBLIRQ() +{ + __asm + ld c, 0xe4 + ld a, 2 + out (c), a + + ld c, 0xe6 + ld a, 0b10 + out (c), a + __endasm; +} + +void Vblank() __critical __interrupt +{ + IRQ_OFF // Disable interrupts during VBL + SetVBLIRQ(); // Reset interrupt level and mask + + // Do our Vblank code: + if(SONGPLAYING) + { + VGMPlayer(); + } + + IRQ_ON +} + +unsigned short songWait; +unsigned char nowt; + +void VGMPlayer() +{ + songWait = 0; + // songPointer contains byte 0 of VGM data (if 1.60) + __asm + + push hl + push bc + push de + push af + + ld hl,(_songPointer) + ld a,(hl) + inc hl + ld (_songPointer),hl + + jp PlayLoop + + endPlay: + pop af + pop de + pop bc + pop hl + + ret + + PlayLoop: + cp #0x55 + jp z,_WRITEOPN + cp #0x61 + jp z,_SAMPLEWAIT + cp #0x62 + jp z,_ENDFRAME + cp #0x63 + jp z,_ENDFRAME + cp #0x66 + jp z,_ENDSONG + cp #0x67 + jp z,_ERROR ; no data blocks + cp #0x80 ; 70-7f + jp c,_QWAIT + + jp endPlay + + _GETNEXTBYTE: + ld hl,(_songPointer) + ld a,(hl) + inc hl + ld (_songPointer),hl + ret + + _WRITEOPN: + ; Get register + ld c,#0x44 + call _GETNEXTBYTE + out (c), a + ;nop + ;nop + ;nop + ;nop + ; Get byte + ld c,#0x45 + call _GETNEXTBYTE + out (c), a + + ; Loop + call _GETNEXTBYTE + jp PlayLoop + + _SAMPLEWAIT: + jp endPlay + + _ENDFRAME: + jp endPlay + + _ENDSONG: + ;xor a + ;ld (_SONGPLAYING),a + ld hl,(_songStart) + ld (_songPointer),hl + jp endPlay + + _ERROR: + jp _ERROR + + _QWAIT: ; approximation! + jp endPlay + + __endasm; +} + + +int main() +{ + #if 0 + IRQ_OFF + __asm + ld hl, #_Vblank + ld (0xf302),hl + __endasm; + SetVBLIRQ(); // And enable the VBL interrupt! + IRQ_ON + + LoadVGM((const u8*)&outsong); + #endif + + // Set V1 mode (640x200, 8 colors) + outp(0x5C, 0x61); + outp(0x5D, 0x00); + + //int TGI_MODE = 2; + //pc88_v2mode(); + //console_ioctl(IOCTL_GENCON_SET_MODE, &TGI_MODE); + //pc88_v2mode(); + //ENABLE_GRAM(); + + outp(0x5F, 0x00); // Switch back to text VRAM + gotoxy(0, 18); + puts_cons("Oh my, What do we have here ? You look so innocent..."); + //Clear_Text(); + //clg(); //Graphics only + + Draw_Bakura(); + + clg(); + Clear_Text(); + + __asm + ; ExpandedGVRAM_On + ld c, 0x35 + ld a, 0x80 + out (c), a + + ; EnableALU(FASTMEM_ON); + ld c, 0x32 + ld a, 16 + out (c), a + __endasm; + + FRAME_CURRENT = 0; + + bit_fx(4); + + for(;;) + { + FRAME_CURRENT++; + if (FRAME_CURRENT > 3) FRAME_CURRENT = 0; + + switch(FRAME_CURRENT) + { + case 0: + Draw_Frame1(); + break; + case 1: + Draw_Frame2(); + break; + case 2: + Draw_Frame3(); + break; + case 3: + Draw_Frame4(); + break; + } + + + pc88_wait_vblank(); + } + return 0; +} diff --git a/PC88/main.c b/PC88/main.c new file mode 100644 index 0000000..c61d35a --- /dev/null +++ b/PC88/main.c @@ -0,0 +1,568 @@ +#include +#include +#include +#include +#include +#include +#include + +#define SetBGColor(c) outp(0x52, c << 4); +#define SetBorderColor(c) outp(0x52, c); // PC8001 only? +#define SETBANK_BLUE() outp(0x5c, 0xff); +#define SETBANK_RED() outp(0x5d, 0xff); +#define SETBANK_GREEN() outp(0x5e, 0xff); +#define SETBANK_MAINRAM() outp(0x5f, 0xff); + +#define bit(n) (1 << n) + +#define FASTMEM_ON 1 +#define FASTMEM_OFF 0 +#define CLR_BLUE 1 + +#define SYS_CTL_REGB 0x31 +#define V1MODE_FLAG 0x80 + +#define vu8 volatile unsigned char +#define u8 unsigned char +#define u16 unsigned short +#define GetVRAMPos(x,y) (vu8*)(((y)*80)+0xc000 + (x)) + +#define EnableALU(fastmem) outp(ALU_MODE_CTRL, 0xC9|(fastmem<<4)); +#define ExpandedGVRAM_On() outp(EXPANDED_GVRAM_CTRL, 0x80); +#define ExpandedGVRAM_Off() outp(EXPANDED_GVRAM_CTRL, 0); +#define DisableALU(fastmem) outp(ALU_MODE_CTRL, 0x89|(fastmem<<4)); + +extern unsigned char frame1_b[]; +extern unsigned char frame1_g[]; +extern unsigned char frame1_r[]; + +extern unsigned char title_b[]; +extern unsigned char title_g[]; +extern unsigned char title_r[]; + +extern unsigned char anim1_g[]; +extern unsigned char anim1_r[]; + +extern unsigned char anim2_g[]; +extern unsigned char anim2_r[]; + +extern unsigned char anim3_g[]; +extern unsigned char anim3_r[]; + +extern unsigned char anim4_g[]; +extern unsigned char anim4_r[]; + +extern void dzx1_mega(); +extern void LZ48_decrunch(); + +unsigned char k, game_mode, text_progress; +#define FRAME_CURRENT text_progress + +void switch_gamemode(unsigned char mode) __z88dk_fastcall; + +#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 +}; + +unsigned char status; +unsigned char i, c; +#define delay i +unsigned char time_game; + +const char ingame_quote[5][12] = +{ + "KEEP IT UP!", + "STOP ", + "FUCK HIM ! ", + "FINISH ! ", +}; + + +const char text_minigame_1[] = +{ + "Your goal is to FUCK Zhongli!\nYou must follow the instructions to get more points.\nPenetrate him by pressing a key then pull out by releasing it.\nGood luck !" +}; + +/* This is done to save further space as game_mode 3, 0 , 1 all shared the same code */ +const unsigned char jump[5] = +{ 3, 0xFF, 0, 0xFF, 1 }; +static unsigned char bcd[4]; + +static void myownprint(const char* str, unsigned char x, unsigned char y) +{ + __asm + ld a, 0x00 + out (0x5F), a + __endasm; + gotoxy(x, y); + puts_cons((const char*)str); +} + +#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; \ + } \ + + + +static void Clear_Text() __z88dk_fastcall +{ + // Switch to TEXT VRAM + __asm + ld a, 0x00 + out (0x5F), a + __endasm; + memset((void*)0xC000, 0, 16000); + + // Switch to graphics mode + /*__asm + ld a, 0x00 + out (0x5c), a + __endasm;*/ +} + +static void Draw_Titlescreen() __z88dk_fastcall +{ + __asm + ; ExpandedGVRAM_On + ld c, 0x35 + ld a, 0x80 + out (c), a + + ; EnableALU(FASTMEM_ON); + ld c, 0x32 + ld a, 16 + out (c), a + + ; Switch to Blue + ld a, 0xff + out (0x5c), a + + ld hl, _title_b + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _title_r + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _title_g + ld de, 0xC000 + call _dzx1_mega + + ; DisableALU(FASTMEM_OFF); + ld c, 0x32 + ld a, 0 + out (c), a + + ; ExpandedGVRAM_Off(); + ld c, 0x35 + ld a, 0 + out (c), a + + ; SetMAINRAMBANK(); + ld c, 0x55 + ld a, 0xff + out (c), a + __endasm; +} + +static void Draw_Bakura() __z88dk_fastcall +{ + __asm + ; ExpandedGVRAM_On + ld c, 0x35 + ld a, 0x80 + out (c), a + + ; EnableALU(FASTMEM_ON); + ld c, 0x32 + ld a, 16 + out (c), a + + ; Switch to Blue + ld a, 0xff + out (0x5c), a + + ld hl, _frame1_b + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _frame1_r + ld de, 0xC000 + call _dzx1_mega + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _frame1_g + ld de, 0xC000 + call _dzx1_mega + + ; DisableALU(FASTMEM_OFF); + ld c, 0x32 + ld a, 0 + out (c), a + + ; ExpandedGVRAM_Off(); + ld c, 0x35 + ld a, 0 + out (c), a + + ; SetMAINRAMBANK(); + ld c, 0x55 + ld a, 0xff + out (c), a + __endasm; +} + +static void Draw_Frame1() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim1_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim1_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + +static void Draw_Frame2() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim2_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim2_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + +static void Draw_Frame3() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim3_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim3_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + +static void Draw_Frame4() __z88dk_fastcall +{ + __asm + + ; Switch to Red + ld a, 0xff + out (0x5d), a + + ld hl, _anim4_r + ld de, 0xC000+4000 + call _LZ48_decrunch + + ; Switch to Green + ld a, 0xff + out (0x5e), a + + ld hl, _anim4_g + ld de, 0xC000+4000 + call _LZ48_decrunch + __endasm; +} + +//pc88_fm_addr(); Check for FM, 0 if not found +//pc88_mode(); //2=V2, 1=V1, 0=N Mode +//pc88_8mhz(); Check if CPU is 8Mhz +unsigned char speedup; +void main() __z88dk_fastcall +{ + speedup = 48+3; + if (pc88_8mhz() == 1) + { + speedup = 48+4; + } + + // Set V1 mode + outp(0x5C, 0x61); + outp(0x5D, 0x00); + + switch_gamemode(0); + + bit_open(); + + while (1) + { + k = getk(); + switch(game_mode) + { + default: + if (k > 0) + { + 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 > 4) FRAME_CURRENT = 0; + + switch(FRAME_CURRENT) + { + case 0: + Draw_Frame1(); + break; + case 1: + Draw_Frame1(); + break; + case 2: + Draw_Frame2(); + break; + case 3: + Draw_Frame3(); + break; + case 4: + Draw_Frame4(); + break; + } + myownprint("SCORE", 0, 18); + myownprint(bcd, 10, 18); + } + + if (FRAME_CURRENT == 0) + { + if (k > 0) + { + bit_fx(4); + FRAME_CURRENT = 1; + } + } + + + + + + if (time_game > 70) + { + if (status_level1[status] == END_GAME_STATUS) + { + switch_gamemode(2); + } + else + { + time_game = 0; + status++; + myownprint(ingame_quote[status_level1[status]], 0, 19); + } + } + break; + case 3: + if (k > 0) + { + text_progress++; + + if (text_progress > 4) + { + switch_gamemode(4); + } + else + { + bit_fx4(2); + Clear_Text(); + + switch(text_progress) + { + case 1: + myownprint("You're going to be the perfect victim for my games!", 0, 18); + break; + case 2: + myownprint("I'm Rikuto, i offer you the chance to prove your worth in a trial", 0, 18); + break; + case 3: + myownprint("Don't be scared, it'll be fun!", 0, 18); + break; + case 4: + myownprint("Your challenge will be this: you will be on the other end and punish them", 0, 18); + break; + } + } + } + break; + } + + pc88_wait_vblank(); + } +} + +void switch_gamemode(unsigned char mode) __z88dk_fastcall +{ + game_mode = mode; + text_progress = 0; + status = 0; + time_game = 0; + i = 0; + clg(); + Clear_Text(); + + switch(mode) + { + case 0: + Draw_Titlescreen(); + bit_fx4(3); + //putsprite(0,14, 0, title_spr); + myownprint("COPYRIGHT INFRINGEMENT", 32, 12); + myownprint("THE REGRESSIVE RIGHT", 33, 13); + + myownprint("PUSH KEY TO START", 34, 17); + + myownprint("BY GAMEBLABLA, 2023", 0, 19); + break; + case 1: + bcd[0] = 48; + bcd[1] = 48; + bcd[2] = 48; + bcd[3] = '\0'; + __asm + ; ExpandedGVRAM_On + ld c, 0x35 + ld a, 0x80 + out (c), a + + ; EnableALU(FASTMEM_ON); + ld c, 0x32 + ld a, 16 + out (c), a + __endasm; + Draw_Frame1(); + myownprint("SCORE", 0, 18); + myownprint(bcd, 10, 18); + myownprint(ingame_quote[status_level1[status]], 0, 19); + break; + case 2: + Clear_Text(); + myownprint(" ", 0, 18); + myownprint(" ", 0, 19); + Draw_Bakura(); + myownprint("Your SCORE was ", 0, 0); + myownprint(bcd, 15, 0); + + if (bcd[0] < speedup-1) + { + bit_fx(5); + myownprint("Wow, you actually suck! Guess you'll stay there for a while. Haha!", 0, 18); + + } + else if (bcd[0] < speedup) + { + bit_fx(5); + myownprint("Not bad but you can do better! Otherwise you can't leave this place!", 0, 18); + + } + else + { + bit_fx(7); + myownprint("Haha, congrats!\nI'll leave you alone... For now, anyway.\nI'll see you later, bye for now", 0, 18); + + } + break; + case 3: + Draw_Bakura(); + myownprint("Oh my, what do we have here? You look so innocent...", 0, 18); + bit_fx4(0); + break; + case 4: + myownprint(text_minigame_1, 0, 0); + bit_fx4(5); + break; + } + +} + diff --git a/PC88/main.py b/PC88/main.py new file mode 100644 index 0000000..7144cb0 --- /dev/null +++ b/PC88/main.py @@ -0,0 +1,87 @@ +import sys +from PIL import Image + +def pc88_v2_color_mode(png_file): + custom_palette = [ + 0, 0, 0, # BLACK + 0, 0, 255, # BLUE + 255, 0, 0, # RED + 255, 0, 255, # PINK + 0, 255, 0, # GREEN + 0, 255, 255, # CYAN + 255, 255, 0, # YELLOW + 255, 255, 255, # WHITE + ] + + image = Image.open(png_file).convert("RGB") + width, height = image.size + + if width != 640: + print("The input image width must be 640 pixels.") + sys.exit(1) + + palette_image = Image.new("P", (1, 1)) + palette_image.putpalette(custom_palette) + + image = image.quantize(palette=palette_image).convert("P") + + plane_size = (height * 80) + planes = { + 'green': bytearray(plane_size), + 'red': bytearray(plane_size), + 'blue': bytearray(plane_size), + } + + + for y in range(height): + for x in range(width): + pixel = image.getpixel((x, y)) + c = 0 + + if pixel == 0: # Black + c = 0b000 + elif pixel == 1: # Blue + c = 0b001 + elif pixel == 2: # Red + c = 0b010 + elif pixel == 3: # Magenta + c = 0b011 + elif pixel == 4: # Green + c = 0b100 + elif pixel == 5: # Cyan + c = 0b101 + elif pixel == 6: # Yellow + c = 0b110 + elif pixel == 7: # White + c = 0b111 + + po = 7 - (x % 8) + byte_offset = (y * 80) + (x // 8) + + if c & 0b001: + planes['blue'][byte_offset] |= 1 << po + if c & 0b010: + planes['red'][byte_offset] |= 1 << po + if c & 0b100: + planes['green'][byte_offset] |= 1 << po + + return planes + +def main(): + if len(sys.argv) != 2: + print(f"Usage: {sys.argv[0]} ") + sys.exit(1) + + input_png = sys.argv[1] + + output_data = pc88_v2_color_mode(input_png) + base_filename = input_png.rsplit('.', 1)[0] + + for color, data in output_data.items(): + output_file = f"{base_filename}_{color}.bin" + with open(output_file, 'wb') as f: + f.write(data) + print(f"Saved {color} plane to {output_file}") + +if __name__ == "__main__": + main() diff --git a/PC88/pc88_rikuto.png b/PC88/pc88_rikuto.png new file mode 100644 index 0000000..1391e9c Binary files /dev/null and b/PC88/pc88_rikuto.png differ diff --git a/PC88/run.sh b/PC88/run.sh new file mode 100755 index 0000000..f42f36f --- /dev/null +++ b/PC88/run.sh @@ -0,0 +1,40 @@ +#!/bin/sh +rm *.d88 +python main.py bakurapc88.png +python main.py frame1.png +python main.py frame2.png +python main.py frame3.png +python main.py frame4.png +python main.py titlescreen.png + +#zx1 frame1_red.bin frame1_red.zx1 +#zx1 frame1_green.bin frame1_green.zx1 +#zx1 frame2_red.bin frame2_red.zx1 +#zx1 frame2_green.bin frame2_green.zx1 +#zx1 frame3_red.bin frame3_red.zx1 +#zx1 frame3_green.bin frame3_green.zx1 +#zx1 frame4_red.bin frame4_red.zx1 +#zx1 frame4_green.bin frame4_green.zx1 + +zx1 titlescreen_blue.bin titlescreen_blue.zx1 +zx1 titlescreen_red.bin titlescreen_red.zx1 +zx1 titlescreen_green.bin titlescreen_green.zx1 + +zx1 bakurapc88_blue.bin bakurapc88_blue.zx1 +zx1 bakurapc88_red.bin bakurapc88_red.zx1 +zx1 bakurapc88_green.bin bakurapc88_green.zx1 + +./lz48.elf -i frame1_red.bin -o frame1_red.lz +./lz48.elf -i frame1_green.bin -o frame1_green.lz + +./lz48.elf -i frame2_red.bin -o frame2_red.lz +./lz48.elf -i frame2_green.bin -o frame2_green.lz + +./lz48.elf -i frame3_red.bin -o frame3_red.lz +./lz48.elf -i frame3_green.bin -o frame3_green.lz + +./lz48.elf -i frame4_red.bin -o frame4_red.lz +./lz48.elf -i frame4_green.bin -o frame4_green.lz + +zcc -compiler=sdcc -SO3 --max-allocs-per-node200000 +pc88 -subtype=disk main.c data.asm draw.s dzx1.asm lz48.asm -create-app -pragma-define:CLIB_PC8800_V2_ENABLED=1 -pragma-define:CRT_ENABLE_STDIO=0 -pragma-define:CLIB_EXIT_STACK_SIZE=0 -o copyright_infringement +zcc -compiler=sdcc -SO3 --max-allocs-per-node200000 +pc88 -Cz--audio main.c data.asm draw.s dzx1.asm lz48.asm -create-app -pragma-define:CLIB_PC8800_V2_ENABLED=1 -pragma-define:CRT_ENABLE_STDIO=0 -pragma-define:CLIB_EXIT_STACK_SIZE=0 -o copyright_infringement diff --git a/PC88/titlescreen.png b/PC88/titlescreen.png new file mode 100644 index 0000000..6359390 Binary files /dev/null and b/PC88/titlescreen.png differ diff --git a/PC88/titlescreen.vgm b/PC88/titlescreen.vgm new file mode 100644 index 0000000..892fb3a Binary files /dev/null and b/PC88/titlescreen.vgm differ diff --git a/PC88/titlescreen_pc88.png b/PC88/titlescreen_pc88.png new file mode 100644 index 0000000..2be3361 Binary files /dev/null and b/PC88/titlescreen_pc88.png differ diff --git a/README.md b/README.md index 93fd15b..2f4287f 100644 --- a/README.md +++ b/README.md @@ -305,3 +305,27 @@ There's also some PCM samples in there although it's heavily downsampled, 4-bits I still wanted to include it however. [Download C64 version](https://github.com/gameblabla/copyright_infringement_ports/releases/tag/1.0-C64) + +NEC PC-88 +================== +![](https://github.com/gameblabla/copyright_infringement_ports/raw/simp/img/pc88.jpg) + +The NEC PC-88 (and the PC-98) is the home to numerous hentai games. +Thus, this game should have perfectly suitable for this hardware. +Except not really, because outside of japanese documents (and even then, there's not a huge lot of it!), +they are surprisingly poorly documented. +I did get a VGM player working on it thanks to pc88-c but since i can't compose anything on it, +all you gonna get are simple beeps. Oh and forget about the ADPCM card, i have no idea how to use that either. +(Most PC-88 don't have it anyway) + +The other big issue is the huge amount of VRAM it needs to update and the lackluster CPU for it. +I mean, updating 48kb multiple times per second on a puny Z80 is no small task ! +I cheated a little bit by downgrading it to 4 colors in game to get it in a playable state. +It works but you can still see the graphics chip struggling to keep up. + +I'm sure with delta compression, compressed code etc... i could get it further than this +but even if i could figure that out, z88dk's support for non-CP/M platforms is also lackluster as well ! + +I think i did a decent-ish job but it could have been better even considering the hardware. + +[Download PC-88 version](https://github.com/gameblabla/copyright_infringement_ports/releases/tag/1.0-PC88) diff --git a/img/pc88.jpg b/img/pc88.jpg new file mode 100644 index 0000000..95a90c1 Binary files /dev/null and b/img/pc88.jpg differ