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

View File

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