; .TITLE "SOS Console Driver" ; .NOPATCHLIST ; .NOMACROLIST ; ;----------------------------------------------------------------------- ; ; SOS Console Driver ; ; Copyright (C) 1983 by Apple Computer Inc. ; All Rights Reserved ; ; Previous Copyright (C) 1980, 1981 ; ; ; Revisions: ; ; 1.00 14-Nov-80 Initial Release ; ; 1.12 23-Sep-81 ; Bug fixes: ; Download 1-8 characters. ; Download entire character set. ; Include saved screen state in console state table. ; Adjust all pointers for proper extended addressing. ; Fix SYNC to monitor positive edge of vertical blanking. ; Delete extraneous data returned by status calls 12, 13, & 14. ; Fix erase option of character and line delete. ; Extensions: ; Add video toggle on control-5. ; Add dump & restore contents of viewport. ; Change keyboard transform table to include alpha-lock data. ; Retain cursor on SYNC. ; ; 1.30 11-Jan-83 ; Bug fixes: ; Wait for pending download on close. ; Fix branch in 40 column horizontal shift right. ; Fix cursor in dump & restore contents of viewport. ; Disable interrupts while setting events and screen mode. ; Extensions: ; Turn on video iff buffer is empty. ; Set bit 7 on control characters read from screen ; (applies to char copy and screen read status). ; Don't dump viewport when displaying control characters. ; Add status request 9, read screen with normal/inverse flag. ; 1.31 17-Mar-83 ; Fix VERIFY to eleminate noise when setting screen switches. ; ;----------------------------------------------------------------------- ; ; updated source for ca65 assembler ; - add $ for hex numbers ; - update local labels from $ to @ ; - some tweaks for high/low byte ; - ASCII to byte ; - update macro ; - EQU to = ; - BLOCK to RES ; .feature labels_without_colons .setcpu "6502" .reloc DEVTYPE = $61 SUBTYPE = $01 APPLE = $0001 RELEASE = $1310 ; .PAGE ;----------------------------------------------------------------------- ; ; The macro SWITCH performs an N way branch based on a switch index. The ; maximum value of the switch index is 127 with bounds checking provided ; as an option. The macro uses the A and Y registers and alters the C, ; Z, and N flags of the status register, but the X register is unchanged. ; ; SWITCH [index], [bounds], adrs_table, [*] ; ; index This is the variable that is to be used as the switch index. ; If omitted, the value in the accumulator is used. ; ; bounds This is the maximum allowable value for index. If index ; exceeds this value, the carry bit will be set and execution ; will continue following the macro. If bounds is omitted, ; no bounds checking will be performed. ; ; adrs_table This is a table of addresses (low byte first) used by the ; switch. The first entry corresponds to index zero. ; ; * If an asterisk is supplied as the fourth parameter, the ; macro will push the switch address but will not exit to ; it; execution will continue following the macro. The ; program may then load registers or set the status before ; exiting to the switch address. ; ;----------------------------------------------------------------------- ; ; .MACRO SWITCH ; .IF "%1" <> "" ;If PARM1 is present, ; LDA %1 ; Load A with switch index ; .ENDC ; .IF "%2" <> "" ;If PARM2 is present, ; CMP #%2+1 ; Perform bounds checking ; BCS $3579 ; on switch index ; .ENDC ; ASL A ; TAY ; LDA %3+1,Y ;Get switch address from table ; PHA ; and push onto stack ; LDA %3,Y ; PHA ; .IF "%4" <> "*" ;If PARM4 is omitted, ; RTS ; Exit to code ; .ENDC ;Otherwise, drop through ; .IF "%2" <> "" ;$3579 ; .ENDC ; .ENDM .MACRO SWITCH index,bounds,adrs_table,noexec ;See SOS Reference .IFNBLANK index ;If PARM1 is present, LDA index ; load A with switch index .ENDIF .IFNBLANK bounds ;If PARM2 is present, CMP #bounds+1 ; perform bounds checking BCS @110 ; on switch index .ENDIF ASL A ;Multiply by 2 for table index TAY LDA adrs_table+1,Y ;Get switch address from table PHA ; and push onto Stack LDA adrs_table,Y PHA .IFBLANK noexec ; .IF noexec <> '*' ;If PARM4 is omitted, RTS ; exit to code ; .ENDIF .ENDIF @110 .ENDMACRO .PROC CONSOLE .SEGMENT "TEXT" .WORD $FFFF .WORD 59 .BYTE "Console Driver -- " .BYTE "Copyright (C) 1983 by Apple Computer Inc." .SEGMENT "DATA" ;---------------------------------------------------------------------- ; ; Device Handler Identification RES ; ;---------------------------------------------------------------------- ; IDBLK .WORD 0000 ;Link to next device handler .WORD CNSLDH ;Entry point address .BYTE 8 ;Length of device name .BYTE ".CONSOLE " .BYTE $80,$00,$00 ;Device, Slot & Unit numbers .BYTE DEVTYPE .BYTE SUBTYPE .BYTE 00 .WORD 0000 .WORD APPLE .WORD RELEASE .WORD 00 ;No configuration RES ; .PAGE ;---------------------------------------------------------------------- ; ; Global Data: ; ; SUSPFLSH: Suspend and Flush Output Flags ; 7 => Suspend Output ; 6 => Flush Output ; ; SCRNMODE: Current Screen Mode ; 7 => Off / On ; 6 => Text / Graphics ; 2 => Page 1 / Page 2 ; 1 => 40 Col / 80 Col ; 0 => B & W / Color ; ; ; State Flags: ; ; HMODE: Hardware Mode ; 7 => 40 Col / 80 Col ; 1 => 40 Col / 80 Col ; 0 => B & W / Color ; ; SMODE: Software Mode ; 5 => Normal / Inverse ; 4 => Disable / Enable Cursor ; 3 => Disable / Enable Scroll ; 2 => Disable / Enable Auto Carriage Return ; 1 => Disable / Enable Auto Line Feed ; 0 => Disable / Enable Auto Advance ; ; ; Permanant Zero Page Data: ; ; BASE1, BASE2: Screen Memory Pointers ; The base pointers point to the beginning of the current line. In ; 40 column mode, BASE1 points to the ASCII data while BASE2 points ; to the color information. In 80 column mode, BASE1 points to col- ; umn 0 of the viewport while BASE2 points to column 1. ; ; ; Temporary Zero Page Data: ; ; WORK1, WORK2: ; These pointers are used in conjunction with BASE1 and BASE2 for ; scrolling, shifting, etc. ; ; COUNT: ; Number of bytes read or written. ; ; ONEBYTE: ; Boolean flag for single byte read requests. ; ; BLANK: ; Holds an ASCII space in the current video mode (normal or inverse) ; for use in clearing the viewport. ; ; TEMPX: ; Temporary storage for X. ; ; FLAGS: ; Miscellaneous flags for use by SCROLL, SHIFT, SCRNDUMP, etc. ; ; TEMP1, TEMP2, TEMP3, TEMP4: ; General temporary storage for use by SCROLL, SHIFT, SCRNDUMP, etc. ; .PAGE ; ; SOS Global Data & Subroutines ; SUSPFLSH = $1902 ;Suspend & Flush flags SCRNMODE = $1906 ;Current Screen Mode ALLOCSIR = $1913 DEALCSIR = $1916 QUEEVENT = $191F SYSERR = $1928 ; ; SOS Error Codes ; XREQCODE = $20 ;Invalid request code XCTLCODE = $21 ;Invalid controlstatus code XCTLPARM = $22 ;Invalid controlstatus parm XNOTOPEN = $23 ;Device not open XNOTAVIL = $24 ;Device not available XNORESRC = $25 ;Unable to obtain resource ; ; Hardware I/O Addresses ; KAPORT = $C000 KBPORT = $C008 KYBDSTRB = $C010 KYBDCLR = $01 ;Clear keyboard interrupt flag KYBDDSBL = $01 ;Disable keyboard interrupts KYBDENBL = $81 ;Enable keyboard interrupts BELL = $C040 VMODE0 = $C050 ;Video mode switches VMODE1 = $C052 VMODE2 = $C054 VMODE3 = $C056 SCRLDSBL = $C0D8 ;Disable graphics scroll DNLDDSBL = $C0DA ;Disable character download DNLDENBL = $C0DB ;Enable character download VBLCLR = $18 ;Clear both VBL interrupt flags VBLDSBL = $18 ;Disable both VBL interrupts VBLENBL = $90 ;Enable VBL interrupt on CB2 E_REG = $FFDF ;Environment register E_IORB = $FFE0 ;6522 input/output register B E_PCR = $FFEC ;6522 peripheral control register E_IFR = $FFED ;6522 interrupt flag register E_IER = $FFEE ;6522 interrupt mask register B_REG = $FFEF ;Bank register ; ; ASCII Equates and Special Keys ; ASC_NUL = $00 ;Null ASC_SOH = $01 ;Start of Header ASC_STX = $02 ;Start of Text ASC_ETX = $03 ;End of Text ASC_ENQ = $05 ;Enquiry ASC_ACK = $06 ;Acknowledgement ASC_BS = $08 ;Backspace ASC_HT = $09 ;Horizontal Tab ASC_LF = $0A ;Line Feed ASC_VT = $0B ;Vertical Tab ASC_FF = $0C ;Form Feed ASC_CR = $0D ;Carriage Return ASC_NAK = $15 ;Negative Acknowledge ASC_CAN = $18 ;Cancel ASC_ESC = $1B ;Escape ASC_FS = $1C ;File Separator ASC_GS = $1D ;Group Separator ASC_US = $1F ;Unit Separator ASC_SP = $20 ;Space LARROW = ASC_BS ;Left Arrow RARROW = ASC_NAK ;Right Arrow UARROW = ASC_VT ;Up Arrow DARROW = ASC_LF ;Down Arrow ; ; Miscellaneous Equates ; TRUE = $80 FALSE = $00 BITON0 = $01 BITON2 = $04 BITON3 = $08 BITON4 = $10 BITON5 = $20 BITON6 = $40 BITON7 = $80 BITOFF0 = $FE BITOFF4 = $EF BITOFF5 = $DF BITOFF7 = $7F BUFMAX = $80 ;Maximum buffer size TEXTCSA = $C00 ;Text character set address ; .PAGE ;----------------------------------------------------------------------- ; ; SOS Device Handler Interface ; ;----------------------------------------------------------------------- ; SOSINT = $C0 REQCODE = SOSINT+0 ;SOS request code BUFFPTR = SOSINT+2 ;Buffer pointer REQCNT = SOSINT+4 ;Requested count RTNCNT = SOSINT+8 ;Returned count SCCODE = SOSINT+2 ;Status / Control code SCLIST = SOSINT+3 ;Status / Control list ; ; ;----------------------------------------------------------------------- ; ; Zero Page Data (preserved) and Zero Page Save Area ; ;----------------------------------------------------------------------- ; ZPDATA = SOSINT+10 BASEPTRS = ZPDATA+0 ;Screen memory base pointers BASE1 = BASEPTRS+0 ; even col. / text bytes BASE2 = BASEPTRS+2 ; odd col. / color bytes ZPLENGTH = 4 ; ZPSAVE .RES ZPLENGTH ; ; ;----------------------------------------------------------------------- ; ; Zero Page Data (temporary) ; ;----------------------------------------------------------------------- ; WORKPTRS = ZPDATA+ZPLENGTH WORK1 = WORKPTRS+0 WORK2 = WORKPTRS+2 COUNT = WORKPTRS+4 ;Current I/O count ONEBYTE = COUNT+2 ;One byte console read flag BLANK = ONEBYTE+1 TEMPX = BLANK+1 FLAGS = TEMPX+1 TEMP1 = FLAGS+1 TEMP2 = TEMP1+1 TEMP3 = TEMP2+1 TEMP4 = TEMP3+1 ; .PAGE ;----------------------------------------------------------------------- ; ; Console State Table ; ;----------------------------------------------------------------------- ; CONSTTBL = * ;Console state table ; ANYKYEVNT .RES 5 ;Any Key Event parameters ATTNEVNT .RES 5 ;Attention Event parameters ATTNCHAR .BYTE 0 ;Attention character ; DFLTTBL = * ;This RES initialized from default values ; KYBDMODE .BYTE 0 ;Console/Keyboard mode flag NEWLINE .BYTE 0 ;New Line flag NEWLNCHR .BYTE 0 ;New Line character NOWAIT .BYTE 0 ;No Wait flag ECHO .BYTE 0 ;Screen Echo flag CHCPYFLG .BYTE 0 ;Character Copy flag CHCPYCHR = ASC_NAK ;Character Copy character CHDELFLG .BYTE 0 ;Character Delete flag CHDELCHR = ASC_BS ;Character Delete character LNDELFLG .BYTE 0 ;Line Delete flag LNDELCHR = ASC_CAN ;Line Delete character ESCAPE .BYTE 0 ;Escape Mode flag ; SCRSTTBL = * ;Screen state table ; HMODE .BYTE 0 ;Hardware mode SMODE .BYTE 0 ;Software mode TPX .BYTE 0 ;Text position TPY .BYTE 0 VPL .BYTE 0 ;Viewport VPR .BYTE 79 VPT .BYTE 0 VPB .BYTE 23 TCF .BYTE $0F ;Text color TCB .BYTE 00 ; SCRSTLEN = *-SCRSTTBL ; DFLTLEN = *-DFLTTBL ; SCRSTSAV .RES SCRSTLEN ;Saved screen state table ; CONSTLEN = *-CONSTTBL ; .PAGE ;---------------------------------------------------------------------- ; ; Default Values for State Table ; ;---------------------------------------------------------------------- ; DFLTVAL .BYTE FALSE ;Console / Keyboard flag .BYTE FALSE ;Newline flag .BYTE ASC_CR ;Newline character .BYTE FALSE ;Nowait flag .BYTE TRUE ;Screen echo flag .BYTE TRUE ;Character copy flag .BYTE TRUE ;Character delete flags .BYTE TRUE ;Line delete flags .BYTE TRUE ;Escape mode flags .BYTE 02 ;Hardware mode .BYTE $0D ;Software mode .BYTE 0 ;Cursor position .BYTE 0 .BYTE 0 ;Viewport .BYTE 79 .BYTE 0 .BYTE 23 .BYTE $0F ;Text colors .BYTE 00 ; .PAGE ;----------------------------------------------------------------------- ; ; Private Variable Storage ; ;----------------------------------------------------------------------- ; KYBDBUFS = $1500 ;Type ahead buffers KABUF = KYBDBUFS KBBUF = KYBDBUFS+BUFMAX XFORMTBL = $1700 ;Keyboard transform table ; KADATA .BYTE 0 ;Temp Storage KBDATA .BYTE 0 ; for Interrupt Processing ; KEYCNT .BYTE 0 ;Buffered keystroke count BUFSIZ .BYTE 0 ;Current buffer size BUFHEAD .BYTE 0 ;Index of first character BUFTAIL .BYTE 0 ;Index of last character ; OPENFLG .BYTE 0 ;Device open flag READING .BYTE 0 ;Read in progress flag DSPLYCTL .BYTE 0 ;Display control characters ; SMFLAGS = * SMINV .BYTE 0 ;Inverse video SMCURSOR .BYTE 0 ;Cursor enabled SMSCROLL .BYTE 0 ;Scroll flag SMAUTOCR .BYTE 0 ;Auto CR SMAUTOLF .BYTE 0 ;Auto LF SMAUTOADV .BYTE 0 ;Auto advance ; VPHMAX .BYTE 79 ;viewport maximum horizontal index VPVMAX .BYTE 23 ;viewport maximum vertical index TCOLOR .BYTE $F0 ;text fg/bg color byte ; CTLINDX .BYTE 0 ;function buffer index CTLBUFF .RES 8 ;control function buffer CTLQUOTA .BYTE 0 ;parameter quota ; DNLDFLG .BYTE 00 ;Bit 7=Active, Bit 6=Request DNLDCEL .BYTE 00 ;Current download cell number DNLDCHR .BYTE 00 ;Current download ASCII code DNLDIMG .WORD 0000 ;Pointer to character image ; .PAGE ;---------------------------------------------------------------------- ; ; Addresses used as subroutine parameters and SIR request tables ; ;---------------------------------------------------------------------- ; ANYKYPARM .WORD ANYKYEVNT ATTNPARM .WORD ATTNEVNT ; KYBDSADR .WORD KYBDSTBL KYBDSTBL .BYTE 2,0 ;Keyboard interrupt .WORD KYBDMIH KYBDBANK .BYTE 0 KYBDSSIZ = *-KYBDSTBL ; DNLDSADR .WORD DNLDSTBL DNLDSTBL .BYTE 5,0,0,0,0 ;VBL positive .BYTE 6,0 ;VBL negative .WORD DNLDINT DNLDBANK .BYTE 0 .BYTE $10,0,0,0,0 ;Character download / Graphics scroll DNLDSSIZ = *-DNLDSTBL ; SYNCSADR .WORD SYNCSTBL SYNCSTBL .BYTE 5,0,0,0,0 ;VBL positive SYNCSSIZ = *-SYNCSTBL ; ; ;--------------------------------------- ; ; Base Calculator Address Tables ; ;--------------------------------------- ; BASL .BYTE $00,$80,$00,$80 .BYTE $00,$80,$00,$80 .BYTE $28,$A8,$28,$A8 .BYTE $28,$A8,$28,$A8 .BYTE $50,$D0,$50,$D0 .BYTE $50,$D0,$50,$D0 BASH .BYTE $04,$04,$05,$05 .BYTE $06,$06,$07,$07 .BYTE $04,$04,$05,$05 .BYTE $06,$06,$07,$07 .BYTE $04,$04,$05,$05 .BYTE $06,$06,$07,$07 ; .PAGE ;---------------------------------------------------------------------- ; ; Escape Command and Escape Operator Tables ; ;---------------------------------------------------------------------- ; ESCCMD .BYTE "B" ;Viewport bottom right .BYTE "T" ;Viewport top left .BYTE "V" ;Clear Viewport .BYTE "S" ;Clear Screen .BYTE "P" ;Clear to End of Page .BYTE "L" ;Clear to End of Line .BYTE "H" ;Home Cursor .BYTE ASC_BS ;Move left .BYTE ASC_NAK ;Move right .BYTE ASC_VT ;Move up .BYTE ASC_LF ;Move down ECMDCNT = *-ESCCMD ; ESCOP .BYTE ASC_ETX .BYTE ASC_STX .BYTE ASC_SOH .BYTE ASC_FS .BYTE ASC_GS .BYTE ASC_US .BYTE ASC_FF .BYTE ASC_BS .BYTE ASC_HT .BYTE ASC_VT .BYTE ASC_LF ; .PAGE ;----------------------------------------------------------------------- ; ; Console Device Handler ; ; This is the device handler's entry point. It sets the extended ; addressing bytes to zero and moves in the permanant zero page ; data, then switches to the appropriate request handler. If the ; request handler modifies the permanant zero page data, it must ; call ZPOUT before it exits to SOS. ; ;----------------------------------------------------------------------- ; CNSLDH = * LDX #$FF-ZPDATA LDY #00 TYA @010 STA $1400+ZPDATA,X ;Set extend bytes to zero CPX #ZPLENGTH BCS @020 LDA ZPSAVE,X STA ZPDATA,X ;Set up zero page data TYA @020 DEX BPL @010 ; SWITCH REQCODE,8,CREQSW ; ; CBADREQ LDA #XREQCODE ;Invalid request code JSR SYSERR ; CNOTOPEN LDA #XNOTOPEN ;Console is not open JSR SYSERR ; CREQSW .WORD CNSLREAD-1 .WORD CNSLWRIT-1 .WORD CNSLSTAT-1 .WORD CNSLCNTL-1 .WORD CBADREQ-1 .WORD CBADREQ-1 .WORD CNSLOPEN-1 .WORD CNSLCLOS-1 .WORD CNSLINIT-1 ; .PAGE ;----------------------------------------------------------------------- ; ; Keyboard Interrupt Handler ; ;----------------------------------------------------------------------- ; KYBDMIH = * ; ; Read keyboard data and clear interrupt ; LDX #KYBDCLR LDA KAPORT ;Read data port BMI @010 STX E_IFR ;No data ready -- clear RTS ; interrupt and exit @010 AND #BITOFF7 STA KADATA LDA KBPORT ;Read status port EOR #$3C STA KBDATA STX E_IFR ;Clear interrupt STX KYBDSTRB ; and keyboard strobe BMI KIHSPCL LDA KADATA CMP #ASC_CR BNE KIHXFORM LDA KBDATA AND #BITON2 ;Transform CR iff BNE KIHXFORM ; CTRL is held down JMP KIHA1KY ; ; Special key ; Check for console control commands ; Do not transform character code ; KIHSPCL AND #$36 ;Isolate A1, A2, CTRL, & SHIFT CMP #BITON2 BEQ @050 @010 JMP KIHA1KY ;Not a console control command @050 LDA KADATA CMP #'5' ;Toggle video? BCC @010 BNE @060 LDA SCRNMODE EOR #BITON7 STA SCRNMODE RTS @060 CMP #'6' ;Flush input buffer? BNE @070 LDA #00 STA KEYCNT STA BUFHEAD STA BUFTAIL RTS @070 CMP #'7' ;Suspend screen output? BNE @080 LDA SUSPFLSH EOR #BITON7 STA SUSPFLSH RTS @080 CMP #'8' ;Display control characters? BNE @090 LDA DSPLYCTL EOR #BITON7 STA DSPLYCTL RTS @090 CMP #'9' ;Flush screen output? BNE KIHA1KY LDA SUSPFLSH AND #BITOFF7 EOR #BITON6 STA SUSPFLSH RTS ; ; Standard key ; Transform character code ; Check for alpha lock ; KIHXFORM LDA KADATA @010 CMP #$7B ;Convert ASCII code to BCC @030 ; transform table index CMP #$7E BCC @020 EOR #$C0 BNE @040 @020 AND #$5F @030 ORA #$C0 @040 TAX LDA KBDATA ;Get control & shift keys LSR A AND #03 ORA XFORMTBL,X ;OR in key number TAX LDA XFORMTBL,X ;Need to test alpha lock? BPL @050 LDA KBDATA ;Check alpha lock key AND #BITON3 BEQ @050 TXA ORA #BITON0 ;Force shift key on TAX @050 LDA XFORMTBL,X ;Get key code AND #BITOFF7 STA KADATA ; ; Set bit 7 according to Apple 1 key ; KIHA1KY LDA KBDATA AND #BITON4 BEQ KIHCKEV LDA KADATA ORA #BITON7 STA KADATA ; ; Check for Any Key and Attention events ; KIHCKEV BIT READING ;If reading, BMI @010 ; ignore Any Key event LDA ANYKYEVNT ;Check Any Key Event BEQ @010 LDX ANYKYPARM LDY ANYKYPARM+1 JSR QUEEVENT ;Queue the event LDA #FALSE STA ANYKYEVNT ;Disable Any Key event BEQ @020 @010 LDA ATTNEVNT ;Check Attention Event BEQ KIHBFCH LDA KADATA CMP ATTNCHAR BNE KIHBFCH LDX ATTNPARM LDY ATTNPARM+1 JSR QUEEVENT ;Queue the event LDA #FALSE STA ATTNEVNT ;Disable Attention event @020 STA READING ;Terminate any read in progress STA KEYCNT ;Flush the input buffer STA BUFHEAD STA BUFTAIL STA SUSPFLSH ;Clear suspend & flush flags ; ; Buffer the character ; KIHBFCH LDX BUFSIZ ;Buffering enabled? BEQ @030 DEX CPX KEYCNT ;Any room in buffer? BCS @010 BIT BELL ;Buffer overflow BCC @030 @010 INC KEYCNT ;Bump the key count LDX BUFTAIL LDA KADATA STA KABUF,X ;Buffer the keystroke LDA KBDATA STA KBBUF,X INX CPX BUFSIZ ;Bump buffer tail pointer BCC @020 LDX #0 @020 STX BUFTAIL @030 RTS ; .PAGE ;----------------------------------------------------------------------- ; ; Subroutine GETKEY ; ; This subroutine gets the next keystroke from the type ahead buffer. ; On entry, the interrupt system must be enabled but the keyboard ; interrupt must be masked. On exit, if carry is clear, A contains ; the keyboard A port data and X contains the keyboard B port data; ; Y is undefined. If carry is set, no data is returned; either the ; buffer was empty and the NOWAIT flag is true, or the read was ; terminated by the interrupt handler. ; ;----------------------------------------------------------------------- ; GETKEY = * LDA KEYCNT ;Anything in the buffer? BNE @030 ; Yes PHP SEI LDA SCRNMODE ORA #BITON7 STA SCRNMODE ;Turn on video LDA E_REG ORA #BITON5 STA E_REG PLP BIT NOWAIT ;Check the NOWAIT flag BPL @010 ASL READING ;Clear the READING flag, RTS ; set carry, and exit ; @010 LDX BUFSIZ ;Preserve buffer size in X LDA #1 ;Set buffer size to 1 STA BUFSIZ LDA #KYBDENBL ;Unmask the keyboard STA E_IER BIT ESCAPE ;In ESCAPE mode? BVC @020 ; No CLC LDA TPX ;Preserve current cursor and LDY HMODE ; replace it with plus sign BPL @015 LSR A BCC @015 TAY LDA (BASE2),Y PHA AND #BITON7 ORA #$2B STA (BASE2),Y BCS @020 @015 TAY LDA (BASE1),Y PHA AND #BITON7 ORA #$2B STA (BASE1),Y @020 LDA KEYCNT ;Wait for a keystroke BEQ @020 BVC @026 ;Not in ESCAPE mode PLA ;Restore original cursor BCC @024 STA (BASE2),Y BCS @026 @024 STA (BASE1),Y @026 LDA #KYBDDSBL ;Mask the keyboard STA E_IER STX BUFSIZ ;Restore the buffer size SEC BIT READING ;Check the reading flag BPL @060 ; Exit with carry set ; @030 LDY BUFHEAD ;Get buffer index of keystroke DEC KEYCNT BNE @040 ;If KEYCNT = 0 LDA #0 STA BUFHEAD ; then BUFHEAD := BUFTAIL := 0 STA BUFTAIL BEQ @050 @040 INC BUFHEAD ; else BUFHEAD := BUFHEAD + 1 LDA BUFHEAD CMP BUFSIZ ;If BUFHEAD >= BUFSIZ BCC @050 LDA #0 ; then BUFHEAD := 0 STA BUFHEAD @050 LDA KABUF,Y ;Load the A and B port data LDX KBBUF,Y CLC @060 RTS ; .PAGE ;----------------------------------------------------------------------- ; ; Subroutine SCRNECHO ; ; This subroutine writes a single character to the screen. On entry, ; the character must be in A. On exit, all registers are undefined. ; ;----------------------------------------------------------------------- SCRNECHO = * BIT ECHO ;Screen Echo enabled? BPL @010 PHA JSR CURSOR ;Remove cursor PLA JSR PRINT ;Print the character JSR CURSOR ;Restore cursor @010 RTS ; ; ;----------------------------------------------------------------------- ; ; Subroutine BACKSP ; ; This subroutine performs the screen backspace when the console ; deletes an input character. On entry, the input buffer pointer ; must point to the character to be deleted and the overflow flag ; must be set to indicate that the character should be erased, or ; clear to indicate that it should be left on the screen. On exit, ; all registers are undefined. ; ;----------------------------------------------------------------------- BACKSP = * LDA ECHO BPL @020 ;Screen Echo not enabled LDY #0 LDA (BUFFPTR),Y ;Printable character? CMP #ASC_SP BCC @020 PHP ;Save overflow flag JSR CURSOR ;Remove cursor LDA #ASC_BS JSR PRINT ;Backspace PLP BVC @010 ;Don't erase LDA #ASC_SP JSR PRINT ;Erase the character LDA #ASC_BS JSR PRINT @010 JSR CURSOR ;Restore cursor @020 RTS ; .PAGE ;----------------------------------------------------------------------- ; ; Console Read Request ; ; Parameters: ; BUFFPTR: Pointer to caller's data buffer ; REQCNT: Requested read count ; RTNCNT: Pointer to actual read count ; ; Zero Page Temporary Storage ; COUNT: Number of bytes read ; ONEBYTE: TRUE if REQCNT = 1 ; ; If the ECHO or ESCAPE functions are enabled, this segment will call ; PRINT to display a character or perform a screen control function. ; ;----------------------------------------------------------------------- ; CNSLREAD = * ; ; Initialize read variables ; BIT OPENFLG BMI @010 JMP CNOTOPEN @010 BIT KYBDMODE ;Keyboard mode? BMI @030 LDA SMCURSOR ;Save cursor status PHA BMI @020 LDA #ASC_ENQ ;Turn on cursor JSR SCRNECHO @020 LDA #FALSE STA ONEBYTE ;Clear one byte read flag LDA REQCNT+1 BNE @040 LDA REQCNT CMP #1 BNE @040 ROR ONEBYTE ;Set one byte read flag BMI @040 ; @030 LDA REQCNT ;Make requested count even AND #BITOFF0 STA REQCNT ; @040 LDA ESCAPE AND #BITON7 STA ESCAPE ;Clear escape pending LDA #0 STA COUNT STA COUNT+1 ;Zero bytes read count PHP SEI STA SUSPFLSH ;Clear suspend & flush flags LDA #KYBDDSBL STA E_IER ;Mask the keyboard LDA #TRUE STA READING ;Set the READING flag PLP ; ; Main read loop ; CNSLLOOP LDA COUNT ;If COUNT >= REQCNT CMP REQCNT ; then goto CNSLEXIT LDA COUNT+1 SBC REQCNT+1 BCC @020 @010 JMP CNSLEXIT ; @020 JSR GETKEY ;Get next keystroke BCS @010 BIT KYBDMODE ;Console or Keyboard mode? BPL TSTESCAPE ; ; Keyboard mode read ; KYBDRDY PHA ;Save ASCII byte LDY #0 STA (BUFFPTR),Y ;Store data byte in buffer INY TXA STA (BUFFPTR),Y ;Store status byte in buffer LDA #02 JMP BUMPCNT ;Go update COUNT and BUFFPTR ; ; Console mode read ; TSTESCAPE BIT ECHO ;Test for Escape Mode BPL TSTCHDEL BIT ESCAPE BPL TSTCHDEL BVC @040 ;Escape not pending LDY #ECMDCNT-1 CMP #'a' BCC @010 CMP #'{' BCS @010 AND #BITOFF5 ;Upshift lower case alpha @010 CMP ESCCMD,Y ;Search for escape command BEQ @020 DEY BPL @010 ASL ESCAPE ;Not found -- clear pending flag BCS @030 @020 LDA ESCOP,Y ;Get screen control character JSR SCRNECHO @030 JMP CNSLLOOP ; @040 CMP #ASC_ESC ;Is this an ESC? BNE TSTCHDEL ROR ESCAPE ;Set escape pending BMI @030 ; TSTCHDEL BIT ONEBYTE ;Test for character delete BMI TSTLNDEL BIT CHDELFLG BPL TSTLNDEL CMP #CHDELCHR BNE TSTLNDEL LDA COUNT ;Anything to delete? ORA COUNT+1 BEQ @030 LDA COUNT BNE @010 DEC COUNT+1 ;Decrement current read count @010 DEC COUNT LDA BUFFPTR BNE @020 DEC BUFFPTR+1 ;Decrement buffer pointer @020 DEC BUFFPTR JSR BACKSP ;Backspace @030 JMP CNSLLOOP ; TSTLNDEL BIT ONEBYTE ;Test for line delete BMI TSTCHCPY BIT LNDELFLG BPL TSTCHCPY CMP #LNDELCHR BNE TSTCHCPY LDA ECHO BPL @050 BVC @040 ; @010 LDA COUNT ;Anything to delete? ORA COUNT+1 BEQ @060 LDA COUNT BNE @020 DEC COUNT+1 ;Decrement current read count @020 DEC COUNT LDA BUFFPTR BNE @030 DEC BUFFPTR+1 ;Decrement buffer pointer @030 DEC BUFFPTR BIT LNDELFLG JSR BACKSP ;Backspace JMP @010 ; @040 LDA #'\' JSR SCRNECHO ;Write "\ CR LF" LDA #ASC_CR JSR SCRNECHO LDA #ASC_LF JSR SCRNECHO @050 SEC LDA BUFFPTR ;Reset buffer pointer SBC COUNT STA BUFFPTR LDA BUFFPTR+1 SBC COUNT+1 STA BUFFPTR+1 LDA #0 ;Reset current read count STA COUNT STA COUNT+1 @060 JMP CNSLLOOP ; TSTCHCPY BIT ECHO ;Test for character copy BPL CNSLRDY BIT CHCPYFLG BPL CNSLRDY CMP #CHCPYCHR BNE CNSLRDY JSR SCRNPICK ;Copy character from screen ASL A CMP #$40 ROR A EOR #BITON7 ; CNSLRDY PHA ;Save character for new line test LDY #0 STA (BUFFPTR),Y ;Store character in buffer ; BIT ECHO ;Echo enabled? BPL @020 BVS @010 CMP #$20 ;Check for control character BCC @020 @010 JSR SCRNECHO @020 LDA #01 ; BUMPCNT PHA CLC ADC COUNT ;Update current read count STA COUNT BCC @010 INC COUNT+1 @010 PLA CLC ADC BUFFPTR ;Update buffer pointer STA BUFFPTR BCC TSTNEWLN INC BUFFPTR+1 LDA BUFFPTR+1 CMP #$FF BCC TSTNEWLN SBC #$80 ;Wrap buffer at FF page STA BUFFPTR+1 INC $1400+BUFFPTR+1 ; TSTNEWLN PLA ;Test for New Line BIT NEWLINE BPL @010 CMP NEWLNCHR BEQ CNSLEXIT @010 JMP CNSLLOOP ; CNSLEXIT ASL READING ;Clear the READING flag LDA #KYBDENBL STA E_IER ;Unmask the keyboard LDY #0 LDA COUNT ;Return the actual byte count STA (RTNCNT),Y INY LDA COUNT+1 STA (RTNCNT),Y BIT KYBDMODE BMI @020 PLA BMI @010 LDA #ASC_ACK ;Turn off cursor JSR SCRNECHO @010 JSR ZPOUT @020 RTS ; .PAGE ;----------------------------------------------------------------------- ; ; Console Write Request ; ; Parameters: ; BUFFPTR: Pointer to caller's data buffer ; REQCNT: Number of bytes to write ; ; Zero Page Temporary Storage ; COUNT: Number of bytes written ; ; Additional zero page data may be used to perform screen ; control functions. ; ;----------------------------------------------------------------------- ; CNSLWRIT = * BIT OPENFLG BMI @010 JMP CNOTOPEN @010 JSR CURSOR ;Remove Cursor LDA #0 STA COUNT ;Zero COUNT STA COUNT+1 ; @020 LDA COUNT ;Check for end of buffer CMP REQCNT LDA COUNT+1 SBC REQCNT+1 BCS @060 ;Go Exit @030 BIT SUSPFLSH ;Check suspend and flush flags BMI @030 ; Suspend BVS @050 ; Flush LDY #0 LDA (BUFFPTR),Y ;Get next byte JSR PRINT ;Print the byte INC BUFFPTR BNE @040 ;Bump pointer INC BUFFPTR+1 BNE @040 LDA #$80 STA BUFFPTR+1 ;Process buffer wrap around INC $1400+BUFFPTR+1 @040 INC COUNT BNE @020 ;Bump bytes read count INC COUNT+1 JMP @020 ; @050 LDA #00 STA CTLINDX ;Clear any pending cntl function ; @060 JSR CURSOR ;Restore cursor JMP ZPOUT ;Save Zero Page data and exit ; .PAGE ;----------------------------------------------------------------------- ; ; Subroutine PRINT ; ; This routine processes a single byte of output. Characters are ; printed by calling DISPLAY. Screen control functions are processed ; by accumulating any required parameters in CTLBUFF then switching ; to the appropriate screen control routine. ; ; Parameters: ; A: The byte to process ; ; Exit: ; A, X, Y: Undefined ; ;----------------------------------------------------------------------- ; PRINT = * LDY CTLINDX ;Get control function index BNE @010 ORA DSPLYCTL CMP #ASC_SP ;Display or control? BCS DISPLAY TAX LDA QUOTATBL,X ;Get function quota BEQ @020 STA CTLQUOTA TXA @010 STA CTLBUFF,Y ;Save function character INY STY CTLINDX ;Update buffer index CPY CTLQUOTA ;See if quota filled BCC @020 LDY #0 STY CTLINDX ;Zero buffer index SWITCH CTLBUFF,,CTLSWTBL,'*' @020 RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine DISPLAY ; ; This routine displays a single character. If auto advance is ; enabled, it calls CF_HT to advance the cursor. ; ; Parameters: ; A: The character to be displayed ; ; Exit: ; A, X, Y: Undefined ; ;---------------------------------------------------------------------- ; DISPLAY = * ORA #$80 ;set hi-bit EOR SMINV ;set normal or inverse PHA ;(for safe keeping) BIT HMODE ;80 column text? BPL @010 LDA TPX LSR A ;80 col: X=TPX/2 TAY ;carry bit clear? BCC @020 ;yes: use page 1 PLA STA (BASE2),Y ;80 col page two BCS @030 @010 LDY TPX ;40 col: X=TPX LDA TCOLOR STA (BASE2),Y ;set color byte @020 PLA STA (BASE1),Y ;80 col page one @030 BIT SMAUTOADV ;if auto advance, BPL @040 JMP CF_HT ;advance cursor @040 RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Control Function Quota and Switch Tables ; ;---------------------------------------------------------------------- QUOTATBL = * ;The Control Function Quota Table .RES 1,0 ; contains the total number of .RES 15,1 ; bytes required by the function, .RES 1,2 ; including the function character .RES 2,1 ; itself. A zero indicates that .RES 2,2 ; the function is unimplemented. .RES 1,2 .RES 1,1 .RES 3,2 .RES 1,3 .RES 1,0 .RES 4,1 CTLSWTBL = * .WORD CF_NUL-1 ;00 no-op .WORD CF_SOH-1 ;01 Save Environment & Release Viewport .WORD CF_STX-1 ;02 Set Viewport Upper Left .WORD CF_ETX-1 ;03 Set Viewport Lower Right .WORD CF_EOT-1 ;04 Restore Environment .WORD CF_ENQ-1 ;05 Cursor On .WORD CF_ACK-1 ;06 Cursor Off .WORD CF_BEL-1 ;07 Audible signal .WORD CF_BS-1 ;08 Backspace .WORD CF_HT-1 ;09 Forward Space .WORD CF_LF-1 ;0A Line Feed .WORD CF_VT-1 ;0B Reverse Line Feed .WORD CF_FF-1 ;0C Home Cursor .WORD CF_CR-1 ;0D Carriage Return .WORD CF_SO-1 ;0E Screen Off .WORD CF_SI-1 ;0F Screen On .WORD CF_DLE-1 ;10 Set Text Mode .WORD CF_DC1-1 ;11 Normal Video .WORD CF_DC2-1 ;12 Inverse Video .WORD CF_DC3-1 ;13 Foreground Color .WORD CF_DC4-1 ;14 Background Color .WORD CF_NAK-1 ;15 Set Text Options .WORD CF_SYN-1 ;16 Sync on VBL .WORD CF_ETB-1 ;17 Horizontal Shift .WORD CF_CAN-1 ;18 Go to X .WORD CF_EM-1 ;19 Go to Y .WORD CF_SUB-1 ;1A Go to X,Y .WORD CF_ESC-1 ;1B No-op .WORD CF_FS-1 ;1C Clear Screen .WORD CF_GS-1 ;1D Clear to End of Screen .WORD CF_RS-1 ;1E Clear Line .WORD CF_US-1 ;1F Clear to End of Line ; .PAGE ;---------------------------------------------------------------------- ; ; Screen Control Functions ; ; These routines perform all screen control functions. ; ; Parameters: ; All parameters are accumulated in CTLBUFF ; ; Exit: ; A, X, Y: Undefined ; ;---------------------------------------------------------------------- ; CF_NUL = * CF_ESC = * RTS ;NO-OP ; CF_SOH = * ;Save & Release Viewport LDY #SCRSTLEN @010 LDA SCRSTTBL-1,Y STA SCRSTSAV-1,Y DEY BNE @010 CLC LDA TPX ADC VPL STA TPX ;retain X posn LDA TPY ADC VPT STA TPY ;retain y posn LDA #0 STA VPL ;zero left margin STA VPT ;zero top margin LDA #$FF STA VPR ;Let VERIFY set the right edge STA VPB ; and bottom margin JMP VERIFY ; CF_STX = * ;SET VIEWPORT UPPER LEFT CLC LDA VPL ADC TPX ;at cursor posn STA VPL ;set left margin LDA VPT ADC TPY STA VPT ;set top margin LDA #0 STA TPX ;reset cursor X STA TPY ; and cursor Y JMP VERIFY ;and verify ; CF_ETX = * ;SET VIEWPORT LOWER RIGHT CLC LDA TPX ADC VPL STA VPR ;set left margin LDA TPY ADC VPT ;& bottom margin STA VPB JMP VERIFY ;and verify ; CF_EOT = * ;RESTORE VIEWPORT LDY #SCRSTLEN @010 LDA SCRSTSAV-1,Y STA SCRSTTBL-1,Y DEY BNE @010 JMP VERIFY ; CF_ENQ = * ;ENABLE CURSOR LDA SMODE ORA #BITON4 STA SMODE LDA #TRUE STA SMCURSOR RTS ; CF_ACK = * ;DISABLE CURSOR LDA SMODE AND #BITOFF4 STA SMODE LDA #FALSE STA SMCURSOR RTS ; CF_BEL = * ;Sound Bell BIT BELL RTS ; CF_BS = * ;BACKSPACE DEC TPX BPL @020 BIT SMAUTOCR ;BS at left: BPL @010 LDA VPHMAX ;Wrap to right STA TPX ; edge of viewport JMP CF_VT @010 INC TPX @020 RTS ; CF_HT = * ;ADVANCE LDA TPX CMP VPHMAX BCS @010 ;at edge? INC TPX ;no: advance RTS @010 BIT SMAUTOCR ;auto CR on? BPL CF_EXIT LDA #0 ;yes: wrap to STA TPX ;left margin JMP CF_LF ;& line feed ; CF_LF = * ;LINE FEED LDA TPY CMP VPVMAX BCS @010 ;at edge? INC TPY ;no: move down JMP TBASCAL ;calc base address @010 BIT SMSCROLL ;auto scroll? BPL CF_EXIT LDA #00 JMP SCROLL ;yes: go to it ; CF_VT = * ;REVERSE LINE FEED LDA TPY BEQ @010 ;at top? DEC TPY ;no: do it JMP TBASCAL ;calc base address @010 BIT SMSCROLL ;auto scroll? BPL CF_EXIT LDA #$80 JMP SCROLL ; CF_FF = * ;FORM FEED LDA #0 STA TPX ;reset TPX STA TPY ; and TPY JMP TBASCAL ;calc base address ; CF_CR = * ;CARRIAGE RETURN LDA #0 STA TPX ;reset TPX BIT SMAUTOLF ;auto LF set? BPL CF_EXIT JMP CF_LF ;yes: go to it ; CF_SO = * ;SCREEN OFF LDA #FALSE STA SCRNMODE JMP VERIFY ; CF_SI = * ;SCREEN ON LDA #TRUE STA SCRNMODE JMP VERIFY ; CF_DLE = * ;SET HARDWARE MODE LDA CTLBUFF+1 STA HMODE JMP VERIFY ; CF_DC1 = * ;NORMAL VIDEO LDA SMODE AND #BITOFF5 ;reset INVERSE bit STA SMODE LDA #FALSE STA SMINV CF_EXIT RTS ; CF_DC2 = * ;INVERSE VIDEO LDA SMODE ORA #BITON5 ;set INVERSE bit STA SMODE LDA #TRUE STA SMINV RTS ; CF_DC3 = * ;FOREGROUND COLOR LDA CTLBUFF+1 STA TCF JMP VERIFY ;set TCOLOR ; CF_DC4 = * ;BACKGROUND COLOR LDA CTLBUFF+1 STA TCB JMP VERIFY ;set TCOLOR ; CF_NAK = * ;SET SOFTWARE MODE LDA CTLBUFF+1 AND #$0F STA CTLBUFF+1 LDA SMODE ;Save bits 7-4 AND #$F0 ORA CTLBUFF+1 STA SMODE JMP VERIFY ; CF_SYN = * ;SYNCHRONIZE WITH VBL LDA #SYNCSSIZ LDX SYNCSADR LDY SYNCSADR+1 JSR ALLOCSIR ;Allocate CB2 for VBL BCS CF_EXIT JSR CURSOR ;Restore cursor while waiting PHP SEI LDA E_PCR AND #$1F ORA #$60 ;Set up CB2 to monitor STA E_PCR ; VBL positive edge LDA #08 STA E_IER STA E_IFR PLP @010 BIT E_IFR ;Wait for VBL edge BEQ @010 JSR CURSOR ;Remove cursor LDA #SYNCSSIZ LDX SYNCSADR LDY SYNCSADR+1 JMP DEALCSIR ;Release CB2 resource ; CF_ETB = * ;HORIZONTAL SCROLL LDA CTLBUFF+1 @010 JMP SHIFT ; CF_CAN = * ;Go To X LDA CTLBUFF+1 CMP VPHMAX ;out of range? BCC @010 LDA VPHMAX ;Set to right margin @010 STA TPX RTS ; CF_EM = * ;Go To Y LDA CTLBUFF+1 CMP VPVMAX ;out of range? BCC @010 LDA VPVMAX ;Set to top @010 STA TPY JMP TBASCAL ;get base address ; CF_SUB = * ;Go To X, Y JSR CF_CAN LDA CTLBUFF+2 STA CTLBUFF+1 JMP CF_EM ; CF_FS = * ;CLEAR SCREEN JSR CF_FF JMP CLREOS ; CF_GS = * ;CLEAR TO EOS JMP CLREOS ; CF_RS = * ;CLEAR LINE LDA #0 STA TPX JMP CLREOL ; CF_US = * ;CLEAR TO EOL JMP CLREOL ; .PAGE ;---------------------------------------------------------------------- ; ; Console Status Request ; ; Parameters: ; SCCODE: Status / Control code ; SCLIST: Pointer to caller's status / control list ; ; Before switching to the appropriate request handling code, ; Y is set to zero. ; ;---------------------------------------------------------------------- ; CNSLSTAT = * BIT OPENFLG ;Is the Console open? BMI @010 JMP CNOTOPEN @010 SWITCH SCCODE,18,CSTATSW,'*' BCS CBADCTL LDY #0 RTS ; CBADCTL LDA #XCTLCODE ;Invalid control code JSR SYSERR ; CSTATSW .WORD CSTAT00-1 .WORD CSTAT01-1 .WORD CSTAT02-1 .WORD CSTAT03-1 .WORD CSTAT04-1 .WORD CSTAT05-1 .WORD CSTAT06-1 .WORD CBADCTL-1 .WORD CSTAT08-1 .WORD CSTAT09-1 .WORD CSTAT10-1 .WORD CSTAT11-1 .WORD CSTAT12-1 .WORD CSTAT13-1 .WORD CSTAT14-1 .WORD CSTAT15-1 .WORD CSTAT16-1 .WORD CSTAT17-1 .WORD CSTAT18-1 ; CSTAT00 RTS ;0 -- NOP ; CSTAT01 = * ;1 -- Console Status Table LDA (SCLIST),Y CMP #CONSTLEN BCS @010 LDA #XCTLPARM JSR SYSERR @010 LDA #CONSTLEN STA (SCLIST),Y TAY @020 LDA CONSTTBL-1,Y STA (SCLIST),Y DEY BNE @020 RTS ; CSTAT02 = * ;2 -- New Line LDA NEWLINE STA (SCLIST),Y INY LDA NEWLNCHR STA (SCLIST),Y RTS ; CSTAT03 = * ;3 -- Console / Keyboard mode LDA KYBDMODE STA (SCLIST),Y RTS ; CSTAT04 = * ;4 -- Buffer Size LDA BUFSIZ STA (SCLIST),Y RTS ; CSTAT05 = * ;5 -- Current Key Count LDA KEYCNT STA (SCLIST),Y RTS ; CSTAT06 LDY #5 ;6 -- Attention Event @010 LDA ATTNEVNT,Y STA (SCLIST),Y DEY BPL @010 RTS ; CSTAT08 LDY #4 ;8 -- Any Key Event @010 LDA ANYKYEVNT,Y STA (SCLIST),Y DEY BPL @010 RTS ; CSTAT09 = * ;09 -- Read Screen with norm/inv JSR SCRNPICK EOR #BITON7 EOR SMCURSOR LDY #0 STA (SCLIST),Y RTS ; CSTAT10 = * ;10 -- No Wait Input LDA NOWAIT STA (SCLIST),Y RTS ; CSTAT11 = * ;11 -- Screen Echo LDA ECHO STA (SCLIST),Y RTS ; CSTAT12 = * ;12 -- Character Copy LDA CHCPYFLG STA (SCLIST),Y RTS ; CSTAT13 = * ;13 -- Character Delete LDA CHDELFLG STA (SCLIST),Y RTS ; CSTAT14 = * ;14 -- Line Delete LDA LNDELFLG STA (SCLIST),Y RTS ; CSTAT15 = * ;15 -- Escape Functions LDA ESCAPE STA (SCLIST),Y RTS ; CSTAT16 = * ;16 -- Cursor Position LDA TPX STA (SCLIST),Y INY LDA TPY STA (SCLIST),Y RTS ; CSTAT17 = * ;17 -- Pick Character JSR SCRNPICK ASL A CMP #$40 ROR A EOR #BITON7 LDY #0 STA (SCLIST),Y RTS ; CSTAT18 = * ;18 -- Screen Dump LDA HMODE STA (SCLIST),Y INY LDA VPHMAX STA (SCLIST),Y INY LDA VPVMAX STA (SCLIST),Y LDA #00 BIT DSPLYCTL BMI @010 JMP SCRNDUMP @010 STA (SCLIST),Y ;If control characters are being DEY ; displayed, dump a null viewport STA (SCLIST),Y RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Console Control Request ; ; Parameters: ; SCCODE: Status / Control code ; SCLIST: Pointer to caller's status / control list ; ; Before switching to the appropriate request handler, Y is ; set to zero and A is loaded with the first byte of the list. ; ;---------------------------------------------------------------------- ; CNSLCNTL = * BIT OPENFLG ;Console open? BPL @010 SWITCH SCCODE,18,CCNTLSW,'*' BCS @020 LDY #00 LDA (SCLIST),Y RTS ; @010 JMP CNOTOPEN ; @020 JMP CBADCTL ; CCNTLSW .WORD CCNTL00-1 .WORD CCNTL01-1 .WORD CCNTL02-1 .WORD CCNTL03-1 .WORD CCNTL04-1 .WORD CCNTL05-1 .WORD CCNTL06-1 .WORD CBADCTL-1 .WORD CCNTL08-1 .WORD CBADCTL-1 .WORD CCNTL10-1 .WORD CCNTL11-1 .WORD CCNTL12-1 .WORD CCNTL13-1 .WORD CCNTL14-1 .WORD CCNTL15-1 .WORD LOADSET-1 .WORD LOAD8-1 .WORD CCNTL18-1 ; CCNTL00 LDA E_IER ;0 -- Reset PHA ;Save current interrupt state LDA #KYBDDSBL ; and mask off interrupts STA E_IER LDA #BUFMAX STA BUFSIZ ;Set buffer size to maximum LDA #00 STA KEYCNT ;Flush buffer STA BUFHEAD STA BUFTAIL STA READING ;No read in progress STA ANYKYEVNT ;Disable any key event STA ATTNEVNT ;Disable attention event STA CTLINDX ;Abort control function in progress STA DSPLYCTL ;Clear display control char. flag STA SUSPFLSH ;Clear suspend & flush output flags JSR CURSOR ;Remove cursor LDX #DFLTLEN @010 LDA DFLTVAL-1,X ;Copy configuration RES STA DFLTTBL-1,X DEX BNE @010 JSR CF_SOH ;Save screen state & verify JSR CURSOR ;Restore the cursor JSR ZPOUT ;Save screen zero page PLA AND #KYBDENBL ;Restore previous interrupt state ORA #BITON7 STA E_IER RTS ; CCNTL01 = * ;1 -- Console Status Table CMP #CONSTLEN BEQ @010 LDA #XCTLPARM JSR SYSERR @010 JSR CURSOR LDY #CONSTLEN @020 LDA (SCLIST),Y DEY STA CONSTTBL,Y BNE @020 JSR VERIFY JSR CURSOR JSR ZPOUT RTS ; CCNTL02 = * ;2 -- New Line AND #BITON7 STA NEWLINE INY LDA (SCLIST),Y STA NEWLNCHR RTS ; CCNTL03 = * ;3 -- Console / Keyboard mode AND #BITON7 STA KYBDMODE RTS ; CCNTL04 = * ;4 -- Buffer Size CMP #BUFMAX+1 BCC @010 LDA #XCTLPARM JSR SYSERR @010 LDX #KYBDDSBL STX E_IER STY KEYCNT STY BUFHEAD STY BUFTAIL STA BUFSIZ LDX #KYBDENBL STX E_IER RTS ; CCNTL05 LDA E_IER ;5 -- Flush Buffer PHA LDA #KYBDDSBL STA E_IER STY KEYCNT STY BUFHEAD STY BUFTAIL PLA AND #KYBDENBL ORA #BITON7 STA E_IER RTS ; CCNTL06 PHP ;6 -- Attention Event SEI LDY #5 @010 LDA (SCLIST),Y STA ATTNEVNT,Y DEY BPL @010 PLP RTS ; CCNTL08 PHP ;8 -- Any Key Event SEI LDY #4 @010 LDA (SCLIST),Y STA ANYKYEVNT,Y DEY BPL @010 PLP RTS ; CCNTL10 = * ;10 -- No Wait Input AND #BITON7 STA NOWAIT RTS ; CCNTL11 = * ;11 -- Screen Echo AND #BITON7+BITON6 STA ECHO RTS ; CCNTL12 = * ;12 -- Character Copy AND #BITON7 STA CHCPYFLG RTS ; CCNTL13 = * ;13 -- Character Delete AND #BITON7+BITON6 STA CHDELFLG RTS ; CCNTL14 = * ;14 -- Line Delete AND #BITON7+BITON6 STA LNDELFLG RTS ; CCNTL15 = * ;15 -- Escape Functions AND #BITON7 STA ESCAPE RTS ; CCNTL18 = * ;18 -- Restore contents of viewport BIT DSPLYCTL BMI @020 INY EOR HMODE BMI @010 LDA (SCLIST),Y CMP VPHMAX BNE @010 INY LDA (SCLIST),Y CMP VPVMAX BNE @030 LDA #$80 JMP SCRNDUMP ; @010 LDA (SCLIST),Y INY ORA (SCLIST),Y BNE @030 @020 RTS ; @030 LDA #XCTLPARM JSR SYSERR ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine LOADCHR ; ; This subroutine is called to load an ASCII code and a character ; image into one of the character download cells in the text pages. ; ; LOADCHR requires four bytes of zero page storage for pointers. In ; order to make it callable from either a device handler or an ; interrupt processor, all zero page references are indexed by X. ; On entry, the X register must contain the zero page offset to the ; character image pointer. The two bytes following the image ; pointer are used to address the download locations in the text ; page. ; ; Input Parameters: ; DNLDCEL -- character download cell number: [0,7] ; DNLDCHR -- ASCII character code: [0,7F] ; X reg -- zero page offset to pointers ; (0,X) image pointer set by caller ; (2,X) download cell pointer set by LOADCHR ; ; On exit, DNLDCEL, DNLDCHR, and X will be unchanged. The image ; pointer will have been incremented by eight. A and Y are destroyed. ; ;---------------------------------------------------------------------- ; DIMGPTR = 00 ;Zero page pointer to image DCELPTR = 02 ;Zero page pointer to cell ; LOADCHR = * LDY #00 ;Use Y for row counter @010 LDA DNLDCEL ;Set up cell pointer AND #03 ; for ASCII code ORA DCPTRL,Y STA DCELPTR,X LDA DNLDCEL LSR A LSR A CPY #04 ROL A ORA #08 STA DCELPTR+1,X LDA DNLDCHR ;Store ASCII code into STA (DCELPTR,X) ; download cell LDA DCELPTR+1,X ;Fix cell pointer EOR #$0C ; for character image STA DCELPTR+1,X LDA (DIMGPTR,X) ;Store character image STA (DCELPTR,X) ; into download cell INC DIMGPTR,X ;Increment the image pointer BNE @020 INC DIMGPTR+1,X @020 INY ;Increment the row number CPY #08 BCC @010 ;Not done yet RTS ; DCPTRL = * ;Table of download cell addresses .BYTE $78,$7C,$F8,$FC .BYTE $78,$7C,$F8,$FC ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine DNLDINT ; ; This subroutine processes the VBL interrupt that signals the ; completion of a character download cycle. If the REQUEST bit of ; DNLDFLG is set, another RES of eight characters will be ; downloaded; otherwise, the CB1 and CB2 resources will be ; released and the ACTIVE bit will be cleared. DNLDINT assumes ; that the X register points to a four byte area on the zero page ; that can be used for LOADCHR. ; ;---------------------------------------------------------------------- ; DNLDINT = * BIT DNLDDSBL ;Disable download LDA #VBLDSBL STA E_IER ;Mask VBL interrupts BIT DNLDFLG ;Test REQUEST bit BVC @030 CLI ;Enable interrupts LDA #07 STA DNLDCEL ;Start with cell 7 LDA DNLDIMG STA DIMGPTR,X ;Set up IMAGE pointer LDA DNLDIMG+1 STA DIMGPTR+1,X @010 JSR LOADCHR ;Load one character image INC DNLDCHR ;Bump character code BPL @020 ASL DNLDFLG ;Clear REQUEST bit @020 DEC DNLDCEL ;Bump cell number BPL @010 ;More to do LDA DIMGPTR,X STA DNLDIMG ;Save IMAGE pointer LDA DIMGPTR+1,X STA DNLDIMG+1 JMP DNLD_GO ;Enable downloading ; @030 ASL DNLDFLG ;Clear ACTIVE bit LDA #DNLDSSIZ LDX DNLDSADR LDY DNLDSADR+1 JSR DEALCSIR ;Deallocate SIRs RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine GETSIRS ; ; This subroutine allocates SIRs 5 & 6 and initializes them to ; monitor VBL for character downloading. If the SIRs can not be ; allocated, it sets an error code and returns directly to the ; dispatcher. ; ;---------------------------------------------------------------------- ; GETSIRS = * BIT DNLDFLG ;Wait for any previous BMI GETSIRS ; request to finish LDA #DNLDSSIZ LDX DNLDSADR LDY DNLDSADR+1 JSR ALLOCSIR BCS @010 PHP SEI LDA E_PCR ;Set CB1 to monitor VBL AND #$0F ; negative edge and ORA #$60 ; CB2 to monitor STA E_PCR ; positive edge LDA #VBLDSBL STA E_IER PLP RTS ; @010 PLA ; pull caller's PLA ; address, and LDA #XNORESRC ; return to dispatcher JSR SYSERR ; with an error ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine LOADSET ; ; This subroutine is called to initiate downloading of the entire ; text screen character set. LOADSET calls GETSIRS to set up the ; 6522 to monitor VBL and interrupt on the negative edge. It then ; copys the character set to the screen's local data area, sets the ; request bit, and enables the VBL interrupt. The VBL interrupt ; processor, DNLDINT, will complete the actual downloading. ; ; Parameters: ; SCLIST: Pointer to caller's 1024 byte character set ; ; Zero Page Temporary Storage: ; WORK1: Pointer to system's character set ; ;---------------------------------------------------------------------- ; LOADSET = * JSR GETSIRS LDA #TEXTCSA ;/$100 STA WORK1+1 STA DNLDIMG+1 LDA #ASC_NUL STA DNLDCHR LDX #4 ;Set X to move 4 pages LDY #0 ;Set Y to move full page LDA SCLIST+1 CMP #$FB BCC @010 SBC #$80 ;Adjust address to avoid STA SCLIST+1 ; bank wrap around INC $1400+SCLIST+1 @010 LDA (SCLIST),Y ;Copy character set to STA (WORK1),Y ; text char set buffer INY BNE @010 INC SCLIST+1 INC WORK1+1 DEX BNE @010 LDA #$C0 ;Set download active STA DNLDFLG ; and request flags LDA #VBLENBL STA E_IER ;Enable interrupts in VBL neg RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine LOAD8 ; ; This subroutine is called to download up to eight text character ; images. LOAD8 calls GETSIRS to set up the 6522 to monitor VBL ; and interrupt on the negative edge. It then loads the character ; images into the screen's download cells and enables downloading ; and the VBL interrupt. The download operation is completed by ; the interrupt processor DNLDINT. ; ; Parameters: ; SCLIST: Pointer to caller's character sets ; ; Zero Page Temporary Data: ; COUNT: Number of characters to download ; WORK1: Pointer to character image for LOADCHR ; WORK2: Work area for LOADCHR ; ;---------------------------------------------------------------------- ; LOAD8 = * CMP #01 ;Check download count BCS @010 RTS ; @010 CMP #09 BCC @020 LDA #XCTLPARM ;Too many JSR SYSERR ; @020 STA COUNT JSR GETSIRS ; INC SCLIST ;Bump list address BNE @030 ; to first character INC SCLIST+1 ; @030 LDA #08 STA DNLDCEL ; @040 LDY #00 LDA (SCLIST),Y ;Get character code STA DNLDCHR INC SCLIST ;Bump list address BNE @050 ; to character image INC SCLIST+1 ; @050 LDA #03 STA WORK1+1 LDA DNLDCHR ASL A ASL A ROL WORK1+1 ;Set up address of character ASL A ; image in C00 to FFF space ROL WORK1+1 STA WORK1 ; LDY #07 @060 LDA (SCLIST),Y ;Copy character image STA (WORK1),Y ; to C00 image space DEY BPL @060 ; DEC DNLDCEL LDX #WORK1 JSR LOADCHR ;Download this character ; LDA DNLDCEL CMP COUNT BCS @050 ;Do same character again LDA #08 ADC SCLIST ;Bump list address STA SCLIST ; to next character BCC @070 INC SCLIST+1 @070 DEC COUNT BNE @040 ; LDA #$80 ;Set download active STA DNLDFLG DNLD_GO BIT DNLDENBL LDA #VBLCLR STA E_IFR ;Clear both VBL flags @080 BIT E_IORB ;Check composite blanking BVC @090 BIT E_IFR ;Check VBL flags BEQ @080 @090 STA E_IFR ;Clear VBL flags LDA #VBLENBL ;Enable VBL interrupt STA E_IER RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Console Open Request ; ;---------------------------------------------------------------------- ; CNSLOPEN = * BIT OPENFLG ;Console open? BPL @010 ; No LDA #XNOTAVIL JSR SYSERR ; @010 LDA #KYBDSSIZ ;Allocate the keyboard interrupt LDX KYBDSADR LDY KYBDSADR+1 JSR ALLOCSIR BCS @020 LDA #TRUE STA OPENFLG ;Set console open JSR CCNTL00 ;Reset console parameters PHP SEI LDA E_PCR AND #$F1 ORA #02 ;Set up keyboard interrupt STA E_PCR PLP LDA #KYBDCLR STA E_IFR ;Clear keyboard flag BIT KYBDSTRB ;Clear the keyboard strobe LDA #KYBDENBL STA E_IER ;Unmask keyboard interrupts CLC RTS ; @020 LDA #XNORESRC ;Couldn't get keyboard resource JSR SYSERR ; .PAGE ;---------------------------------------------------------------------- ; ; Console Close Request ; ;---------------------------------------------------------------------- ; CNSLCLOS = * ASL OPENFLG ;Console open? BCS @010 ; Yes JMP CNOTOPEN ; @010 BIT DNLDFLG ;Wait for pending download BMI @010 LDA #KYBDDSBL STA E_IER ;Mask keyboard interrupts BIT KYBDSTRB ;Clear the keyboard strobe LDA #KYBDSSIZ LDX KYBDSADR LDY KYBDSADR+1 JSR DEALCSIR ;Deallocate the keyboard interrupt RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Console Initialization Request ; ;---------------------------------------------------------------------- ; CNSLINIT = * LDA #FALSE STA OPENFLG LDA B_REG ;Set bank register for STA KYBDBANK ; keyboard and download STA DNLDBANK ; interrupt handlers LDA #TEXTCSA ;/$100 STA SCLIST+1 LDA #00 STA $1400+SCLIST+1 JSR LOADSET CLC RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine VERIFY ; ; This subroutine checks the screen's hardware mode, software mode, ; and viewport parameters for self consistency. It also sets the ; screen switches and the following internal variables: ; HMODE, SMINV, SMCURSOR, SMSCROLL, SMAUTOCR, SMAUTOLF, ; SMAUTOADV, VPHMAX, VPVMAX, and TCOLOR ; ; Parameters: none ; ; Exit: ; A, X, Y: Undefined ; ;---------------------------------------------------------------------- ; VERIFY = * LDA HMODE ;Validate HMODE AND #03 ; and set 80 column ASL A ; flag in bit 7 CMP #04 BCC @010 LDA #04 @010 ROR A STA HMODE LDY SMODE ;Preserve SMODE LDA #00 LDX #5 @020 STA SMFLAGS,X LSR SMODE ;Set SMODE flags ROR SMFLAGS,X DEX BPL @020 STY SMODE LDA #79 BIT HMODE ;Screen width := If 80 column, BMI @100 ; then 79. LDA #39 ; else 39. @100 CMP VPR ;VPR <= Screen width BCS @110 STA VPR @110 LDA VPR CMP VPL ;VPL <= VPR BCS @120 STA VPL @120 SEC LDA VPR ;VPHMAX := SBC VPL ; VPR - VPL STA VPHMAX CMP TPX ;TPX <= VPHMAX BCS @200 STA TPX @200 LDA #23 CMP VPB ;VPB <= Screen height BCS @210 STA VPB @210 LDA VPB CMP VPT ;VPT <= VPB BCS @220 STA VPT @220 SEC LDA VPB ;VPVMAX := SBC VPT ; VPB - VPT STA VPVMAX CMP TPY ;TPY <= VPVMAX BCS @300 STA TPY @300 LDA TCB AND #$0F ;TCB=TCB MOD 16 STA TCB LDA TCF AND #$0F ;TCF=TCF MOD 16 STA TCF ASL A ASL A ASL A ;SET TCOLOR := ASL A ORA TCB ;TCF * 16 + TCB STA TCOLOR PHP SEI LDA SCRNMODE ;Check screen mode ASL A BMI @500 ; Graphics LDA E_REG ORA #BITON5 BCS @400 AND #BITOFF5 @400 STA E_REG LDA HMODE AND #03 BCC @410 ORA #BITON7 @410 STA SCRNMODE ;Set screen mode LSR A AND #01 TAY LDA #00 ROL A TAX LDA VMODE0,X ;B&W / Color LDA VMODE1,Y ;40 / 80 Column BIT VMODE2 ;Page 1 always BIT VMODE3 ;Text of course @500 PLP JSR TBASCAL ;New base addr. RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine CURSOR ; ; This subroutine displays or removes the cursor by inverting the ; character at the current cursor position. ; ; Parameters: none ; ; Exit: ; A, X, Y: Undefined ; ;---------------------------------------------------------------------- ; CURSOR = * BIT SMCURSOR ;is cursor enabled? BPL @020 ;if not, exit LDA TPX BIT HMODE BPL @010 ;40 col: X=TPX LSR A ;80 col: X=TPX/2 BCC @010 TAY LDA (BASE2),Y ;get character EOR #$80 ;and invert it STA (BASE2),Y ;put it back RTS @010 TAY LDA (BASE1),Y ;get character EOR #$80 ;and invert it STA (BASE1),Y ;put it back @020 RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Single Character Screen Read (Console character copy) ; ; This subroutine returns the character at the current cursor position. ; ; Parameters: none ; ; Exit: ; A: character ; X, Y: Undefined ; ; ;---------------------------------------------------------------------- ; SCRNPICK = * LDA TPX TAY BIT HMODE BPL @010 ;40 Col -- Y := TPX LSR A ;80 Col -- Y := TPX/2 TAY BCC @010 LDA (BASE2),Y ;Read odd text page BCS @020 @010 LDA (BASE1),Y ;Read even text page @020 RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine TBASCAL -- Text Base Address Calculator ; ; This subroutine sets the base address registers, BASE1 and BASE2, ; to point to the current line in screen memory. BASE1 always points ; to column 0 of the current viewport while BASE2 points to column 1. ; ; Entry TBASCAL: ; Parameters: none ; ; Entry TBASCAL1: ; Parameters: ; X: Absolute screen line number ; ; Exit (either entry point): ; A: Undefined ; X: Absolute screen line number ; Y: Unchanged ; ;---------------------------------------------------------------------- ; TBASCAL = * CLC LDA TPY ;vertical position ADC VPT ; + viewport top TAX TBASCAL1 = * CLC LDA VPL ;viewport left: BIT HMODE BPL @010 ;if 80 column mode, LSR A ;then divide by two @010 PHP ADC BASL,X ;base address (LO) STA BASE1 ;same for both pages STA BASE2 LDA BASH,X ;base address (HI) PLP BCC @020 DEC BASE1 ;Odd window adjustment EOR #$0C @020 STA BASE1+1 ;even page address EOR #$0C STA BASE2+1 ;odd page address RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine CLREOL -- Clear to End of Line ; ; This subroutine clears the current line from the current cursor ; position to the end of the line. The starting position may be ; passed in Y using the CLREOL1 entry point. The text base address ; pointers, BASE1 and BASE2, must point to the current line. ; ; Entry CLREOL: ; Parameters: none ; ; Entry CLREOL1: ; Parameters: ; Y: Starting horizontal position ; ; Zero Page Temporary Storage: ; BLANK, TEMPX ; ; Exit (either entry point): ; A, Y: Undefined ; X: Preserved ; ;---------------------------------------------------------------------- ; CLREOL = * LDY TPX ;horizontal position CLREOL1 = * LDA #$80+ASC_SP ;Set up a blank EOR SMINV STA BLANK BIT HMODE BPL @200 TYA BNE @150 ; ; 80 column clear full line ; LDA VPHMAX ;Start at right edge LSR A TAY LDA BLANK ;Load the blank BCC @110 @100 STA (BASE2),Y ;Clear odd column @110 STA (BASE1),Y ; then even column DEY BPL @100 ;Repeat to BOL RTS ; ; 80 column clear to end of line ; @150 STX TEMPX ;Save X CLC SBC VPHMAX ;Calculate negative number TAX ; of bytes to blank TYA LSR A TAY LDA BLANK ;Load the blank BCS @170 @160 STA (BASE1),Y INX BPL @180 @170 STA (BASE2),Y INY INX BMI @160 @180 LDX TEMPX ;Restore X RTS ; ; 40 column clear to end of line ; @200 LDA BLANK STA (BASE1),Y LDA TCOLOR STA (BASE2),Y CPY VPHMAX INY BCC @200 RTS ; .PAGE ;---------------------------------------------------------------------- ; ; Subroutine CLREOS -- Clear to End of Screen ; ; This subroutine clears the screen from the current cursor position ; to the end of the viewport. The CLREOS1 entry allows the line number ; to be passed in X and the starting column number in Y. ; ; Entry CLREOS: ; Parameters: none ; ; Entry CLREOS1: ; Parameters: ; X: Starting absolute line number ; Y: Starting column number ; ; Exit: ; A, X, Y: Undefined ; ;---------------------------------------------------------------------- ; CLREOS = * CLC LDA TPY ADC VPT TAX ;Get starting line number LDY TPX ;Get starting cursor position CLREOS1 = * @010 JSR TBASCAL1 JSR CLREOL1 ;Clear this line LDY #0 ;Reset starting column CPX VPB INX BCC @010 JMP TBASCAL ;Reset base address ; .PAGE ;----------------------------------------------------------------------- ; ; Scroll Text Viewport ; ; This subroutine scrolls the text within the viewport up or down by ; one line. On entry, A must contain an UP/DOWN flag ( $00 => UP, ; $80 => DOWN ). ; ; Parameters: ; A: Up / Down flag ; ; Zero Page Temporary Storage: ; WORK1, WOR2: Screen pointers ; FLAGS: Bit 7 -- even / odd flag for scroll loop ; Bit 6 -- up / down flag ; TEMP1: Starting Y index for scroll loop ; ; Subroutines called: ; TBASCAL1, CLREOL1 ; ; Exit: ; A, X, Y: Undefined ; ;----------------------------------------------------------------------- ; SCROLL = * STA FLAGS ;Save UP/DOWN flag SEC LDA VPHMAX BIT HMODE BPL @010 LSR A @010 STA TEMP1 ;Get starting loop index ROR FLAGS ;Save even/odd flag LDX VPT BIT FLAGS BVC @020 LDX VPB @020 JSR TBASCAL1 ;Get starting base addresses ; @030 BIT FLAGS BVC @040 CPX VPT ;Scroll down BEQ @080 ; All done DEX ; Go up one line BPL @050 @040 CPX VPB ;Scroll up BEQ @080 ; All done INX ; Go down one line ; @050 LDA BASE1 LDY BASE1+1 ;Copy source address STA WORK1 ; to destination address STY WORK1+1 LDA BASE2 LDY BASE2+1 STA WORK2 STY WORK2+1 JSR TBASCAL1 ;Get next source address LDY TEMP1 BIT FLAGS BPL @070 @060 LDA (BASE2),Y ;Scroll this line STA (WORK2),Y ; move odd column @070 LDA (BASE1),Y ; move even column STA (WORK1),Y DEY BPL @060 BMI @030 ; @080 LDY #0 JSR CLREOL1 ;Clear last line JMP TBASCAL ; .PAGE ;----------------------------------------------------------------------- ; ; Horizontal Shift ; ; This subroutine shifts the text within the viewport left or right. ; On entry, A must contain an eight bit signed shift offset, negative ; for left shifts and positive for right shifts. ; ; Parameters: ; A: Signed shift offset ; ; Zero Page Temporary Storage: ; BLANK, TEMPX ; WORK1, WORK2: Screen pointers ; FLAGS: Bit 7 -- right / left flag ; Bit 6 -- odd / even flag for shift right ; TEMP1: Positive shift offset ; TEMP2: Absolute shift column ; TEMP3: shift right -- starting shift index ; shift left -- shift count ; TEMP4: shift right -- starting clear index ; shift left -- column for clear ; ; Subroutines Called: ; CLREOS1, CLREOL1 ; ; Exit: ; A, X, Y: Undefined ; ;----------------------------------------------------------------------- ; SHIFT = * TAY BEQ @020 ;Nothing to do AND #BITON7 STA FLAGS ;Set right / left flag TYA CMP #$80 BCC @010 EOR #$FF ;Make shift count positive @010 ADC #00 STA TEMP1 ;Absolute shift offset ADC VPL ;Absolute column number STA TEMP2 ; for base address LDX VPT SEC LDA VPHMAX SBC TEMP1 BCS @030 LDY #00 ;Shift entire viewport JSR CLREOS1 @020 RTS @030 BIT FLAGS BMI @060 ; SEC ;Set up for shift right BIT HMODE BPL @040 LSR A @040 STA TEMP3 ;Set starting index for shifting LDA #BITON6 BCS @050 LDA #00 @050 ORA FLAGS ;Set odd / even flag STA FLAGS LDY TEMP1 DEY STY TEMP4 ;Set index for clearing LDA #$80+ASC_SP EOR SMINV STA BLANK ;Set up space character JMP SHIFT1 ; @060 TAY ;Set up for shift left BIT HMODE BMI @070 SEC ROL A @070 STA TEMP3 ;Set count for shifting INY STY TEMP4 ;Set index for clearing ; SHIFT1 JSR TBASCAL1 ;Get base address CLC LDA TEMP2 BIT HMODE BPL @010 LSR A @010 PHP ADC BASL,X STA WORK1 ;Get shifted base address STA WORK2 LDA BASH,X PLP BCC @020 DEC WORK1 EOR #$0C @020 STA WORK1+1 EOR #$0C STA WORK2+1 BIT FLAGS BMI SHFTLF ; SHFTRT LDY TEMP3 ;Shift this line right BVC @020 @010 LDA (BASE2),Y STA (WORK2),Y @020 LDA (BASE1),Y STA (WORK1),Y DEY BPL @010 LDA TEMP4 ;Clear beginning of line BIT HMODE BPL @050 LSR A TAY LDA BLANK BCC @040 @030 STA (BASE2),Y @040 STA (BASE1),Y DEY BPL @030 BMI SHIFT2 @050 TAY @060 LDA BLANK STA (BASE1),Y LDA TCOLOR STA (BASE2),Y DEY BPL @060 ; SHIFT2 CPX VPB INX ;Go to next line BCC SHIFT1 JMP TBASCAL ; SHFTLF LDY #00 ;Shift this line left STX TEMPX LDX TEMP3 ;Get shift count @010 LDA (WORK1),Y STA (BASE1),Y DEX BMI @020 LDA (WORK2),Y STA (BASE2),Y INY DEX BPL @010 @020 LDX TEMPX LDY TEMP4 JSR CLREOL1 JMP SHIFT2 ; .PAGE ;----------------------------------------------------------------------- ; ; Dump and Restore Contents of Viewport ; ; This subroutine will dump or restore the contents of the viewport to ; or from the caller's buffer. On entry, A must contain a dump/restore ; flag. ($00 => Dump $80 => Restore) ; ; Parameters: ; A: Dump / Restore flag ; ; Zero Page Temporary Storage: ; WORK1, WORK2: Extended pointers to caller's buffer ; FLAGS: Bit 7 -- odd / even move count flag ; Bit 6 -- dump / restore flag ; TEMP1: Starting move index ; TEMP2: Move count ; ; Exit: ; A, X, Y: Undefined ; ;----------------------------------------------------------------------- ; SCRNDUMP = * STA FLAGS JSR CURSOR ;Turn cursor off LDA VPHMAX STA TEMP2 INC TEMP2 BIT HMODE BMI @010 ASL TEMP2 ASL A @010 LSR A STA TEMP1 ROR FLAGS CLC LDA SCLIST ADC #03 ;Set work pointers to STA WORK1 ; to caller's buffer LDA SCLIST+1 ADC #00 CMP #$F0 LDX $1401+SCLIST BCC @020 SBC #$80 ;Adjust extended address INX @020 STA WORK1+1 STX $1401+WORK1 LDA TEMP2 LSR A ADC WORK1 STA WORK2 LDA WORK1+1 ADC #00 STA WORK2+1 STX $1401+WORK2 ; ; Copy the contents of the window ; LDX VPT @100 JSR TBASCAL1 LDY TEMP1 BIT FLAGS BVS @120 ; BPL @115 @110 LDA (BASE2),Y STA (WORK2),Y @115 LDA (BASE1),Y STA (WORK1),Y DEY BPL @110 BMI @140 ; @120 BPL @135 @130 LDA (WORK2),Y STA (BASE2),Y @135 LDA (WORK1),Y STA (BASE1),Y DEY BPL @130 ; @140 CLC LDA WORK1 ADC TEMP2 STA WORK1 BCC @150 INC WORK1+1 @150 CLC LDA WORK2 ADC TEMP2 STA WORK2 BCC @160 INC WORK2+1 @160 CPX VPB INX BCC @100 ; JSR TBASCAL JSR CURSOR ;Restore cursor RTS ; .PAGE ;---------------------------------------------------------------------- ; ; ZPOUT ; ; This subroutine saves the driver's zero page data. ; ;---------------------------------------------------------------------- ; ZPOUT LDX #ZPLENGTH-1 ;Zero Page save area length @010 LDA ZPDATA,X STA ZPSAVE,X DEX BPL @010 RTS .ENDPROC