19 August 2007

+ Fix so compiles with newish gcc
+ Update asoft_detoken to match documentation found online
+ Create tokenize_asoft

This work was while working on LL_6502
This commit is contained in:
Vince Weaver 2007-08-20 22:26:00 -04:00
parent a3ff5e63e5
commit 8d670e79c6
11 changed files with 315 additions and 131 deletions

24
CHANGES Normal file
View File

@ -0,0 +1,24 @@
1 May 2003
RELEASE 0.0.2
1 June 2003
RELEASE 0.0.4
21 June 2003
+ Fix error where we could allocate a used sector! ARGH!
RELEASE 0.0.5
18 July 2004
+ Minor bug fix
RELEASE 0.0.6
19 August 2007
+ Fix so compiles with newish gcc
+ Update asoft_detoken to match documentation found online
+ Create tokenize_asoft
RELEASE 0.0.7

View File

@ -1,2 +0,0 @@
21 June 2003
+ Fix error where we could allocate a used sector! ARGH!

View File

@ -2,7 +2,7 @@ CC = gcc
C_FLAGS = -O2 -Wall
L_FLAGS =
all: dos33 asoft_detoken mkdos33fs make_b
all: dos33 asoft_detoken mkdos33fs make_b tokenize_asoft
@ -12,7 +12,11 @@ asoft_detoken: asoft_detoken.o
asoft_detoken.o: asoft_detoken.c
$(CC) $(C_FLAGS) -c asoft_detoken.c
tokenize_asoft: tokenize_asoft.o
$(CC) $(L_FLAGS) -o tokenize_asoft tokenize_asoft.o
tokenize_asoft.o: tokenize_asoft.c
$(CC) $(C_FLAGS) -c tokenize_asoft.c
dos33: dos33.o
$(CC) $(L_FLAGS) -o dos33 dos33.o
@ -35,7 +39,7 @@ mkdos33fs.o: mkdos33fs.c dos33.h
install:
cp dos33 asoft_detoken mkdos33fs make_b /usr/local/bin
cp dos33 asoft_detoken mkdos33fs tokenize_asoft make_b /usr/local/bin
clean:
rm -f *~ *.o asoft_detoken dos33 make_b mkdos33fs
rm -f *~ *.o asoft_detoken dos33 make_b mkdos33fs tokenize_asoft

19
README Normal file
View File

@ -0,0 +1,19 @@
dos33fsprogs
by Vince Weaver <vince _at_ deater.net>
These are some tools for manipulating Apple II disk files that
I've written over the years while doing Apple 2 hacking.
make_b : take a machine language blob and give it the size/offset
header needed to BLOAD it from DOS3.3
asoft_detoken: takes an applesoft file obtained with dos33
and converts it to an ASCII text file
tokenize_asoft: takes an ASCII text file and converts it
into a tokenized applesoft file
dos33: a tool for manipulating dos33 .dsk images

2
TODO
View File

@ -4,3 +4,5 @@ defrag utility
test-suite
test mkdosfs copy over DOS functionality
find out why dos33 SAVE puts extra linefeed at end of basic prog?

View File

