Merge remote-tracking branch 'origin/master' into coniopeek

This commit is contained in:
mrdudz
2022-07-24 03:24:45 +02:00
2250 changed files with 195541 additions and 36938 deletions

View File

@@ -0,0 +1,51 @@
;
; 2018-04-23, Marco van den Heuvel
; 2018-04-26, Greg King
;
; unsigned char __fastcall__ set_c128_speed (unsigned char speed);
;
;/* Set the speed of the C128 8502 CPU; using SPEED_SLOW will switch to
; * 1 Mhz (slow) mode, SPEED_2X or SPEED_FAST will switch to 2Mhz (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.
; *
; * For C64 programs, a check for a C128 in C64 mode is needed; make sure you
; * use 'detect_c128();' before using.
; *
; * For C128 programs, no detect function call is needed.
; */
; unsigned char get_c128_speed (void);
;
;/* Get the speed of the C128 8502 CPU.
; *
; * Possible return values:
; * SPEED_SLOW : Slow mode
; * SPEED_2X : Fast mode
; *
; * For C64 programs, a check for a C128 in C64 mode is needed; make sure you
; * use 'detect_c128();' before using.
; *
; * For C128 programs, no detect function call is needed.
; */
.export _set_c128_speed
.export _get_c128_speed
.include "accelerator.inc"
_set_c128_speed:
cmp #SPEED_2X
lda #$00 ; clear VIC-IIe test bit
rol a ; carry flag is speed bit
sta C128_VICIIE_CLK
_get_c128_speed:
lda C128_VICIIE_CLK
and #$01
ldx #>$0000
rts

View File

@@ -0,0 +1,24 @@
;
; Marco van den Heuvel, 2018-04-23
;
; unsigned char detect_c128 (void);
;
;/* Check if the C128 8502 CPU is the current CPU.
; *
; * Possible return values:
; * 0x00 : C128 8502 is not the current CPU
; * 0x01 : C128 8502 is the current CPU
; */
.export _detect_c128
.include "accelerator.inc"
_detect_c128:
ldx #$00
lda #$01
; Make sure the CPU is a 8502
.byte $3A ; NOP on 8502, DEA on 65(S)C(E)02, 4510 and 65816
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,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

@@ -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

@@ -10,6 +10,7 @@
.import cursor
.include "cbm_kernal.inc"
.include "c128.inc"
;--------------------------------------------------------------------------
@@ -17,8 +18,8 @@
_cgetc: lda KEY_COUNT ; Get number of characters
bne L2 ; Jump if there are already chars waiting
; Switch on the cursor if needed. We MUST always switch the cursor on,
; before switching it off, because switching it off will restore the
; Switch on the cursor if needed. We MUST always switch the cursor on,
; before switching it off, because switching it off will restore the
; character attribute remembered when it was switched on. So just switching
; it off will restore the wrong character attribute.
@@ -39,18 +40,18 @@ L2: jsr KBDREAD ; Read char and return in A
;--------------------------------------------------------------------------
; Module constructor/destructor
.bss
.segment "INIT"
keyvec: .res 2
.segment "INIT"
.segment "ONCE"
initcgetc:
; Save the old vector
lda KeyStoreVec
ldx KeyStoreVec+1
sta keyvec
lda KeyStoreVec+1
sta keyvec+1
stx keyvec+1
; Set the new vector. I can only hope that this works for other C128
; versions...
@@ -68,5 +69,3 @@ SetVec: sei
stx KeyStoreVec+1
cli
rts

View File

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

70
libsrc/c128/cpeekc.s Normal file
View File

@@ -0,0 +1,70 @@
;
; 2016-02-28, Groepaz
; 2017-06-26, Greg King
;
; char cpeekc (void);
;
.export _cpeekc
.import plot, popa
.include "zeropage.inc"
.include "c128.inc"
_cpeekc:
lda MODE
bmi @c80
ldy CURS_X
lda (SCREEN_PTR),y ; get char
@return:
and #<~$80 ; remove reverse flag
; 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
@c80:
lda SCREEN_PTR
ldy SCREEN_PTR+1
clc
adc CURS_X
bcc @s
iny
; get byte from VDC mem
@s: ldx #VDC_DATA_LO
stx VDC_INDEX
@L0: bit VDC_INDEX
bpl @L0
sta VDC_DATA
dex
stx VDC_INDEX
sty VDC_DATA
ldx #VDC_RAM_RW
stx VDC_INDEX
@L1: bit VDC_INDEX
bpl @L1 ; wait for blanking
lda VDC_DATA
jmp @return

56
libsrc/c128/cpeekcolor.s Normal file
View File

@@ -0,0 +1,56 @@
;
; 2016-02-28, Groepaz
; 2017-06-26, Greg King
;
; unsigned char cpeekcolor (void);
;
.export _cpeekcolor
.include "c128.inc"
_cpeekcolor:
bit MODE
bmi @c80
ldy CURS_X
lda (CRAM_PTR),y ; get color
and #$0F
ldx #>$0000
rts
@c80: lda CRAM_PTR
ldy CRAM_PTR+1
clc
adc CURS_X
bcc @s
iny
; get byte from VDC mem
@s: ldx #VDC_DATA_LO
stx VDC_INDEX
@L0: bit VDC_INDEX
bpl @L0
sta VDC_DATA
dex
stx VDC_INDEX
sty VDC_DATA
ldx #VDC_RAM_RW
stx VDC_INDEX
@L1: bit VDC_INDEX
bpl @L1 ; wait for blanking
lda VDC_DATA
and #$0F
; translate VDC->VIC colour
vdctovic:
ldy #$0F + 1
@L2: dey
cmp $CE5C,y
bne @L2
tya
ldx #>$0000
rts

