sverx / devkitsms Goto Github PK
View Code? Open in Web Editor NEWdevelopment kit and libraries for SEGA Master System / SEGA Game Gear / SEGA SG-1000 / SEGA SC-3000 homebrew programming using C language (and the SDCC compiler)
development kit and libraries for SEGA Master System / SEGA Game Gear / SEGA SG-1000 / SEGA SC-3000 homebrew programming using C language (and the SDCC compiler)
I am wondering how you were able to compile devkitSMS without the extra include. What stdbool.h does according to http://pubs.opengroup.org/onlinepubs/9699919799//basedefs/stdbool.h.html is expand bool to _Bool which allows me to compile it. Doing a search and replace for bool changing it to _Bool also allows me to compile it.
In C there is no keyword that I am aware of called bool; only _Bool please see http://en.cppreference.com/w/c/keyword.
I am using the latest snapshot of SDCC as of the time of writing the issue which is: 3.5.2 #9277
Can I use the makesms to convert the file that contains CODE and DATA bank?
func1.c~~~~~~
#pragma codeseg CODEBANK1
func1() __banked
~~~~~~
func2.c~~~~~~
#pragma codeseg CODEBANK2
func2() __banked
~~~~~~
data2.c~~~~~~
#pragma constseg DATABANK2
data2()
~~~~~~
data3.c~~~~~~
#pragma constseg DATABANK3
data3()
~~~~~~
#>sdcc -o file.ihx -mz80 --no-std-crt0 --data-loc 0xC000 -Wl-b_CODEBANK1=0x14000 -Wl-b_CODEBANK2=0x24000 -Wl-b_DATABANK2=0x8000 -Wl-b_DATABANK3=0x8000 crt0b_sms.rel SMSlib.lib main.rel fun1.rel func2.rel data2.rel data3.rel
#> makesms file.ihx file.sms
-> It won't run properly...?
When linking with a static library containing multiple code segments/banks, SDCC seems to arrange the segments in a random order (not in the order the lib sources were compiled and linked). This breaks ihx2sms because it assumes segment order == link order.
One way to solve this would be to have ihx2sms read the .map file which shows the order SDCC placed the segments in the .ihx file. Doing that would also eliminate the need to link objects in a specific order.
I was wondering if macros to save/restore the bank mapped to slot 2 would be something you would like to add to SMSlib.
Here is something I find extremely useful in my projects regarding data access by slot2. My convention is that by default, whenever the bank has to be changed to access data, it is to be set back to what it was before returning to avoid unwanted side effects.
For instance, in complex code which accesses banked data but also does calls to functions which may in turn also need to access banked data (in different banks), this helps a lot:
#define SAVEBANK() uint8_t _org_bank = ROM_bank_to_be_mapped_on_slot2
#define RESTOREBANK() SMS_mapROMBank(_org_bank)
So I just place one SAVEBANK() in the function, change the bank any number of time, and add one RESTOREBANK() before each return statement.
Using the above I also implemented a few convenience macros around the default SMSlib functions like this one:
#define SMS_loadTilesBank(src,bank,tilefrom,size) \
do { \
SAVEBANK(); \
SMS_mapROMBank(bank); \
SMS_loadTiles(src, tilefrom, size); \
RESTOREBANK(); \
} while(0)
What do you think? Let me know if you would like me to prepare a pull request.
In PSGLib, the function void PSGSetMusicVolumeAttenuation (unsigned char attenuation);
exists and it's great.
I want to use it to lower the volume all of the music to compensate for the SMS2's sound volume ramp being squashed in the upper values, and have it as an option to toggle in my game.
However, I noticed that there was no equivalent function for the sound effects.
Is it trivial enough to add?
I'm working on H-INT and V-INT.
When my program is using VDP function while H-INT and V-INT, graphics glitches sometimes occur.
Yes, I know the reason, both main loop and H/V-INT uses VDP function, graphics glitches occur.
Can I avoid this issue? I think DISABLE_INTERRUPTS & ENABLE_INTERRUPTS is not work properly...
First request:
While Devkit SMS has great horizontal consecutive tile setting functions, these are not as speedy if called for consecutive vertical tiles.
SMS_setNextTileatXY and SMS_setTile are pretty quick, especially if SMS_setNextTileatXY is set once before a loop calls SMS_setTile.
However, if the same is done in a vertical orientation of consecutive tiles. It takes quite a performance hit.
May I suggest a SMS_setNextTileatYX, or something to that affect?
The general thought is that whatever auto incrementor that is used for consecutive horizontal tiles function, can be utilized for consecutive vertical tiles, as well.
Second Request:
UNSAFE versions of SMS_VRAMmemset and SMS_VRAMmemsetW
Thank you for your time.
Hey there! I'd like to ask for some help with integrating PSGlib onto a project while using banked code.
Up until now I had been compiling my project like this:
sdcc -c -mz80 vania.c sdcc -c -mz80 --constseg BANK2 assets.c sdcc -c -mz80 --codeseg BANK1 xtra.c sdcc -o vania.ihx -mz80 --no-std-crt0 --opt-code-speed --data-loc 0xC000 -Wl-b_BANK1=0x14000 -Wl-b_BANK2=0x28000 crt0b_sms.rel SMSlib.lib PSGlib.rel vania.rel xtra.rel assets.rel makesms vania.ihx build/vania.sms
So bank1 contains banked code and bank2 contains assets. It was working perfectly, but I decided to add one extra bank for code and another for data, so I could better understand the process. So it went:
sdcc -c -mz80 vania.c sdcc -c -mz80 --codeseg CODEBANK1 xtra.c sdcc -c -mz80 --codeseg CODEBANK2 newcode.c sdcc -c -mz80 --constseg DATABANK3 assets.c sdcc -c -mz80 --constseg DATABANK4 tilemap.c sdcc -o vania.ihx -mz80 --no-std-crt0 --data-loc 0xC000 -Wl-b_CODEBANK1=0x14000 -Wl-b_CODEBANK2=0x24000 -Wl-b_DATABANK3=0x38000 -Wl-b_DATABANK4=0x48000 crt0b_sms.rel SMSlib.lib vania.rel xtra.rel newcode.rel assets.rel tilemap.rel makesms vania.ihx build/vania.sms
However, I found out (after way too long, haha) that the only way I could get the ROM to boot at all was by removing PSGlib from the project. It does boot, however there are some glitches due to (I guess) some overlap in RAM due to the lack of PSGlib.
So upon checking the readme for devkitSMS, there are no examples in which banked code is used alongside PSGlib. I've tried inserting the code for the library manually into my main file, to no avail. However, I copied the small example for banked code on SMSPower, added PSGlib to the command line and got it to work fine. (I should note however that I did not test if the library itself worked)
I noticed that apparently PSGlib located itself on bank0 in this test project, so I thought that maybe there was not enough room on bank0, although I doubt this is the case since theres is 4K+ left, and when using PSGlib before it still had 3K+.
So finally, my question is whether it's even possible to use PSGlib with banked code, if there's some detail I'm missing, etc.
Thanks in advance! =D
Unless programs are compiled with the --reserve-regs-iy
flag, SDCC expects the IY register to be preserved across calls just like IX.
In SMSlib_PSGaiden.c, IY is used but is not saved. IX is saved.
I'm trying to implement a fade-in , fade-out with the music, but it looks like the PSGSetMusicVolumeAttenuation is not working properly. Setting it to any value (from 0 to 15) makes the music be reduced a some static cracks. Has anyone tried to perform such a fade effect?
When the paddle reading functions were reworked and replaced by assembly code, the return value changed from int to unsigned char. This exactly fits the range of values reported by a paddle, which is good, but then there is no longer a way to report a timeout which occurs if the user disconnects the paddle.
So I was wondering if a pull request changing the return type back to int and also implementing timeouts in the assembly code would be acceptable or not. Is it allowed (by the SMS user manual) to change controllers when the power is on anyway?
Hi,
I'm not sure where else to put this, but I've been playing with loading SGlib programs from tape and have now got interrupts working. I thought I'd post a copy of my modified crt0_sg.s
here in case you wanted to make use of it.
The LOAD
command from basic puts things at 0x9800
It is jumped to using CALL &H9800
from BASIC.
For memory layout, I use:
0x8000
as the start of work-ram, for 5.5 KiB0x9600
as the interrupt vector table (using interrupt-mode 2)0x9800
is the start of loaded code, where the first line of crt0 gets placed0x9898
is the interrupt vector0x98a0
is the code-loc
that I pass to the linker, although I'm not sure if this is needed. The intention was to prevent user-code from clobbering anything in crt0.If counting from 0x9800, the program can reach 12 KiB on a BASIC IIIa cartridge, or 26 KiB on a BASIC IIIb cartridge.
Cheers,
Joppy
;--------------------------------------------------------------------------
; *** this is a modified version aimed to SG-1000 homebrew - sverx\2015 ***
; *** additional changes aimed at SC-3000 tape homebrew - JoppyFurr\2024 ***
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; crt0.s - Generic crt0.s for a Z80
;
; Copyright (C) 2000, Michael Hope
;
; This library is free software; you can redistribute it and/or modify it
; under the terms of the GNU General Public License as published by the
; Free Software Foundation; either version 2, or (at your option) any
; later version.
;
; This library is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this library; see the file COPYING. If not, write to the
; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
; MA 02110-1301, USA.
;
; As a special exception, if you link this library with other files,
; some of which are compiled with SDCC, to produce an executable,
; this library does not by itself cause the resulting executable to
; be covered by the GNU General Public License. This exception does
; not however invalidate any other reasons why the executable file
; might be covered by the GNU General Public License.
;--------------------------------------------------------------------------
; SC-3000 Tape Changes:
; - No interrupt handling, BASIC owns the vector addresses.
; - Code begins at 0x9800
; -> Has up to 0xc7ff for BASIC IIIa (12 KiB)
; -> Has up to 0xffff for BASIC IIIb (26 KiB)
; - RAM at 0x8000 -- 0x95ff (5.5 KiB) will be free once we take over from basic.
; - Interrupt Vector table at 0x9600 -- 0x9700 (257 bytes)
.module crt0
.globl _main
.area _HEADER (ABS)
.org 0x9800
start::
di ; disable interrupt
ld sp,#0x95f0 ; set stack pointer at end of our 5.5k block of RAM
xor a ; clear RAM (to value 0x00)
ld hl,#0x8000 ; by setting value 0
ld (hl),a ; to $c000 and
ld de,#0x8001 ; copying (LDIR) it to next byte
ld bc,#0x1600-17 ; for 5.5 KB minus 17 bytes
ldir ; do that
;; ensure this runs fine on SC-3000 too
ld a,#0x92
out (0xDF),a ; Config PPI (no effect on SG-1000)
ld a,#7
out (0xDE),a ; Select ROW 7 (row 7 of PPI is joypad = default - no effect on SG-1000)
;; Set up for interrupt-mode 2
;; Register I controls the vector MSB. The vector LSB is whatever happens to be on the bus.
;; So, a 257-entry table with a single repeated byte (0x98) will give us a reliable 0x9898 call.
im 2 ; interrupt mode 2 (this will not change)
ld a,#0x96 ; Vector table at 0x9600, between work-ram and code.
ld i,a
ld a,#0x98
ld hl,#0x9600
ld (hl),a ; Initialize first byte of vector table at 0x9600 to value 0x98
ld de,#0x9601 ; Prepare copy to the next byte
ld bc,#0x0100 ; Copy for 256 bytes, giving 257 bytes total.
ldir
;; Initialise global variables
call gsinit
call _SG_init
ei ; re-enable interrupts before going to main()
call _main
jp _exit
.org 0x9898 ; handle IRQ
jp _SG_isr
;; Ordering of segments for the linker.
.area _HOME
.area _CODE
.area _INITIALIZER
.area _GSINIT
.area _GSFINAL
.area _DATA
.area _INITIALIZED
.area _BSEG
.area _BSS
.area _HEAP
.area _CODE
__clock::
ld a,#2
rst 0x08
ret
_exit::
;; Exit - special code to the emulator
ld a,#0
rst 0x08
1$:
halt
jr 1$
.area _GSINIT
gsinit::
ld bc, #l__INITIALIZER
ld a, b
or a, c
jr Z, gsinit_next
ld de, #s__INITIALIZED
ld hl, #s__INITIALIZER
ldir
gsinit_next:
.area _GSFINAL
ret
There are a few mods to support SC-3000 in SG-1000.
I can send you some mod to let the roms be full compatible.
S.
SMS_saveROMBank is implemented as the following define:
#define SMS_saveROMBank() unsigned char _saved_slot2_ROM_bank = ROM_bank_to_be_mapped_on_slot2
This causes the var _saved_slot2_ROM_bank to be defined only in the same scope where SMS_saveROMBank is used. So, any call to SMS_restoreROMBank outside that scope will fail.
As an example, in my codebase have something like
if(flashCartridge) {
SMS_saveROMBank();
SMS_mapBANK(SAVE_BANK);
} else {
SMS_enableSRAM();
}
//Do saving stuff
if(flashCartridge) {
SMS_restoreROMBank();
} else {
SMS_disableSRAM();
}
Hi,
I noticed when testing my code on an SC-3000H, that gamepad input was not working correctly.
Instead of taking input from my gamepad, the input was coming from a handful of keyboard keys.
It looks like the cause is that in crt0_sg.s, the I/O chip control register is being initialized with 0x9f when it should be initialized with 0x92.
ld a,#0x9F
out (0xDF),a ; Config PPI (no effect on SG-1000)
Cheers,
Joppy
Using metasprites seems to clip sprites when they hit the top of the screen (y = 0). If I use the old addSprite method, the sprite stays on screen partially. Is this by design?
SMS_updateSpritePosition and SMS_updateSpriteImage don't seem to function anymore? As far as I can tell.
Hi sverx
First of all, I want to really thank you for your work grouping all that code into a single, coherent unit. This way it is much easier to do something for the SMS (sometime I plan to do when I have enough time).
I also wanted to ask you some questions about it:
Again, thak you very much for your work :)
Hey @raphnet !
I had an heads up about a strange bug that happens only with compressed songs with the PSGLIB_MULTIBANK version of the PSGlib library.
I suspect the issue happens when the two-byte address of a substring ends up exactly at the end of the bank ($BFFE
, $BFFF
) - in this case the mapper still retains the 'old' bank number when you get to this line so when the compressed block ends the music continues from the beginning of the bank that is the previous one instead of the one that should be, as you're saving $8000 in HL
ld (_PSGMusicSubstringRetAddr),hl ; save return address
but you're NOT saving the incremented bank number...
Can you look into this? Thanks! 🙇
It's not a problem, but is there a way to make calculations with 32-bit variables?
tried:
unsigned long ab = 0x10001;
char buffer[24];
sprintf(buffer, "%d", sizeof(ab));
draw_text(buffer, 9, 2);
sprintf(buffer, "%d", ab);
draw_text(buffer, 9, 3);
But this print:
4 and 1, so unsignd long is 32 bits but why cannot show?
drawText method.
void draw_text(unsigned char* text, unsigned char x, unsigned char y)
{
//const unsigned int* pnt = devkitSMS_font__tiles__1bpp;
unsigned char idx = 0;
while ('\0' != text[idx])
{
signed char tile = text[idx];// -TEXT_ROOT;
SMS_setNextTileatXY(x++, y);
SMS_setTile(SMS_TextRenderer_offset + tile);
idx++;
}
}
Thank you sverx for writing such a great library for sms. We like to collect shiny things in z88dk so devkitSMS has been incorporated into the new c library in z88dk for the sms. What has not been implemented is anything associated with GG or SC1000 as we're not sure yet if those machines are better served by their own independent targets inside z88dk; if it's decided to keep them part of the sms target, those functions will be added too. I chose not to go the fork route because keeping things compatible with sdcc was restricting too much what we could do.
I am sharing to let you know, first of all, but also because you are welcome to take anything back into the original project that you may find useful. In particular we've rewritten the C bits in assembler and separated each function into individual files. The assembler rewrite reduces size and allows more preserve_regs flags to be specified which can improve on code quality a small amount. It also makes the library directly accessible to asm programmers. The fine granularity allows the linker to pick out individual subroutines from the library which can reduce program size somewhat.
PSGlib source code
SMSlib source code
How devkitSMS is configured inside z88dk
You can use devkitSMS with any crt but a devkitSMS-specific one is selected with "-startup=8" on compile lines. What this will do is place the two RSTs and the MI / NMI isrs in the right places, like what is done with native devkitSMS's crt for sdcc.
For testing we are using some source from the smspower website:
split-screen
Your split screen example. The original bmp assets are not committed - only the processed form required by the compile. I hope it's ok if we can use it in our examples directory?
These others we do not have permission to host so they are temporarily in a separate branch that will ultimately be deleted:
Temporary Examples
(I'm also still working a bit in there so the readme.txt are a little curt)
The one main difference between devkitSMS and this adaptation is that the macros used to defined the SEGA/SDSC headers are turned into no-ops. In z88dk, header information is specified via pragmas which you will find (optionally) defined in zpragma.inc files associated with the examples above.
Thanks again sverx; feel free to close any time.
Hi, I read the content of SG_byte_brief_array_to_VDP_data function and I found it copies data from a ram buffer to SAT.
I wonder if you can insert a reverse-copy function in order manage the sprites-on-a-line limit (4 on SC/SG).
Usually I copy SAT buffer to vram SAT in normal mode on even frames and copy SAT buffer to vram SAT in reverse mode on odd frames.
Probably (if I didn't see it) could be useful a "SG_byte_reverse_array_to_VDP_data" function.
Times ago I built it by myself in ASM but I put it in CRT function as standard/fast function.
What do you think about it?
Cheers,
Saverio
I was wondering what you would think of adding an examples/ directory to the root of the repo, where examples and demos using different devkitSMS features could be added? I notice there is no such thing, so maybe you prefer to have this elsewhere?
For instance, when contributing new features, I often make a simple program to test it but there is no good place to share it right now. I think it would make sense to have examples here, those could also be an easy starting point for new projects.
I don't know if this has been implemented yet, or exists. Say a metasprite has been defined eg:
// Frame 0 of multi framed sprite, for entity with loads of states, but tiles may be located differently for each instance:
const unsigned char sprite_00[] = { 0, 0, 0, 8, 0, 2, 16, 0, 4, 0, 16, 6, 8, 16, 8, 16, 16, 10, 0, 32, 12, 8, 32, 14, METASPRITE_END };
Is there a way to offset the tile id, so that the tile id starts with the array tile id + offset?
Sort of like:
SMS_addMetaSprite(x, y, [offset], sprite_00);
Where [offset] would be applied to the defined tile id for each sprite.
I'm very interested to use this library but I wondered if there are any sample projects that use this library? I've searched but haven't been able to find anything.
Hello!!!
When running on real Master System II, the logo SEGA dont is removed after devkit finish startup.
Configured the Emulicious emu with same bios(EU with Alex kid in memory), cause the same issue. Só i make a clearscreen code in asm and run at begin from me main program.
I dont know how to do a Pull requests (rsrsrs) so, need clear vram at startup to remove logo SEGA from screen.
Thats not a issue, Sorry doing this here
#enhancement
Is there any way to assign tile flags to the target? In my use case, it would be nice if the target xy tile used the sprite palette instead of the background palette. I'd imagine if this were supported, that you would need to consider the other bits as well (flipping, priority, etc.. etc..)
Unless there's another function that would be better for this. I do like the simplicity of the function, when changing a single tile on the map. Thank you for your time.
Hello,
Have been trying to use assets2banks with files larger than 16kb and even with --allowsplitting it didn't output any banks, and just gave the "Fatal: no banks generated" error
I had a play about with the python code and managed to get it working by making some changes at around line 480 where i set the part.size and apartgrp.size like this:
if a.size <= gf and offset == 0:
apartgrp.add_asset(a)
else:
part = Asset(a.name + "_PART" + str(partno), l)
part.data = a.data[offset:offset+l]
part.size = l
apartgrp.size += l
apartgrp.add_asset(part)
I think apartgrp.size needs to be set as it's is used in the gf = 16384 - apartgrp.size
and if apartgrp.size > 0:
in that section to actually add the assets to banks
Have uploaded my modified version but I'm sure you'll know the proper way to do it!
Thanks,
Joe
assets2banks.zip
It would be nice to have a SMS_setVerticalInterruptHandler() to install a callback that would run every vblank, similar to the way line interrupts work.
Hello,
In readme, you"re talking about sdcc 3.9.5, but I can only find 3.9.0 version here : http://sdcc.sourceforge.net/ or https://sourceforge.net/projects/sdcc/files/
Where can I find sdcc 3.9.5 ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.