Fix line endings (CRLF -> LF) on all affected files.

This commit is contained in:
Christian Groessler 2017-03-10 11:21:14 +01:00
parent b332064cb5
commit 8a81f9c0c8
14 changed files with 2379 additions and 2379 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,267 +1,267 @@
; smc.mac
; ca65 Macro-Pack for Self Modifying Code (SMC)
;
; (c) Christian Krüger, latest change: 17-Jul-2016
;
; This software is provided 'as-is', without any expressed or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Permission is granted to anyone to use this software for any purpose,
; including commercial applications, and to alter it and redistribute it
; freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you must not
; claim that you wrote the original software. If you use this software
; in a product, an acknowledgment in the product documentation would be
; appreciated but is not required.
; 2. Altered source versions must be plainly marked as such, and must not
; be misrepresented as being the original software.
; 3. This notice may not be removed or altered from any source
; distribution.
;
.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC"))
.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC"))
.define SMC_AbsAdr $FADE
.define SMC_ZpAdr $00
.define SMC_Opcode nop
.define SMC_Value $42
.macro SMC_OperateOnValue opcode, label
opcode _SMCDesignator+1
.endmacro
.macro SMC_OperateOnLowByte opcode, label
SMC_OperateOnValue opcode, label
.endmacro
.macro SMC_OperateOnHighByte opcode, label
opcode _SMCDesignator + 2
.endmacro
.macro SMC_Import alias
.import _SMCAlias
.endmacro
.macro SMC_Export alias, label
.export _SMCAlias := _SMCDesignator
.endmacro
.macro SMC label, statement
_SMCDesignator: statement
.endmacro
.macro SMC_TransferOpcode label, opcode, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda #opcode
sta _SMCDesignator
.elseif .match ({register}, x)
ldx #opcode
stx _SMCDesignator
.elseif .match ({register}, y)
ldy #opcode
sty _SMCDesignator
.else
.error "Invalid usage of macro 'SMC_TransferOpcode'"
.endif
.endmacro
.macro SMC_LoadOpcode label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
lda _SMCDesignator
.elseif .match ({register}, x)
ldx _SMCDesignator
.elseif .match ({register}, y)
ldy _SMCDesignator
.else
.error "Invalid usage of macro 'SMC_LoadOpcode'"
.endif
.endmacro
.macro SMC_StoreOpcode label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
sta _SMCDesignator
.elseif .match ({register}, x)
stx _SMCDesignator
.elseif .match ({register}, y)
sty _SMCDesignator
.else
.error "Invalid usage of macro 'SMC_StoreOpcode'"
.endif
.endmacro
.macro SMC_ChangeBranch label, destination, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda #(<(destination - _SMCDesignator -2))
sta _SMCDesignator+1
.elseif .match ({register}, x)
ldx #(<(destination - _SMCDesignator - 2))
stx _SMCDesignator+1
.elseif .match ({register}, y)
ldy #(<(destination - _SMCDesignator - 2))
sty _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_ChangeBranch'"
.endif
.endmacro
.macro SMC_TransferValue label, value, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda value
sta _SMCDesignator+1
.elseif .match ({register}, x)
ldx value
stx _SMCDesignator+1
.elseif .match ({register}, y)
ldy value
sty _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_TransferValue'"
.endif
.endmacro
.macro SMC_LoadValue label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
lda _SMCDesignator+1
.elseif .match ({register}, x)
ldx _SMCDesignator+1
.elseif .match ({register}, y)
ldy _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_LoadValue'"
.endif
.endmacro
.macro SMC_StoreValue label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
sta _SMCDesignator+1
.elseif .match ({register}, x)
stx _SMCDesignator+1
.elseif .match ({register}, y)
sty _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_StoreValue'"
.endif
.endmacro
.macro SMC_TransferLowByte label, value, register
SMC_TransferValue label, value, register
.endmacro
.macro SMC_LoadLowByte label, register
SMC_LoadValue label, register
.endmacro
.macro SMC_StoreLowByte label, register
SMC_StoreValue label, register
.endmacro
.macro SMC_TransferHighByte label, value, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda value
sta _SMCDesignator+2
.elseif .match ({register}, x)
ldx value
stx _SMCDesignator+2
.elseif .match ({register}, y)
ldy value
sty _SMCDesignator+2
.else
.error "Invalid usage of macro 'SMC_TransferHighByte'"
.endif
.endmacro
.macro SMC_LoadHighByte label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
lda _SMCDesignator+2
.elseif .match ({register}, x)
ldx _SMCDesignator+2
.elseif .match ({register}, y)
ldy _SMCDesignator+2
.else
.error "Invalid usage of macro 'SMC_LoadHighByte'"
.endif
.endmacro
.macro SMC_StoreHighByte label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
sta _SMCDesignator+2
.elseif .match ({register}, x)
stx _SMCDesignator+2
.elseif .match ({register}, y)
sty _SMCDesignator+2
.else
.error "Invalid usage of macro 'SMC_StoreHighByte'"
.endif
.endmacro
.macro SMC_TransferAddressSingle label, address, register
.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, )
.if (.match (.left (1, {address}), #))
; immediate mode
lda #<(.right (.tcount ({address})-1, {address}))
sta _SMCDesignator+1
lda #>(.right (.tcount ({address})-1, {address}))
sta _SMCDesignator+2
.else
; assume absolute or zero page
lda address
sta _SMCDesignator+1
lda 1+(address)
sta _SMCDesignator+2
.endif
.elseif .match ((register), x)
.if (.match (.left (1, {address}), #))
; immediate mode
ldx #<(.right (.tcount ({address})-1, {address}))
stx _SMCDesignator+1
ldx #>(.right (.tcount ({address})-1, {address}))
stx _SMCDesignator+2
.else
; assume absolute or zero page
ldx address
stx _SMCDesignator+1
ldx 1+(address)
stx _SMCDesignator+2
.endif
.elseif .match ((register), y)
.if (.match (.left (1, {address}), #))
; immediate mode
ldy #<(.right (.tcount ({address})-1, {address}))
sty _SMCDesignator+1
ldy #>(.right (.tcount ({address})-1, {address}))
sty _SMCDesignator+2
.else
; assume absolute or zero page
ldy address
sty _SMCDesignator+1
ldy 1+(address)
sty _SMCDesignator+2
.endif
.else
.error "Invalid usage of macro 'SMC_TransferAddressSingle'"
.endif
.endmacro
.macro SMC_TransferAddress label, address
.if (.match (.left (1, {address}), #))
; immediate mode
lda #<(.right (.tcount ({address})-1, {address}))
sta _SMCDesignator+1
ldx #>(.right (.tcount ({address})-1, {address}))
stx _SMCDesignator+2
.else
; assume absolute or zero page
lda {address}
sta _SMCDesignator+1
ldx 1+{address}
stx _SMCDesignator)+2
.endif
.endmacro
.macro SMC_StoreAddress label
sta _SMCDesignator+1
stx _SMCDesignator+2
.endmacro
; smc.mac
; ca65 Macro-Pack for Self Modifying Code (SMC)
;
; (c) Christian Krüger, latest change: 17-Jul-2016
;
; This software is provided 'as-is', without any expressed or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Permission is granted to anyone to use this software for any purpose,
; including commercial applications, and to alter it and redistribute it
; freely, subject to the following restrictions:
;
; 1. The origin of this software must not be misrepresented; you must not
; claim that you wrote the original software. If you use this software
; in a product, an acknowledgment in the product documentation would be
; appreciated but is not required.
; 2. Altered source versions must be plainly marked as such, and must not
; be misrepresented as being the original software.
; 3. This notice may not be removed or altered from any source
; distribution.
;
.define _SMCDesignator .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC"))
.define _SMCAlias .mid(0, .tcount(alias) - 1, alias) .ident(.concat(.string(.right(1, alias)), "_SMC"))
.define SMC_AbsAdr $FADE
.define SMC_ZpAdr $00
.define SMC_Opcode nop
.define SMC_Value $42
.macro SMC_OperateOnValue opcode, label
opcode _SMCDesignator+1
.endmacro
.macro SMC_OperateOnLowByte opcode, label
SMC_OperateOnValue opcode, label
.endmacro
.macro SMC_OperateOnHighByte opcode, label
opcode _SMCDesignator + 2
.endmacro
.macro SMC_Import alias
.import _SMCAlias
.endmacro
.macro SMC_Export alias, label
.export _SMCAlias := _SMCDesignator
.endmacro
.macro SMC label, statement
_SMCDesignator: statement
.endmacro
.macro SMC_TransferOpcode label, opcode, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda #opcode
sta _SMCDesignator
.elseif .match ({register}, x)
ldx #opcode
stx _SMCDesignator
.elseif .match ({register}, y)
ldy #opcode
sty _SMCDesignator
.else
.error "Invalid usage of macro 'SMC_TransferOpcode'"
.endif
.endmacro
.macro SMC_LoadOpcode label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
lda _SMCDesignator
.elseif .match ({register}, x)
ldx _SMCDesignator
.elseif .match ({register}, y)
ldy _SMCDesignator
.else
.error "Invalid usage of macro 'SMC_LoadOpcode'"
.endif
.endmacro
.macro SMC_StoreOpcode label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
sta _SMCDesignator
.elseif .match ({register}, x)
stx _SMCDesignator
.elseif .match ({register}, y)
sty _SMCDesignator
.else
.error "Invalid usage of macro 'SMC_StoreOpcode'"
.endif
.endmacro
.macro SMC_ChangeBranch label, destination, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda #(<(destination - _SMCDesignator -2))
sta _SMCDesignator+1
.elseif .match ({register}, x)
ldx #(<(destination - _SMCDesignator - 2))
stx _SMCDesignator+1
.elseif .match ({register}, y)
ldy #(<(destination - _SMCDesignator - 2))
sty _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_ChangeBranch'"
.endif
.endmacro
.macro SMC_TransferValue label, value, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda value
sta _SMCDesignator+1
.elseif .match ({register}, x)
ldx value
stx _SMCDesignator+1
.elseif .match ({register}, y)
ldy value
sty _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_TransferValue'"
.endif
.endmacro
.macro SMC_LoadValue label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
lda _SMCDesignator+1
.elseif .match ({register}, x)
ldx _SMCDesignator+1
.elseif .match ({register}, y)
ldy _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_LoadValue'"
.endif
.endmacro
.macro SMC_StoreValue label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
sta _SMCDesignator+1
.elseif .match ({register}, x)
stx _SMCDesignator+1
.elseif .match ({register}, y)
sty _SMCDesignator+1
.else
.error "Invalid usage of macro 'SMC_StoreValue'"
.endif
.endmacro
.macro SMC_TransferLowByte label, value, register
SMC_TransferValue label, value, register
.endmacro
.macro SMC_LoadLowByte label, register
SMC_LoadValue label, register
.endmacro
.macro SMC_StoreLowByte label, register
SMC_StoreValue label, register
.endmacro
.macro SMC_TransferHighByte label, value, register
.if .paramcount = 2 .or .match ({register}, a) .or .match ({register}, )
lda value
sta _SMCDesignator+2
.elseif .match ({register}, x)
ldx value
stx _SMCDesignator+2
.elseif .match ({register}, y)
ldy value
sty _SMCDesignator+2
.else
.error "Invalid usage of macro 'SMC_TransferHighByte'"
.endif
.endmacro
.macro SMC_LoadHighByte label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
lda _SMCDesignator+2
.elseif .match ({register}, x)
ldx _SMCDesignator+2
.elseif .match ({register}, y)
ldy _SMCDesignator+2
.else
.error "Invalid usage of macro 'SMC_LoadHighByte'"
.endif
.endmacro
.macro SMC_StoreHighByte label, register
.if .paramcount = 1 .or .match ({register}, a) .or .match ({register}, )
sta _SMCDesignator+2
.elseif .match ({register}, x)
stx _SMCDesignator+2
.elseif .match ({register}, y)
sty _SMCDesignator+2
.else
.error "Invalid usage of macro 'SMC_StoreHighByte'"
.endif
.endmacro
.macro SMC_TransferAddressSingle label, address, register
.if .paramcount = 2 .or .match ((register), a) .or .match ({register}, )
.if (.match (.left (1, {address}), #))
; immediate mode
lda #<(.right (.tcount ({address})-1, {address}))
sta _SMCDesignator+1
lda #>(.right (.tcount ({address})-1, {address}))
sta _SMCDesignator+2
.else
; assume absolute or zero page
lda address
sta _SMCDesignator+1
lda 1+(address)
sta _SMCDesignator+2
.endif
.elseif .match ((register), x)
.if (.match (.left (1, {address}), #))
; immediate mode
ldx #<(.right (.tcount ({address})-1, {address}))
stx _SMCDesignator+1
ldx #>(.right (.tcount ({address})-1, {address}))
stx _SMCDesignator+2
.else
; assume absolute or zero page
ldx address
stx _SMCDesignator+1
ldx 1+(address)
stx _SMCDesignator+2
.endif
.elseif .match ((register), y)
.if (.match (.left (1, {address}), #))
; immediate mode
ldy #<(.right (.tcount ({address})-1, {address}))
sty _SMCDesignator+1
ldy #>(.right (.tcount ({address})-1, {address}))
sty _SMCDesignator+2
.else
; assume absolute or zero page
ldy address
sty _SMCDesignator+1
ldy 1+(address)
sty _SMCDesignator+2
.endif
.else
.error "Invalid usage of macro 'SMC_TransferAddressSingle'"
.endif
.endmacro
.macro SMC_TransferAddress label, address
.if (.match (.left (1, {address}), #))
; immediate mode
lda #<(.right (.tcount ({address})-1, {address}))
sta _SMCDesignator+1
ldx #>(.right (.tcount ({address})-1, {address}))
stx _SMCDesignator+2
.else
; assume absolute or zero page
lda {address}
sta _SMCDesignator+1
ldx 1+{address}
stx _SMCDesignator)+2
.endif
.endmacro
.macro SMC_StoreAddress label
sta _SMCDesignator+1
stx _SMCDesignator+2
.endmacro

View File

@ -1,47 +1,47 @@
/*****************************************************************************/
/* */
/* osic1p.h */
/* */
/* Challenger 1P system specific definitions */
/* */
/* */
/* */
/* (C) 2015 Stephan Muehlstrasser */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef _OSIC1P_H
#define _OSIC1P_H
/* Check for errors */
#if !defined(__OSIC1P__)
# error "This module may only be used when compiling for the Challenger 1P!"
#endif
/* The following #defines will cause the matching functions calls in conio.h
** to be overlaid by macros with the same names, saving the function call
** overhead.
*/
#define _textcolor(color) COLOR_WHITE
#define _bgcolor(color) COLOR_BLACK
#define _bordercolor(color) COLOR_BLACK
#endif
/*****************************************************************************/
/* */
/* osic1p.h */
/* */
/* Challenger 1P system specific definitions */
/* */
/* */
/* */
/* (C) 2015 Stephan Muehlstrasser */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef _OSIC1P_H
#define _OSIC1P_H
/* Check for errors */
#if !defined(__OSIC1P__)
# error "This module may only be used when compiling for the Challenger 1P!"
#endif
/* The following #defines will cause the matching functions calls in conio.h
** to be overlaid by macros with the same names, saving the function call
** overhead.
*/
#define _textcolor(color) COLOR_WHITE
#define _bgcolor(color) COLOR_BLACK
#define _bordercolor(color) COLOR_BLACK
#endif

View File

@ -1,172 +1,172 @@
/*****************************************************************************/
/* */
/* zlib.h */
/* */
/* Decompression routines for the 'deflate' format */
/* */
/* */
/* */
/* (C) 2000-2015 Piotr Fusik <fox@scene.pl> */
/* */
/* This file is based on the zlib.h from 'zlib' general purpose compression */
/* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */
/* */
/* Jean-loup Gailly Mark Adler */
/* jloup@gzip.org madler@alumni.caltech.edu */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef _ZLIB_H
#define _ZLIB_H
#define Z_OK 0
#define Z_DATA_ERROR (-3)
/* Return codes for uncompress() */
#define Z_DEFLATED 8
/* The deflate compression method (the only one supported) */
#define Z_NULL 0
unsigned __fastcall__ inflatemem (char* dest, const char* source);
/*
Decompresses the source buffer into the destination buffer.
Returns the size of the uncompressed data (number of bytes written starting
from dest).
This function expects data in the DEFLATE format, described in RFC
(Request for Comments) 1951 in the file
ftp://ds.internic.net/rfc/rfc1951.txt.
This function does not exist in the original zlib. Its implementation
using original zlib might be following:
unsigned inflatemem (char* dest, const char* source)
{
z_stream stream;
stream.next_in = (Bytef*) source;
stream.avail_in = 65535;
stream.next_out = dest;
stream.avail_out = 65535;
stream.zalloc = (alloc_func) 0;
stream.zfree = (free_func) 0;
inflateInit2(&stream, -MAX_WBITS);
inflate(&stream, Z_FINISH);
inflateEnd(&stream);
return stream.total_out;
}
*/
int __fastcall__ uncompress (char* dest, unsigned* destLen,
const char* source, unsigned sourceLen);
/*
Original zlib description:
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
Implementation notes:
This function expects data in the ZLIB format, described in RFC 1950
in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is
essentially the DEFLATE format plus a very small header and Adler-32
checksum.
Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation.
*/
unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf,
unsigned len);
/*
Original zlib description:
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is NULL, this function returns
the required initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
much faster. Usage example:
unsigned long adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();
Implementation notes:
This function isn't actually much faster than crc32(), but it is smaller
and does not use any lookup tables.
*/
unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf,
unsigned len);
/*
Original zlib description:
Update a running crc with the bytes buf[0..len-1] and return the updated
crc. If buf is NULL, this function returns the required initial value
for the crc. Pre- and post-conditioning (one's complement) is performed
within this function so it shouldn't be done by the application.
Usage example:
unsigned long crc = crc32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
crc = crc32(crc, buffer, length);
}
if (crc != original_crc) error();
Implementation notes:
This function uses statically allocated 1 KB lookup table. The table is
initialised before it is used for the first time (that is, if buffer is
NULL or length is zero, then the lookup table isn't initialised).
*/
/* end of zlib.h */
#endif
/*****************************************************************************/
/* */
/* zlib.h */
/* */
/* Decompression routines for the 'deflate' format */
/* */
/* */
/* */
/* (C) 2000-2015 Piotr Fusik <fox@scene.pl> */
/* */
/* This file is based on the zlib.h from 'zlib' general purpose compression */
/* library, version 1.1.3, (C) 1995-1998 Jean-loup Gailly and Mark Adler. */
/* */
/* Jean-loup Gailly Mark Adler */
/* jloup@gzip.org madler@alumni.caltech.edu */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef _ZLIB_H
#define _ZLIB_H
#define Z_OK 0
#define Z_DATA_ERROR (-3)
/* Return codes for uncompress() */
#define Z_DEFLATED 8
/* The deflate compression method (the only one supported) */
#define Z_NULL 0
unsigned __fastcall__ inflatemem (char* dest, const char* source);
/*
Decompresses the source buffer into the destination buffer.
Returns the size of the uncompressed data (number of bytes written starting
from dest).
This function expects data in the DEFLATE format, described in RFC
(Request for Comments) 1951 in the file
ftp://ds.internic.net/rfc/rfc1951.txt.
This function does not exist in the original zlib. Its implementation
using original zlib might be following:
unsigned inflatemem (char* dest, const char* source)
{
z_stream stream;
stream.next_in = (Bytef*) source;
stream.avail_in = 65535;
stream.next_out = dest;
stream.avail_out = 65535;
stream.zalloc = (alloc_func) 0;
stream.zfree = (free_func) 0;
inflateInit2(&stream, -MAX_WBITS);
inflate(&stream, Z_FINISH);
inflateEnd(&stream);
return stream.total_out;
}
*/
int __fastcall__ uncompress (char* dest, unsigned* destLen,
const char* source, unsigned sourceLen);
/*
Original zlib description:
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
Implementation notes:
This function expects data in the ZLIB format, described in RFC 1950
in the file ftp://ds.internic.net/rfc/rfc1950.txt. The ZLIB format is
essentially the DEFLATE format plus a very small header and Adler-32
checksum.
Z_MEM_ERROR and Z_BUF_ERROR are never returned in this implementation.
*/
unsigned long __fastcall__ adler32 (unsigned long adler, const char* buf,
unsigned len);
/*
Original zlib description:
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is NULL, this function returns
the required initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
much faster. Usage example:
unsigned long adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();
Implementation notes:
This function isn't actually much faster than crc32(), but it is smaller
and does not use any lookup tables.
*/
unsigned long __fastcall__ crc32 (unsigned long crc, const char* buf,
unsigned len);
/*
Original zlib description:
Update a running crc with the bytes buf[0..len-1] and return the updated
crc. If buf is NULL, this function returns the required initial value
for the crc. Pre- and post-conditioning (one's complement) is performed
within this function so it shouldn't be done by the application.
Usage example:
unsigned long crc = crc32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
crc = crc32(crc, buffer, length);
}
if (crc != original_crc) error();
Implementation notes:
This function uses statically allocated 1 KB lookup table. The table is
initialised before it is used for the first time (that is, if buffer is
NULL or length is zero, then the lookup table isn't initialised).
*/
/* end of zlib.h */
#endif

View File

@ -1,376 +1,376 @@
;
; Extended memory driver for 65816 based extra RAM. Driver works without
; problems when statically linked.
;
; Marco van den Heuvel, 2015-12-01
;
.include "zeropage.inc"
.include "em-kernel.inc"
.include "em-error.inc"
.macpack generic
.macpack module
; ------------------------------------------------------------------------
; Header. Includes jump table
module_header _c64_65816_emd
; Driver signature
.byte $65, $6d, $64 ; "emd"
.byte EMD_API_VERSION ; EM API version number
; Library reference
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr PAGECOUNT
.addr MAP
.addr USE
.addr COMMIT
.addr COPYFROM
.addr COPYTO
; ------------------------------------------------------------------------
; Data.
.bss
isnotscpu: .res 1 ; SuperCPU not present
curpage: .res 1 ; Current page number
curbank: .res 1 ; Current bank number (+1)
bankcount: .res 1 ; Number of available banks (pages = banks * 256)
window: .res 256 ; Memory "window"
.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 EM_ERR_xx code in a/x.
;
INSTALL:
sei
clc
sed
lda #$99
adc #$01 ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly
cld
bne @not_present
clc
.P816
sep #$01 ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02
.P02
bcc @not_present
lda $d0bc
and #$80
sta isnotscpu
lda $07e8
pha ; save value incase it was used somewhere else
ldx #$ff
@fillloop: ; fill from top (bank 255) to bottom
txa
pha
.P816
plb ; pull dbr
.P02
stx $07e8
dex
cpx #$ff
bne @fillloop
inx
@compareloop: ; check from bottom to top
txa
pha
.P816
plb
.P02
cmp $07e8
bne @found_pages
.P816
inc
.P02
sta $07e8
cmp $07e8
bne @found_pages
inx
bne @compareloop
@found_pages:
dex
lda #$00
pha
.P816
plb
.P02
pla
sta $07e8
cli
lda isnotscpu
bne @noextradex
dex
@noextradex:
stx bankcount
lda #<EM_ERR_OK
ldx #>EM_ERR_OK
rts
@not_present:
cli
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
; 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
; ------------------------------------------------------------------------
; PAGECOUNT: Return the total number of available pages in a/x.
;
PAGECOUNT:
lda #$00 ; a whole bank is either usable or not
ldx bankcount
rts
; ------------------------------------------------------------------------
; MAP: Map the page in a/x into memory and return a pointer to the page in
; a/x. The contents of the currently mapped page (if any) may be discarded
; by the driver.
;
MAP: sta curpage ; Remember the new page
stx curbank ; Remember the new bank
sta ptr2+1 ; src address low
lda #$00
sta ptr2 ; src address high
inx
ldy isnotscpu ; check if not scpu
bne @notscpu
inx
@notscpu:
stx tmp2 ; src bank
sta tmp1 ; dst bank
sta ptr3+1 ; length high
lda #$ff
sta ptr3 ; length low
lda #<window
sta ptr1 ; dst address low
ldx #>window
stx ptr1+1 ; dst address high
jsr transfer
rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
USE: sta curpage ; Remember the page
stx curbank ; Remember the bank
lda #<window
ldx #>window ; Return the window
rts
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: lda curpage ; Get the current page
sta ptr1+1 ; dst high
ldx #$00
stx ptr1 ; dst low
lda #<window
sta ptr2 ; src low
lda #>window
sta ptr2+1 ; src high
stx ptr3+1 ; length high
lda #$ff
sta ptr3 ; length low
stx tmp2 ; src bank
ldy curbank ; Get the current bank
iny
ldx isnotscpu
bne @notascpu
iny
@notascpu:
sty tmp1 ; dst bank
jsr transfer
rts
; ------------------------------------------------------------------------
; COPYFROM: Copy from extended into linear memory. A pointer to a structure
; describing the request is passed in a/x.
; The function must not return anything.
;
COPYFROM:
sta ptr4
stx ptr4+1 ; Save the passed em_copy pointer
ldy #EM_COPY::COUNT+1 ; start at the end of the struct
lda (ptr4),y ; get high byte of count
tax
dey
lda (ptr4),y ; get low byte of count
bne @nodex
dex
@nodex:
.P816
dec
.P02
sta ptr3 ; length low
stx ptr3+1 ; length high
dey
lda (ptr4),y ; get bank
.P816
inc
.P02
ldx isnotscpu
bne @notscpu64
.P816
inc
.P02
@notscpu64:
sta tmp2 ; src bank
dey
lda (ptr4),y ; get page
sta ptr2+1 ; src high
dey
lda (ptr4),y ; get offset in page
sta ptr2 ; src low
dey
lda (ptr4),y ; get memory buffer high
sta ptr1+1 ; dst high
dey
lda (ptr4),y ; get memory buffer low
sta ptr1 ; dst low
lda #$00
sta tmp1 ; dst bank
jsr transfer
rts
; ------------------------------------------------------------------------
; COPYTO: Copy from linear into extended memory. A pointer to a structure
; describing the request is passed in a/x.
; The function must not return anything.
;
COPYTO: sta ptr4
stx ptr4+1 ; Save the passed em_copy pointer
ldy #EM_COPY::COUNT+1 ; start at the end of the struct
lda (ptr4),y ; get high byte of count
tax
dey
lda (ptr4),y ; get low byte of count
bne @nodex2
dex
@nodex2:
.P816
dec
.P02
sta ptr3 ; length low
txa
sta ptr3+1 ; length high
dey
lda (ptr4),y ; get bank
.P816
inc
.P02
ldx isnotscpu
bne @notascpu64
.P816
inc
.P02
@notascpu64:
sta tmp1 ; dst bank
dey
lda (ptr4),y ; get page
sta ptr1+1 ; dst high
dey
lda (ptr4),y ; get page offset
sta ptr1 ; dst low
dey
lda (ptr4),y ; get memory buffer high
sta ptr2+1 ; src low
dey
lda (ptr4),y ; get memory buffer low
sta ptr2 ; src high
lda #$00
sta tmp2 ; src bank
jsr transfer
rts
; ------------------------------------------------------------------------
; Helper function for moving a block, the following is used:
; ptr1: dst
; ptr2: src
; ptr3: length
; tmp1: dst bank
; tmp2: src bank
transfer:
.P816
.A8
.I8
sei
pha
phx
phy
ldx tmp1 ; load srcbank
stx @move+1 ; store srcbank in move + 1
ldy tmp2 ; load dstbank
sty @move+2 ; store dstbank in move + 2
clc ; switch to native mode
xce
php ; save status bits
rep #%00110000 ; set A and index to 16bit
.A16
.I16
ldy ptr1
ldx ptr2
lda ptr3
@move:
mvn 0,0
plp ; restore status bits
.A8
.I8
lda #$00
pha
plb ; restore dbr
sec
xce ; switch to emul mode
ply
plx
pla
cli
rts
.P02
;
; Extended memory driver for 65816 based extra RAM. Driver works without
; problems when statically linked.
;
; Marco van den Heuvel, 2015-12-01
;
.include "zeropage.inc"
.include "em-kernel.inc"
.include "em-error.inc"
.macpack generic
.macpack module
; ------------------------------------------------------------------------
; Header. Includes jump table
module_header _c64_65816_emd
; Driver signature
.byte $65, $6d, $64 ; "emd"
.byte EMD_API_VERSION ; EM API version number
; Library reference
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr PAGECOUNT
.addr MAP
.addr USE
.addr COMMIT
.addr COPYFROM
.addr COPYTO
; ------------------------------------------------------------------------
; Data.
.bss
isnotscpu: .res 1 ; SuperCPU not present
curpage: .res 1 ; Current page number
curbank: .res 1 ; Current bank number (+1)
bankcount: .res 1 ; Number of available banks (pages = banks * 256)
window: .res 256 ; Memory "window"
.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 EM_ERR_xx code in a/x.
;
INSTALL:
sei
clc
sed
lda #$99
adc #$01 ; on 65C02, 65SC02, 65CE02, 65802 and 65816 sets the zero flag correctly
cld
bne @not_present
clc
.P816
sep #$01 ; nop #$01 on 65C02/65SC02 and lda ($01,s),y on 65CE02
.P02
bcc @not_present
lda $d0bc
and #$80
sta isnotscpu
lda $07e8
pha ; save value incase it was used somewhere else
ldx #$ff
@fillloop: ; fill from top (bank 255) to bottom
txa
pha
.P816
plb ; pull dbr
.P02
stx $07e8
dex
cpx #$ff
bne @fillloop
inx
@compareloop: ; check from bottom to top
txa
pha
.P816
plb
.P02
cmp $07e8
bne @found_pages
.P816
inc
.P02
sta $07e8
cmp $07e8
bne @found_pages
inx
bne @compareloop
@found_pages:
dex
lda #$00
pha
.P816
plb
.P02
pla
sta $07e8
cli
lda isnotscpu
bne @noextradex
dex
@noextradex:
stx bankcount
lda #<EM_ERR_OK
ldx #>EM_ERR_OK
rts
@not_present:
cli
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
; 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
; ------------------------------------------------------------------------
; PAGECOUNT: Return the total number of available pages in a/x.
;
PAGECOUNT:
lda #$00 ; a whole bank is either usable or not
ldx bankcount
rts
; ------------------------------------------------------------------------
; MAP: Map the page in a/x into memory and return a pointer to the page in
; a/x. The contents of the currently mapped page (if any) may be discarded
; by the driver.
;
MAP: sta curpage ; Remember the new page
stx curbank ; Remember the new bank
sta ptr2+1 ; src address low
lda #$00
sta ptr2 ; src address high
inx
ldy isnotscpu ; check if not scpu
bne @notscpu
inx
@notscpu:
stx tmp2 ; src bank
sta tmp1 ; dst bank
sta ptr3+1 ; length high
lda #$ff
sta ptr3 ; length low
lda #<window
sta ptr1 ; dst address low
ldx #>window
stx ptr1+1 ; dst address high
jsr transfer
rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
USE: sta curpage ; Remember the page
stx curbank ; Remember the bank
lda #<window
ldx #>window ; Return the window
rts
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: lda curpage ; Get the current page
sta ptr1+1 ; dst high
ldx #$00
stx ptr1 ; dst low
lda #<window
sta ptr2 ; src low
lda #>window
sta ptr2+1 ; src high
stx ptr3+1 ; length high
lda #$ff
sta ptr3 ; length low
stx tmp2 ; src bank
ldy curbank ; Get the current bank
iny
ldx isnotscpu
bne @notascpu
iny
@notascpu:
sty tmp1 ; dst bank
jsr transfer
rts
; ------------------------------------------------------------------------
; COPYFROM: Copy from extended into linear memory. A pointer to a structure
; describing the request is passed in a/x.
; The function must not return anything.
;
COPYFROM:
sta ptr4
stx ptr4+1 ; Save the passed em_copy pointer
ldy #EM_COPY::COUNT+1 ; start at the end of the struct
lda (ptr4),y ; get high byte of count
tax
dey
lda (ptr4),y ; get low byte of count
bne @nodex
dex
@nodex:
.P816
dec
.P02
sta ptr3 ; length low
stx ptr3+1 ; length high
dey
lda (ptr4),y ; get bank
.P816
inc
.P02
ldx isnotscpu
bne @notscpu64
.P816
inc
.P02
@notscpu64:
sta tmp2 ; src bank
dey
lda (ptr4),y ; get page
sta ptr2+1 ; src high
dey
lda (ptr4),y ; get offset in page
sta ptr2 ; src low
dey
lda (ptr4),y ; get memory buffer high
sta ptr1+1 ; dst high
dey
lda (ptr4),y ; get memory buffer low
sta ptr1 ; dst low
lda #$00
sta tmp1 ; dst bank
jsr transfer
rts
; ------------------------------------------------------------------------
; COPYTO: Copy from linear into extended memory. A pointer to a structure
; describing the request is passed in a/x.
; The function must not return anything.
;
COPYTO: sta ptr4
stx ptr4+1 ; Save the passed em_copy pointer
ldy #EM_COPY::COUNT+1 ; start at the end of the struct
lda (ptr4),y ; get high byte of count
tax
dey
lda (ptr4),y ; get low byte of count
bne @nodex2
dex
@nodex2:
.P816
dec
.P02
sta ptr3 ; length low
txa
sta ptr3+1 ; length high
dey
lda (ptr4),y ; get bank
.P816
inc
.P02
ldx isnotscpu
bne @notascpu64
.P816
inc
.P02
@notascpu64:
sta tmp1 ; dst bank
dey
lda (ptr4),y ; get page
sta ptr1+1 ; dst high
dey
lda (ptr4),y ; get page offset
sta ptr1 ; dst low
dey
lda (ptr4),y ; get memory buffer high
sta ptr2+1 ; src low
dey
lda (ptr4),y ; get memory buffer low
sta ptr2 ; src high
lda #$00
sta tmp2 ; src bank
jsr transfer
rts
; ------------------------------------------------------------------------
; Helper function for moving a block, the following is used:
; ptr1: dst
; ptr2: src
; ptr3: length
; tmp1: dst bank
; tmp2: src bank
transfer:
.P816
.A8
.I8
sei
pha
phx
phy
ldx tmp1 ; load srcbank
stx @move+1 ; store srcbank in move + 1
ldy tmp2 ; load dstbank
sty @move+2 ; store dstbank in move + 2
clc ; switch to native mode
xce
php ; save status bits
rep #%00110000 ; set A and index to 16bit
.A16
.I16
ldy ptr1
ldx ptr2
lda ptr3
@move:
mvn 0,0
plp ; restore status bits
.A8
.I8
lda #$00
pha
plb ; restore dbr
sec
xce ; switch to emul mode
ply
plx
pla
cli
rts
.P02

View File

@ -1,50 +1,50 @@
;
; char cgetc (void);
;
.constructor initcgetc
.export _cgetc
.import cursor
.include "osic1p.inc"
.include "extzp.inc"
.include "zeropage.inc"
; Initialize one-character buffer that is filled by kbhit()
.segment "ONCE"
initcgetc:
lda #$00
sta CHARBUF ; No character in buffer initially
rts
; Input routine from 65V PROM MONITOR, show cursor if enabled
.code
_cgetc:
lda CHARBUF ; character in buffer available?
beq nobuffer
tax ; save character in X
lda #$00
sta CHARBUF ; empty buffer
beq restorex ; restore X and return
nobuffer:
lda cursor ; show cursor?
beq nocursor
ldy CURS_X
lda (SCREEN_PTR),y ; fetch current character
sta tmp1 ; save it
lda #$A1 ; full white square
sta (SCREEN_PTR),y ; store at cursor position
nocursor:
jsr INPUTC ; get input character in A
ldx cursor
beq done ; was cursor on?
tax ; save A in X
lda tmp1 ; fetch saved character
ldy CURS_X
sta (SCREEN_PTR),y ; store at cursor position
restorex:
txa ; restore saved character from X
done:
ldx #$00 ; high byte of int return value
rts
;
; char cgetc (void);
;
.constructor initcgetc
.export _cgetc
.import cursor
.include "osic1p.inc"
.include "extzp.inc"
.include "zeropage.inc"
; Initialize one-character buffer that is filled by kbhit()
.segment "ONCE"
initcgetc:
lda #$00
sta CHARBUF ; No character in buffer initially
rts
; Input routine from 65V PROM MONITOR, show cursor if enabled
.code
_cgetc:
lda CHARBUF ; character in buffer available?
beq nobuffer
tax ; save character in X
lda #$00
sta CHARBUF ; empty buffer
beq restorex ; restore X and return
nobuffer:
lda cursor ; show cursor?
beq nocursor
ldy CURS_X
lda (SCREEN_PTR),y ; fetch current character
sta tmp1 ; save it
lda #$A1 ; full white square
sta (SCREEN_PTR),y ; store at cursor position
nocursor:
jsr INPUTC ; get input character in A
ldx cursor
beq done ; was cursor on?
tax ; save A in X
lda tmp1 ; fetch saved character
ldy CURS_X
sta (SCREEN_PTR),y ; store at cursor position
restorex:
txa ; restore saved character from X
done:
ldx #$00 ; high byte of int return value
rts

View File

@ -1,4 +1,4 @@
; Addresses
INPUTC := $FD00 ; Input character from keyboard
RESET := $FF00 ; Reset address, show boot prompt
KBD := $DF00 ; Polled keyboard register
; Addresses
INPUTC := $FD00 ; Input character from keyboard
RESET := $FF00 ; Reset address, show boot prompt
KBD := $DF00 ; Polled keyboard register

View File

@ -1,183 +1,183 @@
;
; Macro definitions for screen layout modules
;
.include "extzp.inc"
.linecont +
;
; Internal function for screensize()
;
.macro osi_screensize ScrWidth, ScrHeight
; Macro implementation of internal screensize
; function for given width and height in
; characters
.export screensize
.proc screensize
ldx #ScrWidth
ldy #ScrHeight
rts
.endproc
.endmacro
;
; void clrscr (void);
;
.macro osi_clrscr ScrBase, ScrRamSize
.export _clrscr
.proc _clrscr
lda #<ScrBase ; Fill whole video RAM with blanks by calling
ldx #>ScrBase ; memset appropriately
jsr pushax
lda #' '
ldx #$00
jsr pushax
lda #<ScrRamSize
ldx #>ScrRamSize
jsr _memset
lda #$00 ; Cursor in upper left corner
sta CURS_X
sta CURS_Y
jmp plot ; Set the cursor position
.endproc
.endmacro
;
; cputc/cputcxy for Challenger 1P
; Based on PET/CBM implementation
;
.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
ScrollDist, ScrLo, ScrHi
; Number of characters to move for scrolling
; by one line
ScrollLength = (ScrHeight - 1) * ScrollDist
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
_cputcxy:
pha ; Save C
jsr gotoxy ; Set cursor, drop x and y
pla ; Restore C
; Plot a character - also used as internal function
_cputc: cmp #$0A ; CR?
bne L1
lda #0
sta CURS_X
beq plot ; Recalculate pointers
L1: cmp #$0D ; LF?
beq newline ; Recalculate pointers
cputdirect:
jsr putchar ; Write the character to the screen
; Advance cursor position, register Y contains horizontal position after
; putchar
cpy #(ScrWidth - 1) ; Check whether line is full
bne L3
jsr newline ; New line
ldy #$FF ; + cr
L3: iny
sty CURS_X
rts
newline:
inc CURS_Y
lda CURS_Y
cmp #ScrHeight ; Screen height
bne plot
dec CURS_Y ; Bottom of screen reached, scroll
; Scroll destination address
lda #<(ScrBase + ScrFirstChar)
ldx #>(ScrBase + ScrFirstChar)
jsr pushax
; Scroll source address
lda #<(ScrBase + ScrFirstChar + ScrollDist)
ldx #>(ScrBase + ScrFirstChar + ScrollDist)
jsr pushax
; Number of characters to move
lda #<ScrollLength
ldx #>ScrollLength
jsr _memmove
; Address of first character in last line
; of screen
lda #<(ScrBase + ScrFirstChar + ScrollLength)
sta ptr1
lda #>(ScrBase + ScrFirstChar + ScrollLength)
sta ptr1+1
ldy #ScrWidth ; Fill last line with blanks
lda #' '
clrln: sta (ptr1),y
dey
bpl clrln
plot: ldy CURS_Y
lda ScrLo,y
sta SCREEN_PTR
lda ScrHi,y
sta SCREEN_PTR+1
rts
; Write one character to the screen without doing anything else, return X
; position in register Y
putchar:
ldy CURS_X
sta (SCREEN_PTR),y ; Set char
rts
.endmacro
.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \
ScrWidth, ScrHeight, ScrollDist
.import gotoxy
.import _memmove, _memset, pushax
.importzp ptr1
.rodata
; Screen address tables - offset to real screen
ScrTabLo:
.repeat ScrHeight, I
.byte <(ScrBase + ScrFirstChar + I * ScrollDist)
.endrep
ScrTabHi:
.repeat ScrHeight, I
.byte >(ScrBase + ScrFirstChar + I * ScrollDist)
.endrep
.code
osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
ScrollDist, ScrTabLo, ScrTabHi
osi_screensize ScrWidth, ScrHeight
osi_clrscr ScrBase, ScrRamSize
;
; Macro definitions for screen layout modules
;
.include "extzp.inc"
.linecont +
;
; Internal function for screensize()
;
.macro osi_screensize ScrWidth, ScrHeight
; Macro implementation of internal screensize
; function for given width and height in
; characters
.export screensize
.proc screensize
ldx #ScrWidth
ldy #ScrHeight
rts
.endproc
.endmacro
;
; void clrscr (void);
;
.macro osi_clrscr ScrBase, ScrRamSize
.export _clrscr
.proc _clrscr
lda #<ScrBase ; Fill whole video RAM with blanks by calling
ldx #>ScrBase ; memset appropriately
jsr pushax
lda #' '
ldx #$00
jsr pushax
lda #<ScrRamSize
ldx #>ScrRamSize
jsr _memset
lda #$00 ; Cursor in upper left corner
sta CURS_X
sta CURS_Y
jmp plot ; Set the cursor position
.endproc
.endmacro
;
; cputc/cputcxy for Challenger 1P
; Based on PET/CBM implementation
;
.macro osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
ScrollDist, ScrLo, ScrHi
; Number of characters to move for scrolling
; by one line
ScrollLength = (ScrHeight - 1) * ScrollDist
;
; void cputcxy (unsigned char x, unsigned char y, char c);
; void cputc (char c);
;
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
_cputcxy:
pha ; Save C
jsr gotoxy ; Set cursor, drop x and y
pla ; Restore C
; Plot a character - also used as internal function
_cputc: cmp #$0A ; CR?
bne L1
lda #0
sta CURS_X
beq plot ; Recalculate pointers
L1: cmp #$0D ; LF?
beq newline ; Recalculate pointers
cputdirect:
jsr putchar ; Write the character to the screen
; Advance cursor position, register Y contains horizontal position after
; putchar
cpy #(ScrWidth - 1) ; Check whether line is full
bne L3
jsr newline ; New line
ldy #$FF ; + cr
L3: iny
sty CURS_X
rts
newline:
inc CURS_Y
lda CURS_Y
cmp #ScrHeight ; Screen height
bne plot
dec CURS_Y ; Bottom of screen reached, scroll
; Scroll destination address
lda #<(ScrBase + ScrFirstChar)
ldx #>(ScrBase + ScrFirstChar)
jsr pushax
; Scroll source address
lda #<(ScrBase + ScrFirstChar + ScrollDist)
ldx #>(ScrBase + ScrFirstChar + ScrollDist)
jsr pushax
; Number of characters to move
lda #<ScrollLength
ldx #>ScrollLength
jsr _memmove
; Address of first character in last line
; of screen
lda #<(ScrBase + ScrFirstChar + ScrollLength)
sta ptr1
lda #>(ScrBase + ScrFirstChar + ScrollLength)
sta ptr1+1
ldy #ScrWidth ; Fill last line with blanks
lda #' '
clrln: sta (ptr1),y
dey
bpl clrln
plot: ldy CURS_Y
lda ScrLo,y
sta SCREEN_PTR
lda ScrHi,y
sta SCREEN_PTR+1
rts
; Write one character to the screen without doing anything else, return X
; position in register Y
putchar:
ldy CURS_X
sta (SCREEN_PTR),y ; Set char
rts
.endmacro
.macro osi_screen_funcs ScrBase, ScrRamSize, ScrFirstChar, \
ScrWidth, ScrHeight, ScrollDist
.import gotoxy
.import _memmove, _memset, pushax
.importzp ptr1
.rodata
; Screen address tables - offset to real screen
ScrTabLo:
.repeat ScrHeight, I
.byte <(ScrBase + ScrFirstChar + I * ScrollDist)
.endrep
ScrTabHi:
.repeat ScrHeight, I
.byte >(ScrBase + ScrFirstChar + I * ScrollDist)
.endrep
.code
osi_cputfuncs ScrBase, ScrFirstChar, ScrWidth, ScrHeight, \
ScrollDist, ScrTabLo, ScrTabHi
osi_screensize ScrWidth, ScrHeight
osi_clrscr ScrBase, ScrRamSize
.endmacro

View File

@ -1,38 +1,38 @@
/*
!!DESCRIPTION!! div/mod test
!!ORIGIN!!
!!LICENCE!! public domain
*/
#include <stdio.h>
void printc(signed char a,signed char b){
signed char x=a/b,y=a%b,z=a*b;
printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);
}
void prints(short a,short b){
short x=a/b,y=a%b,z=a*b;
printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);
}
void printl(long a,long b){
long x=a/b,y=a%b,z=a*b;
printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z);
}
int main(void) {
printl( 3,-2);
printl(-3,-2);
printl(-3, 2);
printl( 3, 2);
printf("-\n");
prints( 3,-2);
prints(-3,-2);
prints(-3, 2);
prints( 3, 2);
printf("-\n");
printc( 3,-2);
printc(-3,-2);
printc(-3, 2);
printc( 3, 2);
/*
!!DESCRIPTION!! div/mod test
!!ORIGIN!!
!!LICENCE!! public domain
*/
#include <stdio.h>
void printc(signed char a,signed char b){
signed char x=a/b,y=a%b,z=a*b;
printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);
}
void prints(short a,short b){
short x=a/b,y=a%b,z=a*b;
printf("%3d,%3d is %3d,%3d,%3d\n",a,b,x,y,z);
}
void printl(long a,long b){
long x=a/b,y=a%b,z=a*b;
printf("%3ld,%3ld is %3ld,%3ld,%3ld\n",a,b,x,y,z);
}
int main(void) {
printl( 3,-2);
printl(-3,-2);
printl(-3, 2);
printl( 3, 2);
printf("-\n");
prints( 3,-2);
prints(-3,-2);
prints(-3, 2);
prints( 3, 2);
printf("-\n");
printc( 3,-2);
printc(-3,-2);
printc(-3, 2);
printc( 3, 2);
return 0;
}
}

View File

@ -1,95 +1,95 @@
/*
!!DESCRIPTION!! variable initialization
!!ORIGIN!! LCC 4.1 Testsuite
!!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC
*/
#include "common.h"
/* todo: add back conditional stuff here ! */
typedef struct { int codes[3]; char name[6]; } Word;
#ifdef NO_IMPLICIT_FUNC_PROTOTYPES
#ifdef NO_OLD_FUNC_DECL
f();
void g(Word *p);
h();
#else
f();
g();
h();
#endif
#endif
/*
Word words[] = {
1, 2, 3,"if",
{ { 4, 5 }, { 'f', 'o', 'r' } },
6, 7, 8, {"else"},
{ { 9, 10, 11,}, 'w', 'h', 'i', 'l', 'e', },
{ 0 },
}, *wordlist = words;
*/
Word words[] = {
{{1, 2, 3},"if"},
{ { 4, 5 }, { 'f', 'o', 'r' } },
{{6, 7, 8}, "else"},
{ { 9, 10, 11}, {'w', 'h', 'i', 'l', 'e', }},
{{ 0 }},
}, *wordlist = words;
/*int x[][5] = { 1, 2, 3, 4, 0, { 5, 6 }, { 7 } };*/
int x[][5] = { {1, 2, 3, 4, 0 }, { 5, 6 }, { 7 } };
int *y[] = { x[0], x[1], x[2], 0 };
main()
{
int i, j;
for (i = 0; y[i]; i++) {
for (j = 0; y[i][j]; j++)
printf(" %d", y[i][j]);
printf("\n");
}
f();
g(wordlist);
return 0;
}
f() {
static char *keywords[] = {"if", "for", "else", "while", 0, };
char **p;
for (p = keywords; *p; p++)
printf("%s\n", *p);
}
#ifdef NO_OLD_FUNC_DECL
void g(Word *p)
#else
g(p)
Word *p;
#endif
{
int i;
for ( ; p->codes[0]; p++) {
for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++)
printf("%d ", p->codes[i]);
printf("%s\n", p->name);
}
h();
}
h()
{
int i;
for (i = 0; i < sizeof(words)/sizeof(Word); i++)
printf("%d %d %d %s\n", words[i].codes[0],
words[i].codes[1], words[i].codes[2],
&words[i].name[0]);
}
/*
!!DESCRIPTION!! variable initialization
!!ORIGIN!! LCC 4.1 Testsuite
!!LICENCE!! own, freely distributeable for non-profit. read CPYRIGHT.LCC
*/
#include "common.h"
/* todo: add back conditional stuff here ! */
typedef struct { int codes[3]; char name[6]; } Word;
#ifdef NO_IMPLICIT_FUNC_PROTOTYPES
#ifdef NO_OLD_FUNC_DECL
f();
void g(Word *p);
h();
#else
f();
g();
h();
#endif
#endif
/*
Word words[] = {
1, 2, 3,"if",
{ { 4, 5 }, { 'f', 'o', 'r' } },
6, 7, 8, {"else"},
{ { 9, 10, 11,}, 'w', 'h', 'i', 'l', 'e', },
{ 0 },
}, *wordlist = words;
*/
Word words[] = {
{{1, 2, 3},"if"},
{ { 4, 5 }, { 'f', 'o', 'r' } },
{{6, 7, 8}, "else"},
{ { 9, 10, 11}, {'w', 'h', 'i', 'l', 'e', }},
{{ 0 }},
}, *wordlist = words;
/*int x[][5] = { 1, 2, 3, 4, 0, { 5, 6 }, { 7 } };*/
int x[][5] = { {1, 2, 3, 4, 0 }, { 5, 6 }, { 7 } };
int *y[] = { x[0], x[1], x[2], 0 };
main()
{
int i, j;
for (i = 0; y[i]; i++) {
for (j = 0; y[i][j]; j++)
printf(" %d", y[i][j]);
printf("\n");
}
f();
g(wordlist);
return 0;
}
f() {
static char *keywords[] = {"if", "for", "else", "while", 0, };
char **p;
for (p = keywords; *p; p++)
printf("%s\n", *p);
}
#ifdef NO_OLD_FUNC_DECL
void g(Word *p)
#else
g(p)
Word *p;
#endif
{
int i;
for ( ; p->codes[0]; p++) {
for (i = 0; i < sizeof p->codes/sizeof(p->codes[0]); i++)
printf("%d ", p->codes[i]);
printf("%s\n", p->name);
}
h();
}
h()
{
int i;
for (i = 0; i < sizeof(words)/sizeof(Word); i++)
printf("%d %d %d %s\n", words[i].codes[0],
words[i].codes[1], words[i].codes[2],
&words[i].name[0]);
}

View File

@ -1,112 +1,112 @@
/*
!!DESCRIPTION!! pointer test
!!ORIGIN!!
!!LICENCE!! public domain
*/
#include "common.h"
#include <stdio.h>
/*
check behaviour on incompletely declared arrays
*/
char i1[];
void test1(void) {
int a;
a=sizeof(i1[0]);
printf("%04x - ",a);
if(sizeof(i1[0])==sizeof(char)) {
/* gcc gives size of element */
printf("sizeof(i1[0]) gives size of element\n");
}
if(sizeof(i1[0])==sizeof(char*)) {
printf("sizeof(i1[0]) gives size of pointer to element\n");
}
}
/*
check behaviour on string init
*/
char t1[]="abcde";
char t2[]={"abcde"};
char *t3="abcde";
char *t4={"abcde"};
void test2(void) {
char c1,c2,c3,c4;
int i,e=0;
for(i=0;i<5;i++){
c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i];
/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */
printf("%c %c %c %c\n",c1,c2,c3,c4);
if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1;
}
if(e) printf("test2 failed.\n");
else printf("test2 ok.\n");
}
/*
check behaviour on extern-declarations inside functions
*/
typedef struct {
char *name;
void *func;
} A3;
#ifdef NO_SLOPPY_STRUCT_INIT
A3 a3[] = {
{ "test3", (void*) NULL },
{ "test3", (void*) NULL },
};
#else
/*gcc warning: missing braces around initializer (near initialization for `a3[0]')
this type of struct-initialization seems to be kinda common */
A3 a3[] = {
"test3", (void*) NULL ,
"test3", (void*) NULL ,
};
#endif
void test3a(A3 *list, int number){
printf("%s %d\n",list->name,number);
}
static void test31(void)
{
extern A3 a3[];
test3a(a3, -1);
}
#if 0
/* this variation compiles and works with cc65, but gives an error with gcc :=P */
static void test32(void)
{
extern A3 *a3;
test3a(a3, -1);
}
#endif
static void test30(void)
{
test3a(a3, -1);
}
/*
todo: add test on function pointers in the form of (*func)(arg) ...
cc65 seems to have problems here aswell ;/
*/
int main(void) {
test1();
test2();
test30();
test31();
/* test32(); */
return 0;
}
/*
!!DESCRIPTION!! pointer test
!!ORIGIN!!
!!LICENCE!! public domain
*/
#include "common.h"
#include <stdio.h>
/*
check behaviour on incompletely declared arrays
*/
char i1[];
void test1(void) {
int a;
a=sizeof(i1[0]);
printf("%04x - ",a);
if(sizeof(i1[0])==sizeof(char)) {
/* gcc gives size of element */
printf("sizeof(i1[0]) gives size of element\n");
}
if(sizeof(i1[0])==sizeof(char*)) {
printf("sizeof(i1[0]) gives size of pointer to element\n");
}
}
/*
check behaviour on string init
*/
char t1[]="abcde";
char t2[]={"abcde"};
char *t3="abcde";
char *t4={"abcde"};
void test2(void) {
char c1,c2,c3,c4;
int i,e=0;
for(i=0;i<5;i++){
c1=t1[i];c2=t2[i];c3=t3[i];c4=t4[i];
/* printf("%02x %02x %02x %02x\n",c1,c2,c3,c4); */
printf("%c %c %c %c\n",c1,c2,c3,c4);
if(!((c1==c2)&(c1==c3)&(c1==c4))) e=1;
}
if(e) printf("test2 failed.\n");
else printf("test2 ok.\n");
}
/*
check behaviour on extern-declarations inside functions
*/
typedef struct {
char *name;
void *func;
} A3;
#ifdef NO_SLOPPY_STRUCT_INIT
A3 a3[] = {
{ "test3", (void*) NULL },
{ "test3", (void*) NULL },
};
#else
/*gcc warning: missing braces around initializer (near initialization for `a3[0]')
this type of struct-initialization seems to be kinda common */
A3 a3[] = {
"test3", (void*) NULL ,
"test3", (void*) NULL ,
};
#endif
void test3a(A3 *list, int number){
printf("%s %d\n",list->name,number);
}
static void test31(void)
{
extern A3 a3[];
test3a(a3, -1);
}
#if 0
/* this variation compiles and works with cc65, but gives an error with gcc :=P */
static void test32(void)
{
extern A3 *a3;
test3a(a3, -1);
}
#endif
static void test30(void)
{
test3a(a3, -1);
}
/*
todo: add test on function pointers in the form of (*func)(arg) ...
cc65 seems to have problems here aswell ;/
*/
int main(void) {
test1();
test2();
test30();
test31();
/* test32(); */
return 0;
}

View File

@ -1,262 +1,262 @@
/*
!!DESCRIPTION!! switch test
!!ORIGIN!!
!!LICENCE!! public domain
*/
/*#define STANDALONE*/
#include <stdio.h>
/*
!!DESCRIPTION!! switch test
!!ORIGIN!!
!!LICENCE!! public domain
*/
/*#define STANDALONE*/
#include <stdio.h>
void testlimits(int i) {
printf("%d:",i);
printf("%d:",i);
switch(i) {
case -1: /* works */
/* case 0xffff: */ /* 'range error' (-1) */
printf("-1\n");
break;
/* max int */
/* case 0x7fff: */ /* works */
case 32767: /* works */
/* case 32768: */ /* 'range error' (correct for that one!) */
printf("max\n");
break;
/* min int */
case -32768: /* 'warning. constant is long' */
/* case 0x8000: */ /* 'range error' */
/* case -32769: */ /* 'range error' (correct for that one!) */
printf("min\n");
break;
}
printf("\n");
}
void testdefault1(unsigned char i) {
/* we want a signed char */
#ifdef REFCC
#ifdef REFCC_UNSIGNED_CHARS
signed char k;
#else
char k;
#endif
#else
#ifdef UNSIGNED_CHARS
signed char k;
#else
char k;
#endif
#endif
for(;i<254;) {
k = i;
printf(">%d\n",i);i++;
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
break;
case 17:
break;
/* triggers bug ? */
/* gcc warning: case label value exceeds maximum value for type */
/* cc65 error: range error */
/*
case 170:
break;
*/
case 18:
break;
case 19:
break;
case 20:
break;
case 21:
break;
case 22:
break;
case 23:
break;
case 24:
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
case 5:
break;
case 6:
case 7:
break;
case 8:
case 9:
break;
}
break;
case 100:
break;
default:
printf(">>>default\n");
/* triggers bug if this break; is missing? */
/* break; */
}
}
}
void testdefault2(unsigned char i) {
/* we want a unsigned char */
#ifdef REFCC
#ifdef REFCC_UNSIGNED_CHARS
char k;
#else
unsigned char k;
#endif
#else
#ifdef UNSIGNED_CHARS
char k;
#else
unsigned char k;
#endif
#endif
for(;i<254;) {
k = i;
printf(">%d\n",i);i++;
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
break;
case 17:
break;
/* triggers bug ? */
case 170:
break;
case 18:
break;
case 19:
break;
case 20:
break;
case 21:
break;
case 22:
break;
case 23:
break;
case 24:
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
case 5:
break;
case 6:
case 7:
break;
case 8:
case 9:
break;
}
break;
case 100:
break;
default:
printf(">>>default\n");
/* triggers bug if this break; is missing? */
/* break; */
}
}
case -1: /* works */
/* case 0xffff: */ /* 'range error' (-1) */
printf("-1\n");
break;
/* max int */
/* case 0x7fff: */ /* works */
case 32767: /* works */
/* case 32768: */ /* 'range error' (correct for that one!) */
printf("max\n");
break;
/* min int */
case -32768: /* 'warning. constant is long' */
/* case 0x8000: */ /* 'range error' */
/* case -32769: */ /* 'range error' (correct for that one!) */
printf("min\n");
break;
}
printf("\n");
}
void testdefault1(unsigned char i) {
/* we want a signed char */
#ifdef REFCC
#ifdef REFCC_UNSIGNED_CHARS
signed char k;
#else
char k;
#endif
#else
#ifdef UNSIGNED_CHARS
signed char k;
#else
char k;
#endif
#endif
for(;i<254;) {
k = i;
printf(">%d\n",i);i++;
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
break;
case 17:
break;
/* triggers bug ? */
/* gcc warning: case label value exceeds maximum value for type */
/* cc65 error: range error */
/*
case 170:
break;
*/
case 18:
break;
case 19:
break;
case 20:
break;
case 21:
break;
case 22:
break;
case 23:
break;
case 24:
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
case 5:
break;
case 6:
case 7:
break;
case 8:
case 9:
break;
}
break;
case 100:
break;
default:
printf(">>>default\n");
/* triggers bug if this break; is missing? */
/* break; */
}
}
}
void testdefault2(unsigned char i) {
/* we want a unsigned char */
#ifdef REFCC
#ifdef REFCC_UNSIGNED_CHARS
char k;
#else
unsigned char k;
#endif
#else
#ifdef UNSIGNED_CHARS
char k;
#else
unsigned char k;
#endif
#endif
for(;i<254;) {
k = i;
printf(">%d\n",i);i++;
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
break;
case 12:
break;
case 13:
break;
case 14:
break;
case 15:
break;
case 17:
break;
/* triggers bug ? */
case 170:
break;
case 18:
break;
case 19:
break;
case 20:
break;
case 21:
break;
case 22:
break;
case 23:
break;
case 24:
switch(k) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
case 5:
break;
case 6:
case 7:
break;
case 8:
case 9:
break;
}
break;
case 100:
break;
default:
printf(">>>default\n");
/* triggers bug if this break; is missing? */
/* break; */
}
}
}
int main(void) {
testlimits(32767);
testlimits(-32768);
testlimits(-1);
testdefault1(1);
testdefault1(2);
testdefault1(3);
testdefault1(4);
testdefault2(1);
testdefault2(2);
testdefault2(3);
testdefault2(4);
return 0;
}
testlimits(32767);
testlimits(-32768);
testlimits(-1);
testdefault1(1);
testdefault1(2);
testdefault1(3);
testdefault1(4);
testdefault2(1);
testdefault2(2);
testdefault2(3);
testdefault2(4);
return 0;
}

