Merge branch 'cc65:master' into master

This commit is contained in:
rumbledethumps
2024-02-17 14:54:12 -08:00
committed by GitHub
41 changed files with 3044 additions and 228 deletions

View File

@@ -13,6 +13,7 @@
.import _strlower, _strlen
.macpack generic
.macpack cpu
; ----------------------------------------------------------------------------
; We will store variables into the register bank in the zeropage. Define
@@ -37,7 +38,11 @@ FCount = ptr2
GetFormatChar:
ldy #0
.if (.cpu .bitand ::CPU_ISET_65SC02)
lda (Format)
.else
lda (Format),y
.endif
IncFormatPtr:
inc Format
bne @L1
@@ -110,7 +115,11 @@ GetIntArg:
lda (ArgList),y
tax
dey
.if (.cpu .bitand ::CPU_ISET_65SC02)
lda (ArgList)
.else
lda (ArgList),y
.endif
rts
; ----------------------------------------------------------------------------
@@ -135,9 +144,9 @@ ReadInt:
pha ; Save digit value
lda ptr1
ldx ptr1+1
asl ptr1
asl a
rol ptr1+1 ; * 2
asl ptr1
asl a
rol ptr1+1 ; * 4, assume carry clear
adc ptr1
sta ptr1
@@ -265,10 +274,16 @@ Save: lda regbank,y
; Initialize the output counter in the output descriptor to zero
lda #0
.if (.cpu .bitand ::CPU_ISET_65SC02)
sta (OutData)
ldy #$01
sta (OutData),y
.else
tay
sta (OutData),y
iny
sta (OutData),y
.endif
; Get the output function from the output descriptor and remember it
@@ -338,7 +353,11 @@ MainLoop:
sta (sp),y
dey
lda FCount
.if (.cpu .bitand ::CPU_ISET_65SC02)
sta (sp)
.else
sta (sp),y
.endif
jsr CallOutFunc ; Call the output function
; We're back from out(), or we didn't call it. Check for end of string.
@@ -551,10 +570,16 @@ CheckCount:
jsr GetIntArg
sta ptr1
stx ptr1+1 ; Get user supplied pointer
.if (.cpu .bitand ::CPU_ISET_65SC02)
lda (OutData) ; Low byte of OutData->ccount
sta (ptr1)
ldy #1
.else
ldy #0
lda (OutData),y ; Low byte of OutData->ccount
sta (ptr1),y
iny
.endif
lda (OutData),y ; High byte of OutData->ccount
sta (ptr1),y
jmp MainLoop ; Done

View File

@@ -0,0 +1,24 @@
;
; Colin Leroy-Mira, 2024
;
; Helper to check for file opened, not eof, not ferror
; Expects file pointer in ptr1,
; Returns with Z flag set if everything is OK,
; Destroys A, X, Y,
; Sets file flags in A
;
.export checkferror
.importzp ptr1
.include "_file.inc"
checkferror:
ldy #_FILE::f_flags
lda (ptr1),y
tax
and #(_FOPEN|_FERROR|_FEOF); Check for file open, error/eof
tay
txa
cpy #_FOPEN
rts

View File

@@ -5,31 +5,33 @@
;
.export _fgetc
.import _read, pusha0, pushax, popptr1, incsp2, returnFFFF
.import _read, checkferror
.import pusha0, pushax, popptr1, incsp2, returnFFFF
.importzp ptr1
.include "stdio.inc"
.include "_file.inc"
.macpack cpu
_fgetc:
sta ptr1
stx ptr1+1
jsr pushax ; Backup our ptr
ldy #_FILE::f_flags
lda (ptr1),y
tax
and #_FOPEN ; Check for file open
beq ret_eof
txa
and #(_FERROR|_FEOF); Check for error/eof
jsr checkferror
bne ret_eof
txa
.if (.cpu .bitand ::CPU_ISET_65SC02)
bit #_FPUSHBACK ; Check for pushed back char
beq do_read
.else
tax
and #_FPUSHBACK ; Check for pushed back char
beq do_read
txa
.endif
and #<(~_FPUSHBACK) ; Reset flag
sta (ptr1),y

View File

@@ -90,9 +90,7 @@ read_loop:
: cmp #$0A ; Stop at \n
beq done
clc
bcc read_loop
bne read_loop
got_eof:
lda didread

View File

@@ -1,41 +0,0 @@
/*
** fputc.c
**
** Ullrich von Bassewitz, 02.06.1998
*/
#include <stdio.h>
#include <unistd.h>
#include "_file.h"
/*****************************************************************************/
/* Code */
/*****************************************************************************/
int __fastcall__ fputc (int c, register FILE* f)
{
/* Check if the file is open or if there is an error condition */
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
goto ReturnEOF;
}
/* Write the byte */
if (write (f->f_fd, &c, 1) != 1) {
/* Error */
f->f_flags |= _FERROR;
ReturnEOF:
return EOF;
}
/* Return the byte written */
return c & 0xFF;
}

66
libsrc/common/fputc.s Normal file
View File

@@ -0,0 +1,66 @@
;
; Colin Leroy-Mira, 2024
;
; int __fastcall__ fputc (int c, FILE* f);
;
.export _fputc
.importzp ptr1
.import _write, checkferror
.import pushax, pusha0, popax, incsp2
.import pushptr1, popptr1, returnFFFF
.include "stdio.inc"
.include "_file.inc"
_fputc:
sta ptr1
stx ptr1+1
jsr popax ; Get char, as we'll have
sta c ; to return it anyway
stx c+1
jsr checkferror
bne ret_eof
jsr pushptr1 ; Backup fp pointer
; Push _write parameters
ldy #_FILE::f_fd
lda (ptr1),y
jsr pusha0
lda #<c
ldx #>c
jsr pushax
lda #$01
ldx #$00
; Write
jsr _write
; Check for errors
cmp #$01
bne set_ferror
; Return char
lda c
ldx #$00
jmp incsp2 ; Drop fp pointer copy
ret_eof:
jmp returnFFFF
set_ferror:
jsr popptr1
lda #_FERROR
ldy #_FILE::f_flags
ora (ptr1),y
sta (ptr1),y
jmp returnFFFF
.bss
c: .res 2

View File

@@ -1,28 +0,0 @@
/*
** int fputs (const char* s, FILE* f);
**
** Ullrich von Bassewitz, 11.08.1998
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "_file.h"
int __fastcall__ fputs (const char* s, register FILE* f)
{
/* Check if the file is open or if there is an error condition */
if ((f->f_flags & _FOPEN) == 0 || (f->f_flags & (_FERROR | _FEOF)) != 0) {
return EOF;
}
/* Write the string */
return write (f->f_fd, s, strlen (s));
}

36
libsrc/common/fputs.s Normal file
View File

@@ -0,0 +1,36 @@
;
; Colin Leroy-Mira, 2024
;
; int __fastcall__ fputs (const char* s, register FILE* f)
;
.export _fputs
.importzp ptr1, ptr2
.import _write, _strlen, checkferror
.import swapstk, pushax, returnFFFF
.include "stdio.inc"
.include "_file.inc"
_fputs:
sta ptr1
stx ptr1+1
jsr checkferror
bne ret_eof
; Push _write parameters
ldy #_FILE::f_fd
lda (ptr1),y
ldx #$00
jsr swapstk ; Push fd, get s
jsr pushax ; Push s
jsr _strlen ; Get length
; Write
jmp _write
ret_eof:
jmp returnFFFF

View File

@@ -20,6 +20,7 @@
.include "_file.inc"
.macpack generic
.macpack cpu
; ------------------------------------------------------------------------
; Code
@@ -47,13 +48,21 @@
ldy #_FILE::f_flags
lda (file),y
.if (.cpu .bitand ::CPU_ISET_65SC02)
bit #_FOPEN ; Is the file open?
.else
and #_FOPEN ; Is the file open?
.endif
beq @L1 ; Branch if no
; Check if the stream is in an error state
.if (.cpu .bitand ::CPU_ISET_65SC02)
bit #_FERROR
.else
lda (file),y ; get file->f_flags again
and #_FERROR
.endif
beq @L2
; File not open or in error state
@@ -65,11 +74,19 @@
; Remember if we have a pushed back character and reset the flag.
@L2: tax ; X = 0
@L2: .if (.cpu .bitand ::CPU_ISET_65SC02)
ldx #$00
bit #_FPUSHBACK
.else
tax ; X = 0
lda (file),y
and #_FPUSHBACK
.endif
beq @L3
.if (.not .cpu .bitand ::CPU_ISET_65SC02)
lda (file),y
.endif
and #<~_FPUSHBACK
sta (file),y ; file->f_flags &= ~_FPUSHBACK;
inx ; X = 1
@@ -118,12 +135,20 @@
; Copy the buffer pointer into ptr1, and increment the pointer value passed
; to read() by one, so read() starts to store data at buf+1.
.if (.cpu .bitand ::CPU_ISET_65SC02)
lda (sp)
sta ptr1
add #1
sta (sp)
ldy #1
.else
ldy #0
lda (sp),y
sta ptr1
add #1
sta (sp),y
iny
.endif
lda (sp),y
sta ptr1+1
adc #0
@@ -134,8 +159,12 @@
ldy #_FILE::f_pushback
lda (file),y
.if (.cpu .bitand ::CPU_ISET_65SC02)
sta (ptr1) ; *buf = file->f_pushback;
.else
ldy #0
sta (ptr1),y ; *buf = file->f_pushback;
.endif
; Restore the low byte of count and decrement count by one. This may result
; in count being zero, so check for that.
@@ -210,4 +239,3 @@
.bss
save: .res 2
pb: .res 1

