Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!mit-eddie!killer!chasm From: chasm@killer.DALLAS.TX.US (Charles Marslett) Newsgroups: comp.sys.atari.8bit Subject: MYDOS 4.51 source posting Keywords: DOS MYDOS A65 SOURCE Message-ID: <8451@killer.DALLAS.TX.US> Date: 24 Jun 89 16:26:52 GMT Organization: The Unix(R) Connection, Dallas, Texas Lines: 2628 # This is a shell archive (Part 2 of 3) # # It contains the source code to the file manager # part of MYDOS. See the documentation in part 1 to # assemble it. # # Run this file through the Bourne shell "sh" or an unshar # program to extract the individual files. Assemble using # the just posted A65 assembler. # #----cut here-----cut here-----cut here-----cut here----# #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # mdos.asm # mdos1.asm # mdos2.asm # mdos3.asm # mdos4.asm # This archive created: Sat Jun 24 08:37:24 1989 sed 's/^X//' << \SHAR_EOF > mdos.asm X TITLE 'LARGE DISK FMS' X; X; Copyright 1984, Charles Marslett, Wordmark Systems X; X; Permission is granted by the author for any use whatsoever of this X; code, so long as this notice remains in the source code, and so X; long as the source to this routine, however modified or unmodified, X; is made available for a nominal cost. X; X LIST C,G,I X; X; DISK I/O EQUATES X; XDKADDR = $31 ;SIO ADDRESS OF FIRST DISK DRIVE (D1:) XTODK = $80 ;STATUS BYTE FOR A DATA TRANSFER TO THE DISK XFROMDK = $40 ;STATUS BYTE FOR A DATA TRANSFER FROM THE DISK X; XREAD = 'R' ;SIO COMMAND EQUATE FOR READING A DISK XWRITE = 'P' ;SIO COMMAND EQUATE FOR WRITING A DISK XRDSTAT = 'S' ;SIO COMMAND EQUATE FOR READING THE DRIVE STATUS XWRITEV = 'W' ;SIO COMMAND EQUATE FOR WRITING A DISK with VERIFY XFMTCMD = '!' ;SIO COMMAND TO FORMAT A DISKETTE X; XLK128 = 125 ;LOCATION OF 128 BYTE SECTOR LINK XLK256 = 253 ;LOCATION OF 256 BYTE SECTOR LINK X; XWARMST = $0008 XDOSVEC = $000A XDOSINI = $000C X; X ORG $0020 XICHIDZ DS 1 XICDNOZ DS 1 XICCOMZ DS 1 XICSTAZ DS 1 XICBALZ DS 1 XICBAHZ DS 1 XICPTLZ DS 2 XICBLLZ DS 1 XICBLHZ DS 1 XICAX1Z DS 1 XICAX2Z DS 1 X DS 2 XCURFCB DS 1 XDATBYT DS 1 X; X ORG $0031 XCHKSUM DS 1 XBUFR DS 2 X; X ORG $0043 XFMSZPG DS 2 XDIRDSP = FMSZPG XDIRSEC = FMSZPG+1 XCURFNO DS 1 XFMSBPT DS 2 XTMP1 DS 1 XTMP2 DS 1 X; X; DEFINITIONS FOR THE ATARI ROM EXECUTIVE X; XDSKTIM = $0246 XRUNADR = $02E0 XINIADR = $02E2 XMEMTOP = $02E7 XDVSTAT = $02EA X; X; SIO COMMAND BUFFER DEFINITION X; X ORG $0300 XDDEVIC DS 1 XDUNIT DS 1 XDCOMND DS 1 XDSTATS DS 1 XDBUFLO DS 1 XDBUFHI DS 1 XDTIMLO DS 2 XDBYTLO DS 1 XDBYTHI DS 1 XDAUX1 DS 1 XDAUX2 DS 1 X; X; I/O SYSTEM DEFINITIONS X; XHATABS = $031A ;BASE OF THE DYNAMIC HANDLER TABLE X; X; CIO COMMAND TABLE BASE DEFINITIONS (FOR IOCB $00) X; X ORG $0340 XICHID DS 1 XICDNO DS 1 XICCOM DS 1 XICSTA DS 1 XICBAL DS 1 XICBAH DS 1 XICPTL DS 1 XICPTH DS 1 XICBLL DS 1 XICBLH DS 1 XICAX1 DS 1 XICAX2 DS 1 XICSPR DS 4 X; X; CARTRIDGE SUBSYSTEM DEFINITIONS X; XCARINIT = $BFFE ;LOCATION OF INIT VECTOR XCARTEST = $BFFC ;LOCATION OF FLAGS XCARRUN = $BFFA ;LOCATION OF RUN VECTOR X; X; 800XL MAP CONTROL X; XMAPREG = $D301 X; X; OTHER I/O PORT DEFINITIONS X; XNMIEN = $D40E X; X; ROM VECTORS X; XDSKINV = $E453 ;SINGLE DENSITY DISK I/O ENTRY POINT XSIOV = $E459 ;SERIAL I/O O.S. ENTRY POINT X; X INCLUDE D:MDOS1.ASM ;DATA AND CODE THAT REMAINS FIXED X; X INCLUDE D:MDOS2.ASM ;FILE SYSTEM FUNCTIONS X; X INCLUDE D:MDOS3.ASM ;INTERNAL DISK I/O ROUTINES X; X INCLUDE D:MDOS4.ASM ;UTILITY SUBROUTINES X; XBOOTND END ;START DUP HERE! SHAR_EOF sed 's/^X//' << \SHAR_EOF > mdos1.asm X;================================================= X;= MYDOS BOOT CODE == X;================================================= X; X; DISK BOOT SECTORS (3) X; X ORG $0700 ;DOS.BOOT LOADS AT 0700 XBOOTFL DB 'M' ;INDICATE MYDOS 4.5 OR LATER XBOOTL DB 3 ;NUMBER OF SECTORS IN THE BOOT XBOOTAD DW BOOTFL ;ADDRESS OF BOOT CODE IN RAM XBOOTIN DW INIT X JMP INBOOT ;JUMP TO THE BOOT CONTINUATION XFILES DB 3 ;NUMBER OF FILES THAT MAY BE OPEN AT ONCE X;DRIVES = * ;USED TO BE BIT PATTERN FOR DRIVES XRAMDKU DB $09 ;RAM DISK UNIT # X;BUFALC = * ;USED TO BE BUF. ALLOC. DIR. XDEFAULT DB 1 ;DEFAULT UNIT NUMBER XDOSEND DW BOOTND ;ADDRESS OF THE FIRST BYTE OF FREE MEM. XSECDAT DB 1 ;1=128 BYTE SECTOR/2=256 BYTE SECTOR XDOSLOC DW 4 ;SECTOR ADDRESS OF DOS.SYS XDLINK DB LK128 ;OFFSET TO THE SECTOR LINK FIELD XDOSAD DW BASE ;ADDRESS TO LOAD DOS.SYS INTO X; XINBOOT LDY DOSAD ;SET UP START OF DOS AS BUFFER ADDRESS X LDA DOSAD+1 X JSR BTSET ;LOW ADDR IN Y, HIGH IN A X; X LDA DOSLOC+1 X LDY DOSLOC ;PUT DOS DISK ADDRESS INTO (A,Y) X; X; DOS.SYS INPUT LOOP X; XINITLP CLC ;CLEAR CY, 'DO A READ' X LDX SECDAT ;GET CODE FOR SECTOR SIZE X BEQ NODOS ;IF ZERO, NO DOS ON DISK! X JSR DKIO ;INVOKE DISK I/O ROUTINE X BMI NODOS ;IF AN ERROR, RETURN NO-DOS ERROR X LDY DLINK ;POINT TO LINK X LDA (FMSZPG),Y ;CHECK FOR NEXT LINK (10-BITS) XANDCD AND #$03 ;BEING ZERO, X PHA ;SAVE UPPER BYTE OF ADDRESS X INY X ORA (FMSZPG),Y ;IF SO, LOADING IS COMPLETE X BEQ BOOTXT X LDA (FMSZPG),Y ;ELSE, IT'S THE ADDRESS OF NEXT SECTOR X PHA ;SAVE LOWER BYTE ON STACK X JSR MVBUFR ;THEN ADJUST THE BUFFER POINTER IN DCB X PLA X TAY ;RESTORE LOWER BYTE TO Y-REG X PLA ;RECOVER UPPER BYTE OF DISK ADDRESS X BCC INITLP ;AND CONTINUE LOADING X; XNODOS LDA #$C0 ;NO BOOT PROGRAM ERROR CODE X DB $A0 ;SKIP SINGLE BYTE (LDY #) X; XBOOTXT PLA XDOSXIT ASL A ;SET CARRY, CONVER CODE TO FINAL VALUE X TAY ;PUT CODE INTO Y-REG X RTS ;AND EXIT X; X; MOVE BUFFER POINTERS TO NEXT AREA TO BE LOADED X; XMVBUFR LDA DLINK X CLC X ADC FMSZPG ;ADD DLINK TO THE CURRENT BUFFER ADDRESS X TAY ;LOW BYTE TO Y-REG X LDA FMSZPG+1 X ADC #0 XBTSET STY FMSZPG X STA FMSZPG+1 XBUFSET STY DBUFLO ;STORE LOW BYTE INTO DCB X STA DBUFHI ;THEN UPPER BYTE X RTS X; X; PERFORM DISK READ(CY=0) OR WRITE (CY=1) X; XDKIO STA DAUX2 ;STORE UPPER BYTE OF SECTOR ADDRESS X STY DAUX1 ;THEN LOWER BYTE XDKIO2 LDY #3 X LDA #READ X BCC SETRTY ;IF CY=0, READ INTO RAM X LDA WRCMDB X; XSETRTY STY TMP1 ;SET NUMBER OF TRIES XDKFME STA DCOMND X CLC X LDA #WRITEV ;CLC AND CONSTANT FOR POKERS XWRCMDB = *-1 X STY DTIMLO X LDA #128 ;ASSUME A 128-BYTE SECTOR SIZE X DEX X BEQ STBUFL X LDX DAUX2 ;SECTOR > 256? X BNE SET256 X LDX DAUX1 X CPX #4 ;SECTOR > 3 X BCC STBUFL ;IF NOT XSET256 ASL A ;MAKE A 256 BYTE SECTOR SIZE XSTBUFL STA DBYTLO X ROL A X STA DBYTHI X LDY #DKADDR ;PUT DISK DEVICE CODE INTO DCB X STY DDEVIC XIORTRY DEC TMP1 X BMI DIOXIT X LDX DCOMND X INX X TXA X LDX #FROMDK ;ASSUME DATA ==> DISK X AND #$06 X BNE ISREAD ;IF NOT X0,X7,X8 OR XF, OK X LDX #TODK ;ELSE, DATA ==> DISK XISREAD STX DSTATS ;RESTORE STATUS TO DCB X JSR SIOV ;DO THE I/O OPERATIONS X DEY X BMI IORTRY ;IF NOT OK, RETRY X; XDIOXIT LDX CURFCB ;ELSE, LOAD FCB OFFSET AND STATUS X INY X TYA X RTS X; X; FIXED RAM DEFINITIONS IN BOOT SECTORS X; XDIUNIT DS 1 ;UNIT NO. OF CURRENT DIRECTORY XCDIREC DS 2 ;SECTOR NO. OF CURRENT DIRECTORY XHOLFN DS 1 XSTATE DB $70 ;DUP loaded, MEM.SAV inactive, Warmstart X ; bit 7 -- MEM.SAV in use X ; bit 6 -- DUP.SYS loaded X ; bit 5 -- AUTORUN.SYS already run X ; bit 4 -- Initial BUILD active X ; XSTKPSV DS 1 ;SAVED STACK POINTER X ORG $07C0 ;MUST MATCH DUP LOCATION X; XTRACKS DB 35,40,80,77 ;TRACKS IN EACH DISK FORMAT X; XSECSIZ DB 0,0,0,0 ;BUFFER SIZE TABLE X DB 0,0,0,0 X; XDRVDEF DB $52,$52 ;DRIVE CONFIGURATION TABLE: X DB $D2,$D2 ;BIT 7=1 => NO DRIVE X DB $D2,$D2 ;BIT 6=1 => ATARI 810 DRIVE X DB $D2,$D2 ;BIT 5-4 IS (0=35, 1=40, X ; 2=80, 3=77 TRACKS(8") X ;BIT 3=1 => DOUBLE DENSITY X ;BIT 2-1 IS DRIVE STEP RATE X ;BIT 0=1 => DOUBLE SIDED X; X; DOS.SYS PROGRAM FOLLOWS X; XDKEPT DW DKOPEN-1 X DW DKCLOS-1 X DW DKREAD-1 X DW DKWRIT-1 X DW DKSTAT-1 X DW DKXIO-1 X; X ORG $07E0 X; X; IDENTIFY DRIVE TYPES X; XINIT LDA #LOW[361] X STA CDIREC X LDA #HIGH[361] X STA CDIREC+1 X; X; IDENTIFY DRIVE TYPES X; X LDX #8 XIDRVLP STX DUNIT X JSR ZERDVS ;ASSUME THE DRIVE IS NOT PRESENT X LDA DRVDEF-1,X X BMI NXTDRV ;IF NOT DECLARED, WE ARE DONE X; X JSR JSTRD ;ELSE, READ ITS STATUS X BEQ NXTDRV ;IF ABSENT, GO ON TO THE NEXT ONE X LDY #9 XWOTCPY LDA WOTDCB,Y X STA DDEVIC+2,Y X DEY X BPL WOTCPY X LDA DRVDEF-1,X X CMP #$40 X BCS NXTDRV ;IF NOT CONFIGURABLE, CONTINUE X LDY SECSIZ-1,X X JSR SETDRV ;TELL IT ABOUT MY CONFIGURATION X; XNXTDRV DEX ;STEP TO NEXT DRIVE NUMBER X BNE IDRVLP ;IF MORE, LOOK AT THEM X; X; ZERO INITIALIZED MEMORY X; X LDY #MAPBUF+7-CHGMAP X TXA ;NOTE X=0 HERE XZERLP1 STA CHGMAP-1,Y X DEY X BNE ZERLP1 X INC MAP2MOD X; X; DEFINE TOP OF FMS FOR USER PROGRAM X; X LDA DOSEND X STA MEMTOP X LDY DOSEND+1 X; X; ALLOCATE FILE SECTOR BUFFERS X; X LDX #15 ;MAX OF 16 SECTOR BUFFERS XDKBFLP CPX FILES ;EMPTY BUFFERS DONE? X BCC ALCBUF X DEC BUFFLG,X X BMI DKBFSQ XALCBUF TYA X STA SBTABU,X X INY XDKBFSQ DEX ;BUMP BUFFER COUNTER X BPL DKBFLP ;IF NOT CONTINUE LOOPING X STY MEMTOP+1 ;DEFINE TOP OF MEMORY USED X; X; SET UP HANDLER VECTOR X; XFNDHND INX X INX X INX X LDA HATABS-2,X ;END OF THE HANDLER TABLE? X BEQ NOHAND ;THEN INSTALL IT HERE X CMP #$44 ;A 'D' ALREADY PRESENT? X BNE FNDHND ;NO, CONTINUE LOOKING, ELSE OVERWRITE IT X; XNOHAND LDA #$44 ;WRITE AT END OF TABLE OR CURRENT "D" ENTRY X STA HATABS-2,X X LDA #LOW[DKEPT] ;STASH MYDOS ENTRY VECTOR X STA HATABS-1,X X LDA #HIGH[DKEPT] X STA HATABS,X ;BUILD HANDLER VECTOR X JMP DUPINV ;DONE, INITIALIZE DUP [overwritten by MDUP] X; X; DOS NON-ZERO PAGE RAM ALLOCATIONS X; XCHGMAP DS 1 XCURMAP DS 1 XMAP2 DS 1 XMAP2MOD DS 1 XLSTSEC DS 2 XLSTIOCB DS 1 X; X; MYDOS FCB STRUCTURE (ALMOST THE SAME AS ATARI DOS 2.0) X; XFCBFNO DS 1 XFCBOTC DS 1 ;OPEN TYPE CODE XFCBFLG DS 1 XMAXLEN DS 1 XCURLEN DS 1 XBUFNO DS 1 XCURSEC DS 2 XLNKSEC DS 2 XSECCNT DS 2 XDIRBAS DS 2 ;BASE ADDRESS OF CUR. SECTOR XSAVSEC DS 2 XFCBLEN = 16 X DS 7*FCBLEN ;SPACE FOR THE REMAINING 7 IOCBs X; XBUFFLG DS 16 ;IF 0, BUFFER NOT IN USE XSBTABU DS 16 ;UPPER BYTE OF THE SECTOR BUFFER ADDRESS XMAPBUF DS 512 ;SPACE ALLOCATED FOR VTOC XDIRBUF = MAPBUF ;SPACE ALLOCATED TO READ DIRECTORIES XFNAME DS 12 XCURMP DS 1 X; XBASE = * XHDTAB DW 0,0,0,0 ;8 LOGICAL HARD DRIVES OF X DW 0,0,0,0 ;UP TO 65535 SECTORS EACH X; X; X;NOTE: this table is referenced by DUP.SYS, and should not be moved! X; X; DOS CONFIGURATION CODE X; X; CONTROL BLOCK TO BE WRITTEN TO A DRIVE TO CONFIGURE IT X; XWOTDCB DB $4E,$40 X DW DIRBUF,1 X DW 12,4 X; X; THE CONFIGURATION CODE, FORCES A DRIVE INTO THE APPROPRIATE CONFIGURATION X; XSETDRV AND #$3F ;EXTRACT CONF. BITS X STA TMP1 X STY TMP2 X JSR SIOV ;READ CURRENT CONFIGURATION X BMI JSTRD X LDA TMP1 X LDY TMP2 X LSR A X PHA ;SAVE REMAINING BITS X AND #3 ;EXTRACT STEP RATE CODE X STA DIRBUF+1 X LDA #0 X STA DIRBUF+2 X ROL A X STA DIRBUF+4 ;STORE DOUBLE SIDED FLAG X TYA ;GET DENSITY X LSR A X STA DIRBUF+6 ;STORE UPPER BYTE OF SECTOR SIZE X ROR A X STA DIRBUF+7 ;THEN LOWER BYTE X ROL A X ASL A X ASL A X STA DIRBUF+5 X PLA X LSR A X LSR A X LSR A ;POSITION TRACK COUNT FIELD X TAY X LDA TRACKS,Y ;GET NUMBER OF TRACKS X STA DIRBUF X AND #$04 ;SEE IF 77 TRACK 8 IN. X PHA X LSR A X ORA DIRBUF+5 ;MERGE D/DENSITY WITH 8 IN. FLAG X STA DIRBUF+5 X PLA X ASL A ;CONVERT TO 0 OR 8 X ADC #18 ;SECTOR COUNT = 18 OR 26 X STA DIRBUF+3 X LDY DUNIT X LDA HDTAB-1+8,Y X BEQ TOSIOV X STA DIRBUF+2 ;SIZE = SECTORS/TK X LDA HDTAB-1,Y X STA DIRBUF+3 ;LOW BYTE OF SIZE X LDA #1 X STA DIRBUF ;ONE TRACK/DRIVE XTOSIOV INC DCOMND ;CHANGE COMMAND TO WRITE X LDA #$80 X STA DSTATS ;SET DIRECTION -> DISK X JSR SIOV ;WRITE OPTION TABLE TO DRIVE X; XJSTRD LDA #RDSTAT X STA DCOMND X JSR DSKINV X LDX DUNIT X TYA X BMI ZERDVS X LDA DVSTAT X ASL A ;SECTOR SIZE=256? X ASL A X ASL A X LDA #1 X ADC #0 XSETSIZ STA SECSIZ-1,X X RTS X; XZERDVS LDA #0 X BEQ SETSIZ ;ALWAYS BRANCHES! X; X; DOS RAMDISK CODE (moved here starting with version 4.5) X; X; RAM DISK I/O HANDLER (POS. IND. CODE) X; XMAPAGE X DB $E3,$E7,$EB,$EF X DB $83,$87,$8B,$8F X DB $C3,$C7,$CB,$CF X DB $A3,$A7,$AB,$AF X; X DB $93,$97,$9B,$9F X DB $D3,$D7,$DB,$DF X DB $B3,$B7,$BB,$BF X DB $F3,$F7,$FB,$FF X; X DB $E3,$E7,$EB,$EF X DB $83,$87,$8B,$8F X DB $C3,$C7,$CB,$CF X DB $A3,$A7,$AB,$AF X; X DB $93,$97,$9B,$9F X DB $D3,$D7,$DB,$DF X DB $B3,$B7,$BB,$BF X DB $F3,$F7,$FB,$FF X; XVALSEC PHA X TYA X ORA #$80 X LSR A X STA BUFR+1 X SEI ;DISABLE INT-S X LDA #0 X STA NMIEN ;DISABLE NMI-S X ROR A X STA BUFR X PLA X TAY X LDA MAPREG X ORA #$1C X STA CHKSUM X ORA #$7C X AND MAPAGE,Y X STA MAPREG ;SELECT RAMDISK DATA PAGE X; X LDA DBUFLO ;USER BUFFER ADDRESS GOES HERE X STA BUFR+2 X LDA DBUFLO+1 X STA BUFR+3 X LDY #0 X PLP X BCC RREADL ;CY=0 IF READ XRWRITL LDA (BUFR+2),Y X STA (BUFR),Y X INY X BPL RWRITL X BMI RIOX X; XRDKIO STY DAUX1 ;*** FOR FORMAT CODE *** X CPY #$80 X ROL A X CMP #4 XRDKLMT = *-1 ;NUMBER OF 16K PAGES IN RAMDISK X BCC VALSEC ;CALCULATE MEM. ADDR. X PLP X LDA #139 X BMI RERROR X; XRREADL LDA (BUFR),Y X STA (BUFR+2),Y X INY X BPL RREADL X; XRIOX LDA CHKSUM ;FORCE REAL RAM PAGE X STA MAPREG ;BEFORE EXITING X LDA #$C0 X STA NMIEN ;RE-ENABLE NMI X CLI ;ENABLE INTERRUPTS X LDA #1 ;RETURN '1' IN Y-REG XRERROR STA DSTATS ;AND IN STATUS BYTE X LDX CURFCB ;RESTORE FCB ADDR X TAY X RTS ;THEN EXIT X; XSTEPBP LDA DBUFLO X EOR #$80 X STA DBUFLO X BMI TSTEOD X INC DBUFHI X; XTSTEOD LDY DAUX1 X RTS SHAR_EOF sed 's/^X//' << \SHAR_EOF > mdos2.asm X; X; DISK OPEN ROUTINE X; XDKOPEN JSR WBITMP ;Fix nasty bug! [Bob Puff] X JSR SETUP ;SET UP BUF PTRS, ETC. X JSR GETFNM ;GET DRIVE ID OR FILE NAME FROM BUFFER X LDA ICAX1Z ;GET TYPE OF OPEN FROM IOCB X STA FCBOTC,X X AND #$02 ;TEST DIRECTORY READ FLAG X BEQ DKOPN1 X JMP LSTDIR ;IF SET, GO HANDLE DIRECTORY FORMATTING X; XDKOPN1 STA SAVSEC,X X STA SAVSEC+1,X ;CLEAR SAVSEC X JSR SFDIR X PHP ;SAVE STATUS RETURNED X BCS OPNEW X LDA #$10 ;MAKE SURE THIS IS NOT A DIRECTORY X JSR GETFLAG X BNE DIROPN ;IF A DIRECTORY, GO HANDLE IT SEPERATELY XOPNEW LDY ICAX1Z X CPY #8 X BEQ OPNOP ;IF OPEN FOR OUTPUT X CPY #4 X BEQ OPNIN ;IF OPEN FOR INPUT X CPY #12 X BEQ OPNUP ;IF OPEN FOR READ/WRITE (UPDATE) X CPY #9 X BEQ OPNAP ;IF OPEN FOR OUTPUT/APPENDED XDIROPN JMP ERRCMD ;IF NONE OF THE ABOVE, IT IS AN ERROR! X; XOPNAP PLP ;OPEN APPEND X BCS OPNCR0 X JSR TSTLOK X JSR INITYP ;READ ALL THE SECTORS IN THE FILE X LDA DIRBUF+1,Y X STA SECCNT,X X LDA DIRBUF+2,Y X STA SECCNT+1,X XAPPRD JSR RDNXTS X BCC APPRD ;IF NOT EOF, READ ANOTHER X LDA MAXLEN,X X JSR LENSET ;SET LENGTHS FOR OUTPUT X LDA SECCNT,X X BNE SGLDEC X DEC SECCNT+1,X XSGLDEC DEC SECCNT,X ;ALLOW FOR SECTOR REWRITTEN X JMP OPOUTX X; XOPNUP PLP ;OPEN UPDATE (OUTPUT) X BCS OPNER1 X JSR TSTLOK XOPNOWR JSR INSTRT X JMP DONE X; XOPNIN PLP ;OPEN INPUT X BCC OPNOWR XOPNER1 LDA #170 ;FILE NOT FOUND X BMI EROXIT X; XOPNOP PLP ;OPEN (NORMAL) OUTPUT X BCS OPNCR X JSR REMOVE X JMP GET1ST X; XOPNCR0 DEC FCBOTC,X XOPNCR LDA HOLFN X STA CURFNO X BMI OPDIRF XGET1ST JSR ALLOC X; X LDA ICAX2Z ;IF OUTPUT, TYPE OF FILE X AND #$24 ;SAVE LOCKED & FORMAT BITS (with 4.5, DOS I no-more) X EOR #$43 ;MERGE IN DEFAULT CODE (DOS II, UNLOCKED) X LDY MAPBUF ;WHICH TYPE DISK? X CPY #3 ;IF >2 THEN MYDOS X BCC LLINKS X ORA #$04 X; XLLINKS PHA X JSR RDCFNO ;SELECT PROPER SECTOR IN DIRECTORY X SEC X JSR ENTNAME ;ENTER NAME INTO IT X LDA LNKSEC+1,X X STA DIRBUF+4,Y X LDA LNKSEC,X X STA DIRBUF+3,Y X PLA X JSR SAVFLAG X JSR INITYP X JSR TONXT XOPOUTX LDA #$80 X STA FCBFLG,X X JSR TSTDOS ;FILE NAME = DOS.SYS? X BNE JDONE X LDY CURSEC,X X LDA CURSEC+1,X X JSR SETDOS ;IF SO, UPDATE BOOT SECTORS X; X LDA DOSAD X STA FMSZPG X LDA DOSAD+1 X STA FMSZPG+1 X BNE OWTDOS ;NOTE: DOS CANNOT START ON ZERO-PAGE X; XOPDIRF LDA #169 XEROXIT JMP AEXIT X; XLWTDOS JSR WRNXTS ;AUTOMATICALLY WRITE DOS.SYS OUT XOWTDOS LDY #0 ;IF WE OPEN "DOS.SYS" FOR A WRITE XCDOSBF LDA (FMSZPG),Y ;(THIS IS BECAUSE DOS 2.0 WOULD BLOW X STA (FMSBPT),Y ; ITSELF AWAY IF A REAL WRITE FROM THE X INY ; DOS AREA WAS ATTEMPTED, AND WE HAVE X CPY DLINK ; TO REMAIN COMPATIBLE). X BCC CDOSBF X TYA X STA CURLEN,X X JSR MVBUFR X CPY DOSEND X SBC DOSEND+1 X BCC LWTDOS XJDONE JMP DONE X; X; READ DATA FROM A FILE X; XDKREAD JSR SETUP ;SETUP BUFFER POINTERS, ETC. X LDA FCBOTC,X X AND #$02 ;TEST THE DIRECTORY I/O FLAG X BEQ RDFILE X JMP DIRRD ;JUMP IF THE SPECIAL CASE OF A DIRECTORY READ X; XRDFILE LDA CURLEN,X X CMP MAXLEN,X X BCC RDSGBT ;IF NOT AT SECTOR BOUND., READ A BYTE AT A TIME X BCS RDASNT ;ELSE, CHECK FOR READ MODE AND BUFFER SIZE X; XRDASLP LDA ICCOMZ X AND #$02 X BEQ RDSGBT ;IF NOT BINARY I/O READ A BYTE AT A TIME X LDY DLINK X DEY XRDSCLP LDA (FMSBPT),Y ;SIMULATED BURST I/O (with unrolled loop) X STA (ICBALZ),Y X DEY X LDA (FMSBPT),Y X STA (ICBALZ),Y X DEY X LDA (FMSBPT),Y X STA (ICBALZ),Y X DEY X LDA (FMSBPT),Y X STA (ICBALZ),Y X DEY X BNE RDSCLP X LDA (FMSBPT),Y ;NUM OF DATA BYTES IS MULTIPLE OF 4 + 1 X STA (ICBALZ),Y X JSR BUFADJ ;ADJUST BUFFER PTR BY 125 OR 253 XRDASNT JSR RDNXTS ;READ IN THE NEXT SECTOR X BCS RETEOF ;REPORT EOF/ERROR IF NECESSARY X LDA ICBLLZ+1 X BNE RDASLP ;AND REPEAT THE LOOP IF > 256 BYTES LEFT X; XRDSGBT TAY X LDA (FMSBPT),Y ;FETCH A DATA BYTE FROM THE BUFFER X STA DATBYT ;AND RETURN IT TO CIO X INY X TYA X STA CURLEN,X ;BUMP CURRENT BUFFER LENGTH X EOR MAXLEN,X X ORA LNKSEC,X X ORA LNKSEC+1,X ;TEST FOR THE LAST BYTE OF THE FILE X BNE JDONE X LDA #3 ;IF IT IS, REPORT THIS IS THE LAST BYTE X DB $2C X; XRETEOF LDA #136 ;RETURN END OF FILE STATUS X JMP AEXIT X; X; WRITE DATA TO A FILE X; XDKWRIT STA DATBYT ;SAVE THE DATA BYTE (IF IT IS IN ACC) X LDY ICDNO,X X STY ICDNOZ ;INSURE ICDNOZ IS SET UP (BASIC DOES NOT!) X JSR SETUPW X LDA FCBOTC,X X AND #$08 X BEQ CANTWR ;ERROR OUT IF ILLEGAL TO WRITE (BASIC AGAIN!) X LDA CURLEN,X X TAY X CMP MAXLEN,X X BCC SKBURST ;SKIP AROUND IF NOT THE END OF THE SECTOR X XWRASLP JSR WRNXTS ;WRITE A SECTOR OF DATA X BCS RETEOF ;ERROR OUT IF NO MORE DISK SPACE X LDY STKPSV X LDA $0102,Y X CMP #$C0 ;IF FROM BASIC (RETURN ADDRESS < $C000) X BCC BASWRT ;PASS SINGLE BYTES X LDA FCBOTC,X ;Fix bug in open/update vs. burst I/O X AND #$04 ;[Bob Puff, again!] X BNE BASWRT X LDA ICCOMZ ;IF RECORD I/O, PASS SINGLE BYTES ALSO X AND #$02 X BEQ BASWRT X LDY ICBLLZ+1 ;AND IF THE BUFFER HOLDS FEWER THAN 256 BYTES X BEQ BASWRT ;PASS SINGLE BYTES AS WELL X LDY MAXLEN,X X DEY XWRSCLP LDA (ICBALZ),Y ;ELSE, DO SIMULATED BURST I/O X STA (FMSBPT),Y X DEY X LDA (ICBALZ),Y X STA (FMSBPT),Y ;BUT ONLY UNROLL 2 ENTRIES FOR WRITES! X DEY ;(WE GOT VERY LITTLE RAM TO WASTE!) X BNE WRSCLP X LDA (ICBALZ),Y X STA (FMSBPT),Y X JSR BUFADJ X LDA (ICBALZ),Y X STA DATBYT X JMP WRASLP X; XBASWRT LDY #0 XSKBURST LDA DATBYT X INC CURLEN,X X STA (FMSBPT),Y X LDA #$40 X ORA FCBFLG,X ;FOR UPDATE MODE, SAY THE SECTOR WAS MODIFIED X STA FCBFLG,X X BNE TODONE ;BRANCH ALWAYS! X; XCANTWR JMP ERRCMD X; XBUFADJ CLC X LDA MAXLEN,X X STA CURLEN,X X ADC ICBALZ X STA ICBALZ X BCC RBAOK X INC ICBALZ+1 XRBAOK SEC X LDA ICBLLZ X SBC MAXLEN,X X STA ICBLLZ X BCS RBLOK X DEC ICBLLZ+1 XRBLOK RTS X; X; RETURN FILE STATUS X; XDKSTAT JSR SETUP ;SET UP RETURN ADDRESS, ETC. X JSR LFFILE ;FIND IF FILE IS THERE, ETC. X JSR TSTLOK ;IS IT LOCKED? XTODONE JMP DONE ;RETURN TO CALLER X; X; CLOSE FILE (WRITING ANY PENDING SECTOR) X; XDKCLOS JSR SETUP X LDA FCBOTC,X X AND #$08 ;OUTPUT ALLOWED? X BEQ CLROTC ;IF NOT, JUST EXIT X ROL FCBFLG,X X BCC CKFLSC X JSR REWRIT ;REWRITE THE LAST SECTOR X JSR RRDIR X LDA SECCNT,X X LDY DIRDSP X STA DIRBUF+1,Y X LDA SECCNT+1,X X STA DIRBUF+2,Y X LDA DIRBUF,Y X AND #$FE ;NOT OPEN FOR OUTPUT ANY MORE X JSR SAVFLAG X LDA SAVSEC,X X ORA SAVSEC+1,X X BEQ CLROTC X CPX LSTIOCB X BEQ FAPPD X JSR INITYP ;READ ALL THE SECTORS AGAIN XAPPLP JSR RDNXTS X BCC APPLP ;NOT EOF YET X BCS TIELNK XFAPPD LDA LSTSEC X STA CURSEC,X X LDA LSTSEC+1 X STA CURSEC+1,X XTIELNK CLC X JSR RWDISK X LDA DLINK X STA CURLEN,X X LDA SAVSEC,X X LDY SAVSEC+1,X X JSR SAVLNK XCLROTE BPL CLROTC X LDA #163 ;FAILURE IS A SYSTEM ERROR X JMP AEXIT XCLROTC LDA #$FF X STA ICHID,X X LDA #0 X STA FCBOTC,X X JMP FREDON X; XCKFLSC ROL FCBFLG,X X BCC CLROTC X JSR WRDISK X JMP CLROTE X; XINITYP LDA #$06 X JSR GETFLAG X LSR A X ROR A X ROR A X ROR A X ORA FCBOTC,X X STA FCBOTC,X X LDA DIRBUF+3,Y X STA LNKSEC,X X LDA DIRBUF+4,Y X STA LNKSEC+1,X X LDA CURFNO X STA FCBFNO,X X LDA #0 X STA FCBFLG,X X STA CURLEN,X X STA SECCNT,X X STA SECCNT+1,X X RTS X; X; DOS XIO ROUTINES X; X; Sorry about the lack of comments in some parts of this file, X; I just never had to figure this code out after I wrote it (:-)! X; XNODIRF LDA #176 ;FILE NOT A DIRECTORY X JMP AEXIT X; XPIKDIR LDY #0 X LDA #':' XFDVND INY X CMP (ICBALZ),Y X BNE FDVND X INY X LDA (ICBALZ),Y X CMP #'@' X BCC SETRDIR X CMP #'Z'+1 X BCC GFNDIR X CMP #'_' X BCC SETRDIR X CMP #'z'+1 X BCS SETRDIR XGFNDIR JSR LFFILE ;FIND NEW DEFAULT DIRECTORY X JSR INITYP X JSR TONXDR X BEQ NODIRF ;IF NOT A DIRECTORY X LDA DIRBAS+1,X X TAY X LDA DIRBAS,X XSAVDEF STY CDIREC+1 ;UPDATE ADDRESS OF DIR. X STA CDIREC X LDA ICDNOZ X STA DEFAULT ;UPDATE UNIT NUMBER X BPL TOFDN X; XSETRDIR LDA #LOW[361] X LDY #HIGH[361] X BPL SAVDEF X; XRENAME JSR LFFILE ;GET OLD NAME, DRIVE, VALIDATE X LDY #11 XSTEMPL LDA FNAME-1,Y X STA MAPBUF+256,Y X DEY X BNE STEMPL XRNLOOP JSR TSTLOK ;CANNOT RENAME IF LOCKED X JSR TDDOS ;TEST FOR DOS GONE! X LDY TMP2 X JSR GETNAM ;GET NEW NAME X CLC X JSR ENTNAME ;OVERWRITE NAME IN DIR. X JSR WDIRBK ;REWRITE DIRECTORY TO DISK X; X JSR TSTDOS ;NEW NAME DOS.SYS? X BNE REPLDS ;NO, LOOK AT NEXT X X LDY DIRDSP X LDA DIRBUF+4,Y ;SAVE FILE LOCATION ON THE STACK X PHA X LDA DIRBUF+3,Y X PHA X; X;;; JSR SYSSET ;Use the MAP buffer [IS THIS NECESSARY???] X; X CLC ; == READ X LDX #1 ; == SECTOR SIZE CODE (1=128, 2=256) X LDA #0 X LDY #1 ; == SECTOR #1 X JSR DKIO ;Read it X; X LDA SECDAT X STA MAPBUF+SECDAT-$0700 X PLA X STA MAPBUF+DOSLOC-$0700 X PLA X STA MAPBUF+DOSLOC+1-$0700 X; X;;; LDA #$00 ;[AND IS THIS REALLY NECESSARY???] X;;; STA MAPBUF+STATE-$0700 X; X SEC ; == WRITE X LDX #1 ; == SECTOR SIZE CODE (1=128, 2=256) X JSR DKIO2 ;Write it (same sector as I read before) X; X LDA #$FF ;Then make sure we reread the directory buffer X STA DIUNIT X; XREPLDS LDY #11 XRTEMPL LDA MAPBUF+256,Y X STA FNAME-1,Y X DEY X BNE RTEMPL X JSR CSFDIR ;TO RENAME X BCC RNLOOP XTOFDN JMP FREDON X; XDELETE JSR LFFILE XDELLP JSR REMOVE ;FLUSH THE SECTORS X JSR RRDIR ;REREAD DIRECTORY BLOCK X JSR TDDOS ;DOS.SYS DELETED? X LDA #$80 X JSR SAVFLAG ;REWRITE DIRECTORY BLOCK X JSR CSFDIR X BCC DELLP ;IF ANOTHER FOUND, X BCS TOFDN ;ELSE, WRAP UP AND EXIT X; XREMOVE JSR TSTLOK ;ONCE HAD 'OPVTOC' CALL FIRST X JSR INITYP X JSR TONXDR X BNE DELDIR X JSR CHASE X; XFREELP JSR FREE X JSR RDNXTS X BCC FREELP X RTS X; XINVDEL LDA #175 ;DIRECTORY NOT DELETABLE X JMP AEXIT X; XLOCK LDA #$20 X DB $2C ;BIT ABS (SKIP 2 BYTES) X; XUNLOCK LDA #$00 X STA DATBYT X JSR LFFILE ;FIND FILE AND VERIFY WRITABLE XLKULKL LDA #$DF ;STRIP OFF OLD BIT 5 X JSR GETFLAG X ORA DATBYT ;AND REPLACE WITH NEW X JSR SAVFLAG X JSR CSFDIR X BCC LKULKL X BCS TOFDN X; XDELDIR LDY #-11 X LDA #'?' XDELSET STA FNAME+11-256,Y X INY X BNE DELSET X JSR SFDIR X BCC INVDEL X; X LDA #8 X STA DATBYT X JSR TONXT XDELDRL JSR FREE X JSR INCCSEC X DEC DATBYT X BNE DELDRL X JMP GETFNM X; XPOINT LDY FCBFLG,X X BMI ERRCMD X; X LDA ICSPR+1,X X CMP CURSEC+1,X X BNE PNTREAD X LDA ICSPR,X X CMP CURSEC,X X BEQ PNTSME XPNTREAD TYA X BEQ PNTCLN ;IF SECTOR UNMODIFIED X JSR WRDISK X LDA #0 X STA FCBFLG,X XPNTCLN LDA ICSPR+1,X X STA LNKSEC+1,X X LDA ICSPR,X X STA LNKSEC,X X JSR CHASE ;READ SECTOR POINTED TO X BCS BADPNT X; XPNTSME LDA ICSPR+2,X X CMP MAXLEN,X X BCS PNTEQL XPNTLST STA CURLEN,X X JMP DONE X; XPNTEQL BEQ PNTLST ;IF POINTING AT LAST BYTE XBADPNT LDA #166 ;INVALID POINT LOCATION X DB $AE X; XERRCMD LDA #168 ;INVALID IOCB PARAMETER X JMP AEXIT X; XNOTE LDA CURSEC,X X STA ICSPR,X X LDA CURSEC+1,X X STA ICSPR+1,X X LDA CURLEN,X X STA ICSPR+2,X X JMP DONE X; XDKXIO JSR SETUP X LDA ICCOMZ ;GET COMMAND BYTE X CMP #254 X BEQ FORMAT X CMP #43 ;ADD "MKDIR" CODE FOR SpartaDOS(?) [Bob Puff] X BCS ERRCMD ;IF INVALID COMMAND X SBC #32-1 X BCC ERRCMD X TAY X LDA VECTBH,Y X PHA X LDA VECTBL,Y X PHA X RTS ;VECTOR TO PROPER ROUTINE X; XVECTBH DB HIGH[RENAME-1],HIGH[DELETE-1] X DB HIGH[MKDIR-1],HIGH[LOCK-1] X DB HIGH[UNLOCK-1],HIGH[POINT-1] X DB HIGH[NOTE-1],HIGH[DKLOAD-1] X DB HIGH[ERRCMD-1],HIGH[PIKDIR-1] X DB HIGH[MKDIR-1] ;extra vector to MKDIR [Bob Puff] X; XVECTBL DB LOW[RENAME-1],LOW[DELETE-1] X DB LOW[MKDIR-1],LOW[LOCK-1] X DB LOW[UNLOCK-1],LOW[POINT-1] X DB LOW[NOTE-1],LOW[DKLOAD-1] X DB LOW[ERRCMD-1],LOW[PIKDIR-1] X DB LOW[MKDIR-1] X; X; DOS FORMAT ROUTINES X; XFORMAT JSR WBITMP ;WRITE OUT ANY PENDING VTOC SECTORS X; X ldy #9 ;Force format to match current density XWOTCP2 lda WOTDCB,y ;set up DCB for specified density [Bob Puff] X sta DDEVIC+2,y X dey X bpl WOTCP2 X ldx ICDNOZ X cpx RAMDKU X beq WOTRAM ;don't do it for RAMdisks X; X ldy SECSIZ-1,x X lda DRVDEF-1,x X jsr SETDRV ;set density XWOTRAM ldx CURFCB ;restore X reg X; X LDY #0 X TYA ;THEN INITIALIZE NEW BIT MAP (VTOC) XCLRMAP STA MAPBUF,Y X STA MAPBUF+256,Y X INY X BNE CLRMAP X; X LDA #2 X STA MAPBUF ;start out as a DOS 2.0 disk X LDA #$FF X STA (FMSBPT),Y X INY X STA (FMSBPT),Y ;PRESUME NO BAD SECTORS IF BUFFER IS UNMODIFIED X LDY ICDNOZ X CPY RAMDKU X BEQ RAMFMT ;IF RAMDISK, SKIP EVERYTHING X LDA FMSBPT+1 X LDY FMSBPT X JSR BUFSET ;SET UP BUFFER POINTER FOR SIO CALL X LDX #1 X STX TMP1 ;ALLOW ONE TRY ONLY X LDA #$22 ;PRESUME 1050 D/D FORMAT NEEDED X LDY ICAX2Z ;GET AUX2 BYTE X BMI FMTOK ;MINUS --> NO FORMAT REQUIRED X BNE NMLFMT ;AUX2 NONZERO, NORMAL FORMAT WITH SIZE DEFINED X LDY ICAX1Z ;(AUX2,AUX1) = 1? X DEY X BEQ FT1050 ;YES, FORMAT WITH A $22 COMMAND X; XNMLFMT ldx DUNIT X lda SECSIZ-1,X ;PUT SECTOR SIZE CODE (1 OR 2) INTO X X tax X lda #FMTCMD ;AUX IS 0, must not be 1050 d/d XFT1050 STA DAUX1 ;MAKE SURE WE SECTOR > 3 X LDY DSKTIM ;DISK TIMEOUT VALUE (RETURNED IN STATUS) X JSR DKFME ;ENTER DKIO AT FORMAT ENTRY X BPL FMTOK ;Accepting 144 errors here removed [Bob Puff] X JMP AEXIT ;RETURN ERROR CODE IF ANY OCCURRED X; XRAMFMT STA CURSEC,X ;STUFF PROPER NUMBER OF SECTORS INTO CURSEC X CLC ;(256-BYTE PAGES * 2 SINCE SECTOR SIZE IS 128) X ADC RDKLMT X LSR A X ROR CURSEC,X X BNE NOTDEF ;FAIL IF NOT 256 SECTORS OR MORE (need 370) X; X; SUCCESSFUL FORMAT, CREATE VTOC AND EMPTY DIRECTORY X; XFMTOK ;Bob Puff disabled the marginal format code X; ldy #0 ;check for a bad format X; lda (FMSBPT),y X; and (FMSBPT),y ;first two bytes $FF? X; cmp #$FF X; beq FMTOK2 ;yep, continue X; lda #173 ;otherwise format error X; bne FMEXIT X; XFMTOK2 X JSR INVUNIT ;Can we do this (asks Bob Puff) X JSR DELDOS X LDA ICAX1Z X STA CURSEC,X X LDA ICAX2Z X AND #$7F ;DISK MUST HAVE 256 SECTORS X BNE NOTDEF ;IF SIZE SPECIFIED, USE IT X LDY ICDNOZ X LDA HDTAB-1,Y ;IF NOT AND THIS IS A HARD DISK X STA CURSEC,X ;USE THE SYSTEM DEFINED SIZE X LDA HDTAB+8-1,Y X BNE NOTDEF X BIT DVSTAT ;1050 DRIVE? X BPL FIGSIZ ;NO, FIGURE SIZE THEN X LDA #LOW[1040] ;YES, FORCE TO 1040 SECTORS X STA CURSEC,X X LDA #HIGH[1040] X BNE NOTDEF X; XFIGSIZ LDA DRVDEF-1,Y X AND #$31 ;EXTRACT TRACK COUNT FLAGS X LSR A X PHP X LSR A X LSR A X TAY X LDA NOSECS,Y ;AND USE DRIVE DEFAULT SECTOR COUNT X STA CURSEC,X X LDA NOSECS+1,Y X PLP X BCC NOTDEF ;IF NOT DOUBLE SIDED, THIS IS IT X ASL CURSEC,X X ROL A ;ELSE, DOUBLE IT X; XNOTDEF STA CURSEC+1,X X CMP #4 ;NEED 16 BIT LINKS? X BCC SHORTS ;NO, SHORT FORMAT OK X INC MAPBUF ;YES, FORCE LONG FORMAT (DOS3) XSHORTS JSR FNDBIT ;FIND LAST BIT MAP SECTOR X LDA TMP2 X BNE GT246 ;IF PAST 256TH MAP BYTE X BIT DLINK ;SINGLE DENSITY? X BMI FDBDEN X CPY #0 X BPL FDBDEN XGT246 STA MAP2 X CLC X ADC #3 X STA MAPBUF XFDBDEN LDA #HIGH[-9] X STA MAPBUF+4 X LDA #LOW[-9] X STA MAPBUF+3 ;START WITH 9 FREE SECTORS UN-FREE! XFLOOP JSR FMTFRE X JSR DECCSEC X CMP #4 ;BOOT SECTORS YET? X BNE FLOOP ;IF NOT, CONTINUE DEALLOCATING X LDA CURSEC+1,X X BNE FLOOP X; X; ALLOCATE BAD SECTORS X; [Bob Puff replaced this with code to set FMSBPT to 1, since he X; disallows bad sectors] X; X LDY #0 XCLRBDLP LDA (FMSBPT),Y X STA CURSEC,X X INY X LDA (FMSBPT),Y X STA CURSEC+1,X X INY X AND CURSEC,X X CMP #$FF X CLC X BEQ MAPDONE X STY TMP1 X JSR DECCNT X JSR FNDLBIT X EOR #$FF X BCC CLRBD1 X AND MAPBUF+256,Y X STA MAPBUF+256,Y X BCS CLRBD2 XCLRBD1 AND MAPBUF,Y X STA MAPBUF,Y XCLRBD2 LDY TMP1 X BNE CLRBDLP X SEC X LDY #173*2-256 ;NO $FFFF => BAD FORMAT XMAPDONE TYA X ROR A X STA FMSBPT ;POSITIVE VALUE = NUMBER OF BAD SECTORS X; X; [End of code that can be optionally deleted] X; X LDA #$00 X STA MAPBUF+55 X LDA #$7F X STA MAPBUF+56 X LDY #44 ;START ALLOC. OF VTOC HERE X LDA MAPBUF X SEC X SBC #2 ;GET NUMBER OF SECTORS X BIT DLINK ;(SINGLE DENSITY?) X BMI MPNSD ;IF NOT, M-3 X ASL A ;IF SO, M*2-5 XMPNSD TAX X DEX ;MOVE COUNT TO X X; XALCMPL LDA #$FF XALCMAP DEX X BMI SMBSIZ X PHA X JSR DECCNT X PLA X ASL A X BNE ALCMAP X STA MAPBUF+10,Y X DEY X BPL ALCMPL ;BRANCH ALWAYS! X; XSMBSIZ STA MAPBUF+10,Y X LDA MAPBUF+3 ;MARK EMPTY SIZE, TOO X STA MAPBUF+1 X LDA MAPBUF+4 X STA MAPBUF+2 X JSR FMTMAP ;WRITE MAP TO DISK X; X; CREATE AN EMPTY DIRECTORY X; X LDA #LOW[361] X LDY #HIGH[361] XCLRDIR JSR SETDIR ;RESET THE DIRECTORY BASE SECTOR X TYA XCLRDLP STA DIRBUF,Y ;ZERO THE DIRECTORY BUFFER X INY X BNE CLRDLP X; X LDA #7 X STA DIRSEC XCLRDL2 JSR WDIRBK ;THEN WRITE ALL 8 SECTORS OUT X DEC DIRSEC X BPL CLRDL2 X LDY BUFNO,X X LDA #0 X STA BUFNO,X X STA BUFFLG-1,Y ;FORMAT DONE, FREE THE INTERNAL BUFFER X LDA FMSBPT X JMP AEXIT X; XNOSECS DW 35*18,40*18,80*18,77*26 X; XSETDIR STA DIRBAS,X X TYA X STA DIRBAS+1,X X LDY #0 X RTS X; X; DOS BINARY LOAD CODE (LOAD AND OPTIONALLY EXECUTE A PROGRAM) X; XDKLOAD LDA ICAX1Z X STA ICPTLZ ;SAVE PROGRAM NAME BUFFER POINTER X CMP #$08 X BCS TOERRC ;IF WRITE, REPORT ERROR X; X LDA #LOW[TORTS] X STA RUNADR X LDA #HIGH[TORTS] ;ASSUME RUNN ADDRESS IS ABSENT X STA RUNADR+1 X LDA #4 X STA ICAX1Z X LDA ICHID,X ;IOCB OPEN? X BPL CCFILE X JSR DKOPEN ;IF NOT, OPEN IT X BMI DKLERV X JSR WDREAD ;READ ONE WORD OF THE HEADER X BEQ CCFILE X LDY #180 ;NO $FFFF, HEADER ERROR CODE X BMI DKLERV X; XTOERRC LDY #168 ;INVALID IOCB X RTS X; XGETTXT LDA #LOW[TORTS] X STA INIADR X LDA #HIGH[TORTS] ;FOR EACH SEGMENT, RECLEAR THE INIT VECTOR X STA INIADR+1 XTXTLP JSR DKREAD XDKLERV BMI DKLERR X LDY #0 X STA (ICBALZ),Y X INC ICBALZ X BNE DECLEN X INC ICBAHZ XDECLEN LDA ICBLLZ X BNE DECLOW X DEC ICBLHZ XDECLOW DEC ICBLLZ X BNE TXTLP X LDA ICBLHZ X BNE TXTLP X LDA ICBAHZ X CMP #HIGH[INIADR] X BNE CCFILE X; X LDA ICPTLZ ;IF NO INITS, X LSR A X BCS CCFILE ;SKIP TO NEXT PAGE X TXA ;ELSE SAVE IOCB X PHA X LDY #256-12 XCPSICB LDA ICHIDZ-256+12,Y X STA ICHID,X ;SAVE THE 12-BYTE IOCB ENTRY X INX X INY X BNE CPSICB X PLA X TAX X PHA X JSR DOINIT ;AND CALL INIT FUNCTION X PLA X TAX X PHA X LDY #256-12 XCPRICB LDA ICHID,X ;THEN RESTORE THE 12-BYTE IOCB X STA ICHIDZ-256+12,Y X INX X INY X BNE CPRICB X PLA X TAX X; XCCFILE JSR WDREAD ;READ THE SEGMENT START ADDRESS X BEQ CCFILE X STA ICBALZ X STY ICBAHZ X JSR WDREAD ;READ THE SEGMENT END ADDRESS X SEC X ADC #0 X BCC CCSUBT X INY XCCSUBT SEC X SBC ICBALZ ;CALCULATE THE LENGTH TO LOAD INTO RAM X STA ICBLLZ X TYA X SBC ICBAHZ X STA ICBLHZ X BCS GETTXT ;BRANCH IF VALID LENGTH (GET DATA BYTES) X LDY #181 ;ELSE, MEMORY WRAP ERROR X BMI DKLERR X; XWDXIT PLA X PLA XDKLERR TYA X PHA X JSR DKCLOS ;CLOSE THE PROGRAM FILE X PLA X TAY ;AND RETURN ANY ERROR CODE X RTS X; X; READ A WORD FROM THE PROGRAM FILE AND COMPARE IT WITH $FFFF X; XWDREAD LDA #0 X STA ICBLLZ X STA ICBLHZ ;SET LENGTH TO ZERO X JSR DKREAD ;READ A BYTE X BMI WDEOF X PHA X JSR DKREAD ;READ THE SECOND BYTE X BMI WDEOF1 X TAY X PLA X CPY #$FF ;UPPER BYTE $FF? X BNE TORTS ;NO, THEN WORD IS NOT $FFFF X CMP #$FF ;YES, IS LOWER BYTE $FF? XTORTS RTS ;IF BOTH $FF, RETURN ZERO FLAG X; XWDEOF1 PLA XWDEOF CPY #136 ;IS THIS END OF FILE? X BNE WDXIT ;IF NOT, RETURN ERROR CODE X PLA X PLA ;ELSE, GET RID OF RETURN ADDR X LDA ICPTLZ X LSR A X LSR A X PHP X JSR DKCLOS ;CLOSE FILE AND SET Y=1 X PLP X BCS TORTS ;EXIT IF NO-RUN SPECIFIED X JMP (RUNADR) ;THEN GO TO RUN ADDRESS X; X; INVOKE INIT FOR EVERY BLOCK OF INPUT CODE (USUALLY JUST AN RTS) X; XDOINIT JMP (INIADR) ;CALL INDIRECT X; X; XIO FUNCTION TO CREATE A NEW DIRECTORY X; X; PARSE DIRECTORY NAME X; XMKDIR JSR GETFNM X JSR SFDIR ;FIND FILE IN DIRECTORY X BCS MKDMRD X LDA #172 ;FILE ALREADY EXISTS X DB $AE ;SKIP 2 BYTES XDISFUL LDA #169 ;DIRECTORY FULL X JMP AEXIT X; X; READ IN BIT MAP X; XMKDMRD LDA HOLFN X BMI DISFUL X JSR RBITMP X LDY MAPBUF X DEY X DEY X STY DATBYT X; X; FIND EIGHT SECTORS FOR DIRECTORY X; X LDA #LOW[369] ;FIRST AVAILABLE SECTOR AFTER ROOT DIR. X STA CURSEC,X X LDA #HIGH[369] X STA CURSEC+1,X X LDA #0 X STA TMP1 XFDIRLP INC TMP1 X JSR FNDLBIT ;IS THIS SECTOR FREE? X BCS FDIR2 X AND MAPBUF,Y X BCC FDIR1 XFDIR2 AND MAPBUF+256,Y XFDIR1 BNE FDIR3 X STA TMP1 XFDIR3 JSR INCCSEC X LDA TMP1 X CMP #8 X BNE FDIRLP X; X; ALLOCATE THE SECTORS USED X; XALCDLP JSR DECCSEC X JSR FNDLBIT X EOR #$FF X BCS ALCPG2 X AND MAPBUF,Y X STA MAPBUF,Y X BCC ALCPG1 XALCPG2 AND MAPBUF+256,Y X STA MAPBUF+256,Y X LSR MAP2MOD XALCPG1 JSR DECCNT X DEC TMP1 X BNE ALCDLP X; X; WRITE ALLOCATION MAP BACK TO DISK X; X JSR FMTMAP X; X; ENTER NAME AND TYPE INFO INTO PARENT DIRECTORY X; X LDA HOLFN X JSR SDIRBK X SEC X JSR ENTNAME X LDA CURSEC+1,X X STA DIRBUF+4,Y X LDA CURSEC,X X STA DIRBUF+3,Y X LDA #0 X STA DIRBUF+2,Y X LDA #8 X STA DIRBUF+1,Y X ASL A X JSR SAVFLAG X; X; THEN CLEAR NEW DIRECTORY X; X LDA #1 X STA FMSBPT X LDA CURSEC,X X LDY CURSEC+1,X X JMP CLRDIR SHAR_EOF sed 's/^X//' << \SHAR_EOF > mdos3.asm X; X; DOS DIRECTORY ROUTINES X; X; OPEN A DIRECTORY (FOR USER) X; XLSTDIR LDY #$80-11 XSAVFNB LDA FNAME-$80+11,Y X STA (FMSBPT),Y X INY X BPL SAVFNB X JSR SFDIR ;FIND A MATCH IN THE DIRECTORY X BCS ENDDIR ;IF NO MORE MATCHES, REPORT FREE SPACE XNXTDIR JSR FMTDIR ;ENTRY FOUND, FORMAT INTO A TEXT STRING X LDA CURFNO X STA FCBFNO,X ;SAVE THE FILE NUMBER OF THE ENTRY FOUND XGODONE JMP DONE ;AND RETURN X; XGOTEOD DEC DATBYT ;CONVERT EOL TO $9B (REAL EOL) X STA CURLEN,X ;AND FINISH UP X BNE GODONE X; XDIRRD LDY #$80-11 XRSTFNB LDA (FMSBPT),Y ;FETCH BYTES OF PREVIOUSLY PARSED DIRECTORY ENT X STA FNAME-$80+11,Y X INY X BPL RSTFNB X LDA CURLEN,X X BMI DIREOF ;EOF IF WE ALREADY REPORTED FREE SPACE X TAY X LDA (FMSBPT),Y X STA DATBYT X INC CURLEN,X X CMP #$9C X BEQ GOTEOD X CMP #$9B ;IS THIS END OF LINE? X BNE GODONE ;IF NOT, CONTINUE FETCHING OLD BYTES X LDA FCBFNO,X X CMP CURFNO X BNE DMSTRD X CPX DIUNIT X BEQ DRDNRQ XDMSTRD JSR RRDIR ;IF SO, INSURE DIRECTORY BLOCK IS IN MEMORY XDRDNRQ JSR CSFDIR ;AND FIND THE NEXT ENTRY X BCC NXTDIR ;IF FOUND, LOOP BACK AND FORMAT IT X; X; NO MORE ENTRIES, REPORT FREE SECTORS LAST X; XENDDIR JSR RBITMP ;READ THE VTOC DATA X LDY #0 X STY CURMAP ;FORCE A REREAD NEXT TIME X LDA MAPBUF+3 X LDX MAPBUF+4 ;AND STUFF THE BUFFER WITH NO. OF FREE SECTORS X JSR CVTDEC X LDX #-14 XFSECL LDA FSECM+14-256,X ;FOLLOWED BY THE "FREE SECTORS" TEXT X STA (FMSBPT),Y X INY X INX X BNE FSECL X BEQ GODONE X; XDIREOF JMP RETEOF ;NO MORE LINES, RETURN EOF INDICATION X; XFSECM DB ' FREE SECTORS',$9C X; X; FORMAT A DIRECTORY ENTRY FOR BASIC, ETC. X; XFMTDIR LDY #' ' X LDX DIRDSP X LDA DIRBUF,X X PHA X AND #$20 X BEQ D0E35 X LDY #'*' ;IF SO, MARK AS LOCKED XD0E35 TYA X LDY #0 X STA (FMSBPT),Y X PLA X LDY #' ' X AND #$10 X BEQ NOTDIR X LDY #':' XNOTDIR TYA X LDY #1 X STA (FMSBPT),Y XCPYNAML INY X LDA DIRBUF+5,X X STA (FMSBPT),Y X INX X CPY #13 X BCC CPYNAML X; X LDA #' ' X STA (FMSBPT),Y X LDY DIRDSP X LDA DIRBUF+1,Y X LDX DIRBUF+2,Y X LDY #14 ;SECTOR COUNT STARTS HERE X; X; CONVERT A 16-BIT INTEGER TO A 4 OR 5 DIGIT NUMBER X; XCVTDEC STX TMP2 X STA TMP1 X LDX #HIGH[10000] X LDA #LOW[10000] X JSR MKDGT2 X CMP #'0' X BNE SKIP5 X DEY XSKIP5 LDX #HIGH[1000] X LDA #LOW[1000] X JSR MKDGT2 X LDA #100 ;FOR THE SHORT STUFF X JSR MAKDGT X LDA #10 X JSR MAKDGT X TXA X ADC #'0'+10 X STA (FMSBPT),Y X INY X LDA #$9B ;TERMINATE LINE X STA DATBYT X STA (FMSBPT),Y X LDA #0 X LDX CURFCB X STA CURLEN,X X RTS X; X; CREATE A DIGIT AND STORE IT INTO THE DIRECTORY BUFFER X; XMAKDGT LDX #0 ;IF SUBTRAHEND < 256, ZERO UPPER BYTE XMKDGT2 STX DIRDSP X STA DIRSEC X STY DATBYT X LDY #'0' X SEC XDGTLP2 LDA TMP1 X SBC DIRSEC X TAX X LDA TMP2 X SBC DIRDSP X BCC DGTXIT X STA TMP2 X STX TMP1 X INY X BCS DGTLP2 X; XDGTXIT TYA X LDY DATBYT X STA (FMSBPT),Y X INY X RTS X; X; PARSE A FILE NAME WITH WILD CARD CHARACTERS ('*' AND '?') X; XGETNM2 iny ;look for ">" in X lda (ICBALZ),y ;the start of X cmp #'>' ;the filename X beq GETNAM ;(for SpartaDOS compatibility) X dey ;[Bob Puff] X bne GETNAM ;branch always X; XGETFNM LDX CURFCB X LDY #HIGH[361] X LDA #LOW[361] X JSR SETDIR X INY X LDA (ICBALZ),Y X INY X CMP #':' ;DEFAULT DIRECTORY? X BNE GETNM2 ;IF NOT, CHECK FOR SPARTA ">" X DEY X STY TMP1 X LDY DEFAULT X STY ICDNOZ X TYA X STA ICDNO,X X JSR SETUPD X LDA CDIREC X LDY CDIREC+1 X JSR SETDIR X LDY TMP1 X; XGETNAM LDX #-11 X INY XAFTSTR LDA (ICBALZ),Y X CMP #'*' X BNE TSTPER X LDA #'?' X INY XQLOOP STA FNAME+11-256,X X INX X BPL TOXITC ;END OF EXTENSION? XPERFND CPX #-3 ;END OF FILE NAME? X BNE QLOOP ;NO MORE -?-S X BEQ AFTSTR X; XTSTPER CMP #'.' ;A PERIOD? X BNE TSTCHR ;IF NOT, CHECK FOR INDIVIDUAL CHARACTERS X LDA #' ' ;IF SO, FILL WITH SPACES X INY X BNE PERFND X; XTSTCHR CMP #'?' X BCC ENDCHR ;IF < '?', CHECK FOR DIGIT X CMP #'Z'+1 ;ELSE, UPPER CASE LETTER, '?', OR '@'? X BCC GOTCHR X CMP #'_' X BCC ENDCHR ;IF CARET, BACKSL. OR BRACKETS X CMP #'z'+1 ;LOWER CASE, ACCENT OR UNDERSCORE? X BCC GOTCHR XENDCHR CPX #-11 ;IF FIRST CHAR, ERROR X BEQ ERRCHR ;NO BYTES IN FILE NAME X CMP #'0' ;ELSE, A DIGIT? X BCC FILLNM ;IF NOT, THIS IS END OF NAME X CMP #':' X BCS FILLNM X; XGOTCHR STA FNAME+11-256,X X INY X INX X BMI AFTSTR X; XTOXITC LDA (ICBALZ),Y XTSTDIR CMP #':' ;LOOK FOR SUBDIRECTORY X BEQ MYDIR ;IF MYDOS SYNTAX X CMP #'>' ;OR SPARTA SYNTAX X BNE XITCHR ;IF FINISHED, RESTORE FCB PTR TO X AND EXIT XMYDIR STY TMP2 X JSR SFDIR ;ELSE, FIND FILE X BCS FNER1 ;NO SUCH FILE X JSR TONXDR X BEQ FNER1 X LDY TMP2 X BNE GETNAM XFNER1 LDA #174 ;IF NOT, RETURN ERROR 174 X DB $2C ;BIT ABS (SKIP 2 BYTES) X; XERRCHR LDA #165 X JMP AEXIT X; XFILLNM PHA X LDA #' ' XFILLLP STA FNAME+11-256,X X INX X BMI FILLLP X PLA X JMP TSTDIR X; X; RETURN WITH NON-ZERO FLAG IF FILE IS A DIRECTORY X; XTONXDR LDA #$10 ;FILE FOUND, A DIRECTORY? X JSR GETFLAG X BEQ TONXIT ;IF NOT, SET ZERO FLAG X LDA DIRBUF+3,Y ;IF SO, MOVE POINTERS TO THE NEW LEVEL X STA DIRBAS,X X LDA DIRBUF+4,Y X STA DIRBAS+1,X X LDA #$10 ;AND CLEAR THE ZERO FLAG XTONXIT RTS X; X; ENTER A NAME INTO THE DIRECTORY AT DIRBUF[DIRDSP] X; XENTNAME PHP X LDX #-11 X LDY DIRDSP XNAMELP LDA FNAME+11-256,X ;LOAD THE MASK CHARACTER X CMP #'?' X BNE STORIT ;IF NOT '?', SAVE IT AS IT APPEARS X PLP X PHP X BCC NOSTOR ;IF CY CLEAR, LEAVE THE CHARACTERS UNCHANGED X LDA #' ' ;IF CY SET, CONVERT '?'S TO SPACES XSTORIT STA DIRBUF+5,Y XNOSTOR INY X INX X BMI NAMELP X PLP X LDY DIRDSP XXITCHR LDX CURFCB X RTS X; XSFDIR JSR WBITMP ;INSURE BIT MAP IS SAFE X LDX #255 X STX HOLFN X STX CURFNO X INX X STX DAUX2 X INX X STX DAUX1 X LDX #READ X STX DCOMND X JSR SYSSET ;SET UP POINTERS FOR SYSTEM BUFFER I/O X; X LDA ICDNOZ X CMP RAMDKU X BEQ CSFDIR ;IF RAMDISK, FORGET DENSITY CHECK X ldx CURFCB ;IF A ROOT DIRECTORY ACCESS, READ BOOT SECTOR X lda DIRBAS,X ;IF IN A SUBDIRECTORY, ASSUME DENSITY IS OK X cmp #LOW[361] ;[Bob Puff] X bne CSFDIR X;;; lda DIRBAS+1,X ;Only occasionally will we get an extra read! X;;; cmp #HIGH[361] X;;; bne CSFDIR X; X JSR DSKINV ;ELSE, READ THE FIRST BOOT SECTOR X BMI ERRX X JSR INVUNIT ;UPDATE DRIVE CONFIGURATION X; XCSFDIR INC CURFNO ;READ NEXT 16-BYTE DIR. BLOCK X LDA CURFNO X JSR BSECDS ;CONVERT TO SECTOR AND DISPLACEMENT XXITCH1 BCS XITCHR X BNE NOREAD ;IF DISP>0, PROCESS BLOCK X JSR RDIRBK ;IF DISP=0, READ SECTOR X; XNOREAD LDY DIRDSP X LDA DIRBUF,Y X BEQ FNDOLD ;ZERO IS END OF DIRECTORY (NO MORE ENTRIES) X BMI FNDOLD ;NEGATIVE IS EMPTY SLOT (MAY HAVE MORE ENTRIES) X; X; HANDLE DOS 2.5 FILES X; X and #$DF ;preserve lock flag X cmp #3 ;is this DOS 2.5 + file? X bne NOD25 ;nope X lda #$41 ;otherwise, kludge the X eor DIRBUF,Y ;flag to make $42 X sta DIRBUF,Y ;and save lock. X; XNOD25 AND #$01 ;IGNORE ANY FILE THAT IS MARKED "OPEN" X BNE CSFDIR X LDX #-11 XCPNXCH LDA FNAME+11-256,X X CMP #'?' X BEQ WCMTCH ;EVERYTHING MATCHES "?" X CMP DIRBUF+5,Y X BNE CSFDIR ;NO MATCH, LOOK AT THE NEXT DIRECTORY ENT XWCMTCH INY X INX X BMI CPNXCH X CLC X BCC XITCHR ;ENTRY FOUND, RETURN WITH CY=0 X; XFNDOLD LDX HOLFN X BPL KPOLD ;IF AN EMPTY SLOT IS ALREADY FOUND, DO NOTHING X LDX CURFNO X STX HOLFN ;ELSE SAVE THIS ONE, ITS THE FIRST! XKPOLD TAX X BMI CSFDIR ;IF NOT END OF THE DIRECTORY, KEEP LOOKING XERRX SEC X BCS XITCH1 ;ELSE, ENTRY NOT FOUND, RETURN WITH CY=1 X; X; DOS I/O ROUTINES X; X; DISK SECTOR I/O ROUTINES X; XWRDISK SEC ;FMS DISK WRITE ENTRY XRWDISK LDY FMSBPT ;DATA SECTOR READ/WRITE ENTRY X LDA FMSBPT+1 X JSR BUFSET X LDA CURSEC+1,X X LDY CURSEC,X XFMDKIO PHP X LDX DUNIT X CPX RAMDKU X BEQ RDKIO1 X PLP X pha ;ALLOW FOR DENSITY CHANGE IN FORMAT, ETC. X lda SECSIZ-1,X ;[Bob Puff] X tax X pla X JMP DKIO X; XRDKIO1 JMP RDKIO ;ABSOLUTE DISK I/O ROUTINE WAS MOVED TO LOW RAM X; XEXTEND JSR ALLOC X LDA FCBOTC,X X LSR A X BCC REWRIT X DEC FCBOTC,X X JSR WTRICK X JMP WRTTST X; XREWRIT LDY LNKSEC+1,X X LDA LNKSEC,X X JSR SAVLNK XWRTTST BMI RTBADF X INC SECCNT,X X BNE TONXT X INC SECCNT+1,X X; XTONXT LDA LNKSEC,X ;MAKE NEXT SECTOR X STA CURSEC,X ;NEW CURRENT SEC. X LDA LNKSEC+1,X X STA CURSEC+1,X X LDA #0 X STA LNKSEC,X ;ZERO LINK X STA LNKSEC+1,X XLENSET STA CURLEN,X ;ZERO CURRENT OFFSET X LDA DLINK ;GET THE LINK LOC. X STA MAXLEN,X ;MAKE IT MAX. LEN. X CLC ;CLEAR CY FOR LATER READ X RTS X; XRDNXTS LDA FCBFLG,X X BEQ CHASE X; XWRNXTS LDA FCBFLG,X X BMI EXTEND X ASL A X BPL RDNXTS X ASL A X STA FCBFLG,X X JSR WRDISK X BPL RDNXTS X; XRTBADF JMP HWERR ;RETURN HARDWARE ERROR CODE IF PRESENT X; XSAVLNK PHA X TYA X LDY DLINK X STA (FMSBPT),Y X PLA X INY X STA (FMSBPT),Y X INY X LDA CURLEN,X XNOBIT STA (FMSBPT),Y X LDY FCBOTC,X X BMI LEN16 ;16-BIT LENGTH? X LDA FCBFNO,X X ASL A X ASL A X LDY DLINK X ORA (FMSBPT),Y X STA (FMSBPT),Y XLEN16 JMP WRDISK X; XWTRICK LDA LNKSEC,X X STA SAVSEC,X X LDA LNKSEC+1,X X STA SAVSEC+1,X X STX LSTIOCB X LDA CURSEC,X X STA LSTSEC X LDA CURSEC+1,X X STA LSTSEC+1 X JMP WRDISK X; XINSTRT JSR INITYP X; XCHASE LDA LNKSEC,X X ORA LNKSEC+1,X X BEQ NOLINK X JSR TONXT ;SET CY=0, FUNC=READ X JSR RWDISK X BMI RTBADF ;CANNOT READ SO BAD FILE NUMBER(ERR=164) X LDY DLINK X LDA FCBOTC,X ;16-BIT LINK? X ORA #$7F X BMI LNGLNK X LDA (FMSBPT),Y X LSR A X LSR A X CMP FCBFNO,X X BNE XLINKED X LDA #$03 XLNGLNK AND (FMSBPT),Y X STA LNKSEC+1,X X INY X LDA (FMSBPT),Y X STA LNKSEC,X X INY X LDA (FMSBPT),Y X STA MAXLEN,X XDRDXIT CLC X RTS X; XXLINKED LDA ICCOM,X X CMP #FMTCMD ;IS THIS A FORMAT? X BNE FNOERR XNOLINK SEC X RTS X; X; READ OR WRITE A DIRECTORY BLOCK X; XRRDIR LDA FCBFNO,X X; XSDIRBK STA CURFNO XRDCFNO LDA CURFNO X JSR BSECDS X; XRDIRBK JSR WBITMP ;TAKE CONTROL OF SYSTEM BUFFER X CLC X DB $A9 ;LDA # (SKIPS 1 BYTE) XWDIRBK SEC XRWDBK PHP X LDX CURFCB ;PUT FCB NO. IN X X STX DIUNIT ;SAVE THE DIR. BUFFER IOCB X JSR SYSSET X CLC X LDA DIRSEC X ADC DIRBAS,X X TAY X LDA DIRBAS+1,X X ADC #0 ;MULTIPLE DIRS. REQ. THIS [ChasM] X PLP XSYSRW JSR FMDKIO X BPL DRDXIT X LDA #163 ;BIT MAP R/W ERROR, RETURN SYSTEM ERR. CODE X DB $AE ;SKIP 2 BYTES X; XFNOERR lda #164 X sta DSTATS X jmp HWERR ;FILE NUMBER MISMATCH X; X; READ OR WRITE THE DISK VTOC (BIT MAP) X; XRBITMP LDA CURMAP X CMP ICDNOZ X BEQ MAPXIT ;SKIP READ IF WHAT WE WANT IS ALREADY THERE X JSR WBITMP ;ELSE, REAL I/O, SAVE CURRENT BUFFER CONTENTS X; X LDA #0 X TAY XZMAP STA MAPBUF,Y ;ZERO ENTIRE 512 X STA MAPBUF+256,Y ;BYTES OF MAP BUF. X DEY X BNE ZMAP X CLC X JSR RWBMAP ;THEN READ 128 OR 256 BYTES OF VTOC DATA X; X LDY #$FF X STY DIUNIT ;INDICATE MAP (NOT DIR) IS LOADED X STY MAP2 ;INDICATE SECOND PAGE OF MAP IS UNLOADED X INY X STY CHGMAP ;INDICATE MAP IS UNCHANGED X INY X STY MAP2MOD X STY CURMP X; XMAPCLR STA CURMAP ;AND SAVE DRIVE NUMBER MAP APPLIES TO XMAPXIT RTS X; XWBITMP LDA CHGMAP X BEQ MAPCLR ;IF MAP NOT CHANGED, SKIP WRITING IT X STA DUNIT XFMTMAP LDA #0 X STA CHGMAP ;ELSE MARK IT UNUSED X STA CURMAP X lda DUNIT ;save drive # [Bob Puff] X pha X SEC X JSR RWBMAP X pla ;then restore it [Bob Puff] X sta DUNIT X; XWRNXTM LDA MAP2MOD X BNE NOMPI2 ;IF THE PAGE BUFFER IS CLEAN, JUST EXIT X LDA #$FF ;ELSE, WRITE IT TO DISK X PHA X LDA MAP2 X INC MAP2MOD X SEC X BCS MUSTWM X; XRDNXTM CMP MAP2 ;READ A PAGE INTO THE SECOND PAGE BUFFER X BEQ NOMAPI ;IF IT IS ALREADY THERE, JUST EXIT X PHA X JSR WRNXTM ;ELSE, WRITE THE CURRENT PAGE (IF NECESSARY) X PLA ;AND READ THE NEW ONE X PHA X CLC ;BY FALLING INTO MUSTWM WITH CY=0 X; XMUSTWM PHA X LDA #HIGH[MAPBUF+256] X LDY #LOW[MAPBUF+256] X JSR BUFSET ;SET UP THE BUFFER POINTER FOR 2ND PAGE X PLA ; OF THE VTOC BUFFER X JSR MAPIOC ;ISSUE I/O REQUESTS X PLA X STA MAP2 ;UPDATE SECOND BUFFER ID BYTE XNOMAPI RTS X; XRWBMAP JSR SYSSET ;SET UP BUFFER POINTERS FOR SYSTEM BUF I/O X LDA #0 XMAPIOC PHP X pha X ldx DUNIT ;NOTE: THE CURRENT I/O MAY NOT BE TO THE X lda SECSIZ-1,X ;FCB BEING ACCESSED! X tax ;[Bob Puff] X pla X cpx #2 ;256 BYTE SECS? X beq MAPDDS X ASL A ;128, CHANGE PAGE NUMBER TO PAIR NUMBER XMAPDDS EOR #$FF X SEC X ADC #LOW[360] X TAY X cpx #2 ;128 OR 256 BYTE SECTORS? X beq DDMAPX ;IF 128, READ 2 SECTORS TO FILL BUFFER X LDA #HIGH[360] X PLP X PHP X JSR SYSRW ;READ OR WRITE THE FIRST SECTOR X LDA MAPBUF X CMP #3 ;IF DOS 2.0 DISK, READ ONE SECTOR X BCC XITMBF ;EVEN IN SINGLE DENSITY X JSR STEPBP X DEY XDDMAPX LDA #HIGH[360] X PLP X PHP X JSR SYSRW ;READ OR WRITE THE SECOND (OR ONLY) SECTOR XXITMBF PLP XNOMPI2 LDA ICDNOZ X STA DUNIT ;RESTORE THE USER DRIVE NUMBER TO DUNIT, X RTS ;SINCE I/O MAY HAVE BEEN TO ANOTHER DRIVE X; XSYSSET LDA #HIGH[MAPBUF] X LDY #LOW[MAPBUF] X JMP BUFSET X; X; ROUTINE TO STEP TO THE NEXT DIRECTORY ENTRY (UNTIL WE RUN OUT) X; XBSECDS LDY #0 X STY DIRDSP X LSR A X ROR DIRDSP X LSR A X ROR DIRDSP X LSR A X ROR DIRDSP ;(FILE NUMBER MOD 8) * 16 IS OFFSET IN SECTOR X STA DIRSEC ;FILE NUMBER/8 IS SECTOR OFFSET X; X CMP #8 ;END OF DIRECTORY? X DEY X BCS BSECXT X ROR DIRDSP XBSECXT RTS SHAR_EOF sed 's/^X//' << \SHAR_EOF > mdos4.asm X; X; DOS ALLOCATION ROUTINES X; X; FREE A SECTOR FOR LATER USE X; XFREE JSR RBITMP ;MAKE SURE WE HAVE THE RIGHT MAP X STA CHGMAP XFMTFRE INC MAPBUF+3 ;BUMP LOW BYTE OF FREE SECTOR COUNT X BNE FREE0 ;IF NO CARRY X INC MAPBUF+4 XFREE0 JSR FNDBIT X PHA X LDA TMP2 X BEQ SBMP1 X STY TMP2 X CMP CURMP ;BEFORE FIRST HOLE? X BCS SBMP2 ;NO, LEAVE UNCHANGED X STA CURMP ;YES, NEW FIRST HOLE XSBMP2 JSR RDNXTM X LDY TMP2 X LSR MAP2MOD ;MARK MAP PAGE2 DIRTY X PLA X ORA MAPBUF+256,Y X STA MAPBUF+256,Y X RTS X; XSBMP1 PLA X ORA MAPBUF,Y X STA MAPBUF,Y X RTS X; X; FIND BIT ASSOCIATED WITH A SECTOR ON THE DISK X; XFNDBIT LDA CURSEC,X X AND #7 ;EXTRACT THE BIT NUMBER X TAY X SEC X LDA #0 XFREE1 ROR A ;POSITION CARRY TO THE BIT TO FLIP X DEY X BPL FREE1 X PHA ;SAVE THE BIT MASK X; X LDA CURSEC,X X CLC X ADC #10*8 ;ALLOW FOR 10 BYTE HEADER X TAY ;SAVE LOW BYTE X LDA CURSEC+1,X X ADC #0 ;PROPOGATE CARRY X LSR A X STA TMP2 X TYA X ROR A X LSR TMP2 X ROR A X LSR TMP2 X ROR A X TAY X; X PLA ;RESTORE THE BIT MASK X RTS X; X; ALLOCATE AN UNUSED SECTOR TO A FILE X; XALLOC JSR RBITMP X STA CHGMAP X LDY #10 X LDA #0 X STA TMP2 XALL1 CMP MAPBUF,Y ;ANY BITS LEFT? X BNE SECFN1 ;IF SO X INY X BNE ALL1 X; X SEC X LDA MAPBUF X SBC CURMP X SEC X SBC #3 X STA TMP1 XALLCK BMI ALGONE X LDA CURMP X STA TMP2 X JSR RDNXTM X LDA #0 X TAY XALL2 CMP MAPBUF+256,Y X BNE SECFN2 ;IF FREE SECTOR IN SECOND PART OF MAP X INY X BNE ALL2 X INC CURMP ;TO NEXT SECTOR OF BIT MAP X DEC TMP1 X BPL ALLCK X; XALGONE DEC CURMP XDFERR LDA #162 ;DISK FULL ERROR CODE X JMP AEXIT ;IF THIS IS IT, ERROR-EXIT X; XSECFN1 SEC X LDX #$AF ;I.E., -8*10 - 1 XALL3 ROR A X INX X CMP MAPBUF,Y X BCC ALL4 X CLC X BNE ALL3 XALL4 EOR MAPBUF,Y X STA MAPBUF,Y X BPL ALL7 X; XSECFN2 SEC X LDX #$AF ;I.E., -8*10 - 1 XALL5 ROR A X INX X CMP MAPBUF+256,Y X BCC ALL6 X CLC X BNE ALL5 XALL6 LSR MAP2MOD X EOR MAPBUF+256,Y X STA MAPBUF+256,Y X; XALL7 TYA X ASL A X ROL TMP2 X ASL A X ROL TMP2 X ASL A X ROL TMP2 X STA TMP1 X TXA X ADC TMP1 X LDX CURFCB X STA LNKSEC,X X LDA TMP2 X ADC #$FF X STA LNKSEC+1,X XDECCNT LDA MAPBUF+3 X BNE NOBOR X DEC MAPBUF+4 XNOBOR DEC MAPBUF+3 X CLC X RTS X; X; SIMULATE OLD STYLE BIT FINDER X; XFNDLBIT JSR FNDBIT X PHA ;SAVE MASK X LDA TMP2 ;FIRST PAGE? X BEQ FNDPG0 X STY TMP2 ;SAVE OFFSET IN PAGE X CMP DATBYT X BCS DFEJMP X JSR RDNXTM ;READ IN PROPER PAGE X LDY TMP2 ;THEN RESTORE A AND Y REGS X PLA X SEC ;SET CY (PAGE 1 BUFFER USED) X RTS X; XFNDPG0 PLA ;RESTORE SAVED MASK X CLC ;AND CLR CY (SAY PAGE 0) X RTS X; XDFEJMP JMP DFERR X; XDECCSEC LDA CURSEC,X X BNE ALCPG0 X DEC CURSEC+1,X XALCPG0 DEC CURSEC,X X RTS X; XINCCSEC INC CURSEC,X X BNE DELDIN X INC CURSEC+1,X XDELDIN RTS X; X; DOS MISC. SUBROUTINES X; X; SET UP STATE VARIABLES ON ENTRY X; XSETUP LDY ICDNOZ ;GET UNIT NO. XSETUPW STX CURFCB X TSX X INX X INX X STX STKPSV ;SAVE POINTER TO RETURN ADDR ON STACK XSETUPD STY DUNIT ;COPY UNIT NO. TO DCB X LDA #1 X CPY RAMDKU X BEQ UFIXED ;RAMDISK SECTOR SIZE IS ALWAYS 128 BYTES X LDA SECSIZ-1,Y X BEQ INVUNIT ;IF NOT CURRENTLY VALID UNIT, TEST FOR DENSITY XUFIXED STA SECDAT ;OTHERWISE, STORE CORRECT DENSITY DATA X LSR A X ROR A X ROR A X ORA #$7D ;UPDATE THE LINK POSITION IN THE DISK SECTOR X STA DLINK X; X LDX CURFCB X LDY BUFNO,X ;GET THE BUFFER NUMBER X BNE RSETUP X LDY FILES ;IF ONE IS NOT ALLOCATED X INY XSFORB DEY X BEQ NOSECB ;ALLOCATE ONE, OR ABORT THE OPERATION NOW X LDA BUFFLG-1,Y X BNE SFORB X LDA #$80 X STA BUFFLG-1,Y X TYA X STA BUFNO,X XRSETUP LDA DOSEND ;==SBTABL X STA FMSBPT X LDA SBTABU-1,Y X STA FMSBPT+1 X RTS X; XINVUNIT JSR JSTRD X BNE UFIXED X; XNOUNIT LDA #160 ;RETURN ST=160, DRIVE NOT PRESENT X DB $AE ;SKIP TO JMP INSTRUCTION XNOSECB LDA #161 ;RETURN ST=161, NO MORE FILE BUFFERS X JMP AEXIT X; X; REMOVE DOS POINTER FROM BOOT SECTORS X; XTDDOS JSR TSTDOS ;MUST WE UPDATE BOOT? X BNE NODOSX ;NO, RETURN X; XDELDOS LDY #0 ;YES, REMOVE DOS POINTER FROM BOOT X BEQ UPDBT X; X; ADD DOS POINTER TO BOOT SECTORS X; XSETDOS STY DOSLOC X STA DOSLOC+1 X LDY SECDAT XUPDBT LDA DUNIT X CMP RAMDKU X BEQ TDEXIT X STY SECDAT X LDA STATE X PHA X LDA DEFAULT X PHA X LDA #$00 X STA STATE ;NOTHING IS IN MEMORY YET X LDY #$FF X LDA FCBOTC,X X BMI NOAND ;LONG LENGTH FIELD? X LDY #$03 ;IF NOT, USE ONLY 10 BITS XNOAND STY ANDCD+1 X LDA #HIGH[BOOTFL] X LDY #LOW[BOOTFL] X JSR BUFSET X LDY #0 X STY DAUX2 X; XWSECL INY X STY DAUX1 X LDX #1 X STX DEFAULT X SEC X JSR DKIO2 X JSR STEPBP X CPY BOOTL X BNE WSECL X; X PLA X STA DEFAULT X PLA X STA STATE X LDY ICDNOZ X STY DUNIT X LDA SECSIZ-1,Y X STA SECDAT XNODOSX RTS X; X; TEST FOR FILE NAME = 'DOS.SYS' X; XTSTDOS LDY #256-11 X LDX DIRDSP XTDLOOP LDA DIRBUF+5,X X EOR DOSSYS-256+11,Y X BNE TDEXIT X INX X INY X BNE TDLOOP XTDEXIT LDX CURFCB X TAY X RTS X; XDOSSYS DB 'DOS SYS' X; X; FIND AT LEAST ONE FILE MATCHING GIVEN NAME X; XLFFILE JSR GETFNM ;EXTRACT FILE NAME FROM BUFFER X STY TMP2 ;SAVE IT FOR -RENAME- X JSR SFDIR ;FIND FIRST MATCHING FILE IN DIR X LDA #170 ;IF NONE, RETURN ERROR 170 X BCS AEXIT ;ELSE, RETURN X RTS X; X; RETURN ERROR IF FILE IS LOCKED X; XTSTLOK LDA #$20 ;CHECK BIT 5 X JSR GETFLAG X BEQ TDEXIT X LDA #167 ;FILE LOCKED ERROR = 167 X DB $AE ;SKIP 2 BYTES X; X; RETURN WITH NO ERROR X; XDONE LDA #1 ;NORMAL COMPLETION X; X; RETURN ERROR CODE IN ACC TO CIO (IN Y) X; XAEXIT LDX STKPSV ;RESTORE STACK POINTER X TXS X LDX CURFCB ;RESTORE IOCB OFFSET TO X-REG X STA ICSTA,X ;RETURN STATUS IN IOCB X TAY ;RETURN STATUS IN Y-REG X LDA DATBYT X CPY #0 X RTS X; X; RETURN HARDWARE ERRORS TO CIO X; XHWERR X;;; lda #0 ;fix VTOC updating bug X;;; sta CURMAP ;do we really want to do this????? X;;; sta CHGMAP ;[Bob Puff] X X LDA DSTATS X BNE AEXIT X; X; RELEASE FCB AND RETURN NO-ERROR STATUS X; XFREDON LDX CURFCB X; X LDY BUFNO,X ;FINISHED WITH THE SECTOR BUFFER, RETURN IT X BEQ DONE ;IF NONE ALLOCATED, SO WHAT! X LDA #0 X STA BUFNO,X X STA BUFFLG-1,Y X BEQ DONE X; X; TEST OR CLEAR A BIT IN THE FLAG BYTE X; XGETFLAG LDY DIRDSP X AND DIRBUF,Y X RTS X; X; SAVE FLAG BYTE AND WRITE BACK TO DIRECTORY X; XSAVFLAG LDY DIRDSP X STA DIRBUF,Y X JMP WDIRBK SHAR_EOF # End of shell archive exit 0 =========================================================================== Charles Marslett STB Systems, Inc. <== Apply all standard disclaimers Wordmark Systems <== No disclaimers required -- that's just me chasm@killer.dallas.tx.us