PAGE SBTTL "--- MACHINE-DEPENDENT I/O: APPLE II ---" ; ---------------------------- ; FETCH ASCII KEYCODE INTO [A] ; ---------------------------- ; EXIT: ASCII IN [A] & [IOCHAR] GETKEY: CLD TXA ; SAVE [X] & [Y] PHA TYA PHA GKEY0: JSR RDKEY ;GET A CHAR ;CHECK TO MAKE SURE KEY IS VALID, ONLY ACCEPT IT IF IT IS AND #$7F ;SCREEN OUT SHIFTS CMP #EOL ;CHECK FOR GOOD (BAD) CHAR BNE GK0 JMP OK GK0: CMP #BACKSP BNE GK5 JMP OK GK5: CMP #ARROW BNE GK1 JMP OK ; CHECK FOR "ARROWS", CONVERT FOR USE (EZIP) ; ALSO : CHANGE <_>)@%^&*( TO ,-.0256789 GK1: LDX #ENDKEY ; GET LENGTH OF LIST GK2: CMP HAVE,X ; CHECK AGAINST LIST OF UNWANTED KEYS BEQ GK3 ; FOUND IT DEX BPL GK2 ; CHECK THEM ALL BMI GK4 ; NOT FOUND, CONTINUE OTHER CHECKS GK3: LDA WANT,X ; GET KEY TO USE INSTEAD BNE OK ; JMP GK4: CMP #SPACE ; NO CTRL CHARS ACCEPTABLE BCC BADKEY ; IF < SPACE, BAD CMP #$2B BEQ BADKEY CMP #$3C BCC OK CMP #$3F BEQ OK MASK0: CMP #'z'+1 ;PICK OUT LETTERS NOW BCS BADKEY ;IF > BAD CMP #'a' BCS OK ;IF > OK CMP #'A' BCC BADKEY 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 RNUM1 ;FUTZ WITH RANDOM STA RNUM1 EOR RNUM2 STA RNUM2 PLA ; RESTORE TAY ; EVERYTHING PLA TAX LDA IOCHAR ; GET CHAR INTO [A] RTS ; AND RETURN IT HAVE: DB $3C,$5F,$3E,$29,$40,$25,$5E,$26,$2A,$28 WANT: DB $2C,$2D,$2E,$30,$32,$35,$36,$37,$38,$39 ENDKEY EQU $-WANT-1 ; ----------------- ; PRINT CHAR IN [A] ; ----------------- CHAR: STA IOCHAR ; SAVE HERE TXA ; SAVE [X] AND [Y] PHA TYA PHA LDA IOCHAR CMP #$61 ; (L) BCC CHAR1 ;LESS THAN a CMP #$7B ; (L) BCS CHAR1 ;GREATER THAN z LDX COL80 BNE CHAR1 ;ONLY CONVERT IF 40 COLUMN AND #%11011111 ;STRIP LOWER CASE BIT CHAR1: ORA #%10000000 ;SET BIT 7 SO WILL BE NORMAL IF WANTED JSR MCOUT PLA ; RESTORE [X] AND [Y] TAY PLA TAX RTS ; --------------------- ; FETCH A LINE OF INPUT ; --------------------- ; ENTRY: ABS ADDR OF READ BUFFER IN [ARG1] ; EXIT: # CHARS READ IN [A] INPUT: JSR LINOUT ; FLUSH [LBUFF] LDY WTOP STY LINCNT ; RESET LINE COUNT INC LINCNT ; 1 FOR THIS LINE LDY #0 ; AND CHAR COUNT INLOOP: JSR GETKEY ; GET ASCII INTO [A] AND [IOCHAR] CMP #EOL ; EOL? BEQ ENDLIN ; LINE DONE IF SO CMP #BACKSP ; BACKSPACE? BEQ BACKUP ; SPECIAL HANDLING CMP #ARROW ; LEFT ARROW (BACKSPACE)? BEQ BACKUP STA LBUFF,Y ; ELSE ADD CHAR TO INPUT BUFFER INY ; NEXT POSITION IN LINE SHOWIT: JSR CHAR ; SEND TO SCREEN CPY #77 ; 2 SCREEN LINES FULL? BCC INLOOP ; NO, GET ANOTHER CHAR ; HANDLE LINE OVERFLOW NOMORE: JSR GETKEY CMP #EOL ; IF EOL, BEQ ENDLIN ; WRAP UP THE LINE CMP #BACKSP ; BACKSPACE BEQ BACKUP ; IS OKAY TOO CMP #ARROW ; BACKSPACE BEQ BACKUP JSR BOOP ; ELSE COMPLAIN JMP NOMORE ; AND INSIST ; HANDLE BACKSPACE BACKUP: DEY ; BACK UP THE POINTER BMI BBAD LDA #$08 ;BACKSP STRANGE SO DO 082008 JSR CHAR LDA #$20 JSR CHAR LDA #$08 BNE SHOWIT ;JMP BBAD: JSR BOOP ; ELSE SCREAM WITH PAIN LDY #0 ; RESET POINTER BEQ INLOOP ; AND WAIT FOR SOMETHING BETTER ; HANDLE END OF LINE ENDLIN: LDA #$8D ; (MUST BE $8D FOR PRINTER Le 5/8/85) STA LBUFF,Y ; SHIP EOL TO BUFFER INY ; UPDATE INDEX STY LINLEN ; SAVE HERE FOR "READ" STY PRLEN ; AND HERE FOR "PPRINT" JSR CHAR ; AND SEND EOL TO SCREEN ; MOVE [LBUFF] TO [ARG1] W/LC CONVERSION LEX0: LDA LBUFF-1,Y ; GET A CHAR FROM [LBUFF] LEX1: CMP #'A' ; IF CHAR IS ALPHA, BCC LEX2 ; CONVERT TO LOWER CASE CMP #'Z'+1 BCS LEX2 ADC #$20 LEX2: AND #$7F ; HIGH BIT OFF STA (ARG1),Y ; MOVE CHAR TO INPUT BUFFER AT [ARG1] DEY ; LOOP TILL BNE LEX0 ; ALL CHARS MOVED JSR PPRINT ; SCRIPT [LBUFF] IF ENABLED LDA LINLEN ; RESTORE # CHARS LDX COL80 BNE LEX3 ; 80 COL. CMP #40 BCC LEX3 INC LINCNT ; USED 2 LINES LEX3: RTS ; INTO [A] ; ----------------------- ; 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 LDX #0 ; INIT CHAR-FETCH INDEX DOUT: DB $BD ; 6502 "LDA nnnn,X" OPCODE STRING: DW $0000 ; DUMMY OPERAND BYTES JSR CHAR INX DEY ; 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 ZBEGIN+ZSCRIP+1 ; CHECK SCRIPT FLAG AND #%00000001 ; SCRIPTING ON? BEQ PLEAV ; NO, EXIT LDA CSW+LO ;SAVE NORMAL OUTPUT HOOK PHA LDA CSW+HI PHA LDA CH ;SAVE CURRENT CURSOR POSITION PHA LDA EH ; IF 80 COL PHA LDA ALTCSW+LO ;LOAD SCRIPTING HOOK STA CSW+LO LDA ALTCSW+HI STA CSW+HI LDA #0 STA CH STA EH IF 0 ;PRINTER INIT SEQUENCE FROM OLD ZIP (I DON'T KNOW) LDA PSTAT ;CHECK PRINTER STATUS CMP #1 BNE PP4 ;OPEN, ONLY DO ONCE INC PSTAT ;SET TO DONE PP0: LDA #$89 ;OUTPUT PRINTER SETUP SEQUENCE JSR MCOUT ; LDA CSW+HI STA ALTCSW+HI LDA CSW+LO STA ALTCSW+LO ; (SETTING BYTE $779 REMOVED - UNNECCESARY COMPLICATION) ; (HANDLED BY THE ^I 80N Le 5/8/85) LDA #$B8 ; 8 (80 COL WIDE) JSR MCOUT LDA #$B0 ; 0 JSR MCOUT LDA #$CE ; N (LF AFTER CR) JSR MCOUT LDA #$8D ; (GUY AT APPLE SAID THIS A GOOD IDEA) JSR MCOUT ENDIF PP4: 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 EH PLA STA CH PLA STA CSW+HI PLA STA CSW+LO PEX: RTS SLOTM: DB EOL DB "Printer Slot 1-7: " SLOTML EQU $-SLOTM PSTAT: DB 0 ;SET TO CLEAR WHEN BOOT, ;I PUT IT HERE SO RESTART WON'T ALTER ALTCSW: DB 0,0 ;(WORD) PRINTER COUT ; ------------ ; PRINTER INIT ; ------------ PCHK: LDX #LOW SLOTM ;ASK WHICH SLOT PRINTER IS IN LDA #HIGH SLOTM LDY #SLOTML JSR DLINE LDA #0 ;ACTUALLY SLOT 1 JSR DODEF ;DISPLAY IT AS DEFAULT JSR GETKEY CMP #EOL BEQ PC2 ;USE DEFAULT SEC SBC #"0" CMP #8 ;1-7 BCS PCHK ;OOPS BCC PC3 ;SKIP AROUND DEFAULT PC2: LDA #1 ;WHICH IS 1 PC3: CLC ADC #$C0 STA ALTCSW+HI JSR PISSER ;SEND 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 PP0: LDA #$89 ; OUTPUT PRINTER SETUP SEQUENCE JSR MCOUT ; START WITH COMMAND CHAR 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 RTS ; ------------ ; SPLIT SCREEN ; ------------ ; SPLIT SCREEN AT LINE [ARG1] ; DISABLE SPLIT IF [ARG1] = 0 ; IGNORE IF SPLIT ALREADY ENABLED OR [ARG1] >= 20 ZSPLIT: LDA ZBEGIN+ZMODE AND #%00100000 ;CHECK IF ENABLED BEQ ZSPOUT ;NOT, LEAVE LDA ARG1+LO ;GET # OF LINES FOR SCREEN BEQ NORL ;IF 0 THEN RESTORE SCREEN LDX SPSTAT ;CHECK IF ALREADY ENABLED BNE ZSPOUT ;IT IS CMP #20 ;IS SPLIT REALLY = WHOLE SCREEN BCS ZSPOUT ;YES, IGNORE PHA CLC ADC #1 ;ONE LINE ADDITIONAL TO SIZE GIVEN ;TO MAKE UP FOR STATUS LINE STA WBOTM ;TEMPORARILY FOR TOP SCREEN CLEAR STA SPSTAT ;NON ZERO = SCREEN IS SPLIT JSR HOME ;CLEAR FROM TOP TO BOTTOM (OF TOP SCREEN) LDA #$18 ;RESTORE BOTTOM FOR SCROLL STA WBOTM PLA ;GET @ OF LINES AGAIN CLC ADC #1 ;ADD 1 STA WTOP ;MAKE THAT THE TOP OF THE SECOND SCREEN LDA #1 STA CH STA EH LDA #$16 STA CV ;RESTORE CURSOR AFTER HOME CALL JMP PISSER ; TO MAKE CV WORK ZSPOUT: RTS NORL: ;RESTORE SCREEN TO FULL SCREEN MODE LDA #1 ;PUT CURSOR AT TOP OF SCREEN STA WTOP ;RESTORE FULL SCREEN ALIGNMENT LDA #0 STA LINCNT STA SPSTAT ;FLAG NOT SPLIT RTS ; ------ ; SCREEN ; ------ ; GO TO TOP WINDOW (TOP OF SCREEN) IF [A] = 1 ; GO TO BOTTOM OF SCREEN IF [A] = 0 ; IGNORE IF SPLIT NOT ENABLED OR [A] <> 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 ZBEGIN+ZMODE AND #%00100000 ;CHECK IF ENABLED BEQ ZSPOUT ;NOT, LEAVE LDA SPSTAT ;CHECK IF SCREEN IS SPLIT BEQ ZSPOUT ;NO, SO JUST LEAVE LDA ARG1+LO ;CHECK WHICH WINDOW BNE SCRN1 ;TOP SCREEN STA SPLITF ;SET FLAG TO SPLIT SCREEN (0) LDA #01 ;PUT CURSOR AT BOTTOM OF SCREEN STA CH STA EH LDA #$16 STA CV BNE SCRNP ;JMP TO RTN SCRN1: CMP #01 BNE ZSPOUT ;INVALID SCREEN ID STA SPLITF ;SET FLAG TO UNSCROLLING SCREEN (1) LDA #0 STA CH STA EH STA CV ;ALIGN AT TOP OF SCREEN SCRNP: JMP PISSER ;CALL RTN TO SET CURSOR (+ LEAVE) ; --------- ; RAZZ USER ; --------- BOOP EQU BELL ;MONITOR BELL ; ------------ ; CLEAR SCREEN ; ------------ CLS EQU HOME ;CLEAR & HOME CURSOR PISSER: LDA COL80 ;SEND APPROPRIATE TO SCREEN BEQ PISS ;IF = 0 THEN 40 COL. LDA #$0D BNE PIS ;JMP PISS LDA #$8D PIS JMP MCOUT END