Login
Back to forumReply to this topicGo to last reply

Posted By

Harry Potter
on 2022-03-11
10:46:26
 MemBankP4/cc65: demo prg won't load data to expansion RAM

Hi! I am working on a port of my MemBank128 to the Plus4, but the demo program is locking up when it tries to load data to Csory expansion RAM. The code in question follows:
--------------------------
crt0.s:
--------------------------
.segment "STARTUP"

Start:

; Save the zero-page locations that we need.

; sei ; No interrupts since we're banking out the ROM
; sta ENABLE_RAM
; ldx #zpspace-1
;L1: lda sp,x
; sta zpsave,x
; dex
; bpl L1
; sta ENABLE_ROM
; cli

; Switch to the second charset.

lda #14
jsr $FFD2 ; BSOUT

; Save some system stuff; and, set up the stack. The stack starts at the top
; of the usable RAM.

;tsx
;stx spsave ; Save system stk ptr

lda #<(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
ldx #>(__MAIN_START__ + __MAIN_SIZE__ + __STACKSIZE__)
sta sp
stx sp+1

; Set up the IRQ vector in the banked RAM; and, switch off the ROM.

ldx #<IRQ
ldy #>IRQ
sei ; No ints, handler not yet in place
sta ENABLE_RAM
stx $FFFE ; Install interrupt handler
sty $FFFF
cli ; Allow interrupts

; Clear the BSS data.

jsr zerobss

; Initialize irqcount, which means that, from now on, custom linked-in IRQ
; handlers will be called (via condes).

lda #.lobyte(__INTERRUPTOR_COUNT__*2)
sta irqcount

; Copy banked memory access routines to Low RAM.
;lda #<__MEMBANK_RUN__
;lda #>__MEMBANK_RUN__
ldx #<__MEMBANK_SIZE__-1
a01: lda __MEMBANK_LOAD__,x
sta __MEMBANK_RUN__,x
dex
bpl a01
; Call the module constructors.

jsr initlib

; Push the command-line arguments; and, call main().

;jsr callmain
jsr push0
jsr push0
jsr _main

; Back from main() [this is also the exit() entry]. Run the module destructors.

_exit: ;pha ; Save the return code
jsr donelib ; Run module destructors

; Disable the chained IRQ handlers.

lda #0
sta irqcount ; Disable custom IRQ handlers

; Copy back the zero-page stuff.

; ldx #zpspace-1
;L2: lda zpsave,x
; sta sp,x
; dex
; bpl L2

; Place the program return code into BASIC's status variable.

; pla
; sta ST

; Restore the stack pointer.

; ldx spsave
; txs

; Enable the ROM; and, return to BASIC.

sta ENABLE_ROM
;rts
jmp ($FFFC)

; ------------------------------------------------------------------------
; IRQ handler. The handler in the ROM enables the Kernal, and jumps to
; $CE00, where the ROM code checks for a BRK or IRQ, and branches via the
; indirect vectors at $314/$316.
; To make our stub as fast as possible, we skip the whole part of the ROM
; handler, and jump to the indirect vectors directly. We do also call our
; own interrupt handlers if we have any; so, they need not use $314.

.segment "LOWCODE"

IRQ: cld ; Just to be sure
pha
txa
pha
tya
pha
tsx ; Get the stack pointer
lda $0104,x ; Get the saved status register
and #$10 ; Test for BRK bit
bne dobreak

; It's an IRQ; and, RAM is enabled. If we have handlers, call them. We will use
; a flag here instead of loading __INTERRUPTOR_COUNT__ directly, since the
; condes function is not reentrant. The irqcount flag will be set/reset from
; the main code, to avoid races.

ldy irqcount
beq @L1
jsr callirq_y ; Call the IRQ functions

; Since the ROM handler will end with an RTI, we have to fake an IRQ return
; on the stack, so that we get control of the CPU after the ROM handler,
; and can switch back to RAM.

@L1: lda #>irq_ret ; Push new return address
pha
lda #<irq_ret
pha
php ; Push faked IRQ frame on stack
pha ; Push faked A register
pha ; Push faked X register
pha ; Push faked Y register
sta ENABLE_ROM ; Switch to ROM
jmp (IRQVec) ; Jump indirect to Kernal IRQ handler

irq_ret:
sta ENABLE_RAM ; Switch back to RAM
pla
tay
pla
tax
pla
rti

dobreak:
lda brk_jmp+2 ; Check high byte of address
beq nohandler
jmp brk_jmp ; Jump to the handler

; No break handler installed, jump to ROM.

