Re: New version emulator ZEsarUX-4.0
Posted: Sun Mar 06, 2016 7:19 pm
Yes I remember that some of the songs crashed the machine and I don't know why. I must take a look again and try to find the error...
Cheers
Cheers
Discussion forums for users of the Sinclair 8-bit range of computers - ZX80, ZX81, ZX Spectrum, Z88, clones...
https://www.sinclairzxworld.com/
Code: Select all
CONTROL:
DB $00 ;used as a way of getting a signal into the interrupt handler
;
;on initialise ' call start '
;
; CONTROL = 0
;
; 0~ DON'T CALL PLAYER DURRING INT
; BUT SILENCE SOUND.
;
; 1 ~ CALL PLAYER DURRING INT
;
; 255 ~ SILENCE SOUND AND
; STOP INTTERUPT HANDLER
START:
XOR A ;ZERO
LD (CONTROL),A ;STORE IN CONTROL BYTE
;AFTER INITIALISING
;PLAYER WILL NOT PLAY
;UNTIL USER ALTERS THIS BYTE
;TO = 1
INIT:
OUT ($FD),A ;TURN OFF nmi, SONG INITIALISE TAKES A WHILE
PUSH IY ;AND USES iy REGISTER.
CALL INIT_PLAYER ;INIT SONG
POP IY ;RESTORE iy
OUT ($FE),A ;TURN ON nmi
GO_HANDLER:
CALL FRAME_WAIT ;WAIT FOR START OF BOTTOM MARGIN
;ITS A SAFE PLACE TO ALTER THE IX REGISTER
;AS WE HAVE APPROX 11000 T STATES TILL
;IX IS USED AGAIN.
;AND THEN LOAD IX REGISTER SO OUR
LD IX,END_OF_BOTTOM_MARGIN ;HANDLER IS USED INSTEAD
RET ;BACK TO USERS PROGRAM
;=============================
;= =
;= DISPLAY INTTERUPT HANDLER =
;= =
;==================================================
;= =
;= The display intturupt handler has 2 main parts =
;= =
;= during user program execution the NMI int are =
;= processed by incrementing the a register (from =
;= the af' pair ) and when zero is reached the =
;= main registers AF, BC, DE, HL are pushed onto =
;= the stack and a jump is made to address held =
;= in IX. The nmi's are active during the 'blank' =
;= area's at the top and bottom of the diaply =
;= these are the top and bottom margins.
;= =
;= So by altering IX we can take control of the =
;= display intterupt cycle =
;= =
;= 1) create a vsync signal and read keyboard. =
;= 1a) start top margin, and resume user program. =
;= =
;= 2) generate the display. =
;= 2a) start bottom margin, and resume user prog- =
;= gram =
;= =
;==================================================
;NOW THE TRICKY BIT !
;
;==========
;= =
;= PART 1 =
;= =
;==========
END_OF_BOTTOM_MARGIN:
;NMI ROUTINE JUMPS HERE AT THE END OF THE BOTTOM MARGIN.
;THIS REPLACES THE $028F JUMP.
;when we get here the NMI routine has already put AF, BC, DE, HL on the stack
;HL on last
;
; sp ---> HL
; DE
; BC
; AF
;nmi is also turned off
;but i want it to return here so i can alter IX again.
;so beacuase the rom routine will pop these off before RET-ing
;i need to get my return address under 4 words on the stack
;
;i thought about pushing the return address and then subtracting 8 from the SP
;but it is no quicker.
;FIRST SAVE iy REGISTER
PUSH IY ;SAVE IY
; THEN PUSH THE ADDRESS THAT I WISH TO RETURN TO ON THE STACK
LD HL, AFTER_VSYNC ;new value for on top of stack
PUSH HL
; FOLLOWED BY 3 MORE THAT WILL BE POPPED OFF BY THE ROM ROUTINE
PUSH HL
PUSH HL
PUSH HL
LD IY,$4000 ;SET IY FOR ROM CODE TO RUN CORRECTLY
; AND 1 MORE MAKES 4, AF,BC,DE,HL, gotta be a better way to do this
CALL $0229 ;THIS ROM ROUTINE NORMALLY POPS THE REGISTERS AND
;RETURNS TO USER CODE EXECUTION
;WITH IX LOADED WITH $0281, READY FOR NEXT VIDEO INT.
;BUT NOW IT RETURNS HERE, BECAUSE I SHOVED EXTRA STUFF
;ON THE STACK
AFTER_VSYNC:
START_OF_TOP_MARGIN:
;SO WE HAVE RETURNED HERE
;AND IY STILL ON STACK, ALONG WITH THE REAL REGISTERS THAT WERE PUSHED
;BEFORE THE nmi int did JP (IX)
POP IY
POP HL
POP DE
POP BC
POP AF
;NOW ALL THIS PUSHING AND POPPING MEANS WE HAVE MISSED THE FIRST HSYNC
;REMEBER HSYNC ARE NOT RESET BY VSYNC, BUT A NORMAL INT ACK.
;SO NOW ALL THE CHARACTERS ARE MOVED UP 1 PIXEL LINE (LINE COUNTER IN ula)
;SO MUST DECREMENT THE NMI INTERUPT COUNTER (IT ACTUALLY COUNTS UP)
;
;Ha Ha, I've known for a while that eightyone does not correctly
;handle the hsync timming. so the character are displayed wrong on eightyone.
;
;wonder if this will work on any other emulator correctly ?
;we are not due an NMI for a good number of clock cycles
;the last one happen during the pops above
; out ($fd),a ;TURN OFF nmi JUST INCASE AN NMI HAPPENS WITH THE
ex af,af' ;THE WRONG AF PAIR ACTIVE
inc a ;DECREMENT THE LINE COUNTER (YES IT COUNTS UP)
ex af,af' ;SWAP BACK TO NORMAL AF
; out ($fe),a ;AND TURN ON THE nmi AGAIN
RESET_IX_VECT: ;FINALLY WE ARE READY TO RETURN TO USER CODE
LD IX,END_OF_TOP_MARGIN ;SET THE IX REG READY FOR NEXT END OF TOP MARGIN
RET ;RETURN TO USER PROGRAM
END_OF_TOP_MARGIN:
;==========
;= =
;= PART 2 =
;= =
;==========
;NMI ROUTINE HAS NOW JUMPED HERE AT THE END OF THE TOP MARGIN
;NMI'S ARE OFF
;STACK IS AS BEFORE
;MUST PRETTY MUCH COPY ROM ELSE TOP FEW LINES OF DISPLAY GET CORRUPTED
LD A,R ; SAME AS
LD BC,$1901 ; ROM
LD A,$F5 ; CODE
CALL $02B5 ; BUT....
;RETURNS HERE WHEN DISPLAY IS DONE
START_OF_BOTTOM_MARGIN
;code copied from ROM
;but a few tweaks
PUSH IY ;SAVE iy ONCE AGAIN,
ld iy,$4000 ;
LD c,(iy + $28) ; load C with value of system constant MARGIN.
;ALWAYS RUN IN COMPUTE AND DISPLAY MODE
;BIT 7,(IY+$3B) ; test CDFLAG for compute and display.
;jp Z,$02A9 ; forward, with FAST mode, to DISPLAY-4
ld A,C ; move MARGIN to A - 31d or 55d.
NEG ; Negate
;INC A ; MISSING THIS INC COMPENSATES FOR THE EXTRA
; ONE ABOVE
EX AF,AF' ; place negative count of blank lines in A'
LD IX,END_OF_BOTTOM _MARGIN ;AND MAKE SURE IX IS LOADED
OUT ($FE),A ; enable the NMI generator.
; THATS PRETTY MUCH THE INTERRUPT HANDLER
;LETS PLAY SOME MUSIC ;-)
; IF (CONTROL) = 255 THEN ix LOADED WITH NORMAL ROM VECTOR (STOPS HANDLER RUNNING )
; (NEXT TIME NMI ROUTINE )
; (DOES A JP (IX) )
; AND ALSO MUTES PLAYER.
;
; IF (CONTROL) = 0 THEN MUTES PLAYER.
;
; IF (CONTROL) = 1 THEN CALLS PLAYER EVERY 1/50TH SECOND
;
; IF (CONTROL) = OTHER VALUES THEN DO NOTHING; SO SOUND CHIP WILL CONTINUE TO SOUND...
; LAST DATA SENT TO IT...
LD A,(CONTROL)
INC A ;TEST FOR 255
JR NZ,DONT_EXIT_INTS ;ONLY 255 WILL RSULT IN ZERO
EXIT_INTS:
LD IX,$028F ;NORMAL ix VECTOR
INC A ;TRICK NEXT TEST
DONT_EXIT_INTS:
DEC A ;TEST FOR ZERO
CALL Z,MUTE_PLAYER ;IF IT WAS 0 RESULT WILL BE ZERO
DEC A ;OR 1
CALL Z,PLAY_PLAYER ;OTHER VALUES WILL DO NOTHING
;HERE
; THATS IT FOR THE PLAYER BIT.
POPS:
pop IY ;restored from entry to int routine
POP HL ;AND FINNALY RESTORE USERS REGISTERS
POP DE ;
POP BC ;
POP AF ;
;AND ENDS HERE
RET ; BACK TO USER PROG.
You're welcome!Moggy wrote:Hmmm just tried the player you mentioned and after loading and running, the emulator just automatically calls the xpand "CAT" command.
IE a list of files in the directory that can be loaded.
Many thanks for taking time and trouble with this Cesar and one last thing although not a great worry the AY emulation is slightly low in frequency compared to real AY, but as I say not really important in the scheme of things.
did you remember to lower ramtop to 25000 ( decimal of course ) before loading the compiler ?Moggy wrote:@ Cesar.
@ Andy
Andy, as written above the player and tracker are ok in Olofsons emulator but the compiler just crashes.
BUT WHATEVER YOU DO LEAVE THE TRACKER ALONE!!!!