; BEGIN7.S  TOS 3.06 fr PAK/3

            >PART 'symbole'
; Hardwareregister
romporta    equ $FFFA0000           ; ROM-Port Leitung ROM4
romportb    equ $FFFB0000           ; ROM-Port Leitung ROM3
dmahigh     equ $FFFF8609
dmamid      equ $FFFF860B
dmalow      equ $FFFF860D
fdcclk      equ $FFFF860E           ; Nur GST-MCU: Taktumschaltung fr FDC
gpip        equ $FFFFFA01           ; MFP: Interface Port Datenregister

; sonstige Variablen
cr          equ 13
lf          equ 10
supexec     equ 38
pterm       equ 76
xbios       equ 14
cconws      equ 9
gemdos      equ 1

; dokumentierte Systemvariablen
berr        equ $08                 ; L: Buserror Vektor
etv_critic  equ $0404               ; L: zeigt auf Critical Error Handler
phystop     equ $042E               ; L: Obergrenze ST-RAM
flock       equ $043E               ; W: Sperren von FDC-Aktionen
seekrate    equ $0440               ; W:
_frclock    equ $0466               ; L:
hdv_bpb     equ $0472               ; L: BPB holen
hdv_rw      equ $0476               ; L: Lesen-/Schreiben von Sektoren
hdv_med     equ $047E               ; L: Test auf Mediumwechsel
_nflops     equ $04A6               ; W: Anzahl Floppy-Laufwerke
_hz_200     equ $04BA               ; L: 200Hz Z„hler
_drvbits    equ $04C2               ; L: Bitvektor fr angeschl. Laufwerke
_dskbufp    equ $04C6               ; L: Zeiger auf 1k Diskbuffer
_longframe  equ $059F               ; B: Stackframe: bei 68000: 0, sonst: -1
_cookies    equ $05A0               ; L: zeigt auf Cookiejar

; nicht dokumentierte Systemvariablen
dmasnd      equ $0A12               ; B: DMA-Sound vorh.: -1, sonst: 0
gstmcu      equ $0A13               ; B: falls GSTMCU vorh.: 0, sonst: -1

            endpart

            text
            org $E00000
;******************************************************************************
;********************************************************** TOS 3.06 Header ***
_00000:     >PART 'Header'

E00000:     bra.s     E00030              ; jmp os_text

            dc.w $0306              ; os_version
            dc.l $E00030            ; os_start
E00008:     dc.l $E00000            ; os_header
            dc.l $8316              ; os_?
            dc.l $E00030            ; os_membot

E00014:     dc.l $E36008            ; os_magic
            dc.l $09241991          ; os_gendat
            dc.b 0
            dc.b 3                  ; pal/ntsc flag
E0001E:     dc.w $1738              ; os_gendatg
            dc.l $5766              ; mifl
            dc.l $10BB              ; kb_shift
            dc.l $771E              ; act_pd
            dc.l 0

            endpart
;******************************************************************************
;************************************************************ TOS 3.06 Text ***
_00030:     >PART 'init'

E00030:     move      #$2700,SR
            reset

;--------------------------------------------------- ggf. ROM Modul starten ---

            cmpi.l    #$FA52235F,$FA0000  ; ROM-Modul magic?
            bne.s     chkmconf            ; nein: jmp
            lea       chkmconf(PC),A6     ; ja: Returnadresse in A6
            jmp       $FA0004             ; Modul anspringen

;----------------------------------------------------- Memory Konfiguration ---

chkmconf:   moveq     #1,D7               ; Bootflag: Kaltstart
            moveq     #$0A,D0             ; Default MemConf 2x 2MB

            lea       mconfret(PC),A6     ; Returnadresse in A6
            bra       *+$0BB0             ; test: memctrl gltig?       $E00C06
mconfret:   bne.s     setmconf            ; nein: exit

            moveq     #0,D7               ; Bootflag: Warmstart
            move.b    $0424.w,D0          ; MemConf aus SysVariable

setmconf:   move.b    D0,$FFFF8001.w      ; ja: memctrl nach memconf
            lea       $07FC.w,A7          ; Stack knapp unter 2kB

;----------------------------------------- CPU, MMU und FPU Initialisierung ---

            move.l    #$0808,D0           ; L1-Caches ausschalten
            dc.l $4E7B0002          ;     ; MOVEC  D0,CACR

            moveq     #0,D0               ; MMU?
            dc.l $4E7B0801          ;     ; MOVEC  D0,VBR

            lea       illvec(PC),A0       ; 20er mit FPU (PAK/3)
            move.l    A0,$10.w            ; Illegal Instruction Vector
            lea       linefvec(PC),A0     ; 20er und 30er ohne FPU
            move.l    A0,$2C.w            ; Line F Vector

            lea       $E36014,A0          ; MMU und FPU Reset Tabelle
            dc.l $F0104000          ;     ; PMOVE  (A0),TC
            dc.l $F0100800          ;     ; PMOVE  (A0),TT0
            dc.l $F0100C00          ;     ; PMOVE  (A0),TT1

illvec:     dc.w $F350              ;     ; FRESTORE (A0)

;----------------------------------------------- ggf Resetvektor anspringen ---

linefvec:   tst.l     D7                  ; Warmstart?
            bne.s     deselect            ; nein: exit

resvec1:    moveq     #0,D7               ; Bootflag: Warmstart
            cmpi.l    #$31415926,$0426.w  ; resvalid gltig?
            bne.s     deselect            ; nein: exit

            move.l    $042A.w,D0          ; resvec holen
            btst      #0,D0               ; Adresse gerade?
            bne.s     deselect            ; nein: exit
;-----------------------------------------
            movea.l   D0,A0               ; dann Adresse nach A0
            lea       resvec1(PC),A6      ; Returnadresse in A6
            jmp       (A0)                ; Resetvector anspringen

