Tools for working with Cidco Mailstations

recvdump: Add a unix utility for receiving codedump/datadump

+154 -13
+8 -5
Makefile
··· 1 1 # 2 - # Requires SDCC and its ASZ80 assembler 2 + # ASM code requires SDCC and its ASZ80 assembler 3 3 # http://sdcc.sourceforge.net/ 4 - # 5 - # Requires hex2bin 4 + # and hex2bin 6 5 # https://sourceforge.net/projects/hex2bin/files/hex2bin/ 7 6 # 8 7 ··· 11 10 12 11 OBJ ?= obj/ 13 12 14 - all: loader.bin codedump.bin datadump.bin 13 + all: loader.bin codedump.bin datadump.bin recvdump 15 14 16 15 clean: 17 - rm -f *.{map,bin,ihx,lst,rel,sym,lk,noi} 16 + rm -f *.{map,bin,ihx,lst,rel,sym,lk,noi} recvdump 18 17 19 18 # parallel loader 20 19 loader.rel: loader.asm ··· 45 44 46 45 datadump.bin: datadump.ihx 47 46 hex2bin $> >/dev/null 47 + 48 + # datadump/codedump receiver 49 + recvdump: util/recvdump.c 50 + $(CC) -lamd64 -o $@ $>
+15 -8
README.md
··· 1 1 ## mailstation-tools 2 2 3 - This is a collection of tools for working with Cidco Mailstation devices, 4 - primarily the DET1. 3 + This is a collection of tools for working with Cidco Mailstation devices 4 + (primarily the DET1), from a Unix machine. 5 5 6 6 It was mostly pieced together from the now-defunct 7 7 [mailstation Yahoo Group](https://groups.yahoo.com/neo/groups/mailstation/info) ··· 12 12 it was all posted to the public Yahoo group, I am naively assuming it is in the 13 13 public domain. 14 14 15 - (Except for win32/inpout32.dll, obtained from 15 + (Except for `win32/inpout32.dll`, obtained from 16 16 [its website](http://www.highrez.co.uk/downloads/inpout32/) which states "This 17 17 product is released as open source (Freeware).") 18 18 19 19 The Z80 assembly files have been updated to assemble on newer non-win32 20 20 assemblers. 21 21 22 + ### Compiling 23 + 24 + Install [SDCC](http://sdcc.sourceforge.net/) and 25 + [hex2bin](https://sourceforge.net/projects/hex2bin/files/hex2bin/). 26 + 27 + Create an `obj` directory with `mkdir obj` and then run `make`. 28 + 22 29 ### Loading code onto the Mailstation 23 30 24 31 See [loader.txt](loader.txt) for a more thorough explanation. ··· 69 76 You need to type the hex values of `z80/codedump.bin` into one of the 70 77 application slots as detailed above. 71 78 72 - Run `maildump.exe /code` to wait for the code dump to begin. 79 + Run `obj/recvdump -code` to wait for the code dump to begin. 73 80 74 - Then run the new Code Dump app on the Mailstation and `maildump` should show 81 + Then run the new Code Dump app on the Mailstation and `recvdump` should show 75 82 its progress as it reads the transmitted data and saves it to `codeflash.bin`. 76 83 You may want to run it twice and compare checksums of the two resulting files. 77 84 ··· 84 91 You need to type the hex values of `z80/datadump.bin` into one of the 85 92 application slots as detailed above. 86 93 87 - Run `maildump.exe /data` to wait for the data dump to begin. 94 + Run `obj/recvdump -data` to wait for the data dump to begin. 88 95 89 - Then run the new Data Dump app on the Mailstation and `maildump` should show 96 + Then run the new Data Dump app on the Mailstation and `recvdump` should show 90 97 its progress as it reads the transmitted data and saves it to `dataflash.bin`. 91 98 You may want to run it twice and compare checksums of the two resulting files. 92 99 ··· 102 109 103 110 To extract program 0 (which lives at 0x0000) from `dataflash.bin`, run: 104 111 105 - app_extractor.rb -f dataflash.bin -a 0 112 + util/app_extractor.rb -f dataflash.bin -a 0 106 113 107 114 Each of the programs can be extracted with different `-a` values. 108 115
app_extractor.rb util/app_extractor.rb
+131
util/recvdump.c
··· 1 + /* 2 + * recvdump 3 + * based on win32/maildump.cpp by FyberOptic 4 + * 5 + * usage: recvdump [-data | -code] 6 + * 7 + * must be run as root to set iopl and use inb/outb 8 + * 9 + * assumes parallel port is at PORTADDRESS and codedump or datadump has been 10 + * loaded on the MailStation and is running 11 + */ 12 + 13 + #include <stdio.h> 14 + #include <string.h> 15 + #include <err.h> 16 + #include <unistd.h> 17 + #include <sys/types.h> 18 + #include <machine/sysarch.h> 19 + #include <machine/pio.h> 20 + 21 + #define PORTADDRESS 0x378 22 + 23 + #define DATA PORTADDRESS+0 24 + #define STATUS PORTADDRESS+1 25 + #define CONTROL PORTADDRESS+2 26 + 27 + #define bsyin 0x40 28 + #define bsyout 0x08 29 + #define stbin 0x80 30 + #define stbout 0x10 31 + #define tribmask 0x07 32 + #define dibmask 0x03 33 + 34 + unsigned char 35 + recvtribble(void) 36 + { 37 + unsigned char mytribble; 38 + 39 + /* drop busy/ack */ 40 + outb(DATA, 0); 41 + 42 + /* wait for (inverted) strobe */ 43 + while ((inb(STATUS) & stbin) != 0) 44 + ; 45 + 46 + /* grab tribble */ 47 + mytribble = (inb(STATUS) >> 3) & tribmask; 48 + 49 + /* raise busy/ack */ 50 + outb(DATA,bsyout); 51 + 52 + /* wait for (inverted) UNstrobe */ 53 + while ((inb(STATUS) & stbin) == 0) 54 + ; 55 + 56 + return mytribble; 57 + } 58 + 59 + int 60 + main(int argc, char *argv[]) 61 + { 62 + FILE *pFile; 63 + unsigned int received = 0, expected = 0; 64 + unsigned char t1, t2, t3, b; 65 + char fn[14]; 66 + int codeflash = 0, dataflash = 0; 67 + int x; 68 + 69 + for (x = 1; x < argc; x++) { 70 + if (strncmp((char *)argv[x], "-code", 5) == 0) 71 + codeflash = 1; 72 + else if (strncmp((char *)argv[x], "-data", 5) == 0) 73 + dataflash = 1; 74 + else 75 + printf("unknown parameter: %s\n", argv[x]); 76 + } 77 + 78 + if (codeflash == dataflash) { 79 + printf("usage: %s [-code | -data]\n", argv[0]); 80 + return 1; 81 + } 82 + 83 + if (codeflash) { 84 + expected = 1024 * 1024; 85 + strlcpy(fn, "codeflash.bin", sizeof(fn)); 86 + } else if (dataflash) { 87 + expected = 1024 * 512; 88 + strlcpy(fn, "dataflash.bin", sizeof(fn)); 89 + } 90 + 91 + if (geteuid() != 0) 92 + errx(1, "must be run as root"); 93 + 94 + #ifdef __OpenBSD__ 95 + if (amd64_iopl(1) != 0) 96 + errx(1, "amd64_iopl failed (is machdep.allowaperture=1?)"); 97 + #endif 98 + 99 + pFile = fopen(fn, "wb"); 100 + if (!pFile) { 101 + printf("couldn't open file %s\n", fn); 102 + return -1; 103 + } 104 + 105 + printf("dumping to %s, run Code Dump on MailStation now...", fn); 106 + fflush(stdout); 107 + 108 + while (received < expected) { 109 + t1 = recvtribble(); 110 + t2 = recvtribble(); 111 + t3 = recvtribble(); 112 + 113 + b = t1 + (t2 << 3) + ((t3 & dibmask) << 6); 114 + 115 + if (received == 0) 116 + printf("\n"); 117 + 118 + fputc(b, pFile); 119 + received++; 120 + 121 + if (received % 1024 == 0 || received == expected) { 122 + printf("\rreceived: %07d/%07d", received, expected); 123 + fflush(stdout); 124 + } 125 + } 126 + fclose(pFile); 127 + 128 + printf("\n"); 129 + 130 + return 0; 131 + }
z80_opcodes.txt util/z80_opcodes.txt