--- title: "SADOS+" id: 72722 type: "computer_media" slug: "sados" url: "http://localhost/computer_media/sados/" markdown_url: "http://localhost/computer_media/sados.md" published_at: "2026-10-26T23:19:25+00:00" modified_at: "2026-10-26T23:19:25+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/10/menu-16k.png" excerpt: "AERCO's menu-driven disk operating system for its FD-ZX floppy interface, with page-based load, save, copy, format, directory names and a hex monitor." post_tag: - name: "AERCO" slug: "aerco" taxonomy: "post_tag" url: "http://localhost/tag/aerco/" - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Sinclair ZX81" slug: "zx81" taxonomy: "model" url: "http://localhost/model/zx81/" - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "DOS" slug: "dos" taxonomy: "genre" url: "http://localhost/type/dos/" media_type: "Diskette" download_url: "https://archive.org/download/timex-sinclair-software-archive/SADOS%2B%20%281983%29%28AERCO%29%28TS1000%29%28US%29%28Diskette%29.zip" mediadate: "1983" producer_company: - id: 10635 title: "AERCO" type: "company" url: "http://localhost/company/aerco/" images: - url: "http://localhost/wp-content/uploads/2026/10/menu-16k.png" - url: "http://localhost/wp-content/uploads/2026/10/directory-16k.png" - url: "http://localhost/wp-content/uploads/2026/10/directory-64k.png" - url: "http://localhost/wp-content/uploads/2026/10/label.jpg" related_products: - id: 12601 title: "FD-ZX Floppy Disk Interface" type: "product" url: "http://localhost/product/floppy-disk-interface/" related_content: - id: 54609 title: "AERCO Model FD-ZX Instructions" type: "document" url: "http://localhost/document/aerco-model-fd-zx-instructions/" - id: 70681 title: "FD-ZX Floppy Disk Interface Unofficial Technical Manual" type: "document" url: "http://localhost/document/fd-zx-floppy-disk-interface-unofficial-technical-manual/" media_type_tags: "DOS" license: false --- # SADOS+ SADOS+ is the disk operating system AERCO supplied with its FD-ZX floppy disk interface for the ZX81 and TS1000. It is a BASIC menu program that calls the machine code in the interface’s EPROM at address 12288. The menu offers C to copy a disk (with two drives), D for disk utilities, E to enter names in the directory, F to format the disk in drive A, H for a hex monitor, L to load memory from disk, S to save memory to disk, and Q to quit. The disk is divided into numbered pages. L lists the page names and loads a page by number, and S saves memory to a page you choose. Option 99 on the directory screen prints a hard copy. There are two versions on the disk. “SADOS+ 16K (40 TRACK)” on page 1 is the boot program and handles twenty 16K pages. “SADOS+ 64K” on page 2 handles six 64K pages instead. Both title screens are dated 8/83. You need a real ZX81 or TS1000 with the AERCO FD-ZX interface; the disk boots with `RAND USR 13303`. In an emulator the programs show the menu and the directory, but the disk functions do nothing. The disk is labelled “COPY OF ORIGINALLY SUPPLIED AERCO ‘SADOS’ DISK”. Its directory lists only the two SADOS+ programs. Pages 10, 11 and 20, which are not in the directory, hold leftover copies of page 1. The copies on pages 10 and 20 match it, but the one on page 11 is damaged and is not in the download. The download holds the two programs as `.p` files, the complete disk image and a README on the page format. [BBDOS](/?p=72719) by Bill Bell later replaced SADOS with a DOS that handles files by name. ## Program Analysis ### Program Structure - Lines 100-225: the main menu, read with `INKEY$`, and the L option. L prints the directory from `Q$` and loads the chosen page with `RAND USR (BASE+2+P)` (16K) or `RAND USR (BASE+3+(P-1)*3)` / `(BASE+4+(P-1)*3)` (64K). - Lines 230-260: S asks for a page number and calls `RAND USR (BASE+432+P)` (16K) or `(BASE+1712+P)` (64K). - Line 265 onward: format, after an “OK TO ERASE ALL FILES ON DISC A?” check, then `RAND USR (BASE+1024)`. Later lines handle disk copy, entering directory names, the disk utilities and the hex monitor. ### Notable Techniques - The directory is not stored separately on the disk. It is the string array `Q$(20,24)` inside the page 1 program, so changing a name means saving SADOS itself again. - Each page is a raw memory image starting at 16393. Loading a page replaces the whole BASIC system, including SADOS, with the program that was saved. ### Potential Issues - In the 64K version, line 216 skips line 217 only for pages above 3. Pages 1-3 run `RAND USR (BASE+3+(P-1)*3)` and then fall through to line 218’s `RAND USR (BASE+4+(P-1)*3)`. That appears harmless only if the first call never returns. The programs came from an AERCO FD-ZX disk in Joe’s collection, read with a new reader for FD-ZX disk images. In ZEsarUX, both versions were loaded on an emulated ZX81 and showed their menus and directory screens. The disk functions were not tested, because they need the AERCO interface. ## Source Code ``` 100 LET BASE=12288 105 FAST 110 CLS 115 PRINT " WELCOME TO SADOS+ 16K 8/83",,,,,"C COPY DISC (REQUIRES 2 DRIVES)",,"D DISC UTILITIES",,,"E ENTER NAMES IN DIRECTORY",,,"F FORMAT DISC IN DRIVE A",,,"H HEX MONITOR",,,,"L LOAD MEMORY FROM DISC",,,"Q QUIT",,,,"S SAVE MEMORY ON DISC" 120 SLOW 125 IF INKEY$ ="" THEN GOTO 0125 127 LET C$=INKEY$ 130 IF C$<>"Q" THEN GOTO 0145 135 FAST 140 STOP 145 IF C$="C" THEN GOTO 0430 150 IF C$="E" THEN GOTO 0300 155 IF C$="H" THEN GOTO 0670 160 IF C$="D" THEN GOTO 0485 165 IF C$<>"L" THEN GOTO 0230 170 FAST 175 CLS 180 PRINT AT 0,0;" 1. ";Q$(1)," 2. ";Q$(2)," 3. ";Q$(3)," 4. ";Q$(4)," 5. ";Q$(5)," 6. ";Q$(6)," 7. ";Q$(7)," 8. ";Q$(8)," 9. ";Q$(9),"10. ";Q$(10),"11. ";Q$(11),"12. ";Q$(12),"13. ";Q$(13),"14. ";Q$(14),"15. ";Q$(15),"16. ";Q$(16),"17. ";Q$(17),"18. ";Q$(18),"19. ";Q$(19),"20. ";Q$(20),"99. HARD COPY",," 0. RETURN TO MENU" 185 SLOW 190 INPUT P 195 IF P=0 THEN GOTO 0105 200 IF P<>99 THEN GOTO 0215 205 PRINT AT 20,0;" " 210 COPY 215 IF P>20 THEN GOTO 0170 220 RAND USR (BASE+2+P) 225 GOTO 0105 230 IF C$<>"S" THEN GOTO 0265 235 PRINT AT 21,0;"ENTER PAGE NUMBER 1 TO 20" 240 INPUT P 245 IF P=0 THEN GOTO 0105 250 IF P>20 THEN GOTO 0240 255 RAND USR (BASE+432+P) 260 GOTO 0105 265 IF C$<>"F" THEN GOTO 0125 270 GOSUB 0635 275 PRINT AT 19,0;"OK TO ERASE ALL FILES ON DISC A? (Y/N) " 280 IF INKEY$ ="N" THEN GOTO 0105 285 IF INKEY$ <>"Y" THEN GOTO 0280 290 IF INKEY$ ="Y" THEN RAND USR (BASE+1024) 295 GOTO 0105 300 FAST 305 CLS 310 PRINT AT 3,0;"ENTER PROGRAM NUMBER:(1 TO 20)",,,"0 TO ABORT" 315 INPUT CC 320 IF CC<=0 THEN GOTO 0105 325 IF CC>20 THEN GOTO 0305 330 PRINT AT 3,20;" ";CC;" ",,,"ENTER NAME OF PROGRAM:" 335 INPUT Q$(CC) 340 PRINT AT 5,0;CC;".";" ";Q$(CC),,,"IS THIS CORRECT? (Y/N)" 345 SLOW 350 IF INKEY$ ="" THEN GOTO 0350 355 IF INKEY$ ="N" THEN GOTO 0300 360 IF INKEY$ ="Y" THEN GOTO 0370 365 IF INKEY$ <>"Y" THEN GOTO 0350 370 FAST 375 CLS 380 PRINT AT 6,0;" ";CC;". ";Q$(CC),,," THE ABOVE HAS BEEN ENTERED",,," INTO THE DIRECTORY.",,,"MORE DIRECTORY ENTRIES? (Y/N)" 385 SLOW 390 IF INKEY$ <>"" THEN GOTO 0390 395 IF INKEY$ ="" THEN GOTO 0395 400 IF INKEY$ ="Y" THEN GOTO 0300 405 PRINT ,,"SAVE DOS ON DISC PAGE 1? (Y/N)" 407 LET P=1 410 IF INKEY$ <>"" THEN GOTO 0410 415 IF INKEY$ ="" THEN GOTO 0415 420 IF INKEY$ ="Y" THEN RAND USR (BASE+433) 425 GOTO 0105 430 FAST 435 CLS 440 PRINT " DISC COPY ROUTINE",,,,,,,"PLACE ORIGINAL DISC IN DRIVE B",,,"PLACE FORMATTED DISC IN DRIVE A",,,"PRESS C TO COPY",,,,"PRESS Q TO ABORT" 445 SLOW 450 IF INKEY$ <>"" THEN GOTO 0450 455 IF INKEY$ ="" THEN GOTO 0455 460 IF INKEY$ ="Q" THEN GOTO 0105 465 IF INKEY$ ="C" THEN GOTO 0475 470 GOTO 0455 475 RAND USR (BASE+1472) 480 GOTO 0105 485 FAST 490 CLS 495 PRINT " DISC CONTROL UTILITIES",,,,,,,"C CLEAR DIRECTORY",,,"D SET DATA MODE",,,"P SET PROGRAM MODE",,,"R RETURN TO MAIN MENU",,,"T TRANSFER DISC DRIVE" 500 SLOW 505 IF INKEY$ <>"" THEN GOTO 0505 510 IF INKEY$ ="R" THEN GOTO 0105 515 IF INKEY$ <>"C" THEN GOTO 0550 520 CLS 525 DIM Q$(20,24) 530 PRINT AT 10,5;"DIRECTORY IS NOW BLANK" 535 FOR Z=1 TO 30 540 NEXT Z 545 GOTO 0105 550 IF INKEY$ <>"D" THEN GOTO 0565 555 RAND USR (BASE+1610) 560 GOTO 0105 565 IF INKEY$ <>"P" THEN GOTO 0580 570 RAND USR (BASE+1603) 575 GOTO 0105 580 IF INKEY$ <>"T" THEN GOTO 0510 585 PRINT AT 19,0;"SELECT DRIVE: A/B/C/D Q TO QUIT" 590 IF INKEY$ ="" THEN GOTO 0590 595 IF INKEY$ ="Q" THEN GOTO 0105 600 LET D=CODE INKEY$ 605 IF D<38 OR D>41 THEN GOTO 0590 610 RAND USR (BASE+977+D-38) 615 GOSUB 0635 620 RAND USR (BASE+512) 625 RAND USR (BASE+564) 630 GOTO 0105 635 PRINT AT 19,0;"(S)INGLE (D)OUBLE DENSITY (Q)UIT" 640 IF INKEY$ ="" THEN GOTO 0640 645 IF INKEY$ ="Q" THEN GOTO 0105 650 IF INKEY$ ="S" THEN RAND USR (BASE+752) 655 IF INKEY$ ="D" THEN RAND USR (BASE+1002) 660 IF INKEY$ <>"D" AND INKEY$ <>"S" THEN GOTO 0640 665 RETURN 670 FAST 675 CLS 680 GOSUB 0985 685 SCROLL 690 PRINT "HEX START ADR" 695 INPUT H$ 700 IF H$="Q" THEN GOTO 1 705 GOSUB 1075 710 LET DADR=DEC 715 IF DADR<0 THEN LET DADR=DADR+65536 720 IF DADR>65535 THEN LET DADR=DADR-65536 725 SCROLL 730 GOSUB 0925 735 INPUT H$ 740 IF H$="Q" THEN GOTO 1 745 IF H$<>"" THEN GOTO 0760 750 LET DADR=DADR+1 755 GOTO 0715 760 IF H$<>":" THEN GOTO 0775 765 LET DADR=DADR-16 770 GOTO 0715 775 IF H$<>"Z" THEN GOTO 0790 780 LET DADR=DADR-1 785 GOTO 0715 790 IF H$<>"S" THEN GOTO 0805 795 LET DADR=DADR+16 800 GOTO 0715 805 IF H$<>" LPRINT " THEN GOTO 0820 810 LET DADR=DADR+256 815 GOTO 0715 820 IF LEN H$<2 THEN GOTO 1010 825 IF H$(1)<>"R" THEN GOTO 0840 830 LET H$=H$(LEN H$-(LEN H$-2) TO ) 835 GOTO 0700 840 IF H$(1)<>"G" THEN GOTO 0860 845 LET H$=H$(LEN H$-(LEN H$-2) TO ) 850 GOTO VAL H$ 855 GOTO 0715 860 IF H$(1)<>"H" THEN GOTO 0880 865 LET H$=H$(LEN H$-(LEN H$-2) TO ) 870 GOSUB VAL H$ 875 GOTO 0715 880 GOTO 0885 885 LET H$=H$((LEN H$-1) TO ) 890 GOSUB 1075 895 IF DEC<0 THEN GOTO 0715 900 IF DEC>255 THEN GOTO 0715 905 POKE DADR,DEC 910 PRINT AT 21,0; 915 GOSUB 0925 920 GOTO 0750 925 LET DEC=DADR 930 GOSUB 1040 935 PRINT " (";DEC;")"; 940 PRINT AT 21,13;"= "; 945 LET DDATA=PEEK DADR 950 LET C$=CHR$ DDATA 955 LET DEC=DDATA 960 GOSUB 1020 965 PRINT " (";DDATA;") "; 970 PRINT AT 21,24;" " 975 PRINT AT 21,24 ;C$ 980 RETURN 985 PRINT AT 14,0;" HIMON 1.9 14 AUG 82" 990 PRINT "Q=QUIT R(ADR)=RSTRT ENT=INC 1" 995 PRINT "S=+16 (SH)S=+256 Z=-1 :=-16" 1000 PRINT "G(LIN)=GOTO H(LIN)=GOSUB" 1005 RETURN 1010 GOSUB 0985 1015 GOTO 0735 1020 LET DEC1=INT (DEC/16) 1025 PRINT CHR$ (DEC1+28); 1030 PRINT CHR$ (DEC-16*DEC1+28); 1035 RETURN 1040 LET DDEC=DEC 1045 LET DEC=INT (DDEC/256) 1050 GOSUB 1020 1055 LET DEC=DDEC-256*DEC 1060 GOSUB 1020 1065 LET DEC=DDEC 1070 RETURN 1075 LET VALH=1 1080 LET DEC=0 1085 IF LEN H$>4 THEN LET H$=H$(LEN H$-3 TO ) 1090 LET LENH=LEN H$ 1095 IF LENH<=0 THEN RETURN 1100 LET DEC=DEC+(CODE H$(LENH)-28)*VALH 1105 LET VALH=VALH*16 1110 LET LENH=LENH-1 1115 GOTO 1095 ```