Skip to content

Commit

Permalink
Zx80, load and Save, TV sound (#34)
Browse files Browse the repository at this point in the history
* zx80 and vsync sound

* Test wav save

* improve beep generation

* Correct silence

* Testing

* Fix race

* add uf2

* audio sync & z80 chroma offset

* Update uf2

---------

Co-authored-by: ikjordan <iankjordan@gmail.com>
  • Loading branch information
ikjordan and ikjordan authored Jul 3, 2024
1 parent 47fcc42 commit 08b5233
Show file tree
Hide file tree
Showing 52 changed files with 2,700 additions and 1,365 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,4 @@
build/*

# Allow example file
!examples/ZX80/simple.o
!examples/ZX80-4K/simple.o
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ elseif ((${PICO_BOARD} STREQUAL "vgamaker222cboard") OR (${PICO_BOARD} STREQUAL
endif()

set(ZX8X_SOURCES
src/Z80.c
src/z80.c
src/zx8x.c
src/emuapi.cpp
src/emusound.cpp
src/emuvideo.cpp
src/emukeyboard.cpp
src/loadp.c
src/pico81.cpp
src/hid_usb.c
src/sound.c
Expand Down Expand Up @@ -217,6 +218,9 @@ if (${OVER_VOLT})
target_compile_definitions(${PROJECT} PRIVATE -DOVER_VOLT)
endif()

# always support Chroma
target_compile_definitions(${PROJECT} PRIVATE -DSUPPORT_CHROMA -DLOAD_AND_SAVE)

target_compile_options(${PROJECT} PRIVATE -Wall)

target_link_libraries(${PROJECT}
Expand Down
70 changes: 49 additions & 21 deletions README.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions buildall
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build_uf2()
board=$1"board .."
uf2="picozx81_"$1".uf2"

cmake -DHDMI_SOUND=OFF -DPICO_BOARD=${board}
cmake -DHDMI_SOUND=OFF -DCMAKE_BUILD_TYPE=Release -DTIME_SPARE=OFF -DPICO_BOARD=${board}
make -j4
cp ./${uf2} ../uf2/${uf2}
}
Expand All @@ -16,7 +16,7 @@ build_uf2_hdmi()
board=$1"board .."
uf2="picozx81_"$1"_hdmi_sound.uf2"

cmake -DHDMI_SOUND=ON -DPICO_BOARD=${board}
cmake -DHDMI_SOUND=ON -DCMAKE_BUILD_TYPE=Release -DTIME_SPARE=OFF -DPICO_BOARD=${board}
make -j4
cp ./${uf2} ../uf2/${uf2}
}
Expand All @@ -26,7 +26,7 @@ build_uf2_lcd()
board=$1"board .."
uf2="picozx81_"$1"_lcd.uf2"

cmake -DPICOZX_LCD=ON -DPICO_BOARD=${board}
cmake -DPICOZX_LCD=ON -DCMAKE_BUILD_TYPE=Release -DTIME_SPARE=OFF -DPICO_BOARD=${board}
make -j4
cp ./${uf2} ../uf2/${uf2}
}
Expand Down
9 changes: 6 additions & 3 deletions display/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,24 @@ extern uint displayInitialise(bool fiveSevenSix, bool match, uint16_t minBuffByt
uint16_t* pixelHeight, uint16_t* strideBit, DisplayExtraInfo_T* info);
extern void displayStart(void);

extern bool displayShowKeyboard(bool zx81);
extern bool displayShowKeyboard(bool ROM8K);

/* Common */
extern void displayGetFreeBuffer(uint8_t** buff);
extern void displayBuffer(uint8_t* buff, bool sync, bool free, bool chroma);
extern void displayGetCurrentBuffer(uint8_t** buff);
extern void displayGetChromaBuffer(uint8_t** chroma, uint8_t* buff);
extern void displayResetChroma(void);
extern void displaySetInterlace(bool on);

extern void displayBlank(bool black);
extern bool displayIsBlank(bool* isBlack);

extern bool displayHideKeyboard(void);

#ifdef SUPPORT_CHROMA
extern void displayGetChromaBuffer(uint8_t** chroma, uint8_t* buff);
extern void displayResetChroma(void);
#endif

#ifdef PICO_SPI_LCD_SD_SHARE
extern void displayRequestSPIBus(void);
extern void displayGrantSPIBus(void);
Expand Down
32 changes: 24 additions & 8 deletions display/display_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
#include "zx80bmp.h"
#include "zx81bmp.h"

#ifdef SUPPORT_CHROMA
// Structure for chroma buffers
typedef struct
{
uint8_t* buff;
bool used;
} chroma_t;
#endif

mutex_t next_frame_mutex;
semaphore_t display_initialised;
Expand All @@ -23,8 +25,9 @@ bool blank = true;
uint16_t blank_colour = BLACK;

uint8_t* curr_buff = 0; // buffer being displayed
#ifdef SUPPORT_CHROMA
uint8_t* cbuffer = 0; // Chroma buffer

#endif
const KEYBOARD_PIC* keyboard = &ZX81KYBD;
bool showKeyboard = false;

Expand All @@ -39,7 +42,9 @@ bool showKeyboard = false;

static uint8_t* pend_buff[MAX_PEND] = {0, 0}; // Buffers queued for display
static uint8_t* free_buff[MAX_FREE] = {0, 0, 0, 0}; // Buffers available to be claimed
#ifdef SUPPORT_CHROMA
static chroma_t chroma[MAX_FREE] = { {0, false}, {0, false}, {0,false}, {0,false} };
#endif
static uint8_t* index_to_display[MAX_FREE] = {0, 0, 0, 0};
static uint8_t* last_buff = 0; // previously displayed buffer (interlace mode only)

Expand All @@ -54,9 +59,10 @@ static bool no_skip = false;
static inline void freeAllPending(void);
static inline void freeLast(void);
static inline void swapCurrAndLast(void);
#ifdef SUPPORT_CHROMA
static inline void displayGetChromaBufferUsed(uint8_t** chroma_buff, uint8_t* buff);
static inline void set_chroma_used(uint8_t* buff, bool used);

#endif
//
// Public functions
//
Expand All @@ -73,6 +79,7 @@ void displayAllocateBuffers(uint16_t minBuffByte, uint16_t stride, uint16_t heig
index_to_display[i] = free_buff[i];
}

#ifdef SUPPORT_CHROMA
// Allocate chroma buffers
for (int i=0; i<MAX_FREE; ++i)
{
Expand All @@ -85,8 +92,8 @@ void displayAllocateBuffers(uint16_t minBuffByte, uint16_t stride, uint16_t heig
exit(-1);
}
}
#endif
free_count = MAX_FREE;

}

