--- title: "CTAS (Customized Tasword)" id: 72718 type: "computer_media" slug: "ctas-customized-tasword" url: "http://localhost/computer_media/ctas-customized-tasword/" markdown_url: "http://localhost/computer_media/ctas-customized-tasword.md" published_at: "2026-10-26T23:19:26+00:00" modified_at: "2026-10-27T20:09:21+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Larry Crawford's revised Tasword Two for the Oliger and Larken disk systems, with disk catalogues, an expanded print menu and a customizer." post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Larry Crawford" slug: "larry-crawford" taxonomy: "indiv" url: "http://localhost/indiv/larry-crawford/" - name: "Steve Gunhouse" slug: "steve-gunhouse" taxonomy: "indiv" url: "http://localhost/indiv/steve-gunhouse/" genre: - name: "Word Processor" slug: "word-processor" taxonomy: "genre" url: "http://localhost/type/word-processor/" media_type: "Diskette" programmers: - name: "Larry Crawford" slug: "larry-crawford" taxonomy: "indiv" url: "http://localhost/indiv/larry-crawford/" - name: "Steve Gunhouse" slug: "steve-gunhouse" taxonomy: "indiv" url: "http://localhost/indiv/steve-gunhouse/" download_url: "https://archive.org/download/timex-sinclair-software-archive/CTAS%20%28198x%29%28Crawford%2C%20Larry%29%28TS2068%29%28US%29%28Program%29.zip" tsrun_member: "CTAS (198x)(Crawford, Larry)(TS2068)(US)(Program)/ctas.B1.tap" mediadate: "1993" article_media: - id: 22189 title: "A Guide to Using CTAS, the Customizer and the Printer" type: "article" url: "http://localhost/article/a-guide-to-using-ctas-the-customizer-and-the-printer/" related_content: - id: 51793 title: "Tasword II" type: "computer_media" url: "http://localhost/computer_media/tasword-ii/" - id: 72769 title: "24-Pin Bit Image Graphics" type: "computer_media" url: "http://localhost/computer_media/24-pin-bit-image-graphics/" media_type_tags: "Word Processor" license: false --- # CTAS (Customized Tasword) CTAS is Larry Crawford’s extensively revised version of Tasword Two for TS2068 owners with a disk drive. It works with the Oliger (JLO SAFE) disk system, the Larken (LKDOS) system, or both at once. Colour-coded prompts show which system is active, and text files can be loaded from one system and saved to the other. When a file is loaded, added or saved, CTAS shows a catalogue of the text files on the active drive, so a single keystroke picks one. The main menu shows the name of the file in memory, its length in bytes, lines and words, the number of tracks needed to save it, and the active drive, which a single key changes. The print menu adds a top margin, a pause at the end of each page, multiple copies, page numbers, and a header or footer taken from the first line of the text. A companion customizing program sets the printer, interface and graphics codes as in the original Tasword, and adds the help pages, colours and default page layout. Other options compress and uncompress text files, copy the whole package to another drive, and switch between disk and tape operation. Crawford released CTAS into the public domain in 1993; the guide is dated January 1993 and the program June 1993. It was described in his article [“A Guide to Using CTAS, the Customizer and the Printer”](/?p=22189) in *Update* magazine, January 1994. ## What’s in the Download - `ctas.B1`, the word processor, and `ctas.C1`, its machine code for both disk systems - `taspak.C1`, the compress/uncompress routine - `cust.B1`, the customizing program - Crawford’s guide to CTAS and his HOT-Z disassemblies of the Oliger and Larken code routines, as Tasword files and as plain text This is a disk edition, not converted for tape: CTAS reads the disk system’s own variables and calls its routines, so it needs an Oliger or Larken interface and will not run on a bare TS2068. The files come from an Oliger disk in Joe’s collection. The author’s street address and phone number have been blanked in the texts, and the disk image and two JLO state saves from the disk are not included. ### The 1991 version: tasldc The download also holds an earlier, Oliger-only version of the program, in the folder “CTAS 1991 version (tasldc)”. It comes from Crawford’s Oliger disk “PRINTER DRIVER 2”, which he sent to *Update* magazine in February 1991. `tasldc` (dated 18 Feb 1991) already has most of what CTAS offers: the main menu with drive selection by number key, a word count, a default file name read from the top left of the text, the print parameter screen, a tape/disk toggle for text files, and an option that saves the whole Tasword package. Its code `tas` has the same length and load address as `ctas.C1`. `custtw` (17 Feb 1991) is the Customizer for printer codes, graphics characters and help pages. Option K loads `taspak`, Steve Gunhouse’s text compressor and uncompressor, published in the Jan-Feb 1991 issue of *SILC-LINK*. It is the same routine as CTAS’s `taspak.C1`, saved at a different address. Crawford’s notes (`tashlp.CT`, included as text) thank Bob Mitchell for the drive selection and default name features, and say the word count is Duncan Teague’s from the Jul/Aug 1986 *Time Designs*. Like CTAS, tasldc is a disk program that is not converted for tape; it uses the JLO system variables and catalogue routines and needs the Oliger interface. The download now also has Larry Crawford’s technical documents for the October 1991 Larken build of tasldc (folder “Technical docs, Oct 1991”): a two-part line-by-line walk-through of the tasldc BASIC, notes on the Customizer, a HOT-Z disassembly of the code routines (“Public Domain 911028”) and a table of menu line numbers and variable addresses. His street address, postal code and phone number are blanked. ## Source Code ``` 5 REM ctas.B1 930608 10 CLEAR VAL "33279": LET g=PEEK VAL "26660": LET z=NOT PI: LET a=SGN PI: LET b=a+a: LET c=a+b: LET d=b+b: LET j=d+d: LET t=j+b: LET a3=t+c: LET p=t+t-a: LET v=t*c: LET s4=j*j: LET s=t*t: LET o=VAL "127": LET q=d*s4: LET fh=VAL "500": LET sh=fh+s: LET eh=VAL "800": LET nh=eh+s: LET e=fh*b: LET f=e+t: LET ck=e*c: LET fk=ck+e+e: LET sk=ck*b: LET ek=eh*t: LET nk=nh*t: LET tx=VAL "33280" 20 LET t$="text file ": LET f$=" ": LET df=d: LET sd=PEEK VAL "26666": POKE VAL "64516",j-a: LET u=s4*INT ((USR VAL "64330")/s4+VAL ".99"): IF u=z THEN GO TO ck 30 LET n$="": FOR i=a TO d+b: LET l$=CHR$ PEEK (tx+i-a): IF l$=" " THEN GO TO v+t 32 LET n$=n$+l$: NEXT i 35 IF u>VAL "19200" THEN LET u=VAL "19200" 40 LET pa=d-b*g: LET o$=("OLIGER " AND NOT g)+("LARKEN " AND g): LET ds=sh+VAL "1100"*df: LET dd=PEEK VAL "26667": GO SUB VAL "9600"+g: LET x=VAL "26703": LET m=VAL "1280": GO SUB nh 45 BORDER a: CLS : PRINT PAPER pa;"MAIN MENU"; PAPER a'''"J: LOAD )"'"A: ADD ) ";o$;t$'"S: SAVE )"'"P: PRINT ";t$'"Y: RETURN to ";t$'"T: SAVE BASIC only"'"W: SAVE Whole tas package"'"C: Customize Gr/Prntr/Help Pgs"'"K: Compress/uncomp ";t$'"O: OLIGER/LKDOS"'"D: "; PAPER pa;("tape" AND NOT df)+("disk" AND df) 100 PRINT AT p-c,z;" ";t$;CHR$ j;": "; PAPER pa;n$+(" " AND n$=""); PAPER a;TAB p+a;INT u;" bytes "'INT (u/s4);" lines, ";USR VAL "53098";" words, ";INT (u/VAL "5090")+a;" tracks"''TAB t; PAPER pa;"drive now "; FLASH a;dd; FLASH z''"# KEY=DRIVE LETTER KEY=OPTION" 120 POKE VAL "23658",z: GO SUB e: PAUSE z: LET k=CODE INKEY$-d*j 130 IF kVAL "89" THEN GO TO f 150 GO TO k*s 500 PRINT AT y,z; FLASH a; OVER a;" ": INPUT ;: PRINT #z; INK t-a; PAPER pa;" if OK to change": GO SUB e: PAUSE z: IF INKEY$="c" THEN GO TO v 501 RETURN 600 CLS : PRINT AT t,z;"position tape in recorder: PLAY": RETURN 800 LET x$=STR$ PEEK x 810 PRINT AT y,p; FLASH a;x$; FLASH z;" " 820 GO SUB e: IF NOT (k>=t) THEN INPUT LINE a$: IF a$="" THEN LET a$=x$ 835 IF k>b AND kx$ THEN PRINT AT y,p; INVERSE a;a$ 841 RETURN 900 POKE x,q*(m/q-INT (m/q)): POKE x+a,INT (m/q): RETURN 1000 BEEP a/v,v+t: RETURN 1010 GO SUB e: GO TO VAL "120" 2000 LET dd=(k-j-j): IF dd>d THEN GO TO f 2001 IF dd>c AND NOT g THEN LET dd=z: GO SUB e: GO SUB e 2005 POKE VAL "26667",dd: GO SUB VAL "9600"+g: GO TO s 2999 GO TO f 3000 CLS : FOR i=VAL "23296" TO VAL "23361": POKE i,v+b: NEXT i 3005 POKE i,z 3010 PRINT AT t,d+b;"type word to be found": GO SUB e: INPUT a$: IF a$="" THEN GO TO v 3020 FOR i=a TO LEN a$: POKE VAL "23297"+i,CODE a$(i): IF a$(i)=" " THEN CLS : GO SUB e: PRINT "no spaces allowed: any key": GO SUB e: PAUSE z: GO TO ck 3021 NEXT i 3025 POKE VAL "23297",LEN a$ 3030 CLS : PRINT "type new word/phrase (max 64)"''"or to FIND only": LET i=t+d: GO SUB e: INPUT a$ 3040 IF a$="" THEN POKE VAL "23362",a: GO TO VAL "3060" 3050 FOR i=a TO LEN a$: POKE VAL "23329"+i,CODE a$(i): NEXT i 3060 RANDOMIZE USR VAL "64955": RANDOMIZE USR VAL "64333": GO TO v 5000 CLS : POKE VAL "52741",mf: GO SUB VAL "9600"+g: IF g THEN POKE VAL "23692",p*t: INK a: RANDOMIZE USR s: CAT ".CT", 5002 INK t-a: CLS : PRINT '': LET n=USR (VAL "52751"+g*VAL "187") 5004 IF n=z AND mf THEN CLS : PRINT AT t,a;"NO "+t$+"ON DISK...ANY KEY": GO SUB e: PAUSE z: GO TO v 5010 PRINT AT z,z; PAPER pa;("SAVE" AND NOT mf)+("LOAD" AND mf=a)+("ADD" AND mf=b);" OPTION";AT t+j,z;(" for nxt pg " AND n>p+d)+("<^> for 1st pg " AND k=v+b)+" for menu"''("CHOOSE" AND mf)+(" TO CONTINUE WITH SAVE" AND NOT mf) 5015 GO SUB e: PAUSE z: LET k=CODE INKEY$: IF k=t+a OR k=VAL "55" THEN CLS : GO TO fk 5020 IF k=a3 AND NOT mf THEN RETURN 5025 IF k=VAL "226" THEN GO TO v 5030 IF k=v+b THEN CLS : PRINT '': LET n=USR (VAL "52874"+g*VAL "191"): GO TO fk+t 5035 LET k=k-VAL "96": IF kn+b THEN GO SUB e: GO TO fk+c 5040 LET y=INT (k/b+a/b)+a: LET x=c+(j+j)*(INT (k/b)=k/b): LET f$="" 5045 FOR i=z TO j-b: LET f$=f$+SCREEN$ (y,x+i): IF SCREEN$ (y,x+i)="." THEN LET f$=f$+"CT": GO TO sk 1466 NEXT i: GO SUB e: GO TO fk+o 6000 LET a$="LOADING " 6004 CLS : PRINT AT t,j; PAPER pa;a$;f$;: RETURN 6010 LET a$="SAVING ": GO TO sk+d 6500 LET y=d: GO SUB fh: LET mf=b: GO TO VAL "7402" 6600 GO TO f 6700 LET y=t: GO SUB fh 6710 POKE VAL "26679",y: LET f$="CUSTOMIZER": GO SUB sk: LET f$="cust.B1": GO SUB VAL "9100"+g: GO SUB VAL "9200"+g: GO TO p 6800 LET df=ABS (df-d): GO TO v 7300 GO TO f 7400 LET y=c: GO SUB fh 7401 RANDOMIZE USR VAL "59081": LET mf=a 7402 GO SUB ds: IF df=d THEN GO SUB VAL "9300"+g 7404 GO TO p 7500 LET y=t+a: GO SUB fh 7550 CLS : PRINT AT j,z; PAPER pa;"C/U ME@ MERGE "; PAPER a'''"S: save file (must be on disk)"''"L: load old file": GO SUB e: PAUSE z 7555 IF INKEY$="s" THEN GO TO VAL "8301" 7560 LET mf=a: GO SUB fk: FOR i=a TO LEN f$: POKE VAL "24310"+i,CODE f$(i): NEXT i: GO TO VAL "6710" 7800 GO TO f 7900 LET g=NOT g: POKE VAL "26660",g: GO TO v 8000 IF PEEK tx=z THEN CLS : GO SUB e: GO SUB e: PRINT AT t,d;"NO "+t$+"..": PAUSE z: GO TO v 8001 LET u=INT u: LET y=c+c: GO SUB fh: LET sl=a: LET hf=z: LET nf=z: LET tbf=a: LET pf=PEEK VAL "52747": LET tm=PEEK VAL "52748": POKE VAL "62235",a: LET bm=PEEK VAL "52742": LET fl=PEEK VAL "52750": LET s$=STR$ a: LET e$=STR$ (u/s4): LET nc=a: LET h=u 8002 CLS : PRINT PAPER pa;"PRINTER SETUP"; PAPER a;" Form length=";fl''"A: Start line";TAB p; INVERSE hf;s$; INVERSE z;''"B: Finish line";TAB p; INVERSE (VAL e$<>u/s4);e$+(" (last)" AND VAL e$=u/s4); INVERSE z;''"C: Line spacing";TAB p;PEEK VAL "62235"''"D: Left margin";TAB p;PEEK VAL "60927" 8003 PRINT AT t,z;"E: Top margin";TAB p;tm;'TAB p;"> max l/pg=";fl-tm-bm'"F: Bottom margin";TAB p;bm;''"G: Page pause?";TAB p; ("NO " AND NOT pf)+("YES" AND pf)''"H: # of Copies";TAB p;nc''"I: Number pages?";TAB p;("NO " AND NOT nf); INVERSE a;("top" AND nf AND tbf)+("btm" AND nf AND NOT tbf); INVERSE z;''"J: Header/Footer?";TAB p;("NO " AND NOT hf); INVERSE a;("hdr" AND hf AND tbf)+("ftr" AND hf AND NOT tbf): INPUT ;: PRINT #z;"P:PRINT";TAB p;"M:MENU" 8004 GO SUB e: PAUSE z: LET k=CODE INKEY$-s+d: GO TO ek+d+b+(v+d)*(k=j*b)-VAL "7966"*(k=A3) 8006 IF kt THEN GO SUB e: GO TO ek+b 8007 LET y=b*k: GO SUB ek+t+k*c*(k": GO SUB e: PAUSE z: LET x=o-s: GO SUB nk: LET x=CODE "O": GO SUB nk: LET x=a3: GO SUB nk: LET y=tm-d 8041 LET y=y-a: IF y>=z THEN LET x=t: GO SUB nk: GO TO VAL "8041" 8042 LET pg=a: GO SUB VAL "8085": LET x=o-s: GO SUB nk: LET x=CODE "C": GO SUB nk: LET x=fl: GO SUB nk: LET x=a3: GO SUB nk: LET x=VAL "60045": LET sb=s4*(VAL s$-a)+tx: LET m=sb: GO SUB nh: LET h=s4*(VAL e$-VAL s$+a): LET pl=fl-tm-bm: LET wp=INT (s4*pl/PEEK VAL "62235"): LET m=wp: IF m>h THEN LET m=h 8043 RANDOMIZE USR VAL "59806": RANDOMIZE USR VAL "64836" 8044 LET tf=((nf OR hf) AND tbf): LET bf=((nf OR hf) AND NOT tbf) 8045 IF pg<>a AND tf THEN GO SUB VAL "8090" 8046 IF pg<>a THEN LET x=t+b: GO SUB nk 8047 LET x=VAL "60049": GO SUB nh: RANDOMIZE USR VAL "60038" 8048 LET y=fl-tm-b: GO SUB nk+v: IF bf THEN GO SUB VAL "8090" 8050 IF NOT pf THEN LET x=t: FOR i=a TO d: GO SUB nk: NEXT i 8055 LET pg=pg+a: LET h=h-m: IF NOT h THEN LET nc=nc-a: IF NOT nc THEN RANDOMIZE USR VAL "59806": GO TO v 8057 IF NOT h AND nc THEN GO TO VAL "8041" 8065 LET sb=sb+wp: LET x=VAL "60045": LET m=sb: GO SUB nh: LET m=wp*(h>=wp)+h*(h": GO SUB e: PAUSE z 8086 RETURN 8090 IF pg=a THEN RETURN 8091 IF hf THEN FOR i=z TO s4-a: LET x=PEEK (tx+i): GO SUB nk: NEXT i 8092 IF NOT hf THEN LET x=v+b: FOR i=a TO s4-LEN n$: GO SUB nk: NEXT i: IF nf AND LEN n$ THEN FOR i=a TO LEN n$: LET x=CODE n$(i): GO SUB nk: NEXT i 8094 IF nf THEN RESTORE VAL "8094": FOR i=a TO j+a: GO SUB nk-d: NEXT i: DATA o-s,CODE "D",CODE "C",z,t-a,CODE "P",s+c,s4/b,pg+CODE "0" 8096 RETURN 8200 GO TO f 8300 LET y=d+a: GO SUB fh 8301 LET mf=z: GO SUB ds: CLS : PRINT AT t,z;"enter name (max 6, no .CT)";'''"or for default: "; PAPER d-b*g;n$+(" " AND LEN n$=z) 8325 GO SUB e: INPUT f$: IF f$="" THEN LET f$=n$ 8330 LET f$=f$+".CT": IF LEN f$>t-a OR f$(a TO c)=".CT" THEN GO SUB f: GO TO VAL "8301" 8350 GO SUB sk+t: GO SUB VAL "9400"+g 8360 GO TO v+VAL "7350"*(y=t+a) 8400 LET y=j: GO SUB fh 8405 LET f$="ctas.B1": GO SUB sk+t: GO SUB VAL "9500"+g 8440 IF y=t-a THEN GO TO VAL "6710" 8450 GO TO v 8600 GO TO f 8700 LET y=t-a: GO SUB fh: GO TO VAL "8405" 8800 GO TO f 8900 LET y=d+c: GO SUB fh: GO TO t 8999 READ x 9000 IF IN o>VAL "236" THEN GO TO nk 9001 OUT o,x: RETURN 9030 LET x=o-s: GO SUB nk: LET x=CODE "B": GO SUB nk: LET x=y: GO SUB nk: LET x=z: GO SUB nk: LET x=t+a: GO SUB nk: LET x=a3: GO SUB nk: RETURN 9100 LET /d=sd: RETURN 9101 RANDOMIZE USR s: GO TO sd: RETURN 9200 LOAD /f$ 9201 RANDOMIZE USR s: LOAD f$ 9300 LOAD /f$CODE tx+u*(mf=b): RETURN 9301 RANDOMIZE USR s: LOAD f$CODE tx+u*(mf=b): RETURN 9400 SAVE //f$CODE tx,u: RETURN 9401 RANDOMIZE USR s: SAVE f$CODE tx,u: RETURN 9500 SAVE //f$ LINE t: RETURN 9501 RANDOMIZE USR s: SAVE f$ LINE t: RETURN 9600 LET /d=dd: RETURN 9601 RANDOMIZE USR s: GO TO dd: RETURN ```