toastrack ramdrive viewer, step 1

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

toastrack ramdrive viewer, step 1

Post by cborn »

first stap seems working
based on my basic ramdrive viewer:
www.cborn.nl/zxfiles/RAMLOAD012.bas

load a file with LOAD! "name" and test it

Code: Select all

// ramdrive021c
// zcc +zx -v -lm -startup=31 ramdrive021c.c -o ramdr021c -lndos -create-app --list --c-code-in-asm

// read the contence off the early zx spectrum 128 'toastrack' Ramdrive

 #include <stdio.h>

 static __at(23429) unsigned long LEFTMEMORY ;
 

//-------------------------------------------------
void preskey( int cls)
{
char key;
printf("Press a key");
scanf("%c",&key ) ;
if (cls == 1) {printf("\xC");}
return ;
}
//-------------------------------------------------

//                    //( 2nd     ,    1st     )   ret
int  __CALLEE__   fetchheader(int lowermemoryadres, int headeradres) __naked {
//      POKE VAL "23388",pg: OUT VAL "32765",pg: RETURN 
//	int *rambank=23388;   // sysvar to save value
//	int  ramport=32765;   // port to write value to
#asm
           di                 // disable interrupt for save RamBank switching
           pop bc             // fetch return addres s
           pop hl             // headerstart adres
           pop de             // copy destiny adres
           push bc            // reinstall return address on stack
          
           ld a,(23388)
	   or 7               // set bank 7
	   ld bc,32765
	   out (c),a          // signal page
	   
	   ld bc,20  // BC=headerlength , HL=headerinfo, DE=destiny
	   ldir      // copy header info to LOWER MEMORY
  	   ld bc,32765
  	             // a_reg still holds RAMBANK info
	   and 247   // cut page info to 0
	   out (c),a             // signal page
           ei
	   ret
#endasm
           }
           
//-------------------------------------------------
          
	    // attempt to build nececary parts
struct rd_header    // header is stored in BANK 7 and has to be retrieved in 'one  go' switch7/fetch/switch0
 {                          //DEF FN p(a)=PEEK a+256*PEEK (a+1)
  unsigned char name[10] ;  // FOR y=x TO VAL "x+9": LET u$=u$+CHR$ PEEK y: NEXT y:
  unsigned char logicbank ; // : LET logicbank=PEEK VAL "x+12"
  unsigned char bk2 ;       // : LET bk2=PEEK VAL "x+15":
  unsigned char bk3 ;       //   LET bk3=PEEK VAL "x+18"
  unsigned char ch ;        // : LET ch=PEEK VAL "x+19"
  unsigned char bank ;      // : LET bank=VAL "134670"(logicbank+1)
  unsigned char page ;      // 

  unsigned int length ;     // : LET bk2=PEEK VAL "x+15"
  unsigned int strt ;       // : LET strt=FN p(VAL "x+10")
  
	                    //: DEF FN z(a)=FN p(a)+16384*PEEK (a+2)   << 1 bank = 16k !! correct value ??  
  unsigned long leng ;      //   LET leng=FN z(VAL "x+13")
  unsigned long start ;     //   LET start=FN z(VAL "x+10")
  unsigned long end ;       // : LET end=FN z(VAL "x+16")
 };

//-------------------------------------------------
          

   main (){

           unsigned long mem_count ;  //*leftmemory

           unsigned int *rd_counter=23427, rd_count , filecount ;  //LET el=FN p(VAL "23427")
	   unsigned int *rd_files=23427 ;

	   unsigned int rd_bottom=49512, rd_middle=56424, rd_top=60415 ; // rt=VAL "60415" rb=VAL "49512" rm=VAL "rb+6912"
	   unsigned int rd_entrysize=20 ;  // ram file header size or entry size
	   unsigned int rd_header=9 ;      // small infile header to confirm big entry header
	   unsigned int x,  ram0=0, rdisc=7 ;  // ram=VAL "16" rdisc=VAL "16+7"

	   unsigned char discstr[64+1] ;        // DIM z$(VAL "64")
	   unsigned char headerinfo[20] ;
	   unsigned char logicbank[]="134670"  ;//logicbank
	   unsigned char oldpage , lastpage ;
	   
	   rd_count=*rd_counter;
	   mem_count=LEFTMEMORY & 0x00FFFFFF ;// 3bytes 
	   printf("\xCRamdrive contence \n address %6u points to %6u \n",rd_counter, rd_count ) ;
	   
	   filecount = (rd_top -20 -rd_count +1 ) /20 ;  // LET fl=VAL "(rt-20-el+1)/20"
           printf("%4u file entries found in RamDrive\n",filecount);
	   printf("%7lu bytes memory left\n",mem_count);

	   fetchheader(headerinfo,rd_count+20) ;
           for (x=0;x<20;x++){ printf("%4d %c ",headerinfo[x],headerinfo[x]); } 
	   printf("\n");
	   
	   preskey(1);
	   
           return 0;
   }
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: toastrack ramdrive viewer, step 1

Post by stefano »

Are you thinking at comething specific ? EG a file driver or a low level library ?

EDIT: ok, I found the answer on your other post :)
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

Hi, i never build a library.
it would be nice if i can get a good struct that might work as a header file. that could be the start of a lib of what ever.
and low level is what i can so it will be simple i guess. If i can aim the struct to a specific memory part, that would be nice.
momentary it fetches 20 bytes and moves back to ram0 and thus C asap, in a single move. Since a DI/EI set is needed i think that the bankswitching always will be an asm part. in ZX Basic its no problem but it has its 'lib' , the rom, in the lower 16k ofcourse...
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

one step forward and one step back. It did show the file name but not any longer.
i renamed since its a catalogue viewer, hence ramcat if you like. do i need to make it into a pointer?
if someone has a good line its welcome!
if that works then the next part will be fetching the 9byte progheader which can be ANYwere in almost any ram. thats why i addapted the fetchblock a bit. becarefull with the bank value you set, there is NO check on that value so a crash is easily made!!
any comment and.or improvement is welcome ;-)

Code: Select all


// ramcat028
// zcc +zx -vn -lm -startup=31 -zorg 0x7000 ramcat028.c -o ramcat028 -lndos -create-app -Cz --noloader --list --c-code-in-asm
// cat ramcatBAS.tap ramcat028.tap > testramcat028.tap


// Catalogue WIP for the contence off the early zx spectrum 128 'toastrack' RamDrive