nohandler:
sta ENABLE_ROM
jmp (BRKVec) ; Jump indirect to the break vector
----------------------------------
unsigned int bank1_cbm_load(const char* name, unsigned char device, void* data)
{
/* LFN is set to 0 but it's not needed for loading.
* (BASIC V2 sets it to the value of the SA for LOAD) */
static unsigned int i;
cbm_k_setlfs(0, device, CBM_READ);
cbm_k_setnam(name);
i=cbm_k_open(); if (i) return -1;
i=bank1_cbm_read (0, data, 0xFC00-(unsigned) data);
putchar ('-');
cbm_close (0);
return i;
}
-----------------------
unsigned __fastcall__ bank1_cbm_read (unsigned char lfn, void* buffer, unsigned size)
/* Reads up to "size" bytes from a file to "buffer".
* Returns the number of actually read bytes, 0 if there are no bytes left
* (EOF) or -1 in case of an error. _oserror contains an errorcode then (see
* table below).
*/
{
static unsigned int bytesread;
static unsigned char tmp;

/* if we can't change to the inputchannel #lfn then return an error */
if (_oserror = cbm_k_chkin(lfn)) return -1;

bytesread = 0;
while (bytesread<size && !cbm_k_readst()) {
tmp = cbm_k_basin();
/* the kernal routine BASIN sets ST to EOF if the end of file
* is reached the first time, then we have store tmp.
* every subsequent call returns EOF and READ ERROR in ST, then
* we have to exit the loop here immidiatly. */
if (cbm_k_readst() & 0xBF) break;
++*(unsigned char*)0xC00;
//((unsigned char*)buffer)[bytesread++] = tmp;
//bank1_writebyte (((unsigned char*)buffer)[bytesread++], tmp);
bank1_writebyte (((unsigned char*)&buffer+bytesread), tmp);
++bytesread;
}
cbm_k_clrch();
putchar ('-');
return bytesread;
}
----------------------
Any help would be appreciated.

Posted By

Harry Potter
on 2022-03-11
10:49:55
 Re: MemBankP4/cc65: demo prg won't load data to expansion RAM

Oops, I forgot the memory-writing code:
------------------------------
.segment "LOWCODE"

_bank1_writebyte:
;jsr popa
pha
jsr popax
sta ptr1
stx ptr1+1
pla
ldy #0
jmp bank1_writebytedirect

_bank1_writeword:
;jsr popax
pha
stx tmp1
jsr popax
sta ptr1
stx ptr1+1
pla
ldx tmp1
jmp bank1_writeworddirect



.segment "MEMBANK"

bank1_writebytedirect:
;sta $FF02
pha
lda #$2
sta $FD16
pla
sta (ptr1),y
lda #$3
sta $FD16
rts

bank1_writeworddirect:
pha
lda #$2
sta $FD16
pla
sta $FF02
sta (ptr1),y
iny
txa
sta (ptr1),y
lda #$3
sta $FD16
rts

Posted By

Harry Potter
on 2022-03-11
11:09:03
 Re: MemBankP4/cc65: demo prg won't load data to expansion RAM

One last thing: the program seems to work if I decrease the size of the load, but I want to be able to load the whole file in without the size of the file.

Posted By

siz
on 2022-03-12
06:09:48
 Re: MemBankP4/cc65: demo prg won't load data to expansion RAM

I tried to read your code but it's pretty hard due to forum formatting. And a lot of symbols are referenced but I can only guess what they mean. What _can_ be a problem though is that you write values 2 and 3 to $fd16 which is ... how to put it... not recommended. For the Csory expansion the upper two bits select the 16k address space of the CPU you want to see the expansion memory window selected by the lower 4 bits.
So if you set it to 2 or 3 it will replace the memory from $0000-$3fff which contains the zero page and the stack and that can cause problems. (and perhaps your own code gets mapped out which is also not that good).
If you insist on using the Csory expansion I would recommend using $4000-$7fff or $8000-$bfff address spaces as your window (the latter only when ROM is switched off).

Be aware of two things:
1) Csory RAM expansion is controlled by a MOS 6529B IC meaning it's default value is $ff
2) I'm pretty sure that NONE of the emulators handle Csory expansion correctly. And I'm not aware of anyone having a computer with original Csory expansion to test it. (although TLC built one several years ago for himself) But if your intended audience is yourself using VICE then good luck.

Posted By

Harry Potter
on 2022-03-12
07:28:01
 Re: MemBankP4/cc65: demo prg won't load data to expansion RAM

I was wrong. I just looked at my docs., and I'm actually using Hannes.

Posted By

Harry Potter
on 2022-03-12
08:05:34
 Re: MemBankP4/cc65: demo prg won't load data to expansion RAM

I tried to set the Vice xplus4 memory mode to Hannes, and the emulator stopped responding for a second then displayed garbage. sad I think my docs got the two confused. I will try to convert the code now.

Posted By

Harry Potter
on 2022-08-20
14:10:45
 Re: MemBankP4/cc65: demo prg won't load data to expansion RAM

Now, I got the data to load properly. I was using Hannes. happy Unfortunately, when I retrieve a key from the user, the screen blinks several times then displays a message that I pressed an invalid key. If I press a wrong key, it will tell me and then restart the code to display the main menu. I'm not pressing a key. sad I will attach the getkey() code now.
---------------------
.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
----------------------

Posted By

Harry Potter
on 2022-08-20
14:24:01
 Re: MemBankP4/cc65: demo prg won't load data to expansion RAM

I just found two bugs in the program: 1. It was using cgetc() instead of getkey(), and 2. I was using the wrong address for the stub that loads into Low memory. I'm still getting the same error. happy



Back to topReply to this topic


Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon