Jump to content
IGNORED

Converting z80 code to CP1610 and intybasic


artrag

Recommended Posts

In short: I have binary data generated by a windows editor that can be played by a z80 machine.

The binary file packs 16 bit data and 8 bit data in the same stream.

It is in accessed by the z80 player almost sequentially, sometimes byte by byte, sometimes word by word.

 

I'm trying to convert the z80 code to intybasic using peek() but it is quite complex and ineffective because I have to keep in mind when the data that the player needs are word aligned, and when no.

If the data are not word aligned I need two peeks in adjacent addresses to be merged in one 16 bit result...

 

I've was thinking that building a function able to count bytes in the data stream and return a byte or a world could be a possible solution, even if not very efficient, at least to get something working.

 

But I've the feeling I'm reinventing the wheel and that maybe something ready and efficient is already somewhere...

Any idea on how to do something like this ?

 

For those curious of what I'm doing this is the WIP.


ayFX_INIT:	procedure
		' ---     INIT A NEW ayFX STREAM     ---
		' --- INPUT: A -> sound to be played ---
		' ---        C -> sound priority     ---
		' --- Checks the priorities of playing ayFX streams to place ---
		' --- the new one on the channel with lowest priority        ---

		' --- Check if the index is in the bank ---
		b = a								' b:=a (new ayFX stream index)
											
		if 	(peek(#ayFX_BANK) and 255 = 0) then		' Number of samples in the bank
			goto CHECK_PRI					' If zero (means 256 samples) goto @@CHECK_PRI
		elseif	(peek(#ayFX_BANK) and 255 < b) then	' The bank has less than 256 samples
			a = 2							' If new index is not in the bank...
			return							' a:=2 (error 2: Sample not in the bank)
		end									' ...we can't init it
CHECK_PRI:	
		' --- Places the data on the correct channel                  ---
		' ---   Remember: 0 = highest priority, 15 = lowest priority  ---

		if (ayFX_C1 = 255) then			' If there's no Stream being played...
			goto TOC1					' ...place the new Stream on channel 1
		end	
		if (ayFX_C2 = 255) then			' If there's no Stream being played...
			goto TOC2					' ...place the new Stream on channel 2
		end	
		if (ayFX_C3 = 255) then 		' If there's no Stream being played...
			goto TOC3					' ...place the new Stream on channel 3
		end


		if	(ayFX_C2 >= ayFX_C1) and (ayFX_C3 >= ayFX_C1) then	
			if (c<ayFX_C1) then 
				a = 1			' a:=1 (error 1: A sample with higher priority is being played)
				return 			' ...we can't play the new ayFX Stream
			end
			goto TOC1	
		end	
		if	(ayFX_C1 >= ayFX_C2) and (ayFX_C3 >= ayFX_C2) then	
			if (c<ayFX_C2) then 
				a = 1			' a:=1 (error 1: A sample with higher priority is being played)
				return 			' ...we can't play the new ayFX Stream
			end
			goto TOC2
		end			
		if	(ayFX_C2 >= ayFX_C3) and (ayFX_C1 >= ayFX_C3) then	
			if (c<ayFX_C3) then 
				a = 1			' a:=1 (error 1: A sample with higher priority is being played)
				return 			' ...we can't play the new ayFX Stream
			end
			goto TOC3
		end			

		
TOC3:							' --- Stream will be played on channel 3
		#IX = varptr ayFX_C3			' Pointer to the chanel data
		goto	SETDATA			' Go to @@SETDATA
TOC2:							' --- Stream will be played on channel 2
		#IX = varptr ayFX_C2			' Pointer to the channel data
		goto 	SETDATA			' Go to @@SETDATA
TOC1:							' --- Stream will be played on channel 1
		#IX = varptr ayFX_C1	' Pointer to the chanel data
SETDATA:						' --- Set data on the correct channel ---
		poke #IX, c and 15			' new ayFX stream priority saved in RAM

		' --- Calculate the pointer to the new ayFX stream ---
		ld	de,[ayFX_BANK]			' de:=Current ayFX bank
		inc	de				' de points to the increments table of the bank
		ld	l,b				' l:=b (new ayFX stream index)
		ld	h,0				' hl:=b (new ayFX stream index)
		add	hl,hl				' hl:=hl*2
		add	hl,de				' hl:=hl+de (hl points to the correct increment)
		ld	e,[hl]				' e:=lower byte of the increment
		inc	hl				' hl points to the higher byte of the correct increment
		ld	d,[hl]				' de:=increment
		add	hl,de				' hl:=hl+de (hl points to the new ayFX stream)
		ld	[IX+1],l			' Pointer lower byte saved in RAM
		ld	[IX+2],h			' Pointer higher byte saved in RAM
		xor	a				' a:=0 (no errors)
		
		end
Edited by artrag
Link to comment
Share on other sites

I'll be honest: I'd probably try to do this in assembly language, because I can think of some clever ways to keep the instruction count down. IntyBASIC makes it harder.

 

One approach is to structure it as a "prefetch" so that the only variable paths are associated with refilling the prefetch buffer:

.

UNSIGNED #prefetch, #index, #datum, packed_data
  
#prefetch = 0
#index = 0
#datum = 0

NextByte: Procedure
    #datum = #prefetch AND 255
    #index = #index + 1
    if #index AND 1 then
        #prefetch = packed_data(#index / 2)
    else
        #prefetch = (#prefetch / 256) + (packed_data(#index / 2) * 256)
    end if
end

NextWord: Procedure
    #datum = #prefetch
    #index = #index + 2
    if #index AND 1 then
        #prefetch = (packed_data(#index / 2) / 256) + (packed_data(#index / 2 + 1) * 256)
    else
        #prefetch = packed_data(#index / 2)
    end if
end


packed_data:
    DATA 1, 2, 3, 4, 5

.

Another approach that would work well in assembly language, if you have some 8-bit RAM to spare, would be to unpack 16-bit words to 8-bit RAM in chunks (say, 8 bytes at a time), and then use MVI@ or SDBD; MVI@ as needed to read 8 and 16-bit values, unpacking the next few words whenever needed.

 

I can see a way to make that reasonably efficient in assembly, but not so much in IntyBASIC.

Edited by intvnut
Link to comment
Share on other sites

 

Thanks for the code, I will start from your solution, in the attempt to get a quick and dirty, but working, conversion.

 

Another idea I was evaluating is that due to the fact that intybasic is not capable of importing binary files, there is the possibility to do an offline converter in C able to interpret the bin file, unpack bytes in words when needed and generate a bas file...

I'll let you know

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...