;******************************************************************************
;*                                                                            *
;*                          CapsLock Anzeigetreiber                           *
;*                                                                            *
;*                              Stand 17.01.1993                              *
;*                                                                            *
;******************************************************************************

; Zum Betrieb ist die CapsLock-Anzeige Hardware in der Tastatur erforderlich!

;    Autor: Roland Skuplik

;  1993 by WRS Software-Design
;           Hohenzollernstrae 121 / PF 10 29 37
;      4650 Gelsenkirchen 1
;    <0209> 87 30 01 / 81 13 31 (priv.)

;------------------------------------------------------------------------------

caps_anz: pea       copyrght            ; 'Hallo, da bin ich...'
          move.w    #9,-(sp)            ; per CconWs ausgeben
          trap      #1                  ; GEMDOS
          addq.l    #6,sp               ; Stack aufrumen
          pea       install             ; im Supervisor Vektoren installieren
          move.w    #38,-(sp)           ; Opcode
          trap      #14                 ; XBIOS
          addq.l    #6,sp               ; Stack aufrumen
          tst.w     d0                  ; Installation erfolgreich?
          beq.s     weiter              ; ja...
          pea       nixvbl              ; Fehler bei der Installation
          move.w    #9,-(sp)            ; per CconWs
          trap      #1                  ; GEMDOS
          addq.l    #6,sp               ; Stack aufrumen
          move.w    #7,-(sp)            ; CrawcIn (auf Taste warten)
          trap      #1                  ; GEMDOS
          addq.l    #2,sp               ; Stack aufrumen
          clr.w     -(sp)               ; Pterm
          trap      #1                  ; und zurck an's GEMDOS

weiter:   pea       instok              ; Installation erfolgreich
          move.w    #9,-(sp)            ; per CconWs
          trap      #1                  ; GEMDOS
          addq.l    #6,sp               ; Stack aufrumen
          movea.l   4(sp),a0            ; Zeiger auf BASEPAGE abholen
          move.l    #256,d0             ; Basepagelnge als Minimum
          add.l     12(a0),d0           ; dazu Lnge des TextSegments
          add.l     20(a0),d0           ; dazu Lnge des DatenSegments
          add.l     28(a0),d0           ; dazu Lnge des BSS-Segments
          clr.w     -(sp)               ; RET-Code 0, alles OK
          move.l    d0,-(sp)            ; Programm komplett im Speicher halten
          move.w    #49,-(sp)           ; PtermRes
          trap      #1                  ; und tsch...

install:  move.w    $454,d0             ; Anzahl der VBLs ermitteln
          subq.w    #2,d0               ; wegen SysMouseVec und DBRA
          movea.l   $456,a0             ; Zeiger auf VBLs holen
          move.w    d0,d1               ; fr Spter
          movea.l   a0,a1               ; dito
suchvbl:  addq.l    #4,a0               ; ersten berspringen (MAUS)
          tst.l     (a0)                ; frei?
          beq.s     nxsuch              ; ja, dann weiter nach belegten suchen
          movea.l   (a0),a2             ; Vektor holen und reingucken
          cmpi.l    #"CPSL",-8(a2)      ; ist der Eintrag etwa der eigene?
          beq       nxvbl               ; ja, Installation abbrechen
nxsuch:   dbra      d0,suchvbl          ; alle Sloz berprfen
suchslot: addq.l    #4,a1               ; ersten wieder berspringen
          tst.l     (a1)                ; frei?
          beq.s     gefunden
          dbra      d1,suchslot         ; alle Sloz
          cmpi.w    #16,$454            ; >=16 VBLs installiert?
          bge       nxvbl               ; nicht durch dieses Prog erweiterbar
          move.w    $454,d0             ; Anzahl VBLs holen
          subq.w    #1,d0               ; wegen DBRA
          movea.l   $456,a0             ; Zeiger auf VBLs wiederherstellen
          lea       newvbls,a1          ; Zeiger auf neuen VBL-Queue
vblcopy:  move.l    (a0)+,(a1)+         ; kopieren
          dbra      d0,vblcopy
          lea       newvbls,a0          ; nochmal Adresse berechnen
          move.l    a0,$456             ; neue Adresse merken
          move.w    #16,$454            ; jetzt sind's 16 Stck
          bra.s     install             ; neu versuchen

gefunden: move.l    #capsvec,(a1)       ; eigenen Vektor einklinken
          movea.l   $4F2,a0             ; _sysbase aus den SysVars
          cmpi.w    #$100,2(a0)         ; TOS-Version grer 1.00?
          beq.s     old_tos             ; nein, dann stimmt der Defaultwert
          move.l    36(a0),kbshift      ; _pkbshift aus dem OS-Header (ab 1.02)
old_tos:  movea.l   kbshift,a0          ; Adresse der Umschalttastenvariablen
          move.b    (a0),d0             ; Status holen
          andi.b    #16,d0              ; nur CapsLock briglassen
          bsr.s     do_led              ; Status auch zur LED bertragen
          move.l    $5a0,d0             ; Zeiger auf Cookie Jar aus SysVars
          beq.s     nocjar              ; schade, kein Cookie Jar im System
          movea.l   d0,a0               ; Vektor in ein Adressregister rein
          moveq     #1,d1               ; Zhler fr Cookies auf InitWert