/* Set the interlace state */
Expand Down Expand Up @@ -156,7 +163,9 @@ void __not_in_flash_func(displayBuffer)(uint8_t* buff, bool sync, bool free, boo
// Obtain lock
mutex_enter_blocking(&next_frame_mutex);

#ifdef SUPPORT_CHROMA
set_chroma_used(buff, chroma);
#endif
if (sync && !blank)
{
// Store in next, unless next is full
Expand Down Expand Up @@ -231,6 +240,7 @@ void __not_in_flash_func(displayGetCurrentBuffer)(uint8_t** buff)
mutex_exit(&next_frame_mutex);
}

#ifdef SUPPORT_CHROMA
/* Get the chroma buffer associated with a display buffer */
void __not_in_flash_func(displayGetChromaBuffer)(uint8_t** chroma_buff, uint8_t* buff)
{
Expand Down Expand Up @@ -268,6 +278,7 @@ static inline void displayGetChromaBufferUsed(uint8_t** chroma_buff, uint8_t* bu
}
*chroma_buff = 0;
}
#endif

/* Blank the display */
void __not_in_flash_func(displayBlank)(bool black)
Expand Down Expand Up @@ -329,6 +340,7 @@ void displayStartCommon(void)
void __not_in_flash_func(newFrame)(void)
{
mutex_enter_blocking(&next_frame_mutex);

if (!blank)
{
if (pend_count)
Expand Down Expand Up @@ -404,15 +416,18 @@ void __not_in_flash_func(newFrame)(void)
}
}
}
#ifdef SUPPORT_CHROMA
// Obtain the associated chroma buffer iff chroma enabled
displayGetChromaBufferUsed(&cbuffer, curr_buff);
#endif
mutex_exit(&next_frame_mutex);
}

