CC65 and system cursor implementation

Since we do not have native C compilers on the Oric, this forum will be mostly be used by people using CC65 or the OSDK. But any general C related post will be welcome !
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

CC65 and system cursor implementation

Post by xahmol »

I am in the progress of porting a screen editor I wrote for Commodore machines to the Oric Atmos, code is in C using CC65.

In the original I use the system cursor as cursor in my program, saves a lot of own code for a cursor and can be easily enabled/disabled by the CC65 cursor(1) resp. cursor(0) function in the conio lib.

However, for me this cursor() function does absolutely nothing if I compile code for the Oric Atmos target. It does not give an error as well, it just does not do anything it seems. Which is funny, as I see in the compiler .map output that the cursos function is actually compiled for the Atmos and takes up 10 bytes of code:

Code: Select all

/mnt/d/retro/cc65/lib/atmos.lib(cursor.o):
    CODE              Offs=002BDB  Size=00000A  Align=00001  Fill=0000
So I went looking how the OSDK C compiler does it, see there that it enables/disables the cursor by setting a bit in the $269 memory position. The setflags function in the OSDK default header file.
Tried that, and I do get a cursor. However, this cursor only moves horizontally, vertically it keeps stuck on line 1 (first line after the status line 0). Also tried poking the Y position to $268 cursos row number, but that has no effect at all.

No clue what goes on here.

So my questions:
- can anyone confirm that the cursor() function of the CC65 conio lib is broken for the Atmos target? Or do I miss something else here?
- when enabling bit 0 on $269, why does the cursor in my CC65 compiled program remains stuck on line 1 (but does move correctly horizontally?) Again, something I miss? Or is here the CC65 conio lib conflicting?
- why doesn't poking to $268 cursor row number and $269 cursor column position do anything? Maybe again a conflict with CC65 conio functions?

Already have an alternative in mind (plotting in inverse, so charactervalue + 128, on cursor position). But still would like to have at least the option to use the Atmos system cursor instead.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

(testing in Oricutron by the way. Did not tru on original hardware yet)
Edit: Also the same on real hardware.
Last edited by xahmol on Wed Jun 08, 2022 10:43 am, edited 1 time in total.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

Looking at the CC65 lib sources now, and I see that the Atmos conio implementation uses those exact same $268, $269 and $26A addresses to set x,y of cursor and enable/disable cursor. Which would indeed explain why conio interferes with directly setting those addresses as well, but not why the default CC65 does not work for me....

https://github.com/cc65/cc65/blob/maste ... /atmos.inc

Code: Select all

CURS_Y          := $0268
CURS_X          := $0269
STATUS          := $026A
https://github.com/cc65/cc65/blob/maste ... o/cursor.s

Code: Select all

;
; Ullrich von Bassewitz, 17.06.1998
;
; unsigned char cursor (unsigned char onoff);
;

        .export         _cursor
        .import         cursor


.proc   _cursor

        tay                     ; onoff into Y
        ldx     #0              ; High byte of result
        lda     cursor          ; Get old value
        sty     cursor          ; Set new value
        rts

.endproc
https://github.com/cc65/cc65/blob/maste ... os/cgetc.s

Code: Select all

; No character, enable cursor and wait

        lda     cursor          ; Should cursor be off?
        beq     @L1             ; Skip if so
        lsr     STATUS
        sec                     ; Cursor ON
        rol     STATUS
 
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

Werid.

Tried setting $26A first with 2, so screen without cursor. And then switching cursor on by cursor(1). In that case, I do get a cursor at cgetc();, but again a cursor that only moves on line 1. And also leaves quite some inverted spaces on that line while moving.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

Youtube video to better explain. See the cursor moving on the first line only and leaving inverted spaces. Cursor should be following the exclamation mark.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

Will post a CC65 issue on the CC65 Github as well, unless somebody will point me here that I am myself missing something.
User avatar
Dbug
Site Admin
Posts: 4444
Joined: Fri Jan 06, 2006 10:00 pm
Location: Oslo, Norway
Contact:

Re: CC65 and system cursor implementation

Post by Dbug »

Personally I never use the system cursor, it's to easy to break when scrolling, refreshing stuff, etc...

All it does really is that every second the system IRQ changes the bit 7 of wherever the cursor is supposed to be displayed to toggle the inverse video
User avatar
iss
Wing Commander
Posts: 1641
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: CC65 and system cursor implementation

Post by iss »

Maybe the CC65's conio for Atmos is little strange but I think it works.
Check the conio.h file:

Code: Select all

char cgetc (void);
/* Return a character from the keyboard. If there is no character available,
** the function waits until the user does press a key. If cursor is set to
** 1 (see below), a blinking cursor is displayed while waiting.
*/
and

Code: Select all

unsigned char __fastcall__ cursor (unsigned char onoff);
/* If onoff is 1, a cursor is displayed when waiting for keyboard input. If
** onoff is 0, the cursor is hidden when waiting for keyboard input. The
** function returns the old cursor setting.
*/
The value set by 'cursor' function is used ONLY during the waiting for keyboard input.
Using clrscr() at program start will HIDE the cursor.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

@iss, thanks, but did already know that.

Maybe I should have been more precise, cursor does not appear waiting on cgetc() after selecting cursor(1).

It does appear if I first disable the cursor bit of $26A but as seen in the video very erratically.

In the video, the exclamation mark is moved by pressing the cursor keys, it does this by waiting with cgetc() for the cursor to be pressed.

But I think I now already believe what Dbug says: do not use it because it behaves to erratically 😉
So probably will move to an alternative. Which is actually set that inverse bit of the active character myself, only thing that I miss than is the flashing as I have not much inclination to write a flash IRQ routine myself.
User avatar
iss
Wing Commander
Posts: 1641
Joined: Sat Apr 03, 2010 5:43 pm
Location: Bulgaria
Contact:

Re: CC65 and system cursor implementation

Post by iss »

Actually the cursor works as it's supposed to work.
But there is a bug too - the internal screen pointer is not updated properly.
Here is working code:

Code: Select all

#include <conio.h>

#define PX    2
#define PY    2

static int n;

int main(void)
{
  clrscr();
  cursor(1);

  for(n=0; n<26; n++)
  {
    gotoxy(PX+n,PY+n);
    cputs("Hello world!");

    // FIX1: update screen pointer to current row
    *((unsigned int*)0x0012) = 0xbb80+(PY+n)*40;

    cgetc();

    // FIX2: hide cursor trace
    cputc(0x20);
  }

  return 0;
}
BTW, as Dbug I also never use this functions (except for prototyping and debugging) ;)
Last edited by iss on Wed Jun 08, 2022 1:22 pm, edited 1 time in total.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

Thanks Iss! That explains a lot.
Problem only is that that cputc(0x20); will rather wreck havoc in the screen that you are editing. Which is fixable by getting the proper char for that position from the memory map memory area again, but the fix will be rather complex with that.

So probably will go without the system cursor then, and contemplate to issue a CC65 bug for this on the CC65 github.
User avatar
xahmol
Flight Lieutenant
Posts: 437
Joined: Sun Jun 28, 2020 7:32 pm
Location: Utrecht, The Netherlands
Contact:

Re: CC65 and system cursor implementation

Post by xahmol »

Works much better now with just inverting the inverse bit. No flashing, but working.
Now have a basis to copy the rest of the code in.

Post Reply