1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-25 19:29:49 +00:00
millfork/include/cbm_file.mfk
2019-08-05 14:06:50 +02:00

216 lines
4.4 KiB
Plaintext

#if not(CBM)
#warn cbm_file module should be only used on Commodore targets
#endif
import string
import err
byte __last_used_device @$ba
inline byte last_used_device() {
byte device
device = __last_used_device
if device == 0 { device = 8 }
return device
}
void load_file(byte device, pointer name) {
setnamz(name)
setlfs(1, device, 1)
asm {
lda #0
jsr load
? jmp __handle_disk_err
}
}
void load_file_at(byte device, pointer name, pointer at) {
setnamz(name)
setlfs(1, device, 0)
asm {
lda #0
? ldx at
? ldy at+1
jsr load
? jmp __handle_disk_err
}
}
asm void __handle_disk_err() {
bcs __handle_disk_err_failed
lda #err_ok
? jmp __handle_disk_err_store
__handle_disk_err_failed:
ora #$40
jsr $FFD2
and #$BF
lsr
eor #2
bne __handle_disk_err_not_4_or_5
lda #err_nofile
bcc __handle_disk_err_store
lda #err_nodevice
[ $2c ]
__handle_disk_err_not_4_or_5:
lda #err_fail
__handle_disk_err_store:
? sta errno
? rts
}
void save_file(byte device, pointer name, pointer start, word length) {
setnamz(name)
setlfs(1, device, 0)
word end
end = start + length
asm {
lda #start
? ldx end
? ldy end+1
jsr save
? jmp __handle_disk_err
}
}
inline void setnamz(pointer name) {
setnam(name, strzlen(name))
}
array __cbm_cmd_buffer[64]
void exec_disk(byte device, pointer command) {
setnamz(command)
setlfs(1, device, 15)
open()
close(1)
}
void __exec_disk(byte device) {
setnamz(__cbm_cmd_buffer)
setlfs(1, device, 15)
open()
close(1)
}
void delete_file(byte device, pointer name) {
byte i
byte length
__cbm_cmd_buffer[0] = 's'
__cbm_cmd_buffer[1] = '0'
__cbm_cmd_buffer[2] = ':'
length = strzlen(name)
for i,0,parallelto,length {
__cbm_cmd_buffer[i + 3] = name[i]
}
__exec_disk(device)
}
void initialize_disk(byte device) {
__cbm_cmd_buffer[0] = 'i'
__cbm_cmd_buffer[1] = '0'
__cbm_cmd_buffer[2] = 0
__exec_disk(device)
}
void validate_disk(byte device) {
__cbm_cmd_buffer[0] = 'v'
__cbm_cmd_buffer[1] = '0'
__cbm_cmd_buffer[2] = 0
__exec_disk(device)
}
void format_disk(byte device) {
setnam(__cmd_format_disk, __cmd_format_disk.length)
setlfs(1, device, 15)
open()
close(1)
}
const byte MODE_READ = 0
const byte MODE_WRITE = 1
// const byte MODE_OVERWRITE = 3 // TODO: SAVE@ bug?
void open_file(byte device, pointer name, byte fd, byte mode) {
byte length
byte i
__cbm_cmd_buffer[0] = '0'
__cbm_cmd_buffer[1] = ':'
length = strzlen(name)
for i,0,parallelto,length {
__cbm_cmd_buffer[i + 2] = name[i]
}
if length < 3 || __cbm_cmd_buffer[length] != ',' || (__cbm_cmd_buffer[length+1] != 'r' && __cbm_cmd_buffer[length+1] != 'w') {
strzappendchar(__cbm_cmd_buffer, ',')
if mode & MODE_WRITE != 0 {
strzappendchar(__cbm_cmd_buffer, 'w')
} else {
strzappendchar(__cbm_cmd_buffer, 'r')
}
length += 2
}
setnam(__cbm_cmd_buffer, length + 2)
setlfs(fd, device, fd)
asm {
jsr open
? jmp __handle_disk_err
}
}
void close_file(byte fd) {
asm {
? lda fd
? jsr close
? jmp __handle_disk_err
}
}
void __translate_st_to_errno() {
byte st
st = readst()
if st == 0 {
errno = err_ok
} else if st & 0x80 != 0 {
errno = err_nodevice
} else if st & 0x40 != 0 {
errno = err_eof
} else {
errno = err_fail
}
}
byte getbyte_safe() {
byte b
b = getchar()
__translate_st_to_errno()
return b
}
void putbyte_safe(byte b) {
putchar(b)
__translate_st_to_errno()
}
array __cmd_format_disk = "n0:disk,01"z
void rename_file(byte device, pointer old_name, pointer new_name) {
__cbm_cmd_buffer[0] = 'r'
__cmd_rename_copy_common(device, old_name, new_name)
}
void copy_file(byte device, pointer old_name, pointer new_name) {
__cbm_cmd_buffer[0] = 'c'
__cmd_rename_copy_common(device, old_name, new_name)
}
void __cmd_rename_copy_common(byte device, pointer old_name, pointer new_name) {
__cbm_cmd_buffer[1] = '0'
__cbm_cmd_buffer[2] = ':'
__cbm_cmd_buffer[3] = 0
strzappend(__cbm_cmd_buffer, new_name)
strzappendchar(__cbm_cmd_buffer, '=')
strzappend(__cbm_cmd_buffer, old_name)
__exec_disk(device)
}