Jump to content
IGNORED

cc65 __graphics call using IOCB #1 instead of #6?


fenrock

Recommended Posts

Does anyone know if this is incorrect behaviour?

I'm issuing a `__graphics` call when quitting my assembly application to emulate doing a "GR.0".

 

The application is run from SDX, and when I quit the application, I want it to go back to DOS, which I'm doing by doing the GR.0.
However, when I then issue a command like "DIR", it's giving an error 129 (iocb already open).

 

In Altirra, it's showing the following:

 

CIO call tracing is now on.
CUSTOMDEV: Fuji READ DEVICES
CIO: IOCB=1, CMD=$03 (open), AUX1=$1c, filename="S:"
CIO: IOCB=0 (E:), CMD=$07 (put characters): buf=$145F, len=$0004
CIO: IOCB=0 (E:), CMD=$05 (get record), buffer=$1411, length=$0040
CIO: IOCB=1, CMD=$03 (open), AUX1=$06, filename="D2:*.*"
CIO: IOCB=1 (S:), CMD=$0C (close)
CIO: IOCB=1 (-), CMD=$0C (close)

 

showing that S: is open on IOCB#1 instead of #6, which then throws an error.

 

All I'm doing in my code is:

 

  lda #$00
  jsr __graphics

 

I've replaced this with some custom "close #6, reopen S: on #6" instead, which is working fine, and I no longer get the errors. Screen resets nicely, and users should be happy

 

        ; ...
        lda     #$60
        jsr     _close_scr
        jsr     _open_scr

        ; exit back to caller
        rts
.endproc

.proc _close_scr
        tax
        mva     #$0C,  {ICCOM, x}
        jsr     CIOV
        bpl     ok
        jmp     return1
ok:
        jmp     return0
        rts
.endproc

.proc _open_scr
        ldx     #$60
        mva     #$03,   {ICCOM, x}  ; open
        mva     #<dev_name, {ICBAL, x}
        mva     #>dev_name, {ICBAH, x}
        mva     #$2C,   {ICAX1, x}  ; $20 = clear screen, $0C = R/W
        mva     #$00,   {ICAX2, x}
        jsr     CIOV
        bpl     ok
        jmp     return1
ok:
        jmp     return0
.endproc

.data
dev_name:        .byte "S:", 0

 

Should cc65's `__graphics` be using IOCB #6 instead of looking for a free IOCB when doing GR.0?

 

Thanks!

 

FYI @sanny @DjayBee

 

Edited by fenrock
typos in code
Link to comment
Share on other sites

If you want to emulate what BASIC does for GR.0, then yeah, opening S: with IOCB#6 would be preferable over IOCB#1. But you don't really need to do that and it'd be safer not to leave S: open. Instead, make sure any handles to S: are closed and then close and reopen E: on IOCB#0 to reset the Display Handler.

 

Link to comment
Share on other sites

Cheers @phaeron

 

Thom had originally told me I should "just close and open E:" but I was having trouble doing that, with what turned out to be the need to specify RESERVED_MEMORY, and while solving that stumbled on __graphics. I'm not creating anything on S:, that was all being done by cc65's `__graphics`call as far as I can tell.

 

This was more a case of reporting something odd in CC65's handling of IOCBs for S:, I've been told it should have been on #6, hence mentioning @sanny.

 

I've amended my code to use E: on #0, and that works nicely too, so thanks for the suggestion 👍

 

Link to comment
Share on other sites

Hi!

2 hours ago, DjayBee said:

IOCB #0 is always E: and at least by convention IOCB #6 is S:. 

The numbers are not selected as "next free one". 

That is in BASIC.

 

CC65 keeps compatibility with the C library, so it needs to allocate IOCB dynamically (allocating on open, freeing on close), and needs to use the same machinery for it's "graphics" command to avoid conflicts.

 

Have Fun!.

 

Link to comment
Share on other sites

Then there must be an issue in SDX, as that was making assumptions about IOCB numbers and getting errors because the one it expected to use was already allocated by CC65's __graphics library.

Or maybe I'm not supposed to drop out of the application once issuing __graphics commands.
Either way, it's resolved by manually opening and closing E: as I was told by a couple of people.

It's all good, I learned a few things, and I'm very happy it all "just worked" in the end.

 

And another thing. Merry Christmas :D 🌲

Link to comment
Share on other sites

On 12/23/2023 at 11:19 PM, dmsc said:

