Files
erkyrath.infocom-zcode-terps/acorn/machine.asm
Andrew Plotkin b642da811e Initial commit.
2023-11-16 18:19:54 -05:00

301 lines
5.3 KiB
NASM

PAGE
SBTTL 'MACHINE DEPENDENT I/O'
GETKEY: TXA ;SAVE X AND Y
PHA
TYA
PHA
GKEY0: JSR OSRDCH ;GET A CHAR
;CHECK TO MAKE SURE KEY IS VALID, ONLY ACCEPT IT IF IT IS
GKEY3: AND #$7F ;SCREEN OUT SHIFTS
CMP #EOL ;CHECK FOR GOOD (BAD) CHAR
BEQ OK
CMP #BACKSP
BEQ OK
CMP #SPACE
BCC BADKEY ;IF < SPACE, BAD
CMP #$40 ;@
BEQ BADKEY
CMP #$25 ;%
BCC OK ;BELOW RANGE
CMP #$27 ;'
BEQ OK ;GOOD CHAR
CMP #$2C ;+ +1
BCS MASK0 ;NOT IN THIS GROUP, TRY OTHER
ORA #$10 ;SET BIT 4, CHANGE %&()*+ TO 5689:;
;(FROM BAD TO GOOD CHAR AS SAME KEY LOCATION)
JMP OK ;GOOD, DONE NOW
MASK0: CMP #$3C ;<
BCC OK ;LESS
CMP #$3F ;> +1
BCS MASK1 ;OK, GO DO LETTERS
AND #$2F ;CLEAR BIT 4, CHANGE <=> TO ,-.
BNE OK ;BRANCH ALWAYS, DONE
MASK1: CMP #'z'+1
BCS BADKEY ;IF > BAD
CMP #'a'
BCS OK ;IF > OK
CMP #'Z'+1
BCC OK ;IF < OK
BADKEY: JSR BOOP ;BAD KEY, GIVE WARNING NOISE
JMP GKEY0 ;TRY AGAIN
OK: STA IOCHAR ;HOLD ON TO IT
ADC RAND1
STA RAND2
LSR A
STA RAND1
PLA
TAY
PLA
TAX
LDA IOCHAR ;RETRIEVE IT
RTS
BOOP: LDA #BELL ;(DOES NOT WORK, STOLE SOUND GENERATION MEMORY)
JSR OSWRCH
RTS
;PUT A CHAR TO SCREEN (PHYSICALLY), HANDLE EOL, SCROLLING IF NECESSARY
CHAR: STA IOCHAR ;PRESERVE X,Y SAVE A TO USE
TXA
PHA
TYA
PHA
LDA #RDCPOS ;READ TEXT CURSOR POS.
JSR OSBYTE ;GIVES X,Y
LDA IOCHAR
CMP #EOL
BEQ OUTEOL ;EOL = SPECIAL HANDLING
CMP #BACKSP ;IF DEL CHAR DON'T SCROLL
BEQ NOSCRL
CPY #YSIZE-1 ;ON LAST SCREEN LINE?
BCC NOSCRL ;NO, NO SCROLL NEEDED
CPX #XSIZE ;LAST CHAR ON LINE?
BCC NOSCRL ;NO, NO SCROLL YET
DOSCRL: LDA #11 ;MOVE CURSOR UP 1 LINE
JSR VDU ;FOR ALIGNMENT AFTER SCROLL
LDX #1 ;START TRANSFERING FROM LINE 1
SRL0: CPX #YSIZE
BEQ SRL2
LDA LOLINE,X ;GET ADDR OF DEST LINE
STA LTO+LO ;INTO [LTO]
LDA HILINE,X
STA LTO+HI
INX ;NEXT LINE
LDA LOLINE,X ;GET ADDR OF SOURCE LINE
STA LFROM+LO ;INTO [LFROM]
LDA HILINE,X
STA LFROM+HI
LDY #XSIZE
SRL1: LDA (LFROM),Y ;MOVE SOURCE LINE
STA (LTO),Y ;TO DEST LINE
DEY
BPL SRL1
BMI SRL0 ;LOOP TILL X = YSIZE
SRL2: LDX #XSIZE ;CLEAR LAST LINE
LDA #SPACE ;OF SCREEN RAM
SRL3: STA SCREEN+960,X
DEX
BPL SRL3
;DROP THRU TO SEND CHAR OUT NOW
NOSCRL: LDA IOCHAR
JSR OSWRCH ;SEND CHAR TO SCREEN
CMP #EOL ;IF CR
BNE NS1
LDA #$0A ;SEND LF
JSR OSWRCH
NS1: PLA
TAY
PLA
TAX
LDA IOCHAR
RTS
OUTEOL: CPY #YSIZE-1 ;LAST LINE ON SCREEN?
BCC NOSCRL ;NO
BCS DOSCRL ;YES, SO SCROLL
;*******
INPUT: ;FETCH A LINE OF INPUT FOR READ RTN
;ENTRY: ABS ADDR OF READ BUFFR IN ARG1
;EXIT: # CHARS READ IN A
JSR LINOUT ;FLUSH LBUFF
LDY #0
STY LINCNT ;RESET LINE COUNT
INLOOP: JSR GETKEY ;GET ASCII INTO A
CMP #EOL ;<RET>?
BEQ ENDLIN ;LINE DONE IF SO
CMP #BACKSP ;BACKSPACE?
BEQ BACKUP ;SPECIAL HANDLING
STA LBUFF,Y ;ELSE ADD CHAR TO INPUT BUFFR
INY ;NEXT POSITION IN LINE
SHOWIT: JSR CHAR ;DISPLAY CHAR
CPY #77 ;2 SCREEN LINES FULL?
BCC INLOOP ;NO, KEEP GOING
;HANDLE LINE OVERFLOW
NOMORE: JSR GETKEY
CMP #EOL ;IF EOL, WRAP UP THE LINE
BEQ ENDLIN
CMP #BACKSP ;BACKSPACE OK TOO
BEQ BACKUP
JSR BOOP ;ELSE COMPLAIN
JMP NOMORE ;AND INSIST
;HANDLE BACKSPACE
BACKUP: DEY ;BACKUP THE POINTER
BPL SHOWIT ;SEND BS IF NOT START OF LINE
JSR BOOP ;ELSE SAY BAD
LDY #0 ;RESET POINTER
BEQ INLOOP ;AND TRY AGAIN
;END OF LINE
ENDLIN: STA LBUFF,Y ;PLACE IN BUFFER
INY ;UPDATE INDEX
STY LINLEN ;SAVE FOR "READ"
STY PRLEN ;AND "PRINT"
JSR CHAR ;SEND EOL TO SCREEN
;MOVE LBUFF TO ARG1 W/LOWER CASE CONVERSION
LEX1: LDA LBUFF-1,Y ;GET A CHAR FROM LBUFF
CMP #'A' ;IF CHAR IS ALPHA
BCC LEX2 ;CONVERT TO LOWER CASE
CMP #'Z'+1
BCS LEX2
ADC #$20
LEX2: STA (ARG1),Y ;MOVE CHAR TO INPUT BUFF AT ARG1
DEY ;LOOP TILL ALL CHARS MOVED
BPL LEX1
JSR PPRINT ;SCRIPT LBUFF IF ENABLED
LDA LINLEN ;RESTORE # CHARS
RTS ;INTO A
DLINE: ;DISPLAY A STRING
;ENTRY: STRING ADDR X=LSB A=MSB
; STRING LENGTH IN Y
STX STRNG+LO ;DROP STRING ADDRESS
STA STRNG+HI ;INTO DUMMY BYTES
LDX #0 ;INIT INDEX
DOUT: DB $BD ;6502 "LDA nnnn,X" OPCODE
STRNG: DW $0000 ;DUMMY OPERAND BYTES
JSR CHAR
INX ;NEXT CHAR
DEY ;DECREMENT CHAR COUNT
BNE DOUT ;LOOP TILL OUT OF CHARS
RTS
;CLEAR SCREEN
CLS: LDA #HIGH SCREEN
STA I+HI
LDA #0
STA I+LO
TAY
LDX #$04
CLS0: STA (I),Y
INY
BNE CLS0
INC I+HI
DEX
BNE CLS0
LDA #MVTXC ;ALIGN CURSOR AT
JSR VDU ;TOP OF SCREEN
LDA #0 ;COL 0
JSR VDU
LDA #1 ;TOP LINE
JMP VDU
;*****
;PRINT ON PRINTER
;*****
PPRINT: LDA SCRIPT ;SCRIPTING INTERNALLY ENABLED?
BEQ PEX ;NO, LEAVE
LDA ZBEGIN+ZSCRIP+1 ;CHECK SCRIPT FLAG
AND #%00000001 ;SCRIPTING ON?
BEQ PEX ;NO, LEAVE
LDA #OUTSTR ;SET OUTPUT STREAM
LDX #2 ;TO PRINTER
JSR OSBYTE
LDA #IGNORE ;SET TO PRINT
LDX #0 ;LINE FEEDS
JSR OSBYTE
LDY #0 ;PRINT OUT LINE
POUT: LDA LBUFF,Y
JSR OSWRCH
INY
DEC PRLEN
BNE POUT ;DO WHOLE LINE
LDA #OUTSTR ;RESET OUTPUT STREAM
LDA #4 ;TO VIDEO
JSR OSBYTE
PEX: RTS ;AND LEAVE
; ************
;NO SPLIT SCREEN OPTION IS BEING INCLUDED SO I AM INSERTING
; ************ RETURNS FOR THE ROUTINES
ZSPLIT: RTS
ZSCRN: RTS
;*******************
;LINE ADDRESS TABLES
;*******************
LOLINE: DB $00,$28,$50,$78,$A0,$C8,$F0,$18
DB $40,$68,$90,$B8,$E0,$08,$30,$58
DB $80,$A8,$D0,$F8,$20,$48,$70,$98
DB $C0
HILINE: DB $7C,$7C,$7C,$7C,$7C,$7C,$7C,$7D
DB $7D,$7D,$7D,$7D,$7D,$7E,$7E,$7E
DB $7E,$7E,$7E,$7E,$7F,$7F,$7F,$7F
DB $7F
END