Fix line endings (CRLF -> LF) on all affected files.
This commit is contained in:
parent
b332064cb5
commit
8a81f9c0c8
14 changed files with 2379 additions and 2379 deletions
1018
asminc/opcodes.inc
1018
asminc/opcodes.inc
File diff suppressed because it is too large
Load diff
534
asminc/smc.inc
534
asminc/smc.inc
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
344
include/zlib.h
344
include/zlib.h
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
190
test/ref/init.c
190
test/ref/init.c
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue