Merge branch 'master' into rremd

This commit is contained in:
Bob Andrews
2021-12-11 22:36:12 +01:00
committed by GitHub
1834 changed files with 95693 additions and 35139 deletions

View File

@@ -0,0 +1,5 @@
;
; Marco van den Heuvel, 2018-04-23
;
.include "../c128/acc_c128_speed.s"

View File

@@ -0,0 +1,64 @@
;
; Marco van den Heuvel, 2018-04-14
;
; unsigned char __fastcall__ set_c64dtv_speed (unsigned char speed);
;
;/* Set the speed of the C64DTV, using SPEED_SLOW will switch to
; * slow mode, SPEED_2X or SPEED_FAST will switch to fast mode.
; *
; * Note that any value higher or equal to SPEED_2X will switch to fast mode.
; *
; * This function will return the actual speed the CPU is at after trying
; * to set the requested speed, to my knowledge the switching should not fail.
; *
; * This function does not check for the presence of the C64DTV,
; * make sure you use 'detect_c64dtv();' before using.
; */
; unsigned char get_c64dtv_speed (void);
;
;/* Get the speed of the C64DTV.
; *
; * Possible return values:
; * SPEED_1X : slow mode
; * SPEED_2X : fast mode
; *
; * This function does not check for the presence of the C64DTV,
; * make sure you use 'detect_c64dtv();' before using.
; */
.export _set_c64dtv_speed
.export _get_c64dtv_speed
.include "accelerator.inc"
_set_c64dtv_speed:
cmp #SPEED_2X
bcs high_speed
low_speed:
ldx #C64DTV_Slow
set_speed:
.byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control)
txa ; (re)set skip and burst bits
.byte $32,$00 ; SAC #$00 set accumulator back to reg 0
jmp _get_c64dtv_speed
high_speed:
ldx #C64DTV_Fast
bne set_speed
_get_c64dtv_speed:
.byte $32,$99 ; SAC #$99 set accumulator to reg 9 (cpu control)
tax
.byte $32,$00 ; SAC #$00 set accumulator back to reg 0
txa
and #C64DTV_Fast
bne in_fast_mode
lda #$00
.byte $2C
in_fast_mode:
lda #$01
ldx #$00
rts

View File

@@ -0,0 +1,69 @@
;
; Marco van den Heuvel, 2018-04-27
;
; unsigned char __fastcall__ set_c65_speed (unsigned char speed);
;
;/* Set the speed of the C65 CPU, using SPEED_SLOW will switch to
; * 1 Mhz mode, SPEED_3X or SPEED_FAST will switch to 3.5 Mhz (fast) mode.
; *
; * Note that any value higher or equal to SPEED_3X will switch to fast mode.
; *
; * This function will return the actual speed the CPU is at after trying
; * to set the requested speed, to my knowledge the switching should not fail.
; *
; * This function does not check for the presence of a C65/C64DX in C64 mode,
; * make sure you use 'detect_c65();' before using.
; */
; unsigned char get_c65_speed (void);
;
;/* Get the speed of the C65 CPU.
; *
; * Possible return values:
; * SPEED_SLOW : 1 Mhz mode
; * SPEED_3X : 3.5 Mhz mode
; *
; * This function does not check for the presence of a C65/C64DX in C64 mode,
; * make sure you use 'detect_c65();' before using.
; */
.export _set_c65_speed
.export _get_c65_speed
.include "accelerator.inc"
_set_c65_speed:
tay
jsr activate_new_vic_mode
cpy #SPEED_3X
bcs high_speed
low_speed:
and #$BF
store_speed:
sta C65_VICIII_CTRL_B
lda C65_VICIII_CTRL_B
jmp return_c65_speed
high_speed:
ora #$40
bne store_speed
_get_c65_speed:
jsr activate_new_vic_mode
return_c65_speed:
sta C65_VICIII_KEY
and #$40
beq speed_is_slow ; when this branch is taken then register A is already set to SPEED_SLOW
lda #SPEED_3X
speed_is_slow:
ldx #$00
rts
activate_new_vic_mode:
lda #C65_VICIII_UNLOCK_1
sta C65_VICIII_KEY
lda #C65_VICIII_UNLOCK_2
sta C65_VICIII_KEY
lda C65_VICIII_CTRL_B
rts

View File

@@ -0,0 +1,100 @@
;
; Marco van den Heuvel, 2018-04-25
;
; unsigned char __fastcall__ set_chameleon_speed (unsigned char speed);
;
;/* Set the speed of the Chameleon cartridge, the following inputs
; * are accepted:
; * SPEED_SLOW : 1 Mhz mode
; * SPEED_1X : 1 Mhz mode
; * SPEED_2X : 2 Mhz mode
; * SPEED_3X : 3 Mhz mode
; * SPEED_4X : 4 Mhz mode
; * SPEED_5X : 5 Mhz mode
; * SPEED_6X : 6 Mhz mode
; * SPEED_FAST : Maximum speed mode
; *
; * Note that any value higher or equal to SPEED_7X will switch to maximum
; * speed mode.
; *
; * This function will return the actual speed the CPU is at after trying
; * to set the requested speed, to my knowledge the switching should not fail.
; *
; * This function does not check for the presence of the Chameleon cartridge,
; * make sure you use 'detect_chameleon();' before using.
; */
; unsigned char get_chameleon_speed (void);
;
;/* Get the speed of the Chameleon cartridge.
; *
; * Possible return values:
; * SPEED_SLOW : Slow mode
; * SPEED_2X : 2Mhz mode
; * SPEED_3X : 3Mhz mode
; * SPEED_4X : 4Mhz mode
; * SPEED_5X : 5Mhz mode
; * SPEED_6X : 6Mhz mode
; * SPEED_FAST : Maximum speed mode
; *
; * This function does not check for the presence of the Chameleon cartridge,
; * make sure you use 'detect_chameleon();' before using.
; */
.export _set_chameleon_speed
.export _get_chameleon_speed
.include "accelerator.inc"
_set_chameleon_speed:
cmp #SPEED_7X
bcs maximum_speed
cmp #SPEED_1X
beq low_speed
ora #$80
set_speed:
jsr activate_regs
sta CHAMELEON_CFGTUR
jmp return_speed
low_speed:
lda #CHAMELEON_CFGTUR_LIMIT_1MHZ
bne set_speed
maximum_speed:
lda #CHAMELEON_CFGTUR_LIMIT_NONE
bne set_speed
_get_chameleon_speed:
jsr activate_regs
return_speed:
ldx #$00
lda CHAMELEON_CFGTUR
tay
and #%10000000
beq return_value
tya
and #%00001000
bne is_slow_mode
tya
and #%00000111
beq is_max_mode
return_value:
ldy #CHAMELEON_DISABLE_REGS
sty CHAMELEON_CFGENA
rts
is_slow_mode:
txa
bne return_value
is_max_mode:
lda #SPEED_FAST
bne return_value
activate_regs:
ldy #CHAMELEON_ENABLE_REGS
sty CHAMELEON_CFGENA
rts

View File

@@ -0,0 +1,33 @@
;
; 2018-04-20, Marco van den Heuvel
; 2018-04-26, Greg King
;
; unsigned char detect_c128 (void);
;
;/* Check for the presence of a C128 in C64 mode.
; *
; * Possible return values:
; * 0x00 : C128 in C64 mode not present
; * 0x01 : C128 in C64 mode present
; */
.export _detect_c128
.include "accelerator.inc"
_detect_c128:
ldx #>$0001
lda #<$0001
; Make sure the CPU is an 8502.
.byte $3A ; NOP on 8502, DEA on 65(S)C(E)02, 4510, and 65816
beq detect_end
; Make sure a C128 VIC-IIe is present.
ldy C128_VICIIE_CLK
cpy #$FF
bne detect_end
txa ; return zero when not VIC-IIe
detect_end:
rts

View File

@@ -0,0 +1,44 @@
;
; Marco van den Heuvel, 2018-04-14
;
; unsigned char detect_c64dtv (void);
;
;/* Check for the presence of the C64DTV.
; *
; * Possible return values:
; * 0x00 : C64DTV not present
; * 0x01 : C64DTV present
; */
.export _detect_c64dtv
.include "accelerator.inc"
_detect_c64dtv:
ldy C64DTV_Extended_Regs
lda #$00
ldx $D000
; Make sure the CPU is a 6510
.byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816
bne not_found
lda #$01
sta C64DTV_Extended_Regs
; Check if $D000 is mirrored at $D040
cpx $D040
bne found
inc $D000
cpx $D040
bne not_found
found:
lda #$01
.byte $2C
not_found:
lda #$00
stx $D000
ldx #$00
sty C64DTV_Extended_Regs
rts

View File

