; Junior Prommer Resourcen
; (c) Merlin Computer   KICKSTART
; erstellt am 20.3.88
; R.Hofmann
; Aufruf: Return = Junior (Funktion,P1,P2....);
;
; Aztec C 3.6
; as junior -N -C -D

max_f   equ 11

strobe  equ %01000000

azb     equ %00010000
lazb    equ %00000100

ciaapb  equ $bfe101
ciabpa  equ $bfd000
ciaapbd equ $bfe301

bpe     equ 82

; Indizies in die Typentabelle
; 82 Bytes/Eintrag

zkette  equ 0
kapazi  equ 30
seite   equ 34
alg     equ 38
i_zeit  equ 40
m_zeit  equ 42
trials  equ 44
standby equ 46
read    equ 48
odis    equ 50
program equ 52
pr_ver  equ 54
pr_inh  equ 56
page_wr equ 58
manufac equ 60
devcode equ 61
tsmask  equ 62
frei3   equ 63
frei1   equ 64
frei2   equ 66

m_a10   equ 68
m_a11   equ 70
m_a12   equ 72
m_a13   equ 74
m_a14   equ 76
m_a15   equ 78
m_a16   equ 80

      cseg
      public _Junior
      public _WaitForTimer

_Junior:
        movem.l d1-d7/a0-a6,save        ; Hauptverteiler
        lea 6(a7),a5                    ; Parameterbasis
        move.w -2(a5),d0
        cmp.w #max_f,d0
        bhi  f_err
        lsl.w #2,d0
        lea f_adr,a0

        movea.l 0(a0,d0.w),a0
        jsr  (a0)

ende:   movem.l save,d1-d7/a0-a6
        rts
f_err:  move.l $12345678,d0
        bra    ende

        dseg

; Zeiger auf Funktionen
f_adr:  dc.l srx                        ; 0=SRX 
        dc.l srd                        ; 1=SRD
        dc.l az                         ; 2=AZ
        dc.l setzea                     ; 3=SETZEA
        dc.l lese                       ; 4=LESEN
        dc.l ltest                      ; 5=LTEST
        dc.l vergl                      ; 6=VERGL
        dc.l vtest                      ; 7=VTEST
        dc.l ipro                       ; 8=PROG
        dc.l tstest                     ; 9=TRTEST
        dc.l waltp                      ; 10=TYP
        dc.l init                       ; 11=INIT

        cseg  

sra:    movem.l d0/d2,-(sp)
        moveq #2,d1
        or.b adrsra,d0
        move.w d0,-(sp)
        bsr srxd                        ; Byte herausschieben
        move.w (sp),d0                  ; alter Wert
        move.b d0,d1
        and.b #%11100000,d0             ; Testen auf Aenderung
        move.b letzt_a2,d2
        and.b #%11100000,d2
        cmp.b d0,d2
        beq  ta15                       ; Alles gleich
        scs d2
        move.w #1000,d0                 ; 0.1s Verzoegerung
        tst.b d2
        bne  zver
        move.w #8000,d0                 ; 0.8s Verzoegerung
zver:   bsr zeit
ta15:   and.b #1,d1                     ; A15 auf Aenderung testen
        move.b letzt_a2,d0
        and.b #1,d0
        cmp.b d0,d1
        beq  uspr                       ; Alles gleich
        moveq #50,d0                    ; 5 mS Verzoegerung
        bsr zeit
uspr:   move.w (sp)+,d0                 ; Alter Vergleichswert
        move.b d0,letzt_a2              ; als Byte
        movem.l (sp)+,d0/d2
        move.b d0,letzt_a
        rts

srb:    moveq #4,d1                     ; Taktbit
        move.b d0,letzt_b
        or.b adrsrb,d0                  ; Adressen
        eori.b #%01000000,d0            ; A13 invers
        bra  srxd

src:    moveq #8,d1                     ; Datenschieberegister
        bra  srxd

srx:    move.w (a5),d0                  ; Daten
        moveq #1,d1
decoder: lsl.w #1,d1
        subq.w #1,2(a5)                 ; Takt
        bne  decoder

