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

386 lines
8.0 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
PAGE
STTL "--- MACHINE-DEPENDENT I/O: APPLE II ---"
; -----------------
; PRINT CHAR IN [A]
; -----------------
CHAR: STA IOCHAR ; SAVE HERE
TXA ; SAVE [X] AND [Y]
PHA
TYA
PHA
LDA IOCHAR
CHAR1: JSR MCOUT
CMP #$8D ; check for <CR>
BNE CHj ; nope
;
; move cursor back to left margin
;
LDA ZBEGIN+ZLMRG+1 ; set left margin
STA EHZ ; positions
CHj:
PLA ; RESTORE [X] AND [Y]
TAY
PLA
TAX
RTS
; -----------------------
; DIRECT PRINT LINE [X/A]
; -----------------------
; ENTRY: STRING ADDRESS IN [X/A] (LSB/MSB)
; STRING LENGTH IN [Y]
DLINE: STX STRING+LO ; DROP STRING ADDRESS
STA STRING+HI ; INTO DUMMY BYTES
STY J ; COUNTER
LDX #0 ; INIT CHAR-FETCH INDEX
DOUT: DB $BD ; 6502 "LDA nnnn,X" OPCODE
STRING: DW $0000 ; DUMMY OPERAND BYTES
; LDY INVFLG ; INVERSE?
; BPL DOUT1 ; YES
ORA #%10000000 ; ELSE MAKE IT NORMAL
DOUT1: JSR CHAR
INX
DEC J ; LOOP TILL
BNE DOUT ; OUT OF CHARS
RTS
; -----------------------
; SEND [LBUFF] TO PRINTER
; -----------------------
; ENTRY: LENTH OF LINE IN [PRLEN]
PLEAV: RTS
PPRINT: LDA SCRIPT ; SCRIPTING INTERNALLY ENABLED?
BEQ PLEAV ; NO, SCRAM IMMEDIATELY
LDA SCRIPTF ; SCRIPTING ON?
BEQ PLEAV ; NO, EXIT
LDA CSW+LO ;SAVE NORMAL OUTPUT HOOK
PHA
LDA CSW+HI
PHA
LDA EHZ ; IF 80 COL
PHA
LDA ALTCSW+LO ;LOAD SCRIPTING HOOK
STA CSW+LO
LDA ALTCSW+HI
STA CSW+HI
LDA #0
STA EHZ
LDY #0
PP5: LDA LBUFF,Y ;GET A CHAR TO SEND OUT
JSR MCOUT
INY
DEC PRLEN ;LINE COUNT
BNE PP5 ;PRINT WHOLE LINE
;ALL DONE, RESET TO NORMAL AND LEAVE
PLA ;RETRIEVE CURRENT CURSOR POSITION
STA EHZ
PLA
STA CSW+HI
PLA
STA CSW+LO
RTS
PSTAT: DB 0 ;SET TO CLEAR WHEN BOOT,
;I PUT IT HERE SO RESTART WON'T ALTER
ALTCSW: DB 0,0 ;(WORD) PRINTER COUT
; FIRST TIME USING PRINTER, INITIALIZE IT
PCHK: LDX #<SLOTM ;ASK WHICH SLOT PRINTER IS IN
LDA #>SLOTM
LDY #SLOTML
JSR DLINE
LDA #0 ;ACTUALLY SLOT 1
JSR DODEF ;DISPLAY IT AS DEFAULT
JSR GETKEY
CMP #EOL
BEQ PC1 ;USE DEFAULT
SEC
SBC #'0'
CMP #8 ;1-7
BCS PCHK ;OOPS
BCC PC2 ;SKIP AROUND DEFAULT
PC1: LDA #1 ;WHICH IS 1
PC2: CLC
ADC #$C0
STA ALTCSW+HI
JSR PISSER ;SEND >CR< TO SCREEN FOR NEATNESS
INC PSTAT ;SET TO ON
LDA CSW+LO ;SAVE NORMAL OUTPUT HOOK
PHA
LDA CSW+HI
PHA
LDA ALTCSW+LO ;LOAD SCRIPTING HOOK
STA CSW+LO
LDA ALTCSW+HI
STA CSW+HI
; jsr INIT_PR ; do initialization
; lda #$07 ; output @ Cs07
; sta CSW+LO ; okay
LDA #$89 ; OUTPUT PRINTER SETUP SEQUENCE
JSR MCOUT ; START WITH COMMAND CHAR >CTRL-I<
LDA #$B8 ; 8 (80 COL WIDE)
JSR MCOUT
LDA #$B0 ; 0
JSR MCOUT
LDA #$CE ; N (LF AFTER CR)
JSR MCOUT
LDA CSW+LO ; SAVE REAL PRINTER OUTPUT
STA ALTCSW+LO ; LOC. FOR NEXT TIME
LDA CSW+HI
STA ALTCSW+HI
PLA ; RESET NORMAL OUTPUT
STA CSW+HI
PLA
STA CSW+LO
; PRINTER SETUP ON THE IIc COPIES THE ROM INTERRUPT VECTOR
; FROM $FFFE IN ROM TO BOTH MAIN & AUX. RAM PAGES @ $FFFE
; THAT PAGE IN MAIN RAM CONTAINS THE MONITOR STUFF SO IS OK
; BUT THAT PAGE IN AUX. RAM IS BEING USED TO CONTAIN A PAGE
; OF GAME CODE. THE FOLLOWING RTN CAUSES THE NEXT USE OF THAT
; PAGE TO READ IT IN NEW FROM THE DISK SO THAT THE VALUES
; WILL ALL BE CORRECT. (6/14/85 Le)
;
; THAT PAGE IS SECTOR $4F IN RAMDSK
; AND IT IS NOT USED
; ASK 85
RTS
;INIT_PR:
; jmp (CSW) ; jump to init routine
; ------------
; SPLIT SCREEN
; ------------
; SPLIT SCREEN AT LINE [ARG1]
; DISABLE SPLIT IF [ARG1] = 0
; IGNORE IF SPLIT ALREADY ENABLED OR [ARG1] >= 24
ZSPLIT: LDA ARG1+LO ; GET # OF LINES FOR SCREEN
BEQ NORL ; IF 0 THEN RESTORE SCREEN
CMP #24 ; IS SPLIT REALLY = WHOLE SCREEN
BCS ZSPOUT ; YES, IGNORE
STA SPSTAT ; NON ZERO = SCREEN IS SPLIT
LDA #$18 ; RESTORE BOTTOM FOR SCROLL
STA WBOTM
LDA WTOP
STA I ; HOLD A SEC
LDA ARG1+LO ; GET BOTTOM OF SPLIT SCREEN (AGAIN)
STA WTOP ; MAKE THAT THE TOP OF THE SECOND SCREEN
CMP LINCNT ; IS SCROLLING SCREEN NOW LESS THAN LINCNT?
BCC ZSPL3 ; NO
STA LINCNT ; YES
ZSPL3:
LDA #0 ; ALIGN CURSOR PROPERLY
STA OLD1CHZ
STA OLD1EHZ
STA OLD1CVT
LDA CVT
CMP I
BCC ZSPL5 ; FOR TOP SCREEN
CMP WTOP ; OR TO KEEP WITHIN BOTTOM SCREEN
BCS ZSPOUT ; OR IF OK WHERE IT IS, LEAVE IT
LDA WTOP
STA CVT
LDA ZBEGIN+ZLMRG+1 ; XZIP
ZSPL4:
STA EHZ
JMP BASCAL ; <CR> TO MAKE CVT WORK
ZSPL5: LDA #0
STA CVT
BEQ ZSPL4 ; JMP
NORL: ;RESTORE SCREEN TO FULL SCREEN MODE
LDA #0 ; PUT CURSOR AT TOP OF SCREEN
STA WTOP ; RESTORE FULL SCREEN ALIGNMENT
STA LINCNT
STA SPSTAT ; FLAG NOT SPLIT
ZSPOUT: RTS
; ------
; SCREEN
; ------
; GO TO TOP WINDOW (TOP OF SCREEN) IF [ARG1] = 1
; GO TO BOTTOM OF SCREEN IF [ARG1] = 0
; IGNORE IF SPLIT NOT ENABLED OR [ARG1] <> 0 OR 1
; FLAG SPLITF WILL BE SET FOR OUTPUT TO DETERMINE
; IF AND WHICH WINDOW TO DISPLAY TO
; (0=BOTTOM 1=TOP)
ZSCRN:
LDA SPSTAT ; CHECK IF SCREEN IS SPLIT
BEQ ZSPOUT ; NO, SO JUST LEAVE
JSR CLRBUF ; EMPTY OUTPUT BUFFER BEFORE MOVING
LDX SPLITF ; SAVE CURSOR OF SCREEN NOW IN
SCRSAV:
LDA CVT
STA OLD0CVT,X
LDA EHZ
STA OLD0EHZ,X
LDA ARG1+LO ; CHECK WHICH WINDOW
BNE SCRN1 ; TOP SCREEN
SCRN0: LDA #$FF ; SCROLLING SCREEN SO
STA SCRIPT ; AL<SCRIPTING
LDA OLDWD ; RESET MARGINS
STA XSIZE
LDA #0
STA SPLITF ; SET FLAG TO BOTTOM SCREEN (0)
BEQ SCRNP ; JMP TO <CR> RTN
SCRN1: CMP #01
BNE ZSPOUT ; INVALID SCREEN ID
STA SPLITF ; SET FLAG TO UNSCROLLING SCREEN (1)
LDA XSIZE ; SAVE MARGINS
STA OLDWD
LDA #0
STA SCRIPT ; SET SCRIPTNG OFF, NOT ALLOWED THIS SCREEN
LDA #79
STA XSIZE ; SET FOR TOP SCREEN USING WHOLE WIDTH
SCRNP:
LDX SPLITF ; WHICH SCREEN
LDA FONT,X ; get old font
JSR CHFONT ; now change font to this screen's last font
LDX SPLITF ; WHICH SCREEN
LDA OLD0CVT,X ; SET CURSOR TO WHERE IT WAS IN THAT WINDOW
STA CVT
LDA OLD0EHZ,X
STA EHZ
JMP BASCAL ; SET CURSOR (+ LEAVE)
; ------
; MARGIN
; ------
ZMARG: JSR CLRBUF ; CLEAR LBUFF BEFORE RESETTING LINE MARGINS
LDA ARG2+LO ; SET RIGHT MARGIN
STA ZBEGIN+ZRMRG+1
LDA ARG1+LO ; GET LEFT MARGIN POSITION
STA ZBEGIN+ZLMRG+1
STA EHZ
LDA #79 ; FULL WIDTH
SEC
SBC ARG2+LO ; SUBTRACT BOTH MARGINS
SBC ARG1+LO ; TO GET NEW WIDTH
STA XSIZE
STA OLDWD ; JIC
RTS
; ------------
; CLEAR SCREEN
; ------------
CLS: JSR HOME ; CLEAR & HOME CURSOR
LDA ZBEGIN+ZLMRG+1 ; GET LEFT MARGIN
STA EHZ
RTS
PISSER: LDA #$8D
JMP MCOUT
; -----
; SOUND
; -----
; ARG1 = BOOP (2) BEEP (1) ALL OTHERS INVALID
; (EZIP)
ZSOUND: LDA ZBEGIN+ZMODE
AND #%00100000
BEQ ZSOEX ; NOT ENABLED
LDX ARG1+LO ; GET SOUND WANTED
DEX
BEQ BEEP
DEX
BNE ZSOEX ; INVALID
LDY #$FF ; DURATION ($C0 = .1 SEC)
BOOP: LDA #$10 ; TONE ($0C = 1 KHZ)
JSR MWAIT
LDA SPKR ; TOGGLE SPEAKER
DEY
BNE BOOP
ZSOEX: RTS
BEEP: JMP BELL ; QUICK BEEP ( 1KHZ @ .1 SEC)
; ------------------------
; CHECK IF 128 K OF MEMORY
; ------------------------
; EXIT: CARRY SET IF NOT 128K, CLEAR IF THERE IS
MEMCHK: LDA #0 ; START @ 0
STA TSTVAL
MLOOP1: LDY #0
MLOOP2: STA $1000,Y ; WRITE [TSTVAL] TO
INY ; MAIN MEMORY
BNE MLOOP2
INC TSTVAL
LDA TSTVAL
STA WRTBNK+AUX ; SET TO AUX MEMORY
MLOOP3: STA $1000,Y ; WRITE NEXT VALUE
INY ; TO AUX MEMOYR
BNE MLOOP3
STA WRTBNK+MAIN ; SET TO MAIN MEMORY
DEC TSTVAL ; RESET TO [TSTVAL] WRITTEN TO MAIN
MLOOP4: LDA $1000,Y ; CHECK IF WHAT WRITTEN
CMP TSTVAL ; 1ST TO MAIN MEM PG $10
BNE NO128 ; IS STILL THERE
INY
BNE MLOOP4
INC TSTVAL
STA RDBNK+AUX ; & SET TO AUX MEMORY
MLOOP5: LDA $1000,Y ; & SEE IF WHAT WROTE
CMP TSTVAL ; TO AUX MEM IS STILL THERE
BNE NO128
INY
BNE MLOOP5
STA RDBNK+MAIN ; RESET TO MAIN MEM
LDA TSTVAL ; LAST THING WAS INC'D
BNE MLOOP1 ; GO TRY W/ NEXT SET OF VALUES, DO 0,1 -> FF,O
CLC
RTS ; SIGNAL OK
NO128: STA RDBNK+MAIN ; RESET TO MAIN MEM
SEC
RTS ; OOPS, ONLY 64K
; NOT IMPLEMENTED ON THE APPLE
ZCOLOR:
ZDISPL:
ZDCLR: RTS
ZPICNF: JMP PREDF ; SET AS BAD
END