home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
misc
/
akf52_2
/
AKF52
/
AKF52_A_s
(
.txt
)
< prev
next >
Wrap
RISC OS BBC BASIC V Source
|
1995-11-28
|
19KB
|
427 lines
>AKF52_A_s
$+" / "+
*** You can edit these constants if you need to: ***
But best leave alone if you're unsure!
vsn$="1.10"
*** Leave these constants alone or it'll all go pear shaped :-)
VFlag%=1<<28
code% 163840
p%=4
P%=0:O%=code%
[OPT p%
.moduleheader
I.startcode EQUD 0 \ We are a service module only
N.initcode EQUD initialise \ claims workspace, maybe loads map
>.finalisecode EQUD finalise \ not much actually
B.servicehandler EQUD service \ test for mode changes
,.titleofset EQUD titlestring \
,.helpofset EQUD helpstring \
?.tableofset EQUD commtable \ table of *commands
<.swichunk EQUD 0 \swichunk% \ my SWI chunk
>.swihandlerofset EQUD 0 \swihandler \ my SWI handler
B.swidectabofset EQUD 0 \swidecodetable \ and decoding table
M.swidecodeofset EQUD 0 \swidecodecode \ doesn't (need to) do anything
..titlestring EQUS "AKF52":EQUB 0:ALIGN
H.helpstring EQUS "AKF52":EQUB 9:EQUB 9:EQUS vsn$+" ("+
$,5,11)
8 EQUS ")
Musus Umbra":EQUB 0:ALIGN
.commtable
"Kequs "mrep":dcb 0:align:equd mrep:equd &20000:equd mrep_is:equd mrep_he
#Kequs "rmap":dcb 0:align:equd rmap:equd &00000:equd rmap_is:equd rmap_he
$Kequs "reps":dcb 0:align:equd reps:equd &00000:equd reps_is:equd reps_he
equd 0 \ terminator
\ .swidecodetable
\ EQUS "AKF52":EQUB 0
\ equs "Status":dcb 0
\ equs "ShowMap":dcb 0
\ equs "ReadMap":dcb 0
\ equs "WriteMap":dcb 0
\ equd 0
\ALIGN
\.swidecodecode
\MOVS PC,R14
46\.swihandler \ code taken straigt from the PRM!
5/\CMP R11,#(EndOfJumpTable-JumpTable)/4
\ADDLO PC,PC,R11,LSL#2
\B unknownswierror
\.JumpTable
\B status_entry
\b rmap
\b readmap_entry
\b writemap_entry
\.EndOfJumpTable
\.unknownswierror
\ADR R0,errtoken
\MOV R1,#0
\MOV R2,#0
\ADR R4,titlestring
D)\SWI "XMessageTrans_ErrorLookup"
RS PC,R14,#VFlag%
\.errtoken
G(\EQUD &1E6:EQUS "BadSWI":EQUB0:ALIGN
.initialise
STMFD R13!,{R7-R11,R14}
K2LDR R2,[R12] \ get !private word
LBCMP R2,#0 \ is this a re-init? (after RMTidy)
MCLDMneFD R13!,{R7-R11,R14} \ if so then we've got nothing to do
N(MOVnes PC,R14 \ so exit
P=MOV R0,#6 \ OS_Module6 = Claim workspace
QRMOV R3,#256 \ We want 256 bytes (1 byte per mode) + scrap space
R0SWI "XOS_Module" \ claim workspace
SQbvs initover \ if it didn't work then we'd best just die now...
THSTR R2,[R12] \ store workspace pointer in private word
UKbl copydeftab \ if not a reinit then install default table
VK.initover \ initialisation done (either failed or not)
W-LDMfD R13!,{R7-R11,R14} \ restore regs
X6mov pc,r14 \ exit (with any error)
.finalise
[CMOV PC,R14 \ goodbye cruel module area, shniff.
\P \ I know it's unnecesary, but I used to have some
]J \ code here, and might do again, one day...
a,\\ The command help/syntax message text:
cN.mrep_he equs "The Mrep command allows you to specify whether the AKF52 "
dN equs "module should replace the default RISC OS modes with its "
eQ equs "larger ones for a specific mode. Its main use is to disable "
fO equs "the replacement of a screen mode that a game fails to use "
gK equs "properly. If no parameters are given then the current "
hL equs "screen mode and its 'replaced' status is displayed. If "
iS equs "you specify a mode but omit the On/Off, the 'replaced' status "
jO equs "of the mode will be displayed. If you use the full syntax "
kO equs "the mode's 'replaced' status will be changed. Use 'On' to "
lK equs "mark the mode as replaced and 'Off' to use the normal "
m2 equs "RISC OS mode.":equb 10:equb 13
nB.mrep_is equs "Syntax: *Mrep [ <mode> [On|Off] ]":dcb 0:align
pS.rmap_he equs "The Rmap command displays a table showing which RISC OS modes "
qS equs "are marked to be replaced by the 'enhanced' modes provided by "
r0 equs "the module.":equb 10:equb 13
s..rmap_is equs "Syntax: *Rmap":dcb 0:align
uP.reps_he equs "The Reps command lists all the avlaiable replacement modes."
equb 10:equb 13
w..reps_is equs "Syntax: *Reps":dcb 0:align
equd 0
{ ALIGN
}B\\ The service handler; just listens for modeextension service
~C\\ and replaces the RISCOS mode only if the mode table says so.
4.service \ The backbone!
=teq r1,#&50 \ is it a modeextension?
DmovNE pc,r14 \ pass call on ASAP (was movne)
7ldr r12,[r12] \ get private word
1stmfd r13!,{r0-r2,r14} \ store regs
(cmp r2,#0 \ \
Cldmltfd r13!,{r0-r2,pc}^ \ \ don't attempt lookup for
Acmp r2,#64 \ / modes outide our range
(ldmgefd r13!,{r0-r2,pc}^ \ /
Eldrb r1,[r12,r2] \ get byte corresponding to mode
0cmp r1,#0 \ if 0 then
Lldmeqfd r13!,{r0-r2,pc}^ \ pass call on (mode is unreplaced).
/bl getptrsformode \ get ptrs
cmp r1,#&50
Ildmeqfd r13!,{r0-r2,pc}^ \ pass call on (mode is unreplaced).
ldmfd r13!,{r0-r2,r14}
mov r1,#0
Emov pc,r14 \ claim call (mode is replaced).
N\\ Display the mode table. The table is formatted to that the mode numbers
G\\ are right aligned in fields 4 chars wide. Also, the width of the
Q\\ screen is examined so that we can make sure that no column splits over two
P\\ lines. Neat kludge- widths greater than 80 are rounded down to 80 so that
3\\ the output still looks good in a taskwindow.
0.rmap \ SWI & command
0stmfd r13!,{r0-r5,r14} \ preserve regs
4ldr r12,[r12] \ get workspace ptr
Emov r1,#1 \ text cols Mode Variable = number 1
<sub r0,r1,#2 \ -1 (ie. current mode)
$swi "XOS_ReadModeVariable"
=cmp r2,#79 \ is is >80 (var is cols-1)
Tmovge r2,#79 \ clamp to 80 col mode (makes taskwindow O/P nicer)
9mov r5,r2,lsr#2 \ modes entries per line
?mov r0,#32 \ store the padding spaces now
-strb r0,[r12,#128] \ dum de dum
0strb r0,[r12,#129] \ doodedumdedah
*strb r0,[r12,#130] \ hmmhmmm
1swi "XOS_WriteS" \ display header
Kequs "The following modes are marked for replacement:":dcb 0:align
"swi "XOS_NewLine" \
;mov r4,#0 \ start checking at mode 0
8mov r3,#0 \ 0th mode on this line
.showloop
3ldrb r1,[r12,r4] \ get flag for mode
.cmp r1,#0 \ is it clear?
=beq notshow \ if so then don't preent eet
4mov r0,r4 \ r0=the mode number
3add r1,r12,#131 \ address of buffer
Pmov r2,#100 \ size of buffer (overkill, but hey, who cares?)
@swi "XOS_ConvertInteger1" \ Convert LSB of r0 to text
@sub r2,r1,r0 \ get length of string resulting
Srsb r2,r2,#4 \ calculate how many spaces are needed to format it
-add r0,r12,#131 \ ptr->buffer
;sub r0,r0,r2 \ ptr->start of padded text
5swi "XOS_Write0" \ display mode number
Qadd r3,r3,#1 \ increment the 'modes printed this line' counter
Icmp r3,r5 \ have we hit the edge of the screen yet?
=movgt r3,#0 \ if so then start a new line
Qswigt "XOS_NewLine" \ with the 'modes printed this line' counter at 0
Q.notshow \ right, either we've printed the mode, or didn't
Hadd r4,r4,#1 \ either way, increment the mode counter
Ccmp r4,#64 \ have we hit the end of the table?
7blt showloop \ if not then loop back
@cmp r3,#0 \ did we finish on a blank line?
Kswine "XOS_NewLine" \ if not then print a newline to compensate
0swi "XOS_WriteS" \ display footer
Gequs "All other modes use standard RISC OS modes.":dcb 0:align
swi "XOS_NewLine"
.ldmfd r13!,{r0-r5,r14} \ restore regs
&mov pc,r14 \ exit
L\\ Okay, the *Mrep command (by far and away the most complex bit of the
\\ module)
.mrep
3stmfd r13!,{r1-r4,r14} \ Store regs
Ncmp r1,#0 \ is this an info request? (ie. 0 args)
8beq showcurrmode \ if so handle it
Kcmp r1,#2 \ or a *mode <n> on|off (ie. 1 arg)
Kbeq configmode \ if not then handle the full syntax
9mov r1,r0 \ r1->command tail
Pmov r2,#63 \ max value we'll accept as the first arg
Bmov r0,#10 \ default base of fisrt arg
Lorr r0,r0,#(1<<29
1<<31) \ must be in range 0..r2 & terminated
?swi "XOS_ReadUnsigned" \ convert arg to a number
@ldmvsfd r13!,{r1-r4,r14} \ exit with error if V set
@orrvss pc,r14,#1<<28 \ ------------------------
'swi "XOS_WriteS" \
'equs "Mode: ":dcb 0:align \
:mov r0,r2 \ r0=the mode number
mov r4,r2
3ldr r12,[r12] \ get ->wkspc
9add r1,r12,#131 \ address of buffer
Amov r2,#100 \ size of buffer (overkill)
Aswi "XOS_ConvertInteger1" \ Convert LSB of r0 to text
.swi "XOS_Write0" \ output
5ldrb r1,[r12,r4] \ get mode flag
8cmp r1,#0 \ replaced or not?
'beq unreplaced \
'swi "XOS_WriteS" \
*equs " marked for replacement."
dcb 0:align
'swi "XOS_NewLine" \
0ldmfd r13!,{r1-r4,r14} \ and exit
'mov pc,r14 \
.unreplaced
'swi "XOS_WriteS" \
*equs " marked as RISC OS mode."
dcb 0:align
'swi "XOS_NewLine" \
0ldmfd r13!,{r1-r4,r14} \ and exit
'mov pc,r14 \
<.showcurrmode \ display current mode
3mov r0,#135 \ OS_Byte 135
>swi "XOS_Byte" \ read screen mode in R2
>swi "XOS_WriteS" \ display message header
3equs "Current screen mode: ":dcb 0:align
9ldr r12,[r12] \ get workspace ptr
Radd r1,r12,#132 \ r1->buffer (after mode table in workspace)
-mov r0,r2 \ mode#
<ldrb r3,[r12,r2] \ get flag (for later)
Dmov r2,#100 \ buffer size (majot overkill)
=swi "XOS_ConvertInteger1" \ convert mode# to text
2swi "XOS_Write0" \ write text
Qswi "XOS_NewLine" \ do you really *need* this line commented?
Hswi "XOS_WriteS" \ think of my poor aching fingers!
#equs "Marked status: "
dcb 0:align
Hcmp r3,#0 \ is the mode marked as 'enhanced'
Eadreq r0,unrepmess \ if not, use the 'off' message
Fadrne r0,repmess \ otherwise use the 'on' message
7swi "XOS_Write0" \ display message
Nswi "XOS_NewLine" \ and 5...2...4...3...1...Oh No!...-pop-
Ildmfd r13!,{r1-r4,r14} \ Damm. Slip, dammit Freudian SLIP.
,mov pc,r14 \ exit
2.unrepmess equs "standard RISC OS mode.":dcb 0
>.repmess equs "replaced by 'enhanced' mode.":dcb 0:align
!\\ SWI to update the mode map
J.writemap_entry \ Set flag for 'mode R0' to '(bool) R1'
ldr r12,[r12]
cmp r0,#64
bge badmodee
cmp r0,#0
blt badmodee
stmfd r13!,{r1}
cmp r1,#0
movne r1,#255
strb r1,[r12,r0]
ldmfd r13!,{r1}
mov pc,r14
.badmodee
adr r0,badmodeeblk
orrs pc,r14,#1<<28
.badmodeeblk
-equd 0:equs "Bad mode number":dcb 0:align
"G.readmap_entry \ Return flag for mode R0 in R1 (r0 preserved)
ldr r12,[r12]
cmp r0,#64
bge badmodee
cmp r0,#0
blt badmodee
ldrb r1,[r12,r0]
mov pc,r14
\\ Return replacement state
.status_entry
./mov pc,r14 \ and exit
0/\\ Aha! at last! The *Mrep <n> On|Off bit!
.configmode
3M\ at this point, r1-4,r14 are stacked, r0->command tail, r12=private word
48ldr r12,[r12] \ get workspace ptr
57mov r1,r0 \ r1->command tail
60mov r2,#63 \ max value
76mov r0,#10 \ default base 10
8Eorr r0,r0,#(1<<31
1<<29) \ space/ctrl terminated
95swi "XOS_ReadUnsigned" \ convert number
:?ldmvsfd r13!,{r1-r4,r14} \ exit with error if V set
;?orrvss pc,r14,#1<<28 \ ------------------------
<E\ Okay, so now r2 holds the mode number and r1->terminating space
=@.findnextarg \ now find the next argument...
>&ldrb r0,[r1],#1 \ ...
?Gcmp r0,#32 \ by skip spaces until next char found
@&beq findnextarg \ ...
A+orr r0,r0,#32 \ Mung Ho!
BQcmp r0,#
"o" \ Test for On|off just like in the VME entry above
bne mbadarg
D/ldrb r0,[r1],#1 \ get 2nd char
E"cmp r0,#32 \
ble mbadarg
orr r0,r0,#32
H$cmp r0,#
"n" \ On?
beq mteston
J%cmp r0,#
"f" \ Off?
beq mtestoff
.mbadarg
ldmfd r13!,{r1-r4,r14}
adr r0,msyntaxmess
O/orrs pc,r14,#1<<28 \ Return error
.msyntaxmess
Q7dcd 0:equs "Syntax: Mode [<number> [On|Off]]":dcb 0
R align
.mbadrep
ldmfd r13!,{r1-r4,r14}
adr r0,mrepmess
W/orrs pc,r14,#1<<28 \ Return error
.mrepmess
YCdcd 0:equs "No replacement available for that mode":dcb 0:align
.mteston
\6ldrb r0,[r1],#1 \ test for terminator
cmp r0,#32
bgt mbadarg
_Q\ at this point, we know that 'on' was the argument. the mode number is in r2
`:\ so we can check if we can actally replace that mode.
bl getptrsformode
cmp r1,#0
bne mbadrep
mov r1,#255
e:.meupscotty \ very crap pun coming up
f<strb r1,[r12,r2] \ update mode flag in table
gAmov r3,r2 \ take a copy of the mode number
h/ldmfd r13!,{r1-r4,r14} \ restore regs
i+mov pc,r14 \ and exit
.mtestoff
k0ldrb r0,[r1],#1 \ get next char
orr r0,r0,#32
m cmp r0,#
"f" \
n"bne mbadarg \
o6ldrb r0,[r1],#1 \ test for terminator
cmp r0,#32
bgt mbadarg
mov r1,#0
sRb meupscotty \ certainly sir, will a 2x4 do? (I did warn you)
u6.prurm equs " (replacement not used).":dcb 0:align
v4.prrm equs " (replacement in use).":dcb 0:align
x>\\ Copy the default mode table into the current mode table
y8.copydeftab \ On entry, R2->workspace
zIadr r3,defaulttable \ get pointer to default table (hardcoded)
{Gmov r5,#128 \ maximum number of entries in the table
|Nmov r6,#0 \ well, um, zero. Also flag for unenhanced mode
.cleartable
~Kstr r6,[r2,r5] \ blank word in table (starts R5 entries in)
2subs r5,r5,#4 \ working backwards
Gbge cleartable \ until we've run out of table to blank!
Tmov r5,#255 \ this is the byte we'll write for an 'enhanced' mode
.cdt_loop
8ldrb r4,[r3],#1 \ get next mode from list
/cmp r4,#128 \ is top bit set
?movge pc,r14 \ if so then we're done so exit.
Estrb r5,[r2,r4] \ otherwise set mode flag in the table
/b cdt_loop \ and loop back.
.reps
#stmfd r13!,{r0-r2,r5,r6,r14}
adr r5,modedata
ldr r12,[r12]
add r1,r12,#132
swi "XOS_WriteS"
0equs "Replacements available for modes:"
dcb 0:align
swi "XOS_NewLine"
.prloop
*ldr r6,[r5],#176 \ writeback
7cmn r6,#1 \ -1 terminates the list
#ldmeqfd r13!,{r0-r2,r5,r6,pc}^
cmp r6,#63
#ldmgtfd r13!,{r0-r2,r5,r6,pc}^
'mov r0,r6 \ number
%cmp r0,#10 \ <10?
.swilt 256+32 \ padding space
swi 256+32
swi 256+32
,mov r2,#100 \ buffer size
-swi "XOS_ConvertInteger1" \ LSB only
,swi "XOS_Write0" \ display
-ldrb r6,[r12,r6] \ get flag
0cmp r6,#0 \ unreplaced?
swine 256+42
swi "XOS_NewLine"
b prloop
D.getptrsformode \ on entry, r2=mode number to look up
stmfd r13!,{r3-r6,r14}
adr r5,modedata
.searchloop
*ldr r6,[r5],#176 \ writeback
7cmn r6,#1 \ -1 terminates the list
/moveq r1,#&50 \ not found flag
ldmeqfd r13!,{r3-r6,pc}^
and r6,r6,#&ff
Dcmp r6,r2 \ is this the mode we're looking for?
6bne searchloop \ if not then try again
mov r1,r5
ldmfd r13!,{r3-r6,r14}
,sub r3,r1,#&ac \ get -> data
,add r4,r3,#&40 \ get -> data
0mov r1,#0 \ mode found flag
movs pc,r14
*\\ Start of
table flag - DO
OVE!
EQUB 255
H.defaulttable \ list of mode numbers, terminated by 128
equb 0
equb 12
equb 18
equb 19
equb 20
equb 21
equb 128 \
align
.modedata
("ModeData"):
A=0
0,"Can't find 'ModeData'.":
"OS_File",255,"ModeData",O%,0:O%+=(E+4)
"OS_File",10,"akf52",&FFA,,code%,O%
0,"Code size = "+
~(modedata-moduleheader)+" bytes."
H3(A%):=
"000"+
~A%,3)