// https://github.com/ZXSpectrumVault/rom-disassemblies/blob/master/Spectrum%20128K/Spectrum128_ROM0.asm
// ------------------
// RAM Disk Catalogue
// ------------------
// The catalogue can occupy addresses $C000-$EBFF in physical RAM bank 7, starting at $EBFF and growing downwards.
//
// Each entry contains 20 bytes:
//   Bytes $00-$09: Filename.
//   Bytes $0A-$0C: Start address of file in RAM disk area.
//   Bytes $0D-$0F: Length of file in RAM disk area.
//   Bytes $10-$12: End address of file in RAM disk area (used as current position indicator when loading/saving).
//   Byte  $13    : Flags:
//                     Bit 0   : 1=Entry requires updating.
//                     Bits 1-7: Not used (always hold 0).

//
// A file consists of a 9 byte header followed by the data for the file. The header bytes
// have the following meaning:
//   Byte  $00    : File type - $00=Program, $01=Numeric array, $02=Character array, $03=Code/Screen$.
//   Bytes $01-$02: Length of program/code block/screen$/array ($1B00 for screen$).
//   Bytes $03-$04: Start of code block/screen$ ($4000 for screen$).
//   Bytes $05-$06: Offset to the variables (i.e. length of program) if a program. For an array, $05 holds the variable name.
//   Bytes $07-$08: Auto-run line number for a program ($80 in high byte if no auto-run).



 #include <stdio.h>

 static __at(23429) unsigned long LEFTMEMORY ;
 

//-------------------------------------------------
void preskey( int cls)
{
char key;
printf("Press a key");
scanf("%c",&key ) ;
if (cls == 1) {printf("\xC");}
return ;
}
//-------------------------------------------------

//                         //(        4th    ,  3rd     ,             2nd     ,        1st     )   ret
int  __CALLEE__   fetchheader(int blocklength, char bank, int lowermemoryadres, int headeradres) __naked {

#asm
                              // ALWAYS RETURNS WITH RAM 0 SET !!!
           di                 // disable interrupt for save RamBank switching
           pop bc             // fetch return addres
           exx

           pop hl             // source cq headerstart adres
           pop de             // destiny adres
           pop bc             // length
           ld a,c
           ex af,af              // save BANK number
           pop bc
           exx
           push bc            // reinstall return address on stack
           exx

           push bc            // save length on stack
           ex af,af
           ld b,a
           ld a,(23388)
           or b               // set bank 7
           ld bc,32765
           out (c),a          // signal page

           pop bc             // BC=headerlength , HL=headerinfo, DE=destiny
           ldir               // copy header info to LOWER MEMORY

           ld bc,32765        // a_reg still holds RAMBANK info
           and 247            // cut page info to 0
           out (c),a          // signal page
           ei
           ret
#endasm
           }  // ALWAYS RETURNS WITH RAM 0 SET !!!
//-------------------------------------------------


          

  main(){

  
    unsigned long mem_count ;  //*leftmemory

    unsigned int *rd_counter=23427, rd_count , filecount ,tempaddress ;  //LET el=FN p(VAL "23427")

	   unsigned int rd_bottom=49512, rd_middle=56424, rd_top=60415 ; // rt=VAL "60415" rb=VAL "49512" rm=VAL "rb+6912"
	   unsigned int rd_headersize=20 ;  // ram file header size or entry size @ram_7
	   unsigned int rd_smheader=9 ;      // small infile header to confirm big entry header @ram_x
    unsigned int ram0=0, rdisc=7 ;  // ram=VAL "16" rdisc=VAL "16+7"
	   unsigned int x,y ;

	   unsigned char discstr[64+1] ;        // DIM z$(VAL "64")
	   unsigned char headerinfo[20+1] ;
	   unsigned char logicbankstr[]="134670"  ;//logicbank
	   
	   rd_count=*rd_counter;
	   mem_count=LEFTMEMORY & 0x00FFFFFF ;// 3bytes 
	   filecount = (rd_top -20 -rd_count +1 ) /20 ;  // LET fl=VAL "(rt-20-el+1)/20"

	   printf("\xCRamdrive %6u points to %6u \n",rd_counter, rd_count ) ;
    printf("%4u file found, %7lu bytes left\n",filecount,mem_count);

    tempaddress = rd_top -20;
	   if (filecount > 0){
		  for (x=0;x<filecount;x++){ 
         fetchheader(rd_headersize, rdisc, headerinfo,tempaddress) ;  // rambank=7  !!!

            unsigned char name[10+1] ;               // FOR y=x TO VAL "x+9": LET u$=u$+CHR$ PEEK y: NEXT y:
            unsigned int strt=headerinfo[10] ;        // LET strt=FN p(VAL "x+10")
            unsigned char logicbank=headerinfo[2] ;   // LET logicbank=PEEK VAL "x+12"
            unsigned char blocks_leng=headerinfo[15] ;// LET blocks_leng=PEEK VAL "x+15":
            unsigned char blocks_end=headerinfo[18]  ;// LET blocks_end=PEEK VAL "x+18"
            unsigned char changed=headerinfo[19]  ;   // LET ch=PEEK VAL "x+19"
            unsigned char bank;
            bank=logicbankstr[logicbank+1] ;          // : LET bank=VAL "134670"(logicbank+1)

            unsigned char page ;                      // 
            unsigned int length ;                     // : LET blocks_leng=PEEK VAL "x+15"

            //: DEF FN z(a)=FN p(a)+16384*PEEK (a+2)   << 1 bank = 16k !! correct value ??  
            unsigned long start=headerinfo[10]  ;     //   LET start=FN z(VAL "x+10")

            start = start & 0x0000FFFF ;
            start = start  + logicbank *16384 ;

            unsigned long leng=headerinfo[13] ;       //   LET leng=FN z(VAL "x+13")
            leng  = leng & 0x0000FFFF ;
            leng = leng + blocks_leng *16384 ;
  
            unsigned long end=headerinfo[16]  ;       // : LET end=FN z(VAL "x+16")
            end   = end & 0x00FFFFFF ;
            end   = end + blocks_end *16384 ;
  
            for (y=0;y<10;y++){ name[y]=headerinfo[y]; } ;
            name[10]='\0';
            printf("file %d at %d\n",x,tempaddress);
            printf("name: %s\n",name );
            printf("(logic)bank: %u %u  ..  %c  %c\n",logicbank ,bank ,logicbank ,bank );
            printf("strt: %u\n",strt );
            printf("leng: %lu\n",leng );
            printf("start: %lu\n",start );
            printf("end: %lu\n",end );

            tempaddress=tempaddress-20 ;  //  topdown is apearing order (while CAT! function results alphabetic)

            preskey(1);	  
          } // end 'for filecount'
      } //end 'if filecount'

  return 0;
 }



//	   struct rd_header    // header is stored in BANK 7 and has to be retrieved in 'one  go' switch7/fetch/switch0
// {                          //DEF FN p(a)=PEEK a+256*PEEK (a+1)
//  unsigned char name[10+1] ;  // FOR y=x TO VAL "x+9": LET u$=u$+CHR$ PEEK y: NEXT y:
//  unsigned char logicbank ; // : LET logicbank=PEEK VAL "x+12"
//  unsigned char blocks_leng ;       // : LET blocks_leng=PEEK VAL "x+15":
//  unsigned char blocks_end ;       //   LET blocks_end=PEEK VAL "x+18"
//  unsigned char ch ;        // : LET ch=PEEK VAL "x+19"
//  unsigned char bank ;      // : LET bank=VAL "134670"(logicbank+1)
//  unsigned char page ;      // 
//  unsigned int length ;     // : LET blocks_leng=PEEK VAL "x+15"
//  unsigned int strt ;       // : LET strt=FN p(VAL "x+10")
//: DEF FN z(a)=FN p(a)+16384*PEEK (a+2)   << 1 bank = 16k !! correct value ??
//  unsigned long leng ;      //   LET leng=FN z(VAL "x+13")
//  unsigned long start ;     //   LET start=FN z(VAL "x+10")
//  unsigned long end ;       // : LET end=FN z(VAL "x+16")
// };
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

i use a Basic loader to load different types off files to RamDrive
NOT PI is a short noting off the number '0' and saves 5 bytes in memory of zx spectrum

Code: Select all

   1 CLEAR : SAVE "RDtestfile" LINE VAL "10"
  10 CLEAR VAL "28671": LOAD ""CODE : RANDOMIZE USR VAL "28672": PAUSE NOT PI
  20 SAVE !"RDviewer0"
  22 SAVE !"RDviewer1" LINE SGN PI
  24 LET c=VAL "512": DIM a(c)
  25 SAVE !"RDviewer2"
  26 DIM b$(c)
  27 SAVE !"RDviewer4" LINE VAL "9999"
  28 SAVE !"0"CODE NOT PI,NOT PI
  30 SAVE !"RDblock"CODE VAL "16384",c
  32 SAVE !"A()" DATA a()
  34 SAVE !"B$()" DATA b$()
  90 CAT !: PAUSE NOT PI
 100 RANDOMIZE USR VAL "28672"
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

i found the logic to fysic bank calculation from Toni Baker, used in SuperCat from about 1987, its in Z80
i added the number sequence to have a look on what happens

Code: Select all

;part of SuperCAT by Toni Baker from ZX Computing June 1987

                          ORG  8000h
8000 C5       PAGE_(A)    PUSH BC
8001 FE05                 CP   #05          ;0,1,2,3,4,5
8003 2002                 JR   NZ,PAGE_(A)_2;Jump unless normal RAM required
8005 3EFF                 LD   A,#FF        ;A will contain 0 after increment

8007 3C       PAGE_(A)_2  INC  A            ;1,2,3,4,5,0
8008 47                   LD   B,A          ;              B=page-code + 1
8009 CB38                 SRL  B            ;0,1,1,2,2,0   Divide B by two
800B 80                   ADD  A,B          ;1,3,4,6,7,0   A=absolute RAM page number

800C F610                 OR   #10          ;Include "ROM 1" bit
800E 01FD7F               LD   BC,#7FFD     ;BC=port number for paging
8011 325C5B               LD   (BANK_M),A   ;Store as current pages
8014 ED79                 OUT  (C),A        ;Page in required RAM page
8016 C1                   POP  BC
8017 C9                   RET
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

meanwhile i am back to my old little problem about pointing correctly
i will not show al my mistakes, but the names are *ALMOST* correct now. and there is the +20 or -20, which i seem to misunderstand
is it from the top of the header pile + or - 20 bytes, i am such a simplist.

* it skips a letter, probably from int to char
so, first fix that and then i will be back.. hopefully with a complete routine

Code: Select all

// ramcat029j
// zcc +zx -vn -lm -startup=31 -zorg 0x7000 ramcat029j.c -o ramcat029j -lndos -create-app -Cz --noloader --list --c-code-in-asm
// cat ramcatBAS.tap ramcat029j.tap > testramcat029j.tap


// Catalogue WIP for the contence off the early zx spectrum 128 'toastrack' RamDrive


// https://github.com/ZXSpectrumVault/rom-disassemblies/blob/master/Spectrum%20128K/Spectrum128_ROM0.asm
// ------------------
// RAM Disk Catalogue
// ------------------
// The catalogue can occupy addresses $C000-$EBFF in physical RAM bank 7, starting at $EBFF and growing downwards.
//
// Each entry contains 20 bytes:
//   Bytes $00-$09: Filename.
//   Bytes $0A-$0C: Start address of file in RAM disk area.
//   Bytes $0D-$0F: Length of file in RAM disk area.
//   Bytes $10-$12: End address of file in RAM disk area (used as current position indicator when loading/saving).
//   Byte  $13    : Flags:
//                     Bit 0   : 1=Entry requires updating.
//                     Bits 1-7: Not used (always hold 0).

//
// A file consists of a 9 byte header followed by the data for the file. The header bytes
// have the following meaning:
//   Byte  $00    : File type - $00=Program, $01=Numeric array, $02=Character array, $03=Code/Screen$.
//   Bytes $01-$02: Length of program/code block/screen$/array ($1B00 for screen$).
//   Bytes $03-$04: Start of code block/screen$ ($4000 for screen$).
//   Bytes $05-$06: Offset to the variables (i.e. length of program) if a program. For an array, $05 holds the variable name.
//   Bytes $07-$08: Auto-run line number for a program ($80 in high byte if no auto-run).

// Logical Bank   Physical Bank
// ------------   -------------
//     $00             $01
//     $01             $03
//     $02             $04
//     $03             $06
//     $04             $07
//     $05             $00
// This scheme makes the RAM disk code simpler than having to deal directly with physical RAM bank numbers.

// BASIC LOADER for testing
/*
   1 CLEAR : SAVE "RDtestfile" LINE VAL "10"
  10 CLEAR VAL "28671": LOAD ""CODE 
  20 SAVE !"RD1       "
  22 SAVE !"RD2       " LINE VAL "10"
  24 LET n$="RD        ": LET c=VAL "512": DIM a(c): LET d=INT PI
  25 LET n$(d)="3": SAVE !n$
  26 DIM b$(c)
  27 LET n$(d)="4": SAVE !n$ LINE VAL "10"
  28 LET n$(d)="5": SAVE !n$CODE VAL "0",VAL "0"
  30 LET n$(d)="6": SAVE !n$CODE VAL "16384",c
  32 LET n$(d)="7": SAVE !n$ DATA a()
  34 LET n$(d)="8": SAVE !n$ DATA b$()
  36 LET n$(d)="9": SAVE !n$SCREEN$ 
 100 RANDOMIZE USR VAL "28672"
 150 CLS: CAT !: FOR x=VAL "1" TO VAL "9": LET n$(d)=STR$ x: ERASE !n$: NEXT x
 200 PAUSE VAL"0": GO TO VAL "20"
*/


//-------------------------------------------------

 #include <stdio.h>

 static __at(23429) unsigned long LEFTMEMORY ;
 
//-------------------------------------------------

void preskey( int cls)
{
char key;
printf("Press a key");
scanf("%c",&key ) ;
if (cls == 1) {printf("\xC");}
return ;
}

//-------------------------------------------------


//                         //(        4th    ,  3rd     ,             2nd     ,        1st     )   ret
int  __CALLEE__   fetchheader(int blocklength, char fysicbank, int lowermemoryadres, int headeradres) __naked {

#asm
                              // ALWAYS RETURNS WITH RAM 0 SET !!!
           di                 // disable interrupt for save RamBank switching
           pop bc             // fetch return addres
           exx

           pop hl             // source cq headerstart adres
           pop de             // destiny adres HAS TO BE UNDER 49152-length , well, most off the times !!!
           pop bc             // length
           ld a,c
           ex af,af           // save FYSIC BANK number
           pop bc
           exx
           push bc            // reinstall return address on stack
           exx

           push bc            // save length on stack
           ex af,af
           ld b,a
           ld a,(23388)
           or b               // set bank 7
           ld bc,32765
           out (c),a          // signal page

           pop bc             // BC=headerlength , HL=headerinfo, DE=destiny
           ldir               // copy header info to LOWER MEMORY

           ld bc,32765        // a_reg still holds RAMBANK info
           and 247            // cut page info to 0
           out (c),a          // signal page
           ei
           ret
#endasm
           }  // ALWAYS RETURNS WITH RAM 0 SET !!!
//-------------------------------------------------


          

  main(){

  
    unsigned long mem_count ;               //*leftmemory at(23429)

    unsigned int *rd_counter=23427 ;        //LET el=FN p(VAL "23427")
    unsigned int rd_count , filecount ,tempaddress ;
	   unsigned int rd_bottom=49512, rd_middle=56424, rd_top=60415 ; // rt=VAL "60415" rb=VAL "49512" rm=VAL "rb+6912"

	   unsigned char logicbankstr[]="134670"  ;//logicbank 0,1,2,3,4,5 => fysic rambank 1,3,4,6,7,0

	   unsigned int rd_headersize=20 ;         // ram file header size or entry size @ram_7
	   unsigned int rd_fileheader=9 ;          // small infile header to confirm big entry header @ram_x
    unsigned int ram0=0, rdisc=7 ;          // ram=VAL "16" rdisc=VAL "16+7"
	   unsigned int x,y ;

//	   unsigned char discstr[64+1] ;           // DIM z$(VAL "64")

	   unsigned char *headerinfo[20+1] ;


    unsigned char name[10+1] ;              // FOR y=x TO VAL "x+9": LET u$=u$+CHR$ PEEK y: NEXT y:
    unsigned int strt ;                  // LET strt=FN p(VAL "x+10")
    unsigned char logicbank ;            // LET logicbank=PEEK VAL "x+12"
    unsigned char blocks_leng ;          // LET blocks_leng=PEEK VAL "x+15":
    unsigned char blocks_end ;           // LET blocks_end=PEEK VAL "x+18"
    unsigned char changed ;              // LET ch=PEEK VAL "x+19"
    unsigned char bank;
    unsigned char page ;                 //
    unsigned int length ;                // LET blocks_leng=PEEK VAL "x+15"
  
    unsigned long *start, start1 ;                // LET start=FN z(VAL "x+10")
    unsigned long *leng, leng1 ;                 // LET leng=FN z(VAL "x+13")
    unsigned long *end, end1 ;                  // LET end=FN z(VAL "x+16")

	   
	   rd_count=*rd_counter;
	   mem_count=LEFTMEMORY & 0x00FFFFFF ;// 3bytes 
	   filecount = (rd_top -20 -rd_count +1 ) /20 ;  // LET fl=VAL "(rt-20-el+1)/20"

	   printf("\xCRamdrive %6u points to %6u \n",rd_counter, rd_count ) ;
    printf("%4u file%c found, %7lu bytes left\n",filecount,'s',mem_count);

    tempaddress = rd_count+rd_headersize;
	   if (filecount > 0){
		  for (x=1;x<=filecount;x++){
 
        fetchheader(rd_headersize, rdisc, headerinfo,tempaddress) ;  // rambank=7  !!!

        strt=headerinfo[10] ;
        logicbank=headerinfo[12] ;
        blocks_leng=headerinfo[15] ;
        blocks_end=headerinfo[18] ;
        changed=headerinfo[19] ;
        bank=logicbankstr[logicbank] ;          // : LET bank=VAL "134670"(logicbank+1)

        //: DEF FN z(a)=FN p(a)+16384*PEEK (a+2)   << 1 bank = 16k !! correct value ??  

        start = headerinfo[10] ;
        start1 =*start & 0x0000FFFF ;
        start1 = start1 + (logicbank *16384) ;
        printf("start: %lu\n",start1 );
//        start = start & 0x0000FFFF ;
//        printf("start: %lu\n",start );
//        start = start  + (logicbank *16384) ;
//        printf("start: %lu\n",start );


        leng=headerinfo[13] ;
        leng1  = *leng ;
//        leng = leng + (blocks_leng *16384) ;
  
        end=headerinfo[16] ;
        end1  = *end  ;
//        end   = end + (blocks_end *16384) ;

        for (y=0;y<10;y++){ name[y]=' '; } ;  
        for (y=0;y<10;y++){ name[y]=headerinfo[y]; } ;
        name[10]='\0';
        printf("file %d at %d\n",x,tempaddress);
        printf("name: %s\n",name );
        printf("(logic)bank: %u %u  ..  %c  %c\n",logicbank ,bank ,logicbank ,bank );
        printf("strt: %u\n",strt );
        printf("leng: %lu\n",leng );
        printf("start: %lu\n",start );
        printf("end: %lu\n",end );

        tempaddress=tempaddress+20 ;  //  bottom2top in appearing order (while CAT! function results alphabetic)

        preskey(1);	  
      } // end 'for filecount'
    } //end 'if filecount'

  return 0;
 }
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