@@ -0,0 +1,55 @@
;
; Marco van den Heuvel, 2018-04-27
;
; unsigned char detect_c65 (void);
;
;/* Check for the presence of a C65/C64DX in C64 mode.
; *
; * Possible return values:
; * 0x00 : C65/C64DX in C64 mode not present
; * 0x01 : C65/C64DX in C64 mode present
; */
.export _detect_c65
.include "accelerator.inc"
_detect_c65:
ldy $D000
; Make sure the CPU is not a 65816
clc
.byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816
lda #$00
tax
bcs not_found ; carry will be set on 65816
; Make sure the CPU is not a 6510
.byte $1A ; NOP on 6510, INA on 65(S)C(E)02
beq not_found
txa
; Make sure the CPU is a 65CE02/4510
.byte $A3,$A3 ; NOP NOP on 65(S)C02, LDZ #$A3 on 65CE02 and 4510
.byte $6B ; NOP on 65(S)C02, TZA on 65CE02 and 4510
cmp #$A3
bne not_found
; Switch to VICIII mode and check if $D040 is a mirror of $D000
ldy #C65_VICIII_UNLOCK_1
sty C65_VICIII_KEY
ldy #C65_VICIII_UNLOCK_2
sty C65_VICIII_KEY
cpy $D040
bne found
inc $D000
cpy $D040
bne not_found
found:
lda #$01
not_found:
sty $D000
sta C65_VICIII_KEY
rts

View File

@@ -0,0 +1,39 @@
;
; Marco van den Heuvel, 2018-04-25
;
; unsigned char detect_chameleon (void);
;
;/* Check for the presence of the Chameleon cartridge.
; *
; * Possible return values:
; * 0x00 : Chameleon cartridge not present
; * 0x01 : Chameleon cartridge present
; */
.export _detect_chameleon
.include "accelerator.inc"
_detect_chameleon:
lda #$00
tax
; Make sure the CPU is a 6510
.byte $1A ; NOP on 6510, INA on 65(S)C(E)02, 4510 and 65816
bne not_found
ldy CHAMELEON_CFGENA
lda #CHAMELEON_ENABLE_REGS
sta CHAMELEON_CFGENA
lda CHAMELEON_CFGENA
sty CHAMELEON_CFGENA
cmp #$FF
beq not_found
found:
lda #$01
.byte $24
not_found:
txa
rts

View File

@@ -0,0 +1,34 @@
;
; Marco van den Heuvel, 2018-04-08
;
; unsigned char detect_scpu (void);
;
;/* Check for the presence of the SuperCPU cartridge.
; *
; * Possible return values:
; * 0x00 : SuperCPU cartridge not present
; * 0x01 : SuperCPU cartridge present
; */
.export _detect_scpu
.include "accelerator.inc"
_detect_scpu:
ldx #$00
txa
; Make sure the current CPU is a 65816
clc
.byte $E2,$01 ; NOP #$01 on 6510 and 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816
bcc not_found ; carry will be set on 65816
; 65816 has been detected, make sure it's the SuperCPU cartridge
lda SuperCPU_Detect
asl
bcs not_found
found:
lda #$01
not_found:
rts

View File

@@ -0,0 +1,45 @@
;
; Marco van den Heuvel, 2018-04-30
;
; unsigned char detect_turbomaster (void);
;
;/* Check for the presence of a Turbo Master cartridge.
; *
; * Possible return values:
; * 0x00 : TurboMaster cartridge not present
; * 0x01 : TurboMaster cartridge present
; */
.export _detect_turbomaster
.include "accelerator.inc"
_detect_turbomaster:
lda #$00
tax
; Make sure the current CPU is not a 6510
.byte $1A ; NOP on 8502, INA on 65(S)C(E)02, 4510 and 65816
beq not_found
; Make sure the current CPU is not a 65816
clc
.byte $E2,$01 ; NOP #$01 on 65(S)C02, LDA $(01,S),Y on 65CE02 and 4510, SEP #$01 on 65816
bcs not_found ; carry will be set on 65816
; Make sure the current CPU is not a 65CE02/4510
.byte $A3,$A3 ; NOP NOP on 65(S)C02 and LDZ #$00 on 65CE02 and 4510
.byte $6B ; NOP on 65(S)C02 and TZA on 65CE02 and 4510
cmp #$A3
beq not_found
; Check for turbo master basic replacement
ldy TURBOMASTER_DETECT
cpy #$A2
beq found
not_found:
txa
found:
rts

View File

@@ -0,0 +1,59 @@
;
; Marco van den Heuvel, 2018-04-09
;
; unsigned char __fastcall__ set_scpu_speed (unsigned char speed);
;
;/* Set the speed of the SuperCPU cartridge, using SPEED_SLOW will switch to
; * 1 Mhz mode, SPEED_20X or SPEED_FAST will switch to 20 Mhz mode.
; *
; * Note that any value lower than SPEED_20X will switch to 1 Mhz mode, and
; * any value higher or equal to SPEED_20X will switch to 20 Mhz mode.
; *
; * This function will return the actual speed the CPU is at after trying
; * to set the requested speed, if this is not the speed that was requested
; * then possibly the hardware speed switch prevented any software speed
; * switching.
; *
; * This function does not check for the presence of the SuperCPU cartridge,
; * make sure you use 'detect_scpu();' before using.
; */
; unsigned char get_scpu_speed (void);
;
;/* Get the speed of the SuperCPU cartridge.
; *
; * Possible return values:
; * SPEED_1X : 1 Mhz mode
; * SPEED_20X : 20 Mhz mode
; *
; * This function does not check for the presence of the SuperCPU cartridge,
; * make sure you use 'detect_scpu();' before using.
; */
.export _set_scpu_speed
.export _get_scpu_speed
.include "accelerator.inc"
_set_scpu_speed:
cmp #SPEED_20X
bcs high_speed
low_speed:
sta SuperCPU_Slow
jmp _get_scpu_speed
high_speed:
sta SuperCPU_Fast
_get_scpu_speed:
ldx #$00
lda SuperCPU_Speed_Mode
asl
asl
bcc is_fast_speed
lda #SPEED_1X
rts
is_fast_speed:
lda #SPEED_20X
rts

View File

@@ -0,0 +1,56 @@
;
; Marco van den Heuvel, 2018-04-30
;
; unsigned char __fastcall__ set_turbomaster_speed (unsigned char speed);
;
;/* Set the speed of the Turbo Master cartridge, using SPEED_SLOW will switch to
; * 1 Mhz mode, SPEED_4X or SPEED_FAST will switch to 4 Mhz mode.
; *
; * Note that any value higher or equal to SPEED_4X will switch to 4 Mhz mode,
; * any value lower than SPEED_4X will switch to 1 Mhz mode.
; *
; * This function will return the actual speed the CPU is at after trying
; * to set the requested speed, if the speed is different it might indicate
; * that the hardware switch has locked the speed.
; *
; * This function does not check for the presence of a Turbo Master cartridge,
; * make sure you use 'detect_turbomaster();' before using.
; */
; unsigned char get_turbomaster_speed (void);
;
;/* Get the speed of the Turbo Master cartridge.
; *
; * Possible return values:
; * SPEED_SLOW : 1 Mhz mode
; * SPEED_4X : 4 Mhz mode
; *
; * This function does not check for the presence of a Turbo Master cartridge,
; * make sure you use 'detect_turbomaster();' before using.
; */
.export _set_turbomaster_speed
.export _get_turbomaster_speed
.include "accelerator.inc"
_set_turbomaster_speed:
tay
lda TURBOMASTER_SPEED_REG
asl
cpy #SPEED_4X
ror
store_speed:
sta TURBOMASTER_SPEED_REG
_get_turbomaster_speed:
ldx #$00
lda TURBOMASTER_SPEED_REG
and #$80
beq is_slow_speed
is_high_speed:
lda #SPEED_4X
is_slow_speed:
rts

View File

@@ -1,7 +1,7 @@
;
; Ullrich von Bassewitz, 27.09.1998
;
; void set_brk (unsigned Addr);
; void __fastcall__ set_brk (unsigned Addr);
; void reset_brk (void);
;

View File

@@ -7,6 +7,7 @@
.export _cgetc
.import cursor
.include "cbm_kernal.inc"
.include "c64.inc"
_cgetc: lda KEY_COUNT ; Get number of characters

View File

@@ -6,9 +6,6 @@
.export _clrscr
.include "c64.inc"
.include "cbm_kernal.inc"
_clrscr = CLRSCR

View File

@@ -7,7 +7,7 @@
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
.import popa, _gotoxy
.import gotoxy
.import PLOT
.include "c64.inc"
@@ -15,8 +15,7 @@
_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
jsr gotoxy ; Set cursor, drop x and y
pla ; Restore C
; Plot a character - also used as internal function
@@ -75,10 +74,9 @@ L5: inc CURS_Y
; Handle character if high bit set
L10: and #$7F
cmp #$7E ; PI?
cmp #$7F ; PI?
bne L11
lda #$5E ; Load screen code for PI
bne cputdirect
L11: ora #$40
bne cputdirect

View File

