Merge pull request #2734 from mrdudz/mega65c

C65 and Mega65 initial C support
This commit is contained in:
Bob Andrews
2025-06-27 16:41:28 +02:00
committed by GitHub
76 changed files with 3771 additions and 47 deletions

239
asminc/c65.inc Normal file
View File

@@ -0,0 +1,239 @@
; ---------------------------------------------------------------------------
; Zero page, Commodore stuff
TXTPTR := $3C ; Pointer into BASIC source code
STATUS := $90 ; Kernal I/O completion status
FNAM_LEN := $B7 ; Length of filename
SECADR := $B9 ; Secondary address
DEVNUM := $BA ; Device number
FNAM := $BB ; Address of filename
FNAM_BANK := $BE ; Bank for filename
KEY_COUNT := $D0 ; Number of keys in input buffer
FKEY_COUNT := $D1 ; Characters for function key
MODE := $D7 ; 40-/80-column mode (bit 7: 80 columns)
GRAPHM := $D8 ; Graphics mode flags (bits 5-7)
CHARDIS := $D9 ; Bit 2 shadow for location $01
CURS_X := $EC ; Cursor column
CURS_Y := $EB ; Cursor row
SCREEN_PTR := $E0 ; Pointer to current char in text screen
CRAM_PTR := $E2 ; Pointer to current char in color RAM
CHARCOLOR := $F1
RVS := $F3 ; Reverse output flag
SCROLL := $F8 ; Disable scrolling flag
BASIC_BUF := $0200 ; Location of command-line
BASIC_BUF_LEN = 161 ; Maximum length of command-line
FKEY_LEN := $1000 ; Function key lengths
FKEY_TEXT := $100A ; Function key texts
PALFLAG := $1103 ; $FF=PAL, $00=NTSC
INIT_STATUS := $1104 ; Flags: Reset/Restore initiation status
TIME := $110C ; 60HZ clock
KBDREPEAT := $111a
KBDREPEATRATE := $111b
KBDREPEATDELAY := $111c
; ---------------------------------------------------------------------------
; Vectors
IRQVec := $0314
BRKVec := $0316
NMIVec := $0318
; ---------------------------------------------------------------------------
; I/O: VIC
VIC := $D000
VIC_SPR0_X := $D000
VIC_SPR0_Y := $D001
VIC_SPR1_X := $D002
VIC_SPR1_Y := $D003
VIC_SPR2_X := $D004
VIC_SPR2_Y := $D005
VIC_SPR3_X := $D006
VIC_SPR3_Y := $D007
VIC_SPR4_X := $D008
VIC_SPR4_Y := $D009
VIC_SPR5_X := $D00A
VIC_SPR5_Y := $D00B
VIC_SPR6_X := $D00C
VIC_SPR6_Y := $D00D
VIC_SPR7_X := $D00E
VIC_SPR7_Y := $D00F
VIC_SPR_HI_X := $D010
VIC_SPR_ENA := $D015
VIC_SPR_EXP_Y := $D017
VIC_SPR_EXP_X := $D01D
VIC_SPR_MCOLOR := $D01C
VIC_SPR_BG_PRIO := $D01B
VIC_SPR_COLL := $D01E
VIC_SPR_BG_COLL := $D01F
VIC_SPR_MCOLOR0 := $D025
VIC_SPR_MCOLOR1 := $D026
VIC_SPR0_COLOR := $D027
VIC_SPR1_COLOR := $D028
VIC_SPR2_COLOR := $D029
VIC_SPR3_COLOR := $D02A
VIC_SPR4_COLOR := $D02B
VIC_SPR5_COLOR := $D02C
VIC_SPR6_COLOR := $D02D
VIC_SPR7_COLOR := $D02E
VIC_CTRL1 := $D011
VIC_CTRL2 := $D016
VIC_HLINE := $D012
VIC_LPEN_X := $D013
VIC_LPEN_Y := $D014
VIC_VIDEO_ADR := $D018
VIC_IRR := $D019 ; Interrupt request register
VIC_IMR := $D01A ; Interrupt mask register
VIC_BORDERCOLOR := $D020
VIC_BG_COLOR0 := $D021
VIC_BG_COLOR1 := $D022
VIC_BG_COLOR2 := $D023
VIC_BG_COLOR3 := $D024
; ---------------------------------------------------------------------------
; I/O: FDC
FDC := $D080
; ---------------------------------------------------------------------------
; I/O: SID
SID1 := $D400
SID1_S1Lo := $D400
SID1_S1Hi := $D401
SID1_PB1Lo := $D402
SID1_PB1Hi := $D403
SID1_Ctl1 := $D404
SID1_AD1 := $D405
SID1_SUR1 := $D406
SID1_S2Lo := $D407
SID1_S2Hi := $D408
SID1_PB2Lo := $D409
SID1_PB2Hi := $D40A
SID1_Ctl2 := $D40B
SID1_AD2 := $D40C
SID1_SUR2 := $D40D
SID1_S3Lo := $D40E
SID1_S3Hi := $D40F
SID1_PB3Lo := $D410
SID1_PB3Hi := $D411
SID1_Ctl3 := $D412
SID1_AD3 := $D413
SID1_SUR3 := $D414
SID1_FltLo := $D415
SID1_FltHi := $D416
SID1_FltCtl := $D417
SID1_Amp := $D418
SID1_ADConv1 := $D419
SID1_ADConv2 := $D41A
SID1_Noise := $D41B
SID1_Read3 := $D41C
SID2 := $D420
SID2_S1Lo := $D420
SID2_S1Hi := $D421
SID2_PB1Lo := $D422
SID2_PB1Hi := $D423
SID2_Ctl1 := $D424
SID2_AD1 := $D425
SID2_SUR1 := $D426
SID2_S2Lo := $D427
SID2_S2Hi := $D428
SID2_PB2Lo := $D429
SID2_PB2Hi := $D42A
SID2_Ctl2 := $D42B
SID2_AD2 := $D42C
SID2_SUR2 := $D42D
SID2_S3Lo := $D42E
SID2_S3Hi := $D42F
SID2_PB3Lo := $D430
SID2_PB3Hi := $D431
SID2_Ctl3 := $D432
SID2_AD3 := $D433
SID2_SUR3 := $D434
SID2_FltLo := $D435
SID2_FltHi := $D436
SID2_FltCtl := $D437
SID2_Amp := $D438
SID2_ADConv1 := $D439
SID2_ADConv2 := $D43A
SID2_Noise := $D43B
SID2_Read3 := $D43C
; ---------------------------------------------------------------------------
; I/O: Complex Interface Adapters
CIA1 := $DC00
CIA1_PRA := $DC00 ; Port A
CIA1_PRB := $DC01 ; Port B
CIA1_DDRA := $DC02 ; Data direction register for port A
CIA1_DDRB := $DC03 ; Data direction register for port B
CIA1_TA := $DC04 ; 16-bit timer A
CIA1_TB := $DC06 ; 16-bit timer B
CIA1_TOD10 := $DC08 ; Time-of-day tenths of a second
CIA1_TODSEC := $DC09 ; Time-of-day seconds
CIA1_TODMIN := $DC0A ; Time-of-day minutes
CIA1_TODHR := $DC0B ; Time-of-day hours
CIA1_SDR := $DC0C ; Serial data register
CIA1_ICR := $DC0D ; Interrupt control register
CIA1_CRA := $DC0E ; Control register for timer A
CIA1_CRB := $DC0F ; Control register for timer B
CIA2 := $DD00
CIA2_PRA := $DD00
CIA2_PRB := $DD01
CIA2_DDRA := $DD02
CIA2_DDRB := $DD03
CIA2_TA := $DD04
CIA2_TB := $DD06
CIA2_TOD10 := $DD08
CIA2_TODSEC := $DD09
CIA2_TODMIN := $DD0A
CIA2_TODHR := $DD0B
CIA2_SDR := $DD0C
CIA2_ICR := $DD0D
CIA2_CRA := $DD0E
CIA2_CRB := $DD0F
; ---------------------------------------------------------------------------
; I/O: DMA
DMA := $D700
; ---------------------------------------------------------------------------
; Processor Port at $01
LORAM = $01 ; Enable the basic rom
HIRAM = $02 ; Enable the kernal rom
IOEN = $04 ; Enable I/O
CASSDATA = $08 ; Cassette data
CASSPLAY = $10 ; Cassette: Play
CASSMOT = $20 ; Cassette motor on
TP_FAST = $80 ; Switch Rossmoeller TurboProcess to fast mode
RAMONLY = $F8 ; (~(LORAM | HIRAM | IOEN)) & $FF
; temporary, to get conio working
XSIZE = 80
YSIZE = 50

View File

@@ -63,6 +63,43 @@
MOUSE_GET := $FF6B MOUSE_GET := $FF6B
.endif .endif
.if .def (__MEGA65__)
; extended C65 jump table
; memory before $ff3b is all $ff in mega65 ROM?
; VERSIONQ := $FF2F
; RESET_RUN := $FF32
; CURSOR := $FF35
SAVEFL := $FF3B
GETIO := $FF41
GETLFS := $FF44
KEYLOCKS := $FF47
ADDKEY := $FF4A
.endif
.if .def(__C65__) || .def (__MEGA65__)
CURSOR := $E030 ; in editor ROM
SPIN_SPOUT := $FF4D
CLSALL := $FF50
C64MODE := $FF53
MonitorCall := $FF56
BOOT_SYS := $FF59
PHOENIX := $FF5C
LKUPLA := $FF5F
LKUPSA := $FF62
SWAPPER := $FF65
PFKEY := $FF68
SETBNK := $FF6B
JSRFAR := $FF6E
JMPFAR := $FF71
LDA_FAR := $FF74
STA_FAR := $FF77
CMP_FAR := $FF7A
PRIMM := $FF7D
.endif
.if .def(__C128__) .if .def(__C128__)
; C128 extended jump table ; C128 extended jump table
C64MODE := $FF4D C64MODE := $FF4D
@@ -83,7 +120,7 @@
PRIMM := $FF7D PRIMM := $FF7D
.endif .endif
.if .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) .if .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def (__MEGA65__)
CINT := $FF81 CINT := $FF81
IOINIT := $FF84 IOINIT := $FF84
RAMTAS := $FF87 RAMTAS := $FF87
@@ -96,7 +133,7 @@
CINT := $FF7E CINT := $FF7E
.endif .endif
.if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) .if .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def (__MEGA65__)
RESTOR := $FF8A RESTOR := $FF8A
VECTOR := $FF8D VECTOR := $FF8D
.elseif .def(__CBM510__) || .def(__CBM610__) .elseif .def(__CBM510__) || .def(__CBM610__)
@@ -112,6 +149,17 @@
MEMBOT := $FF9C MEMBOT := $FF9C
SCNKEY := $FF9F SCNKEY := $FF9F
SETTMO := $FFA2 SETTMO := $FFA2
.elseif .def(__C65__) || .def (__MEGA65__)
SETMSG := $FF90
SECOND := $FF93
TKSA := $FF96
MEMTOP := $FF99
MEMBOT := $FF9C
SCNKEY := $FF9F
MONEXIT := $FFA2
.endif
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def(__MEGA65__)
ACPTR := $FFA5 ACPTR := $FFA5
CIOUT := $FFA8 CIOUT := $FFA8
UNTLK := $FFAB UNTLK := $FFAB
@@ -136,7 +184,7 @@ CHRIN := $FFCF
BSOUT := $FFD2 BSOUT := $FFD2
CHROUT := $FFD2 CHROUT := $FFD2
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) .if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def(__MEGA65__)
LOAD := $FFD5 LOAD := $FFD5
SAVE := $FFD8 SAVE := $FFD8
SETTIM := $FFDB SETTIM := $FFDB
@@ -147,9 +195,14 @@ CHROUT := $FFD2
STOP := $FFE1 STOP := $FFE1
GETIN := $FFE4 GETIN := $FFE4
CLALL := $FFE7 CLALL := $FFE7
UDTIM := $FFEA
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) .if .def(__C65__) || .def(__MEGA65__)
ScanStopKey := $FFEA
.else
UDTIM := $FFEA
.endif
.if .def(__CBM510__) || .def(__CBM610__) || .def(__VIC20__) || .def(__C64__) || .def(__C128__) || .def(__C16__) || .def(__CX16__) || .def(__C65__) || .def(__MEGA65__)
SCREEN := $FFED SCREEN := $FFED
PLOT := $FFF0 PLOT := $FFF0
IOBASE := $FFF3 IOBASE := $FFF3
@@ -173,10 +226,10 @@ UDTIM := $FFEA
KBDREAD := $E5CF KBDREAD := $E5CF
UPDCRAMPTR := $EAB2 UPDCRAMPTR := $EAB2
.elseif .def(__C64__) .elseif .def(__C64__)
CLRSCR := $E544 CLRSCR := $E544 ; Clear the screen
KBDREAD := $E5B4 KBDREAD := $E5B4 ; Get Character From Keyboard Buffer
NMIEXIT := $FEBC NMIEXIT := $FEBC
UPDCRAMPTR := $EA24 UPDCRAMPTR := $EA24 ; Update color ram pointer
.elseif .def(__C128__) .elseif .def(__C128__)
CLRSCR := $C142 CLRSCR := $C142
KBDREAD := $C006 KBDREAD := $C006
@@ -189,4 +242,7 @@ UDTIM := $FFEA
.elseif .def(__C16__) .elseif .def(__C16__)
CLRSCR := $D88B CLRSCR := $D88B
KBDREAD := $D8C1 KBDREAD := $D8C1
.elseif .def(__C65__) || .def(__MEGA65__)
; CLRSCR := $E0EC ; ???
KBDREAD := $E006
.endif .endif

View File