View File

@@ -8,7 +8,7 @@
.export _fwrite
.import _write
.import pushax, incsp6, addysp, ldaxysp, pushwysp, return0
.import pushax, pusha0, incsp6, addysp, ldaxysp, pushwysp, return0
.import tosumulax, tosudivax
.importzp ptr1
@@ -16,6 +16,7 @@
.include "errno.inc"
.include "_file.inc"
.macpack cpu
; ------------------------------------------------------------------------
; Code
@@ -33,7 +34,11 @@
ldy #_FILE::f_flags
lda (ptr1),y
.if (.cpu .bitand ::CPU_ISET_65SC02)
bit #_FOPEN
.else
and #_FOPEN ; Is the file open?
.endif
bne @L2 ; Branch if yes
; File not open
@@ -45,7 +50,9 @@
; Check if the stream is in an error state
@L2: lda (ptr1),y ; get file->f_flags again
@L2: .if (.not .cpu .bitand ::CPU_ISET_65SC02)
lda (ptr1),y ; get file->f_flags again
.endif
and #_FERROR
bne @L1
@@ -53,8 +60,7 @@
ldy #_FILE::f_fd
lda (ptr1),y
ldx #$00
jsr pushax ; file->f_fd
jsr pusha0 ; file->f_fd
ldy #9
jsr pushwysp ; buf
@@ -123,4 +129,3 @@
.bss
file: .res 2

View File

@@ -68,7 +68,7 @@ MikeyInitData: .byte $9e,$18,$68,$1f,$00,$00,$00,$00,$00,$ff,$1a,$1b,$04,$0d,$2
; Disable the TX/RX IRQ; set to 8E1.
lda #%00011101
lda #PAREN|RESETERR|TXOPEN|PAREVEN ; #%00011101
sta SERCTL
; Clear all pending interrupts.

View File

