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