;
; Ullrich von Bassewitz, 16.09.2001
;
; char cgetc (void);
;

        .export         _cgetc
        .condes         k_blncur, 2
        .import         cursor

        .include        "cbm510.inc"
        .include        "extzp.inc"


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

.proc   _cgetc

        lda     keyidx                  ; Characters waiting?
        bne     L3                      ; Jump if so

; Switch on the cursor if needed

        lda     CURS_FLAG
        pha
        lda     cursor
        jsr     setcursor
L1:     lda     keyidx
        beq     L1
        ldx     #0
        pla
        bne     L2
        inx
L2:     txa
        jsr     setcursor

; Read the character from the keyboard buffer

L3:     ldx     #$00            ; Get index
        ldy     keybuf          ; Get first character in the buffer
        sei
L4:     lda     keybuf+1,x      ; Move up the remaining chars
        sta     keybuf,x
        inx
        cpx     keyidx
        bne     L4
        dec     keyidx
        cli

        ldx     #$00            ; High byte
        tya                     ; First char from buffer
        rts

.endproc

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

.proc   setcursor

        ldy     #$00                    ;
        tax                             ; On or off?
        bne     @L9                     ; Go set it on
        lda     CURS_FLAG               ; Is the cursor currently off?
        bne     @L8                     ; Jump if yes
        lda     #1
        sta     CURS_FLAG               ; Mark it as off
        lda     CURS_STATE              ; Cursor currently displayed?
        sty     CURS_STATE              ; Cursor will be cleared later
        beq     @L8                     ; Jump if no

; Switch to the system bank, load Y with the cursor X coordinate

        lda     #$0F
        sta     IndReg                  ; Access system bank
        ldy     CURS_X

; Reset the current cursor

        lda     CURS_COLOR
        sta     (CRAM_PTR),y            ; Store cursor color
        lda     ExecReg
        sta     IndReg                  ; Switch to our segment
        lda     (SCREEN_PTR),y
        eor     #$80                    ; Toggle reverse flag
        sta     (SCREEN_PTR),y

; Done

@L8:    rts

@L9:    sty     CURS_FLAG               ; Cursor on (Y = 0)
        rts

.endproc


; ------------------------------------------------------------------------
; Blink the cursor in the interrupt. A blinking cursor is only available if
; we use the cgetc() function, so we will export this IRQ handler only in
; case the module is included into a program.


.proc   k_blncur

        lda     CURS_FLAG               ; Is the cursor on?
        bne     curend                  ; Jump if not
        dec     CURS_BLINK
        bne     curend

; Re-initialize the blink counter

        lda     #20                     ; Initial value
        sta     CURS_BLINK

; Load Y with the cursor X coordinate

        ldy     CURS_X

; Check if the cursor state was on or off before

        lda     CURS_COLOR              ; Load color behind cursor
        lsr     CURS_STATE              ; Cursor currently displayed?
        bcs     curset                  ; Jump if yes

; Cursor was off before, switch it on

        inc     CURS_STATE              ; Mark as displayed
        lda     (CRAM_PTR),y            ; Get color behind cursor...
        sta     CURS_COLOR              ; ...and remember it
        lda     CHARCOLOR               ; Use character color

; Set the cursor with color in A

curset: sta     (CRAM_PTR),y            ; Store cursor color
        lda     ExecReg
        sta     IndReg                  ; Switch to our segment
        lda     (SCREEN_PTR),y
        eor     #$80                    ; Toggle reverse flag
        sta     (SCREEN_PTR),y

; Switch back to the system bank

        lda     #$0F
        sta     IndReg

curend: rts

.endproc