-
Notifications
You must be signed in to change notification settings - Fork 1
/
libcpm.s
196 lines (155 loc) · 4.16 KB
/
libcpm.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
.module libcpm
.globl _cpm_f_open
.globl _cpm_f_create
.globl _cpm_f_close
.globl _cpm_f_delete
.globl _cpm_f_read_next
.globl _cpm_f_write_next
.globl _cpm_f_read_random
.globl _cpm_f_write_random
.globl _cpm_f_getsize
.globl _cpm_abort
.area _CODE
_cpm_abort:
ld c, #0
jp 5
_cpm_f_create:
ld c, #0x16 ; Function 22, Make File
jr gocpm
_cpm_f_close:
ld c, #0x10 ; Function 16, Close File
jr gocpm
_cpm_f_delete:
ld c, #0x13 ; Function 19, Delete File
jr gocpm
_cpm_f_open:
ld c, #0x0F ; Function 15, Open File
gocpm: ; the rest of this routine is shared with the other simple CP/M calls
pop hl ; return address
pop de ; FCB address (argument)
; put the stack back
push de
push hl
call 5 ; call CP/M BDOS
ld hl, #0 ; return 0 on success
inc a ; A=0xFF means error, becomes 0
ret nz
dec hl ; return -1 on error
ret
_cpm_f_getsize:
pop hl ; return address
pop de ; FCB address (argument)
; put the stack back
push de
push hl
push de ; save FCB address
ld c, #0x23 ; Function 35, Compute File Size
call 5 ; call CP/M BDOS
pop de ; restore FCB address to DE
; there does not appear to be any "error" status return from function 35.
; some docs suggest A=0xFF indicates error but this is not borne out by testing.
ld hl, #33 ; random offset is at offset 33, 34, 35 in FCB
add hl, de
ld e, (hl) ; load size (in 128-byte blocks) into DE
inc hl
ld d, (hl)
ex de, hl ; return value in HL
ret
_cpm_f_read_next:
push ix
ld ix, #0
add ix, sp
; stack has: ix, return address, fcb, buffer
; ix+4 ix+6
; set the CP/M DMA address to our buffer
ld c, #0x1A ; Function 26, Set DMA address
ld e, 6(ix)
ld d, 7(ix)
call 5
ld c, #0x14 ; Function 20, Read next record
ld e, 4(ix)
ld d, 5(ix)
call 5
; return result code
ld h, #0
ld l, a
pop ix
ret
_cpm_f_write_next:
push ix
ld ix, #0
add ix, sp
; stack has: ix, return address, fcb, buffer
; ix+4 ix+6
; set the CP/M DMA address to our buffer
ld c, #0x1A ; Function 26, Set DMA address
ld e, 6(ix)
ld d, 7(ix)
call 5
ld c, #0x15 ; Function 21, Write next record
ld e, 4(ix)
ld d, 5(ix)
call 5
; return result code
ld h, #0
ld l, a
pop ix
ret
_cpm_f_read_random:
push ix
ld ix, #0
add ix, sp
; stack has: ix, return address, fcb, block, buffer
; ix+4 ix+6 ix+8
; set the CP/M DMA address to our buffer
ld c, #0x1A ; Function 26, Set DMA address
ld e, 8(ix)
ld d, 9(ix)
call 5
; load FCB address into DE
ld e, 4(ix)
ld d, 5(ix)
; adjust record number in FCB
ld hl, #33 ; random offset is at offset 33, 34, 35 in FCB
add hl, de
ld a, 6(ix)
ld (hl), a
inc hl
ld a, 7(ix)
ld (hl), a
ld c, #0x21 ; Function 33, Read random
call 5
; return result code
ld h, #0
ld l, a
pop ix
ret
_cpm_f_write_random:
push ix
ld ix, #0
add ix, sp
; stack has: ix, return address, fcb, block, buffer
; ix+4 ix+6 ix+8
; set the CP/M DMA address to our buffer
ld c, #0x1A ; Function 26, Set DMA address
ld e, 8(ix)
ld d, 9(ix)
call 5
; load FCB address into DE
ld e, 4(ix)
ld d, 5(ix)
; adjust record number in FCB
ld hl, #33 ; random offset is at offset 33, 34, 35 in FCB
add hl, de
ld a, 6(ix)
ld (hl), a
inc hl
ld a, 7(ix)
ld (hl), a
ld c, #0x22 ; Function 34, Write random
call 5
; return result code
ld h, #0
ld l, a
pop ix
ret