;e000 This is a commented disassembly of the DOS V1 as used ;e000 in the Commodore 2040 dual disk drive. The disassembly ;e000 is taken from the images of the ROM chips named ;e000 "901468-06.bin" and "901468-07.bin". ;e000 ; ;e000 Technically the disassembly was produced and merged ;e000 with the comments using the "recomment" utility ;e000 (version 4.08 at least). ;e000 ; ;e000 To create the comments, I compared the ROM source code ;e000 of the 4040 dual disk drive with DOS V2. The uppercase ;e000 comments are copied from the 4040 DOS. I have added the ;e000 (few) lowercase comments myself. ;e000 ; ;e000 In general there is only littel code that remains unchanged, ;e000 if any at all. A lot of code only has minor changes, though. ;e000 Some code has major changes. ;e000 ; ;e000 I found an interesting comment for routine "USER" in the 4040 ;e000 ROM. The comment is "ROM 1.1 ADDITIONS" and seems to indicate ;e000 that there was a version before the 2040 DOS version, ;e000 because the USER command already exists in the 2040. ;e000 ; ;e000 I was unable to completely relate the code to the new version ;e000 as used in the 4040. I could not relate the following methods: ;e000 ED53 ;e000 F482 ;e000 F67A, F80F, F851 ;e000 ; ;e000 15. May 2005 Andre Fachat (afachat@gmx.de) ;e000 ; CMDBUF=0+27 BMPNT=28+1 TEMP=2a+5 IP=30+1 LSNADR=32 TLKADR=33 LSNACT=34 TLKACT=35 ADRSED=36 ENTFND=37 DIRLST=38 CMDWAT=3a LINUSE=3c BUFTAB=3d+1 BUFNUM=5f+15 DRVNUM=80 TRACK=81 SECTOR=82 LINDX=83 SA=84 ORGSA=85 DATA=87 EOIFLG=88 CMD=89 LSTSEC=8a BUFUSE=8b+1 JOBNUM=8d DISKID=8e+1 SECINC=92 DIRBUF=93+1 CMDSIZ=95 CMDNUM=96 CHAR=97 LIMIT=98 F1CNT=99 R0=9a F1PTR=9b F2PTR=9c FILTBL=9d+1 FILENT=a2 FILDAT=a7+1 FILTRK=ac FILSEC=b1+2 FILTYP=b6 CHNRDY=be+7 LSTCHR=c6+7 PATFLG=ce IMAGE=cf DRVCNT=d0 DRVFLG=d1 LSTDRV=d2 FOUND=d3 DIRSEC=d4 DELSEC=d5 DELIND=d6 LSTBUF=d7 INDEX=d8 FILCNT=d9 TYPFLG=da USRJMP=dd+1 ! MOS6532-1 ! IEEE data in RIOT1IEEEDI=0200 ! IEEE data dir RIOT1PADD=0201 ! IEEE data out RIOT1IEEEDO=0202 ! IEEE data out dir RIOT1PBDD=0203 ! MOS6532-2 ! IEEE control port RIOT2PAD=0280 RIOT2PADD=0281 ! bit0-2 device select ! bit3 active LED 0 ! bit4 active LED 1 ! bit5 hardware init error LED RIOT2PBD=0282 RIOT2PBDD=0283 RIOT2ATNPE=0287 ! some of these ranges are estimates &JOBS=1003+5 HDRS=1021+1f LSTJOB=1099 ERRCNT=10a8 CHNDAT=10d9+f ERWORD=10e9 NBTEMP=10ed+1 &BUFS=1100+04ff NAMBUF=42b4+13-1 ERRBUF=43b4+f ATNIRQ=e2d6 DSKINT=e18e &CMDTBL=e000+9 &CJUMPL=e00a+9 &CJUMPH=e014+9 &TRKTBL=e022+3 &CHGTRACKS=e026+3 &MODLST=e02e+2 &TYPLST=e031+3 &TP1LST=e035+3 &TP2LST=e039+3 &CODE=e040+140 DROMTS=e181 DIAGROM=d000+0fff FORMAT=fb14 UBLKRD=FF26 UBLKWT=FF65 MAXSEC=e5b1 ERROR=e6b3 SETH=e86b INITDR=e8c1 ENDCMD=f075 CPYTRK=fa51 INTDRV=e8a8 VERDIR=fc37 DUPLCT=f9ed MEM=fced BLOCK=fde5 USER=fd43 DSKCPY=fb47 RENAME=fbd3 SCRTCH=f973 NEW=f8c8 ;e000 INIT-DRIVE VEIFY-DIR DUPLICATE MEMORY-OP BLOCK-OP USER POSITION DSKCPY RENAME SCRATCH NEW e00a INTDRV, >VERDIR, >DUPLCT, >MEM, >BLOCK, >USER, >DSKCPY, >RENAME, >SCRTCH, >NEW ;e01e; ;e01e original 4040 comment for the next bytes ;e01e the bytes for RENAMEi ($dd), SCRATCH ($1c) and NEW ($9e) seem to be the same at the ;e01e same place, but DSKCPY is different (here $d9, in 4040 it's $51) ;e01e and LOAD is missing here. ;e01e ;e01e ; STRUCTURE IMAGES FOR CMDS ;e01e PCMD =8 ;e01e .BYT %01010001 ; DSKCPY ;e01e STRUCT =*-PCMD ; CMDS NOT PARSED ;e01e .BYT %11011101 ; RENAME ;e01e .BYT %00011100 ; SCRATCH ;e01e .BYT %10011110 ; NEW ;e01e LDCMD =*-STRUCT ; LOAD CMD IMAGE ;e01e .BYT %00011100 ; LOAD ;e01e ; --- --- ;e01e ; PGDRPGDR ;e01e ; FS1 FS2 ;e01e; ;e01e ; BIT REPS: NOT PATTERN ;e01e ; NOT GREATER THAN ONE FILE ;e01e ; NOT DEFAULT DRIVE(S) ;e01e ; REQUIRED FILENAME e022 number of sectors per track (from hi to lo) e026 highest track of each speed zone e02a last byte of a BAM track entry per speed zone e02e list of file modes e031 filetypes available "DEL", "SEQ", "PRG", "USR". Note: no "REL"! e03d ; *e040 DATA e040 start of special routine to be copied to controller buffer e181 test for diagnostic ROM e18e RESET drive e199 DAVO+EOIO+RFDO e1a3 ERRLED+ACTLDB+ACTLDA e1ab test zeropage e1c3 check for diagnostic ROM e1c6 not here, goto E-ROM test e1c8 diagnostic hook ROMTST=e1cb e1de zeropage bad ZPBAD=e1de e1e2 endless loop EROMCHK=e1e4 e1f6 ok, goto F-ROM check FROMCHK=e1fe BADE=e1f8 DIAGOK=e214 BADF=e20e e1f8 this stores into ROM? e1fb endless loop e20e this stores into ROM? e211 endless loop e219 compute primary IEEE address e226 init command channel INTTAB=edd6 LINTAB=10b7+0021 e23c CMDRD e241 CMDWRT e268 init user jump e26b setup sector offset e26f allow ATN to interrupt IDLE=e272 IDLE2=e27e PARSXQ=f044 e27b parse and execute command e27e test for drive running or openfile e289 look thru LINTAB e28e for active file GETACT=e89d e298 determine which drv is on e2a0 set flag indicating drive e2a2 has file open e2a4 look through job queue e2a6 for jobs still running e2ae set flag indicating drive e2b0 is active e2b6 255-ACTLDA-ACTLDB e2bf turn on LED if drive flag e2c2 ACTLDB if not 0 e2ce ACTLDA e2d6 IRQ routine (triggered by ATN), listen to PET e2d8 clear stack e2d9 clear IRQ flag e2dc DAVO+EOIO e2de free control lines e2e6 clear data lines e2e9 DACO+RFDO+ATNA e2f4 DAV LO e2f6 ATN LO ATNI HI e2f8 ATN HI e2fa 255-RFDO; NRFD LO e302 save EOI e30b save command e30d 255-DACO; NDAC HI e31b TALK? e31f LISTEN? e323 SECONDARY? e327 OTHER e32d my listen address e32f UNLISTEN e335 not primary ADDRSED e340 default SA e344 PRIMARY ADDRESSED e35c NOT ADDRESSED e364 CLOSE? CLOSE=ec0f e379 255-RFDO-ATNA LISTEN=e39b e388 255-RFDO-ATNA TALK=e42b e39b RFD HI e3a3 DAV LO FNDWCH=e9ad e3a8 WAS LDX SA e3af ok, open for LISTEN e3b2 WAS TXA e3b4 SA=OPEN? e3bc save? e3c5 255-DACO e3ce 255-RFDO, ACCEPT ALL DATA e3d3 RFD LOW e3d6 255-DACO e3db DAC HI e3de DAV HI e3e3 DACO e3e8 DAC LOW e3eb RFDO, RFD HI e3f3 WAIT DAV LOW e3f8 Do UNTIL ATn PULLED e3fb 255-RFDO e303 EOII e40f 255-DACO e41c DACO PUT=e7fe FNDRCH=e9b0 e42e TEST IF CHANNEL READY NOTLK=e436 e437 RFD HI e446 255-EOIO-DAVO, DAV LO e455 DAVO+EOIO GET=ecd6 e46d DAVO+EOIO e47a END OF IEEE ;e47c NEXT TRACK & SECTOR ;e47c RETURNS NEXT AVAILABLE TRACK & SECTOR ;e47c GIVEN CURRENT T & S ;e47c ; ;e47c ALLOCATION IS FROM TRACK 18 ;e47c TOWARDS 1 & 35, BY FULL TRACKS e4c1 DSKFUL FNDNXT=e4d8 ;e4d8 FIND THE NEXT OPTIMUM SECTOR ;e4d8 NEXT SECTOR=CURRENT SECTOR+N ;e51b RETURNS OPTIMUM INITIAL TRACK, SECTOR e53b DSKFUL FNDSEC=e542 e557 DIRERR ;e55f SET (INDIRECT) BAM PNTR BY DRVNUM ;e56b LOAD TRACK BAM INTO TEMP AND FINDS ;e56b AVAILABLE SECTOR ON THE TRACK ;e593 BIT MAP VALIDITY CHECK e597 (BRANCH) e5a9 DIRERR ;e5b1 .A=TRACK # ,RETURNS #SECTORS ON THIS TRACK &TRKNUM=e5bd+3-1 &NUMSEC=e5c1+3 !error table ;e5c5 ; ;e5c5 this is the original comment on the error table in the 4040 ;e5c5 of course the table here is similar, but still different. ;e5c5 ; ;e5c5 ; CONTROLLER ERRORS ;e5c5 ; 0 (1) NO ERROR ;e5c5 ; 20 (2) CAN'T FIND BLOCK HEADER ;e5c5 ; 21 (3) NO SYNCH CHARACTER ;e5c5 ; 22 (4) DATA BLOCK NOT PRESENT ;e5c5 ; 23 (5) CHECKSUM ERROR IN DATA ;e5c5 ; 24 (16) BYTE DECODING ERROR ;e5c5 ; 25 (7) WRITE-VERIFY ERROR ;e5c5 ; 26 (8) WRITE W/ WRITE PROTECT ON ;e5c5 ; 27 (9) CHECKSUM ERROR IN HEADER ;e5c5 ; 28 (10) DATA EXTENDS INTO NEXT BLOCK ;e5c5 ; 29 (11) DISK I.D. MISMATCH ;e5c5 .SKIP ;e5c5 ; COMMAND ERRORS ;e5c5 ; 30 GENERAL SYNTAX ;e5c5 ; 31 INVALID COMMAND ;e5c5 ; 32 LONG LINE ;e5c5 ; 33 INVALID FILNAME ;e5c5 ; 34 NO FILE GIVEN ;e5c5 .SKIP ;e5c5 ; 50 RECORD NOT PRESENT ;e5c5 ; 51 OVERFLOW IN RECORD ;e5c5 ; 52 FILE TOO LARGE ;e5c5 .SKIP ;e5c5 ; 60 FILE OPEN FOR WRITE ;e5c5 ; 61 FILE NOT OPEN ;e5c5 ; 62 FILE NOT FOUND ;e5c5 ; 63 FILE EXISTS ;e5c5 ; 64 FILE TYPE MISMATCH ;e5c5 ; 65 NO BLOCK ;e5c5 ; 66 ILLEGAL TRACK OR SECTOR ;e5c5 ; 67 ILLEGAL SYSTEM T OR S ;e5c5 .SKIP ;e5c5 ; 70 NO CHANNELS AVAILABLE ;e5c5 ; 71 DIRECTORY ERROR ;e5c5 ; 72 DISK FULL ;e5c5 ; 73 CBM DOS V2 ;e5c5 .SKIP ;e5c5 ; 1 FILES SCRATCHED RESPONSE ;e5c5 .SKIP2 ;e5c5 BADSYN =$30 ;e5c5 BADCMD =$31 ;e5c5 LONGLN =$32 ;e5c5 BADFN =$33 ;e5c5 NOFILE =$34 ;e5c5 NOREC =$50 ;e5c5 RECOVF =$51 ;e5c5 BIGFIL =$52 ;e5c5 FILOPN =$60 ;e5c5 FILNOP =$61 ;e5c5 FLNTFD =$62 ;e5c5 FLEXST =$63 ;e5c5 MISTYP =$64 ;e5c5 NOBLK =$65 ;e5c5 BADTS =$66 ;e5c5 NOCHNL =$70 ;e5c5 DIRERR =$71 ;e5c5 DSKFUL =$72 ;e5c5 CBMV2 =$73 ;e5c5 .PAGE ;e5c5 ; ERROR MESSAGE TABLE ;e5c5 ; LEADING ERRROR NUMBERS, ;e5c5 ; TEXT WITH 1ST & LAST CHARS ;e5c5 ; OR'ED WITH $80, ;e5c5 ; TOKENS FOR KEY WORDS ARE ;e5c5 ; LESS THAN $10 (AND'ED W/ $80) &ERRTAB=e5c5 &e_read=e5c9 &e_write=e5d4 &e_prot=e5d8 &e_id=e5e5 &e_synt=e5eb &e_wfile=e5f7 &e_exist=e5fb &e_type=e604 &e_block=e60c &e_fnotop=e615 &e_fnotfnd=e619 &e_scratchd=e61d &e_nchanl=e62a &e_dir=e635 &e_dskfull=e63a &t_error=e641 &t_write=e647 &t_file=e64d &t_open=e652 &t_mismatch=e657 &t_not=e660 &t_found=e664 &t_disk=e66a !end error table ;e66f RECURSIVE (2) ERROR MESSAGE ROUTINE e66f .A=BCD ERROR # e675 ERREND e67a SKIP PAST ERROR #'S e690 LAST CHARACTER e695 TOKEN e69d TOKEN PROCESS e6a1 IMPLIED LEADING SPACE e6a8 ERRTOK MOVERR=e66f e6aa RECURSIVE FOR TOKENS ;e6b3 CONTROLLER ERROR ENTRY ;e6b3 .A= ERROR # ;e6b3 .X= JOB # e6bb RECALL TRACK,SECTOR e6c6 CONVERT CONTROLLER... e6c8 ...ERRORS TO DOS ERRORS e6ca CODE=16-->14 e6d7 check for diagnostic ROM e6df SET ERROR LED e6e2 ERRLED e6e7 FREE INTERNAL CHANNEL e6ea CLEAR POINTERS e6ec the 4040 purges the stack and SEI e6f8 error while listening LSNERR=e71b e6fc error while talking TLKERR=e701 ;e701 TALKER ERROR RECOVERY ;e701 IF COMMAND CHANNEL, RELEASE DAV ;e701 IF DATA CHANNEL, FORCE NOT READY ;e701 AND RELEASE CHANNEL ;e701 this code is different from 4040 ;e71b LISTENER ERROR RECOVERY ;e71b IF COMMAND CHANNEL, RELEASE RFD ;e71b IF DATA CHANNEL, FORCE NOT READY ;e71b AND RELEASE CHANNEL ;e71b this code is different from 4040 e713 DAVO ;e73a CONVERT HEX TO BCD BCDDEC=e74a ;e74a CONVERT BCD TO ASCII DEC ;e74a RETURN BCD IN .X ;e74a STORE ASCII IN (TEMP)Y ERRMSG=e75d e75d ERRBUF e768 "," e765 CONVERT ERROR # e771 CHNDAT+ERRCHN e778 ERROR # IN .X e77b MOVE MESSAGE e77e "," HEXDEC=e73a e784 CONVERT TRACK # e78f CONVERT SECTOR # e79b 40) e828 NOT FULL YET e82a STORE THE BYTE e82d TST IF LST BYTE OF MSG e82f IT IS e831 NOT YET, RETURN e832 this test is missing in 4040, instead directly gone to e839 e839 SET CMD WAITING FLAG TSTJOB=e83c ;e83c TEST IF JOB (.X) IS DONE YET ;e83c IF NOT DONE RETURN ;e83c IF OK THEN RETURN ELSE REDO IT NOTYET=e855 OK=e857 e847 REDO UNTIL ERRCNT=0 AGAIN=e84f ;e859 WAIT UNTIL JOB(.X) IS DONE ;e859 RETURN WHEN DONE e85f this routine seems to be unused? SETHDR=e868 ;e868 SET HEADER OF ACTIVE BUFFER OF THE ;e868 CURRENT LINDX TO TRACK,SECTOR,ID e872 SEt TRACK e877 SET SECTOR e87a GET PROPER ID(DRVNUM) ;e889 PUT .A INTO ACTIVE BUFFER OF LINDX e889 SAVE .A e88a GET ACTIVE BUF# e88d BRANCH IF THERE IS ONE e88f NO BUFFER ERROR e890 FILNOP e892 JMP TO ERROR ROUTINE e895 SAVE THE BYTE IN BUFFER e89a INC THE BUFFER POINTER e89c Z=1 IF LAST CHAR SLOT IN BUFFER ;e8a8 INITIALIZE DRIVES (COMMAND) e8ae USED AS FLAG FOR BOTH DRIVES TOGDRV=f212 ;e8c1 INITIALIZE DRIVE (DRVNUM) ;e8c1 in 4040 this is called INITSU CLDCHN=ebce e8c1 missing in 4040 e8c4 DO A BUMP TO TRK 1 e8c6 READ IN BIT MAP (18.00) e8c7 BAMJOB; AND SAVE DISK ID e8d3 SEEK e8e1 READ ;e908 DO JOB IN .A, SET UP ERROR COUNT ;e908 AND LSTJOB. RETURN WHEN JOB DONE OK ;e908 JMP TO ERROR IF ERROR RETURNS ;e908 this code is vastly different from 4040 ;e943 START DOUBLE BUFFERING ;e943 USE TRACK,SECTOR AS STARTING BLOCK STRDBL=e943 ;e96a START A READ JOB ON TRACK, SECTOR e96a READ ;e96e START A WRITE JOB ON TRACK, SECTOR e96e WRITE e9b4 MAXSA+1 ;e9d4 READ BYTE FROM ACTIVE BUFFER ;e9d4 AND SET FLAG IF LAST DATA BYTE ;e9d4 IF LAST THEN Z=1 ELSE Z=0 ;e9f3 READ A CHAR FROM FILE AND READ NEXT ;e9f3 BLOCK OF FILE IF NEEDED. ;e9f3 SET CHNRDY=EOI IF END OF FILE e9ff EOIOUT SETDRN=ea66 RDBUF=e96a ;ea35 WRITE A CHAR TO CHANL AND WRITE ;ea35 BUFFER OUT TO DISK IF ITS FULL NXTTS=e47c WRTBUF=e96e INCPTR=ea59 ;ea59 INC POINTER OF ACTIVE BUFFER ;ea59 BY .A ea59 SCOTT PATCH ;ea66 SET DRVNUM TO DRIVE INDICATED BY ;ea66 LSTJOB OF ACTIVE BUFFER ;ea72 OPEN A READ CHANL WITH 2 BUFFERS ;ea72 WILL INSERT SA IN LINTAB ;ea72 AND INITS ALL POINTERS. ea72 GET TWO DATA BUFFERS ea7a READ 1ST ONE OR TWO BLOCKS ea7f RDYTLK ea8d SET LAST CHAR PTR ea8f SEQUENTIAL SET UP INTPNT=ea98 ;ea98 INITIALIZE VARIABLES FOR OPEN CHANL ;ea98 LSTJOB,SETS ACTIVE BUFFER#,LSTCHR, ;ea98 BUFFER POINTERS IN BUFTAB=2 ;eace OPEN A WRITE CHANNEL WITH 2 BUFFERS eace GET FIRST TRACK,SECTOR INTTS=e51b GETWCH=eae6 ;eae6 .A=#BUFFERS NEEDED ;eae6 SETS UP BUFFER # AND ALLOCATES LINDX ;eae6 for write eae6 SAVE #BUFS NEEDED ;eaf3 .A=#BUFFERS NEEDED ;eaf3 SETS UP BUFFER # AND ALLOCATES LINDX ;eaf3 for read eaf3 SAVE #BUFS NEEDED eafe save r/w flag (.C) ;eb32 FREE CHANL ASSOCIATED WITH SA ;eb32 FREE READ AND WRITE CHANLS ;eb32 DONT FREE CHANL 15 GETBUF=eb88 ;eb6e GIVEN SA, FREE ITS READ CHANL ;eb6e RELEASE BUFFERS (LINDX) RELBUF=eb6e ;eb88 GET A FREE BUFFER # FREBUF=ebb0 ;ebb0 ALLOCATE CLRCHN=ebc2 ;ebf6 FIND A FREE LINDX TO USE ;ebf6 MARK AS USED IN LINUSE FNDLNX=ebf6 ebfa 1=FREE 0=USED ec02 NOCHNL; NO FREE LINDX AVAILABLE ec07 TOGGLE BIT MASK ec09 MARK BIT USED ec0d RETURN LINDX IN .A ;ec0f CLOSE THE FILE ASSOCIATED WITH SA ;ec0f this routine is massively different, partly due to REL files in 4040 ec11 DIRECTORY CLOSE ec15 CLOSE CMD CHANL CLSALL=ec32 ec52 CLEAR DIR LIST ec57 in 4040 JMP FREICH ;ec87 WRITE OUT THE BIT MAP TO ;ec87 THE DRIVE IN LSTJOB(ACTIVE) ec90 CHECK BAM BEFORE WRITING MAPCHK=eca3 ;eca3 VERIFY THE BAM BLOCK COUNT ;eca3 MATCHES THE BITS ecc2 MAXTRK eccd BAMJOB ecd1 WRITE ;ecd6 GET NEXT CHAR FROM A CHANL RNGET1=ed2c RNGET2=ed2e ed23 UP TO LST CHAR YET ed26 NOT YET ed28 READ THE WHOLE THING ed2a WRAP PNTR TO 0 ed2c GET THE NEXT CHAR ed30 SAVE CHAR IN RNGET3=ed3f ed3a RNDEOI ed3c THIS IS LAST CHAR ed3f SEND EOI WITH IT SEQGET=ed40 ed40 READ THE NEXT BYTE GET3=ed43 ed45 STORE IN CHNDAT AVCK=e593 DOIT=e908 ;edd6 INITIALIZE BUFFER PNTR TABLE ;edd6 this function is much longer in 4040 ;edf3 READ NEXT BUFFER OF A FILE ;edf3 FOLLOW LINKS IN FIRST TWO BYTES ;edf3 END OF FILE IF 1ST BYTE=0 ;edf3 2ND CHAR LENGTH ;ee06 READ TRACK, SECTOR FROM HEADER ;ee1d DIRECT BLOCK READ ee1d READ ;ee21 DIRECT BLOCK WRITE ee21 WRITE DOIT2=e90a ;ee36 OPEN INTERNAL READ CHANL (SA=16) ee36 IRSA OPNRCH=ea72 ;ee42 OPEN INTERNAL WRITE CHANL (SA=16) OPNWCH=eace ;ee49 ALLOCATE NEXT DIRECTORY BLOCK ON 18 ;ee49 AND MARK AS USED IN BAM NXDRBK=ee49 ee58 INCR SECTOR BY 3 IN DIRECTORY NXTDS=e491 ;ee89 .A=NEW PNTR VALUE ;eea9 FREE THE INTERNAL CHANL (SA=16) FREICH=eea9 eea9 in the 4040 there are two calls to FRECHN, with .A as #IRSA and #IWSA ;eeb0 READ THE ACTIVE BUFFER POINTER ;eebe DIRECT READ BYTE, .A=BYTE# TO READ ;eece INDEX TABLE CONTAINING HIGH ;eece BYTE ADRESS OF BUFFERS ;eedd MARK A TRACK, SECTOR AS FREE IN BAM eedd POINT BMPNT AT BAM eee0 CALC INDEX INTO BAM - in 4040 done in subrouting FREUSE ef05 free it ;ef0a TURN ON ACTIVITY LED SPECIFIED ;ef0a BY DRVNUM ef0a clear both LEDs ef0f the 4040 does not store it back, but puts it on stack. Avoiding possible IO side effects ef16 LED1 ef1f LED0 ;ef28 START THE DIRECTORY LOADING FUNCTION ;ef28 GET THE BUFFER AND GET IT STARTED ef2c ALLOCATE CHANL AND 1 BUFFER ef49 PUT SAL IN BUFFER ef4e PUT SAH IN BUFFER ef53 INSERT FHONEY LINKS (0101) ef5b the 4040 reads NBTEMP here ef5d PUT IN DRVNUM ef65 GET DISK NAME ef71 END OF THIS LINE ef76 INSERT FHONEY LINKS ($0101) ef7e GET #BUFRS AND FILE NAME ef81 TEST IF LAST ENTRY ef92 END OF ENTRY efa2 RDYTLK efa8 DIRECTORY LIST BUFFER FULL DIR3=efae efae THIS IS END OF LOAD DIR10=ef99 efc6 END OF LISTING (000) ;efe2 TRANSFRE FILE NAME TO LISTING BUFFER efeb in 4040 src this is #27, not a constant MOVBUF=efe2 GETDIR=eff0 ;eff0 GET CHAR FOR DIRECTORY LOADING efff EOIOUT DIR1=ef76 ;f00a CALC THE NUMBER OF FREE BLOCKS ON DRVNUM f013 0 LOW PTR f039 DON'T COUNT THE DIR ;f044 PARSE & EXECUTE STRING IN CMDBUF ;f044 in 4040 there is some code in PARSXQ before this code here f044 SET VARIABLES, REGS f04c NCMDS-1 f058 BADCMD, NO SUCH CMD f05d X= CMD # f05f PCMD, CMDS NOT PARSED TAGCMD=f0ab f063 SET TABLES, POINTERS &PATTERNS f072 COMMAND TABLE JUMP ;f075 SUCCESSFUL COMMAND TERMINATION f07a SCRATCH ENTRY f07c CB f08d FREE INTERNAL CHANNELS (? label should be FREICH) ;f090 COMMAND LEVEL ERROR PROCESSING CMDER2=e6d4 SIMPRS=f099 f099 SIMPLE PARSER f09d ":" PARSE=f117 SETANY=f1ec f0a8 SET DRIVE# ;f0ab TAG COMMAND STRING ;f0ab SET UP CMD STRUCTURE ;f0ab IMAGE & FILE STREAM PTRS ;f0ab Note: in 4040 the code up to the first PARSE is in subroutine PRSCLN TAGCMD=f0ab f0af ":" f0b1 FIND POS'N OF ":" f0b6 NOFILE, NONE, NO FILES f0bd ":"-1 STARTS FS1 f0c0 ERR: "," BEFORE ":" f0c2 SEARCH "=" f0c7 ?FILE COUNT = 1-1? f0ca %01000000, G1-BIT f0cc %00100001, E1,^E2-BITS f0ce FS STRUCTURE f0d3 F2CNT, INIT FOR NO FS2 f0d9 %10000000, P1-BIT f0e1 CLEAR PATTERN FLAG f0e3 PTR TO FS2 f0e4 FS2 NOT HERE f0e8 FS2 IS HERE NOW,... f0ea ...NOW SET F2 PTR f0ec FIND CR-SHIFTED f0ee PARSE REST OF CMD STRING f0f1 ADVANCE FILTBL PTR TO END f0f2 F2CNT, SAVE IT f0f4 RESTORE FOR TEST f0f5 SAVE LAST PATTERN f0f7 ?ANY PATTERN? f0f9 %1000, YES, P2-BIT f0fb ?F2CNT=F1CNT+1? f0ff %0100, G2-BIT f101 %0011, E2-BIT, ^E2-BIT f103 EOR CLEARS ^E2-BIT f109 MATCH CMD TEMPLATE (orignal label: STRUCT) f10f **COULD BE WARNING f112 BADSYN, ERR: BAD SYNTAX ;f117 PARSE STRING ;f117 LOOKS FOR SPECIAL CHARS, ;f117 RETURNING WHEN VAR'BL CHAR ;f117 IS FOUND ;f117 A: VAR'BL CHAR ;f117 X: IN,OUT: INDEX, FILTBL+1 ;f117 Y: IN: INDEX, CMDBUF ;f117 OUT: NEW PTR, =0 IF NONE ;f117 (Z=1) IF Y=0 f117 SAVE VAR'BL CHAR f119 STAY IN STRING f11d MATCH CHAR f123 FOUND CHAR f125 MATCH PATTERN CHAR ("*" in this case) f129 "?" f12d SET PATTERN FLAG f12f MATCH FILE SEPARATOR (",") f134 PUT PTRS IN TABLE f136 SAVE PATTERN FOR EA FILE f13c RETAIN PATTERN PRESENCE... f140 ... BUT CLEAR COUNT f143 MXFILS-1 f145 NO MORE THAN MXFILS f147 Y=0 (Z=1) f157 Z IS SET CMDSET=f159 ;f159 INITIALIZE COMMAND TABLES, PTRS, ETC. f159 in 4040 source this is "LDY BUFTAB+CBPTR", but what does it mean? f163 CR f16b CR f171 SEt CMD STRING SIZE f173 CMDLEN-1 f17b LONGLN, LONG LINE ERROR ;f180 CLEAR VARIABLES, TABLES CMDRST=f180 f180 in 4040, .Y is explicitely set to 0 f181 "BUFTAB+CBPTR" f18c F2CNT f193 MXFILS f197 FILENT-1 f199 FILDAT-1 f19b FILTRK-1 f19d FILSEC-1 ;f1a3 SET 1ST DRIVE AND TABLE POINTERS ;f1ad SET UP ALL DRIVES FROM F2CNT f1ad ET UP DRIVE #'S... f1af ... INTO FILE ENTRY TABLE... f1b1 ... ON SECTOR PTR BYTE SETDRV=f1c5 f1ba INCR PTR PAST ":" f1bc BITS REP DRIVES f1bd BIT7: DEFAULT f1bf BIT0: DRIVE # ;f1c5 SET DRIVE NUMBER ;f1c5 DETERMINES DRIVE # FROm TEST OR ;f1c5 USES DEFAULT (-D) ;f1c5 A: IN,OUT: INDEX, CMDBUF ;f1c5 Y: IN: DEFAULT DRIVE ;f1c5 OUT: DRIVE NUMBER, - IF DEFAULT f1c5 X=CMDBUF INDEX f1c6 ":" f1c8 FOR XXX:FILE f1ca ^ f1cc FOR XXX:FILE f1ce ...^ f1d0 FOUND ":", SO ... f1d1 DRIVE= DEFAULT f1d2 CONVERT TO NUMERIC f1d4 RESTORE DRIVE f1d5 A=INDEX && XXXXFILE f1d6 ...............^ f1d9 XXX:FILE f1da ..--^ f1db FOR XX0:FILE f1dd ........^ f1df FOR XX1:FILE f1e1 ........^ f1e3 CMD:FILE OR XX,:FILE ; here points to the "F" in FILE twice f1e5 FOR XXX,FILE OR XX=FILE f1e6 ........^ ^ f1e8 DRIVE= -DEFAULT f1ea FINISH TESTING ;f1ec SET DRIVE FROM ANY CONFIG ;f212 TOGGLE DRVNUM ;f21b SET PTRS TO ONE FILE STREAM & CHK TYPE FS1SET=f21b f21f R0 aka F2CNT f22b in 4040 this is an indirect indexed LDA (DB),Y f22e NTYPES-1 TST0V1=f23d ;f23d TEST CHAR In ACCUM FOR "0" OR "1" ;f24a OPTSCH OPTIMAL SEARCH FOR LOOKUP ;f24a AND FNDFIL f24a DETERMINE OPTIMAL SEARCH f24c INIT DRIVE MASK f26d (BRANCH) SCHTBL=f28a+e-1 f283 in 4040 before JMP comment "*RSR ADD FOR AUTO INIT" and auto init code? ;f299 LOOK Up ALL FILES IN STREAM ;f299 AND FILL TABLES W/ INFO f2a0 START SEARCH f2a9 NO MORE DRIVE SEARCHES f2aa TOGGLE DRIVE # f2b1 TURN ON LEDS f2b4 (BRANCH) f2b8 FIND VALID FN f2bb END OF SEARCH COMPAR=f314 f2bd COMPARE DIR W/ TABLE f2c0 FOUND FLAG f2c2 ALL FN'S NOT FOUND, YET ;f2d0 FIND NEXT FILE NAME MATCHING ;f2d0 ANY FILE IN STREAM & RETURN ;f2d0 WITH ENTRY FOUND STUFFED INTO ;f2d0 TABLES f2d0 FIND FILE RE-ENTRY f2e1 FIND FILE START ENTRY f2f5 FIND FILE CONTINUOUS... f2f8 ... RE-ENTRY, NO CHANNEL ACTIVITY f2fa COMPARE FILE NAMES f309 NO TYPE RESTRICTION ;f314 COMPARE ALL FILENAMES IN STREAM TABLE ;f314 WITH EACH VALID ENTRY IN THE ;f314 DIRECTORY. MATCHES ARE TABULATED CMPCHK=f3b4 f320 ALL ARE FOUND CC10=f3bc f32b RIGHT DRIVE f32f NO DEFAULT f335 DON'T USE DEFAULT f337 GOOD DRIVE MATCH f33f in 4040 the CMDBUF,x and (DIRBUF),y are exchanged, so the char is always in .A and can directly compared with f341 this compare and the branch is later in 4040 f343 END OF PATTERN f347 CHARS ARE = f349 "?" f34d NO SINGLE PATTERN f355 END OF FILENAME f359 in 4040 this is at different place as BCS, with comment "END OF FILENAME" f35b "*" f35d STAR MATCHES ALL f365 FILENAMES MATCH f369 STORE INFO IN TABLES f3a8 here is a change from 4040 CMPCHK=f3b4 ;f3b4 CHECK TABLES FOR UNFOUND FILES f3c0 TABLE EXHAUSTED ;f3ce SEARCH DIRECTORY ;f3ce RETURNS WITH VALID ENTRY W/ DELIND=0 ;f3ce OR RETURNS W/ 1ST DELETED ENTRY ;f3ce DELIND=1 ;f3ce ;f3ce SRCHST WILL INITIATE A SEARCH ;f3ce SEARCH WILL CONTINUE A SEARCH f3ce INIT DELETED SECTOR f3d5 START SEARCH AT BEGINNING f3df OPEN INTERNAL READ CHNL f3e2 LAST BUFFER IF 0 f3e6 (Z=1) f3eb READ TRACK # DRDBYT=eebe f3f0 UPDATE END FLAG f3f9 READ FILE TYPE f3fd DELETED ENTRY FOUND f3ff DELETED ENTRY ALREADY FOUND f401 GET CURRENT SECTOR f408 GET CURRENT INDEX f40a BIT1: WANT DELETED ENTRY f40e NEED VALID ENTRY f413 ?LOOKING FOR DELETED? f415 NO! SEARCH=f429 f42d ADJUST FILE COUNT f431 INCR BY 32 f436 these two branches are later replaced by a JMP :-) f43a NEW BUFFER f43d in 4040 replaced by JMP, with comment "(BRANCH)" :-) f441 FOUND VALID ENTRY f443 SAVE INDEX f445 GET SECTOR CURBLK=ee06 f44c (Z=0) ;f44d TRANSFER FILENAME FROM CMD TO BUFFER. ;f44d A=STRING SIZE. ;f44d X=STARTING INDEX IN CMDBUF. ;f44d Y=BUFFER # FNDLMT=f52f TRCMBF=f466 ;f466 TRANSFER CMD BUFFER TO OTHER BUFFER ;f466 USES CURRENT BUFFER PTR. ;f466 LIMIT ENDING INDEX+1 IN CMD BUF ;f466 X=STARTING INDEX IN CMD BUF ;f466 Y=BUFFER# ;f482 TODO ;f52f FIND THE LIMIT OF THE STRING IN CMDBUF ;f52f POINTED TO BY X f537 "." f53b "=" GETNAM=f551 ;f551 GET FILE ENTRY FROM DIRECTORY ;f551 CALLED BY STDIR, GETDIR; SAVE VARIABLES f551 SAVE VARIABLES GNSUB=f561 f561 IRSA f56d MORE FILES f56f SEND BLOCKS FREE f572 (C=0) = END f573 TERMINATE f57a (DRVFLG=-1) = NEW DIR f57e (DRVFLG=-1) = f580 SEND BLOCKS FREE f599 DIRLEN; SET NUMBER BLOCKS f59b & ADJUST SPACING f5a4 DIRLEN-2 f5ac DIRLEN-2 f5ba CLEAR NAME BUFFER f5bd SEt TYPE CHARS f5c0 (USED IN BCS) f5b5 "<" f5db (FROM ASL) f5dd "*"; FILE NOT CLOSED f5f5 '"' SEND NAME IN QUOTES f602 '"' f60a '"' FNDFIL=f2f5 f623 BLANK NAMBUF NEWDIR=f62e ;f62e NEW DIRECTORY IN LISTING f642 the 4040 adds version check here (write out "1" when no version on disk) BLKNB=f623 FREMSG=f66e NUMFRE=f00a MSGFRE=f65d f660 MSGLEN-1 f66e blocks free message ;f67a TODO ;f8c8 NEW: INITIALIZE A DISK, DISK IS ;f8c8 SOFT-SECTORED, BIT AVAIL. MAP, ;f8c8 DIRECTORY, & 1ST BLOCK ARE ALL INITED ONEDRV=f1a3 CMDERR=f090 f8cb SET UP DRIVE# f8cf BADFN f8dd GET DISK ID f8df IS THIS NEW OR CLEAR? f8e1 END OF CMD STRING f8e6 STORE IN PROPER DRIVE f8e8 (Y=0) f8ed ...IN TRACK, TRACK=1 f8f1 TRANSFER FORMAT TO RAM f8fb load high byte of buffer for drive, either $4200 or $4300? f905 clear buffer f90a X contains the drive f90c BAMJOB, BUF#13 + DRVNUM f90e either 13 or 14 (dezimal) f911 either 26 or 28 (dezimal) = $1a or $1c f914 store either into $57 or $59 f91a directory track (18) f91e loop over directory starting with SECTOR=4 until SECTOR contains #1 f921 write each sector with interleave of 3 f924 secs 4,7,10,13,16,19,22, 3,6,9,12,15,18,21, 2,5,8,11,14,17,20 f934 end of loop, SECTOR contains $01 f938 end of file marker (followup sector in second byte in sector = $ff) f93a CLEAR DIRECTORY (write t=18/s=1) f93d move pointer to BAM block SETLDS=ef0a TRNAME=f44d f953 TRANSFER CMD BUF TO BUF0 f958 SET UP CURRENT I.D. f966 add two spaces. Newer versions add "DOSVER+$30" and "VERNUM" -> "2A" DRTWRT=ee21 f96d WRITE IT OUT FS1SET=f21ba ;f973 SCRATCH FILE(S) f973 SET UP FOR 1 STREAM OPTSCH=f24a FFST=f2e1 f986 DELETE DIRECTORY; in 4040 before this a test for active file is inserted f989 in 4040 before this a REL-file test is inserted f98f CREATED, NOT CLOSED f991 no needed f993 DELETE BY LINKS DELFIL=f9b6 FFRE=f2d0 f9a8 FINISHED SET f9ab FILE COUNT f9b3 END OF SCRATCH SCREND=f07a f9b6 DELETE FILE BY LINKS f9b9 UPDATE BAM RDBYT=e9f3 DEL2=f9bc *e5bd DATA ;f9ed DUPLICATE DISK f9ed "=" SPECIAL CASE fa10 LED0+LED1 fa18 INIT SRC fa34 FORMAT DST DRIVE CPYD1=fa37 ;fa37 COPY BLOCKS FROM ONE DRIVE TO OTHER fa40 COPY ONE TRACK fa47 MAXTRK ;fa51 COPY ONE TRACK READS=faa0 WRITES=fad8 fa57 READ 10 SECTORS fa5a WRITE 10 SECTORS SETRH=fa6d fa77 the 4040 has this up to fa95 in subroutine SETH ;faa0 READ TEMP+2 BLOCKS IN faa2 READ ;fad8 WRITE TEMP+2 BUFFERS OUT fad8 #WRITE ;fb14 TRANSFER FORMAT CODE TO BUFFER 0 ;fb14 & START CONTROLLER FORMATTING fb31 or with EXEC ;fb47 DSKCPY CHECK FOR TYPE AND PARSES SPECIAL CASE ;fbd3 RENAME FILE NAME IN DIRECTORY fbd3 SET BOTH DRIVE #'S ALLDRS=f1ad fbde SAME DRIVE #'S fbe0 CHECK BOTH DRIVES FOR NAME LOOKUP=f299 CHKIO=fc16 fbe7 LOOK UP BOTH NAMES fbea CHECK FOR EXISTENCE fbfa in 4040 different code with comment "POSIBLE BUG" fbfe SET SECTOR INDEX fc00 ;+5 fc0d TRANSFER NAME fc10 WRITE SECTOR OUT ;fc16 CHECK I/O FILE FOR EXIST ;fc16 this is different from 4040 ;fc37 VALIDATE FILES WITH BAM ;fc37 CREATE NEW BAM ACCORDING TO ;fc37 CONTENTS OF FILES ENTERED IN DIR fc37 EXTRACT DRIVE # fc3d INIT THE DRIVE FOR NAME, ID fc40 SET NEW BAM SRCHST=f3ce fc47 SEARCH FOR FIRST FILE fc4a FOUND ONE fc4c SET DIRECTORY SECTORS... fc4e ... IN BAM MRKBAM=fc79 MAPOUT=ec87 fc57 WRITE OUT BAM fc65 in 4040 here is inserted PHA .... REL-File Side Sector code ... PLA; NOW DO DATA BLOCKS fc67 SET BIT USED IN BAM fc6a SEARCH FOR MORE SRRE=f419 fc6d NO MORE FILES DELDIR=f9de fc73 NOT CLOSED DELETE DIR ;fc79 MARK BAM WITH FILE SECTORS SETBMP=e55f USEDTS=e7a0 OPNIRD=ee36 SETPNT=ee89 GETBYT=e9d4 FRECHN=eb32 NXTBUF=edf3 NEWMAP=fca1 fca1 create BAM fca6 buffer is $4200 for drive 0 or $4300 for drive 1 fcac track(!) count, not sector fcb1 start with track=0 (=illegal), place for link address fcb8 fill buffer with data (sector/track, #$ff, #$ff, e02a+x) for each track fcba i.e. about 35*4=140 bytes, where x is number of speedzone BAMEND=e02a fcc3 lookup, do not compute (as in later DOS versions) last entry in BAM sector map for track fccb check track with track where speed zone changes fcd0 if not new speed zone, go to next track fcd3 compare with number of speed zones fcd7 write track link address fcd9 track 18 fcde sector 1 fce2 version 1 fce5 fill byte 0 ;fced MEMORY ACCESS COMMANDS ;fced "-" MUST BE 2ND CHAR fcef "-" fcf5 "W" fcf7 WRITE MEMWRT=fd28 fcf9 "R" fcfb READ MEMRD=fd0f fcfd "E" fcff ERROR fd01 copy address fd04 EXECUTE MEMEX=fd0c fd0f copy address MEMERR=fd23 fd23 BADCMD fd28 WRITE; copy address fd2e TRANSFER FROM CMDBUF fd31 # OF BYTES TO WRITE fd38 copy address from command to tmp USRINT=fd49 ;fd43 ROM 1.1 ADDITIONS ;fd43 USER COMMANDS fd47 "0" RESETS PNTR fd49 #UBLOCK UBLOCK=ffea fd52 EXECUTE CODE BY TABLE USREXC=fd58 fd58 ENTRY IS (((INDEX-1)AND$F)*2) ;fd6a OPEN DIRECT ACCESS BUFFER ;fd6a FROM OPEN "#" fd6f GET ANY BUFFER GETRCH=eaf3 fd77 NOCHNL fd7c BUFFER # IS REQUESTED fd83 BAMJOB; MUST BE LESS THAN 13 fd99 BUFFER IS USED fd9f BUF IS USED fda3 SET BUFFER AS USED fdad SET UP CHANNEL OPNBLK=fd6a fdbe SET LINDX TABLE fdc1 the 4040 has LINTAB and LINTAB+1 folded together by ORing with #$40 fdca RNDRDY fdcc SET CHANNEL READY fdd4 BUFFER # AS 1ST CHAR fddd DIRTYP+DIRTYP fddf SET DIRECT FILE TYPE ;fde5 BLOCK COMMANDS fde9 "-" SEPARATES CMD FROM SUBCMD fdeb LOCATE SUB-CMD fdf0 BADCMD fdf5 BADSYN fdfd NBCMDS-1; FIND COMMAND &BCTAB=fe22+5 fe0c found command BLKPAR=fe34 fe0e PARSE PARAMS BCJMP=fe28+0b fe1f GOTO COMMAND BLKALC=febb BLKFRE=feb2 BLKRD=ff09 BLKWT=ff41 BLKEXC=ff71 BLKPTR=ff88 *fe28 ADDR ;fe28 NBCMDS = *-BCTAB ;fe28 BLOCK-ALLOCATE, BLOCK-FREE, BLOCK-READ, BLOCK-WRITE, BLOCK-EXECUTE, BLOCK-POINTER fe34 PARSE BLOCK PARMS fe38 ":" fe3d FOUND ":" fe3f ELSE CHAR #3 IS BEGINNING fe44 " " fe48 SKIP CHARACTER fe4c "," fe55 THAT'S ALL ASCHEX=fe63 fe5d MXFILS-1 fe61 BAD SYNTAX ;fe63 CONVERT ASCII TO HEX (BINARY) ;fe63 & STORE CONVERSION IN TABLES ;fe63 .Y=PTR INTO CMDBUF fe6d TEST FOR DEC # fe72 NON-NUMERIC TERMINATES fe76 NON-NUMERIC fe7b SHIFT DIGITS (*10) fe89 STILL IN STRING fe8b CONVERT DIGITS TO... fe8d ...BINARY BY DEC TABLE &DECTAB=feaf fea9 STORE RESULT IN TABLE feaf DECIMAL TABLE BLKTST=ffb9 FRETS=eedd ;feb2 BLOCK-FREE ;febb BLOCK-ALLOCATE AVAIL=e56b AV2=e587 fed2 SET NOT AVAIL FLAG fee6 similar to TSCHK in 4040 feed NOBLK fef2 FINISHED SEARCH fef5 BLOCK WASN'T AVAILABLE fef7 BLOCK AVAIL, SET AS USED BLKRD2=fefd BKOTST=ffe4 fefd TEST PARAMS DRTRD=ee1d GETSIM=ff03 GETPRE=e9cc ff00 GET BYTE W/O INC ;ff09 BLOCK READ ff11 Y=LINDX ff20 RNDRDY ;ff26 USER DIRECT READ, LSTCHR=$FF ff3e (RTS) ;ff41 BLOCK WRITE GETPNT=eeb0 ff4f SET RECORD SIZE PUTBYT=e889 ff5a WRITE BLOCK ;ff65 USER DIRECT WRITE, NO LSTCHR ;ff71 BLOCK-EXECUTE ff71 READ BLOCK & EXECUTE &BUFIND=eece ff7f INDIRECT JSR ;ff88 BUFFER-POINTER, SET BUFFER POINTER BUFTST=ff9a ff94 in 4040 JSR GETPRE, JSR RNDGET2; SET UP GET ;ff9a TEST FOR ALLOCATED BUFFER.. ;ff9a ..RELATED TO SA ffa3 BAMJOB ffa7 NOCHNL ;ffb9 TEST FOR LEGAL BLOCK &.. ;ffb9 ..SET UP DRV, TRK, SEC ffc9 in 4040 separated out into TSCHK ffe4 TEST BLOCK OPERATION PARAMS *ffea ADDR *fffa ADDR