Merge branch 'master' into feature/plus4-tgi-driver
This commit is contained in:
@@ -21,21 +21,29 @@ TARGETS = apple2 \
|
||||
atarixl \
|
||||
atari2600 \
|
||||
atari5200 \
|
||||
atari7800 \
|
||||
atmos \
|
||||
creativision \
|
||||
$(CBMS) \
|
||||
$(GEOS) \
|
||||
gamate \
|
||||
kim1 \
|
||||
lynx \
|
||||
nes \
|
||||
none \
|
||||
osic1p \
|
||||
pce \
|
||||
rp6502 \
|
||||
sim6502 \
|
||||
sim65c02 \
|
||||
supervision \
|
||||
sym1 \
|
||||
telestrat
|
||||
|
||||
TARGETTEST = none \
|
||||
sim6502 \
|
||||
sim65c02
|
||||
|
||||
DRVTYPES = emd \
|
||||
joy \
|
||||
mou \
|
||||
@@ -50,7 +58,7 @@ OUTPUTDIRS := lib
|
||||
$(subst ../,,$(wildcard ../target/*/drv/*)) \
|
||||
$(subst ../,,$(wildcard ../target/*/util))
|
||||
|
||||
.PHONY: all mostlyclean clean install zip lib $(TARGETS)
|
||||
.PHONY: all mostlyclean clean install zip lib libtest $(TARGETS)
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
@@ -78,6 +86,8 @@ datadir = $(PREFIX)/share/cc65
|
||||
|
||||
all lib: $(TARGETS)
|
||||
|
||||
libtest: $(TARGETTEST)
|
||||
|
||||
mostlyclean:
|
||||
$(call RMDIR,../libwrk)
|
||||
|
||||
@@ -94,7 +104,6 @@ INSTALL = install
|
||||
|
||||
define INSTALL_recipe
|
||||
|
||||
$(if $(PREFIX),,$(error variable "PREFIX" must be set))
|
||||
$(INSTALL) -d $(DESTDIR)$(datadir)/$(dir)
|
||||
$(INSTALL) -m0644 ../$(dir)/*.* $(DESTDIR)$(datadir)/$(dir)
|
||||
|
||||
@@ -114,13 +123,17 @@ endef # ZIP_recipe
|
||||
zip:
|
||||
$(foreach dir,$(OUTPUTDIRS),$(ZIP_recipe))
|
||||
|
||||
$(TARGETS):
|
||||
$(TARGETS): | ../lib
|
||||
@$(MAKE) --no-print-directory $@
|
||||
|
||||
# ../lib must be created globally before doing lib targets in parallel
|
||||
../lib:
|
||||
@$(call MKDIR,$@)
|
||||
|
||||
else # TARGET
|
||||
|
||||
CA65FLAGS =
|
||||
CC65FLAGS = -Or -W error
|
||||
CA65FLAGS = -g
|
||||
CC65FLAGS = -g -Or -W error
|
||||
|
||||
EXTZP = cbm510 \
|
||||
cbm610 \
|
||||
@@ -133,8 +146,7 @@ MKINC = $(GEOS) \
|
||||
|
||||
TARGETUTIL = apple2 \
|
||||
apple2enh \
|
||||
atari \
|
||||
geos-apple
|
||||
atari
|
||||
|
||||
GEOSDIRS = common \
|
||||
conio \
|
||||
@@ -286,10 +298,12 @@ $(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../libwrk/$(TARGET) ../lib
|
||||
@echo $(TARGET) - $(<F)
|
||||
@$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:../lib/%.o=../libwrk/$(TARGET)/%.d) -o $@ $<
|
||||
|
||||
$(EXTRA_OBJS): | ../lib
|
||||
|
||||
../lib/$(TARGET).lib: $(OBJS) | ../lib
|
||||
$(AR65) a $@ $?
|
||||
|
||||
../libwrk/$(TARGET) ../lib ../target/$(TARGET)/util:
|
||||
../libwrk/$(TARGET) ../target/$(TARGET)/util:
|
||||
@$(call MKDIR,$@)
|
||||
|
||||
$(TARGET): $(EXTRA_OBJS) ../lib/$(TARGET).lib
|
||||
|
||||
380
libsrc/NameClashes.md
Normal file
380
libsrc/NameClashes.md
Normal file
@@ -0,0 +1,380 @@
|
||||
List of cc65 library name clashes
|
||||
=================================
|
||||
|
||||
The following is a list of identifiers that might need
|
||||
to be fixed, sorted by directory and identifier:
|
||||
|
||||
# common
|
||||
|
||||
## \_\_argc
|
||||
|
||||
* libsrc/runtime/callmain.s
|
||||
* libsrc/cbm610/mainargs.s
|
||||
* libsrc/cx16/mainargs.s
|
||||
* libsrc/plus4/mainargs.s
|
||||
* libsrc/lynx/mainargs.s
|
||||
* libsrc/c16/mainargs.s
|
||||
* libsrc/geos-common/system/mainargs.s
|
||||
* libsrc/sim6502/mainargs.s
|
||||
* libsrc/c128/mainargs.s
|
||||
* libsrc/vic20/mainargs.s
|
||||
* libsrc/nes/mainargs.s
|
||||
* libsrc/atari/getargs.s
|
||||
* libsrc/apple2/mainargs.s
|
||||
* libsrc/cbm510/mainargs.s
|
||||
* libsrc/telestrat/mainargs.s
|
||||
* libsrc/c64/mainargs.s
|
||||
* libsrc/pet/mainargs.s
|
||||
* libsrc/atmos/mainargs.s
|
||||
|
||||
## \_\_argv
|
||||
|
||||
* libsrc/runtime/callmain.s
|
||||
* libsrc/cbm610/mainargs.s
|
||||
* libsrc/cx16/mainargs.s
|
||||
* libsrc/plus4/mainargs.s
|
||||
* libsrc/lynx/mainargs.s
|
||||
* libsrc/c16/mainargs.s
|
||||
* libsrc/geos-common/system/mainargs.s
|
||||
* libsrc/sim6502/mainargs.s
|
||||
* libsrc/c128/mainargs.s
|
||||
* libsrc/vic20/mainargs.s
|
||||
* libsrc/nes/mainargs.s
|
||||
* libsrc/atari/getargs.s
|
||||
* libsrc/apple2/mainargs.s
|
||||
* libsrc/cbm510/mainargs.s
|
||||
* libsrc/telestrat/mainargs.s
|
||||
* libsrc/c64/mainargs.s
|
||||
* libsrc/pet/mainargs.s
|
||||
* libsrc/atmos/mainargs.s
|
||||
|
||||
## \_\_cos
|
||||
|
||||
* libsrc/common/sincos.s
|
||||
|
||||
## \_\_ctypeidx
|
||||
|
||||
* libsrc/common/ctype.s
|
||||
* libsrc/common/ctypemask.s
|
||||
* libsrc/geos-common/system/ctype.s
|
||||
* libsrc/atari/ctype.s
|
||||
* libsrc/cbm/ctype.s
|
||||
* libsrc/atmos/ctype.s
|
||||
* asminc/ctype\_common.inc
|
||||
|
||||
## \_\_cwd
|
||||
|
||||
* libsrc/common/getcwd.s
|
||||
* libsrc/common/_cwd.s
|
||||
* libsrc/atari/initcwd.s
|
||||
* libsrc/apple2/initcwd.s
|
||||
* libsrc/apple2/initcwd.s
|
||||
* libsrc/telestrat/initcwd.s
|
||||
* libsrc/cbm/initcwd.s
|
||||
|
||||
## \_\_cwd\_buf\_size
|
||||
|
||||
* libsrc/common/_cwd.s
|
||||
|
||||
## \_\_envcount
|
||||
|
||||
* libsrc/common/searchenv.s
|
||||
* libsrc/common/_environ.s
|
||||
* libsrc/common/putenv.s
|
||||
* libsrc/common/getenv.s
|
||||
|
||||
## \_\_environ
|
||||
|
||||
* libsrc/common/searchenv.s
|
||||
* libsrc/common/_environ.s
|
||||
* libsrc/common/putenv.s
|
||||
* libsrc/common/getenv.s
|
||||
|
||||
## \_\_envsize
|
||||
|
||||
* libsrc/common/_environ.s
|
||||
* libsrc/common/putenv.s
|
||||
|
||||
## \_\_fdesc
|
||||
|
||||
* libsrc/common/_fdesc.s
|
||||
* libsrc/common/fopen.s
|
||||
|
||||
## \_\_filetab
|
||||
|
||||
* libsrc/common/_fdesc.s
|
||||
* libsrc/common/_file.s
|
||||
* asminc/_file.inc
|
||||
|
||||
## \_\_fopen
|
||||
|
||||
* libsrc/common/fopen.s
|
||||
* libsrc/common/_fopen.s
|
||||
|
||||
## \_\_printf
|
||||
|
||||
* libsrc/common/vsnprintf.s
|
||||
* libsrc/common/_printf.s
|
||||
* libsrc/common/vfprintf.s
|
||||
* libsrc/conio/vcprintf.s
|
||||
* libsrc/pce/_printf.s
|
||||
|
||||
## \_\_scanf
|
||||
|
||||
* libsrc/common/_scanf.inc
|
||||
* libsrc/common/vsscanf.s
|
||||
* libsrc/conio/vcscanf.s
|
||||
|
||||
## \_\_sin
|
||||
|
||||
* libsrc/common/sincos.s
|
||||
|
||||
## \_\_sys
|
||||
|
||||
* libsrc/common/_sys.s
|
||||
* libsrc/apple2/_sys.s
|
||||
|
||||
## \_\_sys\_oserrlist
|
||||
|
||||
* libsrc/common/stroserr.s
|
||||
* libsrc/geos-common/system/oserrlist.s
|
||||
* libsrc/atari/oserrlist.s
|
||||
* libsrc/apple2/oserrlist.s
|
||||
* libsrc/cbm/oserrlist.s
|
||||
* libsrc/atmos/oserrlist.s
|
||||
|
||||
## \_\_syschdir
|
||||
|
||||
* libsrc/common/chdir.s
|
||||
* libsrc/atari/syschdir.s
|
||||
* libsrc/apple2/syschdir.s
|
||||
* libsrc/telestrat/syschdir.s
|
||||
* libsrc/cbm/syschdir.s
|
||||
|
||||
## \_\_sysmkdir
|
||||
|
||||
* libsrc/common/mkdir.s
|
||||
* libsrc/atari/sysmkdir.s
|
||||
* libsrc/apple2/sysmkdir.s
|
||||
* libsrc/telestrat/sysmkdir.s
|
||||
|
||||
## \_\_sysremove
|
||||
|
||||
* libsrc/common/remove.s
|
||||
* libsrc/geos-common/file/sysremove.s
|
||||
* libsrc/atari/sysremove.s
|
||||
* libsrc/atari/sysrmdir.s
|
||||
* libsrc/apple2/sysremove.s
|
||||
* libsrc/apple2/sysrmdir.s
|
||||
* libsrc/telestrat/sysremove.s
|
||||
* libsrc/cbm/sysremove.s
|
||||
|
||||
## \_\_sysrename
|
||||
|
||||
* libsrc/common/rename.s
|
||||
* libsrc/geos-common/file/sysrename.s
|
||||
* libsrc/atari/sysrename.s
|
||||
* libsrc/apple2/sysrename.s
|
||||
* libsrc/cbm/sysrename.s
|
||||
|
||||
## \_\_sysrmdir
|
||||
|
||||
* libsrc/common/rmdir.s
|
||||
* libsrc/atari/sysrmdir.s
|
||||
* libsrc/apple2/sysrmdir.s
|
||||
|
||||
\_\_sysuname
|
||||
|
||||
* libsrc/common/uname.s
|
||||
* libsrc/cbm610/sysuname.s
|
||||
* libsrc/cx16/sysuname.s
|
||||
* libsrc/plus4/sysuname.s
|
||||
* libsrc/lynx/sysuname.s
|
||||
* libsrc/c16/sysuname.s
|
||||
* libsrc/geos-common/system/sysuname.s
|
||||
* libsrc/c128/sysuname.s
|
||||
* libsrc/creativision/sysuname.s
|
||||
* libsrc/vic20/sysuname.s
|
||||
* libsrc/nes/sysuname.s
|
||||
* libsrc/atari/sysuname.s
|
||||
* libsrc/apple2/sysuname.s
|
||||
* libsrc/cbm510/sysuname.s
|
||||
* libsrc/telestrat/sysuname.s
|
||||
* libsrc/c64/sysuname.s
|
||||
* libsrc/pet/sysuname.s
|
||||
* libsrc/atari5200/sysuname.s
|
||||
* libsrc/atmos/sysuname.s
|
||||
|
||||
# apple2
|
||||
|
||||
## \_\_auxtype
|
||||
|
||||
* libsrc/apple2/open.s
|
||||
|
||||
## \_\_datetime
|
||||
|
||||
* libsrc/apple2/open.s
|
||||
|
||||
## \_\_dos\_type
|
||||
|
||||
* libsrc/apple2/dioopen.s
|
||||
* libsrc/apple2/curdevice.s
|
||||
* libsrc/apple2/mainargs.s
|
||||
* libsrc/apple2/settime.s
|
||||
* libsrc/apple2/getdevice.s
|
||||
* libsrc/apple2/dosdetect.s
|
||||
* libsrc/apple2/irq.s
|
||||
* libsrc/apple2/open.s
|
||||
* libsrc/apple2/mli.s
|
||||
* libsrc/apple2/getres.s
|
||||
|
||||
## \_\_filetype
|
||||
|
||||
* libsrc/apple2/open.s
|
||||
* libsrc/apple2/exehdr.s
|
||||
|
||||
## atari
|
||||
|
||||
## \_\_defdev
|
||||
|
||||
* libsrc/atari/posixdirent.s
|
||||
* libsrc/atari/ucase\_fn.s
|
||||
* libsrc/atari/getdefdev.s
|
||||
|
||||
## \_\_dos\_type
|
||||
|
||||
* libsrc/atari/getargs.s
|
||||
* libsrc/atari/exec.s
|
||||
* libsrc/atari/settime.s
|
||||
* libsrc/atari/syschdir.s
|
||||
* libsrc/atari/dosdetect.s
|
||||
* libsrc/atari/is\_cmdline\_dos.s
|
||||
* libsrc/atari/sysrmdir.s
|
||||
* libsrc/atari/gettime.s
|
||||
* libsrc/atari/lseek.s
|
||||
* libsrc/atari/getres.s
|
||||
* libsrc/atari/getdefdev.s
|
||||
|
||||
## \_\_do\_oserror
|
||||
|
||||
* libsrc/atari/posixdirent.s
|
||||
* libsrc/atari/do\_oserr.s
|
||||
* libsrc/atari/serref.s
|
||||
* libsrc/atari/read.s
|
||||
* libsrc/atari/write.s
|
||||
* libsrc/atari/close.s
|
||||
|
||||
## \_\_getcolor
|
||||
|
||||
* libsrc/atari/setcolor.s
|
||||
|
||||
## \_\_getdefdev
|
||||
|
||||
* libsrc/atari/getdefdev.s
|
||||
|
||||
## \_\_graphics
|
||||
|
||||
* libsrc/atari/graphics.s
|
||||
|
||||
## \_\_inviocb
|
||||
|
||||
* libsrc/atari/serref.s
|
||||
* libsrc/atari/ser/atrrdev.s
|
||||
* libsrc/atari/inviocb.s
|
||||
* libsrc/atari/read.s
|
||||
* libsrc/atari/write.s
|
||||
* libsrc/atari/lseek.s
|
||||
* libsrc/atari/close.s
|
||||
|
||||
## \_\_is\_cmdline\_dos
|
||||
|
||||
* libsrc/atari/is\_cmdline\_dos.s
|
||||
* libsrc/atari/doesclrscr.s
|
||||
|
||||
## \_\_rest\_vecs
|
||||
|
||||
* libsrc/atari/savevec.s
|
||||
|
||||
## \_\_rwsetup
|
||||
|
||||
* libsrc/atari/rwcommon.s
|
||||
* libsrc/atari/read.s
|
||||
* libsrc/atari/write.s
|
||||
|
||||
## \_\_save\_vecs
|
||||
|
||||
* libsrc/atari/savevec.s
|
||||
|
||||
## \_\_scroll
|
||||
|
||||
* libsrc/atari/scroll.s
|
||||
|
||||
## \_\_setcolor
|
||||
|
||||
* libsrc/atari/setcolor.s
|
||||
|
||||
## \_\_setcolor\_low
|
||||
|
||||
* libsrc/atari/setcolor.s
|
||||
|
||||
## \_\_sio\_call
|
||||
|
||||
* libsrc/atari/diowritev.s
|
||||
* libsrc/atari/diopncls.s
|
||||
* libsrc/atari/siocall.s
|
||||
* libsrc/atari/diowrite.s
|
||||
* libsrc/atari/dioread.s
|
||||
|
||||
# cbm
|
||||
|
||||
## \_\_cbm\_filetype
|
||||
|
||||
* libsrc/cbm/cbm\_filetype.s
|
||||
* asminc/cbm\_filetype.in
|
||||
|
||||
## \_\_dirread
|
||||
|
||||
* libsrc/cbm/dir.inc
|
||||
* libsrc/cbm/dir.s
|
||||
|
||||
## \_\_dirread1
|
||||
|
||||
* libsrc/cbm/dir.inc
|
||||
* libsrc/cbm/dir.s
|
||||
|
||||
# lynx
|
||||
|
||||
## \_\_iodat
|
||||
|
||||
* libsrc/lynx/lynx-cart.s
|
||||
* libsrc/lynx/bootldr.s
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
## \_\_iodir
|
||||
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
## \_\_sprsys
|
||||
|
||||
* libsrc/lynx/tgi/lynx-160-102-16.s
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
## \_\_viddma
|
||||
|
||||
* libsrc/lynx/tgi/lynx-160-102-16.s
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
# pce
|
||||
|
||||
## \_\_nmi
|
||||
|
||||
* libsrc/pce/irq.s
|
||||
* libsrc/pce/crt0.s
|
||||
28
libsrc/apple2/allow_lowercase.s
Normal file
28
libsrc/apple2/allow_lowercase.s
Normal file
@@ -0,0 +1,28 @@
|
||||
;
|
||||
; Oliver Schmidt, 2024-08-06
|
||||
;
|
||||
; unsigned char __fastcall__ allow_lowercase (unsigned char onoff);
|
||||
;
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
|
||||
.export _allow_lowercase
|
||||
.import return0
|
||||
.import uppercasemask, return1
|
||||
|
||||
_allow_lowercase:
|
||||
tax
|
||||
lda values,x
|
||||
ldx uppercasemask
|
||||
sta uppercasemask
|
||||
cpx #$FF
|
||||
beq :+
|
||||
jmp return0
|
||||
: jmp return1
|
||||
|
||||
.rodata
|
||||
|
||||
values: .byte $DF ; Force uppercase
|
||||
.byte $FF ; Keep lowercase
|
||||
|
||||
.endif
|
||||
20
libsrc/apple2/beep.s
Normal file
20
libsrc/apple2/beep.s
Normal file
@@ -0,0 +1,20 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; void beep(void)
|
||||
;
|
||||
|
||||
.export _beep
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
_beep:
|
||||
; Switch in ROM and call BELL
|
||||
bit $C082
|
||||
jsr $FF3A ; BELL
|
||||
|
||||
; Switch in LC bank 2 for R/O and return
|
||||
bit $C080
|
||||
rts
|
||||
73
libsrc/apple2/boxchars.s
Normal file
73
libsrc/apple2/boxchars.s
Normal file
@@ -0,0 +1,73 @@
|
||||
;
|
||||
; Colin Leroy-Mira and Oliver Schmidt, 26.05.2025
|
||||
;
|
||||
; Initialize box-drawing characters according to
|
||||
; MouseText availability
|
||||
;
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
|
||||
.constructor initboxchars
|
||||
.import machinetype
|
||||
|
||||
.export _CH_HLINE
|
||||
.export _CH_VLINE
|
||||
.export _CH_ULCORNER
|
||||
.export _CH_URCORNER
|
||||
.export _CH_LLCORNER
|
||||
.export _CH_LRCORNER
|
||||
.export _CH_TTEE
|
||||
.export _CH_BTEE
|
||||
.export _CH_LTEE
|
||||
.export _CH_RTEE
|
||||
.export _CH_CROSS
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
initboxchars:
|
||||
bit machinetype ; IIe enhanced or newer?
|
||||
bvs out
|
||||
|
||||
ldx #NUM_BOXCHARS ; No mousetext, patch characters
|
||||
: lda std_boxchars,x
|
||||
sta boxchars,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
out: rts
|
||||
|
||||
; Replacement chars for when MouseText is not available
|
||||
std_boxchars: .byte '!'
|
||||
.byte '-'
|
||||
.byte '+'
|
||||
.byte '+'
|
||||
.byte '+'
|
||||
.byte '+'
|
||||
|
||||
.data
|
||||
|
||||
; MouseText-based box characters
|
||||
boxchars:
|
||||
VERT: .byte $DF
|
||||
HORIZ: .byte $5F
|
||||
ULCORNER: .byte $5F
|
||||
URCORNER: .byte $20
|
||||
LLCORNER: .byte $D4
|
||||
LRCORNER: .byte $DF
|
||||
|
||||
NUM_BOXCHARS = *-boxchars
|
||||
|
||||
; exported symbols, referencing our 6 bytes
|
||||
_CH_HLINE = HORIZ
|
||||
_CH_VLINE = VERT
|
||||
_CH_ULCORNER = ULCORNER
|
||||
_CH_URCORNER = URCORNER
|
||||
_CH_LLCORNER = LLCORNER
|
||||
_CH_LRCORNER = LRCORNER
|
||||
_CH_TTEE = ULCORNER
|
||||
_CH_BTEE = LLCORNER
|
||||
_CH_LTEE = LLCORNER
|
||||
_CH_RTEE = LRCORNER
|
||||
_CH_CROSS = LLCORNER
|
||||
|
||||
.endif ; not __APPLE2ENH__
|
||||
75
libsrc/apple2/callmain.s
Normal file
75
libsrc/apple2/callmain.s
Normal file
@@ -0,0 +1,75 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-03-07
|
||||
;
|
||||
; Push arguments and call main()
|
||||
;
|
||||
|
||||
|
||||
.export callmain, _exit
|
||||
.export __argc, __argv
|
||||
|
||||
.import _main, pushax, done, donelib
|
||||
.import zpsave, rvsave, reset
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Setup the stack for main(), then jump to it
|
||||
|
||||
callmain:
|
||||
lda __argc
|
||||
ldx __argc+1
|
||||
jsr pushax ; Push argc
|
||||
|
||||
lda __argv
|
||||
ldx __argv+1
|
||||
jsr pushax ; Push argv
|
||||
|
||||
ldy #4 ; Argument size
|
||||
jsr _main
|
||||
|
||||
; Avoid a re-entrance of donelib. This is also the exit() entry.
|
||||
_exit: ldx #<exit
|
||||
lda #>exit
|
||||
jsr reset ; Setup RESET vector
|
||||
|
||||
; Switch in LC bank 2 for R/O in case it was switched out by a RESET.
|
||||
bit $C080
|
||||
|
||||
; Call the module destructors.
|
||||
jsr donelib
|
||||
|
||||
; Switch in ROM.
|
||||
bit $C082
|
||||
|
||||
; Restore the original RESET vector.
|
||||
exit: ldx #$02
|
||||
: lda rvsave,x
|
||||
sta SOFTEV,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; Copy back the zero-page stuff.
|
||||
ldx #zpspace-1
|
||||
: lda zpsave,x
|
||||
sta sp,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; ProDOS TechRefMan, chapter 5.2.1:
|
||||
; "System programs should set the stack pointer to $FF at the
|
||||
; warm-start entry point."
|
||||
ldx #$FF
|
||||
txs ; Re-init stack pointer
|
||||
|
||||
; We're done
|
||||
jmp done
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.data
|
||||
__argc: .word 0
|
||||
__argv: .addr 0
|
||||
@@ -7,8 +7,13 @@
|
||||
;
|
||||
|
||||
.export _cgetc
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.endif
|
||||
.import cursor, putchardirect
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
_cgetc:
|
||||
@@ -17,12 +22,15 @@ _cgetc:
|
||||
beq :+
|
||||
|
||||
; Show caret.
|
||||
.ifdef __APPLE2ENH__
|
||||
lda #$7F | $80 ; Checkerboard, screen code
|
||||
.else
|
||||
.ifndef __APPLE2ENH__
|
||||
lda #' ' | $40 ; Blank, flashing
|
||||
bit machinetype
|
||||
bpl put_caret
|
||||
.endif
|
||||
jsr putchardirect ; Returns old character in X
|
||||
|
||||
lda #$7F | $80 ; Checkerboard, screen code
|
||||
put_caret:
|
||||
jsr putchardirect ; Saves old character in tmp3
|
||||
|
||||
; Wait for keyboard strobe.
|
||||
: inc RNDL ; Increment random counter low
|
||||
@@ -37,16 +45,20 @@ _cgetc:
|
||||
|
||||
; Restore old character.
|
||||
pha
|
||||
txa
|
||||
lda tmp3
|
||||
jsr putchardirect
|
||||
pla
|
||||
|
||||
; At this time, the high bit of the key pressed is set.
|
||||
: bit KBDSTRB ; Clear keyboard strobe
|
||||
.ifdef __APPLE2ENH__
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype ; Apple //e or more recent?
|
||||
bpl clear
|
||||
.endif
|
||||
bit BUTN0 ; Check if OpenApple is down
|
||||
bmi done
|
||||
.endif
|
||||
and #$7F ; If not down, then clear high bit
|
||||
|
||||
clear: and #$7F ; If not down, then clear high bit
|
||||
done: ldx #>$0000
|
||||
rts
|
||||
|
||||
@@ -33,8 +33,8 @@ zerofd: lda #$00
|
||||
; Return success
|
||||
lda #$00
|
||||
|
||||
; Set __oserror
|
||||
oserr: jmp __mappederrno
|
||||
; Set ___oserror
|
||||
oserr: jmp ___mappederrno
|
||||
|
||||
; Set __errno
|
||||
errno: jmp __directerrno
|
||||
errno: jmp ___directerrno
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* closedir.c */
|
||||
/* */
|
||||
/* Close a directory */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include "dir.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
int __fastcall__ closedir (DIR* dir)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* Cleanup directory file */
|
||||
result = close (dir->fd);
|
||||
|
||||
/* Cleanup DIR */
|
||||
free (dir);
|
||||
|
||||
return result;
|
||||
}
|
||||
35
libsrc/apple2/closedir.s
Normal file
35
libsrc/apple2/closedir.s
Normal file
@@ -0,0 +1,35 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; int __fastcall__ closedir (DIR *dir)
|
||||
;
|
||||
|
||||
.export _closedir, closedir_ptr1
|
||||
|
||||
.import _close
|
||||
.import _free
|
||||
.import pushax, popax, pushptr1, swapstk
|
||||
|
||||
.importzp ptr1
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "dir.inc"
|
||||
.include "errno.inc"
|
||||
.include "fcntl.inc"
|
||||
.include "zeropage.inc"
|
||||
|
||||
_closedir:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
closedir_ptr1:
|
||||
; Close fd
|
||||
jsr pushptr1 ; Backup ptr1
|
||||
ldy #$00
|
||||
lda (ptr1),y ; Get fd
|
||||
ldx #$00
|
||||
jsr _close
|
||||
jsr swapstk ; Store result, pop ptr1
|
||||
|
||||
; Free dir structure
|
||||
jsr _free
|
||||
jmp popax ; Return result
|
||||
@@ -13,4 +13,4 @@ _textcolor := return1
|
||||
|
||||
_bgcolor := return0
|
||||
|
||||
_bordercolor := return0
|
||||
_bordercolor := return0
|
||||
|
||||
42
libsrc/apple2/cpeekc.s
Normal file
42
libsrc/apple2/cpeekc.s
Normal file
@@ -0,0 +1,42 @@
|
||||
;
|
||||
; 2020-07-12, Oliver Schmidt
|
||||
;
|
||||
; char cpeekc (void);
|
||||
;
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.endif
|
||||
|
||||
.export _cpeekc
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
_cpeekc:
|
||||
ldy CH
|
||||
|
||||
sec ; Assume main memory
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl peek
|
||||
.endif
|
||||
|
||||
bit RD80VID ; In 80 column mode?
|
||||
bpl peek ; No, just go ahead
|
||||
lda OURCH
|
||||
lsr ; Div by 2
|
||||
tay
|
||||
bcs peek ; Odd cols are in main memory
|
||||
php
|
||||
sei ; No valid MSLOT et al. in aux memory
|
||||
bit HISCR ; Assume SET80COL
|
||||
|
||||
peek: lda (BASL),Y ; Get character
|
||||
bcs :+ ; In main memory
|
||||
bit LOWSCR
|
||||
plp
|
||||
|
||||
: eor #$80 ; Invert high bit
|
||||
ldx #>$0000
|
||||
rts
|
||||
@@ -5,23 +5,33 @@
|
||||
; void __fastcall__ cputc (char c);
|
||||
;
|
||||
|
||||
.ifdef __APPLE2ENH__
|
||||
.constructor initconio
|
||||
.endif
|
||||
.export _cputcxy, _cputc
|
||||
.export cputdirect, newline, putchar, putchardirect
|
||||
.import gotoxy, VTABZ
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.import uppercasemask
|
||||
.endif
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
.macpack cpu
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
.ifdef __APPLE2ENH__
|
||||
initconio:
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bmi :+
|
||||
rts
|
||||
:
|
||||
.endif
|
||||
sta SETALTCHAR ; Switch in alternate charset
|
||||
bit LORES ; Limit SET80COL-HISCR to text
|
||||
rts
|
||||
.endif
|
||||
|
||||
.code
|
||||
|
||||
@@ -33,7 +43,7 @@ _cputcxy:
|
||||
pla ; Restore C and run into _cputc
|
||||
|
||||
_cputc:
|
||||
cmp #$0D ; Test for \r = carrage return
|
||||
cmp #$0D ; Test for \r = carriage return
|
||||
beq left
|
||||
cmp #$0A ; Test for \n = line feed
|
||||
beq newline
|
||||
@@ -41,19 +51,53 @@ _cputc:
|
||||
.ifndef __APPLE2ENH__
|
||||
cmp #$E0 ; Test for lowercase
|
||||
bcc cputdirect
|
||||
and #$DF ; Convert to uppercase
|
||||
and uppercasemask
|
||||
.endif
|
||||
|
||||
cputdirect:
|
||||
jsr putchar
|
||||
inc CH ; Bump to next column
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl :+
|
||||
.endif
|
||||
bit RD80VID ; In 80 column mode?
|
||||
bpl :+
|
||||
inc OURCH ; Bump to next column
|
||||
lda OURCH
|
||||
.ifdef __APPLE2ENH__
|
||||
bra check ; Must leave CH alone
|
||||
.else
|
||||
jmp check
|
||||
.endif
|
||||
|
||||
: inc CH ; Bump to next column
|
||||
lda CH
|
||||
cmp WNDWDTH
|
||||
bcc :+
|
||||
check: cmp WNDWDTH
|
||||
bcc done
|
||||
jsr newline
|
||||
left: lda #$00 ; Goto left edge of screen
|
||||
left:
|
||||
.ifdef __APPLE2ENH__
|
||||
stz CH ; Goto left edge of screen
|
||||
.else
|
||||
lda #$00
|
||||
sta CH
|
||||
: rts
|
||||
.endif
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl done
|
||||
.endif
|
||||
|
||||
bit RD80VID ; In 80 column mode?
|
||||
bpl done
|
||||
.ifdef __APPLE2ENH__
|
||||
stz OURCH ; Goto left edge of screen
|
||||
.else
|
||||
sta OURCH
|
||||
.endif
|
||||
|
||||
done: rts
|
||||
|
||||
newline:
|
||||
inc CV ; Bump to next line
|
||||
@@ -77,22 +121,32 @@ putchar:
|
||||
mask: and INVFLG ; Apply normal, inverse, flash
|
||||
|
||||
putchardirect:
|
||||
pha
|
||||
tax
|
||||
ldy CH
|
||||
.ifdef __APPLE2ENH__
|
||||
|
||||
sec ; Assume main memory
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl put
|
||||
.endif
|
||||
|
||||
bit RD80VID ; In 80 column mode?
|
||||
bpl put ; No, just go ahead
|
||||
tya
|
||||
lda OURCH
|
||||
lsr ; Div by 2
|
||||
tay
|
||||
bcs put ; Odd cols go in main memory
|
||||
php
|
||||
sei ; No valid MSLOT et al. in aux memory
|
||||
bit HISCR ; Assume SET80COL
|
||||
.endif
|
||||
|
||||
put: lda (BASL),Y ; Get current character
|
||||
tax ; Return old character for _cgetc
|
||||
pla
|
||||
sta tmp3 ; Save old character for _cgetc
|
||||
txa
|
||||
sta (BASL),Y
|
||||
.ifdef __APPLE2ENH__
|
||||
bit LOWSCR ; Doesn't hurt in 40 column mode
|
||||
.endif
|
||||
rts
|
||||
|
||||
bcs :+ ; In main memory
|
||||
bit LOWSCR
|
||||
plp
|
||||
: rts
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
; Startup code for cc65 (Apple2 version)
|
||||
;
|
||||
|
||||
.export _exit, done, return
|
||||
.export done, return
|
||||
.export zpsave, rvsave, reset
|
||||
.export __STARTUP__ : absolute = 1 ; Mark as startup
|
||||
|
||||
.import initlib, donelib
|
||||
.import initlib, _exit
|
||||
.import zerobss, callmain
|
||||
.import bltu2
|
||||
.import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated
|
||||
.import __LC_START__, __LC_LAST__ ; Linker generated
|
||||
|
||||
@@ -33,41 +35,7 @@
|
||||
jsr zerobss
|
||||
|
||||
; Push the command-line arguments; and, call main().
|
||||
jsr callmain
|
||||
|
||||
; Avoid a re-entrance of donelib. This is also the exit() entry.
|
||||
_exit: ldx #<exit
|
||||
lda #>exit
|
||||
jsr reset ; Setup RESET vector
|
||||
|
||||
; Switch in ROM, in case it wasn't already switched in by a RESET.
|
||||
bit $C082
|
||||
|
||||
; Call the module destructors.
|
||||
jsr donelib
|
||||
|
||||
; Restore the original RESET vector.
|
||||
exit: ldx #$02
|
||||
: lda rvsave,x
|
||||
sta SOFTEV,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; Copy back the zero-page stuff.
|
||||
ldx #zpspace-1
|
||||
: lda zpsave,x
|
||||
sta sp,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; ProDOS TechRefMan, chapter 5.2.1:
|
||||
; "System programs should set the stack pointer to $FF at the
|
||||
; warm-start entry point."
|
||||
ldx #$FF
|
||||
txs ; Re-init stack pointer
|
||||
|
||||
; We're done
|
||||
jmp done
|
||||
jmp callmain
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
@@ -126,6 +94,7 @@ basic: lda HIMEM
|
||||
; Call the module constructors.
|
||||
jsr initlib
|
||||
|
||||
; Copy the LC segment to its destination
|
||||
; Switch in LC bank 2 for W/O.
|
||||
bit $C081
|
||||
bit $C081
|
||||
@@ -153,7 +122,7 @@ basic: lda HIMEM
|
||||
|
||||
; Call into Applesoft Block Transfer Up -- which handles zero-
|
||||
; sized blocks well -- to move the content of the LC memory area.
|
||||
jsr $D39A ; BLTU2
|
||||
jsr bltu2
|
||||
|
||||
; Switch in LC bank 2 for R/O and return.
|
||||
bit $C080
|
||||
|
||||
@@ -1,161 +0,0 @@
|
||||
;
|
||||
; Stefan Haubenthal with minor changes from Ullrich von Bassewitz, 2003-05-02
|
||||
;
|
||||
; Character specification table.
|
||||
;
|
||||
|
||||
.include "ctype.inc"
|
||||
|
||||
; The tables are readonly, put them into the rodata segment
|
||||
|
||||
.rodata
|
||||
|
||||
; The following 256 byte wide table specifies attributes for the isxxx type
|
||||
; of functions. Doing it by a table means some overhead in space, but it
|
||||
; has major advantages:
|
||||
;
|
||||
; * It is fast. If it were'nt for the slow parameter passing of cc65, one
|
||||
; could even define macros for the isxxx functions (this is usually
|
||||
; done on other platforms).
|
||||
;
|
||||
; * It is highly portable. The only unportable part is the table itself,
|
||||
; all real code goes into the common library.
|
||||
;
|
||||
; * We save some code in the isxxx functions.
|
||||
|
||||
|
||||
__ctype:
|
||||
.repeat 2
|
||||
.byte CT_CTRL ; 0/00 ___ctrl_@___
|
||||
.byte CT_CTRL ; 1/01 ___ctrl_A___
|
||||
.byte CT_CTRL ; 2/02 ___ctrl_B___
|
||||
.byte CT_CTRL ; 3/03 ___ctrl_C___
|
||||
.byte CT_CTRL ; 4/04 ___ctrl_D___
|
||||
.byte CT_CTRL ; 5/05 ___ctrl_E___
|
||||
.byte CT_CTRL ; 6/06 ___ctrl_F___
|
||||
.byte CT_CTRL ; 7/07 ___ctrl_G___
|
||||
.byte CT_CTRL ; 8/08 ___ctrl_H___
|
||||
.byte CT_CTRL | CT_OTHER_WS | CT_SPACE_TAB
|
||||
; 9/09 ___ctrl_I___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 10/0a ___ctrl_J___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 11/0b ___ctrl_K___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 12/0c ___ctrl_L___
|
||||
.byte CT_CTRL | CT_OTHER_WS ; 13/0d ___ctrl_M___
|
||||
.byte CT_CTRL ; 14/0e ___ctrl_N___
|
||||
.byte CT_CTRL ; 15/0f ___ctrl_O___
|
||||
.byte CT_CTRL ; 16/10 ___ctrl_P___
|
||||
.byte CT_CTRL ; 17/11 ___ctrl_Q___
|
||||
.byte CT_CTRL ; 18/12 ___ctrl_R___
|
||||
.byte CT_CTRL ; 19/13 ___ctrl_S___
|
||||
.byte CT_CTRL ; 20/14 ___ctrl_T___
|
||||
.byte CT_CTRL ; 21/15 ___ctrl_U___
|
||||
.byte CT_CTRL ; 22/16 ___ctrl_V___
|
||||
.byte CT_CTRL ; 23/17 ___ctrl_W___
|
||||
.byte CT_CTRL ; 24/18 ___ctrl_X___
|
||||
.byte CT_CTRL ; 25/19 ___ctrl_Y___
|
||||
.byte CT_CTRL ; 26/1a ___ctrl_Z___
|
||||
.byte CT_CTRL ; 27/1b ___ctrl_[___
|
||||
.byte CT_CTRL ; 28/1c ___ctrl_\___
|
||||
.byte CT_CTRL ; 29/1d ___ctrl_]___
|
||||
.byte CT_CTRL ; 30/1e ___ctrl_^___
|
||||
.byte CT_CTRL ; 31/1f ___ctrl_____
|
||||
.byte CT_SPACE | CT_SPACE_TAB ; 32/20 ___SPACE___
|
||||
.byte CT_NONE ; 33/21 _____!_____
|
||||
.byte CT_NONE ; 34/22 _____"_____
|
||||
.byte CT_NONE ; 35/23 _____#_____
|
||||
.byte CT_NONE ; 36/24 _____$_____
|
||||
.byte CT_NONE ; 37/25 _____%_____
|
||||
.byte CT_NONE ; 38/26 _____&_____
|
||||
.byte CT_NONE ; 39/27 _____'_____
|
||||
.byte CT_NONE ; 40/28 _____(_____
|
||||
.byte CT_NONE ; 41/29 _____)_____
|
||||
.byte CT_NONE ; 42/2a _____*_____
|
||||
.byte CT_NONE ; 43/2b _____+_____
|
||||
.byte CT_NONE ; 44/2c _____,_____
|
||||
.byte CT_NONE ; 45/2d _____-_____
|
||||
.byte CT_NONE ; 46/2e _____._____
|
||||
.byte CT_NONE ; 47/2f _____/_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 48/30 _____0_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 49/31 _____1_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 50/32 _____2_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 51/33 _____3_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 52/34 _____4_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 53/35 _____5_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 54/36 _____6_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 55/37 _____7_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 56/38 _____8_____
|
||||
.byte CT_DIGIT | CT_XDIGIT ; 57/39 _____9_____
|
||||
.byte CT_NONE ; 58/3a _____:_____
|
||||
.byte CT_NONE ; 59/3b _____;_____
|
||||
.byte CT_NONE ; 60/3c _____<_____
|
||||
.byte CT_NONE ; 61/3d _____=_____
|
||||
.byte CT_NONE ; 62/3e _____>_____
|
||||
.byte CT_NONE ; 63/3f _____?_____
|
||||
|
||||
.byte CT_NONE ; 64/40 _____@_____
|
||||
.byte CT_UPPER | CT_XDIGIT ; 65/41 _____A_____
|
||||
.byte CT_UPPER | CT_XDIGIT ; 66/42 _____B_____
|
||||
.byte CT_UPPER | CT_XDIGIT ; 67/43 _____C_____
|
||||
.byte CT_UPPER | CT_XDIGIT ; 68/44 _____D_____
|
||||
.byte CT_UPPER | CT_XDIGIT ; 69/45 _____E_____
|
||||
.byte CT_UPPER | CT_XDIGIT ; 70/46 _____F_____
|
||||
.byte CT_UPPER ; 71/47 _____G_____
|
||||
.byte CT_UPPER ; 72/48 _____H_____
|
||||
.byte CT_UPPER ; 73/49 _____I_____
|
||||
.byte CT_UPPER ; 74/4a _____J_____
|
||||
.byte CT_UPPER ; 75/4b _____K_____
|
||||
.byte CT_UPPER ; 76/4c _____L_____
|
||||
.byte CT_UPPER ; 77/4d _____M_____
|
||||
.byte CT_UPPER ; 78/4e _____N_____
|
||||
.byte CT_UPPER ; 79/4f _____O_____
|
||||
.byte CT_UPPER ; 80/50 _____P_____
|
||||
.byte CT_UPPER ; 81/51 _____Q_____
|
||||
.byte CT_UPPER ; 82/52 _____R_____
|
||||
.byte CT_UPPER ; 83/53 _____S_____
|
||||
.byte CT_UPPER ; 84/54 _____T_____
|
||||
.byte CT_UPPER ; 85/55 _____U_____
|
||||
.byte CT_UPPER ; 86/56 _____V_____
|
||||
.byte CT_UPPER ; 87/57 _____W_____
|
||||
.byte CT_UPPER ; 88/58 _____X_____
|
||||
.byte CT_UPPER ; 89/59 _____Y_____
|
||||
.byte CT_UPPER ; 90/5a _____Z_____
|
||||
.byte CT_NONE ; 91/5b _____[_____
|
||||
.byte CT_NONE ; 92/5c _____\_____
|
||||
.byte CT_NONE ; 93/5d _____]_____
|
||||
.byte CT_NONE ; 94/5e _____^_____
|
||||
.byte CT_NONE ; 95/5f _UNDERLINE_
|
||||
.byte CT_NONE ; 96/60 ___grave___
|
||||
.byte CT_LOWER | CT_XDIGIT ; 97/61 _____a_____
|
||||
.byte CT_LOWER | CT_XDIGIT ; 98/62 _____b_____
|
||||
.byte CT_LOWER | CT_XDIGIT ; 99/63 _____c_____
|
||||
.byte CT_LOWER | CT_XDIGIT ; 100/64 _____d_____
|
||||
.byte CT_LOWER | CT_XDIGIT ; 101/65 _____e_____
|
||||
.byte CT_LOWER | CT_XDIGIT ; 102/66 _____f_____
|
||||
.byte CT_LOWER ; 103/67 _____g_____
|
||||
.byte CT_LOWER ; 104/68 _____h_____
|
||||
.byte CT_LOWER ; 105/69 _____i_____
|
||||
.byte CT_LOWER ; 106/6a _____j_____
|
||||
.byte CT_LOWER ; 107/6b _____k_____
|
||||
.byte CT_LOWER ; 108/6c _____l_____
|
||||
.byte CT_LOWER ; 109/6d _____m_____
|
||||
.byte CT_LOWER ; 110/6e _____n_____
|
||||
.byte CT_LOWER ; 111/6f _____o_____
|
||||
.byte CT_LOWER ; 112/70 _____p_____
|
||||
.byte CT_LOWER ; 113/71 _____q_____
|
||||
.byte CT_LOWER ; 114/72 _____r_____
|
||||
.byte CT_LOWER ; 115/73 _____s_____
|
||||
.byte CT_LOWER ; 116/74 _____t_____
|
||||
.byte CT_LOWER ; 117/75 _____u_____
|
||||
.byte CT_LOWER ; 118/76 _____v_____
|
||||
.byte CT_LOWER ; 119/77 _____w_____
|
||||
.byte CT_LOWER ; 120/78 _____x_____
|
||||
.byte CT_LOWER ; 121/79 _____y_____
|
||||
.byte CT_LOWER ; 122/7a _____z_____
|
||||
.byte CT_NONE ; 123/7b _____{_____
|
||||
.byte CT_NONE ; 124/7c _____|_____
|
||||
.byte CT_NONE ; 125/7d _____}_____
|
||||
.byte CT_NONE ; 126/7e _____~_____
|
||||
.byte CT_OTHER_WS ; 127/7f ____DEL____
|
||||
.endrepeat
|
||||
|
||||
|
||||
@@ -23,5 +23,5 @@ _getcurrentdevice:
|
||||
bne :+
|
||||
lda #$FF ; INVALID_DEVICE
|
||||
|
||||
: ldx #$00
|
||||
: ldx #>$0000
|
||||
rts
|
||||
|
||||
56
libsrc/apple2/detect80cols.s
Normal file
56
libsrc/apple2/detect80cols.s
Normal file
@@ -0,0 +1,56 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 27/05/2025
|
||||
;
|
||||
; Verify the presence of a 80 columns card in slot 3,
|
||||
; and publish a flag accordingly.
|
||||
;
|
||||
.export aux80col
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.endif
|
||||
|
||||
.constructor detect80cols
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
.data
|
||||
|
||||
aux80col: .byte 0
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
IdOfsTable: ; Table of bytes positions, used to check four
|
||||
; specific bytes on the slot's firmware to make
|
||||
; sure this is a serial card.
|
||||
.byte $05 ; Pascal 1.0 ID byte
|
||||
.byte $07 ; Pascal 1.0 ID byte
|
||||
.byte $0B ; Pascal 1.1 generic signature byte
|
||||
.byte $0C ; Device signature byte
|
||||
|
||||
IdValTable: ; Table of expected values for the four checked
|
||||
; bytes
|
||||
.byte $38 ; ID Byte 0 (from Pascal 1.0), fixed
|
||||
.byte $18 ; ID Byte 1 (from Pascal 1.0), fixed
|
||||
.byte $01 ; Generic signature for Pascal 1.1, fixed
|
||||
.byte $88 ; Device signature byte (80 columns card)
|
||||
|
||||
IdTableLen = * - IdValTable
|
||||
|
||||
detect80cols:
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype ; Check we're on a //e at least, otherwise we
|
||||
bpl NoDev ; handle no 80cols hardware (like Videx)
|
||||
.endif
|
||||
|
||||
ldx #IdTableLen-1
|
||||
: ldy IdOfsTable,x ; Check Pascal 1.1 Firmware Protocol ID bytes
|
||||
lda IdValTable,x
|
||||
cmp $C300,y
|
||||
bne NoDev
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
dec aux80col ; We have an 80-columns card! Set flag to $FF
|
||||
|
||||
NoDev: rts
|
||||
17
libsrc/apple2/detect_iigs.s
Normal file
17
libsrc/apple2/detect_iigs.s
Normal file
@@ -0,0 +1,17 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; void __fastcall__ detect_iigs(void)
|
||||
;
|
||||
|
||||
.export _detect_iigs
|
||||
.import ostype, return0, return1
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
; Returns 1 if running on IIgs, 0 otherwise
|
||||
_detect_iigs:
|
||||
lda ostype
|
||||
bpl :+
|
||||
jmp return1
|
||||
: jmp return0
|
||||
@@ -45,9 +45,9 @@ _getdevicedir:
|
||||
|
||||
; Handle errors
|
||||
erange: lda #<ERANGE
|
||||
jsr __directerrno
|
||||
jsr ___directerrno
|
||||
bne :+ ; Branch always
|
||||
oserr: jsr __mappederrno
|
||||
oserr: jsr ___mappederrno
|
||||
: lda #$00 ; Return NULL
|
||||
tax
|
||||
rts
|
||||
@@ -73,7 +73,7 @@ oserr: jsr __mappederrno
|
||||
iny
|
||||
lda #$00
|
||||
sta (ptr1),y
|
||||
sta __oserror ; Clear _oserror
|
||||
sta ___oserror ; Clear __oserror
|
||||
|
||||
; Success, return buf
|
||||
lda ptr1
|
||||
|
||||
@@ -30,6 +30,6 @@ diocommon:
|
||||
|
||||
dioepilog:
|
||||
; Return success or error
|
||||
sta __oserror
|
||||
ldx #$00
|
||||
sta ___oserror
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
@@ -24,7 +24,7 @@ _dio_open:
|
||||
lda #$28 ; "No device connected"
|
||||
|
||||
; Return oserror
|
||||
oserr: sta __oserror
|
||||
oserr: sta ___oserror
|
||||
jmp return0
|
||||
|
||||
; Return success
|
||||
@@ -34,5 +34,5 @@ oserr: sta __oserror
|
||||
asl
|
||||
asl
|
||||
ldx #$00
|
||||
stx __oserror
|
||||
stx ___oserror
|
||||
rts
|
||||
|
||||
@@ -16,7 +16,7 @@ _dio_query_sectcount:
|
||||
; Set handle
|
||||
sta mliparam + MLI::ON_LINE::UNIT_NUM
|
||||
|
||||
; Get ProDOS 8 block size (clears __oserror)
|
||||
; Get ProDOS 8 block size (clears ___oserror)
|
||||
jsr _dio_query_sectsize
|
||||
|
||||
; Alloc buffer
|
||||
@@ -74,7 +74,7 @@ done: lda ptr4
|
||||
rts
|
||||
|
||||
nomem: lda #$FF ; Error code for sure not used by MLI
|
||||
oserr: sta __oserror
|
||||
oserr: sta ___oserror
|
||||
|
||||
; Save total blocks for failure
|
||||
lda #$00
|
||||
@@ -85,7 +85,7 @@ oserr: sta __oserror
|
||||
; Check for non-ProDOS disk
|
||||
check: cmp #$52 ; "Not a ProDOS volume"
|
||||
bne oserr
|
||||
sta __oserror
|
||||
sta ___oserror
|
||||
|
||||
; Save total blocks for a 16-sector disk
|
||||
lda #<280
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
_dio_query_sectsize:
|
||||
; Clear error
|
||||
stx __oserror ; X = 0
|
||||
stx ___oserror ; X = 0
|
||||
|
||||
; Return ProDOS 8 block size
|
||||
txa ; X = 0
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dir.h */
|
||||
/* */
|
||||
/* Apple ][ system specific DIR */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef _DIR_H
|
||||
#define _DIR_H
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
struct DIR {
|
||||
int fd;
|
||||
unsigned char entry_length;
|
||||
unsigned char entries_per_block;
|
||||
unsigned char current_entry;
|
||||
union {
|
||||
unsigned char bytes[512];
|
||||
struct {
|
||||
unsigned prev_block;
|
||||
unsigned next_block;
|
||||
unsigned char entries[1];
|
||||
} content;
|
||||
} block;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* End of dir.h */
|
||||
#endif
|
||||
15
libsrc/apple2/dir.inc
Normal file
15
libsrc/apple2/dir.inc
Normal file
@@ -0,0 +1,15 @@
|
||||
.struct DIR
|
||||
FD .word
|
||||
ENTRY_LENGTH .byte
|
||||
ENTRIES_PER_BLOCK .byte
|
||||
FILE_COUNT .word
|
||||
CURRENT_ENTRY .byte
|
||||
.union
|
||||
BYTES .byte 512
|
||||
.struct CONTENT
|
||||
PREV_BLOCK .word
|
||||
NEXT_BLOCK .word
|
||||
ENTRIES .byte
|
||||
.endstruct
|
||||
.endunion
|
||||
.endstruct
|
||||
24
libsrc/apple2/dir_entry_count.s
Normal file
24
libsrc/apple2/dir_entry_count.s
Normal file
@@ -0,0 +1,24 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; unsigned int __fastcall__ dir_entry_count(DIR *dir);
|
||||
;
|
||||
|
||||
.export _dir_entry_count
|
||||
|
||||
.importzp ptr1
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "dir.inc"
|
||||
|
||||
.proc _dir_entry_count
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
ldy #DIR::FILE_COUNT + 1
|
||||
lda (ptr1),y
|
||||
tax
|
||||
dey
|
||||
lda (ptr1),y
|
||||
rts
|
||||
.endproc
|
||||
@@ -14,10 +14,11 @@
|
||||
; ProDOS 8 1.6 - $16
|
||||
; ProDOS 8 1.7 - $17
|
||||
; ProDOS 8 1.8 - $18
|
||||
; ProDOS 8 1.9 - $18
|
||||
; ProDOS 8 1.9 - $18 (!)
|
||||
; ProDOS 8 2.0.1 - $21
|
||||
; ProDOS 8 2.0.2 - $22
|
||||
; ProDOS 8 2.0.3 - $23
|
||||
; ProDOS 8 2.4.x - $24
|
||||
;
|
||||
|
||||
.constructor initdostype, 25
|
||||
|
||||
41
libsrc/apple2/dynchline.s
Normal file
41
libsrc/apple2/dynchline.s
Normal file
@@ -0,0 +1,41 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 08.08.1998
|
||||
; Colin Leroy-Mira, 26.05.2025
|
||||
;
|
||||
; void __fastcall__ dyn_chlinexy (unsigned char c, unsigned char x, unsigned char y, unsigned char length);
|
||||
; void __fastcall__ dyn_chline (unsigned char c, unsigned char length);
|
||||
;
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
|
||||
.export _dyn_chlinexy, _dyn_chline, chlinedirect
|
||||
.import gotoxy, cputdirect, popa
|
||||
.import machinetype
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
_dyn_chlinexy:
|
||||
pha ; Save the length
|
||||
jsr gotoxy ; Call this one, will pop params
|
||||
pla ; Restore the length and run into _chline
|
||||
|
||||
_dyn_chline:
|
||||
pha
|
||||
jsr popa ; Get the character to draw
|
||||
eor #$80 ; Invert high bit
|
||||
tax
|
||||
pla
|
||||
|
||||
chlinedirect:
|
||||
stx tmp1
|
||||
cmp #$00 ; Is the length zero?
|
||||
beq done ; Jump if done
|
||||
sta tmp2
|
||||
: lda tmp1 ; Screen code
|
||||
jsr cputdirect ; Direct output
|
||||
dec tmp2
|
||||
bne :-
|
||||
done: rts
|
||||
|
||||
.endif
|
||||
40
libsrc/apple2/dyncvline.s
Normal file
40
libsrc/apple2/dyncvline.s
Normal file
@@ -0,0 +1,40 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 08.08.1998
|
||||
; Colin Leroy-Mira, 26.05.2025
|
||||
;
|
||||
; void __fastcall__ dyn_cvlinexy (unsigned char c, unsigned char x, unsigned char y, unsigned char length);
|
||||
; void __fastcall__ dyn_cvline (unsigned char c, unsigned char length);
|
||||
;
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
|
||||
.export _dyn_cvlinexy, _dyn_cvline
|
||||
.import gotoxy, putchar, newline, popa
|
||||
.import machinetype
|
||||
|
||||
.include "zeropage.inc"
|
||||
|
||||
_dyn_cvlinexy:
|
||||
pha ; Save the length
|
||||
jsr gotoxy ; Call this one, will pop params
|
||||
pla ; Restore the length and run into _cvline
|
||||
|
||||
_dyn_cvline:
|
||||
pha
|
||||
jsr popa ; Get the character to draw
|
||||
eor #$80 ; Invert high bit
|
||||
tax
|
||||
pla
|
||||
|
||||
stx tmp1
|
||||
cmp #$00 ; Is the length zero?
|
||||
beq done ; Jump if done
|
||||
sta tmp2
|
||||
: lda tmp1 ; Screen code
|
||||
jsr putchar ; Write, no cursor advance
|
||||
jsr newline ; Advance cursor to next line
|
||||
dec tmp2
|
||||
bne :-
|
||||
done: rts
|
||||
|
||||
.endif
|
||||
@@ -73,7 +73,8 @@ INSTALL:
|
||||
and #$f0
|
||||
cmp #$80
|
||||
bne @L1
|
||||
lda #EM_ERR_OK
|
||||
.assert EM_ERR_OK = 0, error
|
||||
txa
|
||||
rts
|
||||
@L1: lda #EM_ERR_NO_DEVICE
|
||||
; rts
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
;
|
||||
|
||||
.export _exec
|
||||
.import pushname, popname
|
||||
.import popax, done, _exit
|
||||
.import mli_file_info_direct
|
||||
.import aux80col
|
||||
.import pushname, popname, popax, done, _exit
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
@@ -17,13 +18,12 @@
|
||||
typerr: lda #$4A ; "Incompatible file format"
|
||||
|
||||
; Cleanup name
|
||||
oserr: jsr popname ; Preserves A
|
||||
|
||||
; Set __oserror
|
||||
jmp __mappederrno
|
||||
|
||||
mlierr: jsr popname
|
||||
oserr: jmp ___mappederrno
|
||||
|
||||
_exec:
|
||||
; Save cmdline
|
||||
; Store cmdline
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
|
||||
@@ -32,6 +32,9 @@ _exec:
|
||||
jsr pushname
|
||||
bne oserr
|
||||
|
||||
jsr mli_file_info_direct
|
||||
bcs mlierr
|
||||
|
||||
; ProDOS TechRefMan, chapter 5.1.5.1:
|
||||
; "The complete or partial pathname of the system program
|
||||
; is stored at $280, starting with a length byte."
|
||||
@@ -46,18 +49,6 @@ _exec:
|
||||
dey
|
||||
bpl :-
|
||||
|
||||
; Set pushed name
|
||||
lda sp
|
||||
ldx sp+1
|
||||
sta mliparam + MLI::INFO::PATHNAME
|
||||
stx mliparam + MLI::INFO::PATHNAME+1
|
||||
|
||||
; Get file_type and aux_type
|
||||
lda #GET_INFO_CALL
|
||||
ldx #GET_INFO_COUNT
|
||||
jsr callmli
|
||||
bcs oserr
|
||||
|
||||
; If we get here the program file at least exists so we copy
|
||||
; the loader stub right now and patch it later to set params
|
||||
ldx #size - 1
|
||||
@@ -121,37 +112,12 @@ setbuf: lda #$00 ; Low byte
|
||||
dex
|
||||
dex
|
||||
|
||||
; Set I/O buffer
|
||||
sta mliparam + MLI::OPEN::IO_BUFFER
|
||||
stx mliparam + MLI::OPEN::IO_BUFFER+1
|
||||
; Set OPEN MLI call I/O buffer parameter
|
||||
sta io_buffer
|
||||
stx io_buffer+1
|
||||
|
||||
; PATHNAME already set
|
||||
.assert MLI::OPEN::PATHNAME = MLI::INFO::PATHNAME, error
|
||||
|
||||
; Lower file level to avoid program file
|
||||
; being closed by C libary shutdown code
|
||||
ldx LEVEL
|
||||
stx level
|
||||
beq :+
|
||||
dec LEVEL
|
||||
|
||||
; Open file
|
||||
: lda #OPEN_CALL
|
||||
ldx #OPEN_COUNT
|
||||
jsr callmli
|
||||
|
||||
; Restore file level
|
||||
ldx level
|
||||
stx LEVEL
|
||||
bcc :+
|
||||
jmp oserr
|
||||
|
||||
; Get and save fd
|
||||
: lda mliparam + MLI::OPEN::REF_NUM
|
||||
sta read_ref
|
||||
sta close_ref
|
||||
|
||||
.ifdef __APPLE2ENH__
|
||||
bit aux80col
|
||||
bpl :+
|
||||
; Calling the 80 column firmware needs the ROM switched
|
||||
; in, otherwise it copies the F8 ROM to the LC (@ $CEF4)
|
||||
bit $C082
|
||||
@@ -164,9 +130,8 @@ setbuf: lda #$00 ; Low byte
|
||||
|
||||
; Switch in LC bank 2 for R/O
|
||||
bit $C080
|
||||
.endif
|
||||
|
||||
; Reset stack as we already passed
|
||||
: ; Reset stack as we already passed
|
||||
; the point of no return anyway
|
||||
ldx #$FF
|
||||
txs
|
||||
@@ -185,23 +150,34 @@ setbuf: lda #$00 ; Low byte
|
||||
lda #$00 ; '\0'
|
||||
beq :- ; Branch always
|
||||
|
||||
; Call loader stub after C libary shutdown
|
||||
; Call loader stub after C library shutdown
|
||||
: lda #<target
|
||||
ldx #>target
|
||||
sta done+1
|
||||
stx done+2
|
||||
|
||||
; Initiate C libary shutdown
|
||||
; Initiate C library shutdown
|
||||
jmp _exit
|
||||
|
||||
.bss
|
||||
|
||||
level : .res 1
|
||||
|
||||
.rodata
|
||||
|
||||
source:
|
||||
; Open program file
|
||||
; PATHNAME parameter is already set (we reuse
|
||||
; the copy at $0280); IO_BUFFER has been setup
|
||||
; before shutting down the C library
|
||||
jsr $BF00
|
||||
.byte OPEN_CALL
|
||||
.word open_param
|
||||
bcs error
|
||||
|
||||
; Copy REF_NUM to MLI READ and CLOSE parameters
|
||||
lda open_ref
|
||||
sta read_ref
|
||||
sta close_ref
|
||||
|
||||
; Read whole program file
|
||||
source: jsr $BF00
|
||||
jsr $BF00
|
||||
.byte READ_CALL
|
||||
.word read_param
|
||||
bcs error
|
||||
@@ -213,8 +189,6 @@ source: jsr $BF00
|
||||
bcs error
|
||||
|
||||
; Check for cmdline handling
|
||||
lda $0100 ; Valid cmdline?
|
||||
beq jump ; No, jump to program right away
|
||||
ldx file_type ; SYS file?
|
||||
bne system ; Yes, check for startup filename
|
||||
|
||||
@@ -256,6 +230,14 @@ jump: jmp (data_buffer)
|
||||
file_type = * - source + target
|
||||
.byte $00
|
||||
|
||||
open_param = * - source + target
|
||||
.byte $03 ; PARAM_COUNT
|
||||
.addr $0280 ; PATHNAME
|
||||
io_buffer = * - source + target
|
||||
.addr $0000 ; IO_BUFFER
|
||||
open_ref = * - source + target
|
||||
.byte $00 ; REF_NUM
|
||||
|
||||
read_param = * - source + target
|
||||
.byte $04 ; PARAM_COUNT
|
||||
read_ref = * - source + target
|
||||
@@ -287,4 +269,8 @@ size = * - source
|
||||
|
||||
target = DOSWARM - size
|
||||
|
||||
; Make sure that the loader isn't too big, and
|
||||
; fits in $300-$3D0
|
||||
.assert target >= $300, error
|
||||
|
||||
dosvec: jmp quit
|
||||
|
||||
33
libsrc/apple2/extra/integer-basic-compat.s
Normal file
33
libsrc/apple2/extra/integer-basic-compat.s
Normal file
@@ -0,0 +1,33 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 06.03.2025
|
||||
;
|
||||
; Copy the LC segment from the end of the binary to the Language Card
|
||||
; using _memcpy. This allows running apple2 programs on the original
|
||||
; Integer ROM Apple ][.
|
||||
;
|
||||
|
||||
.export bltu2
|
||||
|
||||
.import _memcpy, pushax
|
||||
.import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated
|
||||
.import __LC_START__, __LC_LAST__ ; Linker generated
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
bltu2:
|
||||
; Get the destination start address.
|
||||
lda #<__LC_START__
|
||||
ldx #>__LC_START__
|
||||
jsr pushax
|
||||
|
||||
; Get the source start address.
|
||||
lda #<(__ONCE_LOAD__ + __ONCE_SIZE__)
|
||||
ldx #>(__ONCE_LOAD__ + __ONCE_SIZE__)
|
||||
jsr pushax
|
||||
|
||||
; Set the length
|
||||
lda #<(__LC_LAST__ - __LC_START__)
|
||||
ldx #>(__LC_LAST__ - __LC_START__)
|
||||
|
||||
; And do the copy
|
||||
jmp _memcpy
|
||||
@@ -54,18 +54,20 @@ iobuf_alloc:
|
||||
rts
|
||||
|
||||
; Mark table entry as used
|
||||
: lda #$FF
|
||||
sta table,x
|
||||
: dec table,x
|
||||
|
||||
; Convert table index to address hibyte
|
||||
txa
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
; Skip clearing carry, it can't be set as long as MAX_FDS*4 is
|
||||
; less than 64.
|
||||
.assert MAX_FDS*4 < $40, error
|
||||
adc #>$0800
|
||||
|
||||
; Store address in "memptr"
|
||||
ldy #$01
|
||||
; (Y still equals 0 from popptr1)
|
||||
iny
|
||||
sta (ptr1),y
|
||||
dey
|
||||
tya
|
||||
@@ -82,8 +84,7 @@ iobuf_free:
|
||||
|
||||
; Mark table entry as free
|
||||
tax
|
||||
lda #$00
|
||||
sta table,x
|
||||
inc table,x
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
.import subysp, addysp, decsp1
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
.include "mli.inc"
|
||||
|
||||
pushname:
|
||||
@@ -15,7 +16,7 @@ pushname:
|
||||
stx ptr1+1
|
||||
|
||||
; Alloc pathname buffer
|
||||
ldy #64+1 ; Max pathname length + zero
|
||||
ldy #FILENAME_MAX
|
||||
jsr subysp
|
||||
|
||||
; Check for full pathname
|
||||
@@ -71,14 +72,14 @@ copy: lda (ptr1),y
|
||||
sta (sp),y
|
||||
beq setlen
|
||||
iny
|
||||
cpy #64+1 ; Max pathname length + zero
|
||||
cpy #FILENAME_MAX
|
||||
bcc copy
|
||||
|
||||
; Load oserror code
|
||||
lda #$40 ; "Invalid pathname"
|
||||
|
||||
; Free pathname buffer
|
||||
addsp65:ldy #64+1
|
||||
addsp65:ldy #FILENAME_MAX
|
||||
bne addsp ; Branch always
|
||||
|
||||
; Alloc and set length byte
|
||||
@@ -93,5 +94,5 @@ setlen: tya
|
||||
|
||||
popname:
|
||||
; Cleanup stack
|
||||
ldy #1 + 64+1 ; Length byte + max pathname length + zero
|
||||
addsp: jmp addysp ; Preserves A
|
||||
ldy #1 + FILENAME_MAX
|
||||
addsp: jmp addysp ; Preserves A and X
|
||||
|
||||
22
libsrc/apple2/get_iigs_speed.s
Normal file
22
libsrc/apple2/get_iigs_speed.s
Normal file
@@ -0,0 +1,22 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; unsigned char __fastcall__ get_iigs_speed(void)
|
||||
;
|
||||
|
||||
.export _get_iigs_speed
|
||||
.import ostype, return0
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "accelerator.inc"
|
||||
|
||||
_get_iigs_speed:
|
||||
lda ostype ; Return SLOW if not IIgs
|
||||
bpl :+
|
||||
lda CYAREG ; Check current setting
|
||||
bpl :+
|
||||
lda #SPEED_FAST
|
||||
ldx #>$0000
|
||||
rts
|
||||
.assert SPEED_SLOW = 0, error
|
||||
: jmp return0 ; SPEED_SLOW
|
||||
@@ -4,8 +4,10 @@
|
||||
; unsigned char get_ostype (void)
|
||||
;
|
||||
|
||||
.constructor initostype
|
||||
.export _get_ostype
|
||||
; Priority higher than the default one so that things depending
|
||||
; on ostype can get ostype set when called at normal priority
|
||||
.constructor initostype, 9
|
||||
.export _get_ostype, ostype
|
||||
|
||||
; Identify machine according to:
|
||||
; Apple II Miscellaneous TechNote #7, Apple II Family Identification
|
||||
@@ -32,30 +34,30 @@ next: inx
|
||||
bne :-
|
||||
beq next ; Branch always
|
||||
|
||||
index: .byte $B3, $00 ; Apple ][
|
||||
.byte $B3, $1E, $00 ; Apple ][+
|
||||
.byte $B3, $1E, $00 ; Apple /// (emulation)
|
||||
.byte $B3, $C0, $00 ; Apple //e
|
||||
.byte $B3, $C0, $DD, $BE, $00 ; Apple //e Option Card
|
||||
.byte $B3, $C0, $00 ; Apple //e (enhanced)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c (Mem. Exp.)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c (Rev. Mem. Exp.)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c Plus
|
||||
index: .byte $B3, $00 ; Apple ][
|
||||
.byte $B3, $1E, $00 ; Apple ][+
|
||||
.byte $B3, $1E, $00 ; Apple /// (emulation)
|
||||
.byte $B3, $C0, $00 ; Apple //e
|
||||
.byte $B3, $C0, $DD, $00 ; Apple //e Option Card
|
||||
.byte $B3, $C0, $00 ; Apple //e (enhanced)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c (3.5 ROM)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c (Mem. Exp.)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c (Rev. Mem. Exp.)
|
||||
.byte $B3, $C0, $BF, $00 ; Apple //c Plus
|
||||
.byte $00
|
||||
|
||||
value: .byte $38, $10 ; Apple ][
|
||||
.byte $EA, $AD, $11 ; Apple ][+
|
||||
.byte $EA, $8A, $20 ; Apple /// (emulation)
|
||||
.byte $06, $EA, $30 ; Apple //e
|
||||
.byte $06, $E0, $02, $00, $40 ; Apple //e Option Card
|
||||
.byte $06, $E0, $31 ; Apple //e (enhanced)
|
||||
.byte $06, $00, $FF, $50 ; Apple //c
|
||||
.byte $06, $00, $00, $51 ; Apple //c (3.5 ROM)
|
||||
.byte $06, $00, $03, $53 ; Apple //c (Mem. Exp.)
|
||||
.byte $06, $00, $04, $54 ; Apple //c (Rev. Mem. Exp.)
|
||||
.byte $06, $00, $05, $55 ; Apple //c Plus
|
||||
value: .byte $38, $10 ; Apple ][
|
||||
.byte $EA, $AD, $11 ; Apple ][+
|
||||
.byte $EA, $8A, $20 ; Apple /// (emulation)
|
||||
.byte $06, $EA, $30 ; Apple //e
|
||||
.byte $06, $E0, $02, $32 ; Apple //e Option Card
|
||||
.byte $06, $E0, $31 ; Apple //e (enhanced)
|
||||
.byte $06, $00, $FF, $40 ; Apple //c
|
||||
.byte $06, $00, $00, $41 ; Apple //c (3.5 ROM)
|
||||
.byte $06, $00, $03, $43 ; Apple //c (Mem. Exp.)
|
||||
.byte $06, $00, $04, $44 ; Apple //c (Rev. Mem. Exp.)
|
||||
.byte $06, $00, $05, $45 ; Apple //c Plus
|
||||
.byte $00
|
||||
|
||||
.code
|
||||
|
||||
189
libsrc/apple2/get_tv.s
Normal file
189
libsrc/apple2/get_tv.s
Normal file
@@ -0,0 +1,189 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2025
|
||||
;
|
||||
; unsigned char __fastcall__ get_tv(void)
|
||||
;
|
||||
.export _get_tv
|
||||
|
||||
.import _set_iigs_speed, _get_iigs_speed
|
||||
.import ostype
|
||||
|
||||
.constructor calibrate_tv, 8 ; After ostype
|
||||
|
||||
.include "accelerator.inc"
|
||||
.include "apple2.inc"
|
||||
.include "get_tv.inc"
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
; Cycle wasters
|
||||
waste_72:
|
||||
jsr waste_36
|
||||
waste_36:
|
||||
jsr waste_12
|
||||
waste_24:
|
||||
jsr waste_12
|
||||
waste_12:
|
||||
rts
|
||||
|
||||
.proc calibrate_tv
|
||||
lda ostype
|
||||
bmi iigs
|
||||
cmp #$20
|
||||
bcc iip
|
||||
cmp #$40
|
||||
bcc iie
|
||||
|
||||
iic: jmp calibrate_iic
|
||||
iigs: jmp calibrate_iigs
|
||||
iie: jmp calibrate_iie
|
||||
iip: rts ; Keep TV::OTHER.
|
||||
.endproc
|
||||
|
||||
|
||||
; Magic numbers
|
||||
WASTE_LOOP_CYCLES = 92 ; The wait loop total cycles
|
||||
NTSC_LOOP_COUNT = 17030/WASTE_LOOP_CYCLES ; How many loops expected on NTSC
|
||||
PAL_LOOP_COUNT = 20280/WASTE_LOOP_CYCLES ; How many loops expected on PAL
|
||||
STOP_PTRIG = 16500/WASTE_LOOP_CYCLES ; Stop PTRIG at 16.5ms
|
||||
|
||||
; Carry set at enter: wait for VBL +
|
||||
; Carry clear at enter: wait for VBL -
|
||||
; Increments X every 92 cycles.
|
||||
.proc count_until_vbl_bit
|
||||
lda #$10 ; BPL
|
||||
bcc :+
|
||||
lda #$30 ; BMI
|
||||
: sta sign
|
||||
|
||||
; Wait for VBLsign change with 92 cycles loops.
|
||||
; Hit PTRIG repeatedly so that accelerators will slow down.
|
||||
; But stop hitting PTRIG after 16.5ms cycles, so that on the //c,
|
||||
; the VBLINT will not be reset right before we get it. 16.5ms
|
||||
; is a good value because it's far enough from 17ms for NTSC
|
||||
; models, and close enough to 20.2ms for PAL models that accelerators
|
||||
; will stay slow until there. (5ms usually).
|
||||
|
||||
: cpx #STOP_PTRIG ; 2 - see if we spent 16.5ms already
|
||||
bcs notrig ; 4 / 5 - if so, stop hitting PTRIG
|
||||
sta PTRIG ; 8 - otherwise hit it
|
||||
bcc count ; 11
|
||||
notrig:
|
||||
nop ; 7 - keep cycle count constant when not
|
||||
nop ; 9 - hitting PTRIG
|
||||
nop ; 11
|
||||
count:
|
||||
inx ; 13
|
||||
jsr waste_72 ; 85
|
||||
bit RDVBLBAR ; 89 - Wait for VBL change
|
||||
sign:
|
||||
bpl :- ; 92 - patched with bpl/bmi
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.proc calibrate_iic
|
||||
php
|
||||
sei
|
||||
|
||||
sta IOUDISOFF
|
||||
lda RDVBLMSK
|
||||
pha ; Back up for cleanup
|
||||
|
||||
bit ENVBL
|
||||
bit PTRIG ; Reset VBL interrupt flag
|
||||
: bit RDVBLBAR ; Wait for one VBL
|
||||
bpl :-
|
||||
|
||||
bit PTRIG ; Reset VBL interrupt flag again
|
||||
ldx #$00
|
||||
clc
|
||||
jsr count_until_vbl_bit
|
||||
|
||||
pla ; Cleanup
|
||||
asl
|
||||
bcs :+ ; VBL interrupts were already enabled
|
||||
bit DISVBL
|
||||
: sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on.
|
||||
|
||||
plp
|
||||
jmp calibrate_done
|
||||
.endproc
|
||||
|
||||
.proc calibrate_iie
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be off (VBL start)
|
||||
bmi :-
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be on (VBL end)
|
||||
bpl :-
|
||||
|
||||
; Wait and count during a full cycle
|
||||
ldx #$00
|
||||
sec
|
||||
jsr count_until_vbl_bit
|
||||
clc
|
||||
jsr count_until_vbl_bit
|
||||
|
||||
jmp calibrate_done
|
||||
.endproc
|
||||
|
||||
.proc calibrate_iigs
|
||||
; Backup speed and slow down
|
||||
jsr _get_iigs_speed
|
||||
pha
|
||||
lda #SPEED_SLOW
|
||||
jsr _set_iigs_speed
|
||||
|
||||
; The same as IIe, but reverted, because... something?
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be on (VBL start)
|
||||
bpl :-
|
||||
: bit RDVBLBAR ; Wait for bit 7 to be off (VBL end)
|
||||
bmi :-
|
||||
|
||||
; Wait and count during a full cycle
|
||||
ldx #$00
|
||||
clc
|
||||
jsr count_until_vbl_bit
|
||||
sec
|
||||
jsr count_until_vbl_bit
|
||||
|
||||
jsr calibrate_done
|
||||
|
||||
; Restore user speed
|
||||
pla
|
||||
jmp _set_iigs_speed
|
||||
.endproc
|
||||
|
||||
.proc calibrate_done
|
||||
; Consider X +/- 3 to be valid,
|
||||
; anything else is unknown.
|
||||
|
||||
lda #TV::NTSC
|
||||
cpx #NTSC_LOOP_COUNT-3
|
||||
bcc unexpected
|
||||
cpx #NTSC_LOOP_COUNT+3
|
||||
bcc matched
|
||||
|
||||
lda #TV::PAL
|
||||
cpx #PAL_LOOP_COUNT-3
|
||||
bcc unexpected
|
||||
cpx #PAL_LOOP_COUNT+3
|
||||
bcs unexpected
|
||||
|
||||
matched:
|
||||
sta tv
|
||||
|
||||
unexpected:
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.code
|
||||
|
||||
; The only thing remaining from that code after init
|
||||
.proc _get_tv
|
||||
lda tv
|
||||
ldx #>$0000
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
tv: .byte TV::OTHER
|
||||
@@ -30,5 +30,5 @@ next: inx
|
||||
bne next
|
||||
|
||||
done: txa
|
||||
ldx #$00
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
@@ -52,7 +52,7 @@ _clock_getres:
|
||||
enosys: lda #ENOSYS
|
||||
|
||||
; Set __errno
|
||||
jmp __directerrno
|
||||
jmp ___directerrno
|
||||
|
||||
.rodata
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp);
|
||||
;
|
||||
|
||||
.import pushax, steaxspidx, incsp1, incsp3, return0
|
||||
.import pushax, incsp1, incsp3, steaxspidx, return0
|
||||
.import _mktime_dt
|
||||
|
||||
.include "time.inc"
|
||||
.include "zeropage.inc"
|
||||
@@ -29,42 +30,12 @@ _clock_gettime:
|
||||
jsr callmli
|
||||
bcs oserr
|
||||
|
||||
; Get date
|
||||
lda DATELO+1
|
||||
lsr
|
||||
php ; Save month msb
|
||||
cmp #70 ; Year < 70?
|
||||
bcs :+ ; No, leave alone
|
||||
adc #100 ; Move 19xx to 20xx
|
||||
: sta TM + tm::tm_year
|
||||
lda DATELO
|
||||
tax ; Save day
|
||||
plp ; Restore month msb
|
||||
ror
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
beq erange ; [1..12] allows for validity check
|
||||
tay
|
||||
dey ; Move [1..12] to [0..11]
|
||||
sty TM + tm::tm_mon
|
||||
txa ; Restore day
|
||||
and #%00011111
|
||||
sta TM + tm::tm_mday
|
||||
; Convert DATELO/TIMELO to time_t
|
||||
lda #<DATELO
|
||||
ldx #>DATELO
|
||||
jsr _mktime_dt
|
||||
|
||||
; Get time
|
||||
lda TIMELO+1
|
||||
sta TM + tm::tm_hour
|
||||
lda TIMELO
|
||||
sta TM + tm::tm_min
|
||||
|
||||
; Make time_t
|
||||
lda #<TM
|
||||
ldx #>TM
|
||||
jsr _mktime
|
||||
|
||||
; Store tv_sec
|
||||
; Store
|
||||
ldy #timespec::tv_sec
|
||||
jsr steaxspidx
|
||||
|
||||
@@ -74,21 +45,8 @@ _clock_gettime:
|
||||
; Return success
|
||||
jmp return0
|
||||
|
||||
; Load errno code
|
||||
erange: lda #ERANGE
|
||||
|
||||
; Cleanup stack
|
||||
jsr incsp3 ; Preserves A
|
||||
|
||||
; Set __errno
|
||||
jmp __directerrno
|
||||
|
||||
; Cleanup stack
|
||||
oserr: jsr incsp3 ; Preserves A
|
||||
|
||||
; Set __oserror
|
||||
jmp __mappederrno
|
||||
|
||||
.bss
|
||||
|
||||
TM: .tag tm
|
||||
; Set ___oserror
|
||||
jmp ___mappederrno
|
||||
|
||||
73
libsrc/apple2/gmtime_dt.s
Normal file
73
libsrc/apple2/gmtime_dt.s
Normal file
@@ -0,0 +1,73 @@
|
||||
;
|
||||
; Oliver Schmidt, 14.08.2018
|
||||
; Colin Leroy-Mira, 2023 <colin@colino.net>
|
||||
;
|
||||
; struct tm * __fastcall__ gmtime_dt(const struct datetime *dt)
|
||||
;
|
||||
|
||||
.export _gmtime_dt, tm_buf
|
||||
|
||||
.include "time.inc"
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
.include "mli.inc"
|
||||
|
||||
; Convert ProDOS date/time to a struct tm
|
||||
; source date address in AX
|
||||
; on stack:
|
||||
; destination struct
|
||||
|
||||
_gmtime_dt:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
; Get time
|
||||
ldy #$03
|
||||
lda (ptr1),y
|
||||
sta tm_buf + tm::tm_hour
|
||||
dey
|
||||
lda (ptr1),y
|
||||
sta tm_buf + tm::tm_min
|
||||
|
||||
; Get date
|
||||
dey
|
||||
lda (ptr1),y
|
||||
lsr
|
||||
php ; Save month msb
|
||||
cmp #70 ; Year < 70?
|
||||
bcs :+ ; No, leave alone
|
||||
adc #100 ; Move 19xx to 20xx
|
||||
: sta tm_buf + tm::tm_year
|
||||
|
||||
dey
|
||||
lda (ptr1),y
|
||||
tax ; Save day
|
||||
plp ; Restore month msb
|
||||
ror
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
beq erange ; [1..12] allows for validity check
|
||||
tay
|
||||
dey ; Move [1..12] to [0..11]
|
||||
sty tm_buf + tm::tm_mon
|
||||
txa ; Restore day
|
||||
and #%00011111
|
||||
sta tm_buf + tm::tm_mday
|
||||
|
||||
lda #<tm_buf ; Return pointer to tm_buf
|
||||
ldx #>tm_buf
|
||||
rts
|
||||
|
||||
; Load errno code and return NULL
|
||||
erange: lda #ERANGE
|
||||
sta ___errno
|
||||
lda #$00
|
||||
tax
|
||||
rts
|
||||
|
||||
.bss
|
||||
|
||||
tm_buf:
|
||||
.tag tm
|
||||
@@ -8,6 +8,10 @@
|
||||
.export gotoxy, _gotoxy, _gotox
|
||||
.import popa, VTABZ
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.endif
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
gotoxy:
|
||||
@@ -22,4 +26,13 @@ _gotoxy:
|
||||
|
||||
_gotox:
|
||||
sta CH ; Store X
|
||||
rts
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl :+
|
||||
.endif
|
||||
|
||||
bit RD80VID ; In 80 column mode?
|
||||
bpl :+
|
||||
sta OURCH ; Store X
|
||||
: rts
|
||||
|
||||
@@ -3,22 +3,37 @@
|
||||
;
|
||||
|
||||
.export initcwd
|
||||
.import __cwd
|
||||
.import __cwd, __dos_type
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
.include "mli.inc"
|
||||
|
||||
initcwd:
|
||||
; Set static prefix buffer
|
||||
lda #<__cwd
|
||||
ldx #>__cwd
|
||||
sta mliparam + MLI::PREFIX::PATHNAME
|
||||
stx mliparam + MLI::PREFIX::PATHNAME+1
|
||||
; Check for ProDOS 8
|
||||
lda __dos_type
|
||||
beq done
|
||||
|
||||
; Get current working directory
|
||||
lda #GET_PREFIX_CALL
|
||||
ldx #PREFIX_COUNT
|
||||
jsr callmli
|
||||
; Save random counter
|
||||
lda RNDL
|
||||
pha
|
||||
lda RNDH
|
||||
pha
|
||||
|
||||
; Call MLI
|
||||
; We're not using mli.s' callmli because its
|
||||
; mliparam is in BSS and this will be called
|
||||
; before LC code is moved to the Language Card.
|
||||
|
||||
jsr $BF00 ; MLI call entry point
|
||||
.byte GET_PREFIX_CALL ; MLI command
|
||||
.addr mli_parameters ; MLI parameter
|
||||
|
||||
; Restore random counter
|
||||
pla
|
||||
sta RNDH
|
||||
pla
|
||||
sta RNDL
|
||||
|
||||
; Check for null prefix
|
||||
ldx __cwd
|
||||
@@ -39,3 +54,9 @@ initcwd:
|
||||
sta __cwd,x
|
||||
|
||||
done: rts
|
||||
|
||||
.rodata
|
||||
|
||||
mli_parameters:
|
||||
.byte $01 ; Number of parameters
|
||||
.addr __cwd ; Address of parameter
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
; Oliver Schmidt, 10.9.2009
|
||||
;
|
||||
; Default ProDOS 8 I/O buffer management
|
||||
;
|
||||
;
|
||||
|
||||
.export iobuf_alloc, iobuf_free
|
||||
.import _posix_memalign, _free
|
||||
|
||||
@@ -19,13 +19,8 @@
|
||||
|
||||
; Constants
|
||||
|
||||
THRESHOLD = 20 ; Deviation from center triggering movement
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
; ROM entry points
|
||||
|
||||
PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
|
||||
LOWER_THRESHOLD = 05
|
||||
UPPER_THRESHOLD = 85
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
@@ -44,26 +39,41 @@ PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
|
||||
|
||||
; Library reference
|
||||
|
||||
.addr $0000
|
||||
libref: .addr $0000
|
||||
|
||||
; Jump table
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr COUNT
|
||||
.addr READJOY
|
||||
.addr READ
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
.bss
|
||||
|
||||
ostype: .res 1
|
||||
value0: .res 1
|
||||
value1: .res 1
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
; INSTALL routine. Is called after the driver is loaded into memory. If
|
||||
; possible, check if the hardware is present and determine the amount of
|
||||
; memory available.
|
||||
; Must return an JOY_ERR_xx code in a/x.
|
||||
INSTALL:
|
||||
lda #<JOY_ERR_OK
|
||||
ldx #>JOY_ERR_OK
|
||||
lda libref
|
||||
ldx libref+1
|
||||
sta gettype+1
|
||||
stx gettype+2
|
||||
gettype:jsr $0000
|
||||
sta ostype
|
||||
lda #JOY_ERR_OK
|
||||
.assert JOY_ERR_OK = 0, error
|
||||
tax
|
||||
; Fall through
|
||||
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory.
|
||||
@@ -71,57 +81,94 @@ INSTALL:
|
||||
UNINSTALL:
|
||||
rts
|
||||
|
||||
; COUNT: Return the total number of available joysticks in a/x.
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
; COUNT routine. Return the total number of available joysticks in a/x.
|
||||
COUNT:
|
||||
lda #$02 ; Number of joysticks we support
|
||||
ldx #$00
|
||||
ldx #$02
|
||||
bit ostype
|
||||
bvc noiic ; Not $4x
|
||||
dex ; Only one joystick for the //c
|
||||
noiic: txa ; Number of joysticks we support
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
; READ: Read a particular joystick passed in A.
|
||||
READJOY:
|
||||
bit $C082 ; Switch in ROM
|
||||
and #$01 ; Restrict joystick number
|
||||
|
||||
; Read horizontal paddle
|
||||
; READ routine. Read a particular joystick passed in A.
|
||||
READ:
|
||||
asl ; Joystick number -> paddle number
|
||||
tax ; Set paddle number (0, 2)
|
||||
jsr PREAD ; Read paddle value
|
||||
lda #$00 ; 0 0 0 0 0 0 0 0
|
||||
cpy #127 - THRESHOLD
|
||||
ror ; !LEFT 0 0 0 0 0 0 0
|
||||
cpy #127 + THRESHOLD
|
||||
ror ; RIGHT !LEFT 0 0 0 0 0 0
|
||||
tax
|
||||
ldy #$00
|
||||
sty value0
|
||||
sty value1
|
||||
|
||||
; Read vertical paddle
|
||||
; If IIgs -> set speed to normal
|
||||
bit ostype
|
||||
bpl nogs1 ; Not $8x
|
||||
lda CYAREG
|
||||
pha
|
||||
inx ; Set paddle number (1, 3)
|
||||
jsr PREAD ; Read paddle value
|
||||
and #%01111111
|
||||
sta CYAREG
|
||||
|
||||
; Read both paddles simultaneously according to:
|
||||
; Apple IIe Technote #6, The Apple II Paddle Circuits
|
||||
nogs1: lda PTRIG ; Trigger paddles
|
||||
loop: lda PADDL0,x ; Read paddle (0 or 2)
|
||||
bmi set0 ; Cycles: 2 3
|
||||
nop ; Cycles: 2
|
||||
bpl nop0 ; Cycles: 3
|
||||
set0: sty value0 ; Cycles: 4
|
||||
nop0: ; - -
|
||||
; Cycles: 7 7
|
||||
lda PADDL1,x ; Read paddle (1 or 3)
|
||||
bmi set1 ; Cycles: 2 3
|
||||
nop ; Cycles: 2
|
||||
bpl nop1 ; Cycles: 3
|
||||
set1: sty value1 ; Cycles: 4
|
||||
nop1: ; - -
|
||||
; Cycles: 7 7
|
||||
iny
|
||||
cpy #UPPER_THRESHOLD+1
|
||||
bne loop
|
||||
|
||||
; If IIgs -> restore speed
|
||||
bit ostype
|
||||
bpl nogs2 ; Not $8x
|
||||
pla
|
||||
cpy #127 - THRESHOLD
|
||||
sta CYAREG
|
||||
|
||||
; Transform paddle readings to directions
|
||||
nogs2: lda #$00 ; 0 0 0 0 0 0 0 0
|
||||
ldy value0
|
||||
cpy #LOWER_THRESHOLD
|
||||
ror ; !LEFT 0 0 0 0 0 0 0
|
||||
cpy #UPPER_THRESHOLD
|
||||
ror ; RIGHT !LEFT 0 0 0 0 0 0
|
||||
ldy value1
|
||||
cpy #LOWER_THRESHOLD
|
||||
ror ; !UP RIGHT !LEFT 0 0 0 0 0
|
||||
cpy #127 + THRESHOLD
|
||||
cpy #UPPER_THRESHOLD
|
||||
ror ; DOWN !UP RIGHT !LEFT 0 0 0 0
|
||||
|
||||
; Read primary button
|
||||
tay
|
||||
lda BUTN0-1,x ; Check button (1, 3)
|
||||
lda BUTN0,x ; Check button (0 or 2)
|
||||
asl
|
||||
tya
|
||||
ror ; BTN DOWN !UP RIGHT !LEFT 0 0 0
|
||||
ror ; BTN_1 DOWN !UP RIGHT !LEFT 0 0 0
|
||||
|
||||
; Read secondary button
|
||||
tay
|
||||
inx
|
||||
txa
|
||||
and #$03 ; IIgs has fourth button at TAPEIN
|
||||
eor #$02 ; IIgs has fourth button at TAPEIN
|
||||
tax
|
||||
lda BUTN0-1,x ; Check button (2, 0)
|
||||
lda TAPEIN,x ; Check button (1 or 3)
|
||||
asl
|
||||
tya
|
||||
ror ; BTN2 BTN DOWN !UP RIGHT !LEFT 0 0
|
||||
ror ; BTN_2 BTN_1 DOWN !UP RIGHT !LEFT 0 0
|
||||
|
||||
; Finalize
|
||||
eor #%00010100 ; BTN2 BTN DOWN UP RIGHT LEFT 0 0
|
||||
ldx #$00
|
||||
bit $C080 ; Switch in LC bank 2 for R/O
|
||||
eor #%00010100 ; BTN_2 BTN_1 DOWN UP RIGHT LEFT 0 0
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
8
libsrc/apple2/joyref.s
Normal file
8
libsrc/apple2/joyref.s
Normal file
@@ -0,0 +1,8 @@
|
||||
;
|
||||
; Oliver Schmidt, 2020-06-04
|
||||
;
|
||||
|
||||
.export joy_libref
|
||||
.import _get_ostype
|
||||
|
||||
joy_libref := _get_ostype
|
||||
9
libsrc/apple2/lc-copy-applesoft.s
Normal file
9
libsrc/apple2/lc-copy-applesoft.s
Normal file
@@ -0,0 +1,9 @@
|
||||
;
|
||||
; Oliver Schmidt, 15.09.2009
|
||||
;
|
||||
; Copy the LC segment from the end of the binary to the Language Card
|
||||
; using AppleSoft's BLTU2 routine.
|
||||
;
|
||||
.export bltu2
|
||||
|
||||
bltu2 := $D39A
|
||||
@@ -2,11 +2,8 @@
|
||||
; Oliver Schmidt, 2013-05-31
|
||||
;
|
||||
|
||||
.export em_libref, joy_libref, mouse_libref, ser_libref, tgi_libref
|
||||
.export em_libref, ser_libref
|
||||
.import _exit
|
||||
|
||||
em_libref := _exit
|
||||
joy_libref := _exit
|
||||
mouse_libref := _exit
|
||||
ser_libref := _exit
|
||||
tgi_libref := _exit
|
||||
|
||||
@@ -107,13 +107,13 @@ seek_common:
|
||||
einval: lda #EINVAL
|
||||
|
||||
; Set __errno
|
||||
errno: jsr __directerrno ; leaves -1 in AX
|
||||
errno: jsr ___directerrno ; leaves -1 in AX
|
||||
stx sreg ; extend return value to 32 bits
|
||||
stx sreg+1
|
||||
rts
|
||||
|
||||
; Set __oserror
|
||||
oserr: jsr __mappederrno ; leaves -1 in AX
|
||||
; Set ___oserror
|
||||
oserr: jsr ___mappederrno ; leaves -1 in AX
|
||||
stx sreg ; extend return value to 32 bits
|
||||
stx sreg+1
|
||||
rts
|
||||
|
||||
24
libsrc/apple2/machinetype.s
Normal file
24
libsrc/apple2/machinetype.s
Normal file
@@ -0,0 +1,24 @@
|
||||
.ifndef __APPLE2ENH__
|
||||
|
||||
.constructor initmachinetype, 8
|
||||
|
||||
.import ostype
|
||||
.export machinetype
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
initmachinetype:
|
||||
ldx ostype
|
||||
cpx #$31 ; Apple //e enhanced?
|
||||
ror machinetype ; Carry to high bit
|
||||
cpx #$30 ; Apple //e?
|
||||
ror machinetype
|
||||
rts
|
||||
|
||||
.data
|
||||
|
||||
; bit 7: Machine is a //e or newer
|
||||
; bit 6: Machine is a //e enhanced or newer
|
||||
machinetype: .byte 0
|
||||
|
||||
.endif
|
||||
@@ -8,13 +8,17 @@
|
||||
;
|
||||
|
||||
.export _mouse_def_callbacks
|
||||
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.endif
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.bss
|
||||
|
||||
|
||||
backup: .res 1
|
||||
visible:.res 1
|
||||
|
||||
@@ -42,11 +46,14 @@ cursor = '+' | $40 ; Flashing crosshair
|
||||
.endif
|
||||
|
||||
getcursor:
|
||||
.ifdef __APPLE2ENH__
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl column
|
||||
.endif
|
||||
bit RD80VID ; In 80 column mode?
|
||||
bpl column ; No, skip bank switching
|
||||
switch: bit LOWSCR ; Patched at runtime
|
||||
.endif
|
||||
|
||||
column: ldx #$00 ; Patched at runtime
|
||||
getscr: lda $0400,x ; Patched at runtime
|
||||
cmp #cursor
|
||||
@@ -55,9 +62,7 @@ getscr: lda $0400,x ; Patched at runtime
|
||||
setcursor:
|
||||
lda #cursor
|
||||
setscr: sta $0400,x ; Patched at runtime
|
||||
.ifdef __APPLE2ENH__
|
||||
bit LOWSCR ; Doesn't hurt in 40 column mode
|
||||
.endif
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
@@ -65,9 +70,7 @@ setscr: sta $0400,x ; Patched at runtime
|
||||
.code
|
||||
|
||||
done:
|
||||
.ifdef __APPLE2ENH__
|
||||
bit LOWSCR ; Doesn't hurt in 40 column mode
|
||||
.endif
|
||||
return: rts
|
||||
|
||||
; Hide the mouse cursor.
|
||||
@@ -108,14 +111,14 @@ movex:
|
||||
inx
|
||||
bcs :-
|
||||
stx column+1
|
||||
.ifdef __APPLE2ENH__
|
||||
|
||||
; Patch switch anyway, it will just be skipped over if in 40-col mode
|
||||
adc #7 / 2 ; Left or right half of 40-col column?
|
||||
ldx #<LOWSCR ; Columns 1,3,5..79
|
||||
bcs :+
|
||||
.assert LOWSCR + 1 = HISCR, error
|
||||
inx ; Columns 0,2,4..78
|
||||
: stx switch+1
|
||||
.endif
|
||||
rts
|
||||
|
||||
; Move the mouse cursor y position to the value in A/X.
|
||||
|
||||
37
libsrc/apple2/mktime_dt.s
Normal file
37
libsrc/apple2/mktime_dt.s
Normal file
@@ -0,0 +1,37 @@
|
||||
;
|
||||
; Oliver Schmidt, 14.08.2018
|
||||
; Colin Leroy-Mira, 2023 <colin@colino.net>
|
||||
;
|
||||
; time_t __fastcall__ mktime_dt(const struct datetime *dt)
|
||||
;
|
||||
|
||||
.import steaxspidx, pushax, incsp2, _gmtime_dt
|
||||
.import tm_buf
|
||||
.export _mktime_dt
|
||||
|
||||
.include "time.inc"
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
.include "mli.inc"
|
||||
|
||||
; Convert ProDOS date/time to UNIX timestamp
|
||||
; source date address in AX
|
||||
|
||||
_mktime_dt:
|
||||
; Convert to internal tm
|
||||
jsr _gmtime_dt
|
||||
cpx #$00
|
||||
bne :+
|
||||
cmp #$00
|
||||
beq err
|
||||
|
||||
; Make time_t
|
||||
: lda #<tm_buf
|
||||
ldx #>tm_buf
|
||||
jmp _mktime
|
||||
|
||||
err: lda #$00
|
||||
tax
|
||||
sta sreg
|
||||
sta sreg+1
|
||||
rts
|
||||
@@ -83,8 +83,8 @@ EOF_COUNT = 2
|
||||
AUX_TYPE .word
|
||||
STORAGE_TYPE .byte
|
||||
BLOCKS .word
|
||||
MODE_DATE .word
|
||||
MODE_TIME .word
|
||||
MOD_DATE .word
|
||||
MOD_TIME .word
|
||||
CREATE_DATE .word
|
||||
CREATE_TIME .word
|
||||
.endstruct
|
||||
@@ -139,3 +139,6 @@ LEVEL := $BF94 ; File level: used in open, flush, close
|
||||
MACHID := $BF98 ; Machine identification
|
||||
PFIXPTR := $BF9A ; If = 0, no prefix active
|
||||
KVERSION:= $BFFF ; Kernel version number
|
||||
|
||||
; Max filename length
|
||||
FILENAME_MAX = 64+1
|
||||
|
||||
33
libsrc/apple2/mli_file_info.s
Normal file
33
libsrc/apple2/mli_file_info.s
Normal file
@@ -0,0 +1,33 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2023 <colin@colino.net>
|
||||
;
|
||||
|
||||
.export mli_file_info
|
||||
.import pushname, popname, mli_file_info_direct
|
||||
.import popax
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
.include "mli.inc"
|
||||
|
||||
; Calls ProDOS MLI GET_FILE_INFO on the filename
|
||||
; stored as C string in AX at top of stack
|
||||
; Returns with carry set on error, and sets errno
|
||||
mli_file_info:
|
||||
; Get pathname
|
||||
jsr popax
|
||||
jsr pushname
|
||||
bne oserr
|
||||
|
||||
jsr mli_file_info_direct
|
||||
php ; Save return status
|
||||
|
||||
jsr popname ; Preserves A
|
||||
|
||||
plp
|
||||
bcs oserr
|
||||
rts
|
||||
|
||||
oserr:
|
||||
jsr ___mappederrno
|
||||
sec
|
||||
rts
|
||||
22
libsrc/apple2/mli_file_info_direct.s
Normal file
22
libsrc/apple2/mli_file_info_direct.s
Normal file
@@ -0,0 +1,22 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2023 <colin@colino.net>
|
||||
;
|
||||
|
||||
.export mli_file_info_direct
|
||||
.include "zeropage.inc"
|
||||
.include "mli.inc"
|
||||
|
||||
; Calls ProDOS MLI GET_FILE_INFO on the ProDOS style
|
||||
; filename stored on top of stack
|
||||
; Returns with carry set on error, and sets errno
|
||||
mli_file_info_direct:
|
||||
; Set pushed name
|
||||
lda sp
|
||||
ldx sp+1
|
||||
sta mliparam + MLI::INFO::PATHNAME
|
||||
stx mliparam + MLI::INFO::PATHNAME+1
|
||||
|
||||
; Get file information
|
||||
lda #GET_INFO_CALL
|
||||
ldx #GET_INFO_COUNT
|
||||
jmp callmli
|
||||
@@ -7,6 +7,7 @@
|
||||
.include "zeropage.inc"
|
||||
.include "mouse-kernel.inc"
|
||||
.include "apple2.inc"
|
||||
.include "get_tv.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
@@ -21,6 +22,7 @@ CLAMPMOUSE = $17 ; Sets mouse bounds in a window
|
||||
HOMEMOUSE = $18 ; Sets mouse to upper-left corner of clamp win
|
||||
INITMOUSE = $19 ; Resets mouse clamps to default values and
|
||||
; sets mouse position to 0,0
|
||||
TIMEDATA = $1C ; Set mousecard's interrupt rate
|
||||
|
||||
pos1_lo := $0478
|
||||
pos1_hi := $0578
|
||||
@@ -41,6 +43,7 @@ status := $0778
|
||||
.byte MOUSE_API_VERSION ; Mouse driver API version number
|
||||
|
||||
; Library reference
|
||||
libref:
|
||||
.addr $0000
|
||||
|
||||
; Jump table
|
||||
@@ -133,8 +136,8 @@ next: inc ptr1+1
|
||||
bcc :+
|
||||
|
||||
; Mouse firmware not found
|
||||
lda #<MOUSE_ERR_NO_DEVICE
|
||||
ldx #>MOUSE_ERR_NO_DEVICE
|
||||
lda #MOUSE_ERR_NO_DEVICE
|
||||
ldx #0 ; return value is char
|
||||
rts
|
||||
|
||||
; Check Pascal 1.1 Firmware Protocol ID bytes
|
||||
@@ -152,9 +155,10 @@ next: inc ptr1+1
|
||||
sta xparam+1
|
||||
sta jump+2
|
||||
|
||||
; Disable interrupts now because setting the slot number makes
|
||||
; Disable interrupts now because setting the slot number makes
|
||||
; the IRQ handler (maybe called due to some non-mouse IRQ) try
|
||||
; calling the firmware which isn't correctly set up yet
|
||||
php
|
||||
sei
|
||||
|
||||
; Convert to and save slot number
|
||||
@@ -167,15 +171,39 @@ next: inc ptr1+1
|
||||
asl
|
||||
asl
|
||||
sta yparam+1
|
||||
|
||||
; The AppleMouse II Card needs the ROM switched in
|
||||
|
||||
; Apple II technical notes "Varying VBL Interrupt Rate",
|
||||
lda libref
|
||||
ldx libref+1
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
.ifdef __APPLE2ENH__
|
||||
lda (ptr1)
|
||||
.else
|
||||
ldy #$00
|
||||
lda (ptr1),y
|
||||
.endif
|
||||
|
||||
cmp #TV::OTHER
|
||||
beq :+
|
||||
|
||||
; The TV values are aligned with the values the mousecard
|
||||
; expect: 0 for 60Hz, 1 for 50Hz.
|
||||
.assert TV::NTSC = 0, error
|
||||
.assert TV::PAL = 1, error
|
||||
|
||||
ldx #TIMEDATA
|
||||
jsr firmware
|
||||
|
||||
: ; The AppleMouse II Card needs the ROM switched in
|
||||
; to be able to detect an Apple //e and use RDVBL
|
||||
bit $C082
|
||||
|
||||
; Reset mouse hardware
|
||||
ldx #INITMOUSE
|
||||
jsr firmware
|
||||
|
||||
|
||||
; Switch in LC bank 2 for R/O
|
||||
bit $C080
|
||||
|
||||
@@ -211,7 +239,7 @@ next: inc ptr1+1
|
||||
common: jsr firmware
|
||||
|
||||
; Enable interrupts and return success
|
||||
cli
|
||||
plp
|
||||
lda #<MOUSE_ERR_OK
|
||||
ldx #>MOUSE_ERR_OK
|
||||
rts
|
||||
@@ -220,6 +248,7 @@ common: jsr firmware
|
||||
; No return code required (the driver is removed from memory on return).
|
||||
UNINSTALL:
|
||||
; Hide cursor
|
||||
php
|
||||
sei
|
||||
jsr CHIDE
|
||||
|
||||
@@ -236,12 +265,12 @@ UNINSTALL:
|
||||
SETBOX:
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
|
||||
; Set x clamps
|
||||
ldx #$00
|
||||
ldy #MOUSE_BOX::MINX
|
||||
jsr :+
|
||||
|
||||
|
||||
; Set y clamps
|
||||
ldx #$01
|
||||
ldy #MOUSE_BOX::MINY
|
||||
@@ -249,7 +278,8 @@ SETBOX:
|
||||
; Apple II Mouse TechNote #1, Interrupt Environment with the Mouse:
|
||||
; "Disable interrupts before placing position information in the
|
||||
; screen holes."
|
||||
: sei
|
||||
: php
|
||||
sei
|
||||
|
||||
; Set low clamp
|
||||
lda (ptr1),y
|
||||
@@ -257,7 +287,7 @@ SETBOX:
|
||||
sta pos1_lo
|
||||
iny
|
||||
lda (ptr1),y
|
||||
sta box,y
|
||||
sta box,y
|
||||
sta pos1_hi
|
||||
|
||||
; Skip one word
|
||||
@@ -267,11 +297,11 @@ SETBOX:
|
||||
; Set high clamp
|
||||
iny
|
||||
lda (ptr1),y
|
||||
sta box,y
|
||||
sta box,y
|
||||
sta pos2_lo
|
||||
iny
|
||||
lda (ptr1),y
|
||||
sta box,y
|
||||
sta box,y
|
||||
sta pos2_hi
|
||||
|
||||
txa
|
||||
@@ -298,6 +328,7 @@ GETBOX:
|
||||
; the screen). No return code required.
|
||||
MOVE:
|
||||
ldy slot
|
||||
php
|
||||
sei
|
||||
|
||||
; Set y
|
||||
@@ -328,9 +359,10 @@ MOVE:
|
||||
; no special action is required besides hiding the mouse cursor.
|
||||
; No return code required.
|
||||
HIDE:
|
||||
php
|
||||
sei
|
||||
jsr CHIDE
|
||||
cli
|
||||
plp
|
||||
rts
|
||||
|
||||
; SHOW: Is called to show the mouse cursor. The mouse kernel manages a
|
||||
@@ -339,15 +371,16 @@ HIDE:
|
||||
; no special action is required besides enabling the mouse cursor.
|
||||
; No return code required.
|
||||
SHOW:
|
||||
php
|
||||
sei
|
||||
jsr CSHOW
|
||||
cli
|
||||
plp
|
||||
rts
|
||||
|
||||
; BUTTONS: Return the button mask in A/X.
|
||||
BUTTONS:
|
||||
lda info + MOUSE_INFO::BUTTONS
|
||||
ldx #$00
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
|
||||
@@ -360,12 +393,13 @@ POS:
|
||||
; struct pointed to by ptr1. No return code required.
|
||||
INFO:
|
||||
ldy #.sizeof(MOUSE_INFO)-1
|
||||
copy: sei
|
||||
copy: php
|
||||
sei
|
||||
: lda info,y
|
||||
sta (ptr1),y
|
||||
dey
|
||||
bpl :-
|
||||
cli
|
||||
plp
|
||||
rts
|
||||
|
||||
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
|
||||
25
libsrc/apple2/mouseref.s
Normal file
25
libsrc/apple2/mouseref.s
Normal file
@@ -0,0 +1,25 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2025-05-11
|
||||
;
|
||||
|
||||
.export mouse_libref
|
||||
.import _get_tv, ostype, return0
|
||||
|
||||
.constructor init_mousetv
|
||||
|
||||
.include "get_tv.inc"
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
.proc init_mousetv
|
||||
lda ostype
|
||||
cmp #$40 ; Technical notes say not to change
|
||||
bcs :+ ; interrupt rate on IIc/IIgs, so...
|
||||
jsr _get_tv
|
||||
sta mouse_libref
|
||||
: rts ; ...don't update "Other" on those machines
|
||||
.endproc
|
||||
|
||||
.data
|
||||
|
||||
mouse_libref: .byte TV::OTHER
|
||||
@@ -1,27 +1,26 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 08.08.1998
|
||||
; Colin Leroy-Mira, 26.05.2025
|
||||
;
|
||||
; void __fastcall__ chlinexy (unsigned char x, unsigned char y, unsigned char length);
|
||||
; void __fastcall__ chline (unsigned char length);
|
||||
; void __fastcall__ mt_chlinexy (unsigned char x, unsigned char y, unsigned char length);
|
||||
; void __fastcall__ mt_chline (unsigned char length);
|
||||
;
|
||||
|
||||
.export _chlinexy, _chline, chlinedirect
|
||||
.ifdef __APPLE2ENH__
|
||||
|
||||
.export _mt_chlinexy, _mt_chline, chlinedirect
|
||||
.import gotoxy, cputdirect
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
_chlinexy:
|
||||
_mt_chlinexy:
|
||||
pha ; Save the length
|
||||
jsr gotoxy ; Call this one, will pop params
|
||||
pla ; Restore the length and run into _chline
|
||||
|
||||
_chline:
|
||||
.ifdef __APPLE2ENH__
|
||||
_mt_chline:
|
||||
ldx #'_' | $80 ; Underscore, screen code
|
||||
.else
|
||||
ldx #'-' | $80 ; Minus, screen code
|
||||
.endif
|
||||
|
||||
chlinedirect:
|
||||
stx tmp1
|
||||
@@ -33,3 +32,5 @@ chlinedirect:
|
||||
dec tmp2
|
||||
bne :-
|
||||
done: rts
|
||||
|
||||
.endif
|
||||
@@ -1,34 +1,32 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 08.08.1998
|
||||
; Colin Leroy-Mira, 26.05.2025
|
||||
;
|
||||
; void __fastcall__ cvlinexy (unsigned char x, unsigned char y, unsigned char length);
|
||||
; void __fastcall__ cvline (unsigned char length);
|
||||
; void __fastcall__ mt_cvlinexy (unsigned char x, unsigned char y, unsigned char length);
|
||||
; void __fastcall__ mt_cvline (unsigned char length);
|
||||
;
|
||||
|
||||
.export _cvlinexy, _cvline
|
||||
.ifdef __APPLE2ENH__
|
||||
|
||||
.export _mt_cvlinexy, _mt_cvline
|
||||
.import gotoxy, putchar, newline
|
||||
|
||||
.include "zeropage.inc"
|
||||
|
||||
_cvlinexy:
|
||||
_mt_cvlinexy:
|
||||
pha ; Save the length
|
||||
jsr gotoxy ; Call this one, will pop params
|
||||
pla ; Restore the length and run into _cvline
|
||||
|
||||
_cvline:
|
||||
.ifdef __APPLE2ENH__
|
||||
ldx #$5F ; Left vertical line MouseText character
|
||||
.else
|
||||
ldx #'!' | $80 ; Exclamation mark, screen code
|
||||
.endif
|
||||
|
||||
stx tmp1
|
||||
_mt_cvline:
|
||||
cmp #$00 ; Is the length zero?
|
||||
beq done ; Jump if done
|
||||
sta tmp2
|
||||
: lda tmp1 ; Screen code
|
||||
: lda #$5F ; Left vertical line MouseText character
|
||||
jsr putchar ; Write, no cursor advance
|
||||
jsr newline ; Advance cursor to next line
|
||||
dec tmp2
|
||||
bne :-
|
||||
done: rts
|
||||
|
||||
.endif
|
||||
@@ -18,6 +18,7 @@
|
||||
.include "fcntl.inc"
|
||||
.include "mli.inc"
|
||||
.include "filedes.inc"
|
||||
.include "time.inc"
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
@@ -64,7 +65,7 @@ _open:
|
||||
errno: jsr incsp4 ; Preserves A
|
||||
|
||||
; Set __errno
|
||||
jmp __directerrno
|
||||
jmp ___directerrno
|
||||
|
||||
; Save fdtab slot
|
||||
found: tya
|
||||
@@ -147,8 +148,8 @@ oserr1: ldy tmp2 ; Restore fdtab slot
|
||||
jsr freebuffer
|
||||
pla ; Restore oserror code
|
||||
|
||||
; Set __oserror
|
||||
jmp __mappederrno
|
||||
; Set ___oserror
|
||||
jmp ___mappederrno
|
||||
|
||||
open: ldy tmp2 ; Restore fdtab slot
|
||||
|
||||
@@ -208,8 +209,8 @@ done: lda tmp1 ; Restore fd
|
||||
jsr popname ; Preserves A
|
||||
|
||||
; Return success
|
||||
ldx #$00
|
||||
stx __oserror
|
||||
ldx #>$0000
|
||||
stx ___oserror
|
||||
rts
|
||||
|
||||
freebuffer:
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* opendir.h */
|
||||
/* */
|
||||
/* Open a directory */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include "dir.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
extern char _cwd[FILENAME_MAX];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
DIR* __fastcall__ opendir (register const char* name)
|
||||
{
|
||||
register DIR* dir;
|
||||
|
||||
/* Alloc DIR */
|
||||
if ((dir = malloc (sizeof (*dir))) == NULL) {
|
||||
|
||||
/* May not have been done by malloc() */
|
||||
_directerrno (ENOMEM);
|
||||
|
||||
/* Return failure */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Interpret dot as current working directory */
|
||||
if (*name == '.') {
|
||||
name = _cwd;
|
||||
}
|
||||
|
||||
/* Open directory file */
|
||||
if ((dir->fd = open (name, O_RDONLY)) != -1) {
|
||||
|
||||
/* Read directory key block */
|
||||
if (read (dir->fd,
|
||||
dir->block.bytes,
|
||||
sizeof (dir->block)) == sizeof (dir->block)) {
|
||||
|
||||
/* Get directory entry infos from directory header */
|
||||
dir->entry_length = dir->block.bytes[0x23];
|
||||
dir->entries_per_block = dir->block.bytes[0x24];
|
||||
|
||||
/* Skip directory header entry */
|
||||
dir->current_entry = 1;
|
||||
|
||||
/* Return success */
|
||||
return dir;
|
||||
}
|
||||
|
||||
/* EOF: Most probably no directory file at all */
|
||||
if (_oserror == 0) {
|
||||
_directerrno (EINVAL);
|
||||
}
|
||||
|
||||
/* Cleanup directory file */
|
||||
close (dir->fd);
|
||||
}
|
||||
|
||||
/* Cleanup DIR */
|
||||
free (dir);
|
||||
|
||||
/* Return failure */
|
||||
return NULL;
|
||||
}
|
||||
159
libsrc/apple2/opendir.s
Normal file
159
libsrc/apple2/opendir.s
Normal file
@@ -0,0 +1,159 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; DIR* __fastcall__ opendir (register const char* name)
|
||||
;
|
||||
|
||||
.export _opendir, read_dir_block_ptr1
|
||||
|
||||
.import closedir_ptr1
|
||||
.import _open, _read, _close
|
||||
.import _malloc
|
||||
.import ___directerrno
|
||||
|
||||
.import ___oserror, __cwd
|
||||
|
||||
.import pushptr1, popptr1
|
||||
.import pushax, pusha0
|
||||
.import return0, returnFFFF
|
||||
|
||||
.importzp ptr1
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "dir.inc"
|
||||
.include "errno.inc"
|
||||
.include "fcntl.inc"
|
||||
.include "zeropage.inc"
|
||||
|
||||
.proc _opendir
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
ldy #$00
|
||||
lda (ptr1),y
|
||||
cmp #'.'
|
||||
bne :+
|
||||
|
||||
lda #<__cwd
|
||||
ldx #>__cwd
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
: ; Open directory
|
||||
jsr pushptr1
|
||||
lda #O_RDONLY
|
||||
jsr pusha0
|
||||
|
||||
ldy #$04
|
||||
jsr _open
|
||||
|
||||
cmp #$FF ; Did we succeed?
|
||||
beq @return_null
|
||||
pha ; Yes - Push fd for backup
|
||||
|
||||
; malloc the dir struct
|
||||
lda #<.sizeof(DIR)
|
||||
ldx #>.sizeof(DIR)
|
||||
jsr _malloc
|
||||
bne :+
|
||||
|
||||
; We failed to allocate
|
||||
pla ; Get fd back
|
||||
ldx #$00
|
||||
jsr _close ; Close it
|
||||
|
||||
lda #ENOMEM ; Set error
|
||||
jsr ___directerrno
|
||||
@return_null:
|
||||
jmp return0
|
||||
|
||||
: ; Store dir struct to pointer
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
; Save fd to dir struct
|
||||
lda #$00
|
||||
ldy #DIR::FD + 1
|
||||
sta (ptr1),y
|
||||
|
||||
dey
|
||||
pla ; Get fd back
|
||||
sta (ptr1),y
|
||||
|
||||
jsr read_dir_block_ptr1
|
||||
bcc @read_ok
|
||||
|
||||
; Close directory, free it
|
||||
jsr closedir_ptr1
|
||||
jmp return0 ; Return NULL
|
||||
|
||||
@read_ok:
|
||||
; Read succeeded, populate dir struct
|
||||
|
||||
; Get file_count to entry_length from block
|
||||
ldy #$26 + DIR::BYTES
|
||||
: lda (ptr1),y
|
||||
pha
|
||||
dey
|
||||
cpy #$23 + DIR::BYTES - 1
|
||||
bne :-
|
||||
|
||||
; Set entry_length to file_count in struct
|
||||
ldy #DIR::ENTRY_LENGTH
|
||||
: pla
|
||||
sta (ptr1),y
|
||||
iny
|
||||
cpy #DIR::CURRENT_ENTRY
|
||||
bne :-
|
||||
|
||||
; Skip directory header entry
|
||||
lda #$01
|
||||
sta (ptr1),y
|
||||
|
||||
; Return pointer to dir struct
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
rts
|
||||
.endproc
|
||||
|
||||
; Read a directory for the DIR* pointer in ptr1
|
||||
; Return with carry clear on success
|
||||
read_dir_block_ptr1:
|
||||
; Push ptr1, read will destroy it
|
||||
jsr pushptr1
|
||||
|
||||
ldy #DIR::FD
|
||||
lda (ptr1),y
|
||||
|
||||
jsr pusha0 ; Push fd for read
|
||||
lda #<DIR::BYTES
|
||||
clc
|
||||
adc ptr1
|
||||
pha
|
||||
lda #>DIR::BYTES
|
||||
adc ptr1+1
|
||||
tax
|
||||
pla
|
||||
jsr pushax ; Push dir->block.bytes for read
|
||||
|
||||
lda #<.sizeof(DIR::BYTES)
|
||||
ldx #>.sizeof(DIR::BYTES)
|
||||
|
||||
jsr _read ; Read directory block
|
||||
cpx #>.sizeof(DIR::BYTES)
|
||||
bne @read_err
|
||||
cmp #<.sizeof(DIR::BYTES)
|
||||
beq @read_ok
|
||||
|
||||
@read_err:
|
||||
; Read failed, exit
|
||||
lda ___oserror
|
||||
bne :+
|
||||
lda #EINVAL
|
||||
jsr ___directerrno
|
||||
: sec
|
||||
bcs @out
|
||||
@read_ok:
|
||||
clc
|
||||
@out:
|
||||
jmp popptr1
|
||||
@@ -1,14 +1,14 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 17.05.2000
|
||||
;
|
||||
; int __fastcall__ _osmaperrno (unsigned char oserror);
|
||||
; int __fastcall__ __osmaperrno (unsigned char oserror);
|
||||
;
|
||||
|
||||
.export __osmaperrno
|
||||
.export ___osmaperrno
|
||||
|
||||
.include "errno.inc"
|
||||
|
||||
__osmaperrno:
|
||||
___osmaperrno:
|
||||
ldx #ErrTabSize
|
||||
: cmp ErrTab-2,x ; Search for the error code
|
||||
beq :+ ; Jump if found
|
||||
@@ -23,7 +23,7 @@ __osmaperrno:
|
||||
|
||||
; Found the code
|
||||
: lda ErrTab-1,x
|
||||
ldx #$00 ; High byte always zero
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
.rodata
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 07.11.2002
|
||||
;
|
||||
; void _randomize (void);
|
||||
; void __randomize (void);
|
||||
; /* Initialize the random number generator */
|
||||
;
|
||||
|
||||
.export __randomize
|
||||
.export ___randomize
|
||||
.import _srand
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
__randomize:
|
||||
___randomize:
|
||||
ldx RNDH ; Use random value supplied by ROM
|
||||
lda RNDL
|
||||
jmp _srand ; Initialize generator
|
||||
|
||||
@@ -19,11 +19,14 @@
|
||||
.segment "ONCE"
|
||||
|
||||
initprompt:
|
||||
; Set prompt <> ']' to let DOS 3.3 know that we're
|
||||
; not in Applesoft immediate mode and thus keep it
|
||||
; from scanning our device I/O for DOS commands.
|
||||
; Set prompt <> ']' and currently executed Applesoft
|
||||
; line number hibyte <> $FF to let DOS 3.3 (at $A65E)
|
||||
; know that we're not in Applesoft immediate mode and
|
||||
; thus keep it from scanning our device I/O for DOS
|
||||
; commands.
|
||||
lda #$80 ; Same value used at $D52C
|
||||
sta PROMPT
|
||||
sta CURLIN+1 ; Any value <> $FF will do
|
||||
rts
|
||||
|
||||
.code
|
||||
@@ -49,7 +52,7 @@ _read:
|
||||
|
||||
; Device succeeds always
|
||||
device: lda #$00
|
||||
sta __oserror
|
||||
sta ___oserror
|
||||
|
||||
; Set counter to zero
|
||||
sta ptr3
|
||||
@@ -104,4 +107,4 @@ check: lda ptr3
|
||||
einval: lda #EINVAL
|
||||
|
||||
; Set __errno
|
||||
errno: jmp __directerrno
|
||||
errno: jmp ___directerrno
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* readdir.c */
|
||||
/* */
|
||||
/* Read directory entry */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include "dir.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
struct dirent* __fastcall__ readdir (register DIR* dir)
|
||||
{
|
||||
register unsigned char* entry;
|
||||
|
||||
/* Search for the next active directory entry */
|
||||
do {
|
||||
|
||||
/* Read next directory block if necessary */
|
||||
if (dir->current_entry == dir->entries_per_block) {
|
||||
if (read (dir->fd,
|
||||
dir->block.bytes,
|
||||
sizeof (dir->block)) != sizeof (dir->block)) {
|
||||
|
||||
/* Just return failure as read() has */
|
||||
/* set errno if (and only if) no EOF */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Start with first entry in next block */
|
||||
dir->current_entry = 0;
|
||||
}
|
||||
|
||||
/* Compute pointer to current entry */
|
||||
entry = dir->block.content.entries +
|
||||
dir->current_entry * dir->entry_length;
|
||||
|
||||
/* Switch to next entry */
|
||||
++dir->current_entry;
|
||||
} while (entry[0x00] == 0);
|
||||
|
||||
/* Move creation date/time to allow for next step below */
|
||||
*(unsigned long*)&entry[0x1A] = *(unsigned long*)&entry[0x18];
|
||||
|
||||
/* Feature unsigned long access to EOF by extension from 3 to 4 bytes */
|
||||
entry[0x18] = 0;
|
||||
|
||||
/* Move file type to allow for next step below */
|
||||
entry[0x19] = entry[0x10];
|
||||
|
||||
/* Zero-terminate file name */
|
||||
entry[0x01 + (entry[0x00] & 0x0F)] = 0;
|
||||
|
||||
/* Return success */
|
||||
return (struct dirent*)&entry[0x01];
|
||||
}
|
||||
113
libsrc/apple2/readdir.s
Normal file
113
libsrc/apple2/readdir.s
Normal file
@@ -0,0 +1,113 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; struct dirent * __fastcall__ readdir (DIR *dir)
|
||||
;
|
||||
.export _readdir
|
||||
.import read_dir_block_ptr1
|
||||
|
||||
.import incax1, return0
|
||||
.import tosaddax, tosumula0, incaxy
|
||||
.import pushax, pusha0, pushptr1, popptr1
|
||||
.importzp ptr1, ptr4
|
||||
|
||||
.include "dir.inc"
|
||||
|
||||
.proc _readdir
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
|
||||
@next_entry:
|
||||
; Do we need to read the next directory block?
|
||||
ldy #DIR::CURRENT_ENTRY
|
||||
lda (ptr1),y
|
||||
ldy #DIR::ENTRIES_PER_BLOCK
|
||||
cmp (ptr1),y
|
||||
bne @read_entry ; We don't
|
||||
|
||||
jsr read_dir_block_ptr1
|
||||
bcc @read_ok
|
||||
|
||||
; We had a read error
|
||||
jmp return0
|
||||
|
||||
@read_ok:
|
||||
ldy #DIR::CURRENT_ENTRY
|
||||
lda #$00
|
||||
sta (ptr1),y
|
||||
|
||||
@read_entry:
|
||||
; Compute pointer to current entry:
|
||||
; entry = dir->block.content.entries +
|
||||
; dir->current_entry * dir->entry_length
|
||||
|
||||
jsr pushptr1 ; Backup ptr1
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
ldy #DIR::BYTES + DIR::CONTENT::ENTRIES
|
||||
jsr incaxy
|
||||
jsr pushax
|
||||
ldy #DIR::CURRENT_ENTRY
|
||||
lda (ptr1),y
|
||||
jsr pusha0
|
||||
ldy #DIR::ENTRY_LENGTH
|
||||
lda (ptr1),y
|
||||
jsr tosumula0
|
||||
jsr tosaddax
|
||||
; Store pointer to current entry
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
jsr popptr1
|
||||
|
||||
; Switch to next entry
|
||||
ldy #DIR::CURRENT_ENTRY
|
||||
lda (ptr1),y
|
||||
clc
|
||||
adc #1
|
||||
sta (ptr1),y
|
||||
|
||||
; Check if entry[0] == 0
|
||||
ldy #$00
|
||||
lda (ptr4),y
|
||||
beq @next_entry ; Yes, skip entry
|
||||
|
||||
; Move creation date/time to allow for next step below
|
||||
; 18-19-1A-1B => 1A-1B-1C-1D
|
||||
ldy #$1B
|
||||
: lda (ptr4),y
|
||||
iny
|
||||
iny
|
||||
sta (ptr4),y
|
||||
dey
|
||||
dey
|
||||
dey
|
||||
cpy #$17
|
||||
bne :-
|
||||
|
||||
; Feature unsigned long access to EOF by extension from 3 to 4 bytes
|
||||
; entry[0x18] = 0
|
||||
iny
|
||||
lda #$00
|
||||
sta (ptr4),y
|
||||
|
||||
; Move file type to allow for next step below
|
||||
; entry[0x19] = entry[0x10]
|
||||
ldy #$10
|
||||
lda (ptr4),y
|
||||
ldy #$19
|
||||
sta (ptr4),y
|
||||
|
||||
; Zero-terminate file name
|
||||
ldy #$00
|
||||
lda (ptr4),y
|
||||
and #$0F
|
||||
tay
|
||||
iny
|
||||
lda #$00
|
||||
sta (ptr4),y
|
||||
|
||||
; Return pointer to entry+1
|
||||
lda ptr4
|
||||
ldx ptr4+1
|
||||
jmp incax1
|
||||
.endproc
|
||||
@@ -18,5 +18,5 @@ normal: dex ; $00->$FF, $40->$3F
|
||||
stx INVFLG ; Save new flag value
|
||||
bmi :+ ; Jump if current value is $FF (normal)
|
||||
lda #$01 ; Return "inverse"
|
||||
: ldx #$00
|
||||
: ldx #>$0000
|
||||
rts
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* rewinddir.c */
|
||||
/* */
|
||||
/* Reset directory stream */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2005 Oliver Schmidt, <ol.sc@web.de> */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include "dir.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void __fastcall__ rewinddir (register DIR* dir)
|
||||
{
|
||||
/* Rewind directory file */
|
||||
if (lseek (dir->fd, 0, SEEK_SET)) {
|
||||
|
||||
/* Read directory key block */
|
||||
if (read (dir->fd,
|
||||
dir->block.bytes,
|
||||
sizeof (dir->block)) == sizeof (dir->block)) {
|
||||
|
||||
/* Skip directory header entry */
|
||||
dir->current_entry = 1;
|
||||
|
||||
/* Return success */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Assert that no subsequent readdir() finds an active entry */
|
||||
memset (dir->block.bytes, 0, sizeof (dir->block));
|
||||
|
||||
/* Return failure */
|
||||
}
|
||||
70
libsrc/apple2/rewinddir.s
Normal file
70
libsrc/apple2/rewinddir.s
Normal file
@@ -0,0 +1,70 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; void __fastcall__ rewinddir (DIR* dir)
|
||||
;
|
||||
.export _rewinddir
|
||||
.import read_dir_block_ptr1
|
||||
|
||||
.import pusha, pusha0, pushax
|
||||
.import pushptr1, popptr1
|
||||
.import incaxy
|
||||
.import _lseek, _memset
|
||||
|
||||
.importzp ptr1, sreg
|
||||
|
||||
.include "dir.inc"
|
||||
.include "stdio.inc"
|
||||
|
||||
.proc _rewinddir
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
jsr pushptr1 ; Backup ptr1, destroyed by _lseek
|
||||
|
||||
; Rewind directory file
|
||||
ldy #DIR::FD
|
||||
lda (ptr1),y
|
||||
jsr pusha0 ; Push dir->fd
|
||||
|
||||
tya ; Y = 0 here
|
||||
jsr pusha0
|
||||
jsr pusha0 ; Push 0L
|
||||
|
||||
lda #SEEK_SET ; X = 0 here
|
||||
jsr _lseek
|
||||
|
||||
ora sreg ; Check lseek returned 0L
|
||||
ora sreg+1
|
||||
bne @rewind_err
|
||||
txa
|
||||
bne @rewind_err
|
||||
|
||||
jsr popptr1 ; Restore ptr1
|
||||
|
||||
; Read directory key block
|
||||
jsr read_dir_block_ptr1
|
||||
bcs @rewind_err
|
||||
|
||||
; Skip directory header entry
|
||||
lda #$01
|
||||
ldy #DIR::CURRENT_ENTRY
|
||||
sta (ptr1),y
|
||||
rts
|
||||
|
||||
@rewind_err:
|
||||
jsr popptr1 ; Restore ptr1
|
||||
|
||||
; Assert that no subsequent readdir() finds an active entry
|
||||
lda ptr1
|
||||
ldx ptr1+1
|
||||
ldy #DIR::BYTES + DIR::CONTENT::ENTRIES
|
||||
jsr incaxy
|
||||
jsr pushax
|
||||
|
||||
lda #$00
|
||||
jsr pusha
|
||||
|
||||
lda #<.sizeof(DIR::BYTES)
|
||||
ldx #>.sizeof(DIR::BYTES)
|
||||
jmp _memset
|
||||
.endproc
|
||||
@@ -49,10 +49,10 @@ rwcommon:
|
||||
|
||||
rwepilog:
|
||||
; Return success
|
||||
sta __oserror ; A = 0
|
||||
sta ___oserror ; A = 0
|
||||
lda mliparam + MLI::RW::TRANS_COUNT
|
||||
ldx mliparam + MLI::RW::TRANS_COUNT+1
|
||||
rts
|
||||
|
||||
; Set __oserror
|
||||
oserr: jmp __mappederrno
|
||||
; Set ___oserror
|
||||
oserr: jmp ___mappederrno
|
||||
|
||||
752
libsrc/apple2/ser/a2.gs.s
Normal file
752
libsrc/apple2/ser/a2.gs.s
Normal file
@@ -0,0 +1,752 @@
|
||||
;
|
||||
; Serial driver for the Apple IIgs Zilog Z8530.
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2023
|
||||
;
|
||||
; This software is licensed under the same license as cc65,
|
||||
; the zlib license (see LICENSE file).
|
||||
;
|
||||
; Documentation from http://www.applelogic.org/files/Z8530UM.pdf (pages
|
||||
; referred to where applicable)
|
||||
; and https://gswv.apple2.org.za/a2zine/Utils/Z8530_SCCsamples_info.txt
|
||||
|
||||
|
||||
|
||||
.setcpu "65816"
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "ser-kernel.inc"
|
||||
.include "ser-error.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.ifdef __APPLE2ENH__
|
||||
module_header _a2e_gs_ser
|
||||
.else
|
||||
module_header _a2_gs_ser
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
.byte SER_API_VERSION ; Serial API version number
|
||||
|
||||
; Library reference
|
||||
.addr $0000
|
||||
|
||||
; Jump table
|
||||
.addr SER_INSTALL
|
||||
.addr SER_UNINSTALL
|
||||
.addr SER_OPEN
|
||||
.addr SER_CLOSE
|
||||
.addr SER_GET
|
||||
.addr SER_PUT
|
||||
.addr SER_STATUS
|
||||
.addr SER_IOCTL
|
||||
.addr SER_IRQ
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Global variables
|
||||
|
||||
.bss
|
||||
|
||||
RecvHead: .res 1 ; Head of receive buffer
|
||||
RecvTail: .res 1 ; Tail of receive buffer
|
||||
RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
|
||||
SendHead: .res 1 ; Head of send buffer
|
||||
SendTail: .res 1 ; Tail of send buffer
|
||||
SendFreeCnt: .res 1 ; Number of bytes in send buffer
|
||||
|
||||
Stopped: .res 1 ; Flow-stopped flag
|
||||
RtsOff: .res 1
|
||||
HSType: .res 1 ; Flow-control type
|
||||
|
||||
RecvBuf: .res 256 ; Receive buffers: 256 bytes
|
||||
SendBuf: .res 256 ; Send buffers: 256 bytes
|
||||
|
||||
CurClockSource: .res 1 ; Whether to use BRG or RTxC for clock
|
||||
|
||||
.data
|
||||
|
||||
Opened: .byte $00 ; 1 when opened
|
||||
Channel: .byte $00 ; Channel B by default
|
||||
CurChanIrqFlags:.byte $00
|
||||
|
||||
SerFlagOrig: .byte $00
|
||||
|
||||
RxBitTable: .byte %00000000 ; SER_BITS_5, in WR_RX_CTRL (WR3)
|
||||
.byte %10000000 ; SER_BITS_6 (Ref page 5-7)
|
||||
.byte %01000000 ; SER_BITS_7
|
||||
.byte %11000000 ; SER_BITS_8
|
||||
|
||||
TxBitTable: .byte %00000000 ; SER_BITS_5, in WR_TX_CTRL (WR5)
|
||||
.byte %01000000 ; SER_BITS_6 (Ref page 5-9)
|
||||
.byte %00100000 ; SER_BITS_7
|
||||
.byte %01100000 ; SER_BITS_8
|
||||
|
||||
.rodata
|
||||
|
||||
ClockMultiplier:.byte %01000000 ; Clock x16 (300-57600bps, WR4, ref page 5-8)
|
||||
.byte %10000000 ; Clock x32 (115200bps, ref page 5-8)
|
||||
|
||||
ClockSource: .byte %01010000 ; Use baud rate generator (ch. B) (WR11, page 5-17)
|
||||
.byte %00000000 ; Use RTxC (115200bps) (ch. B)
|
||||
.byte %11010000 ; Use baud rate generator (ch. A)
|
||||
.byte %10000000 ; Use RTxC (115200bps) (ch. A)
|
||||
|
||||
BrgEnabled: .byte %00000001 ; Baud rate generator on (WR14, page 5-19)
|
||||
.byte %00000000 ; BRG Off
|
||||
|
||||
ChanIrqFlags: .byte %00000101 ; ANDed (RX/special IRQ, ch. B) (page 5-25)
|
||||
.byte %00101000 ; ANDed (RX/special IRQ, ch. A)
|
||||
|
||||
ChanIrqMask: .byte %00000111 ; Ch. B IRQ flags mask
|
||||
.byte %00111000 ; Ch. A IRQ flags mask
|
||||
|
||||
BaudTable: ; bit7 = 1 means setting is invalid
|
||||
; Indexes cc65 RS232 SER_BAUD enum
|
||||
; into WR12/13 register values
|
||||
; (Ref page 5-18 and 5-19)
|
||||
.word $FFFF ; SER_BAUD_45_5
|
||||
.word $FFFF ; SER_BAUD_50
|
||||
.word $FFFF ; SER_BAUD_75
|
||||
.word $FFFF ; SER_BAUD_110
|
||||
.word $FFFF ; SER_BAUD_134_5
|
||||
.word $FFFF ; SER_BAUD_150
|
||||
.word $017E ; SER_BAUD_300
|
||||
.word $FFFF ; SER_BAUD_600
|
||||
.word $005E ; SER_BAUD_1200
|
||||
.word $FFFF ; SER_BAUD_1800
|
||||
.word $002E ; SER_BAUD_2400
|
||||
.word $FFFF ; SER_BAUD_3600
|
||||
.word $0016 ; SER_BAUD_4800
|
||||
.word $FFFF ; SER_BAUD_7200
|
||||
.word $000A ; SER_BAUD_9600
|
||||
.word $0004 ; SER_BAUD_19200
|
||||
.word $0001 ; SER_BAUD_38400
|
||||
.word $0000 ; SER_BAUD_57600
|
||||
.word $0000 ; SER_BAUD_115200 (constant unused at that speed)
|
||||
.word $FFFF ; SER_BAUD_230400
|
||||
|
||||
; About the speed selection: either we use the baud rate generator:
|
||||
; - Load the time constants from BaudTable into WR12/WR13
|
||||
; - Setup the TX/RX clock source to BRG (ClockSource into WR11)
|
||||
; - Setup the clock multiplier (WR4)
|
||||
; - Enable the baud rate generator (WR14)
|
||||
; In this case, the baud rate will be:
|
||||
; rate = crystal_clock/(2+BRG_time_constant))/(2*clock_multiplier)
|
||||
; Example: (3686400/(2+0x0004)) / (2*16) = 19200 bps
|
||||
;
|
||||
; Or we don't use the baud rate generator:
|
||||
; - Setup the TX/RX clock source to RTxC
|
||||
; - Setup the clock multiplier
|
||||
; - Disable the baud rate generator
|
||||
; - WR12 and 13 are ignored
|
||||
; In this case, the baud rate will be:
|
||||
; rate = crystal_clock/clock_multiplier
|
||||
; Example: 3686400/32 = 115200 bps
|
||||
|
||||
StopTable: .byte %00000100 ; SER_STOP_1, in WR_TX_RX_CTRL (WR4)
|
||||
.byte %00001100 ; SER_STOP_2 (Ref page 5-8)
|
||||
|
||||
ParityTable: .byte %00000000 ; SER_PAR_NONE, in WR_TX_RX_CTRL (WR4)
|
||||
.byte %00000001 ; SER_PAR_ODD (Ref page 5-8)
|
||||
.byte %00000011 ; SER_PAR_EVEN
|
||||
.byte $FF ; SER_PAR_MARK
|
||||
.byte $FF ; SER_PAR_SPACE
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Addresses
|
||||
|
||||
SCCAREG := $C039
|
||||
SCCBREG := $C038
|
||||
SCCADATA := $C03B
|
||||
SCCBDATA := $C03A
|
||||
|
||||
; We're supposed to get SerFlag's address using GetAddr on ROMs 1 and 3.
|
||||
; (https://archive.org/details/IIgs_2523018_SCC_Access, page 9)
|
||||
; But, it's the same value as on ROM0. As we don't expect a ROM 4 anytime
|
||||
; soon with a different value, let's keep it simple.
|
||||
|
||||
SER_FLAG := $E10104
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Channels
|
||||
|
||||
CHANNEL_B = 0
|
||||
CHANNEL_A = 1
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Write registers, read registers, and values that interest us
|
||||
|
||||
WR_INIT_CTRL = 0
|
||||
RR_INIT_STATUS = 0
|
||||
INIT_CTRL_CLEAR_EIRQ = %00010000
|
||||
INIT_CTRL_CLEAR_ERR = %00110000
|
||||
INIT_STATUS_READY = %00000100
|
||||
INIT_STATUS_RTS = %00100000
|
||||
|
||||
WR_TX_RX_MODE_CTRL = 1
|
||||
TX_RX_MODE_OFF = %00000000
|
||||
TX_RX_MODE_RXIRQ = %00010001
|
||||
|
||||
WR_RX_CTRL = 3 ; (Ref page 5-7)
|
||||
RR_RX_STATUS = 9 ; Corresponding status register
|
||||
RX_CTRL_ON = %00000001 ; ORed, Rx enabled
|
||||
RX_CTRL_OFF = %11111110 ; ANDed,Rx disabled
|
||||
|
||||
WR_TX_RX_CTRL = 4
|
||||
RR_TX_RX_STATUS = 4
|
||||
|
||||
WR_TX_CTRL = 5 ; (Ref page 5-9)
|
||||
RR_TX_STATUS = 5 ; Corresponding status register
|
||||
TX_CTRL_ON = %00001000 ; ORed, Tx enabled
|
||||
TX_CTRL_OFF = %11110111 ; ANDed,Tx disabled
|
||||
TX_DTR_ON = %01111111 ; ANDed,DTR ON (high)
|
||||
TX_DTR_OFF = %10000000 ; ORed, DTR OFF
|
||||
TX_RTS_ON = %00000010 ; ORed, RTS ON (low)
|
||||
TX_RTS_OFF = %11111101 ; ANDed, RTS OFF
|
||||
|
||||
WR_MASTER_IRQ_RST = 9 ; (Ref page 5-14)
|
||||
MASTER_IRQ_SHUTDOWN = %00000010 ; STA'd
|
||||
MASTER_IRQ_MIE_RST = %00001010 ; STA'd
|
||||
MASTER_IRQ_SET = %00011001 ; STA'd
|
||||
|
||||
WR_CLOCK_CTRL = 11 ; (Ref page 5-17)
|
||||
|
||||
WR_BAUDL_CTRL = 12 ; (Ref page 5-18)
|
||||
WR_BAUDH_CTRL = 13 ; (Ref page 5-19)
|
||||
|
||||
WR_MISC_CTRL = 14 ; (Ref page 5-19)
|
||||
|
||||
WR_IRQ_CTRL = 15 ; (Ref page 5-20)
|
||||
IRQ_CLEANUP_EIRQ = %00001000
|
||||
|
||||
RR_SPEC_COND_STATUS = 1 ; (Ref page 5-23)
|
||||
SPEC_COND_FRAMING_ERR = %01000000
|
||||
SPEC_COND_OVERRUN_ERR = %00100000
|
||||
|
||||
RR_IRQ_STATUS = 2 ; (Ref page 5-24)
|
||||
IRQ_MASQ = %01110000 ; ANDed
|
||||
IRQ_RX = %00100000
|
||||
IRQ_SPECIAL = %01100000
|
||||
|
||||
RR_INTR_PENDING_STATUS = 3 ; (Ref page 5-25)
|
||||
INTR_IS_RX = %00100100 ; ANDed (RX IRQ, channel A or B)
|
||||
|
||||
.code
|
||||
|
||||
; Read register value to A.
|
||||
; Input: X as channel
|
||||
; Y as register
|
||||
; Output: A
|
||||
readSSCReg:
|
||||
cpx #0
|
||||
bne ReadAreg
|
||||
sty SCCBREG
|
||||
lda SCCBREG
|
||||
rts
|
||||
ReadAreg:
|
||||
sty SCCAREG
|
||||
lda SCCAREG
|
||||
rts
|
||||
|
||||
; Write value of A to a register.
|
||||
; Input: X as channel
|
||||
; Y as register
|
||||
writeSCCReg:
|
||||
cpx #0
|
||||
bne WriteAreg
|
||||
sty SCCBREG
|
||||
sta SCCBREG
|
||||
rts
|
||||
WriteAreg:
|
||||
sty SCCAREG
|
||||
sta SCCAREG
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_INSTALL: Is called after the driver is loaded into memory. If possible,
|
||||
; check if the hardware is present. Must return an SER_ERR_xx code in a/x.
|
||||
;
|
||||
; Since we don't have to manage the IRQ vector on the Apple II, this is
|
||||
; actually the same as:
|
||||
;
|
||||
; SER_UNINSTALL: Is called before the driver is removed from memory.
|
||||
; No return code required (the driver is removed from memory on return).
|
||||
;
|
||||
; and:
|
||||
;
|
||||
; SER_CLOSE: Close the port and disable interrupts. Called without parameters.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
SER_INSTALL:
|
||||
SER_UNINSTALL:
|
||||
SER_CLOSE:
|
||||
; Check if this is a IIgs (Apple II Miscellaneous TechNote #7,
|
||||
; Apple II Family Identification)
|
||||
sec
|
||||
bit $C082
|
||||
jsr $FE1F
|
||||
bit $C080
|
||||
|
||||
bcc IIgs
|
||||
|
||||
lda #SER_ERR_NO_DEVICE ; Not a IIgs
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
IIgs:
|
||||
ldx Opened ; Check for open port
|
||||
beq :+
|
||||
|
||||
ldx Channel
|
||||
|
||||
php ; Deactivate interrupts
|
||||
sei ; if enabled
|
||||
|
||||
ldy #WR_MASTER_IRQ_RST
|
||||
lda #MASTER_IRQ_SHUTDOWN
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #WR_TX_RX_MODE_CTRL
|
||||
lda #TX_RX_MODE_OFF
|
||||
jsr writeSCCReg
|
||||
|
||||
; Reset SerFlag to what it was
|
||||
lda SerFlagOrig
|
||||
sta SER_FLAG
|
||||
|
||||
lda SCCBDATA
|
||||
|
||||
; Clear external interrupts (twice)
|
||||
ldy #WR_INIT_CTRL
|
||||
lda #INIT_CTRL_CLEAR_EIRQ
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg
|
||||
|
||||
; Reset MIE for firmware use
|
||||
ldy #WR_MASTER_IRQ_RST
|
||||
lda #MASTER_IRQ_MIE_RST
|
||||
jsr writeSCCReg
|
||||
|
||||
ldx #$00
|
||||
stx Opened ; Mark port as closed
|
||||
|
||||
plp ; Reenable interrupts if needed
|
||||
: txa ; Promote char return value
|
||||
rts
|
||||
|
||||
getClockSource:
|
||||
.assert SER_PARAMS::BAUDRATE = 0, error
|
||||
lda (ptr1) ; Baudrate index - cc65 value
|
||||
cmp #SER_BAUD_115200
|
||||
lda #$00
|
||||
adc #$00
|
||||
sta CurClockSource ; 0 = BRG, 1 = RTxC
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
SER_OPEN:
|
||||
php ; Deactivate interrupts
|
||||
sei ; if enabled
|
||||
|
||||
; Check if the handshake setting is valid
|
||||
ldy #SER_PARAMS::HANDSHAKE ; Handshake
|
||||
lda (ptr1),y
|
||||
cmp #SER_HS_SW ; Not supported
|
||||
beq InvParam
|
||||
|
||||
sta HSType ; Store flow control type
|
||||
|
||||
; Initialize buffers
|
||||
ldy #$00
|
||||
sty Stopped
|
||||
sty RecvHead
|
||||
sty RecvTail
|
||||
sty SendHead
|
||||
sty SendTail
|
||||
dey ; Y = 255
|
||||
sty RecvFreeCnt
|
||||
sty SendFreeCnt
|
||||
|
||||
ldx Channel
|
||||
|
||||
ldy #RR_INIT_STATUS ; Hit rr0 once to sync up
|
||||
jsr readSSCReg
|
||||
|
||||
ldy #WR_MISC_CTRL ; WR14: Turn everything off
|
||||
lda #$00
|
||||
jsr writeSCCReg
|
||||
|
||||
jsr getClockSource ; Should we use BRG or RTxC?
|
||||
|
||||
ldy #SER_PARAMS::STOPBITS ; WR4 setup: clock mult., stop & parity
|
||||
lda (ptr1),y ; Stop bits
|
||||
tay
|
||||
lda StopTable,y ; Get value
|
||||
|
||||
pha
|
||||
ldy #SER_PARAMS::PARITY
|
||||
lda (ptr1),y ; Parity bits
|
||||
tay
|
||||
pla
|
||||
ora ParityTable,y ; Get value
|
||||
bmi InvParam
|
||||
|
||||
ldy CurClockSource ; Clock multiplier
|
||||
ora ClockMultiplier,y
|
||||
|
||||
ldy #WR_TX_RX_CTRL
|
||||
jsr writeSCCReg ; End of WR4 setup
|
||||
|
||||
ldy CurClockSource ; WR11 setup: clock source
|
||||
cpx #CHANNEL_B
|
||||
beq SetClock
|
||||
iny ; Shift to get correct ClockSource val
|
||||
iny ; depending on our channel
|
||||
|
||||
SetClock:
|
||||
lda ClockSource,y
|
||||
ldy #WR_CLOCK_CTRL
|
||||
jsr writeSCCReg ; End of WR11 setup
|
||||
|
||||
lda ChanIrqFlags,x ; Store which IRQ bits we'll check
|
||||
sta CurChanIrqFlags
|
||||
|
||||
SetBaud:
|
||||
.assert SER_PARAMS::BAUDRATE = 0, error
|
||||
lda (ptr1) ; Baudrate index - cc65 value
|
||||
asl
|
||||
tay
|
||||
|
||||
lda BaudTable,y ; Get low byte of register value
|
||||
bpl BaudOK ; Verify baudrate is supported
|
||||
|
||||
InvParam:
|
||||
lda #SER_ERR_INIT_FAILED
|
||||
ldy #$00 ; Mark port closed
|
||||
bra SetupOut
|
||||
|
||||
BaudOK:
|
||||
phy ; WR12 setup: BRG time constant, low byte
|
||||
ldy #WR_BAUDL_CTRL ; Setting WR12 & 13 is useless if we're using
|
||||
jsr writeSCCReg ; RTxC, but doing it anyway makes code smaller
|
||||
ply
|
||||
|
||||
iny
|
||||
lda BaudTable,y ; WR13 setup: BRG time constant, high byte
|
||||
ldy #WR_BAUDH_CTRL
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy CurClockSource ; WR14 setup: BRG enabling
|
||||
lda BrgEnabled,y
|
||||
ldy #WR_MISC_CTRL ; Time to turn this thing on
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #SER_PARAMS::DATABITS ; WR3 setup: RX data bits
|
||||
lda (ptr1),y
|
||||
tay
|
||||
lda RxBitTable,y
|
||||
ora #RX_CTRL_ON ; and turn receiver on
|
||||
|
||||
phy
|
||||
ldy #WR_RX_CTRL
|
||||
jsr writeSCCReg ; End of WR3 setup
|
||||
ply
|
||||
|
||||
lda TxBitTable,y ; WR5 setup: TX data bits
|
||||
ora #TX_CTRL_ON ; and turn transmitter on
|
||||
and #TX_DTR_ON ; and turn DTR on
|
||||
|
||||
sta RtsOff ; Save value for flow control
|
||||
|
||||
ora #TX_RTS_ON ; and turn RTS on
|
||||
|
||||
ldy #WR_TX_CTRL
|
||||
jsr writeSCCReg ; End of WR5 setup
|
||||
|
||||
ldy #WR_IRQ_CTRL ; WR15 setup: IRQ
|
||||
lda #IRQ_CLEANUP_EIRQ
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #WR_INIT_CTRL ; WR0 setup: clear existing IRQs
|
||||
lda #INIT_CTRL_CLEAR_EIRQ
|
||||
jsr writeSCCReg ; Clear (write twice)
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #WR_TX_RX_MODE_CTRL ; WR1 setup: Activate RX IRQ
|
||||
lda #TX_RX_MODE_RXIRQ
|
||||
jsr writeSCCReg
|
||||
|
||||
lda SCCBREG ; WR9 setup: Activate master IRQ
|
||||
ldy #WR_MASTER_IRQ_RST
|
||||
lda #MASTER_IRQ_SET
|
||||
jsr writeSCCReg
|
||||
|
||||
lda SER_FLAG ; Get SerFlag's current value
|
||||
sta SerFlagOrig ; and save it
|
||||
|
||||
ora ChanIrqMask,x ; Tell firmware which channel IRQs we want
|
||||
sta SER_FLAG
|
||||
|
||||
ldy #$01 ; Mark port opened
|
||||
lda #SER_ERR_OK
|
||||
|
||||
SetupOut:
|
||||
plp ; Reenable interrupts if needed
|
||||
ldx #>$0000
|
||||
sty Opened
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_GET: Will fetch a character from the receive buffer and store it into the
|
||||
; variable pointed to by ptr1. If no data is available, SER_ERR_NO_DATA is
|
||||
; returned.
|
||||
|
||||
SER_GET:
|
||||
ldx Channel
|
||||
|
||||
lda RecvFreeCnt ; Check for buffer empty
|
||||
cmp #$FF
|
||||
beq NoData
|
||||
|
||||
ldy Stopped ; Check for flow stopped
|
||||
beq :+
|
||||
cmp #63 ; Enough free?
|
||||
bcc :+
|
||||
stz Stopped ; Release flow control
|
||||
|
||||
lda RtsOff
|
||||
ora #TX_RTS_ON
|
||||
|
||||
ldy #WR_TX_CTRL
|
||||
jsr writeSCCReg
|
||||
|
||||
: ldy RecvHead ; Get byte from buffer
|
||||
lda RecvBuf,y
|
||||
inc RecvHead
|
||||
inc RecvFreeCnt
|
||||
sta (ptr1)
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
rts
|
||||
NoData:
|
||||
lda #SER_ERR_NO_DATA
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_PUT: Output character in A.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
SER_PUT:
|
||||
ldx Channel
|
||||
|
||||
ldy SendFreeCnt ; Anything to send first?
|
||||
iny ; Y = $FF?
|
||||
beq :+
|
||||
pha
|
||||
lda #$00 ; TryHard = false
|
||||
jsr TryToSend
|
||||
pla
|
||||
|
||||
: ldy SendFreeCnt ; Do we have room to store byte?
|
||||
bne :+
|
||||
lda #SER_ERR_OVERFLOW
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
: ldy SendTail ; Put byte into send buffer & send
|
||||
sta SendBuf,y
|
||||
inc SendTail
|
||||
dec SendFreeCnt
|
||||
lda #$FF ; TryHard = true
|
||||
jsr TryToSend
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax ; Promote char return value
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_STATUS: Return the status in the variable pointed to by ptr1.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
; We provide the read register 0, containing interesting info like
|
||||
; INIT_STATUS_READY (hardware handshake status) or INIT_STATUS_RTS
|
||||
; (ready to send).
|
||||
|
||||
SER_STATUS:
|
||||
ldx Channel
|
||||
ldy #RR_INIT_STATUS
|
||||
jsr readSSCReg
|
||||
ldx #$00
|
||||
sta (ptr1)
|
||||
.assert SER_ERR_OK = 0, error
|
||||
txa
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; Sets communication channel A or B (A = 1, B = 0)
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
SER_IOCTL:
|
||||
ora ptr1+1 ; Check data msb and code to be 0
|
||||
bne :+
|
||||
|
||||
ldx ptr1 ; Check data lsb to be 0 or 1
|
||||
bmi :+
|
||||
cpx #$02
|
||||
bcs :+
|
||||
|
||||
stx Channel
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax ; Promote char return value
|
||||
rts
|
||||
|
||||
: lda #SER_ERR_INV_IOCTL
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_IRQ: Called from the builtin runtime IRQ handler as a subroutine. All
|
||||
; registers are already saved, no parameters are passed, but the carry flag
|
||||
; is clear on entry. The routine must return with carry set if the interrupt
|
||||
; was handled, otherwise with carry clear.
|
||||
|
||||
SER_IRQ:
|
||||
ldy #RR_INTR_PENDING_STATUS ; IRQ status is always in A reg
|
||||
sty SCCAREG
|
||||
lda SCCAREG
|
||||
|
||||
and CurChanIrqFlags ; Is this ours?
|
||||
beq Done
|
||||
|
||||
and #INTR_IS_RX ; Is this an RX irq?
|
||||
beq CheckSpecial
|
||||
|
||||
ldx Channel
|
||||
beq ReadBdata
|
||||
lda SCCADATA
|
||||
bra ReadDone
|
||||
ReadBdata:
|
||||
lda SCCBDATA ; Get byte
|
||||
ReadDone:
|
||||
ldx RecvFreeCnt ; Check if we have free space left
|
||||
beq Flow ; Jump if no space in receive buffer
|
||||
ldy RecvTail ; Load buffer pointer
|
||||
sta RecvBuf,y ; Store received byte in buffer
|
||||
inc RecvTail ; Increment buffer pointer
|
||||
dec RecvFreeCnt ; Decrement free space counter
|
||||
cpx #33
|
||||
bcc Flow ; Assert flow control if buffer space low
|
||||
rts ; Interrupt handled (carry already set)
|
||||
|
||||
CheckSpecial:
|
||||
; Always check IRQ special flags from Channel B (Ref page 5-24)
|
||||
ldy #RR_IRQ_STATUS
|
||||
sty SCCBREG
|
||||
lda SCCBREG
|
||||
|
||||
and #IRQ_MASQ
|
||||
cmp #IRQ_SPECIAL
|
||||
beq Special
|
||||
|
||||
; Clear exint
|
||||
ldx Channel
|
||||
ldy #WR_INIT_CTRL
|
||||
lda #INIT_CTRL_CLEAR_EIRQ
|
||||
jsr writeSCCReg
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
Flow: lda HSType ; Don't touch if no flow control
|
||||
beq IRQDone
|
||||
|
||||
ldx Channel ; Assert flow control if buffer space too low
|
||||
ldy #WR_TX_CTRL
|
||||
lda RtsOff
|
||||
jsr writeSCCReg
|
||||
|
||||
sta Stopped
|
||||
IRQDone:sec ; Interrupt handled
|
||||
Done: rts
|
||||
|
||||
Special:ldx Channel
|
||||
ldy #RR_SPEC_COND_STATUS
|
||||
jsr readSSCReg
|
||||
|
||||
tax
|
||||
and #SPEC_COND_FRAMING_ERR
|
||||
bne BadChar
|
||||
txa
|
||||
and #SPEC_COND_OVERRUN_ERR
|
||||
beq BadChar
|
||||
|
||||
ldy #WR_INIT_CTRL
|
||||
lda #INIT_CTRL_CLEAR_ERR
|
||||
jsr writeSCCReg
|
||||
|
||||
sec
|
||||
rts
|
||||
|
||||
BadChar:
|
||||
cpx #CHANNEL_B
|
||||
beq BadCharB
|
||||
lda SCCADATA
|
||||
bra BadCharDone
|
||||
BadCharB:
|
||||
lda SCCBDATA ; Remove char in error
|
||||
BadCharDone:
|
||||
sec
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Try to send a byte. Internal routine. A = TryHard, X = Channel
|
||||
|
||||
TryToSend:
|
||||
sta tmp1 ; Remember tryHard flag
|
||||
Again: lda SendFreeCnt ; Anything to send?
|
||||
cmp #$FF
|
||||
beq Quit ; No
|
||||
|
||||
lda Stopped ; Check for flow stopped
|
||||
bne Quit ; Bail out if it is
|
||||
|
||||
Wait:
|
||||
ldy #RR_INIT_STATUS
|
||||
jsr readSSCReg ; Check that we're ready to send
|
||||
tay
|
||||
and #INIT_STATUS_READY
|
||||
beq NotReady
|
||||
|
||||
tya
|
||||
and #INIT_STATUS_RTS ; Ready to send
|
||||
bne Send
|
||||
|
||||
NotReady:
|
||||
bit tmp1 ; Keep trying if must try hard
|
||||
bmi Wait
|
||||
Quit: rts
|
||||
|
||||
Send: ldy SendHead ; Send byte
|
||||
lda SendBuf,y
|
||||
|
||||
cpx #CHANNEL_B
|
||||
beq WriteBdata
|
||||
sta SCCADATA
|
||||
bra WriteDone
|
||||
WriteBdata:
|
||||
sta SCCBDATA
|
||||
WriteDone:
|
||||
inc SendHead
|
||||
inc SendFreeCnt
|
||||
jmp Again ; Continue flushing TX buffer
|
||||
@@ -26,6 +26,7 @@
|
||||
.include "ser-error.inc"
|
||||
|
||||
.macpack module
|
||||
.macpack cpu
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
@@ -37,8 +38,8 @@
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
.byte SER_API_VERSION ; Serial API version number
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
.byte SER_API_VERSION ; Serial API version number
|
||||
|
||||
; Library reference
|
||||
.addr $0000
|
||||
@@ -57,11 +58,19 @@
|
||||
;----------------------------------------------------------------------------
|
||||
; I/O definitions
|
||||
|
||||
ACIA = $C088
|
||||
ACIA_DATA = ACIA+0 ; Data register
|
||||
ACIA_STATUS = ACIA+1 ; Status register
|
||||
ACIA_CMD = ACIA+2 ; Command register
|
||||
ACIA_CTRL = ACIA+3 ; Control register
|
||||
.if (.cpu .bitand CPU_ISET_65C02)
|
||||
ACIA := $C088
|
||||
.else
|
||||
Offset = $8F ; Move 6502 false read out of I/O to page $BF
|
||||
ACIA := $C088-Offset
|
||||
.endif
|
||||
|
||||
ACIA_DATA := ACIA+0 ; Data register
|
||||
ACIA_STATUS := ACIA+1 ; Status register
|
||||
ACIA_CMD := ACIA+2 ; Command register
|
||||
ACIA_CTRL := ACIA+3 ; Control register
|
||||
|
||||
SLTROMSEL := $C02D ; For Apple IIgs slot verification
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Global variables
|
||||
@@ -70,16 +79,18 @@ ACIA_CTRL = ACIA+3 ; Control register
|
||||
|
||||
RecvHead: .res 1 ; Head of receive buffer
|
||||
RecvTail: .res 1 ; Tail of receive buffer
|
||||
RecvFreeCnt: .res 1 ; Number of bytes in receive buffer
|
||||
RecvFreeCnt: .res 1 ; Number of free bytes in receive buffer
|
||||
SendHead: .res 1 ; Head of send buffer
|
||||
SendTail: .res 1 ; Tail of send buffer
|
||||
SendFreeCnt: .res 1 ; Number of bytes in send buffer
|
||||
SendFreeCnt: .res 1 ; Number of free bytes in send buffer
|
||||
|
||||
Stopped: .res 1 ; Flow-stopped flag
|
||||
RtsOff: .res 1 ;
|
||||
RtsOff: .res 1 ; Cached value of command register with
|
||||
; flow stopped
|
||||
HSType: .res 1 ; Flow-control type
|
||||
|
||||
RecvBuf: .res 256 ; Receive buffers: 256 bytes
|
||||
SendBuf: .res 256 ; Send buffers: 256 bytes
|
||||
RecvBuf: .res 256 ; Receive buffer: 256 bytes
|
||||
SendBuf: .res 256 ; Send buffer: 256 bytes
|
||||
|
||||
Index: .res 1 ; I/O register index
|
||||
|
||||
@@ -89,8 +100,9 @@ Slot: .byte $02 ; Default to SSC in slot 2
|
||||
|
||||
.rodata
|
||||
|
||||
; Tables used to translate RS232 params into register values
|
||||
BaudTable: ; bit7 = 1 means setting is invalid
|
||||
BaudTable: ; Table used to translate RS232 baudrate param
|
||||
; into control register value
|
||||
; bit7 = 1 means setting is invalid
|
||||
.byte $FF ; SER_BAUD_45_5
|
||||
.byte $01 ; SER_BAUD_50
|
||||
.byte $02 ; SER_BAUD_75
|
||||
@@ -109,32 +121,44 @@ BaudTable: ; bit7 = 1 means setting is invalid
|
||||
.byte $0F ; SER_BAUD_19200
|
||||
.byte $FF ; SER_BAUD_38400
|
||||
.byte $FF ; SER_BAUD_57600
|
||||
.byte $FF ; SER_BAUD_115200
|
||||
.byte $00 ; SER_BAUD_115200
|
||||
.byte $FF ; SER_BAUD_230400
|
||||
BitTable:
|
||||
|
||||
BitTable: ; Table used to translate RS232 databits param
|
||||
; into control register value
|
||||
.byte $60 ; SER_BITS_5
|
||||
.byte $40 ; SER_BITS_6
|
||||
.byte $20 ; SER_BITS_7
|
||||
.byte $00 ; SER_BITS_8
|
||||
StopTable:
|
||||
|
||||
StopTable: ; Table used to translate RS232 stopbits param
|
||||
; into control register value
|
||||
.byte $00 ; SER_STOP_1
|
||||
.byte $80 ; SER_STOP_2
|
||||
ParityTable:
|
||||
|
||||
ParityTable: ; Table used to translate RS232 parity param
|
||||
; into command register value
|
||||
.byte $00 ; SER_PAR_NONE
|
||||
.byte $20 ; SER_PAR_ODD
|
||||
.byte $60 ; SER_PAR_EVEN
|
||||
.byte $A0 ; SER_PAR_MARK
|
||||
.byte $E0 ; SER_PAR_SPACE
|
||||
IdOfsTable:
|
||||
|
||||
IdOfsTable: ; Table of bytes positions, used to check four
|
||||
; specific bytes on the slot's firmware to make
|
||||
; sure this is a serial card.
|
||||
.byte $05 ; Pascal 1.0 ID byte
|
||||
.byte $07 ; Pascal 1.0 ID byte
|
||||
.byte $0B ; Pascal 1.1 generic signature byte
|
||||
.byte $0C ; Device signature byte
|
||||
IdValTable:
|
||||
.byte $38 ; Fixed
|
||||
.byte $18 ; Fixed
|
||||
.byte $01 ; Fixed
|
||||
.byte $31 ; Serial or parallel I/O card type 1
|
||||
|
||||
IdValTable: ; Table of expected values for the four checked
|
||||
; bytes
|
||||
.byte $38 ; ID Byte 0 (from Pascal 1.0), fixed
|
||||
.byte $18 ; ID Byte 1 (from Pascal 1.0), fixed
|
||||
.byte $01 ; Generic signature for Pascal 1.1, fixed
|
||||
.byte $31 ; Device signature byte (serial or
|
||||
; parallel I/O card type 1)
|
||||
|
||||
IdTableLen = * - IdValTable
|
||||
|
||||
@@ -161,115 +185,167 @@ SER_CLOSE:
|
||||
ldx Index ; Check for open port
|
||||
beq :+
|
||||
|
||||
; Deactivate DTR and disable 6551 interrupts
|
||||
lda #%00001010
|
||||
lda #%00001010 ; Deactivate DTR and disable 6551 interrupts
|
||||
sta ACIA_CMD,x
|
||||
|
||||
; Done, return an error code
|
||||
: lda #<SER_ERR_OK
|
||||
tax ; A is zero
|
||||
: lda #SER_ERR_OK ; Done, return an error code
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
stx Index ; Mark port as closed
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
; Note: Hardware checks are done in SER_OPEN instead of SER_INSTALL,
|
||||
; because they depend on the selected slot, and we can't select the slot
|
||||
; before SER_INSTALL.
|
||||
|
||||
SER_OPEN:
|
||||
ldx #<$C000
|
||||
; Check if this is a IIgs (Apple II Miscellaneous TechNote #7,
|
||||
; Apple II Family Identification)
|
||||
sec
|
||||
bit $C082
|
||||
jsr $FE1F
|
||||
bit $C080
|
||||
|
||||
bcs NotIIgs
|
||||
|
||||
; We're on a IIgs. For every slot N, either bit N of $C02D is
|
||||
; 0 for the internal ROM, or 1 for "Your Card". Let's make sure
|
||||
; that slot N's bit is set to 1, otherwise, that can't be an SSC.
|
||||
|
||||
ldy Slot
|
||||
lda SLTROMSEL
|
||||
: lsr
|
||||
dey
|
||||
bpl :- ; Shift until slot's bit ends in carry
|
||||
bcc NoDev
|
||||
|
||||
NotIIgs:ldx #<$C000
|
||||
stx ptr2
|
||||
lda #>$C000
|
||||
ora Slot
|
||||
sta ptr2+1
|
||||
|
||||
; Check Pascal 1.1 Firmware Protocol ID bytes
|
||||
: ldy IdOfsTable,x
|
||||
: ldy IdOfsTable,x ; Check Pascal 1.1 Firmware Protocol ID bytes
|
||||
lda IdValTable,x
|
||||
cmp (ptr2),y
|
||||
bne NoDevice
|
||||
bne NoDev
|
||||
inx
|
||||
cpx #IdTableLen
|
||||
bcc :-
|
||||
|
||||
; Convert slot to I/O register index
|
||||
lda Slot
|
||||
lda Slot ; Convert slot to I/O register index
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
.if .not (.cpu .bitand CPU_ISET_65C02)
|
||||
adc #Offset ; Assume carry to be clear
|
||||
.endif
|
||||
tax
|
||||
|
||||
; Check if the handshake setting is valid
|
||||
ldy #SER_PARAMS::HANDSHAKE ; Handshake
|
||||
lda (ptr1),y
|
||||
cmp #SER_HS_HW ; This is all we support
|
||||
bne InvParam
|
||||
; Check that this works like an ACIA 6551 is expected to work
|
||||
|
||||
; Initialize buffers
|
||||
ldy #$00
|
||||
lda ACIA_STATUS,x ; Save current values in what we expect to be
|
||||
sta tmp1 ; the ACIA status register
|
||||
lda ACIA_CMD,x ; and command register. So we can restore them
|
||||
sta tmp2 ; if this isn't a 6551.
|
||||
|
||||
ldy #%00000010 ; Disable TX/RX, disable IRQ
|
||||
: tya
|
||||
sta ACIA_CMD,x
|
||||
cmp ACIA_CMD,x ; Verify what we stored is there
|
||||
bne NotAcia
|
||||
iny ; Enable TX/RX, disable IRQ
|
||||
cpy #%00000100
|
||||
bne :-
|
||||
sta ACIA_STATUS,x ; Reset ACIA
|
||||
lda ACIA_CMD,x ; Check that RX/TX is disabled
|
||||
lsr
|
||||
bcc AciaOK
|
||||
|
||||
NotAcia:lda tmp2 ; Restore original values
|
||||
sta ACIA_CMD,x
|
||||
lda tmp1
|
||||
sta ACIA_STATUS,x
|
||||
|
||||
NoDev: lda #SER_ERR_NO_DEVICE
|
||||
bne Out
|
||||
|
||||
; Check if the handshake setting is valid
|
||||
AciaOK: ldy #SER_PARAMS::HANDSHAKE
|
||||
lda (ptr1),y
|
||||
cmp #SER_HS_SW ; Not supported
|
||||
bne HandshakeOK
|
||||
|
||||
lda #SER_ERR_INIT_FAILED
|
||||
bne Out
|
||||
|
||||
HandshakeOK:
|
||||
sta HSType ; Store flow control type
|
||||
|
||||
ldy #$00 ; Initialize buffers
|
||||
sty Stopped
|
||||
sty RecvHead
|
||||
sty RecvTail
|
||||
sty SendHead
|
||||
sty SendTail
|
||||
dey ; Y = 255
|
||||
dey ; Y = 255
|
||||
sty RecvFreeCnt
|
||||
sty SendFreeCnt
|
||||
|
||||
; Set the value for the control register, which contains stop bits,
|
||||
; word length and the baud rate.
|
||||
ldy #SER_PARAMS::BAUDRATE
|
||||
lda (ptr1),y ; Baudrate index
|
||||
lda (ptr1),y ; Baudrate index
|
||||
tay
|
||||
lda BaudTable,y ; Get 6551 value
|
||||
bmi InvBaud ; Branch if rate not supported
|
||||
sta tmp1
|
||||
lda BaudTable,y ; Get 6551 value
|
||||
sta tmp2 ; Backup for IRQ setting
|
||||
bpl BaudOK ; Check that baudrate is supported
|
||||
|
||||
ldy #SER_PARAMS::DATABITS ; Databits
|
||||
lda (ptr1),y
|
||||
lda #SER_ERR_BAUD_UNAVAIL
|
||||
bne Out
|
||||
|
||||
BaudOK: sta tmp1
|
||||
ldy #SER_PARAMS::DATABITS
|
||||
lda (ptr1),y ; Databits index
|
||||
tay
|
||||
lda BitTable,y
|
||||
lda BitTable,y ; Get 6551 value
|
||||
ora tmp1
|
||||
sta tmp1
|
||||
|
||||
ldy #SER_PARAMS::STOPBITS ; Stopbits
|
||||
lda (ptr1),y
|
||||
ldy #SER_PARAMS::STOPBITS
|
||||
lda (ptr1),y ; Stopbits index
|
||||
tay
|
||||
lda StopTable,y
|
||||
lda StopTable,y ; Get 6551 value
|
||||
ora tmp1
|
||||
ora #%00010000 ; Receiver clock source = baudrate
|
||||
ora #%00010000 ; Set receiver clock source = baudrate
|
||||
sta ACIA_CTRL,x
|
||||
|
||||
; Set the value for the command register. We remember the base value
|
||||
; in RtsOff, since we will have to manipulate ACIA_CMD often.
|
||||
ldy #SER_PARAMS::PARITY ; Parity
|
||||
lda (ptr1),y
|
||||
ldy #SER_PARAMS::PARITY
|
||||
lda (ptr1),y ; Parity index
|
||||
tay
|
||||
lda ParityTable,y
|
||||
ora #%00000001 ; DTR active
|
||||
sta RtsOff
|
||||
ora #%00001000 ; Enable receive interrupts
|
||||
sta ACIA_CMD,x
|
||||
lda ParityTable,y ; Get 6551 value
|
||||
|
||||
ora #%00000001 ; Set DTR active
|
||||
sta RtsOff ; Store value to easily handle flow control later
|
||||
|
||||
ora #%00001010 ; Disable interrupts and set RTS low
|
||||
|
||||
ldy tmp2 ; Don't enable IRQs if 115200bps
|
||||
beq :+
|
||||
and #%11111101 ; Enable receive IRQs
|
||||
: sta ACIA_CMD,x
|
||||
|
||||
; Done
|
||||
stx Index ; Mark port as open
|
||||
lda #<SER_ERR_OK
|
||||
tax ; A is zero
|
||||
rts
|
||||
|
||||
; Device (hardware) not found
|
||||
NoDevice:lda #<SER_ERR_NO_DEVICE
|
||||
ldx #>SER_ERR_NO_DEVICE
|
||||
rts
|
||||
|
||||
; Invalid parameter
|
||||
InvParam:lda #<SER_ERR_INIT_FAILED
|
||||
ldx #>SER_ERR_INIT_FAILED
|
||||
rts
|
||||
|
||||
; Baud rate not available
|
||||
InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
|
||||
ldx #>SER_ERR_BAUD_UNAVAIL
|
||||
stx Index ; Mark port as open
|
||||
lda #SER_ERR_OK
|
||||
Out:
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
@@ -279,38 +355,38 @@ InvBaud:lda #<SER_ERR_BAUD_UNAVAIL
|
||||
|
||||
SER_GET:
|
||||
ldx Index
|
||||
ldy SendFreeCnt ; Send data if necessary
|
||||
iny ; Y == $FF?
|
||||
beq :+
|
||||
lda #$00 ; TryHard = false
|
||||
jsr TryToSend
|
||||
|
||||
; Check for buffer empty
|
||||
: lda RecvFreeCnt ; (25)
|
||||
lda RecvFreeCnt ; Check for buffer empty
|
||||
cmp #$FF
|
||||
bne :+
|
||||
lda #<SER_ERR_NO_DATA
|
||||
ldx #>SER_ERR_NO_DATA
|
||||
lda #SER_ERR_NO_DATA
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
; Check for flow stopped & enough free: release flow control
|
||||
: ldy Stopped ; (34)
|
||||
: ldy Stopped ; Check for flow stopped
|
||||
beq :+
|
||||
cmp #63
|
||||
cmp #63 ; Enough free?
|
||||
bcc :+
|
||||
.if (.cpu .bitand CPU_ISET_65C02)
|
||||
stz Stopped ; Release flow control
|
||||
.else
|
||||
lda #$00
|
||||
sta Stopped
|
||||
.endif
|
||||
lda RtsOff
|
||||
ora #%00001000
|
||||
sta ACIA_CMD,x
|
||||
|
||||
; Get byte from buffer
|
||||
: ldy RecvHead ; (41)
|
||||
: ldy RecvHead ; Get byte from buffer
|
||||
lda RecvBuf,y
|
||||
inc RecvHead
|
||||
inc RecvFreeCnt
|
||||
ldx #$00 ; (59)
|
||||
ldx #$00
|
||||
.if (.cpu .bitand CPU_ISET_65C02)
|
||||
sta (ptr1) ; Store it for caller
|
||||
.else
|
||||
sta (ptr1,x)
|
||||
.endif
|
||||
txa ; Return code = 0
|
||||
rts
|
||||
|
||||
@@ -321,29 +397,28 @@ SER_GET:
|
||||
SER_PUT:
|
||||
ldx Index
|
||||
|
||||
; Try to send
|
||||
ldy SendFreeCnt
|
||||
iny ; Y = $FF?
|
||||
ldy SendFreeCnt ; Anything to send first?
|
||||
cpy #$FF ; No
|
||||
beq :+
|
||||
pha
|
||||
lda #$00 ; TryHard = false
|
||||
jsr TryToSend
|
||||
jsr TryToSend ; Try to flush send buffer
|
||||
pla
|
||||
|
||||
; Put byte into send buffer & send
|
||||
: ldy SendFreeCnt
|
||||
ldy SendFreeCnt ; Reload SendFreeCnt after TryToSend
|
||||
bne :+
|
||||
lda #<SER_ERR_OVERFLOW
|
||||
ldx #>SER_ERR_OVERFLOW
|
||||
lda #SER_ERR_OVERFLOW
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
: ldy SendTail
|
||||
: ldy SendTail ; Put byte into send buffer
|
||||
sta SendBuf,y
|
||||
inc SendTail
|
||||
dec SendFreeCnt
|
||||
lda #$FF ; TryHard = true
|
||||
jsr TryToSend
|
||||
lda #<SER_ERR_OK
|
||||
jsr TryToSend ; Flush send buffer
|
||||
lda #SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
rts
|
||||
|
||||
@@ -356,31 +431,32 @@ SER_STATUS:
|
||||
lda ACIA_STATUS,x
|
||||
ldx #$00
|
||||
sta (ptr1,x)
|
||||
txa ; SER_ERR_OK
|
||||
.assert SER_ERR_OK = 0, error
|
||||
txa
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; The ioctl data is the slot number to open.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
|
||||
SER_IOCTL:
|
||||
; Check data msb and code to be 0
|
||||
ora ptr1+1
|
||||
ora ptr1+1 ; Check data msb and code to be 0
|
||||
bne :+
|
||||
|
||||
; Check data lsb to be [1..7]
|
||||
ldx ptr1
|
||||
ldx ptr1 ; Check data lsb to be [1..7]
|
||||
beq :+
|
||||
cpx #7+1
|
||||
bcs :+
|
||||
|
||||
stx Slot
|
||||
tax ; SER_ERR_OK
|
||||
stx Slot ; Store slot
|
||||
.assert SER_ERR_OK = 0, error
|
||||
tax
|
||||
rts
|
||||
|
||||
: lda #<SER_ERR_INV_IOCTL
|
||||
ldx #>SER_ERR_INV_IOCTL
|
||||
: lda #SER_ERR_INV_IOCTL
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
@@ -396,22 +472,24 @@ SER_IRQ:
|
||||
and #$08
|
||||
beq Done ; Jump if no ACIA interrupt
|
||||
lda ACIA_DATA,x ; Get byte from ACIA
|
||||
ldy RecvFreeCnt ; Check if we have free space left
|
||||
ldx RecvFreeCnt ; Check if we have free space left
|
||||
beq Flow ; Jump if no space in receive buffer
|
||||
ldy RecvTail ; Load buffer pointer
|
||||
sta RecvBuf,y ; Store received byte in buffer
|
||||
inc RecvTail ; Increment buffer pointer
|
||||
dec RecvFreeCnt ; Decrement free space counter
|
||||
ldy RecvFreeCnt ; Check for buffer space low
|
||||
cpy #33
|
||||
cpx #33 ; Check for buffer space low
|
||||
bcc Flow ; Assert flow control if buffer space low
|
||||
rts ; Interrupt handled (carry already set)
|
||||
|
||||
; Assert flow control if buffer space too low
|
||||
Flow: lda RtsOff
|
||||
Flow: lda HSType ; Don't touch if no flow control
|
||||
beq IRQDone
|
||||
|
||||
ldx Index ; Assert flow control if buffer space too low
|
||||
lda RtsOff
|
||||
sta ACIA_CMD,x
|
||||
sta Stopped
|
||||
sec ; Interrupt handled
|
||||
IRQDone:sec ; Interrupt handled
|
||||
Done: rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
@@ -419,26 +497,24 @@ Done: rts
|
||||
|
||||
TryToSend:
|
||||
sta tmp1 ; Remember tryHard flag
|
||||
Again: lda SendFreeCnt
|
||||
cmp #$FF
|
||||
beq Quit ; Bail out
|
||||
NextByte:
|
||||
lda SendFreeCnt ; Is there anything to send? This can happen if
|
||||
cmp #$FF ; we got interrupted by RX while sending, and
|
||||
beq Quit ; flow control was asserted.
|
||||
|
||||
; Check for flow stopped
|
||||
lda Stopped
|
||||
bne Quit ; Bail out
|
||||
Again: lda Stopped ; Is flow stopped?
|
||||
bne Quit ; Yes, Bail out
|
||||
|
||||
; Check that ACIA is ready to send
|
||||
lda ACIA_STATUS,x
|
||||
lda ACIA_STATUS,x ; Check that ACIA is ready to send
|
||||
and #$10
|
||||
bne Send
|
||||
bne Send ; It is!
|
||||
bit tmp1 ; Keep trying if must try hard
|
||||
bmi Again
|
||||
Quit: rts
|
||||
|
||||
; Send byte and try again
|
||||
Send: ldy SendHead
|
||||
Send: ldy SendHead ; Get first byte to send
|
||||
lda SendBuf,y
|
||||
sta ACIA_DATA,x
|
||||
sta ACIA_DATA,x ; Send it
|
||||
inc SendHead
|
||||
inc SendFreeCnt
|
||||
jmp Again
|
||||
bne NextByte ; And try next one
|
||||
|
||||
22
libsrc/apple2/ser_stat_stddrv.s
Normal file
22
libsrc/apple2/ser_stat_stddrv.s
Normal file
@@ -0,0 +1,22 @@
|
||||
;
|
||||
; Address of the static standard serial driver
|
||||
;
|
||||
; Oliver Schmidt, 2022-12-22
|
||||
;
|
||||
; const void ser_static_stddrv[];
|
||||
;
|
||||
|
||||
.export _ser_static_stddrv
|
||||
.ifdef __APPLE2ENH__
|
||||
.import _a2e_ssc_ser
|
||||
.else
|
||||
.import _a2_ssc_ser
|
||||
.endif
|
||||
|
||||
.rodata
|
||||
|
||||
.ifdef __APPLE2ENH__
|
||||
_ser_static_stddrv := _a2e_ssc_ser
|
||||
.else
|
||||
_ser_static_stddrv := _a2_ssc_ser
|
||||
.endif
|
||||
18
libsrc/apple2/ser_stddrv.s
Normal file
18
libsrc/apple2/ser_stddrv.s
Normal file
@@ -0,0 +1,18 @@
|
||||
;
|
||||
; Name of the standard serial driver
|
||||
;
|
||||
; Oliver Schmidt, 2022-12-22
|
||||
;
|
||||
; const char ser_stddrv[];
|
||||
;
|
||||
|
||||
.export _ser_stddrv
|
||||
|
||||
.rodata
|
||||
|
||||
_ser_stddrv:
|
||||
.ifdef __APPLE2ENH__
|
||||
.asciiz "A2E.SSC.SER"
|
||||
.else
|
||||
.asciiz "A2.SSC.SER"
|
||||
.endif
|
||||
29
libsrc/apple2/set_iigs_speed.s
Normal file
29
libsrc/apple2/set_iigs_speed.s
Normal file
@@ -0,0 +1,29 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; unsigned char __fastcall__ detect_iigs(unsigned char speed)
|
||||
;
|
||||
|
||||
.export _set_iigs_speed
|
||||
.import ostype, return0
|
||||
|
||||
.include "apple2.inc"
|
||||
.include "accelerator.inc"
|
||||
|
||||
_set_iigs_speed:
|
||||
tax ; Keep parameter
|
||||
lda ostype ; Return if not IIgs
|
||||
bmi :+
|
||||
jmp return0
|
||||
|
||||
: lda CYAREG
|
||||
cpx #SPEED_SLOW
|
||||
beq :+
|
||||
ora #%10000000
|
||||
bne set_speed
|
||||
: and #%01111111
|
||||
set_speed:
|
||||
sta CYAREG
|
||||
txa
|
||||
ldx #>$0000
|
||||
rts
|
||||
@@ -68,4 +68,4 @@ enosys: lda #ENOSYS
|
||||
erange: lda #ERANGE
|
||||
|
||||
; Set __errno
|
||||
errno: jmp __directerrno
|
||||
errno: jmp ___directerrno
|
||||
|
||||
54
libsrc/apple2/sleep.s
Normal file
54
libsrc/apple2/sleep.s
Normal file
@@ -0,0 +1,54 @@
|
||||
;
|
||||
; Colin Leroy-Mira <colin@colino.net>, 2024
|
||||
;
|
||||
; void __fastcall__ sleep(unsigned s)
|
||||
;
|
||||
;
|
||||
|
||||
.export _sleep
|
||||
.import _get_iigs_speed
|
||||
.import _set_iigs_speed
|
||||
.import WAIT
|
||||
.importzp tmp1
|
||||
|
||||
.include "accelerator.inc"
|
||||
|
||||
; This functions uses the Apple2 WAIT ROM routine to waste a certain
|
||||
; amount of cycles and returns approximately after the numbers of
|
||||
; seconds passed in AX.
|
||||
;
|
||||
; It takes 1023730 cycles when called with AX=1 (1,0007s),
|
||||
; 10236364 cycles when called with AX=10 (10,006 seconds),
|
||||
; 306064298 cycles with AX=300 (299.2 seconds).
|
||||
;
|
||||
; Caveat: IRQs firing during calls to sleep will make the sleep longer
|
||||
; by the amount of cycles it takes to handle the IRQ.
|
||||
;
|
||||
_sleep:
|
||||
stx tmp1 ; High byte of s in X
|
||||
tay ; Low byte in A
|
||||
ora tmp1
|
||||
bne :+
|
||||
rts
|
||||
: jsr _get_iigs_speed ; Save current CPU speed
|
||||
pha
|
||||
lda #SPEED_SLOW ; Down to 1MHz for consistency around WAIT
|
||||
jsr _set_iigs_speed
|
||||
sleep_1s:
|
||||
ldx #$0A ; Loop 10 times
|
||||
sleep_100ms:
|
||||
lda #$C7 ; Sleep about 99ms
|
||||
jsr WAIT
|
||||
lda #$0D ; About 1ms
|
||||
jsr WAIT
|
||||
dex
|
||||
bne sleep_100ms
|
||||
dey
|
||||
bne sleep_1s
|
||||
dec tmp1
|
||||
bmi done
|
||||
dey ; Down to #$FF
|
||||
bne sleep_1s
|
||||
done:
|
||||
pla ; Restore CPU speed
|
||||
jmp _set_iigs_speed
|
||||
129
libsrc/apple2/stat.s
Normal file
129
libsrc/apple2/stat.s
Normal file
@@ -0,0 +1,129 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2023 <colin@colino.net>
|
||||
;
|
||||
; int __fastcall__ stat(const char *pathname, struct stat *statbuf);
|
||||
;
|
||||
|
||||
.export _stat
|
||||
.import __errno, _open,_close
|
||||
.import mli_file_info
|
||||
.import popax, pushax, pusha0, incsp2
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
.include "fcntl.inc"
|
||||
.include "filedes.inc"
|
||||
.include "mli.inc"
|
||||
.include "stat.inc"
|
||||
|
||||
_stat:
|
||||
; Store statbuf pointer
|
||||
sta ptr4
|
||||
sta stbuf
|
||||
stx ptr4+1
|
||||
stx stbuf+1
|
||||
|
||||
; Clear statbuf
|
||||
lda #$00
|
||||
ldy #.sizeof(stat)-1
|
||||
: sta (ptr4),y
|
||||
dey
|
||||
bpl :-
|
||||
|
||||
; Reset errno
|
||||
sta ___errno
|
||||
|
||||
; Store pathname
|
||||
jsr popax
|
||||
jsr pushax ; Push it back for mli_file_info
|
||||
jsr pushax ; and for open
|
||||
|
||||
jsr mli_file_info
|
||||
|
||||
bcc got_info
|
||||
jmp incsp2 ; Drop filename copy for open
|
||||
|
||||
got_info:
|
||||
; st_dev
|
||||
lda DEVNUM
|
||||
lsr ; Shift right to cc65 representation
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ldy #stat::st_dev
|
||||
sta (ptr4),y
|
||||
|
||||
; st_mode (S_IFDIR/S_IFREG only)
|
||||
lda mliparam + MLI::INFO::FILE_TYPE
|
||||
ldy #stat::st_mode
|
||||
cmp #$0f
|
||||
bne is_reg
|
||||
lda #S_IFDIR
|
||||
bne set_st_mode
|
||||
|
||||
is_reg: lda #S_IFREG
|
||||
|
||||
set_st_mode:
|
||||
sta (ptr4),y
|
||||
|
||||
; st_access through st_create_time
|
||||
ldx #MLI::INFO::ACCESS
|
||||
ldy #stat::st_access
|
||||
: lda mliparam,x
|
||||
sta (ptr4),y
|
||||
inx
|
||||
iny
|
||||
cpy #stat::st_create_time + .sizeof(stat::st_create_time)
|
||||
bne :-
|
||||
|
||||
; st_size
|
||||
lda #O_RDONLY
|
||||
jsr pusha0
|
||||
ldy #$04
|
||||
jsr _open
|
||||
cmp #$FF
|
||||
beq done
|
||||
pha ; Save file descriptor for closing
|
||||
|
||||
; Get ProDOS's REF_NUM from file descriptor
|
||||
jsr getfd
|
||||
; Get file information
|
||||
sta mliparam + MLI::EOF::REF_NUM
|
||||
lda #GET_EOF_CALL
|
||||
ldx #EOF_COUNT
|
||||
jsr callmli
|
||||
bcs eoferr
|
||||
|
||||
; Get struct stat in ptr4 back, open destroyed it
|
||||
lda stbuf
|
||||
ldx stbuf+1
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
|
||||
; Store size
|
||||
ldy #stat::st_size
|
||||
lda mliparam + MLI::EOF::EOF
|
||||
sta (ptr4),y
|
||||
lda mliparam + MLI::EOF::EOF+1
|
||||
iny
|
||||
sta (ptr4),y
|
||||
lda mliparam + MLI::EOF::EOF+2
|
||||
iny
|
||||
sta (ptr4),y
|
||||
|
||||
; Close file
|
||||
eoferr:
|
||||
pla
|
||||
ldx #$00
|
||||
jsr _close
|
||||
|
||||
; Set return value if we had an error
|
||||
lda ___errno
|
||||
beq done
|
||||
lda #$FF
|
||||
done:
|
||||
tax ; Promote char return value
|
||||
rts
|
||||
|
||||
.bss
|
||||
|
||||
stbuf: .res 2
|
||||
123
libsrc/apple2/statvfs.s
Normal file
123
libsrc/apple2/statvfs.s
Normal file
@@ -0,0 +1,123 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2023 <colin@colino.net>
|
||||
;
|
||||
; int __fastcall__ statvfs(const char *pathname, struct statvfs *statvfsbuf);
|
||||
;
|
||||
|
||||
.export _statvfs
|
||||
.import _dio_query_sectsize
|
||||
.import mli_file_info, pushax, popax, popptr1, pushptr1
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
.include "errno.inc"
|
||||
.include "mli.inc"
|
||||
.include "statvfs.inc"
|
||||
|
||||
_statvfs:
|
||||
; Store statbuf
|
||||
sta ptr4
|
||||
stx ptr4+1
|
||||
|
||||
; Clear statbuf
|
||||
lda #$00
|
||||
ldy #.sizeof(statvfs)-1
|
||||
: sta (ptr4),y
|
||||
dey
|
||||
bpl :-
|
||||
|
||||
; Store pathname, keeping only volume name
|
||||
jsr popptr1
|
||||
ldy #$00
|
||||
sty vol_sep
|
||||
lda (ptr1),y
|
||||
cmp #'/' ; Is the path absolute?
|
||||
beq :+
|
||||
lda #EINVAL
|
||||
jmp ___directerrno
|
||||
|
||||
: iny
|
||||
lda (ptr1),y
|
||||
beq :+ ; End of string, no other /
|
||||
cpy #FILENAME_MAX
|
||||
beq :+ ; Max filename length reached
|
||||
cmp #'/'
|
||||
bne :- ; Not a slash, keep looking
|
||||
sty vol_sep ; Register '/' index
|
||||
lda #$00
|
||||
sta (ptr1),y ; Cut pathname at first slash
|
||||
: jsr pushptr1
|
||||
|
||||
jsr mli_file_info
|
||||
|
||||
php
|
||||
ldy vol_sep ; Put slash back in pathname
|
||||
lda #'/'
|
||||
sta (ptr1),y
|
||||
plp
|
||||
|
||||
bcc got_info
|
||||
|
||||
jmp ___mappederrno
|
||||
|
||||
got_info:
|
||||
; f_fsid
|
||||
lda DEVNUM
|
||||
lsr ; Shift right to cc65 representation
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ldy #statvfs::f_fsid
|
||||
sta (ptr4),y
|
||||
|
||||
; total number of blocks
|
||||
lda mliparam + MLI::INFO::AUX_TYPE
|
||||
ldy #statvfs::f_blocks
|
||||
sta (ptr4),y
|
||||
lda mliparam + MLI::INFO::AUX_TYPE+1
|
||||
iny
|
||||
sta (ptr4),y
|
||||
|
||||
; blocks free & avail
|
||||
sec
|
||||
lda mliparam + MLI::INFO::AUX_TYPE
|
||||
sbc mliparam + MLI::INFO::BLOCKS
|
||||
ldy #statvfs::f_bfree
|
||||
sta (ptr4),y
|
||||
ldy #statvfs::f_bavail
|
||||
sta (ptr4),y
|
||||
|
||||
lda mliparam + MLI::INFO::AUX_TYPE+1
|
||||
sbc mliparam + MLI::INFO::BLOCKS+1
|
||||
iny
|
||||
sta (ptr4),y
|
||||
ldy #statvfs::f_bfree+1
|
||||
sta (ptr4),y
|
||||
|
||||
; block sizes
|
||||
jsr _dio_query_sectsize
|
||||
; low bytes
|
||||
ldy #statvfs::f_bsize
|
||||
sta (ptr4),y
|
||||
ldy #statvfs::f_frsize
|
||||
sta (ptr4),y
|
||||
; f_frsize high byte
|
||||
iny
|
||||
txa
|
||||
sta (ptr4),y
|
||||
; f_bsize high byte
|
||||
ldy #statvfs::f_bsize+1
|
||||
sta (ptr4),y
|
||||
|
||||
; f_namemax
|
||||
lda #FILENAME_MAX
|
||||
ldy #statvfs::f_namemax
|
||||
sta (ptr4),y
|
||||
|
||||
lda #$00
|
||||
sta ___errno
|
||||
tax
|
||||
rts
|
||||
|
||||
.bss
|
||||
|
||||
vol_sep:.res 1
|
||||
@@ -29,7 +29,8 @@ __syschdir:
|
||||
bcs cleanup
|
||||
|
||||
; Update current working directory
|
||||
jsr initcwd ; Returns with A = 0
|
||||
jsr initcwd
|
||||
lda #$00
|
||||
|
||||
; Cleanup name
|
||||
cleanup:jsr popname ; Preserves A
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
DEPS += ../libwrk/$(TARGET)/loader.d
|
||||
DEPS += ../libwrk/$(TARGET)/convert.d \
|
||||
../libwrk/$(TARGET)/loader.d
|
||||
|
||||
../libwrk/$(TARGET)/convert.o: $(SRCDIR)/targetutil/convert.c | ../libwrk/$(TARGET)
|
||||
$(COMPILE_recipe)
|
||||
|
||||
../libwrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../libwrk/$(TARGET)
|
||||
$(ASSEMBLE_recipe)
|
||||
|
||||
../target/$(TARGET)/util/convert.system: ../libwrk/$(TARGET)/convert.o ../lib/$(TARGET).lib | ../target/$(TARGET)/util
|
||||
$(LD65) -o $@ -C $(TARGET)-system.cfg $^
|
||||
|
||||
../target/$(TARGET)/util/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../target/$(TARGET)/util
|
||||
$(LD65) -o $@ -C $(filter %.cfg,$^) $(filter-out %.cfg,$^)
|
||||
|
||||
$(TARGET): ../target/$(TARGET)/util/loader.system
|
||||
$(TARGET): ../target/$(TARGET)/util/convert.system \
|
||||
../target/$(TARGET)/util/loader.system
|
||||
|
||||
@@ -108,7 +108,7 @@ static unsigned get_dir_entry(char* p_name)
|
||||
}
|
||||
|
||||
/* Field header_pointer directly follows field last_mod */
|
||||
cur_addr = *(unsigned*)(&dirent->d_mtime.hour + 1);
|
||||
cur_addr = *(unsigned*)(&dirent->d_mtime.time.hour + 1);
|
||||
|
||||
dhandle = dio_open(getcurrentdevice());
|
||||
if (!dhandle) {
|
||||
@@ -83,7 +83,10 @@ Y2 := ptr4
|
||||
|
||||
.byte $74, $67, $69 ; "tgi"
|
||||
.byte TGI_API_VERSION ; TGI API version number
|
||||
|
||||
libref:
|
||||
.addr $0000 ; Library reference
|
||||
|
||||
.word 280 ; X resolution
|
||||
.word 192 ; Y resolution
|
||||
.byte 8 ; Number of drawing colors
|
||||
@@ -120,6 +123,10 @@ pages: .byte 2 ; Number of screens available
|
||||
|
||||
.bss
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
machinetype: .res 1
|
||||
.endif
|
||||
|
||||
; Absolute variables used in the code
|
||||
|
||||
ERROR: .res 1 ; Error code
|
||||
@@ -146,13 +153,22 @@ FONT:
|
||||
; most of the time.
|
||||
; Must set an error code: NO
|
||||
INSTALL:
|
||||
.ifdef __APPLE2ENH__
|
||||
.ifndef __APPLE2ENH__
|
||||
lda libref
|
||||
ldx libref+1
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #$0
|
||||
lda (ptr1),y
|
||||
sta machinetype
|
||||
bpl :+
|
||||
.endif
|
||||
; No page switching if 80 column store is enabled
|
||||
bit RD80COL
|
||||
bpl :+
|
||||
lda #$01
|
||||
sta pages
|
||||
: .endif
|
||||
:
|
||||
|
||||
; Fall through
|
||||
|
||||
@@ -175,6 +191,16 @@ INIT:
|
||||
; Switch into graphics mode
|
||||
bit MIXCLR
|
||||
bit HIRES
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl clr_txt
|
||||
.endif
|
||||
|
||||
sta IOUDISON
|
||||
bit DHIRESOFF
|
||||
|
||||
clr_txt:
|
||||
bit TXTCLR
|
||||
|
||||
; Beagle Bros Shape Mechanic fonts don't
|
||||
@@ -196,11 +222,14 @@ DONE:
|
||||
bit TXTSET
|
||||
bit LOWSCR
|
||||
|
||||
.ifdef __APPLE2ENH__
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl reset_wndtop
|
||||
.endif
|
||||
; Limit SET80COL-HISCR to text
|
||||
bit LORES
|
||||
.endif
|
||||
|
||||
reset_wndtop:
|
||||
; Reset the text window top
|
||||
lda #$00
|
||||
sta WNDTOP
|
||||
@@ -338,7 +367,7 @@ GETPIXEL:
|
||||
lda #$03 ; 3 (white)
|
||||
: bcc :+
|
||||
adc #$03 ; += 4 (black -> black2, white -> white2)
|
||||
: ldx #$00
|
||||
: ldx #>$0000
|
||||
bit $C080 ; Switch in LC bank 2 for R/O
|
||||
rts
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ Y2 := ptr4
|
||||
|
||||
.byte $74, $67, $69 ; "tgi"
|
||||
.byte TGI_API_VERSION ; TGI API version number
|
||||
.addr $0000 ; Library reference
|
||||
libref: .addr $0000 ; Library reference
|
||||
.word 40 ; X resolution
|
||||
.word 48 ; Y resolution
|
||||
.byte 16 ; Number of drawing colors
|
||||
@@ -93,6 +93,10 @@ Y2 := ptr4
|
||||
ERROR: .res 1 ; Error code
|
||||
MIX: .res 1 ; 4 lines of text
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
machinetype: .res 1
|
||||
.endif
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.rodata
|
||||
@@ -126,7 +130,15 @@ INIT:
|
||||
bit $C082 ; Switch in ROM
|
||||
jsr SETGR
|
||||
bit MIXCLR
|
||||
bit $C080 ; Switch in LC bank 2 for R/O
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl lc_in
|
||||
.endif
|
||||
|
||||
sta IOUDISON
|
||||
bit DHIRESOFF
|
||||
lc_in: bit $C080 ; Switch in LC bank 2 for R/O
|
||||
|
||||
; Done, reset the error code
|
||||
lda #TGI_ERR_OK
|
||||
@@ -140,6 +152,16 @@ INIT:
|
||||
; most of the time.
|
||||
; Must set an error code: NO
|
||||
INSTALL:
|
||||
.ifndef __APPLE2ENH__
|
||||
lda libref
|
||||
ldx libref+1
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
ldy #$0
|
||||
lda (ptr1),y
|
||||
sta machinetype
|
||||
bpl :+
|
||||
.endif
|
||||
; Fall through
|
||||
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory. May
|
||||
@@ -317,7 +339,7 @@ GETPIXEL:
|
||||
jsr SCRN
|
||||
tax
|
||||
lda COL2TGI,x
|
||||
ldx #$00
|
||||
ldx #>$0000
|
||||
bit $C080 ; Switch in LC bank 2 for R/O
|
||||
rts
|
||||
|
||||
|
||||
18
libsrc/apple2/tgiref.s
Normal file
18
libsrc/apple2/tgiref.s
Normal file
@@ -0,0 +1,18 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2025-05-10
|
||||
;
|
||||
|
||||
.export tgi_libref
|
||||
.import _exit
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
|
||||
.import machinetype
|
||||
|
||||
tgi_libref := machinetype
|
||||
|
||||
.else
|
||||
|
||||
tgi_libref := _exit
|
||||
|
||||
.endif
|
||||
27
libsrc/apple2/uppercasemask.s
Normal file
27
libsrc/apple2/uppercasemask.s
Normal file
@@ -0,0 +1,27 @@
|
||||
;
|
||||
; Oliver Schmidt, 2024-08-06
|
||||
;
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
|
||||
.export uppercasemask
|
||||
|
||||
.import machinetype
|
||||
.constructor detectlowercase
|
||||
|
||||
.segment "ONCE"
|
||||
|
||||
detectlowercase:
|
||||
bit machinetype
|
||||
bpl :+
|
||||
|
||||
lda #$FF
|
||||
sta uppercasemask
|
||||
: rts
|
||||
|
||||
|
||||
.data
|
||||
|
||||
uppercasemask: .byte $DF ; Convert to uppercase
|
||||
|
||||
.endif
|
||||
@@ -1,68 +1,52 @@
|
||||
;
|
||||
; Oliver Schmidt, 07.09.2009
|
||||
;
|
||||
; unsigned __fastcall__ videomode (unsigned mode);
|
||||
; signed char __fastcall__ videomode (unsigned mode);
|
||||
;
|
||||
.ifdef __APPLE2ENH__
|
||||
|
||||
.export _videomode
|
||||
.import COUT
|
||||
|
||||
.import aux80col
|
||||
.import returnFFFF
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
|
||||
VIDEOMODE_40x24 = $15
|
||||
VIDEOMODE_80x24 = $00
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
_videomode:
|
||||
bit aux80col
|
||||
bmi set_mode
|
||||
|
||||
; No 80 column card, return error if requested mode is 80cols
|
||||
cmp #VIDEOMODE_40x24
|
||||
beq out
|
||||
jmp returnFFFF
|
||||
set_mode:
|
||||
|
||||
; Get and save current videomode flag
|
||||
bit RD80VID
|
||||
php
|
||||
|
||||
; If we are in 80 column mode then the 80 column firmware is
|
||||
; known to be active so we can just print the ctrl-char code
|
||||
; (even if this only means staying in the current videomode)
|
||||
bpl :+
|
||||
jsr COUT
|
||||
bra done
|
||||
|
||||
; If we are in 40 column mode and want to set 40 column mode
|
||||
; then we explicitly do nothing as we neither know about the
|
||||
; current state of the 80 column firmware nor want to fix it
|
||||
: cmp #$11 ; Ctrl-char code for 40 cols
|
||||
beq done
|
||||
|
||||
; If we are in 40 column mode and want to set 80 column mode
|
||||
; then we first presume the 80 column firmware being already
|
||||
; active and print the ctrl-char code (this causes a garbage
|
||||
; char to be printed on the screen if isn't already active)
|
||||
jsr COUT
|
||||
|
||||
; If we successfully switched to 80 column mode then the 80
|
||||
; column firmware was in fact already active and we're done
|
||||
bit RD80VID
|
||||
bmi done
|
||||
|
||||
; The 80 column firmware isn't already active so we need to
|
||||
; initialize it - causing the screen to be cleared and thus
|
||||
; the garbage char printed above to be erased (but for some
|
||||
; reason the cursor horizontal position not to be zeroed)
|
||||
stz CH
|
||||
|
||||
; Initializing the 80 column firmware needs the ROM switched
|
||||
; in, otherwise it would copy the F8 ROM to the LC (@ $CEF4)
|
||||
bit $C082
|
||||
|
||||
; Initialize 80 column firmware
|
||||
jsr $C300 ; PR#3
|
||||
; Call 80 column firmware with ctrl-char code
|
||||
jsr $C300
|
||||
|
||||
; Switch in LC bank 2 for R/O
|
||||
bit $C080
|
||||
|
||||
|
||||
; Switch in alternate charset again
|
||||
sta SETALTCHAR
|
||||
|
||||
; Return ctrl-char code for setting previous
|
||||
; videomode using the saved videomode flag
|
||||
done: lda #$11 ; Ctrl-char code for 40 cols
|
||||
lda #VIDEOMODE_40x24
|
||||
plp
|
||||
bpl :+
|
||||
lda #$12 ; Ctrl-char code for 80 cols
|
||||
: rts ; X was preserved all the way
|
||||
|
||||
.endif ; __APPLE2ENH__
|
||||
bpl out
|
||||
lda #VIDEOMODE_80x24
|
||||
out: rts ; X was preserved all the way
|
||||
|
||||
20
libsrc/apple2/wait.s
Normal file
20
libsrc/apple2/wait.s
Normal file
@@ -0,0 +1,20 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 2024
|
||||
;
|
||||
; WAIT routine
|
||||
;
|
||||
|
||||
.export WAIT
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
WAIT:
|
||||
; Switch in ROM and call WAIT
|
||||
bit $C082
|
||||
jsr $FCA8 ; Vector to WAIT routine
|
||||
|
||||
; Switch in LC bank 2 for R/O and return
|
||||
bit $C080
|
||||
rts
|
||||
53
libsrc/apple2/waitvsync.s
Normal file
53
libsrc/apple2/waitvsync.s
Normal file
@@ -0,0 +1,53 @@
|
||||
;
|
||||
; Oliver Schmidt, 2020-06-14
|
||||
;
|
||||
; void waitvsync (void);
|
||||
;
|
||||
.export _waitvsync
|
||||
.import ostype
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.endif
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
_waitvsync:
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype ; IIe/enh?
|
||||
bpl out ; No, silently fail
|
||||
.endif
|
||||
|
||||
bit ostype
|
||||
bmi iigs ; $8x
|
||||
bvs iic ; $4x
|
||||
|
||||
; Apple IIe
|
||||
: bit RDVBLBAR
|
||||
bpl :- ; Blanking
|
||||
: bit RDVBLBAR
|
||||
bmi :- ; Drawing
|
||||
rts
|
||||
|
||||
; Apple IIgs TechNote #40, VBL Signal
|
||||
iigs: bit RDVBLBAR
|
||||
bmi iigs ; Blanking
|
||||
: bit RDVBLBAR
|
||||
bpl :- ; Drawing
|
||||
rts
|
||||
|
||||
; Apple IIc TechNote #9, Detecting VBL
|
||||
iic: php
|
||||
sei
|
||||
sta IOUDISOFF
|
||||
lda RDVBLMSK
|
||||
bit ENVBL
|
||||
bit PTRIG ; Reset VBL interrupt flag
|
||||
: bit RDVBLBAR
|
||||
bpl :-
|
||||
asl
|
||||
bcs :+ ; VBL interrupts were already enabled
|
||||
bit DISVBL
|
||||
: sta IOUDISON ; IIc Tech Ref Man: The firmware normally leaves IOUDIS on.
|
||||
plp
|
||||
out: rts
|
||||
@@ -4,11 +4,23 @@
|
||||
; unsigned char wherex (void);
|
||||
;
|
||||
|
||||
.ifndef __APPLE2ENH__
|
||||
.import machinetype
|
||||
.endif
|
||||
|
||||
.export _wherex
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
_wherex:
|
||||
lda CH
|
||||
ldx #$00
|
||||
.ifndef __APPLE2ENH__
|
||||
bit machinetype
|
||||
bpl :+
|
||||
.endif
|
||||
bit RD80VID ; In 80 column mode?
|
||||
bpl :+
|
||||
lda OURCH
|
||||
|
||||
: ldx #>$0000
|
||||
rts
|
||||
|
||||
@@ -12,5 +12,5 @@ _wherey:
|
||||
lda CV
|
||||
sec
|
||||
sbc WNDTOP
|
||||
ldx #$00
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
.export _write
|
||||
.import rwprolog, rwcommon, rwepilog
|
||||
.import COUT
|
||||
.ifndef __APPLE2ENH__
|
||||
.import uppercasemask
|
||||
.endif
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
@@ -84,7 +87,7 @@ next: lda (ptr1),y
|
||||
.ifndef __APPLE2ENH__
|
||||
cmp #$E0 ; Test for lowercase
|
||||
bcc output
|
||||
and #$DF ; Convert to uppercase
|
||||
and uppercasemask
|
||||
.endif
|
||||
output: jsr COUT ; Preserves X and Y
|
||||
|
||||
@@ -107,8 +110,8 @@ done: lda #$00
|
||||
einval: lda #EINVAL
|
||||
|
||||
; Set __errno
|
||||
errno: jmp __directerrno
|
||||
errno: jmp ___directerrno
|
||||
|
||||
; Set ___oserror
|
||||
oserr: jmp ___mappederrno
|
||||
|
||||
; Set __oserror
|
||||
oserr: jmp __mappederrno
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ L1: lda #<brk_handler ; Set the break vector to our routine
|
||||
lda #$00
|
||||
sta oldvec ; Clear the old vector
|
||||
stx oldvec+1
|
||||
@L9: rts
|
||||
@L9: rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
.import __BSS_RUN__, __STARTADDRESS__, _cas_init
|
||||
.import __INIT_RUN__, __STARTADDRESS__, _cas_init
|
||||
.export _cas_hdr
|
||||
|
||||
.assert ((__BSS_RUN__ - __STARTADDRESS__ + 127) / 128) < $101, error, "File to big to load from cassette"
|
||||
.assert ((__INIT_RUN__ - __STARTADDRESS__ + 127) / 128) < $101, error, "File to big to load from cassette"
|
||||
|
||||
|
||||
; for a description of the cassette header, see De Re Atari, appendix C
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
_cas_hdr:
|
||||
.byte 0 ; ignored
|
||||
.byte <((__BSS_RUN__ - __STARTADDRESS__ + 127) / 128) ; # of 128-byte records to read
|
||||
.byte <((__INIT_RUN__ - __STARTADDRESS__ + 127) / 128) ; # of 128-byte records to read
|
||||
.word __STARTADDRESS__ ; load address
|
||||
.word _cas_init ; init address
|
||||
|
||||
@@ -31,6 +31,8 @@ _cas_hdr:
|
||||
ldy #80
|
||||
sta (SAVMSC),y
|
||||
.endif
|
||||
lda #$3c ; motor off
|
||||
sta PACTL
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ _cclearxy:
|
||||
_cclear:
|
||||
cmp #0 ; Is the length zero?
|
||||
beq L9 ; Jump if done
|
||||
sta tmp1
|
||||
sta tmp1
|
||||
L1: lda #0 ; Blank - screen code
|
||||
jsr cputdirect ; Direct output
|
||||
dec tmp1
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
; originally by Ullrich von Bassewitz and Sidney Cadot
|
||||
;
|
||||
; clock_t clock (void);
|
||||
; unsigned _clocks_per_sec (void);
|
||||
; clock_t __clocks_per_sec (void);
|
||||
;
|
||||
|
||||
.export _clock, __clocks_per_sec
|
||||
.export _clock, ___clocks_per_sec
|
||||
.importzp sreg
|
||||
|
||||
.include "atari.inc"
|
||||
@@ -28,10 +28,12 @@
|
||||
.endproc
|
||||
|
||||
|
||||
.proc __clocks_per_sec
|
||||
.proc ___clocks_per_sec
|
||||
|
||||
ldx #$00 ; Clear high byte of return value
|
||||
lda PAL ; use hw register, PALNTS is only supported on XL/XE ROM
|
||||
ldx #$00 ; Clear byte 1 of return value
|
||||
stx sreg ; Clear byte 2 of return value
|
||||
stx sreg+1 ; Clear byte 3 of return value
|
||||
lda PAL ; Use hw register, PALNTS is only supported on XL/XE ROM
|
||||
and #$0e
|
||||
bne @NTSC
|
||||
lda #50
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
.include "atari.inc"
|
||||
.export _close
|
||||
.import __do_oserror,popax,__oserror
|
||||
.import __do_oserror,popax,___oserror
|
||||
.import fdtoiocb_down,__inviocb
|
||||
|
||||
.proc _close
|
||||
@@ -18,7 +18,7 @@
|
||||
jsr CIOV
|
||||
bmi closerr
|
||||
ok: ldx #0
|
||||
stx __oserror ; clear system specific error code
|
||||
stx ___oserror ; clear system specific error code
|
||||
txa
|
||||
rts
|
||||
|
||||
|
||||
35
libsrc/atari/cpeekc.s
Normal file
35
libsrc/atari/cpeekc.s
Normal file
@@ -0,0 +1,35 @@
|
||||
;
|
||||
; 2016-02-28, Groepaz
|
||||
; 2017-06-21, Greg King
|
||||
;
|
||||
; char cpeekc (void);
|
||||
;
|
||||
|
||||
.export _cpeekc
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
|
||||
_cpeekc:
|
||||
lda OLDCHR ; get char under cursor
|
||||
and #<~$80 ; remove reverse bit
|
||||
|
||||
;; convert internal screen code to AtSCII
|
||||
|
||||
tay
|
||||
and #%01100000
|
||||
asl a
|
||||
asl a
|
||||
rol a
|
||||
rol a
|
||||
tax
|
||||
tya
|
||||
eor intats,x
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
.rodata
|
||||
intats: .byte %00100000 ; -> %001xxxxx
|
||||
.byte %01100000 ; -> %010xxxxx
|
||||
.byte %01000000 ; -> %000xxxxx
|
||||
.byte %00000000 ; -> %011xxxxx
|
||||
8
libsrc/atari/cpeekcolor.s
Normal file
8
libsrc/atari/cpeekcolor.s
Normal file
@@ -0,0 +1,8 @@
|
||||
;
|
||||
; 2017-06-03, Greg King
|
||||
;
|
||||
; unsigned char cpeekcolor (void);
|
||||
;
|
||||
|
||||
.import return1
|
||||
.export _cpeekcolor := return1 ; always COLOR_WHITE
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user