Merge https://github.com/cc65/cc65 into c1p
This commit is contained in:
167
libsrc/Makefile
167
libsrc/Makefile
@@ -1,3 +1,7 @@
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
CBMS = c128 \
|
||||
c16 \
|
||||
c64 \
|
||||
@@ -14,6 +18,7 @@ TARGETS = apple2 \
|
||||
apple2enh \
|
||||
atari \
|
||||
atarixl \
|
||||
atari5200 \
|
||||
atmos \
|
||||
c1p \
|
||||
$(CBMS) \
|
||||
@@ -30,6 +35,27 @@ DRVTYPES = emd \
|
||||
ser \
|
||||
tgi
|
||||
|
||||
OUTPUTDIRS := lib \
|
||||
$(DRVTYPES) \
|
||||
targetutil \
|
||||
asminc \
|
||||
cfg \
|
||||
include \
|
||||
$(subst ../,,$(filter-out $(wildcard ../include/*.*),$(wildcard ../include/*)))
|
||||
|
||||
.PHONY: all mostlyclean clean install zip lib $(TARGETS)
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
ifdef CMD_EXE
|
||||
DIRLIST = $(strip $(foreach dir,$1,$(wildcard $(dir))))
|
||||
MKDIR = mkdir $(subst /,\,$1)
|
||||
RMDIR = $(if $(DIRLIST),rmdir /s /q $(subst /,\,$(DIRLIST)))
|
||||
else
|
||||
MKDIR = mkdir -p $1
|
||||
RMDIR = $(RM) -r $1
|
||||
endif
|
||||
|
||||
# Every target requires its individual vpath setting but the vpath directive
|
||||
# acts globally. Therefore each target is built in a separate make instance.
|
||||
|
||||
@@ -39,37 +65,55 @@ ifeq ($(words $(MAKECMDGOALS)),1)
|
||||
endif
|
||||
endif
|
||||
|
||||
DIRLIST = $(strip $(foreach dir,$1,$(wildcard $(dir))))
|
||||
|
||||
ifeq ($(shell echo),)
|
||||
MKDIR = mkdir -p $1
|
||||
RMDIR = $(RM) -r $1
|
||||
else
|
||||
MKDIR = mkdir $(subst /,\,$1)
|
||||
RMDIR = $(if $(DIRLIST),rmdir /s /q $(subst /,\,$(DIRLIST)))
|
||||
endif
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
.PHONY: all lib $(TARGETS) mostlyclean clean
|
||||
|
||||
ifndef TARGET
|
||||
|
||||
datadir = $(prefix)/share/cc65
|
||||
|
||||
all lib: $(TARGETS)
|
||||
|
||||
mostlyclean:
|
||||
$(call RMDIR,../libwrk)
|
||||
|
||||
clean:
|
||||
$(call RMDIR,../libwrk ../lib ../targetutil $(addprefix ../,$(DRVTYPES)))
|
||||
|
||||
ifdef CMD_EXE
|
||||
|
||||
install:
|
||||
|
||||
else # CMD_EXE
|
||||
|
||||
INSTALL = install
|
||||
|
||||
define INSTALL_recipe
|
||||
|
||||
$(if $(prefix),,$(error variable `prefix' must be set))
|
||||
$(INSTALL) -d $(DESTDIR)$(datadir)/$(dir)
|
||||
$(INSTALL) -m644 ../$(dir)/*.* $(DESTDIR)$(datadir)/$(dir)
|
||||
|
||||
endef # INSTALL_recipe
|
||||
|
||||
install:
|
||||
$(foreach dir,$(OUTPUTDIRS),$(INSTALL_recipe))
|
||||
|
||||
endif # CMD_EXE
|
||||
|
||||
define ZIP_recipe
|
||||
|
||||
@cd .. && zip cc65 $(dir)/*.*
|
||||
|
||||
endef # ZIP_recipe
|
||||
|
||||
zip:
|
||||
$(foreach dir,$(OUTPUTDIRS),$(ZIP_recipe))
|
||||
|
||||
$(TARGETS):
|
||||
@$(MAKE) --no-print-directory $@
|
||||
|
||||
mostlyclean:
|
||||
$(call RMDIR,../wrk)
|
||||
|
||||
clean:
|
||||
$(call RMDIR,../wrk ../lib ../targetutil $(addprefix ../,$(DRVTYPES)))
|
||||
|
||||
else # TARGET
|
||||
|
||||
CA65FLAGS =
|
||||
CC65FLAGS = -Osir -W error
|
||||
CC65FLAGS = -Or -W error
|
||||
|
||||
EXTZP = cbm510 \
|
||||
cbm610 \
|
||||
@@ -77,9 +121,12 @@ EXTZP = cbm510 \
|
||||
|
||||
MKINC = $(GEOS) \
|
||||
atari \
|
||||
atarixl \
|
||||
nes
|
||||
|
||||
TARGETUTIL = apple2 \
|
||||
TARGETUTIL = apple2 \
|
||||
apple2enh \
|
||||
atari \
|
||||
geos-apple
|
||||
|
||||
GEOSDIRS = common \
|
||||
@@ -137,7 +184,7 @@ vpath %.c $(SRCDIRS)
|
||||
OBJS := $(patsubst %.s,%.o,$(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.s)))
|
||||
OBJS += $(patsubst %.c,%.o,$(foreach dir,$(SRCDIRS),$(wildcard $(dir)/*.c)))
|
||||
|
||||
OBJS := $(addprefix ../wrk/$(TARGET)/,$(sort $(notdir $(OBJS))))
|
||||
OBJS := $(addprefix ../libwrk/$(TARGET)/,$(sort $(notdir $(OBJS))))
|
||||
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
|
||||
@@ -145,106 +192,96 @@ EXTRA_SRCPAT = $(SRCDIR)/extra/%.s
|
||||
EXTRA_OBJPAT = ../lib/$(TARGET)-%.o
|
||||
EXTRA_OBJS := $(patsubst $(EXTRA_SRCPAT),$(EXTRA_OBJPAT),$(wildcard $(SRCDIR)/extra/*.s))
|
||||
|
||||
ZPOBJ = ../wrk/$(TARGET)/zeropage.o
|
||||
ZPOBJ = ../libwrk/$(TARGET)/zeropage.o
|
||||
ifeq ($(TARGET),$(filter $(TARGET),$(EXTZP)))
|
||||
ZPOBJ += ../wrk/$(TARGET)/extzp.o
|
||||
ZPOBJ += ../libwrk/$(TARGET)/extzp.o
|
||||
endif
|
||||
|
||||
ifeq ($(SRCDIR),$(filter $(SRCDIR),$(MKINC)))
|
||||
ifeq ($(TARGET),$(filter $(TARGET),$(MKINC)))
|
||||
include $(SRCDIR)/Makefile.inc
|
||||
endif
|
||||
|
||||
ifeq ($(SRCDIR),$(filter $(SRCDIR),$(TARGETUTIL)))
|
||||
ifeq ($(TARGET),$(filter $(TARGET),$(TARGETUTIL)))
|
||||
include $(SRCDIR)/targetutil/Makefile.inc
|
||||
endif
|
||||
|
||||
##########
|
||||
|
||||
define DRVTYPE_template
|
||||
|
||||
$1_SRCDIR = $$(SRCDIR)/$1
|
||||
$1_OBJDIR = ../wrk/$$(TARGET)/$1
|
||||
$1_STCDIR = ../libwrk/$$(TARGET)
|
||||
$1_DYNDIR = ../libwrk/$$(TARGET)/$1
|
||||
$1_DRVDIR = ../$1
|
||||
|
||||
$1_OBJPAT = $$($1_OBJDIR)/$$(OBJPFX)%.o
|
||||
$1_SRCPAT = $$($1_SRCDIR)/$$(OBJPFX)%.s
|
||||
$1_STCPAT = $$($1_STCDIR)/$$(OBJPFX)%-$1.o
|
||||
$1_DYNPAT = $$($1_DYNDIR)/$$(OBJPFX)%.o
|
||||
$1_DRVPAT = $$($1_DRVDIR)/$$(DRVPFX)%.$1
|
||||
$1_STCPAT = ../wrk/$$(TARGET)/$$(DRVPFX)%-$1.o
|
||||
|
||||
$1_OBJS := $$(patsubst $$($1_SRCDIR)/%.s,$$($1_OBJDIR)/%.o,$$(wildcard $$($1_SRCDIR)/*.s))
|
||||
$1_SRCS := $$(wildcard $$($1_SRCDIR)/*.s)
|
||||
$1_STCS = $$(patsubst $$($1_SRCPAT),$$($1_STCPAT),$$($1_SRCS))
|
||||
$1_DYNS = $$(patsubst $$($1_SRCPAT),$$($1_DYNPAT),$$($1_SRCS))
|
||||
$1_DRVS = $$(patsubst $$($1_DYNPAT),$$($1_DRVPAT),$$($1_DYNS))
|
||||
|
||||
$1_DRVS = $$(patsubst $$($1_OBJPAT),$$($1_DRVPAT),$$($1_OBJS))
|
||||
$$($1_STCPAT): $$($1_SRCPAT)
|
||||
@echo $$(TARGET) - $$< - static
|
||||
@$$(CA65) -t $$(TARGET) -D DYN_DRV=0 $$(CA65FLAGS) --create-dep $$(@:.o=.d) -o $$@ $$<
|
||||
|
||||
$1_STCS = $$(patsubst $$($1_DRVPAT),$$($1_STCPAT),$$($1_DRVS))
|
||||
OBJS += $$($1_STCS)
|
||||
DEPS += $$($1_STCS:.o=.d)
|
||||
|
||||
$$($1_OBJS): | $$($1_OBJDIR)
|
||||
$$($1_DYNS): | $$($1_DYNDIR)
|
||||
|
||||
$$($1_DRVPAT): $$($1_OBJPAT) $$(ZPOBJ) | $$($1_DRVDIR)
|
||||
@echo $$(TARGET) - $$(@F)
|
||||
$$($1_DRVPAT): $$($1_DYNPAT) $$(ZPOBJ) | $$($1_DRVDIR)
|
||||
@echo $$(TARGET) - $$(<F)
|
||||
@$$(LD65) -o $$@ -t module $$^
|
||||
|
||||
$$($1_OBJDIR) $$($1_DRVDIR):
|
||||
$$($1_DYNDIR) $$($1_DRVDIR):
|
||||
@$$(call MKDIR,$$@)
|
||||
|
||||
$(TARGET): $$($1_DRVS)
|
||||
|
||||
$$($1_STCPAT): $$($1_DRVPAT)
|
||||
@echo $$(TARGET) - $$(<F)
|
||||
@$$(CO65) -o $$(@:.o=.s) --code-label _$$(subst -,_,$$(subst .,_,$$(<F))) $$<
|
||||
@$$(CA65) -t $$(TARGET) -o $$@ $$(@:.o=.s)
|
||||
DEPS += $$($1_DYNS:.o=.d)
|
||||
|
||||
OBJS += $$($1_STCS)
|
||||
|
||||
DEPS += $$($1_OBJS:.o=.d)
|
||||
|
||||
endef
|
||||
|
||||
##########
|
||||
endef # DRVTYPE_template
|
||||
|
||||
$(foreach drvtype,$(DRVTYPES),$(eval $(call DRVTYPE_template,$(drvtype))))
|
||||
|
||||
AR65 := $(if $(wildcard ../bin/ar65*),../bin/ar65,ar65)
|
||||
CA65 := $(if $(wildcard ../bin/ca65*),../bin/ca65,ca65)
|
||||
CC65 := $(if $(wildcard ../bin/cc65*),../bin/cc65,cc65)
|
||||
CO65 := $(if $(wildcard ../bin/co65*),../bin/co65,co65)
|
||||
LD65 := $(if $(wildcard ../bin/ld65*),../bin/ld65,ld65)
|
||||
|
||||
export CC65_HOME := $(abspath ..)
|
||||
|
||||
##########
|
||||
|
||||
define ASSEMBLE_recipe
|
||||
|
||||
$(if $(TRAVIS),,@echo $(TARGET) - $<)
|
||||
$(if $(QUIET),,@echo $(TARGET) - $<)
|
||||
@$(CA65) -t $(TARGET) $(CA65FLAGS) --create-dep $(@:.o=.d) -o $@ $<
|
||||
|
||||
endef
|
||||
|
||||
##########
|
||||
endef # ASSEMBLE_recipe
|
||||
|
||||
define COMPILE_recipe
|
||||
|
||||
$(if $(TRAVIS),,@echo $(TARGET) - $<)
|
||||
$(if $(QUIET),,@echo $(TARGET) - $<)
|
||||
@$(CC65) -t $(TARGET) $(CC65FLAGS) --create-dep $(@:.o=.d) --dep-target $@ -o $(@:.o=.s) $<
|
||||
@$(CA65) -t $(TARGET) -o $@ $(@:.o=.s)
|
||||
|
||||
endef
|
||||
endef # COMPILE_recipe
|
||||
|
||||
##########
|
||||
|
||||
../wrk/$(TARGET)/%.o: %.s | ../wrk/$(TARGET)
|
||||
../libwrk/$(TARGET)/%.o: %.s | ../libwrk/$(TARGET)
|
||||
$(ASSEMBLE_recipe)
|
||||
|
||||
../wrk/$(TARGET)/%.o: %.c | ../wrk/$(TARGET)
|
||||
../libwrk/$(TARGET)/%.o: %.c | ../libwrk/$(TARGET)
|
||||
$(COMPILE_recipe)
|
||||
|
||||
$(EXTRA_OBJPAT): $(EXTRA_SRCPAT) | ../lib
|
||||
@echo $(TARGET) - $(@F)
|
||||
@echo $(TARGET) - $(<F)
|
||||
@$(CA65) -t $(TARGET) $(CA65FLAGS) -o $@ $<
|
||||
|
||||
../lib/$(TARGET).lib: $(OBJS) | ../lib
|
||||
$(AR65) a $@ $?
|
||||
|
||||
../wrk/$(TARGET) ../lib ../targetutil:
|
||||
../libwrk/$(TARGET) ../lib ../targetutil:
|
||||
@$(call MKDIR,$@)
|
||||
|
||||
$(TARGET): $(EXTRA_OBJS) ../lib/$(TARGET).lib
|
||||
|
||||
@@ -24,76 +24,76 @@
|
||||
ldx #$FF
|
||||
txs ; Init stack pointer
|
||||
|
||||
; Switch in LC bank 2 for W/O
|
||||
; Switch in LC bank 2 for W/O.
|
||||
bit $C081
|
||||
bit $C081
|
||||
|
||||
; Set source start address
|
||||
; Set the source start address.
|
||||
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
|
||||
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
|
||||
sta $9B
|
||||
sty $9C
|
||||
|
||||
; Set source last address
|
||||
; Set the source last address.
|
||||
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
|
||||
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__ + __LC_LAST__ - __LC_START__)
|
||||
sta $96
|
||||
sty $97
|
||||
|
||||
; Set destination last address
|
||||
; Set the destination last address.
|
||||
lda #<__LC_LAST__
|
||||
ldy #>__LC_LAST__
|
||||
sta $94
|
||||
sty $95
|
||||
|
||||
; Call into Applesoft Block Transfer Utility - which handles zero
|
||||
; sized blocks well - to move content of the LC memory area
|
||||
; Call into the Applesoft Block Transfer Utility -- which handles zero-
|
||||
; sized blocks well -- to move the content of the LC memory area.
|
||||
jsr $D396 ; BLTU + 3
|
||||
|
||||
; Set source start address
|
||||
; Set the source start address.
|
||||
lda #<__ZPSAVE_RUN__
|
||||
ldy #>__ZPSAVE_RUN__
|
||||
sta $9B
|
||||
sty $9C
|
||||
|
||||
; Set source last address
|
||||
; Set the source last address.
|
||||
lda #<(__ZPSAVE_RUN__ + __INIT_SIZE__)
|
||||
ldy #>(__ZPSAVE_RUN__ + __INIT_SIZE__)
|
||||
sta $96
|
||||
sty $97
|
||||
|
||||
; Set destination last address
|
||||
; Set the destination last address.
|
||||
lda #<(__INIT_RUN__ + __INIT_SIZE__)
|
||||
ldy #>(__INIT_RUN__ + __INIT_SIZE__)
|
||||
sta $94
|
||||
sty $95
|
||||
|
||||
; Call into Applesoft Block Transfer Utility - which handles moving
|
||||
; overlapping blocks upwards well - to move the INIT segment
|
||||
; Call into the Applesoft Block Transfer Utility -- which handles moving
|
||||
; overlapping blocks upwards well -- to move the INIT segment.
|
||||
jsr $D396 ; BLTU + 3
|
||||
|
||||
; Delegate all further processing to keep the STARTUP segment small
|
||||
; Delegate all further processing, to keep the STARTUP segment small.
|
||||
jsr init
|
||||
|
||||
; Avoid re-entrance of donelib. This is also the _exit entry
|
||||
; 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
|
||||
; Switch in ROM, in case it wasn't already switched in by a RESET.
|
||||
bit $C082
|
||||
|
||||
; Call module destructors
|
||||
; Call the module destructors.
|
||||
jsr donelib
|
||||
|
||||
; Restore the original RESET vector
|
||||
; Restore the original RESET vector.
|
||||
exit: ldx #$02
|
||||
: lda rvsave,x
|
||||
sta SOFTEV,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; Copy back the zero page stuff
|
||||
; Copy back the zero-page stuff.
|
||||
ldx #zpspace-1
|
||||
: lda zpsave,x
|
||||
sta sp,x
|
||||
@@ -107,21 +107,21 @@ exit: ldx #$02
|
||||
txs ; Re-init stack pointer
|
||||
|
||||
; We're done
|
||||
jmp (done)
|
||||
jmp done
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
; Save the zero page locations we need
|
||||
; Save the zero-page locations that we need.
|
||||
init: ldx #zpspace-1
|
||||
: lda sp,x
|
||||
sta zpsave,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; Clear the BSS data
|
||||
; Clear the BSS data.
|
||||
jsr zerobss
|
||||
|
||||
; Save the original RESET vector
|
||||
; Save the original RESET vector.
|
||||
ldx #$02
|
||||
: lda SOFTEV,x
|
||||
sta rvsave,x
|
||||
@@ -135,58 +135,58 @@ init: ldx #zpspace-1
|
||||
lda #>_exit
|
||||
jsr reset ; Setup RESET vector
|
||||
|
||||
; Check for ProDOS
|
||||
; Check for ProDOS.
|
||||
ldy $BF00 ; MLI call entry point
|
||||
cpy #$4C ; Is MLI present? (JMP opcode)
|
||||
bne basic
|
||||
|
||||
; Check ProDOS system bit map
|
||||
|
||||
; Check the ProDOS system bit map.
|
||||
lda $BF6F ; Protection for pages $B8 - $BF
|
||||
cmp #%00000001 ; Exactly system global page is protected
|
||||
bne basic
|
||||
|
||||
; No BASIC.SYSTEM so quit to ProDOS dispatcher instead
|
||||
; No BASIC.SYSTEM; so, quit to the ProDOS dispatcher instead.
|
||||
lda #<quit
|
||||
ldx #>quit
|
||||
sta done
|
||||
stx done+1
|
||||
|
||||
; No BASIC.SYSTEM so use addr of ProDOS system global page
|
||||
sta done+1
|
||||
stx done+2
|
||||
|
||||
; No BASIC.SYSTEM; so, use the addr of the ProDOS system global page.
|
||||
lda #<$BF00
|
||||
ldx #>$BF00
|
||||
bne :+ ; Branch always
|
||||
|
||||
; Get highest available mem addr from BASIC interpreter
|
||||
; Get the highest available mem addr from the BASIC interpreter.
|
||||
basic: lda HIMEM
|
||||
ldx HIMEM+1
|
||||
|
||||
; Setup the C stack
|
||||
; Set up the C stack.
|
||||
: sta sp
|
||||
stx sp+1
|
||||
|
||||
; Enable interrupts as old ProDOS versions (i.e. 1.1.1)
|
||||
; jump to SYS and BIN programs with interrupts disabled
|
||||
; Enable interrupts, as old ProDOS versions (i.e. 1.1.1)
|
||||
; jump to SYS and BIN programs with interrupts disabled.
|
||||
cli
|
||||
|
||||
; Call module constructors
|
||||
; Call the module constructors.
|
||||
jsr initlib
|
||||
|
||||
; Switch in LC bank 2 for R/O
|
||||
; Switch in LC bank 2 for R/O.
|
||||
bit $C080
|
||||
|
||||
; Push arguments and call main()
|
||||
; Push the command-line arguments; and, call main().
|
||||
jmp callmain
|
||||
|
||||
.code
|
||||
|
||||
; Setup RESET vector
|
||||
; Set up the RESET vector.
|
||||
reset: stx SOFTEV
|
||||
sta SOFTEV+1
|
||||
eor #$A5
|
||||
sta PWREDUP
|
||||
return: rts
|
||||
|
||||
; Quit to ProDOS dispatcher
|
||||
; Quit to the ProDOS dispatcher.
|
||||
quit: jsr $BF00 ; MLI call entry point
|
||||
.byte $65 ; Quit
|
||||
.word q_param
|
||||
@@ -202,8 +202,8 @@ q_param:.byte $04 ; param_count
|
||||
|
||||
.data
|
||||
|
||||
; Location to jump to when we're done
|
||||
done: .addr DOSWARM
|
||||
; Final jump when we're done
|
||||
done: jmp DOSWARM ; Potentially patched at runtime
|
||||
|
||||
.segment "ZPSAVE"
|
||||
|
||||
|
||||
@@ -10,10 +10,16 @@
|
||||
.include "em-kernel.inc"
|
||||
.include "em-error.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __APPLE2ENH__
|
||||
module_header _a2e_auxmem_emd
|
||||
.else
|
||||
module_header _a2_auxmem_emd
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -161,8 +161,8 @@ setbuf: lda #$00 ; Low byte
|
||||
; Call loader stub after C libary shutdown
|
||||
lda #<target
|
||||
ldx #>target
|
||||
sta done
|
||||
stx done+1
|
||||
sta done+1
|
||||
stx done+2
|
||||
|
||||
; Initiate C libary shutdown
|
||||
jmp _exit
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
.include "joy-error.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
; Constants
|
||||
@@ -29,7 +31,11 @@ PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
|
||||
|
||||
; Header. Includes jump table.
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __APPLE2ENH__
|
||||
module_header _a2e_stdjoy_joy
|
||||
.else
|
||||
module_header _a2_stdjoy_joy
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
.bss
|
||||
|
||||
backup: .res 1
|
||||
visible:.res 1
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
@@ -25,6 +26,8 @@ backup: .res 1
|
||||
_mouse_def_callbacks:
|
||||
.addr hide
|
||||
.addr show
|
||||
.addr prep
|
||||
.addr draw
|
||||
.addr movex
|
||||
.addr movey
|
||||
|
||||
@@ -65,10 +68,15 @@ done:
|
||||
.ifdef __APPLE2ENH__
|
||||
bit LOWSCR ; Doesn't hurt in 40 column mode
|
||||
.endif
|
||||
rts
|
||||
return: rts
|
||||
|
||||
; Hide the mouse cursor.
|
||||
hide:
|
||||
dec visible
|
||||
; Fall through
|
||||
|
||||
; Prepare to move the mouse cursor.
|
||||
prep:
|
||||
jsr getcursor ; Cursor visible at current position?
|
||||
bne done ; No, we're done
|
||||
lda backup ; Get character at cursor position
|
||||
@@ -76,6 +84,13 @@ hide:
|
||||
|
||||
; Show the mouse cursor.
|
||||
show:
|
||||
inc visible
|
||||
; Fall through
|
||||
|
||||
; Draw the mouse cursor.
|
||||
draw:
|
||||
lda visible
|
||||
beq return
|
||||
jsr getcursor ; Cursor visible at current position?
|
||||
beq done ; Yes, we're done
|
||||
sta backup ; Save character at cursor position
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
.include "mouse-kernel.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
SETMOUSE = $12 ; Sets mouse mode
|
||||
@@ -28,7 +30,11 @@ status := $0778
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __APPLE2ENH__
|
||||
module_header _a2e_stdmou_mou
|
||||
.else
|
||||
module_header _a2_stdmou_mou
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
.byte $6D, $6F, $75 ; "mou"
|
||||
@@ -57,6 +63,8 @@ status := $0778
|
||||
; Callback table, set by the kernel before INSTALL is called
|
||||
CHIDE: jmp $0000 ; Hide the cursor
|
||||
CSHOW: jmp $0000 ; Show the cursor
|
||||
CPREP: jmp $0000 ; Prepare to move the cursor
|
||||
CDRAW: jmp $0000 ; Draw the cursor
|
||||
CMOVEX: jmp $0000 ; Move the cursor to X coord
|
||||
CMOVEY: jmp $0000 ; Move the cursor to Y coord
|
||||
|
||||
@@ -67,7 +75,6 @@ CMOVEY: jmp $0000 ; Move the cursor to Y coord
|
||||
box: .tag MOUSE_BOX
|
||||
info: .tag MOUSE_INFO
|
||||
slot: .res 1
|
||||
visible:.res 1
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
@@ -321,7 +328,6 @@ MOVE:
|
||||
; no special action is required besides hiding the mouse cursor.
|
||||
; No return code required.
|
||||
HIDE:
|
||||
dec visible
|
||||
sei
|
||||
jsr CHIDE
|
||||
cli
|
||||
@@ -333,7 +339,9 @@ HIDE:
|
||||
; no special action is required besides enabling the mouse cursor.
|
||||
; No return code required.
|
||||
SHOW:
|
||||
inc visible
|
||||
sei
|
||||
jsr CSHOW
|
||||
cli
|
||||
rts
|
||||
|
||||
; BUTTONS: Return the button mask in A/X.
|
||||
@@ -409,7 +417,7 @@ done: rts
|
||||
beq :+
|
||||
|
||||
; Remove the cursor at the old position
|
||||
update: jsr CHIDE
|
||||
update: jsr CPREP
|
||||
|
||||
; Get and set the new X position
|
||||
ldy slot
|
||||
@@ -427,11 +435,7 @@ update: jsr CHIDE
|
||||
stx info + MOUSE_POS::YCOORD+1
|
||||
jsr CMOVEY
|
||||
|
||||
; Check for visibility
|
||||
: lda visible
|
||||
beq :+
|
||||
|
||||
; Draw the cursor at the new position
|
||||
jsr CSHOW
|
||||
: sec ; Interrupt handled
|
||||
: jsr CDRAW
|
||||
sec ; Interrupt handled
|
||||
rts
|
||||
|
||||
@@ -16,6 +16,6 @@ initreboot:
|
||||
; Quit to PWRUP
|
||||
lda #<$FAA6
|
||||
ldx #>$FAA6
|
||||
sta done
|
||||
stx done+1
|
||||
sta done+1
|
||||
stx done+2
|
||||
rts
|
||||
|
||||
@@ -25,10 +25,16 @@
|
||||
.include "ser-kernel.inc"
|
||||
.include "ser-error.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __APPLE2ENH__
|
||||
module_header _a2e_ssc_ser
|
||||
.else
|
||||
module_header _a2_ssc_ser
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
;
|
||||
; time_t _systime (void);
|
||||
; /* Similar to time(), but:
|
||||
; * - Is not ISO C
|
||||
; * - Does not take the additional pointer
|
||||
; * - Does not set errno when returning -1
|
||||
; */
|
||||
; ** - Is not ISO C
|
||||
; ** - Does not take the additional pointer
|
||||
; ** - Does not set errno when returning -1
|
||||
; */
|
||||
;
|
||||
|
||||
.include "time.inc"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
DEPS += ../wrk/$(TARGET)/loader.d
|
||||
DEPS += ../libwrk/$(TARGET)/loader.d
|
||||
|
||||
../wrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../wrk/$(TARGET)
|
||||
../libwrk/$(TARGET)/loader.o: $(SRCDIR)/targetutil/loader.s | ../libwrk/$(TARGET)
|
||||
$(ASSEMBLE_recipe)
|
||||
|
||||
../targetutil/loader.system: ../wrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../targetutil
|
||||
../targetutil/loader.system: ../libwrk/$(TARGET)/loader.o $(SRCDIR)/targetutil/loader.cfg | ../targetutil
|
||||
$(LD65) -o $@ -C $(filter %.cfg,$^) $(filter-out %.cfg,$^)
|
||||
|
||||
$(TARGET): ../targetutil/loader.system
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
LOADER.SYSTEM - an Apple][ ProDOS 8 loader for cc65 programs (Oliver Schmidt)
|
||||
=============================================================================
|
||||
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
Apple][ ProDOS 8 system programs (filetype SYS) are always loaded into memory
|
||||
starting at location $2000. This poses the problem of how to make efficient
|
||||
use of the memory in the range $0800-$2000. The usual approach of relocation
|
||||
has two downsides:
|
||||
- Relocating e.g. 30 kB from $2000-$9800 to $0800-$8000 takes a considerable
|
||||
amount of time.
|
||||
- Really large programs just don't fit into memory when loaded starting at
|
||||
location $2000.
|
||||
|
||||
The relocation can be eliminated by loading the major part(s) of the program
|
||||
from disk right to the final location by a rather small system program.
|
||||
|
||||
LOADER.SYSTEM is such a small program. In fact it's so small that it fits into
|
||||
a single block in the ProDOS 8 file system making it a so-called seedling file,
|
||||
which are loaded really fast. LOADER.SYSTEM can load cc65 programs into memory
|
||||
anywhere in the range $0800-$BB00 (44,75 kB).
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Link the cc65 program to the start address $0803 (or any other address) and
|
||||
store it as binary program (filetype BIN). This is in fact no different from
|
||||
a binary program to be run by BASIC.SYSTEM's BRUN command in the usual way.
|
||||
|
||||
If however the cc65 program isn't run by BASIC.SYSTEM but is rather run by
|
||||
LOADER.SYSTEM then it behaves like a system program which means:
|
||||
- It uses memory up to the ProDOS 8 system global page located at $BF00.
|
||||
- It supports the ProDOS 8 startup file mechanism (mapped to argv[1]).
|
||||
- It quits to the ProDOS 8 dispatcher.
|
||||
|
||||
Obviously LOADER.SYSTEM has to be told which cc65 program to run. Unfortunately
|
||||
the ProDOS 8 dispatcher has no notion of system program parameters so the usual
|
||||
approach would have been to make LOADER.SYSTEM bring up yet another menu to
|
||||
select the cc65 program to run.
|
||||
|
||||
But to allow to select the cc65 program directly from the ProDOS 8 dispatcher
|
||||
anyway LOADER.SYSTEM detects the path to the cc65 program from its own path by
|
||||
just removing the '.SYSTEM' from its name. So if you want to run the cc65
|
||||
program MYPROGRAM you'll need a copy of LOADER.SYSTEM in the same directory
|
||||
being renamed to MYPROGRAM.SYSTEM.
|
||||
|
||||
This means you will end up with a copy of LOADER.SYSTEM for every cc65 program
|
||||
to be run by it. But as LOADER.SYSTEM is a ProDOS 8 seedling file using up only
|
||||
a single block in the ProDOS 8 file system this should be no issue.
|
||||
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
In case you want to build 'loader.system' from the source code yourself you can
|
||||
do so using the following commands:
|
||||
|
||||
ca65 loader.s
|
||||
ld65 -C loader.cfg -o loader.system loader.o
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
The file 'loader.system' as generated by the cc65 linker with the command above
|
||||
does NOT include the 4-byte address/length header that is generated for Apple][
|
||||
programs by default. This is because ProDOS 8 system programs are always loaded
|
||||
into memory starting at location $2000.
|
||||
|
||||
The recommended way to transfer 'loader.system' from your native file system to
|
||||
a ProDOS 8 file system disk image is to use AppleCommander which is available at
|
||||
http://applecommander.sourceforge.net/
|
||||
|
||||
If you want to put the file 'loader.system' onto a disk image 'mydisk.dsk' as
|
||||
system program MYPROGRAM.SYSTEM you can do so using the following command:
|
||||
|
||||
java -jar ac.jar -p mydisk.dsk MYPROGRAM.SYSTEM sys < loader.system
|
||||
@@ -11,6 +11,8 @@
|
||||
.include "tgi-error.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
; Zero page stuff
|
||||
@@ -68,7 +70,11 @@ Y2 := ptr4
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __APPLE2ENH__
|
||||
module_header _a2e_hi_tgi
|
||||
.else
|
||||
module_header _a2_hi_tgi
|
||||
.endif
|
||||
|
||||
; Header. Includes jump table and constants.
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
.include "tgi-error.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
; Zero page stuff
|
||||
@@ -38,7 +40,11 @@ Y2 := ptr4
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __APPLE2ENH__
|
||||
module_header _a2e_lo_tgi
|
||||
.else
|
||||
module_header _a2_lo_tgi
|
||||
.endif
|
||||
|
||||
; Header. Includes jump table and constants.
|
||||
|
||||
|
||||
@@ -31,3 +31,7 @@ CA65FLAGS += -D NUMDRVS=4 -D LINEBUF=80 -D UCASE_FILENAME=1 -D DEFAULT_DEVICE=1
|
||||
# Disabled by default, you should enable it if the linker script relocates the
|
||||
# character generator (like atarixl-largehimem.cfg).
|
||||
#CA65FLAGS += -D CHARGEN_RELOC -D USEWSYNC
|
||||
|
||||
# Disable if you don't want to use page 6 for mouse P/M data.
|
||||
# If disabled, top of the RAM is used for P/M data.
|
||||
CA65FLAGS += -D USE_PAGE6
|
||||
|
||||
23
libsrc/atari/carthdr.s
Normal file
23
libsrc/atari/carthdr.s
Normal file
@@ -0,0 +1,23 @@
|
||||
; Cartridge "header"
|
||||
; (In fact, it's at the end of the cartridge, so more a "trailer".)
|
||||
;
|
||||
; Christian Groessler, 06-Jan-2014
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
|
||||
.export __CART_HEADER__: absolute = 1
|
||||
|
||||
.import __CARTSIZE__, __CARTFLAGS__, cartinit, cartstart
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
.segment "CARTHDR"
|
||||
|
||||
.word cartstart ; start routine
|
||||
.byte 0 ; must be zero
|
||||
.byte <__CARTFLAGS__
|
||||
.word cartinit ; init routine
|
||||
|
||||
.assert (__CARTSIZE__ = $2000 || __CARTSIZE__ = $4000), error, "Cartridge size must either be $2000 or $4000"
|
||||
|
||||
.endif ; .ifndef __ATARIXL__
|
||||
11
libsrc/atari/cartinit.s
Normal file
11
libsrc/atari/cartinit.s
Normal file
@@ -0,0 +1,11 @@
|
||||
; Cartridge init routine
|
||||
;
|
||||
; Christian Groessler, 06-Jan-2014
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
|
||||
.export cartinit
|
||||
|
||||
cartinit: rts
|
||||
|
||||
.endif ; .ifndef __ATARIXL__
|
||||
20
libsrc/atari/cartstart.s
Normal file
20
libsrc/atari/cartstart.s
Normal file
@@ -0,0 +1,20 @@
|
||||
; Cartridge start routine
|
||||
;
|
||||
; Christian Groessler, 06-Jan-2014
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
|
||||
.export cartstart
|
||||
|
||||
.import start, copydata
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
; start routine of cartridge
|
||||
; copy data segment to RAM and chain to entry point of crt0.s
|
||||
|
||||
cartstart: jsr copydata
|
||||
jsr start ; run program
|
||||
jmp (DOSVEC) ; return to DOS
|
||||
|
||||
.endif ; .ifndef __ATARIXL__
|
||||
37
libsrc/atari/cashdr.s
Normal file
37
libsrc/atari/cashdr.s
Normal file
@@ -0,0 +1,37 @@
|
||||
;
|
||||
; Cassette boot file header
|
||||
;
|
||||
; Christian Groessler, chris@groessler.org, 2014
|
||||
;
|
||||
|
||||
;DEBUG = 1
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
.import __BSS_RUN__, __STARTADDRESS__, _cas_init
|
||||
.export _cas_hdr
|
||||
|
||||
.assert ((__BSS_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
|
||||
|
||||
.segment "CASHDR"
|
||||
|
||||
_cas_hdr:
|
||||
.byte 0 ; ignored
|
||||
.byte <((__BSS_RUN__ - __STARTADDRESS__ + 127) / 128) ; # of 128-byte records to read
|
||||
.word __STARTADDRESS__ ; load address
|
||||
.word _cas_init ; init address
|
||||
|
||||
.ifdef DEBUG
|
||||
lda #33
|
||||
ldy #80
|
||||
sta (SAVMSC),y
|
||||
.endif
|
||||
clc
|
||||
rts
|
||||
|
||||
.endif ; .ifdef __ATARIXL__
|
||||
31
libsrc/atari/casinit.s
Normal file
31
libsrc/atari/casinit.s
Normal file
@@ -0,0 +1,31 @@
|
||||
;
|
||||
; Cassette boot file init routine
|
||||
;
|
||||
; Christian Groessler, chris@groessler.org, 2014
|
||||
;
|
||||
|
||||
;DEBUG = 1
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
.import start
|
||||
.export _cas_init
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
_cas_init:
|
||||
.ifdef DEBUG
|
||||
lda #34
|
||||
ldy #81
|
||||
sta (SAVMSC),y
|
||||
.endif
|
||||
|
||||
lda #<start
|
||||
sta DOSVEC
|
||||
lda #>start
|
||||
sta DOSVEC+1
|
||||
rts
|
||||
|
||||
.endif ; .ifdef __ATARIXL__
|
||||
@@ -14,10 +14,10 @@ _cgetc:
|
||||
jsr setcursor
|
||||
lda #12
|
||||
sta ICAX1Z ; fix problems with direct call to KEYBDV
|
||||
.ifndef __ATARIXL__
|
||||
jsr @1
|
||||
.else
|
||||
.ifdef __ATARIXL__
|
||||
jsr KEYBDV_handler
|
||||
.else
|
||||
jsr @1
|
||||
.endif
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
.import popa, _gotoxy, cputdirect, setcursor
|
||||
.importzp tmp1
|
||||
|
||||
.ifdef __ATARI5200__
|
||||
CHRCODE = 14
|
||||
.else
|
||||
CHRCODE = $12+64
|
||||
.endif
|
||||
|
||||
_chlinexy:
|
||||
pha ; Save the length
|
||||
jsr popa ; Get y
|
||||
@@ -19,12 +25,8 @@ _chline:
|
||||
cmp #0 ; Is the length zero?
|
||||
beq L9 ; Jump if done
|
||||
sta tmp1
|
||||
L1: lda #$12+64 ; Horizontal line, screen code
|
||||
L1: lda #CHRCODE ; Horizontal line, screen code
|
||||
jsr cputdirect ; Direct output
|
||||
dec tmp1
|
||||
bne L1
|
||||
L9: jmp setcursor
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
.segment "STARTUP"
|
||||
|
||||
rts ; fix for SpartaDOS / OS/A+
|
||||
; they first call the entry point from AUTOSTRT and
|
||||
; then the load addess (this rts here).
|
||||
; They first call the entry point from AUTOSTRT; and
|
||||
; then, the load address (this rts here).
|
||||
; We point AUTOSTRT directly after the rts.
|
||||
|
||||
; Real entry point:
|
||||
@@ -44,18 +44,25 @@ start:
|
||||
jsr sram_init
|
||||
.endif
|
||||
|
||||
; Clear the BSS data
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Setup the stack
|
||||
; Set up the stack.
|
||||
|
||||
tsx
|
||||
stx SP_save
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
.ifdef __ATARIXL__
|
||||
|
||||
; Report memory usage
|
||||
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
sta sp
|
||||
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
sta sp+1
|
||||
|
||||
.else
|
||||
|
||||
; Report the memory usage.
|
||||
|
||||
lda APPMHI
|
||||
sta APPMHI_save ; remember old APPMHI value
|
||||
@@ -66,67 +73,60 @@ start:
|
||||
lda MEMTOP
|
||||
sbc #<__RESERVED_MEMORY__
|
||||
sta APPMHI ; initialize our APPMHI value
|
||||
sta sp ; setup runtime stack part 1
|
||||
sta sp ; set up runtime stack part 1
|
||||
lda MEMTOP+1
|
||||
sbc #>__RESERVED_MEMORY__
|
||||
sta APPMHI+1
|
||||
sta sp+1 ; setup runtime stack part 2
|
||||
|
||||
.else
|
||||
|
||||
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
sta sp
|
||||
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
sta sp+1
|
||||
sta sp+1 ; set up runtime stack part 2
|
||||
|
||||
.endif
|
||||
|
||||
; Call module constructors
|
||||
; Call the module constructors.
|
||||
|
||||
jsr initlib
|
||||
|
||||
; Set left margin to 0
|
||||
; Set the left margin to 0.
|
||||
|
||||
lda LMARGN
|
||||
sta LMARGN_save
|
||||
ldy #0
|
||||
sty LMARGN
|
||||
|
||||
; Set keyb to upper/lowercase mode
|
||||
; Set the keyboard to upper-/lower-case mode.
|
||||
|
||||
ldx SHFLOK
|
||||
stx SHFLOK_save
|
||||
sty SHFLOK
|
||||
|
||||
; Initialize conio stuff
|
||||
; Initialize the conio stuff.
|
||||
|
||||
dey ; Set X to $FF
|
||||
sty CH
|
||||
dey ; Set Y to $FF
|
||||
sty CH ; remove keypress which might be in the input buffer
|
||||
|
||||
; Push arguments and call main
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Call module destructors. This is also the _exit entry.
|
||||
; Call the module destructors. This is also the exit() entry.
|
||||
|
||||
_exit: jsr donelib ; Run module destructors
|
||||
|
||||
; Restore system stuff
|
||||
; Restore the system stuff.
|
||||
|
||||
ldx SP_save
|
||||
txs ; Restore stack pointer
|
||||
|
||||
; Restore left margin
|
||||
; Restore the left margin.
|
||||
|
||||
lda LMARGN_save
|
||||
sta LMARGN
|
||||
|
||||
; Restore kb mode
|
||||
; Restore the kb mode.
|
||||
|
||||
lda SHFLOK_save
|
||||
sta SHFLOK
|
||||
|
||||
; Restore APPMHI
|
||||
; Restore APPMHI.
|
||||
|
||||
lda APPMHI_save
|
||||
sta APPMHI
|
||||
@@ -147,8 +147,8 @@ _exit: jsr donelib ; Run module destructors
|
||||
sta MEMTOP+1
|
||||
|
||||
|
||||
; Issue a GRAPHICS 0 call (copied'n'pasted from TGI drivers) in
|
||||
; order to restore screen memory to its defailt location just
|
||||
; Issue a GRAPHICS 0 call (copied'n'pasted from the TGI drivers), in
|
||||
; order to restore screen memory to its default location just
|
||||
; before the ROM.
|
||||
|
||||
jsr findfreeiocb
|
||||
@@ -169,7 +169,7 @@ _exit: jsr donelib ; Run module destructors
|
||||
lda #0
|
||||
sta ICBLH,x
|
||||
jsr CIOV_org
|
||||
; No error checking here, shouldn't happen(tm), and no way to
|
||||
; No error checking here, shouldn't happen(TM); and, no way to
|
||||
; recover anyway.
|
||||
|
||||
lda #CLOSE
|
||||
@@ -178,12 +178,12 @@ _exit: jsr donelib ; Run module destructors
|
||||
|
||||
.endif
|
||||
|
||||
; Turn on cursor
|
||||
; Turn on the cursor.
|
||||
|
||||
ldx #0
|
||||
stx CRSINH
|
||||
|
||||
; Back to DOS
|
||||
; Back to DOS.
|
||||
|
||||
rts
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
.import popa, _gotoxy, putchar, setcursor
|
||||
.importzp tmp1
|
||||
|
||||
.ifdef __ATARI5200__
|
||||
CHRCODE = 1 ; exclamation mark
|
||||
.else
|
||||
CHRCODE = $7C ; Vertical bar
|
||||
.endif
|
||||
|
||||
_cvlinexy:
|
||||
pha ; Save the length
|
||||
jsr popa ; Get y
|
||||
@@ -22,7 +28,7 @@ _cvline:
|
||||
sta tmp1
|
||||
L1: lda COLCRS
|
||||
pha
|
||||
lda #$7C ; Vertical bar
|
||||
lda #CHRCODE ; Vertical bar
|
||||
jsr putchar ; Write, no cursor advance
|
||||
pla
|
||||
sta COLCRS
|
||||
@@ -30,6 +36,3 @@ L1: lda COLCRS
|
||||
dec tmp1
|
||||
bne L1
|
||||
L9: jmp setcursor
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -31,12 +31,17 @@
|
||||
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrx130_emd
|
||||
.else
|
||||
module_header _atr130_emd
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
; This file defines the EXE file "trailer" which sets the entry point
|
||||
|
||||
.export __AUTOSTART__: absolute = 1
|
||||
.import start
|
||||
.import start
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
|
||||
@@ -16,26 +16,24 @@
|
||||
.segment "INIT"
|
||||
|
||||
initirq:
|
||||
lda VVBLKI
|
||||
ldx VVBLKI+1
|
||||
lda VVBLKD
|
||||
ldx VVBLKD+1
|
||||
sta IRQInd+1
|
||||
stx IRQInd+2
|
||||
lda #6
|
||||
lda #7
|
||||
ldy #<IRQStub
|
||||
ldx #>IRQStub
|
||||
jsr SETVBV
|
||||
rts
|
||||
jmp SETVBV
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
doneirq:
|
||||
lda #6
|
||||
lda #7
|
||||
ldy IRQInd+1
|
||||
ldx IRQInd+2
|
||||
jsr SETVBV
|
||||
rts
|
||||
jmp SETVBV
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
@@ -44,7 +42,6 @@ doneirq:
|
||||
IRQStub:
|
||||
cld ; Just to be sure
|
||||
.ifdef __ATARIXL__
|
||||
pha
|
||||
.ifdef CHARGEN_RELOC
|
||||
lda CHBAS
|
||||
pha
|
||||
@@ -64,7 +61,6 @@ IRQStub:
|
||||
sta CHBAS
|
||||
sta CHBASE
|
||||
.endif
|
||||
pla
|
||||
.endif
|
||||
jmp IRQInd ; Jump to the saved IRQ vector
|
||||
|
||||
|
||||
@@ -14,12 +14,17 @@
|
||||
.include "atari.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxmj8_joy
|
||||
.else
|
||||
module_header _atrmj8_joy
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -13,12 +13,17 @@
|
||||
.include "atari.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxstd_joy
|
||||
.else
|
||||
module_header _atrstd_joy
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -7,8 +7,16 @@
|
||||
;
|
||||
|
||||
.export _joy_static_stddrv
|
||||
.ifdef __ATARIXL__
|
||||
.import _atrxstd_joy
|
||||
.else
|
||||
.import _atrstd_joy
|
||||
.endif
|
||||
|
||||
.rodata
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
_joy_static_stddrv := _atrxstd_joy
|
||||
.else
|
||||
_joy_static_stddrv := _atrstd_joy
|
||||
.endif
|
||||
|
||||
@@ -10,4 +10,9 @@
|
||||
|
||||
.rodata
|
||||
|
||||
_joy_stddrv: .asciiz "atrstd.joy"
|
||||
_joy_stddrv:
|
||||
.ifdef __ATARIXL__
|
||||
.asciiz "atrxstd.joy"
|
||||
.else
|
||||
.asciiz "atrstd.joy"
|
||||
.endif
|
||||
|
||||
8
libsrc/atari/mcbdefault.s
Normal file
8
libsrc/atari/mcbdefault.s
Normal file
@@ -0,0 +1,8 @@
|
||||
;
|
||||
; This file defines the default mouse callback
|
||||
;
|
||||
|
||||
.import _mouse_pm_callbacks
|
||||
.export _mouse_def_callbacks
|
||||
|
||||
_mouse_def_callbacks := _mouse_pm_callbacks
|
||||
31
libsrc/atari/mcbpm-shape.s
Normal file
31
libsrc/atari/mcbpm-shape.s
Normal file
@@ -0,0 +1,31 @@
|
||||
;
|
||||
; P/M mouse shape default definition
|
||||
;
|
||||
; Christian Groessler, 11.04.2014
|
||||
;
|
||||
; Note that the height of the mouse cursor must not exceed 32
|
||||
; lines, otherwise the display routines won't do The Right
|
||||
; Thing(tm).
|
||||
;
|
||||
|
||||
.export mouse_pm_bits
|
||||
.export mouse_pm_height : zeropage
|
||||
.export mouse_pm_hotspot_x : zeropage
|
||||
.export mouse_pm_hotspot_y : zeropage
|
||||
|
||||
.rodata
|
||||
|
||||
mouse_pm_bits:
|
||||
.byte %11110000
|
||||
.byte %11000000
|
||||
.byte %10100000
|
||||
.byte %10010000
|
||||
.byte %10001000
|
||||
.byte %00000100
|
||||
.byte %00000010
|
||||
|
||||
mouse_pm_height = <(* - mouse_pm_bits)
|
||||
|
||||
; hot spot is upper left corner
|
||||
mouse_pm_hotspot_x = 0
|
||||
mouse_pm_hotspot_y = 0
|
||||
237
libsrc/atari/mcbpm.s
Normal file
237
libsrc/atari/mcbpm.s
Normal file
@@ -0,0 +1,237 @@
|
||||
;
|
||||
; P/M mouse callbacks for the Ataris
|
||||
;
|
||||
; Christian Groessler, 11.04.2014
|
||||
;
|
||||
; All functions in this module should be interrupt safe, because they may
|
||||
; be called from an interrupt handler
|
||||
;
|
||||
|
||||
.include "atari.inc"
|
||||
.importzp sp
|
||||
.export _mouse_pm_callbacks
|
||||
.constructor pm_init,27
|
||||
.destructor pm_down,7
|
||||
|
||||
; get mouse shape data
|
||||
.import mouse_pm_bits
|
||||
.importzp mouse_pm_height
|
||||
.importzp mouse_pm_hotspot_x
|
||||
.importzp mouse_pm_hotspot_y
|
||||
|
||||
|
||||
; P/M definitions. The MOUSE_PM_NUM value can be changed to adjust the
|
||||
; number of the P/M used for the mouse. All others depend on this value.
|
||||
; Valid P/M numbers are 0 to 4. When 4 is used, the missiles are used
|
||||
; as a player.
|
||||
.ifdef USE_PAGE6
|
||||
MOUSE_PM_NUM = 2 ; P/M used for the mouse
|
||||
; This cannot be changed since only player #2 uses the memory at $600.
|
||||
.else
|
||||
MOUSE_PM_NUM = 4 ; P/M used for the mouse
|
||||
; Using player #4 (missiles) wastes the least amount of memory on the
|
||||
; atari target, since top of memory is typically at $xC20, and the
|
||||
; missiles use the space at $xB00-$xBFF.
|
||||
; On the atarixl target this configuration (not using page 6) is not
|
||||
; really satisfying since the top of memory typically lies beneath
|
||||
; the ROM and there is flickering visible while the ROM is banked in.
|
||||
.endif
|
||||
MOUSE_PM_BASE = pm_base ; ZP location pointing to the hw area used by the selected P/M
|
||||
|
||||
.if MOUSE_PM_NUM = 4
|
||||
MOUSE_PM_RAW = 0 ; MOUSE_PM_RAW is the hardware P/M number for MOUSE_PM_NUM
|
||||
.macro set_mouse_x
|
||||
; assume CF = 0
|
||||
sta HPOSM3
|
||||
adc #2
|
||||
sta HPOSM2
|
||||
adc #2
|
||||
sta HPOSM1
|
||||
adc #2
|
||||
sta HPOSM0
|
||||
.endmacro
|
||||
.else
|
||||
MOUSE_PM_RAW = MOUSE_PM_NUM + 1
|
||||
.macro set_mouse_x
|
||||
sta HPOSP0 + MOUSE_PM_NUM
|
||||
.endmacro
|
||||
.endif
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.rodata
|
||||
|
||||
; Callback structure
|
||||
_mouse_pm_callbacks:
|
||||
.addr hide
|
||||
.addr show
|
||||
.addr prep
|
||||
.addr draw
|
||||
.addr movex
|
||||
.addr movey
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.bss
|
||||
|
||||
omy: .res 1 ; old Mouse Y position
|
||||
colhlp: .res 1 ; helper variable to set P/M color
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "EXTZP" : zeropage
|
||||
|
||||
pm_base:.res 2
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
; Hide the mouse cursor.
|
||||
hide: lda #0
|
||||
sta GRACTL
|
||||
rts
|
||||
|
||||
; Show the mouse cursor.
|
||||
show:
|
||||
.if MOUSE_PM_NUM < 4
|
||||
lda #2
|
||||
.else
|
||||
lda #1
|
||||
.endif
|
||||
sta GRACTL
|
||||
jmp update_colors
|
||||
|
||||
prep:
|
||||
draw:
|
||||
rts
|
||||
|
||||
; Move the mouse cursor x position to the value in A/X.
|
||||
movex: cpx #1
|
||||
ror a
|
||||
clc
|
||||
adc #48
|
||||
sbc #(mouse_pm_hotspot_x - 1) & $FF
|
||||
set_mouse_x
|
||||
jmp update_colors
|
||||
|
||||
; Move the mouse cursor y position to the value in A/X.
|
||||
movey: clc
|
||||
adc #32
|
||||
sbc #(mouse_pm_hotspot_y - 1) & $FF
|
||||
pha
|
||||
lda omy
|
||||
jsr clr_pm ; remove player at old position
|
||||
jsr update_colors
|
||||
pla
|
||||
sta omy
|
||||
;jmp set_pm ; put player to new position
|
||||
; fall thru
|
||||
|
||||
; Set P/M data from 'mouse_pm_bits'
|
||||
set_pm: tay
|
||||
ldx #0
|
||||
set_l: lda mouse_pm_bits,x
|
||||
sta (MOUSE_PM_BASE),y
|
||||
inx
|
||||
iny
|
||||
beq set_end
|
||||
cpx #mouse_pm_height
|
||||
bcc set_l
|
||||
set_end:rts
|
||||
|
||||
; Clear (zero) P/M data
|
||||
clr_pm: ldx #mouse_pm_height
|
||||
tay
|
||||
lda #0
|
||||
clr_l: sta (MOUSE_PM_BASE),y
|
||||
iny
|
||||
beq clr_end
|
||||
dex
|
||||
bne clr_l
|
||||
clr_end:rts
|
||||
|
||||
|
||||
pm_down = hide
|
||||
|
||||
|
||||
; this assumes a GRAPHICS 0 screen
|
||||
update_colors:
|
||||
lda COLOR2 ; get background color
|
||||
and #$F0
|
||||
sta colhlp
|
||||
lda COLOR1
|
||||
and #$0F
|
||||
ora colhlp
|
||||
|
||||
.if MOUSE_PM_NUM = 4
|
||||
sta PCOLR0
|
||||
sta PCOLR1
|
||||
sta PCOLR2
|
||||
sta PCOLR3
|
||||
lda #0
|
||||
sta SIZEM
|
||||
.else
|
||||
sta PCOLR0 + MOUSE_PM_NUM
|
||||
lda #0
|
||||
sta SIZEP0 + MOUSE_PM_NUM
|
||||
.endif
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
pm_init:
|
||||
lda #0
|
||||
|
||||
.ifdef USE_PAGE6
|
||||
|
||||
sta MOUSE_PM_BASE
|
||||
ldx #6 ; page 6
|
||||
stx MOUSE_PM_BASE+1
|
||||
|
||||
.else
|
||||
|
||||
; use top of memory and lower sp accordingly
|
||||
sta sp
|
||||
sta MOUSE_PM_BASE
|
||||
lda sp+1
|
||||
and #7 ; offset within 2K
|
||||
cmp #3 + MOUSE_PM_RAW + 1 ; can we use it?
|
||||
bcc @decr ; no
|
||||
|
||||
lda sp+1
|
||||
and #$F8
|
||||
@set: adc #3 + MOUSE_PM_RAW - 1 ; CF is set, so adding MOUSE_PM_RAW + 3
|
||||
sta MOUSE_PM_BASE+1
|
||||
sta sp+1
|
||||
bne @cont ; jump always
|
||||
|
||||
@decr: lda sp+1
|
||||
and #$F8
|
||||
sbc #8 - 1 ; CF is clear, subtracts 8
|
||||
bcs @set ; jump always
|
||||
|
||||
@cont: lda #0
|
||||
|
||||
.endif
|
||||
|
||||
tay
|
||||
@iniloo:sta (MOUSE_PM_BASE),y
|
||||
iny
|
||||
bne @iniloo
|
||||
|
||||
.ifndef USE_PAGE6
|
||||
lda MOUSE_PM_BASE+1
|
||||
and #$F8
|
||||
.endif
|
||||
sta PMBASE
|
||||
|
||||
lda #62
|
||||
sta SDMCTL
|
||||
|
||||
lda #1
|
||||
sta GPRIOR
|
||||
|
||||
jmp update_colors
|
||||
7
libsrc/atari/mcbtxtchar-char.s
Normal file
7
libsrc/atari/mcbtxtchar-char.s
Normal file
@@ -0,0 +1,7 @@
|
||||
;
|
||||
; Default text mode mouse cursor character
|
||||
;
|
||||
; Christian Groessler, 11.04.2014
|
||||
;
|
||||
|
||||
.export mouse_txt_char : zp = 96 ; 'diamond' screen code
|
||||
125
libsrc/atari/mcbtxtchar.s
Normal file
125
libsrc/atari/mcbtxtchar.s
Normal file
@@ -0,0 +1,125 @@
|
||||
;
|
||||
; Text mode character mouse callbacks for the Ataris
|
||||
;
|
||||
; Christian Groessler, 03.01.2014
|
||||
;
|
||||
; derived from Apple2 version by
|
||||
; Oliver Schmidt, 22.09.2005
|
||||
;
|
||||
; All functions in this module should be interrupt safe, because they may
|
||||
; be called from an interrupt handler
|
||||
;
|
||||
|
||||
.export _mouse_txt_callbacks
|
||||
.importzp tmp4
|
||||
.import mul40,loc_tmp
|
||||
.importzp mouse_txt_char ; screen code of mouse cursor
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.bss
|
||||
|
||||
backup: .res 1
|
||||
visible:.res 1
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "EXTZP" : zeropage
|
||||
scrptr: .res 2
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
|
||||
.rodata
|
||||
|
||||
; Callback structure
|
||||
_mouse_txt_callbacks:
|
||||
.addr hide
|
||||
.addr show
|
||||
.addr prep
|
||||
.addr draw
|
||||
.addr movex
|
||||
.addr movey
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
; setcursor
|
||||
|
||||
getcursor:
|
||||
column: ldy #$00 ; Patched at runtime
|
||||
lda (scrptr),y
|
||||
rts
|
||||
|
||||
setcursor:
|
||||
column2:ldy #$00 ; Patched at runtime
|
||||
sta (scrptr),y
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
done:
|
||||
rts
|
||||
|
||||
; Hide the mouse cursor.
|
||||
hide:
|
||||
dec visible
|
||||
|
||||
prep:
|
||||
jsr getcursor ; Get character at cursor position
|
||||
cmp #mouse_txt_char ; "mouse" character
|
||||
bne overwr ; no, probably program has overwritten it
|
||||
lda backup ;
|
||||
jmp setcursor ; Draw character
|
||||
overwr: sta backup
|
||||
rts
|
||||
|
||||
; Show the mouse cursor.
|
||||
show:
|
||||
inc visible
|
||||
|
||||
draw:
|
||||
lda visible
|
||||
beq done
|
||||
jsr getcursor ; Cursor visible at current position?
|
||||
sta backup ; Save character at cursor position
|
||||
lda #mouse_txt_char
|
||||
jmp setcursor ; Draw cursor
|
||||
|
||||
|
||||
; Move the mouse cursor x position to the value in A/X.
|
||||
movex:
|
||||
cpx #1
|
||||
ror a
|
||||
lsr a ; convert to character position
|
||||
lsr a
|
||||
sta column+1
|
||||
sta column2+1
|
||||
rts
|
||||
|
||||
; Move the mouse cursor y position to the value in A/X.
|
||||
movey:
|
||||
tax
|
||||
ldy tmp4 ; mul40 uses tmp4
|
||||
lda loc_tmp ; and this local variable
|
||||
pha
|
||||
txa ; get parameter back
|
||||
lsr a ; convert y position to character line
|
||||
lsr a
|
||||
lsr a
|
||||
jsr mul40
|
||||
clc
|
||||
adc SAVMSC
|
||||
sta scrptr
|
||||
txa
|
||||
adc SAVMSC+1
|
||||
sta scrptr+1
|
||||
pla
|
||||
sta loc_tmp
|
||||
sty tmp4
|
||||
rts
|
||||
2
libsrc/atari/mou/atrami.s
Normal file
2
libsrc/atari/mou/atrami.s
Normal file
@@ -0,0 +1,2 @@
|
||||
AMIGA_MOUSE = 1
|
||||
.include "atrst.s"
|
||||
440
libsrc/atari/mou/atrjoy.s
Normal file
440
libsrc/atari/mou/atrjoy.s
Normal file
@@ -0,0 +1,440 @@
|
||||
;
|
||||
; Driver for a "joystick mouse".
|
||||
;
|
||||
; C128 version: Ullrich von Bassewitz, 2004-04-05, 2009-09-26
|
||||
; Adapted to Atari: Christian Groessler, 2014-01-02
|
||||
;
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "mouse-kernel.inc"
|
||||
.include "atari.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxjoy_mou
|
||||
.else
|
||||
module_header _atrjoy_mou
|
||||
.endif
|
||||
|
||||
HEADER:
|
||||
|
||||
; Driver signature
|
||||
|
||||
.byte $6d, $6f, $75 ; "mou"
|
||||
.byte MOUSE_API_VERSION ; Mouse driver API version number
|
||||
|
||||
; Library reference
|
||||
|
||||
.addr $0000
|
||||
|
||||
; Jump table
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr HIDE
|
||||
.addr SHOW
|
||||
.addr SETBOX
|
||||
.addr GETBOX
|
||||
.addr MOVE
|
||||
.addr BUTTONS
|
||||
.addr POS
|
||||
.addr INFO
|
||||
.addr IOCTL
|
||||
.addr IRQ
|
||||
|
||||
; Mouse driver flags
|
||||
|
||||
.byte MOUSE_FLAG_LATE_IRQ
|
||||
|
||||
; Callback table, set by the kernel before INSTALL is called
|
||||
|
||||
CHIDE: jmp $0000 ; Hide the cursor
|
||||
CSHOW: jmp $0000 ; Show the cursor
|
||||
CPREP: jmp $0000 ; Prepare to move the cursor
|
||||
CDRAW: jmp $0000 ; Draw the cursor
|
||||
CMOVEX: jmp $0000 ; Move the cursor to X coord
|
||||
CMOVEY: jmp $0000 ; Move the cursor to Y coord
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Constants
|
||||
|
||||
SCREEN_HEIGHT = 191
|
||||
SCREEN_WIDTH = 319
|
||||
|
||||
.enum JOY
|
||||
UP = $01
|
||||
DOWN = $02
|
||||
LEFT = $04
|
||||
RIGHT = $08
|
||||
.endenum
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Global variables. The bounding box values are sorted so that they can be
|
||||
; written with the least effort in the SETBOX and GETBOX routines, so don't
|
||||
; reorder them.
|
||||
|
||||
.bss
|
||||
|
||||
Vars:
|
||||
YPos: .res 2 ; Current mouse position, Y
|
||||
XPos: .res 2 ; Current mouse position, X
|
||||
XMin: .res 2 ; X1 value of bounding box
|
||||
YMin: .res 2 ; Y1 value of bounding box
|
||||
XMax: .res 2 ; X2 value of bounding box
|
||||
YMax: .res 2 ; Y2 value of bounding box
|
||||
Buttons: .res 1 ; Button mask
|
||||
|
||||
|
||||
Temp: .res 1 ; Temporary value used in the int handler
|
||||
|
||||
; Default values for above variables
|
||||
|
||||
.rodata
|
||||
|
||||
; (We use ".proc" because we want to define both a label and a scope.)
|
||||
|
||||
.proc DefVars
|
||||
.word SCREEN_HEIGHT/2 ; YPos
|
||||
.word SCREEN_WIDTH/2 ; XPos
|
||||
.word 0 ; XMin
|
||||
.word 0 ; YMin
|
||||
.word SCREEN_WIDTH ; XMax
|
||||
.word SCREEN_HEIGHT ; YMax
|
||||
.byte 0 ; Buttons
|
||||
.endproc
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; INSTALL routine. Is called after the driver is loaded into memory. If
|
||||
; possible, check if the hardware is present.
|
||||
; Must return an MOUSE_ERR_xx code in a/x.
|
||||
|
||||
INSTALL:
|
||||
|
||||
; Initialize variables. Just copy the default stuff over
|
||||
|
||||
ldx #.sizeof(DefVars)-1
|
||||
@L1: lda DefVars,x
|
||||
sta Vars,x
|
||||
dex
|
||||
bpl @L1
|
||||
|
||||
; Make sure the mouse cursor is at the default location.
|
||||
|
||||
lda XPos
|
||||
ldx XPos+1
|
||||
jsr CMOVEX
|
||||
lda YPos
|
||||
ldx YPos+1
|
||||
jsr CMOVEY
|
||||
|
||||
; Done, return zero (= MOUSE_ERR_OK)
|
||||
|
||||
ldx #$00
|
||||
txa
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory.
|
||||
; No return code required (the driver is removed from memory on return).
|
||||
|
||||
UNINSTALL = HIDE ; Hide cursor on exit
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
|
||||
; a counter for calls to show/hide, and the driver entry point is only called
|
||||
; if the mouse is currently visible and should get hidden. For most drivers,
|
||||
; no special action is required besides hiding the mouse cursor.
|
||||
; No return code required.
|
||||
|
||||
HIDE: php
|
||||
sei
|
||||
jsr CHIDE
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
|
||||
; a counter for calls to show/hide, and the driver entry point is only called
|
||||
; if the mouse is currently hidden and should become visible. For most drivers,
|
||||
; no special action is required besides enabling the mouse cursor.
|
||||
; No return code required.
|
||||
|
||||
SHOW: php
|
||||
sei
|
||||
jsr CSHOW
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SETBOX: Set the mouse bounding box. The parameters are passed as they come
|
||||
; from the C program, that is, a pointer to a mouse_box struct in a/x.
|
||||
; No checks are done if the mouse is currently inside the box, this is the job
|
||||
; of the caller. It is not necessary to validate the parameters, trust the
|
||||
; caller and save some code here. No return code required.
|
||||
|
||||
SETBOX: sta ptr1
|
||||
stx ptr1+1 ; Save data pointer
|
||||
|
||||
ldy #.sizeof (MOUSE_BOX)-1
|
||||
php
|
||||
sei
|
||||
|
||||
@L1: lda (ptr1),y
|
||||
sta XMin,y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; GETBOX: Return the mouse bounding box. The parameters are passed as they
|
||||
; come from the C program, that is, a pointer to a mouse_box struct in a/x.
|
||||
|
||||
GETBOX: sta ptr1
|
||||
stx ptr1+1 ; Save data pointer
|
||||
|
||||
ldy #.sizeof (MOUSE_BOX)-1
|
||||
php
|
||||
sei
|
||||
|
||||
@L1: lda XMin,y
|
||||
sta (ptr1),y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; MOVE: Move the mouse to a new position. The position is passed as it comes
|
||||
; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
|
||||
; remove the parameter from the stack on return.
|
||||
; No checks are done if the new position is valid (within the bounding box or
|
||||
; the screen). No return code required.
|
||||
;
|
||||
|
||||
MOVE: php
|
||||
sei ; No interrupts
|
||||
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
jsr CPREP
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
|
||||
sta YPos
|
||||
stx YPos+1 ; New Y position
|
||||
jsr CMOVEY ; Set it
|
||||
|
||||
ldy #$01
|
||||
lda (sp),y
|
||||
sta XPos+1
|
||||
tax
|
||||
dey
|
||||
lda (sp),y
|
||||
sta XPos ; New X position
|
||||
jsr CMOVEX ; Move the cursor
|
||||
|
||||
jsr CDRAW
|
||||
|
||||
plp ; Restore interrupt flag
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; BUTTONS: Return the button mask in a/x.
|
||||
|
||||
BUTTONS:
|
||||
lda Buttons
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
|
||||
; No return code required.
|
||||
|
||||
POS: ldy #MOUSE_POS::XCOORD ; Structure offset
|
||||
|
||||
php
|
||||
sei ; Disable interrupts
|
||||
lda XPos ; Transfer the position
|
||||
sta (ptr1),y
|
||||
lda XPos+1
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda YPos
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda YPos+1
|
||||
plp ; Restore interrupt flag
|
||||
|
||||
iny
|
||||
sta (ptr1),y ; Store last byte
|
||||
|
||||
rts ; Done
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; INFO: Returns mouse position and current button mask in the MOUSE_INFO
|
||||
; struct pointed to by ptr1. No return code required.
|
||||
;
|
||||
; We're cheating here to keep the code smaller: The first fields of the
|
||||
; mouse_info struct are identical to the mouse_pos struct, so we will just
|
||||
; call _mouse_pos to initialize the struct pointer and fill the position
|
||||
; fields.
|
||||
|
||||
INFO: jsr POS
|
||||
|
||||
; Fill in the button state
|
||||
|
||||
lda Buttons
|
||||
ldy #MOUSE_INFO::BUTTONS
|
||||
sta (ptr1),y
|
||||
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
|
||||
ldx #>MOUSE_ERR_INV_IOCTL
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
|
||||
; (so be careful). The routine MUST return carry set if the interrupt has been
|
||||
; 'handled' - which means that the interrupt source is gone. Otherwise it
|
||||
; MUST return carry clear.
|
||||
;
|
||||
|
||||
IRQ:
|
||||
|
||||
; Check for a pressed button and place the result into Buttons
|
||||
|
||||
ldx #0
|
||||
lda TRIG0 ; joystick #0 trigger
|
||||
bne @L0 ; not pressed
|
||||
ldx #MOUSE_BTN_LEFT
|
||||
@L0: stx Buttons
|
||||
|
||||
lda PORTA ; get joystick direction bits
|
||||
and #15 ; clear joystick #1 bits
|
||||
eor #15
|
||||
sta Temp
|
||||
|
||||
jsr CPREP
|
||||
|
||||
; Check left/right
|
||||
|
||||
lda Temp ; Read joystick #0
|
||||
and #(JOY::LEFT | JOY::RIGHT)
|
||||
beq @SkipX ;
|
||||
|
||||
; We will cheat here and rely on the fact that either the left, OR the right
|
||||
; bit can be active
|
||||
|
||||
and #JOY::RIGHT ; Check RIGHT bit
|
||||
bne @Right
|
||||
lda #$FF
|
||||
tax
|
||||
bne @AddX ; Branch always
|
||||
@Right: lda #$01
|
||||
ldx #$00
|
||||
|
||||
; Calculate the new X coordinate (--> a/y)
|
||||
|
||||
@AddX: add XPos
|
||||
tay ; Remember low byte
|
||||
txa
|
||||
adc XPos+1
|
||||
tax
|
||||
|
||||
; Limit the X coordinate to the bounding box
|
||||
|
||||
cpy XMin
|
||||
sbc XMin+1
|
||||
bpl @L1
|
||||
ldy XMin
|
||||
ldx XMin+1
|
||||
jmp @L2
|
||||
@L1: txa
|
||||
|
||||
cpy XMax
|
||||
sbc XMax+1
|
||||
bmi @L2
|
||||
ldy XMax
|
||||
ldx XMax+1
|
||||
@L2: sty XPos
|
||||
stx XPos+1
|
||||
|
||||
; Move the mouse pointer to the new X pos
|
||||
|
||||
tya
|
||||
jsr CMOVEX
|
||||
|
||||
; Calculate the Y movement vector
|
||||
|
||||
@SkipX: lda Temp ; Read joystick #0
|
||||
and #(JOY::UP | JOY::DOWN) ; Check up/down
|
||||
beq @SkipY ;
|
||||
|
||||
; We will cheat here and rely on the fact that either the up, OR the down
|
||||
; bit can be active
|
||||
|
||||
lsr a
|
||||
bcc @Down
|
||||
lda #$FF
|
||||
tax
|
||||
bne @AddY
|
||||
@Down: lda #$01
|
||||
ldx #$00
|
||||
|
||||
; Calculate the new Y coordinate (--> a/y)
|
||||
|
||||
@AddY: add YPos
|
||||
tay ; Remember low byte
|
||||
txa
|
||||
adc YPos+1
|
||||
tax
|
||||
|
||||
; Limit the Y coordinate to the bounding box
|
||||
|
||||
cpy YMin
|
||||
sbc YMin+1
|
||||
bpl @L3
|
||||
ldy YMin
|
||||
ldx YMin+1
|
||||
jmp @L4
|
||||
@L3: txa
|
||||
|
||||
cpy YMax
|
||||
sbc YMax+1
|
||||
bmi @L4
|
||||
ldy YMax
|
||||
ldx YMax+1
|
||||
@L4: sty YPos
|
||||
stx YPos+1
|
||||
|
||||
; Move the mouse pointer to the new X pos
|
||||
|
||||
tya
|
||||
jsr CMOVEY
|
||||
|
||||
; Done
|
||||
|
||||
@SkipY: jsr CDRAW
|
||||
clc ; Interrupt not "handled"
|
||||
rts
|
||||
|
||||
823
libsrc/atari/mou/atrst.s
Normal file
823
libsrc/atari/mou/atrst.s
Normal file
@@ -0,0 +1,823 @@
|
||||
;
|
||||
; Mouse driver for ST & Amiga mouses and Atari trakball.
|
||||
;
|
||||
; Original access routines: 05/07/2000 Freddy Offenga
|
||||
; Converted to driver: Christian Groessler, 2014-01-04
|
||||
;
|
||||
; Defines:
|
||||
; AMIGA_MOUSE - builds Amiga mouse version
|
||||
; TRAK_MOUSE - builds trakball version
|
||||
; If none of these defines are active, the ST mouse version
|
||||
; is being built.
|
||||
;
|
||||
|
||||
;DEBUG = 1
|
||||
|
||||
DISABLE_TIMEOUT = 30 ; # of vertical blank interrupts after which, if
|
||||
; no mouse motion occurred, the polling IRQ gets
|
||||
; disabled.
|
||||
; VBI frequency is 50Hz for PAL and 60Hz for NTSC
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "mouse-kernel.inc"
|
||||
.include "atari.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
.if .not ( .defined (AMIGA_MOUSE) .or .defined (TRAK_MOUSE))
|
||||
ST_MOUSE = 1
|
||||
.endif
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.if .defined (ST_MOUSE)
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxst_mou
|
||||
.else
|
||||
module_header _atrst_mou
|
||||
.endif
|
||||
|
||||
.elseif .defined (AMIGA_MOUSE)
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxami_mou
|
||||
.else
|
||||
module_header _atrami_mou
|
||||
.endif
|
||||
|
||||
.elseif .defined (TRAK_MOUSE)
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxtrk_mou
|
||||
.else
|
||||
module_header _atrtrk_mou
|
||||
.endif
|
||||
|
||||
.endif
|
||||
|
||||
HEADER:
|
||||
|
||||
; Driver signature
|
||||
|
||||
.byte $6d, $6f, $75 ; "mou"
|
||||
.byte MOUSE_API_VERSION ; Mouse driver API version number
|
||||
|
||||
; Library reference
|
||||
|
||||
libref: .addr $0000
|
||||
|
||||
; Jump table
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr HIDE
|
||||
.addr SHOW
|
||||
.addr SETBOX
|
||||
.addr GETBOX
|
||||
.addr MOVE
|
||||
.addr BUTTONS
|
||||
.addr POS
|
||||
.addr INFO
|
||||
.addr IOCTL
|
||||
.addr IRQ
|
||||
|
||||
; Mouse driver flags
|
||||
|
||||
.byte MOUSE_FLAG_LATE_IRQ
|
||||
|
||||
; Callback table, set by the kernel before INSTALL is called
|
||||
|
||||
CHIDE: jmp $0000 ; Hide the cursor
|
||||
CSHOW: jmp $0000 ; Show the cursor
|
||||
CPREP: jmp $0000 ; Prepare to move the cursor
|
||||
CDRAW: jmp $0000 ; Draw the cursor
|
||||
CMOVEX: jmp $0000 ; Move the cursor to X coord
|
||||
CMOVEY: jmp $0000 ; Move the cursor to Y coord
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Constants
|
||||
|
||||
SCREEN_HEIGHT = 191
|
||||
SCREEN_WIDTH = 319
|
||||
|
||||
.enum JOY
|
||||
UP = $01
|
||||
DOWN = $02
|
||||
LEFT = $04
|
||||
RIGHT = $08
|
||||
.endenum
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Global variables. The bounding box values are sorted so that they can be
|
||||
; written with the least effort in the SETBOX and GETBOX routines, so don't
|
||||
; reorder them.
|
||||
|
||||
.bss
|
||||
|
||||
Vars:
|
||||
YPos: .res 2 ; Current mouse position, Y
|
||||
XPos: .res 2 ; Current mouse position, X
|
||||
XMin: .res 2 ; X1 value of bounding box
|
||||
YMin: .res 2 ; Y1 value of bounding box
|
||||
XMax: .res 2 ; X2 value of bounding box
|
||||
YMax: .res 2 ; Y2 value of bounding box
|
||||
Buttons: .res 1 ; Button mask
|
||||
|
||||
XPosWrk: .res 2
|
||||
YPosWrk: .res 2
|
||||
|
||||
irq_enabled: .res 1 ; flag indicating that the high frequency polling interrupt is enabled
|
||||
old_porta_vbi: .res 1 ; previous PORTA value of the VBI interrupt (IRQ)
|
||||
how_long: .res 1 ; counter for how many VBI interrupts the mouse hasn't been moved
|
||||
|
||||
.if .defined (AMIGA_MOUSE) .or .defined (ST_MOUSE)
|
||||
dumx: .res 1
|
||||
dumy: .res 1
|
||||
.endif
|
||||
|
||||
.ifdef TRAK_MOUSE
|
||||
oldval: .res 1
|
||||
.endif
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
OldT1: .res 2
|
||||
.else
|
||||
|
||||
.data
|
||||
set_VTIMR1_handler:
|
||||
.byte $4C, 0, 0
|
||||
.endif
|
||||
|
||||
.rodata
|
||||
|
||||
; Default values for some of the above variables
|
||||
; (We use ".proc" because we want to define both a label and a scope.)
|
||||
|
||||
.proc DefVars
|
||||
.word (SCREEN_HEIGHT+1)/2 ; YPos
|
||||
.word (SCREEN_WIDTH+1)/2 ; XPos
|
||||
.word 0 ; XMin
|
||||
.word 0 ; YMin
|
||||
.word SCREEN_WIDTH ; XMax
|
||||
.word SCREEN_HEIGHT ; YMax
|
||||
.byte 0 ; Buttons
|
||||
.endproc
|
||||
|
||||
.ifdef ST_MOUSE
|
||||
|
||||
; ST mouse lookup table
|
||||
|
||||
STTab: .byte $FF,$01,$00,$01
|
||||
.byte $00,$FF,$00,$01
|
||||
.byte $01,$00,$FF,$00
|
||||
.byte $01,$00,$01,$FF
|
||||
|
||||
.endif
|
||||
|
||||
.ifdef AMIGA_MOUSE
|
||||
|
||||
; Amiga mouse lookup table
|
||||
|
||||
AmiTab: .byte $FF,$01,$00,$FF
|
||||
.byte $00,$FF,$FF,$01
|
||||
.byte $01,$FF,$FF,$00
|
||||
.byte $FF,$00,$01,$FF
|
||||
|
||||
.endif
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; INSTALL routine. Is called after the driver is loaded into memory. If
|
||||
; possible, check if the hardware is present.
|
||||
; Must return an MOUSE_ERR_xx code in a/x.
|
||||
|
||||
INSTALL:
|
||||
|
||||
; Initialize variables. Just copy the default stuff over
|
||||
|
||||
ldx #.sizeof(DefVars)-1
|
||||
@L1: lda DefVars,x
|
||||
sta Vars,x
|
||||
dex
|
||||
bpl @L1
|
||||
|
||||
; Make sure the mouse cursor is at the default location.
|
||||
|
||||
lda XPos
|
||||
sta XPosWrk
|
||||
ldx XPos+1
|
||||
stx XPosWrk+1
|
||||
jsr CMOVEX
|
||||
lda YPos
|
||||
sta YPosWrk
|
||||
ldx YPos+1
|
||||
stx YPosWrk+1
|
||||
jsr CMOVEY
|
||||
|
||||
; Install timer irq routine to poll mouse.
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
|
||||
; Setup pointer to wrapper install/deinstall function.
|
||||
lda libref
|
||||
sta set_VTIMR1_handler+1
|
||||
lda libref+1
|
||||
sta set_VTIMR1_handler+2
|
||||
|
||||
; Install my handler.
|
||||
sec
|
||||
lda #<T1Han
|
||||
ldx #>T1Han
|
||||
jsr set_VTIMR1_handler
|
||||
|
||||
.else
|
||||
|
||||
lda VTIMR1
|
||||
sta OldT1
|
||||
lda VTIMR1+1
|
||||
sta OldT1+1
|
||||
|
||||
php
|
||||
sei
|
||||
lda #<T1Han
|
||||
sta VTIMR1
|
||||
lda #>T1Han
|
||||
sta VTIMR1+1
|
||||
plp
|
||||
|
||||
.endif
|
||||
|
||||
lda #%00000001
|
||||
sta AUDCTL
|
||||
|
||||
lda #0
|
||||
sta AUDC1
|
||||
|
||||
lda #15
|
||||
sta AUDF1
|
||||
sta STIMER
|
||||
|
||||
.if 0 ; the IRQ will now be dynamically enabled when the mouse is moved
|
||||
lda POKMSK
|
||||
ora #%00000001 ; timer 1 enable
|
||||
sta POKMSK
|
||||
sta IRQEN
|
||||
sta irq_enabled
|
||||
.endif
|
||||
|
||||
lda PORTA
|
||||
and #$0f
|
||||
sta old_porta_vbi
|
||||
|
||||
; Done, return zero (= MOUSE_ERR_OK)
|
||||
|
||||
ldx #$00
|
||||
txa
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory.
|
||||
; No return code required (the driver is removed from memory on return).
|
||||
|
||||
UNINSTALL:
|
||||
|
||||
; uninstall timer irq routine
|
||||
|
||||
lda POKMSK
|
||||
and #%11111110 ; timer 1 disable
|
||||
sta IRQEN
|
||||
sta POKMSK
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
|
||||
clc
|
||||
jsr set_VTIMR1_handler
|
||||
|
||||
.else
|
||||
|
||||
php
|
||||
sei
|
||||
lda OldT1
|
||||
sta VTIMR1
|
||||
lda OldT1+1
|
||||
sta VTIMR1+1
|
||||
plp
|
||||
|
||||
.endif
|
||||
; fall thru...
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
|
||||
; a counter for calls to show/hide, and the driver entry point is only called
|
||||
; if the mouse is currently visible and should get hidden. For most drivers,
|
||||
; no special action is required besides hiding the mouse cursor.
|
||||
; No return code required.
|
||||
|
||||
HIDE: php
|
||||
sei
|
||||
jsr CHIDE
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
|
||||
; a counter for calls to show/hide, and the driver entry point is only called
|
||||
; if the mouse is currently hidden and should become visible. For most drivers,
|
||||
; no special action is required besides enabling the mouse cursor.
|
||||
; No return code required.
|
||||
|
||||
SHOW: php
|
||||
sei
|
||||
jsr CSHOW
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SETBOX: Set the mouse bounding box. The parameters are passed as they come
|
||||
; from the C program, that is, a pointer to a mouse_box struct in a/x.
|
||||
; No checks are done if the mouse is currently inside the box, this is the job
|
||||
; of the caller. It is not necessary to validate the parameters, trust the
|
||||
; caller and save some code here. No return code required.
|
||||
|
||||
SETBOX: sta ptr1
|
||||
stx ptr1+1 ; Save data pointer
|
||||
|
||||
ldy #.sizeof (MOUSE_BOX)-1
|
||||
php
|
||||
sei
|
||||
|
||||
@L1: lda (ptr1),y
|
||||
sta XMin,y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; GETBOX: Return the mouse bounding box. The parameters are passed as they
|
||||
; come from the C program, that is, a pointer to a mouse_box struct in a/x.
|
||||
|
||||
GETBOX: sta ptr1
|
||||
stx ptr1+1 ; Save data pointer
|
||||
|
||||
ldy #.sizeof (MOUSE_BOX)-1
|
||||
php
|
||||
sei
|
||||
|
||||
@L1: lda XMin,y
|
||||
sta (ptr1),y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; MOVE: Move the mouse to a new position. The position is passed as it comes
|
||||
; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
|
||||
; remove the parameter from the stack on return.
|
||||
; No checks are done if the new position is valid (within the bounding box or
|
||||
; the screen). No return code required.
|
||||
;
|
||||
|
||||
MOVE: php
|
||||
sei ; No interrupts
|
||||
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
jsr CPREP
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
|
||||
sta YPos
|
||||
sta YPosWrk
|
||||
stx YPos+1 ; New Y position
|
||||
stx YPosWrk+1
|
||||
jsr CMOVEY ; Set it
|
||||
|
||||
ldy #$01
|
||||
lda (sp),y
|
||||
sta XPos+1
|
||||
sta XPosWrk+1
|
||||
tax
|
||||
dey
|
||||
lda (sp),y
|
||||
sta XPos ; New X position
|
||||
sta XPosWrk
|
||||
jsr CMOVEX ; Move the cursor
|
||||
|
||||
jsr CDRAW
|
||||
|
||||
plp ; Restore interrupt flag
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; BUTTONS: Return the button mask in a/x.
|
||||
|
||||
BUTTONS:
|
||||
lda Buttons
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
|
||||
; No return code required.
|
||||
|
||||
POS: ldy #MOUSE_POS::XCOORD ; Structure offset
|
||||
|
||||
php
|
||||
sei ; Disable interrupts
|
||||
lda XPos ; Transfer the position
|
||||
sta (ptr1),y
|
||||
lda XPos+1
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda YPos
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda YPos+1
|
||||
plp ; Restore interrupt flag
|
||||
|
||||
iny
|
||||
sta (ptr1),y ; Store last byte
|
||||
|
||||
rts ; Done
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; INFO: Returns mouse position and current button mask in the MOUSE_INFO
|
||||
; struct pointed to by ptr1. No return code required.
|
||||
;
|
||||
; We're cheating here to keep the code smaller: The first fields of the
|
||||
; mouse_info struct are identical to the mouse_pos struct, so we will just
|
||||
; call _mouse_pos to initialize the struct pointer and fill the position
|
||||
; fields.
|
||||
|
||||
INFO: jsr POS
|
||||
|
||||
; Fill in the button state
|
||||
|
||||
lda Buttons
|
||||
ldy #MOUSE_INFO::BUTTONS
|
||||
sta (ptr1),y
|
||||
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
|
||||
ldx #>MOUSE_ERR_INV_IOCTL
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
|
||||
; (so be careful). The routine MUST return carry set if the interrupt has been
|
||||
; 'handled' - which means that the interrupt source is gone. Otherwise it
|
||||
; MUST return carry clear.
|
||||
;
|
||||
|
||||
IRQ: lda PORTA ; mouse port contents
|
||||
and #$0f ; check port 1 only
|
||||
ldx irq_enabled
|
||||
bne @L1
|
||||
|
||||
; IRQ is disabled, check for mouse motion and enable IRQ if mouse motion detected
|
||||
|
||||
cmp old_porta_vbi
|
||||
beq @L3 ; no motion
|
||||
|
||||
; Turn mouse polling IRQ back on
|
||||
|
||||
lda POKMSK
|
||||
ora #%00000001 ; timer 1 enable
|
||||
sta POKMSK
|
||||
sta IRQEN
|
||||
sta irq_enabled
|
||||
bne @L3
|
||||
; not reached
|
||||
|
||||
; IRQ is enabled
|
||||
|
||||
@L1: cmp old_porta_vbi ; mouse motion since last VBI?
|
||||
sta old_porta_vbi
|
||||
beq @L2 ; no, increment timeout to disable IRQ
|
||||
|
||||
lda #0
|
||||
sta how_long ; yes, reinitialize wait counter
|
||||
beq @L3
|
||||
; not reached
|
||||
|
||||
@L2: inc how_long ; no motion, increment wait counter
|
||||
lda how_long
|
||||
cmp #DISABLE_TIMEOUT ; timeout?
|
||||
bcc @L3 ; no
|
||||
|
||||
lda #0 ; yes, turn off IRQ
|
||||
sta how_long
|
||||
|
||||
; no mouse input -- turn IRQ off
|
||||
|
||||
sta irq_enabled
|
||||
lda POKMSK
|
||||
and #%11111110 ; timer 1 disable
|
||||
sta IRQEN
|
||||
sta POKMSK
|
||||
|
||||
; Check for a pressed button and place the result into Buttons
|
||||
|
||||
@L3: ldx #0
|
||||
lda TRIG0 ; joystick #0 trigger
|
||||
bne @L4 ; not pressed
|
||||
ldx #MOUSE_BTN_LEFT
|
||||
@L4: stx Buttons
|
||||
|
||||
jsr CPREP
|
||||
|
||||
; Limit the X coordinate to the bounding box
|
||||
|
||||
lda XPosWrk+1
|
||||
ldy XPosWrk
|
||||
tax
|
||||
cpy XMin
|
||||
sbc XMin+1
|
||||
bpl @L5
|
||||
ldy XMin
|
||||
ldx XMin+1
|
||||
jmp @L6
|
||||
|
||||
@L5: txa
|
||||
cpy XMax
|
||||
sbc XMax+1
|
||||
bmi @L6
|
||||
ldy XMax
|
||||
ldx XMax+1
|
||||
@L6: sty XPos
|
||||
stx XPos+1
|
||||
tya
|
||||
jsr CMOVEX
|
||||
|
||||
; Limit the Y coordinate to the bounding box
|
||||
|
||||
lda YPosWrk+1
|
||||
ldy YPosWrk
|
||||
tax
|
||||
cpy YMin
|
||||
sbc YMin+1
|
||||
bpl @L7
|
||||
ldy YMin
|
||||
ldx YMin+1
|
||||
jmp @L8
|
||||
|
||||
@L7: txa
|
||||
cpy YMax
|
||||
sbc YMax+1
|
||||
bmi @L8
|
||||
ldy YMax
|
||||
ldx YMax+1
|
||||
@L8: sty YPos
|
||||
stx YPos+1
|
||||
tya
|
||||
jsr CMOVEY
|
||||
|
||||
jsr CDRAW
|
||||
|
||||
.ifdef DEBUG
|
||||
; print on upper right corner 'E' or 'D', indicating the IRQ is enabled or disabled
|
||||
ldy irq_enabled
|
||||
beq @L9
|
||||
lda #37 ; screen code for 'E'
|
||||
.byte $2c ; bit opcode, eats next 2 bytes
|
||||
@L9: lda #36 ; screen code for 'D'
|
||||
ldy #39
|
||||
sta (SAVMSC),y
|
||||
.endif
|
||||
|
||||
clc
|
||||
rts
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; T1Han: Local IRQ routine to poll mouse
|
||||
;
|
||||
|
||||
T1Han: lda CRITIC ; if CRITIC flag is set, disable the
|
||||
bne disable_me ; high frequency polling IRQ, in order
|
||||
; not to interfere with SIO I/O (e.g.
|
||||
; floppy access)
|
||||
|
||||
tya
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
|
||||
.ifdef DEBUG
|
||||
lda RANDOM
|
||||
sta COLBK
|
||||
.endif
|
||||
|
||||
lda PORTA
|
||||
tay
|
||||
|
||||
.ifdef ST_MOUSE
|
||||
|
||||
; ST mouse version
|
||||
|
||||
and #%00000011
|
||||
ora dumx
|
||||
tax
|
||||
lda STTab,x
|
||||
bmi nxst
|
||||
|
||||
beq xist
|
||||
|
||||
dec XPosWrk
|
||||
lda XPosWrk
|
||||
cmp #255
|
||||
bne nxst
|
||||
dec XPosWrk+1
|
||||
jmp nxst
|
||||
|
||||
xist: inc XPosWrk
|
||||
bne nxst
|
||||
inc XPosWrk+1
|
||||
|
||||
nxst: tya
|
||||
and #%00001100
|
||||
ora dumy
|
||||
tax
|
||||
lda STTab,x
|
||||
bmi nyst
|
||||
|
||||
bne yst
|
||||
|
||||
dec YPosWrk
|
||||
lda YPosWrk
|
||||
cmp #255
|
||||
bne nyst
|
||||
dec YPosWrk+1
|
||||
jmp nyst
|
||||
|
||||
yst: inc YPosWrk
|
||||
bne nyst
|
||||
inc YPosWrk+1
|
||||
|
||||
; store old readings
|
||||
|
||||
nyst: tya
|
||||
and #%00000011
|
||||
asl
|
||||
asl
|
||||
sta dumx
|
||||
tya
|
||||
and #%00001100
|
||||
lsr
|
||||
lsr
|
||||
sta dumy
|
||||
|
||||
.elseif .defined (AMIGA_MOUSE)
|
||||
|
||||
; Amiga mouse version
|
||||
|
||||
lsr
|
||||
and #%00000101
|
||||
ora dumx
|
||||
tax
|
||||
lda AmiTab,x
|
||||
bmi nxami
|
||||
|
||||
bne xiami
|
||||
|
||||
dec XPosWrk
|
||||
lda XPosWrk
|
||||
cmp #255
|
||||
bne nxami
|
||||
dec XPosWrk+1
|
||||
jmp nxami
|
||||
|
||||
xiami: inc XPosWrk
|
||||
bne nxami
|
||||
inc XPosWrk+1
|
||||
|
||||
nxami: tya
|
||||
|
||||
and #%00000101
|
||||
ora dumy
|
||||
tax
|
||||
lda AmiTab,x
|
||||
bmi nyami
|
||||
|
||||
bne yiami
|
||||
|
||||
dec YPosWrk
|
||||
lda YPosWrk
|
||||
cmp #255
|
||||
bne nyami
|
||||
dec YPosWrk+1
|
||||
jmp nyami
|
||||
|
||||
yiami: inc YPosWrk
|
||||
bne nyami
|
||||
inc YPosWrk+1
|
||||
|
||||
; store old readings
|
||||
|
||||
nyami: tya
|
||||
and #%00001010
|
||||
sta dumx
|
||||
tya
|
||||
and #%00000101
|
||||
asl
|
||||
sta dumy
|
||||
|
||||
.elseif .defined (TRAK_MOUSE)
|
||||
|
||||
; trakball version
|
||||
|
||||
eor oldval
|
||||
and #%00001000
|
||||
beq horiz
|
||||
|
||||
tya
|
||||
and #%00000100
|
||||
beq mmup
|
||||
|
||||
inc YPosWrk
|
||||
bne horiz
|
||||
inc YPosWrk+1
|
||||
bne horiz
|
||||
|
||||
mmup: dec YPosWrk
|
||||
lda YPosWrk
|
||||
cmp #255
|
||||
bne horiz
|
||||
dec YPosWrk+1
|
||||
|
||||
horiz: tya
|
||||
eor oldval
|
||||
and #%00000010
|
||||
beq mmexit
|
||||
|
||||
tya
|
||||
and #%00000001
|
||||
beq mmleft
|
||||
|
||||
inc XPosWrk
|
||||
bne mmexit
|
||||
inc XPosWrk+1
|
||||
bne mmexit
|
||||
|
||||
mmleft: dec XPosWrk
|
||||
lda XPosWrk
|
||||
cmp #255
|
||||
bne mmexit
|
||||
dec XPosWrk+1
|
||||
|
||||
mmexit: sty oldval
|
||||
|
||||
.endif
|
||||
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
tay
|
||||
.ifdef __ATARIXL__
|
||||
rts
|
||||
.else
|
||||
pla
|
||||
rti
|
||||
.endif
|
||||
|
||||
|
||||
; Disable the interrupt source which caused us to be called.
|
||||
; The interrupt will be enabled again by the "IRQ" routine.
|
||||
; The "IRQ" routine, despite its name, is called from the
|
||||
; vertical blank NMI interrupt *only* if the CRITIC flag has
|
||||
; been cleared.
|
||||
|
||||
disable_me:
|
||||
lda POKMSK
|
||||
and #%11111110 ; timer 1 disable
|
||||
sta IRQEN
|
||||
sta POKMSK
|
||||
lda #0
|
||||
sta irq_enabled
|
||||
lda PORTA
|
||||
and #$0f
|
||||
sta old_porta_vbi
|
||||
.ifdef __ATARIXL__
|
||||
rts
|
||||
.else
|
||||
pla
|
||||
rti
|
||||
.endif
|
||||
2
libsrc/atari/mou/atrtrk.s
Normal file
2
libsrc/atari/mou/atrtrk.s
Normal file
@@ -0,0 +1,2 @@
|
||||
TRAK_MOUSE = 1
|
||||
.include "atrst.s"
|
||||
482
libsrc/atari/mou/atrtt.s
Normal file
482
libsrc/atari/mou/atrtt.s
Normal file
@@ -0,0 +1,482 @@
|
||||
;
|
||||
; Mouse driver for Atari Touch Tablet
|
||||
;
|
||||
; Christian Groessler, 2014-01-05
|
||||
;
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "mouse-kernel.inc"
|
||||
.include "atari.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxtt_mou
|
||||
.else
|
||||
module_header _atrtt_mou
|
||||
.endif
|
||||
|
||||
HEADER:
|
||||
|
||||
; Driver signature
|
||||
|
||||
.byte $6d, $6f, $75 ; "mou"
|
||||
.byte MOUSE_API_VERSION ; Mouse driver API version number
|
||||
|
||||
; Library reference
|
||||
|
||||
.addr $0000
|
||||
|
||||
; Jump table
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr HIDE
|
||||
.addr SHOW
|
||||
.addr SETBOX
|
||||
.addr GETBOX
|
||||
.addr MOVE
|
||||
.addr BUTTONS
|
||||
.addr POS
|
||||
.addr INFO
|
||||
.addr IOCTL
|
||||
.addr IRQ
|
||||
|
||||
; Mouse driver flags
|
||||
|
||||
.byte MOUSE_FLAG_LATE_IRQ
|
||||
|
||||
; Callback table, set by the kernel before INSTALL is called
|
||||
|
||||
CHIDE: jmp $0000 ; Hide the cursor
|
||||
CSHOW: jmp $0000 ; Show the cursor
|
||||
CPREP: jmp $0000 ; Prepare to move the cursor
|
||||
CDRAW: jmp $0000 ; Draw the cursor
|
||||
CMOVEX: jmp $0000 ; Move the cursor to X coord
|
||||
CMOVEY: jmp $0000 ; Move the cursor to Y coord
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Constants
|
||||
|
||||
SCREEN_HEIGHT = 191
|
||||
SCREEN_WIDTH = 319
|
||||
|
||||
.enum JOY
|
||||
UP = $01
|
||||
DOWN = $02
|
||||
LEFT = $04
|
||||
RIGHT = $08
|
||||
.endenum
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Global variables. The bounding box values are sorted so that they can be
|
||||
; written with the least effort in the SETBOX and GETBOX routines, so don't
|
||||
; reorder them.
|
||||
|
||||
.bss
|
||||
|
||||
Vars:
|
||||
YPos: .res 2 ; Current mouse position, Y
|
||||
XPos: .res 2 ; Current mouse position, X
|
||||
XMin: .res 2 ; X1 value of bounding box
|
||||
YMin: .res 2 ; Y1 value of bounding box
|
||||
XMax: .res 2 ; X2 value of bounding box
|
||||
YMax: .res 2 ; Y2 value of bounding box
|
||||
Buttons: .res 1 ; Button mask
|
||||
|
||||
; Default values for above variables
|
||||
|
||||
.rodata
|
||||
|
||||
; (We use ".proc" because we want to define both a label and a scope.)
|
||||
|
||||
.proc DefVars
|
||||
.word SCREEN_HEIGHT/2 ; YPos
|
||||
.word SCREEN_WIDTH/2 ; XPos
|
||||
.word 0 ; XMin
|
||||
.word 0 ; YMin
|
||||
.word SCREEN_WIDTH ; XMax
|
||||
.word SCREEN_HEIGHT ; YMax
|
||||
.byte 0 ; Buttons
|
||||
.endproc
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; INSTALL routine. Is called after the driver is loaded into memory. If
|
||||
; possible, check if the hardware is present.
|
||||
; Must return an MOUSE_ERR_xx code in a/x.
|
||||
|
||||
INSTALL:
|
||||
|
||||
; Initialize variables. Just copy the default stuff over
|
||||
|
||||
ldx #.sizeof(DefVars)-1
|
||||
@L1: lda DefVars,x
|
||||
sta Vars,x
|
||||
dex
|
||||
bpl @L1
|
||||
|
||||
; Make sure the mouse cursor is at the default location.
|
||||
|
||||
lda XPos
|
||||
ldx XPos+1
|
||||
jsr CMOVEX
|
||||
lda YPos
|
||||
ldx YPos+1
|
||||
jsr CMOVEY
|
||||
|
||||
; Done, return zero (= MOUSE_ERR_OK)
|
||||
|
||||
ldx #$00
|
||||
txa
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory.
|
||||
; No return code required (the driver is removed from memory on return).
|
||||
|
||||
UNINSTALL = HIDE ; Hide cursor on exit
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; HIDE routine. Is called to hide the mouse pointer. The mouse kernel manages
|
||||
; a counter for calls to show/hide, and the driver entry point is only called
|
||||
; if the mouse is currently visible and should get hidden. For most drivers,
|
||||
; no special action is required besides hiding the mouse cursor.
|
||||
; No return code required.
|
||||
|
||||
HIDE: php
|
||||
sei
|
||||
jsr CHIDE
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SHOW routine. Is called to show the mouse pointer. The mouse kernel manages
|
||||
; a counter for calls to show/hide, and the driver entry point is only called
|
||||
; if the mouse is currently hidden and should become visible. For most drivers,
|
||||
; no special action is required besides enabling the mouse cursor.
|
||||
; No return code required.
|
||||
|
||||
SHOW: php
|
||||
sei
|
||||
jsr CSHOW
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SETBOX: Set the mouse bounding box. The parameters are passed as they come
|
||||
; from the C program, that is, a pointer to a mouse_box struct in a/x.
|
||||
; No checks are done if the mouse is currently inside the box, this is the job
|
||||
; of the caller. It is not necessary to validate the parameters, trust the
|
||||
; caller and save some code here. No return code required.
|
||||
|
||||
SETBOX: sta ptr1
|
||||
stx ptr1+1 ; Save data pointer
|
||||
|
||||
ldy #.sizeof (MOUSE_BOX)-1
|
||||
php
|
||||
sei
|
||||
|
||||
@L1: lda (ptr1),y
|
||||
sta XMin,y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; GETBOX: Return the mouse bounding box. The parameters are passed as they
|
||||
; come from the C program, that is, a pointer to a mouse_box struct in a/x.
|
||||
|
||||
GETBOX: sta ptr1
|
||||
stx ptr1+1 ; Save data pointer
|
||||
|
||||
ldy #.sizeof (MOUSE_BOX)-1
|
||||
php
|
||||
sei
|
||||
|
||||
@L1: lda XMin,y
|
||||
sta (ptr1),y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
plp
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; MOVE: Move the mouse to a new position. The position is passed as it comes
|
||||
; from the C program, that is: X on the stack and Y in a/x. The C wrapper will
|
||||
; remove the parameter from the stack on return.
|
||||
; No checks are done if the new position is valid (within the bounding box or
|
||||
; the screen). No return code required.
|
||||
;
|
||||
|
||||
MOVE: php
|
||||
sei ; No interrupts
|
||||
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
jsr CPREP
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
|
||||
sta YPos
|
||||
stx YPos+1 ; New Y position
|
||||
jsr CMOVEY ; Set it
|
||||
|
||||
ldy #$01
|
||||
lda (sp),y
|
||||
sta XPos+1
|
||||
tax
|
||||
dey
|
||||
lda (sp),y
|
||||
sta XPos ; New X position
|
||||
jsr CMOVEX ; Move the cursor
|
||||
|
||||
jsr CSHOW
|
||||
|
||||
plp ; Restore interrupt flag
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; BUTTONS: Return the button mask in a/x.
|
||||
|
||||
BUTTONS:
|
||||
lda Buttons
|
||||
ldx #$00
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; POS: Return the mouse position in the MOUSE_POS struct pointed to by ptr1.
|
||||
; No return code required.
|
||||
|
||||
POS: ldy #MOUSE_POS::XCOORD ; Structure offset
|
||||
|
||||
php
|
||||
sei ; Disable interrupts
|
||||
lda XPos ; Transfer the position
|
||||
sta (ptr1),y
|
||||
lda XPos+1
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda YPos
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda YPos+1
|
||||
plp ; Restore interrupt flag
|
||||
|
||||
iny
|
||||
sta (ptr1),y ; Store last byte
|
||||
|
||||
rts ; Done
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; INFO: Returns mouse position and current button mask in the MOUSE_INFO
|
||||
; struct pointed to by ptr1. No return code required.
|
||||
;
|
||||
; We're cheating here to keep the code smaller: The first fields of the
|
||||
; mouse_info struct are identical to the mouse_pos struct, so we will just
|
||||
; call _mouse_pos to initialize the struct pointer and fill the position
|
||||
; fields.
|
||||
|
||||
INFO: jsr POS
|
||||
|
||||
; Fill in the button state
|
||||
|
||||
lda Buttons
|
||||
ldy #MOUSE_INFO::BUTTONS
|
||||
sta (ptr1),y
|
||||
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioclts for now
|
||||
ldx #>MOUSE_ERR_INV_IOCTL
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; IRQ: Irq handler entry point. Called as a subroutine but in IRQ context
|
||||
; (so be careful). The routine MUST return carry set if the interrupt has been
|
||||
; 'handled' - which means that the interrupt source is gone. Otherwise it
|
||||
; MUST return carry clear.
|
||||
;
|
||||
|
||||
IRQ:
|
||||
|
||||
; Check for a pressed button and place the result into Buttons
|
||||
|
||||
ldx #0
|
||||
stx Buttons
|
||||
|
||||
lda PORTA ; get other buttons
|
||||
eor #255
|
||||
tax
|
||||
and #5 ; pen button and left button are mapped to left mouse button
|
||||
beq @L01
|
||||
lda #MOUSE_BTN_LEFT
|
||||
ora Buttons
|
||||
sta Buttons
|
||||
@L01: txa
|
||||
and #8
|
||||
beq @L02
|
||||
lda #MOUSE_BTN_RIGHT
|
||||
ora Buttons
|
||||
sta Buttons
|
||||
|
||||
; If we read 228 for X or Y positions, we assume the user has lifted the pen
|
||||
; and don't change the cursor position.
|
||||
|
||||
@L02: lda PADDL0
|
||||
cmp #228
|
||||
beq @Cont ; CF set if equal
|
||||
lda PADDL1
|
||||
cmp #228 ; CF set if equal
|
||||
|
||||
@Cont: php ; remember CF
|
||||
jsr CPREP
|
||||
plp ; restore CF
|
||||
|
||||
bcc @L03
|
||||
jmp @Show
|
||||
|
||||
@L03: ldx #0
|
||||
stx XPos+1
|
||||
stx YPos+1
|
||||
|
||||
; Get cursor position
|
||||
; -------------------
|
||||
; The touch pad is read thru the paddle potentiometers. The possible
|
||||
; values are 1..228. Since the maximum value is less than the X
|
||||
; dimension we have to "stretch" this value. In order to use only
|
||||
; divisions by powers of two, we use the following appoximation:
|
||||
; 320/227 = 1.4096
|
||||
; 1+1/2-1/8+1/32 = 1.4062
|
||||
; For Y we subtract 1/8 of it to get in the YMax ballpark.
|
||||
; 228-228/8=199.5
|
||||
; A small area in the Y dimension of the touchpad isn't used with
|
||||
; this approximation. The Y value is inverted, (0,0) is the bottom
|
||||
; left corner of the touchpad.
|
||||
|
||||
; X
|
||||
|
||||
ldx PADDL0 ; get X postion
|
||||
dex ; decrement, since it's 1-based
|
||||
stx XPos
|
||||
txa
|
||||
lsr a
|
||||
tax
|
||||
clc
|
||||
adc XPos
|
||||
sta XPos
|
||||
bcc @L04
|
||||
inc XPos+1
|
||||
@L04: txa
|
||||
lsr a ; port value / 4
|
||||
lsr a ; port value / 8
|
||||
tax
|
||||
sec
|
||||
lda XPos
|
||||
stx XPos
|
||||
sbc XPos
|
||||
sta XPos
|
||||
bcs @L05
|
||||
dec XPos+1
|
||||
@L05: txa
|
||||
lsr a ; port value / 16
|
||||
lsr a ; port value / 32
|
||||
clc
|
||||
adc XPos
|
||||
sta XPos
|
||||
bcc @L06
|
||||
inc XPos+1
|
||||
|
||||
@L06: tay
|
||||
lda XPos+1
|
||||
tax
|
||||
|
||||
; Limit the X coordinate to the bounding box
|
||||
|
||||
cpy XMin
|
||||
sbc XMin+1
|
||||
bpl @L07
|
||||
ldy XMin
|
||||
ldx XMin+1
|
||||
jmp @L08
|
||||
@L07: txa
|
||||
|
||||
cpy XMax
|
||||
sbc XMax+1
|
||||
bmi @L08
|
||||
ldy XMax
|
||||
ldx XMax+1
|
||||
@L08: sty XPos
|
||||
stx XPos+1
|
||||
|
||||
; Move the mouse pointer to the new X pos
|
||||
|
||||
tya
|
||||
jsr CMOVEX
|
||||
|
||||
; Y
|
||||
|
||||
ldx PADDL1 ; get Y postion
|
||||
dex ; decrement, since it's 1-based
|
||||
stx YPos
|
||||
lda #228
|
||||
sec
|
||||
sbc YPos ; invert value
|
||||
tax
|
||||
lsr a
|
||||
lsr a
|
||||
lsr a
|
||||
sta YPos
|
||||
txa
|
||||
sec
|
||||
sbc YPos
|
||||
sta YPos
|
||||
tay
|
||||
lda YPos+1
|
||||
tax
|
||||
|
||||
; Limit the Y coordinate to the bounding box
|
||||
|
||||
cpy YMin
|
||||
sbc YMin+1
|
||||
bpl @L09
|
||||
ldy YMin
|
||||
ldx YMin+1
|
||||
jmp @L10
|
||||
@L09: txa
|
||||
|
||||
cpy YMax
|
||||
sbc YMax+1
|
||||
bmi @L10
|
||||
ldy YMax
|
||||
ldx YMax+1
|
||||
@L10: sty YPos
|
||||
stx YPos+1
|
||||
|
||||
; Move the mouse pointer to the new X pos
|
||||
|
||||
tya
|
||||
jsr CMOVEY
|
||||
|
||||
@Show: jsr CDRAW
|
||||
|
||||
clc ; Interrupt not "handled"
|
||||
rts
|
||||
|
||||
@@ -1,576 +0,0 @@
|
||||
;--------------------------------------------------------------------
|
||||
; Atari 8-bit mouse routines -- 05/07/2000 Freddy Offenga
|
||||
; Some changes by Christian Groessler, Ullrich von Bassewitz
|
||||
;
|
||||
; The following devices are supported:
|
||||
; - Atari trak-ball
|
||||
; - ST mouse
|
||||
; - Amiga mouse
|
||||
;
|
||||
; Mouse checks are done in the timer 1 IRQ and the mouse arrow is
|
||||
; drawn in player 0 during the vertical blank
|
||||
;--------------------------------------------------------------------
|
||||
|
||||
.export _mouse_init, _mouse_done, _mouse_box
|
||||
.export _mouse_show, _mouse_hide, _mouse_move
|
||||
.export _mouse_buttons, _mouse_pos, _mouse_info
|
||||
.constructor initmouse,27
|
||||
|
||||
.import popax
|
||||
.importzp ptr1
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
TRAK_BALL = 0 ; device Atari trak-ball
|
||||
ST_MOUSE = 1 ; device ST mouse
|
||||
AMIGA_MOUSE = 2 ; device Amiga mouse
|
||||
MAX_TYPE = 3 ; first illegal device type
|
||||
|
||||
; the default values force the mouse cursor inside the test screen (no access to border)
|
||||
defxmin = 48 ; default x minimum
|
||||
defymin = 31 ; default y minimum
|
||||
defxmax = 204 ; default x maximum
|
||||
defymax = 211 ; default y maximum
|
||||
|
||||
pmsize = 16 ; y size pm shape
|
||||
|
||||
xinit = defxmin ; init. x pos.
|
||||
yinit = defymin ; init. y pos.
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; reserve memory for the mouse pointer
|
||||
|
||||
initmouse:
|
||||
lda APPMHI+1
|
||||
and #%11111000 ; make 2k aligned
|
||||
sec
|
||||
sbc #%00001000 ; reserve 2k
|
||||
tax
|
||||
adc #3 ; add 4 (C = 1)
|
||||
sta mouse_pm0
|
||||
lda #0
|
||||
sta APPMHI
|
||||
stx APPMHI+1
|
||||
rts
|
||||
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Initialize mouse routines
|
||||
; void __fastcall__ mouse_init (unsigned char type);
|
||||
|
||||
_mouse_init:
|
||||
cmp #MAX_TYPE+1 ; Check for a valid type
|
||||
bcc setup
|
||||
|
||||
ifail: lda #0 ; init. failed
|
||||
tax
|
||||
rts
|
||||
|
||||
setup: tax
|
||||
lda lvectab,x
|
||||
sta mouse_vec+1
|
||||
lda hvectab,x
|
||||
sta mouse_vec+2
|
||||
|
||||
jsr pminit
|
||||
|
||||
lda VTIMR1
|
||||
sta old_t1
|
||||
lda VTIMR1+1
|
||||
sta old_t1+1
|
||||
|
||||
lda #<t1_vec
|
||||
sta VTIMR1
|
||||
lda #>t1_vec
|
||||
sta VTIMR1+1
|
||||
|
||||
lda #%00000001
|
||||
sta AUDCTL
|
||||
|
||||
lda #0
|
||||
sta AUDC1
|
||||
|
||||
lda #15
|
||||
sta AUDF1
|
||||
sta STIMER
|
||||
|
||||
sei
|
||||
lda POKMSK
|
||||
ora #%00000001 ; timer 1 enable
|
||||
sta POKMSK
|
||||
sta IRQEN
|
||||
cli
|
||||
|
||||
lda VVBLKI
|
||||
sta vbi_jmp+1
|
||||
lda VVBLKI+1
|
||||
sta vbi_jmp+2
|
||||
|
||||
lda #6
|
||||
ldy #<vbi
|
||||
ldx #>vbi
|
||||
jsr SETVBV
|
||||
|
||||
lda #$C0
|
||||
sta NMIEN
|
||||
|
||||
ldx #0
|
||||
lda #1
|
||||
sta mouse_off
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Finish mouse routines
|
||||
; void mouse_done(void)
|
||||
|
||||
_mouse_done:
|
||||
sei
|
||||
lda POKMSK
|
||||
and #%11111110 ; timer 1 disable
|
||||
sta IRQEN
|
||||
sta POKMSK
|
||||
cli
|
||||
|
||||
lda old_t1
|
||||
sta VTIMR1
|
||||
lda old_t1+1
|
||||
sta VTIMR1+1
|
||||
|
||||
lda #$40
|
||||
sta NMIEN
|
||||
|
||||
lda #6
|
||||
ldy vbi_jmp+1
|
||||
ldx vbi_jmp+2
|
||||
jsr SETVBV
|
||||
|
||||
ldx #0
|
||||
stx GRACTL
|
||||
stx HPOSP0
|
||||
inx
|
||||
stx mouse_off
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Set mouse limits
|
||||
; void __fastcall__ mouse_box(int xmin, int ymin, int xmax, int ymax)
|
||||
|
||||
_mouse_box:
|
||||
sta ymax
|
||||
jsr popax ; always ignore high byte
|
||||
sta xmax
|
||||
jsr popax
|
||||
sta ymin
|
||||
jsr popax
|
||||
sta xmin
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Set mouse position
|
||||
; void __fastcall__ mouse_move(int xpos, int ypos)
|
||||
|
||||
_mouse_move:
|
||||
sta mousey ; always ignore high byte
|
||||
jsr popax
|
||||
sta mousex
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Show mouse arrow
|
||||
; void mouse_show(void)
|
||||
|
||||
_mouse_show:
|
||||
lda mouse_off ; Already on?
|
||||
beq @L1
|
||||
dec mouse_off
|
||||
@L1: rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Hide mouse arrow
|
||||
; void mouse_hide(void)
|
||||
|
||||
_mouse_hide:
|
||||
inc mouse_off
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Ask mouse button
|
||||
; unsigned char mouse_buttons(void)
|
||||
|
||||
_mouse_buttons:
|
||||
ldx #0
|
||||
lda STRIG0
|
||||
bne nobut
|
||||
; lda #14
|
||||
;??? sta COLOR1
|
||||
lda #1
|
||||
rts
|
||||
nobut: txa
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Get the mouse position
|
||||
; void mouse_pos (struct mouse_pos* pos);
|
||||
|
||||
_mouse_pos:
|
||||
sta ptr1
|
||||
stx ptr1+1 ; Store argument pointer
|
||||
ldy #0
|
||||
lda mousex ; X position
|
||||
sta (ptr1),y
|
||||
lda #0
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda mousey ; Y position
|
||||
iny
|
||||
sta (ptr1),y
|
||||
lda #0
|
||||
iny
|
||||
sta (ptr1),y
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Get the mouse position and button information
|
||||
; void mouse_info (struct mouse_info* info);
|
||||
|
||||
_mouse_info:
|
||||
|
||||
; We're cheating here to keep the code smaller: The first fields of the
|
||||
; mouse_info struct are identical to the mouse_pos struct, so we will just
|
||||
; call _mouse_pos to initialize the struct pointer and fill the position
|
||||
; fields.
|
||||
|
||||
jsr _mouse_pos
|
||||
|
||||
; Fill in the button state
|
||||
|
||||
jsr _mouse_buttons ; Will not touch ptr1
|
||||
ldy #4
|
||||
sta (ptr1),y
|
||||
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Atari trak-ball check, A,Y = 4-bit port value
|
||||
|
||||
trak_check:
|
||||
eor oldval
|
||||
and #%00001000
|
||||
beq horiz
|
||||
|
||||
tya
|
||||
and #%00000100
|
||||
beq mmup
|
||||
|
||||
inc mousey
|
||||
bne horiz
|
||||
|
||||
mmup: dec mousey
|
||||
|
||||
horiz: tya
|
||||
eor oldval
|
||||
and #%00000010
|
||||
beq mmexit
|
||||
|
||||
tya
|
||||
and #%00000001
|
||||
beq mmleft
|
||||
|
||||
inc mousex
|
||||
bne mmexit
|
||||
|
||||
mmleft: dec mousex
|
||||
|
||||
mmexit: sty oldval
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; ST mouse check, A,Y = 4-bit port value
|
||||
|
||||
st_check:
|
||||
and #%00000011
|
||||
ora dumx
|
||||
tax
|
||||
lda sttab,x
|
||||
bmi nxst
|
||||
|
||||
beq xist
|
||||
dec mousex ; 1 = left
|
||||
bne nxst
|
||||
xist: inc mousex ; 0 = right
|
||||
|
||||
nxst: tya
|
||||
and #%00001100
|
||||
ora dumy
|
||||
tax
|
||||
lda sttab,x
|
||||
bmi nyst
|
||||
|
||||
bne yst
|
||||
dec mousey ; 0 = up
|
||||
bne nyst
|
||||
yst: inc mousey ; 1 = down
|
||||
|
||||
; store old readings
|
||||
|
||||
nyst: tya
|
||||
and #%00000011
|
||||
asl
|
||||
asl
|
||||
sta dumx
|
||||
tya
|
||||
and #%00001100
|
||||
lsr
|
||||
lsr
|
||||
sta dumy
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; Amiga mouse check, A,Y = 4-bit port value
|
||||
|
||||
amiga_check:
|
||||
|
||||
lsr
|
||||
and #%00000101
|
||||
ora dumx
|
||||
tax
|
||||
lda amitab,x
|
||||
bmi nxami
|
||||
|
||||
bne xiami
|
||||
dec mousex ; 0 = left
|
||||
bne nxami
|
||||
xiami: inc mousex ; 1 = right
|
||||
|
||||
nxami: tya
|
||||
|
||||
and #%00000101
|
||||
ora dumy
|
||||
tax
|
||||
lda amitab,x
|
||||
bmi nyami
|
||||
|
||||
bne yiami
|
||||
dec mousey ; 0 = up
|
||||
bne nyami
|
||||
yiami: inc mousey ; 1 = down
|
||||
|
||||
; store old readings
|
||||
|
||||
nyami: tya
|
||||
and #%00001010
|
||||
sta dumx
|
||||
tya
|
||||
and #%00000101
|
||||
asl
|
||||
sta dumy
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; timer 1 IRQ routine - check mouse
|
||||
|
||||
t1_vec: tya
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
|
||||
.ifdef DEBUG
|
||||
lda RANDOM
|
||||
sta COLBK ; debug
|
||||
.endif
|
||||
|
||||
lda PORTA
|
||||
tay
|
||||
|
||||
mouse_vec:
|
||||
jsr st_check ; will be modified; won't be ROMmable
|
||||
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
rti
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; VBI - check mouse limits and display mouse arrow
|
||||
|
||||
vbi: lda mousex
|
||||
cmp xmin
|
||||
bcs ok1 ; xmin <= mousex
|
||||
lda xmin
|
||||
sta mousex
|
||||
|
||||
ok1: lda mousey
|
||||
cmp ymin
|
||||
bcs ok2 ; ymin <= mousey
|
||||
lda ymin
|
||||
sta mousey
|
||||
|
||||
ok2: lda xmax
|
||||
cmp mousex
|
||||
bcs ok3 ; xmax >= mousex
|
||||
lda xmax
|
||||
sta mousex
|
||||
|
||||
ok3: lda ymax
|
||||
cmp mousey
|
||||
bcs ok4 ; ymax >= mousey
|
||||
lda ymax
|
||||
sta mousey
|
||||
|
||||
ok4: jsr clrpm
|
||||
|
||||
lda mouse_off
|
||||
beq mon
|
||||
lda #0
|
||||
sta HPOSP0
|
||||
beq moff
|
||||
|
||||
mon: jsr drwpm
|
||||
lda mousey
|
||||
sta omy
|
||||
|
||||
lda #3
|
||||
moff: sta GRACTL
|
||||
|
||||
vbi_jmp:
|
||||
jmp SYSVBV ; will be modified; won't be ROMmable
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; initialize mouse pm
|
||||
|
||||
pminit: lda mouse_pm0
|
||||
sta mpatch1+2
|
||||
sta mpatch2+2
|
||||
sta mpatch3+2
|
||||
|
||||
ldx #0
|
||||
txa
|
||||
mpatch1:
|
||||
clpm: sta $1000,x ; will be patched
|
||||
inx
|
||||
bne clpm
|
||||
|
||||
lda mouse_pm0
|
||||
sec
|
||||
sbc #4
|
||||
sta PMBASE
|
||||
|
||||
lda #62
|
||||
sta SDMCTL
|
||||
|
||||
lda #1
|
||||
sta GPRIOR
|
||||
|
||||
lda #0
|
||||
sta PCOLR0
|
||||
sta SIZEP0
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; draw new mouse pm
|
||||
|
||||
drwpm: lda mousex
|
||||
sta HPOSP0
|
||||
|
||||
lda mousey
|
||||
tax
|
||||
|
||||
ldy #0
|
||||
fmp2: lda mskpm,y
|
||||
mpatch2:
|
||||
sta $1000,x ; will be patched
|
||||
inx
|
||||
iny
|
||||
cpy #pmsize
|
||||
bne fmp2
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
; clear old mouse pm
|
||||
|
||||
clrpm: lda omy
|
||||
tax
|
||||
|
||||
ldy #0
|
||||
tya
|
||||
mpatch3:
|
||||
fmp1: sta $1000,x ; will be patched
|
||||
inx
|
||||
iny
|
||||
cpy #pmsize
|
||||
bne fmp1
|
||||
rts
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
.rodata
|
||||
|
||||
; mouse arrow - pm shape
|
||||
|
||||
mskpm: .byte %00000000
|
||||
.byte %10000000
|
||||
.byte %11000000
|
||||
.byte %11000000
|
||||
|
||||
.byte %11100000
|
||||
.byte %11100000
|
||||
.byte %11110000
|
||||
.byte %11100000
|
||||
|
||||
.byte %11100000
|
||||
.byte %00100000
|
||||
.byte %00100000
|
||||
.byte %00110000
|
||||
|
||||
.byte %00110000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
.byte %00000000
|
||||
|
||||
; ST mouse lookup table
|
||||
|
||||
sttab: .byte $FF,$01,$00,$01
|
||||
.byte $00,$FF,$00,$01
|
||||
.byte $01,$00,$FF,$00
|
||||
.byte $01,$00,$01,$FF
|
||||
|
||||
; Amiga mouse lookup table
|
||||
|
||||
amitab: .byte $FF,$01,$00,$FF
|
||||
.byte $00,$FF,$FF,$01
|
||||
.byte $01,$FF,$FF,$00
|
||||
.byte $FF,$00,$01,$FF
|
||||
|
||||
; Device vectors
|
||||
|
||||
lvectab:
|
||||
.byte <trak_check, <st_check, <amiga_check
|
||||
hvectab:
|
||||
.byte >trak_check, >st_check, >amiga_check
|
||||
|
||||
; default values
|
||||
|
||||
xmin: .byte defxmin
|
||||
ymin: .byte defymin
|
||||
xmax: .byte defxmax
|
||||
ymax: .byte defymax
|
||||
|
||||
mousex: .byte xinit
|
||||
mousey: .byte yinit
|
||||
|
||||
;--------------------------------------------------------------------
|
||||
.bss
|
||||
|
||||
; Misc. vars
|
||||
|
||||
old_t1: .res 2 ; old timer interrupt vector
|
||||
oldval: .res 1 ; used by trakball routines
|
||||
dumx: .res 1
|
||||
dumy: .res 1
|
||||
omy: .res 1 ; old y pos
|
||||
|
||||
mouse_off:
|
||||
.res 1
|
||||
mouse_pm0:
|
||||
.res 1
|
||||
22
libsrc/atari/mouse_stat_stddrv.s
Normal file
22
libsrc/atari/mouse_stat_stddrv.s
Normal file
@@ -0,0 +1,22 @@
|
||||
;
|
||||
; Address of the static standard mouse driver
|
||||
;
|
||||
; Christian Groessler, 2014-01-02
|
||||
;
|
||||
; const void mouse_static_stddrv[];
|
||||
;
|
||||
|
||||
.export _mouse_static_stddrv
|
||||
.ifdef __ATARIXL__
|
||||
.import _atrxst_mou
|
||||
.else
|
||||
.import _atrst_mou
|
||||
.endif
|
||||
|
||||
.rodata
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
_mouse_static_stddrv := _atrxst_mou
|
||||
.else
|
||||
_mouse_static_stddrv := _atrst_mou
|
||||
.endif
|
||||
18
libsrc/atari/mouse_stddrv.s
Normal file
18
libsrc/atari/mouse_stddrv.s
Normal file
@@ -0,0 +1,18 @@
|
||||
;
|
||||
; Name of the standard mouse driver
|
||||
;
|
||||
; Christian Groessler, 2014-01-02
|
||||
;
|
||||
; const char mouse_stddrv[];
|
||||
;
|
||||
|
||||
.export _mouse_stddrv
|
||||
|
||||
.rodata
|
||||
|
||||
_mouse_stddrv:
|
||||
.ifdef __ATARIXL__
|
||||
.asciiz "ATRXST.MOU"
|
||||
.else
|
||||
.asciiz "ATRST.MOU"
|
||||
.endif
|
||||
13
libsrc/atari/mouseref.s
Normal file
13
libsrc/atari/mouseref.s
Normal file
@@ -0,0 +1,13 @@
|
||||
;
|
||||
; Christian Groessler, 2014-04-22
|
||||
;
|
||||
|
||||
.export mouse_libref
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
.import set_VTIMR1_handler
|
||||
mouse_libref := set_VTIMR1_handler
|
||||
.else
|
||||
.import _exit
|
||||
mouse_libref := _exit
|
||||
.endif
|
||||
@@ -6,7 +6,7 @@
|
||||
; uses tmp4
|
||||
|
||||
.importzp tmp4
|
||||
.export mul40
|
||||
.export mul40,loc_tmp
|
||||
|
||||
.proc mul40
|
||||
|
||||
|
||||
@@ -48,13 +48,13 @@ _inviocb:
|
||||
.segment "EXTZP" : zeropage
|
||||
|
||||
index: .res 1 ; index into line buffer
|
||||
buflen: .res 1 ; length of used part of buffer
|
||||
cbs: .res 1 ; current buffer size: buflen - index
|
||||
dataptr:.res 2 ; temp pointer to user buffer
|
||||
copylen:.res 1 ; temp counter
|
||||
|
||||
.bss
|
||||
|
||||
buflen: .res 1 ; length of used part of buffer
|
||||
linebuf:.res LINEBUF ; the line buffer
|
||||
|
||||
.code
|
||||
|
||||
@@ -1,389 +0,0 @@
|
||||
;
|
||||
; Christian Groessler, Dec-2001
|
||||
;
|
||||
; RS232 routines using the R: device (currently tested with an 850 only)
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_init (char hacked);
|
||||
; unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity);
|
||||
; unsigned char __fastcall__ rs232_done (void);
|
||||
; unsigned char __fastcall__ rs232_get (char* B);
|
||||
; unsigned char __fastcall__ rs232_put (char B);
|
||||
; unsigned char __fastcall__ rs232_pause (void); [TODO]
|
||||
; unsigned char __fastcall__ rs232_unpause (void); [TODO]
|
||||
; unsigned char __fastcall__ rs232_status (unsigned char* status,
|
||||
; unsigned char* errors); [TODO]
|
||||
;
|
||||
|
||||
.import findfreeiocb
|
||||
.import __do_oserror
|
||||
.import fddecusage
|
||||
.import fdtoiocb
|
||||
.import __inviocb
|
||||
.import clriocb
|
||||
.import newfd
|
||||
.import _close, pushax, popax, popa
|
||||
.importzp ptr1, tmp2, tmp3
|
||||
|
||||
.export _rs232_init, _rs232_params, _rs232_done, _rs232_get
|
||||
.export _rs232_put, _rs232_pause, _rs232_unpause, _rs232_status
|
||||
|
||||
.include "atari.inc"
|
||||
.include "errno.inc"
|
||||
.include "rs232.inc"
|
||||
|
||||
.rodata
|
||||
|
||||
rdev: .byte "R:", ATEOL, 0
|
||||
|
||||
.bss
|
||||
|
||||
; receive buffer
|
||||
RECVBUF_SZ = 256
|
||||
recv_buf: .res RECVBUF_SZ
|
||||
|
||||
cm_run: .res 1 ; concurrent mode running?
|
||||
|
||||
.data
|
||||
|
||||
rshand: .word $ffff
|
||||
|
||||
.code
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_init (char hacked);
|
||||
; /* Initialize the serial port. The parameter is ignored in the Atari version.
|
||||
; * return 0/-1 for OK/Error
|
||||
; */
|
||||
;
|
||||
|
||||
.proc _rs232_init
|
||||
|
||||
jsr findfreeiocb
|
||||
bne init_err
|
||||
txa
|
||||
tay ; move iocb # into Y
|
||||
lda #3
|
||||
sta tmp3 ; name length + 1
|
||||
lda #<rdev
|
||||
ldx #>rdev
|
||||
jsr newfd
|
||||
tya
|
||||
bcs doopen ; C set: open needed / device not already open
|
||||
|
||||
pha
|
||||
jsr _rs232_done ;** shut down if started @@@TODO check this out!!
|
||||
pla
|
||||
|
||||
doopen: tax
|
||||
pha
|
||||
jsr clriocb
|
||||
pla
|
||||
tax
|
||||
lda #<rdev
|
||||
sta ICBAL,x
|
||||
lda #>rdev
|
||||
sta ICBAH,x
|
||||
lda #OPEN
|
||||
sta ICCOM,x
|
||||
|
||||
lda #$0D ; mode in+out+concurrent
|
||||
sta ICAX1,x
|
||||
lda #0
|
||||
sta ICAX2,x
|
||||
sta ICBLL,x ; zap buf len
|
||||
sta ICBLH,x
|
||||
jsr CIOV
|
||||
bmi cioerr1
|
||||
|
||||
lda tmp2 ; get fd
|
||||
sta rshand
|
||||
ldx #0
|
||||
stx rshand+1
|
||||
txa
|
||||
rts
|
||||
|
||||
cioerr1:jsr fddecusage ; decrement usage counter of fd as open failed
|
||||
|
||||
init_err:
|
||||
ldx #0
|
||||
lda #RS_ERR_INIT_FAILED
|
||||
rts
|
||||
|
||||
.endproc ; _rs232_init
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity);
|
||||
;
|
||||
; Set communication parameters.
|
||||
;
|
||||
; params contains baud rate, stop bits and word size
|
||||
; parity contains parity
|
||||
;
|
||||
; 850 manual documents restrictions on the baud rate (not > 300), when not
|
||||
; using 8 bit word size. So only 8 bit is currently tested.
|
||||
;
|
||||
|
||||
.proc _rs232_params
|
||||
|
||||
sta tmp2
|
||||
lda rshand
|
||||
cmp #$ff
|
||||
bne work ; work only if initialized
|
||||
lda #RS_ERR_NOT_INITIALIZED
|
||||
bne done
|
||||
work: lda rshand
|
||||
ldx #0
|
||||
jsr fdtoiocb ; get iocb index into X
|
||||
bmi inverr ; shouldn't happen
|
||||
tax
|
||||
|
||||
; set handshake lines
|
||||
|
||||
lda #34 ; xio 34, set cts, dtr etc
|
||||
sta ICCOM,x
|
||||
lda #192+48+3 ; DTR on, RTS on, XMT on
|
||||
sta ICAX1,x
|
||||
lda #0
|
||||
sta ICBLL,x
|
||||
sta ICBLH,x
|
||||
sta ICBAL,x
|
||||
sta ICBAH,x
|
||||
sta ICAX2,x
|
||||
jsr CIOV
|
||||
bmi cioerr
|
||||
|
||||
; set baud rate, word size, stop bits and ready monitoring
|
||||
|
||||
lda #36 ; xio 36, baud rate
|
||||
sta ICCOM,x
|
||||
jsr popa ; get parameter
|
||||
sta ICAX1,x
|
||||
;ICAX2 = 0, monitor nothing
|
||||
jsr CIOV
|
||||
bmi cioerr
|
||||
|
||||
; set translation and parity
|
||||
|
||||
lda #38 ; xio 38, translation and parity
|
||||
sta ICCOM,x
|
||||
lda tmp2
|
||||
ora #32 ; no translation
|
||||
sta ICAX1,x
|
||||
jsr CIOV
|
||||
bmi cioerr
|
||||
|
||||
lda #0
|
||||
done: ldx #0
|
||||
rts
|
||||
|
||||
inverr: jmp __inviocb
|
||||
|
||||
.endproc ;_rs232_params
|
||||
|
||||
cioerr: jmp __do_oserror
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_done (void);
|
||||
; /* Close the port, deinstall the interrupt hander. You MUST call this function
|
||||
; * before terminating the program, otherwise the machine may crash later. If
|
||||
; * in doubt, install an exit handler using atexit(). The function will do
|
||||
; * nothing, if it was already called.
|
||||
; */
|
||||
;
|
||||
|
||||
.proc _rs232_done
|
||||
|
||||
lda rshand
|
||||
cmp #$ff
|
||||
beq done
|
||||
work: ldx rshand+1
|
||||
jsr pushax
|
||||
jsr _close
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
ldx #$ff
|
||||
stx rshand
|
||||
stx rshand+1
|
||||
inx
|
||||
stx cm_run
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
done: rts
|
||||
|
||||
.endproc ;rs232_done
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_get (char* B);
|
||||
; /* Get a character from the serial port. If no characters are available, the
|
||||
; * function will return RS_ERR_NO_DATA, so this is not a fatal error.
|
||||
; */
|
||||
;
|
||||
|
||||
.proc _rs232_get
|
||||
|
||||
ldy rshand
|
||||
cpy #$ff
|
||||
bne work ; work only if initialized
|
||||
lda #RS_ERR_NOT_INITIALIZED
|
||||
bne nierr
|
||||
|
||||
work: sta ptr1
|
||||
stx ptr1+1 ; store pointer to received char
|
||||
|
||||
lda rshand
|
||||
ldx #0
|
||||
jsr fdtoiocb
|
||||
tax
|
||||
lda cm_run ; concurrent mode already running?
|
||||
bne go
|
||||
jsr ena_cm ; turn on concurrent mode
|
||||
|
||||
go: ; check whether there is any input available
|
||||
|
||||
lda #STATIS ; status request, returns bytes pending
|
||||
sta ICCOM,x
|
||||
jsr CIOV
|
||||
bmi cioerr ; @@@ error handling
|
||||
|
||||
lda DVSTAT+1 ; get byte count pending
|
||||
ora DVSTAT+2
|
||||
beq nix_da ; no input waiting...
|
||||
|
||||
; input is available: get it!
|
||||
|
||||
lda #GETCHR ; get raw bytes
|
||||
sta ICCOM,x ; in command code
|
||||
lda #0
|
||||
sta ICBLL,x
|
||||
sta ICBLH,x
|
||||
sta ICBAL,x
|
||||
sta ICBAH,x
|
||||
jsr CIOV ; go get it
|
||||
bmi cioerr ; @@@ error handling
|
||||
|
||||
ldx #0
|
||||
sta (ptr1,x) ; return received byte
|
||||
txa
|
||||
rts
|
||||
|
||||
nierr: ldx #0
|
||||
rts
|
||||
|
||||
nix_da: lda #RS_ERR_NO_DATA
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
.endproc ;_rs232_get
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_put (char B);
|
||||
; /* Send a character via the serial port. There is a transmit buffer, but
|
||||
; * transmitting is not done via interrupt. The function returns
|
||||
; * RS_ERR_OVERFLOW if there is no space left in the transmit buffer.
|
||||
; */
|
||||
;
|
||||
|
||||
.proc _rs232_put
|
||||
|
||||
ldy rshand
|
||||
cpy #$ff
|
||||
bne work ; work only if initialized
|
||||
lda #RS_ERR_NOT_INITIALIZED
|
||||
bne nierr
|
||||
|
||||
work: pha
|
||||
lda rshand
|
||||
ldx #0
|
||||
jsr fdtoiocb
|
||||
tax
|
||||
lda cm_run ; concurrent mode already running?
|
||||
bne go
|
||||
jsr ena_cm ; turn on concurrent mode
|
||||
|
||||
; @@@TODO: check output buffer overflow
|
||||
go: lda #PUTCHR ; put raw bytes
|
||||
sta ICCOM,x ; in command code
|
||||
lda #0
|
||||
sta ICBLL,x
|
||||
sta ICBLH,x
|
||||
sta ICBAL,x
|
||||
sta ICBAH,x
|
||||
pla ; get the char back
|
||||
jsr CIOV ; go do it
|
||||
rts
|
||||
|
||||
nierr: ldx #0
|
||||
rts
|
||||
|
||||
.endproc ;_rs232_put
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_pause (void);
|
||||
; /* Assert flow control and disable interrupts. */
|
||||
;
|
||||
|
||||
_rs232_pause:
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_unpause (void);
|
||||
; /* Re-enable interrupts and release flow control */
|
||||
;
|
||||
|
||||
_rs232_unpause:
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;
|
||||
; unsigned char __fastcall__ rs232_status (unsigned char* status,
|
||||
; unsigned char* errors);
|
||||
; /* Return the serial port status. */
|
||||
;
|
||||
|
||||
_rs232_status:
|
||||
|
||||
lda #255
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
; enable concurrent rs232 mode
|
||||
; gets iocb index in X
|
||||
; all registers destroyed
|
||||
|
||||
.proc ena_cm
|
||||
|
||||
lda #40 ; XIO 40, start concurrent IO
|
||||
sta ICCOM,x
|
||||
sta cm_run ; indicate concurrent mode is running
|
||||
lda #0
|
||||
sta ICAX1,x
|
||||
sta ICAX2,x
|
||||
lda #<recv_buf
|
||||
sta ICBAL,x
|
||||
lda #>recv_buf
|
||||
sta ICBAH,x
|
||||
lda #<RECVBUF_SZ
|
||||
sta ICBLL,x
|
||||
lda #>RECVBUF_SZ
|
||||
sta ICBLH,x
|
||||
lda #$0D ; value from 850 man, p62. must be 0D?,
|
||||
sta ICAX1,x ; or any non-zero?
|
||||
jmp CIOV
|
||||
|
||||
.endproc ;ena_cm
|
||||
|
||||
.end
|
||||
585
libsrc/atari/ser/atrrdev.s
Normal file
585
libsrc/atari/ser/atrrdev.s
Normal file
@@ -0,0 +1,585 @@
|
||||
;
|
||||
; Christian Groessler, Dec-2001
|
||||
; converted to driver interface Dec-2013
|
||||
;
|
||||
; RS232 routines using the R: device (currently tested with an 850 only)
|
||||
;
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "ser-kernel.inc"
|
||||
.include "ser-error.inc"
|
||||
.include "atari.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
module_header _atrxrdev_ser
|
||||
.else
|
||||
module_header _atrrdev_ser
|
||||
.endif
|
||||
|
||||
; Driver signature
|
||||
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
.byte SER_API_VERSION ; Serial API version number
|
||||
|
||||
; Library reference
|
||||
|
||||
libref: .addr $0000
|
||||
|
||||
; Jump table
|
||||
|
||||
.word SER_INSTALL
|
||||
.word SER_UNINSTALL
|
||||
.word SER_OPEN
|
||||
.word SER_CLOSE
|
||||
.word SER_GET
|
||||
.word SER_PUT
|
||||
.word SER_STATUS
|
||||
.word SER_IOCTL
|
||||
.word SER_IRQ
|
||||
|
||||
|
||||
.rodata
|
||||
|
||||
rdev: .byte "R:", ATEOL, 0
|
||||
bauds: .byte 1 ; SER_BAUD_45_5
|
||||
.byte 2 ; SER_BAUD_50
|
||||
.byte 4 ; SER_BAUD_75
|
||||
.byte 5 ; SER_BAUD_110
|
||||
.byte 6 ; SER_BAUD_134_5
|
||||
.byte 7 ; SER_BAUD_150
|
||||
.byte 8 ; SER_BAUD_300
|
||||
.byte 9 ; SER_BAUD_600
|
||||
.byte 10 ; SER_BAUD_1200
|
||||
.byte 11 ; SER_BAUD_1800
|
||||
.byte 12 ; SER_BAUD_2400
|
||||
.byte 0 ; SER_BAUD_3600
|
||||
.byte 13 ; SER_BAUD_4800
|
||||
.byte 0 ; SER_BAUD_7200
|
||||
.byte 14 ; SER_BAUD_9600
|
||||
.byte 0 ; SER_BAUD_19200
|
||||
.byte 0 ; SER_BAUD_38400
|
||||
.byte 0 ; SER_BAUD_57600
|
||||
.byte 0 ; SER_BAUD_115200
|
||||
.byte 0 ; SER_BAUD_230400
|
||||
.byte 0 ; SER_BAUD_31250
|
||||
.byte 0 ; SER_BAUD_62500
|
||||
.byte 3 ; SER_BAUD_56_875
|
||||
num_bauds = * - bauds
|
||||
databits:
|
||||
.byte 48 ; SER_BITS_5
|
||||
.byte 32 ; SER_BITS_6
|
||||
.byte 16 ; SER_BITS_7
|
||||
.byte 0 ; SER_BITS_8
|
||||
num_databits = * - databits
|
||||
parities:
|
||||
.byte 0 ; SER_PAR_NONE
|
||||
.byte 4+1 ; SER_PAR_ODD
|
||||
.byte 2+8 ; SER_PAR_EVEN
|
||||
;.byte 0 ; SER_PAR_MARK
|
||||
;.byte 0 ; SER_PAR_SPACE
|
||||
num_parities = * - parities
|
||||
|
||||
.bss
|
||||
|
||||
; receive buffer
|
||||
RECVBUF_SZ = 256
|
||||
recv_buf: .res RECVBUF_SZ
|
||||
|
||||
cm_run: .res 1 ; concurrent mode running?
|
||||
|
||||
.data
|
||||
|
||||
rshand: .word $ffff
|
||||
|
||||
; jump table into main program, initialized from libref
|
||||
my_newfd:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my__close:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my_pushax:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my_popax:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my_findfreeiocb:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my___do_oserror:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my_fddecusage:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my_fdtoiocb:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my___inviocb:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my_clriocb:
|
||||
.byte $4C
|
||||
.word 0
|
||||
my_CIOV:
|
||||
.byte $4C
|
||||
.word 0
|
||||
|
||||
.code
|
||||
|
||||
invbaud:
|
||||
lda #<SER_ERR_BAUD_UNAVAIL
|
||||
ldx #>SER_ERR_BAUD_UNAVAIL
|
||||
openerr:
|
||||
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:
|
||||
jsr do_open
|
||||
bne openerr
|
||||
|
||||
; set line parameters
|
||||
lda rshand
|
||||
ldx #0
|
||||
jsr my_fdtoiocb ; get iocb index into X
|
||||
bmi openerr ; shouldn't happen
|
||||
tax
|
||||
|
||||
; set baud rate, word size, stop bits and ready monitoring
|
||||
|
||||
; build ICAX1 value
|
||||
ldy #SER_PARAMS::BAUDRATE
|
||||
lda (ptr1),y
|
||||
cmp #num_bauds
|
||||
bcs invbaud
|
||||
|
||||
tay
|
||||
lda bauds,y
|
||||
beq invbaud
|
||||
sta ICAX1,x
|
||||
|
||||
ldy #SER_PARAMS::DATABITS
|
||||
lda (ptr1),y
|
||||
cmp #num_databits
|
||||
bcs init_err
|
||||
|
||||
tay
|
||||
lda databits,y
|
||||
ora ICAX1,x
|
||||
sta ICAX1,x
|
||||
|
||||
ldy #SER_PARAMS::STOPBITS
|
||||
lda (ptr1),y
|
||||
clc
|
||||
ror a
|
||||
ror a
|
||||
ora ICAX1,x
|
||||
sta ICAX1,x
|
||||
|
||||
lda #36 ; xio 36, baud rate
|
||||
sta ICCOM,x
|
||||
lda #0
|
||||
;ICAX2 = 0, monitor nothing
|
||||
sta ICAX2,x
|
||||
sta ICBLL,x
|
||||
sta ICBLH,x
|
||||
sta ICBAL,x
|
||||
sta ICBAH,x
|
||||
jsr my_CIOV
|
||||
bmi cioerr
|
||||
|
||||
; check if the handshake setting is valid
|
||||
ldy #SER_PARAMS::HANDSHAKE
|
||||
lda (ptr1),y
|
||||
cmp #SER_HS_HW ; this is all we support
|
||||
bne init_err
|
||||
|
||||
; set handshake lines
|
||||
lda #34 ; xio 34, set cts, dtr etc
|
||||
sta ICCOM,x
|
||||
lda #192+48+3 ; DTR on, RTS on, XMT on
|
||||
sta ICAX1,x
|
||||
jsr my_CIOV
|
||||
bmi cioerr
|
||||
|
||||
; set translation and parity
|
||||
ldy #SER_PARAMS::PARITY
|
||||
lda (ptr1),y
|
||||
cmp #num_parities
|
||||
bcs init_err
|
||||
|
||||
tay
|
||||
lda parities,y
|
||||
ora #32 ; no translation
|
||||
sta ICAX1,x
|
||||
|
||||
lda #38 ; xio 38, translation and parity
|
||||
sta ICCOM,x
|
||||
jsr my_CIOV
|
||||
bmi cioerr
|
||||
|
||||
lda #<SER_ERR_OK
|
||||
tax ; A is zero
|
||||
rts
|
||||
|
||||
inverr: jmp my___inviocb
|
||||
|
||||
cioerr:
|
||||
; @@@ need to close IOCB here
|
||||
jsr my_fddecusage ; decrement usage counter of fd as open failed
|
||||
|
||||
init_err:
|
||||
ldx #0
|
||||
lda #SER_ERR_INIT_FAILED
|
||||
rts
|
||||
|
||||
;---- open the device
|
||||
|
||||
do_open:
|
||||
jsr my_findfreeiocb
|
||||
bne init_err
|
||||
txa
|
||||
tay ; move iocb # into Y
|
||||
lda #3
|
||||
sta tmp3 ; name length + 1
|
||||
lda #<rdev
|
||||
ldx #>rdev
|
||||
jsr my_newfd
|
||||
tya
|
||||
bcs @doopen ; C set: open needed / device not already open
|
||||
|
||||
pha
|
||||
jsr SER_CLOSE ;** shut down if started @@@TODO check this out!!
|
||||
pla
|
||||
|
||||
@doopen:tax
|
||||
pha
|
||||
jsr my_clriocb
|
||||
pla
|
||||
tax
|
||||
lda #<rdev
|
||||
sta ICBAL,x
|
||||
lda #>rdev
|
||||
sta ICBAH,x
|
||||
lda #OPEN
|
||||
sta ICCOM,x
|
||||
|
||||
lda #$0D ; mode in+out+concurrent
|
||||
sta ICAX1,x
|
||||
lda #0
|
||||
sta ICAX2,x
|
||||
sta ICBLL,x ; zap buf len
|
||||
sta ICBLH,x
|
||||
jsr my_CIOV
|
||||
bmi cioerr
|
||||
|
||||
lda tmp2 ; get fd (from newfd)
|
||||
sta rshand
|
||||
ldx #0
|
||||
stx rshand+1
|
||||
txa
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; CLOSE: Close the port, disable interrupts and flush the buffer. Called
|
||||
; without parameters. Must return an error code in a/x.
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_UNINSTALL routine. Is called before the driver is removed from memory.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
;
|
||||
|
||||
SER_UNINSTALL:
|
||||
SER_CLOSE:
|
||||
lda rshand
|
||||
cmp #$ff
|
||||
beq @done
|
||||
|
||||
ldx rshand+1
|
||||
jsr my__close
|
||||
ldx #$ff
|
||||
stx rshand
|
||||
stx rshand+1
|
||||
inx
|
||||
stx cm_run
|
||||
@done: lda #<SER_ERR_OK
|
||||
ldx #>SER_ERR_OK
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_GET: Will fetch a character from the receive buffer and store it into the
|
||||
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
|
||||
; return.
|
||||
;
|
||||
|
||||
SER_GET:
|
||||
ldy rshand
|
||||
cpy #$ff
|
||||
beq ni_err ; work only if initialized
|
||||
|
||||
lda rshand
|
||||
ldx #0
|
||||
jsr my_fdtoiocb
|
||||
tax
|
||||
lda cm_run ; concurrent mode already running?
|
||||
bne @go
|
||||
jsr ena_cm ; turn on concurrent mode
|
||||
|
||||
@go: ; check whether there is any input available
|
||||
|
||||
lda #STATIS ; status request, returns bytes pending
|
||||
sta ICCOM,x
|
||||
jsr my_CIOV
|
||||
bmi ser_error
|
||||
|
||||
lda DVSTAT+1 ; get byte count pending
|
||||
ora DVSTAT+2
|
||||
beq @nix_da ; no input waiting...
|
||||
|
||||
; input is available: get it!
|
||||
|
||||
lda #GETCHR ; get raw bytes
|
||||
sta ICCOM,x ; in command code
|
||||
lda #0
|
||||
sta ICBLL,x
|
||||
sta ICBLH,x
|
||||
sta ICBAL,x
|
||||
sta ICBAH,x
|
||||
jsr my_CIOV ; go get it
|
||||
bmi ser_error
|
||||
|
||||
ldx #0
|
||||
sta (ptr1,x) ; return received byte
|
||||
txa
|
||||
rts
|
||||
|
||||
@nix_da:lda #SER_ERR_NO_DATA
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
ser_error:
|
||||
lda #SER_ERR_OVERFLOW ; there is no large selection of serial error codes... :-/
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
ni_err: lda #SER_ERR_NOT_OPEN
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_PUT: Output character in A.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
SER_PUT:
|
||||
ldy rshand
|
||||
cpy #$ff
|
||||
beq ni_err ; work only if initialized
|
||||
|
||||
pha ; remember char to write
|
||||
lda rshand
|
||||
ldx #0
|
||||
jsr my_fdtoiocb
|
||||
tax
|
||||
|
||||
lda cm_run ; concurrent mode already running?
|
||||
bne @go
|
||||
jsr ena_cm ; turn on concurrent mode
|
||||
|
||||
; @@@TODO: check output buffer overflow
|
||||
@go: lda #PUTCHR ; put raw bytes
|
||||
sta ICCOM,x ; in command code
|
||||
lda #0
|
||||
sta ICBLL,x
|
||||
sta ICBLH,x
|
||||
sta ICBAL,x
|
||||
sta ICBAH,x
|
||||
pla ; get the char back
|
||||
jsr my_CIOV ; go do it
|
||||
bmi ser_error
|
||||
lda #0
|
||||
tax
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_STATUS: Return the status in the variable pointed to by ptr1.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
SER_STATUS:
|
||||
; fall through to SER_IOCTL
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
|
||||
; specific data in ptr1, and the ioctl code in A.
|
||||
; Must return an error code in a/x.
|
||||
;
|
||||
|
||||
SER_IOCTL:
|
||||
lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
|
||||
ldx #>SER_ERR_INV_IOCTL
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_IRQ: Not used on the Atari
|
||||
;
|
||||
|
||||
SER_IRQ = $0000
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_INSTALL routine. 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.
|
||||
|
||||
SER_INSTALL:
|
||||
; check if R: device is installed
|
||||
ldy #0
|
||||
search: lda HATABS,y ; get device name
|
||||
cmp #'R'
|
||||
beq found
|
||||
iny
|
||||
iny
|
||||
iny
|
||||
cpy #MAXDEV
|
||||
bcc search
|
||||
|
||||
; R: device not found, return error
|
||||
|
||||
lda #<SER_ERR_NO_DEVICE
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
; R: device found, initialize jump table into main program
|
||||
|
||||
found: lda ptr3
|
||||
pha
|
||||
lda ptr3+1
|
||||
pha
|
||||
lda libref
|
||||
sta ptr3
|
||||
lda libref+1
|
||||
sta ptr3+1
|
||||
|
||||
ldy #0
|
||||
lda (ptr3),y
|
||||
sta my_newfd+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_newfd+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my__close+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my__close+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my_pushax+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_pushax+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my_popax+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_popax+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my_findfreeiocb+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_findfreeiocb+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my___do_oserror+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my___do_oserror+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my_fddecusage+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_fddecusage+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my_fdtoiocb+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_fdtoiocb+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my___inviocb+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my___inviocb+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my_clriocb+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_clriocb+2
|
||||
iny
|
||||
|
||||
lda (ptr3),y
|
||||
sta my_CIOV+1
|
||||
iny
|
||||
lda (ptr3),y
|
||||
sta my_CIOV+2
|
||||
;iny
|
||||
|
||||
pla
|
||||
sta ptr3+1
|
||||
pla
|
||||
sta ptr3
|
||||
|
||||
lda #<SER_ERR_OK
|
||||
tax ; A is zero
|
||||
rts
|
||||
|
||||
|
||||
; enable concurrent rs232 mode
|
||||
; gets iocb index in X
|
||||
; all registers destroyed
|
||||
|
||||
.proc ena_cm
|
||||
|
||||
lda #40 ; XIO 40, start concurrent IO
|
||||
sta ICCOM,x
|
||||
sta cm_run ; indicate concurrent mode is running
|
||||
lda #$0D ; value from 850 manual, p62. must be $0D?,
|
||||
sta ICAX1,x ; or any non-zero?
|
||||
lda #0
|
||||
sta ICAX2,x
|
||||
lda #<recv_buf
|
||||
sta ICBAL,x
|
||||
lda #>recv_buf
|
||||
sta ICBAH,x
|
||||
lda #<RECVBUF_SZ
|
||||
sta ICBLL,x
|
||||
lda #>RECVBUF_SZ
|
||||
sta ICBLH,x
|
||||
jmp my_CIOV
|
||||
|
||||
.endproc ;ena_cm
|
||||
33
libsrc/atari/serref.s
Normal file
33
libsrc/atari/serref.s
Normal file
@@ -0,0 +1,33 @@
|
||||
;
|
||||
; Christian Groessler, 2014-04-22
|
||||
;
|
||||
|
||||
.include "atari.inc"
|
||||
|
||||
.export ser_libref
|
||||
|
||||
.import _close, pushax, popax
|
||||
.import findfreeiocb
|
||||
.import __do_oserror
|
||||
.import fddecusage
|
||||
.import fdtoiocb
|
||||
.import __inviocb
|
||||
.import clriocb
|
||||
.import newfd
|
||||
|
||||
ser_libref := atari_ser_libref
|
||||
|
||||
.rodata
|
||||
|
||||
atari_ser_libref:
|
||||
.word newfd
|
||||
.word _close
|
||||
.word pushax
|
||||
.word popax
|
||||
.word findfreeiocb
|
||||
.word __do_oserror
|
||||
.word fddecusage
|
||||
.word fdtoiocb
|
||||
.word __inviocb
|
||||
.word clriocb
|
||||
.word CIOV
|
||||
81
libsrc/atari/shadow_ram_timerirq1.s
Normal file
81
libsrc/atari/shadow_ram_timerirq1.s
Normal file
@@ -0,0 +1,81 @@
|
||||
;
|
||||
; Atari XL shadow RAM timer IRQ #1 handler
|
||||
;
|
||||
; Christian Groessler, chris@groessler.org, 2014
|
||||
;
|
||||
|
||||
;DEBUG = 1
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
|
||||
SHRAM_HANDLERS = 1
|
||||
.include "atari.inc"
|
||||
.include "romswitch.inc"
|
||||
.export set_VTIMR1_handler
|
||||
|
||||
|
||||
.segment "LOWBSS"
|
||||
|
||||
VTIMR1_handler: .res 3
|
||||
|
||||
|
||||
.segment "BSS"
|
||||
|
||||
old_VTIMR1_handler:
|
||||
.res 2
|
||||
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
; timer interrupt handler:
|
||||
; disable ROM, call user handler, enable ROM again
|
||||
|
||||
my_VTIMR1_handler:
|
||||
disable_rom_quick
|
||||
jsr VTIMR1_handler
|
||||
enable_rom_quick
|
||||
pla
|
||||
rti
|
||||
|
||||
.segment "CODE"
|
||||
|
||||
; install or remove VTIMR1 handler
|
||||
; input: CF - 0/1 for remove/install handler
|
||||
; AX - pointer to handler (if CF=1)
|
||||
; registers destroyed
|
||||
|
||||
set_VTIMR1_handler:
|
||||
|
||||
bcc @remove
|
||||
|
||||
; install vector
|
||||
|
||||
stx VTIMR1_handler+2
|
||||
sta VTIMR1_handler+1 ; save passed vector in low memory
|
||||
lda #$4C ; "JMP" opcode
|
||||
sta VTIMR1_handler
|
||||
|
||||
lda VTIMR1
|
||||
sta old_VTIMR1_handler
|
||||
lda VTIMR1+1
|
||||
sta old_VTIMR1_handler+1
|
||||
|
||||
lda #<my_VTIMR1_handler
|
||||
php
|
||||
sei
|
||||
sta VTIMR1
|
||||
lda #>my_VTIMR1_handler
|
||||
sta VTIMR1+1
|
||||
plp
|
||||
rts
|
||||
|
||||
@remove: php
|
||||
sei
|
||||
lda old_VTIMR1_handler
|
||||
sta VTIMR1
|
||||
lda old_VTIMR1_handler+1
|
||||
sta VTIMR1+1
|
||||
plp
|
||||
rts
|
||||
|
||||
.endif ; .ifdef __ATARIXL__
|
||||
@@ -45,13 +45,7 @@ iocbok: stx tmp4 ; remember IOCB index
|
||||
ldy #0
|
||||
sty sspc+1 ; initialize stack space
|
||||
|
||||
.ifndef UCASE_FILENAME
|
||||
|
||||
sta ptr3
|
||||
stx ptr3+1
|
||||
sty sspc
|
||||
|
||||
.else
|
||||
.ifdef UCASE_FILENAME
|
||||
|
||||
; uppercase first (old) name and prepend device if needed
|
||||
|
||||
@@ -100,6 +94,12 @@ ucok2: sta ptr2 ; remember pointer to uppercased new name
|
||||
inc sspc+1
|
||||
ukok4:
|
||||
|
||||
.else
|
||||
|
||||
sta ptr3
|
||||
stx ptr3+1
|
||||
sty sspc
|
||||
|
||||
.endif
|
||||
|
||||
; create a string on the stack with the old filename and the new filename separated by an invalid character (space in our case)
|
||||
|
||||
@@ -194,7 +194,7 @@ delay1: ldx #0
|
||||
end:
|
||||
|
||||
.ifndef __ATARIXL__
|
||||
tmp: ; outside of the load chunk, some kind of poor man's .bss
|
||||
tmp: ; outside of the load chunk, some kind of poor man's .bss
|
||||
.endif
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
;
|
||||
; time_t _systime (void);
|
||||
; /* Similar to time(), but:
|
||||
; * - Is not ISO C
|
||||
; * - Does not take the additional pointer
|
||||
; * - Does not set errno when returning -1
|
||||
; */
|
||||
; ** - Is not ISO C
|
||||
; ** - Does not take the additional pointer
|
||||
; ** - Does not set errno when returning -1
|
||||
; */
|
||||
;
|
||||
|
||||
.export __systime
|
||||
|
||||
9
libsrc/atari/targetutil/Makefile.inc
Normal file
9
libsrc/atari/targetutil/Makefile.inc
Normal file
@@ -0,0 +1,9 @@
|
||||
DEPS += ../libwrk/$(TARGET)/w2cas.d
|
||||
|
||||
../libwrk/$(TARGET)/w2cas.o: $(SRCDIR)/targetutil/w2cas.c | ../libwrk/$(TARGET)
|
||||
$(COMPILE_recipe)
|
||||
|
||||
../targetutil/w2cas.com: ../libwrk/$(TARGET)/w2cas.o ../lib/$(TARGET).lib | ../targetutil
|
||||
$(LD65) -o $@ -t $(TARGET) $^
|
||||
|
||||
$(TARGET): ../targetutil/w2cas.com
|
||||
186
libsrc/atari/targetutil/w2cas.c
Normal file
186
libsrc/atari/targetutil/w2cas.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/* w2cas.c -- write file to cassette
|
||||
**
|
||||
** This program writes a boot file (typically linked with
|
||||
** 'atari-cassette.cfg') to the cassette.
|
||||
** Only files < 32K are supported, since the loading of
|
||||
** larger files requires a special loader inside the program.
|
||||
**
|
||||
** Christian Groessler, chris@groessler.org, 2014
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <6502.h>
|
||||
#include <atari.h>
|
||||
#include <conio.h>
|
||||
|
||||
static int verbose = 1;
|
||||
static char C_dev[] = "C:";
|
||||
|
||||
static struct __iocb *findfreeiocb(void)
|
||||
{
|
||||
struct __iocb *iocb = &IOCB; /* first IOCB (#0) */
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (iocb->handler == 0xff)
|
||||
return iocb;
|
||||
iocb++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *filename, *x;
|
||||
char buf[20];
|
||||
FILE *file;
|
||||
unsigned char *buffer;
|
||||
size_t filen, buflen = 32768l + 1;
|
||||
struct regs regs;
|
||||
struct __iocb *iocb = findfreeiocb();
|
||||
int iocb_num;
|
||||
|
||||
if (! iocb) {
|
||||
fprintf(stderr, "couldn't find a free iocb\n");
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 1;
|
||||
}
|
||||
iocb_num = (iocb - &IOCB) * 16;
|
||||
if (verbose)
|
||||
printf("using iocb index $%02X ($%04X)\n", iocb_num, iocb);
|
||||
|
||||
if (argc < 2) {
|
||||
printf("\nfilename: ");
|
||||
x = fgets(buf, 19, stdin);
|
||||
printf("\n");
|
||||
if (! x)
|
||||
return 1;
|
||||
if (*x && *(x + strlen(x) - 1) == '\n')
|
||||
*(x + strlen(x) - 1) = 0;
|
||||
filename = x;
|
||||
}
|
||||
else {
|
||||
filename = *(argv+1);
|
||||
}
|
||||
|
||||
/* allocate buffer */
|
||||
buffer = malloc(buflen);
|
||||
if (! buffer) {
|
||||
buflen = _heapmaxavail(); /* get as much as we can */
|
||||
buffer = malloc(buflen);
|
||||
if (! buffer) {
|
||||
fprintf(stderr, "cannot alloc %ld bytes -- aborting...\n", (long)buflen);
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (verbose)
|
||||
printf("buffer size: %ld bytes\n", (long)buflen);
|
||||
|
||||
/* open file */
|
||||
file = fopen(filename, "rb");
|
||||
if (! file) {
|
||||
free(buffer);
|
||||
fprintf(stderr, "cannot open '%s': %s\n", filename, strerror(errno));
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* read file -- file length must be < 32K */
|
||||
if (verbose)
|
||||
printf("reading input file...\n");
|
||||
filen = fread(buffer, 1, buflen, file);
|
||||
if (! filen) {
|
||||
fprintf(stderr, "read error\n");
|
||||
file_err:
|
||||
fclose(file);
|
||||
free(buffer);
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 1;
|
||||
}
|
||||
if (filen > 32767l) {
|
||||
fprintf(stderr, "file is too large (must be < 32768)\n");
|
||||
goto file_err;
|
||||
}
|
||||
if (filen == buflen) { /* we have a buffer < 32768 and the file fits into it (and is most probably larger) */
|
||||
fprintf(stderr, "not enough memory\n");
|
||||
goto file_err;
|
||||
}
|
||||
if (verbose)
|
||||
printf("file size: %ld bytes\n", (long)filen);
|
||||
|
||||
/* close input file */
|
||||
fclose(file);
|
||||
|
||||
/* open cassette */
|
||||
if (verbose)
|
||||
printf("opening cassette...\n");
|
||||
iocb->buffer = C_dev;
|
||||
iocb->aux1 = 8; /* open for output */
|
||||
iocb->aux2 = 128; /* short breaks and no stop between data blocks */
|
||||
iocb->command = IOCB_OPEN;
|
||||
regs.x = iocb_num;
|
||||
regs.pc = 0xe456; /* CIOV */
|
||||
|
||||
_sys(®s);
|
||||
if (regs.y != 1) {
|
||||
fprintf(stderr, "CIO call to open cassette returned %d\n", regs.y);
|
||||
free(buffer);
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* write file */
|
||||
if (verbose)
|
||||
printf("writing to cassette...\n");
|
||||
iocb->buffer = buffer;
|
||||
iocb->buflen = filen;
|
||||
iocb->command = IOCB_PUTCHR;
|
||||
regs.x = iocb_num;
|
||||
regs.pc = 0xe456; /* CIOV */
|
||||
|
||||
_sys(®s);
|
||||
if (regs.y != 1) {
|
||||
fprintf(stderr, "CIO call to write file returned %d\n", regs.y);
|
||||
free(buffer);
|
||||
|
||||
iocb->command = IOCB_CLOSE;
|
||||
regs.x = iocb_num;
|
||||
regs.pc = 0xe456; /* CIOV */
|
||||
_sys(®s);
|
||||
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* free buffer */
|
||||
free(buffer);
|
||||
|
||||
/* close cassette */
|
||||
iocb->command = IOCB_CLOSE;
|
||||
regs.x = iocb_num;
|
||||
regs.pc = 0xe456; /* CIOV */
|
||||
_sys(®s);
|
||||
|
||||
if (regs.y != 1) {
|
||||
fprintf(stderr, "CIO call to close cassette returned %d\n", regs.y);
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* all is fine */
|
||||
printf("success\n");
|
||||
if (_dos_type != 1)
|
||||
cgetc();
|
||||
return 0;
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
;
|
||||
|
||||
.macpack longbranch
|
||||
.macpack module
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
CIO_vec := my_CIOV
|
||||
@@ -18,7 +19,19 @@
|
||||
;
|
||||
; ----------------------------------------------------------------------
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
.ifdef __ATARIXL__
|
||||
.define LABEL_X "x"
|
||||
.else
|
||||
.define LABEL_X ""
|
||||
.endif
|
||||
|
||||
.if pages = 2
|
||||
.define LABEL_P2 "p2"
|
||||
.else
|
||||
.define LABEL_P2 ""
|
||||
.endif
|
||||
|
||||
module_header .ident (.sprintf ("_atr%s%d%s_tgi", LABEL_X, ::grmode, LABEL_P2))
|
||||
|
||||
; Header
|
||||
|
||||
|
||||
@@ -7,8 +7,16 @@
|
||||
;
|
||||
|
||||
.export _tgi_static_stddrv
|
||||
.ifdef __ATARIXL__
|
||||
.import _atrx8_tgi
|
||||
.else
|
||||
.import _atr8_tgi
|
||||
.endif
|
||||
|
||||
.rodata
|
||||
|
||||
.ifdef __ATARIXL__
|
||||
_tgi_static_stddrv := _atrx8_tgi
|
||||
.else
|
||||
_tgi_static_stddrv := _atr8_tgi
|
||||
.endif
|
||||
|
||||
@@ -10,4 +10,9 @@
|
||||
|
||||
.rodata
|
||||
|
||||
_tgi_stddrv: .asciiz "atr8.tgi"
|
||||
_tgi_stddrv:
|
||||
.ifdef __ATARIXL__
|
||||
.asciiz "atrx8.tgi"
|
||||
.else
|
||||
.asciiz "atr8.tgi"
|
||||
.endif
|
||||
|
||||
13
libsrc/atari5200/cartentry.s
Normal file
13
libsrc/atari5200/cartentry.s
Normal file
@@ -0,0 +1,13 @@
|
||||
; Cartridge entry point
|
||||
;
|
||||
; Christian Groessler, 01-Mar-2014
|
||||
|
||||
.export __CART_ENTRY__: absolute = 1
|
||||
.import __CARTSIZE__, start
|
||||
.forceimport __CART_YEAR__, __CART_NAME__
|
||||
|
||||
.segment "CARTENTRY"
|
||||
|
||||
.word start ; entry point
|
||||
|
||||
.assert (__CARTSIZE__ = $4000 || __CARTSIZE__ = $8000), error, "Cartridge size must either be $4000 or $8000"
|
||||
13
libsrc/atari5200/cartname.s
Normal file
13
libsrc/atari5200/cartname.s
Normal file
@@ -0,0 +1,13 @@
|
||||
; default cartridge name
|
||||
;
|
||||
; Christian Groessler, 01-Mar-2014
|
||||
|
||||
.include "atari.mac"
|
||||
|
||||
.export __CART_NAME__: absolute = 1
|
||||
|
||||
.segment "CARTNAME"
|
||||
|
||||
scrcode " cc"
|
||||
.byte '6' + 32, '5' + 32 ; use playfield 1
|
||||
scrcode " compiled"
|
||||
9
libsrc/atari5200/cartyear.s
Normal file
9
libsrc/atari5200/cartyear.s
Normal file
@@ -0,0 +1,9 @@
|
||||
; Cartridge copyright year
|
||||
;
|
||||
; Christian Groessler, 01-Mar-2014
|
||||
|
||||
.export __CART_YEAR__: absolute = 1
|
||||
|
||||
.segment "CARTYEAR"
|
||||
|
||||
.byte '9' + 32,'8' + 32 ; "98", but using playfield 1
|
||||
1
libsrc/atari5200/cclear.s
Normal file
1
libsrc/atari5200/cclear.s
Normal file
@@ -0,0 +1 @@
|
||||
.include "../atari/cclear.s"
|
||||
1
libsrc/atari5200/chline.s
Normal file
1
libsrc/atari5200/chline.s
Normal file
@@ -0,0 +1 @@
|
||||
.include "../atari/chline.s"
|
||||
26
libsrc/atari5200/clock.s
Normal file
26
libsrc/atari5200/clock.s
Normal file
@@ -0,0 +1,26 @@
|
||||
;
|
||||
; from Atari computer version by Christian Groessler, 2014
|
||||
;
|
||||
; clock_t clock (void);
|
||||
; unsigned _clocks_per_sec (void);
|
||||
;
|
||||
|
||||
.export _clock
|
||||
.importzp sreg
|
||||
|
||||
.include "atari5200.inc"
|
||||
|
||||
|
||||
.proc _clock
|
||||
|
||||
ldx #5 ; Synchronize with Antic, so the interrupt won't change RTCLOK
|
||||
stx WSYNC ; while we're reading it. The synchronization is done same as
|
||||
@L1: dex ; in SETVBLV function in Atari OS.
|
||||
bne @L1
|
||||
stx sreg+1 ; Byte 3 is always zero
|
||||
stx sreg ; Byte 2 is always zero, too
|
||||
lda RTCLOK+1
|
||||
ldx RTCLOK
|
||||
rts
|
||||
|
||||
.endproc
|
||||
34
libsrc/atari5200/clrscr.s
Normal file
34
libsrc/atari5200/clrscr.s
Normal file
@@ -0,0 +1,34 @@
|
||||
;
|
||||
; Christian Groessler, May-2014
|
||||
;
|
||||
; void clrscr (void);
|
||||
;
|
||||
|
||||
.export _clrscr
|
||||
.include "atari5200.inc"
|
||||
.importzp ptr1
|
||||
|
||||
SCRSIZE = 480 ; 20x24: size of default conio atari5200 screen
|
||||
|
||||
_clrscr:lda SAVMSC ; screen memory
|
||||
sta ptr1
|
||||
lda SAVMSC+1
|
||||
clc
|
||||
adc #>(SCRSIZE-1)
|
||||
sta ptr1+1
|
||||
lda #0 ; screen code of space char
|
||||
ldy #<(SCRSIZE-1)
|
||||
ldx #>(SCRSIZE-1)
|
||||
_clr1: sta (ptr1),y
|
||||
dey
|
||||
bne _clr1
|
||||
sta (ptr1),y
|
||||
dex
|
||||
bmi done
|
||||
dec ptr1+1
|
||||
dey
|
||||
jmp _clr1
|
||||
|
||||
done: sta COLCRS_5200
|
||||
sta ROWCRS_5200
|
||||
rts
|
||||
83
libsrc/atari5200/conioscreen.s
Normal file
83
libsrc/atari5200/conioscreen.s
Normal file
@@ -0,0 +1,83 @@
|
||||
; setup default CONIO screen (20x24, Antic mode 6, BASIC mode 1)
|
||||
;
|
||||
; 28-May-2014, Christian Groessler <chris@groessler.org>
|
||||
|
||||
.include "atari5200.inc"
|
||||
|
||||
SCREEN_BUF_SIZE = 20 * 24
|
||||
SCREEN_BUF = $4000 - SCREEN_BUF_SIZE
|
||||
|
||||
.code
|
||||
.export screen_setup_20x24
|
||||
|
||||
screen_setup_20x24:
|
||||
|
||||
; initialize SAVMSC
|
||||
lda #<SCREEN_BUF
|
||||
sta SAVMSC
|
||||
lda #>SCREEN_BUF
|
||||
sta SAVMSC+1
|
||||
|
||||
; initialize cursor position
|
||||
lda #0
|
||||
sta COLCRS_5200
|
||||
sta ROWCRS_5200
|
||||
|
||||
; clear screen buffer
|
||||
ldy #<(SCREEN_BUF_SIZE-1)
|
||||
ldx #>(SCREEN_BUF_SIZE-1)
|
||||
clrscr: sta (SAVMSC),y
|
||||
dey
|
||||
cpy #$FF
|
||||
bne clrscr
|
||||
dex
|
||||
cpx #$FF
|
||||
bne clrscr
|
||||
|
||||
; set default colors
|
||||
|
||||
lda #40
|
||||
sta COLOR0
|
||||
lda #202
|
||||
sta COLOR1
|
||||
lda #148
|
||||
sta COLOR2
|
||||
lda #70
|
||||
sta COLOR3
|
||||
lda #0
|
||||
sta COLOR4
|
||||
|
||||
; set display list
|
||||
|
||||
lda #<dlist
|
||||
sta SDLSTL
|
||||
lda #>dlist
|
||||
sta SDLSTH
|
||||
|
||||
rts
|
||||
|
||||
|
||||
.segment "RODATA"
|
||||
|
||||
; display list for 20x24 text mode
|
||||
|
||||
dlist: .repeat 3
|
||||
.byte DL_BLK8
|
||||
.endrepeat
|
||||
|
||||
.byte DL_CHR20x8x2 | DL_LMS
|
||||
.word SCREEN_BUF
|
||||
|
||||
.repeat 23
|
||||
.byte DL_CHR20x8x2
|
||||
.endrepeat
|
||||
|
||||
.byte DL_JVB
|
||||
.word dlist
|
||||
|
||||
; end of display list
|
||||
|
||||
.assert ((* >> 10) = (dlist >> 10)), error, "Display list crosses 1K boundary"
|
||||
|
||||
|
||||
.end
|
||||
94
libsrc/atari5200/cputc.s
Normal file
94
libsrc/atari5200/cputc.s
Normal file
@@ -0,0 +1,94 @@
|
||||
;
|
||||
; adapted from Atari version
|
||||
; Christian Groessler, 2014
|
||||
;
|
||||
; void cputcxy (unsigned char x, unsigned char y, char c);
|
||||
; void cputc (char c);
|
||||
;
|
||||
|
||||
.include "atari5200.inc"
|
||||
|
||||
.export _cputcxy, _cputc
|
||||
.export plot, cputdirect, putchar
|
||||
.import popa, _gotoxy, mul20
|
||||
.importzp ptr4
|
||||
.import setcursor
|
||||
|
||||
.constructor screen_setup, 26
|
||||
.import screen_setup_20x24
|
||||
screen_setup = screen_setup_20x24
|
||||
|
||||
|
||||
_cputcxy:
|
||||
pha ; Save C
|
||||
jsr popa ; Get Y
|
||||
jsr _gotoxy ; Set cursor, drop x
|
||||
pla ; Restore C
|
||||
|
||||
_cputc:
|
||||
cmp #$0D ; CR
|
||||
bne L4
|
||||
lda #0
|
||||
sta COLCRS_5200
|
||||
beq plot ; return
|
||||
|
||||
L4: cmp #$0A ; LF
|
||||
beq newline
|
||||
cmp #ATEOL ; Atari-EOL?
|
||||
beq newline
|
||||
|
||||
tay
|
||||
rol a
|
||||
rol a
|
||||
rol a
|
||||
rol a
|
||||
and #3
|
||||
tax
|
||||
tya
|
||||
and #$9f
|
||||
ora ataint,x
|
||||
|
||||
cputdirect: ; accepts screen code
|
||||
jsr putchar
|
||||
|
||||
; advance cursor
|
||||
inc COLCRS_5200
|
||||
lda COLCRS_5200
|
||||
cmp #20
|
||||
bcc plot
|
||||
lda #0
|
||||
sta COLCRS_5200
|
||||
|
||||
.export newline
|
||||
newline:
|
||||
inc ROWCRS_5200
|
||||
lda ROWCRS_5200
|
||||
cmp #24
|
||||
bne plot
|
||||
lda #0
|
||||
sta ROWCRS_5200
|
||||
plot: jsr setcursor
|
||||
ldy COLCRS_5200
|
||||
ldx ROWCRS_5200
|
||||
rts
|
||||
|
||||
putchar:
|
||||
pha ; save char
|
||||
|
||||
lda ROWCRS_5200
|
||||
jsr mul20 ; destroys tmp4
|
||||
clc
|
||||
adc SAVMSC ; add start of screen memory
|
||||
sta ptr4
|
||||
txa
|
||||
adc SAVMSC+1
|
||||
sta ptr4+1
|
||||
pla ; get char again
|
||||
|
||||
ldy COLCRS_5200
|
||||
sta (ptr4),y
|
||||
jmp setcursor
|
||||
|
||||
.rodata
|
||||
ataint: .byte 64,0,32,96
|
||||
|
||||
48
libsrc/atari5200/crt0.s
Normal file
48
libsrc/atari5200/crt0.s
Normal file
@@ -0,0 +1,48 @@
|
||||
;
|
||||
; Startup code for cc65 (Atari5200 version)
|
||||
;
|
||||
; Christian Groessler (chris@groessler.org), 2014
|
||||
;
|
||||
|
||||
.export _exit, start
|
||||
.export __STARTUP__ : absolute = 1 ; Mark as startup
|
||||
.import __RAM_START__, __RAM_SIZE__
|
||||
.import __RESERVED_MEMORY__
|
||||
|
||||
.import initlib, donelib, callmain
|
||||
.import zerobss, copydata
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "atari5200.inc"
|
||||
|
||||
start:
|
||||
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Initialize the data.
|
||||
jsr copydata
|
||||
|
||||
; Set up the stack.
|
||||
|
||||
lda #<(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__)
|
||||
sta sp
|
||||
lda #>(__RAM_START__ + __RAM_SIZE__ - __RESERVED_MEMORY__)
|
||||
sta sp+1 ; Set argument stack ptr
|
||||
|
||||
; Call the module constructors.
|
||||
|
||||
jsr initlib
|
||||
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Call the module destructors. This is also the exit() entry.
|
||||
|
||||
_exit: jsr donelib ; Run module destructors
|
||||
|
||||
; A 5200 program isn't supposed to exit.
|
||||
|
||||
halt: jmp halt
|
||||
5
libsrc/atari5200/ctype.s
Normal file
5
libsrc/atari5200/ctype.s
Normal file
@@ -0,0 +1,5 @@
|
||||
; Character specification table.
|
||||
;
|
||||
; same as for "atari" target
|
||||
|
||||
.include "../atari/ctype.s"
|
||||
1
libsrc/atari5200/cvline.s
Normal file
1
libsrc/atari5200/cvline.s
Normal file
@@ -0,0 +1 @@
|
||||
.include "../atari/cvline.s"
|
||||
20
libsrc/atari5200/get_tv.s
Normal file
20
libsrc/atari5200/get_tv.s
Normal file
@@ -0,0 +1,20 @@
|
||||
;
|
||||
; Christian Groessler, 2014
|
||||
;
|
||||
; unsigned char get_tv (void);
|
||||
; /* Return the video mode the machine is using */
|
||||
;
|
||||
|
||||
.include "get_tv.inc"
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
; _get_tv
|
||||
|
||||
.proc _get_tv
|
||||
|
||||
lda #<TV::NTSC
|
||||
ldx #>TV::NTSC
|
||||
rts
|
||||
|
||||
.endproc
|
||||
13
libsrc/atari5200/gotox.s
Normal file
13
libsrc/atari5200/gotox.s
Normal file
@@ -0,0 +1,13 @@
|
||||
;
|
||||
; Christian Groessler, 13-Mar-2014
|
||||
;
|
||||
; void gotox (unsigned char x);
|
||||
;
|
||||
|
||||
.include "atari5200.inc"
|
||||
.export _gotox
|
||||
.import setcursor
|
||||
|
||||
_gotox:
|
||||
sta COLCRS_5200 ; Set X
|
||||
jmp setcursor
|
||||
17
libsrc/atari5200/gotoxy.s
Normal file
17
libsrc/atari5200/gotoxy.s
Normal file
@@ -0,0 +1,17 @@
|
||||
;
|
||||
; Christian Groessler, 13-Mar-2014
|
||||
;
|
||||
; void gotoxy (unsigned char x, unsigned char y);
|
||||
;
|
||||
|
||||
.include "atari5200.inc"
|
||||
|
||||
.export _gotoxy
|
||||
.import popa
|
||||
.import setcursor
|
||||
|
||||
_gotoxy: ; Set the cursor position
|
||||
sta ROWCRS_5200 ; Set Y
|
||||
jsr popa ; Get X
|
||||
sta COLCRS_5200 ; Set X
|
||||
jmp setcursor
|
||||
13
libsrc/atari5200/gotoy.s
Normal file
13
libsrc/atari5200/gotoy.s
Normal file
@@ -0,0 +1,13 @@
|
||||
;
|
||||
; Christian Groessler, 13-Mar-2014
|
||||
;
|
||||
; void gotoy (unsigned char y);
|
||||
;
|
||||
|
||||
.include "atari5200.inc"
|
||||
.export _gotoy
|
||||
.import setcursor
|
||||
|
||||
_gotoy:
|
||||
sta ROWCRS_5200 ; Set Y
|
||||
jmp setcursor
|
||||
59
libsrc/atari5200/irq.s
Normal file
59
libsrc/atari5200/irq.s
Normal file
@@ -0,0 +1,59 @@
|
||||
;
|
||||
; IRQ handling (ATARI 5200 version)
|
||||
;
|
||||
|
||||
.export initirq, doneirq
|
||||
.import callirq
|
||||
|
||||
.include "atari5200.inc"
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
initirq:
|
||||
lda VVBLKD
|
||||
ldx VVBLKD+1
|
||||
sta IRQInd+1
|
||||
stx IRQInd+2
|
||||
ldy #<IRQStub
|
||||
ldx #>IRQStub
|
||||
jmp SETVBV
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
doneirq:
|
||||
ldy IRQInd+1
|
||||
ldx IRQInd+2
|
||||
;jmp SETVBV
|
||||
; fall thru
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Set deferred vertical blank interrupt
|
||||
; logic copied from Atari computer ROM
|
||||
|
||||
SETVBV: txa
|
||||
ldx #5
|
||||
sta WSYNC ; waste 20 CPU cycles
|
||||
@1: dex ; to allow VBLANK to happen
|
||||
bne @1 ; if this is line "7C"
|
||||
sta VVBLKD+1
|
||||
sty VVBLKD
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
IRQStub:
|
||||
cld ; Just to be sure
|
||||
jsr callirq ; Call the functions
|
||||
jmp IRQInd ; Jump to the saved IRQ vector
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
.data
|
||||
|
||||
IRQInd: jmp $0000
|
||||
132
libsrc/atari5200/joy/atr5200std.s
Normal file
132
libsrc/atari5200/joy/atr5200std.s
Normal file
@@ -0,0 +1,132 @@
|
||||
;
|
||||
; Standard joystick driver for the Atari 5200.
|
||||
;
|
||||
; Christian Groessler, 2014-05-28
|
||||
;
|
||||
|
||||
.include "zeropage.inc"
|
||||
|
||||
.include "joy-kernel.inc"
|
||||
.include "joy-error.inc"
|
||||
.include "atari5200.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
module_header _atr5200std_joy
|
||||
|
||||
; Driver signature
|
||||
|
||||
.byte $6A, $6F, $79 ; "joy"
|
||||
.byte JOY_API_VERSION ; Driver API version number
|
||||
|
||||
; Library reference
|
||||
|
||||
.addr $0000
|
||||
|
||||
; Button state masks (8 values)
|
||||
|
||||
.byte $01 ; JOY_UP
|
||||
.byte $02 ; JOY_DOWN
|
||||
.byte $04 ; JOY_LEFT
|
||||
.byte $08 ; JOY_RIGHT
|
||||
.byte $10 ; JOY_FIRE
|
||||
.byte $20 ; JOY_FIRE2
|
||||
.byte $00 ; Future expansion
|
||||
.byte $00 ; Future expansion
|
||||
|
||||
; Jump table.
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr COUNT
|
||||
.addr READJOY
|
||||
.addr 0 ; IRQ entry not used
|
||||
|
||||
.code
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; 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 #0
|
||||
; rts ; Run into UNINSTALL instead
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory.
|
||||
; Can do cleanup or whatever. Must not return anything.
|
||||
;
|
||||
|
||||
UNINSTALL:
|
||||
rts
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; COUNT: Return the total number of available joysticks in a/x.
|
||||
;
|
||||
|
||||
COUNT:
|
||||
lda $FD32 ; check ROM version
|
||||
cmp #$E8
|
||||
bne @2port
|
||||
lda #4
|
||||
.byte $2C ; bit opcode, eats the next 2 bytes
|
||||
@2port: lda #2
|
||||
ldx #0
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; READ: Read a particular joystick passed in A.
|
||||
;
|
||||
|
||||
CENTER = 228 / 2
|
||||
SENSIVITY = 16
|
||||
|
||||
READJOY:
|
||||
and #3 ; put joystick number in range, just in case
|
||||
tay
|
||||
asl a
|
||||
tax ; Joystick number * 2 (0-6) into X, index into ZP shadow registers
|
||||
|
||||
lda #0 ; Initialize return value
|
||||
cmp TRIG0,y
|
||||
bne @notrg
|
||||
lda #$10 ; JOY_FIRE
|
||||
|
||||
; Read joystick
|
||||
|
||||
@notrg: ldy PADDL0,x ; get horizontal position
|
||||
cpy #CENTER-SENSIVITY
|
||||
bcs @chkleft
|
||||
|
||||
ora #4 ; JOY_LEFT
|
||||
bne @updown
|
||||
|
||||
@chkleft:
|
||||
cpy #CENTER+SENSIVITY
|
||||
bcc @updown
|
||||
|
||||
ora #8 ; JOY_RIGHT
|
||||
|
||||
@updown:ldy PADDL0+1,x ; get vertical position
|
||||
cpy #CENTER-SENSIVITY
|
||||
bcs @chkdown
|
||||
|
||||
ora #1 ; JOY_UP
|
||||
bne @done
|
||||
|
||||
@chkdown:
|
||||
cpy #CENTER+SENSIVITY
|
||||
bcc @done
|
||||
|
||||
ora #2 ; JOY_DOWN
|
||||
|
||||
@done: rts
|
||||
12
libsrc/atari5200/joy_stat_stddrv.s
Normal file
12
libsrc/atari5200/joy_stat_stddrv.s
Normal file
@@ -0,0 +1,12 @@
|
||||
;
|
||||
; Address of the static standard joystick driver
|
||||
;
|
||||
; Christian Groessler, 2014-05-12
|
||||
;
|
||||
; const void joy_static_stddrv[];
|
||||
;
|
||||
|
||||
.export _joy_static_stddrv
|
||||
.import _atr5200std_joy
|
||||
|
||||
_joy_static_stddrv := _atr5200std_joy
|
||||
8
libsrc/atari5200/libref.s
Normal file
8
libsrc/atari5200/libref.s
Normal file
@@ -0,0 +1,8 @@
|
||||
;
|
||||
; Christian Groessler, 2014-05-12
|
||||
;
|
||||
|
||||
.export joy_libref
|
||||
.import _exit
|
||||
|
||||
joy_libref := _exit
|
||||
33
libsrc/atari5200/mul20.s
Normal file
33
libsrc/atari5200/mul20.s
Normal file
@@ -0,0 +1,33 @@
|
||||
;
|
||||
; Christian Groessler, April 2014
|
||||
;
|
||||
; mul20
|
||||
; multiplies A by 20 and returns result in AX
|
||||
; uses tmp4
|
||||
|
||||
.importzp tmp4
|
||||
.export mul20,loc_tmp
|
||||
|
||||
.proc mul20
|
||||
|
||||
ldx #0
|
||||
stx tmp4
|
||||
sta loc_tmp
|
||||
asl a
|
||||
rol tmp4
|
||||
asl a
|
||||
rol tmp4 ; val * 4
|
||||
adc loc_tmp
|
||||
bcc L1
|
||||
inc tmp4 ; val * 5
|
||||
L1: asl a
|
||||
rol tmp4 ; val * 10
|
||||
asl a
|
||||
rol tmp4 ; val * 20
|
||||
ldx tmp4
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
.bss
|
||||
loc_tmp:.res 1
|
||||
17
libsrc/atari5200/randomize.s
Normal file
17
libsrc/atari5200/randomize.s
Normal file
@@ -0,0 +1,17 @@
|
||||
;
|
||||
; Christian Groessler, 01-Mar-2014
|
||||
;
|
||||
; void _randomize (void);
|
||||
; /* Initialize the random number generator */
|
||||
;
|
||||
|
||||
.export __randomize
|
||||
.import _srand
|
||||
|
||||
.include "atari5200.inc"
|
||||
|
||||
__randomize:
|
||||
ldx VCOUNT ; Use vertical line counter as high byte
|
||||
lda RTCLOK+1 ; Use clock as low byte
|
||||
jmp _srand ; Initialize generator
|
||||
|
||||
11
libsrc/atari5200/setcursor.s
Normal file
11
libsrc/atari5200/setcursor.s
Normal file
@@ -0,0 +1,11 @@
|
||||
; Dummy version, there is no visible cursor in the default CONIO screen
|
||||
;
|
||||
; 28-May-2014, Christian Groessler <chris@groessler.org>
|
||||
|
||||
.export setcursor
|
||||
|
||||
.proc setcursor
|
||||
|
||||
rts
|
||||
|
||||
.endproc
|
||||
39
libsrc/atari5200/sysuname.s
Normal file
39
libsrc/atari5200/sysuname.s
Normal file
@@ -0,0 +1,39 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-08-12
|
||||
;
|
||||
; unsigned char __fastcall__ _sysuname (struct utsname* buf);
|
||||
;
|
||||
|
||||
.export __sysuname, utsdata
|
||||
|
||||
.import utscopy
|
||||
|
||||
__sysuname = utscopy
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
; Data. We define a fixed utsname struct here and just copy it.
|
||||
|
||||
.rodata
|
||||
|
||||
utsdata:
|
||||
; sysname
|
||||
.asciiz "cc65"
|
||||
|
||||
; nodename
|
||||
.asciiz ""
|
||||
|
||||
; release
|
||||
.byte ((.VERSION >> 8) & $0F) + '0'
|
||||
.byte '.'
|
||||
.byte ((.VERSION >> 4) & $0F) + '0'
|
||||
.byte $00
|
||||
|
||||
; version
|
||||
.byte (.VERSION & $0F) + '0'
|
||||
.byte $00
|
||||
|
||||
; machine
|
||||
.asciiz "Atari5200"
|
||||
|
||||
|
||||
|
||||
41
libsrc/atari5200/y2k.inc
Normal file
41
libsrc/atari5200/y2k.inc
Normal file
@@ -0,0 +1,41 @@
|
||||
;-----------------------------------------------------------
|
||||
; Y2K FIX by Alan Davis, Dennis Debro, and Ronen Habot
|
||||
;-----------------------------------------------------------
|
||||
Y2K LDY #$00 ; Copy BIOS opening screen to RAM
|
||||
LDA #$FD
|
||||
STA TEMPH
|
||||
LDA #$58 ; Assume 2 port system
|
||||
LDX $FD32
|
||||
CPX #$E8 ; Is this a 4 port?
|
||||
BNE Y2K0 ; Jump if not
|
||||
LDA #$42 ; Yes, 4 port system
|
||||
Y2K0 STA TEMPL
|
||||
Y2K1 LDA (TEMPL),Y
|
||||
STA $0600,Y
|
||||
INY
|
||||
BNE Y2K1
|
||||
LDY #$50
|
||||
INC TEMPH
|
||||
Y2K2 LDA (TEMPL),Y
|
||||
STA $0700,Y
|
||||
DEY
|
||||
BPL Y2K2
|
||||
LDA #$D4 ; Point to copyright string
|
||||
STA $0724
|
||||
LDA #$BF
|
||||
STA $0725
|
||||
LDX #$0B ; Store NOP's @ end
|
||||
LDA #$EA
|
||||
Y2K3 STA $0732,X
|
||||
DEX
|
||||
BPL Y2K3
|
||||
LDA #$60 ; Store RTS opcode @ end
|
||||
STA $0750
|
||||
JSR $0600 ; Show title screen
|
||||
LDY #$00 ; Clear RAM from $0600-$3FFF
|
||||
STY $80
|
||||
LDA #$06
|
||||
STA $81
|
||||
JSR CLRRAM
|
||||
RTS
|
||||
|
||||
49
libsrc/atmos/capslock.s
Normal file
49
libsrc/atmos/capslock.s
Normal file
@@ -0,0 +1,49 @@
|
||||
;
|
||||
; When Oric computers are in BASIC's command mode, the keyboard is in CAPS lock
|
||||
; mode (because Oric BASIC keywords must be typed in upper-case). This
|
||||
; constructor disables that mode, so that text will be typed as lower-case
|
||||
; (which is the default on other cc65 platforms).
|
||||
; This module is linked by the conio and POSIX input functions.
|
||||
;
|
||||
; 2014-09-04, Greg King
|
||||
;
|
||||
|
||||
.constructor disable_caps
|
||||
.destructor restore_caps
|
||||
|
||||
.include "atmos.inc"
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
; Put this constructor into a segment that can be re-used by programs.
|
||||
;
|
||||
.segment "INIT"
|
||||
|
||||
; Turn the capitals lock off.
|
||||
|
||||
disable_caps:
|
||||
lda CAPSLOCK
|
||||
sta capsave
|
||||
lda #$7F
|
||||
sta CAPSLOCK
|
||||
rts
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
.code
|
||||
|
||||
; Restore the old capitals-lock state.
|
||||
|
||||
restore_caps:
|
||||
lda capsave
|
||||
sta CAPSLOCK
|
||||
rts
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
.bss
|
||||
|
||||
capsave:
|
||||
.res 1
|
||||
@@ -1,13 +1,15 @@
|
||||
;
|
||||
; 2003-04-13, Ullrich von Bassewitz
|
||||
; 2013-07-26, Greg King
|
||||
; 2014-09-04, Greg King
|
||||
;
|
||||
; char cgetc (void);
|
||||
;
|
||||
|
||||
.export _cgetc
|
||||
.constructor initcgetc
|
||||
|
||||
.import cursor
|
||||
.forceimport disable_caps
|
||||
|
||||
.include "atmos.inc"
|
||||
|
||||
@@ -22,11 +24,11 @@
|
||||
|
||||
; No character, enable cursor and wait
|
||||
|
||||
lda cursor ; Cursor currently off?
|
||||
lda cursor ; Should cursor be off?
|
||||
beq @L1 ; Skip if so
|
||||
lda STATUS
|
||||
ora #%00000001 ; Cursor ON
|
||||
sta STATUS
|
||||
lsr STATUS
|
||||
sec ; Cursor ON
|
||||
rol STATUS
|
||||
@L1: lda KEYBUF
|
||||
bpl @L1
|
||||
|
||||
@@ -34,17 +36,17 @@
|
||||
|
||||
ldx cursor
|
||||
beq @L2
|
||||
ldx #$00 ; Zero high byte
|
||||
dec STATUS ; Clear bit zero
|
||||
|
||||
; We have the character, clear avail flag
|
||||
; We have the character, clear the "available" flag
|
||||
|
||||
@L2: and #$7F ; Mask out avail flag
|
||||
sta KEYBUF
|
||||
ldx #>$0000
|
||||
ldy MODEKEY
|
||||
cpy #FUNCTKEY
|
||||
bne @L3
|
||||
ora #$80 ; FUNCT pressed
|
||||
ora #$80 ; FUNCT-key pressed
|
||||
|
||||
; Done
|
||||
|
||||
@@ -53,16 +55,12 @@
|
||||
.endproc
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Switch the cursor off, disable capslock. Code goes into the INIT segment
|
||||
; Switch the cursor off. Code goes into the INIT segment
|
||||
; which may be reused after it is run.
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
initcgetc:
|
||||
lda STATUS
|
||||
and #%11111110
|
||||
sta STATUS
|
||||
lda #$7F
|
||||
sta CAPSLOCK
|
||||
lsr STATUS
|
||||
asl STATUS ; Clear bit zero
|
||||
rts
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
; Startup code for cc65 (Oric version)
|
||||
;
|
||||
; By Debrune J<>r<EFBFBD>me <jede@oric.org> and Ullrich von Bassewitz <uz@cc65.org>
|
||||
; 2014-08-22, Greg King
|
||||
;
|
||||
|
||||
.export _exit
|
||||
@@ -39,26 +40,26 @@
|
||||
|
||||
.segment "STARTUP"
|
||||
|
||||
; Save the zero page area we're about to use
|
||||
; Save the zero-page area that we're about to use.
|
||||
|
||||
ldx #zpspace-1
|
||||
L1: lda sp,x
|
||||
sta zpsave,x ; Save the zero page locations we need
|
||||
sta zpsave,x
|
||||
dex
|
||||
bpl L1
|
||||
|
||||
; Clear the BSS data
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Unprotect columns 0 and 1
|
||||
; Unprotect screen columns 0 and 1.
|
||||
|
||||
lda STATUS
|
||||
sta stsave
|
||||
and #%11011111
|
||||
sta STATUS
|
||||
|
||||
; Save system stuff and setup the stack
|
||||
; Save some system stuff; and, set up the stack.
|
||||
|
||||
tsx
|
||||
stx spsave ; Save system stk ptr
|
||||
@@ -68,26 +69,26 @@ L1: lda sp,x
|
||||
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
sta sp+1 ; Set argument stack ptr
|
||||
|
||||
; Call module constructors
|
||||
; Call the module constructors.
|
||||
|
||||
jsr initlib
|
||||
|
||||
; Push arguments and call main()
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Call module destructors. This is also the _exit entry.
|
||||
; Call the module destructors. This is also the exit() entry.
|
||||
|
||||
_exit: jsr donelib ; Run module destructors
|
||||
|
||||
; Restore system stuff
|
||||
; Restore the system stuff.
|
||||
|
||||
ldx spsave
|
||||
txs
|
||||
lda stsave
|
||||
sta STATUS
|
||||
|
||||
; Copy back the zero page stuff
|
||||
; Copy back the zero-page stuff.
|
||||
|
||||
ldx #zpspace-1
|
||||
L2: lda zpsave,x
|
||||
@@ -95,7 +96,7 @@ L2: lda zpsave,x
|
||||
dex
|
||||
bpl L2
|
||||
|
||||
; Back to BASIC
|
||||
; Back to BASIC.
|
||||
|
||||
rts
|
||||
|
||||
|
||||
@@ -11,11 +11,13 @@
|
||||
.include "joy-error.inc"
|
||||
.include "atmos.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
module_header _atmos_pase_joy
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
;
|
||||
; 2003-03-07, Ullrich von Bassewitz
|
||||
; 2011-01-28, Stefan Haubenthal
|
||||
; 2013-07-15, Greg King
|
||||
; 2014-09-10, Greg King
|
||||
;
|
||||
; Setup arguments for main
|
||||
; Set up arguments for main
|
||||
;
|
||||
|
||||
.constructor initmainargs, 24
|
||||
@@ -40,11 +40,21 @@ L0: lda CFOUND_NAME,y
|
||||
;
|
||||
ldx #0
|
||||
L2: lda BASIC_BUF,x
|
||||
beq done ; no "rem," no args.
|
||||
beq done ; no "rem", no args.
|
||||
inx
|
||||
cmp #REM
|
||||
bne L2
|
||||
ldy #1 * 2
|
||||
|
||||
; The arguments must be copied to a safe place because BASIC's input buffer
|
||||
; might be re-used by the stdin console.
|
||||
|
||||
ldy #(SCREEN_XSIZE * 2 - 1) - 1
|
||||
L3: lda BASIC_BUF,y
|
||||
sta args,y
|
||||
dey
|
||||
bpl L3
|
||||
|
||||
ldy #1 * 2 ; Point to second argv slot
|
||||
|
||||
; Find the next argument
|
||||
|
||||
@@ -65,12 +75,14 @@ found: cmp #'"' ; Is the argument quoted?
|
||||
lda #' ' ; A space ends the argument
|
||||
setterm:sta term ; Set end of argument marker
|
||||
|
||||
; Now store a pointer to the argument into the next slot. Since the BASIC
|
||||
; input buffer is located at the zero page, no calculations are necessary.
|
||||
; Now, store a pointer, to the argument, into the next slot.
|
||||
|
||||
txa ; Get low byte
|
||||
add #<BASIC_BUF ; Not at page boundary
|
||||
add #<args
|
||||
sta argv,y ; argv[y]= &arg
|
||||
lda #>$0000
|
||||
adc #>args
|
||||
sta argv+1,y
|
||||
iny
|
||||
iny
|
||||
inc __argc ; Found another arg
|
||||
@@ -87,8 +99,8 @@ argloop:lda BASIC_BUF,x
|
||||
; A contains the terminating character. To make the argument a valid C string,
|
||||
; replace the terminating character by a zero.
|
||||
|
||||
lda #0
|
||||
sta BASIC_BUF-1,x
|
||||
lda #$00
|
||||
sta args-1,x
|
||||
|
||||
; Check if the maximum number of command line arguments is reached. If not,
|
||||
; parse the next one.
|
||||
@@ -103,7 +115,6 @@ done: lda #<argv
|
||||
ldx #>argv
|
||||
sta __argv
|
||||
stx __argv + 1
|
||||
|
||||
rts
|
||||
|
||||
.endproc
|
||||
@@ -115,7 +126,8 @@ done: lda #<argv
|
||||
.bss
|
||||
term: .res 1
|
||||
name: .res FNAME_LEN + 1
|
||||
args: .res SCREEN_XSIZE * 2 - 1
|
||||
|
||||
.data
|
||||
argv: .addr name
|
||||
.res MAXARGS * 2
|
||||
.res MAXARGS * 2, $00
|
||||
|
||||
86
libsrc/atmos/read.s
Normal file
86
libsrc/atmos/read.s
Normal file
@@ -0,0 +1,86 @@
|
||||
;
|
||||
; 2014-08-22, Greg King
|
||||
;
|
||||
; int read (int fd, void* buf, unsigned count);
|
||||
;
|
||||
; This function is a hack! It lets us get text from the stdin console.
|
||||
;
|
||||
|
||||
.export _read
|
||||
.constructor initstdin
|
||||
|
||||
.import popax
|
||||
.importzp ptr1, ptr2, ptr3
|
||||
.forceimport disable_caps
|
||||
|
||||
.macpack generic
|
||||
.include "atmos.inc"
|
||||
|
||||
.proc _read
|
||||
|
||||
sta ptr3
|
||||
stx ptr3+1 ; save count as result
|
||||
eor #$FF
|
||||
sta ptr2
|
||||
txa
|
||||
eor #$FF
|
||||
sta ptr2+1 ; Remember -count-1
|
||||
|
||||
jsr popax ; get buf
|
||||
sta ptr1
|
||||
stx ptr1+1
|
||||
jsr popax ; get fd and discard
|
||||
|
||||
L1: inc ptr2
|
||||
bnz L2
|
||||
inc ptr2+1
|
||||
bze L9 ; no more room in buf
|
||||
|
||||
; If there are no more characters in BASIC's input buffer, then get a line from
|
||||
; the console into that buffer.
|
||||
|
||||
L2: ldx text_count
|
||||
bpl L3
|
||||
jsr GETLINE
|
||||
ldx #<(0 - 1)
|
||||
|
||||
L3: inx
|
||||
lda BASIC_BUF,x
|
||||
bnz L4 ; (zero-terminated buffer)
|
||||
ldx #<-1
|
||||
lda #$0A ; return newline char. at end of line
|
||||
L4: stx text_count
|
||||
ldy #0
|
||||
sta (ptr1),y
|
||||
inc ptr1
|
||||
bnz L1
|
||||
inc ptr1+1
|
||||
bnz L1 ; branch always
|
||||
|
||||
; No error, return count.
|
||||
|
||||
L9: lda ptr3
|
||||
ldx ptr3+1
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
; initstdin: Reset the stdin console.
|
||||
|
||||
.segment "INIT"
|
||||
|
||||
initstdin:
|
||||
ldx #<-1
|
||||
stx text_count
|
||||
rts
|
||||
|
||||
|
||||
;--------------------------------------------------------------------------
|
||||
|
||||
.bss
|
||||
|
||||
text_count:
|
||||
.res 1
|
||||
|
||||
@@ -28,10 +28,13 @@
|
||||
.include "ser-error.inc"
|
||||
.include "atmos.inc"
|
||||
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
module_header _atmos_acia_ser
|
||||
|
||||
; Driver signature
|
||||
.byte $73, $65, $72 ; "ser"
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
;
|
||||
; time_t _systime (void);
|
||||
; /* Similar to time(), but:
|
||||
; * - Is not ISO C
|
||||
; * - Does not take the additional pointer
|
||||
; * - Does not set errno when returning -1
|
||||
; */
|
||||
; ** - Is not ISO C
|
||||
; ** - Does not take the additional pointer
|
||||
; ** - Does not set errno when returning -1
|
||||
; */
|
||||
;
|
||||
|
||||
.export __systime
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
; Graphics driver for the 228x200x3 palette mode on the Atmos
|
||||
;
|
||||
; Stefan Haubenthal <polluks@sdf.lonestar.org>
|
||||
; 2013-07-15, Greg King <gregdk@users.sf.net>
|
||||
; 2014-09-10, Greg King <gregdk@users.sf.net>
|
||||
;
|
||||
|
||||
.include "zeropage.inc"
|
||||
@@ -12,6 +12,7 @@
|
||||
.include "atmos.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
XSIZE = 6 ; System font width
|
||||
YSIZE = 8 ; System font height
|
||||
@@ -19,7 +20,7 @@ YSIZE = 8 ; System font height
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table and constants.
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
module_header _atmos_228_200_3_tgi
|
||||
|
||||
; The first part of the header is a structure that has a signature,
|
||||
; and defines the capabilities of the driver.
|
||||
@@ -274,7 +275,7 @@ mymode: sta PARAM3
|
||||
lda X1
|
||||
add #2 * XSIZE ; Skip screen attribute columns
|
||||
sta PARAM1
|
||||
lda #0
|
||||
lda #>$0000
|
||||
sta PARAM1+1
|
||||
sta PARAM2+1
|
||||
sta PARAM3+1
|
||||
@@ -290,13 +291,13 @@ GETPIXEL:
|
||||
sta PARAM1
|
||||
lda Y1
|
||||
sta PARAM2
|
||||
lda #0
|
||||
lda #>$0000
|
||||
sta PARAM1+1
|
||||
sta PARAM2+1
|
||||
jsr POINT
|
||||
lda PARAM1
|
||||
and #%00000001
|
||||
ldx #0
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
@@ -322,7 +323,7 @@ LINE:
|
||||
sta PARAM2+1
|
||||
lda MODE
|
||||
sta PARAM3
|
||||
ldx #>0
|
||||
ldx #>$0000
|
||||
stx PARAM3+1
|
||||
jmp DRAW
|
||||
|
||||
@@ -358,7 +359,7 @@ BAR:
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in the x
|
||||
; and y directions is passend in X/Y, the text direction is passed in A.
|
||||
; and y directions is passed in X/Y, the text direction is passed in A.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
;
|
||||
@@ -368,7 +369,7 @@ TEXTSTYLE:
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
|
||||
; OUTTEXT: Output text at x/y = ptr1/ptr2, using the current color and the
|
||||
; current text style. The text to output is given as a zero-terminated
|
||||
; string with its address in ptr3.
|
||||
;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
; Graphics driver for the 240x200x2 monochrome mode on the Atmos
|
||||
;
|
||||
; Stefan Haubenthal <polluks@sdf.lonestar.org>
|
||||
; 2013-07-16, Greg King <gregdk@users.sf.net>
|
||||
; 2014-09-10, Greg King <gregdk@users.sf.net>
|
||||
;
|
||||
|
||||
.include "zeropage.inc"
|
||||
@@ -12,6 +12,7 @@
|
||||
.include "atmos.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
XSIZE = 6 ; System font width
|
||||
YSIZE = 8 ; System font height
|
||||
@@ -19,7 +20,7 @@ YSIZE = 8 ; System font height
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table and constants.
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
module_header _atmos_240_200_2_tgi
|
||||
|
||||
; First part of the header is a structure that has a magic and defines the
|
||||
; capabilities of the driver
|
||||
@@ -253,7 +254,7 @@ SETPIXEL:
|
||||
mymode: sta PARAM3
|
||||
lda X1
|
||||
sta PARAM1
|
||||
lda #0
|
||||
lda #>$0000
|
||||
sta PARAM1+1
|
||||
sta PARAM2+1
|
||||
sta PARAM3+1
|
||||
@@ -269,13 +270,13 @@ GETPIXEL:
|
||||
sta PARAM1
|
||||
lda Y1
|
||||
sta PARAM2
|
||||
lda #0
|
||||
lda #>$0000
|
||||
sta PARAM1+1
|
||||
sta PARAM2+1
|
||||
jsr POINT
|
||||
lda PARAM1
|
||||
and #%00000001
|
||||
ldx #0
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
@@ -301,7 +302,7 @@ LINE:
|
||||
sta PARAM2+1
|
||||
lda MODE
|
||||
sta PARAM3
|
||||
ldx #>0
|
||||
ldx #>$0000
|
||||
stx PARAM3+1
|
||||
jmp DRAW
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
.proc _toascii
|
||||
|
||||
; .X must be zero, on return.
|
||||
ldx #>0
|
||||
ldx #>$0000
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
@@ -22,21 +22,21 @@
|
||||
|
||||
Start:
|
||||
|
||||
; Switch to the second charset
|
||||
; Switch to the second charset.
|
||||
|
||||
lda #14
|
||||
jsr BSOUT
|
||||
|
||||
; Before doing anything else, we have to setup our banking configuration.
|
||||
; Otherwise just the lowest 16K are actually RAM. Writing through the ROM
|
||||
; to the underlying RAM works, but it is bad style.
|
||||
; Before doing anything else, we have to set up our banking configuration.
|
||||
; Otherwise, just the lowest 16K are actually RAM. Writing through the ROM
|
||||
; to the underlying RAM works; but, it is bad style.
|
||||
|
||||
lda MMU_CR ; Get current memory configuration...
|
||||
pha ; ...and save it for later
|
||||
lda #MMU_CFG_CC65 ; Bank0 with kernal ROM
|
||||
lda #MMU_CFG_CC65 ; Bank0 with Kernal ROM
|
||||
sta MMU_CR
|
||||
|
||||
; Save the zero page locations we need
|
||||
; Save the zero-page locations that we need.
|
||||
|
||||
ldx #zpspace-1
|
||||
L1: lda sp,x
|
||||
@@ -44,11 +44,11 @@ L1: lda sp,x
|
||||
dex
|
||||
bpl L1
|
||||
|
||||
; Clear the BSS data
|
||||
; Clear the BSS data.
|
||||
|
||||
jsr zerobss
|
||||
|
||||
; Save system stuff and setup the stack
|
||||
; Save some system stuff; and, set up the stack.
|
||||
|
||||
pla ; Get MMU setting
|
||||
sta mmusave
|
||||
@@ -61,27 +61,27 @@ L1: lda sp,x
|
||||
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
|
||||
sta sp+1 ; Set argument stack ptr
|
||||
|
||||
; Call module constructors
|
||||
; Call the module constructors.
|
||||
|
||||
jsr initlib
|
||||
|
||||
; Set the bank for the file name to our execution bank. We must do this,
|
||||
; *after* calling constructors, because some of them may depend on the
|
||||
; original value of this register.
|
||||
; Set the bank for the file name to our execution bank. We must do this
|
||||
; *after* calling the constructors because some of them might depend on
|
||||
; the original value of this register.
|
||||
|
||||
lda #0
|
||||
sta FNAM_BANK
|
||||
|
||||
; Push arguments and call main()
|
||||
; Push the command-line arguments; and, call main().
|
||||
|
||||
jsr callmain
|
||||
|
||||
; Back from main (this is also the _exit entry). Run module destructors
|
||||
; Back from main() [this is also the exit() entry]. Run the module destructors.
|
||||
|
||||
_exit: pha ; Save the return code on stack
|
||||
jsr donelib
|
||||
|
||||
; Copy back the zero page stuff
|
||||
; Copy back the zero-page stuff.
|
||||
|
||||
ldx #zpspace-1
|
||||
L2: lda zpsave,x
|
||||
@@ -89,19 +89,19 @@ L2: lda zpsave,x
|
||||
dex
|
||||
bpl L2
|
||||
|
||||
; Place the program return code into ST
|
||||
; Place the program return code into BASIC's status variable.
|
||||
|
||||
pla
|
||||
sta ST
|
||||
|
||||
; Reset the stack and the memory configuration
|
||||
; Reset the stack and the memory configuration.
|
||||
|
||||
ldx spsave
|
||||
txs
|
||||
ldx mmusave
|
||||
stx MMU_CR
|
||||
|
||||
; Done, return to BASIC
|
||||
; Done, return to BASIC.
|
||||
|
||||
rts
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
.include "em-kernel.inc"
|
||||
.include "em-error.inc"
|
||||
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
module_header _c128_georam_emd
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
.include "em-error.inc"
|
||||
.include "c128.inc"
|
||||
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
module_header _c128_ram_emd
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
.include "em-error.inc"
|
||||
.include "c128.inc"
|
||||
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table
|
||||
|
||||
.segment "JUMPTABLE"
|
||||
module_header _c128_ram2_emd
|
||||
|
||||
; Driver signature
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user