@@ -1,4 +1,5 @@
; CPU bitmask constants ; CPU bitmask constants (make sure this matches src/common/cpu.h)
CPU_ISET_NONE = $0001 CPU_ISET_NONE = $0001
CPU_ISET_6502 = $0002 CPU_ISET_6502 = $0002
CPU_ISET_6502X = $0004 CPU_ISET_6502X = $0004
@@ -13,17 +14,20 @@ CPU_ISET_4510 = $0400
CPU_ISET_45GS02 = $0800 CPU_ISET_45GS02 = $0800
; CPU capabilities ; CPU capabilities
; make sure to only combine the instruction sets that are 100% compatible
CPU_NONE = CPU_ISET_NONE CPU_NONE = CPU_ISET_NONE
CPU_6502 = CPU_ISET_6502 CPU_6502 = CPU_ISET_6502
CPU_6502X = CPU_ISET_6502|CPU_ISET_6502X CPU_6502X = CPU_ISET_6502X | CPU_ISET_6502
CPU_6502DTV = CPU_ISET_6502|CPU_ISET_6502DTV CPU_6502DTV = CPU_ISET_6502DTV | CPU_ISET_6502
CPU_65SC02 = CPU_ISET_6502|CPU_ISET_65SC02 CPU_65SC02 = CPU_ISET_65SC02 | CPU_ISET_6502
CPU_65C02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02 CPU_65C02 = CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02
CPU_65816 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65816 CPU_65816 = CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02
CPU_SWEET16 = CPU_ISET_SWEET16 CPU_SWEET16 = CPU_ISET_SWEET16
; FIXME: CPU_ISET_65SC02 does not apply to the following, because the zp-indirect
; addressing was replaced with zp-indirect,z-indexed in 652SCE02
; NOTE: HUC6280 removes "wai" ($cb) and "stp" ($db) from the 65C02 instruction set ; NOTE: HUC6280 removes "wai" ($cb) and "stp" ($db) from the 65C02 instruction set
CPU_HUC6280 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_HUC6280 CPU_HUC6280 = CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65C02
; NOTE: 45100 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set ; NOTE: 4510 replaces "wai" ($cb) and "stp" ($db) of the 65C02 instruction set
CPU_4510 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510 CPU_4510 = CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02
CPU_45GS02 = CPU_ISET_6502|CPU_ISET_65SC02|CPU_ISET_65C02|CPU_ISET_4510|CPU_ISET_45GS02 CPU_45GS02 = CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510
CPU_M740 = CPU_ISET_6502|CPU_ISET_M740 CPU_M740 = CPU_ISET_M740 | CPU_ISET_6502

239
asminc/mega65.inc Normal file
View File

@@ -0,0 +1,239 @@
; ---------------------------------------------------------------------------
; Zero page, Commodore stuff
TXTPTR := $3C ; Pointer into BASIC source code
STATUS := $90 ; Kernal I/O completion status
FNAM_LEN := $B7 ; Length of filename
SECADR := $B9 ; Secondary address
DEVNUM := $BA ; Device number
FNAM := $BB ; Address of filename
FNAM_BANK := $BE ; Bank for filename
KEY_COUNT := $D0 ; Number of keys in input buffer
FKEY_COUNT := $D1 ; Characters for function key
MODE := $D7 ; 40-/80-column mode (bit 7: 80 columns)
GRAPHM := $D8 ; Graphics mode flags (bits 5-7)
CHARDIS := $D9 ; Bit 2 shadow for location $01
CURS_X := $EC ; Cursor column
CURS_Y := $EB ; Cursor row
SCREEN_PTR := $E0 ; Pointer to current char in text screen
CRAM_PTR := $E2 ; Pointer to current char in color RAM
CHARCOLOR := $F1
RVS := $F3 ; Reverse output flag
SCROLL := $F8 ; Disable scrolling flag
BASIC_BUF := $0200 ; Location of command-line
BASIC_BUF_LEN = 161 ; Maximum length of command-line
FKEY_LEN := $1000 ; Function key lengths
FKEY_TEXT := $100A ; Function key texts
PALFLAG := $1103 ; $FF=PAL, $00=NTSC
INIT_STATUS := $1104 ; Flags: Reset/Restore initiation status
TIME := $110C ; 60HZ clock
KBDREPEAT := $111a
KBDREPEATRATE := $111b
KBDREPEATDELAY := $111c
; ---------------------------------------------------------------------------
; Vectors
IRQVec := $0314
BRKVec := $0316
NMIVec := $0318
; ---------------------------------------------------------------------------
; I/O: VIC
VIC := $D000
VIC_SPR0_X := $D000
VIC_SPR0_Y := $D001
VIC_SPR1_X := $D002
VIC_SPR1_Y := $D003
VIC_SPR2_X := $D004
VIC_SPR2_Y := $D005
VIC_SPR3_X := $D006
VIC_SPR3_Y := $D007
VIC_SPR4_X := $D008
VIC_SPR4_Y := $D009
VIC_SPR5_X := $D00A
VIC_SPR5_Y := $D00B
VIC_SPR6_X := $D00C
VIC_SPR6_Y := $D00D
VIC_SPR7_X := $D00E
VIC_SPR7_Y := $D00F
VIC_SPR_HI_X := $D010
VIC_SPR_ENA := $D015
VIC_SPR_EXP_Y := $D017
VIC_SPR_EXP_X := $D01D
VIC_SPR_MCOLOR := $D01C
VIC_SPR_BG_PRIO := $D01B
VIC_SPR_COLL := $D01E
VIC_SPR_BG_COLL := $D01F
VIC_SPR_MCOLOR0 := $D025
VIC_SPR_MCOLOR1 := $D026
VIC_SPR0_COLOR := $D027
VIC_SPR1_COLOR := $D028
VIC_SPR2_COLOR := $D029
VIC_SPR3_COLOR := $D02A
VIC_SPR4_COLOR := $D02B
VIC_SPR5_COLOR := $D02C
VIC_SPR6_COLOR := $D02D
VIC_SPR7_COLOR := $D02E
VIC_CTRL1 := $D011
VIC_CTRL2 := $D016
VIC_HLINE := $D012
VIC_LPEN_X := $D013
VIC_LPEN_Y := $D014
VIC_VIDEO_ADR := $D018
VIC_IRR := $D019 ; Interrupt request register
VIC_IMR := $D01A ; Interrupt mask register
VIC_BORDERCOLOR := $D020
VIC_BG_COLOR0 := $D021
VIC_BG_COLOR1 := $D022
VIC_BG_COLOR2 := $D023
VIC_BG_COLOR3 := $D024
; ---------------------------------------------------------------------------
; I/O: FDC
FDC := $D080
; ---------------------------------------------------------------------------
; I/O: SID
SID0 := $D400
SID0_S1Lo := $D400
SID0_S1Hi := $D401
SID0_PB1Lo := $D402
SID0_PB1Hi := $D403
SID0_Ctl1 := $D404
SID0_AD1 := $D405
SID0_SUR1 := $D406
SID0_S2Lo := $D407
SID0_S2Hi := $D408
SID0_PB2Lo := $D409
SID0_PB2Hi := $D40A
SID0_Ctl2 := $D40B
SID0_AD2 := $D40C
SID0_SUR2 := $D40D
SID0_S3Lo := $D40E
SID0_S3Hi := $D40F
SID0_PB3Lo := $D410
SID0_PB3Hi := $D411
SID0_Ctl3 := $D412
SID0_AD3 := $D413
SID0_SUR3 := $D414
SID0_FltLo := $D415
SID0_FltHi := $D416
SID0_FltCtl := $D417
SID0_Amp := $D418
SID0_ADConv1 := $D419
SID0_ADConv2 := $D41A
SID0_Noise := $D41B
SID0_Read3 := $D41C
SID1 := $D420
SID1_S1Lo := $D420
SID1_S1Hi := $D421
SID1_PB1Lo := $D422
SID1_PB1Hi := $D423
SID1_Ctl1 := $D424
SID1_AD1 := $D425
SID1_SUR1 := $D426
SID1_S2Lo := $D427
SID1_S2Hi := $D428
SID1_PB2Lo := $D429
SID1_PB2Hi := $D42A
SID1_Ctl2 := $D42B
SID1_AD2 := $D42C
SID1_SUR2 := $D42D
SID1_S3Lo := $D42E
SID1_S3Hi := $D42F
SID1_PB3Lo := $D430
SID1_PB3Hi := $D431
SID1_Ctl3 := $D432
SID1_AD3 := $D433
SID1_SUR3 := $D434
SID1_FltLo := $D435
SID1_FltHi := $D436
SID1_FltCtl := $D437
SID1_Amp := $D438
SID1_ADConv1 := $D439
SID1_ADConv2 := $D43A
SID1_Noise := $D43B
SID1_Read3 := $D43C
; ---------------------------------------------------------------------------
; I/O: Complex Interface Adapters
CIA1 := $DC00
CIA1_PRA := $DC00 ; Port A
CIA1_PRB := $DC01 ; Port B
CIA1_DDRA := $DC02 ; Data direction register for port A
CIA1_DDRB := $DC03 ; Data direction register for port B
CIA1_TA := $DC04 ; 16-bit timer A
CIA1_TB := $DC06 ; 16-bit timer B
CIA1_TOD10 := $DC08 ; Time-of-day tenths of a second
CIA1_TODSEC := $DC09 ; Time-of-day seconds
CIA1_TODMIN := $DC0A ; Time-of-day minutes
CIA1_TODHR := $DC0B ; Time-of-day hours
CIA1_SDR := $DC0C ; Serial data register
CIA1_ICR := $DC0D ; Interrupt control register
CIA1_CRA := $DC0E ; Control register for timer A
CIA1_CRB := $DC0F ; Control register for timer B
CIA2 := $DD00
CIA2_PRA := $DD00
CIA2_PRB := $DD01
CIA2_DDRA := $DD02
CIA2_DDRB := $DD03
CIA2_TA := $DD04
CIA2_TB := $DD06
CIA2_TOD10 := $DD08
CIA2_TODSEC := $DD09
CIA2_TODMIN := $DD0A
CIA2_TODHR := $DD0B
CIA2_SDR := $DD0C
CIA2_ICR := $DD0D
CIA2_CRA := $DD0E
CIA2_CRB := $DD0F
; ---------------------------------------------------------------------------
; I/O: DMA
DMA := $D700
; ---------------------------------------------------------------------------
; Processor Port at $01
LORAM = $01 ; Enable the basic rom
HIRAM = $02 ; Enable the kernal rom
IOEN = $04 ; Enable I/O
CASSDATA = $08 ; Cassette data
CASSPLAY = $10 ; Cassette: Play
CASSMOT = $20 ; Cassette motor on
TP_FAST = $80 ; Switch Rossmoeller TurboProcess to fast mode
RAMONLY = $F8 ; (~(LORAM | HIRAM | IOEN)) & $FF
; temporary, to get conio working
XSIZE = 80
YSIZE = 50

44
cfg/c65.cfg Normal file
View File

@@ -0,0 +1,44 @@
FEATURES {
STARTADDRESS: default = $2001;
}
SYMBOLS {
__LOADADDR__: type = import;
__EXEHDR__: type = import;
__STACKSIZE__: type = weak, value = $0800; # 2k stack
__HIMEM__: type = weak, value = $8000;
}
MEMORY {
ZP: file = "", define = yes, start = $0018, size = $001A;
LOADADDR: file = %O, start = %S - 2, size = $0002;
HEADER: file = %O, define = yes, start = %S, size = $0010;
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = HEADER, type = ro;
STARTUP: load = MAIN, type = ro;
LOWCODE: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BSS: load = BSS, type = bss, define = yes;
}
FEATURES {
CONDES: type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__,
segment = ONCE;
CONDES: type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__,
segment = RODATA;
CONDES: type = interruptor,
label = __INTERRUPTOR_TABLE__,
count = __INTERRUPTOR_COUNT__,
segment = RODATA,
import = __CALLIRQ__;
}

44
cfg/mega65.cfg Normal file
View File

@@ -0,0 +1,44 @@
FEATURES {
STARTADDRESS: default = $2001;
}
SYMBOLS {
__LOADADDR__: type = import;
__EXEHDR__: type = import;
__STACKSIZE__: type = weak, value = $0800; # 2k stack
__HIMEM__: type = weak, value = $8000;
}
MEMORY {
ZP: file = "", define = yes, start = $0018, size = $001A;
LOADADDR: file = %O, start = %S - 2, size = $0002;
HEADER: file = %O, define = yes, start = %S, size = $0010;
MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__;
BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __STACKSIZE__ - __ONCE_RUN__;
}
SEGMENTS {
ZEROPAGE: load = ZP, type = zp;
LOADADDR: load = LOADADDR, type = ro;
EXEHDR: load = HEADER, type = ro;
STARTUP: load = MAIN, type = ro;
LOWCODE: load = MAIN, type = ro, optional = yes;
CODE: load = MAIN, type = ro;
RODATA: load = MAIN, type = ro;
DATA: load = MAIN, type = rw;
INIT: load = MAIN, type = rw; # uninitialized, but reserves output space
ONCE: load = MAIN, type = ro, define = yes;
BSS: load = BSS, type = bss, define = yes;
}
FEATURES {
CONDES: type = constructor,
label = __CONSTRUCTOR_TABLE__,
count = __CONSTRUCTOR_COUNT__,
segment = ONCE;
CONDES: type = destructor,
label = __DESTRUCTOR_TABLE__,
count = __DESTRUCTOR_COUNT__,
segment = RODATA;
CONDES: type = interruptor,
label = __INTERRUPTOR_TABLE__,
count = __INTERRUPTOR_COUNT__,
segment = RODATA,
import = __CALLIRQ__;
}

