;-----------------------------------------------------------;
;                                                           ;
; Maths Pack                                                ;
; Version 1.0                                               ;
; Routines                                                  ;
;                                                           ;
;-----------------------------------------------------------;

;------------------------------------------------
; waitKey - Wait for a key press
;
; Input:    None
; Output:   A = Key code (_getcsc style)
;------------------------------------------------
waitKey:
        ei
wKeyLoop:
        halt
        bcall(GET_KEY)
        or      a
        jr      z,wKeyLoop
        ret

;------------------------------------------------
; vPuts - Set pen coords and display a string in small font on gbuf
;
; Input:    DE = New pen coordinates (Y, X)
;           HL => String to display
; Output:   HL => Next string
;------------------------------------------------
vPuts:
        ld      (pencol),de
        bcall(_vputs)
        ret

;------------------------------------------------
; vDispASetPen - Set pen coords and display the value of A on gbuf
;
; Input:    DE = New pen coordinates (Y, X)
;           A = Value to display
; Output:   None
;------------------------------------------------
vDispASetPen:
        ld      (pencol),de

;------------------------------------------------
; vDispA - Display the value of A on gbuf
;
; Input:    A = Value to display
; Output:   None
;------------------------------------------------
vDispA:
        ld      l,a
        ld      h,0
        bcall(_setxxxxop2)
        bcall(_op2toop1)
        ld      a,3
        bcall(_dispop1a)
        ret

;------------------------------------------------
; pushOps - Save a copy of all Op vars
;
; Input:    None
; Output:   None
;------------------------------------------------
pushOps:
        ld      hl,op1
        ld      de,op1Buffer
        ld      bc,11*6
        ldir
        ret

;------------------------------------------------
; pushOp1 - Save a copy of Op1
;
; Input:    None
; Output:   None
;------------------------------------------------
pushOp1:
        ld      hl,op1
        ld      de,op1Buffer
copyOp:
        ld      bc,11
        ldir
        ret

;------------------------------------------------
; pushOp2 - Save a copy of Op2
;
; Input:    None
; Output:   None
;------------------------------------------------
pushOp2:
        ld      hl,op2
        ld      de,op2Buffer
        jr      copyOp

;------------------------------------------------
; pushOp3 - Save a copy of Op3
;
; Input:    None
; Output:   None
;------------------------------------------------
pushOp3:
        ld      hl,op3
        ld      de,op3Buffer
        jr      copyOp

;------------------------------------------------
; pushOp4 - Save a copy of Op4
;
; Input:    None
; Output:   None
;------------------------------------------------
pushOp4:
        ld      hl,op4
        ld      de,op4Buffer
        jr      copyOp

;------------------------------------------------
; pushOp5 - Save a copy of Op5
;
; Input:    None
; Output:   None
;------------------------------------------------
pushOp5:
        ld      hl,op5
        ld      de,op5Buffer
        jr      copyOp

;------------------------------------------------
; pushOp6 - Save a copy of Op6
;
; Input:    None
; Output:   None
;------------------------------------------------
pushOp6:
        ld      hl,op6
        ld      de,op6Buffer
        jr      copyOp

;------------------------------------------------
; popOps - Restore copy of all Ops
;
; Input:    None
; Output:   None
;------------------------------------------------
popOps:
        ld      hl,op1Buffer
        ld      de,op1
        ld      bc,11*6
        ldir
        ret

;------------------------------------------------
; popOp1 - Restore copy of Op1
;
; Input:    None
; Output:   None
;------------------------------------------------
popOp1:
        ld      hl,op1Buffer
        ld      de,op1
        jr      copyOp

;------------------------------------------------
; popOp2 - Restore copy of Op2
;
; Input:    None
; Output:   None
;------------------------------------------------
popOp2:
        ld      hl,op2Buffer
        ld      de,op2
        jr      copyOp

;------------------------------------------------
; popOp3 - Restore copy of Op3
;
; Input:    None
; Output:   None
;------------------------------------------------
popOp3:
        ld      hl,op3Buffer
        ld      de,op3
        jr      copyOp

;------------------------------------------------
; popOp4 - Restore copy of Op4
;
; Input:    None
; Output:   None
;------------------------------------------------
popOp4:
        ld      hl,op4Buffer
        ld      de,op4
        jr      copyOp

;------------------------------------------------
; popOp5 - Restore copy of Op5
;
; Input:    None
; Output:   None
;------------------------------------------------
popOp5:
        ld      hl,op5Buffer
        ld      de,op5
        jr      copyOp

;------------------------------------------------
; popOp6 - Restore copy of Op6
;
; Input:    None
; Output:   None
;------------------------------------------------
popOp6:
        ld      hl,op6Buffer
        ld      de,op6
        jr      copyOp

;------------------------------------------------
; pushOp - Push any Op var to a specified memory location
;
; Input:   HL => Start of Op var
;          DE => Where to push to
; Output:  None
;------------------------------------------------
pushOp          = copyOp

;------------------------------------------------
; popOp - Pop any Op var from a specified memory location
;
; Input:   HL => Start of Op var
;          DE => Where to pop from
; Output:  None
;------------------------------------------------
popOp:
        ex      de,hl
        jr      copyOp

;------------------------------------------------
; putsNewLine - Call _puts then call _newline
;
; Input:    HL => String to display
; Output:   HL => Next string
;------------------------------------------------
putsNewLine:
        bcall(_puts)
        bcall(_newline)
        ret

;------------------------------------------------
; getNumber - Get a number from the user
;
; Input:    DE => Where to store it, eg. op1, op2, etc.
; Output:   None
;------------------------------------------------
getNumber:
        push    de
        ld      de,getNumberBuffer
        xor     a
        ld      (curcol),a
        ld      b,15                            ; B = 15 chars. max
getNumberLoop:
        push    bc                              ; Save counter
        push    de                              ; Save string pointer
        ld      a,'|'
        bcall(_putmap)                          ; Show cursor
        call    waitKey                         ; Wait for a key press
        cp      56                              ; [DEL]
        jr      z,numberBackspace
        cp      9                               ; [ENTER]
        jr      z,endNumber
        dec     a
        ld      e,a
        ld      d,0                             ; DE = Offset in CharTable
        ld      hl,getNumberTable
        add     hl,de
        ld      a,(hl)                          ; A = Character entered
        cp      '+'                             ; If it's a "+", it's an invalid character
        jr      z,invalidNumberChar
        push    af
        bcall(_putc)
        pop     af
        pop     de                              ; Restore string pointer
        ld      (de),a                          ; Save character
        inc     de                              ; DE => Where to store next character
        pop     bc
        djnz    getNumberLoop
        jr      endNumberAfterPop
invalidNumberChar:
        pop     de
        pop     bc
        jr      getNumberLoop
numberBackspace:
        pop     de                              ; Restore string pointer
        pop     bc
        ld      a,b
        cp      15
        jr      z,getNumberLoop
        inc     b
        dec     de
        push    bc
        push    de
        ld      a,' '
        bcall(_putmap)
        pop     de
        pop     bc
        ld      hl,curcol
        dec     (hl)
        jr      getNumberLoop
endNumber:
        pop     de                              ; Restore string pointer
        pop     bc
endNumberAfterPop:
        xor     a                               ; NULL terminator
        ld      (de),a                          ; Save it
        ld      a,' '
        bcall(_putmap)                          ; Erase cursor character
; Clear where to store floating point value
        pop     de
        push    de
        ld      h,d
        ld      l,e
        inc     de
        ld      bc,11
        ld      (hl),0
        ldir
; Check it's a valid number
preCheckValidNumber:
        ld      hl,getNumberBuffer
        ld      bc,$FEFE
        ld      d,0
checkValidNumber:
        ld      a,(hl)
        cp      '.'
        jr      nz,cvnNotDecimal
        inc     b
        jr      z,invalidNumber
        ld      e,a
        ld      a,d
        add     a,$7F
        ld      (_gnExponent),a
        ld      a,e
cvnNotDecimal:
        cp      $1A
        jr      nz,cvnNotNeg
        inc     c
        jr      z,invalidNumber
        ld      e,a
        ld      a,d
        or      a
        jr      nz,invalidNumber
        ld      a,e
        dec     d
cvnNotNeg:
        or      a
        jr      z,endNumberString
        inc     hl
        inc     d
        jr      checkValidNumber
endNumberString:
; Format number and write to Op var
        inc     b
        jr      z,gnGetSign
        ld      (hl),'.'
        inc     hl
        ld      (hl),'0'
        inc     hl
        ld      (hl),0
        jr      preCheckValidNumber
gnGetSign:
        pop     de                              ; DE => Sign byte of Op var
        inc     c
        ld      a,$80                           ; Negative
        jr      z,getNumberSetSign
        xor     a
getNumberSetSign:
        ld      (de),a
        inc     de                              ; DE => Exponent
        ld      a,$80                           ; Exponent value
_gnExponent             = $-1
        ld      (de),a                          ; Save exponent
        inc     de                              ; DE => First byte of mantissa
        push    de
        ld      l,e
        ld      h,d
        inc     de
        ld      bc,6
        ld      (hl),0
        ldir
        pop     de
        ld      hl,getNumberBuffer
        ex      de,hl
getNumberFormat:
        call    getNumberCharacter
        or      a
        ret     z
        sub     '0'
        add     a,a
        add     a,a
        add     a,a
        add     a,a
        or      (hl)
        ld      (hl),a
        call    getNumberCharacter
        or      a
        ret     z
        sub     '0'
        or      (hl)
        ld      (hl),a
        inc     hl                              ; HL => Next byte of mantissa
        jr      getNumberFormat
invalidNumber:
        bcall(_newline)
        pop     de
        jp      getNumber
getNumberCharacter:
        ld      a,(de)
        inc     de
        cp      $1A
        jr      z,getNumberCharacter
        cp      '.'
        jr      z,getNumberCharacter
        ret
getNumberTable:
.db "++++++++++"
.db "++++++",$1A,"369"
.db "++++.258++"
.db "++0147++++"
.db "++++++++++"
.db "+++++"

;------------------------------------------------
; cls - Clear screen & textshadow and return homescreen cursor to top-left
;
; Input:    None
; Output:   None
;------------------------------------------------
cls:
        bcall(_clrscrnfull)
        bcall(_homeup)
        ret

.end
