;;; -*- TI-Asm -*- ;;; ;;; Mimas - Assembly language IDE for the TI-83 Plus ;;; ;;; Copyright (C) 2010 Benjamin Moody ;;; ;;; This program is free software: you can redistribute it and/or ;;; modify it under the terms of the GNU General Public License as ;;; published by the Free Software Foundation; either version 3 of the ;;; License, or (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;; General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program. If not, see . ;; UnpackSymbolString: ;; ;; Uncompress a symbol string. ;; ;; Input: ;; - HL = address of start of packed string ;; - DE = address of buffer to place output ;; ;; Output: ;; - HL = address of byte following input ;; - DE = address of byte following output ((DE) = 0) ;; ;; Destroys: ;; - AF, BC P1_UnpackSymbolString: ld c,0FFh ;; initial zero nibble represents a dot (local label) call P1_ReadNibble or a jr nz,P1_UnpackSymbolString_Begin ld a,'.' P1_UnpackSymbolString_SpecialChar: call c,P1_ReadPackedValue_SpecialChar P1_UnpackSymbolString_Loop: ld (de),a inc de call P1_ReadNibble or a jr z,P1_UnpackSymbolString_Done P1_UnpackSymbolString_Begin: cp 0Ch jr c,P1_UnpackSymbolString_SpecialChar call P1_ReadPackedValue jr P1_UnpackSymbolString_Loop ;; UnpackCommentString: ;; ;; Uncompress a comment string. ;; ;; Input: ;; - HL = address of start of packed string ;; - DE = address of buffer to place output ;; - C = number of bytes of input (> 0) ;; ;; Output: ;; - HL = address of byte following input ;; - DE = address of byte following output ((DE) = 0) ;; ;; Destroys: ;; - AF, BC P1_UnpackCommentString: scf rl c jr P1_UnpackCommentString_Begin P1_UnpackCommentString_SpecialChar: call P1_ReadPackedValue_SpecialChar P1_UnpackCommentString_Loop: ld (de),a inc de P1_UnpackCommentString_Begin: call P1_ReadNibble jr c,P1_UnpackCommentString_Done cp 0Bh jr c,P1_UnpackCommentString_SpecialChar call P1_ReadPackedValue jr nc,P1_UnpackCommentString_Loop P1_UnpackCommentString_Done: xor a P1_UnpackSymbolString_Done: ld (de),a bit 0,c ret z inc hl ret P1_ReadPackedValue: call P1_ShiftReadFlipNibble ret c cp 0EEh ; (note: flipped) jr z,P1_ReadPackedValue_z cp 0B0h jr z,P1_ReadPackedValue_lBrack sub 90h cp 60h ccf ret nc sub 70h P1_ReadPackedValue_SpecialChar: push hl add a,low(P1_stringPackingTable + 10h) ld l,a ld h,high(P1_stringPackingTable) ld a,(hl) pop hl or a ret P1_ReadPackedValue_z: ld a,'z' ret P1_ReadPackedValue_lBrack: ld a,LlBrack ret P1_ShiftReadFlipNibble: add a,a add a,a add a,a add a,a ld b,a call P1_ReadNibble ret c or b bit 4,a ret nz xor 0Fh ret P1_ReadNibble: dec c scf ret z ld a,(hl) and 0Fh inc hl bit 0,c ret nz dec hl xor (hl) rrca rrca rrca rrca ret ;; CompareToSymbolString: ;; ;; Compare a zero-terminated string with a packed symbol string. ;; ;; Input: ;; - HL = address of start of packed string ;; - DE = address of start of ZT string ;; ;; Output: ;; - Zero flag set if strings are equal (ignoring case) ;; - Bit 6 of C = 0 if strings are identical (including case) ;; - Carry flag set if string at HL > string at DE ;; ;; Destroys: ;; - AF, BC, DE, HL P1_CompareToSymbolString: ld c,5 ;; initial zero nibble represents a dot (local label) call P1_ReadNibble or a jr nz,P1_CompareToSymbolString_Begin ld a,'.' P1_CompareToSymbolString_SpecialChar: call c,P1_ReadPackedValue_SpecialChar P1_CompareToSymbolString_Loop: ld b,a ld a,(de) or a jr z,P1_CompareToSymbolString_DETooShort cp b jr z,P1_CompareToSymbolString_SameChar bit 6,c jr nz,P1_CompareToSymbolString_AlreadyDifferent ld a,c rla rrca or 40h ld c,a P1_CompareToSymbolString_AlreadyDifferent: ld a,b call P1_CompareStrings_Norm ld b,a ld a,(de) call P1_CompareStrings_Norm cp b ret nz P1_CompareToSymbolString_SameChar: inc de set 2,c call P1_ReadNibble or a jr z,P1_CompareToSymbolString_Done P1_CompareToSymbolString_Begin: cp 0Ch jr c,P1_CompareToSymbolString_SpecialChar call P1_ReadPackedValue jr P1_CompareToSymbolString_Loop P1_CompareToSymbolString_Done: ld a,(de) or a jr nz,P1_CompareToSymbolString_HLTooShort ld a,c add a,a bit 0,a ret P1_CompareToSymbolString_DETooShort: inc a scf P1_CompareToSymbolString_HLTooShort: ld c,0FFh ret ;; PackSymbolString: ;; ;; Compress a symbol string. The result is zero-terminated. NOTE: ;; this routine checks for characters that are forbidden in comments, ;; but does not check for characters that are forbidden in symbols. ;; (Only the characters A-Z, a-z, theta, and _ are permitted in ;; symbols. Passing any other characters to this routine may result ;; in invalid output.) ;; ;; Input: ;; - DE = address of start of string (zero-terminated) ;; - HL = address of buffer to place output ;; ;; Output: ;; - DE = address of byte following input ;; - HL = address of byte following output ;; ;; Destroys: ;; - AF, BC P1_PackSymbolString: ld a,(de) inc de sub '.' jr z,P1_PackSymbolString_LocalLabel dec de ld a,10h P1_PackSymbolString_LocalLabel: ld (hl),a P1_PackSymbolString_Loop: ld a,(de) inc de or a jr z,P1_PackSymbolString_Done push hl ld hl,P1_stringPackingTable + 27 ld bc,28 call P1_PackCharValue pop hl call P1_WritePackedValue jr P1_PackSymbolString_Loop P1_PackSymbolString_Done: ;; write zero terminator rld inc hl ret ;; PackCommentString: ;; ;; Compress a comment string. The result is not zero-terminated. ;; ;; Input: ;; - DE = address of start of string ;; - HL = address of buffer to place output ;; - B = number of characters (at least 1) ;; ;; Output: ;; - DE = address of byte following input ;; - HL = address of byte following output ;; ;; Destroys: ;; - AF, BC P1_PackCommentString: ld (hl),10h P1_PackCommentString_Loop: ld a,(de) inc de push bc push hl ld hl,P1_stringPackingTable + 26 ld bc,27 call P1_PackCharValue pop hl pop bc call P1_WritePackedValue djnz P1_PackCommentString_Loop xor a rld rra ret c inc hl ret ;; WritePackedValue: ;; ;; Write a packed value (4 or 8 bits) to RAM. ;; ;; Input: ;; - A = input value (A < 16 to write only four bits) ;; - HL = destination pointer; (HL) = 10 if unused, or 0X if one ;; nibble already written ;; ;; Output: ;; - HL updated ;; ;; Destroys: ;; - AF P1_WritePackedValue: cp 16 jr c,P1_WritePackedValue_Nibble push af rlca rlca rlca rlca call P1_WritePackedValue_Nibble pop af P1_WritePackedValue_Nibble: rld rra ret c inc hl ld (hl),10h ret ;; PackCharValue: ;; ;; Convert an ASCII character to its packed value (4 or 8 bits.) ;; Invalid characters are converted to '#' (in comment mode) or '_e' ;; (in symbol mode). ;; ;; Input: ;; - A = value to convert ;; - HL = address of last value in packing table ;; - BC = number of values in packing table ;; ;; Output: ;; - A = packed value ;; ;; Destroys: ;; - HL, BC P1_PackCharValue: cpdr jr z,P1_PackCharValue_SpecialChar cp LlBrack ld c,0B0h + 10h jr z,P1_PackCharValue_SpecialChar cp 'z' ld c,0E1h + 10h jr z,P1_PackCharValue_SpecialChar cp SFourSpaces ld c,10h jr z,P1_PackCharValue_SpecialChar add a,90h bit 4,a jr nz,P1_PackCharValue_NoFlip xor 0Fh P1_PackCharValue_NoFlip: cp 0B1h jr c,P1_PackCharValue_Invalid cp 0F0h ret c P1_PackCharValue_Invalid: ld c,0B3h + 10h P1_PackCharValue_SpecialChar: ld a,c add a,0F0h ret ;;; Packing/unpacking table P1_stringPackingTable: ;; 8-bit extra characters (Fx) ;; 0123456789ABCDEF db "^bcfghjkmpquvwxy" ;; 4-bit compressed characters ;; 0123456789ABCDEF db " adeilnorst_" ; note that 0 is a terminator in ; symbols and B is a prefix in ; comments ;; Other valid characters: ;; 0123456789ABCDEF ;; Bx: [!"#$%&'()*+,-./ (comments only; note [ replaces space) ;; Cx: ?>=<;:9876543210 ;; Dx: @ABCDEFGHIJKLMNO ;; Ex: _z]\0ZYXWVUTSRQP (0 = theta; note z replaces ^) ;; Note that the Cx and Ex lines are reversed; as a result, ;; valid symbols cannot contain "0" nibbles anywhere except at ;; the end. NO_BYTE_CARRY P1_stringPackingTable