//
// Private functions
//

#ifdef SUPPORT_CHROMA
/* Indicate whether chroma is enabled for the supplied pixel buffer */
static inline void set_chroma_used(uint8_t* buff, bool used)
{
Expand All @@ -426,6 +441,7 @@ static inline void set_chroma_used(uint8_t* buff, bool used)
}
}
}
#endif

static inline void __not_in_flash_func(freeAllPending)(void)
{
Expand Down Expand Up @@ -479,12 +495,12 @@ static inline void __not_in_flash_func(swapCurrAndLast)(void)
extern uint displayInitialiseLCD(bool fiveSevenSix, bool match, uint16_t minBuffByte, uint16_t* pixelWidth,
uint16_t* pixelHeight, uint16_t* strideBit, DisplayExtraInfo_T* info);
extern void displayStartLCD(void);
extern bool displayShowKeyboardLCD(bool zx81);
extern bool displayShowKeyboardLCD(bool ROM8K);

extern uint displayInitialiseVGA(bool fiveSevenSix, bool match, uint16_t minBuffByte, uint16_t* pixelWidth,
uint16_t* pixelHeight, uint16_t* strideBit, DisplayExtraInfo_T* info);
extern void displayStartVGA(void);
extern bool displayShowKeyboardVGA(bool zx81);
extern bool displayShowKeyboardVGA(bool ROM8K);

uint displayInitialise(bool fiveSevenSix, bool match, uint16_t minBuffByte, uint16_t* pixelWidth,
uint16_t* pixelHeight, uint16_t* strideBit, DisplayExtraInfo_T* info)
Expand Down Expand Up @@ -513,15 +529,15 @@ void displayStart(void)
}
}

bool displayShowKeyboard(bool zx81)
bool displayShowKeyboard(bool ROM8K)
{
if (useLCD)
{
return displayShowKeyboardLCD(zx81);
return displayShowKeyboardLCD(ROM8K);
}
else
{
return displayShowKeyboardVGA(zx81);
return displayShowKeyboardVGA(ROM8K);
}
}

Expand Down
13 changes: 9 additions & 4 deletions display/display_dvi.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,13 @@ void displayStart(void)
displayStartCommon();
}