;----------------------------------------------------- Floppy deselektieren ---

deselect:   lea       $FFFF8800.w,A0      ; Soundchip base
            move.b    #7,(A0)             ; Controlregister selektieren
            move.b    #$C0,2(A0)          ; Port A und B auf Output
            move.b    #$0E,(A0)           ; Port A selektieren
            move.b    #7,2(A0)            ; Drive Select aus

;------------------------------------------------- Videomode initialisieren ---

            bsr       *+$1696             ; DE_SYNC: auf /DE warten     $E0176E
            move.b    #2,$FFFF820A.w      ; Sync Mode Reg: 50Hz, intern

            lea       $FFFF8240.w,A1      ; CLUTBASE
            move.w    #15,D0              ; 16 Eintr„ge
            lea       *+$0B3C(PC),A0      ; CLUT-Tabelle Defaultwerte   $E00C24
setclut:    move.w    (A0)+,(A1)+         ; kopieren
            dbra      D0,setclut

            move.b    #1,$FFFF8201.w      ; vid_bas_H  Videospeicher
            clr.b     $FFFF8203.w         ; vid_bas_M  ab 64kB

;---------------------------------------------------- Warm- oder Kaltstart? ---

            move.l    $042E.w,D5          ; phystop holen (wozu?)

            lea       E00108(PC),A6       ; Returnadresse in A6
            bra       *+$0B00             ; test: memctrl gltig?       $E00C06
E00108:     beq       E00262              ; ja: dann Warmstart

            endpart
;******************************************************************************
***************************************************************** Kaltstart ***
_0010C:     >PART 'Kaltstart'

;------------------------------------------- Memory Konfiguration ermitteln ---

E0010C:     move.b    #$0A,$FFFF8001.w    ; memconf auf 2x 2MB setzen

            movea.w   #8,A0               ; A0: zeigt auf Bank0  8
            lea       $200008,A1          ; A1: zeigt auf Bank1  2MB + 8
            moveq     #0,D0               ; D0: Schreibmuster, Startwert 0
;-----------------------------------------
E00120:     move.w    D0,(A0)+            ; Bank0 schreiben
            move.w    D0,(A1)+            ; Bank1 schreiben
            addi.w    #$FA54,D0           ; Muster incrementieren
            cmpa.w    #$0200,A0           ; 512 Worte geschrieben?
            bne.s     E00120              ; loop
;-----------------------------------------
            move.l    #$0200,D7           ; 512, fr normale MCU (Default)

            move.b    #$5A,$FFFF820D.w    ; vid_bas_L (nur GSTMCU) schreiben
            tst.b     $FFFF8203.w         ; vid_bas_M
            move.b    $FFFF820D.w,D0      ; vid_bas_L lesen
            cmp.b     #$5A,D0             ; šbereinstimmung?
            bne.s     E0015E              ; nein: keine GSTMCU, exit

            clr.b     $FFFF820D.w         ; ja: vid_bas_L l”schen
            tst.w     $FFFF8240.w         ; CLUT
            tst.b     $FFFF820D.w         ; ist vid_bas_L 0?
            bne.s     E0015E              ; nein: keine GSTMCU, exit

            move.l    #$040000,D7         ; 256k, fr GSTMCU (Mega STE)
;-----------------------------------------
E0015E:     move.l    #$200000,D1         ; 2 MB
            moveq     #0,D6               ;
            jsr       $E0208E             ; GETMCONF memconf ermitteln      ***
;           bsr       *+$1F28             ; GETMCONF memconf ermitteln   E0208E
            move.b    D6,$FFFF8001.w      ; memconf setzen

            lea       $8000,A7            ; Stackpointer auf 32kB

;---------------------------------------------- Gr”že des ST-RAMs ermitteln ---

            lea       E001A8(PC),A0       ; Buserror-Vektor..
            move.l    A0,8.w              ; ..hinter ST-RAM Test setzen

            move.w    #$FB55,D3           ; Fllmuster Increment
            move.l    #$020000,D7         ; 128kB Schrittweite
            movea.l   D7,A0               ; Startadresse 128kB
;-----------------------------------------
E00186:     movea.l   A0,A1               ; A1: Adresspointer
            move.w    D0,D2               ; D2: Fllmuster, Startwert aus D0
            moveq     #42,D1              ; D1: Anzahl: 43 Worte

E0018C:     move.w    D2,-(A1)            ; Wort schreiben
            add.w     D3,D2               ; Muster incrementieren
            dbra      D1,E0018C           ; loop
;-----------------------------------------
            movea.l   A0,A1               ; A1: Adresspointer
            moveq     #42,D1              ; D1: Anzahl: 43 Worte

E00198:     cmp.w     -(A1),D0            ; D0: Soll-Muster zum Vergleich
            bne.s     E001A8              ; Stimmt nicht? Dann raus hier!

            clr.w     (A1)                ; Stimmt? Dann Wort l”schen
            add.w     D3,D0               ; D0: Muster incrementieren
            dbra      D1,E00198           ; loop
;-----------------------------------------
            adda.l    D7,A0               ; Adresspointer + 128kB
            bra.s     E00186              ; loop

;------------------------------ ST-RAM ist durch: L”schen, Variablen setzen ---

E001A8:     suba.l    D7,A0               ; A0: phystop
            move.l    A0,D5               ; in D5 merken

            movea.w   #$0100,A0           ;* Speicher ab $100...  (war #$0400)
            moveq     #0,D0
            moveq     #0,D1
            moveq     #0,D2
            moveq     #0,D3

E001B8:     movem.l   D0-D3,(A0)          ; l”schen...
            lea       16(A0),A0
            cmpa.l    D5,A0               ; bis phystop
            bcs.s     E001B8              ;* loop  (war bne.s)

            move.b    D6,$0424.w          ; memctrl setzen
            move.l    D5,$042E.w          ; phystop setzen
            move.l    #$752019F3,$0420.w  ; memvalid setzen
            move.l    #$237698AA,$043A.w  ; memval2 setzen
            move.l    #$5555AAAA,$051A.w  ; memval3 setzen

;---------------------------------------------------- Wilder Schreibzugriff ---

            lea       E001F4(PC),A0       ; Buserror abfangen
            move.l    A0,8.w
            move.w    #0,$FFD000E0        ; Was soll das?             >FFD000E0

;------------------------------- Test auf gespiegeltes ST-RAM oberhalb 16MB ---

E001F4:     lea       E0024A(PC),A0       ; Buserror-Vektor..
            move.l    A0,8.w              ; ..hinter TT-RAM Test setzen

            move.w    #$FB55,D3           ; Fllmuster Increment
            moveq     #0,D0               ; D0: Muster, Startwert 0
            move.l    #$020000,D7         ; 128kB Schrittweite
            movea.l   #$01020000,A0       ; A0: Startadresse 16MB + 128kB
            movea.l   A0,A2               ;* fr TT-RAM Spiegeltest merken
;-----------------------------------------
            movea.l   D7,A1               ; A1: zeigt auf ST-RAM 128kB

            move.l    -(A0),D1            ; TT-RAM (16MB+128kB) lesen
            not.l     D1                  ; invertieren...
            move.l    D1,-(A1)            ; und ins ST-RAM (128kB) schreiben
            sub.l     (A0)+,D1            ; wurde TT-RAM ver„ndert?

            clr.l     (A1)+               ; ST-RAM l”schen

            tst.l     D1                  ; wurde TT-RAM ver„ndert?
            beq.s     E0024A              ; ja: es gibt kein TT-RAM

;---------------------------------------------- Gr”že des TT-RAMs ermitteln ---

E00220:     movea.l   A0,A1               ; A1: Adresspointer
            move.w    D0,D2               ; D2: Fllmuster, Startwert aus D0
            moveq     #42,D1              ; D1: Anzahl: 43 Worte

E00226:     move.w    D2,-(A1)            ; Wort schreiben
            add.w     D3,D2               ; Muster incrementieren
            dbra      D1,E00226           ; loop
;-----------------------------------------
            movea.l   A0,A1               ; A1: Adresspointer
            moveq     #42,D1              ; D1: Anzahl: 43 Worte

E00232:     cmp.w     -(A1),D0            ; D0: Soll-Muster zum Vergleich
            bne.s     E0024A              ; Stimmt nicht? Dann raus hier!

            clr.w     (A1)                ; Stimmt? Dann Wort l”schen
            add.w     D3,D0               ; D0: Muster incrementieren
            dbra      D1,E00232           ; loop
;-----------------------------------------
            adda.l    D7,A0               ; Adresspointer + 128kB

            move.l    A0,-4(A0)           ;* TT-RAM Spiegeltest
            cmpa.l    -4(A2),A0           ;* Page 0 des TT-RAMs gespiegelt?
            bne.s     E00220              ; nein: ist TT-RAM, loop

;--------------------------------------- TT-RAM ist durch: Variablen setzen ---

E0024A:     suba.l    D7,A0               ; 128kB vor Buserror oder Lesefehler
            cmpa.l    #$01000000,A0       ; A0: ramtop, gleich 16MB?
            bne.s     E00256              ; nein: TT-RAM vorhanden

            suba.l    A0,A0               ; ja: kein TT-RAM, ramtop auf 0
E00256:     move.l    A0,$05A4.w          ; ramtop setzen
            move.l    #$1357BD13,$05A8.w  ; magic setzen

            endpart
;******************************************************************************
;**************************************************************** Warmstart ***
_00262:     PART 'Warmstart'

E00262:     movea.w   #$5758,A7           ; ssp setzen
            clr.l     $04F6.w             ; _shell_p

            clr.w     $0A12.w             ;* $A12 und $A13 l”schen (war clr.b)
;           bsr       *+$152E             ; DMA Sound Init              $E017A0
            jsr       $E017A0             ; DMA Sound Init                  ***

;------------------------------------------------- Variablenbereich l”schen ---

            movea.l   #$E6FC,A1           ; bis Adresse $E06C..
            movea.w   #$0A14,A0           ; ab Adresse $A14
            moveq     #0,D0

E00280:     move.l    D0,(A0)+            ;* l”schen  (war move.w)
            cmpa.l    A0,A1
            bhi.s     E00280              ;* loop  (war bne.s)

;------------------------------------------------------ MMU Initialisierung ---

            lea       E0029A(PC),A0       ;
            move.l    A0,$10.w            ; Illegal Instruction Vector
            move.l    A0,$2C.w            ; Line F Vector
            movea.l   A7,A2               ; SP sichern

            jsr       $E016EC             ; MMU-Tabelle ins RAM, MMU Init   ***

E0029A:     movea.l   A2,A7               ; SP zurck

            end
;**************************************** bis hierher PAK-TOS als Bin„rfile ***

;---------------------------------------------------- Videospeicher l”schen ---

E0029C:     movea.l   $042E.w,A0          ; phystop
            suba.l    #$8000,A0           ; 32kB darunter
            move.w    #$07FF,D1           ; D1: Anzahl: 2k * 4 Langworte
            move.l    A0,$044E.w          ; _v_bas_ad
            move.b    $044F.w,$FFFF8201.w ; vid_bas_H
            move.b    $0450.w,$FFFF8203.w ; vid_bas_M
            moveq     #0,D0
E002BC:     move.l    D0,(A0)+            ; je 4 Langworte l”schen
            move.l    D0,(A0)+
            move.l    D0,(A0)+
            move.l    D0,(A0)+
            dbra      D1,E002BC           ; loop

;--------------------------------------------------- Systemvariablen setzen ---

            movea.l   E00014(PC),A0       ; os_magic
            cmpi.l    #$87654321,(A0)     ; (E36008) = magic?
            beq.s     E002DA              ; ja: dann jmp

            lea       E00008,A0           ; nein: A0 zeigt auf os_header

E002DA:     move.l    4(A0),$04FA.w       ; end_os
            move.l    8(A0),$04FE.w       ; exec_os
            move.l    #$E055DA,$046A.w    ; hdv_init
            move.l    #$E05A96,$0476.w    ; hdv_rw
            move.l    #$E0565C,$0472.w    ; hdv_bpb
            move.l    #$E058AE,$047E.w    ; hdv_mediach
            move.l    #$E05D88,$047A.w    ; hdv_boot
            move.l    #$E02394,$0506.w    ; prt_stat
            move.l    #$E022EE,$050A.w    ; prt_vec
            move.l    #$E02406,$050E.w    ; aux_stat
            move.l    #$E0241E,$0512.w    ; aux_vec
            move.l    #$E01462,$0502.w    ; dump_vec
            move.l    $044E.w,$0436.w     ; _memtop               = _v_bas_ad
            move.l    $04FA.w,$0432.w     ; membot                = end_os

            move.w    #8,$0454.w          ; nvbls
            st        $0444.w             ; _fverify      einschalten
            move.w    #3,$0440.w          ; seekrate      3 ms
            move.l    #$185A,$04C6.w      ; _dskbufp
            move.w    #-1,$04EE.w         ; _prt_cnt
            move.l    #E00000,$04F2.w     ; _sysbase
            move.l    #$093A,$04A2.w      ; savptr
            move.l    #$E00BEE,$046E.w    ; swv_vec
            clr.l     $04C2.w             ; _drvbits
            move.l    #$E03B98,$05AC.w    ; bel_hook      Ctrl G
            move.l    #$E0378A,$05B0.w    ; kcl_hook      Key Click

E0038C:     bsr       *+$1214             ; INIT_OSH                    $E015A2

            endpart
;******************************************************************************
;*************************************************** Cookies initialisieren ***
_00390:     >PART 'Cookies'

            lea       $0980,A0            ; Startadresse Cookies
            move.l    A0,$05A0.w          ; _p_cookies

;-------------------------------------------------------------- _CPU-Cookie ---

            move.l    #$5F435055,(A0)+    ; "_CPU"
            moveq     #0,D1               ; D1: 0 68000 Default

            movea.w   #$10,A2
            movea.l   (A2),A3             ; Illegal-Vektor sichern
            movea.l   A7,A1               ; Stackpointer sichern
            move.l    #E003D4,(A2)        ; neuer Illegal-Vektor

            dc.w $42C0              ;     ; MOVE CCR,DO     falls kein Illegal:
            moveq     #10,D1              ; D1: 10          mindestens 68010

            dc.w $49C0              ;     ; EXTB.L D0       falls kein Illegal:
            moveq     #20,D1              ; D1: 20          mindestens 68020

            dc.l $4E7A0002          ;     ; MOVEC CACR,D0   falls kein Illegal:
            bset      #9,D0               ; Datencache on
            dc.l $4E7B0002          ;     ; MOVEC D0,CACR       CACR schreiben
            dc.l $4E7A0002          ;     ; MOVEC CACR,D0       CACR lesen
            bclr      #9,D0               ; ist Datencache noch on?
            beq.s     E003D4              ; nein: ist 68020

            moveq     #30,D1              ; D1: 30          mindestens 68030
            dc.l $4E7B0002          ;     ; MOVEC D0,CACR       Datencache off

E003D4:     movea.l   A1,A7               ; Illegal: restore Stackpointer
            move.l    A3,(A2)             ; restore Illegal-Vektor

            move.l    D1,(A0)+            ; CPU-Nr in Cookie eintragen
            sne       $059F.w             ; _longframe setzen bei _CPU<>0

;---------------------------------------------------- _VDO und _MCH Cookies ---

;           bsr       E01806              ; _VDO und _MCH setzen
            bsr       *+$1426             ; _VDO und _MCH setzen         E01806

            bra.s     E003F6

            ds.w 9,-1               ;     ; Rest mit $FF fllen

;-------------------------------------------------------------- _SWI-Cookie ---

E003F6:     move.b    #$7F,D0             ; D0: Default SWI
            tst.b     $0A13               ; GST-MCU vorhanden?
            bne.s     E00412              ; nein: raus hier
;-----------------------------------------
            move.l    #$5F535749,(A0)+    ; "_SWI"
            moveq     #0,D0
            move.w    $FFFF9200.w,D0      ; DIP-Switches einlesen, 8 Bit
            lsr.w     #8,D0               ; ins Low-Byte
            move.l    D0,(A0)+            ; im Cookie eintragen

;-------------------------------------------------------------- _SND-Cookie ---

E00412:     moveq     #3,D1
            move.l    #$5F534E44,(A0)+    ; "_SND"
            btst      #7,D0
            bne.s     E00424

            bclr      #1,D1

E00424:     move.l    D1,(A0)+            ; Wert eintragen

;-------------------------------------------------------------- _FDC-Cookie ---

            btst      #6,D0
            bne.s     E00440              ; kein HD-Laufwerk: raus hier
;-----------------------------------------
            move.b    #8,$1820            ; cmd_flag fr A: Spin-up off
            move.l    #$5F464443,(A0)+    ; "_FDC"
            move.l    #$01415443,(A0)+    ; Wert eintragen

;-------------------------------------------------------------- _FPU-Cookie ---

