Skip to content

Commit 8c13f23

Browse files
committed
v31.4 Bugfixes and additions
1 parent 5648d4d commit 8c13f23

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1688
-1113
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 smds
3+
Copyright (c) 2025 smds
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

changelog.txt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,42 @@
1+
v0.31.4
2+
IRC: Added NICK and PART to the internal command parser that parses messages received from the server. (Sending NICK/PART from client to server is already supported)
3+
IRC: Reverted the upload icon colour back to default, changing it from red to orange serves no purpose anymore.
4+
Drivers: Added timeout to pinging in xport driver, apparently there wasn't one already...
5+
Telnet/Term: Added IAC DM (Data Mark).
6+
Telnet/Term: Prototype scrollable regions (Scroll part of the screen vertically). It can scroll content upwards only! scrolling down requires more work.
7+
Telnet/Term: Rewrote the OSC parser so it is not hardcoded to just reading title changes.
8+
Telnet/Term: Fake RGB24 attribute colour support (Truncates RGB888 to RGB111, yes 1 bit per channel).
9+
Telnet/Term: Rewrote attribute code parser slightly, hopefully I haven't borked colour attribute changes in some way...
10+
Telnet/Term: Cursor is now using s16 instead of s32 (Haven't dared to change this before in case of hidden edge cases).
11+
Telnet/Term: Many little changes and fixes here and there.
12+
Telnet: Added F1-F12, Page Up/Down, End, Home, Insert and Delete function keys.
13+
Buffer system now uses boolean return values instead of cryptic magic numbers as return values on PUSH/POP.
14+
Cleaned up Buffer_PeekLast() and various other functions.
15+
For no real reason: 2 new theme colours: Aqua and hot pink. Don't ask why.
16+
Removed old debug streaming.
17+
Changed Backspace default back from ^H to DEL now that I've found out why it bugged out at times (smdt manually moved cursor and inserted blankspace, it shouldn't do that).
18+
Some UTF-8 code point fixes and additions in U+2500 and a few arrows in U+2190.
19+
Added 68k exception pages (Inspired by Vladikcompers recent exception handler added to SGDK). Still fairly basic but its better than what SMDT had before: no exception handlers at all.
20+
Uname command can now show SMDT build date and time.
21+
22+
Bugs?
23+
Spurious keyboard input when SMDT is overwhelmed by large incoming data transfers? May be emulator/xport emulator error on my end but I have not noticed this problem in previous versions of SMDT...
24+
25+
Bugfixes:
26+
IRC: Receiving NAMES list should no longer show a channel as having new messages.
27+
IRC: Nicklist now shows the last nick in the nicklist. Beware that showing >300 nicks may cause issues still.
28+
IRC: Normal mIRC colours should now work as expected when using 4x8 fonts, albeit in mono (2 colours).
29+
IRC: Now using \4 and \5 to set/unset custom text colouring in IRC (instead of \1 and \2), in hindsight this change was not actually necessary but it doesn't matter anyway.
30+
Telnet/Term: Fixed G1 charset bug that caused the terminal to use the wrong character set in certain applications.
31+
Telnet/Term: Fixed ESC PARAM not resetting all parameters between different escape sequences.
32+
Telnet/Term: Finally fixed wraparound "bug" that appears when the terminal receives \n at column 80 (causing 2 newlines), as opposed to receiving a printable character at column 80 (which should wrap and print to the next line).
33+
Drivers: Maybe fixed PS/2 timing issues on model 2 / NTSC genesis systems?
34+
35+
Known bugs:
36+
TimeToStr_Full() in IRC client does not take your timezone into account? (Command 333 @ IRC.c).
37+
4x8 colouring in IRC can only colour even number of characters, uneven number will result in the final character being uncoloured.
38+
39+
140
v0.31.3 Minor bugfix
241
IRC mono colour antialiasing colour is now updated to reflect the new amber text colour.
342
Interrupts were disabled to early on StateExit() which made the XPN drivers unable to actually communicate during Disconnect(). This caused excessive delays when trying to disconnect from servers.

doc/VRAM.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ $10 - $15 Cursor tiles (Block/Line/Bar 8x8/4x8)
66
$16 Blank/invisible cursor tile
77
$17 Mouse pointer cursor
88
$18 - $1F Icons
9-
$20 - $2F Screensaver sprite tiles (16 tiles) - Used by boot logo on startup
10-
$30 - $3F Free (16 tiles) - Used by boot logo on startup
9+
$20 - $2F Screensaver sprite tiles (16 tiles)
10+
$30 - $3F Free (16 tiles)
1111
$40 - $23F Terminal ASCII font
1212
$240 - $43F Terminal ASCII font duplicate used for 80 column colour support otherwise free (480 tiles)
1313
$440 - $4FF UI font and window tiles

src/Buffer.c

Lines changed: 45 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,18 @@
33

44
/// @brief Check if buffer is full
55
/// @param b Pointer to buffer
6-
/// @return 0xFF if full, otherwise 0
7-
u8 Buffer_IsFull(Buffer *b)
6+
/// @return TRUE if full, otherwise FALSE
7+
bool Buffer_IsFull(Buffer *b)
88
{
9-
if ((b->head + 1) == b->tail) // if the head + 1 == tail, circular buffer is full
10-
return 0xFF;
11-
12-
return 0; // return false
9+
return ((b->head + 1 == BUFFER_LEN ? 0 : b->head + 1) == b->tail);
1310
}
1411

1512
/// @brief Check if buffer is empty
1613
/// @param b Pointer to buffer
17-
/// @return 0xFF if empty, otherwise 0
18-
u8 Buffer_IsEmpty(Buffer *b)
14+
/// @return TRUE if empty, otherwise FALSE
15+
bool Buffer_IsEmpty(Buffer *b)
1916
{
20-
if (b->head == b->tail) // if the head == tail, circular buffer is empty
21-
return 0xFF;
22-
23-
return 0; // return false
17+
return b->head == b->tail;
2418
}
2519

2620
/// @brief Get the number of bytes in buffer
@@ -45,86 +39,56 @@ u16 Buffer_GetNum(Buffer *b)
4539
/// @brief Push byte into buffer at head
4640
/// @param b Pointer to buffer
4741
/// @param data Byte data to push into buffer
48-
/// @return 0xFF is returned if the buffer is full (data is dropped). 0 on successful push
49-
u8 Buffer_Push(Buffer *b, u8 data)
42+
/// @return FALSE is returned if the buffer is full (data is dropped). TRUE on successful push
43+
bool Buffer_Push(Buffer *b, u8 data)
5044
{
5145
u16 next;
5246

5347
next = b->head + 1; // next is where head will point to after this write.
54-
if (next >= BUFFER_LEN)
48+
if (next == BUFFER_LEN)
5549
next = 0;
5650

5751
if (next == b->tail) // if the head + 1 == tail, circular buffer is full
58-
return 0xFF;
52+
return FALSE;
5953

6054
b->data[b->head] = data; // Load data and then move
6155
b->head = next; // head to next data offset.
6256

63-
return 0; // return success to indicate successful push.
57+
return TRUE; // return success to indicate successful push.
6458
}
6559

6660
/// @brief Pop buffer data at tail into return byte
6761
/// @param b Pointer to buffer
6862
/// @param data Return byte to pop data into
69-
/// @return 0xFF is returned if the buffer is empty. 0 on successful pop.
70-
u8 Buffer_Pop(Buffer *b, u8 *data)
63+
/// @return FALSE is returned if the buffer is empty. TRUE on successful pop.
64+
bool Buffer_Pop(Buffer *b, u8 *data)
7165
{
7266
u16 next;
7367

7468
if (b->head == b->tail) // if the head == tail, we don't have any data
75-
return 0xFF;
69+
return FALSE;
7670

7771
next = b->tail + 1; // next is where tail will point to after this read.
78-
if (next >= BUFFER_LEN) next = 0;
72+
if (next == BUFFER_LEN) next = 0;
7973

8074
*data = b->data[b->tail]; // Read data and then move
8175
b->tail = next; // tail to next offset.
8276

83-
return 0; // return success to indicate successful pop.
84-
}
85-
86-
/// @brief Push byte into buffer at specific position - Do not use! Not implemented!
87-
/// @param b Pointer to buffer
88-
/// @param pos Position where the byte should be pushed into
89-
/// @param data Byte data to push into buffer
90-
/// @return FALSE is returned if the buffer is full (data is dropped). TRUE on successful push
91-
bool Buffer_PushAt(Buffer *b, u16 pos, u8 data)
92-
{
93-
//u16 next;
94-
95-
if (Buffer_IsFull(b)) return FALSE;
96-
97-
// Quick path
98-
if (Buffer_IsEmpty(b))
99-
{
100-
b->data[pos] = data;
101-
return TRUE;
102-
}
103-
104-
if (b->tail < b->head)
105-
{
106-
// ...
107-
}
108-
else if (b->tail > b->head)
109-
{
110-
// ...
111-
}
112-
113-
return TRUE; // return success to indicate successful push.
77+
return TRUE; // return success to indicate successful pop.
11478
}
11579

11680
/// @brief Pop the byte at the head of buffer
11781
/// @param b Pointer to buffer
118-
/// @return 0xFF if the buffer is empty. 0 on successful pop.
119-
u8 Buffer_ReversePop(Buffer *b)
82+
/// @return FALSE if the buffer is empty. TRUE on successful pop.
83+
bool Buffer_ReversePop(Buffer *b)
12084
{
12185
if (b->head == b->tail) // if the head == tail, we don't have any data
122-
return 0xFF;
86+
return FALSE;
12387

12488
if (b->head == 0) b->head = BUFFER_LEN-1;
12589
else b->head--;
12690

127-
return 0;
91+
return TRUE;
12892
}
12993

13094
/// @brief Clear the buffer
@@ -145,60 +109,39 @@ void Buffer_Flush0(Buffer *b)
145109
for (u8 i = 0; i < 32; i++) b->data[i] = 0;
146110
}
147111

148-
/// @brief Get the last <num> of bytes up to head
149-
/// @param b Pointer to buffer
150-
/// @param num Number of bytes to return
151-
/// @param r Array of bytes to return the popped data in
152-
void Buffer_PeekLast(Buffer *b, u16 num, u8 r[])
112+
/// @brief Get the last <num> bytes from the buffer.
113+
/// @param b Pointer to the buffer.
114+
/// @param num Number of bytes to return.
115+
/// @param r Array to store the extracted bytes.
116+
void Buffer_PeekLast(Buffer *b, u16 num, u8 r[])
153117
{
154-
u16 tmpTail = b->tail;
155-
u16 c = 0;
156-
u16 next;
118+
// Calculate the size of valid data in the buffer
119+
u16 size = (b->head >= b->tail)
120+
? (b->head - b->tail)
121+
: (BUFFER_LEN - b->tail + b->head);
157122

158-
// Get the size difference between the head and tail to determine amount of bytes we can pull from it
159-
if (b->tail < b->head)
160-
{
161-
tmpTail = (b->head - num) > 0 ? b->head - num : 0; // Tail smaller than head. We must check if we actually have 'num' bytes available
162-
}
163-
else if (b->tail > b->head)
164-
{
165-
tmpTail = ((b->head-1-((num-1)-c))+BUFFER_LEN) % BUFFER_LEN; // Tail larger than head. Wrap around and get 'num' bytes available
166-
}
167-
168-
tmpTail = (tmpTail < b->tail ? b->tail : tmpTail); // Make sure the temporary tail is not behind the real tail
169-
170-
if (tmpTail == b->head)
123+
// Determine the actual number of bytes to copy
124+
u16 bytesToCopy = (num > size) ? size : num;
125+
126+
// Ensure the result array is fully zero-filled if no valid data is available
127+
if (bytesToCopy == 0)
171128
{
172-
// Tail == head. No bytes available, clear 'r' and return
173-
while (c < num)
174-
{
175-
r[c] = 0;
176-
c++;
177-
}
129+
for (u16 i = 0; i < num; i++) r[i] = 0;
178130
return;
179131
}
180132

181-
// Fill the array 'r' with all the bytes from head back to the tail in reverse order
182-
while (c < num)
183-
{
184-
if (b->head == tmpTail) // if the head == tail, we don't have any data
185-
break;
186-
187-
next = tmpTail + 1; // next is where tail will point to after this read.
188-
if(next >= BUFFER_LEN)
189-
next = 0;
190-
191-
r[c] = b->data[tmpTail]; // Read data and then move
192-
tmpTail = next; // tail to next offset.
193-
c++;
194-
}
133+
// Calculate the starting index for reading
134+
u16 start = (b->head >= bytesToCopy)
135+
? (b->head - bytesToCopy)
136+
: (BUFFER_LEN + b->head - bytesToCopy);
195137

196-
// If the array 'r' is not full then fill the rest of the array with NULL
197-
while (c < num)
138+
// Copy the valid bytes into the result array
139+
for (u16 i = 0; i < bytesToCopy; i++)
198140
{
199-
r[c] = 0;
200-
c++;
141+
u16 index = (start + i) % BUFFER_LEN;
142+
r[i] = b->data[index];
201143
}
202144

203-
return;
145+
// Null-terminate/zero-fill the remainder of the array
146+
for (u16 i = bytesToCopy; i < num; i++) r[i] = 0;
204147
}

