mirror of
https://github.com/tebl/RC6502-Apple-1-Replica.git
synced 2024-12-30 02:31:22 +00:00
wozmon source
This commit is contained in:
parent
6c09ac5565
commit
87cdd5d782
6
software/firmware/WozMon/README.md
Normal file
6
software/firmware/WozMon/README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Woz Monitor
|
||||
This project was originally aimed at being an Apple 1 replica, but before long I got distracted by other things and started adding a lot of things that were never present on the original machine - mostly because making them is fun! On the other hand, one shouldn't forget one's own roots - the computer is still an Apple 1 at heart and so it needs the Woz Monitor.
|
||||
|
||||
This has always been part of the software package, but I haven't had an attempt at doing something on the coding side of things - step 1 is then, naturally, to get a version of the code that can compile before introducting my own bugs into it all. I'm currently using [SB-Assembler 3](https://www.sbprojects.net/sbasm/index.php) as my choice of assembler, so given that the creator of that hosts a copy of assembler source files for WozMon on the same site at [Apple 1 ROMs](https://www.sbprojects.net/projects/apple1/download.php).
|
||||
|
||||
I'm hoping to add more functionality to the code in order to support my own cards as time goes by, but until I get that farI also noticed that someone has already made a version of the monitor that works with an ACIA (serial) called [EWoz](http://www.brielcomputers.com/phpBB3/viewtopic.php?f=9&t=197) which may be of some interest.
|
4
software/firmware/WozMon/assemble.bat
Normal file
4
software/firmware/WozMon/assemble.bat
Normal file
@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
sbasm.py wozaci.asm
|
||||
sbasm.py wozmon.asm
|
||||
pause
|
245
software/firmware/WozMon/wozaci.asm
Normal file
245
software/firmware/WozMon/wozaci.asm
Normal file
@ -0,0 +1,245 @@
|
||||
.CR 6502
|
||||
.TF wozaci.hex,HEX,8
|
||||
.LF wozaci.list
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; The WOZ Apple Cassette Interface for the Apple 1
|
||||
; Written by Steve Wozniak somewhere around 1976
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Memory declaration
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
HEX1L .EQ $24 End address of dump block
|
||||
HEX1H .EQ $25
|
||||
HEX2L .EQ $26 Begin address of dump block
|
||||
HEX2H .EQ $27
|
||||
SAVEINDEX .EQ $28 Save index in input buffer
|
||||
LASTSTATE .EQ $29 Last input state
|
||||
|
||||
IN .EQ $0200 Input buffer
|
||||
FLIP .EQ $C000 Output flip-flop
|
||||
TAPEIN .EQ $C081 Tape input
|
||||
KBD .EQ $D010 PIA.A keyboard input
|
||||
KBDCR .EQ $D011 PIA.A keyboard control register
|
||||
ESCAPE .EQ $FF1A Escape back to monitor
|
||||
ECHO .EQ $FFEF Echo character to terminal
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Constants
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
CR .EQ $8D Carriage Return
|
||||
ESC .EQ $9B ASCII ESC
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Let's get started
|
||||
;-------------------------------------------------------------------------
|
||||
.OR $C100
|
||||
WOZACI LDA #"*" Print the Tape prompt
|
||||
JSR ECHO
|
||||
LDA #CR And drop the cursor one line
|
||||
JSR ECHO
|
||||
|
||||
LDY #-1 Reset the input buffer index
|
||||
NEXTCHAR INY
|
||||
KBDWAIT LDA KBDCR Wait for a key
|
||||
BPL KBDWAIT Still no key!
|
||||
|
||||
LDA KBD Read key from keyboard
|
||||
STA IN,Y Save it into buffer
|
||||
JSR ECHO And type it on the screen
|
||||
CMP #ESC
|
||||
BEQ WOZACI Start from scratch if ESC!
|
||||
CMP #CR
|
||||
BNE NEXTCHAR Read keys until CR
|
||||
|
||||
LDX #-1 Initialize parse buffer pointer
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Start parsing first or a new tape command
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NEXTCMD LDA #0 Clear begin and end values
|
||||
STA HEX1L
|
||||
STA HEX1H
|
||||
STA HEX2L
|
||||
STA HEX2H
|
||||
|
||||
NEXTCHR INX Increment input pointer
|
||||
LDA IN,X Get next char from input line
|
||||
CMP #"R" Read command?
|
||||
BEQ READ Yes!
|
||||
CMP #"W" Write command?
|
||||
BEQ WRITE Yes! (note: CY=1)
|
||||
CMP #"." Separator?
|
||||
BEQ SEP Yes!
|
||||
CMP #CR End of line?
|
||||
BEQ GOESC Escape to monitor! We're done
|
||||
CMP #" " Ignore spaces
|
||||
BEQ NEXTCHR
|
||||
EOR #"0" Map digits to 0-9
|
||||
CMP #9+1 Is it a decimal digit?
|
||||
BCC DIG Yes!
|
||||
ADC #$88 Map letter "A"-"F" to $FA-$FF
|
||||
CMP #$FA Hex letter?
|
||||
BCC WOZACI No! Character not hex!
|
||||
|
||||
DIG ASL Hex digit to MSD of A
|
||||
ASL
|
||||
ASL
|
||||
ASL
|
||||
|
||||
LDY #4 Shift count
|
||||
HEXSHIFT ASL Hex digit left, MSB to carry
|
||||
ROL HEX1L Rotate into LSD
|
||||
ROL HEX1H Rotate into MSD
|
||||
DEY Done 4 shifts?
|
||||
BNE HEXSHIFT No! Loop
|
||||
BEQ NEXTCHR Handle next character
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Return to monitor, prints \ first
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
GOESC JMP ESCAPE Escape back to monitor
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Separating . found. Copy HEX1 to Hex2. Doesn't clear HEX1!!!
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
SEP LDA HEX1L Copy hex value 1 to hex value 2
|
||||
STA HEX2L
|
||||
LDA HEX1H
|
||||
STA HEX2H
|
||||
BCS NEXTCHR Always taken!
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Write a block of memory to tape
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
WRITE LDA #64 Write 10 second header
|
||||
JSR WHEADER
|
||||
|
||||
WRNEXT DEY Compensate timing for extra work
|
||||
LDX #0 Get next byte to write
|
||||
LDA (HEX2L,X)
|
||||
|
||||
LDX #8*2 Shift 8 bits (decremented twice)
|
||||
WBITLOOP ASL Shift MSB to carry
|
||||
JSR WRITEBIT Write this bit
|
||||
BNE WBITLOOP Do all 8 bits!
|
||||
|
||||
JSR INCADDR Increment address
|
||||
LDY #30 Compensate timer for extra work
|
||||
BCC WRNEXT Not done yet! Write next byte
|
||||
|
||||
RESTIDX LDX SAVEINDEX Restore index in input line
|
||||
BCS NEXTCMD Always taken!
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Read from tape
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
READ JSR FULLCYCLE Wait until full cycle is detected
|
||||
LDA #22 Introduce some delay to allow
|
||||
JSR WHEADER the tape speed to stabilize
|
||||
JSR FULLCYCLE Synchronize with full cycle
|
||||
|
||||
NOTSTART LDY #31 Try to detect the much shorter
|
||||
JSR CMPLEVEL start bit
|
||||
BCS NOTSTART Start bit not detected yet!
|
||||
|
||||
JSR CMPLEVEL Wait for 2nd phase of start bit
|
||||
|
||||
LDY #58 Set threshold value in middle
|
||||
RDBYTE LDX #8 Receiver 8 bits
|
||||
RDBIT PHA
|
||||
JSR FULLCYCLE Detect a full cycle
|
||||
PLA
|
||||
ROL Roll new bit into result
|
||||
LDY #57 Set threshold value in middle
|
||||
DEX Decrement bit counter
|
||||
BNE RDBIT Read next bit!
|
||||
STA (HEX2L,X) Save new byte
|
||||
|
||||
JSR INCADDR Increment address
|
||||
LDY #53 Compensate threshold with workload
|
||||
BCC RDBYTE Do next byte if not done yet!
|
||||
BCS RESTIDX Always taken! Restore parse index
|
||||
|
||||
FULLCYCLE JSR CMPLEVEL Wait for two level changes
|
||||
CMPLEVEL DEY Decrement time counter
|
||||
LDA TAPEIN Get Tape In data
|
||||
CMP LASTSTATE Same as before?
|
||||
BEQ CMPLEVEL Yes!
|
||||
STA LASTSTATE Save new data
|
||||
|
||||
CPY #128 Compare threshold
|
||||
RTS
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Write header to tape
|
||||
;
|
||||
; The header consists of an asymmetric cycle, starting with one phase of
|
||||
; approximately (66+47)x5=565us, followed by a second phase of
|
||||
; approximately (44+47)x5=455us.
|
||||
; Total cycle duration is approximately 1020us ~ 1kHz. The actual
|
||||
; frequencywill be a bit lower because of the additional workload between
|
||||
; the twoloops.
|
||||
; The header ends with a short phase of (30+47)x5=385us and a normal
|
||||
; phase of (44+47)x5=455us. This start bit must be detected by the read
|
||||
; routine to trigger the reading of the actual data.
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
WHEADER STX SAVEINDEX Save index in input line
|
||||
HCOUNT LDY #66 Extra long delay
|
||||
JSR WDELAY CY is constantly 1, writing a 1
|
||||
BNE HCOUNT Do this 64 * 256 time!
|
||||
ADC #-2 Decrement A (CY=1 all the time)
|
||||
BCS HCOUNT Not all done!
|
||||
LDY #30 Write a final short bit (start)
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Write a full bit cycle
|
||||
;
|
||||
; Upon entry Y contains a compensated value for the first phase of 0
|
||||
; bit length. All subsequent loops don't have to be time compensated.
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
WRITEBIT JSR WDELAY Do two equal phases
|
||||
LDY #44 Load 250us counter - compensation
|
||||
|
||||
WDELAY DEY Delay 250us (one phase of 2kHz)
|
||||
BNE WDELAY
|
||||
BCC WRITE1 Write a '1' (2kHz)
|
||||
|
||||
LDY #47 Additional delay for '0' (1kHz)
|
||||
WDELAY0 DEY (delay 250us)
|
||||
BNE WDELAY0
|
||||
|
||||
WRITE1 LDY FLIP,X Flip the output bit
|
||||
LDY #41 Reload 250us cntr (compensation)
|
||||
DEX Decrement bit counter
|
||||
RTS
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Increment current address and compare with last address
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
INCADDR LDA HEX2L Compare current address with
|
||||
CMP HEX1L end address
|
||||
LDA HEX2H
|
||||
SBC HEX1H
|
||||
INC HEX2L And increment current address
|
||||
BNE NOCARRY No carry to MSB!
|
||||
INC HEX2H
|
||||
NOCARRY RTS
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.LI OFF
|
||||
|
32
software/firmware/WozMon/wozaci.hex
Normal file
32
software/firmware/WozMon/wozaci.hex
Normal file
@ -0,0 +1,32 @@
|
||||
A9AA20EFFFA98D20
|
||||
EFFFA0FFC8AD11D0
|
||||
10FBAD10D0990002
|
||||
20EFFFC99BF0E1C9
|
||||
8DD0E9A2FFA90085
|
||||
24852585268527E8
|
||||
BD0002C9D2F056C9
|
||||
D7F035C9AEF027C9
|
||||
8DF020C9A0F0E849
|
||||
B0C90A90066988C9
|
||||
FA90AD0A0A0A0AA0
|
||||
040A2624262588D0
|
||||
F8F0CC4C1AFFA524
|
||||
8526A5258527B0BF
|
||||
A94020CCC188A200
|
||||
A126A2100A20DBC1
|
||||
D0FA20F1C1A01E90
|
||||
ECA628B09820BCC1
|
||||
A91620CCC120BCC1
|
||||
A01F20BFC1B0F920
|
||||
BFC1A03AA2084820
|
||||
BCC1682AA039CAD0
|
||||
F5812620F1C1A035
|
||||
90EAB0CD20BFC188
|
||||
AD81C0C529F0F885
|
||||
29C080608628A042
|
||||
20E0C1D0F969FEB0
|
||||
F5A01E20E0C1A02C
|
||||
88D0FD9005A02F88
|
||||
D0FDBC00C0A029CA
|
||||
60A526C524A527E5
|
||||
25E626D002E62760
|
240
software/firmware/WozMon/wozaci.list
Normal file
240
software/firmware/WozMon/wozaci.list
Normal file
@ -0,0 +1,240 @@
|
||||
0000- 4 ;-------------------------------------------------------------------------
|
||||
0000- 5 ;
|
||||
0000- 6 ; The WOZ Apple Cassette Interface for the Apple 1
|
||||
0000- 7 ; Written by Steve Wozniak somewhere around 1976
|
||||
0000- 8 ;
|
||||
0000- 9 ;-------------------------------------------------------------------------
|
||||
0000- 10
|
||||
0000- 11
|
||||
0000- 12 ;-------------------------------------------------------------------------
|
||||
0000- 13 ; Memory declaration
|
||||
0000- 14 ;-------------------------------------------------------------------------
|
||||
0000- 15
|
||||
0024- 16 HEX1L .EQ $24 End address of dump block
|
||||
0025- 17 HEX1H .EQ $25
|
||||
0026- 18 HEX2L .EQ $26 Begin address of dump block
|
||||
0027- 19 HEX2H .EQ $27
|
||||
0028- 20 SAVEINDEX .EQ $28 Save index in input buffer
|
||||
0029- 21 LASTSTATE .EQ $29 Last input state
|
||||
0000- 22
|
||||
0200- 23 IN .EQ $0200 Input buffer
|
||||
C000- 24 FLIP .EQ $C000 Output flip-flop
|
||||
C081- 25 TAPEIN .EQ $C081 Tape input
|
||||
D010- 26 KBD .EQ $D010 PIA.A keyboard input
|
||||
D011- 27 KBDCR .EQ $D011 PIA.A keyboard control register
|
||||
FF1A- 28 ESCAPE .EQ $FF1A Escape back to monitor
|
||||
FFEF- 29 ECHO .EQ $FFEF Echo character to terminal
|
||||
0000- 30
|
||||
0000- 31 ;-------------------------------------------------------------------------
|
||||
0000- 32 ; Constants
|
||||
0000- 33 ;-------------------------------------------------------------------------
|
||||
0000- 34
|
||||
008D- 35 CR .EQ $8D Carriage Return
|
||||
009B- 36 ESC .EQ $9B ASCII ESC
|
||||
0000- 37
|
||||
0000- 38 ;-------------------------------------------------------------------------
|
||||
0000- 39 ; Let's get started
|
||||
0000- 40 ;-------------------------------------------------------------------------
|
||||
C100- 41 .OR $C100
|
||||
C100-A9 AA 42 ( 2) WOZACI LDA #"*" Print the Tape prompt
|
||||
C102-20 EF FF 43 ( 6) JSR ECHO
|
||||
C105-A9 8D 44 ( 2) LDA #CR And drop the cursor one line
|
||||
C107-20 EF FF 45 ( 6) JSR ECHO
|
||||
C10A- 46
|
||||
C10A-A0 FF 47 ( 2) LDY #-1 Reset the input buffer index
|
||||
C10C-C8 48 ( 2) NEXTCHAR INY
|
||||
C10D-AD 11 D0 49 ( 4) KBDWAIT LDA KBDCR Wait for a key
|
||||
C110-10 FB 50 (2**) BPL KBDWAIT Still no key!
|
||||
C112- 51
|
||||
C112-AD 10 D0 52 ( 4) LDA KBD Read key from keyboard
|
||||
C115-99 00 02 53 ( 5) STA IN,Y Save it into buffer
|
||||
C118-20 EF FF 54 ( 6) JSR ECHO And type it on the screen
|
||||
C11B-C9 9B 55 ( 2) CMP #ESC
|
||||
C11D-F0 E1 56 (2**) BEQ WOZACI Start from scratch if ESC!
|
||||
C11F-C9 8D 57 ( 2) CMP #CR
|
||||
C121-D0 E9 58 (2**) BNE NEXTCHAR Read keys until CR
|
||||
C123- 59
|
||||
C123-A2 FF 60 ( 2) LDX #-1 Initialize parse buffer pointer
|
||||
C125- 61
|
||||
C125- 62 ;-------------------------------------------------------------------------
|
||||
C125- 63 ; Start parsing first or a new tape command
|
||||
C125- 64 ;-------------------------------------------------------------------------
|
||||
C125- 65
|
||||
C125-A9 00 66 ( 2) NEXTCMD LDA #0 Clear begin and end values
|
||||
C127-85 24 67 ( 2) STA HEX1L
|
||||
C129-85 25 68 ( 2) STA HEX1H
|
||||
C12B-85 26 69 ( 2) STA HEX2L
|
||||
C12D-85 27 70 ( 2) STA HEX2H
|
||||
C12F- 71
|
||||
C12F-E8 72 ( 2) NEXTCHR INX Increment input pointer
|
||||
C130-BD 00 02 73 ( 4*) LDA IN,X Get next char from input line
|
||||
C133-C9 D2 74 ( 2) CMP #"R" Read command?
|
||||
C135-F0 56 75 (2**) BEQ READ Yes!
|
||||
C137-C9 D7 76 ( 2) CMP #"W" Write command?
|
||||
C139-F0 35 77 (2**) BEQ WRITE Yes! (note: CY=1)
|
||||
C13B-C9 AE 78 ( 2) CMP #"." Separator?
|
||||
C13D-F0 27 79 (2**) BEQ SEP Yes!
|
||||
C13F-C9 8D 80 ( 2) CMP #CR End of line?
|
||||
C141-F0 20 81 (2**) BEQ GOESC Escape to monitor! We're done
|
||||
C143-C9 A0 82 ( 2) CMP #" " Ignore spaces
|
||||
C145-F0 E8 83 (2**) BEQ NEXTCHR
|
||||
C147-49 B0 84 ( 2) EOR #"0" Map digits to 0-9
|
||||
C149-C9 0A 85 ( 2) CMP #9+1 Is it a decimal digit?
|
||||
C14B-90 06 86 (2**) BCC DIG Yes!
|
||||
C14D-69 88 87 ( 2) ADC #$88 Map letter "A"-"F" to $FA-$FF
|
||||
C14F-C9 FA 88 ( 2) CMP #$FA Hex letter?
|
||||
C151-90 AD 89 (2**) BCC WOZACI No! Character not hex!
|
||||
C153- 90
|
||||
C153-0A 91 ( 2) DIG ASL Hex digit to MSD of A
|
||||
C154-0A 92 ( 2) ASL
|
||||
C155-0A 93 ( 2) ASL
|
||||
C156-0A 94 ( 2) ASL
|
||||
C157- 95
|
||||
C157-A0 04 96 ( 2) LDY #4 Shift count
|
||||
C159-0A 97 ( 2) HEXSHIFT ASL Hex digit left, MSB to carry
|
||||
C15A-26 24 98 ( 5) ROL HEX1L Rotate into LSD
|
||||
C15C-26 25 99 ( 5) ROL HEX1H Rotate into MSD
|
||||
C15E-88 100 ( 2) DEY Done 4 shifts?
|
||||
C15F-D0 F8 101 (2**) BNE HEXSHIFT No! Loop
|
||||
C161-F0 CC 102 (2**) BEQ NEXTCHR Handle next character
|
||||
C163- 103
|
||||
C163- 104 ;-------------------------------------------------------------------------
|
||||
C163- 105 ; Return to monitor, prints \ first
|
||||
C163- 106 ;-------------------------------------------------------------------------
|
||||
C163- 107
|
||||
C163-4C 1A FF 108 ( 3) GOESC JMP ESCAPE Escape back to monitor
|
||||
C166- 109
|
||||
C166- 110 ;-------------------------------------------------------------------------
|
||||
C166- 111 ; Separating . found. Copy HEX1 to Hex2. Doesn't clear HEX1!!!
|
||||
C166- 112 ;-------------------------------------------------------------------------
|
||||
C166- 113
|
||||
C166-A5 24 114 ( 3) SEP LDA HEX1L Copy hex value 1 to hex value 2
|
||||
C168-85 26 115 ( 2) STA HEX2L
|
||||
C16A-A5 25 116 ( 3) LDA HEX1H
|
||||
C16C-85 27 117 ( 2) STA HEX2H
|
||||
C16E-B0 BF 118 (2**) BCS NEXTCHR Always taken!
|
||||
C170- 119
|
||||
C170- 120 ;-------------------------------------------------------------------------
|
||||
C170- 121 ; Write a block of memory to tape
|
||||
C170- 122 ;-------------------------------------------------------------------------
|
||||
C170- 123
|
||||
C170-A9 40 124 ( 2) WRITE LDA #64 Write 10 second header
|
||||
C172-20 CC C1 125 ( 6) JSR WHEADER
|
||||
C175- 126
|
||||
C175-88 127 ( 2) WRNEXT DEY Compensate timing for extra work
|
||||
C176-A2 00 128 ( 2) LDX #0 Get next byte to write
|
||||
C178-A1 26 129 ( 6) LDA (HEX2L,X)
|
||||
C17A- 130
|
||||
C17A-A2 10 131 ( 2) LDX #8*2 Shift 8 bits (decremented twice)
|
||||
C17C-0A 132 ( 2) WBITLOOP ASL Shift MSB to carry
|
||||
C17D-20 DB C1 133 ( 6) JSR WRITEBIT Write this bit
|
||||
C180-D0 FA 134 (2**) BNE WBITLOOP Do all 8 bits!
|
||||
C182- 135
|
||||
C182-20 F1 C1 136 ( 6) JSR INCADDR Increment address
|
||||
C185-A0 1E 137 ( 2) LDY #30 Compensate timer for extra work
|
||||
C187-90 EC 138 (2**) BCC WRNEXT Not done yet! Write next byte
|
||||
C189- 139
|
||||
C189-A6 28 140 ( 3) RESTIDX LDX SAVEINDEX Restore index in input line
|
||||
C18B-B0 98 141 (2**) BCS NEXTCMD Always taken!
|
||||
C18D- 142
|
||||
C18D- 143 ;-------------------------------------------------------------------------
|
||||
C18D- 144 ; Read from tape
|
||||
C18D- 145 ;-------------------------------------------------------------------------
|
||||
C18D- 146
|
||||
C18D-20 BC C1 147 ( 6) READ JSR FULLCYCLE Wait until full cycle is detected
|
||||
C190-A9 16 148 ( 2) LDA #22 Introduce some delay to allow
|
||||
C192-20 CC C1 149 ( 6) JSR WHEADER the tape speed to stabilize
|
||||
C195-20 BC C1 150 ( 6) JSR FULLCYCLE Synchronize with full cycle
|
||||
C198- 151
|
||||
C198-A0 1F 152 ( 2) NOTSTART LDY #31 Try to detect the much shorter
|
||||
C19A-20 BF C1 153 ( 6) JSR CMPLEVEL start bit
|
||||
C19D-B0 F9 154 (2**) BCS NOTSTART Start bit not detected yet!
|
||||
C19F- 155
|
||||
C19F-20 BF C1 156 ( 6) JSR CMPLEVEL Wait for 2nd phase of start bit
|
||||
C1A2- 157
|
||||
C1A2-A0 3A 158 ( 2) LDY #58 Set threshold value in middle
|
||||
C1A4-A2 08 159 ( 2) RDBYTE LDX #8 Receiver 8 bits
|
||||
C1A6-48 160 ( 3) RDBIT PHA
|
||||
C1A7-20 BC C1 161 ( 6) JSR FULLCYCLE Detect a full cycle
|
||||
C1AA-68 162 ( 4) PLA
|
||||
C1AB-2A 163 ( 2) ROL Roll new bit into result
|
||||
C1AC-A0 39 164 ( 2) LDY #57 Set threshold value in middle
|
||||
C1AE-CA 165 ( 2) DEX Decrement bit counter
|
||||
C1AF-D0 F5 166 (2**) BNE RDBIT Read next bit!
|
||||
C1B1-81 26 167 ( 6) STA (HEX2L,X) Save new byte
|
||||
C1B3- 168
|
||||
C1B3-20 F1 C1 169 ( 6) JSR INCADDR Increment address
|
||||
C1B6-A0 35 170 ( 2) LDY #53 Compensate threshold with workload
|
||||
C1B8-90 EA 171 (2**) BCC RDBYTE Do next byte if not done yet!
|
||||
C1BA-B0 CD 172 (2**) BCS RESTIDX Always taken! Restore parse index
|
||||
C1BC- 173
|
||||
C1BC-20 BF C1 174 ( 6) FULLCYCLE JSR CMPLEVEL Wait for two level changes
|
||||
C1BF-88 175 ( 2) CMPLEVEL DEY Decrement time counter
|
||||
C1C0-AD 81 C0 176 ( 4) LDA TAPEIN Get Tape In data
|
||||
C1C3-C5 29 177 ( 3) CMP LASTSTATE Same as before?
|
||||
C1C5-F0 F8 178 (2**) BEQ CMPLEVEL Yes!
|
||||
C1C7-85 29 179 ( 2) STA LASTSTATE Save new data
|
||||
C1C9- 180
|
||||
C1C9-C0 80 181 ( 2) CPY #128 Compare threshold
|
||||
C1CB-60 182 ( 6) RTS
|
||||
C1CC- 183
|
||||
C1CC- 184 ;-------------------------------------------------------------------------
|
||||
C1CC- 185 ; Write header to tape
|
||||
C1CC- 186 ;
|
||||
C1CC- 187 ; The header consists of an asymmetric cycle, starting with one phase of
|
||||
C1CC- 188 ; approximately (66+47)x5=565us, followed by a second phase of
|
||||
C1CC- 189 ; approximately (44+47)x5=455us.
|
||||
C1CC- 190 ; Total cycle duration is approximately 1020us ~ 1kHz. The actual
|
||||
C1CC- 191 ; frequencywill be a bit lower because of the additional workload between
|
||||
C1CC- 192 ; the twoloops.
|
||||
C1CC- 193 ; The header ends with a short phase of (30+47)x5=385us and a normal
|
||||
C1CC- 194 ; phase of (44+47)x5=455us. This start bit must be detected by the read
|
||||
C1CC- 195 ; routine to trigger the reading of the actual data.
|
||||
C1CC- 196 ;-------------------------------------------------------------------------
|
||||
C1CC- 197
|
||||
C1CC-86 28 198 ( 3) WHEADER STX SAVEINDEX Save index in input line
|
||||
C1CE-A0 42 199 ( 2) HCOUNT LDY #66 Extra long delay
|
||||
C1D0-20 E0 C1 200 ( 6) JSR WDELAY CY is constantly 1, writing a 1
|
||||
C1D3-D0 F9 201 (2**) BNE HCOUNT Do this 64 * 256 time!
|
||||
C1D5-69 FE 202 ( 2) ADC #-2 Decrement A (CY=1 all the time)
|
||||
C1D7-B0 F5 203 (2**) BCS HCOUNT Not all done!
|
||||
C1D9-A0 1E 204 ( 2) LDY #30 Write a final short bit (start)
|
||||
C1DB- 205
|
||||
C1DB- 206 ;-------------------------------------------------------------------------
|
||||
C1DB- 207 ; Write a full bit cycle
|
||||
C1DB- 208 ;
|
||||
C1DB- 209 ; Upon entry Y contains a compensated value for the first phase of 0
|
||||
C1DB- 210 ; bit length. All subsequent loops don't have to be time compensated.
|
||||
C1DB- 211 ;-------------------------------------------------------------------------
|
||||
C1DB- 212
|
||||
C1DB-20 E0 C1 213 ( 6) WRITEBIT JSR WDELAY Do two equal phases
|
||||
C1DE-A0 2C 214 ( 2) LDY #44 Load 250us counter - compensation
|
||||
C1E0- 215
|
||||
C1E0-88 216 ( 2) WDELAY DEY Delay 250us (one phase of 2kHz)
|
||||
C1E1-D0 FD 217 (2**) BNE WDELAY
|
||||
C1E3-90 05 218 (2**) BCC WRITE1 Write a '1' (2kHz)
|
||||
C1E5- 219
|
||||
C1E5-A0 2F 220 ( 2) LDY #47 Additional delay for '0' (1kHz)
|
||||
C1E7-88 221 ( 2) WDELAY0 DEY (delay 250us)
|
||||
C1E8-D0 FD 222 (2**) BNE WDELAY0
|
||||
C1EA- 223
|
||||
C1EA-BC 00 C0 224 ( 4*) WRITE1 LDY FLIP,X Flip the output bit
|
||||
C1ED-A0 29 225 ( 2) LDY #41 Reload 250us cntr (compensation)
|
||||
C1EF-CA 226 ( 2) DEX Decrement bit counter
|
||||
C1F0-60 227 ( 6) RTS
|
||||
C1F1- 228
|
||||
C1F1- 229 ;-------------------------------------------------------------------------
|
||||
C1F1- 230 ; Increment current address and compare with last address
|
||||
C1F1- 231 ;-------------------------------------------------------------------------
|
||||
C1F1- 232
|
||||
C1F1-A5 26 233 ( 3) INCADDR LDA HEX2L Compare current address with
|
||||
C1F3-C5 24 234 ( 3) CMP HEX1L end address
|
||||
C1F5-A5 27 235 ( 3) LDA HEX2H
|
||||
C1F7-E5 25 236 ( 3) SBC HEX1H
|
||||
C1F9-E6 26 237 ( 5) INC HEX2L And increment current address
|
||||
C1FB-D0 02 238 (2**) BNE NOCARRY No carry to MSB!
|
||||
C1FD-E6 27 239 ( 5) INC HEX2H
|
||||
C1FF-60 240 ( 6) NOCARRY RTS
|
||||
C200- 241
|
||||
C200- 242 ;-------------------------------------------------------------------------
|
||||
C200- 243
|
38
software/firmware/WozMon/wozaci.txt
Normal file
38
software/firmware/WozMon/wozaci.txt
Normal file
@ -0,0 +1,38 @@
|
||||
C100:A9 AA 20 EF FF A9 8D 20
|
||||
C108:EF FF A0 FF C8 AD 11 D0
|
||||
C110:10 FB AD 10 D0 99 00 02
|
||||
C118:20 EF FF C9 9B F0 E1 C9
|
||||
C120:8D D0 E9 A2 FF A9 00 85
|
||||
C128:24 85 25 85 26 85 27 E8
|
||||
C130:BD 00 02 C9 D2 F0 56 C9
|
||||
C138:D7 F0 35 C9 AE F0 27 C9
|
||||
C140:8D F0 20 C9 A0 F0 E8 49
|
||||
C148:B0 C9 0A 90 06 69 88 C9
|
||||
C150:FA 90 AD 0A 0A 0A 0A A0
|
||||
C158:04 0A 26 24 26 25 88 D0
|
||||
C160:F8 F0 CC 4C 1A FF A5 24
|
||||
C168:85 26 A5 25 85 27 B0 BF
|
||||
C170:A9 40 20 CC C1 88 A2 00
|
||||
C178:A1 26 A2 10 0A 20 DB C1
|
||||
C180:D0 FA 20 F1 C1 A0 1E 90
|
||||
C188:EC A6 28 B0 98 20 BC C1
|
||||
C190:A9 16 20 CC C1 20 BC C1
|
||||
C198:A0 1F 20 BF C1 B0 F9 20
|
||||
C1A0:BF C1 A0 3A A2 08 48 20
|
||||
C1A8:BC C1 68 2A A0 39 CA D0
|
||||
C1B0:F5 81 26 20 F1 C1 A0 35
|
||||
C1B8:90 EA B0 CD 20 BF C1 88
|
||||
C1C0:AD 81 C0 C5 29 F0 F8 85
|
||||
C1C8:29 C0 80 60 86 28 A0 42
|
||||
C1D0:20 E0 C1 D0 F9 69 FE B0
|
||||
C1D8:F5 A0 1E 20 E0 C1 A0 2C
|
||||
C1E0:88 D0 FD 90 05 A0 2F 88
|
||||
C1E8:D0 FD BC 00 C0 A0 29 CA
|
||||
C1F0:60 A5 26 C5 24 A5 27 E5
|
||||
C1F8:25 E6 26 D0 02 E6 27 60
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
255
software/firmware/WozMon/wozmon.asm
Normal file
255
software/firmware/WozMon/wozmon.asm
Normal file
@ -0,0 +1,255 @@
|
||||
.CR 6502
|
||||
.TF wozmon.hex,HEX,8
|
||||
.LF wozmon.list
|
||||
;-------------------------------------------------------------------------
|
||||
;
|
||||
; The WOZ Monitor for the Apple 1
|
||||
; Written by Steve Wozniak 1976
|
||||
;
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Memory declaration
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
XAML .EQ $24 Last "opened" location Low
|
||||
XAMH .EQ $25 Last "opened" location High
|
||||
STL .EQ $26 Store address Low
|
||||
STH .EQ $27 Store address High
|
||||
L .EQ $28 Hex value parsing Low
|
||||
H .EQ $29 Hex value parsing High
|
||||
YSAV .EQ $2A Used to see if hex value is given
|
||||
MODE .EQ $2B $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
||||
|
||||
IN .EQ $0200,$027F Input buffer
|
||||
|
||||
KBD .EQ $D010 PIA.A keyboard input
|
||||
KBDCR .EQ $D011 PIA.A keyboard control register
|
||||
DSP .EQ $D012 PIA.B display output register
|
||||
DSPCR .EQ $D013 PIA.B display control register
|
||||
|
||||
; KBD b7..b0 are inputs, b6..b0 is ASCII input, b7 is constant high
|
||||
; Programmed to respond to low to high KBD strobe
|
||||
; DSP b6..b0 are outputs, b7 is input
|
||||
; CB2 goes low when data is written, returns high when CB1 goes high
|
||||
; Interrupts are enabled, though not used. KBD can be jumpered to IRQ,
|
||||
; whereas DSP can be jumpered to NMI.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Constants
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
BS .EQ $DF Backspace key, arrow left key
|
||||
CR .EQ $8D Carriage Return
|
||||
ESC .EQ $9B ESC key
|
||||
PROMPT .EQ "\" Prompt character
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Let's get started
|
||||
;
|
||||
; Remark the RESET routine is only to be entered by asserting the RESET
|
||||
; line of the system. This ensures that the data direction registers
|
||||
; are selected.
|
||||
;-------------------------------------------------------------------------
|
||||
.OR $FF00
|
||||
RESET CLD Clear decimal arithmetic mode
|
||||
CLI
|
||||
LDY #%0111.1111 Mask for DSP data direction reg
|
||||
STY DSP (DDR mode is assumed after reset)
|
||||
LDA #%1010.0111 KBD and DSP control register mask
|
||||
STA KBDCR Enable interrupts, set CA1, CB1 for
|
||||
STA DSPCR positive edge sense/output mode.
|
||||
|
||||
; Program falls through to the GETLINE routine to save some program bytes
|
||||
; Please note that Y still holds $7F, which will cause an automatic Escape
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; The GETLINE process
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTCR CMP #BS Backspace key?
|
||||
BEQ BACKSPACE Yes
|
||||
CMP #ESC ESC?
|
||||
BEQ ESCAPE Yes
|
||||
INY Advance text index
|
||||
BPL NEXTCHAR Auto ESC if line longer than 127
|
||||
|
||||
ESCAPE LDA #PROMPT Print prompt character
|
||||
JSR ECHO Output it.
|
||||
|
||||
GETLINE LDA #CR Send CR
|
||||
JSR ECHO
|
||||
|
||||
LDY #0+1 Start a new input line
|
||||
BACKSPACE DEY Backup text index
|
||||
BMI GETLINE Oops, line's empty, reinitialize
|
||||
|
||||
NEXTCHAR LDA KBDCR Wait for key press
|
||||
BPL NEXTCHAR No key yet!
|
||||
LDA KBD Load character. B7 should be '1'
|
||||
STA IN,Y Add to text buffer
|
||||
JSR ECHO Display character
|
||||
CMP #CR
|
||||
BNE NOTCR It's not CR!
|
||||
|
||||
; Line received, now let's parse it
|
||||
|
||||
LDY #-1 Reset text index
|
||||
LDA #0 Default mode is XAM
|
||||
TAX X=0
|
||||
|
||||
SETSTOR ASL Leaves $7B if setting STOR mode
|
||||
|
||||
SETMODE STA MODE Set mode flags
|
||||
|
||||
BLSKIP INY Advance text index
|
||||
|
||||
NEXTITEM LDA IN,Y Get character
|
||||
CMP #CR
|
||||
BEQ GETLINE We're done if it's CR!
|
||||
CMP #"."
|
||||
BCC BLSKIP Ignore everything below "."!
|
||||
BEQ SETMODE Set BLOCK XAM mode ("." = $AE)
|
||||
CMP #":"
|
||||
BEQ SETSTOR Set STOR mode! $BA will become $7B
|
||||
CMP #"R"
|
||||
BEQ RUN Run the program! Forget the rest
|
||||
STX L Clear input value (X=0)
|
||||
STX H
|
||||
STY YSAV Save Y for comparison
|
||||
|
||||
; Here we're trying to parse a new hex value
|
||||
|
||||
NEXTHEX LDA IN,Y Get character for hex test
|
||||
EOR #$B0 Map digits to 0-9
|
||||
CMP #9+1 Is it a decimal 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 #4 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
|
||||
|
||||
NOTHEX CPY YSAV Was at least 1 hex digit given?
|
||||
BEQ ESCAPE No! Ignore all, start from scratch
|
||||
|
||||
BIT MODE Test MODE byte
|
||||
BVC NOTSTOR B6=0 is STOR, 1 is XAM or BLOCK XAM
|
||||
|
||||
; STOR mode, save LSD of new hex byte
|
||||
|
||||
LDA L LSD's of hex data
|
||||
STA (STL,X) Store current 'store index'(X=0)
|
||||
INC STL Increment store index.
|
||||
BNE NEXTITEM No carry!
|
||||
INC STH Add carry to 'store index' high
|
||||
TONEXTITEM JMP NEXTITEM Get next command item.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; RUN user's program from last opened location
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
RUN JMP (XAML) Run user's program
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; We're not in Store mode
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
NOTSTOR BMI XAMNEXT B7 = 0 for XAM, 1 for BLOCK XAM
|
||||
|
||||
; We're in XAM mode now
|
||||
|
||||
LDX #2 Copy 2 bytes
|
||||
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
|
||||
|
||||
; Print address and data from this address, fall through next BNE.
|
||||
|
||||
NXTPRNT BNE PRDATA NE means no address to print
|
||||
LDA #CR Print CR first
|
||||
JSR ECHO
|
||||
LDA XAMH Output high-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA XAML Output low-order byte of address
|
||||
JSR PRBYTE
|
||||
LDA #":" Print colon
|
||||
JSR ECHO
|
||||
|
||||
PRDATA LDA #" " Print space
|
||||
JSR ECHO
|
||||
LDA (XAML,X) Get data from address (X=0)
|
||||
JSR PRBYTE Output it in hex format
|
||||
XAMNEXT STX MODE 0 -> MODE (XAM mode).
|
||||
LDA XAML See if there's more to print
|
||||
CMP L
|
||||
LDA XAMH
|
||||
SBC H
|
||||
BCS TONEXTITEM Not less! No more data to output
|
||||
|
||||
INC XAML Increment 'examine index'
|
||||
BNE MOD8CHK No carry!
|
||||
INC XAMH
|
||||
|
||||
MOD8CHK LDA XAML If address MOD 8 = 0 start new line
|
||||
AND #%0000.0111
|
||||
BPL NXTPRNT Always taken.
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a byte in A in hex form (destructive)
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRBYTE PHA Save A for LSD
|
||||
LSR
|
||||
LSR
|
||||
LSR MSD to LSD position
|
||||
LSR
|
||||
JSR PRHEX Output hex digit
|
||||
PLA Restore A
|
||||
|
||||
; Fall through to print hex routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a hexadecimal digit
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
PRHEX AND #%0000.1111 Mask LSD for hex print
|
||||
ORA #"0" Add "0"
|
||||
CMP #"9"+1 Is it a decimal digit?
|
||||
BCC ECHO Yes! output it
|
||||
ADC #6 Add offset for letter A-F
|
||||
|
||||
; Fall through to print routine
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Subroutine to print a character to the terminal
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
ECHO BIT DSP DA bit (B7) cleared yet?
|
||||
BMI ECHO No! Wait for display ready
|
||||
STA DSP Output character. Sets DA
|
||||
RTS
|
||||
|
||||
;-------------------------------------------------------------------------
|
||||
; Vector area
|
||||
;-------------------------------------------------------------------------
|
||||
|
||||
.DA $0000 Unused, what a pity
|
||||
NMI_VEC .DA $0F00 NMI vector
|
||||
RESET_VEC .DA RESET RESET vector
|
||||
IRQ_VEC .DA $0000 IRQ vector
|
32
software/firmware/WozMon/wozmon.hex
Normal file
32
software/firmware/WozMon/wozmon.hex
Normal file
@ -0,0 +1,32 @@
|
||||
D858A07F8C12D0A9
|
||||
A78D11D08D13D0C9
|
||||
DFF013C99BF003C8
|
||||
100FA9DC20EFFFA9
|
||||
8D20EFFFA0018830
|
||||
F6AD11D010FBAD10
|
||||
D099000220EFFFC9
|
||||
8DD0D4A0FFA900AA
|
||||
0A852BC8B90002C9
|
||||
8DF0D4C9AE90F4F0
|
||||
F0C9BAF0EBC9D2F0
|
||||
3B86288629842AB9
|
||||
000249B0C90A9006
|
||||
6988C9FA90110A0A
|
||||
0A0AA2040A262826
|
||||
29CAD0F8C8D0E0C4
|
||||
2AF097242B5010A5
|
||||
288126E626D0B5E6
|
||||
274C44FF6C240030
|
||||
2BA202B527952595
|
||||
23CAD0F7D014A98D
|
||||
20EFFFA52520DCFF
|
||||
A52420DCFFA9BA20
|
||||
EFFFA9A020EFFFA1
|
||||
2420DCFF862BA524
|
||||
C528A525E529B0C1
|
||||
E624D002E625A524
|
||||
290710C8484A4A4A
|
||||
4A20E5FF68290F09
|
||||
B0C9BA900269062C
|
||||
12D030FB8D12D060
|
||||
0000000F00FF0000
|
252
software/firmware/WozMon/wozmon.list
Normal file
252
software/firmware/WozMon/wozmon.list
Normal file
@ -0,0 +1,252 @@
|
||||
0000- 4 ;-------------------------------------------------------------------------
|
||||
0000- 5 ;
|
||||
0000- 6 ; The WOZ Monitor for the Apple 1
|
||||
0000- 7 ; Written by Steve Wozniak 1976
|
||||
0000- 8 ;
|
||||
0000- 9 ;-------------------------------------------------------------------------
|
||||
0000- 10
|
||||
0000- 11
|
||||
0000- 12 ;-------------------------------------------------------------------------
|
||||
0000- 13 ; Memory declaration
|
||||
0000- 14 ;-------------------------------------------------------------------------
|
||||
0000- 15
|
||||
0024- 16 XAML .EQ $24 Last "opened" location Low
|
||||
0025- 17 XAMH .EQ $25 Last "opened" location High
|
||||
0026- 18 STL .EQ $26 Store address Low
|
||||
0027- 19 STH .EQ $27 Store address High
|
||||
0028- 20 L .EQ $28 Hex value parsing Low
|
||||
0029- 21 H .EQ $29 Hex value parsing High
|
||||
002A- 22 YSAV .EQ $2A Used to see if hex value is given
|
||||
002B- 23 MODE .EQ $2B $00=XAM, $7F=STOR, $AE=BLOCK XAM
|
||||
0000- 24
|
||||
0200- 25 IN .EQ $0200,$027F Input buffer
|
||||
0000- 26
|
||||
D010- 27 KBD .EQ $D010 PIA.A keyboard input
|
||||
D011- 28 KBDCR .EQ $D011 PIA.A keyboard control register
|
||||
D012- 29 DSP .EQ $D012 PIA.B display output register
|
||||
D013- 30 DSPCR .EQ $D013 PIA.B display control register
|
||||
0000- 31
|
||||
0000- 32 ; KBD b7..b0 are inputs, b6..b0 is ASCII input, b7 is constant high
|
||||
0000- 33 ; Programmed to respond to low to high KBD strobe
|
||||
0000- 34 ; DSP b6..b0 are outputs, b7 is input
|
||||
0000- 35 ; CB2 goes low when data is written, returns high when CB1 goes high
|
||||
0000- 36 ; Interrupts are enabled, though not used. KBD can be jumpered to IRQ,
|
||||
0000- 37 ; whereas DSP can be jumpered to NMI.
|
||||
0000- 38
|
||||
0000- 39 ;-------------------------------------------------------------------------
|
||||
0000- 40 ; Constants
|
||||
0000- 41 ;-------------------------------------------------------------------------
|
||||
0000- 42
|
||||
00DF- 43 BS .EQ $DF Backspace key, arrow left key
|
||||
008D- 44 CR .EQ $8D Carriage Return
|
||||
009B- 45 ESC .EQ $9B ESC key
|
||||
00DC- 46 PROMPT .EQ "\" Prompt character
|
||||
0000- 47
|
||||
0000- 48 ;-------------------------------------------------------------------------
|
||||
0000- 49 ; Let's get started
|
||||
0000- 50 ;
|
||||
0000- 51 ; Remark the RESET routine is only to be entered by asserting the RESET
|
||||
0000- 52 ; line of the system. This ensures that the data direction registers
|
||||
0000- 53 ; are selected.
|
||||
0000- 54 ;-------------------------------------------------------------------------
|
||||
FF00- 55 .OR $FF00
|
||||
FF00-D8 56 ( 2) RESET CLD Clear decimal arithmetic mode
|
||||
FF01-58 57 ( 2) CLI
|
||||
FF02-A0 7F 58 ( 2) LDY #%0111.1111 Mask for DSP data direction reg
|
||||
FF04-8C 12 D0 59 ( 4) STY DSP (DDR mode is assumed after reset)
|
||||
FF07-A9 A7 60 ( 2) LDA #%1010.0111 KBD and DSP control register mask
|
||||
FF09-8D 11 D0 61 ( 4) STA KBDCR Enable interrupts, set CA1, CB1 for
|
||||
FF0C-8D 13 D0 62 ( 4) STA DSPCR positive edge sense/output mode.
|
||||
FF0F- 63
|
||||
FF0F- 64 ; Program falls through to the GETLINE routine to save some program bytes
|
||||
FF0F- 65 ; Please note that Y still holds $7F, which will cause an automatic Escape
|
||||
FF0F- 66
|
||||
FF0F- 67 ;-------------------------------------------------------------------------
|
||||
FF0F- 68 ; The GETLINE process
|
||||
FF0F- 69 ;-------------------------------------------------------------------------
|
||||
FF0F- 70
|
||||
FF0F-C9 DF 71 ( 2) NOTCR CMP #BS Backspace key?
|
||||
FF11-F0 13 72 (2**) BEQ BACKSPACE Yes
|
||||
FF13-C9 9B 73 ( 2) CMP #ESC ESC?
|
||||
FF15-F0 03 74 (2**) BEQ ESCAPE Yes
|
||||
FF17-C8 75 ( 2) INY Advance text index
|
||||
FF18-10 0F 76 (2**) BPL NEXTCHAR Auto ESC if line longer than 127
|
||||
FF1A- 77
|
||||
FF1A-A9 DC 78 ( 2) ESCAPE LDA #PROMPT Print prompt character
|
||||
FF1C-20 EF FF 79 ( 6) JSR ECHO Output it.
|
||||
FF1F- 80
|
||||
FF1F-A9 8D 81 ( 2) GETLINE LDA #CR Send CR
|
||||
FF21-20 EF FF 82 ( 6) JSR ECHO
|
||||
FF24- 83
|
||||
FF24-A0 01 84 ( 2) LDY #0+1 Start a new input line
|
||||
FF26-88 85 ( 2) BACKSPACE DEY Backup text index
|
||||
FF27-30 F6 86 (2**) BMI GETLINE Oops, line's empty, reinitialize
|
||||
FF29- 87
|
||||
FF29-AD 11 D0 88 ( 4) NEXTCHAR LDA KBDCR Wait for key press
|
||||
FF2C-10 FB 89 (2**) BPL NEXTCHAR No key yet!
|
||||
FF2E-AD 10 D0 90 ( 4) LDA KBD Load character. B7 should be '1'
|
||||
FF31-99 00 02 91 ( 5) STA IN,Y Add to text buffer
|
||||
FF34-20 EF FF 92 ( 6) JSR ECHO Display character
|
||||
FF37-C9 8D 93 ( 2) CMP #CR
|
||||
FF39-D0 D4 94 (2**) BNE NOTCR It's not CR!
|
||||
FF3B- 95
|
||||
FF3B- 96 ; Line received, now let's parse it
|
||||
FF3B- 97
|
||||
FF3B-A0 FF 98 ( 2) LDY #-1 Reset text index
|
||||
FF3D-A9 00 99 ( 2) LDA #0 Default mode is XAM
|
||||
FF3F-AA 100 ( 2) TAX X=0
|
||||
FF40- 101
|
||||
FF40-0A 102 ( 2) SETSTOR ASL Leaves $7B if setting STOR mode
|
||||
FF41- 103
|
||||
FF41-85 2B 104 ( 2) SETMODE STA MODE Set mode flags
|
||||
FF43- 105
|
||||
FF43-C8 106 ( 2) BLSKIP INY Advance text index
|
||||
FF44- 107
|
||||
FF44-B9 00 02 108 ( 4*) NEXTITEM LDA IN,Y Get character
|
||||
FF47-C9 8D 109 ( 2) CMP #CR
|
||||
FF49-F0 D4 110 (2**) BEQ GETLINE We're done if it's CR!
|
||||
FF4B-C9 AE 111 ( 2) CMP #"."
|
||||
FF4D-90 F4 112 (2**) BCC BLSKIP Ignore everything below "."!
|
||||
FF4F-F0 F0 113 (2**) BEQ SETMODE Set BLOCK XAM mode ("." = $AE)
|
||||
FF51-C9 BA 114 ( 2) CMP #":"
|
||||
FF53-F0 EB 115 (2**) BEQ SETSTOR Set STOR mode! $BA will become $7B
|
||||
FF55-C9 D2 116 ( 2) CMP #"R"
|
||||
FF57-F0 3B 117 (2**) BEQ RUN Run the program! Forget the rest
|
||||
FF59-86 28 118 ( 3) STX L Clear input value (X=0)
|
||||
FF5B-86 29 119 ( 3) STX H
|
||||
FF5D-84 2A 120 ( 3) STY YSAV Save Y for comparison
|
||||
FF5F- 121
|
||||
FF5F- 122 ; Here we're trying to parse a new hex value
|
||||
FF5F- 123
|
||||
FF5F-B9 00 02 124 ( 4*) NEXTHEX LDA IN,Y Get character for hex test
|
||||
FF62-49 B0 125 ( 2) EOR #$B0 Map digits to 0-9
|
||||
FF64-C9 0A 126 ( 2) CMP #9+1 Is it a decimal digit?
|
||||
FF66-90 06 127 (2**) BCC DIG Yes!
|
||||
FF68-69 88 128 ( 2) ADC #$88 Map letter "A"-"F" to $FA-FF
|
||||
FF6A-C9 FA 129 ( 2) CMP #$FA Hex letter?
|
||||
FF6C-90 11 130 (2**) BCC NOTHEX No! Character not hex
|
||||
FF6E- 131
|
||||
FF6E-0A 132 ( 2) DIG ASL
|
||||
FF6F-0A 133 ( 2) ASL Hex digit to MSD of A
|
||||
FF70-0A 134 ( 2) ASL
|
||||
FF71-0A 135 ( 2) ASL
|
||||
FF72- 136
|
||||
FF72-A2 04 137 ( 2) LDX #4 Shift count
|
||||
FF74-0A 138 ( 2) HEXSHIFT ASL Hex digit left, MSB to carry
|
||||
FF75-26 28 139 ( 5) ROL L Rotate into LSD
|
||||
FF77-26 29 140 ( 5) ROL H Rotate into MSD's
|
||||
FF79-CA 141 ( 2) DEX Done 4 shifts?
|
||||
FF7A-D0 F8 142 (2**) BNE HEXSHIFT No, loop
|
||||
FF7C-C8 143 ( 2) INY Advance text index
|
||||
FF7D-D0 E0 144 (2**) BNE NEXTHEX Always taken
|
||||
FF7F- 145
|
||||
FF7F-C4 2A 146 ( 3) NOTHEX CPY YSAV Was at least 1 hex digit given?
|
||||
FF81-F0 97 147 (2**) BEQ ESCAPE No! Ignore all, start from scratch
|
||||
FF83- 148
|
||||
FF83-24 2B 149 ( 3) BIT MODE Test MODE byte
|
||||
FF85-50 10 150 (2**) BVC NOTSTOR B6=0 is STOR, 1 is XAM or BLOCK XAM
|
||||
FF87- 151
|
||||
FF87- 152 ; STOR mode, save LSD of new hex byte
|
||||
FF87- 153
|
||||
FF87-A5 28 154 ( 3) LDA L LSD's of hex data
|
||||
FF89-81 26 155 ( 6) STA (STL,X) Store current 'store index'(X=0)
|
||||
FF8B-E6 26 156 ( 5) INC STL Increment store index.
|
||||
FF8D-D0 B5 157 (2**) BNE NEXTITEM No carry!
|
||||
FF8F-E6 27 158 ( 5) INC STH Add carry to 'store index' high
|
||||
FF91-4C 44 FF 159 ( 3) TONEXTITEM JMP NEXTITEM Get next command item.
|
||||
FF94- 160
|
||||
FF94- 161 ;-------------------------------------------------------------------------
|
||||
FF94- 162 ; RUN user's program from last opened location
|
||||
FF94- 163 ;-------------------------------------------------------------------------
|
||||
FF94- 164
|
||||
FF94-6C 24 00 165 ( 5) RUN JMP (XAML) Run user's program
|
||||
FF97- 166
|
||||
FF97- 167 ;-------------------------------------------------------------------------
|
||||
FF97- 168 ; We're not in Store mode
|
||||
FF97- 169 ;-------------------------------------------------------------------------
|
||||
FF97- 170
|
||||
FF97-30 2B 171 (2**) NOTSTOR BMI XAMNEXT B7 = 0 for XAM, 1 for BLOCK XAM
|
||||
FF99- 172
|
||||
FF99- 173 ; We're in XAM mode now
|
||||
FF99- 174
|
||||
FF99-A2 02 175 ( 2) LDX #2 Copy 2 bytes
|
||||
FF9B-B5 27 176 ( 4) SETADR LDA L-1,X Copy hex data to
|
||||
FF9D-95 25 177 ( 4) STA STL-1,X 'store index'
|
||||
FF9F-95 23 178 ( 4) STA XAML-1,X and to 'XAM index'
|
||||
FFA1-CA 179 ( 2) DEX Next of 2 bytes
|
||||
FFA2-D0 F7 180 (2**) BNE SETADR Loop unless X = 0
|
||||
FFA4- 181
|
||||
FFA4- 182 ; Print address and data from this address, fall through next BNE.
|
||||
FFA4- 183
|
||||
FFA4-D0 14 184 (2**) NXTPRNT BNE PRDATA NE means no address to print
|
||||
FFA6-A9 8D 185 ( 2) LDA #CR Print CR first
|
||||
FFA8-20 EF FF 186 ( 6) JSR ECHO
|
||||
FFAB-A5 25 187 ( 3) LDA XAMH Output high-order byte of address
|
||||
FFAD-20 DC FF 188 ( 6) JSR PRBYTE
|
||||
FFB0-A5 24 189 ( 3) LDA XAML Output low-order byte of address
|
||||
FFB2-20 DC FF 190 ( 6) JSR PRBYTE
|
||||
FFB5-A9 BA 191 ( 2) LDA #":" Print colon
|
||||
FFB7-20 EF FF 192 ( 6) JSR ECHO
|
||||
FFBA- 193
|
||||
FFBA-A9 A0 194 ( 2) PRDATA LDA #" " Print space
|
||||
FFBC-20 EF FF 195 ( 6) JSR ECHO
|
||||
FFBF-A1 24 196 ( 6) LDA (XAML,X) Get data from address (X=0)
|
||||
FFC1-20 DC FF 197 ( 6) JSR PRBYTE Output it in hex format
|
||||
FFC4-86 2B 198 ( 3) XAMNEXT STX MODE 0 -> MODE (XAM mode).
|
||||
FFC6-A5 24 199 ( 3) LDA XAML See if there's more to print
|
||||
FFC8-C5 28 200 ( 3) CMP L
|
||||
FFCA-A5 25 201 ( 3) LDA XAMH
|
||||
FFCC-E5 29 202 ( 3) SBC H
|
||||
FFCE-B0 C1 203 (2**) BCS TONEXTITEM Not less! No more data to output
|
||||
FFD0- 204
|
||||
FFD0-E6 24 205 ( 5) INC XAML Increment 'examine index'
|
||||
FFD2-D0 02 206 (2**) BNE MOD8CHK No carry!
|
||||
FFD4-E6 25 207 ( 5) INC XAMH
|
||||
FFD6- 208
|
||||
FFD6-A5 24 209 ( 3) MOD8CHK LDA XAML If address MOD 8 = 0 start new line
|
||||
FFD8-29 07 210 ( 2) AND #%0000.0111
|
||||
FFDA-10 C8 211 (2**) BPL NXTPRNT Always taken.
|
||||
FFDC- 212
|
||||
FFDC- 213 ;-------------------------------------------------------------------------
|
||||
FFDC- 214 ; Subroutine to print a byte in A in hex form (destructive)
|
||||
FFDC- 215 ;-------------------------------------------------------------------------
|
||||
FFDC- 216
|
||||
FFDC-48 217 ( 3) PRBYTE PHA Save A for LSD
|
||||
FFDD-4A 218 ( 2) LSR
|
||||
FFDE-4A 219 ( 2) LSR
|
||||
FFDF-4A 220 ( 2) LSR MSD to LSD position
|
||||
FFE0-4A 221 ( 2) LSR
|
||||
FFE1-20 E5 FF 222 ( 6) JSR PRHEX Output hex digit
|
||||
FFE4-68 223 ( 4) PLA Restore A
|
||||
FFE5- 224
|
||||
FFE5- 225 ; Fall through to print hex routine
|
||||
FFE5- 226
|
||||
FFE5- 227 ;-------------------------------------------------------------------------
|
||||
FFE5- 228 ; Subroutine to print a hexadecimal digit
|
||||
FFE5- 229 ;-------------------------------------------------------------------------
|
||||
FFE5- 230
|
||||
FFE5-29 0F 231 ( 2) PRHEX AND #%0000.1111 Mask LSD for hex print
|
||||
FFE7-09 B0 232 ( 2) ORA #"0" Add "0"
|
||||
FFE9-C9 BA 233 ( 2) CMP #"9"+1 Is it a decimal digit?
|
||||
FFEB-90 02 234 (2**) BCC ECHO Yes! output it
|
||||
FFED-69 06 235 ( 2) ADC #6 Add offset for letter A-F
|
||||
FFEF- 236
|
||||
FFEF- 237 ; Fall through to print routine
|
||||
FFEF- 238
|
||||
FFEF- 239 ;-------------------------------------------------------------------------
|
||||
FFEF- 240 ; Subroutine to print a character to the terminal
|
||||
FFEF- 241 ;-------------------------------------------------------------------------
|
||||
FFEF- 242
|
||||
FFEF-2C 12 D0 243 ( 4) ECHO BIT DSP DA bit (B7) cleared yet?
|
||||
FFF2-30 FB 244 (2**) BMI ECHO No! Wait for display ready
|
||||
FFF4-8D 12 D0 245 ( 4) STA DSP Output character. Sets DA
|
||||
FFF7-60 246 ( 6) RTS
|
||||
FFF8- 247
|
||||
FFF8- 248 ;-------------------------------------------------------------------------
|
||||
FFF8- 249 ; Vector area
|
||||
FFF8- 250 ;-------------------------------------------------------------------------
|
||||
FFF8- 251
|
||||
FFF8-00 00 252 .DA $0000 Unused, what a pity
|
||||
FFFA-00 0F 253 NMI_VEC .DA $0F00 NMI vector
|
||||
FFFC-00 FF 254 RESET_VEC .DA RESET RESET vector
|
||||
FFFE-00 00 255 IRQ_VEC .DA $0000 IRQ vector
|
32
software/firmware/WozMon/wozmon.txt
Normal file
32
software/firmware/WozMon/wozmon.txt
Normal file
@ -0,0 +1,32 @@
|
||||
FF00: D8 58 A0 7F 8C 12 D0 A9
|
||||
FF08: A7 8D 11 D0 8D 13 D0 C9
|
||||
FF10: DF F0 13 C9 9B F0 03 C8
|
||||
FF18: 10 0F A9 DC 20 EF FF A9
|
||||
FF20: 8D 20 EF FF A0 01 88 30
|
||||
FF28: F6 AD 11 D0 10 FB AD 10
|
||||
FF30: D0 99 00 02 20 EF FF C9
|
||||
FF38: 8D D0 D4 A0 FF A9 00 AA
|
||||
FF40: 0A 85 2B C8 B9 00 02 C9
|
||||
FF48: 8D F0 D4 C9 AE 90 F4 F0
|
||||
FF50: F0 C9 BA F0 EB C9 D2 F0
|
||||
FF58: 3B 86 28 86 29 84 2A B9
|
||||
FF60: 00 02 49 B0 C9 0A 90 06
|
||||
FF68: 69 88 C9 FA 90 11 0A 0A
|
||||
FF70: 0A 0A A2 04 0A 26 28 26
|
||||
FF78: 29 CA D0 F8 C8 D0 E0 C4
|
||||
FF80: 2A F0 97 24 2B 50 10 A5
|
||||
FF88: 28 81 26 E6 26 D0 B5 E6
|
||||
FF90: 27 4C 44 FF 6C 24 00 30
|
||||
FF98: 2B A2 02 B5 27 95 25 95
|
||||
FFA0: 23 CA D0 F7 D0 14 A9 8D
|
||||
FFA8: 20 EF FF A5 25 20 DC FF
|
||||
FFB0: A5 24 20 DC FF A9 BA 20
|
||||
FFB8: EF FF A9 A0 20 EF FF A1
|
||||
FFC0: 24 20 DC FF 86 2B A5 24
|
||||
FFC8: C5 28 A5 25 E5 29 B0 C1
|
||||
FFD0: E6 24 D0 02 E6 25 A5 24
|
||||
FFD8: 29 07 10 C8 48 4A 4A 4A
|
||||
FFE0: 4A 20 E5 FF 68 29 0F 09
|
||||
FFE8: B0 C9 BA 90 02 69 06 2C
|
||||
FFF0: 12 D0 30 FB 8D 12 D0 60
|
||||
FFF8: 00 00 00 0F 00 FF 00 00
|
Loading…
Reference in New Issue
Block a user