GAMEX
game launcher code source with comments
* Sideways Gamex/normal
play launcher
* Compatible on all ST(E) , Falcon ....
* Atari ST gaming system GAMEX
* Features: it needs min 1MB RAM for games working with 512KB
normally
* Game may be exited to Desktop. In that case gamestate is preserved in
area 512KB-1MB
* User may after exit to Desktop to continue playing or to save
gamestate on disk
* This will be open source
* Created by Pera Putnik, May 2009.
* Example of
Single part, TOS independent game
* Game : Sideways
* Sideways is originally with Exec and 10 data files,
* but I made it singleparted + packed ...
* Launcher stage 1: reserving TOP RAM - lovering memtop, phystop
* Values for this game:
GameScrB equ
$78000 *For games working with 512KB
AltRamPos equ $80000
MainInb equ $FFF40
SwapLen equ $7FCF8
GameRest equ $7FD20
GameJmp equ $14D5C *
for this game
begin *Beginning of program
* Adding low RAM usage check and
exit if too much is used...
lea hwpal(pc),a1
cmp.l
#FreeMem-DeskCopy-48,a1 *Place available to store TOS
bcs.s lowRamOK
lea lowRamTM(pc),a0
toPMex bsr pmess
move.w #1,-(sp)
trap #1
addq.l #2,sp
clr.w -(sp)
trap #1 *Exit
lowRamOK
NewPhyst equ $80000 *For
512K games
* First test HW, if only 512KB phys. then skip whole Gamex stuff
pea hwdet(pc)
move.w #38,-(sp)
trap #14
addq.l #6,sp
lea machin(pc),a1
cmp.b #3,(a1) *TT TOS vers.
beq.s low_sp
cmp.b #4,(a1) *Falcon TOS
vers.
beq.s low_sp
* Check Physical RAM
cmp.b #1,7(a1) * Is only
512K ?
sne gxf * Set
Gamex flag if over 512KB ( = min 1MB )
low_sp
move.l 4(sp),a2
*basepage adr.
lea $77F00,sp
clr.l (sp)
move.l a2,4(sp)
get_bp
move.b
#1,machin+2 * 'Set' TOS RAM size
move.l a2,basep
move.l 4(a2),d2 *memtop
move.l d2,memt
move.l #NewPhyst,d1
sub.l #$8000,d1 *This
is new memtop
move.l
d1,4(a2) * Correct in basepage
* Conditional settings in subrutine following :
pea lowmsuv(pc)
move.w #38,-(sp)
trap #14
addq.l #6,sp
* Now TOP RAM is reserved, TOS sees only 512KB of RAM !
* Launcher stage 2: storing stack pointers, MFP, screen
stage2
* Get current screen resolution:
move.w #4,-(sp)
trap #14
addq.l #2,sp
* Falcon patch:
cmp.w #3,d0 *Allow
only 0-2 !
bcs.s store_res
clr.w d0
store_res move.w d0,DeskRes
dc.w
$A00A * Hide mouse
clr.w -(sp) *set low
res
pea GameScrB
pea GameScrB
move.w #5,-(sp)
trap #14
lea 12(sp),sp
clr.l -(sp)
move.w #32,-(sp)
trap #1
addq.l #6,sp
move.l d0,uspstor
tst.b gxf
beq show_hw
stage22
* SysSto layout :
* relative pos, what
* 0 USP
* 4 Desktop screen
resolution at prg start !
* 6 SSP
* 10 Palette, 32 bytes
* 42 MFP state, 24 bytes
* 66 ?
mfpof equ 42
SysStor equ
$FFF80 *Place for storing TOS system - 128 bytes
lea SysStor+10,a6
*palette store pos
.
* Save desktop palette:
lea $FFFF8240.w,a1
moveq #15,d1
.palc move.w (a1)+,(a6)+
dbf d1,.palc
* Saving MFP state.....
* Save MFP registers :
lea $FFFFFA01.w,a1
moveq #23,d2 *24
registers, up to $FFFA2F
.mfpsl move.b (a1),(a6)+
addq.l #2,a1
dbf d2,.mfpsl
*Timer B and C need accurate reading:
* Other 2 is off in TOS....
*So we read them some time and take
*Max value:
* To speed it up we can test both in same time !
lea $FFFFFA21.w,a1
lea $FFFFFA23.w,a2
move.w #3777,d7
*Determines time for read
clr.b d2
clr.b d4
retimbl move.b (a1),d1
cmp.b d1,d2
bcc.s renotbb
rebiggerb move.b d1,d2
renotbb move.b (a2),d3
cmp.b d3,d4
bcc.s renotbc
rebiggerc move.b d3,d4
renotbc dbf d7,retimbl
move.b d2,-8(a6)
* Timer B Data reg
move.b d4,-7(a6)
* Timer C Data reg.
* TOS values are normally: Timer B: $41, Timer C: $C0
!
* Preparing some IKBD storage:
move.w #34,-(sp)
*Kbdvbase
trap #14
addq.l
#2,sp
move.l d0,a1
lea
32(a1),a1 * IKBD system vector
move.l a1,ikbdsysv
move.l (a1),orgikbds
show_hw
bsr clearkb
pea swpal(pc)
move.w #6,-(sp)
trap #14
addq.l #6,sp
move.w #37,-(sp)
trap #14
addq.l #2,sp
bsr machipr *HW
detected print
*Little pause to see it:
move.w #1177,d7
dell1 move.w #37,-(sp)
trap #14
addq.l #2,sp
* Allow abort with keypress:
pea $600ff
trap #1
addq.l #4,sp
tst.b d0
beq.s wait_k
cmp.b #"M",d0
beq megastes * Opt
MSTE or Falcon settings
cmp.b #"m",d0
beq megastes
bra.s toPicsh
wait_k dbf d7,dell1
toPicsh * No cover pic for this unreleased game
clr.w -(a7)
pea packn(pc)
move.w #$3D,-(a7)
trap #1
addq.l #8,a7
move.w d0,d7
pea $68000 *
Loading game ...
pea 41524
* Total len of packed complete game
move.w d7,-(a7)
move.w #$3F,-(a7)
trap #1
lea 12(sp),sp
move.w d7,-(a7)
move.w #$3E,-(a7)
trap #1
addq.l #4,a7
*now set stack pointers in picshow area
lea hwpal(pc),sp
lea -200(sp),a1
move.l a1,usp
tst.b gxf
beq lau_2
lea SysStor,a6
move.l
a1,(a6)+ *Store USP
move.w DeskRes(pc),(a6)+
move.l sp,(a6) *SSP
* Launcher stage 3: storing lower 512KB in area
$80008 - $FFD00
* Header build support #2 : filling MainInb
lea MainInb,a2
lea 64(a2),a1
move.l #SwapLen,(a2)+
move.l
#FreeMem,(a2)+
move.l #SysStor,(a2)+
move.l #GameRest,(a2)+
move.l #GameStat,(a2)+
move.l #GameJmp,(a2)+
* move.w #$C3C2,(a2)+
*Keys
* move.w #$1200,(a2)+ *
Disable mouse
* clr.l (a2)+ *Forced
Timer regs
* move.l #DeskCopy,(a2)+
* clr.l (a2)+
* move.w
#1,(a2)+ *Flag for COS 1.00 at $C0100
* pos 38, Falcon cache setting, byte...
clr_maininb clr.w (a2)+
cmp.l a2,a1
bne.s clr_maininb
*Clear rest for future good
* Needs Falcon Cache setting store too
lea MainInb+38,a2
move.w falccach(pc),(a2)
* Saving area from adr 8 to
hwpal in high RAM
DeskCopy equ $C0108 *
* what must be enough for TOS 2.06 with hard ddriver, buffers
lea 8.w,a5
lea DeskCopy,a6 * We
have enough place...
lea hwpal(pc),a1
move.l a1,d0
divu
#48,d0 *get loop count
move.w
d0,swapln+2 *Set same len for TOS restore *swap part
.cod movem.l
(a5)+,d1-d7/a0-a4 *48 bytes at once
movem.l
d1-d7/a0-a4,(a6)
lea 48(a6),a6
dbf d0,.cod
* Little overshot, no problems...
* Stage 4: preparing setting Exit to Desktop in stored
mem. :
* We need only regular exit TOS call at certain point...
* Copy code in free area $FFD00 - $FFFFF
FreeMem equ
$FFD20 *For 1M games, 2MB total RAM
lea GamexCtrl(pc),a1
lea FreeMem,a2
move.w
#127,d2 *There is 768 bytes place !
* But top is reserved for storing state, palette etc....
* so copying only 512 bytes ....
.cou move.l (a1)+,(a2)+
dbf d2,.cou
lau_2 * Game launch, step 2
pea intrt(pc) * Some
info for game before run
move.w #9,-(sp)
trap #1
addq.l #6,sp
move.w #1,-(sp)
trap #1
addq.l #2,sp
moveq #27,d7
dell11 move.w #37,-(sp)
trap #14
addq.l #2,sp
dbf d7,dell11
lea $68000,sp
lea coup(pc),a2 * Moving
up...
lea $67600,a3
move.l a3,a1
moveq #126,d2
coul move.l (a2)+,(a3)+
dbf d2,coul
jmp (a1)
coup lea $68020,a1
lea $144C0,a4
bsr depak3
clr.l
-(sp) * Back to user mode
move.w #32,-(sp)
trap #1
addq.l #6,sp
* Copy panel to it's place:
* it's not in one block with other datas
lea $144C0+$23B40,a1
lea $75AA0,a2
move.w #2199,d2
.cop move.l (a1)+,(a2)+
dbf d2,.cop
* Prevent load attempts: - due to singleparting
move.w #$4E75,$187EA
* Skip screen and palette setting in game :
* Otherwise Falcon palette error !
move.w #$601C,$1450E
* Need to find good place in game where can abort it and
* doing state storing, then ramswap and exit to Desktop....
lea $14F86,a1 * Here will
replace org. Game exit code...
lea gxf(pc),a2
tst.b (a2)
beq.s runit5
move.w #$4EF9,(a1)+
move.l #GameStoPl,(a1)
*storing code here
* Copy code to place:
lea GameStoPl,a2
lea GameSto(pc),a1
move.w #127,d2
.cop2 move.l (a1)+,(a2)+
dbf d2,.cop2
bra.s runit
runit5 * Reset if no Gamex (on 512KB machines) when
press escape...
move.w #$2278,(a1)+ * Jump
to TOS start - reset
move.l #$00044ED1,(a1)
runit jmp $144C0 * Run game
gxf dc.b 1,0
uspstor dc.l 0
swpal
* Game's palette here:
dc.w 0,$777,0,0,0,23,$333,$510
dc.w 0,$45,$555,$630,0,$67,$777,$750
packn dc.b "S123.FIC",0
even
* Code for game state store when exit
is requested:
* By Sideways it can be little under $144C0 for instance...
GameStat equ $14000
*Set for particular game always
GameStoPl equ
$14100 *Where to place code for gamestate save
GameSto * The code itself. Must be PC relative !!!
* Presumable we are in supervisor mode....
* For games not running in SV need some switch, workaround...
* will see later....
* 0 USP
* 4 Cur screen resolution -
almost always 0 !
* 6 SSP
* 10 Palette, 32 bytes
* 42 MFP state, 24 bytes
* 66 Screen base
* 70 IKBD status, 8 bytes
* 80 SR, 2 bytes
* 84 PSG status, 14 bytes
* 100 ???
ikbdof equ 70
srofs equ 80
psgofs equ 84
* Store CPU regs, SR, stack pointers
movem.l d0-d7/a0-a6,-(sp)
lea GameStat,a6
move.w sr,80(a6)
move.l usp,a1
move.l
a1,(a6)+ *Store USP
move.b $FFFF8260.w,d1
and.w #$3,d1
move.w d1,(a6)+ *
Usually 0
move.l sp,(a6)+
* Saving PSG state:
lea $FFFF8800.w,a1
lea GameStat+psgofs,a2
moveq #0,d2
.psgl move.b d2,(a1)
move.b (a1),(a2)+
addq.b #1,d2
cmp.b #14,d2
bne.s .psgl
* Save palette:
lea $FFFF8240.w,a1
moveq #15,d1
.palc move.w (a1)+,(a6)+
dbf d1,.palc
* Saving MFP state.....
* Save MFP registers :
lea $FFFFFA01.w,a1
moveq #23,d2 *24
registers, up to $FFFA2F
.mfpsl move.b (a1),(a6)+
addq.l #2,a1
dbf d2,.mfpsl
*Timer A, C and D need accurate reading:
* we presume that timer B is intact (for now)
*So we read them some time and take
*Max value:
* To speed it up we can test all 3 in same time !
lea $FFFFFA1F.w,a1
*Timer A data
lea $FFFFFA23.w,a2
*Timer C data
lea $FFFFFA25.w,a3
*Timer D data
move.w #4777,d7
*Determines time for read
clr.b d2
clr.b d4
clr.b d6
gatimbl move.b (a1),d1
cmp.b d1,d2
bcc.s ganotba
move.b d1,d2
ganotba move.b (a2),d3
cmp.b d3,d4
bcc.s ganotbc
move.b d3,d4
ganotbc move.b (a3),d5
cmp.b d5,d6
bcc.s ganotbd
move.b d5,d6
ganotbd
dbf d7,gatimbl
move.b d2,-9(a6)
* Timer A Data reg
move.b d4,-7(a6)
* Timer C Data reg.
move.b d6,-6(a6)
* Timer D Data reg.
* Screen Base:
move.b
$FFFF8201.w,(a6)+ * High byte
move.b
$FFFF8203.w,(a6)+ * Mid byte
* IKBD status will store after setting
TOS workable - in restoring it....
* so, may jump to TOS restore:
* Clear abort flag in game !!!!
clr.b
$1477B *Game specific
* Above will be present in savegames too always !!!
jmp FreeMem
depak3 clr.l d0
moveq #6,d4
moveq #$3f,d5 *for masking bits 5-0
* Bit meaning: 7 - if set it's back referrer , if 0 then bits
* 6-0 give count of literals to copy
* if all bits are 0 it is terminator
* When bit 7 set, bit 6: if 1 then long distance back given by 2
following byte
* bit 6: when 0 then short distance given by following 1
byte
* bits 5-0 count of bytes referred.
* By short refer. 0 means 3, 1 means 4, etc up to 66 .
* By long refer. 0 means 4, 1 means 5, etc up to 67 .
main3 clr.w d0 *prep for dbf
move.b (a1)+,d0
bmi.s back3
beq.s nom3 *end
subq.w #1,d0 *compens dbf
litc move.b (a1)+,(a4)+
dbf d0,litc
bra.s main3
nom3 rts
back3 move.b d0,d2
and.w d5,d2 *d5=$3f
* Test is long or short referrer:
btst d4,d0 *test bit 6
bne.s longr
addq.w #2,d2 *compens
displl move.b (a1)+,d0 * displac
calcadr move.l a4,a2
sub.l d0,a2
baksl move.b (a2)+,(a4)+
dbf d2,baksl
bra.s main3
longr addq.w #3,d2 *compens
move.b (a1)+,d0 * displac
lsl.w #8,d0 *MSB
bra.s displl
* End of C3 depak
* Following will set TOS RAM like we
have only 512KB machine !
lowmsuv *Supervisor mode needed for set some
sysvars...
move.l
$42E.w,d5 *Old Phystop
move.l #NewPhyst,$42E.w
* See is Memtop sysvar $8000 bytes below Phystop :
* By Falcon is usually $7E00 bytes below
move.l $436.w,d3
move.l d5,d4
sub.l d3,d4
move.l #$8000,d3
sub.l d4,d3 *
add diff
sub.l
#NewPhyst,d5 *Get diff.
sub.l d5,$436.w
*Correct Memtop sysvar
sub.l d3,$436.w
* By Falcon if....
* Get os_end :
move.l $4F2.w,a1
move.l
12(a1),a1 *seek until this addr
lea
$800,a2 *from here seek
* Seek basepage value, followed by free RAM for... :
move.l basep(pc),d1
move.l memt(pc),d2
sub.l d1,d2 *free RAM
for
bvseekl cmp.l (a2),d1
bne.s bvseendt
* if found test freeram value matching :
cmp.l 4(a2),d2
beq.s bvgotit
bvseendt addq.l #2,a2
cmp.l a2,a1
bgt.s bvseekl
bvgotit * decrease free RAM value by diff. :
sub.l d5,4(a2)
* Dirty hack, but works !
* By stoopid Falcon it is $200 bytes higher !!!!
* cmp.b #4,machin+3
* bne.s corr_2
sub.l d3,4(a2)
corr_2
* If no RAM for GX skip Signature writing :
tst.b gxf
beq.s fin_lowm
* Header build support #1:
move.l $42E.w,a2
move.l #"PPGX",(a2)+
move.l #MainInb,(a2)
fin_lowm rts
DeskRes dc.w 0
basep dc.l 0
memt dc.l
$78000 *preset for case...
GamexCtrl
*Code for controlling game exit ....
* Must be PC relative !!
RamSwap *This swaps 2 RAM halves
move.w #$2700,sr
* MFP restoring flow:
* disable all MFP interrups
* allow little time that CPU finish
* Clear IE registers
clr.b $FFFFFA07.w
clr.b $FFFFFA09.w
* Clear Pending regs
clr.b $FFFFFA0B.w
clr.b $FFFFFA0D.w
*Clear in Service regs :
clr.b $FFFFFA0F.w
clr.b $FFFFFA11.w
*Some little delay
* Until find not better solution ... ?
move.l #3984,d1
.del subq.l #1,d1
bne.s .del
ramswp lea 8.w,a5
lea AltRamPos+8,a6
move.w
#5460,d0
ramswl
movem.l
(a5)+,d1-d7/a0-a4 *48 bytes at once
movem.l
d1-d7/a0-a4,(a6)
lea 48(a6),a6
*48 bytes in one cycle
tst.b d0
bne.s ramsw_loop
*Little fade/flash :
move.w $FFFF8240.w,d1
addq.w #1,d1
cmp.w #$0FFF,d1
bcs.s .colup
clr.w d1
.colup move.w d1,$FFFF8240.w
ramsw_loop dbf d0,ramswl
* game up to $3FFF8 copied
lea 8.w,a6
lea DeskCopy,a5
swapln move.w #0,d0
.cod2 movem.l
(a5)+,d1-d7/a0-a4 *48 bytes at once
movem.l
d1-d7/a0-a4,(a6)
lea 48(a6),a6
dbf d0,.cod2
* Now only copy remaining of game in high RAM
lea $3FFF8,a5 *src
lea
AltRamPos+$3FFF8,a6 *dest
move.w
#5445,d0 *for rest, to $7FD00 !
.cou movem.l
(a5)+,d1-d7/a0-a4 *48 bytes at once
movem.l
d1-d7/a0-a4,(a6)
lea 48(a6),a6
dbf d0,.cou
* May be little overshot, so set locations min 24 bytes over !
* Now need to restore stack pointers, screen, MFP, PSG ....
* relative pos, what in
SysStor
* 0 USP
* 4 Desktop screen
resolution at prg start !
* 6 SSP
* 10 Palette, 32 bytes
* 42 MFP state....
lea SysStor,a1
move.l (a1)+,a4
move.l a4,usp
move.w (a1)+,d7
*Resolution
move.l (a1)+,sp
*Set palette pointer Sysvar:
move.l a1,$45A.w
*Colorptr - will set palette in first Vblank
* Restore MFP regs ....
lea $FFFFFA01.w,a1
lea SysStor+mfpof,a2
moveq #23,d2 *24
registers
mfprl move.b (a2)+,(a1)
addq.l #2,a1
dbf d2,mfprl
move.w #$2300,sr
*Signal and silencing possible tone
lea forvs(pc),a6
lea $ffff8800.w,a0
moveq #0,d0
sounl move.b d0,(a0)
move.b (a6)+,2(a0)
addq.b #1,d0
cmp.b #14,d0
blt.s sounl
* Flush IKBD ACIA buffer - may be blocked
aciafl btst
#0,$FFFFFC00.w
beq.s aciaempt
tst.b $FFFFFC02.w
bra.s aciafl
aciaempt
* Now save IKBD status (mode set)
* Requesting joystick mode:
* by other games it may be different !!!
* Prepare fetching code:
lea GameStat+ikbdof+AltRamPos,a4
lea ikbstoc+2(pc),a2
move.l a4,(a2)
pea joysta(pc)
move.w #0,-(sp) *1 byte only to
send
move.w #25,-(sp)
trap #14
addq.l #8,sp
* Need to receive status packet:
move.l ikbdsysv(pc),a1
lea my_ikbds(pc),a2
move.l a2,(a1)
*Some delay * Or solve with counting receives....
move.l #6984,d1
.del subq.l #1,d1
bne.s .del
* Back org ikbdsys vector:
move.l ikbdsysv(pc),a1
lea orgikbds(pc),a2
move.l (a2),(a1)
pea ikbdres(pc) *Back
regular IKBD mode
move.w #1,-(sp)
move.w #25,-(sp)
trap #14
addq.l #8,sp
* Set screen
move.w d7,-(sp)
pea GameScrB
pea GameScrB
move.w #5,-(sp)
trap #14
lea 12(sp),sp
* Write for sure :
lea NewPhyst,a2
move.l #"PPGX",(a2)+
move.l #MainInb,(a2)
ToDesktop clr.w -(sp)
trap #1 *Regular exit - back to Desktop
* Reading 8-byte packet from IKBD:
my_ikbds
* btst #0,$FFFFFC00.w
* beq.s ikbdpac
movem.l a3-a4,-(sp)
tst.b $FFFFFC00.w
ikbstoc lea
0,a4 *****
lea ikbstoc+2(pc),a3
move.b $FFFFFC02.w,(a4)+
move.l a4,(a3)
movem.l (sp)+,a3-a4
rts *Not rte !
* It was last part of saving gamestate !
ikbdsysv dc.l 0
orgikbds dc.l 0
ikbdres dc.b $80,1,0,0
joysta dc.b $94,0
even
forvs *Sound pattern, simple
dc.b 66,2
dc.b 125,2,80,2
dc.b 1 *Noise perlen -here not used
dc.b %11111000 *Mixer control
dc.b 16,16,16
dc.b 0,22,0
* Detecting HW, RAM. Called right
after start
hwdet
*Check TOS version - may be not built inm, but running in RAM !
move.l $4F2.w,d1
* clr.b
d1 *on round address always
move.l d1,a1
move.b 2(a1),d0 *TOS
ver major
move.b 3(a1),d1 *TOS
ver minor
* Following is necessary to correct if run in low RAM
* in area below launcher
* otherwise Trap #1 will write in code !!!!
* move.l $28(a1),gemdap *
Actual GEMDOS proc.
* Writing TOS version for later outprint
lea machin(pc),a2
move.b d0,(a2)+ *TOS V
move.b d1,(a2)+ *TOS v
move.b 29(a1),4(a2) *Lang
code
* 'Detecting' TOS RAM size, just by $42E
move.l $42E,d2
swap d2
lsr.w #3,d2 *shift so
that 512KB will be 1
move.b d2,(a2)+
*Detecting machine HW - is STE, MSTE ?
*If TOS is 4, skip next tests...
cmp.b #4,d0
beq isfalc
cmp.b #3,d0
beq istt
* Physical RAM size by MemCTRL sysvar, or by Chip read ...
clr.l d3
*Instead orgphystop look MMU control register shadow $424
move.b $424.w,d3
move.l d3,d2
and.b
#1,d2
move.l d3,d1
and.b
#4,d1
lsr.b
#2,d1
add.b
d1,d2 *512K multiplier - 1 or 2 or 0
move.l
d3,d4
and.b
#2,d4
move.l d3,d1
and.b
#8,d1
lsr.b
#2,d1
add.b
d1,d4 *2M mult. 2 or 4 or 0
lsr.b #1,d4 *now 1 or 2
clr.l d3
tst.b d2
beq.s seem2
move.l #$40000,d3 *256KB
lsl.l d2,d3 *mult by 2 or
4
seem2 clr.l d2
tst.b d4
beq.s keepms
move.l #$100000,d2 *1MB
lsl.l d4,d2
add.l d2,d3
keepms swap d3
lsr.w #3,d3 *shift so
that 512KB will be 1
move.b d3,4(a2)
*Is MSTE ?
move.l sp,a3
lea buser1(pc),a1
move.l 8.w,backorb-buser1+2(a1)
move.l a1,8.w
move.b $FFFF8E21.w,d1
* read from HW reg
*Will do bus error if not Mega STE
move.b #3,(a2)+ *Code for
MSTE
* d1 - bit 0 = cache on/off , bit 1 (?) =
8/16MHz
* btst #1,d1
* sne (a2)
move.b #$FC,$FFFF8E21.w *Set 8 MHz
* After this may set 16MHz by need, or even back to 8...
* addq.l #1,a2
* move.b #$FF,$FFFF8E21.w
* st (a2)
bra.s backorb
buser1 lea buser2(pc),a1
move.l a1,8.w
tst.b $FFFF8924.w *Microwire
for STE detect
move.b #2,(a2) *Code for STE
bra.s restosp
buser2 move.b #1,(a2)
restosp move.l a3,sp
backorb move.l
#0,8.w *here comes original buserror vector
rts
machin dc.b 0,0,0,0,0,0,0,0,0,0
*TOS V Major, TOS v minor, RAM size, HW
* MSTE clock at start, MSTE clock set,
Lang code, Real RAM size
istt move.b #5,(a2) *HW code
rts
isfalc move.b #4,(a2) *HW code
*PMMU moving
newpos equ $3FE000
lea
pmmuop(pc),a1
move.b #0,(a1)
clr.l d0
movec cacr,d0
move.w #$20A,d0
movec d0,cacr
lea $700.w,a0
lea newpos,a1
move.w #$100,d0
pmmml move.b (a0)+,(a1)+
dbf d0,pmmml
lea pmmuop+2(pc),a0
pmove.d crp,(a0)
move.l #newpos,4(a0)
pmove.d (a0),crp
lea pmmuop+10(pc),a1
move.l #$FF8707,(a1)
pmove.l (a1),tt0
move.w #$809,d7 *
Instr cache on, data off
movec d7,cacr
move.w d7,d2
and.w #1,d2
lsr.w #7,d7
and.w #2,d7
or.w d7,d2
lea falccach(pc),a1
move.b d2,(a1)+
move.b #$CF,(a1) *
Validity flag !
* and.b #%11011111,$FFFF8007.w
or.b
#%00000001,$FFFF8007.w * CPU 16MHz, Blitter irrelevant
rts
pmmuop ds.b 32
falccach dc.w 0
machipr *Outprints machine parameters
lea hwpos(pc),a0
bsr pmess
lea mait(pc),a0
bsr pmess
lea machin+3(pc),a1
cmp.b #1,(a1)
bne.s isstem
lea hwst(pc),a0
bra.s hwoup
isstem cmp.b #2,(a1)
bne.s ismstem
lea hwste(pc),a0
bra.s hwoup
ismstem cmp.b #3,(a1)
bne.s isfalcm
lea hwmste(pc),a0
bsr pmess
*Outprint CPU clock too if MSTE:
lea machin+4(pc),a1
tst.b (a1)
bne.s sho16 *if begin clock
16 then print 16 only
addq.l #1,a1
tst.b (a1)
beq.s sho8 *if begin and end
is 8 show 8 only
* Show 8>16
lea hwm816m(pc),a0
bra.s hwoup
sho16 lea hwm16m(pc),a0
bra.s hwoup
sho8 lea hwm8m(pc),a0
bra.s hwoup
isfalcm cmp.b #4,(a1)
bne.s seetv
lea hwfalc(pc),a0
hwoup bsr pmess
seetv *TOS version outprint
lea tosvit(pc),a0
bsr pmess
lea tosvp+1(pc),a2
lea machin(pc),a1
move.b (a1)+,d0 *Major
add.b #"0",d0
move.b d0,(a2)
move.b (a1),d1 *Minor
cmp.b #$62,d1 *is TOS 1.62 ?
beq.s t162s
add.b #"0",d1
moveq #"0",d0
bra.s tosvpri
t162s moveq #"6",d0
moveq #"2",d1
tosvpri addq.l #2,a2
move.b d0,(a2)+
move.b d1,(a2)
lea tosvp(pc),a0
bsr pmess
*TOS RAM size outprint
lea ramit(pc),a0
bsr pmess
lea machin+2(pc),a1
cmp.b #1,(a1)
bne.s not512
lea rams512(pc),a0
bra.s ramsoup
not512 *needs some calc...
moveq #0,d1
move.b (a1),d1
lsr.b #1,d1
scs d6 *Flag for half MB at
end
lea ramsiu+1(pc),a1 *Some aligning...
tst.b d6
beq.s bratoa
lea ramsiu(pc),a1
bratoa bsr toasc
tst.b d6
beq.s ramsta
move.b #".",(a1)+
move.b #"5",(a1)
ramsta lea ramsiu(pc),a0
ramsoup bsr.s pmess
* ST RAM size outprint
lea machin+3(pc),a1
cmp.b #5,(a1)
beq.s end_hwpr
cmp.b #4,(a1)
beq.s end_hwpr
lea ramst(pc),a0
bsr pmess
lea machin+7(pc),a1
cmp.b #1,(a1)
bne.s not512rs
lea
rams512(pc),a0
bra.s ramsouprs
not512rs *needs some calc...
moveq #0,d1
move.b (a1),d1
lsr.b #1,d1
scs d6 *Flag for half MB at
end
lea
ramsiu+1(pc),a1 *Some aligning...
tst.b d6
beq.s bratoars
lea ramsiu(pc),a1
bratoars bsr toasc
tst.b d6
beq.s ramstars
move.b #".",(a1)+
move.b #"5",(a1)
ramstars lea ramsiu(pc),a0
ramsouprs bsr.s pmess
end_hwpr
lea noGXp(pc),a0
tst.b gxf
beq.s skip_gxki
lea gamext(pc),a0
skip_gxki bsr pmess
rts
pmess pea (a0)
move.w #9,-(sp)
trap #1
addq.l #6,sp
rts
toasc *cover values from 1 to 14
divu #10,d1
move.b d1,d2
swap d1
add.b #"0",d2 *10s of MB
cmp.b #"0",d2
bne.s putdig1
move.b #" ",d2
putdig1 move.b d2,(a1)+
add.b #"0",d1 *1s of MB
move.b d1,(a1)+
rts
hwst dc.b " ST",0
hwste dc.b " STE",0
hwmste dc.b "Mega STE",0
hwfalc dc.b " Falcon",0
hwm8m dc.b 13,10," 8 MHz",0
hwm16m dc.b 13,10," 16 MHz",0
hwm816m dc.b 13,10,"8>16 MHz",0
tosvp dc.b " 1.00",0
rams512 dc.b " 512 KB",0 * ,27,"H",0
ramsiu dc.b " MB",0
hwpos dc.b 27,"E",27,"Y",48,32,0
homec dc.b 27,"H",0 *Cursor back to top left
* Info texts:
mait dc.b "Machine: ",0
ramit dc.b 13,10,"TOS RAM:",0
ramst dc.b ", ST RAM:",0
tosvit dc.b 13,10,"TOS ver: ",0
gamext dc.b 13,10,13,10,"GAMEX: Escape",27,"H",0
lowRamTM dc.b 13,10,"Too much low RAM occupied !",0
*RAMne dc.b 13,10,"Min RAM: 1MB !",0
noGXp dc.b 13,10,13,10,"For Gamex min 1MB RAM
!",27,"H",0
even
hwpal *Palette with white 0 and all other as blue
*because of medres/lowres switch bug
dc.w $666,$116,$116,$116,$116,$116,$116,$116
dc.w $116,$116,$116,$116,$116,$116,$116,$116
* Adding Mega STE and Falcon machine settings as option :
megastes *see machine
lea machin+3(pc),a2
cmp.b #3,(a2)
beq.s itsMSTE
cmp.b #4,(a2)
beq itsFalc
bra show_hw
itsMSTE
* Mega STE
* Only setting 8/16MHz, together with cache off/on
bsr
clearkb * Clear ikbd buffer for sure
lea mstest(pc),a0
bsr pmess
tst.b machin+5 * Clock
?
bne.s its16m1
lea mste8mt(pc),a0 *
Change txt on screen
bsr pmess
clr.b mstetems
its16m1 move.w #7,-(sp)
trap #1
addq.l #2,sp
cmp.b #"1",d0
beq.s msteset8
cmp.b #"2",d0
beq.s msteset16
cmp.b #" ",d0
beq.s msteexit
cmp.b #13,d0
beq.s mstesetexit
bra.s its16m1
msteset8 lea
mste8mt(pc),a0 * Change txt on screen
bsr pmess
moveq #0,d1
mstecls move.b
d1,mstetems
bra.s its16m1
msteset16 lea
mste16mt(pc),a0 * Change txt on screen
bsr pmess
st d1
bra.s mstecls
mstesetexit * We are in supervisor mode
move.b #$FC,d1
tst.b mstetems
beq.s set8caoff
move.b #$FF,d1
set8caoff move.b
d1,$FFFF8E21.w
addq.b #1,d1
seq machin+5
msteexit bra
show_hw
mstetems dc.b
255,0 *Must preset to on !
mstest dc.b
27,"E"," Mega STE CPU clock setting",13,10
dc.b 13,10,"Press: 1 for 8
MHz, 2 for 16 MHz",13,10
dc.b "Enter for set and
exit",13,10
dc.b "Space exits without change",13,10
dc.b 13,10,13,10,"CPU clock: 16 MHz",0
mste8mt dc.b 27,"Y",39,43,"
8",0
mste16mt dc.b 27,"Y",39,43,"16",0
even
itsFalc * Set bus - CPU, Blitter clock, STE emul.,
CPU instr and Data cache
bsr
clearkb * Clear ikbd buffer for sure
lea falconst(pc),a0
bsr pmess
* Falcon bus settings:
* FF8007 Bit 0 = CPU clock, Bit 2 = Blitter
clock, Bit 5 = STE bus emul when = 0 !
move.b $FFFF8007.w,d7
btst #0,d7
bne.s fas1
lea falcc8mt(pc),a0 *
Change txt on screen
bsr pmess
clr.b falset1
fas1 btst #2,d7
bne.s fas2
lea falcb8mt(pc),a0 *
Change txt on screen
bsr pmess
clr.b falset1+1
fas2 btst #5,d7
bne.s fas3
lea falcsten(pc),a0 *
Change txt on screen
bsr pmess
clr.b falset1+2
fas3 move.b falccach(pc),d7
btst #0,d7
*Instr cache
bne.s fas4
lea falcincf(pc),a0 *
Change txt on screen
bsr pmess
clr.b falset1+3
fas4 btst #1,d7
*Data cache
bne.s fas5
lea falcdcf(pc),a0 *
Change txt on screen
bsr pmess
clr.b falset1+4
fas5
move.w #7,-(sp)
trap #1
addq.l #2,sp
cmp.b #"1",d0
beq.s falsetc8
cmp.b #"2",d0
beq.s falsetc16
cmp.b #"3",d0
beq.s falsetb8
cmp.b #"4",d0
beq.s falsetb16
cmp.b #"5",d0
beq falsetsteoff
cmp.b #"6",d0
beq falsetsteon
cmp.b #"7",d0
beq falsetinof
cmp.b #"8",d0
beq falsetinon
cmp.b #"9",d0
beq falsetdaof
cmp.b #"0",d0
beq falsetdaon
cmp.b #" ",d0
beq msteexit
*same exit
cmp.b #13,d0
beq falsetexit
bra.s fas5
falsetc8 lea
falcc8mt(pc),a0 * Change txt on screen
bsr pmess
moveq #0,d1
fal1cls move.b
d1,falset1
bra.s fas5
falsetc16 lea
falcc16mt(pc),a0 * Change txt on screen
bsr pmess
st d1
bra.s fal1cls
falsetb8 lea
falcb8mt(pc),a0 * Change txt on screen
bsr pmess
moveq #0,d1
fal1bls move.b
d1,falset1+1
bra fas5
falsetb16 lea
falcb16mt(pc),a0 * Change txt on screen
bsr pmess
st d1
bra.s fal1bls
falsetsteoff lea
falcstef(pc),a0 * Change txt on screen
bsr pmess
st
d1 * When set, then is off !!!
fal1ste move.b
d1,falset1+2
bra fas5
falsetsteon lea
falcsten(pc),a0 * Change txt on screen
bsr pmess
moveq #0,d1
bra.s fal1ste
falsetinof lea
falcincf(pc),a0 * Change txt on screen
bsr pmess
moveq #0,d1
fal1inc move.b
d1,falset1+3
bra fas5
falsetinon lea
falcincn(pc),a0 * Change txt on screen
bsr pmess
st d1
bra.s fal1inc
falsetdaof lea
falcdcf(pc),a0 * Change txt on screen
bsr pmess
moveq #0,d1
fal1dac move.b
d1,falset1+4
bra fas5
falsetdaon lea
falcdcn(pc),a0 * Change txt on screen
bsr pmess
st d1
bra.s fal1dac
falsetexit *activate changes :
lea falset1(pc),a3
moveq #0,d3
moveq #0,d4
tst.b (a3) * CPU clock
beq.s fnot1
bset #0,d3
fnot1 addq.l #1,a3
tst.b (a3) * Blitter
clock
beq.s fnot2
bset #2,d3
fnot2 addq.l #1,a3
tst.b (a3) * STE bus
emul
beq.s fnot3
bset #5,d3
fnot3 addq.l #1,a3
tst.b (a3) * Instr.
cache
beq.s fnot4
bset #0,d4
fnot4 addq.l #1,a3
tst.b (a3) * Data cache
beq.s fnot5
bset #1,d4
fnot5 * Now set HW regs :
move.b $FFFF8007.w,d2
and.b #%11011010,d2 *
Mask required bits
or.b d3,d2
move.b d2,$FFFF8007.w
* move.b d3,$FFFF8007.w
move.b d4,falccach
move.b d4,d3
and.w #1,d3
lsl.w #7,d4
and.w #$0100,d4
or.w d3,d4
or.w #$0808,d4 * Clear
order prepare
movec d4,cacr
bra show_hw
falconst dc.b
27,"E"," Falcon bus and cache settings",13,10
dc.b 13,10,"Press: 1 for 8 MHz, 2 for 16 MHz
CPU",13,10
dc.b " 3 for 8
MHz, 4 for 16 MHz Blitter",13,10
dc.b " 5 for not
STE, 6 for STE bus",13,10
dc.b " 7 for
instr. cache off, 8 for on",13,10
dc.b " 9 for
data cache off, 0 for on",13,10
dc.b "Enter for set and
exit",13,10
dc.b "Space exits without change",13,10
dc.b 13,10,13,10,"CPU
clock: 16 MHz"
dc.b 13,10,"Blitter clock: 16 MHz"
dc.b 13,10,"STE
bus: off"
dc.b 13,10,"Instr. cache: on"
dc.b 13,10,"Data
cache: on",0
falcc8mt dc.b 27,"Y",43,47,"
8",0
falcc16mt dc.b 27,"Y",43,47,"16",0
falcb8mt dc.b 27,"Y",44,47,"
8",0
falcb16mt dc.b 27,"Y",44,47,"16",0
falcstef dc.b
27,"Y",45,47,"off",0
falcsten dc.b 27,"Y",45,47," on",0
falcincf dc.b
27,"Y",46,47,"off",0
falcincn dc.b 27,"Y",46,47," on",0
falcdcf dc.b
27,"Y",47,47,"off",0
falcdcn dc.b 27,"Y",47,47," on",0
even
falset1 dc.b 255,255,255,255,255,0
clearkb pea $10002
*Keyboard, Bconstat
trap #13
addq.l #4,sp
tst.b d0
beq.s nocha
pea $20002 *Keyboard,
Bconin
trap #13
addq.l #4,sp
bra.s clearkb
nocha rts
intrt dc.b 27,"H"
dc.b "--------------------------------------------",13,10
dc.b "Sideways - By Jamie Woodhouse",13,10
dc.b "--------------------------------------------",13,10
dc.b "Game prototype developed in 1989-1990",13,10,13,10
dc.b "Basic Instructions:",13,10,13,10
dc.b "Move about and press fire to shoot",13,10
dc.b "crystals, turrets and aliens.",13,10
dc.b "Shield goes down if you get hit by",13,10
dc.b "aliens on bullets.",13,10
dc.b "Energy goes down over time, shoot",13,10
dc.b "crystals (on floor) to restore energy.",13,10
dc.b "Shoot a full wave of aliens (8) and",13,10
dc.b "then collect a bonus item left behind.",13,10
dc.b "-----------------------------------------------",13,10