@@ -73,7 +73,12 @@ SER_UNINSTALL:
; Must return an SER_ERR_xx code in a/x.
SER_CLOSE:
; Disable interrupts
; Disable interrupts and stop timer 4 (serial)
lda #TXOPEN|RESETERR
sta SERCTL
stz TIM4CTLA ; Disable count and no reload
stz SerialStat ; Reset status
; Done, return an error code
lda #SER_ERR_OK
.assert SER_ERR_OK = 0, error
@@ -108,17 +113,17 @@ SER_OPEN:
stz TxPtrIn
stz TxPtrOut
; clock = 8 * 15625
lda #%00011000
sta TIM4CTLA
ldy #SER_PARAMS::BAUDRATE
lda (ptr1),y
; Source period is 1 us
ldy #%00011000 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_1
ldx #1
cmp #SER_BAUD_62500
beq setbaudrate
ldx #2
ldx #3
cmp #SER_BAUD_31250
beq setbaudrate
@@ -134,6 +139,10 @@ SER_OPEN:
cmp #SER_BAUD_2400
beq setbaudrate
ldx #68
cmp #SER_BAUD_1800
beq setbaudrate
ldx #103
cmp #SER_BAUD_1200
beq setbaudrate
@@ -142,65 +151,22 @@ SER_OPEN:
cmp #SER_BAUD_600
beq setbaudrate
; clock = 6 * 15625
ldx #%00011010
stx TIM4CTLA
; Source period is 8 us
ldy #%00011011 ; ENABLE_RELOAD|ENABLE_COUNT|AUD_8
ldx #12
cmp #SER_BAUD_7200
beq setbaudrate
ldx #25
cmp #SER_BAUD_3600
beq setbaudrate
ldx #207
stx TIM4BKUP
; clock = 4 * 15625
ldx #%00011100
ldx #51
cmp #SER_BAUD_300
beq setprescaler
; clock = 6 * 15625
ldx #%00011110
cmp #SER_BAUD_150
beq setprescaler
; clock = 1 * 15625
ldx #%00011111
stx TIM4CTLA
cmp #SER_BAUD_75
beq baudsuccess
ldx #141
cmp #SER_BAUD_110
beq setbaudrate
; clock = 2 * 15625
ldx #%00011010
stx TIM4CTLA
ldx #68
cmp #SER_BAUD_1800
beq setbaudrate
; clock = 6 * 15625
ldx #%00011110
stx TIM4CTLA
ldx #231
cmp #SER_BAUD_134_5
beq setbaudrate
lda #SER_ERR_BAUD_UNAVAIL
ldx #0 ; return value is char
rts
setprescaler:
stx TIM4CTLA
bra baudsuccess
setbaudrate:
sty TIM4CTLA
stx TIM4BKUP
baudsuccess:
ldx #TxOpenColl|ParEven
ldx #TXOPEN|PAREVEN
stx contrl
ldy #SER_PARAMS::DATABITS ; Databits
lda (ptr1),y
@@ -218,15 +184,15 @@ baudsuccess:
beq checkhs
cmp #SER_PAR_SPACE
bne @L0
ldx #TxOpenColl
ldx #TXOPEN
stx contrl
bra checkhs
@L0:
ldx #TxParEnable|TxOpenColl|ParEven
ldx #PAREN|TXOPEN|PAREVEN
stx contrl
cmp #SER_PAR_EVEN
beq checkhs
ldx #TxParEnable|TxOpenColl
ldx #PAREN|TXOPEN
stx contrl
checkhs:
ldx contrl
@@ -234,15 +200,27 @@ checkhs:
ldy #SER_PARAMS::HANDSHAKE ; Handshake
lda (ptr1),y
cmp #SER_HS_NONE
beq redeye_ok
cmp #SER_HS_SW ; Software handshake will check for connected redeye
bne invparameter
lda IODAT
and #NOEXP ; Check if redeye bit flag is unset
beq redeye_ok
lda #SER_ERR_NO_DEVICE ; ComLynx cable is not inserted
ldx #0
rts
redeye_ok:
lda SERDAT
lda contrl
ora #RxIntEnable|ResetErr
ora #RXINTEN|RESETERR ; Turn on interrupts for receive
sta SERCTL
lda #SER_ERR_OK
.assert SER_ERR_OK = 0, error
tax
rts
invparameter:
lda #SER_ERR_INIT_FAILED
ldx #0 ; return value is char
@@ -264,8 +242,8 @@ GetByte:
ldy RxPtrOut
lda RxBuffer,y
inc RxPtrOut
sta (ptr1)
ldx #$00
sta (ptr1,x)
txa ; Return code = 0
rts
@@ -279,24 +257,26 @@ SER_PUT:
ina
cmp TxPtrOut
bne PutByte
lda #SER_ERR_OVERFLOW
ldx #0 ; return value is char
rts
PutByte:
ldy TxPtrIn
txa
sta TxBuffer,y
inc TxPtrIn
bit TxDone
bmi @L1
bit TxDone ; Check bit 7 of TxDone (TXINTEN)
bmi @L1 ; Was TXINTEN already set?
php
sei
lda contrl
ora #TxIntEnable|ResetErr
sta SERCTL ; Allow TX-IRQ to hang RX-IRQ
lda contrl ; contrl does not include RXINTEN setting
ora #TXINTEN|RESETERR
sta SERCTL ; Allow TX-IRQ to hang RX-IRQ (no receive while transmitting)
sta TxDone
plp
plp ; Restore processor and interrupt enable
@L1:
lda #SER_ERR_OK
.assert SER_ERR_OK = 0, error
@@ -308,9 +288,9 @@ PutByte:
; Must return an SER_ERR_xx code in a/x.
SER_STATUS:
ldy SerialStat
lda SerialStat
sta (ptr1)
ldx #$00
sta (ptr1,x)
txa ; Return code = 0
rts
@@ -342,48 +322,56 @@ SER_IRQ:
@L0:
bit TxDone
bmi @tx_irq ; Transmit in progress
ldx SERDAT
lda SERCTL
and #RxParityErr|RxOverrun|RxFrameErr|RxBreak
beq @rx_irq
ldx SERDAT ; Read received data
lda contrl
and #PAREN ; Parity enabled implies SER_PAR_EVEN or SER_PAR_ODD
tay
ora #OVERRUN|FRAMERR|RXBRK
and SERCTL ; Check presence of relevant error flags in SERCTL
beq @rx_irq ; No errors so far
tsb SerialStat ; Save error condition
bit #RxBreak
bit #RXBRK ; Check for break signal
beq @noBreak
stz TxPtrIn ; Break received - drop buffers
stz TxPtrOut
stz RxPtrIn
stz RxPtrOut
@noBreak:
lda contrl
ora #RxIntEnable|ResetErr
sta SERCTL
lda #$10
sta INTRST
bra @IRQexit
bra @exit0
@rx_irq:
tya
bne @2 ; Parity was enabled so no marker bit check needed
lda contrl
ora #RxIntEnable|ResetErr
sta SERCTL
eor SERCTL ; Should match current parity bit
and #PARBIT ; Check for mark or space value
bne @exit0
@2:
txa
ldx RxPtrIn
sta RxBuffer,x
txa
inx
@cont0:
cpx RxPtrOut
beq @1
stx RxPtrIn
lda #SERIAL_INTERRUPT
sta INTRST
bra @IRQexit
@1:
sta RxPtrIn
lda #$80
tsb SerialStat
bra @exit0
@tx_irq:
ldx TxPtrOut ; Has all bytes been sent?
ldx TxPtrOut ; Have all bytes been sent?
cpx TxPtrIn
beq @allSent
@@ -393,24 +381,24 @@ SER_IRQ:
@exit1:
lda contrl
ora #TxIntEnable|ResetErr
ora #TXINTEN|RESETERR
sta SERCTL
lda #SERIAL_INTERRUPT
sta INTRST
bra @IRQexit
@allSent:
lda SERCTL ; All bytes sent
bit #TxEmpty
bit #TXEMPTY
beq @exit1
bvs @exit1
stz TxDone
@exit0:
lda contrl
ora #RxIntEnable|ResetErr
ora #RXINTEN|RESETERR ; Re-enable receive interrupt
sta SERCTL
@IRQexit:
lda #SERIAL_INTERRUPT
sta INTRST
@IRQexit:
clc
rts

