| 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. 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. 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. 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.
|
|
| |
Copyright © Plus/4 World Team, 2001-2024. Support Plus/4 World on Patreon |