         .TAB 11,15,27
         .SET 1,7
         .TITLE "RAMDISK FOR FMS VERSION 2             05-25-85"
;
********* ZERO PAGE **********
;
RTCLKL   =   $14
BUFRL    =   $32     ;SIO ZPG, CAN USE
BFENL    =   $34     ;SIO ZPG, CAN USE
;
******** OTHER RAM ***********
;
INITAD   =   $02E2
DVSTAT   =   $02EA
DRVBYT   =   $070A   ;DRIVE BITS
SASA     =   $070C   ;END FMS CODE
DSIO4    =   $07A2   ;FMS 2 SIO CALL
FMSINIT  =   $07E0
DIHCL    =   $0816   ;FMS 2 NORM STAT CALL
WRTDOS   =   $120A   ;FMS 2 WRITE DOS ENTRY
ERDVDC   =   $12BF   ;FMS INVALID CMD ERR
TSTLC    =   $4000   ;EXTRA RAMS
VTOCP    =   $7200   ;XRAM VTOC
RDIHCL   =   $E536   ;DOSXL.XL STAT CALL
;
********** OS ROM *************
;
DHADR    =   $E453   ;OS RES DISK
SIOV     =   $E459   ;SIO ENTRY ADDR
;
********* CONSTANT ************
;
RAMDRV   =   4       ;DRIVE # OF RAMDISK
;
****** I/O REGISTERS **********
;
PORTB    =   $D301
NMIEN    =   $D40E
;
;
*********** DCB ***************
;
;
DDEVIC   =   $0300   ;SERIAL BUS ID
DUNIT    =   $0301   ;UNIT NUMBER
DCOMND   =   $0302   ;COMMAND
DSTATS   =   $0303   ;DIRECTION/STATUS
DBUFLO   =   $0304   ;BUF ADDR LO
DBUFHI   =   $0305   ;         HI
;
;
DAUX1    =   $030A   ;DEVICE INFO (SECT LO)
DAUX2    =   $030B   ;  "     "   (     HI)
;
;
;
;
******                 *********
****** RAMDISK HANDLER *********
******                 *********
;
         *=  $3800   ;WILL RELOCATE
;
; SIO CALL TO HERE
;
SECIO    LDA DUNIT
         CMP #RAMDRV
         BEQ SECIO1
         JMP SIOV
;
SECIO1   LDA DAUX2   ;HI SECT
         CMP #2
         BCC TGSEC   ;IN RANGE
         BNE BDSEC   ;RIDICULOUS
         LDA DAUX1
         CMP #4
         BCC TGSEC   ;BR IF < 516
;
BDSEC    LDY #144
         STY DSTATS
         RTS 
;
TGSEC    LDA DAUX2
         BNE NRMSC   ;BR IF SEC> 255
;
TSCLO    LDA DAUX1
         CMP #4      ;HI WAS ZERO
         BCS NRMSC   ;DO TRANS IF 4+
         LDY #1
         STY DSTATS  ;ELSE LIE
         RTS 
;
NRMSC    SEC         ;READY TRANSFER
         LDA DAUX1   ;SECTOR LO
         SBC #4
         STA BFENL   ;RAMDISK 4 THRU 515
         LDA DAUX2
         SBC #0
         ASL BFENL   ;EXTRA RAM PG UPPER
         ROL A       ;2 BITS
         ASL A
         ASL A
         STA BFENL+1 ;AT BITS 2 AND 3
         LDX RTCLKL
WVLP     CPX RTCLKL
         BEQ WVLP    ;WAIT 'TIL END VBLANK
         LDA #0
         STA NMIEN   ;TURN OFF NMI
         SEI         ;     AND IRQ
         LDA PORTB   ;MEM CONTROL
         TAX         ;NORM IN X
         AND #$E3
         ORA BFENL+1
         PHA         ;RMDSK ON STACK
         LDA BFENL   ;SECT # REMAINDER
         SEC         ;+ $40 (WILL BE)
         ROR A
         LSR A       ;LSB TO C
         STA BFENL+1 ;IS HIGH ADDR
         LDA #0
         ROR A       ;SECT LSB = 128 BYTES
         STA BFENL
         LDA DBUFLO
         STA BUFRL   ;SET I/O ADDRESS
         LDA DBUFHI
         STA BUFRL+1
         LDY #127
         LDA DSTATS
         BMI SCWRT   ;BR IF 'TO DISK'
SECRD    PLA         ;ELSE
         PHA 
         STA PORTB   ;RMDSK
         LDA (BFENL),Y ;IS SOURCE
         STX PORTB   ;NORM
         STA (BUFRL),Y ;IS DEST
         DEY 
         BPL SECRD
         BMI SCDON
