|
Post by dshadoff on Feb 14, 2020 18:09:52 GMT
The inability to easily choose your library/libraries in having multiple choices, is what makes HuC entry level. A C developer should be able to choose what library and what sections of a library to tailor to their needs, without having an advance level of understanding of assembly and the underlying environment. That would be a start. And that is primarily because it doesn't have a linker. Not that I'm advocating for a linker to be written... there could be a middle ground where included code is appended into named groups of banks (i.e. BOOT/BASE/DATA/USER) before fixed bank numbers are assigned to them, allowing for a much larger degree of flexibility. But page-in/page-out operations take up a lot of space and time, complicating the process, and the machine might not choose to optimally co-locate those functions... Sadly, each solution seems to come with an associated new problem which is at least as complicated as the problem it was intended to solve. This is why I like HuC as a platform to test ideas and get the algorithms working prior to hand-optimization into assembly (but that's just me).
|
|
|
Post by DarkKobold on Feb 14, 2020 18:14:51 GMT
I guess its not good to get caught up on words. Its just, HuC is the beginning and end of my PCE career. I have no intentions of moving into a full-code or even partial ASM programmer. So, the words "entry level" kinda suggest to me, no matter how many games I make, no matter what I manage to achieve, all my stuff is just "entry level," and I'll never surpass that. So, yeah, maybe I take a bit of unnecessary offense, because the idea I'm just perpetually an entry-level PCE coder hurts the feel-bads.
I agree with not being able to choose what goes into the startup banks, or much less add your own code to those banks is a deficit. But a possibly fixable one? The way globals.h works means you don't even #include it. I think having a "common.c" that includes all of the library selection, plus a few extra functions that you can force into the early banks would be great.
Also, thanks to a discussion with Arkhan last night, I solved all of my space issues by using the ADPCM ram to store enemies. I haven't tested performance on actual hardware yet, but in the emulator it works perfect. I even have free banks to work with!
|
|
|
Post by dshadoff on Feb 14, 2020 19:20:13 GMT
I understand where you're coming from; I've been there. Around 1979 or so, I started out programming BASIC, and it was great. ...until I saw something that was just a little too slow, or maybe I ran out of memory...
I found out about assembly language, and learned that you could make *one key routine* run ten times faster or more... and I got hooked. It was not without a bit of pain, I can assure you... but the reward was worth it. One taste, and there was no going back (although 'C' is a decent middle ground).
|
|
|
Post by turboxray on Feb 15, 2020 17:12:30 GMT
I understand where you're coming from; I've been there. Around 1979 or so, I started out programming BASIC, and it was great. ...until I saw something that was just a little too slow, or maybe I ran out of memory... I found out about assembly language, and learned that you could make *one key routine* run ten times faster or more... and I got hooked. It was not without a bit of pain, I can assure you... but the reward was worth it. One taste, and there was no going back (although 'C' is a decent middle ground). Not just faster but pretty much no limitations other than the system itself. For example I'm writing object oriented code for the PCE in assembly, for a project I'm working on right now with another game author (porting their game over to the PCE). I have classes, objects, instantiation (heap allocation, constructors, destructors), methods, inheritance, etc. Not that the PCE needs it, but it's a fun exercise hahah. Assembly gets you there.
|
|
|
Post by DarkKobold on Feb 15, 2020 18:40:26 GMT
I understand where you're coming from; I've been there. Around 1979 or so, I started out programming BASIC, and it was great. ...until I saw something that was just a little too slow, or maybe I ran out of memory... I found out about assembly language, and learned that you could make *one key routine* run ten times faster or more... and I got hooked. It was not without a bit of pain, I can assure you... but the reward was worth it. One taste, and there was no going back (although 'C' is a decent middle ground). Not just faster but pretty much no limitations other than the system itself. For example I'm writing object oriented code for the PCE in assembly, for a project I'm working on right now with another game author (porting their game over to the PCE). I have classes, objects, instantiation (heap allocation, constructors, destructors), methods, inheritance, etc. Not that the PCE needs it, but it's a fun exercise hahah. Assembly gets you there. You guys are making a couple assumptions - just because you enjoy assembly, doesn't mean I do. I've had to do it to clean up that zsort. I've done it in college. I did some asm hacking when I made my shining force TAS. Given the choice between C and ASM, I'll take C 100% of the time. Its just better for me. People created abstraction for a reason. ASM is frustrating and difficult to read.
That said, the ADPCM route wasn't the best solution. Elmer fixed load_vram to use TIA instructions, and I'm guessing the ad_read function didn't get the same update. I tried looking at the ASM, but it's confusing af. He created a subroutine, jsr ram_hdwr_tia, but trying to figure out the rest of the ASM is well beyond my skills. So, yeah, I'm handicapped by my lack of ASM skills.
Elmer, would it be easy to make the same fix to ad_read( ) ?
|
|
|
Post by dshadoff on Feb 15, 2020 19:22:43 GMT
I'm pretty sure I never said I *like* assembly (so I certainly wouldn't assume it about other people), but I can put up with it for the benefits and flexibility it brings me. That was the point I was trying to make. And I thought you might come out of the cost/benefit equation with a similar conclusion (but it's fine if you don't - I just didn't realize that you had already done some).
I guess you could say "assembly is the worst language to use for programming computers. Except for all the others."
|
|
|
Post by turboxray on Feb 15, 2020 20:10:11 GMT
Not just faster but pretty much no limitations other than the system itself. For example I'm writing object oriented code for the PCE in assembly, for a project I'm working on right now with another game author (porting their game over to the PCE). I have classes, objects, instantiation (heap allocation, constructors, destructors), methods, inheritance, etc. Not that the PCE needs it, but it's a fun exercise hahah. Assembly gets you there. You guys are making a couple assumptions - just because you enjoy assembly, doesn't mean I do. I've had to do it to clean up that zsort. I've done it in college. I did some asm hacking when I made my shining force TAS. Given the choice between C and ASM, I'll take C 100% of the time. Its just better for me. People created abstraction for a reason. ASM is frustrating and difficult to read.
That said, the ADPCM route wasn't the best solution. Elmer fixed load_vram to use TIA instructions, and I'm guessing the ad_read function didn't get the same update. I tried looking at the ASM, but it's confusing af. He created a subroutine, jsr ram_hdwr_tia, but trying to figure out the rest of the ASM is well beyond my skills. So, yeah, I'm handicapped by my lack of ASM skills.
Elmer, would it be easy to make the same fix to ad_read( ) ?
The assembly stuff aside, what's the problem with ADPCM ram? Too slow to access? Sadly, there's not port-to-port transfer instruction... and ADPCM has a delay on the port so you can't just read really fast from the port. I didn't realize you guys were doing a CD platform build as well. Maybe it's worth looking back into elmer's compression example for CDRAM?? Although that's going to complicate one build for two platforms... On the assembly side of things; I didn't say I enjoyed it haha. I'm definitely comfortable with it, but I would never go as far as to say that I enjoy it. I enjoy the flexibility and performance that it brings to the table. Matter of fact, a lot of what I write for PCE assembly heavily involves macro because I dislike the drawn out readability of assembly instructions (65x is a little bit noisy in its listings). Macros make it much better to read (I often do macros inside of macros, inside of macros). I like C, C++, Python, Java, even JS, etc. I've enjoyed some of the functional languages I got to mess with in college. I totally dislike PHP, Perl, and BASH scripts (the syntax is just crap) haha. But PCE is a pretty clean/baked design. Other than the PCE CPU not having linear addressing mode, a lot of stuff is pretty straight forward on the PCE as a whole IMO when it comes to assembly and hardware. It's not like the SNES ;_; Like anything, you just keep using it until you get a certain level of comfortability with it. Use lots of equates to make things clear, and use macros to compact the code for readability. But yeah no one is badass with assembly right out of the gate. Also, romhacking isn't really assembly programming IMO, and it's a painful experience the way the romhacking community goes about it. Here's my main: ; ; ; {Assemble with PCEAS: ver 3.23 or higher} ; ; Tomaitheous '20 ;
;.............................................................................................................. ;.............................................................................................................. ;.............................................................................................................. ;..............................................................................................................
list mlist
;.............................................. ; . ; Logical Memory Map: . ; . ; $0000 = Hardware bank . ; $2000 = Sys Ram . ; $4000 = Subcode . ; $6000 = Cont. of Subcode . ; $8000 = Data . ; $A000 = Cont. of Data . ; $C000 = Main . ; $E000 = Fixed Libray . ; . ;..............................................
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// Equates and Vars
;// Varibles defines .include "..\base_func\vars.inc" .include "..\lib\sprites\vars.inc"
;.................................... .code
.bank $00, "Fixed Lib/Start up" .org $e000 ;....................................
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// Support files: equates and macros
;// Support files for MAIN .include "..\base_func\base.inc" .include "..\base_func\video\vdc\vdc.inc" .include "..\base_func\video\vce\vce.inc" .include "..\base_func\timer\timer.inc" .include "..\base_func\IO\irq_controller\irq.inc" .include "..\base_func\IO\mapper\mapper.inc"
.include "..\lib\sprites\sprites.inc" .include "..\lib\level\level.inc" .include "..\lib\support\support.inc"
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// Main
startup: ;................................ ;Main initialization routine. InitialStartup CallFarWide init_audio CallFarWide init_video
stz $2000 tii $2000,$2001,$2000
;................................ ;Set video parameters VCE.reg LOW_RES|H_FILTER_ON VDC.reg HSR , $0202 VDC.reg HDR , $031F VDC.reg VSR , $0F02 VDC.reg VDR , $00EF VDC.reg VDE , $0003 VDC.reg DCR , AUTO_SATB_ON VDC.reg CR , $0000 IRQ.control IRQ2_ON|VIRQ_ON|TIRQ_ON VDC.reg SATB , $7F00 VDC.reg MWR , SCR64_32 TIMER.cmd TMR_OFF TIMER.port _7.00khz
MAP_BANK #MAIN, MPR6 jmp MAIN
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// Data / fixed bank
;Stuff for printing on screen .include "..\base_func\video\print\lib.asm"
;other basic functions .include "..\base_func\video\vdc\lib.asm"
;end DATA ;//...................................................................
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// Interrupt routines
;//........ TIRQ: ;// Not used stz $1403 rti
;//........ BRK: rti
;//........ VDC: pha lda $0000 bit #$20 bne .vsync .hsync pla rti
.vsync phx phy
ply plx pla stz __vblank rti
;//........ NMI: rti
;end INT
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// INT VECTORS
.org $fff6
.dw BRK .dw VDC .dw TIRQ .dw NMI .dw startup
;.............................................................................................................. ;.............................................................................................................. ;.............................................................................................................. ;.............................................................................................................. ;Bank 0 end
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// Main code bank @ $C000
.bank $01, "MAIN" .org $c000
MAIN: ;................................ ;Turn display on VDC.reg CR , BG_ON|SPR_ON|VINT_ON|HINT_OFF
;................................ ;Load font loadCellToVram Font, $1000 loadCellToCram.BG Font, 0
;................................ ;Clear 64x32 map jsr ClearScreen
;................................ ;Load sprites loadCellToVram Bat, $4000 loadCellToCram.SPR Bat, 4
loadCellToVram Rat, $4100 loadCellToCram.SPR Rat, 5
loadCellToVram Slime, $4200 loadCellToCram.SPR Slime, 6
loadCellToVram Spider, $4400 loadCellToCram.SPR Spider, 7
loadCellToVram Ghost, $4600 loadCellToCram.SPR Ghost, 8
loadCellToVram Frog, $4700 loadCellToCram.SPR Frog, 9
loadCellToVram Coin, $4800 loadCellToCram.SPR Coin, 10
loadCellToVram Key, $4900
;ResetFuncList ;DisableFuncList
loadLevel_1
;................................ ;start the party Interrupts.enable
;............................... ; PRINT_STR_i "Init build",2,3
main_loop:
WAITVBLANK 0 ProcessLevelObjects TransferSATB ;jsr READ_IO ;jsr DoScript ;jsr ScrollMap ;jsr DoFuncList ;jsr UpdateDebugOSD bra main_loop
;Main end ;//...................................................................
.include "..\lib\level\lib.asm" .include "..\lib\sprites\lib.asm" .include "..\lib\support\lib.asm"
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; .bank $02, "Subcode 1" .org $8000
IncludeBinary Font.cell, "..\base_func\video\print\font.dat"
Font.pal: .db $00,$00,$33,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$01,$ff,$01,$f6,$01 Font.pal.size = sizeof(Font.pal)
;// Support files for MAIN .include "..\base_func\init\InitHW.asm"
;.............................................................................................................. ;.............................................................................................................. ;.............................................................................................................. ;.............................................................................................................. ;Bank 1 end
;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////////////// ; ;// Game enemies, player, and objects
.bank $03, "Enemy cells" .org $8000
.include "..\assets\spritesheets\enemy_cells.asm"
.bank $04, "Enemy Classes" .org $4000
ObjectClasses: .include "..\assets\spritesheets\enemy_classes.asm"
;.............................................................................................................. ;.............................................................................................................. ;.............................................................................................................. ;.............................................................................................................. ;END OF FILE And if you look inside those macros, you'll see more macros.. loadCellToVram .macro
MAP_BANK.2 #(\1.cell) , MPR2 VDC.reg MAWR, \2 VDC.reg VRWR DMA.word.port \1.cell, Page.2, vdata_port, \1.cell.size .endm
loadCellToCram.BG .macro
VCE.BGblock \2 DMA.word.port \1.pal, Page.2, vce_data, \1.pal.size .endm
loadCellToCram.SPR .macro
VCE.SPRblock \2 DMA.word.port \1.pal, Page.2, vce_data, \1.pal.size .endm
. . . .
;......................... loadLevel_1 .macro
resetObjectGroupList resetHwSpriteIndex
MAP_BANK.2 #ObjectClasses , MPR2
; 1 = class name ; 2 = X ; 3 = Y ; 4 = animation ; 5 = frame ; 6 = delay ; 7 = pattern vram instantiateObject Bat, 80, 100, 0, 0, 2, $4000
instantiateObject Rat, 110, 100, 0, 0, 2, $4100
instantiateObject Slime, 90, 120, 0, 0, 2, $4200
instantiateObject Spider, 70, 130, 0, 0, 2, $4400
instantiateObject Ghost, 150, 110, 0, 0, 2, $4600
instantiateObject Frog, 90, 160, 0, 0, 2, $4700
instantiateObject Coin, 70, 70, 0, 0, 2, $4800
instantiateObject Key, 90, 70, 0, 0, 2, $4900
.endm
. . . .
;................................................ PUSH.addr .macro
lda #>(\1 - 1) pha lda #<(\1 - 1) pha
.endm
;................................................ jsr.ind .macro PUSH.addr .return_\@ jmp [\1] .return_\@ .endm
;................................................ jsr.ind.x .macro PUSH.addr .return_\@ jmp [\1,x] .return_\@ .endm
;................................................ Interrupts.disable .macro sei .endm
;................................................ Interrupts.enable .macro cli .endm Or data structures ;............... ; Frame table . ;...............
Key.AnimeTable: ;length .db 3 ;table .dw keyVisible, keyCollected, keyDisappear
;..................... ; Frame Definitions . ;.....................
;//..................... ;// . ;//..................... keyVisible: ;type: 0 = literal data. .db 0 ;table length .db 1 ;frame table .dw keyVisible.1 keyVisible.1: ; delay in frames .db 3 ; table .dw keyVisible.meta.1, keyVisible.damageCollision.1, keyVisible.attackCollision.1
keyVisible.meta.1: .db 1 .dw keyVisible.cell.1
keyVisible.cell.1: addOffsetX 0 addOffsetY 0 addAttributes SIZE16_16 | NO_V_FLIP | NO_H_FLIP | PRIOR_H | SPAL10 addVramOffset 0 rts
keyVisible.damageCollision.1: keyVisible.attackCollision.1: .dw keyVisible.a_box.1.1
keyVisible.a_box.1.1: ;X1, Y1, width, Height, Type .db 3, 3, 12, 8, 0
;//..................... ;// . ;//..................... keyCollected:
; type: 1 = current animation but blink .db 1
;blink params
; number of cycles to blink .db 4
;duration of visible frames .db 30
;duraction of invisible frames .db 30
;//..................... ;// . ;//..................... keyDisappear:
; type: 2 = common death (blink, then cloud of smoke) .db 2 EDIT: How do you have the code tags to be collapsible?! Shouldn't they have a scroll bar and not be expanded out to the full size??? ;_;
|
|
|
Post by elmer on Feb 15, 2020 21:12:22 GMT
That said, the ADPCM route wasn't the best solution. Elmer fixed load_vram to use TIA instructions, and I'm guessing the ad_read function didn't get the same update. I tried looking at the ASM, but it's confusing af. He created a subroutine, jsr ram_hdwr_tia, but trying to figure out the rest of the ASM is well beyond my skills. So, yeah, I'm handicapped by my lack of ASM skills. Elmer, would it be easy to make the same fix to ad_read( ) ? I didn't create HuC's ram_hdwr_tia, it already existed ... it was just that HuC's load_vram() wasn't using it (the code to use it was there, but commented out, presumably because of RCR interrupt-response issues). Anyway, nope as turboxray said, you can't use any of the Txx transfer instructions on ADPCM RAM, it wasn't designed for high speed access like that. The memory is relatively slow and it requires polling and delays when accessed by the CPU (but the CD drive has direct access to it, so you can load data in the background with no effect on the CPU ... which is marvelous). The slow speed is OK if you're uploading sprites (or background tiles) to VRAM once at the beginning of a level, but you can't just use it to upload animations on a frame-by-frame basis that way that you're using HuC's load_vram() right now. I suspect that Arkhan didn't realize how you were wishing to use the ADPCM RAM, because I'm pretty sure that he aready knows this stuff. You could put your background tiles in ADPCM RAM ... but at that point, you might as well just load them from CD directly into VRAM anyway.
|
|