; Bedient Schieberegister SRA bis SRC
srxd:   movem.l d2-d3/a0,-(sp)
        lea ciaapb,a0
        
        move.w rwstat,d3
        move.w d3,d2                    ; 1.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)
        move.w d3,d2                    ; 2.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)
        move.w d3,d2                    ; 3.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)
        move.w d3,d2                    ; 4.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)
        move.w d3,d2                    ; 5.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)
        move.w d3,d2                    ; 6.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)
        move.w d3,d2                    ; 7.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)
        move.w d3,d2                    ; 8.Bit
        roxl.b #1,d0
        roxr.b #1,d2
        move.b d2,(a0)
        or.b d1,d2
        move.b d2,(a0)

        or.b #strobe,(a0)               ; Strobe =1
        and.b #255-strobe,(a0)          ; Strobe = 0
        movem.l (sp)+,d2-d3/a0
        rts

srd:           
; Bedient srd
srdd:   movem.l d3-d5/a1-a2,-(sp)       ; Eingangsschieberegister lesen
        lea ciaapb,a1
        move.b (a1),d3                  ; Strobeimpuls geben
        or.b #strobe,(a1)
        lea ciabpa,a2
        and.b #255-strobe,(a1)          ; Strobe low
        moveq #32,d3                    ; Register vorbesetzen

        moveq #0,d4
        moveq #0,d0

        move.b (a2),d5                  ;1
        roxr.b #1,d5
        move.b d3,(a1)
        addx.w d0,d0
        move.b d4,(a1)

        move.b (a2),d5                  ;2
        roxr.b #1,d5
        move.b d3,(a1)
        addx.w d0,d0
        move.b d4,(a1)

        move.b (a2),d5                  ;3
        roxr.b #1,d5
        move.b d3,(a1)
        addx.w d0,d0
        move.b d4,(a1)

        move.b (a2),d5                  ;4
        roxr.b #1,d5
        move.b d3,(a1)
        addx.w d0,d0
        move.b d4,(a1)

        move.b (a2),d5                  ;5
        roxr.b #1,d5
        move.b d3,(a1)
        addx.w d0,d0
        move.b d4,(a1)

        move.b (a2),d5                  ;6
        roxr.b #1,d5
        move.b d3,(a1)
        addx.w d0,d0
        move.b d4,(a1)

        move.b (a2),d5                  ;7
        roxr.b #1,d5
        move.b d3,(a1)
        addx.w d0,d0
        move.b d4,(a1)

        move.b (a2),d5                  ;8
        roxr.b #1,d5
        addx.w d0,d0

        not.b d0                        ; Datenwort invertieren
        movem.l (sp)+,d3-d5/a1-a2
        rts

        
az:     tst.w (a5)                      ; Adresszaehler inkrement./loeschen
        beq lazd

; Adresszaehler erhoehen
azd:    ori.b #azb,ciaapb
        and.b #255-azb,ciaapb
        rts

; Adresszaehler loeschen
lazd:   move.b letzt_a,d0
        move.w d0,-(sp)
        or.b #lazb,d0
        bsr sra
        move.w (sp)+,d0
        and.b #255-lazb,d0
        bsr sra
        rts

setzea: move.w (a5),d0                  ; Eingabe / Ausgabestatus setzen
        and.w #1,d0

; setzt E/A Status
setzead: move.b d0,ciaapb
        lsl.w #1,d0
        move.w d0,rwstat
        rts

; setzt Adresse in d0 auf den virtuellen Speicher
setzadr: movem.l d1-d4/a0/a1,-(sp)
        move.l d0,d2
        move.l typzeig,a1
wdh:    cmp.l istadr,d2
        beq  stimmt
        bhi  gr
        clr.l istadr
        bsr lazd
        bra nerh
gr:     addq.l #1,istadr            ; Adresse erhoehen
        bsr azd                         ; Adresszaehler auch
