Compare commits

..

No commits in common. "main" and "v1.0" have entirely different histories.
main ... v1.0

10 changed files with 75 additions and 133 deletions

7
.gitignore vendored
View File

@ -1,5 +1,4 @@
*.tap *.tap
*.block *bin
body *bincs
header ac
ttttt

View File

@ -1,28 +1,33 @@
program.tap: header.block body.block program.tap: program.asm headerbincs body.tap
cat header.block body.block > program.tap pasmo program.asm program.tap
header.block: header ttttt headerbincs: headerbin ac
./ttttt header header cp headerbin headerbincs
./ac headerbincs
header: header.asm body.block headerbin: header.tap
pasmo header.asm headerlong dd if=header.tap of=headerbin bs=1 count=18
dd if=headerlong of=header bs=17 count=1
rm -f headerlong
body.block: body ttttt header.tap: header.asm body.tap
./ttttt body data pasmo header.asm header.tap
body: remload.asm code.asm body.tap: body.asm bodybincs
pasmo remload.asm body pasmo body.asm body.tap
ttttt: ttttt.c bodybincs: bodybin ac
cc ttttt.c -o ttttt cp bodybin bodybincs
./ac bodybincs
bodybin: remload.asm code.asm
pasmo remload.asm bodybin
ac: append_checksum.c
cc append_checksum.c -o ac
clean: clean:
rm -f *.tap rm -f *.tap
rm -f *.block rm -f *bin
rm -f body rm -f *bincs
rm -f header rm -f ac
rm -f ttttt
.PHONY: clean .PHONY: clean

View File

@ -4,7 +4,7 @@ Sometimes it would be useful to run machine code directly from ZX BASIC without
This Makefile will generate a ZX BASIC .tap file with a REM statement containing the machine code, and will automatically run it. Simply amend the code in `code.asm` and run `make`. The file `program.tap` will be created which can be loaded in an emulator or real Spectrum. This Makefile will generate a ZX BASIC .tap file with a REM statement containing the machine code, and will automatically run it. Simply amend the code in `code.asm` and run `make`. The file `program.tap` will be created which can be loaded in an emulator or real Spectrum.
The included BASIC routine will CLEAR 32767 and set BORDER and PAPER to black and INK to white. Amend the `remload.asm` routine if this is not desired. The included BASIC routine will CLEAR 59999 and set BORDER and PAPER to black and INK to white. Amend the `remload.asm` routine if this is not desired.
## Requirements ## Requirements

26
append_checksum.c Normal file
View File

@ -0,0 +1,26 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int fd;
unsigned char tally = 0;
unsigned char next = 0;
if (argc!=2) return -1;
fd = open(argv[1], O_RDWR|O_APPEND);
if (fd<0) return -2;
while (read(fd, &next, 1)) {
//printf("Tally: %X, next byte: %X\n", tally, next);
tally ^= next;
};
printf("Final tally: %X\n", tally);
write(fd, &tally, 1);
close(fd);
return 0;
}

7
body.asm Normal file
View File

@ -0,0 +1,7 @@
bodylength:
dw bodyend - bodycontent
bodycontent:
INCBIN bodybincs
bodyend:

View File

@ -1,12 +1,2 @@
; This is the main file you will edit to add your machine code to the REM statement.
; You _must_ include the "entry_point" tag to point to the address which will called by the BASIC "PRINT USR" statement.
; The default code below is for illustration only, and can be deleted.
; But REMEMBER TO ADD THE entry_point TAG TO YOUR OWN CODE!
data_start: ;if your routine starts here, move the entry_point tag here too
ld bc, 42 ld bc, 42
ret ret
entry_point: ;move this tag to the start point of your code
jr data_start

View File

@ -1,3 +1,6 @@
headerflag:
db 0
blocktype: blocktype:
db 0 ;basic program db 0 ;basic program
@ -17,5 +20,5 @@ checksum:
db 0 db 0
bodytap: bodytap:
INCBIN body.block INCBIN body.tap
endbodytap: endbodytap:

5
program.asm Normal file
View File

@ -0,0 +1,5 @@
headlength:
dw 19
INCBIN headerbincs
INCBIN body.tap

View File

@ -1,5 +1,7 @@
org #5ccb org #5cca
bodyformat:
db #ff
linenumber: linenumber:
db #00 ;MSB db #00 ;MSB
db #00 ;LSB db #00 ;LSB
@ -31,10 +33,10 @@ ink:
db ':' db ':'
clear: clear:
db #fd, "32767" ;CLEAR 32767 - presumably code will be loaded somewhere? db #fd, "59999" ;CLEAR 59999 - presumably code will be loaded somewhere?
db #0e db #0e
db 0,0 db 0,0
dw 32767 dw 59999
db 0 db 0
db ':' db ':'
@ -43,7 +45,7 @@ printusr:
db "0" ;don't know if actual value is important db "0" ;don't know if actual value is important
db #0e db #0e
db 0,0 db 0,0
dw entry_point ;actual call to REM statement code dw code ;actual call to REM statement code
db 0 db 0
db ':' db ':'

95
ttttt.c
View File

@ -1,95 +0,0 @@
/* McPhail's Tip-Top TAP Top-Tailer
* Takes a raw code file as input
* Prepends data length and appends xor checksum
* Outputs to new file with .block suffix */
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/limits.h>
#include <string.h>
int main(int argc, char *argv[])
{
int fdin, fdout;
char outfilename[PATH_MAX];
unsigned int count = 0;
unsigned char flagopt = 0;
unsigned char tally = 0;
unsigned char next = 0;
if ((argc<2) || (argc>3)) {
printf("Please specify file to read.\n");
return -1;
}
if (3==argc) {
if (!strcmp(argv[2], "header")) flagopt = 1;
if (!strcmp(argv[2], "data")) flagopt = 2;
if (!flagopt) {
printf("Optional flags are \"header\" or \"data\"\n");
return -1;
}
}
if (! flagopt) {
printf("*** WARNING ***\n");
printf("*** ttttt is running in RAW mode.\n");
printf("*** Have you manually included the format flag as the first byte of the block?\n");
printf("*** If not, run again passing 'header' or 'data' as the second parameter.\n");
printf("*** WARNING ***\n\n");
}
fdin = open(argv[1], O_RDONLY);
if (fdin<0) {
printf("Couldn't open %s. for reading\n", argv[1]);
return -1;
}
snprintf(outfilename, PATH_MAX, "%s.block", argv[1]);
outfilename[PATH_MAX - 1] = '\0';
if (! strcmp(argv[1], outfilename)) {
printf("Filename too long - would clobber existing.\n");
close(fdin);
return -1;
}
fdout = open(outfilename, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
if (fdout<0) {
printf("Couldn't open %s for writing.\n", outfilename);
close(fdin);
return -1;
}
while (read(fdin, &next, 1)) {
tally ^= next;
count ++;
};
lseek(fdin, 0, SEEK_SET);
if (flagopt) count++;
char lsb = (count+1)&255;
char msb = ((count+1)>>8)&255;
write(fdout, &lsb, 1);
write(fdout, &msb, 1);
next = 0;
if (flagopt == 2) next = 255;
if (flagopt) {
write(fdout, &next, 1);
tally ^= next;
}
while (read(fdin, &next, 1)) {
write(fdout, &next, 1);
}
write(fdout, &tally, 1);
close(fdout);
close(fdin);
printf("File %s written.\n", outfilename);
count--;
printf("Code length is %d (0x%.4X).\n", count, count);
return 0;
}