Skip to content

Instantly share code, notes, and snippets.

@BigEd
Created May 21, 2012 04:33
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save BigEd/2760560 to your computer and use it in GitHub Desktop.
Save BigEd/2760560 to your computer and use it in GitHub Desktop.
Extended Woz monitor for 6502 by fsafstrom after Steve Wozniak
EWoz 1.0
by fsafstrom » Mar Wed 14, 2007 12:23 pm
http://www.brielcomputers.com/phpBB3/viewtopic.php?f=9&t=197#p888
via http://jefftranter.blogspot.co.uk/2012/05/woz-mon.html
The EWoz 1.0 is just the good old Woz mon with a few improvements and extensions so to say.
It's using ACIA @ 19200 Baud.
It prints a small welcome message when started.
All key strokes are converted to uppercase.
The backspace works so the _ is no longer needed.
When you run a program, it's called with an JSR so if the program ends with an RTS, you will be taken back to the monitor.
You can load Intel HEX format files and it keeps track of the checksum.
To load an Intel Hex file, just type L and hit return.
Now just send a Text file that is in the Intel HEX Format just as you would send a text file for the Woz mon.
You can abort the transfer by hitting ESC.
The reason for implementing a loader for HEX files is the 6502 Assembler @ http://home.pacbell.net/michal_k/6502.html
This assembler saves the code as Intel HEX format.
In the future I might implement XModem, that is if anyone would have any use for it...
Enjoy...
7000: D8 58 A9 1F 8D 03 C0 A9 0B 8D 02 C0 A9 0D 20 2A
7010: 71 A9 2F 85 2C A9 72 85 2D 20 39 71 A9 0D 20 2A
7020: 71 A9 9B C9 88 F0 13 C9 9B F0 03 C8 10 19 A9 DC
7030: 20 2A 71 A9 8D 20 2A 71 A0 01 88 30 F6 A9 A0 20
7040: 2A 71 A9 88 20 2A 71 AD 01 C0 29 08 F0 F9 AD 00
7050: C0 C9 60 30 02 29 5F 09 80 99 00 02 20 2A 71 C9
7060: 8D D0 C0 A0 FF A9 00 AA 0A 85 2B C8 B9 00 02 C9
7070: 8D F0 C0 C9 AE 90 F4 F0 F0 C9 BA F0 EB C9 D2 F0
7080: 31 C9 CC F0 36 86 28 86 29 84 2A B9 00 02 49 B0
7090: C9 0A 90 06 69 88 C9 FA 90 11 0A 0A 0A 0A A2 04
70A0: 0A 26 28 26 29 CA D0 F8 C8 D0 E0 C4 2A D0 12 4C
70B0: 2E 70 20 B8 70 4C 21 70 6C 24 00 20 46 71 4C 21
70C0: 70 24 2B 50 0D A5 28 81 26 E6 26 D0 9F E6 27 4C
70D0: 6C 70 30 2B A2 02 B5 27 95 25 95 23 CA D0 F7 D0
70E0: 14 A9 8D 20 2A 71 A5 25 20 17 71 A5 24 20 17 71
70F0: A9 BA 20 2A 71 A9 A0 20 2A 71 A1 24 20 17 71 86
7100: 2B A5 24 C5 28 A5 25 E5 29 B0 C4 E6 24 D0 02 E6
7110: 25 A5 24 29 0F 10 C8 48 4A 4A 4A 4A 20 20 71 68
7120: 29 0F 09 B0 C9 BA 90 02 69 06 48 29 7F 8D 00 C0
7130: AD 01 C0 29 10 F0 F9 68 60 A0 00 B1 2C F0 06 20
7140: 2A 71 C8 D0 F6 60 A9 0D 20 2A 71 A9 44 85 2C A9
7150: 72 85 2D 20 39 71 A9 0D 20 2A 71 A0 00 84 30 20
7160: 24 72 99 00 02 C8 C9 1B F0 67 C9 0D D0 F1 A0 FF
7170: C8 B9 00 02 C9 3A D0 F8 C8 A2 00 86 2F 20 01 72
7180: 85 2E 18 65 2F 85 2F 20 01 72 85 27 18 65 2F 85
7190: 2F 20 01 72 85 26 18 65 2F 85 2F A9 2E 20 2A 71
71A0: 20 01 72 C9 01 F0 2A 18 65 2F 85 2F 20 01 72 81
71B0: 26 18 65 2F 85 2F E6 26 D0 02 E6 27 C6 2E D0 EC
71C0: 20 01 72 A0 00 18 65 2F F0 95 A9 01 85 30 4C 5F
71D0: 71 A5 30 F0 16 A9 0D 20 2A 71 A9 7A 85 2C A9 72
71E0: 85 2D 20 39 71 A9 0D 20 2A 71 60 A9 0D 20 2A 71
71F0: A9 63 85 2C A9 72 85 2D 20 39 71 A9 0D 20 2A 71
7200: 60 B9 00 02 49 30 C9 0A 90 02 69 08 0A 0A 0A 0A
7210: 85 28 C8 B9 00 02 49 30 C9 0A 90 02 69 08 29 0F
7220: 05 28 C8 60 AD 01 C0 29 08 F0 F9 AD 00 C0 60 57
7230: 65 6C 63 6F 6D 65 20 74 6F 20 45 57 4F 5A 20 31
7240: 2E 30 2E 00 53 74 61 72 74 20 49 6E 74 65 6C 20
7250: 48 65 78 20 63 6F 64 65 20 54 72 61 6E 73 66 65
7260: 72 2E 00 49 6E 74 65 6C 20 48 65 78 20 49 6D 70
7270: 6F 72 74 65 64 20 4F 4B 2E 00 49 6E 74 65 6C 20
7280: 48 65 78 20 49 6D 70 6F 72 74 65 64 20 77 69 74
7290: 68 20 63 68 65 63 6B 73 75 6D 20 65 72 72 6F 72
72A0: 2E 00
; EWOZ Extended Woz Monitor.
; Just a few mods to the original monitor.
; START @ $7000
* = $7000
ACIA = $C000
ACIA_CTRL = ACIA+3
ACIA_CMD = ACIA+2
ACIA_SR = ACIA+1
ACIA_DAT = ACIA
IN = $0200 ;*Input buffer
XAML = $24 ;*Index pointers
XAMH = $25
STL = $26
STH = $27
L = $28
H = $29
YSAV = $2A
MODE = $2B
MSGL = $2C
MSGH = $2D
COUNTER = $2E
CRC = $2F
CRCCHECK = $30
RESET CLD ;Clear decimal arithmetic mode.
CLI
LDA #$1F ;* Init ACIA to 19200 Baud.
STA ACIA_CTRL
LDA #$0B ;* No Parity.
STA ACIA_CMD
LDA #$0D
JSR ECHO ;* New line.
LDA #<MSG1
STA MSGL
LDA #>MSG1
STA MSGH
JSR SHWMSG ;* Show Welcome.
LDA #$0D
JSR ECHO ;* New line.
SOFTRESET LDA #$9B ;* Auto escape.
NOTCR CMP #$88 ;"<-"? * Note this was chaged to $88 which is the back space key.
BEQ BACKSPACE ;Yes.
CMP #$9B ;ESC?
BEQ ESCAPE ;Yes.
INY ;Advance text index.
BPL NEXTCHAR ;Auto ESC if >127.
ESCAPE LDA #$DC ;"\"
JSR ECHO ;Output it.
GETLINE LDA #$8D ;CR.
JSR ECHO ;Output it.
LDY #$01 ;Initiallize text index.
BACKSPACE DEY ;Backup text index.
BMI GETLINE ;Beyond start of line, reinitialize.
LDA #$A0 ;*Space, overwrite the backspaced char.
JSR ECHO
LDA #$88 ;*Backspace again to get to correct pos.
JSR ECHO
NEXTCHAR LDA ACIA_SR ;*See if we got an incoming char
AND #$08 ;*Test bit 3
BEQ NEXTCHAR ;*Wait for character
LDA ACIA_DAT ;*Load char
CMP #$60 ;*Is it Lower case
BMI CONVERT ;*Nope, just convert it
AND #$5F ;*If lower case, convert to Upper case
CONVERT ORA #$80 ;*Convert it to "ASCII Keyboard" Input
STA IN,Y ;Add to text buffer.
JSR ECHO ;Display character.
CMP #$8D ;CR?
BNE NOTCR ;No.
LDY #$FF ;Reset text index.
LDA #$00 ;For XAM mode.
TAX ;0->X.
SETSTOR ASL ;Leaves $7B if setting STOR mode.
SETMODE STA MODE ;$00 = XAM, $7B = STOR, $AE = BLOK XAM.
BLSKIP INY ;Advance text index.
NEXTITEM LDA IN,Y ;Get character.
CMP #$8D ;CR?
BEQ GETLINE ;Yes, done this line.
CMP #$AE ;"."?
BCC BLSKIP ;Skip delimiter.
BEQ SETMODE ;Set BLOCK XAM mode.
CMP #$BA ;":"?
BEQ SETSTOR ;Yes, set STOR mode.
CMP #$D2 ;"R"?
BEQ RUN ;Yes, run user program.
CMP #$CC ;* "L"?
BEQ LOADINT ;* Yes, Load Intel Code.
STX L ;$00->L.
STX H ; and H.
STY YSAV ;Save Y for comparison.
NEXTHEX LDA IN,Y ;Get character for hex test.
EOR #$B0 ;Map digits to $0-9.
CMP #$0A ;Digit?
BCC DIG ;Yes.
ADC #$88 ;Map letter "A"-"F" to $FA-FF.
CMP #$FA ;Hex letter?
BCC NOTHEX ;No, character not hex.
DIG ASL
ASL ;Hex digit to MSD of A.
ASL
ASL
LDX #$04 ;Shift count.
HEXSHIFT ASL ;Hex digit left MSB to carry.
ROL L ;Rotate into LSD.
ROL H ;Rotate into MSD's.
DEX ;Done 4 shifts?
BNE HEXSHIFT ;No, loop.
INY ;Advance text index.
BNE NEXTHEX ;Always taken. Check next character for hex.
NOTHEX CPY YSAV ;Check if L, H empty (no hex digits).
BNE NOESCAPE ;* Branch out of range, had to improvise...
JMP ESCAPE ;Yes, generate ESC sequence.
RUN JSR ACTRUN ;* JSR to the Address we want to run.
JMP SOFTRESET ;* When returned for the program, reset EWOZ.
ACTRUN JMP (XAML) ;Run at current XAM index.
LOADINT JSR LOADINTEL ;* Load the Intel code.
JMP SOFTRESET ;* When returned from the program, reset EWOZ.
NOESCAPE BIT MODE ;Test MODE byte.
BVC NOTSTOR ;B6=0 for STOR, 1 for XAM and BLOCK XAM
LDA L ;LSD's of hex data.
STA (STL, X) ;Store at current "store index".
INC STL ;Increment store index.
BNE NEXTITEM ;Get next item. (no carry).
INC STH ;Add carry to 'store index' high order.
TONEXTITEM JMP NEXTITEM ;Get next command item.
NOTSTOR BMI XAMNEXT ;B7=0 for XAM, 1 for BLOCK XAM.
LDX #$02 ;Byte count.
SETADR LDA L-1,X ;Copy hex data to
STA STL-1,X ;"store index".
STA XAML-1,X ;And to "XAM index'.
DEX ;Next of 2 bytes.
BNE SETADR ;Loop unless X = 0.
NXTPRNT BNE PRDATA ;NE means no address to print.
LDA #$8D ;CR.
JSR ECHO ;Output it.
LDA XAMH ;'Examine index' high-order byte.
JSR PRBYTE ;Output it in hex format.
LDA XAML ;Low-order "examine index" byte.
JSR PRBYTE ;Output it in hex format.
LDA #$BA ;":".
JSR ECHO ;Output it.
PRDATA LDA #$A0 ;Blank.
JSR ECHO ;Output it.
LDA (XAML,X) ;Get data byte at 'examine index".
JSR PRBYTE ;Output it in hex format.
XAMNEXT STX MODE ;0-> MODE (XAM mode).
LDA XAML
CMP L ;Compare 'examine index" to hex data.
LDA XAMH
SBC H
BCS TONEXTITEM ;Not less, so no more data to output.
INC XAML
BNE MOD8CHK ;Increment 'examine index".
INC XAMH
MOD8CHK LDA XAML ;Check low-order 'exainine index' byte
AND #$0F ;For MOD 8=0 ** changed to $0F to get 16 values per row **
BPL NXTPRNT ;Always taken.
PRBYTE PHA ;Save A for LSD.
LSR
LSR
LSR ;MSD to LSD position.
LSR
JSR PRHEX ;Output hex digit.
PLA ;Restore A.
PRHEX AND #$0F ;Mask LSD for hex print.
ORA #$B0 ;Add "0".
CMP #$BA ;Digit?
BCC ECHO ;Yes, output it.
ADC #$06 ;Add offset for letter.
ECHO PHA ;*Save A
AND #$7F ;*Change to "standard ASCII"
STA ACIA_DAT ;*Send it.
.WAIT LDA ACIA_SR ;*Load status register for ACIA
AND #$10 ;*Mask bit 4.
BEQ .WAIT ;*ACIA not done yet, wait.
PLA ;*Restore A
RTS ;*Done, over and out...
SHWMSG LDY #$0
.PRINT LDA (MSGL),Y
BEQ .DONE
JSR ECHO
INY
BNE .PRINT
.DONE RTS
; Load an program in Intel Hex Format.
LOADINTEL LDA #$0D
JSR ECHO ;New line.
LDA #<MSG2
STA MSGL
LDA #>MSG2
STA MSGH
JSR SHWMSG ;Show Start Transfer.
LDA #$0D
JSR ECHO ;New line.
LDY #$00
STY CRCCHECK ;If CRCCHECK=0, all is good.
INTELLINE JSR GETCHAR ;Get char
STA IN,Y ;Store it
INY ;Next
CMP #$1B ;Escape ?
BEQ INTELDONE ;Yes, abort.
CMP #$0D ;Did we find a new line ?
BNE INTELLINE ;Nope, continue to scan line.
LDY #$FF ;Find (:)
FINDCOL INY
LDA IN,Y
CMP #$3A ; Is it Colon ?
BNE FINDCOL ; Nope, try next.
INY ; Skip colon
LDX #$00 ; Zero in X
STX CRC ; Zero Check sum
JSR GETHEX ; Get Number of bytes.
STA COUNTER ; Number of bytes in Counter.
CLC ; Clear carry
ADC CRC ; Add CRC
STA CRC ; Store it
JSR GETHEX ; Get Hi byte
STA STH ; Store it
CLC ; Clear carry
ADC CRC ; Add CRC
STA CRC ; Store it
JSR GETHEX ; Get Lo byte
STA STL ; Store it
CLC ; Clear carry
ADC CRC ; Add CRC
STA CRC ; Store it
LDA #$2E ; Load "."
JSR ECHO ; Print it to indicate activity.
NODOT JSR GETHEX ; Get Control byte.
CMP #$01 ; Is it a Termination record ?
BEQ INTELDONE ; Yes, we are done.
CLC ; Clear carry
ADC CRC ; Add CRC
STA CRC ; Store it
INTELSTORE JSR GETHEX ; Get Data Byte
STA (STL,X) ; Store it
CLC ; Clear carry
ADC CRC ; Add CRC
STA CRC ; Store it
INC STL ; Next Address
BNE TESTCOUNT ; Test to see if Hi byte needs INC
INC STH ; If so, INC it.
TESTCOUNT DEC COUNTER ; Count down.
BNE INTELSTORE ; Next byte
JSR GETHEX ; Get Checksum
LDY #$00 ; Zero Y
CLC ; Clear carry
ADC CRC ; Add CRC
BEQ INTELLINE ; Checksum OK.
LDA #$01 ; Flag CRC error.
STA CRCCHECK ; Store it
JMP INTELLINE ; Process next line.
INTELDONE LDA CRCCHECK ; Test if everything is OK.
BEQ OKMESS ; Show OK message.
LDA #$0D
JSR ECHO ;New line.
LDA #<MSG4 ; Load Error Message
STA MSGL
LDA #>MSG4
STA MSGH
JSR SHWMSG ;Show Error.
LDA #$0D
JSR ECHO ;New line.
RTS
OKMESS LDA #$0D
JSR ECHO ;New line.
LDA #<MSG3 ;Load OK Message.
STA MSGL
LDA #>MSG3
STA MSGH
JSR SHWMSG ;Show Done.
LDA #$0D
JSR ECHO ;New line.
RTS
GETHEX LDA IN,Y ;Get first char.
EOR #$30
CMP #$0A
BCC DONEFIRST
ADC #$08
DONEFIRST ASL
ASL
ASL
ASL
STA L
INY
LDA IN,Y ;Get next char.
EOR #$30
CMP #$0A
BCC DONESECOND
ADC #$08
DONESECOND AND #$0F
ORA L
INY
RTS
GETCHAR LDA ACIA_SR ;See if we got an incoming char
AND #$08 ;Test bit 3
BEQ GETCHAR ;Wait for character
LDA ACIA_DAT ;Load char
RTS
MSG1 !TEXT "Welcome to EWOZ 1.0.",0
MSG2 !TEXT "Start Intel Hex code Transfer.",0
MSG3 !TEXT "Intel Hex Imported OK.",0
MSG4 !TEXT "Intel Hex Imported with checksum error.",0
@TheTrueForce
Copy link

TheTrueForce commented Sep 29, 2017

Is there anything that will bug if I assemble this to go in ROM?
I've had a look at it and it doesn't appear so, but I'd like to seek a second opinion anyway.

EDIT: It seems to work when assembled to go in ROM. It certainly displays the welcome message, at any rate.

@ramgui
Copy link

ramgui commented Jan 7, 2020

I just made 2 changes, ACIA's address and .org to match my memory map and assembled to ROM. Vector for reset was also changed to match address.
.org $8000
ACIA = $5000
$FFFC = $8000 ($FFFC=00, $FFFD=80)

I can't seem to make it work. I'm using FTDI TTL to USB which works with my other codes.
Any other changes I need to make it work?
Unlike TheTrueForce comment, it does not even display the welcome message.

@BigEd
Copy link
Author

BigEd commented Jan 7, 2020

Probably best to start a discussion thread over on the 6502.org forums. All problems can be solved!

@ramgui
Copy link

ramgui commented Jan 7, 2020

I got it working! I had a bad batch of EEPROMs and tried to burn it on a new chip and it works beautifully.
Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment