--- title: "Larken Disk Editor (Larken Edition)" id: 72957 type: "computer_media" slug: "larken-disk-editor-larken-edition" url: "http://localhost/computer_media/larken-disk-editor-larken-edition/" markdown_url: "http://localhost/computer_media/larken-disk-editor-larken-edition.md" published_at: "2026-10-27T21:30:12+00:00" modified_at: "2026-10-27T21:30:12+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Larry Kenny's disk editor for LKDOS: edit disk data byte by byte, repair directories and map out bad blocks; with his Cat+ catalogue command." post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "LARKEN Electronics" slug: "larken-electronics" taxonomy: "post_tag" url: "http://localhost/tag/larken-electronics/" - 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 Kenny" slug: "larry-kenny" taxonomy: "indiv" url: "http://localhost/indiv/larry-kenny/" genre: - name: "Utility" slug: "utility" taxonomy: "genre" url: "http://localhost/type/utility/" media_type: "Diskette" programmers: - name: "Larry Kenny" slug: "larry-kenny" taxonomy: "indiv" url: "http://localhost/indiv/larry-kenny/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Larken%20Disk%20Editor%20%281989%29%28Kenny%2C%20Larry%29%28TS2068%29%28US%29%28Larken%20Disk%29.zip" tsrun_member: "Larken Disk Editor (1989)(Kenny, Larry)(TS2068)(US)(Larken Disk)/disk files/AercoF.CZ.tap" mediadate: "1989" producer_company: - id: 11042 title: "LARKEN Electronics" type: "company" url: "http://localhost/company/larken-electronics/" article_media: - id: 23187 title: "Larken Disk Editor: Review" type: "article" url: "http://localhost/article/larken-disk-editor-review/" - id: 21777 title: "Customized Catalog Command for LKDos" type: "article" url: "http://localhost/article/customized-catalog-command-for-lkdos/" - id: 21600 title: "Accessing LKDOS from Machine Code" type: "article" url: "http://localhost/article/accessing-lkdos-from-machine-code/" related_products: - id: 25918 title: "LARKEN Disk Editor" type: "product" url: "http://localhost/product/larken-disk-editor/" media_type_tags: "Utility" license: false --- # Larken Disk Editor (Larken Edition) The Larken Disk Editor is Larry Kenny’s disk maintenance program for the Larken (LKDOS) disk system, sold by Larken Electronics. **It needs a TS2068 with the Larken disk interface**; it has not been converted for tape. Its menu offers nine functions: - edit data on the disk byte by byte - read disk headers - change the head speed - reformat a single block - initialize the directory - map out bad blocks - change the disk name - catalogue and select a drive - display the track map The program is credited “By Larry Kenny”. With it on the disk is Kenny’s “Customized Catalog Command” (Cat+), an alternative CAT routine that can be added to your own programs, with its documentation (the text of his article on it), a commented assembler listing and the Zeus assembler source. Further Zeus source files give the LKDOS work-area equates and format routines for the Larken and AERCO disk controllers. The download holds the editor files (`Editor.B1` with the code blocks `Edit.C1`, `EDbas.C1` and `Form1T.Cl`), the Cat+ files and the Zeus sources as TAPs, with the Cat+ text files converted to plain text. No disk image is included: the same disk also held other commercial software (an assembler, copies of Hot Z and a Z180 monitor ROM), which is left out. ## Source Code ``` 1 2 REM --LARKEN DISK EDITOR-- 3 REM By Larry Kenny 5 REM RESET LARKEN ELECTRONICS 6 7 REM Save to Disk at 6000 8 9 10 CLEAR : BORDER 0: PAPER 0: INK 7: CLS : GO TO 40 20 CLEAR 43400: PRINT AT 7,4;"LOADING...": RANDOMIZE USR 100: OPEN #4,"dd" 30 PRINT #4: LOAD "Edit.C1"CODE 44000 35 PRINT #4: LOAD "EDbas.C1"CODE 60000 38 PRINT #4: POKE 8218,63700-256: REM Addr of Window Chars Set 40 LET Scroll=44200 50 LET Scrol2=44400 60 LET Fdir=44600 70 LET Trac=43900 80 LET Drv=43901 90 LET Cdrv=44198 100 LET buf=50000 110 LET Settrk=44000 120 LET Nextrk=44003 130 LET Format=45000 140 LET Load=44006 150 LET Save=44009 160 LET peek=44012 170 LET Nsid=43910 180 LET Ntrk=43911 190 LET Hspd=43912 200 LET peekv=43920 210 PRINT #4: GO TO PEEK Cdrv 220 BORDER 0: PAPER 0: INK 7: CLS 230 PLOT 0,30: DRAW 255,0: DRAW 0,140: DRAW -255,0: DRAW 0,-140 240 PLOT 0,145: DRAW 255,0: PRINT AT 2,4;" LARKEN DISK EDITOR" 250 PRINT AT 6,4;"1 Edit data on disk";AT 7,4;"2 Read Disk Headers";AT 8,4;"3 Change Head Speed";AT 9,4;"4 Reformat Single Block ";AT 10,4;"5 Initialize Directory " 260 PRINT AT 11,4;"6 Map out Bad Blocks";AT 12,4;"7 Change Disk Name";AT 13,4;"8 Cat/Goto Drive (Now ";PEEK Cdrv;") ";AT 14,4;"9 Display Track Map" 270 PRINT #0;" Press 1 to 9": 280 IF INKEY$="" THEN GO TO 280 290 INPUT ; 300 IF INKEY$="1" THEN GO TO 800 310 IF INKEY$="2" THEN GO TO 440 320 IF INKEY$="3" THEN GO TO 1470 330 IF INKEY$="4" THEN GO TO 1580 340 IF INKEY$="5" THEN GO TO 1780 350 IF INKEY$="6" THEN GO TO 2470 360 IF INKEY$="7" THEN GO TO 1890 370 IF INKEY$="8" THEN CLS : GO TO 400 380 IF INKEY$="9" THEN CLS : GO TO 2370 390 GO TO 270 400 INPUT "Drive # 0 - 4 :"; LINE d$: IF d$="" THEN GO TO 430 410 IF CODE d$<48 OR CODE d$>52 THEN GO TO 400 420 PRINT #4: GO TO VAL d$: POKE cdrv,VAL d$ 430 PRINT #4: CAT "",: PAUSE 0: RUN 440 CLS : PRINT " DISK DATA-HEADER READER" 450 PRINT : PRINT " This displays the file info saved on each block along with the data" 460 PRINT : PRINT "BLK - The block number on disk" 470 PRINT : PRINT "NAME - The file name of the data" 480 PRINT : PRINT "START - The start address of the code. Used for code only" 490 PRINT : PRINT "LENGTH - The total length of the file." 500 PRINT : PRINT "LINE# - The auto start line # for Basic progs only. 65535 means a non autostart prog" 510 PRINT '"'s' to pause - 'q' to quit" 520 LET ch=2: INPUT "Send to (S)creen or (P)rinter "; LINE a$ 524 IF a$="p" OR a$="P" THEN LET ch=3 530 CLS : PRINT #ch;"BLK NAME START LENTH LINE#" 540 PRINT #ch;"--------------------------------" 550 PRINT #0;"Q - Quit S - pause Ent- Cont" 560 POKE Trac,0: RANDOMIZE USR Settrk: RANDOMIZE USR load: LET sid=PEEK 50020: LET tk=PEEK 50021 570 FOR t=0 TO tk*2-1: 580 IF INKEY$="q" THEN RUN 590 IF INKEY$<>"s" THEN GO TO 620 600 IF INKEY$=CHR$ 13 THEN POKE trac,t: RANDOMIZE USR settrk: GO TO 620 610 GO TO 600 620 RANDOMIZE USR Load 630 IF PEEK 23689<=3 THEN RANDOMIZE USR Scrol2: PRINT AT 20,0; 640 PRINT #ch;PEEK (buf+1);" ";TAB 4; 650 IF PEEK (buf+1)<>0 THEN : IF PEEK (buf+1)<>t THEN PRINT #ch: PRINT #ch;"Block Number Error on Block ";t 660 IF PEEK (buf+1)=0 THEN PRINT #ch: GO TO 730 670 FOR a=(buf+2) TO (buf+10) 680 PRINT #ch;CHR$ PEEK a; 690 NEXT a 700 PRINT #ch;" ";TAB 14;PEEK (buf+12)+256*PEEK (buf+13);" "; 710 PRINT #ch;TAB 20;PEEK (buf+22)+256*PEEK (buf+23);" "; 720 PRINT #ch;TAB 26;PEEK (buf+17)+256*PEEK (buf+18)+1 730 IF Sid=1 THEN LET t=t+1:: POKE Trac,(PEEK trac)+1 740 RANDOMIZE USR Nextrk 750 NEXT t 760 BEEP .1,15: INPUT "End of Tracks "; LINE a$: RUN 770 STOP 800 CLS : PRINT PAPER 7; INK 0;"ADDRES PEEK CHARACTER " 810 PRINT #4: OPEN #5,"w0": PRINT #4: INPUT #0,0,22,31,20: PRINT #4: POKE 16014,15: PRINT #4: CLEAR 0 820 PRINT #5;" BLOCK EDITOR" 830 PRINT #5;'" COMMANDS"'"-------------"'" ENT- SCROLL"'" SPC- Step"'" N- New Num"'" C- Char Str$"'" G- Goto Addr"'" F- Find Num"'" S- Save Blok"'" Q- Main Menu"' 840 PRINT #5;'''" << EDIT LINE"''"-BUFFER INFO-"'" 50000 START"'" 55114 END" 850 PRINT INK 7; PAPER 1;AT 15,0;" " 860 LET n=1e3: INPUT "Edit which Block ? ";tr: IF tr=n THEN GO TO 890 880: POKE trac,tr: RANDOMIZE USR settrk: PRINT AT 1,0;USR load 885 PRINT #4: GO TO PEEK Cdrv 890 PRINT #5;" Block - ";PEEK Trac; 895 PRINT INK 7; PAPER 1;AT 15,0;" " 900 PRINT AT 15,0;: INK 7: PAPER 8 905 RANDOMIZE USR 60000: RUN 910 REM --Compile start here -- 920 LET l=50000: LET scroll=44200: LET Trac=43900: LET settrk=44000: LET save=44009 930 IF PEEK 23689=3 THEN RANDOMIZE USR Scroll: PRINT AT 20,0; 940 POKE 23692,255: PRINT l;TAB 7;PEEK l;TAB 12;: 950 LET nl=l: GO SUB 1290 960 IF INKEY$=" " THEN GO TO 960 970 LET a$=INKEY$: IF a$="" THEN GO TO 970 980 IF a$="n" OR a$="N" THEN BEEP .05,10: GO TO 1220 990 IF a$="s" OR a$="S" THEN BEEP .1,10: INPUT "Save back to Disk (y) ";s$: IF s$="Y" OR s$="y" THEN GO TO 1100 1000 IF a$="q" OR a$="Q" THEN GO TO 1450 1010 IF a$="c" OR a$="C" THEN BEEP .05,10: INPUT AT 0,0;"Character or String ";n$: GO TO 1130 1020 IF a$="g" OR a$="G" THEN BEEP .05,10: INPUT "Enter New Address ";l: PRINT AT 15,0;: FOR a=1 TO 7: RANDOMIZE USR Scroll: NEXT a: PRINT AT 15,0;: GO TO 940 1030 IF a$="f" OR a$="F" THEN GO TO 1040 1035 GO TO 1060 1040: BEEP .05,10: INPUT "Search for which number ";b: PRINT #0; FLASH 1;"Searching for ";b: FOR a=l TO 55120: IF PEEK a<>b THEN : NEXT a: INPUT "Sorry not found"; LINE a$: GO TO 1060 1050 INPUT ;: LET l=a: FOR a=1 TO 7: RANDOMIZE USR scroll: NEXT a: PRINT AT 15,0;: GO TO 930 1060 GO TO 1080 1070 LET l=l-1: PRINT AT 23-(PEEK 23689),0; 1080 IF l<50000 OR l>55114 THEN INPUT "Address out of Range "; LINE a$: LET a$="g": GO TO 1020 1090: LET l=l+1: GO TO 930 1100 REM ***** Resave Track**** 1110: RANDOMIZE USR Settrk: RANDOMIZE USR save 1120 GO TO 1450 1130 GO SUB 1410 1140 LET l=INT v 1150 PRINT 1160 PRINT AT 15,0;: FOR a=1 TO 6: PRINT " ": NEXT a: PRINT AT 15,0; 1170 FOR a=1 TO LEN n$ 1180 POKE l,CODE n$(a) 1190 IF PEEK 23689=3 THEN RANDOMIZE USR Scroll: PRINT AT 20,0; 1200 PRINT l;TAB 7;PEEK l;TAB 12;: LET nl=l: GO SUB 1290: LET l=l+1 1210 NEXT a: GO TO 930 1220 LET pos=PEEK 23689 1230 GO SUB 1410: LET nl=INT v 1240 INPUT "New Number :";n: POKE nl,n 1250 PRINT AT 15,0;" " 1260: PRINT AT 15,0;nl;TAB 7;PEEK nl;TAB 12;: GO SUB 1290 1270 PRINT AT 24-pos,0; 1280 GO TO 1070 1290 IF PEEK nl>=32 AND PEEK nl<245 THEN PRINT CHR$ PEEK nl: RETURN 1300 IF PEEK nl<32 THEN PRINT : RETURN 1310 IF PEEK Trac<>0 THEN GO TO 1380 1320 IF PEEK nl=254 THEN PRINT "Empty Cell";: 1330 IF PEEK nl=245 THEN PRINT "Track Used";: 1340 IF PEEK nl=249 THEN PRINT "Blocks End";: 1350 IF PEEK nl=253 THEN PRINT "Blck Start";: 1360 IF PEEK l=255 THEN PRINT "Cell Start";: 1370 PRINT : RETURN 1380 IF PEEK l<245 THEN RETURN 1390 PRINT CHR$ PEEK l: RETURN 1400 PRINT AT 15,0;50245: LET v=0: GO SUB 1410: PRINT v: STOP 1410 LET v=0: LET m=1e4: FOR a=0 TO 4 1420 LET v=v+(CODE SCREEN$ (15,a)-48)*m 1430 LET m=m/10 1440 NEXT a: RETURN 1450 GO TO 10 1460 REM --Compile End -- 1470 REM -- Head speed -- 1480 LET Hspd=50022 1490 CLS : GO SUB 2750 1500 CLS : PRINT AT 4,0;"Current Head Speed is "; 1510 POKE Trac,0: RANDOMIZE USR settrk: RANDOMIZE USR load 1520 LET h$="06122030" 1530 LET h=(PEEK Hspd)*2+1: PRINT h$(h);h$(h+1);" MS" 1540 PRINT ''"Enter 0 to 3 for new Head Speed"'';"06 MS",0,"12 MS",1,"20 MS",2,"30 MS",3,,,"Abort",4 1550 INPUT "Enter 0 to 4 : ";h: IF h>4 THEN GO TO 1550 1560 IF h=4 THEN : BEEP .1,1: BEEP .1,-7: RUN 1570 PRINT #4: POKE 8202,h: POKE Hspd,h: RANDOMIZE USR settrk: RANDOMIZE USR save: BEEP .05,10: RUN 1580 1590 1600 CLS : PRINT AT 0,2;"RE-FORMAT a SINGLE BLOCK" 1610 PRINT : PRINT "This will attempt to correct a bad block which may be either a Hard or Soft error." 1620 PRINT : PRINT " Insert the Disk Editor disk in drive 0 so the Format Code can be Loaded. "'' 1630 PRINT "Enter Disk Interface Type"''"Larken","L","Ramex","R","Aerco","A","Oliger","O" 1634 PRINT ''"If Format code has already been loaded once since powerup enter - 'Z'" 1640 INPUT "Enter Interface Type ";a$ 1650 IF a$="A" OR a$="a" THEN LET t$="a": GO TO 1700 1660 IF a$="L" OR a$="l" THEN LET t$="l": GO TO 1700 1670 IF a$="O" OR a$="o" THEN LET t$="o": GO TO 1700 1680 IF a$="R" OR a$="r" THEN LET t$="r": GO TO 1700 1685 IF a$="z" OR a$="Z" THEN : GO TO 1720 1690 GO TO 1640 1700 POKE 23728,100: PRINT #4: LOAD "Form1T.C"+t$CODE 45000 1710 IF PEEK 23728=101 THEN CLS : PRINT AT 10,2;"'Form1T.C"+t$+"' Not Found": BEEP .1,1: BEEP .1,-5: PAUSE 0: RUN 1720 PRINT AT 5,0;: FOR a=1 TO 16: PRINT " ": NEXT a 1730 INPUT " Insert Disk to be Altered "; LINE a$ 1740 GO SUB 2110 1750 INPUT "Enter Block # ";b: POKE trac,b: PRINT AT 10,0;" Formating Block ";b 1760 INPUT "Ok to ReFormat (y) ";a$: IF a$="Y" OR a$="y" THEN RANDOMIZE USR Format 1770: RUN 1780 1790 CLS : PRINT AT 2,0;" This will create a Blank Catalog on the disk but not change the Disk Name."''" All files will be deleted !" 1800 PRINT ''" Enter Drive Parameters" 1810 GO SUB 2200 1820 PRINT ''"Head Speed",h,"Sides",a,"Tracks",numtrks 1830 GO SUB 2750 1840 INPUT "Ok to Init Catalog (y) ";a$: IF a$="y" OR a$="Y" THEN POKE trac,0: RANDOMIZE USR settrk: RANDOMIZE USR load: RANDOMIZE USR Fdir: RANDOMIZE USR settrk: RANDOMIZE USR save 1850 BEEP .1,10: RUN 1860 1870 1880 1890: CLS : POKE trac,0: RANDOMIZE USR settrk: RANDOMIZE USR load 1895 PRINT #4: GO TO PEEK Cdrv 1900 PRINT : PRINT " "; FLASH 1;" Enter Disk Name" 1910 PRINT "Press STOP (SS 'A') to end name": PRINT 1920: PRINT "Disk Name : "; 1930 LET m=54500 1940 LET a$=INKEY$: IF INKEY$="" THEN GO TO 1940 1950 IF CODE a$=0 THEN GO TO 1940 1960 BEEP .02,1 1970 IF CODE a$=12 THEN PRINT CHR$ 8;CHR$ 32;CHR$ 8;: LET m=m-1: GO TO 2020 1980 IF CODE a$=226 THEN POKE m,0: GO TO 2040 1990 POKE m,CODE a$ 2000 PRINT a$; 2010 LET m=m+1 2020 IF INKEY$<>"" THEN GO TO 2020 2030 GO TO 1940 2040 POKE m,0: BEEP .1,20: BEEP .1,20: GO SUB 2750: INPUT "Ok to save to catalog (y) ?"; LINE a$: IF a$="y" OR a$="Y" THEN RANDOMIZE USR settrk: RANDOMIZE USR save: RUN 2050 RUN 2060 2070 2080 2090 PRINT "Drive Parameters": PRINT : PRINT "Drive #",dv-1,"Head Speed",h,"No of Sides",a,"No of Tracks",numtrks 2100 GO TO 2370 2110 REM 2120 2130 2140 REM ** DRIVE PARAMETERS ** 2150 INPUT "Enter Drive 0 to 3 ? ";dv: 2160 IF dv>3 THEN GO TO 2150 2170 PRINT #4: GO TO dv: LET dv=dv+1 2180 LET a=2^dv: POKE drv,a 2190 RETURN 2200 POKE Hspd,0: REM 6=0 12=1 20=2 30=3 2210 INPUT "Head speed 6 12 20 30 MS ? ";h 2220 IF h=6 OR h=12 OR h=20 OR h=30 THEN GO TO 2240 2230 GO TO 2210 2240 IF h=6 THEN LET a=0 2250 IF h=12 THEN LET a=1 2260 IF h=20 THEN LET a=2 2270 IF h=30 THEN LET a=3 2280 POKE Hspd,a 2290 INPUT "Number of Sides '1 or 2' ";a 2300 IF a=1 THEN GO TO 2330 2310 IF a=2 THEN GO TO 2330 2320 GO TO 2290 2330: POKE Nsid,a 2340 INPUT "Number of Tracks 35,40 or 80 ";Numtrks 2350 POKE Ntrk,Numtrks 2360 RETURN 2370 REM Display Track Map 2380 CLS : POKE trac,0: RANDOMIZE USR settrk: RANDOMIZE USR load 2385 PRINT #4: GO TO PEEK Cdrv 2390 PRINT " TRACK MAP REPRESENTATION"'': PRINT "X = Used Blocks O = Free Blocks"''; PAPER 1;" 0 1 2 3 4 5 6 7 8 9": LET l=50024 2400 FOR x=0 TO 15 2410 PRINT x;TAB 4; 2420 FOR y=1 TO 10 2430 PRINT ("X" AND PEEK l=245)+("O" AND PEEK l<>245);" ";: LET l=l+1 2435 IF PEEK l=255 THEN GO TO 2460 2440 NEXT y: PRINT 2450 NEXT x 2460 BEEP .05,20: PRINT #0;"Press any Key for Main Menu ": PAUSE 0: RUN 2470 REM Bad blocks Mapout 2480 CLS : PRINT AT 5,4;"One Moment Please" 2490 FOR a=43500 TO 43670: POKE a,255: NEXT a: LET p=43500 2500 CLS : PRINT " BAD BLOCK SCAN" 2510 POKE trac,0: RANDOMIZE USR settrk: RANDOMIZE USR load 2520 LET s=PEEK 50020: LET t=PEEK 50021 2530 PRINT AT 10,2;"Tracks ";t,"Sides ";s 2540 FOR a=0 TO t*2-1 2550 PRINT AT 2,0;: RANDOMIZE USR load: IF PEEK 23689<>22 THEN POKE p,PEEK trac: LET p=p+1: PRINT AT 2,0;" ": PRINT AT 2,0; 2560 RANDOMIZE USR Nextrk: IF s=1 THEN RANDOMIZE USR nextrk: LET a=a+1 2570 NEXT a 2580 CLS : PRINT "List of Bad blocks found"'': FOR a=43500 TO 43670 2590 IF PEEK a=255 THEN GO TO 2620 2600 PRINT PEEK a;" "; 2610 NEXT a 2620 PRINT ''"End"''"Total Found ";p-43500 2630 IF p-43500=0 THEN CLS : PRINT AT 5,3;"NO BAD BLOCKS FOUND": PAUSE 200: RUN 2640 GO SUB 2750 2650 PAUSE 60: BEEP .1,10: PRINT '''''" Are you sure you want these Mapped Out of the track map ?": 2660 INPUT "Map them out ? (y) ";a$: IF a$="y" OR a$="Y" THEN GO TO 2680 2670 CLS : PRINT AT 5,3;"Mapping Aborted !!": PAUSE 200: RUN 2680 POKE trac,0: RANDOMIZE USR settrk: RANDOMIZE USR load 2690 FOR a=43500 TO 43670 2700 IF PEEK a=255 THEN GO TO 2730 2710 POKE 50024+PEEK a,245 2720 NEXT a 2730 POKE trac,0: RANDOMIZE USR settrk: RANDOMIZE USR save 2740 BEEP .1,10: RUN 2750 BEEP .05,10: BEEP .05,10: INPUT " Disk must have Write protect Removed OK "; LINE a$: RETURN 6000 PRINT #4: SAVE "Editor.B1" LINE 20: PRINT #4: SAVE "Edit.C1"CODE 44000,1000: PRINT #4: SAVE "EDbas.C1"CODE 60000,4600 ```