E00440:     move.l    #$5F465055,(A0)+    ; "_FPU"
            moveq     #0,D1               ; D1: 0 Default: keine FPU
            movea.l   $2C,A1              ; save Line F Vektor
            lea       E00478(PC),A2       ; neuer Line F Vektor
            move.l    A2,$2C              ; eintragen

            dc.w $F327              ;     ; FSAVE  -(A7)
            move.b    1(A7),D0
            cmpi.b    #$18,D0
            beq.s     E00474              ; L0021

            cmpi.b    #$38,D0             ;(#"8")
            beq.s     E00472              ; L0020

            cmpi.b    #$40,D0             ;(#"@")
            bne.s     E00476              ; L0022

            addq.w    #2,D1
E00472:     addq.w    #2,D1
E00474:     addq.w    #2,D1
E00476:     addq.w    #2,D1

E00478:     swap      D1                  ; Line F Interrupt
            move.l    D1,(A0)+            ; Wert eintragen
            move.l    A1,$2C              ; restore Line F Vektor
            bra.s     E00496

            ds.w 9,-1               ; Rest mit $FF auffllen

;------------------------------------------------- FRB anlegen, _FRB-Cookie ---

E00496:     tst.l     $05A4.w             ; ramtop testen
            beq.s     E004B6              ; 0: kein TT-RAM, raus hier

            move.l    #$5F465242,(A0)+    ; "_FRB"
            move.l    $0432.w,D0          ; _membot holen
            move.l    D0,(A0)+            ; wird Startadresse des FRB
            add.l     #$010000,D0         ; L„nge 64 kB aufaddieren
            move.l    D0,$0432.w          ; _membot neu
            move.l    D0,$04FA.w          ; end_os neu

E004B6:     clr.l     (A0)+
            move.l    #$10,(A0)+

            endpart
;******************************************************************************
;************************************************ Exception Vektoren setzen ***
_004BE:     >PART 'Exceptions'

;           lea       $E00D78,A3          ; zeigt auf RTE (PC-Rel)
            lea       *+$08BA(PC),A3      ; zeigt auf RTE (PC-Rel)       E00D78
;           lea       $E00BEE,A4          ; zeigt auf RTS (PC-Rel)
            lea       *+$072C(PC),A4      ; zeigt auf RTS (PC-Rel)       E00BEE

;           lea       $E012C1,A1          ; A1: zeigt auf Bombenroutine
            lea       *+$0D56(PC),A1      ; A1: zeigt auf Bombenroutine  E012C1
            lea       8.w,A0              ; A0: Ziel
            move.w    #61,D0              ; D0: Anzahl: 62 Vektoren

E004D2:     move.l    A1,(A0)+            ; auf Bombenroutine lenken
            dbra      D0,E004D2           ; loop

            move.l    A3,$14.w            ; Vektor $14 auf RTE lenken
            move.l    A3,$7C.w            ; Vektor $7C auf RTE lenken

;------------------------------------------------ Interrupt Vektoren setzen ---

            moveq     #6,D0               ; D0: Anzahl: 7 Vektoren
            lea       $64.w,A1            ; A1: Ziel
E004E6:     move.l    #$E00D78,(A1)+      ; alle auf RTE lenken
            dbra      D0,E004E6           ; loop

;-------------------------------------------------- Trap-Handler einrichten ---

            move.l    #$E00C5A,$70.w      ; vbl-handler
            move.l    #$E00C44,$68.w      ; hbl-handler
            move.l    A3,$88.w            ; trap #2       (= RTE)
            move.l    #$E00DA2,$B4.w      ; trap #13
            move.l    #$E00D9C,$B8.w      ; trap #14
            move.l    #$E0792C,$28.w      ; line-A
            move.l    A4,$0400.w          ; etv_timer     (= RTS)
            move.l    #$E00D98,$0404.w    ; etv_critic
            move.l    A4,$0408.w          ; etv_term      (= RTS)

;-------------------------------------------------------- VBL-Liste l”schen ---

            lea       $04CE.w,A0          ; vbl_list
            move.l    A0,$0456.w          ; _vblqueu
            move.w    #7,D0

E00538:     clr.l     (A0)+
            dbra      D0,E00538           ; loop

;----------------------------- Tabelle xconstat .. xconout ins RAM kopieren ---

            lea       $E01024,A0
            movea.w   #$051E,A1           ; Systemvariable
            moveq     #31,D0              ; D0: Anzahl: 32 Langworte

E0054A:     move.l    (A0)+,(A1)+
            dbra      D0,E0054A           ; loop

;------------------------------------- sys_mask und vme_mask initialisieren ---

            movea.l   8.w,A0              ; Buserror-Vektor retten
            movea.l   A7,A1               ; Stackpointer retten
            move.l    #E0056A,8.w         ; Buserror abfangen
            move.b    #$40,$FFFF8E0D.w    ; vme_mask: IRQ6 enabled
            move.b    #$14,$FFFF8E01.w    ; sys_mask: IRQ4 + IRQ2 enabled

E0056A:     move.l    A0,8.w              ; Buserror restaurieren
            movea.l   A1,A7               ; Stackpointer restaurieren

;------------------------------------------ MFP und Keyboard initialisieren ---

E00570:
;           bsr       E024D6              ; MFP_INIT:
            bsr       *+$1F64             ; MFP_INIT:                    E024D6

            move.w    #$0400,D0           ; Vorteiler: 50, Data: 256  (5ms)
;           bsr       E0162E              ; DELAY_D0: 2.457 MHz
            bsr       *+$10B4             ; DELAY_D0: 2.457 MHz          E0162E

            move.l    #$E00988,-(A7)      ; zeigt auf IKBD_STR
            move.w    #1,-(A7)            ; Anz: 2 Bytes
            jsr       $E02474             ; IKBD_WS: String an IKBD senden  ***
            addq.l    #6,A7

            move.w    #$0700,D0           ; Vorteiler: 200, Data: 256  (20ms)
            move.w    #14,D1              ; 15 * 20ms = 300ms