@@ -6,14 +6,13 @@
.export __STARTUP__ : absolute = 1 ; Mark as startup
.import initlib, donelib
.import moveinit, zerobss, callmain
.import zerobss, callmain
.import BSOUT
.import __MAIN_START__, __MAIN_SIZE__ ; Linker generated
.import __STACKSIZE__ ; from configure file
.importzp ST
.include "zeropage.inc"
.include "c64.inc"
; ------------------------------------------------------------------------
@@ -23,11 +22,6 @@
Start:
; Switch to the second charset.
lda #14
jsr BSOUT
; Switch off the BASIC ROM.
lda $01
@@ -39,22 +33,10 @@ Start:
tsx
stx spsave ; Save the system stack ptr
; Allow some re-entrancy by skipping the next task if it already was done.
; This sometimes can let us rerun the program without reloading it.
ldx move_init
beq L0
; Move the INIT segment from where it was loaded (over the bss segments)
; into where it must be run (over the BSS segment).
jsr moveinit
dec move_init ; Set to false
; Save space by putting some of the start-up code in the INIT segment,
; 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.
L0: jsr runinit
jsr init
; Clear the BSS data.
@@ -96,9 +78,9 @@ L2: lda zpsave,x
; ------------------------------------------------------------------------
.segment "INIT"
.segment "ONCE"
runinit:
init:
; Save the zero-page locations that we need.
@@ -110,11 +92,16 @@ L1: lda sp,x
; Set up the stack.
lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
lda #<(__MAIN_START__ + __MAIN_SIZE__)
ldx #>(__MAIN_START__ + __MAIN_SIZE__)
sta sp
stx sp+1 ; Set argument stack ptr
; Switch to the second charset.
lda #14
jsr BSOUT
; Call the module constructors.
jmp initlib
@@ -123,17 +110,8 @@ L1: lda sp,x
; ------------------------------------------------------------------------
; Data
.data
; These two variables were moved out of the BSS segment, and into DATA, because
; we need to use them before INIT is moved off of BSS, and before BSS is zeroed.
.segment "INIT"
mmusave:.res 1
spsave: .res 1
move_init:
.byte 1
.segment "INITBSS"
zpsave: .res zpspace

View File

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

View File

@@ -0,0 +1,280 @@
; Extended Memory Driver for the Kerberos MIDI interface.
; http://www.frank-buss.de/kerberos/
; based on the code for RamCart 64/128KB cartridge.
; 2020-06-16 Dirk Jagdmann <doj@cubic.org>
.include "zeropage.inc"
.include "em-kernel.inc"
.include "em-error.inc"
.macpack generic
.macpack module
; ------------------------------------------------------------------------
; Header. Includes jump table
module_header _c64_kerberos_emd
; Driver signature
.byte $65, $6d, $64 ; "emd"
.byte EMD_API_VERSION ; EM API version number
; Library reference
.addr $0000
; Jump table
.addr INSTALL
.addr UNINSTALL
.addr PAGECOUNT
.addr MAP
.addr USE
.addr COMMIT
.addr COPYFROM
.addr COPYTO
; ------------------------------------------------------------------------
; Constants
RAMC_WINDOW = $DF00 ; Address of Kerberos SRAM
RAMC_PAGE_LO = $DE3E ; Page register low
RAMC_PAGE_HI = $DE3F ; Page register high
.code
; ------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present and determine the amount of
; memory available.
; Must return an EM_ERR_xx code in a/x.
;
INSTALL:
;; write $55 into first page
lda #0
sta RAMC_PAGE_LO
sta RAMC_PAGE_HI
lda #$55
sta RAMC_WINDOW
;; write $AA into second page
lda #1
sta RAMC_PAGE_LO
sta RAMC_PAGE_HI
lda #$AA
sta RAMC_WINDOW
;; check $55 in first page
lda #0
sta RAMC_PAGE_LO
sta RAMC_PAGE_HI
lda RAMC_WINDOW
cmp #$55
bne @notpresent
;; check $AA in first page
lda #1
sta RAMC_PAGE_LO
sta RAMC_PAGE_HI
lda RAMC_WINDOW
cmp #$AA
bne @notpresent
lda #<EM_ERR_OK
ldx #>EM_ERR_OK
rts
@notpresent:
lda #<EM_ERR_NO_DEVICE
ldx #>EM_ERR_NO_DEVICE
; use rts from UNINSTALL below
; ------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; Can do cleanup or whatever. Must not return anything.
;
UNINSTALL:
rts
; ------------------------------------------------------------------------
; PAGECOUNT: Return the total number of available pages in a/x.
;
PAGECOUNT:
lda #<(128 * 1024 / 256)
ldx #>(128 * 1024 / 256)
rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
; The Kerberos cartridge does not copy but actually map the window, so USE is
; identical to MAP.
USE = MAP
; ------------------------------------------------------------------------
; MAP: Map the page in a/x into memory and return a pointer to the page in
; a/x. The contents of the currently mapped page (if any) may be discarded
; by the driver.
;
MAP: sta RAMC_PAGE_LO
txa
and #1
sta RAMC_PAGE_HI
lda #<RAMC_WINDOW
ldx #>RAMC_WINDOW
; Use the RTS from COMMIT below to save a precious byte of storage
; ------------------------------------------------------------------------
; COMMIT: Commit changes in the memory window to extended storage.
COMMIT: rts
; ------------------------------------------------------------------------
; COPYFROM: Copy from extended into linear memory. A pointer to a structure
; describing the request is passed in a/x.
; The function must not return anything.
;
COPYFROM:
jsr setup
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - tmp2 contains the high page register value
; - X contains the page offset
; - Y contains zero
beq @L5 ; will always branch, because setup ends with ldy #0
@L1: lda RAMC_WINDOW,x
sta (ptr2),y
iny
bne @L2
inc ptr2+1
@L2: inx
beq @L4
; Bump count and repeat
@L3: inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4: inc tmp1
bne @L5
inc tmp2
@L5: lda tmp1
sta RAMC_PAGE_LO
lda tmp2
sta RAMC_PAGE_HI
jmp @L3
; ------------------------------------------------------------------------
; COPYTO: Copy from linear into extended memory. A pointer to a structure
; describing the request is passed in a/x.
; The function must not return anything.
;
COPYTO:
jsr setup
; Setup is:
;
; - ptr1 contains the struct pointer
; - ptr2 contains the linear memory buffer
; - ptr3 contains -(count-1)
; - tmp1 contains the low page register value
; - tmp2 contains the high page register value
; - X contains the page offset
; - Y contains zero
beq @L5 ; will always branch, because setup ends with ldy #0
@L1: lda (ptr2),y
sta RAMC_WINDOW,x
iny
bne @L2
inc ptr2+1
@L2: inx
beq @L4
; Bump count and repeat
@L3: inc ptr3
bne @L1
inc ptr3+1
bne @L1
rts
; Bump page register
@L4: inc tmp1
bne @L5
inc tmp2
@L5: lda tmp1
sta RAMC_PAGE_LO
lda tmp2
sta RAMC_PAGE_HI
jmp @L3
; ------------------------------------------------------------------------
; Helper function for COPYFROM and COPYTO: Store the pointer to the request
; structure and prepare data for the copy
setup: sta ptr1
stx ptr1+1 ; Save passed pointer
; Get the page number from the struct and adjust it so that it may be used
; with the hardware. That is: lower 6 bits in tmp1, high bits in tmp2.
ldy #EM_COPY::PAGE+1
lda (ptr1),y
sta tmp2
dey
lda (ptr1),y
sta tmp1
; Get the buffer pointer into ptr2
ldy #EM_COPY::BUF
lda (ptr1),y
sta ptr2
iny
lda (ptr1),y
sta ptr2+1
; Get the count, calculate -(count-1) and store it into ptr3
ldy #EM_COPY::COUNT
lda (ptr1),y
eor #$FF
sta ptr3
iny
lda (ptr1),y
eor #$FF
sta ptr3+1
; Get the page offset into X and clear Y
ldy #EM_COPY::OFFS
lda (ptr1),y
tax
ldy #$00
; Done
rts

View File

@@ -44,7 +44,7 @@
; Constants
BASE = $D000
PAGES = ($10000 - BASE) / 256
PAGES = ($FF00 - BASE) / 256
; ------------------------------------------------------------------------
; Data.
@@ -167,7 +167,7 @@ loop: .repeat 8
; Done
done: rts
done: rts
; ------------------------------------------------------------------------
; COPYFROM: Copy from extended into linear memory. A pointer to a structure
@@ -178,7 +178,7 @@ done: rts
COPYFROM:
sta ptr3
stx ptr3+1 ; Save the passed em_copy pointer
ldy #EM_COPY::OFFS
lda (ptr3),y
sta ptr1
@@ -267,5 +267,3 @@ COPYTO: sta ptr3
sta ptr1+1 ; From
jmp common

View File