View File

@@ -40,14 +40,14 @@ cont1:
bra loop1
read_byte:
bit SERCTL
bit SERCTL ; Check for RXRDY ($40)
bvc read_byte
lda SERDAT
rts
_UpLoaderIRQ:
lda INTSET
and #$10
and #SERIAL_INTERRUPT
bne @L0
clc
rts
@@ -69,7 +69,7 @@ again:
; last action : clear interrupt
;
exit:
lda #$10
lda #SERIAL_INTERRUPT
sta INTRST
clc
rts

21
libsrc/runtime/aslax7.s Normal file
View File

@@ -0,0 +1,21 @@
;
; Miloslaw Smyk, 2024
;
; CC65 runtime: Scale the primary register by 128, unsigned
;
.export shlax7, aslax7
aslax7:
shlax7: ; XXXXXXXL AAAAAAAl
tay
txa
lsr ; XXXXXXXL -> 0XXXXXXX, L->C
tya
ror ; AAAAAAAl -> LAAAAAAA, l->C
tax
lda #$00 ; LAAAAAAA 00000000
ror ; LAAAAAAA l0000000
rts
; 10 bytes, 16 cycles + rts

18
libsrc/runtime/asrax7.s Normal file
View File

@@ -0,0 +1,18 @@
;
; Miloslaw Smyk, 2024
;
; CC65 runtime: Scale the primary register by 128, signed
;
.export asrax7
asrax7: ; HXXXXXXL hAAAAAAl
asl ; AAAAAAA0, h->C
txa
rol ; XXXXXXLh, H->C
ldx #$00 ; 00000000 XXXXXXLh
bcc :+
dex ; 11111111 XXXXXXLh if C
: rts
; 12 cycles max, 9 bytes

18
libsrc/runtime/shrax7.s Normal file
View File

@@ -0,0 +1,18 @@
;
; Miloslaw Smyk, 2024
;
; CC65 runtime: Scale the primary register by 128, unsigned
;
.export shrax7
shrax7: ; HXXXXXXL hAAAAAAl
asl ; AAAAAAA0, h->C
txa
rol ; XXXXXXLh, H->C
ldx #$00 ; 00000000 XXXXXXLh
bcc :+
inx ; 0000000H XXXXXXLh if C
: rts
; 12 cycles max, 9 bytes