	Hello,

	Thanks for using this MOUNT/XMOUNT routines on your TI-99

Requiered Hardware:
-------------------

	- CF7+ (if it works with the CF7, please tell me!)
	- Extended Basic
	- Ram expansion 32k
	- a TI 99/4A...


Limitation of CALL MOUNT:
-------------------------

	This rom routine allows you to mount one of your volumes into
	In XB, only a command, not into a program, and does not support something else than numeric constants:
	CALL MOUNT(1,23) works
	CALL MOUNT(A,B-5) doesn't
	CALL MOUNT(01,23) doesn't because the first constant must be a single digit...


Extensions with my routines:
----------------------------
	They are both command and instructions.
	They support numerical expressions for both parameters.

	Load it with:
	CALL INIT :: CALL LOAD("DSK1.XMOUNTOBJ")

	And then:
	CALL LINK("MOUNT",u,v) mounts volume V into unit DSKu, this information is lost after a RESET, so you keep your "boot" drive as before.

	CALL LINK("XMOUNT",u,v) the same, but this setting is preserved even after a reset, so can can mount auto-starting volumes that will run after a reset.

	DIM V(3)
	CALL LINK("DSKINF",V()) returns in V(1), V(2) and V(3) the mounted disks in each unit.

	LIMITATION: 
	1)	V value can't be more than 9999 for the XMOUNT routine and the same for DSKINF (9999 volumes with 400kb each = close to 4Gb, so a 8Gb CF card (because CF7 only uses half of the capacity)
	2)	V value can't be more than a word value in all cases (65535), 50Gb CF card.


Thanks:
-------
	to all the kind people met in the Yahoo TI99 group that took some of their precious time to guide me in my programming.

	
Well that's all:
----------------

	Well, that's all!

	Guillaume (guillaume.tello@orange.fr)


The commented source code:
--------------------------

* MOUNT A CF7 VOLUME INTO ONE
* OF THE THREE UNITS DSKn
*
* XB CALL:
* CALL LINK("MOUNT",N,V)
* N=1,2 OR 3 FOR DSKN
* V=VOLUME FROM 1 TO MAX
*
* CALL LINK("XMOUNT",N,V)
* FOR THE VERSION THAT RESIST
* TO A RESET
 
       DEF  MOUNT,XMOUNT,DSKINF
 
VMBW   EQU  >2024	multiple byte write to VDP RAM
VSBW   EQU  >2020	single byte write to VDP RAM
VMBR   EQU  >202C
NUMASG EQU  >2008
XMLLNK EQU  >2018	to call float to integer routine
NUMREF EQU  >200C	to get the CALL LINK parameters
FAC    EQU  >834A	the floating point accumulator
STATUS EQU  >837C	GPL status byte
 
