dragon64 assembler: string I/O
Re: dragon64 assembler: string I/O
I don't think there's really any need to have both a length byte and terminator for your strings, unless you have a special reason for doing that. It's usual just to have a 0 at the end as terminator. The confusion perhaps comes from the fact that the string output ROM routine at $90E5 expects X to point at the byte before the start of a string, hence if you declare a dummy byte before your string that will be fine, but alternatively you can simply subtract 1 from the address instead before executing that call. Since you're writing your own input and output routines anyway, you can choose whatever conventions you prefer.
- heavyfranz
- Posts: 6
- Joined: Sun Sep 01, 2013 10:37 am
- Location: Italy
Re: dragon64 assembler: string I/O
Here I am.
First, thank you Jeek for welcoming me on the forum and another time thank you all people have replied me![Smile :)](./images/smilies/icon_e_smile.gif)
I've spent some time to fix the images but now I think that I could play more better if I post some plain text code...so...after a little work here it is, I've "traduced" Italian constant string to English for clarity.
1) THE PROGRAM THAT WORKS
2) THE PROGRAM THAT NOT WORKS
- constant string are 0 terminated
- user string are terminated with CR
- in the main all the string are redirected to the screen ( one problem at the time...)
- constant string works perfectly
- user string cause what you see in screenshot, garbage + string
- program run and return to basic so I think that there wouldn't be problems in subroutine call
From what I've read I've understand that if I declare a string with FCC I have to give address+1 of the string? Is correct? So in memory if i use FCC 4,/AND/,0 constant string are instantiated with LENGHT,MANY CHAR, TERMINATOR ?
I attach edited code scan and screenshot of the nonworking program
PS: gosh...On notepad++ code was beautifully spaced...
First, thank you Jeek for welcoming me on the forum and another time thank you all people have replied me
![Smile :)](./images/smilies/icon_e_smile.gif)
I've spent some time to fix the images but now I think that I could play more better if I post some plain text code...so...after a little work here it is, I've "traduced" Italian constant string to English for clarity.
1) THE PROGRAM THAT WORKS
Code: Select all
*MAIN PROGRAM THAT WORKS
ORG 20001
HEAP RMB 255
OUTCH EQU #%800C ; output char in A reg
; A remain there after
; RTS
INCH EQU #$8006 ; store in A the ASCCI
; of the key pressed
; 0 if no key pressed
CR EQU $0D
NULL EQU $00
TEXT FCC 8,/STRING=/,0 ; please correct me
FCB 0 ; here, but I've explained
; what happens if is not
; like here
MAIN PSHS U,X,B,A,CC
LEAX TEXT,PCR ; address of 1st char of fixed text
LDA #NULL ; 0 is the terminator
PSHS X,A ; pass parameters to subroutine
BSR PRINTL ; go to subroutine "print fixed string"
LEAS 3,S ; I could not waste time
LEAS -3,S ; and space but for clarity..
; let some space for subroutine results
; 16bit address and 8bit string length
BSR GETLNE ; go to subroutine "input a line from keyboard"
;
PULS A,X ; extract string length
TFR A,B ; that nobody cares at the moment
LDA #CR ; now we want to print what the user has typed
PSHS X,A ; pass parameters
BSR PRINTL ; print the string
LEAS 3,S ; fix the stack pointer
ENDM PULS A,B,X,U,CC,PC ; return to BASIC
*LIBS
******************************************************
*PRINTL - Wants the terminator type and the address of first char only
PRINTL PSHS U,X,B,A,CC
LEAU 7,S
LDX 3,U ; 1st char address
STLOOP LDA 0,X+
CMPA 2,U ; is what you set for string terminator?
BEQ ENDLOP
JSR OUTCH
BRA STLOOP
ENDLOP PULS PC,CC,A,B,X,U
*****************************************************
*GETSCH - Get a single char from keyboard.
GETSCH PSHS U,X,B,A,CC
LEAU 7,S
INPUT JSR INCH
CMPA #NULL ; if 0 key not pressed
BEQ INPUT
STA 2,U ; store ASCII of key
ENDG PULS PC,CC,A,B,X,U
********************************************************
*GETLNE - Get a whole string from the user, CR terminated
GETLNE PSHS U,X,B,A,CC
LEAU 7,S
LEAX HEAP,PCR
SCHAR LEAS -1,S
BSR GETSCH
PULS A
INC 2,U
STA ,X+
JSR OUTCH ; user char
CMPA #CR ; is enter?
BNE SCHAR
DECB ; length is without the terminator
STB 2,U
LEAX HEAP,PCR ; calculate address of 1st char
STX 3,U ; store it
ENDGTL PULS PC,CC,A,B,X,U
- constant string are 0 terminated
- user string are terminated with CR
- in the main all the string are redirected to the screen ( one problem at the time...)
- constant string works perfectly
- user string cause what you see in screenshot, garbage + string
- program run and return to basic so I think that there wouldn't be problems in subroutine call
Code: Select all
*MAIN PROGRAM THAT NOT WORKS WITH NEW PRINTL
ORG 20001
HEAP RMB 255
OUTCH EQU #%800C ; output char in A reg
; A remain there after
; RTS
INCH EQU #$8006 ; store in A the ASCCI
; of the key pressed
; 0 if no key pressed
CR EQU $0D
NULL EQU $00
OUTSER EQU #$802D ; from page 336 of "Inside the dragon" seems to behave like OUTCH
; put char in A and it sends out without destroying any register
CH2SER EQU $02 ; select output to serial
CH2SCR EQU $01 ; select output to screen
TEXT FCC 8,/STRING=/,0 ; please correct me
FCB 0 ; here, but I've explained
; what happens if is not
; like here (program halts or "memory dump" until a 0 is found
TXT2 FCC 6,/SEND=/,0
FCB
MAIN PSHS U,X,B,A,CC
LEAX TEXT,PCR ; address of 1st char of fixed text
LDA #NULL ; 0 is the terminator
LDB #CH2SCR
PSHS X,B, ; pass parameters to subroutine
BSR PRINTL ; go to subroutine "print fixed string"
; "STRING=" is correctly displayed
LEAS 4,S ; I could not waste time
LEAS -3,S ; and space but for clarity..
; let some space for subroutine results
; 16bit address and 8bit string length
BSR GETLNE ; go to subroutine "input a line from keyboard"
;
PULS A,X ; extract string length that nobody cares at the moment
LDA #CR
JSR OUTCH ; a newline on the screen
LDB #CH2SCR
LEAX TXT2,PCR
PSHS X,B,A
BSR PRINTL ; correctly displayed "SEND="
LEAS 4,S
LEAX HEAP,PCR
LDA #CR
LDB #CH2SCR
PSHS X,B,A
BSR PRINTL ; user string is badly displayed, see screenshot
LEAS 4,S ; but at least the program terminate correctly
ENDM PULS A,B,X,U,CC,PC ; return to BASIC
*LIBS
******************************************************
*PRINTL - Wants the terminator type, the address of first char and where to print out
PRINTL PSHS U,X,B,A,CC
LEAU 7,S
LDB 3,U ; what is the output? SCR or 232?
LDX 4,U ; 1st char address
STLOOP LDA 0,X+
CMPA 2,U ; is what you set for string terminator?
BEQ ENDLOP ; if it's the terminator exit
CMPB #CH2SER ; output to serial?
BNE TOSCR ; if no output to string
TOSER JSR OUTSER
TOSCR JSR OUTCH
BRA STLOOP
ENDLOP PULS PC,CC,A,B,X,U
*****************************************************
*GETSCH - Get a single char from keyboard.
GETSCH PSHS U,X,B,A,CC
LEAU 7,S
INPUT JSR INCH
CMPA #NULL ; if 0 key not pressed
BEQ INPUT
STA 2,U ; store ASCII of key
ENDG PULS PC,CC,A,B,X,U
********************************************************
*GETLNE - Get a whole string from the user, CR terminated
GETLNE PSHS U,X,B,A,CC
LEAU 7,S
LEAX HEAP,PCR
SCHAR LEAS -1,S
BSR GETSCH
PULS A
INC 2,U
STA ,X+
JSR OUTCH ; user char
CMPA #CR ; is enter?
BNE SCHAR
DECB ; length is without the terminator
STB 2,U
LEAX HEAP,PCR ; calculate address of 1st char
STX 3,U ; store it
ENDGTL PULS PC,CC,A,B,X,U
I attach edited code scan and screenshot of the nonworking program
PS: gosh...On notepad++ code was beautifully spaced...
Re: dragon64 assembler: string I/O
I still think your problem is this code trying to output TXT2 using CR as a terminator instead of NULL (0):
LDA #CR
JSR OUTCH ; a newline on the screen
LDB #CH2SCR
LEAX TXT2,PCR
PSHS X,B,A
BSR PRINTL
LDA #CR
JSR OUTCH ; a newline on the screen
LDB #CH2SCR
LEAX TXT2,PCR
PSHS X,B,A
BSR PRINTL
- heavyfranz
- Posts: 6
- Joined: Sun Sep 01, 2013 10:37 am
- Location: Italy
Re: dragon64 assembler: string I/O
You're right! I've never seen that error all the time I checked code! A is with the CR for the newline and I forgot to re-set it for TXT2! Now I'll try to patch!
it WORKS!!! Thank you very very very much!
it WORKS!!! Thank you very very very much!