@@ -55,6 +55,9 @@ REU_TRIGGER = $FF00 ; REU command trigger
OP_COPYFROM = $ED
OP_COPYTO = $EC
OP_COPYFROM_ALOAD = $B1
OP_COPYTO_ALOAD = $B0
; ------------------------------------------------------------------------
; Data.
@@ -92,19 +95,59 @@ INSTALL:
cmp REU_REUADDR ; Check for presence of REU
bne nodevice
ldy #>(128*4) ; Assume 128KB
lda REU_STATUS
and #$10 ; Check size bit
beq @L1
ldy #>(256*4) ; 256KB when size bit is set
@L1: sty pagecount+1
; determine the size
php
sei
ldy #$FF
sty curpage
sty curpage+1 ; Invalidate the current page
txa ; X = A = EM_ERR_OK
loop:
sty window
jsr reu_size_check_common
ldx #OP_COPYTO_ALOAD
stx REU_COMMAND
dey
cpy #$FF
bne loop
iny
size_loop:
jsr reu_size_check_common
ldx #OP_COPYFROM_ALOAD
stx REU_COMMAND
cpy window
bne size_found
iny
bne size_loop
size_found:
plp
ldx #$00
cpy #$00 ; too many pages, shave off 2
bne pagecount_ok
dex
dex
dey
pagecount_ok:
stx pagecount
sty pagecount+1
lda #<EM_ERR_OK
ldx #>EM_ERR_OK
rts
; common REU setup for size check
reu_size_check_common:
sty REU_REUADDR+2
ldx #<window
stx REU_C64ADDR
ldx #>window
stx REU_C64ADDR+1
ldx #$00
stx REU_REUADDR
stx REU_REUADDR+1
stx REU_COUNT+1
stx REU_CONTROL
inx
stx REU_COUNT
rts
; No REU found
nodevice:
@@ -147,7 +190,7 @@ done: rts
; ------------------------------------------------------------------------
; USE: Tell the driver that the window is now associated with a given page.
USE: sta curpage
stx curpage+1 ; Remember the page
lda #<window

View File

@@ -15,6 +15,22 @@
.export _textcolor := soft80_textcolor ; color.s
.export _bgcolor := soft80_bgcolor ; color.s
; soft80_cpeekc.s
.import soft80_cpeekc
.export _cpeekc := soft80_cpeekc ; cpeekc.s
; soft80_cpeekcolor.s
.import soft80_cpeekcolor
.export _cpeekcolor := soft80_cpeekcolor ; cpeekcolor.s
; soft80_cpeekrevers.s
.import soft80_cpeekrevers
.export _cpeekrevers := soft80_cpeekrevers ; cpeekrevers.s
; soft80_cpeeks.s
.import soft80_cpeeks
.export _cpeeks := soft80_cpeeks ; cpeeks.s
; soft80_cputc.s
.import soft80_cputc
.import soft80_cputcxy
@@ -50,3 +66,6 @@
; Chars used by chline () and cvline ()
.exportzp chlinechar = CH_HLINE
.exportzp cvlinechar = CH_VLINE
.import return1
.export _doesclrscrafterexit := return1

View File

@@ -18,6 +18,22 @@
.export _textcolor := soft80mono_textcolor ; color.s
.export _bgcolor := soft80mono_bgcolor ; color.s
; soft80mono_cpeekc.s
.import soft80_cpeekc
.export _cpeekc := soft80_cpeekc ; cpeekc.s
; soft80mono_cpeekcolor.s
.import soft80mono_cpeekcolor
.export _cpeekcolor := soft80mono_cpeekcolor ; cpeekcolor.s
; soft80mono_cpeekrevers.s
.import soft80_cpeekrevers
.export _cpeekrevers := soft80_cpeekrevers ; cpeekrevers.s
; soft80mono_cpeeks.s
.import soft80_cpeeks
.export _cpeeks := soft80_cpeeks ; cpeeks.s
; soft80mono_cputc.s
.import soft80mono_cputc
.import soft80mono_cputcxy
@@ -53,3 +69,6 @@
; Chars used by chline () and cvline ()
.exportzp chlinechar = CH_HLINE
.exportzp cvlinechar = CH_VLINE
.import return1
.export _doesclrscrafterexit := return1

View File

@@ -0,0 +1,21 @@
; C64 sprite addresses for the TGI mouse pointer
;
; 2017-01-13, Greg King
; In order to provide a visible mouse pointer during TGI's graphics mode,
; the object file "c64-tgimousedata.o" must be linked explicitly into
; a program file. Example:
;
; cl65 -t c64 -o program-file main-code.c subroutines.s c64-tgimousedata.o
;
; Note: Currently, a program cannot have default
; pointers for both text and graphic modes.
; The TGI graphics mode uses VIC-II's 16K bank number three.
;
; Address of the TGI bitmap's color RAM
COLORMAP := $D000
.export mcb_spritepointer := COLORMAP + $03F8
.export mcb_spritememory := COLORMAP + $0400

83
libsrc/c64/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 "c64.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

@@ -9,7 +9,7 @@
; ------------------------------------------------------------------------
.segment "INIT"
.segment "ONCE"
initirq:
lda IRQVec

View File

@@ -29,24 +29,12 @@
.addr $0000
; Button state masks (8 values)
.byte $01 ; JOY_UP
.byte $02 ; JOY_DOWN
.byte $04 ; JOY_LEFT
.byte $08 ; JOY_RIGHT
.byte $10 ; JOY_FIRE
.byte $00 ; JOY_FIRE2 unavailable
.byte $00 ; Future expansion
.byte $00 ; Future expansion
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr COUNT
.addr READ
.addr IRQ
; ------------------------------------------------------------------------
; Constants
@@ -85,13 +73,22 @@ UNINSTALL:
rts
; ------------------------------------------------------------------------
; IRQ entry point. Is called from the C layer as a subroutine in the
; interrupt. The routine MUST return carry set if the interrupt has been
; 'handled' - which means that the interrupt source is gone. Otherwise it
; MUST return carry clear.
; COUNT: Return the total number of available joysticks in a/x.
;
IRQ: ; cia 2 setup
COUNT: lda #<JOY_COUNT
ldx #>JOY_COUNT
rts
; ------------------------------------------------------------------------
; READ: Read a particular joystick passed in A.
;
readadapter:
sei
; cia 2 setup
ldy #$00 ; port b direction
sty $dd03 ; => input
@@ -155,32 +152,24 @@ IRQ: ; cia 2 setup
sta temp4
fire:
; Default Value: $40/64 on PAL
; $42/66 on NTSC
; FIXME: to be really 100% correct this should restore the correct timer
; values for the respective machine (PAL: $4025, NTSC: $4295)
; however, this should hardly be a problem in a real world program
lda #$41
sta $dc05
; Default Value: $25/37 on PAL
; $95/149 on NTSC
lda #0
sta $dc04
; We do never "handle" the interrupt, we use it just as a timer.
clc
cli
rts
; ------------------------------------------------------------------------
; COUNT: Return the total number of available joysticks in a/x.
;
READ:
pha
jsr readadapter
pla
COUNT: lda #<JOY_COUNT
ldx #>JOY_COUNT
rts
; ------------------------------------------------------------------------
; READ: Read a particular joystick passed in A.
;
READ: tax ; Joystick number into X
tax ; Joystick number into X
bne joy2
; Read joystick 1
@@ -226,4 +215,3 @@ joy4: lda temp4
eor #$1F
ldx #0
rts

View File

@@ -30,24 +30,12 @@
.addr $0000
; Button state masks (8 values)
.byte $02 ; JOY_UP "8"
.byte $10 ; JOY_DOWN "2"
.byte $20 ; JOY_LEFT "4"
.byte $08 ; JOY_RIGHT "6"
.byte $04 ; JOY_FIRE "5" ENTER
.byte $00 ; JOY_FIRE2 unavailable
.byte $00 ; Future expansion
.byte $00 ; Future expansion
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr COUNT
.addr READ
.addr 0 ; IRQ entry unused
; ------------------------------------------------------------------------
; Constants
@@ -58,6 +46,49 @@ JOY_COUNT = 1 ; Number of joysticks we support
; ------------------------------------------------------------------------
; Data.
.rodata
; <U>p '8' key
; <D>own '2' key
; <L>eft '4' key
; <R>ight '6' key
; <B>utton '5' or ENTER key
masktable:
; Input: LDRBU
; Output: BRLDU
.byte %00000000 ; $00
.byte %00000001 ; $01
.byte %00010000 ; $02
.byte %00010001 ; $03
.byte %00001000 ; $04
.byte %00001001 ; $05
.byte %00011000 ; $06
.byte %00011001 ; $07
.byte %00000010 ; $08
.byte %00000011 ; $09
.byte %00010010 ; $0A
.byte %00010011 ; $0B
.byte %00001010 ; $0C
.byte %00001011 ; $0D
.byte %00011010 ; $0E
.byte %00011011 ; $0F
.byte %00000100 ; $10
.byte %00000101 ; $11
.byte %00010100 ; $12
.byte %00010101 ; $13
.byte %00001100 ; $14
.byte %00001101 ; $15
.byte %00011100 ; $16
.byte %00011101 ; $17
.byte %00000110 ; $18
.byte %00000111 ; $19
.byte %00010110 ; $1A
.byte %00010111 ; $1B
.byte %00001110 ; $1C
.byte %00001111 ; $1D
.byte %00011110 ; $1E
.byte %00011111 ; $1F
.code
@@ -100,21 +131,23 @@ COUNT: lda #JOY_COUNT
;
READ: tax ; Clear high byte
lda #$FD
ldy #$FE
lda #$FD ; For ENTER and '6'
ldy #$FE ; For '8', '5', '2', '4'
sei
sta VIC_KBD_128
lda CIA1_PRB
and #%00110000
eor #%00110000
lsr
lsr
lsr ; Map ENTER ...
lsr ; ... onto '5'
sty VIC_KBD_128
eor CIA1_PRB
iny
sty VIC_KBD_128 ; Reset to $FF
cli
and #%11111110
eor #%11111110
and #%00111110
eor #%00111110
lsr
tay
lda masktable,y ; Convert LDRBU to BRLDU
rts

