Nuove funzioni per BASIC C64
di
pubblicato il 10-03-2012 alle 23:32 (4123 Visite)
Questa volta vi presento codice assembly 6510 che implementa due nuove funzioni per il BASIC del Commodore 64.
Le funzioni sono la HEX$ per la conversione di valori interi da decimale ad esadecimale e la funzione DEC per la conversione opposta.
Questo è il codice sorgente delle due funzioni, commentato (e che sfrutta alcune chiamate di sistema).
; Funzione HEX$ ; ; Converte valore numerico decimale a 16 bit in ; una stringa esadecimale di lunghezza indicata ; ; Sintassi : HEX$(VAL16, NCESA) ; VAL16 = Valore decimale a 16 bit ; NCESA = Numero cifre esadecimali, da 1 a 4 ; ; Esempio : ; PRINT HEX$(40961, 4) ; A001 ; HEXS JSR CHKSYNPOP ; Controlla la presenza del carattere ( JSR GETNUM ; Legge una stringa numerica, la converte in un valore a 16 bit ; e lo inserisce in memoria all'indirizzo LINNUM/LINNUM+1; ; inoltre, controlla la presenza del carattere , e ; legge una stringa numerica e la converte in un byte in X TXA ; Sposta il numero di cifre nell'accumulatore BNE HEXS1 ; Continua solo se non è stato indicato 0 HEXS2 JMP ERRILLQTY ; altrimenti visualizza ILLEGAL QUANTITY HEXS1 CPX #05 ; Confronta con 5 ; se il numero di cifre richieste BCS HEXS2 ; è uguale o maggiore allora errore ILLEGAL QUANTITY PHA ; Salva l'accumulatore nello stack (numero di cifre richieste) JSR ALLOCA ; Alloca il numero di caratteri richiesti per la stringa PLA ; Recupera l'accumulatore dallo stack (numero di cifre richieste) TAY ; Numero di cifre in Y come contatore (dall'ultima alla prima) LDX #$00 ; Indice per il primo byte del valore a 16 bit (X=0) HEXS3 DEY ; Prossima cifra esadecimale BMI HEXS5 ; Se sono state trattate tutte le cifre esa continua in HEXS5 LDA LINNUM,X ; Legge il prossimo byte del valore a 16 bit PHA ; Salva il valore nello stack JSR HEXS4 ; Converte il nibble basso del byte in esa e lo salva nella stringa PLA ; Recupera il byte L del valore a 16 bit dallo stack DEY ; Prossima cifra esadecimale BMI HEXS5 ; Se sono state trattate tutte le cifre esa continua in HEXS5 LSR ; LSR ; LSR ; LSR ; Sposta il nibble alto nel nibble basso JSR HEXS4 ; Converte il nibble basso del byte in esa e lo salva nella stringa INX ; Prossimo byte del valore a 16 bit CPX #$02 BNE HEXS3 ; Se non è stato ancora trattato il secondo byte, ripete HEXS5 JSR CHKSYNPCL ; Controlla la presenza del carattere ) JMP SAVEDES61 ; Restituisce la stringa come risultato ; ; Converte nibble binario (0-F) ; in carattere ASCII ('0','F') ; HEXS4 AND #$0F ; Converte cifra decimale da ASCII in binario (4 bit) SED ; Attiva modalità decimale CLC ; Riporto = 0 ADC #$90 ; Addiziona #$90 (risultato da $90 a $99, CY=0 o da $00 A $06, CY=1) ADC #$40 ; Addiziona #$40 (risultato da $30 a $39, CY=1 o da $41 A $46, CY=0) CLD ; Disattiva modalità decimale STA (FACHO),Y ; Memorizza il carattere ASCII esa nella stringa di output RTS ; Controlla e converte ; un carattere ASCII esa ; CHKCVTHEX CMP #'0' ; Confronta con il carattere 0 BCC HEXS2 ; Se è < allora visualizza ILLEGAL QUANTITY CMP #'F'+1 ; Confronta con il carattere seguente a F BCS HEXS2 ; Se è >= allora visualizza ILLEGAL QUANTITY CMP #'9'+1 ; Confronta con il carattere seguente a 9 BCC CHKCVTHEX2 ; Se è minore, allora è tra 0 e 9, converte e termina CMP #'A' ; Confronta con il carattere A BCC HEXS2 ; Se è < allora visualizza ILLEGAL QUANTITY SBC #$37 ; E' tra A e F, sottrae $37 CHKCVTHEX2 AND #$0F ; Converte da ASCII a binario RTS ; Funzione DEC ; ; Converte una stringa esadecimale di max. 4 cifre ; in un valore numerico ; ; Sintassi : DEC("HHHH") ; "XXXX" = Stringa di max. 4 cifre esa ; ; Esempio : ; PRINT DEC("A001") ; 40961 ; DECF JSR GETOP2 ; Ottiene una stringa temporanea dal parametro ; e la memorizza a partire da (INDEX) JSR LEN1 ; Misura la lunghezza della stringa BEQ HEXS2 ; Se è zero, visualizza ILLEGAL QUANTITY CMP #$05 ; Confronta con la lunghezza di 5 caratteri BCS HEXS2 ; Se è >=, visualizza ILLEGAL QUANTITY TAX ; Copia il numero di caratteri in X LDY #$00 ; Numero carattere della stringa (Y = 0) STY TMPLOC ; Azzera TMPLOC STY TMPLOC2 ; Azzera TMPLOC2 DECF0 LDA (INDEX),Y ; Legge primo carattere della stringa in A JSR CHKCVTHEX ; Converte il carattere da ASCII esa in binario CLC ADC TMPLOC STA TMPLOC ; Somma il valore in TMPLOC BCC NOCY INC TMPLOC2 ; e in TMPLOC2 per l'eventuale riporto NOCY INY ; Aggiorna indice per prossimo carattere nella stringa DEX ; Decrementa contatore caratteri BEQ DECF1 ; Se è l'ultimo, esce verso DECF1 ASL TMPLOC ; ROL TMPLOC2 ; ASL TMPLOC ; ROL TMPLOC2 ; ASL TMPLOC ; ROL TMPLOC2 ; ASL TMPLOC ; Moltiplica per 16 risultato temporaneo ROL TMPLOC2 ; a 16 bit in TMPLOC,TMPLOC2 JMP DECF0 ; Ripete per prossimo carattere esa DECF1 LDY TMPLOC LDA TMPLOC2 ; Carica indirizzo TMPLOC/TMPLOC2 in A/Y JSR CVTINTFLT ; Converte valore a 16 bit in A/Y in float LDA FACSGN BMI DECF2 ; Se il segno è negativo, allora va a DECF2 RTS DECF2 JSR MOVF1F2 ; Sposta FAC1 in FAC2 LDA #<FLTM65 LDY #>FLTM65 JSR MOVMF1 ; Carica 65536 in FAC1 JMP MINUS ; Esegue sottrazione per complemento
mentre questo è il risultato dopo aver assemblato con il D64ASM il codice integrato nella nuova versione di BASIC che ho scritto
(e che vedremo in futuro ...).
00001579 8335 20 FA AE HEXS JSR CHKSYNPOP 00001580 8338 20 EB B7 JSR GETNUM 00001581 833B 8A TXA 00001582 833C D0 03 BNE HEXS1 00001583 833E 4C 48 B2 HEXS2 JMP ERRILLQTY 00001584 8341 E0 05 HEXS1 CPX #05 00001585 8343 B0 F9 BCS HEXS2 00001586 8345 48 PHA 00001587 8346 20 7D B4 JSR ALLOCA 00001588 8349 68 PLA 00001589 834A A8 TAY 00001590 834B A2 00 LDX #$00 00001591 834D 88 HEXS3 DEY 00001592 834E 30 16 BMI HEXS5 00001593 8350 B5 14 LDA LINNUM,X 00001594 8352 48 PHA 00001595 8353 20 6C 83 JSR HEXS4 00001596 8356 68 PLA 00001597 8357 88 DEY 00001598 8358 30 0C BMI HEXS5 00001599 835A 4A LSR 00001600 835B 4A LSR 00001601 835C 4A LSR 00001602 835D 4A LSR 00001603 835E 20 6C 83 JSR HEXS4 00001604 8361 E8 INX 00001605 8362 E0 02 CPX #$02 00001606 8364 D0 E7 BNE HEXS3 00001607 8366 20 F7 AE HEXS5 JSR CHKSYNPCL 00001608 8369 4C CA B4 JMP SAVEDES61 00001609 836C 29 0F HEXS4 AND #$0F 00001610 836E F8 SED 00001611 836F 18 CLC 00001612 8370 69 90 ADC #$90 00001613 8372 69 40 ADC #$40 00001614 8374 D8 CLD 00001615 8375 91 62 STA (FACHO),Y 00001616 8377 60 RTS 00001617 8378 00001618 8378 00001619 8378 00001620 8378 C9 30 CHKCVTHEX CMP #'0' 00001621 837A 90 C2 BCC HEXS2 00001622 837C C9 47 CMP #'F'+1 00001623 837E B0 BE BCS HEXS2 00001624 8380 C9 3A CMP #'9'+1 00001625 8382 90 06 BCC CHKCVTHEX2 00001626 8384 C9 41 CMP #'A' 00001627 8386 90 B6 BCC HEXS2 00001628 8388 E9 37 SBC #$37 00001629 838A 29 0F CHKCVTHEX2 AND #$0F 00001630 838C 60 RTS 00001631 838D 00001632 838D 00001633 838D 00001634 838D 20 F1 AE DECF JSR GETOP2 00001635 8390 20 82 B7 JSR LEN1 00001636 8393 F0 A9 BEQ HEXS2 00001637 8395 C9 05 CMP #$05 00001638 8397 B0 A5 BCS HEXS2 00001639 8399 AA TAX 00001640 839A A0 00 LDY #$00 00001641 839C 84 02 STY TMPLOC 00001642 839E 84 FE STY TMPLOC2 00001643 83A0 B1 22 DECF0 LDA (INDEX),Y 00001644 83A2 20 78 83 JSR CHKCVTHEX 00001645 83A5 18 CLC 00001646 83A6 65 02 ADC TMPLOC 00001647 83A8 85 02 STA TMPLOC 00001648 83AA 90 02 BCC NOCY 00001649 83AC E6 FE INC TMPLOC2 00001650 83AE C8 NOCY INY 00001651 83AF CA DEX 00001652 83B0 F0 13 BEQ DECF1 00001653 83B2 06 02 ASL TMPLOC 00001654 83B4 26 FE ROL TMPLOC2 00001655 83B6 06 02 ASL TMPLOC 00001656 83B8 26 FE ROL TMPLOC2 00001657 83BA 06 02 ASL TMPLOC 00001658 83BC 26 FE ROL TMPLOC2 00001659 83BE 06 02 ASL TMPLOC 00001660 83C0 26 FE ROL TMPLOC2 00001661 83C2 4C A0 83 JMP DECF0 00001662 83C5 A4 02 DECF1 LDY TMPLOC 00001663 83C7 A5 FE LDA TMPLOC2 00001664 83C9 20 91 B3 JSR CVTINTFLT 00001665 83CC A5 66 LDA FACSGN 00001666 83CE 30 01 BMI DECF2 00001667 83D0 60 RTS 00001668 83D1 20 0C BC DECF2 JSR MOVF1F2 00001669 83D4 A9 AF LDA #<FLTM65 00001670 83D6 A0 80 LDY #>FLTM65 00001671 83D8 20 A2 BB JSR MOVMF1 00001672 83DB 4C 53 B8 JMP MINUSIl risultato in esecuzione ...
![]()