Files
GBBS/Source/Config/Video/Vid40.S
paulhlee1967 caf6ddd745 Refresh all Files
All files refreshed.  Config now shows uppercase when using a ][+

Minor bug fixes in logon.seg.s

Newer XDOS external with bug fixes
2023-01-09 11:13:29 -08:00

419 lines
5.6 KiB
ArmAsm

********************************
* *
* Apple 40 Column Driver *
* *
********************************
*-------------------------------
* Date: 01/03/86
*-------------------------------
lst off
rel
dsk rel/apple40
cr equ $0d
lf equ $0a
bs equ $08
wndlft equ $20
wndwdth equ $21
wndtop equ $22
wndbtm equ $23
ch equ $24
cv equ $25
blink equ $26
oldcv equ $27
base equ $28
base2 equ $2a
x_save equ $2c
y_save equ $2d
invflg equ $32
vid40 ent
org $0900
jmp :init
jmp :cls
jmp :cout
jmp :scroll
jmp :banner
jmp :clrlast
jmp :rdinit
jmp :rdkey
jmp :rdend
jmp :window
jmp :read
jmp :keyin
jmp :xypos
jmp :shchat
; init 40 col video
:init lda $c30b
cmp #1
bne :init_2
lda $c30c
cmp #$82
bne :init_1
lda $c058
clc
bcc :init_2
:init_1 cmp #$87
bne :init_2
lda #0
sta $c0b2
:init_2 lda #0 ; reset screen
sta blink
sta wndlft
sta wndtop
sta invflg
lda #40
sta wndwdth
sta oldcv ; make sure it is different!
lda #24
sta wndbtm
; ...fall through to cls...
:cls ldx wndtop
:cls1 jsr :setbase ; setup base address
ldy #39
lda #" "
:cls2 sta (base),y ; clear screen
dey
bpl :cls2
inx
cpx wndbtm ; is there more?
bne :cls1 ; yep
; ...fall through to home routine...
:home lda #0 ; home cursor
sta ch
lda wndtop ; top of window
sta cv
tax
; ...fall through to setbase routine
:setbase cpx oldcv ; do we have the base already?
beq :setbas2 ; yep
pha
txa
asl a ; x = x * 2
tax
lda :scrnadr,x ; get and save address
sta base
lda :scrnadr+1,x
sta base+1
txa
lsr a ; x = x / 2
tax
stx oldcv ; update old cv value
pla
:setbas2 rts
; output a character
:cout stx x_save ; save everything
sty y_save
pha
and #$7f ; clear high
cmp #cr
beq :cout2
cmp #lf
beq :cout3
cmp #bs
beq :cout5
cmp #' '
bcc :cout4
ldx cv ; set base
jsr :setbase
ldy ch ; get offset
ora #$80
cmp #"a" ; lower?
bcc :cout0 ; nope
cmp #"z"+1 ; lower?
bcs :cout0 ; nope
sbc #$1f ; make upper
:cout0 bit invflg ; inverse?
bpl :cout1 ; nope
and #$3f ; inverse upper
:cout1 sta (base),y ; save character
inc ch ; move over 1 space
ldy ch
cpy #40 ; wrap-around?
bne :cout4 ; nope
:cout2 ldy #0 ; reset horiz
sty ch
:cout3 inc cv ; go down 1 line
lda cv ; is it in range?
cmp wndbtm
bne :cout4 ; nope
dec cv ; put it back
jsr :scroll
:cout4 pla
ldx x_save ; restore stuff
ldy y_save
rts
:cout5 dec ch ; backup
bpl :cout4 ; all is well
lda #39 ; move to end of line
sta ch
lda cv ; are we at the top
cmp wndtop
beq :cout4 ; yep
dec cv
jmp :cout4 ; ok, we are done
; scroll the screen down 1 line
:scroll ldx wndtop ; get first line to scroll
:scroll2 jsr :setbase ; get the first base
lda base
sta base2 ; move to second
lda base+1
sta base2+1
inx
jsr :setbase ; get other base
ldy #39 ; copy line
:scroll3 lda (base),y ; move character
sta (base2),y
dey
bpl :scroll3
txa
tay
iny
cpy wndbtm ; done?
bne :scroll2 ; nope
; ...fall through into clear last line routine...
:clrlast ldx wndbtm
dex
lda #" " ; fill with spaces
:clrline pha
jsr :setbase ; point to last line
pla
ldy #39
:clrlst3 sta (base),y ; clear the line
dey
bpl :clrlst3
rts
; scroll a character across the bottom line
:banner pha ; save eveything
txa
pha
ldx #0
:banner2 lda $7d5,x ; move char
sta $7d4,x
inx
cpx #$24 ; do all the chars
bne :banner2
pla
tax
pla
pha
cmp #"a" ; lower?
bcc :banner3 ; nope
cmp #"z"+1 ; lower?
bcs :banner3 ; nope
sbc #$1f ; make upper
:banner3 sta $7f7 ; save new char
pla
rts
; get a character -- non destructable
:rdkey pha
sty y_save ; save Y
ldy ch
lda #$df ; underline
cmp (base),y ; is it in underline phase?
bne :rdkey2 ; nope, put it there
lda blink ; put into character phase
:rdkey2 sta (base),y
ldy y_save ; were done
pla
rts
; init rdkey routine
:rdinit pha
stx x_save
sty y_save
ldx cv
jsr :setbase ; setup base
ldy ch ; select screen to work with
lda (base),y
sta blink ; save blink character
ldx x_save
ldy y_save
pla
rts
; finish up rdkey routine
:rdend pha
sty y_save ; save A & Y
ldy ch
lda blink ; put back orig char
sta (base),y
ldy y_save ; restore
pla
rts
; set up window for top of screen display
:window ldx #0
lda #'-'
jsr :clrline ; fill line 1
ldx #3
jsr :clrline ; fill line 4
dex
lda #' '
jsr :clrline ; fill line 3
dex
jsr :clrline ; fill line 2
lda #4 ; set top of window
sta wndtop
rts
; read a line of data from the screen
:read jsr :setbase ; setup base
lda (base),y ; get character
and #$7f
cmp #' '
bcs *+4 ; make into ascii character
adc #'@'
rts
; check for local keyin
:keyin lda $c000
rts
; do x-y positioning
:xypos stx ch ; save location
sty cv
tya
tax
jmp :setbase ; reset base
; show that chat has been selected
:shchat tax
lda wndtop ; are we full screen?
beq :shchat5 ; yep, dont display
lda ch ; save location
pha
lda cv
pha
txa
beq :shchat3 ; cover it up
pha
ldy #0
ldx #13 ; position cursor
jsr :xypos
lda #-1
sta invflg ; set inverse mode
pla
tay
ldx :msgoff-1,y
:shchat2 lda :chatmsg,x ; print chat message
inx
pha
jsr :cout
pla
bpl :shchat2
lda #0 ; set normal mode
sta invflg
beq :shchat4 ; finish up
:shchat3 ldx #0 ; fix top line
lda #'-'
jsr :clrline
:shchat4 pla
tay
pla ; move back
tax
jsr :xypos
:shchat5 rts
:msgoff db 0,12
:chatmsg dci '[ PAGE: ON ]'
dci '[ EXEC: ON ]'
; table of screen address
:scrnadr dw $400 ; first 1/3 decoding
dw $480
dw $500
dw $580
dw $600
dw $680
dw $700
dw $780
dw $428 ; second 1/3 decoding
dw $4a8
dw $528
dw $5a8
dw $628
dw $6a8
dw $728
dw $7a8
dw $450 ; third 1/3 decoding
dw $4d0
dw $550
dw $5d0
dw $650
dw $6d0
dw $750
dw $7d0