188
include/_vic3.h Normal file
View File

@@ -0,0 +1,188 @@
/*****************************************************************************/
/* */
/* _vic3.h */
/* */
/* Internal include file, do not use directly */
/* */
/* */
/* */
/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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 __VIC3_H
#define __VIC3_H
/* FIXME: only VIC2 registers right now */
/* Define a structure with the vic register offsets. In cc65 mode, there
** are aliases for the field accessible as arrays.
*/
#if __CC65_STD__ == __CC65_STD_CC65__
struct __vic3 {
union {
struct {
unsigned char spr0_x; /* Sprite 0, X coordinate */
unsigned char spr0_y; /* Sprite 0, Y coordinate */
unsigned char spr1_x; /* Sprite 1, X coordinate */
unsigned char spr1_y; /* Sprite 1, Y coordinate */
unsigned char spr2_x; /* Sprite 2, X coordinate */
unsigned char spr2_y; /* Sprite 2, Y coordinate */
unsigned char spr3_x; /* Sprite 3, X coordinate */
unsigned char spr3_y; /* Sprite 3, Y coordinate */
unsigned char spr4_x; /* Sprite 4, X coordinate */
unsigned char spr4_y; /* Sprite 4, Y coordinate */
unsigned char spr5_x; /* Sprite 5, X coordinate */
unsigned char spr5_y; /* Sprite 5, Y coordinate */
unsigned char spr6_x; /* Sprite 6, X coordinate */
unsigned char spr6_y; /* Sprite 6, Y coordinate */
unsigned char spr7_x; /* Sprite 7, X coordinate */
unsigned char spr7_y; /* Sprite 7, Y coordinate */
};
struct {
unsigned char x; /* X coordinate */
unsigned char y; /* Y coordinate */
} spr_pos[8];
};
unsigned char spr_hi_x; /* High bits of X coordinate */
unsigned char ctrl1; /* Control register 1 */
unsigned char rasterline; /* Current raster line */
union {
struct {
unsigned char strobe_x; /* Light pen, X position */
unsigned char strobe_y; /* Light pen, Y position */
};
struct {
unsigned char x; /* Light pen, X position */
unsigned char y; /* Light pen, Y position */
} strobe;
};
unsigned char spr_ena; /* Enable sprites */
unsigned char ctrl2; /* Control register 2 */
unsigned char spr_exp_y; /* Expand sprites in Y dir */
unsigned char addr; /* Address of chargen and video ram */
unsigned char irr; /* Interrupt request register */
unsigned char imr; /* Interrupt mask register */
unsigned char spr_bg_prio; /* Priority to background */
unsigned char spr_mcolor; /* Sprite multicolor bits */
unsigned char spr_exp_x; /* Expand sprites in X dir */
unsigned char spr_coll; /* Sprite/sprite collision reg */
unsigned char spr_bg_coll; /* Sprite/background collision reg */
unsigned char bordercolor; /* Border color */
union {
struct {
unsigned char bgcolor0; /* Background color 0 */
unsigned char bgcolor1; /* Background color 1 */
unsigned char bgcolor2; /* Background color 2 */
unsigned char bgcolor3; /* Background color 3 */
};
unsigned char bgcolor[4]; /* Background colors */
};
union {
struct {
unsigned char spr_mcolor0; /* Color 0 for multicolor sprites */
unsigned char spr_mcolor1; /* Color 1 for multicolor sprites */
};
/* spr_color is already used ... */
unsigned char spr_mcolors[2]; /* Color for multicolor sprites */
};
union {
struct {
unsigned char spr0_color; /* Color sprite 0 */
unsigned char spr1_color; /* Color sprite 1 */
unsigned char spr2_color; /* Color sprite 2 */
unsigned char spr3_color; /* Color sprite 3 */
unsigned char spr4_color; /* Color sprite 4 */
unsigned char spr5_color; /* Color sprite 5 */
unsigned char spr6_color; /* Color sprite 6 */
unsigned char spr7_color; /* Color sprite 7 */
};
unsigned char spr_color[8]; /* Colors for the sprites */
};
/* The following ones are only valid in the C128: */
unsigned char x_kbd; /* Additional keyboard lines */
unsigned char clock; /* Clock switch bit */
};
#else
struct __vic3 {
unsigned char spr0_x; /* Sprite 0, X coordinate */
unsigned char spr0_y; /* Sprite 0, Y coordinate */
unsigned char spr1_x; /* Sprite 1, X coordinate */
unsigned char spr1_y; /* Sprite 1, Y coordinate */
unsigned char spr2_x; /* Sprite 2, X coordinate */
unsigned char spr2_y; /* Sprite 2, Y coordinate */
unsigned char spr3_x; /* Sprite 3, X coordinate */
unsigned char spr3_y; /* Sprite 3, Y coordinate */
unsigned char spr4_x; /* Sprite 4, X coordinate */
unsigned char spr4_y; /* Sprite 4, Y coordinate */
unsigned char spr5_x; /* Sprite 5, X coordinate */
unsigned char spr5_y; /* Sprite 5, Y coordinate */
unsigned char spr6_x; /* Sprite 6, X coordinate */
unsigned char spr6_y; /* Sprite 6, Y coordinate */
unsigned char spr7_x; /* Sprite 7, X coordinate */
unsigned char spr7_y; /* Sprite 7, Y coordinate */
unsigned char spr_hi_x; /* High bits of X coordinate */
unsigned char ctrl1; /* Control register 1 */
unsigned char rasterline; /* Current raster line */
unsigned char strobe_x; /* Light pen, X position */
unsigned char strobe_y; /* Light pen, Y position */
unsigned char spr_ena; /* Enable sprites */
unsigned char ctrl2; /* Control register 2 */
unsigned char spr_exp_y; /* Expand sprites in Y dir */
unsigned char addr; /* Address of chargen and video ram */
unsigned char irr; /* Interrupt request register */
unsigned char imr; /* Interrupt mask register */
unsigned char spr_bg_prio; /* Priority to background */
unsigned char spr_mcolor; /* Sprite multicolor bits */
unsigned char spr_exp_x; /* Expand sprites in X dir */
unsigned char spr_coll; /* Sprite/sprite collision reg */
unsigned char spr_bg_coll; /* Sprite/background collision reg */
unsigned char bordercolor; /* Border color */
unsigned char bgcolor0; /* Background color 0 */
unsigned char bgcolor1; /* Background color 1 */
unsigned char bgcolor2; /* Background color 2 */
unsigned char bgcolor3; /* Background color 3 */
unsigned char spr_mcolor0; /* Color 0 for multicolor sprites */
unsigned char spr_mcolor1; /* Color 1 for multicolor sprites */
unsigned char spr0_color; /* Color sprite 0 */
unsigned char spr1_color; /* Color sprite 1 */
unsigned char spr2_color; /* Color sprite 2 */
unsigned char spr3_color; /* Color sprite 3 */
unsigned char spr4_color; /* Color sprite 4 */
unsigned char spr5_color; /* Color sprite 5 */
unsigned char spr6_color; /* Color sprite 6 */
unsigned char spr7_color; /* Color sprite 7 */
};
#endif
/* End of _vic3.h */
#endif

120
include/c65.h Normal file
View File

@@ -0,0 +1,120 @@
/*****************************************************************************/
/* */
/* c65.h */
/* */
/* C65 system specific definitions */
/* */
/* */
/* */
/* (C) 1998-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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 _C65_H
#define _C65_H
/* Check for errors */
#if !defined(__C65__)
# error This module may only be used when compiling for the MEGA65!
#endif
/* Additional key defines */
#define CH_F1 133
#define CH_F2 137
#define CH_F3 134
#define CH_F4 138
#define CH_F5 135
#define CH_F6 139
#define CH_F7 136
#define CH_F8 140
/* Color defines */
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
#define COLOR_RED 0x02
#define COLOR_CYAN 0x03
#define COLOR_PURPLE 0x04
#define COLOR_GREEN 0x05
#define COLOR_BLUE 0x06
#define COLOR_YELLOW 0x07
#define COLOR_ORANGE 0x08
#define COLOR_BROWN 0x09
#define COLOR_LIGHTRED 0x0A
#define COLOR_GRAY1 0x0B
#define COLOR_GRAY2 0x0C
#define COLOR_LIGHTGREEN 0x0D
#define COLOR_LIGHTBLUE 0x0E
#define COLOR_GRAY3 0x0F
/* TGI color defines */
#define TGI_COLOR_BLACK COLOR_BLACK
#define TGI_COLOR_WHITE COLOR_WHITE
#define TGI_COLOR_RED COLOR_RED
#define TGI_COLOR_CYAN COLOR_CYAN
#define TGI_COLOR_PURPLE COLOR_PURPLE
#define TGI_COLOR_GREEN COLOR_GREEN
#define TGI_COLOR_BLUE COLOR_BLUE
#define TGI_COLOR_YELLOW COLOR_YELLOW
#define TGI_COLOR_ORANGE COLOR_ORANGE
#define TGI_COLOR_BROWN COLOR_BROWN
#define TGI_COLOR_LIGHTRED COLOR_LIGHTRED
#define TGI_COLOR_GRAY1 COLOR_GRAY1
#define TGI_COLOR_GRAY2 COLOR_GRAY2
#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN
#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE
#define TGI_COLOR_GRAY3 COLOR_GRAY3
/* Masks for joy_read */
#define JOY_UP_MASK 0x01
#define JOY_DOWN_MASK 0x02
#define JOY_LEFT_MASK 0x04
#define JOY_RIGHT_MASK 0x08
#define JOY_BTN_1_MASK 0x10
/* Define hardware */
#include <_vic3.h>
#define VIC (*(struct __vic2*)0xD000)
#include <_sid.h>
#define SID1 (*(struct __sid*)0xD400)
#define SID2 (*(struct __sid*)0xD420)
#include <_6526.h>
#define CIA1 (*(struct __6526*)0xDC00)
#define CIA2 (*(struct __6526*)0xDD00)
/* Define special memory areas */
#define COLOR_RAM ((unsigned char*)0xD800)
/* End of c65.h */
#endif

View File

@@ -67,6 +67,10 @@
# include <pet.h> # include <pet.h>
#elif defined(__CX16__) && !defined(_CX16_H) #elif defined(__CX16__) && !defined(_CX16_H)
# include <cx16.h> # include <cx16.h>
#elif defined(__C65__) && !defined(_C65_H)
# include <c65.h>
#elif defined(__MEGA65__) && !defined(_MEGA65_H)
# include <mega65.h>
#endif #endif
/* Include definitions for CBM file types */ /* Include definitions for CBM file types */

120
include/mega65.h Normal file
View File

@@ -0,0 +1,120 @@
/*****************************************************************************/
/* */
/* mega65.h */
/* */
/* MEGA65 system specific definitions */
/* */
/* */
/* */
/* (C) 1998-2013, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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 _MEGA65_H
#define _MEGA65_H
/* Check for errors */
#if !defined(__MEGA65__)
# error This module may only be used when compiling for the MEGA65!
#endif
/* Additional key defines */
#define CH_F1 133
#define CH_F2 137
#define CH_F3 134
#define CH_F4 138
#define CH_F5 135
#define CH_F6 139
#define CH_F7 136
#define CH_F8 140
/* Color defines */
#define COLOR_BLACK 0x00
#define COLOR_WHITE 0x01
#define COLOR_RED 0x02
#define COLOR_CYAN 0x03
#define COLOR_PURPLE 0x04
#define COLOR_GREEN 0x05
#define COLOR_BLUE 0x06
#define COLOR_YELLOW 0x07
#define COLOR_ORANGE 0x08
#define COLOR_BROWN 0x09
#define COLOR_LIGHTRED 0x0A
#define COLOR_GRAY1 0x0B
#define COLOR_GRAY2 0x0C
#define COLOR_LIGHTGREEN 0x0D
#define COLOR_LIGHTBLUE 0x0E
#define COLOR_GRAY3 0x0F
/* TGI color defines */
#define TGI_COLOR_BLACK COLOR_BLACK
#define TGI_COLOR_WHITE COLOR_WHITE
#define TGI_COLOR_RED COLOR_RED
#define TGI_COLOR_CYAN COLOR_CYAN
#define TGI_COLOR_PURPLE COLOR_PURPLE
#define TGI_COLOR_GREEN COLOR_GREEN
#define TGI_COLOR_BLUE COLOR_BLUE
#define TGI_COLOR_YELLOW COLOR_YELLOW
#define TGI_COLOR_ORANGE COLOR_ORANGE
#define TGI_COLOR_BROWN COLOR_BROWN
#define TGI_COLOR_LIGHTRED COLOR_LIGHTRED
#define TGI_COLOR_GRAY1 COLOR_GRAY1
#define TGI_COLOR_GRAY2 COLOR_GRAY2
#define TGI_COLOR_LIGHTGREEN COLOR_LIGHTGREEN
#define TGI_COLOR_LIGHTBLUE COLOR_LIGHTBLUE
#define TGI_COLOR_GRAY3 COLOR_GRAY3
/* Masks for joy_read */
#define JOY_UP_MASK 0x01
#define JOY_DOWN_MASK 0x02
#define JOY_LEFT_MASK 0x04
#define JOY_RIGHT_MASK 0x08
#define JOY_BTN_1_MASK 0x10
/* Define hardware */
#include <_vic3.h>
#define VIC (*(struct __vic2*)0xD000)
#include <_sid.h>
#define SID1 (*(struct __sid*)0xD400)
#define SID2 (*(struct __sid*)0xD420)
#include <_6526.h>
#define CIA1 (*(struct __6526*)0xDC00)
#define CIA2 (*(struct __6526*)0xDD00)
/* Define special memory areas */
#define COLOR_RAM ((unsigned char*)0xD800)
/* End of mega65.h */
#endif

View File

@@ -11,9 +11,11 @@ endif
CBMS = c128 \ CBMS = c128 \
c16 \ c16 \
c64 \ c64 \
c65 \
cbm510 \ cbm510 \
cbm610 \ cbm610 \
cx16 \ cx16 \
mega65 \
pet \ pet \
plus4 \ plus4 \
vic20 vic20
@@ -21,7 +23,6 @@ CBMS = c128 \
GEOS = geos-apple \ GEOS = geos-apple \
geos-cbm geos-cbm
# FIXME: c65 (and perhaps mega65?) should be moved up to CBMS maybe
TARGETS = agat \ TARGETS = agat \
apple2 \ apple2 \
apple2enh \ apple2enh \
@@ -31,7 +32,6 @@ TARGETS = agat \
atari5200 \ atari5200 \
atari7800 \ atari7800 \
atmos \ atmos \
c65 \
creativision \ creativision \
$(CBMS) \ $(CBMS) \
$(GEOS) \ $(GEOS) \
@@ -47,8 +47,7 @@ TARGETS = agat \
sim65c02 \ sim65c02 \
supervision \ supervision \
sym1 \ sym1 \
telestrat \ telestrat
mega65
TARGETTEST = none \ TARGETTEST = none \
sim6502 \ sim6502 \
@@ -196,11 +195,6 @@ ifeq ($(TARGET),$(filter $(TARGET),$(GEOS)))
SRCDIRS += $(addprefix geos-common/,$(GEOSDIRS)) SRCDIRS += $(addprefix geos-common/,$(GEOSDIRS))
endif endif
ifeq ($(TARGET),c65)
# FIXME: this does not work because of the SP vs C_SP clash
else ifeq ($(TARGET),mega65)
# FIXME: this does not work because of the SP vs C_SP clash
else
SRCDIRS += common \ SRCDIRS += common \
conio \ conio \
dbg \ dbg \
@@ -211,7 +205,6 @@ SRCDIRS += common \
serial \ serial \
tgi \ tgi \
zlib zlib
endif
vpath %.s $(SRCDIRS) vpath %.s $(SRCDIRS)
vpath %.c $(SRCDIRS) vpath %.c $(SRCDIRS)

17
libsrc/c65/_scrsize.s Normal file
View File

@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 26.10.2000
;
; Screen size variables
;
.export screensize
.include "cbm_kernal.inc"
.proc screensize
jsr SCREEN
inx
iny
rts
.endproc

17
libsrc/c65/bordercolor.s Normal file
View File

@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _bordercolor
.include "c65.inc"
_bordercolor:
ldx VIC_BORDERCOLOR ; get old value
sta VIC_BORDERCOLOR ; set new value
txa
rts

32
libsrc/c65/cgetc.s Normal file
View File

@@ -0,0 +1,32 @@
.include "cbm_kernal.inc"
.import cursor
.export _cgetc
_cgetc:
lda cursor
beq nocursor
; enable the cursor
clc
jsr CURSOR
nocursor:
; wait for a key
; FIXME: is $d610 mega65 specific?
:
lda $d610
beq :-
jsr KBDREAD
pha
; disable the cursor
sec
jsr CURSOR
pla
ldx #0
rts

15
libsrc/c65/clrscr.s Normal file
View File

@@ -0,0 +1,15 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; void clrscr (void);
;
.export _clrscr
.include "cbm_kernal.inc"
;_clrscr = CLRSCR
_clrscr:
lda #$93
jmp CHROUT

24
libsrc/c65/color.s Normal file
View File

@@ -0,0 +1,24 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
;
.export _textcolor, _bgcolor
.include "c65.inc"
_textcolor:
ldx CHARCOLOR ; get old value
sta CHARCOLOR ; set new value
txa
rts
_bgcolor:
ldx VIC_BG_COLOR0 ; get old value
sta VIC_BG_COLOR0 ; set new value
txa
rts

10
libsrc/c65/conio.s Normal file
View File

@@ -0,0 +1,10 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; Low level stuff for screen output/console input
;
.exportzp CURS_X, CURS_Y
.include "c65.inc"

45
libsrc/c65/cpeekc.s Normal file
View File

@@ -0,0 +1,45 @@
;
; 2016-02-28, Groepaz
; 2017-06-22, Greg King
;
; char cpeekc (void);
;
.include "c65.inc"
.export _cpeekc
.importzp ptr1
_cpeekc:
lda SCREEN_PTR + 1
clc
adc #>$0800
sta ptr1 + 1
lda SCREEN_PTR
sta ptr1
ldy CURS_X
lda (ptr1),y ; get screen code
ldx #>$0000
and #<~$80 ; remove reverse bit
; Convert the screen code into a PetSCII code.
; $00 - $1F: +$40
; $20 - $3F
; $40 - $5f: +$20
; $60 - $7F: +$40
cmp #$20
bcs @sk1 ;(bge)
ora #$40
rts
@sk1: cmp #$40
bcc @end ;(blt)
cmp #$60
bcc @sk2 ;(blt)
;sec
adc #$20 - $01
@sk2: ;clc ; both above cmp and adc clear carry flag
adc #$20
@end: rts

25
libsrc/c65/cpeekcolor.s Normal file
View File

@@ -0,0 +1,25 @@
;
; 2016-02-28, Groepaz
; 2017-06-22, Greg King
;
; unsigned char cpeekcolor (void);
;
.include "c65.inc"
.export _cpeekcolor
.importzp ptr1
_cpeekcolor:
lda SCREEN_PTR + 1
clc
adc #>$D800
sta ptr1 + 1
lda SCREEN_PTR
sta ptr1
ldy #0
lda (ptr1),y
ldx #>$0000
rts

28
libsrc/c65/cpeekrevers.s Normal file
View File

@@ -0,0 +1,28 @@
;
; 2016-02-28, Groepaz
; 2017-06-15, Greg King
;
; unsigned char cpeekrevers (void);
;
.include "c65.inc"
.export _cpeekrevers
.importzp ptr1
_cpeekrevers:
lda SCREEN_PTR + 1
clc
adc #>$0800
sta ptr1 + 1
lda SCREEN_PTR
sta ptr1
ldy CURS_X
lda (ptr1),y ; get screen code
and #$80 ; get reverse bit
asl a
tax ; ldx #>$0000
rol a ; return boolean value
rts

80
libsrc/c65/cpeeks.s Normal file
View File

@@ -0,0 +1,80 @@
;
; 2017-07-05, Greg King
;
; void cpeeks (char* s, unsigned length);
;
.include "c65.inc"
.export _cpeeks
.import popax
.importzp ptr1, ptr2, ptr3, tmp1, tmp2
.macpack generic
_cpeeks:
eor #<$FFFF ; counting a word upward is faster
sta ptr3 ; so, we use -(length + 1)
txa
eor #>$FFFF
sta ptr3+1
lda SCREEN_PTR
sta ptr2
lda SCREEN_PTR+1
clc
adc #>$0800
sta ptr2+1
ldy CURS_X
sty tmp2
jsr popax
sta tmp1 ; (will be a .Y index)
stx ptr1+1
ldx #<$0000
stx ptr1
bze L3 ; branch always
L4: ldy tmp2
lda (ptr2),y ; get char
iny
bnz L2
inc ptr2+1
L2: sty tmp2
and #<~$80 ; remove reverse bit
; Convert the screen code into a PetSCII code.
; $00 - $1F: +$40
; $20 - $3F
; $40 - $5f: +$20
; $60 - $7F: +$40
cmp #$20
blt @sk1 ;(bcc)
cmp #$40
blt L5
cmp #$60
blt @sk2 ;(bcc)
clc
@sk1: adc #$20
@sk2: ;clc ; both above cmp and adc clear carry flag
adc #$20
L5: ldy tmp1
sta (ptr1),y
iny
bnz L1
inc ptr1+1
L1: sty tmp1
L3: inc ptr3 ; count length
bnz L4
inc ptr3+1
bnz L4
txa ; terminate the string
ldy tmp1
sta (ptr1),y
rts

120
libsrc/c65/cputc.s Normal file
View File

@@ -0,0 +1,120 @@
;
; Ullrich von Bassewitz, 1998-08-06, 2009-09-26
;
; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c);
; void __fastcall__ cputc (char c);
;
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
.import gotoxy
.import PLOT
.importzp ptr4
.include "c65.inc"
_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
; Printable char of some sort
cmp #' '
bcc cputdirect ; Other control char
tay
bmi L10
cmp #$60
bcc L2
and #$DF
bne cputdirect ; Branch always
L2: and #$3F
cputdirect:
jsr putchar ; Write the character to the screen
; Advance cursor position
advance:
iny
cpy #XSIZE
bne L3
jsr newline ; new line
ldy #0 ; + cr
L3: sty CURS_X
rts
newline:
clc
lda #XSIZE
adc SCREEN_PTR
sta SCREEN_PTR
bcc L4
inc SCREEN_PTR+1
clc
L4: lda #XSIZE
adc CRAM_PTR
sta CRAM_PTR
bcc L5
inc CRAM_PTR+1
L5: inc CURS_Y
rts
; Handle character if high bit set
L10: and #$7F
cmp #$7F ; PI?
bne L11
lda #$5E ; Load screen code for PI
L11: ora #$40
bne cputdirect
; Set cursor position, calculate RAM pointers.
plot: ldy CURS_X
ldx CURS_Y
clc
jmp PLOT ; Set the new cursor
; Write one character to the screen without doing anything else, return X
; position in Y
putchar:
ora RVS ; Set revers bit
tay
lda SCREEN_PTR + 1
clc
adc #>$0800
sta ptr4 + 1
lda SCREEN_PTR
sta ptr4
tya
ldy CURS_X
sta (ptr4),y ; Set char
lda ptr4 + 1
clc
adc #>$d000
sta ptr4 + 1
lda CHARCOLOR
sta (ptr4),y ; Set color
rts

123
libsrc/c65/crt0.s Normal file
View File

@@ -0,0 +1,123 @@
;
; Startup code for cc65 (C65 version)
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import zerobss, callmain
.import BSOUT
.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated
.import __STACKSIZE__ ; from configure file
.include "zeropage.inc"
.include "c65.inc"
; ------------------------------------------------------------------------
; Startup code
.segment "STARTUP"
Start:
; Switch off the BASIC ROM.
; FIXME
; lda $01
; sta mmusave ; Save the memory configuration
; and #$F8
; ora #$06 ; Enable Kernal+I/O, disable BASIC
; sta $01
; sei
; lda #%00000000 ; lower offset 15-8
; ldx #%00000000 ; map blk3-1 | lower offset 19-6
; ldy #%00000000 ; upper offset 15-8
; ldz #%00000000 ; map blk7-4 | upper offset 19-6
; map
; eom
tsx
stx spsave ; Save the system stack ptr
; Save space by putting some of the start-up code in the ONCE segment,
; which can be re-used by the BSS segment, the heap and the C stack.
jsr init
; Clear the BSS data.
jsr zerobss
; Push the command-line arguments; and, call main().
jsr callmain
; Back from main() [this is also the exit() entry]. Run the module destructors.
_exit: pha ; Save the return code on stack
jsr donelib
; Copy back the zero-page stuff.
ldx #zpspace-1
L2: lda zpsave,x
sta c_sp,x
dex
bpl L2
; Place the program return code into BASIC's status variable.
pla
sta STATUS
; Restore the system stuff.
ldx spsave
txs ; Restore stack pointer
; Back to BASIC.
rts
; ------------------------------------------------------------------------
.segment "ONCE"
init:
; Save the zero-page locations that we need.
ldx #zpspace-1
L1: lda c_sp,x
sta zpsave,x
dex
bpl L1
; Set up the stack.
lda #<(__MAIN_START__ + __MAIN_SIZE__)
ldx #>(__MAIN_START__ + __MAIN_SIZE__)
sta c_sp
stx c_sp+1 ; Set argument stack ptr
; Switch to the second charset.
lda #14
jsr BSOUT
; Call the module constructors.
jmp initlib
; ------------------------------------------------------------------------
; Data
.segment "INIT"
mmusave:.res 1
spsave: .res 1
zpsave: .res zpspace

7
libsrc/c65/devnum.s Normal file
View File

@@ -0,0 +1,7 @@
;
; Oliver Schmidt, 2010-02-14
;
.include "c65.inc"
.exportzp devnum := DEVNUM

25
libsrc/c65/get_tv.s Normal file
View File

@@ -0,0 +1,25 @@
;
; Ullrich von Bassewitz, 2002-12-03
;
; unsigned char get_tv (void);
; /* Return the video mode the machine is using */
;
.include "get_tv.inc"
.include "c65.inc"
;--------------------------------------------------------------------------
; _get_tv
.proc _get_tv
ldx #TV::PAL ; Assume PAL
lda PALFLAG
bne pal
dex ; NTSC
pal: txa
ldx #0
rts
.endproc

83
libsrc/c65/gettime.s Normal file
View File

