image_contents_t *diskcontents_block_read(vdrive_t *vdrive) { image_contents_t *contents; BYTE buffer[256]; int retval; image_contents_file_list_t *lp; machine_drive_flush(); if (vdrive == NULL) return NULL; retval = vdrive_bam_read_bam(vdrive); if (retval < 0) { vdrive_internal_close_disk_image(vdrive); return NULL; } contents = image_contents_new(); memcpy(contents->name, vdrive->bam + vdrive->bam_name, IMAGE_CONTENTS_NAME_LEN); contents->name[IMAGE_CONTENTS_NAME_LEN] = 0; memcpy(contents->id, vdrive->bam + vdrive->bam_id, IMAGE_CONTENTS_ID_LEN); contents->id[IMAGE_CONTENTS_ID_LEN] = 0; contents->blocks_free = (int)vdrive_bam_free_block_count(vdrive); vdrive->Curr_track = vdrive->Dir_Track; vdrive->Curr_sector = vdrive->Dir_Sector; lp = NULL; contents->file_list = NULL; circular_check_init(); while (1) { BYTE *p; int j; retval = vdrive_read_sector(vdrive, buffer, vdrive->Curr_track, vdrive->Curr_sector); if (retval != 0 || circular_check(vdrive->Curr_track, vdrive->Curr_sector)) { /*image_contents_destroy(contents);*/ vdrive_internal_close_disk_image(vdrive); circular_check_free(); return contents/*NULL*/; } for (p = buffer, j = 0; j < 8; j++, p += 32) if (p[SLOT_TYPE_OFFSET] != 0) { image_contents_file_list_t *new_list; int i; new_list = lib_malloc(sizeof(image_contents_file_list_t)); new_list->size = ((int)p[SLOT_NR_BLOCKS] + ((int)p[SLOT_NR_BLOCKS + 1] << 8)); for (i = 0; i < IMAGE_CONTENTS_FILE_NAME_LEN; i++) new_list->name[i] = p[SLOT_NAME_OFFSET + i]; new_list->name[IMAGE_CONTENTS_FILE_NAME_LEN] = 0; new_list->name[i] = 0; sprintf((char *)new_list->type, "%c%s%c", (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_CLOSED ? ' ' : '*'), cbmdos_filetype_get(p[SLOT_TYPE_OFFSET] & 0x07), (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_LOCKED ? '<' : ' ')); new_list->next = NULL; if (lp == NULL) { new_list->prev = NULL; contents->file_list = new_list; lp = contents->file_list; } else { new_list->prev = lp; lp->next = new_list; lp = new_list; } } if (buffer[0] == 0) break; vdrive->Curr_track = (int)buffer[0]; vdrive->Curr_sector = (int)buffer[1]; } vdrive_internal_close_disk_image(vdrive); circular_check_free(); return contents; }
int vdrive_dir_next_directory(vdrive_t *vdrive, bufferinfo_t *b) { BYTE *l, *p; int blocks, i; while ((p = vdrive_dir_find_next_slot(&b->dir))) { if (p[SLOT_TYPE_OFFSET]) { l = b->buffer + b->bufptr; *l++ = 1; *l++ = 1; /* * Length and spaces */ *l++ = p[SLOT_NR_BLOCKS]; *l++ = p[SLOT_NR_BLOCKS + 1]; memset(l, 32, 27); l[27] = 0; blocks = p[SLOT_NR_BLOCKS] + p[SLOT_NR_BLOCKS + 1] * 256; if (blocks < 10) { l++; } if (blocks < 100) { l++; } l++; *l++ = '"'; memcpy(l, &p[SLOT_NAME_OFFSET], 16); for (i = 0; (i < 16) && (p[SLOT_NAME_OFFSET + i] != 0xa0); ) { i++; } vdrive_dir_no_a0_pads(l, 16); l[i] = '"'; /* * Type + End * There are 3 spaces or < and 2 spaces after the filetype. * Well, not exactly - the whole directory entry is 32 byte long * (including nullbyte). * Depending on the file size, there are more or less spaces */ l[17] = (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_CLOSED) ? ' ' : '*'; memcpy(l + 18, cbmdos_filetype_get(p[SLOT_TYPE_OFFSET] & 0x07), 3); l[21] = (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_LOCKED) ? '<' : ' '; b->bufptr = (b->bufptr + 32) & 255; if (b->bufptr == 0) { return 0; } } } blocks = vdrive_bam_free_block_count(vdrive); l = b->buffer + b->bufptr; *l++ = 1; *l++ = 1; *l++ = blocks; *l++ = blocks >> 8; memcpy(l, "BLOCKS FREE.", 12); memset(l + 12, 32, 13); l[25] = 0; l[26] = 0; l[27] = 0; return b->bufptr + 31; }
int vdrive_dir_create_directory(vdrive_t *vdrive, const char *name, int length, int filetype, BYTE *outputptr) { BYTE *l, *p; BYTE *origptr = outputptr; int blocks, i; if (length) { if (*name == '$') { ++name; --length; } if (*name == ':') { ++name; --length; } } if (!*name || length < 1) { name = "*\0"; length = 1; } /* * Start Address, Line Link and Line number 0 */ l = outputptr; *l++ = 1; *l++ = 4; l += 2; /* Leave space for Next Line Link */ *l++ = 0; *l++ = 0; *l++ = (BYTE)0x12; /* Reverse on */ *l++ = '"'; memcpy(l, &vdrive->bam[vdrive->bam_name], 16); vdrive_dir_no_a0_pads(l, 16); l += 16; *l++ = '"'; *l++ = ' '; memcpy(l, &vdrive->bam[vdrive->bam_id], 5); vdrive_dir_no_a0_pads(l, 5); l += 5; *l++ = 0; /* * Pointer to the next line */ outputptr[2] = 1; outputptr[3] = 1; outputptr = l; /* * Now, list files that match the pattern. * Wildcards can be used too. */ vdrive_dir_find_first_slot(vdrive, name, length, filetype); while ((p = vdrive_dir_find_next_slot(vdrive))) { BYTE *tl; /* Check whether the directory exceeds the malloced memory. We make sure there is enough space for two lines because we also have to add the final ``...BLOCKS FREE'' line. */ if ((l - origptr) >= DIR_MAXBUF - 64) { log_error(vdrive_dir_log, "Directory too long: giving up."); return -1; } if (p[SLOT_TYPE_OFFSET]) { tl = l; l += 2; /* * Length and spaces */ blocks = p[SLOT_NR_BLOCKS] + p[SLOT_NR_BLOCKS + 1] * 256; SET_LO_HI(l, blocks); if (blocks < 10) *l++ = ' '; if (blocks < 100) *l++ = ' '; /* * Filename */ *l++ = ' '; *l++ = '"'; memcpy(l, &p[SLOT_NAME_OFFSET], 16); for (i = 0; (i < 16) && (p[SLOT_NAME_OFFSET + i] != 0xa0);) i++; vdrive_dir_no_a0_pads(l, 16); l[16] = ' '; l[i] = '"'; l += 17; /* * Type + End * There are 3 spaces or < and 2 spaces after the filetype. * Well, not exactly - the whole directory entry is 32 byte long * (including nullbyte). * Depending on the file size, there are more or less spaces */ sprintf((char *)l, "%c%s%c%c", (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_CLOSED ? ' ' : '*'), cbmdos_filetype_get(p[SLOT_TYPE_OFFSET] & 0x07), (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_LOCKED ? '<' : ' '), 0); l += 5; i = (int)(l - tl); while (i < 31) { *l++ = ' '; i++; } *l++ = '\0'; /* * New address */ outputptr[0] = 1; outputptr[1] = 1; outputptr = l; } } blocks = vdrive_bam_free_block_count(vdrive); *l++ = 0; *l++ = 0; SET_LO_HI(l, blocks); memcpy(l, "BLOCKS FREE.", 12); l += 12; memset(l, ' ', 13); l += 13; *l++ = (char) 0; /* Line Address */ outputptr[0] = 1; outputptr[1] = 1; /* * end */ *l++ = (char) 0; *l++ = (char) 0; *l = (char) 0; return (int)(l - origptr); }