cborn wrote: Thu Apr 20, 2023 6:06 pm
is it from the top of the header pile + or - 20 bytes, i am such a simplist.
found that part, i missed the EndOf Catalogu marker

Code: Select all

// This is the information contained by the end-of-catalogue marker,
// assuming that IX points to the first byte. Note that this marker is indexed by (4)(SF_NEXT).
// IX+00          (ten bytes):   Not used
// IX+0A SF_START (three bytes): Page-coded address of first spare byte in RAMdisc
// IX+0D          (seven bytes): Not used
// 
www.users.globalnet.co.uk/~jg27paw4/typ ... the128.zip
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

not fully working but i start to like it
ANY comment or enbettering is always welcome

i think fetchblock() is ready for use

Code: Select all

// RDcat035
// zcc +zx -vn -lm -startup=31 -zorg0x7000 RDcat035.c -oRDcat035 -lndos -create-app -Cz --noloader --list --c-code-in-asm //-a
// cat ramcatBAS.tap RDcat035.tap > testRDcat035.tap

// Catalogue for the contence off the early zx spectrum 128 'toastrack' RamDrive



// http://www.users.globalnet.co.uk/~jg27paw4/type-ins/zx-comp/zx8605_intothe128.zip
// https://github.com/ZXSpectrumVault/rom-disassemblies/blob/master/Spectrum%20128K/Spectrum128_ROM0.asm

// BANK_M      EQU $5B5C  ;  1   Copy of last byte output to I/O port $7FFD.
// SFNEXT      EQU $5B83  ;  2   End of RAM disk catalogue marker. Pointer to first empty catalogue entry.
// SFSPACE     EQU $5B85  ;  3   Number of bytes free in RAM disk (3 bytes, 17 bit, LSB first).

// ------------------
// RAM Disk Catalogue
// ------------------
// The catalogue can occupy addresses $C000-$EBFF in physical RAM bank 7, starting at $EBFF and growing downwards.
//
// Each entry contains 20 bytes:
//   Bytes $00-$09: Filename.
//   Bytes $0A-$0C: Start address of file in RAM disk area.
//   Bytes $0D-$0F: Length of file in RAM disk area.
//   Bytes $10-$12: End address of file in RAM disk area (used as current position indicator when loading/saving).
//   Byte  $13    : Flags:
//                     Bit 0   : 1=Entry requires updating.
//                     Bits 1-7: Not used (always hold 0).

//
// A file consists of a 9 byte header followed by the data for the file. The header bytes
// have the following meaning:
//   Byte  $00    : File type - $00=Program, $01=Numeric array, $02=Character array, $03=Code/Screen$.
//   Bytes $01-$02: Length of program/code block/screen$/array ($1B00 for screen$).
//   Bytes $03-$04: Start of code block/screen$ ($4000 for screen$).
//   Bytes $05-$06: Offset to the variables (i.e. length of program) if a program. For an array, $05 holds the variable name.
//   Bytes $07-$08: Auto-run line number for a program ($80 in high byte if no auto-run).

// This is the information contained by the end-of-catalogue marker,
// assuming that IX points to the first byte. Note that this marker is indexed by (4)(SF_NEXT).
// IX+00          (ten bytes):   Not used
// IX+0A SF_START (three bytes): Page-coded address of first spare byte in RAMdisc
// IX+0D          (seven bytes): Not used
// 
// -----------------
// Throughout ROM 0, memory banks are accessed using a logical numbering scheme, which
// maps to physical RAM banks as follows:
// Logical Bank   Physical Bank
// ------------   -------------
//     $00             $01
//     $01             $03
//     $02             $04
//     $03             $06
//     $04             $07
//     $05             $00
// This scheme makes the RAM disk code simpler than having to deal directly with physical RAM bank numbers.

// BASIC LOADER for testing
/*
   1 CLEAR : SAVE "RDtestfile" LINE VAL "10"
  10 CLEAR VAL "28671": LOAD ""CODE 
  12 RANDOMIZE USR VAL "28672"
  13 SAVE !"Ramdrive_1"CODE VAL "0",VAL "16384-9"
  15 RANDOMIZE USR VAL "28672"
  19 SAVE !"Ramdrive_2"CODE VAL "0",VAL "16384"
  20 SAVE !"RamDrive_3"
  22 SAVE !"RamDrive_4" LINE VAL "10"
  24 LET n$="RamDrive_ ": LET c=VAL "512": DIM a(c): LET d=VAL "10"
  25 LET n$(d)="5": SAVE !n$
  26 DIM b$(c)
  27 LET n$(d)="6": SAVE !n$ LINE VAL "10"
  32 LET n$(d)="7": SAVE !n$ DATA a()
  34 LET n$(d)="8": SAVE !n$ DATA b$()
  36 LET n$(d)="9": SAVE !n$SCREEN$ 
 100 RANDOMIZE USR VAL "28672"
 150 CLS : CAT !: LET n$="          ": FOR x=VAL "1" TO VAL "10": LET n$(x)=SCREEN$ (0,x-1): NEXT x: PRINT AT 21,0;n$: IF n$<>"          " THEN  ERASE !n$: GO TO VAL "150"
 200 GO TO VAL "12"
*/
//-------------------------------------------------




#include <stdio.h>
#include <string.h>

 static __at(23429) unsigned long LEFTMEMORY ;
 
//-------------------------------------------------

void preskey( int cls)
{
 char key;
 printf("Press a key");
 scanf("%c",&key ) ;
 if (cls == 1) {printf("\xC");}
 return ;
}

//-------------------------------------------------


//  PAGE CODEING USED    (             4th        ,               3rd     ,              2nd    ,              1st   )   ret
int __CALLEE__ fetchblock(unsigned int blocklength, unsigned char pagecode, unsigned int destiny, unsigned int source)__naked {

#asm                           // ALWAYS RETURN WITH RAM 0 SET !!!
            di                 // disable interrupt for save RamBank switching

            pop bc             // fetch return addres
            exx

            pop hl             // source cq headerstart adres
            pop de             // destiny adres HAS TO BE UNDER 49151-length , well, most off the times !!!
            pop bc
            ld a,c             // logicbank aka pagecode 0,1,2,3,4,5: Ramdrive @ pagecode(4)=fysicbank(7)
            pop bc             // length

            exx
            push bc           // reinstall return address on stack
            exx

            push bc           // save length on stack

// from 'SuperCAT' by Toni Baker from ZX Computing June 1987
PAGE_A:     CP   5            // 0,1,2,3,4,5

            jr z,a255         // jump on a=5 
            jr c,PAGE_A_2     // jump on a<5
            JR   reit         // return if pagecode above a>5

a255:       LD   A,0xFF       // A will contain 0 after increment
PAGE_A_2:   INC  A            // 1,2,3,4,5,0
            LD   B,A          //               B= pagecode + 1
            SRL  B            // 0,1,1,2,2,0   Divide B by two
            ADD  A,B          // 1,3,4,6,7,0   A=absolute RAM page number
// Thank you
            ld b,a
            ld a,(23388)
            and 248            // cut page info to 0
            or b               // set bank B

            ld bc,32765
            out (c),a          // signal page

            pop bc             // BC=headerlength , HL=headerinfo, DE=destiny
            ldir               // copy header info to LOWER MEMORY

            and 248            //  a_reg still holds RAMBANK info, cut page info to 0
            ld (23388),a

            ld bc,32765        //
            out (c),a          // signal page 0

reit:       ei
            ret
#endasm
           }  // ALWAYS RETURNS WITH RAM 0 SET !!!
//-------------------------------------------------

          

  main(){
  
    unsigned long mem_count ;               //*leftmemory at(23429)

    unsigned long *start, start1 ;                   // LET start=FN z(VAL "x+10")
    unsigned long *leng, leng1 ;             // LET leng=FN z(VAL "x+13")
    unsigned long *end, end1 ;               // LET end=FN z(VAL "x+16")

    unsigned int *rd_counter=23427 ;        //LET el=FN p(VAL "23427")
    unsigned int rd_count, filecount, tempaddress ;
	   unsigned int rd_bottom=49512, rd_middle=56424, rd_top=60415 ; // rt=VAL "60415" rb=VAL "49512" rm=VAL "rb+6912"

	   unsigned int rd_headersize=20 ;         // ram file header size or entry size @ram_7
	   unsigned int rd_fileheader=9 ;          // small infile header to confirm big entry header @ram_x
    unsigned int ram0=0, rdisc=4 ;          // ramdisc at PAGE 4 = BANK 7
	   unsigned int x,y ;

	   unsigned char pagecodestr[]="134670" ; // pagecode 0,1,2,3,4,5 => fysic rambank 1,3,4,6,7,0
    unsigned char pagecode, bank;          // LET pagecode=PEEK VAL "x+12"
    unsigned char blocks_leng ;             // LET blocks_leng=PEEK VAL "x+15":
    unsigned char blocks_end ;              // LET blocks_end=PEEK VAL "x+18"

    unsigned char changed ;                  // LET ch=PEEK VAL "x+19"


	   rd_count=*rd_counter;
	   mem_count=LEFTMEMORY & 0x0001FFFF ;  // 3bytes > 17 bits
	   filecount = (rd_top -20 -rd_count +1 ) /20 ;  // LET fl=VAL "(rt-20-el+1)/20"

	   printf("\xCRamdrive %6u points to %6u \n",rd_counter, rd_count ) ;
    printf("%3u file found, %7lu bytes left\n",filecount,mem_count);

    tempaddress = rd_top + 1 - rd_headersize ;

		  for (x=0;x<=filecount;x++){

    	   unsigned char headerinfo[20+1];
        unsigned char fileinfo[9+1] ;

        fetchblock(rd_headersize, rdisc, headerinfo, tempaddress) ;  // catalogue=page 4  !!!

        pagecode=headerinfo[12] ;
        bank=pagecodestr[pagecode]-48 ;          // ascii48='0': LET bank=VAL "134670"(pagecode+1)
        start= (char)headerinfo[10] + ( (char)headerinfo[11] *256 );
//        start1= start + (pagecode * 16384);

        blocks_leng=headerinfo[15] ;
        leng = (char)headerinfo[13] + ( (char)headerinfo[14] *256 );
        leng1= leng + (blocks_leng * 16384);

        blocks_end=headerinfo[18] ;
        end  = (char)headerinfo[16] + ( (char)headerinfo[17] *256 );
//        end1 = end + (blocks_end * 16384);

        changed=headerinfo[19] ;  // internal flag  if FILE needs update in CATalogue
    
        printf("(%u)%5u (%u)%5u (%u)%5u\n",pagecode,start,blocks_leng,leng,blocks_end,end);
 
        unsigned char name[]="End_Of_Cat" ;
        unsigned char type[]="????" ;
        if ( x < filecount){
            for (y=0;y<10;y++){name[y]=headerinfo[y]; } ;
           };
        name[10]='\0';
        type[4] ='\0';

        fetchblock(rd_fileheader, pagecode, fileinfo, start ) ;
        unsigned char filetype=fileinfo[0] ;
        unsigned int filelength, filestart, variables, autoline  ;
        filelength= (char)fileinfo[1] + ( (char)fileinfo[2] *256 );
        filestart = (char)fileinfo[3] + ( (char)fileinfo[4] *256 );
        variables = (char)fileinfo[5] + ( (char)fileinfo[6] *256 );
        autoline  = (char)fileinfo[7] + ( (char)fileinfo[8] *256 );

        switch (filetype){
               case 0:   strcpy(type, "PROG");
                     break;
               case 1:   strcpy(type, "DATA");
                     break;
               case 2:   strcpy(type, "DAT$");
                     break;
               case 3:   strcpy(type, "CODE");
                     if (filelength==6912 && filestart==16384) {strcpy(type, "SCR$");};
                     break;
               }

        printf("header %3u at %5u %s:%s (logic)bank: %u %u\n",x+1,tempaddress,type ,name ,pagecode ,bank);
        printf("");

        tempaddress=tempaddress-20 ;
      } // end 'for filecount'

        printf("\n");
        preskey(1);	 

  return 0;
 }


cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

ps
on ram BREAK fetchblock() will fail, at this moment the blok MUST be al on 1 page.
this mean if the 9 bytes file header starts in page 0 but reaches page 1 already, then an EXTRA bankswitch has to be made.
LDIR will have to be replaced with a ram limit calculation and a single increase of the PAGECODE, not the rambank ....
so version 2 has a future, cant wait for it
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: toastrack ramdrive viewer, step 1

Post by cborn »

by now it looks ALMOST normal, but it lacks some decent filling, i have no clue why "screen$" is Not Selected at all

Code: Select all

// RDcat040h
// zcc +zx -vn -lm -startup=31 -zorg0x7000 RDcat040h.c -oRDcat040h -lndos -create-app -Cz --noloader --list --c-code-in-asm //-a
// cat ramcatBAS.tap RDcat040h.tap > testRDcat040h.tap

// Catalogue for the contence off the early zx spectrum 128k 'toastrack' RamDrive



// http://www.users.globalnet.co.uk/~jg27paw4/type-ins/zx-comp/zx8605_intothe128.zip
// https://github.com/ZXSpectrumVault/rom-disassemblies/blob/master/Spectrum%20128K/Spectrum128_ROM0.asm

// BANK_M      EQU $5B5C  ;  1byte  Copy of last byte output to I/O port $7FFD
// SFNEXT      EQU $5B83  ;  2byte  End of RAM disk catalogue marker. Pointer to first empty catalogue entry.
// SFSPACE     EQU $5B85  ;  3byte  Number of bytes free in RAM disk (3 bytes, 17 bit, LSB first).

// ------------------
// RAM Disk Catalogue
// ------------------
// The catalogue can occupy addresses $C000-$EBFF in physical RAM bank 7, starting at $EBFF and growing downwards.
//
// Each entry contains 20 bytes:
//   Bytes $00-$09: Filename.
//   Bytes $0A-$0C: Start address of file in RAM disk area.
//   Bytes $0D-$0F: Length of file in RAM disk area.
//   Bytes $10-$12: End address of file in RAM disk area (used as current position indicator when loading/saving).
//   Byte  $13    : Flags:
//                     Bit 0   : 1=Entry requires updating.
//                     Bits 1-7: Not used (always hold 0).

//
// A file consists of a 9 byte header followed by the data for the file. The header bytes
// have the following meaning:
//   Byte  $00    : File type - $00=Program, $01=Numeric array, $02=Character array, $03=Code/Screen$.
//   Bytes $01-$02: Length of program/code block/screen$/array ($1B00 for screen$).
//   Bytes $03-$04: Start of code block/screen$ ($4000 for screen$).
//   Bytes $05-$06: Offset to the variables (i.e. length of program) if a program. For an array, $05 holds the variable name.
//   Bytes $07-$08: Auto-run line number for a program ($80 in high byte if no auto-run).

// This is the information contained by the end-of-catalogue marker,
// assuming that IX points to the first byte. Note that this marker is indexed by (4)(SF_NEXT).
// IX+00          (ten bytes)  : Not used
// IX+0A SF_START (three bytes): Page-coded address of first spare byte in RAMdisc
// IX+0D          (seven bytes): Not used
// 
// -----------------
// Throughout ROM 0, memory banks are accessed using a logical numbering scheme, which
// maps to physical RAM banks as follows:
// Logical Bank   Physical Bank
// ------------   -------------
//     $00             $01
//     $01             $03
//     $02             $04
//     $03             $06
//     $04             $07
//     $05             $00
// This scheme makes the RAM disk code simpler than having to deal directly with physical RAM bank numbers.

// BASIC LOADER for testing
/*
   1 CLEAR : SAVE "RDtestfile" LINE VAL "10"
  10 CLEAR VAL "28671": LOAD ""CODE 
  11 GO TO VAL "150"
  12 RANDOMIZE USR VAL "28672"
  13 SAVE !"Ramdrive_1"CODE VAL "0",VAL "16384-9"
  15 RANDOMIZE USR VAL "28672"
  19 SAVE !"Ramdrive_2"CODE VAL "0",VAL "16384"
  20 SAVE !"RamDrive_3"
  22 SAVE !"RamDrive_4" LINE VAL "10"
  24 LET n$="RamDrive_ ": LET c=VAL "512": DIM a(c): LET d=VAL "10"
  25 LET n$(d)="5": SAVE !n$
  26 DIM b$(c)
  27 LET n$(d)="6": SAVE !n$ LINE VAL "10"
  32 LET n$(d)="7": SAVE !n$ DATA a()
  34 LET n$(d)="8": SAVE !n$ DATA b$()
  36 LET n$(d)="9": SAVE !n$SCREEN$ 
 100 RANDOMIZE USR VAL "28672"
 150 CLS : CAT !: LET n$="          ": FOR x=VAL "1" TO VAL "10": LET n$(x)=SCREEN$ (0,x-1): NEXT x: PRINT AT 21,0;n$: IF n$<>"          " THEN  ERASE !n$: GO TO VAL "150"
 200 GO TO VAL "12"
*/
//-------------------------------------------------



#include <stdio.h>
#include <string.h>

 static __at(23429) unsigned long LEFTMEMORY ;
 
//-------------------------------------------------

void preskey( int cls)
{
 char key;
 printf("Press a key");
 scanf("%c",&key ) ;
 if (cls == 1) {printf("\xC");}
 return ;
}

//-------------------------------------------------

//                                    32768(-1)??         0-3 save area            16384-49151           49512-65535
//  PAGE CODEING USED    (             4th        ,               3rd     ,              2nd    ,              1st   )   ret
int __CALLEE__ fetchblock(unsigned int blocklength, unsigned char pagecode, unsigned int destiny, unsigned int source)__naked {

#asm                           // ALWAYS RETURN WITH RAM 0 SET !!!
            di                 // disable interrupt for save RamBank switching

            pop bc             // fetch return addres
            exx

            pop hl             // source cq headerstart adres
            pop de             // destiny adres HAS TO BE UNDER 49151-length , well, most off the times !!!
            pop bc
            ld a,c             // logicbank aka pagecode 0,1,2,3,4,5: RamdriveCatalogue @ pagecode(4)=fysicbank(7)
            pop bc             // length

            exx
            push bc           // reinstall return address on stack
            exx

            push bc          // save length on stack

            ld c,a
            ex af,af         // save for PAGECODE increase
            ld a,c           // both a hold pagecode

            call PAGE_A      // A must hold PAGE CODE

            pop bc           // BC=headerlength , HL=headerinfo, DE=destiny

fetch:      ld a,(hl)
            ld (de),a
            inc de           // ram UNDER 49152, hopefully it works, max range now 16384-49151, MIGHT overwrite THIS routine !!
            inc hl           // 0xffff top off RAM
            ld a,h
            or l
            jr nz,nextbc

            ex af,af         // fetch pagecode again
            inc a            // raise to next page

            push bc
            call PAGE_A      // A must hold PAGE CODE
            pop bc
            ld hl,0xC000     // ld h,0xC0 save 1 byte

nextbc:   
            dec bc
            ld a,b
            or c
            jr nz,fetch

            ld a,5
            call PAGE_A     

reit:       ei
            ret // ALWAYS RETURNS WITH RAM 0 SET !!!


// from 'SuperCAT' by Toni Baker from ZX Computing June 1987
PAGE_A:     CP   5            // 0,1,2,3,4,5

            jr z,a255         // jump on a=5 
            jr c,PAGE_A_2     // jump on a<5
            ret               // return if pagecode above a>5

a255:       LD   A,0xFF       // A will contain 0 after increment
PAGE_A_2:   INC  A            // 1,2,3,4,5,0
            LD   B,A          //               B= pagecode + 1
            SRL  B            // 0,1,1,2,2,0   Divide B by two
            ADD  A,B          // 1,3,4,6,7,0   A=absolute RAM page number

            ld b,a
            ld a,(23388)
            and 248            // cut page info to 0
            or b               // set bank B

            ld bc,32765
            ld (23388),a
            out (c),a          // signal page

            ret
// Thank you

#endasm       // ROMS NOT CHANGED
           }  // ALWAYS RETURN WITH RAM 0 SET !!!

