.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 = 40 .exportzp vt100_screen_rows = 24 .import beep .import telnet_close .import telnet_send_char .import telnet_send_string .import vt100_font 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 "atari.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 ; --- reverse mode --- ; 0 = normal, !0 = revers Rvs .res 1 ; --- buffer for addDecDig --- mul10buf .res 1 ; --- system settings at entry, restored at termination time --- LMARGN_save .res 1 SHFLOK_save .res 1 INVFLG_save .res 1 CHBAS_save .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 DoCR jsr clPending ldx ROWCRS ; get row ldy #$00 ; set col=0 jsr CPlot ; set crsr rts ; --- BS --- D1 cmp #$08 ; BS? bne D2 BS jsr clPending ldy COLCRS ; get col beq D1rts ; stop @ left margin dey ; dec column ldx ROWCRS ; 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 ROWCRS ; 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 COLCRS ; get col jsr CPlot ; set crsr rts ; --- TAB --- D5 cmp #$09 ; TAB? bne D6 ; don't clear pending ; don't set pending lda COLCRS ; crsr col and #$f8 ; (col DIV 8) * 8 clc ; col + 8 adc #$08 cmp #Cols ; col=40? bne D5a ; no -> skip lda #Cols-1 ; yes -> col=39 D5a tay ; col to y ldx ROWCRS ; 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 ROWCRS ; 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 COLCRS ; get crsr col jsr CPlot ; set crsr jmp Eend ; --- E --- next line E7 cmp #$45 ; E ? bne E8 jsr DoCR jsr LF jmp Eend ; --- 7 --- save crsr E8 cmp #$37 ; 7 ? bne E9 lda Font ; save font sta SaveF lda Rvs ; save reverse mode sta SaveR lda Draw ; save line drawing sta SaveD ldx ROWCRS ; save position ldy COLCRS 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 Rvs ; .. 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 ROWCRS ; 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 COLCRS ; 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 ROWCRS ; 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 COLCRS ; 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 COLCRS ; 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 ROWCRS ; 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 COLCRS ; get crsr col sec sbc EPar ; col = col - left bpl LE4a ; stop at left.. lda #$00 ; ..margin LE4a tay ; y is col ldx ROWCRS ; 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 #0 ; reverse off lsr ; reverse? bcc LE5k ldx #$80 ; reverse on LE5k stx Rvs ; 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 ROWCRS ; 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 ; >= 40?.. 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 ROWCRS ; 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 ROWCRS ; 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 --- cmp #ATLRW bne C0 ; crsr L crsrL ldx #ScrsrL jsr SendStr rts ; --- crsr D --- C0 cmp #ATDRW bne C1 ; crsr down is pressed crsrD ldx #ScrsrD jsr SendStr rts ; --- crsr U --- C1 cmp #ATURW bne C2 ; crsr up is pressed crsrU ldx #ScrsrU jsr SendStr rts ; --- crsr R --- C2 cmp #ATRRW bne C3 ; crsr R crsrR ldx #ScrsrR jsr SendStr rts ; --- Option h H --- ; print help C3 cmp #$fc ; special value for HELP key beq Help cmp #$68 ; h beq C31 cmp #$48 ; H bne C4 C31 lda CONSOL and #4 beq Help ; "Option" pressed tya jsr putRS ; send h or H rts ; --- Option q Q --- ; quit CaTer C4 cmp #$71 ; q beq C41 cmp #$51 ; Q bne C5 C41 lda CONSOL and #4 beq Cquit ; "Option" pressed tya jsr putRS ; send q or 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 DoCR ; next screen line jsr LF ldx #HelpStr1 jsr CPrnStrNL ldx #HelpStr2 jsr CPrnStrNL ldx #HelpStr3 jsr CPrnStrNL rts HelpStr1;".........1.........2.........3.........4" .asc "O-H Help (this text) " .asc "O-Q Quit Telnet session " .asc "C-8, S-C-8 Send C-@ " .asc "C-,, S-C-, Send C-[ " .asc "C-., S-C-. Send C-] " .asc "C-/, S-C-/ Send C-\" .byt $00 HelpStr2;".........1.........2.........3.........4" .asc "C-7 Send C-^ " .asc "S-C-7 Send ` " .asc "S-C-- Send C-_ " .asc "C-9, S-C-9 Send { " .asc "C-0, S-C-0 Send } " .asc "S-C-T, S-C-2 Send ~" .byt $00 HelpStr3;".........1.........2.........3.........4" .asc " C: Control O: Option S: Shift " .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 ldy COLCRS ; get column lda sCrsrChar ; restore char sta (ADRESS),y 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 ldy COLCRS ; get column lda (ADRESS),y ; save chr sta sCrsrChar eor #$80 sta (ADRESS),y 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 ROWCRS ; set row sty COLCRS ; set col jsr SLV ldx xVector ; set screen line ldy xVector+1 stx ADRESS sty ADRESS+1 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 PCreg cmp #$60 ; line drawing char? bcc PCreg sbc #$60 ; adapt index for table starting at offset $60 tax lda ltsc,x ; line drawing to ScreenCode eor Rvs jmp PCput PCreg tay rol a rol a rol a rol a and #3 tax tya and #$9f ora ataint,x eor Rvs PCput ldx lbPending ; need new line? beq PC2 ; no -> skip ldx #$00 ; clear pending stx lbPending jsr NewLn PC2 ldy COLCRS ; get crsr col sta (ADRESS),y ; char to screen ; -- move on crsr -- cpy #Cols-1 ; col = 39? bne PC8 ; no -> skip lda #$ff ; yes -> set.. sta lbPending ; ..pending bne PCend PC8 iny ; move on crsr sty COLCRS 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 ROWCRS ; 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 COLCRS 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 COLCRS lda lbPending beq DEL1 ; pending jsr clPending jmp DELe DEL1 dey bmi DEL2 ; middle of line sty COLCRS jmp DELe DEL2 ; first col ldx ROWCRS beq DELee ; odd: top left corner dex ldy #Cols-1 jsr Plot ldy COLCRS DELe lda #$00 sta (ADRESS),y ; clear char 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 line -- ldy #Cols-1 US2 lda (xVector),y ; copy char sta (zVector),y dey bpl US2 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 line -- ldy #Cols-1 DS2 lda (xVector),y ; copy char sta (zVector),y dey bpl DS2 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 DoCR 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: $00 (space screen code) in A ; ; For internal use: ; ErLn_ needs line ptr in xVector ; ------------------------------------- ErLn jsr SLV ; line start in xVector ; -- erase chars -- ErLn_ ldy #Cols-1 ; col 39 lda #$00 ; load space EL1 sta (xVector),y ; clear char dey bpl EL1 rts ; ------------------------------------- ; ErEnLn - erase to end of line ; ; affects: A, X, Y ; ; erase screen line from crsr to end of line ; ------------------------------------- ErEnLn jsr COff ; -- erase chars -- ldy COLCRS ; get crsr col lda #$00 ; load space EEL1 sta (ADRESS),y; clear char iny cpy #Cols ; pos 40? bne EEL1 ; 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 chars -- ldy COLCRS ; get crsr col lda #$00 ; load space EBL1 sta (ADRESS),y; clear char dey bpl EBL1 ; 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 clc lda SAVMSC adc LineOffsLo,x sta xVector lda SAVMSC+1 adc LineOffsHi,x sta xVector+1 rts LineOffsLo .repeat Rows, i .byt (Cols * i) & $ff .endrepeat LineOffsHi .repeat Rows, i .byt (Cols * i) >> 8 .endrepeat ; ************************************* ; * ; * 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 sta Rvs lda #Rows-1 ; last line sta SRE ; = 23 rts ; ------------------------------------- ; Init char ; ; ------------------------------------- InitChar lda CHBAS sta CHBAS_save lda #>vt100_font sta CHBAS rts ; ------------------------------------- ; Exit char ; ; ------------------------------------- ExitChar lda CHBAS_save sta CHBAS rts ; ------------------------------------- ; Init Screen ; ; ------------------------------------- InitScr lda LMARGN sta LMARGN_save lda SHFLOK sta SHFLOK_save lda INVFLG sta INVFLG_save lda #0 sta LMARGN sta SHFLOK sta INVFLG InitScr1 ; called from ExitScr ldx #Rows-1 IS1 txa pha ; save X jsr ErLn ; erase line pla tax ; restore X dex ; previous line bpl IS1 ; --- put crsr --- ldx #$00 ldy #$00 sty COLCRS+1 ; sanity jsr Plot rts ; ------------------------------------- ; Exit Screen ; ; ------------------------------------- ExitScr lda LMARGN_save sta LMARGN lda SHFLOK_save sta SHFLOK lda INVFLG_save sta INVFLG jmp InitScr1 ; ************************************* ; * ; * ASCII and ScreenCode tables ; * ; ************************************* ; ------------------------------------- ; table line drawing to ScreenCode ; ; This table is used to convert incoming ; line drawing chars. First entry is for ; offset $60 (see PrnChr). ; ------------------------------------- ltsc;_0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f ; --- normal ------------------------------------------------------- ; ◆ ▒ ␉ ␌ ␍ ␊ ° ± ␤ ␋ ┘ ┐ ┌ └ ┼ ⎺ .byt $5b,$5c,$40,$48,$49,$4a,$4b,$50,$54,$55,$43,$45,$51,$5a,$53,$4d ; 6_ ; ⎻ ─ ⎼ ⎽ ├ ┤ ┴ ┬ │ ≤ ≥ π ≠ £ · ' ' .byt $4c,$52,$4f,$4e,$41,$44,$58,$57,$7c,$59,$5d,$5e,$5f,$47,$46,$00 ; 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,$08,$09,$0A,$B,$0c,$0d,$0e,$0f ; 0_ ; {↑} {↓} {←} {→} ; ^P ^Q ^R ^S ^T ^U ^V ^W ^X ^Y ^Z ^[ ^\ ^] ^^ ^_ .byt $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1a,$1b,$fe,$fe,$fe,$fe ; 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,$fe,$49,$4a,$4b,$4c,$4d,$4e,$4f ; 4_ ; P Q R S T U V W X Y Z [ \ ] ^ _ .byt $50,$fe,$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_ ; {DELETE} ; 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,$0c,$7f,$09 ; 7_ ; --- most of the following values are set to "ignored" ($ff) ------ ; --- some of the not ignored values can come from the ROM --------- ; --- some of them are synthesized in atrinput.s ------------------- .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; 8_ ; {RETURN} .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$7e,$0d,$1c,$1d,$1e,$1f ; 9_ .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; a_ .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; b_ .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; c_ .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; d_ .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; e_ ; {HELP} .byt $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$fe,$7d,$08,$ff ; f_ ; ----------------------------------------------- ; helper table to convert ASCII to screen code ; ----------------------------------------------- ataint .byt 64,0,32,96