@ -22,130 +22,36 @@ char applesoft_tokens[][8]={
/* F8 */ "","","","","","(","(","("
};
/*
Integer Basic
#if 0
/* Integer Basic */
$03: :
$04: LOAD
$05: SAVE
$07: RUN
$09: DEL
$0A: ,
$0B: NEW
$0C: CLR
$0D: AUTO
$0F: MAN
$10: HIMEM:
$11: LOMEM:
$12: +
$13: -
$14: *
$15: /
$16: =
$17: #
$18: >=
$19: >
$1A: <=
$1B: <>
$1C: <
$1D: AND
$1E: OR
$1F: MOD
$20: ^
$22: (
$23: ,
$24,
$25: THEN
$26,
$27: ,
$28, $29: \"
$2A: (
$2D: (
$2E: PEEK
$2F: RND
$30: SGN
$31: ABS
$32: PDL
$34: (
$35: +
$36: -
$37: NOT
$38: (
$39: =
$3A: #
$3B: LEN (
$3C: ASC (
$3D: SCRN (
$3E: ,
$3F: (
$40: $
$42: (
$43,
$44: ,
$45,
$46,
$47: ;
$48,
$49: ,
$4A: ,
$4B: TEXT
$4C: GR
$4D: CALL
$4E,
$4F: DIM
$50: TAB
$51: END
$52, $53, $54: INPUT
$55: FOR
$56: =
$57: TO
$58: STEP
$59: NEXT
$5A: ,
$5B: RETURN
$5C: GOSUB
$5D: REM
$5E: LET
$5F: GOTO
$60: IF
$61,
$62: PRINT
$63: PRINT
$64: POKE
$65: ,
$66: COLOR=
$67: PLOT
$68: ,
$69: HLIN
$6A: ,
$6B: AT
$6C: VLIN
$6D: ,
$6E: AT
$6F: VTAB
$70,
$71: =
$72: )
$74: LIST
$75: ,
$77: POP
$79: NO DSP
$7A: NO TRACE
$7B,
$7C: DSP
$7D: TRACE
$7E: PR #
$7F: IN #
*/
char integer_tokens[][8]={
/* 00 */ "","","",":","LOAD","SAVE","","RUN",
/* 08 */ "","DEL",",","NEW","CLR","AUTO","","MAN",
/* 10 */ "HIMEM:","LOMEM:","+","-","*","/","=","#",
/* 18 */ ">=",">","<=","<>","<"," AND"," OR"," MOD",
/* 20 */ "^","","(",",",""," THEN","",",",
/* 28 */ "\"","\"","(","","","("," PEEK","RND",
/* 30 */ "SGN","ABS","PDL","","(","+","-","NOT",
/* 38 */ "(","=","LEN (","ASC (","SCRN (",","," (",
/* 40 */ "$","(","",",","","",";",
/* 48 */ "",",",",","TEXT","GR","CALL","","DIM",
/* 50 */ "TAB","END","","","INPUT","FOR","=","TO",
/* 58 */ " STEP","NEXT",",","RETURN","GOSUB","REM","LET","GOTO",
/* 60 */ "IF","","PRINT","PRINT"," POKE",",","COLOR=","PLOT",
/* 68 */ ",","HLIN",","," AT","VLIN",","," AT","VTAB",
/* 70 */ "","=",")","","LIST",",","","POP",
/* 78 */ "","NO DSP","NO TRACE","","DSP","TRACE","PR #","IN #"
};
#endif
int main(int argc, char **argv) {
int ch1,i;
unsigned char size1,size2;
unsigned char line1,line2;
unsigned char eight,line_length;
int size1,size2;
int line1,line2;
int link1,link2,link;
/* read size, first two bytes */
@ -153,17 +59,24 @@ int main(int argc, char **argv) {
size2=fgetc(stdin);
while(!feof(stdin)) {
/* link points to the next line */
/* assumes asoft program starts at address $801 */
link1=fgetc(stdin);
link2=fgetc(stdin);
link=(link1<<8)|link2;
/* link==0 indicates EOF */
if (link==0) goto the_end;
line_length=fgetc(stdin);
eight=fgetc(stdin); /* sometimes 8, sometimes 9? */
if (eight==0) goto the_end;
/* line number is little endian 16-bit value */
line1=fgetc(stdin);
line2=fgetc(stdin);
if (feof(stdin)) goto the_end;
printf("%4d ",(((int)line2)<<8)+line1);
printf("%4d ",((line2)<<8)+line1);
/* repeat until EOL character (0) */
while( (ch1=fgetc(stdin))!=0 ) {
/* if > 0x80 it's a token */
if (ch1>=0x80) {
fputc(' ',stdout);
for(i=0;i<strlen(applesoft_tokens[ch1-0x80]);i++) {
@ -171,7 +84,11 @@ int main(int argc, char **argv) {
}
fputc(' ',stdout);
}
else fputc(ch1,stdout);
/* otherwise it is an ascii char */
else {
fputc(ch1,stdout);
}
}
printf("\n");
}

View File

@ -843,7 +843,7 @@ repeat_tsl:
ts_s=tslist[TSL_NEXT_SECTOR];
if (!((ts_s==0) && (ts_t==0))) goto repeat_tsl;
continue_dump:
continue_dump:;
}
catalog_t=buffer[CATALOG_NEXT_T];

BIN
tests/GR Normal file

Binary file not shown.

BIN
tests/SINCOS Normal file

Binary file not shown.

220
tokenize_asoft.c Normal file
View File

@ -0,0 +1,220 @@
#include <stdio.h>
#include <string.h> /* strlen() */
#include <stdlib.h> /* exit() */
/* TODO */
/* match lowecase tokens as well as upper case ones */
/* Info from http://docs.info.apple.com/article.html?coll=ap&artnum=57 */
/* In memory, applesoft file starts at address $801 */
/* format is <LINE><LINE><LINE>$00$00 */
/* Where <LINE> is: */
/* 2 bytes (little endian) of LINK indicating addy of next line */
/* 2 bytes (little endian) giving the line number */
/* a series of bytes either ASCII or tokens (see below) */
/* a $0 char indicating end of line */
/* Starting at 0x80 */
char applesoft_tokens[][8]={
/* 80 */ "END","FOR","NEXT","DATA","INPUT","DEL","DIM","READ",
/* 88 */ "GR","TEXT","PR #","IN #","CALL","PLOT","HLIN","VLIN",
/* 90 */ "HGR2","HGR","HCOLOR=","HPLOT","DRAW","XDRAW","HTAB","HOME",
/* 98 */ "ROT=","SCALE=","SHLOAD","TRACE","NOTRACE","NORMAL","INVERSE","FLASH",
/* A0 */ "COLOR=","POP","VTAB ","HIMEM:","LOMEM:","ONERR","RESUME","RECALL",
/* A8 */ "STORE","SPEED=","LET","GOTO","RUN","IF","RESTORE","&",
/* B0 */ "GOSUB","RETURN","REM","STOP","ON","WAIT","LOAD","SAVE",
/* B8 */ "DEF FN","POKE","PRINT","CONT","LIST","CLEAR","GET","NEW",
/* C0 */ "TAB","TO","FN","SPC(","THEN","AT","NOT","STEP",
/* C8 */ "+","-","*","/","^","AND","OR",">",
/* D0 */ "=","<","SGN","INT","ABS","USR","FRE","SCRN (",
/* D8 */ "PDL","POS","SQR","RND","LOG","EXP","COS","SIN",
/* E0 */ "TAN","ATN","PEEK","LEN","STR$","VAL","ASC","CHR$",
/* E8 */ "LEFT$","RIGHT$","MID$","","","","","",
/* F0 */ "","","","","","","","",
/* F8 */ "","","","","","(","(","("
};
#if 0
/* Integer Basic */
char integer_tokens[][8]={
/* 00 */ "","","",":","LOAD","SAVE","","RUN",
/* 08 */ "","DEL",",","NEW","CLR","AUTO","","MAN",
/* 10 */ "HIMEM:","LOMEM:","+","-","*","/","=","#",
/* 18 */ ">=",">","<=","<>","<"," AND"," OR"," MOD",
/* 20 */ "^","","(",",",""," THEN","",",",
/* 28 */ "\"","\"","(","","","("," PEEK","RND",
/* 30 */ "SGN","ABS","PDL","","(","+","-","NOT",
/* 38 */ "(","=","LEN (","ASC (","SCRN (",","," (",
/* 40 */ "$","(","",",","","",";",
/* 48 */ "",",",",","TEXT","GR","CALL","","DIM",
/* 50 */ "TAB","END","","","INPUT","FOR","=","TO",
/* 58 */ " STEP","NEXT",",","RETURN","GOSUB","REM","LET","GOTO",
/* 60 */ "IF","","PRINT","PRINT"," POKE",",","COLOR=","PLOT",
/* 68 */ ",","HLIN",","," AT","VLIN",","," AT","VTAB",
/* 70 */ "","=",")","","LIST",",","","POP",
/* 78 */ "","NO DSP","NO TRACE","","DSP","TRACE","PR #","IN #"
};
#endif
#define LOW(_x) ((_x)&0xff)
#define HIGH(_x) (((_x)>>8)&0xff)
#define MAXSIZE 65535
/* File cannot be longer than 64k */
unsigned char output[MAXSIZE+1];
char *line_ptr;
int line=0;
char input_line[BUFSIZ];
static void show_problem(char *line_ptr) {
int offset,i;
offset=(int)(line_ptr-input_line);
fprintf(stderr,"%s",input_line);
for(i=0;i<offset;i++) fputc(' ',stderr);
fprintf(stderr,"^\n");
}
static int getnum(void) {
int num=0;
/* skip any whitespace */
while((*line_ptr<=' ') && (*line_ptr!=0)) line_ptr++;
while (*line_ptr>' ') {
if ((*line_ptr<'0')||(*line_ptr>'9')) {
fprintf(stderr,"Invalid line number line %d\n",line);
show_problem(line_ptr);
exit(-1);
}
num*=10;
num+=(*line_ptr)-'0';
line_ptr++;
}
if (!line_ptr) {
fprintf(stderr,"Missing line number line %d\n",line);
exit(-1);
}
return num;
}
static int in_quotes;
static int find_token() {
int ch,i;
ch=*line_ptr;
/* don't skip whitespace in quotes */
if (!in_quotes) {
while(ch<=' ') {
if ((ch=='\n') || (ch=='\r') || (ch=='\0')) {
return 0;
}
line_ptr++;
ch=*line_ptr;
}
}
/* toggle quotes mode */
if (ch=='\"') in_quotes=!in_quotes;
/* don't tokenize if in quotes */
if (!in_quotes) {
// fprintf(stderr,"%s",line_ptr);
for(i=0;i<107;i++) {
if (!strncmp(line_ptr,applesoft_tokens[i],strlen(applesoft_tokens[i]))) {
// fprintf(stderr,"Found token %x (%s) %d\n",0x80+i,applesoft_tokens[i],i);
line_ptr+=strlen(applesoft_tokens[i]);
return 0x80+i;
}
// fprintf(stderr,"%s ",applesoft_tokens[i]);
}
}
// fprintf(stderr,"\n");
/* not a token, just ascii */
line_ptr++;
return ch;
}
static void check_oflo(int size) {
if (size>MAXSIZE) {
fprintf(stderr,"Output file too big!\n");
exit(-1);
}
}
int main(int argc, char **argv) {
int offset=2,i;
int linenum,link_offset;
int link_value=0x801; /* start of applesoft program */
int token;
while(1) {
/* get line from input file */
line_ptr=fgets(input_line,BUFSIZ,stdin);
line++;
if (line_ptr==NULL) break;
linenum=getnum();
if (linenum>65535) {
printf("Invalid line number %d\n",linenum);
exit(-1);
}
link_offset=offset;
check_oflo(offset+4);
output[offset+2]=LOW(linenum);
output[offset+3]=HIGH(linenum);
offset+=4;
while(1) {
token=find_token();
output[offset]=token;
offset++;
check_oflo(offset);
if (!token) break;
}
/* 2 bytes is to ignore size from beginning of file */
link_value=0x801+(offset-2);
/* point link value to next line */
check_oflo(offset+2);
output[link_offset]=LOW(link_value);
output[link_offset+1]=HIGH(link_value);
}
/* set last link field to $00 $00 which indicates EOF */
check_oflo(offset+2);
output[offset]='\0';
output[offset+1]='\0';
offset+=2;
/* Set filesize */
/* -1 to match observed values */
output[0]=LOW(offset-1);
output[1]=HIGH(offset-1);
/* output our file */
for(i=0;i<offset;i++) putchar(output[i]);
return 0;
}