mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-08-09 01:25:00 +00:00
Fix resetmemfiles, use heap for catalog/volumes, and free CMD init code
This commit is contained in:
@@ -42,6 +42,6 @@ fin
|
|||||||
*jitcomp = @compiler
|
*jitcomp = @compiler
|
||||||
cmdsys.jitcount = 44
|
cmdsys.jitcount = 44
|
||||||
cmdsys.jitsize = 96
|
cmdsys.jitsize = 96
|
||||||
puts("JITC")
|
puts("JITC enabled\n")
|
||||||
return modkeep
|
return modkeep
|
||||||
done
|
done
|
||||||
|
@@ -48,6 +48,6 @@ fin
|
|||||||
*jitcomp = @compiler
|
*jitcomp = @compiler
|
||||||
cmdsys.jitcount = 44
|
cmdsys.jitcount = 44
|
||||||
cmdsys.jitsize = 96
|
cmdsys.jitsize = 96
|
||||||
puts("16-bit VM/JITC")
|
puts("16-bit VM/JITC enabled\n")
|
||||||
return modkeep
|
return modkeep
|
||||||
done
|
done
|
||||||
|
@@ -98,7 +98,7 @@ export def mouseInit
|
|||||||
//
|
//
|
||||||
// Hook mouse IRQ handler into ProDOS IRQ chain
|
// Hook mouse IRQ handler into ProDOS IRQ chain
|
||||||
//
|
//
|
||||||
puts("serviceMouse @ $"); puth(@serviceMouse); putln; getc
|
puts("serviceMouse @ $"); puth(@serviceMouse); putln
|
||||||
params.0 = 2
|
params.0 = 2
|
||||||
params.1 = 0
|
params.1 = 0
|
||||||
params:2 = @serviceMouse
|
params:2 = @serviceMouse
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
const MACHID = $BF98
|
const MACHID = $BF98
|
||||||
const iobuffer = $0800
|
const iobuffer = $0800
|
||||||
const databuff = $2000
|
|
||||||
const RELADDR = $1000
|
const RELADDR = $1000
|
||||||
const symtbl = $0C00
|
const symtbl = $0C00
|
||||||
const freemem = $0006
|
const freemem = $0006
|
||||||
@@ -1157,9 +1156,9 @@ def volumes()#0
|
|||||||
|
|
||||||
params.0 = 2
|
params.0 = 2
|
||||||
params.1 = 0
|
params.1 = 0
|
||||||
params:2 = databuff
|
params:2 = heap
|
||||||
perr = syscall($C5, @params)
|
perr = syscall($C5, @params)
|
||||||
strbuf = databuff
|
strbuf = heap
|
||||||
for i = 0 to 15
|
for i = 0 to 15
|
||||||
^strbuf = ^strbuf & $0F
|
^strbuf = ^strbuf & $0F
|
||||||
if ^strbuf
|
if ^strbuf
|
||||||
@@ -1184,12 +1183,12 @@ def catalog(path)#0
|
|||||||
fin
|
fin
|
||||||
firstblk = 1
|
firstblk = 1
|
||||||
repeat
|
repeat
|
||||||
if read(refnum, databuff, 512) == 512
|
if read(refnum, heap, 512) == 512
|
||||||
entry = databuff + 4
|
entry = heap + 4
|
||||||
if firstblk
|
if firstblk
|
||||||
entrylen = databuff.$23
|
entrylen = heap->$23
|
||||||
entriesblk = databuff.$24
|
entriesblk = heap->$24
|
||||||
filecnt = databuff:$25
|
filecnt = heap=>$25
|
||||||
entry = entry + entrylen
|
entry = entry + entrylen
|
||||||
fin
|
fin
|
||||||
for i = firstblk to entriesblk
|
for i = firstblk to entriesblk
|
||||||
@@ -1272,7 +1271,7 @@ def resetmemfiles()#0
|
|||||||
//
|
//
|
||||||
// Close all files
|
// Close all files
|
||||||
//
|
//
|
||||||
^$BFD8 = 0
|
^$BF94 = 0
|
||||||
close(0)
|
close(0)
|
||||||
//
|
//
|
||||||
// Set memory bitmap
|
// Set memory bitmap
|
||||||
@@ -1291,7 +1290,7 @@ def execsys(sysfile)#0
|
|||||||
striptrail(sysfile)
|
striptrail(sysfile)
|
||||||
refnum = open(sysfile)
|
refnum = open(sysfile)
|
||||||
if refnum
|
if refnum
|
||||||
len = read(refnum, databuff, $FFFF)
|
len = read(refnum, $2000, $FFFF)
|
||||||
resetmemfiles()
|
resetmemfiles()
|
||||||
if len
|
if len
|
||||||
strcpy(sysfile, $280)
|
strcpy(sysfile, $280)
|
||||||
@@ -1326,13 +1325,68 @@ def execmod(modfile)#1
|
|||||||
return -perr
|
return -perr
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
|
// Command line processor
|
||||||
|
//
|
||||||
|
def docmds#0
|
||||||
|
while 1
|
||||||
|
if ^getlnbuf
|
||||||
|
strcpy(@cmdln, getlnbuf)
|
||||||
|
when toupper(parsecmd(getlnbuf))
|
||||||
|
is 'C'
|
||||||
|
catalog(getlnbuf)
|
||||||
|
break
|
||||||
|
is 'P'
|
||||||
|
pfxop(getlnbuf, SET_PFX)
|
||||||
|
break
|
||||||
|
is '/'
|
||||||
|
repeat
|
||||||
|
prefix--
|
||||||
|
until prefix[prefix] == '/'
|
||||||
|
if prefix > 1
|
||||||
|
pfxop(@prefix, SET_PFX)
|
||||||
|
fin
|
||||||
|
break
|
||||||
|
is 'V'
|
||||||
|
volumes()
|
||||||
|
break
|
||||||
|
is '-'
|
||||||
|
execsys(getlnbuf)
|
||||||
|
break
|
||||||
|
is '+'
|
||||||
|
execmod(striptrail(getlnbuf))
|
||||||
|
//
|
||||||
|
// Clean up
|
||||||
|
//
|
||||||
|
resetmemfiles
|
||||||
|
break
|
||||||
|
otherwise
|
||||||
|
cout('?')
|
||||||
|
wend
|
||||||
|
if perr
|
||||||
|
prstr("ERR:$")
|
||||||
|
prbyte(perr)
|
||||||
|
else
|
||||||
|
prstr("OK")
|
||||||
|
fin
|
||||||
|
crout()
|
||||||
|
fin
|
||||||
|
prstr(pfxop(@prefix, GET_PFX))
|
||||||
|
rdstr($BA)
|
||||||
|
loop
|
||||||
|
end
|
||||||
|
//
|
||||||
|
// Dummy definition to get free heap
|
||||||
|
//
|
||||||
|
def lastdef#0
|
||||||
|
end
|
||||||
|
//
|
||||||
// Get heap start.
|
// Get heap start.
|
||||||
//
|
//
|
||||||
heap = *freemem
|
heap = @lastdef
|
||||||
//
|
//
|
||||||
// Print PLASMA version
|
// Print PLASMA version
|
||||||
//
|
//
|
||||||
prstr("PLASMA 2.0 Dev 64K \n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout
|
prstr("PLASMA 2.0 Dev 64K\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout
|
||||||
//
|
//
|
||||||
// Init symbol table.
|
// Init symbol table.
|
||||||
//
|
//
|
||||||
@@ -1361,49 +1415,5 @@ else
|
|||||||
prstr("MEM FREE:$"); prword(availheap); crout
|
prstr("MEM FREE:$"); prword(availheap); crout
|
||||||
fin
|
fin
|
||||||
perr = 0
|
perr = 0
|
||||||
while 1
|
docmds
|
||||||
if ^getlnbuf
|
|
||||||
strcpy(@cmdln, getlnbuf)
|
|
||||||
when toupper(parsecmd(getlnbuf))
|
|
||||||
is 'C'
|
|
||||||
catalog(getlnbuf)
|
|
||||||
break
|
|
||||||
is 'P'
|
|
||||||
pfxop(getlnbuf, SET_PFX)
|
|
||||||
break
|
|
||||||
is '/'
|
|
||||||
repeat
|
|
||||||
prefix--
|
|
||||||
until prefix[prefix] == '/'
|
|
||||||
if prefix > 1
|
|
||||||
pfxop(@prefix, SET_PFX)
|
|
||||||
fin
|
|
||||||
break
|
|
||||||
is 'V'
|
|
||||||
volumes()
|
|
||||||
break
|
|
||||||
is '-'
|
|
||||||
execsys(getlnbuf)
|
|
||||||
break
|
|
||||||
is '+'
|
|
||||||
execmod(striptrail(getlnbuf))
|
|
||||||
//
|
|
||||||
// Clean up
|
|
||||||
//
|
|
||||||
resetmemfiles
|
|
||||||
break
|
|
||||||
otherwise
|
|
||||||
cout(perr)//cout('?')
|
|
||||||
wend
|
|
||||||
if perr
|
|
||||||
prstr("ERR:$")
|
|
||||||
prbyte(perr)
|
|
||||||
else
|
|
||||||
prstr("OK")
|
|
||||||
fin
|
|
||||||
crout()
|
|
||||||
fin
|
|
||||||
prstr(pfxop(@prefix, GET_PFX))
|
|
||||||
rdstr($BA)
|
|
||||||
loop
|
|
||||||
done
|
done
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
const MACHID = $BF98
|
const MACHID = $BF98
|
||||||
const iobuffer = $0800
|
const iobuffer = $0800
|
||||||
const databuff = $2000
|
|
||||||
const RELADDR = $1000
|
const RELADDR = $1000
|
||||||
const symtbl = $0C00
|
const symtbl = $0C00
|
||||||
const freemem = $0006
|
const freemem = $0006
|
||||||
@@ -1221,9 +1220,9 @@ def volumes()#0
|
|||||||
|
|
||||||
params.0 = 2
|
params.0 = 2
|
||||||
params.1 = 0
|
params.1 = 0
|
||||||
params:2 = databuff
|
params:2 = heap
|
||||||
perr = syscall($C5, @params)
|
perr = syscall($C5, @params)
|
||||||
strbuf = databuff
|
strbuf = heap
|
||||||
for i = 0 to 15
|
for i = 0 to 15
|
||||||
^strbuf = ^strbuf & $0F
|
^strbuf = ^strbuf & $0F
|
||||||
if ^strbuf
|
if ^strbuf
|
||||||
@@ -1248,12 +1247,12 @@ def catalog(path)#0
|
|||||||
fin
|
fin
|
||||||
firstblk = 1
|
firstblk = 1
|
||||||
repeat
|
repeat
|
||||||
if read(refnum, databuff, 512) == 512
|
if read(refnum, heap, 512) == 512
|
||||||
entry = databuff + 4
|
entry = heap + 4
|
||||||
if firstblk
|
if firstblk
|
||||||
entrylen = databuff.$23
|
entrylen = heap->$23
|
||||||
entriesblk = databuff.$24
|
entriesblk = heap->$24
|
||||||
filecnt = databuff:$25
|
filecnt = heap=>$25
|
||||||
entry = entry + entrylen
|
entry = entry + entrylen
|
||||||
fin
|
fin
|
||||||
for i = firstblk to entriesblk
|
for i = firstblk to entriesblk
|
||||||
@@ -1336,7 +1335,7 @@ def resetmemfiles()#0
|
|||||||
//
|
//
|
||||||
// Close all files
|
// Close all files
|
||||||
//
|
//
|
||||||
^$BFD8 = 0
|
^$BF94 = 0
|
||||||
close(0)
|
close(0)
|
||||||
//
|
//
|
||||||
// Set memory bitmap
|
// Set memory bitmap
|
||||||
@@ -1355,7 +1354,7 @@ def execsys(sysfile)#0
|
|||||||
striptrail(sysfile)
|
striptrail(sysfile)
|
||||||
refnum = open(sysfile)
|
refnum = open(sysfile)
|
||||||
if refnum
|
if refnum
|
||||||
len = read(refnum, databuff, $FFFF)
|
len = read(refnum, $2000, $FFFF)
|
||||||
resetmemfiles()
|
resetmemfiles()
|
||||||
if len
|
if len
|
||||||
strcpy(sysfile, $280)
|
strcpy(sysfile, $280)
|
||||||
@@ -1394,13 +1393,71 @@ def execmod(modfile)#1
|
|||||||
return -perr
|
return -perr
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
|
// Command line processor
|
||||||
|
//
|
||||||
|
def docmds#0
|
||||||
|
loadmod(jitmod) // Cannot do this in init code - it will overwrite it!
|
||||||
|
xheap = $0400 // Reset heap to point at low memory
|
||||||
|
xheaptop = $A000 // Top below JITC
|
||||||
|
while 1
|
||||||
|
if ^getlnbuf
|
||||||
|
strcpy(@cmdln, getlnbuf)
|
||||||
|
when toupper(parsecmd(getlnbuf))
|
||||||
|
is 'C'
|
||||||
|
catalog(getlnbuf)
|
||||||
|
break
|
||||||
|
is 'P'
|
||||||
|
pfxop(getlnbuf, SET_PFX)
|
||||||
|
break
|
||||||
|
is '/'
|
||||||
|
repeat
|
||||||
|
prefix--
|
||||||
|
until prefix[prefix] == '/'
|
||||||
|
if prefix > 1
|
||||||
|
pfxop(@prefix, SET_PFX)
|
||||||
|
fin
|
||||||
|
break
|
||||||
|
is 'V'
|
||||||
|
volumes()
|
||||||
|
break
|
||||||
|
is '-'
|
||||||
|
execsys(getlnbuf)
|
||||||
|
break
|
||||||
|
is '+'
|
||||||
|
execmod(striptrail(getlnbuf))
|
||||||
|
//
|
||||||
|
// Clean up
|
||||||
|
//
|
||||||
|
resetmemfiles
|
||||||
|
break
|
||||||
|
otherwise
|
||||||
|
cout('?')
|
||||||
|
wend
|
||||||
|
if perr
|
||||||
|
prstr("ERR:$")
|
||||||
|
prbyte(perr)
|
||||||
|
else
|
||||||
|
prstr("OK")
|
||||||
|
fin
|
||||||
|
crout()
|
||||||
|
fin
|
||||||
|
prstr(pfxop(@prefix, GET_PFX))
|
||||||
|
rdstr($BA)
|
||||||
|
loop
|
||||||
|
end
|
||||||
|
//
|
||||||
|
// Dummy definition to get free heap
|
||||||
|
//
|
||||||
|
def lastdef#0
|
||||||
|
end
|
||||||
|
//
|
||||||
// Get heap start.
|
// Get heap start.
|
||||||
//
|
//
|
||||||
heap = *freemem
|
heap = @lastdef
|
||||||
//
|
//
|
||||||
// Print PLASMA version
|
// Print PLASMA version
|
||||||
//
|
//
|
||||||
prstr("PLASMA 2.0 Dev 128K ")//; prbyte(version.1); cout('.'); prbyte(version.0); crout
|
prstr("PLASMA 2.0 Dev 128K\n")//; prbyte(version.1); cout('.'); prbyte(version.0); crout
|
||||||
//
|
//
|
||||||
// Init symbol table.
|
// Init symbol table.
|
||||||
//
|
//
|
||||||
@@ -1415,9 +1472,6 @@ loop
|
|||||||
strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD
|
strcat(strcpy(@sysmods, $280), "SYS/")) // This is the path to CMD
|
||||||
syspath = @sysmods // Update external interface table
|
syspath = @sysmods // Update external interface table
|
||||||
syscmdln = @cmdln
|
syscmdln = @cmdln
|
||||||
loadmod(jitmod)
|
|
||||||
xheap = $0400 // Reset heap to point at low memory
|
|
||||||
xheaptop = $A000 // Top where JIT loaded
|
|
||||||
//
|
//
|
||||||
// Try to load autorun.
|
// Try to load autorun.
|
||||||
//
|
//
|
||||||
@@ -1429,52 +1483,8 @@ else
|
|||||||
//
|
//
|
||||||
// Print some startup info.
|
// Print some startup info.
|
||||||
//
|
//
|
||||||
prstr("\nMEM FREE:$"); prword(availheap); crout
|
prstr("MEM FREE:$"); prword(availheap); crout
|
||||||
fin
|
fin
|
||||||
perr = 0
|
perr = 0
|
||||||
while 1
|
docmds
|
||||||
if ^getlnbuf
|
|
||||||
strcpy(@cmdln, getlnbuf)
|
|
||||||
when toupper(parsecmd(getlnbuf))
|
|
||||||
is 'C'
|
|
||||||
catalog(getlnbuf)
|
|
||||||
break
|
|
||||||
is 'P'
|
|
||||||
pfxop(getlnbuf, SET_PFX)
|
|
||||||
break
|
|
||||||
is '/'
|
|
||||||
repeat
|
|
||||||
prefix--
|
|
||||||
until prefix[prefix] == '/'
|
|
||||||
if prefix > 1
|
|
||||||
pfxop(@prefix, SET_PFX)
|
|
||||||
fin
|
|
||||||
break
|
|
||||||
is 'V'
|
|
||||||
volumes()
|
|
||||||
break
|
|
||||||
is '-'
|
|
||||||
execsys(getlnbuf)
|
|
||||||
break
|
|
||||||
is '+'
|
|
||||||
execmod(striptrail(getlnbuf))
|
|
||||||
//
|
|
||||||
// Clean up
|
|
||||||
//
|
|
||||||
resetmemfiles
|
|
||||||
break
|
|
||||||
otherwise
|
|
||||||
cout('?')
|
|
||||||
wend
|
|
||||||
if perr
|
|
||||||
prstr("ERR:$")
|
|
||||||
prbyte(perr)
|
|
||||||
else
|
|
||||||
prstr("OK")
|
|
||||||
fin
|
|
||||||
crout()
|
|
||||||
fin
|
|
||||||
prstr(pfxop(@prefix, GET_PFX))
|
|
||||||
rdstr($BA)
|
|
||||||
loop
|
|
||||||
done
|
done
|
||||||
|
@@ -27,10 +27,6 @@ JITCODE = $03E4
|
|||||||
INC DSTH
|
INC DSTH
|
||||||
DEX ; STOP WHEN DST=$2000 REACHED
|
DEX ; STOP WHEN DST=$2000 REACHED
|
||||||
BNE -
|
BNE -
|
||||||
LDA #<_CMDEND
|
|
||||||
STA SRCL
|
|
||||||
LDA #>_CMDEND
|
|
||||||
STA SRCH
|
|
||||||
;
|
;
|
||||||
; INIT VM ENVIRONMENT STACK POINTERS
|
; INIT VM ENVIRONMENT STACK POINTERS
|
||||||
;
|
;
|
||||||
|
@@ -25,10 +25,6 @@ LCBNK1 = $08
|
|||||||
INC DSTH
|
INC DSTH
|
||||||
DEX ; STOP WHEN DST=$2000 REACHED
|
DEX ; STOP WHEN DST=$2000 REACHED
|
||||||
BNE -
|
BNE -
|
||||||
LDA #<_CMDEND
|
|
||||||
STA SRCL
|
|
||||||
LDA #>_CMDEND
|
|
||||||
STA SRCH
|
|
||||||
;
|
;
|
||||||
; INIT VM ENVIRONMENT STACK POINTERS
|
; INIT VM ENVIRONMENT STACK POINTERS
|
||||||
;
|
;
|
||||||
|
@@ -1832,7 +1832,7 @@ CALL INY ;+INC_IP
|
|||||||
LDA (IP),Y
|
LDA (IP),Y
|
||||||
STA TMPH
|
STA TMPH
|
||||||
TYA
|
TYA
|
||||||
CLC
|
SEC
|
||||||
ADC IPL
|
ADC IPL
|
||||||
PHA
|
PHA
|
||||||
LDA IPH
|
LDA IPH
|
||||||
@@ -1845,7 +1845,7 @@ CALL INY ;+INC_IP
|
|||||||
STA IPL
|
STA IPL
|
||||||
LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
||||||
STA OPPAGE
|
STA OPPAGE
|
||||||
LDY #$01
|
LDY #$00
|
||||||
JMP FETCHOP
|
JMP FETCHOP
|
||||||
CALLX INY ;+INC_IP
|
CALLX INY ;+INC_IP
|
||||||
LDA (IP),Y
|
LDA (IP),Y
|
||||||
@@ -1854,7 +1854,7 @@ CALLX INY ;+INC_IP
|
|||||||
LDA (IP),Y
|
LDA (IP),Y
|
||||||
STA TMPH
|
STA TMPH
|
||||||
TYA
|
TYA
|
||||||
CLC
|
SEC
|
||||||
ADC IPL
|
ADC IPL
|
||||||
PHA
|
PHA
|
||||||
LDA IPH
|
LDA IPH
|
||||||
@@ -1876,7 +1876,7 @@ CALLX INY ;+INC_IP
|
|||||||
STA IPL
|
STA IPL
|
||||||
LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
||||||
STA OPPAGE
|
STA OPPAGE
|
||||||
LDY #$01
|
LDY #$00
|
||||||
JMP FETCHOP
|
JMP FETCHOP
|
||||||
;*
|
;*
|
||||||
;* INDIRECT CALL TO ADDRESS (NATIVE CODE)
|
;* INDIRECT CALL TO ADDRESS (NATIVE CODE)
|
||||||
@@ -1887,7 +1887,7 @@ ICAL LDA ESTKL,X
|
|||||||
STA TMPH
|
STA TMPH
|
||||||
INX
|
INX
|
||||||
TYA
|
TYA
|
||||||
CLC
|
SEC
|
||||||
ADC IPL
|
ADC IPL
|
||||||
PHA
|
PHA
|
||||||
LDA IPH
|
LDA IPH
|
||||||
@@ -1900,7 +1900,7 @@ ICAL LDA ESTKL,X
|
|||||||
STA IPL
|
STA IPL
|
||||||
LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
LDA #>OPTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
||||||
STA OPPAGE
|
STA OPPAGE
|
||||||
LDY #$01
|
LDY #$00
|
||||||
JMP FETCHOP
|
JMP FETCHOP
|
||||||
ICALX LDA ESTKL,X
|
ICALX LDA ESTKL,X
|
||||||
STA TMPL
|
STA TMPL
|
||||||
@@ -1908,7 +1908,7 @@ ICALX LDA ESTKL,X
|
|||||||
STA TMPH
|
STA TMPH
|
||||||
INX
|
INX
|
||||||
TYA
|
TYA
|
||||||
CLC
|
SEC
|
||||||
ADC IPL
|
ADC IPL
|
||||||
PHA
|
PHA
|
||||||
LDA IPH
|
LDA IPH
|
||||||
@@ -1922,6 +1922,7 @@ ICALX LDA ESTKL,X
|
|||||||
PHP
|
PHP
|
||||||
PLA
|
PLA
|
||||||
STA PSR
|
STA PSR
|
||||||
|
SEI
|
||||||
STA ALTRDON
|
STA ALTRDON
|
||||||
PLA
|
PLA
|
||||||
STA IPH
|
STA IPH
|
||||||
@@ -1929,7 +1930,7 @@ ICALX LDA ESTKL,X
|
|||||||
STA IPL
|
STA IPL
|
||||||
LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
LDA #>OPXTBL ; MAKE SURE WE'RE INDEXING THE RIGHT TABLE
|
||||||
STA OPPAGE
|
STA OPPAGE
|
||||||
LDY #$01
|
LDY #$00
|
||||||
JMP FETCHOP
|
JMP FETCHOP
|
||||||
;*
|
;*
|
||||||
;* JUMP INDIRECT TRHOUGH TMP
|
;* JUMP INDIRECT TRHOUGH TMP
|
||||||
|
Reference in New Issue
Block a user