mirror of
https://github.com/ksherlock/itty-bitty-vtty.git
synced 2024-11-21 05:31:06 +00:00
807 lines
9.2 KiB
ArmAsm
807 lines
9.2 KiB
ArmAsm
|
|
lst off
|
|
|
|
rel
|
|
xc
|
|
xc
|
|
use vt.equ
|
|
use apple2gs.equ
|
|
|
|
mx %11
|
|
|
|
|
|
* x 0-79
|
|
* y 0-23
|
|
* DECMT 0-22
|
|
* DECMB 1-23
|
|
*
|
|
* cursor_base - pointer to current line
|
|
* cursor_offset - index into current line
|
|
* cursor_saved_char - saved character under the cursor
|
|
* cursor_state - $80 = disabled, $40 = on
|
|
|
|
|
|
|
|
text
|
|
dw $0400
|
|
dw $0480
|
|
dw $0500
|
|
dw $0580
|
|
dw $0600
|
|
dw $0680
|
|
dw $0700
|
|
dw $0780
|
|
dw $0428
|
|
dw $04a8
|
|
dw $0528
|
|
dw $05a8
|
|
dw $0628
|
|
dw $06a8
|
|
dw $0728
|
|
dw $07a8
|
|
dw $0450
|
|
dw $04d0
|
|
dw $0550
|
|
dw $05d0
|
|
dw $0650
|
|
dw $06d0
|
|
dw $0750
|
|
dw $07d0
|
|
|
|
|
|
|
|
disable_cursor ent
|
|
mx %11
|
|
php
|
|
sei
|
|
bit cursor_state
|
|
bmi :rts
|
|
bvc :80
|
|
|
|
lda cursor_saved_char
|
|
ldy cursor_offset
|
|
sta [cursor_base],y
|
|
|
|
:80 lda #$80
|
|
tsb cursor_state
|
|
|
|
:rts plp
|
|
rts
|
|
|
|
enable_cursor ent
|
|
mx %11
|
|
php
|
|
sei
|
|
bit cursor_state
|
|
bpl :rts
|
|
bvc :80
|
|
|
|
* option for inverted cursor?
|
|
ldy cursor_offset
|
|
lda [cursor_base],y
|
|
sta cursor_saved_char
|
|
lda cursor_char
|
|
sta [cursor_base],y
|
|
|
|
:80 lda #$80
|
|
trb cursor_state
|
|
|
|
:rts plp
|
|
rts
|
|
|
|
|
|
cursor_vector ent
|
|
jml cursor_int
|
|
|
|
NumInts equ $e01d67
|
|
|
|
cursor_int
|
|
* cursor interrupt - blink the cursor.
|
|
|
|
mx %11
|
|
|
|
* check if CDA active.
|
|
* $ff = inactive, $00 = active
|
|
lda >NumInts
|
|
bpl :rts
|
|
|
|
ldy cursor_offset
|
|
|
|
lda cursor_state
|
|
bmi :rts
|
|
eor #$40
|
|
sta cursor_state
|
|
beq :off
|
|
:on
|
|
lda [cursor_base],y
|
|
sta cursor_saved_char
|
|
lda cursor_char
|
|
sta [cursor_base],y
|
|
|
|
bra :rts
|
|
|
|
:off
|
|
lda cursor_saved_char
|
|
sta [cursor_base],y
|
|
|
|
:rts stz SCANINT ; reset 1-sec interrupt
|
|
clc
|
|
rtl
|
|
|
|
|
|
|
|
|
|
recalc_cursor ent
|
|
* recalculate the cursor pointer after x/y changed
|
|
* assumes cursor is off so no saving/restoring the cursor char.
|
|
mx %11
|
|
php
|
|
rep #$30
|
|
lda y
|
|
asl
|
|
tay
|
|
lda text,y
|
|
sta cursor_base
|
|
|
|
lda x
|
|
and #$7f
|
|
lsr
|
|
sta cursor_offset
|
|
stz cursor_base+2
|
|
bcs :ok
|
|
inc cursor_base+2
|
|
|
|
:ok plp
|
|
rts
|
|
|
|
recalc_cursor_x ent
|
|
|
|
mx %11
|
|
php
|
|
|
|
lda x
|
|
and #$7f
|
|
lsr
|
|
sta cursor_offset
|
|
stz cursor_base+2
|
|
bcs :ok
|
|
inc cursor_base+2
|
|
|
|
:ok plp
|
|
rts
|
|
|
|
|
|
recalc_cursor_y ent
|
|
|
|
mx %11
|
|
php
|
|
rep #$30
|
|
|
|
lda y
|
|
asl
|
|
tay
|
|
lda text,y
|
|
sta cursor_base
|
|
plp
|
|
rts
|
|
|
|
|
|
advance_x ent
|
|
mx %11
|
|
|
|
* ldx x
|
|
* cpx #79
|
|
* bcs :rts
|
|
|
|
inc x
|
|
|
|
lda #1
|
|
eor cursor_base+2
|
|
sta cursor_base+2
|
|
|
|
beq :rts
|
|
|
|
inc cursor_offset
|
|
|
|
:rts rts
|
|
|
|
|
|
|
|
draw_char ent
|
|
; a = char
|
|
|
|
* alternate character set
|
|
* 00 - 1f = uppercase inverse letters ('@' - '_')
|
|
* 00 - 3f = special characters, inverse (' ' - '?')
|
|
* 40 - 4f = mouse text
|
|
* 60 - 7f = lower case letters, inverse
|
|
* 80 - 9f = upper case letters, normal
|
|
* a9 - ff = special, upper, lower chars, normal.
|
|
|
|
* for normal letters, ora $80
|
|
* for inverse letters, uppercase need to be remapped to 0-1f
|
|
* others don't change.
|
|
bit draw_inverse
|
|
bpl :normal
|
|
; invert it.
|
|
cmp #$60 ; `, first lowercase
|
|
bge :draw ; nothing to do for lowercase
|
|
cmp #$40 ; @, first uppercase
|
|
bcc :draw ; nothing to do for special
|
|
|
|
:uc and #%10111111 ; ~ $40
|
|
bra :draw
|
|
|
|
|
|
:normal ora #$80
|
|
:draw
|
|
* sta cursor_saved_char
|
|
|
|
* with DECAWM, x = 79, will CR LF (with scroll) before drawing character.
|
|
|
|
* at column 79, x increases but cursor does not. up/down does not change
|
|
* overflow. backspace / left arrow will go to 78.
|
|
|
|
* x = 80 indicates next char will wrap if DECAWM. however, treated as 79
|
|
|
|
* based on testing, will not advance to column 80 unless DECAWM is enabled.
|
|
|
|
ldx x
|
|
cpx #79
|
|
bcs :rm
|
|
|
|
ldy cursor_offset
|
|
sta [cursor_base],y
|
|
jmp advance_x
|
|
|
|
|
|
:rm
|
|
beq :79
|
|
|
|
bit DECAWM
|
|
bmi :wrap
|
|
|
|
:79
|
|
ldy cursor_offset
|
|
sta [cursor_base],y
|
|
lda DECAWM ; set bit 7 if DECAWM.
|
|
tsb x ; mark overflow
|
|
rts
|
|
|
|
|
|
|
|
|
|
:wrap
|
|
stz x
|
|
ldy y
|
|
cpy DECBM
|
|
beq :scroll
|
|
cpy #23
|
|
beq :23 ;
|
|
|
|
inc y
|
|
:23 pha ; save character
|
|
jsr recalc_cursor
|
|
pla
|
|
sta [cursor_base] ; offset 0
|
|
rts
|
|
|
|
:scroll
|
|
pha ; save
|
|
|
|
jsr scroll_down
|
|
jsr recalc_cursor_x
|
|
pla
|
|
sta [cursor_base] ; offset 0
|
|
rts
|
|
|
|
|
|
* erase screen commands are not affected by origin or scrolling region.
|
|
|
|
erase_screen ent
|
|
erase_screen_2 ent
|
|
* erase the entire screen.
|
|
|
|
mx %11
|
|
lda erase_char
|
|
* fall through
|
|
fill_screen ent
|
|
* fill the entire screen with the a register.
|
|
* text screen is out of order, so this doesn't use much code but
|
|
* it's not linear either.
|
|
* +64 bytes of screen hole data.
|
|
mx %11
|
|
|
|
sta >$000400
|
|
sta >$010400
|
|
|
|
php
|
|
rep #$30
|
|
|
|
|
|
ldx #$0400
|
|
ldy #$0401
|
|
lda #40*3-2
|
|
mvn $010000,$010000
|
|
|
|
ldx #$0400
|
|
ldy #$0480
|
|
lda #40*3-1
|
|
mvn $010000,$010000
|
|
|
|
ldx #$0400
|
|
ldy #$0500
|
|
lda #40*3-1
|
|
mvn $010000,$010000
|
|
|
|
ldx #$0400
|
|
ldy #$0580
|
|
lda #40*3-1
|
|
mvn $010000,$010000
|
|
|
|
ldx #$0400
|
|
ldy #$0600
|
|
lda #40*3-1
|
|
mvn $010000,$010000
|
|
|
|
ldx #$0400
|
|
ldy #$0680
|
|
lda #40*3-1
|
|
mvn $010000,$010000
|
|
|
|
ldx #$0400
|
|
ldy #$0700
|
|
lda #40*3-1
|
|
mvn $010000,$010000
|
|
|
|
ldx #$0400
|
|
ldy #$0780
|
|
lda #40*3-1
|
|
mvn $010000,$010000
|
|
|
|
*
|
|
ldx #$0400
|
|
ldy #$0401
|
|
lda #40*3-2
|
|
mvn $000000,$000000
|
|
|
|
ldx #$0400
|
|
ldy #$0480
|
|
lda #40*3-1
|
|
mvn $000000,$000000
|
|
|
|
ldx #$0400
|
|
ldy #$0500
|
|
lda #40*3-1
|
|
mvn $000000,$000000
|
|
|
|
ldx #$0400
|
|
ldy #$0580
|
|
lda #40*3-1
|
|
mvn $000000,$000000
|
|
|
|
ldx #$0400
|
|
ldy #$0600
|
|
lda #40*3-1
|
|
mvn $000000,$000000
|
|
|
|
ldx #$0400
|
|
ldy #$0680
|
|
lda #40*3-1
|
|
mvn $000000,$000000
|
|
|
|
ldx #$0400
|
|
ldy #$0700
|
|
lda #40*3-1
|
|
mvn $000000,$000000
|
|
|
|
ldx #$0400
|
|
ldy #$0780
|
|
lda #40*3-1
|
|
mvn $000000,$000000
|
|
|
|
|
|
|
|
|
|
* not needed since $0,$0 last
|
|
* phk
|
|
* plb
|
|
plp
|
|
rts
|
|
|
|
* scroll...
|
|
* scroll will always be one line at a time
|
|
scroll_up ent
|
|
* move DECTM .. DECBM-1 -> DECTM+1 .. DECBM insert blank line at DECTM.
|
|
|
|
mx %11
|
|
php
|
|
rep #$30
|
|
|
|
|
|
lda DECBM
|
|
sec
|
|
sbc DECTM
|
|
sta r0
|
|
|
|
lda DECBM
|
|
asl ;
|
|
tax
|
|
jmp (:dispatch,x)
|
|
|
|
|
|
:dispatch
|
|
dw :00,:01,:02,:03,:04
|
|
dw :05,:06,:07,:08,:09
|
|
dw :10,:11,:12,:13,:14
|
|
dw :15,:16,:17,:18,:19
|
|
dw :20,:21,:22,:23
|
|
|
|
|
|
|
|
* mvn 1,1 first so mvn 0,0 will restore b
|
|
:cp mac
|
|
lda #40-1
|
|
ldx #]1
|
|
ldy #]2
|
|
mvn $010000,$010000
|
|
|
|
lda #40-1
|
|
ldx #]1
|
|
ldy #]2
|
|
mvn $000000,$000000
|
|
|
|
dec r0
|
|
bne *+5
|
|
brl :done
|
|
<<<
|
|
|
|
* number refers to the source line.
|
|
:23 :cp $0750;$07d0
|
|
:22 :cp $06d0;$0750
|
|
:21 :cp $0650;$06d0
|
|
:20 :cp $05d0;$0650
|
|
:19 :cp $0550;$05d0
|
|
:18 :cp $04d0;$0550
|
|
:17 :cp $0450;$04d0
|
|
:16 :cp $07a8;$0450
|
|
:15 :cp $0728;$07a8
|
|
:14 :cp $06a8;$0728
|
|
:13 :cp $0628;$06a8
|
|
:12 :cp $05a8;$0628
|
|
:11 :cp $0528;$05a8
|
|
:10 :cp $04a8;$0528
|
|
:09 :cp $0428;$04a8
|
|
:08 :cp $0780;$0428
|
|
:07 :cp $0700;$0780
|
|
:06 :cp $0680;$0700
|
|
:05 :cp $0600;$0680
|
|
:04 :cp $0580;$0600
|
|
:03 :cp $0500;$0580
|
|
:02 :cp $0480;$0500
|
|
:01 :cp $0400;$0480
|
|
:00
|
|
|
|
:done
|
|
* now clear DECTM line
|
|
* lda DECTM
|
|
* asl
|
|
* tay
|
|
* ldx text,y
|
|
|
|
ldx cursor_base
|
|
lda erase_char
|
|
sta cursor_saved_char
|
|
ldy #19
|
|
:loop
|
|
sta >$000000,x
|
|
sta >$010000,x
|
|
inx
|
|
inx
|
|
dey
|
|
bpl :loop
|
|
|
|
plp
|
|
rts
|
|
|
|
|
|
scroll_down ent
|
|
* move DECTM+1 .. DECBM -> DECTM .. DECBM-1, insert blank line at DECBM.
|
|
|
|
mx %11
|
|
php
|
|
rep #$30
|
|
|
|
|
|
lda DECBM
|
|
sec
|
|
sbc DECTM
|
|
sta r0
|
|
|
|
lda DECTM
|
|
asl ;
|
|
tax
|
|
jmp (:dispatch,x)
|
|
|
|
|
|
:dispatch
|
|
dw :00,:01,:02,:03,:04
|
|
dw :05,:06,:07,:08,:09
|
|
dw :10,:11,:12,:13,:14
|
|
dw :15,:16,:17,:18,:19
|
|
dw :20,:21,:22,:23
|
|
|
|
|
|
:cp mac
|
|
lda #40-1
|
|
ldx #]1
|
|
ldy #]2
|
|
mvn $010000,$010000
|
|
|
|
lda #40-1
|
|
ldx #]1
|
|
ldy #]2
|
|
mvn $000000,$000000
|
|
|
|
dec r0
|
|
bne *+5
|
|
brl :done
|
|
<<<
|
|
|
|
* todo -- fix offsets
|
|
|
|
* number refers to the dest line.
|
|
:00 :cp $0480;$0400
|
|
:01 :cp $0500;$0480
|
|
:02 :cp $0580;$0500
|
|
:03 :cp $0600;$0580
|
|
:04 :cp $0680;$0600
|
|
:05 :cp $0700;$0680
|
|
:06 :cp $0780;$0700
|
|
:07 :cp $0428;$0780
|
|
:08 :cp $04a8;$0428
|
|
:09 :cp $0528;$04a8
|
|
:10 :cp $05a8;$0528
|
|
:11 :cp $0628;$05a8
|
|
:12 :cp $06a8;$0628
|
|
:13 :cp $0728;$06a8
|
|
:14 :cp $07a8;$0728
|
|
:15 :cp $0450;$07a8
|
|
:16 :cp $04d0;$0450
|
|
:17 :cp $0550;$04d0
|
|
:18 :cp $05d0;$0550
|
|
:19 :cp $0650;$05d0
|
|
:20 :cp $06d0;$0650
|
|
:21 :cp $0750;$06d0
|
|
:22 :cp $07d0;$0750
|
|
:23
|
|
|
|
:done
|
|
* now clear DECBM line
|
|
* lda DECBM
|
|
* asl
|
|
* tay
|
|
* ldx text,y
|
|
|
|
ldx cursor_base
|
|
lda erase_char
|
|
sta cursor_saved_char
|
|
ldy #19
|
|
:loop
|
|
sta >$000000,x
|
|
sta >$010000,x
|
|
inx
|
|
inx
|
|
dey
|
|
bpl :loop
|
|
|
|
plp
|
|
rts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* erase 0 - cursor to end of line
|
|
* erase 1 - start of line to cursor
|
|
* erase 2 - erase line
|
|
erase_line_2 ent
|
|
mx %11
|
|
php
|
|
rep #$30
|
|
* lda y
|
|
* asl
|
|
* ldx text,y
|
|
ldx cursor_base
|
|
lda erase_char
|
|
ldy #19
|
|
:loop
|
|
sta >$000000,x
|
|
sta >$010000,x
|
|
inx
|
|
inx
|
|
dey
|
|
bpl :loop
|
|
|
|
plp
|
|
rts
|
|
|
|
|
|
|
|
erase_line_0 ent
|
|
*
|
|
* erase cursor to end of line.
|
|
*
|
|
mx %11
|
|
|
|
lda x
|
|
beq erase_line_2
|
|
|
|
php
|
|
rep #$30
|
|
lda cursor_base
|
|
clc
|
|
adc cursor_offset
|
|
tax
|
|
|
|
sep #$20 ; short m
|
|
|
|
* odd byte
|
|
ldy cursor_offset
|
|
lda cursor_base+2
|
|
bne :even
|
|
lda erase_char
|
|
sta [cursor_base],y
|
|
inx
|
|
iny
|
|
cpy #40
|
|
beq :exit
|
|
|
|
:even
|
|
lda erase_char
|
|
:loop sta >$010000,x
|
|
sta >$000000,x
|
|
inx
|
|
iny
|
|
cpy #40
|
|
blt :loop
|
|
|
|
:exit
|
|
plp
|
|
rts
|
|
|
|
|
|
erase_line_1 ent
|
|
* erase start of line to cursor.
|
|
mx %11
|
|
|
|
lda x
|
|
cmp #79
|
|
bcs erase_line_2
|
|
|
|
php
|
|
rep #$30
|
|
lda cursor_base
|
|
clc
|
|
adc cursor_offset
|
|
tax
|
|
|
|
sep #$20 ; short m
|
|
|
|
ldy cursor_offset
|
|
lda cursor_base+2
|
|
beq :odd
|
|
lda erase_char
|
|
sta [cursor_base],y
|
|
dex
|
|
dey
|
|
bmi :exit
|
|
|
|
:odd
|
|
lda erase_char
|
|
:loop sta >$010000,x
|
|
sta >$000000,x
|
|
dex
|
|
dey
|
|
bpl :loop
|
|
:exit plp
|
|
rts
|
|
|
|
erase_screen_0 ent
|
|
* erase cursor to end of screen.
|
|
mx %11
|
|
jsr erase_line_0
|
|
php
|
|
rep #$30
|
|
|
|
lda y
|
|
inc
|
|
cmp #24
|
|
bcs :exit
|
|
asl
|
|
tay
|
|
lda erase_char
|
|
|
|
:loop
|
|
|
|
sty r0
|
|
ldx text,y
|
|
ldy #19
|
|
:loop0
|
|
sta >$000000,x
|
|
inx
|
|
inx
|
|
dey
|
|
bpl :loop0
|
|
|
|
ldy r0
|
|
ldx text,y
|
|
ldy #19
|
|
:loop1
|
|
sta >$010000,x
|
|
inx
|
|
inx
|
|
dey
|
|
bpl :loop1
|
|
|
|
ldy r0
|
|
iny
|
|
iny
|
|
cpy #24*2
|
|
bcc :loop
|
|
|
|
:exit
|
|
plp
|
|
rts
|
|
|
|
erase_screen_1 ent
|
|
* erase beginning of screen to cursor.
|
|
mx %11
|
|
jsr erase_line_1
|
|
|
|
php
|
|
rep #$30
|
|
|
|
lda y
|
|
dec
|
|
bmi :exit
|
|
asl
|
|
tay
|
|
lda erase_char
|
|
|
|
:loop
|
|
|
|
sty r0
|
|
ldx text,y
|
|
ldy #19
|
|
:loop0
|
|
sta >$000000,x
|
|
inx
|
|
inx
|
|
dey
|
|
bpl :loop0
|
|
|
|
ldy r0
|
|
ldx text,y
|
|
ldy #19
|
|
:loop1
|
|
sta >$010000,x
|
|
inx
|
|
inx
|
|
dey
|
|
bpl :loop1
|
|
|
|
ldy r0
|
|
dey
|
|
dey
|
|
bpl :loop
|
|
|
|
|
|
:exit
|
|
plp
|
|
rts
|
|
rts
|
|
|
|
sav vt100.screen.L
|