E00596:
;           bsr       E0162E              ; DELAY_D0: 2.457 MHz
            bsr       *+$1096             ; DELAY_D0: 2.457 MHz          E0162E
            dbra      D1,E00596           ; loop

;-------------------------------------------------------- Cartridge starten ---

            moveq     #2,D0               ; ROM-Modul Typ 2
;           bsr       E00BBC              ; CARTBOOT: starten
            bsr       *+$061A             ; CARTBOOT: starten            E00BBC
;-----------------------------------------
            moveq     #0,D1               ; IRQ-Flag
            btst      #7,$FFFFFA01.w      ; mfp_gpip: Monochrome Monitor Detect
            bne.s     E005B0              ; IFLG_RDY

            moveq     #2,D1

E005B0:
;           bsr       E01764              ; auf aktives DE warten?
            bsr       *+$11B2             ; auf aktives DE warten?       E01764
;-----------------------------------------
            move.b    D1,$044C.w          ; sshiftmd
;           bsr       E01604              ;
            bsr       *+$104A             ;                              E01604

            jsr       $E069F4             ;                                 ***
            jsr       $E0694A             ;                                 ***

            move.l    #$E00030,$046E.w    ; swv_vec   bei Monitorwechsel
            move.w    #1,$0452.w          ; vblsem    Semaphore einschalten
;-----------------------------------------
            clr.w     D0                  ; ROM-Modul Typ 0
;           bsr       E00BBC              ; CARTBOOT: starten
            bsr       *+$05E2             ; CARTBOOT: starten            E00BBC

            move      #$2300,SR           ; Super, IPL3

            moveq     #1,D0               ; ROM-Modul Typ 1
;           bsr       E00BBC              ; CARTBOOT: starten
            bsr       *+$05D8             ; CARTBOOT: starten            E00BBC

            move.l    #E0060A,$20.w       ; Vektor fr Privilegverletzung
            bra       E00706

            endpart
;******************************************************************************
;******************************************** Move SR (Privileged) Emulator ***
_005F2:     >PART 'SR Emulator'

;---------------------------------------------- CLRCACHE  L1-Caches l”schen ---
E005F2:     move      SR,-(A7)            ; SR sichern
            ori       #$0700,SR           ; alle IRQs sperren

            dc.l $4E7A0002          ; MOVEC CACR,D0  Cache-Controlr. lesen
            or.l      #$0808,D0           ; Clear Data- & Instr-Cache
            dc.l $4E7B0002          ; MOVEC D0,CACR  und zurckschreiben

            move      (A7)+,SR            ; SR restaurieren
            rts

;---------------------- PRVL_SR0: Exception-Routine fr Privileg-Verletzung ---

E0060A:     movem.l   D0-D2,-(A7)         ; Einsprung ber Exception 8 Vektor
            move.l    A1,-(A7)
            move.l    A0,-(A7)
            movea.l   22(A7),A0
            move.w    (A0),D0             ; Befehl holen
            move.w    D0,D1
            and.w     #$FFC0,D0
            cmp.w     #$40C0,D0           ; war es ein MOVE from SR?
            bne       E006F8              ; nein: 8 Bomben

;--------------------------- 68000-Befehl MOVE from SR beim 68030 emulieren ---

            move.l    #$30004E71,$0A14.w  ; SysVar
            move.l    #$4E714E75,$0A18.w  ; SysVar

            move.w    D1,D0
            and.w     #7,D0
            lsl.w     #8,D0
            lsl.w     #1,D0
            or.w      D0,$0A14.w
            move.w    D1,D0
            and.w     #$38,D0
            lsl.w     #3,D0
            or.w      D0,$0A14.w
            moveq     #2,D2
            cmp.w     #$0180,D0
            beq       E006F8              ; sonst: 8 Bomben

            tst.w     D0
            beq.s     E006B8

            cmp.w     #$0140,D0
            beq.s     E00682

            cmp.w     #$01C0,D0
            bne.s     E0068A

            and.w     #7,D1
            beq.s     E00678

            addq.w    #2,D2
            move.w    4(A0),$0A18.w
E00678:     addq.w    #2,D2
            move.w    2(A0),$0A16.w
            bra.s     E006DE

E00682:     addq.w    #2,D2
            move.w    2(A0),$0A16.w
E0068A:     and.w     #7,D1
            cmp.w     #7,D1
            bne.s     E006DE

;----------------------------------------------- MOVE.W  SR,(A7)  emulieren ---

            move      USP,A1
            andi.w    #-$0C01,$0A14.w
            add.l     D2,22(A7)
            bsr       E005F2              ; L1 Cache clear, neu gg. TOS 2.06!

            move.w    20(A7),D0
            jsr       $0A14.w

            move      A1,USP
            movea.l   (A7)+,A0
            movea.l   (A7)+,A1
            movem.l   (A7)+,D0-D2
            rte

;------------------------------------------------- MOVE.W  SR,Dn  emulieren ---

E006B8:     add.l     D2,22(A7)
            ori.w     #$10,$0A14.w
            bsr       E005F2              ; L1 Cache clear, neu gg. TOS 2.06!

            lea       20(A7),A0
            movem.l   8(A7),D0-D2
            jsr       $0A14.w

            movea.l   (A7)+,A0
            movea.l   (A7)+,A1
            adda.w    #$0C,A7
            rte

;------------------------------------ MOVE.W  SR,(An)  mit A0..A6 emulieren ---

E006DE:     add.l     D2,22(A7)
            bsr       E005F2              ; L1 Cache clear, neu gg. TOS 2.06!

            movea.l   (A7)+,A0
            movea.l   (A7)+,A1
            move.w    12(A7),D0
            jsr       $0A14.w

            movem.l   (A7)+,D0-D2
            rte

;------------------------------------ Exception 8 Privilegverletzung melden ---

E006F8:     movea.l   (A7)+,A0
            movea.l   (A7)+,A1
            movem.l   (A7)+,D0-D2
            jmp       $E0121C             ; 8 Bomben ausgeben               ***

            endpart
;******************************************************************************
;************************************************ Zeit holen, Atari-Zeichen ***
_00706:     >PART 'Get date'

E00706:     jsr       $E18A6C             ;                                 ***

            move.w    E0001E,$82B6        ; Default: Datum aus TOS-Header

            jsr       $E01F20             ; GET_RTC  Uhrenchip auslesen     ***
            bcc.s     E00736
;-----------------------------------------
;           bsr       E021A4              ; GET_KBT  Keyboard Time lesen
            bsr       *+$1A84             ; GET_KBT  Keyboard Time lesen E021A4
            swap      D0

            tst.b     D0
            beq.s     E00736

            move.w    D0,$82B6            ; W: Datum yyyy.yyym.mmmd.dddd
            swap      D0
            move.w    D0,$575C            ; W: Zeit  hhhh.hmmm.mmms.ssss

;--------------------------------------------------- Atari-Zeichen ausgeben ---

E00736:     clr.b     $FFFFFA19.w         ; TACR  Timer A off
            bclr      #5,$FFFFFA07.w      ; IERA  IRQ off

            move.l    #$3111,D0           ; neu gg 2.06
            dc.l $4E7B0002          ;     ; MOVEC D0,CACR

            movea.l   #$E36018,A0         ; MusterPointer
            movea.l   $044E.w,A1          ; _v_bs_ad
            move.b    $044C.w,D0          ; sshiftmd

            cmp.b     #2,D0               ; 640 * 400 * 1 ST?
            beq.s     E00786              ; ja: jmp

            cmp.b     #6,D0               ; 1280 * 960 * 1 TT?
            beq.s     E00786              ; ja: jmp
;-----------------------------------------
            adda.w    #1280,A1            ; Color: _v_bs_ad + 1280 (2.06: +640)
            move.w    #85,D0              ; „užerer Counter 86

E0076C:     moveq     #5,D1               ; innerer Counter 6
E0076E:     move.w    (A0)+,D2            ; MusterWort holen
            move.w    D2,(A1)+            ; in VideoRam Plane 0
            move.w    D2,(A1)+            ;                   1
            move.w    D2,(A1)+            ;                   2
            move.w    D2,(A1)+            ; 4 Worte * 6       3
            dbra      D1,E0076E
            adda.w    #112,A1
            dbra      D0,E0076C

            bra.s     E0079E
;-----------------------------------------
E00786:     adda.w    #640,A1             ; Mono: _v_bs_ad + 640 (2.06: +320)
            move.w    #85,D0              ; „užerer Counter 86

E0078E:     moveq     #11,D1              ; innerer Counter 12
E00790:     move.b    (A0)+,(A1)+
            dbra      D1,E00790
            adda.w    #68,A1
            dbra      D0,E0078E

;---------------------------------------------------- Cursorposition setzen ---

E0079E:     moveq     #39,D7              ; Cursorpos. fr Color
            tst.b     $044C.w             ; sshiftmd 320 * 200?
            bne.s     E007A8              ; nein: jmp

            moveq     #44,D7              ; Cursorpos. fr Mono
;-----------------------------------------
E007A8:     move.l    #$030002,D6         ; $00030002 = bconout, CON
            move.w    #27,-(A7)           ; "esc"
            move.l    D6,-(A7)
            trap      #13

            move.w    #'Y',4(A7)          ; "Y"  Cursor Pos. y,x
            move.l    D6,(A7)
            trap      #13

            move.w    D7,4(A7)            ; y-Wert
            move.l    D6,(A7)
            trap      #13

            move.w    #32,4(A7)           ; x-Wert
            move.l    D6,(A7)
            trap      #13
            addq.w    #6,A7

            endpart
;******************************************************************************
;******************************************************** ROM-TOS CRC-Check ***
_007D4:     >PART 'CRC Check'

            move.l    #$01FFFE,D7         ; D7: Anzahl Bytes: 128 kB
            move.w    #3,D6               ; D6: Anzahl ROM-Chips: 4
            movea.l   #E00000,A5          ; A5: Chip Basisadresse even/upper

E007E4:     move.w    #4,-(A7)            ; step
            move.l    D7,-(A7)            ; count
            move.l    A5,-(A7)            ; start
;           bsr       E01724              ; CALC_CRC: CRC berechnen
            bsr       *+$0F36             ; CALC_CRC: CRC berechnen      E01724
            adda.w    #10,A7

            movea.l   A5,A0               ; Chip Basisadresse
            adda.l    #$07FFF8,A0         ; A0: zeigt auf vorletztes Byte
            move.b    (A0),D1             ; CRC High-Byte lesen
            lsl.w     #8,D1               ; an die richtige Pos. schieben
            move.b    4(A0),D1            ; CRC Low-Byte lesen
            cmp.w     D1,D0               ; gleich dem berechneteten Wert?
            bne.s     E00832              ; nein: dann Alarm schlagen

            addq.l    #1,A5               ; ja: der n„chste ROM-Chip
            dbra      D6,E007E4           ; alle durch?
            bra.s     E00886              ; dann weiter im Plan   >L0040

;------------------------------------------------------------------ Strings ---

E00810:     dc.b 'WARNING: BAD ROM CRC IN CHIP ',0

E0082E:     dc.b '.',cr,lf,0

;---------------------------------------------- Meldung ausgeben und h„ngen ---

