; ; ********************************************************************* ; ; The name decoding section of a Redefinable Telesoftware Decoder ; ; ; (C) C.J. Oswald 1982 ; -- rtf4 -- ; ; ********************************************************************* ; ; ; ; *********************************************************************** ; ; A subroutine to get the next name from the telesoftware source, ; decode it, and add any decode bytes it may represent to the queue. ; ; If instead it represents a command, then (providing it should be ; at the present stage of decoding) execut it. ; ; All registers preserved, along with ztempa, ztempl ; qname JSR saveal ; save registers & temporary zero page locations LDAIM star04 ; call buffer control subroutine to mark the start of JSR buffer ; a name ; qn3 JSR setlon ; set pointers ztype, zlo, zhi to lone tables ; qn1 JSR rawbyt ; get a byte in A from telesoftware source BCC qn7 ; byte successfully obtained ; ; All of file has now been loaded ; JSR restor ; restore registers & temporary zero page locations SEC ; set carry to flag end of file RTS ; qn7 TAY ; transfer byte to Y LDAIY ztype ; look up byte in type section of name table TAX ; copy entry to X BEQ qnend ; ignore this name (entry is 0) CMPIM &1B BEQ qnesco ; it's the escape operator (entry is &1B) CMPIM &1F ; check it is in the range 0 to &1F BEQ qnretr ; if it is &1F, then error in reception - ask for retrans. BCS qnerro ; if not, it is an unrecognised entry ANDIM &10 ; get bit 4 BNE qncomm ; it's a command subroutine LDAIM 2 CMP pass ; check that this is the second pass of the data BEQ qn8 ; (yes - continue) LDA operan ; check if operan is being decode BEQ qnend ; (if not, ignore this name) ; qn8 CPXIM 2 ; type entry in X BMI qn1byt ; code 1; it decodes to 1 byte BEQ qn2byt ; code 2; it decodes to 2 bytes ; ; The name decodes to a string of (more than 2) bytes ; LDAIY zlo ; get low byte of address where string can be found STA ztempa LDAIY zhi ; and get high byte STA ztempa+1 LDYIM 0 ; 1st byte indicates length of string LDAIY ztempa BEQ qnend ; (length of zero) TAX ; store length in X ; qn2 INY ; get next byte in string LDAIY ztempa JSR qbyte ; add it to queue DEX ; decrement count BNE qn2 ; continue until end of string BEQ qnend ; ; The name decodes to 2 bytes ; qn2byt LDAIY zhi ; get the first byte JSR qbyte ; queue it & drop through for the second byte ; ; The name decodes to 1 byte ; qn1byt LDAIY zlo ; get the byte JSR qbyte ; queue it JMP qnend ; ; The entry in the name tables was unrecognised ; qnerro LDAIM unexpe ; error code for unexpected entry in name tables JMP error ; ; Error in reception - ask for retran ; qnretr JSR chopqu ; empty the queue LDAIM 0 ; set pass to zero STA pass LDAIM retran ; code to ask for retran JSR buffer ; call buffer control subroutines JMP qn3 ; try again ; ; The name represents the escape operator ; qnesco JSR setesc ; set pointers ztype, zlo, zhi to escaped tables JMP qn1 ; go round again ; ; End of qname (this is positioned centrally, so it may be branched to) ; qnend JSR restor ; restore registers & temporary zero page locations CLC ; ensure carry is clear RTS ; ; The name represents some other command subroutine ; qncomm TXA ; copy back entry to A ANDIM &0F ; consider the LSN CMP pass ; correct type to be obeyed this pass? BNE qnend ; (no) LDAIY zlo ; store execution address of commmand subr. at ztempa STA ztempa LDAIY zhi STA ztempa+1 JSR qncexe ; execute command (it will destroy registers & temporary ; zero page locations) BCS qneof ; EOF (carry is set) JMP qnend ; qneof JSR restor SEC ; set carry to mark EOF RTS qncexe LDAIM nosuch ; error code in case command subroutine not available ; (the execution address of the command subroutine will be ; the address of the error handling routine if the command ; is not implemented) JMI ztempa ; execute command - if it is available ; ; *********************************************************************** ; ; A subroutine to decode the number of operans of a command ; or the number of names in one of those operans (result in A) ; ; PreservesAY X and temporary zero page locations ; opinfo INC operan ; ensure operan flag is set JSR decode ; get the next decode byte PHA ; save it LDA sevenb ; in 7-bit mode? BNE op3 ; (in 7-bit mode) PLA ; restore byte JMP op2 ; return ; ; In 7-bit mode, therefore ASCII to hex conversion needed ; op3 PLA ; restore byte ANDIM &4F ; convert lower case to upper case, & ASCII "0" to "9" ; ; to hex 00 to 09 CMPIM &0A BMI op2 ; count was in the range "0" to "9" SEC SBCIM "A"-&0A ; otherwise covert "A" to "F" to hex 0A to 0F CMPIM &10 BMI op2 ; count was in range "A" to "F" ("a" to "f") CMPIM &11 ; was char originally an "X" ("x") BEQ op1 ; (yes) ; ; illega operan information - give an error message and abort ; LDAIM ille00 ; error code for illega operan information JMP error ; ; Next two decode bytes indicate length ; op1 JSR opinfo ; get the most signif. nibble ASLA ; left hand justify the nibble ASLA ASLA ASLA STA oploc0 ; save the most signif. nibble JSR opinfo ; get the least signif. nibble ORA oploc0 ; assemble the byte count ; op2 DEC operan ; restore previous value of operan flag (probably clear) RTS ; ; *********************************************************************** ; ; A subroutine to add the byte passed in A to the queue ; ; Preserves all registers and temporary zero page locations ; qbyte PHA JSR saveal ; save all registers and temporary zero page locations PLA LDY queue ; copy pointer to zero page STY ztempa DEC queue ; decrement lsb of queue pointer LDX queue+1 ; continue copying pointer to zero page STX ztempa+1 CPYIM 0 ; see if msb of queue pointer needs to be decremented BNE qb2 ; (it doesn't) DEC queue+1 ; (it does) ; qb2 CPX heapfr+1 ; out of heap/queue space? BCC qb3 ; heap/queue space not OK BNE qb1 ; heap/queue space OK CPY heapfr BCS qb1 ; heap/queue space OK ; ; Out of heap/queue space - give an error message and abort ; qb3 LDAIM noheap ; error code for out of heap/queue space JMP error ; qb1 LDYIM 0 ; store byte at offset of zero from queue pointer STAIY ztempa JSR restor ; restore registers and temporary zero page locations RTS ; ; ********************************************************************** ; ; A subroutine to obtain from the GETBYTE channel the next byte of ; raw (ie encoded) telesoftware ; ; Preserves X,Y and temporary zero page locations ; rawbyt STY rawloc ; save Y ; rb8 LDYIM getfro ; channel getfro JSR getbyt ; (note that zero page locations & X,Y may be destroyed) BCC rb1 ; carry clear if next byte has been successfully got CMPIM &FE BEQ rb4 ; Escape? CMPIM 1 BMI rb4 ; no more data available from source (code 0) BNE rb5 ; this is the end of the block (code 2 or 3) ; ; This is the last block in the file & the end of the block (code 1) ; INC lastbl ; set last block in file flag to true ; ; End of block rb5 LDAIM unlo02 JSR buffer ;********************** Free page buffer for new page, ; - It was locked while BGETing. LDA ordern BEQ rb9 LDAIM nextpa JMP rb10 rb9 LDAIM next02 rb10 JSR buffer JMP rb8 ; Blank page fix ; ; Give no more data available error code and abort ; rb4 LDAIM nomore ; error code for no more data available from source JMP error ; ; Byte obtained OK ; rb1 LDY pass CPYIM 1 ; update CRC if on 1st pass? BNE rb7 ; (not on 1st pass) ; ; Update CRC ; ; A call to the CRC calculation subroutine should be made here ; to update the locations crc and crc+1 for the byte in A ; (should preserve registers and temporary zero page locations) ; ; rb7 LDY rawloc ; restore Y CLC ; ensure carry is clear RTS ; ; *********************************************************************** ; ; A subroutine to empty the queue ; ; Preserves all registers and zero page locations ; chopqu PHA ; save A LDAIM :LSB: hispac STA queue STA headqu LDAIM :MSB: hispac STA queue+1 STA headqu+1 PLA ; restore A RTS ; ; *********************************************************************** ; LNK RTF5