View File

@@ -29,24 +29,12 @@
.addr $0000
; Button state masks (8 values)
.byte $01 ; JOY_UP
.byte $02 ; JOY_DOWN
.byte $04 ; JOY_LEFT
.byte $08 ; JOY_RIGHT
.byte $10 ; JOY_FIRE
.byte $00 ; JOY_FIRE2 unavailable
.byte $00 ; Future expansion
.byte $00 ; Future expansion
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr COUNT
.addr READ
.addr 0 ; IRQ entry unused
; ------------------------------------------------------------------------
; Constants
@@ -133,8 +121,8 @@ joy3:
sta CIA2_PRB ; (output one at PB7)
lda CIA2_PRB ; cia 2 port B read/write
and #$1f ; get bit 4-0 (PB4-PB0)
eor #$1f
and #$1F ; get bit 4-0 (PB4-PB0)
eor #$1F
rts
; Read joystick 4
@@ -143,14 +131,14 @@ joy4: lda #$00 ; cia 2 port B read/write
sta CIA2_PRB ; (output zero at PB7)
lda CIA2_PRB ; cia 2 port B read/write
and #$0f ; get bit 3-0 (PB3-PB0)
and #$0F ; get bit 3-0 (PB3-PB0)
sta tmp1 ; joy 4 directions
lda CIA2_PRB ; cia 2 port B read/write
and #%00100000 ; get bit 5 (PB5)
lsr
ora tmp1
eor #$1f
eor #$1F
ldx #0
rts

View File

@@ -29,24 +29,12 @@
.addr $0000
; Button state masks (8 values)
.byte $01 ; JOY_UP
.byte $02 ; JOY_DOWN
.byte $04 ; JOY_LEFT
.byte $08 ; JOY_RIGHT
.byte $10 ; JOY_FIRE
.byte $00 ; JOY_FIRE2 unavailable
.byte $00 ; Future expansion
.byte $00 ; Future expansion
; Jump table.
.addr INSTALL
.addr UNINSTALL
.addr COUNT
.addr READ
.addr 0 ; IRQ entry unused
; ------------------------------------------------------------------------
; Constants
@@ -105,9 +93,7 @@ joy1: lda #$7F
sta CIA1_PRA
lda CIA1_PRB
cli
and #$1F
eor #$1F
rts
jmp end
; Read joystick 2
@@ -119,8 +105,6 @@ joy2: ldx #0
lda CIA1_PRA
sty CIA1_DDRA
cli
and #$1F
end: and #$1F
eor #$1F
rts

14
libsrc/c64/kbrepeat.s Normal file
View File

@@ -0,0 +1,14 @@
;
; unsigned char __fastcall__ kbrepeat (unsigned char mode);
;
.export _kbrepeat
.include "c64.inc"
_kbrepeat:
ldx KBDREPEAT ; get old value
sta KBDREPEAT ; store new value
txa ; return old value
ldx #0
rts

View File

@@ -1,9 +1,16 @@
;
; Ullrich von Bassewitz, 19.11.2002
;
; C64 kernal functions
; C64 Kernal functions
;
.include "cbm_kernal.inc"
.export CLRSCR
.export KBDREAD
.export UPDCRAMPTR
.export NMIEXIT
.export CINT
.export IOINIT
.export RAMTAS
@@ -31,7 +38,9 @@
.export CKOUT
.export CLRCH
.export BASIN
.export CHRIN
.export BSOUT
.export CHROUT
.export LOAD
.export SAVE
.export SETTIM
@@ -42,47 +51,3 @@
.export UDTIM
.export SCREEN
.export IOBASE
;-----------------------------------------------------------------------------
; All functions are available in the kernal jump table
CINT = $FF81
IOINIT = $FF84
RAMTAS = $FF87
RESTOR = $FF8A
VECTOR = $FF8D
SETMSG = $FF90
SECOND = $FF93
TKSA = $FF96
MEMTOP = $FF99
MEMBOT = $FF9C
SCNKEY = $FF9F
SETTMO = $FFA2
ACPTR = $FFA5
CIOUT = $FFA8
UNTLK = $FFAB
UNLSN = $FFAE
LISTEN = $FFB1
TALK = $FFB4
READST = $FFB7
SETLFS = $FFBA
SETNAM = $FFBD
OPEN = $FFC0
CLOSE = $FFC3
CHKIN = $FFC6
CKOUT = $FFC9
CLRCH = $FFCC
BASIN = $FFCF
BSOUT = $FFD2
LOAD = $FFD5
SAVE = $FFD8
SETTIM = $FFDB
RDTIM = $FFDE
STOP = $FFE1
GETIN = $FFE4
CLALL = $FFE7
UDTIM = $FFEA
SCREEN = $FFED
IOBASE = $FFF3

View File

@@ -7,15 +7,16 @@
.export PLOT
.scope KERNAL
.include "cbm_kernal.inc"
.endscope
.proc PLOT
bcs @L1
jsr $FFF0 ; Set cursor position
jmp $EA24 ; Set pointer to color RAM
jsr KERNAL::PLOT ; Set cursor position using original ROM PLOT
jmp KERNAL::UPDCRAMPTR ; Set pointer to color RAM to match new cursor position
@L1: jmp $FFF0 ; Get cursor position
@L1: jmp KERNAL::PLOT ; Get cursor position
.endproc

View File

@@ -32,10 +32,10 @@ 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 INIT segment,
; Get possible command-line arguments. Goes into the special ONCE segment,
; which may be reused after the startup code is run
.segment "INIT"
.segment "ONCE"
initmainargs:
@@ -125,7 +125,7 @@ done: lda #<argv
stx __argv + 1
rts
.segment "INITBSS"
.segment "INIT"
term: .res 1
name: .res NAME_LEN + 1

View File

@@ -21,16 +21,16 @@
; Sprite definitions. The first value can be changed to adjust the number
; of the sprite used for the mouse. All others depend on this value.
MOUSE_SPR = 0 ; Sprite used for the mouse
MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask
MOUSE_SPR_NMASK = .lobyte(.not MOUSE_SPR_MASK) ; Negative mask
VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
MOUSE_SPR = 0 ; Sprite used for the mouse
MOUSE_SPR_MASK = $01 .shl MOUSE_SPR ; Positive mask
MOUSE_SPR_NMASK = .lobyte(.bitnot MOUSE_SPR_MASK) ; Negative mask
VIC_SPR_X = (VIC_SPR0_X + 2*MOUSE_SPR) ; Sprite X register
VIC_SPR_Y = (VIC_SPR0_Y + 2*MOUSE_SPR) ; Sprite Y register
; --------------------------------------------------------------------------
; Initialize the mouse sprite.
.segment "INIT"
.segment "ONCE"
initmcb:

View File

@@ -12,4 +12,3 @@
_mouse_stddrv: .asciiz "c64-1351.mou"

View File

@@ -11,7 +11,7 @@
.include "c64.inc"
__randomize:
__randomize:
ldx VIC_HLINE ; Use VIC rasterline as high byte
lda TIME+2 ; Use 60HZ clock as low byte
jmp _srand ; Initialize generator

View File

