SADOS+

Date: 1983
Type: Diskette
Platform(s): TS 1000
Tags: DOS

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 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.

Related Products

Supports 1-4 drives of any size, single/double density. Software driver in EPROM.

Image Gallery

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

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