mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-02 16:10:55 +11:00
Compare commits
No commits in common. "97dcad9b15414e7a645e9b8d89dfe19449d860d6" and "247b200dcc50ba5bd141a4c037093636df99a052" have entirely different histories.
97dcad9b15
...
247b200dcc
@ -628,19 +628,19 @@ _parseArgs:
|
||||
|
||||
_readBit:
|
||||
ld a, 7
|
||||
jp _readExpr
|
||||
jr _readExpr
|
||||
|
||||
_readA6:
|
||||
ld a, 0x3f
|
||||
jp _readExpr
|
||||
jr _readExpr
|
||||
|
||||
_readA5:
|
||||
ld a, 0x1f
|
||||
jp _readExpr
|
||||
jr _readExpr
|
||||
|
||||
_readK8:
|
||||
ld a, 0xff
|
||||
jp _readExpr
|
||||
jr _readExpr
|
||||
|
||||
_readDouble:
|
||||
push de
|
||||
@ -707,12 +707,6 @@ _readR5:
|
||||
push de
|
||||
ld a, (hl)
|
||||
call upcase
|
||||
cp 'X'
|
||||
jr z, .rdXYZ
|
||||
cp 'Y'
|
||||
jr z, .rdXYZ
|
||||
cp 'Z'
|
||||
jr z, .rdXYZ
|
||||
cp 'R'
|
||||
jr nz, .end ; not a register
|
||||
inc hl
|
||||
@ -723,34 +717,6 @@ _readR5:
|
||||
.end:
|
||||
pop de
|
||||
ret
|
||||
.rdXYZ:
|
||||
; First, let's get a base value, that is, (A-'X'+26)*2, because XL, our
|
||||
; lowest register, is equivalent to r26.
|
||||
sub 'X'
|
||||
rla ; no carry from sub
|
||||
add a, 26
|
||||
ld d, a ; store that
|
||||
inc hl
|
||||
ld a, (hl)
|
||||
call upcase
|
||||
cp 'H'
|
||||
jr nz, .skip1
|
||||
; second char is 'H'? our value is +1
|
||||
inc d
|
||||
jr .skip2
|
||||
.skip1:
|
||||
cp 'L'
|
||||
jr nz, .end ; not L either? then it's not good
|
||||
.skip2:
|
||||
; Good, we have our final value in D and we're almost sure it's a valid
|
||||
; register. Our only check left is that the 3rd char is a null.
|
||||
inc hl
|
||||
ld a, (hl)
|
||||
or a
|
||||
jr nz, .end
|
||||
; we're good
|
||||
ld a, d
|
||||
jr .end
|
||||
|
||||
; Put DE's LSB into A and, additionally, ensure that the new value is <=
|
||||
; than what was previously in A.
|
||||
|
@ -1,5 +1,12 @@
|
||||
; *** CPU registers aliases ***
|
||||
|
||||
.equ XH 27
|
||||
.equ XL 26
|
||||
.equ YH 29
|
||||
.equ YL 28
|
||||
.equ ZH 31
|
||||
.equ ZL 30
|
||||
|
||||
.equ SREG_C 0 ; Carry Flag
|
||||
.equ SREG_Z 1 ; Zero Flag
|
||||
.equ SREG_N 2 ; Negative Flag
|
||||
|
@ -108,9 +108,6 @@ void create_window()
|
||||
xcb_map_window(conn, win);
|
||||
}
|
||||
|
||||
// To make things simple with X11, we only support monochrome display, which is
|
||||
// inverted: As soon as the color of the pixel is non-black, we show a black
|
||||
// pixel. If the pixel is white, we show black.
|
||||
void draw_pixels()
|
||||
{
|
||||
xcb_get_geometry_reply_t *geom;
|
||||
|
@ -51,7 +51,6 @@ void vdp_data_wr(VDP *vdp, uint8_t val)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a 8-bit RGB value (0b00bbggrr)
|
||||
uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
|
||||
{
|
||||
if (x >= VDP_SCREENW) {
|
||||
@ -64,8 +63,6 @@ uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
|
||||
uint16_t offset = 0x3800 + ((y/8) << 6) + ((x/8) << 1);
|
||||
uint16_t tableval = vdp->vram[offset] + (vdp->vram[offset+1] << 8);
|
||||
uint16_t tilenum = tableval & 0x1ff;
|
||||
// is palette select bit on? if yes, use sprite palette instead
|
||||
uint8_t palettemod = tableval & 0x800 ? 0x10 : 0;
|
||||
// tile offset this time. Each tile is 0x20 bytes long.
|
||||
offset = tilenum * 0x20;
|
||||
// Each 4 byte is a row. Find row first.
|
||||
@ -73,10 +70,8 @@ uint8_t vdp_pixel(VDP *vdp, uint16_t x, uint16_t y)
|
||||
uint8_t bitnum = 7 - (x%8);
|
||||
// Now, let's compose the result by pushing the right bit of our 4 bytes
|
||||
// into our result.
|
||||
uint8_t palette_id = ((vdp->vram[offset] >> bitnum) & 1) + \
|
||||
return ((vdp->vram[offset] >> bitnum) & 1) + \
|
||||
(((vdp->vram[offset+1] >> bitnum) & 1) << 1) + \
|
||||
(((vdp->vram[offset+2] >> bitnum) & 1) << 2) + \
|
||||
(((vdp->vram[offset+3] >> bitnum) & 1) << 3);
|
||||
uint8_t rgb = vdp->vram[0x4000+palettemod+palette_id];
|
||||
return rgb;
|
||||
}
|
||||
|
@ -12,10 +12,8 @@
|
||||
; can access those cells by their (X, Y) address. In addition to this, we have
|
||||
; the concept of an active cursor, which will be indicated visually if possible.
|
||||
;
|
||||
; This module provides PutC and GetC routines, suitable for plugging into stdio.
|
||||
; PutC, for obvious reasons, GetC, for less obvious reasons: We need to wrap
|
||||
; GetC because we need to update the cursor before calling actual GetC, but
|
||||
; also, because we need to know when a bulk update ends.
|
||||
; Additionally, this module provides a PutC routine, suitable for plugging into
|
||||
; stdio.
|
||||
;
|
||||
; *** Defines ***
|
||||
;
|
||||
@ -23,9 +21,7 @@
|
||||
; GRID_ROWS: Number of rows in the grid
|
||||
; GRID_SETCELL: Pointer to routine that sets cell at row D and column E with
|
||||
; character in A. If C is nonzero, this cell must be displayed,
|
||||
; if possible, as the cursor. This routine is never called with
|
||||
; A < 0x20.
|
||||
; GRID_GETC: Routine that gridGetC will wrap around.
|
||||
; if possible, as the cursor.
|
||||
;
|
||||
; *** Consts ***
|
||||
.equ GRID_SIZE GRID_COLS*GRID_ROWS
|
||||
@ -35,10 +31,6 @@
|
||||
.equ GRID_CURX GRID_RAMSTART
|
||||
; Cursor's row
|
||||
.equ GRID_CURY @+1
|
||||
; Whether we scrolled recently. We don't refresh the screen immediately when
|
||||
; scrolling in case we have many lines being spit at once (refreshing the
|
||||
; display is then very slow). Instead, we wait until the next gridGetC call
|
||||
.equ GRID_SCROLLED @+1
|
||||
; Grid's in-memory buffer of the contents on screen. Because we always push to
|
||||
; display right after a change, this is almost always going to be a correct
|
||||
; representation of on-screen display.
|
||||
@ -61,7 +53,7 @@ _gridPlaceCell:
|
||||
ld hl, GRID_BUF
|
||||
ld a, d
|
||||
or a
|
||||
jr z, .setcol
|
||||
ret z
|
||||
push de ; --> lvl 1
|
||||
ld de, GRID_COLS
|
||||
.loop:
|
||||
@ -69,18 +61,10 @@ _gridPlaceCell:
|
||||
dec a
|
||||
jr nz, .loop
|
||||
pop de ; <-- lvl 1
|
||||
.setcol:
|
||||
; We're at the proper row, now let's advance to cell
|
||||
ld a, e
|
||||
jp addHL
|
||||
|
||||
; Ensure that A >= 0x20
|
||||
_gridAdjustA:
|
||||
cp 0x20
|
||||
ret nc
|
||||
ld a, 0x20
|
||||
ret
|
||||
|
||||
; Push row D in the buffer onto the screen.
|
||||
gridPushRow:
|
||||
push af
|
||||
@ -94,7 +78,6 @@ gridPushRow:
|
||||
ld b, GRID_COLS
|
||||
.loop:
|
||||
ld a, (hl)
|
||||
call _gridAdjustA
|
||||
; A, C, D and E have proper values
|
||||
call GRID_SETCELL
|
||||
inc hl
|
||||
@ -115,10 +98,11 @@ gridClrRow:
|
||||
push hl
|
||||
ld e, 0
|
||||
call _gridPlaceCell
|
||||
ld a, ' '
|
||||
xor a
|
||||
ld b, GRID_COLS
|
||||
call fill
|
||||
call gridPushRow
|
||||
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
@ -135,7 +119,7 @@ gridPushScr:
|
||||
pop de
|
||||
ret
|
||||
|
||||
; Set character under cursor to A. C is passed to GRID_SETCELL as-is.
|
||||
; Set character under cursor to A
|
||||
gridSetCur:
|
||||
push de
|
||||
push hl
|
||||
@ -147,34 +131,17 @@ gridSetCur:
|
||||
call _gridPlaceCell
|
||||
pop af \ push af ; <--> lvl 1
|
||||
ld (hl), a
|
||||
call _gridAdjustA
|
||||
call GRID_SETCELL
|
||||
pop af ; <-- lvl 1
|
||||
pop hl
|
||||
pop de
|
||||
ret
|
||||
|
||||
; Call gridSetCur with C = 1.
|
||||
gridSetCurH:
|
||||
push bc
|
||||
ld c, 1
|
||||
call gridSetCur
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; Call gridSetCur with C = 0.
|
||||
gridSetCurL:
|
||||
push bc
|
||||
ld c, 0
|
||||
call gridSetCur
|
||||
pop bc
|
||||
ret
|
||||
|
||||
; Clear character under cursor
|
||||
gridClrCur:
|
||||
push af
|
||||
ld a, ' '
|
||||
call gridSetCurL
|
||||
call gridSetCur
|
||||
pop af
|
||||
ret
|
||||
|
||||
@ -183,10 +150,19 @@ gridLF:
|
||||
push de
|
||||
push af
|
||||
ld a, (GRID_CURY)
|
||||
; increase A
|
||||
call .incA
|
||||
ld d, a
|
||||
call gridClrRow
|
||||
ld (GRID_CURY), a
|
||||
xor a
|
||||
ld (GRID_CURX), a
|
||||
pop af
|
||||
pop de
|
||||
ret
|
||||
.incA:
|
||||
inc a
|
||||
cp GRID_ROWS
|
||||
jr nz, .noscroll
|
||||
ret nz ; no rollover
|
||||
; bottom reached, stay on last line and scroll screen
|
||||
push hl
|
||||
push de
|
||||
@ -195,21 +171,11 @@ gridLF:
|
||||
ld hl, GRID_BUF+GRID_COLS
|
||||
ld bc, GRID_SIZE-GRID_COLS
|
||||
ldir
|
||||
ld hl, GRID_SCROLLED
|
||||
inc (hl) ; mark as scrolled
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
call gridPushScr
|
||||
dec a
|
||||
.noscroll:
|
||||
; A has been increased properly
|
||||
ld d, a
|
||||
call gridClrRow
|
||||
ld (GRID_CURY), a
|
||||
xor a
|
||||
ld (GRID_CURX), a
|
||||
pop af
|
||||
pop de
|
||||
ret
|
||||
|
||||
gridBS:
|
||||
@ -244,7 +210,7 @@ gridPutC:
|
||||
cp ' '
|
||||
ret c ; ignore unhandled control characters
|
||||
|
||||
call gridSetCurL
|
||||
call gridSetCur
|
||||
push af ; --> lvl 1
|
||||
; Move cursor
|
||||
ld a, (GRID_CURX)
|
||||
@ -260,16 +226,3 @@ gridPutC:
|
||||
call gridLF
|
||||
pop af ; <-- lvl 1
|
||||
ret
|
||||
|
||||
gridGetC:
|
||||
ld a, (GRID_SCROLLED)
|
||||
or a
|
||||
jr z, .nopush
|
||||
; We've scrolled recently, update screen
|
||||
xor a
|
||||
ld (GRID_SCROLLED), a
|
||||
call gridPushScr
|
||||
.nopush:
|
||||
ld a, ' '
|
||||
call gridSetCurH
|
||||
jp GRID_GETC
|
||||
|
@ -181,7 +181,7 @@ padGetC:
|
||||
; no action button pressed, but because our pad status changed, update
|
||||
; VDP before looping.
|
||||
ld a, (PAD_SELCHR)
|
||||
call gridSetCurH
|
||||
call gridSetCur
|
||||
jp padGetC
|
||||
.return:
|
||||
ld a, LF
|
||||
@ -190,7 +190,7 @@ padGetC:
|
||||
.advance:
|
||||
ld a, (PAD_SELCHR)
|
||||
; Z was already set from previous BIT instruction
|
||||
jp gridSetCurL
|
||||
ret
|
||||
.backspace:
|
||||
ld a, BS
|
||||
; Z was already set from previous BIT instruction
|
||||
|
@ -23,8 +23,8 @@
|
||||
; *** Code ***
|
||||
|
||||
vdpInit:
|
||||
ld hl, .initData
|
||||
ld b, .initDataEnd-.initData
|
||||
ld hl, vdpInitData
|
||||
ld b, vdpInitDataEnd-vdpInitData
|
||||
ld c, VDP_CTLPORT
|
||||
otir
|
||||
|
||||
@ -47,10 +47,10 @@ vdpInit:
|
||||
out (VDP_CTLPORT), a
|
||||
ld a, 0xc0
|
||||
out (VDP_CTLPORT), a
|
||||
ld hl, .paletteData
|
||||
ld b, .paletteDataEnd-.paletteData
|
||||
ld c, VDP_DATAPORT
|
||||
otir
|
||||
xor a ; palette 0: black
|
||||
out (VDP_DATAPORT), a
|
||||
ld a, 0x3f ; palette 1: white
|
||||
out (VDP_DATAPORT), a
|
||||
|
||||
; Define tiles
|
||||
xor a
|
||||
@ -97,28 +97,6 @@ vdpInit:
|
||||
out (VDP_CTLPORT), a
|
||||
ret
|
||||
|
||||
; VDP initialisation data
|
||||
.initData:
|
||||
; 0x8x == set register X
|
||||
.db 0b00000100, 0x80 ; Bit 2: Select mode 4
|
||||
.db 0b00000000, 0x81
|
||||
.db 0b11111111, 0x82 ; Name table: 0x3800
|
||||
.db 0b11111111, 0x85 ; Sprite table: 0x3f00
|
||||
.db 0b11111111, 0x86 ; sprite use tiles from 0x2000
|
||||
.db 0b11111111, 0x87 ; Border uses palette 0xf
|
||||
.db 0b00000000, 0x88 ; BG X scroll
|
||||
.db 0b00000000, 0x89 ; BG Y scroll
|
||||
.db 0b11111111, 0x8a ; Line counter (why have this?)
|
||||
.initDataEnd:
|
||||
.paletteData:
|
||||
; BG palette
|
||||
.db 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
; Sprite palette (inverted colors)
|
||||
.db 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
.paletteDataEnd:
|
||||
|
||||
; Convert ASCII char in A into a tile index corresponding to that character.
|
||||
; When a character is unknown, returns 0x5e (a '~' char).
|
||||
vdpConv:
|
||||
@ -130,8 +108,7 @@ vdpConv:
|
||||
ld a, 0x5e
|
||||
ret
|
||||
|
||||
; grid routine. Sets cell at row D and column E to character A. If C is one, we
|
||||
; use the sprite palette.
|
||||
; grid routine. Sets cell at row D and column E to character A
|
||||
vdpSetCell:
|
||||
call vdpConv
|
||||
; store A away
|
||||
@ -164,11 +141,18 @@ vdpSetCell:
|
||||
; We're ready to send our data now. Let's go
|
||||
ex af, af'
|
||||
out (VDP_DATAPORT), a
|
||||
|
||||
; Palette select is on bit 3 of MSB
|
||||
ld a, 1
|
||||
and c
|
||||
rla \ rla \ rla
|
||||
out (VDP_DATAPORT), a
|
||||
ret
|
||||
|
||||
; VDP initialisation data
|
||||
vdpInitData:
|
||||
; 0x8x == set register X
|
||||
.db 0b00000100, 0x80 ; Bit 2: Select mode 4
|
||||
.db 0b00000000, 0x81
|
||||
.db 0b11111111, 0x82 ; Name table: 0x3800
|
||||
.db 0b11111111, 0x85 ; Sprite table: 0x3f00
|
||||
.db 0b11111111, 0x86 ; sprite use tiles from 0x2000
|
||||
.db 0b11111111, 0x87 ; Border uses palette 0xf
|
||||
.db 0b00000000, 0x88 ; BG X scroll
|
||||
.db 0b00000000, 0x89 ; BG Y scroll
|
||||
.db 0b11111111, 0x8a ; Line counter (why have this?)
|
||||
vdpInitDataEnd:
|
||||
|
@ -1,9 +1,7 @@
|
||||
; vid - TRS-80's video
|
||||
;
|
||||
; Implement PutC and GRID_SETCELL using TRS-80's SVC calls.
|
||||
|
||||
.equ TRS80_COLS 80
|
||||
.equ TRS80_ROWS 24
|
||||
; Implement PutC using TRS-80's SVC calls so that character it put on video
|
||||
; display.
|
||||
|
||||
trs80PutC:
|
||||
push af
|
||||
@ -16,44 +14,3 @@ trs80PutC:
|
||||
pop bc
|
||||
pop af
|
||||
ret
|
||||
|
||||
trs80SetCell:
|
||||
push af
|
||||
push bc
|
||||
push hl ; HL altered by @VDCTL
|
||||
push de ; DE altered by @VDCTL
|
||||
ex de, hl
|
||||
bit 0, c
|
||||
ld c, a ; save A now
|
||||
jr z, .skip ; Z from BIT above. cursor not set
|
||||
; set cursor
|
||||
ld a, 0x0f ; @VDCTL
|
||||
ld b, 3 ; move cursor fn
|
||||
rst 0x28
|
||||
; HL altered.
|
||||
; Our Row/Col is our currently-pushed DE value. Let's take advantage of
|
||||
; that.
|
||||
pop hl \ push hl ; HL altered. bring back from stack
|
||||
.skip:
|
||||
ld a, 0x0f ; @VDCTL
|
||||
ld b, 2 ; display char
|
||||
rst 0x28
|
||||
pop de
|
||||
pop hl
|
||||
pop bc
|
||||
pop af
|
||||
ret
|
||||
|
||||
; This is a much faster version of gridPushScr. Use it in your glue code, but
|
||||
; you need to set HL to GRID_BUF first.
|
||||
trs80PushScr:
|
||||
push af
|
||||
push bc
|
||||
ld a, 0x0f ; @VDCTL
|
||||
ld b, 5 ; move from RAM to vid
|
||||
; HL is already set by caller
|
||||
rst 0x28
|
||||
pop bc
|
||||
pop af
|
||||
cp a ; ensure Z
|
||||
ret
|
||||
|
@ -21,7 +21,6 @@
|
||||
jp fsOpen
|
||||
jp fsGetB
|
||||
jp printstr
|
||||
jp printcrlf
|
||||
jp _blkGetB
|
||||
jp _blkPutB
|
||||
jp _blkSeek
|
||||
@ -29,15 +28,12 @@
|
||||
jp sdcGetB
|
||||
jp sdcPutB
|
||||
jp blkGetB
|
||||
jp stdioPutC
|
||||
|
||||
; interrupt hook
|
||||
.fill 0x38-$
|
||||
jp aciaInt
|
||||
|
||||
; *** cont. ***
|
||||
|
||||
jp stdioPutC
|
||||
|
||||
.inc "err.h"
|
||||
.inc "ascii.h"
|
||||
.inc "blkdev.h"
|
||||
|
@ -10,7 +10,6 @@
|
||||
.equ fsOpen @+3
|
||||
.equ fsGetB @+3
|
||||
.equ printstr @+3
|
||||
.equ printcrlf @+3
|
||||
.equ _blkGetB @+3
|
||||
.equ _blkPutB @+3
|
||||
.equ _blkSeek @+3
|
||||
@ -18,6 +17,4 @@
|
||||
.equ sdcGetB @+3
|
||||
.equ sdcPutB @+3
|
||||
.equ blkGetB @+3
|
||||
|
||||
; *** cont. ***
|
||||
.equ stdioPutC 0x3b
|
||||
.equ stdioPutC @+3
|
||||
|
@ -21,11 +21,10 @@
|
||||
.equ GRID_COLS VDP_COLS
|
||||
.equ GRID_ROWS VDP_ROWS
|
||||
.equ GRID_SETCELL vdpSetCell
|
||||
.equ GRID_GETC padGetC
|
||||
.inc "grid.asm"
|
||||
|
||||
.equ STDIO_RAMSTART GRID_RAMEND
|
||||
.equ STDIO_GETC gridGetC
|
||||
.equ STDIO_GETC padGetC
|
||||
.equ STDIO_PUTC gridPutC
|
||||
.inc "stdio.asm"
|
||||
|
||||
|
@ -1,13 +1,11 @@
|
||||
PROGNAME = ps2ctl
|
||||
AVRDUDEMCU ?= t45
|
||||
AVRDUDEARGS ?= -c usbtiny -P usb
|
||||
TARGETS = $(PROGNAME).bin os.sms
|
||||
TARGETS = $(PROGNAME).hex os.sms
|
||||
BASEDIR = ../../..
|
||||
ZASM = $(BASEDIR)/emul/zasm/zasm
|
||||
KERNEL = $(BASEDIR)/kernel
|
||||
APPS = $(BASEDIR)/apps
|
||||
AVRA = $(BASEDIR)/emul/zasm/avra
|
||||
AVRINC = $(BASEDIR)/avr
|
||||
|
||||
# Rules
|
||||
|
||||
@ -16,14 +14,14 @@ AVRINC = $(BASEDIR)/avr
|
||||
all: $(TARGETS)
|
||||
@echo Done!
|
||||
|
||||
send: $(PROGNAME).bin
|
||||
avrdude $(AVRDUDEARGS) -p $(AVRDUDEMCU) -U flash:w:$(PROGNAME).bin
|
||||
send: $(PROGNAME).hex
|
||||
avrdude $(AVRDUDEARGS) -p $(AVRDUDEMCU) -U flash:w:$(PROGNAME).hex
|
||||
|
||||
$(PROGNAME).bin: $(PROGNAME).asm
|
||||
$(AVRA) $(AVRINC) < $(PROGNAME).asm > $@
|
||||
$(PROGNAME).hex: $(PROGNAME).asm
|
||||
avra -o $@ $(PROGNAME).asm
|
||||
|
||||
os.sms: glue.asm
|
||||
$(ZASM) $(KERNEL) $(APPS) < glue.asm > $@
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
rm -f $(TARGETS) *.eep.hex *.obj os.bin
|
||||
|
@ -55,6 +55,7 @@ either the low or high bits.
|
||||
* 74xx157 (multiplexer)
|
||||
* A NOR SR-latch. I used a 4043.
|
||||
* Proto board, wires, IC sockets, etc.
|
||||
* [AVRA][avra]
|
||||
|
||||
## Historical note
|
||||
|
||||
@ -113,3 +114,4 @@ Just hook it on. I've tried it, it works.
|
||||
Did you get there? Feels pretty cool huh?
|
||||
|
||||
[rc2014-ps2]: ../../rc2014/ps2
|
||||
[avra]: https://github.com/hsoft/avra
|
||||
|
@ -23,11 +23,10 @@
|
||||
.equ GRID_COLS VDP_COLS
|
||||
.equ GRID_ROWS VDP_ROWS
|
||||
.equ GRID_SETCELL vdpSetCell
|
||||
.equ GRID_GETC kbdGetC
|
||||
.inc "grid.asm"
|
||||
|
||||
.equ STDIO_RAMSTART GRID_RAMEND
|
||||
.equ STDIO_GETC gridGetC
|
||||
.equ STDIO_GETC kbdGetC
|
||||
.equ STDIO_PUTC gridPutC
|
||||
.inc "stdio.asm"
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
.include "tn45def.inc"
|
||||
|
||||
; Receives keystrokes from PS/2 keyboard and send them to the '164. On the PS/2
|
||||
; side, it works the same way as the controller in the rc2014/ps2 recipe.
|
||||
; However, in this case, what we have on the other side isn't a z80 bus, it's
|
||||
@ -28,22 +30,17 @@
|
||||
; written.
|
||||
; Z: pointer to the next scan code to push to the 595
|
||||
;
|
||||
|
||||
.inc "avr.h"
|
||||
.inc "tn254585.h"
|
||||
.inc "tn45.h"
|
||||
|
||||
; *** Constants ***
|
||||
.equ CLK 2 ; Port B
|
||||
.equ DATA 1 ; Port B
|
||||
.equ CP 3 ; Port B
|
||||
.equ CLK = PINB2
|
||||
.equ DATA = PINB1
|
||||
.equ CP = PINB3
|
||||
; SR-Latch's Q pin
|
||||
.equ LQ 0 ; Port B
|
||||
.equ LQ = PINB0
|
||||
; SR-Latch's R pin
|
||||
.equ LR 4 ; Port B
|
||||
.equ LR = PINB4
|
||||
|
||||
; init value for TCNT0 so that overflow occurs in 100us
|
||||
.equ TIMER_INITVAL 0x100-100
|
||||
.equ TIMER_INITVAL = 0x100-100
|
||||
|
||||
; *** Code ***
|
||||
|
||||
@ -59,9 +56,9 @@ hdlINT0:
|
||||
reti
|
||||
|
||||
main:
|
||||
ldi r16, RAMEND&0xff
|
||||
ldi r16, low(RAMEND)
|
||||
out SPL, r16
|
||||
ldi r16, RAMEND}8
|
||||
ldi r16, high(RAMEND)
|
||||
out SPH, r16
|
||||
|
||||
; init variables
|
||||
@ -70,23 +67,23 @@ main:
|
||||
|
||||
; Setup int0
|
||||
; INT0, falling edge
|
||||
ldi r16, 0x02 ; ISC01
|
||||
ldi r16, (1<<ISC01)
|
||||
out MCUCR, r16
|
||||
; Enable INT0
|
||||
ldi r16, 0x40 ; INT0
|
||||
ldi r16, (1<<INT0)
|
||||
out GIMSK, r16
|
||||
|
||||
; Setup buffer
|
||||
clr YH
|
||||
ldi YL, SRAM_START&0xff
|
||||
ldi YL, low(SRAM_START)
|
||||
clr ZH
|
||||
ldi ZL, SRAM_START&0xff
|
||||
ldi ZL, low(SRAM_START)
|
||||
|
||||
; Setup timer. We use the timer to clear up "processbit" registers after
|
||||
; 100us without a clock. This allows us to start the next frame in a
|
||||
; fresh state. at 1MHZ, no prescaling is necessary. Each TCNT0 tick is
|
||||
; already 1us long.
|
||||
ldi r16, 0x01 ; CS00 - no prescaler
|
||||
ldi r16, (1<<CS00) ; no prescaler
|
||||
out TCCR0B, r16
|
||||
|
||||
; init DDRB
|
||||
@ -104,7 +101,7 @@ loop:
|
||||
; nothing to do. Before looping, let's check if our communication timer
|
||||
; overflowed.
|
||||
in r16, TIFR
|
||||
sbrc r16, 1 ; TOV0
|
||||
sbrc r16, TOV0
|
||||
rjmp processbitReset ; Timer0 overflow? reset processbit
|
||||
|
||||
; Nothing to do for real.
|
||||
@ -223,7 +220,7 @@ sendTo164Loop:
|
||||
resetTimer:
|
||||
ldi r16, TIMER_INITVAL
|
||||
out TCNT0, r16
|
||||
ldi r16, 0x02 ; TOV0
|
||||
ldi r16, (1<<TOV0)
|
||||
out TIFR, r16
|
||||
ret
|
||||
|
||||
@ -240,8 +237,8 @@ sendToPS2:
|
||||
|
||||
; Wait until the timer overflows
|
||||
in r16, TIFR
|
||||
sbrs r16, 1 ; TOV0
|
||||
rjmp $-4
|
||||
sbrs r16, TOV0
|
||||
rjmp PC-2
|
||||
; Good, 100us passed.
|
||||
|
||||
; Pull Data low, that's our start bit.
|
||||
@ -261,7 +258,7 @@ sendToPS2:
|
||||
sendToPS2Loop:
|
||||
; Wait for CLK to go low
|
||||
sbic PINB, CLK
|
||||
rjmp $-2
|
||||
rjmp PC-1
|
||||
|
||||
; set up DATA
|
||||
cbi PORTB, DATA
|
||||
@ -271,7 +268,7 @@ sendToPS2Loop:
|
||||
|
||||
; Wait for CLK to go high
|
||||
sbis PINB, CLK
|
||||
rjmp $-2
|
||||
rjmp PC-1
|
||||
|
||||
dec r16
|
||||
brne sendToPS2Loop ; not zero? loop
|
||||
@ -282,7 +279,7 @@ sendToPS2Loop:
|
||||
|
||||
; Wait for CLK to go low
|
||||
sbic PINB, CLK
|
||||
rjmp $-2
|
||||
rjmp PC-1
|
||||
|
||||
; set parity bit
|
||||
cbi PORTB, DATA
|
||||
@ -291,22 +288,22 @@ sendToPS2Loop:
|
||||
|
||||
; Wait for CLK to go high
|
||||
sbis PINB, CLK
|
||||
rjmp $-2
|
||||
rjmp PC-1
|
||||
|
||||
; Wait for CLK to go low
|
||||
sbic PINB, CLK
|
||||
rjmp $-2
|
||||
rjmp PC-1
|
||||
|
||||
; We can now release the DATA line
|
||||
cbi DDRB, DATA
|
||||
|
||||
; Wait for DATA to go low. That's our ACK
|
||||
sbic PINB, DATA
|
||||
rjmp $-2
|
||||
rjmp PC-1
|
||||
|
||||
; Wait for CLK to go low
|
||||
sbic PINB, CLK
|
||||
rjmp $-2
|
||||
rjmp PC-1
|
||||
|
||||
; We're finished! Enable INT0, reset timer, everything back to normal!
|
||||
rcall resetTimer
|
||||
@ -317,21 +314,21 @@ sendToPS2Loop:
|
||||
; Check that Y is within bounds, reset to SRAM_START if not.
|
||||
checkBoundsY:
|
||||
tst YL
|
||||
breq $+4
|
||||
breq PC+2
|
||||
ret ; not zero, nothing to do
|
||||
; YL is zero. Reset Y
|
||||
clr YH
|
||||
ldi YL, SRAM_START&0xff
|
||||
ldi YL, low(SRAM_START)
|
||||
ret
|
||||
|
||||
; Check that Z is within bounds, reset to SRAM_START if not.
|
||||
checkBoundsZ:
|
||||
tst ZL
|
||||
breq $+4
|
||||
breq PC+2
|
||||
ret ; not zero, nothing to do
|
||||
; ZL is zero. Reset Z
|
||||
clr ZH
|
||||
ldi ZL, SRAM_START&0xff
|
||||
ldi ZL, low(SRAM_START)
|
||||
ret
|
||||
|
||||
; Counts the number of 1s in r19 and set r16 to 1 if there's an even number of
|
||||
@ -339,10 +336,10 @@ checkBoundsZ:
|
||||
checkParity:
|
||||
ldi r16, 1
|
||||
lsr r19
|
||||
brcc $+4 ; Carry unset? skip next
|
||||
brcc PC+2 ; Carry unset? skip next
|
||||
inc r16 ; Carry set? We had a 1
|
||||
tst r19 ; is r19 zero yet?
|
||||
brne checkParity+2 ; no? loop and skip first LDI
|
||||
brne checkParity+1 ; no? loop and skip first LDI
|
||||
andi r16, 0x1 ; Sets Z accordingly
|
||||
ret
|
||||
|
||||
|
@ -52,11 +52,10 @@
|
||||
.equ GRID_COLS VDP_COLS
|
||||
.equ GRID_ROWS VDP_ROWS
|
||||
.equ GRID_SETCELL vdpSetCell
|
||||
.equ GRID_GETC kbdGetC
|
||||
.inc "grid.asm"
|
||||
|
||||
.equ STDIO_RAMSTART GRID_RAMEND
|
||||
.equ STDIO_GETC gridGetC
|
||||
.equ STDIO_GETC kbdGetC
|
||||
.equ STDIO_PUTC gridPutC
|
||||
.inc "stdio.asm"
|
||||
|
||||
|
@ -2,13 +2,17 @@
|
||||
.equ RAMEND 0xcfff
|
||||
; Address of the *CL driver. Same as in recv.asm
|
||||
.equ COM_DRV_ADDR 0x0238
|
||||
; in sync with user.h. Last BAS_RAMEND: 0x600b
|
||||
.equ USER_CODE 0x6100
|
||||
; in sync with user.h. Last BAS_RAMEND: 0x5705
|
||||
.equ USER_CODE 0x5800
|
||||
|
||||
; Free memory in TRSDOS starts at 0x3000
|
||||
.org 0x3000
|
||||
jp init
|
||||
|
||||
; The TRS-80 generates a double line feed if we give it both CR and LF.
|
||||
; Has to be defined before the jump table.
|
||||
.equ printcrlf printcr
|
||||
|
||||
; *** Jump Table ***
|
||||
jp strncmp
|
||||
jp upcase
|
||||
@ -41,14 +45,7 @@
|
||||
.equ FLOPPY_RAMSTART RAMSTART
|
||||
.inc "trs80/floppy.asm"
|
||||
|
||||
.equ GRID_RAMSTART FLOPPY_RAMEND
|
||||
.equ GRID_ROWS TRS80_ROWS
|
||||
.equ GRID_COLS TRS80_COLS
|
||||
.equ GRID_SETCELL trs80SetCell
|
||||
.equ GRID_GETC trs80GetC
|
||||
.equ gridPushScr fastPushScr
|
||||
.inc "grid.asm"
|
||||
.equ BLOCKDEV_RAMSTART GRID_RAMEND
|
||||
.equ BLOCKDEV_RAMSTART FLOPPY_RAMEND
|
||||
.equ BLOCKDEV_COUNT 3
|
||||
.inc "blockdev.asm"
|
||||
; List of devices
|
||||
@ -57,9 +54,8 @@
|
||||
.dw blk2GetB, blk2PutB
|
||||
|
||||
.equ STDIO_RAMSTART BLOCKDEV_RAMEND
|
||||
.equ STDIO_GETC gridGetC
|
||||
.equ STDIO_PUTC gridPutC
|
||||
.equ STDIO_SETCUR gridSetCurH
|
||||
.equ STDIO_GETC trs80GetC
|
||||
.equ STDIO_PUTC trs80PutC
|
||||
.inc "stdio.asm"
|
||||
|
||||
.equ FS_RAMSTART STDIO_RAMEND
|
||||
@ -95,7 +91,6 @@
|
||||
|
||||
init:
|
||||
ld sp, RAMEND
|
||||
call gridInit
|
||||
call floppyInit
|
||||
call fsInit
|
||||
call basInit
|
||||
@ -108,6 +103,13 @@ init:
|
||||
|
||||
jp basStart
|
||||
|
||||
printcr:
|
||||
push af
|
||||
ld a, CR
|
||||
call STDIO_PUTC
|
||||
pop af
|
||||
ret
|
||||
|
||||
; Receive a byte from *cl and put it in A.
|
||||
; Returns A > 0xff when receiving the last byte
|
||||
recvCmd:
|
||||
@ -170,13 +172,6 @@ basFindCmdExtra:
|
||||
.dw recvCmd
|
||||
.db 0xff ; end of table
|
||||
|
||||
fastPushScr:
|
||||
push hl
|
||||
ld hl, GRID_BUF
|
||||
call trs80PushScr
|
||||
pop hl
|
||||
ret
|
||||
|
||||
; *** blkdev 1: file handle 0 ***
|
||||
|
||||
blk1GetB:
|
||||
|
@ -1,4 +1,4 @@
|
||||
.org 0x6100
|
||||
.org 0x5800
|
||||
.equ strncmp 0x3003
|
||||
.equ upcase @+3
|
||||
.equ findchar @+3
|
||||
|
@ -24,5 +24,3 @@ jmp bar
|
||||
mov r6, r30
|
||||
lsl r3
|
||||
tst r12
|
||||
clr YH
|
||||
clr r29
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user