@@ -24,6 +24,7 @@
.include "zeropage.inc"
.include "ser-kernel.inc"
.include "ser-error.inc"
.include "cbm_kernal.inc"
.include "c64.inc"
.macpack module
@@ -45,15 +46,15 @@
; Jump table
.word INSTALL
.word UNINSTALL
.word OPEN
.word CLOSE
.word GET
.word PUT
.word STATUS
.word IOCTL
.word IRQ
.word SER_INSTALL
.word SER_UNINSTALL
.word SER_OPEN
.word SER_CLOSE
.word SER_GET
.word SER_PUT
.word SER_STATUS
.word SER_IOCTL
.word SER_IRQ
;----------------------------------------------------------------------------
; I/O definitions
@@ -136,11 +137,11 @@ ParityTable:
.code
;----------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. If
; SER_INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present.
; Must return an SER_ERR_xx code in a/x.
INSTALL:
SER_INSTALL:
; Deactivate DTR and disable 6551 interrupts
@@ -165,10 +166,10 @@ SetNMI: sta NMIVec
rts
;----------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory.
; SER_UNINSTALL routine. Is called before the driver is removed from memory.
; Must return an SER_ERR_xx code in a/x.
UNINSTALL:
SER_UNINSTALL:
; Stop interrupts, drop DTR
@@ -185,7 +186,7 @@ UNINSTALL:
; PARAMS routine. A pointer to a ser_params structure is passed in ptr1.
; Must return an SER_ERR_xx code in a/x.
OPEN:
SER_OPEN:
; Check if the handshake setting is valid
@@ -256,11 +257,11 @@ InvBaud:
rts
;----------------------------------------------------------------------------
; CLOSE: Close the port, disable interrupts and flush the buffer. Called
; SER_CLOSE: Close the port, disable interrupts and flush the buffer. Called
; without parameters. Must return an error code in a/x.
;
CLOSE:
SER_CLOSE:
; Stop interrupts, drop DTR
@@ -278,12 +279,13 @@ CLOSE:
rts
;----------------------------------------------------------------------------
; GET: Will fetch a character from the receive buffer and store it into the
; SER_GET: Will fetch a character from the receive buffer and store it into the
; variable pointer to by ptr1. If no data is available, SER_ERR_NO_DATA is
; return.
;
GET: ldx SendFreeCnt ; Send data if necessary
SER_GET:
ldx SendFreeCnt ; Send data if necessary
inx ; X == $FF?
beq @L1
lda #$00
@@ -322,11 +324,11 @@ GET: ldx SendFreeCnt ; Send data if necessary
rts
;----------------------------------------------------------------------------
; PUT: Output character in A.
; SER_PUT: Output character in A.
; Must return an error code in a/x.
;
PUT:
SER_PUT:
; Try to send
@@ -356,31 +358,33 @@ PUT:
rts
;----------------------------------------------------------------------------
; STATUS: Return the status in the variable pointed to by ptr1.
; SER_STATUS: Return the status in the variable pointed to by ptr1.
; Must return an error code in a/x.
;
STATUS: lda ACIA_STATUS
SER_STATUS:
lda ACIA_STATUS
ldx #0
sta (ptr1,x)
txa ; SER_ERR_OK
rts
;----------------------------------------------------------------------------
; IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; SER_IOCTL: Driver defined entry point. The wrapper will pass a pointer to ioctl
; specific data in ptr1, and the ioctl code in A.
; Must return an error code in a/x.
;
IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
SER_IOCTL:
lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
ldx #>SER_ERR_INV_IOCTL
rts
rts
;----------------------------------------------------------------------------
; IRQ: Not used on the C64
; SER_IRQ: Not used on the C64
;
IRQ = $0000
SER_IRQ = $0000
;----------------------------------------------------------------------------
;
@@ -476,4 +480,3 @@ InitBuffers:
stx RecvFreeCnt
stx SendFreeCnt
rts

84
libsrc/c64/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 "c64.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

View File

@@ -11,6 +11,7 @@
.import cursor
.importzp tmp1
.include "cbm_kernal.inc"
.include "c64.inc"
.include "soft80.inc"
@@ -45,39 +46,33 @@ invertcursor:
lda #$34
sta $01
ldy #$00
jsr setcolor
ldx soft80_internal_cursorxlsb
@lp1:
lda (SCREEN_PTR),y
eor nibble,x
sta (SCREEN_PTR),y
iny
cpy #8
bne @lp1
pla
sta $01 ; enable I/O
cli
rts
; do not use soft80_putcolor here to make sure the cursor is always
; shown using the current textcolor without disturbing the "color voodoo"
; in soft80_cputc
setcolor:
;ldy #0 ; is 0
ldy #0
bcs @set
; restore old value
lda tmp1
sta (CRAM_PTR),y ; vram
rts
bcc @lp0
@set:
; save old value
lda (CRAM_PTR),y ; vram
sta tmp1
lda soft80_internal_cellcolor
@lp0:
sta (CRAM_PTR),y ; vram
ldx soft80_internal_cursorxlsb
ldy #7
@lp1:
lda (SCREEN_PTR),y
eor nibble,x
sta (SCREEN_PTR),y
dey
bpl @lp1
pla
sta $01 ; enable I/O
cli
rts
.rodata

View File

@@ -43,7 +43,7 @@
.export soft80_charset
.segment "INIT"
.segment "ONCE"
soft80_charset:
.byte $0f,$03,$0f,$00,$0f,$07,$05,$0e
.byte $0f,$05,$0e,$0b,$0f,$0b,$0f,$0f

View File

@@ -56,7 +56,7 @@ soft80_shutdown:
sta CIA2_PRA
jmp $FF5B ; Initialize video I/O
.segment "INIT"
.segment "ONCE"
firstinit:
; copy charset to RAM under I/O
sei
@@ -67,22 +67,20 @@ firstinit:
inc soft80_first_init
; soft80_lo_charset and soft80_hi_charset are page-aligned
ldy #0
lda #<soft80_charset
ldx #>soft80_charset
sta ptr1
stx ptr1+1
lda #<soft80_lo_charset
ldx #>soft80_lo_charset
sta ptr2
sty ptr2
stx ptr2+1
lda #<soft80_hi_charset
ldx #>soft80_hi_charset
sta ptr3
sty ptr3
stx ptr3+1
ldx #4
@l2:
ldy #0
@l1:
lda (ptr1),y
sta (ptr2),y
@@ -97,17 +95,17 @@ firstinit:
inc ptr2+1
inc ptr3+1
dex
bne @l2
bne @l1
; copy the kplot tables to ram under I/O
;ldx #0 ; is 0
@l3:
@l2:
lda soft80_tables_data_start,x
sta soft80_bitmapxlo,x
lda soft80_tables_data_start + (soft80_tables_data_end - soft80_tables_data_start - $0100),x
sta soft80_bitmapxlo + (soft80_tables_data_end - soft80_tables_data_start - $0100),x
inx
bne @l3
bne @l2
pla
sta $01
@@ -146,7 +144,7 @@ soft80_bitmapyhi_data:
soft80_tables_data_end:
;-------------------------------------------------------------------------------
.segment "INITBSS"
.segment "INIT"
soft80_internal_cellcolor:
.res 1
soft80_internal_bgcolor:

148
libsrc/c64/soft80_cpeekc.s Normal file
View File

@@ -0,0 +1,148 @@
;
; 2017-12-28, Groepaz
;
; char cpeekc (void);
;
.export soft80_cpeekc, soft80_cpeekchar
.include "c64.inc"
.include "soft80.inc"
.macpack longbranch
.segment "CODE"
soft80_cpeekc:
jsr soft80_cpeekchar
; 0-1F -> A0-BF
; 20-7F -> 20-7F
cmp #$20
bcs @sk
;clc
adc #$a0
@sk:
ldx #0
rts
soft80_cpeekchar:
sei
lda #$34
sta $01
lda CURS_X
and #$01
jne @l1a
; test non-inverted character (left side)
ldx #0
@l2aa:
ldy #0
.repeat 8,line
lda (SCREEN_PTR),y
and #$f0
cmp soft80_hi_charset+(line*$80),x
bne @l2b
.if (line < 7)
iny
.endif
.endrepeat
@backok:
lda #$36
sta $01
cli
txa ; return char in A
ldx #$00 ; revers flag
rts
@l2b:
inx
cpx #$80
jne @l2aa
; test inverted character (left side)
ldx #0
@l2aa2:
ldy #0
.repeat 8,line
lda (SCREEN_PTR),y
and #$f0
eor #$f0
cmp soft80_hi_charset+(line*$80),x
bne @l2b2
.if (line < 7)
iny
.endif
.endrepeat
@backokrevers:
lda #$36
sta $01
cli
txa ; return char in A
ldx #$01 ; revers flag
rts
@l2b2:
inx
cpx #$80
jne @l2aa2
@backerr:
lda #$36
sta $01
cli
ldx #0
txa
rts
; test non-inverted character (right side)
@l1a:
ldx #0
@l1aa:
ldy #0
.repeat 8,line
lda (SCREEN_PTR),y
and #$0f
eor soft80_lo_charset+(line*$80),x
bne @l2bb
.if line < 7
iny
.endif
.endrepeat
jmp @backok
@l2bb:
inx
cpx #$80
bne @l1aa
; test inverted character (right side)
ldx #0
@l1aa2:
ldy #0
.repeat 8,line
lda (SCREEN_PTR),y
and #$0f
eor #$0f
eor soft80_lo_charset+(line*$80),x
bne @l2bb2
.if line < 7
iny
.endif
.endrepeat
jmp @backokrevers
@l2bb2:
inx
cpx #$80
bne @l1aa2
jmp @backerr

View File

@@ -0,0 +1,19 @@
;
; 2017-12-27, Groepaz
;
; unsigned char cpeekcolor (void);
;
.export soft80_cpeekcolor
.include "c64.inc"
.include "soft80.inc"
.segment "CODE"
soft80_cpeekcolor:
ldy #0
lda (CRAM_PTR),y
and #$0f
ldx #0
rts

View File

@@ -0,0 +1,15 @@
;
; 2017-12-28, Groepaz
;
; unsigned char cpeekrevers (void);
;
.import soft80_cpeekchar
.export soft80_cpeekrevers
soft80_cpeekrevers:
jsr soft80_cpeekchar
txa
ldx #0
rts

View File

@@ -0,0 +1,71 @@
;
; 2017-12-27, groepaz
;
; void cpeeks (char* s, unsigned length);
;
.export soft80_cpeeks
.import soft80_cpeekc, soft80_kplot, popax
.importzp ptr1, ptr2
.include "c64.inc"
.include "soft80.inc"
soft80_cpeeks:
eor #<$FFFF ; counting a word upward is faster
sta ptr2 ; so, we use -(length + 1)
txa
eor #>$FFFF
sta ptr2+1
jsr popax
sta ptr1
stx ptr1+1
; save current cursor position
lda CURS_X
pha
lda CURS_Y
pha
; get the string
@lp:
jsr soft80_cpeekc
ldy #0
sta (ptr1),y
; advance cursor position
ldy CURS_X
ldx CURS_Y
iny
cpy #charsperline
bne @sk2
ldy #0
inx
@sk2:
sty CURS_X
stx CURS_Y
clc
jsr soft80_kplot
inc ptr1
bne @sk
inc ptr1+1
@sk:
inc ptr2
bne @lp
inc ptr2+1
bne @lp
; terminate the string
lda #0
ldy #0
sta (ptr1),y
; restore the cursor position
pla
tax ; CURS_Y
pla
tay ; CURS_X
clc
jmp soft80_kplot

View File

@@ -12,7 +12,7 @@
.export soft80_newline, soft80_plot
.export soft80_checkchar
.import popa, _gotoxy
.import gotoxy
.import soft80_kplot
.import soft80_internal_bgcolor, soft80_internal_cellcolor
@@ -25,8 +25,7 @@
soft80_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
jsr gotoxy ; Set cursor, drop x and y
pla ; Restore C
; Plot a character - also used as internal function

View File

@@ -12,6 +12,7 @@
.import cursor
.importzp tmp1
.include "cbm_kernal.inc"
.include "c64.inc"
.include "soft80.inc"

View File

@@ -60,7 +60,7 @@ soft80mono_shutdown:
sta VIC_VIDEO_ADR
rts
.segment "INIT"
.segment "ONCE"
firstinit:
; copy charset to RAM under I/O
sei
@@ -150,7 +150,7 @@ soft80_bitmapyhi_data:
soft80_tables_data_end:
;-------------------------------------------------------------------------------
.segment "INITBSS"
.segment "INIT"
soft80mono_internal_cellcolor:
.res 1
soft80mono_internal_bgcolor:

View File

@@ -0,0 +1,17 @@
;
; 2017-12-27, Groepaz
;
; unsigned char cpeekcolor (void);
;
.export soft80mono_cpeekcolor
.include "c64.inc"
.include "soft80.inc"
.segment "CODE"
soft80mono_cpeekcolor:
lda CHARCOLOR
ldx #0
rts

View File

@@ -11,7 +11,7 @@
.export soft80mono_cputdirect, soft80mono_putchar
.export soft80mono_newline, soft80mono_plot
.import popa, _gotoxy
.import gotoxy
.import soft80mono_kplot
.import soft80mono_internal_bgcolor, soft80mono_internal_cellcolor
@@ -24,8 +24,7 @@
soft80mono_cputcxy:
pha ; Save C
jsr popa ; Get Y
jsr _gotoxy ; Set cursor, drop x
jsr gotoxy ; Set cursor, drop x and y
pla ; Restore C
; Plot a character - also used as internal function

View File

@@ -35,5 +35,3 @@ utsdata:
; machine
.asciiz "Commodore 64"

View File

