apple1/Controllers drivers/Hi-Res Video Driver Source/video processor source and hex/ProcChr.inc

1009 lines
28 KiB
PHP

;******************************************************
; ProcChr - decode host command and update display
;
; Original design by Daryl Rictor (c)2003-2004
;
; Major redesign by Grant Searle 2007-13
; - Commands modified
; - 40 char or 80 char support
; - Multi fonts and sizes
; - Medium resolution graphics
; - Line attributes to define text/graphics and font
;******************************************************
processChar:
rcall setYfromRowCol
; restore chr under cursor
mov temp,inpt
mov inpt,charUnderCursor
rcall putCharAtY
mov inpt,temp
mov J,cmdVal ; Was previous byte 1st char of a multi-byte command?
cpi J, 0x00
brne processCommandPart2
mov J, inpt
; If delete char then jump
cpi J,0x7F
brne notDelete
rjmp delete
notDelete:
; If control code then handle it
cpi J,0x20
brlo controlCode
; Otherwise print the character
rjmp printableASCII
controlCode:
ldi ZH, 0x08 ; no, setup jump table page address
mov ZL, inpt ; put the input chr into Z
ijmp ; jump table based on INPT
;---------------------------------------------------------------------------------------------------------------------------
processCommandPart2:
cmd1:
mov J,cmdVal
cpi J, 0x0E ; set column
brne cmd2
cpi inpt, 0x50 ; check column = 0-79
brlo setColumn
rjmp cmdComplete
setColumn:
mov column, inpt ; update hpos
rcall putCursorOnScreen ; put cursor back on screen if >39 on a 40 char line
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
rjmp cmdComplete
cmd2:
cpi J, 0x0F ; set row
brne cmd3
cpi inpt, 0x19 ; check row = 0-24
brlo setRow
rjmp cmdComplete
setRow:
mov row, inpt ; save new vertical position
rcall getCurrentLineAtt ; set the current attribute to match the cursor line
rcall setLineAtt ; to ensure double-height lines are reset to top line at cursor
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
rjmp cmdComplete
cmd3:
cpi J, 0x1A ; Force Char Into RAM
brne cmd4
rcall printableASCII
rjmp cmdComplete
cmd4:
cpi J, 0x18 ; Set font attribute
brne cmd5
mov activeLineAtt, inpt ; Set the attribute to use for all subsequent lines
rcall setLineAtt ; Set the attribute on the current line to match
rcall putCursorOnScreen ; put cursor back on screen if >39 on a 40 char line
rjmp cmdComplete
cmd5:
cpi J, 0x02 ; Set cursor character
brne cmd6
mov cursorChar, inpt
rjmp cmdComplete
cmd6:
cpi J, 0x05 ; Set pixel
brne cmd7
mov J,previousInpt
cpi J, 0xFF ; If previous input was FF then this is first param
brne setPixel ; otherwise this is second param so method can be called
mov previousInpt, inpt ; Store current input as the previous input value
ret ; Just return, don't terminate command
cmd7:
cpi J, 0x06 ; Reset pixel
brne cmdComplete
mov J,previousInpt
cpi J, 0xFF
brne resetPixel
mov previousInpt, inpt
ret ; Just return, don't terminate command
cmdComplete:
ldi J,0x00
mov cmdVal, J
ret
;---------------------------------------------------------------------------------------------------------------------------
resetPixel:
ldi J,0x00
mov temp,J
rjmp setOrResetPixel
setPixel:
ldi J,0x01
mov temp,J
setOrResetPixel:
; Validate coordinates and exit if out of range
mov J,inpt ; Y=0..99
cpi J,100
brsh cmdComplete
mov J,previousInpt ; X=0..159
cpi J,160
brsh cmdComplete
; inpt contains the Y coordinate, previousInpt contains X coordinate
push row
push column
; Get the row of location that needs to be manipulated
mov J,inpt
lsr J
lsr J
andi J,0x1F
mov row,J
; Get attribute location into Z
ldi ZH, 0x08
ldi ZL, 0xD0
add ZL, row
; Get line attribute into J
ld J,Z
; If already set then skip
sbrc J,ATT_GRAPHICS
rjmp graphicsLineSet
; If not already graphics then set the attribute and clear the line
ldi column,0x00
; Get the location for start of line
rcall setYfromRowCol
ldi J, 0x00
clrGraphics:
st Y+, J
inc column
cpi column, 0x50
brne clrGraphics ; clear to end of line
; Force graphics property for the row
ldi J,0x00
ori J, 1<<ATT_GRAPHICS
ori J, 1<<ATT_80_CHAR_PER_LINE
st Z, J
graphicsLineSet:
; Get column of byte to be changed
mov J,previousInpt
lsr J
andi J,0x7F
mov column,J
mov J,previousInpt ; X coord
andi J,0x01
mov K,J
mov J,inpt ; Y coord
andi J,0x03
lsl J
or K,J
; K now contains the bit number that needs to be set (0..7)
ldi J,0x01
cpi K,0x00
breq setBitDone ; Bitmap already correct for bit number 0
setBit:
lsl J
dec K
brne setBit
; J now contains the bitmap with bit J set
setBitDone:
rcall setYfromRowCol
; Put the display byte in K
ld K,Y ; Retrieve the byte
; if temp=1 then set the pixel
sbrc temp,0
or K,J ; Set the pixel
; if temp=0 then reset the pixel
sbrs temp,0
ldi ZH,0xFF
sbrs temp,0
eor J,ZH
sbrs temp,0
and K,J
st Y,K ; Store the byte
pop column
pop row
ldi J, 0xFF
mov previousInpt, J ; reset value for next call
rjmp cmdComplete
;---------------------------------------------------------------------------------------------------------------------------
tab:
ldi inpt, 0x20 ; convert tabs to spaces
rcall putCharAtY
rcall moveToNext
mov K, column ; tabs are fixed 0,8,16... (will wrap to next line if needed)
andi K, 0x07 ; colums 0-7 only
brne tab ; not to next tab, so do again
ret
;---------------------------------------------------------------------------------------------------------------------------
delEndOfLine:
ldi inpt, 0x20
mov temp2,YL
mov temp3,YH
mov temp,column
deleol1:
rcall putCharAtY
adiw Y,0x01
inc column
cpi column, 0x50
brne deleol1 ; clear to end of line
mov column,temp
mov YH,temp3
mov YL,temp2
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
delStartOfLine:
ldi inpt, 0x20
mov temp2,YL
mov temp3,YH
mov temp,column
rcall setYfromRowCol
delsol1:
rcall putCharAtY
sbiw YL, 0x01
dec column
cpi column, 0x00
brne delsol1 ; clear to start of line
mov column,temp
mov YH,temp3
mov YL,temp2
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
delStartOfScreen:
ldi inpt, 0x20
mov temp2,YL
mov temp3,YH
delsos1:
rcall putCharAtY
sbiw YL,0x01
cpi YH, 0x01
brne delsos1
cpi YL, 0x00
brne delsos1
mov YH,temp3
mov YL,temp2
ld charUnderCursor, Y
ret
;---------------------------------------------------------------------------------------------------------------------------
delEndOfScreen:
ldi inpt, 0x20
mov temp2,YL
mov temp3,YH
deleos1:
st Y+, inpt
cpi YH, 0x08
brne deleos1
cpi YL, 0xD0
brne deleos1
mov YH,temp3
mov YL,temp2
ld charUnderCursor, Y
ret
;---------------------------------------------------------------------------------------------------------------------------
setLineAtt:
; Get attribute location into Z
ldi ZH, 0x08
ldi ZL, 0xD0
add ZL, row
ldi J, 0x00
sbrc activeLineAtt,ATT_GRAPHICS
rjmp setGraphicsAtts
sbrc activeLineAtt,ATT_80_CHAR_PER_LINE
ori J, 1<<ATT_80_CHAR_PER_LINE
sbrc activeLineAtt,ATT_BOLD
ori J, 1<<ATT_BOLD
; If double-height then set the double top and double bottom attributes
sbrc activeLineAtt,ATT_DBL_HEIGHT
rjmp setDoubleLineAtts
st Z, J
ret
setDoubleLineAtts:
; If at row 25 then scroll up first otherwise it won't fit
mov temp,J
cpi row,0x18
brne notAtLastLine
rcall singleScrollUp
dec row
rcall setYfromRowCol
; reset attribute location
ldi ZH, 0x08
ldi ZL, 0xD0
add ZL, row
mov J,temp
notAtLastLine:
; Set first double line attribute
ori J, 1<<ATT_DBL_TOP ; Set double top bit
st Z+, J
; Set second double line attribute
andi J, 0xFF - (1<<ATT_DBL_TOP) ; Clear double top bit
ori J, 1<<ATT_DBL_BOTTOM ; Set double bottom bit
st Z, J
ret
setGraphicsAtts:
; Override any other attribute property if graphics
ori J, 1<<ATT_GRAPHICS
ori J, 1<<ATT_80_CHAR_PER_LINE
st Z, J
ret
;---------------------------------------------------------------------------------------------------------------------------
getRawCurrentLineAtt:
; Get attribute location into Z
ldi ZH, 0x08
ldi ZL, 0xD0
add ZL, row
; Get line attribute into J
ld J,Z
ret
;---------------------------------------------------------------------------------------------------------------------------
getCurrentLineAtt:
; Get attribute location into Z
ldi ZH, 0x08
ldi ZL, 0xD0
add ZL, row
; Get line attribute into J
ld J,Z
; Map the line attribute into cursor line attribute
ldi K, 0x00
sbrc J,ATT_GRAPHICS
rjmp getGraphicsAtts
sbrc J,ATT_80_CHAR_PER_LINE
ori K, 1<<ATT_80_CHAR_PER_LINE
sbrc J,ATT_BOLD
ori K, 1<<ATT_BOLD
sbrc J,ATT_DBL_TOP
ori K, 1<<ATT_DBL_HEIGHT
sbrc J,ATT_DBL_BOTTOM
ori K, 1<<ATT_DBL_HEIGHT
mov activeLineAtt,K
ret
getGraphicsAtts:
; Override any other attribute property if graphics
ori K, 1<<ATT_GRAPHICS
ori K, 1<<ATT_80_CHAR_PER_LINE
mov activeLineAtt,K
ret
;---------------------------------------------------------------------------------------------------------------------------
printableASCII:
rcall putCharAtY
rcall moveToNext
; rcall cleanUpDisplay
ret
;---------------------------------------------------------------------------------------------------------------------------
setYfromRowCol:
ldi YL, 0x50 ; # chrs per line
ldi YH, 0x01 ; offset to start of display
mul YL, row ; multiply by chrs per line
ldi K, 0x00 ; need a zero for upper byte addition
add R1, YH ; add display start offset to result
movw YL, R0 ; mov it back to Y reg
add YL, column ; add in column
adc YH, K ; add the carry bit
ret
;---------------------------------------------------------------------------------------------------------------------------
putCharAtY:
st Y, inpt ; store chr
sbrs activeLineAtt,ATT_DBL_HEIGHT
ret
; If double height then store char on next line as well if not past end of screen
cpi row,0x18 ; Check if on last line (24)
breq putEnd
adiw YL, 0x20 ; Get to next line
adiw YL, 0x30
st Y, inpt ; store chr
sbiw YL, 0x20 ; Get back to original line
sbiw YL, 0x30
putEnd:
ret
;---------------------------------------------------------------------------------------------------------------------------
moveToNext:
adiw YL,0x01
inc column ; inc hpos
wrap:
sbrs activeLineAtt,ATT_80_CHAR_PER_LINE
rjmp wrap40
cpi column, 0x50 ; past column 80?
brne wrapExit ; no, continue
rjmp wrap0
wrap40:
cpi column, 0x28 ; past column 40?
brne wrapExit ; no, continue
wrap0:
ldi column, 0x00 ; back to start of line
sbrc activeLineAtt,ATT_DBL_HEIGHT
rjmp doubleWrap
normalWrap:
inc row ; next line
cpi row, 0x19 ; is it below last line (25)?
brlo wrapExit ; no, do cursor and exit
dec row ; Screen is moving up a line, so move the current row pointer up one
ldi column, 0x00 ; column back to zero
rcall singleScrollUp
rjmp wrapExit
doubleWrap:
inc row ; next line
inc row ; inc again (two lines per char)
cpi row, 0x18 ; is it below last line (23)?
brlo wrapExit ; no, do cursor and exit
dec row ; Screen is moving up two lines, so move the current row pointer up two
dec row
ldi column, 0x00 ; column back to zero
rcall doubleScrollUp
wrapExit:
rcall setLineAtt ; Set the attribute for the cursor line
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
return:
ldi column, 0x00 ; column back to zero
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
ret ; return to Main
;---------------------------------------------------------------------------------------------------------------------------
linefeed:
sbrc activeLineAtt,ATT_DBL_HEIGHT
rjmp doubleLinefeed
rjmp singleLinefeed
singleLinefeed:
cpi row, 0x18 ; are we at line 24 (for normal height)?
brlo noSingleScroll
rcall singleScrollUp ; yes, need to scroll up one line
rcall setLineAtt ; Set the attribute for the cursor line
ld charUnderCursor, Y ; save chr under cursor
; rcall cleanUpDisplay
ret
noSingleScroll:
inc row ; No scroll so move current line pointer down one
rcall setYfromRowCol
rcall setLineAtt ; Set the attribute for the cursor line
ld charUnderCursor, Y ; save chr under cursor
; rcall cleanUpDisplay
ret
doubleLinefeed:
cpi row, 0x16 ; are we at line 22 (for double height)?
brlo noDoubleScroll
rcall doubleScrollUp ; yes, need to scroll up two lines
rcall setLineAtt ; Set the attribute for the cursor line
ld charUnderCursor, Y ; save chr under cursor
; rcall cleanUpDisplay
ret
noDoubleScroll:
inc row ; No scroll so move current line pointer down two
inc row
rcall setYfromRowCol
rcall setLineAtt ; Set the attribute for the cursor line
ld charUnderCursor, Y ; save chr under cursor
; rcall cleanUpDisplay
ret
;---------------------------------------------------------------------------------------------------------------------------
delete:
ldi inpt, 0x20 ; space
rcall putCharAtY ; save to SRAM
mov charUnderCursor, inpt ; save chr under cursor (space)
ret ; return to Main
;---------------------------------------------------------------------------------------------------------------------------
backspace:
cpi column, 0x00 ; are we already at the left edge?
brne bs1 ; no, move left one chr
cpi row, 0x00 ; are we already on the top line?
brne bsToPrevLine ; no, so go up a line
ret
bsToPrevLine:
dec row
call getRawCurrentLineAtt; Unconverted, into J
sbrc J,ATT_DBL_BOTTOM ; If now at the bottom of a double line, go up again
dec row
rcall getCurrentLineAtt ; set the current attribute to match the cursor line
ldi column,0x4F ; set column to end of an 80 column line
rcall putCursorOnScreen ; adjust if now on a 40 column line
rjmp bs2
bs1:
dec column ; move cursor left one chr
bs2:
ldi inpt, 0x20 ; space
rcall setYfromRowCol
rcall putCharAtY
mov charUnderCursor, inpt ; save chr under cursor (space)
ret ; return to Main
;---------------------------------------------------------------------------------------------------------------------------
putCursorOnScreen:
; If moving from an 80 col line to a 40 col line, the
; column number has now exceeded the line width
; reset it to the end of the line
sbrc activeLineAtt,ATT_80_CHAR_PER_LINE ; if on an 80 col line then nothing to do
ret
; On a 40 char line...
cpi column, 0x28 ; if less that column 40 then nothing to do
brlo endOfPutCursor
ldi column,0x27 ; Set column to be 39
rcall setYfromRowCol
rcall putCharAtY
mov charUnderCursor, inpt ; save chr under cursor (space)
endOfPutCursor:
ret
;---------------------------------------------------------------------------------------------------------------------------
clrScr: ; Clear the Screen
; Reset all line atts
ldi ZL,25
ldi YL, 0xD0
ldi YH, 0x08
mov J,activeLineAtt
clrAtt:
st Y+,J
dec ZL
brne clrAtt
ldi row, 0x00
rcall setLineAtt ; Set the attribute for the top line to be current
ldi ZL, 0x00
ldi ZH, 0x01 ; set to start of display RAM
ldi YL, 0xD0
ldi YH, 0x07 ; set Y to 2000
ldi inpt, 0x20 ; " " space chracter
clsloop:
st Z+, inpt ; save to SRAM
sbiw YL, 0x01 ; dec Y
brne clsloop ; do until Y=0
cursorHome: ; move cursor to Home w/o clear
ldi column, 0x00 ; set cursor to top left pos
ldi row, 0x00
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
rcall getCurrentLineAtt ; set the current attribute to match the cursor line
; rcall cleanUpDisplay
ret ; return to Main
;---------------------------------------------------------------------------------------------------------------------------
scrollUp:
sbrc activeLineAtt,ATT_DBL_HEIGHT
rcall doubleScrollUp
sbrs activeLineAtt,ATT_DBL_HEIGHT
rcall singleScrollUp
rcall getCurrentLineAtt
rcall putCursorOnScreen ; if cursor is now past the end of a 40 char line then move it back on screen
ld charUnderCursor, Y ; save chr under cursor
; rcall cleanUpDisplay
ret
singleScrollUp:
mov temp2,YL
mov temp3,YH
ldi YL, 0x00 ; start of first line
ldi YH, 0x01 ;
ldi ZL, 0x50 ; start of second line
ldi ZH, 0x01 ;
scup1:
ld inpt, Z+ ; get line 2
st Y+, inpt ; place in line 1
cpi ZL, 0xD0
brne scup1
cpi ZH, 0x08 ; at the end of disp RAM?
brne scup1 ; no, do again
ldi inpt, 0x20 ; space
scup2:
st Y+, inpt ; fill last line with spaces
cpi YL, 0xD0
brne scup2
; Scroll the attributes up
ldi ZL,24
ldi YL, 0xD1 ; start of attributes +1
ldi YH, 0x08
scrollAttsUp:
ld J,Y
sbiw Y, 0x01
st Y,J
adiw Y, 0x02
dec ZL
brne scrollAttsUp
mov YH,temp3
mov YL,temp2
ret
doubleScrollUp:
mov temp2,YL
mov temp3,YH
ldi YL, 0x00 ; start of first line
ldi YH, 0x01 ;
ldi ZL, 0xA0 ; start of third line
ldi ZH, 0x01 ;
dscup1:
ld inpt, Z+ ; get line 3
st Y+, inpt ; place in line 1
cpi ZL, 0xD0
brne dscup1
cpi ZH, 0x08 ; at the end of disp RAM?
brne dscup1 ; no, do again
ldi inpt, 0x20 ; space
dscup2:
st Y+, inpt ; fill last two lines with spaces
cpi YL, 0xD0
brne dscup2
; Scroll the attributes up two
ldi ZL,23
ldi YL, 0xD2 ; start of attributes +2
ldi YH, 0x08
dscrollAttsUp:
ld J,Y
sbiw Y, 0x02
st Y,J
adiw Y, 0x03
dec ZL
brne dscrollAttsUp
mov YH,temp3
mov YL,temp2
ret
;---------------------------------------------------------------------------------------------------------------------------
scrollDown:
sbrc activeLineAtt,ATT_DBL_HEIGHT
rcall doubleScrollDown
sbrs activeLineAtt,ATT_DBL_HEIGHT
rcall singleScrollDown
rcall getCurrentLineAtt
rcall putCursorOnScreen ; if cursor is now past the end of a 40 char line then move it back on screen
ld charUnderCursor, Y ; save chr under cursor
; rcall cleanUpDisplay
ret
singleScrollDown:
mov temp2,YL
mov temp3,YH
ldi YL, 0x80 ; end of line 24
ldi YH, 0x08 ;
ldi ZL, 0xD0 ; end of line 25
ldi ZH, 0x08 ;
scdn1:
ld inpt, -Y ; get line 25
st -Z, inpt ; place in line 24
cpi YL, 0x00
brne scdn1
cpi YH, 0x01 ; at the end of disp RAM?
brne scdn1 ; no, do again
ldi inpt, 0x20 ; space
scdn2:
st -Z, inpt ; fill first line with spaces
cpi ZL, 0x00
brne scdn2
cpi ZH, 0x01 ; at the start of disp RAM?
brne scdn2 ; no, do again
; Scroll the attributes down
ldi ZL,24
ldi YL, 0xE7 ; end of attributes -1
ldi YH, 0x08
scrollAttsDn:
ld J,Y+
st Y,J
sbiw Y, 0x02
dec ZL
brne scrollAttsDn
mov YH,temp3
mov YL,temp2
ret
doubleScrollDown:
mov temp2,YL
mov temp3,YH
ldi YL, 0x30 ; end of line 23 + 1
ldi YH, 0x08 ;
ldi ZL, 0xD0 ; end of line 25 + 1
ldi ZH, 0x08 ;
dscdn1:
ld inpt, -Y ; get line 25
st -Z, inpt ; place in line 23
cpi YL, 0x00
brne dscdn1
cpi YH, 0x01 ; at the end of disp RAM?
brne dscdn1 ; no, do again
ldi inpt, 0x20 ; space
dscdn2:
st -Z, inpt ; fill first two lines with spaces
cpi ZL, 0x00
brne dscdn2
cpi ZH, 0x01 ; at the start of disp RAM?
brne dscdn2 ; no, do again
; Scroll the attributes down two lines
ldi ZL,23
ldi YL, 0xE6 ; end of attributes -2
ldi YH, 0x08
dscrollAttsDn:
ld J,Y
adiw Y, 0x2
st Y,J
sbiw Y, 0x03
dec ZL
brne dscrollAttsDn
mov YH,temp3
mov YL,temp2
ret
;---------------------------------------------------------------------------------------------------------------------------
scrollLeft:
mov temp2,YL
mov temp3,YH
ldi YL, 0x00 ; start of first col
ldi YH, 0x01 ;
ldi ZL, 0x01 ; start of second col
ldi ZH, 0x01 ;
sclf1:
ld inpt, Z+ ; get col 2
st Y+, inpt ; place in col 1
cpi ZL, 0xD0
brne sclf1
cpi ZH, 0x08 ; at the end of disp RAM?
brne sclf1 ; no, do again
ldi inpt, 0x20 ; space
sclf2:
st Y, inpt ; fill last line with spaces
sbiw YL, 0x30
sbiw YL, 0x20
cpi YL, 0xFF
brne sclf2
cpi YH, 0x00 ; at the end of display RAM?
brne sclf2 ; no, do again
mov YH,temp3
mov YL,temp2
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
scrollRight:
mov temp2,YL
mov temp3,YH
ldi YL, 0xCF ; end char
ldi YH, 0x08 ;
ldi ZL, 0xD0 ; end char +1
ldi ZH, 0x08 ;
scrt1:
ld inpt, -Y ; get line 2
st -Z, inpt ; place in line 1
cpi YL, 0x00
brne scrt1
cpi YH, 0x01 ; at the start of display RAM?
brne scrt1 ; no, do again
ldi inpt, 0x20 ; space
scrt2:
st Y, inpt ; fill left column with spaces
adiw YL, 0x30
adiw YL, 0x20
cpi YL, 0xD0
brne scrt2
cpi YH, 0x08 ; at the end of disp RAM?
brne scrt2 ; no, do again
mov YH,temp3
mov YL,temp2
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
cursorBlink:
ldi cursorClk, 0x00
ret
;---------------------------------------------------------------------------------------------------------------------------
cursorSolid:
ldi cursorClk, 0xff
ret
;---------------------------------------------------------------------------------------------------------------------------
cursorUp:
cpi row, 0x00
breq Null ; already at top, nothing to do
dec row
rcall getCurrentLineAtt
rcall getRawCurrentLineAtt; Unconverted, into J
sbrc J,ATT_DBL_BOTTOM ; If now at the bottom of a double line, go up again (if not at top of screen)
rjmp cursorUp
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
cursorDown:
cpi row, 0x18
breq Null ; already at bottom, nothing to do
inc row
rcall getCurrentLineAtt
rcall getRawCurrentLineAtt; Unconverted, into J
sbrc J,ATT_DBL_BOTTOM ; If now at the bottom of a double line, go down again (if not at end of screen)
rjmp cursorDown
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
cursorLeft:
cpi column, 0x00
breq Null
dec column
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
cursorRight:
call getCurrentLineAtt
sbrc activeLineAtt,ATT_80_CHAR_PER_LINE ; 0 = 40 cols, 1=80 cols
cpi column, 0x4F ; 79
sbrs activeLineAtt,ATT_80_CHAR_PER_LINE
cpi column, 0x27 ; 39
breq Null ; already at right, nothing to do
inc column ;
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
cleanUpDisplay:
; IMPROVEMENTS TO DO - NOT USED AT THE MOMENT
; If current att is double
; If cursor has been repositioned to the bottom line of a double then
; Set the first of the double lines to non-double
; If the current line is not double then
; Set the following line to be the bottom of a double
; Copy this line to the next to display the double properly (overwriting the line below)
; If current att is normal
; If cursor has been repositioned to the top line of a double then
; Set the next line to non-double
; If cursor has been repositioned to the bottom line of a double then
; Set the previous line to non-double
ldi ZL,24
ldi YL, 0xD0 ; start of attributes
ldi YH, 0x08
cleanFirstLine:
; If first line is the bottom of a double-height char then turn off the double-height
; so that it is fully visible again
ld J,Y
sbrc J,ATT_DBL_BOTTOM
rjmp firstNotDblBottom
andi J,0xFF - (1<<ATT_DBL_BOTTOM)
st Y,J
firstNotDblBottom:
cleanLastLine:
; If last line is the top of a double-height char then turn off the double-height
; so that it is fully visible again
ldi YL, 0xE8 ; end of attributes
ld J,Y
sbrc J,ATT_DBL_TOP
rjmp lastNotDblTop
andi J,0xFF - (1<<ATT_DBL_TOP)
st Y,J
lastNotDblTop:
;cleanUp1:
; ld J,Y
; adiw YL, 0x01
; dec ZL
; brne cleanUp1
rcall getCurrentLineAtt
rcall putCursorOnScreen ; if cursor is now past the end of a 40 char line then move it back on screen
rcall setYfromRowCol
ld charUnderCursor, Y ; save chr under cursor
ret
;---------------------------------------------------------------------------------------------------------------------------
multiByteCommand:
mov cmdVal,inpt ; Store the command ready for the second byte. Process once 2nd byte received
ret
;---------------------------------------------------------------------------------------------------------------------------
NULL:
ret
;---------------------------------------------------------------------------------------------------------------------------
.cseg
.org 0x800
;
; jump table for control codes 00 - 1F
;
rjmp null ; 00 [SPARE]
rjmp cursorHome ; 01 Ctrl-A Standard ASCII
rjmp multiByteCommand ; 02 Ctrl-B define cursor character (next byte = cursor [char 0 = off])
rjmp cursorBlink ; 03 Ctrl-C cursor blinking
rjmp cursorSolid ; 04 Ctrl-D cursor solid
rjmp multiByteCommand ; 05 Ctrl-E Set pixel (next two bytes = x,y)
rjmp multiByteCommand ; 06 Ctrl-F Reset pixel (next two bytes = x,y)
rjmp null ; 07 Ctrl-G [SPARE]
rjmp backspace ; 08 Ctrl-H Standard ASCII
rjmp tab ; 09 Ctrl-I Standard ASCII
rjmp linefeed ; 0A Ctrl-J Standard ASCII
rjmp null ; 0B Ctrl-K [SPARE]
rjmp clrScr ; 0C Ctrl-L Standard ASCII
rjmp return ; 0D Ctrl-M Standard ASCII
rjmp multiByteCommand ; 0E Ctrl-N SetColumn command (next byte = col number)
rjmp multiByteCommand ; 0F Ctrl-O SetRow command (next byte = row number)
rjmp delStartOfLine ; 10 Ctrl-P Delete to start of line
rjmp delEndOfLine ; 11 Ctrl-Q Delete to end of line
rjmp delStartOfScreen ; 12 Ctrl-R Delete to start of screen
rjmp delEndOfScreen ; 13 Ctrl-S Delete to end of screen
rjmp scrollUp ; 14 Ctrl-T Scroll the complete screen up one text line
rjmp scrollDown ; 15 Ctrl-U Scroll the complete screen down one text line
rjmp scrollLeft ; 16 Ctrl-V Scroll the complete screen left
rjmp scrollRight ; 17 Ctrl-W Scroll the complete screen right
rjmp multiByteCommand ; 18 Ctrl-X Set font attribute
rjmp null ; 19 Ctrl-Y [SPARE]
rjmp multiByteCommand ; 1A Ctrl-Z Force next byte into RAM (for 00 to 1F chars)
rjmp null ; 1B Don't use - reserved for ANSI ESC
rjmp cursorRight ; 1C
rjmp cursorLeft ; 1D
rjmp cursorUp ; 1E
rjmp cursorDown ; 1F