llvm-mos-sdk
cpm.h
Go to the documentation of this file.
1 /* CP/M entrypoints for C.
2  *
3  * © 2022 David Given
4  * This file is part of the llvm-mos-sdk project and is redistributable under
5  * the terms of the Apache 2.0 license with the LLVM exceptions. See the LICENSE
6  * file in the project root for the full text.
7  */
8 
9 #ifndef CPM_H
10 #define CPM_H
11 
12 #ifdef __cplusplus
13 extern "C" {
14 #endif
15 
16 #include <stdint.h>
17 
18 /* Standard FCB used for file access. */
19 
20 typedef struct __attribute__((packed)) {
21  uint8_t dr; /* drive number (1-based, or 0 for default) */
22  uint8_t f[11]; /* filename, space padded */
23  uint8_t ex; /* extent low: set to zero on open and otherwise ignore */
24  uint8_t s1; /* spare: ignore */
25  uint8_t s2; /* extent high: ignore */
26  uint8_t rc; /* number of records in this extent: ignore */
27  uint8_t al[16]; /* allocation map: ignore */
28  uint8_t cr; /* current record: ignore */
29  uint16_t r; /* random-access pointer: set when doing random-access calls */
30  uint8_t r2; /* random-access overflow: used only by cpm_seek_to_end */
31 } FCB;
32 
33 /* Rename control block, used only by cpm_rename_file. */
34 
35 typedef struct __attribute__((packed)) {
36  uint8_t dr; /* drive number (1-based, or 0 for default) */
37  uint8_t src[11]; /* source filename */
38  uint8_t _padding[5]; /* unused; ignore */
39  uint8_t dest[11]; /* destination filename */
40 } RCB;
41 
42 /* Directory entry on disk */
43 
44 typedef struct __attribute__((packed)) {
45  uint8_t us; /* user number */
46  uint8_t f[11]; /* filename, space padded */
47  uint8_t ex; /* extent low */
48  uint8_t s1; /* unused */
49  uint8_t s2; /* extent high */
50  uint8_t rc; /* number of records in the last extent in this dirent */
51  uint8_t al[16]; /* allocation map */
52 } DIRE;
53 
54 typedef struct __attribute__((packed)) {
55  uint16_t spt; /* number of 128-byte sectors per track (unused on CP/M-65) */
56  uint8_t bsh; /* block shift; 3=1kB, 4=2kB, 5=4kB etc */
57  uint8_t blm; /* block mask; 0x07=1kB, 0x0f=2kB, 0x1f=4k etc */
58  uint8_t exm; /* extent mask */
59  uint16_t dsm; /* maximum block number */
60  uint16_t drm; /* maximum directory entry number */
61  uint8_t al[2]; /* directory allocation bitmap */
62  uint16_t cks; /* checksum vector size */
63  uint16_t off; /* number of reserved sectors */
64 } DPB;
65 
66 typedef struct __attribute__((packed)) {
67  uint8_t *xlt; /* address of translation vector */
68  uint8_t scratch[6]; /* BDOS scratchpad */
69  uint8_t *dirbuf; /* address of directory scratchpad */
70  DPB *dpb; /* address of DPB */
71  uint8_t *csv; /* address of disk change scratchpad */
72  uint8_t *alv; /* address of allocation bitmap */
73 } DPH;
74 
75 typedef struct {
77  const char *name;
78  void *strategy;
79 } DRIVER;
80 
81 enum {
82  CPME_OK = 0x00, /* success (usually) */
83  CPME_NOBLOCK = 0x01, /* or EOF */
84  CPME_DISKFULL = 0x02, /* no free blocks on disk */
85  CPME_CANTCLOSE = 0x03, /* can't write extent back to disk */
86  CPME_NOEXTENT = 0x04, /* only on random access reads */
87  CPME_DIRFULL = 0x05, /* no free dirents on disk */
88  CPME_BADFCB = 0x09, /* FCB couldn't be parsed */
89  CPME_FAILED = 0xff, /* general purpose failure code */
90 };
91 
92 extern FCB cpm_fcb; /* primary FCB */
93 extern FCB cpm_fcb2; /* secondary FCB (special purpose, overlaps cpm_fcb) */
94 
95 extern uint8_t cpm_default_dma[128]; /* also contains the parsed command line */
96 extern uint8_t cpm_ram[];
97 extern uint8_t cpm_cmdlinelen;
98 extern char cpm_cmdline[0x7f];
99 extern uint8_t cpm_errno;
100 
101 enum {
103  CONIO_READ_BLOCKING = 0xfd00
104 };
105 
106 /* 0 */ extern __attribute__((leaf)) void _Noreturn cpm_warmboot(void);
107 /* 1 */ extern __attribute__((leaf)) uint8_t cpm_conin(void);
108 /* 2 */ extern __attribute__((leaf)) void cpm_conout(uint8_t b);
109 /* 3 */ extern __attribute__((leaf)) uint8_t cpm_auxin(void);
110 /* 4 */ extern __attribute__((leaf)) void cpm_auxout(uint8_t b);
111 /* 5 */ extern __attribute__((leaf)) void cpm_lstout(uint8_t b);
112 /* 6 */ extern __attribute__((leaf)) uint8_t cpm_conio(uint16_t b);
113 /* 7 */ extern __attribute__((leaf)) uint8_t cpm_get_iobyte(void);
114 /* 8 */ extern __attribute__((leaf)) void cpm_set_iobyte(uint8_t iob);
115 /* 9 */ extern __attribute__((leaf)) void cpm_printstring_i(uint16_t s);
116 extern void cpm_printstring(const char *s); /* $-terminated */
117 /* 10 */ extern __attribute__((leaf)) uint8_t cpm_readline_i(uint16_t buffer);
118 /* */ extern uint8_t cpm_readline(uint8_t *buffer);
119 /* 11 */ extern __attribute__((leaf)) uint8_t cpm_const(void);
120 /* 12 */ extern __attribute__((leaf)) uint16_t cpm_get_version(void);
121 /* 13 */ extern __attribute__((leaf)) void cpm_reset_disk_system(void);
122 /* 14 */ extern __attribute__((leaf)) void cpm_select_drive(uint8_t disk);
123 /* 15 */ extern __attribute__((leaf)) uint8_t cpm_open_file_i(uint16_t fcb);
124 extern uint8_t cpm_open_file(FCB *fcb);
125 /* 16 */ extern __attribute__((leaf)) uint8_t cpm_close_file_i(uint16_t fcb);
127 /* 17 */ extern __attribute__((leaf)) uint8_t cpm_findfirst_i(uint16_t fcb);
128 extern uint8_t cpm_findfirst(FCB *fcb);
129 /* 18 */ extern __attribute__((leaf)) uint8_t cpm_findnext_i(uint16_t fcb);
130 extern uint8_t cpm_findnext(FCB *fcb);
131 /* 19 */ extern __attribute__((leaf)) uint8_t cpm_delete_file_i(uint16_t fcb);
133 /* 20 */ extern __attribute__((leaf)) uint8_t
134 cpm_read_sequential_i(uint16_t fcb);
136 /* 21 */ extern __attribute__((leaf)) uint8_t
137 cpm_write_sequential_i(uint16_t fcb);
139 /* 22 */ extern __attribute__((leaf)) uint8_t cpm_make_file_i(uint16_t fcb);
140 extern uint8_t cpm_make_file(FCB *fcb);
141 /* 23 */ extern __attribute__((leaf)) uint8_t cpm_rename_file_i(uint16_t rcb);
143 /* 24 */ extern __attribute__((leaf)) uint16_t cpm_get_login_vector(void);
144 /* 25 */ extern __attribute__((leaf)) uint8_t cpm_get_current_drive(void);
145 /* 26 */ extern __attribute__((leaf)) void cpm_set_dma_i(uint16_t ptr);
146 extern void cpm_set_dma(void *ptr);
147 /* 27 */ extern __attribute__((leaf)) uint16_t
148 cpm_get_allocation_vector_i(void);
150 /* 28 */ extern __attribute__((leaf)) void cpm_write_protect_drive(void);
151 /* 29 */ extern __attribute__((leaf)) uint16_t cpm_get_readonly_vector(void);
152 /* 30 */ extern __attribute__((leaf)) uint8_t
153 cpm_set_file_attributes_i(uint16_t fcb);
155 /* 31 */ extern __attribute__((leaf)) uint16_t cpm_get_dpb_i(void);
156 extern DPB *cpm_get_dpb(void);
157 /* 32 */ extern __attribute__((leaf)) uint8_t cpm_get_set_user(uint8_t user);
158 /* 33 */ extern __attribute__((leaf)) uint8_t cpm_read_random_i(uint16_t fcb);
160 /* 34 */ extern __attribute__((leaf)) uint8_t cpm_write_random_i(uint16_t fcb);
162 /* 35 */ extern __attribute__((leaf)) void cpm_seek_to_end_i(uint16_t fcb);
163 extern void cpm_seek_to_end(FCB *fcb);
164 /* 36 */ extern __attribute__((leaf)) void cpm_seek_to_seq_pos_i(uint16_t fcb);
165 extern void cpm_seek_to_seq_pos(FCB *fcb);
166 /* 37 */ extern __attribute__((leaf)) uint8_t
167 cpm_reset_drives(uint16_t drive_bitmap);
168 /* 40 */ extern __attribute__((leaf)) uint8_t
169 cpm_write_random_filled_i(uint16_t fcb);
171 /* 41 */ extern __attribute__((leaf)) uint16_t cpm_getzp(void);
172 /* 42 */ extern __attribute__((leaf)) uint16_t cpm_gettpa(void);
173 /* 43 */ extern __attribute__((leaf)) uint16_t
174 cpm_parse_filename_i(uint16_t buffer);
175 extern const char *cpm_parse_filename(const char *buffer);
176 
177 #define cpm_get_user() cpm_get_set_user(0xff)
178 #define cpm_set_user(u) cpm_get_set_user(u)
179 
180 extern __attribute__((leaf)) uint8_t cpm_bios_const(void);
181 extern __attribute__((leaf)) uint8_t cpm_bios_conin(void);
182 extern __attribute__((leaf)) void cpm_bios_conout(uint8_t c);
185 extern __attribute__((leaf)) void
186 cpm_bios_setsec_i(uint16_t sector); /* actually only 24 bits */
187 extern void cpm_bios_setsec(uint32_t *sector); /* actually only 24 bits */
188 extern __attribute__((leaf)) void cpm_bios_setdma_i(uint16_t dma);
189 extern void cpm_bios_setdma(void *dma);
190 extern __attribute__((leaf)) uint8_t cpm_bios_read(void);
191 extern __attribute__((leaf)) uint8_t cpm_bios_write(uint8_t deblock);
192 extern __attribute__((leaf)) void cpm_bios_relocate(uint8_t zp, uint8_t mem);
193 extern __attribute__((leaf)) uint16_t cpm_bios_gettpa(void);
194 extern __attribute__((leaf)) void cpm_bios_settpa(uint8_t start, uint8_t end);
195 extern __attribute__((leaf)) uint16_t cpm_bios_getzp(void);
196 extern __attribute__((leaf)) void cpm_bios_setzp(uint8_t start, uint8_t end);
197 extern __attribute__((leaf)) void cpm_bios_adddrv_i(uint16_t driver);
198 extern void cpm_bios_adddrv(DRIVER *driver);
199 extern __attribute__((leaf)) uint16_t cpm_bios_finddrv_i(uint16_t id);
200 extern void *cpm_bios_finddrv(uint16_t id);
201 
202 #ifdef __cplusplus
203 }
204 #endif
205 
206 #endif
207 
208 // vim: ts=4 sw=4 et
DPH * cpm_bios_seldsk(uint8_t disk)
uint8_t cpm_write_random_filled(FCB *fcb)
void * cpm_bios_finddrv(uint16_t id)
uint8_t cpm_read_sequential(FCB *fcb)
void cpm_bios_adddrv(DRIVER *driver)
void cpm_bios_setdma(void *dma)
uint8_t cpm_write_random(FCB *fcb)
uint8_t cpm_make_file(FCB *fcb)
FCB
Definition: cpm.h:31
uint8_t cpm_rename_file(RCB *rcb)
char cpm_cmdline[0x7f]
uint8_t cpm_set_file_attributes(FCB *fcb)
uint8_t cpm_findnext(FCB *fcb)
void cpm_set_dma(void *ptr)
void cpm_printstring(const char *s)
@ CPME_BADFCB
Definition: cpm.h:88
@ CPME_CANTCLOSE
Definition: cpm.h:85
@ CPME_OK
Definition: cpm.h:82
@ CPME_DISKFULL
Definition: cpm.h:84
@ CPME_DIRFULL
Definition: cpm.h:87
@ CPME_NOEXTENT
Definition: cpm.h:86
@ CPME_NOBLOCK
Definition: cpm.h:83
@ CPME_FAILED
Definition: cpm.h:89
uint8_t cpm_readline(uint8_t *buffer)
uint8_t cpm_default_dma[128]
uint8_t cpm_read_random(FCB *fcb)
uint8_t cpm_findfirst(FCB *fcb)
uint8_t cpm_ram[]
uint8_t mem
Definition: cpm.h:192
FCB cpm_fcb
void cpm_seek_to_end(FCB *fcb)
uint16_t cpm_bios_seldsk_i(uint8_t disk)
@ CONIO_READ_BLOCKING
Definition: cpm.h:103
@ CONIO_READ_POLLING
Definition: cpm.h:102
uint8_t cpm_delete_file(FCB *fcb)
uint8_t cpm_cmdlinelen
FCB cpm_fcb2
RCB
Definition: cpm.h:40
DPH
Definition: cpm.h:73
uint8_t * cpm_get_allocation_vector(void)
uint8_t cpm_close_file(FCB *fcb)
void cpm_bios_setsec(uint32_t *sector)
uint8_t end
Definition: cpm.h:194
uint8_t cpm_write_sequential(FCB *fcb)
DPB
Definition: cpm.h:64
uint8_t cpm_open_file(FCB *fcb)
const char * cpm_parse_filename(const char *buffer)
void cpm_seek_to_seq_pos(FCB *fcb)
uint8_t cpm_errno
DPB * cpm_get_dpb(void)
DIRE
Definition: cpm.h:52
byte byte byte byte byte f
Definition: api.h:27
byte byte c
Definition: api.h:59
const void * src
Definition: memory.h:57
::uint32_t uint32_t
Definition: cstdint:23
::uint16_t uint16_t
Definition: cstdint:22
::uint8_t uint8_t
Definition: cstdint:21
Definition: cpm.h:75
uint16_t id
Definition: cpm.h:76
const char * name
Definition: cpm.h:77
void * strategy
Definition: cpm.h:78