GXUTIL source with comments


*GUI Atari ST program GAMEX

* By P. Putnik, at April 2009.

* AES program for saving permanently gamestates
* and  loading them later and playing



* Every gamestate is complete game, RAM, machine settings
* In header are all necessary parameters for restoring
* state as it was in moment of abort (exit to Desktop)
* All it requires digging and some changes in games !

* Additional files may be: GOS (GEMDOS in RAM)
* content of floppies as disk images or RamDisk


* Header len is 256 bytes



* Doing some changes at devel  V12 -
* As no need to save whole 512KB for TOS restoring
* from now will save only  up to  this util bss end (where
* stack must be ! )

* Correcting  RAM allocation code. Adding
* more HW detection, some tests....

* Adding show of basepage address of this run
* to see how much low RAM is occupied !

* Displayed version is now 0.6
* This is devel version 20 - name GXUT20

* Adding GOS 1.04  support
* It requires some rearranging,
* direct HW access instead TOS calls



*First RSC object indices

; resource set indices for GAMEX
;
MAIND    equ 0 ; form/dialog
TIT1     equ 1 ; BOXTEXT in MAIND
TIT2     equ 2 ; BOXTEXT in MAIND
VERSINF  equ 3 ; STRING in MAIND
TIT3     equ 4 ; BOXTEXT in MAIND
BUSAVC   equ 5 ; BUTTON in MAIND
BUENTNOT equ 6 ; BUTTON in MAIND
BUPLAYS  equ 7 ; BUTTON in MAIND
BUSHOWI  equ 8 ; BUTTON in MAIND
BUPLAYR  equ 9 ; BUTTON in MAIND
BUEXIT   equ 10 ; BUTTON in MAIND
LOWRU    equ 11 ; TEXT in MAIND

ENTERDIA equ 1 ; form/dialog
TITS1    equ 1 ; STRING in ENTERDIA
EDB1     equ 2 ; FBOXTEXT in ENTERDIA
EDB2     equ 3 ; FBOXTEXT in ENTERDIA
EDBGXK   equ 4 ; FTEXT in ENTERDIA
BUCANC   equ 5 ; BUTTON in ENTERDIA
BUENTR   equ 6 ; BUTTON in ENTERDIA

SHOWDIA  equ 2 ; form/dialog
TIT4     equ 1 ; STRING in SHOWDIA
INF1     equ 2 ; STRING in SHOWDIA
INF2     equ 3 ; STRING in SHOWDIA
NOTT     equ 4 ; STRING in SHOWDIA
INFNOT1  equ 5 ; BOXTEXT in SHOWDIA
INFNOT2  equ 6 ; BOXTEXT in SHOWDIA
GXKEYI   equ 7 ; STRING in SHOWDIA
BUINFEX  equ 8 ; BUTTON in SHOWDIA







* Header entries for keeping track on what TOS, HW is snapshot made:
* at pos 128


* First textual mode entries for easy reading :

* 128   Machine     8 bytes  longest entry:  Mega STE
* 136   TOS V    8 bytes again    TOS 2.06
* 144   TOS lang     4 bytes                ITA,0   
* 148    HWdet        10         Binary machine description
* 158    reserved
* 174    Gamex key string  ASCII  10  bytes - User fillable
*  184   Note  ASCII  64 bytes  - User fillable
*  248    reserved   8  bytes
*  256  End

headp_mcha   equ  128
headp_tosv    equ   136
headp_tosl    equ    144
headp_hwd   equ    148

headp_gamx   equ  174
headp_note    equ   184







  include gemdmacr.s
  include aes2macr.s     *Devpac3




progbeg

* Preparations :

    move.l    4(sp),a4

* Mshrink needed because of Fileselector !

     lea         fin-progbeg+256,a1 *len of program and bss
     pea          (a1)
     add.l       (a4),a1
     move.l     a1,memtop     * This will be after Mshrink !
     move.l     (a4),-(sp)  *TPA begin
     move.w    #0,-(sp)
     move.w    #74,-(sp)
     trap #1                    *Mshrink is not good for TOP RAM allocation - solved !
     lea        12(sp),sp

     move.l    4(sp),a4   *Basepage addr.
 
* Set stack in own space
     lea         stack+560,sp
     clr.l        (sp)
     move.l    a4,4(sp)   *


usualGameScrB    equ    $78000   * By 512K games




aplinit
    appl_init

*Coordinate conversion-needed by integrated RSC
coordc
    moveq #0,d0

obfloop
    move.w d0,obfia
    move.w d0,-(sp)

    rsrc_obfix
obfia  dc.w 0
    dc.l form1  *begin adress of objects

    move.w (sp)+,d0
    addq.b #1,d0
    cmp.b #rsc_obnum,d0 *
    bne.s obfloop


 *Calling some supervisor test at start :
* As HW, TOS detection....
    pea supv(pc)
    move.w #38,-(sp)
    trap #14
    addq.l #6,sp

  

***********
* Setting current DIR for fileselector:

  *Get aktuell drive
    move.w #25,-(sp)
    trap #1
    addq.l #2,sp

    lea path(pc),a2 
    add.b #"A",d0
    move.b d0,(a2)


* Add current DIR too ...

    clr.w         -(sp)   * Actuel drive
    pea     pathbuf(pc)
    move.w     #71,-(sp)
    trap     #1
    addq.l    #8,sp

* Put actual DIR in path:

     lea    pathbuf+1(pc),a1
    lea    path+3(pc),a2
    tst.b    (a1)    * Are we in ROOT ?
    bne.s    set_l77
    subq.l    #1,a2    * Prevent double backslash
    bra.s    dirtop_end

set_l77    moveq    #77,d2    *limiter
dirtop_l     tst.b    (a1)
    beq.s    dirtop_end
    move.b    (a1)+,(a2)+
    dbf    d2,dirtop_l

dirtop_end  
* Copy backslash, asterixes:
    lea    pathendp(pc),a1
    moveq    #4,d2
.ast    move.b    (a1)+,(a2)+
    dbf    d2,.ast


* Display basepage address of this run :

    lea    progbeg-256(pc),a1
    lea    text120+7(pc),a2
    moveq    #5,d3    *6 cyphers - 24 bits
    move.l    a1,d1
bapdl    move.b    d1,d2
    and.b    #$0F,d2
    add.b    #"0",d2
    cmp.b    #"9",d2
    ble.s    put_cyp
    add.b    #7,d2      * "A"-$3A
put_cyp    move.b    d2,-(a2)
    lsr.l    #4,d1
    dbf    d3,bapdl





**********  End of preparations


mcontrl  bsr mctrl *program takes maus controll
  lea form1(pc),a0
  bsr opdial
  bsr resscp *screen part reserve
  bsr drdial

  move.l    sp,work_usp  *for keeping SP after subrut exit in menu

*Main loop of dialog   
mcont
   move.l   work_usp(pc),sp

   bsr mafing *needed if is PRG (PRG startet with bee)
   bsr fodial

   move.w excod(pc),d0

  *Here come actions by button press

    cmp.w   #BUSAVC,d0
    beq    savestat

    cmp.w   #BUPLAYS,d0
    beq    playstat
 
    cmp.w   #BUPLAYR,d0
    beq    playram
 
    cmp.w   #BUENTNOT,d0
    beq    entnotes

    cmp.w   #BUSHOWI,d0
    beq    showinf

    cmp.w    #BUEXIT,d0
    beq cl2


menu
*  bsr mafing
    bsr exobdes 
    bra mcont




* Draw second dialog
entnotes
  bsr noredr   *deselect calling button!
  lea form2(pc),a0
  bsr opdial
  bsr resscp    *screen part reserve
  bsr drdial
  bsr maarr

mcont2
  bsr fodial

  move.w excod(pc),d0

  cmp.w #BUCANC,d0
  beq   helpcanc
  cmp.w #BUENTR,d0
  beq   helpentr

menu2
*  bsr exobdes    *not much sense
   bra mcont2


helpex
   bsr noredr   *deselect last pressed button
   lea form1(pc),a0
   bsr opdial
   bsr resscp *screen part reserve
   bsr drdial
   bra menu

helpcanc
   sf   putnotes
   bra  helpex

helpentr
   st   putnotes    *Flag for Header builder part
   bra  helpex

putnotes  dc.w  0


* Draw third dialog:
showinf 

* First load savefile, so fileselector

    bsr     mabee
    lea     initst(pc),a1
    bsr     putext  *put initial extension

*Call fileselector:
    lea       fsloadm(pc),a1
    bsr       filesel
    tst.b     buffr+100
    beq      redrdial  * to dialog if nothing selected

*Open file  and load header: 

    move.w     #0,-(sp)   *read only
    pea         buffr+100(pc)
    move.w    #61,-(sp) *Open file
    trap         #1
    addq.l     #8,sp
*Error check
    tst.w       d0
    bmi         filerr

    move.w     d0,handl

    pea     header(pc)
    pea    header_len
    move.w    handl(pc),-(sp)
    move.w    #63,-(sp)
     trap         #1
    lea          12(sp),sp
    cmp.l       #header_len,d0  *check
    bne          filerr_clof


* Check signature
    lea     header(pc),a2
    cmp.l    #"PPGX",(a2)
    bne    notGamex


    bsr    closfile


* Copy   infos  from header to RSC:

    lea     header+128(pc),a1   * Machine info txt
    lea    text12+9,a2
    moveq    #7,d2
.co1    move.b    (a1)+,(a2)+
    dbf    d2,.co1
    clr.b    (a2)

    lea          header+140(pc),a1   *TOS Vers. txt
    lea    text13+5,a2
    moveq    #3,d2
.co2    move.b    (a1)+,(a2)+
    dbf    d2,.co2
    move.b    #" ",(a2)+

    move.b    header+136(pc),d2  * Is GOS ?
    move.b    d2,text13
    cmp.b    #"G",d2   * if GOS skip lang show
    beq.s    term_tosvp

* Lang ?
    move.b    (a1)+,(a2)+
    move.b    (a1)+,(a2)+
    move.b    (a1)+,(a2)+
term_tosvp    clr.b    (a2)

* Now  Gamex key info:

    lea           header+174(pc),a1   * Gamex info txt
    lea    text15+9,a2
    moveq    #9,d2
.co3    move.b    (a1)+,(a2)+
    dbf    d2,.co3
    clr.b    (a2)


* Notes -  2 x 32  bytes

    lea           header+184(pc),a1    * Notes txt
    lea    text29,a2
    moveq    #31,d2
.co4    move.b    (a1)+,(a2)+
    dbf    d2,.co4
   
    lea    text30,a2
    moveq    #31,d2
.co5    move.b    (a1)+,(a2)+
    dbf    d2,.co5





  bsr noredr   *deselect calling button!
  lea form3(pc),a0
  bsr opdial
  bsr resscp *screen part reserve
  bsr drdial
  bsr maarr

mcont3
  bsr      fodial
  move.w   excod(pc),d0
  cmp.w   #BUINFEX,d0
  beq      helpex   *Same
 
menu3
*  bsr exobdes    *not much sense
   bra mcont3














* Here comes after swapping RAM from game (gamex key pressed) :
back_fromg
    move.l    uspstor(pc),-(sp)
    move.w    #32,-(sp)
    trap    #1
    addq.l    #6,sp
     
cl2 
   bsr mctab *vrati kontrolu

 
applex
  appl_exit
  nop
  pterm0  *exit PRG
  nop




redrdial   bsr drdial
     bra menu  *back to dialog


***************


savestat    *Saving gamestate currently in alt RAM :


* First testing is it present at all :


    move.l      physt(pc),a2
    cmp.l    #$400000,a2
    beq    nogame_inar   *Phystop at ST top RAM value
* Reading above it causes bus error !
     cmp.l       #"PPGX",(a2)

* But phystop may be not correct set if play 1MB after 512K !

    beq    go_savestat

* Fix it in launchers ! - fixed ...
* Do some seek for PPGX on round addresses !
* Doing some seek for case that no correct signature at Phystop
* it should not happen by corrected launchers !  :

    lea    $80000,a1   *at
    move.l    #$8000,d1   *step
    moveq    #95,d2   * how much for up to $380000

sign_sl    cmp.l       #"PPGX",(a1)
    beq.s    got_sign
    add.l    d1,a1
    dbf    d2,sign_sl
    bra           nogame_inar

got_sign    * fix Phystop now
    move.l    a1,physt
    move.l    a1,header+4
    pea     phyfix(pc)
    move.w     #38,-(sp)
    trap    #14
    addq.l    #6,sp


*    bne         nogame_inar

go_savestat
    bsr mabee
    lea initst(pc),a1
    bsr putext  *put initial extension
*Call fileselector:
*pfilesel
    lea fssavem(pc),a1
    bsr filesel
    tst.b buffr+100
    beq redrdial  *dialog if nothing selected
    bsr autoext


    bsr mabee
    bsr drdial   *Must redraw it after filesel...

* Now build header:

* Header struct:
* Offset,              meaning,        note
*     0    signature        PPGX
*     4    AltRamStart    new phystop, $80000 for 512KB games
*     8    Length of Swap area     usually  $7FCC8
*    12    TOS restoring code pos  usually  $FFD00
*    16    SysSto  pos          usually   $FFF80
*    20    Game rest, code pos    usually   $7FD00 ???
*    24    GameStat   pos        varies...
*    28    GameJmp      where to jump to continue game - varies
*    32      GamexKey code      $43  for F9
*    33    GamePosS  code  ....
*    34    Special IKBD flag #1   if  $14  then force mouse off by restore   
*    35      STE   DMA   flag
*    36    Force Timer Data registers - for 4 timers, if not 0 force !
*    40    TOS saving loc  - if no GCOS then 256Kbytes + $108 after AltRamStart
*    it is when here is zero.  If here is some value then it
*    will be used as TOS saving loc - usually $C0108
*    44    Flag for loading and install  extra files ....
*    value   $0001  is for  D15R_NG1  at pos $C0100 !
*    will need some table for ...
*    46 Falcon cache settings, byte, + flag for validity = $CF
*    48  .....



*  64 bytes for notes, 10 bytes for Gamex key info
* Some bytes for machine, TOS info - max 30 bytes...


header_len    equ    256



* Preclear area for sure:
    lea    header(pc),a2
    moveq    #63,d2   *for 256 bytes
.hecl    clr.l    (a2)+
    dbf    d2,.hecl


    move.l      physt(pc),a2
    move.l    4(a2),a3    *MainInb adr




* Main info block:  usually  at  $FFF40 :

* Offset,              meaning,        note
*      0    Length of swap area -  usually $7FCF8
*      4    Addr. of TOS restore code  - usually $FFD00
*      8     Addr. of SysStor  data    -  usually  $FFF80
*     12    Addr. of Game restore code - usually $7FD00 .... ?
*     16    Addr. of GameStat  data   - no usual place
*     20    Addr. of  Game Jump (by continue it)  - no usual place..
*     24      GamexKey code      $43  for F9
*     25    GamePosS  code  ....
*     26    Special IKBD flag #1   if  $14  then force mouse off by restore   
*     27     STE DMA snd  flag
*     28     Force Timer Data regs
*     32    TOS saving loc  -  see above in header desc.
*     36    Flag for extra files....
*     38        Falcon cache setting + flag, word
*     40        .....


* May be further datas...
* Space is 64 bytes, occupied so far: 40 bytes...
* It is actually same as header block from ofs. 8...


    lea    header(pc),a4

    move.l    #"PPGX",(a4)+   *Signature
    move.l    a2,(a4)+       * Alt RAM start - phystop adr.
    move.l    (a3)+,(a4)+
    move.l    (a3)+,(a4)+
    move.l    (a3)+,(a4)+
    move.l    (a3)+,(a4)+
    move.l    (a3)+,(a4)+
    move.l    (a3)+,(a4)+  
    move.l    (a3)+,(a4)+
    move.l    (a3)+,(a4)+
    move.l    (a3)+,(a4)+
    move.w    (a3)+,(a4)+

     

* Now at pos Falcon cache

* Copy it in machin block too !

    move.w    (a3),machin+8

    move.w    (a3)+,(a4)+


* Total 48 bytes so far ....


* Inserting   "keeping track on what TOS, HW is snapshot made"
* at pos 128



    lea    header+headp_mcha(pc),a4

machipr  *Outprints machine parameters
    
    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
    bra.s  hwoup

isfalcm    cmp.b  #4,(a1)
    bne.s   isttm
    lea   hwfalc(pc),a0
    bra.s  hwoup

isttm    cmp.b  #5,(a1)
    bne.s   seetv
    lea   hwtt(pc),a0

hwoup     bsr     put_inh


seetv    *TOS version outprint
    lea    header+headp_tosv(pc),a4

* If GOS, then write it to header

    cmp.w    #1,header+44
    bne.s    see_gos4
    lea      gosv1(pc),a0
    bra    put_in2

see_gos4
    cmp.w    #4,header+44
    bne.s    reg_tos     *fornow
    lea      gosv4(pc),a0
    bra.s    put_in2

   