bool displayShowKeyboard(bool zx81)
bool displayShowKeyboard(bool ROM8K)
{
bool previous = showKeyboard;

if (!showKeyboard)
{
keyboard = zx81 ? &ZX81KYBD : &ZX80KYBD;
keyboard = ROM8K ? &ZX81KYBD : &ZX80KYBD;
keyboard_x = (PIXEL_WIDTH - keyboard->width)>>1;
keyboard_y = (HEIGHT - keyboard->height)>>1;
keyboard_right = (keyboard_x & 0xffe0) + keyboard->width;
Expand All @@ -162,8 +162,9 @@ static void __not_in_flash_func(render_loop)()
for (uint y = 0; y < HEIGHT; ++y)
{
uint8_t* buff = curr_buff; // As curr_buff can change at any time
#ifdef SUPPORT_CHROMA
uint8_t* cbuf = cbuffer;

#endif
const uint8_t* linebuf = &buff[stride * y];

queue_remove_blocking_u32(&dvi0.q_tmds_free, &tmdsbuf);
Expand Down Expand Up @@ -196,6 +197,7 @@ static void __not_in_flash_func(render_loop)()
}
else
{
#ifdef SUPPORT_CHROMA
if (cbuf)
{
const uint8_t* chromabuf = &cbuf[stride * y];
Expand All @@ -220,14 +222,15 @@ static void __not_in_flash_func(render_loop)()
}
}
else
#endif
{
// 32 pixels of display at 320, 52 pixels at 360
tmds_double_1bpp(linebuf, tmdsbuf, keyboard_x<<1);

// Now do the end, as we need to encode from a 32 bit aligned boundary

// 32 more pixels of display at 320, 52 more pixels at 360
// Calculate start in pixels - to get to bytes need to shift 3 times
// Calculate start in pixels - to get to bytes need to shift 3 times
tmds_double_1bpp(&linebuf[keyboard_right>>3], &tmdsbuf[keyboard_right], keyboard_to_fill<<1);

// Insert 256 pixel of keyboard
Expand All @@ -254,6 +257,7 @@ static void __not_in_flash_func(render_loop)()
}
else
{
#ifdef SUPPORT_CHROMA
if (cbuf)
{
const uint8_t* chromabuf = &cbuf[stride * y];
Expand All @@ -262,6 +266,7 @@ static void __not_in_flash_func(render_loop)()
tmds_encode_screen(linebuf, chromabuf, &tmdsbuf[p], CHARACTER_WIDTH, plane);
}
else
#endif
{
tmds_double_1bpp(linebuf, tmdsbuf, video_mode->h_active_pixels);
tmds_clone(tmdsbuf, PIXEL_WIDTH);
Expand Down
13 changes: 8 additions & 5 deletions display/display_lcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ void displayStartLCD(void)
}

#ifndef PICOZX_LCD
bool displayShowKeyboard(bool zx81)
bool displayShowKeyboard(bool ROM8K)
#else
bool displayShowKeyboardLCD(bool zx81)
bool displayShowKeyboardLCD(bool ROM8K)
#endif
{
bool previous = showKeyboard;
Expand All @@ -165,12 +165,12 @@ bool displayShowKeyboardLCD(bool zx81)
#ifdef PICOZX_LCD
if (useLCD)
{
keyboard = zx81 ? &ZX81KYBD_LCD : &ZX80KYBD_LCD;
keyboard = ROM8K ? &ZX81KYBD_LCD : &ZX80KYBD_LCD;
}
else
#endif
{
keyboard = zx81 ? &ZX81KYBD : &ZX80KYBD;
keyboard = ROM8K ? &ZX81KYBD : &ZX80KYBD;
}
keyboard_x = (PIXEL_WIDTH - keyboard->width)>>1;
keyboard_y = (HEIGHT - keyboard->height)>>1;
Expand Down Expand Up @@ -300,8 +300,11 @@ static void __not_in_flash_func(render_loop)()
for (uint y = 0; y < HEIGHT; ++y)
{
uint8_t* buff = curr_buff; // As curr_buff can change at any time
#ifdef SUPPORT_CHROMA
uint8_t* cbuff = cbuffer;

#else
uint8_t* cbuff = 0;
#endif
uint8_t* linebuf = &buff[stride * y];
uint8_t* clinebuf = cbuff ? &cbuff[stride * y] : 0;

Expand Down
11 changes: 7 additions & 4 deletions display/display_vga.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,16 @@ void displayStartVGA(void)
}

#ifndef PICOZX_LCD
bool displayShowKeyboard(bool zx81)
bool displayShowKeyboard(bool ROM8K)
#else
bool displayShowKeyboardVGA(bool zx81)
bool displayShowKeyboardVGA(bool ROM8K)
#endif
{
bool previous = showKeyboard;

if (!showKeyboard)
{
keyboard = zx81 ? &ZX81KYBD : &ZX80KYBD;
keyboard = ROM8K ? &ZX81KYBD : &ZX80KYBD;
keyboard_x = (video_mode->width - keyboard->width) >> 2; // Centre (>>1), then 2 pixels per byte (>>1)
keyboard_y = (HEIGHT - keyboard->height) >> 1;
showKeyboard = true;
Expand Down Expand Up @@ -413,8 +413,11 @@ static void __not_in_flash_func(render_loop)()
}

uint8_t* current = curr_buff; // As disp_index can change at any time
#ifdef SUPPORT_CHROMA
uint8_t* cbuf = cbuffer;

#else
uint8_t* cbuf = 0;
#endif
if (showKeyboard && (line_num >= keyboard_y) && (line_num <(keyboard_y + keyboard->height)))
{
if (blank)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[Default]
# The default settings for Chroma ZX80
Computer = ZX80
Sound = NONE
Computer = ZX80-4K
Sound = CHROMA
Memory = 48
LowRAM = ON
WRX = OFF
Expand Down
Loading

0 comments on commit 08b5233

Please sign in to comment.