+karri Posted January 5, 2023 Author Share Posted January 5, 2023 7 minutes ago, RevEng said: From the first posted script, try the values in the comments instead. Bracketed values show the link to the 7800 bit ordering... def map160B(val): ''' 3276 1054 ''' ret = 0 if (val & 1) == 1: ret = ret | 4 # 64 (6) if (val & 2) == 2: ret = ret | 8 #128 (7) if (val & 4) == 4: ret = ret | 64 # 4 (2) if (val & 8) == 8: ret = ret | 128 # 8 (3) if (val & 16) == 16: ret = ret | 1 # 16 (4) if (val & 32) == 32: ret = ret | 2 # 32 (5) if (val & 64) == 64: ret = ret | 16 # 1 (0) if (val & 128) == 128: ret = ret | 32 # 2 (1) return ret Transparent color indexes are at 0,4,8,16, so you'd need to skip those in your mapping. Thanks! You are perfectly right. This works. I just don't understand why. Actually I don't have any pixels with values 4, 8, 12 in my source images. All transparency is at index 0. Edit! Now I get it! I was just thinking along the wrong lines. Thanks! Your explanation made it clear. 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted January 5, 2023 Share Posted January 5, 2023 14 minutes ago, karri said: Edit! Now I get it! I was just thinking along the wrong lines. Thanks! Your explanation made it clear. You're welcome! I know from personal experience it's super easy to get turned around the wrong way between the png indexes and the 7800 indexes. Quote Link to comment Share on other sites More sharing options...
+karri Posted January 5, 2023 Author Share Posted January 5, 2023 I have been wondering what would be the best way to save progress on a game like Wizzy. As the carts do not have writable storage my choices may be - a password system - a joystick port "savekey" - or just have a menu that allows you to choose which mission to run There is a certain charm in having to earn your upgrades. So I am thinking about the savekey option. It would be possible to encode stuff into one "high score" value. My original plan was to have 7 areas for Wizzy to explore. Every successful area has an artifact that grants Wizzy a new skill when used. So essentially I need at least 7 bits to keep track of which artifacts Wizzy has found. 2 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 6, 2023 Author Share Posted January 6, 2023 I kind of like the TIA Tracker. But for Wizzy I would like to use a cart with a 3 channel square wave plus a noise channel. Is there some modular driver that could be used with the 7800 to play Furnace tracker sounds. I merely need control over volume and pitch. The chip I am experimenting with is SN76489. A fairly common thing in retro consoles. Perhaps I could modify the TIA Tracker driver for furnace data? Quote Link to comment Share on other sites More sharing options...
+karri Posted January 9, 2023 Author Share Posted January 9, 2023 My Wizzy is going strong on the new SN cart by @Eagle and @rj1307. Here is a first screenshot. What makes this new cart amazing is the bank flipping. If Wizzy is going right I can make her go left by just setting a bit to flip the animation. This is also very interesting when you look at the memory consumtion. Name Start End Size Align ---------------------------------------------------- EXEHDR 000000 00007F 000080 00001 ZEROPAGE 000040 000059 00001A 00001 EXTZP 00005A 00005B 000002 00001 DATA 001800 00187A 00007B 00001 BSS 00187B 001CCF 000455 00001 CODE 008000 009A9C 001A9D 00001 RODATA 009B00 009BC5 0000C6 00001 B008 00A000 00AFFF 001000 00001 - Wizzy running W000 00A000 00AFFF 001000 00001 - Wizzy standing M000 00D000 00DFFF 001000 00001 - World map to $5000 RAM T000 00D000 00DFFF 001000 00001 - Tiles to $6000 RAM T001 00D000 00DFFF 001000 00001 - Tiles to $7000 RAM R000 00E000 00E13E 00013F 00001 - Some level garbage that should be in the resident segment. STARTUP 00FF21 00FF5B 00003B 00001 ONCE 00FF5C 00FF79 00001E 00001 ENCRYPTION 00FF7A 00FFF9 000080 00001 VECTORS 00FFFA 00FFFF 000006 00001 The Wizzy animations take up just one slot $A000. The generic cart load buffer takes one slot $D000. And I still have not started to code in the NPC's and enemies at $C000 and $E000. The sfx sound effects are already in the code and there is tons of free space still. Thanks for making coding on the 7800 fun! PS. I just had a thought. The $D000 needs to be used mainly between levels when the scenery changes. As it is mostly useless in other times it could be used for music! I mean at the end of the level you fade out whatever is playing and when the next level is up ane running you se up a new tune. The actual interruptor and player code would be in main memory but the notes could be flipped in from the banks. PPS. I just had a glance at the vgc-player with compression support. It relies heavily on self-modifying code. So I believe it could live at the lowest RAM block at $4000. Now all the RAM is accounted for PPPS. In case some SN cart owner wants to build code for the cc65 you can look at my config file for the linker of how to direct code segments for the SN cart. # Atari VCS 7800 linker configuration file for cc65 SYMBOLS { __STACKSIZE__: type = weak, value = $0600; __CARTSIZE__: type = weak, value = $c000; __EXEHDR__: type = import; __VEC_BOTTOM__: value = $fffa, type = export; __VEC_SIZE__: value = $6, type = export; __ENCRYPT_BOTTOM__: value = $ff7a, type = export; __ENCRYPT_SIZE__: value = $80, type = export; __INIT_TOP__: value = __ENCRYPT_BOTTOM__, type = export; __INIT_SIZE__: value = 89, type = export; __INIT_BOTTOM__: value = __INIT_TOP__ - __INIT_SIZE__, type = export; __BANK7_BOTTOM__: value = $f000, type = export; __BANK7_SIZE__: value = __INIT_BOTTOM__ - __BANK7_BOTTOM__, type = export; __BANK6_BOTTOM__: value = $e000, type = export; __BANK6_SIZE__: value = $1000, type = export; __BANK5_BOTTOM__: value = $d000, type = export; __BANK5_SIZE__: value = $1000, type = export; __BANK4_BOTTOM__: value = $c000, type = export; __BANK4_SIZE__: value = $1000, type = export; __BANK3_BOTTOM__: value = $b000, type = export; __BANK3_SIZE__: value = $1000, type = export; __BANK2_BOTTOM__: value = $a000, type = export; __BANK2_SIZE__: value = $1000, type = export; __BANK01_BOTTOM__: value = $8000, type = export; __BANK01_SIZE__: value = $2000, type = export; __BANK_SIZE__: value = $1000, type = export; __WBANK_BOTTOM__: value = $a000, type = export; __TBANK_BOTTOM__: value = $d000, type = export; __TBANK_TOP__: value = $d000, type = export; } MEMORY { ZP: file = "", define = yes, start = $0040, size = $00C0, type = rw; SP: file = "", define = yes, start = $0140, size = $00C0, type = rw; RAM1: file = "", define = yes, start = $1800, size = $0840, type = rw; RAM2: file = "", define = yes, start = $2100, size = $0040, type = rw; RAM3: file = "", define = yes, start = $2200, size = $0600, type = rw; # For emulators you also need a header file HEADER: file = %O, start = $0000, size = 128; # Wizzy cartridge rom. # $4000..$7fff Banked RAM # - start must be a multiple of $1000 # - ROM must end at $ff79 RESIDENT: file = %O, define = yes, start = __BANK01_BOTTOM__, size = __BANK01_SIZE__, type = ro, fill = yes, fillval = $ff; WIZZY000: file = %O, define = yes, start = __BANK2_BOTTOM__, size = __BANK2_SIZE__, type = ro, fill = yes, fillval = $ff; MLEVEL000: file = %O, define = yes, start = __BANK3_BOTTOM__, size = __BANK3_SIZE__, type = ro, fill = yes, fillval = $ff; LEVEL000: file = %O, define = yes, start = __BANK4_BOTTOM__, size = __BANK4_SIZE__+__BANK5_SIZE__, type = ro, fill = yes, fillval = $ff; RLEVEL000: file = %O, define = yes, start = __BANK6_BOTTOM__, size = __BANK6_SIZE__, type = ro, fill = yes, fillval = $ff; # Extra area. Not used by MARIA. ROMH: file = %O, define = yes, start = __BANK7_BOTTOM__, size = __BANK7_SIZE__, type = ro, fill = yes, fillval = $ff; # Startup code. Good to be close to ROMS. ROMS: file = %O, define = yes, start = __INIT_BOTTOM__, size = __INIT_SIZE__, type = ro, fill = yes, fillval = $ff; # Encryption stuff ROME: file = %O, start = __ENCRYPT_BOTTOM__, size = __ENCRYPT_SIZE__, type = ro, fill = yes, fillval = $ff; # Interrupt vectors ROMV: file = %O, start = __VEC_BOTTOM__, size = __VEC_SIZE__, type = ro, fill = yes, fillval = $ff; # Bank 8 WIZZY008: file = "wizzybanks.dat", define = yes, start = __WBANK_BOTTOM__, size = __BANK_SIZE__, type = ro, fill = yes, fillval = $ff; # Bank 9 TILE000: file = "wizzybanks.dat", define = yes, start = __TBANK_BOTTOM__, size = __BANK_SIZE__, type = ro, fill = yes, fillval = $ff; # Bank 10 TILE001: file = "wizzybanks.dat", define = yes, start = __TBANK_TOP__, size = __BANK_SIZE__, type = ro, fill = yes, fillval = $ff; } SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp; EXEHDR: load = HEADER, type = ro, define = yes; CODE: load = RESIDENT, type = ro, define = yes; RODATA: load = RESIDENT, type = ro, define = yes, align = 256; DATA: load = RESIDENT, run = RAM1, type = rw, define = yes; W000: load = WIZZY008, type = ro, define = yes; M000: load = MLEVEL000, type = ro, define = yes; L000: load = LEVEL000, type = ro, define = yes; R000: load = RLEVEL000, type = ro, define = yes; BSS: load = RAM1, type = bss, define = yes; STARTUP: load = ROMS, type = ro, define = yes; ONCE: load = ROMS, type = ro, define = yes; ENCRYPTION: load = ROME, type = ro define = yes; VECTORS: load = ROMV, type = ro, define = yes; B008: load = WIZZY000, type = ro, define = yes; T000: load = TILE000, type = ro, define = yes; T001: load = TILE001, type = ro, define = yes; } FEATURES { CONDES: type = constructor, label = __CONSTRUCTOR_TABLE__, count = __CONSTRUCTOR_COUNT__, segment = ONCE; CONDES: type = destructor, label = __DESTRUCTOR_TABLE__, count = __DESTRUCTOR_COUNT__, segment = RODATA; CONDES: type = interruptor, label = __INTERRUPTOR_TABLE__, count = __INTERRUPTOR_COUNT__, segment = RODATA, import = __CALLIRQ__; } 4 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 11, 2023 Author Share Posted January 11, 2023 After a lot of fiddling around with the code I managed to pack my first Furnace tracker file to the compressed runlength format. The size is just 1700 bytes which will well fit into my 4096 byte buffer. The music was from the demo folder in furnace. Enjoy FirstFurnaceTest.mp3 The resulting file size is just 8% of the original vgm file. And I just export the SN76489AN chip music to the vgm file. 5 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 12, 2023 Author Share Posted January 12, 2023 As a newbie on the 7800 I don't know how much people read manuals of a game. The problem I see with Wizzy is that it is a bit difficult to create the right mood for an adventure game. Part of the mood comes from the music and the graphics. So I have been thinking on writing a small "novel" that doubles as a cheat sheet if you get stuck. Putting all this text in the game would not work. There will just be short sentences said by the npc's that hopefully nudge you in the right direction. Here is my first land "Suvi" as a taster. Suvi is the island where Wizzy has grown up and where our adventure begins. Wizzy.pdf If you plan to read my pdf above and want to give me positive feedback, please do so. The plan is to have all 7 lands in the book. These adventures can be solved in any order. But the game in one land follows the storyline in the book. So this is kind of a cinematic adventure. But you cannot have different endings. My plan is to create a single run of 40 copies containing the Wizzy game on a SN cart and a hand-bound small booklet around 90 pages. About same size as the cart. In order to keep them together. 4 Quote Link to comment Share on other sites More sharing options...
gambler172 Posted January 12, 2023 Share Posted January 12, 2023 Hi Karri Sounds great 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 14, 2023 Author Share Posted January 14, 2023 I hate self modifying code... You can only run the code in RAM. It is difficult to read. So I managed to initialize the vgc player and set the irq's at every frame. But playing the stuff turns the screen to purple after a while and the code breaks. My first concern is the instruction set. Do I use instructions that don't work on the 7800? Another thing that passed my mind is the rate 50Hz. I could block every 6th interrupt on NTSF 7800 to produce 50Hz for the music on both consoles. Fortunately most of the self modifying code is in the huffman part and I don't really need it just now. Edit: now I have fixed all crashes. The sound the vgcplayer produces is just noise right now. I assume the problem is in my misunderstanding of the original assembly syntax. Well, I realize now that the SN76489AN looks very different in the vlcplayer sources. How is the chip wired on the SN cart? Does it has just one data port? The original code referenced addresses $fe40, $fe43 and $fe4f. So I thought that they would be addresses on the SN76489AN. ; Write data to SN76489 sound chip ; A contains data to be written to sound chip ; clobbers X, A is non-zero on exit sn_write: ldx #255 stx SN76489AN_BASE+3 sta SN76489AN_BASE+15 inx stx SN76489AN_BASE lda SN76489AN_BASE ora #8 sta SN76489AN_BASE rts ; 21 bytes ; Reset SN76489 sound chip to a default (silent) state sn_reset: ; Zero volume on all channels lda #$9f jsr sn_write lda #$bf jsr sn_write lda #$df jsr sn_write lda #$ff jmp sn_write Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 14, 2023 Share Posted January 14, 2023 I had a song that played fine on the CPU, but when I played it on the DLI it started playing badly. I still have no clue why No problem with other songs at all. Worth remembering: Always clear zero page at the beginning If you use NMI and jump by JMP (DLIVECTOR), set DLIVECTOR before you set DLL (otherwise you will get JMP ($0000)) Try to not use WSYNC Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 14, 2023 Share Posted January 14, 2023 (edited) 1 hour ago, karri said: How is the chip wired on the SN cart? Does it has just one data port? The original code referenced addresses $fe40, $fe43 and $fe4f. So I thought that they would be addresses on the SN76489AN. It's just one $43F EDIT: Memory map BBC micro $FE40 6522 System VIA Output B / Input B Sound & Keyboard $FE41 6522 System VIA Output A / Input A $FE42 6522 System VIA Data Direction B $FE43 6522 System VIA Data Direction A $FE44 6522 System VIA T1 Low order Latches/Counter $FE45 6522 System VIA T1 High order Counter $FE46 6522 System VIA T1 Low order Latches $FE47 6522 System VIA T1 High order Latches $FE48 6522 System VIA T2 Low order Latches/Counter $FE49 6522 System VIA T2 High order Counter $FE4A 6522 System VIA Shift Register $FE4B 6522 System VIA Auxiliary Control Register $FE4C 6522 System VIA Peripheral Control Register $FE4D 6522 System VIA Interrupt Flags %v12ALSBK V=systemVia 1=Timer1 (100hz) 2=Timer2 (speech) A=Analog conv L=Lightpen S=Shift reg B=Vblank K=Keypress $FE4E 6522 System VIA Interrupt Enable $FE4F 6522 System VIA Output A / Input A - No Handshake Edited January 14, 2023 by Eagle Memory Map 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 14, 2023 Author Share Posted January 14, 2023 5 minutes ago, Eagle said: I had a song that played fine on the CPU, but when I played it on the DLI it started playing badly. I still have no clue why No problem with other songs at all. Worth remembering: Always clear zero page at the beginning If you use NMI and jump by JMP (DLIVECTOR), set DLIVECTOR before you set DLL (otherwise you will get JMP ($0000)) Try to not use WSYNC Thanks for the help. All my interrupts are the NMI's generated at the start and end zones. In cc65 I use interruptors so the system will make the calls to the interruptors automatically. I already have the sfx library in place with the TIA sound effects. It also uses interruptors. The only problem I had was to delay the interrupts until I had time to copy the vgcplayer to RAM and read in the bank with the correct music to $D000. Without Huffman the size was about 1980 bytes. With Huffman 1700 bytes. Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 14, 2023 Share Posted January 14, 2023 @karri I used Huffmunch for YM and SN before. Much easier and you don't need put your code in to Ram It's not that good as Exomizer but has some advantages. huffmunch_init lda #<vgm_data sta hm_node lda #>vgm_data sta hm_node+1 ldx #00 ldy #00 jsr huffmunch_load rts then jsr huffmunch_read an you will get one byte https://github.com/bbbradsmith/huffmunch huffmunch.asm 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 14, 2023 Author Share Posted January 14, 2023 20 minutes ago, Eagle said: It's not that good as Exomizer but has some advantages. Exomizer was used for packing the binary stuff. In the vgc player they used runlengths, lz and huffman. It is slower but much better compressed. So I can always fit my music into one 4k block. It is an important thing as the game is pretty large. Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 14, 2023 Share Posted January 14, 2023 This is how I'm changing bank $D000 to read data to play VGM Also you can store/restore bankcounter when you access $dxxx for any other reasons (reading level data, map, etc.) e.g. lda (snmusic),y sta SNBASE incbank .... .... .macro incbank inc snmusic bne @+ inc snmusic+1 lda snmusic+1 cmp #$E0 bne @+ lda #$D0 sta snmusic+1 inc bankcounter lda bankcounter sta $D000 @ .endm 1 Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 15, 2023 Share Posted January 15, 2023 (edited) @karri can you send me your vgm example? I can't find this music in Furnace demos. (VGM, bin and exo files please) Edited January 15, 2023 by Eagle Quote Link to comment Share on other sites More sharing options...
+karri Posted January 15, 2023 Author Share Posted January 15, 2023 9 hours ago, Eagle said: @karri can you send me your vgm example? I can't find this music in Furnace demos. (VGM, bin and exo files please) Yes. I picked a tune in demos/sms/doorintosummer.fur, removed the Yamaha chip from the song and exported the SN chip as a vgm file. I can try to convert it to bin and exo also. I only needed the vgc packed version in Wizzy. furnacetest.vgm Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 16, 2023 Share Posted January 16, 2023 OK. Tested and VGC compress better than Huffmunch but need much more memory. If you really need 512KB and you have spare CPU time then is worth to compress music. But if you need every cycle and lot of space left use BIN file and stream from $Dxxxx 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 16, 2023 Author Share Posted January 16, 2023 Thanks. I don't know what I need yet. I may try both approaches and choose later. Currently I am a bit stuck with a weird problem. If I copy my code from $d000 to $4000 if overwrites segment $5000 as well. And this happens before I execute the code at $4000. I wonder if my memcpy is bad in cc65 for the 7800? I can easily fix this by copying stuff in order $4000, $5000, $6000, $7000. But I would like to know why any other order causes problems. Debugging is a bit difficult when running on real hw... Edit: Case solved. When you use the linker to link in your code. Don't link it to address $D000 if you copy it to address $4000 for execution. When I debugged my map was using whatever happened to be in the $D000 bank. Sigh... 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 19, 2023 Author Share Posted January 19, 2023 The Huffmunch seems to work on my build. How do I know when the tune ends? In my build the huffmunch_read seems to crash at the end of the tune... Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 19, 2023 Share Posted January 19, 2023 Quote The length of the data will be returned from huffmunch_load in Y:X. Or just put $66 (vgm end) on the end of BIN file before you compress the file, then when you reach the end just cal huffmunch_load again. Quote Link to comment Share on other sites More sharing options...
+karri Posted January 19, 2023 Author Share Posted January 19, 2023 23 minutes ago, Eagle said: Or just put $66 (vgm end) on the end of BIN file before you compress the file, then when you reach the end just cal huffmunch_load again. Thanks! My setup that works is like: RAM0 RAM1 TILES0 HUFFMUNCH player TILES1 HFF music FONT HFF music MAP MAP To my big surprise it was easy and straight forward to make this work in Wizzy. The reason I put in the MAP in both banks was that scrolling is time consuming and I need the MAP all the time. The nice thing is that the music just keeps going in the background and I don't have to think about it. The sfx sound effects seem to work nicely with the music. A big plus! This also leaves me free to use bank $d000 at any time without concern of interrupts. 1 Quote Link to comment Share on other sites More sharing options...
+karri Posted January 20, 2023 Author Share Posted January 20, 2023 I have been playing with huffmunch a bit. It appears that single instruments doing vibrato or glides in frequency produce quite big files. Unfortunately I am very fond of flute-like sounds with glides and vibrato. But I still cannot get my vgcplayer to work properly. If I start with a vgm file I understand that there is two ways to go: 1) Huffmunch way - dump.py vgmconverter.py to convert vgm to raw - huffmunch to convert raw to hff + simple player, easy to get to work, sounds good 2) Vgc way - vgmpacker.py to convert vgm to vgc + Uses run-length encoding for every channel separately which compresses anything that is stable a LOT. Has also built-in huffman compression. But I have not been able to get it to work yet. The code is self-modifying so you need to run it in RAM. I may do something wrong here. But I recently tried to build my small furnacetest.vgm with both tools. 1) Huffmunch way: furnacetest.hff 8416 5822 bytes 2) Vgc way: furnacetest.vgc 1949 bytes It appears that I can get 4 times longer tunes if I can get the vgcplayer to work. (And if the code is fast enough to run during the blank period.) Edit: I can only play previously processed huffmunch files like CollisionChaos.hff. When I compress my own stuff it does not work. I wonder what the correct process is to convert a vgm file to hff format. python2 vgmconvert.py file.vgm -q50 -o file.bin huffmunch -B file.bin file.hff Quote Link to comment Share on other sites More sharing options...
Eagle Posted January 20, 2023 Share Posted January 20, 2023 5 hours ago, karri said: python2 vgmconvert.py file.vgm -q50 -o file.bin try this: python2 vgmconvert.py file.vgm - q 50 -n -r file.bin Quote Link to comment Share on other sites More sharing options...
+karri Posted January 20, 2023 Author Share Posted January 20, 2023 And it works! Perhaps I should name the final boss in Wizzy after you. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.