@@ -0,0 +1,83 @@
;
; Stefan Haubenthal, 27.7.2009
; Oliver Schmidt, 14.8.2018
;
; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp);
;
.include "time.inc"
.include "c65.inc"
.importzp sreg, tmp1, tmp2
.import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0
.import TM, load_tenth
;----------------------------------------------------------------------------
.code
.proc _clock_gettime
jsr pushax
jsr pushax
lda CIA1_TODHR
sed
tax ; Save PM flag
and #%01111111
cmp #$12 ; 12 AM/PM
bcc @L1
sbc #$12
@L1: inx ; Get PM flag
bpl @L2
clc
adc #$12
@L2: cld
jsr BCD2dec
sta TM + tm::tm_hour
lda CIA1_TODMIN
jsr BCD2dec
sta TM + tm::tm_min
lda CIA1_TODSEC
jsr BCD2dec
sta TM + tm::tm_sec
lda #<TM
ldx #>TM
jsr _mktime
ldy #timespec::tv_sec
jsr steaxspidx ; Pops address pushed by 2. pushax
jsr load_tenth
jsr pusheax
lda CIA1_TOD10
ldx #>$0000
jsr tosmul0ax
ldy #timespec::tv_nsec
jsr steaxspidx ; Pops address pushed by 1. pushax
jsr incsp1
jmp return0
.endproc
;----------------------------------------------------------------------------
; dec = (((BCD>>4)*10) + (BCD&0xf))
.proc BCD2dec
tax
and #%00001111
sta tmp1
txa
and #%11110000 ; *16
lsr ; *8
sta tmp2
lsr
lsr ; *2
adc tmp2 ; = *10
adc tmp1
rts
.endproc

111
libsrc/c65/joy/c65-stdjoy.s Normal file
View File

@@ -0,0 +1,111 @@
;
; Standard joystick driver for the C65. May be used multiple times when linked
; to the statically application.
;
; Ullrich von Bassewitz, 2002-12-20
;
.include "zeropage.inc"
.include "joy-kernel.inc"
.include "joy-error.inc"
.include "c65.inc"
.macpack generic
.macpack module
; ------------------------------------------------------------------------
; Header. Includes jump table
module_header _c65_stdjoy_joy
; Driver signature
.byte $6A, $6F, $79 ; "joy"
.byte JOY_API_VERSION ; Driver API version number
; Library reference
.addr $0000
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr COUNT
.addr READ
; ------------------------------------------------------------------------
; Constants
JOY_COUNT = 2 ; Number of joysticks we support
; ------------------------------------------------------------------------
; Data.
.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 JOY_ERR_xx code in a/x.
;
INSTALL:
lda #JOY_ERR_OK
.assert JOY_ERR_OK = 0, error
tax
; 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
; ------------------------------------------------------------------------
; COUNT: Return the total number of available joysticks in a/x.
;
COUNT:
lda #<JOY_COUNT
ldx #>JOY_COUNT
rts
; ------------------------------------------------------------------------
; READ: Read a particular joystick passed in A.
;
READ: tax ; Joystick number into X
bne joy2
; Read joystick 1
joy1: lda #$7F
sei
sta CIA1_PRA
lda CIA1_PRB
cli
jmp end
; Read joystick 2
joy2: ldx #0
lda #$E0
ldy #$FF
sei
sta CIA1_DDRA
lda CIA1_PRA
sty CIA1_DDRA
cli
end: and #$1F
eor #$1F
rts

View File

@@ -0,0 +1,14 @@
;
; Address of the static standard joystick driver
;
; Oliver Schmidt, 2012-11-01
;
; const void joy_static_stddrv[];
;
.export _joy_static_stddrv
.import _c65_stdjoy_joy
.rodata
_joy_static_stddrv := _c65_stdjoy_joy

14
libsrc/c65/joy_stddrv.s Normal file
View File

@@ -0,0 +1,14 @@
;
; Name of the standard joystick driver
;
; Ullrich von Bassewitz, 2002-12-21
;
; const char joy_stddrv[];
;
.export _joy_stddrv
.rodata
_joy_stddrv: .asciiz "c65-stdjoy.joy"

14
libsrc/c65/kbhit.s Normal file
View File

@@ -0,0 +1,14 @@
; FIXME: is $d610 mega65 specific?
; FIXME: this should rather use the kernal (with keyboard buffer etc)
.export _kbhit
_kbhit:
lda $d610
beq :+
lda #1
:
ldx #>$0000
rts

47
libsrc/c65/kernal.s Normal file
View File

@@ -0,0 +1,47 @@
;
; Ullrich von Bassewitz, 19.11.2002
;
; C65 Kernal functions
;
.include "cbm_kernal.inc"
.export CINT
.export IOINIT
.export RAMTAS
.export RESTOR
.export VECTOR
.export SETMSG
.export SECOND
.export TKSA
.export MEMTOP
.export MEMBOT
.export SCNKEY
.export ACPTR
.export CIOUT
.export UNTLK
.export UNLSN
.export LISTEN
.export TALK
.export READST
.export SETLFS
.export SETNAM
.export OPEN
.export CLOSE
.export CHKIN
.export CKOUT
.export CLRCH
.export BASIN
.export CHRIN
.export BSOUT
.export CHROUT
.export LOAD
.export SAVE
.export SETTIM
.export RDTIM
.export STOP
.export GETIN
.export CLALL
.export SCREEN
.export IOBASE
.export PLOT

8
libsrc/c65/libref.s Normal file
View File

@@ -0,0 +1,8 @@
;
; Oliver Schmidt, 2013-05-31
;
.export joy_libref
.import _exit
joy_libref := _exit

137
libsrc/c65/mainargs.s Normal file
View File

@@ -0,0 +1,137 @@
; mainargs.s
;
; Ullrich von Bassewitz, 2003-03-07
; Based on code from Stefan A. Haubenthal, <polluks@web.de>
; 2003-05-18, Greg King
; 2004-04-28, 2005-02-26, Ullrich von Bassewitz
;
; Scan a group of arguments that are in BASIC's input-buffer.
; Build an array that points to the beginning of each argument.
; Send, to main(), that array and the count of the arguments.
;
; Command-lines look like these lines:
;
; run
; run : rem
; run:rem arg1 " arg 2 is quoted " arg3 "" arg5
;
; "run" and "rem" are entokenned; the args. are not. Leading and trailing
; spaces outside of quotes are ignored.
;
; TO-DO:
; - The "file-name" might be a path-name; don't copy the directory-components.
; - Add a control-character quoting mechanism.
.constructor initmainargs, 24
.import __argc, __argv
.include "c65.inc"
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special ONCE segment,
; which may be reused after the startup code is run
.segment "ONCE"
initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
lda #0 ; The terminating NUL character
ldy FNAM_LEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (FNAM),y
L1: sta name,y
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
ldx #0
L2: lda BASIC_BUF,x
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
ldy #1 * 2
; Find the next argument
next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
; will check now for a quoted argument, in which case we will have to skip this
; first character.
found: cmp #'"' ; Is the argument quoted?
beq setterm ; Jump if so
dex ; Reset pointer to first argument character
lda #' ' ; A space ends the argument
setterm:sta term ; Set end of argument marker
; Now store a pointer to the argument into the next slot. Since the BASIC
; input buffer is located at the start of a RAM page, no calculations are
; necessary.
txa ; Get low byte
sta argv,y ; argv[y]= &arg
iny
lda #>BASIC_BUF
sta argv,y
iny
inc __argc ; Found another arg
; Search for the end of the argument
argloop:lda BASIC_BUF,x
beq done
inx
cmp term
bne argloop
; We've found the end of the argument. X points one character behind it, and
; A contains the terminating character. To make the argument a valid C string,
; replace the terminating character by a zero.
lda #0
sta BASIC_BUF-1,x
; Check if the maximum number of command line arguments is reached. If not,
; parse the next one.
lda __argc ; Get low byte of argument count
cmp #MAXARGS ; Maximum number of arguments reached?
bcc next ; Parse next one if not
; (The last vector in argv[] already is NULL.)
done: lda #<argv
ldx #>argv
sta __argv
stx __argv + 1
rts
.segment "INIT"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2

18
libsrc/c65/randomize.s Normal file
View File

@@ -0,0 +1,18 @@
;
; 2002-11-05, Ullrich von Bassewitz
; 2015-09-11, Greg King
;
; void __randomize (void);
; /* Initialize the random number generator */
;
.export ___randomize
.import _srand
.include "c65.inc"
___randomize:
ldx VIC_HLINE ; Use VIC rasterline as high byte
lda TIME+2 ; Use 60HZ clock as low byte
jmp _srand ; Initialize generator

27
libsrc/c65/revers.s Normal file
View File

@@ -0,0 +1,27 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; unsigned char revers (unsigned char onoff);
;
.export _revers
.include "c65.inc"
.proc _revers
ldx #$00 ; Assume revers off
tay ; Test onoff
beq L1 ; Jump if off
ldx #$80 ; Load on value
ldy #$00 ; Assume old value is zero
L1: lda RVS ; Load old value
stx RVS ; Set new value
beq L2 ; Jump if old value zero
iny ; Make old value = 1
L2: ldx #$00 ; Load high byte of result
tya ; Load low byte, set CC
rts
.endproc

84
libsrc/c65/settime.s Normal file
View File

@@ -0,0 +1,84 @@
;
; Oliver Schmidt, 16.8.2018
;
; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp);
;
.include "time.inc"
.include "c65.inc"
.importzp sreg, ptr1
.import pushax, pusheax, ldax0sp, ldeaxidx
.import tosdiveax, incsp3, return0
.import TM, load_tenth
;----------------------------------------------------------------------------
.code
.proc _clock_settime
jsr pushax
.assert timespec::tv_sec = 0, error
jsr _localtime
sta ptr1
stx ptr1+1
ldy #.sizeof(tm)-1
@L1: lda (ptr1),y
sta TM,y
dey
bpl @L1
lda TM + tm::tm_hour
jsr dec2BCD
tax ; Force flags
bne @L2
lda #$92 ; 12 AM
bne @L3
@L2: cmp #$13 ; 1 PM
bcc @L3
sed
sbc #$12
cld
ora #%10000000
@L3: sta CIA1_TODHR
lda TM + tm::tm_min
jsr dec2BCD
sta CIA1_TODMIN
lda TM + tm::tm_sec
jsr dec2BCD
sta CIA1_TODSEC
jsr ldax0sp
ldy #3+timespec::tv_nsec
jsr ldeaxidx
jsr pusheax
jsr load_tenth
jsr tosdiveax
sta CIA1_TOD10
jsr incsp3
jmp return0
.endproc
;----------------------------------------------------------------------------
; Just sum up the value in BCD mode.
; http://forum.6502.org/viewtopic.php?p=7629#p7629
.proc dec2BCD
tax
dex
bmi @L9
lda #0
clc
sed
@L1: adc #1
dex
bpl @L1
cld
@L9: rts
.endproc

5
libsrc/c65/status.s Normal file
View File

@@ -0,0 +1,5 @@
;
; Oliver Schmidt, 2012-09-30
;
.exportzp ST := $90 ; IEC status byte

37
libsrc/c65/sysuname.s Normal file
View File

@@ -0,0 +1,37 @@
;
; Ullrich von Bassewitz, 2003-08-12
;
; unsigned char __fastcall__ _sysuname (struct utsname* buf);
;
.export __sysuname, utsdata
.import utscopy
__sysuname = utscopy
;--------------------------------------------------------------------------
; Data. We define a fixed utsname struct here and just copy it.
.rodata
utsdata:
; sysname
.asciiz "cc65"
; nodename
.asciiz ""
; release
.byte .string (>.version)
.byte '.'
.byte .string (<.version)
.byte $00
; version
.byte '0' ; unused
.byte $00
; machine
.asciiz "Commodore 65"

64
libsrc/c65/tmcommon.s Normal file
View File

@@ -0,0 +1,64 @@
;
; Oliver Schmidt, 16.8.2018
;
; Common stuff for the clock routines
;
.include "c65.inc"
.include "get_tv.inc"
.export TM, load_tenth
.constructor inittime
.importzp sreg
.import _get_tv
;----------------------------------------------------------------------------
.code
.proc load_tenth
lda #<(100 * 1000 * 1000 / $10000)
ldx #>(100 * 1000 * 1000 / $10000)
sta sreg
stx sreg+1
lda #<(100 * 1000 * 1000)
ldx #>(100 * 1000 * 1000)
rts
.endproc
;----------------------------------------------------------------------------
; Constructor that writes to the 1/10 sec register of the TOD to kick it
; into action. If this is not done, the clock hangs. We will read the register
; and write it again, ignoring a possible change in between.
.segment "ONCE"
.proc inittime
lda CIA1_TOD10
sta CIA1_TOD10
jsr _get_tv
cmp #TV::PAL
bne @60Hz
lda CIA1_CRA
ora #$80
sta CIA1_CRA
@60Hz: rts
.endproc
;----------------------------------------------------------------------------
; TM struct with date set to 1970-01-01
.data
TM: .word 0 ; tm_sec
.word 0 ; tm_min
.word 0 ; tm_hour
.word 1 ; tm_mday
.word 0 ; tm_mon
.word 70 ; tm_year
.word 0 ; tm_wday
.word 0 ; tm_yday
.word 0 ; tm_isdst

17
libsrc/mega65/_scrsize.s Normal file
View File

@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 26.10.2000
;
; Screen size variables
;
.export screensize
.include "cbm_kernal.inc"
.proc screensize
jsr SCREEN
inx
iny
rts
.endproc

View File

@@ -0,0 +1,17 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ bordercolor (unsigned char color);
;
.export _bordercolor
.include "mega65.inc"
_bordercolor:
ldx VIC_BORDERCOLOR ; get old value
sta VIC_BORDERCOLOR ; set new value
txa
rts

32
libsrc/mega65/cgetc.s Normal file
View File

@@ -0,0 +1,32 @@
.include "cbm_kernal.inc"
.import cursor
.export _cgetc
_cgetc:
lda cursor
beq nocursor
; enable the cursor
clc
jsr CURSOR
nocursor:
; wait for a key
; FIXME: is $d610 mega65 specific?
:
lda $d610
beq :-
jsr KBDREAD
pha
; disable the cursor
sec
jsr CURSOR
pla
ldx #0
rts

15
libsrc/mega65/clrscr.s Normal file
View File

