mmc3 loading screen !

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
v.depatie
Posts: 121
Joined: Sun Nov 03, 2024 4:01 pm

mmc3 loading screen !

Post by v.depatie »

Almost got my game back, got the music.
And a loading screen !

This is all using mmc3 mapper.

Switchable @c000
fixed $8000 and $e000

My font is in the third chr bank bank, I did a bank switch to get access to it !

Pure ASM. Pure fun. Almost ready to continue writing the game :D

Feel free to ask any questions, Ill share
Attachments
cart - with story.nes
(256.02 KiB) Downloaded 13 times
User avatar
DRW
Posts: 2273
Joined: Sat Sep 07, 2013 2:59 pm

Re: mmc3 loading screen !

Post by DRW »

When I keep holding the Start button for a white, the screen becomes gray.
cart - with story-0.png
cart - with story-0.png (2.7 KiB) Viewed 531 times
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
v.depatie
Posts: 121
Joined: Sun Nov 03, 2024 4:01 pm

Re: mmc3 loading screen !

Post by v.depatie »

Almost done with loading screen yay :D .

This one freeze black screen on the third start. As intended. I cant get to gray screens now can you still?

Will continue this post on homebrew soon
Attachments
cart - loading screen2.nes
(256.02 KiB) Downloaded 11 times
User avatar
donato-zits-
Posts: 92
Joined: Fri Jun 03, 2022 11:14 am
Location: -&&.&&&&&, -88.88888
Contact:

Re: mmc3 loading screen !

Post by donato-zits- »

Cool man!MMC3 is an excellent mapper goal to build a game with very abrangent freedow of memory, affter I will write more in the coment ,now I have another thingts to do here, but I wants to comment othes subjects( my skills of North Amerikan/Duck comunication are not soo good, soo too much time I spend writing)

edit: well my attemps to build, or better to correctlly understand the mapper do not begun yet but I already have a build(attached), my next concetration will be take a closelly loodk to maths that I dont compreend yet like this two ones:

Code: Select all

  
.proc Checkcolider
   
  txa
  lsr 
  lsr 
  lsr 
  lsr 
  sta temp
  
  tya
  and #$F0
  ora temp
  tay
  
  ; lda #<screenData         ;load the map
  ; sta pointer+0
  ; lda #>screenData
  ; sta pointer+1
  
  
  LDA RAM_0700,y
  TAX
  LDA metatileAtribute,x
  
 
 rts 
.endproc
 ;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;

||||||||||||||||||||||||||||||||||||||||||||||||




.proc change_Checkcolider
  pha
  txa
  lsr 
  lsr 
  lsr 
  lsr 
  sta temp
  
  tya
  and #$F0
  ora temp
  tay
  
  
  pla
  sta RAM_0700,y
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
  
   

  lda #$20>>2          ; >>desloka los bits
  sta addrHi
  
  
  tya
  and #%11110000
  asl 
  ROL addrHi
  asl 
  rol addrHi
  
  and #%11000000
  sta addrLo
  tya
  and #%00001111
  asl 
  ora addrLo
  sta addrLo
 
  lda addrHi
  sta graphicsBuffer+1
  adc #$00
  sta graphicsBuffer+6
  lda addrLo
  sta graphicsBuffer+2
  clc
  adc #$20
  sta graphicsBuffer+7
  
  lda #$02
  sta graphicsBuffer+0
  sta graphicsBuffer+5
  lda#$00
  sta graphicsBuffer+10
  
   lda metatileTopLeft+2
  sta graphicsBuffer+3
  lda metatileTopRight+2
  sta graphicsBuffer+4
 lda metatileBottomLeft+2
 sta graphicsBuffer+8
 lda  metatileBottomRight+2
 sta graphicsBuffer+9

 rts 
.endproc
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;

||||||||||||||||||||||||||||||||||||||||||||||||


and then try a simple free scroll whiout colision or right-places spawn to the non-char objetcs, I hope that maths understanding will engage my mind in a way forward annother whole field of programing posibilitys
Attachments
MMC3_6banks-($C000-switchable).rar
(808.4 KiB) Downloaded 13 times
viewtopic.php?t=24252 <<<<my game
viewtopic.php?t=25285 <<<my second game
User avatar
DRW
Posts: 2273
Joined: Sat Sep 07, 2013 2:59 pm

Re: mmc3 loading screen !

Post by DRW »