;
SCWRT    PLA         ;FOR WRITE,
         STX PORTB
         TAX         ;SWAP SO THAT
         LDA PORTB
         PHA 
SCWT1    PLA 
         PHA 
         STA PORTB   ;NORM
         LDA (BUFRL),Y ;IS SOURCE
         STX PORTB   ;RMDSK
         STA (BFENL),Y ;IS DEST
         DEY 
         BPL SCWT1
;
         TXA 
         AND #$0C
         CMP #8      ;VTOC BANK?
         BNE SCDON   ;BR NO
         LDX #1
         CPX VTOCP+2 ;TEST MAXSEC HI
         BEQ SCDON   ;ASSUME OK
         LDA VTOCP+3
         SBC #707-504 ;ALSO BORROW
         BCS SCWT2
         DEC VTOCP+4
         BPL SCWT2
         LDA #0
         STA VTOCP+4
SCWT2    STA VTOCP+3 ;FREE SECTS
         STX VTOCP+2
         LDA #$F7
         STA VTOCP+1 ;& MAX SECTS
;
SCDON    PLA         ;FIX STACK
         LDA PORTB
         AND #$E3
         ORA #$1C
         STA PORTB   ;NORM
         LDA #$C0
         STA NMIEN   ;ENABLE NMI
         CLI         ;   AND IRQ
         LDA #0
         LDY #1
         STY DSTATS  ;AFFIRM GOOD
         RTS 
;
SCIOLN   =   *-SECIO
;
********* DRIVE STATUS ********
;
DRSTAT   LDA DUNIT
         CMP #RAMDRV
         BEQ RMSTA
         JMP DHADR
;
RMSTA    LDA #0
         STA DVSTAT
         STA DVSTAT+1
         STA DVSTAT+3
         LDY #1
         STY DVSTAT+2 ;128 BYTE SECTS
         RTS 
;
RELEN    =   *-SECIO ;RELOCATE LENGTH
;
;
;
*****                      *****
***** INSTALLATION ROUTINE *****
*****                      *****
;
INSTALL  LDA DSIO4+1 ;SIO CALL?
         CMP # <SIOV
         BNE NOPE
         LDA DSIO4+2
         CMP # >SIOV
         BNE NOPE
;
******* 130XE TEST *********
;
         LDA PORTB
         TAX         ;SAVE NORM CONFIG
         AND #$EF
         TAY         ;SAVE EXTRA CONFIG
         STY PORTB
         LDA TSTLC   ;GET EXTRA BYTE
         STX PORTB   ;SET NORM
         CMP TSTLC
         BNE CNTIN   ;BR IF EXTRA
         LDA TSTLC
         EOR #$FF    ;COMPLEMENT NORM
         STA TSTLC
         STY PORTB   ;SET EXTRA
         CMP TSTLC
         PHP         ;SAVE COMPARE RESULT
         STX PORTB
         EOR #$FF    ;UNCOMPLEMENT
         STA TSTLC   ;& REPAIR NORM
         PLP 
         BNE CNTIN   ;BR IF EXTRA
NOPE     JMP NONE
;
CNTIN    LDA DIHCL+1 ;NORM V2 STAT CALL?
         CMP # <DHADR
         BNE NOTLO
         LDA DIHCL+2
         CMP # >DHADR
         BEQ DS2LO   ;IF SO, CAN INSTALL
;
NOTLO    LDA #0      ;ELSE DOSXL.XL STAT CALL?
         LDX RTCLKL
IVBLP    CPX RTCLKL
         BEQ IVBLP
         STA NMIEN
         SEI 
         LDA PORTB
         AND #$FE
         STA PORTB
         LDA RDIHCL+1
         CMP # <DHADR
         BNE NOTFN
         LDA RDIHCL+2
         CMP # >DHADR
         BNE NOTFN
         JSR COPYDOWN ;YES...DO MOVE
         LDA DRSADR  ;& REPLACE STAT CALL
         STA RDIHCL+1
         LDA DRSADR+1
         STA RDIHCL+2
         LDA PORTB
         ORA #1
         STA PORTB
         LDA #$C0
         STA NMIEN
         CLI 
         JMP D2HAV
;
NOTFN    LDA PORTB   ;NO, JUST BACK TO OS
         ORA #1
         STA PORTB
         LDA #$C0
         STA NMIEN
         CLI         ;INTS ENABLED
NONE     RTS         ;AND OUT
;
DS2LO    JSR COPYDOWN ;LO FOUND
         LDA DRSADR
         STA DIHCL+1 ;REPLACE STAT CALL
         LDA DRSADR+1
         STA DIHCL+2
         LDA #$4C    ;JMP INSTRUCTION
         STA WRTDOS
         LDA # <ERDVDC ;TO INVALID CMD
         STA WRTDOS+1
         LDA # >ERDVDC ;DISABLES DOS WRITE
         STA WRTDOS+2
