Note-se que ao voltar de uma rotina C/M podem devolver o número no registo BC.
Como exemplo:
ORG 50000
LD BC,20
RET
E então a partir de BASIC:
10 PRINT USR 50000
Irá imprimir 20.
Vendo a rotina da ROM de retornar ao BASIC, é 2D2B: THE 'STACK-BC' SUBROUTINE
THE 'STACK-BC' SUBROUTINE
Used by the routines at S_RND, DEC_TO_FP, usr and len.
The routine at STACK_A continues here.
This subroutine gives the floating-point form for the absolute binary value currently held in the BC register pair.
The form used in this and hence in the two previous subroutines as well is the one reserved in the Spectrum for small integers n, where -65535<=n<=65535. The first and fifth bytes are zero; the third and fourth bytes are the less significant and more significant bytes of the 16 bit integer n in two's complement form (if n is negative, these two bytes hold 65536+n); and the second byte is a sign byte, +00 for '+' and +FF for '-'.
Used by the routines at S_RND, DEC_TO_FP, usr and len.
The routine at STACK_A continues here.
This subroutine gives the floating-point form for the absolute binary value currently held in the BC register pair.
The form used in this and hence in the two previous subroutines as well is the one reserved in the Spectrum for small integers n, where -65535<=n<=65535. The first and fifth bytes are zero; the third and fourth bytes are the less significant and more significant bytes of the 16 bit integer n in two's complement form (if n is negative, these two bytes hold 65536+n); and the second byte is a sign byte, +00 for '+' and +FF for '-'.
BC Value to stack
STACK_BC 2D2B LD IY,$5C3A Re-initialise IY to ERR-NR.
2D2F XOR A Clear the A register.
2D30 LD E,A And the E register, to indicate '+'.
2D31 LD D,C Copy the less significant byte to D.
2D32 LD C,B And the more significant byte to C.
2D33 LD B,A Clear the B register.
2D34 CALL STK_STORE Now stack the number.
2D37 RST $28 Use the calculator to make HL point to STKEND-5.
2D38 DEFB $38 End_calc
2D39 AND A Clear the carry flag.
2D3A RET Finished.
The address of this routine is found in the table of addresses. It is called indirectly via fp_calc_2.
This subroutine ('USR number' as distinct from 'USR string') handles the function USR X, where X is a number. The value of X is obtained in BC, a return address is stacked and the machine code is executed from location X.
usr_no 34B3 CALL FIND_INT2 Evaluate the 'last value', rounded to the nearest integer; test
that it is in range and return it in BC.
34B6 LD HL,$2D2B Make the return address be that of the subroutine
STACK_BC.
34B9 PUSH HL
34BA PUSH BC Make an indirect jump to the required location.
34BB RET
34B3: THE 'USR' FUNCTION (offset +2D)
Por exemplo, nesta rotina:
A entrar por RAND USR 50000 vai para LD_ENTRY e por RAND USR 50001 salta para SA_BYTES
Note-se, que já que estamos a falar deste tema, que as rotinas código M/C têm de preservar o valor de HL´ antes de voltar ao BASIC (ou restaurá-lo a $2758). Como nota adicional, chamar funções de ROM a partir de C/M que necessitem de usar o stack FP implica não mexer ou restaurar o registo IY.
ORG 50000
NOP
LD IX,16384
LD DE,6912
LD A,$FF
BIT 0,C
JR Z,LD_ENTRY
JP SA_BYTES
Note-se, que já que estamos a falar deste tema, que as rotinas código M/C têm de preservar o valor de HL´ antes de voltar ao BASIC (ou restaurá-lo a $2758). Como nota adicional, chamar funções de ROM a partir de C/M que necessitem de usar o stack FP implica não mexer ou restaurar o registo IY.
IY tem de ser sempre $5C3A para usar as rotinas da ROM e a rotina IM 1 da ROM.
ResponderEliminar