
**********************************************************************
files: RAMdisk.TXT, RAMdisk.TAP
       RAMdskStat.BAS, CAT!RAM.BAS, PUTRAM.ASM
**********************************************************************


** RAMdisk functions
   =================

The first two items only work on the +128/+2, as the system variables used don't exist on the +2A/+3.

   =================

This shows how to get the RAMdisk file stats into program variables. F$() holds names, F() holds start,size,end. Line 15 swaps in the RAM page which holds the RAMdisk catalogue and line 25 swaps in the normal page. RAMTOP should probably be below 49152 ($C000) or things might go horribly wrong. Note that file sizes include a 9-byte header.

RAMdskStat.BAS [code]
  10 LET sfnext=PEEK 23427+256*PEEK 23428:
  11 DIM f$(20,10): DIM f(20,3): LET n=0
  15 OUT 32765,16+7: POKE 23388,16+7
  20 FOR a=sfnext+20 TO 60415 STEP 20: LET n=n+1
  21 FOR b=a TO a+9: LET f$(n,b-a+1)=CHR$ PEEK b: NEXT b
  22 FOR b=a+10 TO a+16 STEP 3: LET f(n,(b-a-7)/3)=PEEK b+256*PEEK (b+1): NEXT b
  24 NEXT a
  25 OUT 32765,16: POKE 23388,16
  30 FOR a=1 TO n: PRINT f$(a): FOR b=1 TO 3: PRINT f(a,b);" ";: NEXT b: PRINT : NEXT a
[/code]


   =================

Details of the last RAMdisk file accessed are held in the system variables:

[code]
N_STR1   23399-23408    name
HD_00    23409          file type
HD_0B    23410          length of block
HD_0D    23412          start of block
HD_0F    23414          if a program: length of program
HD_11    23416          if a program: auto-run line number
[/code]


**********************************************************************


CAT!RAM and PUTRAM
==================
CAT!RAM catalogues the 128k RAMdisk in BASIC.
PUTRAM moves RAMTOP and the stacks from BASIC.
CAT!RAM will work on any 128k Spectrum; PUTRAM will work on any Spectrum.

As CAT!RAM is in BASIC and is swapping around RAM pages to get at the RAMdisk catalogue and file info, it needs RAMTOP to be below $C000 so that the stacks are preserved. It checks for this and if necessary calls PUTRAM to temporarily put RAMTOP and the stacks below $C000 and then puts them back where they were afterwards. Lines 9905 & 9950 can be deleted if it is known that RAMTOP will be below the threshold.

CAT!RAM prints file name & type, RAMdisk page-coded location & size, file save address & size, program size & auto-start line, array name. With the printing disabled or optional it can also be used to check if a file actually exists before attempting to save, load or erase it.

PUTRAM allows RAMTOP to be moved anywhere (including anywhere stupid) from within a BASIC program while preserving the m/c stack and GOSUB stack and BASIC variables; it also updates (ERR_SP). I use it to make more or less space available for BASIC or m/code while a program is running. There's a related UNDEFINE program which reclaims space in VARS as well.


CAT!RAM.BAS [code]
   3 REM CAT!RAM print the RAMdisk catalogue & file data
   4 DEF FN p(a)=PEEK a+256*PEEK (a+1)
9900 LET a=FN p(23427): LET e=(60416-(a+20))/20:
     IF NOT e THEN PRINT "No Files": RETURN
9901 REM move RAMTOP & m/c stack & GOSUB stack below $C000 if needed
9905 LET r=FN p(23730): IF r>49151 THEN LET m=48000: RANDOMIZE 49151+USR m
9910 DIM f$(e,10): DIM f(e,8): LET p$="13467"
9920 FOR n=1 TO e: POKE 23388,16+7:
       REM RAMdisk catalogue: file name
9921   LET a=a+20: FOR b=a TO a+9: LET f$(n,b-a+1)=CHR$ PEEK b: NEXT b:
9922   REM RAMdisk catalogue: file storage details ((2+1)*3 bytes lo,mid,hi)
9923   REM (page codes 0,1,2,3,4 <=> RAM pages 1,3,4,6,7)
9924   REM start, page code, length of header+file, 0, following, page code
9925   REM error flag byte
9927   LET d=1: FOR b=a+10 TO a+16 STEP 3:
         LET f(n,d)=FN p(b)+VAL p$(PEEK (b+2)+1)/10: LET d=d+1: NEXT b
9929   REM select page where file starts & locate header
9930   LET h=INT f(n,1): POKE 23388,16+(f(n,1)-h)*10: LET f(n,4)=PEEK h
9931   REM 1   type: 0=program, 1=numeric array, 2=string array, 3=bytes
9932   REM 2,3 file length - header; 4,5 saved from address
9933   REM 6,7 program length, or array name; 8,9 auto-run line number
9935   LET d=5: FOR b=h+1 TO h+7 STEP 2:
         LET f(n,d)=FN p(b): LET d=d+1: NEXT b
9940   LET t=f(n,4): PRINT f$(n),t:
       PRINT " RAMd: ";f(n,1);TAB 15;INT f(n,2);TAB 21;f(n,3):
       PRINT " File: ";f(n,6);TAB 15;f(n,5);
9941   IF NOT t THEN
         PRINT TAB 21;f(n,7);TAB 27;f(n,8) AND f(n,8)<10000
9942   IF t=1 OR t=2 THEN
         PRINT TAB 21;CHR$ (f(n,7)-32768-64-(64 AND t=2))+("$" AND t=2)+"()"
9943   IF t>=3 THEN
         PRINT
9945 NEXT n: POKE 23388,16+0
9949 REM restore RAMTOP & m/c stack & GOSUB stack before RETURNing
9950 IF r>49151 THEN RANDOMIZE r+USR m
9951 RETURN
[/code]


PUTRAM.ASM [code]
;Change RAMTOP to "val" while preserving variables & GOSUBs
;RANDOMIZE val+USR putram
        org  48000
PUTRAM: di
        ld   hl,$0000
        add  hl,sp           ;HL=stack pointer
        ld   de,(23730)      ;(RAMTOP) = old RAMTOP
        ex   de,hl
        and  a
        sbc  hl,de           ;(RAMTOP)-SP
        ld   b,l
        inc  b               ;B =number of bytes to copy
        add  hl,de
        ld   ix,(23653)      ;STKEND
        ld   d,(ix-2)
        ld   e,(ix-3)        ;DE=new RAMTOP
        ld   (23730),de
COPYON: ld   a,(hl)
        ld   (de),a
        dec  hl
        dec  de
        djnz COPYON
        sbc  hl,de           ;HL=displacement
        ld   de,(23613)      ;(ERR_SP)
        ex   de,hl
        and  a
        sbc  hl,de
        ld   (23613),hl      ;adjust (ERRSP)
        ld   hl,$0000
        add  hl,sp
        sbc  hl,de
        ld   sp,hl           ;adjust SP
        ei
        ret
[/code]