reg_tos    lea   tosvp+4(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
put_in2    bsr     put_inh

*Lang. outprint:
    lea    header+headp_tosl(pc),a4
    cmp.b    #4,machin+3  *Is falcon?
    beq.s    rams2   
   
    moveq   #0,d1
    move.b   machin+6(pc),d1
    lsr.w      #1,d1   *drop TV norm
    lsl.w     #2,d1  *mult by 4
    lea       tosl1(pc),a0
    add.l    d1,a0
    bsr       put_inh

* Copy binary HW info :

* There is Mega STE cache/CPU clock setting at pos  4
* Falcon   Clock, STEbus emul - pos 5
* Falcon   cache  settings, flag :  pos 8,9



rams2
    lea    header+headp_hwd(pc),a4
    lea    machin(pc),a2
    moveq      #9,d1
.cop    move.b     (a2)+,(a4)+
    dbf    d1,.cop



* Here comes  yet  Gamex key and Note if are entered !!!

* Maybe some warnings when saving another snapshot - no way !


    tst.b         putnotes
    beq          nowsavh

    lea           header+174(pc),a2
    lea           text26(pc),a3
* If nothing entered skip:
    cmp.b     #"@",(a3)
    beq.s    .lo2

    moveq     #9,d3
.co1    move.b     (a3)+,(a2)+
    dbf     d3,.co1

.lo2
    lea          header+184(pc),a2
    lea           text20(pc),a3
* If nothing entered skip:
    cmp.b     #"@",(a3)
    beq.s    .lo3
    moveq    #31,d3
.co2    move.b    (a3)+,(a2)+
    dbf    d3,.co2

.lo3
    lea          text23(pc),a3
    moveq    #31,d3
* If nothing entered skip:
    cmp.b     #"@",(a3)
    beq.s    .lo4
.co3    move.b    (a3)+,(a2)+
    dbf    d3,.co3

.lo4



* Now save header:
nowsavh
*Create wanted filename
    move.w #0,-(sp)
    pea buffr+100(pc)
    move.w #60,-(sp) *Create file
    trap #1
    addq.l #8,sp
*Error check
    tst.w d0
    bmi filerr

    move.w d0,handl

    pea     header(pc)
    pea    header_len
    move.w    handl(pc),-(sp)
    move.w    #64,-(sp)
     trap         #1
    lea          12(sp),sp
*    tst.l         d0
*    bmi         filerr   
    cmp.l       #header_len,d0  *check
    bne         filerr_clof2

* It will be more complicated if need to save some current system too !!!!!

* Saving  alt RAM :

    move.l      physt(pc),a2
    move.l    4(a2),a3    *MainInb adr

    lea    8(a2),a2   *Here starts
    move.l    (a3),a3    *Length
    pea    (a3)      *save len for check...

    pea     (a2)
    pea    (a3)
    move.w     handl(pc),-(sp)
    move.w     #64,-(sp)
     trap          #1
    lea           12(sp),sp
    move.l    (sp)+,a3
    cmp.l        a3,d0  *check
    bne          filerr_clof

    bsr     closfile
    bra    menu




nogame_inar
    lea      alertnogr(pc),a0
    bsr      doalert
    bra      menu


 


* end of savestat
*****************



* Some constants, ofsets
mfpof    equ         42
ikbdof    equ    70
ikbdm_of   equ       100
srofs    equ    80
psgofs     equ    84
stedmaof    equ      108


*************

playram     * Very similar to playstat
* so just make flag and branching while executing common rut...


* First testing is it present at all :

* Same checks as by savestat :
    move.l      physt(pc),a2
    cmp.l    #$400000,a2
    beq    nogame_inar   *Phystop at ST top RAM value
* Reading above it causes bus error !
     cmp.l      #"PPGX",(a2)

* Here need same fixing of phystop

    beq    set_fromrf

    lea    $80000,a1   *at
    move.l    #$8000,d1   *step
    moveq    #95,d2   * how much for up to $380000

sign_sl2    cmp.l       #"PPGX",(a1)
    beq.s    got_sign2
    add.l    d1,a1
    dbf    d2,sign_sl2
    bra           nogame_inar

got_sign2      * fix Phystop now
    move.l    a1,physt
    move.l    a1,header+4
    pea     phyfix(pc)
    move.w     #38,-(sp)
    trap    #14
    addq.l    #6,sp
    move.l      physt(pc),a2


*    bne         nogame_inar

set_fromrf
                st     from_ram
   
* Fill header:
    lea    header(pc),a4
    move.l    (a2),(a4)+    *Signature
    move.l    a2,(a4)+     *Alt Ram Start
   
    move.l    4(a2),a3    *MainInb   here
   
    move.l    (a3)+,(a4)+   * Len
    move.l    (a3)+,(a4)+   * TOS restore code pos
    move.l    (a3)+,(a4)+   * SysStor   pos
    move.l    (a3)+,(a4)+   * Game restore code pos
    move.l    (a3)+,(a4)+    *  GameStat  pos
    move.l    (a3)+,(a4)+       * Game JMP adr.
    move.l    (a3)+,(a4)+      *Gamex keys, special IKBD flag
    move.l    (a3)+,(a4)+     * Timer Data regs....   
    move.l    (a3)+,(a4)+     * TOS save pos if not +8
    move.w    (a3)+,(a4)+     * Extra file flag(s)
    move.w    (a3)+,(a4)+    * Falcon cache flag
* it seems that ret. to Desktop activates both caches !
   
   *  48 bytes of header filled

    bsr           mabee
                bra    placomm


from_ram     dc.w    0   *Flag

****************



******************
playstat    * Loading and playing saved state....

    clr.b    from_ram   *Flag for loading file

    bsr     mabee
    lea     initst(pc),a1
    bsr     putext  *put initial extension

*Call fileselector:
    lea       fsloadm(pc),a1
    bsr       filesel
    tst.b     buffr+100
    beq      redrdial  * to dialog if nothing selected

*Open file  and load header: 

    move.w     #0,-(sp)   *read only
    pea         buffr+100(pc)
    move.w    #61,-(sp) *Open file
    trap         #1
    addq.l     #8,sp
*Error check
    tst.w       d0
    bmi         filerr

    move.w     d0,handl

    pea     header(pc)
    pea    header_len
    move.w    handl(pc),-(sp)
    move.w    #63,-(sp)
     trap         #1
    lea          12(sp),sp
    cmp.l       #header_len,d0  *check
    bne          filerr_clof


* Check signature
    lea     header(pc),a2
    cmp.l    #"PPGX",(a2)
    bne    notGamex


* Here check for extra files and abort if missing


* At this point must  check for extra files - for case that they missing may back to AES !!!!!

    lea     header(pc),a2
    tst.w    44(a2)   * GOS support needed ?
    beq    noGOSiC

    cmp.w    #1,44(a2)  *is GOS 1.00 ?
    bne    GosT2iC

    moveq    #1,d0      * version
    bsr    ldCheGOS    *universal subrutine
    bra    noGOSiC

GosT2iC
    cmp.w    #4,44(a2)  *is GOS 1.04 ?
    bne    GosT3iC

    moveq    #4,d0      * version
    bsr    ldCheGOS    *universal subrutine
    bra    noGOSiC

GosT3iC




noGOSiC


* Check for Physical RAM size :
* Maybe low RAM usage too....


   
    lea    machin(pc),a1
    cmp.b    #3,(a1)  *TT TOS vers.
    beq.s    skip_pr
    cmp.b    #4,(a1)  *Falcon TOS vers.
    beq.s    skip_pr


    lea     header(pc),a2
    move.l    4(a2),d4    * AltRamPos

* If 1MB 2 MB needed,  if 512KB 1MB needed .... so far....
   
    cmp.l    #$100000,d4
    beq.s    che2m

    cmp.l    #$80000,d4
    ble.s    need1m


che2m    * But it may be over, and still need only 1M total RAM ????

* best to compare with ~$90000-$A0000 ...

      cmp.l    #$A0000,d4
    blt.s    need1m


* Check Physical RAM

    cmp.b    #1,7(a1)  * Is only half M ?
    bne.s    che1m
    bra    insufR

che1m    cmp.b    #2,7(a1)  * Is only 1M ?
    beq    insufR
    bra.s    skip_pr



need1m    *
   
    cmp.b    #1,7(a1)  * Is only half M ?
    bne.s    skip_pr
    bra    insufR




skip_pr


* Now need to preserve TOS state.....
*

* Here actually  store  only  screen settings ....



*   Doing  high RAM allocation:


* General  Values

* Following is only for temporary screen setting !
GameScrB       equ  $78000    *For games working with 512KB


placomm
* 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


* Must lower screen because of possible overlap !
    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




* Now lower memtop:  (or move it up !)

* ** NewPhyst     equ  $80000    *For 512KB games


* But if it is already set PPGX or phystop is at $80000 do not lower anything...

    move.l      4(sp),a2   *basepage
    move.l      a2,basep
    move.l    4(a2),d2   *memtop

* How is it after Mshrink ?????  It was OK,
* But lowering works not because of ....

   
* or      cmp.l    #NewPhyst -$8000,d2

    lea     header(pc),a3
    move.l    4(a3),d5   *Actually NewPhyst
    move.l    d5,NewPhy


is_fromr2        tst.b    from_ram   *skip lowering for sure if fromRAM
    bne.s    set_pointers

    move.l    memtop(pc),basep   * This is begin of free RAM
    move.l    d2,memt
*    move.l     d5,4(a2)    *New memtop in my basepage, out because of Mshrink
*    sub.l    d5,d2      *Get difference


    pea     lowmsuv(pc)
    move.w     #38,-(sp)
    trap    #14
    addq.l    #6,sp



 * Now TOP RAM is reserved, TOS sees only 512KB or 1MB or ....  of RAM !

set_pointers

    lea     header(pc),a3
    move.l    16(a3),a2   * SysSto pos

    move.l    a2,TosRestSS+2    *Prepare TOS restore...
* Prepare GameStat pointer for IKBD state save too :

    move.l    24(a3),a4
    add.l    4(a3),a4    * it will be executed in top alt RAM
    lea    ikbdof(a4),a4
    move.l    a4,GameStap+2

    lea    ikbdm_of-ikbdof(a4),a4
    move.l    a4,GameStap2+2
    move.l    a4,GameStap3+2

    tst.b    from_ram   *skip if fromRAM
    bne.s    stage2

* Set  MainInb  pointer
    lea    -64(a2),a2    ****** !!!!  below SysSto
    move.l    NewPhy(pc),a3
    move.l    a2,4(a3)
   
*  Fill  MainInb with values:
    lea     header(pc),a3
         move.l    8(a3),(a2)+
    move.l    12(a3),(a2)+   
    move.l    16(a3),(a2)+
    move.l    20(a3),(a2)+
    move.l    24(a3),(a2)+
    move.l    28(a3),(a2)+
    move.l    32(a3),(a2)+
    move.l    36(a3),(a2)+
    move.l    40(a3),(a2)+
    move.w    44(a3),(a2)+
    move.w    46(a3),(a2)+   *Falc cacheinf




   *48 bytes filled !


stage2     
  * Must set stefl  in game restore code:

             move.b   35(a3),stefl





* 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



    tst.b    from_ram   *skip if fromRAM
    bne.s    TosStore




* Load  GameState  content to it's place :

     lea     header(pc),a3
    move.l    4(a3),a5    *Actually NewPhyst
    lea    8(a5),a5     *dest
    move.l    8(a3),d5     *length
    move.l    d5,-(sp)
   
    pea    (a5)
    move.l     d5,-(sp)
    move.w    handl(pc),-(sp)
    move.w     #63,-(sp)
    trap          #1
    lea          12(sp),sp
    move.l    (sp)+,d5
      cmp.l       d5,d0  *check for full filelength load
    bne         filerr_clof
   
    bsr    closfile







TosStore   
    lea     header(pc),a3
    move.l    16(a3),a6   * SysSto pos

    move.l    sp,(a6)+     *Store USP
    move.w    DeskRes(pc),(a6)+

* Prepare  correct screen pos for back to TOS !

    move.l    4(a3),a1   *Phystop
    sub.l    #$8000,a1
    move.l    a1,tosr_scr1+2
    move.l    a1,tosr_scr2+2




* Set supervisor mode !

    clr.l    -(sp)
    move.w    #32,-(sp)
    trap    #1
    addq.l    #6,sp
    move.l    d0,uspstor   *

* Here save TOS state ..... 


    move.l    sp,(a6)+     *Store SSP.



* 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, Timer C:  $C0  !


* Launcher stage 3 :  not doing here - it will happen by ramswap !



*  Stage 4  :  preparing setting Exit to Desktop in stored mem.  :

* We need only  regular exit  from AES App on certain point...

* Return point is in Supervisor mode expected !!
    move.l    #back_fromg,AesExit+2



* Here need to set Mega STE cache  or  Falcon bus, cache  by header state

    tst.b    from_ram   *skip if fromRAM
    bne.s    set_Falcc


* Only if saved on proper machine and are on such !

* Mega STE first :

    lea    header+148+3(pc),a2    *Binary machine desc. here
    cmp.b    #3,(a2)
    bne.s    nots_mste
    cmp.b    #3,machin+3
    bne.s    nots_mste

    move.b    1(a2),$FFFF8E21.w   *Set it
    bra.s    nots_falc

nots_mste    * For Falcon :

    lea    header+148+3(pc),a2    *Binary machine desc. here
    cmp.b    #4,(a2)
    bne.s    nots_falc
    cmp.b    #4,machin+3
    bne.s    nots_falc

* Only if we have flag set :

    cmp.b    #$CF,header+47    * See Falcon validity flag, derived from MainInb in fact
    bne.s    nots_falc

    move.b    2(a2),$FFFF8007.w


set_Falcc        cmp.b    #4,machin+3
    bne.s    nots_falc

    move.b    header+46(pc),d2
    clr.w    d4
    move.b    d2,d4
    and.w    #1,d2
    lsl.w    #7,d4
    and.w    #$0100,d4
    or.w    d4,d2

    or.w    #$0808,d2
    movec    d2,cacr


nots_falc


* Set screen now, just to see it -  early


    lea     header(pc),a2
    move.l    24(a2),a6    * GameStat  here

* not copied down yet
    add.l    4(a2),a6    * Add alt Ram pos as it is there still ...
    clr.l    d3
    move.w    66(a6),d3

    move.b    d4,$FFFF8260.w
    move.b    d3,$FFFF8203.w   * Order of writing relevant ?
    lsr.w    #8,d3
    move.b    d3,$FFFF8201.w

* Palette:
    lea    10(a6),a1
    lea    $FFFF8240.w,a2
    moveq    #15,d1
.palc    move.w    (a1)+,(a2)+
    dbf    d1,.palc


    move.w    #37,-(sp)
    trap    #14
    addq.l    #2,sp


* At this point should  set  GOS 1.04 and install HD driver in it !!!




* Another problem is sp !
* Must find good address - 77xxx no good, 7fxxx no good

    lea    fin(pc),sp  

   

* Here  with GOS  support :

* First copy game from High, second half to low

* calc  loop  count first

   

* With GOS 1.00, 1.04  support

* Wait V-blank here....
* Otherwise IR disabling may coming too fast !

    move.w    #37,-(sp)
    trap    #14
    addq.l    #2,sp


    lea     header(pc),a2

    move.l    8(a2),d0     * SwapLen
    sub.l    #$40000,d0    *get cnt. of bytes to copy down
    divu    #48,d0

* Set it in game exit code too !
    move.w    d0,ramsw_ph3it+2   *len for phase 3 of TOS restore swap



    move.l    4(a2),a5     *
*    addq.l    #8,a5
    lea    $40008,a6     * Here for sure
    add.l    a6,a5
    move.l    a5,ramsw_ph3d+2
    move.l    a6,ramsw_ph3s+2

.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 - Game restore code will be copied after


* Saving running TOS 

    lea     header(pc),a2
    tst.w    44(a2)   * GOS support needed ?
    beq    noGOSs1

    lea    $D7008,a6   * We have enough place...
    bra    toss_lok


noGOSs1
    move.l    40(a2),d1
    move.l    d1,a6
    bne.s    toss_lok

* Otherwise set to  AltRamStart+256KB
    move.l    4(a2),a6
    add.l    #$40108,a6   * Little over because overshot   

toss_lok

* Copying TOS to upper RAM
    lea    8.w,a5
   
    move.l    a6,deskCS+2
   
    lea    fin(pc),a1   *including stack space !
    move.l    a1,d0
    divu    #48,d0     *get loop count

    move.w    d0,swapln+2    *Set same len for TOS restore *swap part


.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   
* Little overshot, no problems...




* Again GOS check :

    lea     header(pc),a2
    tst.w    44(a2)   * GOS support needed ?
    beq    noGOS

    cmp.w    #1,44(a2)  *is GOS 1.00 ?
    bne    GosT2


* Now must install    GOS 1.00 to it's place :

    moveq    #1,d0      * version
    bsr    ldInsGOS    *universal subrutine

* No need to run it, as it is static (ROM) code, and vars are in low RAM of
* gamesave !!!

    * Wait V-blank here....
* Otherwise IR disabling may coming too fast !

    move.w    #37,-(sp)
    trap    #14
    addq.l    #2,sp

    bra    common2

GosT2     * here further GOS versions support
 ****

    cmp.w    #4,44(a2)  *is GOS 1.00 ?
    bne    GosT3

* Copy area  $AF000-$BFFFF down !   

    lea    $AF000-48,a5
    lea    $2F000-48,a6
    move.w    #1451,d0    * +1 because lowering

.cod6    movem.l      (a5)+,d1-d7/a0-a4   *48 bytes at once
     movem.l    d1-d7/a0-a4,(a6)   
    lea    48(a6),a6
    dbf    d0,.cod6   
* Little overshot, prepared...

    move.w    #4009,game_dls+2   * one less to prevent overwrite !

* Now must install    GOS 1.04 to it's place :

    moveq    #4,d0      * version
    bsr    ldInsGOS    *universal subrutine




* We need to run it for hard disk install !

* First lower phystop to prevent some overwrites !
* But it will screw up screen !!!

    * Wait V-blank here....
* Otherwise IR disabling may coming too fast !

    move.w    #37,-(sp)
    trap    #14
    addq.l    #2,sp

* If PP hd driver is then just copy driver up ....

    move.l    $472.w,a1    * Getbpb vector
    cmp.l    #"PPHD",-8(a1)   * See XBRA sign
    bne    must_inshdd

   
    lea    -12(a1),a1   * XBRA here

    *place where we need it:

    move.l    $80472,a2   * In saved state
    lea    -12(a2),a2
    move.w    #1800,d2    *  ???? is enough ...
.hc    move.l    (a1)+,(a2)+
    dbf    d2,.hc

* Need to set Buffer Ctrl blocks too
* Area is ready ....
    lea          $AF100,a2   * Buffers here
    move.l    #$FFFF0000,d3

    move.l    $804B2,a0
    lea     20(a0),a1
    move.l      a1,(a0)+
    move.l      d3,(a0)+
    clr.l    (a0)+
    clr.l    (a0)+
    move.l      a2,(a0)
    lea           8192(a2),a2
           
    clr.l    (a1)+
    move.l      d3,(a1)+
    clr.l    (a1)+
    clr.l    (a1)+
    move.l      a2,(a1)
    lea           8192(a2),a2

    move.l    $804B6,a0
    lea     20(a0),a1
    move.l      a1,(a0)+
    move.l      d3,(a0)+
    clr.l    (a0)+
    clr.l    (a0)+
    move.l      a2,(a0)
    lea           8192(a2),a2
   
    clr.l    (a1)+
    move.l      d3,(a1)+
    clr.l    (a1)+
    clr.l    (a1)+
    move.l      a2,(a1)
   

    bra.s    afterHi



must_inshdd
* Must lower Phystop otherwise will destroy RAM at $40000 ! And even lower now !
    move.l    #$2F000,$42E.w

* Then set that exits right after installing HD driver

GOSafterHi    equ    $C040A   *currently

    lea    GOSafterHi,a2
    move.w    #$4EF9,(a2)+
    move.l    #afterHi,(a2)

    jmp    $C0100    * Init GOS, install HD driver

afterHi    move    #$2700,sr
    lea    fin(pc),sp
    lea    header(pc),a2
   
    bra    common2




GosT3





noGOS
   
common2


* Continue with restoring game State


*    set screen:   *** Possible problems if it is very low - overlapping !!!
* solution may be moving this code up first !!!

* Another problem is sp !
* Must find good address - 77xxx no good, 7fxxx no good

    lea    fin(pc),sp  

    lea     header(pc),a2
    move.l    24(a2),a6    * GameStat  here


* Part is already copied down, so depends from pos !

* If pos is over $40000 need to skip adding !
*  Never set Gamestat to boundary !

    cmp.l    #$40000,a6
    bcc.s    gstat_dw

    add.l    4(a2),a6    * Add alt Ram pos as it is there still ...
gstat_dw    move.w    4(a6),d4       *Res

    clr.l    d3
    move.w    66(a6),d3
*    lsl.l    #8,d3    *Screen base


* Must do everything without TOS calls !!!!

    move.b    d4,$FFFF8260.w
    move.b    d3,$FFFF8203.w   * Order of writing relevant ?
    lsr.w    #8,d3
    move.b    d3,$FFFF8201.w


* Palette:
    lea    10(a6),a1
    lea    $FFFF8240.w,a2
    moveq    #15,d1
.palc    move.w    (a1)+,(a2)+
    dbf    d1,.palc



   

* Set IKBD joy  mode as saved:

* If   we have force, do it and nothing else....

    lea     header(pc),a2
    move.b    34(a2),d1
    beq.s    see_ad1

    moveq    #0,d2
    moveq    #1,d3   *1 to sub usually
    lea    ikbd_xco(pc),a2
    move.b    d1,(a2)+
    cmp.b    #7,d1   * It has 2 bytes !!!
    bne.s    not7
    move.b    #4,(a2)+   *Keymode
    moveq    #2,d3     * 2 to sub ...
    moveq    #1,d2      *2 bytes to send !

not7
    clr.b    (a2)
    sub.l    d3,a2
    bra    ikbd_tr142


see_ad1
      lea    ikbdof(a6),a1

* See byte count  (not perfect, but good for start).... !!!!****

    cmp.b    #$F6,(a1)+
    bne.s    skip_ikbds   * If header missing
    move.l    a1,a2      *Pointer
    moveq     #6,d1   *limiter
ikbd_sel    tst.b    (a1)+
    beq.s    ikbd_ser
    dbf    d1,ikbd_sel

ikbd_ser  moveq      #6,d2
    sub.b    d1,d2
    beq.s     skip_ikbds

    subq.w    #1,d2

*    pea     (a2)    *
*    move.w  d2,-(sp)
*    move.w  #25,-(sp)
*    trap  #14
*    addq.l  #8,sp

ikw1    move.b    (a2)+,$FFFFFC02.w

ikready    btst    #1,$FFFFFC00.w
    beq.s    ikready

*Some little delay :
     move.l   #284,d1
.del    subq.l    #1,d1
    bne.s   .del

    dbf    d2,ikw1



skip_ikbds


* Set  IKBD  mouse  mode as saved:

      lea    ikbdm_of(a6),a1

* See byte count  (not perfect, but good for start).... !!!!****

    cmp.b    #$F6,(a1)+
    bne.s    skip_ikbds2   * If header missing
    move.l    a1,a2      *Pointer
    moveq     #6,d1   *limiter
ikbd_sel2       tst.b    (a1)+
    beq.s    ikbd_ser2
    dbf    d1,ikbd_sel2

ikbd_ser2  moveq      #6,d2
    sub.b    d1,d2
    beq.s     skip_ikbds2

    subq.w    #1,d2

ikbd_tr142

*    pea     (a2)    *
*    move.w  d2,-(sp)
*    move.w  #25,-(sp)
*    trap  #14
*    addq.l  #8,sp

ikw2    move.b    (a2)+,$FFFFFC02.w

ikready2    btst    #1,$FFFFFC00.w
    beq.s    ikready2

*Some little delay :
     move.l   #284,d1
.del    subq.l    #1,d1
    bne.s   .del
    dbf    d2,ikw2

skip_ikbds2

*Some little delay :

     move.l   #784,d1
.del    subq.l    #1,d1
    bne.s   .del


    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


* Here  doing  preset of Forced Timer Data regs in GameStat :


    lea     header+36(pc),a2   *Timer datas
    lea    mfpof+15(a6),a1    * Pos 15 inside MFP area !
    move.b    (a2)+,d1
    beq.s    notforc_a
    move.b    d1,(a1)
notforc_a    addq.l    #1,a1
    move.b    (a2)+,d1
    beq.s    notforc_b
    move.b    d1,(a1)
notforc_b  addq.l    #1,a1
    move.b    (a2)+,d1
    beq.s    notforc_c
    move.b    d1,(a1)
notforc_c  addq.l    #1,a1
    move.b    (a2)+,d1
    beq.s    notforc_d
    move.b    d1,(a1)
notforc_d 

 

*Some little delay
* Until find not better solution ... ?
     move.l   #3784,d1
.del    subq.l    #1,d1
    bne.s   .del



* Need to set sp outside swap area -  later, after saving TOS !!!

    lea     header(pc),a2
*    move.l    20(a2),a3   *Game Restore code pos
*    lea           520(a3),sp    ****

* Prepare jump into game:
    lea    togame+2(pc),a1
    move.l    28(a2),(a1)





* Latest step is copying lower half of game to low RAM :

* but it must be done outside swap area !!!

    lea     header(pc),a2

* Len corrected if GOS 1.04 !  :
game_dls        move.w    #5461,d0   * for $40000  bytes
    lea    8.w,a6

*    lea    $80008,a5
    move.l    4(a2),a5
    addq.l    #8,a5

    move.l    a5,ramsw2hi+2
*    move.w    d0,ramsw2it+2   * this is constant so far ....
* By TOS restore we need constant len !
    move.w    #5461,ramsw2it+2   * this is constant so far ....


* Set positions so, that no overwrite of code may happen !!!

   
*set SP outside swap areas !
set_spa

    * Copy code in free area $FFD00 - $FFFFF
* Must here because some additional values set   
..
*    lea     header(pc),a3
    move.l    12(a2),a3   * TOS restore Code pos
    lea    GamexCtrl(pc),a1   
   
    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)+,(a3)+
    dbf    d2,.cou





