Skip to content

Commit

Permalink
another evening of miscellaneous coding
Browse files Browse the repository at this point in the history
- int-test: terminal size output now in decimal
- minor updates in documentation
- added additional bootblock for minimal NMOS 6502 support
- kernel/bios updates to improve minimal NMOS 6502 support
- work on wozmon2: bugfix, improvements and new feature

Signed-off-by: Sven Oliver Moll <svolli@svolli.de>
  • Loading branch information
Sven Oliver Moll committed Nov 4, 2024
1 parent 0a678d6 commit 92f5cb9
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 103 deletions.
2 changes: 1 addition & 1 deletion doc/cpu_detect.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ with a pin layout similar to the original NMOS 6502 and the CMOS 65C02:
- 65C02, the base CMOS variant, as compared to the NMOS version,
a couple of bugs were fixed, and new instructions were introduced
- 65SC02, a 65C02 with the bit-related opcodes removed ($x7 and $xF are
just 1 byte, 1 cycle NOPs)
just 1 byte, 1 cycle NOPs), STP and WAI are missing as well
- 65816, a 16 bit capable variant of the 65SC02, with all 256 opcodes
defined now
- 65CE02, a CMOS reimplementation of the 65C02 by Commodore with also
Expand Down
21 changes: 14 additions & 7 deletions doc/monitors.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ comes with a lot of new features like a disassembler, a direct mini
assembler from the Apple //c and file access which is custom to the
Sorbus Computer.

As of now, this monitor needs to be loaded from the internal drive
using the file browser. This is intended to change, once it is
considered stable.

Displaying and entering data works the same as on the original WozMon.
There is an addition: instead of entering hex data, you can also enter
ASCII by prepending the letter with a single quote (`'`). However, when
Expand Down Expand Up @@ -63,10 +67,12 @@ When the prompt is a asterisk (`*`):
opcode. (Option renamed from Ctrl-E.) The values of those registers can
be changed by the `:` command as the edit address pointer has been put to
the correct place in memory ($00FB-$00FF).
- `c000<0400.07ffM`: move (or rather copy) the memory from $0400 to $0BFF to
- `c000<0400.0bffM`: move (or rather copy) the memory from $0400 to $0BFF to
$C000 to $C7FF.
- `c000<0400.07ffV`: verify (or rather compare) the memory from $0400 to
- `c000<0400.0bffV`: verify (or rather compare) the memory from $0400 to
$0BFF to $C000 to $C7FF.
- `bd<c000.cfffP`: put (or rather fill) the memory from $C000 to $CFFF with
the value of $BD.
- `0400L`: list (or rather disassemble) 20 instructions starting at $0400.
- `!`: drop to the direct mini assembler (see below)
- `A$`: display the directory of the user id $A (10) (Sorbus extension)
Expand All @@ -80,12 +86,13 @@ running. Now the user input is evaluated like:

- `1000:stz $DF01`: assemble the instruction `STZ $DF01` to address $1000.
(Note the `$` is optional.)
- `(space)rts`: assemble the instruction `RTS` to the now current address.
($1003 in this example, also note that the `(space)` means a space
character.)
- ` rts`: assemble the instruction `RTS` to the now current address.
($1003 in this example, also note the mendatory leading space character
for this case.)
- an empty input returns to the "asterisk input"

The supported instruction set is of the 65SC02.
The supported instruction set is of the 65SC02. The BRK instruction is not
supporing an operand here, as it is used with the Sorbus Native kernel.


TIM
Expand Down Expand Up @@ -155,5 +162,5 @@ entries there also relate to "monitor commands".
the output of more false instructions.
- D)isassemble: this will disassemble memory. Press space to advance.
Press "Q" to quit and return to meta menu.
- M)memory dump: view memory 256 bytes at a time, combined hexdump and
- M)emory dump: view memory 256 bytes at a time, combined hexdump and
ASCII.
11 changes: 9 additions & 2 deletions src/65c02/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ function(gencpmfs target)
add_custom_target(${target} ALL
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../tools/mkcpmfsimage.sh"
"${target}"
$<TARGET_FILE:native_cpm_bootblock>
$<TARGET_FILE:native_cpm_bootblock>:$<TARGET_FILE:native_nmos6502_bootblock>
"${CMAKE_CURRENT_SOURCE_DIR}/../bin/cpm"
${extra_files}
DEPENDS ${native_cpm_bootblock} ${native_browser} ${CPM_FILES} ${CPMFS_EXTRA_TARGETS}
DEPENDS ${native_cpm_bootblock} ${native_nmos6502_bootblock} ${native_browser} ${CPM_FILES} ${CPMFS_EXTRA_TARGETS}
)
endfunction()

