Open kochs-online opened 1 month ago
Great, thanks. I can implement LOCATE
for the PET once we have the ROM address for all targets.
I added the missing ROM addresses above and tested all of them successfully in VICE:
Trying to find the addresses I noticed, that the routines mentioned above are edtior ROM routines (located within $E000-$E0FF
memory range). Considering how many different editor ROMs are around I wasn't so sure anymore, if using the ROM routines really is a good idea…
Maybe it would be better (in terms of compatibility with different editor ROMs) to implement LOCATE
the same way these ROM routines do it one way or another?
So I tried to understand how it works and in the end the routines only perform a lookup of the screen memory address using the given row/line. This address is then written to a zero-page address. The given column is written directly to another zero-page address.
Here is an example for BASIC 4 (80 columns) from the PET BASIC and Kernal 4.0 ROM Disassembly:
; - Set Screen Pointers
E067 iE067 LDX $D8 ; Current Cursor Physical Line Number
E069 JMP $E06F
E06C iE06C LDY $E2 ; 4.80: first column of window (left margin)
E06E DEY
E06F iE06F LDA $E755,X ; - Screen Line Addresses LO DATA
E072 STA $C4 ; Pointer: Current Screen Line Address
E074 LDA $E76E,X ; - Screen Line Addresses HI DATA
E077 STA $C5
E079 RTS
So the routine only reads the desired cursor position line number from $D8
, performs a lookup of the address (low byte & high byte) of the first column of this line and stores this address at $C4
and $C5
. (The desired cursor position row number is stored in $C6
elsewhere.)
The lookup addresses (here: $E755
and $E76E
) differ of course for all the ROMs, but since we know the screen memory always starts at $8000
(it does, does it?!) we can calculate the address. All we need to know is the physical screen line length (40 or 80 characters/columns) of the target machine. This length value is already stored in zero-page address $D5
for BASIC 2 & BASIC 4 and $F2
for BASIC 1.
In the end all that is required is this pseudo-code (I'm not yet fluent enough in Assembler, sorry!):
; SCR_LN_ADDR = SCR_MEM_START + y_pos * (SCR_WDTH + 1)
lda #SCR_LN_ADDR[LO]
sta SCR_LN_PTR[LO]
lda #SCR_LN_ADDR[HI]
sta SCR_LN_PTR[HI]
lda x_pos
sta CRS_COL
lda y_pos
sta CRS_ROW ; required for next call of editor ROM subroutine by Kernal or BASIC
These are the required addresses for different PET targets: | BASIC 1 | BASIC 2 & 4 | Description |
---|---|---|---|
$8000 |
$8000 |
SCR_MEM_START : starting address of screen memory |
|
$F2 |
$D5 |
SCR_WIDTH : length of screen line (39 or 79) |
|
$E0-$E1 |
$C4-$C5 |
SCR_LN_PTR : pointer to screen RAM position of start of current line |
|
$E2 |
$C6 |
CRS_COL : position of cursor along line (column) |
|
$F5 |
$D8 |
CRS_ROW : screen line of cursor (row) |
Thanks! This is why many I/O commands aren't implemented for the PET, which does not expose a consistent KERNAL API. The second approach seems easy though, I'll give it a shot.
Great, thank you! Let me know, if I can be of any assistance!
According to the documentation of
LOCATE
this keyword is not supported for PET targets.I used this code to successfully position the cursor using the
Kernaleditor ROM routine to set screen pointers:SCR_COL
is$E2
for BASIC 1 and$C6
for BASIC 2 & BASIC 4.SCR_ROW
is$F5
for BASIC 1 and$D8
for BASIC 2 & BASIC 4.SET_SCR_PTR
is$E5DB
for BASIC 1,$E25D
for BASIC 2,$E071
for BASIC 4 (40 columns) and$E067
for BASIC 4 (80 columns);I haven't found the address for BASIC 1, BASIC 2 and BASIC 4 (40 column) yet.