Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
cbmhostfs.c
Go to the documentation of this file.
1 /* Test program for Xemu/CBMhostFS, use it with CC65 compiler.
2 
3  Copyright (C)2016 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 
20 
21 #include <stdio.h>
22 
23 typedef unsigned char BYTE;
24 
25 #define POKE(a,d) *(BYTE*)(a) = (d)
26 #define PEEK(a) (*(BYTE*)(a))
27 
28 #define HOSTFSR0 0xD0FEU
29 #define HOSTFSR1 0xD0FFU
30 
31 
32 #define HOSTFS_READ 0
33 #define HOSTFS_OVERWRITE 1
34 #define HOSTFS_WRITE 2
35 
36 /* Open a HostFS file
37  channel: channel number (0-15), for future compatibility, values 2-14 should be used (15 will be the command/status channel as with CBM DOS)
38  filename: guess what ... currently there is no PETSCII-ASCII conversion, so be careful!
39  mode: HOSTFS_READ, HOSTFS_WRITE, HOSTFS_OVERWRITE, only one! Note: write access does not work (at all or too well ...) yet.
40  Return value: 0 = ok, non-zero = error
41 */
42 static BYTE hostfs_open ( BYTE channel, const char *filename, BYTE mode )
43 {
44  channel &= 0xF;
45  POKE(HOSTFSR0,0x00); // signal start transmission of "channel specification" (ie: file name), low nibble is not used
46  // TODO: we don't check status on transmitting file name ... That should be a mistake, however if filename is not too long it should be no problem.
47  if (mode == HOSTFS_OVERWRITE) {
48  POKE(HOSTFSR1,'@'); // send the '@' prefix if overwrite is instructed
50  }
51  while (*filename)
52  POKE(HOSTFSR1,*(filename++)); // transmit filename
53  if (mode == HOSTFS_WRITE) {
54  POKE(HOSTFSR1,',');
55  POKE(HOSTFSR1,'p'); // this would be "P" as "PRG" file, though it's currently ignored (but needed!)
56  POKE(HOSTFSR1,',');
57  POKE(HOSTFSR1,'w'); // Write access ...
58  }
59  POKE(HOSTFSR0,0x10 | channel); // open "call", low nibble is channel number to open the desired filename at.
60  return PEEK(HOSTFSR0);
61 }
62 
63 
64 static BYTE hostfs_close ( BYTE channel )
65 {
66  POKE(HOSTFSR0, 0x30 | (channel & 0xF)); // close function
67  return PEEK(HOSTFSR0);
68 }
69 
70 
71 static int hostfs_read ( BYTE channel, void *buffer_spec, int num )
72 {
73  int numread = 0;
74  BYTE *buffer = buffer_spec;
75  POKE(HOSTFSR0, 0x40 | (channel & 0xF)); // set channel (already open channel) number for communication
76  while (numread < num) {
77  BYTE data = PEEK(HOSTFSR1); // try to read one byte, this must be the FIRST, and status must check after this, if this byte is valid at all!
78  // check status
80  if (status & 64) // EOF?
81  break;
82  if (status & 128)
83  return -1; // some kind of hostFS I/O error?
84  numread++;
85  *(buffer++) = data;
86  }
87  return numread;
88 }
89 
90 
91 static int hostfs_write ( BYTE channel, void *buffer_spec, int num )
92 {
93  int numwrite = 0;
94  BYTE *buffer = buffer_spec;
95  POKE(HOSTFSR0, 0x40 | (channel & 0xF)); // set channel (already open channel) number for communication
96  while (numwrite < num) {
97  POKE(HOSTFSR1, *(buffer++));
98  if (PEEK(HOSTFSR0))
99  return -1;
100  numwrite++;
101  }
102  return numwrite;
103 }
104 
105 
106 
107 
108 static const char *TEST_FILE_NAME = "testfile"; // filename. BEWARE! currently emulator does not do conversion PETSII<->ASCII etc ......
109 
110 static BYTE buffer[256];
111 
112 
113 
114 int main ( void )
115 {
116  int ret,n;
117  /* Use C65 I/O mode */
118  POKE(0xD02FU,0xA5);
119  POKE(0xD02FU,0x96);
120  /* whatever ... */
121  POKE(53281U,0);
122 
123  /* trying to open a file */
124  printf("Trying to open file: %s\n", TEST_FILE_NAME);
125  if (hostfs_open(2, TEST_FILE_NAME, HOSTFS_READ)) {
126  printf("Could not open hostfs file!\n");
127  printf("Continue with test #2\n");
128  goto test2;
129  }
130  printf("OK, file is open\n");
131  ret = hostfs_read(2, buffer, sizeof buffer);
132  printf("File read returned with = %d\n", ret);
133  if (ret < 0)
134  return 1;
135  printf("Dumping read data ...\n");
136  n = 0;
137  while (n < ret) {
138  putchar(buffer[n++]);
139  }
140  putchar('\n');
141 
142  printf("Closing file\n");
143  hostfs_close(2);
144 
145  /* test-2: try to open directory, dump that into a new file, overwriting it */
146 
147 test2:
148  printf("Test#2: dump dir to dirfile\n");
149 
150  if (hostfs_open(3, "$", HOSTFS_READ)) {
151  printf("Cannot open file $\n");
152  return 1;
153  }
154  if (hostfs_open(4, "dirlist", HOSTFS_OVERWRITE)) {
155  printf("Cannot create file dirlist\n");
156  return 1;
157  }
158  for (;;) {
159  int r = hostfs_read(3, buffer, sizeof buffer);
160  printf("Read retval: %d\n", r);
161  if (r < 0) {
162  printf("I/O error while reading $\n");
163  hostfs_close(3);
164  hostfs_close(4);
165  return 1;
166  }
167  if (r == 0)
168  break;
169  if (hostfs_write(4, buffer, r) != r) {
170  printf("Error writing file dirlist\n");
171  hostfs_close(3);
172  hostfs_close(4);
173  return 1;
174  }
175  }
176  hostfs_close(3);
177  hostfs_close(4);
178 
179  printf("END :-)\n");
180  return 0;
181 }
HOSTFSR1
#define HOSTFSR1
Definition: cbmhostfs.c:29
HOSTFS_OVERWRITE
#define HOSTFS_OVERWRITE
Definition: cbmhostfs.c:33
BYTE
unsigned char BYTE
Definition: cbmhostfs.c:23
PEEK
#define PEEK(a)
Definition: cbmhostfs.c:26
HOSTFS_READ
#define HOSTFS_READ
Definition: cbmhostfs.c:32
m65-memcontent-generator.data
data
Definition: m65-memcontent-generator.py:119
mode
int mode
Definition: vera.c:61
main
int main(void)
Definition: cbmhostfs.c:114
HOSTFSR0
#define HOSTFSR0
Definition: cbmhostfs.c:28
compress_sd_image.r
def r
Definition: compress_sd_image.py:76
status
enum @26::@29 status
HOSTFS_WRITE
#define HOSTFS_WRITE
Definition: cbmhostfs.c:34
POKE
#define POKE(a, d)
Definition: cbmhostfs.c:25