Hi!

That is in BASIC.

 

CC65 keeps compatibility with the C library, so it needs to allocate IOCB dynamically (allocating on open, freeing on close), and needs to use the same machinery for it's "graphics" command to avoid conflicts.

 

Have Fun!.

 

Ah, looking at the source, calling __graphics returns a File Descriptor, and there's an "fdtoiocb" function available too, so I suppose in theory I could issue __graphics, convert the return value to IOCB number, and close it, as I'm "done" with my graphics routines.

 

Ok, that worked.

 

        lda     #$00
        jsr     __graphics
        jsr     fdtoiocb
        tax
        mva     #CLOSE, {ICCOM, x}
        jsr     CIOV

 

Good to know when I use graphics, but not so good here as it adds 718 bytes to the application for the functions it pulls in, but had I been using graphics for another reason, would work perfectly.

 

Thanks all.

Link to comment
Share on other sites

Ah, thanks.

 

This is the problem with being fairly new to the library!

 

I hadn't come across FDs before using cc65.

There's also no docs on using __graphics (it's mentioned, and says read the list of functions, but then doesn't appear), which may have lead me to reading up on FDs and using close. I literally read the source and saw the fdtoiocb function mentioned, so hacked on that :D 

 

Thank you for your time again, really helps me when my experiments are corrected to use the right code.

 

This is now minimally working nicely with no IOCB errors anymore to effectively do a "GR.0" when exiting an application (for anyone who comes across this thread):

 

        lda     #$00
        jsr     __graphics
        jsr     _close

 

 

Edited by fenrock
Link to comment
Share on other sites

In cc65, you can use the following:-

fd is not the channel number, but it can be used with the functions read and write.

In this example, fd is set to 3, but the channel that opens is channel1 (IOCB1)

 

#include <atari.h>
#include <stdlib.h>
#include <peekpoke.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
//#include <fcntl.h>
//#include <stdio.h>
#include <conio.h>
// display memory (max 256 bytes)
void main(void)
{
char fd;
    fd=_graphics(0);                     // open screen
    printf("%d\n",fd);                   // print the channel number
    write(fd,"Hello\n",strlen("Hello\n")); // output string to screen via fd
    POKE(764,255);                     // wait for key press
    do
        {}while(PEEK(764)==255);
    close(fd);                             // don't forget to close, else it stays open


}

 

image.thumb.png.2807f29be92fee2d05ef393fb975c5c1.png

Edited by TGB1718
Link to comment
Share on other sites

Hi!

4 hours ago, fenrock said:

Ah, thanks.

 

This is the problem with being fairly new to the library!

 

I hadn't come across FDs before using cc65.

 

The CC65 library is meant to be used from C, so it uses file-descriptors to be compatible with standard C, using open(), close(), read(), write(), etc.

 

4 hours ago, fenrock said:

There's also no docs on using __graphics (it's mentioned, and says read the list of functions, but then doesn't appear), which may have lead me to reading up on FDs and using close. I literally read the source and saw the fdtoiocb function mentioned, so hacked on that :D 

 

Thank you for your time again, really helps me when my experiments are corrected to use the right code.

 

This is now minimally working nicely with no IOCB errors anymore to effectively do a "GR.0" when exiting an application (for anyone who comes across this thread):

 

        lda     #$00
        jsr     __graphics
        jsr     _close

Yes, that should work. But when writing in assembler, I would not use the C library.

 

Have Fun!

Link to comment
Share on other sites

On 12/21/2023 at 9:43 PM, fenrock said:

The application is run from SDX, and when I quit the application, I want it to go back to DOS, which I'm doing by doing the GR.0.
However, when I then issue a command like "DIR", it's giving an error 129 (iocb already open).

You sure of this? SDX almost never uses the CIO channels, and certainly not for DIR, so it is beyond me how leaving a IOCB open may cause error 129 in DIR...

Link to comment
Share on other sites

The way to say it is:

In the CC65 Atari library, the Atari "IOCB" construct has been completely abstracted under the C standard 'File Descriptor' concept. It is still possible to use either or both in a program, but mixing the two in the same program can lead to problems.

 

In my opinion, the memory cost of pulling in a bunch of stdio stuff supporting the file descriptors is too high, and I just wrote a thin utility layer over IOCB's and used that. Where the CC65 stdio library really comes into it's own is for quick utilities and also when cross compiling non-Atari c programs.

Edited by danwinslow
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...