|
Post by bjonte on Jun 20, 2017 14:50:01 GMT
I made a test today to see if I could modify RAM under the MMU registers at $FF00. It was possible to do that by moving the stack to $ff00 and write through that to the address range $FF00-$FF04.
|
|
|
Post by mirkosoft on Jun 20, 2017 22:11:22 GMT
Nice idea... This RAM place was always hole in data area... Will try too.
Miro
|
|
|
Post by bjonte on Jun 21, 2017 7:19:39 GMT
Yes. It is possible to have a bitmap image at $e000 if it is static in the MMU region at least.
|
|
|
Post by bjonte on Jun 24, 2017 9:42:27 GMT
This is my test program. I set the screen address to $fc00 and fill the screen with a new character every frame. I skipped the macros and register definitions to keep down the size. I follow the naming conventions in Mapping the C64.
const SCREEN_ADDR = $fc00 const CHARACTER_ADDR = $d000 const SCREEN_SIZE = 40*25
section code, "main", $1c01, $d000 { basic_line(2017, .start)
.start: sei
// enable character set and color memory bank 0 lda #R8502_CPU_COLOR_BANK_0 | R8502_VIC_COLOR_BANK_0 | R8502_VIC_CHAR_VISIBLE | R8502_CASSETTE_MOTOR_OFF sta R8502
// set VIC bank lda #MMURCR_COMMON_1K | MMURCR_COMMON_BOTTOM | MMURCR_VIC_BANK_0 sta MMURCR
// setup MMU to use RAM bank 0 and I/O lda #MMUCR_4000_RAM | MMUCR_8000_RAM | MMUCR_C000_RAM | MMUCR_D000_IO | MMUCR_RAM_BANK_0 sta MMUCR
// setup character location and screen memory lda #vmcsb_value(CHARACTER_ADDR, SCREEN_ADDR) sta VMCSB
// select VIC bank lda CI2PRA and #~CI2PRA_VIC_BANK_MASK ora #CI2PRA_VIC_BANK_C000 sta CI2PRA
// setup colors lda #Color.Gray1 sta BGCOL0 lda #Color.White memset(COLORRAM, $400)
ldy #0 { // wait for upper border lda RASTER bne @loop lda SCROLY bmi @loop
// move stack lda #$ff sta MMUP1L lda #0 sta MMUP1H
// write under $ff00 sty $0100 sty $0101 sty $0102 sty $0103 sty $0104
// restore stack lda #$01 sta MMUP1L lda #0 sta MMUP1H
// fill the rest of the screen tya memset(SCREEN_ADDR, $ff00 - SCREEN_ADDR) // fill to $ff00 memset($ff05, SCREEN_ADDR + SCREEN_SIZE - $ff05) // fill from $ff05
iny jmp @loop } }
|
|
|
Post by hydrophilic on Oct 26, 2017 13:07:01 GMT
I haven't tried this myself, but it sounds like legitimate (if cumbersome) way to use $ff00~$ff04 as normal RAM (presumably Video RAM). Thank you, bjonte, for sharing this trick with us!!
|
|
|
Post by Wagner on Oct 26, 2017 15:18:47 GMT
When I saw this trick here, I decided to use it in an editor I have been working on. The original code did something like this--
sta $ff01 ;just RAM 0 visible lda (line),y ;get a byte of text to display sta $ff02 ;back to kernal and i/o visible cmp #END ;have we reached the end of the line? beq ;somewhere sta $d601 ;to the VDC screen somehow iny bpl back ;for more
I realized how much more efficient it would be not to have to switch banks at all. By moving the stack through memory I could leave the kernal and i/o visible--
pla cmp #END beq sta $d601 iny bpl back
The PLA always pulls from RAM even though I/O or ROM might be visible. Sure, there is a little overhead before and after processing the line, but it worked out surprisingly well.
|
|
|
Post by bjonte on Oct 29, 2017 19:45:32 GMT
The difficult thing with the stack is that it becomes dangerous to get interrupts triggered and you can't easily use subroutines so that has to be avoided. The zero page can probably be used in the same way and may be easier to use if the interrupt code is free from zero page accesses.
|
|
|
Post by Wagner on Oct 30, 2017 0:48:26 GMT
Well, I agree--interrupts enabled with the stack located somewhere sensitive would be disastrous (don't touch that restore key). And as you say, it might be worth trying to move zero-page. A shorter, faster addressing mode is always a big plus, but then one would have to switch ROM and I/O in an out to get access to RAM underneath. It's certainly something worth keeping in mind for when an opportunity presents itself. Now that I have gained some programming confidence, I'm more willing to try these things and exploit the C128 wherever possible.
|
|
|
Post by Wagner on Oct 30, 2017 12:30:56 GMT
Oops, I'm wrong. LDA $00,x does indeed access RAM underneath ROM and I/O. But, the relocated zero-page still has ports at $00 and $01 getting in the way. For me, this makes swapping zero-page not as tidy as swapping the stack.
|
|
|
Post by hydrophilic on Nov 11, 2017 9:39:11 GMT
@wagner, I think you are on a good/optimal path... but yes the $00 and $01 registers can 'ruin' an otherwise 'perfect' algorithm. I *promise* I will publish a real-life example with TEMPEST 128, but here is some theory that may (or may not) motivate you... Think about how much faster the CPU can write zero page, or the stack page. Next imagine using that power. Maybe you can't read/write *all* 256 of the zero/stack page, but if each access saves you 25% of time, and you multiply that savings by *almost* 256 (like 248) then you can *literally* save many hundreds of CPU cycles... if done correctly. Sure there will be loss from the $00/$01 'exclusion' code, but the gain from the remaining 254 bytes should OVER-Compensate for that... if you do it right. I hope that helps to motivate people for now!! If not, stay tuned for *deep* program code [Edit]I was referring to GENERAL zero-page / stack-page redirection. After contemplation, I now realize this thread is *explicitly* about page 255 manipulation. I apologize because my GENERAL post has only a statistically small chance of relevance (1/256). Personally, I hate the way the $ff00 registers foul up an otherwise perfect VIC-II bitmap ($e000~$ff40). [/Edit]
|
|