*    lea     header(pc),a2
    move.l    20(a2),a3   *Game Restore code pos
    lea           520(a3),sp    ****




*Will need not more than 12 bytes as IR is disabled !
   
*    move.l    a6,a1      * GameStat pos
    move.l    24(a2),a1   *Pos after swap !

* It may be in HighRam,  then no subbing !!!!
* so test: 
*    cmp.l       #$80000,a1
*    bcc.s    noSubb

*    sub.l    4(a2),a1   * Will go in low RAM !!!

noSubb    move.l    a1,-(sp)   *save location

   


* Following part must be outside swapping areas !!!

* Ideal place is after screen -  $7FD00  !
* Taken from header above

* But in this testing it is $7FF00, so only 240 bytes to copy:
* Stack is at top !!!

    lea    ramswp(pc),a2
    move.l    a3,a1
    move.w    #60,d2
.mou    move.l    (a2)+,(a1)+
    dbf    d2,.mou

    jmp    (a3)





* PC relative must be !

* Here only final swap part - first half of game to 8 - of GOS
* or whole Game if no GOS

ramswp   
*    move.w    #5461,d0   * for $3FFF8  bytes
*    lea    8.w,a6    *this is constantly !
*    lea    $80008,a5

.cod3    movem.l      (a5)+,d1-d7/a0-a4   *48 bytes at once
     movem.l    d1-d7/a0-a4,(a6)   
    lea    48(a6),a6
    dbf    d0,.cod3   
