Merge branch 'cc65:master' into master
This commit is contained in:
380
libsrc/NameClashes.md
Normal file
380
libsrc/NameClashes.md
Normal file
@@ -0,0 +1,380 @@
|
||||
List of cc65 library name clashes
|
||||
=================================
|
||||
|
||||
The following is a list of identifiers that might need
|
||||
to be fixed, sorted by directory and identifier:
|
||||
|
||||
# common
|
||||
|
||||
## \_\_argc
|
||||
|
||||
* libsrc/runtime/callmain.s
|
||||
* libsrc/cbm610/mainargs.s
|
||||
* libsrc/cx16/mainargs.s
|
||||
* libsrc/plus4/mainargs.s
|
||||
* libsrc/lynx/mainargs.s
|
||||
* libsrc/c16/mainargs.s
|
||||
* libsrc/geos-common/system/mainargs.s
|
||||
* libsrc/sim6502/mainargs.s
|
||||
* libsrc/c128/mainargs.s
|
||||
* libsrc/vic20/mainargs.s
|
||||
* libsrc/nes/mainargs.s
|
||||
* libsrc/atari/getargs.s
|
||||
* libsrc/apple2/mainargs.s
|
||||
* libsrc/cbm510/mainargs.s
|
||||
* libsrc/telestrat/mainargs.s
|
||||
* libsrc/c64/mainargs.s
|
||||
* libsrc/pet/mainargs.s
|
||||
* libsrc/atmos/mainargs.s
|
||||
|
||||
## \_\_argv
|
||||
|
||||
* libsrc/runtime/callmain.s
|
||||
* libsrc/cbm610/mainargs.s
|
||||
* libsrc/cx16/mainargs.s
|
||||
* libsrc/plus4/mainargs.s
|
||||
* libsrc/lynx/mainargs.s
|
||||
* libsrc/c16/mainargs.s
|
||||
* libsrc/geos-common/system/mainargs.s
|
||||
* libsrc/sim6502/mainargs.s
|
||||
* libsrc/c128/mainargs.s
|
||||
* libsrc/vic20/mainargs.s
|
||||
* libsrc/nes/mainargs.s
|
||||
* libsrc/atari/getargs.s
|
||||
* libsrc/apple2/mainargs.s
|
||||
* libsrc/cbm510/mainargs.s
|
||||
* libsrc/telestrat/mainargs.s
|
||||
* libsrc/c64/mainargs.s
|
||||
* libsrc/pet/mainargs.s
|
||||
* libsrc/atmos/mainargs.s
|
||||
|
||||
## \_\_cos
|
||||
|
||||
* libsrc/common/sincos.s
|
||||
|
||||
## \_\_ctypeidx
|
||||
|
||||
* libsrc/common/ctype.s
|
||||
* libsrc/common/ctypemask.s
|
||||
* libsrc/geos-common/system/ctype.s
|
||||
* libsrc/atari/ctype.s
|
||||
* libsrc/cbm/ctype.s
|
||||
* libsrc/atmos/ctype.s
|
||||
* asminc/ctype\_common.inc
|
||||
|
||||
## \_\_cwd
|
||||
|
||||
* libsrc/common/getcwd.s
|
||||
* libsrc/common/_cwd.s
|
||||
* libsrc/atari/initcwd.s
|
||||
* libsrc/apple2/initcwd.s
|
||||
* libsrc/apple2/initcwd.s
|
||||
* libsrc/telestrat/initcwd.s
|
||||
* libsrc/cbm/initcwd.s
|
||||
|
||||
## \_\_cwd\_buf\_size
|
||||
|
||||
* libsrc/common/_cwd.s
|
||||
|
||||
## \_\_envcount
|
||||
|
||||
* libsrc/common/searchenv.s
|
||||
* libsrc/common/_environ.s
|
||||
* libsrc/common/putenv.s
|
||||
* libsrc/common/getenv.s
|
||||
|
||||
## \_\_environ
|
||||
|
||||
* libsrc/common/searchenv.s
|
||||
* libsrc/common/_environ.s
|
||||
* libsrc/common/putenv.s
|
||||
* libsrc/common/getenv.s
|
||||
|
||||
## \_\_envsize
|
||||
|
||||
* libsrc/common/_environ.s
|
||||
* libsrc/common/putenv.s
|
||||
|
||||
## \_\_fdesc
|
||||
|
||||
* libsrc/common/_fdesc.s
|
||||
* libsrc/common/fopen.s
|
||||
|
||||
## \_\_filetab
|
||||
|
||||
* libsrc/common/_fdesc.s
|
||||
* libsrc/common/_file.s
|
||||
* asminc/_file.inc
|
||||
|
||||
## \_\_fopen
|
||||
|
||||
* libsrc/common/fopen.s
|
||||
* libsrc/common/_fopen.s
|
||||
|
||||
## \_\_printf
|
||||
|
||||
* libsrc/common/vsnprintf.s
|
||||
* libsrc/common/_printf.s
|
||||
* libsrc/common/vfprintf.s
|
||||
* libsrc/conio/vcprintf.s
|
||||
* libsrc/pce/_printf.s
|
||||
|
||||
## \_\_scanf
|
||||
|
||||
* libsrc/common/_scanf.inc
|
||||
* libsrc/common/vsscanf.s
|
||||
* libsrc/conio/vcscanf.s
|
||||
|
||||
## \_\_sin
|
||||
|
||||
* libsrc/common/sincos.s
|
||||
|
||||
## \_\_sys
|
||||
|
||||
* libsrc/common/_sys.s
|
||||
* libsrc/apple2/_sys.s
|
||||
|
||||
## \_\_sys\_oserrlist
|
||||
|
||||
* libsrc/common/stroserr.s
|
||||
* libsrc/geos-common/system/oserrlist.s
|
||||
* libsrc/atari/oserrlist.s
|
||||
* libsrc/apple2/oserrlist.s
|
||||
* libsrc/cbm/oserrlist.s
|
||||
* libsrc/atmos/oserrlist.s
|
||||
|
||||
## \_\_syschdir
|
||||
|
||||
* libsrc/common/chdir.s
|
||||
* libsrc/atari/syschdir.s
|
||||
* libsrc/apple2/syschdir.s
|
||||
* libsrc/telestrat/syschdir.s
|
||||
* libsrc/cbm/syschdir.s
|
||||
|
||||
## \_\_sysmkdir
|
||||
|
||||
* libsrc/common/mkdir.s
|
||||
* libsrc/atari/sysmkdir.s
|
||||
* libsrc/apple2/sysmkdir.s
|
||||
* libsrc/telestrat/sysmkdir.s
|
||||
|
||||
## \_\_sysremove
|
||||
|
||||
* libsrc/common/remove.s
|
||||
* libsrc/geos-common/file/sysremove.s
|
||||
* libsrc/atari/sysremove.s
|
||||
* libsrc/atari/sysrmdir.s
|
||||
* libsrc/apple2/sysremove.s
|
||||
* libsrc/apple2/sysrmdir.s
|
||||
* libsrc/telestrat/sysremove.s
|
||||
* libsrc/cbm/sysremove.s
|
||||
|
||||
## \_\_sysrename
|
||||
|
||||
* libsrc/common/rename.s
|
||||
* libsrc/geos-common/file/sysrename.s
|
||||
* libsrc/atari/sysrename.s
|
||||
* libsrc/apple2/sysrename.s
|
||||
* libsrc/cbm/sysrename.s
|
||||
|
||||
## \_\_sysrmdir
|
||||
|
||||
* libsrc/common/rmdir.s
|
||||
* libsrc/atari/sysrmdir.s
|
||||
* libsrc/apple2/sysrmdir.s
|
||||
|
||||
\_\_sysuname
|
||||
|
||||
* libsrc/common/uname.s
|
||||
* libsrc/cbm610/sysuname.s
|
||||
* libsrc/cx16/sysuname.s
|
||||
* libsrc/plus4/sysuname.s
|
||||
* libsrc/lynx/sysuname.s
|
||||
* libsrc/c16/sysuname.s
|
||||
* libsrc/geos-common/system/sysuname.s
|
||||
* libsrc/c128/sysuname.s
|
||||
* libsrc/creativision/sysuname.s
|
||||
* libsrc/vic20/sysuname.s
|
||||
* libsrc/nes/sysuname.s
|
||||
* libsrc/atari/sysuname.s
|
||||
* libsrc/apple2/sysuname.s
|
||||
* libsrc/cbm510/sysuname.s
|
||||
* libsrc/telestrat/sysuname.s
|
||||
* libsrc/c64/sysuname.s
|
||||
* libsrc/pet/sysuname.s
|
||||
* libsrc/atari5200/sysuname.s
|
||||
* libsrc/atmos/sysuname.s
|
||||
|
||||
# apple2
|
||||
|
||||
## \_\_auxtype
|
||||
|
||||
* libsrc/apple2/open.s
|
||||
|
||||
## \_\_datetime
|
||||
|
||||
* libsrc/apple2/open.s
|
||||
|
||||
## \_\_dos\_type
|
||||
|
||||
* libsrc/apple2/dioopen.s
|
||||
* libsrc/apple2/curdevice.s
|
||||
* libsrc/apple2/mainargs.s
|
||||
* libsrc/apple2/settime.s
|
||||
* libsrc/apple2/getdevice.s
|
||||
* libsrc/apple2/dosdetect.s
|
||||
* libsrc/apple2/irq.s
|
||||
* libsrc/apple2/open.s
|
||||
* libsrc/apple2/mli.s
|
||||
* libsrc/apple2/getres.s
|
||||
|
||||
## \_\_filetype
|
||||
|
||||
* libsrc/apple2/open.s
|
||||
* libsrc/apple2/exehdr.s
|
||||
|
||||
## atari
|
||||
|
||||
## \_\_defdev
|
||||
|
||||
* libsrc/atari/posixdirent.s
|
||||
* libsrc/atari/ucase\_fn.s
|
||||
* libsrc/atari/getdefdev.s
|
||||
|
||||
## \_\_dos\_type
|
||||
|
||||
* libsrc/atari/getargs.s
|
||||
* libsrc/atari/exec.s
|
||||
* libsrc/atari/settime.s
|
||||
* libsrc/atari/syschdir.s
|
||||
* libsrc/atari/dosdetect.s
|
||||
* libsrc/atari/is\_cmdline\_dos.s
|
||||
* libsrc/atari/sysrmdir.s
|
||||
* libsrc/atari/gettime.s
|
||||
* libsrc/atari/lseek.s
|
||||
* libsrc/atari/getres.s
|
||||
* libsrc/atari/getdefdev.s
|
||||
|
||||
## \_\_do\_oserror
|
||||
|
||||
* libsrc/atari/posixdirent.s
|
||||
* libsrc/atari/do\_oserr.s
|
||||
* libsrc/atari/serref.s
|
||||
* libsrc/atari/read.s
|
||||
* libsrc/atari/write.s
|
||||
* libsrc/atari/close.s
|
||||
|
||||
## \_\_getcolor
|
||||
|
||||
* libsrc/atari/setcolor.s
|
||||
|
||||
## \_\_getdefdev
|
||||
|
||||
* libsrc/atari/getdefdev.s
|
||||
|
||||
## \_\_graphics
|
||||
|
||||
* libsrc/atari/graphics.s
|
||||
|
||||
## \_\_inviocb
|
||||
|
||||
* libsrc/atari/serref.s
|
||||
* libsrc/atari/ser/atrrdev.s
|
||||
* libsrc/atari/inviocb.s
|
||||
* libsrc/atari/read.s
|
||||
* libsrc/atari/write.s
|
||||
* libsrc/atari/lseek.s
|
||||
* libsrc/atari/close.s
|
||||
|
||||
## \_\_is\_cmdline\_dos
|
||||
|
||||
* libsrc/atari/is\_cmdline\_dos.s
|
||||
* libsrc/atari/doesclrscr.s
|
||||
|
||||
## \_\_rest\_vecs
|
||||
|
||||
* libsrc/atari/savevec.s
|
||||
|
||||
## \_\_rwsetup
|
||||
|
||||
* libsrc/atari/rwcommon.s
|
||||
* libsrc/atari/read.s
|
||||
* libsrc/atari/write.s
|
||||
|
||||
## \_\_save\_vecs
|
||||
|
||||
* libsrc/atari/savevec.s
|
||||
|
||||
## \_\_scroll
|
||||
|
||||
* libsrc/atari/scroll.s
|
||||
|
||||
## \_\_setcolor
|
||||
|
||||
* libsrc/atari/setcolor.s
|
||||
|
||||
## \_\_setcolor\_low
|
||||
|
||||
* libsrc/atari/setcolor.s
|
||||
|
||||
## \_\_sio\_call
|
||||
|
||||
* libsrc/atari/diowritev.s
|
||||
* libsrc/atari/diopncls.s
|
||||
* libsrc/atari/siocall.s
|
||||
* libsrc/atari/diowrite.s
|
||||
* libsrc/atari/dioread.s
|
||||
|
||||
# cbm
|
||||
|
||||
## \_\_cbm\_filetype
|
||||
|
||||
* libsrc/cbm/cbm\_filetype.s
|
||||
* asminc/cbm\_filetype.in
|
||||
|
||||
## \_\_dirread
|
||||
|
||||
* libsrc/cbm/dir.inc
|
||||
* libsrc/cbm/dir.s
|
||||
|
||||
## \_\_dirread1
|
||||
|
||||
* libsrc/cbm/dir.inc
|
||||
* libsrc/cbm/dir.s
|
||||
|
||||
# lynx
|
||||
|
||||
## \_\_iodat
|
||||
|
||||
* libsrc/lynx/lynx-cart.s
|
||||
* libsrc/lynx/bootldr.s
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
## \_\_iodir
|
||||
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
## \_\_sprsys
|
||||
|
||||
* libsrc/lynx/tgi/lynx-160-102-16.s
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
## \_\_viddma
|
||||
|
||||
* libsrc/lynx/tgi/lynx-160-102-16.s
|
||||
* libsrc/lynx/extzp.s
|
||||
* libsrc/lynx/crt0.s
|
||||
* libsrc/lynx/extzp.inc
|
||||
|
||||
# pce
|
||||
|
||||
## \_\_nmi
|
||||
|
||||
* libsrc/pce/irq.s
|
||||
* libsrc/pce/crt0.s
|
||||
23
libsrc/apple2/allow_lowercase.s
Normal file
23
libsrc/apple2/allow_lowercase.s
Normal file
@@ -0,0 +1,23 @@
|
||||
;
|
||||
; Oliver Schmidt, 2024-08-06
|
||||
;
|
||||
; unsigned char __fastcall__ allow_lowercase (unsigned char onoff);
|
||||
;
|
||||
|
||||
.export _allow_lowercase
|
||||
.import uppercasemask, return0, return1
|
||||
|
||||
_allow_lowercase:
|
||||
tax
|
||||
lda values,x
|
||||
ldx uppercasemask
|
||||
sta uppercasemask
|
||||
cpx #$FF
|
||||
beq :+
|
||||
jmp return0
|
||||
: jmp return1
|
||||
|
||||
.rodata
|
||||
|
||||
values: .byte $DF ; Force uppercase
|
||||
.byte $FF ; Keep lowercase
|
||||
75
libsrc/apple2/callmain.s
Normal file
75
libsrc/apple2/callmain.s
Normal file
@@ -0,0 +1,75 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 2003-03-07
|
||||
;
|
||||
; Push arguments and call main()
|
||||
;
|
||||
|
||||
|
||||
.export callmain, _exit
|
||||
.export __argc, __argv
|
||||
|
||||
.import _main, pushax, done, donelib
|
||||
.import zpsave, rvsave, reset
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "apple2.inc"
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Setup the stack for main(), then jump to it
|
||||
|
||||
callmain:
|
||||
lda __argc
|
||||
ldx __argc+1
|
||||
jsr pushax ; Push argc
|
||||
|
||||
lda __argv
|
||||
ldx __argv+1
|
||||
jsr pushax ; Push argv
|
||||
|
||||
ldy #4 ; Argument size
|
||||
jsr _main
|
||||
|
||||
; Avoid a re-entrance of donelib. This is also the exit() entry.
|
||||
_exit: ldx #<exit
|
||||
lda #>exit
|
||||
jsr reset ; Setup RESET vector
|
||||
|
||||
; Switch in LC bank 2 for R/O in case it was switched out by a RESET.
|
||||
bit $C080
|
||||
|
||||
; Call the module destructors.
|
||||
jsr donelib
|
||||
|
||||
; Switch in ROM.
|
||||
bit $C082
|
||||
|
||||
; Restore the original RESET vector.
|
||||
exit: ldx #$02
|
||||
: lda rvsave,x
|
||||
sta SOFTEV,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; Copy back the zero-page stuff.
|
||||
ldx #zpspace-1
|
||||
: lda zpsave,x
|
||||
sta sp,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; ProDOS TechRefMan, chapter 5.2.1:
|
||||
; "System programs should set the stack pointer to $FF at the
|
||||
; warm-start entry point."
|
||||
ldx #$FF
|
||||
txs ; Re-init stack pointer
|
||||
|
||||
; We're done
|
||||
jmp done
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; Data
|
||||
|
||||
.data
|
||||
__argc: .word 0
|
||||
__argv: .addr 0
|
||||
@@ -11,6 +11,9 @@
|
||||
.export _cputcxy, _cputc
|
||||
.export cputdirect, newline, putchar, putchardirect
|
||||
.import gotoxy, VTABZ
|
||||
.ifndef __APPLE2ENH__
|
||||
.import uppercasemask
|
||||
.endif
|
||||
|
||||
.include "apple2.inc"
|
||||
|
||||
@@ -43,7 +46,7 @@ _cputc:
|
||||
.ifndef __APPLE2ENH__
|
||||
cmp #$E0 ; Test for lowercase
|
||||
bcc cputdirect
|
||||
and #$DF ; Convert to uppercase
|
||||
and uppercasemask
|
||||
.endif
|
||||
|
||||
cputdirect:
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
; Startup code for cc65 (Apple2 version)
|
||||
;
|
||||
|
||||
.export _exit, done, return
|
||||
.export done, return
|
||||
.export zpsave, rvsave, reset
|
||||
.export __STARTUP__ : absolute = 1 ; Mark as startup
|
||||
|
||||
.import initlib, donelib
|
||||
.import initlib, _exit
|
||||
.import zerobss, callmain
|
||||
.import __ONCE_LOAD__, __ONCE_SIZE__ ; Linker generated
|
||||
.import __LC_START__, __LC_LAST__ ; Linker generated
|
||||
@@ -33,44 +34,7 @@
|
||||
jsr zerobss
|
||||
|
||||
; Push the command-line arguments; and, call main().
|
||||
jsr callmain
|
||||
|
||||
; Avoid a re-entrance of donelib. This is also the exit() entry.
|
||||
_exit: ldx #<exit
|
||||
lda #>exit
|
||||
jsr reset ; Setup RESET vector
|
||||
|
||||
; Switch in LC bank 2 for R/O in case it was switched out by a RESET.
|
||||
bit $C080
|
||||
|
||||
; Call the module destructors.
|
||||
jsr donelib
|
||||
|
||||
; Switch in ROM.
|
||||
bit $C082
|
||||
|
||||
; Restore the original RESET vector.
|
||||
exit: ldx #$02
|
||||
: lda rvsave,x
|
||||
sta SOFTEV,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; Copy back the zero-page stuff.
|
||||
ldx #zpspace-1
|
||||
: lda zpsave,x
|
||||
sta sp,x
|
||||
dex
|
||||
bpl :-
|
||||
|
||||
; ProDOS TechRefMan, chapter 5.2.1:
|
||||
; "System programs should set the stack pointer to $FF at the
|
||||
; warm-start entry point."
|
||||
ldx #$FF
|
||||
txs ; Re-init stack pointer
|
||||
|
||||
; We're done
|
||||
jmp done
|
||||
jmp callmain
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -66,34 +66,16 @@ HSType: .res 1 ; Flow-control type
|
||||
RecvBuf: .res 256 ; Receive buffers: 256 bytes
|
||||
SendBuf: .res 256 ; Send buffers: 256 bytes
|
||||
|
||||
CurClockSource: .res 1 ; Whether to use BRG or RTxC for clock
|
||||
|
||||
.data
|
||||
|
||||
Opened: .byte $00 ; 1 when opened
|
||||
Channel: .byte $00 ; Channel B by default
|
||||
CurChanIrqFlags:.byte INTR_PENDING_RX_EXT_B
|
||||
CurChanIrqFlags:.byte $00
|
||||
|
||||
SerFlagOrig: .byte $00
|
||||
|
||||
; Tables used to translate cc65 RS232 params into register values
|
||||
; (Ref page 5-18 and 5-19)
|
||||
BaudLowTable: .byte $7E ; SER_BAUD_300
|
||||
.byte $5E ; SER_BAUD_1200
|
||||
.byte $2E ; SER_BAUD_2400
|
||||
.byte $16 ; SER_BAUD_4800
|
||||
.byte $0A ; SER_BAUD_9600
|
||||
.byte $04 ; SER_BAUD_19200
|
||||
.byte $01 ; SER_BAUD_38400
|
||||
.byte $00 ; SER_BAUD_57600
|
||||
|
||||
BaudHighTable: .byte $01 ; SER_BAUD_300
|
||||
.byte $00 ; SER_BAUD_1200
|
||||
.byte $00 ; SER_BAUD_2400
|
||||
.byte $00 ; SER_BAUD_4800
|
||||
.byte $00 ; SER_BAUD_9600
|
||||
.byte $00 ; SER_BAUD_19200
|
||||
.byte $00 ; SER_BAUD_38400
|
||||
.byte $00 ; SER_BAUD_57600
|
||||
|
||||
RxBitTable: .byte %00000000 ; SER_BITS_5, in WR_RX_CTRL (WR3)
|
||||
.byte %10000000 ; SER_BITS_6 (Ref page 5-7)
|
||||
.byte %01000000 ; SER_BITS_7
|
||||
@@ -106,29 +88,65 @@ TxBitTable: .byte %00000000 ; SER_BITS_5, in WR_TX_CTRL (WR5)
|
||||
|
||||
.rodata
|
||||
|
||||
ClockMultiplier:.byte %01000000 ; Clock x16 (300-57600bps, WR4, ref page 5-8)
|
||||
.byte %10000000 ; Clock x32 (115200bps, ref page 5-8)
|
||||
|
||||
ClockSource: .byte %01010000 ; Use baud rate generator (ch. B) (WR11, page 5-17)
|
||||
.byte %00000000 ; Use RTxC (115200bps) (ch. B)
|
||||
.byte %11010000 ; Use baud rate generator (ch. A)
|
||||
.byte %10000000 ; Use RTxC (115200bps) (ch. A)
|
||||
|
||||
BrgEnabled: .byte %00000001 ; Baud rate generator on (WR14, page 5-19)
|
||||
.byte %00000000 ; BRG Off
|
||||
|
||||
ChanIrqFlags: .byte %00000101 ; ANDed (RX/special IRQ, ch. B) (page 5-25)
|
||||
.byte %00101000 ; ANDed (RX/special IRQ, ch. A)
|
||||
|
||||
ChanIrqMask: .byte %00000111 ; Ch. B IRQ flags mask
|
||||
.byte %00111000 ; Ch. A IRQ flags mask
|
||||
|
||||
BaudTable: ; bit7 = 1 means setting is invalid
|
||||
; Otherwise refers to the index in
|
||||
; Baud(Low/High)Table
|
||||
.byte $FF ; SER_BAUD_45_5
|
||||
.byte $FF ; SER_BAUD_50
|
||||
.byte $FF ; SER_BAUD_75
|
||||
.byte $FF ; SER_BAUD_110
|
||||
.byte $FF ; SER_BAUD_134_5
|
||||
.byte $FF ; SER_BAUD_150
|
||||
.byte $00 ; SER_BAUD_300
|
||||
.byte $FF ; SER_BAUD_600
|
||||
.byte $01 ; SER_BAUD_1200
|
||||
.byte $FF ; SER_BAUD_1800
|
||||
.byte $02 ; SER_BAUD_2400
|
||||
.byte $FF ; SER_BAUD_3600
|
||||
.byte $03 ; SER_BAUD_4800
|
||||
.byte $FF ; SER_BAUD_7200
|
||||
.byte $04 ; SER_BAUD_9600
|
||||
.byte $05 ; SER_BAUD_19200
|
||||
.byte $06 ; SER_BAUD_38400
|
||||
.byte $07 ; SER_BAUD_57600
|
||||
.byte $FF ; SER_BAUD_115200
|
||||
.byte $FF ; SER_BAUD_230400
|
||||
; Indexes cc65 RS232 SER_BAUD enum
|
||||
; into WR12/13 register values
|
||||
; (Ref page 5-18 and 5-19)
|
||||
.word $FFFF ; SER_BAUD_45_5
|
||||
.word $FFFF ; SER_BAUD_50
|
||||
.word $FFFF ; SER_BAUD_75
|
||||
.word $FFFF ; SER_BAUD_110
|
||||
.word $FFFF ; SER_BAUD_134_5
|
||||
.word $FFFF ; SER_BAUD_150
|
||||
.word $017E ; SER_BAUD_300
|
||||
.word $FFFF ; SER_BAUD_600
|
||||
.word $005E ; SER_BAUD_1200
|
||||
.word $FFFF ; SER_BAUD_1800
|
||||
.word $002E ; SER_BAUD_2400
|
||||
.word $FFFF ; SER_BAUD_3600
|
||||
.word $0016 ; SER_BAUD_4800
|
||||
.word $FFFF ; SER_BAUD_7200
|
||||
.word $000A ; SER_BAUD_9600
|
||||
.word $0004 ; SER_BAUD_19200
|
||||
.word $0001 ; SER_BAUD_38400
|
||||
.word $0000 ; SER_BAUD_57600
|
||||
.word $0000 ; SER_BAUD_115200 (constant unused at that speed)
|
||||
.word $FFFF ; SER_BAUD_230400
|
||||
|
||||
; About the speed selection: either we use the baud rate generator:
|
||||
; - Load the time constants from BaudTable into WR12/WR13
|
||||
; - Setup the TX/RX clock source to BRG (ClockSource into WR11)
|
||||
; - Setup the clock multiplier (WR4)
|
||||
; - Enable the baud rate generator (WR14)
|
||||
; In this case, the baud rate will be:
|
||||
; rate = crystal_clock/(2+BRG_time_constant))/(2*clock_multiplier)
|
||||
; Example: (3686400/(2+0x0004)) / (2*16) = 19200 bps
|
||||
;
|
||||
; Or we don't use the baud rate generator:
|
||||
; - Setup the TX/RX clock source to RTxC
|
||||
; - Setup the clock multiplier
|
||||
; - Disable the baud rate generator
|
||||
; - WR12 and 13 are ignored
|
||||
; In this case, the baud rate will be:
|
||||
; rate = crystal_clock/clock_multiplier
|
||||
; Example: 3686400/32 = 115200 bps
|
||||
|
||||
StopTable: .byte %00000100 ; SER_STOP_1, in WR_TX_RX_CTRL (WR4)
|
||||
.byte %00001100 ; SER_STOP_2 (Ref page 5-8)
|
||||
@@ -156,6 +174,7 @@ SER_FLAG := $E10104
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Channels
|
||||
|
||||
CHANNEL_B = 0
|
||||
CHANNEL_A = 1
|
||||
|
||||
@@ -180,7 +199,6 @@ RX_CTRL_OFF = %11111110 ; ANDed,Rx disabled
|
||||
|
||||
WR_TX_RX_CTRL = 4
|
||||
RR_TX_RX_STATUS = 4
|
||||
TX_RX_CLOCK_MUL = %01000000 ; Clock x16 (Ref page 5-8)
|
||||
|
||||
WR_TX_CTRL = 5 ; (Ref page 5-9)
|
||||
RR_TX_STATUS = 5 ; Corresponding status register
|
||||
@@ -197,15 +215,11 @@ MASTER_IRQ_MIE_RST = %00001010 ; STA'd
|
||||
MASTER_IRQ_SET = %00011001 ; STA'd
|
||||
|
||||
WR_CLOCK_CTRL = 11 ; (Ref page 5-17)
|
||||
CLOCK_CTRL_CH_A = %11010000
|
||||
CLOCK_CTRL_CH_B = %01010000
|
||||
|
||||
WR_BAUDL_CTRL = 12 ; (Ref page 5-18)
|
||||
WR_BAUDH_CTRL = 13 ; (Ref page 5-19)
|
||||
|
||||
WR_MISC_CTRL = 14 ; (Ref page 5-19)
|
||||
MISC_CTRL_RATE_GEN_ON = %00000001 ; ORed
|
||||
MISC_CTRL_RATE_GEN_OFF = %11111110 ; ANDed
|
||||
|
||||
WR_IRQ_CTRL = 15 ; (Ref page 5-20)
|
||||
IRQ_CLEANUP_EIRQ = %00001000
|
||||
@@ -220,13 +234,8 @@ IRQ_RX = %00100000
|
||||
IRQ_SPECIAL = %01100000
|
||||
|
||||
RR_INTR_PENDING_STATUS = 3 ; (Ref page 5-25)
|
||||
INTR_PENDING_RX_EXT_A = %00101000 ; ANDed (RX or special IRQ)
|
||||
INTR_PENDING_RX_EXT_B = %00000101 ; ANDed (RX or special IRQ)
|
||||
INTR_IS_RX = %00100100 ; ANDed (RX IRQ, channel A or B)
|
||||
|
||||
SER_FLAG_CH_A = %00111000
|
||||
SER_FLAG_CH_B = %00000111
|
||||
|
||||
.code
|
||||
|
||||
; Read register value to A.
|
||||
@@ -329,6 +338,15 @@ IIgs:
|
||||
: txa ; Promote char return value
|
||||
rts
|
||||
|
||||
getClockSource:
|
||||
.assert SER_PARAMS::BAUDRATE = 0, error
|
||||
lda (ptr1) ; Baudrate index - cc65 value
|
||||
cmp #SER_BAUD_115200
|
||||
lda #$00
|
||||
adc #$00
|
||||
sta CurClockSource ; 0 = BRG, 1 = RTxC
|
||||
rts
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SER_OPEN: A pointer to a ser_params structure is passed in ptr1.
|
||||
; Must return an SER_ERR_xx code in a/x.
|
||||
@@ -360,11 +378,13 @@ SER_OPEN:
|
||||
ldy #RR_INIT_STATUS ; Hit rr0 once to sync up
|
||||
jsr readSSCReg
|
||||
|
||||
ldy #WR_MISC_CTRL ; Turn everything off
|
||||
ldy #WR_MISC_CTRL ; WR14: Turn everything off
|
||||
lda #$00
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #SER_PARAMS::STOPBITS
|
||||
jsr getClockSource ; Should we use BRG or RTxC?
|
||||
|
||||
ldy #SER_PARAMS::STOPBITS ; WR4 setup: clock mult., stop & parity
|
||||
lda (ptr1),y ; Stop bits
|
||||
tay
|
||||
lda StopTable,y ; Get value
|
||||
@@ -377,36 +397,33 @@ SER_OPEN:
|
||||
ora ParityTable,y ; Get value
|
||||
bmi InvParam
|
||||
|
||||
ora #TX_RX_CLOCK_MUL
|
||||
ldy CurClockSource ; Clock multiplier
|
||||
ora ClockMultiplier,y
|
||||
|
||||
ldy #WR_TX_RX_CTRL ; Setup stop & parity bits
|
||||
jsr writeSCCReg
|
||||
ldy #WR_TX_RX_CTRL
|
||||
jsr writeSCCReg ; End of WR4 setup
|
||||
|
||||
ldy CurClockSource ; WR11 setup: clock source
|
||||
cpx #CHANNEL_B
|
||||
bne ClockA
|
||||
ClockB:
|
||||
beq SetClock
|
||||
iny ; Shift to get correct ClockSource val
|
||||
iny ; depending on our channel
|
||||
|
||||
SetClock:
|
||||
lda ClockSource,y
|
||||
ldy #WR_CLOCK_CTRL
|
||||
lda #CLOCK_CTRL_CH_B
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg ; End of WR11 setup
|
||||
|
||||
lda #INTR_PENDING_RX_EXT_B ; Store which IRQ bits we'll check
|
||||
sta CurChanIrqFlags
|
||||
|
||||
bra SetBaud
|
||||
ClockA:
|
||||
ldy #WR_CLOCK_CTRL
|
||||
lda #CLOCK_CTRL_CH_A
|
||||
jsr writeSCCReg
|
||||
|
||||
lda #INTR_PENDING_RX_EXT_A ; Store which IRQ bits we'll check
|
||||
lda ChanIrqFlags,x ; Store which IRQ bits we'll check
|
||||
sta CurChanIrqFlags
|
||||
|
||||
SetBaud:
|
||||
ldy #SER_PARAMS::BAUDRATE
|
||||
lda (ptr1),y ; Baudrate index - cc65 value
|
||||
.assert SER_PARAMS::BAUDRATE = 0, error
|
||||
lda (ptr1) ; Baudrate index - cc65 value
|
||||
asl
|
||||
tay
|
||||
|
||||
lda BaudTable,y ; Get chip value from Low/High tables
|
||||
lda BaudTable,y ; Get low byte of register value
|
||||
bpl BaudOK ; Verify baudrate is supported
|
||||
|
||||
InvParam:
|
||||
@@ -415,59 +432,57 @@ InvParam:
|
||||
bra SetupOut
|
||||
|
||||
BaudOK:
|
||||
tay
|
||||
|
||||
lda BaudLowTable,y ; Get low byte
|
||||
|
||||
phy
|
||||
ldy #WR_BAUDL_CTRL
|
||||
jsr writeSCCReg
|
||||
phy ; WR12 setup: BRG time constant, low byte
|
||||
ldy #WR_BAUDL_CTRL ; Setting WR12 & 13 is useless if we're using
|
||||
jsr writeSCCReg ; RTxC, but doing it anyway makes code smaller
|
||||
ply
|
||||
|
||||
lda BaudHighTable,y ; Get high byte
|
||||
iny
|
||||
lda BaudTable,y ; WR13 setup: BRG time constant, high byte
|
||||
ldy #WR_BAUDH_CTRL
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy CurClockSource ; WR14 setup: BRG enabling
|
||||
lda BrgEnabled,y
|
||||
ldy #WR_MISC_CTRL ; Time to turn this thing on
|
||||
lda #MISC_CTRL_RATE_GEN_ON
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #SER_PARAMS::DATABITS
|
||||
lda (ptr1),y ; Data bits
|
||||
ldy #SER_PARAMS::DATABITS ; WR3 setup: RX data bits
|
||||
lda (ptr1),y
|
||||
tay
|
||||
lda RxBitTable,y ; Data bits for RX
|
||||
ora #RX_CTRL_ON ; and turn RX on
|
||||
lda RxBitTable,y
|
||||
ora #RX_CTRL_ON ; and turn receiver on
|
||||
|
||||
phy
|
||||
ldy #WR_RX_CTRL
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg ; End of WR3 setup
|
||||
ply
|
||||
|
||||
lda TxBitTable,y ; Data bits for TX
|
||||
ora #TX_CTRL_ON ; and turn TX on
|
||||
and #TX_DTR_ON
|
||||
lda TxBitTable,y ; WR5 setup: TX data bits
|
||||
ora #TX_CTRL_ON ; and turn transmitter on
|
||||
and #TX_DTR_ON ; and turn DTR on
|
||||
|
||||
sta RtsOff ; Save value for flow control
|
||||
|
||||
ora #TX_RTS_ON
|
||||
ora #TX_RTS_ON ; and turn RTS on
|
||||
|
||||
ldy #WR_TX_CTRL
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg ; End of WR5 setup
|
||||
|
||||
ldy #WR_IRQ_CTRL
|
||||
ldy #WR_IRQ_CTRL ; WR15 setup: IRQ
|
||||
lda #IRQ_CLEANUP_EIRQ
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #WR_INIT_CTRL ; Clear ext status (write twice)
|
||||
ldy #WR_INIT_CTRL ; WR0 setup: clear existing IRQs
|
||||
lda #INIT_CTRL_CLEAR_EIRQ
|
||||
jsr writeSCCReg
|
||||
jsr writeSCCReg ; Clear (write twice)
|
||||
jsr writeSCCReg
|
||||
|
||||
ldy #WR_TX_RX_MODE_CTRL ; Activate RX IRQ
|
||||
ldy #WR_TX_RX_MODE_CTRL ; WR1 setup: Activate RX IRQ
|
||||
lda #TX_RX_MODE_RXIRQ
|
||||
jsr writeSCCReg
|
||||
|
||||
lda SCCBREG ; Activate master IRQ
|
||||
lda SCCBREG ; WR9 setup: Activate master IRQ
|
||||
ldy #WR_MASTER_IRQ_RST
|
||||
lda #MASTER_IRQ_SET
|
||||
jsr writeSCCReg
|
||||
@@ -475,14 +490,7 @@ BaudOK:
|
||||
lda SER_FLAG ; Get SerFlag's current value
|
||||
sta SerFlagOrig ; and save it
|
||||
|
||||
cpx #CHANNEL_B
|
||||
bne IntA
|
||||
IntB:
|
||||
ora #SER_FLAG_CH_B ; Inform firmware we want channel B IRQs
|
||||
bra StoreFlag
|
||||
IntA:
|
||||
ora #SER_FLAG_CH_A ; Inform firmware we want channel A IRQs
|
||||
StoreFlag:
|
||||
ora ChanIrqMask,x ; Tell firmware which channel IRQs we want
|
||||
sta SER_FLAG
|
||||
|
||||
ldy #$01 ; Mark port opened
|
||||
|
||||
@@ -121,7 +121,7 @@ BaudTable: ; Table used to translate RS232 baudrate param
|
||||
.byte $0F ; SER_BAUD_19200
|
||||
.byte $FF ; SER_BAUD_38400
|
||||
.byte $FF ; SER_BAUD_57600
|
||||
.byte $FF ; SER_BAUD_115200
|
||||
.byte $00 ; SER_BAUD_115200
|
||||
.byte $FF ; SER_BAUD_230400
|
||||
|
||||
BitTable: ; Table used to translate RS232 databits param
|
||||
@@ -302,6 +302,7 @@ HandshakeOK:
|
||||
lda (ptr1),y ; Baudrate index
|
||||
tay
|
||||
lda BaudTable,y ; Get 6551 value
|
||||
sta tmp2 ; Backup for IRQ setting
|
||||
bpl BaudOK ; Check that baudrate is supported
|
||||
|
||||
lda #SER_ERR_BAUD_UNAVAIL
|
||||
@@ -332,8 +333,13 @@ BaudOK: sta tmp1
|
||||
|
||||
ora #%00000001 ; Set DTR active
|
||||
sta RtsOff ; Store value to easily handle flow control later
|
||||
ora #%00001000 ; Enable receive interrupts (RTS low)
|
||||
sta ACIA_CMD,x
|
||||
|
||||
ora #%00001010 ; Disable interrupts and set RTS low
|
||||
|
||||
ldy tmp2 ; Don't enable IRQs if 115200bps
|
||||
beq :+
|
||||
and #%11111101 ; Enable receive IRQs
|
||||
: sta ACIA_CMD,x
|
||||
|
||||
; Done
|
||||
stx Index ; Mark port as open
|
||||
|
||||
9
libsrc/apple2/uppercasemask.s
Normal file
9
libsrc/apple2/uppercasemask.s
Normal file
@@ -0,0 +1,9 @@
|
||||
;
|
||||
; Oliver Schmidt, 2024-08-06
|
||||
;
|
||||
|
||||
.export uppercasemask
|
||||
|
||||
.data
|
||||
|
||||
uppercasemask: .byte $DF ; Convert to uppercase
|
||||
@@ -7,6 +7,9 @@
|
||||
.export _write
|
||||
.import rwprolog, rwcommon, rwepilog
|
||||
.import COUT
|
||||
.ifndef __APPLE2ENH__
|
||||
.import uppercasemask
|
||||
.endif
|
||||
|
||||
.include "zeropage.inc"
|
||||
.include "errno.inc"
|
||||
@@ -84,7 +87,7 @@ next: lda (ptr1),y
|
||||
.ifndef __APPLE2ENH__
|
||||
cmp #$E0 ; Test for lowercase
|
||||
bcc output
|
||||
and #$DF ; Convert to uppercase
|
||||
and uppercasemask
|
||||
.endif
|
||||
output: jsr COUT ; Preserves X and Y
|
||||
|
||||
|
||||
@@ -53,13 +53,20 @@ JOY_COUNT = 2 ; Number of joysticks we support
|
||||
; Must return an JOY_ERR_xx code in a/x.
|
||||
;
|
||||
|
||||
PB2 = $04 ; Joystick 0
|
||||
PB4 = $10 ; Joystick 1
|
||||
|
||||
INSTALL:
|
||||
; Assume 7800 2-button controller, can change
|
||||
; to 2600 1-button later
|
||||
lda #$14
|
||||
sta CTLSWB ; enable 2-button 7800 controller 1: set pin 6 to output
|
||||
lda #(PB2 | PB4)
|
||||
; enable 2-button 7800 controllers on both ports
|
||||
; by setting PB2 and PB4 to output
|
||||
sta CTLSWB
|
||||
; enable 2-button 7800 controllers by setting
|
||||
; the outputs to 0; (INPT4 and INPT5) high
|
||||
ldy #$00
|
||||
sty SWCHB ; enable 2-button 7800 controller 2: pull pin 6 (INPT4) high
|
||||
sty SWCHB
|
||||
|
||||
reset:
|
||||
lda #JOY_ERR_OK
|
||||
@@ -88,6 +95,28 @@ COUNT:
|
||||
; ------------------------------------------------------------------------
|
||||
; READ: Read a particular joystick passed in A for 2 fire buttons.
|
||||
|
||||
readdualbuttons0:
|
||||
ldy #0 ; ........
|
||||
bit INPT0 ; Check for right button
|
||||
bpl L1
|
||||
ldy #2 ; ......2.
|
||||
L1: bit INPT1 ; Check for left button
|
||||
bpl L2
|
||||
iny ; ......21
|
||||
L2: tya
|
||||
rts
|
||||
|
||||
readdualbuttons1:
|
||||
ldy #0 ; ........
|
||||
bit INPT2 ; Check for right button
|
||||
bpl L1
|
||||
ldy #2 ; ......2.
|
||||
L3: bit INPT3 ; Check for left button
|
||||
bpl L2
|
||||
iny ; ......21
|
||||
L4: tya
|
||||
rts
|
||||
|
||||
readbuttons:
|
||||
; Y has joystick of interest 0/1
|
||||
; return value:
|
||||
@@ -97,42 +126,48 @@ readbuttons:
|
||||
; $03: both buttons
|
||||
; preserves X
|
||||
tya
|
||||
beq L5
|
||||
beq readbuttons0
|
||||
readbuttons1:
|
||||
; Joystick 1 processing
|
||||
; 7800 joystick 1 buttons
|
||||
ldy #0 ; ........
|
||||
bit INPT2 ; Check for right button
|
||||
bpl L1
|
||||
ldy #2 ; ......2.
|
||||
L1: bit INPT3 ;Check for left button
|
||||
bpl L2
|
||||
iny ; ......21
|
||||
L2: tya
|
||||
bne L4 ; 7800 mode joystick worked
|
||||
; 2600 Joystick 1
|
||||
; Start by checking for single button 2600 joystick
|
||||
bit INPT5
|
||||
bmi L4
|
||||
L3: iny ; .......1
|
||||
lda #0 ; Fallback to 2600 joystick mode
|
||||
sta CTLSWB
|
||||
L4: tya ; ......21
|
||||
bpl singlebtn1detected
|
||||
jmp readdualbuttons1
|
||||
singlebtn1detected:
|
||||
; Single button joystick detected but could be dual
|
||||
jsr readdualbuttons1
|
||||
bne L5 ; It was a dual button press
|
||||
; It was a single button press
|
||||
bit INPT5
|
||||
bmi L5
|
||||
iny ; .......1
|
||||
lda #PB4 ; Joystick 1 is a single button unit
|
||||
clc
|
||||
adc SWCHB
|
||||
sta SWCHB ; Cut power from the dual button circuit
|
||||
L5: tya ; ......21
|
||||
rts
|
||||
|
||||
L5: ; Joystick 0 processing
|
||||
; 7800 joystick 0 buttons
|
||||
ldy #0 ; ........
|
||||
bit INPT0 ; Check for right button
|
||||
bpl L6
|
||||
ldy #2 ; ......2.
|
||||
L6: bit INPT1 ;Check for left button
|
||||
bpl L7
|
||||
iny ; ......21
|
||||
L7: tya
|
||||
bne L4 ; 7800 mode joystick worked
|
||||
; 2600 Joystick 0
|
||||
readbuttons0:
|
||||
; Joystick 0 processing
|
||||
; Start by checking for single button 2600 joystick
|
||||
bit INPT4
|
||||
bmi L4
|
||||
bpl L3
|
||||
bpl singlebtn0detected
|
||||
jmp readdualbuttons0
|
||||
singlebtn0detected:
|
||||
; Single button joystick detected but could be dual
|
||||
jsr readdualbuttons0
|
||||
bne L6 ; It was a dual button press
|
||||
; It was a single button press
|
||||
bit INPT4
|
||||
bmi L6
|
||||
iny ; .......1
|
||||
lda #PB2 ; Joystick 0 is a single button unit
|
||||
clc
|
||||
adc SWCHB
|
||||
sta SWCHB ; Cut power from the dual button circuit
|
||||
L6: tya ; ......21
|
||||
rts
|
||||
|
||||
READ:
|
||||
tay ; Store joystick 0/1 in Y
|
||||
|
||||
18
libsrc/atmos/waitvsync.s
Normal file
18
libsrc/atmos/waitvsync.s
Normal file
@@ -0,0 +1,18 @@
|
||||
;
|
||||
; Written by Stefan Haubenthal <polluks@sdf.org>, requires VSync hack
|
||||
;
|
||||
; void waitvsync (void);
|
||||
;
|
||||
|
||||
.export _waitvsync
|
||||
|
||||
.include "atmos.inc"
|
||||
|
||||
.proc _waitvsync
|
||||
|
||||
lda #%00010000 ; CB1
|
||||
wait: and VIA::PRA2
|
||||
bne wait
|
||||
rts
|
||||
|
||||
.endproc
|
||||
@@ -23,8 +23,8 @@ _waitvsync:
|
||||
|
||||
@c80:
|
||||
;FIXME: do we have to switch banks?
|
||||
lda #$20
|
||||
@l3:
|
||||
lda VDC_INDEX
|
||||
and #$20
|
||||
and VDC_INDEX
|
||||
beq @l3
|
||||
rts
|
||||
|
||||
22
libsrc/common/stpcpy.s
Normal file
22
libsrc/common/stpcpy.s
Normal file
@@ -0,0 +1,22 @@
|
||||
;
|
||||
; Colin Leroy-Mira, 4 Sept. 2024
|
||||
;
|
||||
; char* stpcpy (char* dest, const char* src);
|
||||
;
|
||||
|
||||
.export _stpcpy
|
||||
.import _strcpy
|
||||
|
||||
.importzp tmp1, ptr2
|
||||
|
||||
_stpcpy:
|
||||
jsr _strcpy
|
||||
|
||||
ldx ptr2+1 ; Load dest pointer's last high byte
|
||||
tya ; Get the last offset strcpy wrote to
|
||||
|
||||
clc
|
||||
adc ptr2 ; Add to low byte value
|
||||
bcc :+
|
||||
inx
|
||||
: rts ; Return pointer to dest's terminator
|
||||
95
libsrc/common/strcasestr.s
Normal file
95
libsrc/common/strcasestr.s
Normal file
@@ -0,0 +1,95 @@
|
||||
;
|
||||
; Ullrich von Bassewitz, 11.12.1998
|
||||
;
|
||||
; char* strcasestr (const char* haystack, const char* needle);
|
||||
;
|
||||
|
||||
.export _strcasestr
|
||||
.import popptr1, return0, tolowerdirect
|
||||
.importzp ptr1, ptr2, ptr3, ptr4, tmp1, tmp2, tmp3, tmp4
|
||||
.include "ctype.inc"
|
||||
|
||||
.segment "LOWCODE"
|
||||
|
||||
_strcasestr:
|
||||
sta ptr2 ; Save needle
|
||||
stx ptr2+1
|
||||
sta ptr4 ; Setup temp copy for later
|
||||
|
||||
jsr popptr1 ; Get haystack to ptr1
|
||||
|
||||
; If needle is empty, return haystack
|
||||
|
||||
; ldy #$00 Y=0 guaranteed by popptr1
|
||||
lda (ptr2),y ; Get first byte of needle
|
||||
beq @Found ; Needle is empty --> we're done
|
||||
|
||||
; Search for the beginning of the string (this is not an optimal search
|
||||
; strategy [in fact, it's pretty dumb], but it's simple to implement).
|
||||
|
||||
jsr tolowerdirect ; Lowercase
|
||||
sta tmp1 ; Save start of needle
|
||||
@L1: lda (ptr1),y ; Get next char from haystack
|
||||
beq @NotFound ; Jump if end
|
||||
|
||||
jsr tolowerdirect ; Lowercase
|
||||
cmp tmp1 ; Start of needle found?
|
||||
beq @L2 ; Jump if so
|
||||
iny ; Next char
|
||||
bne @L1
|
||||
inc ptr1+1 ; Bump high byte
|
||||
bne @L1 ; Branch always
|
||||
|
||||
; We found the start of needle in haystack
|
||||
|
||||
@L2: tya ; Get offset
|
||||
clc
|
||||
adc ptr1
|
||||
sta ptr1 ; Make ptr1 point to start
|
||||
bcc @L3
|
||||
inc ptr1+1
|
||||
|
||||
; ptr1 points to the start of needle in haystack now. Setup temporary pointers for the
|
||||
; search. The low byte of ptr4 is already set.
|
||||
|
||||
@L3: sta ptr3
|
||||
lda ptr1+1
|
||||
sta ptr3+1
|
||||
lda ptr2+1
|
||||
sta ptr4+1
|
||||
ldy #1 ; First char is identical, so start on second
|
||||
|
||||
; Do the compare
|
||||
|
||||
@L4: lda (ptr4),y ; Get char from needle
|
||||
beq @Found ; Jump if end of needle (-> found)
|
||||
|
||||
jsr tolowerdirect ; Lowercase
|
||||
sta tmp2
|
||||
|
||||
lda (ptr3),y ; Compare with haystack
|
||||
|
||||
jsr tolowerdirect ; Lowercase
|
||||
cmp tmp2
|
||||
bne @L5 ; Jump if not equal
|
||||
iny ; Next char
|
||||
bne @L4
|
||||
inc ptr3+1
|
||||
inc ptr4+1 ; Bump hi byte of pointers
|
||||
bne @L4 ; Next char (branch always)
|
||||
|
||||
; The strings did not compare equal, search next start of needle
|
||||
|
||||
@L5: ldy #1 ; Start after this char
|
||||
bne @L1 ; Branch always
|
||||
|
||||
; We found the start of needle
|
||||
|
||||
@Found: lda ptr1
|
||||
ldx ptr1+1
|
||||
rts
|
||||
|
||||
; We reached end of haystack without finding needle
|
||||
|
||||
@NotFound:
|
||||
jmp return0 ; return NULL
|
||||
@@ -25,6 +25,9 @@ L1: lda (ptr1),y
|
||||
inc ptr2+1
|
||||
bne L1
|
||||
|
||||
L9: lda ptr2 ; X still contains high byte
|
||||
rts
|
||||
L9: lda ptr2 ; X still contains dest's original high byte
|
||||
|
||||
; On exit, we want AX to be dest (as this is what strcpy returns).
|
||||
; We also want (ptr2),y to still point to dest's terminator, as this
|
||||
; is used by stpcpy().
|
||||
rts
|
||||
|
||||
@@ -82,14 +82,3 @@ _strstr:
|
||||
lda #$00 ; return NULL
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
.export _time
|
||||
|
||||
.import decsp1, ldeaxi
|
||||
.import pusha, ldeaxi
|
||||
.importzp ptr1, sreg, tmp1, tmp2
|
||||
|
||||
.include "time.inc"
|
||||
@@ -22,54 +22,50 @@
|
||||
|
||||
; Get the time (machine dependent)
|
||||
|
||||
jsr decsp1
|
||||
.assert timespec::tv_sec = 0, error
|
||||
lda #CLOCK_REALTIME
|
||||
jsr pusha
|
||||
lda #<time
|
||||
ldx #>time
|
||||
jsr _clock_gettime
|
||||
sta tmp2
|
||||
lda #<time
|
||||
ldx #>time
|
||||
.assert timespec::tv_sec = 0, error
|
||||
jsr ldeaxi
|
||||
sta tmp1 ; Save low byte of result
|
||||
|
||||
; _clock_gettime returns 0 on success and -1 on error. Check that.
|
||||
|
||||
inx ; Did _clock_gettime return -1?
|
||||
bne @L2 ; Jump if not
|
||||
|
||||
; We had an error so invalidate time. A contains $FF.
|
||||
|
||||
ldy #3
|
||||
@L1: sta time,y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
; Restore timep and check if it is NULL
|
||||
|
||||
pla
|
||||
@L2: pla
|
||||
sta ptr1+1
|
||||
pla
|
||||
sta ptr1 ; Restore timep
|
||||
ora ptr1+1 ; timep == 0?
|
||||
beq @L1
|
||||
beq @L4
|
||||
|
||||
; timep is not NULL, store the result there
|
||||
|
||||
ldy #3
|
||||
lda sreg+1
|
||||
@L3: lda time,y
|
||||
sta (ptr1),y
|
||||
dey
|
||||
lda sreg
|
||||
sta (ptr1),y
|
||||
dey
|
||||
txa
|
||||
sta (ptr1),y
|
||||
dey
|
||||
lda tmp1
|
||||
sta (ptr1),y
|
||||
bpl @L3
|
||||
|
||||
; If the result is != 0, return -1
|
||||
; Load the final result.
|
||||
|
||||
@L1: lda tmp2
|
||||
beq @L2
|
||||
|
||||
tax
|
||||
sta sreg
|
||||
@L4: lda time+3
|
||||
sta sreg+1
|
||||
rts
|
||||
|
||||
; Reload the low byte of the result and return
|
||||
|
||||
@L2: lda tmp1
|
||||
lda time+2
|
||||
sta sreg
|
||||
ldx time+1
|
||||
lda time
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
@@ -10,19 +10,20 @@
|
||||
; int tolower (int c);
|
||||
;
|
||||
|
||||
.export _tolower
|
||||
.export _tolower, tolowerdirect
|
||||
.include "ctype.inc"
|
||||
.import ctypemaskdirect
|
||||
|
||||
_tolower:
|
||||
cpx #$00 ; out of range?
|
||||
bne @L2 ; if so, return the argument unchanged
|
||||
tay ; save char
|
||||
bne out ; if so, return the argument unchanged
|
||||
tolowerdirect:
|
||||
pha ; save char
|
||||
jsr ctypemaskdirect ; get character classification
|
||||
and #CT_UPPER ; upper case char?
|
||||
beq @L1 ; jump if no
|
||||
tya ; restore char
|
||||
pla ; restore char
|
||||
adc #<('a'-'A') ; make lower case char (ctypemaskdirect ensures carry clear)
|
||||
rts
|
||||
@L1: tya ; restore char
|
||||
@L2: rts
|
||||
@L1: pla ; restore char
|
||||
out: rts
|
||||
|
||||
675
libsrc/cx16/tgi/cx640p1.s
Normal file
675
libsrc/cx16/tgi/cx640p1.s
Normal file
@@ -0,0 +1,675 @@
|
||||
;
|
||||
; Graphics driver for the 640 pixels across, 480 pixels down, 2 color mode
|
||||
; on the Commander X16
|
||||
;
|
||||
; 2024-06-11, Scott Hutter
|
||||
; Based on code by Greg King
|
||||
;
|
||||
|
||||
.include "zeropage.inc"
|
||||
|
||||
.include "tgi-kernel.inc"
|
||||
.include "tgi-error.inc"
|
||||
|
||||
.include "cbm_kernal.inc"
|
||||
.include "cx16.inc"
|
||||
|
||||
.macpack generic
|
||||
.macpack module
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Header. Includes jump table and constants.
|
||||
|
||||
module_header _cx640p1_tgi ; 640 pixels across, 1 pixel per bit
|
||||
|
||||
; First part of the header is a structure that has a signature,
|
||||
; and defines the capabilities of the driver.
|
||||
|
||||
.byte $74, $67, $69 ; ASCII "tgi"
|
||||
.byte TGI_API_VERSION ; TGI API version number
|
||||
.addr $0000 ; Library reference
|
||||
.word 640 ; X resolution
|
||||
.word 480 ; Y resolution
|
||||
.byte 2 ; Number of drawing colors
|
||||
.byte 0 ; Number of screens available
|
||||
.byte 8 ; System font X size
|
||||
.byte 8 ; System font Y size
|
||||
.word $0100 ; Aspect ratio (based on VGA display)
|
||||
.byte 0 ; TGI driver flags
|
||||
|
||||
; Next, comes the jump table. Currently, all entries must be valid,
|
||||
; and may point to an RTS for test versions (function not implemented).
|
||||
|
||||
.addr INSTALL
|
||||
.addr UNINSTALL
|
||||
.addr INIT
|
||||
.addr DONE
|
||||
.addr GETERROR
|
||||
.addr CONTROL
|
||||
.addr CLEAR
|
||||
.addr SETVIEWPAGE
|
||||
.addr SETDRAWPAGE
|
||||
.addr SETCOLOR
|
||||
.addr SETPALETTE
|
||||
.addr GETPALETTE
|
||||
.addr GETDEFPALETTE
|
||||
.addr SETPIXEL
|
||||
.addr GETPIXEL
|
||||
.addr LINE
|
||||
.addr BAR
|
||||
.addr TEXTSTYLE
|
||||
.addr OUTTEXT
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Constant
|
||||
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Data.
|
||||
|
||||
; Variables mapped to the zero page segment variables. Some of these are
|
||||
; used for passing parameters to the driver.
|
||||
|
||||
X1 = ptr1
|
||||
Y1 = ptr2
|
||||
X2 = ptr3
|
||||
Y2 = ptr4
|
||||
|
||||
ADDR = tmp1 ; ADDR+1,2,3
|
||||
|
||||
TEMP = tmp3
|
||||
TEMP2 = tmp4 ; HORLINE
|
||||
TEMP3 = sreg ; HORLINE
|
||||
|
||||
|
||||
; Absolute variables used in the code
|
||||
|
||||
.bss
|
||||
|
||||
; The colors are indicies into a TGI palette. The TGI palette is indicies into
|
||||
; VERA's palette. Vera's palette is a table of Red, Green, and Blue levels.
|
||||
; The first 16 RGB elements mimic the Commodore 64's colors.
|
||||
|
||||
SCRBASE: .res 1 ; High byte of screen base
|
||||
BITMASK: .res 1 ; $00 = clear, $FF = set pixels
|
||||
|
||||
defpalette: .res 2
|
||||
palette: .res 2
|
||||
|
||||
color: .res 1 ; Stroke and fill index
|
||||
text_mode: .res 1 ; Old text mode
|
||||
|
||||
tempX: .res 2
|
||||
tempY: .res 2
|
||||
ERR2: .res 1
|
||||
ERR: .res 1
|
||||
SY: .res 1
|
||||
SX: .res 1
|
||||
DY: .res 1
|
||||
DX: .res 1
|
||||
CURRENT_Y: .res 2
|
||||
CURRENT_X: .res 2
|
||||
|
||||
.data
|
||||
|
||||
ERROR: .byte TGI_ERR_OK ; Error code
|
||||
|
||||
|
||||
; Constants and tables
|
||||
|
||||
.rodata
|
||||
|
||||
veracolors:
|
||||
col_black: .byte %00000000, %00000000
|
||||
col_white: .byte %11111111, %00001111
|
||||
col_red: .byte %00000000, %00001000
|
||||
col_cyan: .byte %11111110, %00001010
|
||||
col_purple: .byte %01001100, %00001100
|
||||
col_green: .byte %11000101, %00000000
|
||||
col_blue: .byte %00001010, %00000000
|
||||
col_yellow: .byte %11100111, %00001110
|
||||
col_orange: .byte %10000101, %00001101
|
||||
col_brown: .byte %01000000, %00000110
|
||||
col_lred: .byte %01110111, %00001111
|
||||
col_gray1: .byte %00110011, %00000011
|
||||
col_gray2: .byte %01110111, %00000111
|
||||
col_lgreen: .byte %11110110, %00001010
|
||||
col_lblue: .byte %10001111, %00000000
|
||||
col_gray3: .byte %10111011, %00001011
|
||||
|
||||
; Bit masks for setting pixels
|
||||
bitMasks1:
|
||||
.byte %10000000, %01000000, %00100000, %00010000
|
||||
.byte %00001000, %00000100, %00000010, %00000001
|
||||
bitMasks2:
|
||||
.byte %01111111, %10111111, %11011111, %11101111
|
||||
.byte %11110111, %11111011, %11111101, %11111110
|
||||
|
||||
|
||||
.code
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; INSTALL routine. Is called after the driver is loaded into memory. May
|
||||
; initialize anything that has to be done just once. Is probably empty
|
||||
; most of the time.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
INSTALL:
|
||||
; Create the default palette.
|
||||
lda #$00
|
||||
sta defpalette
|
||||
lda #$01
|
||||
sta defpalette+1
|
||||
|
||||
; Fall through.
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; UNINSTALL routine. Is called before the driver is removed from memory. May
|
||||
; clean up anything done by INSTALL, but is probably empty most of the time.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
UNINSTALL:
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; INIT: Changes an already installed device from text mode to graphics
|
||||
; mode.
|
||||
; Note that INIT/DONE may be called multiple times while the driver
|
||||
; is loaded, while INSTALL is called only once; so, any code that is needed
|
||||
; to initiate variables and so on must go here. Setting the palette is not
|
||||
; needed because that is called by the graphics kernel later.
|
||||
; The graphics kernel never will call INIT when a graphics mode already is
|
||||
; active, so there is no need to protect against that.
|
||||
;
|
||||
; Must set an error code: YES
|
||||
|
||||
INIT: stz ERROR ; #TGI_ERR_OK
|
||||
|
||||
; Save the current text mode.
|
||||
|
||||
sec
|
||||
jsr SCREEN_MODE
|
||||
sta text_mode
|
||||
|
||||
; Switch into (640 x 480 x 2 bpp) graphics mode.
|
||||
|
||||
lda #%00000000 ; DCSEL = 0, VRAM port 1
|
||||
sta VERA::CTRL
|
||||
lda #%00100001 ; Disable sprites, layer 1 enable, VGA
|
||||
sta VERA::DISP::VIDEO
|
||||
lda #%00000100 ; Bitmap mode enable
|
||||
sta VERA::L1::CONFIG
|
||||
lda #%00000001 ; Tile width 640
|
||||
sta VERA::L1::TILE_BASE
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; DONE: Will be called to switch the graphics device back into text mode.
|
||||
; The graphics kernel never will call DONE when no graphics mode is active,
|
||||
; so there is no need to protect against that.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
DONE:
|
||||
jsr CINT
|
||||
lda text_mode
|
||||
clc
|
||||
jmp SCREEN_MODE
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETERROR: Return the error code in .A, and clear it.
|
||||
|
||||
GETERROR:
|
||||
lda ERROR
|
||||
stz ERROR
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; CONTROL: Platform-/driver-specific entry point.
|
||||
;
|
||||
; Must set an error code: YES
|
||||
|
||||
CONTROL:
|
||||
lda #TGI_ERR_INV_FUNC
|
||||
sta ERROR
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; CLEAR: Clear the screen.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
CLEAR:
|
||||
.scope inner
|
||||
|
||||
; set up DCSEL=2
|
||||
lda #(2 << 1)
|
||||
sta VERA::CTRL
|
||||
|
||||
; set cache writes
|
||||
lda #$40
|
||||
tsb VERA::DISP::VIDEO ; VERA_FX_CTRL when DCSEL=2
|
||||
|
||||
; set FX cache to all zeroes
|
||||
lda #(6 << 1)
|
||||
sta VERA::CTRL
|
||||
|
||||
lda #$00
|
||||
sta VERA::DISP::VIDEO
|
||||
sta VERA::DISP::HSCALE
|
||||
sta VERA::DISP::VSCALE
|
||||
sta VERA::DISP::FRAME
|
||||
|
||||
stz VERA::CTRL
|
||||
; set address and increment for bitmap area
|
||||
stz VERA::ADDR
|
||||
stz VERA::ADDR + 1
|
||||
lda #$30 ; increment +4
|
||||
sta VERA::ADDR + 2
|
||||
|
||||
ldy #$F0
|
||||
@blank_outer:
|
||||
ldx #$0A
|
||||
@blank_loop:
|
||||
|
||||
.repeat 8
|
||||
stz VERA::DATA0
|
||||
.endrep
|
||||
|
||||
dex
|
||||
bne @blank_loop
|
||||
dey
|
||||
bne @blank_outer
|
||||
|
||||
; set up DCSEL=2
|
||||
lda #(2 << 1)
|
||||
sta VERA::CTRL
|
||||
|
||||
; set FX off (cache write bit 1 -> 0)
|
||||
stz VERA::DISP::VIDEO ; VERA_FX_CTRL when DCSEL=2
|
||||
stz VERA::CTRL
|
||||
|
||||
.endscope
|
||||
rts
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETVIEWPAGE: Set the visible page. Called with the new page in .A (0..n-1).
|
||||
; The page number already is checked to be valid by the graphics kernel.
|
||||
;
|
||||
; Must set an error code: NO (will be called only if page OK)
|
||||
|
||||
SETVIEWPAGE:
|
||||
|
||||
; Fall through.
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETDRAWPAGE: Set the drawable page. Called with the new page in .A (0..n-1).
|
||||
; The page number already is checked to be valid by the graphics kernel.
|
||||
;
|
||||
; Must set an error code: NO (will be called only if page OK)
|
||||
|
||||
SETDRAWPAGE:
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETPALETTE: Set the palette (not available with all drivers/hardware).
|
||||
; A pointer to the palette is passed in ptr1. Must set an error if palettes
|
||||
; are not supported
|
||||
;
|
||||
; Must set an error code: YES
|
||||
|
||||
SETPALETTE:
|
||||
stz ERROR ; #TGI_ERR_OK
|
||||
ldy #$01 ; Palette size of 2 colors
|
||||
@L1: lda (ptr1),y ; Copy the palette
|
||||
sta palette,y
|
||||
dey
|
||||
bpl @L1
|
||||
|
||||
; set background color from palette color 0
|
||||
lda #$00
|
||||
sta VERA::ADDR
|
||||
lda #$FA
|
||||
sta VERA::ADDR+1
|
||||
lda #$01
|
||||
sta VERA::ADDR+2 ; write color RAM @ $1FA00
|
||||
|
||||
lda palette
|
||||
asl
|
||||
tay
|
||||
lda veracolors,y
|
||||
sta VERA::DATA0
|
||||
|
||||
inc VERA::ADDR ; $1FA01
|
||||
|
||||
lda palette
|
||||
asl
|
||||
tay
|
||||
iny ; second byte of color
|
||||
lda veracolors,y
|
||||
sta VERA::DATA0
|
||||
|
||||
; set foreground color from palette color 1
|
||||
inc VERA::ADDR ; $1FA02
|
||||
|
||||
lda palette+1
|
||||
asl
|
||||
tay
|
||||
lda veracolors,y
|
||||
sta VERA::DATA0
|
||||
|
||||
inc VERA::ADDR ; $1FA03
|
||||
|
||||
lda palette+1
|
||||
asl
|
||||
tay
|
||||
iny ; second byte of color
|
||||
lda veracolors,y
|
||||
sta VERA::DATA0
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETCOLOR: Set the drawing color (in .A). The new color already is checked
|
||||
; to be in a valid range (0..maxcolor).
|
||||
;
|
||||
; Must set an error code: NO (will be called only if color OK)
|
||||
|
||||
SETCOLOR:
|
||||
tax
|
||||
beq @L1
|
||||
lda #$FF
|
||||
@L1: sta BITMASK
|
||||
stx color
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETPALETTE: Return the current palette in .XA. Even drivers that cannot
|
||||
; set the palette should return the default palette here, so there's no
|
||||
; way for this function to fail.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
GETPALETTE:
|
||||
lda #<palette
|
||||
ldx #>palette
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETDEFPALETTE: Return the default palette for the driver in .XA. All
|
||||
; drivers should return something reasonable here, even drivers that don't
|
||||
; support palettes, otherwise the caller has no way to determine the colors
|
||||
; of the (not changable) palette.
|
||||
;
|
||||
; Must set an error code: NO (all drivers must have a default palette)
|
||||
|
||||
GETDEFPALETTE:
|
||||
lda #<defpalette
|
||||
ldx #>defpalette
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
|
||||
; color. The co-ordinates passed to this function never are outside the
|
||||
; visible screen area, so there is no need for clipping inside this function.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
SETPIXEL:
|
||||
jsr CALC
|
||||
|
||||
stx TEMP
|
||||
|
||||
lda ADDR
|
||||
ldy ADDR+1
|
||||
ldx #$00
|
||||
|
||||
sta VERA::ADDR
|
||||
sty VERA::ADDR + 1
|
||||
stx VERA::ADDR + 2
|
||||
|
||||
ldx TEMP
|
||||
|
||||
lda BITMASK
|
||||
beq @ahead
|
||||
|
||||
; if BITMASK = $00, white is line color
|
||||
; Set the bit in the byte at VERA_DATA0
|
||||
lda VERA::DATA0 ; Load the byte at memory address
|
||||
ora bitMasks1,X ; OR with the bit mask
|
||||
sta VERA::DATA0 ; Store back the modified byte
|
||||
rts
|
||||
|
||||
@ahead:
|
||||
; if BITMASK = $FF, black is line color
|
||||
lda VERA::DATA0 ; Load the byte at memory address
|
||||
and bitMasks2,X ; OR with the bit mask
|
||||
sta VERA::DATA0 ; Store back the modified byte
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; GETPIXEL: Read the color value of a pixel, and return it in .XA. The
|
||||
; co-ordinates passed to this function never are outside the visible screen
|
||||
; area, so there is no need for clipping inside this function.
|
||||
|
||||
GETPIXEL:
|
||||
jsr CALC
|
||||
|
||||
stx TEMP
|
||||
|
||||
lda ADDR
|
||||
ldy ADDR+1
|
||||
ldx #$00
|
||||
|
||||
sta VERA::ADDR
|
||||
sty VERA::ADDR + 1
|
||||
stx VERA::ADDR + 2
|
||||
|
||||
ldx TEMP
|
||||
lda VERA::DATA0 ; Load the byte at memory address
|
||||
and bitMasks1,X
|
||||
|
||||
bne @ahead
|
||||
|
||||
ldx #$00
|
||||
lda #$00
|
||||
rts
|
||||
|
||||
@ahead:
|
||||
ldx #$00
|
||||
lda #$01
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
|
||||
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4, using the current drawing color.
|
||||
; Contrary to most other functions, the graphics kernel will sort and clip
|
||||
; the co-ordinates before calling the driver; so on entry, the following
|
||||
; conditions are valid:
|
||||
; X1 <= X2
|
||||
; Y1 <= Y2
|
||||
; (X1 >= 0) && (X1 < XRES)
|
||||
; (X2 >= 0) && (X2 < XRES)
|
||||
; (Y1 >= 0) && (Y1 < YRES)
|
||||
; (Y2 >= 0) && (Y2 < YRES)
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
BAR:
|
||||
; Initialize tempY with Y1
|
||||
lda Y1
|
||||
sta tempY
|
||||
lda Y1+1
|
||||
sta tempY+1
|
||||
|
||||
@outer_loop:
|
||||
; Compare tempY with Y2
|
||||
lda tempY+1
|
||||
cmp Y2+1
|
||||
bcc @outer_continue ; If tempY high byte < Y2 high byte, continue
|
||||
bne @outer_end ; If tempY high byte > Y2 high byte, end
|
||||
lda tempY
|
||||
cmp Y2
|
||||
bcc @outer_continue ; If tempY low byte < Y2 low byte, continue
|
||||
beq @outer_end ; If tempY low byte = Y2 low byte, end
|
||||
|
||||
@outer_continue:
|
||||
; Initialize tempX with X1
|
||||
lda X1
|
||||
sta tempX
|
||||
lda X1+1
|
||||
sta tempX+1
|
||||
|
||||
@inner_loop:
|
||||
; Compare tempX with X2
|
||||
lda tempX+1
|
||||
cmp X2+1
|
||||
bcc @inner_continue ; If tempX high byte < X2 high byte, continue
|
||||
bne @inner_end ; If tempX high byte > X2 high byte, end
|
||||
lda tempX
|
||||
cmp X2
|
||||
bcc @inner_continue ; If tempX low byte < X2 low byte, continue
|
||||
|
||||
@inner_end:
|
||||
; Increment tempY
|
||||
inc tempY
|
||||
bne @outer_loop ; If no overflow, continue outer loop
|
||||
inc tempY+1 ; If overflow, increment high byte
|
||||
|
||||
@inner_continue:
|
||||
; Call setpixel(tempX, tempY)
|
||||
lda X1
|
||||
pha
|
||||
lda X1+1
|
||||
pha
|
||||
lda Y1
|
||||
pha
|
||||
lda Y1+1
|
||||
pha
|
||||
|
||||
lda tempX
|
||||
ldx tempX+1
|
||||
sta X1
|
||||
stx X1+1
|
||||
|
||||
lda tempY
|
||||
ldx tempY+1
|
||||
sta Y1
|
||||
stx Y1+1
|
||||
|
||||
jsr SETPIXEL
|
||||
|
||||
pla
|
||||
sta Y1+1
|
||||
pla
|
||||
sta Y1
|
||||
pla
|
||||
sta X1+1
|
||||
pla
|
||||
sta X1
|
||||
|
||||
; Increment tempX
|
||||
inc tempX
|
||||
bne @inner_loop_check ; If no overflow, continue
|
||||
inc tempX+1 ; If overflow, increment high byte
|
||||
|
||||
@inner_loop_check:
|
||||
; Compare tempX with X2 again after increment
|
||||
lda tempX+1
|
||||
cmp X2+1
|
||||
bcc @inner_continue ; If tempX high byte < X2 high byte, continue
|
||||
bne @outer_increment ; If tempX high byte > X2 high byte, increment tempY
|
||||
lda tempX
|
||||
cmp X2
|
||||
bcc @inner_continue ; If tempX low byte < X2 low byte, continue
|
||||
|
||||
@outer_increment:
|
||||
; Increment tempY
|
||||
inc tempY
|
||||
bne @outer_loop ; If no overflow, continue outer loop
|
||||
inc tempY+1 ; If overflow, increment high byte
|
||||
|
||||
@outer_end:
|
||||
jmp @done
|
||||
|
||||
@done:
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
|
||||
; directions are passed in .X and .Y, the text direction is passed in .A.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
TEXTSTYLE:
|
||||
rts
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; 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 address in ptr3.
|
||||
;
|
||||
; Must set an error code: NO
|
||||
|
||||
OUTTEXT:
|
||||
rts
|
||||
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; Calculate all variables to plot the pixel at X1/Y1.
|
||||
;------------------------
|
||||
;< X1,Y1 - pixel
|
||||
;> ADDR - address of card
|
||||
;> X - bit number (X1 & 7)
|
||||
CALC:
|
||||
lda Y1+1
|
||||
sta ADDR+1
|
||||
lda Y1
|
||||
asl
|
||||
rol ADDR+1
|
||||
asl
|
||||
rol ADDR+1 ; Y*4
|
||||
clc
|
||||
adc Y1
|
||||
sta ADDR
|
||||
lda Y1+1
|
||||
adc ADDR+1
|
||||
sta ADDR+1 ; Y*4+Y=Y*5
|
||||
lda ADDR
|
||||
asl
|
||||
rol ADDR+1
|
||||
asl
|
||||
rol ADDR+1
|
||||
asl
|
||||
rol ADDR+1
|
||||
asl
|
||||
rol ADDR+1
|
||||
sta ADDR ; Y*5*16=Y*80
|
||||
lda X1+1
|
||||
sta TEMP
|
||||
lda X1
|
||||
lsr TEMP
|
||||
ror
|
||||
lsr TEMP
|
||||
ror
|
||||
lsr TEMP
|
||||
ror
|
||||
clc
|
||||
adc ADDR
|
||||
sta ADDR
|
||||
lda ADDR+1 ; ADDR = Y*80+x/8
|
||||
adc TEMP
|
||||
sta ADDR+1
|
||||
lda ADDR+1
|
||||
lda X1
|
||||
and #7
|
||||
tax
|
||||
rts
|
||||
|
||||
|
||||
.include "../../tgi/tgidrv_line.inc"
|
||||
@@ -9,8 +9,7 @@
|
||||
.include "pet.inc"
|
||||
|
||||
_waitvsync:
|
||||
@l1:
|
||||
lda VIA_PB
|
||||
and #%00100000
|
||||
bne @l1
|
||||
lda #%00100000
|
||||
: and VIA_PB
|
||||
bne :-
|
||||
rts
|
||||
|
||||
@@ -9,11 +9,21 @@
|
||||
.import __MAIN_START__
|
||||
.import startup
|
||||
|
||||
.macpack cpu
|
||||
|
||||
.segment "EXEHDR"
|
||||
|
||||
.byte $73, $69, $6D, $36, $35 ; 'sim65'
|
||||
.byte 2 ; header version
|
||||
.byte .defined(__SIM65C02__) ; CPU type
|
||||
.if (.cpu .bitand ::CPU_ISET_6502X)
|
||||
.byte 2
|
||||
.elseif (.cpu .bitand ::CPU_ISET_65C02)
|
||||
.byte 1
|
||||
.elseif (.cpu .bitand ::CPU_ISET_6502)
|
||||
.byte 0
|
||||
.else
|
||||
.error Unknow CPU type.
|
||||
.endif
|
||||
.byte sp ; sp address
|
||||
.addr __MAIN_START__ ; load address
|
||||
.addr startup ; reset address
|
||||
|
||||
Reference in New Issue
Block a user