mirror of
https://github.com/jeremysrand/ocanada.git
synced 2025-08-09 14:25:20 +00:00
Initial version
This commit is contained in:
@@ -17,6 +17,15 @@
|
|||||||
9D1A7CBB1F085D7F00669D60 /* prodos_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = prodos_template.dsk; path = make/prodos_template.dsk; sourceTree = "<group>"; };
|
9D1A7CBB1F085D7F00669D60 /* prodos_template.dsk */ = {isa = PBXFileReference; lastKnownFileType = file; name = prodos_template.dsk; path = make/prodos_template.dsk; sourceTree = "<group>"; };
|
||||||
9D1A7CBC1F085D7F00669D60 /* tail.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = tail.mk; path = make/tail.mk; sourceTree = "<group>"; };
|
9D1A7CBC1F085D7F00669D60 /* tail.mk */ = {isa = PBXFileReference; lastKnownFileType = text; name = tail.mk; path = make/tail.mk; sourceTree = "<group>"; };
|
||||||
9D1A7CBD1F085D7F00669D60 /* V2Make.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = V2Make.scpt; path = make/V2Make.scpt; sourceTree = "<group>"; };
|
9D1A7CBD1F085D7F00669D60 /* V2Make.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = V2Make.scpt; path = make/V2Make.scpt; sourceTree = "<group>"; };
|
||||||
|
9D1A7CC31F085DA800669D60 /* flag.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = flag.c; sourceTree = "<group>"; };
|
||||||
|
9D1A7CC41F085DA800669D60 /* flag.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = flag.h; sourceTree = "<group>"; };
|
||||||
|
9D1A7CC51F085DA800669D60 /* song.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = song.c; sourceTree = "<group>"; };
|
||||||
|
9D1A7CC61F085DA800669D60 /* song.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = song.h; sourceTree = "<group>"; };
|
||||||
|
9D1A7CC71F085DA800669D60 /* mockingboard_speech.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mockingboard_speech.h; sourceTree = "<group>"; };
|
||||||
|
9D1A7CC81F085DA800669D60 /* mockingboard_speech.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mockingboard_speech.s; sourceTree = "<group>"; };
|
||||||
|
9D1A7CC91F085DA800669D60 /* mockingboard.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mockingboard.c; sourceTree = "<group>"; };
|
||||||
|
9D1A7CCA1F085DA800669D60 /* mockingboard.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mockingboard.h; sourceTree = "<group>"; };
|
||||||
|
9D1A7CCB1F085DA800669D60 /* a2.lo.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = a2.lo.s; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
@@ -32,6 +41,15 @@
|
|||||||
children = (
|
children = (
|
||||||
9D1A7CB31F085D7F00669D60 /* main.c */,
|
9D1A7CB31F085D7F00669D60 /* main.c */,
|
||||||
9D1A7CB41F085D7F00669D60 /* Makefile */,
|
9D1A7CB41F085D7F00669D60 /* Makefile */,
|
||||||
|
9D1A7CC31F085DA800669D60 /* flag.c */,
|
||||||
|
9D1A7CC41F085DA800669D60 /* flag.h */,
|
||||||
|
9D1A7CC51F085DA800669D60 /* song.c */,
|
||||||
|
9D1A7CC61F085DA800669D60 /* song.h */,
|
||||||
|
9D1A7CC71F085DA800669D60 /* mockingboard_speech.h */,
|
||||||
|
9D1A7CC81F085DA800669D60 /* mockingboard_speech.s */,
|
||||||
|
9D1A7CC91F085DA800669D60 /* mockingboard.c */,
|
||||||
|
9D1A7CCA1F085DA800669D60 /* mockingboard.h */,
|
||||||
|
9D1A7CCB1F085DA800669D60 /* a2.lo.s */,
|
||||||
9D1A7CB51F085D7F00669D60 /* make */,
|
9D1A7CB51F085D7F00669D60 /* make */,
|
||||||
);
|
);
|
||||||
path = ocanada;
|
path = ocanada;
|
||||||
|
@@ -5,6 +5,22 @@
|
|||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
buildImplicitDependencies = "YES">
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "9D1A7CB11F085D7F00669D60"
|
||||||
|
BuildableName = "ocanada"
|
||||||
|
BlueprintName = "ocanada"
|
||||||
|
ReferencedContainer = "container:ocanada.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction
|
<TestAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
@@ -26,6 +42,15 @@
|
|||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "9D1A7CB11F085D7F00669D60"
|
||||||
|
BuildableName = "ocanada"
|
||||||
|
BlueprintName = "ocanada"
|
||||||
|
ReferencedContainer = "container:ocanada.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
@@ -35,6 +60,15 @@
|
|||||||
savedToolIdentifier = ""
|
savedToolIdentifier = ""
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
debugDocumentVersioning = "YES">
|
debugDocumentVersioning = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "9D1A7CB11F085D7F00669D60"
|
||||||
|
BuildableName = "ocanada"
|
||||||
|
BlueprintName = "ocanada"
|
||||||
|
ReferencedContainer = "container:ocanada.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
</ProfileAction>
|
</ProfileAction>
|
||||||
<AnalyzeAction
|
<AnalyzeAction
|
||||||
buildConfiguration = "Debug">
|
buildConfiguration = "Debug">
|
||||||
|
@@ -25,7 +25,7 @@ PGM=ocanada
|
|||||||
# Uncomment the one you want below (the first one is the default):
|
# Uncomment the one you want below (the first one is the default):
|
||||||
# MACHINE = apple2
|
# MACHINE = apple2
|
||||||
# MACHINE = apple2-dos33
|
# MACHINE = apple2-dos33
|
||||||
# MACHINE = apple2-system
|
MACHINE = apple2-system
|
||||||
# MACHINE = apple2-loader
|
# MACHINE = apple2-loader
|
||||||
# MACHINE = apple2-reboot
|
# MACHINE = apple2-reboot
|
||||||
# MACHINE = apple2enh
|
# MACHINE = apple2enh
|
||||||
|
930
ocanada/a2.lo.s
Normal file
930
ocanada/a2.lo.s
Normal file
@@ -0,0 +1,930 @@
|
|||||||
|
;
|
||||||
|
; File generated by co65 v 2.13.3 using model `cc65-module'
|
||||||
|
;
|
||||||
|
.fopt compiler,"co65 v 2.13.3"
|
||||||
|
.case on
|
||||||
|
.debuginfo off
|
||||||
|
.export _a2_lo
|
||||||
|
|
||||||
|
;
|
||||||
|
; CODE SEGMENT
|
||||||
|
;
|
||||||
|
.segment "CODE"
|
||||||
|
_a2_lo:
|
||||||
|
.byte $74
|
||||||
|
.byte $67
|
||||||
|
.byte $69
|
||||||
|
.byte $02
|
||||||
|
.byte $28
|
||||||
|
.byte $00
|
||||||
|
.byte $30
|
||||||
|
.byte $00
|
||||||
|
.byte $10
|
||||||
|
.byte $01
|
||||||
|
.byte $08
|
||||||
|
.byte $08
|
||||||
|
.byte $00
|
||||||
|
.byte $00
|
||||||
|
.byte $00
|
||||||
|
.byte $00
|
||||||
|
.word _a2_lo+75
|
||||||
|
.word _a2_lo+75
|
||||||
|
.word _a2_lo+58
|
||||||
|
.word _a2_lo+76
|
||||||
|
.word _a2_lo+89
|
||||||
|
.word _a2_lo+118
|
||||||
|
.word _a2_lo+98
|
||||||
|
.word _a2_lo+75
|
||||||
|
.word _a2_lo+75
|
||||||
|
.word _a2_lo+108
|
||||||
|
.word _a2_lo+118
|
||||||
|
.word _a2_lo+124
|
||||||
|
.word _a2_lo+124
|
||||||
|
.word _a2_lo+129
|
||||||
|
.word _a2_lo+194
|
||||||
|
.word _a2_lo+210
|
||||||
|
.word _a2_lo+558
|
||||||
|
.word _a2_lo+586
|
||||||
|
.word _a2_lo+75
|
||||||
|
.word _a2_lo+75
|
||||||
|
.byte $00
|
||||||
|
.byte $00
|
||||||
|
.byte $2C
|
||||||
|
.byte $82
|
||||||
|
.byte $C0
|
||||||
|
.byte $20
|
||||||
|
.byte $40
|
||||||
|
.byte $FB
|
||||||
|
.byte $2C
|
||||||
|
.byte $52
|
||||||
|
.byte $C0
|
||||||
|
.byte $2C
|
||||||
|
.byte $80
|
||||||
|
.byte $C0
|
||||||
|
.byte $A9
|
||||||
|
.byte $00
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+0
|
||||||
|
.byte $60
|
||||||
|
.byte $2C
|
||||||
|
.byte $82
|
||||||
|
.byte $C0
|
||||||
|
.byte $20
|
||||||
|
.byte $99
|
||||||
|
.byte $F3
|
||||||
|
.byte $20
|
||||||
|
.byte $58
|
||||||
|
.byte $FC
|
||||||
|
.byte $2C
|
||||||
|
.byte $80
|
||||||
|
.byte $C0
|
||||||
|
.byte $60
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+0
|
||||||
|
.byte $A2
|
||||||
|
.byte $00
|
||||||
|
.byte $8E
|
||||||
|
.word BSS+0
|
||||||
|
.byte $60
|
||||||
|
.byte $2C
|
||||||
|
.byte $82
|
||||||
|
.byte $C0
|
||||||
|
.byte $20
|
||||||
|
.byte $32
|
||||||
|
.byte $F8
|
||||||
|
.byte $2C
|
||||||
|
.byte $80
|
||||||
|
.byte $C0
|
||||||
|
.byte $60
|
||||||
|
.byte $2C
|
||||||
|
.byte $82
|
||||||
|
.byte $C0
|
||||||
|
.byte $20
|
||||||
|
.byte $64
|
||||||
|
.byte $F8
|
||||||
|
.byte $2C
|
||||||
|
.byte $80
|
||||||
|
.byte $C0
|
||||||
|
.byte $60
|
||||||
|
.byte $A9
|
||||||
|
.byte $06
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+0
|
||||||
|
.byte $60
|
||||||
|
.byte $A9
|
||||||
|
.byte <(_a2_lo+227)
|
||||||
|
.byte $A2
|
||||||
|
.byte >(_a2_lo+995)
|
||||||
|
.byte $60
|
||||||
|
.byte $2C
|
||||||
|
.byte $82
|
||||||
|
.byte $C0
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $20
|
||||||
|
.byte $00
|
||||||
|
.byte $F8
|
||||||
|
.byte $2C
|
||||||
|
.byte $80
|
||||||
|
.byte $C0
|
||||||
|
.byte $60
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $30
|
||||||
|
.byte $2E
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $30
|
||||||
|
.byte $2A
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+16)
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+17)
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+16)
|
||||||
|
.byte $AD
|
||||||
|
.word _a2_lo+4
|
||||||
|
.byte $AC
|
||||||
|
.word _a2_lo+5
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $B0
|
||||||
|
.byte $15
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+16)
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+17)
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+16)
|
||||||
|
.byte $AD
|
||||||
|
.word _a2_lo+6
|
||||||
|
.byte $AC
|
||||||
|
.word _a2_lo+7
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $90
|
||||||
|
.byte $C0
|
||||||
|
.byte $60
|
||||||
|
.byte $2C
|
||||||
|
.byte $82
|
||||||
|
.byte $C0
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $20
|
||||||
|
.byte $71
|
||||||
|
.byte $F8
|
||||||
|
.byte $A2
|
||||||
|
.byte $00
|
||||||
|
.byte $2C
|
||||||
|
.byte $80
|
||||||
|
.byte $C0
|
||||||
|
.byte $60
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $A8
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+943
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $84
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+3
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $A8
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+3
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+943
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+3
|
||||||
|
.byte $8C
|
||||||
|
.word BSS+4
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $90
|
||||||
|
.byte $04
|
||||||
|
.byte $A9
|
||||||
|
.byte $01
|
||||||
|
.byte $D0
|
||||||
|
.byte $02
|
||||||
|
.byte $A9
|
||||||
|
.byte $FF
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+5
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $90
|
||||||
|
.byte $04
|
||||||
|
.byte $A9
|
||||||
|
.byte $01
|
||||||
|
.byte $D0
|
||||||
|
.byte $02
|
||||||
|
.byte $A9
|
||||||
|
.byte $FF
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+6
|
||||||
|
.byte $A9
|
||||||
|
.byte $00
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+7
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+8
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+3
|
||||||
|
.byte $AC
|
||||||
|
.word BSS+4
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $B0
|
||||||
|
.byte $28
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $AE
|
||||||
|
.word BSS+3
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+3
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $AE
|
||||||
|
.word BSS+4
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+4
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+5
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+7
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+6
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+8
|
||||||
|
.byte $A9
|
||||||
|
.byte $00
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+5
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+6
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+3
|
||||||
|
.byte $AC
|
||||||
|
.word BSS+4
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+947
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+3
|
||||||
|
.byte $8C
|
||||||
|
.word BSS+4
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+1
|
||||||
|
.byte $8E
|
||||||
|
.word BSS+2
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+1
|
||||||
|
.byte $0D
|
||||||
|
.word BSS+2
|
||||||
|
.byte $D0
|
||||||
|
.byte $01
|
||||||
|
.byte $60
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $18
|
||||||
|
.byte $6D
|
||||||
|
.word BSS+3
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $6D
|
||||||
|
.word BSS+4
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $AA
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $8A
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $A2
|
||||||
|
.byte $00
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+5
|
||||||
|
.byte $10
|
||||||
|
.byte $01
|
||||||
|
.byte $CA
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $8A
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $A2
|
||||||
|
.byte $00
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+8
|
||||||
|
.byte $10
|
||||||
|
.byte $01
|
||||||
|
.byte $CA
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $8A
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+943
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+2)
|
||||||
|
.byte $84
|
||||||
|
.byte <(ZEROPAGE+3)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+943
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+2)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $10
|
||||||
|
.byte $07
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $4C
|
||||||
|
.word _a2_lo+534
|
||||||
|
.byte $A2
|
||||||
|
.byte $00
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+7
|
||||||
|
.byte $10
|
||||||
|
.byte $01
|
||||||
|
.byte $CA
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $8A
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $A2
|
||||||
|
.byte $00
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+6
|
||||||
|
.byte $10
|
||||||
|
.byte $01
|
||||||
|
.byte $CA
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $8A
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+1
|
||||||
|
.byte $38
|
||||||
|
.byte $E9
|
||||||
|
.byte $01
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+1
|
||||||
|
.byte $90
|
||||||
|
.byte $03
|
||||||
|
.byte $4C
|
||||||
|
.word _a2_lo+386
|
||||||
|
.byte $CE
|
||||||
|
.word BSS+2
|
||||||
|
.byte $4C
|
||||||
|
.word _a2_lo+386
|
||||||
|
.byte $2C
|
||||||
|
.byte $82
|
||||||
|
.byte $C0
|
||||||
|
.byte $E6
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $86
|
||||||
|
.byte $2C
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $20
|
||||||
|
.byte $19
|
||||||
|
.byte $F8
|
||||||
|
.byte $E6
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $C5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $D0
|
||||||
|
.byte $F1
|
||||||
|
.byte $2C
|
||||||
|
.byte $80
|
||||||
|
.byte $C0
|
||||||
|
.byte $60
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+16)
|
||||||
|
.byte $D0
|
||||||
|
.byte $03
|
||||||
|
.byte $4C
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A9
|
||||||
|
.byte $00
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+2)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+3)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A4
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $90
|
||||||
|
.byte $01
|
||||||
|
.byte $60
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $48
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $48
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+5
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+6
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $68
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $68
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+5
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+6
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $48
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $48
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+6)
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+5
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+7)
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+6
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $68
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $68
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+4)
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+8)
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+5)
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+9)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+5
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+10)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+6
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+11)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+143
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+2)
|
||||||
|
.byte $A6
|
||||||
|
.byte <(ZEROPAGE+3)
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $A8
|
||||||
|
.byte $8A
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $AA
|
||||||
|
.byte $98
|
||||||
|
.byte $18
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $A8
|
||||||
|
.byte $8A
|
||||||
|
.byte $65
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $AA
|
||||||
|
.byte $98
|
||||||
|
.byte $18
|
||||||
|
.byte $69
|
||||||
|
.byte $01
|
||||||
|
.byte $90
|
||||||
|
.byte $01
|
||||||
|
.byte $E8
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+1
|
||||||
|
.byte $8E
|
||||||
|
.word BSS+2
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A8
|
||||||
|
.byte $8A
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $AA
|
||||||
|
.byte $98
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $A8
|
||||||
|
.byte $8A
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $AA
|
||||||
|
.byte $98
|
||||||
|
.byte $18
|
||||||
|
.byte $69
|
||||||
|
.byte $01
|
||||||
|
.byte $90
|
||||||
|
.byte $01
|
||||||
|
.byte $E8
|
||||||
|
.byte $8D
|
||||||
|
.word BSS+3
|
||||||
|
.byte $8E
|
||||||
|
.word BSS+4
|
||||||
|
.byte $E6
|
||||||
|
.byte <(ZEROPAGE+14)
|
||||||
|
.byte $D0
|
||||||
|
.byte $02
|
||||||
|
.byte $E6
|
||||||
|
.byte <(ZEROPAGE+15)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+3
|
||||||
|
.byte $AC
|
||||||
|
.word BSS+4
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+943
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+2)
|
||||||
|
.byte $84
|
||||||
|
.byte <(ZEROPAGE+3)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+1
|
||||||
|
.byte $AC
|
||||||
|
.word BSS+2
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+943
|
||||||
|
.byte $A2
|
||||||
|
.byte <(ZEROPAGE+2)
|
||||||
|
.byte $20
|
||||||
|
.word _a2_lo+961
|
||||||
|
.byte $10
|
||||||
|
.byte $14
|
||||||
|
.byte $A5
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $38
|
||||||
|
.byte $E9
|
||||||
|
.byte $01
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+12)
|
||||||
|
.byte $B0
|
||||||
|
.byte $02
|
||||||
|
.byte $C6
|
||||||
|
.byte <(ZEROPAGE+13)
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+3
|
||||||
|
.byte $AE
|
||||||
|
.word BSS+4
|
||||||
|
.byte $4C
|
||||||
|
.word _a2_lo+936
|
||||||
|
.byte $AD
|
||||||
|
.word BSS+1
|
||||||
|
.byte $AE
|
||||||
|
.word BSS+2
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+2)
|
||||||
|
.byte $86
|
||||||
|
.byte <(ZEROPAGE+3)
|
||||||
|
.byte $4C
|
||||||
|
.word _a2_lo+623
|
||||||
|
.byte $C0
|
||||||
|
.byte $00
|
||||||
|
.byte $10
|
||||||
|
.byte $0D
|
||||||
|
.byte $18
|
||||||
|
.byte $49
|
||||||
|
.byte $FF
|
||||||
|
.byte $69
|
||||||
|
.byte $01
|
||||||
|
.byte $48
|
||||||
|
.byte $98
|
||||||
|
.byte $49
|
||||||
|
.byte $FF
|
||||||
|
.byte $69
|
||||||
|
.byte $00
|
||||||
|
.byte $A8
|
||||||
|
.byte $68
|
||||||
|
.byte $60
|
||||||
|
.byte $85
|
||||||
|
.byte <(ZEROPAGE+18)
|
||||||
|
.byte $84
|
||||||
|
.byte <(ZEROPAGE+19)
|
||||||
|
.byte $B5
|
||||||
|
.byte $00
|
||||||
|
.byte $48
|
||||||
|
.byte $B5
|
||||||
|
.byte $01
|
||||||
|
.byte $A8
|
||||||
|
.byte $68
|
||||||
|
.byte $AA
|
||||||
|
.byte $98
|
||||||
|
.byte $38
|
||||||
|
.byte $E5
|
||||||
|
.byte <(ZEROPAGE+19)
|
||||||
|
.byte $D0
|
||||||
|
.byte $09
|
||||||
|
.byte $E4
|
||||||
|
.byte <(ZEROPAGE+18)
|
||||||
|
.byte $F0
|
||||||
|
.byte $04
|
||||||
|
.byte $69
|
||||||
|
.byte $FF
|
||||||
|
.byte $09
|
||||||
|
.byte $01
|
||||||
|
.byte $60
|
||||||
|
.byte $50
|
||||||
|
.byte $04
|
||||||
|
.byte $49
|
||||||
|
.byte $FF
|
||||||
|
.byte $09
|
||||||
|
.byte $01
|
||||||
|
.byte $60
|
||||||
|
.byte $00
|
||||||
|
.byte $01
|
||||||
|
.byte $02
|
||||||
|
.byte $03
|
||||||
|
.byte $04
|
||||||
|
.byte $05
|
||||||
|
.byte $06
|
||||||
|
.byte $07
|
||||||
|
.byte $08
|
||||||
|
.byte $09
|
||||||
|
.byte $0A
|
||||||
|
.byte $0B
|
||||||
|
.byte $0C
|
||||||
|
.byte $0D
|
||||||
|
.byte $0E
|
||||||
|
.byte $0F
|
||||||
|
|
||||||
|
;
|
||||||
|
; DATA SEGMENT
|
||||||
|
;
|
||||||
|
.segment "DATA"
|
||||||
|
DATA:
|
||||||
|
|
||||||
|
;
|
||||||
|
; BSS SEGMENT
|
||||||
|
;
|
||||||
|
.segment "BSS"
|
||||||
|
BSS:
|
||||||
|
.res 9
|
||||||
|
|
||||||
|
;
|
||||||
|
; ZEROPAGE SEGMENT
|
||||||
|
;
|
||||||
|
.import __ZP_START__ ; Linker generated symbol
|
||||||
|
ZEROPAGE = __ZP_START__
|
||||||
|
|
||||||
|
.end
|
74
ocanada/flag.c
Normal file
74
ocanada/flag.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// flag.c
|
||||||
|
// ocanada
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2017-07-01.
|
||||||
|
// Copyright © 2017 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <apple2.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <tgi.h>
|
||||||
|
#include <tgi/tgi-mode.h>
|
||||||
|
|
||||||
|
#include "flag.h"
|
||||||
|
|
||||||
|
// Extern symbols for graphics drivers
|
||||||
|
extern char a2_lo;
|
||||||
|
|
||||||
|
void initGraphics(void)
|
||||||
|
{
|
||||||
|
static bool tgi_inited = false;
|
||||||
|
|
||||||
|
if (tgi_inited)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Install drivers
|
||||||
|
tgi_install(&a2_lo);
|
||||||
|
|
||||||
|
tgi_init();
|
||||||
|
|
||||||
|
// Mixed text and graphics mode
|
||||||
|
asm ("STA %w", 0xc053);
|
||||||
|
|
||||||
|
tgi_inited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void drawFlag(void)
|
||||||
|
{
|
||||||
|
initGraphics();
|
||||||
|
|
||||||
|
tgi_setcolor(LORES_MAGENTA);
|
||||||
|
tgi_bar(0,0,9,39);
|
||||||
|
tgi_bar(30,0,39,39);
|
||||||
|
|
||||||
|
tgi_setcolor(LORES_WHITE);
|
||||||
|
tgi_bar(10,0,29,39);
|
||||||
|
|
||||||
|
tgi_setcolor(LORES_MAGENTA);
|
||||||
|
tgi_bar(19,4,20,34);
|
||||||
|
tgi_line(18,7,18,26);
|
||||||
|
tgi_line(21,7,21,26);
|
||||||
|
|
||||||
|
tgi_line(17,6,17,26);
|
||||||
|
tgi_line(22,6,22,26);
|
||||||
|
|
||||||
|
tgi_line(16,14,16,27);
|
||||||
|
tgi_line(23,14,23,27);
|
||||||
|
|
||||||
|
tgi_line(15,13,15,27);
|
||||||
|
tgi_line(24,13,24,27);
|
||||||
|
|
||||||
|
tgi_line(14,12,14,28);
|
||||||
|
tgi_line(25,12,25,28);
|
||||||
|
|
||||||
|
tgi_line(13,14,13,26);
|
||||||
|
tgi_line(26,14,26,26);
|
||||||
|
|
||||||
|
tgi_line(12,13,12,23);
|
||||||
|
tgi_line(27,13,27,23);
|
||||||
|
|
||||||
|
tgi_line(11,16,11,20);
|
||||||
|
tgi_line(28,16,28,20);
|
||||||
|
}
|
16
ocanada/flag.h
Normal file
16
ocanada/flag.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// flag.h
|
||||||
|
// ocanada
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2017-07-01.
|
||||||
|
// Copyright © 2017 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __ocanada__flag__
|
||||||
|
#define __ocanada__flag__
|
||||||
|
|
||||||
|
|
||||||
|
extern void drawFlag(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* defined(__ocanada__flag__) */
|
@@ -8,13 +8,58 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <apple2.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <conio.h>
|
#include <conio.h>
|
||||||
|
|
||||||
|
#include "flag.h"
|
||||||
|
#include "mockingboard.h"
|
||||||
|
#include "song.h"
|
||||||
|
|
||||||
|
|
||||||
|
void showTitleScreen(void)
|
||||||
|
{
|
||||||
|
clrscr();
|
||||||
|
printf("%s",
|
||||||
|
//0000000001111111111222222222233333333334
|
||||||
|
//1234567890123456789012345678901234567890
|
||||||
|
" HAPPY CANADA DAY\n"
|
||||||
|
" JULY 1, 2017\n"
|
||||||
|
" BY\n"
|
||||||
|
" JEREMY RAND\n"
|
||||||
|
"\n"
|
||||||
|
"THIS PROGRAM REQUIRES A MOCKINGBOARD TO\n"
|
||||||
|
"PLAY THE SONG\n"
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tSlot getSlotNum(void)
|
||||||
|
{
|
||||||
|
printf("MOCKINGBOARD SLOT NUMBER [1-7]?");
|
||||||
|
while (true) {
|
||||||
|
char ch = cgetc();
|
||||||
|
if ((ch >= '1') &&
|
||||||
|
(ch <= '7'))
|
||||||
|
return (ch - '0');
|
||||||
|
|
||||||
|
if ((ch == '0') ||
|
||||||
|
(ch == 'q') ||
|
||||||
|
(ch == 'Q') ||
|
||||||
|
(ch == CH_ESC))
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
printf("\007");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
printf("HELLO, WORLD!\n");
|
showTitleScreen();
|
||||||
cgetc();
|
mockingBoardInit(getSlotNum(), false);
|
||||||
|
drawFlag();
|
||||||
|
playSong();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
189
ocanada/mockingboard.c
Executable file
189
ocanada/mockingboard.c
Executable file
@@ -0,0 +1,189 @@
|
|||||||
|
//
|
||||||
|
// mockingboard.c
|
||||||
|
// mocktest
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2016-09-10.
|
||||||
|
// Copyright © 2016 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "mockingboard.h"
|
||||||
|
#include "mockingboard_speech.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Defines
|
||||||
|
|
||||||
|
#define LATCH_COMMAND 0x7
|
||||||
|
#define WRITE_COMMAND 0x6
|
||||||
|
#define RESET_COMMAND 0x0
|
||||||
|
#define THROUGH_PORT_B 0x4
|
||||||
|
|
||||||
|
#define MOCKINGBOARD_LATCH(soundChip) writeCommand((soundChip), LATCH_COMMAND)
|
||||||
|
#define MOCKINGBOARD_WRITE(soundChip) writeCommand((soundChip), WRITE_COMMAND)
|
||||||
|
#define MOCKINGBOARD_RESET(soundChip) writeCommand((soundChip), RESET_COMMAND)
|
||||||
|
|
||||||
|
|
||||||
|
// Typedefs
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SOUND_CHIP_1 = 0,
|
||||||
|
SOUND_CHIP_2 = 1,
|
||||||
|
NUM_SOUND_CHIPS = 2
|
||||||
|
} tMockingBoardSoundChip;
|
||||||
|
|
||||||
|
|
||||||
|
// Globals
|
||||||
|
|
||||||
|
// Addresses for the two 6522's (assuming slot 4 for now)
|
||||||
|
static uint8_t *gMockPortB[NUM_SOUND_CHIPS] = { (uint8_t *)0xc000, (uint8_t *)0xc080 };
|
||||||
|
static uint8_t *gMockPortA[NUM_SOUND_CHIPS] = { (uint8_t *)0xc001, (uint8_t *)0xc081 };
|
||||||
|
static uint8_t *gMockDataDirB[NUM_SOUND_CHIPS] = { (uint8_t *)0xc002, (uint8_t *)0xc082 };
|
||||||
|
static uint8_t *gMockDataDirA[NUM_SOUND_CHIPS] = { (uint8_t *)0xc003, (uint8_t *)0xc083 };
|
||||||
|
|
||||||
|
static uint8_t gMockingBoardInitialized = false;
|
||||||
|
static uint8_t gMockingBoardSpeechInitialized = false;
|
||||||
|
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
static uint8_t *mapIOPointer(tSlot slot, uint8_t *ptr)
|
||||||
|
{
|
||||||
|
uint16_t temp1 = (uint16_t)ptr;
|
||||||
|
uint16_t temp2 = slot;
|
||||||
|
|
||||||
|
temp2 <<= 8;
|
||||||
|
temp1 &= 0xf0ff;
|
||||||
|
|
||||||
|
temp1 |= temp2;
|
||||||
|
ptr = (uint8_t *)temp1;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardInit(tSlot slot, bool hasSpeechChip)
|
||||||
|
{
|
||||||
|
tMockingBoardSoundChip soundChip;
|
||||||
|
|
||||||
|
if (sizeof(tMockingSoundRegisters) != 16) {
|
||||||
|
printf("The sound registers must be 16 bytes long!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (soundChip = SOUND_CHIP_1; soundChip < NUM_SOUND_CHIPS; soundChip++) {
|
||||||
|
gMockPortB[soundChip] = mapIOPointer(slot, gMockPortB[soundChip]);
|
||||||
|
gMockPortA[soundChip] = mapIOPointer(slot, gMockPortA[soundChip]);
|
||||||
|
gMockDataDirB[soundChip] = mapIOPointer(slot, gMockDataDirB[soundChip]);
|
||||||
|
gMockDataDirA[soundChip] = mapIOPointer(slot, gMockDataDirA[soundChip]);
|
||||||
|
|
||||||
|
*(gMockDataDirA[soundChip]) = 0xff; // Set port A for output
|
||||||
|
*(gMockDataDirB[soundChip]) = 0x7; // Set port B for output
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSpeechChip) {
|
||||||
|
if (gMockingBoardSpeechInitialized) {
|
||||||
|
mockingBoardSpeechShutdown();
|
||||||
|
}
|
||||||
|
mockingBoardSpeechInit(slot);
|
||||||
|
gMockingBoardSpeechInitialized = true;
|
||||||
|
} else if (gMockingBoardSpeechInitialized) {
|
||||||
|
mockingBoardSpeechShutdown();
|
||||||
|
gMockingBoardSpeechInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gMockingBoardInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardShutdown(void)
|
||||||
|
{
|
||||||
|
if (gMockingBoardSpeechInitialized) {
|
||||||
|
mockingBoardSpeechShutdown();
|
||||||
|
gMockingBoardSpeechInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gMockingBoardInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void writeCommand(tMockingBoardSoundChip soundChip, uint8_t command)
|
||||||
|
{
|
||||||
|
volatile uint8_t *ptr = gMockPortB[soundChip];
|
||||||
|
|
||||||
|
*ptr = command;
|
||||||
|
*ptr = THROUGH_PORT_B;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mockingBoardTableAccess(tMockingBoardSoundChip soundChip, tMockingSoundRegisters *registers)
|
||||||
|
{
|
||||||
|
uint8_t *data = (uint8_t *)registers;
|
||||||
|
volatile uint8_t *ptr = gMockPortA[soundChip];
|
||||||
|
uint8_t index;
|
||||||
|
|
||||||
|
if (!gMockingBoardInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MOCKINGBOARD_RESET(soundChip);
|
||||||
|
for (index = 0; index < 16; index++) {
|
||||||
|
*ptr = index;
|
||||||
|
MOCKINGBOARD_LATCH(soundChip);
|
||||||
|
*ptr = *data;
|
||||||
|
MOCKINGBOARD_WRITE(soundChip);
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardPlaySound(tMockingBoardSpeaker speaker, tMockingSoundRegisters *registers)
|
||||||
|
{
|
||||||
|
if ((speaker & SPEAKER_LEFT) != 0) {
|
||||||
|
mockingBoardTableAccess(SOUND_CHIP_1, registers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((speaker & SPEAKER_RIGHT) != 0) {
|
||||||
|
mockingBoardTableAccess(SOUND_CHIP_2, registers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mockingBoardStopSound(tMockingBoardSpeaker speaker)
|
||||||
|
{
|
||||||
|
if ((speaker & SPEAKER_LEFT) != 0) {
|
||||||
|
MOCKINGBOARD_RESET(SOUND_CHIP_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((speaker & SPEAKER_RIGHT) != 0) {
|
||||||
|
MOCKINGBOARD_RESET(SOUND_CHIP_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool mockingBoardSpeechIsBusy(void)
|
||||||
|
{
|
||||||
|
return (mockingBoardSpeechBusy != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool mockingBoardSpeechIsPlaying(void)
|
||||||
|
{
|
||||||
|
return (mockingBoardSpeechPlaying != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool mockingBoardSpeak(uint8_t *data, uint16_t dataLen)
|
||||||
|
{
|
||||||
|
if (!gMockingBoardSpeechInitialized)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mockingBoardSpeechIsBusy())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mockingBoardSpeechData = data;
|
||||||
|
mockingBoardSpeechLen = dataLen;
|
||||||
|
mockingBoardSpeakPriv();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
131
ocanada/mockingboard.h
Executable file
131
ocanada/mockingboard.h
Executable file
@@ -0,0 +1,131 @@
|
|||||||
|
//
|
||||||
|
// mockingboard.h
|
||||||
|
// mocktest
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2016-09-10.
|
||||||
|
// Copyright © 2016 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __mocktest__mockingboard__
|
||||||
|
#define __mocktest__mockingboard__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
// Defines
|
||||||
|
|
||||||
|
#define MOCK_NUM_CHANNELS 3
|
||||||
|
|
||||||
|
|
||||||
|
#define TONE_PERIOD_C(octave) (0x7a3 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_C_SHARP(octave) (0x735 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_D(octave) (0x6cd >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_D_SHARP(octave) (0x66c >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_E(octave) (0x60f >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_F(octave) (0x5b8 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_F_SHARP(octave) (0x566 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_G(octave) (0x518 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_G_SHARP(octave) (0x4cf >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_A(octave) (0x48a >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_A_SHARP(octave) (0x449 >> (octave - 1))
|
||||||
|
#define TONE_PERIOD_B(octave) (0x40b >> (octave - 1))
|
||||||
|
|
||||||
|
#define MIN_NOISE_PERIOD 0
|
||||||
|
#define MAX_NOISE_PERIOD 31
|
||||||
|
|
||||||
|
#define TONE_CHANNEL_A 1
|
||||||
|
#define TONE_CHANNEL_B 2
|
||||||
|
#define TONE_CHANNEL_C 4
|
||||||
|
#define NOISE_CHANNEL_A 8
|
||||||
|
#define NOISE_CHANNEL_B 16
|
||||||
|
#define NOISE_CHANNEL_C 32
|
||||||
|
|
||||||
|
#define ENABLE_CHANNEL(channels) (0x3f ^ (channels))
|
||||||
|
#define ENABLE_ALL_TONE_CHANNELS ENABLE_CHANNEL(TONE_CHANNEL_A|TONE_CHANNEL_B|TONE_CHANNEL_C)
|
||||||
|
#define ENABLE_ALL_NOISE_CHANNELS ENABLE_CHANNEL(NOISE_CHANNEL_A|NOISE_CHANNEL_B|NOISE_CHANNEL_C)
|
||||||
|
#define ENABLE_ALL_CHANNELS ENABLE_CHANNEL(TONE_CHANNEL_A|TONE_CHANNEL_B|TONE_CHANNEL_C|NOISE_CHANNEL_A|NOISE_CHANNEL_B|NOISE_CHANNEL_C)
|
||||||
|
|
||||||
|
#define MIN_AMPLITUDE 0
|
||||||
|
#define MAX_AMPLITUDE 15
|
||||||
|
#define VARIABLE_AMPLITUDE 16
|
||||||
|
|
||||||
|
#define MIN_ENVELOPE_PERIOD 0
|
||||||
|
#define MAX_ENVELOPE_PERIOD 65535u
|
||||||
|
#define MILLISEC_TO_ENVELOP_PERIOD(ms) ((ms) * 4)
|
||||||
|
|
||||||
|
|
||||||
|
// Here is a table of the envelope shapes and how they look:
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_ONE_SHOT_DECAY \__________...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_ONE_SHOT_ATTACK /__________...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY \|\|\|\|\|\...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY_HOLD \__________...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY_ALT \/\/\/\/\/\...
|
||||||
|
// _________
|
||||||
|
// ENVELOPE_SHAPE_CONT_DECAY_ALT_HOLD \| ...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK /|/|/|/|/|/...
|
||||||
|
// __________
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK_HOLD / ...
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK_ALT /\/\/\/\/\/...
|
||||||
|
//
|
||||||
|
// ENVELOPE_SHAPE_CONT_ATTACK_ALT_HOLD /|_________...
|
||||||
|
|
||||||
|
#define ENVELOPE_SHAPE_ONE_SHOT_DECAY 0
|
||||||
|
#define ENVELOPE_SHAPE_ONE_SHOT_ATTACK 4
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY 8
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY_HOLD 9
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY_ALT 10
|
||||||
|
#define ENVELOPE_SHAPE_CONT_DECAY_ALT_HOLD 11
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK 12
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK_HOLD 13
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK_ALT 14
|
||||||
|
#define ENVELOPE_SHAPE_CONT_ATTACK_ALT_HOLD 15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Typedefs
|
||||||
|
|
||||||
|
typedef uint8_t tSlot;
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SPEAKER_NONE = 0,
|
||||||
|
SPEAKER_LEFT = (1 << 0),
|
||||||
|
SPEAKER_RIGHT = (1 << 1),
|
||||||
|
SPEAKER_BOTH = (1 << 0) | (1 << 1)
|
||||||
|
} tMockingBoardSpeaker;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct tMockingSoundRegisters {
|
||||||
|
uint16_t tonePeriod[MOCK_NUM_CHANNELS];
|
||||||
|
uint8_t noisePeriod;
|
||||||
|
uint8_t enable;
|
||||||
|
uint8_t amplitude[MOCK_NUM_CHANNELS];
|
||||||
|
uint16_t envelopePeriod;
|
||||||
|
uint8_t envelopeShape;
|
||||||
|
uint8_t dummy1;
|
||||||
|
uint8_t dummy2;
|
||||||
|
} tMockingSoundRegisters;
|
||||||
|
|
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
extern void mockingBoardInit(tSlot slot, bool hasSpeechChip);
|
||||||
|
extern void mockingBoardShutdown(void);
|
||||||
|
|
||||||
|
extern void mockingBoardPlaySound(tMockingBoardSpeaker speaker, tMockingSoundRegisters *registers);
|
||||||
|
extern void mockingBoardStopSound(tMockingBoardSpeaker speaker);
|
||||||
|
|
||||||
|
extern bool mockingBoardSpeechIsBusy(void);
|
||||||
|
extern bool mockingBoardSpeechIsPlaying(void);
|
||||||
|
extern bool mockingBoardSpeak(uint8_t *data, uint16_t dataLen);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* defined(__mocktest__mockingboard__) */
|
26
ocanada/mockingboard_speech.h
Executable file
26
ocanada/mockingboard_speech.h
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// mockingboard_speech.h
|
||||||
|
// mocktest
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2016-10-17.
|
||||||
|
// Copyright © 2016 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef mockingboard_speech_h
|
||||||
|
#define mockingboard_speech_h
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern uint8_t *mockingBoardSpeechData;
|
||||||
|
extern uint16_t mockingBoardSpeechLen;
|
||||||
|
extern uint8_t mockingBoardSpeechBusy;
|
||||||
|
extern uint8_t mockingBoardSpeechPlaying;
|
||||||
|
|
||||||
|
extern void mockingBoardSpeechInit(uint8_t slot);
|
||||||
|
extern void mockingBoardSpeechShutdown(void);
|
||||||
|
extern void mockingBoardSpeakPriv(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* mockingboard_speech_h */
|
265
ocanada/mockingboard_speech.s
Executable file
265
ocanada/mockingboard_speech.s
Executable file
@@ -0,0 +1,265 @@
|
|||||||
|
;
|
||||||
|
; speech.s
|
||||||
|
; mocktest
|
||||||
|
;
|
||||||
|
; Created by Jeremy Rand on 2016-09-29.
|
||||||
|
; Copyright © 2016 Jeremy Rand. All rights reserved.
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
.export _mockingBoardSpeechInit, _mockingBoardSpeechShutdown, _mockingBoardSpeakPriv
|
||||||
|
.export _mockingBoardSpeechData, _mockingBoardSpeechLen
|
||||||
|
.export _mockingBoardSpeechBusy, _mockingBoardSpeechPlaying
|
||||||
|
.interruptor mock_irq
|
||||||
|
|
||||||
|
|
||||||
|
TMPPTR := $FB ; Temporary pointer used in interrupt handler
|
||||||
|
IRQL := $03FE ; Interrupt vector, low byte
|
||||||
|
IRQH := $03FF ; Interrupt vector, high byte
|
||||||
|
BASE := $40 ; First speech chip
|
||||||
|
DURPHON := BASE ; Register 0 of speech chip
|
||||||
|
INFLECT := BASE+$01 ; Register 1 of speech chip
|
||||||
|
RATEINF := BASE+$02 ; Register 2 of speech chip
|
||||||
|
CTTRAMP := BASE+$03 ; Register 3 of speech chip
|
||||||
|
FILFREQ := BASE+$04 ; Register 4 of speech chip
|
||||||
|
DDRB := $02
|
||||||
|
DDRA := $03
|
||||||
|
PCR := $8C ; Peripheral control register, 6522
|
||||||
|
IFR := $8D ; Interrupt flag register, 6522
|
||||||
|
IER := $8E
|
||||||
|
|
||||||
|
|
||||||
|
.DATA
|
||||||
|
_mockingBoardSpeechData: .byte $00, $00
|
||||||
|
_mockingBoardSpeechLen: .byte $00, $00
|
||||||
|
_outptr: .byte $00, $00
|
||||||
|
_endptr: .byte $00, $00
|
||||||
|
_mockingBoardSpeechBusy: .byte $00
|
||||||
|
_mockingBoardSpeechPlaying: .byte $00
|
||||||
|
|
||||||
|
mock_irq: .byte $60
|
||||||
|
.lobytes _mockInterrupt
|
||||||
|
.hibytes _mockInterrupt
|
||||||
|
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
|
||||||
|
writeChip:
|
||||||
|
sta $C000,X
|
||||||
|
rts
|
||||||
|
|
||||||
|
readChip:
|
||||||
|
lda $C000,X
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
.proc _mockingBoardSpeechInit
|
||||||
|
sei
|
||||||
|
|
||||||
|
; The accumulator has the slot number of the mockingboard.
|
||||||
|
; Turn that into the address of the slot and set the address
|
||||||
|
; in the read and write functions.
|
||||||
|
and #$7
|
||||||
|
ora #$c0
|
||||||
|
sta writeChip+2
|
||||||
|
sta readChip+2
|
||||||
|
|
||||||
|
; Write a jump instruction at mock_irq to turn on our handler
|
||||||
|
lda #$4c
|
||||||
|
sta mock_irq
|
||||||
|
|
||||||
|
cli
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.proc _mockingBoardSpeechShutdown
|
||||||
|
sei
|
||||||
|
|
||||||
|
; Write a RTS instruction at mock_irq to disable our handler
|
||||||
|
lda #$60
|
||||||
|
sta mock_irq
|
||||||
|
|
||||||
|
cli
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.proc _mockingBoardSpeakPriv
|
||||||
|
sei
|
||||||
|
lda #$00
|
||||||
|
ldx #DDRA
|
||||||
|
jsr writeChip
|
||||||
|
ldx #DDRB
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Get the starting address of the data and store in the work pointer
|
||||||
|
lda _mockingBoardSpeechData+1
|
||||||
|
sta _outptr+1
|
||||||
|
lda _mockingBoardSpeechData
|
||||||
|
sta _outptr
|
||||||
|
|
||||||
|
; Calculate the end address from the start address and the length
|
||||||
|
lda _mockingBoardSpeechLen+1
|
||||||
|
clc
|
||||||
|
adc _mockingBoardSpeechData+1
|
||||||
|
sta _endptr+1
|
||||||
|
lda _mockingBoardSpeechLen
|
||||||
|
clc
|
||||||
|
adc _mockingBoardSpeechData
|
||||||
|
bcc @L2
|
||||||
|
inc _endptr+1
|
||||||
|
@L2:
|
||||||
|
sta _endptr
|
||||||
|
|
||||||
|
; Set the busy flag
|
||||||
|
lda #$FF
|
||||||
|
sta _mockingBoardSpeechBusy
|
||||||
|
|
||||||
|
; Set peripheral control register to recognize the signal from the
|
||||||
|
; speech chip.
|
||||||
|
lda #$0C
|
||||||
|
ldx #PCR
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Raise control bit in register 3
|
||||||
|
lda #$80
|
||||||
|
ldx #CTTRAMP
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Set transitioned inflection mode in register 0
|
||||||
|
lda #$C0
|
||||||
|
ldx #DURPHON
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Lower control bit
|
||||||
|
lda #$70
|
||||||
|
ldx #CTTRAMP
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Enable 6522 interrupts
|
||||||
|
lda #$82
|
||||||
|
ldx #IER
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
cli
|
||||||
|
rts
|
||||||
|
.endproc
|
||||||
|
|
||||||
|
|
||||||
|
.proc _mockInterrupt
|
||||||
|
; If we have a 6522 interrupt, jump to L4.
|
||||||
|
ldx #IFR
|
||||||
|
jsr readChip
|
||||||
|
bmi @L4
|
||||||
|
|
||||||
|
; Otherwise clear the carry to indicate we didn't handle the interrupt
|
||||||
|
; and return to the caller.
|
||||||
|
clc
|
||||||
|
rts
|
||||||
|
|
||||||
|
@L4:
|
||||||
|
; Clear the interrupt flag
|
||||||
|
lda #$02
|
||||||
|
ldx #IFR
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Check for end of data file. If not the end, jump to L1
|
||||||
|
lda _outptr+1
|
||||||
|
cmp _endptr+1
|
||||||
|
bcc @L1
|
||||||
|
bne @L5
|
||||||
|
lda _outptr
|
||||||
|
cmp _endptr
|
||||||
|
bcc @L1
|
||||||
|
|
||||||
|
@L5:
|
||||||
|
|
||||||
|
; If at the end, turn everything off. Store a pause phoneme.
|
||||||
|
lda #$00
|
||||||
|
ldx #DURPHON
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Zero amplitude
|
||||||
|
lda #$70
|
||||||
|
ldx #CTTRAMP
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Clear busy and playing flags
|
||||||
|
lda #$00
|
||||||
|
sta _mockingBoardSpeechBusy
|
||||||
|
sta _mockingBoardSpeechPlaying
|
||||||
|
|
||||||
|
; Clear interrupt enable in 6522
|
||||||
|
lda #$02
|
||||||
|
ldx #IER
|
||||||
|
jsr writeChip
|
||||||
|
lda #$FF
|
||||||
|
ldx #DDRA
|
||||||
|
jsr writeChip
|
||||||
|
lda #$07
|
||||||
|
ldx #DDRB
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
@L2:
|
||||||
|
; Set the carry flag to indicate we handled the interrupt and return to the caller.
|
||||||
|
sec
|
||||||
|
rts
|
||||||
|
|
||||||
|
@L1:
|
||||||
|
|
||||||
|
; Set the speach playing flag
|
||||||
|
lda #$ff
|
||||||
|
sta _mockingBoardSpeechPlaying
|
||||||
|
|
||||||
|
; Save the value of the tmp pointer on the stack
|
||||||
|
lda TMPPTR
|
||||||
|
pha
|
||||||
|
lda TMPPTR+1
|
||||||
|
pha
|
||||||
|
|
||||||
|
; Move the _outptr into the tmp pointer
|
||||||
|
lda _outptr
|
||||||
|
sta TMPPTR
|
||||||
|
lda _outptr+1
|
||||||
|
sta TMPPTR+1
|
||||||
|
|
||||||
|
; Init registers
|
||||||
|
ldy #$00
|
||||||
|
ldx #FILFREQ
|
||||||
|
|
||||||
|
@L6:
|
||||||
|
; Get the next data
|
||||||
|
lda (TMPPTR),Y
|
||||||
|
|
||||||
|
; Store in the speech chip
|
||||||
|
jsr writeChip
|
||||||
|
|
||||||
|
; Next data
|
||||||
|
inc TMPPTR
|
||||||
|
bne @L3
|
||||||
|
inc TMPPTR+1
|
||||||
|
|
||||||
|
@L3:
|
||||||
|
; Go to next register
|
||||||
|
dex
|
||||||
|
|
||||||
|
; If we are not done the last register, then loop back to L6
|
||||||
|
cpx #BASE-1
|
||||||
|
bne @L6
|
||||||
|
|
||||||
|
; We are done writing so move the tmp pointer back into _outptr
|
||||||
|
lda TMPPTR
|
||||||
|
sta _outptr
|
||||||
|
lda TMPPTR+1
|
||||||
|
sta _outptr+1
|
||||||
|
|
||||||
|
; Restore the tmp pointer from the stack
|
||||||
|
pla
|
||||||
|
sta TMPPTR+1
|
||||||
|
pla
|
||||||
|
sta TMPPTR
|
||||||
|
|
||||||
|
; Finish the interrupt handler
|
||||||
|
jmp @L2
|
||||||
|
.endproc
|
151
ocanada/song.c
Normal file
151
ocanada/song.c
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
//
|
||||||
|
// song.c
|
||||||
|
// ocanada
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2017-07-01.
|
||||||
|
// Copyright © 2017 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <conio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "mockingboard.h"
|
||||||
|
#include "song.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct tSongNote {
|
||||||
|
uint16_t mainTone;
|
||||||
|
uint16_t bassTone;
|
||||||
|
uint8_t duration;
|
||||||
|
char *words;
|
||||||
|
} tSongNote;
|
||||||
|
|
||||||
|
|
||||||
|
static tSongNote notes[] = {
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 8, "\n\nO" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 6, " CAN" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 2, "A" },
|
||||||
|
{ TONE_PERIOD_C(4), TONE_PERIOD_A(2), 12, "DA" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_A(2), 4, "\nOUR" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 4, " HOME" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_C(2), 4, " AND" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_C(2), 4, " NA" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_C(2), 4, "TIVE" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 16, " LAND" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 8, "\nTRUE" },
|
||||||
|
{ TONE_PERIOD_F_SHARP(4), TONE_PERIOD_D(2), 6, " PA" },
|
||||||
|
{ TONE_PERIOD_F_SHARP(4), TONE_PERIOD_D(2), 2, "TRIOT" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 12, " LOVE" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_G(2), 4, " IN" },
|
||||||
|
{ TONE_PERIOD_B(4), TONE_PERIOD_G(2), 4, "\nALL" },
|
||||||
|
{ TONE_PERIOD_B(4), TONE_PERIOD_G(2), 4, " THY" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_D(2), 4, " SONS" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_D(2), 4, " COM" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 12, "MAND" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 3, "\nWITH" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_G(2), 1, "" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_G(2), 6, " GLOW" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_G(2), 2, "ING" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 4, " HEARTS" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_G(2), 3, " WE" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_G(2), 1, "" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_C(2), 6, " SEE" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_C(2), 2, " THEE" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 4, " RISE" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_C(2), 3, "\nTHE" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_C(2), 1, "" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_F(2), 4, " TRUE" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_F(2), 4, " NORTH" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_F(2), 4, " STRONG" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_F(2), 4, " AND" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 12, " FREE" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 3, "\nFROM" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_G(2), 1, "" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_G(2), 6, " FAR" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_G(2), 2, " AND" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 4, " WIDE" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_G(2), 3, ", O" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_G(2), 1, "" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_C(2), 6, " CAN" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_C(2), 2, "A" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 4, "DA" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 4, "\nWE" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 4, " STAND" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 4, " ON" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_D(2), 2, " GUARD" },
|
||||||
|
{ TONE_PERIOD_F_SHARP(4), TONE_PERIOD_D(2), 2, "" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_D(2), 2, " FOR" },
|
||||||
|
{ TONE_PERIOD_F_SHARP(4), TONE_PERIOD_D(2), 2, "" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 16, " THEE" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 8, "\nGOD" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 6, " KEEP" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_G(2), 2, " OUR" },
|
||||||
|
{ TONE_PERIOD_C(4), TONE_PERIOD_A(2), 16, " LAND" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_D(2), 8, ", GLO" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_D(2), 6, "RIOUS" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_D(2), 2, " AND" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_G(2), 16, " FREE" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_C(2), 8, "\nO" },
|
||||||
|
{ TONE_PERIOD_G_SHARP(4), TONE_PERIOD_E(2), 6, " CAN" },
|
||||||
|
{ TONE_PERIOD_G_SHARP(4), TONE_PERIOD_E(2), 2, "A" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_F(2), 4, "DA" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_F(2), 4, ", WE" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 4, " STAND" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_C(2), 4, " ON" },
|
||||||
|
{ TONE_PERIOD_C(4), TONE_PERIOD_A(2), 8, " GUARD" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_D(2), 8, " FOR" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_E(2), 16, " THEE" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_C(2), 8, "\nO" },
|
||||||
|
{ TONE_PERIOD_C(5), TONE_PERIOD_C(2), 6, " CAN" },
|
||||||
|
{ TONE_PERIOD_C(5), TONE_PERIOD_C(2), 2, "A" },
|
||||||
|
{ TONE_PERIOD_A(4), TONE_PERIOD_F(2), 4, "DA" },
|
||||||
|
{ TONE_PERIOD_F(4), TONE_PERIOD_F(2), 4, ", WE" },
|
||||||
|
{ TONE_PERIOD_E(4), TONE_PERIOD_C(2), 4, " STAND" },
|
||||||
|
{ TONE_PERIOD_D(4), TONE_PERIOD_C(2), 4, " ON" },
|
||||||
|
{ TONE_PERIOD_G(4), TONE_PERIOD_C(2), 8, " GUARD" },
|
||||||
|
{ TONE_PERIOD_B(4), TONE_PERIOD_G(2), 8, " FOR" },
|
||||||
|
{ TONE_PERIOD_C(5), TONE_PERIOD_C(2), 16, " THEE!" },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void delay(uint8_t duration)
|
||||||
|
{
|
||||||
|
uint8_t count;
|
||||||
|
|
||||||
|
for (count = 0; count < duration; count++) {
|
||||||
|
uint16_t insideCount = 0;
|
||||||
|
do {
|
||||||
|
insideCount++;
|
||||||
|
} while (insideCount != 768);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void playSong(void)
|
||||||
|
{
|
||||||
|
uint16_t noteNum;
|
||||||
|
static tMockingSoundRegisters regs;
|
||||||
|
|
||||||
|
regs.noisePeriod = MIN_NOISE_PERIOD;
|
||||||
|
regs.enable = ENABLE_ALL_TONE_CHANNELS;
|
||||||
|
regs.amplitude[0] = MAX_AMPLITUDE;
|
||||||
|
regs.amplitude[1] = MAX_AMPLITUDE;
|
||||||
|
regs.amplitude[2] = MAX_AMPLITUDE;
|
||||||
|
regs.envelopePeriod = MIN_ENVELOPE_PERIOD;
|
||||||
|
regs.envelopeShape = ENVELOPE_SHAPE_CONT_ATTACK_HOLD;
|
||||||
|
|
||||||
|
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||||
|
for (noteNum = 0; noteNum < (sizeof(notes) / sizeof(notes[0])); noteNum++) {
|
||||||
|
regs.tonePeriod[0] = notes[noteNum].mainTone;
|
||||||
|
regs.tonePeriod[1] = notes[noteNum].mainTone;
|
||||||
|
regs.tonePeriod[2] = notes[noteNum].bassTone;
|
||||||
|
|
||||||
|
mockingBoardPlaySound(SPEAKER_BOTH, ®s);
|
||||||
|
printf("%s", notes[noteNum].words);
|
||||||
|
delay(notes[noteNum].duration);
|
||||||
|
}
|
||||||
|
mockingBoardStopSound(SPEAKER_BOTH);
|
||||||
|
cgetc();
|
||||||
|
}
|
16
ocanada/song.h
Normal file
16
ocanada/song.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// song.h
|
||||||
|
// ocanada
|
||||||
|
//
|
||||||
|
// Created by Jeremy Rand on 2017-07-01.
|
||||||
|
// Copyright © 2017 Jeremy Rand. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __ocanada__song__
|
||||||
|
#define __ocanada__song__
|
||||||
|
|
||||||
|
|
||||||
|
extern void playSong(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* defined(__ocanada__song__) */
|
Reference in New Issue
Block a user