v.depatie wrote: Thu Jan 09, 2025 10:11 pm I cant get to gray screens now can you still?
Indeed, I can. Sometimes.

Have a look at the movies in the attachments. They are for playback in fceux 2.2.3.
Under "Config", "Display", "Input Display", you can let the emulator show the button input.
Also, you can enable a lag counter to see that the game starts to freeze (or at least no input is read anymore, a lag is detected if there's no controller reading in one frame)
Attachments
Movies.zip
(831 Bytes) Downloaded 8 times
My game "City Trouble":
Gameplay video: https://youtu.be/Eee0yurkIW4
Download (ROM, manual, artworks): http://www.denny-r-walter.de/city.html
v.depatie
Posts: 121
Joined: Sun Nov 03, 2024 4:01 pm

Re: mmc3 loading screen !

Post by v.depatie »

cool,

Im almost there :D , slowly but surely getting there.
Untitled.png
Attachments
cart - almost there.nes
(256.02 KiB) Downloaded 8 times
v.depatie
Posts: 121
Joined: Sun Nov 03, 2024 4:01 pm

Re: mmc3 loading screen !

Post by v.depatie »

donato-zits- wrote: Fri Jan 10, 2025 7:20 am Cool man!MMC3 is an excellent mapper goal to build a game with very abrangent freedow of memory, affter I will write more in the coment ,now I have another thingts to do here, but I wants to comment othes subjects( my skills of North Amerikan/Duck comunication are not soo good, soo too much time I spend writing)

edit: well my attemps to build, or better to correctlly understand the mapper do not begun yet but I already have a build(attached), my next concetration will be take a closelly loodk to maths that I dont compreend yet like this two ones:

Code: Select all

  
.proc Checkcolider
   
  txa
  lsr 
  lsr 
  lsr 
  lsr 
  sta temp
  
  tya
  and #$F0
  ora temp
  tay
  
  ; lda #<screenData         ;load the map
  ; sta pointer+0
  ; lda #>screenData
  ; sta pointer+1
  
  
  LDA RAM_0700,y
  TAX
  LDA metatileAtribute,x
  
 
 rts 
.endproc
 ;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;

||||||||||||||||||||||||||||||||||||||||||||||||




.proc change_Checkcolider
  pha
  txa
  lsr 
  lsr 
  lsr 
  lsr 
  sta temp
  
  tya
  and #$F0
  ora temp
  tay
  
  
  pla
  sta RAM_0700,y
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
  
   

  lda #$20>>2          ; >>desloka los bits
  sta addrHi
  
  
  tya
  and #%11110000
  asl 
  ROL addrHi
  asl 
  rol addrHi
  
  and #%11000000
  sta addrLo
  tya
  and #%00001111
  asl 
  ora addrLo
  sta addrLo
 
  lda addrHi
  sta graphicsBuffer+1
  adc #$00
  sta graphicsBuffer+6
  lda addrLo
  sta graphicsBuffer+2
  clc
  adc #$20
  sta graphicsBuffer+7
  
  lda #$02
  sta graphicsBuffer+0
  sta graphicsBuffer+5
  lda#$00
  sta graphicsBuffer+10
  
   lda metatileTopLeft+2
  sta graphicsBuffer+3
  lda metatileTopRight+2
  sta graphicsBuffer+4
 lda metatileBottomLeft+2
 sta graphicsBuffer+8
 lda  metatileBottomRight+2
 sta graphicsBuffer+9

 rts 
.endproc
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;

||||||||||||||||||||||||||||||||||||||||||||||||


and then try a simple free scroll whiout colision or right-places spawn to the non-char objetcs, I hope that maths understanding will engage my mind in a way forward annother whole field of programing posibilitys

NOT to sure what you are trying to do but I commented your code; you should always do that so your maths brain see's . Im not sure what your trying to do though....

Code: Select all

; ===== Checkcolider =====
.proc Checkcolider

  ; Transfer the X register to the A register
  txa
  ; Perform 4 logical shifts right to divide the value by 16
  lsr 
  lsr 
  lsr 
  lsr 
  ; Store the result in the temporary variable
  sta temp
  
  ; Transfer the Y register to the A register
  tya
  ; Mask the lower nibble (keep only the upper 4 bits)
  and #$F0
  ; Combine the upper 4 bits of A with the lower 4 bits from temp
  ora temp
  ; Store the result back in the Y register
  tay
  
  ; Load a value from RAM_0700 indexed by Y
  LDA RAM_0700,y
  ; Transfer the loaded value to the X register
  TAX
  ; Load a value from the metatile attributes table indexed by X
  LDA metatileAtribute,x
  
  ; Return from subroutine
  rts 
.endproc

;;;;;;;;;;;;;;;;;;;;;;;;;;
; ===== change_Checkcolider =====
;;;;;;;;;;;;;;;;;;;;;;;;;;

.proc change_Checkcolider
  ; Save the accumulator value on the stack
  pha
  ; Transfer the X register to the A register
  txa
  ; Perform 4 logical shifts right to divide the value by 16
  lsr 
  lsr 
  lsr 
  lsr 
  ; Store the result in the temporary variable
  sta temp
  
  ; Transfer the Y register to the A register
  tya
  ; Mask the lower nibble (keep only the upper 4 bits)
  and #$F0
  ; Combine the upper 4 bits of A with the lower 4 bits from temp
  ora temp
  ; Store the result back in the Y register
  tay
  
  ; Restore the accumulator value from the stack
  pla
  ; Store the accumulator value into RAM_0700 indexed by Y
  sta RAM_0700,y

  ; Set up the high byte of an address
  lda #$20>>2          ; Shift $20 right by 2 bits
  sta addrHi
  
  ; Prepare the high byte of the address based on Y register
  tya
  and #%11110000       ; Keep only the upper 4 bits of Y
  asl                  ; Shift left 1 bit
  ROL addrHi           ; Rotate into addrHi
  asl                  ; Shift left 1 bit
  rol addrHi           ; Rotate into addrHi again

  ; Prepare the low byte of the address
  and #%11000000       ; Keep the two most significant bits
  sta addrLo           ; Store partial result in addrLo
  tya
  and #%00001111       ; Keep only the lower nibble
  asl                  ; Shift left 1 bit
  ora addrLo           ; Combine with the previous result in addrLo
  sta addrLo           ; Finalize addrLo

  ; Set up graphics buffer for rendering
  lda addrHi
  sta graphicsBuffer+1 ; Store high byte of address
  adc #$00             ; Add carry (default is 0)
  sta graphicsBuffer+6 ; Store updated high byte of address
  lda addrLo
  sta graphicsBuffer+2 ; Store low byte of address
  clc                  ; Clear carry flag
  adc #$20             ; Add $20 to calculate the next tile's low byte
  sta graphicsBuffer+7 ; Store result

  ; Fill in graphics buffer properties
  lda #$02
  sta graphicsBuffer+0 ; Set graphics property 1
  sta graphicsBuffer+5 ; Set graphics property 2
  lda#$00
  sta graphicsBuffer+10 ; Clear extra property

  ; Load metatile attributes into the graphics buffer
  lda metatileTopLeft+2
  sta graphicsBuffer+3
  lda metatileTopRight+2
  sta graphicsBuffer+4
  lda metatileBottomLeft+2
  sta graphicsBuffer+8
  lda metatileBottomRight+2
  sta graphicsBuffer+9

  ; Return from subroutine
  rts 
.endproc

v.depatie
Posts: 121
Joined: Sun Nov 03, 2024 4:01 pm

Re: mmc3 graphics loaded for level 1 , final cfg file

Post by v.depatie »

Got my graphic loaded !

Remember my initial goal was to trnsfer a project from UNROM to mmc3. :x It was to big, the code was more than 8kb :lol: :beer: so I could notjust copy paste the code. I had to understand the mapper and split everything into memory . Remember the mmc3 mapper is many 8kb banks ( size $2000 )

So what I did .... :idea: :

I've put the main routines AND includes at $e000, in the fixed bank with the startup segment/reset code. Since its the loading screen, I also put the ROdata for the title screen, the book title, and the first page of the story. This was enough to fill $2000 sized bank ( $e000 ).

at $8000,size $2000, in the CODE segment, I have more routines and includes. Then the CODE_LOADING_SCREEN segment, with the music infinity loop, and NMI''s. My NMI routine will be splitted into nmi_level1, nmi_level2 eventually, so thats it for $8000.


in my $c000 switchables, I load my dmc samples. Got 11 banks of size $2000 so far.

in my $a000 switchables, 3 banks of size $2000 as well, I will put my level routines. SO at abank_level1, the includes, the READ only data ( ROdata_level1 ) and the code; the main infinity loop for level one. Thats where the NMI_level1 RTI will go back to when level one is loaded.

so thats in size 128kb ( e000 + 3 * a000 + 11 * c000 + 1 * 8000 , 16 block of size $2000, 8kb each )


Finally I also have 8kb of prg-RAM, I call it XRAM. Its working like a charm, you have to activate it at the beginning of lets say the reset code:

Code: Select all

LDA #%10000000   ; enable prg-RAM, bit 7 and allow writes, bit 6
STA $A001            ; Write to $A001 . bit 7 is to enable if 1 , bits 6 is to allow writes, if 0
 
Indeed there is also all my chr-banks. I've got 3 loaded so far, but got enough memory for 128 kb, 16 banks of 8kb each.



Here is my final config ( very personalized, see other post for a basic cfg file or pm me ):

Code: Select all

MEMORY {

#INES Header:
    HEADER: start = $0, size = $10, file = %O ,fill = yes;

#RAM Addresses:
    # Zero page
    ZP: start = $00, size = $100, type = rw, file = "", define = yes;
	#note, the c compiler + neslib + famitone2 use about 60 zp addresses, I think
	
	#note OAM: start = $0200, size = $0100, define = yes;
	#note, sprites stored here in the RAM
	
	RAM: start = $0300, size = $0400, file = "", define = yes;
	
	
	WRAM: start = $6000, size = $2000, file = "", fill=yes, fillval=$00,define = yes;


#ROM Addresses:
		
	DMC: 		start = $C000, size = $2000, file = %O, fill = yes, define = yes;					# Switchable PRG-ROM bank for my dmc samples
	DMC2: 		start = $C000, size = $2000, file = %O, fill = yes, define = yes;  					# Switchable PRG-ROM bank for my dmc samples
	DMC3: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;  	# Switchable PRG-ROM bank for my dmc samples 
	DMC4: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;   	# Switchable PRG-ROM bank
    DMC5: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;      # Switchable PRG-ROM bank
    DMC6: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;      # Switchable PRG-ROM bank
    DMC7: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;      # Switchable PRG-ROM bank
    DMC8: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;      # Switchable PRG-ROM bank
    DMC9: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;      # Switchable PRG-ROM bank
    DMC10: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF, define = yes;      # Switchable PRG-ROM bank
	DMC11: 		start = $C000, size = $2000, file = %O, fill = yes, fillval=$FF,  define = yes;     # Switchable PRG-ROM bank

	#DMC12: 	start = $C000, size = $2000, file = %O, fill = yes, define = yes;  				    # Switchable PRG-ROM bank 
	#DMC13: 	start = $C000, size = $2000, file = %O, fill = yes, define = yes;  				    # Switchable PRG-ROM bank
	
	PRG:  		start = $A000, size = $2000, file = %O, fill = yes, define = yes;  		  # Switchable PRG-ROM bank for $A000-$BFFF
	PRG2:  		start = $A000, size = $2000, file = %O, fill = yes, define = yes;   	  # Switchable PRG-ROM bank for $A000-$BFFF
	PRG3:  		start = $A000, size = $2000, file = %O, fill = yes, define = yes;   	  # Switchable PRG-ROM bank for $A000-$BFFF
	
	
	#since we are using $c000 switchable THIS HAVE TO BE HERE for mmc3 to work correctly!!! correct me if im wrong, cc65 compiler.	
	PRG_FIXED: 	start = $8000, size = $2000, file = %O, fill = yes, define = yes;  # Fixed PRG-ROM, second-last bank, 
	
	PRGRESET: 	start = $E000, size = $2000-6, file = %O, fill = yes, define = yes;   # Fixed PRG-ROM for reset at last bank
	# make sure the reset code is in e000-ffff, and vectors at that end.	
	ROMV:       start = $FFFA, size = $6 , file =%O, fill = yes, define = yes ;
	

	
	
# ! 16 Banks of 8K CHR ROM
	CHR0: 		start = $0000,  size = $2000, file = %O, fill = yes;
    CHR1: 		start = $2000,  size = $2000, file = %O, fill = yes;
    CHR2: 		start = $4000,  size = $2000, file = %O, fill = yes;
    CHR3: 		start = $6000,  size = $2000, file = %O, fill = yes;
    CHR4: 		start = $8000,  size = $2000, file = %O, fill = yes;
    CHR5:	 	start = $A000,  size = $2000, file = %O, fill = yes;
    CHR6:		start = $C000,  size = $2000, file = %O, fill = yes;
    CHR7:		start = $E000,  size = $2000, file = %O, fill = yes;
    CHR8: 		start = $10000, size = $2000, file = %O, fill = yes;
    CHR9:	    start = $12000, size = $2000, file = %O, fill = yes;
    CHR10: 		start = $14000, size = $2000, file = %O, fill = yes;
    CHR11:	    start = $16000, size = $2000, file = %O, fill = yes;
    CHR12:		start = $18000, size = $2000, file = %O, fill = yes;
    CHR13:		start = $1A000, size = $2000, file = %O, fill = yes;
    CHR14:		start = $1C000, size = $2000, file = %O, fill = yes;
    CHR15:		start = $1E000, size = $2000, file = %O, fill = yes;
}




SEGMENTS {
    HEADER:  	 load = HEADER,         type = ro;
    ZEROPAGE:	 load = ZP,             type = zp;
	
# this needs to be in right order and nothing missing except optionals
	#LOWCODE:  	 load = PRG_FIXED,      type = ro,                optional = yes;
	#INIT:     	 load = PRG_FIXED,      type = ro,  define = yes, optional = yes;
	
	#IT SEEMS THIS SEGMENT CODE IS MANDATORY FOR MMC3 to work fine, correct me if IM wrong
    CODE:    	 load = PRG_FIXED,      type = ro,  define = yes;
    CODE_START:  load = PRG_FIXED,      type = ro,  define = yes;
	CODE_LOADING_SCREEN: load = PRG_FIXED, 		type = ro,  define = yes;
	
	
    #DATA:  	 load = PRG, run = RAM, type = rw,  define = yes;
    
    BSS:   		 load = RAM,           	type = bss, define = yes;
    #HEAP:   	 load = RAM,            type = bss, optional = yes;
    
    #ONCE:   	 load = PRG_FIXED,      type = ro,  define = yes;
	
	XRAM:	 	 load = WRAM,			type = rw, define = yes;

	

ABANK_LEVEL1: 		load = PRG,        	type = ro, define = yes;	# SWITCHABLE $A000 #1
CODE_START_LEVEL1: 	load = PRG, 		type = ro, define = yes;    # ppu startup lvl_1
RODATA_LEVEL1:		load = PRG,         type = ro, define = yes;    # rodata for level 1	
	
	
	ABANK2: 	 load = PRG2,          	type = ro, define = yes;	# SWITCHABLE $A000 #2 
	ABANK3: 	 load = PRG3,          	type = ro, define = yes;	# SWITCHABLE $A000 #3
	 
	DMCBANK1:    load = DMC,         	type = ro, define = yes; 	#$C000 first of 13 banks
    DMCBANK2:    load = DMC2,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM 
    DMCBANK3:    load = DMC3,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM 
    DMCBANK4:    load = DMC4,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM 
    DMCBANK5:    load = DMC5,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM 
    DMCBANK6:    load = DMC6,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM
    DMCBANK7:    load = DMC7,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM
    DMCBANK8:    load = DMC8,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM 
    DMCBANK9:    load = DMC9,           type = ro, define = yes;   	# SWITCHABLE PRG-ROM 
    DMCBANK10:   load = DMC10,          type = ro, define = yes;   	# SWITCHABLE PRG-ROM
    DMCBANK11:   load = DMC11,          type = ro, define = yes;   	# SWITCHABLE PRG-ROM 
 	
	# startup needs to be in the e000-ffff fixed bank
	STARTUP: 	 load = PRGRESET,       type = ro, define = yes;
RODATA_RESET:	 load = PRGRESET,      	type = ro, define = yes;
RODATA_STORY1:	 load = PRGRESET, 		type = ro, define = yes;
	# VECTORS at the last fixed bank, in our case startup
	VECTORS:  	 load = ROMV, 			type = ro;

	CHARS:   	 load = CHR0,           type = ro;
	CHARS2:   	 load = CHR1,           type = ro;
	CHARS3:   	 load = CHR2,           type = ro;

}
#I know nothing yet about theses, not even sure we need it.
#FEATURES {
#    CONDES: segment = INIT,
#        type = constructor,
#        label = __CONSTRUCTOR_TABLE__,
#        count = __CONSTRUCTOR_COUNT__;
#    CONDES: segment = RODATA,
#        type = destructor,
#        label = __DESTRUCTOR_TABLE__,
#        count = __DESTRUCTOR_COUNT__;
#   CONDES: type = interruptor,
#        segment = RODATA,
#        label = __INTERRUPTOR_TABLE__,
#        count = __INTERRUPTOR_COUNT__;
#}
Also attach my main cart.s and cart.nes
cart - mmc3 with graphic loaded !.nes
(256.02 KiB) Downloaded 9 times

PM me or post if you have any questions, im going back to homebrew soon
Attachments
cart.s
(4.59 KiB) Downloaded 8 times
v.depatie
Posts: 121
Joined: Sun Nov 03, 2024 4:01 pm

TEXT to hex tiles ( string to ASM rodata )

Post by v.depatie »

https://www.programiz.com/online-compiler/8eYhLWJZZ8B42

Working like a charm, its creating 32 kb long sentences you can load directly into a cart ( providing you use the same tile arrangement:
; $00 = Space (Blank)
; $01 = Comma (,)
; $02-$1B = A-Z / a-z (Case-insensitive, A=$02, Z=$1B)
; $1C-$25 = 0-9 (0=$1C, 9=$25)
; $26 = Dollar sign ($)
; $27 = Plus sign (+)
; $28 = Minus sign (-)
; $29 = Exclamation mark (!)
; $2A = Question mark (?)
; $2B = Single quotation mark (')
; $2C = Period (.)
; -1 = Invalid character (Ignored)

you can load this font.asm and load it into chr.
)

Code: Select all

#include <stdio.h>
#include <string.h>

#define MAX_INPUT_SIZE 8192
#define ROW_SIZE 32

char get_tile_index(char c) {
    if (c == ' ') return 0x00;               // Blank
    else if (c == ',') return 0x01;         // Comma
    else if (c >= 'A' && c <= 'Z') return 0x02 + (c - 'A'); // A-Z
    else if (c >= 'a' && c <= 'z') return 0x02 + (c - 'a'); // a-z
    else if (c >= '0' && c <= '9') return 0x1C + (c - '0'); // 0-9
    else if (c == '$') return 0x26;         // Dollar sign
    else if (c == '+') return 0x27;         // Plus sign
    else if (c == '-') return 0x28;         // Minus sign
    else if (c == '!') return 0x29;         // Exclamation mark
    else if (c == '?') return 0x2A;         // Question mark
    else if (c == '\'') return 0x2B;        // Single quotation mark
    else if (c == '.') return 0x2C;         // Period
    return -1;                              // Invalid character
}

void print_asm_bytes(const char *input) {
    int index = 0;
    int row_count = 0;
    int current_row_size = 0;

    printf(".byte ");

    while (input[index] != '\0') {
        char tile_index = get_tile_index(input[index]);

        if (tile_index != -1) {
            if (current_row_size == ROW_SIZE) {
                printf("\n.byte ");
                row_count++;
                current_row_size = 0;
            }

            if (current_row_size > 0) {
                printf(",");
            }
            printf("$%02X", tile_index);
            current_row_size++;
        } else if (input[index] == ' ') {
            // Handle spaces to ensure words fit within rows
            if (current_row_size + 1 > ROW_SIZE) {
                printf(",\n.byte $00");
                row_count++;
                current_row_size = 1;
            } else {
                if (current_row_size > 0) {
                    printf(",");
                }
                printf("$00");
                current_row_size++;
            }
        }

        index++;
    }

    // Pad the last row with $00 if it isn't full
    while (current_row_size < ROW_SIZE) {
        if (current_row_size > 0) {
            printf(",");
        }
        printf("$00");
        current_row_size++;
    }

    printf("\n");
}

int main() {
    char input[MAX_INPUT_SIZE + 1];  // Allow up to 8192 characters plus null terminator

    // Prompt the user for input
    printf("Enter a string (max 8192 bytes): ");

    // Read the input string
    if (fgets(input, MAX_INPUT_SIZE + 1, stdin) == NULL) {
        printf("Error reading input\n");
        return 1;
    }

    // Remove newline character if present
    size_t len = strlen(input);
    if (len > 0 && input[len - 1] == '\n') {
        input[len - 1] = '\0';
    }

    // Print the assembly representation of the tile indices
    print_asm_bytes(input);

    return 0;
}

saving it for future uses
Attachments
font.asm
(11.42 KiB) Downloaded 8 times
Post Reply