Friday, April 06, 2007

Plus4 ROM disassmebly

After a post by Luca on Plus/4 world about clearing the screen via the kernal, I thought I'd have a quick poke around inside my kernal disassembly to see what it does. So I've spent an hour or so comenting my disassembly and how the screen clear stuff actually works. Its pretty simple really, and more or less loops around the current text window size clearing lines at a time. So, its not great, but its far from terrible. The "normal" kernal way of clearing a screen is to set the cursor to the top left and use Chrout to print each character. This doesn't, it hits the screen directly.
This also answers my question as to whether the kernal can move/relocate the main character map screen. The answer is no. This is because located at $d802 and $d81b you'll find a screen line lookup table, with the address of every line on the screen. and $0c00 is encoded into this table. Pitty.

Here's the main parts for anyone interested....


; *************************************************
;
; Clear screen with colour $10
;
; *************************************************
LD87E LDA #$10 ; Colour to clear screen to (black)
STA $053B ; Set current character colour
LDA #$04
STA $0541

; *************************************************
;
; Esc-n SCNCLR
;
; *************************************************
LD888:
JSR LDE70 ; Set full screen window
LD88B JSR LD89A ; Set the cursor HOME
LD88E JSR LD8AA ; Set screen pointers

; *************************************************
;
; Actual Screen Clear
;
; *************************************************
ClearScreen:
LD891:
JSR LDAF7 ; Clear the current line the cursor is on
CPX $07E5 ; At window lower edge?
INX ; move cursor down a line
BCC LD88E ; if not done, clear more


; *************************************************
;
; Set cursor HOME (set to top/left of current window)
;
; *************************************************
LD89A LDX $07E6 ; Get window TOP
STX $CD ; set cursor Y
STX $C4 ; cursor input row
LD8A1 LDY $07E7 ; Get window LEFT
STY $CA ; Set cursor X
STY $C5 ; Set cursor input X

LD8A8 LDX $CD ; get cursor Y
LD8AA LDA ScreenAddressLO,x ; look up screen xply table (LO)
STA $C8 ; store current screen address (low)
LDA ScreenAddressHI,x ; look up screen xply table (HI)
STA $C9 ; store current screen address (HI)

LD8B4 LDA $C8 ; get current screen address LO
STA $EA ; store in current editor COLOUR address LO
LDA $C9 ; now get the screen HI
AND #$03 ; and work out the HI addrews
ORA #$08 ; of the colour screen
STA $EB ; and store in the editor colour address HI
RTS




; *************************************************
;
; Clear the current line the cursor is on.
; (within the left/right window range)
;
; *************************************************
LDAF7 LDY $07E7 ; Get window LEFT edge
JSR LDF4A ; ???
LDAFD JSR LD8AA ; Setup screen addresses
DEY
LDB01 INY
LDA #$20 ; fill character address with spaces ($20)
STA ($C8),y
LDA $053B ; get current colour attribute
STA ($EA),y ; and store in colour address
CPY $07E8 ; right edge yet?
BNE LDB01 ; if not loop
RTS


; *************************************************
; Set window bottom and right
; *************************************************
LDE67 STA $07E5 ; Set current screen window bottom
STX $07E8 ; Set current screen window right
JMP LDE80

; *************************************************
; Reset current text window back to full screen
; (0,0) to (39,24)
; *************************************************
LDE70 LDA #$18 ; Set window bottom to 24
LDX #$27 ; Set window right to 39
JSR LDE67 ; set bottom and right variables
LDA #$00 ; Set window top to 0
TAX ; set window left to 0

; *************************************************
; Set window top and left
; *************************************************
LDE7A STA $07E6 ; Set current screen window top
STX $07E7 ; Set current screen window left


; *************************************************
; Clear screen line wrap table
; *************************************************
LDE80 LDA #$00
LDX #$04
LDE84 STA $07ED,x
DEX
BNE LDE84
RTS

No comments: