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
69 KiB
Plaintext
1 line
69 KiB
Plaintext
string asis
|
|
|
|
;-----------------------------------------------
|
|
;
|
|
; Forward addresses and entries
|
|
;
|
|
;-----------------------------------------------
|
|
|
|
ENTRY add2bktlist
|
|
ENTRY add_to_free
|
|
ENTRY addme2lru
|
|
ENTRY bucket_vp
|
|
ENTRY c_bytes_free
|
|
ENTRY c_marker
|
|
ENTRY c_request_size
|
|
ENTRY c_temp_1
|
|
ENTRY c_temp_2
|
|
ENTRY c_temp_bwd
|
|
ENTRY c_temp_element
|
|
ENTRY c_temp_fwd
|
|
ENTRY c_temp_nvp
|
|
ENTRY cache_error
|
|
ENTRY cache_search
|
|
ENTRY cashseg_end
|
|
ENTRY current_vp
|
|
ENTRY d_from_tail
|
|
ENTRY enuf_room
|
|
ENTRY getlinks
|
|
ENTRY head_vp
|
|
ENTRY is_there_room
|
|
ENTRY look_in_array
|
|
ENTRY message_shown
|
|
ENTRY next_vp
|
|
ENTRY no_find
|
|
ENTRY prev_vp
|
|
ENTRY search_vol_id
|
|
ENTRY set_cache_ptr
|
|
ENTRY set_flink_2nil
|
|
ENTRY show_message
|
|
ENTRY start_of_data
|
|
ENTRY tail_vp
|
|
ENTRY unlink
|
|
ENTRY unlink_bwd
|
|
ENTRY update_free
|
|
ENTRY write_to_disk
|
|
|
|
include 'common.equ.src'
|
|
|
|
;===============================================================================
|
|
; cashseg.s
|
|
;
|
|
; Framework for building load segment cashseg.s
|
|
;
|
|
;===============================================================================
|
|
|
|
longa on
|
|
longi on
|
|
|
|
header_length equ $30
|
|
cashseg_org equ $00a280
|
|
cashseg_start equ cashseg_org
|
|
|
|
|
|
cashseg_header proc org cashseg_org-header_length
|
|
|
|
msb on
|
|
|
|
dc.w cashseg_end-cashseg_start
|
|
dc.l cashseg_org
|
|
dc.w $0000
|
|
dc.b 'Caching Manager v03.00 '
|
|
dc.b 00
|
|
|
|
msb off
|
|
endp
|
|
|
|
|
|
|
|
cashseg_dummy proc org cashseg_org
|
|
endp
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
; internal notes for gs/os caching routines. these notes should never be
|
|
; separated from the source code, they're listed here in no particular order.
|
|
;
|
|
; -- entry to each routine is via the system service table, the recognized
|
|
; entry points are: cash_init, cash_add, cash_find, cash_delete, cash_del_vol,
|
|
; cash_flsh_def and cash_shutdown. all other routines are used by the
|
|
; caching routines and are not known to anyone else.
|
|
;
|
|
; -- at the start of each entry point are comments describing briefly what
|
|
; the routine does, what the inputs are and what the outputs are. entry and
|
|
; exit to each routine is always with full native mode and direct page equal
|
|
; to gs/os direct page.
|
|
;
|
|
; -- cash_init and cash_shutdown are only used by gs/os, applications are
|
|
; not allowed to make these calls.
|
|
;
|
|
; -- the cache size, (always in bytes) is determined by reading battery ram.
|
|
; each tick is equal to 32K, if minus then the cache manager will assume 32K.
|
|
; if 0 then the cache manager will assume 8K. 8K is about enough to boot the
|
|
; system and not much else.
|
|
;
|
|
; -- the cache manager does not allocate to itself an amount of memory equal
|
|
; to the cache size as specified by the user. instead, the cache manager
|
|
; keeps a running byte count of the remaining amount of memory that can be
|
|
; used for the cache. as the cache grows and shrinks, the cache manager updates
|
|
; the remaining bytes left in the cache.
|
|
;
|
|
; -- the cache manager makes no assumptions about the size of the block that
|
|
; wants to be cached. it doesn't even have to be a power of 2. i'm not sure
|
|
; what the behavior of the mike memory manager is when the request for memory
|
|
; is greater than his nominal memory size unit.
|
|
;
|
|
; -- the cache manager obtains memory from the mike memory manager. (the
|
|
; mike memory manager is a custom memory manager for gs/os.) communications
|
|
; to the mike memory manager is by virtual pointers. vps are sort of like
|
|
; handles, pointers are derived from vps by de-referencing them.
|
|
;
|
|
; -- depending on the state of the system, there can be cases where the cache
|
|
; manager cannot get memory even though it's own running byte count says
|
|
; there's room. this usually happens when the system has no more free memory.
|
|
;
|
|
; -- in front of each cached block is a cache header. in it are the vital
|
|
; pieces of information that is needed to maintain the cache links.
|
|
;
|
|
; -- there are 2 classes of cached blocks, those that can be automatically
|
|
; deleted from the cache list by LRU and those that can't. the privileged
|
|
; cached blocks are also known as deferred blocks.
|
|
;
|
|
; -- the cache list is doubly linked with a head virtual pointer and a tail
|
|
; virtual pointer. the head_vp always points to the most recently added or
|
|
; requested block. the tail_vp always points to the block that is least
|
|
; recently used and that can be deleted because of LRU. things get a little
|
|
; complicated if the tail_vp points to a deferred block.
|
|
;
|
|
; -- incoming blocks are 'hashed' by 'and'ing away the block number and only
|
|
; keeping the low 7 bits. this will yield a max value of 127. without looking
|
|
; at disk structure, and assuming a fair amount of randomness in block number,
|
|
; 'hashing' to one of 128 different values will generally yield a somewhat
|
|
; even distribution. these values are known here as buckets and the cache
|
|
; list is also linked by bucket virtual pointers. there are 128 different
|
|
; bucket vps, there are no tail bucket vps. also maintaining a linked list by
|
|
; bucket vps gives the cache manager a very fast scheme of finding or deleting
|
|
; a block. (faster schemes were avoided because of the complexity implementing
|
|
; and maintaining it.)
|
|
;
|
|
; -- when cash_flsh_def (flush deferred blocks) is called, the deferred blocks
|
|
; are written to disk in the order they are found in the cache. no, it doesn't
|
|
; meet interleave and it maybe could if the deferred blocks were ordered
|
|
; sequentially but it isn't that important here. the cost in code, time and
|
|
; maintaining it isn't worth one pass through the disk. this call isn't used
|
|
; that much and when it is used, no big deal if the heads move back and forth
|
|
; a few times.
|
|
;
|
|
; -- the cache header contains a 2 byte reserved field that is currently used
|
|
; to number the incoming block. it can be used for other things if you want.
|
|
;
|
|
; -- there is some amount of memory that is used by the cache manager so the
|
|
; user won't get 32K worth of cached blocks if he specified a 32K cache. he'll
|
|
; get about 29K depending on block size. this is rather obscure but worth
|
|
; mentioning and rather difficult to notice by the user.
|
|
;
|
|
; -- Jan 25, 1988 R.T.
|
|
;
|
|
; Changed CASH_DEV_VOL. The routine did not delete deferred blocks. The
|
|
; routine now will delete both reqular blocks as well as deferred blocks.
|
|
; files changed: 'caching/scache1'
|
|
;
|
|
; -- Jan 26, 1988 R.T.
|
|
;
|
|
; Changed CASH_DEV_VOL. The routine will now tell the user that the volume
|
|
; may be damaged if a deferred block is deleted.
|
|
; files changed: 'caching/scache1' -> added a routine called 'show_message'
|
|
; 'caching/scache2' -> added 'message_shown' to data area
|
|
;
|
|
; -- Mar 22, 1988 R.T.
|
|
;
|
|
; Changed CASH_DEL_VOL. The routine will now delete ALL non-deferred
|
|
; blocks if both the device number and fst number are set to zero.
|
|
; The routine will now check the deferred bit when removing blocks by
|
|
; fst number.
|
|
; files changed: 'caching/scache1'
|
|
;
|
|
; -- Jan 30, 1989 R.T.
|
|
;
|
|
; added auto_flush_handler:
|
|
; This routine will check to see if sessions are enabled. If
|
|
; they are then I will issue a stop session call and then
|
|
; re-enable them.
|
|
;
|
|
; -- Feb 28, 1989 B.P.A
|
|
;
|
|
; Changed cashseg_org from $a200 to $a280 to give SCM some more room to
|
|
; grow. Added cache_overflow proc at end of code to check for code
|
|
; overflowing its space (will generate an error at link time).
|
|
;
|
|
; -- Mar 08, 1989 G.R.T
|
|
;
|
|
; The Cache Manager now adds itself to the OutOfMemory Queue. If I am
|
|
; called, I will do a reset_cache to the OS then return with the
|
|
; new bytes free count.
|
|
;
|
|
; -- Jun 05, 1989 G.R.T and B.P.A. and M.S.A
|
|
;
|
|
; Fixed a bug in Cash_Del_Vol. The routine was not doing a deref call
|
|
; for the bucket table. This caused a problem if compact memory was
|
|
; called Vault.
|
|
;
|
|
; -- 9/14/89 Mensch and B.P.A.
|
|
;
|
|
; Added a deref_bucket to the start of shutdown_cache in case the only cache
|
|
; block is that. This is to fix a reset_cache system death bug.
|
|
;
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;------------------------------------------------------------------------------
|
|
;Revisions
|
|
EXPORT cash_notes
|
|
cash_notes PROC
|
|
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Deref_bucket:
|
|
; This routine will deref the bucket table VP and setup
|
|
; cache_bkt_ptr
|
|
;
|
|
;
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; Copyright (c) 1987,1988,1989 Apple Computer Inc. All rights reserved.
|
|
; author: Rob Turner
|
|
;-----------------------------------------------------------------------------
|
|
|
|
Deref_bucket proc
|
|
php
|
|
phx
|
|
phy
|
|
|
|
ldx bucket_vp
|
|
ldy bucket_vp+2
|
|
jsl deref ;deref this for real pointing
|
|
stx <cache_bkt_ptr
|
|
sty <cache_bkt_ptr+2
|
|
|
|
ply
|
|
plx
|
|
plp
|
|
|
|
rts
|
|
endp
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; curr_vp_to_ptr:
|
|
; This routine will set current_vp then deref current VP
|
|
; and store the result in cache_cur_ptr
|
|
;
|
|
;
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = vp low X = trashed
|
|
; Y = vp high Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; Copyright (c) 1987,1988,1989 Apple Computer Inc. All rights reserved.
|
|
; author: Rob Turner
|
|
;-----------------------------------------------------------------------------
|
|
|
|
curr_vp_to_ptr proc
|
|
stx current_vp
|
|
sty current_vp+2
|
|
export XY_to_cur_ptr
|
|
XY_to_cur_ptr
|
|
jsl deref
|
|
stx <cache_cur_ptr
|
|
sty <cache_cur_ptr+2
|
|
rts
|
|
endp
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; auto_flush_handler:
|
|
; This routine will check to see if sessions are enabled. If
|
|
; they are then I will issue a stop session call and then
|
|
; re-enable them.
|
|
;
|
|
;
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; Copyright (c) 1987,1988,1989 Apple Computer Inc. All rights reserved.
|
|
; author: Rob Turner
|
|
;-----------------------------------------------------------------------------
|
|
|
|
auto_flush_handler proc
|
|
import in_queue
|
|
|
|
phk
|
|
plb
|
|
|
|
jsl $e100a8
|
|
dc.w $201f ;get the current sessions flag
|
|
dc.l get_session
|
|
|
|
lda session_state
|
|
and #$0001 ;clear all other bits
|
|
beq @no_sessions
|
|
|
|
jsl $e100a8 ;now do a stop session call please
|
|
dc.w $201E
|
|
dc.l session_list
|
|
|
|
jsl $e100a8
|
|
dc.w $201d ;turn the session back on please
|
|
dc.l session_list
|
|
|
|
@no_sessions
|
|
stz in_queue ;indicate that we have ran
|
|
rtl
|
|
|
|
get_session dc.w $01 ;PCount
|
|
session_state dc.w 00
|
|
|
|
session_list dc.w $0000
|
|
|
|
endp
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; CASH_INIT -- initializes the cache
|
|
;
|
|
; This routine will try to initialize the cache. Memory as needed by the
|
|
; cache is obtained from the Mike Memory Manager. The size of the cache is
|
|
; determined by looking at battery ram. Once this is read, changing the
|
|
; value in battery ram will not change the size of the cache. The cache size
|
|
; cannot be changed on the fly unless you're SSSPECIAL !!!
|
|
;
|
|
; Input and output is passed to this routine by GS/OS direct page and full
|
|
; native mode is always assumed.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the block is cached
|
|
; c = 1 means something screwed up, the block's not cached
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cash_init
|
|
cash_init PROC
|
|
import c_data_len
|
|
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
|
|
ldx #c_data_len ;number of bytes to zero
|
|
cash_i00 stz start_of_data,x
|
|
dex
|
|
dex
|
|
bpl cash_i00
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; we need a segment of memory for holding the bucket vps. since there will be
|
|
; 128 buckets and each bucket will contain a bucket vp, the memory request
|
|
; will be 512 bytes.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
lda #$0200 ;size of request, in bytes
|
|
sta c_request_size ;save this for later
|
|
sec ;we want it zeroed
|
|
jsl alloc_seg ;try to get it from mr. mike
|
|
bcc cash_i01 ;skip if no problem
|
|
jmp cache_error ;damn, couldn't get memory
|
|
|
|
cash_i01 stx bucket_vp
|
|
sty bucket_vp+2 ;save vp to bucket array
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; read battery ram to find the user selected cache size. each tick equals
|
|
; 32K. (max size = 4M - 32K) normal battery ram is $ff, if the value read
|
|
; is $ff then we'll pretend it's a 1. if the value read is 0, then the
|
|
; ram cache size will be about 16K, enough to boot, not much more.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
pea $0000 ;push space for result
|
|
pea ram_cache_size ;location of cache size
|
|
ldx #$0c03 ;read battery parameter
|
|
jsl $e10000 ;ain't no error possible
|
|
pla ;get cache size, low only
|
|
and #$00ff ;make sure to only keep low byte
|
|
beq cash_i02 ;skip if 0, user wants no cache
|
|
cmp #$00ff
|
|
beq cash_i03 ;skip if $ff, pretend it's 1
|
|
clc
|
|
ror a
|
|
bcc cash_i01a ;skip if c = 0, even number of 32Ks
|
|
ldx #$0080 ;32K
|
|
stx c_bytes_free+1 ;take care of odd
|
|
|
|
cash_i01a sta c_bytes_free+2 ;take care of even
|
|
bra cash_i05
|
|
|
|
cash_i02 lda #default_cache_size
|
|
bra cash_i04
|
|
|
|
cash_i03 lda #$0080 ;32K
|
|
cash_i04 sta c_bytes_free+1 ;size of total cache in bytes
|
|
|
|
; subtract bucket array size from total bytes free
|
|
|
|
cash_i05 jmp update_free
|
|
|
|
ENDP
|
|
;-----------------------------------------------------------------------------
|
|
; CASH_ADD -- adds a block to the cache
|
|
;
|
|
; This routine will try to add the requested block into the cache. It's
|
|
; position within the LRU and bucket chain will be at the start of the list.
|
|
; In the event there is not enough room in the cache, the last recently used
|
|
; block(s) will be purged until there is enough room for the requested block.
|
|
;
|
|
; Input and output is passed to this routine by GS/OS direct page and full
|
|
; native mode is always assumed.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the block is cached
|
|
; c = 1 means something screwed up, the block's not cached
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cash_add
|
|
cash_add PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
jsr deref_bucket ;Deref the bucket table and setup cache_bkt_ptr
|
|
|
|
; always assume it ain't there, but see if there's enough room first
|
|
|
|
cash_a00 clc
|
|
lda <drvr_blk_size ;get requested block size
|
|
adc #c_headerlen ;add to size of cache header
|
|
sta c_request_size ;save this for later
|
|
jsr enuf_room ;check for space free
|
|
bcc cash_a01 ;skip if there's room for it
|
|
bra cash_a02 ;something's wrong
|
|
|
|
cash_a01 lda c_request_size ;get the size we want
|
|
; clc ;we don't want it zeroed
|
|
jsl alloc_seg ;ask for this amount from mike
|
|
bcc cash_a03 ;skip if we got it
|
|
cash_a02 jmp cache_error ;damn! couldn't get the memory
|
|
|
|
; add this cache cell to the start of the LRU chain
|
|
|
|
cash_a03 jsr addme2lru
|
|
|
|
; add this cache cell to the start of the bucket chain
|
|
|
|
jsr add2bktlist
|
|
bcs cash_a02 ;error from mike
|
|
|
|
; now fill in the rest of the cache header information
|
|
|
|
ldy #c_blknum ;point to block number, lo
|
|
lda <drvr_blk_num
|
|
sta [<cache_cur_ptr],y
|
|
iny
|
|
iny ;point to block number, hi
|
|
lda <drvr_blk_num+2
|
|
sta [<cache_cur_ptr],y
|
|
|
|
iny
|
|
iny ;point to block size
|
|
lda <drvr_blk_size
|
|
sta [<cache_cur_ptr],y
|
|
|
|
iny
|
|
iny ;point to FST number
|
|
lda <drvr_fst_num
|
|
sta [<cache_cur_ptr],y
|
|
|
|
iny
|
|
iny ;point to volume id
|
|
lda <drvr_vol_id
|
|
sta [<cache_cur_ptr],y
|
|
|
|
iny
|
|
iny ;point to device number
|
|
lda <drvr_dev_num
|
|
sta [<cache_cur_ptr],y
|
|
|
|
iny
|
|
iny ;point to cache priority
|
|
lda <drvr_cache
|
|
sta [<cache_cur_ptr],y
|
|
|
|
iny
|
|
iny ;point to cell size
|
|
lda c_request_size
|
|
sta [<cache_cur_ptr],y
|
|
|
|
; the following is only for debugging purposes . . .
|
|
|
|
iny
|
|
iny ;point to reserved field
|
|
inc c_marker
|
|
lda c_marker
|
|
sta [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
sta [<cache_cur_ptr],y
|
|
|
|
jsr set_cache_ptr ;set drvr_cach_ptr before returning
|
|
|
|
; update bytes free and we're done.
|
|
|
|
EXPORT update_free
|
|
update_free ;
|
|
sec
|
|
lda c_bytes_free
|
|
sbc c_request_size
|
|
sta c_bytes_free
|
|
|
|
lda c_bytes_free+2
|
|
sbc #$0000
|
|
sta c_bytes_free+2 ;4 byte subtract
|
|
|
|
plb
|
|
clc
|
|
rtl
|
|
|
|
ENDP
|
|
;-----------------------------------------------------------------------------
|
|
; CASH_FIND -- finds a block in the cache
|
|
;
|
|
; This routine will try to find the requested block in the cache. If it's
|
|
; found, it'll be moved to the start of the LRU chain and a 4 byte pointer will
|
|
; be returned pointing to the start of the requested block. The bucket links
|
|
; will not be moved.
|
|
;
|
|
; Input and output is passed to this routine by GS/OS direct page and full
|
|
; native mode is always assumed.
|
|
;
|
|
; on input: c = 0 means look for the block
|
|
; c = 1 means look for vol_id and deferred bit
|
|
;
|
|
; inputs: A = vol_id if c=1 outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the block is in the cache or vol_id found
|
|
; c = 1 means something screwed up or the block's not in the cache
|
|
; or vol_id not found
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cash_find
|
|
cash_find PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
|
|
bcc cash_fff ;skip if we're looking for a block
|
|
jsr search_vol_id ;we're looking for vol_id
|
|
plb ;pull to balance the stack
|
|
rtl ;result in c
|
|
|
|
; if we came from cash_flsh_def then we want to skip this
|
|
|
|
cash_fff ldx no_find ;non 0 means we want to skip this
|
|
bne cash_fff0
|
|
jsr cache_search ;locate the requested block
|
|
bcc cash_fm00 ;skip if we found it
|
|
cash_fff0 jmp cache_error ;error, no can find
|
|
|
|
; if we're in deferred mode and the block ain't, then correct for this
|
|
|
|
cash_fm00 ldy #c_priority ;offset to priority field
|
|
lda [<cache_cur_ptr],y
|
|
tax ;save for later
|
|
bmi cash_f00 ;skip if deferred bit set
|
|
lda <drvr_cache ;are we deferred mode now ?
|
|
bpl cash_f00 ;skip if no
|
|
txa ;bring a back
|
|
ora #$8000 ;make this block deferred
|
|
sta [<cache_cur_ptr],y ;this guy's deferred
|
|
|
|
lda <drvr_vol_id
|
|
ldy #c_volumeid
|
|
sta [<cache_cur_ptr],y
|
|
|
|
; pull out both LRU links into next_vp and prev_vp
|
|
|
|
cash_f00 ldx #c_lru_bwd
|
|
ldy #c_lru_fwd
|
|
jsr getlinks ;prev_vp in x and y
|
|
|
|
tya
|
|
bne cash_f01 ;skip if hi backlink <> 0
|
|
txa
|
|
bne cash_f01 ;skip if lo backlink <> 0
|
|
|
|
; backlink = 0, cache cell is at the start of list, ain't much left to do
|
|
|
|
bra cash_f04
|
|
|
|
; backlink <> 0, check forward link to see if cache cell is at the end
|
|
|
|
cash_f01 lda next_vp
|
|
bne cash_f02 ;skip if hi forward link <> 0
|
|
lda next_vp+2
|
|
bne cash_f02 ;skip if hi forward link <> 0
|
|
|
|
; forward link = 0, cache cell is at end of list, update tail_vp
|
|
; prev_vp is still in x and y
|
|
|
|
stx tail_vp
|
|
sty tail_vp+2
|
|
lda #c_lru_fwd
|
|
jsr set_flink_2nil ;set forward link to nil
|
|
bra cash_f03
|
|
|
|
; backlink and forward link are both <> 0, the cache cell is somewhere in
|
|
; the middle of the list. the head_vp and tail_vp aren't used here. unlink
|
|
; the LRU links of the current cell by joining the previous and next cells
|
|
; together.
|
|
|
|
cash_f02 ldx #c_lru_bwd
|
|
ldy #c_lru_fwd
|
|
jsr unlink
|
|
|
|
; the current cache cell has been LRU unlinked. reattach the LRU links at
|
|
; the start of the LRU chain.
|
|
|
|
cash_f03 ldx current_vp
|
|
ldy current_vp+2
|
|
jsr addme2lru
|
|
|
|
; last thing to do is return the pointer to the cached block
|
|
|
|
cash_f04 jsr set_cache_ptr ;set drvr_cach_ptr before returning
|
|
|
|
cash_f05 plb ;restore caller's data bank
|
|
clc ;indicate no error
|
|
rtl
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; CASH_DELETE -- deletes (purges) a block from the cache
|
|
;
|
|
; This routine will try to delete the requested block from the cache. If
|
|
; entry to this routine is via cache_xdelete then we don't have to look for
|
|
; the block before deleting it, the block is pointed to by current_vp.
|
|
;
|
|
; Input and output is passed to this routine by GS/OS direct page and full
|
|
; native mode is always assumed.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the block has been deleted from the cache
|
|
; c = 1 means something screwed up or the block's not in the cache
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cash_delete
|
|
cash_delete PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
bra cash_dxxx ;skip over other entry point
|
|
|
|
EXPORT cache_xdelete
|
|
cache_xdelete ;
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
bra cash_d00 ;jump into it
|
|
|
|
cash_dxxx jsr cache_search ;locate the requested block
|
|
bcc cash_d00 ;skip if we found it
|
|
jmp cache_error ;error, no can find
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; remove this cache cell from the LRU chain
|
|
;-----------------------------------------------------------------------------
|
|
|
|
; pull out both LRU links into next_vp and prev_vp, we'll need them later
|
|
|
|
cash_d00 ldx #c_lru_bwd
|
|
ldy #c_lru_fwd
|
|
jsr getlinks ;prev_vp in x and y
|
|
|
|
; if we happen to come in from xdelete, then we need to keep around the value
|
|
; of next_vp. removing by bucket will destroy this.
|
|
|
|
lda next_vp
|
|
sta c_temp_nvp
|
|
lda next_vp+2
|
|
sta c_temp_nvp+2
|
|
|
|
tya
|
|
bne cash_d02 ;skip if hi backlink <> 0
|
|
txa
|
|
bne cash_d02 ;skip if lo backlink <> 0
|
|
|
|
; backlink = 0, cache cell is at the start of list. if forward link = 0 then
|
|
; we have a single cell cache. x is still 0.
|
|
|
|
cpx next_vp
|
|
bne cash_d01 ;skip if lo forward link <> 0
|
|
cpx next_vp+2
|
|
bne cash_d01 ;skip if hi forward link <> 0
|
|
|
|
; forward link is also = 0, we have a single cell cache.
|
|
|
|
stz head_vp ;x is 0 from above
|
|
stz head_vp+2
|
|
stz tail_vp
|
|
stz tail_vp+2
|
|
jmp cash_dd00a
|
|
|
|
; forward link is not = 0, but the backlink is still = 0
|
|
|
|
cash_d01 ldx next_vp
|
|
stx head_vp
|
|
ldx next_vp+2
|
|
stx head_vp+2 ;head_vp now points to 2nd cell
|
|
|
|
ldx #c_lru_bwd
|
|
stx c_temp_bwd
|
|
jsr unlink_bwd ;unlink backward link
|
|
bra cash_dd00
|
|
|
|
; backlink <> 0, check forward link to see if cache cell is at the end
|
|
|
|
cash_d02 lda next_vp
|
|
bne cash_d03 ;skip if lo forward link <> 0
|
|
lda next_vp+2
|
|
bne cash_d03 ;skip if hi forward link <> 0
|
|
|
|
; forward link = 0, cache cell is at end of list. prev_vp is still in x and y
|
|
|
|
stx tail_vp
|
|
sty tail_vp+2 ;tail_vp now points to 2nd from last
|
|
|
|
lda #c_lru_fwd
|
|
jsr set_flink_2nil ;set forward link to nil
|
|
bra cash_dd00
|
|
|
|
; backlink and forward link are both <> 0, the cache cell is somewhere in
|
|
; the middle of the list. the head_vp and tail_vp aren't used here. unlink
|
|
; the LRU links of the current cell by joining the previous and next cells
|
|
; together.
|
|
|
|
cash_d03 ldx #c_lru_bwd
|
|
ldy #c_lru_fwd
|
|
jsr unlink
|
|
|
|
; the current cache cell has been LRU unlinked.
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; remove this cache cell from the bucket chain
|
|
;-----------------------------------------------------------------------------
|
|
|
|
; pull out both bucket links into next_vp and prev_vp, we'll need them later
|
|
|
|
cash_dd00 ldx #c_bkt_bwd
|
|
ldy #c_bkt_fwd
|
|
jsr getlinks ;prev_vp in x and y
|
|
|
|
tya
|
|
bne cash_dd01 ;skip if hi backlink <> 0
|
|
txa
|
|
bne cash_dd01 ;skip if lo backlink <> 0
|
|
|
|
; backlink = 0, cache cell is at the start of list. if forward link = 0 then
|
|
; we have a single cell cache. x is still 0.
|
|
|
|
cpx next_vp
|
|
bne cash_dd00b ;skip if lo forward link <> 0
|
|
cpx next_vp+2
|
|
bne cash_dd00b ;skip if hi forward link <> 0
|
|
|
|
; forward link is also = 0, we have a single cell bucket list
|
|
|
|
cash_dd00a ldy #c_blknum
|
|
lda [<cache_cur_ptr],y ;get block number, lo
|
|
and #$007f ;keep low 7 bits
|
|
asl a
|
|
asl a ;multiply by 4 to make into index
|
|
tay
|
|
txa ;set acc to 0
|
|
sta [<cache_bkt_ptr],y
|
|
iny
|
|
iny
|
|
sta [<cache_bkt_ptr],y
|
|
bra cash_dd03 ;we done
|
|
|
|
; forward link is not = 0, but backlink is still = 0
|
|
|
|
cash_dd00b ldy #c_blknum
|
|
lda [<cache_cur_ptr],y ;get block number, lo
|
|
and #$007f ;keep low 7 bits
|
|
asl a
|
|
asl a ;multiply by 4 to make into index
|
|
tay
|
|
lda next_vp
|
|
sta [<cache_bkt_ptr],y
|
|
iny
|
|
iny
|
|
lda next_vp+2
|
|
sta [<cache_bkt_ptr],y
|
|
|
|
ldx #c_bkt_bwd
|
|
stx c_temp_bwd
|
|
jsr unlink_bwd ;unlink backward link
|
|
bra cash_dd03
|
|
|
|
; backlink <> 0, check forward link to see if cache cell is at the end
|
|
|
|
cash_dd01 lda next_vp
|
|
bne cash_dd02 ;skip if hi forward link <> 0
|
|
lda next_vp+2
|
|
bne cash_dd02 ;skip if hi forward link <> 0
|
|
|
|
; forward link = 0, cache cell is at end of list. prev_vp is still in x and y
|
|
|
|
lda #c_bkt_fwd
|
|
jsr set_flink_2nil ;set forward link to nil
|
|
bra cash_dd03
|
|
|
|
; backlink and forward link are both <> 0, the cache cell is somewhere in
|
|
; the middle of the list. unlink the bucket links of the current cell by
|
|
; joining the previous and next cells together.
|
|
|
|
cash_dd02 ldx #c_bkt_bwd
|
|
ldy #c_bkt_fwd
|
|
jsr unlink
|
|
|
|
; the current cache cell has been bucket unlinked. now give it back to mike.
|
|
; also, update the free byte count
|
|
|
|
cash_dd03 jsr add_to_free ;add this amount to free byte count
|
|
|
|
ldx current_vp
|
|
ldy current_vp+2
|
|
jsl release_seg ;try to give it back to mike
|
|
bcc cash_dd04 ;skip if no problem
|
|
jmp cache_error ;damn, couldn't give it back
|
|
|
|
cash_dd04 plb ;restore caller's data bank
|
|
clc ;indicate no error
|
|
rtl
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; CASH_DEL_VOL -- deletes (purges) a volume's block(s) from the cache
|
|
;
|
|
; This routine will try to delete all blocks belonging to the requested
|
|
; device number from the cache. If the device number = 0 then all blocks
|
|
; of all device numbers of the specified FST will be deleted. If both
|
|
; device number and fst number are zero all blocks that are not deferred
|
|
; will be deleted.
|
|
;
|
|
; Input and output is passed to this routine by GS/OS direct page and full
|
|
; native mode is always assumed.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the volume's block(s) are deleted
|
|
; c = 1 means something screwed up, the blocks may still be cached
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cash_del_vol
|
|
cash_del_vol PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
|
|
jsr deref_bucket ;Deref the bucket table and setup cache_bkt_ptr
|
|
|
|
stz message_shown ;reset flag. Flag used to tell user
|
|
;that a deferred block has been flushed
|
|
|
|
ldy <drvr_dev_num
|
|
sty c_temp_2 ;assume we're deleting by device number
|
|
|
|
ldy <drvr_fst_num
|
|
ldx #c_devnum
|
|
lda <drvr_dev_num
|
|
bne cash_dv00 ;skip if we're deleting by device #
|
|
sty c_temp_2 ; we're deleting by FST
|
|
ldx #c_fstnum
|
|
cash_dv00 stx c_temp_1
|
|
|
|
ldy head_vp+2
|
|
sty next_vp+2
|
|
ldx head_vp
|
|
stx next_vp ;start this mess from the head
|
|
bra cash_dv03 ;check for 0 first
|
|
|
|
cash_dv01 stx current_vp
|
|
ldy next_vp+2
|
|
sty current_vp+2
|
|
|
|
jsr curr_vp_to_ptr ;convert the current VP to a real pointer
|
|
|
|
lda c_temp_2 ;delete all non-deferred blocks?
|
|
beq do_all_please
|
|
|
|
ldy c_temp_1
|
|
lda [<cache_cur_ptr],y
|
|
cmp c_temp_2 ;equal ?
|
|
bne cash_dv04 ;nope
|
|
|
|
; only pick out the non-deferred blocks
|
|
|
|
; ldx c_temp_1
|
|
; cpx #c_fstnum ;are we deleting by fst number ?
|
|
; beq cash_dv01a ;yes, don't worry about deferred stuff
|
|
|
|
;===========================================================================
|
|
;
|
|
; We no longer skip deferred blocks. They get kicked out along with
|
|
; other blocks on the device. By Rob Turner 1/25/88
|
|
;
|
|
;===========================================================================
|
|
do_all_please ;
|
|
ldy #c_priority
|
|
lda [<cache_cur_ptr],y
|
|
bpl cash_dv01a ;Block is not deferred
|
|
|
|
lda c_temp_2 ;removing all non-deferred blocks?
|
|
beq cash_dv04 ;yes, so skip this block
|
|
|
|
bit message_shown ;have we told the user about damage?
|
|
bmi cash_dv01a ;Yes!
|
|
|
|
jsr show_message ;tell the user
|
|
dec message_shown
|
|
|
|
;
|
|
; we've located a block for deletion
|
|
;
|
|
cash_dv01a jsl cache_xdelete ;delete this guy
|
|
bcc cash_dv02 ;skip if no error
|
|
jmp cache_error ;i don't know why
|
|
|
|
cash_dv02 lda c_temp_nvp ;restore next_vp
|
|
sta next_vp
|
|
lda c_temp_nvp+2
|
|
sta next_vp+2
|
|
|
|
cash_dv03 ldx next_vp
|
|
bne cash_dv01 ;skip if <> 0
|
|
ldy next_vp+2
|
|
bne cash_dv01 ;skip if <> 0
|
|
bra cash_dv05 ;it's 0, we done deleting
|
|
|
|
; it's not this cell, follow forward link and try again.
|
|
|
|
cash_dv04 ldy #c_lru_fwd
|
|
lda [<cache_cur_ptr],y
|
|
tax ;low link in x
|
|
iny
|
|
iny
|
|
lda [<cache_cur_ptr],y
|
|
sta next_vp+2
|
|
tay ;hi link in y
|
|
bne cash_dv01 ;y <> 0, loop
|
|
txa
|
|
bne cash_dv01 ;x <> 0, loop
|
|
|
|
; the forward link is 0, we're all done here.
|
|
|
|
cash_dv05 plb ;restore caller's data bank
|
|
clc ;indicate no error
|
|
rtl
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------
|
|
;Show_Message: This routine will tell the user that the volume is
|
|
; possible damaged.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT show_message
|
|
show_message PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
lda <cache_cur_ptr+2
|
|
pha ;save the zeropage pointer
|
|
lda <cache_cur_ptr
|
|
pha
|
|
|
|
ldy #c_volumeid ;get the volume id please
|
|
lda [<cache_cur_ptr],y
|
|
beq end_show ;major problem
|
|
|
|
jsl find_vcr ;go and get the vcr ptr
|
|
bcs end_show ;major problem
|
|
|
|
jsr XY_to_cur_ptr ;deref X and Y & setup cache_cur_ptr with real address.
|
|
|
|
ldy #vcr_name ;index to volume name
|
|
lda [<cache_cur_ptr],y
|
|
tax
|
|
iny
|
|
iny
|
|
lda [<cache_cur_ptr],y
|
|
tay
|
|
jsr XY_to_cur_ptr ;deref X and Y & setup cache_cur_ptr with real address.
|
|
|
|
lda [<cache_cur_ptr]
|
|
xba ;convert length word to length byte
|
|
sta [<cache_cur_ptr]
|
|
|
|
pea $0010 ;error message number
|
|
ldx <cache_cur_ptr+2
|
|
lda <cache_cur_ptr ;low word of address
|
|
inc a ;point to length byte
|
|
bne high_ok
|
|
inx ;advance the bank address
|
|
high_ok ;
|
|
phx ;high word
|
|
pha ;low word
|
|
|
|
pha ;garbage
|
|
pha
|
|
jsl report_error
|
|
|
|
lda [<cache_cur_ptr]
|
|
xba ;convert length byte to length word
|
|
sta [<cache_cur_ptr]
|
|
|
|
end_show ;
|
|
pla
|
|
sta <cache_cur_ptr
|
|
pla
|
|
sta <cache_cur_ptr+2
|
|
rts
|
|
ENDP
|
|
;-----------------------------------------------------------------------------
|
|
; CASH_FLSH_DEF -- write to disk the deferred cache block(s)
|
|
;
|
|
; This routine will try to write to disk the deferred cache blocks belonging
|
|
; to a specific volume id. After being written to disk, these deferred cache
|
|
; blocks will be downgraded to regular cache blocks.
|
|
;
|
|
; Input and output is passed to this routine by GS/OS direct page and full
|
|
; native mode is always assumed.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the volume ids deferred blocks have been
|
|
; written to disk
|
|
; c = 1 means something screwed up, couldn't write to disk all
|
|
; deferred blocks of the given volume id
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cash_flsh_def
|
|
cash_flsh_def PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
|
|
jsr deref_bucket ;Deref the bucket table and setup cache_bkt_ptr
|
|
|
|
ldx <drvr_cache ;get this
|
|
phx ;save this for later
|
|
stz <drvr_cache
|
|
|
|
;-----------------------------------------------------------------------------
|
|
;
|
|
;-----------------------------------------------------------------------------
|
|
|
|
ldx head_vp ;start this mess from the head
|
|
ldy head_vp+2
|
|
|
|
cfd_00
|
|
jsr curr_vp_to_ptr ;convert the current VP to a real pointer
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; we can only write out cell(s) that are deferred. we may have to walk the
|
|
; entire list to find it but we know it's there.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
ldy #c_priority
|
|
lda [<cache_cur_ptr],y ;get this cell's priority
|
|
bmi cfd_02 ;skip if deferred
|
|
|
|
cfd_00a ldy #c_lru_fwd
|
|
lda [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
tax ;save backward vp link, lo
|
|
bne cfd_01 ;skip if not 0
|
|
|
|
lda [<cache_cur_ptr],y
|
|
beq cash_fd09 ;we found a vp of $0000
|
|
|
|
cfd_01 lda [<cache_cur_ptr],y
|
|
tay ;save backward vp link, hi
|
|
bra cfd_00 ;loop for next cell
|
|
|
|
; if we get here then we found a deferred block, check for volume id
|
|
|
|
cfd_02 ldy #c_volumeid
|
|
lda [<cache_cur_ptr],y ;get volume id
|
|
cmp <drvr_vol_id ;same ?
|
|
bne cfd_00a ;no, check next cell
|
|
|
|
; if we get here then we found a match, write this puppy out
|
|
|
|
inc no_find ;disable find routine
|
|
jsr write_to_disk ;write this block to disk
|
|
bcs cash_fd09 ;this wasn't expected
|
|
|
|
; if we get here then the writes okay and now turn off deferred status
|
|
|
|
ldy #c_priority
|
|
lda [<cache_cur_ptr],y
|
|
and #$7fff ;turn off bit 15
|
|
sta [<cache_cur_ptr],y
|
|
bra cfd_00a ;loop to find next one if any
|
|
|
|
cash_fd09 stz no_find ;re-enable find routine
|
|
plx ;restore drvr_cache
|
|
stx <drvr_cache
|
|
plb ;restore caller's data bank
|
|
clc ;indicate no error
|
|
rtl
|
|
|
|
ENDP
|
|
;-----------------------------------------------------------------------------
|
|
; CASH_SHUTDOWN -- shutdown the cache
|
|
;
|
|
; This routine will try to shutdown the cache by deleting each entry one at a
|
|
; time. The LRU list will be used for deletion, the bucket lists will not be
|
|
; used nor updated. The state of the cache is unknown if there's an error.
|
|
;
|
|
; Input and output is passed to this routine by GS/OS direct page and full
|
|
; native mode is always assumed.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the cache has been shutdown
|
|
; c = 1 means something screwed up, the cache is unreliable now
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cash_shutdown
|
|
cash_shutdown PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
phb ;save caller's data bank
|
|
phk
|
|
plb ;set data bank to ourspace
|
|
jsr deref_bucket ;Deref the bucket table and setup cache_bkt_ptr
|
|
|
|
bra cash_sd01
|
|
|
|
cash_sd00 jsr d_from_tail ;delete one from the tail
|
|
bcc cash_sd01 ;skip if no problem
|
|
jmp cache_error ;not suppose to happen
|
|
|
|
cash_sd01 ldx tail_vp
|
|
bne cash_sd00 ;head <> 0, at least 1 cell left
|
|
ldy tail_vp+2
|
|
bne cash_sd00 ;head <> 0, at least 1 cell left
|
|
|
|
; lastly, get rid of the bucket array
|
|
|
|
ldx bucket_vp
|
|
ldy bucket_vp+2
|
|
jsl release_seg
|
|
bcc cash_sd02 ;skip if no problem
|
|
jmp cache_error ;mike's got a problem
|
|
|
|
cash_sd02
|
|
Import Cache_out_of_Queue
|
|
jsr Cache_out_of_Queue
|
|
plb ;restore caller's data bank
|
|
clc ;indicate no error
|
|
rtl
|
|
|
|
ENDP
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cache_misc
|
|
cache_misc PROC
|
|
;using common_equ
|
|
;using cache_data
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; ENUF_ROOM -- checks for space remaining in cache
|
|
;
|
|
; This routine will check the cache free space to see if there's enough room
|
|
; for adding another cell into the chain. If there's not enough room then
|
|
; LRU will be invoked and cells will be deleted until there's enough room for
|
|
; the requested block.
|
|
;
|
|
; inputs: A = cell size outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, there's enough room for the request size
|
|
; c = 1 means something screwed up, it's probably mike's fault
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT enuf_room
|
|
enuf_room ;
|
|
import in_queue
|
|
|
|
jsr is_there_room ;is there room for something ?
|
|
bcs enuf_02 ;there's enough room
|
|
|
|
lda tail_vp
|
|
bne enuf_00 ;skip if not 0
|
|
lda tail_vp+2
|
|
bne enuf_00 ;skip if not 0
|
|
|
|
; there isn't enough room yet, the tail_vp is 0, something is all screwed up.
|
|
; Or sessions are enabled and the cache is full. If this is the case
|
|
; then I will do an end session and flush the word.
|
|
;
|
|
|
|
put_in_queue lda in_queue ;lets see if we have queued up to check for sessions
|
|
bmi @already_in
|
|
|
|
lda #$FFFF
|
|
sta in_queue ;do not add to the queue until I have ran once
|
|
|
|
lda #$0001 ;priority 1
|
|
ldx #auto_flush_handler
|
|
ldy #^auto_flush_handler
|
|
jsl signal ;add in our signal handler
|
|
@already_in
|
|
sec ;this should never happen
|
|
rts
|
|
|
|
; there ain't enough room to cache the requested cell. enforce LRU until
|
|
; there's enough room or error whichever is first.
|
|
|
|
enuf_00 jsr d_from_tail ;delete one from the tail
|
|
bcc enuf_room ;skip if no problem
|
|
bcs put_in_queue ;let error migrate up
|
|
|
|
enuf_02 clc
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; ADDME2LRU -- adds a block to the LRU chain
|
|
;
|
|
; This routine will take the cache cell pointed to by x and y and add it to
|
|
; the start of the LRU chain.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = vp to cache cell, lo X = trashed
|
|
; Y = vp to cache cell, hi Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = don't care
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT addme2lru
|
|
addme2lru ;
|
|
lda head_vp
|
|
sta next_vp
|
|
lda head_vp+2
|
|
sta next_vp+2
|
|
stx head_vp
|
|
sty head_vp+2 ;this is the new LRU head
|
|
jsr XY_to_cur_ptr ;deref X and Y & setup cache_cur_ptr with real address.
|
|
|
|
ldy #c_lru_fwd ;offset to forward vp link
|
|
lda next_vp
|
|
sta [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
lda next_vp+2
|
|
sta [<cache_cur_ptr],y
|
|
|
|
ldy #c_lru_bwd ;offset to backward vp link
|
|
lda #$0000
|
|
sta [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
sta [<cache_cur_ptr],y
|
|
|
|
lda next_vp
|
|
bne addme00
|
|
lda next_vp+2
|
|
bne addme00
|
|
lda head_vp
|
|
sta tail_vp
|
|
lda head_vp+2
|
|
sta tail_vp+2
|
|
rts
|
|
|
|
addme00 ldx next_vp
|
|
ldy next_vp+2
|
|
jsl deref
|
|
stx <cache_nxt_ptr
|
|
sty <cache_nxt_ptr+2
|
|
|
|
ldy #c_lru_bwd ;offset to backward vp link
|
|
lda head_vp
|
|
sta [<cache_nxt_ptr],y
|
|
iny
|
|
iny
|
|
lda head_vp+2
|
|
sta [<cache_nxt_ptr],y
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; add2bktlist -- adds a block to the bucket chain
|
|
;
|
|
; This routine will take the cache cell pointed to by head_vp and add it to
|
|
; the head of the bucket chain.
|
|
;
|
|
; inputs: A = bucket number outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the cache cell has been added to the head
|
|
; of the bucket chain
|
|
; c = 1 means something screwed up, the operation was not completed
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT add2bktlist
|
|
add2bktlist ;
|
|
jsr look_in_array ;look in bucket array for it
|
|
bcc add2d00 ;skip if there's something there
|
|
|
|
stz next_vp ;set forward link to nil
|
|
stz next_vp+2
|
|
bra add2d01
|
|
|
|
add2d00 stx next_vp
|
|
sty next_vp+2
|
|
jsl deref
|
|
stx <cache_nxt_ptr
|
|
sty <cache_nxt_ptr+2
|
|
|
|
ldy #c_bkt_bwd ;offset to backward vp link
|
|
lda head_vp
|
|
sta [<cache_nxt_ptr],y
|
|
iny
|
|
iny
|
|
lda head_vp+2
|
|
sta [<cache_nxt_ptr],y
|
|
|
|
add2d01 lda c_temp_element
|
|
asl a
|
|
asl a ;multiply by 4 to make into index
|
|
tay
|
|
lda head_vp
|
|
sta [<cache_bkt_ptr],y
|
|
iny
|
|
iny
|
|
lda head_vp+2
|
|
sta [<cache_bkt_ptr],y
|
|
|
|
ldy #c_bkt_fwd ;offset to forward vp link
|
|
lda next_vp
|
|
sta [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
lda next_vp+2
|
|
sta [<cache_cur_ptr],y
|
|
|
|
ldy #c_bkt_bwd ;offset to backward vp link
|
|
lda #$0000
|
|
sta [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
sta [<cache_cur_ptr],y
|
|
|
|
clc
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; CACHE_SEARCH -- searches the cache for the requested block
|
|
;
|
|
; This routine will search the bucket list to locate the requested block. If
|
|
; it's found, cache_cur_ptr will be pointing to that block.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the requested block has been found
|
|
; c = 1 means something screwed up or the block's not in the cache
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cache_search
|
|
cache_search ;
|
|
jsr look_in_array ;look in bucket array for it
|
|
bcc cash_s00 ;skip if maybe
|
|
rts ;error, it ain't there
|
|
|
|
; the block should be somewhere in this bucket list, look for it
|
|
|
|
cash_s00
|
|
jsr curr_vp_to_ptr ;convert the current VP to a real pointer
|
|
|
|
ldy #c_blknum ;point to block number, lo
|
|
lda [<cache_cur_ptr],y
|
|
cmp <drvr_blk_num ;equal ?
|
|
bne cash_s01 ;nope
|
|
iny
|
|
iny ;point to block number, hi
|
|
lda [<cache_cur_ptr],y
|
|
cmp <drvr_blk_num+2 ;equal ?
|
|
bne cash_s01 ;nope
|
|
|
|
ldy #c_blksize ;point to block size
|
|
lda [<cache_cur_ptr],y
|
|
cmp <drvr_blk_size ;equal ?
|
|
bne cash_s02 ;nope ----------> L O O K !!!
|
|
|
|
ldy #c_devnum ;point to device number
|
|
lda [<cache_cur_ptr],y
|
|
cmp <drvr_dev_num ;equal ?
|
|
bne cash_s01 ;nope
|
|
clc ;we've located the requested cell
|
|
rts
|
|
|
|
; it's not this cell, follow forward link and try again.
|
|
|
|
cash_s01 ldy #c_bkt_fwd
|
|
lda [<cache_cur_ptr],y
|
|
tax ;low link in x
|
|
iny
|
|
iny
|
|
lda [<cache_cur_ptr],y
|
|
tay ;high link in y
|
|
bne cash_s00 ;y <> 0, loop
|
|
txa
|
|
bne cash_s00 ;x <> 0, loop
|
|
|
|
; the forward link is 0, seems like we didn't find it
|
|
|
|
sec
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; if we get here then we found a block in the cache that's a different size
|
|
; than the requested size. this could be caused by different FSTs asking for
|
|
; it. in any case, to be safe and not sorry, this found block will be deleted
|
|
; from the cache and the find_block routine will return with carry set. the
|
|
; requestor will have to get that block off the disk.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
cash_s02 jsl cache_xdelete ;current_vp still valid here
|
|
sec ;pretend we didn't find the block
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; SEARCH_VOL_ID -- searches the cache for a volume ids deferred block
|
|
;
|
|
; This routine will search the cache list for a volume ids deferred block.
|
|
; If we find any, then we'll return carry clear otherwise carry set.
|
|
;
|
|
; inputs: A = volume id outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means no error, the requested volume id has deferred blocks
|
|
; c = 1 means something screwed up or no deferred blocks found
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT search_vol_id
|
|
search_vol_id ;
|
|
lda tail_vp
|
|
ora tail_vp+2
|
|
bne svi_0010
|
|
sec ;no blocks
|
|
rts
|
|
|
|
svi_0010 ;
|
|
ldx tail_vp
|
|
ldy tail_vp+2
|
|
|
|
svi_00
|
|
jsr curr_vp_to_ptr ;convert the current VP to a real pointer
|
|
|
|
ldy #c_priority
|
|
lda [<cache_cur_ptr],y ;get this cell's priority
|
|
bpl svi_01 ;skip if not deferred
|
|
ldy #c_volumeid
|
|
lda [<cache_cur_ptr],y
|
|
cmp <drvr_vol_id
|
|
bne svi_01 ;skip if not this volume id
|
|
clc ;we found at least one.
|
|
rts
|
|
|
|
svi_01 ldy #c_lru_bwd
|
|
lda [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
tax ;save backward vp link, lo
|
|
bne svi_03 ;skip if not 0
|
|
lda [<cache_cur_ptr],y
|
|
bne svi_03a ;skip if not 0
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; if we get here then we're at the head of the list and still haven't been
|
|
; able to find any blocks that match volume id and deferred bit set.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
sec ;we're at the end
|
|
rts
|
|
|
|
svi_03 lda [<cache_cur_ptr],y
|
|
svi_03a tay ;save backward vp link, hi
|
|
bra svi_00 ;loop for next cell
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; GETLINKS -- fetches the forward and backward vp links
|
|
;
|
|
; This routine will fetch the forward and backward vp links of either the LRU
|
|
; or bucket chain and return them into next_vp and prev_vp. Additionally, x
|
|
; and y will contain prev_vp and prev_vp+2.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = offset to backward link X = prev_vp
|
|
; Y = offset to forward link Y = prev_vp+2
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = don't care
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT getlinks
|
|
getlinks ;
|
|
lda [<cache_cur_ptr],y
|
|
sta next_vp
|
|
iny
|
|
iny
|
|
lda [<cache_cur_ptr],y
|
|
sta next_vp+2
|
|
|
|
txy ;offset to backward vp link
|
|
lda [<cache_cur_ptr],y
|
|
sta prev_vp
|
|
tax
|
|
iny
|
|
iny
|
|
lda [<cache_cur_ptr],y
|
|
sta prev_vp+2
|
|
tay
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; SET_FLINK_2NIL -- sets forward vp link to nil
|
|
;
|
|
; This routine will set the forward vp link of the cache cell pointed to by
|
|
; prev_vp to nil.
|
|
;
|
|
; inputs: A = offset to forward link outputs: A = trashed
|
|
; X = prev_vp X = trashed
|
|
; Y = prev_vp+2 Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = don't care
|
|
;
|
|
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT set_flink_2nil
|
|
set_flink_2nil ;
|
|
sta c_temp_fwd
|
|
jsl deref
|
|
stx <cache_pre_ptr
|
|
sty <cache_pre_ptr+2
|
|
|
|
ldy c_temp_fwd ;offset to forward vp link
|
|
lda #$0000
|
|
sta [<cache_pre_ptr],y
|
|
iny
|
|
iny
|
|
sta [<cache_pre_ptr],y
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; UNLINK -- unlinks the current cache cell
|
|
;
|
|
; This routine will link together the cache cells pointed to by next_vp and
|
|
; prev_vp. By doing this, the current cache cell will be 'unlink'ed from
|
|
; either the LRU or bucket chains.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = offset to backward link X = trashed
|
|
; Y = offset to forward link Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = don't care
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT unlink
|
|
unlink ;
|
|
stx c_temp_bwd
|
|
sty c_temp_fwd
|
|
|
|
ldx prev_vp
|
|
ldy prev_vp+2
|
|
jsl deref
|
|
stx <cache_pre_ptr
|
|
sty <cache_pre_ptr+2
|
|
|
|
ldy c_temp_fwd ;offset to forward vp link
|
|
lda next_vp
|
|
sta [<cache_pre_ptr],y
|
|
iny
|
|
iny
|
|
lda next_vp+2
|
|
sta [<cache_pre_ptr],y
|
|
|
|
EXPORT unlink_bwd
|
|
unlink_bwd ;
|
|
ldx next_vp
|
|
ldy next_vp+2
|
|
jsl deref
|
|
stx <cache_nxt_ptr
|
|
sty <cache_nxt_ptr+2
|
|
|
|
ldy c_temp_bwd ;offset to backward vp link
|
|
lda prev_vp
|
|
sta [<cache_nxt_ptr],y
|
|
iny
|
|
iny
|
|
lda prev_vp+2
|
|
sta [<cache_nxt_ptr],y
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; D_FROM_TAIL -- deletes a cache cell from the LRU tail
|
|
;
|
|
; This routine will try to delete the last recently used cache cell that's
|
|
; not deferred from the cache list.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means a cache cell was deleted
|
|
; c = 1 means it's mike's fault or they're all deferred blocks
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT d_from_tail
|
|
d_from_tail ;
|
|
ldx tail_vp
|
|
ldy tail_vp+2
|
|
|
|
dft_00
|
|
jsr curr_vp_to_ptr ;convert the current VP to a real pointer
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; we can only delete cell(s) that are not deferred. we may have to walk the
|
|
; entire list to find somebody who's not deferred.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
ldy #c_priority
|
|
lda [<cache_cur_ptr],y ;get this cell's priority
|
|
bpl dft_02 ;skip if not deferred
|
|
ldy #c_lru_bwd
|
|
lda [<cache_cur_ptr],y
|
|
iny
|
|
iny
|
|
tax ;save backward vp link, lo
|
|
bne dft_01 ;skip if not 0
|
|
lda [<cache_cur_ptr],y
|
|
bne dft_01a ;skip if not 0
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; if we get here then we're at the head of the list and still haven't been
|
|
; able to delete anybody.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
sec ;we're at the end
|
|
rts
|
|
|
|
dft_01 lda [<cache_cur_ptr],y
|
|
dft_01a tay ;save backward vp link, hi
|
|
bra dft_00 ;loop for next cell
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; if we get here then we found a non deferred block, delete this puppy. The
|
|
; tail_vp may be updated by the delete routine, we don't mess with it here.
|
|
;-----------------------------------------------------------------------------
|
|
|
|
dft_02 ;
|
|
|
|
dft_03 jsl cache_xdelete ;delete this block
|
|
rts ;result in c
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; IS_THERE_ROOM -- checks to if there is enough room for the next cache cell
|
|
;
|
|
; It's just a simple 4 byte compare.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means there's not enough room
|
|
; c = 1 means there's enough room
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT is_there_room
|
|
is_there_room ;
|
|
sec
|
|
lda c_bytes_free
|
|
sbc c_request_size
|
|
lda c_bytes_free+2
|
|
sbc #$0000
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; ADD_TO_FREE -- add freed bytes back to free byte count
|
|
;
|
|
; This routine will add the number of bytes about to be released, back to
|
|
; Mike. It's just a simple 4 byte addition.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = don't care
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT add_to_free
|
|
add_to_free ;
|
|
ldy #c_cellsize
|
|
clc
|
|
lda c_bytes_free
|
|
adc [<cache_cur_ptr],y
|
|
sta c_bytes_free
|
|
bcc atf_00
|
|
inc c_bytes_free+2 ;bump this for carry
|
|
atf_00 rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; SET_CACHE_PTR -- sets drvr_cach_ptr
|
|
;
|
|
; This routine will set drvr_cach_ptr, that's all.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = trashed
|
|
; Y = don't care Y = trashed
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = don't care
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT set_cache_ptr
|
|
set_cache_ptr ;
|
|
clc
|
|
lda <cache_cur_ptr ;get pointer to current cache cell
|
|
adc #c_headerlen ;add to it the cache header length
|
|
sta <drvr_cach_ptr ;pointer to cached block, lo
|
|
lda <cache_cur_ptr+2
|
|
adc #$0000
|
|
sta <drvr_cach_ptr+2 ;pointer to cached block, hi
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; LOOK_IN_ARRAY -- looks in bucket array for an entry
|
|
;
|
|
; This routine will index into the bucket array for an entry. If the entry is
|
|
; not 0, then the block we're looking for is somewhere in that particular
|
|
; bucket list. If the entry is 0, then the bucket array has no knowledge of
|
|
; the requested block.
|
|
;
|
|
; inputs: A = don't care outputs: A = trashed
|
|
; X = don't care X = vp to cached block, lo
|
|
; Y = don't care Y = vp to cached block, hi
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means there's something here, still have to traverse links
|
|
; c = 1 means there's no entry for this bucket index
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT look_in_array
|
|
look_in_array
|
|
jsr deref_bucket ;Deref the bucket table and setup cache_bkt_ptr
|
|
|
|
lda <drvr_blk_num ;get block number
|
|
and #$007f ;keep low 7 bits
|
|
sta c_temp_element ;save this for later
|
|
asl a
|
|
asl a ;multiply by 4 and make into index
|
|
tay
|
|
|
|
lda [<cache_bkt_ptr],y ;get lo part
|
|
tax ;save in x
|
|
iny
|
|
iny
|
|
lda [<cache_bkt_ptr],y ;get hi part
|
|
bne lia_00 ;skip if <> 0
|
|
tay
|
|
txa
|
|
bne lia_01 ;skip if <> 0
|
|
sec ;no entry for this block
|
|
rts
|
|
|
|
lia_00 tay ;move hi part into y
|
|
lia_01 clc ;indicate an entry found
|
|
rts
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; WRITE_TO_DISK -- writes a block to a disk
|
|
;
|
|
; This routine will write a block from the cache to a block device. The
|
|
; blocks to be written will most likely be deferred blocks. The block to be
|
|
; written is pointed to by cache_cur_ptr
|
|
;
|
|
; inputs: A = don't care outputs: A = don't care
|
|
; X = don't care X = don't care
|
|
; Y = don't care Y = don't care
|
|
; D = gs/os direct page D = i didn't change it
|
|
; B = don't care B = preserved
|
|
; K = don't care K = preserved
|
|
; LCbank = don't care LCbank = i didn't change it
|
|
;
|
|
; on output: c = 0 means the write's successful
|
|
; c = 1 means the write went wrong
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT write_to_disk
|
|
write_to_disk ;
|
|
lda #drvr_write ;driver write command
|
|
sta <drvr_call_num
|
|
|
|
ldy #c_blknum ;offset to block number, lo
|
|
lda [<cache_cur_ptr],y
|
|
sta <drvr_blk_num
|
|
iny
|
|
iny ;offset to block number, hi
|
|
lda [<cache_cur_ptr],y
|
|
sta <drvr_blk_num+2
|
|
|
|
sec
|
|
ldy #c_cellsize ;offset to size of cache cell
|
|
lda [<cache_cur_ptr],y
|
|
sbc #c_headerlen ;subtract away the cache header
|
|
sta <drvr_req_cnt ;want to write this many bytes
|
|
|
|
clc
|
|
lda <cache_cur_ptr
|
|
adc #c_headerlen ;point past the cacher header
|
|
sta <drvr_buf_ptr ;data starts here, lo
|
|
lda <cache_cur_ptr+2
|
|
adc #$0000
|
|
sta <drvr_buf_ptr+2 ;data starts here, hi
|
|
|
|
; i think we got everything ready for a write, let's do it
|
|
|
|
jsl dev_dispatcher
|
|
rts ;result in a and c
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; CACHE_ERROR -- exits to the caller
|
|
;
|
|
; This routine will exit back to the caller because of some sort of error.
|
|
; The error usually results from fiddling with the mike memory manager or
|
|
; the LRU or bucket links are trashed. This shouldn't happen though . . .
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cache_error
|
|
cache_error ;
|
|
plb ;restore caller's data bank
|
|
sec ;indicate an error
|
|
rtl ;go back with bad news
|
|
|
|
ENDP
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; Cache_In_Queue --
|
|
;
|
|
; This routine will add a task in the OutOfMemory queue routine. If the
|
|
; memory manager runs out of memory then I will purge the cache.
|
|
;
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT Cache_In_Queue
|
|
Cache_In_Queue Proc
|
|
|
|
lda >InQueueAlready ;See if I am already in the queue
|
|
bmi @skip_add ;I am already in the queue thank you very much.
|
|
|
|
pea MyOutOfMemRoutine>>16
|
|
pea MyOutOfMemRoutine
|
|
ldx #$0C02 ;AddToOOMQueue
|
|
jsl $e10000
|
|
lda #$FFFF
|
|
sta >InQueueAlready
|
|
@skip_add rtl ;return to the caller
|
|
|
|
Export Cache_out_of_Queue
|
|
Cache_out_of_Queue
|
|
lda call_number ;is this a Reset_Cache Call?
|
|
cmp #$2026
|
|
beq @skip_remove ;It sure is so don't do anything
|
|
|
|
lda InQueueAlready ;Am I in the queue?
|
|
beq @skip_remove
|
|
|
|
pea MyOutOfMemRoutine>>16
|
|
pea MyOutOfMemRoutine
|
|
ldx #$0D02 ;DeleteFromOOMQueue
|
|
jsl $e10000
|
|
lda #$0000 ;zero the InQueue Flag
|
|
sta InQueueAlready
|
|
|
|
@skip_remove rts
|
|
|
|
MyOutOfMemRoutine
|
|
dc.l 000000 ;Used by the Queue Manager?
|
|
cache_reset_list ;zero PCount for reset cache call
|
|
dc.w 0000 ;Doubles as ResetCacheList and Queue Header
|
|
dc.w $A55A
|
|
|
|
RTLAddr equ 1
|
|
stage equ RTLAddr+3 ;First or second stage of calls
|
|
BytesNeeded equ stage+2 ;Number of bytes the memory manager needs
|
|
Result equ BytesNeeded+4 ;Number of bytes I have freed up!
|
|
active_flag equ $e100Be ;OS active flag: BIT 15 set to 1 = busy
|
|
|
|
;
|
|
;Lets zap the results please
|
|
;
|
|
lda #$0000
|
|
sta Result,s
|
|
sta Result+2,s ;tell Memory Manger Nothing yet.
|
|
;
|
|
;See if the OS busy first. If it is then we let the OS deal with the situation.
|
|
;
|
|
lda >active_flag ;is the OS Busy???
|
|
bmi @end_mem ;Yep it sure is.
|
|
;
|
|
;See if we are being called before or after purging data.
|
|
;
|
|
|
|
lda stage,s
|
|
beq @do_free ;only free before purging....
|
|
@end_mem
|
|
longa off
|
|
sep #$20 ;8 bit mode please
|
|
;
|
|
;Get return address
|
|
;
|
|
pla
|
|
ply
|
|
;
|
|
;Remove size bytes of parameters
|
|
;
|
|
plx
|
|
plx
|
|
plx
|
|
|
|
phy
|
|
pha
|
|
longa on
|
|
rep #$20 ;back to caller
|
|
rtl
|
|
|
|
@do_free
|
|
phb
|
|
phk
|
|
plb
|
|
|
|
jsr GetFreeMem ;go get the count please A=Low, Y=High
|
|
sta curr_free_mem ;the current state of memory
|
|
sty curr_free_mem+2
|
|
;
|
|
;Now what we do is issue a Reset Cache Call to GS/OS
|
|
;
|
|
jsl $e100a8
|
|
dc.w $2026 ;reset cache call
|
|
dc.l cache_reset_list
|
|
|
|
jsr GetFreeMem ;A=Low, Y=High
|
|
sec
|
|
sbc curr_free_mem ;get the new memory count please
|
|
tax
|
|
tya
|
|
sbc curr_free_mem+2
|
|
|
|
plb ;reset the bank register please
|
|
sta result+2,s ;save the high word of newly freed memory
|
|
txa
|
|
sta result,s
|
|
bra @end_mem ;return to the caller
|
|
|
|
GetFreeMem
|
|
pha
|
|
pha ;lets see how much memory is free right now.
|
|
ldx #$1b02 ;Get FREEMEM call
|
|
jsl $e10000
|
|
|
|
pla ;get the low word
|
|
ply
|
|
rts
|
|
|
|
curr_free_mem dc.l 00
|
|
InQueueAlready dc.w 00 ;indicates if I am installed in the Queue.
|
|
endp
|
|
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; DATA
|
|
;
|
|
; Note: every variable better be an even number of bytes.
|
|
;
|
|
; cache_cur_ptr, cache_nxt_ptr, cache_pre_ptr and cache_bkt_ptr are in
|
|
; GS/OS direct page
|
|
;
|
|
; Copyright (c) 1987 Apple Computer Inc. All rights reserved.
|
|
; author: Ray (Rowdy Yates) Chiang
|
|
;-----------------------------------------------------------------------------
|
|
|
|
EXPORT cache_data
|
|
cache_data PROC
|
|
|
|
EXPORT start_of_data
|
|
start_of_data ;
|
|
EXPORT head_vp
|
|
head_vp DS.B 4 ;vp to head of LRU list
|
|
EXPORT tail_vp
|
|
tail_vp DS.B 4 ;vp to tail of LRU list
|
|
EXPORT current_vp
|
|
current_vp DS.B 4 ;vp to current cache cell
|
|
EXPORT next_vp
|
|
next_vp DS.B 4 ;vp to next cache cell
|
|
EXPORT prev_vp
|
|
prev_vp DS.B 4 ;vp to previous cache cell
|
|
EXPORT bucket_vp
|
|
bucket_vp DS.B 4 ;vp to bucket vps
|
|
EXPORT c_bytes_free
|
|
c_bytes_free DS.B 4 ;number of bytes free in cache
|
|
EXPORT c_request_size
|
|
c_request_size DS.B 2 ;current request size
|
|
EXPORT c_temp_element
|
|
c_temp_element DS.B 2 ;temp for bucket element
|
|
EXPORT c_temp_fwd
|
|
c_temp_fwd DS.B 2 ;temp for forward vp link
|
|
EXPORT c_temp_bwd
|
|
c_temp_bwd DS.B 2 ;temp for backward vp link
|
|
EXPORT c_temp_1
|
|
c_temp_1 DS.B 2 ;temp for device number or FST offset
|
|
EXPORT c_temp_2
|
|
c_temp_2 DS.B 2 ;temp for device number or FST value
|
|
EXPORT c_temp_nvp
|
|
c_temp_nvp DS.B 4 ;temp for next_vp
|
|
EXPORT c_marker
|
|
c_marker DS.B 2 ;temp for debugging
|
|
EXPORT no_find
|
|
no_find DS.B 2 ;flag for enable/disable find routine
|
|
EXPORT message_shown
|
|
message_shown DS.B 2 ;flag to indicate deferred blocks
|
|
; ;have been flushed and user was told
|
|
export in_queue
|
|
|
|
in_queue dc.w $0000
|
|
EXPORT end_of_data
|
|
end_of_data
|
|
export c_data_len:equ
|
|
c_data_len equ end_of_data-start_of_data-1
|
|
|
|
ENDP
|
|
;===============================================================================
|
|
; cashseg
|
|
;
|
|
; Framework for building load segment cashseg.
|
|
;
|
|
;===============================================================================
|
|
|
|
|
|
cashseg_end PROC
|
|
ENDP
|
|
|
|
cache_overflow proc org $00AA00, skip ;This will generate an error if
|
|
endp ;the code overflows its space.
|
|
|
|
END
|