| Posted By
Harry Potter on 2022-05-17 11:56:29
| Harry Potter CC65 Thread
Hi! I am working on some cartridge configurations for the Plus4 target of cc65 and am having some problems during the boot process on a 32k cartridge. The start-up code follows:
------------------- startup: ;Thi sei ldx #$ff txs lda $fb pha ;ldx #$02 ; cartrige 1 lo, kernal sta $FDD2 jsr $FF84 ; Initialize I/O devices jsr $FF87 ; RAM Test pla sta $FB jsr $FF8A ; Restore vectors to initial values jsr $FF81 ; Initialize screen editor cli
; Switch to second charset
lda #14 jsr BSOUT
; Clear the BSS data
jsr zerobss
lda #<(__RAM_START__ + __RAM_SIZE__) sta sp lda #>(__RAM_START__ + __RAM_SIZE__) sta sp+1 ; Set argument stack ptr
lda #$03 sta $FF0C lda #$FF sta $FF0D
; If we have IRQ functions, chain our stub into the IRQ vector
; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ1 ; lda IRQVec ; ldx IRQVec+1 ; sta IRQInd+1 ; stx IRQInd+2 ; lda #; ldx #>IRQStub ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
; Call module constructors
NoIRQ1: lda #<__DATA_RUN__ ldx #>__DATA_RUN__ jsr pushax lda #<__DATA_LOAD__ ldx #>__DATA_LOAD__ jsr pushax lda #<__DATA_SIZE__ ldx #>__DATA_SIZE__ jsr _memcpy
jsr initlib
; Push arguments and call main ;ra: ; inc $D021 ; jmp ra
jsr _main
; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib
; Reset the IRQ vector if we chained it.
; ;pha ; Save the return code on stack ; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ2 ; lda IRQInd+1 ; ldx IRQInd+2 ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
NoIRQ2: jmp startup ---------------------
|
|
Posted By
Harry Potter on 2022-05-17 11:58:15
| Re: cc65 Plus4 Cart bug...
The error appears to be near the code that initializes the stack. BTW, the 16k version works. Should I upload it now? Or should I wait until the 32k version is ready?
|
|
Posted By
Harry Potter on 2022-06-12 16:53:02
| Re: cc65 Plus4 Cart bug...
The 16k version does not work. I get from WinVice a JAM instruction at $01FF. I really want this to work. The Plus4/C16 cartridge version of AdvSkelVic65 works, though.
The 16k cartridge crt0.s file follows:
--------------------------- ; ; Startup code for cc65 (C64 version) ;
.export _exit .export __STARTUP__ : absolute = 1 ; Mark as startup .import initlib, donelib, callirq .import zerobss .import _main, pushax .import RESTOR, BSOUT, CLRCH .import __INTERRUPTOR_COUNT__ .import __RAM_START__, __RAM_SIZE__ ; Linker generated
.import _cgetc, _puts, _memcpy
.import __DATA_LOAD__, __DATA_RUN__, __DATA_SIZE__
.exportzp _i, _j, _Itm1, _CRoom, _CurPos, _CurItem, _s, _Vrb, _c .exportzp _CRm, _CurRoomInv, _e, _ItemPtr, _s2
.include "zeropage.inc" .include "plus4.inc"
.segment "STARTUP" jmp startup ;Cold start jmp $FEBC ;Warm start, default calls NMI exit. .byt 1, $43,$42,$4d ;magic to identify cartridge
startup: ;Thi sei ldx #$ff txs lda $fb pha ;ldx #$02 ; cartrige 1 lo, kernal sta $FDD2 jsr $FF84 ; Initialize I/O devices jsr $FF87 ; RAM Test pla sta $FB jsr $FF8A ; Restore vectors to initial values jsr $FF81 ; Initialize screen editor cli
; Switch to second charset
lda #14 jsr BSOUT
; Clear the BSS data
jsr zerobss
lda #$00 sta sp lda #$80 sta sp+1 ; Set argument stack ptr
lda #$03 sta $FF0C lda #$FF sta $FF0D
; If we have IRQ functions, chain our stub into the IRQ vector
; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ1 ; lda IRQVec ; ldx IRQVec+1 ; sta IRQInd+1 ; stx IRQInd+2 ; lda #; ldx #>IRQStub ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
; Call module constructors
NoIRQ1: lda #<__DATA_RUN__ ldx #>__DATA_RUN__ jsr pushax lda #<__DATA_LOAD__ ldx #>__DATA_LOAD__ jsr pushax lda #<__DATA_SIZE__ ldx #>__DATA_SIZE__ jsr _memcpy
jsr initlib
; Push arguments and call main ;ra: ; inc $D021 ; jmp ra
jsr _main
; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib
; Reset the IRQ vector if we chained it.
; ;pha ; Save the return code on stack ; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ2 ; lda IRQInd+1 ; ldx IRQInd+2 ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
NoIRQ2: jmp startup
.zeropage _i: .res 1 _j: .res 1 _Itm1: .res 1 _CRoom: .res 1 _CurPos: .res 1 _CurItem: .res 1 _s: .res 2 _Vrb: .res 1 _c: .res 1 _CRm: .res 2 _CurRoomInv: .res 2 _e: .res 1 _ItemPtr: .res 2 _s2: .res 2 -------------------
|
|
|
Posted By
Harry Potter on 2022-06-20 19:18:27
| Re: cc65 Plus4 Cart bug...
I found the bug: BSOUT seems to point to the wrong address. Replacing it with $FFD2 worked.
|
|
Posted By
Harry Potter on 2022-06-21 14:05:41
| Plus4Cart issue w/ printf(): lock-up at start-up
Hi! I got my Plus4/cc65 cartridge libraries to work, but now, there is a problem: I added my own version of printf() to the test program. Now, the program locks up at start-up. I disabled the line in the crt0.s file that calls initlib, and the program locks up at the call to printf(). I looked at the source for a reference to the init routines and didn't find anything. What in printf() would be called from initlib? Or do I need to check out the initlib function? Following is the crt0.s file:
-------------------- startup: ;Thi sei ldx #$ff txs lda $fb pha ;ldx #$02 ; cartrige 1 lo, kernal sta $FDD2 jsr $FF84 ; Initialize I/O devices jsr $FF87 ; RAM Test pla sta $FB jsr $FF8A ; Restore vectors to initial values jsr $FF81 ; Initialize screen editor cli
; Switch to second charset
lda #14 jsr $FFD2
; Clear the BSS data
jsr zerobss
;lda #<(__RAM_START__ + __RAM_SIZE__) lda #$00 sta sp ;lda #>(__RAM_START__ + __RAM_SIZE__) lda #$80 sta sp+1 ; Set argument stack ptr
lda #$03 sta $FF0C lda #$FF sta $FF0D
; If we have IRQ functions, chain our stub into the IRQ vector
; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ1 ; lda IRQVec ; ldx IRQVec+1 ; sta IRQInd+1 ; stx IRQInd+2 ; lda #; ldx #>IRQStub ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
; Call module constructors
NoIRQ1: lda #<__DATA_RUN__ ldx #>__DATA_RUN__ jsr pushax lda #<__DATA_LOAD__ ldx #>__DATA_LOAD__ jsr pushax lda #<__DATA_SIZE__ ldx #>__DATA_SIZE__ jsr _memcpy
jsr initlib
; Push arguments and call main ;ra: ; inc $D021 ; jmp ra
jsr _main
; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib
; Reset the IRQ vector if we chained it.
; ;pha ; Save the return code on stack ; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ2 ; lda IRQInd+1 ; ldx IRQInd+2 ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
NoIRQ2: jmp startup
--------------------
If you want, I can post my version of printf().
|
|
Posted By
Harry Potter on 2022-06-21 15:24:14
| Re: Plus4Cart issue w/ printf(): lock-up at start-up
I found the bug. It was the same as before: the kernal entry names don't seem to be pointing to the proper addresses. This time, it was in the write.s file in the cbm library sources. I think I have a recent build of cc65 but not the latest. I didn't include "cbm_kernal.inc" in the sources, but the entry point declarations sjhould point to the right kernal entry point.
|
|
Posted By
Harry Potter on 2022-06-22 15:39:31
| cc65/Plus4 bug w/ kernal calls: bad labels
Hi! I've been having an issue with cc65 and the Plus4 target regarding kernal calls from assembler using entry-point labels: I get system crashes and lock-ups. When I use the address, however, it works. I believe this is a bug in cc65's Plus4 libraries. I can try to include an assembler module containing an .include of the file containing the kernal jump entries from the CBM library.
|
|
|
|
Posted By
Harry Potter on 2022-06-28 10:10:35
| Bug in Plus4Cart03/cc65
Hi! I already have two Plus4 cartridge configurations for the Plus4: one for a 16k cartridge and one for a 32k cartridge to treat the upper 16k as hidden data via a port of my Hidden64 library. Now, I am working on a 32k cartridge where the whole 32k is accessible and kernal access is delegated. It has a bug: the first time it is run, it works. The demo is doing everything it's supposed to do. However, when I exit the program, the first piece of text is displayed, but the first key press doesn't register. Following is the crt0.s code:
-------------------------- startup: ;Thi sei ldx #$ff txs lda $fb pha ;ldx #$02 ; cartrige 1 lo, kernal sta $FDD2 jsr $FF84 ; Initialize I/O devices jsr $FF87 ; RAM Test pla sta $FB jsr $FF8A ; Restore vectors to initial values jsr $FF81 ; Initialize screen editor cli
; Switch to second charset
lda #14 jsr $FFD2
; Clear the BSS data
jsr zerobss
;lda #<(__RAM_START__ + __RAM_SIZE__) lda #$00 sta sp ;lda #>(__RAM_START__ + __RAM_SIZE__) lda #$80 sta sp+1 ; Set argument stack ptr
lda #$03 sta $FF0C lda #$FF sta $FF0D
sta $FDD2 ; Enable the ROM ; If we have IRQ functions, chain our stub into the IRQ vector
; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ1 ; lda IRQVec ; ldx IRQVec+1 ; sta IRQInd+1 ; stx IRQInd+2 ; lda #; ldx #>IRQStub ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
; Call module constructors
NoIRQ1: lda #<__DATA_RUN__ ldx #>__DATA_RUN__ jsr pushax lda #<__DATA_LOAD__ ldx #>__DATA_LOAD__ jsr pushax lda #<__DATA_SIZE__ ldx #>__DATA_SIZE__ jsr _memcpy
jsr initlib
; Push arguments and call main ;ra: ; inc $D021 ; jmp ra
jsr _main
; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib
; Reset the IRQ vector if we chained it.
; ;pha ; Save the return code on stack ; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ2 ; lda IRQInd+1 ; ldx IRQInd+2 ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
NoIRQ2: jmp startup ------------------------------
The write.s code:
----------------------------- ;-------------------------------------------------------------------------- ; initstdout: Open the stdout and stderr file descriptors for the screen.
.segment "ONCE"
.proc initstdout
lda #STDOUT_FILENO + LFN_OFFS jsr @L1 lda #STDERR_FILENO + LFN_OFFS @L1: ldx #CBMDEV_SCREEN ldy #$FF sta $FDD2
jsr SETLFS jsr OPEN ; Will always succeed sta $FDDA rts
.endproc
;-------------------------------------------------------------------------- ; _write
;.code .segment "LOWCODE"
.proc _write
jsr rwcommon ; Pop params, check handle bcs invalidfd ; Invalid handle
; Check if the LFN is valid and the file is open for writing
adc #LFN_OFFS ; Carry is already clear tax lda fdtab-LFN_OFFS,x; Get flags for this handle and #LFN_WRITE ; File open for writing? beq invalidfd
; Valid lfn. Make it the output file
sta $FDD2 jsr CKOUT bcc @L2 @error: jmp __mappederrno ; Store into __oserror, map to errno, return -1
; Output the next character from the buffer
@L0: ldy #0 sta $FDDA lda (ptr1),y inc ptr1 bne @L1 inc ptr1+1 ; A = *buf++;
@L1: sta $FDD2 jsr BSOUT
; Check the status
pha jsr READST lsr a ; Bit zero is write timeout bne devnotpresent2 pla bcs @L3
; Count characters written
inc ptr3 bne @L2 inc ptr3+1
; Decrement count
@L2: dec ptr2 bne @L0 dec ptr2+1 bne @L0
; Wrote all chars or disk full. Close the output channel
@L3: jsr CLRCH
; Clear _oserror and return the number of chars written
lda #0 sta __oserror lda ptr3 ldx ptr3+1 sta $FDDA rts
; Error entry: Device not present
devnotpresent2: pla devnotpresent: lda #ENODEV .byte $2C ; Skip next opcode via BIT
; Error entry: The given file descriptor is not valid or not open
invalidfd: lda #EBADF jmp __directerrno ; Sets _errno, clears _oserror, returns -1
.endproc ---------------------- and the key press code: ---------------------- .proc _getkey sta $FDD2 @lp: jsr $ffe4 ;Call the getin kernal routine to ;get the key-press. cmp #0 ;Continue until key pressed. beq @lp sta $FDDA ldx #0 ;Clear MSB because I keep seeing ;this done in cc65's source code. rts ;Return. .endproc -------------------------
|
|
Posted By
Harry Potter on 2022-06-28 11:25:23
| Re: cc65/Plus4 cartridge libraries available!
Now I have a better 32k Plus4 cartridge library for cc65: the full 32k cartridge is available, and kernal calls are delegated accordingly. There is a bug at restart, though. It is at the same location as the previous.
|
|
Posted By
Harry Potter on 2022-07-04 15:30:43
| Re: Bug in Plus4Cart03/cc65
Right now, cgetc() doesn't work, and, sometimes, while displaying the text, it doesn't complete the option, and the keyboard doesn't respond.
|
|
Posted By
Harry Potter on 2022-07-07 13:36:11
| Plus4Cart3 bug
Hi! I am working hard on my Plus4/cc65 cartridge library and am having a problem: while printing text to the screen, the program stops in the middle of the process. I don't know what's causing this. Following is the write.s file as included in the library:
--------------------- .proc _write
jsr rwcommon ; Pop params, check handle bcs invalidfd ; Invalid handle
; Check if the LFN is valid and the file is open for writing
adc #LFN_OFFS ; Carry is already clear tax lda fdtab-LFN_OFFS,x; Get flags for this handle and #LFN_WRITE ; File open for writing? beq invalidfd
; Valid lfn. Make it the output file
jsr CKOUT bcc @L2 @error: jmp __mappederrno ; Store into __oserror, map to errno, return -1
; Output the next character from the buffer
@L0: ldy #0 lda (ptr1),y inc ptr1 bne @L1 inc ptr1+1 ; A = *buf++; @L1: jsr BSOUT
; Check the status
pha jsr READST lsr a ; Bit zero is write timeout bne devnotpresent2 pla bcs @L3
; Count characters written
inc ptr3 bne @L2 inc ptr3+1
; Decrement count
@L2: dec ptr2 bne @L0 dec ptr2+1 bne @L0
; Wrote all chars or disk full. Close the output channel
@L3: jsr CLRCH
; Clear _oserror and return the number of chars written
lda #0 sta __oserror lda ptr3 ldx ptr3+1 rts
; Error entry: Device not present
devnotpresent2: pla devnotpresent: lda #ENODEV .byte $2C ; Skip next opcode via BIT
; Error entry: The given file descriptor is not valid or not open
invalidfd: lda #EBADF jmp __directerrno ; Sets _errno, clears _oserror, returns -1
.endproc --------------------------------
BTW, IIRC, cgetc() doesn't work either, but getkey() does.
|
|
Posted By
Harry Potter on 2022-07-07 14:00:27
| Re: Plus4Cart3 bug
Maybe the bug is in the crt0.s file:
----------------------------------- .segment "STARTUP" jmp startup ;Cold start jmp $FEBC ;Warm start, default calls NMI exit. .byt 1, $43,$42,$4d ;magic to identify cartridge
startup: ;Thi sei ldx #$ff txs lda $fb pha ;ldx #$02 ; cartrige 1 lo, kernal sta $FDD2 jsr $FF84 ; Initialize I/O devices jsr $FF87 ; RAM Test pla sta $FB jsr $FF8A ; Restore vectors to initial values jsr $FF81 ; Initialize screen editor cli
; Switch to second charset
lda #14 jsr $FFD2
; Clear the BSS data
jsr zerobss
;lda #<(__RAM_START__ + __RAM_SIZE__) lda #$00 sta sp ;lda #>(__RAM_START__ + __RAM_SIZE__) lda #$80 sta sp+1 ; Set argument stack ptr
lda #$03 sta $FF0C lda #$FF sta $FF0D
sta $FDD2 ; Enable the ROM ; If we have IRQ functions, chain our stub into the IRQ vector
; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ1 ; lda IRQVec ; ldx IRQVec+1 ; sta IRQInd+1 ; stx IRQInd+2 ; lda #; ldx #>IRQStub ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
; Call module constructors
NoIRQ1: lda #<__DATA_RUN__ ldx #>__DATA_RUN__ jsr pushax lda #<__DATA_LOAD__ ldx #>__DATA_LOAD__ jsr pushax lda #<__DATA_SIZE__ ldx #>__DATA_SIZE__ jsr _memcpy
jsr initlib
; Push arguments and call main ;ra: ; inc $D021 ; jmp ra
jsr _main
; Back from main (This is also the _exit entry). Run module destructors
_exit: jsr donelib
; Reset the IRQ vector if we chained it.
; ;pha ; Save the return code on stack ; lda #<__INTERRUPTOR_COUNT__ ; beq NoIRQ2 ; lda IRQInd+1 ; ldx IRQInd+2 ; sei ; sta IRQVec ; stx IRQVec+1 ; cli
NoIRQ2: jmp startup
|
|
Posted By
Harry Potter on 2022-07-12 17:10:03
| Re: Harry Potter CC65 Thread
Hi, again! I am having a problem with my MemBankP4 library: the getkey() function isn't working properly: the screen keeps refreshing, as if I keep pressing a key, then, when I press a key, I get a JAM execution error at $0004. Following is the gertkey.s code:
----------------------- .segment "LOWCODE"
.proc _getkey sta ENABLE_ROM @lp: ;inc $0C00 jsr $ffe4 ;Call the getin kernal routine to ;lda #$E4 ;jsr callkernal ;get the key-press. cmp #0 ;Continue until key pressed. beq @lp ldx #0 ;Clear MSB because I keep seeing ;this done in cc65's source code. ;sta $C00 sta ENABLE_RAM rts ;Return. .endproc ------------------
BTW, I'm testing on WinVice 3.0.
|
|
Posted By
Harry Potter on 2022-07-12 17:34:11
| Re: Harry Potter CC65 Thread
I still have a bug with my 32k cartridge format: it usually stops working while displaying some text and doesn't finish displaying the text. Following is my version of the cc65/Plus4 library's write.s code: ----------------------- .proc _write
jsr rwcommon ; Pop params, check handle bcs invalidfd ; Invalid handle
; Check if the LFN is valid and the file is open for writing
adc #LFN_OFFS ; Carry is already clear tax lda fdtab-LFN_OFFS,x; Get flags for this handle and #LFN_WRITE ; File open for writing? beq invalidfd
; Valid lfn. Make it the output file
jsr CKOUT bcc @L2 @error: jmp __mappederrno ; Store into __oserror, map to errno, return -1
; Output the next character from the buffer
@L0: ldy #0 lda (ptr1),y inc ptr1 bne @L1 inc ptr1+1 ; A = *buf++; @L1: jsr BSOUT
; Check the status
pha jsr READST lsr a ; Bit zero is write timeout bne devnotpresent2 pla bcs @L3
; Count characters written
inc ptr3 bne @L2 inc ptr3+1
; Decrement count
@L2: dec ptr2 bne @L0 dec ptr2+1 bne @L0
; Wrote all chars or disk full. Close the output channel
@L3: jsr CLRCH
; Clear _oserror and return the number of chars written
lda #0 sta __oserror lda ptr3 ldx ptr3+1 rts
; Error entry: Device not present
devnotpresent2: pla devnotpresent: lda #ENODEV .byte $2C ; Skip next opcode via BIT <abs>
; Error entry: The given file descriptor is not valid or not open
invalidfd: lda #EBADF jmp __directerrno ; Sets _errno, clears _oserror, returns -1
.endproc -----------------------
|
|
Posted By
Harry Potter on 2022-08-28 08:46:58
| cc65: printtok.c
Hi! I have a code module for cc65 and CBM targets called printtok.c. It is a way to compress strings slightly using tokenization. It contains a function to print strings that contain embedded tokens and expand the tokens. You can find it at https://sourceforge.net/projects/cc65extra/files/ui/. I ask you to try it out and tell me what you think.
|
|
| |
Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon |