mirror of
https://github.com/erkyrath/infocom-zcode-terps.git
synced 2026-01-11 23:43:24 +00:00
345 lines
10 KiB
Plaintext
345 lines
10 KiB
Plaintext
* FILE ZIP50.ASM
|
|
|
|
* STRING FUNCTIONS ************************************************
|
|
|
|
RORG
|
|
DEF PUTSTR,ZWORD
|
|
|
|
REF CHRFUN,WRDOFF,WRDTAB
|
|
REF GETWRD,GTAWRD,BSPLTB,NEWLIN,JSR
|
|
|
|
* ZSTR CHARACTER CONVERSION VECTOR
|
|
|
|
ZCHRS TEXT 'abcdefghijklmnopqrstuvwxyz'
|
|
TEXT 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
TEXT ' 0123456789.,!?_#'
|
|
BYTE ''' * () CHECK THIS
|
|
TEXT '"/\-:()'
|
|
BYTE >00
|
|
EVEN
|
|
|
|
* OUTPUT A ZSTR
|
|
* GIVEN: R0 = BLOCK POINTER, R1 = BYTE POINTER
|
|
* RETURN UPDATED POINTER
|
|
|
|
PUTSTR DECT R6
|
|
MOV R2,*R6
|
|
DECT R6
|
|
MOV R3,*R6
|
|
DECT R6
|
|
MOV R4,*R6
|
|
DECT R6
|
|
MOV R5,*R6 SAVE OLD REGISTERS
|
|
|
|
CLR R4 TEMP CHAR SET STARTS AT 0
|
|
CLR R5 PERM CHAR SET STARTS AT 0
|
|
|
|
*--------------------------------------------------------------------
|
|
X551 BL @JSR
|
|
DATA GETWRD GET NEXT STRING WORD
|
|
|
|
DECT R6
|
|
MOV R0,*R6
|
|
DECT R6
|
|
MOV R1,*R6
|
|
DECT R6
|
|
MOV R2,*R6 SAVE PTR & COPY OF STRING WORD
|
|
|
|
LI R3,3 3 BYTES IN (Z)WORD
|
|
X552 DECT R6
|
|
MOV R2,*R6 SAVE CURRENT BYTE (LOW 5 BITS)
|
|
|
|
SRA R2,5 SHIFT NEXT BYTE INTO POSITION
|
|
DEC R3
|
|
JNE X552 LOOP UNTIL DONE
|
|
|
|
LI R3,3 RETRIEVE THE 3 BYTES
|
|
X553 MOV *R6+,R2 GET NEXT BYTE
|
|
ANDI R2,>001F CLEAR UNWANTED BITS
|
|
|
|
MOV R4,R4 IN WORD MODE?
|
|
JGT X554 NO
|
|
JEQ X554 NO
|
|
*--------------------------------------------------------------------
|
|
|
|
SLA R2,1 YES, CALCULATE WORD OFFSET
|
|
A @WRDTAB,R2 POINT INTO WORD TABLE
|
|
A @WRDOFF,R2 USING PROPER 32-WORD BLOCK
|
|
|
|
MOV R2,R0
|
|
BL @JSR
|
|
DATA GTAWRD POINT TO WORD STRING
|
|
|
|
BL @JSR
|
|
DATA BSPLIT SPLIT IT
|
|
|
|
BL @JSR
|
|
DATA PUTSTR AND PRINT IT
|
|
|
|
JMP X565 CONTINUE WHERE WE LEFT OFF,
|
|
WITH TEMP CS RESET
|
|
*---------------------------------------------------------------------
|
|
X554 CI R4,3 CS 3 SELECTED? (ASCII MODE)
|
|
JLT X556 NO, NORMAL CS
|
|
*---------------------------------------------------------------------
|
|
|
|
JNE X555 NO, BUT WE ARE IN ASCII MODE
|
|
SWPB R4 SHIFT SOME BITS HIGH TO MAKE NUMBER LARGE
|
|
SOC R2,R4 SAVE HIGH-ORDER ASCII BITS HERE
|
|
JMP X566 GO GET NEXT BYTE
|
|
|
|
X555 ANDI R4,>0003 EXTRACT PREVIOUSLY SAVED HIGH-ORDER BITS
|
|
SLA R4,5 POSITION THEM
|
|
SOC R2,R4 OR IN LOW-ORDER BITS
|
|
|
|
MOV R4,R0
|
|
JMP X564 GO PRINT THE CHARACTER
|
|
|
|
*---------------------------------------------------------------------
|
|
X556 CI R2,6 SPECIAL CODE?
|
|
JLT X559 YES, SPACE, WORD, OR SHIFT
|
|
|
|
CI R4,2 MIGHT ALSO BE SPECIAL IF IN CS2
|
|
JNE X558 BUT WE'RE NOT
|
|
*---------------------------------------------------------------------
|
|
|
|
CI R2,7 CRLF?
|
|
JEQ X557 YES
|
|
JGT X558 NO, NOT ASCII MODE, EITHER?
|
|
|
|
INC R4 YES IT IS, SWITCH TO ASCII MODE
|
|
JMP X566 AND GO GET NEXT BYTE
|
|
|
|
X557 BL @JSR
|
|
DATA NEWLIN CRLF REQUESTED, DO A NEWLINE
|
|
JMP X565
|
|
|
|
*-------------------------------------------------------------------
|
|
X558 LI R8,26 NORMAL CHAR,
|
|
MPY R4,R8 CALCULATE OFFSET FOR THIS CS
|
|
A R2,R9 ADD IN CHARACTER OFFSET (+6)
|
|
|
|
MOVB @ZCHRS-6(R9),R0 GET THE CHAR FROM CONV VECTOR
|
|
SWPB R0 MOVE TO R0 LOW
|
|
JMP X564 GO PRINT IT
|
|
*-------------------------------------------------------------------
|
|
|
|
X559 MOV R2,R2 IS IT A SPACE?
|
|
JNE X560 NO
|
|
|
|
LI R0,' ' YES
|
|
JMP X564 GO PRINT A SPACE
|
|
|
|
X560 CI R2,3 IS IT A WORD?
|
|
JGT X561 NO, MUST BE A SHIFT
|
|
|
|
ORI R4,>8000 SHIFT TO WORD MODE FOR NEXT BYTE
|
|
DEC R2 CALC WORD-TABLE BLOCK OFFSET
|
|
SLA R2,6 64 BYTES IN A BLOCK
|
|
MOV R2,@WRDOFF SAVE IT AND LOOP
|
|
JMP X566
|
|
|
|
X561 AI R2,-3 CALCULATE NEW CS
|
|
MOV R4,R4 TEMP SHIFT (FROM CS 0)?
|
|
JNE X562 NO
|
|
|
|
MOV R2,R4 YES, JUST SAVE NEW TEMP CS
|
|
JMP X566 AND LOOP
|
|
|
|
X562 C R2,R4 IS THIS THE CURRENT CS?
|
|
JEQ X563 YES, DO A PERM SHIFT TO IT
|
|
CLR R4 OTHERWISE, PERM SHIFT TO CS 0
|
|
X563 MOV R4,R5 TEMP AND PERM CS'S ARE SAME NOW
|
|
JMP X566
|
|
|
|
*----------------------------------------------------------------------
|
|
X564 LI R8,X565 (DO AN INDIRECT JSR)
|
|
DECT R6
|
|
MOV R8,*R6 PUSH RETURN ADDRESS (NEXT INST)
|
|
|
|
MOV @CHRFUN,R8 IDENTIFY PRINT ROUTINE
|
|
B *R8 PRINT THE CHARACTER
|
|
|
|
X565 MOV R5,R4 RESET TEMP CS TO PERM CS
|
|
|
|
X566 DEC R3
|
|
JNE X553 NEXT BYTE
|
|
*----------------------------------------------------------------------
|
|
|
|
MOV *R6+,R2 RESTORE POINTERS
|
|
MOV *R6+,R1 AND ORIGINAL
|
|
MOV *R6+,R0 STRING WORD
|
|
|
|
MOV R2,R2 END OF STRING?
|
|
JGT X551 NO, GET NEXT WORD
|
|
JEQ X551 NO, GET NEXT WORD
|
|
|
|
MOV *R6+,R5 YES, CLEAN UP
|
|
MOV *R6+,R4
|
|
MOV *R6+,R3
|
|
MOV *R6+,R2 AND RETURN UPDATED POINTER
|
|
|
|
MOV *R6+,R11
|
|
B *R11 RETURN
|
|
|
|
* GIVEN AN ASCII CHAR IN R0 HIGH,
|
|
* RETURN THE CHARACTER SET # IN R0
|
|
|
|
CHRCS SWPB R0
|
|
ANDI R0,>00FF IS THIS A NULL?
|
|
JNE X571 NO
|
|
|
|
LI R0,3 YES, RETURN DUMMY CS NUMBER
|
|
JMP X574
|
|
|
|
X571 CI R0,'a' LOWER CASE?
|
|
JLT X572 NO
|
|
CI R0,'z'
|
|
JGT X572 NO
|
|
|
|
CLR R0 YES
|
|
JMP X574
|
|
|
|
X572 CI R0,'A' UPPER CASE?
|
|
JLT X573 NO
|
|
CI R0,'Z'
|
|
JGT X573 NO
|
|
|
|
LI R0,1 YES
|
|
JMP X574
|
|
|
|
X573 LI R0,2 CALL IT NUMBER/PUNCTUATION
|
|
|
|
X574 MOV *R6+,R11
|
|
B *R11 RETURN
|
|
|
|
* GIVEN AN ASCII CHAR IN R0 HIGH,
|
|
* RETURN ZSTR BYTE VALUE (6 TO 31, OR 0) IN R0
|
|
|
|
CHRBYT LI R8,ZCHRS POINT TO CHAR CONVERSION TABLE
|
|
|
|
X576 CB R0,*R8+ FOUND THE CHARACTER?
|
|
JEQ X577 YES
|
|
|
|
MOVB *R8,*R8 NO, END OF STRING?
|
|
JNE X576 NO, CONTINUE LOOP
|
|
|
|
CLR R0 YES, RETURN ZERO FOR FAILURE
|
|
JMP X579
|
|
|
|
X577 AI R8,-ZCHRS+5 ADJUST PTR SO FIRST CHAR IS 6
|
|
MOV R8,R0
|
|
|
|
X578 CI R0,32 SUBTRACT MULTIPLES OF 26
|
|
JLT X579 UNTIL BASE CODE IS REACHED
|
|
AI R0,-26
|
|
JMP X578
|
|
|
|
X579 MOV *R6+,R11
|
|
B *R11 RETURN
|
|
|
|
* CONVERT UP TO 6 ASCIZ CHARS POINTED TO BY R0
|
|
* TO A 2-WORD ZSTR RETURNED IN R0 AND R1
|
|
|
|
PADCHR EQU 5
|
|
|
|
ZWORD DECT R6
|
|
MOV R2,*R6
|
|
DECT R6
|
|
MOV R3,*R6 SAVE REGISTERS
|
|
|
|
MOV R0,R2 CHAR STRING POINTER
|
|
LI R3,6 MAKE 6 ZSTR BYTES
|
|
|
|
*---------------------------------------------------------------------
|
|
X581 MOVB *R2+,R1 GET NEXT CHAR
|
|
JNE X583 NOT END-OF-STRING
|
|
*---------------------------------------------------------------------
|
|
|
|
LI R0,PADCHR AT END OF STRING, PAD WITH PAD CHARS
|
|
X582 DECT R6
|
|
MOV R0,*R6 SAVE A PAD BYTE
|
|
|
|
DEC R3
|
|
JNE X582 LOOP UNTIL DONE
|
|
JMP X586
|
|
|
|
*---------------------------------------------------------------------
|
|
X583 MOV R1,R0
|
|
BL @JSR
|
|
DATA CHRCS FIND THE CS NUMBER FOR THIS CHAR
|
|
|
|
MOV R0,R0 CS 0?
|
|
JEQ X584 YES
|
|
*---------------------------------------------------------------------
|
|
|
|
AI R0,3 NO, CALCULATE TEMP SHIFT BYTE
|
|
DECT R6
|
|
MOV R0,*R6 SAVE THE SHIFT BYTE
|
|
|
|
DEC R3 REDUCE BYTE COUNT
|
|
JEQ X586 DONE
|
|
|
|
*---------------------------------------------------------------------
|
|
X584 MOV R1,R0
|
|
BL @JSR
|
|
DATA CHRBYT FIND PROPER BYTE VAL FOR THIS CHAR
|
|
|
|
MOV R0,R0 IN NORMAL CS'S?
|
|
JNE X585 YES
|
|
*---------------------------------------------------------------------
|
|
|
|
LI R0,6 NO, USE ASCII SHIFT
|
|
DECT R6
|
|
MOV R0,*R6 SAVE IT
|
|
|
|
DEC R3 DONE YET?
|
|
JEQ X586 YES
|
|
|
|
SWPB R1 NO, MOVE CHAR TO R1 LOW
|
|
ANDI R1,>00FF
|
|
|
|
MOV R1,R0
|
|
SRA R0,5 SHIFT (3) HIGH BITS INTO POSITION
|
|
DECT R6
|
|
MOV R0,*R6 SAVE THEM
|
|
|
|
DEC R3 DONE YET?
|
|
JEQ X586 YES
|
|
|
|
ANDI R1,>001F NO, POSITION THE (5) LOW BITS
|
|
MOV R1,R0
|
|
|
|
*----------------------------------------------------------------------
|
|
X585 DECT R6
|
|
MOV R0,*R6 SAVE THIS BYTE
|
|
|
|
DEC R3
|
|
JNE X581 LOOP UNTIL ZWORD FULL
|
|
*----------------------------------------------------------------------
|
|
|
|
X586 MOV @10(R6),R0 BUILD ZWORD WORDS FROM 6 SAVED BYTES
|
|
SLA R0,5
|
|
SOC @8(R6),R0
|
|
SLA R0,5
|
|
SOC @6(R6),R0
|
|
|
|
MOV @4(R6),R1
|
|
SLA R1,5
|
|
SOC @2(R6),R1
|
|
SLA R1,5
|
|
SOC @0(R6),R1
|
|
|
|
ORI R1,>8000 SET END-OF-STRING BIT IN SECOND WORD
|
|
AI R6,12 FLUSH STACK
|
|
|
|
MOV *R6+,R3
|
|
MOV *R6+,R2 RESTORE REGISTERS
|
|
|
|
MOV *R6+,R11
|
|
B *R11 RETURN
|
|
|
|
|
|
END
|
|
|