src/Buffer.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ typedef struct s_buffer
1212
u16 tail;
1313
} Buffer;
1414

15-
u8 Buffer_IsFull(Buffer *b);
16-
u8 Buffer_IsEmpty(Buffer *b);
15+
bool Buffer_IsFull(Buffer *b);
16+
bool Buffer_IsEmpty(Buffer *b);
1717
u16 Buffer_GetNum(Buffer *b);
18-
u8 Buffer_Push(Buffer *b, u8 data);
19-
u8 Buffer_Pop(Buffer *b, u8 *data);
20-
u8 Buffer_ReversePop(Buffer *b);
18+
bool Buffer_Push(Buffer *b, u8 data);
19+
bool Buffer_Pop(Buffer *b, u8 *data);
20+
bool Buffer_ReversePop(Buffer *b);
2121

2222
void Buffer_Flush(Buffer *b);
2323
void Buffer_Flush0(Buffer *b);

src/DevMgr.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,16 @@ void DetectDevices()
131131

132132
// -- PS/2 Keyboard setup --------------------------
133133
bool ps2_r = FALSE;
134-
135-
// Try to find the keyboard twice... because apparently that is needed in some cases
136-
for (u8 i = 0; i < 2; i++)
137-
{
138-
if ( DevId0 == DEVICE_UNKNOWN) {ps2_r = KB_PS2_Init(DP_Port1);}
139-
if ((DevId1 == DEVICE_UNKNOWN) && !ps2_r) {ps2_r = KB_PS2_Init(DP_Port2);}
140-
if ((DevId2 == DEVICE_UNKNOWN) && !ps2_r) {ps2_r = KB_PS2_Init(DP_Port3);}
141134

142-
if (ps2_r)
143-
{
144-
DevList[DevSeq++] = &DRV_KBPS2;
145-
TRM_SetStatusIcon(ICO_KB_OK, ICO_POS_0);
146-
bNoKeyboard = FALSE;
147-
break;
148-
}
135+
if ( DevId0 == DEVICE_UNKNOWN) {ps2_r = KB_PS2_Init(DP_Port1);}
136+
if ((DevId1 == DEVICE_UNKNOWN) && !ps2_r) {ps2_r = KB_PS2_Init(DP_Port2);}
137+
if ((DevId2 == DEVICE_UNKNOWN) && !ps2_r) {ps2_r = KB_PS2_Init(DP_Port3);}
138+
139+
if (ps2_r)
140+
{
141+
DevList[DevSeq++] = &DRV_KBPS2;
142+
TRM_SetStatusIcon(ICO_KB_OK, ICO_POS_0);
143+
bNoKeyboard = FALSE;
149144
}
150145

151146
// -- Saturn Keyboard setup ------------------------
@@ -198,11 +193,11 @@ void DetectDevices()
198193
char SEGASTR[5] = {0, 0, 0, 0, 0};
199194
memcpyU32((u32*)SEGASTR, (u32*)0x400100, 1);
200195
201-
//stdout_printf("SEGASTR= \"%s\" -- SCDver= %u\n%c %c %c %c\n", SEGASTR, SCDver, *((vu8*) 0x400100), *((vu8*) 0x400101), *((vu8*) 0x400102), *((vu8*) 0x400103));
196+
//printf("SEGASTR= \"%s\" -- SCDver= %u\n%c %c %c %c\n", SEGASTR, SCDver, *((vu8*) 0x400100), *((vu8*) 0x400101), *((vu8*) 0x400102), *((vu8*) 0x400103));
202197
203198
if ((SCDver) || (strcmp(SEGASTR, "SEGA") == 0))
204199
{
205-
stdout_printf("%s CD found.\n", bPALSystem ? "SEGA" : "MEGA");
200+
printf("%s CD found.\n", bPALSystem ? "SEGA" : "MEGA");
206201
bMegaCD = TRUE;
207202
}*/
208203

@@ -269,6 +264,9 @@ void DetectDevices()
269264

270265
Stdout_Push("├No network adapters found\n");
271266
Stdout_Push("└Listening on built in UART\n");
267+
268+
TRM_SetStatusIcon(ICO_NET_ERROR, ICO_POS_1);
269+
TRM_SetStatusIcon(ICO_NET_ERROR, ICO_POS_2);
272270
}
273271
}
274272