51
libsrc/c128/cpeekrevers.s Normal file
View File

@@ -0,0 +1,51 @@
;
; 2016-02-28, Groepaz
; 2017-06-26, Greg King
;
; unsigned char cpeekrevers (void);
;
.export _cpeekrevers
.include "zeropage.inc"
.include "c128.inc"
_cpeekrevers:
lda MODE
bmi @c80
ldy CURS_X
lda (SCREEN_PTR),y ; get char
@return:
and #$80 ; get reverse flag
asl a
tax ; ldx #>$0000
rol a ; return boolean value
rts
@c80:
lda SCREEN_PTR
ldy SCREEN_PTR+1
clc
adc CURS_X
bcc @s
iny
; get byte from VDC mem
@s: ldx #VDC_DATA_LO
stx VDC_INDEX
@L0: bit VDC_INDEX
bpl @L0
sta VDC_DATA
dex
stx VDC_INDEX
sty VDC_DATA
ldx #VDC_RAM_RW
stx VDC_INDEX
@L1: bit VDC_INDEX
bpl @L1 ; wait for blanking
lda VDC_DATA
jmp @return

159
libsrc/c128/cpeeks.s Normal file
View File

@@ -0,0 +1,159 @@
;
; 2017-07-05, Greg King
; 2017-12-12, Groepaz
;
; void cpeeks (char* s, unsigned length);
;
.export _cpeeks
.import popax
.importzp ptr1, ptr2, ptr3, tmp1, tmp2
.macpack generic
; FIXME c128 needs special version that handles the 80-column VDC.
.include "c128.inc"
_cpeeks:
eor #<$FFFF ; counting a word upward is faster
sta ptr3 ; so, we use -(length + 1)
txa
eor #>$FFFF
sta ptr3+1
lda MODE
bmi c80
lda SCREEN_PTR
ldx SCREEN_PTR+1
sta ptr2
stx 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
;-----------------------------------------------------------
c80:
lda SCREEN_PTR
clc
adc CURS_X
sta ptr2
lda SCREEN_PTR+1
adc #0
sta ptr2+1
jsr popax
sta tmp1 ; (will be a .Y index)
stx ptr1+1
ldx #<$0000
stx ptr1
bze L3a ; branch always
L4a:
lda ptr2
ldy ptr2+1
inc ptr2
bne @s
inc ptr2+1
@s:
; get byte from VDC mem
ldx #VDC_DATA_LO
stx VDC_INDEX
@L0: bit VDC_INDEX
bpl @L0
sta VDC_DATA
dex
stx VDC_INDEX
sty VDC_DATA
ldx #VDC_RAM_RW
stx VDC_INDEX
@L1: bit VDC_INDEX
bpl @L1 ; wait for blanking
lda VDC_DATA
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 L5a
cmp #$60
blt @sk2 ;(bcc)
clc
@sk1: adc #$20
@sk2: ;clc ; both above cmp and adc clear carry flag
adc #$20
L5a: ldy tmp1
sta (ptr1),y
iny
bnz L1a
inc ptr1+1
L1a: sty tmp1
L3a: inc ptr3 ; count length
bnz L4a
inc ptr3+1
bnz L4a
lda #0 ; terminate the string
ldy tmp1
sta (ptr1),y
rts

View File

@@ -8,9 +8,9 @@
.export _cputcxy, _cputc, cputdirect, putchar
.export newline, plot
.import popa, _gotoxy
.import PLOT
.import gotoxy
.include "cbm_kernal.inc"
.include "c128.inc"
newline = NEWLINE
@@ -21,8 +21,7 @@ newline = NEWLINE
_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
@@ -63,10 +62,9 @@ cputdirect:
; Handle character if high bit set
L5: and #$7F
cmp #$7E ; PI?
cmp #$7F ; PI?
bne L6
lda #$5E ; Load screen code for PI
bne cputdirect
L6: ora #$40
bne cputdirect ; Branch always
@@ -86,4 +84,3 @@ plot: ldy CURS_X
; position in Y
putchar = $CC2F

View File

@@ -8,7 +8,7 @@
.import zerobss
.import push0, callmain
.import RESTOR, BSOUT, CLRCH
.import __RAM_START__, __RAM_SIZE__, __STACKSIZE__
.import __MAIN_START__, __MAIN_SIZE__, __STACKSIZE__
.importzp ST
.include "zeropage.inc"
@@ -56,10 +56,10 @@ L1: lda sp,x
tsx
stx spsave ; Save the system stack pointer
lda #<(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
sta sp
lda #>(__RAM_START__ + __RAM_SIZE__ + __STACKSIZE__)
sta sp+1 ; Set argument stack ptr
stx sp+1 ; Set argument stack ptr
; Call the module constructors.
@@ -108,7 +108,7 @@ L2: lda zpsave,x
; ------------------------------------------------------------------------
; Data
.segment "INITBSS"
.segment "INIT"
zpsave: .res zpspace