* Little overshot, no problems...




* ACIA may be blocked...

gaciafl        btst    #0,$FFFFFC00.w
    beq.s    gaciaempt
    tst.b     $FFFFFC02.w
    bra.s     gaciafl
gaciaempt



* Restore MFP....

    move.l    (sp)+,a6

* Now in low RAM !!!

    lea    $FFFFFA01.w,a1
    lea    mfpof(a6),a2

* Be sure that ACIA in service bit is cleared - ahead
    bclr      #6,8(a2)

    moveq    #23,d2   *24 registers
mfprl    move.b    (a2)+,(a1)
    addq.l    #2,a1
    dbf    d2,mfprl


*    move.w    srofs(a6),sr


     move.l    (a6),a1
    move.l    a1,usp
    move.l    6(a6),sp   *SSP


* Restore PSG state:
    lea    $FFFF8800.w,a1
*    lea    GameStat+psgofs,a2
    lea    psgofs(a6),a2
    moveq    #0,d2
.psgl    move.b    d2,(a1)
    move.b    (a2)+,2(a1)
    addq.b    #1,d2
    cmp.b    #14,d2
    bne.s    .psgl


* Restore   STE DMA if ....
    lea    stefl(pc),a1
    tst.b    (a1)
    beq.s    workar


    lea    stedmaof(a6),a2
    move.b    (a2)+,$FFFF8903.w
    move.b    (a2)+,$FFFF8905.w
    move.b    (a2)+,$FFFF8907.w
    move.b    (a2)+,$FFFF890F.w
    move.b    (a2)+,$FFFF8911.w
    move.b    (a2)+,$FFFF8913.w
    move.b    (a2)+,$FFFF8921.w
    move.b    (a2)+,$FFFF8901.w



*    move.w    srofs(a6),sr
* Problem: after above V-blank activates immediately
* so, if some reg is not set as expected - crash, boomm.

* Workaround:
workar                   lea    resto_sr+2(pc),a1
    move.w    srofs(a6),(a1)

    movem.l    (sp)+,d0-d7/a0-a6

resto_sr    move.w    #0,sr     **** Setting value above !

togame    jmp        0  *****  As is saved...


stefl   dc.w    0


ikbd_xco   ds.b    8








lowmsuv     *Supervisor mode needed for set some sysvars...

        move.l    $42E.w,d5   *Old Phystop
    move.l    NewPhy(pc),$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    NewPhy(pc),d5    *Get diff.
    sub.l     d5,$436.w    *Correct Memtop sysvar

    sub.l    d3,$436.w    * By Falcon if....




get_osend
*    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 may be $200 bytes higher !!!!
* but not after exiting game correct set !
*    cmp.b    #4,machin+3
*    bne.s    corr_2
    sub.l    d3,4(a2)


hb_supp
* Header build support  #1:
    move.l    $42E.w,a2
    move.l    #"PPGX",(a2)+
*    move.l    #MainInb,(a2)
   
    rts
 

DeskRes    dc.w    0
basep    dc.l      0
memt    dc.l      $78000    *preset for case...
memtop   dc.l     0    * Here comes  free RAM pos after Mshrink at
* PRG start ....


