mirror of
https://github.com/cc65/cc65.git
synced 2024-12-26 08:32:00 +00:00
Lynx update including file routines that access a file system on a cartridge
by Karri Kaksonen. git-svn-id: svn://svn.cc65.org/cc65/trunk@4892 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
4a92522c82
commit
d993b332a4
@ -73,11 +73,19 @@
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Accessing the cart */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void __fastcall__ lynx_load (int fileno);
|
||||||
|
/* Load a file into ram. The first entry is fileno=0. */
|
||||||
|
|
||||||
|
void __fastcall__ lynx_exec (int fileno);
|
||||||
|
/* Load a file into ram and execute it. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Accessing the EEPROM */
|
/* Accessing the EEPROM */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -94,10 +102,13 @@ void __fastcall__ lynx_eeprom_erase (unsigned char cell);
|
|||||||
/* Clear the word at the given address */
|
/* Clear the word at the given address */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* TGI extras */
|
/* TGI extras */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define tgi_sprite(spr) tgi_ioctl(0, spr)
|
#define tgi_sprite(spr) tgi_ioctl(0, spr)
|
||||||
#define tgi_flip() tgi_ioctl(1, (void*)0)
|
#define tgi_flip() tgi_ioctl(1, (void*)0)
|
||||||
#define tgi_setbgcolor(bgcol) tgi_ioctl(2, (void*)(bgcol))
|
#define tgi_setbgcolor(bgcol) tgi_ioctl(2, (void*)(bgcol))
|
||||||
@ -106,6 +117,8 @@ void __fastcall__ lynx_eeprom_erase (unsigned char cell);
|
|||||||
#define tgi_updatedisplay() tgi_ioctl(4, (void*)1)
|
#define tgi_updatedisplay() tgi_ioctl(4, (void*)1)
|
||||||
#define tgi_setcollisiondetection(active) tgi_ioctl(5, (void*)(active))
|
#define tgi_setcollisiondetection(active) tgi_ioctl(5, (void*)(active))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of lynx.h */
|
/* End of lynx.h */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -49,9 +49,16 @@ OBJS = cgetc.o \
|
|||||||
crt0.o \
|
crt0.o \
|
||||||
ctype.o \
|
ctype.o \
|
||||||
eeprom.o \
|
eeprom.o \
|
||||||
|
exec.o \
|
||||||
extzp.o \
|
extzp.o \
|
||||||
kbhit.o \
|
kbhit.o \
|
||||||
|
load.o \
|
||||||
|
lseek.o \
|
||||||
|
lynx-cart.o \
|
||||||
mainargs.o \
|
mainargs.o \
|
||||||
|
open.o \
|
||||||
|
oserror.o \
|
||||||
|
read.o \
|
||||||
sysuname.o \
|
sysuname.o \
|
||||||
toascii.o
|
toascii.o
|
||||||
|
|
||||||
|
34
libsrc/lynx/exec.s
Normal file
34
libsrc/lynx/exec.s
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
;
|
||||||
|
; Karri Kaksonen, 2010
|
||||||
|
;
|
||||||
|
; lynx_exec(fileno) loads a file into memory but after the read the CPU
|
||||||
|
; does a jump into the loaded start address.
|
||||||
|
;
|
||||||
|
; lynx_exec is often used in compilation carts when you run small demos
|
||||||
|
; created with various (non-cc65) compilers.
|
||||||
|
;
|
||||||
|
; void lynx_exec(int fileno)
|
||||||
|
;
|
||||||
|
.importzp _FileDestAddr
|
||||||
|
.import pushax,ldax0sp,incsp2
|
||||||
|
.import _lynx_load
|
||||||
|
.export _lynx_exec
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
; void __near__ __fastcall__ lynx_exec (int)
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
.proc _lynx_exec: near
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
jsr pushax
|
||||||
|
jsr ldax0sp
|
||||||
|
jsr _lynx_load
|
||||||
|
jsr incsp2
|
||||||
|
jmp (_FileDestAddr)
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
41
libsrc/lynx/load.s
Normal file
41
libsrc/lynx/load.s
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
;
|
||||||
|
; Karri Kaksonen, 2010
|
||||||
|
;
|
||||||
|
; lynx_load(fileno) is a convenience function that is widely used on the Lynx.
|
||||||
|
; Basically this opens directory entry fileno and reads the content of the
|
||||||
|
; file this points to into RAM.
|
||||||
|
;
|
||||||
|
; void lynx_load(int fileno)
|
||||||
|
;
|
||||||
|
.importzp _FileFileLen
|
||||||
|
.importzp _FileDestAddr
|
||||||
|
.import pushax,ldax0sp,pusha0,incsp2
|
||||||
|
.import _openn
|
||||||
|
.import _read
|
||||||
|
.export _lynx_load
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
; void __near__ __fastcall__ lynx_load (int)
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
.proc _lynx_load: near
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
jsr pushax
|
||||||
|
jsr ldax0sp
|
||||||
|
jsr _openn
|
||||||
|
lda #$01
|
||||||
|
jsr pusha0
|
||||||
|
lda _FileDestAddr
|
||||||
|
ldx _FileDestAddr+1
|
||||||
|
jsr pushax
|
||||||
|
lda _FileFileLen
|
||||||
|
ldx _FileFileLen+1
|
||||||
|
jsr _read
|
||||||
|
jmp incsp2
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
59
libsrc/lynx/lseek.s
Normal file
59
libsrc/lynx/lseek.s
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
;
|
||||||
|
; Karri Kaksonen, 2010
|
||||||
|
;
|
||||||
|
; This function is used to place the Lynx hardware to point to any byte in
|
||||||
|
; the Lynx cart.
|
||||||
|
;
|
||||||
|
; This function supports all available block sizes (512, 1024 and 2048 bytes).
|
||||||
|
; No other block sizes have been used afaik.
|
||||||
|
;
|
||||||
|
; Only SEEK_SET operation mode is implemented.
|
||||||
|
;
|
||||||
|
; off_t __fastcall__ lseek(int fd, off_t offset, int whence);
|
||||||
|
|
||||||
|
.importzp sp, sreg, regsave, regbank, tmp1, ptr1, ptr2
|
||||||
|
.macpack longbranch
|
||||||
|
.export _lseek
|
||||||
|
.import addysp, stax0sp, tosand0ax, pusheax, asreax2
|
||||||
|
.import ldeaxysp, decsp2, pushax, incsp8
|
||||||
|
.import tosandeax,decax1,tosdiveax,axlong,ldaxysp
|
||||||
|
.import lynxskip0, lynxblock,tosasreax
|
||||||
|
.import __BLOCKSIZE__
|
||||||
|
.importzp _FileCurrBlock
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
.proc _lseek: near
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
jsr pushax
|
||||||
|
ldy #$05
|
||||||
|
jsr ldeaxysp
|
||||||
|
jsr pusheax
|
||||||
|
ldx #$00
|
||||||
|
lda #<(__BLOCKSIZE__/1024 + 9)
|
||||||
|
jsr tosasreax
|
||||||
|
sta _FileCurrBlock
|
||||||
|
jsr lynxblock
|
||||||
|
ldy #$05
|
||||||
|
jsr ldeaxysp
|
||||||
|
jsr pusheax
|
||||||
|
lda #<(__BLOCKSIZE__-1)
|
||||||
|
ldx #>(__BLOCKSIZE__-1)
|
||||||
|
jsr decax1
|
||||||
|
jsr axlong
|
||||||
|
jsr tosandeax
|
||||||
|
eor #$FF
|
||||||
|
pha
|
||||||
|
txa
|
||||||
|
eor #$FF
|
||||||
|
tay
|
||||||
|
plx
|
||||||
|
jsr lynxskip0
|
||||||
|
ldy #$05
|
||||||
|
jsr ldeaxysp
|
||||||
|
jmp incsp8
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
99
libsrc/lynx/lynx-cart.s
Normal file
99
libsrc/lynx/lynx-cart.s
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
; ***
|
||||||
|
; CC65 Lynx Library
|
||||||
|
;
|
||||||
|
; Originally by Bastian Schick
|
||||||
|
; http://www.geocities.com/SiliconValley/Byte/4242/lynx/
|
||||||
|
;
|
||||||
|
; Ported to cc65 (http://www.cc65.org) by
|
||||||
|
; Shawn Jefferson, June 2004
|
||||||
|
;
|
||||||
|
; This version by Karri Kaksonen, December 2010
|
||||||
|
;
|
||||||
|
; Helper stuff for the cartridge file functions. This version can deal
|
||||||
|
; with 1024 bytes/block carts that are using CART0 as a read strobe.
|
||||||
|
; Also the default crt0.s supports this most common Lynx cart format.
|
||||||
|
|
||||||
|
.include "lynx.inc"
|
||||||
|
.include "extzp.inc"
|
||||||
|
.export lynxskip0, lynxread0
|
||||||
|
.export lynxblock
|
||||||
|
|
||||||
|
__BLOCKSIZE0__ = 1024
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
;**********************************
|
||||||
|
; Skip bytes on bank 0
|
||||||
|
; X:Y count (EOR $FFFF)
|
||||||
|
;**********************************
|
||||||
|
lynxskip0:
|
||||||
|
inx
|
||||||
|
bne @0
|
||||||
|
iny
|
||||||
|
beq exit
|
||||||
|
@0: jsr readbyte0
|
||||||
|
bra lynxskip0
|
||||||
|
|
||||||
|
;**********************************
|
||||||
|
; Read bytes from bank 0
|
||||||
|
; X:Y count (EOR $ffff)
|
||||||
|
;**********************************
|
||||||
|
lynxread0:
|
||||||
|
inx
|
||||||
|
bne @1
|
||||||
|
iny
|
||||||
|
beq exit
|
||||||
|
@1: jsr readbyte0
|
||||||
|
sta (_FileDestPtr)
|
||||||
|
inc _FileDestPtr
|
||||||
|
bne lynxread0
|
||||||
|
inc _FileDestPtr+1
|
||||||
|
bra lynxread0
|
||||||
|
|
||||||
|
;**********************************
|
||||||
|
; Read one byte from cartridge
|
||||||
|
;**********************************
|
||||||
|
readbyte0:
|
||||||
|
lda RCART0
|
||||||
|
inc _FileBlockByte
|
||||||
|
bne exit
|
||||||
|
inc _FileBlockByte+1
|
||||||
|
bne exit
|
||||||
|
|
||||||
|
;**********************************
|
||||||
|
; Select a block
|
||||||
|
;**********************************
|
||||||
|
lynxblock:
|
||||||
|
pha
|
||||||
|
phx
|
||||||
|
phy
|
||||||
|
lda __iodat
|
||||||
|
and #$fc
|
||||||
|
tay
|
||||||
|
ora #2
|
||||||
|
tax
|
||||||
|
lda _FileCurrBlock
|
||||||
|
inc _FileCurrBlock
|
||||||
|
sec
|
||||||
|
bra @2
|
||||||
|
@0: bcc @1
|
||||||
|
stx IODAT
|
||||||
|
clc
|
||||||
|
@1: inx
|
||||||
|
stx SYSCTL1
|
||||||
|
dex
|
||||||
|
@2: stx SYSCTL1
|
||||||
|
rol
|
||||||
|
sty IODAT
|
||||||
|
bne @0
|
||||||
|
lda __iodat
|
||||||
|
sta IODAT
|
||||||
|
stz _FileBlockByte
|
||||||
|
lda #$100-(>__BLOCKSIZE0__)
|
||||||
|
sta _FileBlockByte+1
|
||||||
|
ply
|
||||||
|
plx
|
||||||
|
pla
|
||||||
|
|
||||||
|
exit: rts
|
||||||
|
|
127
libsrc/lynx/open.s
Normal file
127
libsrc/lynx/open.s
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
;
|
||||||
|
; Karri Kaksonen, 2010
|
||||||
|
;
|
||||||
|
; This function reads the directory entry for file "name".
|
||||||
|
;
|
||||||
|
; The name is actually plain ASCII string starting from
|
||||||
|
; "0", "1", up to "4095" which is the largest file number we can handle.
|
||||||
|
;
|
||||||
|
; open() does not take part in what kind of cart we have. If it is RAM
|
||||||
|
; you may also be able to write into it. Therefore we allow both reads
|
||||||
|
; and writes in this routine.
|
||||||
|
;
|
||||||
|
; int open(const char *name, int flags, ...)
|
||||||
|
;
|
||||||
|
; As helper functions we also provide.
|
||||||
|
; void openn(int fileno)
|
||||||
|
;
|
||||||
|
.importzp sreg, tmp3
|
||||||
|
.macpack longbranch
|
||||||
|
.import _atoi
|
||||||
|
.import _read
|
||||||
|
.import _lseek
|
||||||
|
.import addysp,popax,pushax,decsp6,pusha0,pusheax,ldaxysp
|
||||||
|
.import aslax3,axlong,tosaddeax,steaxysp,stax0sp,incsp8
|
||||||
|
.import ldax0sp
|
||||||
|
.importzp _FileEntry
|
||||||
|
.importzp _FileStartBlock
|
||||||
|
.importzp _FileCurrBlock
|
||||||
|
.importzp _FileBlockOffset
|
||||||
|
.import __STARTOFDIRECTORY__
|
||||||
|
.export _open
|
||||||
|
.export _openn
|
||||||
|
|
||||||
|
.include "errno.inc"
|
||||||
|
.include "fcntl.inc"
|
||||||
|
|
||||||
|
.segment "DATA"
|
||||||
|
|
||||||
|
_startofdirectory:
|
||||||
|
.dword __STARTOFDIRECTORY__
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
; int __near__ open (__near__ const unsigned char*, int)
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
.proc _open
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
dey
|
||||||
|
dey
|
||||||
|
dey
|
||||||
|
dey
|
||||||
|
beq parmok
|
||||||
|
jsr addysp
|
||||||
|
|
||||||
|
parmok: jsr popax
|
||||||
|
sta tmp3
|
||||||
|
and #(O_RDWR | O_CREAT)
|
||||||
|
cmp #O_RDONLY
|
||||||
|
beq flagsok
|
||||||
|
cmp #(O_WRONLY | O_CREAT)
|
||||||
|
beq flagsok
|
||||||
|
lda #EINVAL
|
||||||
|
ldx #0
|
||||||
|
jmp __directerrno
|
||||||
|
|
||||||
|
flagsok:
|
||||||
|
jsr popax
|
||||||
|
jsr _atoi
|
||||||
|
jsr pushax
|
||||||
|
jsr ldax0sp
|
||||||
|
jsr _openn
|
||||||
|
ldx #$00
|
||||||
|
lda #$01
|
||||||
|
stx __oserror
|
||||||
|
rts
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
; void __near__ __fastcall__ openn (int)
|
||||||
|
; ---------------------------------------------------------------
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
.proc _openn: near
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
jsr pushax
|
||||||
|
jsr decsp6
|
||||||
|
lda #$01
|
||||||
|
jsr pusha0
|
||||||
|
lda _startofdirectory+3
|
||||||
|
sta sreg+1
|
||||||
|
lda _startofdirectory+2
|
||||||
|
sta sreg
|
||||||
|
ldx _startofdirectory+1
|
||||||
|
lda _startofdirectory
|
||||||
|
jsr pusheax
|
||||||
|
ldy #$0D
|
||||||
|
jsr ldaxysp
|
||||||
|
jsr aslax3
|
||||||
|
jsr axlong
|
||||||
|
jsr tosaddeax
|
||||||
|
jsr pusheax
|
||||||
|
ldx #$00
|
||||||
|
txa
|
||||||
|
jsr _lseek
|
||||||
|
ldy #$02
|
||||||
|
jsr steaxysp
|
||||||
|
lda #$01
|
||||||
|
jsr pusha0
|
||||||
|
lda _FileEntry
|
||||||
|
ldx _FileEntry+1
|
||||||
|
jsr pushax
|
||||||
|
ldx #$00
|
||||||
|
lda #$08
|
||||||
|
jsr _read
|
||||||
|
jsr stax0sp
|
||||||
|
jmp incsp8
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
14
libsrc/lynx/oserror.s
Normal file
14
libsrc/lynx/oserror.s
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
;
|
||||||
|
; Karri Kaksonen, 2010
|
||||||
|
;
|
||||||
|
; int __fastcall__ _osmaperrno (unsigned char oserror);
|
||||||
|
; /* Map a system specific error into a system independent code */
|
||||||
|
;
|
||||||
|
|
||||||
|
.include "errno.inc"
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
__osmaperrno:
|
||||||
|
rts
|
||||||
|
|
50
libsrc/lynx/read.s
Normal file
50
libsrc/lynx/read.s
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
;
|
||||||
|
; Karri Kaksonen, 2010
|
||||||
|
;
|
||||||
|
; This function reads count bytes from the place where the address counter is.
|
||||||
|
; Use lseek to place the address counter where you want to read from.
|
||||||
|
;
|
||||||
|
; The file descriptor is ignored in this implementation. The read operation
|
||||||
|
; reads bytes from a raw cart and does not understand the concept of files.
|
||||||
|
; So if you read over the end of file you get data from the next file.
|
||||||
|
;
|
||||||
|
; The count-parameter can be positive (Atari style) or negative (BLL style).
|
||||||
|
; In any case the read routine will work correctly.
|
||||||
|
;
|
||||||
|
; int __fastcall__ read(int fd,void *buf,int count)
|
||||||
|
;
|
||||||
|
.importzp _FileDestPtr
|
||||||
|
.import lynxread0
|
||||||
|
.import pushax,ldaxysp,ldax0sp,incsp6
|
||||||
|
.export _read
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
.proc _read: near
|
||||||
|
|
||||||
|
.segment "CODE"
|
||||||
|
|
||||||
|
jsr pushax
|
||||||
|
ldy #$03
|
||||||
|
jsr ldaxysp
|
||||||
|
sta _FileDestPtr
|
||||||
|
stx _FileDestPtr+1
|
||||||
|
jsr ldax0sp
|
||||||
|
phx ; The BLL kit uses negative counts
|
||||||
|
plx ; while the basic Lynx uses positive
|
||||||
|
bmi @1 ; make all counts negative
|
||||||
|
eor #$FF
|
||||||
|
pha
|
||||||
|
txa
|
||||||
|
eor #$FF
|
||||||
|
bra @2
|
||||||
|
@1: pha
|
||||||
|
txa
|
||||||
|
@2: tay
|
||||||
|
plx
|
||||||
|
jsr lynxread0
|
||||||
|
jsr ldax0sp
|
||||||
|
jmp incsp6
|
||||||
|
|
||||||
|
.endproc
|
||||||
|
|
@ -1,5 +1,7 @@
|
|||||||
SYMBOLS {
|
SYMBOLS {
|
||||||
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
||||||
|
__STARTOFDIRECTORY__: type = weak, value = $019A; # start just after loader
|
||||||
|
__BLOCKSIZE__: type = weak, value = 1024; # cart block size
|
||||||
}
|
}
|
||||||
MEMORY {
|
MEMORY {
|
||||||
ZP: file = "", define = yes, start = $0000, size = $0100;
|
ZP: file = "", define = yes, start = $0000, size = $0100;
|
||||||
|
Loading…
Reference in New Issue
Block a user