mirror of
https://github.com/stid/woz64.git
synced 2024-11-28 06:49:41 +00:00
422 lines
13 KiB
NASM
422 lines
13 KiB
NASM
#importonce
|
|
#import "../core/pseudo.asm"
|
|
#import "../core/system.asm"
|
|
#import "../libs/print.asm"
|
|
#import "../libs/timers.asm"
|
|
#import "../core/module.asm"
|
|
#import "../hardware/vic.asm"
|
|
#import "../devices/keyboard.asm"
|
|
#import "../devices/video.asm"
|
|
#import "../hardware/mem_map.asm"
|
|
|
|
.filenamespace WozShell
|
|
|
|
|
|
|
|
|
|
|
|
* = * "WozShell Routines"
|
|
|
|
// ========================================================
|
|
// ////// CONSTANTS ///////////////////////////////////////
|
|
// ========================================================
|
|
|
|
.const R = $52
|
|
.const CR = $0d
|
|
.const BS = $14
|
|
|
|
.const MAX_CMD_BUFFER = 40
|
|
|
|
// ========================================================
|
|
// ////// METHODS /////////////////////////////////////////
|
|
// ========================================================
|
|
|
|
|
|
clear:
|
|
init: {
|
|
lda #-1
|
|
sta MemMap.SHELL.pos
|
|
rts
|
|
}
|
|
|
|
start: {
|
|
PrintLine(lineString)
|
|
PrintLine(aboutString)
|
|
PrintLine(lineString)
|
|
|
|
//jsr WozShell.startCursor
|
|
jmp WozShell.loop
|
|
}
|
|
|
|
startCursor: {
|
|
sei
|
|
lda #$01
|
|
sta Vic.INTE
|
|
|
|
lda #<cursortInt
|
|
ldx #>cursortInt
|
|
|
|
sta $314 // store in $314/$315
|
|
stx $315
|
|
|
|
lda #$00
|
|
sta Vic.RCNT
|
|
|
|
lda $d011
|
|
and #$7f
|
|
sta $d011
|
|
|
|
cli
|
|
|
|
rts
|
|
|
|
cursortInt: {
|
|
dec $d019 // ACK INT
|
|
|
|
|
|
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
rti
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------------
|
|
loop: {
|
|
jsr Keyboard.waitForKey
|
|
|
|
cmp #CR
|
|
beq execute
|
|
|
|
cmp #BS
|
|
beq backspace
|
|
inputChar:
|
|
jsr WozShell.push // Char in Buffer
|
|
cpy #MAX_CMD_BUFFER
|
|
beq loop
|
|
PrintChar()
|
|
jmp loop
|
|
backspace:
|
|
jsr WozShell.backspace
|
|
PrintChar()
|
|
jmp loop
|
|
|
|
execute:
|
|
jsr WozShell.push // CR in Buffer
|
|
jsr Video.screenNewLine
|
|
jsr WozShell.exec
|
|
jsr Video.screenNewLine
|
|
jsr WozShell.clear
|
|
jmp loop
|
|
}
|
|
|
|
toDebug: {
|
|
ModuleToDebug(module_type, module_name, version)
|
|
rts
|
|
}
|
|
|
|
push: {
|
|
ldy MemMap.SHELL.pos
|
|
iny
|
|
cpy #MAX_CMD_BUFFER
|
|
beq done
|
|
sty MemMap.SHELL.pos
|
|
sta MemMap.SHELL.buffer, y
|
|
done:
|
|
rts
|
|
}
|
|
|
|
backspace: {
|
|
ldy MemMap.SHELL.pos
|
|
cpy #-1
|
|
beq done
|
|
dey
|
|
sty MemMap.SHELL.pos
|
|
done:
|
|
rts
|
|
}
|
|
|
|
exec: {
|
|
lda MemMap.SHELL.buffer // Check first char
|
|
cmp #'!'
|
|
beq stidExec // if ! is stid mon command
|
|
jmp wozExec // Otherwise exec Woz
|
|
// Expect exec functions to RTS
|
|
}
|
|
|
|
|
|
stidExec: {
|
|
ldy #1
|
|
|
|
lda MemMap.SHELL.buffer, y
|
|
|
|
cmp #$48 // H
|
|
beq cmdHelp
|
|
|
|
cmp #$52 // R
|
|
beq cmdReset
|
|
|
|
cmp #$56 // V
|
|
beq cmdSysInfo
|
|
|
|
.break
|
|
cmp #$54 // T
|
|
beq cmdTest
|
|
|
|
done:
|
|
rts
|
|
// STID Commands
|
|
cmdHelp:
|
|
PrintLine(helpString)
|
|
jmp done
|
|
cmdReset:
|
|
jmp $fce2 // SYS 64738
|
|
|
|
cmdSysInfo:
|
|
jsr System.toDebug
|
|
jmp done
|
|
|
|
cmdTest: {
|
|
// TODO: Optizime for code size here
|
|
ldy #1
|
|
loop:
|
|
tya
|
|
jsr clearVideo
|
|
jsr clearColors
|
|
jsr Timers.delayOne
|
|
iny
|
|
bne loop
|
|
VideoClearColorRam($03)
|
|
|
|
jmp done
|
|
|
|
clearVideo: {
|
|
ldx #0
|
|
!loop:
|
|
sta $0400, x
|
|
sta $0400 + $100, x
|
|
sta $0400 + $200, x
|
|
sta $0400 + $300, x
|
|
inx
|
|
bne !loop-
|
|
rts
|
|
}
|
|
|
|
clearColors: {
|
|
ldx #0
|
|
!loop:
|
|
sta $d800, x
|
|
sta $d800 + $100, x
|
|
sta $d800 + $200, x
|
|
sta $d800 + $300, x
|
|
inx
|
|
bne !loop-
|
|
rts
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// WOZ MONITOR FLOW - FROM APPLE1
|
|
wozExec: {
|
|
ldy #-1
|
|
lda #0
|
|
tax
|
|
SETSTOR:
|
|
asl
|
|
SETMODE:
|
|
cmp #0
|
|
beq !+
|
|
eor #%10000000
|
|
!:
|
|
sta MemMap.SHELL.MODE
|
|
|
|
BLSKIP: iny
|
|
|
|
NEXTITEM:
|
|
lda MemMap.SHELL.buffer,Y //Get character
|
|
cmp #CR
|
|
bne CONT // We're done if it's CR!
|
|
rts
|
|
CONT:
|
|
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 MemMap.SHELL.L // Clear input value (X=0)
|
|
stx MemMap.SHELL.H
|
|
sty MemMap.SHELL.YSAV // Save Y for comparison
|
|
|
|
// Here we're trying to parse a new hex value
|
|
|
|
NEXTHEX:
|
|
lda MemMap.SHELL.buffer,y // Get character for hex test
|
|
eor #$30 // 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 MemMap.SHELL.L // Rotate into LSD
|
|
rol MemMap.SHELL.H // Rotate into MSD's
|
|
dex // Done 4 shifts?
|
|
bne HEXSHIFT // No, loop
|
|
iny // Advance text index
|
|
bne NEXTHEX // Always taken
|
|
|
|
NOTHEX: cpy MemMap.SHELL.YSAV //Was at least 1 hex digit given?
|
|
bne !+ // No! Ignore all, start from scratch
|
|
rts
|
|
!:
|
|
bit MemMap.SHELL.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 MemMap.SHELL.L // LSD's of hex data
|
|
sta (MemMap.SHELL.STL,X) //Store current 'store index'(X=0)
|
|
inc MemMap.SHELL.STL //Increment store index.
|
|
bne NEXTITEM // No carry!
|
|
inc MemMap.SHELL.STH // Add carry to 'store index' high
|
|
TONEXTITEM:
|
|
jmp NEXTITEM //Get next command item.
|
|
|
|
//-------------------------------------------------------------------------
|
|
// RUN user's program from last opened location
|
|
//-------------------------------------------------------------------------
|
|
|
|
RUN: jmp (MemMap.SHELL.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 MemMap.SHELL.L-1,X // Copy hex data to
|
|
sta MemMap.SHELL.STL-1,X // 'store index'
|
|
sta MemMap.SHELL.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
|
|
PrintChar()
|
|
lda MemMap.SHELL.XAMH // Output high-order byte of address
|
|
jsr PRBYTE
|
|
lda MemMap.SHELL.XAML // Output low-order byte of address
|
|
jsr PRBYTE
|
|
lda #':' // Print colon
|
|
PrintChar()
|
|
|
|
PRDATA: lda #' ' // Print space
|
|
PrintChar()
|
|
lda (MemMap.SHELL.XAML,X) // Get data from address (X=0)
|
|
jsr PRBYTE // Output it in hex format
|
|
XAMNEXT:
|
|
stx MemMap.SHELL.MODE // 0 -> MODE (XAM mode).
|
|
lda MemMap.SHELL.XAML // See if there's more to print
|
|
cmp MemMap.SHELL.L
|
|
lda MemMap.SHELL.XAMH
|
|
sbc MemMap.SHELL.H
|
|
bcs TONEXTITEM // Not less! No more data to output
|
|
|
|
inc MemMap.SHELL.XAML // Increment 'examine index'
|
|
bne MOD8CHK // No carry!
|
|
inc MemMap.SHELL.XAMH
|
|
|
|
MOD8CHK:
|
|
lda MemMap.SHELL.XAML // If address MOD 8 = 0 start new line
|
|
and #%00000111
|
|
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 #%00001111 // Mask LSD for hex print
|
|
ora #'0' // Add "0"
|
|
cmp #'9'+1 // Is it a decimal digit?
|
|
bcc !+ // Yes! output it
|
|
adc #6 // Add offset for letter A-F
|
|
!:
|
|
PrintChar()
|
|
rts
|
|
}
|
|
|
|
|
|
// ========================================================
|
|
// ////// DATA ////////////////////////////////////////////
|
|
// ========================================================
|
|
|
|
* = * "WozShell Data"
|
|
module_type: .byte Module.TYPES.PROG
|
|
version: .byte 1, 5, 0
|
|
|
|
.encoding "screencode_mixed"
|
|
module_name:
|
|
.text "woz-shell"
|
|
.byte 0
|
|
|
|
helpString:
|
|
.text "----------------------"
|
|
.byte $8e
|
|
.text "h : this help"
|
|
.byte $8e
|
|
.text "r : hard reset"
|
|
.byte $8e
|
|
.text "v : modue versions"
|
|
.byte $8e
|
|
.text "----------------------"
|
|
.byte $8e, 0
|
|
|
|
aboutString:
|
|
.text "woz64 mon - v 1.6.0"
|
|
.byte $8e, 0
|
|
lineString:
|
|
.text "----------------------------------------"
|
|
.byte $8e, 0
|
|
|
|
#import "../hardware/mem_map.asm"
|