Compare commits

...

19 Commits

Author SHA1 Message Date
Bobbi Webber-Manners
9fdedd46bb Fix copy/paste typo. 2022-09-28 23:45:16 -04:00
Bobbi Webber-Manners
9fa090f34d Release 2.1.14. Migrated to latest IP65 version. 2022-09-14 16:23:13 -04:00
Bobbi Webber-Manners
95615458aa Rebased on latest IP65. Needs latest CC65 to build. 2022-09-14 13:02:41 -04:00
Bobbi Webber-Manners
d8d532fd72 Bump up version number to 2.1.14 2022-09-13 20:13:21 -04:00
Bobbi Webber-Manners
7c402facc7 attacher.c: Turn off optimizer for inline asm. 2022-09-13 20:08:50 -04:00
Bobbi Webber-Manners
7bb47d4b85 email.c: Turn off optimizer for inline asm 2022-09-13 20:05:12 -04:00
Bobbi Webber-Manners
d015ca310c
README-gmail-gateway.md: add line to force IPv4 2022-09-04 20:19:21 -04:00
Bobbi Webber-Manners
e102d732b0
Update README-gmail-gateway.md to add libsasl2-modules package 2022-09-04 20:17:02 -04:00
Bobbi Webber-Manners
6106701fa8 Added 2.1.13 disk image. 2021-11-16 15:15:11 -05:00
Bobbi Webber-Manners
077bddc9f1 Bump upversion to 2.1.13. 2021-11-16 15:03:32 -05:00
Bobbi Webber-Manners
e123dc2dbc NNTP65: Change to way filename to delete is computed. 2021-11-16 15:03:11 -05:00
Bobbi Webber-Manners
675073a6c9 SMTP65/NNTP65.UP: Stop looking for headers on finding blank line 2021-11-16 15:02:03 -05:00
Bobbi Webber-Manners
4e482b14cb Fixed memory exhaustion bug in EMAIL.SYSTEM. 2021-11-14 20:13:18 -05:00
Bobbi Webber-Manners
ef07cc8b88 2.1.11 release. 2021-11-13 13:12:12 -05:00
Bobbi Webber-Manners
c2b4773e1c Improved tagged message prompt. Allow OA-/ for help. 2021-11-13 13:11:08 -05:00
Bobbi Webber-Manners
305c7bcf34 Fix to REBUILD.SYSTEM to handle empty email dirs. 2021-11-12 22:26:45 -05:00
Bobbi Webber-Manners
6e9c751f53 Fixed 2.1.9 release, which was generated incorrectly! 2021-11-12 17:10:02 -05:00
Bobbi Webber-Manners
6613ec218c Added missing releases to 'releases' dir. 2021-11-12 17:04:24 -05:00
Bobbi Webber-Manners
44c46943b0 Rebuild: Initialize max/min email number. 2021-11-12 16:56:22 -05:00
43 changed files with 357 additions and 297 deletions

View File

@ -82,7 +82,7 @@ Install the packages with root privs on the Pi:
```
sudo apt update
sudo apt upgrade
sudo apt install postfix postfix-pcre
sudo apt install postfix postfix-pcre libsasl2-modules
sudo apt install dovecot-common dovecot-pop3d
sudo apt install fetchmail
```
@ -134,7 +134,7 @@ We will modify a number of configuration files:
- `/etc/postfix/sasl/sasl_passwd`
- `/etc/postfix/sasl/sasl_passwd.db`
Once Dovecot has been configured, the service may be controlled as follows:
Once Postfix has been configured, the service may be controlled as follows:
- `systemctl start postfix` - start service.
- `systemctl stop postfix` - stop service.
- `systemctl status postfix` - status of service.
@ -179,6 +179,10 @@ My home network is 192.168.10.0/24, so I added it here:
`mynetworks = 192.168.10.0/24 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128`.
You should adjust this line to match your own LAN subnet.
I had an issue where the Pi was unable to connect to Google's SMTP server.
It turned out it was trying to use IPv6, so I forced IPv4 as follows:
`inet_protocols = ipv4`
Finally I added the following block of settings to enabled SASL authentication
when talking to Gmail:
@ -245,7 +249,7 @@ mynetworks = 192.168.10.0/24 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all
inet_protocols = ipv4
# Enable SASL authentication
smtp_sasl_auth_enable = yes

View File

@ -397,14 +397,10 @@ void file_ui_draw_all(uint16_t first, uint16_t selected, uint16_t entries) {
}
/*
* Perform ProDOS MLI ON_LINE call to
* write all online volume names into iobuf[]
* Return the number of entries
* Asm code for online()
*/
uint16_t online(void) {
uint16_t entries = 0;
struct tabent *entry;
uint8_t i, j, len;
#pragma optimize (push, off)
void onlineasm(void) {
__asm__("lda #$00"); // All devices
__asm__("sta mliparam + 1");
__asm__("lda #<%v", iobuf); // iobuf LSB
@ -415,6 +411,19 @@ uint16_t online(void) {
__asm__("lda #$c5"); // ON_LINE
__asm__("ldx #$02"); // Two parms
__asm__("jsr callmli");
}
#pragma optimize (pop)
/*
* Perform ProDOS MLI ON_LINE call to
* write all online volume names into iobuf[]
* Return the number of entries
*/
uint16_t online(void) {
uint16_t entries = 0;
struct tabent *entry;
uint8_t i, j, len;
onlineasm();
entry = (struct tabent*)iobuf;
for (i = 0; i < 16; ++i) {
len = iobuf[256 + i * 16] & 0x0f;

View File

@ -2638,6 +2638,7 @@ int edit(char *fname) {
}
break;
case 0x80 + '?': // OA-? "Help"
case 0x80 + '/': // OA-/ "Help"
help1:
help(1);
c = cgetc();

View File

@ -22,8 +22,9 @@
// Program constants
#define MSGS_PER_PAGE 19 // Number of messages shown on summary screen
#define PROMPT_ROW 24 // Row that data entry prompt appears on
#define LINEBUFSZ 1000 // According to RFC2822 Section 2.1.1 (998+CRLF)
#define READSZ 512 // Size of buffer for copying files
#define LINEBUFSZ 1024 // Max line 1000 according to RFC2822 Sect 2.1.1
// We use 1024 because this is also used for scrollback
// Characters
#define BELL 0x07
@ -88,8 +89,7 @@ struct datetime {
static char filename[80];
static char userentry[80];
static char linebuf[LINEBUFSZ];
static char halfscreen[0x0400];
static uint8_t linebuf[LINEBUFSZ];
static FILE *fp;
static struct emailhdrs *headers;
static uint16_t selection = 1;
@ -925,6 +925,21 @@ void sanitize_filename(char *s) {
enum aux_ops {FROMAUX, TOAUX};
/*
* Asm code for copyaux()
*/
#pragma optimize (push, off)
void copyauxasm(enum aux_ops dir) {
if (dir == TOAUX)
__asm__("sec"); // Copy main->aux
else
__asm__("clc"); // Copy aux->main
__asm__("sta $c000"); // Turn off 80STORE
__asm__("jsr $c311"); // AUXMOVE
__asm__("sta $c001"); // Turn on 80STORE
}
#pragma optimize (pop)
/*
* Aux memory copy routine
*/
@ -935,54 +950,58 @@ void copyaux(char *src, char *dst, uint16_t len, enum aux_ops dir) {
*a1 = src;
*a2 = src + len - 1; // AUXMOVE moves length+1 bytes!!
*a4 = dst;
if (dir == TOAUX)
__asm__("sec"); // Copy main->aux
else
__asm__("clc"); // Copy aux->main
__asm__("sta $c000"); // Turn off 80STORE
__asm__("jsr $c311"); // AUXMOVE
__asm__("sta $c001"); // Turn on 80STORE
copyauxasm(dir);
}
/*
* Save the current screen to the scrollback file
* We preserve linebuf[] by copying it to aux 0x0800, and recover
* it at the end. This saves us having an additional 1KB buffer.
*/
void save_screen_to_scrollback(FILE *fp) {
copyaux(linebuf, (void*)0x800, 1024, TOAUX); // Preserve linebuf[]
if (fwrite((void*)0x0400, 0x0400, 1, fp) != 1) { // Even cols
error(ERR_NONFATAL, sb_err);
return;
goto done;
}
copyaux((void*)0x400, halfscreen, 0x400, FROMAUX);
if (fwrite(halfscreen, 0x0400, 1, fp) != 1) { // Odd cols
copyaux((void*)0x400, linebuf, 0x400, FROMAUX);
if (fwrite(linebuf, 0x0400, 1, fp) != 1) { // Odd cols
error(ERR_NONFATAL, sb_err);
return;
goto done;
}
done:
copyaux((void*)0x800, linebuf, 1024, FROMAUX); // Recover linebuf[]
}
/*
* Load a screen from the scrollback file
* Screens are numbered 1, 2, 3 ...
* Does not trash the screen holes, which must be preserved!
* We preserve linebuf[] by copying it to aux 0x0800, and recover
* it at the end. This saves us having an additional 1KB buffer.
*/
void load_screen_from_scrollback(FILE *fp, uint8_t screen) {
uint8_t i;
copyaux(linebuf, (void*)0x800, 1024, TOAUX); // Preserve linebuf[]
if (fseek(fp, (screen - 1) * 0x0800, SEEK_SET) ||
(fread(halfscreen, 0x0400, 1, fp) != 1)) { // Even cols
(fread(linebuf, 0x0400, 1, fp) != 1)) { // Even cols
error(ERR_NONFATAL, sb_err);
return;
goto done;
}
for (i = 0; i < 8; ++i)
memcpy((char*)0x400 + i * 0x80, halfscreen + i * 0x80, 0x078);
if (fread(halfscreen, 0x0400, 1, fp) != 1) { // Odd cols
memcpy((char*)0x400 + i * 0x80, linebuf + i * 0x80, 0x078);
if (fread(linebuf, 0x0400, 1, fp) != 1) { // Odd cols
error(ERR_NONFATAL, sb_err);
return;
goto done;
}
for (i = 0; i < 8; ++i)
copyaux(halfscreen + i * 0x80, (char*)0x400 + i * 0x80, 0x078, TOAUX);
copyaux(linebuf + i * 0x80, (char*)0x400 + i * 0x80, 0x078, TOAUX);
if (fseek(fp, 0, SEEK_END)) {
error(ERR_NONFATAL, sb_err);
return;
goto done;
}
done:
copyaux((void*)0x800, linebuf, 1024, FROMAUX); // Recover linebuf[]
}
/*
@ -1777,7 +1796,7 @@ char prompt_okay(char *msg) {
*/
void get_email_body(struct emailhdrs *h, FILE *f, char mode) {
uint16_t chars;
char c, *readp, *writep;
uint8_t c, *readp, *writep;
uint32_t pos = 0;
const int8_t *b = b64dec - 43;
uint8_t mime = 0, mime_enc = ENC_7BIT, mime_binary, mime_hasfile;
@ -2044,7 +2063,7 @@ uint16_t get_db_index(void) {
* on the current message. If they are, prompt the user and, if affirmative,
* iterate through the tagged messages calling copy_to_mailbox() on each.
*/
uint8_t copy_to_mailbox_tagged(char *mbox, uint8_t delete) {
uint8_t copy_to_mailbox_tagged(char *mbox, char mode, uint8_t delete) {
uint16_t count = 0, tagcount = 0;
struct emailhdrs *h;
uint16_t l;
@ -2053,7 +2072,8 @@ uint8_t copy_to_mailbox_tagged(char *mbox, uint8_t delete) {
copy_to_mailbox(h, get_db_index(), mbox, delete, ' ');
return 0;
}
snprintf(filename, 80, "%u tagged - ", total_tag);
snprintf(filename, 80, "%s %u tagged - ",
(mode == 'C' ? "Copy" : (mode == 'M' ? "Move" : "Archive")), total_tag);
if (!prompt_okay(filename))
return 0;
h = (struct emailhdrs*)malloc(sizeof(struct emailhdrs));
@ -2333,7 +2353,7 @@ void keyboard_hdlr(void) {
if (h) {
c = prompt_for_name("Copy to mbox", 1);
if ((c != 0) && (c != 255))
copy_to_mailbox_tagged(userentry, 0);
copy_to_mailbox_tagged(userentry, 'C', 0);
}
break;
case 'm':
@ -2341,14 +2361,14 @@ void keyboard_hdlr(void) {
if (h) {
c = prompt_for_name("Move to mbox", 1);
if ((c != 0) && (c != 255))
copy_to_mailbox_tagged(userentry, 1);
copy_to_mailbox_tagged(userentry, 'M', 1);
}
break;
case 'a':
case 'A':
if (h) {
goto_prompt_row();
copy_to_mailbox_tagged("RECEIVED", 1);
copy_to_mailbox_tagged("RECEIVED", 'A', 1);
}
break;
case 'p':
@ -2421,6 +2441,7 @@ void keyboard_hdlr(void) {
load_app(APP_SMTP);
break;
case 0x80 + '?': // OA-? "Help"
case 0x80 + '/': // OA-/ "Help"
help(1);
c = cgetc();
email_summary();

View File

@ -6,7 +6,7 @@
#include <stdint.h>
#define PROGNAME "emai//er v2.1.8"
#define PROGNAME "emai//er v2.1.14"
// Configuration params from EMAIL.CFG
char cfg_server[40]; // IP of POP3 server

View File

@ -42,7 +42,7 @@ void send(unsigned char flags, const char* str, ...)
}
va_start(args, str);
send_size += vsnprintf(send_buffer + send_size, sizeof(send_buffer) - send_size, str, args);
send_size += vsnprintf((char*)send_buffer + send_size, sizeof(send_buffer) - send_size, str, args);
va_end(args);
if (flags & SEND_LAST || sizeof(send_buffer) - send_size < 1024 / 4)
@ -309,9 +309,9 @@ int main(void)
{
read(file, &eth_init, 1);
close(file);
eth_init &= ~'0';
eth_init &= 7;
}
printf("- %d", eth_init);
printf("- %u", eth_init);
}
#endif

View File

@ -91,7 +91,7 @@ int ifttt_trigger(const char* key, const char* event,
return -1;
}
len = url_download(url, download, sizeof(download));
len = url_download(url, (uint8_t*)download, sizeof(download));
if (len < 12)
{

View File

@ -78,15 +78,15 @@ struct linenoiseState {
int history_index; /* The history index we are currently editing. */
};
enum KEY_ACTION{
CTRL_A = 1, /* Ctrl+a */
CTRL_B = 2, /* Ctrl-b */
CTRL_C = 3, /* Ctrl-c */
CTRL_D = 4, /* Ctrl-d */
CTRL_E = 5, /* Ctrl-e */
CTRL_F = 6, /* Ctrl-f */
CTRL_N = 14, /* Ctrl-n */
CTRL_P = 16 /* Ctrl-p */
enum KEY_ACTION {
CTRL_A = 1, /* Ctrl+a */
CTRL_B = 2, /* Ctrl-b */
CTRL_C = 3, /* Ctrl-c */
CTRL_D = 4, /* Ctrl-d */
CTRL_E = 5, /* Ctrl-e */
CTRL_F = 6, /* Ctrl-f */
CTRL_N = 14, /* Ctrl-n */
CTRL_P = 16 /* Ctrl-p */
};
static void refreshLine(struct linenoiseState *l);
@ -102,14 +102,16 @@ static int getColumns() {
return cols;
}
#ifdef __APPLE2__
#pragma code-name (push, "LC")
#endif
/* Beep, used for completion when there is nothing to complete or when all
* the choices were already shown. */
static void linenoiseBeep(void) {
#ifdef __APPLE2__
unsigned char x = wherex();
#endif
putchar('\a');
#ifdef __APPLE2__
gotox(x);
#endif
}
/* ============================== Completion ================================ */
@ -123,6 +125,10 @@ static void freeCompletions(linenoiseCompletions *lc) {
free(lc->cvec);
}
#ifdef __APPLE2__
#pragma code-name (push, "LC")
#endif
/* This is an helper function for linenoiseEdit() and is called when the
* user types the <tab> key in order to complete the string currently in the
* input.

View File

@ -561,7 +561,8 @@ void update_mailbox(char *mbox) {
update_email_db(mbox, &hdrs);
puts("");
sprintf(filename, "%s/NEWS.SPOOL/NEWS.%u", cfg_emaildir, msg);
//sprintf(filename, "%s/NEWS.SPOOL/NEWS.%u", cfg_emaildir, msg);
sprintf(filename, "%s/NEWS.SPOOL/%s", cfg_emaildir, d->d_name);
if (unlink(filename))
printf("Can't delete %s\n", filename);
}
@ -636,11 +637,12 @@ void main(int argc, char *argv[]) {
}
// Copy IP config from IP65 to W5100
w5100_config(eth_init);
w5100_init(eth_init);
w5100_config();
printf("Ok\nConnecting to %s (%u) - ", cfg_server, nntp_port);
if (!w5100_connect(parse_dotted_quad(cfg_server), nntp_port)) {
if (!w5100_connect_addr(parse_dotted_quad(cfg_server), nntp_port)) {
printf("Fail\n");
error_exit();
}

View File

@ -548,7 +548,8 @@ void main(int argc, char *argv[]) {
printf("Ok\n");
// Copy IP config from IP65 to W5100
w5100_config(eth_init);
w5100_init(eth_init);
w5100_config();
sprintf(filename, "%s/NEWS.OUTBOX", cfg_emaildir);
dp = opendir(filename);
@ -577,7 +578,7 @@ void main(int argc, char *argv[]) {
linecount = 0;
while (1) {
if ((get_line(fp, 0, linebuf, LINEBUFSZ) == 0) || (linecount == 20))
if ((get_line(fp, 0, linebuf, LINEBUFSZ) == 0) || (linecount == 20) || (linebuf[0] == '\r'))
break;
++linecount;
if (!strncmp(linebuf, "Newsgroups: ", 12))
@ -632,7 +633,7 @@ sendmessage:
if (!connected) {
printf("\nConnecting to %s (%u) - ", cfg_server, nntp_port);
if (!w5100_connect(parse_dotted_quad(cfg_server), nntp_port)) {
if (!w5100_connect_addr(parse_dotted_quad(cfg_server), nntp_port)) {
printf("Fail\n");
error_exit();
}

View File

@ -534,17 +534,19 @@ void main(int argc, char *argv[]) {
// Abort on Ctrl-C to be consistent with Linenoise
abort_key = 0x83;
w5100_init(eth_init);
printf("Ok\nObtaining IP address - ");
if (dhcp_init()) {
ip65_error_exit();
}
// Copy IP config from IP65 to W5100
w5100_config(eth_init);
w5100_config();
printf("Ok\nConnecting to %s - ", cfg_server);
if (!w5100_connect(parse_dotted_quad(cfg_server), pop_port)) {
if (!w5100_connect_addr(parse_dotted_quad(cfg_server), pop_port)) {
printf("Fail\n");
error_exit();
}

View File

@ -280,7 +280,8 @@ void main(int argc, char *argv[]) {
printf("Ok\n");
// Copy IP config from IP65 to W5100
w5100_config(eth_init);
w5100_init(eth_init);
w5100_config();
fp = fopen(filename, "rb");
if (!fp) {
@ -291,7 +292,7 @@ void main(int argc, char *argv[]) {
if (!connected) {
printf("\nConnecting to %s:%d - ", cfg_server, jetdirect_port);
if (!w5100_connect(parse_dotted_quad(cfg_server), jetdirect_port)) {
if (!w5100_connect_addr(parse_dotted_quad(cfg_server), jetdirect_port)) {
printf("Fail\n");
error_exit();
}

View File

@ -163,6 +163,9 @@ void repair_mailbox(void) {
}
fclose(fp);
maxemailnum = 0;
minemailnum = 65535;
printf("** Scanning directory %s\n", dirname);
while (d = readdir(dp)) {
@ -180,6 +183,11 @@ void repair_mailbox(void) {
}
closedir(dp);
if (maxemailnum < minemailnum) {
printf("** No messages in this directory\n");
error_exit();
}
printf("** Will process EMAIL.%u to EMAIL.%u\n", minemailnum, maxemailnum);
for (emailnum = minemailnum; emailnum <= maxemailnum; ++emailnum) {
sprintf(filename, "%s/EMAIL.%u", dirname, emailnum);

View File

@ -547,7 +547,8 @@ void main(int argc, char *argv[]) {
printf("Ok\n");
// Copy IP config from IP65 to W5100
w5100_config(eth_init);
w5100_init(eth_init);
w5100_config();
sprintf(filename, "%s/OUTBOX", cfg_emaildir);
dp = opendir(filename);
@ -577,7 +578,7 @@ void main(int argc, char *argv[]) {
strcpy(recipients, "");
while (1) {
if ((get_line(fp, 0, linebuf, LINEBUFSZ) == 0) || (linecount == 20)) {
if ((get_line(fp, 0, linebuf, LINEBUFSZ) == 0) || (linecount == 20) || (linebuf[0] == '\r')) {
if (strlen(recipients) == 0) {
printf("No recipients (To or Cc) in %s. Skipping msg.\n", d->d_name);
goto skiptonext;
@ -644,7 +645,7 @@ sendmessage:
if (!connected) {
printf("\nConnecting to %s - ", cfg_smtp_server);
if (!w5100_connect(parse_dotted_quad(cfg_smtp_server), smtp_port)) {
if (!w5100_connect_addr(parse_dotted_quad(cfg_smtp_server), smtp_port)) {
printf("Fail\n");
error_exit();
}

View File

@ -152,9 +152,9 @@ int main(void)
{
read(file, &eth_init, 1);
close(file);
eth_init &= ~'0';
eth_init &= 7;
}
printf("- %d\n", eth_init);
printf("- %u\n", eth_init);
}
#endif

View File

@ -65,12 +65,8 @@ static uint16_t addr_mask [2];
static void set_addr(uint16_t addr)
{
// The variables are necessary to have cc65 generate code
// suitable to access the W5100 auto-increment registers.
uint8_t addr_hi = addr >> 8;
uint8_t addr_lo = addr;
*w5100_addr_hi = addr_hi;
*w5100_addr_lo = addr_lo;
*w5100_addr_hi = addr >> 8;
*w5100_addr_lo = addr;
}
static uint8_t get_byte(uint16_t addr)
@ -91,54 +87,44 @@ static uint16_t get_word(uint16_t addr)
{
set_addr(addr);
{
// The variables are necessary to have cc65 generate code
// suitable to access the W5100 auto-increment registers.
uint8_t data_hi = *w5100_data;
uint8_t data_lo = *w5100_data;
return data_hi << 8 | data_lo;
}
return *w5100_data << 8 | *w5100_data;
}
static void set_word(uint16_t addr, uint16_t data)
{
set_addr(addr);
{
// The variables are necessary to have cc65 generate code
// suitable to access the W5100 auto-increment registers.
uint8_t data_hi = data >> 8;
uint8_t data_lo = data;
*w5100_data = data_hi;
*w5100_data = data_lo;
}
*w5100_data = data >> 8;
*w5100_data = data;
}
static void set_quad(uint16_t addr, uint32_t data)
{
set_addr(addr);
{
// The variables are necessary to have cc65 generate code
// suitable to access the W5100 auto-increment registers.
uint8_t data_1 = data;
uint8_t data_2 = data >> 8;
uint8_t data_3 = data >> 16;
uint8_t data_4 = data >> 24;
*w5100_data = data_1;
*w5100_data = data_2;
*w5100_data = data_3;
*w5100_data = data_4;
}
*w5100_data = data;
*w5100_data = data >> 8;
*w5100_data = data >> 16;
*w5100_data = data >> 24;
}
void w5100_config(uint8_t eth_init)
bool w5100_init(uint8_t eth_init)
{
w5100_mode = (uint8_t*)(eth_init << 4 | 0xC084);
w5100_addr_hi = w5100_mode + 1;
w5100_addr_lo = w5100_mode + 2;
w5100_data = w5100_mode + 3;
// PPP Link Control Protocol Request Timer Register defaults to 0x28
// on a real W5100. However, AppleWin features a virtual W5100 that
// supports DNS offloading. On that virtual W5100, the (otherwise
// anyhow unused) register defaults to 0x00 as detection mechanism.
// https://github.com/a2retrosystems/uthernet2/wiki/Virtual-W5100-with-DNS
return get_byte(0x0028) == 0x00;
}
void w5100_config(void)
{
#ifdef SINGLE_SOCKET
// IP65 is inhibited so disable the W5100 Ping Block Mode.
@ -193,14 +179,14 @@ void w5100_config(uint8_t eth_init)
}
}
bool w5100_connect(uint32_t addr, uint16_t port)
static bool w5100_connect(uint16_t port)
{
// Socket x Mode Register: TCP
set_byte(SOCK_REG(0x00), 0x01);
// Socket x Source Port Register
set_word(SOCK_REG(0x04), ip65_random_word());
// Socket x Destination Port Register
set_word(SOCK_REG(0x10), port);
// Socket x Command Register: OPEN
set_byte(SOCK_REG(0x01), 0x01);
@ -213,12 +199,6 @@ bool w5100_connect(uint32_t addr, uint16_t port)
}
}
// Socket x Destination IP Address Register
set_quad(SOCK_REG(0x0C), addr);
// Socket x Destination Port Register
set_word(SOCK_REG(0x10), port);
// Socket x Command Register: CONNECT
set_byte(SOCK_REG(0x01), 0x04);
@ -238,6 +218,34 @@ bool w5100_connect(uint32_t addr, uint16_t port)
}
}
bool w5100_connect_addr(uint32_t addr, uint16_t port)
{
// Socket x Mode Register: TCP, Use No Delayed ACK
set_byte(SOCK_REG(0x00), 0x21);
// Socket x Destination IP Address Register
set_quad(SOCK_REG(0x0C), addr);
return w5100_connect(port);
}
bool w5100_connect_name(const char* name, uint8_t length, uint16_t port)
{
// Socket x Mode Register: TCP, Use No Delayed ACK, Use DNS Offloading
set_byte(SOCK_REG(0x00), 0x29);
// Socket x DNS name length
set_byte(SOCK_REG(0x2A), length);
// Socket x DNS name chars
while (length--)
{
*w5100_data = *name++;
}
return w5100_connect(port);
}
bool w5100_connected(void)
{
// Socket x Status Register: SOCK_ESTABLISHED ?

View File

@ -46,13 +46,23 @@ void w5100_data_commit(bool do_send, uint16_t size);
// to be sent to the server.
extern volatile uint8_t* w5100_data;
// Initialize this module after the IP65 TCP/IP stack has been initialized.
// Return true if the (virtual) W5100 supports DNS Offloading.
// https://github.com/a2retrosystems/uthernet2/wiki/Virtual-W5100-with-DNS
bool w5100_init(uint8_t eth_init);
// Configure W5100 Ethernet controller with additional information from IP65
// after the IP65 TCP/IP stack has been configured.
void w5100_config(uint8_t eth_init);
void w5100_config(void);
// Connect to server with IP address <server_addr> on TCP port <server_port>.
// Connect to server with IP address <addr> on TCP port <port>.
// Return true if the connection is established, return false otherwise.
bool w5100_connect(uint32_t addr, uint16_t port);
bool w5100_connect_addr(uint32_t addr, uint16_t port);
// Connect to server with name <name>, <length> on TCP port <port> using
// DNS Offloading.
// Return true if the connection is established, return false otherwise.
bool w5100_connect_name(const char* name, uint8_t length, uint16_t port);
// Check if still connected to server.
// Return true if the connection is established, return false otherwise.

View File

@ -39,16 +39,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#pragma optimize (on)
#pragma static-locals (on)
bool w5100_http_open(uint32_t addr, uint16_t port, const char* selector,
char* buffer, size_t length)
static bool w5100_http_open(const char* selector, char* buffer, size_t length)
{
printf("Connecting to %s:%d ", dotted_quad(addr), port);
if (!w5100_connect(addr, port))
{
printf("- Connect failed\n");
return false;
}
register volatile uint8_t *data = w5100_data;
printf("- Ok\n\nSending request ");
{
@ -82,15 +75,11 @@ bool w5100_http_open(uint32_t addr, uint16_t port, const char* selector,
}
{
// One less to allow for faster pre-increment below
const char *dataptr = selector + pos - 1;
const char *dataptr = selector + pos;
uint16_t i;
for (i = 0; i < snd; ++i)
{
// The variable is necessary to have cc65 generate code
// suitable to access the W5100 auto-increment register.
char data = *++dataptr;
*w5100_data = data;
*data = *dataptr++;
}
}
@ -132,17 +121,13 @@ bool w5100_http_open(uint32_t addr, uint16_t port, const char* selector,
}
{
// One less to allow for faster pre-increment below
char *dataptr = buffer + len - 1;
char *dataptr = buffer + len;
uint16_t i;
for (i = 0; i < rcv; ++i)
{
// The variable is necessary to have cc65 generate code
// suitable to access the W5100 auto-increment register.
char data = *w5100_data;
*++dataptr = data;
*dataptr++ = *data;
if (!memcmp(dataptr - 3, "\r\n\r\n", 4))
if (!memcmp(dataptr - 4, "\r\n\r\n", 4))
{
rcv = i + 1;
body = true;
@ -183,3 +168,31 @@ bool w5100_http_open(uint32_t addr, uint16_t port, const char* selector,
}
return true;
}
bool w5100_http_open_addr(uint32_t addr, uint16_t port, const char* selector,
char* buffer, size_t length)
{
printf("Connecting to %s:%d ", dotted_quad(addr), port);
if (!w5100_connect_addr(addr, port))
{
printf("- Connect failed\n");
return false;
}
return w5100_http_open(selector, buffer, length);
}
bool w5100_http_open_name(const char* name, uint8_t name_length, uint16_t port,
const char* selector, char* buffer, size_t buffer_length)
{
printf("Connecting to port %d ", port);
if (!w5100_connect_name(name, name_length, port))
{
printf("- Connect failed\n");
return false;
}
return w5100_http_open(selector, buffer, buffer_length);
}

View File

@ -37,12 +37,20 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdint.h>
#include <stdbool.h>
// Connect to server with IP address <server_addr> on TCP port <server_port>,
// then HTTP GET <selector> and consume HTTP response header. Provide feedback
// on progress to the user via STDOUT. After returning from w5100_http_open()
// the connection is ready to consume the HTTP body.
// Connect to server with IP address <addr> on TCP port <port>, then HTTP GET
// <selector> and consume HTTP response header. Provide feedback on progress
// to the user via STDOUT. After returning from w5100_http_open_addr(), the
// connection is ready to consume the HTTP body.
// Return true if the connection is established, return false otherwise.
bool w5100_http_open(uint32_t addr, uint16_t port, const char* selector,
char* buffer, size_t length);
bool w5100_http_open_addr(uint32_t addr, uint16_t port, const char* selector,
char* buffer, size_t length);
// Connect to server with name <name>, <name_length> on TCP port <port> using
// DNS Offloading, then HTTP GET <selector> and consume HTTP response header.
// Provide feedback on progress to the user via STDOUT. After returning from
// w5100_http_open_name(), the connection is ready to consume the HTTP body.
// Return true if the connection is established, return false otherwise.
bool w5100_http_open_name(const char* name, uint8_t name_length, uint16_t port,
const char* selector, char* buffer, size_t buffer_length);
#endif

View File

@ -241,6 +241,7 @@ void exit_on_key(void)
void write_file(const char *name)
{
register volatile uint8_t *data = w5100_data;
uint16_t i;
int file;
uint16_t rcv;
@ -277,14 +278,10 @@ void write_file(const char *name)
}
{
// One less to allow for faster pre-increment below
char *dataptr = buffer + len - 1;
char *dataptr = buffer + len;
for (i = 0; i < rcv; ++i)
{
// The variable is necessary to have cc65 generate code
// suitable to access the W5100 auto-increment register.
char data = *w5100_data;
*++dataptr = data;
*dataptr++ = *data;
}
}
@ -318,6 +315,7 @@ void write_file(const char *name)
void write_device(char device)
{
register volatile uint8_t *data = w5100_data;
uint16_t i;
dhandle_t dio;
uint16_t rcv;
@ -383,8 +381,7 @@ void write_device(char device)
rcv = sizeof(buffer) - len;
}
// One less to allow for faster pre-increment below
dataptr = buffer + len - 1;
dataptr = buffer + len;
}
else
{
@ -394,16 +391,12 @@ void write_device(char device)
rcv = 0x100 - len % 0x100;
}
// One less to allow for faster pre-increment below
dataptr = buffer + (skew[len / 0x100] << 8 | len % 0x100) - 1;
dataptr = buffer + (skew[len / 0x100] << 8 | len % 0x100);
}
for (i = 0; i < rcv; ++i)
{
// The variable is necessary to have cc65 generate code
// suitable to access the W5100 auto-increment register.
char data = *w5100_data;
*++dataptr = data;
*dataptr++ = *data;
}
}
@ -442,6 +435,7 @@ int main(int, char *argv[])
uint16_t i;
char *arg;
char device;
bool Offload_DNS;
uint8_t eth_init = ETH_INIT_DEFAULT;
if (doesclrscrafterexit())
@ -475,11 +469,11 @@ int main(int, char *argv[])
{
read(file, &eth_init, 1);
close(file);
eth_init &= ~'0';
eth_init &= 7;
}
}
printf("- %d\n\nInitializing %s ", eth_init, eth_name);
printf("- %u\n\nInitializing %s ", eth_init, eth_name);
if (ip65_init(eth_init))
{
ip65_error_exit();
@ -488,15 +482,20 @@ int main(int, char *argv[])
// Abort on Ctrl-C to be consistent with Linenoise
abort_key = 0x83;
printf("- Ok\n\nObtaining IP address ");
if (dhcp_init())
Offload_DNS = w5100_init(eth_init);
if (!Offload_DNS)
{
ip65_error_exit();
printf("- Ok\n\nObtaining IP address ");
if (dhcp_init())
{
ip65_error_exit();
}
}
printf("- Ok\n\n");
// Copy IP config from IP65 to W5100
w5100_config(eth_init);
w5100_config();
load_argument("wget.urls");
while (true)
@ -504,7 +503,7 @@ int main(int, char *argv[])
arg = get_argument(1, "URL", url_completion);
printf("\n\nProcessing URL ");
if (!url_parse(arg))
if (!url_parse(arg, !Offload_DNS))
{
break;
}
@ -657,9 +656,21 @@ int main(int, char *argv[])
save_argument("wget.files");
printf("\n\n");
if (!w5100_http_open(url_ip, url_port, url_selector, buffer, sizeof(buffer)))
if (Offload_DNS)
{
return EXIT_FAILURE;
if (!w5100_http_open_name(url_host, strlen(url_host) - 4, url_port,
url_selector, buffer, sizeof(buffer)))
{
return EXIT_FAILURE;
}
}
else
{
if (!w5100_http_open_addr(url_ip, url_port,
url_selector, buffer, sizeof(buffer)))
{
return EXIT_FAILURE;
}
}
if (device)

View File

@ -1,23 +1,21 @@
# For assembler programs
# ----------------------
# c64rrnet.lib : C64 with RR-Net (or clone)
# c64eth64.lib : C64 with ETH64
# c64combo.lib : C64 with RR-Net or ETH64
# a2uther.lib : Apple ][ with Uthernet (default slot: #3)
# a2lancegs.lib : Apple ][ with LANceGS (default slot: #3)
# a2uther2.lib : Apple ][ with Uthernet II (default slot: #3)
# a2combo.lib : Apple ][ with Uthernet or LANceGS or Uthernet II (default slot: #3)
# atrdragon.lib : ATARI 8-bit with Dragon Cart
# atrdracarys.lib : ATARI 8-bit with Dracarys (default PBI device ID: #8)
# atrcombo.lib : ATARI 8-bit with Dragon Cart or Dracarys (default PBI device ID: #8)
# vic20rrnet.lib : VIC20 with RR-Net (or clone)
# c64rrnet.lib : C64 with RR-Net (or clone)
# c64eth64.lib : C64 with ETH64
# c64combo.lib : C64 with RR-Net or ETH64
# a2uther.lib : Apple ][ with Uthernet (default slot: #3)
# a2uther2.lib : Apple ][ with Uthernet II (default slot: #3)
# a2lancegs.lib : Apple ][ with LANceGS (default slot: #3)
# a2combo.lib : Apple ][ with Uthernet or Uthernet II or LANceGS (default slot: #3)
# atrdragon.lib : ATARI 8-bit with Dragon Cart
# vic20rrnet.lib : VIC20 with RR-Net (or clone)
# For C programs
# --------------
# ip65_c64.lib : C64 with RR-Net or ETH64
# ip65_apple2.lib : Apple ][ with Uthernet or LANceGS or Uthernet II (default slot: #3)
# ip65_atari.lib : ATARI 8-bit with Dragon Cart or Dracarys (default PBI device ID: #8)
# ip65_atarixl.lib : ATARI XL with Dragon Cart or Dracarys (default PBI device ID: #8)
# ip65_apple2.lib : Apple ][ with Uthernet or Uthernet II or LANceGS (default slot: #3)
# ip65_atari.lib : ATARI 8-bit with Dragon Cart
# ip65_atarixl.lib : ATARI XL with Dragon Cart
DRIVERS=\
c64rrnet.lib \
@ -25,14 +23,12 @@ DRIVERS=\
c64combo.lib \
ip65_c64.lib \
a2uther.lib \
a2lancegs.lib \
a2uther2.lib \
a2lancegs.lib \
a2combo.lib \
ip65_apple2.lib \
ip65_apple2_uther2.lib \
atrdragon.lib \
atrdracarys.lib \
atrcombo.lib \
ip65_atari.lib \
ip65_atarixl.lib \
vic20rrnet.lib
@ -118,9 +114,9 @@ rr-net.o uthernet.o dragoncart.o vic20-rr-net.o: cs8900a.s
eth64.o lancegs.o: lan91c96.s
uthernet2.o dracarys.o: w5100.s
uthernet2.o: w5100.s
c64combo.o a2combo.o atrcombo.o: ethernetcombo.s
c64combo.o a2combo.o: ethernetcombo.s
c64rrnet.lib: rr-net.o $(CS8900AOBJS) c64init.o $(C64OBJS)
@ -132,10 +128,10 @@ ip65_c64.lib: rr-net.o eth64.o c64combo.o c64init.o $(C64_OBJS)
a2uther.lib: uthernet.o $(CS8900AOBJS) a2init.o $(A2OBJS)
a2lancegs.lib: lancegs.o $(LAN91C96OBJS) a2init.o $(A2OBJS)
a2uther2.lib: uthernet2.o $(W5100OBJS) a2init.o $(A2OBJS)
a2lancegs.lib: lancegs.o $(LAN91C96OBJS) a2init.o $(A2OBJS)
a2combo.lib: uthernet.o lancegs.o uthernet2.o a2combo.o a2init.o $(A2OBJS)
ip65_apple2.lib: uthernet.o lancegs.o uthernet2.o a2combo.o a2init.o $(A2_OBJS)
@ -144,13 +140,9 @@ ip65_apple2_uther2.lib: uthernet2.o $(W5100OBJS) a2init.o $(A2_OBJS)
atrdragon.lib: dragoncart.o $(CS8900AOBJS) atrinit.o $(ATROBJS)
atrdracarys.lib: dracarys.o $(W5100OBJS) atrinit.o $(ATROBJS)
ip65_atari.lib: dragoncart.o $(CS8900AOBJS) atrinit.o $(ATR_OBJS)
atrcombo.lib: dragoncart.o dracarys.o atrcombo.o atrinit.o $(ATROBJS)
ip65_atari.lib: dragoncart.o dracarys.o atrcombo.o atrinit.o $(ATR_OBJS)
ip65_atarixl.lib: dragoncart.o dracarys.o atrcombo.o atrinit.o $(ATRXL_OBJS)
ip65_atarixl.lib: dragoncart.o $(CS8900AOBJS) atrinit.o $(ATRXL_OBJS)
vic20rrnet.lib: vic20-rr-net.o $(CS8900AOBJS) vic20init.o $(VIC20OBJS)

View File

@ -1 +1 @@
.exportzp eth_init_default = 5 ; Apple 2 default slot
.exportzp eth_init_default = 3 ; Apple 2 default slot

View File

@ -1 +1 @@
.exportzp eth_init_default = 8 ; PBI default device ID
.exportzp eth_init_default = 0

View File

@ -132,7 +132,7 @@ set_name:
eth_init:
sta eth_init_value
.if .defined (__APPLE2__) .or .defined (__ATARI__)
.if .defined (__APPLE2__)
ldax #_w5100
jsr patch_wrapper
ldax #_w5100_name

View File

@ -41,12 +41,7 @@
; Ethernet address
mac: .byte $00, $08, $DC ; OUI of WIZnet
.ifdef __APPLE2__
.byte $A2, $A2, $A2
.endif
.ifdef __ATARI__
.byte $A8, $A8, $A8
.endif
; Buffer attributes
bufaddr:.res 2 ; Address
@ -91,8 +86,6 @@ tmp := tmp4 ; Temporary value
;=====================================================================
.ifdef __APPLE2__
.rodata
fixup: .byte fixup02-fixup01, fixup03-fixup02, fixup04-fixup03
@ -155,54 +148,6 @@ init:
bcs :- ; Always
:
.endif
;=====================================================================
.ifdef __ATARI__
.rodata
pdtab: .byte %00000001
.byte %00000010
.byte %00000100
.byte %00001000
.byte %00010000
.byte %00100000
.byte %01000000
.byte %10000000
;---------------------------------------------------------------------
.bss
pdbit: .res 1
;---------------------------------------------------------------------
mode := $D1F0
addr := $D1F1
data := $D1F3
pdvs := $D1FF ; parallel device select
shpdvs := $0248 ; shadow parallel device select
;---------------------------------------------------------------------
.code
init:
; Convert parallel device ID (1-8) to parallel device bit
tay
lda pdtab-1,y
sta pdbit
; Select parallel device
sta shpdvs
sta pdvs
.endif
;=====================================================================
; Indirect Bus I/F mode, Address Auto-Increment
@ -287,13 +232,6 @@ fixup14:sta data
;---------------------------------------------------------------------
poll:
.ifdef __ATARI__
; Select parallel device
lda pdbit
sta shpdvs
sta pdvs
.endif
; Check for completion of previous command
; Socket 0 Command Register: = 0 ?
jsr set_addrcmdreg0
@ -401,13 +339,6 @@ send:
sta adv
stx adv+1
.ifdef __ATARI__
; Select parallel device
lda pdbit
sta shpdvs
sta pdvs
.endif
; Set parameters for transmitting data
lda #>$4000 ; Socket 0 TX Base Address
ldx #$01 ; Write

View File

@ -7,9 +7,7 @@
// Ethernet driver initialization parameter values
//
#if defined(__APPLE2__)
#define ETH_INIT_DEFAULT 5 // Apple II slot number
#elif defined(__ATARI__)
#define ETH_INIT_DEFAULT 8 // ATARI PBI device ID
#define ETH_INIT_DEFAULT 3 // Apple II slot number
#else
#define ETH_INIT_DEFAULT 0 // Unused
#endif
@ -294,16 +292,18 @@ bool __fastcall__ tftp_upload_from_memory(uint32_t server, const char* name,
//
// On success the variables url_ip, url_port and url_selector (see below) are valid.
//
// Inputs: url: Zero (or ctrl char) terminated string containing the URL
// Inputs: url: Zero (or ctrl char) terminated string containing the URL
// resolve: Resolve host in URL
// Output: true if an error occured, false otherwise
//
bool __fastcall__ url_parse(const char* url);
bool __fastcall__ url_parse(const char* url, bool resolve);
// Access to parsed HTTP URL
//
// Access to the three items below is only valid after url_parse returned false.
// Access to the four items below is only valid after url_parse returned false.
//
extern uint32_t url_ip; // IP address of host in URL
extern char* url_host; // Zero terminated string containing host in URL + "\r\n\r\n"
extern uint32_t url_ip; // IP address of host in URL (only if 'resolve' is true)
extern uint16_t url_port; // Port number of URL
extern char* url_selector; // Zero terminated string containing selector part of URL

View File

@ -85,6 +85,7 @@ dhcp_message_sent_count: .res 1
dhcp_timer: .res 1
dhcp_loop_count: .res 1
dhcp_break_polling_loop: .res 1
dhcp_ip: .res 4
; DHCP constants
BOOTREQUEST = 1
@ -315,9 +316,9 @@ dhcp_in:
cmp dhcp_inp+dhcp_yiaddr ; is the first byte in the assigned address 0?
bne :+
rts ; if so, it's a bogus response - ignore
: ldx #4 ; copy the our new IP address
: ldx #3 ; copy the new IP address
: lda dhcp_inp+dhcp_yiaddr,x
sta cfg_ip,x
sta dhcp_ip,x
dex
bpl :-
@ -423,7 +424,7 @@ send_dhcprequest:
ldx #4 ; option length is 4
stx output_buffer+dhcp_options+4
dex
: lda cfg_ip,x
: lda dhcp_ip,x
sta output_buffer+dhcp_options+5,x
dex
bpl :-
@ -449,9 +450,16 @@ send_dhcprequest:
ldax #output_buffer
jsr udp_send
bcs :+ ; if we didn't send the message we probably need to wait for an ARP reply to come back.
bcs :++ ; if we didn't send the message we probably need to wait for an ARP reply to come back.
lda #dhcp_bound ; technically, we should wait till we get a DHCPACK message. but we'll assume success
sta dhcp_state
ldx #3 ; set the new IP address
: lda dhcp_ip,x
sta cfg_ip,x
dex
bpl :-
: rts

View File

@ -61,6 +61,7 @@ url_download:
sty url_selector
ldy url_download_buffer+1
sty url_selector+1
ldy #1
jsr url_parse_buffer
bcc resource_download
rts

View File

@ -65,7 +65,7 @@ _udp_recv_src_port:
ldx udp_inp+udp_src_port
rts
_udp_send:
_udp_send:
stax udp_send_src_port
jsr popax
stax udp_send_dest_port

View File

@ -13,6 +13,7 @@
.import parse_integer
.import dns_ip
.export url_host
.export url_ip
.export url_port
.export url_selector
@ -26,7 +27,8 @@ search_string = ptr1
.bss
url_string: .res 2
url_ip: .res 4 ; will be set with ip address of host in url
url_host: .res 2 ; will be set with hostname + CRLFCRLF
url_ip: .res 4 ; will be set with ip address of host in url (if resolve)
url_port: .res 2 ; will be set with port number of url
url_selector: .res 2 ; will be set with address of selector part of URL
url_type: .res 1
@ -35,6 +37,7 @@ search_string = ptr1
url_type_gopher = 1
url_type_http = 2
resolve: .res 1
src_ptr: .res 1
dest_ptr: .res 1
@ -46,28 +49,33 @@ search_string = ptr1
; inputs:
; AX = address of URL string
; any control character (i.e. <$20) is treated as 'end of string', e.g. a CR or LF, as well as $00
; Y = do resolve hostname
; outputs:
; sec if a malformed url, otherwise:
; url_ip = ip address of host in url
; url_port = port number of url
; url_selector = address of selector part of URL
url_parse:
sty resolve
ldy #<output_buffer
sty url_selector
ldy #>output_buffer
sty url_selector+1
ldy resolve
; parses a URL into a form that makes it easy to retrieve the specified resource
; caution - the resulting selector part of URL must fit into the provided buffer !!!
; inputs:
; AX = address of URL string
; any control character (i.e. <$20) is treated as 'end of string', e.g. a CR or LF, as well as $00
; Y = do resolve hostname
; url_selector = points to a buffer that selector part of URL will be placed into
; outputs:
; sec if a malformed url, otherwise:
; url_ip = ip address of host in url
; url_port = port number of url
url_parse_buffer:
sty resolve
stax url_string
ldy #url_type_http
sty url_type
@ -109,6 +117,8 @@ lda #url_type_gopher
; now pointing at hostname
bcs @exit_with_error
@no_protocol_specifier:
ldy resolve
beq @no_resolve
jsr dns_set_hostname
bcs @exit_with_sec
jsr dns_resolve
@ -125,6 +135,7 @@ lda #url_type_gopher
jsr skip_to_hostname
@no_resolve:
; skip over next colon
ldax #colon
jsr parser_skip_next
@ -212,11 +223,17 @@ lda #url_type_gopher
jsr skip_to_hostname
; AX now pointing at hostname
stax ptr1
clc
lda url_selector
sta ptr2
adc dest_ptr
sta url_host
pla
sta ptr2+1
adc #0
sta url_host+1
lda #0
sta src_ptr

View File

@ -1,22 +1,32 @@
.include "../inc/common.inc"
.export _url_parse
.export _url_host
.export _url_ip
.export _url_port
.export _url_selector
.import url_parse
.import url_host
.import url_ip
.import url_port
.import url_selector
.import popax
.importzp tmp1
_url_parse:
sta tmp1
jsr popax
ldy tmp1
jsr url_parse
ldx #$00
txa
rol
rts
_url_host := url_host
_url_ip := url_ip
_url_port := url_port

BIN
releases/emailler-2.1.10.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.11.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.12.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.13.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.14.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.6.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.7.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.8.po Normal file

Binary file not shown.

BIN
releases/emailler-2.1.9.po Normal file

Binary file not shown.

View File

@ -17,15 +17,14 @@ else ifeq ($(eth),sm)
A2DRIVERLIB = ../drivers/a2lancegs.lib
else ifeq ($(eth),wn)
A2DRIVERLIB = ../drivers/a2uther2.lib
ATRDRIVERLIB = ../drivers/atrdracarys.lib
else
C64DRIVERLIB = ../drivers/c64combo.lib
A2DRIVERLIB = ../drivers/a2combo.lib
ATRDRIVERLIB = ../drivers/atrcombo.lib
ATRDRIVERLIB = ../drivers/atrdragon.lib
VICDRIVERLIB = ../drivers/vic20rrnet.lib
endif
# See http://vice-emu.sourceforge.net/
# See https://vice-emu.sourceforge.net/
C1541 ?= c1541
# See https://applecommander.github.io/
@ -112,32 +111,28 @@ vt100.com: ATARI_CFG = ../apps/atrtelnet.cfg
%.o: %.c
%.prg: %.o ip65 drivers
ld65 -o $*.prg -C c64.cfg -m $*.c64.map -vm $< $(IP65LIB) $(C64DRIVERLIB) c64.lib
ld65 -o $*.prg -C c64.cfg -m $*.prg.map -vm $< $(IP65LIB) $(C64DRIVERLIB) c64.lib
%.bin: %.o ip65 drivers
ld65 -o $*.bin -C apple2.cfg -m $*.a2.map -vm $< $(IP65LIB) $(A2DRIVERLIB) apple2.lib
ld65 -o $*.bin -C apple2.cfg -m $*.bin.map -vm $< $(IP65LIB) $(A2DRIVERLIB) apple2.lib
%.com: %.o ip65 drivers
ld65 -o $*.com -C $(ATARI_CFG) -m $*.atr.map -vm $< $(IP65LIB) $(ATRDRIVERLIB) atari.lib
ld65 -o $*.com -C $(ATARI_CFG) -m $*.com.map -vm $< $(IP65LIB) $(ATRDRIVERLIB) atari.lib
%.vicprg: %.o ip65 drivers
ld65 -o $*.vicprg -C vic20-32k.cfg -m $*.vic.map -vm $< $(IP65LIB) $(VICDRIVERLIB) vic20.lib
ld65 -o $*.vicprg -C vic20-32k.cfg -m $*.vicprg.map -vm $< $(IP65LIB) $(VICDRIVERLIB) vic20.lib
%.prg: %.c ip65 drivers
cl65 -o $*.prg -O -t c64 -m $*.c64.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_c64.lib
rm $*.o
cl65 -o $*.prg -O -t c64 -m $*.prg.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_c64.lib
%.bin: %.c ip65 drivers
cl65 -o $*.bin -O -t apple2 -m $*.a2.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_apple2.lib
rm $*.o
cl65 -o $*.bin -O -t apple2 -m $*.bin.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_apple2.lib
%.com: %.c ip65 drivers
cl65 -o $*.com -O -t atari -m $*.atr.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_atari.lib
rm $*.o
cl65 -o $*.com -O -t atari -m $*.com.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_atari.lib
%.xl.com: %.c ip65 drivers
cl65 -o $*.xl.com -O -t atarixl -m $*.atrxl.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_atarixl.lib
rm $*.o
cl65 -o $*.xl.com -O -t atarixl -m $*.xl.com.map -vm $< $(wildcard $**.s) $(IP65LIB) ../drivers/ip65_atarixl.lib
ip65test.d64: prg
$(C1541) -format ip65,00 d64 $@

View File

@ -17,7 +17,6 @@
.import url_port
.import url_selector
.import url_resource_type
.import url_parse
.import url_download
.import url_download_buffer
.import url_download_buffer_length

View File

@ -100,6 +100,7 @@ test_url_parse:
jsr print
jsr print_cr
ldax temp_url_ptr
ldy #1
jsr url_parse
bcc :+
jmp print_errorcode