GAMEX
game launcher code source with comments
* Starglider Gamex
launcher
* Compatible on all ST(E) , any TOS.
* Here we use special GEMDOS in RAM
* It fixes copmatibility problems, but runs not on 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, little TOS dependent game launcher
* with special GEMDOS in RAM - modded GEMDOS 0.15 of TOS 1.04
* Game : Starglider
* Starglider gamex launcher
* Compatible on all ST(E) because using
* TOS 1.04 GEMDOS part: V.015
* AUTO run without reset of ST !
* running from hard drive
* Game exit to Desktop, pos saving
* 1MB RAM needed...
*Concept:
* Installing GEMDOS 0.15 in high RAM
* leave place for original TOS save
* some 150-180KB (with drivers)
* and fast init it (no floppy boot ...)
*
* in this, first version just depack executable
* and run under GEMDOS 0.15
* Starglider 1 is for specific location !
* 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 * in fact save len
GameRest equ $7FD20
SysStor equ
$FFF80 *Place for storing TOS system - 128 bytes
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
incomp lea incoTM(pc),a0
bra.s toPMex
noENR lea RAMne(pc),a0
bra.s toPMex
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 incomp
cmp.b #4,(a1) *Falcon TOS
vers.
beq.s incomp
* Check Physical RAM
cmp.b #1,7(a1) * Is only
512K ?
beq.s noENR
move.l 4(sp),a2
*basepage adr.
lea $77FE0,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 !
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
* 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
* 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
* Must following in Supervisor mode
clr.l -(sp)
move.w #32,-(sp)
trap #1
addq.l #6,sp
move.l d0,uspstor
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 needs 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 (PAL mode), Timer
C: $C0 !
* Launcher stage 3: storing TOS, desktop, this prg active
part in * Upper RAM for later restore
* First show HW, option select by
need ...
show_hw
bsr clearkb
move.l
#GameScrB,screnb *screen pos. for pic show
pea hwpal(pc)
move.w #6,-(sp)
trap #14
addq.l #6,sp
move.w #37,-(sp)
trap #14
addq.l #2,sp
bsr machipr *HW
detect. 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 * Optional
MSTE settings
beq megastes
cmp.b #"m",d0
beq megastes
bra.s toPicsh
wait_k dbf d7,dell1
toPicsh
steph
bsr photoc *Call Photochrome pic
show rut., on (M)ST(E)
loadg *now set stack pointers in picshow area
lea hwpal(pc),sp
lea -200(sp),a1
move.l a1,usp
lea SysStor,a6
move.l
a1,(a6)+ *Store USP
move.w DeskRes(pc),(a6)+
move.l sp,(a6) *SSP
* Header build support #2 :
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.l #$A000+backingam-gamex,(a2)+
move.w #$C3C2,(a2)+
*Keys
clr.w (a2)+
clr.l (a2)+ *Forced
Timer regs
clr.l (a2)+
move.w
#1,(a2)+ *Flag for COS 1.00 at $C0100
* GXUTIL must install GOS 1.00 when loading saved gamestate !
clr_maininb clr.w (a2)+
cmp.l a2,a1
bne.s clr_maininb
*Clear rest for future good
* Now
set GEMDOS 0.15 variant to loc
$C0100 :
* Must little higher than $C0000 because of PRG header !
* $C0020 not good, must be round by $100 from some reason !!!
* so using $C0100 !
* Usually need new SP to avoid overlap !
lea $77F80,sp
* Yet to add load from common DIR C:\GAMEX ...
* Load it
clr.w -(a7)
pea d15n(pc)
move.w #$3D,-(a7)
trap #1
addq.l #8,a7
move.w d0,d7
bmi exitu
d15loc equ $C0100
* Loading packed:
pea hwpal+8(pc)
pea 68000 *len ++
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
* Depack :
lea d15loc-28,a4 *28
bytes lover due header
lea hwpal+40(pc),a1
bsr depak3
* Relocate, here no basepage !
lea d15loc-28,a3
move.l 2(A3),A0
add.l 6(A3),A0
add.l 14(A3),A0
*symbol tabl len
lea 28(A0),A0 *by
header length
add.l A3,A0
* No data segement here
lea 28(a3),a1 *text begin
move.l a1,d0
move.l a0,a2 * reloc table begin
tst.l (A0)
beq.s corrbp2
add.l (A0)+,A1
clr.l d1
relol2 add.l D0,(A1)
bigd2
MOVE.B (A0)+,D1
beq.s corrbp2
CMP.B #1,D1
bne.s nmd2
lea $FE(A1),A1
BRA.S bigd2
nmd2 ADDA.L D1,A1
BRA.S relol2
corrbp2
* GEMDOS 0.15 now ready
* called GOS from now - Gemdos or Gaming OS .
* this is with GOS 1.00 - no disk support - for games not
loading/saving
* Saving area from adr 8 to
hwpal in high RAM
* that's enough for successful return to Desktop by exit
DeskCopy equ $D7008 *
167000 bytes available
* 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 512KB games, 1MB 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
* Now load game
clr.w -(a7)
pea exen(pc)
move.w #$3D,-(a7)
trap #1
addq.l #8,a7
move.w d0,d7
bmi exitu
gamela equ $30E00
pea gamela
pea 290006 * Packed
len, singleparted
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
* Must move up:
lea $77B80,a4
move.l a4,a3 *save adr.
lea coup(pc),a1
moveq #116,d2 *whole mc len/4-1
mouc move.l (a1)+,(a4)+
dbf d2,mouc
jmp (a3)
exitu clr.w -(sp)
trap #1
game_dest equ $AA56 *
For Starglider 1
* address fixed in fact !
* so reloc is unnecessary
coup
move #$2700,sr
lea game_dest,a4
*depack here ...
lea gamela+32,a1
bsr depak3
* Anti-load patch:
move.l #$60000080,$DD54
*skips TRA file loads and building ...
* Setting some informations for game starting:
procee
move.l
#game_dest,$5F0.w * Write start address for 0.15
clr.w
$5F4.w *Flag that user mode start needed
* Inject game exit activation :
* To pos $A000
* Warning ! Area up to OS_end will be cleared ( adr $61C2 ! )
lea gamex(pc),a1
lea $A000,a2
moveq #100,d2
.gac move.l (a1)+,(a2)+
dbf d2,.gac
* Link to :
lea $B694,a2 * ingame
IKBD receive code
move.w #$4EF9,(a2)+
move.l #$A000,(a2)
* Must clear RAM above - game specific !
move.w #7904,d2
.clr clr.l (a4)+
dbf d2,.clr
* Now jump in 0.15 start:
jmp d15loc * This will run game after setting GEMDOS
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
exen dc.b "SG1W.FIC",0 *
Packed game, whole with title pic
d15n dc.b "D15R_NG1.FIC",0 * Packed
GEMDOS, GOS 1.00
even
*uspstor dc.l 0
*Game exit code: *
gamex cmp.b
#$C3,d0 * For F9
beq.s gamex_w
backingam
gamnoex cmp.w #$F8,d0
bpl.s toB6CE
jmp
$B69A * 6 bytes after game exit inj. pos.
toB6CE jmp $B6CE
gamex_w *Exiting game with storing state
* Code for game state store when exit
is requested:
GameStat equ $A180 *Set
for particular game always
GameStoPl equ
$A000 *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 joy status, 8 bytes
* 80 SR, 2 bytes
* 84 PSG status, 14 bytes
* 100 IKBD mouse status, 8 bytes
* 108 Next thing worth to
store :-)
ikbdof equ 70
ikbdm_of equ 100
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)+ * Res.
Usually 0
move.l sp,(a6)+ *SSP
* 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
* Trying with longer test: worked not
move.w #6777,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 !!!!
* If needed !
* Above will be present in savegames too always !!!
jmp FreeMem
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...
uspstor dc.l 0
GamexCtrl
*Code for controlling game exit ....
* and return to Ddesktop
* Must be PC relative !!
RamSwap *This swaps 2 RAM halves
* Areas are 8-$7FD00
and $80008 - $FFD00
* If game uses RAM $7FD00-$7FFFF we need some
* space to store that 768 bytes ..... problem ???
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
* Swapping only used Sys area, after it just copy left game area
* to top RAM !!!
* no need for swap, in fact .....
* First copy game up, then TOS down, then rest of game up
* 256KB max at once
ramswp lea 8.w,a5
lea $80008,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 $BFFF8,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
* Here deal with MFP....
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
* Here need IKBD mode test and store too !!!!!
* Now save IKBD status (mode set)
* Requesting mouse vertical mode:
* by other games it may be different !!!
* Prepare fetching code:
lea GameStat+ikbdof+AltRamPos,a4
*GameStap lea
0,a4 *will be prepared
lea ikbstoc+2(pc),a2
move.l a4,(a2)
* Need to receive status packet:
move.l ikbdsysv(pc),a1
lea my_ikbds(pc),a2
move.l a2,(a1)
* Now for Mouse button eml. state:
* Prepare fetching code:
* lea GameStat+ikbdm_of+AltRamPos,a4
*GameStap2 lea
0,a4 *will be prepared
* lea ikbstoc+2(pc),a2
* move.l a4,(a2)
pea mousta(pc)
move.w #0,-(sp) *1 byte only to
send
move.w #25,-(sp)
trap #14
addq.l #8,sp
*Some delay * Or solve with counting receives....
move.l #6984,d1
.del2 subq.l #1,d1
bne.s .del2
cmp.b #$00,1(a4) * Normal value
bne.s go_mor3
clr.b (a4)
go_mor3
* 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
* 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
*joysta dc.b
$90,0
mousta dc.b $87,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
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
* 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 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)+
*If TOS is 4, skip next tests...
cmp.b #4,d0
beq.s isfalc
cmp.b #3,d0
beq.s 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)
*Detecting machine HW - is STE, MSTE ?
*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)
* 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 *TOS V
Major, TOS v minor, RAM size, HW
* MSTE clock at start, MSTE clock set... Lang
code
istt move.b #5,(a2) *HW code
rts
* Not Falcon compatible !
isfalc move.b #4,(a2) *HW code
rts
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: key F9",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
incoTM dc.b 13,10,"Only ST or STE ! But
any TOS.",0
even
* Adding Mega STE 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
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
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
screnb ds.l 1
picfn dc.b "STARGL.PCH",0
even
* Not Falcon compatible dude !!!!
* falcpic
* include "PCHTOF3.S"
photoc
include "PHOTUS.S"
section data
section bss
head ds.b 6 *PCH header here...
stbitm ds.b 32000
stpal ds.b $4B20
stbm2 ds.b 32000
stpal2 ds.b $4B20
convtbl ds.b 8192