@@ -0,0 +1,15 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; void clrscr (void);
;
.export _clrscr
.include "cbm_kernal.inc"
;_clrscr = CLRSCR
_clrscr:
lda #$93
jmp CHROUT

24
libsrc/mega65/color.s Normal file
View File

@@ -0,0 +1,24 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; unsigned char __fastcall__ textcolor (unsigned char color);
; unsigned char __fastcall__ bgcolor (unsigned char color);
;
.export _textcolor, _bgcolor
.include "mega65.inc"
_textcolor:
ldx CHARCOLOR ; get old value
sta CHARCOLOR ; set new value
txa
rts
_bgcolor:
ldx VIC_BG_COLOR0 ; get old value
sta VIC_BG_COLOR0 ; set new value
txa
rts

10
libsrc/mega65/conio.s Normal file
View File

@@ -0,0 +1,10 @@
;
; Ullrich von Bassewitz, 06.08.1998
;
; Low level stuff for screen output/console input
;
.exportzp CURS_X, CURS_Y
.include "mega65.inc"

45
libsrc/mega65/cpeekc.s Normal file
View File

@@ -0,0 +1,45 @@
;
; 2016-02-28, Groepaz
; 2017-06-22, Greg King
;
; char cpeekc (void);
;
.include "mega65.inc"
.export _cpeekc
.importzp ptr1
_cpeekc:
lda SCREEN_PTR + 1
clc
adc #>$0800
sta ptr1 + 1
lda SCREEN_PTR
sta ptr1
ldy CURS_X
lda (ptr1),y ; get screen code
ldx #>$0000
and #<~$80 ; remove reverse bit
; Convert the screen code into a PetSCII code.
; $00 - $1F: +$40
; $20 - $3F
; $40 - $5f: +$20
; $60 - $7F: +$40
cmp #$20
bcs @sk1 ;(bge)
ora #$40
rts
@sk1: cmp #$40
bcc @end ;(blt)
cmp #$60
bcc @sk2 ;(blt)
;sec
adc #$20 - $01
@sk2: ;clc ; both above cmp and adc clear carry flag
adc #$20
@end: rts

View File

@@ -0,0 +1,25 @@
;
; 2016-02-28, Groepaz
; 2017-06-22, Greg King
;
; unsigned char cpeekcolor (void);
;
.include "mega65.inc"
.export _cpeekcolor
.importzp ptr1
_cpeekcolor:
lda SCREEN_PTR + 1
clc
adc #>$d800
sta ptr1 + 1
lda SCREEN_PTR
sta ptr1
ldy CURS_X
lda (ptr1),y
ldx #>$0000
rts

View File

@@ -0,0 +1,28 @@
;
; 2016-02-28, Groepaz
; 2017-06-15, Greg King
;
; unsigned char cpeekrevers (void);
;
.include "mega65.inc"
.export _cpeekrevers
.importzp ptr1
_cpeekrevers:
lda SCREEN_PTR + 1
clc
adc #>$0800
sta ptr1 + 1
lda SCREEN_PTR
sta ptr1
ldy CURS_X
lda (ptr1),y ; get screen code
and #$80 ; get reverse bit
asl a
tax ; ldx #>$0000
rol a ; return boolean value
rts

80
libsrc/mega65/cpeeks.s Normal file
View File

@@ -0,0 +1,80 @@
;
; 2017-07-05, Greg King
;
; void cpeeks (char* s, unsigned length);
;
.include "c65.inc"
.export _cpeeks
.import popax
.importzp ptr1, ptr2, ptr3, tmp1, tmp2
.macpack generic
_cpeeks:
eor #<$FFFF ; counting a word upward is faster
sta ptr3 ; so, we use -(length + 1)
txa
eor #>$FFFF
sta ptr3+1
lda SCREEN_PTR
sta ptr2
lda SCREEN_PTR+1
clc
adc #>$0800
sta ptr2+1
ldy CURS_X
sty tmp2
jsr popax
sta tmp1 ; (will be a .Y index)
stx ptr1+1
ldx #<$0000
stx ptr1
bze L3 ; branch always
L4: ldy tmp2
lda (ptr2),y ; get char
iny
bnz L2
inc ptr2+1
L2: sty tmp2
and #<~$80 ; remove reverse bit
; Convert the screen code into a PetSCII code.
; $00 - $1F: +$40
; $20 - $3F
; $40 - $5f: +$20
; $60 - $7F: +$40
cmp #$20
blt @sk1 ;(bcc)
cmp #$40
blt L5
cmp #$60
blt @sk2 ;(bcc)
clc
@sk1: adc #$20
@sk2: ;clc ; both above cmp and adc clear carry flag
adc #$20
L5: ldy tmp1
sta (ptr1),y
iny
bnz L1
inc ptr1+1
L1: sty tmp1
L3: inc ptr3 ; count length
bnz L4
inc ptr3+1
bnz L4
txa ; terminate the string
ldy tmp1
sta (ptr1),y
rts

120
libsrc/mega65/cputc.s Normal file
View File

@@ -0,0 +1,120 @@
;
; Ullrich von Bassewitz, 1998-08-06, 2009-09-26
;
; void __fastcall__ cputcxy (unsigned char x, unsigned char y, char c);
; void __fastcall__ cputc (char c);
;
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
.import gotoxy
.import PLOT
.importzp ptr4
.include "mega65.inc"
_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
; Printable char of some sort
cmp #' '
bcc cputdirect ; Other control char
tay
bmi L10
cmp #$60
bcc L2
and #$DF
bne cputdirect ; Branch always
L2: and #$3F
cputdirect:
jsr putchar ; Write the character to the screen
; Advance cursor position
advance:
iny
cpy #XSIZE
bne L3
jsr newline ; new line
ldy #0 ; + cr
L3: sty CURS_X
rts
newline:
clc
lda #XSIZE
adc SCREEN_PTR
sta SCREEN_PTR
bcc L4
inc SCREEN_PTR+1
clc
L4: lda #XSIZE
adc CRAM_PTR
sta CRAM_PTR
bcc L5
inc CRAM_PTR+1
L5: inc CURS_Y
rts
; Handle character if high bit set
L10: and #$7F
cmp #$7F ; PI?
bne L11
lda #$5E ; Load screen code for PI
L11: ora #$40
bne cputdirect
; Set cursor position, calculate RAM pointers.
plot: ldy CURS_X
ldx CURS_Y
clc
jmp PLOT ; Set the new cursor
; Write one character to the screen without doing anything else, return X
; position in Y
putchar:
ora RVS ; Set revers bit
tay
lda SCREEN_PTR + 1
clc
adc #>$0800
sta ptr4 + 1
lda SCREEN_PTR
sta ptr4
tya
ldy CURS_X
sta (ptr4),y ; Set char
lda ptr4 + 1
clc
adc #>$d000
sta ptr4 + 1
lda CHARCOLOR
sta (ptr4),y ; Set color
rts

123
libsrc/mega65/crt0.s Normal file
View File

@@ -0,0 +1,123 @@
;
; Startup code for cc65 (MEGA65 version)
;
.export _exit
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import zerobss, callmain
.import BSOUT
.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated
.import __STACKSIZE__ ; from configure file
.include "zeropage.inc"
.include "mega65.inc"
; ------------------------------------------------------------------------
; Startup code
.segment "STARTUP"
Start:
; Switch off the BASIC ROM.
; FIXME
; lda $01
; sta mmusave ; Save the memory configuration
; and #$F8
; ora #$06 ; Enable Kernal+I/O, disable BASIC
; sta $01
; sei
; lda #%00000000 ; lower offset 15-8
; ldx #%00000000 ; map blk3-1 | lower offset 19-6
; ldy #%00000000 ; upper offset 15-8
; ldz #%00000000 ; map blk7-4 | upper offset 19-6
; map
; eom
tsx
stx spsave ; Save the system stack ptr
; Save space by putting some of the start-up code in the ONCE segment,
; which can be re-used by the BSS segment, the heap and the C stack.
jsr init
; Clear the BSS data.
jsr zerobss
; Push the command-line arguments; and, call main().
jsr callmain
; Back from main() [this is also the exit() entry]. Run the module destructors.
_exit: pha ; Save the return code on stack
jsr donelib
; Copy back the zero-page stuff.
ldx #zpspace-1
L2: lda zpsave,x
sta c_sp,x
dex
bpl L2
; Place the program return code into BASIC's status variable.
pla
sta STATUS
; Restore the system stuff.
ldx spsave
txs ; Restore stack pointer
; Back to BASIC.
rts
; ------------------------------------------------------------------------
.segment "ONCE"
init:
; Save the zero-page locations that we need.
ldx #zpspace-1
L1: lda c_sp,x
sta zpsave,x
dex
bpl L1
; Set up the stack.
lda #<(__MAIN_START__ + __MAIN_SIZE__)
ldx #>(__MAIN_START__ + __MAIN_SIZE__)
sta c_sp
stx c_sp+1 ; Set argument stack ptr
; Switch to the second charset.
lda #14
jsr BSOUT
; Call the module constructors.
jmp initlib
; ------------------------------------------------------------------------
; Data
.segment "INIT"
mmusave:.res 1
spsave: .res 1
zpsave: .res zpspace

7
libsrc/mega65/devnum.s Normal file
View File

@@ -0,0 +1,7 @@
;
; Oliver Schmidt, 2010-02-14
;
.include "mega65.inc"
.exportzp devnum := DEVNUM

25
libsrc/mega65/get_tv.s Normal file
View File

@@ -0,0 +1,25 @@
;
; Ullrich von Bassewitz, 2002-12-03
;
; unsigned char get_tv (void);
; /* Return the video mode the machine is using */
;
.include "get_tv.inc"
.include "mega65.inc"
;--------------------------------------------------------------------------
; _get_tv
.proc _get_tv
ldx #TV::PAL ; Assume PAL
lda PALFLAG
bne pal
dex ; NTSC
pal: txa
ldx #0
rts
.endproc

83
libsrc/mega65/gettime.s Normal file
View File

@@ -0,0 +1,83 @@
;
; Stefan Haubenthal, 27.7.2009
; Oliver Schmidt, 14.8.2018
;
; int __fastcall__ clock_gettime (clockid_t clk_id, struct timespec *tp);
;
.include "time.inc"
.include "mega65.inc"
.importzp sreg, tmp1, tmp2
.import pushax, pusheax, tosmul0ax, steaxspidx, incsp1, return0
.import TM, load_tenth
;----------------------------------------------------------------------------
.code
.proc _clock_gettime
jsr pushax
jsr pushax
lda CIA1_TODHR
sed
tax ; Save PM flag
and #%01111111
cmp #$12 ; 12 AM/PM
bcc @L1
sbc #$12
@L1: inx ; Get PM flag
bpl @L2
clc
adc #$12
@L2: cld
jsr BCD2dec
sta TM + tm::tm_hour
lda CIA1_TODMIN
jsr BCD2dec
sta TM + tm::tm_min
lda CIA1_TODSEC
jsr BCD2dec
sta TM + tm::tm_sec
lda #<TM
ldx #>TM
jsr _mktime
ldy #timespec::tv_sec
jsr steaxspidx ; Pops address pushed by 2. pushax
jsr load_tenth
jsr pusheax
lda CIA1_TOD10
ldx #>$0000
jsr tosmul0ax
ldy #timespec::tv_nsec
jsr steaxspidx ; Pops address pushed by 1. pushax
jsr incsp1
jmp return0
.endproc
;----------------------------------------------------------------------------
; dec = (((BCD>>4)*10) + (BCD&0xf))
.proc BCD2dec
tax
and #%00001111
sta tmp1
txa
and #%11110000 ; *16
lsr ; *8
sta tmp2
lsr
lsr ; *2
adc tmp2 ; = *10
adc tmp1
rts
.endproc

View File

@@ -0,0 +1,111 @@
;
; Standard joystick driver for the C64. May be used multiple times when linked
; to the statically application.
;
; Ullrich von Bassewitz, 2002-12-20
;
.include "zeropage.inc"
.include "joy-kernel.inc"
.include "joy-error.inc"
.include "mega65.inc"
.macpack generic
.macpack module
; ------------------------------------------------------------------------
; Header. Includes jump table
module_header _mega65_stdjoy_joy
; Driver signature
.byte $6A, $6F, $79 ; "joy"
.byte JOY_API_VERSION ; Driver API version number
; Library reference
.addr $0000
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr COUNT
.addr READ
; ------------------------------------------------------------------------
; Constants
JOY_COUNT = 2 ; Number of joysticks we support
; ------------------------------------------------------------------------
; Data.
.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 JOY_ERR_xx code in a/x.
;
INSTALL:
lda #JOY_ERR_OK
.assert JOY_ERR_OK = 0, error
tax
; 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
; ------------------------------------------------------------------------
; COUNT: Return the total number of available joysticks in a/x.
;
COUNT:
lda #<JOY_COUNT
ldx #>JOY_COUNT
rts
; ------------------------------------------------------------------------
; READ: Read a particular joystick passed in A.
;
READ: tax ; Joystick number into X
bne joy2
; Read joystick 1
joy1: lda #$7F
sei
sta CIA1_PRA
lda CIA1_PRB
cli
jmp end
; Read joystick 2
joy2: ldx #0
lda #$E0
ldy #$FF
sei
sta CIA1_DDRA
lda CIA1_PRA
sty CIA1_DDRA
cli
end: and #$1F
eor #$1F
rts

View File

@@ -0,0 +1,14 @@
;
; Address of the static standard joystick driver
;
; Oliver Schmidt, 2012-11-01
;
; const void joy_static_stddrv[];
;
.export _joy_static_stddrv
.import _mega65_stdjoy_joy
.rodata
_joy_static_stddrv := _mega65_stdjoy_joy

View File

@@ -0,0 +1,14 @@
;
; Name of the standard joystick driver
;
; Ullrich von Bassewitz, 2002-12-21
;
; const char joy_stddrv[];
;
.export _joy_stddrv
.rodata
_joy_stddrv: .asciiz "m65-stdjoy.joy"

14
libsrc/mega65/kbhit.s Normal file
View File

@@ -0,0 +1,14 @@
; FIXME: is $d610 mega65 specific?
; FIXME: this should rather use the kernal (with keyboard buffer etc)
.export _kbhit
_kbhit:
lda $d610
beq :+
lda #1
:
ldx #>$0000
rts

47
libsrc/mega65/kernal.s Normal file
View File

@@ -0,0 +1,47 @@
;
; Ullrich von Bassewitz, 19.11.2002
;
; MEGA65 Kernal functions
;
.include "cbm_kernal.inc"
.export CINT
.export IOINIT
.export RAMTAS
.export RESTOR
.export VECTOR
.export SETMSG
.export SECOND
.export TKSA
.export MEMTOP
.export MEMBOT
.export SCNKEY
.export ACPTR
.export CIOUT
.export UNTLK
.export UNLSN
.export LISTEN
.export TALK
.export READST
.export SETLFS
.export SETNAM
.export OPEN
.export CLOSE
.export CHKIN
.export CKOUT
.export CLRCH
.export BASIN
.export CHRIN
.export BSOUT
.export CHROUT
.export LOAD
.export SAVE
.export SETTIM
.export RDTIM
.export STOP
.export GETIN
.export CLALL
.export SCREEN
.export IOBASE
.export PLOT

8
libsrc/mega65/libref.s Normal file
View File

@@ -0,0 +1,8 @@
;
; Oliver Schmidt, 2013-05-31
;
.export joy_libref
.import _exit
joy_libref := _exit

137
libsrc/mega65/mainargs.s Normal file
View File

@@ -0,0 +1,137 @@
; mainargs.s
;
; Ullrich von Bassewitz, 2003-03-07
; Based on code from Stefan A. Haubenthal, <polluks@web.de>
; 2003-05-18, Greg King
; 2004-04-28, 2005-02-26, Ullrich von Bassewitz
;
; Scan a group of arguments that are in BASIC's input-buffer.
; Build an array that points to the beginning of each argument.
; Send, to main(), that array and the count of the arguments.
;
; Command-lines look like these lines:
;
; run
; run : rem
; run:rem arg1 " arg 2 is quoted " arg3 "" arg5
;
; "run" and "rem" are entokenned; the args. are not. Leading and trailing
; spaces outside of quotes are ignored.
;
; TO-DO:
; - The "file-name" might be a path-name; don't copy the directory-components.
; - Add a control-character quoting mechanism.
.constructor initmainargs, 24
.import __argc, __argv
.include "mega65.inc"
MAXARGS = 10 ; Maximum number of arguments allowed
REM = $8f ; BASIC token-code
NAME_LEN = 16 ; Maximum length of command-name
; Get possible command-line arguments. Goes into the special ONCE segment,
; which may be reused after the startup code is run
.segment "ONCE"
initmainargs:
; Assume that the program was loaded, a moment ago, by the traditional LOAD
; statement. Save the "most-recent filename" as argument #0.
lda #0 ; The terminating NUL character
ldy FNAM_LEN
cpy #NAME_LEN + 1
bcc L1
ldy #NAME_LEN ; Limit the length
bne L1 ; Branch always
L0: lda (FNAM),y
L1: sta name,y
dey
bpl L0
inc __argc ; argc always is equal to, at least, 1
; Find the "rem" token.
ldx #0
L2: lda BASIC_BUF,x
beq done ; No "rem," no args.
inx
cmp #REM
bne L2
ldy #1 * 2
; Find the next argument
next: lda BASIC_BUF,x
beq done ; End of line reached
inx
cmp #' ' ; Skip leading spaces
beq next
; Found start of next argument. We've incremented the pointer in X already, so
; it points to the second character of the argument. This is useful since we
; will check now for a quoted argument, in which case we will have to skip this
; first character.
found: cmp #'"' ; Is the argument quoted?
beq setterm ; Jump if so
dex ; Reset pointer to first argument character
lda #' ' ; A space ends the argument
setterm:sta term ; Set end of argument marker
; Now store a pointer to the argument into the next slot. Since the BASIC
; input buffer is located at the start of a RAM page, no calculations are
; necessary.
txa ; Get low byte
sta argv,y ; argv[y]= &arg
iny
lda #>BASIC_BUF
sta argv,y
iny
inc __argc ; Found another arg
; Search for the end of the argument
argloop:lda BASIC_BUF,x
beq done
inx
cmp term
bne argloop
; We've found the end of the argument. X points one character behind it, and
; A contains the terminating character. To make the argument a valid C string,
; replace the terminating character by a zero.
lda #0
sta BASIC_BUF-1,x
; Check if the maximum number of command line arguments is reached. If not,
; parse the next one.
lda __argc ; Get low byte of argument count
cmp #MAXARGS ; Maximum number of arguments reached?
bcc next ; Parse next one if not
; (The last vector in argv[] already is NULL.)
done: lda #<argv
ldx #>argv
sta __argv
stx __argv + 1
rts
.segment "INIT"
term: .res 1
name: .res NAME_LEN + 1
.data
; char* argv[MAXARGS+1]={name};
argv: .addr name
.res MAXARGS * 2

18
libsrc/mega65/randomize.s Normal file
View File

@@ -0,0 +1,18 @@
;
; 2002-11-05, Ullrich von Bassewitz
; 2015-09-11, Greg King
;
; void __randomize (void);
; /* Initialize the random number generator */
;
.export ___randomize
.import _srand
.include "mega65.inc"
___randomize:
ldx VIC_HLINE ; Use VIC rasterline as high byte
lda TIME+2 ; Use 60HZ clock as low byte
jmp _srand ; Initialize generator

27
libsrc/mega65/revers.s Normal file
View File

@@ -0,0 +1,27 @@
;
; Ullrich von Bassewitz, 07.08.1998
;
; unsigned char revers (unsigned char onoff);
;
.export _revers
.include "mega65.inc"
.proc _revers
ldx #$00 ; Assume revers off
tay ; Test onoff
beq L1 ; Jump if off
ldx #$80 ; Load on value
ldy #$00 ; Assume old value is zero
L1: lda RVS ; Load old value
stx RVS ; Set new value
beq L2 ; Jump if old value zero
iny ; Make old value = 1
L2: ldx #$00 ; Load high byte of result
tya ; Load low byte, set CC
rts
.endproc

84
libsrc/mega65/settime.s Normal file
View File

@@ -0,0 +1,84 @@
;
; Oliver Schmidt, 16.8.2018
;
; int __fastcall__ clock_settime (clockid_t clk_id, const struct timespec *tp);
;
.include "time.inc"
.include "mega65.inc"
.importzp sreg, ptr1
.import pushax, pusheax, ldax0sp, ldeaxidx
.import tosdiveax, incsp3, return0
.import TM, load_tenth
;----------------------------------------------------------------------------
.code
.proc _clock_settime
jsr pushax
.assert timespec::tv_sec = 0, error
jsr _localtime
sta ptr1
stx ptr1+1
ldy #.sizeof(tm)-1
@L1: lda (ptr1),y
sta TM,y
dey
bpl @L1
lda TM + tm::tm_hour
jsr dec2BCD
tax ; Force flags
bne @L2
lda #$92 ; 12 AM
bne @L3
@L2: cmp #$13 ; 1 PM
bcc @L3
sed
sbc #$12
cld
ora #%10000000
@L3: sta CIA1_TODHR
lda TM + tm::tm_min
jsr dec2BCD
sta CIA1_TODMIN
lda TM + tm::tm_sec
jsr dec2BCD
sta CIA1_TODSEC
jsr ldax0sp
ldy #3+timespec::tv_nsec
jsr ldeaxidx
jsr pusheax
jsr load_tenth
jsr tosdiveax
sta CIA1_TOD10
jsr incsp3
jmp return0
.endproc
;----------------------------------------------------------------------------
; Just sum up the value in BCD mode.
; http://forum.6502.org/viewtopic.php?p=7629#p7629
.proc dec2BCD
tax
dex
bmi @L9
lda #0
clc
sed
@L1: adc #1
dex
bpl @L1
cld
@L9: rts
.endproc

5
libsrc/mega65/status.s Normal file
View File

@@ -0,0 +1,5 @@
;
; Oliver Schmidt, 2012-09-30
;
.exportzp ST := $90 ; IEC status byte

37
libsrc/mega65/sysuname.s Normal file
View File

@@ -0,0 +1,37 @@
;
; Ullrich von Bassewitz, 2003-08-12
;
; unsigned char __fastcall__ _sysuname (struct utsname* buf);
;
.export __sysuname, utsdata
.import utscopy
__sysuname = utscopy
;--------------------------------------------------------------------------
; Data. We define a fixed utsname struct here and just copy it.
.rodata
utsdata:
; sysname
.asciiz "cc65"
; nodename
.asciiz ""
; release
.byte .string (>.version)
.byte '.'
.byte .string (<.version)
.byte $00
; version
.byte '0' ; unused
.byte $00
; machine
.asciiz "MEGA65"

64
libsrc/mega65/tmcommon.s Normal file
View File

@@ -0,0 +1,64 @@
;
; Oliver Schmidt, 16.8.2018
;
; Common stuff for the clock routines
;
.include "c65.inc"
.include "get_tv.inc"
.export TM, load_tenth
.constructor inittime
.importzp sreg
.import _get_tv
;----------------------------------------------------------------------------
.code
.proc load_tenth
lda #<(100 * 1000 * 1000 / $10000)
ldx #>(100 * 1000 * 1000 / $10000)
sta sreg
stx sreg+1
lda #<(100 * 1000 * 1000)
ldx #>(100 * 1000 * 1000)
rts
.endproc
;----------------------------------------------------------------------------
; Constructor that writes to the 1/10 sec register of the TOD to kick it
; into action. If this is not done, the clock hangs. We will read the register
; and write it again, ignoring a possible change in between.
.segment "ONCE"
.proc inittime
lda CIA1_TOD10
sta CIA1_TOD10
jsr _get_tv
cmp #TV::PAL
bne @60Hz
lda CIA1_CRA
ora #$80
sta CIA1_CRA
@60Hz: rts
.endproc
;----------------------------------------------------------------------------
; TM struct with date set to 1970-01-01
.data
TM: .word 0 ; tm_sec
.word 0 ; tm_min
.word 0 ; tm_hour
.word 1 ; tm_mday
.word 0 ; tm_mon
.word 70 ; tm_year
.word 0 ; tm_wday
.word 0 ; tm_yday
.word 0 ; tm_isdst

View File

