mirror of
https://github.com/callapple/GBBS.git
synced 2026-04-20 08:16:28 +00:00
caf6ddd745
All files refreshed. Config now shows uppercase when using a ][+ Minor bug fixes in logon.seg.s Newer XDOS external with bug fixes
1873 lines
30 KiB
ArmAsm
1873 lines
30 KiB
ArmAsm
PAG
|
|
********************************
|
|
* *
|
|
* ACOS.OBJ - Disk *
|
|
* *
|
|
********************************
|
|
DATE
|
|
*-------------------------------
|
|
* open a text file [actually, any type of file!]
|
|
*-------------------------------
|
|
|
|
DO_OPEN LDX #"#"
|
|
JSR GOBBLE ;gobble "#"
|
|
JSR INPNUM ;get channel to open
|
|
DEX
|
|
STX TEMP2 ;save buffer number
|
|
CPX #2
|
|
BGE :DO_OPN4 ;make sure it's in range [1-2]
|
|
|
|
LDA DEVUSE+1,X ;see if channel in use
|
|
BMI :DO_OPN3
|
|
|
|
JSR GOBCOM ;gobble comma
|
|
JSR MOVNAME ;move file name
|
|
LDY TEMP2 ;get buffer number
|
|
JSR BFOPEN
|
|
|
|
LDX TEMP2
|
|
LDA #0 ;save refnum or 0 if none
|
|
BCS :DO_OPN2
|
|
|
|
LDA REFNUM
|
|
:DO_OPN2 STA REFTAB,X ;save ref number
|
|
DEC DEVUSE+1,X ;put "in use"
|
|
RTS
|
|
|
|
:DO_OPN3 LDX #badfn ;bad file name
|
|
BNE :DO_OPN5
|
|
|
|
:DO_OPN4 LDX #baddev ;bad device number
|
|
:DO_OPN5 JMP BADERR
|
|
|
|
*-------------------------------
|
|
* try to open in a non-used channel
|
|
*-------------------------------
|
|
|
|
IFOPEN LDY #0 ;check channel 1
|
|
LDA DEVUSE+1,Y
|
|
BPL :IFOPEN2 ;it's open
|
|
|
|
INY
|
|
LDA DEVUSE+1,Y ;try channel 2
|
|
BMI :IFOPEN3 ;hmm, no open channel
|
|
|
|
:IFOPEN2 JSR BFOPEN ;open file
|
|
BCS :IFOPEN3 ;opps, file didn't open
|
|
RTS ;clc = all is well
|
|
|
|
:IFOPEN3 SEC ;opps, couldn't open
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* append to a file
|
|
*-------------------------------
|
|
|
|
DO_APP JSR GETDEV ;get device
|
|
JSR CHKDSK ;make sure device is a file
|
|
LDA REFTAB,Y
|
|
STA REFNUM ;get refnum
|
|
JMP APPEND ;append to file
|
|
|
|
*-------------------------------
|
|
* close a file
|
|
*-------------------------------
|
|
|
|
DO_CLOS JSR GETDEV ;get device
|
|
CPX #0
|
|
BEQ DO_CL3 ;if there wasn't one (or dev0) close all
|
|
|
|
JSR CHKDSK ;make sure device is a file
|
|
TYA
|
|
TAX ;x = y
|
|
LDA #0
|
|
STA DEVUSE+1,X ;"un use" it
|
|
LDA REFTAB,X ;get refnum
|
|
BEQ DO_CL6 ;opps, not really open
|
|
|
|
STA REFNUM
|
|
JMP CLOSE ;close the correct file(s)
|
|
|
|
*-------------------------------
|
|
* close open files
|
|
*-------------------------------
|
|
|
|
DO_CL3 LDA DEVUSE+1 ;check channel 1
|
|
BPL :DO_CL4
|
|
|
|
LDA REFTAB ;close channel 1
|
|
BEQ :DO_CL4 ;opps, not really open
|
|
|
|
STA REFNUM
|
|
JSR CLOSE
|
|
|
|
:DO_CL4 LDA DEVUSE+2 ;check channel 2
|
|
BPL :DO_CL5
|
|
|
|
LDA REFTAB+1 ;close channel 2
|
|
BEQ :DO_CL5 ;opps, not really open
|
|
|
|
STA REFNUM
|
|
JSR CLOSE
|
|
|
|
:DO_CL5 LDA #0
|
|
STA DEVUSE+1 ;close both channels
|
|
STA DEVUSE+2
|
|
DO_CL6 RTS
|
|
|
|
*-------------------------------
|
|
* get input from the file
|
|
*-------------------------------
|
|
|
|
DISKIN1 LDA REFTAB ;use channel 1
|
|
STA REFNUM
|
|
JMP RDBYTE
|
|
|
|
DISKIN2 LDA REFTAB+1 ;use channel 2
|
|
STA REFNUM
|
|
JMP RDBYTE
|
|
|
|
*-------------------------------
|
|
* output to a file
|
|
*-------------------------------
|
|
|
|
DSKOUT1 PHA
|
|
LDA REFTAB ;use channel 1
|
|
STA REFNUM
|
|
PLA
|
|
JMP WRBYTE
|
|
|
|
DSKOUT2 PHA
|
|
LDA REFTAB+1
|
|
STA REFNUM ;use channel 2
|
|
PLA
|
|
JMP WRBYTE
|
|
|
|
REFTAB DS 2 ;reference numbers
|
|
|
|
*-------------------------------
|
|
* get the device number
|
|
*-------------------------------
|
|
|
|
GETDEV JSR CHKBYT
|
|
LDX #0
|
|
LDY #0
|
|
CMP #"#"
|
|
BNE :GETDEV1 ;device indicator?, nope
|
|
|
|
JSR GETBYT ;gobble '#'
|
|
LDA #0
|
|
STA DEVCLR ;reset device byte
|
|
JSR CHKBYT
|
|
CMP #msg
|
|
BEQ :GETMSG ;check for message
|
|
|
|
JSR INPNUM
|
|
CMP #0
|
|
BNE GETDEV2 ;if > 255
|
|
|
|
BIT MSGINIT ;is channel 6 setup?
|
|
BMI :GETMSG2 ;yep
|
|
|
|
CPX #6
|
|
BEQ GETDEV2 ;trying to use channel 6?, yes, stop them
|
|
|
|
:GETMSG2 JSR CHKBYT
|
|
CMP #","
|
|
BNE :GETDEV0
|
|
|
|
JSR GETBYT ;gobble comma
|
|
:GETDEV0 LDA DEVUSE,X ;is channel in use
|
|
BPL GETDEV2 ;nope
|
|
|
|
TXA
|
|
TAY ;y = x
|
|
ASL ;x = x * 2
|
|
TAX
|
|
:GETDEV1 RTS
|
|
|
|
:GETMSG JSR GETBYT ;gobble
|
|
JSR INPNUM ;get msg number
|
|
STX MSGNUM ;save
|
|
STA MSGNUM+1
|
|
LDA #0
|
|
STA MSGINIT ;init message
|
|
LDX #6 ;return channel
|
|
JMP :GETMSG2 ;finish up
|
|
|
|
GETDEV2 LDX #baddev ;bad device #
|
|
JMP BADERR
|
|
|
|
CHKDSK DEY ;make sure device is a file
|
|
CPY #2
|
|
BGE GETDEV2 ;if it's not a file...
|
|
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* get the size of the open file
|
|
*-------------------------------
|
|
|
|
DO_SIZE JSR INPNARG ;get volume number
|
|
CPX #3
|
|
BGE GETDEV2 ;bad device
|
|
|
|
LDA REFTAB-1,X ;get refnum
|
|
STA REFNUM
|
|
JSR GETSIZ ;get the file size
|
|
JMP DO_MATH
|
|
|
|
*-------------------------------
|
|
* check for end of file
|
|
*-------------------------------
|
|
|
|
DO_EOF JSR INPNARG ;get channel number
|
|
CPX #3
|
|
BGE GETDEV2 ;bad device
|
|
|
|
LDA REFTAB-1,X ;move refnum
|
|
STA REFNUM
|
|
JSR CHKEOF ;check for eof
|
|
TXA
|
|
JMP SVDATA ;return results
|
|
|
|
*-------------------------------
|
|
* set/get the mark for a file
|
|
*-------------------------------
|
|
|
|
DO_MARK JSR INPNARG
|
|
CPX #10
|
|
BEQ :DO_MRK5 ;ram drive?
|
|
|
|
DEX
|
|
CPX #2
|
|
BGE :DO_MRK3 ;make sure it's a valid channel
|
|
|
|
LDA DEVUSE+1,X ;not current in use
|
|
BPL :DO_MRK3
|
|
|
|
LDA REFTAB,X
|
|
TAY ;get refnum
|
|
|
|
BIT IMMDEF ;see if mark was exec'ed
|
|
BPL :DO_MRK2
|
|
|
|
JSR GOBEQU ;possible syntax error
|
|
STY SAVE_Y ;set the mark
|
|
JSR INPNUM
|
|
LDY SAVE_Y
|
|
JMP SETMARK
|
|
|
|
:DO_MRK2 JSR GETMARK ;get the mark
|
|
BCC :DO_MRK4 ;all is well
|
|
|
|
LDA #1 ;error
|
|
JMP SVDATA
|
|
|
|
:DO_MRK4 JMP DO_MATH ;return location
|
|
|
|
:DO_MRK3 LDX #baddev ;bad device #
|
|
JMP BADERR
|
|
|
|
:DO_MRK5 BIT IMMDEF ;did they exec command?
|
|
BPL :DO_MRK6 ;nope
|
|
|
|
JSR GOBEQU
|
|
JSR INPNUM ;get pointer
|
|
STX RAMPTR ;save
|
|
RTS
|
|
|
|
:DO_MRK6 LDA RAMPTR ;return pointer
|
|
JMP SVDATA
|
|
|
|
*-------------------------------
|
|
* link to another segment
|
|
*-------------------------------
|
|
|
|
DO_LINK JSR DO_FRE ;compact variables
|
|
JSR DO_CL3 ;close all open files
|
|
JSR MOVNAME ;move filename
|
|
LDA #0
|
|
STA LNKLBL
|
|
JSR CHKBYT
|
|
CMP #","
|
|
BNE :LINK4 ;check for link label, nope
|
|
|
|
JSR GOBCOM ;gobble comma
|
|
JSR INPSTR ;get link label
|
|
|
|
LDY #0
|
|
:LINK2 LDA (STRLOC),Y ;copy label name
|
|
JSR CONV
|
|
INY
|
|
CPY STRLEN
|
|
BNE :LINK3 ;is this the last char?
|
|
|
|
ORA #hibit
|
|
:LINK3 STA LNKLBL-1,Y ;save char
|
|
CPY #8
|
|
BNE :LINK2
|
|
|
|
ORA #hibit ;mark last char
|
|
STA LNKLBL-1,Y
|
|
|
|
:LINK4 JSR COMPRES ;compress variables
|
|
JSR LD_MOD ;load in module
|
|
JSR UNCOMP ;un-compress variables
|
|
|
|
LDA #<CODEND ;were finally done!
|
|
STA PRGPTR
|
|
LDA #>CODEND
|
|
STA PRGPTR+1
|
|
LDA LNKLBL ;link to a label?
|
|
BEQ :LINK9 ;nope, just return
|
|
|
|
LDX #128 ;start table pointer
|
|
:LINK5 LDY #0 ;start string pointer
|
|
:LINK6 LDA LNBUF,X ;get first char
|
|
BEQ :LINK8 ;opps, end of table
|
|
|
|
INX
|
|
CMP LNKLBL,Y
|
|
BNE :LINK7 ;check it, no match
|
|
INY
|
|
ASL ;are we done?
|
|
BCC :LINK6 ;nope, keep checking
|
|
|
|
TXA
|
|
AND #$F0 ;round down X
|
|
TAX
|
|
|
|
LDA LNBUF+8,X
|
|
STA PRGPTR ;get address and save
|
|
LDA LNBUF+9,X
|
|
STA PRGPTR+1
|
|
:LINK9 RTS ;return
|
|
|
|
:LINK7 TXA ;round down X
|
|
AND #$F0
|
|
CLC
|
|
ADC #$10 ;go to next label
|
|
TAX
|
|
BCC :LINK5 ;keep going if more data
|
|
|
|
:LINK8 LDX #nolink ;link label not found
|
|
JMP BADERR
|
|
|
|
LNKLBL DS 9 ;location of link label
|
|
|
|
*-------------------------------
|
|
* store current variables to a disk file
|
|
*-------------------------------
|
|
|
|
DO_STOR JSR DO_CL3 ;close any open files
|
|
JSR MOVNAME ;move filename
|
|
LDY #a2data
|
|
LDA #>packfile
|
|
LDX #<packfile
|
|
JSR CREATE ;create file
|
|
JSR OPEN ;open file
|
|
|
|
JSR COMPRES ;compress memory
|
|
|
|
LDA DATA ;point to old lomem location
|
|
JSR WRBYTE
|
|
LDA DATA+1
|
|
JSR WRBYTE
|
|
|
|
LDA FREMEM ;save # of string pages
|
|
JSR WRBYTE
|
|
|
|
LDA MIDMEM ;point to address of strings
|
|
JSR WRBYTE
|
|
LDA MIDMEM+1
|
|
JSR WRBYTE
|
|
|
|
SEC
|
|
LDA HIMEM+1
|
|
SBC MIDMEM+1
|
|
CLC
|
|
ADC #1 ;write # pages of data
|
|
JSR WRBYTE
|
|
|
|
ASL
|
|
TAY
|
|
LDX MIDMEM ;write data out to disk
|
|
LDA MIDMEM+1
|
|
JSR WRBLK
|
|
|
|
JSR CLOSE ;close file
|
|
JSR UNCOMP ;fix memory
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* recall a set of variables from disk to memory
|
|
*-------------------------------
|
|
|
|
DO_RCAL JSR DO_CL3 ;close all open files
|
|
|
|
JSR MOVNAME ;get filename
|
|
JSR CLEAR
|
|
JSR OPEN
|
|
BCC :RCALL2 ;all is fine
|
|
LDX #badfn
|
|
JMP BADERR ;illegal filename
|
|
|
|
:RCALL2 JSR RDBYTE ;restore old lomem position
|
|
STA DATA
|
|
JSR RDBYTE
|
|
STA DATA+1
|
|
|
|
JSR RDBYTE ;restore # pages of strings
|
|
STA FREMEM
|
|
|
|
JSR RDBYTE
|
|
STA MIDMEM
|
|
TAX ;get address of data
|
|
JSR RDBYTE
|
|
STA MIDMEM+1
|
|
PHA
|
|
|
|
JSR RDBYTE ;get length of data
|
|
ASL
|
|
TAY
|
|
PLA
|
|
JSR RDBLK ;read in data
|
|
|
|
JSR CLOSE ;close file
|
|
|
|
LDA #1 ;make sure it uncompresses
|
|
STA CPASS
|
|
|
|
JSR UNCOMP ;un-compress
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* compress variables at top of memory
|
|
* at exit: data points to data
|
|
*-------------------------------
|
|
|
|
COMPRES JSR DO_FRE ;clear up memory
|
|
LDA HIMEM ;point to var-pointers
|
|
STA TEMP
|
|
LDA HIMEM+1
|
|
STA TEMP+1
|
|
LDA #0 ;flag for pass through
|
|
STA CPASS
|
|
|
|
:COMP2 SEC ;walk through pointers
|
|
LDA TEMP
|
|
SBC #6
|
|
STA TEMP
|
|
LDA TEMP+1
|
|
SBC #0
|
|
STA TEMP+1
|
|
|
|
LDY #0
|
|
LDA (TEMP),Y
|
|
BEQ :COMP5 ;were done copying
|
|
PHP
|
|
LDA #-1
|
|
STA CPASS
|
|
PLP
|
|
BPL :COMP2 ;only do strings
|
|
|
|
LDY #2
|
|
LDA (TEMP),Y
|
|
STA VPTR ;point to string
|
|
INY
|
|
LDA (TEMP),Y
|
|
STA VPTR+1
|
|
INY
|
|
LDA (TEMP),Y
|
|
TAX
|
|
BEQ :COMP2 ;if 0 long...
|
|
|
|
LDA VPTR+1 ;find out if string is in tokanized
|
|
CMP LOMEM+1 ;program segment
|
|
BEQ :COMP3 ;if so, move it to ram
|
|
BGE :COMP2 ;ok, it's in memory
|
|
|
|
CMP #>CODEND ;make sure it's really in program
|
|
BLT :COMP2 ;good thing we checked
|
|
|
|
:COMP3 LDA VPTR
|
|
CMP LOMEM
|
|
BGE :COMP2 ;it's ok
|
|
|
|
LDY #0
|
|
:COMP4 LDA (VPTR),Y
|
|
STA (VARSTR),Y ;copy string along with other strings
|
|
INY
|
|
DEX
|
|
BNE :COMP4
|
|
|
|
TYA ;x = y
|
|
TAX
|
|
LDY #2
|
|
LDA VARSTR
|
|
STA (VPTR),Y ;point to new string
|
|
INY
|
|
LDA VARSTR+1
|
|
STA (VPTR),Y
|
|
|
|
CLC
|
|
TXA
|
|
ADC VARSTR ;move up pointers
|
|
STA VARSTR
|
|
LDA #0
|
|
ADC VARSTR+1
|
|
STA VARSTR+1
|
|
JMP :COMP2
|
|
|
|
:COMP5 LDA CPASS ;anything done?
|
|
BEQ COMP8 ;no, just exit
|
|
|
|
LDA TEMP ;save pointer to end of var pointers
|
|
STA TEMP3
|
|
LDA TEMP+1
|
|
STA TEMP3+1
|
|
|
|
LDA LOMEM
|
|
CMP VARSTR
|
|
BGE :COMP6 ;make pointers point to a boundry
|
|
|
|
INC VARSTR+1
|
|
:COMP6 STA VARSTR
|
|
DEC TEMP+1
|
|
DEC VARSTR+1
|
|
|
|
LDY #0
|
|
STY FREMEM
|
|
|
|
:COMP7 LDA (VARSTR),Y
|
|
STA (TEMP),Y ;copy a page
|
|
INY
|
|
BNE :COMP7
|
|
|
|
LDA VARSTR+1
|
|
INC FREMEM
|
|
DEC TEMP+1
|
|
DEC VARSTR+1 ;go until we are done
|
|
CMP LOMEM+1
|
|
BNE :COMP7
|
|
|
|
LDX TEMP
|
|
STX MIDMEM ;save location of strings
|
|
LDX TEMP+1
|
|
INX
|
|
STX MIDMEM+1
|
|
|
|
LDA LOMEM ;point to variables/tables
|
|
STA DATA
|
|
LDA LOMEM+1
|
|
STA DATA+1
|
|
COMP8 RTS
|
|
|
|
*-------------------------------
|
|
* un-compress memory into variables
|
|
*-------------------------------
|
|
|
|
UNCOMP LDA CPASS ;anything compressed?
|
|
BEQ COMP8 ;no, do nothing
|
|
|
|
SEC
|
|
LDA LOMEM
|
|
SBC DATA
|
|
STA DATA ;compute offset
|
|
|
|
LDA LOMEM+1
|
|
SBC DATA+1
|
|
STA DATA+1 ;compute offset
|
|
|
|
LDA LOMEM ;point at strings
|
|
STA TEMP
|
|
LDA LOMEM+1
|
|
STA TEMP+1
|
|
|
|
LDX FREMEM
|
|
LDY #0
|
|
:UNCOMP2 LDA (MIDMEM),Y
|
|
STA (TEMP),Y ;copy a page
|
|
INY
|
|
BNE :UNCOMP2
|
|
|
|
INC MIDMEM+1
|
|
INC TEMP+1 ;count the page
|
|
DEX
|
|
BNE :UNCOMP2
|
|
|
|
LDA TEMP ;set up varstr [approx...]
|
|
STA VARSTR
|
|
LDA TEMP+1
|
|
STA VARSTR+1
|
|
|
|
LDA HIMEM
|
|
STA TEMP
|
|
LDA HIMEM+1
|
|
STA TEMP+1
|
|
|
|
:UNCOMP3 SEC
|
|
LDA TEMP
|
|
SBC #6
|
|
STA TEMP ;count down through strings
|
|
LDA TEMP+1
|
|
SBC #0
|
|
STA TEMP+1
|
|
|
|
LDY #0
|
|
LDA (TEMP),Y
|
|
BEQ :UNCOMP4 ;were done
|
|
BPL :UNCOMP3 ;don't fool with numbers
|
|
|
|
LDY #4 ;check length of string
|
|
LDA (TEMP),Y ;is it an empty string?
|
|
BEQ :UNCOMP3 ;yep
|
|
|
|
DEY
|
|
LDA (TEMP),Y ;get address of string
|
|
CMP #>CODEND
|
|
BLT :UNCOMP3 ;don't touch it
|
|
|
|
DEY
|
|
CLC
|
|
LDA DATA
|
|
ADC (TEMP),Y
|
|
STA (TEMP),Y ;fix pointers
|
|
INY
|
|
LDA DATA+1
|
|
ADC (TEMP),Y
|
|
STA (TEMP),Y
|
|
JMP :UNCOMP3
|
|
|
|
:UNCOMP4 SEC
|
|
LDA TEMP+1
|
|
SBC LOMEM+1 ;fix midmem pointer
|
|
LSR A
|
|
CLC
|
|
ADC LOMEM+1
|
|
STA MIDMEM+1
|
|
|
|
LDA #0
|
|
STA MIDMEM
|
|
SHWRTS RTS
|
|
|
|
*-------------------------------
|
|
* copy a file from device to device
|
|
*-------------------------------
|
|
|
|
DO_SHOW LDA #0
|
|
STA SHW_CNT ;reset line count
|
|
JSR CHKBYT ;check for # of lines
|
|
CMP #"("
|
|
BNE :SHOW0A
|
|
|
|
JSR INPNARG ;get argument
|
|
STX SHW_CNT ;save count
|
|
|
|
:SHOW0A JSR GETDEV ;get input source
|
|
STY SHWIN
|
|
|
|
LDA INPVEC,X ;save vector
|
|
STA VECTOR2
|
|
LDA INPVEC+1,X
|
|
STA VECTOR2+1
|
|
|
|
LDA REFTAB-1,Y
|
|
STA REFNUM ;save possible refnum
|
|
TYA
|
|
BNE :SHOW0 ;if using device, skip
|
|
|
|
JSR MOVNAME ;get filename
|
|
|
|
:SHOW0 JSR CHKBYT
|
|
CMP #","
|
|
BNE :SHOW1
|
|
|
|
JSR GOBCOM ;gobble
|
|
:SHOW1 JSR GETDEV
|
|
STY SHWOUT
|
|
|
|
LDA OUTVEC,X ;save output vectors
|
|
STA VECTOR
|
|
LDA OUTVEC+1,X
|
|
STA VECTOR+1
|
|
|
|
LDA SHWIN ;get input device
|
|
CMP #3
|
|
BGE :SHOW3
|
|
CMP #0
|
|
BNE :SHOW2 ;is file open?, yep
|
|
|
|
JSR OPEN ;open the file
|
|
BCS SHWRTS ;we are done (that was quick!)
|
|
|
|
:SHOW2 JSR RDLNSET ;setup for rdline
|
|
LDA REFNUM
|
|
STA SHWREF ;save refnum
|
|
|
|
* input line of data from a disk file
|
|
|
|
:SHOW3 BIT XTERNAL ;use external?
|
|
BMI :SHOW3X ;yep
|
|
|
|
LDA SHWIN
|
|
CMP #3
|
|
BGE :SHOW3A ;char device?, yep
|
|
|
|
:SHOW3X LDA SHWREF
|
|
STA REFNUM ;make sure refnum is correct
|
|
|
|
JSR RDLINE ;get char
|
|
BCC :SHOW4
|
|
JMP :SHOW5 ;opps, end of data
|
|
|
|
* input a line of data from a character device
|
|
|
|
:SHOW3A LDX #0 ;start pointer
|
|
:SHOW3B TXA
|
|
PHA
|
|
JSR DO_INP ;get data
|
|
CMP #eot
|
|
BNE :SHOW3C ;end of section?, nope
|
|
|
|
LDA #0 ;mark it
|
|
|
|
:SHOW3C STA LNBUF,X ;save
|
|
TAY
|
|
PLA
|
|
TAX
|
|
INX
|
|
|
|
CPY #0
|
|
BEQ :SHOW4 ;are we done?, yep
|
|
CPY #cr
|
|
BNE :SHOW3B ;end of line?, nope
|
|
|
|
* check for and handle ".x" external
|
|
|
|
LDA SHWOUT ;is it to the crt?
|
|
CMP #6
|
|
BGE :SHOW4 ;nope
|
|
|
|
LDA LNBUF ;is it a dot?
|
|
AND #clrhi
|
|
CMP #'.'
|
|
BNE :SHOW4 ;nope
|
|
|
|
LDA LNBUF+1 ;check for "X"
|
|
JSR CONV
|
|
CMP #'X'
|
|
BNE :SHOW4 ;nope
|
|
|
|
LDA LNBUF+2 ;is it a space?
|
|
AND #clrhi
|
|
CMP #' '
|
|
BNE :SHOW4 ;nope
|
|
|
|
JSR EXTERN ;set up external file
|
|
BIT XTERNAL
|
|
BMI :SHOW2 ;ok, file is open
|
|
|
|
* output a line of data to a device
|
|
|
|
:SHOW4 LDX #0 ;start pointer
|
|
:SHOW4A STX SHOW_X
|
|
LDA LNBUF,X ;get data
|
|
BEQ :SHOW5 ;we are done with file
|
|
|
|
AND #clrhi
|
|
CMP #lf
|
|
BEQ :SHOW4B ;strip all lf's
|
|
PHA
|
|
JSR DO_OUT ;output it
|
|
PLA
|
|
|
|
:SHOW4B LDX SHOW_X ;get back pointer
|
|
INX
|
|
CMP #cr
|
|
BNE :SHOW4A ;done with line?, nope
|
|
|
|
* handle end of line of output
|
|
|
|
LDA SHW_CNT ;is there a line limit?
|
|
BEQ :SHOW4C ;nope
|
|
|
|
DEC SHW_CNT
|
|
BEQ :SHOW5 ;count down lines, opps, that is all
|
|
|
|
:SHOW4C LDA SHWIN ;is this a read mail?
|
|
CMP #7
|
|
BEQ :JSHOW3 ;yep
|
|
|
|
LDA SHWOUT ;is output to the crt?
|
|
BNE :JSHOW3 ;nope
|
|
|
|
BIT INTOUT ;stop output?
|
|
BPL :JSHOW3 ;nope
|
|
|
|
* handle end of output and return
|
|
|
|
:SHOW5 BIT XTERNAL ;external on?
|
|
BMI :SHOW5B ;yep, close it
|
|
|
|
LDA SHWIN ;is this from a disk file?
|
|
BNE :SHOW6 ;nope
|
|
|
|
:SHOW5B LDA SHWREF
|
|
STA REFNUM ;get correct refnum
|
|
JSR CLOSE ;close file
|
|
BIT XTERNAL
|
|
BPL :SHOW6
|
|
|
|
INC XTERNAL ;turn off external
|
|
:JSHOW3 JMP :SHOW3 ;and continue
|
|
|
|
:SHOW6 LDA SHWOUT ;check destination
|
|
CMP #4 ;is it console, disk 1 or 2?
|
|
BLT EXTERN2 ;yep, don't send null, just return
|
|
|
|
LDA #0 ;were finished
|
|
JMP DO_OUT
|
|
|
|
EXTERN LDA #<LNBUF+3 ;point to filename
|
|
STA STRLOC
|
|
LDA #>LNBUF+3
|
|
STA STRLOC+1
|
|
LDA #19
|
|
STA STRLEN ;save max string length
|
|
JSR MOVNM0 ;move the filename
|
|
|
|
JSR IFOPEN ;open file
|
|
BCS EXTERN2 ;opps, file didn't open
|
|
|
|
DEC XTERNAL ;flag that external read is on
|
|
EXTERN2 RTS
|
|
|
|
SHWIN DB 0
|
|
SHWOUT DB 0
|
|
SHWREF DB 0
|
|
XTERNAL DB 0
|
|
|
|
*-------------------------------
|
|
* position into a file
|
|
*-------------------------------
|
|
|
|
DO_POS JSR GETDEV ;get device
|
|
JSR CHKDSK ;make sure it's a file
|
|
|
|
LDA REFTAB,Y
|
|
STA REFNUM ;save the reference number
|
|
|
|
JSR INPNUM ;get record length
|
|
STX FLPOS ;save rec length
|
|
STA FLPOS+1
|
|
|
|
JSR GOBCOM ;gobble comma
|
|
JSR INPNUM ;get record number
|
|
STX FLPOS+2 ;save rec number
|
|
STA FLPOS+3
|
|
|
|
LDA #0
|
|
STA FLPOS+4 ;default offset to 0
|
|
JSR CHKBYT
|
|
CMP #","
|
|
BNE :DO_POS2 ;check for last arg...
|
|
|
|
JSR GOBCOM ;gobble comma
|
|
JSR INPNUM
|
|
STX FLPOS+4 ;save byte offset
|
|
|
|
:DO_POS2 LDX FLPOS ;set up for multiply
|
|
LDA FLPOS+1
|
|
JSR SAVNUMB
|
|
|
|
LDA FLPOS+2
|
|
STA DATA+1
|
|
LDA FLPOS+3
|
|
STA DATA+2
|
|
|
|
JSR DO_MUL0
|
|
|
|
CLC
|
|
LDA FLPOS+4
|
|
ADC RESULT
|
|
TAX ;save low (X)
|
|
LDA #0 ;compute med (A)
|
|
ADC RESULT+1
|
|
LDY RESULT+2 ;get high (Y)
|
|
JMP SETPOS
|
|
|
|
*-------------------------------
|
|
* read data from device into memory
|
|
*-------------------------------
|
|
|
|
DO_READ JSR GETDEV
|
|
LDA INPVEC,X ;point to vector
|
|
STA VECTOR2
|
|
LDA INPVEC+1,X
|
|
STA VECTOR2+1
|
|
|
|
JSR INPNUM ;point to data
|
|
STX TEMP2
|
|
STA TEMP2+1
|
|
|
|
JSR GOBCOM ;gobble comma
|
|
JSR INPNUM ;get length of read
|
|
|
|
LDY #0
|
|
:DO_RD2 JSR DO_INP ;read data into memory
|
|
STA (TEMP2),Y
|
|
INY
|
|
DEX
|
|
BNE :DO_RD2
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* write data to a device
|
|
*-------------------------------
|
|
|
|
DO_WRIT JSR GETDEV
|
|
LDA OUTVEC,X ;set up vectors
|
|
STA VECTOR
|
|
LDA OUTVEC+1,X
|
|
STA VECTOR+1
|
|
|
|
JSR INPNUM ;point to data
|
|
STX TEMP2
|
|
STA TEMP2+1
|
|
|
|
JSR GOBCOM ;gobble comma
|
|
JSR INPNUM ;get length
|
|
|
|
LDY #0
|
|
:DO_WR2 LDA (TEMP2),Y ;write data
|
|
JSR DO_OUT
|
|
INY
|
|
DEX
|
|
BNE :DO_WR2
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* kill a file (or message)
|
|
*-------------------------------
|
|
|
|
DO_KILL JSR CHKBYT
|
|
CMP #"#"
|
|
BEQ :KILL2 ;kill message?, yep
|
|
|
|
JSR MOVNAME ;get filename
|
|
JMP DELFILE ;delete file
|
|
|
|
:KILL2 JSR GETDEV ;get msg number
|
|
LDX MSGNUM
|
|
LDA MSGNUM+1
|
|
JSR MSG
|
|
|
|
LDY #2 ;get first block into A & X
|
|
LDA (TEMP),Y
|
|
PHA
|
|
INY
|
|
LDA (TEMP),Y
|
|
PHA
|
|
|
|
LDA #0
|
|
STA (TEMP),Y ;zero pointers
|
|
DEY
|
|
STA (TEMP),Y
|
|
DEY
|
|
STA (TEMP),Y
|
|
DEY
|
|
STA (TEMP),Y
|
|
JSR WRTDIR ;write dir back to disk
|
|
|
|
PLA ;get high
|
|
TAY
|
|
PLA ;get low
|
|
TAX
|
|
TYA
|
|
|
|
:KILL3 STX MSGNUM ;save block number
|
|
STA MSGNUM+1
|
|
ORA MSGNUM ;done?
|
|
BEQ :KILL4 ;yep
|
|
|
|
LDA MSGNUM+1
|
|
JSR DEALLOC ;de-alloc block
|
|
|
|
LDX MSGNUM ;get block number
|
|
LDA MSGNUM+1
|
|
JSR SETBLK ;position to block
|
|
|
|
LDX #<LNBUF ;read in block
|
|
LDA #>LNBUF
|
|
LDY #1
|
|
JSR RDBLK
|
|
|
|
LDX LNBUF+126 ;get next block number
|
|
LDA LNBUF+127
|
|
JMP :KILL3 ;and repeat
|
|
|
|
:KILL4 JSR WRTBIT ;update bitmap
|
|
JMP FINISH ;write out dir info
|
|
|
|
*-------------------------------
|
|
* ready a message file
|
|
*-------------------------------
|
|
|
|
DO_RDY JSR CHKBYT ;do they want to ready a message?
|
|
CMP #"#"
|
|
BNE :DO_RDY0 ;nope
|
|
|
|
JMP GETDEV ;fix message
|
|
|
|
:DO_RDY0 LDA MSGREF ;get back old refnum
|
|
STA REFNUM
|
|
BEQ :DO_RDY1 ;file is closed
|
|
|
|
JSR CLOSE ;close old msgfile
|
|
|
|
:DO_RDY1 JSR MOVNAME ;get msg-file name
|
|
LDA FLNAME
|
|
BEQ :DO_RDY3 ;they are done with it
|
|
|
|
LDY #2 ;use msgfile buffer
|
|
JSR BFOPEN ;open file
|
|
BCS :DO_RDY4 ;hmmm, thats bad!
|
|
|
|
LDA REFNUM
|
|
STA MSGREF ;save refnum
|
|
|
|
LDY #0
|
|
:DO_RDY2 JSR RDBYTE ;read in info
|
|
STA MSGINFO,Y
|
|
INY
|
|
CPY #8
|
|
BNE :DO_RDY2
|
|
|
|
LDA #-1
|
|
STA DIRSEG ;no dir or bit seg loaded
|
|
STA BITSEG
|
|
STA DEVUSE+6
|
|
STA DEVUSE+7
|
|
:DO_RDY3 RTS
|
|
|
|
:DO_RDY4 LDX #nomsg ;message file not found
|
|
JMP BADERR
|
|
|
|
FINISH LDA MSGREF ;get refnum
|
|
STA REFNUM
|
|
LDX #0
|
|
TXA
|
|
JSR SETMARK
|
|
|
|
LDY #0
|
|
:FINISH2 LDA MSGINFO,Y ;write the info
|
|
JSR WRBYTE
|
|
INY
|
|
CPY #8
|
|
BNE :FINISH2
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* get new message info (or number of messages)
|
|
*-------------------------------
|
|
|
|
DO_MSG JSR INPNARG ;what message do they want to know about?
|
|
|
|
BIT IMMDEF ;is this an assignment [msg(x)=] ?
|
|
BMI :DO_MSG4 ;yep
|
|
|
|
CPX MSGINFO+4
|
|
BNE :DO_MSG2 ;is it the last message?, nope
|
|
CMP MSGINFO+5
|
|
BNE :DO_MSG2 ;nope
|
|
|
|
LDX MSGINFO+6 ;we don't need to load the dir to find out
|
|
LDA MSGINFO+7
|
|
JMP DO_MATH
|
|
|
|
:DO_MSG2 ORA NUMB ;do they want the number of files?
|
|
BNE :DO_MSG3 ;nope
|
|
|
|
LDX MSGINFO+4 ;get number of files
|
|
LDA MSGINFO+5
|
|
JMP DO_MATH
|
|
|
|
:DO_MSG3 JSR GETNUMB ;get message number
|
|
JSR MSG ;get info
|
|
|
|
LDY #0
|
|
LDA (TEMP),Y ;get new message # into a & x
|
|
TAX
|
|
INY
|
|
LDA (TEMP),Y
|
|
JMP DO_MATH ;finish up
|
|
|
|
:DO_MSG4 PHA ;save msg number
|
|
TXA
|
|
PHA
|
|
|
|
JSR GOBEQU ;gobble
|
|
JSR INPNUM ;get number
|
|
|
|
PLA ;get back msg number
|
|
TAX
|
|
PLA
|
|
|
|
CPX MSGINFO+4
|
|
BNE :DO_MSG5 ;is this last message?, nope
|
|
|
|
CMP MSGINFO+5
|
|
BNE :DO_MSG5 ;check high, nope
|
|
|
|
PHA ;save a and x
|
|
TXA
|
|
PHA
|
|
|
|
JSR GETNUMB ;update highest new message
|
|
STX MSGINFO+6
|
|
STA MSGINFO+7
|
|
JSR FINISH ;write info to disk
|
|
|
|
PLA ;restore a and x
|
|
TAX
|
|
PLA
|
|
|
|
:DO_MSG5 JSR MSG ;position to info
|
|
|
|
JSR GETNUMB ;get the new number
|
|
LDY #1
|
|
STA (TEMP),Y ;save new message number
|
|
DEY
|
|
TXA
|
|
STA (TEMP),Y
|
|
JMP WRTDIR ;write dir back to disk
|
|
|
|
*-------------------------------
|
|
* position and load directory for needed segment
|
|
* and setup pointers for needed entry
|
|
*-------------------------------
|
|
|
|
MSG DEX ;msg = msg - 1
|
|
CPX #-1
|
|
BNE :MSG1
|
|
|
|
SEC
|
|
SBC #1
|
|
|
|
:MSG1 STX TEMP ;save msg number
|
|
STX TEMP2
|
|
|
|
ASL TEMP2 ;compute dir section number
|
|
ROL
|
|
ASL ;a = a * 4
|
|
ASL ;make A into actual block number
|
|
CMP DIRSEG
|
|
BEQ :MSG2
|
|
|
|
STA DIRSEG ;save loaded dir seg number
|
|
CLC
|
|
ADC MSGINFO ;add in dir offset
|
|
|
|
TAX
|
|
LDA #0 ;we have starting block
|
|
JSR POSMSG ;position for read
|
|
|
|
LDX #<DIRBUF ;point to buffer
|
|
LDA #>DIRBUF
|
|
LDY #4 ;read 4 blocks
|
|
JSR RDBLK
|
|
|
|
:MSG2 LDA TEMP ;get msg number
|
|
ASL
|
|
ASL ;a = a * 4
|
|
STA TEMP
|
|
LDA #0 ;put last bit into a
|
|
ROL
|
|
CLC
|
|
ADC #>DIRBUF ;add in location of buffer
|
|
STA TEMP+1
|
|
RTS ;all is set up
|
|
|
|
*-------------------------------
|
|
* read a mail file
|
|
*-------------------------------
|
|
|
|
RDMAIL BIT DEVCLR ;is this start?
|
|
BMI :RDMAIL2 ;nope
|
|
|
|
STX BUF_X ;save x
|
|
LDX #4
|
|
:RDMAIL1 LDA MSGPTR,X
|
|
STA RWDPTR,X ;copy all 5 bytes
|
|
DEX
|
|
BPL :RDMAIL1 ;loop
|
|
|
|
LDX BUF_X
|
|
DEC DEVCLR ;clear change
|
|
:RDMAIL2 JMP RDMSG
|
|
|
|
*-------------------------------
|
|
* rewind file to previous spot
|
|
*-------------------------------
|
|
|
|
DO_RWD LDX RWDBLK ;get old block number
|
|
LDA RWDBLK+1
|
|
|
|
CPX RMXBLK
|
|
BNE :DO_RWD1 ;check low, nope
|
|
|
|
CMP RMXBLK+1
|
|
BEQ :DO_RWD2 ;check high, yep, it's the same
|
|
|
|
:DO_RWD1 STX RMXBLK ;update
|
|
STA RMXBLK+1
|
|
|
|
JSR SETBLK ;point to block
|
|
LDX #<BLKBUF ;read block back in
|
|
LDA #>BLKBUF
|
|
LDY #1
|
|
JSR RDBLK
|
|
|
|
:DO_RWD2 LDA RWDPTR
|
|
STA MSGPTR ;move pointers
|
|
LDA RWDBYT8
|
|
STA BYTE8
|
|
LDA RWDCHR8
|
|
STA CHAR8
|
|
RTS
|
|
|
|
* setup message for read
|
|
|
|
SETMSG LDA #-1
|
|
STA MSGINIT ;init message base
|
|
LDX MSGNUM ;get message number
|
|
LDA MSGNUM+1
|
|
JSR MSG ;locate message
|
|
|
|
LDY #2 ;get starting block number
|
|
LDA (TEMP),Y
|
|
TAX
|
|
INY
|
|
ORA (TEMP),Y ;check for no data...
|
|
BNE SETMSGX
|
|
JMP SETMSG2
|
|
|
|
SETMSGX LDA (TEMP),Y
|
|
SETMSG1 STX RMXBLK ;save current block number
|
|
STA RMXBLK+1
|
|
JSR SETBLK ;position and translate
|
|
|
|
LDA #0
|
|
STA RDEND ;reset end pointer
|
|
STA BLKBUF
|
|
LDX #<BLKBUF ;and read data
|
|
LDA #>BLKBUF
|
|
LDY #1
|
|
JSR RDBLK
|
|
|
|
LDY #0
|
|
STY MSGPTR ;reset pointer
|
|
LDA #6
|
|
STA BYTE8 ;reset hidden byte counter
|
|
LDX MSG_X ;get back x and y
|
|
LDY MSG_Y
|
|
|
|
* ... fall through and read a byte ...
|
|
|
|
*-------------------------------
|
|
* read a byte of message
|
|
*-------------------------------
|
|
|
|
RDMSG STX MSG_X ;save both x and y
|
|
STY MSG_Y
|
|
|
|
BIT MSGINIT ;is read in progress?
|
|
BPL SETMSG ;nope, start it
|
|
|
|
BIT RDEND ;at end of data?
|
|
BMI SETMSG2 ;yep
|
|
|
|
BIT BYTE8 ;check for hidden byte
|
|
BMI RDMSG2 ;do it
|
|
|
|
LDY MSGPTR ;get index
|
|
CPY #126
|
|
BEQ RDMSG3 ;need more data?, yep
|
|
|
|
LDA BLKBUF,Y ;get byte
|
|
ASL ;put extra bit into carry
|
|
BEQ RDMSG4 ;opps, end of data
|
|
ROR CHAR8 ;put carry into hidden byte
|
|
LSR ;fix byte
|
|
INC MSGPTR ;inc pointer
|
|
DEC BYTE8 ;count down for hidden byte
|
|
JMP SETMSG3
|
|
|
|
RDMSG2 LDA CHAR8 ;get hidden byte
|
|
LSR ;fix
|
|
BEQ RDMSG4
|
|
|
|
LDX #6
|
|
STX BYTE8 ;reset hidden byte counter
|
|
JMP SETMSG3
|
|
|
|
RDMSG3 LDA BLKBUF+126
|
|
TAX
|
|
ORA BLKBUF+127 ;is next block 0?
|
|
BEQ RDMSG4 ;yep
|
|
|
|
LDA BLKBUF+127
|
|
JMP SETMSG1 ;read next block
|
|
|
|
RDMSG4 DEC RDEND ;at end of data
|
|
|
|
SETMSG2 LDA #0 ;opps, no data
|
|
SETMSG3 LDX MSG_X ;get back data
|
|
LDY MSG_Y
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* setup message for write
|
|
*-------------------------------
|
|
|
|
WRTMSG LDX MSGNUM ;get msg number
|
|
LDA MSGNUM+1
|
|
|
|
CMP MSGINFO+5
|
|
BEQ WRTMSG0
|
|
BLT WRTMSG1
|
|
BGE WRTMSG5 ;is the meessage file this big?
|
|
|
|
WRTMSG0 CPX MSGINFO+4
|
|
BLT WRTMSG1
|
|
|
|
WRTMSG5 STX MSGINFO+4 ;update message count
|
|
STA MSGINFO+5
|
|
|
|
WRTMSG1 JSR MSG ;locate message
|
|
LDY #2
|
|
LDA (TEMP),Y
|
|
INY
|
|
ORA (TEMP),Y
|
|
BNE WRTMSG2
|
|
|
|
JSR ALLOC ;allocate new block
|
|
|
|
STX WRKBLK ;update block number
|
|
STA WRKBLK+1
|
|
|
|
LDY #3
|
|
STA (TEMP),Y
|
|
DEY
|
|
TXA
|
|
STA (TEMP),Y
|
|
JSR WRTDIR ;write dir back to disk
|
|
|
|
LDX MSG_X
|
|
DEC MSGINIT ;init msg
|
|
LDA #6
|
|
STA BYTE82 ;init byte counter
|
|
LDA #0
|
|
STA MSGPTR2 ;init message pointer
|
|
BEQ WRTMSG4
|
|
|
|
WRTMSG2 LDA BITSEG ;bitmap loaded?
|
|
CMP #-1
|
|
BNE WRTMSG2A ;yes
|
|
|
|
LDY #2 ;read in bitmap
|
|
LDA (TEMP),Y
|
|
TAX
|
|
INY
|
|
LDA (TEMP),Y
|
|
JSR GETBITS
|
|
|
|
WRTMSG2A JSR SWPBLK ;swap pointers
|
|
LDX MSG_X ;restore x and y
|
|
LDY MSG_Y
|
|
|
|
WRTMSG3 JSR RDMSG ;do append to current data
|
|
CMP #0
|
|
BNE WRTMSG3
|
|
|
|
JSR SWPBLK ;swap back
|
|
WRTMSG4 LDY MSG_Y
|
|
LDA #0
|
|
STA WRTEND ;let them write data
|
|
|
|
WRTMSG6 LDX MSG_X ;get back parms
|
|
LDY MSG_Y
|
|
PLA
|
|
|
|
* ... fall througn and write byte ...
|
|
|
|
*-------------------------------
|
|
* write a byte to a message
|
|
*-------------------------------
|
|
|
|
WRMSG PHA
|
|
STX MSG_X ;save x and y
|
|
STY MSG_Y
|
|
|
|
BIT MSGINIT ;have we started?
|
|
BMI WRMSG0A
|
|
JMP WRTMSG ;nope
|
|
|
|
WRMSG0A BIT WRTEND ;has end been written?
|
|
BMI WRMSG1B ;yep, take no more
|
|
|
|
BIT BYTE82 ;check for hidden byte
|
|
BMI WRMSG2 ;add it
|
|
|
|
LDY MSGPTR2 ;get index
|
|
CPY #126
|
|
BEQ WRMSG1 ;allocate new block?, yep
|
|
|
|
STA BLKBUF2,Y ;save data and continue
|
|
INC MSGPTR2
|
|
DEC BYTE82 ;count down hidden byte
|
|
CMP #0
|
|
BNE WRMSG4
|
|
|
|
WRMSG0 LDX #0
|
|
STX BLKBUF2+126 ;no link
|
|
STX BLKBUF2+127
|
|
JMP WRMSG1A ;skip around link setup
|
|
|
|
WRMSG1 JSR ALLOC ;allocate new block
|
|
STX BLKBUF2+126
|
|
STA BLKBUF2+127
|
|
|
|
WRMSG1A LDX WRKBLK ;translate and position block
|
|
LDA WRKBLK+1
|
|
JSR SETBLK
|
|
|
|
LDX #<BLKBUF2 ;write the block
|
|
LDA #>BLKBUF2
|
|
LDY #1
|
|
JSR WRBLK
|
|
|
|
LDA #0
|
|
STA MSGPTR2 ;reset pointer
|
|
LDA #6
|
|
STA BYTE82 ;reset hidden counter
|
|
|
|
LDA BLKBUF2+126 ;save new block number
|
|
STA WRKBLK
|
|
LDA BLKBUF2+127
|
|
STA WRKBLK+1
|
|
ORA WRKBLK ;is there another block?
|
|
BNE WRTMSG6 ;yep
|
|
|
|
JSR WRTBIT ;write out bitmap
|
|
JSR FINISH ;write out info
|
|
DEC WRTEND ;end has been written
|
|
LDX MSG_X
|
|
LDY MSG_Y
|
|
WRMSG1B PLA
|
|
RTS
|
|
|
|
WRMSG2 LDX MSGPTR2
|
|
LDY #7
|
|
ASL
|
|
WRMSG3 DEX
|
|
ROL BLKBUF2,X ;add in bit 7
|
|
ASL
|
|
ROR BLKBUF2,X
|
|
DEY
|
|
BNE WRMSG3
|
|
|
|
LDX #6
|
|
STX BYTE82
|
|
PLA ;get back byte
|
|
PHA
|
|
BEQ WRMSG0
|
|
|
|
WRMSG4 LDX MSG_X ;restore x and y
|
|
LDY MSG_Y
|
|
PLA
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* allocate a block for data
|
|
*-------------------------------
|
|
|
|
ALLOC LDA BITSEG ;fresh start?
|
|
CMP #$FF
|
|
BEQ :ALLOC4 ;yep
|
|
|
|
LDY #0 ;start count
|
|
:ALLOC2 LDX #0
|
|
:ALLOC3 LDA BITBUF,Y ;search for free block
|
|
AND BITVAL,X
|
|
BEQ :ALLOC5 ;found one
|
|
|
|
INX ;done with byte?
|
|
CPX #8
|
|
BNE :ALLOC3 ;nope
|
|
INY
|
|
BPL :ALLOC2 ;done with buffer?, nope
|
|
|
|
JSR WRTBIT ;write bit map back to disk
|
|
|
|
:ALLOC4 INC BITSEG ;is there more space?
|
|
JSR RDBIT ;read in bit map segment
|
|
JMP ALLOC ;start (keep) looking
|
|
|
|
:ALLOC5 LDA BITBUF,Y
|
|
ORA BITVAL,X ;mark byte
|
|
STA BITBUF,Y
|
|
|
|
STY TEMP2 ;shift Y into 16 bits
|
|
LDA #0 ;bit16 = y * 8
|
|
ASL TEMP2
|
|
ROL
|
|
ASL TEMP2
|
|
ROL
|
|
ASL TEMP2
|
|
ROL
|
|
STA TEMP2+1
|
|
|
|
TXA ;add in x
|
|
SEC ;special (+1)
|
|
ADC TEMP2 ;bit16 = bit16 + x + 1
|
|
TAX
|
|
LDA #0
|
|
ADC TEMP2+1
|
|
STA TEMP2+1
|
|
|
|
LDA BITSEG ;add in segment
|
|
ASL
|
|
ASL ;a = a * 4
|
|
CLC
|
|
ADC TEMP2+1 ;bit16 = bit16 + a
|
|
|
|
INC MSGINFO+2
|
|
BNE :ALLOC6 ;add 1 to used blocks
|
|
INC MSGINFO+3
|
|
:ALLOC6 RTS
|
|
|
|
*-------------------------------
|
|
* de-alloc
|
|
*-------------------------------
|
|
|
|
DEALLOC JSR GETBITS
|
|
|
|
LDA TEMP ;shift down temp 3 bits into A
|
|
LSR TEMP+1
|
|
ROR
|
|
LSR TEMP+1
|
|
ROR
|
|
LSR
|
|
TAY
|
|
|
|
LDX TEMP2 ;get bit offset
|
|
LDA BITVAL,X
|
|
EOR #$FF
|
|
AND BITBUF,Y ;clear bit
|
|
STA BITBUF,Y ;and save
|
|
|
|
LDA MSGINFO+2 ;used blocks = used blocks -1
|
|
BNE :DEALL3
|
|
DEC MSGINFO+3
|
|
:DEALL3 DEC MSGINFO+2
|
|
RTS
|
|
|
|
* read in bitmap, save old one (if any)
|
|
|
|
GETBITS SEC
|
|
PHA
|
|
TXA
|
|
SBC #1
|
|
STA TEMP
|
|
AND #%00000111
|
|
STA TEMP2 ;save offset (in bits)
|
|
PLA
|
|
SBC #0
|
|
STA TEMP+1 ;temp = (AX)-1
|
|
|
|
LSR
|
|
LSR ;a = a / 4
|
|
|
|
CMP BITSEG
|
|
BEQ :DEALL2 ;are we in position?, yep
|
|
|
|
PHA
|
|
LDA BITSEG ;first access to bitmap?
|
|
CMP #$FF
|
|
BEQ :DEALL1 ;yep, done write
|
|
|
|
JSR WRTBIT ;hmmm, write out current bitmap
|
|
:DEALL1 PLA
|
|
STA BITSEG ;update segment
|
|
JSR RDBIT ;read bit map
|
|
:DEALL2 RTS
|
|
|
|
* read bit map from disk
|
|
|
|
RDBIT LDX BITSEG
|
|
LDA #0
|
|
JSR POSMSG ;position to block
|
|
|
|
LDX #<BITBUF ;read in block
|
|
LDA #>BITBUF
|
|
LDY #1
|
|
JMP RDBLK
|
|
|
|
* write bit map back to disk
|
|
|
|
WRTBIT LDX BITSEG ;position to block
|
|
LDA #0
|
|
JSR POSMSG
|
|
|
|
LDX #<BITBUF ;write current block out
|
|
LDA #>BITBUF
|
|
LDY #1
|
|
JMP WRBLK
|
|
|
|
*-------------------------------
|
|
* position to false block number
|
|
*-------------------------------
|
|
|
|
SETBLK STX POSBLK ;save block number
|
|
STA POSBLK+1
|
|
CLC
|
|
LDA MSGINFO ;a = msginfo + msginfo(1)
|
|
ADC MSGINFO+1
|
|
SEC ;a = a - 1
|
|
SBC #1
|
|
CLC
|
|
ADC POSBLK ;blk = blk + a
|
|
TAX
|
|
LDA POSBLK+1
|
|
ADC #0
|
|
JMP POSMSG
|
|
|
|
*-------------------------------
|
|
* write the current directory segment back to disk
|
|
*-------------------------------
|
|
|
|
WRTDIR CLC
|
|
LDA DIRSEG ;position to dir segment
|
|
ADC MSGINFO
|
|
TAX
|
|
LDA #0
|
|
JSR POSMSG
|
|
|
|
SEC
|
|
LDA MSGINFO+1 ;get # of dir blocks
|
|
SBC DIRSEG ;subtract current pointer
|
|
CMP #4
|
|
BLT :WRTDIR1 ;there are less than 4 blocks left
|
|
LDA #4 ;there are more - only write 4
|
|
|
|
:WRTDIR1 TAY ;# of blocks to write
|
|
LDX #<DIRBUF ;write it
|
|
LDA #>DIRBUF
|
|
JMP WRBLK
|
|
|
|
*-------------------------------
|
|
* switch block buffers
|
|
*-------------------------------
|
|
|
|
SWPBLK LDY #127
|
|
:SWPBLK2 LDA BLKBUF,Y ;get buf 1 char
|
|
PHA ;save
|
|
LDA BLKBUF2,Y
|
|
STA BLKBUF,Y ;get buf 2 char, put in buf 1
|
|
PLA
|
|
STA BLKBUF2,Y ;restore buf 1 char, put in buf 2
|
|
DEY
|
|
BPL :SWPBLK2 ;loop
|
|
|
|
LDY #5
|
|
:SWPBLK3 LDA MSGPTR,Y ;swap pointers
|
|
PHA
|
|
LDA MSGPTR2,Y
|
|
STA MSGPTR,Y
|
|
PLA
|
|
STA MSGPTR2,Y
|
|
DEY
|
|
BPL :SWPBLK3
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* create a file
|
|
*-------------------------------
|
|
|
|
DO_MAKE JSR MOVNAME ;get filename
|
|
LDY #txt ;TEXT
|
|
LDA #<notype
|
|
LDX #>notype
|
|
JMP CREATE ;create it
|
|
|
|
*-------------------------------
|
|
* crunch a message file
|
|
*-------------------------------
|
|
|
|
DO_CNCH LDX #$FF
|
|
STX DIRSEG
|
|
STX DIRSEG+1 ;load in first dir block
|
|
INX
|
|
STX MSGINFO+4 ;reset number of msg's
|
|
STX MSGINFO+5
|
|
LDX #128
|
|
LDY #128
|
|
|
|
:CRUNCH2 CPX #128
|
|
BEQ :CRUNCH3 ;at end of block?
|
|
|
|
LDA DIRSEG ;more data?
|
|
CMP MSGINFO+1
|
|
BEQ :CRUNCH7 ;yep
|
|
|
|
LDA DIRBUF+2,X ;is there any entry?
|
|
ORA DIRBUF+3,X
|
|
BNE :CRUNCH4 ;yep
|
|
|
|
INX ;x = x + 4
|
|
INX
|
|
INX
|
|
INX
|
|
BPL :CRUNCH2 ;keep going until 128 done
|
|
|
|
:CRUNCH3 INC DIRSEG
|
|
LDX #0
|
|
LDA DIRSEG ;are we done?
|
|
CMP MSGINFO+1
|
|
BEQ :CRUNCH2 ;yep
|
|
|
|
STY SAVE_Y ;save Y
|
|
CLC
|
|
ADC MSGINFO ;add in bitmap offset
|
|
TAX
|
|
LDA #0
|
|
JSR POSMSG ;position
|
|
|
|
LDX #<DIRBUF ;read next dir block
|
|
LDA #>DIRBUF
|
|
LDY #1
|
|
JSR RDBLK
|
|
|
|
LDY SAVE_Y ;restore Y
|
|
LDX #0
|
|
BEQ :CRUNCH2 ;keep going
|
|
|
|
:CRUNCH7 LDX #0
|
|
STX DIRBUF ;use 0 offset
|
|
STX DIRBUF+1
|
|
STX DIRBUF+2 ;zero pointers
|
|
STX DIRBUF+3
|
|
|
|
:CRUNCH4 CPY #128
|
|
BEQ :CRUNCH6 ;at end of block?, yep
|
|
|
|
:CRUNCH5 LDA DIRSEG ;are we at end?
|
|
CMP MSGINFO+1
|
|
BEQ :CRUNCH6 ;yep
|
|
|
|
INC MSGINFO+4
|
|
BNE :CRUNCH5A ;add one to message count
|
|
INC MSGINFO+5
|
|
|
|
:CRUNCH5A LDA DIRBUF,X
|
|
STA MSGINFO+6 ;copy byte
|
|
STA DIRBUF+128,Y ;and save in new message field
|
|
INX
|
|
INY
|
|
|
|
LDA DIRBUF,X
|
|
STA MSGINFO+7 ;copy other byte
|
|
STA DIRBUF+128,Y ;and save in new message field
|
|
INX
|
|
INY
|
|
|
|
LDA DIRBUF,X
|
|
STA DIRBUF+128,Y ;copy byte
|
|
INX
|
|
INY
|
|
LDA DIRBUF,X
|
|
STA DIRBUF+128,Y ;copy byte
|
|
INX
|
|
INY
|
|
|
|
JMP :CRUNCH2
|
|
|
|
:CRUNCH6 LDA DIRSEG+1 ;do we want to write this?
|
|
CMP #$FF
|
|
BEQ :CRUNCH8 ;nope
|
|
|
|
STX SAVE_X ;save x
|
|
CLC
|
|
ADC MSGINFO ;add in bitmap
|
|
TAX
|
|
LDA #0
|
|
JSR POSMSG ;position
|
|
|
|
LDX #<DIRBUF+128 ;write out dir segment
|
|
LDA #>DIRBUF+128
|
|
LDY #1
|
|
JSR WRBLK
|
|
|
|
LDX SAVE_X ;restore x
|
|
LDY #128
|
|
:CRUNCH8 LDA #0
|
|
:CRUNCH9 STA DIRBUF+127,Y ;fill buffer with 0's
|
|
DEY
|
|
BNE :CRUNCH9
|
|
|
|
INC DIRSEG+1 ;use next segment
|
|
TAY
|
|
LDA DIRSEG+1
|
|
CMP MSGINFO+1
|
|
BNE :CRUNCH5 ;are we at end?, nope
|
|
|
|
JSR FINISH ;write out 8 byte header
|
|
LDA #$FF
|
|
STA DIRSEG ;reset dir segment
|
|
RTS
|
|
|
|
*-------------------------------
|
|
* update a file back to disk
|
|
*-------------------------------
|
|
|
|
DO_UP LDA MSGREF ;use msg refnum
|
|
STA REFNUM
|
|
JMP FLUSH ;flush file back to disk
|
|
|
|
*-------------------------------
|
|
* use an external command
|
|
*-------------------------------
|
|
|
|
DO_USE LDA MSGREF ;get back old refnum
|
|
STA REFNUM
|
|
BEQ :DO_USE1 ;file is closed
|
|
|
|
JSR CLOSE ;close old msgfile
|
|
|
|
LDA #0
|
|
STA MSGREF
|
|
|
|
:DO_USE1 LDY #0
|
|
JSR SETIVEC ;set to default input/output
|
|
JSR SETOVEC
|
|
|
|
JSR MOVNAME ;setup filename
|
|
JSR OPEN ;open file
|
|
BCS :DO_USE2
|
|
|
|
LDX #<ENDMOD
|
|
LDA #>ENDMOD
|
|
LDY #32 ;read 32 - 128 byte pages (4k)
|
|
JSR RDBLK
|
|
|
|
JSR CLOSE ;finish up
|
|
JMP ENDMOD ;exec external routine
|
|
|
|
:DO_USE2 LDX #badxtrn ;unable to load external
|
|
JMP BADERR
|
|
|
|
|