;*************************************************************** ; * ; utils.s -- General purpose utilities (Assembler) * ; * ; v0.9 01/06/2003 Formatted for jump table creation * ; * ;**************************************************************/ ;*************************************************************** ; _sp_gets -- Gets string. If 1st char a space, it exits _sp_gets: pshhx psha ldhx #_inbuf jsr _getch cmp #SPACE beq cancel_gets cmp #BS beq cancel_gets bra first_gets ;*************************************************************** ; _gets -- Receive a String, No Interrupt Routine ; Returns carry set if ^C, or ESC _gets: pshhx psha ldhx #_inbuf inrlp: ; Fill receiver buffer with spaces clr ,x aix #1 cphx #(_inbuf+RXBLEN) bne inrlp ldhx #_inbuf wt_nxt_char: sta copctl ; strobe Watch dog timer brclr SCRF,scs1,wt_nxt_char lda scdr ; Read in byte jsr _putch first_gets: cmp #CR bne notcr ; Is the entry over? (CR received) ; If so, terminate entry with a null clr ,x ; Store null in buffer cphx #_inbuf bne rxdn_ok ; If buffer not empty, exit with carry clear bra rxdn_err ; If buffer empty, exit with carry set notcr: cmp #$03 ; ^C hit? bne not_cancel ; If so store and buffer and terminate entry cancel_gets: sta _inbuf clra sta _inbuf+1 rxdn_err: sec bra rxdn not_cancel: cmp #$08 bne notbs ; Is it a back space? (BS received) cphx #_inbuf beq rx_cancel ; Don't baskspace past beginning aix #-1 bra wt_nxt_char notbs: sta ,x ; Store char in buffer aix #1 cphx #_inbuf+RXBLEN-1 ; Is buffer full bne wt_nxt_char rx_cancel: clr ,x rxdn_ok: clc rxdn: pula pulhx rts ;*************************************************************** ; _ahex2b -- Converts 2 ascii hex (h:x-reg) encodes byte ; to one byte hex (a-reg) _ahex2b: txa bsr _a2nibhex ; Convert low byte to ascii psha tha bsr _a2nibhex ; Convert high byte to ascii nsa ; put high byte in high nibble add 1,sp ; Combine low and high nibbles pulx rts ;*************************************************************** ; _a2nibhex -- Convert ASCII Byte to hex nibble. _a2nibhex: cmp #'9' ; If Ascii A-F, you need to add 9 to bls ah1 ; convert to hex, ie, A(41) + 9 -> 4A -> 0A add #$09 ah1: and #$0F rts ;*************************************************************** ; _dblchar -- passed a byte in a register ; returns ascii encoded chars in h-x registers _dblchar: psha bsr _nib_to_asc tax pula dblow: nsa bsr _nib_to_asc tah rts ;*************************************************************** ; _nib_to_asc -- Convert low nibble to ASCII encoded Hex _nib_to_asc: and #$0F ora #$30 cmp #$39 ble dbend add #$07 dbend: rts ;*************************************************************** ; _comma_sp -- Output ,sp _comma_sp: psha bsr _pr_comma lda #'s' bsr _putch lda #'p' bra out_byte ;*************************************************************** ; _pr_letter_x -- Output the letter X (X) _pr_letter_x: psha lda #'x' bra out_byte ;-------------------------------- ; _pr_pound -- Output a pound sign (#) _pr_pound: psha lda #'#' bra out_byte ;-------------------------------- ; _pr_comma -- Output a comma _pr_comma: psha lda #',' bra out_byte ;-------------------------------- ; _crlf -- Output a cr & lf _crlf: psha lda #CR bsr _putch lda #LF bra out_byte ;-------------------------------- ; _sp_byte -- Prints a byte and then a space _byte_sp: jsr _pbyte ;-------------------------------- ; _space -- Output a space _space: psha lda #SPACE out_byte: bsr _putch pula rts ;*************************************************************** ; _pr_nibble -- Output Ascii encoded low nibble _pr_nibble: jsr _nib_to_asc ;-------------------------------- ; _putch -- Put a char, Nn ints _putch: wt_putch: sta copctl ; strobe Watch dog timer brclr SCTE,scs1,wt_putch ;TDRE = 1 ? sta scdr ;OK, send rts ;*************************************************************** ; _pwordx -- Output 16 bit number pointed to by h:x-reg as 4 ascii chars ; _pwordx: lda ,x bsr _pbyte lda 1,x bsr _pbyte rts ;*************************************************************** ; _pword -- Output 16 bit number in h:x-reg as 4 ascii chars ; _pword: pshhx tha bsr _pbyte txa bsr _pbyte pulhx rts ;*************************************************************** ; _pbyte_sp -- Output Ascii encoded byte, No int. ; and a space ; _pbyte_sp: bsr _space bra _pbyte ;-------------------------------- ; pbytex -- Put a byte pointed by x-reg _pbytex: lda ,x ;-------------------------------- ; _pbyte -- Output Ascii encoded byte, No int. _pbyte: pshhx jsr _dblchar tha bsr _putch txa bsr _putch pulhx rts ;*************************************************************** ; _ischar -- Checks for char, returns it in b-reg, =0 if none _ischar: clra sta copctl brclr SCRF,scs1,no_char ;SCRF = 1 ? lda scdr ;OK, get no_char: rts ;*************************************************************** ; _getchne -- get a character, no echo, returns in a-reg ; returns carry set if ESC or CTRL-C _getchne: sta copctl brclr SCRF,scs1,_getchne ;SCRF = 1 ? lda scdr ;OK, get bra no_geco ;-------------------------------- ; _getch -- get a character, echo, returns in a-reg ; returns carry set if ESC or CTRL-C _getch: sta copctl brclr SCRF,scs1,_getch ;SCRF = 1 ? lda scdr ;OK, get bsr _putch no_geco: clc cmp #ESC beq gc_can cmp #$0C bne egchar gc_can: sec egchar: rts ;*************************************************************** ; _do_again -- Returns z set(zero) if again, clear if end _do_again: bsr _getch cmp #SPACE beq yep_again cmp #CR bne _do_again tsta yep_again: rts ;*************************************************************** ; _puts -- This subroutine will output the null teminated string ; pointed to by H:X to the SCI. ; ; Calling convention: ; ldhx #string ; jsr _puts ; ; Returns: nothing ; ; Changes: H:X puts_lp: sta copctl ; strobe Watch dog timer brclr SCTE,scs1,puts_lp ; wait until SCI transmitter is empty mov x+,scdr ; output character to the SCI and advance pointer _puts: tst ,x ; test string character bne puts_lp ; loop back if not null rts ; else, return ;*************************************************************** ; GetHexByte ; This subroutine retrieves two ASCII bytes via the SCI and converts ; (packs) them into one hex byte, which is returned in ACC. ; ; Calling convention: ; jsr GetHexByte ; ; Returns: CCRZ= 1 if valid hex byte retrieved. Otherwise, CCRZ= 0. ; ACC= data ; ; Changes: ACC GetHexByte: bsr _getchne ; get msb character from the SCI #if HYPERTERM #elseif jsr _putch ; echo it back #endif bsr _ishex ; check if valid ASCII hex character beq GetHexByte2 ; exit if not bsr ToHex ; convert ASCII hex character to hex value nsa ; swap lower nibble up psha ; save temporarily bsr _getchne ; get lsb character from the SCI #if HYPERTERM #elseif jsr _putch ; echo it back #endif bsr _ishex ; check if valid ASCII hex character beq GetHexByte1 ; exit if not bsr ToHex ; convert ASCII hex character to hex value add 1,sp ; combine msb and lsb nibbles bit #0 ; CCRZ= 1 GetHexByte1: ais #1 ; deallocate local variable GetHexByte2: rts ; return ;*************************************************************** ; _get_atbl -- Look up address in table ; Passed: byte to compare in a-reg ; table address in h:x reg ; WARNING: last table entry must be null ; Returns: Carry set if found, clear if not ; If found, returns value in address in h:x reg _get_atbl: cmp ,x bne not_match lda 1,x psha lda 2,x tax pulh sec rts not_match: aix #3 tst ,x bne _get_atbl clc rts ;*************************************************************** ; ToHex ; This subroutine converts the ASCII hex value passed in ACC to a ; binary hex value. ; ; Calling convention: ; lda data ; jsr ToHex ; ; Returns: ACC= data. ; ; Changes: ACC ToHex: sub #'0' ; adjust first by subtracting '0' cmp #9T ; check if value was between '0' to '9' bls ToHex1 ; exit if so sub #7 ; else, adjust for value between 'A' to 'F' ToHex1: rts ; return ;*************************************************************** ; _ishex -- Tests if it is an ascii hex ; Returns char if yes ; Returns 0 if no _ishex: cmp #'0' blo nothex cmp #'9' bls yeshex and #$DF cmp #'F' bhi nothex cmp #'A' blo nothex yeshex: tsta rts nothex: clra rts ;*************************************************************** ; clr_spaces -- Increments x:h pointer past spaces _clr_spaces: psha cl_sp_lp: lda ,x cmp #SPACE bne not_sp aix #1 bra cl_sp_lp not_sp: pula rts ;*************************************************************** ; _first_hex -- Gets 1st parameter in buffer: 4 or a-reg hex chars ; _next_hex -- Gets successive parameters in buffer: 4 or a-reg hex chars ; returns number in X-reg & carry clear if ok ; if error or cancel, set carry _next_hex: lda _hbufpos tah ldx _hbufpos+1 incx bra _again_hex _first_hex: ldhx #_inbuf+1 _again_hex: bsr _clr_spaces bra _readhex ;-------------------------------- ; _gethex -- Gets up to 4 or a-reg length digit number, ; returns number in X-reg & carry clear if ok ; if error or cancel, set carry _gethex: jsr _sp_gets bcs buf_can ldhx #_inbuf _readhex: clra pshh pshx numck_lp: psha lda ,x beq end_num_str cmp #SPACE beq end_num_str jsr _ishex pula beq err_can aix #1 inca cmp #$05 bne numck_lp bra err_can end_num_str: tha sta _hbufpos stx _hbufpos+1 pula tsta beq err_can gnumok: pulx pulh cmp #$04 beq gcv4 cmp #$03 beq gcv3 cmp #$02 beq gcv2 bra gcv1 gcv4: pshx pshh lda ,x ldx 1,x tah gcv3_cut: jsr _ahex2b pulh pulx psha lda 2,x ldx 3,x tah jsr _ahex2b tax pulh bra gvc_end gcv3: aix #-1 pshx pshh lda #'0' ldx 1,x tah bra gcv3_cut gcv2: lda ,x ldx 1,x tah bra gcv1a gcv1: ldhx #0 ldx ,x gcv1a: jsr _ahex2b ldhx #0 tax gvc_end: clc rts err_can: pulx pulh buf_can: sec rts