summary refs log tree commit diff
path: root/pc-thing/code/wozmon.a
diff options
context:
space:
mode:
authorWlodekM <[email protected]>2025-03-31 19:47:54 +0300
committerWlodekM <[email protected]>2025-03-31 19:47:54 +0300
commitcccb99226d3951fd9dfe1c4cf1c43126a1309d51 (patch)
tree518d3e965558ba313f103cee6161cd2b6aedb3b9 /pc-thing/code/wozmon.a
parentef4e8c20719822eebd6318a878cc37902c2b85a5 (diff)
move to pc-thing/
Diffstat (limited to 'pc-thing/code/wozmon.a')
-rw-r--r--pc-thing/code/wozmon.a160
1 files changed, 160 insertions, 0 deletions
diff --git a/pc-thing/code/wozmon.a b/pc-thing/code/wozmon.a
new file mode 100644
index 0000000..5462c4d
--- /dev/null
+++ b/pc-thing/code/wozmon.a
@@ -0,0 +1,160 @@
+;  The WOZ Monitor for the Apple 1
+;  Written by Steve Wozniak in 1976
+
+
+; Page 0 Variables
+
+.label XAML            0x24           ;  Last "opened" location Low
+.label XAMH            0x25           ;  Last "opened" location High
+.label STL             0x26           ;  Store address Low
+.label STH             0x27           ;  Store address High
+.label L               0x28           ;  Hex value parsing Low
+.label H               0x29           ;  Hex value parsing High
+.label YSAV            0x2A           ;  Used to see if hex value is given
+.label MODE            0x2B           ;  $00=XAM, $7F=STOR, $AE=BLOCK XAM
+
+
+; Other Variables
+
+.label IN              0x0200         ;  Input buffer to $027F
+.label KBD             0xD010         ;  PIA.A keyboard input
+.label KBDCR           0xD011         ;  PIA.A keyboard control register
+.label DSP             0xD012         ;  PIA.B display output register
+.label DSPCR           0xD013         ;  PIA.B display control register
+
+               .org $FF00
+               .export RESET
+
+RESET:          ;CLD             ; Clear decimal arithmetic mode.
+                ;CLI
+                MOV Y 0x7F        ; Mask for DSP data direction register.
+                STY DSP         ; Set it up.
+                MOV A 0xA7        ; KBD and DSP control register mask.
+                STA KBDCR       ; Enable interrupts, set CA1, CB1, for
+                STA DSPCR       ;  positive edge sense/output mode.
+NOTCR:          CMP #'_'+$80    ; "_"?
+                BEQ BACKSPACE   ; Yes.
+                CMP 0x9B        ; ESC?
+                BEQ ESCAPE      ; Yes.
+                INY             ; Advance text index.
+                BPL NEXTCHAR    ; Auto ESC if > 127.
+ESCAPE:         LD A #'\'+$80    ; "\".
+                JSR ECHO        ; Output it.
+GETLINE:        LD A 0x8D        ; CR.
+                JSR ECHO        ; Output it.
+                LD Y 0x01        ; Initialize text index.
+BACKSPACE:      DEY             ; Back up text index.
+                BMI GETLINE     ; Beyond start of line, reinitialize.
+NEXTCHAR:       LD A KBDCR       ; Key ready?
+                BPL NEXTCHAR    ; Loop until ready.
+                LD A KBD         ; Load character. B7 should be ‘1’.
+                STA IN,Y        ; Add to text buffer.
+                JSR ECHO        ; Display character.
+                CMP 0x8D        ; CR?
+                BNE NOTCR       ; No.
+                LD Y 0xFF        ; Reset text index.
+                LD A 0x00        ; For XAM mode.
+                TAX             ; 0->X.
+SETSTOR:        ASL             ; Leaves $7B if setting STOR mode.
+SETMODE:        STA MODE        ; $00=XAM, $7B=STOR, $AE=BLOCK XAM.
+BLSKIP:         INY             ; Advance text index.
+NEXTITEM:       LD A IN,Y        ; Get character.
+                CMP 0x8D        ; CR?
+                BEQ GETLINE     ; Yes, done this line.
+                CMP #'.'+$80    ; "."?
+                BCC BLSKIP      ; Skip delimiter.
+                BEQ SETMODE     ; Set BLOCK XAM mode.
+                CMP #':'+$80    ; ":"?
+                BEQ SETSTOR     ; Yes. Set STOR mode.
+                CMP #'R'+$80    ; "R"?
+                BEQ RUN         ; Yes. Run user program.
+                STX L           ; $00->L.
+                STX H           ;  and H.
+                STY YSAV        ; Save Y for comparison.
+NEXTHEX:        LD A IN,Y        ; Get character for hex test.
+                EOR 0xB0        ; Map digits to $0-9.
+                CMP 0x0A        ; Digit?
+                BCC DIG         ; Yes.
+                ADC 0x88        ; Map letter "A"-"F" to $FA-FF.
+                CMP 0xFA        ; Hex letter?
+                BCC NOTHEX      ; No, character not hex.
+DIG:            ASL
+                ASL             ; Hex digit to MSD of A.
+                ASL
+                ASL
+                LD X 0x04        ; Shift count.
+HEXSHIFT:       ASL             ; Hex digit left, MSB to carry.
+                ROL L           ; Rotate into LSD.
+                ROL H           ; Rotate into MSD’s.
+                DEX             ; Done 4 shifts?
+                BNE HEXSHIFT    ; No, loop.
+                INY             ; Advance text index.
+                BNE NEXTHEX     ; Always taken. Check next character for hex.
+NOTHEX:         CPY YSAV        ; Check if L, H empty (no hex digits).
+                BEQ ESCAPE      ; Yes, generate ESC sequence.
+                BIT MODE        ; Test MODE byte.
+                BVC NOTSTOR     ; B6=0 STOR, 1 for XAM and BLOCK XAM
+                LD A L           ; LSD’s of hex data.
+                STA (STL,X)     ; Store at current ‘store index’.
+                INC STL         ; Increment store index.
+                BNE NEXTITEM    ; Get next item. (no carry).
+                INC STH         ; Add carry to ‘store index’ high order.
+TONEXTITEM:     JMP NEXTITEM    ; Get next command item.
+RUN:            JMP (XAML)      ; Run at current XAM index.
+NOTSTOR:        BMI XAMNEXT     ; B7=0 for XAM, 1 for BLOCK XAM.
+                LD X 0x02        ; Byte count.
+SETADR:         LD A L-1,X       ; Copy hex data to
+                STA STL-1,X     ;  ‘store index’.
+                STA XAML-1,X    ; And to ‘XAM index’.
+                DEX             ; Next of 2 bytes.
+                BNE SETADR      ; Loop unless X=0.
+NXTPRNT:        BNE PRDATA      ; NE means no address to print.
+                LD A 0x8D        ; CR.
+                JSR ECHO        ; Output it.
+                LD A XAMH        ; ‘Examine index’ high-order byte.
+                JSR PRBYTE      ; Output it in hex format.
+                LD A XAML        ; Low-order ‘examine index’ byte.
+                JSR PRBYTE      ; Output it in hex format.
+                LD A #':'+$80    ; ":".
+                JSR ECHO        ; Output it.
+PRDATA:         LD A 0xA0        ; Blank.
+                JSR ECHO        ; Output it.
+                LD A (XAML,X)    ; Get data byte at ‘examine index’.
+                JSR PRBYTE      ; Output it in hex format.
+XAMNEXT:        STX MODE        ; 0->MODE (XAM mode).
+                LD A XAML
+                CMP L           ; Compare ‘examine index’ to hex data.
+                LD A XAMH
+                SBC H
+                BCS TONEXTITEM  ; Not less, so no more data to output.
+                INC XAML
+                BNE MOD8CHK     ; Increment ‘examine index’.
+                INC XAMH
+MOD8CHK:        LD A XAML        ; Check low-order ‘examine index’ byte
+                AND 0x07        ;  For MOD 8=0
+                BPL NXTPRNT     ; Always taken.
+PRBYTE:         PHA             ; Save A for LSD.
+                LSR
+                LSR
+                LSR             ; MSD to LSD position.
+                LSR
+                JSR PRHEX       ; Output hex digit.
+                PLA             ; Restore A.
+PRHEX:          AND 0x0F        ; Mask LSD for hex print.
+                ORA #'0'+$80    ; Add "0".
+                CMP 0xBA        ; Digit?
+                BCC ECHO        ; Yes, output it.
+                ADC 0x06        ; Add offset for letter.
+ECHO:           BIT DSP         ; DA bit (B7) cleared yet?
+                BMI ECHO        ; No, wait for display.
+                STA DSP         ; Output character. Sets DA.
+                RTS             ; Return.
+
+                BRK             ; unused
+                BRK             ; unused
+
+; Interrupt Vectors
+
+                .WORD $0F00     ; NMI
+                .WORD RESET     ; RESET
+                .WORD $0000     ; BRK/IRQ
\ No newline at end of file