; ; DISK OPEN ROUTINE ; DKOPEN JSR WBITMP ;Fix nasty bug! [Bob Puff] JSR SETUP ;SET UP BUF PTRS, ETC. JSR GETFNM ;GET DRIVE ID OR FILE NAME FROM BUFFER LDA ICAX1Z ;GET TYPE OF OPEN FROM IOCB STA FCBOTC,X AND #$02 ;TEST DIRECTORY READ FLAG BEQ DKOPN1 JMP LSTDIR ;IF SET, GO HANDLE DIRECTORY FORMATTING ; DKOPN1 STA SAVSEC,X STA SAVSEC+1,X ;CLEAR SAVSEC JSR SFDIR PHP ;SAVE STATUS RETURNED BCS OPNEW LDA #$10 ;MAKE SURE THIS IS NOT A DIRECTORY JSR GETFLAG BNE DIROPN ;IF A DIRECTORY, GO HANDLE IT SEPERATELY OPNEW LDY ICAX1Z CPY #8 BEQ OPNOP ;IF OPEN FOR OUTPUT CPY #4 BEQ OPNIN ;IF OPEN FOR INPUT CPY #12 BEQ OPNUP ;IF OPEN FOR READ/WRITE (UPDATE) CPY #9 BEQ OPNAP ;IF OPEN FOR OUTPUT/APPENDED DIROPN JMP ERRCMD ;IF NONE OF THE ABOVE, IT IS AN ERROR! ; OPNAP PLP ;OPEN APPEND BCS OPNCR0 JSR TSTLOK JSR INITYP ;READ ALL THE SECTORS IN THE FILE LDA DIRBUF+1,Y STA SECCNT,X LDA DIRBUF+2,Y STA SECCNT+1,X APPRD JSR RDNXTS BCC APPRD ;IF NOT EOF, READ ANOTHER LDA MAXLEN,X JSR LENSET ;SET LENGTHS FOR OUTPUT LDA SECCNT,X BNE SGLDEC DEC SECCNT+1,X SGLDEC DEC SECCNT,X ;ALLOW FOR SECTOR REWRITTEN JMP OPOUTX ; OPNUP PLP ;OPEN UPDATE (OUTPUT) BCS OPNER1 JSR TSTLOK OPNOWR JSR INSTRT JMP DONE ; OPNIN PLP ;OPEN INPUT BCC OPNOWR OPNER1 LDA #170 ;FILE NOT FOUND BMI EROXIT ; OPNOP PLP ;OPEN (NORMAL) OUTPUT BCS OPNCR JSR REMOVE JMP GET1ST ; OPNCR0 DEC FCBOTC,X OPNCR LDA HOLFN STA CURFNO BMI OPDIRF GET1ST JSR ALLOC ; LDA ICAX2Z ;IF OUTPUT, TYPE OF FILE AND #$24 ;SAVE LOCKED & FORMAT BITS (with 4.5, DOS I no-more) EOR #$43 ;MERGE IN DEFAULT CODE (DOS II, UNLOCKED) LDY MAPBUF ;WHICH TYPE DISK? CPY #3 ;IF >2 THEN MYDOS BCC LLINKS ORA #$04 ; LLINKS PHA JSR RDCFNO ;SELECT PROPER SECTOR IN DIRECTORY SEC JSR ENTNAME ;ENTER NAME INTO IT LDA LNKSEC+1,X STA DIRBUF+4,Y LDA LNKSEC,X STA DIRBUF+3,Y PLA JSR SAVFLAG JSR INITYP JSR TONXT OPOUTX LDA #$80 STA FCBFLG,X JSR TSTDOS ;FILE NAME = DOS.SYS? BNE JDONE LDY CURSEC,X LDA CURSEC+1,X JSR SETDOS ;IF SO, UPDATE BOOT SECTORS ; LDA DOSAD STA FMSZPG LDA DOSAD+1 STA FMSZPG+1 BNE OWTDOS ;NOTE: DOS CANNOT START ON ZERO-PAGE ; OPDIRF LDA #169 EROXIT JMP AEXIT ; LWTDOS JSR WRNXTS ;AUTOMATICALLY WRITE DOS.SYS OUT OWTDOS LDY #0 ;IF WE OPEN "DOS.SYS" FOR A WRITE CDOSBF LDA (FMSZPG),Y ;(THIS IS BECAUSE DOS 2.0 WOULD BLOW STA (FMSBPT),Y ; ITSELF AWAY IF A REAL WRITE FROM THE INY ; DOS AREA WAS ATTEMPTED, AND WE HAVE CPY DLINK ; TO REMAIN COMPATIBLE). BCC CDOSBF TYA STA CURLEN,X JSR MVBUFR CPY DOSEND SBC DOSEND+1 BCC LWTDOS JDONE JMP DONE ; ; READ DATA FROM A FILE ; DKREAD JSR SETUP ;SETUP BUFFER POINTERS, ETC. LDA FCBOTC,X AND #$02 ;TEST THE DIRECTORY I/O FLAG BEQ RDFILE JMP DIRRD ;JUMP IF THE SPECIAL CASE OF A DIRECTORY READ ; RDFILE LDA CURLEN,X CMP MAXLEN,X BCC RDSGBT ;IF NOT AT SECTOR BOUND., READ A BYTE AT A TIME BCS RDASNT ;ELSE, CHECK FOR READ MODE AND BUFFER SIZE ; RDASLP LDA ICCOMZ AND #$02 BEQ RDSGBT ;IF NOT BINARY I/O READ A BYTE AT A TIME LDY DLINK DEY RDSCLP LDA (FMSBPT),Y ;SIMULATED BURST I/O (with unrolled loop) STA (ICBALZ),Y DEY LDA (FMSBPT),Y STA (ICBALZ),Y DEY LDA (FMSBPT),Y STA (ICBALZ),Y DEY LDA (FMSBPT),Y STA (ICBALZ),Y DEY BNE RDSCLP LDA (FMSBPT),Y ;NUM OF DATA BYTES IS MULTIPLE OF 4 + 1 STA (ICBALZ),Y JSR BUFADJ ;ADJUST BUFFER PTR BY 125 OR 253 RDASNT JSR RDNXTS ;READ IN THE NEXT SECTOR BCS RETEOF ;REPORT EOF/ERROR IF NECESSARY LDA ICBLLZ+1 BNE RDASLP ;AND REPEAT THE LOOP IF > 256 BYTES LEFT ; RDSGBT TAY LDA (FMSBPT),Y ;FETCH A DATA BYTE FROM THE BUFFER STA DATBYT ;AND RETURN IT TO CIO INY TYA STA CURLEN,X ;BUMP CURRENT BUFFER LENGTH EOR MAXLEN,X ORA LNKSEC,X ORA LNKSEC+1,X ;TEST FOR THE LAST BYTE OF THE FILE BNE JDONE LDA #3 ;IF IT IS, REPORT THIS IS THE LAST BYTE DB $2C ; RETEOF LDA #136 ;RETURN END OF FILE STATUS JMP AEXIT ; ; WRITE DATA TO A FILE ; DKWRIT STA DATBYT ;SAVE THE DATA BYTE (IF IT IS IN ACC) LDY ICDNO,X STY ICDNOZ ;INSURE ICDNOZ IS SET UP (BASIC DOES NOT!) JSR SETUPW LDA FCBOTC,X AND #$08 BEQ CANTWR ;ERROR OUT IF ILLEGAL TO WRITE (BASIC AGAIN!) LDA CURLEN,X TAY CMP MAXLEN,X BCC SKBURST ;SKIP AROUND IF NOT THE END OF THE SECTOR WRASLP JSR WRNXTS ;WRITE A SECTOR OF DATA BCS RETEOF ;ERROR OUT IF NO MORE DISK SPACE LDY STKPSV LDA $0102,Y CMP #$C0 ;IF FROM BASIC (RETURN ADDRESS < $C000) BCC BASWRT ;PASS SINGLE BYTES LDA FCBOTC,X ;Fix bug in open/update vs. burst I/O AND #$04 ;[Bob Puff, again!] BNE BASWRT LDA ICCOMZ ;IF RECORD I/O, PASS SINGLE BYTES ALSO AND #$02 BEQ BASWRT LDY ICBLLZ+1 ;AND IF THE BUFFER HOLDS FEWER THAN 256 BYTES BEQ BASWRT ;PASS SINGLE BYTES AS WELL LDY MAXLEN,X DEY WRSCLP LDA (ICBALZ),Y ;ELSE, DO SIMULATED BURST I/O STA (FMSBPT),Y DEY LDA (ICBALZ),Y STA (FMSBPT),Y ;BUT ONLY UNROLL 2 ENTRIES FOR WRITES! DEY ;(WE GOT VERY LITTLE RAM TO WASTE!) BNE WRSCLP LDA (ICBALZ),Y STA (FMSBPT),Y JSR BUFADJ LDA (ICBALZ),Y STA DATBYT JMP WRASLP ; BASWRT LDY #0 SKBURST LDA DATBYT INC CURLEN,X STA (FMSBPT),Y LDA #$40 ORA FCBFLG,X ;FOR UPDATE MODE, SAY THE SECTOR WAS MODIFIED STA FCBFLG,X BNE TODONE ;BRANCH ALWAYS! ; CANTWR JMP ERRCMD ; BUFADJ CLC LDA MAXLEN,X STA CURLEN,X ADC ICBALZ STA ICBALZ BCC RBAOK INC ICBALZ+1 RBAOK SEC LDA ICBLLZ SBC MAXLEN,X STA ICBLLZ BCS RBLOK DEC ICBLLZ+1 RBLOK RTS ; ; RETURN FILE STATUS ; DKSTAT JSR SETUP ;SET UP RETURN ADDRESS, ETC. JSR LFFILE ;FIND IF FILE IS THERE, ETC. JSR TSTLOK ;IS IT LOCKED? TODONE JMP DONE ;RETURN TO CALLER ; ; CLOSE FILE (WRITING ANY PENDING SECTOR) ; DKCLOS JSR SETUP LDA FCBOTC,X AND #$08 ;OUTPUT ALLOWED? BEQ CLROTC ;IF NOT, JUST EXIT ROL FCBFLG,X BCC CKFLSC JSR REWRIT ;REWRITE THE LAST SECTOR JSR RRDIR LDA SECCNT,X LDY DIRDSP STA DIRBUF+1,Y LDA SECCNT+1,X STA DIRBUF+2,Y LDA DIRBUF,Y AND #$FE ;NOT OPEN FOR OUTPUT ANY MORE JSR SAVFLAG LDA SAVSEC,X ORA SAVSEC+1,X BEQ CLROTC CPX LSTIOCB BEQ FAPPD JSR INITYP ;READ ALL THE SECTORS AGAIN APPLP JSR RDNXTS BCC APPLP ;NOT EOF YET BCS TIELNK FAPPD LDA LSTSEC STA CURSEC,X LDA LSTSEC+1 STA CURSEC+1,X TIELNK CLC JSR RWDISK LDA DLINK STA CURLEN,X LDA SAVSEC,X LDY SAVSEC+1,X JSR SAVLNK CLROTE BPL CLROTC LDA #163 ;FAILURE IS A SYSTEM ERROR JMP AEXIT CLROTC LDA #$FF STA ICHID,X LDA #0 STA FCBOTC,X JMP FREDON ; CKFLSC ROL FCBFLG,X BCC CLROTC JSR WRDISK JMP CLROTE ; INITYP LDA #$06 JSR GETFLAG LSR A ROR A ROR A ROR A ORA FCBOTC,X STA FCBOTC,X LDA DIRBUF+3,Y STA LNKSEC,X LDA DIRBUF+4,Y STA LNKSEC+1,X LDA CURFNO STA FCBFNO,X LDA #0 STA FCBFLG,X STA CURLEN,X STA SECCNT,X STA SECCNT+1,X RTS ; ; DOS XIO ROUTINES ; ; Sorry about the lack of comments in some parts of this file, ; I just never had to figure this code out after I wrote it (:-)! ; NODIRF LDA #176 ;FILE NOT A DIRECTORY JMP AEXIT ; PIKDIR LDY #0 LDA #':' FDVND INY CMP (ICBALZ),Y BNE FDVND INY LDA (ICBALZ),Y CMP #'@' BCC SETRDIR CMP #'Z'+1 BCC GFNDIR CMP #'_' BCC SETRDIR CMP #'z'+1 BCS SETRDIR GFNDIR JSR LFFILE ;FIND NEW DEFAULT DIRECTORY JSR INITYP JSR TONXDR BEQ NODIRF ;IF NOT A DIRECTORY LDA DIRBAS+1,X TAY LDA DIRBAS,X SAVDEF STY CDIREC+1 ;UPDATE ADDRESS OF DIR. STA CDIREC LDA ICDNOZ STA DEFAULT ;UPDATE UNIT NUMBER BPL TOFDN ; SETRDIR LDA #LOW[361] LDY #HIGH[361] BPL SAVDEF ; RENAME JSR LFFILE ;GET OLD NAME, DRIVE, VALIDATE LDY #11 STEMPL LDA FNAME-1,Y STA MAPBUF+256,Y DEY BNE STEMPL RNLOOP JSR TSTLOK ;CANNOT RENAME IF LOCKED JSR TDDOS ;TEST FOR DOS GONE! LDY TMP2 JSR GETNAM ;GET NEW NAME CLC JSR ENTNAME ;OVERWRITE NAME IN DIR. JSR WDIRBK ;REWRITE DIRECTORY TO DISK ; JSR TSTDOS ;NEW NAME DOS.SYS? BNE REPLDS ;NO, LOOK AT NEXT LDY DIRDSP LDA DIRBUF+4,Y ;SAVE FILE LOCATION ON THE STACK PHA LDA DIRBUF+3,Y PHA ; ;;; JSR SYSSET ;Use the MAP buffer [IS THIS NECESSARY???] ; CLC ; == READ LDX #1 ; == SECTOR SIZE CODE (1=128, 2=256) LDA #0 LDY #1 ; == SECTOR #1 JSR DKIO ;Read it ; LDA SECDAT STA MAPBUF+SECDAT-$0700 PLA STA MAPBUF+DOSLOC-$0700 PLA STA MAPBUF+DOSLOC+1-$0700 ; ;;; LDA #$00 ;[AND IS THIS REALLY NECESSARY???] ;;; STA MAPBUF+STATE-$0700 ; SEC ; == WRITE LDX #1 ; == SECTOR SIZE CODE (1=128, 2=256) JSR DKIO2 ;Write it (same sector as I read before) ; LDA #$FF ;Then make sure we reread the directory buffer STA DIUNIT ; REPLDS LDY #11 RTEMPL LDA MAPBUF+256,Y STA FNAME-1,Y DEY BNE RTEMPL JSR CSFDIR ;TO RENAME BCC RNLOOP TOFDN JMP FREDON ; DELETE JSR LFFILE DELLP JSR REMOVE ;FLUSH THE SECTORS JSR RRDIR ;REREAD DIRECTORY BLOCK JSR TDDOS ;DOS.SYS DELETED? LDA #$80 JSR SAVFLAG ;REWRITE DIRECTORY BLOCK JSR CSFDIR BCC DELLP ;IF ANOTHER FOUND, BCS TOFDN ;ELSE, WRAP UP AND EXIT ; REMOVE JSR TSTLOK ;ONCE HAD 'OPVTOC' CALL FIRST JSR INITYP JSR TONXDR BNE DELDIR JSR CHASE ; FREELP JSR FREE JSR RDNXTS BCC FREELP RTS ; INVDEL LDA #175 ;DIRECTORY NOT DELETABLE JMP AEXIT ; LOCK LDA #$20 DB $2C ;BIT ABS (SKIP 2 BYTES) ; UNLOCK LDA #$00 STA DATBYT JSR LFFILE ;FIND FILE AND VERIFY WRITABLE LKULKL LDA #$DF ;STRIP OFF OLD BIT 5 JSR GETFLAG ORA DATBYT ;AND REPLACE WITH NEW JSR SAVFLAG JSR CSFDIR BCC LKULKL BCS TOFDN ; DELDIR LDY #-11 LDA #'?' DELSET STA FNAME+11-256,Y INY BNE DELSET JSR SFDIR BCC INVDEL ; LDA #8 STA DATBYT JSR TONXT DELDRL JSR FREE JSR INCCSEC DEC DATBYT BNE DELDRL JMP GETFNM ; POINT LDY FCBFLG,X BMI ERRCMD ; LDA ICSPR+1,X CMP CURSEC+1,X BNE PNTREAD LDA ICSPR,X CMP CURSEC,X BEQ PNTSME PNTREAD TYA BEQ PNTCLN ;IF SECTOR UNMODIFIED JSR WRDISK LDA #0 STA FCBFLG,X PNTCLN LDA ICSPR+1,X STA LNKSEC+1,X LDA ICSPR,X STA LNKSEC,X JSR CHASE ;READ SECTOR POINTED TO BCS BADPNT ; PNTSME LDA ICSPR+2,X CMP MAXLEN,X BCS PNTEQL PNTLST STA CURLEN,X JMP DONE ; PNTEQL BEQ PNTLST ;IF POINTING AT LAST BYTE BADPNT LDA #166 ;INVALID POINT LOCATION DB $AE ; ERRCMD LDA #168 ;INVALID IOCB PARAMETER JMP AEXIT ; NOTE LDA CURSEC,X STA ICSPR,X LDA CURSEC+1,X STA ICSPR+1,X LDA CURLEN,X STA ICSPR+2,X JMP DONE ; DKXIO JSR SETUP LDA ICCOMZ ;GET COMMAND BYTE CMP #254 BEQ FORMAT CMP #43 ;ADD "MKDIR" CODE FOR SpartaDOS(?) [Bob Puff] BCS ERRCMD ;IF INVALID COMMAND SBC #32-1 BCC ERRCMD TAY LDA VECTBH,Y PHA LDA VECTBL,Y PHA RTS ;VECTOR TO PROPER ROUTINE ; VECTBH DB HIGH[RENAME-1],HIGH[DELETE-1] DB HIGH[MKDIR-1],HIGH[LOCK-1] DB HIGH[UNLOCK-1],HIGH[POINT-1] DB HIGH[NOTE-1],HIGH[DKLOAD-1] DB HIGH[ERRCMD-1],HIGH[PIKDIR-1] DB HIGH[MKDIR-1] ;extra vector to MKDIR [Bob Puff] ; VECTBL DB LOW[RENAME-1],LOW[DELETE-1] DB LOW[MKDIR-1],LOW[LOCK-1] DB LOW[UNLOCK-1],LOW[POINT-1] DB LOW[NOTE-1],LOW[DKLOAD-1] DB LOW[ERRCMD-1],LOW[PIKDIR-1] DB LOW[MKDIR-1] ; ; DOS FORMAT ROUTINES ; FORMAT JSR WBITMP ;WRITE OUT ANY PENDING VTOC SECTORS ; ldy #9 ;Force format to match current density WOTCP2 lda WOTDCB,y ;set up DCB for specified density [Bob Puff] sta DDEVIC+2,y dey bpl WOTCP2 ldx ICDNOZ cpx RAMDKU beq WOTRAM ;don't do it for RAMdisks ; ldy SECSIZ-1,x lda DRVDEF-1,x jsr SETDRV ;set density WOTRAM ldx CURFCB ;restore X reg ; LDY #0 TYA ;THEN INITIALIZE NEW BIT MAP (VTOC) CLRMAP STA MAPBUF,Y STA MAPBUF+256,Y INY BNE CLRMAP ; LDA #2 STA MAPBUF ;start out as a DOS 2.0 disk LDA #$FF STA (FMSBPT),Y INY STA (FMSBPT),Y ;PRESUME NO BAD SECTORS IF BUFFER IS UNMODIFIED LDY ICDNOZ CPY RAMDKU BEQ RAMFMT ;IF RAMDISK, SKIP EVERYTHING LDA FMSBPT+1 LDY FMSBPT JSR BUFSET ;SET UP BUFFER POINTER FOR SIO CALL LDX #1 STX TMP1 ;ALLOW ONE TRY ONLY LDA #$22 ;PRESUME 1050 D/D FORMAT NEEDED LDY ICAX2Z ;GET AUX2 BYTE BMI FMTOK ;MINUS --> NO FORMAT REQUIRED BNE NMLFMT ;AUX2 NONZERO, NORMAL FORMAT WITH SIZE DEFINED LDY ICAX1Z ;(AUX2,AUX1) = 1? DEY BEQ FT1050 ;YES, FORMAT WITH A $22 COMMAND ; NMLFMT ldx DUNIT lda SECSIZ-1,X ;PUT SECTOR SIZE CODE (1 OR 2) INTO X tax lda #FMTCMD ;AUX IS 0, must not be 1050 d/d FT1050 STA DAUX1 ;MAKE SURE WE SECTOR > 3 LDY DSKTIM ;DISK TIMEOUT VALUE (RETURNED IN STATUS) JSR DKFME ;ENTER DKIO AT FORMAT ENTRY BPL FMTOK ;Accepting 144 errors here removed [Bob Puff] JMP AEXIT ;RETURN ERROR CODE IF ANY OCCURRED ; RAMFMT STA CURSEC,X ;STUFF PROPER NUMBER OF SECTORS INTO CURSEC CLC ;(256-BYTE PAGES * 2 SINCE SECTOR SIZE IS 128) ADC RDKLMT LSR A ROR CURSEC,X BNE NOTDEF ;FAIL IF NOT 256 SECTORS OR MORE (need 370) ; ; SUCCESSFUL FORMAT, CREATE VTOC AND EMPTY DIRECTORY ; FMTOK ;Bob Puff disabled the marginal format code ; ldy #0 ;check for a bad format ; lda (FMSBPT),y ; and (FMSBPT),y ;first two bytes $FF? ; cmp #$FF ; beq FMTOK2 ;yep, continue ; lda #173 ;otherwise format error ; bne FMEXIT ; FMTOK2 JSR INVUNIT ;Can we do this (asks Bob Puff) JSR DELDOS LDA ICAX1Z STA CURSEC,X LDA ICAX2Z AND #$7F ;DISK MUST HAVE 256 SECTORS BNE NOTDEF ;IF SIZE SPECIFIED, USE IT LDY ICDNOZ LDA HDTAB-1,Y ;IF NOT AND THIS IS A HARD DISK STA CURSEC,X ;USE THE SYSTEM DEFINED SIZE LDA HDTAB+8-1,Y BNE NOTDEF BIT DVSTAT ;1050 DRIVE? BPL FIGSIZ ;NO, FIGURE SIZE THEN LDA #LOW[1040] ;YES, FORCE TO 1040 SECTORS STA CURSEC,X LDA #HIGH[1040] BNE NOTDEF ; FIGSIZ LDA DRVDEF-1,Y AND #$31 ;EXTRACT TRACK COUNT FLAGS LSR A PHP LSR A LSR A TAY LDA NOSECS,Y ;AND USE DRIVE DEFAULT SECTOR COUNT STA CURSEC,X LDA NOSECS+1,Y PLP BCC NOTDEF ;IF NOT DOUBLE SIDED, THIS IS IT ASL CURSEC,X ROL A ;ELSE, DOUBLE IT ; NOTDEF STA CURSEC+1,X CMP #4 ;NEED 16 BIT LINKS? BCC SHORTS ;NO, SHORT FORMAT OK INC MAPBUF ;YES, FORCE LONG FORMAT (DOS3) SHORTS JSR FNDBIT ;FIND LAST BIT MAP SECTOR LDA TMP2 BNE GT246 ;IF PAST 256TH MAP BYTE BIT DLINK ;SINGLE DENSITY? BMI FDBDEN CPY #0 BPL FDBDEN GT246 STA MAP2 CLC ADC #3 STA MAPBUF FDBDEN LDA #HIGH[-9] STA MAPBUF+4 LDA #LOW[-9] STA MAPBUF+3 ;START WITH 9 FREE SECTORS UN-FREE! FLOOP JSR FMTFRE JSR DECCSEC CMP #4 ;BOOT SECTORS YET? BNE FLOOP ;IF NOT, CONTINUE DEALLOCATING LDA CURSEC+1,X BNE FLOOP ; ; ALLOCATE BAD SECTORS ; [Bob Puff replaced this with code to set FMSBPT to 1, since he ; disallows bad sectors] ; LDY #0 CLRBDLP LDA (FMSBPT),Y STA CURSEC,X INY LDA (FMSBPT),Y STA CURSEC+1,X INY AND CURSEC,X CMP #$FF CLC BEQ MAPDONE STY TMP1 JSR DECCNT JSR FNDLBIT EOR #$FF BCC CLRBD1 AND MAPBUF+256,Y STA MAPBUF+256,Y BCS CLRBD2 CLRBD1 AND MAPBUF,Y STA MAPBUF,Y CLRBD2 LDY TMP1 BNE CLRBDLP SEC LDY #173*2-256 ;NO $FFFF => BAD FORMAT MAPDONE TYA ROR A STA FMSBPT ;POSITIVE VALUE = NUMBER OF BAD SECTORS ; ; [End of code that can be optionally deleted] ; LDA #$00 STA MAPBUF+55 LDA #$7F STA MAPBUF+56 LDY #44 ;START ALLOC. OF VTOC HERE LDA MAPBUF SEC SBC #2 ;GET NUMBER OF SECTORS BIT DLINK ;(SINGLE DENSITY?) BMI MPNSD ;IF NOT, M-3 ASL A ;IF SO, M*2-5 MPNSD TAX DEX ;MOVE COUNT TO X ; ALCMPL LDA #$FF ALCMAP DEX BMI SMBSIZ PHA JSR DECCNT PLA ASL A BNE ALCMAP STA MAPBUF+10,Y DEY BPL ALCMPL ;BRANCH ALWAYS! ; SMBSIZ STA MAPBUF+10,Y LDA MAPBUF+3 ;MARK EMPTY SIZE, TOO STA MAPBUF+1 LDA MAPBUF+4 STA MAPBUF+2 JSR FMTMAP ;WRITE MAP TO DISK ; ; CREATE AN EMPTY DIRECTORY ; LDA #LOW[361] LDY #HIGH[361] CLRDIR JSR SETDIR ;RESET THE DIRECTORY BASE SECTOR TYA CLRDLP STA DIRBUF,Y ;ZERO THE DIRECTORY BUFFER INY BNE CLRDLP ; LDA #7 STA DIRSEC CLRDL2 JSR WDIRBK ;THEN WRITE ALL 8 SECTORS OUT DEC DIRSEC BPL CLRDL2 LDY BUFNO,X LDA #0 STA BUFNO,X STA BUFFLG-1,Y ;FORMAT DONE, FREE THE INTERNAL BUFFER LDA FMSBPT JMP AEXIT ; NOSECS DW 35*18,40*18,80*18,77*26 ; SETDIR STA DIRBAS,X TYA STA DIRBAS+1,X LDY #0 RTS ; ; DOS BINARY LOAD CODE (LOAD AND OPTIONALLY EXECUTE A PROGRAM) ; DKLOAD LDA ICAX1Z STA ICPTLZ ;SAVE PROGRAM NAME BUFFER POINTER CMP #$08 BCS TOERRC ;IF WRITE, REPORT ERROR ; LDA #LOW[TORTS] STA RUNADR LDA #HIGH[TORTS] ;ASSUME RUNN ADDRESS IS ABSENT STA RUNADR+1 LDA #4 STA ICAX1Z LDA ICHID,X ;IOCB OPEN? BPL CCFILE JSR DKOPEN ;IF NOT, OPEN IT BMI DKLERV JSR WDREAD ;READ ONE WORD OF THE HEADER BEQ CCFILE LDY #180 ;NO $FFFF, HEADER ERROR CODE BMI DKLERV ; TOERRC LDY #168 ;INVALID IOCB RTS ; GETTXT LDA #LOW[TORTS] STA INIADR LDA #HIGH[TORTS] ;FOR EACH SEGMENT, RECLEAR THE INIT VECTOR STA INIADR+1 TXTLP JSR DKREAD DKLERV BMI DKLERR LDY #0 STA (ICBALZ),Y INC ICBALZ BNE DECLEN INC ICBAHZ DECLEN LDA ICBLLZ BNE DECLOW DEC ICBLHZ DECLOW DEC ICBLLZ BNE TXTLP LDA ICBLHZ BNE TXTLP LDA ICBAHZ CMP #HIGH[INIADR] BNE CCFILE ; LDA ICPTLZ ;IF NO INITS, LSR A BCS CCFILE ;SKIP TO NEXT PAGE TXA ;ELSE SAVE IOCB PHA LDY #256-12 CPSICB LDA ICHIDZ-256+12,Y STA ICHID,X ;SAVE THE 12-BYTE IOCB ENTRY INX INY BNE CPSICB PLA TAX PHA JSR DOINIT ;AND CALL INIT FUNCTION PLA TAX PHA LDY #256-12 CPRICB LDA ICHID,X ;THEN RESTORE THE 12-BYTE IOCB STA ICHIDZ-256+12,Y INX INY BNE CPRICB PLA TAX ; CCFILE JSR WDREAD ;READ THE SEGMENT START ADDRESS BEQ CCFILE STA ICBALZ STY ICBAHZ JSR WDREAD ;READ THE SEGMENT END ADDRESS SEC ADC #0 BCC CCSUBT INY CCSUBT SEC SBC ICBALZ ;CALCULATE THE LENGTH TO LOAD INTO RAM STA ICBLLZ TYA SBC ICBAHZ STA ICBLHZ BCS GETTXT ;BRANCH IF VALID LENGTH (GET DATA BYTES) LDY #181 ;ELSE, MEMORY WRAP ERROR BMI DKLERR ; WDXIT PLA PLA DKLERR TYA PHA JSR DKCLOS ;CLOSE THE PROGRAM FILE PLA TAY ;AND RETURN ANY ERROR CODE RTS ; ; READ A WORD FROM THE PROGRAM FILE AND COMPARE IT WITH $FFFF ; WDREAD LDA #0 STA ICBLLZ STA ICBLHZ ;SET LENGTH TO ZERO JSR DKREAD ;READ A BYTE BMI WDEOF PHA JSR DKREAD ;READ THE SECOND BYTE BMI WDEOF1 TAY PLA CPY #$FF ;UPPER BYTE $FF? BNE TORTS ;NO, THEN WORD IS NOT $FFFF CMP #$FF ;YES, IS LOWER BYTE $FF? TORTS RTS ;IF BOTH $FF, RETURN ZERO FLAG ; WDEOF1 PLA WDEOF CPY #136 ;IS THIS END OF FILE? BNE WDXIT ;IF NOT, RETURN ERROR CODE PLA PLA ;ELSE, GET RID OF RETURN ADDR LDA ICPTLZ LSR A LSR A PHP JSR DKCLOS ;CLOSE FILE AND SET Y=1 PLP BCS TORTS ;EXIT IF NO-RUN SPECIFIED JMP (RUNADR) ;THEN GO TO RUN ADDRESS ; ; INVOKE INIT FOR EVERY BLOCK OF INPUT CODE (USUALLY JUST AN RTS) ; DOINIT JMP (INIADR) ;CALL INDIRECT ; ; XIO FUNCTION TO CREATE A NEW DIRECTORY ; ; PARSE DIRECTORY NAME ; MKDIR JSR GETFNM JSR SFDIR ;FIND FILE IN DIRECTORY BCS MKDMRD LDA #172 ;FILE ALREADY EXISTS DB $AE ;SKIP 2 BYTES DISFUL LDA #169 ;DIRECTORY FULL JMP AEXIT ; ; READ IN BIT MAP ; MKDMRD LDA HOLFN BMI DISFUL JSR RBITMP LDY MAPBUF DEY DEY STY DATBYT ; ; FIND EIGHT SECTORS FOR DIRECTORY ; LDA #LOW[369] ;FIRST AVAILABLE SECTOR AFTER ROOT DIR. STA CURSEC,X LDA #HIGH[369] STA CURSEC+1,X LDA #0 STA TMP1 FDIRLP INC TMP1 JSR FNDLBIT ;IS THIS SECTOR FREE? BCS FDIR2 AND MAPBUF,Y BCC FDIR1 FDIR2 AND MAPBUF+256,Y FDIR1 BNE FDIR3 STA TMP1 FDIR3 JSR INCCSEC LDA TMP1 CMP #8 BNE FDIRLP ; ; ALLOCATE THE SECTORS USED ; ALCDLP JSR DECCSEC JSR FNDLBIT EOR #$FF BCS ALCPG2 AND MAPBUF,Y STA MAPBUF,Y BCC ALCPG1 ALCPG2 AND MAPBUF+256,Y STA MAPBUF+256,Y LSR MAP2MOD ALCPG1 JSR DECCNT DEC TMP1 BNE ALCDLP ; ; WRITE ALLOCATION MAP BACK TO DISK ; JSR FMTMAP ; ; ENTER NAME AND TYPE INFO INTO PARENT DIRECTORY ; LDA HOLFN JSR SDIRBK SEC JSR ENTNAME LDA CURSEC+1,X STA DIRBUF+4,Y LDA CURSEC,X STA DIRBUF+3,Y LDA #0 STA DIRBUF+2,Y LDA #8 STA DIRBUF+1,Y ASL A JSR SAVFLAG ; ; THEN CLEAR NEW DIRECTORY ; LDA #1 STA FMSBPT LDA CURSEC,X LDY CURSEC+1,X JMP CLRDIR