Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 965c947
Showing
22 changed files
with
1,799 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Valence 64 - The input-only VNC client for the Commodore 64. | ||
* | ||
* Copyright 2012 David Simmons | ||
* http://cafbit.com/ | ||
* | ||
* 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. | ||
*/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
all: valence64.prg setup.prg hello.prg vncclient/vncclient.c64 combined.prg disk | ||
|
||
clean: | ||
$(MAKE) TARGET=c64 -C vncclient sterile | ||
rm -f valence64.prg | ||
rm -f combined.prg | ||
rm -f setup.prg | ||
rm -f valence64.d64 | ||
rm -f hello.o hello.prg | ||
|
||
vncclient/vncclient.c64: | ||
$(MAKE) TARGET=c64 -C vncclient build | ||
|
||
combined.prg: valence64.prg vncclient/vncclient.c64 | ||
./combine.pl valence64.prg vncclient/vncclient.c64 vncclient/contiki-c64.map > combined.prg | ||
|
||
%.o: %.asm | ||
ca65 -o $@ $< | ||
|
||
%.prg: %.o %.cfg | ||
ld65 -C $(lastword $^) -o $@ $< | ||
|
||
%.prg: %.bas | ||
petcat -c -w2 -o $@ -- $< | ||
|
||
disk: | ||
c1541 -format valence64,00 d64 valence64.d64 | ||
c1541 -attach valence64.d64 -write combined.prg valence64,p | ||
c1541 -attach valence64.d64 -write setup.prg setup,p | ||
c1541 -attach valence64.d64 -write assets/contiki.cfg contiki.cfg,u | ||
c1541 -attach valence64.d64 -write assets/valence.cfg valence.cfg,u | ||
c1541 -attach valence64.d64 -write vncclient/cs8900a.eth cs8900a.eth,u | ||
c1541 -attach valence64.d64 -write vncclient/lan91c96.eth lan91c96.eth,u | ||
#./randomizesrcport.pl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
|
||
Valence64: The input-only VNC client for the Commodore 64 | ||
====================================================================== | ||
|
||
(c) 2012 David Simmons | ||
Licensed under the Apache License, Version 2.0 | ||
|
||
http://cafbit.com/entry/valence64 | ||
|
||
Valence64 is a simple proof-of-concept application for controlling a | ||
remote computer using a networked Commodore 64. It was developed as | ||
a way for me to learn the Contiki framework and the uIP TCP/IP stack, | ||
both of which are used in actual modern-day embedded systems. | ||
|
||
|
||
Using Valence64 | ||
---------------------------------------- | ||
|
||
The easiest way to use Valence64 is to obtain a prebuilt version of the | ||
valence.d64 disk image from the above web site. Attach the disk image | ||
to your C64 emulator, or write the image to a 1541 5.25" disk for use on | ||
an actual C64. | ||
|
||
Run the SETUP program to configure your TCP/IP settings, select an | ||
ethernet driver, and indicate the VNC server address of the host you | ||
want to control: | ||
|
||
LOAD "SETUP",8 | ||
RUN | ||
|
||
Then, load and run Valence64: | ||
|
||
LOAD "VALENCE64",8 | ||
RUN | ||
|
||
Press F1 to connect to the VNC server. By default, the program is in | ||
"mouse mode" -- CRSR keys will be used to move the mouse, and RETURN | ||
will send a mouse click. Press F7 to toggle "keyboard mode" for typing. | ||
A joystick in control port 2 can also be used to operate the mouse | ||
pointer. | ||
|
||
|
||
Building Valence64 | ||
---------------------------------------- | ||
|
||
Requirements: | ||
Linux development machine. | ||
(It could be made to work with other platforms.) | ||
Contiki 2.5 | ||
The cc65 compiler/assembler (cc65-c64-2.13.2-1) | ||
|
||
You must have a copy of the Contiki 2.5 source code located in the | ||
../contiki-2.5 directory relative to the root of the Valence64 source. | ||
Patch the Contiki source with the supplied contiki-2.5-autostart.patch | ||
file: | ||
|
||
$ cd ../contiki-2.5 | ||
$ patch -p1 < ../valence64/contiki-2.5-autostart.patch | ||
|
||
If you want to use my randomizesrcport.pl script to randomize the | ||
initial source port number (which is useful during development), then | ||
also apply this patch (and uncomment ./randomizesrcport.pl from the disk | ||
target of the Makefile): | ||
|
||
$ patch -p1 < ../valence64/contiki-2.5-randomsrcport.patch | ||
|
||
You must also have the cc65 compiler/assembler package installed in | ||
/usr/local/bin. (Or edit the CC65_HOME value in vncclient/Makefile to | ||
point to the location.) | ||
|
||
Type "make". | ||
|
||
|
||
Build concept | ||
---------------------------------------- | ||
|
||
Valence64 uses a somewhat convoluted process to produce the final | ||
product, due to it being a BASIC/ML hybrid program. In the final | ||
output, the binary 6502 executable code ("ML code") is appended to the | ||
end of the BASIC program, and launched from BASIC via a SYS call. This | ||
poses several challenges: | ||
|
||
1. The ML link step needs knowledge of the final memory location of the | ||
program for proper linking. This location will change every time the | ||
BASIC program is modified, since the starting address will be at the end | ||
of the BASIC code. | ||
2. The BASIC program doesn't know the memory locations to SYS until the | ||
ML code is compiled/assembled/linked. | ||
|
||
To work around this, I use scripts for post-processing. This allows the | ||
BASIC program to SYS with placeholder addresses, which are filled in | ||
based on the symbol table used by the linker. During linking, which | ||
happens after the BASIC program has been rendered into a tight PRG file, | ||
a script inspects the PRG file and determines the ML starting address. | ||
A linker configuration is dynamically built from this information using | ||
a template. | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
��� |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#!/usr/bin/perl | ||
###################################################################### | ||
# | ||
# combine | ||
# | ||
# Merge a BASIC program and a 6502 machine language program into one | ||
# file for convenience and fast loading. The ML code should be linked | ||
# for a starting address just after the end of the BASIC program. | ||
# | ||
# (c) 2012 David Simmons | ||
# | ||
# usage: combine.pl basicprogram.prg mlprog.prg > combinedprog.prg | ||
# | ||
###################################################################### | ||
|
||
use strict; | ||
use warnings; | ||
use bytes; | ||
|
||
if (@ARGV < 2) { | ||
die "usage: combine.pl basicprogram.prg mlprog.prg [symbol.map]\n"; | ||
} | ||
|
||
my ($bas, $ml); | ||
|
||
# read BASIC file | ||
open(BAS, $ARGV[0]) || die "cannot open basic file: $!\n"; | ||
{ | ||
local $/; | ||
$bas = <BAS>; | ||
} | ||
close(BAS); | ||
|
||
# read ML file | ||
open(ML, $ARGV[1]) || die "cannot open ml file: $!\n"; | ||
{ | ||
local $/; | ||
$ml = <ML>; | ||
} | ||
close(ML); | ||
|
||
# read symbol table, if available | ||
my $exports; | ||
if (@ARGV >= 3) { | ||
my $in = 0; | ||
open(MAP, $ARGV[2]) || die "cannot open symbol map: $!\n"; | ||
while (<MAP>) { | ||
chomp; | ||
if (/^Exports list:$/) { | ||
$in = 1; next; | ||
} | ||
if ($in) { | ||
if (/^$/) { | ||
$in = 0; next; | ||
} | ||
if (/^\s*(\S+)\s+(\S+)\s+\S+\s+(\S+)\s+(\S+)\s+\S+\s*$/) { | ||
$exports->{$1} = hex($2); | ||
$exports->{$3} = hex($4); | ||
} elsif (/^\s*(\S+)\s+(\S+)\s+\S+\s*$/) { | ||
$exports->{$1} = hex($2); | ||
} | ||
} | ||
|
||
} | ||
close(MAP); | ||
} | ||
|
||
my $jumpaddr = sprintf("%05d", 0x7FF+length($bas)); | ||
|
||
# write the actual jump addresses into the basic program, | ||
# replacing the placeholder 'SYS "symbol"' calls. | ||
sub translate { | ||
my $symbol = shift; | ||
my $address; | ||
if ($symbol eq 'JUMPSTART') { | ||
$address = $jumpaddr; | ||
} else { | ||
$address = $exports->{lc $symbol}; | ||
} | ||
printf(STDERR "TRANSLATE $symbol -> $address\n"); | ||
return $address; | ||
} | ||
my $l1 = bytes::length($bas); | ||
$bas =~ s/\x9e "(\S+)"(.*?)\x00/sprintf("\x9e %d%s\x00",&translate($1),$2)/ge; | ||
my $l2 = length($bas); | ||
if ($l1 < $l2) { | ||
die "symbol name substitution made the program larger\n"; | ||
} elsif ($l1 > $l2) { | ||
# apply padding | ||
#printf STDERR "PADDING: ".($l1-$l2)."\n"; | ||
$bas .= ("\xff" x ($l1-$l2)); | ||
} | ||
|
||
# trim the first 14 bytes from the ML file. This contains | ||
# the 2-byte starting address, and 12 bytes of needless | ||
# BASIC bootstrap code. | ||
$ml = substr($ml,14); | ||
|
||
# while we're here, hack out the cc65 runtime's annoying | ||
# shift to the upper/lowercase character set | ||
$ml =~ s/\xa9\x0e\x20\xd2\xff/\xa9\x8e\x20\xd2\xff/g; | ||
|
||
# combine and deliver to stdout | ||
print $bas; | ||
print $ml; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
diff -Nru contiki-2.5.orig/platform/c64/contiki-main.c contiki-2.5/platform/c64/contiki-main.c | ||
--- contiki-2.5.orig/platform/c64/contiki-main.c 2011-09-06 15:43:39.000000000 -0600 | ||
+++ contiki-2.5/platform/c64/contiki-main.c 2012-02-13 00:40:44.171722661 -0700 | ||
@@ -63,6 +63,7 @@ | ||
main(void) | ||
{ | ||
struct ethernet_config *ethernet_config; | ||
+ struct process *vncclient_process = NULL; | ||
|
||
process_init(); | ||
|
||
@@ -120,6 +121,26 @@ | ||
process_run(); | ||
|
||
etimer_request_poll(); | ||
+ | ||
+ if (! vncclient_process) { | ||
+ // look for vncclient | ||
+ struct process *q; | ||
+ for (q = PROCESS_LIST(); q != NULL; q = q->next) { | ||
+ if (strcmp(q->name, "vncclient")==0) { | ||
+ vncclient_process = q; | ||
+ break; | ||
+ } | ||
+ } | ||
+ } else { | ||
+ struct process *q; | ||
+ for (q = PROCESS_LIST(); q != vncclient_process && q != NULL; q = q->next); | ||
+ if (q == NULL) { | ||
+ // time to leave | ||
+ break; | ||
+ } | ||
+ } | ||
+ | ||
+ | ||
} | ||
} | ||
/*-----------------------------------------------------------------------------------*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- contiki-2.5.orig/core/net/uip.c 2011-09-06 15:43:39.000000000 -0600 | ||
+++ contiki-2.5/core/net/uip.c 2012-02-15 23:15:18.413803065 -0700 | ||
@@ -377,7 +377,12 @@ | ||
uip_conns[c].tcpstateflags = UIP_CLOSED; | ||
} | ||
#if UIP_ACTIVE_OPEN || UIP_UDP | ||
- lastport = 1024; | ||
+ | ||
+{ | ||
+ // simmons-hack: marker for initial source-port | ||
+ u16_t x[5] = {0xdead, 0xbeef, 0x0000, 0xdead, 0xbeef}; | ||
+ lastport = 1024 + x[2]; | ||
+} | ||
#endif /* UIP_ACTIVE_OPEN || UIP_UDP */ | ||
|
||
#if UIP_UDP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
|
||
;set up some helpful labels | ||
CLEAR = $E544 | ||
CHROUT = $FFD2 | ||
|
||
.segment "BASICSTUB" | ||
|
||
.byte $00 | ||
.byte $C0 | ||
|
||
.code | ||
main: | ||
jsr CLEAR | ||
ldx #0 | ||
loop: | ||
lda greeting,x | ||
cmp #0 | ||
beq finish | ||
jsr CHROUT | ||
inx | ||
jmp loop | ||
finish: | ||
rts | ||
|
||
.data | ||
greeting: | ||
.byte "HELLO, WORLD!" | ||
.byte $00 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
MEMORY { | ||
RAM: start = $BFFE, size = $1002, file = %O, define = yes; | ||
} | ||
SEGMENTS { | ||
BASICSTUB: load = RAM, type = ro; | ||
CODE: load = RAM, type = ro; | ||
DATA: load = RAM, type = rw; | ||
} |
Oops, something went wrong.