Davex/src/shell/3/conio3.asm

356 lines
9.8 KiB
NASM

;---------------------------------------------------------
; Character output
;
; Send one character to the console from Accumulator; preserve A
; Special case: crout, which prints a carriage return
;---------------------------------------------------------
crout: ; Output return character
lda #$0d
cout: ; Character output routine (print to screen)
sta WRITE1_DATA
CALLOS mli_write, WRITE1_PARMS
lda WRITE1_DATA
rts
;---------------------------------------------------------
; init_screen
;
; Sets up the screen for behaviors we expect
;---------------------------------------------------------
init_screen:
; Prepare the system for our expectations
jsr loadfnt
CALLOS mli_open, OPEN_PARMS ; Open the console
;jsr ERRORCK
lda OPEN_REF
sta WRITE_REF ; Save off our console file references
sta WRITE1_REF
sta CONSREAD_REF
jsr crout
jsr on80
lda #80
sta scr_width ; Davex needs to know the screen width
; Ask for device number of the console
CALLOS mli_get_dev_num, GET_DEV_NUM_PARMS
;jsr ERRORCK
lda GET_DEV_NUM_REF
sta D_STATUS_NUM ; Save off our console device references
sta D_CONTROL_NUM
lda #$80
sta D_CONTROL_DATA
lda #$0d
sta D_CONTROL_DATA+1
lda #$02
sta D_CONTROL_CODE
CALLOS mli_d_control, D_CONTROL_PARMS ; Turn data entry termination on
lda #$00
sta D_CONTROL_DATA
lda #$0f
sta D_CONTROL_CODE
CALLOS mli_d_control, D_CONTROL_PARMS ; Turn escape mode off
lda #$00
sta D_CONTROL_DATA
lda #$05
sta D_CONTROL_CODE ; Leave the control block set up to flush the typeahead buffer
lda e_reg ; Read the environment register
and #$f7 ; Turn $C000-$CFFF to R/W
ora #$40 ; Turn $C000-$CFFF to I/O
sta e_reg ; Write the environment register
; Points SOS' NMI vector at the debug routine in SOS. It normally
; points at an RTS so that hitting RESET doesn't do anything. This
; changes it so when you hit RESET, SOS enters a routine that saves all the
; important stuff, and jumps into the built in monitor. To reenter SOS, do
; a 198CG from the monitor. Known to work through SOS 1.3.
; To bank your memory in, set the bank register to the highest page
; I.e. FFEF:F6 for a 256k machine.
; Your zero page actually lives at $1A00-$1AFF.
;
; In Dav3x, to restart from the monitor, you need to reset the zero page
; and the environment registers, then jump to the restart code:
; Davex restart address
; =====
; a000:a9 1a 8d d0 ff a9 70 8d d1 ff 4c ed 21
; a000g
; And then maybe config -4n to get back into 80 column mode, until
; the code is straightened out for setting/resetting modes
lda $1904 ; Grab low byte of NMI vector
sec ; Make sure that carry is set.
sbc #$07 ; Fall back 7 bytes from the
sta $1911 ; byte currently pointed to
lda $1905 ; (an RTS), and store this in
sbc #$00 ; the NMI JMP instruction.
sta $1912 ; Unwrap the high byte.
rts
memory_fail:
jsr mess
ascz "UNABLE TO ALLOCATE REQUIRED MEMORY."
jmp *
set_columns: ; $00 = 80 columns, $ff = 40 columns
lda #INIT_SCREEN_DATA_END-INIT_SCREEN_DATA
sta WRITE_LEN
lda #<INIT_SCREEN_DATA
sta msgp
lda #>INIT_SCREEN_DATA
sta msgp+1
CALLOS mli_write, WRITE_PARMS ; Re-using the message parameter block
rts
on40:
lda #columns40
jmp prep_columns
on80:
lda #columns80
prep_columns:
sta INIT_SCREEN_COLUMNS
jmp set_columns
;---------------------------------------------------------
; HOME
;
; Clears the screen
;---------------------------------------------------------
home:
lda #$1c
jsr cout
rts
;***********************************************
;
; mess -- print an in-line message
;
mess:
pla ; Return address is on the stack - which we use to find parms
clc
adc #$01
sta msgp
sta p
pla
adc #$00
sta msgp+1 ; The output buffer pointer, msgp, is set to the caller's memory following mess call
sta p+1
ldy #$00
sty WRITE_LEN+1 ; Start with MSB of 16-bit write length to zero
get_next: ; Count the number of bytes to print
iny
bne no_inc
inc p+1
inc WRITE_LEN+1
no_inc:
lda (p),y
bne get_next
sty WRITE_LEN
CALLOS mli_write, WRITE_PARMS
clc ; Flatten return address - take an arbitrary pointer plus length and make it an address
tya ; Y holds the lsb of the number of bytes we counted
adc msgp ; Add the original address' lsb
sta p ; Hang on to that for a second while we calculate the msb and push that
lda msgp+1 ; Get original address' msb
adc WRITE_LEN+1 ; Add in the msb from length we counted, plus the carry (if any) from lsb addition
pha ; Push msb of return address
lda p ; Grab the lsb we stashed a second ago
pha ; Push the lsb
rts ; Return to the caller just past the point of the message
;---------------------------------------------------------
; prbyte: Print Byte routine (HEX value)
;---------------------------------------------------------
prbyte:
prhex:
PHA ; PRINT BYTE AS 2 HEX
LSR ; DIGITS, DESTROYS A-REG
LSR
LSR
LSR
JSR :+
PLA
AND #$0F ; PRINT HEX DIG IN A-REG
: ORA #$B0 ; LSB'S
CMP #$BA
BCC :+
ADC #$06
: JMP cout
rts
suspend80:
restore80:
rts
;---------------------------------------------------------
; loadfnt: Load up the standard Apple character font
;---------------------------------------------------------
ctemp1 = $FD
dnldcel = $FE
dnldchr = $FF
dimgptr = $21
dcelptr = $2a
cwrton = $C0DB
cwrtoff = $C0DA
cb2ctrl = $FFEC
cb2int = $FFED
loadfnt:
lda #$F0
sta $FFDF
lda #<fontptr
sta dimgptr
lda #>fontptr
sta dimgptr+1
lda #$00
sta dnldchr
lda #$07
sta dnldcel
@1: jsr loadchr
dec dnldcel
bpl @2
bit cwrton
jsr vretrce
jsr vretrce
bit cwrtoff
lda #$07
sta dnldcel
@2: inc dnldchr
bpl @1
loadchr: lda #$00 ; X will be set to 0 for this function
tax
tay ; Use Y for row counter
@1: lda dnldcel ; Set up cell pointer for ASCII code
and #$03
ora dcptrl, y
sta dcelptr, x
lda dnldcel
lsr
lsr
cpy #$04
rol
ora #$08
sta dcelptr+1, x
lda dnldchr ; Store ASCII code into download cell
sta (dcelptr, x)
lda dcelptr+1, x ; Fix cell pointer for character image
eor #$0C
sta dcelptr+1, x
lda (dimgptr, x) ; Store character image
sta (dcelptr, x) ; into download cell
inc dimgptr, x ; Increment the image pointer
bne @2
inc dimgptr+1, x
@2: iny ; Increment the row number
cpy #$08
bcc @1 ; Not done yet
rts
vretrce: sta ctemp1 ; save bits to be stored
lda cb2ctrl ; control port for "CB2"
and #$3F ; reset high bits to 0
ora ctemp1
sta cb2ctrl
lda #$08 ; test vertical retrace
sta cb2int
vwait: bit cb2int ; wait for retrace
beq vwait
rts
dcptrl: .byte $78, $7C, $F8, $FC, $78, $7C, $F8, $FC
fontptr: .incbin "../../src/shell/3/starfont.bin"
INIT_SCREEN_DATA:
.byte 16
INIT_SCREEN_COLUMNS:
.byte columns80
.byte 21, $0f ; Make return do newline
.byte 1 ; Reset viewport
.byte 28 ; Clear screen
INIT_SCREEN_DATA_END:
; Table for write one character
WRITE1_PARMS: .byte 3
WRITE1_REF: .byte $FF
WRITE1_DATA_PTR: .word WRITE1_DATA
WRITE1_LEN: .word $0001
WRITE1_DATA: .byte $00
; Table for write string
WRITE_PARMS: .byte 3
WRITE_REF: .byte $FF
WRITE_DATA_PTR: .word msgp
WRITE_LEN: .word $0000
; Table for console read
CONSREAD_PARMS: .byte $04
CONSREAD_REF: .byte $00
.word CONSREAD_INPUT
CONSREAD_COUNT: .word $0001
CONSREAD_XFERCT: .word $0000
CONSREAD_INPUT: .res $100, $00
; Table for open
OPEN_PARMS: .byte 4
OPEN_NAME: .addr CONSOLE
OPEN_REF: .byte $ff
OPEN_OPT_PTR: .addr 0
OPEN_LEN: .byte 0
CONSOLE: .byte CONSOLE_END-CONSOLE_BODY
CONSOLE_BODY: .byte ".CONSOLE"
CONSOLE_END:
; Table for get device number
GET_DEV_NUM_PARMS:
.byte $02
GET_DEV_NUM_NAME:
.addr CONSOLE
GET_DEV_NUM_REF:
.byte $00
; Table for device status
D_STATUS_PARMS: .byte $03
D_STATUS_NUM: .byte $00
D_STATUS_CODE: .byte $00
D_STATUS_LIST: .addr D_STATUS_DATA
D_STATUS_DATA: .byte $00, $00
; Table for device control
D_CONTROL_PARMS:
.byte $03
D_CONTROL_NUM: .byte $01
D_CONTROL_CODE: .byte $00
D_CONTROL_LIST: .addr D_CONTROL_DATA
D_CONTROL_DATA: .byte $00, $00
FIND_SEG_PARMS: .byte $06 ; Six parameters
FIND_SEG_MODE: .byte $00 ; In - don't cross 32k boundaries
FIND_SEG_LABEL: .byte $10 ; In - our segment "label"
FIND_SEG_PAGES: .addr $0080 ; In/Out - number of pages
FIND_SEG_BASE: .addr $0000 ; Out - origin segment addr
FIND_SEG_LIMIT: .addr $0000 ; Out - last segment addr
FIND_SEG_NUM: .byte $00 ; Out - segment "number"
GET_PREFIX_PARMS: .byte $02
GET_PREFIX_PATH: .addr string2-1
GET_PREFIX_LENGTH:
.byte $80
SET_PREFIX_PARMS: .byte $01
SET_PREFIX_PATH: .addr string2-1 ; Must be Pascal string