NewPhy    dc.l    $80000
uspstor     dc.l    0
StoSPP      dc.l        0





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


 

    bsr    SomeDel



ramswp2         lea     8.w,a5

ramsw2hi      lea    $80008,a6  * will be set by header
ramsw2it      move.w    #21812,d0  *  will be set by header


*  Above needs to correct according to header - done.

* Copy lower 256 KB up, as first step, so TOS can go down after...
ramswl2    
    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,ramswl2

* game up to $40008  copied

* TOS back to low RAM :
    lea    8.w,a6
deskCS    lea    $D7008,a5  *** will be set
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
ramsw_ph3s    lea    $3FFF8,a5   *src
ramsw_ph3d    lea    $BFFF8,a6   *dest

ramsw_ph3it    move.w    #5445,d0      *for rest
.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  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    TosRestSS+2(pc),a1   *PC relative !
    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
TosRestSS    lea    0,a2   ***
    lea    mfpof(a2),a2
    moveq    #23,d2   *24 registers
mfprl2    move.b    (a2)+,(a1)
    addq.l    #2,a1
    dbf    d2,mfprl2

    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 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)



     pea  mouvertsta(pc)   
    move.w  #0,-(sp)   *1 byte only to send
    move.w  #25,-(sp)
    trap  #14
    addq.l  #8,sp

    bsr    SomeDel

* If result is normal status prepare to be skipped:
* a4 likely unchanged ....

    cmp.b  #$10,1(a4)  * Normal value for ..
    bne.s    go_mor2
    clr.b    (a4)


go_mor2
* Now for Mouse 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   

    bsr    SomeDel

    cmp.b  #$08,1(a4)  * Normal value
    bne.s    go_mor3
    clr.b    (a4)

* If above gives standard val, one test more:

GameStap3    lea    0,a4    *will be prepared
    lea    ikbstoc+2(pc),a2
    move.l    a4,(a2)

     pea  moubua(pc)   
    move.w  #0,-(sp)   *1 byte only to send
    move.w  #25,-(sp)
    trap  #14
    addq.l  #8,sp   

    bsr    SomeDel

    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


    pea  setrelm(pc)    *Set  rel. mouse mode
    move.w  #0,-(sp)
    move.w  #25,-(sp)
    trap  #14
    addq.l  #8,sp


* Set screen
    move.w    d7,-(sp)
tosr_scr1        pea     GameScrB
tosr_scr2        pea    GameScrB
     move.w    #5,-(sp)
    trap    #14
    lea    12(sp),sp



ToDesktop   * AES program, so need little more:

AesExit    jmp    0 *****  will be set

* Jump  to  pos right  before Trap #1, #32, Super to User mode !!!!


*    clr.w    -(sp)
*    trap    #1    *Regular exit



SomeDel
     move.l   #6984,d1
.del2    subq.l    #1,d1
    bne.s   .del2
    rts


* 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  $94
* Instead joysta try  with mouse vertical coords:
mouvertsta      dc.b  $90
mousta      dc.b  $89
moubua     dc.b  $87
setrelm      dc.b  8


   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










* End of playstat
**********


* Need table with extra filenames

* Code for load, install....

* Loading:  first seek in actual DIR, if no then in C:\GAMEX\....
* If not found give alert !


ldInsGOS   *input:  d0 = GOS version code

* doing #1 support

    cmp.b    #1,d0
    bne    whatG2

* load file from curDIR

    lea    gos1nam(pc),a1
    bsr    gfopen
    bpl.s    load_gfile

* Try in common Gamex DIR:

    lea    gosDir+9(pc),a1
    lea    gos1nam(pc),a2
    moveq    #11,d2
.gnc    move.b    (a2)+,(a1)+
    dbf    d2,.gnc

    lea    gos1nam(pc),a1
    bsr    gfopen
    bpl.s    load_gfile

*  Here  set error condition and do Alert, then to menu !!!!
    bra    ig_err


load_gfile  lea    $C0100-28,a1
    bsr    gfread  *with fclose

   
    lea    $C0100-28,a3
    bsr    greloc
   



    bra    ig_oke




whatG2   *for other files coming yet ....
    cmp.b    #4,d0
    bne    whatG3


    * load file from curDIR

    lea    gos4nam(pc),a1
    bsr    gfopen
    bpl.s    load_gfile4

* Try in common Gamex DIR:

    lea    gosDir+9(pc),a1
    lea    gos4nam(pc),a2
    moveq    #11,d2
.gnc    move.b    (a2)+,(a1)+
    dbf    d2,.gnc

    lea    gos4nam(pc),a1
    bsr    gfopen
    bpl.s    load_gfile4

*  Here  set error condition and do Alert, then to menu !!!!
    bra    ig_err


load_gfile4  lea    $C0100-28,a1
    bsr    gfread  *with fclose

   
    lea    $C0100-28,a3
    bsr    greloc

    bra    ig_oke

whatG3



ig_err    * best to reset machine here !
    move.l    4.w,a2
    jmp    (a2)




ig_oke    moveq    #0,d0
    rts


gfopen    clr.w    -(a7)
    pea    (a1)
    move.w    #$3D,-(a7)
    trap    #1
    addq.l    #8,a7
    move.w    d0,d7
    rts

* Load packed GOS !
gfread    pea    (a1)   *28 bytes lover due header, dest

* Wrong !  No enough place there !!!!!

* For test load it  in area above 1MB ....

    pea    $C6A00    * End of file must
* be at point above end of depacking !!!!
* Place is very tight !
*    pea    fin+8(pc)   * Here some 100KB free space still ! No !
    pea    67002    * len exact
    move.w    d7,-(a7)
    move.w    #$3F,-(a7)
    trap    #1
    lea    12(sp),sp
* some tests here.... todo...

    tst.l    d0
    bmi.s    ig_err


    move.w    d7,-(a7)
    move.w    #$3E,-(a7)
    trap    #1
    addq.l    #4,a7   


    lea    $C6A20,a1
*    lea    fin+40(pc),a1
    move.l    (sp)+,a4
    bsr    depak3

    rts



* Just checking presence of files
ldCheGOS   *input:  d0 = GOS version code

* doing #1 support

    cmp.b    #1,d0
    bne    whatG2Che

* load file from curDIR

    lea    gos1nam(pc),a1
    bsr    gfopen
    bpl.s    CheOK

* Try in common Gamex DIR:

    lea    gosDir+9(pc),a1
    lea    gos1nam(pc),a2
    moveq    #11,d2
.gnc    move.b    (a2)+,(a1)+
    dbf    d2,.gnc

    lea    gos1nam(pc),a1
    bsr    gfopen
*    bpl.s    CheOK


    bmi.s    Cheerr


CheOK    move.w    d7,-(a7)
    move.w    #$3E,-(a7)
    trap    #1
    addq.l    #4,a7   

    moveq    #0,d0
    rts

   
whatG2Che
    cmp.b    #4,d0
    bne    whatG3Che

    * load file from curDIR

    lea    gos4nam(pc),a1
    bsr    gfopen
    bpl.s    CheOK

* Try in common Gamex DIR:

    lea    gosDir+9(pc),a1
    lea    gos4nam(pc),a2
    moveq    #11,d2
.gnc    move.b    (a2)+,(a1)+
    dbf    d2,.gnc

    lea    gos4nam(pc),a1
    bsr    gfopen
*    bpl.s    CheOK

    bmi.s    Cheerr

    bra    CheOK



whatG3Che



*  Here  set error condition and do Alert, then to menu !!!!
Cheerr   
  * Close GXP file
    bsr    closfile
   
* Prepare alert :
    lea    gosDir+9(pc),a1
    lea    afilmf(pc),a2
    moveq    #11,d2    * Filename must be exactly 8 . 3 - 12 bytes without 0 term. !
.gnc    move.b    (a1)+,(a2)+
    dbf    d2,.gnc

* May jump directly from here ....

    * back to user:
  *in user now
*    move.l    work_usp(pc),-(sp)
*    move.w    #32,-(sp)
*    trap    #1
*    addq.l    #6,sp

    lea      alert_film(pc),a0
    bsr      doalert
    bra      redrdial




*    bra    exfi_nfa   *to alert in user mode

*    moveq    #13,d0
*    rts
   






greloc    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
    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    rts




insufR     * No enough RAM alert :
    lea      alertnoeR(pc),a0
    bsr      doalert
    bra      redrdial




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






gosDir    dc.b    "C:\GAMEX\XXXXXXXX.XXX",0



gos1nam    dc.b    "D15R_NG1.FIC",0
gos4nam    dc.b    "D15R_HH4.FIC",0


gosv1    dc.b    "GOS 1.00",0
gosv4    dc.b    "GOS 1.04",0





    even  







filerr_clof2
     bsr      closfile
saverr
    lea     alertse(pc),a0
    bra.s  to_alert1

filerr_clof
     bsr      closfile
filerr 
    lea     alertde(pc),a0
to_alert1    bsr doalert

     bra     redrdial   *Needed after fileselector !

notGamex    bsr    closfile
     lea       alertnox(pc),a0
     bra.s    to_alert1




phyfix    lea    header(pc),a2
    move.l    4(a2),$42E.w
    rts

* Above ensures start from RAM and pos save if playing 1M after 512K

* But not fixes if playing with launcher !



supv 

  * Save Supervisor Stack pointer too:
  move.l   sp,a1
  addq.l   #4,a1   *correct stack because we are in subrutine
  move.l   a1,StoSPP

   move.l $42e.w,physt

 *get TOS version too here
*Good because of different fileselector possible