lookcook: move.l    (a0)+,d0            ; Cookie holen
          beq.s     cookend             ; war Null, dann ist (a0) Anzahl
          addq.l    #4,a0               ; sonst Wert berspringen
          addq.w    #1,d1               ; Cookiezhler erhhen
          bra.s     lookcook            ; und weitersuchen
cookend:  cmp.l     (a0),d1             ; CookieJar voll?
          beq.s     nocjar              ; ja
          clr.l     4(a0)               ; Anzahl-Cookie verschieben
          move.l    (a0),8(a0)          ; Anzahl verschieben
          move.l    #'CPSL',-4(a0)      ; Eigenen Cookie eintragen
          move.l    #do_led,(a0)        ; Adresse der Anzeigeroutine als Wert
          pea       okcookie            ; Cookie gesetzt
          move.w    #9,-(sp)            ; per CconWs
          trap      #1                  ; GEMDOS
          addq.l    #6,sp               ; Stack aufrumen
          bra.s     iwok
nocjar:   pea       nocookie            ; Cookie NICHT gesetzt
          move.w    #9,-(sp)            ; per CconWs
          trap      #1                  ; GEMDOS
          addq.l    #6,sp               ; Stack aufrumen
iwok:     moveq     #0,d0               ; alles OK
instend:  rts                           ; Installation beendet
nxvbl:    moveq     #-1,d0              ; Fehlerstatus setzen
          bra.s     instend             ; und raus

          dc.b      "XBRA"              ; Kennung fr Vektorverbieger
          dc.b      "CPSL"              ; 'CaPSLock'-Kennung
          dc.l      0                   ; alter Vektor (nur wg. Struktur)
capsvec:  movea.l   kbshift,a0          ; Adresse der Umschalttastenvariablen
          move.b    (a0),d0             ; Status holen
          andi.b    #16,d0              ; nur CapsLock briglassen
          cmp.b     lastcaps,d0         ; verndert?
          beq.s     vblend              ; nein... schnarch...
          bsr.s     do_led              ; Status auch zur LED bertragen
vblend:   rts

; Routine zum bertragen des CapsLock-Status an den IKBD
; Den Vektor zu dieser Routine findet man auch im CookieJar unter 'CPSL'
;  ~> d0.b : anzuzeigender Status (Bit 4)

do_led:   movem.l   d1/a1/a2,-(sp)      ; Register retten
          move.b    d0,lastcaps         ; Status merken
          btst      #4,d0               ; was darf's denn sein?
          bne.s     set_led
clr_led:  lea       ikbd_cl(pc),a1      ; Lsche-Stringadresse laden
          bra.s     mach_hin
set_led:  lea       ikbd_sl(pc),a1      ; Setze-Stringadresse laden
mach_hin: movea.l   #$FFFFFC00,a2       ; Basisadresse IKBD-ACIA
          moveq     #5,d1               ; 6 Bytes zu schreiben
          move      sr,-(sp)            ; Statusregister retten
          ori       #$700,sr            ; IPL7 - keine Strungen
ikbdws:   move.b    (a1)+,d0            ; zu schreibendes Byte holen
wait:     btst      #1,(a2)             ; Senderegister leer?
          beq.s     wait                ; nein... warten...
          move.b    d0,2(a2)            ; Byte an IKBD schreiben
          dbra      d1,ikbdws           ; alle Bytes senden
          move      (sp)+,sr            ; Statusregister restaurieren
          movem.l   (sp)+,d1/a1/a2      ; Register restaurieren
          rts

          data

kbshift:  dc.l      $E1B                ; Adresse des Umschalttastenstatus
lastcaps: dc.b      0                   ; aktuell angezeigter Status
ikbd_cl:  dc.b      32,0,4,1,255,0      ; Load-IKBD-Memory-String zum lschen
ikbd_sl:  dc.b      32,0,4,1,254,0      ; dito zum setzen der CapsLock-LED

copyrght: dc.b      13,10,27,112
          dc.b      " CapsLock-Anzeigetreiber V1.0 07.01.1993, R. Skuplik "
          dc.b      27,113,13,10
          dc.b      " 1993 by WRS Software-Design, <0209> 873001"
          dc.b      13,10,0
instok:   dc.b      "~> Installation erfolgreich.",13,10,0
nixvbl:   dc.b      10,7,27,112
          dc.b      "~> Installation abgebrochen. "
          dc.b      27,113,13,10
          dc.b      "Anpassung bereits vorgenommen oder VBL-Queue nicht "
          dc.b      "erweiterbar..."
          dc.b      13,10,0
okcookie: dc.b      "~> 'CPSL'-Eintrag im Cookie Jar erfolgreich.",13,10,0
nocookie: dc.b      10,7,27,112
          dc.b      "~> 'CPSL'-Eintrag im Cookie Jar fehlt! "
          dc.b      27,113,13,10,0

          bss

newvbls:  ds.l      16                  ; 16 VBLs freihalten

          end