//-------------------------------------------------


  main(){
  
    unsigned long mem_count ;               //*leftmemory at(23429)

    unsigned int start, start1 ;          // LET start=FN z(VAL "x+10")
    unsigned int leng, leng1 ;            // LET leng=FN z(VAL "x+13")
    unsigned int end, end1 ;              // LET end=FN z(VAL "x+16")

    unsigned int *rd_counter=23427 ;        // LET el=FN p(VAL "23427")
    unsigned int rd_count, filecount, tempaddress ;
	   unsigned int rd_bottom=49512, rd_middle=56424, rd_top=60415 ; // rt=VAL "60415" rb=VAL "49512" rm=VAL "rb+6912"

	   unsigned int rd_headersize=20 ;         // ram file header size or entry size @ram_7
	   unsigned int rd_fileheader=9 ;          // small infile header to confirm big entry header @ram_x
    unsigned int ram0=0, rdisc=4 ;          // ramdisc at PAGE 4 = BANK 7
	   unsigned int x,y ;

	   unsigned char pagecodestr[]="134670" ;  // pagecode 0,1,2,3,4,5 => fysic rambank 1,3,4,6,7,0
    unsigned char pagecode, bank ;          // LET pagecode=PEEK VAL "x+12"
    unsigned char blocks_leng ;             // LET blocks_leng=PEEK VAL "x+15":
    unsigned char blocks_end ;              // LET blocks_end=PEEK VAL "x+18"

    unsigned char changed ;                 // LET ch=PEEK VAL "x+19"


	   rd_count=*rd_counter ;
	   mem_count=LEFTMEMORY & 0x0001FFFF ;  // 3bytes > 17 bits
	   filecount = ( rd_top+1 -rd_headersize -rd_count ) /rd_headersize ;  // LET fl=VAL "(rt-20-el+1)/20"

	   printf("\xCRamdrive %3u file found,%7lu bytes left\n",filecount,mem_count) ;

    tempaddress = rd_top + 1 - rd_headersize ;

		  for (x=0;x<=filecount;x++){

    	   unsigned char headerinfo[20+1];
        unsigned char fileinfo[9+1] ;
        // fetch catalogue
        fetchblock(rd_headersize, rdisc, headerinfo, tempaddress) ;  // catalogue=page 4  !!!

        pagecode=headerinfo[12] ;
        bank=pagecodestr[pagecode]-48 ;          // ascii48='0': LET bank=VAL "134670"(pagecode+1)
        start= (char)headerinfo[10] + ( (char)headerinfo[11] *256 );
//        start1= start + (pagecode * 16384);

        blocks_leng=headerinfo[15] ;
        leng = (char)headerinfo[13] + ( (char)headerinfo[14] *256 );
        leng1= leng + (blocks_leng * 16384);

        blocks_end=headerinfo[18] ;
        end  = (char)headerinfo[16] + ( (char)headerinfo[17] *256 );
//        end1 = end + (blocks_end * 16384);

        changed=headerinfo[19] ;  // internal flag  if FILE needs update in CATalogue
    
        unsigned char name[]="End_Of_Cat" ;
        unsigned char type[]="    ", type2[]="       ", type3[]="     ", type4[]="     ",
                      lenstr[]="     ", startstr[]="     ", autostr[]="     ", varstr[]="     " ;


        if ( x < filecount){
            for (y=0;y<10;y++){name[y]=headerinfo[y]; } ;
            name[10]='\0';
            // fetch fileheader somewhere in RAM
            fetchblock(rd_fileheader, pagecode, fileinfo, start ) ;
            unsigned char filetype=fileinfo[0], datachr ;
            unsigned int filelength, filestart, variables, autoline, basiclength  ;
            filelength  = (char)fileinfo[1] + ( (char)fileinfo[2] *256 );
            filestart   = (char)fileinfo[3] + ( (char)fileinfo[4] *256 );
            variables   = (char)fileinfo[5] + ( (char)fileinfo[6] *256 );
            autoline    = (char)fileinfo[7] + ( (char)fileinfo[8] *256 );
            datachr     = fileinfo[5] ;
            basiclength = filelength - variables ;

            switch (filetype){
               case 0:   strcpy(type, "Prog");
                         if (autoline < 32768 ){
                             strcpy(type2, " LINE  ");
                             sprintf(type3, "%5u", autoline);
                             };
                         if (variables>0){
                             sprintf(type4, "%5u", variables);
                             };
                     break;

               case 1:   strcpy(type, "Data");
                         strcpy(type2, " DATA  ");
                         strcpy(type3, " ()  ");
                         type3[0]=datachr-32 ;
                         sprintf(type4, "%5u", filelength);
                     break;

               case 2:   strcpy(type, "Data");
                         strcpy(type2, " DATA  ");
                         strcpy(type3, " $() ");
                         type3[0]=datachr-96 ;
                         sprintf(type4, "%5u", filelength);
                     break;

               case 3:   strcpy(type, "Byte");
                         sprintf(type3, "%5u", filestart);
                         sprintf(type4, "%5u", filelength);
                         strcpy(type2, " CODE  ");
                         if (filelength==6912 && filestart==16384) {
                             strcpy(type2,"SCREEN$");
                             }
                     break;
            }// end switch
        };  // end IF x<filecount

        printf("%s:%s %s %s %s " ,type ,name , type2 ,type3, type4 );
        printf("%u/%5u %u/%5u %u/%5u",pagecode,start,blocks_leng,leng,blocks_end,end);
        printf("\n");

        tempaddress=tempaddress-rd_headersize ;
    } // end 'for filecount'

  preskey(1);	 
  return 0;
 }
Post Reply