1 REM Ins{nd av Kristoffer Eriksson <5357>    1986-05-30 02.57.34
keymi; Fil: KEYMINIK.ASM (Av KEYK.ASM)
; Av:  Kristoffer Eriksson, "SKE", ABC-klubben <5357>, 1985
; F}r kopieras samt anv{ndas i icke-kommersiella program.
;
;-Ver--/-Datum----/-Sign-/-Kommentar-----------------------------
;  -   / 84-10-22 / SKE  / Fullst{ndiga KEY.
; 1.0  / 85-10-22 / SKE  / Mini-key utan tangentprogrammering.
; 1.1  / 86-05-15 / SKE  / Initieringen omstuvad f|r m|jligg|ra stackladdn.
;
; K{rnan (grundrutinerna) i tangentbordsbufferten KEYMINI.
; Helt utan omprogrammering av tangenter.
; De buffertrutiner som h{r anv{nds {r p} intet s{tt s{rskilt optimala
; eller smarta. De h{rstammar fr}n KEY's f|reg}ngare fr}n ca 1984.
;
; Stack in: Ytterst: Buffertl{ngd, Ladda/ej.
; Struktur: A.  CONSI-rutin.
;           B.  Avbrottsrutin.
;           C.  Ber{kna BUFSLUT. (INIT1)
;               POP buffertl{ngd.
;           D.  Kontrollera om rutinen redan finns. Justera d} Ladda/ej,
;               och skippa D. (INIT2) POP+PUSH
;           E.  Kontrollera ev dubbelladdning. Spara pekare. (INIT3)
;           F.  Initiera CONSI, avbrott, knappklick. (I1.LOAD)
; Stack ut: Ladda/ej.


DOSBUF:   = 62720
CTRLCPTR: = 65413               ; Pekar normalt p} Y.INT
CONSI:    = 65424               ; Hopp till inbyggd teckenl{sning
KEYINT:   = 65460               ; Adress till inbyggd avbrottsrutin
KEYFLG:   = 65506
KEYCHR:   = 65507

          EXPORT BUFFERT, BUFPEK, BUFSLUT, KLEN, INITKLEN
START:
SAVPTR.CI:DEFW  0               ; H{r direkt f|re nya CONSI sparas de gamla
SAVPTR.KI:DEFW  0               ; pekarna f|r CONSI och KEYINT, s} man kan
                                ; }terfinna dem och l{nka ur det hela.

;------------------------------------- CONSI -----
CONSI.NY: PUSH HL               ; Anrop
          PUSH DE
          PUSH BC
$$CONSI:  CALL 0                ; L{gg in datorns egen CONSI-adr.
          PUSH AF               ; Tkn fr KEYCHR, har redan genomg}tt progr.
          DI
          CALL GETTKN
          JR NC C.]TER
          LD    (KEYCHR),A
C.X1:     LD    A,128
          LD    (KEYFLG),A      ; Tecken-finns-att-h{mta-flagga.
C.]TER:   EI
          POP  AF
          POP  BC
          POP  DE
          POP  HL
          RET

GETTKN:   LD   A,(KEYFLG)       ;------- Tecken -> A --------
          ADD  A
          CCF
          RET  NC               ; ]terhopp om nytt tkn inkommet i KEYCHR

          LD   A,(BUFFERT)      ; L{s tecken fr}n buffert.
          EX   AF,AF'           ; A'=H{mtat tecken.
          CALL  BUFTOM?
          RET  Z                ; Inga fler tecken i bufferten, NC.
EJTOM:    LD   B,H              ; BC <- (BUFPEK) - BUFFERT
          LD   C,L
          DEC  DE               ; Minska buffertpekaren.
          LD   (BUFPEK),DE
          LD   DE,BUFFERT       ; Ta bort f|rsta tecknet i buf.
          LD   H,D
          LD   L,E
          INC  HL
          LDIR
          EX   AF,AF'
          SCF
          RET

;---------------------------------------
; Testa om bufferten {r tom, i s} fall Z och NC.
; OBS: Anv{nds f|r att testa om programmet redan {r laddat, och m}ste ligga
; direkt f|re KEYINT.NY.
BUFTOM?:  LD    HL,(BUFPEK)     ; Anv av KEYINT.NY och CONSI.NY
          PUSH  HL
          LD    DE,BUFFERT
$$CHECK:  AND   A
          SBC   HL,DE
          POP   DE              ; DE <- (BUFPEK), HL = Antal tkn i buff
          RET                   ; Z betyder bufferten tom

;---------------------------------------
KEYINT.NY:PUSH  AF               ; Avbrottsrutin f|r tangb.
          PUSH  HL
          PUSH  BC
          PUSH  DE
$$KLICK1: IN    A,(5)            ; Kan bytas mot NOP om klick ej |nskas.
          IN    A,(34)
          LD    B,A
          SUB   3
          JR    Z   CTRLC        ;(OBS A=0)
          CALL  BUFTOM?
          LD    H,D              ; HL<-(BUFPEK)
          LD    L,E
          LD    A,(KEYFLG)       ; Tom & KEYFLG => buffra
          AND   A                ; BUFMODE = 0 => ej buffra
          JR Z  NORMAL
          PUSH  HL
          LD    DE,(BUFSLUT)
          SBC   HL,DE            ; (NC fr}n AND A)
          POP   HL
          JR    NC  Q.AVSL       ; G|r inget om bufferten {r full.
OK:       LD    (HL),B           ; Lagra tecknet i bufferten.
          INC   HL
          JR    Q.AVSL
CTRLC:    LD    HL,(CTRLCPTR)
          SET   0,(HL)           ; CTRL-C-flagga.
          LD    HL,BUFFERT       ; T|m bufferten.
NORMAL:   LD    A,B
          LD    (KEYCHR),A
Q.AVSL:   LD    (BUFPEK),HL
          LD    A,128
          LD    (KEYFLG),A
Q.]TER:
$$KLICK2: IN    A,(5)
          POP   DE
          POP   BC
          POP   HL
          POP   AF
          EI
          RETI

;---------------------------------------------
BUFPEK:   DEFW  BUFFERT
BUFSLUT:  DEFW  0           ; L{gg in adress f|rsta byte efter buf.
BUFFERT:                    ; OBS sista byte m}ste vara 255.

;!                    (BUFPEK)       (BUFSLUT)
;!  Buffert: .Text....   v    inget...  .v

;_Initiering                   _
;*   Initieringen utf|rs i tre delmoduler f|r att ingen ska beh|va bli s}
;*   v{rst l}ng, vilket annars skulle st{lla till problem vid laddning till
;*   stacken, eftersom minnet en liten bit fram inte f}r skadas.

;*   H{r st{lls buffertens l{ngd.
INIT1:    POP   HL
          POP   BC              ; \nskad Buffertl{ngd lyfts fr}n stacken.
          PUSH  HL
          LD    HL,BUFFERT
          ADD   HL,BC           ; HL <- F|rsta byte efter buf.
          LD    (BUFSLUT),HL
          RET

;*   H{r utf|rs kontroll mot dubbel-laddning, samt st{lls SAVPTR.xx.
INIT2:    POP   HL              ; Returadress.
          POP   AF              ; Ladda/Ej/Fel -1/0/1 C/NC/NC
          PUSH  AF              ; L{gg tillbaks v{rdena.
          PUSH  HL
          RET   NC
          LD    HL,(CONSI+1)
          LD    (SAVPTR.CI),HL  ; Spara gamla CONSI.
          LD    HL,(KEYINT)
          LD    (SAVPTR.KI),HL  ; Spara gammal avbrottsadress.
          LD    B,KEYINT.NY-$$CHECK+1
          LD    DE,KEYINT.NY
I2.L1:    LD    A,(DE)          ; J{mf|r $$CHECK - KEYINT.NY med det som
          CP    (HL)            ; finns f|re den gamla avbrottsrutinen f|r
          RET   NZ              ; att se om programmet redan finns laddat.
          DEC   DE              ; Se i s} fall till att det inte g|rs.
          DEC   HL
          DJNZ  I2.L1
          POP   HL              ; Returadressen.
          POP   DE              ; Ladda/Ej/Fel -1/0/1 C/NC/NC
          LD    DE,0            ; [ndra till "Ladda Ej, 0, NC"
          PUSH  DE
          JP    (HL)

;*  H{r utf|rs inl{nkningarna.
INIT3:    POP   HL              ; Returadress.
          POP   AF              ; Ladda/Ej/Fel -1/0/1 C/NC/NC
          PUSH  AF              ; L{gg tillbaks v{rdena.
          PUSH  HL
          RET   NC
          LD    HL,(CONSI+1)    ; L{nka om CONSI.
          LD    ($$CONSI+1),HL
          LD    HL,CONSI.NY
          LD    (CONSI+1),HL
          LD    HL,KEYINT.NY    ; L{nka om tangentbordsavbrottet.
          LD    (KEYINT),HL
          LD    A,(PARKLICK)
          CP    "J"
          RET   Z               ; Ingen }tg{rd om klick |nskas.
          LD    HL,0
          LD    ($$KLICK1),HL   ; Ta bort klick-instruktionerna (INP 5)
          LD    ($$KLICK2),HL
          RET

          DEFB  255
          DEFM  "PARM:Knappklick?"
          DEFB  0,4,"J","N",1   ; Typ=4 (Teckenval), J/N, L{ngd=1
PARKLICK: DEFB  "J"             ; Standard=Klick p}

KLEN:     = BUFFERT - START      ; L{ngd p} rutinerna.
INITKLEN: = PARKLICK - INIT2 + 1 ; L{ngsta initrutinens l{ngd, minsta
          ; till}tna buffertl{ngd vid laddning till stacken. Ingen av
          ; INIT-rutinerna h{r f}r vara l{ngre {n INIT2 i huvudprogrammet,
          ; eftersom INITKLEN antas ange l{nsta l{ngden av alla dessa.