@@ -84,10 +84,12 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),)
EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*) EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*)
MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*) MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*)
TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*) TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*)
JOY := $(wildcard $(TARGET_PATH)/$(SYS)/drv/joy/*)
EMD := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/emd/,$(notdir $(filter %.emd,$(EMD)))) EMD := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/emd/,$(notdir $(filter %.emd,$(EMD))))
MOU := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/mou/,$(notdir $(filter %.mou,$(MOU)))) MOU := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/mou/,$(notdir $(filter %.mou,$(MOU))))
TGI := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/tgi/,$(notdir $(filter %.tgi,$(TGI)))) TGI := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/tgi/,$(notdir $(filter %.tgi,$(TGI))))
JOY := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/joy/,$(notdir $(filter %.joy,$(JOY))))
# This one comes with the VICE emulator. # This one comes with the VICE emulator.
# See http://vice-emu.sourceforge.net/ # See http://vice-emu.sourceforge.net/
@@ -106,6 +108,8 @@ DISK_apple2enh = samples.dsk
DISK_atari = samples.atr DISK_atari = samples.atr
DISK_atarixl = samples.atr DISK_atarixl = samples.atr
DISK_plus4 = samples.d64 DISK_plus4 = samples.d64
DISK_c65 = samples.d81
DISK_mega65 = samples.d81
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# System-dependent settings # System-dependent settings
@@ -180,6 +184,7 @@ EXELIST_apple2 = \
enumdevdir \ enumdevdir \
gunzip65 \ gunzip65 \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
mousedemo \ mousedemo \
multdemo \ multdemo \
@@ -220,6 +225,7 @@ EXELIST_atmos = \
ascii \ ascii \
checkversion \ checkversion \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
sieve \ sieve \
terminal \ terminal \
@@ -234,6 +240,7 @@ EXELIST_c64 = \
enumdevdir \ enumdevdir \
gunzip65 \ gunzip65 \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
mousedemo \ mousedemo \
multdemo \ multdemo \
@@ -243,12 +250,22 @@ EXELIST_c64 = \
tinyshell \ tinyshell \
tgidemo tgidemo
EXELIST_c65 = \
ascii \
checkversion \
enumdevdir \
hello \
joydemo \
sieve \
tinyshell
EXELIST_c128 = \ EXELIST_c128 = \
ascii \ ascii \
checkversion \ checkversion \
enumdevdir \ enumdevdir \
gunzip65 \ gunzip65 \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
mousedemo \ mousedemo \
sieve \ sieve \
@@ -261,13 +278,15 @@ EXELIST_c16 = \
checkversion \ checkversion \
enumdevdir \ enumdevdir \
tinyshell \ tinyshell \
hello hello \
joydemo
EXELIST_cbm510 = \ EXELIST_cbm510 = \
ascii \ ascii \
checkversion \ checkversion \
gunzip65 \ gunzip65 \
hello \ hello \
joydemo \
mousedemo \ mousedemo \
terminal \ terminal \
tinyshell \ tinyshell \
@@ -292,6 +311,7 @@ EXELIST_cx16 = \
enumdevdir \ enumdevdir \
gunzip65 \ gunzip65 \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
mousedemo \ mousedemo \
sieve \ sieve \
@@ -313,20 +333,32 @@ EXELIST_lunix = \
EXELIST_lynx = \ EXELIST_lynx = \
notavailable notavailable
EXELIST_mega65 = \
ascii \
checkversion \
enumdevdir \
hello \
joydemo \
sieve \
tinyshell
EXELIST_nes = \ EXELIST_nes = \
hello hello \
joydemo
EXELIST_osic1p = \ EXELIST_osic1p = \
notavailable notavailable
EXELIST_pce = \ EXELIST_pce = \
hello hello \
joydemo
EXELIST_pet = \ EXELIST_pet = \
ascii \ ascii \
checkversion \ checkversion \
enumdevdir \ enumdevdir \
hello \ hello \
joydemo \
tinyshell \ tinyshell \
sieve sieve
@@ -336,6 +368,7 @@ EXELIST_plus4 = \
enumdevdir \ enumdevdir \
gunzip65 \ gunzip65 \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
terminal \ terminal \
tinyshell \ tinyshell \
@@ -365,6 +398,7 @@ EXELIST_telestrat = \
checkversion \ checkversion \
gunzip65 \ gunzip65 \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
sieve \ sieve \
tgidemo tgidemo
@@ -374,6 +408,7 @@ EXELIST_vic20 = \
checkversion \ checkversion \
enumdevdir \ enumdevdir \
hello \ hello \
joydemo \
mandelbrot \ mandelbrot \
sieve \ sieve \
tgidemo tgidemo
@@ -423,6 +458,7 @@ TARGETS := \
c128 \ c128 \
c16 \ c16 \
c64 \ c64 \
c65 \
cbm510 \ cbm510 \
cbm610 \ cbm610 \
creativision \ creativision \
@@ -433,6 +469,7 @@ TARGETS := \
kim1 \ kim1 \
lunix \ lunix \
lynx \ lynx \
mega65 \
nes \ nes \
osic1p \ osic1p \
pce \ pce \
@@ -533,7 +570,13 @@ samples.d64: samples
@$(C1541) -format "samples,00" d64 $@ >$(NULLDEV) @$(C1541) -format "samples,00" d64 $@ >$(NULLDEV)
$(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe)) $(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe))
$(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe)) $(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe))
$(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_SEQ_recipe)) $(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(D64_WRITE_SEQ_recipe))
samples.d81: samples
@$(C1541) -format "samples,00" d81 $@ >$(NULLDEV)
$(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe))
$(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe))
$(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(D64_WRITE_SEQ_recipe))
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Rule to make an Apple II disk with all samples. Needs the AppleCommander # Rule to make an Apple II disk with all samples. Needs the AppleCommander
@@ -558,7 +601,7 @@ samples.dsk: samples
cp prodos.dsk $@ cp prodos.dsk $@
$(foreach file,$(EXELIST_$(SYS)),$(DSK_WRITE_BIN_recipe)) $(foreach file,$(EXELIST_$(SYS)),$(DSK_WRITE_BIN_recipe))
$(foreach file,$(OVERLAYLIST),$(DSK_WRITE_REL_recipe)) $(foreach file,$(OVERLAYLIST),$(DSK_WRITE_REL_recipe))
$(foreach file,$(EMD) $(MOU) $(TGI),$(DSK_WRITE_REL_recipe)) $(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(DSK_WRITE_REL_recipe))
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------
# Rule to make an Atari disk with all samples. Needs the dir2atr program # Rule to make an Atari disk with all samples. Needs the dir2atr program
@@ -577,7 +620,7 @@ samples.atr: samples
cp "dup.sys" atr/dup.sys cp "dup.sys" atr/dup.sys
@$(foreach file,$(EXELIST_$(SYS)),$(ATR_WRITE_recipe)) @$(foreach file,$(EXELIST_$(SYS)),$(ATR_WRITE_recipe))
@$(foreach file,$(OVERLAYLIST),$(ATR_WRITE_recipe)) @$(foreach file,$(OVERLAYLIST),$(ATR_WRITE_recipe))
@$(foreach file,$(EMD) $(MOU) $(TGI),$(ATR_WRITE_recipe)) @$(foreach file,$(EMD) $(MOU) $(JOY) $(TGI),$(ATR_WRITE_recipe))
$(DIR2ATR) -d -b MyDos4534 3200 $@ atr $(DIR2ATR) -d -b MyDos4534 3200 $@ atr
@$(RMDIR) atr @$(RMDIR) atr

View File

@@ -43,10 +43,12 @@ int main(void)
printf("__CC65__ defined as %04x\n", __CC65__); printf("__CC65__ defined as %04x\n", __CC65__);
printf("compiler version is %u.%u\n", VER_MAJOR, VER_MINOR); printf("compiler version is %u.%u\n", VER_MAJOR, VER_MINOR);
#pragma warn (const-comparison, push, off)
if (__CC65__ == VERSION) { if (__CC65__ == VERSION) {
printf("__CC65__ is defined correctly as (VER_MAJOR * 0x100) + VER_MINOR\n"); printf("__CC65__ is defined correctly as (VER_MAJOR * 0x100) + VER_MINOR\n");
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
#pragma warn (const-comparison, pop)
printf("__CC65__ is incorrectly defined as (VER_MAJOR * 0x100) + (VER_MINOR * 0x10)\n"); printf("__CC65__ is incorrectly defined as (VER_MAJOR * 0x100) + (VER_MINOR * 0x10)\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }

96
samples/joydemo.c Normal file
View File

@@ -0,0 +1,96 @@
#include <stdlib.h>
#include <stdio.h>
#include <joystick.h>
/* define 0 to link the standard driver statically */
/* #define DYN_DRV 0 */
#ifndef DYN_DRV
# define DYN_DRV 1
#endif
#define USECONIO
#ifdef USECONIO
#include <conio.h>
#define PRINTF cprintf
#define CR "\n\r"
#else
#define PRINTF printf
#define CR "\n"
#endif
int main (void)
{
unsigned char num_joy;
unsigned char raw_value;
unsigned char i;
#if DYN_DRV
unsigned char err;
#endif
#ifdef USECONIO
unsigned char y;
clrscr();
#endif
PRINTF("Driver init..." CR);
#if DYN_DRV
/* Load and initialize the standard driver driver */
if ((err = joy_load_driver (joy_stddrv))) {
PRINTF ("Driver load error (code %d)." CR
"Warning: This program needs the JOY" CR
"driver on disk!" CR, err);
exit (EXIT_FAILURE);
}
PRINTF("Driver loaded OK" CR);
#else
/* Install the standard driver */
joy_install (joy_static_stddrv);
#endif
num_joy = joy_count();
PRINTF("Driver reported %d joysticks." CR "waiting for input..." CR, num_joy);
/* wait for something to happen on any joystick input */
{
unsigned char wait = 1;
while (wait) {
for (i = 0; i < num_joy; ++i) {
raw_value = joy_read(i);
if (raw_value) {
wait = 0;
break;
}
}
}
}
/* read all joysticks and print the raw value(s) */
#ifdef USECONIO
y = wherey();
#endif
while (1) {
#ifdef USECONIO
gotoxy(0, y);
#endif
for (i = 0; i < num_joy; ++i) {
raw_value = joy_read(i);
PRINTF("%02x ", raw_value);
}
PRINTF(CR);
}
#if DYN_DRV
/* Unload the driver */
joy_unload ();
#else
/* Uninstall the driver */
joy_uninstall ();
#endif
/* Done */
PRINTF ("Done" CR);
return EXIT_SUCCESS;
}

View File

@@ -66,20 +66,26 @@ const char* CPUNames[CPU_COUNT] = {
"45GS02" "45GS02"
}; };
/* Tables with CPU instruction sets */ /* Tables with CPU instruction sets
* NOTE: make sure to only combine the instruction sets that are 100% compatible
*/
const unsigned CPUIsets[CPU_COUNT] = { const unsigned CPUIsets[CPU_COUNT] = {
CPU_ISET_NONE, CPU_ISET_NONE,
CPU_ISET_6502, CPU_ISET_6502,
CPU_ISET_6502 | CPU_ISET_6502X, CPU_ISET_6502X | CPU_ISET_6502,
CPU_ISET_6502 | CPU_ISET_6502DTV, CPU_ISET_6502DTV | CPU_ISET_6502,
CPU_ISET_6502 | CPU_ISET_65SC02, CPU_ISET_65SC02 | CPU_ISET_6502,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02, CPU_ISET_65C02 | CPU_ISET_6502 | CPU_ISET_65SC02,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_65816, /* FIXME: does 65816 have both wai/stp and indirect-zp (without z)? */
CPU_ISET_65816 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02,
CPU_ISET_SWEET16, CPU_ISET_SWEET16,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_HUC6280, /* FIXME: HUC6280 does not have wai/stp */
CPU_ISET_6502 | CPU_ISET_M740, CPU_ISET_HUC6280 | CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510, CPU_ISET_M740 | CPU_ISET_6502,
CPU_ISET_6502 | CPU_ISET_65SC02 | CPU_ISET_65C02 | CPU_ISET_4510 | CPU_ISET_45GS02, /* 4510 does NOT have indirect-zp (without z), so we can not use 65SC02 */
/* FIXME: 4510 does not have wai/stp */
CPU_ISET_4510 | CPU_ISET_6502 | CPU_ISET_65C02,
CPU_ISET_45GS02 | CPU_ISET_6502 | CPU_ISET_65C02 | CPU_ISET_4510,
}; };

View File

@@ -47,7 +47,7 @@
/* CPUs */ /* CPUs */
typedef enum { typedef enum {
CPU_UNKNOWN = -1, /* Not specified or invalid target */ CPU_UNKNOWN = -1, /* Not specified or invalid target */
CPU_NONE, /* No CPU - for assembler */ CPU_NONE = 0, /* No CPU - for assembler */
CPU_6502, CPU_6502,
CPU_6502X, /* "Extended", that is: with illegal opcodes */ CPU_6502X, /* "Extended", that is: with illegal opcodes */
CPU_6502DTV, /* CPU_6502 + DTV extra and illegal opcodes */ CPU_6502DTV, /* CPU_6502 + DTV extra and illegal opcodes */
@@ -62,7 +62,7 @@ typedef enum {
CPU_COUNT /* Number of different CPUs */ CPU_COUNT /* Number of different CPUs */
} cpu_t; } cpu_t;
/* CPU instruction sets */ /* CPU instruction sets (make sure this matches asminc/cpu.mac) */
enum { enum {
CPU_ISET_NONE = 1 << CPU_NONE, CPU_ISET_NONE = 1 << CPU_NONE,
CPU_ISET_6502 = 1 << CPU_6502, CPU_ISET_6502 = 1 << CPU_6502,

View File

@@ -608,6 +608,64 @@ EXELIST_cx16 = \
strqtok-test \ strqtok-test \
uname-test uname-test
# omitted: deb em-test joy-test mouse-test ser-test seek
EXELIST_c65 = \
arg-test \
clock \
clock-test \
conio \
cpeek-test \
cprintf \
cursor \
dir-test \
div-test \
exec-test1 \
exec-test2 \
fileio-test \
ft \
getopt-test \
heaptest \
moddiv-test \
mul-test \
posixio-test \
rename-test \
scanf-test \
strdup-test \
strnlen \
stroserror-test \
strqtok-test \
uname-test \
minimal
# omitted: deb em-test joy-test mouse-test ser-test seek
EXELIST_mega65 = \
arg-test \
clock \
clock-test \
conio \
cpeek-test \
cprintf \
cursor \
dir-test \
div-test \
exec-test1 \
exec-test2 \
fileio-test \
ft \
getopt-test \
heaptest \
moddiv-test \
mul-test \
posixio-test \
rename-test \
scanf-test \
strdup-test \
strnlen \
stroserror-test \
strqtok-test \
uname-test \
minimal
# omitted: arg-test clock-test clock cpeek-test cprintf cursor deb dir-test div-test # omitted: arg-test clock-test clock cpeek-test cprintf cursor deb dir-test div-test
# em-test exec-test1 exec-test2 fileio-test ft getopt-test heaptest joy-test moddiv-test # em-test exec-test1 exec-test2 fileio-test ft getopt-test heaptest joy-test moddiv-test
# mouse-test mul-test posixio-test rename-test scanf-test seek ser-test strdup-test # mouse-test mul-test posixio-test rename-test scanf-test seek ser-test strdup-test
@@ -756,6 +814,7 @@ TARGETS := \
c128 \ c128 \
c16 \ c16 \
c64 \ c64 \
c65 \
cbm510 \ cbm510 \
cbm610 \ cbm610 \
creativision \ creativision \
@@ -764,6 +823,7 @@ TARGETS := \
kim1 \ kim1 \
lunix \ lunix \
lynx \ lynx \
mega65 \
nes \ nes \
osic1p \ osic1p \
pce \ pce \

View File

@@ -24,6 +24,10 @@
# define SCREEN_RAM ((unsigned char*)0x8000) # define SCREEN_RAM ((unsigned char*)0x8000)
#elif defined(__VIC20__) #elif defined(__VIC20__)
# define SCREEN_RAM ((unsigned char*)0x1000) # define SCREEN_RAM ((unsigned char*)0x1000)
#elif defined(__C65__)
# define SCREEN_RAM ((unsigned char*)0x0800)
#elif defined(__MEGA65__)
# define SCREEN_RAM ((unsigned char*)0x0800)
#else #else
# error This program cannot test that target. # error This program cannot test that target.
# define SCREEN_RAM ((unsigned char*)0) # define SCREEN_RAM ((unsigned char*)0)