0
libsrc/c128/emd/c128-efnram.s Executable file → Normal file
View File

0
libsrc/c128/emd/c128-ifnram.s Executable file → Normal file
View File

View File

@@ -55,6 +55,8 @@ REU_TRIGGER = $FF00 ; REU command trigger
OP_COPYFROM = $ED
OP_COPYTO = $EC
OP_COPYFROM_ALOAD = $B1
OP_COPYTO_ALOAD = $B0
; ------------------------------------------------------------------------
; Data.
@@ -70,7 +72,7 @@ reu_params: .word $0000 ; Host address, lo, hi
.byte $00 ; Expansion bank no.
.word $0000 ; # bytes to move, lo, hi
.byte $00 ; Interrupt mask reg.
.byte $00 ; Adress control reg.
.byte $00 ; Address control reg.
.code
@@ -92,17 +94,56 @@ 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

View File

@@ -52,13 +52,11 @@ VDC_DATA = 31
; ------------------------------------------------------------------------
; Data.
.data
pagecount: .word 64 ; $0000-$3fff as 16k default
curpage: .word $ffff ; currently mapped-in page (invalid)
.bss
pagecount: .res 2 ; $0000-$3fff as 16k default
curpage: .res 2 ; currently mapped-in page (invalid)
vdc_cset_save: .res 1
window: .res 256 ; memory window
.code
@@ -71,11 +69,15 @@ window: .res 256 ; memory window
;
INSTALL:
; do test for VDC presence here???
; reset mapped-in page to invalid
lda #$ff
sta curpage
sta curpage+1
; do test for VDC presence here???
ldx #VDC_CSET ; determine size of RAM...
jsr vdcgetreg
sta tmp1
sta vdc_cset_save
ora #%00010000
jsr vdcputreg ; turn on 64k
@@ -94,6 +96,8 @@ INSTALL:
lda tmp2
jsr vdcputbyte ; restore original value of test byte
ldx #0 ; prepare x with hi of default pagecount
lda ptr1 ; do bytes match?
cmp ptr1+1
bne @have64k
@@ -101,17 +105,22 @@ INSTALL:
cmp ptr2+1
bne @have64k
ldx #VDC_CSET
lda tmp1
jsr vdcputreg ; restore 16/64k flag
jmp @endok ; and leave default values for 16k
lda #64 ; assumes x = 0, here -> p.c = 64
bne @setpagecnt
@have64k:
lda #<256
ldx #>256
txa ; assumes x = 0, here
inx ; so that a/x becomes 0/1 -> p.c. = 256
@setpagecnt:
sta pagecount
stx pagecount+1
@endok:
txa
bne @keep64kBit
ldx #VDC_CSET ; restore 16/64k flag
lda vdc_cset_save
jsr vdcputreg
@keep64kBit:
lda #<EM_ERR_OK
ldx #>EM_ERR_OK
rts
@@ -140,7 +149,7 @@ settestadr1:
ldy #$02 ; test page 2 (here)
.byte $2c
settestadr2:
ldy #$42 ; or page 64+2 (there)
ldy #$82 ; or page 64+2 (there)
lda #0
jmp vdcsetsrcaddr
@@ -199,6 +208,8 @@ transferin:
lda VDC_DATA_REG ; get 2 bytes at a time to speed-up
sta (ptr2),y ; (in fact up to 8 bytes could be fetched with special VDC config)
iny
@L1: bit VDC_ADDR_REG ; XXX: Test waiting for register 31
bpl @L1
lda VDC_DATA_REG
sta (ptr2),y
iny
@@ -326,14 +337,15 @@ COPYTO:
;
vdcsetsrcaddr:
ldx #VDC_DATA_LO
ldx #VDC_DATA_HI
stx VDC_ADDR_REG
@L0: bit VDC_ADDR_REG
bpl @L0
sta VDC_DATA_REG
dex
tya
sty VDC_DATA_REG
inx
stx VDC_ADDR_REG
@L1: bit VDC_ADDR_REG ; XXX: Test waiting for register 18
bpl @L1
sta VDC_DATA_REG
rts

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

21
libsrc/c128/isfast.s Normal file
View File

@@ -0,0 +1,21 @@
;
; Marco van den Heuvel, 2018-03-19
;
; unsigned char isfast (void);
; /* Returns 1 if the CPU is in 2MHz mode. */
;
.export _isfast
.include "c128.inc"
.proc _isfast
lda VIC_CLK_128
and #$01
ldx #$00
rts
.endproc

View File

@@ -30,24 +30,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

View File

@@ -30,24 +30,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 not used
; ------------------------------------------------------------------------
; Constants
@@ -104,7 +92,7 @@ joy1: lda #$7F
sei
sta CIA1_PRA
lda CIA1_PRB
cli
back: cli
and #$1F
eor #$1F
rts
@@ -118,9 +106,4 @@ joy2: ldx #0
sta CIA1_DDRA
lda CIA1_PRA
sty CIA1_DDRA
cli
and #$1F
eor #$1F
rts
jmp back

View File

@@ -20,6 +20,3 @@ L9: rts
.endproc

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

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

View File

