home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Millennium Time Capsule
/
AC2000.BIN
/
disks
/
hbasic_1
/
ooplib
/
oopv0_1.s
< prev
Wrap
Text File
|
1994-08-03
|
15KB
|
561 lines
opt l+,c+
*
* Object Oriented Programming Library for HiSoft Basic.
* Version 0.1 - Only classes & attributes are available.
*
* See accompanying docs for details.
*
* This library was written using DevpacST, the HiSoft assembly language
* development system.
*
*===========================================================================
max_object_size EQU 100 ;100byte object size = 25 long ints
max_classes EQU 20 ;maximum numberof classes available
class_namesize EQU 8 ;8char class names
ct_entry EQU 100 ;100bytes per class table entry
;<8char name><2byte blank><2byte attrib count><attrib names, 8bytes each>
ct_name EQU 0
ct_null EQU 8
ct_constructor EQU 10
ct_attrib_count EQU 14
ct_attribs EQU 12
attrib_name_size EQU 8 ;Length of attribute names
ot_entry EQU 10 ;10bytes per object table entry
;<2byte type><4byteaddress><6bytes unallocated>
ot_type EQU 0
ot_address EQU 2
os_type EQU 0 ;each object in the store has the type filled in here
os_attribs EQU 2 ;start of the attribute area of the object
* Malloc #size, variable
Malloc macro
move.l \1,-(a7)
move.w #$48,-(a7)
trap #1
addq.l #6,a7
move.l d0,\2
endm
* 8) print '<string>'
print macro
lea.l x\@(pc),a0
bsr prnt
bra y\@
x\@ dc.b \1,0
cnop 0,2
y\@ nop
endm
include library.h the standard library include file
library OOP library name
xref get_string external references
xref get_array
xref make_string
xref.l gl_scratch this is referenced off global!
xdef init_oop
xdef declare_objects
xdef class
xdef object
xdef delete_object
xdef o_iset
xdef o_iget
xdef flush_objects
subdef lng init_oop Initialise the OOP system
subdef lng declare_objects How many objects do we think we'll be using?
subdef str,str,lng class Define a new class
fn_lng str object Instantiate an object of a class & return a pointer to it
subdef lng delete_object Delete an object
subdef lng,str,lng o_iset Set the value of an attribute.
fn_lng lng,str o_iget Get the value of an attribute.
subdef lng flush_objects Flush the object store & retreive empty space
option 'uv' underlines & variable checks
libstart the code follows
opt D+
*====================================================================================
* Initialise the OOP run-time system
*====================================================================================
init_oop:
lea.l this(pc),a0
move.l 4(sp),(a0) ;Set the this global
rts
*====================================================================================
* Set up the object store by allocating memory
*====================================================================================
declare_objects:
Malloc #ct_entry*max_classes,d2 ;allocate entries in class table
lea.l class_table(pc),a0
move.l d2,(a0)
move.l d2,a0
clr.l (a0)
lea.l next_class(pc),a0 ;initialise the next class pointer
move.l d2,(a0)
cmp.l #0,d2
beq declare_report_error
move.l 4(sp),d1
subq.l #1,d1
mulu #ot_entry,d1 ;allocate the object table
lea.l object_table_size(pc),a0 ;store the max number of objects (size of object table)
move.l d1,(a0)
add.l #ot_entry,d1
Malloc d1,d2
lea.l ot_next(pc),a0 ;first object goes at start of ot
move.l d2,(a0)
lea.l object_table(pc),a0 ;set pointer to ot in variable area
move.l d2,(a0)
move.l d2,a0
clr.l (a0) ;set first ot entry = null
cmp.l #0,d2
beq declare_report_error
mulu #max_object_size,d1 ;allocate object storage
lea.l object_store_size(pc),a0
move.l d1,(a0)
Malloc d1,d2
lea.l next_object(pc),a0 ;first object at start of object store
move.l d2,(a0)
lea.l object_store(pc),a0
move.l d2,(a0)
move.l d2,a0
clr.l (a0)
cmp.l #0,d2
beq declare_report_error
rts
declare_report_error:
print 'OOP_error[1]-unable_to_allocate_object_storage.'
rts
*====================================================================================
* Create a new class
*====================================================================================
class:
move.l 12(sp),a0 ;pointer to class name
bsr get_string ;D4 contains length of attributes string
move.l a1,d1
lea.l next_class(pc),a0
move.l (a0),a1 ;location of next class table entry
move.l d1,a0
move.w #0,ct_null(a1) ;null entry in table
cmp.l #class_namesize,d4 ;8char class names
blt cn_oksize
move.l #class_namesize,d4
cn_oksize:
subq.w #1,d4
cn_to_table_loop: ;copy class_name into class table
move.b (a0)+,(a1)+
dbf d4,cn_to_table_loop
move.b #0,(a1) ;zero terminate the string
;get the attributes now
move.l 8(sp),a0 ;pointer to class attributes
bsr get_string ;D4 contains length of attributes string
move.l a1,d1
lea.l next_class(pc),a0
move.l (a0),a1 ;location of next class table entry
add.l #ct_attribs,a1
move.l d1,a0
move.w #0,d5 ;d5=#attributes
copy_attribs:
bsr get_this_attrib
cmp.w #0,d4
bne copy_attribs
move.b #0,(a1) ;zero terminate the string
lea.l next_class(pc),a1
move.l d1,a0
move.w d5,ct_attrib_count(a0)
move.l 4(sp),ct_constructor(a0) ;fill in default constructor field
move.l (a1),a0
lea.l next_class(pc),a1
move.l (a1),a0
add.l #ct_attribs,a0
lea.l next_class(pc),a1 ;Update next class pointer to next slot in ct
move.l (a1),d1
add.l #ct_entry,d1
move.l d1,(a1)
rts
get_this_attrib:
addq.w #1,d5 ;increment attribute count
move.w #0,d0
attr_to_table: ;copy an attribute accross
move.b (a0)+,(a1)+
addq.w #1,d0 ;increment number of chars in current attrib
subq.w #1,d4 ;decrement number of chars remaining in attrib list
cmp.w #0,d4 ;ahh. end of attributes list
ble attr_pad
cmp.b #',',(a0) ;comma seperator, begin a new attrib.
bne xxx_1
add.l #1,a0 ;skip the comma
subq.w #1,d4 ;account for comma in string length count
bra attr_pad ;jump to pad out
xxx_1:
cmp.b #attrib_name_size,d0 ;got max chars - so we're clipping
bne gta_loop ; else continue to get more
bra gta_end ;got a full attrib name
attr_pad:
cmp.b #attrib_name_size,d0 ;got max chars - so we're clipping
beq gta_end ;if not, pad with spaces
move.b #' ',(a1)+
addq.w #1,d0
bra attr_pad
gta_loop:
bra attr_to_table
gta_end:
rts
*====================================================================================
* Create an object of a class
*====================================================================================
object:
move.l 4(sp),a0 ;pointer to class attributes
bsr get_string ;D4 contains length of attributes string
clr.l d0 ;d2=number of characters matched
movem.l a3-a6,-(sp)
move.l a1,a4 ;keep a copy of class name
move.w #1,d5 ;class id
lea.l class_table(pc),a3
move.l (a3),a0 ;a0 points to start of class table
find_class:
cmp.l d0,d4 ;have we found the target in the ct ?
beq end_of_target
move.b (a1,d0),d1 ;get char from target
move.b (a0,d0),d2 ;get char from ct
addq.w #1,d0
cmp.w #class_namesize+1,d0 ;exceeded class name field - must be this class
beq got_class
cmp.b d1,d2 ;still matches so continue loop
beq find_class
fc_not_this_one:
add.l #ct_entry,a0 ;next class table entry
cmp.b #0,(a0) ;end of table ?
beq class_not_found ;bum out
addq.w #1,d5 ;next class id
clr.w d0
bra find_class
end_of_target:
move.b (a0,d0),d2 ;end of target string. is next char in ct a 0?
cmp.b #0,d2 ; if so then we have a match, 0 used as terminator
bne fc_not_this_one
got_class:
lea.l ot_next(pc),a0 ;pointer to next free ot entry
move.l (a0),a1
move.l a1,d0
lea.l object_table_size(pc),a6 ;get the size of the object table
move.l (a6),d1
lea.l object_table(pc),a6 ;get the start of the object table
add.l (a6),d1 ;end of ot in d1
cmp.l d1,a1 ;is ot full? if so, we'll have to scan for a space.
blt rtn_scan_ot_for_space
move.l d1,(a0) ;flag ot_next as always being full
bra scan_ot_for_space
rtn_scan_ot_for_space:
move.l a1,d1 ;calculate object store slot from
lea.l object_table(pc),a2 ;object table slot.
move.l (a2),d2
sub.l d2,d1
divu #ot_entry,d1
and.l #$0000ffff,d1
mulu #max_object_size,d1
lea.l object_store(pc),a2
move.l (a2),a3
adda.l d1,a3
move.w d5,os_type(a3) ;tag object with it's type id
move.w d5,ot_type(a1) ;fill object type field in ot
move.l a3,ot_address(a1) ;fill in object address field in ot
move.l a1,tos ;return pointer to object table entry
add.l #max_object_size,a3 ;update next_object
lea.l next_object(pc),a2 ;pointer to next object
move.l a3,(a2)
add.l #ot_entry,a1 ;update ot_next
move.l a1,(a0)
movem.l (sp)+,a3-a6
rts
scan_ot_for_space:
lea.l object_table(pc),a6 ;start scan at base of ot
move.l (a6),a1
scan_ot_loop:
cmp.w #0,ot_type(a1) ;is ot entry empty?
beq rtn_scan_ot_for_space
cmp.l a1,d1 ;have we run out of ot space?
blt no_ot_space_left
add.l #ot_entry,a1 ;check next slot
bra scan_ot_loop
no_ot_space_left:
print 'OOP_error[2]-Object_Table_full_-_declare_more_object_space'
move.l #0,tos ;return 0 as error
movem.l (sp)+,a3-a6
rts
class_not_found:
print 'OOP_error[3]-Class_used_before_defined'
move.l #0,tos ;return 0 as error
movem.l (sp)+,a3-a6
rts
*====================================================================================
* Declare an object of a class.
*====================================================================================
delete_object:
move.l 4(sp),a0 ;pointer to ot entry
move.l ot_address(a0),a1 ;pointer to object store entry
move.w #0,ot_type(a0) ;mark object table entry as unused
move.w #0,os_type(a1) ;mark object as deleted (class id = 0)
rts
*====================================================================================
* Set the value of an attribute in an object
*====================================================================================
o_iset:
clr.l d0
move.l 4(sp),d7 ;the long int value to set
move.l 8(sp),a0
bsr get_string ;a1 points to name of attribute
move.l 12(sp),a0 ;get pointer to object
move.w ot_type(a0),d0 ;get object type
subq.w #1,d0
mulu.w #ct_entry,d0 ;offset to class table entry for this id
lea.l class_table(pc),a2
add.l (a2),d0 ;class table address
move.l d0,a2 ;pointer to class table entry
move.l ct_attrib_count(a2),d1 ;d1=number of attributes available
add.l #ct_attribs,a2 ;a2=pointer to start of attribute name area
move.l #0,d6 ;d6=count of how many attribs we've looked at so far
sfind_attribute:
move.w #0,d2
sscan_along_attribute_name:
move.b (a2,d2),d3 ;first char of attrib name
move.b (a1,d2),d5
cmp.b d2,d4 ;have we reached end of parameter
beq smatched_the_param
cmp.b d3,d5 ;names don't match
bne snext_name
addq.w #1,d2
cmp.w #attrib_name_size,d2
beq sgot_the_right_attribute
bra sscan_along_attribute_name
smatched_the_param:
cmp.w #attrib_name_size,d4
beq sgot_the_right_attribute
move.b 1(a2,d2),d3
cmp.b #' ',d3
beq sgot_the_right_attribute
snext_name:
add.l #attrib_name_size,a2
addq.w #1,d6
cmp.w d6,d1 ;have we looked at all the attribs ?
beq attrib_not_found
bra sfind_attribute
sgot_the_right_attribute:
lsl.l #2,d6
move.l ot_address(a0),a1
move.l d7,os_attribs(a1,d6)
rts
*====================================================================================
* Get an attribute value from an object
*====================================================================================
o_iget:
clr.l d0
move.l 4(sp),a0
bsr get_string ;a1 points to name of attribute
move.l 8(sp),a0 ;get pointer to object
move.w ot_type(a0),d0 ;get object type
subq.w #1,d0
mulu.w #ct_entry,d0 ;offset to class table entry for this id
lea.l class_table(pc),a2
add.l (a2),d0 ;class table address
move.l d0,a2 ;pointer to class table entry
move.l ct_attrib_count(a2),d1 ;d1=number of attributes available
add.l #ct_attribs,a2 ;a2=pointer to start of attribute name area
move.l #0,d6 ;d6=count of how many attribs we've looked at so far
find_attribute:
move.w #0,d2
scan_along_attribute_name:
move.b (a2,d2),d3 ;first char of attrib name
move.b (a1,d2),d5
cmp.b d2,d4 ;have we reached end of parameter
beq matched_the_param
cmp.b d3,d5 ;names don't match
bne next_name
addq.w #1,d2
cmp.w #attrib_name_size,d2
beq got_the_right_attribute
bra scan_along_attribute_name
matched_the_param:
cmp.w #attrib_name_size,d4
beq got_the_right_attribute
move.b 1(a2,d2),d3
cmp.b #' ',d3
beq got_the_right_attribute
next_name:
add.l #attrib_name_size,a2
addq.w #1,d6
cmp.w d6,d1 ;have we looked at all the attribs ?
beq attrib_not_found
bra find_attribute
got_the_right_attribute:
lsl.l #2,d6
move.l ot_address(a0),a1
move.l os_attribs(a1,d6),tos
rts
attrib_not_found:
print 'OOP_error[4]-attrib_not_found'
move.l #0,tos
rts
*====================================================================================
* Flush object store
*====================================================================================
flush_objects:
* clr.l d0
* lea.l object_store_size(pc),a0
* move.l (a0),d1
*
* lea.l object_store(pc),a0
* move.l (a0),a1
* move.l a1,a0
*
* cmp.l d0,d1 ;have we looked at the whole object store?
* blt finished_flush
*
*flush_:
* cmp.w #0,os_type(a0) ;have we encountered an empty slot?
* beq flush_skip1
* add.w #max_object_size,d0 ;yes, so skip it and continue
* bra flush_skip_blanks
*
*flush_skip1:
* move.w #(max_object_size/4)-1,d2
*flush_loop:
* move.l (a0,d0),(a0)+
* dbra d2,flush_loop
*
*finished_flush:
print 'flushed_the_object_store'
move.l #0,tos
rts
*print a string
prnt movem.l a0-a3/d0-d5,-(a7)
move.l a0,-(a7)
move.w #9,-(a7)
trap #1
addq.l #6,a7
movem.l (a7)+,a0-a3/d0-d5
rts
object_table dc.l 0 ;pointer to the object table
object_table_size: ;the size of the object table in bytes
dc.l 0
ot_next dc.l 0 ;pointer to next free entry in object table
object_store dc.l 0 ;pointer to the start of the first object store block
object_store_size:
dc.l 0 ;the size of the object store.
next_object: ;pointer to the next free object store entry
dc.l 0
class_temp_name dc.l 0
class_temp_attribs:
dc.l 0
class_table dc.l 0 ;pointer to the class definition table
next_class dc.l 0 ;pointer to the next free entry in the class definition table
this dc.l 0 ;pointer to the location of the current object when calling a service
;this is the location of the this& variable
END