nerh:   move.l istadr,d1
        lsr.l #8,d1
        lsr.l #2,d1
        cmp.l letzta10,d1           ; gleiche Adresse ??
        beq  wdh                       ; Ja,dann unnoetig
        tst.l seite(a1)                 ; gebankter Speicher
        beq  kbea
        move.l istadr,d3
        divu seite+2(a1),d3             ; Seite errechnen
        cmp.w aseite,d3             ; gleich der Bisherigen ?
        beq  kbea
        move.w d3,aseite
        bsr seitesz
kbea:   move.l d1,letzta10          ; jetzt gleich
        move.l a1,a0
        add.w #m_a10,a0
        moveq #6,d0                     ; maximal 7 Adresspins
        clr.w d3
        clr.w d4
setzax: lsr.w #1,d1                     ; Adresse
        bcc  axnull
        or.b (a0),d3                    ; SRA
        or.b 1(a0),d4                   ; SRB
axnull: addq.l #2,a0
        dbra d0,setzax
        move.b d3,adrsra            ; Oder-Adressen
        move.b d4,adrsrb
        move.b letzt_a,d0           ; Adresse aktualisieren
        movem.l a0-a1,-(sp)
        bsr sra
        move.b letzt_b,d0
        bsr srb
        movem.l (sp)+,a0-a1
        bra wdh
stimmt: movem.l (sp)+,d1-d4/a0/a1
        rts

seitesz: movem.l d0-d3/a0-a1,-(sp)
        move.l typzeig,a1
        move.w aseite,d0            ; Aktuelle Speicherbank
        bsr src                         ; Auf den Datenbus
        moveq #1,d0
        bsr setzead                     ; Schreiben
        move.b letzt_a,d2           ; SRA
        move.b letzt_b,d3           ; SRB
        move.b d2,d0
        andi.b #%11100111,d0            ; evtl. Progammiersp. ausschalten
        bsr sra
        move.w #100,d0
        bsr zeit                        ; 10 mS Warten
        move.b odis+1(a1),d0
        bsr srb
        move.b page_wr+1(a1),d0
        bsr srb
        move.b odis+1(a1),d0
        bsr srb
        move.b d2,d0
        bsr sra
        move.b d3,d0
        bsr srb
        move.w #20,d0
        bsr zeit                        ; 2mS Warten
        moveq #0,d0
        bsr setzead
        movem.l (sp)+,d0-d3/a0-a1
        rts

sraus:  move.b d2,d0
        bsr sra
        move.b d3,d0
        bra srb

; Legt Kontrollzustaende bei A0 an den virtuellen Speicher
setzst: move.l a0,-(sp)
        move.b (a0)+,d0
        cmp.b letzt_a,d0
        beq  ubf1
        bsr sra                         ; Schieberegister a
ubf1:   move.b (a0)+,d0
        cmp.b letzt_b,d0
        beq  ubf2
        bsr srb
ubf2:   move.l (sp)+,a0
        rts

; Zeitverzoegerung
zeit:   tst.w d0
        beq  nullzt
        mulu #100,d0                     ; in 0.1ms Schritten
        sub.l #70,d0
        movem.l d1-d7/a0-a6,-(sp)
        movem.l save,d1-d7/a0-a6 ; Environment
        move.l d0,-(sp)          ; An Funktion uebergeben
        jsr _WaitForTimer
        addq.l #4,sp
        movem.l (sp)+,d1-d7/a0-a6
nullzt: rts


; Aktiviert den Speicher und loescht die Adresse
einsch: move.b #$ff,ciaapbd
        clr.l adrsra
        clr.l letzta10
        clr.w letzt_a
        clr.w letzt_a2
        clr.w letzt_b
        clr.w aseite
        moveq #0,d0                     ; Ausgangsschieberegister aus
        bsr setzead
        move.l typzeig,a0           ; Aktuelles EPROM
        add.w #odis,a0                  ; Betriebszustand
        bsr setzst
        bsr seitesz                     ; Falls noetig, Seite loeschen
        clr.l d0                        ; Adresse zuruecksetzen
        bra setzadr

; Inaktiviert den Speicher und loescht die Adresse
aussch: moveq #0,d0
        bsr setzead
        move.l typzeig,a0
        add.w #standby,a0
        bsr setzst
        clr.l d0
        bra setzadr

; Liest den Speicher in den des Rechners
; Parameter : 0/Adresse.l,4/Epromstart,8/Epromende
lese:   move.l (a5),a2                  ; Speicheradresse
        move.l 4(a5),d3                 ; Epromstart
        move.l 8(a5),d4                 ; Epromende
        bsr einsch                      ; Speicher aktivieren
        move.l typzeig,a0
        add.w #read,a0
        bsr setzst
lesesc: move.l d3,d0
        bsr setzadr                     ; Adresse setzen
        bsr srd                         ; Datenwort reischieben
        move.b d0,(a2)+
        addq.l #1,d3
        cmp.l d3,d4
        bcc  lesesc
        bsr aussch
        move.l d3,d0
        subq.l #1,d0
        rts

; Macht Leertest des Speichers
; Parameter : 0/Epromstart,4/Epromende
ltest:  move.l 0(a5),d3                 ; Epromstart
        move.l 4(a5),d4                 ; Epromende
        bsr einsch                      ; Speicher aktivieren
        move.l typzeig,a0
        add.w #read,a0
        bsr setzst
ltsc:   move.l d3,d0
        bsr setzadr                     ; Adresse setzen
        bsr srd                         ; Datenwort reischieben
        cmp.b #$ff,d0                   ; Leertest
        bne  ltf
        addq.l #1,d3
        cmp.l d3,d4
        bcc  ltsc
        bsr aussch
        move.l d3,d0
        subq.l #1,d0
        rts
ltf:    bsr aussch
        move.l d3,d0
        subq.l #1,d0
        bset #31,d0
        rts

; Vergleicht den Speicher mit dem des Rechners
; Parameter : 0/Adresse.l,4/Epromstart,8/Epromende
vergl:  move.l (a5),a2                  ; Speicheradresse
        move.l 4(a5),d3                 ; Epromstart
        move.l 8(a5),d4                 ; Epromende
        bsr einsch                      ; Speicher aktivieren
        move.l typzeig,a0
        add.w #read,a0
        bsr setzst
vgsc:   move.l d3,d0
        bsr setzadr                     ; Adresse setzen
        bsr srd                         ; Datenwort reischieben
        cmp.b (a2)+,d0
        bne  vgf
        addq.l #1,d3
        cmp.l d3,d4
        bcc  vgsc
        bsr aussch
        move.l d3,d0
        subq.l #1,d0
        rts
vgf:    bsr aussch
        move.l d3,d0
        subq.l #1,d0
        bset #31,d0
        rts

; Fuerht einen Vertraeglichkeitstest der Daten aus
; Parameter : 0/Adresse.l,4/Epromstart,8/Epromende
vtest:  move.l (a5),a2                  ; Speicheradresse
        move.l 4(a5),d3                 ; Epromstart
        move.l 8(a5),d4                 ; Epromende
        bsr einsch                      ; Speicher aktivieren
        move.l typzeig,a0
        add.w #read,a0
        bsr setzst
vtsc:   move.l d3,d0
        bsr setzadr                     ; Adresse setzen
        bsr srd                         ; Datenwort reischieben
        not.b d0                        ; invertieren
        and.b (a2)+,d0
        bne  vtf
        addq.l #1,d3
        cmp.l d3,d4
        bcc  vtsc
        bsr aussch
        move.l d3,d0
        subq.l #1,d0
        rts
vtf:    bsr aussch
        move.l d3,d0
        subq.l #1,d0
        bset #31,d0
        rts

; Programmierroutine
ipro:   move.l (a5),a3                  ; Speicheradresse
        move.l 4(a5),d3                 ; Epromstartadresse
        move.l 8(a5),d4                 ; Epromendadresse
        move.w 12(a5),d5                ; $ff-Flagge
        bsr einsch                      ; Speicher aktivieren
        move.l typzeig,a4
progby:
        move.l d3,d0
        bsr setzadr                     ; Adresse
        move.b (a3),d0
        tst.w d5                        ; $FF Ueberspringen ??
        bne  uff
        cmpi.b #$ff,d0
        beq ladr