@@ -1,9 +1,20 @@
;
; Ullrich von Bassewitz, 19.11.2002
;
; C128 kernal functions
; C128 Kernal functions
;
.include "cbm_kernal.inc"
.export KBDREAD
.export CLRSCR
.export PRINT
.export NEWLINE
.export CURS_SET
.export CURS_ON
.export CURS_OFF
.export NMIEXIT
.export C64MODE
.export SWAPPER
.export SETBNK
@@ -35,7 +46,9 @@
.export CKOUT
.export CLRCH
.export BASIN
.export CHRIN
.export BSOUT
.export CHROUT
.export LOAD
.export SAVE
.export SETTIM
@@ -47,54 +60,3 @@
.export SCREEN
.export PLOT
.export IOBASE
;-----------------------------------------------------------------------------
; All functions are available in the kernal jump table
; Extended jump table
C64MODE = $FF4D
SWAPPER = $FF5F
SETBNK = $FF68
;
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
PLOT = $FFF0
IOBASE = $FFF3

View File

@@ -25,6 +25,7 @@
.constructor initmainargs, 24
.import __argc, __argv
.include "cbm_kernal.inc"
.include "c128.inc"
@@ -32,10 +33,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:
@@ -127,7 +128,7 @@ done: lda #<argv
stx __argv + 1
rts
.segment "INITBSS"
.segment "INIT"
term: .res 1
name: .res NAME_LEN + 1

View File

@@ -19,17 +19,17 @@
; 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_MEM = $0E00 ; Memory location
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_MEM = $0E00 ; Memory location
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

@@ -4,7 +4,7 @@
;
; 2009-09-26, Ullrich von Bassewitz
; 2014-04-26, Christian Groessler
; 2014-04-30, Greg King
; 2020-07-14, Greg King
;
.include "zeropage.inc"
@@ -377,7 +377,7 @@ IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls, for now
IRQ: jsr CPREP
lda KEY_COUNT
sta old_key_count
lda #$7F
lda #$FF
sta CIA1_PRA
lda CIA1_PRB ; Read joystick #0
and #$1F

View File

@@ -2,7 +2,7 @@
; Driver for the Inkwell Systems 170-C and 184-C lightpens.
;
; 2014-04-26, Christian Groessler
; 2014-09-10, Greg King
; 2020-07-14, Greg King
;
.include "zeropage.inc"
@@ -414,8 +414,8 @@ IRQ: jsr CPREP
ldy #%00000000 ; Set ports A and B to input
sty CIA1_DDRB
sty CIA1_DDRA ; Keyboard won't look like buttons
;lda #%01111111 ; (Keyboard scan leaves this in port A)
;sta CIA1_PRA
lda #%11111111
sta CIA1_PRA
lda CIA1_PRB ; Read Control Port 1
dec CIA1_DDRA ; Set port A back to output
eor #%11111111 ; Bit goes up when button goes down

View File

@@ -3,7 +3,7 @@
;
; 2009-09-26, Ullrich von Bassewitz
; 2014-04-26, Christian Groessler
; 2014-05-01, Greg King
; 2020-07-14, Greg King
;
.include "zeropage.inc"
@@ -379,7 +379,7 @@ IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls for now
IRQ: jsr CPREP
lda KEY_COUNT
sta old_key_count
lda #$7F
lda #$FF
sta CIA1_PRA
lda CIA1_PRB ; Read joystick #0
and #$1F

View File

@@ -4,7 +4,7 @@
; 2006-08-20, Stefan Haubenthal
; 2009-09-26, Ullrich von Bassewitz
; 2014-04-26, Christian Groessler
; 2014-05-05, Greg King
; 2020-07-14, Greg King
;
.include "zeropage.inc"
@@ -385,7 +385,7 @@ IOCTL: lda #<MOUSE_ERR_INV_IOCTL ; We don't support ioctls for now
IRQ: jsr CPREP
lda KEY_COUNT
sta old_key_count
lda #$7F
lda #$FF
sta CIA1_PRA
lda CIA1_PRB ; Read port #1
eor #%11111111 ; Make all bits active high

View File

@@ -1,11 +1,12 @@
;
; Callback routine called from the IRQ handler after the ROM IRQ handler
; had been run.
; Callback routine, called from the IRQ handler after the ROM IRQ handler
; has been run.
;
; Christian Groessler, 24.04.2014
; 2014-04-24, Christian Groessler
; 2020-07-14, Greg King
;
; Check if there was button/joystick activity before and/or after the ROM handler.
; If there was activity, discard the key presses since they are most
; If there was activity, discard the key presses because they are most
; probably "phantom" key presses.
callback:
@@ -16,7 +17,7 @@ callback:
lda OLD_BUTTONS ; keypress before?
bne @discard_key ; yes, discard key
lda #$7F
lda #$FF
sta CIA1_PRA
lda CIA1_PRB ; Read joystick #0
and #$1F

View File

@@ -45,15 +45,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
@@ -155,11 +155,11 @@ Vector := *+1
.reloc
;----------------------------------------------------------------------------
; 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
@@ -192,10 +192,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
@@ -212,7 +212,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
@@ -283,11 +283,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
@@ -305,12 +305,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
@@ -349,11 +350,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
@@ -383,23 +384,25 @@ 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
@@ -407,7 +410,7 @@ IOCTL: lda #<SER_ERR_INV_IOCTL ; We don't support ioclts for now
; IRQ: Not used on the C128
;
IRQ = $0000
SER_IRQ = $0000
;----------------------------------------------------------------------------
;
@@ -500,5 +503,3 @@ InitBuffers:
stx RecvFreeCnt
stx SendFreeCnt
rts

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

880
libsrc/c128/tgi/c128-hi.s Normal file
View File

@@ -0,0 +1,880 @@
;
; Graphics driver for the 320x200x2 mode on the C128.
;
; Based on Stephen L. Judd's GRLIB code.
;
; 2018-03-13, Sven Klose
; 2018-07-22, Scott Hutter
; 2018-07-28, Greg King
;
.include "zeropage.inc"
.include "tgi-kernel.inc"
.include "tgi-error.inc"
.include "c128.inc"
.macpack generic
.macpack module
; ------------------------------------------------------------------------
; Header. Includes jump table and constants.
module_header _c128_hi_tgi
; First part of the header is a structure that has a magic and defines the
; capabilities of the driver
.byte $74, $67, $69 ; "tgi"
.byte TGI_API_VERSION ; TGI API version number
.addr $0000 ; Library reference
.word 320 ; X resolution
.word 200 ; Y resolution
.byte 2 ; Number of drawing colors
.byte 1 ; Number of screens available
.byte 8 ; System font X size
.byte 8 ; System font Y size
.word $00D4 ; Aspect ratio (based on 4/3 display)
.byte 0 ; TGI driver flags
; Next comes the jump table. With the exception of IRQ, all entries must be
; valid and may point to an RTS for test versions (function not implemented).
.addr INSTALL
.addr UNINSTALL
.addr INIT
.addr DONE
.addr GETERROR
.addr CONTROL
.addr CLEAR
.addr SETVIEWPAGE
.addr SETDRAWPAGE
.addr SETCOLOR
.addr SETPALETTE
.addr GETPALETTE
.addr GETDEFPALETTE
.addr SETPIXEL
.addr GETPIXEL
.addr LINE
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
; ------------------------------------------------------------------------
; Data.
; Variables mapped to the zero page segment variables. Some of these are
; used for passing parameters to the driver.
X1 := ptr1
Y1 := ptr2
X2 := ptr3
Y2 := ptr4
TEXT := ptr3
TEMP := tmp4
TEMP2 := sreg
POINT := regsave
CHUNK := X2 ; Used in the line routine
OLDCHUNK := X2+1 ; Ditto
; Absolute variables used in the code
.bss
ERROR: .res 1 ; Error code
PALETTE: .res 2 ; The current palette
BITMASK: .res 1 ; $00 = clear, $FF = set pixels
; Line routine stuff
DX: .res 2
DY: .res 2
; BAR variables
X1SAVE: .res 2
Y1SAVE: .res 1
X2SAVE: .res 2
Y2SAVE: .res 1
; Text output stuff
TEXTMAGX: .res 1
TEXTMAGY: .res 1
TEXTDIR: .res 1
; Constants and tables
.rodata
DEFPALETTE: .byte $00, $01 ; White on black
PALETTESIZE = * - DEFPALETTE
BITTAB: .byte $80,$40,$20,$10,$08,$04,$02,$01
BITCHUNK: .byte $FF,$7F,$3F,$1F,$0F,$07,$03,$01
CHARROM := $D000 ; Character ROM base address
VBASE := $C000 ; Video memory base address
CBASE := $E000 ; Color memory base address
.code
; ------------------------------------------------------------------------
; INSTALL routine. Is called after the driver is loaded into memory. May
; initialize anything that has to be done just once. Is probably empty
; most of the time.
;
; Must set an error code: NO
;
INSTALL:
; rts ; fall through
; ------------------------------------------------------------------------
; UNINSTALL routine. Is called before the driver is removed from memory. May
; clean up anything done by INSTALL but is probably empty most of the time.
;
; Must set an error code: NO
;
UNINSTALL:
rts
; ------------------------------------------------------------------------
; INIT: Changes an already installed device from text mode to graphics
; mode.
; Note that INIT/DONE may be called multiple times while the driver
; is loaded, while INSTALL is only called once, so any code that is needed
; to initializes variables and so on must go here. Setting palette and
; clearing the screen is not needed because this is called by the graphics
; kernel later.
; The graphics kernel will never call INIT when a graphics mode is already
; active, so there is no need to protect against that.
;
; Must set an error code: YES
;
INIT:
; Initialize variables.
ldx #$FF ; Foreground color
stx BITMASK
; Switch into graphics mode.
; Select a video bank:
; bank 0 = $03 ($0000-$3FFF) (default)
; bank 1 = $02 ($4000-$7FFF)
; bank 2 = $01 ($8000-$BFFF)
; bank 3 = $00 ($C000-$FFFF) (TGI)
lda CIA2_PRA
and #<~$03 ; Bank 3
sta CIA2_PRA
lda #$80 ; color-map at $E000, bitmap at $C000
sta VM2
; Make the VIC-IIe read RAM instead of the font ROM.
lda #%00000100
sta CHARDIS
; Switch to bitmap mode.
lda #%00100000
sta GRAPHM
lda #TGI_ERR_OK
sta ERROR
rts
; ------------------------------------------------------------------------
; DONE: Will be called to switch the graphics device back into text mode.
; The graphics kernel will never call DONE when no graphics mode is active,
; so there is no need to protect against that.
;
; Must set an error code: NO
;
DONE:
; Select the text video bank.
lda CIA2_PRA
ora #$03 ; Bank 0
sta CIA2_PRA
; Make the VIC-IIe read the font ROM instead of RAM.
lda #%00000000
sta CHARDIS
;lda #%00000000 ; Switch back to text mode
sta GRAPHM
; Restore a value that's needed by BASIC's GRAPHIC 1 statement.
lda #$78 ; color-map at $1C00, bitmap at $2000
sta VM2
rts
; ------------------------------------------------------------------------
; GETERROR: Return the error code in A and clear it.
GETERROR:
ldx #TGI_ERR_OK
lda ERROR
stx ERROR
rts
; ------------------------------------------------------------------------
; CONTROL: Platform/driver specific entry point.
;
; Must set an error code: YES
;
CONTROL:
lda #TGI_ERR_INV_FUNC
sta ERROR
rts
; ------------------------------------------------------------------------
; CLEAR: Clears the screen.
;
; Must set an error code: NO
;
CLEAR:
ldy #$00
tya
ldx #MMU_CFG_RAM0
sei
stx MMU_CR
@L1: sta VBASE+$0000,y
sta VBASE+$0100,y
sta VBASE+$0200,y
sta VBASE+$0300,y
sta VBASE+$0400,y
sta VBASE+$0500,y
sta VBASE+$0600,y
sta VBASE+$0700,y
sta VBASE+$0800,y
sta VBASE+$0900,y
sta VBASE+$0A00,y
sta VBASE+$0B00,y
sta VBASE+$0C00,y
sta VBASE+$0D00,y
sta VBASE+$0E00,y
sta VBASE+$0F00,y
sta VBASE+$1000,y
sta VBASE+$1100,y
sta VBASE+$1200,y
sta VBASE+$1300,y
sta VBASE+$1400,y
sta VBASE+$1500,y
sta VBASE+$1600,y
sta VBASE+$1700,y
sta VBASE+$1800,y
sta VBASE+$1900,y
sta VBASE+$1A00,y
sta VBASE+$1B00,y
sta VBASE+$1C00,y
sta VBASE+$1D00,y
sta VBASE+$1E00,y
sta VBASE+$1F00,y
iny
bne @L1
ldx #MMU_CFG_CC65
stx MMU_CR
cli
rts
; ------------------------------------------------------------------------
; SETVIEWPAGE: Set the visible page. Called with the new page in A (0..n).
; The page number is already checked to be valid by the graphics kernel.
;
; Must set an error code: NO (will only be called if page ok)
;
SETVIEWPAGE:
; rts ; fall through
; ------------------------------------------------------------------------
; SETDRAWPAGE: Set the drawable page. Called with the new page in A (0..n).
; The page number is already checked to be valid by the graphics kernel.
;
; Must set an error code: NO (will only be called if page ok)
;
SETDRAWPAGE:
rts
; ------------------------------------------------------------------------
; SETCOLOR: Set the drawing color (in A). The new color is already checked
; to be in a valid range (0..maxcolor-1).
;
; Must set an error code: NO (will only be called if color ok)
;
SETCOLOR:
tax
beq @L1
lda #$FF
@L1: sta BITMASK
rts
; ------------------------------------------------------------------------
; SETPALETTE: Set the palette (not available with all drivers/hardware).
; A pointer to the palette is passed in ptr1. Must set an error if palettes
; are not supported
;
; Must set an error code: YES
;
SETPALETTE:
ldy #PALETTESIZE - 1
@L1: lda (ptr1),y ; Copy the palette
and #$0F ; Make a valid color
sta PALETTE,y
dey
bpl @L1
; Get the color entries from the palette
lda PALETTE+1 ; Foreground color
asl a
asl a
asl a
asl a
ora PALETTE ; Background color
; Initialize the color map with the new color settings (it is below the
; Kernal ROM).
ldy #$00
ldx #MMU_CFG_RAM0
sei
stx MMU_CR
@L2: sta CBASE+$0000,y
sta CBASE+$0100,y
sta CBASE+$0200,y
sta CBASE+$02e8,y
iny
bne @L2
ldx #MMU_CFG_CC65
stx MMU_CR
cli
; Done, reset the error code
lda #TGI_ERR_OK
sta ERROR
rts
; ------------------------------------------------------------------------
; GETPALETTE: Return the current palette in A/X. Even drivers that cannot
; set the palette should return the default palette here, so there's no
; way for this function to fail.
;
; Must set an error code: NO
;
GETPALETTE:
lda #<PALETTE
ldx #>PALETTE
rts
; ------------------------------------------------------------------------
; GETDEFPALETTE: Return the default palette for the driver in A/X. All
; drivers should return something reasonable here, even drivers that don't
; support palettes, otherwise the caller has no way to determine the colors
; of the (not changeable) palette.
;
; Must set an error code: NO (all drivers must have a default palette)
;
GETDEFPALETTE:
lda #<DEFPALETTE
ldx #>DEFPALETTE
rts
; ------------------------------------------------------------------------
; SETPIXEL: Draw one pixel at X1/Y1 = ptr1/ptr2 with the current drawing
; color. The coordinates passed to this function are never outside the
; visible screen area, so there is no need for clipping inside this function.
;
; Must set an error code: NO
;
SETPIXEL:
jsr CALC ; Calculate coordinates
lda #MMU_CFG_RAM0 ; Work behind ROMs
sei
sta MMU_CR
lda (POINT),Y
eor BITMASK
and BITTAB,X
eor (POINT),Y
sta (POINT),Y
ldx #MMU_CFG_CC65
stx MMU_CR
cli
rts
; ------------------------------------------------------------------------
; GETPIXEL: Read the color value of a pixel and return it in A/X. The
; coordinates passed to this function are never outside the visible screen
; area, so there is no need for clipping inside this function.
GETPIXEL:
jsr CALC ; Calculate coordinates
lda #MMU_CFG_RAM0 ; Work behind ROMs
sei
sta MMU_CR
lda (POINT),Y
and BITTAB,X
beq @L1
lda #$01 ; Foreground color
@L1: ldy #MMU_CFG_CC65
sty MMU_CR
cli
ldx #$00 ; Clear high byte
rts
; ------------------------------------------------------------------------
; 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.
;
; X1,X2 etc. are set up above (x2=LINNUM in particular)
; Format is LINE x2,y2,x1,y1
;
; Must set an error code: NO
;
LINE:
@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
ldy Y1
sta Y1
sty Y2
lda Y2+1
ldy Y1+1
sta Y1+1
sty Y2+1
lda X1
ldy X2
sty X1
sta X2
lda X2+1
ldy X1+1
sta X1+1
sty X2+1
bcc @CHECK
@CONT: sta DX+1
stx DX
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
sec
sbc Y2
tay
ldx #$88 ;DEY
@DYPOS: sty DY ; 8-bit DY -- FIX ME?
stx YINCDEC
stx XINCDEC
jsr CALC ; Set up .X, .Y, and POINT
lda BITCHUNK,X
sta OLDCHUNK
sta CHUNK
lda #MMU_CFG_RAM0 ; Work behind ROMs
sei
sta MMU_CR
ldx DY
cpx DX ;Who's bigger: dy or dx?
bcc STEPINX ;If dx, then...
lda DX+1
bne STEPINX
;
; Big steps in Y
;
; To simplify my life, just use PLOT to plot points.
;
; No more!
; Added special plotting routine -- cool!
;
; X is now counter, Y is y-coordinate
;
; On entry, X=DY=number of loop iterations, and Y=
; Y1 AND #$07
STEPINY:
lda #00
sta OLDCHUNK ;So plotting routine will work right
lda CHUNK
lsr ;Strip the bit
eor CHUNK
sta CHUNK
txa
beq YCONT2 ;If dy=0, it's just a point
@CONT: lsr ;Init counter to dy/2
;
; Main loop
;
YLOOP: sta TEMP
lda (POINT),y
eor BITMASK
and CHUNK
eor (POINT),y
sta (POINT),y
YINCDEC:
iny ;Advance Y coordinate
cpy #8
bcc @CONT ;No prob if Y=0..7
jsr FIXY
@CONT: lda TEMP ;Restore A
sec
sbc DX
bcc YFIXX
YCONT: dex ;X is counter
bne YLOOP
YCONT2: lda (POINT),y ;Plot endpoint
eor BITMASK
and CHUNK
eor (POINT),y
sta (POINT),y
ldx #MMU_CFG_CC65
stx MMU_CR
cli
rts
YFIXX: ;x=x+1
adc DY
lsr CHUNK
bne YCONT ;If we pass a column boundary...
ror CHUNK ;then reset CHUNK to $80
sta TEMP2
lda POINT ;And add 8 to POINT
adc #8
sta POINT
bcc @CONT
inc POINT+1
@CONT: lda TEMP2
dex
bne YLOOP
beq YCONT2
;
; Big steps in X direction
;
; On entry, X=DY=number of loop iterations, and Y=
; Y1 AND #$07
.bss
COUNTHI:
.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
txa
bne @CONT ;Could be $100
dec COUNTHI
@CONT: ror
;
; Main loop
;
XLOOP: lsr CHUNK
beq XFIXC ;If we pass a column boundary...
XCONT1: sbc DY
bcc XFIXY ;Time to step in Y?
XCONT2: dex
bne XLOOP
dec COUNTHI ;High bits set?
bpl XLOOP
lsr CHUNK ;Advance to last point
jsr LINEPLOT ;Plot the last chunk
ldx #MMU_CFG_CC65
stx MMU_CR
cli
rts
;
; CHUNK has passed a column, so plot and increment pointer
; and fix up CHUNK, OLDCHUNK.
;
XFIXC: sta TEMP
jsr LINEPLOT
lda #$FF
sta CHUNK
sta OLDCHUNK
lda POINT
clc
adc #8
sta POINT
lda TEMP
bcc XCONT1
inc POINT+1
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
bpl XCONT2
adc DX
sta TEMP
lda DX+1
adc #$FF ;Hi byte
sta Y1
jsr LINEPLOT ;Plot chunk
lda CHUNK
sta OLDCHUNK
lda TEMP
XINCDEC:
iny ;Y-coord
cpy #8 ;0..7 is ok
bcc XCONT2
sta TEMP
jsr FIXY
lda TEMP
jmp XCONT2
;
; Subroutine to plot chunks/points (to save a little
; room, gray hair, etc.)
;
LINEPLOT: ; Plot the line chunk
lda (POINT),Y
eor BITMASK
ora CHUNK
and OLDCHUNK
eor CHUNK
eor (POINT),Y
sta (POINT),Y
rts
;
; Subroutine to fix up pointer when Y decreases through
; zero or increases through 7.
;
FIXY: cpy #255 ;Y=255 or Y=8
beq @DECPTR
@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
rts
@DECPTR: ;Okay, subtract 320 then
ldy #7 ;Y decreased through 0
lda POINT
sec
sbc #<320
sta POINT
lda POINT+1
sbc #>320
sta POINT+1
rts
; ------------------------------------------------------------------------
; 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.
; Contrary to most other functions, the graphics kernel will sort and clip
; the coordinates before calling the driver, so on entry the following
; conditions are valid:
; X1 <= X2
; Y1 <= Y2
; (X1 >= 0) && (X1 < XRES)
; (X2 >= 0) && (X2 < XRES)
; (Y1 >= 0) && (Y1 < YRES)
; (Y2 >= 0) && (Y2 < YRES)
;
; Must set an error code: NO
;
; Note: This function needs optimization. It's just a cheap translation of
; the original C wrapper and could be written much smaller (besides that,
; calling LINE is not a good idea either).
BAR:
lda X2
sta X2SAVE
lda X2+1
sta X2SAVE+1
lda Y2
sta Y2SAVE
lda X1
sta X1SAVE
lda X1+1
sta X1SAVE+1
lda Y1
sta Y1SAVE
@L1: sta Y2
lda #>200
sta Y1+1
sta Y2+1
jsr LINE
lda Y1SAVE
cmp Y2SAVE
beq @L4
inc Y1SAVE
lda X1SAVE
sta X1
lda X1SAVE+1
sta X1+1
lda X2SAVE
sta X2
lda X2SAVE+1
sta X2+1
lda Y1SAVE
sta Y1
jmp @L1
@L4: rts
; ------------------------------------------------------------------------
; TEXTSTYLE: Set the style used when calling OUTTEXT. Text scaling in X and Y
; direction is passend in X/Y, the text direction is passed in A.
;
; Must set an error code: NO
;
TEXTSTYLE:
stx TEXTMAGX
sty TEXTMAGY
sta TEXTDIR
rts
; ------------------------------------------------------------------------
; OUTTEXT: Output text at X/Y = ptr1/ptr2 using the current color and the
; current text style. The text to output is given as a zero terminated
; string with address in ptr3.
;
; Must set an error code: NO
;
OUTTEXT:
; Calculate a pointer to the representation of the character in the
; character ROM
ldx #((>(CHARROM + $0800)) >> 3)
ldy #0
lda (TEXT),y
bmi @L1
ldx #((>(CHARROM + $0000)) >> 3)
@L1: stx ptr4+1
asl a
rol ptr4+1
asl a
rol ptr4+1
asl a
rol ptr4+1
sta ptr4
rts
; ------------------------------------------------------------------------
; Calculate all variables to plot the pixel at X1/Y1.
CALC: lda Y1
sta TEMP2
and #7
tay
lda Y1+1
lsr ; Neg is possible
ror TEMP2
lsr
ror TEMP2
lsr
ror TEMP2
lda #00
sta POINT
lda TEMP2
cmp #$80
ror
ror POINT
cmp #$80
ror
ror POINT ; row*64
adc TEMP2 ; +row*256
clc
adc #>VBASE ; +bitmap base
sta POINT+1
lda X1
tax
and #$F8
clc
adc POINT ; +(X AND #$F8)
sta POINT
lda X1+1
adc POINT+1
sta POINT+1
txa
and #7
tax
rts

View File

@@ -88,7 +88,6 @@ pages: .byte 1 ; Number of screens available
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
.addr 0 ; IRQ entry is unused
; ------------------------------------------------------------------------
; Data.

View File

@@ -89,7 +89,6 @@ pages: .byte 0 ; Number of screens available
.addr BAR
.addr TEXTSTYLE
.addr OUTTEXT
.addr 0 ; IRQ entry is unused
; ------------------------------------------------------------------------
; Data.

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 "c128.inc"
.include "get_tv.inc"
.constructor initsystime
.importzp tmp1, tmp2
.export TM, load_tenth
.constructor inittime
.importzp sreg
.import _get_tv
;----------------------------------------------------------------------------
.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

30
libsrc/c128/waitvsync.s Normal file
View File

@@ -0,0 +1,30 @@
;
; Written by Groepaz <groepaz@gmx.net>
;
; void waitvsync (void);
;
.export _waitvsync
.include "c128.inc"
_waitvsync:
bit MODE
bmi @c80
@l1:
bit VIC_CTRL1
bpl @l1
@l2:
bit VIC_CTRL1
bmi @l2
rts
@c80:
;FIXME: do we have to switch banks?
@l3:
lda VDC_INDEX
and #$20
beq @l3
rts