Harry Potter Posted October 2, 2021 Share Posted October 2, 2021 Hi! I know about ANSI file commands. I have a program I want to eventually port to the Atari 8-bit series. It is written in cc65 C. I could use the ANSI file functions, but I want to allocate more memory for documents, and they require extra overhead. Is there a better way to access the disk from cc65 C code? If not, I could create it, but I need some info on Atari DOS. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted October 2, 2021 Share Posted October 2, 2021 Sounds like you're inventing imaginary limitations for yourself?! Files are random access in nature so load them as you see fit. Quote Link to comment Share on other sites More sharing options...
Harry Potter Posted October 2, 2021 Author Share Posted October 2, 2021 I mean I want to access the disk in ways other than by using the ANSI functions. Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted October 2, 2021 Share Posted October 2, 2021 Just use CIO functions, write is an assembler module, then it's DOS independent Quote Link to comment Share on other sites More sharing options...
Harry Potter Posted October 2, 2021 Author Share Posted October 2, 2021 Can you provide a link to the docs, please? I looked at cc65's Atari info and headers and didn't find useful information. Quote Link to comment Share on other sites More sharing options...
baktra Posted October 2, 2021 Share Posted October 2, 2021 There are two ways if you want to bypass functions provided by <stdio.h> 1. Use CIO as suggested above. You will be required to code in assembler, of course. You can google for more information on CIO. Perhaps you can look here. This is independent on file management system type. You can see how CIO is used to open a file here. 2. Access sectors of the disk directly using the resident disk handler. This would probably limit you to certain subset of file management systems. Then you might need to read Inside Atari DOS to get information on the DOS2 FMS. As for option #1, the question is, if calling CIO would result in significantly smaller code. Perhaps when you will use only a small set of file-related functions. Option #2 is useful only when your software will work without any DOS. Such option is typically used (but not limited to) by specialized copy programs providing big memory buffer for copied objects, e.g. tape to disk copiers. Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 (edited) Include _atarios.h and use the __iocb struct at the right memory location for IOCB0-7, and call CIOV. Edit: read Mapping The Atari Revised Edition, De Re Atari, OS Manual, et cetera. All free to download. You don't need to read the whole books, obviously Edited October 2, 2021 by ivop Quote Link to comment Share on other sites More sharing options...
Harry Potter Posted October 2, 2021 Author Share Posted October 2, 2021 How do I call CIOV? Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted October 2, 2021 Share Posted October 2, 2021 (edited) cc65 won't help, CIO in assembler is up to you to write the code, you can pass buffers/variables into the routines. Something like this:- closes channel 1, opens a file, reads one line, closes the channel Written in MAC/65 , but can easily be split into procs in cc65 assembler module. 10 LENGTH = 128 20 BUFFER = $0600 ; CIO BUFFER 0100 .INCLUDE #D:HEADER.M65 0110 *= $2000 0120 LDX #16 ; CHANNEL 1 0130 LDA #CLOSE 0140 STA ICCOM,X 0150 JSR CIOV ; CLOSE CHANNEL 1 0160 LDA #OPEN ; OPEN CHANNEL 1 0170 STA ICCOM,X 0180 LDA # <FNAME 0190 STA ICBAL,X 0200 LDA # >FNAME 0210 STA ICBAH,X 0220 LDA #0 0230 STA ICBLL,X 0240 STA ICBLH,X 0250 LDA #OREAD 0260 STA ICAX1,X 0270 LDA #0 0280 STA ICAX2 0290 JSR CIOV 0300 BMI ERROR 0310 JMP GET 0320 FNAME .BYTE "D:TEMP.TXT",$9B 0330 ERROR LDA #$FF 0340 RTS 0350 GET LDA #GETREC ; READ LINE 0360 STA ICCOM,X 0370 LDA # <BUFFER 0380 STA ICBAL,X 0390 LDA # >BUFFER 0400 STA ICBAH,X 0410 LDA #LENGTH 0420 STA ICBLL,X 0430 LDA #0 0440 STA ICBLH,X 0450 JSR CIOV 0460 BMI ERROR 0470 LDA #CLOSE 0480 STA ICCOM,X 0490 JSR CIOV 0500 RTS 0510 .OPT NO LIST Edited October 2, 2021 by TGB1718 Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 4 minutes ago, Harry Potter said: How do I call CIOV? Either with a C function pointer (in line with doing everything in C), or inline assembly doing JSR CIOV (which is $E456). Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 (edited) 9 minutes ago, TGB1718 said: cc65 won't help, CIO in assembler is up to you to write the code With _atari_os.h, it's not. You can do everything in C, including calling CIOV. Perhaps function pointers for these vectors should be added to this header file. Edit: void (*CIOV)(void) = 0xe456; call as: CIOV(); struct __iocb *IOCB0 = 0x0340; struct __iocb *IOCB1 = 0x0350; ... etc... IOCB1->command = IOCB_OPEN; etc... CIOV(); Edited October 2, 2021 by ivop Quote Link to comment Share on other sites More sharing options...
Harry Potter Posted October 2, 2021 Author Share Posted October 2, 2021 How do I pass the block # to CIOV()? Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 1 minute ago, Harry Potter said: How do I pass the block # to CIOV()? Darn, forgot about that. After setting the values through the struct pointer, you indeed need inline assembly to do LDX #$10 (IOCBnr * $10) and then JSR $E456. Sorry about that, _atarios.h is not complete yet. It could need a macro or inline function for that. Everything else I said is still valid. I hope Quote Link to comment Share on other sites More sharing options...
Harry Potter Posted October 2, 2021 Author Share Posted October 2, 2021 Thank you. BTW, do you recommend loading things into Low RAM using this function? Including it in the .XEX file doesn't work. Quote Link to comment Share on other sites More sharing options...
Wrathchild Posted October 2, 2021 Share Posted October 2, 2021 If you are loading it once then in the xex, but if you repeatedly load different content then that would ok, but equally any address suits. Quote Link to comment Share on other sites More sharing options...
Harry Potter Posted October 2, 2021 Author Share Posted October 2, 2021 How do I get an error # of a CIO call? Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted October 2, 2021 Share Posted October 2, 2021 (edited) 49 minutes ago, ivop said: With _atari_os.h, it's not. You can do everything in C, including calling CIOV. Perhaps function pointers for these vectors should be added to this header file. 5 minutes ago, Harry Potter said: How do I get an error # of a CIO call? like this:- ASM Module:- ; Export the start of program code .export _callciov .export _channel .export _result ciov=$e456 .proc _callciov: near .code _callciov: lda _channel clc rol a ; channel * 16 rol a rol a rol a tax jsr ciov sty _result rts .endproc _channel: .byte 0 _result: .byte 0 "C" Module :- #include <atari.h> #include <_atarios.h> extern char callciov(char); extern char channel; extern char result; void main(void) { channel=1; OS.iocb[1].command=IOCB_CLOSE; result=callciov(channel); } Edited October 2, 2021 by TGB1718 Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 Haha, another overlooked issue. The return value is in the Y register, and can be stored in inline assembly to a C variable by __asm__ ("sta %v", ciov_return_value); Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 (edited) 7 minutes ago, TGB1718 said: OS.iocb[1].command=IOCB_CLOSE; Cool, another way to access the IOCBs! But extern channel? Then channel=1 in the main program, and call CIOV(channel) without using the passed variable at all? I don't get it. CIOV(4) won't work. Edited October 2, 2021 by ivop Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted October 2, 2021 Share Posted October 2, 2021 6 minutes ago, ivop said: But extern channel? Then channel=1 in the main program, and call CIOV(channel) without using the passed variable at all? I don't get it. channel is defined in the .s module and exported to the c module, c module sets channel to 1, assembler converts it to 16 (channel 1) and calls CIOV Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 (edited) I love live coding in the AtariAge editor #define CIOV 0xe456 static inline /* optional */ unsigned char callciov(unsigned char channel) { unsigned char retval; channel <<= 4; __asm__ ("ldx %v", channel); __asm__ ("jsr %w", CIOV); __asm__ ("sty %v", retval); return retval; } Edit: improvements Edited October 2, 2021 by ivop Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 (edited) 2 minutes ago, TGB1718 said: channel is defined in the .s module and exported to the c module, c module sets channel to 1, assembler converts it to 16 (channel 1) and calls CIOV But your argument to the callciov() function is not used? Edited October 2, 2021 by ivop Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted October 2, 2021 Share Posted October 2, 2021 it does lda _channel clc rol a ; channel * 16 rol a rol a rol a tax <<<<< here channel now 16 in x register jsr ciov Quote Link to comment Share on other sites More sharing options...
ivop Posted October 2, 2021 Share Posted October 2, 2021 (edited) 3 minutes ago, TGB1718 said: it does lda _channel clc rol a ; channel * 16 rol a rol a rol a tax <<<<< here channel now 16 in x register jsr ciov But that's not the argument that's passed on by calling callciov(4), or is it? That's the global variable. Why do channel=1 in the main program otherwise in the first place? Seems like the argument to the function is moot. Edited October 2, 2021 by ivop Quote Link to comment Share on other sites More sharing options...
danwinslow Posted October 2, 2021 Share Posted October 2, 2021 (edited) Perhaps you could read some documentation, such as this : https://www.atariarchives.org/dere/ MOre specifically, this section: https://www.atariarchives.org/dere/chapt08.php#H8_6 Edited October 2, 2021 by danwinslow 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.