@L}5 _$% l0$)$$Hȱ$ UhL" `e$$%`$%`  R@P!( L(1   Y I`  d  Ld M * @  $ % CC$$)%1 Udߥ$9%: !0 S$% DD˙`  }J)Lr d M * @  $ % CC$$)%1 Udߥ$9%: !0 S$%} DD˙`  }J)Lr J  ((  p L ()   J}L= ( L 0q A    IB JC;? D W } LL  ` W )LA!  ߰")-݆ p" } $G@LL 08`Q")<2Q0 -G$Ș݆ UL# ; p8(()(0ʥ)NQ` }$GȘ݆LU )L ݆ L GȘ ݆LL )W>Z   HH)H }p h  hyhy D L> L JJ    ! LA*` BF }7'8  M HN H` 8 Z  \LdJJ!"! GFE@F (!L }EE !E^ ^ E E7EȩEdE/EȩE  D } .L }  ;F d  ;?F7F? ( .   Z D LL d } . D  L    p  E` , d)  D L) 0BM݊L݉} ML  N݆ L NLML [ TEqEHȱEqEh 0Gȹ G} HLL GɛL  LFREE SECTORS G) *Gȩ GȽG GȌ*jj >G} C8jJ3j2CD( C202C ԠBX` N 1? l LlD:RAMDISK}.COMLu L1 L ;LHL  T`  `1  ɐ     `TU  } L ? .  t`GBJ ~DEHI B V0dV!}QDEHI VF9 ,0 ,0 s0hhL  L` H hDHEh"}DEL8HI4 0 HI,0 0  9 .G VLO#},0 L4*IJ`llD1:AUTORUN.SYSNEED MEM.SAV TO LOAD THIS FILE.D1:MEM.SAV J y08 B|DEHI$} V0 0`B;DEL`?<0LV`@ʆ v s? F0Ξ05: [ BDEHI%} VY8 B V  @  /DE `E:D1:DUP.SYSERROR-SAVING USER MEMORY ON DISKTYPE Y TO &}STILL RUN DOS B;DE J  (` 9 V⪍ ઍ  -'}LLu ÝDEHILV 9 .l 9 .l  `` s$B BH(}I|DE V BLV nB,DE JLV B V BLVDEIʩ BꭝLu  } 3E:}DISK OPERATING SYSTEM II VERSION COPYRIGHT 1984 ATARI CORP.A. DISK DIRECTORY I. FORMAT DISKB. RUN CARTRIDG*}E J. DUPLICATE DISKC. COPY FILE K. BINARY SAVED. DELETE FILE(S) L. BINARY LOADE. RENAME FILE M. RUN AT ADDRES+}SF. LOCK FILE N. CREATE MEM.SAVG. UNLOCK FILE O. DUPLICATE FILEH. WRITE DOS FILES P. FORMAT SINGLEL !N',}#"&))9(&*)/h)''-&؆莟R'S  vL/ˢ L }Insert DOS 2.0s, type Y Λx -}DEfHI 1莏#q! @ y0ɛ8A0,' ȅ 1 1ild! 1L!NO SUCH ITEMSELECT.} ITEM OR FOR MENU! 0 .z:*{}.|{ 1 0 0JB 18L%|DL/}%DIRECTORY--SEARCH SPEC,LIST FILE?[# 0 0 &|D3" 1L!NOT A DISK FILEN !B 1L!E# 1 !BD0}ED:}:1BJ|DE 1DEBHI 1 h0ߢ 0.1}  0?詛 1 y0YЛ 1 ;#L" ;#L! BL1TYPE "Y" TO DELETE...DELETE FILE SPEC2}COPY--FROM, TO?OPTION NOT ALLOWED736 FREE SECTORS COPYING---D1:DIRECK.COMl# 0|D .L/%#3}##JB|DE 1BHID#E 1#0: B 1L!#͑### B 1#c$0SY4}S1}:## # # .#Ƚ# # 𩛙## 1,#PD#ELJ- <.BJD#E 5}1 1HH 0hh|DL%1}:̳# L% #D#EL% 1 0 . .0O% 1L!WILD CARDS NOT A6}LLOWED IN DESTINATION 0 <.|K}N 2 FORMAT. t* 5) 1L!`) 0NΞ 0 L1) 1 L!BAD LOAD FILELOAD FROM WHAT FILE?) 0 ?}0#B 1L!WHAT FILE TO LOCK?) 0 0$B 1L!WHAT FILE TO UNLOCK?DUP DISK-SOURCE,DEST DRIVES?TYPE "Y" IF OK TO US@}E PROGRAM AREACAUTION: A "Y" INVALIDATES MEM.SAV.FE! +L1   `*  70 2 2A} 0.* 1 y0 0)INSERT BOTH DISKS, TYPE RETURN^, 1 y038逍 N, 1L! ,B}C, t*  Lx+, 0 ^, 1 y0 , ,0,0 ,L+ ,I0 ,Vǭ0C}Ξ, 0 }, 1 y0C,ШC, 0K'!" H H 'h h Lx+!EF 5L1L!D,I,HhD}` NOT ENOUGH ROOMINSERT SOURCE DISK,TYPE RETURNINSERT DESTINATION DISK,TYPE RETURNE}`  `8 rL1`-* 1P* 1 y0Y`hhL!NAME OF FILE TO MOVE?- 0 0|DL% <.F},^ 1 70 0 .@L# .BJ 1  DEHIB V L1 ,} 1 70,L.  G}JB|,#P#DE 1 HI BDEHHII 1 B 1 ,^ 1 70,0La- B V,#PH},^ 1 70 0L#L!-* 1P* 1 y0Yj383}mm ݭI}}`8}``|* ? ɛ,`|:-)| / 1L!`DESTINATION CANT BE DOJ}S.SYS0 0H{ 24Δ 28/L!/) 2 Π 2 0 ξK}hAΞB,0 J 1 BDEHI,HÝDE 1HIHIDELSAVE-GIVE L}FILE,START,END(,INIT,RUN)O S0 1`BDEPHI V` S0H 1 L!M}0 0 1L~0`PLEASE TYPE 1 LETTER,0`hhL! 70 1L0L<1 ,;ɛ7,"ɛ:ݦ1ݥN}A"D|ݤD|ȩ:|ȩ|ɛ,,(/+.ީ1 1,ɛ`轤{NAMEO} TOO LONG B VL!` L1I H1EΝDL1|mDiE` V0`8d/8 i:222 1 LP}!ERROR- 138ɛ+,' 20*.. өr2 1``2TOO MANY DIGITSINVALID HEXAQ}DECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8uR} ECIMAL PARAMETER800 0 8 00`,0'D800 H,ɛh`2L1NEED D1 THRU D8u /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */T} /* A65: a macro assembler for 6502's. a65 [-o foo.obj] [-l foo.l] f1.m65 f2.m65... */ #define VERSION "1.U}0" #include #include "symtab.h" #include "parse.h" #include "util.h" #define MAIN 1 #include "global.h" V} /* #define LIST ... turn this on for listing code */ /* #define EITHER .. turn this if ever get around to making the W}assembler produce either rel or abs files */ FILE * inf; FILE * outf; char * in_name[16]; int n_files; char * out_nameX}; #ifdef DEBUG char * sym_name; #endif extern int _start; /* util fun for grokking arglist */ char * arg_value(arY}gs, arg_idx, n_args) char * args[]; int * arg_idx; /* we might increment this */ int n_args; { int i; i = *arZ}g_idx; if (args[i][2]) /* was there something after the '-x'? */ return(args[i] + 2); /* yes, just return that */ [}i++; /* try the next arg */ if (i >= n_args) /* no next arg? */ return(NULL); if (*args[i] == '-') /* next arg\} not a value? */ return(NULL); *arg_idx = i; /* put updated value back */ return(args[i]); /* and return this ar]}g */ } #ifdef M6502 char argbuf[80]; #endif main(argc, argv) int argc; char ** argv; { int i, local_pass, fidx^}, code, class; /* printf("base = %X\n", &_start); */ n_files = 0; /* no files yet */ #ifdef LIST list_p = 0; _}/* no listing */ #endif #ifdef DEBUG sym_name = 0; /* no sym file name yet */ #endif #ifdef EITHER rel_p = 0; /* `}no relocatable output */ #endif verbose = 0; #ifdef M6502 /* if no args, prompt for 'em */ if (argc < 2) argc = a}readargs("RA65>", argbuf, argv + 1) + 1; #endif for (i = 1 ; i < argc ; i++) { /* printf("considering arg %d '%s'\n"b}, i, argv[i]); */ if (argv[i][0] == '-') { switch (argv[i][1]) { #ifdef LIST case 'l': case 'L': { c} list_p = 1; list_name = arg_value(argv, &i, argc); break; } #endif case 'o': case 'O': { out_nd}ame = arg_value(argv, &i, argc); break; } #ifdef DEBUG case 's': case 'S': { sym_name = arg_value(are}gv, &i, argc); if (!sym_name) sym_name = "foo.sym"; break; } #endif #ifdef EITHER /* this is always of}n for this version of the assembler */ case 'r': case 'R': { rel_p = 1; if (verbose) printf("Relocatg}able output\n"); break; } #endif case 'v': case 'V': { verbose++; break; } } } h} else { in_name[n_files] = frob_name(argv[i]); n_files++; if (verbose) printf("Input file %d %s\n", n_files,i} argv[i]); } } if (verbose) printf("RA65 v %s\n", VERSION); if (n_files < 1) { printf("Try A65 ...j}\n"); exit(1); } if (verbose) printf("RA65 v %s\n", VERSION); init_sym(); #ifdef LIST init_list(); #endik}f init_gen(); for (local_pass = 0 ; local_pass < gen_n_passes() ; local_pass++) { errcount = 0; pass = local_pal}ss; pc = 0; disabled = 0; output_p = (pass == (gen_n_passes() - 1)); if (output_p != 0) { gen_o_open(out_name, m}in_name[0]); } for (fidx = 0 ; fidx < n_files ; fidx++) { end_file = 0; inf = fopen(in_name[fidx], "r"); /* prn}intf("open('%s')->%X\n", in_name[fidx], inf); */ line_nbr = 0; while (!end_file && read_line(inf, line)) { if (o}verbose) printf("%4d: '%s'\n", line_nbr, line); line_nbr++; #ifdef LIST line_listed_p = 0; #endif obj_counp}t = 0; parse_line(line, &p); if (p.opcode) { if (opcode_p(p.opcode, &code, &class)) { if (!disaq}bled) assemble_op(code, class, &p.arg[0]); } else if (!do_pseudo()) barf("Bogus linr}e"); } else if (!disabled) gen_label(); #ifdef LIST list_line(0); #endif } fclose(inf); s} } #ifdef DEBUG if (sym_name) dump_syms(); #endif if (output_p) gen_o_close(); if (errcount) printf("%d ert}rors"); } } UG if (sym_name) dump_syms(); #endif if (output_p) gen_o_close(); if (errcount) printf("%d er-*- Mode: Text -*- This is the copyright notice for RA65, LINK65, LIBR65, and other Atari 8-bit programs. Said progra v}ms are Copyright 1989, by John R. Dunning. All rights reserved, with the following exceptions: Anyone may copy or re w}distribute these programs, provided that: 1: You don't charge anything for the copy. It is permissable to charge a x} nominal fee for media, etc. 2: All source code and documentation for the programs is made available as part of the y}distribution. 3: This copyright notice is preserved verbatim, and included in the distribution. You are allo z}wed to modify these programs, and redistribute the modified versions, provided that the modifications are clearly noted. {} There is NO WARRANTY with this software, it comes as is, and is distributed in the hope that it may be useful. T |}his copyright notice applies to any program which contains this text, or the refers to this file. This copyright noti }}ce is based on the one published by the Free Software Foundation, sometimes known as the GNU project. The idea is the same ~} as theirs, ie the software is free, and is intended to stay that way. Everybody has the right to copy, modify, and re- di }stribute this software. Nobody has the right to prevent anyone else from copying, modifying or redistributing it. re- di u /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */} /* error stuff */ #include #include "global.h" #ifdef M6502 barf() { int * arg; arg = &arg; } /* point at self */ arg += arg[1] + 1; /* add next word; arg count, plus 1 */ fprintf(stderr, *arg, *--arg, *--arg, *-}-arg); fprintf(stderr, "\n"); exit(1); } #else barf(msg, arg1, arg2, arg3) char * msg; int arg1, arg2, arg3; { } list_line(1); printf("Error: "); printf(msg, arg1, arg2, arg3); printf("\n"); errcount++; } #endif 3; { w /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */} /* expression evaluator */ #include "eval.h" #include "symtab.h" #include "global.h" char tbuf[32]; char * eva}l_internal(); /* forward decl */ int digit(c) char c; { if ((c >= '0') && (c <= '9')) return(c - '0'); else} if ((c >= 'A') && (c <= 'F')) return(c - 'A' + 10); else return(-1); } char * grok_fixnum(str, base, result)} char * str; int base; int * result; { int d; char * s; int neg; s = str; *result = 0; neg = 0; }if (*s == '-') { neg = 1; s++; } while (((d = digit(toupper(*s))) >= 0) && (d <= base)) { *result = *result * }base + d; s++; } if (neg) { *result = -(*result); } return(s); } /* eval one q, return updated string p}tr */ char * eval_q(str, val, expr_flags, sym_ref) char * str; int * val; int * expr_flags; struct sym ** sym_ref; { } char c; char * p; struct sym * sy; int i; while((c = *str) && white_p(c)) str++; if (id_start_p(c)) { }/* symbol */ p = tbuf; *p++ = *str++; while(id_char_p(*str)) *p++ = *str++; *p = '\0'; if ((tbuf[0] == '.') && (}tbuf[1] == '\0')) *val = pc; else { sy = find_sym(tbuf, 1); if ((!(sy->flags & DEFINED)) && (pass == 1)) } barf("undefined symbol '%s'", tbuf); if (!(sy->flags & DEFINED)) *expr_flags |= E_UNDEF; if (!(sy->flags & ABS)) } *expr_flags |= E_REL; *sym_ref = sy; *val = sy->value; } } else if (c == '$') /* hex constant */ st}r = grok_fixnum(str + 1, 16, val); else if (c == '0') /* octal constant */ str = grok_fixnum(str, 8, val); el}se if (c == '@') /* octal constant */ str = grok_fixnum(str + 1, 8, val); else if (c == '%') /* binary constan}t */ str = grok_fixnum(str + 1, 2, val); else if (c == '^') /* constant with radix */ { switch(str[1]) { } case 'o': { str = grok_fixnum(str + 2, 8, val); break; }; case 'x': { str = grok_fixnum(str + 2, 16, val); break; }; c}ase 'd': { str = grok_fixnum(str + 2, 10, val); break; }; } } else if (((c > '0') && (c <= '9')) || (c == '-')) }/* decimal constant */ str = grok_fixnum(str, 10, val); else if (c == '\'') { *val = str[1]; str += 2; } } else if (c == '*') { *val = pc; str++; } else if (c == '<') str = eval_internal(str + 1, val, expr_fl}ags, sym_ref); else barf("eval error: bogus operand '%c'", c); return(str); } char * binop(str, accum, expr_}flags, sym_ref) char * str; int * accum; int * expr_flags; struct sym ** sym_ref; { int val; char c; c = *str}++; str = eval_q(str, &val, expr_flags, sym_ref); switch (c) { case '+': { *accum += val; break; } case '-': { *a}ccum -= val; break; } case '*': { *accum *= val; break; } case '/': { *accum /= val; break; } case '&': { *accum &= val}; break; } case '|': case '!': { *accum |= val; break; } } return(str); } char * eval_internal(str, val, expr_fl}ags, sym_ref) char * str; int * val; int * expr_flags; struct sym ** sym_ref; { int accum; str = eval_q(str, &ac}cum, expr_flags, sym_ref); while (white_p(*str)) str++; while (*str) /* more expr? */ switch(*str) { case }'+': case '-': case '*': case '/': case '&': case '|': case '!': { str = binop(str, &accum, expr_flags, sym_ref); } break; } case '\\': { (*expr_flags) |= E_LO_BYTE; accum &= 0xFF; str++; break; } case '}^': { (*expr_flags) |= E_HI_BYTE; accum >>= 8; str++; break; } case '>': /* end recursive eval */} { *val = accum; return(++str); } default: str++; }; *val = accum; return(str); } int eval}(str, expr_flags, sym_ref) char * str; int * expr_flags; struct sym ** sym_ref; { int accum; *expr_flags = 0; } *sym_ref = (struct sym *)0; eval_internal(str, &accum, expr_flags, sym_ref); #ifdef DEBUG printf("eval('%s')->%X fl}ags %X sym %X\n", str, accum, *expr_flags, *sym_ref); #endif return(accum); } #ifdef DEBUG printf("eval('%s')->%X flT /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */} /* defs for the evaluator */ /* these are bits in the 'expr_flags' byte returned from eval */ #define E_UNDEF 1 /}* expr contains an undefined sym */ #define E_REL 2 /* expr contains a relative reference */ #define E_HI_BYTE 8 /* hi part} of some value */ #define E_LO_BYTE 16 /* lo part */ expr contains a relative reference */ #define E_HI_BYTE 8 /* hi part7 /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */} /* entry pts for code generator */ extern genlit(); extern genbyte(); extern genword(); extern gen_label(); extern} gen_n_passes(); or code generator */ extern genlit(); extern genbyte(); extern genword(); extern gen_label(); extern /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */ } /* global vars for a65 */ #ifdef MAIN #define ID #else #define ID extern #endif ID char line[256]; /* line buf }fer */ ID struct parse p; /* parsed line */ ID int line_nbr; /* current line number */ ID char * list_name; /* name o }f file we're listing to, if any */ ID int list_pc; /* pc before read line */ ID char list_pc_p; /* lsit pc even if no ob }ject bytes */ ID char obj[4]; /* generated code */ ID int obj_count; /* n valid bytes */ ID char line_listed_p; /* if }text this line has been printed */ ID int list_v; /* other value to show up in listing */ ID char list_v_p; /* use that }instead of obj bytes */ ID char page_title[64]; /* page title string */ ID char page_subttl[64]; /* subtitle */ ID int }page_nbr; /* page number */ ID int line_in_page; ID int errcount; ID char output_p; /* flag for generating output */ } /* conditional stuff */ ID char disabled; /* if we've evaluated an IF that was false */ /* global assembler state */ } ID unsigned int pc; /* pc for assembler */ #define SEG_ABS 0 /* we're doing absolute defs */ #define SEG_REL 1 /* }we're doing relative defs */ ID int curr_seg; /* current state; one of the above values */ ID unsigned int abs_pc, rel_pc; } /* last known pc, each seg */ ID char rel_p; /* if relocatable output */ ID int pass; /* what pass we're doing */ I }D int end_file; /* if we saw a .end pseudo */ ID char list_p; /* generating listing */ ID char verbose; /* various v }erbosities */ /* if we saw a .end pseudo */ ID char list_p; /* generating listing */ ID char verbose; /* various v  /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */$} /* defs for library files #ifndef _TYPES_ #include "types.h" #endif A library file consists of a header lump, as $}described below, some number of module descriptors, and images of files. magic number identifies library files */ #defin$}e LIBR_HEADER 0xFCFC struct librfile { USHORT l_header; /* magic num, as above */ USHORT type; /* type of library, $}values below */ USHORT n_modules; /* number modules this library */ USHORT l_flags; /* library flags, defined below */ $} }; /* library types */ #define LT_OLB 1 /* an object library */ /* flags for object libraries */ #define LOLB_DEF $}0x0001 /* library contains a symbol dictionary */ /* a module of the library */ struct librmod { char m_name[12]; /$}* entry name, typically file name */ USHORT m_nbytes; /* n bytes in entry */ }; uct librmod { char m_name[12]; /$X /* This software is copyright 1989 by John Dunning. See the file 'COPYLEFT.JRD' for the full copyright notice. */(} /* object library maintainer for atari 8-bit .obj files. later, maybe random other kinds of files too. */ #defin(}e VERSION "1.0" #include #include #include #ifdef M6502 /* lots of things in here are d(}efined to use 16-bit values */ #define USHORT int /* other stuff might as well go here */ #define unlink delete #define m(}alloc xmalloc #else #define USHORT unsigned short #endif #include "symtab.h" #include "obj.h" #include "libr.h" (}#ifdef M6502 /* do this part differently on 800 */ #else #include #include /* for _dta, for file size(} */ #endif char * lfname; /* name of the file we've got open */ int in_lfd; /* fd of the file we've got open */ int(} out_lfd; /* fd output, if writing */ int obj_lfd; /* fd for .obj files */ struct librfile lfile; /* header of the f(}ile we've got open */ int input_fd; /* fd of obj files we read */ #ifdef __GNUC__ int _stksize = 16384; #endif /(}* defs for keeping track of what we're doing when maintaining a library */ /* we build a linked list of these when adding/(}deleting etc. If we were writing this in a real language, we'd do this with included defstructs, but since we must u(}se C, we make the first part of this look just like the def of a librmod, in libr.h. */ struct entry { char e_nam(}e[12]; /* the file name of this entry */ USHORT e_nbytes; /* nbytes this entry */ struct entry * e_next; /* next entry */(} int new; /* if this is a new entry */ int skip; /* this is an old entry being skipped */ }; #define SKIP_REPLACE (}1 #define SKIP_DELETE 2 char * skip_names[] = { "", "Replacing", "Deleting" }; struct entry * lfile_components; (} #ifdef M6502 /* debug code */ char * xmalloc(n) int n; { char * foo; foo = pmalloc(n); /* printf("xm(}alloc(%d)->%x; sp %x\n", n, foo, &foo); */ bzero(foo, n); return(foo); } #endif /* util routines */ min(x, y) (}int x,y; { if (x < y) return(x); else return(y); } #ifndef M6502 unsigned #endif char read8(input_f(}d) int input_fd; { #ifdef M6502 unsigned #endif char foo; read(input_fd, &foo, 1); return(foo); } USHORT (}read16(input_fd) int input_fd; { return(read8(input_fd) | (read8(input_fd) << 8)); } write8(ch) char ch; { writ(}e(out_lfd, &ch, 1); } write16(sh) USHORT sh; { write8(sh & 0xFF); write8(sh >> 8); } int open_carefully(name,(} mode, must_exist) char * name; int mode; int must_exist; { int fd; #ifdef M6502 char buf[64]; /* prepend a D: if(} necessary */ if (!strchr(name, ':')) { strcpy(buf, "D:"); strcat(buf, name); name = buf; } #endif printf("o(}pen('%s', %x)->", name, mode); fd = open(name, mode); if ((fd < 0) && must_exist) barf("Can't open '%s'\n", name); (} printf("%d\n", fd); return(fd); } read_header(fd) int fd; { lfile.l_header = read16(fd); lfile.type = read1(}6(fd); lfile.n_modules = read16(fd); lfile.flags = read16(fd); /* #ifdef M6502 printf("read_header: %x %x %x %x\n"(}, lfile.l_header, lfile.type, lfile.n_modules, lfile.flags); #endif */ } read_mdesc(fd, mod) int fd; struct librmo(}d * mod; { read(fd, mod->m_name, 12); mod->m_nbytes = read16(fd); } /* build the module list for an existing file.(} assume the next byte to be read is the first one of the module structs. assume lfile is valid */ build_modlist(f(}d) int fd; { int i; struct entry * elt; struct entry * prev_elt; lfile_components = elt = #ifdef M6502 (} 0; #else (struct entry * )NULL; #endif for (i = 0 ; i < lfile.n_modules ; i++) { prev_elt = elt; elt = #if(}def M6502 malloc(sizeof(struct entry)); #else (struct entry *)malloc(sizeof(struct entry)); #endif read(fd, elt->e_(}name, 12); elt->e_nbytes = read16(fd); /* #ifdef M6502 printf("build_modlist: got name '%s' nbytes %d\n", elt->e_na(}me, elt->e_nbytes); #endif */ elt->new = 0; elt->skip = 0; if (prev_elt) prev_elt->e_next = elt; else lfi(}le_components = elt; } } string_upcase(str) char * str; { for ( ; *str ; str++) if (islower(*str)) *str = to(}upper(*str); } int string_equal(str1, str2) char * str1, * str2; { for ( ; *str1 || *str2 ; str1++, str2++) if (*s(}tr1 != *str2) return(0); return(1); } /* not needed? char * string_copy(str) char * str; { char * t = (char * )m(}alloc(strlen(str) + 1); strcpy(t, str); return(t); } */ string_pad(target, source, nbytes) char * target; char *(} source; int nbytes; { int i; for (i = nbytes ; (i > 0) && (*source) ; i--) *target++ = *source++; for ( ; i(} > 0 ; i--) *target++ = ' '; } string_trim(target, source, nbytes) char * target; char * source; int nbytes; { f(}or ( ; ((nbytes > 0) && (*source != ' ')) ; nbytes--) *target++ = *source++; *target = '\0'; } /* maintaining entry (}list */ struct entry * last_entry() { struct entry * elt; for (elt = lfile_components ; elt && elt->e_next ; el(}t = elt->e_next) ; return(elt); } /* delete an entry. return 1 if found it */ int del_entry(name, why) char * n(}ame; int why; { struct entry * elt; char buf[80]; int found; found = 0; string_upcase(name); for (elt =(} lfile_components ; elt ; ) { string_trim(buf, elt->e_name, 12); if (string_equal(name, buf)) { /* set skip bit i(}n this one; we always add new entries at the end */ elt->skip = why; found++; } if (elt) elt = elt->e_ne(}xt; } return(found); } /* return 1 if replaced old entry */ int add_entry(name, nbytes) char * name; int nbytes; (} { struct entry * elt; struct entry * prev_elt; int replaced; char buf[14]; prev_elt = #ifdef M6502 NUL(}L; #else (struct entry *)NULL; #endif replaced = del_entry(name, SKIP_REPLACE); prev_elt = last_entry(); /* n(}ow make the new one */ elt = #ifdef M6502 malloc(sizeof(struct entry)); #else (struct entry *)malloc(sizeof(struct (}entry)); #endif #ifdef M6502 /* dump drivespec if any */ { char * p; if (p = strchr(name, ':')) (} name = p + 1; } #endif /* elt->e_name = string_copy(name); */ string_pad(elt->e_name, name, 12); elt->new = 1;(} /* get this from file, not libr */ elt->e_nbytes = nbytes; if (prev_elt) prev_elt->e_next = elt; else lfil(}e_components = elt; return(replaced); } /* on 800, this will have to read and count the whole file, unless we're u(}sing Spartados */ int file_nbytes(name) char * name; { #ifdef M6502 char buf[64]; int fd; int siz, total; (} fd = open_carefully(name, O_RDONLY, 1); for (total = 0 ; ((siz = read(fd, buf, 64)) > 0) ; ) total += siz; printf("c(}lose->%x\n", close(fd)); printf("%s is %d bytes long\n", name, total); return(total); #else struct stat st; (}if (stat(name, &st) < 0) return(-1); else return(st.st_size); #endif } /* zzz */ #ifdef M6502 barf() { (}int * arg; arg = &arg; /* point at self */ arg += arg[1] + 1; /* add next word; arg count, plus 1 */ fprintf(st(}derr, *arg, *--arg, *--arg, *--arg); fprintf(stderr, "\n"); exit(1); } #else barf(msg, arg1, arg2, arg3) { fpr)}intf(stderr, msg, arg1, arg2, arg3); fprintf(stderr, "\n"); exit(1); } #endif /* open libr and generate the initia)}l components list */ read_library(must_exist) int must_exist; { int i; lfile_components = #ifdef M6502 NULL;)} #else (struct entry * )NULL; #endif in_lfd = open_carefully(lfname, O_RDONLY, must_exist); /* #ifdef M6502 pri)}ntf("read_lib: fd %x\n", fd); #endif */ if (in_lfd > 0) /* open it ok? */ { read_header(in_lfd); /* read header *)}/ build_modlist(in_lfd); return; } else { if (must_exist) barf("Can't open %s", lfname); else { )} fprintf(stderr, "Creating library %s\n", lfname); in_lfd = 0; lfile_components = (struct entry * )NULL; } } } )} /* using the components_list, write a new library */ write_library() { struct entry * elt; int copy_lfd; char b)}uf[64]; int size; out_lfd = open_carefully("libr65.tmp", O_WRONLY | O_CREAT | O_TRUNC, 0); lfile.l_header )}= LIBR_HEADER; lfile.type = LT_OLB; /* fixed, for now */ lfile.flags = 0; /* refresh module count */ lfile.n_modul) }es = 0; for (elt = lfile_components ; elt ; elt = elt->e_next) if (!elt->skip) /* not skipping this one? */ lfile) }.n_modules++; /* then count it */ /* write the header */ write16(lfile.l_header); write16(lfile.type); write16(lf) }ile.n_modules); write16(lfile.flags); /* write the dictionary */ for (elt = lfile_components ; elt ; elt = elt->e_ne) }xt) if (!elt->skip) { write(out_lfd, elt->e_name, 12); write16(elt->e_nbytes); } /* write the modules themse) }lves */ for (elt = lfile_components ; elt ; elt = elt->e_next) { string_trim(buf, elt->e_name, 12); if (elt->skip) )} { /* skip this entry in the original library */ fprintf(stderr, "%s %s\n", skip_names[elt->skip], buf); size = elt)}->e_nbytes; for ( ; size > 0 ; size -= 64) read(in_lfd, buf, min(size, 64)); } else { if (elt->new) )} { /* new file. open the obj file */ fprintf(stderr, "Adding %s\n", buf); obj_lfd = open_carefully(buf, O_RDONLY)}, 1); copy_lfd = obj_lfd; } else { fprintf(stderr, "Copying %s\n", buf); copy_lfd = in_lfd; } )} /* run the copy loop */ for (size = elt->e_nbytes ; size > 0 ; size -= 64) { read(copy_lfd, buf, min(size, 64)))}; write(out_lfd, buf, min(size, 64)); } /* if have an obj file open, close it */ if (obj_lfd > 0) { clo)}se(obj_lfd); obj_lfd = 0; } } } /* copy writing. close libr file */ close(out_lfd); printf("closing in)}_lfd %d\n", in_lfd); if (in_lfd > 0) close(in_lfd); printf("del '%s'->%x\n", lfname, unlink(lfname)); printf("re)}n '%s','%s'->%x\n", "libr65.tmp", lfname, rename("libr65.tmp", lfname)); out_lfd = 0; printf("New library written\n")}); } /* routines to really do things */ add_files(argc, argv) int argc; char ** argv; { int i, nbytes, found; )} if (argc <= 3) barf("Add what files?"); found = 0; read_library(0); /* read the library */ for (i = 3 ; i <)} argc ; i++) { nbytes = file_nbytes(argv[i]); if (nbytes < 0) fprintf(stderr, "%s not found", argv[i]); else )} { found++; add_entry(argv[i], nbytes); } } if (found = 0) fprintf(stderr, "No files added"); else wr)}ite_library(); printf("Finished adding files\n"); } /* delete some library members */ del_files(argc, argv) int argc)}; char ** argv; { struct entry * elt; int i, deleted; if (argc <= 3) barf("Delete what files?"); read_lib)}rary(1); for (i = 3, deleted = 0 ; i < argc ; i++) if (del_entry(argv[i], SKIP_DELETE)) deleted++; else fpri)}ntf(stderr, "Library contains no member %s\n", argv[i]); if (deleted) write_library(); else fprintf(stderr, "No m)}embers matched"); close(in_lfd); } list_library() { struct entry * elt; char buf[80]; int i; read_li) }brary(1); close(in_lfd); strcpy(buf, lfname); string_upcase(buf); printf(" Library %s\n", buf); printf(" ---)!}--------- -----\n"); for (elt = lfile_components ; elt ; elt = elt->e_next) { buf[12] = '\0'; for (i = 0 ; i < 12 ;)"} i++) { buf[i] = elt->e_name[i]; /* printf("idx %d chr %c buf '%s'\n", i, elt->e_name[i], buf); */ } printf(" )#}%12s %5d\n", buf, elt->e_nbytes); } } print_version() { printf("Libr65 v %s\n", VERSION); } /* main body */ )$} #ifdef M6502 char cmdline[80]; #endif main(argc, argv) int argc; char ** argv; { char op; /* what we're doing t)%}o a file */ #ifdef M6502 /* might not be able to get cmd line from os, so prompt for it */ if (argc == 0) argc = rea)&}dargs("LIBR65>", cmdline, argv + 1) + 1; #endif if (argc < 3) barf("Try LIBR65