PAGE SBTTL "--- Z-STRING HANDLERS ---" ; ----------------- ; POINT TO Z-STRING ; ----------------- SETSTR: CLRA ASL TEMP+1 ROL TEMP ROLA STA MPCH LDD TEMP STD MPCM CLR MPCFLG ZSTEX: RTS ; -------------- ; PRINT Z-STRING ; -------------- PZSTR: CLR CSPERM ; PERMANENT CHARSET CLR STBYTF ; RESET STRING BYTE FLAG LDA #$FF STA CSTEMP ; NO TEMP CHARSET ACTIVE PZSTRL: JSR GETZCH ; GET A Z-CHARACTER BCS ZSTEX ; END OF STRING IF CARRY SET STA MASK ; SAVE CHAR HERE BEQ PZSTRS ; O = SPACE CHAR CMPA #4 ; IS THIS AN F-WORD? BLO PZSTRF ; APPARENTLY SO CMPA #6 ; SHIFT CHAR? BLO PZSTRT ; YES, CHANGE CHARSET JSR GETMOD TSTA ; IS THIS CHARSET 0? BNE PZSTR1 ; NOPE ; PRINT LOWER-CASE CHAR (CHARSET 0) LDA #$61-6 ; ASCII "a" MINUS Z-OFFSET PZSTP0: ADDA MASK ; ADD CHARACTER PZSTP1: JSR COUT ; PRINT RESULT BRA PZSTRL ; AND FETCH ANOTHER Z-CHAR ; CHARSET 1 OR 2? PZSTR1: CMPA #1 ; SET 1? BNE PZSTR2 ; NOPE, IT'S SET 2 ; PRINT UPPER-CASE CHAR (CHARSET 1) LDA #$41-6 ; ASCII "A" MINUS Z-OFFSET BRA PZSTP0 ; AND SO ON ... ; DECODE/PRINT CHARSET 2 PZSTR2: LDB MASK ; RETRIEVE Z-CHAR SUBB #6 ; CONVERT TO ZERO-ALIGNED INDEX BEQ PZSTRA ; IF ZERO, IT'S "DIRECT" ASCII LDX #CHRTBL ; ELSE GET BASE OF DECODE TABLE LDA B,X ; GET CHAR FROM TABLE BRA PZSTP1 ; AND PRINT IT! ; DECODE/PRINT A "DIRECT" ASCII CHAR PZSTRA: JSR GETZCH ; GET NEXT Z-BYTE ASLA ; SHIFT INTO POSITION ASLA ASLA ASLA ASLA STA MASK ; SAVE MSB JSR GETZCH ; FETCH LSB STA MASK+1 ; SAVE THAT, TOO LDA MASK ; GET MSB ORA MASK+1 ; SUPERIMPOSE LSB BRA PZSTP1 ; AND PRINT RESULT ; PRINT A SPACE PZSTRS: LDA #$20 BRA PZSTP1 ; CHANGE CHARACTER SETS PZSTRT: SUBA #3 ; CONVERT TO 1 OR 2 TFR A,B BSR GETMOD BNE PZSTRP ; NO, DO PERMANENT SHIFT STB CSTEMP ; JUST A TEMP-SHIFT BRA PZSTRL PZSTRP: STB CSPERM ; PERMANENT SHIFT CMPA CSPERM ; NEW SET SAME AS OLD? BEQ PZSTRL ; YES, EXIT CLR CSPERM ; ELSE BACK TO SET 0 BRA PZSTRL ; BEFORE FINISHING ; HANDLE AN F-WORD PZSTRF: DECA ; CONVERT TO 0-2 LDB #64 ; TIMES 64 MUL STB PZSTFO ; SAVE FOR LATER JSR GETZCH ; GET F-WORD INDEX TFR A,B ; MOVE IT ASLB ; FORM WORD-ALIGNED INDEX ADDB PZSTFO ; ADD OFFSET LDX FWORDS ; GET BASE ADDR OF FWORDS TABLE ABX ; ADD THE OFFSET LDD ,X ; GET THE FWORD POINTER STD TEMP ; AND SAVE IT ; SAVE THE STATE OF CURRENT Z-PRINT LDA MPCH PSHS A LDA CSPERM LDB STBYTF LDX MPCM LDY ZSTWRD PSHS Y,X,B,A JSR SETSTR ; PRINT THE F-WORD JSR PZSTR ; POINTED TO BY [TEMP] ; RESTORE THE OLD Z-STRING PULS Y,X,B,A STY ZSTWRD STX MPCM STB STBYTF STA CSPERM PULS A STA MPCH LDA #$FF STA CSTEMP ; DISABLE TEMP CHARSET CLR MPCFLG ; MPC HAS CHANGED! JMP PZSTRL ; CONTINUE INNOCENTLY ; ---------------------- ; RETURN CURRENT CHARSET ; ---------------------- GETMOD: LDA CSTEMP BPL GM LDA CSPERM RTS GM: LDB #$FF STB CSTEMP RTS ; --------------- ; GET NEXT Z-CHAR ; --------------- GETZCH: LDA STBYTF ; WHICH BYTE? BPL GTZ0 COMB ; SET CARRY RTS ; TO INDICATE "NO MORE CHARS" GTZ0: BNE GETZH1 ; NOT FIRST CHAR INC STBYTF JSR GETWRD LDD TEMP STD ZSTWRD LSRA LSRA GTEXIT: ANDA #%00011111 CLRB ; CLEAR CARRY RTS GETZH1: DECA BNE GETZH2 ; MUST BE LAST CHAR LDA #2 STA STBYTF LDD ZSTWRD LSRA RORB LDA ZSTWRD LSRA LSRA RORB LSRB LSRB LSRB GETZH3: TFR B,A ; EXPECTED HERE BRA GTEXIT GETZH2: CLR STBYTF LDD ZSTWRD BPL GETZH3 COM STBYTF ; INDICATE END OF STRING BRA GETZH3 ; ------------------- ; CONVERT TO Z-STRING ; ------------------- CONZST: LDD #$0505 ; FILL OUTPUT BUFFER STD ZSTBUO ; WITH PAD CHARS STD ZSTBUO+2 STD ZSTBUO+4 INCA ; = 6 STA MASK ; INIT CHAR COUNT CLR VAL ; RESET OUTPUT AND CLR TEMP ; INPUT INDEXES CNZSL1: LDB TEMP INC TEMP LDX #ZSTBUI ; POINT TO INPUT BUFFER LDA B,X ; GRAB NEXT CHAR STA MASK+1 ; SAVE IT HERE BNE CNZSL2 ; IF CHAR WAS ZERO, LDA #5 ; USE A Z-PAD BRA CNZSLO CNZSL2: LDA MASK+1 JSR ZCHRCS ; WHICH CHARSET TO USE? TSTA BEQ CNZSLC ; IF CHARSET 0, USE LOWER CASE ADDA #3 LDB VAL ; OUTPUT A TEMP SHIFT LDX #ZSTBUO STA B,X INC VAL DEC MASK LBEQ CNZSLE CNZSLC: LDA MASK+1 JSR ZCHRCS DECA BPL CNZSC1 ; NOT CHARSET 0! LDA MASK+1 SUBA #$61-6 ; ASCII "a" MINUS 6 CNZSLO: LDB VAL LDX #ZSTBUO STA B,X INC VAL DEC MASK BEQ CNZSLE ; ALL FINISHED BRA CNZSL1 ; ELSE LOOP BACK FOR MORE CNZSC1: BNE CNZSC3 ; MUST BE CHARSET 3 LDA MASK+1 SUBA #$41-6 ; ASCII "A" MINUS 6 BRA CNZSLO CNZSC3: LDA MASK+1 JSR CNZS2M ; IS IT IN TABLE? BNE CNZSLO ; YES, OUTPUT THE CHAR LDA #6 ; ELSE IT'S A "DIRECT" ASCII CHAR LDB VAL LDX #ZSTBUO STA B,X ; SEND "DIRECT" TO OUTPUT INC VAL DEC MASK BEQ CNZSLE ; NO MORE ROOM! ; CONVERT CHAR TO 2-BYTE DIRECT ASCII LDA MASK+1 LSRA LSRA LSRA LSRA LSRA ANDA #%00000011 LDB VAL LDX #ZSTBUO STA B,X INC VAL DEC MASK BEQ CNZSLE ; NO MORE ROOM! LDA MASK+1 ANDA #%00011111 ; FORM 2ND Z-BYTE BRA CNZSLO ; AND OUTPUT IT ; ---------------------- ; SEARCH CHARSET 3 TABLE ; ---------------------- CNZS2M: LDX #CHRTBL LDB #25 CNLOOP: CMPA B,X BEQ CNOK DECB BNE CNLOOP RTS ; RETURN ZERO IN B IF NO MATCH CNOK: TFR B,A ; EXPECTED IN [A] ADDA #6 ; CONVERT TO Z-CHAR RTS ; ------------------------- ; DETERMINE CHARSET OF CHAR ; ------------------------- ZCHRCS: CMPA #$61 ; ASCII "a" BLO ZCHR1 CMPA #$7B ; ASCII "z"+1 BHS ZCHR1 CLRA ; IT'S CHARSET 0 RTS ZCHR1: CMPA #$41 ; ASCII "A" BLO ZCHR2 CMPA #$5B ; ASCII "Z"+1 BHS ZCHR2 LDA #1 ; IT'S CHARSET 1 RTS ZCHR2: TSTA BEQ ZCHRX ; EXIT IF ZERO BMI ZCHRX ; OR NEGATIVE LDA #2 ; ELSE IT'S CHARSET 2 ZCHRX: RTS ; --------------- ; CRUSH 6 Z-CHARS ; --------------- CNZSLE: LDD ZSTBUO ; HANDLE 1ST TRIPLET ASLB ASLB ASLB ASLB ROLA ASLB ROLA ORB ZSTBUO+2 STD ZSTBUO LDD ZSTBUO+3 ; HANDLE 2ND TRIPLET ASLB ASLB ASLB ASLB ROLA ASLB ROLA ORB ZSTBUO+5 ORA #%10000000 ; SET SIGN BIT OF LAST Z-BYTE STD ZSTBUO+2 RTS ; ---------------------- ; CHARSET 2 DECODE TABLE ; ---------------------- CHRTBL: DB 0 ; DUMMY BYTE DB $0D ; CARRIAGE RETURN DB "0123456789.,!?_#" DB $27 ; SINGLE QUOTE DB $22 ; DOUBLE QUOTE DB "/\-:()" END