MYREG  BSS  32		where my registers are
GPL    DATA >0020	mask to clear the GPL STATUS BYTE upon return

	this is the "useful" part of a pseudo basic line, when the ROM routine CALL MOUNT runs it expects finding 5,M,O,U,N,T,(,200,1,unit,179,200,4,v1,v2,v3,v4
	v1 to v4 being a 4 digit number in ASCII, example, 23 = 0,0,2,3
	The first seven bytes are skipped, so I only create the 10 last bytes into VDP RAM.

XBLINE BYTE 200,1,0,179,200,4
       BYTE 0,0,0,0
SAVEB  BSS  110		here to save the XB parameters.
ROMDSR DATA 0		here the ROM adress of MOUNT
CENT   DATA 100
 
XMOUNT
       LWPI MYREG
       SETO R5		R5 = FFFF for XMOUNT
       JMP  COMMON
 
MOUNT
       LWPI MYREG
       CLR  R5		R5 = 0000 for MOUNT
 
COMMON
       LI   R0,0
       LI   R1,1         UNIT 1-3 PARAM
       BLWP @NUMREF      GET PARAM
       BLWP @XMLLNK      TO INTEGER
       DATA >12B8
       MOV  @FAC,R4
 
       LI   R0,0
       LI   R1,2         DISK PARAM
       BLWP @NUMREF      GET PARAM
       BLWP @XMLLNK      TO INTEGER
       DATA >12B8
       MOV  @FAC,R1
 
       MOV  R5,R5	if R5<>0, then go to XMOUNT particular part
       JNE  DSREMU
 
	the non-reset-resistant part is very easy, it just writes the word "volume" into
VDP RAM location 16376+2u, u being the unit number.

       A    R4,R4
       AI   R4,16376     VDP ADR
       MOV  R4,R0
       BLWP @VSBW        HIGH OF DISK
       INC  R0           NEXT RAM POS
       SWPB R1
       BLWP @VSBW        LOW OF DISK
 
 
EXIT
       SZCB @GPL+1,@STATUS
       LWPI >83E0
       B    @>0070
 
* ROUTINE TO EMULATE A CALL MOUNT
* IT CREATES A PSEUDO BASIC LINE
* IN VDP RAM AND JUMPS TO THE
* ROM ROUTINE THAT INTERPRETS IT
 
DSREMU
       LI   R5,XBLINE+2
       AI   R4,>30       UNIT TO ASCII
       SWPB R4
       MOVB R4,*R5       UNIT TO LINE
 
       AI   R5,7         TO LAST DIGIT
       LI   R2,10
       LI   R6,4         4 DIGITS
 
DIGIT4
       CLR  R0
       DIV  R2,R0
       AI   R1,>30       ONE ASCII DIGIT
       SWPB R1
       MOVB R1,*R5       INTO LINE
       DEC  R5
       MOV  R0,R1
       DEC  R6
       JNE  DIGIT4
 
       AI   R5,-5
       MOV  R5,R1        BUF ADR
       MOV  @>8370,R0    LAST VDP FREE
       AI   R0,-11       ROOM FOR ME
       BLWP @VMBW        COPY PSEUDO LINE
 
	here, with data 0 saves the parameter block of the extended basic to a
buffer reserved as SAVEB because the rom routine overwrites a large part of it

       BL   @COPYB       SAVE BASIC PARAM
       DATA 0

	location >832C is used by the rom routine as a line pointer, so I put my
pseudo line adress in it. 

       AI   R0,-7
       MOV  R0,@>832C    MY LINE PTR
 
	here the common values into the registers when calling a DSR, the MOUNT routine
only uses R12 as far as I know

       LI   R12,>1100    CRU FOR DSR
       SBO  0            ENABLE >4000
       LI   R13,>9800    GROM READ
       STST R14          STATUS
       LI   R15,>8C02    VDPWA
 
	I store the ROM adress of MOUNT into ROMDSR. But, when run for the first time, 
this location is empty I the program has to find it once.

       MOV  @ROMDSR,R10  MOUNT ROM ROUTINE
       JEQ  FNDROM       IF 0, FIND IT!
TOROM
       BL   *R10         JMP TO MOUNT
       DATA 1966         DUMMY VALUE
SKIP
       BL   @COPYB       RESTORE PARAM
       DATA 1
 
	normally R12 should not be modufied by a ROM routine, but, who knows?...

       LI   R12,>1100    SECURITY
       SBZ  0            DISABLES >4000
       JMP  EXIT
 
* ROUTINE TO COPY THE BLOCK
* FROM >8300 TO >836D
* IN BOTH WAYS TO SAVE THE VITAL
* DATA OF THE BASIC INTERPRETER
 
COPYB
       MOV  *R11+,R6     WORD COMMAND
       JNE  RESTOR       IF 0 TO RESTORE
       LI   R6,SAVEB     ELSE TO SAVE
       LI   R7,>8300
       JMP  BLOCK
RESTOR
       LI   R6,>8300
       LI   R7,SAVEB
BLOCK
       LI   R1,55        110 BYTES
LOOP
       MOV  *R7+,*R6+
       DEC  R1
       JNE  LOOP
       B    *R11
 
* ROUTINE TO FIND "MOUNT"
* INTO THE ROM FROM >4000 WHERE
* BYTE >AA VALIDATES THE ROM.
* SUB PROGRAMS CHAIN POINTER IS
* LOCATED AT >400A
* THE CHAIN IS ORGANIZED AS THIS:
* WORD NEXT_SUBPROGRAM
* WORD ADR
* BYTE WORD LEN
* BYTES ASCII WORD
 
FNDROM
       LI   R0,>4000
       MOVB *R0,R10      NO NEED TO CLR R10
       CI   R10,>AA00    SIGNATURE
       JNE  SKIP
       AI   R0,10        GOTO ROUTINES POINTER
NEXT
       MOV  *R0,R0       NEXT ROUTINE
       JEQ  SKIP         NO MORE, EXIT
       MOV  R0,R1
       AI   R1,4         GOTO LEN+NAME
       MOV  *R1+,R2
       CI   R2,>054D     5 M
       JNE  NEXT
       MOV  *R1+,R2
       CI   R2,>4F55     O U
       JNE  NEXT
       MOV  *R1,R2
       CI   R2,>4E54     N T
       JNE  NEXT
       MOV  @-6(R1),R10  IF FOUND, INTO R10
       MOV  R10,@ROMDSR  AND STORED FOR NEXT CALL
       JMP  TOROM

DSKINF
       LWPI MYREG
       LI   R0,16378     VDP RAM
       LI   R1,SAVEB     CPU RAM
       LI   R2,6         6 BYTES
       BLWP @VMBR	 copy in CPU buffer the 3 mounted disks
 
       MOV  R1,R10       R10 as the volume tab pointer
       LI   R0,1         ARRAY INDEX
       MOV  R0,R1        FIRST PARAM
 
NXTDSK
       LI   R4,FAC
       CLR  R8
       MOV  *R10+,R9     VOLUME NUMBER
       DIV  @CENT,R8     R8 = quotient (zero if <100), R9=reminder
       MOV  R8,R8
       JNE  SUP100
       AI   R9,>4000     if less then 100 then exponent = 0
       MOV  R9,*R4+
       CLR  R9
       JMP  FILFAC
SUP100
       AI   R8,>4100     of more than 100 then exponent = 1
       MOV  R8,*R4+
       SWPB R9
FILFAC
       MOV  R9,*R4+
       CLR  R9
       MOV  R9,*R4+
       MOV  R9,*R4
 
       BLWP @NUMASG      assigns FAC to array element R0
 
       INC  R0           next element
       CI   R0,>0004     if 4, stop
       JNE  NXTDSK       else goto next
       B    @EXIT  
 
       END