Expand Down Expand Up @@ -133,6 +133,13 @@ add_executable(native_tools
)
target_type(native_tools native_kernel)

add_executable(native_nmos6502_bootblock
nmos6502/kernel.s
native_rom/woz.s
nmos6502/bios.s
)
target_type(native_nmos6502_bootblock native_kernel)

add_executable(native_cpm_bootblock
linkcpm.s
../bin/cpm/CPM
Expand Down
19 changes: 13 additions & 6 deletions src/65c02/native_bios.inc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
; - For the 65CE02 code, the use of the int macro is strongly recommended
; to take care of the additional Z register, else the Z register must
; be $00
; - For NMOS 6502 variant, only CHRIN, CHROUT and PRINT are suppored

; $FF00: read a character from UART in A, returns C=1 when no queue is empty
.define CHRIN $FF00
Expand All @@ -32,19 +33,25 @@
.global brkjump ; kernel only, doesn't matter in other banks
.global reset ; kernel only, doesn't matter in other banks

.ifp4510
.macro int arg
.ifp02
.macro int arg
.error trying to use software interrupt which is not supported on MOS 6502
.endmacro
.else
.ifp4510
.macro int arg
stz $DF2B ; save Z register that can't be written to stack
ldz #$00 ; clear Z register to be compatible to 65(S)C02
.byte $00,arg ; BRK with operand
php ; ldz changes processor status register
ldz $DF2B ; restore Z register
plp ; restore processor status
.endmacro
.else
.macro int arg
.endmacro
.else
.macro int arg
.byte $00,arg ; BRK with operand
.endmacro
.endmacro
.endif
.endif

; will jump using vector UVBRK ($DF78/$DF79)
Expand Down
4 changes: 2 additions & 2 deletions src/65c02/native_kernel.ld
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

MEMORY {
ROM: start = $E000, size = $1F00, define = yes, file = %O, fill = yes, fillval = $FF;
BIOS: start = $FF00, size = $00FA, define = yes, file = %O, fill = yes, fillval = $FF;
VECTORS: start = $FFFA, size = $0006, define = yes, file = %O, fill = yes;
BIOS: start = $FF00, size = $00EC, define = yes, file = %O, fill = yes, fillval = $FF;
VECTORS: start = $FFEC, size = $0014, define = yes, file = %O, fill = yes;
ZP: start = $0004, size = $00FC, define = yes;
STACK: start = $0100, size = $0100, define = yes;
}
Expand Down
28 changes: 14 additions & 14 deletions src/65c02/native_rom/bios.s
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,6 @@ ramio_cmd:
; optional idea: push X to stack and expand ramio_cmd to 3 bytes for JSR


RESET:
; reset routine that also works when copied to RAM
lda #$01
sta BANK ; set banking to first ROM bank (kernel)
jmp reset ; jump to reset routine
NMI:
jmp (UVNMI) ; user vector for NMI ($DF7A)
IRQ:
jmp (UVIRQ) ; user vector for BRK/IRQ ($DF7E) -> irqcheck (default)

IRQCHECK:
sta BRK_SA ; let's figure out the source of the IRQ
pla ; get processor status from stack
Expand Down Expand Up @@ -130,15 +120,25 @@ IRQCHECK:
lda BRK_SA ; get stored accumulator
rti ; return to calling code

.assert CHRIN = _chrin, error, "CHRIN at wrong address"
.assert CHROUT = _chrout, error, "CHROUT at wrong address"
.assert PRINT = _print, error, "PRINT at wrong address"

.out " ============================="
.out .sprintf( " BIOS size: $%04x ($%04x free)", * - BIOS, $FA - (* - BIOS) )
.out " ============================="

.segment "VECTORS"
NMI:
jmp (UVNMI) ; user vector for NMI ($DF7A)
IRQ:
jmp (UVIRQ) ; user vector for BRK/IRQ ($DF7E) -> irqcheck (default)
RESET:
; reset routine that also works when copied to RAM
lda #$01
sta BANK ; set banking to first ROM bank (kernel)
jmp reset ; jump to reset routine

.word NMI
.word RESET
.word IRQ

.assert CHRIN = _chrin, error, "CHRIN at wrong address"
.assert CHROUT = _chrout, error, "CHROUT at wrong address"
.assert PRINT = _print, error, "PRINT at wrong address"
24 changes: 16 additions & 8 deletions src/65c02/native_rom/kernel.s
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,17 @@ reset:

@no65c02loop:
jsr PRINT
.byte 13, "NMOS 6502 not supported, dropping to WozMon", 0
.byte 13, "NMOS 6502 not supported, key to boot sector 1 ", 0
:
iny
bne :-
inx
bne :-
jsr CHRIN
bcs @no65c02loop

lda #$01
jmp boota
; slip through

woz:
Expand Down Expand Up @@ -117,13 +125,13 @@ cmos6502:
:
cmp #'B'
bne :+
ldy #$03
lda #$03
@execrom2:
jmp execrom ; execute 3rd ROM bank @ $E000
:
cmp #'F'
bne :+
ldy #$02
lda #$02
ldx #$00 ; jmp vector 0: file browser
bra @execrom2 ; execute 2nd ROM bank @ $E000
:
Expand Down Expand Up @@ -243,16 +251,16 @@ boota:
.byte "Go",10,0
execram:
; execute loaded boot block in RAM at $E000
ldy #$00
execrom: ; has to be called with Y=bank to switch to
phy
lda #$00
execrom: ; has to be called with A=bank to switch to
pha
ldy #(@trampolineend-@trampoline-1)
:
lda @trampoline,y ; this requires bankswitching code written to RAM
sta TRAMPOLINE,y
dey
bpl :-
ply
pla
jmp TRAMPOLINE+@jmpbank0-@trampoline

@trampoline:
Expand All @@ -261,7 +269,7 @@ execrom: ; has to be called with Y=bank to switch to
stz BANK ; set BANK back to $00 (RAM)
rts
@jmpbank0:
sty BANK
sta BANK
jmp $E000
@trampolineend:

Expand Down
98 changes: 98 additions & 0 deletions src/65c02/nmos6502/bios.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@

; set processor to NMOS 6502
.p02

.include "../native.inc"
.include "../native_bios.inc"

;-------------------------------------------------------------------------
; BIOS calls $FF00-$FFFF
;-------------------------------------------------------------------------

.segment "BIOS"
BIOS:
_chrin:
; read character from UART
jmp chrin
_chrout:
; write character to UART
jmp chrout
_print:
; print a string while keeping all registers
sta ASAVE ; save A, it is used together with
php ; processor status register,
pla ; which can be only read via stack
sta PSAVE ; save it
pla ; get lobyte of address of text from stack and
sta TMP16+0 ; store it into temporary vector
pla ; same for hibyte
sta TMP16+1 ; store
tya ; make function 6502 proof, store Y the NMOS way
pha
ldy #$00 ; required for "lda (TMP16),y" below
@loop:
inc TMP16+0 ; since JSR stores return address - 1, start with
bne :+ ; incrementing the pointer
inc TMP16+1
:
lda (TMP16),y ; this could be "lda (tmp16)", but does not work with
; NMOS 6502 or 65CE02
beq @out ; $00 bytes indicates end of text
jsr chrout ; output the character
bpl @loop ; get next char (65C02 only opcode, jmp also works)
@out:
pla
tay ; restore save Y register
lda TMP16+1 ; get updated vector now pointing to end of text
pha ; write hibyte to stack
lda TMP16+0 ; (reverse order of fetching)
pha ; write lobyte to stack
lda PSAVE ; get saved processor status
pha ; put it on stack for restoring
lda ASAVE ; get saved A
plp ; get processor status from stack into register
rts ; now return to code after text

chrout:
bit UARTWS ; wait for buffer to accept data
bmi chrout
sta UARTWR ; write data to output queue
rts

chrin:
lda UARTRS ; check for size of input queue
bne :+ ; data available, fetch it
sec ; no input -> return 0 and set carry
rts
:
lda UARTRD ; get key value
clc
rts


IRQCHECK:
sta TRAP
rti ; return to calling code

.out " =================================="
.out .sprintf( " NMOS BIOS size: $%04x ($%04x free)", * - BIOS, $FA - (* - BIOS) )
.out " =================================="

.segment "VECTORS"
NMI:
jmp (UVNMI) ; user vector for NMI ($DF7A)
IRQ:
jmp (UVIRQ) ; user vector for BRK/IRQ ($DF7E) -> irqcheck (default)
RESET:
; reset routine that also has to work when copied to RAM
lda #$01
sta BANK ; set banking to first ROM bank (kernel)
jmp reset ; jump to reset routine

.word NMI
.word RESET
.word IRQ

.assert CHRIN = _chrin, error, "CHRIN at wrong address"
.assert CHROUT = _chrout, error, "CHROUT at wrong address"
.assert PRINT = _print, error, "PRINT at wrong address"
Loading

0 comments on commit 92f5cb9

Please sign in to comment.