Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
specasm: Add clipboard support on the Next
On the Next the commands 'x', 'cc' and 'v', cut, copy and
paste to and from a clipboard.  This is much less clunky than
the existing move and copy mechanism and allows you to copy
code between different files for the first time.  The 'x'
command can also be used in selecting mode to cut the visibly
selected text to the clipboard.

Also fix a small UI issue when the original copy command fails
due to lack of space in the current file.

Signed-off-by: Mark Ryan <[email protected]>
  • Loading branch information
markdryan committed Mar 10, 2024
commit 1e2c017c588d0a9642288e30f839bee47fec9739
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ COMMON =\
line_common.c

SRCS =\
clipboard.c \
editor.c \
editor_tests.c \
editor_test_content.c \
Expand Down
1 change: 1 addition & 0 deletions build/next/specasm/Make.include
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ peer_file_next.o: peer_file_next.c error.h peer_file.h
util_print_next.o: util_print_next.c util_print_zx.h
samake.o: samake.c peer.h error.h peer_zx.h line.h \
salink.h peer_file.h state_base.h strings.h
clipboard_banked.o: clipboard.c clipboard.h line.h error.h

%.o: %.c
zcc $(CFLAGS) -o $@ -c $<
4 changes: 4 additions & 0 deletions build/next/specasm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ line_dump_banked.o: line_dump.c
ld_parse_banked.o: ld_parse.c
$(CC) $(CFLAGS) -DSPECASM_NEXT_BANKED -o $@ --codesegBANK_45_H --constsegBANK_45_H --datasegBANK_45_H -c $<

clipboard_banked.o: clipboard.c
$(CC) $(CFLAGS) -DSPECASM_NEXT_BANKED -o $@ --codesegBANK_46_H --constsegBANK_46_H --datasegBANK_46_H -c $<

expression_banked.o: expression.c
$(CC) $(CFLAGS) -DSPECASM_NEXT_BANKED -o $@ --codesegBANK_43_H --constsegBANK_43_H --datasegBANK_43_H -c $<

Expand All @@ -30,6 +33,7 @@ include Make.include
SPECASM = \
specasm_next.o \
specasm_trampolines.o \
clipboard_banked.o \
line_common.o \
ld_parse_banked.o \
line_dump_banked.o \
Expand Down
1 change: 1 addition & 0 deletions build/next/unit/Make.include
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ peer_file_next.o: peer_file_next.c error.h peer_file.h
util_print_next.o: util_print_next.c util_print_zx.h
samake.o: samake.c peer.h error.h peer_zx.h line.h \
salink.h peer_file.h state_base.h strings.h
clipboard_banked.o: clipboard.c clipboard.h line.h error.h

unittests_zx.o: ../src/unittests_zx.c ../src/error.h ../src/line.h \
../src/state.h ../src/state_base.h ../src/strings.h ../src/test_content.h ../src/test_content_zx.h \
Expand Down
4 changes: 4 additions & 0 deletions build/next/unit/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ line_dump_banked.o: line_dump.c
ld_parse_banked.o: ld_parse.c
$(CC) $(CFLAGS) -DSPECASM_NEXT_BANKED -o $@ --codesegBANK_45_H --constsegBANK_45_H --datasegBANK_45_H -c $<

clipboard_banked.o: clipboard.c
$(CC) $(CFLAGS) -DSPECASM_NEXT_BANKED -o $@ --codesegBANK_46_H --constsegBANK_46_H --datasegBANK_46_H -c $<

include Make.include

UNITNEXT = \
error.o \
state_base.o \
specasm_trampolines.o \
line_common.o \
clipboard_banked.o \
ld_parse_banked.o \
line_dump_banked.o \
line_dump_common.o \
Expand Down
12 changes: 10 additions & 2 deletions docs/specasm.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,19 @@ On entering command mode, a '>' prompt appears at the bottom of the screen. Fro
| g *line number* | Moves the cursor to the specified line number|
| f *string* | Searches for the first instance of *string* starting from the current line. There's no wrap around. |

The Next version of Specasm uses one of the Next's 8Kb memory banks to implement a clipboard. This provides a more traditional copy, cut and paste mechanism than the copy and move commands described above, and allows code to be copied from one file to another. Clipboard support is provided via three new Next specific commands.

| Command | Description |
|---------|-------------|
| x | Replaces the contents of the clipboard with the selected code and deletes the code from the current file |
| cc | Replaces the contents of the clipboard with the selected code |
| v | Pastes the contents of the clipboard into the selected code at the cursor position |

#### Selecting Mode

