mirror of https://github.com/gungwald/copy.git
Added online impl
This commit is contained in:
parent
a63dc4abee
commit
9297b9687f
|
@ -1,3 +1,6 @@
|
||||||
|
# Vim swap files
|
||||||
|
*.swp
|
||||||
|
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
*.d
|
*.d
|
||||||
|
|
||||||
|
|
58
Makefile
58
Makefile
|
@ -1,44 +1,30 @@
|
||||||
# Builds copy command
|
# Compiles with https://www.brutaldeluxe.fr/products/crossdevtools/merlin/
|
||||||
|
#
|
||||||
# Requirements:
|
ifeq ($(OS),Windows_NT)
|
||||||
# 1. Gmake must be used.
|
MERLIN_DIR=C:/opt/Merlin32_v1.0
|
||||||
# 2. The cc65 compiler must be properly setup.
|
MERLIN_LIB=$(MERLIN_DIR)/Library
|
||||||
|
MERLIN=$(MERLIN_DIR)/Windows/Merlin32
|
||||||
ifndef CC65_TARGET
|
RM=del /s
|
||||||
CC65_TARGET:=apple2enh
|
else
|
||||||
|
MERLIN_DIR=$(HOME)/opt/Merlin32_v1.0
|
||||||
|
MERLIN_LIB=$(MERLIN_DIR)/Library
|
||||||
|
MERLIN=$(MERLIN_DIR)/Linux64/Merlin32
|
||||||
|
RM=rm -f
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CC=cl65
|
|
||||||
CFLAGS=-O -t $(CC65_TARGET) -DTRACE
|
|
||||||
LDFLAGS=-t $(CC65_TARGET)
|
|
||||||
PGM=copy
|
|
||||||
DISK_VOL=$(PGM)
|
|
||||||
DISK=$(DISK_VOL).dsk
|
|
||||||
AC=java -jar AppleCommander-ac-1.4.0.jar
|
AC=java -jar AppleCommander-ac-1.4.0.jar
|
||||||
SYS_LOAD_ADDR=0x2000
|
SRC=copy.s
|
||||||
BIN_LOAD_ADDR=0x0803
|
PGM=copy
|
||||||
BASIC_AUX_TYPE=0x0801
|
VOL=$(PGM)
|
||||||
READ_TIME_LOAD_ADDR=0x0260
|
DSK=$(PGM).dsk
|
||||||
MKDISK=$(AC) -pro140 $(DISK) $(DISK_VOL)
|
|
||||||
|
|
||||||
########################################
|
$(DSK): $(PGM)
|
||||||
|
$(AC) -pro140 $(DSK) $(VOL)
|
||||||
|
$(AC) -p $(DSK) $(PGM) SYS < $(PGM)
|
||||||
|
|
||||||
all: $(DISK)
|
$(PGM): $(SRC)
|
||||||
|
$(MERLIN) $(MERLIN_LIB) $(SRC)
|
||||||
$(DISK): $(PGM)
|
|
||||||
$(RM) $(DISK)
|
|
||||||
$(AC) -pro140 $(DISK) $(DISK_VOL)
|
|
||||||
$(AC) -as $(DISK) $(PGM) BIN < $(PGM)
|
|
||||||
|
|
||||||
$(PGM): online.o $(PGM).o
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^
|
|
||||||
|
|
||||||
$(PGM).o: $(PGM).c
|
|
||||||
$(CC) $(CFLAGS) $^
|
|
||||||
|
|
||||||
online.o: online.c
|
|
||||||
$(CC) $(CFLAGS) $^
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) *.o $(PGM) $(DISK)
|
$(RM) $(DSK) $(PGM)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Builds online
|
||||||
|
|
||||||
|
# Requirements:
|
||||||
|
# 1. Gmake must be used.
|
||||||
|
# 2. The cc65 compiler must be properly setup.
|
||||||
|
|
||||||
|
ifndef CC65_TARGET
|
||||||
|
CC65_TARGET:=apple2enh
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC=cl65
|
||||||
|
CFLAGS=-O -t $(CC65_TARGET) -DTRACE
|
||||||
|
# The -S $6000 makes the start address $6000 so that both hi-res
|
||||||
|
# pages are available.
|
||||||
|
LDFLAGS=-t $(CC65_TARGET) -u __EXEHDR__ --start-addr 0x6000
|
||||||
|
PGM=online
|
||||||
|
DISK_VOL=$(PGM)
|
||||||
|
DISK=$(DISK_VOL).dsk
|
||||||
|
BASIC_AUX_TYPE=0x0801
|
||||||
|
READ_TIME_LOAD_ADDR=0x0260
|
||||||
|
AC=java -jar AppleCommander-ac-1.4.0.jar
|
||||||
|
SYS_LOAD_ADDR=0x2000
|
||||||
|
BIN_LOAD_ADDR=0x0803
|
||||||
|
|
||||||
|
########################################
|
||||||
|
|
||||||
|
all: $(DISK)
|
||||||
|
|
||||||
|
$(DISK): $(PGM)
|
||||||
|
$(RM) $(DISK)
|
||||||
|
$(AC) -pro140 $(DISK) $(DISK_VOL)
|
||||||
|
$(AC) -as $(DISK) $(PGM) BIN < $(PGM)
|
||||||
|
|
||||||
|
$(PGM): $(PGM).o
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
$(PGM).o: $(PGM).c
|
||||||
|
$(CC) $(CFLAGS) $(PGM).c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) *.o $(PGM) $(DISK)
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* COPY - COPIES FILES *
|
||||||
|
* *
|
||||||
|
* AUTHOR: BILL CHATFIELD *
|
||||||
|
* LICENSE: GPL2 *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
org $2000
|
||||||
|
dsk copy
|
||||||
|
typ $ff ;System type
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* CONSTANTS *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
IN equ $0200
|
||||||
|
RDKEY equ $FD0C ;Reads 1 character
|
||||||
|
GETLN equ $fd6a
|
||||||
|
GETLN1 equ $fd6f ;Get line, no prompt
|
||||||
|
CROUT equ $FD8E ;Output carriage return
|
||||||
|
COUT equ $FDED ;Output a character
|
||||||
|
PRBYTE equ $FDDA ;Print error message
|
||||||
|
BELL equ $FF3A ;Subroutine to beep
|
||||||
|
PRODOS_MLI equ $bf00 ;Address for MLI subroutine entry point
|
||||||
|
SET_FILE_INFO equ $c3 ;Code for system call
|
||||||
|
GET_FILE_INFO equ $c4 ;Code for system call
|
||||||
|
ON_LINE equ $c5 ;Id for ON_LINE MLI system call
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* puts *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
puts mac
|
||||||
|
tya ;Preserve y
|
||||||
|
pha
|
||||||
|
ldy #0 ;Prepare loop index
|
||||||
|
]nextchar lda ]1,y ;Load a character
|
||||||
|
cmp #0 ;Check for end of string
|
||||||
|
beq finish
|
||||||
|
jsr COUT
|
||||||
|
iny
|
||||||
|
jmp ]nextchar
|
||||||
|
finish pla ;Restore y
|
||||||
|
tay
|
||||||
|
<<<
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* movb - Move byte *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
movb mac
|
||||||
|
lda ]2
|
||||||
|
sta ]1
|
||||||
|
<<<
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* mova - Move addrs *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
mova mac
|
||||||
|
lda src
|
||||||
|
sta dest
|
||||||
|
lda src+1
|
||||||
|
sta dest+1
|
||||||
|
<<<
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* Main *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
main
|
||||||
|
|
||||||
|
; Read in source file name and store it in srcFile
|
||||||
|
|
||||||
|
getSource puts srcPrompt
|
||||||
|
jsr GETLN1
|
||||||
|
cpx #64
|
||||||
|
bpl getSource
|
||||||
|
|
||||||
|
stx srcFileLength
|
||||||
|
ldx #0
|
||||||
|
srcChar lda IN,x
|
||||||
|
sta srcFileChars,x
|
||||||
|
inx
|
||||||
|
cpx srcFileLength
|
||||||
|
bmi srcChar
|
||||||
|
|
||||||
|
; Set fiParamCount parameter
|
||||||
|
|
||||||
|
lda #$a
|
||||||
|
sta fiParamCount
|
||||||
|
|
||||||
|
; Set fiPathName parameter
|
||||||
|
|
||||||
|
lda #<srcFile
|
||||||
|
sta fiPathName
|
||||||
|
lda #>srcFile
|
||||||
|
sta fiPathName+1
|
||||||
|
|
||||||
|
jsr PRODOS_MLI ;Call MLI subroutine
|
||||||
|
db GET_FILE_INFO ;Identify the system call
|
||||||
|
da fileInfo ;Address of system call args
|
||||||
|
beq cont1 ;Returns 0 on success
|
||||||
|
jsr handleError
|
||||||
|
cont1
|
||||||
|
|
||||||
|
; Read in destination file name and store it in dstFile
|
||||||
|
|
||||||
|
getDest puts dstPrompt
|
||||||
|
jsr GETLN1
|
||||||
|
cpx #64
|
||||||
|
bpl getDest
|
||||||
|
|
||||||
|
stx dstFileLength
|
||||||
|
ldx #0
|
||||||
|
dstChar lda IN,x
|
||||||
|
sta dstFileChars,x
|
||||||
|
inx
|
||||||
|
cpx dstFileLength
|
||||||
|
bmi dstChar
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* Data *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
srcPrompt asc "File to copy: ",00
|
||||||
|
srcFile
|
||||||
|
srcFileLength db 0 ;Length byte
|
||||||
|
srcFileChars ds 64 ;Characters of srcFile
|
||||||
|
|
||||||
|
dstFile
|
||||||
|
dstFileLength db 0 ;Length byte
|
||||||
|
dstFileChars ds 64 ;Characters of dstFile
|
||||||
|
|
||||||
|
onlineVols ds 256 ;Space for 16 disk vol records
|
||||||
|
|
||||||
|
onlineArgs
|
||||||
|
olParamCount db 2 ;Parameter count
|
||||||
|
olUnitNumber db 0 ;Unit number, 0=all
|
||||||
|
olBufferAddr da onlineVols ;Address of output buffer
|
||||||
|
|
||||||
|
fileInfo
|
||||||
|
fiParamCount db 0
|
||||||
|
fiPathName da 0
|
||||||
|
fiAccess db 0
|
||||||
|
fiFileType db 0
|
||||||
|
fiAuxType dw 0
|
||||||
|
fiStorageType db 0
|
||||||
|
fiBlocksUsed dw 0
|
||||||
|
fiModDate dw 0
|
||||||
|
fiModTime dw 0
|
||||||
|
fiCreateDate dw 0
|
||||||
|
fiCreateTime dw 0
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
|
||||||
|
ENOERR equ $00
|
||||||
|
EBADCALLNUM equ $01
|
||||||
|
EBADPARMCNT equ $04
|
||||||
|
EINTRTBLFULL equ $25
|
||||||
|
EIO equ $27
|
||||||
|
ENODEV equ $28
|
||||||
|
EROFS equ $b2
|
||||||
|
EDISKSWITCHED equ $2e
|
||||||
|
EINVALIDPATH equ $40
|
||||||
|
EMAXFILES equ $42
|
||||||
|
EINVALIDREF equ $43
|
||||||
|
EDIRNOTFOUND equ $44
|
||||||
|
EVOLNOTFOUND equ $45
|
||||||
|
ENOENT equ $46
|
||||||
|
EDUPFILENAME equ $47
|
||||||
|
EVOLFULL equ $48
|
||||||
|
EVOLDIRFULL equ $49
|
||||||
|
EFILEFORMAT equ $4a
|
||||||
|
ESTRGTYPE equ $4b
|
||||||
|
EEOF equ $4c
|
||||||
|
EOUTOFRANGE equ $4d
|
||||||
|
EFILELOCKED equ $4e
|
||||||
|
EFILEISOPEN equ $50
|
||||||
|
EDAMAGEDDIR equ $51
|
||||||
|
ENOTPRODOS equ $52
|
||||||
|
EBADPARAM equ $53
|
||||||
|
EVCBTBLFULL equ $55
|
||||||
|
EBADADDR equ $56
|
||||||
|
EDUPVOL equ $57
|
||||||
|
EDAMAGEDFILE equ $5a
|
||||||
|
|
||||||
|
handleError
|
||||||
|
sta errorCode
|
||||||
|
ldx #0
|
||||||
|
ldy #0
|
||||||
|
nextCode
|
||||||
|
lda errorCodes,x
|
||||||
|
cmp errorCode
|
||||||
|
beq foundCode
|
||||||
|
inx
|
||||||
|
iny
|
||||||
|
iny
|
||||||
|
cpy errorCodeCount
|
||||||
|
bmi nextCode
|
||||||
|
unknownCode
|
||||||
|
puts errorLabel
|
||||||
|
lda errorCode
|
||||||
|
jsr PRBYTE
|
||||||
|
jsr CROUT
|
||||||
|
rts
|
||||||
|
foundCode
|
||||||
|
lda errorMessages,y
|
||||||
|
sta errorMessage
|
||||||
|
iny
|
||||||
|
lda errorMessage,y
|
||||||
|
sta errorMessage+1
|
||||||
|
puts (errorMessage)
|
||||||
|
rts
|
||||||
|
|
||||||
|
errorCode db 0
|
||||||
|
errorMessage da 0
|
||||||
|
errorLabel asc "Error ",00
|
||||||
|
|
||||||
|
EMNOERR ASC "No error",00 ;$00
|
||||||
|
EMBADCALLNUM ASC "Bad system call number",00 ;$01
|
||||||
|
EMBADPARMCNT ASC "Bad system call parameter count",00 ;$04
|
||||||
|
EMINTRTBLFULL ASC "Interrupt table full",00 ;$25
|
||||||
|
EMIO ASC "I/O error",00 ;$27
|
||||||
|
EMNODEV ASC "No device connected",00 ;$28
|
||||||
|
EMROFS ASC "Disk write protected",00 ;$b2
|
||||||
|
EMDISKSWITCHED ASC "Disk switched",00 ;$2e
|
||||||
|
EMINVALIDPATH ASC "Invalid pathname",00 ;$40
|
||||||
|
EMMAXFILES ASC "Maximum number of files open",00 ;$42
|
||||||
|
EMINVALIDREF ASC "Invalid reference number",00 ;$43
|
||||||
|
EMDIRNOTFOUND ASC "Directory not found",00 ;$44
|
||||||
|
EMVOLNOTFOUND ASC "Volume not found",00 ;$45
|
||||||
|
EMNOENT ASC "File not found",00 ;$46
|
||||||
|
EMDUPFILENAME ASC "Duplicate filename",00 ;$47
|
||||||
|
EMVOLFULL ASC "Volume full",00 ;$48
|
||||||
|
EMVOLDIRFULL ASC "Volume directory full",00 ;$49
|
||||||
|
EMFILEFORMAT ASC "Incompatible file format",00 ;$4a
|
||||||
|
EMSTRGTYPE ASC "Unsupported storage_type",00 ;$4b
|
||||||
|
EMEOF ASC "End of file encountered",00 ;$4c
|
||||||
|
EMOUTOFRANGE ASC "Position out of range",00 ;$4d
|
||||||
|
EMFILELOCKED ASC "File access error or file locked",00 ;$4e
|
||||||
|
EMFILEISOPEN ASC "File is open",00 ;$50
|
||||||
|
EMDAMAGEDDIR ASC "Directory structure damaged",00 ;$51
|
||||||
|
EMNOTPRODOS ASC "Not a ProDOS volume",00 ;$52
|
||||||
|
EMBADPARAM ASC "Invalid system call parameter",00 ;$53
|
||||||
|
EMVCBTBLFULL ASC "Volume Control Block table full",00 ;$55
|
||||||
|
EMBADADDR ASC "Bad buffer address",00 ;$56
|
||||||
|
EMDUPVOL ASC "Duplicate volume",00 ;$57
|
||||||
|
EMDAMAGEDFILE ASC "File structure damaged",00 ;$5a
|
||||||
|
|
||||||
|
errorCodes
|
||||||
|
DB ENOERR
|
||||||
|
DB EBADCALLNUM
|
||||||
|
db EBADPARMCNT
|
||||||
|
db EINTRTBLFULL
|
||||||
|
db EIO
|
||||||
|
db ENODEV
|
||||||
|
db EROFS
|
||||||
|
db EDISKSWITCHED
|
||||||
|
db EINVALIDPATH
|
||||||
|
db EMAXFILES
|
||||||
|
db EINVALIDREF
|
||||||
|
db EDIRNOTFOUND
|
||||||
|
db EVOLNOTFOUND
|
||||||
|
db ENOENT
|
||||||
|
db EDUPFILENAME
|
||||||
|
db EVOLFULL
|
||||||
|
db EVOLDIRFULL
|
||||||
|
db EFILEFORMAT
|
||||||
|
db ESTRGTYPE
|
||||||
|
db EEOF
|
||||||
|
db EOUTOFRANGE
|
||||||
|
db EFILELOCKED
|
||||||
|
db EFILEISOPEN
|
||||||
|
db EDAMAGEDDIR
|
||||||
|
db ENOTPRODOS
|
||||||
|
db EBADPARAM
|
||||||
|
db EVCBTBLFULL
|
||||||
|
db EBADADDR
|
||||||
|
db EDUPVOL
|
||||||
|
db EDAMAGEDFILE
|
||||||
|
errorCodeCount
|
||||||
|
db errorCodeCount - errorCodes
|
||||||
|
|
||||||
|
errorMessages
|
||||||
|
DA EMNOERR
|
||||||
|
DA EMBADCALLNUM
|
||||||
|
da EMBADPARMCNT
|
||||||
|
da EMINTRTBLFULL
|
||||||
|
da EMIO
|
||||||
|
da EMNODEV
|
||||||
|
da EMROFS
|
||||||
|
da EMDISKSWITCHED
|
||||||
|
da EMINVALIDPATH
|
||||||
|
da EMMAXFILES
|
||||||
|
da EMINVALIDREF
|
||||||
|
da EMDIRNOTFOUND
|
||||||
|
da EMVOLNOTFOUND
|
||||||
|
da EMNOENT
|
||||||
|
da EMDUPFILENAME
|
||||||
|
da EMVOLFULL
|
||||||
|
da EMVOLDIRFULL
|
||||||
|
da EMFILEFORMAT
|
||||||
|
da EMSTRGTYPE
|
||||||
|
da EMEOF
|
||||||
|
da EMOUTOFRANGE
|
||||||
|
da EMFILELOCKED
|
||||||
|
da EMFILEISOPEN
|
||||||
|
da EMDAMAGEDDIR
|
||||||
|
da EMNOTPRODOS
|
||||||
|
da EMBADPARAM
|
||||||
|
da EMVCBTBLFULL
|
||||||
|
da EMBADADDR
|
||||||
|
da EMDUPVOL
|
||||||
|
da EMDAMAGEDFILE
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Builds copy command
|
||||||
|
|
||||||
|
# Requirements:
|
||||||
|
# 1. Gmake must be used.
|
||||||
|
# 2. The cc65 compiler must be properly setup.
|
||||||
|
|
||||||
|
ifndef CC65_TARGET
|
||||||
|
CC65_TARGET:=apple2enh
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC=cl65
|
||||||
|
CFLAGS=-O -t $(CC65_TARGET) -DTRACE
|
||||||
|
LDFLAGS=-t $(CC65_TARGET)
|
||||||
|
PGM=copy
|
||||||
|
DISK_VOL=$(PGM)
|
||||||
|
DISK=$(DISK_VOL).dsk
|
||||||
|
AC=java -jar AppleCommander-ac-1.4.0.jar
|
||||||
|
SYS_LOAD_ADDR=0x2000
|
||||||
|
BIN_LOAD_ADDR=0x0803
|
||||||
|
BASIC_AUX_TYPE=0x0801
|
||||||
|
READ_TIME_LOAD_ADDR=0x0260
|
||||||
|
MKDISK=$(AC) -pro140 $(DISK) $(DISK_VOL)
|
||||||
|
OBJS=copy.o online.o prodos.o prodos-util.o
|
||||||
|
SRCS=copy.c online.c prodos-util.c
|
||||||
|
|
||||||
|
########################################
|
||||||
|
|
||||||
|
all: $(DISK)
|
||||||
|
|
||||||
|
$(DISK): $(PGM)
|
||||||
|
$(RM) $(DISK)
|
||||||
|
$(AC) -pro140 $(DISK) $(DISK_VOL)
|
||||||
|
$(AC) -as $(DISK) $(PGM) BIN < $(PGM)
|
||||||
|
|
||||||
|
$(PGM): $(OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
copy.o: copy.c prodos.h
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
online.o: online.c prodos.h
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
prodos-util.o: prodos-util.c prodos.h
|
||||||
|
$(CC) -c $(CFLAGS) $<
|
||||||
|
|
||||||
|
prodos.o: prodos.s prodos.h
|
||||||
|
ca65 -t $(CC65_TARGET) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJS) $(PGM) $(DISK)
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* COPY - COPIES FILES *
|
||||||
|
* *
|
||||||
|
* AUTHOR: BILL CHATFIELD *
|
||||||
|
* LICENSE: GPL2 *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* CONSTANTS *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
RDKEY EQU $FD0C ;READS 1 CHAR
|
||||||
|
CROUT EQU $FD8E ;SUB TO OUTPUT CARRIAGE RETURN
|
||||||
|
COUT EQU $FDED ;SUB TO OUTPUT A CHARACTER
|
||||||
|
PRBYTE EQU $FDDA ;SUB TO PRINT ERROR MESSAGE
|
||||||
|
BELL EQU $FF3A ;SUBROUTINE TO BEEP
|
||||||
|
PRODOS_MLI = $bf00 ;Address for MLI subroutine entry point
|
||||||
|
SET_FILE_INFO = $c3 ;Code for system call
|
||||||
|
GET_FILE_INFO = $c4 ;Code for system call
|
||||||
|
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
|
||||||
|
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* puts *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
.macro puts s
|
||||||
|
.local nextchar
|
||||||
|
.local finish
|
||||||
|
tya ;Preserve y
|
||||||
|
pha
|
||||||
|
ldy #0 ;Prepare loop index
|
||||||
|
nextchar: lda s,y ;Load a character
|
||||||
|
cmp #0 ;Check for end of string
|
||||||
|
beq finish
|
||||||
|
jsr cout
|
||||||
|
iny
|
||||||
|
jmp nextchar
|
||||||
|
finish: pla ;Restore y
|
||||||
|
tay
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
.macro movb dest,src
|
||||||
|
lda src
|
||||||
|
sta dest
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
.macro mova dest,src
|
||||||
|
lda src
|
||||||
|
sta dest
|
||||||
|
lda src+1
|
||||||
|
sta dest+1
|
||||||
|
.endmacro
|
||||||
|
|
||||||
|
.proc handleError
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
********************************
|
||||||
|
* *
|
||||||
|
* Main *
|
||||||
|
* *
|
||||||
|
********************************
|
||||||
|
|
||||||
|
main:
|
||||||
|
movb fileInfo+FileInfo::paramCount,$a
|
||||||
|
mova fileInfo+FileInfo::pathName,srcFile
|
||||||
|
|
||||||
|
jsr PRODOS_MLI ;Call MLI subroutine
|
||||||
|
.byte GET_FILE_INFO ;Identify the system call
|
||||||
|
.addr fileInfo ;Address of system call args
|
||||||
|
beq cont1 ;Returns 0 on success
|
||||||
|
jsr handleError
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; BSS is Block Started by Symbol for zero-initialized read/write data
|
||||||
|
; Constructed by loader and zeroed out based on required size
|
||||||
|
.bss
|
||||||
|
|
||||||
|
onlineVols: .res 256 ;SPACE FOR 16 DISK VOL RECORDS
|
||||||
|
srcFile .byte ;Length byte
|
||||||
|
.res 64 ;Characters of srcFile
|
||||||
|
|
||||||
|
|
||||||
|
; DATA contains initialized read/write data - encoded into binary
|
||||||
|
.data
|
||||||
|
|
||||||
|
onlineArgs: .byte 2 ;PARAMETER COUNT
|
||||||
|
.byte 0 ;UNIT NUMBER, 0=ALL
|
||||||
|
.addr _onlineVols ;ADDRESS OF OUTPUT BUFFER
|
||||||
|
|
||||||
|
.struct FileInfo
|
||||||
|
paramCount .byte
|
||||||
|
pathName .addr
|
||||||
|
access .byte
|
||||||
|
fileType .byte
|
||||||
|
auxType .word
|
||||||
|
storageType .byte
|
||||||
|
blocksUsed .word
|
||||||
|
modDate .word
|
||||||
|
modTime .word
|
||||||
|
createDate .word
|
||||||
|
createTime .word
|
||||||
|
.endstruct
|
||||||
|
|
||||||
|
fileInfo: .tag FileInfo
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
#include <stdio.h> /* FILENAME_MAX */
|
||||||
|
#include <string.h> /* strerror */
|
||||||
|
#include <errno.h> /* errno */
|
||||||
|
#include "prodos.h" /* prodosGetFileInfo, prodosSetFileInfo */
|
||||||
|
|
||||||
|
void copy(const char *srcName, const char *dstName);
|
||||||
|
|
||||||
|
#define BUFFER_SIZE 2048
|
||||||
|
|
||||||
|
char src[FILENAME_MAX];
|
||||||
|
char dst[FILENAME_MAX];
|
||||||
|
char buf[BUFFER_SIZE];
|
||||||
|
|
||||||
|
struct ProdosFileInfo fileAttributes;
|
||||||
|
struct ProdosPathName srcPathName;
|
||||||
|
struct ProdosPathName dstPathName;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
printf("Source file:");
|
||||||
|
fgets(src, FILENAME_MAX, stdin);
|
||||||
|
printf("Destination file:");
|
||||||
|
fgets(dst, FILENAME_MAX, stdin);
|
||||||
|
|
||||||
|
copy(src, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy(const char *srcName, const char *dstName)
|
||||||
|
{
|
||||||
|
FILE *src, *dst;
|
||||||
|
size_t readCount;
|
||||||
|
int errorCode;
|
||||||
|
|
||||||
|
fileAttributes.paramCount = PRODOS_GET_FILE_INFO_PARAM_COUNT;
|
||||||
|
fileAttributes.pathName = prodosAssignPathName(&srcPathName, srcName);
|
||||||
|
errorCode = prodosGetFileInfo(&fileAttributes);
|
||||||
|
if (errorCode > 0) {
|
||||||
|
fprintf(stderr, "%s: %s\n", srcName, prodosGetMessage(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = fopen(srcName, "r");
|
||||||
|
dst = fopen(dstName, "w");
|
||||||
|
|
||||||
|
while ((readCount = fread(buf,1,BUFFER_SIZE,src)) == BUFFER_SIZE) {
|
||||||
|
fwrite(buf,1,BUFFER_SIZE,dst);
|
||||||
|
}
|
||||||
|
if (feof(src) && readCount > 0) {
|
||||||
|
fwrite(buf,1,readCount,dst);
|
||||||
|
} else if (ferror(src)) {
|
||||||
|
fprintf(stderr, "%s: %s\n", srcName, strerror(errno));
|
||||||
|
}
|
||||||
|
fclose(dst);
|
||||||
|
fclose(src);
|
||||||
|
|
||||||
|
fileAttributes.paramCount = PRODOS_SET_FILE_INFO_PARAM_COUNT;
|
||||||
|
fileAttributes.pathName = prodosAssignPathName(&dstPathName, dstName);
|
||||||
|
errorCode = prodosSetFileInfo(&fileAttributes);
|
||||||
|
if (errorCode > 0) {
|
||||||
|
fprintf(stderr, "%s: %s\n", dstName, prodosGetMessage(errorCode));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
.export _onlineSysCall
|
||||||
|
.export _onlineVols
|
||||||
|
|
||||||
|
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
|
||||||
|
PRODOS_MLI = $bf00 ;ADDRESS OF MLI ENTRY POINT
|
||||||
|
|
||||||
|
.proc _onlineSysCall
|
||||||
|
|
||||||
|
jsr PRODOS_MLI ;CALL MACHINE LANGUAGE INTERFACE
|
||||||
|
.byte ON_LINE ;SPECIFY THE ON_LINE SYSTEM CALL
|
||||||
|
.addr onlineArgs ;SPECIFY ADDRESS OF ARGUMENTS
|
||||||
|
|
||||||
|
; sta retCode ;Store the return code
|
||||||
|
; lda #<retCode ;PUT LOW BYTE INTO ACCUMULATOR
|
||||||
|
; ldx #>retCode ;PUT HIGH BYTE INTO X
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; BSS is Block Started by Symbol for zero-initialized read/write data
|
||||||
|
; Constructed by loader and zeroed out based on required size
|
||||||
|
.bss
|
||||||
|
|
||||||
|
retCode: .byte 0
|
||||||
|
_onlineVols:.res 256 ;SPACE FOR 16 DISK VOL RECORDS
|
||||||
|
|
||||||
|
; DATA contains initialized read/write data - encoded into binary
|
||||||
|
.data
|
||||||
|
|
||||||
|
onlineArgs: .byte 2 ;PARAMETER COUNT
|
||||||
|
.byte 0 ;UNIT NUMBER, 0=ALL
|
||||||
|
.addr _onlineVols ;ADDRESS OF OUTPUT BUFFER
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define PRODOS_MLI 0xbf00
|
||||||
|
#define ON_LINE_SYSTEM_CALL 0xc5
|
||||||
|
#define PRODOS_FILE_NAME_MAX_LEN 15
|
||||||
|
typedef char ProdosFileName[PRODOS_FILE_NAME_MAX_LEN + 1];
|
||||||
|
typedef ProdosFileName ProdosFileNameArray16[16];
|
||||||
|
typedef struct OnlineSystemCallArguments {
|
||||||
|
uint8_t argumentCount;
|
||||||
|
uint8_t unitNumber;
|
||||||
|
ProdosFileNameArray16 *volumesOutputBuffer;
|
||||||
|
} OnlineSystemCallArguments;
|
||||||
|
|
||||||
|
static ProdosFileNameArray16 volumes;
|
||||||
|
static OnlineSystemCallArguments arguments;
|
||||||
|
|
||||||
|
ProdosFileNameArray16 *online(uint8_t *errorCode)
|
||||||
|
{
|
||||||
|
arguments.argumentCount = 2;
|
||||||
|
arguments.unitNumber = 0; // All units
|
||||||
|
arguments.volumesOutputBuffer = &volumes;
|
||||||
|
|
||||||
|
__asm__("jsr %w", PRODOS_MLI);
|
||||||
|
__asm__("db %b", ON_LINE_SYSTEM_CALL);
|
||||||
|
__asm__("da %v", &arguments);
|
||||||
|
__asm__("bne %g", errorHandler);
|
||||||
|
|
||||||
|
return &volumes;
|
||||||
|
|
||||||
|
errorHandler:
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <device.h>
|
||||||
|
#include "prodos.h"
|
||||||
|
|
||||||
|
extern uint8_t onlineVols[];
|
||||||
|
extern uint8_t onlineSysCall();
|
||||||
|
|
||||||
|
enum ProdosErrorCode online(struct ProdosVolumes *vols)
|
||||||
|
{
|
||||||
|
uint8_t byte;
|
||||||
|
uint8_t i;
|
||||||
|
uint8_t nameLength;
|
||||||
|
enum ProdosErrorCode errorCode;
|
||||||
|
struct ProdosVolume *volume;
|
||||||
|
|
||||||
|
errorCode = onlineSysCall();
|
||||||
|
if (errorCode != PRODOS_ERR_NO_ERROR) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < PRODOS_MAX_VOLUME_COUNT; ++i) {
|
||||||
|
byte = onlineVols[i*16];
|
||||||
|
if (byte == 0) {
|
||||||
|
vols->count = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
volume = &(vols->volumes[i]);
|
||||||
|
volume->drive = ((byte & 0x80) >> 7) + 1;
|
||||||
|
volume->slot = (byte & 0x70) >> 4;
|
||||||
|
nameLength = byte & 0x0f;
|
||||||
|
strncpy(volume->name, &(onlineVols[i*16+1]), nameLength);
|
||||||
|
volume->name[nameLength] = '\0';
|
||||||
|
}
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ProdosVolume volume;
|
||||||
|
struct ProdosVolumes volumes;
|
||||||
|
enum ProdosErrorCode errorCode;
|
||||||
|
|
||||||
|
void printOnline(void)
|
||||||
|
{
|
||||||
|
uint8_t i, dev;
|
||||||
|
char volName[FILENAME_MAX];
|
||||||
|
|
||||||
|
errorCode = online(&volumes);
|
||||||
|
if (errorCode > 0) {
|
||||||
|
printf("Error: %d\n", errorCode);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < volumes.count; ++i) {
|
||||||
|
volume = volumes.volumes[i];
|
||||||
|
if (strlen(volume.name)>0) {
|
||||||
|
printf("S%d,D%d /%s\n", volume.slot, volume.drive, volume.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = getfirstdevice();
|
||||||
|
while (dev != INVALID_DEVICE) {
|
||||||
|
getdevicedir(dev, volName, sizeof(volName));
|
||||||
|
printf("device=%d volume=%s\n", dev, volName);
|
||||||
|
dev = getnextdevice(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include <string.h> /* size_t */
|
||||||
|
#include "prodos.h"
|
||||||
|
|
||||||
|
struct ProdosPathName *
|
||||||
|
prodosAssignPathName(struct ProdosPathName *dest, const char *src)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
char c;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
name = dest->name;
|
||||||
|
for (i = 0; i < PRODOS_MAX_PATHNAME_LENGTH && (c = src[i]) != '\0'; ++i) {
|
||||||
|
name[i] = c;
|
||||||
|
}
|
||||||
|
dest->length = i;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
prodosGetMessage(enum ProdosErrorCode code)
|
||||||
|
{
|
||||||
|
char *message;
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
|
case PRODOS_ERR_NO_ERROR:
|
||||||
|
message = "No error";
|
||||||
|
break;
|
||||||
|
case PRODOS_ERR_BAD_SYS_CALL_NUM:
|
||||||
|
message = "Bad system call number";
|
||||||
|
break;
|
||||||
|
case PRODOS_ERR_BAD_PARAM_COUNT:
|
||||||
|
message = "Bad parameter count";
|
||||||
|
break;
|
||||||
|
case PRODOS_ERR_INTR_VECT_TBL_FULL:
|
||||||
|
message = "Interrupt vector table full";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
message = "Unknown error";
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
#ifndef PRODOS
|
||||||
|
#define PRODOS
|
||||||
|
|
||||||
|
#include <stdint.h> /* uint8_t, uint16_t */
|
||||||
|
|
||||||
|
#define PRODOS_GET_FILE_INFO_PARAM_COUNT 0x0a
|
||||||
|
#define PRODOS_SET_FILE_INFO_PARAM_COUNT 0x07
|
||||||
|
#define PRODOS_MAX_PATHNAME_LENGTH 64
|
||||||
|
|
||||||
|
#define PRODOS_MAX_VOLUME_NAME_LEN 15
|
||||||
|
#define PRODOS_MAX_VOLUME_COUNT 16
|
||||||
|
|
||||||
|
enum ProdosErrorCode {
|
||||||
|
PRODOS_ERR_NO_ERROR = 0,
|
||||||
|
PRODOS_ERR_BAD_SYS_CALL_NUM = 1,
|
||||||
|
PRODOS_ERR_BAD_PARAM_COUNT = 4,
|
||||||
|
PRODOS_ERR_INTR_VECT_TBL_FULL = 25,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProdosVolume {
|
||||||
|
uint8_t drive;
|
||||||
|
uint8_t slot;
|
||||||
|
uint8_t nameLength;
|
||||||
|
char name[PRODOS_MAX_VOLUME_NAME_LEN+1];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProdosVolumes {
|
||||||
|
uint8_t count;
|
||||||
|
struct ProdosVolume volumes[PRODOS_MAX_VOLUME_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProdosPathName
|
||||||
|
{
|
||||||
|
uint8_t length;
|
||||||
|
char name[PRODOS_MAX_PATHNAME_LENGTH];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProdosFileInfo
|
||||||
|
{
|
||||||
|
uint8_t paramCount;
|
||||||
|
struct ProdosPathName *pathName;
|
||||||
|
uint8_t access;
|
||||||
|
uint8_t fileType;
|
||||||
|
uint16_t auxType;
|
||||||
|
uint8_t storageType;
|
||||||
|
uint16_t blocksUsed;
|
||||||
|
uint16_t modDate;
|
||||||
|
uint16_t modTime;
|
||||||
|
uint16_t createDate;
|
||||||
|
uint16_t createTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int __fastcall__
|
||||||
|
prodosGetFileInfo(struct ProdosFileInfo *fileInfo);
|
||||||
|
|
||||||
|
extern int __fastcall__
|
||||||
|
prodosSetFileInfo(struct ProdosFileInfo *fileInfo);
|
||||||
|
|
||||||
|
extern struct ProdosPathName *
|
||||||
|
prodosAssignPathName(struct ProdosPathName *dest, const char *src);
|
||||||
|
|
||||||
|
extern char *
|
||||||
|
prodosGetMessage(enum ProdosErrorCode code);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
.export _prodosGetFileInfo
|
||||||
|
.export _prodosSetFileInfo
|
||||||
|
.export _onlineSysCall
|
||||||
|
.export _onlineVols
|
||||||
|
|
||||||
|
|
||||||
|
PRODOS_MLI = $bf00 ;Address for MLI subroutine entry point
|
||||||
|
SET_FILE_INFO = $c3 ;Code for system call
|
||||||
|
GET_FILE_INFO = $c4 ;Code for system call
|
||||||
|
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
|
||||||
|
|
||||||
|
.proc _prodosGetFileInfo
|
||||||
|
sta fileInfo ;Store low-byte of C address param
|
||||||
|
stx fileInfo+1 ;Store high-byte of C address param
|
||||||
|
jsr PRODOS_MLI ;Call MLI subroutine
|
||||||
|
.byte GET_FILE_INFO ;Identify the system call
|
||||||
|
fileInfo: .addr $0000 ;Address of system call args
|
||||||
|
ldx #0 ;Zero high byte of int return value
|
||||||
|
rts ;Accum has error code, low byte of int
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
.proc _prodosSetFileInfo
|
||||||
|
sta fileInfo ;Store low-byte of C address param
|
||||||
|
stx fileInfo+1 ;Store high-byte of C address param
|
||||||
|
jsr PRODOS_MLI ;Call MLI subroutine
|
||||||
|
.byte SET_FILE_INFO ;Identify the system call
|
||||||
|
fileInfo: .addr $0000 ;Address of system call args
|
||||||
|
ldx #0 ;Zero high byte of int return value
|
||||||
|
rts ;Accumulator has error code
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
.proc _onlineSysCall
|
||||||
|
|
||||||
|
jsr PRODOS_MLI ;CALL MACHINE LANGUAGE INTERFACE
|
||||||
|
.byte ON_LINE ;SPECIFY THE ON_LINE SYSTEM CALL
|
||||||
|
.addr onlineArgs ;SPECIFY ADDRESS OF ARGUMENTS
|
||||||
|
|
||||||
|
; sta retCode ;Store the return code
|
||||||
|
; lda #<retCode ;PUT LOW BYTE INTO ACCUMULATOR
|
||||||
|
; ldx #>retCode ;PUT HIGH BYTE INTO X
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; BSS is Block Started by Symbol for zero-initialized read/write data
|
||||||
|
; Constructed by loader and zeroed out based on required size
|
||||||
|
.bss
|
||||||
|
|
||||||
|
retCode: .byte 0
|
||||||
|
_onlineVols:.res 256 ;SPACE FOR 16 DISK VOL RECORDS
|
||||||
|
|
||||||
|
; DATA contains initialized read/write data - encoded into binary
|
||||||
|
.data
|
||||||
|
|
||||||
|
onlineArgs: .byte 2 ;PARAMETER COUNT
|
||||||
|
.byte 0 ;UNIT NUMBER, 0=ALL
|
||||||
|
.addr _onlineVols ;ADDRESS OF OUTPUT BUFFER
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
.export _mliGetFileInfo
|
||||||
|
.export _mliSetFileInfo
|
||||||
|
|
||||||
|
SET_FILE_INFO = $c3 ;Code for system call
|
||||||
|
GET_FILE_INFO = $c4 ;Code for system call
|
||||||
|
PRODOS_MLI = $bf00 ;Address for MLI subroutine entry point
|
||||||
|
|
||||||
|
.proc _mliGetFileInfo
|
||||||
|
sta fileInfo ;Store low-byte of C address param
|
||||||
|
stx fileInfo+1 ;Store high-byte of C address param
|
||||||
|
jsr PRODOS_MLI ;Call MLI subroutine
|
||||||
|
.byte GET_FILE_INFO ;Identify the system call
|
||||||
|
fileInfo: .addr $0000 ;Address of system call args
|
||||||
|
ldx #0 ;Zero high byte of int return value
|
||||||
|
rts ;Accum has error code, low byte of int
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
.proc _mliSetFileInfo
|
||||||
|
sta fileInfo ;Store low-byte of C address param
|
||||||
|
stx fileInfo+1 ;Store high-byte of C address param
|
||||||
|
jsr PRODOS_MLI ;Call MLI subroutine
|
||||||
|
.byte SET_FILE_INFO ;Identify the system call
|
||||||
|
fileInfo: .addr $0000 ;Address of system call args
|
||||||
|
ldx #0 ;Zero high byte of int return value
|
||||||
|
rts ;Accumulator has error code
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; BSS is Block Started by Symbol for zero-initialized read/write data
|
||||||
|
; Constructed by loader and zeroed out based on required size
|
||||||
|
|
||||||
|
.bss
|
||||||
|
|
||||||
|
; DATA segment contains initialized read/write data - encoded into binary
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
54
online.c
54
online.c
|
@ -1,33 +1,55 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define PRODOS_MLI 0xbf00
|
#define PRODOS_MLI 0xbf00
|
||||||
#define ON_LINE_SYSTEM_CALL 0xc5
|
#define ON_LINE (uint8_t) 0xc5
|
||||||
#define PRODOS_FILE_NAME_MAX_LEN 15
|
#define PRODOS_NAME_CAPACITY 16
|
||||||
typedef char ProdosFileName[PRODOS_FILE_NAME_MAX_LEN + 1];
|
|
||||||
typedef ProdosFileName ProdosFileNameArray16[16];
|
struct OnlineArguments {
|
||||||
typedef struct OnlineSystemCallArguments {
|
|
||||||
uint8_t argumentCount;
|
uint8_t argumentCount;
|
||||||
uint8_t unitNumber;
|
uint8_t unitNumber;
|
||||||
ProdosFileNameArray16 *volumesOutputBuffer;
|
char **volumes;
|
||||||
} OnlineSystemCallArguments;
|
};
|
||||||
|
|
||||||
static ProdosFileNameArray16 volumes;
|
struct OnlineArguments arguments;
|
||||||
static OnlineSystemCallArguments arguments;
|
char volumes[16][PRODOS_NAME_CAPACITY];
|
||||||
|
uint8_t argumentsAddrLowByte;
|
||||||
|
uint8_t argumentsAddrHighByte;
|
||||||
|
|
||||||
ProdosFileNameArray16 *online(uint8_t *errorCode)
|
void online(void)
|
||||||
{
|
{
|
||||||
arguments.argumentCount = 2;
|
arguments.argumentCount = 2;
|
||||||
arguments.unitNumber = 0; // All units
|
arguments.unitNumber = 0; // All units
|
||||||
arguments.volumesOutputBuffer = &volumes;
|
arguments.volumes = volumes;
|
||||||
|
|
||||||
|
__asm__("lda #%b", ON_LINE);
|
||||||
|
__asm__("sta %g", l1);
|
||||||
|
|
||||||
|
argumentsAddrLowByte = (uint8_t) &arguments;
|
||||||
|
argumentsAddrLowByte = (uint8_t) &arguments >> 4;
|
||||||
|
|
||||||
|
__asm__("lda %v", argumentsAddrLowByte);
|
||||||
|
__asm__("sta %g", l2);
|
||||||
|
|
||||||
|
__asm__("lda %v", argumentsAddrHighByte);
|
||||||
|
__asm__("sta %g", l3);
|
||||||
|
|
||||||
__asm__("jsr %w", PRODOS_MLI);
|
__asm__("jsr %w", PRODOS_MLI);
|
||||||
__asm__("db %b", ON_LINE_SYSTEM_CALL);
|
l1:
|
||||||
__asm__("da %v", &arguments);
|
__asm__("nop");
|
||||||
|
l2:
|
||||||
|
__asm__("nop");
|
||||||
|
l3:
|
||||||
|
__asm__("nop");
|
||||||
__asm__("bne %g", errorHandler);
|
__asm__("bne %g", errorHandler);
|
||||||
|
|
||||||
return &volumes;
|
|
||||||
|
|
||||||
errorHandler:
|
errorHandler:
|
||||||
return errorCode;
|
fprintf(stderr, "Online system call failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
online();
|
||||||
|
puts(volumes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
26
online.s
26
online.s
|
@ -1,26 +0,0 @@
|
||||||
.export _onLineSysCall
|
|
||||||
.export _onLineVols
|
|
||||||
|
|
||||||
ON_LINE = $c5 ;ID FOR ON_LINE MLI SYSTEM CALL
|
|
||||||
PRODOS_MLI = $bf00 ;ADDRESS OF MLI ENTRY POINT
|
|
||||||
|
|
||||||
.proc _onLineSysCall
|
|
||||||
|
|
||||||
jsr PRODOS_MLI ;CALL MACHINE LANGUAGE INTERFACE
|
|
||||||
.byte ON_LINE ;SPECIFY THE ON_LINE SYSTEM CALL
|
|
||||||
.addr onlineArgs ;SPECIFY ADDRESS OF ARGUMENTS
|
|
||||||
|
|
||||||
sta retCode ;Store the return code
|
|
||||||
lda #<retCode ;PUT LOW BYTE INTO ACCUMULATOR
|
|
||||||
ldx #>retCode ;PUT HIGH BYTE INTO X
|
|
||||||
rts
|
|
||||||
.endproc
|
|
||||||
|
|
||||||
.bss
|
|
||||||
retCode: .byte 0
|
|
||||||
_onLineVols:.res 256 ;SPACE FOR 16 DISK VOL RECORDS
|
|
||||||
|
|
||||||
onlineArgs: .byte 2 ;PARAMETER COUNT
|
|
||||||
.byte 0 ;UNIT NUMBER, 0=ALL
|
|
||||||
.addr _onLineVols ;ADDRESS OF OUTPUT BUFFER
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
.export _online
|
||||||
|
.export _olerr
|
||||||
|
|
||||||
|
.include "mli.inc"
|
||||||
|
|
||||||
|
.bss
|
||||||
|
|
||||||
|
_olerr: .byte $00
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
_open:
|
||||||
|
lda #ON_LINE_CALL
|
||||||
|
ldx #ON_LINE_COUNT
|
||||||
|
jsr callmli
|
||||||
|
bcc done
|
||||||
|
|
||||||
|
sta _olerr
|
||||||
|
|
||||||
|
done:
|
||||||
|
rts
|
Loading…
Reference in New Issue