I've been working on porting GWMON-80 from Intel 8080 to NMOS 6502 (naturally, called GWMON-65). Part of the requirement for the port is trying to fit GWMON-65 in 512 bytes, just like GWMON-80. There's a practical reason for this: I have 6502 systems that use 1702A 256-byte EPROMs!
I've got the monitor basically ported and started working on shrinking it down to meet the goal. Originally it was 13 bytes too big, and didn't include the vectors since development has been done at 0x1000 in RAM. Going through the source, I noticed that there was a lot of space consumed by strings in general: the actual strings and printing routine of course, but especially in the setup for calling the string printer. I was loading two zero page variables with the pointer to the string, which requires eight bytes by itself! So, I came up with a way to get that down to two bytes:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;PRTSTR -- Print a high bit terminated string
;
;Destroys contents of Y register.
;
;pre: Y register contains offset into STRNGS of string to be
; printed, minus one
;post: string printed to console
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PRTSTR: INY ;Point to start of string
LDA STRNGS, Y ;A = next char in string
JSR COUT
BPL PRTSTR ;Done if high bit is set
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Message Strings
;
;These strings are indexed by the labels following STRNGS.
;These indexes may be fed into PRTSTR, PRTCLS, or PRTERR in
;the Y register.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STRNGS = *
SIGNON = ^(* - STRNGS - 1)
.byte "GWMON-65 0.1 S" ,'M' + $80
PROMPT = * - STRNGS - 1
.byte LF, '>' + $80
CSERR = * - STRNGS - 1
.byte "CKSUM "
ERRSTR = * - STRNGS - 1
.byte "ERRO", 'R' + $80
Do note that the high byte termination is being stripped in the COUT routine.
Now, the string printer is called like this:
Code:
LDY #SIGNON ;Y = offset to SIGNON string
JSR PRTSTR ;Print signon message
The indexes are calculated at assembly time, so that makes this kinda ugly solution a little more bearable. An index needs to be one less than its actual offset from the start of the string block, as this makes the string printer slightly shorter. The ^ byte cast operator had to be used on the first offset since it's a very large negative otherwise.
Anyway, I thought I'd share since I haven't run across this solution in particular in any old documents, and a cursory search on the Internet didn't reveal anything exactly like this. It's obviously limited to string blocks that are not longer than 255 characters, which does make the high bit termination more attractive. I can't see using this other than for very space-constrained applications.