WIDJUP CAD is a printed-circuit-board artwork program. You describe a board as a data array of up to 99 items: straight lines, boxes, circles and ellipses, 45-degree traces, jogs and slants between two points, round and oblong pads, and quarter-circle arcs. Each item can be repeated in X and Y at a set pitch and can be marked as an eraser that clears what lies under it. The EDIT service shows five items at a time and changes them with number-key commands (ADD, FIX, SELECT, PUT, CUT, MAP, DEL); DISPLAY draws the whole board on a 5 × 4 inch grid; REPORT prints the array. GENERATE turns the board into a 960-dot-wide printer raster at a chosen scale and sends it to an Epson-class dot-matrix printer, to a series of 4 KB image frames on disk, or both, and COPY prints saved frames as 2× photo masters for etching.
The program is by William J. Pedersen of The WIDJUP Co., who sold it as shareware: CAD#2 for the Olivetti PR2300 ink-jet printer, CAD#3 for Epson-class 9-pin printers on the Larken disk system (©1989), and CAD#5, the Oliger JLO SAFE version (©1991). UPDATE magazine printed the program and manual in April 1992 and the CAD#5 listings in October 1992. This download has CAD#5 as the main program and CAD#3 alongside it, both converted to load from tape, with the sample data arrays, the 93-frame demo image, the disk documents as text and the two original disk images.
Program Analysis
Loading chain
CAD#5BE lists the current channel table and rebuilds it: PRINT #4 goes to the TS2040 printer, and a new LPRINT #5 / LLIST #5 channel for formatted printing is assembled into memory from DATA lines written as mnemonic variable names (LET CP=254: LET JRZ=40 and so on), the same scheme as Pedersen’s IO with LLIST #5. INTFC_BE then asks which parallel interface is fitted (Tasman A or B, AERCO/Oliger, A&J, or a general Z80 PIO), shows the port and bit values so they can be changed, and pokes a 242-byte printer module to 26995 from DATA lines whose port numbers and relocated addresses are calculated as they are read (DEF FN b() splits each address into its two bytes). CAD_BE loads the UDG code CAD_CU and the printer-window table J$T, installs the module and shows the main menu.
Data arrays and editing
A board is the array z(100,11): row 1 holds the item count, and each later row holds an item type and up to ten parameters (position, size, repeat counts and pitch, eraser flag). The editor redraws a five-item window with PRINT AT and reads single keys with INKEY$; the DISPLAY service plots each item type with PLOT/DRAW and a circle routine on a scaled grid, labelling the item number as it goes.
Generating the raster
GENERATE converts every item to a scanline description in the work array y(100,13) (lines 1200–1302) and then builds the image 24 printer dot-rows at a time. Each 960-dot row is folded across four 256-pixel character rows of the screen, so one frame of the top two-thirds of the display (4096 bytes) holds 24 rows. Lines 210–214 work out which items cross each row and call the item’s own fill routine through a computed GO SUB y(u,1); the printer module then sends the frame as Epson graphics, and frames can be saved for COPY or edited one at a time in the image update service.
Notable Techniques
- Channel
#5is a real printer channel assembled at run time from DATA mnemonics, soLPRINT #5andLLIST #5give formatted output. - The printer module is relocatable:
DEF FN b(b,o)computes the low or high byte of each absolute address as the DATA is read. - Program-wide constants are held in short variables (
i,ii,iii,iv,six,z) to save memory and time, and menu choices are dispatched withGO SUB SR+xx*n. - Item types are drawn by computed
GO SUBto the line number stored in the work array.
Potential Issues
- In CAD#5, GENERATE “Update” looks for frame 1 with a
.CZsuffix (line 3146, and the image copy service at 8106), although CAD#5 saves frames without it, so an existing image could not be found. - In CAD#5, line 208 repeats the frame step of line 206 and loads a second frame, so Update mode skips every other frame. CAD#3 steps once per pass.
- The DEM frames on the Oliger CAD#5 demo disks are catalogued with load address 16834 instead of 16384, so they load 450 bytes low and print incorrectly; the CAD#3 demo frames in this download are the Larken set, which load correctly.
- Line 1 of CAD#5 sets
ON ERR GO TO 9885, a line that does not exist.
Both programs came from Larken and Oliger disks of Pedersen’s and were converted to run from tape: the disk prefixes, drive selects and CAT commands were removed, the DIRECTORY service (which read the floppy controller ports directly) now says it is not available, the interface builder leaves its module in memory instead of saving it to disk, and the two CAD#5 Update bugs above are fixed in the tape version. They were tested in ZEsarUX on a stock TS2068: loading, the interface set-up, loading the DEMO array, DISPLAY, EDIT and GENERATE to the screen work; printing needs a real Centronics interface and printer and was not tested.
Source Code
1 ON ERR GO TO 9885: GO TO Main
12 IF a1>=960 THEN RETURN
13 LET a=INT a1: IF a<0 THEN LET a=0
14 LET b=INT (b1-1): IF a>b THEN RETURN
15 IF b>959 THEN LET b=959
16 LET c=INT (a/256): LET a=a-256*c: LET d=INT (b/256): LET b=b-256*d: LET s=f-8*c: LET d=d-c
17 IF NOT d THEN PLOT a,s: DRAW b-a,0: RETURN
18 PLOT a,s: DRAW 255-a,0: LET s=s-8
19 IF d=3 THEN PLOT 0,s: DRAW 255,0: LET s=s-8
20 IF d>=2 THEN PLOT 0,s: DRAW 255,0: LET s=s-8
21 PLOT 0,s: DRAW b,0: RETURN
23 STOP
44 LET j=z(kk+1,7)
45 GO SUB 12: IF j<2 THEN RETURN
46 LET j=j-1: LET A1=A1+y(kk,8): LET B1=B1+y(kk,8): GO TO 45
100 IF y>y(kk,5) THEN GO TO 201
101 LET a1=y(kk,2): LET b1=y(kk,3): GO TO 44
120 IF y>y(kk,5) THEN GO TO 201
121 LET a=(y(kk,5)+y(kk,6))/2: LET c=y(kk,4): LET b=y(kk,13): LET s=b+y(kk,12)*(y-a): LET a1=s-c: LET b1=s+c: GO TO 44
130 IF y>y(kk,5) THEN GO TO 201
131 LET d=y(kk,2): LET j=y(kk,3): LET c=y(kk,4): LET a=(y(kk,5)+y(kk,6))/2: LET b=y(kk,13)
132 LET s=b+y(kk,12)*(y-a)
133 LET a1=s-c: IF a1<d THEN LET a1=d
134 LET b1=s+c: IF b1>j THEN LET b1=j
135 GO TO 44
140 LET b=(y(kk,5)+y(kk,6))/2: LET c=y(kk,4): LET d=y-b: LET s=(1-d*d/c/c): IF y>y(kk,5) OR s<z THEN GO TO 201
141 LET a=y(kk,13): LET s=c*k1*SQR s: LET a1=a-s: LET b1=a+s: GO TO 44
150 LET b=(y(kk,5)+y(kk,6))/2: LET c=y(kk,4): LET d=y-b: LET s=(1-d*d/c/c): IF y>y(kk,5) OR s<z THEN GO TO 201
151 LET a=y(kk,13): LET s=c*k1*SQR s: IF s>y(kk,12) THEN LET s=y(kk,12)
152 LET a1=a-s: LET b1=a+s: GO TO 44
160 LET b=(y(kk,5)+y(kk,6))/2: LET c=y(kk,4): LET d=y-b: LET s=(1-d*d/c/c): IF y>y(kk,5) OR s<z THEN GO TO 201
161 LET s=c*y(kk,3)*SQR s
162 LET a=y(kk,13): LET a1=a-s: LET b1=a+s: GO TO 44
170 LET c=y(kk,4): LET d=y-y(kk,6)-y(kk,12): LET s=i-d*d/c/c: IF y>y(kk,5) OR s<z THEN GO TO 201
172 LET s=c*y(kk,3)*SQR s
173 LET a=y(kk,13): LET a1=a-(s AND y(kk,2)>3): LET b1=a+(s AND (y(kk,2)<5)): GO TO 44
201 LET Del=y(kk,10): LET y(kk,5)=y(kk,5)+Del: LET y(kk,6)=y(kk,6)+Del: LET y(kk,9)=y(kk,9)-1: RETURN
205 GO SUB 225: LET t=INT ((ff/24) AND Uflag): LET y=24*t-i: LET kk=z
206 GO SUB 225: LET t=t+i: IF NOT Uflag THEN GO TO 209
207 LET h$=f$( TO iii)+STR$ t: LOAD h$ CODE
208 REM tape version: second frame step removed (it skipped every other frame in Update)
209 FOR L=z TO 23: LET y=y+i: IF y<ff THEN GO TO 214
210 LET f=175-32*L+95*INT (L/3): LET u=0: LET kk=0
211 LET u=u+1: IF y(u,9) THEN IF y>y(u,6) THEN LET kk=u: INVERSE y(u,11): GO SUB y(u,1)
212 IF u<Last THEN GO TO 211
213 IF NOT kk THEN GO SUB 225
214 NEXT L: INVERSE z
215 IF Gmode=ii OR Gmode=iv THEN GO SUB 454: GO SUB 455: GO SUB 456
216 REM tape version: no disk-full prompt
217 IF Gmode>ii THEN LET h$=f$( TO iii)+STR$ t: PRINT AT 15,0;h$;AT 15,16;"Scale=";Scale: SAVE h$ CODE 16384,4112
218 CLS : PRINT AT 18,ii;f$;"*";scale'" Frame #";t;" done."
219 LET s=0: FOR n=1 TO Last: LET s=s+y(n,9): NEXT n: IF NOT s THEN LET Uflag=z: RETURN
220 GO TO 206
225 LET ff=4096: LET s=1
226 IF y(s,9) THEN IF y(s,6)<ff THEN LET ff=y(s,6)
227 IF s<Last THEN LET s=s+1: GO TO 226
228 LET ff=ff AND ff>0: RETURN
300 FOR n=z(i,i) TO here STEP -i: FOR k=i TO 11: LET z(n+ii,k)=z(n+i,k): NEXT k: NEXT n: LET z(i,i)=z(i,i)+i: RETURN
302 FOR n=here TO z(i,i)-i: FOR k=i TO 11: LET z(n+i,k)=z(n+ii,k): NEXT k: NEXT n: LET z(z(i,i)+i,1)=z: LET z(i,i)=z(i,i)-i: IF here>z(i,i) THEN LET here=z(i,i)
303 RETURN
305 PRINT INK 8; PAPER 8;AT ii,11;"LAST ";z(i,i);" ";AT ii,xx;"SELECT ";AT ii,27;Here;: FOR k=left TO left+iv: LET b=6*(k-left)+2: LET d=k+1: LET c=(z(d,6)-1) AND (z(d,1)=10): PRINT AT 4,b;k;" ";AT 5,b;Q$(z(d,1)+1+c);
306 FOR n=1 TO 11: LET a=INT (z(k+1,n)*1000): PRINT INK 1+(k=Here)+(6 AND k>z(1,1));AT n+6,b;a/1000: NEXT n: NEXT k
307 PLOT 0,168: DRAW 0,-150: DRAW 254,0: DRAW 0,150: DRAW -254,0: RETURN
449 FOR n=i TO 11: POKE (Ld0+CODE o$(n)),CODE j$(Select,n): NEXT n
450 RANDOMIZE USR (Ld0+CODE o$(12)): RETURN
451 LET select=i: GO TO 449
452 LET select=ii: GO TO 449
453 LET select=iii: GO TO 449
454 LET select=iv: GO TO 449
455 LET select=v: GO TO 449
456 LET select=six: GO TO 449
1200 RETURN
1210 LET a=z(ss,v)/ii: LET b=(z(ss,iii)+z(ss,iv))/ii: LET c=ABS (b-z(ss,iv))
1211 LET y(n,i)=LK: LET y(n,ii)=(b-c)*kY: LET y(n,iii)=(b+c)*kY: LET y(n,v)=(z(ss,ii)+a)*kX-i/ii: LET y(n,six)=(z(ss,ii)-a)*kX+i/ii: GO TO rr
1220 LET b=z(ss,ii): LET c=z(ss,v)/ii: LET a=(z(ss,iii)+z(ss,iv))/ii: LET d=ABS (z(ss,iii)-z(ss,iv))/ii
1221 LET y(n,i)=LK: LET y(n,ii)=(b-c)*kY: LET y(n,iii)=(b+c)*kY: LET y(n,v)=(a+d)*kX-i/ii: LET y(n,six)=(a-d)*kX+i/ii: GO TO rr
1230 LET b=z(ss,ii): LET d=z(ss,iv)/ii: LET c=z(ss,v)/ii
1231 LET y(n,i)=LK: LET y(n,ii)=(b-d)*kY: LET y(n,iii)=(b+d)*kY: LET y(n,v)=(z(ss,iii)+c)*kX-i/ii: LET y(n,six)=(z(ss,iii)-c)*kX+i/ii: GO TO rr
1240 LET b=z(ss,ii)
1241 LET y(n,i)=160: LET y(n,iii)=z(ss,v)*k1: LET y(n,iv)=z(ss,iv)*kX: LET y(n,v)=(z(ss,iii)+z(ss,iv))*kX-i/ii: LET y(n,six)=(z(ss,iii)-z(ss,iv))*kX+i/ii: GO TO rr
1250 LET a=(z(ss,iv)+z(ss,ii))/ii: LET c=(z(ss,iv)-z(ss,ii))/ii: LET d=z(ss,v)/ii: LET b=z(ss,iii)+c*SGN d: LET w=ABS c+ABS d
1251 LET y(n,i)=130: LET y(n,ii)=(b-w)*kY: LET y(n,iii)=(b+w)*kY: LET y(n,iv)=(ABS d)*kD-i/ii: LET y(n,v)=(a+w)*kX-i/ii: LET y(n,six)=(a-w)*kX+i/ii: LET y(n,12)=k1*SGN d: GO TO rr
1260 LET a=(z(ss,iv)+z(ss,ii))/ii: LET c=(z(ss,iv)-z(ss,ii))/ii: LET d=z(ss,v)/ii: LET b=z(ss,iii)+c*SGN d: LET w=ABS c+ABS d
1261 LET y(n,i)=120: LET y(n,ii)=z: LET y(n,iii)=879: LET y(n,iv)=(ABS d*kD)-i/ii: LET y(n,v)=(a+w)*kX-i/ii: LET y(n,six)=(a-w)*kX+i/ii: LET y(n,12)=k1*SGN d: GO TO rr
1270 LET c=z(ss,ii): LET a1=z(ss,iii): LET d=z(ss,iv): LET b1=z(ss,v): IF c=d OR a1=b1 THEN GO TO 1310
1271 LET a=(a1+b1)/ii: LET b=(c+d)/ii: LET Tan=(b1-a1)/(d-c): LET d=ABS (d-c)/ii: LET c=ABS (b1-a1)/ii
1272 LET w=z(ss,six)/ii: LET An=ATN Tan: LET Sin=SIN An: LET ew=ABS (w*Sin): LET eh=w*COS An
1273 LET y(n,i)=130: LET y(n,ii)=(b-d-ew)*kY: LET y(n,iii)=(b+d+ew)*kY: LET y(n,iv)=ABS (w/Sin*kY)-i/ii: LET y(n,v)=(a+c+eh)*kX-i/ii: LET y(n,six)=(a-c-eh)*kX+i/ii: LET y(n,12)=k1/Tan: GO TO rr
1280 LET b=z(ss,ii): LET a=z(ss,iii): LET h=z(ss,iv)
1281 IF h<=z THEN GO TO 1310
1282 LET y(n,i)=140: LET y(n,iv)=h*kX: LET y(n,v)=(a+.75*h)*kX-i/ii: LET y(n,six)=(a-.75*h)*kX+i/ii: GO TO rr
1290 LET b=z(ss,ii): LET a=z(ss,iii): LET h=z(ss,iv)
1291 IF h<=z THEN GO TO 1310
1292 LET y(n,i)=150: LET y(n,iv)=h*kX: LET y(n,v)=(a+h)*kX-i/ii: LET y(n,six)=(a-h)*kX+i/ii: LET y(n,12)=.75*h*kY: GO TO rr
1300 LET b=z(ss,ii): LET a=z(ss,iii): LET c=z(ss,iv): LET d=z(ss,v): LET w=z(ss,six): LET a1=(w>i AND w<7): LET b1=w>v OR w<iii
1301 LET y(n,i)=170: LET y(n,ii)=w-(iv AND w=8): LET y(n,iii)=d*k1: LET y(n,iv)=c*kX: LET y(n,v)=(a+(c AND b1))*kX-(.5 AND b1): LET y(n,six)=(a-(c AND a1))*kX+(.5 AND a1): LET y(n,12)=(c*kX-i/ii) AND a1
1302 LET y(n,7)=z(ss,7): LET y(n,8)=z(ss,8)*kY: LET y(n,9)=z(ss,9): LET y(n,10)=z(ss,10)*kX: LET y(n,11)=z(ss,11): LET y(n,13)=b*kY: RETURN
1310 PRINT AT 10,iii;" BAD DATA. ITEM #";ss-i;" ";: PAUSE z: ON ERR GO TO Main: LET n=n/z
3020 CLS : PRINT " WIDJUP DATA LOAD SERVICE ";AT 4,1;"DATA ARRAYS are named with _Z.";AT 6,1;"Type the name without _Z, then";AT 7,1;"start the tape. ENTER to quit."
3021 REM removed (LKDOS-only)
3022 REM removed (LKDOS-only)
3023 REM was Oliger-only
3024 INPUT "Which(or ENTER)? ";I$: IF LEN I$=z THEN RETURN
3028 LET F$=I$+"_Z": LOAD F$ DATA z()
3029 LET here=1: RETURN
3041 IF z(i,i)=z THEN GO TO 3060
3042 CLS : PRINT AT 8,8;" WARNING "''" File ";f$;" is present."''" Continuing will destroy file.": INPUT "Continue? Y/n ";I$: IF I$="Y" OR I$="y" THEN DIM z(100,11): LET f$="No Data": GO TO 3060
3043 PRINT ''" CANCELLED": RETURN
3060 LET here=here-(here AND f$="No Data"): LET q$=" abcdXxijkmnopqrstu"
3061 GO SUB SE: GO TO HK
3063 INVERSE p5: PLOT p1,p2: DRAW p3,p4: INVERSE z: RETURN
3064 PLOT p1,p2: DRAW p3,z: DRAW z,p4: DRAW -p3,z: DRAW z,-p4: RETURN
3065 CIRCLE p1,p2,p3: RETURN
3066 PLOT p1,p2: DRAW p3,p4: RETURN
3067 PLOT p1,p2: DRAW i,iii: DRAW i,-iii: DRAW -i,-iii: DRAW -i,iii: RETURN
3068 PLOT p1,p2: DRAW iii,i: DRAW iii,-i: DRAW -iii,-i: DRAW -iii,i: RETURN
3069 LET c=PI/ii: LET a=INT ((p7-1)/ii): LET b=INT (p7/ii)+i: FOR k=a*c TO b*c STEP 1/p3: PLOT p1+p3*COS k,p2+p3*SIN k: NEXT k: RETURN
3081 GO SUB 4010: FOR n=i TO LEN f$: PRINT PAPER 5;AT n,i;f$(n);: NEXT n: PRINT AT 20,0;: FOR n=ii TO z(i,i)+i: PRINT AT 18,z;"#";n-i;: LET a=z(n,i)
3082 IF a=z THEN PRINT AT 11,5; OVER i;" BAD or NO DATA "
3083 IF a=i THEN LET p1=L*z(n,ii)+xo: LET p2=L*z(n,iii)+yo: LET p3=z: LET p4=L*(z(n,4)-z(n,iii)): LET p5=z(n,11): LET bb=3063
3084 IF a=ii THEN LET p1=L*z(n,iii)+xo: LET p2=L*z(n,ii)+yo: LET p3=L*(z(n,4)-z(n,iii)): LET p4=z: LET p5=z(n,11): LET bb=3063
3085 IF a=iii THEN LET p2=L*z(n,ii): LET p1=L*z(n,iii): LET p4=L*z(n,4): LET p3=L*z(n,5): LET p2=p2-p4/ii+yo: LET p1=p1-p3/ii+xo: LET bb=3064
3086 IF a=iv THEN LET p1=L*z(n,iii)+xo: LET p2=L*z(n,ii)+yo: LET p3=L*z(n,4): LET bb=3065
3087 IF a=v OR a=six THEN LET p1=L*z(n,ii)+xo: LET p2=L*z(n,iii)+yo: LET p3=L*(z(n,4)-z(n,ii)): LET p4=SGN z(n,5)*p3: LET bb=3066
3088 IF a=7 THEN LET p4=L*(z(n,4)-z(n,ii)): LET p3=L*(z(n,5)-z(n,iii)): LET p1=L*z(n,iii)+xo: LET p2=L*z(n,ii)+yo: LET bb=3066
3089 IF a=8 THEN LET p1=L*z(n,iii)-i+xo: LET p2=L*z(n,ii)+yo: LET bb=3067
3090 IF a=9 THEN LET p1=L*z(n,iii)-iii+xo: LET p2=L*z(n,ii)+yo: LET bb=3068
3091 IF a=10 THEN LET p1=L*z(n,iii)+xo: LET p2=L*z(n,ii)+yo: LET p3=L*z(n,4): LET p7=z(n,6): LET bb=3069
3092 LET yy=p2: LET b2=z(n,7): LET a2=z(n,9): LET a3=b2
3093 ON ERR GO TO 3095: GO SUB bb: LET p2=p2+L*z(n,8): IF b2>1 THEN LET b2=b2-1: GO TO 3093
3094 LET p2=yy: LET b2=a3: LET p1=p1+L*z(n,10): IF a2>1 THEN LET a2=a2-1: GO TO 3093
3095 ON ERR RESET : NEXT n: RETURN
3100 CLS : PRINT AT 8,2;"WIDJUP DIRECTORY SERVICE";AT 10,2;"needs a disk drive and is not";AT 11,2;"available in the tape version.": RETURN
3101 REM removed (LKDOS-only)
3102 REM removed (LKDOS-only)
3103 REM removed (LKDOS-only)
3104 REM removed (LKDOS-only)
3105 REM removed (LKDOS-only)
3107 REM removed (LKDOS-only)
3108 REM removed (LKDOS-only)
3109 REM removed (LKDOS-only)
3110 REM removed (LKDOS-only)
3118 REM removed (LKDOS-only)
3119 REM removed (LKDOS-only)
3120 INPUT "Comment, Date? ";a$: LPRINT #5'"DATA REPORT.. ";a$;;: LPRINT "lN";CHR$ 6;CHR$ 10
3121 GO SUB 3080: GO SUB 451: LPRINT CHR$ 10
3122 LET Last=Z(i,i): FOR l=ii TO Last+i: PRINT AT 19,z,,,,AT 19,z;: LET c=l-1: PRINT " " AND c<lk;" " AND c<10;c;" ";: RESTORE z(l,i)+3200: READ i$: PRINT INVERSE z(l,11);" ";I$;" ";: PRINT " ";: READ k: FOR k=ii TO k+i: READ I$: PRINT I$;: PRINT z(l,k);: NEXT k: GO SUB 3129
3123 PRINT TAB 14;"[x,y][";z(l,9);"*";z(l,7);"][";z(l,10);";";z(l,8);"]": GO SUB 3129
3125 NEXT l: PRINT "END OF DATA",,,,: GO SUB 3129: LPRINT "lO";CHR$ 12;: RETURN
3128 REM PRINT " " AND c<LK;" " AND c<10;c;" ";: RETURN
3129 GO SUB 453: PRINT AT 19,z,,,,AT 19,z;: RETURN
3140 ON ERR RESET : CLS : PRINT " WIDJUP GENERATE SERVICE "''" 0 QUIT "''" 1 Screen Only"''" 2 LPRINT"''" 3 FILE"''" 4 LPRINT & FILE"
3141 INPUT "Select by # ";I$: ON ERR GO TO 3140: LET Gmode=VAL ("0"+I$): ON ERR RESET : IF Gmode<z OR Gmode>iv THEN GO TO 3141
3142 PRINT '" Mode is #";Gmode''" 0.556 Scale will print an"'" overlay matching the REPORT."
3143 IF NOT gmode THEN PRINT ''"CANCELLED": RETURN
3144 DIM y(100,13): LET Uflag=z: IF gmode>ii THEN INPUT "New or Update? ";I$: IF LEN I$ THEN IF I$( TO i)="U" OR I$( TO i)="u" THEN LET Uflag=i
3145 IF NOT Uflag THEN INPUT "SCALE? ";Scale: GO TO 3148
3146 LET i$=f$( TO iii)+"1": LOAD i$CODE
3147 LET i$="": FOR n=22 TO 28: LET i$=i$+SCREEN$ (15,n): NEXT n: LET Scale=VAL i$
3148 LET kY=Scale*120: LET kX=kY/k1: LET kD=kY*1.414: PRINT #1;" WORKING "
3149 LET Last=z(i,i): FOR n=i TO Last: LET ss=n+i: LET nn=z(n+i,i): IF nn<i OR nn>10 OR nn<>INT nn THEN PRINT AT 21,six;"BAD DATA AT ";3000+n;"": STOP : RETURN
3150 LET Mode=1200+10*nn: GO SUB Mode: NEXT n: CLS : GO TO 205
3160 REM " COPY "
3161 CLS
3162 INPUT "FILE(less number)?";I$'" Count? ";bb: LET I$=I$+" ": LET I$=I$( TO iii): CLS
3163 FOR L=i TO bb: LET H$=I$+STR$ L
3164 REM tape version: no disk change
3165 PRINT AT 18,z: LOAD H$ CODE : GO SUB 454: GO SUB 455: GO SUB 456: NEXT L: LPRINT "lN";CHR$ 6;: RETURN
3180 ON ERR RESET : CLS : PRINT " WIDJUP SAVE SERVICE Existing File is ";F$,""
3181 PRINT ''" 1 KEEP SAME NAME"'''" 2 RENAME FILE (1-6 CHR$)"'" (Extension .AZ is provided.)"''" 3 QUIT ": IF F$="No Data" THEN PRINT '''" NO FILE EXISTS TO SAVE ": RETURN
3182 INPUT "Select by # ";I$: ON ERR GO TO 3180: LET a=INT VAL ("0"+I$): ON ERR RESET : IF a<1 OR a>3 THEN GO TO 3180
3183 IF a=3 THEN RETURN
3184 IF a=1 THEN LET I$=F$: GO TO 3187
3185 INPUT "File Identifier? ";I$: LET I$=I$+".AZ": PRINT AT xx,12;I$: IF LEN I$<4 OR LEN I$>9 THEN PRINT "INVALID FILE NAME, TRY AGAIN": PAUSE 120: GO TO 3180
3186 LET F$=I$
3187 PRINT AT 20,3;" SAVING ";I$;"",: SAVE I$ DATA z(): PRINT AT 20,3;I$;" SAVED",,: RETURN
3201 DATA "a",iv,"X0=","; Y="," to ","; Width="
3202 DATA "b",iv,"Y0=","; X="," to ","; Width="
3203 DATA "c",iv,"Y0=",",X0=","; H=",", W="
3204 DATA "d",iv,"Y0=",", X0=",", Rx=",", Ry/Rx="
3205 DATA ("f" AND z(l,v)<z)+("e" AND z(l,v)>z),iv,"X1=",", Y1=","; X2=","; Width="
3206 DATA ("h" AND z(l,v)<z)+("g" AND z(l,v)>z),iv,"X1=",", Y1=","; X2=","; Width="
3207 DATA "i",v,"Y1=",", X1=","; Y2=",", X2=","; Width="
3208 DATA "j",iii,"Y0=",", X0=","; Rad="
3209 DATA "k",iii,"Y0=",", X0=","; Rad="
3210 DATA CHR$ (155+z(l,six)),v,"X0=",", Y0=","; Rx=","; Ry/Rx=","; Quad="
3230 CLS : PRINT " WIDJUP EDIT SERVICE",""'''" 1 a Line"," 7 g Jog"''" 2 b Line"," 8 h Jog"''" 3 c Box"," 9 i Slant"''" 4 d Circle","10 j Pad"''" 5 e 45 Deg","11 k Pad"''" 6 f 45 Deg","12 n Quadrant"'''" Items oriented as they appear DISPLAYED, not as printed."
3231 INK 2: FOR n=0 TO 5: PLOT 30,62+16*n: DRAW 0,11: DRAW 11,0: DRAW 0,-11: DRAW -11,0: NEXT n: FOR n=0 TO 5: PLOT 158,62+16*n: DRAW 0,11: DRAW 11,0: DRAW 0,-11: DRAW -11,0: NEXT n: INK 0: RETURN
3301 DATA "a"," 1 At X="," 2 Y="," 3 To Y="," 4 Width="," -----"
3302 DATA "b"," 1 At Y="," 2 X="," 3 To X="," 4 Width="," -----"
3303 DATA "c"," 1 At Y="," 2 X="," 3 HighY="," 4 WideX="," -----"
3304 DATA "d"," 1 At Y="," 2 X="," 3 Rx="," 4 Ry/Rx="," -----"
3305 DATA "e"," 1 From X="," 2 Y="," 3 To X="," 4 Width="," -----"
3306 DATA "f"," 1 From X="," 2 Y="," 3 To X="," 4 Width="," -----"
3307 DATA "g"," 1 From X="," 2 Y="," 3 To X="," 4 Width="," -----"
3308 DATA "h"," 1 From X="," 2 Y="," 3 To X="," 4 Width="," -----"
3309 DATA "i"," 1 From Y="," 2 From X="," 3 To Y="," 4 To X="," 5 Width="
3310 DATA "j"," 1 At Y="," 2 X="," 3 Radius="," -----"," -----"
3311 DATA "k"," 1 At Y="," 2 X="," 3 Radius="," -----"," -----"
3312 DATA CHR$ (155+z(c,6))," 1 At Y="," 2 X="," 3 Rx="," 4 Ry/Rx="," 5 Quad="
4010 CLS : LET L=40: LET yo=12: LET xo=36: PLOT xo-i,yo+161: DRAW z,-162: DRAW 214,z: DRAW z,162: DRAW -214,z: PRINT AT z,iii;"4";AT 5,iii;"3";AT 10,iii;"2";AT 15,iii;"1";AT XX,iii;"0";AT 21,4;"0 1 2 >X 3 4 5";AT 12,ii;"Y"'" ^";
4011 FOR n=12 TO 173 STEP 4: PLOT 33,n: DRAW ii,z: PLOT 249,n: DRAW ii,z: NEXT n: FOR n=36 TO 248 STEP 4: PLOT n,9: DRAW z,ii: PLOT n,173: DRAW z,ii: NEXT n: RETURN
4060 IF z(i,i)<i THEN LET F$="No Data"
4061 BORDER 7: CLS : PRINT '" WIDJUP EDIT SERVICE"," ";F$,,""
4062 PRINT AT xx,i;"ESCFIXSELADD < PUTCUT > MAPDEL";AT 21,i;" 1 2 3 4 5 6 7 8 9 0 "
4063 FOR N=7 TO 230 STEP 24: PLOT n,z: DRAW z,16: DRAW 24,z: DRAW z,-16: DRAW -24,z: NEXT N
4064 REM spare
4065 LET left=here-ii: IF left<i THEN LET left=i
4066 PRINT AT 7,z,,,,,,,,,,,,,,,,,,,,,,: GO SUB He
4070 ON ERR RESET : LET a=CODE INKEY$
4071 IF a=4 THEN GO TO 4096
4072 IF a=5 THEN GO TO 5000
4073 IF a=6 THEN GO TO 5010
4074 IF a=7 THEN RETURN
4075 IF a=8 THEN LET here=here-(i AND here>i): GO TO WE
4076 IF a=9 THEN LET here=here+(i AND here<z(i,i)): GO TO WE
4077 IF a=10 THEN PRINT AT 10,12;" PASTING ";: GO SUB 4099: FOR n=i TO 11: LET z(here+i,n)=a(n): NEXT n: GO TO WE
4078 IF a=11 THEN PRINT AT 10,12;" CUTTING ";: DIM a(11): FOR n=i TO 11: LET a(n)=z(here+i,n): NEXT n: GO SUB 4101: GO TO WE
4079 IF a=12 THEN PRINT AT 10,11;" DELETING ";: GO SUB 4101: GO TO WE
4080 IF a=13 OR a=14 THEN GO TO Hk
4081 IF a=15 THEN GO SUB 4010: LET c=here+i: FOR n=i TO LEN f$: PRINT PAPER 5;AT n,i;f$(n): NEXT n: PRINT AT 18,z;"#";here;: FOR n=c TO c: GO SUB z(c,i)+3082: GO SUB 3076: NEXT n: GO SUB Key: GO TO SE
4082 GO TO Hk
4096 ON ERR GO TO HK: INPUT "SELECT ITEM by # ";I$: LET here=VAL ("0"+I$): ON ERR RESET : IF here<i THEN LET here=i
4097 IF here>z(i,i) THEN LET here=z(i,i)
4098 GO TO WE
4099 IF z(i,i)=z THEN LET z(i,i)=i: LET here=i: RETURN
4100 GO TO 300
4101 IF here=z THEN GO SUB Err: RETURN
4102 GO TO 302
4500 PRINT " WIDJUP EDIT SERVICE DATA ENTRY AND MODIFICATION "'',"ITEM # ";here;" ";: READ I$: PRINT " ";I$;" "': PRINT " 0 CANCEL ": FOR k=ii TO six: READ I$: PRINT I$,z(c,k): NEXT k: FOR k=7 TO 11: PRINT " ";k-i,z(c,k): NEXT k
4501 PRINT AT 10,v;"Y Copies..";AT 11,v;"Y Pitch=";AT 12,v;"X Copies..";AT 13,v;"X Pitch=";AT 14,ii;"10 Eraser.."'" 11 INSTALL "
4502 PLOT 0,175: DRAW 255,z: DRAW z,-150: DRAW -255,z: DRAW z,150
4503 IF cc=12 THEN PRINT AT 20,0;"QUADRANT SPRITES"'"1=m,2=n,3=o,4=p,5=q,6=r,7=s,8=t";
4510 RETURN
4901 DATA i,i,i,.02,z,i,z,i,z,z
4902 DATA i,i,i,.02,z,i,z,i,z,z
4903 DATA i,i,.8,.3,z,i,z,i,z,z
4904 DATA i,i,.03,i,z,i,z,i,z,z
4905 DATA i,i,1.5,.02,z,i,z,i,z,z
4906 DATA i,i,1.5,-.02,z,i,z,i,z,z
4907 DATA i,i,1.5,.02,z,i,z,i,z,z
4908 DATA i,i,1.5,-.02,z,i,z,i,z,z
4909 DATA ii,i,i,ii,.02,i,z,i,z,z
4910 DATA i,i,.04,z,z,2,.3,7,.1,z
4911 DATA i,i,.04,z,z,7,.1,2,.3,z
4912 DATA i,i,.04,i,5,i,z,i,z,z
5000 GO SUB ST: LET z(i,i)=z(i,i)+i: LET here=z(i,i)
5001 ON ERR RESET : INPUT "Select by # ";I$
5002 ON ERR GO TO Add+i: LET a=VAL ("0"+I$): ON ERR RESET : IF a<i OR a>12 THEN GO SUB Err: GO TO Add+i
5003 LET c=here+i: LET fixx=z: RESTORE 4900+a: FOR n=2 TO 11: READ a1: LET z(c,n)=a1: NEXT n
5004 LET g$="010203040505060607080910": LET cc=a+a-1: LET z(c,i)=VAL (g$(cc TO cc+1)): IF a=6 OR a=8 THEN LET z(c,5)=-z(c,5)
5005 LET cc=a: GO TO Fix+1
5010 LET c=here+i: LET fixx=i: DIM e(11): FOR n=i TO 11: LET e(n)=z(c,n): NEXT n: LET cc=e(i): LET cc=cc+(i AND cc>5)+(i AND cc>6)+(i AND (cc=5 OR cc=6) AND e(5)<z): IF here<1 THEN GO SUB Err: GO TO WE
5011 CLS : RESTORE 3300+cc: GO SUB 4500
5012 ON ERR RESET : INPUT "Select ";I$: IF I$="" THEN GO SUB Err: GO TO Fix+ii
5013 LET a1=I$( TO i)="0": IF (a1 AND Fixx=i) THEN FOR n=i TO 11: LET z(here+i,n)=e(n): NEXT n: GO TO SE
5014 IF (a1 AND Fixx=z) THEN LET z(here+i,i)=z: LET z(i,i)=z(i,i)-i: LET here=z(i,i): GO TO SE
5015 ON ERR GO TO Fix+ii: LET a=VAL I$: ON ERR RESET : IF a<1 OR a>11 THEN GO SUB Err: GO TO Fix+ii
5016 IF a=11 THEN GO TO 5022
5017 ON ERR RESET : LET Row=a+4: PRINT AT Row,16; OVER i;" ";AT Row,16;: INPUT "Value=";I$
5018 ON ERR GO TO 5021: LET bb=VAL ("0"+I$): ON ERR RESET : IF a=4 THEN IF cc=6 OR cc=8 THEN LET bb=-ABS bb
5019 IF cc=12 AND a=5 THEN IF bb<1 OR bb>8 THEN GO SUB Err: GO TO Fix+ii
5020 LET z(c,a+i)=bb: PRINT bb;" ";: GO TO 5012
5021 ON ERR RESET : GO SUB Err: GO TO 5017
5022 IF f$<>"No Data" THEN GO TO SE
5023 ON ERR RESET : INPUT "FILE NAME (less.AZ ext)? ";f$
5024 IF f$="" OR LEN f$>six THEN GO SUB Err: GO TO 5023
5025 LET f$=f$+".AZ": GO TO SE
6000 FOR n=1 TO 20: FOR l=1 TO 10: PRINT AT n-1,l+l+l-3;CODE j$(n,l): NEXT l: NEXT n: STOP : GO TO 6000
7770 GO SUB 7772: GO SUB 7771: FOR j=1 TO 242: POKE LD0+j-1,CODE U$(j): NEXT j: RANDOMIZE USR (LD0+49): LET Wa=PEEK 23631+256*PEEK 23632: LET Wc=INT (LD0/256): POKE Wa+15,LD0-256*Wc: POKE Wa+16,Wc: RETURN
7771 LET LD0=26995: RETURN
7772 RESTORE 7773: DIM O$(13): FOR n=1 TO 13: READ i$: LET X=VAL I$: LET O$(n)=CHR$ X: NEXT n: RETURN
7773 DATA "161","162","164","165","175","188","235","229","232","233","234","45","49"
8000 CLS : IF f$="No Data" THEN INPUT "Filename? ";f$: CLS
8002 PRINT AT 17,0;" FILE UPDATE SERVICE"," 1 select file"," 4 edit"," 2 store file"," 5 undo"," 3 copy file"," 6 quit",""
8004 INPUT "SELECT FUNCTION BY # ";I$: IF NOT LEN I$ THEN GO SUB Err: GO TO 8004
8006 LET a=VAL I$: IF a<i OR a>6 THEN GO TO 8004
8008 GO TO 8000+10*a
8010 INPUT "Frame=";s: LET H$=F$( TO 3)+STR$ s: LOAD H$ CODE : GO TO 8002
8020 SAVE H$ CODE 16384,4096: GO TO 8002
8030 INPUT "Are you SURE? (Yes)";q$: IF q$<>"Y" THEN GO TO 8002
8032 SAVE H$ CODE 16384,4096: GO TO 8002
8040 INPUT "COLUMN? ";c: LET row=INT (c/32): LET col=c-32*row: PRINT AT row,col; OVER i;" ";
8042 INPUT "WHAT? ";W$
8050 FOR n=0 TO 8 STEP 4: PRINT AT row+n,col; OVER i;W$;: NEXT n: GO TO 8004
8060 STOP : GO TO 8000
8100 CLS : PRINT " IMAGE FILE COPY SERVICE";AT 2,1;"Each frame loads from tape and";AT 3,1;"is saved again.": PAUSE 0
8102 REM was Oliger-only
8104 INPUT "Filename? ";F$;" From: ";from;" To: ";to
8106 CLS : FOR n=from TO TO : LET h$=f$( TO 3)+STR$ n: LOAD h$CODE
8108 SAVE h$ CODE 16384,4096
8110 NEXT n
8140 STOP : GO TO 8100
8995 ON ERR RESET : CLS : PRINT AT 10,9;" WORKING ";: LET s=1: LET u=s: LET kk=s: LET a=s: LET b=s: LET c=s: LET d=s: LET f=s: LET a1=s: LET b1=s: LET j=s: FOR L=s TO s: NEXT L: LET ff=s: LET ee=44: LET aa=201: LET i=s: LET w=s
8996 LET k1=120/216: LET z=s-s: FOR n=s TO s: NEXT n: FOR k=s TO s: NEXT k: LET e=s: LET g=s: LET h=s: LET lk=100
8997 LET ii=i+i: LET iii=ii+i: LET iv=ii+ii: LET v=iv+i: LET six=v+s: LET xx=iv*v: LET drive=z: LET Gdrive=i: LET Ddrive=drive: LET Here=s
8998 LET Main=9000: LET Me=9006: LET Err=Me+i: LET Key=Err+i: LET Dump=451: LET SR=3000: LET SE=4060: LET WE=4065: LET ST=3230: LET SD=6000: LET WD=6000: LET HE=305: LET HK=4070: LET ADD=5000: LET FIX=5010: LET jj=449: LET rr=1302
8999 DIM z(100,11): LET F$="No Data": LOAD "CAD_CU"CODE : LOAD "J$T" DATA j$(): DIM u$(242): FOR j=1 TO 242: LET u$(j)=CHR$ PEEK (26994+j): NEXT j: GO SUB 7770
9000 ON ERR RESET : INVERSE z: PAPER 7: INK z: BORDER 6: CLS : PRINT " The WIDJUP Co. (C)1991..CAD#5 MAIN MENU"," FUNCTION","DESCRIPTION","": PRINT '" 1 LOAD","PCB Data Array"''" 2 CREATE","New PCB"''" 3 EDIT","PCB Data Array"''" 4 DISPLAY","PCB"''" 5 DIRECTORY","Drives 0-4"''" 6 REPORT","LPRINT Data"''" 7 GENERATE","PCB Image"''" 8 COPY","From Image File"''" 9 SAVE","PCB Data Array"
9001 INPUT "SELECT by # ";I$: IF I$="" THEN GO TO Me
9002 IF I$="q" OR I$="Q" THEN STOP
9003 ON ERR GO TO Me: LET n=VAL I$: ON ERR RESET : IF n>9 OR n<i THEN GO TO Me
9004 GO SUB SR+xx*n
9005 GO SUB Key: GO TO Main
9006 ON ERR RESET : GO SUB Err: GO TO Main+i
9007 PRINT #i;AT z,z;" BAD INPUT. TRY AGAIN. ": PAUSE 60: PRINT #i;AT z,z,,: RETURN
9008 PRINT #i;AT z,six;" PRESS ANY KEY ";: PAUSE z: RETURN
9093 PRINT AT xx-ii,i;" DISK FULL. INSTALL ANOTHER. "'" Enter ""GO"" when ready.": FOR n=1 TO 8: BEEP .3,10: BEEP .3,22: NEXT n
9094 INPUT "Enter ""GO"" when ready.";W$: IF LEN W$<2 THEN GO TO 9096
9095 IF W$( TO 2)="GO" THEN RETURN
9096 GO SUB Err: GO TO 9094
9500 FOR n=i TO xx: GO SUB 9501: PAUSE z: NEXT n: STOP : GO TO 9500
9501 RESTORE 9502: CLS : PRINT "GROUP ";n,'': FOR k=i TO 11: READ i$: PRINT i$;CODE j$(n,k);" ",CODE o$(k): NEXT k: RETURN
9502 DATA " 1 col "," 2 ro*8 "," 3 dblh "," 4 lins "," 5 marg "," 6 wide "," 7 n/l "," 8 step "," 9 Gmod ","10 Nlsb ","11 Nmsb "
9990 POKE 26876,167
9991 INPUT "Date? ";i$: LPRINT "lN";CHR$ 6;: LPRINT #5'"CAD_BE Listing Oliger/Epson";i$'': LLIST #5: LPRINT "lO";CHR$ 12;: STOP
9999 CLEAR : SAVE "CAD_BE" LINE 8995: GO TO 8995Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.






