mirror of
https://github.com/marketideas/qasm.git
synced 2026-10-25 13:02:45 +00:00
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set. make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
1 line
281 KiB
Plaintext
1 line
281 KiB
Plaintext
print nohdr
|
|
*******************************************************************************
|
|
*
|
|
* GS/OS High Sierra File System Translator
|
|
*
|
|
* Version 03.00
|
|
* Written by Bryan Atsatt
|
|
*
|
|
* Thanks to Rob Turner for providing his ProDOS FST as a model
|
|
* and for letting me steal some of his routines!
|
|
*
|
|
* Copyright 1987-92 Apple Computer, Inc. All Rights Reserved.
|
|
*
|
|
*******************************************************************************
|
|
|
|
string asis
|
|
blanks off
|
|
pagesize 86
|
|
eject
|
|
*******************************************************************************
|
|
*
|
|
* REVISION HISTORY:
|
|
*
|
|
* Date By Description
|
|
*
|
|
* 2/1/88 BPA 00.01 a01 release.
|
|
* 2/3/88 BPA remove status call from setup_volume, changed polarity of
|
|
* disk switched bit in vcr_status.
|
|
* 2/8/88 BPA 00.02 a01 release.
|
|
* 2/16/88 BPA zero length strings converted to 'UNTITLED'. Removed reserved
|
|
* field checking from id_disk. Added vcr_device_id field to vcr
|
|
* and added support for non-CD-ROM devices to device_read.
|
|
* 2/26/88 BPA ISO support added, changed class 1 separator to colon.
|
|
* 2/29/88 BPA Forced directory bit of file_flags byte to 1 in find_file to
|
|
* fix problem found with Medline Knowledge Finder (ISO) disc.
|
|
* 00.03 a01 release.
|
|
* 3/16/88 BPA Changed device read to handle non-2k blocks by doing one 512
|
|
* byte block read. Changed id_disk so will only recognize 512
|
|
* and 2048 byte blocks.
|
|
* 3/18/88 BPA Fixed get_dir_entry so that if the search_assoc call changes
|
|
* the directory block in memory that the current_record is
|
|
* updated in the FCR.
|
|
* 3/21/88 BPA Fixed bug in make_gstring.
|
|
* 3/22/88 BPA Added status call to find_volume.
|
|
* 00.05 a01 release
|
|
* 3/23/88 BPA Removed status call from find_volume (!).
|
|
* 3/24/88 BPA Changed device_read to handle logical block sizes 512, 1024
|
|
* and 2048. SCSI.DRIVER changed so that CD-ROM default block
|
|
* size = 512.
|
|
* 3/28/88 BPA Changed setup_open_buf and build_fcr to force log_blk_size to
|
|
* 2k if file is a directory. Changed find_file to force
|
|
* log_blk_size to 2k. Changed decice_read to use trans_blk_size
|
|
* instead of log_blk_size. Changed all routines which update
|
|
* log_blk_size (except for setup_open_buf, build_fcr, and
|
|
* find_file) to update trans_blk_size as well. Fixed bug in
|
|
* get_name. Built device_dispatch to handle disk switched and
|
|
* offline errors.
|
|
* 3/29/88 BPA Changed setup_call to clear interleave_skip and interleave_size.
|
|
* Changed setup_open_buf to force log_blk_size only if file is
|
|
* claimed for get_dir_entry. Changed read_next_block and
|
|
* read_prev_block to handle differences betx log_blk_size and
|
|
* trans_blk_size.
|
|
* 3/30/88 BPA Added '.BAT' to default file type mapping table.
|
|
* 3/31/88 BPA File 'access' field returns full access ($C3) instead of read
|
|
* only ($01).
|
|
* 4/8/88 BPA Changed trans_blk_size to real_log_size. Changed to look for
|
|
* associated files before it's companion file. Changed
|
|
* get_dir_entry to skip associated file entries.
|
|
* 4/11/88 BPA Tested and fixed get_option_list.
|
|
* 4/18/88 BPA 00.05 a01 release
|
|
* 4/25/88 BPA Changed calc_open_block and changed set_end_block to use it.
|
|
* Changed get_dir_entry to handle zero length names.
|
|
* 00.06 a02 release
|
|
* 4/29/88 BPA Fixes for interleaved files.
|
|
* 5/2/88 BPA Additions for file and aux type handling of discs made using
|
|
* the GS/OS ISO 9660 Authoring Tool. Bug fixes.
|
|
* 00.07 a01 release
|
|
* 5/4/88 BPA Conversion to MPW.
|
|
* 5/31/88 BPA Enlarged string buffers to ensure that 37 character file names
|
|
* will fit. Fixed bugs in search_path_tbl and find_directory
|
|
* which assumed path table offsets and were wrong for ISO 9660.
|
|
* Changed find_dir_record so doesn't care if directory bit is set
|
|
* for entries whose name is 0 or 1.
|
|
* 6/6/88 BPA Changed h_file_sys_id to return iso_id for ISO 9660 volumes.
|
|
* Affects Volume and Get_Dir_Entry calls only.
|
|
* 6/30/88 BPA Added code to support the Apple Extensions to ISO 9660. Fixed
|
|
* bug in h_vol_name (was not checking for illegal length class 0
|
|
* names). Changed setup_call to save non-bouncing errors for
|
|
* calls that require pathnames; if process_path has no errors,
|
|
* and there is a saved error, it will return the saved error.
|
|
* 7/8/88 BPA Modified code to support Apple Extensions under High Sierra as
|
|
* well (added check_apple_ext and get_ext_type routines).
|
|
* 7/12/88 BPA Modified get_date_time to verify date/time and return default
|
|
* if illegal.
|
|
* 7/14/88 BPA Fixed get_date_time to handle zero date/time. Added code to do
|
|
* the ProDOS transformation on volume names. Fixed bug which
|
|
* caused duplicate volume error when ISO disk with open files
|
|
* is ejected and re-inserted by bumping the size of the date
|
|
* fields in the VCR by 1. Fixed blocks_used bug: log_blk_size
|
|
* set from vcr during calc_blocks.
|
|
* 7/21/88 BPA Added transform_gstring procedure, modified build_vcr to use it,
|
|
* changed find_volume so will not do transform.
|
|
* 7/22/88 BPA Changed apple_string to all uppercase.
|
|
* 7/26/88 BPA Fixed device_read so doesn't clear drvr_fst_num after it sets
|
|
* it to $000b. Fixed direct_read to set io_buffer = data_buffer.
|
|
* 7/27/88 BPA Modified get_dir_entry to return resource_eof and
|
|
* resource_blocks. Fixed get_option_list to handle 00 length
|
|
* option list buffer.
|
|
* 7/28/88 BPA Fixed filename transformation in find_volume to $2e5f. Changed
|
|
* search_dir from using log_blk_size to using constant
|
|
* sector_size. Changed find_file to force sector_size reads on
|
|
* read_next_block and to return file_not_found error if volume
|
|
* is High Sierra and resource_num is non-zero. Changed
|
|
* find_dir_record so never sets extended_flag if volume is High
|
|
* Sierra.
|
|
* 8/2/88 BPA Changed FST Attribute word in header so SCM will clear msb's
|
|
* in pathnames.
|
|
* 8/3/88 BPA Changed max_names to 9.
|
|
* 8/10/88 BPA Changed find_volume to look for invalid_dev_num instead of
|
|
* dev_not_found.
|
|
* 8/11/88 BPA Fixed bounce_errors list; was defined incorrectly. Updated
|
|
* version # in fst_header.
|
|
* 8/12/88 BPA Fixed find_volume so sets drvr_stat_code and then checks status
|
|
* word instead of vcr, and also undoes volume name transformation.
|
|
* Changed get_ext_type to handle padding field before signature.
|
|
* 8/16/88 BPA Changed version info to 2.0. Final!
|
|
* ------------
|
|
* 10/6/88 BPA Converted source so data is a record.
|
|
* 11/14/88 BPA Removed common equates from file and included them. Also
|
|
* reformatted source.
|
|
* 12/2/88 BPA v02.01d5 release.
|
|
* 1/11/89 BPA Cleared invisible bit of file flags in find file so that if
|
|
* call is get_file_info and file is a directory, the bit will not
|
|
* be set (fixes bug report RJHCAF237). Fixed calculation of
|
|
* open_buffer in setup_open_buf so uses byte size length from
|
|
* directory record instead of word (fixes BRC# 37728).
|
|
* 1/24/89 BPA Changed build_fcr so sets high bit of access word indicating
|
|
* that file is never modified.
|
|
* 2/15/89 BPA Changed build_fcr so when calls alloc_fcr uses pointer to full
|
|
* pathname rather than to filename.
|
|
* 2/17/89 BPA Changed build_fcr so when calls alloc_fcr uses pointer to
|
|
* volume name rather than full path, and so sets bit 14 of the
|
|
* fcr_access word if the file is the resource fork.
|
|
* 2/22/89 BPA Changed id_disk so if gets a drvr_bad_block error cuz volume is
|
|
* too small, will return unknown_vol err instead so will bounce.
|
|
* 2/23/89 BPA Changed get_file_type to ignore version # in file name (fixes
|
|
* CAF207LWA). Changed process_path to return res_not_found error
|
|
* instead of path_not_found error if resource_num is non-zero
|
|
* (fixes report CAF208LWA). Changed build_vcr so will toss a
|
|
* duplicate vcr if no open files even when it does not belong to
|
|
* me (fixes report CAF209LWA). Made a minor change to
|
|
* find_volume which MAY fix report CAF210LWA (I can't reproduce
|
|
* it but without the fix I can see how it could happen).
|
|
* 3/2/89 BPA Changed shutdown to respect warm_cold_flag and do nothing if
|
|
* warm shutdown. Changed get_option_list to return fst id and
|
|
* correctly handle small buffer conditions.
|
|
* 3/3/89 BPA Fixed get_option_list so if error and call is open, will
|
|
* release the fcr.
|
|
* 3/9/89 BPA Modified search_dir and find_file so will return path_not_found
|
|
* or file_not_found errors appropriately (fixes MJS246LWA).
|
|
* 3/10/89 BPA Modified find_directory to return a dir_error if directory has
|
|
* an XAR (fixes BRC 37350). Added support for version 2 of the
|
|
* Apple Extensions to ISO 9660.
|
|
* 4/6/89 BPA Fixed bug in get_option_list which caused data to be transfered
|
|
* when no XAR present, and fixed one which caused an end_of_dir
|
|
* error on the next get_dir_entry call after one which returned
|
|
* an XAR (XAR was read into open buffer instead of io_buffer).
|
|
* Added support for Apple Extensions on CD-ROM XA discs.
|
|
* 4/14/89 BPA Fixed process_path so will return res_not_found instead of
|
|
* file_not_found if looking for resource.
|
|
* 5/30/89 BPA Changed version number to 3.00 final.
|
|
* 6/6/89 BPA Fixed bug in search_dir which caused it to fail incorrectly in
|
|
* certain boundary conditions.
|
|
* 10/10/89 CAF Added check to id_disk which maps drvr_disk_sw error code to
|
|
* unknown_vol.
|
|
*
|
|
* Changes for System Disk 5.0.3
|
|
*
|
|
* 08/08/90 CAF device_dispatch now will re_try on a disk switched error always. It wasn't
|
|
* happening before during a volume call because no vcr was setup.
|
|
* 08/08/90 MSD Changed device_dispatch to retry the device access if the error
|
|
* was drvr_disk_sw and id_disk_flag is set. This is so drvr_disk_sw
|
|
* will not be returned from the Volume call, but will be returned
|
|
* during other calls (so that the FST can find out where the volume
|
|
* has moved to). It's ok to retry if all you want to do is find
|
|
* out which disk is there; it's not ok to retry otherwise.
|
|
* Thanks to Cheryl for pointing this out!!
|
|
*
|
|
* Changes for System Disk 6.0
|
|
*
|
|
* 2/07/91 CAE Added "support" for the JudgeName call.
|
|
* Enhancement - The Volume call will now setup the "vol_name"
|
|
* output parameter if a "dup_volume" error is being returned.
|
|
* 2/21/91 CAE Set bit 11 of the FST attributes word in the FST Header. This
|
|
* bit now indicates that the FST is read-only.
|
|
* Changed version number to 4.00 final.
|
|
* 3/05/91 CAE Added support for error priorities.
|
|
* 3/27/91 CAE Bug fix - The start_flags table contained an incorrect maximum
|
|
* pcount for SetFileInfo.
|
|
* 4/05/91 CAE Changed version number to 4.00 prototype.
|
|
* 12/05/91 GAB Change maximum allowable pCount for ChangePath.
|
|
* 12/18/91 MSD Moved checking of span1 from parse_path to process_path
|
|
* (after it sets the error priority bit) so it will find the
|
|
* volume first before checking the syntax. Added code to check
|
|
* volume name length (I'm assuming it must be less than 32).
|
|
* Changed version to 4.00 final.
|
|
*
|
|
* Changes for System Disk 6.0.1
|
|
*
|
|
* 25-Aug-92 DAL Changed version to 4.02 prototype.
|
|
* FSTSpecific map_enable and set_map_table now post volume-changed
|
|
* notifications for all of our online volumes.
|
|
*
|
|
* 2-Dec-92 DAL Changed VCR to have a Memory Manager handle to the path table,
|
|
* so we can allow path tables larger than 8K (the GS/OS Memory
|
|
* Manager limit). Handle is allocated when VCR is allocated.
|
|
* Handle is disposed when the VCR is released. To unlock the
|
|
* handle when it's not in use, the FST zeroes current_path_tbl_handle
|
|
* on the way way in and stores a path table handle there when a new
|
|
* one is allocated or an old one is dereferenced. On the way out,
|
|
* we unlock the handle stored in current_path_tbl_handle, if any.
|
|
* (When disposing a handle, we zero the variable if the handle being
|
|
* disposed is the same one stored, to avoid unlocking a handle we no
|
|
* longer own.) Instead of computing a path_table pointer by adding
|
|
* a constant to the vcr_ptr, we now dereference the vcr_path_tbl_handle
|
|
* field inside the vcr.
|
|
*
|
|
* Curiously, GS/OS Internal Snooper CDA has always displayed a 4-byte
|
|
* field for vcr_path_table, so no change is needed there. It used to
|
|
* display the first four bytes of the actual path table data.
|
|
*
|
|
* 2-Apr-93 SS Changed version to $0402 for 6.0.1 (final)
|
|
*
|
|
*******************************************************************************
|
|
eject
|
|
*******************************************************************************
|
|
*
|
|
* Forward addresses and entries
|
|
*
|
|
*******************************************************************************
|
|
|
|
entry fst_header
|
|
entry appl_call
|
|
entry system_call
|
|
entry startup
|
|
entry shutdown
|
|
entry kill_vcr
|
|
entry easy_calls
|
|
entry setup_call
|
|
entry activate_vcr
|
|
entry get_input
|
|
entry send_output
|
|
entry process_fields
|
|
entry field_handlers
|
|
entry add_separator
|
|
entry send_gstring
|
|
entry make_gstring
|
|
entry move_gstring
|
|
entry parse_path
|
|
entry get_name
|
|
entry long_multiply
|
|
entry long_divide
|
|
entry pro_date_time
|
|
entry get_date_time
|
|
entry calc_dow
|
|
entry get_option_list
|
|
entry transform_in_s
|
|
entry transform_in_f
|
|
entry transform_out
|
|
entry transform_vol
|
|
entry transform_gstring
|
|
entry transform_name
|
|
entry get_ext_type
|
|
entry get_file_type
|
|
entry write_protect
|
|
entry create
|
|
entry get_file_info
|
|
entry volume
|
|
entry id_disk
|
|
entry check_apple_ext
|
|
entry build_vcr
|
|
entry set_file_system
|
|
entry open
|
|
entry process_path
|
|
entry find_a_vcr
|
|
entry find_volume
|
|
entry find_file
|
|
entry find_directory
|
|
entry search_path_tbl
|
|
entry move_dir_record
|
|
entry clear_dir_recs
|
|
entry search_dir
|
|
entry build_fcr
|
|
entry get_dir_info
|
|
entry calc_blocks
|
|
entry read
|
|
entry transfer_data
|
|
entry setup_volume
|
|
entry direct_read
|
|
entry sector_read
|
|
entry block_read
|
|
entry device_read
|
|
entry device_dispatch
|
|
entry read_next_block
|
|
entry read_prev_block
|
|
entry read_with_flag
|
|
entry setup_open_buf
|
|
entry check_open_buf
|
|
entry set_end_block
|
|
entry close
|
|
entry set_mark
|
|
entry calc_open_block
|
|
entry update_fcr
|
|
entry get_mark
|
|
entry get_eof
|
|
entry get_dir_entry
|
|
entry find_dir_record
|
|
entry count_dir_recs
|
|
entry do_update
|
|
entry get_dev_num
|
|
entry fst_specific
|
|
entry map_enable
|
|
entry get_map_size
|
|
entry get_map_table
|
|
entry set_map_table
|
|
entry end_segment
|
|
entry invalid_op
|
|
entry cmd_error
|
|
entry nop
|
|
entry wp_error
|
|
entry clc_rtl
|
|
entry h_pcount
|
|
entry h_ref_num
|
|
entry h_pathname
|
|
entry h_dev_name
|
|
entry h_request_access
|
|
entry h_resource_num
|
|
entry h_data_buffer
|
|
entry h_request_count
|
|
entry h_cache_priority
|
|
entry h_position
|
|
entry h_base
|
|
entry h_displacement
|
|
entry h_access
|
|
entry h_file_type
|
|
entry h_aux_type
|
|
entry h_total_blocks
|
|
entry h_storage_type
|
|
entry h_create_date
|
|
entry h_mod_date
|
|
entry h_create_time
|
|
entry h_mod_time
|
|
entry h_blocks_used
|
|
entry h_create_date_time
|
|
entry h_mod_date_time
|
|
entry h_option_list
|
|
entry h_eof
|
|
entry h_resource_eof
|
|
entry h_resource_blocks
|
|
entry h_vol_name
|
|
entry h_free_blocks
|
|
entry h_file_sys_id
|
|
entry h_block_size
|
|
entry h_transfer_count
|
|
entry h_entry_num
|
|
entry h_dev_number
|
|
entry h_name
|
|
entry h_extended
|
|
entry h_command_num
|
|
entry my_sys_exit
|
|
entry setup_vcr
|
|
entry set_user_cache
|
|
entry common_read
|
|
entry condition_flag
|
|
entry next_block
|
|
entry device_read_b
|
|
entry find_our_volume
|
|
entry check_xa
|
|
|
|
eject
|
|
include 'common.equ.src'
|
|
include 'hw.equ.src'
|
|
include 'M16.Memory'
|
|
eject
|
|
*******************************************************************************
|
|
*
|
|
* High Sierra FST Equates
|
|
*
|
|
*******************************************************************************
|
|
|
|
*
|
|
* Volume Control Record Equates - FST Specific
|
|
*
|
|
|
|
vcr_total_blks equ vcr_dev+2 ;Total # blocks on volume.
|
|
vcr_block_size equ vcr_total_blks+4 ;Size of a logical block.
|
|
vcr_path_size equ vcr_block_size+2 ;Size of the path table.
|
|
vcr_root_dir equ vcr_path_size+4 ;Directory record for root dir.
|
|
vcr_create_dt equ vcr_root_dir+34 ;Create date & time.
|
|
vcr_mod_dt equ vcr_create_dt+17 ;Modification date & time.
|
|
vcr_state_flag equ vcr_mod_dt+17 ;Flags for volume status.
|
|
*** changed 2-Dec-92 DAL
|
|
;vcr_path_table equ vcr_state_flag+2 ;Path table.
|
|
vcr_path_tbl_handle equ vcr_state_flag+2 ;handle to path table (Memory Manager handle)
|
|
our_vcr_size equ vcr_path_tbl_handle+4 ;size of VCR (no longer varies with path table size)
|
|
*** end 2-Dec-92
|
|
|
|
*
|
|
* File Control Record Equates - FST Specific
|
|
*
|
|
|
|
fcr_position equ fcr_access+2 ;File mark.
|
|
fcr_entry_num equ fcr_position+4 ;Directory entry #.
|
|
fcr_start_rec equ fcr_entry_num+2 ;Start entry # of current dir block.
|
|
fcr_storage equ fcr_start_rec+2 ;Storage type.
|
|
fcr_eof equ fcr_storage+2 ;Eof.
|
|
fcr_blks equ fcr_eof+4 ;Blocks used.
|
|
fcr_open_block equ fcr_blks+4 ;Block # in open buffer.
|
|
fcr_open_mark equ fcr_open_block+4 ;Mark within open buffer.
|
|
fcr_skip_count equ fcr_open_mark+2 ;Interleave skip counter.
|
|
fcr_error_flag equ fcr_skip_count+2 ;Flag set if open buffer data invalid.
|
|
fcr_type_flag equ fcr_error_flag+2 ;Shows read or get_dir_entry access.
|
|
fcr_dir_record equ fcr_type_flag+2 ;Directory record. MUST BE LAST FIELD!
|
|
|
|
*
|
|
* FST direct page workspace equates.
|
|
*
|
|
|
|
io_buffer equ fst_start ;Pointer to io_buffer.
|
|
my_pblk equ io_buffer+4 ;Pointer to my parameter block.
|
|
my_vcr equ my_pblk+4 ;Pointer to my volume control record.
|
|
my_fcr equ my_vcr+4 ;Pointer to my file control record.
|
|
newline_ptr equ my_fcr+4 ;Pointer to newline list.
|
|
list_ptr equ newline_ptr+4 ;Field list pointer.
|
|
path_ptr equ list_ptr+4 ;Pointer to pathname.
|
|
dev_name equ path_ptr+4 ;Pointer to device name.
|
|
data_buffer equ dev_name+4 ;Pointer to data buffer.
|
|
path_table equ data_buffer+4 ;Pointer to path table.
|
|
entry_offset equ path_table+4 ;Offset to entry in path table.
|
|
fcr_dir_ptr equ entry_offset+2 ;Pointer to directory record in fcr.
|
|
open_buf_ptr equ fcr_dir_ptr+4 ;Pointer to open buffer in fcr.
|
|
dividend equ open_buf_ptr+4 ;32 bit dividend.
|
|
multiplier equ dividend ;32 bit multiplier.
|
|
divisor equ dividend+4 ;32 bit divisor.
|
|
multiplicand equ divisor ;32 bit multiplicand.
|
|
remainder equ divisor+4 ;32 bit remainder.
|
|
newline_char equ remainder+4 ;Will hold first byte of newline table.
|
|
bytes_left equ newline_char+2 ;# bytes till satisfy read request.
|
|
|
|
*
|
|
* FST direct page to save within device_dispatch call...
|
|
*
|
|
|
|
input_string equ bytes_left+4 ;Pointer to input string.
|
|
output_string equ input_string+4 ;Pointer to output string.
|
|
product equ input_string ;8 byte multiplication product.
|
|
temp0 equ output_string+4 ;Temporary storage.
|
|
temp1 equ temp0+2 ;Temporary storage.
|
|
length equ temp1+4 ;Length (temp).
|
|
|
|
drvr_dp_len equ drvr_blk_num+2-drvr_call_num ;Length of driver dp area.
|
|
fst_dp_len equ length+4-input_string ;Length of fst dp area.
|
|
misc_len equ $0060 ;Length of misc area.
|
|
|
|
*
|
|
* High Sierra Volume Descriptor equates.
|
|
* Suffix 0 (_0) equates are for High Sierra, suffix 1 (_1) equates are for ISO.
|
|
*
|
|
|
|
vol_start equ 16 ;Start sector for volume header.
|
|
vol_terminator equ 255 ;Terminator value.
|
|
|
|
vol_type_0 equ 8 ;Offset to type.
|
|
vol_id_end_0 equ 13 ;Offset to end of 'CDROM' string.
|
|
vol_version_0 equ 14 ;Offset to version.
|
|
vol_file_ver_0 equ 854 ;Offset to file structure standard ver.
|
|
|
|
vol_type_1 equ 0 ;Offset to type.
|
|
vol_id_end_1 equ 5 ;Offset to end of 'CD001' string.
|
|
vol_version_1 equ 6 ;Offset to version.
|
|
vol_file_ver_1 equ 881 ;Offset to file structure standard ver.
|
|
|
|
vol_id_start_0 equ 48 ;Offset to start of volume name.
|
|
vol_id_len_0 equ 79-vol_id_start_0 ;Length of volume name -1.
|
|
vol_spce_size_0 equ 88 ;Offset to blocks used.
|
|
vol_blk_size_0 equ 136 ;Offset to block size.
|
|
vol_path_size_0 equ 140 ;Offset to path table size.
|
|
vol_path_loc_0 equ 148 ;Offset to location of path table.
|
|
vol_root_dir_0 equ 180 ;Offset to root directory.
|
|
vol_root_len_0 equ 213-vol_root_dir_0+1 ;Length of root directory.
|
|
vol_create_dt_0 equ 790 ;Offset to create date & time.
|
|
vol_mod_dt_0 equ 806 ;Offset to modification date & time.
|
|
vol_dt_len_0 equ 821-vol_create_dt_0+1 ;Length of create & mod fields.
|
|
|
|
vol_id_start_1 equ 40 ;Offset to start of volume name.
|
|
vol_id_len_1 equ 71-vol_id_start_1 ;Length of volume name -1.
|
|
vol_spce_size_1 equ 80 ;Offset to blocks used.
|
|
vol_blk_size_1 equ 128 ;Offset to block size.
|
|
vol_path_size_1 equ 132 ;Offset to path table size.
|
|
vol_path_loc_1 equ 140 ;Offset to location of path table.
|
|
vol_root_dir_1 equ 156 ;Offset to root directory.
|
|
vol_root_len_1 equ 189-vol_root_dir_1+1 ;Length of root directory.
|
|
vol_create_dt_1 equ 813 ;Offset to create date & time.
|
|
vol_mod_dt_1 equ 830 ;Offset to modification date & time.
|
|
vol_dt_len_1 equ 846-vol_create_dt_1 ;Length of create & mod fields -1.
|
|
|
|
vol_sys_id_0 equ 16 ;Offset to system id.
|
|
vol_sys_id_1 equ 8 ;Offset to system id.
|
|
|
|
vol_xa_label_1 equ 1024 ;Offset to CD-ROM XA label.
|
|
|
|
*
|
|
* High Sierra Directory Record equates...
|
|
* Suffix 0 (_0) equates are for High Sierra, suffix 1 (_1) equates are for ISO.
|
|
*
|
|
|
|
dir_len_dr equ 0 ;Length of directory record.
|
|
dir_xar_len equ 1 ;Extended attribute record length.
|
|
dir_loc_extent equ 2 ;Location of extent.
|
|
dir_data_length equ 10 ;Length of data, in bytes.
|
|
dir_date_time equ 18 ;Recording date and time.
|
|
dir_flags_0 equ 24 ;File flags.
|
|
dir_flags_1 equ 25 ;File flags.
|
|
dir_int_size equ 26 ;Size of interleave.
|
|
dir_int_skip equ 27 ;Interleave skip factor.
|
|
dir_len_fi equ 32 ;Length of file identifier.
|
|
dir_file_id equ 33 ;File identifier.
|
|
|
|
max_rec_len equ 256 ;Max dir record length. Must be even!
|
|
dir_mask equ 2 ;Bit mask for dir bit of file_flags.
|
|
assoc_mask equ 4 ;Bit mask for assoc file bit of flags.
|
|
clear_invisible equ $fffe ;Bit mask for existence bit of flags.
|
|
|
|
*
|
|
* High Sierra Path Table equates...
|
|
* Suffix 0 (_0) equates are for High Sierra, suffix 1 (_1) equates are for ISO.
|
|
*
|
|
|
|
pt_loc_extent_0 equ 0 ;Offset to location of directory extent.
|
|
pt_loc_extent_1 equ 2 ;Offset to location of directory extent.
|
|
pt_len_di_0 equ 5 ;Offset to len_di in path table entry.
|
|
pt_len_di_1 equ 0 ;Offset to len_di in path table entry.
|
|
pt_di_offset_0 equ 3 ;Offset from len_di to identifier in path table entry.
|
|
pt_di_offset_1 equ 8 ;Offset from len_di to identifier in path table entry.
|
|
pt_xar_len_0 equ 4 ;Offset to xar len in path table entry.
|
|
pt_xar_len_1 equ 1 ;Offset to xar len in path table entry.
|
|
pt_parent_dir equ 6 ;Offset to parent_dir in path table.
|
|
pt_entry_len equ 8 ;Length of path table entry - len_di.
|
|
|
|
*
|
|
* General equates...
|
|
*
|
|
|
|
max_month equ 12 ;Max month value.
|
|
max_day equ 31 ;Max day value.
|
|
max_year equ 100 ;Max year value +1.
|
|
max_hour equ 60 ;Max hour value +1.
|
|
max_minute equ 60 ;Max minute value +1.
|
|
max_second equ 60 ;Max second value +1.
|
|
|
|
prodos_name_ln equ 16 ;Max length for class 0 output names +1.
|
|
phys_blk_size equ 512 ;Physical block size.
|
|
iso_bit equ $0001 ;State flag ISO version bit.
|
|
apple_bit equ $0002 ;State flag Apple Extensions bit.
|
|
prodos_bit equ $0004 ;State flag ProDOS Filename Transformation bit.
|
|
xa_bit equ $0008 ;State flag CD-ROM XA bit.
|
|
prodos_format equ $0001 ;Apple Extensions ProDOS format id.
|
|
sys_use_len equ 35 ;Length used to calculate for presence of sys use.
|
|
apple_str_len equ 28 ;Length of apple string.
|
|
xa_str_len equ 8 ;Length of xa_string.
|
|
xa_offset equ 14 ;System use offset for XA discs.
|
|
apple_sig1 equ $4142 ;Signature word 1 in SystemUse field.
|
|
apple_sig2 equ $4141 ;Signature word 2 in SystemUse field.
|
|
crossover equ $2b800 ;Size at which to switch calc_open_block.
|
|
type_file equ 1 ;Storage type for files.
|
|
type_extended equ 5 ;Storage type for extended files.
|
|
type_directory equ 13 ;Storage type for directories.
|
|
type_vol_dir equ 15 ;Storage type for volume directory.
|
|
file_type_dir equ 15 ;File type for directories.
|
|
set_extended equ $8000 ;Extended flag for get_dir_entry.
|
|
online_mask equ $0010 ;Mask for online bit of device status.
|
|
switched_mask equ $0001 ;Mask for switched bit of device status.
|
|
map_enable_off equ $0006 ;Offset into parm list for fst_specific.
|
|
map_size equ $0006 ;Offset into parm list for fst_specific.
|
|
map_buffer equ $0006 ;Offset into parm list for fst_specific.
|
|
get_file_call equ $06 ;Call number for get_file_info.
|
|
get_dir_call equ $1c ;Call number for get_dir_entry.
|
|
|
|
max_names equ 9 ;Max # of names in pathname.
|
|
separator0 equ $2f ;Class 0 separator ('/').
|
|
separator1 equ $3a ;Class 1 separator (':').
|
|
sector_size equ 2048 ;Size of a logical sector.
|
|
hs_id equ $000B ;Identifies high sierra file system.
|
|
iso_id equ $000C ;Identifies ISO 9660 file system.
|
|
path1_mask equ $4000 ;Used to determine if path1 is avail.
|
|
path2_mask equ $0040 ;Used to determine if path2 is avail.
|
|
space equ $20 ;Ascii space.
|
|
|
|
read_access equ $0001 ;Read access.
|
|
full_access equ $00c3 ;Full access.
|
|
user_cache_val equ $0001 ;User cache value.
|
|
in_cache equ $0002 ;Fst cache value.
|
|
max_base equ $0003 ;Maximum base value.
|
|
|
|
*
|
|
* Storage Type Equates
|
|
*
|
|
|
|
standard_type equ $0001 ;Standard file.
|
|
extended_type equ $0005 ;Extended file.
|
|
directory_type equ $000d ;Directory file.
|
|
|
|
*
|
|
* Local Equates...
|
|
*
|
|
|
|
map_ptr equ temp1 ;startup/get_file_type/fst_specific
|
|
|
|
day_of_mon equ temp0 ;calc_dow
|
|
leap_years equ temp1 ;calc_dow
|
|
option_list equ dividend ;get_option_list
|
|
max_len equ temp0 ;get_option_list
|
|
block_count equ temp1 ;get_option_list
|
|
current_dev equ temp0 ;id_disk
|
|
sector_number equ temp1 ;id_disk
|
|
vol_offset equ temp0 ;build_vcr.
|
|
path_size equ temp1 ;build_vcr.
|
|
device equ temp0 ;find_a_vcr
|
|
last_offset equ temp0 ;find_directory
|
|
start_record equ temp1 ;search_path_table
|
|
file_type equ temp0 ;search_dir
|
|
short_file_flag equ temp0 ;build_fcr
|
|
status_flag equ temp0 ;transfer_data
|
|
xfer_count equ temp1 ;transfer_data
|
|
source_ptr equ dividend ;transfer_data
|
|
log_block equ temp1 ;calc_open_block
|
|
old_vp equ list_ptr ;set_map_table
|
|
|
|
*
|
|
* General Equates...
|
|
*
|
|
|
|
len_bounce_tbl equ $000a ;Points to end of bouncing_errors table.
|
|
specific_len equ $0008 ;Length of fst specific dispatch table.
|
|
max_command_num equ $0004 ;Max fst specific command_num.
|
|
input_len equ $0018 ;Count of input parameters.
|
|
file_sys_len equ $001e ;Length of file_sys_table-2.
|
|
call_count equ $000f ;Count of handled calls.
|
|
max_call equ $0066 ;Last valid application call.
|
|
max_sys equ $0008 ;Last valid system call.
|
|
|
|
*
|
|
* Equates used to build the start_flags table...
|
|
*
|
|
|
|
path_used equ $0100 ;Path used bit.
|
|
vcr_used equ $0200 ;Vcr used bit.
|
|
fcr_used equ $0400 ;Fcr used bit.
|
|
|
|
max_mask equ $001f ;Isolate max pcount.
|
|
min_mask equ $00e0 ;Isolate min pcount.
|
|
|
|
max_class equ $0001 ;Maximum class #.
|
|
|
|
max_pcnt1 equ 1+1 ;Values for max pcounts.
|
|
max_pcnt2 equ 2+1
|
|
max_pcnt3 equ 3+1
|
|
max_pcnt4 equ 4+1
|
|
max_pcnt5 equ 5+1
|
|
max_pcnt6 equ 6+1
|
|
max_pcnt7 equ 7+1
|
|
max_pcnt8 equ 8+1
|
|
max_pcnt9 equ 9+1
|
|
max_pcnt10 equ 10+1
|
|
max_pcnt11 equ 11+1
|
|
max_pcnt12 equ 12+1
|
|
max_pcnt13 equ 13+1
|
|
max_pcnt14 equ 14+1
|
|
max_pcnt15 equ 15+1
|
|
max_pcnt16 equ 16+1
|
|
max_pcnt17 equ 17+1
|
|
|
|
min_pcnt1 equ $0020 ;Values for min pcounts.
|
|
min_pcnt2 equ $0040
|
|
min_pcnt3 equ $0060
|
|
min_pcnt4 equ $0080
|
|
min_pcnt5 equ $00A0
|
|
|
|
*
|
|
* Equates for field list tables...
|
|
*
|
|
|
|
field_mask equ $00ff ;Isolate field.
|
|
offset_mask equ $3f00 ;Isolate offset.
|
|
io_mask equ $4000 ;Isolate i/o flag.
|
|
|
|
terminate equ $8000 ;Terminator bit.
|
|
input equ $0000 ;Input bit.
|
|
output equ $4000 ;Output bit.
|
|
|
|
f_pcount equ $0000 ;(w) input.
|
|
f_ref_num equ $0001 ;(w) input/output.
|
|
f_pathname equ $0002 ;(ptr) input.
|
|
f_dev_name equ $0003 ;(ptr) input.
|
|
f_request_access equ $0004 ;(w) input.
|
|
f_resource_num equ $0005 ;(w) input.
|
|
f_data_buffer equ $0006 ;(ptr) input.
|
|
f_request_count equ $0007 ;(lw) input.
|
|
f_cache_priority equ $0008 ;(w) input.
|
|
f_position equ $0009 ;(lw) input/output.
|
|
f_base equ $000a ;(w) input.
|
|
f_displacement equ $000b ;(lw) input.
|
|
f_access equ $000c ;(w) output.
|
|
f_file_type equ $000d ;(w) output.
|
|
f_aux_type equ $000e ;(lw) output.
|
|
f_total_blocks equ $000f ;(lw) output.
|
|
f_storage_type equ $0010 ;(w) output.
|
|
f_create_date equ $0011 ;(w) output.
|
|
f_create_time equ $0012 ;(w) output.
|
|
f_mod_date equ $0013 ;(w) output.
|
|
f_mod_time equ $0014 ;(w) output.
|
|
f_blocks_used equ $0015 ;(lw) output.
|
|
f_create_date_time equ $0016 ;(4w) output.
|
|
f_mod_date_time equ $0017 ;(4w) output.
|
|
f_option_list equ $0018 ;(ptr) output.
|
|
f_eof equ $0019 ;(lw) output.
|
|
f_resource_eof equ $001a ;(lw) output.
|
|
f_resource_blocks equ $001b ;(lw) output.
|
|
f_vol_name equ $001c ;(ptr) output.
|
|
f_free_blocks equ $001d ;(lw) output.
|
|
f_file_sys_id equ $001e ;(w) output.
|
|
f_block_size equ $001f ;(w) output.
|
|
f_transfer_count equ $0020 ;(lw) output.
|
|
f_entry_num equ $0021 ;(w) output.
|
|
f_dev_number equ $0022 ;(w) output.
|
|
f_name equ $0023 ;(ptr) output.
|
|
f_extended equ $0024 ;(w) output.
|
|
f_command_num equ $0025 ;(w) input.
|
|
|
|
offset0 equ $0000
|
|
offset2 equ $0200
|
|
offset4 equ $0400
|
|
offset6 equ $0600
|
|
offset8 equ $0800
|
|
offsetA equ $0A00
|
|
offsetC equ $0C00
|
|
offsetE equ $0E00
|
|
offset10 equ $1000
|
|
offset12 equ $1200
|
|
offset14 equ $1400
|
|
offset16 equ $1600
|
|
offset18 equ $1800
|
|
offset1A equ $1A00
|
|
offset1C equ $1C00
|
|
offset1E equ $1E00
|
|
offset20 equ $2000
|
|
offset22 equ $2200
|
|
offset24 equ $2400
|
|
offset26 equ $2600
|
|
offset28 equ $2800
|
|
offset2A equ $2A00
|
|
offset2C equ $2C00
|
|
offset2E equ $2E00
|
|
offset30 equ $3000
|
|
offset32 equ $3200
|
|
offset34 equ $3400
|
|
offset36 equ $3600
|
|
offset3A equ $3a00
|
|
eject
|
|
*******************************************************************************
|
|
*
|
|
* FST HEADER
|
|
* Used by GS/OS at boot time.
|
|
*
|
|
*******************************************************************************
|
|
|
|
fst_header proc
|
|
code_start DC.B 'FST ' ;Load identification (4 bytes).
|
|
DC.L appl_call ;Entry point for application calls.
|
|
DC.L system_call ;Entry point for system calls.
|
|
DC.W HS_ID ;High Sierra FST id.
|
|
DC.W $9800 ;Flags: uppercase, clear msb, read-only.
|
|
DC.W $0402 ;Version 4.02 final
|
|
DC.W $800 ;Normal block size. (2k)
|
|
DC.L $57800 ;Maximum blocks/volume. (700Mb)
|
|
DC.L 4 ;Minimum blocks/volume. (8k)
|
|
DC.L $2bbf7800 ;Maximum file size. (699.97Mb)
|
|
DC.L 00000000 ;Reserved.
|
|
DC.B 11 ;Length of FST name.
|
|
DC.B 'High Sierra' ;Text of FST name.
|
|
DC.B 32 ;Length of comment.
|
|
DC.B 'High Sierra FST v04.02'
|
|
DC.W 0000 ;reserved field
|
|
|
|
DC.B endcredit-startcredit
|
|
startcredit DC.B 'Copyright 1987-1992 Apple Computer, Inc. '
|
|
DC.B 'Written by Bryan Atsatt.'
|
|
DC.B 'Tested by Cary Farrier'
|
|
endcredit
|
|
ENDP
|
|
eject
|
|
*******************************************************************************
|
|
*
|
|
* DATA STORAGE AREA
|
|
*
|
|
*******************************************************************************
|
|
|
|
data record export
|
|
|
|
*
|
|
* Miscellaneous constants/variables/storage...
|
|
*
|
|
apple_string DC.B 'APPLE COMPUTER, INC., TYPE: ' ;Apple Extensions.
|
|
xa_string dc.b 'CD-XA001' ;Must match this for CD-ROM XA.
|
|
hs_string DC.B 'CDROM' ;Must match this for High Sierra.
|
|
iso_string DC.B 'CD001' ;Must match this for ISO.
|
|
|
|
bounce_errors dc.w bad_system_call ;Bouncing errors list.
|
|
dc.w invalid_pcount
|
|
dc.w bad_path_syntax
|
|
dc.w vol_not_found
|
|
dc.w unknown_vol
|
|
dc.w not_block_dev
|
|
|
|
length_temp ds.b 2 ;Temporary length storage.
|
|
input_error ds.b 2 ;Storage for input error.
|
|
call DS.B 2 ;Current call #
|
|
trans_call DS.B 2 ;Translated call #.
|
|
class DS.B 2 ;Current class #.
|
|
real_log_size DS.B 2 ;Readl logical block size. MUST INIT!
|
|
io_buffer_vp DS.B 4 ;VP to io_buffer.
|
|
max_pcount DS.B 2 ;Maximum pcount.
|
|
min_pcount DS.B 2 ;Minuimum pcount.
|
|
flags DS.B 2 ;Startup flags word.
|
|
io_flag DS.B 2 ;I/O flag for process_fields.
|
|
file_name DS.B 45 ;File name in gstring format.
|
|
string_buffer DS.B 45 ;Temporary storage for strings.
|
|
name_count DS.B 2 ;Count of names in pathname.
|
|
name_offsets DS.B 8 ;Offsets to start of names in pathname.
|
|
temp_offsets DS.B 8 ;Temporary storage for offsets.
|
|
path_table_size DS.B 2 ;Path table size.
|
|
current_name DS.B 2 ;Current directory.
|
|
current_record DS.B 2 ;Current record.
|
|
record_number DS.B 2 ;Record number.
|
|
record_offset DS.B 2 ;Offset to record.
|
|
record_count DS.B 2 ;Record count.
|
|
cache_value DS.B 2 ;Value of drvr_cache at call start.
|
|
dir_record_0 DS.B max_rec_len ;Buffer for directory record 0.
|
|
dir_record_1 DS.B max_rec_len ;Buffer for directory record 1.
|
|
dir_length DS.B 4 ;Length of directory record.
|
|
start_block DS.B 4 ;First block of file/directory.
|
|
end_block DS.B 4 ;Last block of file/directory.
|
|
newline_length DS.B 2 ;Length of newline list.
|
|
newline_mask DS.B 2 ;Mask for newline.
|
|
interleave_size DS.B 2 ;# consecutive blocks in file extent.
|
|
interleave_skip DS.B 2 ;# blocks to skip btwx consecutive.
|
|
skip_count DS.B 2 ;# blocks till next skip.
|
|
open_mark DS.B 2 ;position mark within open_buffer.
|
|
send_flag DS.B 2 ;Flag for send_open_bufr routine.
|
|
status_list DS.B 6 ;Space for status list.
|
|
skip_read_flag DS.B 2 ;Flag used by read_next_block.
|
|
read_size DS.B 4 ;Size of multi-block read.
|
|
abs_block DS.B 4 ;Absolute block number.
|
|
read_count DS.B 2 ;Read block count.
|
|
id_disk_flag DS.B 2 ;1 = id_disk routine active, else 0.
|
|
state_flag DS.B 2 ;b0 = 1 if ISO version of High Sierra.
|
|
;b1 = 1 if Apple Extensions disc.
|
|
;b2 = 1 if ProDOS Transformation required.
|
|
|
|
error_priority DS.B 2 ;storage for error priority
|
|
|
|
*** added 2-Dec-92 DAL
|
|
current_path_tbl_handle ds.b 4 ;path table handle to unlock on the way out
|
|
*** end 2-Dec-92
|
|
|
|
untitled_str DC.B 'UNTITLED' ;Untitled string.
|
|
DC.B $00
|
|
|
|
*
|
|
* Miscellaneous storage that must be kept together so can be saved during
|
|
* the device_dispatch call...
|
|
*
|
|
* NOTE: If this section changes length, the misc_len equate MUST be changed!!!
|
|
*
|
|
|
|
gstring DS.B 45 ;Temp storage for gstrings.
|
|
volume_name DS.B 45 ;Volume name in gstring format.
|
|
current_device DS.B 2 ;Current device.
|
|
start_device DS.B 2 ;Start device.
|
|
log_blk_size DS.B 2 ;Logical block size. MUST INIT!
|
|
|
|
storage_drvr DS.B drvr_dp_len ;Space for driver dp save.
|
|
storage_fst DS.B fst_dp_len ;Space for fst dp save.
|
|
storage_misc DS.B 45+45+6 ;Space for misc save.
|
|
|
|
*
|
|
* D_info parameter table...
|
|
*
|
|
|
|
d_info_parms DC.W 8 ;Pcount.
|
|
d_info_device DC.W 0 ;Device number.
|
|
DC.L string_buffer ;Pointer to output string.
|
|
DC.W 0 ;Characteristics.
|
|
DC.L 0 ;Total blocks.
|
|
DC.W 0 ;Slot number.
|
|
DC.W 0 ;Unit number.
|
|
DC.W 0 ;Version number.
|
|
d_info_id DC.W 0 ;Device ID.
|
|
|
|
*
|
|
* File type map data and map_enable_flag...
|
|
*
|
|
|
|
map_buffer_vp DS.B 4 ;Storage for vp.
|
|
map_buffer_ptr DS.B 4 ;Storage for pointer.
|
|
|
|
default_map DC.W $000f ;Size of default map.
|
|
DC.B '.TXT' ;Record 0.
|
|
DC.B $00,$04
|
|
DC.B '.BAT' ;Record 1.
|
|
DC.B $00,$04
|
|
DC.B $00 ;Map terminator.
|
|
|
|
map_enable_flag DC.W 0001 ;Default is enabled.
|
|
|
|
*
|
|
* Dispatch table for fst_specific commands...
|
|
*
|
|
specific_cmds DC.W map_enable ;Map_enable.
|
|
DC.W get_map_size ;Get_map_size.
|
|
DC.W get_map_table ;Get_map_table.
|
|
DC.W set_map_table ;Set_map_table.
|
|
|
|
*
|
|
* Storage for input parameters...
|
|
*
|
|
|
|
pcount DC.W 00 ;Parameter count.
|
|
ref_num DC.W 00 ;File reference number.
|
|
request_access DC.W 00 ;Request access permissions.
|
|
resource_num DC.W 00 ;Resource number.
|
|
request_count DC.L 00 ;Request count.
|
|
cache_priority DC.W 00 ;Cache priority flag.
|
|
position DC.L 00 ;File mark.
|
|
base DC.W 00 ;Base.
|
|
displacement DC.L 00 ;Displacement.
|
|
command_num DC.W 00 ;Fst_specific command number.
|
|
|
|
*
|
|
* Storage for output parameters...
|
|
*
|
|
|
|
total_blocks DC.L 00 ;Total blocks.
|
|
storage_type DC.W 00 ;Storage type.
|
|
prodos_time DC.L 00 ;Prodos date/time.
|
|
blocks_used DC.L 00 ;Blocks used.
|
|
|
|
|
|
create_date_time ;Create_date_time structure.
|
|
second dc.b 00
|
|
minute dc.b 00
|
|
hour dc.b 00
|
|
year dc.b 00
|
|
day dc.b 00
|
|
month dc.b 00
|
|
null dc.b 00
|
|
weekday dc.b 00
|
|
|
|
default_date_time dc.b 00,00,12,88,00,00,00,06
|
|
|
|
|
|
mod_date_time DCB.B 8,00 ;Modification date and time.
|
|
eof DC.L 00 ;End of file.
|
|
resource_eof DC.L 00 ;Resource end of file.
|
|
resource_blocks DC.L 00 ;Resource blocks used.
|
|
block_size DC.W 00 ;Block size.
|
|
transfer_count DC.L 00 ;Transfer count.
|
|
entry_num DC.W 00 ;Entry number.
|
|
dev_number DC.W 00 ;Device number.
|
|
extended_flag DC.W 00 ;Extended flag.
|
|
|
|
*
|
|
* High Sierra and ISO Version Support
|
|
*
|
|
* Set_file_system will copy either hs_offsets or iso_offsets into the
|
|
* file_sys_table and all references to the labels in this table will be
|
|
* made as variables.
|
|
*
|
|
* High Sierra/ISO Field Offsets...
|
|
*
|
|
|
|
file_sys_table ;
|
|
|
|
vol_id_start DS.B 2 ;Offset to start of volume name.
|
|
vol_id_len DS.B 2 ;Length of volume name -1.
|
|
vol_space_size DS.B 2 ;Offset to blocks used.
|
|
vol_block_size DS.B 2 ;Offset to block size.
|
|
vol_path_size DS.B 2 ;Offset to path table size.
|
|
vol_path_loc DS.B 2 ;Offset to location of path table.
|
|
vol_root_dir DS.B 2 ;Offset to root directory.
|
|
vol_root_len DS.B 2 ;Length of root directory.
|
|
vol_create_dt DS.B 2 ;Offset to create date & time.
|
|
vol_mod_dt DS.B 2 ;Offset to modification date & time.
|
|
vol_dt_len DS.B 2 ;Length of create & mod fields.
|
|
dir_file_flags DS.B 2 ;File flags.
|
|
pt_loc_extent DS.B 2 ;Offset to location of directory extent.
|
|
pt_len_di DS.B 2 ;Offset to len_di in path table entry.
|
|
pt_di_offset ds.b 2 ;Offset from len_di to identifier in path table entry.
|
|
pt_xar_len ds.b 2 ;Offset to xar len in path table entry.
|
|
|
|
*
|
|
* High Sierra Field Offsets...
|
|
*
|
|
|
|
hs_offsets DC.W vol_id_start_0 ;Offset to start of volume name.
|
|
DC.W vol_id_len_0 ;Length of volume name -1.
|
|
DC.W vol_spce_size_0 ;Offset to blocks used.
|
|
DC.W vol_blk_size_0 ;Offset to block size.
|
|
DC.W vol_path_size_0 ;Offset to path table size.
|
|
DC.W vol_path_loc_0 ;Offset to loc of path table.
|
|
DC.W vol_root_dir_0 ;Offset to root directory.
|
|
DC.W vol_root_len_0 ;Length of root directory.
|
|
DC.W vol_create_dt_0 ;Offset to create date & time.
|
|
DC.W vol_mod_dt_0 ;Offset to mod date & time.
|
|
DC.W vol_dt_len_0 ;Length of create & mod fields.
|
|
DC.W dir_flags_0 ;File flags.
|
|
DC.W pt_loc_extent_0 ;Offset to loc of dir extent.
|
|
DC.W pt_len_di_0 ;Offset to len_di in path table.
|
|
DC.W pt_di_offset_0 ;Offset from len_di to identifier in path table entry.
|
|
DC.W pt_xar_len_0 ;Offset to xar len in path table entry.
|
|
|
|
*
|
|
* ISO Field Offsets...
|
|
*
|
|
|
|
iso_offsets DC.W vol_id_start_1 ;Offset to start of volume name.
|
|
DC.W vol_id_len_1 ;Length of volume name -1.
|
|
DC.W vol_spce_size_1 ;Offset to blocks used.
|
|
DC.W vol_blk_size_1 ;Offset to block size.
|
|
DC.W vol_path_size_1 ;Offset to path table size.
|
|
DC.W vol_path_loc_1 ;Offset to loc of path table.
|
|
DC.W vol_root_dir_1 ;Offset to root directory.
|
|
DC.W vol_root_len_1 ;Length of root directory.
|
|
DC.W vol_create_dt_1 ;Offset to create date & time.
|
|
DC.W vol_mod_dt_1 ;Offset to mod date & time.
|
|
DC.W vol_dt_len_1 ;Length of create & mod fields.
|
|
DC.W dir_flags_1 ;File flags.
|
|
DC.W pt_loc_extent_1 ;Offset to loc of dir extent.
|
|
DC.W pt_len_di_1 ;Offset to len_di in path table.
|
|
DC.W pt_di_offset_1 ;Offset from len_di to identifier in path table entry.
|
|
DC.W pt_xar_len_1 ;Offset to xar len in path table entry.
|
|
|
|
eject
|
|
*
|
|
* STARTUP TABLES
|
|
*
|
|
* The following table is used to translate GS/OS call #'s I handle
|
|
* to sequential values from 0 to 9, times 2.
|
|
*
|
|
handled_calls DC.B $01,$02,$04,$05,$06,$08,$0b,$10,$12,$14,$16,$17,$19,$1c,$20,$33
|
|
|
|
*
|
|
* The following table is used to setup and verify some parameters.
|
|
* Each call has a one word entry in the table with the following
|
|
* format:
|
|
*
|
|
* 1 - Max PCount for the call
|
|
* 2 - Min PCount for the call
|
|
* 3 - Pathnames used by call
|
|
* 4 - Volume control record used
|
|
* 5 - File control record used
|
|
* 6 - I/O buffer used
|
|
*
|
|
* |6|5|4|3| 2 | 1 |
|
|
* _______|_|_|_|_|_____|_________|
|
|
* | | | | | | | | | | | | | | | | |
|
|
* |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|
|
* | | |
|
|
* 1 6 0 8 0 0
|
|
*
|
|
|
|
start_flags ;
|
|
|
|
DC.W max_pcnt7+min_pcnt1+path_used ;(01) Create
|
|
DC.W max_pcnt1+min_pcnt1+path_used ;(02) Destroy
|
|
DC.W max_pcnt3+min_pcnt2+path_used ;(04) Change_path
|
|
DC.W max_pcnt12+min_pcnt2+path_used ;(05) Set_file_info
|
|
DC.W max_pcnt12+min_pcnt2+path_used ;(06) Get_File_Info
|
|
DC.W max_pcnt6+min_pcnt2 ;(08) Volume
|
|
DC.W max_pcnt1+min_pcnt1+path_used ;(0B) Clr_backup_bit
|
|
DC.W max_pcnt15+min_pcnt2+path_used ;(10) Open
|
|
DC.W max_pcnt5+min_pcnt4+vcr_used+fcr_used ;(12) Read
|
|
DC.W max_pcnt1+min_pcnt1+vcr_used+fcr_used ;(14) Close
|
|
DC.W max_pcnt3+min_pcnt3+vcr_used+fcr_used ;(16) Set_mark
|
|
DC.W max_pcnt2+min_pcnt2+vcr_used+fcr_used ;(17) Get_mark
|
|
DC.W max_pcnt2+min_pcnt2+vcr_used+fcr_used ;(19) Get_eof
|
|
DC.W max_pcnt17+min_pcnt5+vcr_used+fcr_used ;(1C) Get_dir_entry
|
|
DC.W max_pcnt2+min_pcnt2+path_used ;(20) Get_dev_num
|
|
DC.W max_pcnt3+min_pcnt3 ;(33) Fst_specific
|
|
|
|
eject
|
|
|
|
* DISPATCH TABLES
|
|
*
|
|
cmd_tbl DC.W create ;($01) create
|
|
DC.W write_protect ;($02) destroy
|
|
DC.W cmd_error ;($03) unimplemented
|
|
DC.W write_protect ;($04) change_path
|
|
DC.W write_protect ;($05) set_file_info
|
|
DC.W get_file_info ;($06) get_file_info
|
|
DC.W invalid_op ;($07) judge_name
|
|
DC.W volume ;($08) volume
|
|
DC.W cmd_error ;($09) set_prefix
|
|
DC.W cmd_error ;($0A) get_prefix'
|
|
DC.W write_protect ;($0B) clear_backup_bit
|
|
DC.W cmd_error ;($0C) unimplemented
|
|
DC.W cmd_error ;($0D) unimplemented
|
|
DC.W cmd_error ;($0E) unimplemented
|
|
DC.W cmd_error ;($0F) unimplemented
|
|
DC.W open ;($10) open
|
|
DC.W cmd_error ;($11) newline
|
|
DC.W read ;($12) read
|
|
DC.W wp_error ;($13) write
|
|
DC.W close ;($14) close
|
|
DC.W nop ;($15) flush
|
|
DC.W set_mark ;($16) set_mark
|
|
DC.W get_mark ;($17) get_mark
|
|
DC.W wp_error ;($18) set_eof
|
|
DC.W get_eof ;($19) get_eof
|
|
DC.W cmd_error ;($1A) set_level
|
|
DC.W cmd_error ;($1B) get_level
|
|
DC.W get_dir_entry ;($1C) get_dir_entry
|
|
DC.W cmd_error ;($1D) unimplemented
|
|
DC.W cmd_error ;($1E) unimplemented
|
|
DC.W cmd_error ;($1F) unimplemented
|
|
DC.W get_dev_num ;($20) get_dev_num
|
|
DC.W cmd_error ;($21) get_last_dev
|
|
DC.W cmd_error ;($22) read_block
|
|
DC.W cmd_error ;($23) write_block
|
|
DC.W wp_error ;($24) format
|
|
DC.W wp_error ;($25) erase_disk
|
|
DC.W cmd_error ;($26) get_pathname
|
|
DC.W cmd_error ;($27) get_name
|
|
DC.W cmd_error ;($28) get_boot_vol
|
|
DC.W cmd_error ;($29) quit
|
|
DC.W cmd_error ;($2A) get_version
|
|
DC.W cmd_error ;($2B) get_fst_info
|
|
DC.W cmd_error ;($2C) d_info
|
|
DC.W cmd_error ;($2D) d_status
|
|
DC.W cmd_error ;($2E) d_control
|
|
DC.W cmd_error ;($2F) d_read
|
|
DC.W cmd_error ;($30) d_write
|
|
DC.W cmd_error ;($31) alloc_interrupt
|
|
DC.W cmd_error ;($32) dealloc_interrupt
|
|
DC.W fst_specific ;($33) fst_specific.
|
|
|
|
|
|
sys_tbl DC.W startup ;Initialize
|
|
DC.W shutdown ;Quit
|
|
DC.W kill_vcr ;was clc_rtl, 2-Dec-92 DAL
|
|
DC.W clc_rtl ;Do nothing call.
|
|
|
|
eject
|
|
|
|
* FIELD TABLES
|
|
*
|
|
* The following tables point to the field lists for class 0 and 1...
|
|
*
|
|
class0 DC.W call01_class0 ;Create.
|
|
DC.W call01_class0 ;Destroy.
|
|
DC.W call01_class0 ;Change_path.
|
|
DC.W call01_class0 ;Set_file_info.
|
|
DC.W call06_class0 ;Get_file_info.
|
|
DC.W call08_class0 ;Volume.
|
|
DC.W call01_class0 ;Clear_backup_bit.
|
|
DC.W call10_class0 ;Open.
|
|
DC.W call12_class0 ;Read.
|
|
DC.W call14_class0 ;Close.
|
|
DC.W call16_class0 ;Set_mark.
|
|
DC.W call17_class0 ;Get_mark.
|
|
DC.W call19_class0 ;Get_eof.
|
|
DC.W call1c_class0 ;Get_dir_entry.
|
|
DC.W call20_class0 ;Get_dev_num.
|
|
|
|
class1 DC.W call01_class1 ;Create.
|
|
DC.W call01_class1 ;Destroy.
|
|
DC.W call01_class1 ;Change_path.
|
|
DC.W call01_class1 ;Set_file_info.
|
|
DC.W call06_class1 ;Get_file_info
|
|
DC.W call08_class1 ;Volume.
|
|
DC.W call01_class1 ;Clear_backup_bit.
|
|
DC.W call10_class1 ;Open.
|
|
DC.W call12_class1 ;Read.
|
|
DC.W call14_class1 ;Close.
|
|
DC.W call16_class1 ;Set_mark.
|
|
DC.W call17_class1 ;Get_mark.
|
|
DC.W call19_class1 ;Get_eof.
|
|
DC.W call1c_class1 ;Get_dir_entry.
|
|
DC.W call20_class1 ;Get_dev_num.
|
|
DC.W call33_class1 ;Fst_specific.
|
|
|
|
*
|
|
* Each call has a list of one word entries with the following format:
|
|
*
|
|
* 1 - Field number times two
|
|
* 2 - Field offset
|
|
* 3 - I/O flag: 0 = input, 1 = output.
|
|
* 4 - Terminator: 1 = last entry in list.
|
|
*
|
|
* |4|3| 2 | 1 |
|
|
* |_|_|___________|_______________|
|
|
* | | | | | | | | | | | | | | | | |
|
|
* |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|
|
* | | |
|
|
* 1 6 0 8 0 0
|
|
|
|
*
|
|
* Create, Destroy, Change_path, Set_file_info, Clear_backup_bit field lists...
|
|
*
|
|
|
|
call01_class0 DC.W 2*f_pathname+offset0+input+terminate
|
|
|
|
call01_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_pathname+offset2+input+terminate
|
|
|
|
*
|
|
* Get_file_info field lists...
|
|
*
|
|
|
|
call06_class0 DC.W 2*f_pathname+offset0+input
|
|
DC.W 2*f_access+offset4+output
|
|
DC.W 2*f_file_type+offset6+output
|
|
DC.W 2*f_aux_type+offset8+output
|
|
DC.W 2*f_storage_type+offsetc+output
|
|
DC.W 2*f_create_date+offsete+output
|
|
DC.W 2*f_create_time+offset10+output
|
|
DC.W 2*f_mod_date+offset12+output
|
|
DC.W 2*f_mod_time+offset14+output
|
|
DC.W 2*f_blocks_used+offset16+output+terminate
|
|
|
|
call06_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_pathname+offset2+input
|
|
DC.W 2*f_access+offset6+output
|
|
DC.W 2*f_file_type+offset8+output
|
|
DC.W 2*f_aux_type+offseta+output
|
|
DC.W 2*f_storage_type+offsete+output
|
|
DC.W 2*f_create_date_time+offset10+output
|
|
DC.W 2*f_mod_date_time+offset18+output
|
|
DC.W 2*f_option_list+offset20+output
|
|
DC.W 2*f_eof+offset24+output
|
|
DC.W 2*f_blocks_used+offset28+output
|
|
DC.W 2*f_resource_eof+offset2c+output
|
|
DC.W 2*f_resource_blocks+offset30+output+terminate
|
|
|
|
*
|
|
* Volume field lists...
|
|
*
|
|
|
|
call08_class0 DC.W 2*f_dev_name+offset0+input
|
|
DC.W 2*f_vol_name+offset4+output
|
|
DC.W 2*f_total_blocks+offset8+output
|
|
DC.W 2*f_free_blocks+offsetc+output
|
|
DC.W 2*f_file_sys_id+offset10+output+terminate
|
|
|
|
call08_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_dev_name+offset2+input
|
|
DC.W 2*f_vol_name+offset6+output
|
|
DC.W 2*f_total_blocks+offseta+output
|
|
DC.W 2*f_free_blocks+offsete+output
|
|
DC.W 2*f_file_sys_id+offset12+output
|
|
DC.W 2*f_block_size+offset14+output+terminate
|
|
|
|
*
|
|
* Open field lists...
|
|
*
|
|
|
|
call10_class0 DC.W 2*f_ref_num+offset0+output
|
|
DC.W 2*f_pathname+offset2+input+terminate
|
|
|
|
call10_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_ref_num+offset2+output
|
|
DC.W 2*f_pathname+offset4+input
|
|
DC.W 2*f_request_access+offset8+input
|
|
DC.W 2*f_resource_num+offseta+input
|
|
DC.W 2*f_access+offsetc+output
|
|
DC.W 2*f_file_type+offsete+output
|
|
DC.W 2*f_aux_type+offset10+output
|
|
DC.W 2*f_storage_type+offset14+output
|
|
DC.W 2*f_create_date_time+offset16+output
|
|
DC.W 2*f_mod_date_time+offset1e+output
|
|
DC.W 2*f_option_list+offset26+output
|
|
DC.W 2*f_eof+offset2a+output
|
|
DC.W 2*f_blocks_used+offset2e+output
|
|
DC.W 2*f_resource_eof+offset32+output
|
|
DC.W 2*f_resource_blocks+offset36+output+terminate
|
|
|
|
*
|
|
* Read field lists...
|
|
*
|
|
|
|
call12_class0 DC.W 2*f_ref_num+offset0+input
|
|
DC.W 2*f_data_buffer+offset2+input
|
|
DC.W 2*f_request_count+offset6+input
|
|
DC.W 2*f_transfer_count+offseta+output+terminate
|
|
|
|
call12_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_ref_num+offset2+input
|
|
DC.W 2*f_data_buffer+offset4+input
|
|
DC.W 2*f_request_count+offset8+input
|
|
DC.W 2*f_transfer_count+offsetc+output
|
|
DC.W 2*f_cache_priority+offset10+input+terminate
|
|
|
|
*
|
|
* Close field lists...
|
|
*
|
|
|
|
call14_class0 DC.W 2*f_ref_num+offset0+input+terminate
|
|
|
|
call14_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_ref_num+offset2+input+terminate
|
|
|
|
*
|
|
* Set_mark field lists...
|
|
*
|
|
|
|
call16_class0 DC.W 2*f_ref_num+offset0+input
|
|
DC.W 2*f_displacement+offset2+input+terminate
|
|
|
|
call16_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_ref_num+offset2+input
|
|
DC.W 2*f_base+offset4+input
|
|
DC.W 2*f_displacement+offset6+input+terminate
|
|
|
|
*
|
|
* Get_mark field lists...
|
|
*
|
|
|
|
call17_class0 DC.W 2*f_ref_num+offset0+input
|
|
DC.W 2*f_position+offset2+output+terminate
|
|
|
|
call17_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_ref_num+offset2+input
|
|
DC.W 2*f_position+offset4+output+terminate
|
|
|
|
*
|
|
* Get_eof field lists...
|
|
*
|
|
|
|
call19_class0 DC.W 2*f_ref_num+offset0+input
|
|
DC.W 2*f_eof+offset2+output+terminate
|
|
|
|
call19_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_ref_num+offset2+input
|
|
DC.W 2*f_eof+offset4+output+terminate
|
|
|
|
*
|
|
* Get_dir_entry field lists...
|
|
*
|
|
|
|
call1c_class0 DC.W 2*f_ref_num+offset0+input
|
|
DC.W 2*f_extended+offset2+output
|
|
DC.W 2*f_base+offset4+input
|
|
DC.W 2*f_displacement+offset6+input
|
|
DC.W 2*f_name+offset8+output
|
|
DC.W 2*f_entry_num+offsetc+output
|
|
DC.W 2*f_file_type+offsete+output
|
|
DC.W 2*f_eof+offset10+output
|
|
DC.W 2*f_blocks_used+offset14+output
|
|
DC.W 2*f_create_date_time+offset18+output
|
|
DC.W 2*f_mod_date_time+offset20+output
|
|
DC.W 2*f_access+offset28+output
|
|
DC.W 2*f_aux_type+offset2a+output
|
|
DC.W 2*f_file_sys_id+offset2e+output+terminate
|
|
|
|
call1c_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_ref_num+offset2+input
|
|
DC.W 2*f_extended+offset4+output
|
|
DC.W 2*f_base+offset6+input
|
|
DC.W 2*f_displacement+offset8+input
|
|
DC.W 2*f_name+offseta+output
|
|
DC.W 2*f_entry_num+offsete+output
|
|
DC.W 2*f_file_type+offset10+output
|
|
DC.W 2*f_eof+offset12+output
|
|
DC.W 2*f_blocks_used+offset16+output
|
|
DC.W 2*f_create_date_time+offset1a+output
|
|
DC.W 2*f_mod_date_time+offset22+output
|
|
DC.W 2*f_access+offset2a+output
|
|
DC.W 2*f_aux_type+offset2c+output
|
|
DC.W 2*f_file_sys_id+offset30+output
|
|
DC.W 2*f_option_list+offset32+output
|
|
DC.W 2*f_resource_eof+offset36+output
|
|
DC.W 2*f_resource_blocks+offset3A+output+terminate
|
|
|
|
*
|
|
* Get_dev_num field lists...
|
|
*
|
|
|
|
call20_class0 DC.W 2*f_dev_name+offset0+input
|
|
DC.W 2*f_dev_number+offset4+output+terminate
|
|
|
|
call20_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_dev_name+offset2+input
|
|
DC.W 2*f_dev_number+offset6+output+terminate
|
|
*
|
|
* Fst_specific field list (this is always a class 1 call)...
|
|
*
|
|
|
|
call33_class1 DC.W 2*f_pcount+offset0+input
|
|
DC.W 2*f_command_num+offset4+input+terminate
|
|
|
|
*
|
|
* The following table is a list of the field handler subroutine
|
|
* addresses...
|
|
*
|
|
|
|
handlers DC.W h_pcount ;(w) input.
|
|
DC.W h_ref_num ;(w) input/output.
|
|
DC.W h_pathname ;(ptr) input.
|
|
DC.W h_dev_name ;(ptr) input.
|
|
DC.W h_request_access ;(w) input.
|
|
DC.W h_resource_num ;(w) input.
|
|
DC.W h_data_buffer ;(ptr) input.
|
|
DC.W h_request_count ;(lw) input.
|
|
DC.W h_cache_priority ;(w) input.
|
|
DC.W h_position ;(lw) output.
|
|
DC.W h_base ;(w) input.
|
|
DC.W h_displacement ;(lw) input.
|
|
DC.W h_access ;(w) output.
|
|
DC.W h_file_type ;(w) output.
|
|
DC.W h_aux_type ;(lw) output.
|
|
DC.W h_total_blocks ;(lw) output.
|
|
DC.W h_storage_type ;(w) output.
|
|
DC.W h_create_date ;(w) output.
|
|
DC.W h_create_time ;(w) output.
|
|
DC.W h_mod_date ;(w) output.
|
|
DC.W h_mod_time ;(w) output.
|
|
DC.W h_blocks_used ;(lw) output.
|
|
DC.W h_create_date_time ;(4w) output.
|
|
DC.W h_mod_date_time ;(4w) output.
|
|
DC.W h_option_list ;(ptr) output.
|
|
DC.W h_eof ;(lw) output.
|
|
DC.W h_resource_eof ;(lw) output.
|
|
DC.W h_resource_blocks ;(lw) output.
|
|
DC.W h_vol_name ;(ptr) output.
|
|
DC.W h_free_blocks ;(lw) output.
|
|
DC.W h_file_sys_id ;(w) output.
|
|
DC.W h_block_size ;(w) output.
|
|
DC.W h_transfer_count ;(lw) output.
|
|
DC.W h_entry_num ;(w) output.
|
|
DC.W h_dev_number ;(w) output.
|
|
DC.W h_name ;(ptr) output.
|
|
DC.W h_extended ;(w) output.
|
|
DC.W h_command_num ;(w) input.
|
|
*
|
|
* Storage for process_fields...
|
|
*
|
|
|
|
field_num DS.B 2 ;Field number.
|
|
field_flags DS.B 2 ;Flags word for field.
|
|
field_count DS.B 2 ;Copy of pcount.
|
|
|
|
*
|
|
******************************************************************************
|
|
endr
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: Appl_call
|
|
*
|
|
* Description: Entry point for all application calls. Called by GS/OS only.
|
|
* Validates call before passing control to call handler.
|
|
*
|
|
* Created: Oct 6, 1987
|
|
* Modified: Mar 5, 1991
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jml
|
|
*
|
|
* Input: A = undefined
|
|
* X = call number times 2
|
|
* Y = class number times 2
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
*
|
|
* Exit: jml sys_exit
|
|
*
|
|
* Uses: Everything!
|
|
*
|
|
******************************************************************************
|
|
|
|
appl_call proc
|
|
with data
|
|
|
|
*
|
|
* Setup environment...
|
|
*
|
|
phk ;Setup our bank register.
|
|
plb
|
|
rep #$30 ;Make sure in 16 bit mode.
|
|
|
|
*** added 2-Dec-92 DAL -- Handle to unlock on the way out
|
|
stz current_path_tbl_handle+2
|
|
stz current_path_tbl_handle
|
|
*** end 2-Dec-92
|
|
|
|
*
|
|
* Call # valid?
|
|
*
|
|
cpx #max_call+1 ;In range?
|
|
bcc command_ok ;Yes.
|
|
brl cmd_error ;Nope.
|
|
*
|
|
* Yes, save drvr_cahce and clear id_disk_flag. Call ok?
|
|
*
|
|
command_ok lda drvr_cache ;Get value.
|
|
sta cache_value ;Save it.
|
|
stz id_disk_flag ;Clear flag.
|
|
|
|
phx ;Save x.
|
|
jsr setup_call ;Do setup parameters and validate.
|
|
plx ;Recover x.
|
|
bcs exit ;Bad call.
|
|
*
|
|
* Yes, so jsr to call handler...
|
|
*
|
|
jsr (cmd_tbl-2,x) ;Do call.
|
|
*
|
|
* Unlock memory, set drvr_cache back the way it was and exit...
|
|
*
|
|
exit php ;Save carry.
|
|
pha ;Save error code.
|
|
jsr unlock_mem ;Unlock memory.
|
|
lda cache_value ;Get old value.
|
|
sta drvr_cache ;Set cache value.
|
|
*** added 2-Dec-92 DAL -- Unlock current_path_tbl_handle, if any
|
|
lda current_path_tbl_handle+1 ;check middle word
|
|
beq @that_was_easy
|
|
lda current_path_tbl_handle+2
|
|
pha
|
|
lda current_path_tbl_handle
|
|
pha
|
|
_HUnlock
|
|
@that_was_easy
|
|
*** end 2-Dec-92
|
|
pla ;Recover error code.
|
|
plp ;Recover carry. Error?
|
|
bcs error_exit ;Yep.
|
|
lda #no_error ;No, so get no error code.
|
|
jml sys_exit ;Exit to GS/OS.
|
|
|
|
*
|
|
* We're reporting an error.
|
|
* Before exiting to SCM, put the error priority in the hi byte of the error code.
|
|
*
|
|
error_exit ora error_priority ;put error priority in hi byte
|
|
jml sys_exit ;exit to GS/OS
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: sys_call
|
|
*
|
|
* Description: Entry point for all FST system calls. Called by GS/OS only.
|
|
*
|
|
* Created: Oct 6, 1987
|
|
* Modified: Oct 6, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsl
|
|
*
|
|
* Input: A = undefined
|
|
* X = call number times 2
|
|
* Y = class number times 2
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* Exit: rtl
|
|
*
|
|
* Uses: Everything!
|
|
*
|
|
******************************************************************************
|
|
|
|
system_call proc
|
|
with data
|
|
|
|
*
|
|
* Setup environment...
|
|
*
|
|
phk ;Setup our bank register.
|
|
plb
|
|
*
|
|
* Call # valid?
|
|
*
|
|
cpx #max_sys+1 ;In range?
|
|
bcc valid ;Yep.
|
|
lda #bad_system_call ;Nope, get error code.
|
|
jmp my_sys_exit ;Unlock mem and exit w/carry set.
|
|
*
|
|
* Jump to call handler...
|
|
*
|
|
valid jmp (sys_tbl-2,x) ;Yes, so do it.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: startup
|
|
*
|
|
* Description: Gets a buffer from GIM to be used as a general io buffer, and
|
|
* a buffer for the file_type_map and copies the default map into
|
|
* it. Also initializes log_blk_size and real_log_size.
|
|
*
|
|
* Created: Oct 6, 1987
|
|
* Modified: Mar 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jmp
|
|
*
|
|
* Input: A = undefined
|
|
* X = call number times 2
|
|
* Y = class number times 2
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
*
|
|
* io_buffer_vp ;vp for io_buffer.
|
|
* map_buffer_vp ;vp for map_buffer.
|
|
*
|
|
* Exit: rtl
|
|
*
|
|
* Uses: io_buffer_vp
|
|
* map_buffer_vp
|
|
* temp1
|
|
* log_blk_size
|
|
* real_log_size
|
|
* alloc_seg (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
startup proc
|
|
with data
|
|
|
|
*
|
|
* Get memory for io_buffer and save vp...
|
|
*
|
|
lda #Sector_size ;Get size of sector.
|
|
jsr alloc_seg ;Get a hunk that size.
|
|
lda #out_of_mem ;Get error code in case full.
|
|
bcs exit ;Error, so exit with carry set.
|
|
|
|
stx io_buffer_vp ;Save it.
|
|
sty io_buffer_vp+2
|
|
*
|
|
* Get memory for map_buffer and save vp...
|
|
*
|
|
lda default_map ;Get size from default_map.
|
|
jsr alloc_seg ;Get a hunk that size.
|
|
lda #out_of_mem ;Get error code in case full.
|
|
bcs exit ;Error, so exit with carry set.
|
|
|
|
stx map_buffer_vp ;Save it.
|
|
sty map_buffer_vp+2
|
|
*
|
|
* Copy default map into map buffer...
|
|
*
|
|
jsl deref ;Dereference vp.
|
|
stx map_ptr ;Save pointer.
|
|
sty map_ptr+2
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
ldy default_map ;Get map size.
|
|
copy_loop dey ;Done all?
|
|
bmi restore_a ;Yep.
|
|
lda default_map,y ;Nope, get byte.
|
|
sta [map_ptr],y ;Put it in buffer.
|
|
bra copy_loop ;And loop.
|
|
|
|
longa on ;Restore 16 bit A.
|
|
restore_a rep #$20
|
|
*
|
|
* Initialize log_blk_size and real_log_size...
|
|
*
|
|
lda #sector_size ;Get sector size (2k).
|
|
sta log_blk_size ;Init log_blk_size.
|
|
sta real_log_size ;Init real_log_size.
|
|
*
|
|
* Exit with no error...
|
|
*
|
|
clc ;Exit with no error.
|
|
exit rtl
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: shutdown
|
|
*
|
|
* Description: Releases 2k io_buffer and unlocks memory.
|
|
*
|
|
* Created: Oct 6, 1987
|
|
* Modified: Oct 6, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jmp
|
|
*
|
|
* Input: A = undefined
|
|
* X = call number times 2
|
|
* Y = class number times 2
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
*
|
|
* Exit: rtl
|
|
*
|
|
* Uses: io_buffer_vp
|
|
*
|
|
******************************************************************************
|
|
|
|
shutdown proc
|
|
with data
|
|
|
|
*
|
|
* Are we doing a warm shutdown? Do nothing if so...
|
|
*
|
|
clc ;Precondition to no error.
|
|
lda >warm_cold_flag ;Get flag. Warm shutdown?
|
|
bne exit ;Yes, so do nothing.
|
|
*
|
|
* Release memory...
|
|
*
|
|
ldx io_buffer_vp ;Get virtual pointer.
|
|
ldy io_buffer_vp+2
|
|
jsr release_seg ;Free it up.
|
|
*
|
|
* Unlock memory and exit...
|
|
*
|
|
entry my_sys_exit
|
|
my_sys_exit ;
|
|
php ;Save carry.
|
|
pha ;Save error code.
|
|
jsr unlock_mem ;Unlock memory.
|
|
pla ;Recover error code.
|
|
plp ;Recover carry.
|
|
exit rtl ;Pass any errors back to Mike & Jim.
|
|
|
|
ENDP
|
|
|
|
*** added 2-Dec-92 DAL -- modeled after HFS FST
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: kill_vcr
|
|
*
|
|
* Description: This routine is called by SCM when a VCR is being released.
|
|
*
|
|
* Entry: jmp
|
|
*
|
|
* Input: A = undefined
|
|
* X = call number times 2
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K (??? I don't think so --DAL)
|
|
*
|
|
* <vcr_ptr - ptr to vcr
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Exit: rtl
|
|
*
|
|
* Uses: all registers
|
|
*
|
|
* Called by: sys_entry
|
|
*
|
|
* Calls: DisposeHandle (Memory Manager)
|
|
*
|
|
******************************************************************************
|
|
|
|
kill_vcr PROC
|
|
with data
|
|
|
|
phk
|
|
plb ;SCM assumes we munge DBR
|
|
*
|
|
* Dispose of the Path Table Handle, if any
|
|
*
|
|
ldy #vcr_path_tbl_handle+1 ;check middle word ($0000=no handle)
|
|
lda [vcr_ptr],y
|
|
clc ;anticipate no error
|
|
beq done
|
|
|
|
ldy #vcr_path_tbl_handle+2 ;get offset path table handle, high word
|
|
lda [vcr_ptr],y
|
|
pha
|
|
dey
|
|
dey
|
|
lda [vcr_ptr],y ;get low word of handle
|
|
pha
|
|
_DisposeHandle
|
|
|
|
*
|
|
* If we just disposed of our current_path_tbl_handle, zero it out so we
|
|
* don't accidentally try to unlock it again.
|
|
*
|
|
php
|
|
pha
|
|
|
|
ldy #vcr_path_tbl_handle+2
|
|
lda [vcr_ptr],y
|
|
cmp current_path_tbl_handle+2
|
|
bne @not_same
|
|
dey
|
|
dey
|
|
lda [vcr_ptr],y
|
|
cmp current_path_tbl_handle
|
|
bne @not_same
|
|
|
|
stz current_path_tbl_handle+2
|
|
stz current_path_tbl_handle
|
|
|
|
@not_same pla
|
|
plp
|
|
|
|
done rtl ;return any errors to SCM
|
|
|
|
EndP
|
|
*** end 2-Dec-92
|
|
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* HERE ARE THE EASY-TO-HANDLE APPLICATION & SYSTEM CALLS
|
|
*
|
|
******************************************************************************
|
|
|
|
easy_calls proc
|
|
with data
|
|
|
|
export INVALID_OP
|
|
invalid_op ;
|
|
lda #invalid_fst_op ;Get invalid op error.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
export CMD_ERROR
|
|
cmd_error ;
|
|
lda #bad_system_call ;Get bad call error.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
export NOP
|
|
nop ;
|
|
clc ;Indicate no error.
|
|
rts ;Exit.
|
|
|
|
export WP_ERROR
|
|
wp_error ;
|
|
lda #drvr_wr_prot ;Get write-protect error.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
export CLC_RTL
|
|
clc_rtl ;
|
|
clc ;Indicate no error.
|
|
rtl ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: setup_call
|
|
*
|
|
* Description: This routine is called at the start of each system call to
|
|
* setup parameters and check the validity of the call. If a
|
|
* VCR is used by the call and the media is swapped out, the
|
|
* system mount routine will be called.
|
|
*
|
|
* Also locks down all GS/OS managed memory.
|
|
*
|
|
* Created: Oct 6, 1987
|
|
* Modified: Mar 5, 1991
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = two times the call #.
|
|
* Y = two times the class #.
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = class of call, or error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 if no error.
|
|
* 1 if error
|
|
* B = K
|
|
*
|
|
* call call number.
|
|
* class call class.
|
|
* trans_call translated call #.
|
|
* io_buffer points to 2k buffer.
|
|
* my_pblk points past to 1st param.
|
|
* my_vcr points to vcr, if used, else 00.
|
|
* path_table points to path table (if vcr used)
|
|
* log_blk_size size of block (if vcr used)
|
|
* real_log_size same as log_blk_size
|
|
* path_table_size size of path table (if vcr used)
|
|
* my_fcr points to fcr (if used).
|
|
* pcount pcount for call (0 if class 0).
|
|
* ref_num file reference number (if present).
|
|
* path_ptr pointer to pathname (if present).
|
|
* volume_name holds volume name (if pathname present).
|
|
* file_name holds file name (if pathname present).
|
|
* name_count # of names in pathname (if pathname present).
|
|
* name_offsets offsets to names in pathname (if present).
|
|
* dev_name pointer to device name (if present).
|
|
* request_access access permissions (if present).
|
|
* resource_num resource number (if present).
|
|
* data_buffer pointer to users data buffer (if present).
|
|
* request_count read count (if present).
|
|
* cache_priority cache value (if present, 0 if not).
|
|
* position file mark (if present).
|
|
* base base flag (if present).
|
|
* displacement displacement (if present).
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: flags
|
|
* max_pcount
|
|
* min_pcount
|
|
* all storage above
|
|
* get_input (sub)
|
|
* parse_path (sub)
|
|
* mount_volume (sub)
|
|
*
|
|
* Each call has a one word entry in the table with the following
|
|
* format:
|
|
*
|
|
* 1 - Max PCount for the call
|
|
* 2 - Min PCount for the call
|
|
* 3 - Pathnames used by call
|
|
* 4 - Volume control record used
|
|
* 5 - File control record used
|
|
*
|
|
* |5|4|3| 2 | 1 |
|
|
* _________|_|_|_|_____|_________|
|
|
* | | | | | | | | | | | | | | | | |
|
|
* |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|
|
* | | |
|
|
* 1 6 0 8 0 0
|
|
*
|
|
******************************************************************************
|
|
|
|
setup_call proc
|
|
with data
|
|
|
|
*
|
|
* Init some variables...
|
|
*
|
|
stz input_error ;Clear error.
|
|
stz name_count ;Clear it.
|
|
stz base ;Clear it.
|
|
stz interleave_size ;Clear it.
|
|
stz interleave_skip ;Clear it.
|
|
stz error_priority ;error priority is 0
|
|
*
|
|
* Set call and class...
|
|
*
|
|
txa ;Divide call # by 2.
|
|
lsr a
|
|
sta call ;Set current call.
|
|
|
|
tya ;Divide class # by 2.
|
|
lsr a
|
|
sta class ;Set current class.
|
|
*
|
|
* Is class valid?
|
|
*
|
|
cmp #max_class ;Valid?
|
|
beq class_ok ;Yep.
|
|
bcc class_ok ;Yep.
|
|
*
|
|
* No, so exit with invalid_class error...
|
|
*
|
|
lda #invalid_class ;Nope, so get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Yes, get translated call #. Exit if this is not a call I handle...
|
|
*
|
|
class_ok ldy #call_count ;Point to end of list.
|
|
call_loop lda handled_calls,y ;Get call #.
|
|
and #$00ff ;Clear high byte.
|
|
cmp call ;Is this the call?
|
|
beq valid_call ;Yep.
|
|
dey ;Nope, checked all?
|
|
bpl call_loop ;No, so loop.
|
|
clc ;Yes, so exit with carry clear.
|
|
rts
|
|
|
|
valid_call tya ;Get call #.
|
|
asl a ;Multiply by 2.
|
|
sta trans_call ;Save it.
|
|
tax ;Put in X.
|
|
*
|
|
* Get entry from start_flags and save it in flags.
|
|
*
|
|
lda start_flags,x ;Get flags word.
|
|
sta flags ;Save it.
|
|
*
|
|
* Set max_pcount and min_pcount...
|
|
*
|
|
and #max_mask ;Isolate max_pcount.
|
|
sta max_pcount ;Save it.
|
|
|
|
lda flags ;Get flags.
|
|
and #min_mask ;Isolate min_pcount.
|
|
asl a ;Get it in low byte.
|
|
asl a
|
|
asl a
|
|
xba
|
|
sta min_pcount ;Save it.
|
|
*
|
|
* Set my_pblk = param_blk_ptr...
|
|
*
|
|
lda param_blk_ptr ;Copy to my_pblk.
|
|
sta my_pblk
|
|
lda param_blk_ptr+2
|
|
sta my_pblk+2
|
|
*
|
|
* Get input parameters. Any Errors?
|
|
*
|
|
jsr get_input ;Get input. Any errors?
|
|
bcc input_ok ;Nope.
|
|
*
|
|
* Yep. If this call does not use a pathname, then exit with the error.
|
|
* If it does, check to see if it is a bouncing error and if so, exit with
|
|
* the error. If not, save error in input_error and continue...
|
|
*
|
|
tax ;Save error code.
|
|
lda flags ;Path used by call?
|
|
and #path_used
|
|
beq send_error ;Nope.
|
|
|
|
ldy #len_bounce_tbl ;Yes, is it a bouncing error?
|
|
txa
|
|
bounce_loop cmp bounce_errors,y
|
|
beq send_error ;Yep.
|
|
dey
|
|
dey
|
|
bpl bounce_loop
|
|
|
|
stx input_error ;Nope, save error.
|
|
bra input_ok ;And continue.
|
|
|
|
send_error txa ;Recover error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Nope, get pointer to io_buffer and map_buffer, and lock memory...
|
|
*
|
|
input_ok ldx io_buffer_vp ;Get vp.
|
|
ldy io_buffer_vp+2
|
|
jsl deref ;Dereference it.
|
|
stx io_buffer ;Save pointer.
|
|
sty io_buffer+2
|
|
|
|
ldx map_buffer_vp ;Get vp.
|
|
ldy map_buffer_vp+2
|
|
jsl deref ;Dereference it.
|
|
stx map_buffer_ptr ;Save pointer.
|
|
sty map_buffer_ptr+2
|
|
|
|
jsl lock_mem ;Lock all memory.
|
|
*
|
|
* Do we need a VCR?
|
|
*
|
|
stz my_vcr ;Clear my_vcr in case don't need it.
|
|
stz my_vcr+2
|
|
lda flags ;Get flags.
|
|
and #vcr_used ;Need a vcr?
|
|
beq check_fcr ;Nope.
|
|
*
|
|
* Yes, so setup pointer to vcr and call setup_vcr...
|
|
*
|
|
ldx vcr_ptr ;Get VP from zp.
|
|
ldy vcr_ptr+2
|
|
jsl deref ;Dereference it.
|
|
stx my_vcr ;Save pointer.
|
|
sty my_vcr+2
|
|
|
|
jsr setup_vcr ;Get some of the vcr variables.
|
|
*
|
|
* Do we need a FCR?
|
|
*
|
|
check_fcr lda flags ;Get flags.
|
|
and #fcr_used ;Need a vcr?
|
|
beq check_path ;Nope.
|
|
*
|
|
* Yes, setup pointer to fcr...
|
|
*
|
|
ldx fcr_ptr ;Get VP from zp.
|
|
ldy fcr_ptr+2
|
|
jsl deref ;Dereference it.
|
|
stx my_fcr ;Save pointer.
|
|
sty my_fcr+2
|
|
*
|
|
* Do we need a pathname?
|
|
*
|
|
check_path lda flags ;Get flags.
|
|
and #path_used ;Need a pathname?
|
|
bne need_path ;Yes.
|
|
*
|
|
* Nope, so exit with carry clear...
|
|
*
|
|
clc ;Indicate no error.
|
|
rts ;exit.
|
|
*
|
|
* Yes, exit through parse_path...
|
|
*
|
|
need_path jmp parse_path ;Parse pathname.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: activate_vcr
|
|
*
|
|
* Description: Marks vcr as active, gets new log_blk_size and real_log_size,
|
|
* sets pointer to the path table and gets the size of the path
|
|
* table. Also sets state_flag and calls set_file_system.
|
|
*
|
|
* NOTE: Contains an alternate entry point!
|
|
*
|
|
* Created: Oct 21, 1987
|
|
* Modified: Mar 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined.
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr points to current vcr.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* log_blk_size ;size of blocks on this volume
|
|
* real_log_size ;copy of log_blk_size
|
|
* path_table_size ;size of path table
|
|
* path_table ;pointer to path table
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* set_file_system (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
activate_vcr proc
|
|
with data
|
|
|
|
*
|
|
* Mark vcr as active...
|
|
*
|
|
ldy #vcr_status ;Get offset to status.
|
|
lda [my_vcr],y ;Get status.
|
|
and #vcr_swapped_in ;Clear swapped bit.
|
|
sta [my_vcr],y ;Save it.
|
|
*
|
|
* Set new log_blk_size and real_log_size ...
|
|
*
|
|
export SETUP_VCR
|
|
setup_vcr ;
|
|
|
|
ldy #vcr_block_size ;Get offset to block size.
|
|
lda [my_vcr],y ;Get size.
|
|
sta log_blk_size ;Set logical block size.
|
|
sta real_log_size ;Set real logical block size.
|
|
*
|
|
* Set path_table_size...
|
|
*
|
|
ldy #vcr_path_size ;Get offset to path table size.
|
|
lda [my_vcr],y ;Get size.
|
|
sta path_table_size ;Set new size.
|
|
*
|
|
* Make a pointer to path table...
|
|
*
|
|
*** changed 2-Dec-92 DAL
|
|
; clc ;Add offset to path table.
|
|
; lda #vcr_path_table
|
|
; adc my_vcr
|
|
; sta path_table
|
|
; lda #0
|
|
; adc my_vcr+2
|
|
; sta path_table+2
|
|
|
|
; use path_ptr as temporary direct page (restore when done)
|
|
pei <path_ptr+2
|
|
pei <path_ptr
|
|
|
|
ldy #vcr_path_tbl_handle+2
|
|
lda [my_vcr],y
|
|
sta current_path_tbl_handle+2
|
|
sta <path_ptr+2
|
|
dey
|
|
dey
|
|
lda [my_vcr],y
|
|
sta current_path_tbl_handle
|
|
sta <path_ptr
|
|
ldy #4
|
|
lda [<path_ptr],y
|
|
ora #$8000 ;brutally lock the handle
|
|
sta [<path_ptr],y
|
|
dey
|
|
dey
|
|
lda [<path_ptr],y
|
|
sta path_table+2
|
|
lda [<path_ptr]
|
|
sta path_table
|
|
|
|
pla
|
|
sta <path_ptr
|
|
pla
|
|
sta <path_ptr+2
|
|
*** end 2-Dec-92
|
|
|
|
*
|
|
* Copy vcr_state_flag to state_flag and exit thru set_file_system...
|
|
*
|
|
ldy #vcr_state_flag ;Get offset to flag.
|
|
lda [my_vcr],y ;Get flag.
|
|
sta state_flag ;Save flag.
|
|
jmp set_file_system ;Exit thru set_file_system.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_input
|
|
*
|
|
* Description: Moves input parameters from callers parameter list to my
|
|
* storage area. Validates the parameters whose range is known.
|
|
* All fields which are not defined for the call will be zero.
|
|
*
|
|
* Created: Oct 14, 1987
|
|
* Modified: Oct 14, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined.
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* class contains class #.
|
|
* trans_call contains translated call #.
|
|
*
|
|
* Output: A = undefined, or error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 if no error.
|
|
* 1 if error
|
|
* B = K
|
|
*
|
|
* pcount pcount for call (0 if class 0).
|
|
* ref_num file reference number (if present).
|
|
* pathname pointer to pathname (if present).
|
|
* dev_name pointer to device name (if present).
|
|
* request_access access permissions (if present).
|
|
* resource_num resource number (if present).
|
|
* data_buffer pointer to users data buffer (if present).
|
|
* request_count read count (if present).
|
|
* cache_priority cache value (if present, 0 if not).
|
|
* position file mark (if present).
|
|
* base base flag (if present).
|
|
* displacement displacement (if present).
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* process_fields
|
|
*
|
|
******************************************************************************
|
|
|
|
get_input proc
|
|
with data
|
|
|
|
*
|
|
* Clear input variables...
|
|
*
|
|
ldy #input_len ;Point to last variable.
|
|
lda #0 ;Get zero.
|
|
clear_loop sta pcount,y ;Clear variable.
|
|
dey ;Done all?
|
|
dey
|
|
bpl clear_loop ;No, so loop.
|
|
*
|
|
* Initialize pcount to maximum value in case this is a class 0 call
|
|
* (see process_fields for more info)...
|
|
*
|
|
lda #$7fff ;Get max value.
|
|
sta pcount ;Set pcount.
|
|
*
|
|
* Process input fields and exit...
|
|
*
|
|
lda #input ;Select input.
|
|
jmp process_fields ;Process fields.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: send_output
|
|
*
|
|
* Description: Sends output fields to callers parameter list.
|
|
*
|
|
* Created: Oct 15, 1987
|
|
* Modified: Oct 15, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined.
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* pcount
|
|
* class
|
|
* trans_call
|
|
*
|
|
* Output: A = undefined, or error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 if no error.
|
|
* 1 if error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* process_fields
|
|
*
|
|
******************************************************************************
|
|
|
|
send_output proc
|
|
with data
|
|
|
|
*
|
|
* Process output fields and exit...
|
|
*
|
|
lda #output ;Select output.
|
|
jmp process_fields ;Process 'em.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: process_fields
|
|
*
|
|
* Description: This routine calls all of the field handler subroutines listed
|
|
* in the field list for the current call and class.
|
|
*
|
|
* Created: Oct 14, 1987
|
|
* Modified: Oct 14, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = 0 if requesting input, $4000 if requesting output.
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* class
|
|
* trans_call
|
|
* pcount ;must be initialized > max pcount!
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 if no error.
|
|
* 1 if error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* list_ptr
|
|
* io_flag
|
|
* field_count
|
|
* field_num
|
|
* field_flags
|
|
*
|
|
* The field list is a list of field flags words which have the
|
|
* following format:
|
|
*
|
|
* 1 - Field number times two
|
|
* 2 - Field offset
|
|
* 3 - I/O flag: 0 = input, 1 = output.
|
|
* 4 - Terminator: 1 = last entry in list.
|
|
*
|
|
* |4|3| 2 | 1 |
|
|
* |_|_|___________|_______________|
|
|
* | | | | | | | | | | | | | | | | |
|
|
* |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|
|
* | | |
|
|
* 1 6 0 8 0 0
|
|
*
|
|
******************************************************************************
|
|
|
|
process_fields proc
|
|
with data
|
|
|
|
*
|
|
* Save requested direction and set list_ptr to point to correct list...
|
|
*
|
|
sta io_flag ;Save direction flag.
|
|
ldx trans_call ;Get translated call #.
|
|
lda class0,x ;Get class 0 address.
|
|
ldy class ;Is this a class 0 call?
|
|
beq set_ptr ;Yep.
|
|
lda class1,x ;Nope, so get class 1 address.
|
|
set_ptr sta list_ptr ;Set pointer.
|
|
*
|
|
* Set field_count = pcount. Pcount must be initialized at call start
|
|
* way out of range in case this is a class 0 call (if it's a class 1 call,
|
|
* the pcount field handler will set field_count equal to pcount).
|
|
* Field_count is used to control the number of fields to process...
|
|
*
|
|
lda pcount ;Copy pcount to field_count.
|
|
sta field_count
|
|
*
|
|
* Init field number...
|
|
*
|
|
lets_go ldy #0 ;Init offset.
|
|
*
|
|
* Save field number, get field flags and save it...
|
|
*
|
|
input_loop sty field_num ;Save field number.
|
|
lda (list_ptr),y ;Get field flags.
|
|
sta field_flags ;Save it.
|
|
*
|
|
* Does the i/o flag match the requested direction?
|
|
*
|
|
and #io_mask ;Isolate flag.
|
|
cmp io_flag ;Does it match request?
|
|
bne next_field ;Nope, so skip it.
|
|
*
|
|
* Yes, get field offset in Y and jsr to selected field handler...
|
|
*
|
|
lda field_flags ;Recover flags.
|
|
and #offset_mask ;Isolate offset.
|
|
xba ;Put in low byte.
|
|
tay ;Put in Y.
|
|
lda field_flags ;Recover flags.
|
|
and #field_mask ;Isolate field.
|
|
tax ;Use as index.
|
|
jsr (handlers,x) ;Execute handler.
|
|
bcs exit ;Error, so exit.
|
|
*
|
|
* Bump field number...
|
|
*
|
|
next_field ldy field_num ;Get field number.
|
|
iny ;Bump it.
|
|
iny
|
|
*
|
|
* Are we done with list?
|
|
*
|
|
lda field_flags ;Done with list?
|
|
bmi done ;Yes.
|
|
*
|
|
* Nope, have we used up all the fields present?
|
|
*
|
|
dec field_count ;Done all fields?
|
|
bpl input_loop ;Nope, so loop.
|
|
*
|
|
* Yes, so exit with carry clear...
|
|
*
|
|
done clc ;Indicate no errors.
|
|
exit rts ;Exit to caller.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: field_handlers
|
|
*
|
|
* Description: This section is a collection of subroutines which handle
|
|
* each of the fields in the parameter lists. These routines
|
|
* should only be called by process_fields...
|
|
*
|
|
* Note: The h_vol_name routine is called directly from the "volume"
|
|
* procedure if id_disk has returned a dup_volume error. This is
|
|
* done so that the "vol_name" output parameter will be set up even
|
|
* though an error is being returned. This is the only case in
|
|
* which a parameter handler is called directly. 2/7/91 CAE
|
|
*
|
|
* Created: Oct 14, 1987
|
|
* Modified: June 30, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* io_flag
|
|
* trans_call
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 if no error.
|
|
* 1 if error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
*
|
|
******************************************************************************
|
|
|
|
field_handlers proc
|
|
with data
|
|
|
|
*
|
|
* PCOUNT Field Handler: Input (w)
|
|
*
|
|
export H_PCOUNT
|
|
h_pcount ;
|
|
|
|
lda [my_pblk],y ;Get pcount.
|
|
cmp max_pcount ;< max?
|
|
bcs bad_pcount ;No, so bad.
|
|
cmp min_pcount ;>= min?
|
|
bcc bad_pcount ;No, so bad.
|
|
sta pcount ;Yep, so save it.
|
|
sta field_count ;Set count as well.
|
|
clc ;Indicate no error.
|
|
rts ;Exit.
|
|
|
|
bad_pcount lda #invalid_pcount ;No, get error code.
|
|
sec ;Set carry.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* REF_NUM Field Handler: Input/Output (w)
|
|
*
|
|
export H_REF_NUM
|
|
h_ref_num ;
|
|
|
|
lda field_flags ;Get flags word.
|
|
and #io_mask ;Is input?
|
|
bne ref_out ;Nope.
|
|
lda [my_pblk],y ;Yes, get word.
|
|
sta ref_num ;Set parameter.
|
|
bra ref_exit ;Exit.
|
|
|
|
ref_out lda ref_num ;Get reference number.
|
|
sta [my_pblk],y ;Send it.
|
|
|
|
ref_exit clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* PATHNAME Field Handler: Input (ptr)
|
|
*
|
|
export H_PATHNAME
|
|
h_pathname ;
|
|
clc ;Do nothing.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* DEV_NAME Field Handler: Input (ptr)
|
|
*
|
|
export H_DEV_NAME
|
|
h_dev_name ;
|
|
|
|
clc ;Do nothing.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* REQUEST_ACCESS Field Handler: Input (w)
|
|
*
|
|
export H_REQUEST_ACCESS
|
|
h_request_access ;
|
|
|
|
lda [my_pblk],y ;Get word.
|
|
beq access_ok ;Zero, so ok.
|
|
cmp #read_access ;Is read only?
|
|
bne access_bad ;Nope, so bad.
|
|
access_ok clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
access_bad lda #invalid_access ;No, so error.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* RESOURCE_NUM Field Handler: Input (w)
|
|
*
|
|
export H_RESOURCE_NUM
|
|
h_resource_num ;
|
|
|
|
lda [my_pblk],y ;Get word.
|
|
sta resource_num ;Save it.
|
|
clc ;No error.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* DATA_BUFFER Field Handler: Input (ptr)
|
|
*
|
|
export H_DATA_BUFFER
|
|
h_data_buffer ;
|
|
|
|
lda [my_pblk],y ;Get low word of ptr.
|
|
sta data_buffer ;Save it.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [my_pblk],y ;Get high word of ptr.
|
|
and #$00ff ;Clear high byte.
|
|
sta data_buffer+2 ;Save it.
|
|
clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* REQUEST_COUNT Field Handler: Input (lw)
|
|
*
|
|
export H_REQUEST_COUNT
|
|
h_request_count ;
|
|
|
|
lda [my_pblk],y ;Get low word of count.
|
|
sta request_count ;Save it.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [my_pblk],y ;Get high word of count.
|
|
sta request_count+2 ;Save it.
|
|
clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* CACHE_PRIORITY Field Handler: Input (w)
|
|
*
|
|
export H_CACHE_PRIORITY
|
|
h_cache_priority ;
|
|
|
|
lda [my_pblk],y ;Get word.
|
|
beq good_priority ;Ok.
|
|
cmp #user_cache_val ;Valid priority?
|
|
bne bad_priority ;Nope.
|
|
good_priority sta cache_priority ;Save it.
|
|
clc ;No error.
|
|
rts ;Exit.
|
|
|
|
bad_priority lda #parm_range_err ;Get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* POSITION Field Handler: Output (lw)
|
|
*
|
|
export H_POSITION
|
|
h_position ;
|
|
|
|
lda position ;Get low word.
|
|
ldx position+2 ;Get high word.
|
|
brl send_long_word ;Send it.
|
|
|
|
*
|
|
* BASE Field Handler: Input (w)
|
|
*
|
|
export H_BASE
|
|
h_base ;
|
|
|
|
lda [my_pblk],y ;Get word.
|
|
cmp #max_base+1 ;In range?
|
|
bcs bad_base ;Nope.
|
|
sta base ;Yes, save it.
|
|
rts ;Exit.
|
|
|
|
bad_base lda #parm_range_err ;Get error code.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* DISPLACEMENT Field Handler: Input (lw)
|
|
*
|
|
export H_DISPLACEMENT
|
|
h_displacement ;
|
|
|
|
lda [my_pblk],y ;Get low word.
|
|
sta displacement ;Save it.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [my_pblk],y ;Get high word.
|
|
sta displacement+2 ;Save it.
|
|
clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* ACCESS Field Handler: Output (w)
|
|
*
|
|
export H_ACCESS
|
|
h_access ;
|
|
|
|
ldx dir_file_flags ;Get offset to file flags.
|
|
lda dir_record_0,x ;Get flags.
|
|
and #1 ;Isolate existence bit.
|
|
asl a ;Shift it to invisible pos.
|
|
asl a
|
|
ora #full_access ;Add full access bits.
|
|
brl send_word ;Send it.
|
|
|
|
*
|
|
* FILE_TYPE Field Handler: Output (w)
|
|
*
|
|
export H_FILE_TYPE
|
|
h_file_type ;
|
|
|
|
ldx dir_file_flags ;Get offset to file flags.
|
|
lda dir_record_0,x ;Get flags.
|
|
ldx #file_type_dir ;Init file type to directory.
|
|
and #dir_mask ;Is it a directory?
|
|
bne send_hop ;Yes.
|
|
jsr get_ext_type ;Nope, do we have Apple Extensions info?
|
|
bcc send_hop ;Yep.
|
|
jsr get_file_type ;Nope, use map.
|
|
send_hop txa ;Put type in A.
|
|
brl send_word ;Send it.
|
|
|
|
*
|
|
* AUX_TYPE Field Handler: Output (lw)
|
|
*
|
|
export H_AUX_TYPE
|
|
h_aux_type ;
|
|
|
|
lda call ;Yes. Is this a get_file_info call?
|
|
cmp #get_file_call
|
|
bne check_apple ;Nope.
|
|
lda storage_type ;Yes, looking at volume directory?
|
|
cmp #type_vol_dir
|
|
bne check_apple ;Nope.
|
|
lda class ;Yes, is it a class zero call?
|
|
beq h_total_blocks ;Yes, so send total blocks.
|
|
send_zero brl h_free_blocks ;Nope, send zero long word.
|
|
|
|
check_apple jsr get_ext_type ;Do we have Apple Extensions info?
|
|
bcs send_zero ;Nope.
|
|
ldx #0000 ;Yep, clear high word.
|
|
brl send_long_word ;Send it.
|
|
|
|
|
|
*
|
|
* TOTAL_BLOCKS Field Handler: Output (lw)
|
|
*
|
|
export H_TOTAL_BLOCKS
|
|
h_total_blocks ;
|
|
|
|
phy ;Save offset.
|
|
ldy #vcr_total_blks+2 ;Get offset to high word.
|
|
lda [my_vcr],y ;Get high word.
|
|
tax ;Save it.
|
|
ldy #vcr_total_blks ;Get offset to low word.
|
|
lda [my_vcr],y ;Get low word.
|
|
ply ;Recover offset.
|
|
brl send_long_word ;Send it.
|
|
|
|
*
|
|
* STORAGE_TYPE Field Handler: Output (w)
|
|
*
|
|
export H_STORAGE_TYPE
|
|
h_storage_type ;
|
|
|
|
lda storage_type ;Get type.
|
|
brl send_word ;Send it.
|
|
|
|
*
|
|
* CREATE_DATE Field Handler: Output (w)
|
|
*
|
|
* NOTE: This must be called before mod_date, or mod_time
|
|
* so that the call to pro_date_time will occur!
|
|
*
|
|
export H_CREATE_DATE
|
|
h_create_date ;
|
|
|
|
phy ;Save offset.
|
|
jsr pro_date_time ;Get date & time.
|
|
ply ;Recover offset.
|
|
*
|
|
* MOD_DATE Field Handler: Output (w)
|
|
*
|
|
export H_MOD_DATE
|
|
h_mod_date ;
|
|
|
|
lda prodos_time ;Get year/mon/day
|
|
brl send_word ;Send it.
|
|
|
|
*
|
|
* CREATE_TIME Field Handler: Output (w)
|
|
* MOD_TIME Field Handler: Output (w)
|
|
*
|
|
export H_CREATE_TIME
|
|
h_create_time ;
|
|
export H_MOD_TIME
|
|
h_mod_time ;
|
|
|
|
lda prodos_time+2 ;Get hour/minute.
|
|
brl send_word ;Send it.
|
|
|
|
*
|
|
* BLOCKS_USED Field Handler: Output (lw)
|
|
*
|
|
export H_BLOCKS_USED
|
|
h_blocks_used ;
|
|
|
|
lda call ;Is this a get_dir_entry call?
|
|
cmp #get_dir_call
|
|
beq send_used ;Yes, so send blocks_used.
|
|
|
|
ldx storage_type ;Nope, is this a directory?
|
|
cpx #type_extended+1
|
|
bcc send_used ;Nope, so send blocks_used.
|
|
|
|
cmp #get_file_call ;Yes, is it a get_file_info call?
|
|
bne send_zero ;Nope, so this field undefined.
|
|
|
|
lda class ;Yes, is it a class zero call?
|
|
bne send_zero ;Nope, so this field undefined.
|
|
|
|
cpx #type_vol_dir ;Yes, is this the volume directory?
|
|
bne send_used ;Nope, so send blocks_used.
|
|
bra h_total_blocks ;Yes, so return total_blocks.
|
|
|
|
send_used lda blocks_used ;Get low word.
|
|
ldx blocks_used+2 ;Get high word.
|
|
bra send_long_word ;Send it.
|
|
|
|
*
|
|
* CREATE_DATE_TIME Field Handler: Output (4w)
|
|
* MOD_DATE_TIME Field Handler: Output (4w)
|
|
*
|
|
export H_CREATE_DATE_TIME
|
|
h_create_date_time ;
|
|
export H_MOD_DATE_TIME
|
|
h_mod_date_time ;
|
|
|
|
phy ;Save offset.
|
|
jsr get_date_time ;Get date & time.
|
|
ply ;Recover offset.
|
|
|
|
ldx #0 ;Init offset.
|
|
time_loop lda create_date_time,x ;Get word.
|
|
sta [my_pblk],y ;Send it.
|
|
iny ;Bump offsets.
|
|
iny
|
|
inx
|
|
inx
|
|
cpx #8 ;Done all?
|
|
bne time_loop ;No, so loop.
|
|
|
|
clc ;Yes, so clear carry.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* OPTION_LIST Field Handler: Output (ptr)
|
|
*
|
|
export H_OPTION_LIST
|
|
h_option_list ;
|
|
|
|
lda [my_pblk],y ;Get low word of pointer.
|
|
tax ;Save it.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [my_pblk],y ;Get high byte of pointer.
|
|
and #$00ff ;Clear high byte.
|
|
jmp get_option_list ;Go get it.
|
|
|
|
*
|
|
* EOF Field Handler: Output (lw)
|
|
*
|
|
export H_EOF
|
|
h_eof ;
|
|
|
|
lda eof ;Get low word.
|
|
ldx eof+2 ;Get high word.
|
|
bra send_long_word ;Send it.
|
|
|
|
*
|
|
* RESOURCE_EOF Field Handler: Output (lw)
|
|
*
|
|
export H_RESOURCE_EOF
|
|
h_resource_eof ;
|
|
|
|
lda resource_eof ;Get low word.
|
|
ldx resource_eof+2 ;Get high word.
|
|
bra send_long_word ;Send it.
|
|
|
|
*
|
|
* RESOURCE_BLOCKS Field Handler: Output (lw)
|
|
*
|
|
export H_RESOURCE_BLOCKS
|
|
h_resource_blocks ;
|
|
|
|
lda resource_blocks ;Get low word.
|
|
ldx resource_blocks+2 ;Get high word.
|
|
bra send_long_word ;Send it.
|
|
|
|
*
|
|
* VOL_NAME Field Handler: Output (ptr)
|
|
*
|
|
export H_VOL_NAME
|
|
h_vol_name ;
|
|
|
|
phy ;Save offset.
|
|
lda #$2e5f ;Replace underscores with periods.
|
|
ldx #gstring
|
|
ldy #^gstring
|
|
jsr transform_name
|
|
ldx #gstring ;Point to volume name.
|
|
ldy #^gstring
|
|
jsr add_separator ;Add separator.
|
|
ply ;Recover offset.
|
|
lda class ;Is this a class 0 call?
|
|
bne send_name ;Nope.
|
|
lda gstring ;Yep, get length.
|
|
cmp #prodos_name_ln ;Legal length?
|
|
bcc send_name ;Yep.
|
|
lda #drvr_off_line ;Nope, return offline error.
|
|
rts ;Exit.
|
|
|
|
send_name ;
|
|
|
|
lda [my_pblk],y ;Get low word of pointer.
|
|
sta output_string ;Set low word.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [my_pblk],y ;Get high word of pointer.
|
|
and #$00ff ;Clear high byte.
|
|
sta output_string+2 ;Set high word.
|
|
|
|
ldx #gstring ;Point to volume name.
|
|
ldy #^gstring
|
|
jmp send_gstring ;Send it out.
|
|
|
|
*
|
|
* FREE_BLOCKS Field Handler: Output (lw)
|
|
*
|
|
export H_FREE_BLOCKS
|
|
h_free_blocks ;
|
|
ldx #0000 ;Always = 0.
|
|
txa
|
|
|
|
send_long_word sta [my_pblk],y ;Send low word.
|
|
iny ;Bump offset.
|
|
iny
|
|
txa ;Get high word.
|
|
send_word sta [my_pblk],y ;Send it.
|
|
clc ;Indicate no error.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* FILE_SYS_ID Field Handler: Output (w)
|
|
*
|
|
export H_FILE_SYS_ID
|
|
h_file_sys_id ;
|
|
|
|
ldx #hs_id ;Get High Sierra Id.
|
|
lda state_flag ;Get flag.
|
|
and #iso_bit ;Iso?
|
|
beq send_id ;Nope.
|
|
ldx #iso_id ;Yes, change id.
|
|
send_id txa ;
|
|
bra send_word ;Send it.
|
|
*
|
|
* BLOCK_SIZE Field Handler: Output (w)
|
|
*
|
|
export H_BLOCK_SIZE
|
|
h_block_size ;
|
|
|
|
tyx ;Save offset.
|
|
ldy #vcr_block_size ;Get offset to size.
|
|
lda [my_vcr],y ;Get word
|
|
txy ;Recover offset.
|
|
bra send_word ;Send it.
|
|
*
|
|
* TRANSFER_COUNT Field Handler: Output (lw)
|
|
*
|
|
export H_TRANSFER_COUNT
|
|
h_transfer_count ;
|
|
|
|
lda transfer_count ;Get low word.
|
|
ldx transfer_count+2 ;Get high word.
|
|
bra send_long_word ;Send it.
|
|
|
|
*
|
|
* ENTRY_NUM Field Handler: Output (w)
|
|
*
|
|
export H_ENTRY_NUM
|
|
h_entry_num ;
|
|
|
|
lda entry_num ;Get entry #.
|
|
bra send_word ;Send it.
|
|
|
|
*
|
|
* DEV_NUMBER Field Handler: Output (w)
|
|
*
|
|
export H_DEV_NUMBER
|
|
h_dev_number ;
|
|
|
|
lda dev_number ;Get number
|
|
sta [my_pblk],y ;Send it.
|
|
clc ;No error.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* NAME Field Handler: Output (ptr)
|
|
*
|
|
export H_NAME
|
|
h_name ;
|
|
|
|
lda dir_record_0+dir_len_fi ;Get length of name.
|
|
and #$00ff ;Clear high word.
|
|
sta gstring ;Put at start of gstring.
|
|
sta file_name ;(Make a copy for get_file_type)
|
|
tax ;Put in X.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
stz gstring+2,x ;Add zero delimiter.
|
|
stz file_name+2,x ;(Make a copy for get_file_type)
|
|
|
|
name_loop lda dir_record_0+dir_len_fi,x ;Get byte.
|
|
sta gstring+1,x ;Put in gstring.
|
|
sta file_name+1,x ;(Make a copy for get_file_type)
|
|
dex ;Done all?
|
|
bne name_loop ;No, so loop.
|
|
|
|
longa on ;Set 16 bit A.
|
|
rep #$20
|
|
|
|
lda class ;Get class.
|
|
pha ;Save it.
|
|
inc class ;Make sure we send a class 1 string.
|
|
phy ;Save Y.
|
|
jsr transform_out ;Transform it if needed.
|
|
ply ;Recover Y.
|
|
jsr send_name ;Do send.
|
|
pla ;Recover class.
|
|
sta class ;Restore it.
|
|
rts ;Exit.
|
|
|
|
*
|
|
* EXTENDED Field Handler: Output (w)
|
|
*
|
|
export H_EXTENDED
|
|
h_extended ;
|
|
|
|
lda extended_flag ;Get extended flag.
|
|
bra send_word ;Send it.
|
|
|
|
*
|
|
* COMMAND_NUM Field Handler: Input (w)
|
|
*
|
|
export H_COMMAND_NUM
|
|
h_command_num ;
|
|
|
|
lda [my_pblk],y ;Get command number.
|
|
cmp #max_command_num ;Is it in range?
|
|
bcs bad_command ;Nope.
|
|
sta command_num ;Yes, save it.
|
|
rts ;Exit
|
|
|
|
bad_command lda #parm_range_err ;Get error code.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: add_separator
|
|
*
|
|
* Description: This routine will insert a class 0 or 1 separator at the
|
|
* beginning of the gstring pointed to by X and Y.
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: Nov 6, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = low byte of pointer to gstring
|
|
* Y = high byte of pointer to gstring
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* class ;class of call.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* input_string
|
|
* length
|
|
*
|
|
******************************************************************************
|
|
|
|
add_separator proc
|
|
with data
|
|
|
|
*
|
|
* Save pointer, bump string length, and bump pointer...
|
|
*
|
|
stx input_string ;Save pointer.
|
|
sty input_string+2
|
|
|
|
lda [input_string] ;Get length.
|
|
tay ;Put in Y.
|
|
inc a ;Bump it.
|
|
sta [input_string] ;Save length.
|
|
|
|
inc input_string ;Bump pointer.
|
|
bne shift_it
|
|
inc input_string+2
|
|
*
|
|
* Shift string 1 byte to the right...
|
|
*
|
|
longa off ;Set 8 bit A.
|
|
shift_it sep #$20
|
|
|
|
shift_loop lda [input_string],y ;Get byte.
|
|
iny ;Bump offset.
|
|
sta [input_string],y ;Save byte.
|
|
dey ;Adjust offset.
|
|
dey ;Done all?
|
|
bne shift_loop ;No, so loop.
|
|
*
|
|
* Add separator and exit...
|
|
*
|
|
lda #separator0 ;Assume class 0.
|
|
ldx class ;Is our assumption right?
|
|
beq save_it ;Yes.
|
|
lda #separator1 ;Nope.
|
|
save_it iny ;Point at separator space.
|
|
sta [input_string],y ;Insert it.
|
|
|
|
longa on ;Set 16 bit A.
|
|
rep #$20
|
|
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: send_gstring
|
|
*
|
|
* Description: This routine will send a class 0 or 1 output string to the
|
|
* users name buffer. Should only be called by a field handler!!
|
|
*
|
|
* Created: Oct 15, 1987
|
|
* Modified: Nov 6, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = low byte of pointer to gstring
|
|
* Y = high byte of pointer to gstring
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* class ;class of call.
|
|
* output_string ;points to output buffer.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 if no error.
|
|
* 1 if error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* input_string
|
|
* output_string
|
|
* length
|
|
*
|
|
******************************************************************************
|
|
|
|
send_gstring proc
|
|
with data
|
|
|
|
*
|
|
* Save pointer, get string length, bump pointer by 1...
|
|
*
|
|
stx input_string ;Save pointer.
|
|
sty input_string+2
|
|
|
|
lda [input_string] ;Get string length in A.
|
|
sta length ;Save it.
|
|
|
|
inc input_string ;Bump pointer.
|
|
bne check_class
|
|
inc input_string+2
|
|
*
|
|
* Is this a class 0 call?
|
|
*
|
|
check_class ldy class ;Class 0?
|
|
bne class_1 ;Nope.
|
|
*
|
|
* Yes, so put a one byte length first and branch to send_string...
|
|
*
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
ldy #0 ;Point to start of output string.
|
|
sta [output_string],y ;Put length.
|
|
|
|
bra send_string ;Continue.
|
|
*
|
|
* No, put a 1 word length first...
|
|
*
|
|
longa on ;Make sure 16 bit A.
|
|
|
|
class_1 ldy #2 ;Point to start of output string.
|
|
sta [output_string],y ;Put length word.
|
|
*
|
|
* Will string fit in caller's buffer?
|
|
*
|
|
clc ;Adjust for buffer length.
|
|
adc #0004
|
|
cmp [output_string] ;Will it fit?
|
|
bcc adjust ;Yep.
|
|
beq adjust ;Yep.
|
|
|
|
lda #buff_too_small ;No, get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Yes, bump pointer past length...
|
|
*
|
|
longa on ;Set 16 bit mode.
|
|
adjust rep #$20
|
|
|
|
clc ;Add 3 to pointer.
|
|
lda #3
|
|
adc output_string
|
|
sta output_string
|
|
lda #0
|
|
adc output_string+2
|
|
sta output_string+2
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
*
|
|
* Now send the rest of the string and exit...
|
|
*
|
|
send_string ldy length ;Get length.
|
|
send_loop lda [input_string],y ;Get byte.
|
|
sta [output_string],y ;Save byte.
|
|
dey ;Done all?
|
|
bne send_loop ;No, so loop.
|
|
|
|
longa on ;Yes, restore 16 bit A.
|
|
rep #$20
|
|
clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: make_gstring
|
|
*
|
|
* Description: This routine will make a gstring from a High Sierra format
|
|
* string.
|
|
*
|
|
* Created: Oct 16, 1987
|
|
* Modified: Oct 16, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = offset to start of name from io_buffer
|
|
* X = undefined
|
|
* Y = maximum length of name -1
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* io_buffer ;points to base of buffer to which A
|
|
* ;and Y are offsets.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = length of string
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
*
|
|
* B = K
|
|
*
|
|
* gstring ;holds gstring
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* input_string
|
|
* gstring
|
|
*
|
|
******************************************************************************
|
|
|
|
make_gstring proc
|
|
with data
|
|
|
|
*
|
|
* Point input_string to start of string...
|
|
*
|
|
clc ;Add A to io_buffer.
|
|
adc io_buffer
|
|
sta input_string ;Save in input_string.
|
|
lda #0
|
|
adc io_buffer+2
|
|
sta input_string+2
|
|
*
|
|
* Find real length of string. Zero length?
|
|
*
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
length_loop lda [input_string],y ;Get byte.
|
|
cmp #space ;Is it a space?
|
|
bne hit_end ;No, so found end of string.
|
|
dey ;Yes, done all?
|
|
bpl length_loop ;Nope, so loop.
|
|
*
|
|
* Yes, so force to 'UNTITLED'...
|
|
*
|
|
iny ;Yes, so point to first byte.
|
|
un_loop lda untitled_str,y ;Get byte. End of string?
|
|
beq end_of_str ;Yes.
|
|
sta [input_string],y ;Nope, so stuff it.
|
|
iny ;Bump pointer.
|
|
bra un_loop ;And loop.
|
|
|
|
end_of_str dey ;Adjust length.
|
|
*
|
|
* Put length word in gstring and add null...
|
|
*
|
|
hit_end iny ;Add 1 to the length.
|
|
sty gstring ;Put length word.
|
|
lda #0 ;Get null.
|
|
sta gstring+2,y ;Add null to end of string.
|
|
dey ;Adjust Y.
|
|
*
|
|
* Now send the rest of the string, put length in Y and exit...
|
|
*
|
|
send_string lda [input_string],y ;Get byte.
|
|
sta gstring+2,y ;Save byte.
|
|
dey ;Done all?
|
|
bpl send_string ;Nope, so loop.
|
|
|
|
longa on ;Restore 16 bit A.
|
|
rep #$20
|
|
|
|
ldy gstring ;Get length.
|
|
clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: move_gstring
|
|
*
|
|
* Description: This routine will move a gstring from the gstring buffer to
|
|
* the selected address. No error checking is done on the string
|
|
* so be careful!
|
|
*
|
|
* Created: Oct 21, 1987
|
|
* Modified: Oct 21, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = low byte of pointer to destination buffer.
|
|
* Y = high byte of pointer to destination buffer.
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* gstring contains gstring.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = length of string
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
*
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* output_string
|
|
* gstring
|
|
*
|
|
******************************************************************************
|
|
|
|
move_gstring proc
|
|
with data
|
|
|
|
*
|
|
* Save pointer to destination...
|
|
*
|
|
stx output_string ;Save pointer.
|
|
sty output_string+2
|
|
*
|
|
* Copy length...
|
|
*
|
|
lda gstring ;Get length.
|
|
sta [output_string] ;Move it.
|
|
*
|
|
* Copy remainder of string and exit...
|
|
*
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
ldy #2 ;Point past length.
|
|
move_loop lda gstring,y ;Get byte.
|
|
sta [output_string],y ;Move it.
|
|
beq exit ;Exit if zero.
|
|
iny ;Otherwise point to next.
|
|
bra move_loop ;And loop.
|
|
|
|
longa on ;Set 16 bit A.
|
|
exit rep #$20
|
|
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: parse_path
|
|
*
|
|
* Description: Vaidates string, then copies first name in path to volume_name
|
|
* and last name to file_name (both in gstring format). Sets
|
|
* name_count to # of names found, and puts offsets to start of
|
|
* each name in name_offsets. If there is only a device name,
|
|
* will exit with name_count = 0.
|
|
*
|
|
* Created: Oct 21, 1987
|
|
* Modified: July 14, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* path1_ptr ;points to pathname.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* volume_name ;volume name in gstring format.
|
|
* file_name ;file name in gstring format.
|
|
* name_count ;# of names found. 0 if device only.
|
|
* name_offsets ;list of offsets to start of names.
|
|
*
|
|
* Uses: All registers
|
|
* path_ptr
|
|
* volume_name
|
|
* file_name
|
|
* name_count
|
|
* name_offsets
|
|
* transform_name (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
parse_path proc
|
|
with data
|
|
|
|
*
|
|
* Make sure that pathname 1 is defined and that its span is in range...
|
|
*
|
|
lda path_flag ;Get pathname flags.
|
|
and #path1_mask ;Is pathname 1 defined?
|
|
bne have_path ; yes, go look at it (18-Dec-91 MSD)
|
|
|
|
; This code commented out 18-Dec-91 MSD. Checking of the span was moved to
|
|
; process_path.
|
|
; beq check_device ;No, so see if we have a device #.
|
|
;
|
|
; lda span1 ;Get span1.
|
|
; cmp #32 ;In range?
|
|
; bcc have_path ;Yes.
|
|
; bra bad_path ;Nope, so bad.
|
|
|
|
*
|
|
* There is no pathname. If we have a device # then exit with name_count = 0,
|
|
* otherwise exit with a bad path error...
|
|
*
|
|
check_device stz name_count ;Clear count.
|
|
lda dev_num ;Do we have a device #?
|
|
beq bad_path ;Nope, so error.
|
|
clc ;Yes, so exit with carry clear.
|
|
rts
|
|
*
|
|
* We have a pathname, set path_ptr...
|
|
*
|
|
have_path lda path1_ptr ;Copy path1_ptr to path_ptr.
|
|
sta path_ptr
|
|
lda path1_ptr+2
|
|
sta path_ptr+2
|
|
*
|
|
* Validate string and build name_offsets list. Valid string?
|
|
*
|
|
ldy #3 ;Point past length & first separator.
|
|
ldx #0 ;Init name count.
|
|
lda dev_num ;Do we have a device #?
|
|
beq set_eight ;Nope.
|
|
inx ;Yes, so bump name count.
|
|
dey ;Adjust for no separator.
|
|
|
|
longa off ;Set 8 bit A.
|
|
set_eight sep #$20
|
|
|
|
new_name tya ;Get offset.
|
|
sta name_offsets,x ;Put in list.
|
|
|
|
check_loop cpy #255 ;Too many characters?
|
|
beq bad_path ;Yes, so bad.
|
|
lda [path_ptr],y ;No, get byte. End of string?
|
|
beq end_of_string ;Yep, so ok.
|
|
cmp #separator1 ;No, hit separator?
|
|
beq separator ;Yes.
|
|
cmp #'.' ;No, is this a valid character?
|
|
beq next_char ;Yes.
|
|
cmp #'0' ;Maybe.
|
|
bcc bad_path ;Nope.
|
|
cmp #'9'+1 ;Maybe.
|
|
bcc next_char ;Yes.
|
|
cmp #';' ;Maybe.
|
|
beq next_char ;Yes.
|
|
cmp #'A' ;Maybe.
|
|
bcc bad_path ;Nope.
|
|
cmp #'Z'+1 ;Maybe.
|
|
bcc next_char ;Yes.
|
|
cmp #'_' ;Maybe.
|
|
bne bad_path ;Nope.
|
|
next_char iny ;Point to next character.
|
|
bra check_loop ;Loop.
|
|
|
|
separator iny ;Point to next character.
|
|
inx ;Bump name count.
|
|
cpx #max_names ;Too many names?
|
|
bne new_name ;Nope, so loop.
|
|
*
|
|
* Nope, exit with bad path error...
|
|
*
|
|
longa on ;Set 16 bit A.
|
|
bad_path rep #$20
|
|
|
|
lda #bad_path_syntax ;Nope, get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Yes, save name_count and move first name to volume_name...
|
|
*
|
|
longa off ;Make sure 8 bit A.
|
|
|
|
end_of_string inx ;Zero adjust.
|
|
stx name_count ;Save count.
|
|
|
|
lda name_offsets ;Get offset to first name.
|
|
tay
|
|
ldx #0 ;Get offset into volume name.
|
|
copy_loop1 lda [path_ptr],y ;Get byte. End of string?
|
|
beq end_name_1 ;Yes.
|
|
cmp #separator1 ;End of name?
|
|
beq end_name_1 ;Yes.
|
|
sta volume_name+2,x ;No, put byte in volume name.
|
|
inx ;Bump offsets.
|
|
iny
|
|
; Begin 18-Dec-91 MSD
|
|
cpx #32 ; volume name too long?
|
|
bge bad_path ; yes, so couldn't be ours anyway
|
|
; End 18-Dec-91 MSD
|
|
bra copy_loop1 ;Loop.
|
|
|
|
end_name_1 lda #0 ;Terminate string.
|
|
sta volume_name+2,x
|
|
stx volume_name ;Put length word.
|
|
*
|
|
* Is there another name?
|
|
*
|
|
ldx name_count ;Get name count.
|
|
cpx #1 ;More than 1?
|
|
beq done ;Nope, so done.
|
|
*
|
|
* Yes, move last one to file_name...
|
|
*
|
|
dex ;Point to last offset.
|
|
lda name_offsets,x ;Get offset to last name.
|
|
tay
|
|
ldx #0 ;Get offset into file name.
|
|
copy_loop2 lda [path_ptr],y ;Get byte. End of string?
|
|
beq end_name_2 ;Yes.
|
|
cmp #separator1 ;End of name?
|
|
beq end_name_2 ;Yes.
|
|
sta file_name+2,x ;No, put byte in volume name.
|
|
inx ;Bump offsets.
|
|
iny
|
|
bra copy_loop2 ;Loop.
|
|
|
|
end_name_2 lda #0 ;Terminate string.
|
|
sta file_name+2,x
|
|
stx file_name ;Put length word.
|
|
*
|
|
* Done, exit with carry clear...
|
|
*
|
|
longa on ;Set 16 bit A.
|
|
done rep #$20
|
|
|
|
clc ;Indicate ok.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_name
|
|
*
|
|
* Description: Copies indicated name from the pathname to string_buffer.
|
|
*
|
|
* Created: Oct 22, 1987
|
|
* Modified: Mar 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = name index (no validity checking is done!)
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* path_ptr ;points to pathname.
|
|
* name_offsets ;list of offsets to start of names.
|
|
*
|
|
* Output: A = undefined
|
|
* X = length of name
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* string_buffer ;name with length byte at start.
|
|
*
|
|
* Uses: All registers
|
|
* path_ptr
|
|
* name_offsets
|
|
* string_buffer
|
|
*
|
|
******************************************************************************
|
|
|
|
get_name proc
|
|
with data
|
|
|
|
*
|
|
* Move name to string buffer...
|
|
*
|
|
ldx #0 ;Init offset/counter.
|
|
txa ;Clear accumulator.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
lda name_offsets,y ;Get offset to start of name.
|
|
tay
|
|
|
|
move_loop lda [path_ptr],y ;Get byte. End of string?
|
|
beq hit_end ;Yes.
|
|
cmp #separator1 ;No, is it a separator?
|
|
beq hit_end ;Yes.
|
|
sta string_buffer+1,x ;No, add to buffer.
|
|
iny ;Bump offsets.
|
|
inx
|
|
bra move_loop ;Loop.
|
|
|
|
hit_end txa ;Put length in A (so is 8 bit).
|
|
sta string_buffer ;Save length.
|
|
|
|
longa on ;Set 16 bit A.
|
|
rep #$20
|
|
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: long_multiply
|
|
*
|
|
* Description: Does 32 bit multiplication. multiplicand * multiplier = product
|
|
*
|
|
* Created: Nov 30, 1987
|
|
* Modified: Nov 30, 1987
|
|
* Author: Bryan Atsatt (adapted from '6502 Software Design')
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* multiplier ;32 bit multiplier.
|
|
* multiplicand ;32 bit multiplicand.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* product ;64 bit product.
|
|
*
|
|
* Uses: All registers
|
|
* multiplier (a.k.a. dividend)
|
|
* multiplicand (a.k.a. divisor)
|
|
* product (a.k.a. input_string & output_string)
|
|
*
|
|
******************************************************************************
|
|
|
|
long_multiply proc
|
|
with data
|
|
|
|
*
|
|
* Initialize...
|
|
*
|
|
ldx #32 ;Get bit count.
|
|
lda #0 ;MUST BE ZEROED!
|
|
sta product+4 ;Clear upper 4 bytes of product.
|
|
sta product+6
|
|
*
|
|
* Do multiplication and exit...
|
|
*
|
|
next_bit lsr multiplier+2 ;Shift multiplier right. Bit set?
|
|
ror multiplier
|
|
bcc align ;Nope.
|
|
clc ;Yes, add product+4 to multiplicand.
|
|
lda product+4
|
|
adc multiplicand
|
|
sta product+4
|
|
lda product+6
|
|
adc multiplicand+2
|
|
align ror a ;Rotate 8 byte product right.
|
|
sta product+6
|
|
ror product+4
|
|
ror product+2
|
|
ror product
|
|
dex ;Done all bits?
|
|
bne next_bit ;Nope, so loop.
|
|
rts ;Yes, so exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: long_divide
|
|
*
|
|
* Description: Does 32 bit division. dividend/divisor = dividend w/remainder.
|
|
*
|
|
* Created: Oct 29, 1987
|
|
* Modified: Oct 29, 1987
|
|
* Author: Bryan Atsatt (adapted from '6502 Software Design')
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* dividend ;32 bit dividend.
|
|
* divisor ;32 bit divisor.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* dividend ;quotient
|
|
* remainder ;remainder
|
|
*
|
|
* Uses: All registers
|
|
* dividend
|
|
* divisor
|
|
* remainder
|
|
*
|
|
******************************************************************************
|
|
|
|
long_divide proc
|
|
with data
|
|
|
|
*
|
|
* Initialize...
|
|
*
|
|
ldx #32 ;Get bit count.
|
|
stz remainder ;Clear remainder.
|
|
stz remainder+2
|
|
*
|
|
* Do division and exit...
|
|
*
|
|
div_loop asl dividend ;Shift dividend & quotient left.
|
|
rol dividend+2
|
|
rol remainder ;Shift partial dividend left.
|
|
rol remainder+2
|
|
sec ;Subtract low bytes.
|
|
lda remainder
|
|
sbc divisor
|
|
tay ;Save low result.
|
|
lda remainder+2 ;Subtract high bytes.
|
|
sbc divisor+2 ;Divisor > dividend?
|
|
bcc next_bit ;Yes.
|
|
inc dividend ;No, set bit in quotient.
|
|
sty remainder ;Enter result in partial dividend.
|
|
sta remainder+2
|
|
next_bit dex ;Done all bits?
|
|
bne div_loop ;No, so loop.
|
|
rts ;Yes, so exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: pro_date_time
|
|
*
|
|
* Description: Converts recording date and time from dir_record_0 to prodos
|
|
* date/time format.
|
|
*
|
|
* Created: Nov 2, 1987
|
|
* Modified: Nov 2, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* prodos_time ;Holds date and time:
|
|
* _______________________________________________________________
|
|
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|
|
* | year | month | day |0 0 0 hour |0 0 minute |
|
|
* |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|
|
*
|
|
* ;year = 1900-year
|
|
* ;month = 1-12
|
|
* ;day = 1-31
|
|
* ;hour = 0-23
|
|
* ;minute = 0-59
|
|
*
|
|
* Uses: All registers
|
|
* create_date_time
|
|
* prodos_time
|
|
* get_date_time (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
pro_date_time proc
|
|
with data
|
|
|
|
*
|
|
* Get the create_date_time...
|
|
*
|
|
jsr get_date_time ;Get it.
|
|
*
|
|
* Now convert it to prodos format and exit...
|
|
*
|
|
lda day ;Get day.
|
|
and #$00ff ;Clear high byte.
|
|
inc a ;Make it 1-31.
|
|
sta prodos_time ;Save it.
|
|
lda month ;Get month.
|
|
and #$00ff ;Clear high byte.
|
|
inc a ;Make it 1-12.
|
|
asl a ;Move to correct position.
|
|
asl a
|
|
asl a
|
|
asl a
|
|
asl a
|
|
ora prodos_time ;Insert it.
|
|
sta prodos_time ;Save it.
|
|
lda year ;Get year.
|
|
and #$00ff ;Clear high byte.
|
|
xba ;Move to correct position.
|
|
asl a
|
|
ora prodos_time ;Insert it.
|
|
sta prodos_time ;Save it.
|
|
lda hour ;Get hour.
|
|
and #$00ff ;Clear high byte.
|
|
xba ;Move to correct position.
|
|
sta prodos_time+2 ;Save it.
|
|
lda minute ;Get minute.
|
|
and #$00ff ;Clear high byte.
|
|
ora prodos_time+2 ;Insert it.
|
|
sta prodos_time+2 ;Save it.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_date_time
|
|
*
|
|
* Description: Converts recording date and time from dir_record_0 to GS/OS
|
|
* date/time format. If date/time is illegal, will set to
|
|
* Jan 1, 1988 12:00 am default.
|
|
*
|
|
* Created: Nov 2, 1987
|
|
* Modified: July 14, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* create_date_time ;Holds date and time:
|
|
*
|
|
* |<-- byte 7 -->|<-- byte 6 -->|<-- byte 5 -->|<-- byte 4 -->|
|
|
* _______________________________________________________________
|
|
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|
|
* | weekday | null | month | day |
|
|
* |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|
|
*
|
|
* |<-- byte 3 -->|<-- byte 2 -->|<-- byte 1 -->|<-- byte 0 -->|
|
|
* _______________________________________________________________
|
|
* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|
|
* | year | hour | minute | second |
|
|
* |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|
|
|
*
|
|
* ;year = year-1900
|
|
* ;month = 0-11
|
|
* ;day = 0-30
|
|
* ;weekday = 1-7, 1 = sunday
|
|
* ;hour = 0-23
|
|
* ;minute = 0-59
|
|
* ;second = 0-59
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
get_date_time proc
|
|
with data
|
|
|
|
|
|
*
|
|
* Set 8 bit registers...
|
|
*
|
|
longa off ;Set 8 bit registers.
|
|
longi off
|
|
sep #$30
|
|
*
|
|
* Convert date and time...
|
|
*
|
|
lda dir_record_0+dir_date_time ;Get year.
|
|
cmp #max_year ;In range?
|
|
bcs use_default ;Nope.
|
|
sta year ;Yes, save it.
|
|
|
|
ldx dir_record_0+dir_date_time+1 ;Get month.
|
|
dex ;Make it 0-11.
|
|
stx month ;Save it.
|
|
cpx #max_month ;In range?
|
|
bcs use_default ;Nope.
|
|
|
|
ldy dir_record_0+dir_date_time+2 ;Get day.
|
|
dey ;Make it 0-30.
|
|
sty day ;Save it.
|
|
cpy #max_day ;In range?
|
|
bcs use_default ;Nope.
|
|
|
|
inx ;Bump month.
|
|
iny ;Bump day.
|
|
jsr calc_dow ;Calculate day of week.
|
|
sta weekday ;Save it.
|
|
|
|
stz null ;Clear null.
|
|
|
|
lda dir_record_0+dir_date_time+3 ;Get hour.
|
|
cmp #max_hour ;In range?
|
|
bcs use_default ;Nope.
|
|
sta hour ;Yes, save it.
|
|
|
|
lda dir_record_0+dir_date_time+4 ;Get minute.
|
|
cmp #max_minute ;In range?
|
|
bcs use_default ;Nope.
|
|
sta minute ;Yes, save it.
|
|
|
|
lda dir_record_0+dir_date_time+5 ;Get second.
|
|
cmp #max_second ;In range?
|
|
bcs use_default ;Nope.
|
|
sta second ;Yes, save it.
|
|
|
|
bra exit ;Exit.
|
|
*
|
|
* Date or time is bad, use default date/time...
|
|
*
|
|
use_default ldy #7 ;Copy default date/time.
|
|
copy_loop lda default_date_time,y
|
|
sta create_date_time,y
|
|
dey
|
|
bpl copy_loop
|
|
*
|
|
* Restore 16 bit registers and exit...
|
|
*
|
|
longa on ;Set 16 bit registers.
|
|
longi on
|
|
exit rep #$30
|
|
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: calc_dow
|
|
*
|
|
* Description: Calculates the day of the week for a given date.
|
|
*
|
|
* NOTE: Call with m & x set!
|
|
*
|
|
* Created: Nov 2, 1987
|
|
* Modified: Nov 2, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = year (year-1900)
|
|
* X = month (1-12)
|
|
* Y = day (1-31)
|
|
* P = nvmxdizc
|
|
* ..110...
|
|
* B = K
|
|
*
|
|
* Output: A = day of week
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..110...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* temp0
|
|
* temp1
|
|
*
|
|
******************************************************************************
|
|
|
|
calc_dow proc
|
|
with data
|
|
|
|
|
|
longa off
|
|
longi off
|
|
*
|
|
* Calculate the number of leap years since 1900...
|
|
*
|
|
sty day_of_mon ;Save day.
|
|
tay ;Save year.
|
|
lsr a ;Divide year by 4.
|
|
lsr a
|
|
sta leap_years ;Save it.
|
|
*
|
|
* If it's a leap year and it's Jan or Feb, subtract 1 from the year...
|
|
*
|
|
tya ;Get year back.
|
|
and #3 ;Is it a leap year?
|
|
bne continue ;Nope.
|
|
cpx #3 ;Yep, is it Jan or Feb?
|
|
bcs continue ;Nope.
|
|
dey ;Yes, adjust year.
|
|
*
|
|
* Now add up the number of leap years elapsed, the year, the day, and a
|
|
* constant for the month...
|
|
*
|
|
continue clc ;Prepare for add.
|
|
tya ;Get year.
|
|
adc leap_years ;Add # leap years.
|
|
adc day_of_mon ;Add day.
|
|
adc constant-1,x ;Add constant.
|
|
*
|
|
* Convert the result to a # in the range 1 to 7 and exit...
|
|
*
|
|
sec ;Prepare for subtract.
|
|
adjust_loop sbc #7 ;Subtact 7.
|
|
cmp #8 ;In range?
|
|
bcs adjust_loop ;No, so loop.
|
|
|
|
rts ;Exit.
|
|
|
|
constant DC.B 8,11,11,7,9,12,7,10,13,8,13
|
|
|
|
longa on
|
|
longi on
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_option_list
|
|
*
|
|
* Description: Load extended attribute record (if present) into option list
|
|
* buffer. If it gets an error when trying to read the data,
|
|
* will set transfer count to zero and exit with carry clear.
|
|
*
|
|
* Created: Nov 2, 1987
|
|
* Modified: Mar 2, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = high word of option list pointer.
|
|
* X = low word of option list pointer.
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* dir_record_0 ;holds directory record.
|
|
*
|
|
* Output: A = error code if error.
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* option list buffer: 1 = input: buffer size, inc. 1 & 2.
|
|
* 2 = output: required size, exc. 1 & 2.
|
|
* 3 = output: fst id.
|
|
* 4 = output: extended attribute record.
|
|
* _____________________
|
|
* | | | | | | | | | | | >
|
|
* | 1 | 2 | 3 | 4 <
|
|
* |_|_|_|_|_|_|_|_|_|_|_>
|
|
*
|
|
* Uses: All registers
|
|
* dividend
|
|
* data_buffer
|
|
* temp0
|
|
* temp1
|
|
*
|
|
******************************************************************************
|
|
|
|
get_option_list proc
|
|
with data
|
|
|
|
*
|
|
* Save pointer, exit if zero...
|
|
*
|
|
stx option_list ;Save low word.
|
|
sta option_list+2
|
|
ora option_list ;Zero?
|
|
bne check_buffer ;No, so ok.
|
|
clc ;Yes, so exit with no error.
|
|
rts
|
|
*
|
|
* Is the buffer big enough to hold the length? Parm_range_err if not...
|
|
*
|
|
check_buffer lda [option_list] ;Get buffer length.
|
|
cmp #4 ;Big enough to hold length?
|
|
bcs init_len ;Yes.
|
|
sec ;No, so parm_range_err.
|
|
lda #parm_range_err
|
|
brl error_exit ;Exit.
|
|
*
|
|
* Yes, so init length to 2 for the FST id...
|
|
*
|
|
init_len lda #2 ;Get minimum length.
|
|
sta length ;Save it.
|
|
*
|
|
* Is there an XAR for this file?
|
|
*
|
|
stz block_count ;Clear in case no XAR.
|
|
lda dir_record_0+dir_xar_len ;Do we have an XAR?
|
|
and #$00ff
|
|
beq no_xar ;Nope, so exit.
|
|
sta block_count ;Yes, save block count.
|
|
*
|
|
* Yes, set length to required size...
|
|
*
|
|
tax ;Use block_count as counter.
|
|
clc ;Prepare for add.
|
|
lda #2 ;Init size to include overhead.
|
|
add_loop adc log_blk_size ;Add logical block size.
|
|
dex ;Done all?
|
|
bne add_loop ;No, so loop.
|
|
|
|
sta length ;Yes, so save it.
|
|
*
|
|
* Set output length to required size...
|
|
*
|
|
no_xar ldy #2 ;Get offset to length.
|
|
lda length ;Get required length.
|
|
sta [option_list],y ;Stuff it in.
|
|
*
|
|
* Will the buffer hold the FST ID? Exit with buf_too_small error if not...
|
|
*
|
|
lda [option_list] ;Get length word.
|
|
cmp #0006 ;Will the id fit?
|
|
bcc full ;Nope.
|
|
*
|
|
* Yes, so stuff it in...
|
|
*
|
|
ldy #0004 ;Point to id area.
|
|
lda #hs_id ;Get fst id.
|
|
sta [option_list],y ;Stuff it in.
|
|
*
|
|
* Yes, set max_len to buffer size - 6 (carry set from above). Exit with
|
|
* buf_too_small error if max_len = 0...
|
|
*
|
|
lda [option_list] ;Get length word.
|
|
sbc #6 ;Adjust for overhead.
|
|
sta max_len ;Save it.
|
|
beq full ;Full if max_len zero.
|
|
*
|
|
* We're done with no error if there isn't an XAR...
|
|
*
|
|
lda block_count ;Is there an XAR?
|
|
beq ok_exit ;Nope, so done.
|
|
*
|
|
* We have an XAR. Make a pointer to data area...
|
|
*
|
|
clc ;Add 6 to option_list.
|
|
lda #6
|
|
adc option_list
|
|
sta data_buffer
|
|
lda #0
|
|
adc option_list+2
|
|
sta data_buffer+2
|
|
*
|
|
* Make sure io_buffer is pointed at the real io_buffer...
|
|
*
|
|
ldx io_buffer_vp ;Get vp.
|
|
ldy io_buffer_vp+2
|
|
jsl deref ;Dereference it.
|
|
stx io_buffer ;Save pointer.
|
|
sty io_buffer+2
|
|
*
|
|
* Get address of first block...
|
|
*
|
|
ldx dir_record_0+dir_loc_extent ;Get low word of block #.
|
|
lda dir_record_0+dir_loc_extent+2 ;Get high word.
|
|
*
|
|
* Read block into io_buffer. Exit on error...
|
|
*
|
|
read_loop jsr block_read ;Do read.
|
|
bcs error_exit ;Error, so set count to zero and exit.
|
|
*
|
|
* Send until we've filled caller's buffer or finished with block...
|
|
*
|
|
longa off ;Set 8 bit mode.
|
|
sep #$20
|
|
|
|
ldy #0 ;Init offset.
|
|
move_loop lda [io_buffer],y ;Get byte.
|
|
sta [data_buffer],y ;Send it.
|
|
iny ;Bump offset.
|
|
cpy max_len ;Full?
|
|
beq full ;Yes.
|
|
cpy log_blk_size ;No, run out of buffer?
|
|
bne move_loop ;Nope, so loop.
|
|
|
|
longa on ;Set 16 bit mode.
|
|
rep #$20
|
|
*
|
|
* Ran out of data. Add log_blk_size to transfer_count and get next block
|
|
* number (if there is one) and loop...
|
|
*
|
|
ldx drvr_blk_num ;Get current block.
|
|
lda drvr_blk_num+2
|
|
inx ;Bump it.
|
|
bne check_block
|
|
inc a
|
|
check_block dec block_count ;Done all blocks?
|
|
bne read_loop ;No, so loop.
|
|
*
|
|
* Done. Exit with carry clear...
|
|
*
|
|
ok_exit clc ;No error.
|
|
rts ;Exit.
|
|
*
|
|
* We've filled up the caller's buffer and there's more to go, so exit
|
|
* with a buffer too small error. If we're processing an open call, we
|
|
* must release the fcr...
|
|
*
|
|
longa on ;Set 16 bit mode.
|
|
full rep #$20
|
|
|
|
lda #buff_too_small ;Get error code.
|
|
sec ;Indicate error.
|
|
error_exit ldx call ;Doing an open call?
|
|
cpx #$10
|
|
bne real_exit ;No.
|
|
|
|
pha ;Yes, save error code.
|
|
lda [my_fcr] ;Get ref_num.
|
|
jsl release_fcr ;Release fcr.
|
|
pla ;Recover error code.
|
|
|
|
real_exit sec ;Make sure carry set.
|
|
rts ;Exit.
|
|
|
|
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: transform_in_s
|
|
*
|
|
* Description: Replaces all periods in string_buffer with underscores if
|
|
* ProDOS Transformation bit is set in state_flag.
|
|
*
|
|
* Created: June 30, 1988
|
|
* Modified: June 30, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to current vcr.
|
|
* string_buffer ;holds name in pascal string format
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
transform_in_s proc
|
|
with data
|
|
|
|
*
|
|
* Are we supposed to do the transformation? Exit if not...
|
|
*
|
|
ldy #vcr_state_flag ;Get offset to state flag in vcr.
|
|
lda [my_vcr],y ;Get state flags.
|
|
and #prodos_bit ;Prodos bit set?
|
|
beq exit ;Nope, so exit.
|
|
*
|
|
* Yes, replace all "." in string with "_" and exit...
|
|
*
|
|
lda string_buffer ;Get length of string
|
|
and #$00ff ;Clear high byte.
|
|
tay ;Point to end of string.
|
|
|
|
lda #$5f2e ;Get underscore and period.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
transform_loop cmp string_buffer,y ;Is period?
|
|
bne next ;Nope.
|
|
xba ;Yes, get underscore.
|
|
sta string_buffer,y ;Replace period.
|
|
xba ;Recover period.
|
|
next dey ;Done all?
|
|
bne transform_loop ;Nope, so loop.
|
|
|
|
longa on ;Yep, set 16 bit A.
|
|
rep #$20
|
|
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: transform_in_f
|
|
*
|
|
* Description: Replaces all periods in file_name with underscores and appends
|
|
* ".;1" if ProDOS Transformation bit is set in state_flag.
|
|
*
|
|
* Created: June 30, 1988
|
|
* Modified: June 30, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to current vcr.
|
|
* file_name ;holds name in gstring format.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
transform_in_f proc
|
|
with data
|
|
|
|
*
|
|
* Are we supposed to do the transformation? Exit if not...
|
|
*
|
|
ldy #vcr_state_flag ;Get offset to state flag in vcr.
|
|
lda [my_vcr],y ;Get state flags.
|
|
and #prodos_bit ;Prodos bit set?
|
|
beq exit ;Nope, so exit.
|
|
*
|
|
* Yes, replace all "." in string with "_"...
|
|
*
|
|
ldy file_name ;Point to end of string
|
|
lda #$5f2e ;Get underscore and period.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
transform_loop cmp file_name+1,y ;Is period?
|
|
bne next ;Nope.
|
|
xba ;Yes, get underscore.
|
|
sta file_name+1,y ;Replace period.
|
|
xba ;Recover period.
|
|
next dey ;Done all?
|
|
bne transform_loop ;Nope, so loop.
|
|
|
|
longa on ;Yep, set 16 bit A.
|
|
rep #$20
|
|
*
|
|
* Append ".;1" and exit...
|
|
*
|
|
ldy file_name ;Point to end of string.
|
|
lda #$3b2e ;Get period-semicolon.
|
|
sta file_name+2,y ;Append to name.
|
|
lda #$0031 ;Get "1" and string terminator.
|
|
sta file_name+4,y ;Append to name.
|
|
|
|
clc ;Add 3 to length.
|
|
lda #0003
|
|
adc file_name
|
|
sta file_name
|
|
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: transform_out
|
|
*
|
|
* Description: If ProDOS Transformation bit is set in state_flag, will strip
|
|
* ".;1" (if present) and replace all underscores with periods.
|
|
*
|
|
* Created: June 30, 1988
|
|
* Modified: June 30, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to current vcr.
|
|
* gstring ;holds name in gstring format
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
transform_out proc
|
|
with data
|
|
|
|
*
|
|
* Are we supposed to do the transformation? Exit if not...
|
|
*
|
|
ldy #vcr_state_flag ;Get offset to state flag in vcr.
|
|
lda [my_vcr],y ;Get state flags.
|
|
and #prodos_bit ;Prodos bit set?
|
|
beq exit ;Nope, so exit.
|
|
*
|
|
* Yes, strip ".;1" if present...
|
|
*
|
|
ldy gstring ;Point to end of string.
|
|
lda gstring,y ;Get last two characters.
|
|
cmp #$313b ;Are they ";1"?
|
|
bne transform ;Nope.
|
|
lda gstring-1,y ;Yep, back up one byte.
|
|
cmp #$3b2e ;Are they ".;"?
|
|
bne transform ;Nope.
|
|
|
|
dey ;Yes, so subtract 3 from length.
|
|
dey
|
|
dey
|
|
sty gstring ;Save new length.
|
|
lda #0 ;Re-terminate string at new position.
|
|
sta gstring+2,y
|
|
*
|
|
* Replace all "_" in string with "." and exit...
|
|
*
|
|
transform ldy gstring ;Point to end of string.
|
|
lda #$2e5f ;Get period and underscore.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
transform_loop cmp gstring+1,y ;Is underscore?
|
|
bne next ;Nope.
|
|
xba ;Yes, get period.
|
|
sta gstring+1,y ;Replace underscore.
|
|
xba ;Recover underscore.
|
|
next dey ;Done all?
|
|
bne transform_loop ;Nope, so loop.
|
|
|
|
longa on ;Yep, set 16 bit A.
|
|
rep #$20
|
|
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: transform_vol
|
|
*
|
|
* Description: Searches volume_name for character in low byte of A and if
|
|
* found, replaces it with character in high byte of A.
|
|
*
|
|
* Created: July 14, 1988
|
|
* Modified: July 14, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = character to match in low byte, replacement in high byte
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* volume_name ;holds name in gstring format
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
transform_vol proc
|
|
with data
|
|
|
|
*
|
|
* Transform volume_name and exit...
|
|
*
|
|
ldy volume_name ;Point to end of string.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
transform_loop cmp volume_name+1,y ;Match?
|
|
bne next ;Nope.
|
|
xba ;Yes, get replacement character.
|
|
sta volume_name+1,y ;Replace.
|
|
xba ;Recover search character.
|
|
next dey ;Done all?
|
|
bne transform_loop ;Nope, so loop.
|
|
|
|
longa on ;Yep, set 16 bit A.
|
|
rep #$20
|
|
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: transform_gstring
|
|
*
|
|
* Description: If ProDOS transformation bit set in state flag, searches
|
|
* gstring for character in low byte of A and if found, replaces
|
|
* it with character in high byte of A.
|
|
*
|
|
* Created: July 21, 1988
|
|
* Modified: July 21, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = character to match in low byte, replacement in high byte
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* gstring ;holds name in gstring format
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
transform_gstring proc
|
|
with data
|
|
|
|
*
|
|
* Should we do the transform?
|
|
*
|
|
tax ;Save A.
|
|
lda state_flag ;Get state flag.
|
|
and #prodos_bit ;ProDOS bit set?
|
|
beq exit ;Nope, so exit.
|
|
txa ;Yes, recover A.
|
|
*
|
|
* Yep, transform gstring and exit...
|
|
*
|
|
ldy gstring ;Point to end of string.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
transform_loop cmp gstring+1,y ;Match?
|
|
bne next ;Nope.
|
|
xba ;Yes, get replacement character.
|
|
sta gstring+1,y ;Replace.
|
|
xba ;Recover search character.
|
|
next dey ;Done all?
|
|
bne transform_loop ;Nope, so loop.
|
|
|
|
longa on ;Yep, set 16 bit A.
|
|
rep #$20
|
|
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: transform_name
|
|
*
|
|
* Description: Searches gstring pointed to by X and Y for character in low
|
|
* byte of A and if found, replaces it with character in high
|
|
* byte of A.
|
|
*
|
|
* Created: July 14, 1988
|
|
* Modified: July 14, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = character to match in low byte, replacement in high byte
|
|
* X = low word of pointer to gstring.
|
|
* Y = high word of pointer to gstring.
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to current vcr.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* remainder
|
|
*
|
|
******************************************************************************
|
|
|
|
transform_name proc
|
|
with data
|
|
|
|
string_ptr set remainder ;Local direct page equate.
|
|
|
|
*
|
|
* Save pointer...
|
|
*
|
|
stx string_ptr ;Save low word.
|
|
sty string_ptr+2 ;Save high word.
|
|
tax ;Save A.
|
|
*
|
|
* Are we supposed to do the transformation? Exit if not...
|
|
*
|
|
ldy #vcr_state_flag ;Get offset to state flag in vcr.
|
|
lda [my_vcr],y ;Get state flags.
|
|
and #prodos_bit ;Prodos bit set?
|
|
beq exit ;Nope, so exit.
|
|
*
|
|
* Yes, get length and bump pointer...
|
|
*
|
|
lda [string_ptr] ;Get length of string
|
|
and #$00ff ;Clear high byte.
|
|
tay ;Point to end of string.
|
|
inc string_ptr ;Bump pointer. Rollover?
|
|
bne replace ;Nope.
|
|
inc string_ptr+2 ;Yep, bump high word.
|
|
*
|
|
* Replace characters and exit...
|
|
*
|
|
replace txa ;Get characters..
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
transform_loop cmp [string_ptr],y ;Match?
|
|
bne next ;Nope.
|
|
xba ;Yes, get replacement.
|
|
sta [string_ptr],y ;Replace it.
|
|
xba ;Recover search character.
|
|
next dey ;Done all?
|
|
bne transform_loop ;Nope, so loop.
|
|
|
|
longa on ;Yep, set 16 bit A.
|
|
rep #$20
|
|
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_ext_type
|
|
*
|
|
* Description: Gets type and aux type from SystemUse field of directory record
|
|
* if SystemUse field and our signature are present.
|
|
*
|
|
* Created: July 8, 1988
|
|
* Modified: Apr 6, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to current vcr
|
|
* dir_record_0 ;holds directory record
|
|
*
|
|
* Output: A = aux_type if no error
|
|
* X = file_type if no error
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
*
|
|
******************************************************************************
|
|
|
|
get_ext_type PROC
|
|
with data
|
|
*
|
|
* Do we have a SystemUse field? Present if dir_record_length - dir_len_fi
|
|
* is >= sys_use_len (35)...
|
|
*
|
|
phy ;Save Y.
|
|
|
|
sec ;Prepare to subtract.
|
|
lda dir_record_0+dir_len_fi ;Get length of file name.
|
|
and #$00ff ;Clear high byte.
|
|
pha ;Save it.
|
|
lda dir_record_0 ;Get length of directory record.
|
|
and #$00ff ;Clear high byte.
|
|
sbc 1,s ;Do subtraction.
|
|
plx ;Recover length of file name.
|
|
cmp #sys_use_len ;Is >= sys_use_len?
|
|
bcc not_here ;Nope.
|
|
*
|
|
* Yes, adjust offset by one if we have a padding field...
|
|
*
|
|
lda dir_record_0+dir_len_fi+1,x ;Padding field?
|
|
and #$00ff
|
|
bne check_signature ;Nope.
|
|
inx ;Yes, so bump offset.
|
|
*
|
|
* Yes, do we have an apple signature?
|
|
*
|
|
check_signature ldy #0001 ;Set pass flag.
|
|
|
|
signature_loop lda dir_record_0+dir_len_fi+1,x ;Get SystemUseID signature.
|
|
cmp #apple_sig1 ;Is old signature?
|
|
beq old_sig ;Yes.
|
|
cmp #apple_sig2 ;No, is new signature?
|
|
beq new_sig ;Yes.
|
|
*
|
|
* No, is this an XA disc?
|
|
*
|
|
lda state_flag ;Get state_flag.
|
|
and #xa_bit ;Do we have an XA disc?
|
|
beq not_here ;Nope, so exit.
|
|
*
|
|
* Yes, have we bumped the offset already? Exit if so...
|
|
*
|
|
dey ;Done this already?
|
|
bne not_here ;Yes, so don't do it again.
|
|
*
|
|
* Nope, so bump offset past XA system_use stuff and re-try...
|
|
*
|
|
clc ;Bump offset.
|
|
txa
|
|
adc #xa_offset
|
|
tax
|
|
bra signature_loop ;Re-try.
|
|
*
|
|
* We have a new signature. See if we have a ProDOS field and, if so,
|
|
* adjust offset and continue on at get_type; else no extensions...
|
|
*
|
|
longa off ;Go to 8 bit regs.
|
|
longi off
|
|
new_sig sep #$30
|
|
|
|
search lda dir_record_0+dir_len_fi+4,x ;Get SystemUseID.
|
|
cmp #prodos_format ;Is it ProDOS?
|
|
bne next ;Nope.
|
|
inx ;Yes, adjust offset.
|
|
bra get_type ;Go get type.
|
|
|
|
next clc ;Point to next extensions.
|
|
txa
|
|
adc dir_record_0+dir_len_fi+3,x
|
|
tax
|
|
bcs not_here ;Done if rolled over.
|
|
adc #dir_len_fi+3 ;Checked all?
|
|
cmp dir_record_0
|
|
bcc search ;No, so keep looking.
|
|
bra not_here ;Yes, so no extensions.
|
|
*
|
|
* Yes, we have an old signature. Is this a ProDOS field?
|
|
*
|
|
longa on
|
|
longi on
|
|
|
|
old_sig lda dir_record_0+dir_len_fi+3,x ;Get SystemUseID.
|
|
and #$00ff ;Clear high byte.
|
|
cmp #prodos_format ;Is it prodos format?
|
|
bne not_here ;Nope.
|
|
*
|
|
* Yes, get file_type in X and aux_type in A and exit with carry clear...
|
|
*
|
|
get_type rep #$30 ;Make sure 16 bit A.
|
|
|
|
lda dir_record_0+dir_len_fi+4,x ;Get file_type.
|
|
and #$00ff ;Clear high byte.
|
|
tay ;Save it.
|
|
lda dir_record_0+dir_len_fi+5,x ;Get aux_type.
|
|
tyx ;Put file_type in X.
|
|
|
|
clc ;Indicate success.
|
|
ply ;Recover Y.
|
|
rts ;Exit.
|
|
*
|
|
* Data not here, so exit with carry set...
|
|
*
|
|
not_here rep #$30 ;Make sure 16 bit A.
|
|
sec ;Indicate failure.
|
|
ply ;Recover Y.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_file_type
|
|
*
|
|
* Description: Scans name in file_name buffer and tries to assign file type
|
|
* by matching entries in the file type map table.
|
|
*
|
|
* The file type map is a list of file name suffixes and associated
|
|
* file types. Each record is variable length and consists of an
|
|
* ascii string followed by a zero and a one byte file type. The
|
|
* table is terminated will a 1 byte null (00):
|
|
*
|
|
* map_size ;(w) size in bytes.
|
|
* record_0 ;file type record.
|
|
* record_1 ;file type record.
|
|
* null ;(b) map terminator.
|
|
*
|
|
* If no matching entry is found, the 'unknown' (00) type is
|
|
* returned.
|
|
*
|
|
* Created: Dec 3, 1987
|
|
* Modified: Feb 23, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* file_name ;holds name in gstring format
|
|
* map_buffer_ptr ;holds a pointer to the file type map
|
|
* map_enable_flag ;0 if disabled.
|
|
*
|
|
* Output: A = undefined
|
|
* X = file_type
|
|
* Y = unchanged
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* temp1
|
|
* length
|
|
*
|
|
******************************************************************************
|
|
|
|
get_file_type proc
|
|
with data
|
|
|
|
*
|
|
* If map_enable_flag is zero, then exit with unknown file type...
|
|
*
|
|
phy ;Save Y.
|
|
|
|
lda map_enable_flag ;Flag zero?
|
|
beq unknown ;Yep.
|
|
*
|
|
* Copy the pointer into map_ptr, init offset and set 8 bit accumulator...
|
|
*
|
|
lda map_buffer_ptr ;Get pointer.
|
|
ldx map_buffer_ptr+2
|
|
sta map_ptr ;Put in direct page pointer.
|
|
stx map_ptr+2
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
*
|
|
* Set length_temp to either real length of file_name or length minus any
|
|
* version number...
|
|
*
|
|
ldy file_name ;Point to real end.
|
|
sty length_temp ;Init length_temp
|
|
version_check lda file_name+1,y ;Get byte.
|
|
cmp #';' ;Semicolon?
|
|
beq fix_length ;Yes, so must change length.
|
|
dey ;No, done all?
|
|
bne version_check ;No, so loop.
|
|
bra init_search ;Yes, so leave length alone.
|
|
|
|
fix_length dey ;Back up past semicolon.
|
|
sty length_temp ;Save new length.
|
|
*
|
|
* Have we checked all records? If so, exit with file type 00...
|
|
*
|
|
init_search ldy #2 ;Init offset past length.
|
|
record_loop lda [map_ptr],y ;Get byte. Zero?
|
|
beq exit ;Yes, so exit with file type 00.
|
|
*
|
|
* Nope, let's find the end of the string for this record and get its length...
|
|
*
|
|
ldx #0 ;Init count.
|
|
end_loop inx ;Bump count.
|
|
iny ;Bump offset.
|
|
lda [map_ptr],y ;Get byte. Zero?
|
|
bne end_loop ;Nope, so continue.
|
|
phy ;Yes, save offset.
|
|
stx length ;Save length.
|
|
dey ;Point to last character.
|
|
*
|
|
* Does the string match?
|
|
*
|
|
cpx length_temp ;String longer than file_name?
|
|
beq check_it ;Nope.
|
|
bcs next_record ;Yep, so don't check.
|
|
check_it ldx length_temp ;Get length of file_name.
|
|
|
|
match_loop lda [map_ptr],y ;Get character.
|
|
cmp file_name+1,x ;Match?
|
|
bne next_record ;Nope.
|
|
dey ;Yes, back up one.
|
|
dex
|
|
dec length ;Done with string?
|
|
bne match_loop ;Nope, so loop.
|
|
*
|
|
* Yes, so get file type, restore 16 bit accumulator and exit...
|
|
*
|
|
ply ;Recover offset.
|
|
iny ;Point to file type.
|
|
lda [map_ptr],y ;Get file type.
|
|
|
|
longa on ;Restore 16 bit A.
|
|
exit rep #$20
|
|
|
|
and #$00ff ;Clear high byte.
|
|
unknown tax ;Put file type in X.
|
|
ply ;Recover Y.
|
|
rts ;Exit.
|
|
*
|
|
* No, so let's point to the next record and loop...
|
|
*
|
|
next_record ply ;Recover offset.
|
|
iny ;Point to file type.
|
|
iny ;Point to next record.
|
|
bra record_loop ;Loop.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: write_protect
|
|
*
|
|
* Description: A common handler for all calls which require writing to disk.
|
|
* Will call process_path, and if successful, will return a
|
|
* drvr_wr_prot error. Always returns an error.
|
|
*
|
|
* Created: Dec 14, 1987
|
|
* Modified: Dec 14, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = error code
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* process_path
|
|
*
|
|
******************************************************************************
|
|
|
|
write_protect proc
|
|
with data
|
|
|
|
*
|
|
* Go look for the requested file. Found?
|
|
*
|
|
jsr process_path ;Go find it.
|
|
bcs exit ;Error, so exit.
|
|
*
|
|
* Yes, but we can't write, so exit with write protect error...
|
|
*
|
|
lda #drvr_wr_prot ;Get error code.
|
|
sec ;Indicate error.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: create
|
|
*
|
|
* Description: Removes any filename from pathname then jumps to write_protect.
|
|
*
|
|
* Created: May 2, 1988
|
|
* Modified: May 2, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = error code
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* write_protect
|
|
*
|
|
******************************************************************************
|
|
|
|
create proc
|
|
with data
|
|
|
|
*
|
|
* Decrement name_count if it is greater than 0, then jump to write_protect...
|
|
*
|
|
lda name_count ;Get count. Zero?
|
|
beq jump ;Yep.
|
|
dec name_count ;Nope, so decrement it by one.
|
|
jump jmp write_protect
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_file_info
|
|
*
|
|
* Description: Returns information about a file or directory.
|
|
*
|
|
* Created: Nov 3, 1987
|
|
* Modified: Nov 3, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* process_path (sub)
|
|
* send_output (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
get_file_info proc
|
|
with data
|
|
|
|
*
|
|
* Go find the file requested...
|
|
*
|
|
jsr process_path ;Go find it.
|
|
bcs error ;Error.
|
|
*
|
|
* Send the parameters back and exit...
|
|
*
|
|
jsr send_output ;Send 'em.
|
|
error rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: volume
|
|
*
|
|
* Description: Returns volume information from a High Sierra disk.
|
|
*
|
|
* Created: Oct 6, 1987
|
|
* Modified: Feb 7, 1991
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* id_disk (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
volume proc
|
|
with data
|
|
|
|
*
|
|
* Now ID the disk. Is it a High Sierra disk?
|
|
*
|
|
lda #in_cache ;Force block into cache.
|
|
sta drvr_cache
|
|
|
|
lda dev_num ;Get device # from zp.
|
|
jsr id_disk ;See if it's my kind of disk.
|
|
bcs got_error ;branch if we got an error
|
|
*
|
|
* Yes, so send the output parameters...
|
|
*
|
|
jsr send_output ;Send 'em.
|
|
*
|
|
* Set cache back to default value and exit...
|
|
*
|
|
export SET_USER_CACHE
|
|
set_user_cache ;
|
|
|
|
pha ;Save A.
|
|
lda cache_priority ;Get user setting.
|
|
sta drvr_cache ;Set cache value.
|
|
pla ;Recover A.
|
|
rts ;Exit
|
|
|
|
*
|
|
* We got an error from id_disk.
|
|
* If the error is "dup_volume" then we need to force the "vol_name" output parameter
|
|
* to be setup even though we're returning an error.
|
|
*
|
|
got_error cmp #dup_volume ;duplicate volume error?
|
|
bne error ;no - so we're done
|
|
|
|
ldy #4 ;get class 0 offset to the volname param
|
|
lda class ;get call class
|
|
beq doit ;branch if doing class 0
|
|
iny ;adjust param offset for class 1
|
|
iny
|
|
doit jsr h_vol_name ;setup the volname output param
|
|
bcs set_user_cache ;return output buffer errors
|
|
lda #dup_volume ;restore the dup_volume error
|
|
error sec ;indicate error
|
|
bra set_user_cache ;and exit
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: id_disk
|
|
*
|
|
* Description: Determines whether or not the media chosen is in High Sierra
|
|
* or ISO format. If so and there is no VCR for it, one is
|
|
* created; if there is a VCR then it is marked active.
|
|
*
|
|
* Created: Oct 7, 1987
|
|
* Author: Bryan Atsatt
|
|
* Modified: Feb 22, 1989 Added check for drvr_bad_block error.
|
|
* Oct 10, 1989 CAF. Added check for drvr_disk_sw error.
|
|
* Aug 8, 1990 MSD. Removed Cary's check for drvr_disk_sw.
|
|
* The device_dispatch routine now has a special
|
|
* case for drvr_disk_sw during id_disk.
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = device number
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* gstring ;holds volume name.
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
*
|
|
* Uses: all registers
|
|
* id_disk_flag
|
|
* gstring
|
|
* temp0
|
|
* temp1
|
|
* drvr_dev_num
|
|
* drvr_call_num
|
|
* dev_id_ref
|
|
* drvr_dib_ptr
|
|
* sector_read (sub)
|
|
* build_vcr (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
id_disk proc
|
|
with data
|
|
|
|
*
|
|
* Save current device, init state_flag to 0 (high sierra), and make sure
|
|
* id_disk_flag is clear...
|
|
*
|
|
sta current_dev ;Save device #.
|
|
stz state_flag ;Clear state_flag.
|
|
stz id_disk_flag ;Clear id_disk_flag.
|
|
*
|
|
* Read in sector with id_disk_flag set, clear flag, then exit if error...
|
|
*
|
|
ldx #vol_start ;Init to volume start.
|
|
|
|
try_next stx sector_number ;Save low word of sector #.
|
|
lda #0 ;Get high word of sector #.
|
|
ldy current_dev ;Get driver number.
|
|
sty drvr_dev_num ;Set driver number.
|
|
|
|
inc id_disk_flag ;Set id_disk_flag.
|
|
jsr sector_read ;Read in the data.
|
|
stz id_disk_flag ;Clear flag.
|
|
bcc do_id ;Continue if no error.
|
|
cmp #drvr_bad_block ;Error. Is volume too small?
|
|
bne return_error ;Nope, some other error.
|
|
lda #unknown_vol ;Yes, so make into a bouncer.
|
|
return_error sec ;Re-set carry.
|
|
rts ;Exit.
|
|
*
|
|
* Ok, now look at the Volume Structure Standard Identifier.
|
|
* Is it 'CDROM' (High Sierra)?
|
|
*
|
|
longa off ;Set 8 bit A.
|
|
do_id sep #$20
|
|
|
|
ldx #4 ;Point to end of string.
|
|
ldy #vol_id_end_0 ;Point to end of identifier.
|
|
check_hs lda [io_buffer],y ;Get byte.
|
|
cmp hs_string,x ;Match?
|
|
bne iso ;Nope, so not High Sierra.
|
|
dey ;Yes, done all?
|
|
dex
|
|
bpl check_hs ;No, so loop.
|
|
bra high_sierra ;Yes, so it's High Sierra.
|
|
*
|
|
* No, is it 'CD001' (ISO)?
|
|
*
|
|
iso ldx #4 ;Point to end of string.
|
|
ldy #vol_id_end_1 ;Point to end of identifier.
|
|
check_iso lda [io_buffer],y ;Get byte.
|
|
cmp iso_string,x ;Match?
|
|
bne unknown_hop ;Nope, so not ISO either.
|
|
dey ;Yes, done all?
|
|
dex
|
|
bpl check_iso ;No, so loop.
|
|
*
|
|
* We have an ISO disk, so set the iso_bit in the state_flag. Is the Volume
|
|
* Structure Standard Version correct?
|
|
*
|
|
lda state_flag ;Get flag.
|
|
ora #iso_bit ;Set ISO bit.
|
|
sta state_flag ;Save flag.
|
|
|
|
ldy #vol_version_1 ;Point to version.
|
|
lda [io_buffer],y ;Get byte.
|
|
cmp #1 ;Is it a 1?
|
|
bne unknown_hop ;Nope, so not ISO.
|
|
*
|
|
* Yes. Is this a Standard File Structure Volume Descriptor?
|
|
*
|
|
ldy #vol_type_1 ;Point at type.
|
|
lda [io_buffer],y ;Get byte.
|
|
cmp #1 ;Is it a 1?
|
|
bne not_standard ;Nope, so it's not standard.
|
|
*
|
|
* Yes. Is the Logical Block Size either 512, 1024, or 2048 bytes?
|
|
*
|
|
ldy #vol_blk_size_1 ;Point at block size.
|
|
lda [io_buffer],y ;Get low byte of size.
|
|
bne unknown ;Unknown if not zero.
|
|
iny ;Point to high byte.
|
|
lda [io_buffer],y ;Get high byte.
|
|
cmp #>2048 ;2k?
|
|
beq chk_file_ver_1 ;Yep, so ok.
|
|
cmp #>1024 ;1k?
|
|
beq chk_file_ver_1 ;Yep, so ok.
|
|
cmp #>512 ;Nope, 512?
|
|
bne unknown ;Nope, so unknown.
|
|
*
|
|
* Yes. Is the File Structure Standard Version correct?
|
|
*
|
|
chk_file_ver_1 ldy #vol_file_ver_1 ;Point to file version.
|
|
lda [io_buffer],y ;Get byte.
|
|
beq check_id ;Ok if zero.
|
|
cmp #1 ;Is it a 1?
|
|
bne unknown ;Nope, so not an ISO disk either.
|
|
*
|
|
* Yes, so we have an ISO disk. See if disk conforms to Apple Extensions, and/or
|
|
* if it is an XA disc, then continue...
|
|
*
|
|
check_id ldy #vol_sys_id_1 ;Get offset to iso sys_id.
|
|
jsr check_apple_ext ;Check for Apple Extensions.
|
|
jsr check_xa ;Check for CD-ROM XA disc.
|
|
bra got_one ;Continue.
|
|
*
|
|
* We have a High Sierra disk. Is the Volume Structure Standard Version
|
|
* correct?
|
|
*
|
|
high_sierra ldy #vol_version_0 ;Point to version.
|
|
lda [io_buffer],y ;Get byte.
|
|
cmp #1 ;Is it a 1?
|
|
bne unknown ;Nope, so not High Sierra.
|
|
*
|
|
* Yes. Is this a Standard File Structure Volume Descriptor?
|
|
*
|
|
ldy #vol_type_0 ;Point at type.
|
|
lda [io_buffer],y ;Get byte.
|
|
cmp #1 ;Is it a 1?
|
|
bne not_standard ;Nope.
|
|
*
|
|
* Yes. Is the Logical Block Size either 512, 1024, or 2048 bytes?
|
|
*
|
|
ldy #vol_blk_size_0 ;Point at block size.
|
|
lda [io_buffer],y ;Get low byte of size.
|
|
bne unknown ;Unknown if not zero.
|
|
iny ;Point to high byte.
|
|
lda [io_buffer],y ;Get high byte.
|
|
cmp #>2048 ;2k?
|
|
beq chk_file_ver_0 ;Yep, so ok.
|
|
cmp #>1024 ;1k?
|
|
beq chk_file_ver_0 ;Yep, so ok.
|
|
cmp #>512 ;Nope, 512?
|
|
bne unknown ;Nope, so unknown.
|
|
*
|
|
* Yes. Is the File Structure Standard Version correct?
|
|
*
|
|
chk_file_ver_0 ldy #vol_file_ver_0 ;Point to file version.
|
|
lda [io_buffer],y ;Get byte.
|
|
beq got_one ;Ok if zero.
|
|
cmp #1 ;Is it a 1?
|
|
unknown_hop bne unknown ;Nope, so not High Sierra.
|
|
*
|
|
* Yes, so we have a High Sierra disk. See if disk conforms to Apple Extensions
|
|
* then continue...
|
|
*
|
|
ldy #vol_sys_id_0 ;Get offset to high sierra sys_id.
|
|
jsr check_apple_ext ;Check for Apple Extensions.
|
|
bra got_one ;Continue.
|
|
|
|
|
|
*
|
|
* It looks like we've got a High Sierra or ISO disk but we're not
|
|
* looking at the Standard File Volume Descriptor. Bump the sector # and
|
|
* loop back to start if this is not the Volume Descriptor Sequence Terminator.
|
|
* If it is the terminator, then we can't ID disk...
|
|
*
|
|
longa on ;Restore 16 bit A.
|
|
not_standard rep #$20
|
|
|
|
and #$00ff ;Clear high byte.
|
|
cmp #vol_terminator ;Is this a terminator type?
|
|
beq unknown ;Yes, so we can't ID the disk.
|
|
|
|
ldx sector_number ;Nope, get sector #.
|
|
inx ;Bump it one.
|
|
brl try_next ;Try next one.
|
|
*
|
|
* Not a High Sierra or ISO disk. Exit with unknown volume error...
|
|
*
|
|
longa on ;First restore 16 bit A.
|
|
unknown rep #$20
|
|
|
|
lda #unknown_vol ;Get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit to caller.
|
|
*
|
|
* Ok, we've got a High Sierra disk and we're looking at the Standard File
|
|
* Volume Descriptor. Exit through build_vcr...
|
|
*
|
|
longa on ;Restore 16 bit A.
|
|
got_one rep #$20
|
|
|
|
jmp build_vcr ;Exit thru build_vcr.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: check_apple_ext
|
|
*
|
|
* Description: Sets state_flag Apple Extensions and ProDOS Transformation bits
|
|
* if present.
|
|
*
|
|
* Created: July 8, 1988
|
|
* Modified: July 8, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* NOTE: This routine must be entered with 8 bit Accumulator!
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = offset to system identifier field in volume descriptor.
|
|
* P = nvmxdizc
|
|
* ..100...
|
|
* B = K
|
|
*
|
|
* io_buffer ;points to volume header
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 0
|
|
* ;b2 = 0
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: state_flag
|
|
*
|
|
******************************************************************************
|
|
|
|
check_apple_ext proc
|
|
with data
|
|
|
|
longa off
|
|
*
|
|
* Does this disk conform to the Apple Extensions?
|
|
*
|
|
ldx #0 ;Point to start of apple_string.
|
|
id_loop lda [io_buffer],y ;Get byte.
|
|
cmp apple_string,x ;Match?
|
|
bne exit ;Nope, so exit.
|
|
iny ;Yes, bump offsets.
|
|
inx
|
|
cpx #apple_str_len ;Reached end?
|
|
bne id_loop ;Nope, so loop.
|
|
*
|
|
* Yes, so put ProDOS Filename Transformation bit into state_flag and set the
|
|
* apple_bit then exit...
|
|
*
|
|
lda [io_buffer],y ;Get byte.
|
|
and #prodos_format ;Isolate prodos transformation bit.
|
|
asl a ;Shift it to prodos_bit position.
|
|
asl a
|
|
ora #apple_bit ;Add apple_bit.
|
|
ora state_flag ;Add to current state_flag.
|
|
sta state_flag ;Save it.
|
|
exit rts ;Exit.
|
|
|
|
longa on
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: check_xa
|
|
*
|
|
* Description: Sets state_flag xa_bit if this is a CD-ROM XA disc.
|
|
*
|
|
* Created: Apr 6, 1989
|
|
* Modified: Apr 6, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* NOTE: This routine must be entered with 8 bit Accumulator!
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..100...
|
|
* B = K
|
|
*
|
|
* io_buffer ;points to volume header
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
* ;b3 = 0
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
* ;b3 = 1 of CD-ROM XA disc.
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: state_flag
|
|
*
|
|
******************************************************************************
|
|
|
|
check_xa proc
|
|
with data
|
|
|
|
longa off
|
|
*
|
|
* Is this a CD-ROM XA disc?
|
|
*
|
|
ldx #0 ;Point to start of xa_string.
|
|
ldy #vol_xa_label_1 ;Point to label area.
|
|
id_loop lda [io_buffer],y ;Get byte.
|
|
cmp xa_string,x ;Match?
|
|
bne exit ;Nope, so exit.
|
|
iny ;Yes, bump offsets.
|
|
inx
|
|
cpx #xa_str_len ;Reached end?
|
|
bne id_loop ;Nope, so loop.
|
|
*
|
|
* Yes, so set xa_bit in state_flag and exit...
|
|
*
|
|
lda state_flag ;Get current flags.
|
|
ora #xa_bit ;Add to current state_flag.
|
|
sta state_flag ;Save it.
|
|
exit rts ;Exit.
|
|
|
|
longa on
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: build_vcr
|
|
*
|
|
* Description: Creates a new VCR if needed. If already present, it is
|
|
* marked active. Checks for duplicate volumes.
|
|
*
|
|
* NOTE: Should only be called by id_disk!!
|
|
*
|
|
* Created: Oct 8, 1987
|
|
* Modified: July 21, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* io_buffer ;points to volume header
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to vcr.
|
|
* path_table ;points to path table.
|
|
* log_blk_size ;size of logical blocks for this disc.
|
|
* real_log_size ;copy of log_blk_size.
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* id_disk_flag
|
|
* my_vcr
|
|
* length
|
|
* temp0
|
|
* temp1
|
|
* set_file_system (sub)
|
|
* make_gstring (sub)
|
|
* block_read (sub)
|
|
* activate_vcr (sub)
|
|
* transform_name (sub)
|
|
* alloc_vcr (sys service)
|
|
* release_vcr (sys service)
|
|
* find_vcr (sys service)
|
|
* deref (sys service)
|
|
*
|
|
******************************************************************************
|
|
|
|
build_vcr proc
|
|
with data
|
|
|
|
*
|
|
* Set file system variables...
|
|
*
|
|
jsr set_file_system ;Set up for ISO or High Sierra.
|
|
*
|
|
* Make a gstring from volume name and transform if needed....
|
|
*
|
|
lda vol_id_start ;Get offset to start of name.
|
|
ldy vol_id_len ;Get length of name.
|
|
jsr make_gstring ;Make gstring.
|
|
lda #$2e5f ;Replace underscores with periods.
|
|
jsr transform_gstring
|
|
*
|
|
* Do we already have a VCR with this name?
|
|
*
|
|
lda #0000 ;Select search by name.
|
|
ldx #gstring ;Get pointer to volume name.
|
|
ldy #^gstring
|
|
jsl find_vcr ;Do search. Found?
|
|
bcs new_vcr ;Nope.
|
|
*
|
|
* Yes, does it belong to me?
|
|
*
|
|
jsl deref ;Yes, dereference VP.
|
|
stx my_vcr ;Save pointer.
|
|
sty my_vcr+2
|
|
|
|
ldy #vcr_fst_id ;Get offset to id.
|
|
lda [my_vcr],y ;Get id.
|
|
cmp #hs_id ;Is it mine?
|
|
bne check_active ;No, check if we can toss it.
|
|
*
|
|
* Yes, does the volume creation date & time match that in the vcr?
|
|
*
|
|
ldy vol_create_dt ;Get offset to create date & time.
|
|
ldx #vcr_create_dt ;Get offset into vcr.
|
|
lda vol_dt_len ;Get length of create + mod fields.
|
|
sta length ;Save it.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
cmp_loop lda [io_buffer],y ;Get byte.
|
|
sty vol_offset ;Save vol offset.
|
|
txy ;Get offset to vcr.
|
|
cmp [my_vcr],y ;Does it match?
|
|
bne check_active ;Nope, so see if it's active.
|
|
ldy vol_offset ;Yes, recover vol offset.
|
|
iny ;Bump it.
|
|
inx ;Bump vcr offset.
|
|
dec length ;Done all?
|
|
bne cmp_loop ;Nope, so loop.
|
|
|
|
longa on ;Set 16 bit A.
|
|
rep #$20
|
|
*
|
|
* Yes, so this is the same volume. Update the last known device,
|
|
* put state_flag in vcr, mark vcr as active and exit with the carry clear...
|
|
*
|
|
ldy #vcr_dev ;Get offset to device number.
|
|
lda drvr_dev_num ;Get device.
|
|
sta [my_vcr],y ;Update vcr.
|
|
|
|
ldy #vcr_state_flag ;Get offset to state_flag.
|
|
lda state_flag ;Get flag.
|
|
sta [my_vcr],y ;Save state word.
|
|
|
|
brl do_activate ;Continue.
|
|
*
|
|
* Exit with duplicate volume error...
|
|
*
|
|
duplicate lda #dup_volume ;Get error code.
|
|
sec ;Indicate error.
|
|
error_exit rts ;Exit.
|
|
*
|
|
* No, so we have a duplicate volume. If there are no open files then
|
|
* release the vcr and build a new one, otherwise exit with a duplicate
|
|
* volume error...
|
|
*
|
|
longa on ;Set 16 bit A.
|
|
check_active rep #$20
|
|
|
|
ldy #vcr_open_cnt ;Get offset to open count.
|
|
lda [my_vcr],y ;Any open?
|
|
bne duplicate ;Yes, so exit with error.
|
|
lda [my_vcr] ;Nope, get the volume ID.
|
|
jsl release_vcr ;Release vcr.
|
|
*
|
|
* Ok, we need to make a new vcr. First calculate size of vcr...
|
|
*
|
|
new_vcr ldy vol_path_size ;Get offset to path table size.
|
|
lda [io_buffer],y ;Get size.
|
|
sta path_table_size ;Save it.
|
|
sta path_size ;And again.
|
|
|
|
*** changed 2-Dec-92 DAL -- size of VCR is now a constant
|
|
;;; clc ;Add offset to path table.
|
|
;;; adc #vcr_path_table
|
|
lda #our_vcr_size
|
|
*** end 2-Dec-92
|
|
|
|
*
|
|
* Now allocate new vcr...
|
|
*
|
|
ldx #gstring ;Point to volume name.
|
|
ldy #^gstring
|
|
jsl alloc_vcr ;Allocate new vcr. Ok?
|
|
bcc alloc_ok ;Yes.
|
|
*
|
|
* Couldn't allocate. Exit with out of memory error...
|
|
*
|
|
lda #out_of_mem ;Get error code.
|
|
rts ;Exit.
|
|
*
|
|
* Fill in all the fields...
|
|
*
|
|
alloc_ok jsl deref ;Dereference vp.
|
|
stx my_vcr ;Save pointer.
|
|
sty my_vcr+2
|
|
|
|
*** added 2-Dec-92 DAL -- zero the path_tbl_handle field, in case we can't get the handle later
|
|
ldy #vcr_path_tbl_handle+2
|
|
lda #0
|
|
sta [my_vcr],y
|
|
dey
|
|
dey
|
|
sta [my_vcr],y
|
|
*** end 2-Dec-92
|
|
|
|
ldy #vcr_status ;Get offset to status.
|
|
lda #vcr_swapped ;Init to swapped.
|
|
sta [my_vcr],y
|
|
|
|
ldy #vcr_fst_id ;Get offset to fst id.
|
|
lda #hs_id ;Get id.
|
|
sta [my_vcr],y ;Save it.
|
|
|
|
ldy #vcr_dev ;Get offset to device.
|
|
lda drvr_dev_num ;Get current device.
|
|
sta [my_vcr],y ;Save it.
|
|
|
|
ldy vol_space_size ;Get offset to low word of size.
|
|
tyx ;Save it.
|
|
lda [io_buffer],y ;Get it.
|
|
ldy #vcr_total_blks ;Get offset to vcr.
|
|
sta [my_vcr],y ;Send low word.
|
|
txy ;Recover offset to low word of size.
|
|
iny ;Point to high word.
|
|
iny
|
|
lda [io_buffer],y ;Get it.
|
|
ldy #vcr_total_blks+2 ;Get offset to vcr.
|
|
sta [my_vcr],y ;Send high word.
|
|
|
|
ldy vol_block_size ;Get offset to block size.
|
|
lda [io_buffer],y ;Get it.
|
|
ldy #vcr_block_size ;Get offset into vcr.
|
|
sta [my_vcr],y ;Save it.
|
|
sta log_blk_size ;Set new log_blk_size.
|
|
sta real_log_size ;Set new real_log_size .
|
|
|
|
ldy #vcr_path_size ;Get offset to path table size.
|
|
lda path_table_size ;Get size.
|
|
sta [my_vcr],y ;Save it.
|
|
|
|
ldy vol_root_dir ;Get offset to root directory entry.
|
|
ldx #vcr_root_dir ;Get offset into vcr.
|
|
lda vol_root_len ;Get length of root dir.
|
|
sta length ;Save it.
|
|
dir_loop lda [io_buffer],y ;Get byte.
|
|
sty vol_offset ;Save vol offset.
|
|
txy ;Get offset to vcr.
|
|
sta [my_vcr],y ;Put byte in vcr.
|
|
ldy vol_offset ;Recover vol offset.
|
|
iny ;Bump it.
|
|
inx ;Bump vcr offset.
|
|
dec length ;Done all?
|
|
bne dir_loop ;Nope, so loop.
|
|
|
|
ldy vol_create_dt ;Get offset to create date & time.
|
|
ldx #vcr_create_dt ;Get offset into vcr.
|
|
lda vol_dt_len ;Get length of create + mod fields.
|
|
sta length ;Save it.
|
|
dt_loop lda [io_buffer],y ;Get byte.
|
|
sty vol_offset ;Save vol offset.
|
|
txy ;Get offset to vcr.
|
|
sta [my_vcr],y ;Put byte in vcr.
|
|
ldy vol_offset ;Recover vol offset.
|
|
iny ;Bump it.
|
|
inx ;Bump vcr offset.
|
|
dec length ;Done all?
|
|
bne dt_loop ;Nope, so loop.
|
|
|
|
ldy #vcr_state_flag ;Get offset to state_flag.
|
|
lda state_flag ;Get flag.
|
|
sta [my_vcr],y ;Put flag in vcr.
|
|
|
|
*** changed 2-Dec-92 DAL -- allocate a Memory Manager handle for the path table
|
|
;*
|
|
;* Now, we need to append the path table to the vcr. First make a
|
|
;* pointer to the path table...
|
|
;*
|
|
; clc ;Prepare to add.
|
|
; lda #vcr_path_table ;Get offset to path table.
|
|
; adc my_vcr ;Add to my_vcr ptr.
|
|
; sta path_table ;Save low word of pointer.
|
|
; lda #0 ;Do high word.
|
|
; adc my_vcr+2
|
|
; sta path_table+2
|
|
|
|
pha
|
|
pha ;space for NewHandle
|
|
pea 0 ;high word of size
|
|
lda path_table_size
|
|
pha ;low word of size
|
|
pha ;space for User ID
|
|
_MMStartUp ;use same User ID as our code (leave on stack)
|
|
pea $8000 ;handle initially locked
|
|
pha
|
|
pha ;garbage (ignored)
|
|
_NewHandle
|
|
plx
|
|
ply
|
|
bcs error
|
|
|
|
pei <path_ptr+2 ;preserve & use temporarily
|
|
pei <path_ptr
|
|
|
|
stx <path_ptr
|
|
sty <path_ptr+2
|
|
|
|
ldy #2
|
|
lda [<path_ptr],y
|
|
sta path_table+2
|
|
lda [<path_ptr]
|
|
sta path_table
|
|
|
|
ldy #vcr_path_tbl_handle+2
|
|
lda <path_ptr+2
|
|
sta [my_vcr],y
|
|
sta current_path_tbl_handle+2
|
|
dey
|
|
dey
|
|
lda <path_ptr
|
|
sta [my_vcr],y
|
|
sta current_path_tbl_handle
|
|
|
|
pla
|
|
sta <path_ptr
|
|
pla
|
|
sta <path_ptr+2
|
|
*** end 2-Dec-92
|
|
|
|
*
|
|
* Get the block number...
|
|
*
|
|
ldy vol_path_loc ;Get offset to path table location.
|
|
lda [io_buffer],y ;Get low word.
|
|
tax
|
|
iny ;Point to high word.
|
|
iny
|
|
lda [io_buffer],y ;Get high word.
|
|
*
|
|
* Set id_disk_flag, read in one block, clear id_disk_flag and exit if error...
|
|
*
|
|
read_loop inc id_disk_flag ;Set flag.
|
|
jsr block_read ;Do read.
|
|
stz id_disk_flag ;Clear flag. Read ok?
|
|
bcs error ;Nope.
|
|
*
|
|
* Append path_size bytes to path_table. Did we run out of data in the
|
|
* buffer?
|
|
*
|
|
ldy #0 ;Init offset.
|
|
append_loop lda [io_buffer],y ;Get byte.
|
|
sta [path_table],y ;Appen to vcr.
|
|
iny ;Bump offset.
|
|
iny
|
|
cpy log_blk_size ;Run out of buffer?
|
|
bcs read_more ;Yep.
|
|
cpy path_size ;No, moved all?
|
|
bcc append_loop ;No, so loop.
|
|
*
|
|
* No, activate_vcr and exit with carry clear...
|
|
*
|
|
do_activate jsr activate_vcr ;Activate it.
|
|
clc ;Clear carry.
|
|
rts ;Exit.
|
|
*
|
|
* Yes, adjust path_size, adjust path_table, bump block # and loop...
|
|
*
|
|
read_more sec ;Adjust path_size.
|
|
lda path_size
|
|
sbc log_blk_size
|
|
sta path_size
|
|
|
|
clc ;Adjust path_table.
|
|
lda path_table
|
|
adc log_blk_size
|
|
sta path_table
|
|
lda path_table+2
|
|
adc #0
|
|
sta path_table+2
|
|
|
|
ldx drvr_blk_num ;Get block #.
|
|
lda drvr_blk_num+2
|
|
inx ;Bump it.
|
|
bne read_loop ;Loop if didn't rollover.
|
|
inc a ;Rollover. Bump high word.
|
|
bra read_loop ;Loop.
|
|
*
|
|
* An error occured, free the vcr before exiting...
|
|
*
|
|
error pha ;Nope, save error code.
|
|
lda [my_vcr] ;Get the volume ID.
|
|
jsl release_vcr ;Release vcr.
|
|
pla ;Recover the error.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: set_file_system
|
|
*
|
|
* Description: Copies either hs_offsets or iso_offsets into file_sys_table.
|
|
*
|
|
* Created: Feb 26, 1988
|
|
* Modified: Mar 23, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* state_flag ;b0 = 1 if ISO version of High Sierra.
|
|
* ;b1 = 1 if Apple Extensions disc.
|
|
* ;b2 = 1 if ProDOS Transformation required.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
*
|
|
******************************************************************************
|
|
|
|
set_file_system proc
|
|
with data
|
|
|
|
*
|
|
* High Sierra or ISO?
|
|
*
|
|
ldy #file_sys_len ;Get length of table.
|
|
|
|
lda state_flag ;Get flag.
|
|
and #iso_bit ;Iso?
|
|
bne iso_loop ;Yes.
|
|
*
|
|
* High Sierra, so copy hs_offsets into file_sys_table...
|
|
*
|
|
hs_loop lda hs_offsets,y ;Get word.
|
|
sta file_sys_table,y ;Put in table.
|
|
dey ;Done all?
|
|
dey
|
|
bpl hs_loop ;Nope, so loop.
|
|
rts ;Yes, so exit.
|
|
*
|
|
* ISO, so copy iso_offsets into file_sys_table...
|
|
*
|
|
iso_loop lda iso_offsets,y ;Get word.
|
|
sta file_sys_table,y ;Put in table.
|
|
dey ;Done all?
|
|
dey
|
|
bpl iso_loop ;Nope, so loop.
|
|
rts ;Yes, so exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: open
|
|
*
|
|
* Description: Opens file or directory and prepares for reading. Will build
|
|
* a new FCR if none exists.
|
|
*
|
|
* Created: Oct 20, 1987
|
|
* Modified: Oct 20, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* process_path
|
|
* build_fcr
|
|
* send_output
|
|
*
|
|
******************************************************************************
|
|
|
|
open proc
|
|
with data
|
|
|
|
*
|
|
* First go find the file requested...
|
|
*
|
|
jsr process_path ;Go find it.
|
|
bcs error ;Error.
|
|
*
|
|
* Now build the FCR if necessary...
|
|
*
|
|
jsr build_fcr ;Build fcr.
|
|
bcs error ;Error.
|
|
*
|
|
* Ok, we've opened the file. Send the output parameters and exit...
|
|
*
|
|
jsr send_output ;Send 'em.
|
|
error rts
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: process_path
|
|
*
|
|
* Description: Find location of file using full pathname. Will make sure
|
|
* that volume is online.
|
|
*
|
|
* Created: Oct 20, 1987
|
|
* Modified: Mar 5, 1991
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* dev_num ;holds device number if used.
|
|
* volume_name ;holds volume name.
|
|
* file_name ;holds file name.
|
|
* name_count ;# of names in path.
|
|
* name_offsets ;offsets to start of names in path.
|
|
* input_error ;set if input error.
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* storage_type ;1=file, 5=extended file, D=directory,
|
|
* or F=volume directory.
|
|
* dir_record_0 ;holds directory record.
|
|
* dir_record_1 ;holds associated dir record (if any).
|
|
* eof ;eof from dir_record_0.
|
|
* blocks_used ;blocks_used from dir_record_0.
|
|
* resource_eof ;eof from dir_record_1.
|
|
* resource_blocks ;blocks_used from dir_record_1.
|
|
* error_priority ;$8000 if we found the specified volume
|
|
*
|
|
* Uses: All registers
|
|
* find_a_vcr (sub)
|
|
* id_disk (sub)
|
|
* find_volume (sub)
|
|
* find_file (sub)
|
|
* get_dir_info (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
process_path proc
|
|
with data
|
|
|
|
*
|
|
* Clear out dir_record_0 and dir_record_1...
|
|
*
|
|
jsr clear_dir_recs ;Clear them.
|
|
*
|
|
* Make sure that all blocks read are cached...
|
|
*
|
|
lda #in_cache ;Cache 'em.
|
|
sta drvr_cache
|
|
*
|
|
* Do we have a device number or a volume name?
|
|
*
|
|
lda dev_num ;Is there a device #?
|
|
beq by_name ;No, so find by name.
|
|
*
|
|
* Device number. Do we have a vcr for it?
|
|
*
|
|
sta drvr_dev_num ;Set device number.
|
|
jsr find_a_vcr ;Do we have a vcr?
|
|
bcc check_file ;Yes.
|
|
*
|
|
* Nope, so id the disk. Exit if it's not mine, else continue on to
|
|
* check_file...
|
|
*
|
|
lda dev_num ;Get device #.
|
|
jsr id_disk ;Is it mine?
|
|
bcs error ;Nope, so exit.
|
|
bra check_file ;Yes.
|
|
*
|
|
* We have a volume name. Try to find the volume using volume_name...
|
|
*
|
|
by_name jsr find_volume ;Look for volume. Found?
|
|
bcs error ;Nope, so exit.
|
|
*
|
|
* Ok, we have the volume and my_vcr points to the vcr. Go find the file
|
|
* or directory. Found?
|
|
*
|
|
check_file lda #$8000 ;indicate that we found the volume
|
|
sta error_priority ;and it's my volume
|
|
; Begin 18-Dec-91 MSD: Make sure the maximum span is less than 32
|
|
; If not, return a bad path syntax error.
|
|
lda span1
|
|
cmp #32
|
|
bcc ok_path
|
|
lda #bad_path_syntax
|
|
bra error ; note: carry already set!
|
|
ok_path
|
|
; End 18-Dec-91 MSD
|
|
jsr find_file ;Go look for it. All ok?
|
|
bcs error ;Nope, so exit.
|
|
*
|
|
* Yes, so call get_dir_info and clear carry...
|
|
*
|
|
jsr get_dir_info ;Get parameters.
|
|
clc ;Indicate success.
|
|
*
|
|
* Restore user cache value. And exit if carry set. If clear and
|
|
* input_error set, exit with input_error...
|
|
*
|
|
error jsr set_user_cache ;Restore user cache value.
|
|
|
|
bcs check_error ;Exit if error.
|
|
lda input_error ;Was there an input error?
|
|
beq check_error ;Nope.
|
|
sec ;Yes, indicate error.
|
|
*
|
|
* If we have a path_not_found error and resource_num is non-zero, change
|
|
* the error to res_not_found...
|
|
*
|
|
check_error bcc exit ;No error, so exit.
|
|
cmp #path_not_found ;Path not found error?
|
|
beq check_resource ;Yes, so check for resource.
|
|
cmp #file_not_found ;No, file not found error?
|
|
sec ;(make sure carry set).
|
|
bne exit ;No, so exit.
|
|
|
|
check_resource ldx resource_num ;Yes, looking for resource?
|
|
beq exit ;No, so exit.
|
|
lda #res_not_found ;Yes, get other error code.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: find_a_vcr
|
|
*
|
|
* Description: Looks for a vcr whose device # matches dev_num and whose
|
|
* id indicates that it belongs to me. Makes sure volume is
|
|
* online.
|
|
*
|
|
* Created: Oct 20, 1987
|
|
* Modified: Oct 20, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* dev_num ;device number to match.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = not found
|
|
* 0 = found
|
|
* B = K
|
|
*
|
|
* my_vcr ;Points to vcr if found.
|
|
*
|
|
* Uses: All registers
|
|
* temp0
|
|
* my_vcr
|
|
* setup_volume (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
find_a_vcr proc
|
|
with data
|
|
|
|
*
|
|
* Get vcr. Exit with carry set if checked all...
|
|
*
|
|
stz device ;Init to device 0.
|
|
|
|
loop inc device ;Bump device #
|
|
lda device ;Get it.
|
|
jsl get_vcr ;Get vcr.
|
|
bcc found_vcr ;Found.
|
|
rts ;Not found.
|
|
*
|
|
* Is this my vcr?
|
|
*
|
|
found_vcr jsl deref ;Dereference vp.
|
|
stx my_vcr ;Save pointer.
|
|
sty my_vcr+2
|
|
ldy #vcr_fst_id ;Get offset to fst id.
|
|
lda [my_vcr],y ;Get id.
|
|
cmp #hs_id ;Is it mine?
|
|
bne loop ;Nope, so loop.
|
|
*
|
|
* Yes, is it the right device #?
|
|
*
|
|
ldy #vcr_dev ;Get offset to device #.
|
|
lda [my_vcr],y ;Get #.
|
|
cmp dev_num ;Match?
|
|
bne loop ;Nope, so loop.
|
|
*
|
|
* Yes, exit thru setup_volume to make sure volume is online and setup some
|
|
* variables from the vcr...
|
|
*
|
|
jmp setup_volume ;Do setup.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: find_volume
|
|
*
|
|
* Description: Looks for a volume whose name matches that in volume_name.
|
|
* If there is a vcr, will do a status call and if the volume
|
|
* has not been switched will return with carry clear.
|
|
*
|
|
* Created: Oct 20, 1987
|
|
* Modified: July 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* volume_name ;volume name to match.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = not found
|
|
* 0 = found
|
|
* B = K
|
|
*
|
|
* drvr_dev_num ;device number found.
|
|
* my_vcr ;Points to vcr.
|
|
*
|
|
* Uses: All registers
|
|
* my_vcr
|
|
* current_device
|
|
* start_device
|
|
* find_vcr (sub)
|
|
* id_disk (sub)
|
|
* transform_name (sub)
|
|
* dev_dispatcher (sys_service)
|
|
*
|
|
******************************************************************************
|
|
|
|
find_volume proc
|
|
with data
|
|
|
|
*
|
|
* Initialize...
|
|
*
|
|
lda #0001 ;Init device to 1.
|
|
sta current_device
|
|
stz start_device ;Clear start device.
|
|
*
|
|
* Look for vcr with volume_name. Found?
|
|
*
|
|
ldx #volume_name ;Get pointer to volume name.
|
|
ldy #^volume_name
|
|
lda #0000 ;Search by name.
|
|
jsl find_vcr ;Do search. Found one?
|
|
bcs check_device ;Nope.
|
|
*
|
|
* Yep, is it mine? Exit with unknown_vol error if not...
|
|
*
|
|
jsl deref ;Dereference pointer..
|
|
stx my_vcr ;Save it.
|
|
sty my_vcr+2
|
|
ldy #vcr_fst_id ;Get offset to id.
|
|
lda [my_vcr],y ;Get id.
|
|
cmp #hs_id ;Is it mine?
|
|
beq get_device ;Yes.
|
|
lda #unknown_vol ;No, get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Yep, get device # and setup to check it first...
|
|
*
|
|
get_device ldy #vcr_dev ;Get offset to device #.
|
|
lda [my_vcr],y ;Get device #.
|
|
sta drvr_dev_num ;Set driver device number.
|
|
sta current_device ;Set current.
|
|
sta start_device ;Set start.
|
|
*
|
|
* Has the vcr been marked as switched?
|
|
*
|
|
ldy #vcr_status ;Get offset to status.
|
|
lda [my_vcr],y ;Get word.
|
|
and #vcr_swapped ;Swapped?
|
|
bne check_id ;Yes, so must do search.
|
|
*
|
|
* No, so fire off a status call then check again. This will ensure that we
|
|
* know if the volume has been taken offline. If it has not been switched, then
|
|
* we can rest assured that the volume is present...
|
|
*
|
|
lda #drvr_status ;Set status command.
|
|
sta drvr_call_num
|
|
stz drvr_stat_code ;Set to status code 0. (!8/12/88)
|
|
lda #status_list ;Set status list pointer.
|
|
sta drvr_slist_ptr
|
|
lda #^status_list
|
|
sta drvr_slist_ptr+2
|
|
lda #6 ;Set request count.
|
|
sta drvr_req_cnt
|
|
stz drvr_req_cnt+2
|
|
jsl dev_dispatcher ;Do call. Error?
|
|
bcs check_id ;Yes, so go do id.
|
|
lda status_list ;Get status word. (!8/12/88)
|
|
and #switched_mask ;Swapped? (!8/12/88)
|
|
bne check_id ;Yes, so go do id.
|
|
clc ;Nope, so exit with carry clear.
|
|
rts
|
|
*
|
|
* Main loop.
|
|
* Need to check this device?
|
|
*
|
|
check_device lda start_device ;Get start device.
|
|
cmp current_device ;Same as current?
|
|
beq next_device ;Yes, so skip it cuz we already did it.
|
|
*
|
|
* Yes, id disk. Any errors?
|
|
*
|
|
check_id lda current_device ;Get current device #.
|
|
jsr id_disk ;Do id. Ok?
|
|
bcc check_match ;Yes.
|
|
*
|
|
* Yes. If it's a disk switched error, let's re-try id_disk. While this may
|
|
* look like an infinite loop, it's not because this error only occurs once per
|
|
* media transition...
|
|
*
|
|
cmp #drvr_disk_sw ;Is it a disk switched?
|
|
bne not_disksw ;Nope.
|
|
lda current_device ;Yes, get current device number.
|
|
bra check_id ;Re-try id_disk.
|
|
*
|
|
* Not a disk switched. If it's a device not found or duplicate volume error
|
|
* then exit, otherwise continue search...
|
|
*
|
|
not_disksw cmp #dup_volume ;Duplicate volume?
|
|
beq error ;Yes, so exit.
|
|
cmp #invalid_dev_num ;Checked all?
|
|
bne no_match ;No, so continue search.
|
|
no_such_vol lda #vol_not_found ;Get error code.
|
|
error sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* No error from id_disk. Does the name match?
|
|
*
|
|
check_match lda #$2e5f ;Get search and replace characters.
|
|
ldx #volume_name ;Get string address.
|
|
ldy #^volume_name
|
|
jsr transform_name ;Do transform if needed.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
ldy gstring ;Get length.
|
|
iny ;Bump it one for length word.
|
|
compare_loop lda volume_name,y ;Get byte.
|
|
cmp gstring,y ;Match?
|
|
bne undo_it ;Nope.
|
|
dey ;Yes, done all?
|
|
bpl compare_loop ;No, so loop.
|
|
|
|
longa on ;Set 16 bit A.
|
|
rep #$20
|
|
*
|
|
* Yes, so we've got it. Exit with carry clear...
|
|
*
|
|
found clc ;Indicate found.
|
|
rts ;Exit.
|
|
*
|
|
* No, undo transformation if necessary...
|
|
*
|
|
longa on ;Set 16 bit A.
|
|
undo_it rep #$20
|
|
|
|
lda #$5f2e ;Get search and replace characters.
|
|
ldx #volume_name ;Get string address.
|
|
ldy #^volume_name
|
|
jsr transform_name ;Do transform if needed.
|
|
*
|
|
* No, reset current_device if this is the start_device...
|
|
*
|
|
no_match lda current_device ;Get current.
|
|
cmp start_device ;Same as start?
|
|
bne next_device ;Nope.
|
|
stz current_device ;Yes, so reset current.
|
|
*
|
|
* Bump current device and loop...
|
|
*
|
|
next_device inc current_device ;Bump current.
|
|
bra check_device ;Loop.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: find_file
|
|
*
|
|
* Description: Looks for a file whose name matches that in file_name.
|
|
*
|
|
* Created: Oct 21, 1987
|
|
* Modified: January 11, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to vcr.
|
|
* file_name ;file name to match.
|
|
* name_count ;# of names in pathname.
|
|
* name_offsets ;offsets to start of names.
|
|
* drvr_dev_num ;device # of volume.
|
|
* resource_num ;associated file flag.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = not found
|
|
* 0 = found
|
|
* B = K
|
|
*
|
|
* storage_type ;1=file, 5=extended file, D=directory,
|
|
* or F=volume directory.
|
|
* dir_record_0 ;holds directory record.
|
|
* dir_record_1 ;holds associated file record if
|
|
* ;present and we were not looking for
|
|
* ;an associated file.
|
|
*
|
|
* Uses: All registers
|
|
* storave_type
|
|
* dir_record_0
|
|
* dir_record_1
|
|
* record_offset
|
|
* dir_length
|
|
* eof
|
|
* length
|
|
* log_blk_size
|
|
* transform_in_f (sub)
|
|
* activate_vcr (sub)
|
|
* find_directory (sub)
|
|
* block_read (sub)
|
|
* move_dir_record (sub)
|
|
* search_dir (sub)
|
|
* read_next_block (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
find_file proc
|
|
with data
|
|
|
|
*
|
|
* First, make sure the vcr is activated and the path table parameters
|
|
* are set up...
|
|
*
|
|
jsr activate_vcr ;Do activate.
|
|
*
|
|
* Get location of directory, set start_block, and read it in...
|
|
*
|
|
jsr find_directory ;Go find it.
|
|
bcs error ;Exit on error.
|
|
stx start_block ;Save start block.
|
|
sta start_block+2
|
|
ldy #sector_size ;Set to read 2k.
|
|
jsr device_read ;Read in block.
|
|
bcs error ;Exit on error.
|
|
*
|
|
* Copy first directory record to dir_record_0 (in case there is no file),
|
|
* force directory bit in file_flags to 1 (cuz sometimes not set), clear invisible
|
|
* bit in file_flags (in case call is get_file_info on a directory), and set
|
|
* end_block...
|
|
*
|
|
lda #0 ;Select dir_record_0.
|
|
sta record_offset ;Clear offset.
|
|
jsr move_dir_record ;Move it.
|
|
|
|
ldx dir_file_flags ;Get offset to file_flags. (2/29/88)
|
|
lda dir_record_0,x ;Get flags.
|
|
ora #dir_mask ;Set directory bit.
|
|
and #clear_invisible ;Clear invisible bit.
|
|
sta dir_record_0,x ;Save flags.
|
|
|
|
stz interleave_size ;Clear interleave values.
|
|
stz interleave_skip
|
|
|
|
ldx dir_record_0+dir_data_length ;Get low word of length.
|
|
lda dir_record_0+dir_data_length+2 ;Get high word of length.
|
|
jsr set_end_block ;Set end_block...
|
|
*
|
|
* Are we looking for a directory?
|
|
*
|
|
lda storage_type ;Get type.
|
|
cmp #type_file ;Is it a file?
|
|
beq transform ;Yes.
|
|
*
|
|
* Yes, so force log_blk_size to 2k. If resource_num is clear then branch to
|
|
* found, else exit with path_not_found error...
|
|
*
|
|
lda #sector_size ;Force log_blk_size to 2k.
|
|
sta log_blk_size
|
|
lda resource_num ;No, is resource_num set?
|
|
beq found ;Nope, so we're done.
|
|
lda #path_not_found ;Yes, get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Transform file_name if needed. If this is a High Sierra volume and resource_num
|
|
* is set, exit with a file_not_found error 'cuz we don't support associated files
|
|
* for High Sierra...
|
|
*
|
|
transform jsr transform_in_f ;Transform file_name string if needed.
|
|
lda resource_num ;Looking for associated file?
|
|
beq search_loop ;Nope.
|
|
lda state_flag ;Yes, is this a High Sierra volume?
|
|
and #iso_bit
|
|
beq not_found ;Yep, so error.
|
|
*
|
|
* We're looking for a file, so let's search for it. Found it?
|
|
*
|
|
search_loop lda resource_num ;Get associated file flag.
|
|
jsr search_dir ;Do search. Success?
|
|
bcc found_file ;Yes.
|
|
lda log_blk_size ;Save logical block size.
|
|
pha
|
|
lda #sector_size ;Force to sector size.
|
|
sta log_blk_size
|
|
jsr read_next_block ;Nope, get next directory block.
|
|
plx ;Restore logical block size.
|
|
stx log_blk_size
|
|
bcc search_loop ;Loop if no error.
|
|
*
|
|
* Not found. Exit with file not found error...
|
|
*
|
|
not_found lda #file_not_found ;Get error code.
|
|
error sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Yes, move directory record to dir_record_0. If we found an associated file
|
|
* then set storage_type to extended...
|
|
*
|
|
found_file lda #0 ;Select dir_record_0.
|
|
jsr move_dir_record ;Move record.
|
|
lda extended_flag ;Did we find an associated file?
|
|
beq found ;Nope.
|
|
lda #type_extended ;Yes, set extended type.
|
|
sta storage_type
|
|
*
|
|
* Exit with carry clear...
|
|
*
|
|
found clc ;Indicate no error.
|
|
rts
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: find_directory
|
|
*
|
|
* Description: Searches path table for correct directory and returns block
|
|
* # of directory. Sets storage_type to indicate whether caller
|
|
* is looking for a file or a directory.
|
|
*
|
|
* Created: Oct 22, 1987
|
|
* Modified: Mar 10, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* path_ptr ;pointer to path name
|
|
* name_count ;# of names in pathname.
|
|
* name_offsets ;offsets to start of names.
|
|
*
|
|
* Output: A = high word of block #, or error code if error.
|
|
* X = low word of block #.
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = not found
|
|
* 0 = found
|
|
* B = K
|
|
*
|
|
* storage_type ;1=file, D=directory, F=volume directory
|
|
* current_name ;points to file name offset if file.
|
|
*
|
|
* Uses: All registers
|
|
* my_vcr
|
|
* current_name
|
|
* string_buffer
|
|
* temp_offsets
|
|
* temp0
|
|
* record_number
|
|
* transform_in_s (sub)
|
|
* get_name (sub)
|
|
* search_path_tbl (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
find_directory proc
|
|
with data
|
|
|
|
*
|
|
* Start by setting up to point to volume name in case there is only a volume
|
|
* name, and set record_number to 1 (always the root directory). Init storage
|
|
* type to volume directory...
|
|
*
|
|
lda #type_vol_dir ;Init storage type to volume directory.
|
|
sta storage_type
|
|
|
|
stz current_name ;Point to volume name.
|
|
lda #0 ;Init last_offset to record 1.
|
|
ldx #1 ;Set record_number = 1.
|
|
*
|
|
* Main loop.
|
|
* Point to next name. Have we done them all?
|
|
*
|
|
walk_path stx current_record ;Save current record number.
|
|
sta last_offset ;Save last offset.
|
|
|
|
inc current_name ;Bump current name.
|
|
ldy current_name ;Get it.
|
|
cpy name_count ;Done all?
|
|
bcs dir_found ;Yes, so we've got it.
|
|
*
|
|
* Nope, set storage_type to directory and search the path table for name.
|
|
* Did we find it?
|
|
*
|
|
lda #type_directory ;Set storage type to directory.
|
|
sta storage_type
|
|
jsr get_name ;Put the name in string_buffer.
|
|
jsr transform_in_s ;Transform name if needed.
|
|
ldx #0 ;Get starting record #.
|
|
|
|
try_again jsr search_path_tbl ;Go look for it. Found?
|
|
bcs name_not_found ;Nope.
|
|
*
|
|
* Yes, loop if parent record matches the current record...
|
|
*
|
|
cpy current_record ;Match?
|
|
beq walk_path ;Yes, so loop.
|
|
*
|
|
* Doesn't match. Is there another one in the path table past the one
|
|
* we just found? (record # is in X from last search)
|
|
*
|
|
bra try_again ;Go look again.
|
|
*
|
|
* Name not found. Are we looking at the last name in the pathname?
|
|
*
|
|
name_not_found ldy current_name ;Get current.
|
|
iny ;Bump it one.
|
|
cpy name_count ;Was it the last one?
|
|
beq last_one ;Yes.
|
|
*
|
|
* Nope, so exit with path not found error...
|
|
*
|
|
lda #path_not_found ;Get error code.
|
|
sec ;Set carry.
|
|
rts ;Exit.
|
|
*
|
|
* Yes, we are, so assume it is a file name. Set storage_type to file...
|
|
*
|
|
last_one lda #type_file ;Set storage type to file.
|
|
sta storage_type
|
|
*
|
|
* We've got it. If this directory has an XAR on it, exit with a dir_error,
|
|
* else exit with block # in A and X and carry clear...
|
|
*
|
|
dir_found clc ;Point to XAR length.
|
|
lda last_offset
|
|
adc pt_xar_len
|
|
tay
|
|
lda [path_table],y ;Get length.
|
|
and #$00ff ;Make 1 byte. Zero?
|
|
beq get_location ;Yes, so ok.
|
|
lda #dir_error ;No, get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
get_location clc ;Calc offset to location of extent.
|
|
lda last_offset
|
|
adc pt_loc_extent
|
|
tay
|
|
lda [path_table],y ;Get low word of directory location.
|
|
tax ;Put in X.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [path_table],y ;Get high word of location in A.
|
|
clc ;Indicate found.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: search_path_tbl
|
|
*
|
|
* Description: Searches pathtable for name in string_buffer, starting one
|
|
* entry past the record # passed in X.
|
|
*
|
|
* Created: Oct 22, 1987
|
|
* Modified: May 31, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = starting record #. Set to 0 for full search.
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* string_buffer ;name to match.
|
|
* path_table ;pointer to pathtable.
|
|
* path_table_size ;size of pathtable.
|
|
*
|
|
* Output: A = entry_offset.
|
|
* X = record number.
|
|
* Y = parent record number.
|
|
* P = nvmxdizc
|
|
* ..000..1 = not found
|
|
* 0 = found
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* string_buffer
|
|
* path_table
|
|
* entry_offset
|
|
* length
|
|
* record_number
|
|
* temp1
|
|
*
|
|
******************************************************************************
|
|
|
|
search_path_tbl proc
|
|
with data
|
|
|
|
*
|
|
* Save start_record and set record_number, length, and entry offset
|
|
* for first entry (the root directory), which we always want to skip
|
|
* because there is no name there...
|
|
*
|
|
stx start_record ;Save start record.
|
|
|
|
lda #1 ;Init record # and length to 1.
|
|
sta record_number
|
|
sta length
|
|
ldy #0 ;Init offset.
|
|
sty entry_offset ;Save it.
|
|
*
|
|
* Main loop.
|
|
* Bump offset to next entry and bump record #...
|
|
*
|
|
longa on ;Make sure in 16 bit mode.
|
|
next_entry rep #$20
|
|
|
|
clc ;Point to length byte.
|
|
lda length ;Get length.
|
|
bit #1 ;Is it odd?
|
|
beq its_even ;Nope.
|
|
inc a ;Yes, so bump length by 1.
|
|
its_even adc #pt_entry_len ;Add length to entry offset.
|
|
adc entry_offset ;Add it to current pointer.
|
|
tay ;Put back in y.
|
|
sty entry_offset ;Save offset to start of entry.
|
|
inc record_number ;Bump record number.
|
|
*
|
|
* Have we reached the end of the table?
|
|
*
|
|
cpy path_table_size ;Reached end?
|
|
bcs exit ;Yes, exit with carry set.
|
|
*
|
|
* No, does the name match? (Note: if branch above changes must clc
|
|
* before add).
|
|
*
|
|
tya ;Point Y at length byte.
|
|
adc pt_len_di
|
|
tay
|
|
|
|
adc pt_di_offset ;Point X at directory identifier.
|
|
tax
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
lda [path_table],y ;Get length.
|
|
sta length ;Save it.
|
|
cmp string_buffer ;Match our length?
|
|
bne next_entry ;Nope, so next entry.
|
|
txy ;Yes, point to directory identifier.
|
|
|
|
ldx #0 ;Init offset to string_buffer.
|
|
check_loop lda string_buffer+1,x ;Get byte.
|
|
cmp [path_table],y ;Match?
|
|
bne next_entry ;Nope, so next entry.
|
|
iny ;Bump offsets.
|
|
inx
|
|
cpx length ;Done all?
|
|
bne check_loop ;No, so continue.
|
|
*
|
|
* Yes, are we past the starting record #?
|
|
*
|
|
longa on ;Restore 16 bit A.
|
|
rep #$20
|
|
|
|
lda start_record ;Get start record number.
|
|
cmp record_number ;Less than current?
|
|
bcs next_entry ;Nope, so continue.
|
|
*
|
|
* Yes, so get offset, record number and parent record, and exit with
|
|
* carry clear...
|
|
*
|
|
clc ;Point to pt_parent_dir.
|
|
lda #pt_parent_dir
|
|
adc entry_offset
|
|
tay
|
|
lda [path_table],y ;Get parent record #.
|
|
tay ;Put in Y.
|
|
lda entry_offset ;Get offset in A.
|
|
ldx record_number ;Get record number in X.
|
|
clc ;Indicate no errors.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: move_dir_record
|
|
*
|
|
* Description: Copies directory record to dir_record 0 or 1.
|
|
*
|
|
* NOTE: Uses self-modifying code!
|
|
*
|
|
* Created: Oct 22, 1987
|
|
* Modified: Oct 29, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = destination: 0 = dir_record_0, 1 = dir_record_1
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* record_offset ;offset to start of record.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* dir_record_0 ;holds record 0.
|
|
* dir_record_1 ;holds record 1.
|
|
*
|
|
* Uses: All registers
|
|
* dir_record_0
|
|
* dir_record_1
|
|
* length
|
|
* output_string
|
|
*
|
|
******************************************************************************
|
|
|
|
move_dir_record proc
|
|
with data
|
|
|
|
*
|
|
* Set destination address...
|
|
*
|
|
ldx #dir_record_0 ;Get pointer to record 0.
|
|
tay ;Move to 0?
|
|
beq set_address ;Yes.
|
|
ldx #dir_record_1 ;Nope, get pointer to record 1.
|
|
set_address stx self_mod+1 ;Set pointer.
|
|
*
|
|
* Copy record and exit...
|
|
*
|
|
ldy record_offset ;Get offset to record.
|
|
lda [io_buffer],y ;Get length.
|
|
and #$00ff ;Make 1 byte.
|
|
sta length ;Save it.
|
|
|
|
ldx #0 ;Init offset to buffer.
|
|
copy_loop lda [io_buffer],y ;Get byte.
|
|
self_mod sta $ffff,x ;Put in record.
|
|
iny ;Bump offsets.
|
|
inx
|
|
cpx length ;Done all?
|
|
bne copy_loop ;No, so loop.
|
|
rts ;Yes, so exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: clear_dir_recs
|
|
*
|
|
* Description: Clears both dir_record_0 and dir_record_1.
|
|
*
|
|
* Created: Nov 9, 1987
|
|
* Modified: Nov 9, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* dir_record_0
|
|
* dir_record_1
|
|
*
|
|
******************************************************************************
|
|
|
|
clear_dir_recs proc
|
|
with data
|
|
|
|
*
|
|
* Clear out dir_record_0 and dir_record_1 and exit...
|
|
*
|
|
ldx #max_rec_len-2 ;Point to end of record.
|
|
clear_loop stz dir_record_0,x ;Clear word.
|
|
stz dir_record_1,x ;Clear word.
|
|
dex ;Done all?
|
|
dex
|
|
bpl clear_loop ;No, so loop.
|
|
rts ;Yes, so exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: search_dir
|
|
*
|
|
* Description: Searches directory in io_buffer for record with a file name
|
|
* that matches the name in file_name.
|
|
*
|
|
* Created: Oct 23, 1987
|
|
* Modified: Jun 6, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = 1 if looking for an associated file, 0 if not
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* file_name ;file name to match.
|
|
* io_buffer ;points to directory.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* record_offset ;offset to record.
|
|
* extended_flag ;1 if found a matching associated file.
|
|
* dir_record_1 ;holds associated file record if
|
|
* ;present and we were not looking for
|
|
* ;an associated file.
|
|
*
|
|
* Uses: All registers
|
|
* record_offset
|
|
* length
|
|
* temp0
|
|
*
|
|
******************************************************************************
|
|
|
|
search_dir proc
|
|
with data
|
|
|
|
*
|
|
* Save file_type, init record offset and clear extended_flag ...
|
|
*
|
|
sta file_type ;Save file type.
|
|
ldy #0 ;Init record offset.
|
|
sty extended_flag ;Clear extended_flag .
|
|
*
|
|
* Have we done all records?
|
|
*
|
|
search_loop sty record_offset ;Save offset.
|
|
cpy #sector_size ;Done all?
|
|
bcs not_found ;Yes, so not found.
|
|
lda [io_buffer],y ;No, get length of record.
|
|
and #$00ff ;We only want 1 byte. Zero?
|
|
beq not_found ;Yes, so not found.
|
|
sta length ;No, save it.
|
|
*
|
|
* No, does the name match?
|
|
*
|
|
clc ;Point to dir_len_fi.
|
|
tya
|
|
adc #dir_len_fi
|
|
tay
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
lda [io_buffer],y ;Get length.
|
|
cmp file_name ;Match length?
|
|
bne next_record ;Nope.
|
|
|
|
iny ;Yes, point to file identifier.
|
|
|
|
ldx #0 ;Init offset to file_name.
|
|
check_loop lda file_name+2,x ;Get byte.
|
|
cmp [io_buffer],y ;Match?
|
|
bne next_record ;Nope.
|
|
iny ;Yes, bump offsets.
|
|
inx
|
|
cpx file_name ;Done all?
|
|
bne check_loop ;No, so continue.
|
|
*
|
|
* Yes, is this a file?
|
|
*
|
|
longa on ;Back to 16 bit A.
|
|
rep #$20
|
|
|
|
clc ;Point to dir_file_flags.
|
|
lda dir_file_flags
|
|
adc record_offset
|
|
tay
|
|
lda [io_buffer],y ;Get flags byte.
|
|
and #dir_mask ;Is this a file?
|
|
bne next_record ;Nope, so next record.
|
|
|
|
longa off ;Back to 8 bit A.
|
|
sep #$20
|
|
*
|
|
* Yes, does associated file bit match the file_type flag?
|
|
*
|
|
lda [io_buffer],y ;Get flags byte.
|
|
and #assoc_mask ;Isolate associated file bit.
|
|
lsr a ;Shift to bit 0.
|
|
lsr a
|
|
cmp file_type ;Is it what we're looking for?
|
|
beq found ;Yes, so exit.
|
|
*
|
|
* Nope. If this is an associated file then set extended_flag and copy
|
|
* directory record to dir_record_1...
|
|
*
|
|
cmp #1 ;Is it an associated file?
|
|
bne next_record ;Nope.
|
|
sta extended_flag ;Yes, so set flag.
|
|
|
|
ldx #0 ;Init offset to buffer.
|
|
ldy record_offset ;Get offset to record.
|
|
copy_loop lda [io_buffer],y ;Get byte.
|
|
sta dir_record_1,x ;Put in record.
|
|
iny ;Bump offsets.
|
|
inx
|
|
cpx length ;Done all?
|
|
bne copy_loop ;No, so loop.
|
|
*
|
|
* Skip to the next record...
|
|
*
|
|
longa on ;Make sure 16 bit mode.
|
|
next_record rep #$20
|
|
|
|
clc ;Add length to offset.
|
|
lda length
|
|
adc record_offset
|
|
tay
|
|
bra search_loop ;And loop.
|
|
*
|
|
* Yes, so exit with carry clear...
|
|
*
|
|
longa on ;Make sure 16 bit mode.
|
|
found rep #$20
|
|
|
|
clc ;Indicate success.
|
|
rts ;Exit.
|
|
*
|
|
* It's not here. Exit with file not found error...
|
|
*
|
|
longa on ;Make sure 16 bit mode.
|
|
not_found rep #$20
|
|
|
|
lda #file_not_found ;Get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: build_fcr
|
|
*
|
|
* Description: Create a new FCR. Uses the last name in the pathname as the
|
|
* FCR name, or, if there is only a device #, will use the volume
|
|
* name found by id_disk. Puts first block of file into the
|
|
* FCR; if the file is less than 1 block long, the FCR size is
|
|
* allocated accordingly.
|
|
*
|
|
* Created: Oct 29, 1987
|
|
* Modified: Feb 17, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* storage_type ;1=file, 5=extended file, D=directory,
|
|
* or F=volume directory.
|
|
* name_count ;# of names in path.
|
|
* name_offsets ;offsets to start of names in path.
|
|
* dir_record_0 ;holds directory record.
|
|
* dir_record_1 ;holds associated dir record (if any).
|
|
*
|
|
* Output: A = error code if error.
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* my_fcr ;Points to fcr.
|
|
* open_buf_ptr ;Points to open buffer in fcr.
|
|
*
|
|
* Uses: All registers
|
|
* my_fcr
|
|
* length
|
|
* temp0
|
|
* dir_length
|
|
*
|
|
******************************************************************************
|
|
|
|
build_fcr proc
|
|
with data
|
|
|
|
*
|
|
* If the file is a directory, set log_blk_size to 2k, else set it using the
|
|
* value in the vcr...
|
|
*
|
|
lda #sector_size ;Init log_blk_size to 2k.
|
|
sta log_blk_size
|
|
lda storage_type ;Get storage type.
|
|
cmp #type_directory ;Is this a directory?
|
|
bcs get_length ;Yep.
|
|
|
|
ldy #vcr_block_size ;Nope, get block size from vcr.
|
|
lda [my_vcr],y
|
|
sta log_blk_size ;Set new logical block size.
|
|
*
|
|
* Ok, now set length = to the smaller of eof or log_blk_size. Set
|
|
* short_file_flag if eof < 1 block and make sure length is even...
|
|
*
|
|
get_length lda log_blk_size ;Get log_blk_size.
|
|
sta length ;Set length
|
|
stz short_file_flag ;Clear flag.
|
|
|
|
lda dir_record_0+dir_data_length+2 ;Get high eof. Zero?
|
|
bne calc_size ;Nope, use log_blk_size.
|
|
lda dir_record_0+dir_data_length ;Get low eof. Zero?
|
|
cmp log_blk_size ;< log_blk_size?
|
|
bcs calc_size ;Nope.
|
|
|
|
inc short_file_flag ;Yes, set flag.
|
|
bit #1 ;Is eof odd?
|
|
beq set_length ;Nope.
|
|
inc a ;Yes, so make it even.
|
|
set_length sta length ;Save size.
|
|
*
|
|
* Calculate size of fcr and allocate it...
|
|
*
|
|
calc_size clc
|
|
lda #fcr_dir_record ;Get offset to dir_record.
|
|
adc dir_record_0 ;Add length of dir_record.
|
|
; 1/11/89 adc dir_record_1 ;Add length of assoc_record.
|
|
and #$00ff ;Clear high byte cuz lengths are bytes.
|
|
adc length ;Add size.
|
|
bcs mem_error ;Exit if too big.
|
|
ldx #gstring ;Get pointer to volume name.
|
|
ldy #^gstring
|
|
jsl alloc_fcr ;Allocate it.
|
|
bcc build_it ;Continue if no error.
|
|
*
|
|
* We couldn't allocate it, exit with out of memory error...
|
|
*
|
|
mem_error lda #out_of_mem ;Get error code.
|
|
rts ;Exit.
|
|
*
|
|
* Get pointer to fcr and dir_record in fcr...
|
|
*
|
|
build_it jsl deref ;Dereference vp.
|
|
stx my_fcr ;Save pointer.
|
|
sty my_fcr+2
|
|
|
|
clc ;Make a pointer to dir_record.
|
|
txa
|
|
adc #fcr_dir_record
|
|
sta fcr_dir_ptr
|
|
tya
|
|
adc #0
|
|
sta fcr_dir_ptr+2
|
|
*
|
|
* Copy directory record into fcr...
|
|
*
|
|
lda dir_record_0 ;Get length.
|
|
and #$00ff ;Make one byte.
|
|
sta dir_length ;Save it for later.
|
|
tay ;Use as offset.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
copy_loop dey ;Done all?
|
|
bmi continue ;Yes.
|
|
lda dir_record_0,y ;No, get byte.
|
|
sta [fcr_dir_ptr],y ;Put in fcr.
|
|
bra copy_loop ;Loop.
|
|
|
|
longa on ;Set 16 bit A.
|
|
continue rep #$20
|
|
*
|
|
* Get reference number...
|
|
*
|
|
ldy #fcr_ref_num ;Get offset to reference num.
|
|
lda [my_fcr],y ;Get #.
|
|
sta ref_num ;Save it.
|
|
*
|
|
* Set access to read only and indicate that the file is never modified by
|
|
* setting the high bit, and set bit 14 if this is a resource fork...
|
|
*
|
|
ldy #fcr_access ;Get offset to access.
|
|
lda #read_access+$8000 ;Set to read only.
|
|
ldx resource_num ;Resource fork?.
|
|
beq save_access ;Nope.
|
|
ora #%0100000000000000 ;Yes, so set bit 14.
|
|
save_access sta [my_fcr],y ;Save it.
|
|
*
|
|
* Set position, open_mark, entry_num, error_flag and type_flag to zero and
|
|
* start_record to one...
|
|
*
|
|
lda #0000 ;Get zero.
|
|
ldy #fcr_position ;Get offset to low word of position.
|
|
sta [my_fcr],y ;Clear it.
|
|
ldy #fcr_open_mark ;Get offset to mark.
|
|
sta [my_fcr],y ;Clear it.
|
|
ldy #fcr_position+2 ;Get offset to low word of position.
|
|
sta [my_fcr],y ;Clear it.
|
|
ldy #fcr_entry_num ;Get offset to entry_num.
|
|
sta [my_fcr],y ;Clear it.
|
|
ldy #fcr_error_flag ;Get offset to error_flag.
|
|
sta [my_fcr],y ;Clear it.
|
|
ldy #fcr_type_flag ;Get offset to type_flag.
|
|
sta [my_fcr],y ;Clear it.
|
|
inc a ;Get one.
|
|
ldy #fcr_start_rec ;Get offset to start_record.
|
|
sta [my_fcr],y ;Save it.
|
|
*
|
|
* Fill in fcr_storage...
|
|
*
|
|
ldy #fcr_storage ;Get offset to storage.
|
|
lda storage_type ;Get type.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
*
|
|
* Fill in fcr_eof...
|
|
*
|
|
ldy #fcr_eof ;Get offset to low word.
|
|
lda eof ;Get low word.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
|
|
ldy #fcr_eof+2 ;Get offset to high word.
|
|
lda eof+2 ;Get high word.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
*
|
|
* Fill in fcr_blks...
|
|
*
|
|
ldy #fcr_blks ;Get offset to low word.
|
|
lda blocks_used ;Get low word.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
|
|
ldy #fcr_blks+2 ;Get offset to high word.
|
|
lda blocks_used+2 ;Get high word.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
*
|
|
* Set fcr_skip_count = interleave_size. If interleave_size = 0 then set
|
|
* fcr_skip_count to $ffff so that the calculation for direct reading will
|
|
* be happy...
|
|
*
|
|
ldy #fcr_skip_count ;Get offset to word.
|
|
lda dir_record_0+dir_int_size ;Get interleave_size.
|
|
and #$00ff ;Clear high byte. Zero?
|
|
bne save_skip ;Nope.
|
|
dec a ;Yes, so make $ffff.
|
|
save_skip sta [my_fcr],y ;Put in fcr.
|
|
*
|
|
* Calculate start block by adding the Extended Attribute Record (XAR) length
|
|
* to the Location of Extent, and put in fcr_open_block. Set drvr_blk_num...
|
|
*
|
|
do_open clc ;Prepare for add.
|
|
ldy #fcr_open_block ;Get offset to field.
|
|
lda dir_record_0+1 ;Get XAR length.
|
|
and #$00ff ;Make sure only 1 byte.
|
|
adc dir_record_0+dir_loc_extent ;Add low word of start block.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
sta drvr_blk_num ;Save it.
|
|
|
|
ldy #fcr_open_block+2 ;Get offset to field.
|
|
lda dir_record_0+dir_loc_extent+2 ;Get high start block.
|
|
adc #0 ;Add in carry.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
sta drvr_blk_num+2 ;Save it.
|
|
*
|
|
* Make pointer to open buffer in fcr...
|
|
*
|
|
clc ;Add dir_length to fcr_dir_ptr.
|
|
lda dir_length
|
|
adc fcr_dir_ptr
|
|
sta open_buf_ptr
|
|
tax
|
|
lda #0
|
|
adc fcr_dir_ptr+2
|
|
sta open_buf_ptr+2
|
|
*
|
|
* If short_file_flag is clear, set drvr_buf_ptr = open_buf_ptr. Otherwise,
|
|
* set it to io_buffer...
|
|
*
|
|
ldy short_file_flag ;Short file?
|
|
beq set_buf ;No, so use open_buf_ptr.
|
|
ldx io_buffer ;Yes, get pointer to io_buffer.
|
|
lda io_buffer+2
|
|
set_buf stx drvr_buf_ptr ;Set low word of drvr_buf_ptr.
|
|
sta drvr_buf_ptr+2 ;Set high word of drvr_buf_ptr.
|
|
*
|
|
* Read one block. Error?
|
|
*
|
|
lda log_blk_size ;Get log_blk_size.
|
|
sta drvr_req_cnt ;Set request count.
|
|
stz drvr_req_cnt+2
|
|
|
|
jsr common_read ;Do read. Error?
|
|
bcc keep_going ;Nope, so continue.
|
|
*
|
|
* Yes, so release fcr and exit...
|
|
*
|
|
pha ;Save error code.
|
|
lda [my_fcr] ;Get reference #.
|
|
jsl release_fcr ;Release fcr.
|
|
pla ;Get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* No, if short_file_flag is set then we must copy the data from the io_buffer
|
|
* into our fcr...
|
|
*
|
|
keep_going lda short_file_flag ;Short file?
|
|
beq finish_up ;No, so finish up.
|
|
|
|
ldy length ;Point to end.
|
|
data_loop dey ;Done all?
|
|
dey
|
|
bmi finish_up ;Yes, so finish up.
|
|
lda [io_buffer],y ;No, get word.
|
|
sta [open_buf_ptr],y ;Put in fcr.
|
|
bra data_loop ;Loop.
|
|
*
|
|
* Update vcr_open_cnt, fcr_fst_id, and fcr_vol_id, and exit with
|
|
* carry clear...
|
|
*
|
|
finish_up ldy #vcr_open_cnt ;Get offset to field.
|
|
lda [my_vcr],y ;Get count.
|
|
inc a ;Bump it.
|
|
sta [my_vcr],y ;Save it.
|
|
|
|
ldy #fcr_fst_id ;Get offset to field.
|
|
lda #hs_id ;Get fst id.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
|
|
ldy #fcr_vol_id ;Get offset to field.
|
|
lda [my_vcr] ;Get vol ID.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
|
|
clc ;Indicate success.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_dir_info
|
|
*
|
|
* Description: Get information out of dir_rec_0 and dir_rec_1 and put it in
|
|
* the output parameter storage area...
|
|
*
|
|
* Created: Oct 30, 1987
|
|
* Modified: July 14, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* dir_record_0 ;holds directory record.
|
|
* dir_record_1 ;holds associated dir record (if any).
|
|
* my_vcr ;points to current vcr.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* eof ;eof from dir_record_0.
|
|
* blocks_used ;blocks_used from dir_record_0.
|
|
* resource_eof ;eof from dir_record_1.
|
|
* resource_blocks ;blocks_used from dir_record_1.
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
get_dir_info proc
|
|
with data
|
|
|
|
*
|
|
* Save log_blk_size and set it from vcr...
|
|
*
|
|
lda log_blk_size ;Save current size.
|
|
pha
|
|
ldy #vcr_block_size ;Get size from vcr.
|
|
lda [my_vcr],y
|
|
sta log_blk_size ;Set new size.
|
|
*
|
|
* Fill in eof from dir_record_0...
|
|
*
|
|
ldy #dir_data_length ;Get offset to low word of data len.
|
|
lda dir_record_0,y ;Get low word.
|
|
sta eof ;Put in eof.
|
|
tax ;Save for division.
|
|
|
|
ldy #dir_data_length+2 ;Get offset to high word of data len.
|
|
lda dir_record_0,y ;Get high word.
|
|
sta eof+2 ;Put in eof.
|
|
*
|
|
* Fill in blocks_used from dir_record_0...
|
|
*
|
|
jsr calc_blocks ;Calculate blocks used.
|
|
stx blocks_used ;Save blocks_used.
|
|
sta blocks_used+2
|
|
*
|
|
* Fill in resource_eof from dir_record_1...
|
|
*
|
|
ldy #dir_data_length ;Get offset to low word of data length.
|
|
lda dir_record_1,y ;Get low word.
|
|
sta resource_eof ;Put in resource_eof.
|
|
tax ;Save for division.
|
|
|
|
ldy #dir_data_length+2 ;Get offset to high word of data len.
|
|
lda dir_record_1,y ;Get high word.
|
|
sta resource_eof+2 ;Put in resource_eof.
|
|
*
|
|
* Fill in resource_blocks from dir_record_1...
|
|
*
|
|
jsr calc_blocks ;Calculate blocks used.
|
|
stx resource_blocks ;Save resource_blocks.
|
|
sta resource_blocks+2
|
|
*
|
|
* Restore log_blk_size and exit...
|
|
*
|
|
pla ;Recover log_blk_size.
|
|
sta log_blk_size ;Restore it.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: calc_blocks
|
|
*
|
|
* Description: Calculates blocks_used from eof.
|
|
*
|
|
* Created: Oct 29, 1987
|
|
* Modified: Oct 29, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = high word of eof
|
|
* X = low word of eof
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* log_blk_size ;logical block size.
|
|
*
|
|
* Output: A = high word of blocks_used
|
|
* X = low word of blocks_used
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
calc_blocks proc
|
|
with data
|
|
|
|
*
|
|
* Set dividend = eof. Exit if eof is zero...
|
|
*
|
|
stx dividend ;Save low word of eof.
|
|
sta dividend+2 ;Save high word of eof.
|
|
ora dividend ;Eof zero?
|
|
beq exit ;Yes, so exit.
|
|
*
|
|
* Set divisor = log_blk_size and do division...
|
|
*
|
|
do_divide lda log_blk_size ;Set divisor = log_blk_size.
|
|
sta divisor
|
|
stz divisor+2
|
|
jsr long_divide ;Do division.
|
|
*
|
|
* Bump count if remainder not zero...
|
|
*
|
|
lda remainder ;Remainder zero?
|
|
ora remainder+2
|
|
beq get_it ;Yes.
|
|
inc dividend ;No, bump count.
|
|
bne get_it
|
|
inc dividend+2
|
|
*
|
|
* Get blocks_used and exit...
|
|
*
|
|
get_it ldx dividend ;Get low word.
|
|
lda dividend+2 ;Get high word.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: read
|
|
*
|
|
* Description: Read from an open file.
|
|
*
|
|
* Created: Nov 12, 1987
|
|
* Modified: May 2, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to vcr.
|
|
* my_fcr ;points to fcr.
|
|
* request_count ;maximum number of bytes to read.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* send_flag
|
|
* request_count
|
|
* newline_length
|
|
* newline_mask
|
|
* newline_ptr
|
|
* newline_char
|
|
* eof
|
|
* position
|
|
* interleave_size
|
|
* interleave_skip
|
|
* interleave_next
|
|
* deref (system service)
|
|
* move_info (system service)
|
|
* setup_open_buf (sub)
|
|
* send_from_open (sub)
|
|
* read_next_block (sub)
|
|
* update_fcr (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
read proc
|
|
with data
|
|
|
|
*
|
|
* Set cache value using caller's cache_priority and clear transfer count...
|
|
*
|
|
lda cache_priority ;Get value.
|
|
sta drvr_cache ;Set/clear driver flag.
|
|
stz transfer_count ;Clear count.
|
|
stz transfer_count+2
|
|
*
|
|
* Exit thru send_output if request count is zero...
|
|
*
|
|
lda request_count ;Count zero?
|
|
ora request_count+2
|
|
bne continue ;Nope.
|
|
jmp send_output ;Yes, so exit.
|
|
*
|
|
* Check our fcr_type_flag and exit with invalid_access error if this FCR
|
|
* has been accessed by get_dir_entry. If the flag is clear, claim this file
|
|
* for reading by setting the flag to 1...
|
|
*
|
|
continue ldy #fcr_type_flag ;Get offset to type_flag.
|
|
lda [my_fcr],y ;Get flag. Set already?
|
|
bne check_flag ;Yes.
|
|
inc a ;No, so set it to 1.
|
|
sta [my_fcr],y
|
|
bra check_dir ;And continue.
|
|
|
|
check_flag cmp #1 ;Are we allowed to read this file?
|
|
bne bad_access ;Nope, so exit with error.
|
|
*
|
|
* If this is a directory and class is zero, exit with an invalid_access error...
|
|
*
|
|
check_dir ldy #fcr_storage ;Get offset to storage_type.
|
|
lda [my_fcr],y ;Get type.
|
|
cmp #type_directory ;Is it a directory?
|
|
bcc setup_vol ;Nope, so we're ok.
|
|
lda class ;Yes, is it class zero?
|
|
bne setup_vol ;Nope, so we're ok.
|
|
bad_access lda #invalid_access ;Yes, so exit with error.
|
|
brl error_exit
|
|
*
|
|
* Make sure volume is online and setup some variables from the vcr...
|
|
*
|
|
setup_vol jsr setup_volume ;Do setup. Online?
|
|
bcc online ;Yes.
|
|
rts ;Nope, so exit.
|
|
*
|
|
* Setup and check open buffer...
|
|
*
|
|
online jsr setup_open_buf ;Do it.
|
|
jsr check_open_buf ;Make sure data is valid.
|
|
bcc set_newline ;Continue if no error.
|
|
rts ;Else exit.
|
|
*
|
|
* Get newline mask from the FCR and save it. Is newline enabled?
|
|
*
|
|
set_newline ldy #fcr_mask ;Get offset to mask.
|
|
lda [my_fcr],y ;Get mask.
|
|
sta newline_mask ;Save it. Enabled?
|
|
beq skip_newline ;Nope.
|
|
*
|
|
* Yes, so get pointer to newline list, set newline_length and newline_char...
|
|
*
|
|
ldy #fcr_newline ;Get offset to vp.
|
|
lda [my_fcr],y ;Get low word.
|
|
tax ;Put in X.
|
|
iny ;Point to high word.
|
|
iny
|
|
lda [my_fcr],y ;Get high word.
|
|
tay ;Put in Y.
|
|
jsl deref ;Dereference vp.
|
|
stx newline_ptr ;Save pointer.
|
|
sty newline_ptr+2
|
|
|
|
ldy #fcr_newline_len ;Point at length.
|
|
lda [my_fcr],y ;Get it.
|
|
sta newline_length ;Save it.
|
|
|
|
lda [newline_ptr] ;Get first newline character.
|
|
sta newline_char ;Save it.
|
|
*
|
|
* Get current position and eof...
|
|
*
|
|
skip_newline ldy #fcr_eof ;Point to low word of eof.
|
|
lda [my_fcr],y ;Get low word.
|
|
sta eof ;Save it.
|
|
iny ;Point to high word.
|
|
iny
|
|
lda [my_fcr],y ;Get high word.
|
|
sta eof+2 ;Save it.
|
|
|
|
ldy #fcr_position ;Point to low word of position.
|
|
lda [my_fcr],y ;Get low word.
|
|
sta position ;Save it.
|
|
tax ;Keep for compare.
|
|
iny ;Point to high word.
|
|
iny
|
|
lda [my_fcr],y ;Get high word.
|
|
sta position+2 ;Save it.
|
|
*
|
|
* Exit with end_of_file error if position = eof...
|
|
*
|
|
cmp eof+2 ;Match?
|
|
bne set_bytes_left ;Nope.
|
|
cpx eof ;Maybe.
|
|
bne set_bytes_left ;Nope.
|
|
lda #end_of_file ;Yes, get error code.
|
|
bra error_exit
|
|
*
|
|
* Set bytes_left = eof - position. If bytes_left is larger than request_count
|
|
* then set bytes_left = request_count...
|
|
*
|
|
set_bytes_left sec ;Do it.
|
|
lda eof
|
|
sbc position
|
|
sta bytes_left
|
|
tax
|
|
lda eof+2
|
|
sbc position+2
|
|
sta bytes_left+2
|
|
|
|
cmp request_count+2 ;Bytes_left > request_count?
|
|
bcc check_size ;Nope.
|
|
bne set_to_request ;Yes.
|
|
cpx request_count ;Maybe.
|
|
bcc check_size ;Nope.
|
|
|
|
set_to_request ldx request_count ;Set bytes_left = request_count.
|
|
lda request_count+2
|
|
stx bytes_left
|
|
sta bytes_left+2
|
|
*
|
|
* If bytes_left is >= 16 Mb then set it to 16 Mb - 1...
|
|
*
|
|
check_size cmp #$0100 ;Too big?
|
|
bcc set_flag ;Nope.
|
|
lda #$ffff ;Yes, so squash it.
|
|
sta bytes_left
|
|
lda #$00ff
|
|
sta bytes_left+2
|
|
*
|
|
* Set send_flag. Do we have to watch for newline?
|
|
*
|
|
set_flag lda #1 ;Set send_flag.
|
|
sta send_flag
|
|
*
|
|
* Send data from open buffer. Did we satisfy the request?
|
|
*
|
|
read_loop jsr transfer_data ;Do send. Did we satisfy the request?
|
|
bne all_done ;Yep.
|
|
*
|
|
* No, do we have at least one block left in request and is newline disabled?
|
|
* (bytes_left is in X and Y)
|
|
*
|
|
lda newline_mask ;Newline enabled?
|
|
bne double_buffer ;Yes, so we must double buffer.
|
|
|
|
tya ;Bytes_left >= log_blk_size?
|
|
bne do_direct ;Yes.
|
|
cpx log_blk_size ;Maybe.
|
|
bcc double_buffer ;Nope.
|
|
*
|
|
* Yes, clear send_flag and read as many blocks as possible directly into
|
|
* data_buffer. Loop if no error...
|
|
*
|
|
do_direct stz send_flag ;Clear flag.
|
|
jsr direct_read ;Do it. Any errors?
|
|
bcc read_loop ;Nope.
|
|
bra error ;Yep.
|
|
*
|
|
* We must double_buffer, so point io_buffer back to open_buffer and set
|
|
* send_flag to force transfer_data to do the move_info...
|
|
*
|
|
double_buffer lda open_buf_ptr ;Get pointer to open_buffer.
|
|
ldx open_buf_ptr+2
|
|
sta io_buffer ;Set io_buffer.
|
|
stx io_buffer+2
|
|
lda #1 ;Set send_flag.
|
|
sta send_flag
|
|
*
|
|
* Read in next block. Loop if no error...
|
|
*
|
|
jsr read_next_block ;Read block.
|
|
bcc read_loop ;No error, so loop.
|
|
*
|
|
* We got an error while reading. Update fcr with position information,
|
|
* send transfer_count, and exit with carry set and error code in A...
|
|
*
|
|
error pha ;Save error code.
|
|
jsr all_done ;Do update.
|
|
pla ;Recover error code.
|
|
error_exit sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Ok, we're done with the read. Did we manage to satisfy the request with
|
|
* the direct_read call? If so, we must restore the io_buffer pointer, set
|
|
* open_mark = log_blk_size, and set fcr_error_flag to indicate that the data
|
|
* in the open_buffer is not valid...
|
|
*
|
|
all_done lda send_flag ;Is flag clear?
|
|
bne do_update ;Nope.
|
|
lda open_buf_ptr ;Yes, get pointer to open_buffer.
|
|
ldx open_buf_ptr+2
|
|
sta io_buffer ;Restore io_buffer pointer.
|
|
stx io_buffer+2
|
|
lda log_blk_size ;Set open_mark = log_blk_size.
|
|
sta open_mark
|
|
sec ;Set fcr_error_flag.
|
|
jsr condition_flag
|
|
*
|
|
* Update fcr with current position information and send output...
|
|
*
|
|
do_update ldx drvr_blk_num ;Get current block #.
|
|
lda drvr_blk_num+2
|
|
jsr update_fcr ;Do update.
|
|
jsr send_output ;Send transfer_count.
|
|
*
|
|
* If this is a directory then we must exit with the fst_caution error code, else
|
|
* exit with carry clear...
|
|
*
|
|
ldy #fcr_storage ;Get offset to storage_type.
|
|
lda [my_fcr],y ;Get type.
|
|
cmp #type_directory ;Is it a directory?
|
|
bcc exit ;Nope, so we're ok.
|
|
lda #fst_caution ;Yes, so exit with error.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: transfer_data
|
|
*
|
|
* Description: Transfer data from open_buffer to data_buffer and update
|
|
* position information.
|
|
*
|
|
* Created: Nov 17, 1987
|
|
* Modified: May 2, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* send_flag ;0 = do update only.
|
|
* data_buffer ;points to caller's buffer.
|
|
* open_buf_ptr ;points to open_buffer.
|
|
* eof ;end of file.
|
|
* newline_length ;length of newline table.
|
|
* newline_ptr ;pointer to newline table.
|
|
* newline_mask ;mask for newline character.
|
|
* newline_char ;first byte of newline table.
|
|
* position ;current file mark.
|
|
* open_mark ;current position within open buffer.
|
|
* transfer_count ;current bytes transfered.
|
|
* bytes_left ;# bytes till satisfy request.
|
|
* log_blk_size ;current size of blocks.
|
|
* read_size ;size used in multi-block reads.
|
|
*
|
|
* Output: A = status_flag: 0 = continue, 1 = satisfied request
|
|
* X = low word of bytes_left
|
|
* Y = high word of bytes_left
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* position ;new file mark.
|
|
* open_mark ;new position within open buffer.
|
|
* transfer_count ;new bytes transfered.
|
|
* bytes_left ;# bytes till satisfy request.
|
|
*
|
|
* Uses: All registers
|
|
* temp0
|
|
* temp1
|
|
* dividend
|
|
* length
|
|
* position
|
|
* open_mark
|
|
* transfer_count
|
|
* request_count
|
|
* bytes_left
|
|
*
|
|
******************************************************************************
|
|
|
|
transfer_data proc
|
|
with data
|
|
|
|
*
|
|
* Clear status_flag and high word of xfer_count...
|
|
*
|
|
stz status_flag ;Clear flag.
|
|
stz xfer_count+2 ;Clear high word of count.
|
|
*
|
|
* If send_flag is clear it means that a block has been transfered directly
|
|
* to data_buffer. If that has happened, we set xfer_count = read_size, and
|
|
* skip to update...
|
|
*
|
|
lda send_flag ;Has a block been transfered directly?
|
|
bne check_buffer ;Nope.
|
|
lda read_size ;Yes, so set xfer_count = read_size.
|
|
sta xfer_count
|
|
lda read_size+2
|
|
sta xfer_count+2
|
|
brl update ;And continue at update...
|
|
*
|
|
* If open_mark = log_blk_size then there is nothing left in this block to
|
|
* transfer, so we reset open_mark to zero and exit with status_flag clear and
|
|
* bytes_left in X & Y...
|
|
*
|
|
check_buffer lda open_mark ;Get mark.
|
|
cmp log_blk_size ;Do we have anything left in here?
|
|
bne set_source ;Yep.
|
|
stz open_mark ;Nope, reset open_mark.
|
|
ldx bytes_left ;Get bytes_left.
|
|
ldy bytes_left+2
|
|
brl exit ;Exit.
|
|
*
|
|
* Set source_ptr = open_buf_ptr + open_mark...
|
|
*
|
|
set_source clc ;Do addition.
|
|
adc open_buf_ptr
|
|
sta source_ptr
|
|
lda #0
|
|
adc open_buf_ptr+2
|
|
sta source_ptr+2
|
|
*
|
|
* Init xfer_count to log_blk_size - open_mark...
|
|
*
|
|
sec ;Prepare for subtraction.
|
|
lda log_blk_size ;Get log_blk_size.
|
|
sbc open_mark ;Subtract open_mark.
|
|
sta xfer_count ;Save xfer_count.
|
|
*
|
|
* If bytes_left <= xfer_count then set status_flag to 1 and xfer_count to
|
|
* bytes_left...
|
|
*
|
|
ldx bytes_left+2 ;Is bytes_left <= xfer_count?
|
|
bne check_newline ;Nope.
|
|
cmp bytes_left ;Maybe.
|
|
bcc check_newline ;Nope, so use xfer_count.
|
|
lda bytes_left ;Yes, so set xfer_count = bytes_left.
|
|
sta xfer_count
|
|
inc status_flag ;Set status to 1.
|
|
*
|
|
* Do we have to watch for newline?
|
|
*
|
|
check_newline lda newline_mask ;Newline enabled?
|
|
beq fast_xfer ;No, so go fast.
|
|
*
|
|
* Yes, set short accumulator. Do we have to look at more than one newline
|
|
* character?
|
|
*
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
dec newline_length ;Point to last byte. More than 1?
|
|
beq medium_xfer ;Nope.
|
|
*
|
|
* Yes, so we'll slow to a crawl and check each byte against the entire
|
|
* newline table after we transfer it...
|
|
*
|
|
ldy #0 ;Init offset.
|
|
slow_loop lda [source_ptr],y ;Get byte.
|
|
sta [data_buffer],y ;Put byte.
|
|
and newline_mask ;Mask it.
|
|
tyx ;Save offset.
|
|
ldy newline_length ;Point to end of newline table.
|
|
newline_loop cmp [newline_ptr],y ;Match byte?
|
|
beq hit_newline ;Yes.
|
|
dey ;Nope, checked all in table?
|
|
bpl newline_loop ;No, so loop.
|
|
txy ;Yes, recover offset.
|
|
iny ;Bump it.
|
|
cpy xfer_count ;Done all?
|
|
bne slow_loop ;No, so loop.
|
|
bra restore_a ;Yes, so continue.
|
|
*
|
|
* We only have to look at one newline character. Do transfer...
|
|
*
|
|
medium_xfer ldy #0 ;Init offset.
|
|
medium_loop lda [source_ptr],y ;Get byte.
|
|
sta [data_buffer],y ;Put byte.
|
|
and newline_mask ;Mask it.
|
|
cmp newline_char ;Match newline?
|
|
beq hit_newline_a ;Yep.
|
|
iny ;Nope, bump offset.
|
|
cpy xfer_count ;Done all?
|
|
bne medium_loop ;Nope.
|
|
bra restore_a ;Yep.
|
|
*
|
|
* We hit a newline character so set xfer_count to current offset +1, set
|
|
* set status_flag to 1, restore 16 bit accumulator and branch to update...
|
|
*
|
|
hit_newline txy ;Get offset.
|
|
hit_newline_a iny ;Bump count by 1.
|
|
sty xfer_count ;Reset xfer_count.
|
|
lda #1 ;Set status flag to 1.
|
|
sta status_flag
|
|
|
|
longa on ;Set 16 bit A.
|
|
restore_a rep #$20
|
|
|
|
inc newline_length ;Restore length.
|
|
bra update ;Continue.
|
|
*
|
|
* We don't have to check for newline so use move_info to move data into
|
|
* data_buffer...
|
|
*
|
|
fast_xfer pei source_ptr+2 ;Push source pointer.
|
|
pei source_ptr
|
|
pei data_buffer+2 ;Push destination pointer.
|
|
pei data_buffer
|
|
pea 0 ;Push transfer request count.
|
|
pei xfer_count
|
|
pea move_sinc_dinc
|
|
jsl move_info ;Do move.
|
|
*
|
|
* Ok, we've moved the data, now let's update the position information. If we
|
|
* did NOT satisfy the request, we must be finished with this block so reset
|
|
* open_mark to zero...
|
|
*
|
|
update lda status_flag ;Did we satisfy the request?
|
|
beq reset_mark ;No, so reset_mark.
|
|
*
|
|
* We satisfied the request, so set open_mark = open_mark + xfer_count. Ignore
|
|
* for now the case in which open_mark = log_blk_size; we handle that case at
|
|
* the beginning of this routine.
|
|
*
|
|
clc ;Do addition.
|
|
lda xfer_count
|
|
adc open_mark
|
|
reset_mark sta open_mark
|
|
*
|
|
* Set data_buffer and io_buffer = data_buffer + xfer_count. By pointing
|
|
* io_buffer at data_buffer we may be able to avoid double buffering by
|
|
* reading directly into the caller's buffer...
|
|
*
|
|
clc ;Do it.
|
|
lda xfer_count
|
|
tax
|
|
adc data_buffer
|
|
sta data_buffer
|
|
sta io_buffer
|
|
lda xfer_count+2
|
|
tay
|
|
adc data_buffer+2
|
|
sta data_buffer+2
|
|
sta io_buffer+2
|
|
*
|
|
* Set transfer_count = transfer_count + xfer_count...
|
|
*
|
|
clc ;Do it.
|
|
txa
|
|
adc transfer_count
|
|
sta transfer_count
|
|
tya
|
|
adc transfer_count+2
|
|
sta transfer_count+2
|
|
*
|
|
* Set position = position + xfer_count...
|
|
*
|
|
clc ;Do it.
|
|
txa
|
|
adc position
|
|
sta position
|
|
tya
|
|
adc position+2
|
|
sta position+2
|
|
*
|
|
* Set bytes_left = bytes_left - xfer_count...
|
|
*
|
|
sec ;Do it.
|
|
lda bytes_left
|
|
sbc xfer_count
|
|
sta bytes_left
|
|
tax
|
|
lda bytes_left+2
|
|
sbc xfer_count+2
|
|
sta bytes_left+2
|
|
tay
|
|
*
|
|
* Set status_flag if bytes_left = zero...
|
|
*
|
|
ora bytes_left ;Bytes_left = zero?
|
|
bne exit ;Nope.
|
|
inc status_flag ;Yes, so set status_flag.
|
|
*
|
|
* Get status_flag in A and exit...
|
|
*
|
|
exit lda status_flag ;Get status_flag.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: setup_volume
|
|
*
|
|
* Description: Sets up all volume specific variables, and checks to see if
|
|
* volume has been switched. Will call mount_message if needed.
|
|
*
|
|
* NOTE: There is an alternate entry point used by device_dispatch.
|
|
*
|
|
* Created: Nov 12, 1987
|
|
* Modified: Mar 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to vcr.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* input_string
|
|
* find_volume (sub)
|
|
* activate_vcr (sub)
|
|
* mount_message (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
setup_volume proc
|
|
with data
|
|
|
|
*
|
|
* Get device number out of VCR and set drvr_dev_num...
|
|
*
|
|
ldy #vcr_dev ;Point to device #.
|
|
lda [my_vcr],y ;Get it.
|
|
sta drvr_dev_num ;Save it.
|
|
*
|
|
* Has a disk switch occured?
|
|
*
|
|
ldy #vcr_status ;Point to status.
|
|
lda [my_vcr],y ;Get word.
|
|
and #vcr_swapped ;Disk switch occured?
|
|
beq ok_exit ;Nope.
|
|
*
|
|
* Yes, get pointer to the vcr name and move it to volume_name...
|
|
*
|
|
export find_our_volume
|
|
find_our_volume ;
|
|
|
|
ldy #vcr_name ;Point to low word of name vp.
|
|
lda [my_vcr],y ;Get low word.
|
|
tax ;Put in X.
|
|
iny ;Point to high word.
|
|
iny
|
|
lda [my_vcr],y ;Get high word.
|
|
tay ;Put in Y.
|
|
jsl deref ;Dereference it.
|
|
stx input_string ;Save pointer.
|
|
sty input_string+2
|
|
|
|
lda [input_string] ;Get length.
|
|
and #$00ff ;Clear high byte.
|
|
tay ;Use as index.
|
|
iny ;Point to last char.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
lda #0 ;Get zero.
|
|
sta volume_name+1,y ;Delimit string.
|
|
|
|
copy_loop lda [input_string],y ;Move byte.
|
|
sta volume_name,y
|
|
dey ;Done all?
|
|
bpl copy_loop ;Nope, so loop.
|
|
|
|
longa on ;Set 16 bit A.
|
|
rep #$20
|
|
*
|
|
* See if we can find it by calling find_volume. Found?
|
|
*
|
|
mount_loop jsr find_volume ;Go look. Found?
|
|
bcc got_volume ;Yes.
|
|
*
|
|
* No, so call mount_message. First make volume name a class 0 name with a
|
|
* leading slash, do call, then restore volume name. Ok button pressed?
|
|
*
|
|
lda #$2e5f ;Replace underscores with periods.
|
|
ldx #volume_name
|
|
ldy #^volume_name
|
|
jsr transform_name
|
|
|
|
lda volume_name ;Get length word.
|
|
pha ;Save it.
|
|
inc a ;Make it one longer.
|
|
ora #$2f00 ;Add a slash (name must be <256 chars!)
|
|
sta volume_name ;Save it.
|
|
|
|
pea volume_name>>16 ;Push address of volume name string.
|
|
pea volume_name
|
|
lda #0001
|
|
jsl mount_message ;Do message.
|
|
|
|
plx ;Restore volume_name.
|
|
stx volume_name
|
|
pha ;Save button status.
|
|
|
|
lda #$5f2e ;Replace periods with underscores.
|
|
ldx #volume_name
|
|
ldy #^volume_name
|
|
jsr transform_name
|
|
|
|
pla ;Ok button pressed?
|
|
beq mount_loop ;Yes, so loop to re-try find_volume.
|
|
*
|
|
* User cancelled, so exit with a vol_not_found error...
|
|
*
|
|
lda #vol_not_found ;Get error code.
|
|
sec ;Set carry.
|
|
rts ;Exit.
|
|
*
|
|
* We have got the volume. Update vcr with device number...
|
|
*
|
|
got_volume ldy #vcr_dev ;Point to device # in vcr.
|
|
lda drvr_dev_num ;Get it.
|
|
sta [my_vcr],y ;Put in vcr.
|
|
*
|
|
* Activate vcr and exit with carry clear...
|
|
*
|
|
ok_exit jsr activate_vcr ;Activate it.
|
|
clc ;Indicate no error.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: direct_read
|
|
*
|
|
* Description: Reads as many blocks in one drvr_read call as possible for
|
|
* this file directly into the caller's buffer.
|
|
*
|
|
* Created: Nov 30, 1987
|
|
* Modified: July 26, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = low word of bytes_left
|
|
* Y = high word of bytes_left
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* skip_count ;# blocks till interleave gap.
|
|
* log_blk_size ;logical block size.
|
|
* data_buffer ;points to caller's buffer.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* read_size ;# bytes read.
|
|
* io_buffer ;points to caller's buffer.
|
|
*
|
|
* Uses: All registers
|
|
* total_blocks
|
|
* multiplier (a.k.a. dividend)
|
|
* multiplicand (a.k.a. divisor)
|
|
* product (a.k.a. input_string & output_string)
|
|
* remainder
|
|
* long_divide (sub)
|
|
* long_multiply (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
direct_read proc
|
|
with data
|
|
|
|
*
|
|
* Set dividend = bytes_left...
|
|
*
|
|
stx dividend ;Set dividend = bytes_left.
|
|
sty dividend+2
|
|
*
|
|
* Point io_buffer to caller's buffer...
|
|
*
|
|
lda data_buffer ;Set io_buffer = data_buffer.
|
|
sta io_buffer
|
|
lda data_buffer+2
|
|
sta io_buffer+2
|
|
*
|
|
* Advance the block number and save it. This will also adjust skip_count to
|
|
* the correct value...
|
|
*
|
|
jsr next_block ;Get next block number.
|
|
bcs error_exit ;Error!
|
|
stx drvr_blk_num ;Set block number to read.
|
|
sta drvr_blk_num+2
|
|
*
|
|
* Can we read more than 1 block?
|
|
*
|
|
lda skip_count ;Get skip_count.
|
|
dec a ;Skip_count = 1?
|
|
bne do_calc ;Nope.
|
|
*
|
|
* No, so set total_blocks to 1 and read_size to log_blk_size, then skip
|
|
* calculation...
|
|
*
|
|
inc a ;Init total_blocks to 1.
|
|
sta total_blocks
|
|
lda log_blk_size ;Init read_size to log_blk_size.
|
|
ldx #0
|
|
bra do_read ;Continue.
|
|
*
|
|
* Yes, so we must do calculation. Set total_blocks = bytes_left/log_blk_size
|
|
* (since bytes_left cannot exceed 16 Mb - 1, and log_blk_size should never be
|
|
* smaller than 256 bytes, total_blocks cannont exceed $ffff). If total_blocks
|
|
* is greater than skip_count, set total_blocks and multiplier = skip_count...
|
|
*
|
|
do_calc lda log_blk_size ;Set divisor = log_blk_size.
|
|
sta divisor
|
|
stz divisor+2
|
|
jsr long_divide ;Do division.
|
|
lda dividend ;Set total_blocks = result.
|
|
sta total_blocks
|
|
cmp skip_count ;Is it larger than skip_count?
|
|
bcc calc_read_size ;Nope.
|
|
|
|
lda skip_count ;Yes, so set total_blocks = skip_count.
|
|
sta total_blocks
|
|
sta multiplier ;Set multiplier = skip_count.
|
|
stz multiplier+2
|
|
*
|
|
* And set read_size = total_blocks * log_blk_size...
|
|
*
|
|
calc_read_size lda log_blk_size ;Set multiplicand = log_blk_size.
|
|
sta multiplicand
|
|
stz multiplicand+2
|
|
jsr long_multiply ;Do multiplication.
|
|
lda product ;Set read_size = low lw of product.
|
|
ldx product+2
|
|
*
|
|
* Save read_size, set drvr_req_cnt = read_size, do the read and condition the
|
|
* fcr error flag. Exit if we get an error...
|
|
*
|
|
do_read sta read_size ;Save read_size.
|
|
stx read_size+2
|
|
sta drvr_req_cnt ;Set request count.
|
|
stx drvr_req_cnt+2
|
|
jsr device_read_b ;Do read.
|
|
jsr condition_flag ;Condition the error flag.
|
|
bcs error_exit ;Error, so exit.
|
|
*
|
|
* Now, we have to adjust drvr_blk_num and skip_count to account for the number
|
|
* of blocks we just read, and exit with carry clear...
|
|
*
|
|
dec total_blocks ;First, zero adjust total_blocks.
|
|
|
|
clc ;Add total_blocks to drvr_blk_num.
|
|
lda total_blocks
|
|
adc drvr_blk_num
|
|
sta drvr_blk_num
|
|
lda #0
|
|
adc drvr_blk_num+2
|
|
sta drvr_blk_num+2
|
|
|
|
sec ;Subtract total_blocks from skip_count.
|
|
lda skip_count
|
|
sbc total_blocks
|
|
sta skip_count
|
|
clc ;Indicate success.
|
|
error_exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: sector_read
|
|
*
|
|
* Description: Reads one sector into io_buffer.
|
|
*
|
|
* NOTE: this call should only be used by id_disk!! Sectors are
|
|
* only used to find the Standard File Volume Descriptor.
|
|
*
|
|
* Created: Oct 21, 1987
|
|
* Modified: Oct 21, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = HIGH word of block #.
|
|
* X = low word of block #.
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* drvr_dev_num ;device number to access.
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* log_blk_size ;set to 2k.
|
|
* real_log_size ;set to 2k.
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: All registers
|
|
* device_read (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
sector_read proc
|
|
with data
|
|
|
|
*
|
|
* Set to read 2k bytes and continue through device_read...
|
|
*
|
|
ldy #sector_size ;Set to read 2k.
|
|
sty log_blk_size ;Set log_blk_size to 2k.
|
|
sty real_log_size ;Set real_log_size to 2k.
|
|
jmp device_read ;Do read and exit...
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: block_read
|
|
*
|
|
* Description: Reads one block of the current log_blk_size into io_buffer.
|
|
*
|
|
* Created: Oct 21, 1987
|
|
* Modified: Oct 21, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = HIGH word of block #.
|
|
* X = low word of block #.
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* drvr_dev_num ;device number to access.
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: All registers
|
|
* device_read (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
block_read proc
|
|
with data
|
|
|
|
*
|
|
* Set to read log_blk_size bytes and continue on through device_read...
|
|
*
|
|
ldy log_blk_size ;Get log_blk_size.
|
|
jmp device_read ;Do read.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: device_read
|
|
*
|
|
* Description: Sets common parameters and does read. Handles logical block
|
|
* sizes 512, 1024 and 2048.
|
|
*
|
|
* NOTE: There are two additional entry points in this routine.
|
|
*
|
|
* Created: Oct 7, 1987
|
|
* Modified: Mar 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = HIGH word of block #.
|
|
* X = low word of block #.
|
|
* Y = request count. Must be multiple of trans_blk_size!
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* drvr_dev_num ;device number to read from
|
|
* real_log_size ;real logical block size
|
|
* ;(usually = log_blk_size)
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: All registers
|
|
* Device Dispatcher
|
|
*
|
|
******************************************************************************
|
|
|
|
device_read proc
|
|
with data
|
|
|
|
*
|
|
* Set driver block #...
|
|
*
|
|
stx drvr_blk_num ;Set low word.
|
|
sta drvr_blk_num+2 ;Set high word.
|
|
*
|
|
* Set request count...
|
|
*
|
|
sty drvr_req_cnt ;Set it.
|
|
stz drvr_req_cnt+2
|
|
*
|
|
* Set to read into io_buffer...
|
|
*
|
|
export device_read_b
|
|
device_read_b ;
|
|
|
|
lda io_buffer ;Get low word of pointer.
|
|
sta drvr_buf_ptr ;Set low word of pointer.
|
|
lda io_buffer+2 ;Get high word of pointer.
|
|
sta drvr_buf_ptr+2 ;Set high word of pointer.
|
|
*
|
|
* Setup common driver parameters...
|
|
*
|
|
export common_read
|
|
common_read ;
|
|
|
|
lda #drvr_read ;Set read command.
|
|
sta drvr_call_num
|
|
|
|
lda #hs_id ;Get High Sierra id.
|
|
sta drvr_fst_num ;Set it.
|
|
|
|
lda #phys_blk_size ;Set block size.
|
|
sta drvr_blk_size
|
|
*
|
|
* If real_log_size is not equal to phys_blk_size (512) then branch to
|
|
* translate_blk, else do call and exit...
|
|
*
|
|
lda real_log_size ;Get real logical block size.
|
|
cmp #phys_blk_size ;Is it same as physical size?
|
|
bne translate_blk ;Nope.
|
|
jmp device_dispatch ;Yep, exit thru device_dispatch.
|
|
*
|
|
* We've got a non 512 byte block size. First save the current block #...
|
|
*
|
|
translate_blk pei drvr_blk_num ;Save current block #.
|
|
pei drvr_blk_num+2
|
|
*
|
|
* Multiply the block # by 2. Is real_log_size = 1024? If so then branch to
|
|
* read_it, else must be 2048 so multiply it by 2 again then do read...
|
|
*
|
|
asl drvr_blk_num ;Multiply block number by 2.
|
|
rol drvr_blk_num+2
|
|
|
|
cmp #1024 ;real_log_size = 1024?
|
|
beq read_it ;Yes.
|
|
|
|
asl drvr_blk_num ;Multiply block number by 2.
|
|
rol drvr_blk_num+2
|
|
|
|
read_it jsr device_dispatch ;Do call.
|
|
*
|
|
* Ok, we've done the read, now let's restore the block number and exit...
|
|
*
|
|
exit plx ;Restore block number.
|
|
stx drvr_blk_num+2
|
|
plx
|
|
stx drvr_blk_num
|
|
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: device_dispatch
|
|
*
|
|
* Description: Calls device dispatcher and checks for disk switched or offline
|
|
* error. If found and id_disk_flag is clear and my_vcr is set,
|
|
* will save current state, do a find_our_volume call, restore
|
|
* state, and retry call.
|
|
*
|
|
* This routine should only be called by device_read!!
|
|
*
|
|
* NOTE: The id_disk_flag is used to ensure that this routine can call
|
|
* itself safely thru find_our_volume -> find_volume -> id_disk.
|
|
*
|
|
*
|
|
* Created: Mar 28, 1988
|
|
* Modified: 8/8/90
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* id_disk_flag ;1 if id_disk routine called, else 0.
|
|
* my_vcr ;clear if not in use.
|
|
* drvr_dev_num ;device number to access.
|
|
* drvr_call_num ;call number.
|
|
* drvr_buf_ptr ;buffer pointer.
|
|
* drvr_req_cnt ;request count (if read).
|
|
* drvr_blk_num ;block number (if read).
|
|
* drvr_blk_size ;block size.
|
|
* drvr_fst_num ;FST id number.
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: All registers
|
|
* find_our_volume (sub)
|
|
* Device Dispatcher (sys service)
|
|
*
|
|
*
|
|
* revision history
|
|
*
|
|
* 08/08/90 CAF now will re_try on a disk switched error always. It wasn't
|
|
* happening before during a volume call because no vcr was setup.
|
|
*
|
|
* 08/08/90 MSD. Changed to retry the device access if the error was
|
|
* drvr_disk_sw and id_disk_flag is set. This is so
|
|
* drvr_disk_sw will not be returned from the Volume call,
|
|
* but will be returned during other calls (so that the FST
|
|
* can find out where the volume has moved to).
|
|
* Thanks to Cheryl for pointing this out!!
|
|
*
|
|
******************************************************************************
|
|
|
|
device_dispatch proc
|
|
with data
|
|
;
|
|
; Cheryl says: Cary and Mark goofed. If we came from the id_disk routine
|
|
; and we get a disk switched error, then we can retry. Otherwise, the retry
|
|
; might access the wrong media (when we really need to go find out where it
|
|
; is after the disk switch).
|
|
;
|
|
*
|
|
* Call device dispatcher. Exit if no error, or if id_disk_flag is set, or if
|
|
* my_vcr is clear, or if error not disk switched or offline...
|
|
*
|
|
re_try jsl dev_dispatcher ;Do call.
|
|
bcc exit ;No error.
|
|
pha ;Save error.
|
|
cmp #drvr_disk_sw ;Disk switched error?
|
|
bne @no_disk_sw ; not disk_sw, so try other errors
|
|
lda id_disk_flag ; trying to id a disk?
|
|
beq check_flag ; no, so do usual stuff
|
|
pla ; clean up stack
|
|
bra re_try ; and try it again
|
|
@no_disk_sw
|
|
cmp #drvr_off_line ;Nope, offline?
|
|
bne error ;Nope.
|
|
lda id_disk_flag ;Yes, is id_disk_flag set?
|
|
bne error ;Yep, so exit with error.
|
|
; in middle of call, so fix up VCR
|
|
check_flag lda my_vcr ;Nope, is my_vcr clear?
|
|
ora my_vcr+2
|
|
bne save_state ;Nope, so let's see if we can recover.
|
|
|
|
error pla ;Get error code.
|
|
sec ;Make sure carry set.
|
|
exit rts ;Exit.
|
|
*
|
|
* We have a disk switched condition, so let's try to recover. Save all of the
|
|
* data that will be modified by calling find_our_volume...
|
|
*
|
|
save_state pla ;Fix stack.
|
|
|
|
ldx #drvr_dp_len-2 ;Save driver direct page space.
|
|
drvr_loop lda drvr_call_num,x
|
|
sta storage_drvr,x
|
|
dex
|
|
dex
|
|
bpl drvr_loop
|
|
|
|
ldx #fst_dp_len-2 ;Save fst direct page space.
|
|
fst_loop lda input_string,x
|
|
sta storage_fst,x
|
|
dex
|
|
dex
|
|
bpl fst_loop
|
|
|
|
ldx #misc_len-2 ;Save miscellaneous space.
|
|
misc_loop lda gstring,x
|
|
sta storage_misc,x
|
|
dex
|
|
dex
|
|
bpl misc_loop
|
|
*
|
|
* Call find_our_volume and save error code and status...
|
|
*
|
|
jsr find_our_volume ;Go look for it.
|
|
php ;Save status.
|
|
pha ;Save error code.
|
|
*
|
|
* Restore the state...
|
|
*
|
|
ldx #drvr_dp_len-2 ;Restore driver direct page space.
|
|
drvr_loop_r lda storage_drvr,x
|
|
sta drvr_call_num,x
|
|
dex
|
|
dex
|
|
bpl drvr_loop_r
|
|
|
|
ldx #fst_dp_len-2 ;Restore fst direct page space.
|
|
fst_loop_r lda storage_fst,x
|
|
sta input_string,x
|
|
dex
|
|
dex
|
|
bpl fst_loop_r
|
|
|
|
ldx #misc_len-2 ;Restore miscellaneous space.
|
|
misc_loop_r lda storage_misc,x
|
|
sta gstring,x
|
|
dex
|
|
dex
|
|
bpl misc_loop_r
|
|
*
|
|
* Recover call status and error code. Re-try call if no error, else exit...
|
|
*
|
|
pla ;Recover error code.
|
|
plp ;Recover status.
|
|
bcs exit ;Exit if error.
|
|
jmp re_try ;No error, so re-try call.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: read_next_block
|
|
*
|
|
* Description: Reads next block of file or directory. Handles interleaved
|
|
* files; for directories, interleave_skip must be zero! Will
|
|
* set fcr_error_flag if error occurs during read.
|
|
*
|
|
* Handles differences between log_blk_size and trans_blk_size.
|
|
*
|
|
* NOTE: the entry point 'next_block' can be used to get the
|
|
* next block # without doing the read.
|
|
*
|
|
* Created: Nov 9, 1987
|
|
* Modified: Mar 29, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* log_blk_size ;logical block size.
|
|
* real_log_size ;usually same as log_blk_size.
|
|
* drvr_blk_num ;current directory block.
|
|
* end_block ;last block # of file/directory.
|
|
* interleave_size ;# contiguous blocks.
|
|
* interleave_skip ;# blocks between contiguous.
|
|
* skip_count ;# blocks till skip. Init to int._size!
|
|
*
|
|
* Interleaved file (blocks):
|
|
* ___________________________________________________________________
|
|
* | a | a | a | a | b | b | a | a | a | a | b | b | a | a | a |a | b >
|
|
* |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___<
|
|
*
|
|
* for file 'a': interleave_size = 4
|
|
* interleave_skip = 2
|
|
*
|
|
* for file 'b': interleave_size = 2
|
|
* interleave_skip = 4
|
|
*
|
|
* Output: A = error code if error.
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* skip_read_flag
|
|
* drvr_blk_num
|
|
* skip_count
|
|
* read_with_flag (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
read_next_block proc
|
|
with data
|
|
|
|
*
|
|
* Clear skip_read_flag and continue...
|
|
*
|
|
stz skip_read_flag ;Clear flag.
|
|
bra check_trans ;Continue.
|
|
*
|
|
* Set skip_read_flag and continue...
|
|
*
|
|
export next_block
|
|
next_block ;
|
|
lda #$8000 ;Set flag.
|
|
sta skip_read_flag
|
|
*
|
|
* Is log_blk_size = trans_blk_size?
|
|
*
|
|
check_trans ldx drvr_blk_num ;Get low word of block #.
|
|
lda drvr_blk_num+2 ;Get high word of block #.
|
|
ldy real_log_size ;Get real logical size.
|
|
cpy log_blk_size ;Same as current logical size?
|
|
beq bump_block ;Yep.
|
|
*
|
|
* Nope, so we must be dealing with a directory. Add 4 to block number if
|
|
* real logical = 512, else add 2 (logical must be 1024). We can skip the
|
|
* interleave stuff 'cuz directories cannot be interleaved...
|
|
*
|
|
lda #4 ;Init offset to 4.
|
|
cpy #512 ;Logical = 512?
|
|
beq do_add ;Yep.
|
|
lda #2 ;Nope, so set offset to 2 (must be 1024)
|
|
do_add clc ;Add offset to block number.
|
|
adc drvr_blk_num
|
|
tax
|
|
lda #0
|
|
adc drvr_blk_num+2
|
|
bra check_end ;Continue.
|
|
*
|
|
* Yes, so bump block #...
|
|
*
|
|
bump_block inx ;Bump block #. Rollover?
|
|
bne check_int ;Nope.
|
|
inc a ;Yes, bump high word.
|
|
*
|
|
* Check for interleave gap and add in skip if needed...
|
|
*
|
|
check_int dec skip_count ;Time to skip?
|
|
bne check_end ;Nope.
|
|
|
|
tay ;Yes, save A.
|
|
lda interleave_size ;Interleave_size zero?
|
|
bne set_skip ;Nope.
|
|
dec a ;Yes, so make $ffff.
|
|
set_skip sta skip_count ;Reset skip_count.
|
|
clc ;Add interleave_skip to block #.
|
|
txa
|
|
adc interleave_skip
|
|
tax
|
|
tya
|
|
adc #0
|
|
*
|
|
* Did that put us past the end block? Exit if so...
|
|
*
|
|
check_end cmp end_block+2 ;Are we past end_block?
|
|
bcc ok ;Nope.
|
|
bne no_more ;Yes.
|
|
cpx end_block ;Maybe.
|
|
beq ok ;Nope.
|
|
bcs no_more ;Yes.
|
|
*
|
|
* Do read if skip_read_flag clear, else exit with carry clear...
|
|
*
|
|
ok clc ;Clear carry in case flag set.
|
|
bit skip_read_flag ;Flag set?
|
|
bmi exit ;Yep, so exit with carry set.
|
|
jmp read_with_flag ;Nope, so read block.
|
|
*
|
|
* At end, so exit with an end of directory error...
|
|
*
|
|
no_more lda #end_of_dir ;Get error code.
|
|
sec ;Indicate done.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: read_prev_block
|
|
*
|
|
* Description: Reads previous block of file or directory. Will set
|
|
* fcr_error_flag if error occurs during read.
|
|
*
|
|
* Handles differences between log_blk_size and trans_blk_size.
|
|
*
|
|
* NOTE: This routine does not handle interleave!
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: Mar 29, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* log_blk_size ;logical block size.
|
|
* real_log_size ;usually same as log_blk_size.
|
|
* drvr_blk_num ;current directory block.
|
|
* start_block ;first block # of file/directory.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* temp1
|
|
* drvr_blk_num
|
|
* read_with_flag (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
read_prev_block proc
|
|
with data
|
|
|
|
*
|
|
* Is log_blk_size = trans_blk_size?
|
|
*
|
|
ldx drvr_blk_num ;Get low word of block #.
|
|
lda drvr_blk_num+2 ;Get high word of block #.
|
|
ldy real_log_size ;Get real logical size.
|
|
cpy log_blk_size ;Same as logical size?
|
|
beq prev_block ;Yep.
|
|
*
|
|
* Nope, so we must be dealing with a directory. Subtract 4 from block number
|
|
* if logical = 2048, else subtract 2 (logical must be 1024). We can skip the
|
|
* interleave stuff 'cuz directories cannot be interleaved...
|
|
*
|
|
lda #4 ;Init offset to 4.
|
|
cpy #2048 ;Logical = 2048?
|
|
beq do_subtract ;Yep.
|
|
lda #2 ;Nope, so set offset to 2.
|
|
do_subtract sta temp1 ;Save offset.
|
|
sec ;Subtract offset from block number.
|
|
lda drvr_blk_num
|
|
sbc temp1
|
|
tax
|
|
lda drvr_blk_num+2
|
|
sbc #0
|
|
bra check_start ;Continue.
|
|
*
|
|
* Nope, so decrement block #...
|
|
*
|
|
prev_block dex ;Decrement it.
|
|
cpx #$ffff ;Did we rollover?
|
|
bne check_start ;Nope.
|
|
dec a ;Yep, so decrement high word.
|
|
*
|
|
* Did that put us before start_block? If not, exit thru read_with_flag...
|
|
*
|
|
check_start cmp start_block+2 ;Are we before start_block?
|
|
bcc no_more ;Yes.
|
|
bne ok ;Nope.
|
|
cpx start_block ;Maybe.
|
|
bcc no_more ;Yes.
|
|
ok jmp read_with_flag ;No, go read it.
|
|
*
|
|
* Yes, so exit with an end of directory error...
|
|
*
|
|
no_more lda #end_of_dir ;Get error code.
|
|
sec ;Indicate done.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: read_with_flag
|
|
*
|
|
* Description: Reads block and sets/clears FCR error flag.
|
|
*
|
|
* NOTE: The entry point 'condition_flag' can be used to
|
|
* set/clear the error flag only.
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: Nov 6, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = high word of block #.
|
|
* X = low word of block #.
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* my_fcr
|
|
* block_read (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
read_with_flag proc
|
|
with data
|
|
|
|
*
|
|
* Do read...
|
|
*
|
|
jsr block_read ;Do read.
|
|
*
|
|
* Set error flag if carry set, else clear it and exit...
|
|
*
|
|
export condition_flag
|
|
condition_flag ;
|
|
|
|
tax ;Save error code.
|
|
lda #0 ;Assume no error.
|
|
bcc continue ;That was the right assumption.
|
|
lda #1 ;Error so get 1.
|
|
continue ldy #fcr_error_flag ;Get offset to error_flag.
|
|
sta [my_fcr],y ;Set/clear flag.
|
|
txa ;Recover error code.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: setup_open_buf
|
|
*
|
|
* Description: Setup pointers and variables for open_buffer. If file is a
|
|
* directory and it is claimed for get_dir_entry, forces
|
|
* log_blk_size to 2k. This is done AFTER the set_end_block call
|
|
* so that the end block will be set correctly.
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: Jan 11, 1989
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
* log_blk_size ;current log_blk_size.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 = error
|
|
* B = K
|
|
*
|
|
* io_buffer ;points to open_buffer in fcr.
|
|
* open_buf_ptr ;points to open_buffer in fcr.
|
|
* start_block ;starting block # of file/directory.
|
|
* end_block ;ending block # of file/directory.
|
|
* interleave_size ;# contiguous blocks.
|
|
* interleave_skip ;# blocks between contiguous blocks.
|
|
* skip_count ;# blocks till next skip.
|
|
* open_mark ;position within open buffer.
|
|
* log_blk_size ;2k if file is a directory.
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
setup_open_buf proc
|
|
with data
|
|
|
|
*
|
|
* Point io_buffer at open_buffer in fcr...
|
|
*
|
|
clc ;Prepare for add.
|
|
ldy #fcr_dir_record ;Get offset to start of dir record.
|
|
lda [my_fcr],y ;Get length of directory.
|
|
and #$00ff ;Clear high byte (1/11/89).
|
|
adc #fcr_dir_record ;Add length to fcr_dir_record.
|
|
adc my_fcr ;Add to my_fcr.
|
|
sta io_buffer ;Save low word of pointer.
|
|
sta open_buf_ptr ;And again.
|
|
lda #0 ;Add carry to high word.
|
|
adc my_fcr+2
|
|
sta io_buffer+2 ;Save high word of pointer.
|
|
sta open_buf_ptr+2 ;And again.
|
|
*
|
|
* Set drvr_blk_num to open_block from fcr in case we need to read another
|
|
* block...
|
|
*
|
|
ldy #fcr_open_block ;Get offset.
|
|
lda [my_fcr],y ;Get low word.
|
|
sta drvr_blk_num ;Save it.
|
|
ldy #fcr_open_block+2 ;Get offset.
|
|
lda [my_fcr],y ;Get high word.
|
|
sta drvr_blk_num+2 ;Save it.
|
|
*
|
|
* Set interleave_size and interleave_skip...
|
|
*
|
|
ldy #fcr_dir_record+dir_int_size ;Get offset to size.
|
|
lda [my_fcr],y ;Get it.
|
|
and #$00ff ;Clear high byte.
|
|
sta interleave_size ;Save it.
|
|
|
|
ldy #fcr_dir_record+dir_int_skip ;Get offset to skip.
|
|
lda [my_fcr],y ;Get it.
|
|
and #$00ff ;Clear high byte.
|
|
sta interleave_skip ;Save it.
|
|
*
|
|
* Set start_block...
|
|
*
|
|
ldy #fcr_dir_record+dir_xar_len ;Point to xar_len.
|
|
lda [my_fcr],y ;Get length.
|
|
and #$00ff ;Clear high byte.
|
|
|
|
clc ;Prepare to add.
|
|
ldy #fcr_dir_record+dir_loc_extent ;Point to low word.
|
|
adc [my_fcr],y ;Add low word to len.
|
|
sta start_block ;Save it.
|
|
ldy #fcr_dir_record+dir_loc_extent+2 ;Point to high word.
|
|
lda [my_fcr],y ;Get high word.
|
|
adc #0 ;Add in carry.
|
|
sta start_block+2 ;Save it.
|
|
*
|
|
* Set end_block...
|
|
*
|
|
ldy #fcr_dir_record+dir_data_length ;Point to low word.
|
|
lda [my_fcr],y ;Get low word.
|
|
tax ;Save it.
|
|
ldy #fcr_dir_record+dir_data_length+2 ;Point to high word.
|
|
lda [my_fcr],y ;Get high word.
|
|
jsr set_end_block ;Set end_block.
|
|
*
|
|
* Set skip_count and open_mark...
|
|
*
|
|
ldy #fcr_skip_count ;Get offset to count.
|
|
lda [my_fcr],y ;Get it.
|
|
sta skip_count ;Save it.
|
|
|
|
ldy #fcr_open_mark ;Get offset to mark.
|
|
lda [my_fcr],y ;Get it.
|
|
sta open_mark ;Save it.
|
|
*
|
|
* Is this a directory? If so, and it is claimed for get_dir_entry, force
|
|
* log_blk_size to 2k, else exit...
|
|
*
|
|
ldy #fcr_storage ;Point at storage type.
|
|
lda [my_fcr],y ;Get type.
|
|
cmp #type_directory ;Is it a directory?
|
|
bcc exit ;Nope.
|
|
ldy #fcr_type_flag ;Yes, get offset to type flag.
|
|
lda [my_fcr],y ;Get flag.
|
|
cmp #2 ;Claimed for get_dir_entry?
|
|
bne exit ;Nope.
|
|
lda #sector_size ;Yes, force log_blk_size = 2k.
|
|
sta log_blk_size
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: check_open_buf
|
|
*
|
|
* Description: Tries to re-fill open_buffer if fcr_error_flag is set.
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: Nov 6, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
* drvr_blk_num ;current open_block.
|
|
* io_buffer ;points to open_buffer in fcr.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
check_open_buf proc
|
|
with data
|
|
*
|
|
* Is error flag set?
|
|
*
|
|
ldy #fcr_error_flag ;Point to flag.
|
|
lda [my_fcr],y ;Get flag. Set?
|
|
bne re_read ;Yes.
|
|
clc ;No, so indicate ok.
|
|
rts ;Exit.
|
|
*
|
|
* Yes, so exit through read_with_flag...
|
|
*
|
|
re_read ldx drvr_blk_num ;Get block #.
|
|
lda drvr_blk_num+2
|
|
jmp read_with_flag ;Read it in.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: set_end_block
|
|
*
|
|
* Description: Calculates and sets end_block.
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: Apr 25, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = high word of file/directory length
|
|
* X = low word of file/directory length
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* start_block ;start_block.
|
|
* log_blk_size ;current log_blk_size.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* end_block ;ending block # of file/directory.
|
|
*
|
|
* Uses: All registers
|
|
* dividend
|
|
* remainder
|
|
* calc_open_block (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
set_end_block proc
|
|
with data
|
|
|
|
*
|
|
* Calculate end block, subtract 1 if open_mark (remainder) = 0, save it
|
|
* and exit...
|
|
*
|
|
jsr calc_open_block ;Calculate block.
|
|
ldy open_mark ;Open_mark = zero?
|
|
bne continue ;Nope.
|
|
dex ;Yep, subtract 1.
|
|
cpx #$ffff
|
|
bne continue
|
|
dec a
|
|
continue stx end_block ;Save end_block.
|
|
sta end_block+2
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: close
|
|
*
|
|
* Description: Closes a file.
|
|
*
|
|
* Created: Nov 3, 1987
|
|
* Modified: Nov 3, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_vcr ;points to vcr.
|
|
* my_fcr ;points to fcr.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* release_fcr (system)
|
|
* sys_death (system)
|
|
*
|
|
******************************************************************************
|
|
|
|
close proc
|
|
with data
|
|
|
|
*
|
|
* Release the FCR...
|
|
*
|
|
lda [my_fcr] ;Get reference #.
|
|
jsl release_fcr ;Release fcr.
|
|
*
|
|
* Decrement VCR open count and exit with carry clear if >= 0...
|
|
*
|
|
ldy #vcr_open_cnt ;Get offset to open count.
|
|
lda [my_vcr],y ;Get open count.
|
|
dec a ;Decrement it.
|
|
cmp #$ffff ;Rollover?
|
|
beq hara_kari ;Yes, we're in deep trouble!
|
|
sta [my_vcr],y ;Nope, so save it.
|
|
clc ;Indicate ok.
|
|
rts ;Exit.
|
|
*
|
|
* Something's terribly wrong here, and we have lost great face: we must commit
|
|
* hara-kari...
|
|
*
|
|
hara_kari lda #$000A ;Get error code for bad VCR.
|
|
jml sys_death ;Die.
|
|
|
|
ENDP
|
|
eject
|
|
*******************************************************************************
|
|
*
|
|
* Name: set_mark
|
|
*
|
|
* Description: Set file position marker and related variables. Will set
|
|
* fcr_error_flag if block # changes.
|
|
*
|
|
* Created: Nov 4, 1987
|
|
* Modified: Nov 13, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
* base ;0: mark = displacement.
|
|
* ;1: mark = eof - displacement.
|
|
* ;2: mark = mark + displacement.
|
|
* ;3: mark = mark - displacement.
|
|
*
|
|
* displacement ;offset.
|
|
*
|
|
* Output: A = error code if error
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0 if no error.
|
|
* 1 if error
|
|
* B = K
|
|
*
|
|
* fcr_open_block ;# of block in open_buffer.
|
|
* fcr_position ;new position.
|
|
* fcr_skip_count ;count to next interleave gap.
|
|
* fcr_open_mark ;position within open_buffer.
|
|
*
|
|
* Uses: All registers
|
|
* calc_open_block (sub)
|
|
* update_fcr (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
set_mark proc
|
|
with data
|
|
|
|
*
|
|
* Get current position and eof...
|
|
*
|
|
ldy #fcr_position ;Point to low word.
|
|
lda [my_fcr],y ;Get low word.
|
|
sta position ;Save it.
|
|
ldy #fcr_position+2 ;Point to high word.
|
|
lda [my_fcr],y ;Get high word.
|
|
sta position+2 ;Save it.
|
|
|
|
ldy #fcr_eof ;Point to low word.
|
|
lda [my_fcr],y ;Get low word.
|
|
sta eof ;Save it.
|
|
ldy #fcr_eof+2 ;Point to high word.
|
|
lda [my_fcr],y ;Get high word.
|
|
sta eof+2 ;Save it.
|
|
*
|
|
* Now branch to the correct handler...
|
|
*
|
|
ldx base ;Get base. Zero?
|
|
beq base_0 ;Yes.
|
|
dex ;No, 1?
|
|
beq base_1 ;Yes.
|
|
dex ;No, 2?
|
|
beq base_2 ;Yes.
|
|
*
|
|
* Set mark = mark - displacement, then branch to check_range...
|
|
*
|
|
sec ;Prepare for subtract.
|
|
lda position ;Do it.
|
|
sbc displacement
|
|
tax
|
|
lda position+2
|
|
sbc displacement+2
|
|
bcc bad_range ;Oops, went too far back!
|
|
bra check_range ;Continue.
|
|
*
|
|
* Set mark = mark + displacement, then branch to check_range...
|
|
*
|
|
base_2 clc ;Prepare for add.
|
|
lda position ;Do it.
|
|
adc displacement
|
|
tax
|
|
lda position+2
|
|
adc displacement+2
|
|
bra check_range ;Continue.
|
|
*
|
|
* Set mark = eof - displacement, then branch to check_range...
|
|
*
|
|
base_1 sec ;Prepare for subtract.
|
|
lda eof ;Do it.
|
|
sbc displacement
|
|
tax
|
|
lda eof+2
|
|
sbc displacement+2
|
|
bcc bad_range ;Oops, went too far back!
|
|
bra check_range ;Continue.
|
|
*
|
|
* Set mark = displacement. If displacement = current position then
|
|
* exit with carry clear...
|
|
*
|
|
base_0 ldx displacement ;Get new position.
|
|
lda displacement+2
|
|
cmp position+2 ;Match current?
|
|
bne check_range ;Nope.
|
|
cpx position ;Maybe.
|
|
bne check_range ;Nope.
|
|
clc ;Yes, so exit with carry clear.
|
|
rts
|
|
*
|
|
* Now see if position is past eof (high word of position is in A, low in X).
|
|
* Is it past?
|
|
*
|
|
check_range cmp eof+2 ;Past eof?
|
|
bcc position_ok ;Nope.
|
|
bne bad_range ;Yes.
|
|
cpx eof
|
|
bcc position_ok ;Nope.
|
|
beq position_ok ;Nope.
|
|
*
|
|
* Yes, so exit with an out of range error...
|
|
*
|
|
bad_range lda #out_of_range ;Get error code.
|
|
sec ;Indicate error.
|
|
error rts ;Exit.
|
|
*
|
|
* No, so calculate open_block. Set carry flag if block # has changed...
|
|
*
|
|
position_ok phx ;Save position.
|
|
pha
|
|
jsr setup_open_buf ;Setup open buffer.
|
|
pla ;Recover position.
|
|
plx
|
|
jsr calc_open_block ;Do calculation.
|
|
pha ;Save A.
|
|
|
|
ldy #fcr_open_block+2 ;Get offset to high word of block.
|
|
cmp [my_fcr],y ;Match?
|
|
bne changed ;Nope.
|
|
txa ;Get low word in A.
|
|
dey ;Point to low word of block.
|
|
dey
|
|
cmp [my_fcr],y ;Match?
|
|
bne changed ;Nope.
|
|
clc ;Yes, so clear carry.
|
|
bra recover_a
|
|
|
|
changed sec ;Block # has changed.
|
|
recover_a pla ;Recover low word of block #.
|
|
*
|
|
* Save flag, do update, and recover flag. Set fcr_error_flag if carry set
|
|
* and exit with carry clear...
|
|
*
|
|
php ;Save flag.
|
|
jsr update_fcr ;Do update.
|
|
plp ;Recover flag. Carry clear?
|
|
bcc exit ;Yep.
|
|
ldy #fcr_error_flag ;Get offset to error flag.
|
|
lda #0001 ;Set flag.
|
|
sta [my_fcr],y
|
|
clc ;Indicate no error.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: calc_open_block
|
|
*
|
|
* Description: Calculate block number from position. Handles interleave.
|
|
* If position is < 174k and file is interleaved, routine will
|
|
* use loop_calc, >= 174k will use long_calc. If file is not
|
|
* interleaved, will always use long_calc, in which case the
|
|
* worst case is 1.719 ms.
|
|
*
|
|
* The crossover point of 174k was determined by timing tests
|
|
* with both routines. Using long_calc for positions >=174k
|
|
* ensures that calc_open_block will never take longer than
|
|
* 3.332 ms to complete, and will be significantly faster for
|
|
* positions < 174k.
|
|
*
|
|
* Created: Nov 13, 1987
|
|
* Modified: Apr 25, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = high word of position
|
|
* X = low word of position
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
* start_block ;Starting block # of file/directory.
|
|
* interleave_skip ;# contiguous blocks.
|
|
* interleave_size ;# blocks between contiguous blocks.
|
|
*
|
|
* Output: A = high word of block #
|
|
* X = low word of block #
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* position ;new position.
|
|
* skip_count ;count to next interleave gap.
|
|
* open_mark ;position within open_buffer.
|
|
*
|
|
* Uses: All registers
|
|
* temp1
|
|
* dividend (a.k.a. multiplier)
|
|
* divisor (a.k.a. multiplicand
|
|
* remainder (a.k.a. input_string & output_string)
|
|
* position
|
|
* skip_count
|
|
* open_mark
|
|
*
|
|
******************************************************************************
|
|
|
|
calc_open_block proc
|
|
with data
|
|
|
|
*
|
|
* Calculate logical_block (position/log_blk_size) and set open_mark...
|
|
*
|
|
stx position ;Save position.
|
|
sta position+2
|
|
stx dividend ;Set dividend = position.
|
|
sta dividend+2
|
|
lda log_blk_size ;Set divisor = log_blk_size.
|
|
sta divisor
|
|
stz divisor+2
|
|
jsr long_divide ;Do division.
|
|
lda dividend ;Set log_block = result.
|
|
ldx dividend+2
|
|
sta log_block
|
|
stx log_block+2
|
|
lda remainder ;Set open_mark = remainder.
|
|
sta open_mark
|
|
*
|
|
* Ok, we've done the common calculation. If file is not interleaved or position
|
|
* is >= 174k then branch to long_calc, otherwise use loop_calc...
|
|
*
|
|
lda interleave_size ;Interleaved file?
|
|
beq zero_size ;Nope, so use long_calc.
|
|
lda position+2 ;Position >= 174k?
|
|
cmp #^crossover
|
|
bcc loop_calc ;Nope, so use loop calc.
|
|
lda position ;Maybe.
|
|
cmp #<crossover
|
|
bcs long_calc ;Yes, so use long_calc.
|
|
*
|
|
* Now we are going to increment the block # from start_block till we've done
|
|
* it logical_block times. Init skip_count to interleave_size (or $ffff if
|
|
* interleave_size is zero) and get start_block in X and A...
|
|
*
|
|
loop_calc lda interleave_size ;Get interleave_size. Zero?
|
|
bne set_skip ;Nope.
|
|
dec a ;Yes, so set to $ffff.
|
|
set_skip sta skip_count
|
|
ldx start_block ;Get start_block.
|
|
lda start_block+2
|
|
*
|
|
* Are we at the correct block? Exit if we are...
|
|
*
|
|
advance_loop dec dividend ;Decrement dividend.
|
|
ldy dividend ;Get it.
|
|
cpy #$ffff ;Rollover?
|
|
bne continue ;Nope.
|
|
dec dividend+2 ;Yep, decrement high word.
|
|
ldy dividend+2 ;Get it.
|
|
cpy #$ffff ;Rollover?
|
|
bne continue ;Nope.
|
|
rts ;Yes, so exit.
|
|
*
|
|
* No, so bump block #...
|
|
*
|
|
continue inx ;Bump block #. Rollover?
|
|
bne check_gap ;Nope.
|
|
inc a ;Yep.
|
|
*
|
|
* Loop if we're not at an interleave gap...
|
|
*
|
|
check_gap dec skip_count ;At a gap?
|
|
bne advance_loop ;Nope.
|
|
*
|
|
* We're at a gap. Reset skip_count to interleave_size ($ffff if zero), add
|
|
* interleave_skip to block #, and loop...
|
|
*
|
|
tay ;Save A.
|
|
lda interleave_size ;Get size. Zero?
|
|
bne reset_a ;Nope.
|
|
dec a ;Yes, so make $ffff.
|
|
reset_a sta skip_count ;Save it.
|
|
clc ;Add interleave_skip to block #.
|
|
txa
|
|
adc interleave_skip
|
|
tax
|
|
tya
|
|
adc #0
|
|
bra advance_loop ;Loop.
|
|
|
|
|
|
* LONG_CALC
|
|
* If interleave_size is zero we can skip most of the following calculations;
|
|
* all we have to do is set skip_count to $ffff and continue on at do_add...
|
|
*
|
|
long_calc lda interleave_size ;Get interleave_size. Zero?
|
|
bne calc_gap ;Nope.
|
|
zero_size dec a ;Yes, so set skip_count = $ffff.
|
|
sta skip_count
|
|
bra do_add ;Continue at do_add.
|
|
*
|
|
* Not zero so calculate gap_count (logical_block/interleave_size). Logical_block
|
|
* is already in dividend...
|
|
*
|
|
calc_gap sta divisor ;Set divisor = interleave_size.
|
|
stz divisor+2
|
|
jsr long_divide ;Do division.
|
|
*
|
|
* Calculate skip_count (interleave_size - remainder of last calculation). If
|
|
* result is zero, reset skip_count to interleave_size...
|
|
*
|
|
sec ;Do subtraction. Zero result?
|
|
lda interleave_size
|
|
sbc remainder
|
|
bne set_count ;Nope.
|
|
lda interleave_size ;Yes, so reset to interleave_size.
|
|
set_count sta skip_count ;Save count.
|
|
*
|
|
* Calculate absolute_block (start_block + logical_block
|
|
* + gap_count(interleave_skip)). gap_count is in multiplier (a.k.a. dividend)
|
|
* already. Exit with absolute_block in A and X...
|
|
*
|
|
lda interleave_skip ;Set multiplicand = interleave_skip.
|
|
sta multiplicand
|
|
stz multiplicand+2
|
|
jsr long_multiply ;Do multiplication.
|
|
clc ;Add logical_block.
|
|
lda product
|
|
adc log_block
|
|
sta log_block
|
|
lda product+2
|
|
adc log_block+2
|
|
sta log_block+2
|
|
do_add clc ;Add start_block.
|
|
lda log_block
|
|
adc start_block
|
|
tax
|
|
lda log_block+2
|
|
adc start_block+2
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: update_fcr
|
|
*
|
|
* Description: Fill in fcr position information.
|
|
*
|
|
* Created: Nov 17, 1987
|
|
* Modified: Nov 17, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = high word of block #
|
|
* X = low word of block #
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
* position ;new position.
|
|
* skip_count ;count to next interleave gap.
|
|
* open_mark ;position within open_buffer.
|
|
*
|
|
* Output: A = high word of block #
|
|
* X = low word of block #
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* fcr_position ;new position.
|
|
* fcr_open_block ;# of block in open_buffer.
|
|
* fcr_skip_count ;count to next interleave gap.
|
|
* fcr_open_mark ;position within open_buffer.
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
update_fcr proc
|
|
with data
|
|
|
|
*
|
|
* Put block # in fcr...
|
|
*
|
|
pha ;Save high word of block.
|
|
|
|
ldy #fcr_open_block+2 ;Get offset to high word of field.
|
|
sta [my_fcr],y ;Fill it in.
|
|
dey ;Point to low word.
|
|
dey
|
|
txa ;Get low word.
|
|
sta [my_fcr],y ;Fill it in.
|
|
*
|
|
* Put position in fcr...
|
|
*
|
|
ldy #fcr_position ;Get offset to low word of field.
|
|
lda position ;Get low word of position.
|
|
sta [my_fcr],y ;Fill it in.
|
|
iny ;Point to high word.
|
|
iny
|
|
lda position+2 ;Get high word.
|
|
sta [my_fcr],y ;Fill it in.
|
|
*
|
|
* Put open_mark in fcr...
|
|
*
|
|
ldy #fcr_open_mark ;Get offset to field.
|
|
lda open_mark ;Get mark.
|
|
sta [my_fcr],y ;Fill it in.
|
|
*
|
|
* Put skip_count in fcr...
|
|
*
|
|
ldy #fcr_skip_count ;Get offset to field.
|
|
lda skip_count ;Get skip_count.
|
|
sta [my_fcr],y ;Fill it in.
|
|
*
|
|
* Recover high word of block # (low is in X) and exit...
|
|
*
|
|
pla ;Recover high word of block #.
|
|
rts ;Exit
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_mark
|
|
*
|
|
* Description: Gets mark for open file.
|
|
*
|
|
* Created: Nov 3, 1987
|
|
* Modified: Nov 3, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
get_mark proc
|
|
with data
|
|
|
|
*
|
|
* Copy position out of fcr...
|
|
*
|
|
ldy #fcr_position ;Get offset to low word of position.
|
|
lda [my_fcr],y ;Get low word.
|
|
sta position ;Save it.
|
|
|
|
ldy #fcr_position+2 ;Get offset to high word of position.
|
|
lda [my_fcr],y ;Get high word.
|
|
sta position+2 ;Save it.
|
|
*
|
|
* Send output and exit...
|
|
*
|
|
jmp send_output ;Send it.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_eof
|
|
*
|
|
* Description: Gets eof for open file.
|
|
*
|
|
* Created: Nov 3, 1987
|
|
* Modified: Nov 3, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
get_eof proc
|
|
with data
|
|
|
|
*
|
|
* Copy eof out of fcr...
|
|
*
|
|
ldy #fcr_eof ;Get offset to low word of eof.
|
|
lda [my_fcr],y ;Get low word.
|
|
sta eof ;Save it.
|
|
|
|
ldy #fcr_eof+2 ;Get offset to high word of eof.
|
|
lda [my_fcr],y ;Get high word.
|
|
sta eof+2 ;Save it.
|
|
*
|
|
* Send output and exit...
|
|
*
|
|
jmp send_output ;Send it.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_dir_entry
|
|
*
|
|
* Description: Returns directory information.
|
|
*
|
|
* Created: Nov 4, 1987
|
|
* Modified: Apr 8, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_fcr ;points to fcr.
|
|
* base ;0: entry_num = displacement.
|
|
* ;1: entry_num = entry_num+displacement.
|
|
* ;2: entry_num = entry_num-displacement.
|
|
* displacement ;entry number.
|
|
*
|
|
* Output: A = error code if carry set
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* entry_num ;entry number returned.
|
|
*
|
|
* Uses: All registers
|
|
* send_output (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
get_dir_entry proc
|
|
with data
|
|
|
|
*
|
|
* Is this fcr for a directory?
|
|
*
|
|
ldy #fcr_storage ;Get offset to storage type.
|
|
lda [my_fcr],y ;Get type.
|
|
cmp #type_directory ;Is it a directory?
|
|
bcs ok ;Yes.
|
|
*
|
|
* No, so exit with an error...
|
|
*
|
|
lda #version_error ;Get error code.
|
|
error_exit sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Check our fcr_type_flag and exit with invalid_access error if this FCR
|
|
* has been accessed by read. If the flag is clear, claim this file
|
|
* for get_dir_entry by setting the flag to 2...
|
|
*
|
|
ok ldy #fcr_type_flag ;Get offset to type_flag.
|
|
lda [my_fcr],y ;Get flag. Set already?
|
|
bne check_flag ;Yes.
|
|
lda #2 ;No, so set it to 2.
|
|
sta [my_fcr],y
|
|
bra do_setup ;And continue.
|
|
|
|
check_flag cmp #2 ;Are we allowed to access this file?
|
|
beq do_setup ;Yep.
|
|
lda #invalid_access ;Nope, so exit with error.
|
|
bra error_exit
|
|
*
|
|
* Make sure volume is online and setup some variables from the vcr...
|
|
*
|
|
do_setup jsr setup_volume ;Do setup. Online?
|
|
bcs exit ;Nope.
|
|
*
|
|
* Turn on caching and set current entry_num...
|
|
*
|
|
lda #in_cache ;Turn on caching.
|
|
sta drvr_cache
|
|
|
|
ldy #fcr_entry_num ;Get offset.
|
|
lda [my_fcr],y ;Get entry_num.
|
|
sta entry_num ;Save it.
|
|
*
|
|
* Clear out dir_record_0 and dir_record_1, call setup_open_buf and
|
|
* check_open_buf...
|
|
*
|
|
jsr clear_dir_recs ;Clear em.
|
|
jsr setup_open_buf ;Setup pointers and variable.
|
|
jsr check_open_buf ;Make sure data in buffer is valid.
|
|
bcs exit ;Error.
|
|
*
|
|
* Branch to correct calculation routine or exit with error if base out
|
|
* of range...
|
|
*
|
|
ldx base ;Get base. Zero?
|
|
beq base_0 ;Yes.
|
|
dex ;No, 1?
|
|
beq base_1 ;Yes.
|
|
dex ;No, 2?
|
|
beq base_2 ;Yes.
|
|
|
|
lda #parm_range_err ;No, get error code.
|
|
sec ;Indicate error.
|
|
rts ;Exit.
|
|
*
|
|
* Set entry_num = entry_number - displacement...
|
|
*
|
|
base_2 sec ;Prepare for subtraction.
|
|
lda entry_num ;Do it.
|
|
sbc displacement
|
|
bcs save_it ;Continue.
|
|
|
|
hit_end lda #end_of_dir ;Passed beginning. Get error code.
|
|
error sec ;Indicate error.
|
|
exit rts ;Exit.
|
|
*
|
|
* Set entry_num = entry_number + displacement...
|
|
*
|
|
base_1 clc ;Prepare for addition.
|
|
lda entry_num ;Do it.
|
|
adc displacement
|
|
bcs hit_end ;Out of range!
|
|
bra save_it ;Continue.
|
|
*
|
|
* Set entry_num = displacement. If displacement is zero then we need to
|
|
* count the entries...
|
|
*
|
|
base_0 lda displacement ;Get displacement. Zero?
|
|
bne save_it ;Nope.
|
|
*
|
|
* Both base and displacement fields are zero, so we must count records
|
|
* in the directory. Go find record #1 then clear entry_num and clear it
|
|
* in the fcr too...
|
|
*
|
|
inc a ;Set entry_num to 1.
|
|
sta entry_num
|
|
jsr find_dir_record ;Go find it.
|
|
bcs error ;Error.
|
|
lda #0 ;Get zero.
|
|
sta entry_num ;Clear entry_num.
|
|
ldy #fcr_entry_num ;Point to entry_num in fcr.
|
|
sta [my_fcr],y ;Clear it.
|
|
*
|
|
* Count records in this block and add to entry_num...
|
|
*
|
|
count_loop jsr count_dir_recs ;Count them.
|
|
clc ;Add count to entry_num.
|
|
txa
|
|
adc entry_num ;Did we rollover?
|
|
bcc save_num ;Nope.
|
|
lda #$ffff ;Yes, so set to max.
|
|
save_num sta entry_num ;Save it.
|
|
sta current_record ;Save for do_update.
|
|
*
|
|
* Go get next block, update fcr and loop. Exit loop when we get an error
|
|
* from read_next_block...
|
|
*
|
|
jsr read_next_block ;Get next block. Error?
|
|
bcs got_error ;Yep.
|
|
inc current_record ;Nope, bump current by 1.
|
|
jsr do_update ;Update fcr.
|
|
bra count_loop ;Loop.
|
|
*
|
|
* We got an error. If it's not an end_of_dir error then exit, else find
|
|
* last record and exit thru count_exit...
|
|
*
|
|
got_error cmp #end_of_dir ;End of dir error?
|
|
bne error ;Nope, so real error.
|
|
jsr find_dir_record ;Get last record.
|
|
bcs error ;Error.
|
|
bra count_exit ;Exit.
|
|
*
|
|
* We're doing a normal call. Save entry_num and go search for it. Found?
|
|
*
|
|
save_it sta entry_num ;Save it.
|
|
jsr find_dir_record ;Go search. Found?
|
|
bcs error ;Nope, so error.
|
|
*
|
|
* Yes, so put entry_num in fcr...
|
|
*
|
|
ldy #fcr_entry_num ;Get offset to entry_num.
|
|
lda entry_num ;Get it.
|
|
sta [my_fcr],y ;Save it.
|
|
*
|
|
* Copy name to file_name...
|
|
*
|
|
lda dir_record_0+dir_len_fi ;Get name length.
|
|
and #$00ff ;Clear high byte.
|
|
sta file_name ;Put length in file_name.
|
|
tay ;Use as offset.
|
|
bne cont ;Continue if non-zero.
|
|
inc file_name ;Zero, so force length to 1.
|
|
lda #'AB' ;Set name to 'A'.
|
|
sta file_name+1
|
|
bra count_exit ;Exit.
|
|
|
|
longa off ;Set 8 bit A.
|
|
cont sep #$20
|
|
|
|
copy_name lda dir_record_0+dir_len_fi,y ;Get byte.
|
|
sta file_name+1,y ;Put in file_name.
|
|
dey ;Done all?
|
|
bne copy_name ;Nope, so loop.
|
|
|
|
longa on ;Set 16 bit A.
|
|
rep #$20
|
|
*
|
|
* Get eof & blocks_used, and exit thru send_output...
|
|
*
|
|
count_exit jsr get_dir_info ;Get eof & blocks_used.
|
|
jmp send_output ;Exit thru send_output.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: find_dir_record
|
|
*
|
|
* Description: Searches directory for specific record and moves it to
|
|
* dir_record_0.
|
|
*
|
|
* Created: Nov 4, 1987
|
|
* Modified: July 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* entry_num ;entry to find.
|
|
* my_fcr ;points to fcr for directory.
|
|
*
|
|
* Output: A = error code if error.
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* dir_record_0 ;holds record if found.
|
|
* extended_flag ;$8000 if record has associated file.
|
|
*
|
|
* Uses: All registers
|
|
* current_record
|
|
* record_offset
|
|
* length
|
|
* io_buffer (points to open_buffer in fcr!)
|
|
* read_next_block (sub)
|
|
* read_prev_block (sub)
|
|
* move_dir_record (sub)
|
|
*
|
|
******************************************************************************
|
|
|
|
find_dir_record proc
|
|
with data
|
|
|
|
*
|
|
* Set current_record to record # of first record of the current directory
|
|
* block, and set extended_flag if b15 set...
|
|
*
|
|
stz extended_flag ;Clear extended_flag.
|
|
|
|
ldy #fcr_start_rec ;Get offset to start record.
|
|
lda [my_fcr],y ;Get start record.
|
|
and #set_extended ;Extended bit set?
|
|
beq set_record ;Nope.
|
|
sta extended_flag ;Yep, so set extended_flag.
|
|
set_record lda [my_fcr],y ;Recover start record.
|
|
and #$7fff ;Clear b15.
|
|
sta current_record ;Save it.
|
|
*
|
|
* Is current_record greater than entry_num?
|
|
*
|
|
cmp entry_num ;current_record > entry_num?
|
|
bcc search ;No, we're ok.
|
|
beq search ;No, we're ok.
|
|
*
|
|
* Yes, so get previous directory block, set new current record. Keep going
|
|
* back until we are before the entry we want or are exactly on it...
|
|
*
|
|
back_up jsr read_prev_block ;Get previous.
|
|
bcs error_hop ;Error.
|
|
jsr count_dir_recs ;Count records.
|
|
sec ;Adjust current record.
|
|
lda current_record
|
|
sbc record_count
|
|
sta current_record
|
|
stz extended_flag ;Clear extended flag.
|
|
jsr do_update ;Set new open_block and start_rec.
|
|
lda current_record ;Recover current record.
|
|
cmp entry_num ;Are we before the entry we want?
|
|
bcc search ;Yep.
|
|
beq at_entry ;No, we're right on it.
|
|
bra back_up ;Nope, so back up a block.
|
|
*
|
|
* We're on exactly the one we want. Are we looking at entry number 1?
|
|
*
|
|
at_entry cmp #1 ;Entry 1?
|
|
beq search ;Yep, so continue.
|
|
*
|
|
* No. This means that we want the first record in this block. Since we had
|
|
* to back up to get here, the extended_flag is not set correctly. To set it,
|
|
* we must read the previous block, call count_dir_recs, then re-read the
|
|
* current block...
|
|
*
|
|
jsr read_prev_block ;Read previous block.
|
|
bcs error_hop ;Exit on error.
|
|
jsr count_dir_recs ;Go set the extended_flag.
|
|
jsr read_next_block ;Recover block.
|
|
bcc read_ok ;Continue on no error.
|
|
error_hop brl error ;Exit on error.
|
|
|
|
read_ok jsr do_update ;Update fcr.
|
|
lda current_record ;Recover current record.
|
|
*
|
|
* Ok, we've got the starting block in the fcr (pointed to now by io_buffer) and
|
|
* we have the record # of the first record in this block. We're ready to start
|
|
* searching forwards. Init record_offset...
|
|
*
|
|
search ldy #0 ;Init offset.
|
|
tax ;Put current_record in X.
|
|
*
|
|
* Have we done all records in this block?
|
|
*
|
|
search_loop sty record_offset ;Save offset.
|
|
cpy log_blk_size ;Done all?
|
|
bcs next_block ;Yes, so next block.
|
|
lda [io_buffer],y ;No, get length of record.
|
|
and #$00ff ;Look at low byte only. Zero?
|
|
beq next_block ;Yes, so next block.
|
|
sta length ;Save length.
|
|
*
|
|
* No. Clear extended_flag and skip this record if the name is either a 0 or a 1.
|
|
* (carry is clear from cpy log_blk_size!)...
|
|
*
|
|
tya ;Get offset. (carry still clear!)
|
|
adc #dir_file_id ;Adjust to point to file name.
|
|
tay
|
|
lda [io_buffer],y ;Get 1st byte of name.
|
|
and #$00ff
|
|
cmp #2 ;Is it a 0 or a 1?
|
|
bcs check_dir ;Nope, so check it.
|
|
stz extended_flag ;Yes, clear flag.
|
|
bra skip_record ;Skip record.
|
|
*
|
|
* Is the file a directory? Clear extended flag and branch to check_record if so...
|
|
*
|
|
check_dir clc ;Adjust offset to point to file flags.
|
|
lda record_offset
|
|
adc dir_file_flags
|
|
tay
|
|
lda [io_buffer],y ;Get file flags.
|
|
and #dir_mask ;Is this a directory?
|
|
beq check_assoc ;Nope.
|
|
stz extended_flag ;Yes, clear flag.
|
|
bra check_record ;Continue.
|
|
*
|
|
* If the file is an associated file and this is an ISO 9660 volume, set extended_flag.
|
|
* If we are at the correct record number, copy record to dir_record_1 then skip
|
|
* record...
|
|
*
|
|
check_assoc lda [io_buffer],y ;Get file flags.
|
|
and #assoc_mask ;Is this an associated file?
|
|
beq check_record ;Nope.
|
|
lda state_flag ;Yep, is this a High Sierra volume?
|
|
and #iso_bit
|
|
beq skip_record ;Yep, so skip record.
|
|
lda #set_extended ;Nope, set flag.
|
|
sta extended_flag
|
|
cpx entry_num ;Are we at the correct record?
|
|
bne skip_record ;Nope.
|
|
pei length ;Yep, save length.
|
|
phx ;Save X.
|
|
lda #0001 ;Copy record to dir_record_1.
|
|
jsr move_dir_record
|
|
plx ;Recover X.
|
|
pla ;Restore length.
|
|
sta length
|
|
bra skip_record ;Skip record.
|
|
*
|
|
* Are we at the correct record?
|
|
*
|
|
check_record cpx entry_num ;Are we there yet, mom?
|
|
beq found ;Yes.
|
|
*
|
|
* No, so bump record # and clear extended_flag...
|
|
*
|
|
inx ;Bump record #.
|
|
stz extended_flag ;Clear flag.
|
|
*
|
|
* Skip to the next record...
|
|
*
|
|
skip_record clc ;Add length to offset.
|
|
lda length
|
|
adc record_offset
|
|
tay
|
|
bra search_loop ;And loop.
|
|
*
|
|
* Get next directory block. Set new current_record, call next_dir_block,
|
|
* update fcr, and loop...
|
|
*
|
|
next_block stx current_record ;Save record.
|
|
jsr read_next_block ;Get next.
|
|
bcs error ;Error.
|
|
jsr do_update ;Set new open_block and start_rec.
|
|
lda current_record ;Recover current record.
|
|
brl search ;Continue search.
|
|
*
|
|
* We found it. Move record to dir_record_0 and exit with carry clear...
|
|
*
|
|
found stx current_record ;Save current record.
|
|
lda #0 ;Select dir_record_0.
|
|
jsr move_dir_record ;Move it.
|
|
clc ;Indicate found.
|
|
error rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: count_dir_recs
|
|
*
|
|
* Description: Count # of records in directory block.
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: July 28, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* io_buffer ;points to directory block.
|
|
* log_blk_size ;current log_blk_size.
|
|
*
|
|
* Output: A = undefined
|
|
* X = count
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..1 = error
|
|
* 0 = no error
|
|
* B = K
|
|
*
|
|
* record_count ;holds count.
|
|
* extended_flag ;$8000 if last entry is associated.
|
|
*
|
|
* Uses: All registers
|
|
* record_count
|
|
* length
|
|
*
|
|
******************************************************************************
|
|
|
|
count_dir_recs proc
|
|
with data
|
|
|
|
*
|
|
* Init offset, extended_flag and count...
|
|
*
|
|
ldy #0 ;Init offset.
|
|
sty extended_flag ;Clear extended_flag.
|
|
tyx ;Init count.
|
|
*
|
|
* Have we done all records in this block?
|
|
*
|
|
count_loop sty record_offset ;Save offset.
|
|
cpy log_blk_size ;Done all?
|
|
bcs done ;Yes, done.
|
|
lda [io_buffer],y ;No, get length of record.
|
|
and #$00ff ;Look at low byte only. Zero?
|
|
beq done ;Yes, so done.
|
|
sta length ;Save length.
|
|
*
|
|
* No. Is the file a directory? (carry is clear from cpy log_blk_size!)...
|
|
*
|
|
tya ;Get offset.
|
|
adc dir_file_flags ;Adjust to point to file flags.
|
|
tay
|
|
lda [io_buffer],y ;Get file flags.
|
|
and #dir_mask ;Is this a directory?
|
|
beq check_assoc ;Nope.
|
|
*
|
|
* Yes, clear extended_flag and skip this record if the name is either a 0 or a
|
|
* 1...
|
|
*
|
|
stz extended_flag ;Clear flag.
|
|
|
|
lda record_offset ;Get offset. (carry still clear!)
|
|
adc #dir_file_id ;Adjust to point to file name.
|
|
tay
|
|
lda [io_buffer],y ;Get 1st byte of name.
|
|
and #$00ff
|
|
cmp #2 ;Is it a 0 or a 1?
|
|
bcc skip_record ;Yes, so ignore it.
|
|
bra bump_record ;Nope, so bump record #.
|
|
*
|
|
* No, if the file is an associated file and the volume is High Sierra, set
|
|
* extended_flag and skip record...
|
|
*
|
|
check_assoc lda [io_buffer],y ;Get file flags.
|
|
and #assoc_mask ;Is this an associated file?
|
|
beq bump_record ;Nope.
|
|
lda state_flag ;Yep, is this a High Sierra volume?
|
|
and #iso_bit
|
|
beq skip_record ;Yep, so skip record.
|
|
lda #set_extended ;Nope, set flag.
|
|
sta extended_flag
|
|
bra skip_record ;Skip record.
|
|
*
|
|
* Bump record # and clear extended_flag...
|
|
*
|
|
bump_record inx ;Bump record #.
|
|
stz extended_flag ;Clear flag.
|
|
*
|
|
* Skip to the next record...
|
|
*
|
|
skip_record clc ;Add length to offset.
|
|
lda length
|
|
adc record_offset
|
|
tay
|
|
bra count_loop ;And loop.
|
|
*
|
|
* Save count and exit...
|
|
*
|
|
done stx record_count ;Save count.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: do_update
|
|
*
|
|
* Description: Sets fcr_open_block and fcr_start_record.
|
|
*
|
|
* Created: Nov 6, 1987
|
|
* Modified: Apr 8, 1988
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* current_record ;current record #.
|
|
* extended_flag ;$8000 if last record is associated.
|
|
* drvr_blk_num ;current block #.
|
|
*
|
|
* Output: A = current_record
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
* current_record
|
|
* drvr_blk_num
|
|
*
|
|
******************************************************************************
|
|
|
|
do_update proc
|
|
with data
|
|
|
|
*
|
|
* Set fcr_open_block and fcr_start_rec and exit...
|
|
*
|
|
ldy #fcr_open_block ;Get offset to low word of open_block.
|
|
lda drvr_blk_num ;Get low word of current block.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
ldy #fcr_open_block+2 ;Get offset to high word of open_block.
|
|
lda drvr_blk_num+2 ;Get high word of current block.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
|
|
ldy #fcr_start_rec ;Get offset to start record.
|
|
lda current_record ;Get current record.
|
|
ora extended_flag ;Add id extended_flag.
|
|
sta [my_fcr],y ;Put in fcr.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_dev_num
|
|
*
|
|
* Description: Get device number of requested volume.
|
|
*
|
|
* Created: Nov 3, 1987
|
|
* Modified: Nov 3, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Uses: All registers
|
|
*
|
|
******************************************************************************
|
|
|
|
get_dev_num proc
|
|
with data
|
|
|
|
*
|
|
* Did we get passed a device number?
|
|
*
|
|
lda dev_num ;Do we have a device #?
|
|
bne got_it ;Yes.
|
|
*
|
|
* No, so use the volume name to find it...
|
|
*
|
|
jsr process_path ;Go look. Found?
|
|
bcs error ;Nope.
|
|
lda drvr_dev_num ;Yes, get device number.
|
|
*
|
|
* Save device number, send output and exit...
|
|
*
|
|
got_it sta dev_number ;Save number.
|
|
jsr send_output ;Send it.
|
|
error rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: fst_specific
|
|
*
|
|
* Description: This routine is a dispatcher for the fst_specific calls. It
|
|
* uses command_num to dispatch to the correct routine.
|
|
*
|
|
* NOTE: These routines do not use send_output to return
|
|
* parameters, but do it themselves.
|
|
*
|
|
* Created: Dec 4, 1987
|
|
* Modified: Dec 4, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* command_num ;command_num
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
*
|
|
******************************************************************************
|
|
|
|
fst_specific proc
|
|
with data
|
|
|
|
*
|
|
* Dispatch to the selected routine...
|
|
*
|
|
lda command_num ;Get command number.
|
|
asl a ;Multiply by 2.
|
|
tax ;Use as index.
|
|
jmp (specific_cmds,x) ;Jump to it.
|
|
|
|
ENDP
|
|
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: post_volume_changed
|
|
*
|
|
* Description: This routine calls the GS/OS notification queue with a volume-
|
|
* changed event for every MS-DOS VCR that's swapped in.
|
|
*
|
|
* Created: 25-Aug-92
|
|
* Modified: 25-Aug-92
|
|
* Author: Dave Lyons
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
*
|
|
******************************************************************************
|
|
|
|
post_volume_changed proc Export
|
|
|
|
temp_ptr equ my_fcr
|
|
|
|
lda #$0001 ;Start with the first FST
|
|
more jsl get_vcr ;Ask for the VCR
|
|
bcs done ;Past the last VCR
|
|
|
|
jsl deref ;Deref VP into temp_ptr
|
|
stx <temp_ptr
|
|
sty <temp_ptr+2
|
|
|
|
ldy #vcr_fst_id
|
|
lda [<temp_ptr],y
|
|
cmp #highSierraFSID ;is it our volume?
|
|
beq @ours
|
|
cmp #iso9660FSID ;I said, is it our volume?
|
|
bne next_vcr
|
|
@ours
|
|
ldy #vcr_status
|
|
lda [<temp_ptr],y
|
|
and #vcr_swapped ; bit set if VCR swapped out
|
|
bne next_vcr
|
|
|
|
pea $2033 ; call number (for A) = FSTSpecific
|
|
ldy #vcr_dev ; get device number
|
|
lda [<temp_ptr],y
|
|
pha ; to be passed in X
|
|
pha ; undefined: passed in Y
|
|
lda #<volume_change ; get event code in A,X
|
|
ldx #^volume_change
|
|
jsl post_os_event ; signal the event
|
|
|
|
next_vcr lda #$0000 ;Value for get next vcr
|
|
bra more
|
|
|
|
done rts
|
|
|
|
EndP
|
|
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: map_enable
|
|
*
|
|
* Description: This routine enables or disables file type mapping.
|
|
*
|
|
* Created: Dec 16, 1987
|
|
* Modified: Dec 16, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_pblk ;points to parameter block.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* my_pblk
|
|
* map_enable_flag
|
|
* temp1
|
|
*
|
|
******************************************************************************
|
|
|
|
map_enable proc
|
|
with data
|
|
|
|
*
|
|
* Setup pointer to current map...
|
|
*
|
|
lda map_buffer_ptr ;Get pointer.
|
|
ldx map_buffer_ptr+2
|
|
sta map_ptr ;Put in direct page pointer.
|
|
stx map_ptr+2
|
|
*
|
|
* Set map_enable_flag and exit with carry clear...
|
|
*
|
|
ldy #map_enable_off ;Get offset to map_enable.
|
|
lda [my_pblk],y ;Get flag.
|
|
cmp map_enable_flag ;added 25-Aug-92 DAL
|
|
sta map_enable_flag ;Save it.
|
|
*** added 25-Aug-92 DAL
|
|
beq @skip_changed
|
|
jsr post_volume_changed
|
|
@skip_changed
|
|
*** end 25-Aug-92
|
|
clc ;No error.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_map_size
|
|
*
|
|
* Description: This routine returns the size of the current file type map in
|
|
* the callers parameter block.
|
|
*
|
|
* Created: Dec 4, 1987
|
|
* Modified: Dec 4, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_pblk ;points to parameter block.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* my_pblk
|
|
* temp1
|
|
*
|
|
******************************************************************************
|
|
|
|
get_map_size proc
|
|
with data
|
|
|
|
*
|
|
* Setup pointer to current map...
|
|
*
|
|
lda map_buffer_ptr ;Get pointer.
|
|
ldx map_buffer_ptr+2
|
|
sta map_ptr ;Put in direct page pointer.
|
|
stx map_ptr+2
|
|
*
|
|
* Get length, stuff it into the parameter block, and exit with carry clear...
|
|
*
|
|
lda [map_ptr] ;Get length.
|
|
|
|
ldy #map_size ;Get offset to map_size.
|
|
sta [my_pblk],y ;Send length.
|
|
|
|
clc ;No error.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: get_map_table
|
|
*
|
|
* Description: This routine copies the current file type map into the buffer
|
|
* pointed to by the map_buffer parameter in the parameter list.
|
|
*
|
|
* NOTE: No checking is done on the size of the caller's buffer!
|
|
*
|
|
* Created: Dec 4, 1987
|
|
* Modified: Dec 4, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_pblk ;points to parameter block.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* my_pblk
|
|
* temp1
|
|
* data_buffer
|
|
*
|
|
******************************************************************************
|
|
|
|
get_map_table proc
|
|
with data
|
|
|
|
*
|
|
* Setup pointer to current map...
|
|
*
|
|
lda map_buffer_ptr ;Get pointer.
|
|
ldx map_buffer_ptr+2
|
|
sta map_ptr ;Put in direct page pointer.
|
|
stx map_ptr+2
|
|
*
|
|
* Get buffer pointer out of parameter list...
|
|
*
|
|
ldy #map_buffer ;Get offset to pointer.
|
|
lda [my_pblk],y ;Get low word of pointer.
|
|
sta data_buffer ;Save it.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [my_pblk],y ;Get high word of pointer.
|
|
sta data_buffer+2 ;Save it.
|
|
*
|
|
* Copy map to data_buffer and exit with carry clear...
|
|
*
|
|
lda [map_ptr] ;Get length of table.
|
|
tay ;Use as offset.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
copy_loop dey ;Done all?
|
|
bmi restore_a ;Yep.
|
|
lda [map_ptr],y ;Nope, get byte.
|
|
sta [data_buffer],y ;Put it in buffer.
|
|
bra copy_loop ;And loop.
|
|
|
|
longa on ;Restore 16 bit A.
|
|
restore_a rep #$20
|
|
|
|
clc ;No error.
|
|
rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
******************************************************************************
|
|
*
|
|
* Name: set_map_table
|
|
*
|
|
* Description: This routine replaces the current file type map with one
|
|
* provided by the caller.
|
|
*
|
|
* Created: Dec 4, 1987
|
|
* Modified: Dec 4, 1987
|
|
* Author: Bryan Atsatt
|
|
*
|
|
* Entry: jsr
|
|
*
|
|
* Input: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000...
|
|
* B = K
|
|
*
|
|
* my_pblk ;points to parameter block.
|
|
*
|
|
* Output: A = undefined
|
|
* X = undefined
|
|
* Y = undefined
|
|
* P = nvmxdizc
|
|
* ..000..0
|
|
* B = K
|
|
*
|
|
* Exit: rts
|
|
*
|
|
* Uses: all registers
|
|
* my_pblk
|
|
* temp1
|
|
* data_buffer
|
|
*
|
|
******************************************************************************
|
|
|
|
set_map_table proc
|
|
with data
|
|
|
|
*
|
|
* Save the current map_buffer_vp so we can release it after we successfully
|
|
* allocate a new one...
|
|
*
|
|
lda map_buffer_vp ;Get vp.
|
|
ldx map_buffer_vp+2
|
|
sta old_vp ;Save it.
|
|
stx old_vp+2
|
|
*
|
|
* Get buffer pointer out of parameter list...
|
|
*
|
|
ldy #map_buffer ;Get offset to pointer.
|
|
lda [my_pblk],y ;Get low word of pointer.
|
|
sta data_buffer ;Save it.
|
|
iny ;Bump offset.
|
|
iny
|
|
lda [my_pblk],y ;Get high word of pointer.
|
|
sta data_buffer+2 ;Save it.
|
|
*
|
|
* Get size of map and allocate memory for it. Exit with out_of_mem error
|
|
* if we couldn't allocate enough memory...
|
|
*
|
|
lda [data_buffer] ;Get size of map
|
|
jsr alloc_seg ;Get a hunk that size.
|
|
lda #out_of_mem ;Get error code in case full.
|
|
bcs exit ;Error, so exit with carry set.
|
|
|
|
stx map_buffer_vp ;Save new vp.
|
|
sty map_buffer_vp+2
|
|
jsl deref ;Dereference vp.
|
|
stx map_ptr ;Save pointer.
|
|
sty map_ptr+2
|
|
*
|
|
* Copy map into map buffer...
|
|
*
|
|
lda [data_buffer] ;Get length of table.
|
|
tay ;Use as offset.
|
|
|
|
longa off ;Set 8 bit A.
|
|
sep #$20
|
|
|
|
copy_loop dey ;Done all?
|
|
bmi restore_a ;Yep.
|
|
lda [data_buffer],y ;Nope, get byte.
|
|
sta [map_ptr],y ;Put it in buffer.
|
|
bra copy_loop ;And loop.
|
|
|
|
longa on ;Restore 16 bit A.
|
|
restore_a rep #$20
|
|
*
|
|
* Now let's deallocate the old map and exit with carry clear...
|
|
*
|
|
ldx old_vp ;Get old vp.
|
|
ldy old_vp+2
|
|
jsl release_seg ;Release it.
|
|
|
|
jsr post_volume_changed ;added 25-Aug-92 DAL
|
|
|
|
clc ;No error.
|
|
exit rts ;Exit.
|
|
|
|
ENDP
|
|
eject
|
|
*******************************************************************************
|
|
*
|
|
* END OF CODE
|
|
*
|
|
*******************************************************************************
|
|
|
|
end_segment proc
|
|
end_code ;
|
|
ENDP
|
|
eject
|
|
END
|
|
|
|
|