uff:    bsr src                         ; An das Eprom
        clr.w d2                        ; Versuchszaehler
ippuls:
        lea pr_inh(a4),a0
        bsr setzst
        moveq #1,d0
        bsr setzead
        lea program(a4),a0
        bsr setzst                      ; Programmierpuls
        move.w i_zeit(a4),d0
        bsr zeit                        ; Verzoegerung
        lea pr_inh(a4),a0
        bsr setzst                      ; aus
        addq.w #1,d2                    ; Versuchszaehler
        cmp.w trials(a4),d2             ; Vergleichen
        beq  lpuls
        moveq #0,d0
        bsr setzead
        lea pr_ver(a4),a0               ; Daten Vergleichen
        bsr setzst
        bsr srd
        cmp.b (a3),d0
        bne  ippuls                    ; Nochmal
lpuls:  tst.w m_zeit(a4)                ; Multiplikationsfaktor
        beq  nichts
        lea pr_inh(a4),a0
        bsr setzst
        moveq #1,d0
        bsr setzead
        lea program(a4),a0              ; 2. Programmierpuls
        bsr setzst
        move.w d2,d0
        mulu m_zeit(a4),d0              ; Multiplikationsfaktor
        bsr zeit
        lea pr_inh(a4),a0
        bsr setzst
nichts: cmp.w trials(a4),d2             ; Maximalzeit ?
        bne  ladr
        moveq #0,d0
        bsr setzead                      ; Daten einlesen
        lea pr_ver(a4),a0
        bsr setzst
        bsr srd
        cmp.b (a3),d0
        bne pfeh
ladr:
        addq.l #1,d3                    ; Epromadresse
        addq.l #1,a3                    ; Speicheradresse
        cmp.l d3,d4
        bcc progby                      ; Bis zur Epromendadresse
        bsr aussch                      ; Speicher abschalten
        move.l d3,d0
        subq.l #1,d0
        rts
pfeh:   bsr aussch
        move.l d3,d0
        subq.l #1,d0
        bset #31,d0
        rts

waltp:  move.l (a5),typzeig         ; Typenzeiger setzen
        bsr einsch
        bra aussch

; Prueft die Treiberfaehigkeit des eingesetzten Speichers

tstest: bsr einsch                      ; Aktivieren
        move.l typzeig,a4
        clr.l d0
        bsr setzadr
        lea read(a4),a0                 ; Lesestatus
        bsr tstbd
        move.b d3,d5
        move.b d4,d6
        lea odis(a4),a0
        bsr tstbd
        tst.b d3
        beq  ed
        tst.b d4
        beq  ed
        tst.b d5
        beq  ed
        tst.b d6
        beq  ed
        bsr aussch
        moveq #2,d0
        rts

ed:     cmp.b d5,d6
        bne  fehl
        cmp.b d3,d4
        beq  fehl
        bsr aussch
        moveq #0,d0
        rts
fehl:
        bsr aussch
        moveq #1,d0
        rts


tstbd:  move.l a0,-(sp)
        bclr #1,(a0)
        bsr setzst
        bsr srd
        btst #7,d0
        seq d3
        move.l (sp)+,a0
        bset #1,(a0)
        bsr setzst
        bsr srd
        btst #7,d0
        seq d4
        rts


init:   move.b #$ff,ciaapbd
        clr.l letzta10
        clr.l adrsra
        clr.l letzt_a
        clr.w letzt_b
        lea inaktiv,a0
        bsr setzst
        clr.l d0
        bra setzadr

   dseg
   
inaktiv: dc.b 0
         dc.b 0
        
stopikb: dc.b $13
startikb: dc.b $11

; lokale Variablen

ergebnis: dc.l $23443333
alt_ssp: dc.l $23334440
alt_sr:  dc.l $0
rwstat:  dc.w $2323
aseite:  dc.w 0

save:    dc.l 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
istadr:  dc.l $44444444
typzeig: dc.l $44444444
adrsra:  dc.w 0
adrsrb:  dc.w 0
letzt_a: dc.w 0
letzt_a2: dc.w 0
letzt_b: dc.w 0

letzta10: dc.l 1


