Larken Disk Editor (Larken Edition)

Developer(s): Larry Kenny
Date: 1989
Type: Diskette
Platform(s): TS 2068
Tags: Utility

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.

Related Products

Examine or change any byte on a LKdos disk. Useful in repairing damaged or glitched disks, changing the disk name or head speed, etc. You can also examine the track map and disk info headers.

Related Articles

The DOS is easy to access from machine code using the internal jump table starting at address 120 in the cartridge.
This is an alternative catalog command that can be added to your programs or to use when modifying an existing program for disk.

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

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.