;
D2HAV    CLC         ;EITHER,
         LDA SASA
         ADC # <RELEN ;ADD INSTALLED LENGTH
         STA SASA    ;TO END FMS VALUE
         LDA SASA+1
         ADC # >RELEN
         STA SASA+1
         JSR FMSINIT ;& REINIT FMS
;
******* FORMAT 'DISK' ********
;
         LDX RTCLKL
FMT      CPX RTCLKL
         BEQ FMT     ;WAIT VBL
         LDA #0
         STA NMIEN
         SEI         ;DISABLE INTS
         LDA PORTB
         AND #$E3
         PHA 
         ORA #8
         STA PORTB   ;VTOC BANK
         LDX #0
         LDA $7200   ;1ST VTOC BYTE
         CMP #2
         BEQ VTST2
         INX 
VTST2    LDA $7201   ;2ND
         CMP #$F7
         BEQ VTST3
         INX 
VTST3    LDA $7202   ;3RD
         CMP #1
         BEQ VTSTN
         INX 
VTSTN    PLA 
         CPX #0
         BEQ FMTDN   ;OUT, PREVIOUSLY DONE
FLP1     STA PORTB
         LDA #$40
         STA BUFRL+1
         TAX 
         LDA #0
         STA BUFRL
         TAY 
FLP2     STA (BUFRL),Y ;CLEAR ALL DISK
         INY 
         BNE FLP2
         INC BUFRL+1
         DEX 
         BNE FLP2
         CLC 
         LDA PORTB
         ADC #4
         PHA 
         AND #$0C
         BEQ FCDON
         PLA 
         BNE FLP1
;
FCDON    PLA         ;FIX STACK
         LDA PORTB
         AND #$E3
         ORA #8
         STA PORTB   ;SET VTOC BANK
         LDA #$72
         STA BUFRL+1 ;AND PAGE
         LDY #0
         LDA #2
         STA (BUFRL),Y ;'DOS 2'
         INY 
         LDA #$F7    ;503 SECTORS
         STA (BUFRL),Y
         INY 
         INY 
         STA (BUFRL),Y
         DEY 
         LDA #1
         STA (BUFRL),Y
         INY 
         INY 
         STA (BUFRL),Y
         LDY #10
         LDA #$0F
         STA (BUFRL),Y ;SECTS 4-7 AVAILABLE
         LDA #$FF
SXF2     INY 
         STA (BUFRL),Y ;SECTS 8-519 AVAIL
         CPY #74
         BNE SXF2
         LDA #$F0
         STA (BUFRL),Y ;516-519 IN USE
         LDY #55
         LDA #0
         STA (BUFRL),Y ;360-367 IN USE
         INY 
         LDA #$7F
         STA (BUFRL),Y ;368 IN USE
FMTDN    LDA PORTB
         ORA #$1C
         STA PORTB   ;NORMAL RAM
         LDA #$C0
         STA NMIEN   ;NMI ENABLE
         CLI         ;IRQ ENABLE
         RTS         ;& OUT
;
; MOVE RELOCATABLE CODE
; AND REPLACE SIO CALL
;
COPYDOWN LDX #RAMDRV
         LDA #0
         SEC         ;SINGLE BIT
DRVLP    ROL A       ;SHIFT TO DRV POS
         DEX 
         BNE DRVLP
         ORA DRVBYT  ;MERGE OTHERS
         STA DRVBYT  ;& REPLACE
         LDA SASA
         STA BUFRL   ;SET MOVE DEST
         LDA SASA+1
         STA BUFRL+1
         LDA # <SECIO
         STA BFENL   ;& SOURCE
         LDA # >SECIO
         STA BFENL+1
         LDX # >RELEN
MVLP1    DEX 
         BMI MPART
         LDY #0
MVLP2    LDA (BFENL),Y ;MOVE A PAGE
         STA (BUFRL),Y
         INY 
         BNE MVLP2
         INC BUFRL+1
         INC BFENL+1
         BNE MVLP1
         BEQ MVLP1
MPART    LDY # <RELEN
MPRT1    LDA (BFENL),Y ;& PART PAGE
         STA (BUFRL),Y
         DEY 
         BNE MPRT1
         LDA (BFENL),Y
         STA (BUFRL),Y
         CLC 
         LDA SASA
         STA DSIO4+1 ;AS SECT I/O CALL
         ADC # <SCIOLN ;PLUS FIRST LEN
         STA DRSADR  ;AS STAT CALL ADDR
         LDA SASA+1
         STA DSIO4+2
         ADC # >SCIOLN
         STA DRSADR+1
         RTS 
;
DRSADR   *=  *+2
;
         *=  INITAD
         .WORD INSTALL
;
