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
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
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!