.feature labels_without_colons .feature leading_dot_in_identifiers .feature loose_char_term .define .asc .byt .export vt100_init_terminal = InitTerminal .export vt100_exit_terminal = ExitTerminal .export vt100_process_inbound_char = ProcIn .export vt100_process_outbound_char = ProcOut .exportzp vt100_screen_cols = 80 .exportzp vt100_screen_rows = 24 .import beep .import telnet_close .import telnet_send_char .import telnet_send_string Cols = vt100_screen_cols Rows = vt100_screen_rows putRS = telnet_send_char SendStr = telnet_send_string ; ************************************* ; * * ; * C a T e r * ; * * ; * Copyright by * ; * Lars Stollenwerk * ; * * ; * 2001 - 2003 * ; * * ; * This file is part of CaTer. * ; * * ; * CaTer is provided under the terms * ; * of GNU General Public License. * ; * * ; * For more information see the * ; * README file. * ; * * ; ************************************* ; ************************************* ; * ; * Constant declaration ; * ; ************************************* .include "apple2.inc" ; ************************************* ; * ; * Zeropage ; * ; ************************************* .include "zeropage.inc" ; --- Vector --- ; four vectors in zeropage for ; temporary use. zVector = ptr1 xVector = ptr2 ; --- vector for PrnScr --- vVector = ptr3 ; ************************************* ; * ; * Variables ; * ; ************************************* .bss ; --- esc mode --- ; $00 = normal ; $0f = esc mode ; $fd = esc ( mode ; $fe = esc ) mode ; $ff = esc [ mode ; $f0 = ignore one char EMode .res 1 ; --- esc buffer --- EBuf .res $100 ; --- esc buffer length --- ; points on first free position EBufL .res 1 ; --- esc parameter --- ; numeric parameter in esc sequence EPar .res 1 ; --- scroll region --- SRS .res 1 ; first line number SRE .res 1 ; last line number ; --- ANSI font attributes --- ; contains three bits ; bit 0 = reverse ; bit 1 = bold ; bit 2 = underline Font .res 1 ; --- line drawing --- ; contains four bits ; bit 0 = G0 is line drawing ; bit 1 = G1 is iine drawing ; bit 6 = do line drawing ; bit 7 = G1 is invoked Draw .res 1 ; --- crsr save area --- ; here is crsr info saved with ESC 7 ; and restored from with ESC 8 SaveF .res 1 ; font SaveR .res 1 ; reverse mode SaveD .res 1 ; line drawing SaveRow .res 1 ; row SaveCol .res 1 ; column ; --- Linebreak pending --- ; 0 = not pending, ff = pending lbPending .res 1 ; --- crsr invisible --- ; 0 = visible, !0 = invisible civis .res 1 ; --- char under crsr --- sCrsrChar .res 1 ; --- buffer for addDecDig --- mul10buf .res 1 ; ************************************* ; * ; * Code ; * ; ************************************* .code ; ------------------------------------- ; init terminal ; ; ------------------------------------- InitTerminal jsr InitVar ; memory variables jsr InitChar; init font jsr InitScr ; init screen rts ; ------------------------------------- ; exit terminal ; ; ------------------------------------- ExitTerminal jsr ExitChar; exit font jsr ExitScr ; exit screen rts ; ************************************* ; * ; * imcoming data ; * ; ************************************* ; ------------------------------------- ; process incoming data ; ; char in Y ; ------------------------------------- ProcIn lda EMode ; handle esc mode bne PIEsc cpy #$20 ; control? bcc Special tya jsr CPrnChr ; print to screen rts ; to far for branch PIEsc jmp Esc ; ------------------------------------- ; special incoming char ; ; ------------------------------------- Special tya ; restore char ; --- CR --- cmp #$0d ; CR? bne D1 CR jsr clPending ldx CV ; get row ldy #$00 ; set col=0 jsr CPlot ; set crsr rts ; --- BS --- D1 cmp #$08 ; BS? bne D2 BS jsr clPending ldy CH ; get col beq D1rts ; stop @ left margin dey ; dec column ldx CV ; get row jsr CPlot ; set crsr D1rts rts ; --- ESC --- D2 cmp #$1b ; esc? bne D3 lda #$0f ; set esc mode sta EMode rts ; --- BEL --- D3 cmp #$07 ; BEL? bne D4 jsr beep rts ; --- LF --- D4 cmp #$0a ; LF? bne D5 LF jsr clPending ldx CV ; crsr line cpx SRE ; end scroll region? bne D4a ; no -> branch jsr CUScrl ; yes -> scroll up rts D4a cpx #Rows-1 ; end of screen? bne D4b ; no -> branch rts ; yes -> do nothing D4b inx ; next line ldy CH ; get col jsr CPlot ; set crsr rts ; --- TAB --- D5 cmp #$09 ; TAB? bne D6 ; don't clear pending ; don't set pending lda CH ; crsr col and #$f8 ; (col DIV 8) * 8 clc ; col + 8 adc #$08 cmp #Cols ; col=80? bne D5a ; no -> skip lda #Cols-1 ; yes -> col=79 D5a tay ; col to y ldx CV ; line to x jsr CPlot ; set crsr rts ; --- SO --- D6 cmp #$0e ; SO? bne D7 asl Draw sec ; set G1 invoked ror Draw jmp SLD ; --- SI --- D7 cmp #$0f ; SI? bne D8 asl Draw clc ; clear G1 invoked ror Draw jmp SLD D8 rts ; ------------------------------------- ; esc mode ; ; char in Y ; EMode != $00 in A ; ------------------------------------- Esc tax ; save EMode and #$0f ; EMode = $0f? bne E1 ; --- throw mode --- EMode = $f0 ; throw away char lda #$00 ; reset EMode sta EMode rts E1 txa ; restore EMode and #$f0 ; EMode = $ff? beq SEsc ; no -> short Emode jmp LEsc ; yes -> long Emode ; ------------------------------------- ; short esc mode ; ; EMode = $0f ; process first char ; ------------------------------------- SEsc tya ; restore char ; --- [ --- cmp #$5b ; [ ? bne E2 lda #$ff ; set esc [ mode sta EMode rts ; --- ( --- E2 cmp #$28 ; ( ? bne E3 lda #$fd ; set esc ( mode sta EMode rts ; --- ) --- E3 cmp #$29 ; ) ? bne E4 lda #$fe ; set esc ) mode sta EMode rts ; --- # --- E4 cmp #$23 ; # ? bne E5 jmp sThrow ; --- D --- index E5 cmp #$44 ; D ? bne E6 jsr LF ; same as LF jmp Eend ; --- M --- reverse index E6 cmp #$4d ; M ? bne E7 jsr clPending ldx CV ; get crsr row cpx SRS ; top os scroll reg? bne E6a jsr CDScrl ; yes -> scroll down jmp Eend E6a cpx #$00 ; top of screen? bne E6b jmp Eend ; yes -> do nothing E6b dex ; one line up ldy CH ; get crsr col jsr CPlot ; set crsr jmp Eend ; --- E --- next line E7 cmp #$45 ; E ? bne E8 jsr CR jsr LF jmp Eend ; --- 7 --- save crsr E8 cmp #$37 ; 7 ? bne E9 lda Font ; save font sta SaveF lda INVFLG ; save reverse mode sta SaveR lda Draw ; save line drawing sta SaveD ldx CV ; save position ldy CH stx SaveRow sty SaveCol jmp Eend ; --- 8 --- restore crsr E9 cmp #$38 ; 8 ? bne E10 jsr clPending ldx SaveRow ; restore pos ldy SaveCol jsr CPlot lda SaveD ; restore line drawing sta Draw lda SaveR ; restore .. sta INVFLG ; .. reverse mode ldx SaveF ; restore font stx Font jmp Eend ; --- unknown --- E10 ; --- reset ESC mode --- Eend lda #$00 ; reset EMode sta EMode rts ; --- set Throw mode --- sThrow lda #$f0 ; set esc mode $f0 sta EMode rts ; ------------------------------------- ; [ or ( or ) esc modes ; ; EMode = $ff or $fd or $fe ; ------------------------------------- LEsc lda EMode cmp #$ff beq LE1b jmp SCS ; ( esc or ) esc LE1b tya ; restore char ldy EBufL sta EBuf,y ; store char iny sty EBufL ; inc esc buffer jsr TestL ; test letter bcs LE1 ; process command rts ; --- process esc command --- ; A = last char ; Y = EBufL ; X conunts processed command chars LE1 ldx #$00 ; first char ; --- A --- crsr up cmp #$41 ; A ? bne LE2 jsr clPending jsr GetNum ; get argument lda EPar ; EPar = 0... bne LE1c inc EPar ; .. means 1 LE1c lda CV ; get crsr row sec sbc EPar ; row = row - up cmp SRS ; stop at top of .. bpl LE1a ; ..scroll region lda SRS LE1a tax ; x is row ldy CH ; y is col jsr CPlot ; set crsr jmp LEend ; --- B --- crsr down LE2 cmp #$42 ; B ? bne LE3 jsr clPending jsr GetNum ; get argument lda EPar ; EPar = 0... bne LE2c inc EPar ; .. means 1 LE2c lda CV ; get crsr row clc adc EPar ; row = row + down cmp SRE ; outside scrregion? bcs LE2d ; yes -> branch tax ; x is row jmp LE2a LE2d ldx SRE ; x = row = SRE LE2a ldy CH ; y is col jsr CPlot ; set crsr jmp LEend ; --- C --- crsr right LE3 cmp #$43 ; C ? bne LE4 jsr clPending jsr GetNum ; get argument lda EPar ; EPar = 0... bne LE3c inc EPar ; .. means 1 LE3c lda CH ; get crsr col clc adc EPar ; col = col + right cmp #Cols-1 ; outside screen? bcs LE3d ; yes -> branch tay jmp LE3a LE3d ldy #Cols-1 ; y=col=left margin LE3a ldx CV ; x is row jsr CPlot ; set crsr jmp LEend ; --- D --- crsr left LE4 cmp #$44 ; D ? bne LE5 jsr clPending jsr GetNum ; get argument lda EPar ; EPar = 0... bne LE4c inc EPar ; .. means 1 LE4c lda CH ; get crsr col sec sbc EPar ; col = col - left bpl LE4a ; stop at left.. lda #$00 ; ..margin LE4a tay ; y is col ldx CV ; x is row jsr CPlot ; set crsr jmp LEend ; --- m --- font attributes LE5 cmp #$6d ; m ? beq LE5a jmp LE6 ; too far to branch LE5a jsr GetNum pha ; save nondigit char lda Font ; font to A ldy EPar ; parameter to Y ; -- 0 -- bne LE5b ; 0 ? tya ; set font = vanilla jmp LE5nx ; -- 1 -- bold LE5b cpy #$01 bne LE5c ora #$02 ; bit 1 = bold jmp LE5nx ; -- 4 -- underline LE5c cpy #$04 bne LE5d ora #$04 ; bit 2 = underline jmp LE5nx ; -- 7 -- reverse LE5d cpy #$07 bne LE5nx ora #$01 ; bit 0 = reverse LE5nx ; -- next char -- sta Font pla ; get nondigit char cmp #$3b ; is semicolon? beq LE5a ; then next param ; set ANSI font attributes lda Font ldx #$ff ; reverse off lsr ; reverse? bcc LE5k ldx #$3f ; reverse on LE5k stx INVFLG ; set reverse mode jmp LEend ; --- K --- erase line LE6 cmp #$4b ; K ? bne LE7 jsr GetNum ; get parameter lda EPar ; in A ; -- 0 -- crsr to end of line bne LE6b jsr ErEnLn ; erase end line jmp LEend ; -- 1 -- begin to crsr LE6b cmp #$01 bne LE6d jsr ErBeLn ; erase beg line jmp LEend ; -- 2 -- whole line LE6d cmp #$02 bne LE6e ; par undefined ldx CV ; line in X jsr COff jsr ErLn ; erase line jsr COn LE6e jmp LEend ; --- f --- same as H LE7 cmp #$66 bne LE8 jmp LE7a ; same as H ; --- H --- cursor position LE8 cmp #$48 bne LE9 LE7a jsr clPending cpy #$01 ; no par means home bne LE8a ; -- home -- ldx #$00 ldy #$00 jsr CPlot ; set crsr jmp LEend ; -- row, col -- LE8a jsr GetNum cmp #$3b ; is ;? bne LE8d ; no -> error ; -- prepare row -- ldy EPar ; get row bne LE8b ; 0 means 1 iny LE8b dey ; line 1 -> line 0 cpy #Rows ; >= 24?.. bcs LE8d ; ..error! sty xVector ; save row ; -- prepare col jsr GetNum ldy EPar ; get col bne LE8c ; 0 means 1 iny LE8c dey ; col 1 -> col 0 cpy #Cols ; >= 80?.. bcs LE8d ; ..error! ldx xVector ; restore row to X jsr CPlot ; set crsr LE8d jmp LEend ; --- J --- erase screen LE9 cmp #$4a ; J ? bne LE10 jsr GetNum ; get parameter lda EPar ; in A ; -- 0 -- crsr to end bne LE9a jsr ErEnLn ; del rest of line ldx CV ; get crsr line LE9b inx ; next line cpx #Rows ; line 24? bcs LE9f ; then end txa pha ; save X jsr ErLn ; erase line pla tax ; restore X jmp LE9b ; next line ; -- 1 -- beg of screen to crsr LE9a cmp #$01 bne LE9e jsr ErBeLn ; del start of ln ldx CV ; get crsr line LE9c dex ; previous line bmi LE9f ; neg line -> end txa pha ; save X jsr ErLn ; erase line pla tax ; restore X jmp LE9c ; -- 2 -- del screen LE9e cmp #$02 ; unknown? bne LE9f ; then ingnore jsr COff ldx #Rows-1 ; start at ln 23 LE9d txa pha ; save X jsr ErLn ; erase line pla tax ; restore X dex ; previous line bpl LE9d jsr COn LE9f jmp LEend ; --- r --- set scroll region LE10 cmp #$72 ; r ? bne LE11 ; -- prepare top -- jsr GetNum cmp #$3b ; is ;? bne LE10e ; no -> error ldy EPar ; get top dey ; line 1 -> line 0 cpy #Rows ; >=24?.. bcs LE10e ; ..error! sty xVector ; save top ; -- prepare bottom -- jsr GetNum ldy EPar ; get bottom dey ; line 1 -> line 0 cpy #Rows ; >=24?.. bcs LE10e ; ..error! sty zVector ; save bottom ; -- validate lines -- lda xVector ; restore top cmp zVector ; >= bottom?.. bcs LE10e ; ..error! sta SRS ; top -> SRStart sty SRE ; bottom -> SREnd ; -- home crsr jsr clPending ldx #$00 ldy #$00 jsr CPlot LE10e jmp LEend ; --- l --- set crsr invisible LE11 cmp #$6c ; l ? bne LE12 lda EBuf ; first char .. cmp #$3f ; .. is '?' ? bne LE11a inx ; at second char .. jsr GetNum lda EPar cmp #25 ; .. 25 ? bne LE11a jsr COff ; switch crsr off sta civis ; mark invisible LE11a jmp LEend ; --- h --- set crsr visible LE12 cmp #$68 ; h ? bne LE13 lda EBuf ; first char .. cmp #$3f ; ... is '?' ? bne LE12a inx ; at second char .. jsr GetNum lda EPar cmp #25 ; .. 25 ? bne LE12a lda #$00 sta civis ; mark visible jsr COn ; switch crsr off LE12a jmp LEend LE13 ; --- unknown esc seqence --- LEend lda #$00 sta EBufL ; reset esc buffer sta EMode ; reset esc mode rts ; ------------------------------------- ; ( or ) esc modes (select char set) ; ; EMode = $fd or $fe in A ; ------------------------------------- SCS and #$03 ; $01 or $02 cpy #'0' ; line drawing? bne SCS1 ora Draw ; set Gx line drawing jmp SCS2 SCS1 eor #$ff ; $fe or $fd and Draw ; clear Gx line drawing SCS2 sta Draw jsr SLD jmp LEend ; ------------------------------------- ; SLD - set line drawing ; ; set bit 6 based on bits 0, 1, 7 ;-------------------------------------- SLD lda Draw bmi SLD1 ; G1 is invoked? and #$01 ; no -> G0.. jmp SLD2 SLD1 and #$02 ; yes -> G1.. SLD2 beq SLD3 ; ..is line drawing? lda #$40 ; yes -> set.. ora Draw ; ..line drawing jmp SLD4 SLD3 lda #$bf ; no -> clear.. and Draw ; ..line drawing SLD4 sta Draw rts ; ------------------------------------- ; GetNum - get decimal number from ; esc sequence ; ; params: esc sequence in EBuf ; first index to process in X ; affects: A, X, Y ; return: number in EPar ; first non digit char in A ; next index to process in X ; ------------------------------------- GetNum lda #$00 ; init value sta EPar GN2 lda EBuf,x ; get next char inx jsr TestD ; digit? bcc GN1 ; no -> return tay ; digit to Y lda EPar jsr addDecDig sta EPar jmp GN2 ; next char GN1 rts ; ------------------------------------- ; TestL - Test letter ; ; params: char in A ; affects: none ; return: c = 1 for letter ; c = 0 for no letter ; ------------------------------------- TestL cmp #$41 ; smaller then A? bcs TL1 ; no -> go on rts ; return no letter TL1 cmp #$5b ; smaller then Z+1? bcs TL2 ; no -> go on sec ; return letter rts TL2 cmp #$61 ; smaller then a? bcs TL3 ; no -> go on rts ; return no letter TL3 cmp #$7b ; smaller then z+1? bcs TL4 ; no -> go on sec ; return letter rts TL4 clc ; return no letter rts ; ------------------------------------- ; TestD - test digit ; ; params: char in A ; affects: none ; return: c = 1 for digit ; c = 0 for no digit ; ------------------------------------- TestD cmp #$30 ; smaller then 0? bcs TD1 ; no -> go on rts ; return no digit TD1 cmp #$3a ; smaller then 9+1? bcs TD2 ; no -> go on sec ; return digit rts TD2 clc ; return no digit rts ; ------------------------------------- ; addDecDig - add decimal digit ; ; multiply A * 10, add Y ; ; param: present number in A ; new digit in Y (may be ASCII digit) ; affects: A ; return: 10 times the number in A + Y ; c = 1 overflow occured, ; number invalid ; c = 0 no overflow ; ------------------------------------- addDecDig ; --- inc value --- ; old value * 10 ; 10a = ( 4a + a ) * 2 sta mul10buf clc asl ; ( 4a bcs aDDigE asl bcs aDDigE adc mul10buf ; + a ) bcs aDDigE asl ; *2 bcs aDDigE sta mul10buf ; --- add Y --- tya and #$0f ; digit to val adc mul10buf aDDigE rts ; ************************************* ; * ; * outgoing data ; * ; ************************************* ; ------------------------------------- ; process outgoing key ; ; params: key in Y ; ------------------------------------- ProcOut lda kta,y ; keyboard to ASCII cmp #$ff beq POrts ; ignore key cmp #$fe beq CmdKey ; command key jsr putRS POrts rts ; ------------------------------------- ; outgoing command key ; ; ------------------------------------- ScrsrU .byt $1b, $4f, $41, $00 ; esc O A ScrsrD .byt $1b, $4f, $42, $00 ; esc O B ScrsrR .byt $1b, $4f, $43, $00 ; esc O C ScrsrL .byt $1b, $4f, $44, $00 ; esc O D CmdKey tya ; restore character ; --- crsr L --- ; --- ^H --- ; both events send char $08 cmp #$08 bne C0 bit BUTN0 ; Open-Apple key bpl crsrL ; not pressed jsr putRS ; send ^H rts ; crsr L crsrL ldx #ScrsrL jsr SendStr rts ; --- crsr D --- ; --- ^J --- ; both events send char $0a C0 cmp #$0a bne C1 bit BUTN0 ; Open-Apple key bpl crsrD ; not pressed jsr putRS ; send ^J rts ; crsr down is pressed crsrD ldx #ScrsrD jsr SendStr rts ; --- crsr U --- ; --- ^K --- ; both events send char $0b C1 cmp #$0b bne C2 bit BUTN0 ; Open-Apple key bpl crsrU ; not pressed jsr putRS ; send ^K rts ; crsr up is pressed crsrU ldx #ScrsrU jsr SendStr rts ; --- crsr R --- ; --- ^U --- ; both events send char $15 C2 cmp #$15 bne C3 bit BUTN0 ; Open-Apple key bpl crsrR ; not pressed jsr putRS ; send ^U rts ; crsr R crsrR ldx #ScrsrR jsr SendStr rts ; --- Open-Apple h --- ; print help C3 cmp #$68 ; h bne C4 bit BUTN0 ; Open-Apple key bmi Help ; pressed jsr putRS ; send h rts ; --- Open-Apple q --- ; quit CaTer C4 cmp #$71 ; q bne C5 bit BUTN0 ; Open-Apple key bmi Cquit ; pressed jsr putRS ; send q rts ; quit CaTer Cquit jsr telnet_close rts ; --- unknown character --- C5 rts ; ------------------------------------- ; Help - print help screen ; ; calledom outgoing data loop ; returns with rts ; ------------------------------------- Help jsr CR ; next screen line jsr LF ldx #HelpStr jsr CPrnStrNL rts HelpStr ;".........1.........2.........3.........4.........5.........6.........7.........8" .asc "OA-H Help (this text) OA-Q Quit current Telnet session " .asc "OA-C-H Send C-H OA-C-J Send C-J " .asc "OA-C-K Send C-K OA-C-U Send C-U" .byt $00 ; ************************************* ; * ; * screen handling ; * ; ************************************* ; ------------------------------------- ; COff - switch cursor off ; ; affects: none ; ; Switch cursor off and restore char. ; This has to be done before every crsr ; movement. ; After movement COn has to be called. ; ------------------------------------- COff pha ; save registers tya pha lda civis ; invisible? bne CO2 ; -> do nothing lda CH ; get column lsr ; column DIV 2 tay lda sCrsrChar ; restore char bcs CO1 ; odd column? bit $c055 CO1 sta (BASL),y bit $c054 CO2 pla ; restore registers tay pla rts ; ------------------------------------- ; COn - switch crsr on ; ; affects: none ; ; opposite of COff ; ------------------------------------- COn pha tya pha lda civis ; invisible? bne COn4 ; -> do nothing lda CH ; get column lsr ; column DIV 2 tay bcs COn1 ; odd column? bit $c055 COn1 lda (BASL),y ; save chr sta sCrsrChar and #$20 ; capital letter? beq COn2 ; yes lda sCrsrChar eor #$80 ; reverse char jmp COn3 COn2 lda sCrsrChar eor #$c0 ; reverse capital letter COn3 sta (BASL),y bit $c054 COn4 pla tay pla rts ; ------------------------------------- ; CPlot - move cursor ; ; params: coumn in Y ; line in X ; affects: A, X, Y ; ; The crsr ist turned off during ; operation (COff - COn) ; ------------------------------------- CPlot jsr COff jsr Plot jsr COn rts ; ------------------------------------- ; Plot - move cursor ; ; params: coumn in Y ; line in X ; affects: A, X, Y ; ------------------------------------- Plot stx CV ; set row sty CH ; set col jsr SLV ldx xVector ; set screen line ldy xVector+1 stx BASL sty BASH rts ; ------------------------------------- ; CPrnChr - print char to screen ; ; params: chr in A, $ff means no output ; affects: A ; uses: xVector ; ; The crsr ist turned off during ; operation (COff - COn) ; ------------------------------------- CPrnChr jsr COff jsr PrnChr jsr COn rts ; ------------------------------------- ; PrnChr - print char to screen ; ; params: chr in A, $80 means no output ; affects: A ; uses: xVector ; ------------------------------------- PrnChr sta xVector ; save char txa ; save registers pha tya pha lda xVector ; restore char ; -- $80-$ff -- non-ASCII bmi PCend ; no output ; -- handle line drawing -- bit Draw ; line drawing? bvc PCrvs cmp #$60 ; line drawing char? bcc PCrvs and INVFLG ; normal:$ff, reverse:$3f tax lda ltsc,x ; line drawing to ScreenCode jmp PCput ; -- handle reverse mode -- PCrvs ldx INVFLG ; normal:$ff, reverse:$3f bmi PC1 ; reverse mode? tax lda rtsc,x ; reverse to ScreenCode jmp PCput PC1 ora #$80 ; normal to ScreenCode PCput ldx lbPending ; need new line? beq PC2 ; no -> skip ldx #$00 ; clear pending stx lbPending jsr NewLn PC2 tax ; save char lda CH ; get crsr col lsr ; col DIV 2 tay txa ; restore char bcs PC3 ; odd col? bit $c055 PC3 sta (BASL),y ; char to screen bit $c054 ldy CH ; get crsr col ; -- move on crsr -- cpy #Cols-1 ; col = 79? bne PC8 ; no -> skip lda #$ff ; yes -> set.. sta lbPending ; ..pending jmp PCend PC8 iny ; move on crsr sty CH PCend pla ; restore registers tay pla tax rts ; ------------------------------------- ; NewLn - move crsr to next line ; ; affects: X, Y ; ; --- INTERNAL --- ; subtask of PrnChr ; ------------------------------------- NewLn pha ; save char ldx CV ; get crsr row cpx SRE ; end of scroll reg? beq NL1 ; yes -> branche cpx #Rows-1 ; line 23? beq NLend ; yes -> crsr stays ; --- normal wrap --- inx ; increase line ldy #$00 ; begin of line jsr Plot jmp NLend ; --- scroll up --- NL1 jsr UScrl ldy #$00 ; begin of line sty CH NLend pla ; restore char rts ; ------------------------------------- ; DEL - move crsr to the left and ; delete char ; ; Can move through left margin. ; ; affects: A, X, Y ; ------------------------------------- DEL jsr COff ldy CH lda lbPending beq DEL1 ; pending jsr clPending jmp DELe DEL1 dey bmi DEL2 ; middle of line sty CH jmp DELe DEL2 ; first col ldx CV beq DELee ; odd: top left corner dex ldy #Cols-1 jsr Plot ldy CH DELe tya lsr ; col DIV 2 tay lda #" "|$80 ; clear char bcs DEL3 ; odd col? bit $c055 DEL3 sta (BASL),y bit $c054 DELee jsr COn rts ; ------------------------------------- ; clPending - clear pending flag ; ; affects: none ; ; Must be called in all crsr movement ; commands. ; ------------------------------------- clPending pha lda #$00 sta lbPending pla rts ; ------------------------------------- ; CUScrl - scroll up scrollregion ; ; affects: A, X, Y ; ; The crsr ist turned off during ; operation (COff - COn) ; ------------------------------------- CUScrl jsr COff jsr UScrl jsr COn rts ; ------------------------------------- ; UScrl - scroll up scrollregion ; ; affects: A, X, Y ; uses: xVector, zVector ; ------------------------------------- UScrl ldx SRS ; get first line ; --- scroll one line --- US1 ; -- new line: -- ; -- zVector -- jsr SLV lda xVector ; screen line ldy xVector+1 sta zVector sty zVector+1 ; -- old line: -- ; -- xVector -- inx ; old line jsr SLV ; -- copy even col chars -- bit $c055 ldy #Cols/2-1 ; even col 39 US2 lda (xVector),y ; copy char sta (zVector),y dey bpl US2 ; -- copy odd col chars -- bit $c054 ldy #Cols/2-1 ; odd col 39 US3 lda (xVector),y ; copy char sta (zVector),y dey bpl US3 cpx SRE ; last line? bne US1 ; no -> go on jsr ErLn_ ; del last line rts ; ------------------------------------- ; CDScrl - scroll down scrollregion ; ; affects: A, X, Y ; ; The crsr ist turned off during ; operation (COff - COn) ; ------------------------------------- CDScrl jsr COff jsr DScrl jsr COn rts ; ------------------------------------- ; DScrl - scroll down scrollregion ; ; affects: A, X, Y ; uses: xVector, zVector ; ------------------------------------- DScrl ldx SRE ; get last line ; --- scroll one line --- DS1 ; -- new line: -- ; -- zVector -- jsr SLV lda xVector ; screen line ldy xVector+1 sta zVector sty zVector+1 ; -- old line: -- ; -- xVector -- dex ; old line jsr SLV ; -- copy even col chars -- bit $c055 ldy #Cols/2-1 ; even col 39 DS2 lda (xVector),y ; copy char sta (zVector),y dey bpl DS2 ; -- copy odd col chars -- bit $c054 ldy #Cols/2-1 ; odd col 39 DS3 lda (xVector),y ; copy char sta (zVector),y dey bpl DS3 cpx SRS ; first line? bne DS1 ; no -> go on jsr ErLn_ ; del first line rts ; ------------------------------------- ; CPrnStrNL - print string to sceen, ; followed by CR NL ; ; string: chars, terminated by $00 ; params: string ptr lo in X ; string ptr hi in y ; affects: A, X, Y ; ; The string must be smaller than ; 255 chrs. ; The crsr ist turned off during ; operation (COff - COn) ; ------------------------------------- CPrnStrNL jsr CPrnStr jsr CR jsr LF rts ; ------------------------------------- ; CPrnStr - print string to screen ; ; string: chars, terminated by $00 ; params: string ptr lo in X ; string ptr hi in y ; affects: A ; ; The string must be smaller than ; 255 chrs. ; The crsr ist turned off during ; operation (COff - COn) ; ------------------------------------- CPrnStr stx vVector ; store string ptr sty vVector+1 jsr COff ldy #$00 L1 lda (vVector),y beq L2 ; string ends at $00 jsr PrnChr ; -- put char to screen -- iny jmp L1 L2 jsr COn rts ; ------------------------------------- ; ErLn - erase screen line ; ; params: line number in X ; affects: A, X, Y ; return: $20 (space) in A ; ; For internal use: ; ErLn_ needs line ptr in xVector ; ------------------------------------- ErLn jsr SLV ; line start in xVector ; -- erase even col chars -- ErLn_ bit $c055 ldy #Cols/2-1 ; even col 39 lda #$20|$80 ; load space EL1 sta (xVector),y ; clear char dey bpl EL1 ; -- erase odd col chars -- bit $c054 ldy #Cols/2-1 ; odd col 39 EL2 sta (xVector),y ; clear char dey bpl EL2 rts ; ------------------------------------- ; ErEnLn - erase to end of line ; ; affects: A, X, Y ; ; erase screen line from crsr to end of line ; ------------------------------------- ErEnLn jsr COff ; -- erase even col chars -- bit $c055 lda CH ; get crsr col lsr ; col DIV 2 tay sty tmp1 ; save start lda #$20|$80 ; load space bcs EEL2 ; odd crsr col EEL1 sta (BASL),y ; clear char EEL2 iny cpy #Cols/2 ; even pos 40? bne EEL1 ; next char ; -- erase odd col chars -- bit $c054 ldy tmp1 ; restore start EEL3 sta (BASL),y ; clear char iny cpy #Cols/2 ; odd pos 40? bne EEL3 ; next char jsr COn rts ; ------------------------------------- ; ErBeLn - erase from begin of line ; ; affects: A, X, Y ; ; erase screen line up to crsr ; ------------------------------------- ErBeLn jsr COff ; -- erase even col chars -- bit $c055 lda CH ; get crsr col lsr ; col DIV 2 tay sty tmp1 ; save start lda #$20|$80 ; load space EBL1 sta (BASL),y ; clear char dey bpl EBL1 ; pos>=0 -> next ; -- erase odd col chars -- bit $c054 ldy tmp1 ; restore start bcc EBL3 ; even crsr col EBL2 sta (BASL),y ; clear char EBL3 dey bpl EBL2 ; pos>=0 -> next jsr COn rts ; ------------------------------------- ; SLV - set line vector ; --- INTERNAL --- ; ; params: line no in X ; affects: A, Y ; return: screen line ptr in xVector ; ------------------------------------- SLV lda LineVecLo,x ldy LineVecHi,x sta xVector sty xVector+1 rts LineVecLo .byt $00, $80, $00, $80, $00, $80, $00, $80 .byt $28, $A8, $28, $A8, $28, $A8, $28, $A8 .byt $50, $D0, $50, $D0, $50, $D0, $50, $D0 LineVecHi .byt $04, $04, $05, $05, $06, $06, $07, $07 .byt $04, $04, $05, $05, $06, $06, $07, $07 .byt $04, $04, $05, $05, $06, $06, $07, $07 ; ************************************* ; * ; * Init routines ; * ; ************************************* ; ------------------------------------- ; init memory ; ; ------------------------------------- InitVar lda #$00 sta EMode sta EBufL sta SRS sta Font sta Draw sta SaveF sta SaveR sta SaveD sta SaveRow sta SaveCol sta lbPending sta civis lda #Rows-1 ; last line sta SRE ; = 23 rts ; ------------------------------------- ; Init char ; ; ------------------------------------- InitChar rts ; ------------------------------------- ; Exit char ; ; ------------------------------------- ExitChar rts ; ------------------------------------- ; Init Screen ; ; ------------------------------------- InitScr ; --- turn on 80 col --- jsr $c300 ; --- limit SET80COL-HISCR to text --- bit LORES ; --- erase screen --- ldx #Rows-1 ; start at ln 23 IS1 txa pha ; save X jsr ErLn ; erase line pla tax ; restore X dex ; previous line bpl IS1 ; --- put crsr --- ldx #$00 ldy #$00 jsr Plot rts ; ------------------------------------- ; Exit Screen ; ; ------------------------------------- ExitScr ; --- erase screen --- jsr $fc58 ; clear current text screen rts ; ************************************* ; * ; * ASCII and ScreenCode tables ; * ; ************************************* ; ------------------------------------- ; table reverse to ScreenCode ; ; This table is used to convert incoming ; reverse chars. ; ------------------------------------- rtsc;_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f ; --- Control chars - should never appear -------------------------- .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 0_ .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 1_ ; --- special chars ------------------------------------------------ .byt $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ; 2_ .byt $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ; 3_ ; --- upper case letters ---------------------------------------------- .byt $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f ; 4_ .byt $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f ; 5_ ; --- lower case letters ------------------------------------------- .byt $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f ; 6_ .byt $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f ; 7_ ; ------------------------------------- ; table line drawing to ScreenCode ; ; This table is used to convert incoming ; line drawing chars. ; ------------------------------------- ltsc;_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f ; --- unused ------------------------------------------------------- .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 0_ .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 1_ ; --- reverse ------------------------------------------------------ ; ◆ ▒ ␉ ␌ ␍ ␊ ° ± ␤ ␋ ┘ ┐ ┌ └ ┼ ⎺ ; ' ' ▒ ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' | ' ' ' ' | | _ .byt $20,$57,$20,$20,$20,$20,$20,$20,$20,$20,$7c,$20,$20,$7c,$7c,$1f ; 2_ ; ⎻ ─ ⎼ ⎽ ├ ┤ ┴ ┬ │ ≤ ≥ π ≠ £ · ' ' ; _ _ _ _ | | _ _ | ' ' ' ' ' ' ' ' ' ' ' ' ' ' .byt $1f,$1f,$1f,$1f,$7c,$7c,$1f,$1f,$7c,$20,$20,$20,$20,$20,$20,$20 ; 3_ ; --- unused ------------------------------------------------------- .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 4_ .byt $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; 5_ ; --- normal ------------------------------------------------------- ; ◆ ▒ ␉ ␌ ␍ ␊ ° ± ␤ ␋ ┘ ┐ ┌ └ ┼ ⎺ ; ◆ ▒ ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ⎸ ' ' _ ⎿ ⎿ ⎺ .byt $5b,$56,$a0,$a0,$a0,$a0,$a0,$a0,$a0,$a0,$5f,$a0,$9f,$54,$54,$4c ; 6_ ; ⎻ ─ ⎼ ⎽ ├ ┤ ┴ ┬ │ ≤ ≥ π ≠ £ · ' ' ; ─ _ _ _ ⎿ ⎸ ⎿ _ ⎸ ' ' ' ' ' ' ' ' ' ' ' ' ' ' .byt $53,$9f,$9f,$9f,$54,$5f,$54,$9f,$5f,$a0,$a0,$a0,$a0,$a0,$a0,$a0 ; 7_ ; ------------------------------------- ; table keyboard to ASCII ; ; This table is used to prepare keyboard ; input for sending over the serial ; line. ; ; ascii = $ff means ignore key ; ascii = $fe means do something ; complicated (command key) ; ------------------------------------- kta ;_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f ; --- Control chars ------------------------------------------------ ; {←} {↓} {↑} ; ^@ ^A ^B ^C ^D ^E ^F ^G ^H ^I ^J ^K ^L ^M ^N ^O .byt $00,$01,$02,$03,$04,$05,$06,$07,$fe,$09,$fe,$fe,$0c,$0d,$0e,$0f ; 0_ ; {→} ; ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ .byt $10,$11,$12,$13,$14,$fe,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f ; 1_ ; --- special chars ------------------------------------------------ ; ' ' ! " # $ % & ' ( ) * + , - . / .byt $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f ; 2_ ; 0 1 2 3 4 5 6 7 8 9 : ; < = > ? .byt $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f ; 3_ ; --- capital letters ---------------------------------------------- ; @ A B C D E F G H I J K L M N O .byt $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f ; 4_ ; P Q R S T U V W X Y Z [ \ ] ^ _ .byt $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$5b,$5c,$5d,$5e,$5f ; 5_ ; --- lower case letters ------------------------------------------- ; ` a b c d e f g h i j k l m n o .byt $60,$61,$62,$63,$64,$65,$66,$67,$fe,$69,$6a,$6b,$6c,$6d,$6e,$6f ; 6_ ; p q r s t u v w x y z { | } ~ DEL .byt $70,$fe,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f ; 7_