The *sel* command switches the editor into selection mode. In selection mode the user can press the up and down keys to select a block of code. They can also press the 'a' key to select the entire file. Only whole lines can be selected. To cancel the selection and return to editor mode, press SPACE. To delete the selected lines and return to editor mode, press DELETE. To confirm the selection and return to editor mode, press ENTER. Once the selection has been confirmed an '*' will appear in the status row at the bottom of the screen to the right of 'INS' or 'OVR'. This indicates that some lines are currently selected. These lines can be manipulated using the 'd', 'm', 'c' and 'b' commands described above. For example, to count the number of machine code bytes in the selected line, type SYMSHIFT+w followed by 'b' and ENTER. The editor is capable of computing the exact size in bytes of the machine code associated with the instructions and data in the selected region as it has already assembled these instructions and knows exactly how much space they will consume.
The *sel* command switches the editor into selection mode. In selection mode the user can press the up and down keys to select a block of code. They can also press the 'a' key to select the entire file. Only whole lines can be selected. To cancel the selection and return to editor mode, press SPACE. To delete the selected lines and return to editor mode, press DELETE. On the Next, the selected lines may be cut to the clipboard by typing 'x'. To confirm the selection and return to editor mode, press ENTER. Once the selection has been confirmed an '*' will appear in the status row at the bottom of the screen to the right of 'INS' or 'OVR'. This indicates that some lines are currently selected. These lines can be manipulated using the 'd', 'm', 'c','b', 'x' and 'cc' commands described above. For example, to count the number of machine code bytes in the selected line, type SYMSHIFT+w followed by 'b' and ENTER. The editor is capable of computing the exact size in bytes of the machine code associated with the instructions and data in the selected region as it has already assembled these instructions and knows exactly how much space they will consume.

All of the four commands that manipulate selections, cancel the selection once they have finished executing. So if you select a block of text, and then issue the 'b' command to count the number of bytes it consumes, you'll need to reselect the text once more to copy it. In addition, the current selection is cancelled if you make any changes to the contents of the editor, e.g., edit an existing line or insert a new one.
All of the six commands that manipulate selections, cancel the selection once they have finished executing. So if you select a block of text, and then issue the 'b' command to count the number of bytes it consumes, you'll need to reselect the text once more to copy it. In addition, the current selection is cancelled if you make any changes to the contents of the editor, e.g., edit an existing line or insert a new one.

#### The Status Row

Expand Down
113 changes: 113 additions & 0 deletions src/clipboard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright contributors to Specasm
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifdef SPECASM_TARGET_NEXT_OPCODES

#include <stdlib.h>
#include <string.h>

#include "clipboard.h"
#include "line.h"

#define SPECASM_CLIP_MAX_SIZE (15 * 512)

static uint8_t clip_buffer[SPECASM_CLIP_MAX_SIZE];

static uint16_t clip_end_ptr;
static uint16_t clip_lines;

#ifdef SPECASM_NEXT_BANKED
void specasm_clip_reset_banked(void)
#else
void specasm_clip_reset(void)
#endif
{
clip_end_ptr = 0;
clip_lines = 0;
}

#ifdef SPECASM_NEXT_BANKED
void specasm_clip_add_line_banked_e(const char *line)
#else
void specasm_clip_add_line_e(const char *line)
#endif
{
uint8_t len;
const char* end_ptr;

/*
* Skip leading and trailing white space. We don't need to store this.
*/

end_ptr = &line[SPECASM_LINE_MAX_LEN - 1];
while ((end_ptr >= line) && (*end_ptr == ' '))
end_ptr--;
end_ptr++;

if (line == end_ptr) {
clip_buffer[clip_end_ptr++] = 0;
} else {
while (*line == ' ') line++;

len = end_ptr - line;
if (len + clip_end_ptr >= SPECASM_CLIP_MAX_SIZE) {
err_type = SPECASM_ERROR_TOO_MANY_LINES;
return;
}

clip_buffer[clip_end_ptr++] = len;
memcpy(&clip_buffer[clip_end_ptr], line, len);
clip_end_ptr += len;
}
clip_lines++;
}

#ifdef SPECASM_NEXT_BANKED
uint16_t specasm_clip_get_line_banked(uint16_t ptr, char *buffer)
#else
uint16_t specasm_clip_get_line(uint16_t ptr, char *buffer)
#endif
{
uint8_t len;
uint8_t spaces;

if (ptr >= clip_end_ptr)
return 0;

len = clip_buffer[ptr++];
if (len > 0) {
memcpy(buffer, &clip_buffer[ptr], len);
ptr += len;
}

spaces = SPECASM_LINE_MAX_LEN - len;
if (spaces > 0)
memset(&buffer[len], ' ', spaces);
buffer[len + spaces] = 0;

return ptr;
}

#ifdef SPECASM_NEXT_BANKED
uint16_t specasm_clip_get_line_count_banked(void)
#else
uint16_t specasm_clip_get_line_count(void)
#endif
{
return clip_lines;
}

#endif
27 changes: 27 additions & 0 deletions src/clipboard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright contributors to Specasm
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef CLIPBOARD_H
#define CLIPBOARD_H

#include <stdint.h>

void specasm_clip_reset(void);
void specasm_clip_add_line_e(const char *line);
uint16_t specasm_clip_get_line(uint16_t ptr, char *buffer);
uint16_t specasm_clip_get_line_count(void);

#endif
Loading