* We need running TOS version, not that in ROM !

     move.l      $4F2.w,a1
     move.b     2(a1),d0  *TOS ver major
     move.b     3(a1),d1  *TOS ver minor

     cmp.b     #2,d0
     blt.s       itstos1
     bra.s      hwt2

itstos1          cmp.b #4,d1
       bge.s      hwt2

under14    st       oldtos   *For fileselector call

hwt2          lea      machin(pc),a2


* Continue with HW detection:
    move.b     d0,(a2)+   *TOS V
    move.b     d1,(a2)+   *TOS v
*    addq.l      #1,a2    *skip  RAM size pos.
    move.b     29(a1),4(a2)   *Lang code  pos 6

   
*'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)+

*If TOS is 4 or 3 , 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)
*    st    stefl

    move.b    d1,(a2)    * Write value direct
    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
*    st    stefl
    bra.s    restosp

buser2    move.b    #1,(a2)    *Bare ST

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,0,0   *RAM TOS V Major, TOS v minor, RAM size, HW
    *   MSTE clock set, Falcon bus setting, Lang code, Real RAM size, Falcon cache - 2 bytes, Falcon validity flag

*  need Falcon settings too in this 10 byte block:




istt     move.b   #5,(a2)   *HW code
        rts

isfalc    move.b   #4,(a2)   *HW code

    move.b    $ffff8007.w,machin+5   *Store Falcon bus setting
    movec    cacr,d5

* It seems that return to Desktop ( or Gemdos progr exit) sets both
* caches on !

*    move.w    d2,d5
*    and.w    #$0101,d2   * Data and instruction cache state
*    move.w    d2,machin+8   * Falcon CPU cache settings, 2 bytes


*PMMU moving
newpos equ $3FE000

    lea     pmmuop(pc),a1   
    move.b    #0,(a1)
    clr.l    d0
    movec    cacr,d0
    move.w    #$20A,d0   *This turns both caches off !
    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

    or.w    #$0808,d5
    movec    d5,cacr        * Restore original cache state

*    st    machin+10   * Flag for valid values of bus and cacr

* Setting Falcon sound to STE DMA mode :

    move.w  #1,-(sp)
    clr.l   -(sp)
    move.w  #8,-(sp)
    clr.w  -(sp)
    move.w  #$8B,-(sp)
    trap   #14
    lea   12(sp),sp



    rts



put_inh     move.b (a0)+,d1
      bne.s  goonHi
       rts

goonHi   move.b d1,(a4)+
      bra.s      put_inh






hwst        dc.b  "   ST",0
hwste      dc.b "  STE",0
hwmste   dc.b "Mega STE",0
hwfalc      dc.b " Falcon",0
hwtt    dc.b "  TT:",0


tosvp      dc.b "TOS 1.00",0
  even




* TOS languages:

* 4 bytes per ...
tosl1   dc.b "USA",0
   dc.b  "FRG",0
   dc.b  "FRA",0
   dc.b  "UK ",0
   dc.b  "SPA",0
   dc.b  "ITA",0
   dc.b  "SWE",0
   dc.b  "SWF",0
   dc.b  "SWG",0
   dc.b  "TUR",0
   dc.b  "FIN",0
   dc.b  "NOR",0
   dc.b  "DEN",0
   dc.b  "SAU",0
   dc.b  "HOL",0

   even







 




 


closfile  move.w handl(pc),-(sp)
  move.w #62,-(sp)
  trap #1
  addq.l #4,sp
  rts

   

*AES dialog subrutines


*DRAW DIALOG SUBRUTINE
*In parameter:a0-tree adress

opdial *put tree adress on all places where needed
  lea fca(pc),a1
  move.l a0,(a1)
*  move.l a0,oda-fca(a1)
  move.l a0,fda-fca(a1)
  move.l a0,oca-fca(a1)
  move.l a0,oda2-fca(a1)
  move.l a0,oda2f-fca(a1)
  move.l a0,oda3-fca(a1)
*  move.l a0,oboff+2-fca(a1)
*centre objekt
 
  form_center
fca ds.l 1
*Enter coords
  lea cost(pc),a1
  lea intout+2(pc),a0
  bsr.s copint2
  bsr.s copints
*  lea odp(pc),a1
*  bsr.s copints
  lea odp2+4(pc),a1
  bsr.s copints
  lea fdf+2(pc),a1
  bsr.s copints
  bsr.s copints
  lea obnu+4(pc),a1
 
copints lea cost(pc),a0
copint2 moveq #3,d0
copil move.w (a0)+,(a1)+
  dbf d0,copil
  rts



*Reserve screen part
resscp
  form_dial
  dc.w 0
cost ds.w 8
  rts



drdial
  moveq #0,d0
  bra obdr  *ret via



*Object exit rutine "Form do"
 
fodial
   form_do
   dc.w 0
fda ds.l 1
   move.w intout(pc),excod  *Save exit button
   rts

cldial  bsr.s noredr

*Back screenpart
backsp
  form_dial
fdf dc.w 3
  ds.w 8

  rts

obsel move.w d0,obnu
  move.w #1,status
  bra.s ochl
obdes move.w d1,obnu
  bra.s clrstat

noredr  clr.w status+2  *No redraw by leave dialog
exobdes
  move.w excod(pc),obnu
clrstat  clr.w status  *normal status
ochl
  objc_change
obnu dc.w 0,0,0,0,0,0
status  dc.w 0,1
oca ds.l 1
  move.w #1,status+2 * redraw needed after again
  rts



doalert
  move.l a0,ala
  form_alert
  dc.w 1  *Default
ala  dc.l 0
  move.w intout(pc),d0
  cmp.w #1,d0 *test pressed key
  rts



obdr move.w d0,odp2
  objc_draw
odp2 dc.w 0,3 *depth=3 used
  ds.w 4
oda2 ds.l 1
  rts


clobdr  *startobject is mainbox
  objc_draw
odp3 dc.w 0,2 *depth=2 used
clip3  ds.w 4
oda3 ds.l 1
  rts

obdrf move.w d0,odp2f
  bsr AEScall
  dc.w 42
odp2f dc.w 0,0
  ds.w 4
oda2f ds.l 1
  rts


mctrl
  wind_update
  dc.w 3
  rts

mctab
  wind_update
  dc.w 2
  rts

mafing moveq #3,d1
  bra.s grafmo
maarr moveq #0,d1
  bra.s grafmo
mabee moveq #2,d1
grafmo move.w d1,mousf
  graf_mouse
mousf dc.w 3
  dc.l 20000 *not used
  rts   






*Central rutine for param. adress serve etc.
AEScall  move.l (sp),a1  *reta
  move.w (a1)+,d0 *function number, a1 now hold intinadr (or reta)
  lea AESct-5(pc),a3
funsrl addq.l #5,a3
  cmp.b (a3),d0
  bne.s funsrl
  moveq #4,d1
  clr.l d0
  lea contrl(pc),a2
  move.l a2,a0
fuccl move.b (a3)+,d0
  move.w d0,(a2)+
  dbf d1,fuccl 
 
  lea AESPB(pc),a2
  move.l a1,8(a2) *pintin
  move.w 2(a0),d0  *# of intin
  lsl.w #1,d0 
  add.l d0,a1  *adress of addrin
  move.w 6(a0),d0
  beq.s noadrin
  move.l a1,16(a2) *paddrin
  lsl.w #2,d0  *mult by 4
  add.l d0,a1
noadrin  move.l a1,(sp)  *Skip datas! -prepare retadress
  move.l a2,d1
  move.w #200,d0
  trap #2  *Call AES function
  rts


AESPB dc.l contrl  * pcontrol
pglobal dc.l global
pintin ds.l 1
pintout dc.l intout
paddrin ds.l 1
paddrout dc.l addrout

*Tables with AES control blocks of (only) used functions
AESct *must contents all in prg. used functions
  dc.b 10,0,1,0,0  *APPL init
  dc.b 19,0,1,0,0  *APPL exit
  dc.b 21,3,5,0,0  *EVNT button
  dc.b 23,0,1,1,0  *Evnt message
  dc.b 42,6,1,1,0  *Objc draw
  dc.b 43,4,1,1,0  *Objc find
  dc.b 44,1,3,1,0  *Objc offset
  dc.b 47,8,1,1,0  *Objc change
  dc.b 50,1,1,1,0  *Form do (dialog)
  dc.b 51,9,1,0,0  *Form dial
  dc.b 52,1,1,1,0  *Form alert
  dc.b 54,0,5,1,0  *Form center
  dc.b 78,1,1,1,0  *Graf mouse
  dc.b 79,0,5,0,0  *Graf mkstate
  dc.b 90,0,2,2,0  *Old Fsel for TOS 1.02 and 1.00
  dc.b 91,0,2,3,0  *Fsel input
  dc.b 107,1,1,0,0 *Wind update
  dc.b 114,1,1,1,0 *RSRC obfix
  dc.b 0
  even


filesel  clr.l buffr
  
    tst.b oldtos
    bne.s fiselold

    move.l    a1,fsmadr
    fsel_i 
*  bsr AEScall
*  dc.w 91,0,2,3,0 *Only for new TOS!!!
   dc.l    path
   dc.l    buffr
fsmadr      ds.l  1 
    tst.w intout
    beq.s fisend
    tst.w intout+2
    beq.s fisend
 
fsok     lea buffr+100(pc),a1
     lea path(pc),a0
     bsr.s pdcopy
*Now drop attributes of select
droat
    subq.l #1,a0
    cmp.b #"\",-(a1)  *is subdir end marker
    bne.s droat
    addq.l #1,a1  *move forward
    lea 2(a0),a2  *store ext (with . ) begin from path

    lea buffr(pc),a0
    tst.b (a0) *check for nothing selected or written
    beq.s fis2
    bra.s pdcopy
 