E00832:     move.l    A5,D5               ;
            pea       E00810              ; zeigt auf "WARNING: BAD ROM.."
            move.w    #9,-(A7)            ; cconws
            trap      #1                  ; gemdos

            move.b    #'E',D0             ; "E" fr even
            btst      #0,D5               ; ROM-Chip Adressbit 0 even?
            beq.s     E0084E              ; ja: jmp

            move.b    #'O',D0             ; nein: dann "O" fr odd

E0084E:     move.w    D0,2(A7)            ; "E" oder "O"
            move.w    #2,(A7)             ; cconout
            trap      #1                  ; gemdos

            move.b    #'E',D0             ; "E" fr even
            btst      #1,D5               ; ROM-Chip Adressbit 1 even?
            beq.s     E00866              ; ja: jmp

            move.b    #$4F,D0             ; nein: dann "O" fr odd

E00866:     move.w    D0,2(A7)            ; "E" oder "O"
            move.w    #2,(A7)             ; cconout
            trap      #1                  ; gemdos

            move.l    #E0082E,2(A7)       ; zeigt auf ".",cr,lf
            move.w    #9,(A7)             ; cconws
            trap      #1                  ; gemdos
            addq.w    #6,A7

            addq.l    #1,A5               ; Leiche?

E00882:     dbra      D6,E007E4           ; insgesamt 4 Durchl„ufe

            endpart
;******************************************************************************
;************************************************* GEM oder COMMAND starten ***
_00886:     >PART 'GEM Start'

E00886:     cmpi.b    #2,$044C.w          ; sshiftmd = 640x400 Mono?
            beq.s     E008BC              ; ja: jmp

            move.l    #$0BFFFF,-(A7)      ; Bios(11) Kbshift(-1)
            trap      #13                 ; Tastaturstatus holen
            addq.w    #4,A7
            btst      #3,D0               ; Alternate gedrckt?
            beq.s     E008BC              ; nein: jmp
;-----------------------------------------
            clr.w     -(A7)               ; res Aufl. 320x200 setzen
            pea       $FFFFFFFF.w         ; physLoc nicht „ndern
            pea       $FFFFFFFF.w         ; logLoc nicht „ndern
            move.w    #5,-(A7)            ; Xbios(5) Setscreen
            trap      #14
            adda.w    #12,A7

            move.l    #$0808,D0
            dc.l $4E7B0002          ;     ; MOVEC D0,CACR

;------------------------------------------------------------------------------

E008BC:     bsr       E0098A              ; FDD_BOOT  Bootsektor von A:
            bsr       E009A2              ; HDD_WAIT  RAM-Test, Wartebalken
;           bsr       *+$E0               ; HDD_WAIT  RAM-Test, Wartebalken
;           bsr       E01530              ; SCAN_TSR  resetfeste Progs
            bsr       *+$0C6A             ; SCAN_TSR  resetfeste Progs   E01530

            tst.w     $0482               ; _cmdload  'COMMAND.PRG' laden?
            beq.s     E008EE              ; nein: jmp

;------------------------------------------------- ggf. COMMAND.PRG starten ---

;           bsr       E0133C              ; AUTOEXEC: Auto-Progs starten
            bsr       *+$0A6A             ; AUTOEXEC: Auto-Progs starten E0133C

            move.l    #E00000,$04F2       ; _sysbase setzen
            pea       E00985(PC)          ; environment: zeigt auf 0
            pea       E00985(PC)          ; commandline: zeigt auf 0
            pea       E00972(PC)          ; path: zeigt auf "COMMAND.PRG"
            clr.w     -(A7)               ; mode: Load and Go
            bra.s     E00956

;----------------------------------- oder Environment String initialisieren ---

E008EE:
;           bsr       E0133C              ; AUTOEXEC: Auto-Progs starten
            bsr       *+$0A4C             ; AUTOEXEC: Auto-Progs starten E0133C

            move.l    #E00000,$04F2       ; _sysbase setzen
            lea       E00966(PC),A0       ; A0: zeigt auf "PATH="
            movea.l   #$0840,A1           ; A1: zeigt auf Environment Buffer

E00906:     cmpi.b    #'#',(A0)           ; Platzhalter "#" erreicht?
            bne.s     E0090E              ; nein: weiterkopieren
            movea.l   A1,A2               ; ja: Adresse merken
E0090E:     move.b    (A0)+,(A1)+         ; Environment in Buffer kopieren
            bpl.s     E00906              ; loop

            move.w    $0446,D0            ; _bootdev
            add.b     #$41,D0             ; in ASCII
            move.b    D0,(A2)             ; statt '#' in Environment Buffer

;---------------------------------------------------------- und GEM starten ---

            pea       $0840               ; environment: zeigt auf Env.Buffer
            pea       $E00985             ; commandline: zeigt auf 0
            pea       89(PC)              ; path: zeigt auf 0
            move.w    #5,-(A7)            ; mode: create basepage
            move.w    #$4B,-(A7)          ; pexec
            trap      #1                  ; gemdos
            adda.w    #14,A7
            movea.l   D0,A0               ; A0: Adresse der Basepage

            move.l    $04FE,8(A0)         ; exec_os  Aufrufende Shell eintragen
            pea       $0840               ; environment: zeigt auf Env.Buffer
            move.l    A0,-(A7)            ; Adresse Basepage
            pea       E00985(PC)          ; path: zeigt auf 0
            move.w    #4,-(A7)            ; mode: just Go

;-------------------------------------- hier geht es wieder zusammen weiter ---

E00956:     move.w    #75,-(A7)           ; pexec
            trap      #1                  ; gemdos
            adda.w    #14,A7
            jmp       $E00030

;------------------------------------------------------------------------------

E00966:     dc.b 'PATH=',0,'#:\',0,0,255

E00972:     dc.b 'COMMAND.PRG',0

E0097E:     dc.b 'GEM.PRG'

E00985:     dc.b 0,0,0,$80,1

            endpart
;******************************************************************************
            end