src/DevMgr.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ typedef struct s_device
5555

5656
#define DEV_PORT ((s >> 1)+1)
5757
#define DEV_SLOT(device) (device.Id.Bitshift >> 1)
58-
#define DEV_FULL(device) DEV_PORT, DEV_SLOT(device)
5958

6059
#define DEV_MASK_SHIFT(d) (d.Id.Bitmask << d.Id.Bitshift) // Helper macro to get the shifted mask
6160
#define DEV_MASK_AND_SHIFT(d, b) ((b & d.Id.Bitmask) << d.Id.Bitshift) // Helper macro to apply the mask and shift to a value 'b'

src/FavView.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static const char *tab_text[3] =
2828

2929
static char *list_telnet[] =
3030
{
31-
"alt.org:23", "telehack.com:23", "bbs.bottomlessabyss.net:2023", "bbs.kd3.us:23"
31+
"alt.org:23", "telehack.com:23", "bbs.bottomlessabyss.net:2023"
3232
};
3333

3434
static char *list_irc[] =

src/HexView.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ void HexView_Open(const char *filename)
161161
{
162162
strcpy(WinTitle, "HexView - Stdout");
163163

164-
bufptr = (char*)stdout.data;
164+
bufptr = (char*)StdoutBuffer.data;
165165
bufsize = BUFFER_LEN;
166166
bIOFILE = TRUE;
167167
}
@@ -170,7 +170,7 @@ void HexView_Open(const char *filename)
170170
SM_File *f = F_Open(fn_buf, FM_RDONLY);
171171
if (f == NULL)
172172
{
173-
stdout_printf("Failed to open file \"%s\"\n", filename);
173+
printf("Failed to open file \"%s\"\n", filename);
174174
return;
175175
}
176176

@@ -180,7 +180,7 @@ void HexView_Open(const char *filename)
180180
bufptr = (char*)malloc(bufsize+1);
181181
if (bufptr == NULL)
182182
{
183-
stdout_printf("Failed to allocate buffer\n");
183+
printf("Failed to allocate buffer\n");
184184
F_Close(f);
185185
return;
186186
}

0 commit comments

Comments
 (0)