fisend
fis2  clr.l buffr+100
     rts


fiselold  *AES 90 for older TOS

  fsel_input
  dc.l path
  dc.l buffr

  tst.w intout
  beq.s fisend
  tst.w intout+2
  beq.s fisend
  bra.s fsok



pdcopy
    tst.b (a0)
    beq.s pdret
    move.b (a0)+,(a1)+
    bra.s pdcopy

pdret move.b (a0),(a1)  *For case that longer was there prior
     rts


*Insert extension on path end
*a1 - pointer

putext lea path(pc),a0
searz  tst.b (a0)+
    bne.s searz
*Now search back for \
searbs cmp.b #"\",-(a0)
    bne.s searbs
    addq.l #1,a0

    moveq #5,d1  *copy 4-5 chars and zero term.
initc move.b (a1)+,(a0)+
    dbf d1,initc
    clr.b (a0)
    rts 


autoext    moveq #3,d1
aecl     move.b (a2),(a1)+
    move.b    (a2)+,(a0)+ *copy in name too -for MK LDER
    dbf      d1,aecl *copy extension from path
    clr.b    (a0)
    clr.b     (a1) *endmarker  
    rts




*The RSC integrated - source made with RSCTOASM


rsc_obnum equ 28


* rsc_obs    dc.w    27    * 28 objects in RSC *

form1    dc.w    -1,1,11
    dc.w    20,0,16        *0*
    dc.l    $2111B
    dc.w    $603,0,$624,$40E

    dc.w    2,-1,-1
    dc.w    22,0,0        *1*
    dc.l    ted1
    dc.w    $201,$300,34,1

    dc.w    3,-1,-1
    dc.w    22,0,0        *2*
    dc.l    ted2
    dc.w    $404,$601,27,1

    dc.w    4,-1,-1
    dc.w    28,0,0        *3*
    dc.l    text1
    dc.w    2,$103,5,1

    dc.w    5,-1,-1
    dc.w    22,0,0        *4*
    dc.l    ted3
    dc.w    $408,$103,$712,1

    dc.w    6,-1,-1
    dc.w    26,5
    dc.b    0
flag1    dc.b    0        *5*
    dc.l    text2
    dc.w    16,5,$712,$202

    dc.w    7,-1,-1
    dc.w    26,5
    dc.b    0
flag2    dc.b    0        *6*
    dc.l    text3
    dc.w    $602,$305,$60B,$301

    dc.w    8,-1,-1
    dc.w    26,5
    dc.b    0
flag3    dc.b    0        *7*
    dc.l    text4
    dc.w    $502,$208,$414,$202

    dc.w    9,-1,-1
    dc.w    26,5
    dc.b    0
flag4    dc.b    0        *8*
    dc.l    text5
    dc.w    $119,$508,$409,$401

    dc.w    10,-1,-1
    dc.w    26,5
    dc.b    0
flag5    dc.b    0        *9*
    dc.l    text6
    dc.w    $105,$40B,17,2

    dc.w    11,-1,-1
    dc.w    26,37
    dc.b    0
flag6    dc.b    0        *10*
    dc.l    text7
    dc.w    $71D,$60B,$505,$701

* This added manually :
    dc.w    0,-1,-1
    dc.w    21,32,0        *11*
    dc.l    ted14
    dc.w    $51C,$103,7,1








form2    dc.w    -1,1,6
    dc.w    20,0,16        *0*
    dc.l    $21100
    dc.w    $401,$500,$124,10

    dc.w    2,-1,-1
    dc.w    28,0,0        *1*
    dc.l    text8
    dc.w    $105,$600,25,1

    dc.w    3,-1,-1
    dc.w    30,8,0        *2*
    dc.l    ted4
    dc.w    1,$302,$122,1

    dc.w    4,-1,-1
    dc.w    30,8,0        *3*
    dc.l    ted5
    dc.w    1,4,$122,1

    dc.w    5,-1,-1
    dc.w    29,8,0        *4*
    dc.l    ted6
    dc.w    $204,$605,21,1

    dc.w    6,-1,-1
    dc.w    26,5
    dc.b    0
flag7    dc.b    0        *5*
    dc.l    text9
    dc.w    $105,$707,8,$201

    dc.w    0,-1,-1
    dc.w    26,37
    dc.b    0
flag8    dc.b    0        *6*
    dc.l    text10
    dc.w    $116,$707,$608,$201




form3    dc.w    -1,1,8
    dc.w    20,0,16        *0*
    dc.l    $21100
    dc.w    $401,1,$623,$50A

    dc.w    2,-1,-1
    dc.w    28,0,0        *1*
    dc.l    text11
    dc.w    $707,$500,20,1

    dc.w    3,-1,-1
    dc.w    28,0,0        *2*
    dc.l    text12
    dc.w    $501,$701,19,1

    dc.w    4,-1,-1
    dc.w    28,0,0        *3*
    dc.l    text13
    dc.w    $501,$203,13,1

    dc.w    5,-1,-1
    dc.w    28,0,0        *4*
    dc.l    text14
    dc.w    $30D,$504,6,1

    dc.w    6,-1,-1
    dc.w    22,0,0        *5*
    dc.l    ted7
    dc.w    $601,$705,32,1

    dc.w    7,-1,-1
    dc.w    22,0,0        *6*
    dc.l    ted8
    dc.w    $601,$207,32,1

    dc.w    8,-1,-1
    dc.w    28,0,0        *7*
    dc.l    text15
    dc.w    $601,$708,19,1

    dc.w    0,-1,-1
    dc.w    26,37
    dc.b    0
flag9    dc.b    0        *8*
    dc.l    text16
    dc.w    26,9,8,1

        * Tedinfo blocks *

ted1    dc.l    text17,null,null
    dc.w    3,6,2,$1180
    dc.w    0,-1,35,1

ted2    dc.l    text18,null,null
    dc.w    3,6,2,$1180
    dc.w    0,-1,26,1

ted3    dc.l    text19,null,null
    dc.w    3,6,2,$1180
    dc.w    0,-1,19,1

ted4    dc.l    text20,text21,text22
    dc.w    3,6,2,$1180
    dc.w    0,-1,33,33

ted5    dc.l    text23,text24,text25
    dc.w    3,6,2,$1180
    dc.w    0,-1,33,33

ted6    dc.l    text26,text27,text28
    dc.w    3,6,0,$1180
    dc.w    0,-1,11,22

ted7    dc.l    text29,null,null
    dc.w    3,6,0,$1180
    dc.w    0,-1,33,1

ted8    dc.l    text30,null,null
    dc.w    3,6,0,$1180
    dc.w    0,-1,33,1

* Added manu.
ted14    dc.l    text120,null,null
    dc.w    3,6,0,$1180
    dc.w    0,-1,8,1




        * Text data *

text1    dc.b    'V 0.6',0
text2    dc.b    'SAVE CURRENT STATE',0
text3    dc.b    'Enter notes',0
text4    dc.b    'PLAY SAVED GAMESTATE',0
text5    dc.b    'Show info',0
text6    dc.b    'PLAY GAME IN RAM',0
text7    dc.b    'EXIT',0
text8    dc.b    'Enter notes for savefile:',0
text9    dc.b    'Cancel',0
text10    dc.b    'Enter',0
text11    dc.b    'Gamestate file info:',0
text12    dc.b    'Machine:           ',0
text13    dc.b    'TOS:         ',0
text14    dc.b    'Notes:',0
text15    dc.b    'GAMEX k:           ',0
text16    dc.b    'Thanx',0
text17    dc.b    'GAMEX-utility for gamestate store,',0
text18    dc.b    'playing stored gamestates',0
text19    dc.b    'By P. Putnik  2009',0
text20    dc.b    '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',0
text21    dc.b    '________________________________',0
text22    dc.b    'X',0
text23    dc.b    '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@',0
text24    dc.b    '________________________________',0
text25    dc.b    'X',0
text26    dc.b    '@@@@@@@@@@',0
text27    dc.b    'Gamex key: __________',0
text28    dc.b    'X',0
text29    dc.b    '                                ',0
text30    dc.b    '                                ',0
*Added manu
text120    dc.b    '$018772',0 
null    dc.b    0,0



alertde    dc.b    '[3][|Load error!][Damn!]',0
alertse    dc.b    '[3][|Save error!][Damn!]',0
alertnogr   dc.b    '[3][|No game in RAM!][ OK ]',0
alertnox     dc.b    '[3][|Not gamestate file !][ Ah ]',0

alertnoeR     dc.b    '[3][|No enough RAM !][ Sad ]',0


* Alert for case that supporting file not found :

alert_film    dc.b   '[3][|This snapshot requires file|     '
afilmf    dc.b       'filename.ext][ OK ]',0





    even

work_usp      dc.l  0   *for restoring USP after some subrut exits, by error usually
pmmuop        ds.b 32



***** File selector stuff:

initst dc.b   "*.GXP",0,0
 
fsloadm dc.b "LOAD GAMESTATE..",0

fssavem dc.b "SAVE GAMESTATE..",0

********

pathendp   dc.b  "\*.*",0



   even

oldtos dc.w 0
errflag ds.w 0

*Put here current drive.... :
path dc.b  "D:\*.*",0,0,0

  even

  SECTION BSS

  ds.b 512  *place for path

excod ds.w 1


contrl ds.w 5
global ds.l 16 
intout ds.w 7  *max 7
addrout ds.l 2  *max 2
emb ds.w 8 


filelen ds.l 1
handl ds.w 1
physt ds.l 1


header   ds.b  256   *Place for making header before save
buffr      ds.b 512    * Loading header here for instance

pathbuf  ds.b  512   *

stack     ds.b 568   *

fin