View File

@ -1,105 +1,105 @@
/*
!!DESCRIPTION!! varargs test
!!ORIGIN!!
!!LICENCE!! public domain
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
void chk0(char *format,...);
void chk1(int fd,char *format,...);
#if 0
// old workaround for broken varargs
void chk0(char *format,...){
__asm__ ("pha"); // save argument size
{
//va_list ap;
char *ap;
char *_format;
static char string[0x100];
// va_start(ap,format);
__asm__ ("pla"); // restore argument size
__asm__ ("ldx #$00"); // clear hibyte of AX
ap=__AX__;
ap+=(char*)&format;
// get value of format
ap-=2;
_format=*((char**)ap);
// vsprintf(string,format,ap);
vsprintf(&string[0],_format,ap);
printf("format:%s,string:%s\n",_format,string);
// va_end(ap);
}
}
void chk1(int fd,char *format,...){
__asm__ ("pha"); // save argument size
{
//va_list ap;
char *ap;
char *_format;
int _fd;
static char string[0x100];
// va_start(ap,format);
__asm__ ("pla"); // restore argument size
__asm__ ("ldx #$00"); // clear hibyte of AX
ap=__AX__;
ap+=(char*)&format;
// get value of fd
ap-=2;
_fd=*((int*)ap);
// get value of format
ap-=2;
_format=*((char**)ap);
// vsprintf(string,format,ap);
vsprintf(&string[0],_format,ap);
printf("fd:%d,format:%s,string:%s\n",_fd,_format,string);
// va_end(ap);
}
}
#endif
void chk0(char *format,...){
va_list ap;
static char string[0x100];
va_start(ap,format);
vsprintf(string,format,ap);
printf("format:%s,string:%s\n",format,string);
va_end(ap);
}
void chk1(int fd,char *format,...){
va_list ap;
static char string[0x100];
va_start(ap,format);
vsprintf(string,format,ap);
printf("fd:%d,format:%s,string:%s\n",fd,format,string);
va_end(ap);
!!DESCRIPTION!! varargs test
!!ORIGIN!!
!!LICENCE!! public domain
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
void chk0(char *format,...);
void chk1(int fd,char *format,...);
#if 0
// old workaround for broken varargs
void chk0(char *format,...){
__asm__ ("pha"); // save argument size
{
//va_list ap;
char *ap;
char *_format;
static char string[0x100];
// va_start(ap,format);
__asm__ ("pla"); // restore argument size
__asm__ ("ldx #$00"); // clear hibyte of AX
ap=__AX__;
ap+=(char*)&format;
// get value of format
ap-=2;
_format=*((char**)ap);
// vsprintf(string,format,ap);
vsprintf(&string[0],_format,ap);
printf("format:%s,string:%s\n",_format,string);
// va_end(ap);
}
}
int main(int argc,char **argv) {
printf("varargs test\n");
printf("\nchk0/0:\n");chk0("chk0 %s","arg0");
printf("\nchk0/1:\n");chk0("chk0 %s %s","arg0","arg1");
printf("\nchk0/2:\n");chk0("chk0 %s %s %s","arg0","arg1","arg2");
printf("\nchk1/0:\n");chk1(0xfd,"chk1 %s","arg0");
printf("\nchk1/1:\n");chk1(0xfd,"chk1 %s %s","arg0","arg1");
printf("\nchk1/2:\n");chk1(0xfd,"chk1 %s %s %s","arg0","arg1","arg2");
void chk1(int fd,char *format,...){
__asm__ ("pha"); // save argument size
{
//va_list ap;
char *ap;
char *_format;
int _fd;
static char string[0x100];
// va_start(ap,format);
__asm__ ("pla"); // restore argument size
__asm__ ("ldx #$00"); // clear hibyte of AX
ap=__AX__;
ap+=(char*)&format;
// get value of fd
ap-=2;
_fd=*((int*)ap);
// get value of format
ap-=2;
_format=*((char**)ap);
// vsprintf(string,format,ap);
vsprintf(&string[0],_format,ap);
printf("fd:%d,format:%s,string:%s\n",_fd,_format,string);
// va_end(ap);
}
}
#endif
void chk0(char *format,...){
va_list ap;
static char string[0x100];
va_start(ap,format);
vsprintf(string,format,ap);
printf("format:%s,string:%s\n",format,string);
va_end(ap);
}
void chk1(int fd,char *format,...){
va_list ap;
static char string[0x100];
va_start(ap,format);
vsprintf(string,format,ap);
printf("fd:%d,format:%s,string:%s\n",fd,format,string);
va_end(ap);
}
int main(int argc,char **argv) {
printf("varargs test\n");
printf("\nchk0/0:\n");chk0("chk0 %s","arg0");
printf("\nchk0/1:\n");chk0("chk0 %s %s","arg0","arg1");
printf("\nchk0/2:\n");chk0("chk0 %s %s %s","arg0","arg1","arg2");
printf("\nchk1/0:\n");chk1(0xfd,"chk1 %s","arg0");
printf("\nchk1/1:\n");chk1(0xfd,"chk1 %s %s","arg0","arg1");
printf("\nchk1/2:\n");chk1(0xfd,"chk1 %s %s %s","arg0","arg1","arg2");
return 0;
}
}

View File

@ -1,170 +1,170 @@
/* mul-test.c -- Test the multiplication operator. */
#include <time.h>
#include <conio.h>
#include <ctype.h>
/* Number of elements in the progress bar. Use a power of 2, to avoid the
** multiplication (which is about to be tested).
*/
#define BAR_ELEMENTS 32U
#if defined(__CBM__)
static const unsigned char revers_bar[8] = {
0, 0, 0, 0, 0, 1, 1, 1
};
static const unsigned char small_bar[8] = {
' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7
};
#elif defined(__ATARI__)
#endif
/* Screen co-ordinates for the progress meter */
static unsigned char Width, Height;
static unsigned char X, Y;
static void ProgressMeter (unsigned Val)
/* Print the progress bar. */
{
gotoxy (X, Y);
cprintf (" %5lu/65536\r\n", (unsigned long) Val);
revers (1);
cclear (Val / (unsigned)(65536U / BAR_ELEMENTS));
/* Commodore and Atari computers can show eight times greater precision. */
#if defined(__CBM__)
Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8;
revers (revers_bar[Val]);
cputc (small_bar[Val]);
#elif defined(__ATARI__)
#endif
revers (0);
}
int main(void)
{
char C;
/* Clock variables */
clock_t Ticks;
clock_t Wait;
unsigned Days;
unsigned Hours;
unsigned Minu;
unsigned Sec;
unsigned Milli;
/* Actual test variables */
register unsigned lhs = 0;
register unsigned rhs = 0;
register unsigned res;
/* Clear the screen, and output an informational message. */
clrscr ();
screensize (&Width, &Height);
cprintf ("This program does an exhaustive test of\r\n"
"the multiplication routine. It runs for\r\n"
"several days; so, please wait very\r\n"
"patiently (or, speed up your emulator).\r\n"
"\n"
"Progress: ");
/* Remember the current position for the progress bar */
X = wherex ();
Y = wherey ();
/* Mark the maximum limit of the bar. */
revers (1);
cputcxy (BAR_ELEMENTS, Y, ' ');
cputcxy (BAR_ELEMENTS, Y + 1, ' ');
revers (0);
/* [Targets that have clock() will define CLOCKS_PER_SEC.] */
#ifdef CLOCKS_PER_SEC
/* Start timing the test. */
Ticks = clock();
#endif
do {
/* Update the progress bar */
ProgressMeter (lhs);
/* Enable this to test the progress-meter code.
** (And, run emulators at their maximun speed.)
*/
#if 0
continue;
#endif
/* Do one row of tests */
res = 0;
do {
if (lhs * rhs != res) {
#ifdef CLOCKS_PER_SEC
Wait = clock ();
#endif
gotoxy (0, Y+3);
cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res);
cprintf ("Press a key -- 'Q' to quit. ");
cursor (1);
C = toupper (cgetc ());
cclearxy (0, Y+3, Width);
cclearxy (0, Y+4, Width);
#ifdef CLOCKS_PER_SEC
/* Don't time the user's interaction. */
Ticks += clock () - Wait;
#endif
if (C == 'Q') {
goto Done;
}
}
if (kbhit () && toupper (cgetc ()) == 'Q') {
goto Done;
}
res += lhs;
} while (++rhs != 0);
} while (++lhs != 0);
Done:
#ifdef CLOCKS_PER_SEC
/* Calculate the time used */
Ticks = clock() - Ticks;
Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC;
Sec = (unsigned) (Ticks / CLOCKS_PER_SEC);
Minu = Sec / 60;
Hours = Minu / 60;
Days = Hours / 24;
Hours %= 24;
Minu %= 60;
Sec %= 60;
/* Print the time used */
gotoxy (0, Y+3);
cprintf ("Time used:\r\n"
" %u days,\r\n"
" %u hours,\r\n"
" %u minutes,\r\n"
" %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli);
#endif
cprintf ("\rTap a key, to exit. ");
cgetc();
return 0;
}
/* mul-test.c -- Test the multiplication operator. */
#include <time.h>
#include <conio.h>
#include <ctype.h>
/* Number of elements in the progress bar. Use a power of 2, to avoid the
** multiplication (which is about to be tested).
*/
#define BAR_ELEMENTS 32U
#if defined(__CBM__)
static const unsigned char revers_bar[8] = {
0, 0, 0, 0, 0, 1, 1, 1
};
static const unsigned char small_bar[8] = {
' ', 0xa5, 0xb4, 0xb5, 0xa1, 0xb6, 0xaa, 0xa7
};
#elif defined(__ATARI__)
#endif
/* Screen co-ordinates for the progress meter */
static unsigned char Width, Height;
static unsigned char X, Y;
static void ProgressMeter (unsigned Val)
/* Print the progress bar. */
{
gotoxy (X, Y);
cprintf (" %5lu/65536\r\n", (unsigned long) Val);
revers (1);
cclear (Val / (unsigned)(65536U / BAR_ELEMENTS));
/* Commodore and Atari computers can show eight times greater precision. */
#if defined(__CBM__)
Val = (Val / (unsigned)(65536U / BAR_ELEMENTS / 8)) % 8;
revers (revers_bar[Val]);
cputc (small_bar[Val]);
#elif defined(__ATARI__)
#endif
revers (0);
}
int main(void)
{
char C;
/* Clock variables */
clock_t Ticks;
clock_t Wait;
unsigned Days;
unsigned Hours;
unsigned Minu;
unsigned Sec;
unsigned Milli;
/* Actual test variables */
register unsigned lhs = 0;
register unsigned rhs = 0;
register unsigned res;
/* Clear the screen, and output an informational message. */
clrscr ();
screensize (&Width, &Height);
cprintf ("This program does an exhaustive test of\r\n"
"the multiplication routine. It runs for\r\n"
"several days; so, please wait very\r\n"
"patiently (or, speed up your emulator).\r\n"
"\n"
"Progress: ");
/* Remember the current position for the progress bar */
X = wherex ();
Y = wherey ();
/* Mark the maximum limit of the bar. */
revers (1);
cputcxy (BAR_ELEMENTS, Y, ' ');
cputcxy (BAR_ELEMENTS, Y + 1, ' ');
revers (0);
/* [Targets that have clock() will define CLOCKS_PER_SEC.] */
#ifdef CLOCKS_PER_SEC
/* Start timing the test. */
Ticks = clock();
#endif
do {
/* Update the progress bar */
ProgressMeter (lhs);
/* Enable this to test the progress-meter code.
** (And, run emulators at their maximun speed.)
*/
#if 0
continue;
#endif
/* Do one row of tests */
res = 0;
do {
if (lhs * rhs != res) {
#ifdef CLOCKS_PER_SEC
Wait = clock ();
#endif
gotoxy (0, Y+3);
cprintf ("Error on %u * %u: %u != %u\r\n", lhs, rhs, lhs * rhs, res);
cprintf ("Press a key -- 'Q' to quit. ");
cursor (1);
C = toupper (cgetc ());
cclearxy (0, Y+3, Width);
cclearxy (0, Y+4, Width);
#ifdef CLOCKS_PER_SEC
/* Don't time the user's interaction. */
Ticks += clock () - Wait;
#endif
if (C == 'Q') {
goto Done;
}
}
if (kbhit () && toupper (cgetc ()) == 'Q') {
goto Done;
}
res += lhs;
} while (++rhs != 0);
} while (++lhs != 0);
Done:
#ifdef CLOCKS_PER_SEC
/* Calculate the time used */
Ticks = clock() - Ticks;
Milli = ((Ticks % CLOCKS_PER_SEC) * 1000) / CLOCKS_PER_SEC;
Sec = (unsigned) (Ticks / CLOCKS_PER_SEC);
Minu = Sec / 60;
Hours = Minu / 60;
Days = Hours / 24;
Hours %= 24;
Minu %= 60;
Sec %= 60;
/* Print the time used */
gotoxy (0, Y+3);
cprintf ("Time used:\r\n"
" %u days,\r\n"
" %u hours,\r\n"
" %u minutes,\r\n"
" %u.%03u seconds.\n", Days, Hours, Minu, Sec, Milli);
#endif
cprintf ("\rTap a key, to exit. ");
cgetc();
return 0;
}