@@ -1,7 +1,10 @@
;
; Graphics driver for the 320x200x2 mode on the C64.
;
; Based on Stephen L. Judds GRLIB code
; Based on Stephen L. Judd's GRLIB code.
;
; 2017-01-13, Greg King
; 2018-03-13, Sven Klose
;
.include "zeropage.inc"
@@ -55,7 +58,6 @@
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
.addr 0 ; IRQ entry is unused
; ------------------------------------------------------------------------
; Data.
@@ -69,12 +71,9 @@ X2 := ptr3
Y2 := ptr4
TEXT := ptr3
ROW := tmp2 ; Bitmap row...
COL := tmp3 ; ...and column, both set by PLOT
TEMP := tmp4
TEMP2 := sreg
POINT := regsave
INRANGE := regsave+2 ; PLOT variable, $00 = coordinates in range
CHUNK := X2 ; Used in the line routine
OLDCHUNK := X2+1 ; Dito
@@ -132,7 +131,7 @@ VBASE := $E000 ; Video memory base address
;
INSTALL:
rts
; rts ; Fall through
; ------------------------------------------------------------------------
@@ -273,7 +272,7 @@ CLEAR: ldy #$00
sta VBASE+$1C00,y
sta VBASE+$1D00,y
sta VBASE+$1E00,y
sta VBASE+$1F00,y
sta VBASE+$1E40,y ; Preserve vectors
iny
bne @L1
rts
@@ -286,7 +285,7 @@ CLEAR: ldy #$00
;
SETVIEWPAGE:
rts
; rts ; Fall through
; ------------------------------------------------------------------------
; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
@@ -351,7 +350,7 @@ SETPALETTE:
@L2: sta CBASE+$0000,y
sta CBASE+$0100,y
sta CBASE+$0200,y
sta CBASE+$0300,y
sta CBASE+$02e8,y
iny
bne @L2
pla
@@ -453,11 +452,6 @@ GETPIXEL:
; LINE: Draw a line from X1/Y1 to X2/Y2, where X1/Y1 = ptr1/ptr2 and
; X2/Y2 = ptr3/ptr4 using the current drawing color.
;
; To deal with off-screen coordinates, the current row
; and column (40x25) is kept track of. These are set
; negative when the point is off the screen, and made
; positive when the point is within the visible screen.
;
; X1,X2 etc. are set up above (x2=LINNUM in particular)
; Format is LINE x2,y2,x1,y1
;
@@ -466,14 +460,14 @@ GETPIXEL:
LINE:
@CHECK: lda X2 ;Make sure x1<x2
@CHECK: lda X2 ; Make sure x1<x2
sec
sbc X1
tax
lda X2+1
sbc X1+1
bpl @CONT
lda Y2 ;If not, swap P1 and P2
lda Y2 ; If not, swap P1 and P2
ldy Y1
sta Y1
sty Y2
@@ -494,25 +488,25 @@ LINE:
@CONT: sta DX+1
stx DX
ldx #$C8 ;INY
lda Y2 ;Calculate dy
ldx #$C8 ; INY
lda Y2 ; Calculate dy
sec
sbc Y1
tay
lda Y2+1
sbc Y1+1
bpl @DYPOS ;Is y2>=y1?
lda Y1 ;Otherwise dy=y1-y2
bpl @DYPOS ; Is y2>=y1?
lda Y1 ; Otherwise dy=y1-y2
sec
sbc Y2
tay
ldx #$88 ;DEY
ldx #$88 ; DEY
@DYPOS: sty DY ; 8-bit DY -- FIX ME?
stx YINCDEC
stx XINCDEC
jsr CALC ; Set up .X,.Y,POINT, and INRANGE
jsr CALC ; Set up .X, .Y, and POINT
lda BITCHUNK,X
sta OLDCHUNK
sta CHUNK
@@ -522,8 +516,8 @@ LINE:
sta $01
ldx DY
cpx DX ;Who's bigger: dy or dx?
bcc STEPINX ;If dx, then...
cpx DX ; Who's bigger: dy or dx?
bcc STEPINX ; If dx, then...
lda DX+1
bne STEPINX
@@ -541,73 +535,57 @@ LINE:
; Y1 AND #$07
STEPINY:
lda #00
sta OLDCHUNK ;So plotting routine will work right
sta OLDCHUNK ; So plotting routine will work right
lda CHUNK
lsr ;Strip the bit
lsr ; Strip the bit
eor CHUNK
sta CHUNK
txa
bne @CONT ;If dy=0 it's just a point
inx
@CONT: lsr ;Init counter to dy/2
beq YCONT2 ; If dy=0, it's just a point
@CONT: lsr ; Init counter to dy/2
;
; Main loop
;
YLOOP: sta TEMP
lda INRANGE ;Range check
bne @SKIP
lda (POINT),y ;Otherwise plot
lda (POINT),y
eor BITMASK
and CHUNK
eor (POINT),y
sta (POINT),y
@SKIP:
YINCDEC:
iny ;Advance Y coordinate
iny ; Advance Y coordinate
cpy #8
bcc @CONT ;No prob if Y=0..7
bcc @CONT ; No prob if Y=0..7
jsr FIXY
@CONT: lda TEMP ;Restore A
@CONT: lda TEMP ; Restore A
sec
sbc DX
bcc YFIXX
YCONT: dex ;X is counter
YCONT: dex ; X is counter
bne YLOOP
YCONT2: lda (POINT),y ;Plot endpoint
YCONT2: lda (POINT),y ; Plot endpoint
eor BITMASK
and CHUNK
eor (POINT),y
sta (POINT),y
YDONE: lda #$36
lda #$36
sta $01
cli
rts
YFIXX: ;x=x+1
YFIXX: ; X = X + 1
adc DY
lsr CHUNK
bne YCONT ;If we pass a column boundary...
ror CHUNK ;then reset CHUNK to $80
bne YCONT ; If we pass a column boundary...
ror CHUNK ; Then reset CHUNK to $80
sta TEMP2
lda COL
bmi @C1 ;Skip if column is negative
cmp #39 ;End if move past end of screen
bcs YDONE
@C1: lda POINT ;And add 8 to POINT
lda POINT ; And add 8 to POINT
adc #8
sta POINT
bcc @CONT
inc POINT+1
@CONT: inc COL ;Increment column
bne @C2
lda ROW ;Range check
cmp #25
bcs @C2
lda #00 ;Passed into col 0
sta INRANGE
@C2: lda TEMP2
@CONT: lda TEMP2
dex
bne YLOOP
beq YCONT2
@@ -620,35 +598,34 @@ YFIXX: ;x=x+1
.bss
COUNTHI:
.byte $00 ;Temporary counter
;only used once
.byte $00 ; Temporary counter, only used once
.code
STEPINX:
ldx DX
lda DX+1
sta COUNTHI
cmp #$80
ror ;Need bit for initialization
sta Y1 ;High byte of counter
ror ; Need bit for initialization
sta Y1 ; High byte of counter
txa
bne @CONT ;Could be $100
bne @CONT ; Could be $100
dec COUNTHI
@CONT: ror
;
; Main loop
;
XLOOP: lsr CHUNK
beq XFIXC ;If we pass a column boundary...
beq XFIXC ; If we pass a column boundary...
XCONT1: sbc DY
bcc XFIXY ;Time to step in Y?
bcc XFIXY ; Time to step in Y?
XCONT2: dex
bne XLOOP
dec COUNTHI ;High bits set?
dec COUNTHI ; High bits set?
bpl XLOOP
XDONE: lsr CHUNK ;Advance to last point
jsr LINEPLOT ;Plot the last chunk
EXIT: lda #$36
lsr CHUNK ; Advance to last point
jsr LINEPLOT ; Plot the last chunk
lda #$36
sta $01
cli
rts
@@ -661,45 +638,34 @@ XFIXC: sta TEMP
lda #$FF
sta CHUNK
sta OLDCHUNK
lda COL
bmi @C1 ;Skip if column is negative
cmp #39 ;End if move past end of screen
bcs EXIT
@C1: lda POINT
lda POINT
clc
adc #8
sta POINT
bcc @CONT
lda TEMP
bcc XCONT1
inc POINT+1
@CONT: inc COL
bne @C2
lda ROW
cmp #25
bcs @C2
lda #00
sta INRANGE
@C2: lda TEMP
sec
bcs XCONT1
jmp XCONT1
;
; Check to make sure there isn't a high bit, plot chunk,
; and update Y-coordinate.
;
XFIXY: dec Y1 ;Maybe high bit set
XFIXY: dec Y1 ; Maybe high bit set
bpl XCONT2
adc DX
sta TEMP
lda DX+1
adc #$FF ;Hi byte
adc #$FF ; Hi byte
sta Y1
jsr LINEPLOT ;Plot chunk
jsr LINEPLOT ; Plot chunk
lda CHUNK
sta OLDCHUNK
lda TEMP
XINCDEC:
iny ;Y-coord
cpy #8 ;0..7 is ok
iny ; Y-coord
cpy #8 ; 0..7 is ok
bcc XCONT2
sta TEMP
jsr FIXY
@@ -711,44 +677,34 @@ XINCDEC:
; room, gray hair, etc.)
;
LINEPLOT: ; Plot the line chunk
lda INRANGE
bne @SKIP
lda (POINT),Y ; Otherwise plot
lda (POINT),Y
eor BITMASK
ora CHUNK
and OLDCHUNK
eor CHUNK
eor (POINT),Y
sta (POINT),Y
@SKIP: rts
rts
;
; Subroutine to fix up pointer when Y decreases through
; zero or increases through 7.
;
FIXY: cpy #255 ;Y=255 or Y=8
FIXY: cpy #255 ; Y=255 or Y=8
beq @DECPTR
@INCPTR: ;Add 320 to pointer
ldy #0 ;Y increased through 7
lda ROW
bmi @C1 ;If negative, then don't update
cmp #24
bcs @TOAST ;If at bottom of screen then quit
@C1: lda POINT
@INCPTR: ; Add 320 to pointer
ldy #0 ; Y increased through 7
lda POINT
adc #<320
sta POINT
lda POINT+1
adc #>320
sta POINT+1
@CONT1: inc ROW
bne @DONE
lda COL
bpl @CLEAR
@DONE: rts
rts
@DECPTR: ;Okay, subtract 320 then
ldy #7 ;Y decreased through 0
@DECPTR: ; Okay, subtract 320 then
ldy #7 ; Y decreased through 0
lda POINT
sec
sbc #<320
@@ -756,21 +712,8 @@ FIXY: cpy #255 ;Y=255 or Y=8
lda POINT+1
sbc #>320
sta POINT+1
@CONT2: dec ROW
bmi @TOAST
lda ROW
cmp #24
bne @DONE
lda COL
bmi @DONE
@CLEAR: lda #00
sta INRANGE
rts
@TOAST: pla ;Remove old return address
pla
jmp EXIT ;Restore interrupts, etc.
; ------------------------------------------------------------------------
; BAR: Draw a filled rectangle with the corners X1/Y1, X2/Y2, where
; X1/Y1 = ptr1/ptr2 and X2/Y2 = ptr3/ptr4 using the current drawing color.
@@ -872,7 +815,7 @@ TEXTSTYLE:
OUTTEXT:
; Calculate a pointer to the representation of the character in the
; character ROM
; character ROM
ldx #((>(CHARROM + $0800)) >> 3)
ldy #0
@@ -895,48 +838,36 @@ OUTTEXT:
rts
; ------------------------------------------------------------------------
; Calculate all variables to plot the pixel at X1/Y1. If the point is out
; of range, a carry is returned and INRANGE is set to a value !0 zero. If
; the coordinates are valid, INRANGE is zero and the carry clear.
; Calculate all variables to plot the pixel at X1/Y1.
CALC: lda Y1
sta ROW
sta TEMP2
and #7
tay
lda Y1+1
lsr ; Neg is possible
ror ROW
ror TEMP2
lsr
ror ROW
ror TEMP2
lsr
ror ROW
ror TEMP2
lda #00
sta POINT
lda ROW
lda TEMP2
cmp #$80
ror
ror POINT
cmp #$80
ror
ror POINT ; row*64
adc ROW ; +row*256
ror POINT ; Row * 64
adc TEMP2 ; + Row * 256
clc
adc #>VBASE ; +bitmap base
adc #>VBASE ; + Bitmap base
sta POINT+1
lda X1
tax
sta COL
lda X1+1
lsr
ror COL
lsr
ror COL
lsr
ror COL
txa
and #$F8
clc
adc POINT ; +(X AND #$F8)
@@ -947,15 +878,4 @@ CALC: lda Y1
txa
and #7
tax
lda ROW
cmp #25
bcs @L9
lda COL
cmp #40
bcs @L9
lda #00
@L9: sta INRANGE
rts

View File

@@ -1,8 +0,0 @@
;
; Target-specific black & white values for use by the target-shared TGI kernel
;
.include "tgi-kernel.inc"
.export tgi_color_black:zp = $00
.export tgi_color_white:zp = $01

View File

@@ -1,60 +1,30 @@
;
; Stefan Haubenthal, 27.7.2009
; Oliver Schmidt, 16.8.2018
;
; time_t _systime (void);
; /* Similar to time(), but:
; ** - Is not ISO C
; ** - Does not take the additional pointer
; ** - Does not set errno when returning -1
; */
; Common stuff for the clock routines
;
.include "time.inc"
.include "c64.inc"
.include "get_tv.inc"
.constructor initsystime
.importzp tmp1, tmp2
.export TM, load_tenth
.constructor inittime
.importzp sreg
.import _get_tv, _get_ostype
;----------------------------------------------------------------------------
.code
.proc __systime
.proc load_tenth
lda CIA1_TODHR
bpl AM
and #%01111111
sed
clc
adc #$12
cld
AM: 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 CIA1_TOD10 ; Dummy read to unfreeze
lda #<TM
ldx #>TM
jmp _mktime
; dec = (((BCD>>4)*10) + (BCD&0xf))
BCD2dec:tax
and #%00001111
sta tmp1
txa
and #%11110000 ; *16
lsr ; *8
sta tmp2
lsr
lsr ; *2
adc tmp2 ; = *10
adc tmp1
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
@@ -63,9 +33,9 @@ BCD2dec:tax
; 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 "INIT"
.segment "ONCE"
.proc initsystime
.proc inittime
lda CIA1_TOD10
sta CIA1_TOD10

18
libsrc/c64/waitvsync.s Normal file
View File

@@ -0,0 +1,18 @@
;
; Written by Groepaz <groepaz@gmx.net>
;
; void waitvsync (void);
;
.export _waitvsync
.include "c64.inc"
_waitvsync:
@l1:
bit VIC_CTRL1
bpl @l1
@l2:
bit VIC_CTRL1
bmi @l2
rts