;imask are the events which are never returned to the user
struct v {
.areastart DCD 0
.areatype DCD 0
.areasize DCD 0
.gamewindow DBD 4; 4 words
.plotwindow DBD 4; 4 words
.killwindow DBD 4; 4 words
.plotxofs DCD 0
.plotyofs DCD 0
.gravx DCD 0
.gravy DCD 0
.colch0 DCD 0
.colch1 DCD 0
.colch3 DCD 0
.colchsave DBD 4; 4 words - save area for colch regs
.colchboxes DBD 8; 8 words - store area for bounding boxes
.errorctr DCD 0
.errorblock DCD 0
.errortable DCD 0
.remote DCD 0
.remoteR12 DCD 0
.buffer DBD 16 ; 16 words
.temp0 DCD 0
.temp1 DCD 0
.temp2 DCD 0
.sizeof
}
struct b {
.id DCD 0
.ptr DCD 0
.name DBB 8 ; 8 bytes
.size DCD 0
.flags DCD 0
.sizeof
}
struct t {
.id DCD 0
.ptr DCD 0
.name DBB 8 ; 8 bytes
.size DCD 0
.flags DCD 0
.objsize DCD 0
.number DCD 0
.tabflags DCD 0
.next DCD 0
.sizeof
}
struct save {
.id DCD 0
.name DBB 8 ; 8 bytes
.objsize DCD 0
.number DCD 0
.gap DCD 0
.sizeof
}
struct h {
.id DCD 0
.ptr DCD 0
.name DBB 8 ; 8 bytes
.size DCD 0
.flags DCD 0
.type DCD 0
.areasize DCD 0
.tlist DCD 0
.sizeof
}
struct o {
.type DCD 0
.flags DCD 0
.x DCD 0
.y DCD 0
.xvec DCD 0
.yvec DCD 0
.timer DCD 0
.size DCD 0
.timer2 DCD 0
.sizeof
}
struct c {
.id DCD 0
.ptr DCD 0
.name DBB 8 ; 8 bytes
.size DCD 0
.flags DCD 0
.writeofs DCD 0
.sizeof
}
struct cent {
.ofs DCD 0
.minx DCD 0
.miny DCD 0
.maxx DCD 0
.maxy DCD 0
.sizeof
}
struct tlist {
.number DCD 0
.sizeof
}
.start
DCD 0
DCD init
DCD final
DCD service
DCD title
DCD help
DCD commandtable
DCD &49600
DCD swicode
DCD switab
DCD 0
.title
DCB "Amnesia"
DCB 0
.help
DCB "Amnesia 1.50 (20 Apr 1995)"
DCB 0
ALIGN
.commandtable
DCB "Amnesia",0
ALIGN
DCD 0
DCD 0
DCD 0
DCD amnesiahelp
DCB "Amnesia"
DCB 0
ALIGN
DCD amscode
DCD &000cff01
DCD amssyntax
DCD amshelp
DCB "AmnesiaFlags",0
ALIGN
DCD 0
DCD 0
DCD 0
DCD flagshelp
DCB "AmnesiaObjects",0
ALIGN
DCD 0
DCD 0
DCD 0
DCD objectshelp
DCB "AmnesiaSWIs",0
ALIGN
DCD 0
DCD 0
DCD 0
DCD swishelp
DCD 0; *** END MARKER ***
.amnesiahelp
DCB 27,0," is a module which provides memory allocation functions and handling routines for on-screen objects in a versatile form. See the help files in the ",27,0," application for details.",10,13
DCB "Copyright A.Southgate 1994 - may be used and distributed freely.",10,13
DCB "Amnesia was written and is maintained by Andy Southgate - permanent address 5 Longview, Sutton, Cambs.",10,13
DCB 0
.amshelp
DCB 27,0," issues an Amnesia SWI from the command line. Its mainly used by me for testing. The SWI tail means the letters after Amnesia_ . If TO is appended register results are returned. String parameters should be entered in SINGLE quotes ('These ones')",10,13
DCB "Amnesia object flags are (bit - action)",10,13
DCB "0 - FastSpr plot",10,13
DCB "1 - User plot",10,13
DCB "2 - Use velocity",10,13
DCB "3 - Apply Gravity",10,13
DCB "4 - Use plot offsets",10,13
DCB "5 - Use timer for FastSpr animation",10,13
DCB "6 - Make up the object size (from FastSpr file)",10,13
DCB "7 - Collison check object",10,13
DCB "8 - Generate attention request if timer expires",10,13
DCB "9 - Destroy object if timer expires",10,13
DCB "10 - Request attention always",10,13
DCB "11 - Run timer 2",10,13
DCB "12 - Zero velocity (and this bit) after first addition",10,13
DCB "13 - Attention if outside game window (horizontal)",10,13
DCB "14 - Attention if outside game window (vertical)",10,13
DCB "15 - Use plot window",10,13
DCB "16 - Use kill window",10,13
DCB "17 - Add to the collision checking table only if object inside plot window",10,13
DCB "18 - Object needs saving by Amnesia_TableSave",10,13
DCB "19 - reserved",10,13
DCB "Bits 20-23 are transient flags for the user. They are zeroed on each process pass",10,13
DCB "Bits 24-31 are the user attention trigger bits. If a user attention request bit is set when calling Amnesia_SelectTable, then all of the objects with that bit set in their flags will return for attention.",10,13
DCB 0
.objectshelp
DCB "The structure of an amnesia object is as follows :",10,13
DCB "base+0",9,"The object type. If this is zero the object is ignored. This number is passed to FastSpr as a sprite number when requested.",10,13
DCB "base+4",9,"The flag word (see AmnesiaFlags)",10,13
DCB "base+8",9,"The x coordinate (pixels per process pass << 12)",10,13
DCB "base+12",9,"The y coordinate",10,13
DCB "base+16",9,"The x velocity (added to the x coord every process pass",10,13
DCB "base+20",9,"The y velocity",10,13
DCB "base+24",9,"The timer. Amnesia performs a SUB R0,R0,R0,LSL #16 to this value on each process pass",10,13
DCB "base+28",9,"The object size [x size][y size] in pixels, 16 bit values",10,13
DCB "base+32",9,"The second timer",10,13
DCB "Only the first two entries are always required. The rest may be required depending on the settings of the flag word",10,13
DCB 0
.swishelp
DCB "Amnesia supports the following SWIs.",10,13,10,13
;returns R0 pointing to the end marker of the block table
;R1 pointing to the start of free space
;R2 the number of blocks
STMFD R13!,{R3-R11,R14}
LDR R11,[R12,#v.areastart]
LDR R0,[R11,#h.areasize]
ADD R10,R11,R0 ;scan the blocks
LDR R7,blockid
MOV R5,#0; space counter
MOV R6,R11; header - last valid entry
.loopB
LDR R9,[R10,#-4]!
CMP R9,#0
BEQ loopB
CMP R9,#-1
BEQ scanblocktableend
MOV R6,R10
LDR R0,[R9]
CMP R0,R7
LDMNEFD R13!,{R3-R11,R14}
BNE scanbadblockerr
ADD R5,R5,#1
B loopB
.scanblocktableend
MOV R0,R10
LDR R2,[R6]
LDR R1,[R2,#b.size]
ADD R1,R2,R1
MOV R2,R5
LDMFD R13!,{R3-R11,PC}^
.xfindblockentry
STMFD R13!,{R7-R11,R14}
MOV R8,R0
LDR R11,[R12,#v.areastart]
LDR R10,[R11,#h.areasize]
ADD R10,R11,R10
CMP R8,#&8000
BLT xfindblockno
.loopE
LDR R9,[R10,#-4]!
CMP R9,#0
BEQ loopE
CMP R9,R8
BEQ foundblock
CMP R9,#-1
BEQ notfoundblock
B loopE
.findblockentry
STMFD R13!,{R7-R11,R14}
MOV R8,R0
LDR R11,[R12,#v.areastart]
LDR R10,[R11,#h.areasize]
ADD R10,R11,R10
LDR R7,blockid
CMP R8,#&8000
BLT findblockno
.loopC
LDR R9,[R10,#-4]!
CMP R9,#0
BEQ loopC
CMP R9,R8
BEQ foundblock
CMP R9,#-1
BEQ notfoundblock
LDR R0,[R9]
CMP R0,R7
LDMNEFD R13!,{R7-R11,R14}
BNE scanbadblockerr
B loopC
.foundblock
MOV R0,R10
LDMFD R13!,{R7-R11,PC}
.notfoundblock
MOV R0,R8
LDMFD R13!,{R7-R11,R14}
B notfoundblockerr
.xfindblockno
.loopF
LDR R9,[R10,#-4]!
CMP R9,#-1
BEQ notfoundblock
MOV R0,R9 ;check for amnesia block
MOV R1,R0
SWI OS_ValidateAddress
LDMCSFD R13!,{R7-R11,R14}
BCS areacorrupterr
SUBS R8,R8,#1
BPL loopF
B foundblock
.findblockno
.loopD
LDR R9,[R10,#-4]!
CMP R9,#-1
BEQ notfoundblock
CMP R9,#0
BEQ findblocknoskip
LDR R0,[R9]
CMP R0,R7
LDMNEFD R13!,{R7-R11,R14}
BNE scanbadblockerr
.findblocknoskip
SUBS R8,R8,#1
BPL loopD
B foundblock
.getfreespace
STMFD R13!,{R1-R2,R14}
BL getusedspace
LDMVSFD R13!,{R1-R2,PC}
LDR R1,[R12,#v.areastart]
LDR R1,[R1,#h.areasize]
SUB R0,R1,R0
LDMFD R13!,{R1-R2,PC}
.getavailablespace
STMFD R13!,{R1-R2,R14}
BL getusedspace
LDMVSFD R13!,{R1-R2,PC}
MOV R0,R1
LDMFD R13!,{R1-R2,PC}
.getusedspace
STMFD R13!,{R2-R11,R14}
LDR R11,[R12,#v.areastart]
LDR R0,[R11,#h.areasize]
ADD R10,R11,R0 ;let's count up the blocks
LDR R7,blockid
MOV R5,#0; space counter
MOV R4,R11
MOV R3,R10
.loopA
LDR R9,[R10,#-4]!
CMP R9,#-1
BEQ usedspaceend
MOV R0,R9
MOV R1,R0
SWI OS_ValidateAddress
LDMCSFD R13!,{R2-R11,R14}
BCS areacorrupterr
SUB R3,R3,#4
ADD R5,R5,#4;for block table entries
CMP R9,#0
BEQ loopA
LDR R0,[R9]
CMP R0,R7
LDMNEFD R13!,{R2-R11,R14}
BNE usedbadblockerr
LDR R2,[R9,#b.size]
ADD R5,R5,R2
ADD R4,R9,R2
B loopA
.usedspaceend
MOV R0,R5
SUB R1,R3,R4
LDMFD R13!,{R2-R11,PC}
.discardarea
STMFD R13!,{R0-R11,R14}
LDR R0,[R12,#v.areastart]
CMP R0,#0
LDMEQFD R13!,{R0-R11,PC}
STMFD R13!,{R0-R3}
ADR R0,start
MOV R1,#Service_Amnesia
MOV R2,R12
MOV R3,#0
SWI OS_ServiceCall
LDMFD R13!,{R0-R3}
LDR R0,[R12,#v.areatype]
TST R0,#1<<31
MOV R2,#v.areastart
BLNE releaserma
MOV R0,#0
STR R0,[R12,#v.areastart]
LDMFD R13!,{R0-R11,PC}
.newapplication
STMFD R13!,{R0,R14}
LDR R0,[R12,#v.areatype]
TST R0,#1<<31
BLEQ discardarea
LDMFD R13!,{R0,PC}
.getarearma
STMFD R13!,{R14}
LDR R0,[R12,#v.areatype]
ORR R0,R0,#1<<31 ;flag as 'in RMA'
STR R0,[R12,#v.areatype]
MOV R2,#v.areastart
LDR R3,[R12,#v.areasize]
BL claimrma
LDMFD R13!,{PC}
.setplotofsswi
STR R0,[R12,#v.plotxofs]
STR R1,[R12,#v.plotyofs]
MOV PC,R14
.readplotofsswi
LDR R0,[R12,#v.plotxofs]
LDR R1,[R12,#v.plotyofs]
MOV PC,R14
.defaultpath
DCB "File$Path",0
ALIGN
.loadfileswi
STMFD R13!,{R1-R9,R14}
; R1 = filename
MOV R3,R0; R3 = pointer address as supplied
MOV R4,R2; R4 = pathname
CMP R4,#0
ADREQ R4,defaultpath
MOV R0,#15
STMFD R13!,{R1-R4}
SWI XOS_File
MOV R6,R4; R6 = file length
LDMFD R13!,{R1-R4}
LDMVSFD R13!,{R1-R9,PC}
CMP R0,#1
LDMNEFD R13!,{R2-R10,R14}
MOVNE R2,R0;for error report
BNE notafileerr
STMFD R13!,{R1-R4}
MOV R5,R1
._loop
LDRB R0,[R5]
CMP R0,#32
ADDGT R5,R5,#1
BGT _loop
SUB R2,R5,#8
CMP R2,R1
MOVLT R2,R1
MOV R0,R3
MOV R1,R6
MOV R3,#2
BL claimblockswi
MOV R5,R0; R5 = block address
LDMFD R13!,{R1-R4}
LDMVSFD R13!,{R1-R9,PC}
STMFD R13!,{R1-R5}
MOV R0,#14
MOV R2,R5
MOV R3,#0 ; and R4 as preserved
SWI XOS_File
LDMFD R13!,{R1-R5}
LDMVSFD R13!,{R1-R9,PC}
MOV R0,R5
LDMFD R13!,{R1-R9,PC}^
.savefileswi
STMFD R13!,{R1-R9,R14}
STMFD R13!,{R1-R2}
BL describeblockswi
MOV R4,R2
ADD R5,R2,R3; end address
LDMFD R13!,{R1-R2}
LDMVSFD R13!,{R1-R9,PC}
MOV R0,#10
SWI XOS_File
LDMFD R13!,{R1-R9,PC} ;returns possible error from SWI
.loadhammeredswi
STMFD R13!,{R1-R9,R14}
; R1 = filename
MOV R7,R0; R7 = pointer address as supplied
CMP R2,#0
ADREQ R2,defaultpath
MOV R4,R2; R4 = pathname
MOV R0,#0
SWI XBlitz_HammerOp
LDMVSFD R13!,{R1-R9,PC}
MOV R6,R3
CMP R3,#0
MOVEQ R0,R7
LDMEQFD R13!,{R1-R9,R14}
BEQ loadfileswi
STMFD R13!,{R1-R4}
MOV R5,R1
._loop
LDRB R0,[R5]
CMP R0,#32
ADDGT R5,R5,#1
BGT _loop
SUB R2,R5,#8
CMP R2,R1
MOVLT R2,R1
MOV R0,R7
MOV R1,R6
MOV R3,#2
BL claimblockswi
MOV R8,R0; R8 = block address
LDMFD R13!,{R1-R4}
LDMVSFD R13!,{R1-R9,PC}
MOV R0,#1
MOV R2,R4
MOV R3,R8
SWI XBlitz_HammerOp
LDMVSFD R13!,{R1-R9,PC}
MOV R0,R8
LDMFD R13!,{R1-R9,PC}^
.claimrma
;on entry r2=pointer to block is at r12+r2 block
; r3=requested size
;sets V if error
STMFD R13!,{R0-R4,R14}
MOV R0,#6
MOV R4,R2
SWI XOS_Module
MOVVS R2,#0
STR R2,[R12,R4]
LDMFD R13!,{R0-R4,PC}
.releaserma
STMFD R13!,{R0-R4,R14}
MOV R0,#7
MOV R4,R2
LDR R2,[R12,R2]
SWI XOS_Module
BLVS releaseerr
MOV R2,#0
STR R2,[R12,R4]
LDMFD R13!,{R0-R4,PC}
.releaseerr
STMFD R13!,{R14}
ADD R0,R0,#4
SWI OS_Write0
SWI OS_NewLine
LDMFD R13!,{PC}
.strncpy
STMFD R13!,{R0-R4,R14}
MOV R4,#0
MOV R3,#1; ie not zero
.loop6
CMP R3,#0
LDRNEB R3,[R1],#1
CMP R3,#"'"
BLEQ strnquote
STRB R3,[R0],#1
SUBS R2,R2,#1
BGT loop6
LDMFD R13!,{R0-R4,PC}
.strnquote
CMP R4,#"'"
MOVEQ R3,#0
MOVEQ PC,R14
MOV R4,#"'"
LDRB R3,[R1],#1
CMP R3,#"'"
MOVEQ R3,#0
MOV PC,R14
.service
CMP R1,#&4E
MOVNES PC,R14
STMFD R13!,{R0-R12,R14}
LDR R12,[R12]
BL newapplication
LDMFD R13!,{R0-R12,PC}
.init
STMFD R13!,{R7-R12,R14}
MOV R0,#6
MOV R3,#v.sizeof
SWI XOS_Module
STR R2,[R12]
LDR R12,[R12]
BVS initabort
MOV R0,#0
STR R0,[R12,#v.areastart]
STR R0,[R12,#v.gravx]
STR R0,[R12,#v.gravy]
LDMFD R13!,{R7-R12,PC}
.final
STMFD R13!,{R7-R12,R14}
LDR R12,[R12]
BL discardarea
.initabort
MOV R0,#7
MOV R2,R12
SWI XOS_Module
LDMFD R13!,{R7-R12,PC}^
.badnumber
STMFD R13!,{R0}
._loop
LDRB R0,[R1],#1
CMP R0,#" "
SWIGE OS_WriteC
BLGE _loop
SWI OS_WriteS
DCB 10,13,"!",10,13,0
ALIGN
LDMFD R13!,{R0}
SWI OS_GenerateError
.err
ORR R14,R14,#1<<28
MOVS PC,R14
.unknownswi
ADR R0,unknownswitext
B err
.unknownswitext
DCD &80C901
DCB "Amnesia : Unrecognised SWI",0
ALIGN
.amsnomatcherr
ADR R0,nomatcherrblock
B err
.nomatcherrblock
DCD &80C902
DCB "Amnesia : Unrecognised SWI tail",0
ALIGN
.badblockerr
ADR R0,badblocktext
B err
.badblocktext
DCD &80C903
DCB "Amnesia : Invalid memory block",0
ALIGN
.noroomrmaerr
ADR R0,noroomrmatext
B err
.noroomrmatext
DCD &80C904
DCB "Amnesia : Not enough memory in module area",0
ALIGN
.noroomerr
ADR R0,noroomtext
B err
.noroomtext
DCD &80C905
DCB "Amnesia : Not enough memory in Amnesia area",0
ALIGN
.notiniterr
ADR R0,notinittext
B err
.notinittext
DCD &80C906
DCB "Amnesia : Cannot perform operation - no area initialised",0
ALIGN
.toomanyerr
ADR R0,toomanytext
B err
.toomanytext
DCD &80C907
DCB "Amnesia : *** Aborting - Too many errors",0
ALIGN
.usedbadblockerr
ADR R0,usedbadblocktext
B err
.usedbadblocktext
DCD &80C908
DCB "Amnesia : Bad block detected when calculating used space",0
ALIGN
.scanbadblockerr
MOV R1,R0
ADR R0,scanbadblocktext
B err
.scanbadblocktext
DCD &80C909
DCB "Amnesia : Bad block detected when scanning block table",0
ALIGN
.badptrerr
ADR R0,badptrtext
B err
.badptrtext
DCD &80C90A
DCB "Amnesia : Supplied pointer address is not in valid memory",0
ALIGN
.tlisterr
STMFD R13!,{R14}
ADD R0,R0,#4
MOV R1,#0
MOV R2,#0
SWI OS_PrettyPrint
SWI OS_NewLine
LDMFD R13!,{R14}
ADR R0,tlisterrtext
B err
.tlisterrtext
DCD &80C90B
DCB "Amnesia : Failed to make a table list",0
ALIGN
.errbuf
DCD 0
.getblockerr
STR R0,[R12,#v.errorblock]
ADR R0,getblockerrtext
B err
.getblockerrtext
DCD &80C90C
DCB "Amnesia : Block does not exist",0
ALIGN
.notlisterr
ADR R0,notlisterrtext
B err
.notlisterrtext
DCD &80C90D
DCB "Amnesia : Cannot produce table - no internal table list",0
ALIGN
.tabletoohigherr
STR R0,[R12,#v.errortable]
ADR R0,tabletoohigherrtext
B err
.tabletoohigherrtext
DCD &80C90E
DCB "Amnesia : Table number is too high",0
ALIGN
.notableerr
STR R0,[R12,#v.errortable]
ADR R0,notableerrtext
B err
.notableerrtext
DCD &80C90F
DCB "Amnesia : Reference to table which does not exist",0
ALIGN
.notfoundblockerr
STR R0,[R12,#v.errorblock]
ADR R0,notfoundblockerrtext
B err
.notfoundblockerrtext
DCD &80C910
DCB "Amnesia : Cannot find requested block",0
ALIGN
.areacorrupterr
ADR R0,areacorrupterrtext
B err
.areacorrupterrtext
DCD &80C911
DCB "Amnesia : Area is corrupted. Use *Ams Blocks",0
ALIGN
.badareaerr
STMFD R13!,{R14}
SWI OS_NewLine
LDMFD R13!,{R14}
ADR R0,badareaerrtext
B err
.badareaerrtext
DCD &80C912
DCB "Amnesia : Amnesia area is not consistent with normal operation",0
ALIGN
.movenonblockerr
STR R0,[R12,#v.errorblock]
ADR R0,movenonblockerrtext
B err
.movenonblockerrtext
DCD &80C913
DCB "Amnesia : Attempt to move a bad block",0
ALIGN
.inconblockerr
ADR R0,inconblockerrtext
B err
.inconblockerrtext
DCD &80C914
DCB "Amnesia : Block position and pointer to position do not agree",0
ALIGN
.needspaceerr
ADR R0,needspaceerrtext
B err
.needspaceerrtext
DCD &80C915
DCB "Amnesia : Abbreviated SWI tails with parameters must be followed by a space",0
ALIGN
.objectoutsideerr
STR R0,[R12,#v.errortable]
ADR R0,objectoutsideerrtext
B err
.objectoutsideerrtext
DCD &80C916
DCB "Amnesia : ProcessTable has received an object address outside of the table",0
ALIGN
.windownonerr
ADR R0,windownonerrtext
B err
.windownonerrtext
DCD &80C917
DCB "Amnesia : Bad window number - must be 0-2",0
ALIGN
.windowdodgyerr
ADR R0,windowdodgyerrtext
B err
.windowdodgyerrtext
DCD &80C918
DCB "Amnesia : Bad window - minimum greater than maximum",0
ALIGN
.colchnotableerr
ADR R0,colchnotableerrtext
B err
.colchnotableerrtext
DCD &80C919
DCB "Amnesia : Collision checking not requested when claiming table",0
ALIGN
.colchnoroomerr
ADR R0,colchnoroomerrtext
B err
.colchnoroomerrtext
DCD &80C920
DCB "Amnesia : No room in collision checking block",0
ALIGN
.notafileerr
STMFD R13!,{R14}
MOV R0,#19
SWI XOS_File
LDMFD R13!,{R14}
B err
.fatalerr
ADR R0,fatalerrtext
B err
.fatalerrtext
DCD &80C921
DCB "Amnesia : ***** Internal error ***** - please report any appearance of this error to the author, together with the circumstances in which the error occured.",0
ALIGN
.qwaerr
STR R0,[R12,#v.errorblock]
ADR R0,qwaerrtext
B err
.qwaerrtext
DCD &80C922
DCB "Amnesia : Area tidy would require a forward block shift. Area corrupt?",0
ALIGN
.notyeterr
ADR R0,notyeterrtext
B err
.notyeterrtext
DCD &80C924
DCB "Amnesia : SWI not supported by this version",0
ALIGN
.badsaveerr
ADR R0,badsaveerrtext
B err
.badsaveerrtext
DCD &80C925
DCB "Amnesia : Failed to save",0
ALIGN
.remoteerr
ADR R0,remoteerrtext
B err
.remoteerrtext
DCD &80C926
DCB "Amnesia : Remote routine guard ID not present. The word before the routine must be &006E0000.",0
ALIGN
.namematchwarn
STMFD R13!,{R14}
SWI OS_WriteS
DCB "Amnesia : LoadTable warning - The table name does not match that in the file",10,13,0
ALIGN
LDMFD R13!,{PC}
.objsizewarn
STMFD R13!,{R14}
SWI OS_WriteS
DCB "Amnesia : LoadTable warning - Object length does not match that in the file",10,13,0