VM02/src/strpool.s

285 lines
5.5 KiB
ArmAsm
Executable File

;*
;* JAVA STRING POOL MANAGER FOR 6502
;*
;*
;* THE STRING POOL CONTAINS ALL THE STRING CONSTANTS USED BY THE JVM. A HASH TABLE AIDS
;* IN THE LOOKUP OF THE STRING CONSTANTS. A STRING IS DEFINED BY ITS LENGTH AND
;* CONTENTS. THESE MAP INTO A UNIQUE HANDLE. TWO STRINGS ARE EQUAL IF THEIR HANDLES ARE
;* EQUAL. THE STRING POOL DOES NOT CONTAIN STRING OBJECTS. STRING OBJECTS SIMPLY CONTAIN
;* A HANDLE TO THEIR STRING VALUE.
;*
;* THE HASH VALUE OF A STRING IS CALCULATED BY XORING THE NEXT CHARACTER
;* INTO A ROTATED TOTAL. E.I. HASH = CHARACTER ^ ROL(HASH);
;*
.INCLUDE "global.inc"
.IMPORT INIT_START,INIT_END
.IMPORT PRBYTE,CROUT,PUTS,PUTSLN,PRSTR,PRSTRLN,MEMSRC,MEMDST,MEMCLR,MEMCPY
.IMPORT HMEM_ALLOC,HMEM_ALLOC_FIXED,HMEM_FREE
.IMPORT HMEM_LOCK,HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC
.EXPORT HSTR_INIT,HSTR_HASH,STR_HASH,HSTRPL_ADD,HSTRPL_DEL
.SEGMENT "INIT"
;*
;* CREATE EXTERNAL LINKEAGE
;*
HSTR_INIT: LDA #<HSTRPL_ADD
STA LINK_HSTRADD
LDA #>HSTRPL_ADD
STA LINK_HSTRADD+1
LDA #<HSTR_HASHL
LDX #>HSTR_HASHL
AUXZP_ACCESS_ON
JSR MEMDST
LDA #$00
LDX #$02
JSR MEMCLR
AUXZP_ACCESS_OFF
RTS
.CODE
;*
;* ADD A STRING CONSTANT TO THE POOL. RETURN A HANDLE TO THE STRING CONSTANT. IF
;* A MATCHING STRING ALREADY EXISTS, RETURN ITS HANDLE AFTER INCREMENTING THE REF COUNT.
;*
HSTR_HASH: JSR HMEM_PTR
STR_HASH: STA STRPTR ; HASH STRING
STX STRPTR+1
LDY #$00
LDA (STRPTR),Y
BEQ STR_EXIT
TAY
LDA #$00
: CMP #$80 ; COPY MSB INTO CARRY
ROL
EOR (STRPTR),Y
DEY
BNE :-
STR_EXIT: RTS
;*
;* ADD A STRING TO THE POOL
;* ENTRY: AX = POINTER TO STRING
;* EXIT: AX = HANDLE TO STRING IN POOL
;* Y = HASH
;*
HSTRPL_ADD: JSR STR_HASH
STA STRHASH ; SAVE HASH FOR LATER
TAY
AUXZP_ACCESS_ON
LDA HSTR_HASHL,Y
LDX HSTR_HASHH,Y
AUXZP_ACCESS_OFF
BEQ STRNEW ; EMPTY LIST, STRING NOT FOUND
STRMATCH_LOOP: STA HSTR
STX HSTR+1
JSR HMEM_PTR
STA STRMATCHPTR
STX STRMATCHPTR+1
LDY #$00 ; COMPARE STRING LENGTHS
LDA (STRPTR),Y
CMP (STRMATCHPTR),Y
BNE STRMATCH_NEXT+2 ; NO NEED TO SET Y TO $00 AGAIN
TAY ; COMPARE STRINGS
BEQ STRMATCH ; CASE OF NULL STRING
: LDA (STRPTR),Y
CMP (STRMATCHPTR),Y
BNE STRMATCH_NEXT
DEY
BNE :-
STRMATCH: LDA HSTR ; STRING EXISTS, INC REF CNT
LDX HSTR+1
JSR HMEM_REF_INC
LDY STRHASH
RTS
STRMATCH_NEXT: LDY #$00 ; NEXT HANDLE AT END OF STRING
LDA (STRMATCHPTR),Y
CLC
ADC STRMATCHPTR
STA STRMATCHPTR
BCC :+
INC STRMATCHPTR+1
: LDY #$02
LDA (STRMATCHPTR),Y ; GET NEXT STRING IN LIST
DEY
TAX
LDA (STRMATCHPTR),Y
CPX #$00
BNE STRMATCH_LOOP
; BEQ STRNEW ; END OF LIST, STRING NOT FOUND
STRNEW: LDY #$00 ; ALLOC MEM FOR STRING ...
LDA (STRPTR),Y
LDX #$00
CLC
ADC #$03 ; ... AND HANDLE TO NEXT STRING IN LIST
BCC :+
INX
: LDY #$01
JSR HMEM_ALLOC
STA HSTR
STX HSTR+1
JSR HMEM_PTR
STA STRMATCHPTR
STX STRMATCHPTR+1
LDY #$00 ; COPY STRING LENGTH OVER
LDA (STRPTR),Y
STA (STRMATCHPTR),Y
TAY ; COPY STRING CHARACTERS
BEQ STRINSRT
: LDA (STRPTR),Y
STA (STRMATCHPTR),Y
DEY
BNE :-
STRINSRT: LDA (STRMATCHPTR),Y ; INSERT NEW HANDLE AT HEAD OF HASH LIST
INY
CLC
ADC STRMATCHPTR
STA STRMATCHPTR
BCC :+
INC STRMATCHPTR+1
: LDX STRHASH
AUXZP_ACCESS_ON
LDA HSTR_HASHL,X
AUXZP_ACCESS_OFF
STA (STRMATCHPTR),Y
INY
AUXZP_ACCESS_ON
LDA HSTR_HASHH,X
AUXZP_ACCESS_OFF
STA (STRMATCHPTR),Y
LDY STRHASH
LDA HSTR+1
AUXZP_ACCESS_ON
STA HSTR_HASHH,Y
AUXZP_ACCESS_OFF
TAX
LDA HSTR
AUXZP_ACCESS_ON
STA HSTR_HASHL,Y
AUXZP_ACCESS_OFF
RTS
;*
;* DECREMENT REFERENCE COUNT OF STRING FROM THE POOL. DELETE IT IF COUNT IS ZERO.
;* ENTRY: AX = HANDLE TO STRING
;*
HSTRPL_DEL: STA HSTR
STX HSTR+1
JSR HMEM_LOCK
JSR STR_HASH
STA STRHASH
LDY #$00
LDA (STRPTR),Y
INY
CLC
ADC STRPTR
STA STRPTR
BCC :+
INC STRPTR+1
: LDA (STRPTR),Y
INY
STA HSTRNEXT
LDA (STRPTR),Y
STA HSTRNEXT+1
LDY STRHASH
AUXZP_ACCESS_ON
LDA HSTR_HASHL,Y
LDX HSTR_HASHH,Y
AUXZP_ACCESS_OFF
BEQ STRBAD ; EMPTY LIST, STRING NOT FOUND
CMP HSTR
BNE HSTRFIND_NEXT
CPX HSTR+1
BNE HSTRFIND_NEXT
LDA HSTRNEXT
LDX HSTRNEXT+1
; LDY STRHASH ; UNLINK FROM HEAD OF LIST
AUXZP_ACCESS_ON
STA HSTR_HASHL,Y
TXA
STA HSTR_HASHH,Y
AUXZP_ACCESS_OFF
LDA HSTR
LDX HSTR+1
JMP HMEM_FREE
HSTRFIND_LOOP: CMP HSTR
BNE HSTRFIND_NEXT
CPX HSTR+1
BNE HSTRFIND_NEXT
LDY #$01 ; UNLINK STRING FROM LIST
LDA HSTRNEXT
STA (STRMATCHPTR),Y
INY
LDA HSTRNEXT+1
STA (STRMATCHPTR),Y
HSTRFREE: LDA HSTR ; FREE STRING MEMORY
LDX HSTR+1
JMP HMEM_FREE
HSTRFIND_NEXT: JSR HMEM_PTR
STA STRMATCHPTR
STX STRMATCHPTR+1
LDY #$00 ; NEXT HANDLE AT END OF STRING
LDA (STRMATCHPTR),Y
CLC
ADC STRMATCHPTR
STA STRMATCHPTR
BCC :+
INC STRMATCHPTR+1
: LDY #$02
LDA (STRMATCHPTR),Y ; GET NEXT STRING IN LIST
DEY
TAX
LDA (STRMATCHPTR),Y
BNE HSTRFIND_LOOP
STRBAD:
.IFDEF DEBUG
PERR "BAD STRING HANDLE"
JMP HSTRFREE
.ELSE
BEQ HSTRFREE ; END OF LIST, STRING NOT FOUND, FREE IT ANYWAY
.ENDIF
.IFDEF DEBUG_STRPOOL
;*
;* PRINT OUT STRING POOL DETAILS
;*
.EXPORT HSTRPL_DUMP
HSTRPL_DUMP: JSR CROUT
PSTRLN "STRING POOL STATE"
PSTRLN "================="
LDY #$00
STY STRHASH
HSTR_HSHDUMP: LDY STRHASH
AUXZP_ACCESS_ON
LDA HSTR_HASHL,Y
LDX HSTR_HASHH,Y
AUXZP_ACCESS_OFF
CPX #$00
BEQ HSTR_HSHNEXT
STA HSTR
STX HSTR+1
PSTR "HASH LIST: $"
LDA STRHASH
JSR PRBYTE
JSR CROUT
LDA HSTR
LDX HSTR+1
HSTR_LSTDUMP: JSR HMEM_PTR
STA STRPTR
STX STRPTR+1
JSR PRSTRLN
LDY #$00 ; NEXT HANDLE AT END OF STRING
LDA (STRPTR),Y
INY
CLC
ADC STRPTR
STA STRPTR
BCC :+
INC STRPTR+1
: LDA (STRPTR),Y ; GET NEXT STRING IN LIST
INY
PHA
LDA (STRPTR),Y
TAX
PLA
BNE HSTR_LSTDUMP
HSTR_HSHNEXT: INC STRHASH
BNE HSTR_HSHDUMP
RTS
.ENDIF