Mercurial > hg > Members > kono > nitros9-code
view 3rdparty/roms/dos/SuperDos/superdos-e6-03.asm @ 2527:051d0f956c6f
Cleaned up patches and attempted to keep tempo intact.
Unfortunately tempo is 1.23x slower for no known reason. RG
author | robertgault |
---|---|
date | Sat, 10 Apr 2010 13:44:38 +0000 |
parents | 9c683723c7aa |
children |
line wrap: on
line source
; ; SuperDos E6, Copyright (C) 1986 ???, Grosvenor. ; ; Disassembled 2004-11-05, P.Harvey-Smith. ; ; Fixed for assembly with "mamou" cross-assembler, ; from NitrOS9 cocotools. ; ; Ported to the Dragon Alpha/Professional hardware, ; 2004-11-21 P.Harvey-Smith. ; ; Ported to RS-DOS cartrage (FD-500), using WD1773, ; 2006-01-16 P.Harvey-Smith. ; ; Began porting to run natively on Tandy CoCo 1/2 ; 2006-01-26 P.Harvey-Smith. ; ; Completed port to CoCo. ; 2006-01-30 P.Harvey-Smith. ; ; The CoCo port has the following differences from the Dragon version, ; these are largely due to the fact that on the CoCo, Color basic, and ; Extended color basic are in 2 roms that are linked, whereas the Dragon ; has the equivelent of Extended basic but all in one ROM. ; Also some of the meanings of the Low ram vectors are slightly different. ; ; 1) The RUN vector at $829C, is not called before a program is run, as DOS ; takes over this vector, the upshot of this is that the parameters for ; the PLAY command are not reset on each run. However this is easily ; enough remedied by EXEC &H829C as the first line of your program. ; ; 2) The error hook at $88F0 is not called however, the SuperDos error handler ; calls the Basic error handler if needed (if errors are not trapped with ; on error) ; ; 3) The close single file hook gets re-directed to the DOS handler, scanning the ; code this should only be a problem if writing a file to cassete. ; ; 4) The Console output hook is overwritten by DOS, this does not appear to have ; any effect. ; ; These are defined by the makefile, and are the DOS controlers supported. ; ;DragonDos EQU 1 ; Define this if compiling for Standard DragonDos Cart. ;DragonAlpha EQU 1 ; Define this if compiling for Dragon Alpha. ;RSDos EQU 1 ; Define this if compiling for the RS-DOS cart. ; ;These are also defined in the makefile and are the Machines supported. ; ;Dragon EQU 1 ; Build for Dragon 32/64/Alpha/Tano/200. ;Tandy EQU 1 ; Build for Tandy CoCo 1/2/3. ; ; ; The file RomDefs.asm contains a set of definitions for calling the ROM routines ; of either the Dragon or CoCo machines, these will be assembled conditionally ; depending on weather Dragon or Tandy is defined. ; ifp1 use dgndefs.asm use romdefs.asm use dosdefs.asm endc IFNE DragonDos DPPIADA EQU DPPIA1DA DPPIACRA EQU DPPIA1CRA DPPIADB EQU DPPIA1DB DPPIACRB EQU DPPIA1CRB PIADA EQU DPPIADA+IO ; Side A Data/DDR PIACRA EQU DPPIACRA+IO ; Side A Control. PIADB EQU DPPIADB+IO ; Side A Data/DDR PIACRB EQU DPPIACRB+IO ; Side A Control. ;WD2797 Floppy disk controler, used in DragonDos. DPCMDREG EQU DPCmdRegD ; command/status DPTRKREG EQU DPTrkRegD ; Track register DPSECREG EQU DPSecRegD ; Sector register DPDATAREG EQU DPDataRegD ; Data register CMDREG EQU DPCMDREG+IO ; command/status TRKREG EQU DPTRKREG+IO ; Track register SECREG EQU DPSECREG+IO ; Sector register DATAREG EQU DPDATAREG+IO ; Data register ; Disk IO bitmasks NMIEn EQU NMIEnD ; Enable/disable NMI WPCEn EQU WPCEnD ; Write precomp enable SDensEn EQU SDensEnD ; Write precomp enable MotorOn EQU MotorOnD ; Motor on enable DskCtl EQU DskCtlD ; Disk control reg DPDskCtl EQU DPDskCtlD ; Disk control reg DriveMask EQU DriveMaskD ; Mask to extract drives form DskCtl ENDC IFNE DragonAlpha * Dragon Alpha has a third PIA at FF24, this is used for * Drive select / motor control, and provides FIRQ from the * disk controler. DPPIADA EQU DPPIA2DA DPPIACRA EQU DPPIA2CRA DPPIADB EQU DPPIA2DB DPPIACRB EQU DPPIA2CRB PIADA EQU DPPIADA+IO ; Side A Data/DDR PIACRA EQU DPPIACRA+IO ; Side A Control. PIADB EQU DPPIADB+IO ; Side A Data/DDR PIACRB EQU DPPIACRB+IO ; Side A Control. ;WD2797 Floppy disk controler, used in Alpha Note registers in reverse order ! DPCMDREG EQU DPCmdRegA ; command/status DPTRKREG EQU DPTrkRegA ; Track register DPSECREG EQU DPSecRegA ; Sector register DPDATAREG EQU DPDataRegA ; Data register CMDREG EQU DPCMDREG+IO ; command/status TRKREG EQU DPTRKREG+IO ; Track register SECREG EQU DPSECREG+IO ; Sector register DATAREG EQU DPDATAREG+IO ; Data register ; Disk IO bitmasks NMIEn EQU NMIEnA ; Enable/disable NMI WPCEn EQU WPCEnA ; Write precomp enable SDensEn EQU SDensEnA ; Write precomp enable MotorOn EQU MotorOnA ; Motor on enable Drive0 EQU Drive0A Drive1 EQU Drive1A Drive2 EQU Drive2A Drive3 EQU Drive3A KnownBits EQU Drive0+Drive1+Drive2+Drive3+MotorOn+WPCEn DriveMask EQU DriveMaskD ; Mask to extract drives form DskCtl ;**** Important, about should be the DragonDos one NOT Alpha one ***** ENDC IFNE RSDos ; This is to use the Tandy FD-500 on a Dragon running superdos. DPPIADA EQU DPPIA1DA DPPIACRA EQU DPPIA1CRA DPPIADB EQU DPPIA1DB DPPIACRB EQU DPPIA1CRB PIADA EQU DPPIADA+IO ; Side A Data/DDR PIACRA EQU DPPIACRA+IO ; Side A Control. PIADB EQU DPPIADB+IO ; Side A Data/DDR PIACRB EQU DPPIACRB+IO ; Side A Control. ;WD2797 Floppy disk controler, used in DragonDos. DPCMDREG EQU DPCmdRegT ; command/status DPTRKREG EQU DPTrkRegT ; Track register DPSECREG EQU DPSecRegT ; Sector register DPDATAREG EQU DPDataRegT ; Data register CMDREG EQU DPCMDREG+IO ; command/status TRKREG EQU DPTRKREG+IO ; Track register SECREG EQU DPSECREG+IO ; Sector register DATAREG EQU DPDATAREG+IO ; Data register ; Disk IO bitmasks NMIEn EQU NMIEnT ; Enable/disable NMI WPCEn EQU WPCEnT ; Write precomp enable SDensEn EQU SDensEnT ; Write precomp enable MotorOn EQU MotorOnT ; Motor on enable DskCtl EQU DskCtlT ; Disk control reg DPDskCtl EQU DPDskCtlT ; Disk control reg Drive0 EQU Drive0T Drive1 EQU Drive1T Drive2 EQU Drive2T Drive3 EQU Drive3T DriveMask EQU DriveMaskT ; Mask to extract drives form DskCtl ENDC IFNE Tandy ; Compiling to run on Tandy CoCo NextResJump EQU BasStub3+StubResJumpOfs ; Jump to reserved word handler of user table NextFuncsJump EQU BasStub3+StubFuncsJumpOfs ; Jump to functions handler of user table ELSE ; Compiling to run on Dragon 32/64/Alpha NextResJump EQU BasStub2+StubResJumpOfs ; Jump to reserved word handler of user table NextFuncsJump EQU BasStub2+StubFuncsJumpOfs ; Jump to functions handler of user table ENDC ORG $C000 ; Disk controler ID, if a cartrage starts with the chars 'DK', then the basic rom routines ; will do a JMP to $C002 to init the cartrage. DC000 FCC /DK/ LC002 BRA DosInit ; ; Jump table containing the addresses of the various dos routines, these should be called by : ; JSR [JumpAddr] rather than jumping directly to the routine. ; JSR [JumpAddr] rather than jumping directly to the routine. ; FDB SuperDosLowLevel ; Low Level disk IO routine FDB DosHWByte ; Address of data table for low level command FDB SuperDosValidFilename ; Validate filename & copy to disk block. FDB SuperDosOpenFile ; Open A file. FDB SuperDosCreateFile ; Create file (make backup) FDB SuperDosGetFLen ; Get file length FDB SuperDosCloseAll ; Close all open files FDB SuperDosCloseFile ; Close file FDB SuperDosFRead ; Read data from file FDB SuperDosFWrite ; Write data to file FDB SuperDosGetFree ; Get free space on a disk FDB SuperDosDeleteFile ; Delete a file FDB SuperDosProtect ; Protect/unprotect file FDB SuperDosRename ; Rename a file FDB SuperDosGetDirEntry ; Get a directory entry FDB SuperDosFindAndRead ; Find free buffer and read sector FDB SuperDosSyncDir ; Copy updated sectors from track 20 to 16 (sync direcories) FDB SuperDosReadAbsSector ; Read absolute sector FDB SuperDosWriteAbsSector ; Write absolute sector (no verify) ; ; Init Dos ; DosInit LDX #DosAreaStart ; Point to bottom of dos vars area TFR X,Y LC02F CLR ,X+ ; Clear a byte, increment X LEAY -1,Y ; decrement counter BNE LC02F ; loop again if more to do ; X now points to the top of the dos variable area TFR X,D TFR A,B ADDB #$18 STB <BasStartProg ; Setup new begining of basic JSR >BasLocateScreen LDA <GrDisplayStartAddr ; Adjust graphics ram pages ADDA #$06 STA <GrLastDisplayAddr ; ; Init various low ram stuff, inturrupt vectors, basic stub etc ; LDX #DDE24 ; Point to rom copy of data to copy LC049 LDB ,X+ ; Get byte count byte BEQ LC054 ; zero= end of table, exit copy LDU ,X++ ; Get destination address JSR >UtilCopyBXtoU ; do copy BRA LC049 ; do next LC054 CLR DosHWMaskFF48 ; clear hardware mask COM DosVerifyFlag ; function unknown LDX #DosNewUSRTable ; Adjust usr vector base STX <BasUSRTableAddr LDU #BasFCError ; Setup the 10 usr vectors to point to BasFCError LDB #$0A ; do 10 LC064 STU ,X++ ; setup vector DECB ; decrement count BNE LC064 ; loop again if more to do INC DosDefDriveNo BSR LC09D LDX #VectBase ; Point to ram hooks LDY #RamHookTable ; Point to ram hook table in rom LDD #$137E ; load A with number of vectors B with opcode for JMP LC078 STB ,X+ ; setup jump LDU ,Y++ ; setup vector STU ,X++ DECA ; decrement counter BNE LC078 ; Loop again if more to do LDX #ResetVector ; Setup new reset vector STX <IndVecReset ANDCC #$AF ; reenable inturrupts LDX #BasSignonMess ; Print staandard Basic signon message JSR >TextOutString JSR >DosDoRestore LDX #DosSignonMess JSR >TextOutString JSR >LDC08 JMP >BasCmdMode ; Jump to normal basic command mode LC09D LDA #WDCmdForceInt ; Force WD2797 to inturrupt & reset STA cmdreg LDX #DosD0Online ; Clear drive online flags LDD <Misc16BitScratch ; load D with 16 bit zero !!!! STD ,X STD 2,X LDX #Drv0Details+5 ; last byte of drive details for each drive CLR ,X CLR 6,X CLR 12,X CLR $12,X CLR <DosIOInProgress ; Flag to check for timeout LDX #DosDirSecStatus ; Clear Dirctory status, FCBs etc LC0BC CLR ,X+ CMPX #DosFCBEnd BNE LC0BC LDB #$04 ; Count of buffers to process LDX #Buff1Details ; Setup disk buffer initial values LDU #$0800 ; addr of buffer LC0CB CLR 2,X STB 4,X STU 5,X LEAU $0100,U ; Increment addr for next buffer LEAX 7,X ; do next buffer DECB ; done all ? BNE LC0CB ; no : do next RTS FCB $2A FCB $20 LC0DD LDB DosTimeout ; Get timeout STA DosTimeout TSTB ; Timeout ? BNE LC0ED ; no : return LDX #SpinUpDelay ; wait some time for drive to spin up LC0E9 LEAX -1,X BNE LC0E9 LC0ED RTS ; These bytes are here to ensure that the entry points below are at the same ; address as they are in DragonDos, so that badly behaved programs that make ; direct calls (rather than going through jump table) will still work ! FCC / / ; ; The following code is quite clever, there are actually multiple code paths. ; This involves having a 2 byte instruction encoded as the oprand to a 3 ; byte instruction eg :- ; ; L00FA CMPX #$C605 ; ; CMPX is one byte long, so a jump to L00DB, will execute the oprand to the ; CMPX, which decodes as LDB #$05 this saves a few bytes by not having LDB #xx, ; BRA label. ; ; There are several examples of this in the Dos ROM ! ; LC0F8 LDB #DosFnReadAddr FCB Skip2 ; CMPX DosDoWriteTrack LDB #DosFnWriteTrack FCB Skip2 ; CMPX DosDoWriteSec2 LDB #DosFnWriteSec2 FCB Skip2 ; CMPX DosDoWriteSec LDB #DosFnWriteSec FCB Skip2 ; CMPX DosDoReadSec LDB #DosFnReadSec DosDoFuncinB PSHS A LEAS -2,S ; Make room on stack CLR $0600 LC10D LDA #$03 ; retry count ? STD ,S ; save on stack LC111 BSR DosDoSeek ; Try to seek to track BCS LC11D ; Error ? LDB 1,S ; No error, get dos op code STB <DosHWByte ; Save operation to perform BSR SuperDosLowLevel BCC LC159 ; No error LC11D CMPB #$84 BEQ LC148 DEC ,S ; Dec retry count BEQ LC13A ; Any retries left ? LDB ,S ; get retry count LSRB ; gety lsbit BCC LC132 ; on even numbered retry, do recal INC <DskTrackNo ; step out a track BSR DosDoSeek DEC <DskTrackNo ; step back in when retrying BRA LC111 LC132 LDA <DskTrackNo ; Save Track no whilst doing restore BSR DosDoRestore ; Restore & Recalibrate STA <DskTrackNo ; Put track no back BRA LC111 ; Try again ; We come here when all reties exhausted LC13A CMPB #$80 BNE LC156 TST $0600 BNE LC156 COM $0600 BRA LC152 ; Something to do with dir track ? Make sure same op done to both copies of Dir LC148 LDA <DskTrackNo ; Get track number CMPA #$14 ; Track 20 ? BNE LC156 ; no : error LDA #$10 ; set track to 16 STA <DskTrackNo LC152 LDB 1,S ; Get Dos op code BRA LC10D ; So same to track 16 LC156 ORCC #$01 ; Flag error FCB Skip1 ; opcocode for BRN LC159 CLRB ; Flag no error LEAS 2,S ; Drop bytes from stack PULS A,PC ; restore & return ; ; Another LDB, enbeded in CMPX sequence.... ; DosDoReadSec2 LDB #DosFnReadSec2 FCB Skip2 ; CMPX DosDoSeek LDB #DosFnSeek FCB Skip2 ; CMPX DosDoRestore LDB #DosFnRestore STB <DosHWByte ; save in hardware byte ; ; Low level hardware command, operation is in $00E8 ; SuperDosLowLevel PSHS CC,A,DP,X,Y,U ORCC #$50 ; Disable inturrupts ROR ,S CLR <DosDiskError ; Flag no disk error LDA <DosHWByte ; get HW byte CMPA #$07 ; Valid op BLS LC178 ; yes : do it ! BRA LC180 ; No: error LC178 JSR >ResetAndStartDrive BCC LC18B ; Error ? LDB #$FD ; yes flag error FCB Skip2 ; Andothe CMPX saving..... LC180 LDB #$FC ; Set error code ORCC #$01 ; and carry bit ROL ,S STB <DosDiskError ; Flag disk error JMP >LC24D ; Disable IRQ LC18B LDX #PIA0CRA ; Point to PIA CR A LC18E LDA ,X ; Get old value PSHS A ; save on stack ANDA #$FC ; Turn off inturrupt STA ,X++ ; Save it and point to CR B LDA ,X ; Get old CRB value PSHS A ; save it on stack ANDA #$FC ; Disable Inturrupt STA ,X LEAX $1E,X ; Point to next PIA CMPX #PIA1CRB ; PIA1 ? BCS LC18E ; No : do disable IFEQ RSDos LDA PIACRB ; Enable FIRQ from FDC (Not on RSDos). ORA #$37 STA PIACRB ENDC LDA #$03 PSHS A LDA <DskSectorNo ; Get disk sector no IFNE RSDos ; Set side select correctly on RSDos controler. RSDosSetSide CMPA #$12 ; >$12, therefore on second side BLS RSDosSide0 ; Yes, on side 0 LDB #SS0 ; turn on SSO bit in FDCREG ORB DosHWMaskFF48 bra RSDosSetSide01 ; Set it RSDosSide0 LDB DosHWMaskFF48 ; Turn off SSO ANDB #~SS0 RSDosSetSide01 STB DosHWMaskFF48 ; Resave STB DskCtl ; Write to hardware ENDC CMPA #$12 ; >$12, therefore on second side BLS LC1C2 ; no: don't adjust SUBA #$12 ; Calculate sector number on second side IFEQ RSDos LDB #$02 ; Flag as side 2 (Dragon WD2797 only) ORB DosHWMaskFF40 STB DosHWMaskFF40 ENDC LC1C2 STA secreg ; Save in sector register STA <DosSectorSeek ; Save sector we are looking for LC1C7 LDY <Misc16BitScratch LDX <DiskBuffPtr ; Point to buffer LDB <DosHWByte ; Get hardware byte (function code) ASLB ; Calculate offset in table LDU #DosFunctionTable ; Point to function dispatch table LDA <DosSectorSeek ; Get sector we are seeking to CMPA secreg ; Found it yet ? BNE LC1C2 LDA #$FF ; Set DP=$FF, to make IO quicker TFR A,DP LC1DD JSR [B,U] ; Jump to function handler STA <DosDiskError ; Save error code BCC LC1E5 ; No error : check verify BRA LC213 LC1E5 ANDA DosErrorMask ; Mask out error bits we are not interested in STA <DosDiskError ; save errors for later use BEQ LC1FA ; No error : jump ahead LDA <DosHWByte ; Get operation code CMPA #DosFnReadSec2 ; ReadSec2 command ? BEQ LC1F6 DEC ,S ; Dec retry count BNE LC1C7 ; retry LC1F6 ORCC #$01 ; Flag error BRA LC213 LC1FA TST DosErrorMask ; is this write sector ? BPL LC213 ; no : jump ahead LDA <DskTrackNo ; Get track number CMPA #$14 ; Primary Dir track ? BEQ LC210 CMPA #$10 ; Secondary dir track ? BEQ LC210 TST DosVerifyFlag ANDCC #$FE ; re-enable inturrupts BPL LC213 LC210 LBSR DosDoReadSec2 LC213 LEAS 1,S ROL 4,S LDX #DosD0Track-1 ; Point to drive track table LDB <LastActiveDrv ; Get last used drive ABX ; get pointer to track for current drive LDA trkreg ; Get current track number from WD CMPA <DskTrackNo ; Same as current track no ? BEQ LC235 ; yes : update table LDB DosErrorMask ; is this a seek ? CMPB #$19 BNE LC235 LDB #$FF STB <DosDiskError ROR 4,S ORCC #$01 ; flag error ROL 4,S LC235 STA ,X ; Update current track for current drive LDX #PIA1CRB ; Restore state of PIA from stack LC23A PULS A STA ,X PULS A STA ,--X LEAX -$1E,X ; Do PIA0 CMPX #PIA0CRA BHI LC23A CLR DosHWMaskFF40 ; Clear hardware mask LC24D CLRB ; Flag no error PULS CC,A,DP,X,Y,U ; Restore regs BCC LC289 LDB <DosDiskError ; get last error code BEQ LC289 ; no error : exit BPL LC278 ; ; Work out the dragon error code that coresponds to the hardware ; error reported by WD. ; CMPB #$FC BNE LC260 LDB #$A4 BRA LC287 LC260 CMPB #$FD BNE LC268 LDB #$28 BRA LC287 LC268 CMPB #$FE BNE LC270 LDB #$80 BRA LC287 LC270 CMPB #$FF BNE LC285 LDB #$82 BRA LC287 LC278 TFR B,A LDB #$82 ROLA LC27D ADDB #$02 ROLA TSTA BCS LC287 BNE LC27D LC285 LDB #$A6 LC287 ORCC #$01 LC289 RTS ; ; Reset controler chip, and spin up drive. ; ResetAndStartDrive LDA #WDCmdForceInt ; Force inturrupt STA cmdreg LDA <DosLastDrive ; Get last active drive no BMI LC29A ; invalid, flag error & exit BEQ StartDrive ; Zero ? : yes branch on DECA ; Make drive number 0..3 from 1..4 CMPA #$03 ; Drive valid ? BLS StartDrive2 ; yes : continue LC29A ORCC #$01 ; flag error DosHookRetDevParam RTS ; return ; ; Select drive, and start motor & load track reg. ; ; A=Drive no 0..3 ; StartDrive INC <DosLastDrive ; Flag drive 1 StartDrive2 IFNE RSDos ; ; Translate Dragon Drive number to RSDos hardware number ; Dragon RSDos ; 00000000 00000001 ; 00000001 00000010 ; 00000010 00000100 ; 00000011 00000100 ; A=Dragon Mask ; leax TDriveTab,pcr ; Point at drive table lda a,x ; get drive ENDC ORA #NMIEn+MotorOn ; Mask in nmi enable & Motor on bits PSHS A LDA DosHWMaskFF48 ; Get HW byte mask ANDA #~DriveMask ; Mask out drive bits ORA ,S+ ; Mask in drive bits ifne DragonAlpha LBSR AlphaDskCtl ; Write to control reg else STA DskCtl ; Write to control reg endc STA DosHWMaskFF48 ; Resave hardware mask LDX #DosD0Track-1 ; Point to current track table LDA <LastActiveDrv ; Get active drive LDA A,X ; Get drive current track STA trkreg ; Write to controler LDA #$D2 JSR >LC0DD CLRB ; no error ? RTS ; ; Dos function 0 comes here ; DosFunctionRestore CLRA STA >DskTrackNo ; Save Track number BRA LC2D9 ; ; Dos function 1 ; DosFunctionSeek LDA >DskTrackNo ; Get current track no CMPA dptrkreg ; Are we over it ? BNE SeekTrackinA ; no : seek to it CLRA STA DosErrorMask ; Turn off verify TFR A,DP ; Reset DP RTS ; ; Seek to a track, routine will exit either with an error, or via NMI. ; On entry A contains track to seek to. ; SeekTrackinA STA dpdatareg LDA #WDCmdSeek ; Seek command LC2D9 LDB #$19 STB DosErrorMask LDX #DosD0StepRate-1 ; Point to step rate table LDB >LastActiveDrv ; Get active drive ORA B,X ; Mask in that drive's step rate STA dpcmdreg ; save in command reg LC2E8 MUL ; burn up CPU time waiting.... MUL ; NMI will exit this loop LEAY -1,Y ; decrement timeout counter BNE LC2E8 ; count exhausted ? : no keep going BRA LC337 ; yes : error ifne RSDos ; ; Dos function 6 : Read address mark (RS-Dos) ; DosFunctionReadAddr LDB #WDCmdReadAddr ; Read address mark FCB Skip2 ; CMPX again :) ; ; Dos function 2 : Read sector (RS-Dos) ; DosFunctionReadSec LDB #WDCmdReadSec ; Read a sector ORB DosHWMaskFF40 ; Mask in side etc LDA #$3F STA DosErrorMask BSR TSetHalt ; Get IO byte with halt enabled in A STB dpcmdreg ; Send command to controler. ldb #02 ; Busy bit LC301 bitb <DPCMDREG ; still busy ? BNE TReadSec ; no : read sector LEAY -1,Y ; decrement timeout count BNE LC301 ; check for int again, if no timeout TReadSec RNext LDB dpDataReg ; Get byte STB ,X+ ; save in mem STA dpDSKCTL ; Update reg BRA RNext ELSE ; ; Dos function 6 : Read address mark (Dragon) ; DosFunctionReadAddr LDA #WDCmdReadAddr ; Read address mark FCB Skip2 ; CMPX again :) ; ; Dos function 2 : Read sector (Dragon/Cumana) ; DosFunctionReadSec LDA #WDCmdReadSec ; Read a sector LDB #$3F STB DosErrorMask LDB #$05 ; try 5x$FFFF for timeout ORA DosHWMaskFF40 ; Mask in side etc STA dpcmdreg LC301 LDA dppiacrb ; Check for INT from WD BMI LC311 ; yes : start reading bytes LEAY -1,Y ; decrement timeout count BNE LC301 ; check for int again, if no timeout LDA dppiadb DECB ; decrement retry wait count BNE LC301 ; count=0 ?, no continue waiting BRA LC337 ; yes : error and exit ; ; Read sector/address mark loop, exits with NMI. ; LC310 SYNC ; Syncronise to FIRQ (INT from WD) LC311 LDB dppiadb ; clear iunturrupt LDA dpdatareg ; read byte from WD STA ,X+ ; save in buffer BRA LC310 ; do next byte ENDC ; ; Dos function 7 read first two bytes of a sector, used by BOOT command. ; DosFunctionReadSec2 LDX #$004F LDA #$3F STA DosErrorMask IFNE RSDos ; ; Code to wait for DRQ when using RS-DOS controler. ; BSR TSetHalt ; Get IO byte with halt enabled in A LDB #WDCmdReadSec ; Read sector command ORB DosHWMaskFF40 ; mask in heads etc STB dpcmdreg ; write it to WD LC32A LDB #$02 ; Bitmask for DRQ BITB <DPCMDREG ; DRQ asserted ? BNE LC343 ; Yes, read data LEAY -1,Y ; decrement timeout BNE LC32A ; check again ELSE ; ; Code to wait for DRQ when using Dragon/Cumana controlers. ; LDB #$05 ; Wait 5x$FFFF LDA #WDCmdReadSec ; Read sector command ORA DosHWMaskFF40 ; mask in heads etc STA dpcmdreg ; write it to WD LC32A LDA dppiacrb ; Check for Int from WD BMI LC343 ; yes : start reading LEAY -1,Y ; decrement timeout BNE LC32A ; check again LDA dppiadb ; try clearing int DECB ; decrement outer count BNE LC32A ; keep going ? ENDC LC337 LDA #WDCmdForceInt ; Force the WD to abort STA dpcmdreg CLRA ; Reset DP to page 0 TFR A,DP LDA #$FE ; return error ORCC #$01 RTS ; Read data from WD, as normal exited with NMI IFNE RSDos ; ; Read bytes code when using RS-DOS controler. ; LC343 ; LDA DosHWMaskFF48 ; Get Drive control reg ; ORA #HaltEn ; enable halt LDB dpDataReg ; Get byte STB ,X+ ; save in mem STA dpDSKCTL ; Update reg LDB dpDataReg ; Get byte STB ,X ; save in mem STA dpDSKCTL ; Update reg LC350 LDB dpDataReg ; clear DRQ STA dpDSKCTL ; Update reg BRA LC350 ELSE ; ; Read bytes code when using Dragon/Cumana controlers. ; LC343 LDA dpdatareg ; read byte from WD TST dppiadb ; clear inturrupt STA ,X+ ; save in memory SYNC ; wait for next LDA dpdatareg ; get next byte TST dppiadb ; clear inturrupt STA ,X ; save byte LC350 SYNC ; wait for next TST dppiadb ; clear inturrupt LDA dpdatareg ; read byte BRA LC350 ; do next ENDC IFNE RSDos ; ; Load Reg A with CmdReg mask & enable halt, making this a sub, saves a few bytes ! ; TSetHalt LDA DosHWMaskFF48 ; Get Drive control reg ORA #HaltEn ; enable halt RTS ENDC ; ; Dos function 4 ; DosFunctionWriteSec2 LDA #$5F FCB Skip2 ; ; Dos function 3 ; DosFunctionWriteSec LDA #$DF STA DosErrorMask BSR DosSetPrecomp ; Setup write precomp IFNE RSDos ; ; Write sector for RS-DOS controlers. ; ; LDA DosHWMaskFF48 ; Get Drive control reg ; ORA #HaltEn ; enable halt BSR TSetHalt ; Get IO byte with halt enabled in A LDB #WDCmdWriteSec ; Write sector ORB DosHWMaskFF40 ; Mask in side etc STB dpcmdreg ; write to WD LDB #2 ; DRQ MASK LC36A BITB <DPCMDREG ; DRQ asserted ? BNE LC374 ; Yes, go write data LEAY -1,Y ; Decrement count BNE LC36A ; if not timed out continue waiting BRA LC337 ; timout, abort, and return error LC374 LDB ,X+ ; Fetch byte to write STB DPDataReg ; Write it STA DPDskCtl ; Halt controler BRA LC374 ELSE ; ; Write sector for Dragon/Cumana controlers. ; LDA #WDCmdWriteSec ; Write sector ORA DosHWMaskFF40 ; Mask in side etc STA dpcmdreg ; write to WD LDA ,X+ ; fetch first byte to write LC36A LDB dppiacrb ; Int from WD ? BMI LC377 ; yes : start writing LEAY -1,Y ; decrement timeout BNE LC36A ; if not timed out continue waiting BRA LC337 ; timout, abort, and return error ; Write sector loop, NMI breaks out of here LC374 LDA ,X+ ; get byte to write SYNC ; wait for WD LC377 STA dpdatareg ; write byte to WD LDA dppiadb ; clear inturrupt BRA LC374 ; Do next byte ENDC ; ; Dos function 5 : Write (format) track ; DosFunctionWriteTrack LDA #$47 STA DosErrorMask BSR DosSetPrecomp ; Set write precomp IFNE RSDos BSR TSetHalt ; Get IO byte with halt enabled in A LDB #WDCmdWriteTrack ; Write (format) track ORB DosHWMaskFF40 ; Mask in head etc STB dpcmdreg STA dpDskCtl ; Set halt etc LC38B LDD ,X++ ; Get bytes to write A=count, B=byte LC38D STB dpdatareg ; Write a byte on track DECA ; decrement byte count BNE LC38D ; continue until count=0 LDB ,X+ ; get next STB dpdatareg ; write to wd BRA LC38B ; do next block ELSE LDA #WDCmdWriteTrack ; Write (format) track ORA DosHWMaskFF40 ; Mask in head etc STA dpcmdreg LC38B LDD ,X++ ; Get bytes to write A=count, B=byte LC38D SYNC ; Wait for WD CMPA dppiadb ; Clear inturrupt STB dpdatareg ; Write a byte on track DECA ; decrement byte count BNE LC38D ; continue until count=0 LDA ,X+ ; get next SYNC CMPA dppiadb ; Clear int STA dpdatareg ; write to wd BRA LC38B ; do next block ENDC ; ; Set write precompensation based on track ; DosSetPrecomp LDA dptrkreg ; Get track CMPA #TrackPrecomp ; track < 16 BLS LC3AB ; no : no write precomp LDA DosHWMaskFF48 ; Enable precomp ORA #WPCEn BRA LC3B0 ; Write to controler LC3AB LDA DosHWMaskFF48 ; Turn off precomp ANDA #~WPCEn ;#$EF LC3B0 ifne DragonAlpha LBSR AlphaDskCtl ; Write control reg else STA DskCtl ; Write control reg endc RTS ; ; Dskinit dispatch routine ; ; Syntax : ; DSKINIT (default drive,sides,tracks) ; DSKINIT drive (specified drive, default sides,tracks) ; DSKINIT drive,sides (specified drive,sides default tracks) ; DSKINIT drive,sides,tracks (specified drive,sides,tracks) ; CmdDskInit BEQ LC3D9 ; No parameters : use defaults JSR >GetDriveNoInB ; Get drive no STB <DosLastDrive ; save it JSR >GetCommaThen8Bit ; Get comma, and then no of sides BEQ LC3DE ; Error, use default sides & tracks DECB ; Convert sides to zero base CMPB #$01 ; > 1 sides specified : error & exit BHI LC3D6 STB <DosRecLenFlag ; Save sides JSR >GetCommaThen8Bit ; Get comman, then tracks BEQ LC3E0 ; Error : use default tracks CMPB #$28 ; 40 tracks ? BEQ LC3E2 ; Yes skip on NEG <DosRecLenFlag CMPB #$50 ; 80 tracks ? BEQ LC3E2 ; yes, skip on LC3D6 JMP >DosPRError ; ; Set defaults for format : disk=1,sides=1,tracks=40 ; LC3D9 LDB DosDefDriveNo ; Get default drive STB <DosLastDrive ; Save as last used drive LC3DE CLR <DosRecLenFlag ; 1 side only LC3E0 LDB #$28 ; 40 tracks LC3E2 STB <DosBytesInDTA JSR >DosHookCloseSingle ; Close single file ???? LBNE CmdDskInitErrorExit LDX #$0800 ; Pointer to param area for format STX <DiskBuffPtr JSR DosDoRestore ; Restore to track 0 BNE CmdDskInitErrorExit ; Error : exit LDA #$01 STA <DskSectorNo JSR >DosDoReadSec2 ; Read sector from disk to be formatted ? CMPB #$80 BEQ CmdDskInitErrorExit LC400 CLR <DosNoBytesMove CLR <DskSectorNo JSR >SetupTrackImage JSR >DosDoWriteTrack BCS CmdDskInitErrorExit TST <DosRecLenFlag BEQ LC41F LDA #$01 STA <DosNoBytesMove NEGA STA <DskSectorNo JSR >SetupTrackImage JSR >DosDoWriteTrack BCS CmdDskInitErrorExit LC41F INC <DskTrackNo LDA <DskTrackNo CMPA <DosBytesInDTA BCS LC400 JSR >DosDoRestore BCS CmdDskInitErrorExit LC42C JSR >DosDoSeek BCS CmdDskInitErrorExit CLRA JSR >LC4F2 INC <DskTrackNo LDA <DskTrackNo CMPA <DosBytesInDTA BCS LC42C LDX <DiskBuffPtr LDD <Misc16BitScratch LC441 STD ,X++ CMPX #$0B00 BNE LC441 LDA #$01 STA <DskSectorNo LDA #$14 BSR LC45A DEC <DskSectorNo DEC <DiskBuffPtr LDA #$10 BSR LC460 BRA LC474 LC45A PSHS A BSR LC49B PULS A LC460 STA <DskTrackNo JSR >DosDoWriteSec BCS CmdDskInitErrorExit INC <DskSectorNo INC <DiskBuffPtr JSR >DosDoWriteSec BCS CmdDskInitErrorExit RTS ; ; Exit with error, allow basic to handle it. ; CmdDskInitErrorExit JMP >DosHookSysError LC474 INC <DiskBuffPtr LDX <DiskBuffPtr LDD #$890A LC47B STA ,X LEAX $19,X DECB BNE LC47B BSR LC489 LDA #$14 STA <DskTrackNo LC489 LDD #$1003 STB <DskSectorNo LC48E JSR >DosDoWriteSec BCS CmdDskInitErrorExit INC <DskSectorNo DECA BNE LC48E JMP >LC09D LC49B STA <DskTrackNo LDA #$12 LDB #$5A TST <DosRecLenFlag BEQ LC4A7 ASLB ASLA LC4A7 STA $08FD COMA STA $08FF LDA <DosBytesInDTA STA $08FC TST <DosRecLenFlag BNE LC4BC CMPA #$50 BNE LC4BC ASLB LC4BC COMA STA $08FE LDX <DiskBuffPtr LDU #$0900 LDA #$FF LC4C7 STA ,X+ DECB BNE LC4C7 LDD #$242D TST <DosRecLenFlag BEQ LC4E0 BPL LC4DD LDD #$B4FF LC4D8 STB ,U+ DECA BNE LC4D8 LC4DD LDD #$485A LC4E0 LDU <Misc16BitScratch PSHS A BSR LC4E8 PULS B LC4E8 LDX <DiskBuffPtr ABX LDA #$FC STU ,X++ STA ,X RTS LC4F2 CLR <DskSectorNo TST <DosRecLenFlag BEQ LC4FA BSR LC4FA LC4FA LDA #$12 LC4FC INC <DskSectorNo JSR >DosDoReadSec2 LBCS CmdDskInitErrorExit DECA BNE LC4FC LC508 RTS ; ; Setup format block for write track ; ;LC509 SetupTrackImage LDU <DiskBuffPtr LDX #DDDFD LDY #DDDEA LDB #$0C BSR LC537 LC516 LDX #DDE09 LDB #$06 BSR LC537 LDA #$01 LDB <DskTrackNo STD ,U++ LDB <DosNoBytesMove STB ,U+ LDB ,Y+ STD ,U++ STA ,U+ LDB #$12 BSR LC537 TST ,Y BNE LC516 LDB #$03 LC537 JMP >UtilCopyBXtoU ; ; GetCommaThen8Bit, scan for comma, error if not found, then fetch 8 bit that follows (or error). ; GetCommaThen8Bit JSR <BasChrGetCurr ; Get current basic char BEQ LC508 ; Any left no: return JSR >VarCKComma ; check for comma JMP >Get8BitorError ; go get it ; ; Backup command dispatch routine ; ; Syntax :- ; BACKUP SrcDrive TO Destdrive,heads,tracks ; ; Stack frame as follows : ; 16 bytes cleared on stack, U points to base of this area as with OS-9. ; ; 0,U Drive number of source ? ; 1,U $00 Source track ; 2,U $01 Source sector ; 3,U $DF5A ??? ; 5,U Source buffer addr ; 7,U Drive number of dest ? ; 8,U $00 Dest track ; 9,U $01 Dest sector ???? ; 10,U $DF6D ??? ; 12,U dest buff addr ; 14,U $12 Sector count per track to copy ? ; 15,U Page number of top of usable RAM CmdBackup LEAS -16,S ; Make tempory space on stack TFR S,U ; Point U at base of tempory space (Like OS-9 !) TFR U,D SUBD #$0040 ; reserve room for working stack SUBD <BasVarEnd ; Check that we have suficient memory available LBMI BasOMError ; NO: report ?OM error CMPA #$01 ; At least 1 sector's worth of ram (256 bytes) available LBLT BasOMError ; NO: report ?OM error STA BupAvailPages,U ; Store memory page count of avaiable RAM LDA #$12 ; Sectors per track, initially 18 for SS disk STA BupSecTrk,U LDD <BasVarEnd ; Get end of RAM in use by basic STD BupSrcBuff,U ; save in buffer pointers for source and dest STD BupDestBuff,U LDD #$DF5A ; Error masks ? STD 3,U LDD #$DF6D STD 10,U LDD #$0001 ; Set source and dest track and sector to 0 & 1 STD BupSrcTrk,U STD BupDestTrk,U LDA DosDefDriveNo ; Get default drive no STA BupSrcDrive,U ; save in source drive STA BupDestDrive,U ; and dest LDY #$02D0 ; sector count 720 sectors=ss40 disk JSR <BasChrGetCurr BEQ DoCmdBackup ; No params backup from default drive to default JSR >Get8BitorError CMPB #$04 ; greater than Max drive (4)? LBHI DosDNError STB BupSrcDrive,U ; Save source drive STB BupDestDrive,U ; and default dest to same drive JSR <BasChrGetCurr ; Get current character from basic BEQ DoCmdBackup ; end of line : yes do backup CMPA #$BC ; is this the "TO" token ? BNE CmdBackupErrorExit ; no : error, exit JSR <BasChrGet ; Get next char, skip over "TO" JSR >Get8BitorError ; Get dest drive in B CMPB #$04 ; Invalid drive no ? LBHI DosDNError ; yes : error, exit STB BupDestDrive,U ; Save in Dest driveno BSR GetCommaThen8Bit ; Skip comma, and get next param BEQ DoCmdBackup ; nothing : do backup CMPB #$02 ; 2 sided disk specified ? BEQ BackupDS ; yes backup double sided CMPB #$01 ; 1 sided disk specified ? BEQ BackupSS ; yes backup single sided CmdBackupErrorExit JMP >BasSNError ; error : exit BackupDS TFR Y,D ; Double sector count if double sided LEAY D,Y ASL BupSecTrk,U ; Set sectors per track for DS disk BackupSS JSR >GetCommaThen8Bit ; Get next param (if any) BEQ DoCmdBackup ; none: continue CMPB #$50 ; Is this an 80 track backup ? BEQ Backup80 CMPB #$28 ; Or a 40 track backup ? BEQ DoCmdBackup BRA CmdBackupErrorExit ; neither error and exit Backup80 TFR Y,D ; Double sector count if 80 track LEAY D,Y DoCmdBackup CLRA BupReadFromSrc LEAY 1,Y ; Get sector count LEAX BupSrcDrive,U ; point to source drive on stack frame BSR LC643 ; read 1 sector LC5D6 LEAY -1,Y ; decrement sector count BNE LC5E0 ; if more sectors, do next BSR BupWriteToDest ; no : write final sectors to destination LEAS $10,U ; Clear stack frame LC5DF RTS ; return to caller LC5E0 CMPA BupAvailPages,U ; Filled all available RAM pages ? BNE LC5F2 ; no : do next sector BSR BupWriteToDest ; Yes : write to destination PSHS D LDD <BasVarEnd ; Get end of basic storage STD BupDestBuff,U ; Save in source and dest buffer pointers STD BupSrcBuff,U PULS D BRA BupReadFromSrc ; Do next sector LC5F2 LDB #$02 BSR LC608 INCA BRA LC5D6 BupWriteToDest TSTA BEQ LC5DF LEAX BupDestDrive,U ; Point to dest drive vars BSR LC643 DC600 LDB #$03 LC602 BSR LC608 DC604 DECA BNE LC602 LC607 RTS LC608 PSHS D LDA BupDrive,X ; Get drive STA <LastActiveDrv ; Set last active drive LDD BupBuff,X STD <DiskBuffPtr ; Setup disk buffer pointer LDD BupTrk,X STD <DskTrackNo ; and disk track no LDB 1,S ; Get function, read or write JSR >DosDoFuncinB BCC LC631 ; no error continue STB DosErrorCode ; Temp storage (error code from dos) LDA 1,S ; Get function, read or write CMPA #DosFnReadSec ; Read ? BRA LC62B PULS D,X ; FCB $35 ; FCB $16 JSR BupWriteToDest ; FCB $BD ; FCB $C5 ; FCB $F9 LC62B LDB DosErrorCode ; Retrieve error code JMP >DosHookSysError LC631 INC 2,X ; Increment sector number LDA 2,X ; check sector number CMPA 14,U ; Done all sectors on track ? BLS LC63F ; No: do next sector LDA #$01 ; Reset sector count to 1 STA 2,X INC 1,X ; Increment track count LC63F INC 5,X ; Move to next page of buffer PULS D,PC ; restore and return LC643 LDB ,U ; get source drive CMPB 7,U ; same as dest drive ? BNE LC607 ; no : continue PSHS A,X,Y,U JSR >TextCls ; clear screen LDX 1,S ; get message pointer LDX 3,X JSR >TextOutString ; Print message (insert source/insert dest) LDX #MessPressAnyKey JSR >TextOutString ; Print press any key JSR >TextWaitKeyCurs2 ; Wait for a kepress JSR >TextCls PULS A,X,Y,U,PC ; ; Get8BitorError, get non zero 8 bit value in B, or generate error ; Get8BitorError PSHS Y,U JSR >VarGet8Bit ; Get 8 bit value into B TSTB ; B non zero ? BNE LC66E JMP >BasFCError ; No : error LC66E PULS Y,U,PC ; Restore and return LC670 CMPA #$FF LBEQ BasSNError SUBA #$CE BPL LC67D LC67A JMP >BasSNError LC67D CMPA #$1A BCC LC687 LDX #CommandDispatchTable JMP >BasDoDipatch LC687 JMP [>NextResJump] ; Jump to user reserved word handler >$0137 LC68B SUBB #$44 BPL LC691 BRA LC67A LC691 CMPB #$0E BCC LC69D LDX #FunctionDipatchTable JSR [B,X] JMP >VarGetExprCC LC69D JMP [>NextFuncsJump] ; Jump to user function handler >$013C LC6A1 LDX #Buff1Details LC6A4 JSR >LD2E2 BNE DosHookSysError CLR 2,X LEAX 7,X CMPX #DosCurDriveInfo ; $0650 BCS LC6A4 LC6B2 RTS ; ; Get drive no in B, returns drive no (from command) in B, ; or causes error if (drive < 0 ) or (drive > 4) ; GetDriveNoInB JSR >VarGet8Bit ; Get 8 bit var TSTB BMI DosDNError ; Minus, invalid drive BNE LC6BC ; greater than 0, check < 4 INCB ; =0 increment so drive 0 = drive 1 LC6BC CMPB #$04 ; Drive in range BLS LC6B2 ; Yes : return it in B DosDNError LDB #$28 FCB Skip2 ; CMPX DosPRError LDB #$A4 DosHookSysError STB DosErrLast ; save last error code LDX <BasCurrentLine ; Get current line no STX DosErrLineNo ; save for ERR routine JSR >BasResetStack ; reset basic stack CLR <DosIOInProgress ; Flag no IO in progress CLR <TextDevN ; Set device no back to console TST DosErrGotoFlag ; Do we have an error handler ? BPL LC6DF ; Yes, handle errors LDX <BasCurrentLine ; Get current line no LEAX 1,X BNE LC6F9 LC6DF JSR >TextOutCRLF ; Output a return JSR >CasMotorOff ; turn off cassette motor JSR >SndDisable ; disable cassette sound JSR >TextOutQuestion ; output '?' LDX #BasErrorCodeTable ; Point to error code table $82A9 LDB DosErrLast ; Get last error code BPL LC6F6 LDX #DosErrorCodeTable-$80 ; Get pointer to error table ! LC6F6 JMP >SysErr2 ; Jump to basic Error handler LC6F9 LDX #BasBRARun ; Go back to main interpreter loop $84DA DC6FC PSHS X LDD DosErrDestLine STD <BasTempLine JMP >BasSkipLineNo ; ; New reset vector ; ResetVector NOP ; Main ROM checks for reset->NOP CLRA ; Reset DP=0 TFR A,DP JSR >LC09D ; Reset WD, and various Dos vars. CLR DosErrorMask ; reset various flags CLR DosTimeout CLR DosAutoFlag LDA #$35 ; Re-enable NMI STA PIA0CRB JMP >WarmStart ; Jump back to Main ROM reset routine ; ; NMI vector, called to break out of read & write loops between 6809 & WD ; This allows the IO routines to handle sectors of all lengths. ; NMISrv LDA dpcmdreg ; Read status register. CLRB ; Reset DP=0 TFR B,DP LEAS 12,S ; Drop registers from stack TSTA ; Setup CC LC726 RTS ; Return to caller ; ; New IRQ vector, used to count down and shut off drives. ; IRQSrv CLRA ; Reset DP=0 TFR A,DP TST <DosIOInProgress ; Doing IO ? BNE LC748 ; Yes: don't time out LDA DosTimeout ; Get timeout byte BEQ LC748 ; Already timed out : exit DECA ; Decrement timeout count STA DosTimeout BNE LC748 ; not zero, don't timeout yet BSR SuperDosSyncDir ; syncronsise directory BNE LC74B ; Error : report it LDA DosHWMaskFF48 ; turn off motor in hw byte IFNE RSDos ANDA #~DriveOffMaskT ; On RSDos turn off motor & deslect drives ELSE ANDA #~MotorOn ENDC STA DosHWMaskFF48 ; Just turn off drives on Dragon ifne DragonAlpha LBSR AlphaDskCtl ; Actually turn off motor else STA DskCtl ; Actually turn off motor endc LC748 JMP >BasIRQVec ; Jump to BASIC IRQ LC74B JMP >DosHookSysError ; Jump to system error trap LC74E TFR S,D SUBD #$0100 SUBD <BasVarEnd BMI LC75B CLRB TSTA BNE LC726 LC75B JMP >BasOMError ; ; Copy directory from track 20 to track 16. ; SuperDosSyncDir JSR >LC6A1 LEAS -8,S ; Make room on stack LEAU ,S ; Point U at stack frame LEAY 4,U LDX #DosDiskBuffBase ; Point at tempory buffer area STX <DiskBuffPtr CLR 2,U LDB <DosLastDrive ; Get last accessed drive STB 1,U ; Save it LDB #$01 STB ,U CLR <DosLastDrive LDX #DosDirSecStatus-1 ; $06AA LC77B LDB #SectorsPerTrack ; Sector count STB 3,U INC <DosLastDrive LC781 LDB 3,U LDA B,X BITA ,U BEQ LC7A7 COMA ANDA B,X STA B,X INC 2,U STB <DskSectorNo STB ,Y+ LDB #DirPrimary ; Track 20 STB <DskTrackNo JSR >DosDoReadSec ; Go read sector BNE LC7BE ; Error ! INC <DiskBuffPtr ; use next disk buffer LDB 2,U ; Check to see if we have filled all buffers CMPB #$04 BCS LC7A7 BSR LC7C1 LC7A7 DEC 3,U BNE LC781 TST 2,U BEQ LC7B1 BSR LC7C1 LC7B1 ASL ,U LDA ,U CMPA #$08 BLS LC77B LDA SyncDrive,U ; Restore last used drive STA <DosLastDrive CLRB ; Flag no error LC7BE LEAS 8,U ; Drop stack frame RTS LC7C1 LDA #DirBackup ; Backup track no STA <DskTrackNo LC7C5 DEC <DiskBuffPtr LEAY -1,Y LDA ,Y STA <DskSectorNo ; Pickup sector no JSR >DosDoWriteSec ; Go write it BEQ LC7D5 LEAS 8,U RTS LC7D5 DEC 2,U BNE LC7C5 RTS FIRQSrv TST PIACRA ; Clear Inturrupt conditions TST PIACRB RTI ; and return DosValidateAndOpen BSR SuperDosValidFilename ; Validate filename BNE LC857 ; Error : exit JMP >SuperDosOpenFile ; Open file if valid ; ; Validate filename and copy to current drive block ; ; On entry: ; X points to filename e.g. '3:FILENAME.EXT' ; B length of filename e.g. 0x0e ; Y points to default extension to use if none is given e.g. 'DAT'. ; Use ' ' for no default extension ; On Return: ; Filename appears at $0650-$065a ; CC.Z clear on error ; B contains error code ; U $065b always (SuperDosE6) ; SuperDosValidFilename LDA DosDefDriveNo STA DosCurDriveNo ; Set current drive number, default if non specified CLR DosCurCount LDU #DosCurDriveInfo ; Point at current drive info LDA #$07 ; Zero out first 8 bytes (filename) LC7F6 CLR A,U DECA BPL LC7F6 LDA 2,Y ; Transfer extension into current details STA DosCurExtension+2 ; $065A LDA 1,Y STA DosCurExtension+1 ; $0659 LDA ,Y STA DosCurExtension ; $0658 CMPB #MaxFilenameLen ; Filename too long ? BHI LC855 ; Yep : error TSTB ; Too short ? BEQ LC855 ; Yep : error CMPB #$03 ; Long enough to contain drive no ? BCS LC83D ; nope : skip on ; Because of the order of compare a drive letter at the END of the filename always ; takes presedence, this would only be siginificant if the filename where something like ; '1:2' which would access a file called '1' on drive 2, and NOT 2 on drive 1 SUBB #$02 ; Look for drive no at end of filename LDA B,X CMPA #': ; Seperator present ? $3A BNE LC823 ; No skip on INCB LDA B,X ; Get drive no INCB BRA LC82D ; Go process it LC823 ADDB #$02 ; Check for drive at begining of path LDA 1,X CMPA #': ; Seperator present ? $3A BNE LC83D ; nope, use default drive LDA ,X++ ; Get ascii drive no LC82D SUBA #$30 ; Work out drive number BLS LC835 CMPA #MaxDriveNo ; Drive valid ? BLS LC838 LC835 LDB #$1C ; Error ! RTS LC838 STA DosCurDriveNo ; Set current drive if specified SUBB #$02 ; Parse filename looking for extension seperator LC83D LDA ,X+ ; Get next char DECB ; Decrement path count BMI LC8A6 ; Reached end : yes skip CMPA #'/ ; Check for slash $2F BEQ LC84A CMPA #'. ; Check for period $2E BNE LC866 LC84A CMPU #DosCurDriveInfo ; $0650 BEQ LC855 TST DosCurCount ; First pass ? BEQ LC858 ; yes : skip on LC855 LDB #$96 ; Error ? LC857 RTS LC858 INC DosCurCount ; Mark second pass LDU #DosCurExtension ; $0658 CLR ,U ; Zero out extension CLR 1,U CLR 2,U BRA LC83D ; Validate filename chars LC866 CMPA #'A ; $41 BCS LC87A ; Below, check if still valid CMPA #'Z ; $5A BLS LC886 ; valid, skip on SUBA #$20 ; Convert to lower case if upper CMPA #'A ; $41 BCS LC855 ; Invalid, return error CMPA #'Z ; $5A BLS LC886 ; Valid: skip on BRA LC855 LC87A CMPA #'- ; $2D BEQ LC886 ; Valid skip on CMPA #'0 ; $30 BCS LC855 ; Invalid : error CMPA #'9 ; $39 BHI LC855 ; Invalid : error LC886 STA ,U+ ; Save char in path CMPU #DosCurDriveNo ; Path full ? BNE LC893 ; nope : skip TSTB ; Done all path chars ? BNE LC855 ; nope : error ! BRA LC8A6 LC893 CMPU #DosCurExtension ; Reached extension ? $0658 BNE LC83D LDA ,X+ ; Get next DECB ; Dec count BMI LC8A6 ; Done, return CMPA #'. ; Check for seperator $2E BEQ LC84A ; yep loop back CMPA #'/ ; Check for seperator $2F BEQ LC84A ; Yep loop back LC8A6 CLRB RTS ; ; Open a file and copy dir entry into FCB. ; ; On entry: ; Filename at $0650 ?? ; Returns: ; CC.Z clear on error ; A FCB number (0-9) ; B contains error code ; SuperDosOpenFile LDX #DosFCB0Addr ; Point to first FCB CLR <DosCurrCtrlBlk LDD DosCurDriveInfo ; Get first 2 bytes of current drive info LC8B0 CMPD ,X ; Does this FCB point to it ? BNE LC8CB ; Nope : check next ; Found matching first 2 bytes of name in an FCB LDU #DosCurDriveInfo+2 ; Check bytes 2..end of filename LEAY 2,X ; Compare from byte 2 of FCB LDB #$0A ; Do 10 bytes, rest of filename + ext LC8BC LDA ,U+ ; Get a byte from current CMPA ,Y+ ; compare to FCB BNE LC8C8 ; Don't match : exit check DECB ; Decrement counter BNE LC8BC ; Not at end : do next JMP >LC973 ; Found it, already have an FCB for it ; Move to check next FCB LC8C8 LDD DosCurDriveInfo ; Re-get first 2 chars of current filaname LC8CB LEAX DosFCBLength,X ; Skip to next FCB INC <DosCurrCtrlBlk ; Set current control block CMPX #DosFCBEnd ; End of blocks ? BCS LC8B0 ; No, loop back and check this block CLR <DosCurrCtrlBlk ; Set current block to zero LDX #DosFCB0Addr ; Point at first FCB LC8DA TST ,X ; FCB in use ? BEQ LC8EB ; No : skip on LEAX DosFCBLength,X ; Check next FCB INC <DosCurrCtrlBlk CMPX #DosFCBEnd ; Done all FCBs BCS LC8DA ; No : check next, yes error, can't open file, no free FCBS LDB #$A2 LC8EA RTS LC8EB LDB #$0C ; Copy 12 characters of filename TFR X,Y ; Point Y at selected FCB LDU #DosCurDriveInfo ; Point at current info LC8F2 LDA ,U+ ; Copy filename STA ,Y+ DECB ; Dec count BNE LC8F2 ; if not all done : do next STA <DosLastDrive ; Save current drive ; Note in disassembled source, the following was LDU #$0616, which is part of the error line ! ; This makes no sense, and is Drv0Details, in DragonDos source, I think I just fixed a 20 year old ; bug !!!!!! LDU #Drv0Details ; Get drive details LDB #$06 ; 6 bytes/drive MUL LEAU D,U ; Point at drive detail block INC 5,U ; Increment usage/open file count LDB #$13 ; Clear rest of FCB LC907 CLR ,Y+ DECB ; Dec counter BNE LC907 ; Loop if more LDA #$80 STA 15,X CLR $0681 JSR >DosGetDiskGeometry BNE LC8EA LDY ,X LEAY 2,Y LDA #$10 STA DosCurCount LC922 STY $065C JSR >SuperDosFindAndRead BNE LC8EA LDX 5,X LEAU $00FA,X STU $065E LC934 LDA ,X BITA #$81 BNE LC954 LDD DosCurDriveInfo CMPD 1,X BNE LC954 LDU #$0652 LEAY 3,X LDB #$09 LC949 LDA ,U+ CMPA ,Y+ BNE LC954 DECB BNE LC949 BRA LC980 LC954 LDA ,X BITA #$08 BNE LC970 INC $0681 LEAX $19,X CMPX $065E BCS LC934 LDY $065C LEAY 1,Y DEC DosCurCount BNE LC922 LC970 JSR >DosFCBNoToAddr LC973 CLRB TST 15,X BPL LC97A LDB #$A0 LC97A LEAX 12,X LDA <DosCurrCtrlBlk TSTB RTS LC980 PSHS X JSR >DosFCBNoToAddr PULS Y LDA $0681 STA $1D,X LDA ,Y STA 15,X LDD 12,Y STD $15,X LDA 14,Y STA $17,X STA $19,X CLR $18,X CLR $13,X CLR $14,X LDD 15,Y STD $1A,X LDA $11,Y STA $1C,X LDD #$FFFF STD $10,X STA $12,X BRA LC973 ; ; Read some data from a file into memory ; SuperDosFRead CLR <DosIRQTimeFlag STA <DosCurrCtrlBlk BRA LC9CA LC9C3 LDA #$01 FCB Skip2 LC9C6 LDA #$FF STA <DosIRQTimeFlag LC9CA STY $0661 LBEQ LCAB0 STU $0669 STB $0663 PSHS X JSR >DosFCBNoToAddr LDA 11,X STA <DosLastDrive TST <DosIRQTimeFlag BNE LC9F0 LDD $0661 ADDD 13,X BCC LC9EE INC 12,X LC9EE STD 13,X LC9F0 PULS X LDB $0663 LC9F5 CLRA NEGB BNE LC9FA INCA LC9FA CMPD $0661 BLS LCA03 LDD $0661 LCA03 PSHS D,X LDU $0669 JSR >LCAB2 BNE LCA1B TFR D,Y LDA 15,X BITA #$02 BEQ LCA1E TST <DosIRQTimeFlag BEQ LCA1E LDB #$98 LCA1B LEAS 4,S RTS LCA1E LDX 2,S TST 1,S BNE LCA4E TST <DosIRQTimeFlag BEQ LCA2F BPL LCA34 JSR >LD330 BRA LCA37 LCA2F JSR >SuperDosReadAbsSector BRA LCA37 LCA34 JSR >SuperDosWriteAbsSector LCA37 BNE LCA1B INC 2,S LDX $0669 LEAX 1,X STX $0669 DEC $0661 LDD $0661 PULS D,X BNE LC9F5 RTS LCA4E TST <DosIRQTimeFlag BMI LCA93 JSR >SuperDosFindAndRead BNE LCA1B STX $0667 LDY 2,S LDB $0663 TST <DosIRQTimeFlag BEQ LCA87 LDA #$FF STA 2,X LDX 5,X ABX LDB 1,S LCA6D LDA ,Y+ STA ,X+ DECB BNE LCA6D TFR X,D TSTB BNE LCA93 LDX $0667 PSHS Y JSR >LD2E2 PULS Y BNE LCA1B BRA LCA93 LCA87 LDX 5,X ABX LDB 1,S LCA8C LDA ,X+ STA ,Y+ DECB BNE LCA8C LCA93 LDX $0669 LEAX 1,X STX $0669 TFR Y,X LDD $0661 SUBD ,S++ STD $0661 LEAS 2,S BEQ LCAB0 CLR $0663 CLRB JMP >LC9F5 LCAB0 CLRB RTS LCAB2 JSR >DosFCBNoToAddr LCAB5 TFR U,D SUBD $13,X BCS LCAC9 TSTA BNE LCAC9 CMPB $17,X BCC LCAC9 ADDD $15,X BRA LCADB LCAC9 TFR U,D SUBD $18,X BCS LCADE TSTA BNE LCADE CMPB $1C,X BCC LCADE ADDD $1A,X LCADB ORCC #$04 RTS LCADE PSHS U BSR LCB20 BNE LCAEF LDD $066B CMPD $066D BHI LCAF1 LDB #$9A LCAEF PULS U,PC LCAF1 SUBB 2,Y SBCA #$00 STD $13,X LDA 2,Y STA $17,X LDD ,Y STD $15,X TFR Y,D PSHS U SUBD ,S++ PULS U CMPB #$13 BCC LCB1E LDA 5,Y STA $1C,X LDD 3,Y STD $1A,X LDD $066B STD $18,X LCB1E BRA LCAB5 ; ; Entry : X=Address of a FCB ; B=File number (on disk), also in $1d,X ; LCB20 PSHS X CLR $066C CLR $066B STU $066D LDB FCBDiskFileNo,X STB DosCurFileNo JSR >SuperDosGetDirEntry ; Go get directory entry BNE LCB7C ; Error : exit TFR X,U PULS X LEAY 12,U LDB #$04 LCB3E LDA ,U ANDA #$20 BEQ LCB47 LDA $18,U LCB47 PSHS D LCB49 LDD $066B ADDB 2,Y ADCA #$00 STD $066B CMPD $066D BHI LCB7B LEAY 3,Y DEC 1,S BNE LCB49 LDB ,S BEQ LCB79 LEAS 2,S STB DosCurFileNo PSHS X JSR >SuperDosGetDirEntry TFR X,U PULS X BNE LCB7E LEAY 1,U LDB #$07 BRA LCB3E LCB79 LEAY -3,Y LCB7B CLRB LCB7C LEAS 2,S ; Drop stack frame LCB7E RTS ; Return ; ; Write data from memory to file, verify if verify on. ; SuperDosFWrite STA <DosCurrCtrlBlk STX $0671 STU $0673 STY $0675 STB $0677 JSR >DosFCBNoToAddr LDB 11,X STB <DosLastDrive LCB95 JSR >SuperDosGetFLen BEQ LCBA8 CMPB #$9C BEQ LCB9F RTS LCB9F LDA <DosCurrCtrlBlk JSR >SuperDosCreateFile BNE LCB7E BRA LCB95 LCBA8 CMPU $0675 BHI LCBB8 BCS LCBB5 CMPA $0677 BCC LCBB8 LCBB5 LDB #$9A LCBB7 RTS LCBB8 PSHS A LDD $0673 ADDB $0677 ADCA $0676 PSHS B TFR A,B LDA $0675 ADCA #$00 PSHS U SUBD ,S++ TFR B,A PULS B BHI LCBDE BCS LCBE6 SUBB ,S BCC LCBE2 BRA LCBE6 LCBDE SUBB ,S SBCA #$00 LCBE2 BSR LCC12 BNE LCC0F LCBE6 LEAS 1,S LDB $0677 LDX $0671 LDY $0673 LDU $0675 JSR >LC9C3 BNE LCBB7 TST DosVerifyFlag BEQ LCBB7 LDB $0677 LDX $0671 LDY $0673 LDU $0675 JMP >LC9C6 LCC0F LEAS 1,S RTS LCC12 LEAS -12,S STD ,S STD 10,S LDA #$01 STA <DosIOInProgress JSR >DosGetDiskGeometry LBNE LCD08 STX 8,S JSR >DosFCBNoToAddr LDB $1E,X JSR >SuperDosGetDirEntry LBNE LCD08 STX 4,S LDU DosCurDirBuff LDA #$FF STA 2,U CLRA LDB $18,X BNE LCC42 INCA LCC42 ADDD ,S TSTB BNE LCC48 DECA LCC48 STD ,S TSTA LBEQ LCCF0 LDB #$04 LEAY 12,X LDA ,X BITA #$01 BEQ LCC5D LEAY 1,X LDB #$07 LCC5D TST 2,Y BNE LCC75 LDD #$FFFF STD 6,S LEAY -3,Y STY 2,S LDX 8,S TST 2,X LBNE LCD0E BRA LCCB3 LCC75 TST 2,Y BEQ LCC7E LEAY 3,Y DECB BNE LCC75 LCC7E LEAY -3,Y LDD ,Y ADDB 2,Y ADCA #$00 STD 6,S STY 2,S LDX 8,S TST 2,X BEQ LCCB3 LDD 6,S SUBD 3,X BEQ LCCC3 JSR >LCD57 BEQ LCCA2 CMPB #$94 BNE LCD08 BRA LCD0E LCCA2 LDX 8,S PSHS A,U LDB 2,X LDX 3,X JSR >LD03B PULS A,U BNE LCD08 BRA LCCB8 LCCB3 JSR >LCD57 BNE LCD08 LCCB8 LDX 8,S STU 3,X STA 2,X CMPU 6,S BNE LCD0E LCCC3 LDA ,S CMPA 2,X BCS LCCCB LDA 2,X LCCCB LDY 2,S PSHS A ADDA 2,Y BCC LCCD8 PULS A BRA LCD0E LCCD8 STA 2,Y LDA 2,X SUBA ,S STA 2,X LDD 3,X ADDB ,S ADCA #$00 STD 3,X LDA 1,S SUBA ,S+ STA ,S BNE LCCB3 LCCF0 LDX 4,S TFR X,U JSR >DosFCBNoToAddr LDD 10,S ADDD $11,X BCC LCD01 INC $10,X LCD01 STD $11,X STB $18,U CLRB LCD08 LEAS 12,S CLR <DosIOInProgress TSTB RTS LCD0E LDD 2,S TFR D,Y SUBD 4,S CMPB #$13 BCC LCD23 LEAY 3,Y STY 2,S LCD1D LDD 3,X STD ,Y BRA LCCC3 LCD23 LDA #$01 JSR >LD123 BNE LCD08 LDY 4,S STA $18,Y LDB ,Y ORB #$20 STB ,Y LDB #$FF STB 2,X LDB #$01 STB ,U STU 4,S JSR >DosFCBNoToAddr STA $1E,X LEAY $19,U LDB #$18 LCD4B CLR ,-Y DECB BNE LCD4B STY 2,S LDX 8,S BRA LCD1D LCD57 STS $0601 LEAS -9,S CLR 4,S JSR >DosGetDiskGeometry LBNE LCE5A LDY ,X LDU $11,S STU 5,S LEAX 1,U BEQ LCD81 BSR LCDB2 BNE LCDAF CMPU #$05A0 BCS LCD81 LDU #$058E BRA LCDA2 LCD81 LEAU ,Y LCD83 LDA #$FF STA ,S LCD87 LEAU -$12,U STU -2,S BMI LCD9A BSR LCDB2 BEQ LCD83 TST ,S BPL LCDAF STU ,S BRA LCD87 LCD9A LDU ,S STU -2,S BPL LCDAF LEAU ,Y LCDA2 LEAU $12,U CMPU #$0B40 BHI LCDB5 BSR LCDB2 BEQ LCDA2 LCDAF JMP >LCE34 LCDB2 JMP >LCE60 LCDB5 LDA #$FF STA 7,S LDA 4,S LCDBB LDU <Misc16BitScratch LSRA BCS LCDC3 LDU #$05A0 LCDC3 BSR LCDB2 LDB #$B4 LCDC7 LDA ,X+ BNE LCDD2 LEAU 8,U DECB BNE LCDC7 BRA LCE13 LCDD2 CLRB STB 8,S PSHS U LCDD7 INCB LDA ,X+ INCA BEQ LCDD7 CMPB 10,S BLS LCDE5 STB 10,S STU ,S LCDE5 LEAX -1,X LDA #$08 MUL LEAU D,U LCDEC CLRB LDA ,X+ BNE LCDD7 LEAU 8,U TFR X,D CMPB #$B4 BCS LCDEC PULS U BSR LCE60 LEAU 8,U LDA ,X LDB 8,S CMPB #$01 BHI LCE0C LCE07 LEAU -1,U ASLA BCC LCE07 LCE0C ASLA BCC LCE13 LEAU -1,U BRA LCE0C LCE13 CMPB #$02 BCC LCE34 CMPB 7,S BHI LCE34 LDA 7,S INCA BNE LCE2A STB 7,S STU 5,S LDA 4,S EORA #$03 BRA LCDBB LCE2A LDU 5,S BSR LCE60 BNE LCE34 LDB #$94 BRA LCE5A LCE34 BSR LCE60 CLRB LCE37 INCB BEQ LCE51 PSHS A COMA ANDA ,X STA ,X PULS A ASLA BCC LCE4A LDA #$01 LEAX 1,X LCE4A BITA ,X BNE LCE37 TFR B,A ;LCE51 EQU *+1 ; CMPX #$86FF FCB Skip2 LCE51 LDA #$FF LDX 2,S LDB #$FF STB 2,X CLRB LCE5A LDS $0601 TSTB RTS LCE60 PSHS Y,U LDA #$01 CMPU #$05A0 BCS LCE71 LEAY 1,Y LEAU $FA60,U ASLA LCE71 PSHS U BITA 12,S BNE LCE84 STA 12,S JSR >SuperDosFindAndRead BNE LCE5A STX 10,S LDA #$FF STA 2,X LCE84 LDX 10,S LDX 5,X PULS D LSRA RORB LSRA RORB LSRA RORB LDA 3,S ANDA #$07 LDU #$A672 NEGA LDA A,U ABX BITA ,X PULS Y,U,PC ; ; Get length of a file ; SuperDosGetFLen STA <DosCurrCtrlBlk BSR DosFCBNoToAddr TST 15,X BPL LCEAA LDB #$9C LCEA9 RTS LCEAA LDA $12,X LDU $10,X LEAY 1,U BNE LCED0 JSR >LCB20 BNE LCEA9 LDB DosCurFileNo STB $1E,X LCEBF LDA $18,U STA $12,X LDU $066B TSTA BEQ LCECD LEAU -1,U LCECD STU $10,X LCED0 CLRB RTS ; ; Converts current FCB number in DosCurrCtrlBlk to the FCB's address ; Exits with : ; X=FCB address ; DosFCBNoToAddr PSHS D LDA <DosCurrCtrlBlk ; Get current FCB no LDB #DosFCBLength ; FCB len ? MUL ; Work out offset to FCB TFR D,X LEAX DosFCB0Addr,X ; Get offset of FCB PULS D,PC ; ; Close all open files. ; SuperDosCloseAll LDA #$09 STA <DosCurrCtrlBlk LCEE5 BSR DosFCBNoToAddr LDA 11,X CMPA <DosLastDrive BNE LCEF1 BSR LCEF9 BNE LCEA9 LCEF1 DEC <DosCurrCtrlBlk BPL LCEE5 LCEF5 CLRB RTS ; ; Close a single file ; SuperDosCloseFile STA <DosCurrCtrlBlk LCEF9 BSR DosFCBNoToAddr TST ,X BEQ LCEF5 LDA <DosLastDrive PSHS A LDA 11,X STA <DosLastDrive CLR ,X JSR >DosGetDiskGeometry BNE LCF34 TST 5,X BEQ LCF19 DEC 5,X BEQ LCF19 CLRB BRA LCF34 LCF19 LDB 2,X BEQ LCF2A PSHS X LDX 3,X JSR >LD03B PULS X BNE LCF34 CLR 2,X LCF2A JSR >SuperDosSyncDir LDU #DosD0Online-1 LDA <DosLastDrive CLR A,U LCF34 PULS A STA <DosLastDrive TSTB LCF39 RTS ; ; Create a file, with backup. ; SuperDosCreateFile STA $067D JSR >DosFCBNoToAddr STX $0678 LDB #$0C LDU #DosCurDriveInfo LCF48 LDA ,X+ STA ,U+ DECB BNE LCF48 LDD -4,U STD $067A LDA -2,U STA $067C LDD #$4241 STD -4,U LDA #$4B STA -2,U TST 3,X BMI LCF92 JSR >SuperDosOpenFile CMPB #$A0 BEQ LCF74 TSTB BNE LCF39 BSR SuperDosDeleteFile BNE LCF39 LCF74 JSR >LCEF9 NOP LDA $067D TST [$0678] BEQ LCF92 JSR >SuperDosRename BEQ LCF8A CMPB #$9C BNE LCF39 LCF8A LDA $067D JSR >SuperDosCloseFile BNE LCF39 LCF92 LDD $067A STD $0658 LDA $067C STA $065A JSR >SuperDosOpenFile BEQ LCFA7 CMPB #$A0 BNE LCF39 LCFA7 STA <DosCurrCtrlBlk JSR >DosFCBNoToAddr TST 15,X BMI LCFB3 LDB #$9E LCFB2 RTS LCFB3 CLRA JSR >LD123 BNE LCFB2 JSR >DosFCBNoToAddr STA FCBDiskFileNo,X STA $1E,X LDB #$1C LCFC4 CLR B,X DECB CMPB #$0C BCC LCFC4 LDB #$18 LCFCD CLR B,U DECB BPL LCFCD LEAU 1,U LDB #$0B LCFD6 LDA ,X+ STA ,U+ DECB BNE LCFD6 CLRB RTS ; ; Delete a file from disk. ; SuperDosDeleteFile JSR >LD0E4 BNE LCFB2 PSHS X LDB FCBDiskFileNo,X JSR >LD237 BNE LD035 TFR X,U PULS X LEAY 12,U LDB #$04 LCFF6 LDA ,U ANDA #$20 BEQ LCFFF LDA $18,U LCFFF PSHS D LDB #$81 STB ,U PSHS X LD007 LDX ,Y++ LDB ,Y+ BEQ LD017 PSHS Y BSR LD03B PULS Y LBNE LCA1B LD017 DEC 3,S BNE LD007 PULS X LDB ,S BEQ LD034 LEAS 2,S PSHS X JSR >LD237 TFR X,U PULS X BNE LCFB2 LEAY 1,U LDB #$07 BRA LCFF6 LD034 CLRB LD035 CLR <DosIOInProgress LEAS 2,S TSTB RTS LD03B CLRA PSHS A PSHS D,X JSR >DosGetDiskGeometry BNE LD0C2 LDY ,X LDD 2,S SUBD #$05A0 BCS LD05A LEAY 1,Y STD 2,S ADDD ,S SUBD #$05A0 BCC LD0C0 LD05A LDD 2,S ADDD ,S SUBD #$05A0 BCS LD06A STB 4,S NEGB ADDB 1,S STB 1,S LD06A JSR >SuperDosFindAndRead BNE LD0C2 LDA #$FF STA 2,X LDD 2,S LSRA RORB ROR ,S LSRA RORB ROR ,S LSRA RORB ROR ,S LDX 5,X ABX LDB #$01 LDA ,S BEQ LD08F LD08A ASLB SUBA #$20 BNE LD08A LD08F STB ,S LDB 1,S LD093 LDA ,S ORA ,X STA ,X DECB BEQ LD0B4 ASL ,S BCC LD093 LDA #$01 STA ,S LEAX 1,X LD0A6 CMPB #$10 BCS LD093 LDA #$FF STA ,X+ STA ,X+ SUBB #$10 BNE LD0A6 LD0B4 LDX #$05A0 LEAS 4,S LDB ,S+ BEQ LD0C4 JMP >LD03B LD0C0 LDB #$90 LD0C2 LEAS 5,S LD0C4 RTS ; ; Protect/unprotect a file. ; SuperDosProtect STA <DosCurrCtrlBlk JSR >DosFCBNoToAddr LDA 15,X BMI LD0F4 TSTB BEQ LD0D4 ORA #$02 ;LD0D4 EQU *+1 ; CMPX #$84FD FCB Skip2 LD0D4 ANDA #$FD STA 15,X LDB FCBDiskFileNo,X JSR >LD237 BNE LD0C4 STA ,X CLRB RTS LD0E4 STA <DosCurrCtrlBlk JSR >DosFCBNoToAddr LDA 15,X BMI LD0F4 BITA #$02 BEQ LD122 LDB #$98 RTS LD0F4 LDB #$9C RTS ; ; Rename a file. ; SuperDosRename BSR LD0E4 BNE LD122 LDB #$0B LDU #DosCurDriveInfo LD100 LDA ,U+ STA ,X+ DECB BNE LD100 LEAX -11,X LDB FCBDiskFileNo,X JSR >LD237 BNE LD122 LDU #DosCurDriveInfo LDB #$0B LEAX 1,X LD118 LDA ,U+ STA ,X+ DECB BNE LD118 CLR <DosIOInProgress CLRB LD122 RTS LD123 CLRB STD $067D BSR DosGetDiskGeometry BNE LD122 LDX ,X PSHS X LEAX 2,X LD131 STX DosCurLSN TFR X,Y JSR >SuperDosFindAndRead BNE LD170 LDU 5,X LDB #$0A TST $067D BEQ LD149 CLR $067D BRA LD14D LD149 LDA ,U BMI LD168 LD14D INC $067E LEAU $19,U DECB BNE LD149 JSR >LDFF3 LEAX 1,X TFR X,D SUBD ,S CMPB #$12 BCS LD131 LEAS 2,S LDB #$92 RTS LD168 LDA #$FF STA 2,X LDA $067E CLRB LD170 LEAS 2,S RTS ; ; Get free space on disk ; SuperDosGetFree BSR DosGetDiskGeometry BNE LD187 LDY ,X LDX <Misc16BitScratch BSR LD188 BNE LD187 LEAY 1,Y BSR LD188 BNE LD187 CLRB LD187 RTS LD188 PSHS X JSR >SuperDosFindAndRead BNE LD170 LDU 5,X PULS X LDB #$B4 LD195 LDA ,U+ LD197 LSRA BCC LD19C LEAX 1,X LD19C TSTA BNE LD197 DECB BNE LD195 RTS ; ; Get geometry for a disk and set the apropreate low memory vars. ; ; Entry : DosLastDrive, set to last drive ; ; Exit : Drive vars setup in low ram, to be same as disk in drive. ; X=Address of buffer detail entry for buffer to use DosGetDiskGeometry LDX #Drv0Details ; Point at drive details LDU #DosD0Online-1 ; Point at drive online table LDB #DrvDeatailLen ; Get drive table entry len LDA <DosLastDrive ; Get last used drive LEAU A,U ; Point U at drive online flag DECA ; Make zero based MUL ; Calculate offset of drive we need LEAX D,X TST ,U ; Is drive online ? BNE LD1FF ; Yes : exit LDY #SectorsPerTrack*DirPrimary ; First sector of DIR track ($0168) LDA #SectorsPerTrack ; Set sectors per track for this drive STA $10,U ; Set it TST $0C,U ; Do we know how many tracks this disk has ? BNE LD1CA ; Yes : skip on JSR >DosDoRestore ; No, do restore BCC LD1CA ; no error : skip RTS LD1CA PSHS X ; Save drive detail pointer JSR >SuperDosFindAndRead ; Find free buffer and read sector BNE LD170 ; Error : exit ; At this point X points to buffer details ??? CLR BuffFlag,X ; Reset buffer flag LDX BuffAddr,X ; Get address of buffer data LDD DirTracks1s,X ; Get complements of tracks/secs per track COMA ; Complemetn them for compare COMB CMPD DirTracks,X ; compare them to validate the disk PULS X ; restore drive detail pointer BNE LD201 ; Not the same, may be ds disk STB $10,U ; Set Sectors/Track for this disk STA $0C,U ; Set tracks for this disk DEC ,U ; Mark drive online CMPB #$12 ; Disk single sided ? BEQ LD1F0 ; yes : skip on CLRB ; zero it LD1F0 PSHS B ; save it CLR BuffFlag,X ; Clear buffer flag LDD #SectorsPerTrack*DirPrimary ; First sector of DIR track ($0168) TST ,S+ ; Do we need to double ? BNE LD1FD ; yes : skip ASLB ; Multiply D by 2, as we have 2 sides ROLA LD1FD STD ,X ; save it LD1FF CLRB ; No error RTS ; Return LD201 LDB #$90 ; Flag error RTS ; ; Get directory entry. ; ; Entry : B= File number(on disk) to get entry for??? ; ; Exit : X=Pointer to required Dir entry. ; SuperDosGetDirEntry LDA #$FF ; Init sector counter LD206 INCA ; increment sector counter SUBB #DirEntPerSec ; Decrement file no, by a sectors worth of files BCC LD206 ; Done all ? no : continue looping ADDB #DirEntPerSec ; Compensate for over loop ; At this point A contains the sector number within the directory that we are intereted in. ; and B contains the entry within that sector of the file's details. PSHS D ; Save them BSR DosGetDiskGeometry ; Setup disk geometry from disk in drive LBNE LCB7C ; Error : exit LDD ,X ; Get LSN number from buffer ADDD #$0002 ; Advance past bitmap sectors ADDB ,S+ ; Add sector offset calculated above ADCA #$00 ; Deal with carry STD DosCurLSN ; Save LSN TFR D,Y ; Get LSN into Y BSR SuperDosFindAndRead ; Find free buffer and read sector PULS A ; Retrieve entry number witin sector BNE LD236 ; Error: exit TFR X,U LDB #$19 ; Length of dir entry MUL ; Calculate offset STX DosCurDirBuff ; Saave block def pointer LDX BuffAddr,X ; Get pointer to block data LEAX D,X ; Get offset of DIR entry into X CLRB ; Flag no error LD236 RTS LD237 PSHS D BSR SuperDosGetDirEntry ; Get directory entry we are interested in LBNE LCB7C ; Error : LDY DosCurDirBuff ; Get Buffer def block for this entry LDA #$FE ; Set flag STA BuffFlag,Y CLRB ; Flag no error PULS D,PC ; Restore and return ; ; Find a free disk buffer. ; ; Entry : Y=?? ; ; Exits : U=pointer to detail entry for free buffer. ; B=Error code ; FindFreeBuffer LDX #Buff1Details ; Point at disk buffer detail table LDU <Misc16BitScratch ; Load U with 0 ? LDB #BuffCount ; 4 Disk buffers LD251 LDA BuffFlag,X ; Get buffer flag in A BEQ LD26C ; Zero ? CMPA #BuffInUse ; Is buffer in use ? BEQ LD26E ; Yes, try next buffer CMPY ,X BNE LD268 LDA <DosLastDrive ; Get last drive CMPA BuffDrive,X ; Is this buffer using the same drive ? BNE LD268 ; nope, skip on BSR MakeBuffYoungest ; Make this the youngest buffer CLRB ; Flag no error RTS LD268 TST BuffFlag,X ; Is buffer free ? BNE LD26E ; nope, look at next LD26C TFR X,U ; Select this buffer LD26E LEAX BuffDetailSize,X ; move on to next buffer detail entry DECB ; Decrement counter BNE LD251 ; Any more to check ? : yes loop again LDB #$FF ; Flag error RTS ; ; Find a free buffer and read sector. ; ; Entry : ; Y= ??? ; U= ??? ; SuperDosFindAndRead PSHS U BSR FindFreeBuffer ; Find free buffer, pointer to details returned in U LBEQ LCB7C LEAX ,U ; Make X point to details PULS U BNE LD288 BSR FindFreeDiskBuffer ; Find buffer to read data into BNE LD2A1 ; Error : exit LD288 CLR BuffFlag,X ; Make buffer free STY ,X LDA <DosLastDrive ; Get last drive STA BuffDrive,X ; Set this drive's buffer PSHS X ; Save buffer detail pointer LDX BuffAddr,X ; Get address of buffer JSR >SuperDosReadAbsSector ; Read the sector PULS X ; Restore buff detail pointer BNE LD2A1 ; Error : exit LDA #$01 ; Set flag to 1 STA BuffFlag,X CLRB ; No error LD2A1 RTS ; ; Find least recently used disk buffer, if none, and there is ; a dirty buffer, then flush it and use that one. ; ; Exit : X=pointer to buffer info block. ; FindFreeDiskBuffer PSHS D,Y,U LD2A4 LDX #Buff1Details ; Point to disk buffer table LDB #$04 ; Check 4 buffers LD2A9 LDA BuffAge,X ; Get buffer age CMPA #$01 ; Oldest ? BEQ LD2B4 ; Yes go process it LEAX 7,X ; Do next bufffer DECB ; Decrement buffer count BNE LD2A9 ; More : do next LD2B4 BSR MakeBuffYoungest ; Adjust ages of all other buffers LDA BuffFlag,X ; Get buffer flag byte CMPA #$55 ; In use ??? BEQ LD2A4 ; yes, select another buffer INCA ; Check for Flag=$FF BNE LD2C3 ; no : skip on DEC BuffFlag,X ; yes, select another buffer BRA LD2A4 LD2C3 BSR LD2E2 ; Check for buffer flush needed ? BEQ LD2C9 ; No error: skip STB 1,S ; Flag error to caller LD2C9 PULS D,Y,U,PC ; restore and return MakeBuffYoungest LDB #BuffCount ; Process 4 buffers LDA BuffAge,X ; Get current buffer Age LDU #Buff1Details ; Point to disk buffer table LD2D2 CMPA BuffAge,U ; Compare to current buffer age BHI LD2D8 ; higher ? skip DEC BuffAge,U ; Decrement Age byte (make older) LD2D8 LEAU BuffDetailSize,U ; Do next buffer DECB ; Decrement count BNE LD2D2 ; More : do next LDA #$04 ; Mark this as youngest buffer STA BuffAge,X RTS LD2E2 TST BuffFlag,X ; Buffer dirty ? BMI FlushBuffer ; Yes, flush it ! CLRB ; No error ? RTS FlushBuffer LDA <DosLastDrive ; Get last drive accessed PSHS A ; save it on stack PSHS X ; Save buffer pointer LDA #$FF ; Flag Dos IO in progress STA <DosIOInProgress CLR 2,X ; Flag buffer no longer dirty LDA 3,X ; Get drive this buffer refers to STA <DosLastDrive ; Save in last accessed drive LDY ,X ; get LSN ? LDX 5,X ; Get buffer pointer BSR SuperDosWriteAbsSector ; Write it PULS X ; Retrieve buffer pointer BNE LD31F ; no error : skip ahead LDA <DskTrackNo ; Get current track no CMPA #$14 ; track 20 (directory) ? BNE LD31A ; no : skip ahead ; ; I do not have a clue why this code does this, it seems to take a byte from ; the basic rom do some stuff to it and update the Directory sector status table ; with it ! ; ; Looking at $A673, the 8 bytes before it are $80,$40,$20,$10,$08,$04,$02,$01 ; This is the 2 colour pixel mask table, but is a convenient table for mapping a bit ; number to the bit it represents. ; LDU #PixMaskTable4Col ; This for some strange reason points U at basic rom !!! LDA <DosLastDrive ; get last drive NEGA LDA A,U LDU #DosDirSecStatus-1 ; Point to directory status table LDB <DskSectorNo ; get sector number ORA B,U ; Put a byte in table STA B,U LD31A LDA #$01 ; Mark bufer as youngest STA BuffFlag,X CLRB LD31F PULS A STA <DosLastDrive ; Restore last drive CLR <DosIOInProgress ; Mark no io in progress TSTB RTS ; ; Write absolute sector. ; ; Entry : X=Address to store data ; Y=LSN to read ; $00EA=Drive number ; SuperDosWriteAbsSector BSR CalcTrackFromLSN ; Setup disk vars in low ram with trackno JSR >DosDoWriteSec2 LD32C LDX <DiskBuffPtr ; Restore buffer pointer TSTB ; Test for Error RTS ; return to caller LD330 BSR CalcTrackFromLSN ; Setup disk vars in low ram with trackno JSR >DosDoReadSec2 BRA LD32C ; ; Read absolute sector. ; ; Entry : X=Address to store data ; Y=LSN to read ; $00EA=Drive number ; SuperDosReadAbsSector BSR CalcTrackFromLSN ; Setup disk vars in low ram with trackno JSR >DosDoReadSec ; Go read data BRA LD32C ; Return to caller ; ; Calculate track from Logical sector number. ; ; Entry : X=Buffer pointer ; Y=LSN to read/write ; ; Exit : D=Disk track no, Low ram vars also set. ; CalcTrackFromLSN STX <DiskBuffPtr ; Save in buffer pointer LDX #DosD0SecTrack-1 ; Point to Sec/Track table LDB <DosLastDrive ; Get last drive LDB B,X ; Get Sec/Track for that drive CLRA PSHS D ; Save it CLR ,-S ; Make room on stack TFR Y,D ; Get LSN into D ; Calculate which track we need LD34E INC ,S ; Inc track counter SUBD 1,S ; Decrement sec/track from LSN BPL LD34E ; keep looping till it goes -ve ADDB 2,S ; Compensate for over-loop LDA ,S ; Get track needed DECA ; Compensate track for over loop INCB LEAS 3,S ; Drop stack temps STD <DskTrackNo ; Save track no RTS ; ; Copy command dispatch routine ; ; Syntax : ; COPY filespec TO filespec ; ; Stack setup as follows ; ; offset size purpose ; 0 1 Source FCB number ; 1 1 Destination FCB number ; 2 2 Buffer pointer ? ; 4 3 File pointer pos ; CmdCopy JSR >SuperDosCloseAll ; Close all files & devices BNE LD39F ; Error : exit LEAS -7,S ; Make room on stack ; ; Make a buffer for copying the file. ; TFR S,D ; move to D SUBD #$0100 ; Make room for 1 sector SUBD <BasVarEnd ; Will we overwrite basic ? LBMI BasOMError ; yes : error, exit CLRB TSTA ; overwrite zero page ? LBEQ BasOMError ; yes : error, exit STD 2,S ; IO buffer pointer JSR >DosGetFilenameAndOpen ; Get source filename FCB number in A BNE LD39F ; Error : exit STA ,S ; save FCB no of source JSR >SuperDosGetFLen ; Get file length BNE LD39F ; Error : exit JSR <BasChrGetCurr ; scan current char from params CMPA #$BC ; "TO" token LBNE BasSNError ; no : Error JSR <BasChrGet ; Get next character JSR >DosGetFilenameAndOpen ; Get dest filename FCB number in A BEQ LD398 ; No error : continue CMPB #$A0 BNE LD39F ; Error : exit LD398 STA 1,S ; Save destination FCB number JSR >SuperDosCreateFile ; re-write destination file BEQ LD3A2 ; no error : continue LD39F JMP >DosHookSysError ; Error : exit LD3A2 LDA ,S ; Get source FCB no STA <DosCurrCtrlBlk ; Save current FCB JSR >DosFCBNoToAddr ; Get FCB address ; Compare file pointer position with file length for source file LDD 12,X CMPD $10,X BCS LD3B8 LDA 14,X CMPA $12,X BEQ LD408 LD3B8 LDU 12,X LDA 14,X STA 6,S STU 4,S LDD 2,S ADDD 5,S STD 5,S BCC LD3CA INC 4,S LD3CA LDA 4,S SUBA $10,X BCS LD3DF LDD 5,S SUBD $11,X BLS LD3DF LDD $11,X SUBD 13,X STD 2,S LD3DF LDA ,S ; Get source FCB no LDU 12,X ; Get number of bytes to read LDB 14,X ; Y:B=position to read from LDY 2,S LDX <BasVarEnd ; Point to end of basic memory JSR >SuperDosFRead ; Read from source file BNE LD39F ; error : exit LDA 1,S ; Get destination FCB No STA <DosCurrCtrlBlk ; Save in current ctrl block no JSR >DosFCBNoToAddr ; Get addres of Dest FCB LDY $10,X LDB $12,X LDU 2,S LDX <BasVarEnd ; Point to end of basic memory JSR >SuperDosFWrite ; Write to destination BNE LD39F ; Error : exit BRA LD3A2 ; continue copying LD408 JSR >SuperDosCloseAll ; Close all files, finished copy BNE LD39F ; Error ! LEAS 7,S ; drop stack frame RTS ; ; Merge command dispatch routine. ; ; Syntax : ; MERGE filespec ; CmdMerge JSR >DosValidateAndOpenBas BNE LD39F BSR LD494 BNE LD39F CMPA #$01 BNE LD45B LDU <BasVarSimpleAddr LDY <BasStartProg PSHS Y,U LEAU 1,U STU <BasStartProg JSR >LD507 PULS X,U STU <BasVarSimpleAddr STX <BasStartProg LEAU 1,U LD433 LDD ,U++ BEQ LD455 LDD ,U++ STD BasLinInpHead STD <BasTempLine CLRB LDX #$02DC LD442 INCB LDA ,U+ STA ,X+ BNE LD442 ADDB #$04 STB <BasGenCount PSHS U BSR LD45E PULS U BRA LD433 LD455 CLR DosRunLoadFlag JMP >LD4E4 LD45B JMP >BasFMError LD45E JSR >BasFindLineNo BCS LD475 LDD <BasVarFPAcc4+2 SUBD ,X ADDD <BasVarSimpleAddr STD <BasVarSimpleAddr LDU ,X LD46D LDA ,U+ STA ,X+ CMPX <BasVarSimpleAddr BNE LD46D LD475 LDD <BasVarSimpleAddr STD <BasVarFPAcc3+3 ADDB <BasGenCount ADCA #$00 STD <BasVarFPAcc3+1 JSR >BasChkArrSpaceMv LDU #$02D8 LD485 LDA ,U+ STA ,X+ CMPX <BasVarFPAcc4 BNE LD485 LDX <BasVarFPAcc3+1 STX <BasVarSimpleAddr JMP >BasVect2 LD494 LDX #DosCurDriveInfo ; Get current drive info LDY #$0009 LDU <Misc16BitScratch ; U=0 ? CLRB LDA <DosCurrCtrlBlk ; Get current FCB address JSR >SuperDosFRead ; Go read the file BNE LD4B6 ; Error : exit LDA #$55 LDX #DosCurDriveInfo ; Get current drive info CMPA ,X BNE LD45B COMA CMPA 8,X BNE LD45B LDA 1,X CLRB LD4B6 RTS DosHookRun CLR $0614 CLR $0619 CLR $0617 CLR $0618 CMPA #$22 BEQ LD4C9 TSTA RTS ; Dragon, just return LD4C9 LEAS 2,S LDB #$01 FCB $21 ; ; Load command dispatch routine ; ; Syntax : ; LOAD filespec ; LOAD filespec,offset ; CmdLoad CLRB ; Set run/load flag to load STB DosRunLoadFlag JSR >DosValidateAndOpenBas ; Open supplied filename BNE LD4DB ; Error : exit BSR LD494 BEQ LD4DE ; No error : skip LD4DB JMP >DosHookSysError LD4DE CMPA #$01 BNE LD529 BSR LD507 LD4E4 CLR <DosIOInProgress ; Flag no DOS IO in progress LDX <BasStartProg ; Get start of program JSR >BasSetProgPtrX ; Set program pointer to X LDX <AddrFWareRamTop ; Set Top of string space STX <BasVarStrTop LDX <BasVarSimpleAddr ; Set Array base=simple var base STX <BasVarArrayAddr STX <BasVarEnd ; Set Basic var end at seme place LD4F5 JSR >CmdRestore ; So the equivelent of a basic 'RESTORE' command JSR >BasResetStack ; Reset basic stack TST DosRunLoadFlag ; Is this a load only or load & then run ? BEQ LD503 ; Just a load, return to basic JMP >BasRun ; Run basic program LD503 CLRA ; Clear error JMP >BasCmdMode ; Go to command mode LD507 LDD 4,X TFR D,Y ADDD <BasStartProg STD <BasVarEnd LDB #$40 JSR >BasChkB2Free LD514 LDA <DosCurrCtrlBlk LDB #$09 LDX <BasStartProg LDU <Misc16BitScratch JSR >SuperDosFRead BNE LD4DB JSR >BasVect2 LEAX 2,X STX <BasVarSimpleAddr RTS LD529 CMPA #$02 LBNE LD45B LDU 6,X STU <BasExecAddr JSR <BasChrGetCurr BEQ LD549 PSHS X BSR LD5AA TFR X,U PULS X LDD 6,X SUBD 2,X STU 2,X ADDD 2,X STD <BasExecAddr LD549 LDY 4,X LDA <DosCurrCtrlBlk LDB #$09 LDU <Misc16BitScratch LDX 2,X JSR >SuperDosFRead BNE LD5A1 TST DosRunLoadFlag BEQ LD5A9 JMP [>BasExecAddr] ; ; Save command dispatch routine. ; ; Syntax : ; SAVE filespec ; SAVE filespec,start_addr,end_addr,entry_addr ; CmdSave JSR >VarGetStr JSR >VarGetExpr JSR <BasChrGetCurr BEQ LD5B0 LDY #DosExtBin BSR LD598 BSR LD5AA STX $0652 BSR LD5AA TFR X,D CMPX $0652 LBCS DosPRError SUBD $0652 LBMI BasFCError ADDD #$0001 STD $0654 BSR LD5AA STX $0656 LDB #$02 BRA LD5CA LD598 JSR >LD6DF BEQ LD5A4 CMPB #$A0 BEQ LD5A4 LD5A1 JMP >DosHookSysError LD5A4 JSR >SuperDosCreateFile BNE LD5A1 LD5A9 RTS LD5AA JSR >VarCKComma JMP >VarGet16Bit LD5B0 LDY #DosExtBas BSR LD598 LDX <BasStartProg STX $0652 LDD <BasVarSimpleAddr SUBD <BasStartProg STD $0654 LDX #BasFCError STX $0656 LDB #$01 LD5CA LDX #DosCurDriveInfo LDA #$55 STA ,X COMA STA 8,X STB 1,X LDA <DosCurrCtrlBlk CLRB LDY <Misc16BitScratch LDU #$0009 JSR >SuperDosFWrite BNE LD5A1 LDA <DosCurrCtrlBlk LDB #$09 LDX $0652 LDU $0654 LDY <Misc16BitScratch JSR >SuperDosFWrite BNE LD5A1 CLR <DosIOInProgress RTS ; ; Chain command dispatch routine. ; ; Syntax : ; CHAIN filespec ; CmdChain BSR LD670 JSR >DosValidateAndOpenBas BNE LD5A1 JSR >LD494 BNE LD5A1 CMPA #$01 LBNE LD45B JSR <BasChrGetCurr BEQ LD61E JSR >VarCKComma JSR >BasGetLineNo BSR LD629 LDD <BasTempLine JSR >BasSkipLineNo BRA LD626 LD61E BSR LD629 LDU <BasStartProg LEAU -1,U STU <BasAddrSigByte LD626 JMP >LD4F5 LD629 LDD $0654 TFR D,Y ADDD <BasStartProg SUBD <BasVarSimpleAddr PSHS D ADDD <BasVarEnd STD <BasVarEnd LDB #$40 STB DosRunLoadFlag JSR >BasChkB2Free LDD ,S BPL LD653 LDX <BasVarSimpleAddr LEAU D,X LD648 LDA ,X+ STA ,U+ CMPU <BasVarEnd BLS LD648 BRA LD661 LD653 LDX <BasVarEnd LEAX 1,X LEAU D,X LD659 LDA ,-X STA ,-U CMPX <BasVarSimpleAddr BCC LD659 LD661 LDD ,S ADDD <BasVarSimpleAddr STD <BasVarSimpleAddr PULS D ADDD <BasVarArrayAddr STD <BasVarArrayAddr JMP >LD514 LD670 LDX <BasVarSimpleAddr ; Get pointer to start of vars LEAX 2,X LD674 CMPX <BasVarArrayAddr ; More than 2 bytes of vars ? BCC LD682 TST -1,X BPL LD67E BSR LD6AA LD67E LEAX 7,X BRA LD674 LD682 LDU <BasVarArrayAddr ; Array pointer LD684 CMPU <BasVarEnd ; any arrays in use ? BCC LD6A7 LDD 2,U LEAX D,U PSHS X TST 1,U BPL LD6A3 LDB 4,U CLRA ASLB LEAX D,U LEAX 5,X LD69B BSR LD6AA LEAX 5,X CMPX ,S BCS LD69B LD6A3 PULS U BRA LD684 LD6A7 JMP >VarGarbageCollect LD6AA PSHS X,U CMPX <BasVarStringBase BCC LD6C3 LDB ,X BEQ LD6C3 JSR >BasResStr2 TFR X,U LDY ,S LDX 2,Y STU 2,Y JSR >UtilCopyBXtoU LD6C3 PULS X,U,PC LD6C5 LDY #DosExtDat BRA DosGetFilenameAndOpenExt ; ; Validate and open Basic program file supplied on command ; DosValidateAndOpenBas LDY #DosExtBas ; Point to 'BAS' file extension BRA DosGetFilenameAndOpenExt ; Validate and open file ; ; Get a filename from Dos and open it ; Takes a string supplied on command name, fetches it and ; tries to open the file of that name. ; ; If entered at DosGetFilenameAndOpenExt then extension must be pointed to by Y ; ; Exits with :- ; A=FCB number for opened file ; B= Error code ? ; Y=ptr to extension ; DosGetFilenameAndOpen LDY #DosExtNone ; Point to Blank extension DosGetFilenameAndOpenExt PSHS Y JSR >VarGetStr ; get string into temp variable JSR >VarGetExpr ; Get address of string in FAC PULS Y LD6DF LDX <BasVarAssign16 ; Get string address PSHS X LDB ,X ; Get string length LDX 2,X ; Get pointer to actual string data JSR >DosValidateAndOpen ; Validate & open file (if valid) PULS X PSHS D JSR >VarDelVar ; Delete tempory variable PULS D TSTB ; Get error? RTS DosHookCloseSingle LDA #$09 STA <DosCurrCtrlBlk LD6F9 JSR >LCEF9 BNE LD717 DEC <DosCurrCtrlBlk BPL LD6F9 LD702 CLR <DosIOInProgress CMPX #$39FD DosFlagDrivesOffline CLRA ; Clears some dos vars CLRB STD DosD0Online ; Drives 0 & 1 STD DosD2Online ; Drives 2 & 3 RTS DosDrivesOffCLS BSR DosFlagDrivesOffline ; Flag all drives as offline JMP >TextCls ; Clear screen LD715 BEQ LD702 LD717 JMP >DosHookSysError LD71A JSR >LCEF9 BRA LD715 ; ; Create command dispatch routine. ; ; Syntax : ; CREATE filespec,length ; CmdCreate BSR LD6C5 BEQ LD72B CMPB #$9E BEQ LD72B CMPB #$A0 BNE LD717 LD72B LDA <DosCurrCtrlBlk JSR >SuperDosCreateFile BNE LD717 JSR <BasChrGetCurr BEQ LD76C JSR >VarCKComma JSR >VarGetStr JSR >LD879 LD73F TST <BasVarFPAcc1+2 BEQ LD755 LDD #$FF00 BSR LD767 LDD <BasVarAssign16 SUBD #$FF00 STD <BasVarAssign16 BCC LD73F DEC <BasVarFPAcc1+2 BNE LD73F LD755 LDD <BasVarAssign16 BEQ LD76C CMPD #$FF00 BLS LD767 SUBD #$FF00 BSR LD767 LDD #$FF00 LD767 JSR >LCC12 BNE LD717 LD76C RTS ; ; Kill command dispatch routine ; ; Syntax : ; KILL filespec ; CmdKill JSR >DosGetFilenameAndOpen BNE LD777 JSR >SuperDosDeleteFile LD775 BEQ LD71A LD777 JMP >DosHookSysError ; ; Protect command dispatch routine. ; ; Syntax : ; PROTECT ON filespec ; PROTECT OFF filespec ; CmdProtect TSTA BPL LD787 CMPA #$C2 BEQ LD798 CMPA #$88 LBNE BasSNError LD787 BSR LD790 LDB #$01 LD78B JSR >SuperDosProtect BRA LD775 LD790 JSR <BasChrGet JSR >DosGetFilenameAndOpen BNE LD7BB RTS LD798 BSR LD790 CLRB BRA LD78B ; ; Rename command dispatch routine ; ; Syntax : ; RENAME filespec TO filespec ; CmdRename JSR >DosGetFilenameAndOpen BNE LD7BB PSHS A LDB #$BC JSR >VarCKChar JSR >DosGetFilenameAndOpen BEQ LD7B9 CMPB #$A0 BNE LD7BB PULS A JSR >SuperDosRename BRA LD775 LD7B9 LDB #$9E LD7BB JMP >DosHookSysError ; ; FLread command dispatch routine ; ; Syntax : ; FLREAD filespec;string ; FLREAD filespec, FROM first_byte,FOR count;string ; CmdFLRead BSR LD7CD LDA #$FF STA DosFlFreadFlag JSR >LD95D BSR LD7F8 JMP >BasLineInputEntry LD7CD JSR >LD6C5 BNE LD822 BSR LD825 JSR >DosFCBNoToAddr TST $067E BEQ LD7E6 LDU $0664 LDB $0666 STU 12,X STB 14,X LD7E6 JSR >LD9CF LDX #$02DC CLR ,X JMP <BasChrGet ; ; Fread command dispatch routine ; ; Syntax : ; FREAD filespec;variable list ; FREAD filespec,FROM startpos,FOR numbytes;variable list ; CmdFRead BSR LD7CD CLR DosFlFreadFlag JSR >CmdReadFromX LD7F8 JSR >DosFCBNoToAddr LDB $0604 BEQ LD80E CLR DosErrorCode LDD FCBFilePointer+1,X ; Get filepointer LSW SUBD $0603 STD FCBFilePointer+1,X ; Resave filepointer LSW BCC LD80E DEC FCBFilePointer,X ; Decrement filepointer MSB LD80E TST <DosRecLenFlag BEQ LD81F LDB <DosNoBytesMove BEQ LD81F CLRA ADDD FCBFilePointer+1,X STD FCBFilePointer+1,X BCC LD81F INC FCBFilePointer,X LD81F CLR <TextDevN RTS LD822 JMP >DosHookSysError LD825 JSR >BasChkDirect LDA <DosCurrCtrlBlk JSR >SuperDosGetFLen BNE LD822 STU $0664 STA $0666 CLR <DosRecLenFlag CLR $067E LDA #$01 STA <TextDevN LD83E JSR <BasChrGetCurr CMPA #$3B BEQ LD896 JSR >VarCKComma CMPA #$E5 BNE LD85F JSR <BasChrGet JSR >VarGetStr BSR LD879 STU $0664 STA $0666 LDA #$FF STA $067E BRA LD83E LD85F CMPA #$80 BNE LD870 JSR <BasChrGet JSR >Get8BitorError STB <DosNoBytesMove LDB #$FF STB <DosRecLenFlag BRA LD83E LD870 JMP >BasSNError LD873 JMP >BasFCError LD876 JMP >BasTMError LD879 TST <BasVarFPAcc1+5 BMI LD873 TST <BasVarType BNE LD876 LDA #$A0 SUBA <BasVarFPAcc1 BEQ LD892 LD887 LSR <BasVarFPAcc1+1 ROR <BasVarFPAcc1+2 ROR <BasVarAssign16 ROR <BasVarFPAcc1+4 DECA BNE LD887 LD892 LDU <BasVarFPAcc1+2 LDA <BasVarFPAcc1+4 LD896 RTS ; ; FWrite command dispatch routine. ; ; Syntax : ; FWRITE filespec;variable list ; FWRITE filespec,FROM startpos,FOR numbytes;variable list ; CmdFWrite JSR >LD6C5 BEQ LD8A5 CMPB #$A0 BNE LD908 JSR >SuperDosCreateFile BNE LD908 LD8A5 JSR >LD825 JSR >FindFreeDiskBuffer BNE LD908 STX $060B LDA #$55 STA 2,X CLR <DosBytesInDTA JSR <BasChrGet JSR >CmdPrint TST <DosRecLenFlag BEQ LD8CA LDB <DosNoBytesMove BEQ LD8CA LDA #$20 LD8C5 BSR LD911 DECB BNE LD8C5 LD8CA TST <DosBytesInDTA BEQ LD8E6 LDX $060B LDX 5,X CLRA LDB <DosBytesInDTA TFR D,U LDA <DosCurrCtrlBlk LDY $0664 LDB $0666 JSR >SuperDosFWrite BNE LD908 LD8E6 LDX $060B CLR 2,X LD8EB RTS DosHookCheckIONum BLE LD8EB CMPB #$04 BHI LD906 PULS X,PC DosHookOpenDev LEAS 2,S JSR >VarGetStr JSR >BasGetStrFirst PSHS B JSR >BasGetDevNo TSTB LBLE CmdOpenEntry LD906 LDB #$28 LD908 JMP >DosHookSysError DosHookCharOut TST <TextDevN BLE LD8EB LEAS 2,S LD911 PSHS D,X,Y,U LDB <DosRecLenFlag BEQ LD91B LDB <DosNoBytesMove BEQ LD952 LD91B LDX $060B LDX 5,X LDB <DosBytesInDTA ABX STA ,X DEC <DosNoBytesMove INC <DosBytesInDTA BNE LD952 LDA <DosCurrCtrlBlk LDX $060B LDX 5,X LDU #$0100 LDY $0664 LDB $0666 JSR >SuperDosFWrite BEQ LD944 JMP >DosHookSysError LD944 LDD $0665 ADDD #$0100 BCC LD94F INC $0664 LD94F STD $0665 LD952 PULS D,X,Y,U,PC DosHookDiskItem TST <TextDevN BLE LD9BB LDX #$879A STX ,S LD95D LDA <DosRecLenFlag BEQ LD965 LDA <DosNoBytesMove BEQ LD9B2 LD965 LDX #$02DD LDB <DosBytesInDTA STB $0603 ABX LDB $0604 STB DosRunLoadFlag CLRB STB -1,X STB <BasBreakFlag LD979 DEC <DosNoBytesMove DEC $0604 INC <DosBytesInDTA LDA ,X+ BEQ LD9B2 CMPA #$0D BEQ LD9B2 TST DosFlFreadFlag BNE LD995 CMPA #$2C BEQ LD9B2 CMPA #$3A BEQ LD9B2 LD995 LDA <DosRecLenFlag BEQ LD99D LDA <DosNoBytesMove BEQ LD9B2 LD99D INCB CMPB #$FF BEQ LD9B0 LDA $0604 BNE LD979 LDB <BasBreakFlag BNE LD9B0 BSR LD9BC CLRB BRA LD979 LD9B0 LEAX 1,X LD9B2 LDB $0603 CLR -1,X LDX #$02DC ABX LD9BB RTS LD9BC JSR >DosFCBNoToAddr CLRA LDB DosRunLoadFlag PSHS D LDD 13,X SUBD ,S++ STD 13,X BCC LD9CF DEC 12,X LD9CF PSHS Y,U LDU #$00FF BSR LD9EF LDU #$02DD CLR D,U LDA <DosCurrCtrlBlk LDB 14,X LDX 12,X EXG X,U JSR >SuperDosFRead BNE LDA25 LDX #$02DD CLR -1,X PULS Y,U,PC LD9EF PSHS U LDD 13,X ADDD ,S PSHS D LDA 12,X ADCA #$00 SUBA $10,X PULS D BCS LDA14 BHI LDA23 SUBD $11,X BLS LDA14 LDD $11,X SUBD 13,X BEQ LDA23 STD ,S COM <BasBreakFlag LDA14 LDD ,S STB $0604 STB DosRunLoadFlag CLR $0603 CLR <DosBytesInDTA PULS Y,PC LDA23 LDB #$9A LDA25 JMP >DosHookSysError ; ; Dir command dispatch routine ; ; Syntax : ; DIR drivenum ; CmdDir BEQ LDA2F ; No drive specified, use default JSR >GetDriveNoInB ; Else get from command BRA LDA32 LDA2F LDB DosDefDriveNo ; Get default drive LDA32 STB <DosLastDrive ; Flag as last drive used CLR ,-S ; make temp on stack (file number on disk counter) JSR >DosDrivesOffCLS ; Flag drives offline, and clear screen CLRB LDA3A JSR >BasPollKeyboard ; Read keyboard, check for break JSR >SuperDosGetDirEntry ; Get next dir entry BNE LDA25 ; Error : exit LDA ,X ; Get Attribute byte BITA #AttrEndOfDir ; Check for end of directory $08 BNE CmdDirDoneAll ; Yes : stop processing BITA #AttrDeleted+AttrIsCont ; Is entry a deleted file, or continuation entry ? $81 ; and another thing BNE CmdDirDoNextEntry ; yes : do next LEAX 1,X ; Point at filename LDB #$08 ; Up to 8 chars BSR PrintBCharsFromX ; Print it LDB #$04 ; 5 chars LDA #$2E ; '.' BSR LDAB8 ; Print extension LDA -12,X ; Point at attributes BITA #AttrWriteProt ; Is this a protected file ? BEQ LDA61 ; no skip on LDA #'p ; Flag protected $70 ;LDA61 EQU *+1 ; CMPX #$8620 FCB Skip2 ; CMPX trick LDA61 LDA #$20 JSR >TextOutChar ; output attribute byte JSR >TextOutSpace ; And a space LDU #$FFFF LDX #DosFCB0Addr ; Point at first FCB LDB ,S ; Get file number STB FCBDiskFileNo,X ; Save in FCB JSR >LCB20 BNE LDA25 ; Check for error JSR >LCEBF BSR LDABF ; Print filesize LDD <TextVDUCursAddr ; Check for near end of screen CMPD #$05A0 BLS LDA97 ; not near end, skip on PSHS D,X,Y,U ; save regs LDX #DosMoreMess ; Point to message JSR >TextOutString ; Print more: prompt JSR >TextWaitKey ; wait for a key JSR >TextCls ; clear screen PULS D,X,Y,U ; Restore regs ;LDA97 EQU *+1 ; LDA #$BD ; SUBA <$A1 IFNE Tandy BRA CmdDirDoNextEntry ELSE FCB Skip1LD ; LDA, like cmpx trick ENDC LDA97 JSR TextOutCRLF ; Output EOL CmdDirDoNextEntry INC ,S ; do next LDB ,S ; Get disk file number counter CMPB #$A0 ; More than max files on disk ? BCS LDA3A ; Less, loop again. ; ; We come here either when we have processed $A0 entries, which is the maximum, ; or we have reached an entry with the AttrEndOfDir bit set which signals the end ; of the directory. ; CmdDirDoneAll PULS A JSR >SuperDosGetFree ; Get free bytes on drive CLRA TFR X,U BSR LDABF ; Display free bytes LDX #BytesFreeMess-1 ; Point to message JMP >TextOutString ; print it, and return ; Print B chars pointed to by X, if char is $00, then output a space. ; Used to print filenames. PrintBCharsFromX LDA ,X+ ; Fetch a char BNE LDAB8 ; Is it zero ? no : skip LDA #$20 ; Replace it with a space LDAB8 JSR >TextOutChar ; Output it DECB ; Decrement count BNE PrintBCharsFromX ; any left yes : loop again RTS LDABF JSR >LDD9B JMP >TextOutNumFPA0 DosHookReadInput PSHS D,X,U LDX #$837D CMPX 8,S BNE LDAD3 JSR >DosHookCloseSingle BRA LDB2D LDAD3 PULS D,X,U,PC BytesFreeMess FCC / BYTES FREE/ FCB $0D FCB $00 FCB $00 FCB $00 FCB $00 ; ; Auto command dispatch routine ; ; Syntax : ; ; AUTO startline,increment ; CmdAuto LDX <BasCurrentLine ; Get current line number LEAX 1,X ; Increment it LBNE BasFCError ; to big : ?FC error LDX #$000A ; Default line no increment 10 TFR X,D PSHS D,X ; make room on stack & setup default start and increment JSR <BasChrGetCurr ; Fetch current char pointed to by basic BEQ CmdAutoDoAuto ; Last char : yes proceed JSR >VarGet16Bit ; get start line no LDD <BasVarAssign16 ; check for error STD 2,S JSR <BasChrGetCurr ; Fetch current char pointed to by basic BEQ CmdAutoDoAuto ; Last char : yes proceed JSR >VarCKComma ; check for comma JSR >VarGet16Bit ; Get Line increment LDD <BasVarAssign16 BEQ CmdAutoErrorExit STD ,S JSR <BasChrGetCurr ; Fetch current char pointed to by basic BEQ CmdAutoDoAuto ; Last char : yes proceed CmdAutoErrorExit JMP >BasSNError ; More chars left, SN? error CmdAutoDoAuto ORCC #$50 ; Disable inturrupts ??? LDD ,S++ ; Get Increment off stack STD DosAutoInc LDD ,S++ ; Get start line off stack SUBD $060F ; Subtrack increment STD DosAutoCurrent ; Save in current LDA #AutoFlag ; Flag in AUTO mode STA DosAutoFlag RTS FCB $34 FCB $56 LDB2D TST $0613 BNE LDB34 LDB32 PULS D,X,U,PC LDB34 LDD $060D ADDD $060F CMPD #$F9FF BHI LDB32 STD ,S JSR >TextOutNum16 LDA #$20 JSR >TextOutChar LDU #$03DA LDD ,S STD $060D LDX #$02DD CLRB LDB56 LDA ,U+ BEQ LDB5F STA ,X+ INCB BRA LDB56 LDB5F LDA #$20 STA ,X+ INCB LDB64 JSR >TextWaitKeyCurs2 CMPA #$0D BEQ LDB6F CMPA #$03 BNE LDB85 LDB6F CLR $0613 LDA #$0D JSR >TextOutChar LEAS 8,S CLR <CasLastSine LDX #$02DD LDA #$0D LDB #$01 JMP >BasInBuffFromX LDB85 CMPA #$20 BCS LDB64 CMPA #$7B BCC LDB64 LEAS 8,S CLR <CasLastSine JMP >BasInBuffFromX LDB94 CLRA ; A=0 LDX #$0008 ; Repeat 8 times LDB98 JSR >CasByteOut ; Output A to cassette LEAX -1,X ; Decrement count BNE LDB98 ; Loop again if all not done RTS ; ; Beep command dispatch routine ; ; Syntax : ; BEEP nobeeps ; CmdBeep BEQ LDBA6 ; if no params, default to 1 beep JSR >Get8BitorError ; get beep count ;LDBA6 EQU *+1 ; CMPX #$C601 ; LDB #$01 (default beep count) FCB Skip2 LDBA6 LDB #$01 ; Default beep count PSHS B ; save count on stack CLRB JSR >SndDTOAOn ; switch dound to D to A LDBAE BSR LDB94 JSR >BasPollKeyboard DEC ,S ; decrement beep count BEQ LDBC1 ; done all : restore and exit LDY #$6000 ; wait a short while LDBBB LEAY -1,Y BEQ LDBAE ; loop back and do next beep BRA LDBBB LDBC1 PULS B,PC ; restore and return ; ; Wait command dispatch routine. ; ; Syntax : ; WAIT miliseconds ; CmdWait BEQ LDBD6 JSR >VarGet16Bit LDX <BasVarAssign16 LDBCA JSR >BasPollKeyboard LDB #$A0 LDBCF DECB BNE LDBCF LEAX -1,X BNE LDBCA LDBD6 RTS ; ; Swap command dispatch routine. ; ; Syntax : ; SWAP var1,var2 ; CmdSwap JSR >VarGetVar LDX <BasVarPtrLast LDA <BasVarType PSHS A,X JSR >VarCKComma JSR >VarGetVar PULS A,Y CMPA <BasVarType LBNE BasTMError LDU <BasVarPtrLast LDX #$0005 LDBF3 LDA ,U LDB ,Y STB ,U+ STA ,Y+ LEAX -1,X BNE LDBF3 RTS LDC00 LDB #$8E LDC02 TST <WarmStartFlag NOP LBRA DosHookSysError LDC08 LDA #$55 STA <WarmStartFlag RTS ; ; If assembling for the DragonDos cartrage, this is the dispatch for ; the boot command, if assembling for the dragon Alpha, I have used ; the space occupied by the boot command to store the code used to ; activate the Alpha's drive selects and motor on, this is reasonable ; because the Alpha has a graphical boot menu, which allows it to boot ; from disk, so this routine seemed expendable. ; ifne DragonAlpha ; Translate DragonDos Drive select mechinisim to work on Alpha ; Takes byte that would be output to $FF48, reformats it and ; outputs to Alpha AY-8912's IO port, which is connected to ; Drive selects, motor on and enable precomp. ; We do not need to preserve the ROM select bit as this code ; operates in RAM only mode. AlphaDskCtl PSHS x,A,B,CC,DP pshs a ; Convert drives anda #%00000011 ; mask out drive number leax ADriveTab,pcr ; point at table lda a,x ; get bitmap ldb ,s andb #%11111100 ; mask out drive number stb ,s ora ,s ; recombine bita #MotorOn ; test motor on ? bne MotorRunning clra ; No, turn off other bits. MotorRunning anda #KnownBits ; Mask out bits we do not know the function of sta ,s lda #AYIOREG ; AY-8912 IO register sta PIA2DB ; Output to PIA ldb #AYREGLatch ; Latch register to modify stb PIA2DA clr PIA2DA ; Idle AY lda ,s+ ; Fetch saved Drive Selects sta PIA2DB ; output to PIA ldb #AYWriteReg ; Write value to latched register stb PIA2DA ; Set register clr PIA2DA ; Idle AY PULS dp,x,A,B,CC,pc org $DC46 else ; ; Boot command dispatch routine (DragonDos only). ; ; Syntax : ; BOOT drivenum ; CmdBoot BEQ LDC14 ; No drive supplied, use default JSR >GetDriveNoInB ; Get drive number BRA LDC17 LDC14 LDB DosDefDriveNo ; use default drive no LDC17 LDA #BootFirstSector; Read boot sector STA <DskSectorNo STB <LastActiveDrv ; Set drive number JSR >DosDoRestore ; Restore to track 0 BCS LDC02 ; Error : exit JSR >DosDoReadSec2 ; Read first 2 chars of boot sec BCS LDC02 ; error : exit LDD #BootSignature ; Boot signature found ? CMPD <BasVarFPAcc1 BNE LDC00 ; no : error LDD #BootLoadAddr ; start at boot load address STD <DiskBuffPtr ; Set disk buffer to point there LDC34 JSR >DosDoReadSec ; Read a sector BCS LDC02 ; Error : exit INC <DiskBuffPtr ; increment page of buffer pointer INC <DskSectorNo ; increment sector number LDA <DskSectorNo ; get sector number CMPA #BootLastSector ; Read the whole boot area ? BLS LDC34 ; no : read next sector JMP >BootEntryAddr ; jump to loaded boot code endc ; ;Drive command dispatch routine. ; ; Syntax : ; DRIVE drivenum ; CmdDrive BEQ LDC4F JSR >GetDriveNoInB STB DosDefDriveNo RTS LDC4F JMP >BasSNError ; ; Error command dispatch routine. ; ; Syntax : ; ERROR GOTO lineno ; CmdError2 CMPA #$81 BNE LDC4F JSR <BasChrGet CMPA #$BC BNE LDC4F JSR <BasChrGet JSR >BasGetLineNo LDX <BasTempLine CMPX #$F9FF LBHI BasFCError STX DosErrDestLine BEQ LDC75 LDA #$FF STA $0614 RTS LDC75 CLR $0614 RTS LDC79 JSR >VarCKComma JSR >VarGetVar JMP >VarGetExpr ; ;Sread command dispatch routine. ; ; Syntax : ; SREAD driveno,trackno,secno,part1$,part2$ ; CmdSread JSR >GetSreadWriteParams ; Get drive,track,secno BSR LDC79 ; Get address of first 128 bytes to read PSHS X ; save on stack BSR LDC79 ; Get address of second 128 bytes to read PSHS X ; save on stack LDB #$FF STB <DosIOInProgress ; Flag Dos IO in progress JSR >FindFreeDiskBuffer ; Find a buffer to read sector into BNE LDCBA ; Error : exit CLR BuffFlag,X ; Clear buffer flag LDX BuffAddr,X ; Get buffer address STX <DiskBuffPtr ; Save as pointer to do read JSR >DosDoReadSec ; Read the sector STB $0603 ; Save error code in temp storage LDU <DiskBuffPtr ; Get pointer to read data LEAU $0080,U ; Point to second half of sector PULS X ; Get address of second string BSR LDCBD ; Copy bytes to string LDU <DiskBuffPtr ; Point at begining of disk buffer PULS X ; Get address of first string BSR LDCBD ; Copy bytes to string CLR <DosIOInProgress ; Flag Dos IO not in progress LDB $0603 ; Retrieve error code from read BNE LDCBA ; Error : go to error handler RTS ; return to caller LDCBA JMP >DosHookSysError ; Jump to error hook LDCBD PSHS X,U LDB #$80 JSR >BasResStr LEAU ,X PULS X STB ,X STU 2,X PULS X JMP >UtilCopyBXtoU ; ; Swrite command dispatch routine. ; ; Syntax : ; SWRITE driveno,side,sector,part1$,part2$ ; CmdSwrite BSR GetSreadWriteParams ; Get drive,track,secno BSR LDD1B JSR >VarGetExpr LDX <BasVarAssign16 PSHS X BSR LDD1B JSR >BasGetStrLenAddr PSHS B,X LDB #$FF STB <DosIOInProgress JSR >FindFreeDiskBuffer BNE LDCBA CLR 2,X LDX 5,X STX <DiskBuffPtr CLRB LDCF3 CLR ,X+ DECB BNE LDCF3 PULS B,X LDU <DiskBuffPtr LEAU $0080,U TSTB BEQ LDD06 JSR >UtilCopyBXtoU LDD06 PULS X JSR >VarDelVar LDU <DiskBuffPtr TSTB BEQ LDD13 JSR UtilCopyBXtoU LDD13 JSR >DosDoWriteSec BCS LDCBA CLR <DosIOInProgress RTS LDD1B JSR VarCKComma JMP >VarGetStr GetSreadWriteParams BNE LDD26 ; params, read them JMP >BasSNError ; none : SN Error ; ; Get params for Sread/Swrite ; LDD26 JSR GetDriveNoInB ; Drive number STB <DosLastDrive JSR >VarGetComma8 ; Track number CMPB #$4F ; greater than track 80 ? BHI LDD3A ; Yes : error STB <DskTrackNo ; Save track number JSR >VarGetComma8 ; Get sector number STB <DskSectorNo ; save it LDD39 RTS LDD3A JMP >BasFCError ; ; Verify command dispatch routine. ; ; Syntax : ; VERIFY ON ; VERIFY OFF ; CmdVerify BEQ LDD4D CMPA #$C2 BNE LDD46 CLRB BRA LDD4F LDD46 CMPA #$88 BEQ LDD4D JMP >BasSNError LDD4D LDB #$FF LDD4F STB DosVerifyFlag JMP <BasChrGet DosHookEOF TST <BasVarType BEQ LDD39 CLR <BasVarType LEAS 2,S LDY #DosExtDat JSR LD6DF BNE LDD7E JSR SuperDosGetFLen BNE LDD7E JSR DosFCBNoToAddr CMPU 12,X BHI LDD76 CMPA 14,X BLS LDD78 LDD76 CLRA ;LDD78 EQU *+1 ; CMPX #$8601 FCB Skip2 LDD78 LDA #$01 LDU <Misc16BitScratch BRA LDD99 LDD7E JMP >DosHookSysError FuncLoc JSR LD6C5 BNE LDD7E JSR DosFCBNoToAddr LDU 12,X LDA 14,X BRA LDD99 FuncLof JSR LD6C5 BNE LDD7E JSR SuperDosGetFLen BNE LDD7E LDD99 CLR <BasVarType LDD9B CLRB STU <BasVarFPAcc1+2 STD <BasVarFPAcc1+4 CLR <BasVarFPAcc2+7 LDA #$A0 STD <BasVarFPAcc1 JMP >VarNormFPA0 FuncFree JSR <BasChrGetCurr BEQ LDDB2 JSR GetDriveNoInB BRA LDDB5 LDDB2 LDB DosDefDriveNo LDDB5 STB <DosLastDrive JSR SuperDosGetFree BNE LDD7E TFR X,U CLRA BRA LDD99 FuncErl LDD $0617 LDDC4 JMP >VarAssign16Bit2 FuncErr CLRA LDB $0619 BRA LDDC4 FuncHimem LDD <AddrFWareRamTop BRA LDDC4 FuncFres JSR VarGarbageCollect LDD <BasVarStrTop SUBD <BasVarStringBase BRA LDDC4 ; ; The actual core disk IO routine, accepts a function code $00..$07 ; these are dispatched through this table ; DosFunctionTable FDB DosFunctionRestore ; Restore to track 0 FDB DosFunctionSeek ; Seek to a track FDB DosFunctionReadSec ; Read a sector FDB DosFunctionWriteSec ; Write a sector FDB DosFunctionWriteSec2 FDB DosFunctionWriteTrack ; Write (format) track FDB DosFunctionReadAddr ; Read address mark FDB DosFunctionReadSec2 ; Read first two bytes of a sector ; ; Data table for Format ? ; DDDEA FCB $01 FCB $0A FCB $02 FCB $0B FCB $03 FCB $0C FCB $04 FCB $0D FCB $05 FCB $0E FCB $06 FCB $0F FCB $07 FCB $10 FCB $08 FCB $11 FCB $09 FCB $12 FCB $00 DDDFD FCC /5NN/ FCB $08 FCB $00 FCB $00 FCB $03 FCB $F6 FCB $FC FCB $1F FCB $4E FCB $4E DDE09 FCB $07 FCB $00 FCB $00 FCB $03 FCB $F5 FCB $FE FCB $01 FCB $F7 FCB $4E FCB $14 FCB $4E FCB $4E FCB $0B FCB $00 FCB $00 FCB $03 FCB $F5 FCB $FB FCB $00 FCB $E5 FCB $F7 FCB $17 FCB $4E FCB $4E FCB $00 FCB $4E FCB $4E ; ; Data copied into low ram at init, inturrupt vectors etc ; DDE24 FCB $09 ; No bytes FDB $0109 ; address to copy ; Inturrupt vectors LDE27 JMP >NMISrv LDE2A JMP >IRQSrv LDE2D JMP >FIRQSrv ; Dos vars, step rates for drives FCB $04 ; No bytes FDB DosD0StepRate ; address to copy FCB SeepRateDefault FCB SeepRateDefault FCB SeepRateDefault FCB SeepRateDefault ; New basic dispatch stub FCB $1E ; No bytes IFEQ Tandy FDB BasStub1 ; Copy to stub 1 ($012A) on Dragons ELSE FDB BasStub2 ; Copy to stub 1 ($0134) on Tandy ENDC FCB $1A FDB DDEDA FDB LC670 FCB $07 FDB DDEC1 FDB LC68B FCB $00 FDB $0000 FDB BasSNError FCB $00 FDB $0000 FDB BasSNError FCB $00 FCB $00 FCB $00 FCB $00 FCB $00 FCB $00 FCB $00 FCB $00 FCB $00 FCB $00 ; No bytes : terminate FCB $00 CommandDispatchTable FDB CmdAuto ; Commented FDB CmdBackup FDB CmdBeep ifne DragonAlpha FDB BasSNError ; If assembling for Alpha, just redirect to ?SN error else FDB CmdBoot ; Else, if dragondos, boot command endc FDB CmdChain FDB CmdCopy FDB CmdCreate FDB CmdDir FDB CmdDrive FDB CmdDskInit FDB CmdFRead FDB CmdFWrite FDB CmdError2 FDB CmdKill FDB CmdLoad FDB CmdMerge FDB CmdProtect FDB CmdWait FDB CmdRename FDB CmdSave FDB CmdSread FDB CmdSwrite FDB CmdVerify FDB BasSNError FDB CmdFLRead FDB CmdSwap FunctionDipatchTable FDB FuncLof FDB FuncFree FDB FuncErl FDB FuncErr FDB FuncHimem FDB FuncLoc FDB FuncFres ; ; New ram hook table copied into low ram ; IFEQ Tandy ; Dragon Table RamHookTable FDB DosHookOpenDev ; open dev/file FDB DosHookCheckIONum ; check io num FDB DosHookRetDevParam ; return dev parameters FDB DosHookCharOut ; char output FDB DosHookRetDevParam ; char input FDB DosHookRetDevParam ; check dev open for input FDB DosHookRetDevParam ; check dev open for output FDB DosHookRetDevParam ; close all devs and files FDB DosHookCloseSingle ; close single dev/file FDB DosHookRetDevParam ; first char of new statement FDB DosHookDiskItem ; Disk file item scanner FDB DosHookRetDevParam ; poll for break FDB DosHookReadInput ; read line of input FDB DosHookRetDevParam ; finish loading ASCII program FDB DosHookEOF ; EOF function FDB DosHookRetDevParam ; Eval expression FDB DosHookRetDevParam ; User error trap FDB DosHookSysError ; System error trap FDB DosHookRun ; run statement ELSE ;CoCo Table. RamHookTable FDB DosHookOpenDev ; open dev/file FDB DosHookCheckIONum ; check io num FDB DosHookRetDevParam ; return dev parameters FDB DosHookCharOut ; char output FDB CoCoVect16A ; char input FDB DosHookRetDevParam ; check dev open for input FDB DosHookRetDevParam ; check dev open for output FDB DosHookRetDevParam ; close all devs and files FDB DosHookCloseSingle ; close single dev/file FDB CoCoVect179 ; first char of new statement FDB DosHookDiskItem ; Disk file item scanner FDB DosHookRetDevParam ; poll for break FDB DosHookReadInput ; read line of input FDB DosHookRetDevParam ; finish loading ASCII program FDB DosHookEOF ; EOF function FDB CoCoVect18B ; Eval expression FDB DosHookRetDevParam ; User error trap FDB DosHookSysError ; System error trap FDB DosHookRun ; run statement ENDC ; ; New Function names table ; DDEC1 FCC /LO/ FCB $C6 FCC /FRE/ FCB $C5 FCC /ER/ FCB $CC FCC /ER/ FCB $D2 FCC /HIME/ FCB $CD FCC /LO/ FCB $C3 FCC /FRE/ FCB $A4 ; ; New Command names table ; DDEDA FCC /AUT/ FCB $CF FCC /BACKU/ FCB $D0 FCC /BEE/ FCB $D0 FCC /BOO/ FCB $D4 FCC /CHAI/ FCB $CE FCC /COP/ FCB $D9 FCC /CREAT/ FCB $C5 FCC /DI/ FCB $D2 FCC /DRIV/ FCB $C5 FCC /DSKINI/ FCB $D4 FCC /FREA/ FCB $C4 FCC /FWRIT/ FCB $C5 FCC /ERRO/ FCB $D2 FCC /KIL/ FCB $CC FCC /LOA/ FCB $C4 FCC /MERG/ FCB $C5 FCC /PROTEC/ FCB $D4 FCC /WAI/ FCB $D4 FCC /RENAM/ FCB $C5 FCC /SAV/ FCB $C5 FCC /SREA/ FCB $C4 FCC /SWRIT/ FCB $C5 FCC /VERIF/ FCB $D9 FCC /FRO/ FCB $CD FCC /FLREA/ FCB $C4 FCC /SWA/ FCB $D0 ; ; Some mesagaes ; ; Dragon versions slightly more verbose, as I had to create space for extra ; code whenporting to RS-DOS cart, by shortening messages, iliminating ; whitespace etc ; IFEQ RSDos FCC /INSERT SOURCE / FCB $0D FCB $00 FCC /INSERT DESTINATION / FCB $0D MessPressAnyKey FCB $00 FCC /PRESS ANY KEY / FCB $0D FCB $00 ELSE FCC /INSERT SOURCE / FCB $0D FCB $00 FCC /INSERT DEST/ FCC /INATION / FCB $0D MessPressAnyKey FCB $00 FCC /PRESS ANY KEY / FCB $0D FCB $00 ENDC ; ; File extensions ; DosExtBas FCC /BAS/ DosExtDat FCC /DAT/ DosExtBin FCC /BIN/ DosExtNone FCC / / DosErrorCodeTable FCC /NRSKWPRTRFCCLDBTIVFDDFFSPTPEFFFENETFPR?/ DosSignonMess ifne DragonDos FCC /?SUPERDOS E6 / endc ifne DragonAlpha FCC /?SUPERDOS E7a/ endc ifne RSDos ifne Tandy FCC /?SUPERDOS E7C/ ; RSDos cart/Tandy CoCo else FCC /?SUPERDOS E7T/ ; RSDos cart/Dragon endc endc FCB $0D FCB $00 DosMoreMess FCB $00 IFEQ RSDos FCC / / ENDC FCC / MORE:/ FCB $00 FCB $00 ifne DragonDos FCC / / endc ; ; Drive lookup table used by Dragon Alpha ; ifne DragonAlpha FCC / / ADriveTab FCB Drive0,Drive1,Drive2,Drive3 ENDC ; ; Drive lookup table used on RS-DOS controler ; IFNE RSDos TDriveTab FCB Drive0,Drive1,Drive2,Drive3 ENDC LDFF3 LDA 2,X DECA BNE LDFFA STA 2,X LDFFA LDX DosCurLSN RTS FCB $61 FCB $34 ;DE000 END