From 87cdd5d7828c61e8aaa03a3c1e49cf19e89e978e Mon Sep 17 00:00:00 2001 From: Tor-Eirik Bakke Lunde Date: Sat, 25 Jan 2020 17:07:42 +0100 Subject: [PATCH] wozmon source --- software/firmware/WozMon/README.md | 6 + software/firmware/WozMon/assemble.bat | 4 + software/firmware/WozMon/wozaci.asm | 245 +++++++++++++++++++++++++ software/firmware/WozMon/wozaci.hex | 32 ++++ software/firmware/WozMon/wozaci.list | 240 ++++++++++++++++++++++++ software/firmware/WozMon/wozaci.txt | 38 ++++ software/firmware/WozMon/wozmon.asm | 255 ++++++++++++++++++++++++++ software/firmware/WozMon/wozmon.hex | 32 ++++ software/firmware/WozMon/wozmon.list | 252 +++++++++++++++++++++++++ software/firmware/WozMon/wozmon.txt | 32 ++++ 10 files changed, 1136 insertions(+) create mode 100644 software/firmware/WozMon/README.md create mode 100644 software/firmware/WozMon/assemble.bat create mode 100644 software/firmware/WozMon/wozaci.asm create mode 100644 software/firmware/WozMon/wozaci.hex create mode 100644 software/firmware/WozMon/wozaci.list create mode 100644 software/firmware/WozMon/wozaci.txt create mode 100644 software/firmware/WozMon/wozmon.asm create mode 100644 software/firmware/WozMon/wozmon.hex create mode 100644 software/firmware/WozMon/wozmon.list create mode 100644 software/firmware/WozMon/wozmon.txt diff --git a/software/firmware/WozMon/README.md b/software/firmware/WozMon/README.md new file mode 100644 index 0000000..b7592f8 --- /dev/null +++ b/software/firmware/WozMon/README.md @@ -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. \ No newline at end of file diff --git a/software/firmware/WozMon/assemble.bat b/software/firmware/WozMon/assemble.bat new file mode 100644 index 0000000..cd6dba3 --- /dev/null +++ b/software/firmware/WozMon/assemble.bat @@ -0,0 +1,4 @@ +@echo off +sbasm.py wozaci.asm +sbasm.py wozmon.asm +pause \ No newline at end of file diff --git a/software/firmware/WozMon/wozaci.asm b/software/firmware/WozMon/wozaci.asm new file mode 100644 index 0000000..c71c56b --- /dev/null +++ b/software/firmware/WozMon/wozaci.asm @@ -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 + \ No newline at end of file diff --git a/software/firmware/WozMon/wozaci.hex b/software/firmware/WozMon/wozaci.hex new file mode 100644 index 0000000..e52c060 --- /dev/null +++ b/software/firmware/WozMon/wozaci.hex @@ -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 diff --git a/software/firmware/WozMon/wozaci.list b/software/firmware/WozMon/wozaci.list new file mode 100644 index 0000000..c3cde4f --- /dev/null +++ b/software/firmware/WozMon/wozaci.list @@ -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 diff --git a/software/firmware/WozMon/wozaci.txt b/software/firmware/WozMon/wozaci.txt new file mode 100644 index 0000000..c5034bc --- /dev/null +++ b/software/firmware/WozMon/wozaci.txt @@ -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 + + + + + + diff --git a/software/firmware/WozMon/wozmon.asm b/software/firmware/WozMon/wozmon.asm new file mode 100644 index 0000000..760f554 --- /dev/null +++ b/software/firmware/WozMon/wozmon.asm @@ -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 \ No newline at end of file diff --git a/software/firmware/WozMon/wozmon.hex b/software/firmware/WozMon/wozmon.hex new file mode 100644 index 0000000..8ede324 --- /dev/null +++ b/software/firmware/WozMon/wozmon.hex @@ -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 diff --git a/software/firmware/WozMon/wozmon.list b/software/firmware/WozMon/wozmon.list new file mode 100644 index 0000000..2584154 --- /dev/null +++ b/software/firmware/WozMon/wozmon.list @@ -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 diff --git a/software/firmware/WozMon/wozmon.txt b/software/firmware/WozMon/wozmon.txt new file mode 100644 index 0000000..599b756 --- /dev/null +++ b/software/firmware/WozMon/wozmon.txt @@ -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